]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge git://www.linux-watchdog.org/linux-watchdog
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 28 Mar 2012 20:03:26 +0000 (13:03 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 28 Mar 2012 20:03:26 +0000 (13:03 -0700)
Pull watchdog updates from Wim Van Sebroeck:
 - Removal of the Documentation/watchdog/00-INDEX file
 - Fix boot status reporting for imx2_wdt
 - clean-up sp805_wdt, pnx4008_wdt and mpcore_wdt
 - convert printk in watchdog drivers to pr_ functions
 - change nowayout module parameter to bool for every watchdog device
 - conversion of jz4740_wdt, pnx4008_wdt, max63xx_wdt, softdog,
   ep93xx_wdt, coh901327 and txx9wdt to new watchdog API
 - Add support for the WDIOC_GETTIMELEFT ioctl call to the new watchdog
   API
 - Change the new watchdog API so that the driver updates the timeout
   value
 - two fixes for the xen_wdt driver

Fix up conflicts in ep93xx driver due to the same patches being merged
through separate branches.

* git://www.linux-watchdog.org/linux-watchdog: (33 commits)
  watchdog: txx9wdt: fix timeout
  watchdog: Convert txx9wdt driver to watchdog framework
  watchdog: coh901327_wdt.c: fix timeout
  watchdog: coh901327: convert to use watchdog core
  watchdog: Add support for WDIOC_GETTIMELEFT IOCTL in watchdog core
  watchdog: ep93xx_wdt: timeout is an unsigned int value.
  watchdog: ep93xx_wdt: Fix timeout after conversion to watchdog core
  watchdog: Convert ep93xx driver to watchdog core
  watchdog: sp805: Use devm routines
  watchdog: sp805: replace readl/writel with lighter _relaxed variants
  watchdog: sp805: Fix documentation style comment
  watchdog: mpcore_wdt: Allow platform_get_irq() to fail
  watchdog: mpcore_wdt: Use devm routines
  watchdog: mpcore_wdt: Rename dev to pdev for pointing to struct platform_device
  watchdog: xen: don't clear is_active when xen_wdt_stop() failed
  watchdog: xen: don't unconditionally enable the watchdog during resume
  watchdog: fix compiler error for missing parenthesis
  watchdog: ep93xx_wdt.c: fix platform probe
  watchdog: ep93xx: Convert the watchdog driver into a platform device.
  watchdog: fix set_timeout operations
  ...

1404 files changed:
Documentation/ABI/testing/sysfs-block-dm [new file with mode: 0644]
Documentation/ABI/testing/sysfs-bus-rpmsg [new file with mode: 0644]
Documentation/clk.txt [new file with mode: 0644]
Documentation/device-mapper/thin-provisioning.txt
Documentation/device-mapper/verity.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/atmel-aic.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/atmel-at91.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/atmel-pmc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/fsl.txt
Documentation/devicetree/bindings/arm/mrvl.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/omap/intc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/spear.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/tegra/emc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/twd.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/vexpress.txt [new file with mode: 0644]
Documentation/devicetree/bindings/dma/tegra20-apbdma.txt [new file with mode: 0644]
Documentation/devicetree/bindings/gpio/gpio_atmel.txt [new file with mode: 0644]
Documentation/devicetree/bindings/gpio/gpio_i2c.txt [new file with mode: 0644]
Documentation/devicetree/bindings/gpio/gpio_nvidia.txt
Documentation/devicetree/bindings/gpio/mrvl-gpio.txt [new file with mode: 0644]
Documentation/devicetree/bindings/i2c/mrvl-i2c.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mtd/atmel-nand.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mtd/nand.txt [new file with mode: 0644]
Documentation/devicetree/bindings/rtc/sa1100-rtc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/serial/mrvl-serial.txt [new file with mode: 0644]
Documentation/devicetree/bindings/usb/atmel-usb.txt [new file with mode: 0644]
Documentation/devicetree/bindings/usb/tegra-usb.txt
Documentation/feature-removal-schedule.txt
Documentation/filesystems/ext4.txt
Documentation/remoteproc.txt [new file with mode: 0644]
Documentation/rpmsg.txt [new file with mode: 0644]
MAINTAINERS
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/Makefile
arch/arm/boot/compressed/head.S
arch/arm/boot/dts/am3517_mt_ventoux.dts [new file with mode: 0644]
arch/arm/boot/dts/at91sam9g20.dtsi
arch/arm/boot/dts/at91sam9g25ek.dts [new file with mode: 0644]
arch/arm/boot/dts/at91sam9g45.dtsi
arch/arm/boot/dts/at91sam9m10g45ek.dts
arch/arm/boot/dts/at91sam9x5.dtsi [new file with mode: 0644]
arch/arm/boot/dts/at91sam9x5cm.dtsi [new file with mode: 0644]
arch/arm/boot/dts/db8500.dtsi [new file with mode: 0644]
arch/arm/boot/dts/exynos5250-smdk5250.dts [new file with mode: 0644]
arch/arm/boot/dts/exynos5250.dtsi [new file with mode: 0644]
arch/arm/boot/dts/highbank.dts
arch/arm/boot/dts/imx27-phytec-phycore.dts [new file with mode: 0644]
arch/arm/boot/dts/imx27.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx51-babbage.dts
arch/arm/boot/dts/imx6q-arm2.dts
arch/arm/boot/dts/imx6q-sabrelite.dts
arch/arm/boot/dts/imx6q.dtsi
arch/arm/boot/dts/kirkwood-dreamplug.dts [new file with mode: 0644]
arch/arm/boot/dts/kirkwood.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap3-beagle.dts
arch/arm/boot/dts/omap3-evm.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3.dtsi
arch/arm/boot/dts/omap4-panda.dts
arch/arm/boot/dts/omap4-sdp.dts
arch/arm/boot/dts/omap4.dtsi
arch/arm/boot/dts/pxa168-aspenite.dts [new file with mode: 0644]
arch/arm/boot/dts/pxa168.dtsi [new file with mode: 0644]
arch/arm/boot/dts/snowball.dts [new file with mode: 0644]
arch/arm/boot/dts/spear600-evb.dts [new file with mode: 0644]
arch/arm/boot/dts/spear600.dtsi [new file with mode: 0644]
arch/arm/boot/dts/tegra-cardhu.dts
arch/arm/boot/dts/tegra-harmony.dts
arch/arm/boot/dts/tegra-paz00.dts
arch/arm/boot/dts/tegra-seaboard.dts
arch/arm/boot/dts/tegra-trimslice.dts
arch/arm/boot/dts/tegra-ventana.dts
arch/arm/boot/dts/tegra20.dtsi
arch/arm/boot/dts/tegra30.dtsi
arch/arm/boot/dts/usb_a9g20-dab-mmx.dtsi [new file with mode: 0644]
arch/arm/boot/dts/usb_a9g20.dts
arch/arm/boot/dts/vexpress-v2m-rs1.dtsi [new file with mode: 0644]
arch/arm/boot/dts/vexpress-v2m.dtsi [new file with mode: 0644]
arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts [new file with mode: 0644]
arch/arm/boot/dts/vexpress-v2p-ca5s.dts [new file with mode: 0644]
arch/arm/boot/dts/vexpress-v2p-ca9.dts [new file with mode: 0644]
arch/arm/common/Kconfig
arch/arm/common/Makefile
arch/arm/common/sa1111.c
arch/arm/common/time-acorn.c [deleted file]
arch/arm/common/timer-sp.c
arch/arm/configs/at91cap9_defconfig [deleted file]
arch/arm/configs/at91sam9g20_defconfig
arch/arm/configs/imx_v4_v5_defconfig
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/configs/lpc32xx_defconfig [new file with mode: 0644]
arch/arm/configs/magician_defconfig
arch/arm/configs/mini2440_defconfig
arch/arm/configs/mxs_defconfig
arch/arm/configs/s3c2410_defconfig
arch/arm/configs/tct_hammer_defconfig
arch/arm/configs/tegra_defconfig
arch/arm/configs/u8500_defconfig
arch/arm/include/asm/hardware/arm_timer.h
arch/arm/include/asm/hardware/sa1111.h
arch/arm/include/asm/hardware/timer-sp.h
arch/arm/include/asm/localtimer.h
arch/arm/include/asm/smp_twd.h
arch/arm/kernel/Makefile
arch/arm/kernel/crunch-bits.S [deleted file]
arch/arm/kernel/crunch.c [deleted file]
arch/arm/kernel/ecard.c [deleted file]
arch/arm/kernel/ecard.h [deleted file]
arch/arm/kernel/smp.c
arch/arm/kernel/smp_twd.c
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/Makefile
arch/arm/mach-at91/Makefile.boot
arch/arm/mach-at91/at91cap9.c [deleted file]
arch/arm/mach-at91/at91cap9_devices.c [deleted file]
arch/arm/mach-at91/at91rm9200.c
arch/arm/mach-at91/at91rm9200_devices.c
arch/arm/mach-at91/at91rm9200_time.c
arch/arm/mach-at91/at91sam9260.c
arch/arm/mach-at91/at91sam9260_devices.c
arch/arm/mach-at91/at91sam9261.c
arch/arm/mach-at91/at91sam9261_devices.c
arch/arm/mach-at91/at91sam9263.c
arch/arm/mach-at91/at91sam9263_devices.c
arch/arm/mach-at91/at91sam926x_time.c
arch/arm/mach-at91/at91sam9_alt_reset.S
arch/arm/mach-at91/at91sam9g45.c
arch/arm/mach-at91/at91sam9g45_devices.c
arch/arm/mach-at91/at91sam9g45_reset.S
arch/arm/mach-at91/at91sam9rl.c
arch/arm/mach-at91/at91sam9rl_devices.c
arch/arm/mach-at91/at91sam9x5.c [new file with mode: 0644]
arch/arm/mach-at91/at91x40.c
arch/arm/mach-at91/at91x40_time.c
arch/arm/mach-at91/board-afeb-9260v1.c
arch/arm/mach-at91/board-cam60.c
arch/arm/mach-at91/board-cap9adk.c [deleted file]
arch/arm/mach-at91/board-cpu9krea.c
arch/arm/mach-at91/board-cpuat91.c
arch/arm/mach-at91/board-dt.c
arch/arm/mach-at91/board-eco920.c
arch/arm/mach-at91/board-flexibity.c
arch/arm/mach-at91/board-kb9202.c
arch/arm/mach-at91/board-neocore926.c
arch/arm/mach-at91/board-picotux200.c
arch/arm/mach-at91/board-qil-a9260.c
arch/arm/mach-at91/board-rm9200dk.c
arch/arm/mach-at91/board-rm9200ek.c
arch/arm/mach-at91/board-sam9-l9260.c
arch/arm/mach-at91/board-sam9260ek.c
arch/arm/mach-at91/board-sam9261ek.c
arch/arm/mach-at91/board-sam9263ek.c
arch/arm/mach-at91/board-sam9g20ek.c
arch/arm/mach-at91/board-sam9m10g45ek.c
arch/arm/mach-at91/board-sam9rlek.c
arch/arm/mach-at91/board-snapper9260.c
arch/arm/mach-at91/board-stamp9g20.c
arch/arm/mach-at91/board-usb-a926x.c
arch/arm/mach-at91/board-yl-9200.c
arch/arm/mach-at91/clock.c
arch/arm/mach-at91/cpuidle.c
arch/arm/mach-at91/generic.h
arch/arm/mach-at91/gpio.c
arch/arm/mach-at91/include/mach/at91_matrix.h [new file with mode: 0644]
arch/arm/mach-at91/include/mach/at91_pio.h
arch/arm/mach-at91/include/mach/at91_pmc.h
arch/arm/mach-at91/include/mach/at91_ramc.h [new file with mode: 0644]
arch/arm/mach-at91/include/mach/at91_shdwc.h
arch/arm/mach-at91/include/mach/at91_st.h
arch/arm/mach-at91/include/mach/at91cap9.h [deleted file]
arch/arm/mach-at91/include/mach/at91cap9_matrix.h [deleted file]
arch/arm/mach-at91/include/mach/at91rm9200.h
arch/arm/mach-at91/include/mach/at91rm9200_mc.h
arch/arm/mach-at91/include/mach/at91rm9200_sdramc.h [new file with mode: 0644]
arch/arm/mach-at91/include/mach/at91sam9260.h
arch/arm/mach-at91/include/mach/at91sam9260_matrix.h
arch/arm/mach-at91/include/mach/at91sam9261.h
arch/arm/mach-at91/include/mach/at91sam9261_matrix.h
arch/arm/mach-at91/include/mach/at91sam9263.h
arch/arm/mach-at91/include/mach/at91sam9263_matrix.h
arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
arch/arm/mach-at91/include/mach/at91sam9_sdramc.h
arch/arm/mach-at91/include/mach/at91sam9g45.h
arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h
arch/arm/mach-at91/include/mach/at91sam9rl.h
arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h
arch/arm/mach-at91/include/mach/at91sam9x5.h [new file with mode: 0644]
arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h [new file with mode: 0644]
arch/arm/mach-at91/include/mach/at91x40.h
arch/arm/mach-at91/include/mach/board.h
arch/arm/mach-at91/include/mach/cpu.h
arch/arm/mach-at91/include/mach/gpio.h
arch/arm/mach-at91/include/mach/hardware.h
arch/arm/mach-at91/include/mach/io.h
arch/arm/mach-at91/irq.c
arch/arm/mach-at91/pm.c
arch/arm/mach-at91/pm.h
arch/arm/mach-at91/pm_slowclock.S
arch/arm/mach-at91/setup.c
arch/arm/mach-at91/soc.h
arch/arm/mach-davinci/board-dm355-evm.c
arch/arm/mach-davinci/board-dm355-leopard.c
arch/arm/mach-davinci/board-dm365-evm.c
arch/arm/mach-davinci/board-dm644x-evm.c
arch/arm/mach-davinci/board-dm646x-evm.c
arch/arm/mach-davinci/board-neuros-osd2.c
arch/arm/mach-davinci/board-sffsdr.c
arch/arm/mach-davinci/cpufreq.c
arch/arm/mach-davinci/da850.c
arch/arm/mach-davinci/davinci.h [new file with mode: 0644]
arch/arm/mach-davinci/devices.c
arch/arm/mach-davinci/dm355.c
arch/arm/mach-davinci/dm365.c
arch/arm/mach-davinci/dm644x.c
arch/arm/mach-davinci/dm646x.c
arch/arm/mach-davinci/dma.c
arch/arm/mach-davinci/include/mach/dm355.h [deleted file]
arch/arm/mach-davinci/include/mach/dm365.h
arch/arm/mach-davinci/include/mach/dm644x.h [deleted file]
arch/arm/mach-davinci/include/mach/dm646x.h
arch/arm/mach-davinci/include/mach/edma.h
arch/arm/mach-davinci/include/mach/hardware.h
arch/arm/mach-ebsa110/core.c
arch/arm/mach-ebsa110/core.h [new file with mode: 0644]
arch/arm/mach-ebsa110/include/mach/hardware.h
arch/arm/mach-ebsa110/io.c
arch/arm/mach-ebsa110/leds.c
arch/arm/mach-ep93xx/Makefile
arch/arm/mach-ep93xx/adssphere.c
arch/arm/mach-ep93xx/clock.c
arch/arm/mach-ep93xx/core.c
arch/arm/mach-ep93xx/crunch-bits.S [new file with mode: 0644]
arch/arm/mach-ep93xx/crunch.c [new file with mode: 0644]
arch/arm/mach-ep93xx/dma.c
arch/arm/mach-ep93xx/edb93xx.c
arch/arm/mach-ep93xx/gesbc9312.c
arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
arch/arm/mach-ep93xx/include/mach/gpio-ep93xx.h
arch/arm/mach-ep93xx/include/mach/hardware.h
arch/arm/mach-ep93xx/include/mach/platform.h
arch/arm/mach-ep93xx/micro9.c
arch/arm/mach-ep93xx/simone.c
arch/arm/mach-ep93xx/snappercl15.c
arch/arm/mach-ep93xx/soc.h [new file with mode: 0644]
arch/arm/mach-ep93xx/ts72xx.c
arch/arm/mach-ep93xx/vision_ep9307.c
arch/arm/mach-exynos/Kconfig
arch/arm/mach-exynos/Makefile
arch/arm/mach-exynos/clock-exynos4.c [new file with mode: 0644]
arch/arm/mach-exynos/clock-exynos4.h [new file with mode: 0644]
arch/arm/mach-exynos/clock-exynos4210.c
arch/arm/mach-exynos/clock-exynos4212.c
arch/arm/mach-exynos/clock-exynos5.c [new file with mode: 0644]
arch/arm/mach-exynos/clock.c [deleted file]
arch/arm/mach-exynos/common.c
arch/arm/mach-exynos/common.h
arch/arm/mach-exynos/cpuidle.c
arch/arm/mach-exynos/dev-ahci.c
arch/arm/mach-exynos/dev-audio.c
arch/arm/mach-exynos/dev-uart.c [new file with mode: 0644]
arch/arm/mach-exynos/dma.c
arch/arm/mach-exynos/include/mach/debug-macro.S
arch/arm/mach-exynos/include/mach/exynos4-clock.h [deleted file]
arch/arm/mach-exynos/include/mach/gpio.h
arch/arm/mach-exynos/include/mach/irqs.h
arch/arm/mach-exynos/include/mach/map.h
arch/arm/mach-exynos/include/mach/pmu.h
arch/arm/mach-exynos/include/mach/regs-clock.h
arch/arm/mach-exynos/include/mach/regs-gpio.h
arch/arm/mach-exynos/include/mach/regs-pmu.h
arch/arm/mach-exynos/include/mach/uncompress.h
arch/arm/mach-exynos/mach-exynos4-dt.c
arch/arm/mach-exynos/mach-exynos5-dt.c [new file with mode: 0644]
arch/arm/mach-exynos/mach-nuri.c
arch/arm/mach-exynos/mach-origen.c
arch/arm/mach-exynos/mach-smdkv310.c
arch/arm/mach-exynos/mach-universal_c210.c
arch/arm/mach-exynos/mct.c
arch/arm/mach-exynos/platsmp.c
arch/arm/mach-exynos/pm.c
arch/arm/mach-exynos/pm_domains.c
arch/arm/mach-exynos/setup-i2c0.c
arch/arm/mach-highbank/Makefile
arch/arm/mach-highbank/highbank.c
arch/arm/mach-highbank/include/mach/memory.h [deleted file]
arch/arm/mach-highbank/localtimer.c [deleted file]
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/Makefile
arch/arm/mach-imx/Makefile.boot
arch/arm/mach-imx/clock-imx27.c
arch/arm/mach-imx/clock-imx31.c
arch/arm/mach-imx/clock-imx35.c
arch/arm/mach-imx/clock-imx6q.c
arch/arm/mach-imx/cpu-imx5.c
arch/arm/mach-imx/crmregs-imx3.h [new file with mode: 0644]
arch/arm/mach-imx/crmregs-imx31.h [deleted file]
arch/arm/mach-imx/imx27-dt.c [new file with mode: 0644]
arch/arm/mach-imx/imx51-dt.c
arch/arm/mach-imx/imx53-dt.c
arch/arm/mach-imx/lluart.c
arch/arm/mach-imx/localtimer.c [deleted file]
arch/arm/mach-imx/mach-armadillo5x0.c
arch/arm/mach-imx/mach-imx27_visstrim_m10.c
arch/arm/mach-imx/mach-imx6q.c
arch/arm/mach-imx/mach-mx21ads.c
arch/arm/mach-imx/mach-mx27_3ds.c
arch/arm/mach-imx/mach-mx31ads.c
arch/arm/mach-imx/mach-mx31moboard.c
arch/arm/mach-imx/mach-mx35_3ds.c
arch/arm/mach-imx/mach-pcm038.c
arch/arm/mach-imx/mm-imx3.c
arch/arm/mach-imx/mm-imx5.c
arch/arm/mach-imx/pm-imx3.c [new file with mode: 0644]
arch/arm/mach-imx/pm-imx5.c
arch/arm/mach-kirkwood/Kconfig
arch/arm/mach-kirkwood/Makefile
arch/arm/mach-kirkwood/Makefile.boot
arch/arm/mach-kirkwood/board-dreamplug.c [new file with mode: 0644]
arch/arm/mach-kirkwood/board-dt.c [new file with mode: 0644]
arch/arm/mach-kirkwood/common.c
arch/arm/mach-kirkwood/common.h
arch/arm/mach-lpc32xx/Kconfig
arch/arm/mach-lpc32xx/clock.c
arch/arm/mach-lpc32xx/common.c
arch/arm/mach-lpc32xx/common.h
arch/arm/mach-lpc32xx/include/mach/board.h [new file with mode: 0644]
arch/arm/mach-lpc32xx/include/mach/platform.h
arch/arm/mach-lpc32xx/irq.c
arch/arm/mach-lpc32xx/phy3250.c
arch/arm/mach-lpc32xx/pm.c
arch/arm/mach-lpc32xx/timer.c
arch/arm/mach-mmp/Kconfig
arch/arm/mach-mmp/Makefile
arch/arm/mach-mmp/include/mach/pxa910.h
arch/arm/mach-mmp/include/mach/regs-apbc.h
arch/arm/mach-mmp/include/mach/regs-rtc.h [new file with mode: 0644]
arch/arm/mach-mmp/mmp-dt.c [new file with mode: 0644]
arch/arm/mach-mmp/mmp2.c
arch/arm/mach-mmp/pxa168.c
arch/arm/mach-mmp/pxa910.c
arch/arm/mach-mmp/ttc_dkb.c
arch/arm/mach-msm/timer.c
arch/arm/mach-mxs/Kconfig
arch/arm/mach-mxs/Makefile
arch/arm/mach-mxs/clock-mx23.c
arch/arm/mach-mxs/clock-mx28.c
arch/arm/mach-mxs/devices-mx23.h
arch/arm/mach-mxs/devices-mx28.h
arch/arm/mach-mxs/devices/Kconfig
arch/arm/mach-mxs/devices/Makefile
arch/arm/mach-mxs/devices/platform-gpmi-nand.c [new file with mode: 0644]
arch/arm/mach-mxs/devices/platform-mxs-mmc.c
arch/arm/mach-mxs/include/mach/common.h
arch/arm/mach-mxs/include/mach/devices-common.h
arch/arm/mach-mxs/include/mach/digctl.h
arch/arm/mach-mxs/include/mach/mxs.h
arch/arm/mach-mxs/include/mach/uncompress.h
arch/arm/mach-mxs/mach-apx4devkit.c [new file with mode: 0644]
arch/arm/mach-mxs/mach-m28evk.c
arch/arm/mach-mxs/mach-mx28evk.c
arch/arm/mach-mxs/system.c
arch/arm/mach-nomadik/board-nhk8815.c
arch/arm/mach-nomadik/include/mach/setup.h [deleted file]
arch/arm/mach-omap1/Kconfig
arch/arm/mach-omap1/ams-delta-fiq-handler.S
arch/arm/mach-omap1/ams-delta-fiq.c
arch/arm/mach-omap1/board-ams-delta.c
arch/arm/mach-omap1/board-fsample.c
arch/arm/mach-omap1/board-h2.c
arch/arm/mach-omap1/board-h3.c
arch/arm/mach-omap1/board-htcherald.c
arch/arm/mach-omap1/board-innovator.c
arch/arm/mach-omap1/board-nokia770.c
arch/arm/mach-omap1/board-osk.c
arch/arm/mach-omap1/board-palmte.c
arch/arm/mach-omap1/board-palmtt.c
arch/arm/mach-omap1/board-palmz71.c
arch/arm/mach-omap1/board-perseus2.c
arch/arm/mach-omap1/board-sx1.c
arch/arm/mach-omap1/board-voiceblue.c
arch/arm/mach-omap1/clock.c
arch/arm/mach-omap1/clock_data.c
arch/arm/mach-omap1/common.h
arch/arm/mach-omap1/devices.c
arch/arm/mach-omap1/dma.c
arch/arm/mach-omap1/flash.c
arch/arm/mach-omap1/fpga.c
arch/arm/mach-omap1/gpio15xx.c
arch/arm/mach-omap1/gpio16xx.c
arch/arm/mach-omap1/gpio7xx.c
arch/arm/mach-omap1/id.c
arch/arm/mach-omap1/include/mach/entry-macro.S
arch/arm/mach-omap1/include/mach/hardware.h
arch/arm/mach-omap1/include/mach/io.h
arch/arm/mach-omap1/include/mach/memory.h
arch/arm/mach-omap1/io.c
arch/arm/mach-omap1/iomap.h [new file with mode: 0644]
arch/arm/mach-omap1/irq.c
arch/arm/mach-omap1/lcd_dma.c
arch/arm/mach-omap1/mcbsp.c
arch/arm/mach-omap1/pm.c
arch/arm/mach-omap1/reset.c
arch/arm/mach-omap1/sleep.S
arch/arm/mach-omap1/sram.S
arch/arm/mach-omap1/time.c
arch/arm/mach-omap1/timer32k.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/am35xx-emac.c [new file with mode: 0644]
arch/arm/mach-omap2/am35xx-emac.h [new file with mode: 0644]
arch/arm/mach-omap2/board-2430sdp.c
arch/arm/mach-omap2/board-3430sdp.c
arch/arm/mach-omap2/board-4430sdp.c
arch/arm/mach-omap2/board-am3517evm.c
arch/arm/mach-omap2/board-cm-t35.c
arch/arm/mach-omap2/board-cm-t3517.c
arch/arm/mach-omap2/board-devkit8000.c
arch/arm/mach-omap2/board-flash.c
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-igep0020.c
arch/arm/mach-omap2/board-ldp.c
arch/arm/mach-omap2/board-n8x0.c
arch/arm/mach-omap2/board-omap3beagle.c
arch/arm/mach-omap2/board-omap3evm.c
arch/arm/mach-omap2/board-omap3logic.c
arch/arm/mach-omap2/board-omap3pandora.c
arch/arm/mach-omap2/board-omap3stalker.c
arch/arm/mach-omap2/board-omap3touchbook.c
arch/arm/mach-omap2/board-omap4panda.c
arch/arm/mach-omap2/board-overo.c
arch/arm/mach-omap2/board-rm680.c
arch/arm/mach-omap2/board-rx51-peripherals.c
arch/arm/mach-omap2/board-zoom-display.c
arch/arm/mach-omap2/board-zoom-peripherals.c
arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
arch/arm/mach-omap2/clkt_clksel.c
arch/arm/mach-omap2/clkt_dpll.c
arch/arm/mach-omap2/clock2420_data.c
arch/arm/mach-omap2/clock2430.c
arch/arm/mach-omap2/clock2430_data.c
arch/arm/mach-omap2/clock2xxx.c
arch/arm/mach-omap2/clock3xxx.c
arch/arm/mach-omap2/clock3xxx_data.c
arch/arm/mach-omap2/clock44xx_data.c
arch/arm/mach-omap2/cm2xxx_3xxx.c
arch/arm/mach-omap2/cm44xx.c
arch/arm/mach-omap2/cminst44xx.c
arch/arm/mach-omap2/common-board-devices.c
arch/arm/mach-omap2/common.c
arch/arm/mach-omap2/common.h
arch/arm/mach-omap2/control.c
arch/arm/mach-omap2/control.h
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/display.c
arch/arm/mach-omap2/dma.c
arch/arm/mach-omap2/emu.c
arch/arm/mach-omap2/gpio.c
arch/arm/mach-omap2/gpmc-nand.c
arch/arm/mach-omap2/gpmc-onenand.c
arch/arm/mach-omap2/gpmc-smsc911x.c
arch/arm/mach-omap2/gpmc.c
arch/arm/mach-omap2/hsmmc.c
arch/arm/mach-omap2/hsmmc.h
arch/arm/mach-omap2/id.c
arch/arm/mach-omap2/include/mach/io.h
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/iomap.h [new file with mode: 0644]
arch/arm/mach-omap2/irq.c
arch/arm/mach-omap2/mcbsp.c
arch/arm/mach-omap2/mux.c
arch/arm/mach-omap2/mux.h
arch/arm/mach-omap2/omap-hotplug.c
arch/arm/mach-omap2/omap-mpuss-lowpower.c
arch/arm/mach-omap2/omap-smp.c
arch/arm/mach-omap2/omap-wakeupgen.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/opp2420_data.c
arch/arm/mach-omap2/opp2430_data.c
arch/arm/mach-omap2/pm-debug.c
arch/arm/mach-omap2/pm.c
arch/arm/mach-omap2/pm.h
arch/arm/mach-omap2/pm24xx.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/pm44xx.c
arch/arm/mach-omap2/powerdomain-common.c
arch/arm/mach-omap2/powerdomain2xxx_3xxx.c
arch/arm/mach-omap2/powerdomain44xx.c
arch/arm/mach-omap2/powerdomains3xxx_data.c
arch/arm/mach-omap2/prcm_mpu44xx.c
arch/arm/mach-omap2/prm44xx.c
arch/arm/mach-omap2/prminst44xx.c
arch/arm/mach-omap2/sdram-nokia.c
arch/arm/mach-omap2/sdrc2xxx.c
arch/arm/mach-omap2/serial.c
arch/arm/mach-omap2/sleep24xx.S
arch/arm/mach-omap2/sleep34xx.S
arch/arm/mach-omap2/smartreflex-class3.c
arch/arm/mach-omap2/smartreflex.c
arch/arm/mach-omap2/smartreflex.h
arch/arm/mach-omap2/sr_device.c
arch/arm/mach-omap2/sram242x.S
arch/arm/mach-omap2/sram243x.S
arch/arm/mach-omap2/sram34xx.S
arch/arm/mach-omap2/timer-mpu.c [deleted file]
arch/arm/mach-omap2/timer.c
arch/arm/mach-omap2/vc.c
arch/arm/mach-omap2/vp.c
arch/arm/mach-pxa/devices.c
arch/arm/mach-pxa/hx4700.c
arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/magician.c
arch/arm/mach-pxa/pxa3xx.c
arch/arm/mach-pxa/pxa95x.c
arch/arm/mach-realview/realview_eb.c
arch/arm/mach-realview/realview_pb11mp.c
arch/arm/mach-realview/realview_pbx.c
arch/arm/mach-rpc/Makefile
arch/arm/mach-rpc/ecard.c [new file with mode: 0644]
arch/arm/mach-rpc/ecard.h [new file with mode: 0644]
arch/arm/mach-rpc/include/mach/irqs.h
arch/arm/mach-rpc/riscpc.c
arch/arm/mach-rpc/time.c [new file with mode: 0644]
arch/arm/mach-s3c2410/Kconfig
arch/arm/mach-s3c2410/Makefile
arch/arm/mach-s3c2410/Makefile.boot [deleted file]
arch/arm/mach-s3c2410/bast-ide.c [deleted file]
arch/arm/mach-s3c2410/bast-irq.c [deleted file]
arch/arm/mach-s3c2410/common.h [deleted file]
arch/arm/mach-s3c2410/dma.c [deleted file]
arch/arm/mach-s3c2410/h1940-bluetooth.c [deleted file]
arch/arm/mach-s3c2410/include/mach/anubis-cpld.h [deleted file]
arch/arm/mach-s3c2410/include/mach/anubis-irq.h [deleted file]
arch/arm/mach-s3c2410/include/mach/anubis-map.h [deleted file]
arch/arm/mach-s3c2410/include/mach/bast-cpld.h [deleted file]
arch/arm/mach-s3c2410/include/mach/bast-irq.h [deleted file]
arch/arm/mach-s3c2410/include/mach/bast-map.h [deleted file]
arch/arm/mach-s3c2410/include/mach/bast-pmu.h [deleted file]
arch/arm/mach-s3c2410/include/mach/debug-macro.S [deleted file]
arch/arm/mach-s3c2410/include/mach/dma.h [deleted file]
arch/arm/mach-s3c2410/include/mach/entry-macro.S [deleted file]
arch/arm/mach-s3c2410/include/mach/fb.h [deleted file]
arch/arm/mach-s3c2410/include/mach/gpio-fns.h [deleted file]
arch/arm/mach-s3c2410/include/mach/gpio-nrs.h [deleted file]
arch/arm/mach-s3c2410/include/mach/gpio-track.h [deleted file]
arch/arm/mach-s3c2410/include/mach/gpio.h [deleted file]
arch/arm/mach-s3c2410/include/mach/h1940-latch.h [deleted file]
arch/arm/mach-s3c2410/include/mach/h1940.h [deleted file]
arch/arm/mach-s3c2410/include/mach/hardware.h [deleted file]
arch/arm/mach-s3c2410/include/mach/idle.h [deleted file]
arch/arm/mach-s3c2410/include/mach/io.h [deleted file]
arch/arm/mach-s3c2410/include/mach/irqs.h [deleted file]
arch/arm/mach-s3c2410/include/mach/leds-gpio.h [deleted file]
arch/arm/mach-s3c2410/include/mach/map.h [deleted file]
arch/arm/mach-s3c2410/include/mach/osiris-cpld.h [deleted file]
arch/arm/mach-s3c2410/include/mach/osiris-map.h [deleted file]
arch/arm/mach-s3c2410/include/mach/otom-map.h [deleted file]
arch/arm/mach-s3c2410/include/mach/pm-core.h [deleted file]
arch/arm/mach-s3c2410/include/mach/regs-clock.h [deleted file]
arch/arm/mach-s3c2410/include/mach/regs-dsc.h [deleted file]
arch/arm/mach-s3c2410/include/mach/regs-gpio.h [deleted file]
arch/arm/mach-s3c2410/include/mach/regs-gpioj.h [deleted file]
arch/arm/mach-s3c2410/include/mach/regs-irq.h [deleted file]
arch/arm/mach-s3c2410/include/mach/regs-lcd.h [deleted file]
arch/arm/mach-s3c2410/include/mach/regs-mem.h [deleted file]
arch/arm/mach-s3c2410/include/mach/regs-power.h [deleted file]
arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h [deleted file]
arch/arm/mach-s3c2410/include/mach/regs-s3c2412.h [deleted file]
arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h [deleted file]
arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h [deleted file]
arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h [deleted file]
arch/arm/mach-s3c2410/include/mach/regs-sdi.h [deleted file]
arch/arm/mach-s3c2410/include/mach/spi.h [deleted file]
arch/arm/mach-s3c2410/include/mach/tick.h [deleted file]
arch/arm/mach-s3c2410/include/mach/timex.h [deleted file]
arch/arm/mach-s3c2410/include/mach/uncompress.h [deleted file]
arch/arm/mach-s3c2410/include/mach/vr1000-cpld.h [deleted file]
arch/arm/mach-s3c2410/include/mach/vr1000-irq.h [deleted file]
arch/arm/mach-s3c2410/include/mach/vr1000-map.h [deleted file]
arch/arm/mach-s3c2410/mach-amlm5900.c [deleted file]
arch/arm/mach-s3c2410/mach-bast.c [deleted file]
arch/arm/mach-s3c2410/mach-h1940.c [deleted file]
arch/arm/mach-s3c2410/mach-n30.c [deleted file]
arch/arm/mach-s3c2410/mach-otom.c [deleted file]
arch/arm/mach-s3c2410/mach-qt2410.c [deleted file]
arch/arm/mach-s3c2410/mach-smdk2410.c [deleted file]
arch/arm/mach-s3c2410/mach-tct_hammer.c [deleted file]
arch/arm/mach-s3c2410/mach-vr1000.c [deleted file]
arch/arm/mach-s3c2410/nor-simtec.c [deleted file]
arch/arm/mach-s3c2410/nor-simtec.h [deleted file]
arch/arm/mach-s3c2410/pm-h1940.S [deleted file]
arch/arm/mach-s3c2410/pm.c [deleted file]
arch/arm/mach-s3c2410/s3c2410.c [deleted file]
arch/arm/mach-s3c2410/sleep.S [deleted file]
arch/arm/mach-s3c2410/usb-simtec.c [deleted file]
arch/arm/mach-s3c2410/usb-simtec.h [deleted file]
arch/arm/mach-s3c2412/Kconfig
arch/arm/mach-s3c2412/Makefile
arch/arm/mach-s3c2412/clock.c [deleted file]
arch/arm/mach-s3c2412/dma.c [deleted file]
arch/arm/mach-s3c2412/irq.c [deleted file]
arch/arm/mach-s3c2412/mach-jive.c [deleted file]
arch/arm/mach-s3c2412/mach-smdk2413.c [deleted file]
arch/arm/mach-s3c2412/mach-vstms.c [deleted file]
arch/arm/mach-s3c2412/pm.c [deleted file]
arch/arm/mach-s3c2412/s3c2412.c [deleted file]
arch/arm/mach-s3c2412/sleep.S [deleted file]
arch/arm/mach-s3c2416/Kconfig [deleted file]
arch/arm/mach-s3c2416/Makefile [deleted file]
arch/arm/mach-s3c2416/clock.c [deleted file]
arch/arm/mach-s3c2416/irq.c [deleted file]
arch/arm/mach-s3c2416/mach-smdk2416.c [deleted file]
arch/arm/mach-s3c2416/pm.c [deleted file]
arch/arm/mach-s3c2416/s3c2416.c [deleted file]
arch/arm/mach-s3c2416/setup-sdhci-gpio.c [deleted file]
arch/arm/mach-s3c2440/Kconfig
arch/arm/mach-s3c2440/Makefile
arch/arm/mach-s3c2440/clock.c [deleted file]
arch/arm/mach-s3c2440/common.h [deleted file]
arch/arm/mach-s3c2440/dma.c [deleted file]
arch/arm/mach-s3c2440/include/mach/gta02.h [deleted file]
arch/arm/mach-s3c2440/irq.c [deleted file]
arch/arm/mach-s3c2440/mach-anubis.c [deleted file]
arch/arm/mach-s3c2440/mach-at2440evb.c [deleted file]
arch/arm/mach-s3c2440/mach-gta02.c [deleted file]
arch/arm/mach-s3c2440/mach-mini2440.c [deleted file]
arch/arm/mach-s3c2440/mach-nexcoder.c [deleted file]
arch/arm/mach-s3c2440/mach-osiris-dvs.c [deleted file]
arch/arm/mach-s3c2440/mach-osiris.c [deleted file]
arch/arm/mach-s3c2440/mach-rx1950.c [deleted file]
arch/arm/mach-s3c2440/mach-rx3715.c [deleted file]
arch/arm/mach-s3c2440/mach-smdk2440.c [deleted file]
arch/arm/mach-s3c2440/s3c2440.c [deleted file]
arch/arm/mach-s3c2440/s3c2442.c [deleted file]
arch/arm/mach-s3c2440/s3c244x-clock.c [deleted file]
arch/arm/mach-s3c2440/s3c244x-irq.c [deleted file]
arch/arm/mach-s3c2440/s3c244x.c [deleted file]
arch/arm/mach-s3c2443/Kconfig [deleted file]
arch/arm/mach-s3c2443/Makefile [deleted file]
arch/arm/mach-s3c2443/clock.c [deleted file]
arch/arm/mach-s3c2443/dma.c [deleted file]
arch/arm/mach-s3c2443/irq.c [deleted file]
arch/arm/mach-s3c2443/mach-smdk2443.c [deleted file]
arch/arm/mach-s3c2443/s3c2443.c [deleted file]
arch/arm/mach-s3c24xx/Kconfig [new file with mode: 0644]
arch/arm/mach-s3c24xx/Makefile [new file with mode: 0644]
arch/arm/mach-s3c24xx/Makefile.boot [new file with mode: 0644]
arch/arm/mach-s3c24xx/bast-ide.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/bast-irq.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/clock-s3c2412.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/clock-s3c2416.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/clock-s3c2440.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/clock-s3c2443.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/clock-s3c244x.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/common-s3c2443.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/common-smdk.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/dma-s3c2410.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/dma-s3c2412.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/dma-s3c2440.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/dma-s3c2443.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/h1940-bluetooth.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/anubis-cpld.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/anubis-irq.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/anubis-map.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/bast-cpld.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/bast-irq.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/bast-map.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/bast-pmu.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/debug-macro.S [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/dma.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/entry-macro.S [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/fb.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/gpio-fns.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/gpio-nrs.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/gpio-track.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/gpio.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/gta02.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/h1940-latch.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/h1940.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/hardware.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/idle.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/io.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/irqs.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/leds-gpio.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/map.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/osiris-cpld.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/osiris-map.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/otom-map.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/pm-core.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/regs-clock.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/regs-dsc.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/regs-gpio.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/regs-gpioj.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/regs-irq.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/regs-lcd.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/regs-mem.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/regs-power.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/regs-s3c2412-mem.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/regs-s3c2412.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/regs-s3c2416-mem.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/regs-s3c2416.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/regs-s3c2443-clock.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/regs-sdi.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/tick.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/timex.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/uncompress.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/vr1000-cpld.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/vr1000-irq.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/include/mach/vr1000-map.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/irq-s3c2412.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/irq-s3c2416.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/irq-s3c2440.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/irq-s3c2443.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/irq-s3c244x.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-amlm5900.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-anubis.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-at2440evb.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-bast.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-gta02.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-h1940.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-jive.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-mini2440.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-n30.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-nexcoder.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-osiris-dvs.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-osiris.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-otom.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-qt2410.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-rx1950.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-rx3715.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-smdk2410.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-smdk2413.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-smdk2416.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-smdk2440.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-smdk2443.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-tct_hammer.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-vr1000.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/mach-vstms.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/pm-h1940.S [new file with mode: 0644]
arch/arm/mach-s3c24xx/pm-s3c2410.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/pm-s3c2412.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/pm-s3c2416.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/s3c2410.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/s3c2412.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/s3c2416.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/s3c2440.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/s3c2442.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/s3c2443.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/s3c244x.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/setup-i2c.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/setup-sdhci-gpio.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/setup-ts.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/simtec-audio.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/simtec-nor.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/simtec-pm.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/simtec-usb.c [new file with mode: 0644]
arch/arm/mach-s3c24xx/simtec.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/sleep-s3c2410.S [new file with mode: 0644]
arch/arm/mach-s3c24xx/sleep-s3c2412.S [new file with mode: 0644]
arch/arm/mach-s3c64xx/Kconfig
arch/arm/mach-s3c64xx/Makefile
arch/arm/mach-s3c64xx/clock.c
arch/arm/mach-s3c64xx/common.h
arch/arm/mach-s3c64xx/cpuidle.c [new file with mode: 0644]
arch/arm/mach-s3c64xx/irq-pm.c
arch/arm/mach-s3c64xx/mach-crag6410-module.c
arch/arm/mach-s3c64xx/mach-crag6410.c
arch/arm/mach-s3c64xx/mach-smartq.c
arch/arm/mach-s3c64xx/mach-smdk6410.c
arch/arm/mach-s3c64xx/setup-usb-phy.c [new file with mode: 0644]
arch/arm/mach-s5p64x0/clock.c
arch/arm/mach-s5p64x0/dma.c
arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h
arch/arm/mach-s5pc100/clock.c
arch/arm/mach-s5pc100/dma.c
arch/arm/mach-s5pv210/Kconfig
arch/arm/mach-s5pv210/Makefile
arch/arm/mach-s5pv210/clock.c
arch/arm/mach-s5pv210/dma.c
arch/arm/mach-s5pv210/include/mach/map.h
arch/arm/mach-s5pv210/include/mach/regs-sys.h
arch/arm/mach-s5pv210/mach-aquila.c
arch/arm/mach-s5pv210/mach-goni.c
arch/arm/mach-s5pv210/mach-smdkc110.c
arch/arm/mach-s5pv210/mach-smdkv210.c
arch/arm/mach-s5pv210/setup-usb-phy.c [new file with mode: 0644]
arch/arm/mach-sa1100/Makefile
arch/arm/mach-sa1100/assabet.c
arch/arm/mach-sa1100/badge4.c
arch/arm/mach-sa1100/cerf.c
arch/arm/mach-sa1100/clock.c
arch/arm/mach-sa1100/collie.c
arch/arm/mach-sa1100/dma.c [deleted file]
arch/arm/mach-sa1100/generic.c
arch/arm/mach-sa1100/generic.h
arch/arm/mach-sa1100/h3100.c
arch/arm/mach-sa1100/h3600.c
arch/arm/mach-sa1100/h3xxx.c
arch/arm/mach-sa1100/hackkit.c
arch/arm/mach-sa1100/include/mach/SA-1100.h
arch/arm/mach-sa1100/include/mach/dma.h [deleted file]
arch/arm/mach-sa1100/include/mach/irqs.h
arch/arm/mach-sa1100/include/mach/mcp.h
arch/arm/mach-sa1100/include/mach/neponset.h
arch/arm/mach-sa1100/include/mach/shannon.h
arch/arm/mach-sa1100/irq.c
arch/arm/mach-sa1100/jornada720.c
arch/arm/mach-sa1100/lart.c
arch/arm/mach-sa1100/nanoengine.c
arch/arm/mach-sa1100/neponset.c
arch/arm/mach-sa1100/pci-nanoengine.c
arch/arm/mach-sa1100/pleb.c
arch/arm/mach-sa1100/shannon.c
arch/arm/mach-sa1100/simpad.c
arch/arm/mach-sa1100/sleep.S
arch/arm/mach-sa1100/ssp.c
arch/arm/mach-sa1100/time.c
arch/arm/mach-shmobile/Makefile
arch/arm/mach-shmobile/board-ag5evm.c
arch/arm/mach-shmobile/board-ap4evb.c
arch/arm/mach-shmobile/board-bonito.c
arch/arm/mach-shmobile/board-g3evm.c
arch/arm/mach-shmobile/board-g4evm.c
arch/arm/mach-shmobile/board-kota2.c
arch/arm/mach-shmobile/board-mackerel.c
arch/arm/mach-shmobile/board-marzen.c
arch/arm/mach-shmobile/clock-r8a7740.c
arch/arm/mach-shmobile/clock-r8a7779.c
arch/arm/mach-shmobile/clock-sh7367.c
arch/arm/mach-shmobile/clock-sh7372.c
arch/arm/mach-shmobile/clock-sh7377.c
arch/arm/mach-shmobile/clock-sh73a0.c
arch/arm/mach-shmobile/clock.c
arch/arm/mach-shmobile/include/mach/common.h
arch/arm/mach-shmobile/localtimer.c [deleted file]
arch/arm/mach-shmobile/platsmp.c
arch/arm/mach-shmobile/setup-r8a7740.c
arch/arm/mach-shmobile/setup-r8a7779.c
arch/arm/mach-shmobile/setup-sh7367.c
arch/arm/mach-shmobile/setup-sh7372.c
arch/arm/mach-shmobile/setup-sh7377.c
arch/arm/mach-shmobile/setup-sh73a0.c
arch/arm/mach-shmobile/smp-r8a7779.c
arch/arm/mach-shmobile/smp-sh73a0.c
arch/arm/mach-shmobile/timer.c
arch/arm/mach-spear6xx/Kconfig
arch/arm/mach-spear6xx/Makefile
arch/arm/mach-spear6xx/clock.c
arch/arm/mach-spear6xx/spear600.c [deleted file]
arch/arm/mach-spear6xx/spear600_evb.c [deleted file]
arch/arm/mach-spear6xx/spear6xx.c
arch/arm/mach-tegra/Kconfig
arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/apbio.c [new file with mode: 0644]
arch/arm/mach-tegra/apbio.h [new file with mode: 0644]
arch/arm/mach-tegra/board-dt-tegra20.c
arch/arm/mach-tegra/board-dt-tegra30.c
arch/arm/mach-tegra/board-harmony-pinmux.c
arch/arm/mach-tegra/board-harmony-power.c
arch/arm/mach-tegra/board-harmony.c
arch/arm/mach-tegra/board-seaboard.c
arch/arm/mach-tegra/clock.c
arch/arm/mach-tegra/clock.h
arch/arm/mach-tegra/common.c
arch/arm/mach-tegra/cpuidle.c [new file with mode: 0644]
arch/arm/mach-tegra/dma.c
arch/arm/mach-tegra/flowctrl.c [new file with mode: 0644]
arch/arm/mach-tegra/flowctrl.h [new file with mode: 0644]
arch/arm/mach-tegra/fuse.c
arch/arm/mach-tegra/fuse.h
arch/arm/mach-tegra/headsmp.S
arch/arm/mach-tegra/include/mach/clk.h
arch/arm/mach-tegra/include/mach/debug-macro.S
arch/arm/mach-tegra/include/mach/gpio-tegra.h
arch/arm/mach-tegra/include/mach/iomap.h
arch/arm/mach-tegra/include/mach/irammap.h [new file with mode: 0644]
arch/arm/mach-tegra/include/mach/irqs.h
arch/arm/mach-tegra/include/mach/powergate.h
arch/arm/mach-tegra/include/mach/uncompress.h
arch/arm/mach-tegra/irq.c
arch/arm/mach-tegra/localtimer.c [deleted file]
arch/arm/mach-tegra/pcie.c
arch/arm/mach-tegra/platsmp.c
arch/arm/mach-tegra/pmc.c [new file with mode: 0644]
arch/arm/mach-tegra/pmc.h [new file with mode: 0644]
arch/arm/mach-tegra/powergate.c
arch/arm/mach-tegra/reset.c [new file with mode: 0644]
arch/arm/mach-tegra/reset.h [new file with mode: 0644]
arch/arm/mach-tegra/sleep.S [new file with mode: 0644]
arch/arm/mach-tegra/tegra2_clocks.c
arch/arm/mach-tegra/tegra2_emc.c
arch/arm/mach-tegra/tegra2_emc.h
arch/arm/mach-tegra/tegra30_clocks.c [new file with mode: 0644]
arch/arm/mach-tegra/timer.c
arch/arm/mach-tegra/usb_phy.c
arch/arm/mach-ux500/Kconfig
arch/arm/mach-ux500/Makefile
arch/arm/mach-ux500/Makefile.boot
arch/arm/mach-ux500/board-mop500-regulators.c
arch/arm/mach-ux500/board-mop500-sdi.c
arch/arm/mach-ux500/board-mop500-u8500uib.c
arch/arm/mach-ux500/board-mop500.c
arch/arm/mach-ux500/board-mop500.h
arch/arm/mach-ux500/board-u5500-sdi.c
arch/arm/mach-ux500/board-u5500.c
arch/arm/mach-ux500/cache-l2x0.c
arch/arm/mach-ux500/clock.c
arch/arm/mach-ux500/clock.h
arch/arm/mach-ux500/cpu-db5500.c
arch/arm/mach-ux500/cpu-db8500.c
arch/arm/mach-ux500/cpu.c
arch/arm/mach-ux500/devices-common.c
arch/arm/mach-ux500/devices-common.h
arch/arm/mach-ux500/devices-db5500.h
arch/arm/mach-ux500/devices-db8500.c
arch/arm/mach-ux500/devices-db8500.h
arch/arm/mach-ux500/dma-db5500.c
arch/arm/mach-ux500/include/mach/db8500-regs.h
arch/arm/mach-ux500/include/mach/hardware.h
arch/arm/mach-ux500/include/mach/irqs.h
arch/arm/mach-ux500/include/mach/setup.h
arch/arm/mach-ux500/include/mach/usb.h
arch/arm/mach-ux500/localtimer.c [deleted file]
arch/arm/mach-ux500/timer.c
arch/arm/mach-ux500/usb.c
arch/arm/mach-vexpress/Kconfig
arch/arm/mach-vexpress/Makefile.boot
arch/arm/mach-vexpress/core.h
arch/arm/mach-vexpress/ct-ca9x4.c
arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
arch/arm/mach-vexpress/include/mach/debug-macro.S
arch/arm/mach-vexpress/include/mach/irqs.h
arch/arm/mach-vexpress/include/mach/motherboard.h
arch/arm/mach-vexpress/include/mach/uncompress.h
arch/arm/mach-vexpress/platsmp.c
arch/arm/mach-vexpress/v2m.c
arch/arm/plat-mxc/avic.c
arch/arm/plat-mxc/cpu.c
arch/arm/plat-mxc/devices/platform-ahci-imx.c
arch/arm/plat-mxc/epit.c
arch/arm/plat-mxc/include/mach/board-mx31ads.h [deleted file]
arch/arm/plat-mxc/include/mach/common.h
arch/arm/plat-mxc/include/mach/debug-macro.S
arch/arm/plat-mxc/include/mach/dma.h
arch/arm/plat-mxc/include/mach/iomux-mx25.h
arch/arm/plat-mxc/pwm.c
arch/arm/plat-mxc/system.c
arch/arm/plat-mxc/time.c
arch/arm/plat-nomadik/include/plat/mtu.h
arch/arm/plat-nomadik/timer.c
arch/arm/plat-omap/Kconfig
arch/arm/plat-omap/clock.c
arch/arm/plat-omap/counter_32k.c
arch/arm/plat-omap/dma.c
arch/arm/plat-omap/dmtimer.c
arch/arm/plat-omap/include/plat/board-ams-delta.h
arch/arm/plat-omap/include/plat/cpu.h
arch/arm/plat-omap/include/plat/gpio.h
arch/arm/plat-omap/include/plat/hardware.h
arch/arm/plat-omap/include/plat/io.h [deleted file]
arch/arm/plat-omap/include/plat/keypad.h
arch/arm/plat-omap/include/plat/mcspi.h
arch/arm/plat-omap/include/plat/omap_device.h
arch/arm/plat-omap/include/plat/omap_hwmod.h
arch/arm/plat-omap/include/plat/remoteproc.h [new file with mode: 0644]
arch/arm/plat-omap/include/plat/serial.h
arch/arm/plat-omap/include/plat/sram.h
arch/arm/plat-omap/include/plat/tc.h
arch/arm/plat-omap/include/plat/uncompress.h
arch/arm/plat-omap/include/plat/usb.h
arch/arm/plat-omap/mailbox.c
arch/arm/plat-omap/mux.c
arch/arm/plat-omap/omap-pm-noop.c
arch/arm/plat-omap/omap_device.c
arch/arm/plat-omap/sram.c
arch/arm/plat-omap/usb.c
arch/arm/plat-orion/common.c
arch/arm/plat-orion/include/plat/audio.h
arch/arm/plat-s3c24xx/Kconfig
arch/arm/plat-s3c24xx/Makefile
arch/arm/plat-s3c24xx/common-smdk.c [deleted file]
arch/arm/plat-s3c24xx/pm-simtec.c [deleted file]
arch/arm/plat-s3c24xx/s3c2443-clock.c [deleted file]
arch/arm/plat-s3c24xx/setup-i2c.c [deleted file]
arch/arm/plat-s3c24xx/setup-ts.c [deleted file]
arch/arm/plat-s3c24xx/simtec-audio.c [deleted file]
arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c [deleted file]
arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c [deleted file]
arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c [deleted file]
arch/arm/plat-s5p/Kconfig
arch/arm/plat-s5p/Makefile
arch/arm/plat-s5p/clock.c
arch/arm/plat-s5p/irq-eint.c
arch/arm/plat-s5p/irq-gpioint.c
arch/arm/plat-s5p/irq-pm.c
arch/arm/plat-s5p/sleep.S
arch/arm/plat-samsung/Kconfig
arch/arm/plat-samsung/clock.c
arch/arm/plat-samsung/dev-backlight.c
arch/arm/plat-samsung/devs.c
arch/arm/plat-samsung/dma-ops.c
arch/arm/plat-samsung/include/plat/audio-simtec.h
arch/arm/plat-samsung/include/plat/clock.h
arch/arm/plat-samsung/include/plat/cpu.h
arch/arm/plat-samsung/include/plat/devs.h
arch/arm/plat-samsung/include/plat/dma-pl330.h
arch/arm/plat-samsung/include/plat/regs-dma.h
arch/arm/plat-samsung/include/plat/regs-rtc.h
arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h
arch/arm/plat-samsung/include/plat/rtc-core.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/s3c2410.h
arch/arm/plat-samsung/include/plat/s3c2443.h
arch/arm/plat-samsung/include/plat/s5p-clock.h
arch/arm/plat-samsung/include/plat/sdhci.h
arch/arm/plat-samsung/include/plat/udc-hs.h
arch/arm/plat-samsung/include/plat/uncompress.h
arch/arm/plat-samsung/irq-vic-timer.c
arch/arm/plat-samsung/platformdata.c
arch/arm/plat-versatile/Makefile
arch/arm/plat-versatile/localtimer.c [deleted file]
arch/avr32/boards/atngw100/setup.c
arch/avr32/boards/atstk1000/atstk1002.c
arch/avr32/mach-at32ap/at32ap700x.c
arch/avr32/mach-at32ap/include/mach/board.h
arch/avr32/mach-at32ap/include/mach/cpu.h
arch/microblaze/Kconfig
arch/microblaze/boot/Makefile
arch/microblaze/include/asm/fixmap.h [new file with mode: 0644]
arch/microblaze/include/asm/highmem.h [new file with mode: 0644]
arch/microblaze/include/asm/mmu.h
arch/microblaze/include/asm/page.h
arch/microblaze/include/asm/pgtable.h
arch/microblaze/include/asm/setup.h
arch/microblaze/include/asm/system.h
arch/microblaze/include/asm/uaccess.h
arch/microblaze/kernel/cpu/cpuinfo.c
arch/microblaze/kernel/early_printk.c
arch/microblaze/kernel/head.S
arch/microblaze/kernel/hw_exception_handler.S
arch/microblaze/kernel/intc.c
arch/microblaze/kernel/misc.S
arch/microblaze/kernel/setup.c
arch/microblaze/kernel/timer.c
arch/microblaze/kernel/vmlinux.lds.S
arch/microblaze/mm/Makefile
arch/microblaze/mm/highmem.c [new file with mode: 0644]
arch/microblaze/mm/init.c
arch/microblaze/mm/pgtable.c
arch/s390/Kconfig
arch/s390/include/asm/cpu_mf.h [new file with mode: 0644]
arch/s390/include/asm/irq.h
arch/s390/include/asm/perf_event.h
arch/s390/kernel/Makefile
arch/s390/kernel/irq.c
arch/s390/kernel/perf_cpum_cf.c [new file with mode: 0644]
arch/s390/kernel/perf_event.c [new file with mode: 0644]
arch/s390/mm/mmap.c
arch/s390/oprofile/hwsampler.c
arch/sh/boards/mach-highlander/setup.c
arch/sh/boards/mach-sdk7786/setup.c
arch/sh/include/asm/clock.h
arch/sh/kernel/cpu/sh2/clock-sh7619.c
arch/sh/kernel/cpu/sh2a/clock-sh7201.c
arch/sh/kernel/cpu/sh2a/clock-sh7203.c
arch/sh/kernel/cpu/sh2a/clock-sh7206.c
arch/sh/kernel/cpu/sh3/clock-sh3.c
arch/sh/kernel/cpu/sh3/clock-sh7705.c
arch/sh/kernel/cpu/sh3/clock-sh7706.c
arch/sh/kernel/cpu/sh3/clock-sh7709.c
arch/sh/kernel/cpu/sh3/clock-sh7710.c
arch/sh/kernel/cpu/sh3/clock-sh7712.c
arch/sh/kernel/cpu/sh4/clock-sh4-202.c
arch/sh/kernel/cpu/sh4/clock-sh4.c
arch/sh/kernel/cpu/sh4a/clock-sh7343.c
arch/sh/kernel/cpu/sh4a/clock-sh7366.c
arch/sh/kernel/cpu/sh4a/clock-sh7722.c
arch/sh/kernel/cpu/sh4a/clock-sh7723.c
arch/sh/kernel/cpu/sh4a/clock-sh7724.c
arch/sh/kernel/cpu/sh4a/clock-sh7757.c
arch/sh/kernel/cpu/sh4a/clock-sh7763.c
arch/sh/kernel/cpu/sh4a/clock-sh7770.c
arch/sh/kernel/cpu/sh4a/clock-sh7780.c
arch/sh/kernel/cpu/sh4a/clock-sh7785.c
arch/sh/kernel/cpu/sh4a/clock-sh7786.c
arch/sh/kernel/cpu/sh4a/clock-shx3.c
arch/sh/kernel/cpu/sh5/clock-sh5.c
arch/um/Kconfig.common
arch/um/Makefile
arch/um/defconfig
arch/um/drivers/chan.h
arch/um/drivers/chan_kern.c
arch/um/drivers/chan_user.h
arch/um/drivers/line.c
arch/um/drivers/line.h
arch/um/drivers/mconsole_kern.c
arch/um/drivers/net_kern.c
arch/um/drivers/port_kern.c
arch/um/drivers/random.c
arch/um/drivers/ssl.c
arch/um/drivers/stdio_console.c
arch/um/drivers/ubd.h [new file with mode: 0644]
arch/um/drivers/ubd_kern.c
arch/um/drivers/ubd_user.c
arch/um/drivers/ubd_user.h [deleted file]
arch/um/drivers/xterm_kern.c
arch/um/include/asm/Kbuild
arch/um/include/asm/asm-offsets.h [deleted file]
arch/um/include/asm/auxvec.h [deleted file]
arch/um/include/asm/current.h [deleted file]
arch/um/include/asm/delay.h [deleted file]
arch/um/include/asm/io.h [deleted file]
arch/um/include/asm/mutex.h [deleted file]
arch/um/include/asm/param.h [deleted file]
arch/um/include/asm/pci.h [deleted file]
arch/um/include/asm/pgalloc.h
arch/um/include/asm/pgtable.h
arch/um/include/asm/ptrace-generic.h
arch/um/include/shared/common-offsets.h
arch/um/include/shared/kern_util.h
arch/um/kernel/Makefile
arch/um/kernel/process.c
arch/um/kernel/sigio.c
arch/um/kernel/time.c
arch/um/os-Linux/Makefile
arch/um/os-Linux/user_syms.c
arch/um/scripts/Makefile.rules
arch/x86/Makefile.um
arch/x86/um/Kconfig
arch/x86/um/asm/processor.h
arch/x86/um/asm/processor_32.h
arch/x86/um/asm/processor_64.h
arch/x86/um/bugs_32.c
drivers/Kconfig
drivers/Makefile
drivers/block/rbd.c
drivers/block/rbd_types.h
drivers/char/hw_random/omap-rng.c
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/clk-divider.c [new file with mode: 0644]
drivers/clk/clk-fixed-rate.c [new file with mode: 0644]
drivers/clk/clk-gate.c [new file with mode: 0644]
drivers/clk/clk-mux.c [new file with mode: 0644]
drivers/clk/clk.c [new file with mode: 0644]
drivers/clocksource/tcb_clksrc.c
drivers/devfreq/exynos4_bus.c
drivers/dma/Kconfig
drivers/dma/Makefile
drivers/dma/sa11x0-dma.c [new file with mode: 0644]
drivers/gpio/gpio-ep93xx.c
drivers/gpio/gpio-omap.c
drivers/gpio/gpio-sa1100.c
drivers/gpio/gpio-samsung.c
drivers/gpio/gpio-tegra.c
drivers/gpu/drm/gma500/mdfld_dsi_output.c
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_i2c.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/atombios_dp.c
drivers/gpu/drm/radeon/atombios_encoders.c
drivers/gpu/drm/radeon/evergreen_cs.c
drivers/gpu/drm/radeon/evergreend.h
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/radeon_object.c
drivers/gpu/drm/radeon/reg_srcs/cayman
drivers/gpu/drm/radeon/reg_srcs/evergreen
drivers/gpu/drm/radeon/reg_srcs/r600
drivers/i2c/busses/i2c-gpio.c
drivers/i2c/busses/i2c-imx.c
drivers/i2c/busses/i2c-pxa.c
drivers/input/keyboard/jornada720_kbd.c
drivers/input/serio/ams_delta_serio.c
drivers/input/serio/rpckbd.c
drivers/input/serio/sa1111ps2.c
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/jornada720_ts.c
drivers/leds/Kconfig
drivers/leds/Makefile
drivers/leds/leds-ams-delta.c [deleted file]
drivers/md/Kconfig
drivers/md/Makefile
drivers/md/dm-bufio.c
drivers/md/dm-bufio.h
drivers/md/dm-crypt.c
drivers/md/dm-delay.c
drivers/md/dm-exception-store.c
drivers/md/dm-flakey.c
drivers/md/dm-ioctl.c
drivers/md/dm-linear.c
drivers/md/dm-log.c
drivers/md/dm-mpath.c
drivers/md/dm-queue-length.c
drivers/md/dm-raid.c
drivers/md/dm-raid1.c
drivers/md/dm-round-robin.c
drivers/md/dm-service-time.c
drivers/md/dm-stripe.c
drivers/md/dm-table.c
drivers/md/dm-thin-metadata.c
drivers/md/dm-thin-metadata.h
drivers/md/dm-thin.c
drivers/md/dm-verity.c [new file with mode: 0644]
drivers/md/dm.c
drivers/md/persistent-data/dm-btree-internal.h
drivers/md/persistent-data/dm-btree-remove.c
drivers/md/persistent-data/dm-btree.c
drivers/md/persistent-data/dm-space-map-common.c
drivers/mfd/Kconfig
drivers/mfd/mcp-core.c
drivers/mfd/mcp-sa11x0.c
drivers/mfd/ucb1x00-assabet.c
drivers/mfd/ucb1x00-core.c
drivers/mfd/ucb1x00-ts.c
drivers/misc/atmel_tclib.c
drivers/mmc/host/Kconfig
drivers/mmc/host/at91_mci.c
drivers/mmc/host/sdhci-esdhc-imx.c
drivers/mmc/host/sdhci-s3c.c
drivers/mtd/Kconfig
drivers/mtd/devices/Kconfig
drivers/mtd/maps/Kconfig
drivers/mtd/maps/sa1100-flash.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/ams-delta.c
drivers/mtd/nand/atmel_nand.c
drivers/mtd/onenand/Kconfig
drivers/net/Space.c
drivers/net/ethernet/cirrus/Kconfig
drivers/net/ethernet/cirrus/cs89x0.c
drivers/net/ethernet/freescale/gianfar.c
drivers/net/ethernet/freescale/gianfar.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
drivers/net/ethernet/smsc/smc91x.c
drivers/net/irda/Kconfig
drivers/net/irda/sa1100_ir.c
drivers/net/usb/cdc-phonet.c
drivers/net/usb/qmi_wwan.c
drivers/net/wireless/iwlegacy/3945.c
drivers/net/wireless/iwlegacy/4965-mac.c
drivers/net/wireless/iwlwifi/iwl-agn-rx.c
drivers/of/Kconfig
drivers/of/Makefile
drivers/of/of_mtd.c [new file with mode: 0644]
drivers/pcmcia/at91_cf.c
drivers/pcmcia/sa1111_generic.c
drivers/pcmcia/sa1111_neponset.c
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/bq24022.c [deleted file]
drivers/remoteproc/Kconfig [new file with mode: 0644]
drivers/remoteproc/Makefile [new file with mode: 0644]
drivers/remoteproc/omap_remoteproc.c [new file with mode: 0644]
drivers/remoteproc/omap_remoteproc.h [new file with mode: 0644]
drivers/remoteproc/remoteproc_core.c [new file with mode: 0644]
drivers/remoteproc/remoteproc_debugfs.c [new file with mode: 0644]
drivers/remoteproc/remoteproc_internal.h [new file with mode: 0644]
drivers/remoteproc/remoteproc_virtio.c [new file with mode: 0644]
drivers/rpmsg/Kconfig [new file with mode: 0644]
drivers/rpmsg/Makefile [new file with mode: 0644]
drivers/rpmsg/virtio_rpmsg_bus.c [new file with mode: 0644]
drivers/rtc/Kconfig
drivers/rtc/rtc-at91sam9.c
drivers/rtc/rtc-mv.c
drivers/rtc/rtc-s3c.c
drivers/rtc/rtc-sa1100.c
drivers/s390/cio/qdio_main.c
drivers/s390/cio/qdio_setup.c
drivers/scsi/arm/arxescsi.c
drivers/scsi/arm/fas216.c
drivers/scsi/arm/fas216.h
drivers/sh/clk/cpg.c
drivers/spi/Kconfig
drivers/spi/spi-orion.c
drivers/spi/spi-s3c24xx.c
drivers/staging/ste_rmi4/Makefile
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/imx.c
drivers/tty/serial/pxa.c
drivers/tty/serial/sa1100.c
drivers/usb/Kconfig
drivers/usb/gadget/Kconfig
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/atmel_usba_udc.c
drivers/usb/gadget/f_phonet.c
drivers/usb/host/ehci-atmel.c
drivers/usb/host/ohci-at91.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-sa1111.c
drivers/usb/serial/option.c
drivers/vhost/net.c
drivers/vhost/vhost.c
drivers/vhost/vhost.h
drivers/video/Kconfig
drivers/video/backlight/ep93xx_bl.c
drivers/video/ep93xx-fb.c
drivers/video/omap/lcd_ams_delta.c
drivers/video/omap2/dss/dispc.c
drivers/video/omap2/dss/dss.c
drivers/video/sa1100fb.c
drivers/video/sa1100fb.h
drivers/watchdog/Kconfig
drivers/watchdog/at91rm9200_wdt.c
drivers/watchdog/orion_wdt.c
fs/9p/vfs_super.c
fs/ceph/inode.c
fs/ceph/mds_client.c
fs/ceph/snap.c
fs/ceph/super.c
fs/ceph/super.h
fs/ceph/xattr.c
fs/dcache.c
fs/ext3/balloc.c
fs/ext3/inode.c
fs/ext4/balloc.c
fs/ext4/dir.c
fs/ext4/ext4.h
fs/ext4/ext4_extents.h
fs/ext4/ext4_jbd2.h
fs/ext4/extents.c
fs/ext4/fsync.c
fs/ext4/ialloc.c
fs/ext4/inode.c
fs/ext4/mballoc.c
fs/ext4/mballoc.h
fs/ext4/migrate.c
fs/ext4/mmp.c
fs/ext4/namei.c
fs/ext4/page-io.c
fs/ext4/resize.c
fs/ext4/super.c
fs/ext4/xattr.c
fs/fs-writeback.c
fs/hostfs/hostfs.h
fs/hostfs/hostfs_kern.c
fs/hostfs/hostfs_user.c
fs/jbd2/checkpoint.c
fs/jbd2/commit.c
fs/jbd2/journal.c
fs/jbd2/recovery.c
fs/jbd2/revoke.c
fs/jbd2/transaction.c
fs/quota/dquot.c
fs/udf/balloc.c
fs/udf/ialloc.c
fs/udf/inode.c
fs/udf/super.c
fs/udf/udf_i.h
include/linux/atmel_tc.h
include/linux/ceph/libceph.h
include/linux/ceph/messenger.h
include/linux/clk-private.h [new file with mode: 0644]
include/linux/clk-provider.h [new file with mode: 0644]
include/linux/clk.h
include/linux/fs.h
include/linux/jbd2.h
include/linux/journal-head.h
include/linux/mfd/mcp.h
include/linux/mfd/ucb1x00.h
include/linux/mod_devicetable.h
include/linux/of.h
include/linux/of_mtd.h [new file with mode: 0644]
include/linux/platform_data/atmel.h [new file with mode: 0644]
include/linux/platform_data/tegra_emc.h [new file with mode: 0644]
include/linux/regulator/bq24022.h [deleted file]
include/linux/remoteproc.h [new file with mode: 0644]
include/linux/rpmsg.h [new file with mode: 0644]
include/linux/sa11x0-dma.h [new file with mode: 0644]
include/linux/sh_clk.h
include/linux/skbuff.h
include/linux/spi/orion_spi.h
include/linux/spi/s3c24xx.h [new file with mode: 0644]
include/linux/virtio_ids.h
include/net/netfilter/nf_conntrack_l4proto.h
include/net/netfilter/nf_conntrack_timeout.h
include/trace/events/jbd2.h
include/video/sa1100fb.h [new file with mode: 0644]
lib/Kconfig
mm/page-writeback.c
net/9p/client.c
net/ceph/ceph_common.c
net/ceph/messenger.c
net/ceph/osdmap.c
net/core/skbuff.c
net/ipv6/route.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_proto.c
net/netfilter/nfnetlink_cttimeout.c
net/netfilter/xt_CT.c
net/netfilter/xt_LOG.c
samples/Kconfig
samples/Makefile
samples/rpmsg/Makefile [new file with mode: 0644]
samples/rpmsg/rpmsg_client_sample.c [new file with mode: 0644]
sound/soc/imx/imx-audmux.c
sound/soc/omap/ams-delta.c
sound/soc/samsung/Kconfig
tools/virtio/linux/hrtimer.h [new file with mode: 0644]
tools/virtio/linux/module.h [new file with mode: 0644]
tools/virtio/linux/virtio.h

diff --git a/Documentation/ABI/testing/sysfs-block-dm b/Documentation/ABI/testing/sysfs-block-dm
new file mode 100644 (file)
index 0000000..87ca569
--- /dev/null
@@ -0,0 +1,25 @@
+What:          /sys/block/dm-<num>/dm/name
+Date:          January 2009
+KernelVersion: 2.6.29
+Contact:       dm-devel@redhat.com
+Description:   Device-mapper device name.
+               Read-only string containing mapped device name.
+Users:         util-linux, device-mapper udev rules
+
+What:          /sys/block/dm-<num>/dm/uuid
+Date:          January 2009
+KernelVersion: 2.6.29
+Contact:       dm-devel@redhat.com
+Description:   Device-mapper device UUID.
+               Read-only string containing DM-UUID or empty string
+               if DM-UUID is not set.
+Users:         util-linux, device-mapper udev rules
+
+What:          /sys/block/dm-<num>/dm/suspended
+Date:          June 2009
+KernelVersion: 2.6.31
+Contact:       dm-devel@redhat.com
+Description:   Device-mapper device suspend state.
+               Contains the value 1 while the device is suspended.
+               Otherwise it contains 0. Read-only attribute.
+Users:         util-linux, device-mapper udev rules
diff --git a/Documentation/ABI/testing/sysfs-bus-rpmsg b/Documentation/ABI/testing/sysfs-bus-rpmsg
new file mode 100644 (file)
index 0000000..189e419
--- /dev/null
@@ -0,0 +1,75 @@
+What:          /sys/bus/rpmsg/devices/.../name
+Date:          June 2011
+KernelVersion: 3.3
+Contact:       Ohad Ben-Cohen <ohad@wizery.com>
+Description:
+               Every rpmsg device is a communication channel with a remote
+               processor. Channels are identified with a (textual) name,
+               which is maximum 32 bytes long (defined as RPMSG_NAME_SIZE in
+               rpmsg.h).
+
+               This sysfs entry contains the name of this channel.
+
+What:          /sys/bus/rpmsg/devices/.../src
+Date:          June 2011
+KernelVersion: 3.3
+Contact:       Ohad Ben-Cohen <ohad@wizery.com>
+Description:
+               Every rpmsg device is a communication channel with a remote
+               processor. Channels have a local ("source") rpmsg address,
+               and remote ("destination") rpmsg address. When an entity
+               starts listening on one end of a channel, it assigns it with
+               a unique rpmsg address (a 32 bits integer). This way when
+               inbound messages arrive to this address, the rpmsg core
+               dispatches them to the listening entity (a kernel driver).
+
+               This sysfs entry contains the src (local) rpmsg address
+               of this channel. If it contains 0xffffffff, then an address
+               wasn't assigned (can happen if no driver exists for this
+               channel).
+
+What:          /sys/bus/rpmsg/devices/.../dst
+Date:          June 2011
+KernelVersion: 3.3
+Contact:       Ohad Ben-Cohen <ohad@wizery.com>
+Description:
+               Every rpmsg device is a communication channel with a remote
+               processor. Channels have a local ("source") rpmsg address,
+               and remote ("destination") rpmsg address. When an entity
+               starts listening on one end of a channel, it assigns it with
+               a unique rpmsg address (a 32 bits integer). This way when
+               inbound messages arrive to this address, the rpmsg core
+               dispatches them to the listening entity.
+
+               This sysfs entry contains the dst (remote) rpmsg address
+               of this channel. If it contains 0xffffffff, then an address
+               wasn't assigned (can happen if the kernel driver that
+               is attached to this channel is exposing a service to the
+               remote processor. This make it a local rpmsg server,
+               and it is listening for inbound messages that may be sent
+               from any remote rpmsg client; it is not bound to a single
+               remote entity).
+
+What:          /sys/bus/rpmsg/devices/.../announce
+Date:          June 2011
+KernelVersion: 3.3
+Contact:       Ohad Ben-Cohen <ohad@wizery.com>
+Description:
+               Every rpmsg device is a communication channel with a remote
+               processor. Channels are identified by a textual name (see
+               /sys/bus/rpmsg/devices/.../name above) and have a local
+               ("source") rpmsg address, and remote ("destination") rpmsg
+               address.
+
+               A channel is first created when an entity, whether local
+               or remote, starts listening on it for messages (and is thus
+               called an rpmsg server).
+
+               When that happens, a "name service" announcement is sent
+               to the other processor, in order to let it know about the
+               creation of the channel (this way remote clients know they
+               can start sending messages).
+
+               This sysfs entry tells us whether the channel is a local
+               server channel that is announced (values are either
+               true or false).
diff --git a/Documentation/clk.txt b/Documentation/clk.txt
new file mode 100644 (file)
index 0000000..1943fae
--- /dev/null
@@ -0,0 +1,233 @@
+               The Common Clk Framework
+               Mike Turquette <mturquette@ti.com>
+
+This document endeavours to explain the common clk framework details,
+and how to port a platform over to this framework.  It is not yet a
+detailed explanation of the clock api in include/linux/clk.h, but
+perhaps someday it will include that information.
+
+       Part 1 - introduction and interface split
+
+The common clk framework is an interface to control the clock nodes
+available on various devices today.  This may come in the form of clock
+gating, rate adjustment, muxing or other operations.  This framework is
+enabled with the CONFIG_COMMON_CLK option.
+
+The interface itself is divided into two halves, each shielded from the
+details of its counterpart.  First is the common definition of struct
+clk which unifies the framework-level accounting and infrastructure that
+has traditionally been duplicated across a variety of platforms.  Second
+is a common implementation of the clk.h api, defined in
+drivers/clk/clk.c.  Finally there is struct clk_ops, whose operations
+are invoked by the clk api implementation.
+
+The second half of the interface is comprised of the hardware-specific
+callbacks registered with struct clk_ops and the corresponding
+hardware-specific structures needed to model a particular clock.  For
+the remainder of this document any reference to a callback in struct
+clk_ops, such as .enable or .set_rate, implies the hardware-specific
+implementation of that code.  Likewise, references to struct clk_foo
+serve as a convenient shorthand for the implementation of the
+hardware-specific bits for the hypothetical "foo" hardware.
+
+Tying the two halves of this interface together is struct clk_hw, which
+is defined in struct clk_foo and pointed to within struct clk.  This
+allows easy for navigation between the two discrete halves of the common
+clock interface.
+
+       Part 2 - common data structures and api
+
+Below is the common struct clk definition from
+include/linux/clk-private.h, modified for brevity:
+
+       struct clk {
+               const char              *name;
+               const struct clk_ops    *ops;
+               struct clk_hw           *hw;
+               char                    **parent_names;
+               struct clk              **parents;
+               struct clk              *parent;
+               struct hlist_head       children;
+               struct hlist_node       child_node;
+               ...
+       };
+
+The members above make up the core of the clk tree topology.  The clk
+api itself defines several driver-facing functions which operate on
+struct clk.  That api is documented in include/linux/clk.h.
+
+Platforms and devices utilizing the common struct clk use the struct
+clk_ops pointer in struct clk to perform the hardware-specific parts of
+the operations defined in clk.h:
+
+       struct clk_ops {
+               int             (*prepare)(struct clk_hw *hw);
+               void            (*unprepare)(struct clk_hw *hw);
+               int             (*enable)(struct clk_hw *hw);
+               void            (*disable)(struct clk_hw *hw);
+               int             (*is_enabled)(struct clk_hw *hw);
+               unsigned long   (*recalc_rate)(struct clk_hw *hw,
+                                               unsigned long parent_rate);
+               long            (*round_rate)(struct clk_hw *hw, unsigned long,
+                                               unsigned long *);
+               int             (*set_parent)(struct clk_hw *hw, u8 index);
+               u8              (*get_parent)(struct clk_hw *hw);
+               int             (*set_rate)(struct clk_hw *hw, unsigned long);
+               void            (*init)(struct clk_hw *hw);
+       };
+
+       Part 3 - hardware clk implementations
+
+The strength of the common struct clk comes from its .ops and .hw pointers
+which abstract the details of struct clk from the hardware-specific bits, and
+vice versa.  To illustrate consider the simple gateable clk implementation in
+drivers/clk/clk-gate.c:
+
+struct clk_gate {
+       struct clk_hw   hw;
+       void __iomem    *reg;
+       u8              bit_idx;
+       ...
+};
+
+struct clk_gate contains struct clk_hw hw as well as hardware-specific
+knowledge about which register and bit controls this clk's gating.
+Nothing about clock topology or accounting, such as enable_count or
+notifier_count, is needed here.  That is all handled by the common
+framework code and struct clk.
+
+Let's walk through enabling this clk from driver code:
+
+       struct clk *clk;
+       clk = clk_get(NULL, "my_gateable_clk");
+
+       clk_prepare(clk);
+       clk_enable(clk);
+
+The call graph for clk_enable is very simple:
+
+clk_enable(clk);
+       clk->ops->enable(clk->hw);
+       [resolves to...]
+               clk_gate_enable(hw);
+               [resolves struct clk gate with to_clk_gate(hw)]
+                       clk_gate_set_bit(gate);
+
+And the definition of clk_gate_set_bit:
+
+static void clk_gate_set_bit(struct clk_gate *gate)
+{
+       u32 reg;
+
+       reg = __raw_readl(gate->reg);
+       reg |= BIT(gate->bit_idx);
+       writel(reg, gate->reg);
+}
+
+Note that to_clk_gate is defined as:
+
+#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, clk)
+
+This pattern of abstraction is used for every clock hardware
+representation.
+
+       Part 4 - supporting your own clk hardware
+
+When implementing support for a new type of clock it only necessary to
+include the following header:
+
+#include <linux/clk-provider.h>
+
+include/linux/clk.h is included within that header and clk-private.h
+must never be included from the code which implements the operations for
+a clock.  More on that below in Part 5.
+
+To construct a clk hardware structure for your platform you must define
+the following:
+
+struct clk_foo {
+       struct clk_hw hw;
+       ... hardware specific data goes here ...
+};
+
+To take advantage of your data you'll need to support valid operations
+for your clk:
+
+struct clk_ops clk_foo_ops {
+       .enable         = &clk_foo_enable;
+       .disable        = &clk_foo_disable;
+};
+
+Implement the above functions using container_of:
+
+#define to_clk_foo(_hw) container_of(_hw, struct clk_foo, hw)
+
+int clk_foo_enable(struct clk_hw *hw)
+{
+       struct clk_foo *foo;
+
+       foo = to_clk_foo(hw);
+
+       ... perform magic on foo ...
+
+       return 0;
+};
+
+Below is a matrix detailing which clk_ops are mandatory based upon the
+hardware capbilities of that clock.  A cell marked as "y" means
+mandatory, a cell marked as "n" implies that either including that
+callback is invalid or otherwise uneccesary.  Empty cells are either
+optional or must be evaluated on a case-by-case basis.
+
+                           clock hardware characteristics
+            -----------------------------------------------------------
+             | gate | change rate | single parent | multiplexer | root |
+             |------|-------------|---------------|-------------|------|
+.prepare     |      |             |               |             |      |
+.unprepare   |      |             |               |             |      |
+             |      |             |               |             |      |
+.enable      | y    |             |               |             |      |
+.disable     | y    |             |               |             |      |
+.is_enabled  | y    |             |               |             |      |
+             |      |             |               |             |      |
+.recalc_rate |      | y           |               |             |      |
+.round_rate  |      | y           |               |             |      |
+.set_rate    |      | y           |               |             |      |
+             |      |             |               |             |      |
+.set_parent  |      |             | n             | y           | n    |
+.get_parent  |      |             | n             | y           | n    |
+             |      |             |               |             |      |
+.init        |      |             |               |             |      |
+            -----------------------------------------------------------
+
+Finally, register your clock at run-time with a hardware-specific
+registration function.  This function simply populates struct clk_foo's
+data and then passes the common struct clk parameters to the framework
+with a call to:
+
+clk_register(...)
+
+See the basic clock types in drivers/clk/clk-*.c for examples.
+
+       Part 5 - static initialization of clock data
+
+For platforms with many clocks (often numbering into the hundreds) it
+may be desirable to statically initialize some clock data.  This
+presents a problem since the definition of struct clk should be hidden
+from everyone except for the clock core in drivers/clk/clk.c.
+
+To get around this problem struct clk's definition is exposed in
+include/linux/clk-private.h along with some macros for more easily
+initializing instances of the basic clock types.  These clocks must
+still be initialized with the common clock framework via a call to
+__clk_init.
+
+clk-private.h must NEVER be included by code which implements struct
+clk_ops callbacks, nor must it be included by any logic which pokes
+around inside of struct clk at run-time.  To do so is a layering
+violation.
+
+To better enforce this policy, always follow this simple rule: any
+statically initialized clock data MUST be defined in a separate file
+from the logic that implements its ops.  Basically separate the logic
+from the data and all is well.
index 1ff044d87ca40d72565191615bac227ee2bc8d5c..3370bc4d7b9885b45040b359d858f4112418b74f 100644 (file)
@@ -75,10 +75,12 @@ less sharing than average you'll need a larger-than-average metadata device.
 
 As a guide, we suggest you calculate the number of bytes to use in the
 metadata device as 48 * $data_dev_size / $data_block_size but round it up
-to 2MB if the answer is smaller.  The largest size supported is 16GB.
+to 2MB if the answer is smaller.  If you're creating large numbers of
+snapshots which are recording large amounts of change, you may find you
+need to increase this.
 
-If you're creating large numbers of snapshots which are recording large
-amounts of change, you may need find you need to increase this.
+The largest size supported is 16GB: If the device is larger,
+a warning will be issued and the excess space will not be used.
 
 Reloading a pool table
 ----------------------
@@ -167,6 +169,38 @@ ii) Using an internal snapshot.
 
     dmsetup create snap --table "0 2097152 thin /dev/mapper/pool 1"
 
+External snapshots
+------------------
+
+You can use an external _read only_ device as an origin for a
+thinly-provisioned volume.  Any read to an unprovisioned area of the
+thin device will be passed through to the origin.  Writes trigger
+the allocation of new blocks as usual.
+
+One use case for this is VM hosts that want to run guests on
+thinly-provisioned volumes but have the base image on another device
+(possibly shared between many VMs).
+
+You must not write to the origin device if you use this technique!
+Of course, you may write to the thin device and take internal snapshots
+of the thin volume.
+
+i) Creating a snapshot of an external device
+
+  This is the same as creating a thin device.
+  You don't mention the origin at this stage.
+
+    dmsetup message /dev/mapper/pool 0 "create_thin 0"
+
+ii) Using a snapshot of an external device.
+
+  Append an extra parameter to the thin target specifying the origin:
+
+    dmsetup create snap --table "0 2097152 thin /dev/mapper/pool 0 /dev/image"
+
+  N.B. All descendants (internal snapshots) of this snapshot require the
+  same extra origin parameter.
+
 Deactivation
 ------------
 
@@ -189,7 +223,13 @@ i) Constructor
              <low water mark (blocks)> [<number of feature args> [<arg>]*]
 
     Optional feature arguments:
-    - 'skip_block_zeroing': skips the zeroing of newly-provisioned blocks.
+
+      skip_block_zeroing: Skip the zeroing of newly-provisioned blocks.
+
+      ignore_discard: Disable discard support.
+
+      no_discard_passdown: Don't pass discards down to the underlying
+                          data device, but just remove the mapping.
 
     Data block size must be between 64KB (128 sectors) and 1GB
     (2097152 sectors) inclusive.
@@ -237,16 +277,6 @@ iii) Messages
 
        Deletes a thin device.  Irreversible.
 
-    trim <dev id> <new size in sectors>
-
-       Delete mappings from the end of a thin device.  Irreversible.
-       You might want to use this if you're reducing the size of
-       your thinly-provisioned device.  In many cases, due to the
-       sharing of blocks between devices, it is not possible to
-       determine in advance how much space 'trim' will release.  (In
-       future a userspace tool might be able to perform this
-       calculation.)
-
     set_transaction_id <current id> <new id>
 
        Userland volume managers, such as LVM, need a way to
@@ -262,7 +292,7 @@ iii) Messages
 
 i) Constructor
 
-    thin <pool dev> <dev id>
+    thin <pool dev> <dev id> [<external origin dev>]
 
     pool dev:
        the thin-pool device, e.g. /dev/mapper/my_pool or 253:0
@@ -271,6 +301,11 @@ i) Constructor
        the internal device identifier of the device to be
        activated.
 
+    external origin dev:
+       an optional block device outside the pool to be treated as a
+       read-only snapshot origin: reads to unprovisioned areas of the
+       thin target will be mapped to this device.
+
 The pool doesn't store any size against the thin devices.  If you
 load a thin target that is smaller than you've been using previously,
 then you'll have no access to blocks mapped beyond the end.  If you
diff --git a/Documentation/device-mapper/verity.txt b/Documentation/device-mapper/verity.txt
new file mode 100644 (file)
index 0000000..32e4879
--- /dev/null
@@ -0,0 +1,194 @@
+dm-verity
+==========
+
+Device-Mapper's "verity" target provides transparent integrity checking of
+block devices using a cryptographic digest provided by the kernel crypto API.
+This target is read-only.
+
+Construction Parameters
+=======================
+    <version> <dev> <hash_dev> <hash_start>
+    <data_block_size> <hash_block_size>
+    <num_data_blocks> <hash_start_block>
+    <algorithm> <digest> <salt>
+
+<version>
+    This is the version number of the on-disk format.
+
+    0 is the original format used in the Chromium OS.
+       The salt is appended when hashing, digests are stored continuously and
+       the rest of the block is padded with zeros.
+
+    1 is the current format that should be used for new devices.
+       The salt is prepended when hashing and each digest is
+       padded with zeros to the power of two.
+
+<dev>
+    This is the device containing the data the integrity of which needs to be
+    checked.  It may be specified as a path, like /dev/sdaX, or a device number,
+    <major>:<minor>.
+
+<hash_dev>
+    This is the device that that supplies the hash tree data.  It may be
+    specified similarly to the device path and may be the same device.  If the
+    same device is used, the hash_start should be outside of the dm-verity
+    configured device size.
+
+<data_block_size>
+    The block size on a data device.  Each block corresponds to one digest on
+    the hash device.
+
+<hash_block_size>
+    The size of a hash block.
+
+<num_data_blocks>
+    The number of data blocks on the data device.  Additional blocks are
+    inaccessible.  You can place hashes to the same partition as data, in this
+    case hashes are placed after <num_data_blocks>.
+
+<hash_start_block>
+    This is the offset, in <hash_block_size>-blocks, from the start of hash_dev
+    to the root block of the hash tree.
+
+<algorithm>
+    The cryptographic hash algorithm used for this device.  This should
+    be the name of the algorithm, like "sha1".
+
+<digest>
+    The hexadecimal encoding of the cryptographic hash of the root hash block
+    and the salt.  This hash should be trusted as there is no other authenticity
+    beyond this point.
+
+<salt>
+    The hexadecimal encoding of the salt value.
+
+Theory of operation
+===================
+
+dm-verity is meant to be setup as part of a verified boot path.  This
+may be anything ranging from a boot using tboot or trustedgrub to just
+booting from a known-good device (like a USB drive or CD).
+
+When a dm-verity device is configured, it is expected that the caller
+has been authenticated in some way (cryptographic signatures, etc).
+After instantiation, all hashes will be verified on-demand during
+disk access.  If they cannot be verified up to the root node of the
+tree, the root hash, then the I/O will fail.  This should identify
+tampering with any data on the device and the hash data.
+
+Cryptographic hashes are used to assert the integrity of the device on a
+per-block basis.  This allows for a lightweight hash computation on first read
+into the page cache.  Block hashes are stored linearly-aligned to the nearest
+block the size of a page.
+
+Hash Tree
+---------
+
+Each node in the tree is a cryptographic hash.  If it is a leaf node, the hash
+is of some block data on disk.  If it is an intermediary node, then the hash is
+of a number of child nodes.
+
+Each entry in the tree is a collection of neighboring nodes that fit in one
+block.  The number is determined based on block_size and the size of the
+selected cryptographic digest algorithm.  The hashes are linearly-ordered in
+this entry and any unaligned trailing space is ignored but included when
+calculating the parent node.
+
+The tree looks something like:
+
+alg = sha256, num_blocks = 32768, block_size = 4096
+
+                                 [   root    ]
+                                /    . . .    \
+                     [entry_0]                 [entry_1]
+                    /  . . .  \                 . . .   \
+         [entry_0_0]   . . .  [entry_0_127]    . . . .  [entry_1_127]
+           / ... \             /   . . .  \             /           \
+     blk_0 ... blk_127  blk_16256   blk_16383      blk_32640 . . . blk_32767
+
+
+On-disk format
+==============
+
+Below is the recommended on-disk format. The verity kernel code does not
+read the on-disk header. It only reads the hash blocks which directly
+follow the header. It is expected that a user-space tool will verify the
+integrity of the verity_header and then call dmsetup with the correct
+parameters. Alternatively, the header can be omitted and the dmsetup
+parameters can be passed via the kernel command-line in a rooted chain
+of trust where the command-line is verified.
+
+The on-disk format is especially useful in cases where the hash blocks
+are on a separate partition. The magic number allows easy identification
+of the partition contents. Alternatively, the hash blocks can be stored
+in the same partition as the data to be verified. In such a configuration
+the filesystem on the partition would be sized a little smaller than
+the full-partition, leaving room for the hash blocks.
+
+struct superblock {
+       uint8_t signature[8]
+               "verity\0\0";
+
+       uint8_t version;
+               1 - current format
+
+       uint8_t data_block_bits;
+               log2(data block size)
+
+       uint8_t hash_block_bits;
+               log2(hash block size)
+
+       uint8_t pad1[1];
+               zero padding
+
+       uint16_t salt_size;
+               big-endian salt size
+
+       uint8_t pad2[2];
+               zero padding
+
+       uint32_t data_blocks_hi;
+               big-endian high 32 bits of the 64-bit number of data blocks
+
+       uint32_t data_blocks_lo;
+               big-endian low 32 bits of the 64-bit number of data blocks
+
+       uint8_t algorithm[16];
+               cryptographic algorithm
+
+       uint8_t salt[384];
+               salt (the salt size is specified above)
+
+       uint8_t pad3[88];
+               zero padding to 512-byte boundary
+}
+
+Directly following the header (and with sector number padded to the next hash
+block boundary) are the hash blocks which are stored a depth at a time
+(starting from the root), sorted in order of increasing index.
+
+Status
+======
+V (for Valid) is returned if every check performed so far was valid.
+If any check failed, C (for Corruption) is returned.
+
+Example
+=======
+
+Setup a device:
+  dmsetup create vroot --table \
+    "0 2097152 "\
+    "verity 1 /dev/sda1 /dev/sda2 4096 4096 2097152 1 "\
+    "4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 "\
+    "1234000000000000000000000000000000000000000000000000000000000000"
+
+A command line tool veritysetup is available to compute or verify
+the hash tree or activate the kernel driver.  This is available from
+the LVM2 upstream repository and may be supplied as a package called
+device-mapper-verity-tools:
+    git://sources.redhat.com/git/lvm2
+    http://sourceware.org/git/?p=lvm2.git
+    http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/verity?cvsroot=lvm2
+
+veritysetup -a vroot /dev/sda1 /dev/sda2 \
+       4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076
diff --git a/Documentation/devicetree/bindings/arm/atmel-aic.txt b/Documentation/devicetree/bindings/arm/atmel-aic.txt
new file mode 100644 (file)
index 0000000..aabca4f
--- /dev/null
@@ -0,0 +1,38 @@
+* Advanced Interrupt Controller (AIC)
+
+Required properties:
+- compatible: Should be "atmel,<chip>-aic"
+- interrupt-controller: Identifies the node as an interrupt controller.
+- interrupt-parent: For single AIC system, it is an empty property.
+- #interrupt-cells: The number of cells to define the interrupts. It sould be 2.
+  The first cell is the IRQ number (aka "Peripheral IDentifier" on datasheet).
+  The second cell is used to specify flags:
+    bits[3:0] trigger type and level flags:
+      1 = low-to-high edge triggered.
+      2 = high-to-low edge triggered.
+      4 = active high level-sensitive.
+      8 = active low level-sensitive.
+      Valid combinations are 1, 2, 3, 4, 8.
+      Default flag for internal sources should be set to 4 (active high).
+- reg: Should contain AIC registers location and length
+
+Examples:
+       /*
+        * AIC
+        */
+       aic: interrupt-controller@fffff000 {
+               compatible = "atmel,at91rm9200-aic";
+               interrupt-controller;
+               interrupt-parent;
+               #interrupt-cells = <2>;
+               reg = <0xfffff000 0x200>;
+       };
+
+       /*
+        * An interrupt generating device that is wired to an AIC.
+        */
+       dma: dma-controller@ffffec00 {
+               compatible = "atmel,at91sam9g45-dma";
+               reg = <0xffffec00 0x200>;
+               interrupts = <21 4>;
+       };
diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt
new file mode 100644 (file)
index 0000000..ecc81e3
--- /dev/null
@@ -0,0 +1,92 @@
+Atmel AT91 device tree bindings.
+================================
+
+PIT Timer required properties:
+- compatible: Should be "atmel,at91sam9260-pit"
+- reg: Should contain registers location and length
+- interrupts: Should contain interrupt for the PIT which is the IRQ line
+  shared across all System Controller members.
+
+TC/TCLIB Timer required properties:
+- compatible: Should be "atmel,<chip>-pit".
+  <chip> can be "at91rm9200" or "at91sam9x5"
+- reg: Should contain registers location and length
+- interrupts: Should contain all interrupts for the TC block
+  Note that you can specify several interrupt cells if the TC
+  block has one interrupt per channel.
+
+Examples:
+
+One interrupt per TC block:
+       tcb0: timer@fff7c000 {
+               compatible = "atmel,at91rm9200-tcb";
+               reg = <0xfff7c000 0x100>;
+               interrupts = <18 4>;
+       };
+
+One interrupt per TC channel in a TC block:
+       tcb1: timer@fffdc000 {
+               compatible = "atmel,at91rm9200-tcb";
+               reg = <0xfffdc000 0x100>;
+               interrupts = <26 4 27 4 28 4>;
+       };
+
+RSTC Reset Controller required properties:
+- compatible: Should be "atmel,<chip>-rstc".
+  <chip> can be "at91sam9260" or "at91sam9g45"
+- reg: Should contain registers location and length
+
+Example:
+
+       rstc@fffffd00 {
+               compatible = "atmel,at91sam9260-rstc";
+               reg = <0xfffffd00 0x10>;
+       };
+
+RAMC SDRAM/DDR Controller required properties:
+- compatible: Should be "atmel,at91sam9260-sdramc",
+                       "atmel,at91sam9g45-ddramc",
+- reg: Should contain registers location and length
+  For at91sam9263 and at91sam9g45 you must specify 2 entries.
+
+Examples:
+
+       ramc0: ramc@ffffe800 {
+               compatible = "atmel,at91sam9g45-ddramc";
+               reg = <0xffffe800 0x200>;
+       };
+
+       ramc0: ramc@ffffe400 {
+               compatible = "atmel,at91sam9g45-ddramc";
+               reg = <0xffffe400 0x200
+                      0xffffe600 0x200>;
+       };
+
+SHDWC Shutdown Controller
+
+required properties:
+- compatible: Should be "atmel,<chip>-shdwc".
+  <chip> can be "at91sam9260", "at91sam9rl" or "at91sam9x5".
+- reg: Should contain registers location and length
+
+optional properties:
+- atmel,wakeup-mode: String, operation mode of the wakeup mode.
+  Supported values are: "none", "high", "low", "any".
+- atmel,wakeup-counter: Counter on Wake-up 0 (between 0x0 and 0xf).
+
+optional at91sam9260 properties:
+- atmel,wakeup-rtt-timer: boolean to enable Real-time Timer Wake-up.
+
+optional at91sam9rl properties:
+- atmel,wakeup-rtc-timer: boolean to enable Real-time Clock Wake-up.
+- atmel,wakeup-rtt-timer: boolean to enable Real-time Timer Wake-up.
+
+optional at91sam9x5 properties:
+- atmel,wakeup-rtc-timer: boolean to enable Real-time Clock Wake-up.
+
+Example:
+
+       rstc@fffffd00 {
+               compatible = "atmel,at91sam9260-rstc";
+               reg = <0xfffffd00 0x10>;
+       };
diff --git a/Documentation/devicetree/bindings/arm/atmel-pmc.txt b/Documentation/devicetree/bindings/arm/atmel-pmc.txt
new file mode 100644 (file)
index 0000000..389bed5
--- /dev/null
@@ -0,0 +1,11 @@
+* Power Management Controller (PMC)
+
+Required properties:
+- compatible: Should be "atmel,at91rm9200-pmc"
+- reg: Should contain PMC registers location and length
+
+Examples:
+       pmc: pmc@fffffc00 {
+               compatible = "atmel,at91rm9200-pmc";
+               reg = <0xfffffc00 0x100>;
+       };
index 54bdddadf1cf66169b789e2ef53754eafd4bfcc6..bfbc771a65f8937124089c238fe6ac0dcaa96142 100644 (file)
@@ -28,3 +28,25 @@ Required root node properties:
 i.MX6 Quad SABRE Lite Board
 Required root node properties:
     - compatible = "fsl,imx6q-sabrelite", "fsl,imx6q";
+
+Generic i.MX boards
+-------------------
+
+No iomux setup is done for these boards, so this must have been configured
+by the bootloader for boards to work with the generic bindings.
+
+i.MX27 generic board
+Required root node properties:
+    - compatible = "fsl,imx27";
+
+i.MX51 generic board
+Required root node properties:
+    - compatible = "fsl,imx51";
+
+i.MX53 generic board
+Required root node properties:
+    - compatible = "fsl,imx53";
+
+i.MX6q generic board
+Required root node properties:
+    - compatible = "fsl,imx6q";
diff --git a/Documentation/devicetree/bindings/arm/mrvl.txt b/Documentation/devicetree/bindings/arm/mrvl.txt
new file mode 100644 (file)
index 0000000..d8de933
--- /dev/null
@@ -0,0 +1,6 @@
+Marvell Platforms Device Tree Bindings
+----------------------------------------------------
+
+PXA168 Aspenite Board
+Required root node properties:
+       - compatible = "mrvl,pxa168-aspenite", "mrvl,pxa168";
diff --git a/Documentation/devicetree/bindings/arm/omap/intc.txt b/Documentation/devicetree/bindings/arm/omap/intc.txt
new file mode 100644 (file)
index 0000000..f2583e6
--- /dev/null
@@ -0,0 +1,27 @@
+* OMAP Interrupt Controller
+
+OMAP2/3 are using a TI interrupt controller that can support several
+configurable number of interrupts.
+
+Main node required properties:
+
+- compatible : should be:
+       "ti,omap2-intc"
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode an
+  interrupt source. The type shall be a <u32> and the value shall be 1.
+
+  The cell contains the interrupt number in the range [0-128].
+- ti,intc-size: Number of interrupts handled by the interrupt controller.
+- reg: physical base address and size of the intc registers map.
+
+Example:
+
+       intc: interrupt-controller@1 {
+               compatible = "ti,omap2-intc";
+               interrupt-controller;
+               #interrupt-cells = <1>;
+               ti,intc-size = <96>;
+               reg = <0x48200000 0x1000>;
+       };
+
diff --git a/Documentation/devicetree/bindings/arm/spear.txt b/Documentation/devicetree/bindings/arm/spear.txt
new file mode 100644 (file)
index 0000000..f8e54f0
--- /dev/null
@@ -0,0 +1,8 @@
+ST SPEAr Platforms Device Tree Bindings
+---------------------------------------
+
+Boards with the ST SPEAr600 SoC shall have the following properties:
+
+Required root node property:
+
+compatible = "st,spear600";
diff --git a/Documentation/devicetree/bindings/arm/tegra/emc.txt b/Documentation/devicetree/bindings/arm/tegra/emc.txt
new file mode 100644 (file)
index 0000000..09335f8
--- /dev/null
@@ -0,0 +1,100 @@
+Embedded Memory Controller
+
+Properties:
+- name : Should be emc
+- #address-cells : Should be 1
+- #size-cells : Should be 0
+- compatible : Should contain "nvidia,tegra20-emc".
+- reg : Offset and length of the register set for the device
+- nvidia,use-ram-code : If present, the sub-nodes will be addressed
+  and chosen using the ramcode board selector. If omitted, only one
+  set of tables can be present and said tables will be used
+  irrespective of ram-code configuration.
+
+Child device nodes describe the memory settings for different configurations and clock rates.
+
+Example:
+
+       emc@7000f400 {
+               #address-cells = < 1 >;
+               #size-cells = < 0 >;
+               compatible = "nvidia,tegra20-emc";
+               reg = <0x7000f4000 0x200>;
+       }
+
+
+Embedded Memory Controller ram-code table
+
+If the emc node has the nvidia,use-ram-code property present, then the
+next level of nodes below the emc table are used to specify which settings
+apply for which ram-code settings.
+
+If the emc node lacks the nvidia,use-ram-code property, this level is omitted
+and the tables are stored directly under the emc node (see below).
+
+Properties:
+
+- name : Should be emc-tables
+- nvidia,ram-code : the binary representation of the ram-code board strappings
+  for which this node (and children) are valid.
+
+
+
+Embedded Memory Controller configuration table
+
+This is a table containing the EMC register settings for the various
+operating speeds of the memory controller. They are always located as
+subnodes of the emc controller node.
+
+There are two ways of specifying which tables to use:
+
+* The simplest is if there is just one set of tables in the device tree,
+  and they will always be used (based on which frequency is used).
+  This is the preferred method, especially when firmware can fill in
+  this information based on the specific system information and just
+  pass it on to the kernel.
+
+* The slightly more complex one is when more than one memory configuration
+  might exist on the system.  The Tegra20 platform handles this during
+  early boot by selecting one out of possible 4 memory settings based
+  on a 2-pin "ram code" bootstrap setting on the board. The values of
+  these strappings can be read through a register in the SoC, and thus
+  used to select which tables to use.
+
+Properties:
+- name : Should be emc-table
+- compatible : Should contain "nvidia,tegra20-emc-table".
+- reg : either an opaque enumerator to tell different tables apart, or
+  the valid frequency for which the table should be used (in kHz).
+- clock-frequency : the clock frequency for the EMC at which this
+  table should be used (in kHz).
+- nvidia,emc-registers : a 46 word array of EMC registers to be programmed
+  for operation at the 'clock-frequency' setting.
+  The order and contents of the registers are:
+    RC, RFC, RAS, RP, R2W, W2R, R2P, W2P, RD_RCD, WR_RCD, RRD, REXT,
+    WDV, QUSE, QRST, QSAFE, RDV, REFRESH, BURST_REFRESH_NUM, PDEX2WR,
+    PDEX2RD, PCHG2PDEN, ACT2PDEN, AR2PDEN, RW2PDEN, TXSR, TCKE, TFAW,
+    TRPAB, TCLKSTABLE, TCLKSTOP, TREFBW, QUSE_EXTRA, FBIO_CFG6, ODT_WRITE,
+    ODT_READ, FBIO_CFG5, CFG_DIG_DLL, DLL_XFORM_DQS, DLL_XFORM_QUSE,
+    ZCAL_REF_CNT, ZCAL_WAIT_CNT, AUTO_CAL_INTERVAL, CFG_CLKTRIM_0,
+    CFG_CLKTRIM_1, CFG_CLKTRIM_2
+
+               emc-table@166000 {
+                       reg = <166000>;
+                       compatible = "nvidia,tegra20-emc-table";
+                       clock-frequency = < 166000 >;
+                       nvidia,emc-registers = < 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+                                                0 0 0 0 0 0 0 0 0 0 0 0 0 0
+                                                0 0 0 0 0 0 0 0 0 0 0 0 0 0
+                                                0 0 0 0 >;
+               };
+
+               emc-table@333000 {
+                       reg = <333000>;
+                       compatible = "nvidia,tegra20-emc-table";
+                       clock-frequency = < 333000 >;
+                       nvidia,emc-registers = < 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+                                                0 0 0 0 0 0 0 0 0 0 0 0 0 0
+                                                0 0 0 0 0 0 0 0 0 0 0 0 0 0
+                                                0 0 0 0 >;
+               };
diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
new file mode 100644 (file)
index 0000000..b5846e2
--- /dev/null
@@ -0,0 +1,19 @@
+NVIDIA Tegra Power Management Controller (PMC)
+
+Properties:
+- name : Should be pmc
+- compatible : Should contain "nvidia,tegra<chip>-pmc".
+- reg : Offset and length of the register set for the device
+- nvidia,invert-interrupt : If present, inverts the PMU interrupt signal.
+  The PMU is an external Power Management Unit, whose interrupt output
+  signal is fed into the PMC. This signal is optionally inverted, and then
+  fed into the ARM GIC. The PMC is not involved in the detection or
+  handling of this interrupt signal, merely its inversion.
+
+Example:
+
+pmc@7000f400 {
+       compatible = "nvidia,tegra20-pmc";
+       reg = <0x7000e400 0x400>;
+       nvidia,invert-interrupt;
+};
diff --git a/Documentation/devicetree/bindings/arm/twd.txt b/Documentation/devicetree/bindings/arm/twd.txt
new file mode 100644 (file)
index 0000000..75b8610
--- /dev/null
@@ -0,0 +1,48 @@
+* ARM Timer Watchdog
+
+ARM 11MP, Cortex-A5 and Cortex-A9 are often associated with a per-core
+Timer-Watchdog (aka TWD), which provides both a per-cpu local timer
+and watchdog.
+
+The TWD is usually attached to a GIC to deliver its two per-processor
+interrupts.
+
+** Timer node required properties:
+
+- compatible : Should be one of:
+       "arm,cortex-a9-twd-timer"
+       "arm,cortex-a5-twd-timer"
+       "arm,arm11mp-twd-timer"
+
+- interrupts : One interrupt to each core
+
+- reg : Specify the base address and the size of the TWD timer
+       register window.
+
+Example:
+
+       twd-timer@2c000600 {
+               compatible = "arm,arm11mp-twd-timer"";
+               reg = <0x2c000600 0x20>;
+               interrupts = <1 13 0xf01>;
+       };
+
+** Watchdog node properties:
+
+- compatible : Should be one of:
+       "arm,cortex-a9-twd-wdt"
+       "arm,cortex-a5-twd-wdt"
+       "arm,arm11mp-twd-wdt"
+
+- interrupts : One interrupt to each core
+
+- reg : Specify the base address and the size of the TWD watchdog
+       register window.
+
+Example:
+
+       twd-watchdog@2c000620 {
+               compatible = "arm,arm11mp-twd-wdt";
+               reg = <0x2c000620 0x20>;
+               interrupts = <1 14 0xf01>;
+       };
diff --git a/Documentation/devicetree/bindings/arm/vexpress.txt b/Documentation/devicetree/bindings/arm/vexpress.txt
new file mode 100644 (file)
index 0000000..ec8b50c
--- /dev/null
@@ -0,0 +1,146 @@
+ARM Versatile Express boards family
+-----------------------------------
+
+ARM's Versatile Express platform consists of a motherboard and one
+or more daughterboards (tiles). The motherboard provides a set of
+peripherals. Processor and RAM "live" on the tiles.
+
+The motherboard and each core tile should be described by a separate
+Device Tree source file, with the tile's description including
+the motherboard file using a /include/ directive. As the motherboard
+can be initialized in one of two different configurations ("memory
+maps"), care must be taken to include the correct one.
+
+Required properties in the root node:
+- compatible value:
+       compatible = "arm,vexpress,<model>", "arm,vexpress";
+  where <model> is the full tile model name (as used in the tile's
+    Technical Reference Manual), eg.:
+    - for Coretile Express A5x2 (V2P-CA5s):
+       compatible = "arm,vexpress,v2p-ca5s", "arm,vexpress";
+    - for Coretile Express A9x4 (V2P-CA9):
+       compatible = "arm,vexpress,v2p-ca9", "arm,vexpress";
+  If a tile comes in several variants or can be used in more then one
+  configuration, the compatible value should be:
+       compatible = "arm,vexpress,<model>,<variant>", \
+                               "arm,vexpress,<model>", "arm,vexpress";
+  eg:
+    - Coretile Express A15x2 (V2P-CA15) with Tech Chip 1:
+       compatible = "arm,vexpress,v2p-ca15,tc1", \
+                               "arm,vexpress,v2p-ca15", "arm,vexpress";
+    - LogicTile Express 13MG (V2F-2XV6) running Cortex-A7 (3 cores) SMM:
+       compatible = "arm,vexpress,v2f-2xv6,ca7x3", \
+                               "arm,vexpress,v2f-2xv6", "arm,vexpress";
+
+Optional properties in the root node:
+- tile model name (use name from the tile's Technical Reference
+  Manual, eg. "V2P-CA5s")
+       model = "<model>";
+- tile's HBI number (unique ARM's board model ID, visible on the
+  PCB's silkscreen) in hexadecimal transcription:
+       arm,hbi = <0xhbi>
+  eg:
+  - for Coretile Express A5x2 (V2P-CA5s) HBI-0191:
+       arm,hbi = <0x191>;
+  - Coretile Express A9x4 (V2P-CA9) HBI-0225:
+       arm,hbi = <0x225>;
+
+Top-level standard "cpus" node is required. It must contain a node
+with device_type = "cpu" property for every available core, eg.:
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a5";
+                       reg = <0>;
+               };
+       };
+
+The motherboard description file provides a single "motherboard" node
+using 2 address cells corresponding to the Static Memory Bus used
+between the motherboard and the tile. The first cell defines the Chip
+Select (CS) line number, the second cell address offset within the CS.
+All interrupt lines between the motherboard and the tile are active
+high and are described using single cell.
+
+Optional properties of the "motherboard" node:
+- motherboard's memory map variant:
+       arm,v2m-memory-map = "<name>";
+  where name is one of:
+  - "rs1" - for RS1 map (i.a. peripherals on CS3); this map is also
+            referred to as "ARM Cortex-A Series memory map":
+       arm,v2m-memory-map = "rs1";
+  When this property is missing, the motherboard is using the original
+  memory map (also known as the "Legacy memory map", primarily used
+  with the original CoreTile Express A9x4) with peripherals on CS7.
+
+Motherboard .dtsi files provide a set of labelled peripherals that
+can be used to obtain required phandle in the tile's "aliases" node:
+- UARTs, note that the numbers correspond to the physical connectors
+  on the motherboard's back panel:
+       v2m_serial0, v2m_serial1, v2m_serial2 and v2m_serial3
+- I2C controllers:
+       v2m_i2c_dvi and v2m_i2c_pcie
+- SP804 timers:
+       v2m_timer01 and v2m_timer23
+
+Current Linux implementation requires a "arm,v2m_timer" alias
+pointing at one of the motherboard's SP804 timers, if it is to be
+used as the system timer. This alias should be defined in the
+motherboard files.
+
+The tile description must define "ranges", "interrupt-map-mask" and
+"interrupt-map" properties to translate the motherboard's address
+and interrupt space into one used by the tile's processor.
+
+Abbreviated example:
+
+/dts-v1/;
+
+/ {
+       model = "V2P-CA5s";
+       arm,hbi = <0x225>;
+       compatible = "arm,vexpress-v2p-ca5s", "arm,vexpress";
+       interrupt-parent = <&gic>;
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       chosen { };
+
+       aliases {
+               serial0 = &v2m_serial0;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a5";
+                       reg = <0>;
+               };
+       };
+
+       gic: interrupt-controller@2c001000 {
+               compatible = "arm,cortex-a9-gic";
+               #interrupt-cells = <3>;
+               #address-cells = <0>;
+               interrupt-controller;
+               reg = <0x2c001000 0x1000>,
+                     <0x2c000100 0x100>;
+       };
+
+       motherboard {
+               /* CS0 is visible at 0x08000000 */
+               ranges = <0 0 0x08000000 0x04000000>;
+               interrupt-map-mask = <0 0 63>;
+               /* Active high IRQ 0 is connected to GIC's SPI0 */
+               interrupt-map = <0 0 0 &gic 0 0 4>;
+       };
+};
+
+/include/ "vexpress-v2m-rs1.dtsi"
diff --git a/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt b/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt
new file mode 100644 (file)
index 0000000..90fa7da
--- /dev/null
@@ -0,0 +1,30 @@
+* NVIDIA Tegra APB DMA controller
+
+Required properties:
+- compatible: Should be "nvidia,<chip>-apbdma"
+- reg: Should contain DMA registers location and length. This shuld include
+  all of the per-channel registers.
+- interrupts: Should contain all of the per-channel DMA interrupts.
+
+Examples:
+
+apbdma: dma@6000a000 {
+       compatible = "nvidia,tegra20-apbdma";
+       reg = <0x6000a000 0x1200>;
+       interrupts = < 0 136 0x04
+                      0 137 0x04
+                      0 138 0x04
+                      0 139 0x04
+                      0 140 0x04
+                      0 141 0x04
+                      0 142 0x04
+                      0 143 0x04
+                      0 144 0x04
+                      0 145 0x04
+                      0 146 0x04
+                      0 147 0x04
+                      0 148 0x04
+                      0 149 0x04
+                      0 150 0x04
+                      0 151 0x04 >;
+};
diff --git a/Documentation/devicetree/bindings/gpio/gpio_atmel.txt b/Documentation/devicetree/bindings/gpio/gpio_atmel.txt
new file mode 100644 (file)
index 0000000..66efc80
--- /dev/null
@@ -0,0 +1,20 @@
+* Atmel GPIO controller (PIO)
+
+Required properties:
+- compatible: "atmel,<chip>-gpio", where <chip> is at91rm9200 or at91sam9x5.
+- reg: Should contain GPIO controller registers location and length
+- interrupts: Should be the port interrupt shared by all the pins.
+- #gpio-cells: Should be two.  The first cell is the pin number and
+  the second cell is used to specify optional parameters (currently
+  unused).
+- gpio-controller: Marks the device node as a GPIO controller.
+
+Example:
+       pioA: gpio@fffff200 {
+               compatible = "atmel,at91rm9200-gpio";
+               reg = <0xfffff200 0x100>;
+               interrupts = <2 4>;
+               #gpio-cells = <2>;
+               gpio-controller;
+       };
+
diff --git a/Documentation/devicetree/bindings/gpio/gpio_i2c.txt b/Documentation/devicetree/bindings/gpio/gpio_i2c.txt
new file mode 100644 (file)
index 0000000..4f8ec94
--- /dev/null
@@ -0,0 +1,32 @@
+Device-Tree bindings for i2c gpio driver
+
+Required properties:
+       - compatible = "i2c-gpio";
+       - gpios: sda and scl gpio
+
+
+Optional properties:
+       - i2c-gpio,sda-open-drain: sda as open drain
+       - i2c-gpio,scl-open-drain: scl as open drain
+       - i2c-gpio,scl-output-only: scl as output only
+       - i2c-gpio,delay-us: delay between GPIO operations (may depend on each platform)
+       - i2c-gpio,timeout-ms: timeout to get data
+
+Example nodes:
+
+i2c@0 {
+       compatible = "i2c-gpio";
+       gpios = <&pioA 23 0 /* sda */
+                &pioA 24 0 /* scl */
+               >;
+       i2c-gpio,sda-open-drain;
+       i2c-gpio,scl-open-drain;
+       i2c-gpio,delay-us = <2>;        /* ~100 kHz */
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       rv3029c2@56 {
+               compatible = "rv3029c2";
+               reg = <0x56>;
+       };
+};
index eb4b530d64e16d35481b013e5e6fb1c59aca15b9..023c9526e5f838c277eefdd10292943c11b4fd5a 100644 (file)
@@ -1,8 +1,40 @@
-NVIDIA Tegra GPIO controller
+NVIDIA Tegra GPIO controller
 
 Required properties:
-- compatible : "nvidia,tegra20-gpio"
+- compatible : "nvidia,tegra<chip>-gpio"
+- reg : Physical base address and length of the controller's registers.
+- interrupts : The interrupt outputs from the controller. For Tegra20,
+  there should be 7 interrupts specified, and for Tegra30, there should
+  be 8 interrupts specified.
 - #gpio-cells : Should be two. The first cell is the pin number and the
   second cell is used to specify optional parameters:
   - bit 0 specifies polarity (0 for normal, 1 for inverted)
 - gpio-controller : Marks the device node as a GPIO controller.
+- #interrupt-cells : Should be 2.
+  The first cell is the GPIO number.
+  The second cell is used to specify flags:
+    bits[3:0] trigger type and level flags:
+      1 = low-to-high edge triggered.
+      2 = high-to-low edge triggered.
+      4 = active high level-sensitive.
+      8 = active low level-sensitive.
+      Valid combinations are 1, 2, 3, 4, 8.
+- interrupt-controller : Marks the device node as an interrupt controller.
+
+Example:
+
+gpio: gpio@6000d000 {
+       compatible = "nvidia,tegra20-gpio";
+       reg = < 0x6000d000 0x1000 >;
+       interrupts = < 0 32 0x04
+                      0 33 0x04
+                      0 34 0x04
+                      0 35 0x04
+                      0 55 0x04
+                      0 87 0x04
+                      0 89 0x04 >;
+       #gpio-cells = <2>;
+       gpio-controller;
+       #interrupt-cells = <2>;
+       interrupt-controller;
+};
diff --git a/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt b/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt
new file mode 100644 (file)
index 0000000..1e34cfe
--- /dev/null
@@ -0,0 +1,23 @@
+* Marvell PXA GPIO controller
+
+Required properties:
+- compatible : Should be "mrvl,pxa-gpio" or "mrvl,mmp-gpio"
+- reg : Address and length of the register set for the device
+- interrupts : Should be the port interrupt shared by all gpio pins, if
+- interrupt-name : Should be the name of irq resource.
+  one number.
+- gpio-controller : Marks the device node as a gpio controller.
+- #gpio-cells : Should be one.  It is the pin number.
+
+Example:
+
+       gpio: gpio@d4019000 {
+               compatible = "mrvl,mmp-gpio", "mrvl,pxa-gpio";
+               reg = <0xd4019000 0x1000>;
+               interrupts = <49>, <17>, <18>;
+               interrupt-name = "gpio_mux", "gpio0", "gpio1";
+               gpio-controller;
+               #gpio-cells = <1>;
+               interrupt-controller;
+               #interrupt-cells = <1>;
+      };
diff --git a/Documentation/devicetree/bindings/i2c/mrvl-i2c.txt b/Documentation/devicetree/bindings/i2c/mrvl-i2c.txt
new file mode 100644 (file)
index 0000000..071eb3c
--- /dev/null
@@ -0,0 +1,37 @@
+* I2C
+
+Required properties :
+
+ - reg : Offset and length of the register set for the device
+ - compatible : should be "mrvl,mmp-twsi" where CHIP is the name of a
+   compatible processor, e.g. pxa168, pxa910, mmp2, mmp3.
+   For the pxa2xx/pxa3xx, an additional node "mrvl,pxa-i2c" is required
+   as shown in the example below.
+
+Recommended properties :
+
+ - interrupts : <a b> where a is the interrupt number and b is a
+   field that represents an encoding of the sense and level
+   information for the interrupt.  This should be encoded based on
+   the information in section 2) depending on the type of interrupt
+   controller you have.
+ - interrupt-parent : the phandle for the interrupt controller that
+   services interrupts for this device.
+ - mrvl,i2c-polling : Disable interrupt of i2c controller. Polling
+   status register of i2c controller instead.
+ - mrvl,i2c-fast-mode : Enable fast mode of i2c controller.
+
+Examples:
+       twsi1: i2c@d4011000 {
+               compatible = "mrvl,mmp-twsi", "mrvl,pxa-i2c";
+               reg = <0xd4011000 0x1000>;
+               interrupts = <7>;
+               mrvl,i2c-fast-mode;
+       };
+       
+       twsi2: i2c@d4025000 {
+               compatible = "mrvl,mmp-twsi", "mrvl,pxa-i2c";
+               reg = <0xd4025000 0x1000>;
+               interrupts = <58>;
+       };
+
diff --git a/Documentation/devicetree/bindings/mtd/atmel-nand.txt b/Documentation/devicetree/bindings/mtd/atmel-nand.txt
new file mode 100644 (file)
index 0000000..5903ecf
--- /dev/null
@@ -0,0 +1,41 @@
+Atmel NAND flash
+
+Required properties:
+- compatible : "atmel,at91rm9200-nand".
+- reg : should specify localbus address and size used for the chip,
+       and if availlable the ECC.
+- atmel,nand-addr-offset : offset for the address latch.
+- atmel,nand-cmd-offset : offset for the command latch.
+- #address-cells, #size-cells : Must be present if the device has sub-nodes
+  representing partitions.
+
+- gpios : specifies the gpio pins to control the NAND device. detect is an
+  optional gpio and may be set to 0 if not present.
+
+Optional properties:
+- nand-ecc-mode : String, operation mode of the NAND ecc mode, soft by default.
+  Supported values are: "none", "soft", "hw", "hw_syndrome", "hw_oob_first",
+  "soft_bch".
+- nand-bus-width : 8 or 16 bus width if not present 8
+- nand-on-flash-bbt: boolean to enable on flash bbt option if not present false
+
+Examples:
+nand0: nand@40000000,0 {
+       compatible = "atmel,at91rm9200-nand";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       reg = <0x40000000 0x10000000
+              0xffffe800 0x200
+             >;
+       atmel,nand-addr-offset = <21>;
+       atmel,nand-cmd-offset = <22>;
+       nand-on-flash-bbt;
+       nand-ecc-mode = "soft";
+       gpios = <&pioC 13 0
+                &pioC 14 0
+                0
+               >;
+       partition@0 {
+               ...
+       };
+};
diff --git a/Documentation/devicetree/bindings/mtd/nand.txt b/Documentation/devicetree/bindings/mtd/nand.txt
new file mode 100644 (file)
index 0000000..03855c8
--- /dev/null
@@ -0,0 +1,7 @@
+* MTD generic binding
+
+- nand-ecc-mode : String, operation mode of the NAND ecc mode.
+  Supported values are: "none", "soft", "hw", "hw_syndrome", "hw_oob_first",
+  "soft_bch".
+- nand-bus-width : 8 or 16 bus width if not present 8
+- nand-on-flash-bbt: boolean to enable on flash bbt option if not present false
diff --git a/Documentation/devicetree/bindings/rtc/sa1100-rtc.txt b/Documentation/devicetree/bindings/rtc/sa1100-rtc.txt
new file mode 100644 (file)
index 0000000..0cda19a
--- /dev/null
@@ -0,0 +1,17 @@
+* Marvell Real Time Clock controller
+
+Required properties:
+- compatible: should be "mrvl,sa1100-rtc"
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- interrupts: Should be two. The first interrupt number is the rtc alarm
+  interrupt and the second interrupt number is the rtc hz interrupt.
+- interrupt-names: Assign name of irq resource.
+
+Example:
+       rtc: rtc@d4010000 {
+               compatible = "mrvl,mmp-rtc";
+               reg = <0xd4010000 0x1000>;
+               interrupts = <5>, <6>;
+               interrupt-name = "rtc 1Hz", "rtc alarm";
+       };
diff --git a/Documentation/devicetree/bindings/serial/mrvl-serial.txt b/Documentation/devicetree/bindings/serial/mrvl-serial.txt
new file mode 100644 (file)
index 0000000..d744340
--- /dev/null
@@ -0,0 +1,4 @@
+PXA UART controller
+
+Required properties:
+- compatible : should be "mrvl,mmp-uart" or "mrvl,pxa-uart".
diff --git a/Documentation/devicetree/bindings/usb/atmel-usb.txt b/Documentation/devicetree/bindings/usb/atmel-usb.txt
new file mode 100644 (file)
index 0000000..60bd215
--- /dev/null
@@ -0,0 +1,49 @@
+Atmel SOC USB controllers
+
+OHCI
+
+Required properties:
+ - compatible: Should be "atmel,at91rm9200-ohci" for USB controllers
+   used in host mode.
+ - num-ports: Number of ports.
+ - atmel,vbus-gpio: If present, specifies a gpio that needs to be
+   activated for the bus to be powered.
+ - atmel,oc-gpio: If present, specifies a gpio that needs to be
+   activated for the overcurrent detection.
+
+usb0: ohci@00500000 {
+       compatible = "atmel,at91rm9200-ohci", "usb-ohci";
+       reg = <0x00500000 0x100000>;
+       interrupts = <20 4>;
+       num-ports = <2>;
+};
+
+EHCI
+
+Required properties:
+ - compatible: Should be "atmel,at91sam9g45-ehci" for USB controllers
+   used in host mode.
+
+usb1: ehci@00800000 {
+       compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
+       reg = <0x00800000 0x100000>;
+       interrupts = <22 4>;
+};
+
+AT91 USB device controller
+
+Required properties:
+ - compatible: Should be "atmel,at91rm9200-udc"
+ - reg: Address and length of the register set for the device
+ - interrupts: Should contain macb interrupt
+
+Optional properties:
+ - atmel,vbus-gpio: If present, specifies a gpio that needs to be
+   activated for the bus to be powered.
+
+usb1: gadget@fffa4000 {
+       compatible = "atmel,at91rm9200-udc";
+       reg = <0xfffa4000 0x4000>;
+       interrupts = <10 4>;
+       atmel,vbus-gpio = <&pioC 5 0>;
+};
index 035d63d5646d422637c2a504b5956d6a2bb42170..007005ddbe12ddbf5780061a94c243cc915bbcfe 100644 (file)
@@ -11,3 +11,16 @@ Required properties :
  - phy_type : Should be one of "ulpi" or "utmi".
  - nvidia,vbus-gpio : If present, specifies a gpio that needs to be
    activated for the bus to be powered.
+
+Optional properties:
+  - dr_mode : dual role mode. Indicates the working mode for
+   nvidia,tegra20-ehci compatible controllers.  Can be "host", "peripheral",
+   or "otg".  Default to "host" if not defined for backward compatibility.
+      host means this is a host controller
+      peripheral means it is device controller
+      otg means it can operate as either ("on the go")
+  - nvidia,has-legacy-mode : boolean indicates whether this controller can
+    operate in legacy mode (as APX 2500 / 2600). In legacy mode some
+    registers are accessed through the APB_MISC base address instead of
+    the USB controller. Since this is a legacy issue it probably does not
+    warrant a compatible string of its own.
index 4bfd982f8080f31458d5e06cba3ac3e1f3e7486b..0cad4803ffacd2c021f33407f21e9ead735c9bac 100644 (file)
@@ -513,20 +513,6 @@ Who:       Bjorn Helgaas <bhelgaas@google.com>
 
 ----------------------------
 
-What:  The CAP9 SoC family will be removed
-When:  3.4
-Files: arch/arm/mach-at91/at91cap9.c
-       arch/arm/mach-at91/at91cap9_devices.c
-       arch/arm/mach-at91/include/mach/at91cap9.h
-       arch/arm/mach-at91/include/mach/at91cap9_matrix.h
-       arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
-       arch/arm/mach-at91/board-cap9adk.c
-Why:   The code is not actively maintained and platforms are now hard to find.
-Who:   Nicolas Ferre <nicolas.ferre@atmel.com>
-       Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
-
-----------------------------
-
 What:  Low Performance USB Block driver ("CONFIG_BLK_DEV_UB")
 When:  3.6
 Why:   This driver provides support for USB storage devices like "USB
index 8c10bf375c73d281c5b9e0919e23e1064ba8abc9..1b7f9acbcbbe450c8d0f3f8a16d592275c61a5dd 100644 (file)
@@ -144,9 +144,6 @@ journal_async_commit        Commit block can be written to disk without waiting
                        mount the device. This will enable 'journal_checksum'
                        internally.
 
-journal=update         Update the ext4 file system's journal to the current
-                       format.
-
 journal_dev=devnum     When the external journal device's major/minor numbers
                        have changed, this option allows the user to specify
                        the new journal location.  The journal device is
@@ -356,11 +353,6 @@ nouid32                    Disables 32-bit UIDs and GIDs.  This is for
                        interoperability  with  older kernels which only
                        store and expect 16-bit values.
 
-resize                 Allows to resize filesystem to the end of the last
-                       existing block group, further resize has to be done
-                       with resize2fs either online, or offline. It can be
-                       used only with conjunction with remount.
-
 block_validity         This options allows to enables/disables the in-kernel
 noblock_validity       facility for tracking filesystem metadata blocks
                        within internal data structures. This allows multi-
diff --git a/Documentation/remoteproc.txt b/Documentation/remoteproc.txt
new file mode 100644 (file)
index 0000000..70a048c
--- /dev/null
@@ -0,0 +1,322 @@
+Remote Processor Framework
+
+1. Introduction
+
+Modern SoCs typically have heterogeneous remote processor devices in asymmetric
+multiprocessing (AMP) configurations, which may be running different instances
+of operating system, whether it's Linux or any other flavor of real-time OS.
+
+OMAP4, for example, has dual Cortex-A9, dual Cortex-M3 and a C64x+ DSP.
+In a typical configuration, the dual cortex-A9 is running Linux in a SMP
+configuration, and each of the other three cores (two M3 cores and a DSP)
+is running its own instance of RTOS in an AMP configuration.
+
+The remoteproc framework allows different platforms/architectures to
+control (power on, load firmware, power off) those remote processors while
+abstracting the hardware differences, so the entire driver doesn't need to be
+duplicated. In addition, this framework also adds rpmsg virtio devices
+for remote processors that supports this kind of communication. This way,
+platform-specific remoteproc drivers only need to provide a few low-level
+handlers, and then all rpmsg drivers will then just work
+(for more information about the virtio-based rpmsg bus and its drivers,
+please read Documentation/rpmsg.txt).
+Registration of other types of virtio devices is now also possible. Firmwares
+just need to publish what kind of virtio devices do they support, and then
+remoteproc will add those devices. This makes it possible to reuse the
+existing virtio drivers with remote processor backends at a minimal development
+cost.
+
+2. User API
+
+  int rproc_boot(struct rproc *rproc)
+    - Boot a remote processor (i.e. load its firmware, power it on, ...).
+      If the remote processor is already powered on, this function immediately
+      returns (successfully).
+      Returns 0 on success, and an appropriate error value otherwise.
+      Note: to use this function you should already have a valid rproc
+      handle. There are several ways to achieve that cleanly (devres, pdata,
+      the way remoteproc_rpmsg.c does this, or, if this becomes prevalent, we
+      might also consider using dev_archdata for this). See also
+      rproc_get_by_name() below.
+
+  void rproc_shutdown(struct rproc *rproc)
+    - Power off a remote processor (previously booted with rproc_boot()).
+      In case @rproc is still being used by an additional user(s), then
+      this function will just decrement the power refcount and exit,
+      without really powering off the device.
+      Every call to rproc_boot() must (eventually) be accompanied by a call
+      to rproc_shutdown(). Calling rproc_shutdown() redundantly is a bug.
+      Notes:
+      - we're not decrementing the rproc's refcount, only the power refcount.
+        which means that the @rproc handle stays valid even after
+        rproc_shutdown() returns, and users can still use it with a subsequent
+        rproc_boot(), if needed.
+      - don't call rproc_shutdown() to unroll rproc_get_by_name(), exactly
+        because rproc_shutdown() _does not_ decrement the refcount of @rproc.
+        To decrement the refcount of @rproc, use rproc_put() (but _only_ if
+        you acquired @rproc using rproc_get_by_name()).
+
+  struct rproc *rproc_get_by_name(const char *name)
+    - Find an rproc handle using the remote processor's name, and then
+      boot it. If it's already powered on, then just immediately return
+      (successfully). Returns the rproc handle on success, and NULL on failure.
+      This function increments the remote processor's refcount, so always
+      use rproc_put() to decrement it back once rproc isn't needed anymore.
+      Note: currently rproc_get_by_name() and rproc_put() are not used anymore
+      by the rpmsg bus and its drivers. We need to scrutinize the use cases
+      that still need them, and see if we can migrate them to use the non
+      name-based boot/shutdown interface.
+
+  void rproc_put(struct rproc *rproc)
+    - Decrement @rproc's power refcount and shut it down if it reaches zero
+      (essentially by just calling rproc_shutdown), and then decrement @rproc's
+      validity refcount too.
+      After this function returns, @rproc may _not_ be used anymore, and its
+      handle should be considered invalid.
+      This function should be called _iff_ the @rproc handle was grabbed by
+      calling rproc_get_by_name().
+
+3. Typical usage
+
+#include <linux/remoteproc.h>
+
+/* in case we were given a valid 'rproc' handle */
+int dummy_rproc_example(struct rproc *my_rproc)
+{
+       int ret;
+
+       /* let's power on and boot our remote processor */
+       ret = rproc_boot(my_rproc);
+       if (ret) {
+               /*
+                * something went wrong. handle it and leave.
+                */
+       }
+
+       /*
+        * our remote processor is now powered on... give it some work
+        */
+
+       /* let's shut it down now */
+       rproc_shutdown(my_rproc);
+}
+
+4. API for implementors
+
+  struct rproc *rproc_alloc(struct device *dev, const char *name,
+                               const struct rproc_ops *ops,
+                               const char *firmware, int len)
+    - Allocate a new remote processor handle, but don't register
+      it yet. Required parameters are the underlying device, the
+      name of this remote processor, platform-specific ops handlers,
+      the name of the firmware to boot this rproc with, and the
+      length of private data needed by the allocating rproc driver (in bytes).
+
+      This function should be used by rproc implementations during
+      initialization of the remote processor.
+      After creating an rproc handle using this function, and when ready,
+      implementations should then call rproc_register() to complete
+      the registration of the remote processor.
+      On success, the new rproc is returned, and on failure, NULL.
+
+      Note: _never_ directly deallocate @rproc, even if it was not registered
+      yet. Instead, if you just need to unroll rproc_alloc(), use rproc_free().
+
+  void rproc_free(struct rproc *rproc)
+    - Free an rproc handle that was allocated by rproc_alloc.
+      This function should _only_ be used if @rproc was only allocated,
+      but not registered yet.
+      If @rproc was already successfully registered (by calling
+      rproc_register()), then use rproc_unregister() instead.
+
+  int rproc_register(struct rproc *rproc)
+    - Register @rproc with the remoteproc framework, after it has been
+      allocated with rproc_alloc().
+      This is called by the platform-specific rproc implementation, whenever
+      a new remote processor device is probed.
+      Returns 0 on success and an appropriate error code otherwise.
+      Note: this function initiates an asynchronous firmware loading
+      context, which will look for virtio devices supported by the rproc's
+      firmware.
+      If found, those virtio devices will be created and added, so as a result
+      of registering this remote processor, additional virtio drivers might get
+      probed.
+
+  int rproc_unregister(struct rproc *rproc)
+    - Unregister a remote processor, and decrement its refcount.
+      If its refcount drops to zero, then @rproc will be freed. If not,
+      it will be freed later once the last reference is dropped.
+
+      This function should be called when the platform specific rproc
+      implementation decides to remove the rproc device. it should
+      _only_ be called if a previous invocation of rproc_register()
+      has completed successfully.
+
+      After rproc_unregister() returns, @rproc is _not_ valid anymore and
+      it shouldn't be used. More specifically, don't call rproc_free()
+      or try to directly free @rproc after rproc_unregister() returns;
+      none of these are needed, and calling them is a bug.
+
+      Returns 0 on success and -EINVAL if @rproc isn't valid.
+
+5. Implementation callbacks
+
+These callbacks should be provided by platform-specific remoteproc
+drivers:
+
+/**
+ * struct rproc_ops - platform-specific device handlers
+ * @start:     power on the device and boot it
+ * @stop:      power off the device
+ * @kick:      kick a virtqueue (virtqueue id given as a parameter)
+ */
+struct rproc_ops {
+       int (*start)(struct rproc *rproc);
+       int (*stop)(struct rproc *rproc);
+       void (*kick)(struct rproc *rproc, int vqid);
+};
+
+Every remoteproc implementation should at least provide the ->start and ->stop
+handlers. If rpmsg/virtio functionality is also desired, then the ->kick handler
+should be provided as well.
+
+The ->start() handler takes an rproc handle and should then power on the
+device and boot it (use rproc->priv to access platform-specific private data).
+The boot address, in case needed, can be found in rproc->bootaddr (remoteproc
+core puts there the ELF entry point).
+On success, 0 should be returned, and on failure, an appropriate error code.
+
+The ->stop() handler takes an rproc handle and powers the device down.
+On success, 0 is returned, and on failure, an appropriate error code.
+
+The ->kick() handler takes an rproc handle, and an index of a virtqueue
+where new message was placed in. Implementations should interrupt the remote
+processor and let it know it has pending messages. Notifying remote processors
+the exact virtqueue index to look in is optional: it is easy (and not
+too expensive) to go through the existing virtqueues and look for new buffers
+in the used rings.
+
+6. Binary Firmware Structure
+
+At this point remoteproc only supports ELF32 firmware binaries. However,
+it is quite expected that other platforms/devices which we'd want to
+support with this framework will be based on different binary formats.
+
+When those use cases show up, we will have to decouple the binary format
+from the framework core, so we can support several binary formats without
+duplicating common code.
+
+When the firmware is parsed, its various segments are loaded to memory
+according to the specified device address (might be a physical address
+if the remote processor is accessing memory directly).
+
+In addition to the standard ELF segments, most remote processors would
+also include a special section which we call "the resource table".
+
+The resource table contains system resources that the remote processor
+requires before it should be powered on, such as allocation of physically
+contiguous memory, or iommu mapping of certain on-chip peripherals.
+Remotecore will only power up the device after all the resource table's
+requirement are met.
+
+In addition to system resources, the resource table may also contain
+resource entries that publish the existence of supported features
+or configurations by the remote processor, such as trace buffers and
+supported virtio devices (and their configurations).
+
+The resource table begins with this header:
+
+/**
+ * struct resource_table - firmware resource table header
+ * @ver: version number
+ * @num: number of resource entries
+ * @reserved: reserved (must be zero)
+ * @offset: array of offsets pointing at the various resource entries
+ *
+ * The header of the resource table, as expressed by this structure,
+ * contains a version number (should we need to change this format in the
+ * future), the number of available resource entries, and their offsets
+ * in the table.
+ */
+struct resource_table {
+       u32 ver;
+       u32 num;
+       u32 reserved[2];
+       u32 offset[0];
+} __packed;
+
+Immediately following this header are the resource entries themselves,
+each of which begins with the following resource entry header:
+
+/**
+ * struct fw_rsc_hdr - firmware resource entry header
+ * @type: resource type
+ * @data: resource data
+ *
+ * Every resource entry begins with a 'struct fw_rsc_hdr' header providing
+ * its @type. The content of the entry itself will immediately follow
+ * this header, and it should be parsed according to the resource type.
+ */
+struct fw_rsc_hdr {
+       u32 type;
+       u8 data[0];
+} __packed;
+
+Some resources entries are mere announcements, where the host is informed
+of specific remoteproc configuration. Other entries require the host to
+do something (e.g. allocate a system resource). Sometimes a negotiation
+is expected, where the firmware requests a resource, and once allocated,
+the host should provide back its details (e.g. address of an allocated
+memory region).
+
+Here are the various resource types that are currently supported:
+
+/**
+ * enum fw_resource_type - types of resource entries
+ *
+ * @RSC_CARVEOUT:   request for allocation of a physically contiguous
+ *                 memory region.
+ * @RSC_DEVMEM:     request to iommu_map a memory-based peripheral.
+ * @RSC_TRACE:     announces the availability of a trace buffer into which
+ *                 the remote processor will be writing logs.
+ * @RSC_VDEV:       declare support for a virtio device, and serve as its
+ *                 virtio header.
+ * @RSC_LAST:       just keep this one at the end
+ *
+ * Please note that these values are used as indices to the rproc_handle_rsc
+ * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
+ * check the validity of an index before the lookup table is accessed, so
+ * please update it as needed.
+ */
+enum fw_resource_type {
+       RSC_CARVEOUT    = 0,
+       RSC_DEVMEM      = 1,
+       RSC_TRACE       = 2,
+       RSC_VDEV        = 3,
+       RSC_LAST        = 4,
+};
+
+For more details regarding a specific resource type, please see its
+dedicated structure in include/linux/remoteproc.h.
+
+We also expect that platform-specific resource entries will show up
+at some point. When that happens, we could easily add a new RSC_PLATFORM
+type, and hand those resources to the platform-specific rproc driver to handle.
+
+7. Virtio and remoteproc
+
+The firmware should provide remoteproc information about virtio devices
+that it supports, and their configurations: a RSC_VDEV resource entry
+should specify the virtio device id (as in virtio_ids.h), virtio features,
+virtio config space, vrings information, etc.
+
+When a new remote processor is registered, the remoteproc framework
+will look for its resource table and will register the virtio devices
+it supports. A firmware may support any number of virtio devices, and
+of any type (a single remote processor can also easily support several
+rpmsg virtio devices this way, if desired).
+
+Of course, RSC_VDEV resource entries are only good enough for static
+allocation of virtio devices. Dynamic allocations will also be made possible
+using the rpmsg bus (similar to how we already do dynamic allocations of
+rpmsg channels; read more about it in rpmsg.txt).
diff --git a/Documentation/rpmsg.txt b/Documentation/rpmsg.txt
new file mode 100644 (file)
index 0000000..409d9f9
--- /dev/null
@@ -0,0 +1,293 @@
+Remote Processor Messaging (rpmsg) Framework
+
+Note: this document describes the rpmsg bus and how to write rpmsg drivers.
+To learn how to add rpmsg support for new platforms, check out remoteproc.txt
+(also a resident of Documentation/).
+
+1. Introduction
+
+Modern SoCs typically employ heterogeneous remote processor devices in
+asymmetric multiprocessing (AMP) configurations, which may be running
+different instances of operating system, whether it's Linux or any other
+flavor of real-time OS.
+
+OMAP4, for example, has dual Cortex-A9, dual Cortex-M3 and a C64x+ DSP.
+Typically, the dual cortex-A9 is running Linux in a SMP configuration,
+and each of the other three cores (two M3 cores and a DSP) is running
+its own instance of RTOS in an AMP configuration.
+
+Typically AMP remote processors employ dedicated DSP codecs and multimedia
+hardware accelerators, and therefore are often used to offload CPU-intensive
+multimedia tasks from the main application processor.
+
+These remote processors could also be used to control latency-sensitive
+sensors, drive random hardware blocks, or just perform background tasks
+while the main CPU is idling.
+
+Users of those remote processors can either be userland apps (e.g. multimedia
+frameworks talking with remote OMX components) or kernel drivers (controlling
+hardware accessible only by the remote processor, reserving kernel-controlled
+resources on behalf of the remote processor, etc..).
+
+Rpmsg is a virtio-based messaging bus that allows kernel drivers to communicate
+with remote processors available on the system. In turn, drivers could then
+expose appropriate user space interfaces, if needed.
+
+When writing a driver that exposes rpmsg communication to userland, please
+keep in mind that remote processors might have direct access to the
+system's physical memory and other sensitive hardware resources (e.g. on
+OMAP4, remote cores and hardware accelerators may have direct access to the
+physical memory, gpio banks, dma controllers, i2c bus, gptimers, mailbox
+devices, hwspinlocks, etc..). Moreover, those remote processors might be
+running RTOS where every task can access the entire memory/devices exposed
+to the processor. To minimize the risks of rogue (or buggy) userland code
+exploiting remote bugs, and by that taking over the system, it is often
+desired to limit userland to specific rpmsg channels (see definition below)
+it can send messages on, and if possible, minimize how much control
+it has over the content of the messages.
+
+Every rpmsg device is a communication channel with a remote processor (thus
+rpmsg devices are called channels). Channels are identified by a textual name
+and have a local ("source") rpmsg address, and remote ("destination") rpmsg
+address.
+
+When a driver starts listening on a channel, its rx callback is bound with
+a unique rpmsg local address (a 32-bit integer). This way when inbound messages
+arrive, the rpmsg core dispatches them to the appropriate driver according
+to their destination address (this is done by invoking the driver's rx handler
+with the payload of the inbound message).
+
+
+2. User API
+
+  int rpmsg_send(struct rpmsg_channel *rpdev, void *data, int len);
+   - sends a message across to the remote processor on a given channel.
+     The caller should specify the channel, the data it wants to send,
+     and its length (in bytes). The message will be sent on the specified
+     channel, i.e. its source and destination address fields will be
+     set to the channel's src and dst addresses.
+
+     In case there are no TX buffers available, the function will block until
+     one becomes available (i.e. until the remote processor consumes
+     a tx buffer and puts it back on virtio's used descriptor ring),
+     or a timeout of 15 seconds elapses. When the latter happens,
+     -ERESTARTSYS is returned.
+     The function can only be called from a process context (for now).
+     Returns 0 on success and an appropriate error value on failure.
+
+  int rpmsg_sendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst);
+   - sends a message across to the remote processor on a given channel,
+     to a destination address provided by the caller.
+     The caller should specify the channel, the data it wants to send,
+     its length (in bytes), and an explicit destination address.
+     The message will then be sent to the remote processor to which the
+     channel belongs, using the channel's src address, and the user-provided
+     dst address (thus the channel's dst address will be ignored).
+
+     In case there are no TX buffers available, the function will block until
+     one becomes available (i.e. until the remote processor consumes
+     a tx buffer and puts it back on virtio's used descriptor ring),
+     or a timeout of 15 seconds elapses. When the latter happens,
+     -ERESTARTSYS is returned.
+     The function can only be called from a process context (for now).
+     Returns 0 on success and an appropriate error value on failure.
+
+  int rpmsg_send_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst,
+                                                       void *data, int len);
+   - sends a message across to the remote processor, using the src and dst
+     addresses provided by the user.
+     The caller should specify the channel, the data it wants to send,
+     its length (in bytes), and explicit source and destination addresses.
+     The message will then be sent to the remote processor to which the
+     channel belongs, but the channel's src and dst addresses will be
+     ignored (and the user-provided addresses will be used instead).
+
+     In case there are no TX buffers available, the function will block until
+     one becomes available (i.e. until the remote processor consumes
+     a tx buffer and puts it back on virtio's used descriptor ring),
+     or a timeout of 15 seconds elapses. When the latter happens,
+     -ERESTARTSYS is returned.
+     The function can only be called from a process context (for now).
+     Returns 0 on success and an appropriate error value on failure.
+
+  int rpmsg_trysend(struct rpmsg_channel *rpdev, void *data, int len);
+   - sends a message across to the remote processor on a given channel.
+     The caller should specify the channel, the data it wants to send,
+     and its length (in bytes). The message will be sent on the specified
+     channel, i.e. its source and destination address fields will be
+     set to the channel's src and dst addresses.
+
+     In case there are no TX buffers available, the function will immediately
+     return -ENOMEM without waiting until one becomes available.
+     The function can only be called from a process context (for now).
+     Returns 0 on success and an appropriate error value on failure.
+
+  int rpmsg_trysendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst)
+   - sends a message across to the remote processor on a given channel,
+     to a destination address provided by the user.
+     The user should specify the channel, the data it wants to send,
+     its length (in bytes), and an explicit destination address.
+     The message will then be sent to the remote processor to which the
+     channel belongs, using the channel's src address, and the user-provided
+     dst address (thus the channel's dst address will be ignored).
+
+     In case there are no TX buffers available, the function will immediately
+     return -ENOMEM without waiting until one becomes available.
+     The function can only be called from a process context (for now).
+     Returns 0 on success and an appropriate error value on failure.
+
+  int rpmsg_trysend_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst,
+                                                       void *data, int len);
+   - sends a message across to the remote processor, using source and
+     destination addresses provided by the user.
+     The user should specify the channel, the data it wants to send,
+     its length (in bytes), and explicit source and destination addresses.
+     The message will then be sent to the remote processor to which the
+     channel belongs, but the channel's src and dst addresses will be
+     ignored (and the user-provided addresses will be used instead).
+
+     In case there are no TX buffers available, the function will immediately
+     return -ENOMEM without waiting until one becomes available.
+     The function can only be called from a process context (for now).
+     Returns 0 on success and an appropriate error value on failure.
+
+  struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *rpdev,
+               void (*cb)(struct rpmsg_channel *, void *, int, void *, u32),
+               void *priv, u32 addr);
+   - every rpmsg address in the system is bound to an rx callback (so when
+     inbound messages arrive, they are dispatched by the rpmsg bus using the
+     appropriate callback handler) by means of an rpmsg_endpoint struct.
+
+     This function allows drivers to create such an endpoint, and by that,
+     bind a callback, and possibly some private data too, to an rpmsg address
+     (either one that is known in advance, or one that will be dynamically
+     assigned for them).
+
+     Simple rpmsg drivers need not call rpmsg_create_ept, because an endpoint
+     is already created for them when they are probed by the rpmsg bus
+     (using the rx callback they provide when they registered to the rpmsg bus).
+
+     So things should just work for simple drivers: they already have an
+     endpoint, their rx callback is bound to their rpmsg address, and when
+     relevant inbound messages arrive (i.e. messages which their dst address
+     equals to the src address of their rpmsg channel), the driver's handler
+     is invoked to process it.
+
+     That said, more complicated drivers might do need to allocate
+     additional rpmsg addresses, and bind them to different rx callbacks.
+     To accomplish that, those drivers need to call this function.
+     Drivers should provide their channel (so the new endpoint would bind
+     to the same remote processor their channel belongs to), an rx callback
+     function, an optional private data (which is provided back when the
+     rx callback is invoked), and an address they want to bind with the
+     callback. If addr is RPMSG_ADDR_ANY, then rpmsg_create_ept will
+     dynamically assign them an available rpmsg address (drivers should have
+     a very good reason why not to always use RPMSG_ADDR_ANY here).
+
+     Returns a pointer to the endpoint on success, or NULL on error.
+
+  void rpmsg_destroy_ept(struct rpmsg_endpoint *ept);
+   - destroys an existing rpmsg endpoint. user should provide a pointer
+     to an rpmsg endpoint that was previously created with rpmsg_create_ept().
+
+  int register_rpmsg_driver(struct rpmsg_driver *rpdrv);
+   - registers an rpmsg driver with the rpmsg bus. user should provide
+     a pointer to an rpmsg_driver struct, which contains the driver's
+     ->probe() and ->remove() functions, an rx callback, and an id_table
+     specifying the names of the channels this driver is interested to
+     be probed with.
+
+  void unregister_rpmsg_driver(struct rpmsg_driver *rpdrv);
+   - unregisters an rpmsg driver from the rpmsg bus. user should provide
+     a pointer to a previously-registered rpmsg_driver struct.
+     Returns 0 on success, and an appropriate error value on failure.
+
+
+3. Typical usage
+
+The following is a simple rpmsg driver, that sends an "hello!" message
+on probe(), and whenever it receives an incoming message, it dumps its
+content to the console.
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rpmsg.h>
+
+static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data, int len,
+                                               void *priv, u32 src)
+{
+       print_hex_dump(KERN_INFO, "incoming message:", DUMP_PREFIX_NONE,
+                                               16, 1, data, len, true);
+}
+
+static int rpmsg_sample_probe(struct rpmsg_channel *rpdev)
+{
+       int err;
+
+       dev_info(&rpdev->dev, "chnl: 0x%x -> 0x%x\n", rpdev->src, rpdev->dst);
+
+       /* send a message on our channel */
+       err = rpmsg_send(rpdev, "hello!", 6);
+       if (err) {
+               pr_err("rpmsg_send failed: %d\n", err);
+               return err;
+       }
+
+       return 0;
+}
+
+static void __devexit rpmsg_sample_remove(struct rpmsg_channel *rpdev)
+{
+       dev_info(&rpdev->dev, "rpmsg sample client driver is removed\n");
+}
+
+static struct rpmsg_device_id rpmsg_driver_sample_id_table[] = {
+       { .name = "rpmsg-client-sample" },
+       { },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_sample_id_table);
+
+static struct rpmsg_driver rpmsg_sample_client = {
+       .drv.name       = KBUILD_MODNAME,
+       .drv.owner      = THIS_MODULE,
+       .id_table       = rpmsg_driver_sample_id_table,
+       .probe          = rpmsg_sample_probe,
+       .callback       = rpmsg_sample_cb,
+       .remove         = __devexit_p(rpmsg_sample_remove),
+};
+
+static int __init init(void)
+{
+       return register_rpmsg_driver(&rpmsg_sample_client);
+}
+module_init(init);
+
+static void __exit fini(void)
+{
+       unregister_rpmsg_driver(&rpmsg_sample_client);
+}
+module_exit(fini);
+
+Note: a similar sample which can be built and loaded can be found
+in samples/rpmsg/.
+
+4. Allocations of rpmsg channels:
+
+At this point we only support dynamic allocations of rpmsg channels.
+
+This is possible only with remote processors that have the VIRTIO_RPMSG_F_NS
+virtio device feature set. This feature bit means that the remote
+processor supports dynamic name service announcement messages.
+
+When this feature is enabled, creation of rpmsg devices (i.e. channels)
+is completely dynamic: the remote processor announces the existence of a
+remote rpmsg service by sending a name service message (which contains
+the name and rpmsg addr of the remote service, see struct rpmsg_ns_msg).
+
+This message is then handled by the rpmsg bus, which in turn dynamically
+creates and registers an rpmsg channel (which represents the remote service).
+If/when a relevant rpmsg driver is registered, it will be immediately probed
+by the bus, and can then start sending messages to the remote service.
+
+The plan is also to add static creation of rpmsg channels via the virtio
+config space, but it's not implemented yet.
index f47091abb8f7eb4f7eaa84407f91b361126b054e..2cce20bbe39cbd4eb283f723154fdfcb67595257 100644 (file)
@@ -786,7 +786,6 @@ M:  Sascha Hauer <kernel@pengutronix.de>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 T:     git git://git.pengutronix.de/git/imx/linux-2.6.git
-F:     arch/arm/mach-mx*/
 F:     arch/arm/mach-imx/
 F:     arch/arm/plat-mxc/
 
@@ -816,9 +815,12 @@ S: Maintained
 
 ARM/H4700 (HP IPAQ HX4700) MACHINE SUPPORT
 M:     Philipp Zabel <philipp.zabel@gmail.com>
+M:     Paul Parsons <lost.distance@yahoo.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm/mach-pxa/hx4700.c
 F:     arch/arm/mach-pxa/include/mach/hx4700.h
+F:     sound/soc/pxa/hx4700.c
 
 ARM/HP JORNADA 7XX MACHINE SUPPORT
 M:     Kristoffer Ericson <kristoffer.ericson@gmail.com>
@@ -2223,13 +2225,16 @@ W:      http://lanana.org/docs/device-list/index.html
 S:     Maintained
 
 DEVICE-MAPPER  (LVM)
-P:     Alasdair Kergon
+M:     Alasdair Kergon <agk@redhat.com>
+M:     dm-devel@redhat.com
 L:     dm-devel@redhat.com
 W:     http://sources.redhat.com/dm
 Q:     http://patchwork.kernel.org/project/dm-devel/list/
+T:     quilt http://people.redhat.com/agk/patches/linux/editing/
 S:     Maintained
 F:     Documentation/device-mapper/
 F:     drivers/md/dm*
+F:     drivers/md/persistent-data/
 F:     include/linux/device-mapper.h
 F:     include/linux/dm-*.h
 
@@ -5420,7 +5425,7 @@ F:        drivers/media/video/pvrusb2/
 PXA2xx/PXA3xx SUPPORT
 M:     Eric Miao <eric.y.miao@gmail.com>
 M:     Russell King <linux@arm.linux.org.uk>
-M:     Haojian Zhuang <haojian.zhuang@marvell.com>
+M:     Haojian Zhuang <haojian.zhuang@gmail.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 T:     git git://github.com/hzhuang1/linux.git
 T:     git git://git.linaro.org/people/ycmiao/pxa-linux.git
@@ -5435,7 +5440,7 @@ F:        sound/soc/pxa
 
 MMP SUPPORT
 M:     Eric Miao <eric.y.miao@gmail.com>
-M:     Haojian Zhuang <haojian.zhuang@marvell.com>
+M:     Haojian Zhuang <haojian.zhuang@gmail.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 T:     git git://github.com/hzhuang1/linux.git
 T:     git git://git.linaro.org/people/ycmiao/pxa-linux.git
@@ -5632,6 +5637,13 @@ S:       Supported
 F:     drivers/base/regmap/
 F:     include/linux/regmap.h
 
+REMOTE PROCESSOR (REMOTEPROC) SUBSYSTEM
+M:     Ohad Ben-Cohen <ohad@wizery.com>
+S:     Maintained
+F:     drivers/remoteproc/
+F:     Documentation/remoteproc.txt
+F:     include/linux/remoteproc.txt
+
 RFKILL
 M:     Johannes Berg <johannes@sipsolutions.net>
 L:     linux-wireless@vger.kernel.org
@@ -6062,7 +6074,8 @@ F:        arch/arm/mach-s3c2410/bast-irq.c
 TI DAVINCI MACHINE SUPPORT
 M:     Sekhar Nori <nsekhar@ti.com>
 M:     Kevin Hilman <khilman@ti.com>
-L:     davinci-linux-open-source@linux.davincidsp.com (subscribers-only)
+L:     davinci-linux-open-source@linux.davincidsp.com (moderated for non-subscribers)
+T:     git git://gitorious.org/linux-davinci/linux-davinci.git
 Q:     http://patchwork.kernel.org/project/linux-davinci/list/
 S:     Supported
 F:     arch/arm/mach-davinci
@@ -6605,9 +6618,10 @@ F:       include/linux/if_team.h
 TEGRA SUPPORT
 M:     Colin Cross <ccross@android.com>
 M:     Olof Johansson <olof@lixom.net>
-M:     Stephen Warren <swarren@nvidia.com>
+M:     Stephen Warren <swarren@wwwdotorg.org>
 L:     linux-tegra@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/olof/tegra.git
+Q:     http://patchwork.ozlabs.org/project/linux-tegra/list/
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra.git
 S:     Supported
 F:     arch/arm/mach-tegra
 
index 87693e631129d5acbd9811d3de33637ecfc6211a..5098564d58799cc8c63e222003a6881a44c509af 100644 (file)
@@ -325,9 +325,10 @@ config ARCH_AT91
        select ARCH_REQUIRE_GPIOLIB
        select HAVE_CLK
        select CLKDEV_LOOKUP
+       select IRQ_DOMAIN
        help
          This enables support for systems based on the Atmel AT91RM9200,
-         AT91SAM9 and AT91CAP9 processors.
+         AT91SAM9 processors.
 
 config ARCH_BCMRING
        bool "Broadcom BCMRING"
@@ -737,7 +738,6 @@ config ARCH_RPC
        bool "RiscPC"
        select ARCH_ACORN
        select FIQ
-       select TIMER_ACORN
        select ARCH_MAY_HAVE_PC_FDC
        select HAVE_PATA_PLATFORM
        select ISA_DMA_API
@@ -760,31 +760,31 @@ config ARCH_SA1100
        select ARCH_HAS_CPUFREQ
        select CPU_FREQ
        select GENERIC_CLOCKEVENTS
-       select HAVE_CLK
+       select CLKDEV_LOOKUP
        select HAVE_SCHED_CLOCK
        select TICK_ONESHOT
        select ARCH_REQUIRE_GPIOLIB
        select HAVE_IDE
        select NEED_MACH_MEMORY_H
+       select SPARSE_IRQ
        help
          Support for StrongARM 11x0 based boards.
 
-config ARCH_S3C2410
-       bool "Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443, S3C2450"
+config ARCH_S3C24XX
+       bool "Samsung S3C24XX SoCs"
        select GENERIC_GPIO
        select ARCH_HAS_CPUFREQ
        select HAVE_CLK
        select CLKDEV_LOOKUP
        select ARCH_USES_GETTIMEOFFSET
        select HAVE_S3C2410_I2C if I2C
+       select HAVE_S3C_RTC if RTC_CLASS
+       select HAVE_S3C2410_WATCHDOG if WATCHDOG
        help
-         Samsung S3C2410X CPU based systems, such as the Simtec Electronics
-         BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
-         the Samsung SMDK2410 development board (and derivatives).
-
-         Note, the S3C2416 and the S3C2450 are so close that they even share
-         the same SoC ID code. This means that there is no separate machine
-         directory (no arch/arm/mach-s3c2450) as the S3C2416 was first.
+         Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443
+         and S3C2450 SoCs based systems, such as the Simtec Electronics BAST
+         (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or the
+         Samsung SMDK2410 development board (and derivatives).
 
 config ARCH_S3C64XX
        bool "Samsung S3C64XX"
@@ -907,6 +907,7 @@ config ARCH_U300
 
 config ARCH_U8500
        bool "ST-Ericsson U8500 Series"
+       depends on MMU
        select CPU_V7
        select ARM_AMBA
        select GENERIC_CLOCKEVENTS
@@ -1072,12 +1073,10 @@ source "arch/arm/plat-s5p/Kconfig"
 
 source "arch/arm/plat-spear/Kconfig"
 
-if ARCH_S3C2410
-source "arch/arm/mach-s3c2410/Kconfig"
+source "arch/arm/mach-s3c24xx/Kconfig"
+if ARCH_S3C24XX
 source "arch/arm/mach-s3c2412/Kconfig"
-source "arch/arm/mach-s3c2416/Kconfig"
 source "arch/arm/mach-s3c2440/Kconfig"
-source "arch/arm/mach-s3c2443/Kconfig"
 endif
 
 if ARCH_S3C64XX
@@ -1133,6 +1132,7 @@ config PLAT_VERSATILE
 config ARM_TIMER_SP804
        bool
        select CLKSRC_MMIO
+       select HAVE_SCHED_CLOCK
 
 source arch/arm/mm/Kconfig
 
@@ -1583,7 +1583,8 @@ config LOCAL_TIMERS
 config ARCH_NR_GPIO
        int
        default 1024 if ARCH_SHMOBILE || ARCH_TEGRA
-       default 350 if ARCH_U8500
+       default 355 if ARCH_U8500
+       default 264 if MACH_H4700
        default 0
        help
          Maximum number of GPIOs in the system.
@@ -1594,7 +1595,7 @@ source kernel/Kconfig.preempt
 
 config HZ
        int
-       default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P64X0 || \
+       default 200 if ARCH_EBSA110 || ARCH_S3C24XX || ARCH_S5P64X0 || \
                ARCH_S5PV210 || ARCH_EXYNOS4
        default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
        default AT91_TIMER_HZ if ARCH_AT91
@@ -2120,7 +2121,7 @@ config CPU_FREQ_S3C
 
 config CPU_FREQ_S3C24XX
        bool "CPUfreq driver for Samsung S3C24XX series CPUs (EXPERIMENTAL)"
-       depends on ARCH_S3C2410 && CPU_FREQ && EXPERIMENTAL
+       depends on ARCH_S3C24XX && CPU_FREQ && EXPERIMENTAL
        select CPU_FREQ_S3C
        help
          This enables the CPUfreq driver for the Samsung S3C24XX family
index 03646c4c13d18becdccfcbf3897a25fa53e3a31e..66ca8014ff3e6648fcb353923e39ee4663d3edc4 100644 (file)
@@ -86,7 +86,7 @@ choice
                depends on HAVE_AT91_DBGU0
 
        config AT91_DEBUG_LL_DBGU1
-               bool "Kernel low-level debugging on 9263, 9g45 and cap9"
+               bool "Kernel low-level debugging on 9263 and 9g45"
                depends on HAVE_AT91_DBGU1
 
        config DEBUG_CLPS711X_UART1
@@ -180,12 +180,12 @@ choice
                  Say Y here if you want kernel low-level debugging support
                  on i.MX50 or i.MX53.
 
-       config DEBUG_IMX6Q_UART
-               bool "i.MX6Q Debug UART"
+       config DEBUG_IMX6Q_UART4
+               bool "i.MX6Q Debug UART4"
                depends on SOC_IMX6Q
                help
                  Say Y here if you want kernel low-level debugging support
-                 on i.MX6Q.
+                 on i.MX6Q UART4.
 
        config DEBUG_MSM_UART1
                bool "Kernel low-level debugging messages via MSM UART1"
index 1683bfb9166fa0d8d1124a2d23f5d5d347cdc4a0..dcb088e868feaa02eb039947cf658b692a7ed0bc 100644 (file)
@@ -174,12 +174,13 @@ machine-$(CONFIG_ARCH_PRIMA2)             := prima2
 machine-$(CONFIG_ARCH_PXA)             := pxa
 machine-$(CONFIG_ARCH_REALVIEW)                := realview
 machine-$(CONFIG_ARCH_RPC)             := rpc
-machine-$(CONFIG_ARCH_S3C2410)         := s3c2410 s3c2412 s3c2416 s3c2440 s3c2443
+machine-$(CONFIG_ARCH_S3C24XX)         := s3c24xx s3c2412 s3c2440
 machine-$(CONFIG_ARCH_S3C64XX)         := s3c64xx
 machine-$(CONFIG_ARCH_S5P64X0)         := s5p64x0
 machine-$(CONFIG_ARCH_S5PC100)         := s5pc100
 machine-$(CONFIG_ARCH_S5PV210)         := s5pv210
 machine-$(CONFIG_ARCH_EXYNOS4)         := exynos
+machine-$(CONFIG_ARCH_EXYNOS5)         := exynos
 machine-$(CONFIG_ARCH_SA1100)          := sa1100
 machine-$(CONFIG_ARCH_SHARK)           := shark
 machine-$(CONFIG_ARCH_SHMOBILE)        := shmobile
index c5d60250d43daf44205cd830de3ca6ed941ed348..5f6045f1766cc758a94c14d2de2d01164179637a 100644 (file)
@@ -58,7 +58,7 @@
                add     \rb, \rb, #0x00010000   @ Ser1
 #endif
                .endm
-#elif defined(CONFIG_ARCH_S3C2410)
+#elif defined(CONFIG_ARCH_S3C24XX)
                .macro loadsp, rb, tmp
                mov     \rb, #0x50000000
                add     \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
diff --git a/arch/arm/boot/dts/am3517_mt_ventoux.dts b/arch/arm/boot/dts/am3517_mt_ventoux.dts
new file mode 100644 (file)
index 0000000..5eb26d7
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 Ilya Yanok, EmCraft Systems
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+/include/ "omap3.dtsi"
+
+/ {
+       model = "TeeJet Mt.Ventoux";
+       compatible = "teejet,mt_ventoux", "ti,omap3";
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x10000000>; /* 256 MB */
+       };
+
+       /* AM35xx doesn't have IVA */
+       soc {
+               iva {
+                       status = "disabled";
+               };
+       };
+};
index 07603b8c95037b10d85739e2dfcafc77d62be7c7..92f36627e7f8a3414ba87f020b051b5c283b69eb 100644 (file)
                serial4 = &usart3;
                serial5 = &usart4;
                serial6 = &usart5;
+               gpio0 = &pioA;
+               gpio1 = &pioB;
+               gpio2 = &pioC;
+               tcb0 = &tcb0;
+               tcb1 = &tcb1;
        };
        cpus {
                cpu@0 {
                        ranges;
 
                        aic: interrupt-controller@fffff000 {
-                               #interrupt-cells = <1>;
+                               #interrupt-cells = <2>;
                                compatible = "atmel,at91rm9200-aic";
                                interrupt-controller;
                                interrupt-parent;
                                reg = <0xfffff000 0x200>;
                        };
 
+                       ramc0: ramc@ffffea00 {
+                               compatible = "atmel,at91sam9260-sdramc";
+                               reg = <0xffffea00 0x200>;
+                       };
+
+                       pmc: pmc@fffffc00 {
+                               compatible = "atmel,at91rm9200-pmc";
+                               reg = <0xfffffc00 0x100>;
+                       };
+
+                       rstc@fffffd00 {
+                               compatible = "atmel,at91sam9260-rstc";
+                               reg = <0xfffffd00 0x10>;
+                       };
+
+                       shdwc@fffffd10 {
+                               compatible = "atmel,at91sam9260-shdwc";
+                               reg = <0xfffffd10 0x10>;
+                       };
+
+                       pit: timer@fffffd30 {
+                               compatible = "atmel,at91sam9260-pit";
+                               reg = <0xfffffd30 0xf>;
+                               interrupts = <1 4>;
+                       };
+
+                       tcb0: timer@fffa0000 {
+                               compatible = "atmel,at91rm9200-tcb";
+                               reg = <0xfffa0000 0x100>;
+                               interrupts = <17 4 18 4 19 4>;
+                       };
+
+                       tcb1: timer@fffdc000 {
+                               compatible = "atmel,at91rm9200-tcb";
+                               reg = <0xfffdc000 0x100>;
+                               interrupts = <26 4 27 4 28 4>;
+                       };
+
+                       pioA: gpio@fffff400 {
+                               compatible = "atmel,at91rm9200-gpio";
+                               reg = <0xfffff400 0x100>;
+                               interrupts = <2 4>;
+                               #gpio-cells = <2>;
+                               gpio-controller;
+                               interrupt-controller;
+                       };
+
+                       pioB: gpio@fffff600 {
+                               compatible = "atmel,at91rm9200-gpio";
+                               reg = <0xfffff600 0x100>;
+                               interrupts = <3 4>;
+                               #gpio-cells = <2>;
+                               gpio-controller;
+                               interrupt-controller;
+                       };
+
+                       pioC: gpio@fffff800 {
+                               compatible = "atmel,at91rm9200-gpio";
+                               reg = <0xfffff800 0x100>;
+                               interrupts = <4 4>;
+                               #gpio-cells = <2>;
+                               gpio-controller;
+                               interrupt-controller;
+                       };
+
                        dbgu: serial@fffff200 {
                                compatible = "atmel,at91sam9260-usart";
                                reg = <0xfffff200 0x200>;
-                               interrupts = <1>;
+                               interrupts = <1 4>;
                                status = "disabled";
                        };
 
                        usart0: serial@fffb0000 {
                                compatible = "atmel,at91sam9260-usart";
                                reg = <0xfffb0000 0x200>;
-                               interrupts = <6>;
+                               interrupts = <6 4>;
                                atmel,use-dma-rx;
                                atmel,use-dma-tx;
                                status = "disabled";
                        usart1: serial@fffb4000 {
                                compatible = "atmel,at91sam9260-usart";
                                reg = <0xfffb4000 0x200>;
-                               interrupts = <7>;
+                               interrupts = <7 4>;
                                atmel,use-dma-rx;
                                atmel,use-dma-tx;
                                status = "disabled";
                        usart2: serial@fffb8000 {
                                compatible = "atmel,at91sam9260-usart";
                                reg = <0xfffb8000 0x200>;
-                               interrupts = <8>;
+                               interrupts = <8 4>;
                                atmel,use-dma-rx;
                                atmel,use-dma-tx;
                                status = "disabled";
                        usart3: serial@fffd0000 {
                                compatible = "atmel,at91sam9260-usart";
                                reg = <0xfffd0000 0x200>;
-                               interrupts = <23>;
+                               interrupts = <23 4>;
                                atmel,use-dma-rx;
                                atmel,use-dma-tx;
                                status = "disabled";
                        usart4: serial@fffd4000 {
                                compatible = "atmel,at91sam9260-usart";
                                reg = <0xfffd4000 0x200>;
-                               interrupts = <24>;
+                               interrupts = <24 4>;
                                atmel,use-dma-rx;
                                atmel,use-dma-tx;
                                status = "disabled";
                        usart5: serial@fffd8000 {
                                compatible = "atmel,at91sam9260-usart";
                                reg = <0xfffd8000 0x200>;
-                               interrupts = <25>;
+                               interrupts = <25 4>;
                                atmel,use-dma-rx;
                                atmel,use-dma-tx;
                                status = "disabled";
                        macb0: ethernet@fffc4000 {
                                compatible = "cdns,at32ap7000-macb", "cdns,macb";
                                reg = <0xfffc4000 0x100>;
-                               interrupts = <21>;
+                               interrupts = <21 4>;
+                               status = "disabled";
+                       };
+
+                       usb1: gadget@fffa4000 {
+                               compatible = "atmel,at91rm9200-udc";
+                               reg = <0xfffa4000 0x4000>;
+                               interrupts = <10 4>;
                                status = "disabled";
                        };
                };
+
+               nand0: nand@40000000 {
+                       compatible = "atmel,at91rm9200-nand";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x40000000 0x10000000
+                              0xffffe800 0x200
+                             >;
+                       atmel,nand-addr-offset = <21>;
+                       atmel,nand-cmd-offset = <22>;
+                       gpios = <&pioC 13 0
+                                &pioC 14 0
+                                0
+                               >;
+                       status = "disabled";
+               };
+
+               usb0: ohci@00500000 {
+                       compatible = "atmel,at91rm9200-ohci", "usb-ohci";
+                       reg = <0x00500000 0x100000>;
+                       interrupts = <20 4>;
+                       status = "disabled";
+               };
+       };
+
+       i2c@0 {
+               compatible = "i2c-gpio";
+               gpios = <&pioA 23 0 /* sda */
+                        &pioA 24 0 /* scl */
+                       >;
+               i2c-gpio,sda-open-drain;
+               i2c-gpio,scl-open-drain;
+               i2c-gpio,delay-us = <2>;        /* ~100 kHz */
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
        };
 };
diff --git a/arch/arm/boot/dts/at91sam9g25ek.dts b/arch/arm/boot/dts/at91sam9g25ek.dts
new file mode 100644 (file)
index 0000000..ac0dc00
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * at91sam9g25ek.dts - Device Tree file for AT91SAM9G25-EK board
+ *
+ *  Copyright (C) 2012 Atmel,
+ *                2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+/include/ "at91sam9x5.dtsi"
+/include/ "at91sam9x5cm.dtsi"
+
+/ {
+       model = "Atmel AT91SAM9G25-EK";
+       compatible = "atmel,at91sam9g25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+
+       chosen {
+               bootargs = "128M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs";
+       };
+
+       ahb {
+               apb {
+                       dbgu: serial@fffff200 {
+                               status = "okay";
+                       };
+
+                       usart0: serial@f801c000 {
+                               status = "okay";
+                       };
+
+                       macb0: ethernet@f802c000 {
+                               phy-mode = "rmii";
+                               status = "okay";
+                       };
+               };
+
+               usb0: ohci@00600000 {
+                       status = "okay";
+                       num-ports = <2>;
+                       atmel,vbus-gpio = <&pioD 19 0
+                                          &pioD 20 0
+                                         >;
+               };
+
+               usb1: ehci@00700000 {
+                       status = "okay";
+               };
+       };
+};
index fffa005300a4274fa29e2c74e610333ae729ac11..3d0c32fb218f4682a1400b38fc00e51195f85752 100644 (file)
                serial2 = &usart1;
                serial3 = &usart2;
                serial4 = &usart3;
+               gpio0 = &pioA;
+               gpio1 = &pioB;
+               gpio2 = &pioC;
+               gpio3 = &pioD;
+               gpio4 = &pioE;
+               tcb0 = &tcb0;
+               tcb1 = &tcb1;
        };
        cpus {
                cpu@0 {
                        ranges;
 
                        aic: interrupt-controller@fffff000 {
-                               #interrupt-cells = <1>;
+                               #interrupt-cells = <2>;
                                compatible = "atmel,at91rm9200-aic";
                                interrupt-controller;
                                interrupt-parent;
                                reg = <0xfffff000 0x200>;
                        };
 
+                       ramc0: ramc@ffffe400 {
+                               compatible = "atmel,at91sam9g45-ddramc";
+                               reg = <0xffffe400 0x200
+                                      0xffffe600 0x200>;
+                       };
+
+                       pmc: pmc@fffffc00 {
+                               compatible = "atmel,at91rm9200-pmc";
+                               reg = <0xfffffc00 0x100>;
+                       };
+
+                       rstc@fffffd00 {
+                               compatible = "atmel,at91sam9g45-rstc";
+                               reg = <0xfffffd00 0x10>;
+                       };
+
+                       pit: timer@fffffd30 {
+                               compatible = "atmel,at91sam9260-pit";
+                               reg = <0xfffffd30 0xf>;
+                               interrupts = <1 4>;
+                       };
+
+
+                       shdwc@fffffd10 {
+                               compatible = "atmel,at91sam9rl-shdwc";
+                               reg = <0xfffffd10 0x10>;
+                       };
+
+                       tcb0: timer@fff7c000 {
+                               compatible = "atmel,at91rm9200-tcb";
+                               reg = <0xfff7c000 0x100>;
+                               interrupts = <18 4>;
+                       };
+
+                       tcb1: timer@fffd4000 {
+                               compatible = "atmel,at91rm9200-tcb";
+                               reg = <0xfffd4000 0x100>;
+                               interrupts = <18 4>;
+                       };
+
                        dma: dma-controller@ffffec00 {
                                compatible = "atmel,at91sam9g45-dma";
                                reg = <0xffffec00 0x200>;
-                               interrupts = <21>;
+                               interrupts = <21 4>;
+                       };
+
+                       pioA: gpio@fffff200 {
+                               compatible = "atmel,at91rm9200-gpio";
+                               reg = <0xfffff200 0x100>;
+                               interrupts = <2 4>;
+                               #gpio-cells = <2>;
+                               gpio-controller;
+                               interrupt-controller;
+                       };
+
+                       pioB: gpio@fffff400 {
+                               compatible = "atmel,at91rm9200-gpio";
+                               reg = <0xfffff400 0x100>;
+                               interrupts = <3 4>;
+                               #gpio-cells = <2>;
+                               gpio-controller;
+                               interrupt-controller;
+                       };
+
+                       pioC: gpio@fffff600 {
+                               compatible = "atmel,at91rm9200-gpio";
+                               reg = <0xfffff600 0x100>;
+                               interrupts = <4 4>;
+                               #gpio-cells = <2>;
+                               gpio-controller;
+                               interrupt-controller;
+                       };
+
+                       pioD: gpio@fffff800 {
+                               compatible = "atmel,at91rm9200-gpio";
+                               reg = <0xfffff800 0x100>;
+                               interrupts = <5 4>;
+                               #gpio-cells = <2>;
+                               gpio-controller;
+                               interrupt-controller;
+                       };
+
+                       pioE: gpio@fffffa00 {
+                               compatible = "atmel,at91rm9200-gpio";
+                               reg = <0xfffffa00 0x100>;
+                               interrupts = <5 4>;
+                               #gpio-cells = <2>;
+                               gpio-controller;
+                               interrupt-controller;
                        };
 
                        dbgu: serial@ffffee00 {
                                compatible = "atmel,at91sam9260-usart";
                                reg = <0xffffee00 0x200>;
-                               interrupts = <1>;
+                               interrupts = <1 4>;
                                status = "disabled";
                        };
 
                        usart0: serial@fff8c000 {
                                compatible = "atmel,at91sam9260-usart";
                                reg = <0xfff8c000 0x200>;
-                               interrupts = <7>;
+                               interrupts = <7 4>;
                                atmel,use-dma-rx;
                                atmel,use-dma-tx;
                                status = "disabled";
                        usart1: serial@fff90000 {
                                compatible = "atmel,at91sam9260-usart";
                                reg = <0xfff90000 0x200>;
-                               interrupts = <8>;
+                               interrupts = <8 4>;
                                atmel,use-dma-rx;
                                atmel,use-dma-tx;
                                status = "disabled";
                        usart2: serial@fff94000 {
                                compatible = "atmel,at91sam9260-usart";
                                reg = <0xfff94000 0x200>;
-                               interrupts = <9>;
+                               interrupts = <9 4>;
                                atmel,use-dma-rx;
                                atmel,use-dma-tx;
                                status = "disabled";
                        usart3: serial@fff98000 {
                                compatible = "atmel,at91sam9260-usart";
                                reg = <0xfff98000 0x200>;
-                               interrupts = <10>;
+                               interrupts = <10 4>;
                                atmel,use-dma-rx;
                                atmel,use-dma-tx;
                                status = "disabled";
                        macb0: ethernet@fffbc000 {
                                compatible = "cdns,at32ap7000-macb", "cdns,macb";
                                reg = <0xfffbc000 0x100>;
-                               interrupts = <25>;
+                               interrupts = <25 4>;
                                status = "disabled";
                        };
                };
+
+               nand0: nand@40000000 {
+                       compatible = "atmel,at91rm9200-nand";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x40000000 0x10000000
+                              0xffffe200 0x200
+                             >;
+                       atmel,nand-addr-offset = <21>;
+                       atmel,nand-cmd-offset = <22>;
+                       gpios = <&pioC 8 0
+                                &pioC 14 0
+                                0
+                               >;
+                       status = "disabled";
+               };
+
+               usb0: ohci@00700000 {
+                       compatible = "atmel,at91rm9200-ohci", "usb-ohci";
+                       reg = <0x00700000 0x100000>;
+                       interrupts = <22 4>;
+                       status = "disabled";
+               };
+
+               usb1: ehci@00800000 {
+                       compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
+                       reg = <0x00800000 0x100000>;
+                       interrupts = <22 4>;
+                       status = "disabled";
+               };
+       };
+
+       i2c@0 {
+               compatible = "i2c-gpio";
+               gpios = <&pioA 20 0 /* sda */
+                        &pioA 21 0 /* scl */
+                       >;
+               i2c-gpio,sda-open-drain;
+               i2c-gpio,scl-open-drain;
+               i2c-gpio,delay-us = <5>;        /* ~100 kHz */
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
        };
 };
index a387e7704ce1e42d2647a19a85311668507a861d..c4c8ae4123d522d4f342f2ebc8ddff1e69126a05 100644 (file)
        compatible = "atmel,at91sam9m10g45ek", "atmel,at91sam9g45", "atmel,at91sam9";
 
        chosen {
-               bootargs = "mem=64M console=ttyS0,115200 mtdparts=atmel_nand:4M(bootstrap/uboot/kernel)ro,60M(rootfs),-(data) root=/dev/mtdblock1 rw rootfstype=jffs2";
+               bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2";
        };
 
        memory@70000000 {
                reg = <0x70000000 0x4000000>;
        };
 
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               main_clock: clock@0 {
+                       compatible = "atmel,osc", "fixed-clock";
+                       clock-frequency = <12000000>;
+               };
+       };
+
        ahb {
                apb {
                        dbgu: serial@ffffee00 {
                                status = "okay";
                        };
                };
+
+               nand0: nand@40000000 {
+                       nand-bus-width = <8>;
+                       nand-ecc-mode = "soft";
+                       nand-on-flash-bbt;
+                       status = "okay";
+
+                       boot@0 {
+                               label = "bootstrap/uboot/kernel";
+                               reg = <0x0 0x400000>;
+                       };
+
+                       rootfs@400000 {
+                               label = "rootfs";
+                               reg = <0x400000 0x3C00000>;
+                       };
+
+                       data@4000000 {
+                               label = "data";
+                               reg = <0x4000000 0xC000000>;
+                       };
+               };
+
+               usb0: ohci@00700000 {
+                       status = "okay";
+                       num-ports = <2>;
+                       atmel,vbus-gpio = <&pioD 1 0
+                                          &pioD 3 0>;
+               };
+
+               usb1: ehci@00800000 {
+                       status = "okay";
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               d8 {
+                       label = "d8";
+                       gpios = <&pioD 30 0>;
+                       linux,default-trigger = "heartbeat";
+               };
+
+               d6 {
+                       label = "d6";
+                       gpios = <&pioD 0 1>;
+                       linux,default-trigger = "nand-disk";
+               };
+
+               d7 {
+                       label = "d7";
+                       gpios = <&pioD 31 1>;
+                       linux,default-trigger = "mmc0";
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               left_click {
+                       label = "left_click";
+                       gpios = <&pioB 6 1>;
+                       linux,code = <272>;
+                       gpio-key,wakeup;
+               };
+
+               right_click {
+                       label = "right_click";
+                       gpios = <&pioB 7 1>;
+                       linux,code = <273>;
+                       gpio-key,wakeup;
+               };
+
+               left {
+                       label = "Joystick Left";
+                       gpios = <&pioB 14 1>;
+                       linux,code = <105>;
+               };
+
+               right {
+                       label = "Joystick Right";
+                       gpios = <&pioB 15 1>;
+                       linux,code = <106>;
+               };
+
+               up {
+                       label = "Joystick Up";
+                       gpios = <&pioB 16 1>;
+                       linux,code = <103>;
+               };
+
+               down {
+                       label = "Joystick Down";
+                       gpios = <&pioB 17 1>;
+                       linux,code = <108>;
+               };
+
+               enter {
+                       label = "Joystick Press";
+                       gpios = <&pioB 18 1>;
+                       linux,code = <28>;
+               };
        };
 };
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
new file mode 100644 (file)
index 0000000..c111001
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * at91sam9x5.dtsi - Device Tree Include file for AT91SAM9x5 family SoC
+ *                   applies to AT91SAM9G15, AT91SAM9G25, AT91SAM9G35,
+ *                   AT91SAM9X25, AT91SAM9X35 SoC
+ *
+ *  Copyright (C) 2012 Atmel,
+ *                2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+       model = "Atmel AT91SAM9x5 family SoC";
+       compatible = "atmel,at91sam9x5";
+       interrupt-parent = <&aic>;
+
+       aliases {
+               serial0 = &dbgu;
+               serial1 = &usart0;
+               serial2 = &usart1;
+               serial3 = &usart2;
+               gpio0 = &pioA;
+               gpio1 = &pioB;
+               gpio2 = &pioC;
+               gpio3 = &pioD;
+               tcb0 = &tcb0;
+               tcb1 = &tcb1;
+       };
+       cpus {
+               cpu@0 {
+                       compatible = "arm,arm926ejs";
+               };
+       };
+
+       memory@20000000 {
+               reg = <0x20000000 0x10000000>;
+       };
+
+       ahb {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               apb {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       aic: interrupt-controller@fffff000 {
+                               #interrupt-cells = <2>;
+                               compatible = "atmel,at91rm9200-aic";
+                               interrupt-controller;
+                               interrupt-parent;
+                               reg = <0xfffff000 0x200>;
+                       };
+
+                       ramc0: ramc@ffffe800 {
+                               compatible = "atmel,at91sam9g45-ddramc";
+                               reg = <0xffffe800 0x200>;
+                       };
+
+                       pmc: pmc@fffffc00 {
+                               compatible = "atmel,at91rm9200-pmc";
+                               reg = <0xfffffc00 0x100>;
+                       };
+
+                       rstc@fffffe00 {
+                               compatible = "atmel,at91sam9g45-rstc";
+                               reg = <0xfffffe00 0x10>;
+                       };
+
+                       shdwc@fffffe10 {
+                               compatible = "atmel,at91sam9x5-shdwc";
+                               reg = <0xfffffe10 0x10>;
+                       };
+
+                       pit: timer@fffffe30 {
+                               compatible = "atmel,at91sam9260-pit";
+                               reg = <0xfffffe30 0xf>;
+                               interrupts = <1 4>;
+                       };
+
+                       tcb0: timer@f8008000 {
+                               compatible = "atmel,at91sam9x5-tcb";
+                               reg = <0xf8008000 0x100>;
+                               interrupts = <17 4>;
+                       };
+
+                       tcb1: timer@f800c000 {
+                               compatible = "atmel,at91sam9x5-tcb";
+                               reg = <0xf800c000 0x100>;
+                               interrupts = <17 4>;
+                       };
+
+                       dma0: dma-controller@ffffec00 {
+                               compatible = "atmel,at91sam9g45-dma";
+                               reg = <0xffffec00 0x200>;
+                               interrupts = <20 4>;
+                       };
+
+                       dma1: dma-controller@ffffee00 {
+                               compatible = "atmel,at91sam9g45-dma";
+                               reg = <0xffffee00 0x200>;
+                               interrupts = <21 4>;
+                       };
+
+                       pioA: gpio@fffff400 {
+                               compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+                               reg = <0xfffff400 0x100>;
+                               interrupts = <2 4>;
+                               #gpio-cells = <2>;
+                               gpio-controller;
+                               interrupt-controller;
+                       };
+
+                       pioB: gpio@fffff600 {
+                               compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+                               reg = <0xfffff600 0x100>;
+                               interrupts = <2 4>;
+                               #gpio-cells = <2>;
+                               gpio-controller;
+                               interrupt-controller;
+                       };
+
+                       pioC: gpio@fffff800 {
+                               compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+                               reg = <0xfffff800 0x100>;
+                               interrupts = <3 4>;
+                               #gpio-cells = <2>;
+                               gpio-controller;
+                               interrupt-controller;
+                       };
+
+                       pioD: gpio@fffffa00 {
+                               compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+                               reg = <0xfffffa00 0x100>;
+                               interrupts = <3 4>;
+                               #gpio-cells = <2>;
+                               gpio-controller;
+                               interrupt-controller;
+                       };
+
+                       dbgu: serial@fffff200 {
+                               compatible = "atmel,at91sam9260-usart";
+                               reg = <0xfffff200 0x200>;
+                               interrupts = <1 4>;
+                               status = "disabled";
+                       };
+
+                       usart0: serial@f801c000 {
+                               compatible = "atmel,at91sam9260-usart";
+                               reg = <0xf801c000 0x200>;
+                               interrupts = <5 4>;
+                               atmel,use-dma-rx;
+                               atmel,use-dma-tx;
+                               status = "disabled";
+                       };
+
+                       usart1: serial@f8020000 {
+                               compatible = "atmel,at91sam9260-usart";
+                               reg = <0xf8020000 0x200>;
+                               interrupts = <6 4>;
+                               atmel,use-dma-rx;
+                               atmel,use-dma-tx;
+                               status = "disabled";
+                       };
+
+                       usart2: serial@f8024000 {
+                               compatible = "atmel,at91sam9260-usart";
+                               reg = <0xf8024000 0x200>;
+                               interrupts = <7 4>;
+                               atmel,use-dma-rx;
+                               atmel,use-dma-tx;
+                               status = "disabled";
+                       };
+
+                       macb0: ethernet@f802c000 {
+                               compatible = "cdns,at32ap7000-macb", "cdns,macb";
+                               reg = <0xf802c000 0x100>;
+                               interrupts = <24 4>;
+                               status = "disabled";
+                       };
+
+                       macb1: ethernet@f8030000 {
+                               compatible = "cdns,at32ap7000-macb", "cdns,macb";
+                               reg = <0xf8030000 0x100>;
+                               interrupts = <27 4>;
+                               status = "disabled";
+                       };
+               };
+
+               nand0: nand@40000000 {
+                       compatible = "atmel,at91rm9200-nand";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x40000000 0x10000000
+                             >;
+                       atmel,nand-addr-offset = <21>;
+                       atmel,nand-cmd-offset = <22>;
+                       gpios = <&pioC 8 0
+                                &pioC 14 0
+                                0
+                               >;
+                       status = "disabled";
+               };
+
+               usb0: ohci@00600000 {
+                       compatible = "atmel,at91rm9200-ohci", "usb-ohci";
+                       reg = <0x00600000 0x100000>;
+                       interrupts = <22 4>;
+                       status = "disabled";
+               };
+
+               usb1: ehci@00700000 {
+                       compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
+                       reg = <0x00700000 0x100000>;
+                       interrupts = <22 4>;
+                       status = "disabled";
+               };
+       };
+
+       i2c@0 {
+               compatible = "i2c-gpio";
+               gpios = <&pioA 30 0 /* sda */
+                        &pioA 31 0 /* scl */
+                       >;
+               i2c-gpio,sda-open-drain;
+               i2c-gpio,scl-open-drain;
+               i2c-gpio,delay-us = <2>;        /* ~100 kHz */
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       i2c@1 {
+               compatible = "i2c-gpio";
+               gpios = <&pioC 0 0 /* sda */
+                        &pioC 1 0 /* scl */
+                       >;
+               i2c-gpio,sda-open-drain;
+               i2c-gpio,scl-open-drain;
+               i2c-gpio,delay-us = <2>;        /* ~100 kHz */
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+
+       i2c@2 {
+               compatible = "i2c-gpio";
+               gpios = <&pioB 4 0 /* sda */
+                        &pioB 5 0 /* scl */
+                       >;
+               i2c-gpio,sda-open-drain;
+               i2c-gpio,scl-open-drain;
+               i2c-gpio,delay-us = <2>;        /* ~100 kHz */
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+};
diff --git a/arch/arm/boot/dts/at91sam9x5cm.dtsi b/arch/arm/boot/dts/at91sam9x5cm.dtsi
new file mode 100644 (file)
index 0000000..67936f8
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * at91sam9x5cm.dtsi - Device Tree Include file for AT91SAM9x5 CPU Module
+ *
+ *  Copyright (C) 2012 Atmel,
+ *                2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/ {
+       memory@20000000 {
+               reg = <0x20000000 0x8000000>;
+       };
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               main_clock: clock@0 {
+                       compatible = "atmel,osc", "fixed-clock";
+                       clock-frequency = <12000000>;
+               };
+       };
+
+       ahb {
+               nand0: nand@40000000 {
+                       nand-bus-width = <8>;
+                       nand-ecc-mode = "soft";
+                       nand-on-flash-bbt;
+                       status = "okay";
+
+                       at91bootstrap@0 {
+                               label = "at91bootstrap";
+                               reg = <0x0 0x40000>;
+                       };
+
+                       uboot@40000 {
+                               label = "u-boot";
+                               reg = <0x40000 0x80000>;
+                       };
+
+                       ubootenv@c0000 {
+                               label = "U-Boot Env";
+                               reg = <0xc0000 0x140000>;
+                       };
+
+                       kernel@200000 {
+                               label = "kernel";
+                               reg = <0x200000 0x600000>;
+                       };
+
+                       rootfs@800000 {
+                               label = "rootfs";
+                               reg = <0x800000 0x1f800000>;
+                       };
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               pb18 {
+                       label = "pb18";
+                       gpios = <&pioB 18 1>;
+                       linux,default-trigger = "heartbeat";
+               };
+
+               pd21 {
+                       label = "pd21";
+                       gpios = <&pioD 21 0>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/db8500.dtsi b/arch/arm/boot/dts/db8500.dtsi
new file mode 100644 (file)
index 0000000..d73dce6
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2012 Linaro Ltd
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+       soc-u9500 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "stericsson,db8500";
+               interrupt-parent = <&intc>;
+               ranges;
+
+               intc: interrupt-controller@a0411000 {
+                       compatible = "arm,cortex-a9-gic";
+                       #interrupt-cells = <3>;
+                       #address-cells = <1>;
+                       interrupt-controller;
+                       interrupt-parent;
+                       reg = <0xa0411000 0x1000>,
+                             <0xa0410100 0x100>;
+               };
+
+               L2: l2-cache {
+                       compatible = "arm,pl310-cache";
+                       reg = <0xa0412000 0x1000>;
+                       interrupts = <0 13 4>;
+                       cache-unified;
+                       cache-level = <2>;
+               };
+
+               pmu {
+                       compatible = "arm,cortex-a9-pmu";
+                       interrupts = <0 7 0x4>;
+               };
+
+               timer@a0410600 {
+                       compatible = "arm,cortex-a9-twd-timer";
+                       reg = <0xa0410600 0x20>;
+                       interrupts = <1 13 0x304>;
+               };
+
+               rtc@80154000 {
+                       compatible = "stericsson,db8500-rtc";
+                       reg = <0x80154000 0x1000>;
+                       interrupts = <0 18 0x4>;
+               };
+
+               gpio0: gpio@8012e000 {
+                       compatible = "stericsson,db8500-gpio",
+                               "stmicroelectronics,nomadik-gpio";
+                       reg =  <0x8012e000 0x80>;
+                       interrupts = <0 119 0x4>;
+                       supports-sleepmode;
+                       gpio-controller;
+               };
+
+               gpio1: gpio@8012e080 {
+                       compatible = "stericsson,db8500-gpio",
+                               "stmicroelectronics,nomadik-gpio";
+                       reg =  <0x8012e080 0x80>;
+                       interrupts = <0 120 0x4>;
+                       supports-sleepmode;
+                       gpio-controller;
+               };
+
+               gpio2: gpio@8000e000 {
+                       compatible = "stericsson,db8500-gpio",
+                               "stmicroelectronics,nomadik-gpio";
+                       reg =  <0x8000e000 0x80>;
+                       interrupts = <0 121 0x4>;
+                       supports-sleepmode;
+                       gpio-controller;
+               };
+
+               gpio3: gpio@8000e080 {
+                       compatible = "stericsson,db8500-gpio",
+                               "stmicroelectronics,nomadik-gpio";
+                       reg =  <0x8000e080 0x80>;
+                       interrupts = <0 122 0x4>;
+                       supports-sleepmode;
+                       gpio-controller;
+               };
+
+               gpio4: gpio@8000e100 {
+                       compatible = "stericsson,db8500-gpio",
+                               "stmicroelectronics,nomadik-gpio";
+                       reg =  <0x8000e100 0x80>;
+                       interrupts = <0 123 0x4>;
+                       supports-sleepmode;
+                       gpio-controller;
+               };
+
+               gpio5: gpio@8000e180 {
+                       compatible = "stericsson,db8500-gpio",
+                               "stmicroelectronics,nomadik-gpio";
+                       reg =  <0x8000e180 0x80>;
+                       interrupts = <0 124 0x4>;
+                       supports-sleepmode;
+                       gpio-controller;
+               };
+
+               gpio6: gpio@8011e000 {
+                       compatible = "stericsson,db8500-gpio",
+                               "stmicroelectronics,nomadik-gpio";
+                       reg =  <0x8011e000 0x80>;
+                       interrupts = <0 125 0x4>;
+                       supports-sleepmode;
+                       gpio-controller;
+               };
+
+               gpio7: gpio@8011e080 {
+                       compatible = "stericsson,db8500-gpio",
+                               "stmicroelectronics,nomadik-gpio";
+                       reg =  <0x8011e080 0x80>;
+                       interrupts = <0 126 0x4>;
+                       supports-sleepmode;
+                       gpio-controller;
+               };
+
+               gpio8: gpio@a03fe000 {
+                       compatible = "stericsson,db8500-gpio",
+                               "stmicroelectronics,nomadik-gpio";
+                       reg =  <0xa03fe000 0x80>;
+                       interrupts = <0 127 0x4>;
+                       supports-sleepmode;
+                       gpio-controller;
+               };
+
+               usb@a03e0000 {
+                       compatible = "stericsson,db8500-musb",
+                               "mentor,musb";
+                       reg = <0xa03e0000 0x10000>;
+                       interrupts = <0 23 0x4>;
+               };
+
+               dma-controller@801C0000 {
+                       compatible = "stericsson,db8500-dma40",
+                                       "stericsson,dma40";
+                       reg = <0x801C0000 0x1000 0x40010000 0x800>;
+                       interrupts = <0 25 0x4>;
+               };
+
+               prcmu@80157000 {
+                       compatible = "stericsson,db8500-prcmu";
+                       reg = <0x80157000 0x1000>;
+                       interrupts = <46 47>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       ab8500@5 {
+                               compatible = "stericsson,ab8500";
+                               reg = <5>; /* mailbox 5 is i2c */
+                               interrupts = <0 40 0x4>;
+                       };
+               };
+
+               i2c@80004000 {
+                       compatible = "stericsson,db8500-i2c", "stmicroelectronics,nomadik-i2c";
+                       reg = <0x80004000 0x1000>;
+                       interrupts = <0 21 0x4>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               i2c@80122000 {
+                       compatible = "stericsson,db8500-i2c", "stmicroelectronics,nomadik-i2c";
+                       reg = <0x80122000 0x1000>;
+                       interrupts = <0 22 0x4>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               i2c@80128000 {
+                       compatible = "stericsson,db8500-i2c", "stmicroelectronics,nomadik-i2c";
+                       reg = <0x80128000 0x1000>;
+                       interrupts = <0 55 0x4>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               i2c@80110000 {
+                       compatible = "stericsson,db8500-i2c", "stmicroelectronics,nomadik-i2c";
+                       reg = <0x80110000 0x1000>;
+                       interrupts = <0 12 0x4>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               i2c@8012a000 {
+                       compatible = "stericsson,db8500-i2c", "stmicroelectronics,nomadik-i2c";
+                       reg = <0x8012a000 0x1000>;
+                       interrupts = <0 51 0x4>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               ssp@80002000 {
+                       compatible = "arm,pl022", "arm,primecell";
+                       reg = <80002000 0x1000>;
+                       interrupts = <0 14 0x4>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+
+                       // Add one of these for each child device
+                       cs-gpios = <&gpio0 31 &gpio4 14 &gpio4 16 &gpio6 22 &gpio7 0>;
+
+               };
+
+               uart@80120000 {
+                       compatible = "arm,pl011", "arm,primecell";
+                       reg = <0x80120000 0x1000>;
+                       interrupts = <0 11 0x4>;
+                       status = "disabled";
+               };
+               uart@80121000 {
+                       compatible = "arm,pl011", "arm,primecell";
+                       reg = <0x80121000 0x1000>;
+                       interrupts = <0 19 0x4>;
+                       status = "disabled";
+               };
+               uart@80007000 {
+                       compatible = "arm,pl011", "arm,primecell";
+                       reg = <0x80007000 0x1000>;
+                       interrupts = <0 26 0x4>;
+                       status = "disabled";
+               };
+
+               sdi@80126000 {
+                       compatible = "arm,pl18x", "arm,primecell";
+                       reg = <0x80126000 0x1000>;
+                       interrupts = <0 60 0x4>;
+                       status = "disabled";
+               };
+               sdi@80118000 {
+                       compatible = "arm,pl18x", "arm,primecell";
+                       reg = <0x80118000 0x1000>;
+                       interrupts = <0 50 0x4>;
+                       status = "disabled";
+               };
+               sdi@80005000 {
+                       compatible = "arm,pl18x", "arm,primecell";
+                       reg = <0x80005000 0x1000>;
+                       interrupts = <0 41 0x4>;
+                       status = "disabled";
+               };
+               sdi@80119000 {
+                       compatible = "arm,pl18x", "arm,primecell";
+                       reg = <0x80119000 0x1000>;
+                       interrupts = <0 59 0x4>;
+                       status = "disabled";
+               };
+               sdi@80114000 {
+                       compatible = "arm,pl18x", "arm,primecell";
+                       reg = <0x80114000 0x1000>;
+                       interrupts = <0 99 0x4>;
+                       status = "disabled";
+               };
+               sdi@80008000 {
+                       compatible = "arm,pl18x", "arm,primecell";
+                       reg = <0x80114000 0x1000>;
+                       interrupts = <0 100 0x4>;
+                       status = "disabled";
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
new file mode 100644 (file)
index 0000000..399d17b
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * SAMSUNG SMDK5250 board device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+/include/ "exynos5250.dtsi"
+
+/ {
+       model = "SAMSUNG SMDK5250 board based on EXYNOS5250";
+       compatible = "samsung,smdk5250", "samsung,exynos5250";
+
+       memory {
+               reg = <0x40000000 0x80000000>;
+       };
+
+       chosen {
+               bootargs = "root=/dev/ram0 rw ramdisk=8192 console=ttySAC1,115200";
+       };
+};
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
new file mode 100644 (file)
index 0000000..dfc4335
--- /dev/null
@@ -0,0 +1,413 @@
+/*
+ * SAMSUNG EXYNOS5250 SoC device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * SAMSUNG EXYNOS5250 SoC device nodes are listed in this file.
+ * EXYNOS5250 based board files can include this file and provide
+ * values for board specfic bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * EXYNOS5250 SoC. As device tree coverage for EXYNOS5250 increases,
+ * additional nodes can be added to this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/include/ "skeleton.dtsi"
+
+/ {
+       compatible = "samsung,exynos5250";
+       interrupt-parent = <&gic>;
+
+       gic:interrupt-controller@10490000 {
+               compatible = "arm,cortex-a9-gic";
+               #interrupt-cells = <3>;
+               interrupt-controller;
+               reg = <0x10490000 0x1000>, <0x10480000 0x100>;
+       };
+
+       watchdog {
+               compatible = "samsung,s3c2410-wdt";
+               reg = <0x101D0000 0x100>;
+               interrupts = <0 42 0>;
+       };
+
+       rtc {
+               compatible = "samsung,s3c6410-rtc";
+               reg = <0x101E0000 0x100>;
+               interrupts = <0 43 0>, <0 44 0>;
+       };
+
+       sdhci@12200000 {
+               compatible = "samsung,exynos4210-sdhci";
+               reg = <0x12200000 0x100>;
+               interrupts = <0 75 0>;
+       };
+
+       sdhci@12210000 {
+               compatible = "samsung,exynos4210-sdhci";
+               reg = <0x12210000 0x100>;
+               interrupts = <0 76 0>;
+       };
+
+       sdhci@12220000 {
+               compatible = "samsung,exynos4210-sdhci";
+               reg = <0x12220000 0x100>;
+               interrupts = <0 77 0>;
+       };
+
+       sdhci@12230000 {
+               compatible = "samsung,exynos4210-sdhci";
+               reg = <0x12230000 0x100>;
+               interrupts = <0 78 0>;
+       };
+
+       serial@12C00000 {
+               compatible = "samsung,exynos4210-uart";
+               reg = <0x12C00000 0x100>;
+               interrupts = <0 51 0>;
+       };
+
+       serial@12C10000 {
+               compatible = "samsung,exynos4210-uart";
+               reg = <0x12C10000 0x100>;
+               interrupts = <0 52 0>;
+       };
+
+       serial@12C20000 {
+               compatible = "samsung,exynos4210-uart";
+               reg = <0x12C20000 0x100>;
+               interrupts = <0 53 0>;
+       };
+
+       serial@12C30000 {
+               compatible = "samsung,exynos4210-uart";
+               reg = <0x12C30000 0x100>;
+               interrupts = <0 54 0>;
+       };
+
+       i2c@12C60000 {
+               compatible = "samsung,s3c2440-i2c";
+               reg = <0x12C60000 0x100>;
+               interrupts = <0 56 0>;
+       };
+
+       i2c@12C70000 {
+               compatible = "samsung,s3c2440-i2c";
+               reg = <0x12C70000 0x100>;
+               interrupts = <0 57 0>;
+       };
+
+       i2c@12C80000 {
+               compatible = "samsung,s3c2440-i2c";
+               reg = <0x12C80000 0x100>;
+               interrupts = <0 58 0>;
+       };
+
+       i2c@12C90000 {
+               compatible = "samsung,s3c2440-i2c";
+               reg = <0x12C90000 0x100>;
+               interrupts = <0 59 0>;
+       };
+
+       i2c@12CA0000 {
+               compatible = "samsung,s3c2440-i2c";
+               reg = <0x12CA0000 0x100>;
+               interrupts = <0 60 0>;
+       };
+
+       i2c@12CB0000 {
+               compatible = "samsung,s3c2440-i2c";
+               reg = <0x12CB0000 0x100>;
+               interrupts = <0 61 0>;
+       };
+
+       i2c@12CC0000 {
+               compatible = "samsung,s3c2440-i2c";
+               reg = <0x12CC0000 0x100>;
+               interrupts = <0 62 0>;
+       };
+
+       i2c@12CD0000 {
+               compatible = "samsung,s3c2440-i2c";
+               reg = <0x12CD0000 0x100>;
+               interrupts = <0 63 0>;
+       };
+
+       amba {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "arm,amba-bus";
+               interrupt-parent = <&gic>;
+               ranges;
+
+               pdma0: pdma@121A0000 {
+                       compatible = "arm,pl330", "arm,primecell";
+                       reg = <0x121A0000 0x1000>;
+                       interrupts = <0 34 0>;
+               };
+
+               pdma1: pdma@121B0000 {
+                       compatible = "arm,pl330", "arm,primecell";
+                       reg = <0x121B0000 0x1000>;
+                       interrupts = <0 35 0>;
+               };
+
+               mdma0: pdma@10800000 {
+                       compatible = "arm,pl330", "arm,primecell";
+                       reg = <0x10800000 0x1000>;
+                       interrupts = <0 33 0>;
+               };
+
+               mdma1: pdma@11C10000 {
+                       compatible = "arm,pl330", "arm,primecell";
+                       reg = <0x11C10000 0x1000>;
+                       interrupts = <0 124 0>;
+               };
+       };
+
+       gpio-controllers {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               gpio-controller;
+               ranges;
+
+               gpa0: gpio-controller@11400000 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x11400000 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpa1: gpio-controller@11400020 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x11400020 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpa2: gpio-controller@11400040 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x11400040 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpb0: gpio-controller@11400060 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x11400060 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpb1: gpio-controller@11400080 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x11400080 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpb2: gpio-controller@114000A0 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x114000A0 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpb3: gpio-controller@114000C0 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x114000C0 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpc0: gpio-controller@114000E0 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x114000E0 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpc1: gpio-controller@11400100 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x11400100 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpc2: gpio-controller@11400120 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x11400120 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpc3: gpio-controller@11400140 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x11400140 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpd0: gpio-controller@11400160 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x11400160 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpd1: gpio-controller@11400180 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x11400180 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpy0: gpio-controller@114001A0 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x114001A0 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpy1: gpio-controller@114001C0 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x114001C0 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpy2: gpio-controller@114001E0 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x114001E0 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpy3: gpio-controller@11400200 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x11400200 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpy4: gpio-controller@11400220 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x11400220 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpy5: gpio-controller@11400240 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x11400240 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpy6: gpio-controller@11400260 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x11400260 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpx0: gpio-controller@11400C00 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x11400C00 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpx1: gpio-controller@11400C20 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x11400C20 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpx2: gpio-controller@11400C40 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x11400C40 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpx3: gpio-controller@11400C60 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x11400C60 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpe0: gpio-controller@13400000 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x13400000 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpe1: gpio-controller@13400020 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x13400020 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpf0: gpio-controller@13400040 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x13400040 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpf1: gpio-controller@13400060 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x13400060 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpg0: gpio-controller@13400080 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x13400080 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpg1: gpio-controller@134000A0 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x134000A0 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpg2: gpio-controller@134000C0 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x134000C0 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gph0: gpio-controller@134000E0 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x134000E0 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gph1: gpio-controller@13400100 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x13400100 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpv0: gpio-controller@10D10000 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x10D10000 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpv1: gpio-controller@10D10020 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x10D10020 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpv2: gpio-controller@10D10040 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x10D10040 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpv3: gpio-controller@10D10060 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x10D10060 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpv4: gpio-controller@10D10080 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x10D10080 0x20>;
+                       #gpio-cells = <4>;
+               };
+
+               gpz: gpio-controller@03860000 {
+                       compatible = "samsung,exynos4-gpio";
+                       reg = <0x03860000 0x20>;
+                       #gpio-cells = <4>;
+               };
+       };
+};
index 305635bd45c01a91f178ee3e9d69ad3feea4644e..37c0ff9c8b90cb03f0ebb7fb2e1ce961ee4c141c 100644 (file)
                ranges;
 
                timer@fff10600 {
-                       compatible = "arm,smp-twd";
+                       compatible = "arm,cortex-a9-twd-timer";
                        reg = <0xfff10600 0x20>;
-                       interrupts = <1 13 0xf04>;
+                       interrupts = <1 13 0xf01>;
                };
 
                watchdog@fff10620 {
-                       compatible = "arm,cortex-a9-wdt";
+                       compatible = "arm,cortex-a9-twd-wdt";
                        reg = <0xfff10620 0x20>;
-                       interrupts = <1 14 0xf04>;
+                       interrupts = <1 14 0xf01>;
                };
 
                intc: interrupt-controller@fff11000 {
diff --git a/arch/arm/boot/dts/imx27-phytec-phycore.dts b/arch/arm/boot/dts/imx27-phytec-phycore.dts
new file mode 100644 (file)
index 0000000..a51a08f
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2012 Sascha Hauer, Pengutronix
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "imx27.dtsi"
+
+/ {
+       model = "Phytec pcm038";
+       compatible = "phytec,imx27-pcm038", "fsl,imx27";
+
+       memory {
+               reg = <0x0 0x0>;
+       };
+
+       soc {
+               aipi@10000000 { /* aipi */
+
+                       wdog@10002000 {
+                               status = "okay";
+                       };
+
+                       uart@1000a000 {
+                               fsl,uart-has-rtscts;
+                               status = "okay";
+                       };
+
+                       uart@1000b000 {
+                               fsl,uart-has-rtscts;
+                               status = "okay";
+                       };
+
+                       uart@1000c000 {
+                               fsl,uart-has-rtscts;
+                               status = "okay";
+                       };
+
+                       fec@1002b000 {
+                               status = "okay";
+                       };
+
+                       i2c@1001d000 {
+                               clock-frequency = <400000>;
+                               status = "okay";
+                               at24@4c {
+                                       compatible = "at,24c32";
+                                       pagesize = <32>;
+                                       reg = <0x52>;
+                               };
+                               pcf8563@51 {
+                                       compatible = "nxp,pcf8563";
+                                       reg = <0x51>;
+                               };
+                               lm75@4a {
+                                       compatible = "national,lm75";
+                                       reg = <0x4a>;
+                               };
+                       };
+               };
+       };
+
+       nor_flash@c0000000 {
+               compatible = "cfi-flash";
+               bank-width = <2>;
+               reg = <0xc0000000 0x02000000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+       };
+};
diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi
new file mode 100644 (file)
index 0000000..bc5e7d5
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2012 Sascha Hauer, Pengutronix
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+       aliases {
+               serial0 = &uart1;
+               serial1 = &uart2;
+               serial2 = &uart3;
+               serial3 = &uart4;
+               serial4 = &uart5;
+               serial5 = &uart6;
+       };
+
+       avic: avic-interrupt-controller@e0000000 {
+               compatible = "fsl,imx27-avic", "fsl,avic";
+               interrupt-controller;
+               #interrupt-cells = <1>;
+               reg = <0x10040000 0x1000>;
+       };
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               osc26m {
+                       compatible = "fsl,imx-osc26m", "fixed-clock";
+                       clock-frequency = <26000000>;
+               };
+       };
+
+       soc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               interrupt-parent = <&avic>;
+               ranges;
+
+               aipi@10000000 { /* AIPI1 */
+                       compatible = "fsl,aipi-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x10000000 0x10000000>;
+                       ranges;
+
+                       wdog@10002000 {
+                               compatible = "fsl,imx27-wdt", "fsl,imx21-wdt";
+                               reg = <0x10002000 0x4000>;
+                               interrupts = <27>;
+                               status = "disabled";
+                       };
+
+                       uart1: uart@1000a000 {
+                               compatible = "fsl,imx27-uart", "fsl,imx21-uart";
+                               reg = <0x1000a000 0x1000>;
+                               interrupts = <20>;
+                               status = "disabled";
+                       };
+
+                       uart2: uart@1000b000 {
+                               compatible = "fsl,imx27-uart", "fsl,imx21-uart";
+                               reg = <0x1000b000 0x1000>;
+                               interrupts = <19>;
+                               status = "disabled";
+                       };
+
+                       uart3: uart@1000c000 {
+                               compatible = "fsl,imx27-uart", "fsl,imx21-uart";
+                               reg = <0x1000c000 0x1000>;
+                               interrupts = <18>;
+                               status = "disabled";
+                       };
+
+                       uart4: uart@1000d000 {
+                               compatible = "fsl,imx27-uart", "fsl,imx21-uart";
+                               reg = <0x1000d000 0x1000>;
+                               interrupts = <17>;
+                               status = "disabled";
+                       };
+
+                       cspi1: cspi@1000e000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx27-cspi";
+                               reg = <0x1000e000 0x1000>;
+                               interrupts = <16>;
+                               status = "disabled";
+                       };
+
+                       cspi2: cspi@1000f000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx27-cspi";
+                               reg = <0x1000f000 0x1000>;
+                               interrupts = <15>;
+                               status = "disabled";
+                       };
+
+                       i2c1: i2c@10012000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx27-i2c", "fsl,imx1-i2c";
+                               reg = <0x10012000 0x1000>;
+                               interrupts = <12>;
+                               status = "disabled";
+                       };
+
+                       gpio1: gpio@10015000 {
+                               compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+                               reg = <0x10015000 0x100>;
+                               interrupts = <8>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                       };
+
+                       gpio2: gpio@10015100 {
+                               compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+                               reg = <0x10015100 0x100>;
+                               interrupts = <8>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                       };
+
+                       gpio3: gpio@10015200 {
+                               compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+                               reg = <0x10015200 0x100>;
+                               interrupts = <8>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                       };
+
+                       gpio4: gpio@10015300 {
+                               compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+                               reg = <0x10015300 0x100>;
+                               interrupts = <8>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                       };
+
+                       gpio5: gpio@10015400 {
+                               compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+                               reg = <0x10015400 0x100>;
+                               interrupts = <8>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                       };
+
+                       gpio6: gpio@10015500 {
+                               compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
+                               reg = <0x10015500 0x100>;
+                               interrupts = <8>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                       };
+
+                       cspi3: cspi@10017000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx27-cspi";
+                               reg = <0x10017000 0x1000>;
+                               interrupts = <6>;
+                               status = "disabled";
+                       };
+
+                       uart5: uart@1001b000 {
+                               compatible = "fsl,imx27-uart", "fsl,imx21-uart";
+                               reg = <0x1001b000 0x1000>;
+                               interrupts = <49>;
+                               status = "disabled";
+                       };
+
+                       uart6: uart@1001c000 {
+                               compatible = "fsl,imx27-uart", "fsl,imx21-uart";
+                               reg = <0x1001c000 0x1000>;
+                               interrupts = <48>;
+                               status = "disabled";
+                       };
+
+                       i2c2: i2c@1001d000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx27-i2c", "fsl,imx1-i2c";
+                               reg = <0x1001d000 0x1000>;
+                               interrupts = <1>;
+                               status = "disabled";
+                       };
+
+                       fec: fec@1002b000 {
+                               compatible = "fsl,imx27-fec";
+                               reg = <0x1002b000 0x4000>;
+                               interrupts = <50>;
+                               status = "disabled";
+                       };
+               };
+       };
+};
index 564cb8c19f1506363e25282f54a58d792b1bc9ef..9949e6060dee0e185ee865453aa70b83f312ebbb 100644 (file)
                                                compatible = "fsl,mc13892";
                                                spi-max-frequency = <6000000>;
                                                reg = <0>;
-                                               mc13xxx-irq-gpios = <&gpio1 8 0>;
-                                               fsl,mc13xxx-uses-regulator;
+                                               interrupt-parent = <&gpio1>;
+                                               interrupts = <8>;
+
+                                               regulators {
+                                                       sw1_reg: sw1 {
+                                                               regulator-min-microvolt = <600000>;
+                                                               regulator-max-microvolt = <1375000>;
+                                                               regulator-boot-on;
+                                                               regulator-always-on;
+                                                       };
+
+                                                       sw2_reg: sw2 {
+                                                               regulator-min-microvolt = <900000>;
+                                                               regulator-max-microvolt = <1850000>;
+                                                               regulator-boot-on;
+                                                               regulator-always-on;
+                                                       };
+
+                                                       sw3_reg: sw3 {
+                                                               regulator-min-microvolt = <1100000>;
+                                                               regulator-max-microvolt = <1850000>;
+                                                               regulator-boot-on;
+                                                               regulator-always-on;
+                                                       };
+
+                                                       sw4_reg: sw4 {
+                                                               regulator-min-microvolt = <1100000>;
+                                                               regulator-max-microvolt = <1850000>;
+                                                               regulator-boot-on;
+                                                               regulator-always-on;
+                                                       };
+
+                                                       vpll_reg: vpll {
+                                                               regulator-min-microvolt = <1050000>;
+                                                               regulator-max-microvolt = <1800000>;
+                                                               regulator-boot-on;
+                                                               regulator-always-on;
+                                                       };
+
+                                                       vdig_reg: vdig {
+                                                               regulator-min-microvolt = <1650000>;
+                                                               regulator-max-microvolt = <1650000>;
+                                                               regulator-boot-on;
+                                                       };
+
+                                                       vsd_reg: vsd {
+                                                               regulator-min-microvolt = <1800000>;
+                                                               regulator-max-microvolt = <3150000>;
+                                                       };
+
+                                                       vusb2_reg: vusb2 {
+                                                               regulator-min-microvolt = <2400000>;
+                                                               regulator-max-microvolt = <2775000>;
+                                                               regulator-boot-on;
+                                                               regulator-always-on;
+                                                       };
+
+                                                       vvideo_reg: vvideo {
+                                                               regulator-min-microvolt = <2775000>;
+                                                               regulator-max-microvolt = <2775000>;
+                                                       };
+
+                                                       vaudio_reg: vaudio {
+                                                               regulator-min-microvolt = <2300000>;
+                                                               regulator-max-microvolt = <3000000>;
+                                                       };
+
+                                                       vcam_reg: vcam {
+                                                               regulator-min-microvolt = <2500000>;
+                                                               regulator-max-microvolt = <3000000>;
+                                                       };
+
+                                                       vgen1_reg: vgen1 {
+                                                               regulator-min-microvolt = <1200000>;
+                                                               regulator-max-microvolt = <1200000>;
+                                                       };
+
+                                                       vgen2_reg: vgen2 {
+                                                               regulator-min-microvolt = <1200000>;
+                                                               regulator-max-microvolt = <3150000>;
+                                                               regulator-always-on;
+                                                       };
+
+                                                       vgen3_reg: vgen3 {
+                                                               regulator-min-microvolt = <1800000>;
+                                                               regulator-max-microvolt = <2900000>;
+                                                               regulator-always-on;
+                                                       };
+                                               };
                                        };
 
                                        flash: at45db321d@1 {
index c3977e0478b9a1ba7f9376d827fb377910f1275a..ce1c8238c8975c6b84f72304f7ff8ae68dda8c88 100644 (file)
                        usdhc@02198000 { /* uSDHC3 */
                                cd-gpios = <&gpio6 11 0>;
                                wp-gpios = <&gpio6 14 0>;
+                               vmmc-supply = <&reg_3p3v>;
                                status = "okay";
                        };
 
                        usdhc@0219c000 { /* uSDHC4 */
                                fsl,card-wired;
+                               vmmc-supply = <&reg_3p3v>;
                                status = "okay";
                        };
 
                };
        };
 
+       regulators {
+               compatible = "simple-bus";
+
+               reg_3p3v: 3p3v {
+                       compatible = "regulator-fixed";
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+       };
+
        leds {
                compatible = "gpio-leds";
 
index 08d920de72868a33347091a9d5f09dbc2147994d..4663a4e5a285dab5232c6bd285c17b6f2136a063 100644 (file)
                        usdhc@02198000 { /* uSDHC3 */
                                cd-gpios = <&gpio7 0 0>;
                                wp-gpios = <&gpio7 1 0>;
+                               vmmc-supply = <&reg_3p3v>;
                                status = "okay";
                        };
 
                        usdhc@0219c000 { /* uSDHC4 */
                                cd-gpios = <&gpio2 6 0>;
                                wp-gpios = <&gpio2 7 0>;
+                               vmmc-supply = <&reg_3p3v>;
                                status = "okay";
                        };
 
                        uart2: uart@021e8000 {
                                status = "okay";
                        };
+
+                       i2c@021a0000 { /* I2C1 */
+                               status = "okay";
+                               clock-frequency = <100000>;
+
+                               codec: sgtl5000@0a {
+                                       compatible = "fsl,sgtl5000";
+                                       reg = <0x0a>;
+                                       VDDA-supply = <&reg_2p5v>;
+                                       VDDIO-supply = <&reg_3p3v>;
+                               };
+                       };
+               };
+       };
+
+       regulators {
+               compatible = "simple-bus";
+
+               reg_2p5v: 2p5v {
+                       compatible = "regulator-fixed";
+                       regulator-name = "2P5V";
+                       regulator-min-microvolt = <2500000>;
+                       regulator-max-microvolt = <2500000>;
+                       regulator-always-on;
+               };
+
+               reg_3p3v: 3p3v {
+                       compatible = "regulator-fixed";
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
                };
        };
 };
index 263e8f3664b51fc83b479b0b6aee8b0ac530ce43..4905f51a106f7299465eaae802b7c98714a3e541 100644 (file)
@@ -88,9 +88,9 @@
                ranges;
 
                timer@00a00600 {
-                       compatible = "arm,smp-twd";
-                       reg = <0x00a00600 0x100>;
-                       interrupts = <1 13 0xf4>;
+                       compatible = "arm,cortex-a9-twd-timer";
+                       reg = <0x00a00600 0x20>;
+                       interrupts = <1 13 0xf01>;
                };
 
                L2: l2-cache@00a02000 {
diff --git a/arch/arm/boot/dts/kirkwood-dreamplug.dts b/arch/arm/boot/dts/kirkwood-dreamplug.dts
new file mode 100644 (file)
index 0000000..a5376b8
--- /dev/null
@@ -0,0 +1,24 @@
+/dts-v1/;
+
+/include/ "kirkwood.dtsi"
+
+/ {
+       model = "Globalscale Technologies Dreamplug";
+       compatible = "globalscale,dreamplug-003-ds2001", "globalscale,dreamplug", "mrvl,kirkwood-88f6281", "mrvl,kirkwood";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x20000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200n8 earlyprintk";
+       };
+
+       ocp@f1000000 {
+               serial@12000 {
+                       clock-frequency = <200000000>;
+                       status = "ok";
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
new file mode 100644 (file)
index 0000000..3474ef8
--- /dev/null
@@ -0,0 +1,36 @@
+/include/ "skeleton.dtsi"
+
+/ {
+       compatible = "mrvl,kirkwood";
+
+       ocp@f1000000 {
+               compatible = "simple-bus";
+               ranges = <0 0xf1000000 0x1000000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               serial@12000 {
+                       compatible = "ns16550a";
+                       reg = <0x12000 0x100>;
+                       reg-shift = <2>;
+                       interrupts = <33>;
+                       /* set clock-frequency in board dts */
+                       status = "disabled";
+               };
+
+               serial@12100 {
+                       compatible = "ns16550a";
+                       reg = <0x12100 0x100>;
+                       reg-shift = <2>;
+                       interrupts = <34>;
+                       /* set clock-frequency in board dts */
+                       status = "disabled";
+               };
+
+               rtc@10300 {
+                       compatible = "mrvl,kirkwood-rtc", "mrvl,orion-rtc";
+                       reg = <0x10300 0x20>;
+                       interrupts = <53>;
+               };
+       };
+};
index 9486be62bcddcd4674c9f0daa7e9f0f7b86f8147..9f72cd4cf3084d6aae6e4f3b4bd17a261d89e296 100644 (file)
        model = "TI OMAP3 BeagleBoard";
        compatible = "ti,omap3-beagle", "ti,omap3";
 
-       /*
-        * Since the initial device tree board file does not create any
-        * devices (MMC, network...), the only way to boot is to provide a
-        * ramdisk.
-        */
-       chosen {
-               bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug earlyprintk";
-       };
-
        memory {
                device_type = "memory";
                reg = <0x80000000 0x20000000>; /* 512 MB */
diff --git a/arch/arm/boot/dts/omap3-evm.dts b/arch/arm/boot/dts/omap3-evm.dts
new file mode 100644 (file)
index 0000000..2eee16e
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+/include/ "omap3.dtsi"
+
+/ {
+       model = "TI OMAP3 EVM (OMAP3530, AM/DM37x)";
+       compatible = "ti,omap3-evm", "ti,omap3";
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x10000000>; /* 256 MB */
+       };
+};
index 216c3317461d6dc6310571cd070ac7d952a38033..c6121357c1ebc95c29dd29e76f78d9972441e216 100644 (file)
                ranges;
                ti,hwmods = "l3_main";
 
-               intc: interrupt-controller@1 {
-                       compatible = "ti,omap3-intc";
+               intc: interrupt-controller@48200000 {
+                       compatible = "ti,omap2-intc";
                        interrupt-controller;
                        #interrupt-cells = <1>;
+                       ti,intc-size = <96>;
+                       reg = <0x48200000 0x1000>;
                };
 
-               uart1: serial@0x4806a000 {
+               uart1: serial@4806a000 {
                        compatible = "ti,omap3-uart";
                        ti,hwmods = "uart1";
                        clock-frequency = <48000000>;
                };
 
-               uart2: serial@0x4806c000 {
+               uart2: serial@4806c000 {
                        compatible = "ti,omap3-uart";
                        ti,hwmods = "uart2";
                        clock-frequency = <48000000>;
                };
 
-               uart3: serial@0x49020000 {
+               uart3: serial@49020000 {
                        compatible = "ti,omap3-uart";
                        ti,hwmods = "uart3";
                        clock-frequency = <48000000>;
                };
 
-               uart4: serial@0x49042000 {
+               uart4: serial@49042000 {
                        compatible = "ti,omap3-uart";
                        ti,hwmods = "uart4";
                        clock-frequency = <48000000>;
                };
+
+               i2c1: i2c@48070000 {
+                       compatible = "ti,omap3-i2c";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "i2c1";
+               };
+
+               i2c2: i2c@48072000 {
+                       compatible = "ti,omap3-i2c";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "i2c2";
+               };
+
+               i2c3: i2c@48060000 {
+                       compatible = "ti,omap3-i2c";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "i2c3";
+               };
        };
 };
index c7026578ce7d6ef25b22f167ec5265918a5d6c8b..9755ad5917f8b75da64d2aebcd5f79637ad0054d 100644 (file)
        model = "TI OMAP4 PandaBoard";
        compatible = "ti,omap4-panda", "ti,omap4430", "ti,omap4";
 
-       /*
-        * Since the initial device tree board file does not create any
-        * devices (MMC, network...), the only way to boot is to provide a
-        * ramdisk.
-        */
-       chosen {
-               bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug";
-       };
-
        memory {
                device_type = "memory";
                reg = <0x80000000 0x40000000>; /* 1 GB */
index 066e28c90328f252639d4d2c1de6b76e2a497a18..63c6b2b2bf42cdf5ac4d595069d3fbb903322b55 100644 (file)
        model = "TI OMAP4 SDP board";
        compatible = "ti,omap4-sdp", "ti,omap4430", "ti,omap4";
 
-       /*
-        * Since the initial device tree board file does not create any
-        * devices (MMC, network...), the only way to boot is to provide a
-        * ramdisk.
-        */
-       chosen {
-               bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug";
-       };
-
        memory {
                device_type = "memory";
                reg = <0x80000000 0x40000000>; /* 1 GB */
index e8fe75fac7c5e727f135721c1183feef0c89d2b1..3d35559e77bc098b220e2dab2360c86a5f156be1 100644 (file)
                gic: interrupt-controller@48241000 {
                        compatible = "arm,cortex-a9-gic";
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <3>;
                        reg = <0x48241000 0x1000>,
                              <0x48240100 0x0100>;
                };
 
-               uart1: serial@0x4806a000 {
+               uart1: serial@4806a000 {
                        compatible = "ti,omap4-uart";
                        ti,hwmods = "uart1";
                        clock-frequency = <48000000>;
                };
 
-               uart2: serial@0x4806c000 {
+               uart2: serial@4806c000 {
                        compatible = "ti,omap4-uart";
                        ti,hwmods = "uart2";
                        clock-frequency = <48000000>;
                };
 
-               uart3: serial@0x48020000 {
+               uart3: serial@48020000 {
                        compatible = "ti,omap4-uart";
                        ti,hwmods = "uart3";
                        clock-frequency = <48000000>;
                };
 
-               uart4: serial@0x4806e000 {
+               uart4: serial@4806e000 {
                        compatible = "ti,omap4-uart";
                        ti,hwmods = "uart4";
                        clock-frequency = <48000000>;
                };
+
+               i2c1: i2c@48070000 {
+                       compatible = "ti,omap4-i2c";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "i2c1";
+               };
+
+               i2c2: i2c@48072000 {
+                       compatible = "ti,omap4-i2c";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "i2c2";
+               };
+
+               i2c3: i2c@48060000 {
+                       compatible = "ti,omap4-i2c";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "i2c3";
+               };
+
+               i2c4: i2c@48350000 {
+                       compatible = "ti,omap4-i2c";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "i2c4";
+               };
        };
 };
diff --git a/arch/arm/boot/dts/pxa168-aspenite.dts b/arch/arm/boot/dts/pxa168-aspenite.dts
new file mode 100644 (file)
index 0000000..e762fac
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  Copyright (C) 2012 Marvell Technology Group Ltd.
+ *  Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ */
+
+/dts-v1/;
+/include/ "pxa168.dtsi"
+
+/ {
+       model = "Marvell PXA168 Aspenite Development Board";
+       compatible = "mrvl,pxa168-aspenite", "mrvl,pxa168";
+
+       chosen {
+               bootargs = "console=ttyS0,115200 root=/dev/nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on";
+       };
+
+       memory {
+               reg = <0x00000000 0x04000000>;
+       };
+
+       soc {
+               apb@d4000000 {
+                       uart1: uart@d4017000 {
+                               status = "okay";
+                       };
+                       twsi1: i2c@d4011000 {
+                               status = "okay";
+                       };
+                       rtc: rtc@d4010000 {
+                               status = "okay";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/pxa168.dtsi b/arch/arm/boot/dts/pxa168.dtsi
new file mode 100644 (file)
index 0000000..d32d512
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ *  Copyright (C) 2012 Marvell Technology Group Ltd.
+ *  Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+       aliases {
+               serial0 = &uart1;
+               serial1 = &uart2;
+               serial2 = &uart3;
+               i2c0 = &twsi1;
+               i2c1 = &twsi2;
+       };
+
+       intc: intc-interrupt-controller@d4282000 {
+               compatible = "mrvl,mmp-intc", "mrvl,intc";
+               interrupt-controller;
+               #interrupt-cells = <1>;
+               reg = <0xd4282000 0x1000>;
+       };
+
+       soc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               interrupt-parent = <&intc>;
+               ranges;
+
+               apb@d4000000 {  /* APB */
+                       compatible = "mrvl,apb-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0xd4000000 0x00200000>;
+                       ranges;
+
+                       uart1: uart@d4017000 {
+                               compatible = "mrvl,mmp-uart", "mrvl,pxa-uart";
+                               reg = <0xd4017000 0x1000>;
+                               interrupts = <27>;
+                               status = "disabled";
+                       };
+
+                       uart2: uart@d4018000 {
+                               compatible = "mrvl,mmp-uart", "mrvl,pxa-uart";
+                               reg = <0xd4018000 0x1000>;
+                               interrupts = <28>;
+                               status = "disabled";
+                       };
+
+                       uart3: uart@d4026000 {
+                               compatible = "mrvl,mmp-uart", "mrvl,pxa-uart";
+                               reg = <0xd4026000 0x1000>;
+                               interrupts = <29>;
+                               status = "disabled";
+                       };
+
+                       gpio: gpio@d4019000 {
+                               compatible = "mrvl,mmp-gpio", "mrvl,pxa-gpio";
+                               reg = <0xd4019000 0x1000>;
+                               interrupts = <49>;
+                               interrupt-names = "gpio_mux";
+                               gpio-controller;
+                               #gpio-cells = <1>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                       };
+
+                       twsi1: i2c@d4011000 {
+                               compatible = "mrvl,mmp-twsi", "mrvl,pxa-i2c";
+                               reg = <0xd4011000 0x1000>;
+                               interrupts = <7>;
+                               mrvl,i2c-fast-mode;
+                               status = "disabled";
+                       };
+
+                       twsi2: i2c@d4025000 {
+                               compatible = "mrvl,mmp-twsi", "mrvl,pxa-i2c";
+                               reg = <0xd4025000 0x1000>;
+                               interrupts = <58>;
+                               status = "disabled";
+                       };
+
+                       rtc: rtc@d4010000 {
+                               compatible = "mrvl,mmp-rtc";
+                               reg = <0xd4010000 0x1000>;
+                               interrupts = <5 6>;
+                               interrupt-names = "rtc 1Hz", "rtc alarm";
+                               status = "disabled";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/snowball.dts b/arch/arm/boot/dts/snowball.dts
new file mode 100644 (file)
index 0000000..359c6d6
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2011 ST-Ericsson AB
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "db8500.dtsi"
+
+/ {
+       model = "Calao Systems Snowball platform with device tree";
+       compatible = "calaosystems,snowball-a9500";
+
+       memory {
+               reg = <0x00000000 0x20000000>;
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               button@1 {
+                       debounce_interval = <50>;
+                       wakeup = <1>;
+                       linux,code = <2>;
+                       label = "userpb";
+                       gpios = <&gpio1 0>;
+               };
+               button@2 {
+                       debounce_interval = <50>;
+                       wakeup = <1>;
+                       linux,code = <3>;
+                       label = "userpb";
+                       gpios = <&gpio4 23>;
+               };
+               button@3 {
+                       debounce_interval = <50>;
+                       wakeup = <1>;
+                       linux,code = <4>;
+                       label = "userpb";
+                       gpios = <&gpio4 23>;
+               };
+               button@4 {
+                       debounce_interval = <50>;
+                       wakeup = <1>;
+                       linux,code = <5>;
+                       label = "userpb";
+                       gpios = <&gpio5 1>;
+               };
+               button@5 {
+                       debounce_interval = <50>;
+                       wakeup = <1>;
+                       linux,code = <6>;
+                       label = "userpb";
+                       gpios = <&gpio5 2>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               used-led {
+                       label = "user_led";
+                       gpios = <&gpio4 14>;
+               };
+       };
+
+       soc-u9500 {
+
+               external-bus@50000000 {
+                       compatible = "simple-bus";
+                       reg = <0x50000000 0x10000000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       ethernet@50000000 {
+                               compatible = "smsc,9111";
+                               reg = <0x50000000 0x10000>;
+                               interrupts = <12>;
+                               interrupt-parent = <&gpio4>;
+                       };
+               };
+
+               sdi@80126000 {
+                       status = "enabled";
+                       cd-gpios = <&gpio6 26>;
+               };
+
+               sdi@80114000 {
+                       status = "enabled";
+               };
+
+               uart@80120000 {
+                       status = "okay";
+               };
+
+               uart@80121000 {
+                       status = "okay";
+               };
+
+               uart@80007000 {
+                       status = "okay";
+               };
+
+               i2c@80004000 {
+                       tc3589x@42 {
+                               //compatible = "tc3589x";
+                               reg = <0x42>;
+                               interrupts = <25>;
+                               interrupt-parent = <&gpio6>;
+                       };
+                       tps61052@33 {
+                               //compatible = "tps61052";
+                               reg = <0x33>;
+                       };
+               };
+
+               i2c@80128000 {
+                       lp5521@0x33 {
+                               // compatible = "lp5521";
+                               reg = <0x33>;
+                       };
+                       lp5521@0x34 {
+                               // compatible = "lp5521";
+                               reg = <0x34>;
+                       };
+                       bh1780@0x29 {
+                               // compatible = "rohm,bh1780gli";
+                               reg = <0x33>;
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/spear600-evb.dts b/arch/arm/boot/dts/spear600-evb.dts
new file mode 100644 (file)
index 0000000..636292e
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2012 Stefan Roese <sr@denx.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "spear600.dtsi"
+
+/ {
+       model = "ST SPEAr600 Evaluation Board";
+       compatible = "st,spear600-evb", "st,spear600";
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       memory {
+               device_type = "memory";
+               reg = <0 0x10000000>;
+       };
+
+       ahb {
+               gmac: ethernet@e0800000 {
+                       phy-mode = "gmii";
+                       status = "okay";
+               };
+
+               apb {
+                       serial@d0000000 {
+                               status = "okay";
+                       };
+
+                       serial@d0080000 {
+                               status = "okay";
+                       };
+
+                       i2c@d0200000 {
+                               clock-frequency = <400000>;
+                               status = "okay";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi
new file mode 100644 (file)
index 0000000..ebe0885
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2012 Stefan Roese <sr@denx.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+       compatible = "st,spear600";
+
+       cpus {
+               cpu@0 {
+                       compatible = "arm,arm926ejs";
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0 0x40000000>;
+       };
+
+       ahb {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               ranges = <0xd0000000 0xd0000000 0x30000000>;
+
+               vic0: interrupt-controller@f1100000 {
+                       compatible = "arm,pl190-vic";
+                       interrupt-controller;
+                       reg = <0xf1100000 0x1000>;
+                       #interrupt-cells = <1>;
+               };
+
+               vic1: interrupt-controller@f1000000 {
+                       compatible = "arm,pl190-vic";
+                       interrupt-controller;
+                       reg = <0xf1000000 0x1000>;
+                       #interrupt-cells = <1>;
+               };
+
+               gmac: ethernet@e0800000 {
+                       compatible = "st,spear600-gmac";
+                       reg = <0xe0800000 0x8000>;
+                       interrupt-parent = <&vic1>;
+                       interrupts = <24 23>;
+                       interrupt-names = "macirq", "eth_wake_irq";
+                       status = "disabled";
+               };
+
+               fsmc: flash@d1800000 {
+                       compatible = "st,spear600-fsmc-nand";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0xd1800000 0x1000        /* FSMC Register */
+                              0xd2000000 0x4000>;      /* NAND Base */
+                       reg-names = "fsmc_regs", "nand_data";
+                       st,ale-off = <0x20000>;
+                       st,cle-off = <0x10000>;
+                       status = "disabled";
+               };
+
+               smi: flash@fc000000 {
+                       compatible = "st,spear600-smi";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0xfc000000 0x1000>;
+                       interrupt-parent = <&vic1>;
+                       interrupts = <12>;
+                       status = "disabled";
+               };
+
+               ehci@e1800000 {
+                       compatible = "st,spear600-ehci", "usb-ehci";
+                       reg = <0xe1800000 0x1000>;
+                       interrupt-parent = <&vic1>;
+                       interrupts = <27>;
+                       status = "disabled";
+               };
+
+               ehci@e2000000 {
+                       compatible = "st,spear600-ehci", "usb-ehci";
+                       reg = <0xe2000000 0x1000>;
+                       interrupt-parent = <&vic1>;
+                       interrupts = <29>;
+                       status = "disabled";
+               };
+
+               ohci@e1900000 {
+                       compatible = "st,spear600-ohci", "usb-ohci";
+                       reg = <0xe1900000 0x1000>;
+                       interrupt-parent = <&vic1>;
+                       interrupts = <26>;
+                       status = "disabled";
+               };
+
+               ohci@e2100000 {
+                       compatible = "st,spear600-ohci", "usb-ohci";
+                       reg = <0xe2100000 0x1000>;
+                       interrupt-parent = <&vic1>;
+                       interrupts = <28>;
+                       status = "disabled";
+               };
+
+               apb {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "simple-bus";
+                       ranges = <0xd0000000 0xd0000000 0x30000000>;
+
+                       serial@d0000000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0xd0000000 0x1000>;
+                               interrupt-parent = <&vic0>;
+                               interrupts = <24>;
+                               status = "disabled";
+                       };
+
+                       serial@d0080000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0xd0080000 0x1000>;
+                               interrupt-parent = <&vic0>;
+                               interrupts = <25>;
+                               status = "disabled";
+                       };
+
+                       /* local/cpu GPIO */
+                       gpio0: gpio@f0100000 {
+                               #gpio-cells = <2>;
+                               compatible = "arm,pl061", "arm,primecell";
+                               gpio-controller;
+                               reg = <0xf0100000 0x1000>;
+                               interrupt-parent = <&vic0>;
+                               interrupts = <18>;
+                       };
+
+                       /* basic GPIO */
+                       gpio1: gpio@fc980000 {
+                               #gpio-cells = <2>;
+                               compatible = "arm,pl061", "arm,primecell";
+                               gpio-controller;
+                               reg = <0xfc980000 0x1000>;
+                               interrupt-parent = <&vic1>;
+                               interrupts = <19>;
+                       };
+
+                       /* appl GPIO */
+                       gpio2: gpio@d8100000 {
+                               #gpio-cells = <2>;
+                               compatible = "arm,pl061", "arm,primecell";
+                               gpio-controller;
+                               reg = <0xd8100000 0x1000>;
+                               interrupt-parent = <&vic1>;
+                               interrupts = <4>;
+                       };
+
+                       i2c@d0200000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "snps,designware-i2c";
+                               reg = <0xd0200000 0x1000>;
+                               interrupt-parent = <&vic0>;
+                               interrupts = <28>;
+                               status = "disabled";
+                       };
+               };
+       };
+};
index 70c41fc897d741b7b9dd84f366d948def83eef3f..ac3fb75584595803cc4e14ff77221f4d63df9456 100644 (file)
                clock-frequency = < 408000000 >;
        };
 
+       serial@70006040 {
+               status = "disable";
+       };
+
+       serial@70006200 {
+               status = "disable";
+       };
+
+       serial@70006300 {
+               status = "disable";
+       };
+
+       serial@70006400 {
+               status = "disable";
+       };
+
        i2c@7000c000 {
                clock-frequency = <100000>;
        };
        i2c@7000d000 {
                clock-frequency = <100000>;
        };
+
+       sdhci@78000000 {
+               cd-gpios = <&gpio 69 0>; /* gpio PI5 */
+               wp-gpios = <&gpio 155 0>; /* gpio PT3 */
+               power-gpios = <&gpio 31 0>; /* gpio PD7 */
+       };
+
+       sdhci@78000200 {
+               status = "disable";
+       };
+
+       sdhci@78000400 {
+               status = "disable";
+       };
+
+       sdhci@78000400 {
+               support-8bit;
+       };
 };
index 80afa1b70b80d6ed448692a5434014fa36e910f8..6e8447dc020203c537383caa219d6c23bf2e775c 100644 (file)
                reg = < 0x00000000 0x40000000 >;
        };
 
+       pmc@7000f400 {
+               nvidia,invert-interrupt;
+       };
+
        i2c@7000c000 {
                clock-frequency = <400000>;
 
-               codec: wm8903@1a {
+               wm8903: wm8903@1a {
                        compatible = "wlf,wm8903";
                        reg = <0x1a>;
-                       interrupts = < 347 >;
+                       interrupt-parent = <&gpio>;
+                       interrupts = < 187 0x04 >;
 
                        gpio-controller;
                        #gpio-cells = <2>;
 
-                       /* 0x8000 = Not configured */
-                       gpio-cfg = < 0x8000 0x8000 0 0x8000 0x8000 >;
+                       micdet-cfg = <0>;
+                       micdet-delay = <100>;
+                       gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >;
                };
        };
 
                clock-frequency = <400000>;
        };
 
-       sound {
-               compatible = "nvidia,harmony-sound", "nvidia,tegra-wm8903";
+       i2s@70002a00 {
+               status = "disable";
+       };
 
-               spkr-en-gpios = <&codec 2 0>;
-               hp-det-gpios = <&gpio 178 0>;
-               int-mic-en-gpios = <&gpio 184 0>;
-               ext-mic-en-gpios = <&gpio 185 0>;
+       sound {
+               compatible = "nvidia,tegra-audio-wm8903-harmony",
+                            "nvidia,tegra-audio-wm8903";
+               nvidia,model = "NVIDIA Tegra Harmony";
+
+               nvidia,audio-routing =
+                       "Headphone Jack", "HPOUTR",
+                       "Headphone Jack", "HPOUTL",
+                       "Int Spk", "ROP",
+                       "Int Spk", "RON",
+                       "Int Spk", "LOP",
+                       "Int Spk", "LON",
+                       "Mic Jack", "MICBIAS",
+                       "IN1L", "Mic Jack";
+
+               nvidia,i2s-controller = <&tegra_i2s1>;
+               nvidia,audio-codec = <&wm8903>;
+
+               nvidia,spkr-en-gpios = <&wm8903 2 0>;
+               nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+               nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */
+               nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
        };
 
        serial@70006000 {
index 825d2957da0b819a8ac9204df02dff60fee9dbbc..6c02abb469d4ba971bde9c4fb5aede05a99d4783 100644 (file)
 
        i2c@7000c000 {
                clock-frequency = <400000>;
+
+               alc5632: alc5632@1e {
+                       compatible = "realtek,alc5632";
+                       reg = <0x1e>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
        };
 
        i2c@7000c400 {
 
        i2c@7000d000 {
                clock-frequency = <400000>;
+
+               adt7461@4c {
+                       compatible = "adi,adt7461";
+                       reg = <0x4c>;
+               };
+       };
+
+       i2s@70002a00 {
+               status = "disable";
+       };
+
+       sound {
+               compatible = "nvidia,tegra-audio-alc5632-paz00",
+                       "nvidia,tegra-audio-alc5632";
+
+               nvidia,model = "Compal PAZ00";
+
+               nvidia,audio-routing =
+                       "Int Spk", "SPKOUT",
+                       "Int Spk", "SPKOUTN",
+                       "Headset Mic", "MICBIAS1",
+                       "MIC1", "Headset Mic",
+                       "Headset Stereophone", "HPR",
+                       "Headset Stereophone", "HPL",
+                       "DMICDAT", "Digital Mic";
+
+               nvidia,audio-codec = <&alc5632>;
+               nvidia,i2s-controller = <&tegra_i2s1>;
+               nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
        };
 
        serial@70006000 {
        sdhci@c8000600 {
                support-8bit;
        };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               power {
+                       label = "Power";
+                       gpios = <&gpio 79 1>; /* gpio PJ7, active low */
+                       linux,code = <116>; /* KEY_POWER */
+                       gpio-key,wakeup;
+               };
+       };
+
+       gpio-leds {
+               compatible = "gpio-leds";
+
+               wifi {
+                       label = "wifi-led";
+                       gpios = <&gpio 24 0>;
+                       linux,default-trigger = "rfkill0";
+               };
+       };
 };
index b55a02e34ba7fe13bacfbaf1e25f5aa515b984ac..dbf1c5a171c251625e9fc39f5cec8efd35668ee1 100644 (file)
 
        i2c@7000c000 {
                clock-frequency = <400000>;
+
+               wm8903: wm8903@1a {
+                       compatible = "wlf,wm8903";
+                       reg = <0x1a>;
+                       interrupt-parent = <&gpio>;
+                       interrupts = < 187 0x04 >;
+
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       micdet-cfg = <0>;
+                       micdet-delay = <100>;
+                       gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >;
+               };
        };
 
        i2c@7000c400 {
                };
        };
 
+       i2s@70002a00 {
+               status = "disable";
+       };
+
+       sound {
+               compatible = "nvidia,tegra-audio-wm8903-seaboard",
+                            "nvidia,tegra-audio-wm8903";
+               nvidia,model = "NVIDIA Tegra Seaboard";
+
+               nvidia,audio-routing =
+                       "Headphone Jack", "HPOUTR",
+                       "Headphone Jack", "HPOUTL",
+                       "Int Spk", "ROP",
+                       "Int Spk", "RON",
+                       "Int Spk", "LOP",
+                       "Int Spk", "LON",
+                       "Mic Jack", "MICBIAS",
+                       "IN1R", "Mic Jack";
+
+               nvidia,i2s-controller = <&tegra_i2s1>;
+               nvidia,audio-codec = <&wm8903>;
+
+               nvidia,spkr-en-gpios = <&wm8903 2 0>;
+               nvidia,hp-det-gpios = <&gpio 185 0>; /* gpio PX1 */
+       };
+
        serial@70006000 {
                status = "disable";
        };
 
        usb@c5000000 {
                nvidia,vbus-gpio = <&gpio 24 0>; /* PD0 */
+               dr_mode = "otg";
        };
 
        gpio-keys {
                        gpio-key,wakeup;
                };
        };
+
+       emc@7000f400 {
+               emc-table@190000 {
+                       reg = < 190000 >;
+                       compatible = "nvidia,tegra20-emc-table";
+                       clock-frequency = < 190000 >;
+                       nvidia,emc-registers = < 0x0000000c 0x00000026
+                               0x00000009 0x00000003 0x00000004 0x00000004
+                               0x00000002 0x0000000c 0x00000003 0x00000003
+                               0x00000002 0x00000001 0x00000004 0x00000005
+                               0x00000004 0x00000009 0x0000000d 0x0000059f
+                               0x00000000 0x00000003 0x00000003 0x00000003
+                               0x00000003 0x00000001 0x0000000b 0x000000c8
+                               0x00000003 0x00000007 0x00000004 0x0000000f
+                               0x00000002 0x00000000 0x00000000 0x00000002
+                               0x00000000 0x00000000 0x00000083 0xa06204ae
+                               0x007dc010 0x00000000 0x00000000 0x00000000
+                               0x00000000 0x00000000 0x00000000 0x00000000 >;
+               };
+
+               emc-table@380000 {
+                       reg = < 380000 >;
+                       compatible = "nvidia,tegra20-emc-table";
+                       clock-frequency = < 380000 >;
+                       nvidia,emc-registers = < 0x00000017 0x0000004b
+                               0x00000012 0x00000006 0x00000004 0x00000005
+                               0x00000003 0x0000000c 0x00000006 0x00000006
+                               0x00000003 0x00000001 0x00000004 0x00000005
+                               0x00000004 0x00000009 0x0000000d 0x00000b5f
+                               0x00000000 0x00000003 0x00000003 0x00000006
+                               0x00000006 0x00000001 0x00000011 0x000000c8
+                               0x00000003 0x0000000e 0x00000007 0x0000000f
+                               0x00000002 0x00000000 0x00000000 0x00000002
+                               0x00000000 0x00000000 0x00000083 0xe044048b
+                               0x007d8010 0x00000000 0x00000000 0x00000000
+                               0x00000000 0x00000000 0x00000000 0x00000000 >;
+               };
+       };
 };
index 3b3ee7db99f3f6893b9113915b016954aa6a3cb9..252476867b54a6804a0c63f484ed4766698c3787 100644 (file)
                status = "disable";
        };
 
+       i2s@70002800 {
+               status = "disable";
+       };
+
+       i2s@70002a00 {
+               status = "disable";
+       };
+
+       das@70000c00 {
+               status = "disable";
+       };
+
        serial@70006000 {
                clock-frequency = < 216000000 >;
        };
index c7d3b87f29dfe0458f047cf64e1dc4f23d5758f9..2dcff8728e904a03dc5ba1200b633617e2c9b048 100644 (file)
 
        i2c@7000c000 {
                clock-frequency = <400000>;
+
+               wm8903: wm8903@1a {
+                       compatible = "wlf,wm8903";
+                       reg = <0x1a>;
+                       interrupt-parent = <&gpio>;
+                       interrupts = < 187 0x04 >;
+
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       micdet-cfg = <0>;
+                       micdet-delay = <100>;
+                       gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >;
+               };
        };
 
        i2c@7000c400 {
                clock-frequency = <400000>;
        };
 
+       i2s@70002a00 {
+               status = "disable";
+       };
+
+       sound {
+               compatible = "nvidia,tegra-audio-wm8903-ventana",
+                            "nvidia,tegra-audio-wm8903";
+               nvidia,model = "NVIDIA Tegra Ventana";
+
+               nvidia,audio-routing =
+                       "Headphone Jack", "HPOUTR",
+                       "Headphone Jack", "HPOUTL",
+                       "Int Spk", "ROP",
+                       "Int Spk", "RON",
+                       "Int Spk", "LOP",
+                       "Int Spk", "LON",
+                       "Mic Jack", "MICBIAS",
+                       "IN1L", "Mic Jack";
+
+               nvidia,i2s-controller = <&tegra_i2s1>;
+               nvidia,audio-codec = <&wm8903>;
+
+               nvidia,spkr-en-gpios = <&wm8903 2 0>;
+               nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+               nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */
+               nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
+       };
+
        serial@70006000 {
                status = "disable";
        };
index 3da7afd45322ba288de7c36ac85923c53aed05a9..108e894a8926d790151b298fcec1b75075dbfa9d 100644 (file)
@@ -4,6 +4,11 @@
        compatible = "nvidia,tegra20";
        interrupt-parent = <&intc>;
 
+       pmc@7000f400 {
+               compatible = "nvidia,tegra20-pmc";
+               reg = <0x7000e400 0x400>;
+       };
+
        intc: interrupt-controller@50041000 {
                compatible = "arm,cortex-a9-gic";
                interrupt-controller;
                      < 0x50040100 0x0100 >;
        };
 
+       pmu {
+               compatible = "arm,cortex-a9-pmu";
+               interrupts = <0 56 0x04
+                             0 57 0x04>;
+       };
+
+       apbdma: dma@6000a000 {
+               compatible = "nvidia,tegra20-apbdma";
+               reg = <0x6000a000 0x1200>;
+               interrupts = < 0 104 0x04
+                              0 105 0x04
+                              0 106 0x04
+                              0 107 0x04
+                              0 108 0x04
+                              0 109 0x04
+                              0 110 0x04
+                              0 111 0x04
+                              0 112 0x04
+                              0 113 0x04
+                              0 114 0x04
+                              0 115 0x04
+                              0 116 0x04
+                              0 117 0x04
+                              0 118 0x04
+                              0 119 0x04 >;
+       };
+
        i2c@7000c000 {
                #address-cells = <1>;
                #size-cells = <0>;
                interrupts = < 0 53 0x04 >;
        };
 
-       i2s@70002800 {
+       tegra_i2s1: i2s@70002800 {
                compatible = "nvidia,tegra20-i2s";
                reg = <0x70002800 0x200>;
                interrupts = < 0 13 0x04 >;
-               dma-channel = < 2 >;
+               nvidia,dma-request-selector = < &apbdma 2 >;
        };
 
-       i2s@70002a00 {
+       tegra_i2s2: i2s@70002a00 {
                compatible = "nvidia,tegra20-i2s";
                reg = <0x70002a00 0x200>;
                interrupts = < 0 3 0x04 >;
-               dma-channel = < 1 >;
+               nvidia,dma-request-selector = < &apbdma 1 >;
        };
 
        das@70000c00 {
                               0 89 0x04 >;
                #gpio-cells = <2>;
                gpio-controller;
+               #interrupt-cells = <2>;
+               interrupt-controller;
        };
 
        pinmux: pinmux@70000000 {
                interrupts = < 0 91 0x04 >;
        };
 
+       emc@7000f400 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "nvidia,tegra20-emc";
+               reg = <0x7000f400 0x200>;
+       };
+
        sdhci@c8000000 {
                compatible = "nvidia,tegra20-sdhci";
                reg = <0xc8000000 0x200>;
                reg = <0xc5000000 0x4000>;
                interrupts = < 0 20 0x04 >;
                phy_type = "utmi";
+               nvidia,has-legacy-mode;
        };
 
        usb@c5004000 {
index ee7db9892e02aba2786613b3e7c52541659adcae..62a7b39f1c9a9e8f55ca409e5c192e312fe93d3b 100644 (file)
@@ -4,6 +4,11 @@
        compatible = "nvidia,tegra30";
        interrupt-parent = <&intc>;
 
+       pmc@7000f400 {
+               compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc";
+               reg = <0x7000e400 0x400>;
+       };
+
        intc: interrupt-controller@50041000 {
                compatible = "arm,cortex-a9-gic";
                interrupt-controller;
                      < 0x50040100 0x0100 >;
        };
 
+       pmu {
+               compatible = "arm,cortex-a9-pmu";
+               interrupts = <0 144 0x04
+                             0 145 0x04
+                             0 146 0x04
+                             0 147 0x04>;
+       };
+
+       apbdma: dma@6000a000 {
+               compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma";
+               reg = <0x6000a000 0x1400>;
+               interrupts = < 0 104 0x04
+                              0 105 0x04
+                              0 106 0x04
+                              0 107 0x04
+                              0 108 0x04
+                              0 109 0x04
+                              0 110 0x04
+                              0 111 0x04
+                              0 112 0x04
+                              0 113 0x04
+                              0 114 0x04
+                              0 115 0x04
+                              0 116 0x04
+                              0 117 0x04
+                              0 118 0x04
+                              0 119 0x04
+                              0 128 0x04
+                              0 129 0x04
+                              0 130 0x04
+                              0 131 0x04
+                              0 132 0x04
+                              0 133 0x04
+                              0 134 0x04
+                              0 135 0x04
+                              0 136 0x04
+                              0 137 0x04
+                              0 138 0x04
+                              0 139 0x04
+                              0 140 0x04
+                              0 141 0x04
+                              0 142 0x04
+                              0 143 0x04 >;
+       };
+
        i2c@7000c000 {
                #address-cells = <1>;
                #size-cells = <0>;
        gpio: gpio@6000d000 {
                compatible = "nvidia,tegra30-gpio", "nvidia,tegra20-gpio";
                reg = < 0x6000d000 0x1000 >;
-               interrupts = < 0 32 0x04 0 33 0x04 0 34 0x04 0 35 0x04 0 55 0x04 0 87 0x04 0 89 0x04 >;
+               interrupts = < 0 32 0x04
+                              0 33 0x04
+                              0 34 0x04
+                              0 35 0x04
+                              0 55 0x04
+                              0 87 0x04
+                              0 89 0x04
+                              0 125 0x04 >;
                #gpio-cells = <2>;
                gpio-controller;
+               #interrupt-cells = <2>;
+               interrupt-controller;
        };
 
        serial@70006000 {
diff --git a/arch/arm/boot/dts/usb_a9g20-dab-mmx.dtsi b/arch/arm/boot/dts/usb_a9g20-dab-mmx.dtsi
new file mode 100644 (file)
index 0000000..ad3eca1
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * calao-dab-mmx.dtsi - Device Tree Include file for Calao DAB-MMX Daughter Board
+ *
+ * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+/ {
+       ahb {
+               apb {
+                       usart1: serial@fffb4000 {
+                               status = "okay";
+                       };
+
+                       usart3: serial@fffd0000 {
+                               status = "okay";
+                       };
+               };
+       };
+
+       i2c-gpio@0 {
+               status = "okay";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               user_led1 {
+                       label = "user_led1";
+                       gpios = <&pioB 20 1>;
+               };
+
+/*
+* led already used by mother board but active as high
+*              user_led2 {
+*                      label = "user_led2";
+*                      gpios = <&pioB 21 1>;
+*              };
+*/
+               user_led3 {
+                       label = "user_led3";
+                       gpios = <&pioB 22 1>;
+               };
+
+               user_led4 {
+                       label = "user_led4";
+                       gpios = <&pioB 23 1>;
+               };
+
+               red {
+                       label = "red";
+                       gpios = <&pioB 24 1>;
+               };
+
+               orange {
+                       label = "orange";
+                       gpios = <&pioB 30 1>;
+               };
+
+               green {
+                       label = "green";
+                       gpios = <&pioB 31 1>;
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               user_pb1 {
+                       label = "user_pb1";
+                       gpios = <&pioB 25 1>;
+                       linux,code = <0x100>;
+               };
+
+               user_pb2 {
+                       label = "user_pb2";
+                       gpios = <&pioB 13 1>;
+                       linux,code = <0x101>;
+               };
+
+               user_pb3 {
+                       label = "user_pb3";
+                       gpios = <&pioA 26 1>;
+                       linux,code = <0x102>;
+               };
+
+               user_pb4 {
+                       label = "user_pb4";
+                       gpios = <&pioC 9 1>;
+                       linux,code = <0x103>;
+               };
+       };
+};
index f04b535477f54b5e63c688ab3294d9c826192eae..3b3c4e0fa79f8429df9efafc2a97942e997e3331 100644 (file)
        compatible = "calao,usb-a9g20", "atmel,at91sam9g20", "atmel,at91sam9";
 
        chosen {
-               bootargs = "mem=64M console=ttyS0,115200 mtdparts=atmel_nand:128k(at91bootstrap),256k(barebox)ro,128k(bareboxenv),128k(bareboxenv2),4M(kernel),120M(rootfs),-(data) root=/dev/mtdblock5 rw rootfstype=ubifs";
+               bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock5 rw rootfstype=ubifs";
        };
 
        memory@20000000 {
                reg = <0x20000000 0x4000000>;
        };
 
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               main_clock: clock@0 {
+                       compatible = "atmel,osc", "fixed-clock";
+                       clock-frequency = <12000000>;
+               };
+       };
+
        ahb {
                apb {
                        dbgu: serial@fffff200 {
                                phy-mode = "rmii";
                                status = "okay";
                        };
+
+                       usb1: gadget@fffa4000 {
+                               atmel,vbus-gpio = <&pioC 5 0>;
+                               status = "okay";
+                       };
+               };
+
+               nand0: nand@40000000 {
+                       nand-bus-width = <8>;
+                       nand-ecc-mode = "soft";
+                       nand-on-flash-bbt;
+                       status = "okay";
+
+                       at91bootstrap@0 {
+                               label = "at91bootstrap";
+                               reg = <0x0 0x20000>;
+                       };
+
+                       barebox@20000 {
+                               label = "barebox";
+                               reg = <0x20000 0x40000>;
+                       };
+
+                       bareboxenv@60000 {
+                               label = "bareboxenv";
+                               reg = <0x60000 0x20000>;
+                       };
+
+                       bareboxenv2@80000 {
+                               label = "bareboxenv2";
+                               reg = <0x80000 0x20000>;
+                       };
+
+                       kernel@a0000 {
+                               label = "kernel";
+                               reg = <0xa0000 0x400000>;
+                       };
+
+                       rootfs@4a0000 {
+                               label = "rootfs";
+                               reg = <0x4a0000 0x7800000>;
+                       };
+
+                       data@7ca0000 {
+                               label = "data";
+                               reg = <0x7ca0000 0x8360000>;
+                       };
+               };
+
+               usb0: ohci@00500000 {
+                       num-ports = <2>;
+                       status = "okay";
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               user_led {
+                       label = "user_led";
+                       gpios = <&pioB 21 1>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               user_pb {
+                       label = "user_pb";
+                       gpios = <&pioB 10 1>;
+                       linux,code = <28>;
+                       gpio-key,wakeup;
+               };
+       };
+
+       i2c@0 {
+               status = "okay";
+
+               rv3029c2@56 {
+                       compatible = "rv3029c2";
+                       reg = <0x56>;
                };
        };
 };
diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
new file mode 100644 (file)
index 0000000..16076e2
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * ARM Ltd. Versatile Express
+ *
+ * Motherboard Express uATX
+ * V2M-P1
+ *
+ * HBI-0190D
+ *
+ * RS1 memory map ("ARM Cortex-A Series memory map" in the board's
+ * Technical Reference Manual)
+ *
+ * WARNING! The hardware described in this file is independent from the
+ * original variant (vexpress-v2m.dtsi), but there is a strong
+ * correspondence between the two configurations.
+ *
+ * TAKE CARE WHEN MAINTAINING THIS FILE TO PROPAGATE ANY RELEVANT
+ * CHANGES TO vexpress-v2m.dtsi!
+ */
+
+/ {
+       aliases {
+               arm,v2m_timer = &v2m_timer01;
+       };
+
+       motherboard {
+               compatible = "simple-bus";
+               arm,v2m-memory-map = "rs1";
+               #address-cells = <2>; /* SMB chipselect number and offset */
+               #size-cells = <1>;
+               #interrupt-cells = <1>;
+
+               flash@0,00000000 {
+                       compatible = "arm,vexpress-flash", "cfi-flash";
+                       reg = <0 0x00000000 0x04000000>,
+                             <4 0x00000000 0x04000000>;
+                       bank-width = <4>;
+               };
+
+               psram@1,00000000 {
+                       compatible = "arm,vexpress-psram", "mtd-ram";
+                       reg = <1 0x00000000 0x02000000>;
+                       bank-width = <4>;
+               };
+
+               vram@2,00000000 {
+                       compatible = "arm,vexpress-vram";
+                       reg = <2 0x00000000 0x00800000>;
+               };
+
+               ethernet@2,02000000 {
+                       compatible = "smsc,lan9118", "smsc,lan9115";
+                       reg = <2 0x02000000 0x10000>;
+                       interrupts = <15>;
+                       phy-mode = "mii";
+                       reg-io-width = <4>;
+                       smsc,irq-active-high;
+                       smsc,irq-push-pull;
+               };
+
+               usb@2,03000000 {
+                       compatible = "nxp,usb-isp1761";
+                       reg = <2 0x03000000 0x20000>;
+                       interrupts = <16>;
+                       port1-otg;
+               };
+
+               iofpga@3,00000000 {
+                       compatible = "arm,amba-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 3 0 0x200000>;
+
+                       sysreg@010000 {
+                               compatible = "arm,vexpress-sysreg";
+                               reg = <0x010000 0x1000>;
+                       };
+
+                       sysctl@020000 {
+                               compatible = "arm,sp810", "arm,primecell";
+                               reg = <0x020000 0x1000>;
+                       };
+
+                       /* PCI-E I2C bus */
+                       v2m_i2c_pcie: i2c@030000 {
+                               compatible = "arm,versatile-i2c";
+                               reg = <0x030000 0x1000>;
+
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               pcie-switch@60 {
+                                       compatible = "idt,89hpes32h8";
+                                       reg = <0x60>;
+                               };
+                       };
+
+                       aaci@040000 {
+                               compatible = "arm,pl041", "arm,primecell";
+                               reg = <0x040000 0x1000>;
+                               interrupts = <11>;
+                       };
+
+                       mmci@050000 {
+                               compatible = "arm,pl180", "arm,primecell";
+                               reg = <0x050000 0x1000>;
+                               interrupts = <9 10>;
+                       };
+
+                       kmi@060000 {
+                               compatible = "arm,pl050", "arm,primecell";
+                               reg = <0x060000 0x1000>;
+                               interrupts = <12>;
+                       };
+
+                       kmi@070000 {
+                               compatible = "arm,pl050", "arm,primecell";
+                               reg = <0x070000 0x1000>;
+                               interrupts = <13>;
+                       };
+
+                       v2m_serial0: uart@090000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0x090000 0x1000>;
+                               interrupts = <5>;
+                       };
+
+                       v2m_serial1: uart@0a0000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0x0a0000 0x1000>;
+                               interrupts = <6>;
+                       };
+
+                       v2m_serial2: uart@0b0000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0x0b0000 0x1000>;
+                               interrupts = <7>;
+                       };
+
+                       v2m_serial3: uart@0c0000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0x0c0000 0x1000>;
+                               interrupts = <8>;
+                       };
+
+                       wdt@0f0000 {
+                               compatible = "arm,sp805", "arm,primecell";
+                               reg = <0x0f0000 0x1000>;
+                               interrupts = <0>;
+                       };
+
+                       v2m_timer01: timer@110000 {
+                               compatible = "arm,sp804", "arm,primecell";
+                               reg = <0x110000 0x1000>;
+                               interrupts = <2>;
+                       };
+
+                       v2m_timer23: timer@120000 {
+                               compatible = "arm,sp804", "arm,primecell";
+                               reg = <0x120000 0x1000>;
+                       };
+
+                       /* DVI I2C bus */
+                       v2m_i2c_dvi: i2c@160000 {
+                               compatible = "arm,versatile-i2c";
+                               reg = <0x160000 0x1000>;
+
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               dvi-transmitter@39 {
+                                       compatible = "sil,sii9022-tpi", "sil,sii9022";
+                                       reg = <0x39>;
+                               };
+
+                               dvi-transmitter@60 {
+                                       compatible = "sil,sii9022-cpi", "sil,sii9022";
+                                       reg = <0x60>;
+                               };
+                       };
+
+                       rtc@170000 {
+                               compatible = "arm,pl031", "arm,primecell";
+                               reg = <0x170000 0x1000>;
+                               interrupts = <4>;
+                       };
+
+                       compact-flash@1a0000 {
+                               compatible = "arm,vexpress-cf", "ata-generic";
+                               reg = <0x1a0000 0x100
+                                      0x1a0100 0xf00>;
+                               reg-shift = <2>;
+                       };
+
+                       clcd@1f0000 {
+                               compatible = "arm,pl111", "arm,primecell";
+                               reg = <0x1f0000 0x1000>;
+                               interrupts = <14>;
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/vexpress-v2m.dtsi b/arch/arm/boot/dts/vexpress-v2m.dtsi
new file mode 100644 (file)
index 0000000..a6c9c7c
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * ARM Ltd. Versatile Express
+ *
+ * Motherboard Express uATX
+ * V2M-P1
+ *
+ * HBI-0190D
+ *
+ * Original memory map ("Legacy memory map" in the board's
+ * Technical Reference Manual)
+ *
+ * WARNING! The hardware described in this file is independent from the
+ * RS1 variant (vexpress-v2m-rs1.dtsi), but there is a strong
+ * correspondence between the two configurations.
+ *
+ * TAKE CARE WHEN MAINTAINING THIS FILE TO PROPAGATE ANY RELEVANT
+ * CHANGES TO vexpress-v2m-rs1.dtsi!
+ */
+
+/ {
+       aliases {
+               arm,v2m_timer = &v2m_timer01;
+       };
+
+       motherboard {
+               compatible = "simple-bus";
+               #address-cells = <2>; /* SMB chipselect number and offset */
+               #size-cells = <1>;
+               #interrupt-cells = <1>;
+
+               flash@0,00000000 {
+                       compatible = "arm,vexpress-flash", "cfi-flash";
+                       reg = <0 0x00000000 0x04000000>,
+                             <1 0x00000000 0x04000000>;
+                       bank-width = <4>;
+               };
+
+               psram@2,00000000 {
+                       compatible = "arm,vexpress-psram", "mtd-ram";
+                       reg = <2 0x00000000 0x02000000>;
+                       bank-width = <4>;
+               };
+
+               vram@3,00000000 {
+                       compatible = "arm,vexpress-vram";
+                       reg = <3 0x00000000 0x00800000>;
+               };
+
+               ethernet@3,02000000 {
+                       compatible = "smsc,lan9118", "smsc,lan9115";
+                       reg = <3 0x02000000 0x10000>;
+                       interrupts = <15>;
+                       phy-mode = "mii";
+                       reg-io-width = <4>;
+                       smsc,irq-active-high;
+                       smsc,irq-push-pull;
+               };
+
+               usb@3,03000000 {
+                       compatible = "nxp,usb-isp1761";
+                       reg = <3 0x03000000 0x20000>;
+                       interrupts = <16>;
+                       port1-otg;
+               };
+
+               iofpga@7,00000000 {
+                       compatible = "arm,amba-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 7 0 0x20000>;
+
+                       sysreg@00000 {
+                               compatible = "arm,vexpress-sysreg";
+                               reg = <0x00000 0x1000>;
+                       };
+
+                       sysctl@01000 {
+                               compatible = "arm,sp810", "arm,primecell";
+                               reg = <0x01000 0x1000>;
+                       };
+
+                       /* PCI-E I2C bus */
+                       v2m_i2c_pcie: i2c@02000 {
+                               compatible = "arm,versatile-i2c";
+                               reg = <0x02000 0x1000>;
+
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               pcie-switch@60 {
+                                       compatible = "idt,89hpes32h8";
+                                       reg = <0x60>;
+                               };
+                       };
+
+                       aaci@04000 {
+                               compatible = "arm,pl041", "arm,primecell";
+                               reg = <0x04000 0x1000>;
+                               interrupts = <11>;
+                       };
+
+                       mmci@05000 {
+                               compatible = "arm,pl180", "arm,primecell";
+                               reg = <0x05000 0x1000>;
+                               interrupts = <9 10>;
+                       };
+
+                       kmi@06000 {
+                               compatible = "arm,pl050", "arm,primecell";
+                               reg = <0x06000 0x1000>;
+                               interrupts = <12>;
+                       };
+
+                       kmi@07000 {
+                               compatible = "arm,pl050", "arm,primecell";
+                               reg = <0x07000 0x1000>;
+                               interrupts = <13>;
+                       };
+
+                       v2m_serial0: uart@09000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0x09000 0x1000>;
+                               interrupts = <5>;
+                       };
+
+                       v2m_serial1: uart@0a000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0x0a000 0x1000>;
+                               interrupts = <6>;
+                       };
+
+                       v2m_serial2: uart@0b000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0x0b000 0x1000>;
+                               interrupts = <7>;
+                       };
+
+                       v2m_serial3: uart@0c000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0x0c000 0x1000>;
+                               interrupts = <8>;
+                       };
+
+                       wdt@0f000 {
+                               compatible = "arm,sp805", "arm,primecell";
+                               reg = <0x0f000 0x1000>;
+                               interrupts = <0>;
+                       };
+
+                       v2m_timer01: timer@11000 {
+                               compatible = "arm,sp804", "arm,primecell";
+                               reg = <0x11000 0x1000>;
+                               interrupts = <2>;
+                       };
+
+                       v2m_timer23: timer@12000 {
+                               compatible = "arm,sp804", "arm,primecell";
+                               reg = <0x12000 0x1000>;
+                       };
+
+                       /* DVI I2C bus */
+                       v2m_i2c_dvi: i2c@16000 {
+                               compatible = "arm,versatile-i2c";
+                               reg = <0x16000 0x1000>;
+
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               dvi-transmitter@39 {
+                                       compatible = "sil,sii9022-tpi", "sil,sii9022";
+                                       reg = <0x39>;
+                               };
+
+                               dvi-transmitter@60 {
+                                       compatible = "sil,sii9022-cpi", "sil,sii9022";
+                                       reg = <0x60>;
+                               };
+                       };
+
+                       rtc@17000 {
+                               compatible = "arm,pl031", "arm,primecell";
+                               reg = <0x17000 0x1000>;
+                               interrupts = <4>;
+                       };
+
+                       compact-flash@1a000 {
+                               compatible = "arm,vexpress-cf", "ata-generic";
+                               reg = <0x1a000 0x100
+                                      0x1a100 0xf00>;
+                               reg-shift = <2>;
+                       };
+
+                       clcd@1f000 {
+                               compatible = "arm,pl111", "arm,primecell";
+                               reg = <0x1f000 0x1000>;
+                               interrupts = <14>;
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
new file mode 100644 (file)
index 0000000..941b161
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * ARM Ltd. Versatile Express
+ *
+ * CoreTile Express A15x2 (version with Test Chip 1)
+ * Cortex-A15 MPCore (V2P-CA15)
+ *
+ * HBI-0237A
+ */
+
+/dts-v1/;
+
+/ {
+       model = "V2P-CA15";
+       arm,hbi = <0x237>;
+       compatible = "arm,vexpress,v2p-ca15,tc1", "arm,vexpress,v2p-ca15", "arm,vexpress";
+       interrupt-parent = <&gic>;
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       chosen { };
+
+       aliases {
+               serial0 = &v2m_serial0;
+               serial1 = &v2m_serial1;
+               serial2 = &v2m_serial2;
+               serial3 = &v2m_serial3;
+               i2c0 = &v2m_i2c_dvi;
+               i2c1 = &v2m_i2c_pcie;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a15";
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a15";
+                       reg = <1>;
+               };
+       };
+
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x80000000 0x40000000>;
+       };
+
+       hdlcd@2b000000 {
+               compatible = "arm,hdlcd";
+               reg = <0x2b000000 0x1000>;
+               interrupts = <0 85 4>;
+       };
+
+       memory-controller@2b0a0000 {
+               compatible = "arm,pl341", "arm,primecell";
+               reg = <0x2b0a0000 0x1000>;
+       };
+
+       wdt@2b060000 {
+               compatible = "arm,sp805", "arm,primecell";
+               reg = <0x2b060000 0x1000>;
+               interrupts = <98>;
+       };
+
+       gic: interrupt-controller@2c001000 {
+               compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+               #interrupt-cells = <3>;
+               #address-cells = <0>;
+               interrupt-controller;
+               reg = <0x2c001000 0x1000>,
+                     <0x2c002000 0x100>;
+       };
+
+       memory-controller@7ffd0000 {
+               compatible = "arm,pl354", "arm,primecell";
+               reg = <0x7ffd0000 0x1000>;
+               interrupts = <0 86 4>,
+                            <0 87 4>;
+       };
+
+       dma@7ffb0000 {
+               compatible = "arm,pl330", "arm,primecell";
+               reg = <0x7ffb0000 0x1000>;
+               interrupts = <0 92 4>,
+                            <0 88 4>,
+                            <0 89 4>,
+                            <0 90 4>,
+                            <0 91 4>;
+       };
+
+       pmu {
+               compatible = "arm,cortex-a15-pmu", "arm,cortex-a9-pmu";
+               interrupts = <0 68 4>,
+                            <0 69 4>;
+       };
+
+       motherboard {
+               ranges = <0 0 0x08000000 0x04000000>,
+                        <1 0 0x14000000 0x04000000>,
+                        <2 0 0x18000000 0x04000000>,
+                        <3 0 0x1c000000 0x04000000>,
+                        <4 0 0x0c000000 0x04000000>,
+                        <5 0 0x10000000 0x04000000>;
+
+               interrupt-map-mask = <0 0 63>;
+               interrupt-map = <0 0  0 &gic 0  0 4>,
+                               <0 0  1 &gic 0  1 4>,
+                               <0 0  2 &gic 0  2 4>,
+                               <0 0  3 &gic 0  3 4>,
+                               <0 0  4 &gic 0  4 4>,
+                               <0 0  5 &gic 0  5 4>,
+                               <0 0  6 &gic 0  6 4>,
+                               <0 0  7 &gic 0  7 4>,
+                               <0 0  8 &gic 0  8 4>,
+                               <0 0  9 &gic 0  9 4>,
+                               <0 0 10 &gic 0 10 4>,
+                               <0 0 11 &gic 0 11 4>,
+                               <0 0 12 &gic 0 12 4>,
+                               <0 0 13 &gic 0 13 4>,
+                               <0 0 14 &gic 0 14 4>,
+                               <0 0 15 &gic 0 15 4>,
+                               <0 0 16 &gic 0 16 4>,
+                               <0 0 17 &gic 0 17 4>,
+                               <0 0 18 &gic 0 18 4>,
+                               <0 0 19 &gic 0 19 4>,
+                               <0 0 20 &gic 0 20 4>,
+                               <0 0 21 &gic 0 21 4>,
+                               <0 0 22 &gic 0 22 4>,
+                               <0 0 23 &gic 0 23 4>,
+                               <0 0 24 &gic 0 24 4>,
+                               <0 0 25 &gic 0 25 4>,
+                               <0 0 26 &gic 0 26 4>,
+                               <0 0 27 &gic 0 27 4>,
+                               <0 0 28 &gic 0 28 4>,
+                               <0 0 29 &gic 0 29 4>,
+                               <0 0 30 &gic 0 30 4>,
+                               <0 0 31 &gic 0 31 4>,
+                               <0 0 32 &gic 0 32 4>,
+                               <0 0 33 &gic 0 33 4>,
+                               <0 0 34 &gic 0 34 4>,
+                               <0 0 35 &gic 0 35 4>,
+                               <0 0 36 &gic 0 36 4>,
+                               <0 0 37 &gic 0 37 4>,
+                               <0 0 38 &gic 0 38 4>,
+                               <0 0 39 &gic 0 39 4>,
+                               <0 0 40 &gic 0 40 4>,
+                               <0 0 41 &gic 0 41 4>,
+                               <0 0 42 &gic 0 42 4>;
+       };
+};
+
+/include/ "vexpress-v2m-rs1.dtsi"
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
new file mode 100644 (file)
index 0000000..6905e66
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * ARM Ltd. Versatile Express
+ *
+ * CoreTile Express A5x2
+ * Cortex-A5 MPCore (V2P-CA5s)
+ *
+ * HBI-0225B
+ */
+
+/dts-v1/;
+
+/ {
+       model = "V2P-CA5s";
+       arm,hbi = <0x225>;
+       compatible = "arm,vexpress,v2p-ca5s", "arm,vexpress";
+       interrupt-parent = <&gic>;
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       chosen { };
+
+       aliases {
+               serial0 = &v2m_serial0;
+               serial1 = &v2m_serial1;
+               serial2 = &v2m_serial2;
+               serial3 = &v2m_serial3;
+               i2c0 = &v2m_i2c_dvi;
+               i2c1 = &v2m_i2c_pcie;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a5";
+                       reg = <0>;
+                       next-level-cache = <&L2>;
+               };
+
+               cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a5";
+                       reg = <1>;
+                       next-level-cache = <&L2>;
+               };
+       };
+
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x80000000 0x40000000>;
+       };
+
+       hdlcd@2a110000 {
+               compatible = "arm,hdlcd";
+               reg = <0x2a110000 0x1000>;
+               interrupts = <0 85 4>;
+       };
+
+       memory-controller@2a150000 {
+               compatible = "arm,pl341", "arm,primecell";
+               reg = <0x2a150000 0x1000>;
+       };
+
+       memory-controller@2a190000 {
+               compatible = "arm,pl354", "arm,primecell";
+               reg = <0x2a190000 0x1000>;
+               interrupts = <0 86 4>,
+                            <0 87 4>;
+       };
+
+       scu@2c000000 {
+               compatible = "arm,cortex-a5-scu";
+               reg = <0x2c000000 0x58>;
+       };
+
+       timer@2c000600 {
+               compatible = "arm,cortex-a5-twd-timer";
+               reg = <0x2c000600 0x38>;
+               interrupts = <1 2 0x304>,
+                            <1 3 0x304>;
+       };
+
+       gic: interrupt-controller@2c001000 {
+               compatible = "arm,corex-a5-gic", "arm,cortex-a9-gic";
+               #interrupt-cells = <3>;
+               #address-cells = <0>;
+               interrupt-controller;
+               reg = <0x2c001000 0x1000>,
+                     <0x2c000100 0x100>;
+       };
+
+       L2: cache-controller@2c0f0000 {
+               compatible = "arm,pl310-cache";
+               reg = <0x2c0f0000 0x1000>;
+               interrupts = <0 84 4>;
+               cache-level = <2>;
+       };
+
+       pmu {
+               compatible = "arm,cortex-a5-pmu", "arm,cortex-a9-pmu";
+               interrupts = <0 68 4>,
+                            <0 69 4>;
+       };
+
+       motherboard {
+               ranges = <0 0 0x08000000 0x04000000>,
+                        <1 0 0x14000000 0x04000000>,
+                        <2 0 0x18000000 0x04000000>,
+                        <3 0 0x1c000000 0x04000000>,
+                        <4 0 0x0c000000 0x04000000>,
+                        <5 0 0x10000000 0x04000000>;
+
+               interrupt-map-mask = <0 0 63>;
+               interrupt-map = <0 0  0 &gic 0  0 4>,
+                               <0 0  1 &gic 0  1 4>,
+                               <0 0  2 &gic 0  2 4>,
+                               <0 0  3 &gic 0  3 4>,
+                               <0 0  4 &gic 0  4 4>,
+                               <0 0  5 &gic 0  5 4>,
+                               <0 0  6 &gic 0  6 4>,
+                               <0 0  7 &gic 0  7 4>,
+                               <0 0  8 &gic 0  8 4>,
+                               <0 0  9 &gic 0  9 4>,
+                               <0 0 10 &gic 0 10 4>,
+                               <0 0 11 &gic 0 11 4>,
+                               <0 0 12 &gic 0 12 4>,
+                               <0 0 13 &gic 0 13 4>,
+                               <0 0 14 &gic 0 14 4>,
+                               <0 0 15 &gic 0 15 4>,
+                               <0 0 16 &gic 0 16 4>,
+                               <0 0 17 &gic 0 17 4>,
+                               <0 0 18 &gic 0 18 4>,
+                               <0 0 19 &gic 0 19 4>,
+                               <0 0 20 &gic 0 20 4>,
+                               <0 0 21 &gic 0 21 4>,
+                               <0 0 22 &gic 0 22 4>,
+                               <0 0 23 &gic 0 23 4>,
+                               <0 0 24 &gic 0 24 4>,
+                               <0 0 25 &gic 0 25 4>,
+                               <0 0 26 &gic 0 26 4>,
+                               <0 0 27 &gic 0 27 4>,
+                               <0 0 28 &gic 0 28 4>,
+                               <0 0 29 &gic 0 29 4>,
+                               <0 0 30 &gic 0 30 4>,
+                               <0 0 31 &gic 0 31 4>,
+                               <0 0 32 &gic 0 32 4>,
+                               <0 0 33 &gic 0 33 4>,
+                               <0 0 34 &gic 0 34 4>,
+                               <0 0 35 &gic 0 35 4>,
+                               <0 0 36 &gic 0 36 4>,
+                               <0 0 37 &gic 0 37 4>,
+                               <0 0 38 &gic 0 38 4>,
+                               <0 0 39 &gic 0 39 4>,
+                               <0 0 40 &gic 0 40 4>,
+                               <0 0 41 &gic 0 41 4>,
+                               <0 0 42 &gic 0 42 4>;
+       };
+};
+
+/include/ "vexpress-v2m-rs1.dtsi"
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
new file mode 100644 (file)
index 0000000..da77869
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * ARM Ltd. Versatile Express
+ *
+ * CoreTile Express A9x4
+ * Cortex-A9 MPCore (V2P-CA9)
+ *
+ * HBI-0191B
+ */
+
+/dts-v1/;
+
+/ {
+       model = "V2P-CA9";
+       arm,hbi = <0x191>;
+       compatible = "arm,vexpress,v2p-ca9", "arm,vexpress";
+       interrupt-parent = <&gic>;
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       chosen { };
+
+       aliases {
+               serial0 = &v2m_serial0;
+               serial1 = &v2m_serial1;
+               serial2 = &v2m_serial2;
+               serial3 = &v2m_serial3;
+               i2c0 = &v2m_i2c_dvi;
+               i2c1 = &v2m_i2c_pcie;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       reg = <0>;
+                       next-level-cache = <&L2>;
+               };
+
+               cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       reg = <1>;
+                       next-level-cache = <&L2>;
+               };
+
+               cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       reg = <2>;
+                       next-level-cache = <&L2>;
+               };
+
+               cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a9";
+                       reg = <3>;
+                       next-level-cache = <&L2>;
+               };
+       };
+
+       memory@60000000 {
+               device_type = "memory";
+               reg = <0x60000000 0x40000000>;
+       };
+
+       clcd@10020000 {
+               compatible = "arm,pl111", "arm,primecell";
+               reg = <0x10020000 0x1000>;
+               interrupts = <0 44 4>;
+       };
+
+       memory-controller@100e0000 {
+               compatible = "arm,pl341", "arm,primecell";
+               reg = <0x100e0000 0x1000>;
+       };
+
+       memory-controller@100e1000 {
+               compatible = "arm,pl354", "arm,primecell";
+               reg = <0x100e1000 0x1000>;
+               interrupts = <0 45 4>,
+                            <0 46 4>;
+       };
+
+       timer@100e4000 {
+               compatible = "arm,sp804", "arm,primecell";
+               reg = <0x100e4000 0x1000>;
+               interrupts = <0 48 4>,
+                            <0 49 4>;
+       };
+
+       watchdog@100e5000 {
+               compatible = "arm,sp805", "arm,primecell";
+               reg = <0x100e5000 0x1000>;
+               interrupts = <0 51 4>;
+       };
+
+       scu@1e000000 {
+               compatible = "arm,cortex-a9-scu";
+               reg = <0x1e000000 0x58>;
+       };
+
+       timer@1e000600 {
+               compatible = "arm,cortex-a9-twd-timer";
+               reg = <0x1e000600 0x20>;
+               interrupts = <1 2 0xf04>,
+                            <1 3 0xf04>;
+       };
+
+       gic: interrupt-controller@1e001000 {
+               compatible = "arm,cortex-a9-gic";
+               #interrupt-cells = <3>;
+               #address-cells = <0>;
+               interrupt-controller;
+               reg = <0x1e001000 0x1000>,
+                     <0x1e000100 0x100>;
+       };
+
+       L2: cache-controller@1e00a000 {
+               compatible = "arm,pl310-cache";
+               reg = <0x1e00a000 0x1000>;
+               interrupts = <0 43 4>;
+               cache-level = <2>;
+               arm,data-latency = <1 1 1>;
+               arm,tag-latency = <1 1 1>;
+       };
+
+       pmu {
+               compatible = "arm,cortex-a9-pmu";
+               interrupts = <0 60 4>,
+                            <0 61 4>,
+                            <0 62 4>,
+                            <0 63 4>;
+       };
+
+       motherboard {
+               ranges = <0 0 0x40000000 0x04000000>,
+                        <1 0 0x44000000 0x04000000>,
+                        <2 0 0x48000000 0x04000000>,
+                        <3 0 0x4c000000 0x04000000>,
+                        <7 0 0x10000000 0x00020000>;
+
+               interrupt-map-mask = <0 0 63>;
+               interrupt-map = <0 0  0 &gic 0  0 4>,
+                               <0 0  1 &gic 0  1 4>,
+                               <0 0  2 &gic 0  2 4>,
+                               <0 0  3 &gic 0  3 4>,
+                               <0 0  4 &gic 0  4 4>,
+                               <0 0  5 &gic 0  5 4>,
+                               <0 0  6 &gic 0  6 4>,
+                               <0 0  7 &gic 0  7 4>,
+                               <0 0  8 &gic 0  8 4>,
+                               <0 0  9 &gic 0  9 4>,
+                               <0 0 10 &gic 0 10 4>,
+                               <0 0 11 &gic 0 11 4>,
+                               <0 0 12 &gic 0 12 4>,
+                               <0 0 13 &gic 0 13 4>,
+                               <0 0 14 &gic 0 14 4>,
+                               <0 0 15 &gic 0 15 4>,
+                               <0 0 16 &gic 0 16 4>,
+                               <0 0 17 &gic 0 17 4>,
+                               <0 0 18 &gic 0 18 4>,
+                               <0 0 19 &gic 0 19 4>,
+                               <0 0 20 &gic 0 20 4>,
+                               <0 0 21 &gic 0 21 4>,
+                               <0 0 22 &gic 0 22 4>,
+                               <0 0 23 &gic 0 23 4>,
+                               <0 0 24 &gic 0 24 4>,
+                               <0 0 25 &gic 0 25 4>,
+                               <0 0 26 &gic 0 26 4>,
+                               <0 0 27 &gic 0 27 4>,
+                               <0 0 28 &gic 0 28 4>,
+                               <0 0 29 &gic 0 29 4>,
+                               <0 0 30 &gic 0 30 4>,
+                               <0 0 31 &gic 0 31 4>,
+                               <0 0 32 &gic 0 32 4>,
+                               <0 0 33 &gic 0 33 4>,
+                               <0 0 34 &gic 0 34 4>,
+                               <0 0 35 &gic 0 35 4>,
+                               <0 0 36 &gic 0 36 4>,
+                               <0 0 37 &gic 0 37 4>,
+                               <0 0 38 &gic 0 38 4>,
+                               <0 0 39 &gic 0 39 4>,
+                               <0 0 40 &gic 0 40 4>,
+                               <0 0 41 &gic 0 41 4>,
+                               <0 0 42 &gic 0 42 4>;
+       };
+};
+
+/include/ "vexpress-v2m.dtsi"
index 81a933eb0903bf446c4722bd645aa2ec0573bf47..3bb1d7589bd9ec52a864487145cd88a428296253 100644 (file)
@@ -35,9 +35,6 @@ config DMABOUNCE
        bool
        select ZONE_DMA
 
-config TIMER_ACORN
-       bool
-
 config SHARP_LOCOMO
        bool
 
index 6ea9b6f3607af35121e2e117e1580b1d841b520d..69feafe7286c152f8eed73b998f2fe2e70347de9 100644 (file)
@@ -9,7 +9,6 @@ obj-$(CONFIG_PL330)             += pl330.o
 obj-$(CONFIG_SA1111)           += sa1111.o
 obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o
 obj-$(CONFIG_DMABOUNCE)                += dmabounce.o
-obj-$(CONFIG_TIMER_ACORN)      += time-acorn.o
 obj-$(CONFIG_SHARP_LOCOMO)     += locomo.o
 obj-$(CONFIG_SHARP_PARAM)      += sharpsl_param.o
 obj-$(CONFIG_SHARP_SCOOP)      += scoop.o
index 61691cdbdcf2cd7b7308c10560a917481c0e0be7..9173d112ea0156a31b2f2769731a3b80be7de680 100644 (file)
@@ -16,6 +16,7 @@
  */
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
@@ -28,9 +29,8 @@
 #include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
 #include <asm/mach/irq.h>
+#include <asm/mach-types.h>
 #include <asm/sizes.h>
 
 #include <asm/hardware/sa1111.h>
 #define IRQ_S1_CD_VALID                (52)
 #define IRQ_S0_BVD1_STSCHG     (53)
 #define IRQ_S1_BVD1_STSCHG     (54)
+#define SA1111_IRQ_NR          (55)
 
-extern void __init sa1110_mb_enable(void);
+extern void sa1110_mb_enable(void);
+extern void sa1110_mb_disable(void);
 
 /*
  * We keep the following data for the overall SA1111.  Note that the
@@ -104,6 +106,7 @@ struct sa1111 {
        int             irq_base;       /* base for cascaded on-chip IRQs */
        spinlock_t      lock;
        void __iomem    *base;
+       struct sa1111_platform_data *pdata;
 #ifdef CONFIG_PM
        void            *saved_state;
 #endif
@@ -118,6 +121,7 @@ static struct sa1111 *g_sa1111;
 struct sa1111_dev_info {
        unsigned long   offset;
        unsigned long   skpcr_mask;
+       bool            dma;
        unsigned int    devid;
        unsigned int    irq[6];
 };
@@ -126,6 +130,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
        {
                .offset         = SA1111_USB,
                .skpcr_mask     = SKPCR_UCLKEN,
+               .dma            = true,
                .devid          = SA1111_DEVID_USB,
                .irq = {
                        IRQ_USBPWR,
@@ -139,6 +144,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
        {
                .offset         = 0x0600,
                .skpcr_mask     = SKPCR_I2SCLKEN | SKPCR_L3CLKEN,
+               .dma            = true,
                .devid          = SA1111_DEVID_SAC,
                .irq = {
                        AUDXMTDMADONEA,
@@ -155,7 +161,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
        {
                .offset         = SA1111_KBD,
                .skpcr_mask     = SKPCR_PTCLKEN,
-               .devid          = SA1111_DEVID_PS2,
+               .devid          = SA1111_DEVID_PS2_KBD,
                .irq = {
                        IRQ_TPRXINT,
                        IRQ_TPTXINT
@@ -164,7 +170,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
        {
                .offset         = SA1111_MSE,
                .skpcr_mask     = SKPCR_PMCLKEN,
-               .devid          = SA1111_DEVID_PS2,
+               .devid          = SA1111_DEVID_PS2_MSE,
                .irq = {
                        IRQ_MSRXINT,
                        IRQ_MSTXINT
@@ -434,16 +440,28 @@ static struct irq_chip sa1111_high_chip = {
        .irq_set_wake   = sa1111_wake_highirq,
 };
 
-static void sa1111_setup_irq(struct sa1111 *sachip)
+static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base)
 {
        void __iomem *irqbase = sachip->base + SA1111_INTC;
-       unsigned int irq;
+       unsigned i, irq;
+       int ret;
 
        /*
         * We're guaranteed that this region hasn't been taken.
         */
        request_mem_region(sachip->phys + SA1111_INTC, 512, "irq");
 
+       ret = irq_alloc_descs(-1, irq_base, SA1111_IRQ_NR, -1);
+       if (ret <= 0) {
+               dev_err(sachip->dev, "unable to allocate %u irqs: %d\n",
+                       SA1111_IRQ_NR, ret);
+               if (ret == 0)
+                       ret = -EINVAL;
+               return ret;
+       }
+
+       sachip->irq_base = ret;
+
        /* disable all IRQs */
        sa1111_writel(0, irqbase + SA1111_INTEN0);
        sa1111_writel(0, irqbase + SA1111_INTEN1);
@@ -463,14 +481,16 @@ static void sa1111_setup_irq(struct sa1111 *sachip)
        sa1111_writel(~0, irqbase + SA1111_INTSTATCLR0);
        sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1);
 
-       for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) {
+       for (i = IRQ_GPAIN0; i <= SSPROR; i++) {
+               irq = sachip->irq_base + i;
                irq_set_chip_and_handler(irq, &sa1111_low_chip,
                                         handle_edge_irq);
                irq_set_chip_data(irq, sachip);
                set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
        }
 
-       for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) {
+       for (i = AUDXMTDMADONEA; i <= IRQ_S1_BVD1_STSCHG; i++) {
+               irq = sachip->irq_base + i;
                irq_set_chip_and_handler(irq, &sa1111_high_chip,
                                         handle_edge_irq);
                irq_set_chip_data(irq, sachip);
@@ -483,6 +503,11 @@ static void sa1111_setup_irq(struct sa1111 *sachip)
        irq_set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING);
        irq_set_handler_data(sachip->irq, sachip);
        irq_set_chained_handler(sachip->irq, sa1111_irq_handler);
+
+       dev_info(sachip->dev, "Providing IRQ%u-%u\n",
+               sachip->irq_base, sachip->irq_base + SA1111_IRQ_NR - 1);
+
+       return 0;
 }
 
 /*
@@ -581,41 +606,10 @@ sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac,
 }
 #endif
 
-#ifdef CONFIG_DMABOUNCE
-/*
- * According to the "Intel StrongARM SA-1111 Microprocessor Companion
- * Chip Specification Update" (June 2000), erratum #7, there is a
- * significant bug in the SA1111 SDRAM shared memory controller.  If
- * an access to a region of memory above 1MB relative to the bank base,
- * it is important that address bit 10 _NOT_ be asserted. Depending
- * on the configuration of the RAM, bit 10 may correspond to one
- * of several different (processor-relative) address bits.
- *
- * This routine only identifies whether or not a given DMA address
- * is susceptible to the bug.
- *
- * This should only get called for sa1111_device types due to the
- * way we configure our device dma_masks.
- */
-static int sa1111_needs_bounce(struct device *dev, dma_addr_t addr, size_t size)
-{
-       /*
-        * Section 4.6 of the "Intel StrongARM SA-1111 Development Module
-        * User's Guide" mentions that jumpers R51 and R52 control the
-        * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or
-        * SDRAM bank 1 on Neponset). The default configuration selects
-        * Assabet, so any address in bank 1 is necessarily invalid.
-        */
-       return (machine_is_assabet() || machine_is_pfs168()) &&
-               (addr >= 0xc8000000 || (addr + size) >= 0xc8000000);
-}
-#endif
-
 static void sa1111_dev_release(struct device *_dev)
 {
        struct sa1111_dev *dev = SA1111_DEV(_dev);
 
-       release_resource(&dev->res);
        kfree(dev);
 }
 
@@ -624,67 +618,58 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
                      struct sa1111_dev_info *info)
 {
        struct sa1111_dev *dev;
+       unsigned i;
        int ret;
 
        dev = kzalloc(sizeof(struct sa1111_dev), GFP_KERNEL);
        if (!dev) {
                ret = -ENOMEM;
-               goto out;
+               goto err_alloc;
        }
 
+       device_initialize(&dev->dev);
        dev_set_name(&dev->dev, "%4.4lx", info->offset);
        dev->devid       = info->devid;
        dev->dev.parent  = sachip->dev;
        dev->dev.bus     = &sa1111_bus_type;
        dev->dev.release = sa1111_dev_release;
-       dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask;
        dev->res.start   = sachip->phys + info->offset;
        dev->res.end     = dev->res.start + 511;
        dev->res.name    = dev_name(&dev->dev);
        dev->res.flags   = IORESOURCE_MEM;
        dev->mapbase     = sachip->base + info->offset;
        dev->skpcr_mask  = info->skpcr_mask;
-       memmove(dev->irq, info->irq, sizeof(dev->irq));
-
-       ret = request_resource(parent, &dev->res);
-       if (ret) {
-               printk("SA1111: failed to allocate resource for %s\n",
-                       dev->res.name);
-               dev_set_name(&dev->dev, NULL);
-               kfree(dev);
-               goto out;
-       }
-
 
-       ret = device_register(&dev->dev);
-       if (ret) {
-               release_resource(&dev->res);
-               kfree(dev);
-               goto out;
-       }
+       for (i = 0; i < ARRAY_SIZE(info->irq); i++)
+               dev->irq[i] = sachip->irq_base + info->irq[i];
 
-#ifdef CONFIG_DMABOUNCE
        /*
-        * If the parent device has a DMA mask associated with it,
-        * propagate it down to the children.
+        * If the parent device has a DMA mask associated with it, and
+        * this child supports DMA, propagate it down to the children.
         */
-       if (sachip->dev->dma_mask) {
+       if (info->dma && sachip->dev->dma_mask) {
                dev->dma_mask = *sachip->dev->dma_mask;
                dev->dev.dma_mask = &dev->dma_mask;
+               dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask;
+       }
 
-               if (dev->dma_mask != 0xffffffffUL) {
-                       ret = dmabounce_register_dev(&dev->dev, 1024, 4096,
-                                       sa1111_needs_bounce);
-                       if (ret) {
-                               dev_err(&dev->dev, "SA1111: Failed to register"
-                                       " with dmabounce\n");
-                               device_unregister(&dev->dev);
-                       }
-               }
+       ret = request_resource(parent, &dev->res);
+       if (ret) {
+               dev_err(sachip->dev, "failed to allocate resource for %s\n",
+                       dev->res.name);
+               goto err_resource;
        }
-#endif
 
-out:
+       ret = device_add(&dev->dev);
+       if (ret)
+               goto err_add;
+       return 0;
+
+ err_add:
+       release_resource(&dev->res);
+ err_resource:
+       put_device(&dev->dev);
+ err_alloc:
        return ret;
 }
 
@@ -698,16 +683,21 @@ out:
  *     Returns:
  *     %-ENODEV        device not found.
  *     %-EBUSY         physical address already marked in-use.
+ *     %-EINVAL        no platform data passed
  *     %0              successful.
  */
 static int __devinit
 __sa1111_probe(struct device *me, struct resource *mem, int irq)
 {
+       struct sa1111_platform_data *pd = me->platform_data;
        struct sa1111 *sachip;
        unsigned long id;
        unsigned int has_devs;
        int i, ret = -ENODEV;
 
+       if (!pd)
+               return -EINVAL;
+
        sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL);
        if (!sachip)
                return -ENOMEM;
@@ -727,6 +717,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
        sachip->dev = me;
        dev_set_drvdata(sachip->dev, sachip);
 
+       sachip->pdata = pd;
        sachip->phys = mem->start;
        sachip->irq = irq;
 
@@ -759,6 +750,16 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
         */
        sa1111_wake(sachip);
 
+       /*
+        * The interrupt controller must be initialised before any
+        * other device to ensure that the interrupts are available.
+        */
+       if (sachip->irq != NO_IRQ) {
+               ret = sa1111_setup_irq(sachip, pd->irq_base);
+               if (ret)
+                       goto err_unmap;
+       }
+
 #ifdef CONFIG_ARCH_SA1100
        {
        unsigned int val;
@@ -789,24 +790,14 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
        }
 #endif
 
-       /*
-        * The interrupt controller must be initialised before any
-        * other device to ensure that the interrupts are available.
-        */
-       if (sachip->irq != NO_IRQ)
-               sa1111_setup_irq(sachip);
-
        g_sa1111 = sachip;
 
        has_devs = ~0;
-       if (machine_is_assabet() || machine_is_jornada720() ||
-           machine_is_badge4())
-               has_devs &= ~(1 << 4);
-       else
-               has_devs &= ~(1 << 1);
+       if (pd)
+               has_devs &= ~pd->disable_devs;
 
        for (i = 0; i < ARRAY_SIZE(sa1111_devices); i++)
-               if (has_devs & (1 << i))
+               if (sa1111_devices[i].devid & has_devs)
                        sa1111_init_one_child(sachip, mem, &sa1111_devices[i]);
 
        return 0;
@@ -824,7 +815,10 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
 
 static int sa1111_remove_one(struct device *dev, void *data)
 {
-       device_unregister(dev);
+       struct sa1111_dev *sadev = SA1111_DEV(dev);
+       device_del(&sadev->dev);
+       release_resource(&sadev->res);
+       put_device(&sadev->dev);
        return 0;
 }
 
@@ -846,6 +840,7 @@ static void __sa1111_remove(struct sa1111 *sachip)
        if (sachip->irq != NO_IRQ) {
                irq_set_chained_handler(sachip->irq, NULL);
                irq_set_handler_data(sachip->irq, NULL);
+               irq_free_descs(sachip->irq_base, SA1111_IRQ_NR);
 
                release_mem_region(sachip->phys + SA1111_INTC, 512);
        }
@@ -904,6 +899,9 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state)
        save->skpwm0   = sa1111_readl(base + SA1111_SKPWM0);
        save->skpwm1   = sa1111_readl(base + SA1111_SKPWM1);
 
+       sa1111_writel(0, sachip->base + SA1111_SKPWM0);
+       sa1111_writel(0, sachip->base + SA1111_SKPWM1);
+
        base = sachip->base + SA1111_INTC;
        save->intpol0  = sa1111_readl(base + SA1111_INTPOL0);
        save->intpol1  = sa1111_readl(base + SA1111_INTPOL1);
@@ -919,13 +917,15 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state)
         */
        val = sa1111_readl(sachip->base + SA1111_SKCR);
        sa1111_writel(val | SKCR_SLEEP, sachip->base + SA1111_SKCR);
-       sa1111_writel(0, sachip->base + SA1111_SKPWM0);
-       sa1111_writel(0, sachip->base + SA1111_SKPWM1);
 
        clk_disable(sachip->clk);
 
        spin_unlock_irqrestore(&sachip->lock, flags);
 
+#ifdef CONFIG_ARCH_SA1100
+       sa1110_mb_disable();
+#endif
+
        return 0;
 }
 
@@ -966,6 +966,11 @@ static int sa1111_resume(struct platform_device *dev)
         */
        sa1111_wake(sachip);
 
+#ifdef CONFIG_ARCH_SA1100
+       /* Enable the memory bus request/grant signals */
+       sa1110_mb_enable();
+#endif
+
        /*
         * Only lock for write ops. Also, sa1111_wake must be called with
         * released spinlock!
@@ -1053,6 +1058,7 @@ static struct platform_driver sa1111_device_driver = {
        .resume         = sa1111_resume,
        .driver         = {
                .name   = "sa1111",
+               .owner  = THIS_MODULE,
        },
 };
 
@@ -1238,16 +1244,23 @@ EXPORT_SYMBOL(sa1111_set_sleep_io);
  *     sa1111_enable_device - enable an on-chip SA1111 function block
  *     @sadev: SA1111 function block device to enable
  */
-void sa1111_enable_device(struct sa1111_dev *sadev)
+int sa1111_enable_device(struct sa1111_dev *sadev)
 {
        struct sa1111 *sachip = sa1111_chip_driver(sadev);
        unsigned long flags;
        unsigned int val;
+       int ret = 0;
 
-       spin_lock_irqsave(&sachip->lock, flags);
-       val = sa1111_readl(sachip->base + SA1111_SKPCR);
-       sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
-       spin_unlock_irqrestore(&sachip->lock, flags);
+       if (sachip->pdata && sachip->pdata->enable)
+               ret = sachip->pdata->enable(sachip->pdata->data, sadev->devid);
+
+       if (ret == 0) {
+               spin_lock_irqsave(&sachip->lock, flags);
+               val = sa1111_readl(sachip->base + SA1111_SKPCR);
+               sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
+               spin_unlock_irqrestore(&sachip->lock, flags);
+       }
+       return ret;
 }
 EXPORT_SYMBOL(sa1111_enable_device);
 
@@ -1265,6 +1278,9 @@ void sa1111_disable_device(struct sa1111_dev *sadev)
        val = sa1111_readl(sachip->base + SA1111_SKPCR);
        sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
        spin_unlock_irqrestore(&sachip->lock, flags);
+
+       if (sachip->pdata && sachip->pdata->disable)
+               sachip->pdata->disable(sachip->pdata->data, sadev->devid);
 }
 EXPORT_SYMBOL(sa1111_disable_device);
 
@@ -1279,7 +1295,7 @@ static int sa1111_match(struct device *_dev, struct device_driver *_drv)
        struct sa1111_dev *dev = SA1111_DEV(_dev);
        struct sa1111_driver *drv = SA1111_DRV(_drv);
 
-       return dev->devid == drv->devid;
+       return dev->devid & drv->devid;
 }
 
 static int sa1111_bus_suspend(struct device *dev, pm_message_t state)
@@ -1304,6 +1320,14 @@ static int sa1111_bus_resume(struct device *dev)
        return ret;
 }
 
+static void sa1111_bus_shutdown(struct device *dev)
+{
+       struct sa1111_driver *drv = SA1111_DRV(dev->driver);
+
+       if (drv && drv->shutdown)
+               drv->shutdown(SA1111_DEV(dev));
+}
+
 static int sa1111_bus_probe(struct device *dev)
 {
        struct sa1111_dev *sadev = SA1111_DEV(dev);
@@ -1333,6 +1357,7 @@ struct bus_type sa1111_bus_type = {
        .remove         = sa1111_bus_remove,
        .suspend        = sa1111_bus_suspend,
        .resume         = sa1111_bus_resume,
+       .shutdown       = sa1111_bus_shutdown,
 };
 EXPORT_SYMBOL(sa1111_bus_type);
 
@@ -1349,9 +1374,70 @@ void sa1111_driver_unregister(struct sa1111_driver *driver)
 }
 EXPORT_SYMBOL(sa1111_driver_unregister);
 
+#ifdef CONFIG_DMABOUNCE
+/*
+ * According to the "Intel StrongARM SA-1111 Microprocessor Companion
+ * Chip Specification Update" (June 2000), erratum #7, there is a
+ * significant bug in the SA1111 SDRAM shared memory controller.  If
+ * an access to a region of memory above 1MB relative to the bank base,
+ * it is important that address bit 10 _NOT_ be asserted. Depending
+ * on the configuration of the RAM, bit 10 may correspond to one
+ * of several different (processor-relative) address bits.
+ *
+ * This routine only identifies whether or not a given DMA address
+ * is susceptible to the bug.
+ *
+ * This should only get called for sa1111_device types due to the
+ * way we configure our device dma_masks.
+ */
+static int sa1111_needs_bounce(struct device *dev, dma_addr_t addr, size_t size)
+{
+       /*
+        * Section 4.6 of the "Intel StrongARM SA-1111 Development Module
+        * User's Guide" mentions that jumpers R51 and R52 control the
+        * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or
+        * SDRAM bank 1 on Neponset). The default configuration selects
+        * Assabet, so any address in bank 1 is necessarily invalid.
+        */
+       return (machine_is_assabet() || machine_is_pfs168()) &&
+               (addr >= 0xc8000000 || (addr + size) >= 0xc8000000);
+}
+
+static int sa1111_notifier_call(struct notifier_block *n, unsigned long action,
+       void *data)
+{
+       struct sa1111_dev *dev = SA1111_DEV(data);
+
+       switch (action) {
+       case BUS_NOTIFY_ADD_DEVICE:
+               if (dev->dev.dma_mask && dev->dma_mask < 0xffffffffUL) {
+                       int ret = dmabounce_register_dev(&dev->dev, 1024, 4096,
+                                       sa1111_needs_bounce);
+                       if (ret)
+                               dev_err(&dev->dev, "failed to register with dmabounce: %d\n", ret);
+               }
+               break;
+
+       case BUS_NOTIFY_DEL_DEVICE:
+               if (dev->dev.dma_mask && dev->dma_mask < 0xffffffffUL)
+                       dmabounce_unregister_dev(&dev->dev);
+               break;
+       }
+       return NOTIFY_OK;
+}
+
+static struct notifier_block sa1111_bus_notifier = {
+       .notifier_call = sa1111_notifier_call,
+};
+#endif
+
 static int __init sa1111_init(void)
 {
        int ret = bus_register(&sa1111_bus_type);
+#ifdef CONFIG_DMABOUNCE
+       if (ret == 0)
+               bus_register_notifier(&sa1111_bus_type, &sa1111_bus_notifier);
+#endif
        if (ret == 0)
                platform_driver_register(&sa1111_device_driver);
        return ret;
@@ -1360,6 +1446,9 @@ static int __init sa1111_init(void)
 static void __exit sa1111_exit(void)
 {
        platform_driver_unregister(&sa1111_device_driver);
+#ifdef CONFIG_DMABOUNCE
+       bus_unregister_notifier(&sa1111_bus_type, &sa1111_bus_notifier);
+#endif
        bus_unregister(&sa1111_bus_type);
 }
 
diff --git a/arch/arm/common/time-acorn.c b/arch/arm/common/time-acorn.c
deleted file mode 100644 (file)
index deeed56..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- *  linux/arch/arm/common/time-acorn.c
- *
- *  Copyright (c) 1996-2000 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  Changelog:
- *   24-Sep-1996       RMK     Created
- *   10-Oct-1996       RMK     Brought up to date with arch-sa110eval
- *   04-Dec-1997       RMK     Updated for new arch/arm/time.c
- *   13=Jun-2004       DS      Moved to arch/arm/common b/c shared w/CLPS7500
- */
-#include <linux/timex.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/hardware/ioc.h>
-
-#include <asm/mach/time.h>
-
-unsigned long ioc_timer_gettimeoffset(void)
-{
-       unsigned int count1, count2, status;
-       long offset;
-
-       ioc_writeb (0, IOC_T0LATCH);
-       barrier ();
-       count1 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
-       barrier ();
-       status = ioc_readb(IOC_IRQREQA);
-       barrier ();
-       ioc_writeb (0, IOC_T0LATCH);
-       barrier ();
-       count2 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
-
-       offset = count2;
-       if (count2 < count1) {
-               /*
-                * We have not had an interrupt between reading count1
-                * and count2.
-                */
-               if (status & (1 << 5))
-                       offset -= LATCH;
-       } else if (count2 > count1) {
-               /*
-                * We have just had another interrupt between reading
-                * count1 and count2.
-                */
-               offset -= LATCH;
-       }
-
-       offset = (LATCH - offset) * (tick_nsec / 1000);
-       return (offset + LATCH/2) / LATCH;
-}
-
-void __init ioctime_init(void)
-{
-       ioc_writeb(LATCH & 255, IOC_T0LTCHL);
-       ioc_writeb(LATCH >> 8, IOC_T0LTCHH);
-       ioc_writeb(0, IOC_T0GO);
-}
-
-static irqreturn_t
-ioc_timer_interrupt(int irq, void *dev_id)
-{
-       timer_tick();
-       return IRQ_HANDLED;
-}
-
-static struct irqaction ioc_timer_irq = {
-       .name           = "timer",
-       .flags          = IRQF_DISABLED,
-       .handler        = ioc_timer_interrupt
-};
-
-/*
- * Set up timer interrupt.
- */
-static void __init ioc_timer_init(void)
-{
-       ioctime_init();
-       setup_irq(IRQ_TIMER, &ioc_timer_irq);
-}
-
-struct sys_timer ioc_timer = {
-       .init           = ioc_timer_init,
-       .offset         = ioc_timer_gettimeoffset,
-};
-
index 8794a34eae61d87b34d433dc1266c555c7687fca..df13a3ffff3514b703584483d1b43a9cb12d3953 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 
+#include <asm/sched_clock.h>
 #include <asm/hardware/arm_timer.h>
 
 static long __init sp804_get_clock_rate(const char *name)
@@ -67,7 +68,16 @@ static long __init sp804_get_clock_rate(const char *name)
        return rate;
 }
 
-void __init sp804_clocksource_init(void __iomem *base, const char *name)
+static void __iomem *sched_clock_base;
+
+static u32 sp804_read(void)
+{
+       return ~readl_relaxed(sched_clock_base + TIMER_VALUE);
+}
+
+void __init __sp804_clocksource_and_sched_clock_init(void __iomem *base,
+                                                    const char *name,
+                                                    int use_sched_clock)
 {
        long rate = sp804_get_clock_rate(name);
 
@@ -83,6 +93,11 @@ void __init sp804_clocksource_init(void __iomem *base, const char *name)
 
        clocksource_mmio_init(base + TIMER_VALUE, name,
                rate, 200, 32, clocksource_mmio_readl_down);
+
+       if (use_sched_clock) {
+               sched_clock_base = base;
+               setup_sched_clock(sp804_read, 32, rate);
+       }
 }
 
 
diff --git a/arch/arm/configs/at91cap9_defconfig b/arch/arm/configs/at91cap9_defconfig
deleted file mode 100644 (file)
index 8826eb2..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91CAP9=y
-CONFIG_MACH_AT91CAP9ADK=y
-CONFIG_MTD_AT91_DATAFLASH_CARD=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_AEABI=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_DATAFLASH=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_NETDEVICES=y
-CONFIG_MII=y
-CONFIG_MACB=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=y
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_SPI=y
-CONFIG_SPI_ATMEL=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_FB=y
-CONFIG_FB_ATMEL=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_CLUT224 is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ETH=m
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_MMC=y
-CONFIG_MMC_AT91=m
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91SAM9=y
-CONFIG_EXT2_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_USER=y
index 9123568d9a8db424f34fceaa66aa69d5fb4374fe..994d331b231956b0edd5d6e01a773beeda32fa60 100644 (file)
@@ -74,6 +74,8 @@ CONFIG_LEGACY_PTY_COUNT=16
 CONFIG_SERIAL_ATMEL=y
 CONFIG_SERIAL_ATMEL_CONSOLE=y
 CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_GPIO=y
 CONFIG_SPI=y
 CONFIG_SPI_ATMEL=y
 CONFIG_SPI_SPIDEV=y
@@ -105,6 +107,7 @@ CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_RV3029C2=y
 CONFIG_RTC_DRV_AT91SAM9=y
 CONFIG_EXT2_FS=y
 CONFIG_MSDOS_FS=y
index a22e93079063855cc5bf8047864bda8284a5ec01..b5ac644e12af9121985b0eadeecfdefaaf85c33b 100644 (file)
@@ -45,6 +45,7 @@ CONFIG_FPE_NWFPE=y
 CONFIG_FPE_NWFPE_XP=y
 CONFIG_PM_DEBUG=y
 CONFIG_NET=y
+CONFIG_SMSC911X=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
 CONFIG_INET=y
@@ -68,6 +69,7 @@ CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_ADV_OPTIONS=y
 CONFIG_MTD_CFI_GEOMETRY=y
 # CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
 # CONFIG_MTD_CFI_I2 is not set
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_PHYSMAP=y
@@ -78,6 +80,8 @@ CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_AT24=y
 CONFIG_EEPROM_AT25=y
 CONFIG_NETDEVICES=y
+CONFIG_CS89x0=y
+CONFIG_CS89x0_PLATFORM=y
 CONFIG_DM9000=y
 CONFIG_SMC91X=y
 CONFIG_SMC911X=y
@@ -115,6 +119,21 @@ CONFIG_FB_IMX=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_LCD_L4F00242T03=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+CONFIG_VIDEO_MEDIA=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_DMA_CONTIG=y
+CONFIG_VIDEOBUF2_CORE=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_OV2640=y
+CONFIG_VIDEO_MX2_HOSTSUPPORT=y
+CONFIG_VIDEO_MX2=y
 CONFIG_BACKLIGHT_PWM=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FONTS=y
index 3a4fb2e5fc68fb53c54467d466da94d295703f72..dc6f6411bbf5e9fb640831da44aa36f3d82cbb5c 100644 (file)
@@ -5,6 +5,7 @@ CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=18
 CONFIG_CGROUPS=y
 CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_COMPAT_BRK is not set
@@ -12,7 +13,6 @@ CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_ARCH_MXC=y
 CONFIG_MACH_MX31LILLY=y
@@ -26,7 +26,6 @@ CONFIG_MACH_ARMADILLO5X0=y
 CONFIG_MACH_KZM_ARM11_01=y
 CONFIG_MACH_PCM043=y
 CONFIG_MACH_MX35_3DS=y
-CONFIG_MACH_EUKREA_CPUIMX35=y
 CONFIG_MACH_VPR200=y
 CONFIG_MACH_IMX51_DT=y
 CONFIG_MACH_MX51_3DS=y
@@ -82,8 +81,9 @@ CONFIG_PATA_IMX=y
 CONFIG_NETDEVICES=y
 # CONFIG_NET_VENDOR_BROADCOM is not set
 # CONFIG_NET_VENDOR_CHELSIO is not set
+CONFIG_CS89x0=y
+CONFIG_CS89x0_PLATFORM=y
 # CONFIG_NET_VENDOR_FARADAY is not set
-CONFIG_FEC=y
 # CONFIG_NET_VENDOR_INTEL is not set
 # CONFIG_NET_VENDOR_MARVELL is not set
 # CONFIG_NET_VENDOR_MICREL is not set
@@ -126,7 +126,40 @@ CONFIG_WATCHDOG=y
 CONFIG_IMX2_WDT=y
 CONFIG_MFD_MC13XXX=y
 CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_MC13783=y
 CONFIG_REGULATOR_MC13892=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF2_CORE=y
+CONFIG_VIDEOBUF2_MEMOPS=y
+CONFIG_VIDEOBUF2_DMA_CONTIG=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_OV2640=y
+CONFIG_MX3_VIDEO=y
+CONFIG_VIDEO_MX3=y
+CONFIG_FB=y
+CONFIG_FB_MX3=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_L4F00242T03=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_MXC=y
diff --git a/arch/arm/configs/lpc32xx_defconfig b/arch/arm/configs/lpc32xx_defconfig
new file mode 100644 (file)
index 0000000..fb20881
--- /dev/null
@@ -0,0 +1,145 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ARCH_LPC32XX=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200n81 root=/dev/ram0"
+CONFIG_CPU_IDLE=y
+CONFIG_FPE_NWFPE=y
+CONFIG_VFP=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_MUSEUM_IDS=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_MISC_DEVICES=y
+CONFIG_EEPROM_AT25=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_PHYLIB=y
+CONFIG_SMSC_PHY=y
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_LPC32XX=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PNX=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_PNX4008_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_ARMCLCD=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SEQUENCER=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_SOC=y
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_LIBUSUAL=y
+CONFIG_MMC=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_ARMMMCI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_LPC32XX=y
+CONFIG_EXT2_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_FTRACE is not set
+# CONFIG_ARM_UNWIND is not set
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_CCITT=y
index 443675d317e6de326c576caf47ae9ff179a0814c..a691ef4c6008bac6a96c38aeb6615e685025d8ee 100644 (file)
@@ -101,7 +101,7 @@ CONFIG_MFD_ASIC3=y
 CONFIG_HTC_EGPIO=y
 CONFIG_HTC_PASIC3=y
 CONFIG_REGULATOR=y
-CONFIG_REGULATOR_BQ24022=y
+CONFIG_REGULATOR_GPIO=y
 CONFIG_FB=y
 CONFIG_FB_PXA=y
 CONFIG_FB_PXA_OVERLAY=y
index 2472a95858340562a0ddbc900e72c49352596991..42da9183acc85509342b00bc14a458a6d5d6a267 100644 (file)
@@ -13,7 +13,7 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_BLK_DEV_INTEGRITY=y
-CONFIG_ARCH_S3C2410=y
+CONFIG_ARCH_S3C24XX=y
 CONFIG_S3C_ADC=y
 CONFIG_S3C24XX_PWM=y
 CONFIG_MACH_MINI2440=y
index 6ee781bf6bf131ceeebac6900d69ae41774dac62..1ebbf451c48d39076446dd84406e00fb5fcb9b6e 100644 (file)
@@ -77,10 +77,10 @@ CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
-CONFIG_I2C=m
+CONFIG_I2C=y
 # CONFIG_I2C_COMPAT is not set
-CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_MXS=m
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MXS=y
 CONFIG_SPI=y
 CONFIG_SPI_GPIO=m
 CONFIG_DEBUG_GPIO=y
@@ -90,6 +90,20 @@ CONFIG_GPIO_SYSFS=y
 CONFIG_DISPLAY_SUPPORT=m
 # CONFIG_HID_SUPPORT is not set
 # CONFIG_USB_SUPPORT is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
+CONFIG_SND_DRIVERS=y
+CONFIG_SND_ARM=y
+CONFIG_SND_SOC=y
+CONFIG_SND_MXS_SOC=y
+CONFIG_SND_SOC_MXS_SGTL5000=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+CONFIG_SND_SOC_SGTL5000=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_MMC=y
 CONFIG_MMC_MXS=y
 CONFIG_RTC_CLASS=y
index f9096c1b0a65646fc1c0b3bbe3bf19a3f746e786..193448f31284994a65a390dd107cf8f03a62a211 100644 (file)
@@ -3,40 +3,47 @@ CONFIG_SYSVIPC=y
 CONFIG_IKCONFIG=m
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=16
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_S3C2410=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_ARCH_S3C24XX=y
 CONFIG_S3C_BOOT_ERROR_RESET=y
 CONFIG_S3C_ADC=y
 CONFIG_S3C24XX_PWM=y
-CONFIG_ARCH_SMDK2410=y
+CONFIG_CPU_S3C2412=y
+CONFIG_CPU_S3C2416=y
+CONFIG_CPU_S3C2440=y
+CONFIG_CPU_S3C2442=y
+CONFIG_CPU_S3C2443=y
+CONFIG_MACH_AML_M5900=y
+CONFIG_ARCH_BAST=y
 CONFIG_ARCH_H1940=y
 CONFIG_MACH_N30=y
-CONFIG_ARCH_BAST=y
 CONFIG_MACH_OTOM=y
-CONFIG_MACH_AML_M5900=y
+CONFIG_MACH_QT2410=y
+CONFIG_ARCH_SMDK2410=y
 CONFIG_MACH_TCT_HAMMER=y
 CONFIG_MACH_VR1000=y
-CONFIG_MACH_QT2410=y
 CONFIG_MACH_JIVE=y
 CONFIG_MACH_SMDK2412=y
 CONFIG_MACH_VSTMS=y
 CONFIG_MACH_SMDK2416=y
 CONFIG_MACH_ANUBIS=y
-CONFIG_MACH_NEO1973_GTA02=y
+CONFIG_MACH_AT2440EVB=y
+CONFIG_MACH_MINI2440=y
+CONFIG_MACH_NEXCODER_2440=y
 CONFIG_MACH_OSIRIS=y
 CONFIG_MACH_OSIRIS_DVS=m
 CONFIG_MACH_RX3715=y
 CONFIG_ARCH_S3C2440=y
-CONFIG_MACH_NEXCODER_2440=y
-CONFIG_SMDK2440_CPU2442=y
-CONFIG_MACH_AT2440EVB=y
-CONFIG_MACH_MINI2440=y
+CONFIG_MACH_NEO1973_GTA02=y
 CONFIG_MACH_RX1950=y
+CONFIG_SMDK2440_CPU2442=y
 CONFIG_MACH_SMDK2443=y
 # CONFIG_ARM_THUMB is not set
 CONFIG_ZBOOT_ROM_TEXT=0x0
@@ -45,7 +52,6 @@ CONFIG_CMDLINE="root=/dev/hda1 ro init=/bin/bash console=ttySAC0"
 CONFIG_FPE_NWFPE=y
 CONFIG_FPE_NWFPE_XP=y
 CONFIG_BINFMT_AOUT=y
-CONFIG_PM=y
 CONFIG_APM_EMULATION=m
 CONFIG_NET=y
 CONFIG_PACKET=y
@@ -58,7 +64,6 @@ CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
@@ -80,7 +85,6 @@ CONFIG_IPV6_MIP6=m
 CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
 CONFIG_IPV6_TUNNEL=m
 CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NF_CONNTRACK=m
 CONFIG_NF_CONNTRACK_EVENTS=y
 CONFIG_NF_CT_PROTO_DCCP=m
@@ -138,7 +142,6 @@ CONFIG_IP_VS=m
 CONFIG_NF_CONNTRACK_IPV4=m
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_ECN=m
 CONFIG_IP_NF_MATCH_TTL=m
@@ -150,7 +153,6 @@ CONFIG_NF_NAT=m
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_TARGET_ECN=m
@@ -177,8 +179,6 @@ CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_RAW=m
 CONFIG_BT=m
-CONFIG_BT_L2CAP=m
-CONFIG_BT_SCO=m
 CONFIG_BT_RFCOMM=m
 CONFIG_BT_RFCOMM_TTY=y
 CONFIG_BT_BNEP=m
@@ -199,7 +199,6 @@ CONFIG_MAC80211_MESH=y
 CONFIG_MAC80211_LEDS=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_REDBOOT_PARTS=y
 CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
 CONFIG_MTD_CMDLINE_PARTS=y
@@ -221,9 +220,6 @@ CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_UB=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_ATA_OVER_ETH=m
-CONFIG_EEPROM_AT25=m
-CONFIG_EEPROM_LEGACY=m
-CONFIG_EEPROM_93CX6=m
 CONFIG_IDE=y
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDETAPE=m
@@ -240,7 +236,6 @@ CONFIG_SCSI_MULTI_LUN=y
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_SCAN_ASYNC=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
 CONFIG_DM9000=y
 CONFIG_INPUT_EVDEV=y
 CONFIG_MOUSE_APPLETOUCH=m
@@ -274,7 +269,6 @@ CONFIG_JOYSTICK_XPAD_LEDS=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
 CONFIG_INPUT_MISC=y
-CONFIG_INPUT_ATI_REMOTE=m
 CONFIG_INPUT_ATI_REMOTE2=m
 CONFIG_INPUT_KEYSPAN_REMOTE=m
 CONFIG_INPUT_POWERMATE=m
@@ -300,7 +294,6 @@ CONFIG_I2C_SIMTEC=y
 CONFIG_SPI=y
 CONFIG_SPI_GPIO=m
 CONFIG_SPI_S3C24XX=m
-CONFIG_SPI_S3C24XX_GPIO=m
 CONFIG_SPI_SPIDEV=m
 CONFIG_SPI_TLE62X0=m
 CONFIG_SENSORS_LM75=m
@@ -315,7 +308,6 @@ CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_S3C2410=y
 CONFIG_FB_SM501=y
 CONFIG_BACKLIGHT_PWM=m
-# CONFIG_VGA_CONSOLE is not set
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_SOUND=y
 CONFIG_SND=y
@@ -330,10 +322,6 @@ CONFIG_SND_VERBOSE_PRINTK=y
 CONFIG_SND_USB_AUDIO=m
 CONFIG_SND_USB_CAIAQ=m
 CONFIG_SND_SOC=y
-CONFIG_SND_S3C24XX_SOC=y
-CONFIG_SND_S3C24XX_SOC_JIVE_WM8750=m
-CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710=m
-CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650=m
 # CONFIG_USB_HID is not set
 CONFIG_USB=y
 CONFIG_USB_DEVICEFS=y
@@ -387,9 +375,7 @@ CONFIG_MMC_TEST=m
 CONFIG_MMC_SDHCI=m
 CONFIG_MMC_SPI=m
 CONFIG_MMC_S3C=y
-CONFIG_LEDS_CLASS=m
 CONFIG_LEDS_S3C24XX=m
-CONFIG_LEDS_H1940=m
 CONFIG_LEDS_PCA9532=m
 CONFIG_LEDS_GPIO=m
 CONFIG_LEDS_PCA955X=m
@@ -410,8 +396,6 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT4_FS=m
 CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_INOTIFY=y
-CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
 CONFIG_ISO9660_FS=y
@@ -436,9 +420,6 @@ CONFIG_NFSD=m
 CONFIG_NFSD_V3_ACL=y
 CONFIG_NFSD_V4=y
 CONFIG_CIFS=m
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_BSD_DISKLABEL=y
-CONFIG_SOLARIS_X86_PARTITION=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_737=m
 CONFIG_NLS_CODEPAGE_775=m
@@ -481,9 +462,7 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_MUTEXES=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_LL=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
index 95c0f0d63db63977e1e4f64220aad77568ac1865..1d24f8458befd49cd41b98e6fb1d6f22fcca8f94 100644 (file)
@@ -14,7 +14,7 @@ CONFIG_SLOB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_S3C2410=y
+CONFIG_ARCH_S3C24XX=y
 CONFIG_MACH_TCT_HAMMER=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
index fd5d3041d717abf45b8243eba47f66f07d38a3cb..351d6708c3aeadde00cce5c6c2ca18cc94b9d11a 100644 (file)
@@ -11,11 +11,14 @@ CONFIG_RT_GROUP_SCHED=y
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_ELF_CORE is not set
 CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_EFI_PARTITION=y
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
 CONFIG_ARCH_TEGRA=y
@@ -27,18 +30,20 @@ CONFIG_MACH_PAZ00=y
 CONFIG_MACH_TRIMSLICE=y
 CONFIG_MACH_WARIO=y
 CONFIG_MACH_VENTANA=y
-CONFIG_TEGRA_DEBUG_UARTD=y
-CONFIG_ARM_ERRATA_742230=y
+CONFIG_TEGRA_EMC_SCALING_ENABLE=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_SMP=y
-CONFIG_NR_CPUS=2
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 # CONFIG_OABI_COMPAT is not set
 CONFIG_HIGHMEM=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_IDLE=y
 CONFIG_VFP=y
 CONFIG_NET=y
 CONFIG_PACKET=y
@@ -68,7 +73,6 @@ CONFIG_IPV6_MULTIPLE_TABLES=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
 CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
-CONFIG_MISC_DEVICES=y
 CONFIG_AD525X_DPOT=y
 CONFIG_AD525X_DPOT_I2C=y
 CONFIG_ICS932S401=y
@@ -76,6 +80,7 @@ CONFIG_APDS9802ALS=y
 CONFIG_ISL29003=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=y
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
@@ -85,8 +90,7 @@ CONFIG_USB_USBNET=y
 CONFIG_USB_NET_SMSC75XX=y
 CONFIG_USB_NET_SMSC95XX=y
 # CONFIG_WLAN is not set
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
+CONFIG_INPUT_EVDEV=y
 # CONFIG_VT is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
@@ -96,13 +100,15 @@ CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
 # CONFIG_I2C_COMPAT is not set
-# CONFIG_I2C_HELPER_AUTO is not set
 CONFIG_I2C_TEGRA=y
 CONFIG_SPI=y
 CONFIG_SPI_TEGRA=y
 CONFIG_SENSORS_LM90=y
 CONFIG_MFD_TPS6586X=y
 CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
+CONFIG_REGULATOR_GPIO=y
 CONFIG_REGULATOR_TPS6586X=y
 CONFIG_SOUND=y
 CONFIG_SND=y
@@ -116,11 +122,13 @@ CONFIG_SND_SOC=y
 CONFIG_SND_SOC_TEGRA=y
 CONFIG_SND_SOC_TEGRA_WM8903=y
 CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
+CONFIG_SND_SOC_TEGRA_ALC5632=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_TEGRA=y
 CONFIG_USB_STORAGE=y
 CONFIG_MMC=y
+CONFIG_MMC_BLOCK_MINORS=16
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_TEGRA=y
@@ -130,6 +138,11 @@ CONFIG_STAGING=y
 CONFIG_IIO=y
 CONFIG_SENSORS_ISL29018=y
 CONFIG_SENSORS_AK8975=y
+CONFIG_MFD_NVEC=y
+CONFIG_KEYBOARD_NVEC=y
+CONFIG_SERIO_NVEC_PS2=y
+CONFIG_TEGRA_IOMMU_GART=y
+CONFIG_TEGRA_IOMMU_SMMU=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
@@ -138,13 +151,12 @@ CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
 # CONFIG_DNOTIFY is not set
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_EFI_PARTITION=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_PRINTK_TIME=y
@@ -162,9 +174,8 @@ CONFIG_DEBUG_SG=y
 CONFIG_DEBUG_LL=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_ARC4=y
 CONFIG_CRYPTO_TWOFISH=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_DEV_TEGRA_AES=y
 CONFIG_CRC_CCITT=y
-CONFIG_CRC16=y
index 2d7b6e7b72713cba72df0349462c29dbe38a67ba..889d73ac1ae11e6870a7a345fb402b8e54ce8070 100644 (file)
@@ -13,6 +13,7 @@ CONFIG_UX500_SOC_DB8500=y
 CONFIG_MACH_HREFV60=y
 CONFIG_MACH_SNOWBALL=y
 CONFIG_MACH_U5500=y
+CONFIG_MACH_UX500_DT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_SMP=y
index c0f4e7bf22de9357da96283d4f22d3eeed33ffba..d6030ff599db968d43b9ddf323db36ac00aceca4 100644 (file)
@@ -9,7 +9,12 @@
  *
  * Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview
  * can have 16-bit or 32-bit selectable via a bit in the control register.
+ *
+ * Every SP804 contains two identical timers.
  */
+#define TIMER_1_BASE   0x00
+#define TIMER_2_BASE   0x20
+
 #define TIMER_LOAD     0x00                    /* ACVR rw */
 #define TIMER_VALUE    0x04                    /* ACVR ro */
 #define TIMER_CTRL     0x08                    /* ACVR rw */
index 92ed254c175bd53b15692ebbcce5dda6174dc95f..7c2bbc7f0be168693a674df1f4f86142b25d5e25 100644 (file)
 #define SKPCR_DCLKEN   (1<<7)
 #define SKPCR_PWMCLKEN (1<<8)
 
-/*
- * USB Host controller
- */
+/* USB Host controller */
 #define SA1111_USB             0x0400
 
-/*
- * Offsets from SA1111_USB_BASE
- */
-#define SA1111_USB_STATUS      0x0118
-#define SA1111_USB_RESET       0x011c
-#define SA1111_USB_IRQTEST     0x0120
-
-#define USB_RESET_FORCEIFRESET (1 << 0)
-#define USB_RESET_FORCEHCRESET (1 << 1)
-#define USB_RESET_CLKGENRESET  (1 << 2)
-#define USB_RESET_SIMSCALEDOWN (1 << 3)
-#define USB_RESET_USBINTTEST   (1 << 4)
-#define USB_RESET_SLEEPSTBYEN  (1 << 5)
-#define USB_RESET_PWRSENSELOW  (1 << 6)
-#define USB_RESET_PWRCTRLLOW   (1 << 7)
-
-#define USB_STATUS_IRQHCIRMTWKUP  (1 <<  7)
-#define USB_STATUS_IRQHCIBUFFACC  (1 <<  8)
-#define USB_STATUS_NIRQHCIM       (1 <<  9)
-#define USB_STATUS_NHCIMFCLR      (1 << 10)
-#define USB_STATUS_USBPWRSENSE    (1 << 11)
-
 /*
  * Serial Audio Controller
  *
  *    PC_SSR           GPIO Block C Sleep State
  */
 
-#define _PA_DDR                _SA1111( 0x1000 )
-#define _PA_DRR                _SA1111( 0x1004 )
-#define _PA_DWR                _SA1111( 0x1004 )
-#define _PA_SDR                _SA1111( 0x1008 )
-#define _PA_SSR                _SA1111( 0x100c )
-#define _PB_DDR                _SA1111( 0x1010 )
-#define _PB_DRR                _SA1111( 0x1014 )
-#define _PB_DWR                _SA1111( 0x1014 )
-#define _PB_SDR                _SA1111( 0x1018 )
-#define _PB_SSR                _SA1111( 0x101c )
-#define _PC_DDR                _SA1111( 0x1020 )
-#define _PC_DRR                _SA1111( 0x1024 )
-#define _PC_DWR                _SA1111( 0x1024 )
-#define _PC_SDR                _SA1111( 0x1028 )
-#define _PC_SSR                _SA1111( 0x102c )
-
 #define SA1111_GPIO    0x1000
 
 #define SA1111_GPIO_PADDR      (0x000)
 #define SA1111_WAKEPOL0                0x0034
 #define SA1111_WAKEPOL1                0x0038
 
-/*
- * PS/2 Trackpad and Mouse Interfaces
- *
- * Registers
- *    PS2CR            Control Register
- *    PS2STAT          Status Register
- *    PS2DATA          Transmit/Receive Data register
- *    PS2CLKDIV                Clock Division Register
- *    PS2PRECNT                Clock Precount Register
- *    PS2TEST1         Test register 1
- *    PS2TEST2         Test register 2
- *    PS2TEST3         Test register 3
- *    PS2TEST4         Test register 4
- */
-
+/* PS/2 Trackpad and Mouse Interfaces */
 #define SA1111_KBD             0x0a00
 #define SA1111_MSE             0x0c00
 
-/*
- * These are offsets from the above bases.
- */
-#define SA1111_PS2CR           0x0000
-#define SA1111_PS2STAT         0x0004
-#define SA1111_PS2DATA         0x0008
-#define SA1111_PS2CLKDIV       0x000c
-#define SA1111_PS2PRECNT       0x0010
-
-#define PS2CR_ENA              0x08
-#define PS2CR_FKD              0x02
-#define PS2CR_FKC              0x01
-
-#define PS2STAT_STP            0x0100
-#define PS2STAT_TXE            0x0080
-#define PS2STAT_TXB            0x0040
-#define PS2STAT_RXF            0x0020
-#define PS2STAT_RXB            0x0010
-#define PS2STAT_ENA            0x0008
-#define PS2STAT_RXP            0x0004
-#define PS2STAT_KBD            0x0002
-#define PS2STAT_KBC            0x0001
+/* PCMCIA Interface */
+#define SA1111_PCMCIA          0x1600
 
-/*
- * PCMCIA Interface
- *
- * Registers
- *    PCSR     Status Register
- *    PCCR     Control Register
- *    PCSSR    Sleep State Register
- */
-
-#define SA1111_PCMCIA  0x1600
-
-/*
- * These are offsets from the above base.
- */
-#define SA1111_PCCR    0x0000
-#define SA1111_PCSSR   0x0004
-#define SA1111_PCSR    0x0008
-
-#define PCSR_S0_READY  (1<<0)
-#define PCSR_S1_READY  (1<<1)
-#define PCSR_S0_DETECT (1<<2)
-#define PCSR_S1_DETECT (1<<3)
-#define PCSR_S0_VS1    (1<<4)
-#define PCSR_S0_VS2    (1<<5)
-#define PCSR_S1_VS1    (1<<6)
-#define PCSR_S1_VS2    (1<<7)
-#define PCSR_S0_WP     (1<<8)
-#define PCSR_S1_WP     (1<<9)
-#define PCSR_S0_BVD1   (1<<10)
-#define PCSR_S0_BVD2   (1<<11)
-#define PCSR_S1_BVD1   (1<<12)
-#define PCSR_S1_BVD2   (1<<13)
-
-#define PCCR_S0_RST    (1<<0)
-#define PCCR_S1_RST    (1<<1)
-#define PCCR_S0_FLT    (1<<2)
-#define PCCR_S1_FLT    (1<<3)
-#define PCCR_S0_PWAITEN        (1<<4)
-#define PCCR_S1_PWAITEN        (1<<5)
-#define PCCR_S0_PSE    (1<<6)
-#define PCCR_S1_PSE    (1<<7)
-
-#define PCSSR_S0_SLEEP (1<<0)
-#define PCSSR_S1_SLEEP (1<<1)
 
 
 
 
 extern struct bus_type sa1111_bus_type;
 
-#define SA1111_DEVID_SBI       0
-#define SA1111_DEVID_SK                1
-#define SA1111_DEVID_USB       2
-#define SA1111_DEVID_SAC       3
-#define SA1111_DEVID_SSP       4
-#define SA1111_DEVID_PS2       5
-#define SA1111_DEVID_GPIO      6
-#define SA1111_DEVID_INT       7
-#define SA1111_DEVID_PCMCIA    8
+#define SA1111_DEVID_SBI       (1 << 0)
+#define SA1111_DEVID_SK                (1 << 1)
+#define SA1111_DEVID_USB       (1 << 2)
+#define SA1111_DEVID_SAC       (1 << 3)
+#define SA1111_DEVID_SSP       (1 << 4)
+#define SA1111_DEVID_PS2       (3 << 5)
+#define SA1111_DEVID_PS2_KBD   (1 << 5)
+#define SA1111_DEVID_PS2_MSE   (1 << 6)
+#define SA1111_DEVID_GPIO      (1 << 7)
+#define SA1111_DEVID_INT       (1 << 8)
+#define SA1111_DEVID_PCMCIA    (1 << 9)
 
 struct sa1111_dev {
        struct device   dev;
@@ -548,6 +432,7 @@ struct sa1111_driver {
        int (*remove)(struct sa1111_dev *);
        int (*suspend)(struct sa1111_dev *, pm_message_t);
        int (*resume)(struct sa1111_dev *);
+       void (*shutdown)(struct sa1111_dev *);
 };
 
 #define SA1111_DRV(_d) container_of((_d), struct sa1111_driver, drv)
@@ -555,9 +440,10 @@ struct sa1111_driver {
 #define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name)
 
 /*
- * These frob the SKPCR register.
+ * These frob the SKPCR register, and call platform specific
+ * enable/disable functions.
  */
-void sa1111_enable_device(struct sa1111_dev *);
+int sa1111_enable_device(struct sa1111_dev *);
 void sa1111_disable_device(struct sa1111_dev *);
 
 unsigned int sa1111_pll_clock(struct sa1111_dev *);
@@ -580,6 +466,10 @@ void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned i
 
 struct sa1111_platform_data {
        int     irq_base;       /* base for cascaded on-chip IRQs */
+       unsigned disable_devs;
+       void    *data;
+       int     (*enable)(void *, unsigned);
+       void    (*disable)(void *, unsigned);
 };
 
 #endif  /* _ASM_ARCH_SA1111 */
index 4384d81eee79d4f456589541d8ea957ca598d50a..2dd9d3f83f2963282ad5c593b94aebbc59df421a 100644 (file)
@@ -1,2 +1,15 @@
-void sp804_clocksource_init(void __iomem *, const char *);
+void __sp804_clocksource_and_sched_clock_init(void __iomem *,
+                                             const char *, int);
+
+static inline void sp804_clocksource_init(void __iomem *base, const char *name)
+{
+       __sp804_clocksource_and_sched_clock_init(base, name, 0);
+}
+
+static inline void sp804_clocksource_and_sched_clock_init(void __iomem *base,
+                                                         const char *name)
+{
+       __sp804_clocksource_and_sched_clock_init(base, name, 1);
+}
+
 void sp804_clockevents_init(void __iomem *, unsigned int, const char *);
index c6a18424888ed4992ed05913e77e262eb3126723..f77ffc1eb0c2b0d2e5a6125169da694b33bd2a0f 100644 (file)
 #define __ASM_ARM_LOCALTIMER_H
 
 #include <linux/errno.h>
-#include <linux/interrupt.h>
 
 struct clock_event_device;
 
-/*
- * Setup a per-cpu timer, whether it be a local timer or dummy broadcast
- */
-void percpu_timer_setup(void);
+struct local_timer_ops {
+       int  (*setup)(struct clock_event_device *);
+       void (*stop)(struct clock_event_device *);
+};
 
 #ifdef CONFIG_LOCAL_TIMERS
-
-#ifdef CONFIG_HAVE_ARM_TWD
-
-#include "smp_twd.h"
-
-#define local_timer_stop(c)    twd_timer_stop((c))
-
-#else
-
-/*
- * Stop the local timer
- */
-void local_timer_stop(struct clock_event_device *);
-
-#endif
-
 /*
- * Setup a local timer interrupt for a CPU.
+ * Register a local timer driver
  */
-int local_timer_setup(struct clock_event_device *);
-
+int local_timer_register(struct local_timer_ops *);
 #else
-
-static inline int local_timer_setup(struct clock_event_device *evt)
+static inline int local_timer_register(struct local_timer_ops *ops)
 {
        return -ENXIO;
 }
-
-static inline void local_timer_stop(struct clock_event_device *evt)
-{
-}
 #endif
 
 #endif
index ef9ffba97ad8d7633a830349d72da8b189e5bda8..0f01f4677bd27569df340029cabe9f602a1e0eeb 100644 (file)
 #define TWD_TIMER_CONTROL_PERIODIC     (1 << 1)
 #define TWD_TIMER_CONTROL_IT_ENABLE    (1 << 2)
 
-struct clock_event_device;
+#include <linux/ioport.h>
 
-extern void __iomem *twd_base;
+struct twd_local_timer {
+       struct resource res[2];
+};
 
-void twd_timer_setup(struct clock_event_device *);
-void twd_timer_stop(struct clock_event_device *);
+#define DEFINE_TWD_LOCAL_TIMER(name,base,irq)  \
+struct twd_local_timer name __initdata = {     \
+       .res    = {                             \
+               DEFINE_RES_MEM(base, 0x10),     \
+               DEFINE_RES_IRQ(irq),            \
+       },                                      \
+};
+
+int twd_local_timer_register(struct twd_local_timer *);
+
+#ifdef CONFIG_HAVE_ARM_TWD
+void twd_local_timer_of_register(void);
+#else
+static inline void twd_local_timer_of_register(void)
+{
+}
+#endif
 
 #endif
index 43b740d0e3744ab65b3c6036f342d734753b97de..3a274878412ec7b1728de840469cd1ffc68e3a38 100644 (file)
@@ -23,7 +23,6 @@ obj-$(CONFIG_LEDS)            += leds.o
 obj-$(CONFIG_OC_ETM)           += etm.o
 
 obj-$(CONFIG_ISA_DMA_API)      += dma.o
-obj-$(CONFIG_ARCH_ACORN)       += ecard.o 
 obj-$(CONFIG_FIQ)              += fiq.o fiqasm.o
 obj-$(CONFIG_MODULES)          += armksyms.o module.o
 obj-$(CONFIG_ARTHUR)           += arthur.o
@@ -62,9 +61,6 @@ obj-$(CONFIG_SWP_EMULATE)     += swp_emulate.o
 CFLAGS_swp_emulate.o           := -Wa,-march=armv7-a
 obj-$(CONFIG_HAVE_HW_BREAKPOINT)       += hw_breakpoint.o
 
-obj-$(CONFIG_CRUNCH)           += crunch.o crunch-bits.o
-AFLAGS_crunch-bits.o           := -Wa,-mcpu=ep9312
-
 obj-$(CONFIG_CPU_XSCALE)       += xscale-cp0.o
 obj-$(CONFIG_CPU_XSC3)         += xscale-cp0.o
 obj-$(CONFIG_CPU_MOHAWK)       += xscale-cp0.o
diff --git a/arch/arm/kernel/crunch-bits.S b/arch/arm/kernel/crunch-bits.S
deleted file mode 100644 (file)
index 0ec9bb4..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * arch/arm/kernel/crunch-bits.S
- * Cirrus MaverickCrunch context switching and handling
- *
- * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
- *
- * Shamelessly stolen from the iWMMXt code by Nicolas Pitre, which is
- * Copyright (c) 2003-2004, MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-#include <asm/thread_info.h>
-#include <asm/asm-offsets.h>
-#include <mach/ep93xx-regs.h>
-
-/*
- * We can't use hex constants here due to a bug in gas.
- */
-#define CRUNCH_MVDX0           0
-#define CRUNCH_MVDX1           8
-#define CRUNCH_MVDX2           16
-#define CRUNCH_MVDX3           24
-#define CRUNCH_MVDX4           32
-#define CRUNCH_MVDX5           40
-#define CRUNCH_MVDX6           48
-#define CRUNCH_MVDX7           56
-#define CRUNCH_MVDX8           64
-#define CRUNCH_MVDX9           72
-#define CRUNCH_MVDX10          80
-#define CRUNCH_MVDX11          88
-#define CRUNCH_MVDX12          96
-#define CRUNCH_MVDX13          104
-#define CRUNCH_MVDX14          112
-#define CRUNCH_MVDX15          120
-#define CRUNCH_MVAX0L          128
-#define CRUNCH_MVAX0M          132
-#define CRUNCH_MVAX0H          136
-#define CRUNCH_MVAX1L          140
-#define CRUNCH_MVAX1M          144
-#define CRUNCH_MVAX1H          148
-#define CRUNCH_MVAX2L          152
-#define CRUNCH_MVAX2M          156
-#define CRUNCH_MVAX2H          160
-#define CRUNCH_MVAX3L          164
-#define CRUNCH_MVAX3M          168
-#define CRUNCH_MVAX3H          172
-#define CRUNCH_DSPSC           176
-
-#define CRUNCH_SIZE            184
-
-       .text
-
-/*
- * Lazy switching of crunch coprocessor context
- *
- * r10 = struct thread_info pointer
- * r9  = ret_from_exception
- * lr  = undefined instr exit
- *
- * called from prefetch exception handler with interrupts disabled
- */
-ENTRY(crunch_task_enable)
-       ldr     r8, =(EP93XX_APB_VIRT_BASE + 0x00130000)        @ syscon addr
-
-       ldr     r1, [r8, #0x80]
-       tst     r1, #0x00800000                 @ access to crunch enabled?
-       movne   pc, lr                          @ if so no business here
-       mov     r3, #0xaa                       @ unlock syscon swlock
-       str     r3, [r8, #0xc0]
-       orr     r1, r1, #0x00800000             @ enable access to crunch
-       str     r1, [r8, #0x80]
-
-       ldr     r3, =crunch_owner
-       add     r0, r10, #TI_CRUNCH_STATE       @ get task crunch save area
-       ldr     r2, [sp, #60]                   @ current task pc value
-       ldr     r1, [r3]                        @ get current crunch owner
-       str     r0, [r3]                        @ this task now owns crunch
-       sub     r2, r2, #4                      @ adjust pc back
-       str     r2, [sp, #60]
-
-       ldr     r2, [r8, #0x80]
-       mov     r2, r2                          @ flush out enable (@@@)
-
-       teq     r1, #0                          @ test for last ownership
-       mov     lr, r9                          @ normal exit from exception
-       beq     crunch_load                     @ no owner, skip save
-
-crunch_save:
-       cfstr64         mvdx0, [r1, #CRUNCH_MVDX0]      @ save 64b registers
-       cfstr64         mvdx1, [r1, #CRUNCH_MVDX1]
-       cfstr64         mvdx2, [r1, #CRUNCH_MVDX2]
-       cfstr64         mvdx3, [r1, #CRUNCH_MVDX3]
-       cfstr64         mvdx4, [r1, #CRUNCH_MVDX4]
-       cfstr64         mvdx5, [r1, #CRUNCH_MVDX5]
-       cfstr64         mvdx6, [r1, #CRUNCH_MVDX6]
-       cfstr64         mvdx7, [r1, #CRUNCH_MVDX7]
-       cfstr64         mvdx8, [r1, #CRUNCH_MVDX8]
-       cfstr64         mvdx9, [r1, #CRUNCH_MVDX9]
-       cfstr64         mvdx10, [r1, #CRUNCH_MVDX10]
-       cfstr64         mvdx11, [r1, #CRUNCH_MVDX11]
-       cfstr64         mvdx12, [r1, #CRUNCH_MVDX12]
-       cfstr64         mvdx13, [r1, #CRUNCH_MVDX13]
-       cfstr64         mvdx14, [r1, #CRUNCH_MVDX14]
-       cfstr64         mvdx15, [r1, #CRUNCH_MVDX15]
-
-#ifdef __ARMEB__
-#error fix me for ARMEB
-#endif
-
-       cfmv32al        mvfx0, mvax0                    @ save 72b accumulators
-       cfstr32         mvfx0, [r1, #CRUNCH_MVAX0L]
-       cfmv32am        mvfx0, mvax0
-       cfstr32         mvfx0, [r1, #CRUNCH_MVAX0M]
-       cfmv32ah        mvfx0, mvax0
-       cfstr32         mvfx0, [r1, #CRUNCH_MVAX0H]
-       cfmv32al        mvfx0, mvax1
-       cfstr32         mvfx0, [r1, #CRUNCH_MVAX1L]
-       cfmv32am        mvfx0, mvax1
-       cfstr32         mvfx0, [r1, #CRUNCH_MVAX1M]
-       cfmv32ah        mvfx0, mvax1
-       cfstr32         mvfx0, [r1, #CRUNCH_MVAX1H]
-       cfmv32al        mvfx0, mvax2
-       cfstr32         mvfx0, [r1, #CRUNCH_MVAX2L]
-       cfmv32am        mvfx0, mvax2
-       cfstr32         mvfx0, [r1, #CRUNCH_MVAX2M]
-       cfmv32ah        mvfx0, mvax2
-       cfstr32         mvfx0, [r1, #CRUNCH_MVAX2H]
-       cfmv32al        mvfx0, mvax3
-       cfstr32         mvfx0, [r1, #CRUNCH_MVAX3L]
-       cfmv32am        mvfx0, mvax3
-       cfstr32         mvfx0, [r1, #CRUNCH_MVAX3M]
-       cfmv32ah        mvfx0, mvax3
-       cfstr32         mvfx0, [r1, #CRUNCH_MVAX3H]
-
-       cfmv32sc        mvdx0, dspsc                    @ save status word
-       cfstr64         mvdx0, [r1, #CRUNCH_DSPSC]
-
-       teq             r0, #0                          @ anything to load?
-       cfldr64eq       mvdx0, [r1, #CRUNCH_MVDX0]      @ mvdx0 was clobbered
-       moveq           pc, lr
-
-crunch_load:
-       cfldr64         mvdx0, [r0, #CRUNCH_DSPSC]      @ load status word
-       cfmvsc32        dspsc, mvdx0
-
-       cfldr32         mvfx0, [r0, #CRUNCH_MVAX0L]     @ load 72b accumulators
-       cfmval32        mvax0, mvfx0
-       cfldr32         mvfx0, [r0, #CRUNCH_MVAX0M]
-       cfmvam32        mvax0, mvfx0
-       cfldr32         mvfx0, [r0, #CRUNCH_MVAX0H]
-       cfmvah32        mvax0, mvfx0
-       cfldr32         mvfx0, [r0, #CRUNCH_MVAX1L]
-       cfmval32        mvax1, mvfx0
-       cfldr32         mvfx0, [r0, #CRUNCH_MVAX1M]
-       cfmvam32        mvax1, mvfx0
-       cfldr32         mvfx0, [r0, #CRUNCH_MVAX1H]
-       cfmvah32        mvax1, mvfx0
-       cfldr32         mvfx0, [r0, #CRUNCH_MVAX2L]
-       cfmval32        mvax2, mvfx0
-       cfldr32         mvfx0, [r0, #CRUNCH_MVAX2M]
-       cfmvam32        mvax2, mvfx0
-       cfldr32         mvfx0, [r0, #CRUNCH_MVAX2H]
-       cfmvah32        mvax2, mvfx0
-       cfldr32         mvfx0, [r0, #CRUNCH_MVAX3L]
-       cfmval32        mvax3, mvfx0
-       cfldr32         mvfx0, [r0, #CRUNCH_MVAX3M]
-       cfmvam32        mvax3, mvfx0
-       cfldr32         mvfx0, [r0, #CRUNCH_MVAX3H]
-       cfmvah32        mvax3, mvfx0
-
-       cfldr64         mvdx0, [r0, #CRUNCH_MVDX0]      @ load 64b registers
-       cfldr64         mvdx1, [r0, #CRUNCH_MVDX1]
-       cfldr64         mvdx2, [r0, #CRUNCH_MVDX2]
-       cfldr64         mvdx3, [r0, #CRUNCH_MVDX3]
-       cfldr64         mvdx4, [r0, #CRUNCH_MVDX4]
-       cfldr64         mvdx5, [r0, #CRUNCH_MVDX5]
-       cfldr64         mvdx6, [r0, #CRUNCH_MVDX6]
-       cfldr64         mvdx7, [r0, #CRUNCH_MVDX7]
-       cfldr64         mvdx8, [r0, #CRUNCH_MVDX8]
-       cfldr64         mvdx9, [r0, #CRUNCH_MVDX9]
-       cfldr64         mvdx10, [r0, #CRUNCH_MVDX10]
-       cfldr64         mvdx11, [r0, #CRUNCH_MVDX11]
-       cfldr64         mvdx12, [r0, #CRUNCH_MVDX12]
-       cfldr64         mvdx13, [r0, #CRUNCH_MVDX13]
-       cfldr64         mvdx14, [r0, #CRUNCH_MVDX14]
-       cfldr64         mvdx15, [r0, #CRUNCH_MVDX15]
-
-       mov     pc, lr
-
-/*
- * Back up crunch regs to save area and disable access to them
- * (mainly for gdb or sleep mode usage)
- *
- * r0 = struct thread_info pointer of target task or NULL for any
- */
-ENTRY(crunch_task_disable)
-       stmfd   sp!, {r4, r5, lr}
-
-       mrs     ip, cpsr
-       orr     r2, ip, #PSR_I_BIT              @ disable interrupts
-       msr     cpsr_c, r2
-
-       ldr     r4, =(EP93XX_APB_VIRT_BASE + 0x00130000)        @ syscon addr
-
-       ldr     r3, =crunch_owner
-       add     r2, r0, #TI_CRUNCH_STATE        @ get task crunch save area
-       ldr     r1, [r3]                        @ get current crunch owner
-       teq     r1, #0                          @ any current owner?
-       beq     1f                              @ no: quit
-       teq     r0, #0                          @ any owner?
-       teqne   r1, r2                          @ or specified one?
-       bne     1f                              @ no: quit
-
-       ldr     r5, [r4, #0x80]                 @ enable access to crunch
-       mov     r2, #0xaa
-       str     r2, [r4, #0xc0]
-       orr     r5, r5, #0x00800000
-       str     r5, [r4, #0x80]
-
-       mov     r0, #0                          @ nothing to load
-       str     r0, [r3]                        @ no more current owner
-       ldr     r2, [r4, #0x80]                 @ flush out enable (@@@)
-       mov     r2, r2
-       bl      crunch_save
-
-       mov     r2, #0xaa                       @ disable access to crunch
-       str     r2, [r4, #0xc0]
-       bic     r5, r5, #0x00800000
-       str     r5, [r4, #0x80]
-       ldr     r5, [r4, #0x80]                 @ flush out enable (@@@)
-       mov     r5, r5
-
-1:     msr     cpsr_c, ip                      @ restore interrupt mode
-       ldmfd   sp!, {r4, r5, pc}
-
-/*
- * Copy crunch state to given memory address
- *
- * r0 = struct thread_info pointer of target task
- * r1 = memory address where to store crunch state
- *
- * this is called mainly in the creation of signal stack frames
- */
-ENTRY(crunch_task_copy)
-       mrs     ip, cpsr
-       orr     r2, ip, #PSR_I_BIT              @ disable interrupts
-       msr     cpsr_c, r2
-
-       ldr     r3, =crunch_owner
-       add     r2, r0, #TI_CRUNCH_STATE        @ get task crunch save area
-       ldr     r3, [r3]                        @ get current crunch owner
-       teq     r2, r3                          @ does this task own it...
-       beq     1f
-
-       @ current crunch values are in the task save area
-       msr     cpsr_c, ip                      @ restore interrupt mode
-       mov     r0, r1
-       mov     r1, r2
-       mov     r2, #CRUNCH_SIZE
-       b       memcpy
-
-1:     @ this task owns crunch regs -- grab a copy from there
-       mov     r0, #0                          @ nothing to load
-       mov     r3, lr                          @ preserve return address
-       bl      crunch_save
-       msr     cpsr_c, ip                      @ restore interrupt mode
-       mov     pc, r3
-
-/*
- * Restore crunch state from given memory address
- *
- * r0 = struct thread_info pointer of target task
- * r1 = memory address where to get crunch state from
- *
- * this is used to restore crunch state when unwinding a signal stack frame
- */
-ENTRY(crunch_task_restore)
-       mrs     ip, cpsr
-       orr     r2, ip, #PSR_I_BIT              @ disable interrupts
-       msr     cpsr_c, r2
-
-       ldr     r3, =crunch_owner
-       add     r2, r0, #TI_CRUNCH_STATE        @ get task crunch save area
-       ldr     r3, [r3]                        @ get current crunch owner
-       teq     r2, r3                          @ does this task own it...
-       beq     1f
-
-       @ this task doesn't own crunch regs -- use its save area
-       msr     cpsr_c, ip                      @ restore interrupt mode
-       mov     r0, r2
-       mov     r2, #CRUNCH_SIZE
-       b       memcpy
-
-1:     @ this task owns crunch regs -- load them directly
-       mov     r0, r1
-       mov     r1, #0                          @ nothing to save
-       mov     r3, lr                          @ preserve return address
-       bl      crunch_load
-       msr     cpsr_c, ip                      @ restore interrupt mode
-       mov     pc, r3
diff --git a/arch/arm/kernel/crunch.c b/arch/arm/kernel/crunch.c
deleted file mode 100644 (file)
index 25ef223..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * arch/arm/kernel/crunch.c
- * Cirrus MaverickCrunch context switching and handling
- *
- * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <mach/ep93xx-regs.h>
-#include <asm/thread_notify.h>
-
-struct crunch_state *crunch_owner;
-
-void crunch_task_release(struct thread_info *thread)
-{
-       local_irq_disable();
-       if (crunch_owner == &thread->crunchstate)
-               crunch_owner = NULL;
-       local_irq_enable();
-}
-
-static int crunch_enabled(u32 devcfg)
-{
-       return !!(devcfg & EP93XX_SYSCON_DEVCFG_CPENA);
-}
-
-static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t)
-{
-       struct thread_info *thread = (struct thread_info *)t;
-       struct crunch_state *crunch_state;
-       u32 devcfg;
-
-       crunch_state = &thread->crunchstate;
-
-       switch (cmd) {
-       case THREAD_NOTIFY_FLUSH:
-               memset(crunch_state, 0, sizeof(*crunch_state));
-
-               /*
-                * FALLTHROUGH: Ensure we don't try to overwrite our newly
-                * initialised state information on the first fault.
-                */
-
-       case THREAD_NOTIFY_EXIT:
-               crunch_task_release(thread);
-               break;
-
-       case THREAD_NOTIFY_SWITCH:
-               devcfg = __raw_readl(EP93XX_SYSCON_DEVCFG);
-               if (crunch_enabled(devcfg) || crunch_owner == crunch_state) {
-                       /*
-                        * We don't use ep93xx_syscon_swlocked_write() here
-                        * because we are on the context switch path and
-                        * preemption is already disabled.
-                        */
-                       devcfg ^= EP93XX_SYSCON_DEVCFG_CPENA;
-                       __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
-                       __raw_writel(devcfg, EP93XX_SYSCON_DEVCFG);
-               }
-               break;
-       }
-
-       return NOTIFY_DONE;
-}
-
-static struct notifier_block crunch_notifier_block = {
-       .notifier_call  = crunch_do,
-};
-
-static int __init crunch_init(void)
-{
-       thread_register_notifier(&crunch_notifier_block);
-       elf_hwcap |= HWCAP_CRUNCH;
-
-       return 0;
-}
-
-late_initcall(crunch_init);
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
deleted file mode 100644 (file)
index 1651d49..0000000
+++ /dev/null
@@ -1,1232 +0,0 @@
-/*
- *  linux/arch/arm/kernel/ecard.c
- *
- *  Copyright 1995-2001 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  Find all installed expansion cards, and handle interrupts from them.
- *
- *  Created from information from Acorns RiscOS3 PRMs
- *
- *  08-Dec-1996        RMK     Added code for the 9'th expansion card - the ether
- *                     podule slot.
- *  06-May-1997        RMK     Added blacklist for cards whose loader doesn't work.
- *  12-Sep-1997        RMK     Created new handling of interrupt enables/disables
- *                     - cards can now register their own routine to control
- *                     interrupts (recommended).
- *  29-Sep-1997        RMK     Expansion card interrupt hardware not being re-enabled
- *                     on reset from Linux. (Caused cards not to respond
- *                     under RiscOS without hard reset).
- *  15-Feb-1998        RMK     Added DMA support
- *  12-Sep-1998        RMK     Added EASI support
- *  10-Jan-1999        RMK     Run loaders in a simulated RISC OS environment.
- *  17-Apr-1999        RMK     Support for EASI Type C cycles.
- */
-#define ECARD_C
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/completion.h>
-#include <linux/reboot.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/mutex.h>
-#include <linux/kthread.h>
-#include <linux/io.h>
-
-#include <asm/dma.h>
-#include <asm/ecard.h>
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mmu_context.h>
-#include <asm/mach/irq.h>
-#include <asm/tlbflush.h>
-
-#include "ecard.h"
-
-#ifndef CONFIG_ARCH_RPC
-#define HAVE_EXPMASK
-#endif
-
-struct ecard_request {
-       void            (*fn)(struct ecard_request *);
-       ecard_t         *ec;
-       unsigned int    address;
-       unsigned int    length;
-       unsigned int    use_loader;
-       void            *buffer;
-       struct completion *complete;
-};
-
-struct expcard_blacklist {
-       unsigned short   manufacturer;
-       unsigned short   product;
-       const char      *type;
-};
-
-static ecard_t *cards;
-static ecard_t *slot_to_expcard[MAX_ECARDS];
-static unsigned int ectcr;
-#ifdef HAS_EXPMASK
-static unsigned int have_expmask;
-#endif
-
-/* List of descriptions of cards which don't have an extended
- * identification, or chunk directories containing a description.
- */
-static struct expcard_blacklist __initdata blacklist[] = {
-       { MANU_ACORN, PROD_ACORN_ETHER1, "Acorn Ether1" }
-};
-
-asmlinkage extern int
-ecard_loader_reset(unsigned long base, loader_t loader);
-asmlinkage extern int
-ecard_loader_read(int off, unsigned long base, loader_t loader);
-
-static inline unsigned short ecard_getu16(unsigned char *v)
-{
-       return v[0] | v[1] << 8;
-}
-
-static inline signed long ecard_gets24(unsigned char *v)
-{
-       return v[0] | v[1] << 8 | v[2] << 16 | ((v[2] & 0x80) ? 0xff000000 : 0);
-}
-
-static inline ecard_t *slot_to_ecard(unsigned int slot)
-{
-       return slot < MAX_ECARDS ? slot_to_expcard[slot] : NULL;
-}
-
-/* ===================== Expansion card daemon ======================== */
-/*
- * Since the loader programs on the expansion cards need to be run
- * in a specific environment, create a separate task with this
- * environment up, and pass requests to this task as and when we
- * need to.
- *
- * This should allow 99% of loaders to be called from Linux.
- *
- * From a security standpoint, we trust the card vendors.  This
- * may be a misplaced trust.
- */
-static void ecard_task_reset(struct ecard_request *req)
-{
-       struct expansion_card *ec = req->ec;
-       struct resource *res;
-
-       res = ec->slot_no == 8
-               ? &ec->resource[ECARD_RES_MEMC]
-               : ec->easi
-                 ? &ec->resource[ECARD_RES_EASI]
-                 : &ec->resource[ECARD_RES_IOCSYNC];
-
-       ecard_loader_reset(res->start, ec->loader);
-}
-
-static void ecard_task_readbytes(struct ecard_request *req)
-{
-       struct expansion_card *ec = req->ec;
-       unsigned char *buf = req->buffer;
-       unsigned int len = req->length;
-       unsigned int off = req->address;
-
-       if (ec->slot_no == 8) {
-               void __iomem *base = (void __iomem *)
-                               ec->resource[ECARD_RES_MEMC].start;
-
-               /*
-                * The card maintains an index which increments the address
-                * into a 4096-byte page on each access.  We need to keep
-                * track of the counter.
-                */
-               static unsigned int index;
-               unsigned int page;
-
-               page = (off >> 12) * 4;
-               if (page > 256 * 4)
-                       return;
-
-               off &= 4095;
-
-               /*
-                * If we are reading offset 0, or our current index is
-                * greater than the offset, reset the hardware index counter.
-                */
-               if (off == 0 || index > off) {
-                       writeb(0, base);
-                       index = 0;
-               }
-
-               /*
-                * Increment the hardware index counter until we get to the
-                * required offset.  The read bytes are discarded.
-                */
-               while (index < off) {
-                       readb(base + page);
-                       index += 1;
-               }
-
-               while (len--) {
-                       *buf++ = readb(base + page);
-                       index += 1;
-               }
-       } else {
-               unsigned long base = (ec->easi
-                        ? &ec->resource[ECARD_RES_EASI]
-                        : &ec->resource[ECARD_RES_IOCSYNC])->start;
-               void __iomem *pbase = (void __iomem *)base;
-
-               if (!req->use_loader || !ec->loader) {
-                       off *= 4;
-                       while (len--) {
-                               *buf++ = readb(pbase + off);
-                               off += 4;
-                       }
-               } else {
-                       while(len--) {
-                               /*
-                                * The following is required by some
-                                * expansion card loader programs.
-                                */
-                               *(unsigned long *)0x108 = 0;
-                               *buf++ = ecard_loader_read(off++, base,
-                                                          ec->loader);
-                       }
-               }
-       }
-
-}
-
-static DECLARE_WAIT_QUEUE_HEAD(ecard_wait);
-static struct ecard_request *ecard_req;
-static DEFINE_MUTEX(ecard_mutex);
-
-/*
- * Set up the expansion card daemon's page tables.
- */
-static void ecard_init_pgtables(struct mm_struct *mm)
-{
-       struct vm_area_struct vma;
-
-       /* We want to set up the page tables for the following mapping:
-        *  Virtual     Physical
-        *  0x03000000  0x03000000
-        *  0x03010000  unmapped
-        *  0x03210000  0x03210000
-        *  0x03400000  unmapped
-        *  0x08000000  0x08000000
-        *  0x10000000  unmapped
-        *
-        * FIXME: we don't follow this 100% yet.
-        */
-       pgd_t *src_pgd, *dst_pgd;
-
-       src_pgd = pgd_offset(mm, (unsigned long)IO_BASE);
-       dst_pgd = pgd_offset(mm, IO_START);
-
-       memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (IO_SIZE / PGDIR_SIZE));
-
-       src_pgd = pgd_offset(mm, (unsigned long)EASI_BASE);
-       dst_pgd = pgd_offset(mm, EASI_START);
-
-       memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (EASI_SIZE / PGDIR_SIZE));
-
-       vma.vm_flags = VM_EXEC;
-       vma.vm_mm = mm;
-
-       flush_tlb_range(&vma, IO_START, IO_START + IO_SIZE);
-       flush_tlb_range(&vma, EASI_START, EASI_START + EASI_SIZE);
-}
-
-static int ecard_init_mm(void)
-{
-       struct mm_struct * mm = mm_alloc();
-       struct mm_struct *active_mm = current->active_mm;
-
-       if (!mm)
-               return -ENOMEM;
-
-       current->mm = mm;
-       current->active_mm = mm;
-       activate_mm(active_mm, mm);
-       mmdrop(active_mm);
-       ecard_init_pgtables(mm);
-       return 0;
-}
-
-static int
-ecard_task(void * unused)
-{
-       /*
-        * Allocate a mm.  We're not a lazy-TLB kernel task since we need
-        * to set page table entries where the user space would be.  Note
-        * that this also creates the page tables.  Failure is not an
-        * option here.
-        */
-       if (ecard_init_mm())
-               panic("kecardd: unable to alloc mm\n");
-
-       while (1) {
-               struct ecard_request *req;
-
-               wait_event_interruptible(ecard_wait, ecard_req != NULL);
-
-               req = xchg(&ecard_req, NULL);
-               if (req != NULL) {
-                       req->fn(req);
-                       complete(req->complete);
-               }
-       }
-}
-
-/*
- * Wake the expansion card daemon to action our request.
- *
- * FIXME: The test here is not sufficient to detect if the
- * kcardd is running.
- */
-static void ecard_call(struct ecard_request *req)
-{
-       DECLARE_COMPLETION_ONSTACK(completion);
-
-       req->complete = &completion;
-
-       mutex_lock(&ecard_mutex);
-       ecard_req = req;
-       wake_up(&ecard_wait);
-
-       /*
-        * Now wait for kecardd to run.
-        */
-       wait_for_completion(&completion);
-       mutex_unlock(&ecard_mutex);
-}
-
-/* ======================= Mid-level card control ===================== */
-
-static void
-ecard_readbytes(void *addr, ecard_t *ec, int off, int len, int useld)
-{
-       struct ecard_request req;
-
-       req.fn          = ecard_task_readbytes;
-       req.ec          = ec;
-       req.address     = off;
-       req.length      = len;
-       req.use_loader  = useld;
-       req.buffer      = addr;
-
-       ecard_call(&req);
-}
-
-int ecard_readchunk(struct in_chunk_dir *cd, ecard_t *ec, int id, int num)
-{
-       struct ex_chunk_dir excd;
-       int index = 16;
-       int useld = 0;
-
-       if (!ec->cid.cd)
-               return 0;
-
-       while(1) {
-               ecard_readbytes(&excd, ec, index, 8, useld);
-               index += 8;
-               if (c_id(&excd) == 0) {
-                       if (!useld && ec->loader) {
-                               useld = 1;
-                               index = 0;
-                               continue;
-                       }
-                       return 0;
-               }
-               if (c_id(&excd) == 0xf0) { /* link */
-                       index = c_start(&excd);
-                       continue;
-               }
-               if (c_id(&excd) == 0x80) { /* loader */
-                       if (!ec->loader) {
-                               ec->loader = kmalloc(c_len(&excd),
-                                                              GFP_KERNEL);
-                               if (ec->loader)
-                                       ecard_readbytes(ec->loader, ec,
-                                                       (int)c_start(&excd),
-                                                       c_len(&excd), useld);
-                               else
-                                       return 0;
-                       }
-                       continue;
-               }
-               if (c_id(&excd) == id && num-- == 0)
-                       break;
-       }
-
-       if (c_id(&excd) & 0x80) {
-               switch (c_id(&excd) & 0x70) {
-               case 0x70:
-                       ecard_readbytes((unsigned char *)excd.d.string, ec,
-                                       (int)c_start(&excd), c_len(&excd),
-                                       useld);
-                       break;
-               case 0x00:
-                       break;
-               }
-       }
-       cd->start_offset = c_start(&excd);
-       memcpy(cd->d.string, excd.d.string, 256);
-       return 1;
-}
-
-/* ======================= Interrupt control ============================ */
-
-static void ecard_def_irq_enable(ecard_t *ec, int irqnr)
-{
-#ifdef HAS_EXPMASK
-       if (irqnr < 4 && have_expmask) {
-               have_expmask |= 1 << irqnr;
-               __raw_writeb(have_expmask, EXPMASK_ENABLE);
-       }
-#endif
-}
-
-static void ecard_def_irq_disable(ecard_t *ec, int irqnr)
-{
-#ifdef HAS_EXPMASK
-       if (irqnr < 4 && have_expmask) {
-               have_expmask &= ~(1 << irqnr);
-               __raw_writeb(have_expmask, EXPMASK_ENABLE);
-       }
-#endif
-}
-
-static int ecard_def_irq_pending(ecard_t *ec)
-{
-       return !ec->irqmask || readb(ec->irqaddr) & ec->irqmask;
-}
-
-static void ecard_def_fiq_enable(ecard_t *ec, int fiqnr)
-{
-       panic("ecard_def_fiq_enable called - impossible");
-}
-
-static void ecard_def_fiq_disable(ecard_t *ec, int fiqnr)
-{
-       panic("ecard_def_fiq_disable called - impossible");
-}
-
-static int ecard_def_fiq_pending(ecard_t *ec)
-{
-       return !ec->fiqmask || readb(ec->fiqaddr) & ec->fiqmask;
-}
-
-static expansioncard_ops_t ecard_default_ops = {
-       ecard_def_irq_enable,
-       ecard_def_irq_disable,
-       ecard_def_irq_pending,
-       ecard_def_fiq_enable,
-       ecard_def_fiq_disable,
-       ecard_def_fiq_pending
-};
-
-/*
- * Enable and disable interrupts from expansion cards.
- * (interrupts are disabled for these functions).
- *
- * They are not meant to be called directly, but via enable/disable_irq.
- */
-static void ecard_irq_unmask(struct irq_data *d)
-{
-       ecard_t *ec = slot_to_ecard(d->irq - 32);
-
-       if (ec) {
-               if (!ec->ops)
-                       ec->ops = &ecard_default_ops;
-
-               if (ec->claimed && ec->ops->irqenable)
-                       ec->ops->irqenable(ec, d->irq);
-               else
-                       printk(KERN_ERR "ecard: rejecting request to "
-                               "enable IRQs for %d\n", d->irq);
-       }
-}
-
-static void ecard_irq_mask(struct irq_data *d)
-{
-       ecard_t *ec = slot_to_ecard(d->irq - 32);
-
-       if (ec) {
-               if (!ec->ops)
-                       ec->ops = &ecard_default_ops;
-
-               if (ec->ops && ec->ops->irqdisable)
-                       ec->ops->irqdisable(ec, d->irq);
-       }
-}
-
-static struct irq_chip ecard_chip = {
-       .name           = "ECARD",
-       .irq_ack        = ecard_irq_mask,
-       .irq_mask       = ecard_irq_mask,
-       .irq_unmask     = ecard_irq_unmask,
-};
-
-void ecard_enablefiq(unsigned int fiqnr)
-{
-       ecard_t *ec = slot_to_ecard(fiqnr);
-
-       if (ec) {
-               if (!ec->ops)
-                       ec->ops = &ecard_default_ops;
-
-               if (ec->claimed && ec->ops->fiqenable)
-                       ec->ops->fiqenable(ec, fiqnr);
-               else
-                       printk(KERN_ERR "ecard: rejecting request to "
-                               "enable FIQs for %d\n", fiqnr);
-       }
-}
-
-void ecard_disablefiq(unsigned int fiqnr)
-{
-       ecard_t *ec = slot_to_ecard(fiqnr);
-
-       if (ec) {
-               if (!ec->ops)
-                       ec->ops = &ecard_default_ops;
-
-               if (ec->ops->fiqdisable)
-                       ec->ops->fiqdisable(ec, fiqnr);
-       }
-}
-
-static void ecard_dump_irq_state(void)
-{
-       ecard_t *ec;
-
-       printk("Expansion card IRQ state:\n");
-
-       for (ec = cards; ec; ec = ec->next) {
-               if (ec->slot_no == 8)
-                       continue;
-
-               printk("  %d: %sclaimed, ",
-                      ec->slot_no, ec->claimed ? "" : "not ");
-
-               if (ec->ops && ec->ops->irqpending &&
-                   ec->ops != &ecard_default_ops)
-                       printk("irq %spending\n",
-                              ec->ops->irqpending(ec) ? "" : "not ");
-               else
-                       printk("irqaddr %p, mask = %02X, status = %02X\n",
-                              ec->irqaddr, ec->irqmask, readb(ec->irqaddr));
-       }
-}
-
-static void ecard_check_lockup(struct irq_desc *desc)
-{
-       static unsigned long last;
-       static int lockup;
-
-       /*
-        * If the timer interrupt has not run since the last million
-        * unrecognised expansion card interrupts, then there is
-        * something seriously wrong.  Disable the expansion card
-        * interrupts so at least we can continue.
-        *
-        * Maybe we ought to start a timer to re-enable them some time
-        * later?
-        */
-       if (last == jiffies) {
-               lockup += 1;
-               if (lockup > 1000000) {
-                       printk(KERN_ERR "\nInterrupt lockup detected - "
-                              "disabling all expansion card interrupts\n");
-
-                       desc->irq_data.chip->irq_mask(&desc->irq_data);
-                       ecard_dump_irq_state();
-               }
-       } else
-               lockup = 0;
-
-       /*
-        * If we did not recognise the source of this interrupt,
-        * warn the user, but don't flood the user with these messages.
-        */
-       if (!last || time_after(jiffies, last + 5*HZ)) {
-               last = jiffies;
-               printk(KERN_WARNING "Unrecognised interrupt from backplane\n");
-               ecard_dump_irq_state();
-       }
-}
-
-static void
-ecard_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
-       ecard_t *ec;
-       int called = 0;
-
-       desc->irq_data.chip->irq_mask(&desc->irq_data);
-       for (ec = cards; ec; ec = ec->next) {
-               int pending;
-
-               if (!ec->claimed || ec->irq == NO_IRQ || ec->slot_no == 8)
-                       continue;
-
-               if (ec->ops && ec->ops->irqpending)
-                       pending = ec->ops->irqpending(ec);
-               else
-                       pending = ecard_default_ops.irqpending(ec);
-
-               if (pending) {
-                       generic_handle_irq(ec->irq);
-                       called ++;
-               }
-       }
-       desc->irq_data.chip->irq_unmask(&desc->irq_data);
-
-       if (called == 0)
-               ecard_check_lockup(desc);
-}
-
-#ifdef HAS_EXPMASK
-static unsigned char priority_masks[] =
-{
-       0xf0, 0xf1, 0xf3, 0xf7, 0xff, 0xff, 0xff, 0xff
-};
-
-static unsigned char first_set[] =
-{
-       0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-       0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00
-};
-
-static void
-ecard_irqexp_handler(unsigned int irq, struct irq_desc *desc)
-{
-       const unsigned int statusmask = 15;
-       unsigned int status;
-
-       status = __raw_readb(EXPMASK_STATUS) & statusmask;
-       if (status) {
-               unsigned int slot = first_set[status];
-               ecard_t *ec = slot_to_ecard(slot);
-
-               if (ec->claimed) {
-                       /*
-                        * this ugly code is so that we can operate a
-                        * prioritorising system:
-                        *
-                        * Card 0       highest priority
-                        * Card 1
-                        * Card 2
-                        * Card 3       lowest priority
-                        *
-                        * Serial cards should go in 0/1, ethernet/scsi in 2/3
-                        * otherwise you will lose serial data at high speeds!
-                        */
-                       generic_handle_irq(ec->irq);
-               } else {
-                       printk(KERN_WARNING "card%d: interrupt from unclaimed "
-                              "card???\n", slot);
-                       have_expmask &= ~(1 << slot);
-                       __raw_writeb(have_expmask, EXPMASK_ENABLE);
-               }
-       } else
-               printk(KERN_WARNING "Wild interrupt from backplane (masks)\n");
-}
-
-static int __init ecard_probeirqhw(void)
-{
-       ecard_t *ec;
-       int found;
-
-       __raw_writeb(0x00, EXPMASK_ENABLE);
-       __raw_writeb(0xff, EXPMASK_STATUS);
-       found = (__raw_readb(EXPMASK_STATUS) & 15) == 0;
-       __raw_writeb(0xff, EXPMASK_ENABLE);
-
-       if (found) {
-               printk(KERN_DEBUG "Expansion card interrupt "
-                      "management hardware found\n");
-
-               /* for each card present, set a bit to '1' */
-               have_expmask = 0x80000000;
-
-               for (ec = cards; ec; ec = ec->next)
-                       have_expmask |= 1 << ec->slot_no;
-
-               __raw_writeb(have_expmask, EXPMASK_ENABLE);
-       }
-
-       return found;
-}
-#else
-#define ecard_irqexp_handler NULL
-#define ecard_probeirqhw() (0)
-#endif
-
-static void __iomem *__ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
-{
-       void __iomem *address = NULL;
-       int slot = ec->slot_no;
-
-       if (ec->slot_no == 8)
-               return ECARD_MEMC8_BASE;
-
-       ectcr &= ~(1 << slot);
-
-       switch (type) {
-       case ECARD_MEMC:
-               if (slot < 4)
-                       address = ECARD_MEMC_BASE + (slot << 14);
-               break;
-
-       case ECARD_IOC:
-               if (slot < 4)
-                       address = ECARD_IOC_BASE + (slot << 14);
-               else
-                       address = ECARD_IOC4_BASE + ((slot - 4) << 14);
-               if (address)
-                       address += speed << 19;
-               break;
-
-       case ECARD_EASI:
-               address = ECARD_EASI_BASE + (slot << 24);
-               if (speed == ECARD_FAST)
-                       ectcr |= 1 << slot;
-               break;
-
-       default:
-               break;
-       }
-
-#ifdef IOMD_ECTCR
-       iomd_writeb(ectcr, IOMD_ECTCR);
-#endif
-       return address;
-}
-
-static int ecard_prints(struct seq_file *m, ecard_t *ec)
-{
-       seq_printf(m, "  %d: %s ", ec->slot_no, ec->easi ? "EASI" : "    ");
-
-       if (ec->cid.id == 0) {
-               struct in_chunk_dir incd;
-
-               seq_printf(m, "[%04X:%04X] ",
-                       ec->cid.manufacturer, ec->cid.product);
-
-               if (!ec->card_desc && ec->cid.cd &&
-                   ecard_readchunk(&incd, ec, 0xf5, 0)) {
-                       ec->card_desc = kmalloc(strlen(incd.d.string)+1, GFP_KERNEL);
-
-                       if (ec->card_desc)
-                               strcpy((char *)ec->card_desc, incd.d.string);
-               }
-
-               seq_printf(m, "%s\n", ec->card_desc ? ec->card_desc : "*unknown*");
-       } else
-               seq_printf(m, "Simple card %d\n", ec->cid.id);
-
-       return 0;
-}
-
-static int ecard_devices_proc_show(struct seq_file *m, void *v)
-{
-       ecard_t *ec = cards;
-
-       while (ec) {
-               ecard_prints(m, ec);
-               ec = ec->next;
-       }
-       return 0;
-}
-
-static int ecard_devices_proc_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, ecard_devices_proc_show, NULL);
-}
-
-static const struct file_operations bus_ecard_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = ecard_devices_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
-static struct proc_dir_entry *proc_bus_ecard_dir = NULL;
-
-static void ecard_proc_init(void)
-{
-       proc_bus_ecard_dir = proc_mkdir("bus/ecard", NULL);
-       proc_create("devices", 0, proc_bus_ecard_dir, &bus_ecard_proc_fops);
-}
-
-#define ec_set_resource(ec,nr,st,sz)                           \
-       do {                                                    \
-               (ec)->resource[nr].name = dev_name(&ec->dev);   \
-               (ec)->resource[nr].start = st;                  \
-               (ec)->resource[nr].end = (st) + (sz) - 1;       \
-               (ec)->resource[nr].flags = IORESOURCE_MEM;      \
-       } while (0)
-
-static void __init ecard_free_card(struct expansion_card *ec)
-{
-       int i;
-
-       for (i = 0; i < ECARD_NUM_RESOURCES; i++)
-               if (ec->resource[i].flags)
-                       release_resource(&ec->resource[i]);
-
-       kfree(ec);
-}
-
-static struct expansion_card *__init ecard_alloc_card(int type, int slot)
-{
-       struct expansion_card *ec;
-       unsigned long base;
-       int i;
-
-       ec = kzalloc(sizeof(ecard_t), GFP_KERNEL);
-       if (!ec) {
-               ec = ERR_PTR(-ENOMEM);
-               goto nomem;
-       }
-
-       ec->slot_no = slot;
-       ec->easi = type == ECARD_EASI;
-       ec->irq = NO_IRQ;
-       ec->fiq = NO_IRQ;
-       ec->dma = NO_DMA;
-       ec->ops = &ecard_default_ops;
-
-       dev_set_name(&ec->dev, "ecard%d", slot);
-       ec->dev.parent = NULL;
-       ec->dev.bus = &ecard_bus_type;
-       ec->dev.dma_mask = &ec->dma_mask;
-       ec->dma_mask = (u64)0xffffffff;
-       ec->dev.coherent_dma_mask = ec->dma_mask;
-
-       if (slot < 4) {
-               ec_set_resource(ec, ECARD_RES_MEMC,
-                               PODSLOT_MEMC_BASE + (slot << 14),
-                               PODSLOT_MEMC_SIZE);
-               base = PODSLOT_IOC0_BASE + (slot << 14);
-       } else
-               base = PODSLOT_IOC4_BASE + ((slot - 4) << 14);
-
-#ifdef CONFIG_ARCH_RPC
-       if (slot < 8) {
-               ec_set_resource(ec, ECARD_RES_EASI,
-                               PODSLOT_EASI_BASE + (slot << 24),
-                               PODSLOT_EASI_SIZE);
-       }
-
-       if (slot == 8) {
-               ec_set_resource(ec, ECARD_RES_MEMC, NETSLOT_BASE, NETSLOT_SIZE);
-       } else
-#endif
-
-       for (i = 0; i <= ECARD_RES_IOCSYNC - ECARD_RES_IOCSLOW; i++)
-               ec_set_resource(ec, i + ECARD_RES_IOCSLOW,
-                               base + (i << 19), PODSLOT_IOC_SIZE);
-
-       for (i = 0; i < ECARD_NUM_RESOURCES; i++) {
-               if (ec->resource[i].flags &&
-                   request_resource(&iomem_resource, &ec->resource[i])) {
-                       dev_err(&ec->dev, "resource(s) not available\n");
-                       ec->resource[i].end -= ec->resource[i].start;
-                       ec->resource[i].start = 0;
-                       ec->resource[i].flags = 0;
-               }
-       }
-
- nomem:
-       return ec;
-}
-
-static ssize_t ecard_show_irq(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct expansion_card *ec = ECARD_DEV(dev);
-       return sprintf(buf, "%u\n", ec->irq);
-}
-
-static ssize_t ecard_show_dma(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct expansion_card *ec = ECARD_DEV(dev);
-       return sprintf(buf, "%u\n", ec->dma);
-}
-
-static ssize_t ecard_show_resources(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct expansion_card *ec = ECARD_DEV(dev);
-       char *str = buf;
-       int i;
-
-       for (i = 0; i < ECARD_NUM_RESOURCES; i++)
-               str += sprintf(str, "%08x %08x %08lx\n",
-                               ec->resource[i].start,
-                               ec->resource[i].end,
-                               ec->resource[i].flags);
-
-       return str - buf;
-}
-
-static ssize_t ecard_show_vendor(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct expansion_card *ec = ECARD_DEV(dev);
-       return sprintf(buf, "%u\n", ec->cid.manufacturer);
-}
-
-static ssize_t ecard_show_device(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct expansion_card *ec = ECARD_DEV(dev);
-       return sprintf(buf, "%u\n", ec->cid.product);
-}
-
-static ssize_t ecard_show_type(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct expansion_card *ec = ECARD_DEV(dev);
-       return sprintf(buf, "%s\n", ec->easi ? "EASI" : "IOC");
-}
-
-static struct device_attribute ecard_dev_attrs[] = {
-       __ATTR(device,   S_IRUGO, ecard_show_device,    NULL),
-       __ATTR(dma,      S_IRUGO, ecard_show_dma,       NULL),
-       __ATTR(irq,      S_IRUGO, ecard_show_irq,       NULL),
-       __ATTR(resource, S_IRUGO, ecard_show_resources, NULL),
-       __ATTR(type,     S_IRUGO, ecard_show_type,      NULL),
-       __ATTR(vendor,   S_IRUGO, ecard_show_vendor,    NULL),
-       __ATTR_NULL,
-};
-
-
-int ecard_request_resources(struct expansion_card *ec)
-{
-       int i, err = 0;
-
-       for (i = 0; i < ECARD_NUM_RESOURCES; i++) {
-               if (ecard_resource_end(ec, i) &&
-                   !request_mem_region(ecard_resource_start(ec, i),
-                                       ecard_resource_len(ec, i),
-                                       ec->dev.driver->name)) {
-                       err = -EBUSY;
-                       break;
-               }
-       }
-
-       if (err) {
-               while (i--)
-                       if (ecard_resource_end(ec, i))
-                               release_mem_region(ecard_resource_start(ec, i),
-                                                  ecard_resource_len(ec, i));
-       }
-       return err;
-}
-EXPORT_SYMBOL(ecard_request_resources);
-
-void ecard_release_resources(struct expansion_card *ec)
-{
-       int i;
-
-       for (i = 0; i < ECARD_NUM_RESOURCES; i++)
-               if (ecard_resource_end(ec, i))
-                       release_mem_region(ecard_resource_start(ec, i),
-                                          ecard_resource_len(ec, i));
-}
-EXPORT_SYMBOL(ecard_release_resources);
-
-void ecard_setirq(struct expansion_card *ec, const struct expansion_card_ops *ops, void *irq_data)
-{
-       ec->irq_data = irq_data;
-       barrier();
-       ec->ops = ops;
-}
-EXPORT_SYMBOL(ecard_setirq);
-
-void __iomem *ecardm_iomap(struct expansion_card *ec, unsigned int res,
-                          unsigned long offset, unsigned long maxsize)
-{
-       unsigned long start = ecard_resource_start(ec, res);
-       unsigned long end = ecard_resource_end(ec, res);
-
-       if (offset > (end - start))
-               return NULL;
-
-       start += offset;
-       if (maxsize && end - start > maxsize)
-               end = start + maxsize;
-       
-       return devm_ioremap(&ec->dev, start, end - start);
-}
-EXPORT_SYMBOL(ecardm_iomap);
-
-/*
- * Probe for an expansion card.
- *
- * If bit 1 of the first byte of the card is set, then the
- * card does not exist.
- */
-static int __init
-ecard_probe(int slot, card_type_t type)
-{
-       ecard_t **ecp;
-       ecard_t *ec;
-       struct ex_ecid cid;
-       void __iomem *addr;
-       int i, rc;
-
-       ec = ecard_alloc_card(type, slot);
-       if (IS_ERR(ec)) {
-               rc = PTR_ERR(ec);
-               goto nomem;
-       }
-
-       rc = -ENODEV;
-       if ((addr = __ecard_address(ec, type, ECARD_SYNC)) == NULL)
-               goto nodev;
-
-       cid.r_zero = 1;
-       ecard_readbytes(&cid, ec, 0, 16, 0);
-       if (cid.r_zero)
-               goto nodev;
-
-       ec->cid.id      = cid.r_id;
-       ec->cid.cd      = cid.r_cd;
-       ec->cid.is      = cid.r_is;
-       ec->cid.w       = cid.r_w;
-       ec->cid.manufacturer = ecard_getu16(cid.r_manu);
-       ec->cid.product = ecard_getu16(cid.r_prod);
-       ec->cid.country = cid.r_country;
-       ec->cid.irqmask = cid.r_irqmask;
-       ec->cid.irqoff  = ecard_gets24(cid.r_irqoff);
-       ec->cid.fiqmask = cid.r_fiqmask;
-       ec->cid.fiqoff  = ecard_gets24(cid.r_fiqoff);
-       ec->fiqaddr     =
-       ec->irqaddr     = addr;
-
-       if (ec->cid.is) {
-               ec->irqmask = ec->cid.irqmask;
-               ec->irqaddr += ec->cid.irqoff;
-               ec->fiqmask = ec->cid.fiqmask;
-               ec->fiqaddr += ec->cid.fiqoff;
-       } else {
-               ec->irqmask = 1;
-               ec->fiqmask = 4;
-       }
-
-       for (i = 0; i < ARRAY_SIZE(blacklist); i++)
-               if (blacklist[i].manufacturer == ec->cid.manufacturer &&
-                   blacklist[i].product == ec->cid.product) {
-                       ec->card_desc = blacklist[i].type;
-                       break;
-               }
-
-       /*
-        * hook the interrupt handlers
-        */
-       if (slot < 8) {
-               ec->irq = 32 + slot;
-               irq_set_chip_and_handler(ec->irq, &ecard_chip,
-                                        handle_level_irq);
-               set_irq_flags(ec->irq, IRQF_VALID);
-       }
-
-       if (slot == 8)
-               ec->irq = 11;
-#ifdef CONFIG_ARCH_RPC
-       /* On RiscPC, only first two slots have DMA capability */
-       if (slot < 2)
-               ec->dma = 2 + slot;
-#endif
-
-       for (ecp = &cards; *ecp; ecp = &(*ecp)->next);
-
-       *ecp = ec;
-       slot_to_expcard[slot] = ec;
-
-       device_register(&ec->dev);
-
-       return 0;
-
- nodev:
-       ecard_free_card(ec);
- nomem:
-       return rc;
-}
-
-/*
- * Initialise the expansion card system.
- * Locate all hardware - interrupt management and
- * actual cards.
- */
-static int __init ecard_init(void)
-{
-       struct task_struct *task;
-       int slot, irqhw;
-
-       task = kthread_run(ecard_task, NULL, "kecardd");
-       if (IS_ERR(task)) {
-               printk(KERN_ERR "Ecard: unable to create kernel thread: %ld\n",
-                      PTR_ERR(task));
-               return PTR_ERR(task);
-       }
-
-       printk("Probing expansion cards\n");
-
-       for (slot = 0; slot < 8; slot ++) {
-               if (ecard_probe(slot, ECARD_EASI) == -ENODEV)
-                       ecard_probe(slot, ECARD_IOC);
-       }
-
-       ecard_probe(8, ECARD_IOC);
-
-       irqhw = ecard_probeirqhw();
-
-       irq_set_chained_handler(IRQ_EXPANSIONCARD,
-                               irqhw ? ecard_irqexp_handler : ecard_irq_handler);
-
-       ecard_proc_init();
-
-       return 0;
-}
-
-subsys_initcall(ecard_init);
-
-/*
- *     ECARD "bus"
- */
-static const struct ecard_id *
-ecard_match_device(const struct ecard_id *ids, struct expansion_card *ec)
-{
-       int i;
-
-       for (i = 0; ids[i].manufacturer != 65535; i++)
-               if (ec->cid.manufacturer == ids[i].manufacturer &&
-                   ec->cid.product == ids[i].product)
-                       return ids + i;
-
-       return NULL;
-}
-
-static int ecard_drv_probe(struct device *dev)
-{
-       struct expansion_card *ec = ECARD_DEV(dev);
-       struct ecard_driver *drv = ECARD_DRV(dev->driver);
-       const struct ecard_id *id;
-       int ret;
-
-       id = ecard_match_device(drv->id_table, ec);
-
-       ec->claimed = 1;
-       ret = drv->probe(ec, id);
-       if (ret)
-               ec->claimed = 0;
-       return ret;
-}
-
-static int ecard_drv_remove(struct device *dev)
-{
-       struct expansion_card *ec = ECARD_DEV(dev);
-       struct ecard_driver *drv = ECARD_DRV(dev->driver);
-
-       drv->remove(ec);
-       ec->claimed = 0;
-
-       /*
-        * Restore the default operations.  We ensure that the
-        * ops are set before we change the data.
-        */
-       ec->ops = &ecard_default_ops;
-       barrier();
-       ec->irq_data = NULL;
-
-       return 0;
-}
-
-/*
- * Before rebooting, we must make sure that the expansion card is in a
- * sensible state, so it can be re-detected.  This means that the first
- * page of the ROM must be visible.  We call the expansion cards reset
- * handler, if any.
- */
-static void ecard_drv_shutdown(struct device *dev)
-{
-       struct expansion_card *ec = ECARD_DEV(dev);
-       struct ecard_driver *drv = ECARD_DRV(dev->driver);
-       struct ecard_request req;
-
-       if (dev->driver) {
-               if (drv->shutdown)
-                       drv->shutdown(ec);
-               ec->claimed = 0;
-       }
-
-       /*
-        * If this card has a loader, call the reset handler.
-        */
-       if (ec->loader) {
-               req.fn = ecard_task_reset;
-               req.ec = ec;
-               ecard_call(&req);
-       }
-}
-
-int ecard_register_driver(struct ecard_driver *drv)
-{
-       drv->drv.bus = &ecard_bus_type;
-
-       return driver_register(&drv->drv);
-}
-
-void ecard_remove_driver(struct ecard_driver *drv)
-{
-       driver_unregister(&drv->drv);
-}
-
-static int ecard_match(struct device *_dev, struct device_driver *_drv)
-{
-       struct expansion_card *ec = ECARD_DEV(_dev);
-       struct ecard_driver *drv = ECARD_DRV(_drv);
-       int ret;
-
-       if (drv->id_table) {
-               ret = ecard_match_device(drv->id_table, ec) != NULL;
-       } else {
-               ret = ec->cid.id == drv->id;
-       }
-
-       return ret;
-}
-
-struct bus_type ecard_bus_type = {
-       .name           = "ecard",
-       .dev_attrs      = ecard_dev_attrs,
-       .match          = ecard_match,
-       .probe          = ecard_drv_probe,
-       .remove         = ecard_drv_remove,
-       .shutdown       = ecard_drv_shutdown,
-};
-
-static int ecard_bus_init(void)
-{
-       return bus_register(&ecard_bus_type);
-}
-
-postcore_initcall(ecard_bus_init);
-
-EXPORT_SYMBOL(ecard_readchunk);
-EXPORT_SYMBOL(ecard_register_driver);
-EXPORT_SYMBOL(ecard_remove_driver);
-EXPORT_SYMBOL(ecard_bus_type);
diff --git a/arch/arm/kernel/ecard.h b/arch/arm/kernel/ecard.h
deleted file mode 100644 (file)
index 4642d43..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- *  ecard.h
- *
- *  Copyright 2007 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-/* Definitions internal to ecard.c - for it's use only!!
- *
- * External expansion card header as read from the card
- */
-struct ex_ecid {
-       unsigned char   r_irq:1;
-       unsigned char   r_zero:1;
-       unsigned char   r_fiq:1;
-       unsigned char   r_id:4;
-       unsigned char   r_a:1;
-
-       unsigned char   r_cd:1;
-       unsigned char   r_is:1;
-       unsigned char   r_w:2;
-       unsigned char   r_r1:4;
-
-       unsigned char   r_r2:8;
-
-       unsigned char   r_prod[2];
-
-       unsigned char   r_manu[2];
-
-       unsigned char   r_country;
-
-       unsigned char   r_fiqmask;
-       unsigned char   r_fiqoff[3];
-
-       unsigned char   r_irqmask;
-       unsigned char   r_irqoff[3];
-};
-
-/*
- * Chunk directory entry as read from the card
- */
-struct ex_chunk_dir {
-       unsigned char r_id;
-       unsigned char r_len[3];
-       unsigned long r_start;
-       union {
-               char string[256];
-               char data[1];
-       } d;
-#define c_id(x)                ((x)->r_id)
-#define c_len(x)       ((x)->r_len[0]|((x)->r_len[1]<<8)|((x)->r_len[2]<<16))
-#define c_start(x)     ((x)->r_start)
-};
-
-typedef enum ecard_type {              /* Cards address space          */
-       ECARD_IOC,
-       ECARD_MEMC,
-       ECARD_EASI
-} card_type_t;
-
-typedef enum {                         /* Speed for ECARD_IOC space    */
-       ECARD_SLOW       = 0,
-       ECARD_MEDIUM     = 1,
-       ECARD_FAST       = 2,
-       ECARD_SYNC       = 3
-} card_speed_t;
index d616ed51e7a7d5d0fff29711925502ff6a37afcb..8f8cce2c46c42d8a10427b77014abb5008a2530c 100644 (file)
@@ -246,6 +246,8 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
        store_cpu_topology(cpuid);
 }
 
+static void percpu_timer_setup(void);
+
 /*
  * This is the secondary CPU boot entry.  We're using this CPUs
  * idle thread stack, but a set of temporary page tables.
@@ -452,7 +454,20 @@ static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt)
        clockevents_register_device(evt);
 }
 
-void __cpuinit percpu_timer_setup(void)
+static struct local_timer_ops *lt_ops;
+
+#ifdef CONFIG_LOCAL_TIMERS
+int local_timer_register(struct local_timer_ops *ops)
+{
+       if (lt_ops)
+               return -EBUSY;
+
+       lt_ops = ops;
+       return 0;
+}
+#endif
+
+static void __cpuinit percpu_timer_setup(void)
 {
        unsigned int cpu = smp_processor_id();
        struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
@@ -460,7 +475,7 @@ void __cpuinit percpu_timer_setup(void)
        evt->cpumask = cpumask_of(cpu);
        evt->broadcast = smp_timer_broadcast;
 
-       if (local_timer_setup(evt))
+       if (!lt_ops || lt_ops->setup(evt))
                broadcast_timer_setup(evt);
 }
 
@@ -475,7 +490,8 @@ static void percpu_timer_stop(void)
        unsigned int cpu = smp_processor_id();
        struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
 
-       local_timer_stop(evt);
+       if (lt_ops)
+               lt_ops->stop(evt);
 }
 #endif
 
index 7a79b24597b2d51953826338e13656803fe9c229..fef42b21cecba517e67e8ed74ef8c88d3cfd2afd 100644 (file)
 #include <linux/smp.h>
 #include <linux/jiffies.h>
 #include <linux/clockchips.h>
-#include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
 
 #include <asm/smp_twd.h>
 #include <asm/localtimer.h>
 #include <asm/hardware/gic.h>
 
 /* set up by the platform code */
-void __iomem *twd_base;
+static void __iomem *twd_base;
 
 static struct clk *twd_clk;
 static unsigned long twd_timer_rate;
 
 static struct clock_event_device __percpu **twd_evt;
+static int twd_ppi;
 
 static void twd_set_mode(enum clock_event_mode mode,
                        struct clock_event_device *clk)
@@ -77,7 +80,7 @@ static int twd_set_next_event(unsigned long evt,
  * If a local timer interrupt has occurred, acknowledge and return 1.
  * Otherwise, return 0.
  */
-int twd_timer_ack(void)
+static int twd_timer_ack(void)
 {
        if (__raw_readl(twd_base + TWD_TIMER_INTSTAT)) {
                __raw_writel(1, twd_base + TWD_TIMER_INTSTAT);
@@ -87,7 +90,7 @@ int twd_timer_ack(void)
        return 0;
 }
 
-void twd_timer_stop(struct clock_event_device *clk)
+static void twd_timer_stop(struct clock_event_device *clk)
 {
        twd_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
        disable_percpu_irq(clk->irq);
@@ -222,28 +225,10 @@ static struct clk *twd_get_clock(void)
 /*
  * Setup the local clock events for a CPU.
  */
-void __cpuinit twd_timer_setup(struct clock_event_device *clk)
+static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
 {
        struct clock_event_device **this_cpu_clk;
 
-       if (!twd_evt) {
-               int err;
-
-               twd_evt = alloc_percpu(struct clock_event_device *);
-               if (!twd_evt) {
-                       pr_err("twd: can't allocate memory\n");
-                       return;
-               }
-
-               err = request_percpu_irq(clk->irq, twd_handler,
-                                        "twd", twd_evt);
-               if (err) {
-                       pr_err("twd: can't register interrupt %d (%d)\n",
-                              clk->irq, err);
-                       return;
-               }
-       }
-
        if (!twd_clk)
                twd_clk = twd_get_clock();
 
@@ -260,6 +245,7 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
        clk->rating = 350;
        clk->set_mode = twd_set_mode;
        clk->set_next_event = twd_set_next_event;
+       clk->irq = twd_ppi;
 
        this_cpu_clk = __this_cpu_ptr(twd_evt);
        *this_cpu_clk = clk;
@@ -267,4 +253,95 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
        clockevents_config_and_register(clk, twd_timer_rate,
                                        0xf, 0xffffffff);
        enable_percpu_irq(clk->irq, 0);
+
+       return 0;
+}
+
+static struct local_timer_ops twd_lt_ops __cpuinitdata = {
+       .setup  = twd_timer_setup,
+       .stop   = twd_timer_stop,
+};
+
+static int __init twd_local_timer_common_register(void)
+{
+       int err;
+
+       twd_evt = alloc_percpu(struct clock_event_device *);
+       if (!twd_evt) {
+               err = -ENOMEM;
+               goto out_free;
+       }
+
+       err = request_percpu_irq(twd_ppi, twd_handler, "twd", twd_evt);
+       if (err) {
+               pr_err("twd: can't register interrupt %d (%d)\n", twd_ppi, err);
+               goto out_free;
+       }
+
+       err = local_timer_register(&twd_lt_ops);
+       if (err)
+               goto out_irq;
+
+       return 0;
+
+out_irq:
+       free_percpu_irq(twd_ppi, twd_evt);
+out_free:
+       iounmap(twd_base);
+       twd_base = NULL;
+       free_percpu(twd_evt);
+
+       return err;
 }
+
+int __init twd_local_timer_register(struct twd_local_timer *tlt)
+{
+       if (twd_base || twd_evt)
+               return -EBUSY;
+
+       twd_ppi = tlt->res[1].start;
+
+       twd_base = ioremap(tlt->res[0].start, resource_size(&tlt->res[0]));
+       if (!twd_base)
+               return -ENOMEM;
+
+       return twd_local_timer_common_register();
+}
+
+#ifdef CONFIG_OF
+const static struct of_device_id twd_of_match[] __initconst = {
+       { .compatible = "arm,cortex-a9-twd-timer",      },
+       { .compatible = "arm,cortex-a5-twd-timer",      },
+       { .compatible = "arm,arm11mp-twd-timer",        },
+       { },
+};
+
+void __init twd_local_timer_of_register(void)
+{
+       struct device_node *np;
+       int err;
+
+       np = of_find_matching_node(NULL, twd_of_match);
+       if (!np) {
+               err = -ENODEV;
+               goto out;
+       }
+
+       twd_ppi = irq_of_parse_and_map(np, 0);
+       if (!twd_ppi) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       twd_base = of_iomap(np, 0);
+       if (!twd_base) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       err = twd_local_timer_common_register();
+
+out:
+       WARN(err, "twd_local_timer_of_register failed (%d)\n", err);
+}
+#endif
index 71feb00a1e995de0991b54189569b04c1cf02f06..45db05d8d94c017fbd57586c80d306fff495affe 100644 (file)
@@ -20,9 +20,11 @@ config HAVE_AT91_USART5
 
 config AT91_SAM9_ALT_RESET
        bool
+       default !ARCH_AT91X40
 
 config AT91_SAM9G45_RESET
        bool
+       default !ARCH_AT91X40
 
 menu "Atmel AT91 System-on-Chip"
 
@@ -45,7 +47,6 @@ config ARCH_AT91SAM9260
        select HAVE_AT91_USART4
        select HAVE_AT91_USART5
        select HAVE_NET_MACB
-       select AT91_SAM9_ALT_RESET
 
 config ARCH_AT91SAM9261
        bool "AT91SAM9261"
@@ -53,7 +54,6 @@ config ARCH_AT91SAM9261
        select GENERIC_CLOCKEVENTS
        select HAVE_FB_ATMEL
        select HAVE_AT91_DBGU0
-       select AT91_SAM9_ALT_RESET
 
 config ARCH_AT91SAM9G10
        bool "AT91SAM9G10"
@@ -61,7 +61,6 @@ config ARCH_AT91SAM9G10
        select GENERIC_CLOCKEVENTS
        select HAVE_AT91_DBGU0
        select HAVE_FB_ATMEL
-       select AT91_SAM9_ALT_RESET
 
 config ARCH_AT91SAM9263
        bool "AT91SAM9263"
@@ -70,7 +69,6 @@ config ARCH_AT91SAM9263
        select HAVE_FB_ATMEL
        select HAVE_NET_MACB
        select HAVE_AT91_DBGU1
-       select AT91_SAM9_ALT_RESET
 
 config ARCH_AT91SAM9RL
        bool "AT91SAM9RL"
@@ -79,7 +77,6 @@ config ARCH_AT91SAM9RL
        select HAVE_AT91_USART3
        select HAVE_FB_ATMEL
        select HAVE_AT91_DBGU0
-       select AT91_SAM9_ALT_RESET
 
 config ARCH_AT91SAM9G20
        bool "AT91SAM9G20"
@@ -90,7 +87,6 @@ config ARCH_AT91SAM9G20
        select HAVE_AT91_USART4
        select HAVE_AT91_USART5
        select HAVE_NET_MACB
-       select AT91_SAM9_ALT_RESET
 
 config ARCH_AT91SAM9G45
        bool "AT91SAM9G45"
@@ -100,16 +96,14 @@ config ARCH_AT91SAM9G45
        select HAVE_FB_ATMEL
        select HAVE_NET_MACB
        select HAVE_AT91_DBGU1
-       select AT91_SAM9G45_RESET
 
-config ARCH_AT91CAP9
-       bool "AT91CAP9"
+config ARCH_AT91SAM9X5
+       bool "AT91SAM9x5 family"
        select CPU_ARM926T
        select GENERIC_CLOCKEVENTS
        select HAVE_FB_ATMEL
        select HAVE_NET_MACB
-       select HAVE_AT91_DBGU1
-       select AT91_SAM9G45_RESET
+       select HAVE_AT91_DBGU0
 
 config ARCH_AT91X40
        bool "AT91x40"
@@ -447,21 +441,6 @@ endif
 
 # ----------------------------------------------------------
 
-if ARCH_AT91CAP9
-
-comment "AT91CAP9 Board Type"
-
-config MACH_AT91CAP9ADK
-       bool "Atmel AT91CAP9A-DK Evaluation Kit"
-       select HAVE_AT91_DATAFLASH_CARD
-       help
-         Select this if you are using Atmel's AT91CAP9A-DK Evaluation Kit.
-         <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4138>
-
-endif
-
-# ----------------------------------------------------------
-
 if ARCH_AT91X40
 
 comment "AT91X40 Board Type"
@@ -544,7 +523,7 @@ config AT91_EARLY_DBGU0
        depends on HAVE_AT91_DBGU0
 
 config AT91_EARLY_DBGU1
-       bool "DBGU on 9263, 9g45 and cap9"
+       bool "DBGU on 9263 and 9g45"
        depends on HAVE_AT91_DBGU1
 
 config AT91_EARLY_USART0
index 705e1fbded3919112efb5858ec921d49e05d1eaa..8512e53bed9356afb310849b7f976f895c6076d1 100644 (file)
@@ -20,7 +20,7 @@ obj-$(CONFIG_ARCH_AT91SAM9263)        += at91sam9263.o at91sam926x_time.o at91sam9263_d
 obj-$(CONFIG_ARCH_AT91SAM9RL)  += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
-obj-$(CONFIG_ARCH_AT91CAP9)    += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9X5)  += at91sam9x5.o at91sam926x_time.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91X40)     += at91x40.o at91x40_time.o
 
 # AT91RM9200 board-specific support
@@ -81,9 +81,6 @@ obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o
 # AT91SAM board with device-tree
 obj-$(CONFIG_MACH_AT91SAM_DT) += board-dt.o
 
-# AT91CAP9 board-specific support
-obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o
-
 # AT91X40 board-specific support
 obj-$(CONFIG_MACH_AT91EB01)    += board-eb01.o
 
index 8ddafadfdc7dc94ac5f8319c5f56dc15fe798e8f..0da66ca4a4f83329dfd290b9582abb2b396153db 100644 (file)
@@ -3,11 +3,7 @@
 #   PARAMS_PHYS must be within 4MB of ZRELADDR
 #   INITRD_PHYS must be in RAM
 
-ifeq ($(CONFIG_ARCH_AT91CAP9),y)
-   zreladdr-y  += 0x70008000
-params_phys-y  := 0x70000100
-initrd_phys-y  := 0x70410000
-else ifeq ($(CONFIG_ARCH_AT91SAM9G45),y)
+ifeq ($(CONFIG_ARCH_AT91SAM9G45),y)
    zreladdr-y  += 0x70008000
 params_phys-y  := 0x70000100
 initrd_phys-y  := 0x70410000
@@ -17,4 +13,10 @@ params_phys-y        := 0x20000100
 initrd_phys-y  := 0x20410000
 endif
 
-dtb-$(CONFIG_MACH_AT91SAM_DT) += at91sam9m10g45ek.dtb usb_a9g20.dtb
+# Keep dtb files sorted alphabetically for each SoC
+# sam9g20
+dtb-$(CONFIG_MACH_AT91SAM_DT) += usb_a9g20.dtb
+# sam9g45
+dtb-$(CONFIG_MACH_AT91SAM_DT) += at91sam9m10g45ek.dtb
+# sam9x5
+dtb-$(CONFIG_MACH_AT91SAM_DT) += at91sam9g25ek.dtb
diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c
deleted file mode 100644 (file)
index 8967d75..0000000
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * arch/arm/mach-at91/at91cap9.c
- *
- *  Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
- *  Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
- *  Copyright (C) 2007 Atmel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <linux/module.h>
-
-#include <asm/proc-fns.h>
-#include <asm/irq.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/cpu.h>
-#include <mach/at91cap9.h>
-#include <mach/at91_pmc.h>
-
-#include "soc.h"
-#include "generic.h"
-#include "clock.h"
-#include "sam9_smc.h"
-
-/* --------------------------------------------------------------------
- *  Clocks
- * -------------------------------------------------------------------- */
-
-/*
- * The peripheral clocks.
- */
-static struct clk pioABCD_clk = {
-       .name           = "pioABCD_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_PIOABCD,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk mpb0_clk = {
-       .name           = "mpb0_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_MPB0,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk mpb1_clk = {
-       .name           = "mpb1_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_MPB1,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk mpb2_clk = {
-       .name           = "mpb2_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_MPB2,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk mpb3_clk = {
-       .name           = "mpb3_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_MPB3,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk mpb4_clk = {
-       .name           = "mpb4_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_MPB4,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk usart0_clk = {
-       .name           = "usart0_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_US0,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk usart1_clk = {
-       .name           = "usart1_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_US1,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk usart2_clk = {
-       .name           = "usart2_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_US2,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk mmc0_clk = {
-       .name           = "mci0_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_MCI0,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk mmc1_clk = {
-       .name           = "mci1_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_MCI1,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk can_clk = {
-       .name           = "can_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_CAN,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk twi_clk = {
-       .name           = "twi_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_TWI,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk spi0_clk = {
-       .name           = "spi0_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_SPI0,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk spi1_clk = {
-       .name           = "spi1_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_SPI1,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk ssc0_clk = {
-       .name           = "ssc0_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_SSC0,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk ssc1_clk = {
-       .name           = "ssc1_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_SSC1,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk ac97_clk = {
-       .name           = "ac97_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_AC97C,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk tcb_clk = {
-       .name           = "tcb_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_TCB,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk pwm_clk = {
-       .name           = "pwm_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_PWMC,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk macb_clk = {
-       .name           = "pclk",
-       .pmc_mask       = 1 << AT91CAP9_ID_EMAC,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk aestdes_clk = {
-       .name           = "aestdes_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_AESTDES,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk adc_clk = {
-       .name           = "adc_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_ADC,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk isi_clk = {
-       .name           = "isi_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_ISI,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk lcdc_clk = {
-       .name           = "lcdc_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_LCDC,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk dma_clk = {
-       .name           = "dma_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_DMA,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk udphs_clk = {
-       .name           = "udphs_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_UDPHS,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-static struct clk ohci_clk = {
-       .name           = "ohci_clk",
-       .pmc_mask       = 1 << AT91CAP9_ID_UHP,
-       .type           = CLK_TYPE_PERIPHERAL,
-};
-
-static struct clk *periph_clocks[] __initdata = {
-       &pioABCD_clk,
-       &mpb0_clk,
-       &mpb1_clk,
-       &mpb2_clk,
-       &mpb3_clk,
-       &mpb4_clk,
-       &usart0_clk,
-       &usart1_clk,
-       &usart2_clk,
-       &mmc0_clk,
-       &mmc1_clk,
-       &can_clk,
-       &twi_clk,
-       &spi0_clk,
-       &spi1_clk,
-       &ssc0_clk,
-       &ssc1_clk,
-       &ac97_clk,
-       &tcb_clk,
-       &pwm_clk,
-       &macb_clk,
-       &aestdes_clk,
-       &adc_clk,
-       &isi_clk,
-       &lcdc_clk,
-       &dma_clk,
-       &udphs_clk,
-       &ohci_clk,
-       // irq0 .. irq1
-};
-
-static struct clk_lookup periph_clocks_lookups[] = {
-       /* One additional fake clock for macb_hclk */
-       CLKDEV_CON_ID("hclk", &macb_clk),
-       CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk),
-       CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk),
-       CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk),
-       CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.1", &mmc1_clk),
-       CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
-       CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
-       CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk),
-       CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
-       CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
-       /* fake hclk clock */
-       CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
-       CLKDEV_CON_ID("pioA", &pioABCD_clk),
-       CLKDEV_CON_ID("pioB", &pioABCD_clk),
-       CLKDEV_CON_ID("pioC", &pioABCD_clk),
-       CLKDEV_CON_ID("pioD", &pioABCD_clk),
-};
-
-static struct clk_lookup usart_clocks_lookups[] = {
-       CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
-       CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
-       CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
-       CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
-};
-
-/*
- * The four programmable clocks.
- * You must configure pin multiplexing to bring these signals out.
- */
-static struct clk pck0 = {
-       .name           = "pck0",
-       .pmc_mask       = AT91_PMC_PCK0,
-       .type           = CLK_TYPE_PROGRAMMABLE,
-       .id             = 0,
-};
-static struct clk pck1 = {
-       .name           = "pck1",
-       .pmc_mask       = AT91_PMC_PCK1,
-       .type           = CLK_TYPE_PROGRAMMABLE,
-       .id             = 1,
-};
-static struct clk pck2 = {
-       .name           = "pck2",
-       .pmc_mask       = AT91_PMC_PCK2,
-       .type           = CLK_TYPE_PROGRAMMABLE,
-       .id             = 2,
-};
-static struct clk pck3 = {
-       .name           = "pck3",
-       .pmc_mask       = AT91_PMC_PCK3,
-       .type           = CLK_TYPE_PROGRAMMABLE,
-       .id             = 3,
-};
-
-static void __init at91cap9_register_clocks(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
-               clk_register(periph_clocks[i]);
-
-       clkdev_add_table(periph_clocks_lookups,
-                        ARRAY_SIZE(periph_clocks_lookups));
-       clkdev_add_table(usart_clocks_lookups,
-                        ARRAY_SIZE(usart_clocks_lookups));
-
-       clk_register(&pck0);
-       clk_register(&pck1);
-       clk_register(&pck2);
-       clk_register(&pck3);
-}
-
-static struct clk_lookup console_clock_lookup;
-
-void __init at91cap9_set_console_clock(int id)
-{
-       if (id >= ARRAY_SIZE(usart_clocks_lookups))
-               return;
-
-       console_clock_lookup.con_id = "usart";
-       console_clock_lookup.clk = usart_clocks_lookups[id].clk;
-       clkdev_add(&console_clock_lookup);
-}
-
-/* --------------------------------------------------------------------
- *  GPIO
- * -------------------------------------------------------------------- */
-
-static struct at91_gpio_bank at91cap9_gpio[] __initdata = {
-       {
-               .id             = AT91CAP9_ID_PIOABCD,
-               .regbase        = AT91CAP9_BASE_PIOA,
-       }, {
-               .id             = AT91CAP9_ID_PIOABCD,
-               .regbase        = AT91CAP9_BASE_PIOB,
-       }, {
-               .id             = AT91CAP9_ID_PIOABCD,
-               .regbase        = AT91CAP9_BASE_PIOC,
-       }, {
-               .id             = AT91CAP9_ID_PIOABCD,
-               .regbase        = AT91CAP9_BASE_PIOD,
-       }
-};
-
-static void at91cap9_idle(void)
-{
-       at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
-       cpu_do_idle();
-}
-
-/* --------------------------------------------------------------------
- *  AT91CAP9 processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init at91cap9_map_io(void)
-{
-       at91_init_sram(0, AT91CAP9_SRAM_BASE, AT91CAP9_SRAM_SIZE);
-}
-
-static void __init at91cap9_ioremap_registers(void)
-{
-       at91_ioremap_shdwc(AT91CAP9_BASE_SHDWC);
-       at91_ioremap_rstc(AT91CAP9_BASE_RSTC);
-       at91sam926x_ioremap_pit(AT91CAP9_BASE_PIT);
-       at91sam9_ioremap_smc(0, AT91CAP9_BASE_SMC);
-}
-
-static void __init at91cap9_initialize(void)
-{
-       arm_pm_idle = at91cap9_idle;
-       arm_pm_restart = at91sam9g45_restart;
-       at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1);
-
-       /* Register GPIO subsystem */
-       at91_gpio_init(at91cap9_gpio, 4);
-
-       /* Remember the silicon revision */
-       if (cpu_is_at91cap9_revB())
-               system_rev = 0xB;
-       else if (cpu_is_at91cap9_revC())
-               system_rev = 0xC;
-}
-
-/* --------------------------------------------------------------------
- *  Interrupt initialization
- * -------------------------------------------------------------------- */
-
-/*
- * The default interrupt priority levels (0 = lowest, 7 = highest).
- */
-static unsigned int at91cap9_default_irq_priority[NR_AIC_IRQS] __initdata = {
-       7,      /* Advanced Interrupt Controller (FIQ) */
-       7,      /* System Peripherals */
-       1,      /* Parallel IO Controller A, B, C and D */
-       0,      /* MP Block Peripheral 0 */
-       0,      /* MP Block Peripheral 1 */
-       0,      /* MP Block Peripheral 2 */
-       0,      /* MP Block Peripheral 3 */
-       0,      /* MP Block Peripheral 4 */
-       5,      /* USART 0 */
-       5,      /* USART 1 */
-       5,      /* USART 2 */
-       0,      /* Multimedia Card Interface 0 */
-       0,      /* Multimedia Card Interface 1 */
-       3,      /* CAN */
-       6,      /* Two-Wire Interface */
-       5,      /* Serial Peripheral Interface 0 */
-       5,      /* Serial Peripheral Interface 1 */
-       4,      /* Serial Synchronous Controller 0 */
-       4,      /* Serial Synchronous Controller 1 */
-       5,      /* AC97 Controller */
-       0,      /* Timer Counter 0, 1 and 2 */
-       0,      /* Pulse Width Modulation Controller */
-       3,      /* Ethernet */
-       0,      /* Advanced Encryption Standard, Triple DES*/
-       0,      /* Analog-to-Digital Converter */
-       0,      /* Image Sensor Interface */
-       3,      /* LCD Controller */
-       0,      /* DMA Controller */
-       2,      /* USB Device Port */
-       2,      /* USB Host port */
-       0,      /* Advanced Interrupt Controller (IRQ0) */
-       0,      /* Advanced Interrupt Controller (IRQ1) */
-};
-
-struct at91_init_soc __initdata at91cap9_soc = {
-       .map_io = at91cap9_map_io,
-       .default_irq_priority = at91cap9_default_irq_priority,
-       .ioremap_registers = at91cap9_ioremap_registers,
-       .register_clocks = at91cap9_register_clocks,
-       .init = at91cap9_initialize,
-};
diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c
deleted file mode 100644 (file)
index d298fb7..0000000
+++ /dev/null
@@ -1,1273 +0,0 @@
-/*
- * arch/arm/mach-at91/at91cap9_devices.c
- *
- *  Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
- *  Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
- *  Copyright (C) 2007 Atmel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-#include <linux/platform_device.h>
-#include <linux/i2c-gpio.h>
-
-#include <video/atmel_lcdc.h>
-
-#include <mach/board.h>
-#include <mach/cpu.h>
-#include <mach/at91cap9.h>
-#include <mach/at91cap9_matrix.h>
-#include <mach/at91sam9_smc.h>
-
-#include "generic.h"
-
-
-/* --------------------------------------------------------------------
- *  USB Host
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-static u64 ohci_dmamask = DMA_BIT_MASK(32);
-static struct at91_usbh_data usbh_data;
-
-static struct resource usbh_resources[] = {
-       [0] = {
-               .start  = AT91CAP9_UHP_BASE,
-               .end    = AT91CAP9_UHP_BASE + SZ_1M - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91CAP9_ID_UHP,
-               .end    = AT91CAP9_ID_UHP,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device at91_usbh_device = {
-       .name           = "at91_ohci",
-       .id             = -1,
-       .dev            = {
-                               .dma_mask               = &ohci_dmamask,
-                               .coherent_dma_mask      = DMA_BIT_MASK(32),
-                               .platform_data          = &usbh_data,
-       },
-       .resource       = usbh_resources,
-       .num_resources  = ARRAY_SIZE(usbh_resources),
-};
-
-void __init at91_add_device_usbh(struct at91_usbh_data *data)
-{
-       int i;
-
-       if (!data)
-               return;
-
-       if (cpu_is_at91cap9_revB())
-               irq_set_irq_type(AT91CAP9_ID_UHP, IRQ_TYPE_LEVEL_HIGH);
-
-       /* Enable VBus control for UHP ports */
-       for (i = 0; i < data->ports; i++) {
-               if (gpio_is_valid(data->vbus_pin[i]))
-                       at91_set_gpio_output(data->vbus_pin[i], 0);
-       }
-
-       /* Enable overcurrent notification */
-       for (i = 0; i < data->ports; i++) {
-               if (data->overcurrent_pin[i])
-                       at91_set_gpio_input(data->overcurrent_pin[i], 1);
-       }
-
-       usbh_data = *data;
-       platform_device_register(&at91_usbh_device);
-}
-#else
-void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  USB HS Device (Gadget)
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_USB_ATMEL_USBA) || defined(CONFIG_USB_ATMEL_USBA_MODULE)
-
-static struct resource usba_udc_resources[] = {
-       [0] = {
-               .start  = AT91CAP9_UDPHS_FIFO,
-               .end    = AT91CAP9_UDPHS_FIFO + SZ_512K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91CAP9_BASE_UDPHS,
-               .end    = AT91CAP9_BASE_UDPHS + SZ_1K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [2] = {
-               .start  = AT91CAP9_ID_UDPHS,
-               .end    = AT91CAP9_ID_UDPHS,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-#define EP(nam, idx, maxpkt, maxbk, dma, isoc)                 \
-       [idx] = {                                               \
-               .name           = nam,                          \
-               .index          = idx,                          \
-               .fifo_size      = maxpkt,                       \
-               .nr_banks       = maxbk,                        \
-               .can_dma        = dma,                          \
-               .can_isoc       = isoc,                         \
-       }
-
-static struct usba_ep_data usba_udc_ep[] = {
-       EP("ep0", 0,   64, 1, 0, 0),
-       EP("ep1", 1, 1024, 3, 1, 1),
-       EP("ep2", 2, 1024, 3, 1, 1),
-       EP("ep3", 3, 1024, 2, 1, 1),
-       EP("ep4", 4, 1024, 2, 1, 1),
-       EP("ep5", 5, 1024, 2, 1, 0),
-       EP("ep6", 6, 1024, 2, 1, 0),
-       EP("ep7", 7, 1024, 2, 0, 0),
-};
-
-#undef EP
-
-/*
- * pdata doesn't have room for any endpoints, so we need to
- * append room for the ones we need right after it.
- */
-static struct {
-       struct usba_platform_data pdata;
-       struct usba_ep_data ep[8];
-} usba_udc_data;
-
-static struct platform_device at91_usba_udc_device = {
-       .name           = "atmel_usba_udc",
-       .id             = -1,
-       .dev            = {
-                               .platform_data  = &usba_udc_data.pdata,
-       },
-       .resource       = usba_udc_resources,
-       .num_resources  = ARRAY_SIZE(usba_udc_resources),
-};
-
-void __init at91_add_device_usba(struct usba_platform_data *data)
-{
-       if (cpu_is_at91cap9_revB()) {
-               irq_set_irq_type(AT91CAP9_ID_UDPHS, IRQ_TYPE_LEVEL_HIGH);
-               at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS |
-                                                 AT91_MATRIX_UDPHS_BYPASS_LOCK);
-       }
-       else
-               at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS);
-
-       /*
-        * Invalid pins are 0 on AT91, but the usba driver is shared
-        * with AVR32, which use negative values instead. Once/if
-        * gpio_is_valid() is ported to AT91, revisit this code.
-        */
-       usba_udc_data.pdata.vbus_pin = -EINVAL;
-       usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
-       memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));
-
-       if (data && gpio_is_valid(data->vbus_pin)) {
-               at91_set_gpio_input(data->vbus_pin, 0);
-               at91_set_deglitch(data->vbus_pin, 1);
-               usba_udc_data.pdata.vbus_pin = data->vbus_pin;
-       }
-
-       /* Pullup pin is handled internally by USB device peripheral */
-
-       platform_device_register(&at91_usba_udc_device);
-}
-#else
-void __init at91_add_device_usba(struct usba_platform_data *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  Ethernet
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
-static u64 eth_dmamask = DMA_BIT_MASK(32);
-static struct macb_platform_data eth_data;
-
-static struct resource eth_resources[] = {
-       [0] = {
-               .start  = AT91CAP9_BASE_EMAC,
-               .end    = AT91CAP9_BASE_EMAC + SZ_16K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91CAP9_ID_EMAC,
-               .end    = AT91CAP9_ID_EMAC,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device at91cap9_eth_device = {
-       .name           = "macb",
-       .id             = -1,
-       .dev            = {
-                               .dma_mask               = &eth_dmamask,
-                               .coherent_dma_mask      = DMA_BIT_MASK(32),
-                               .platform_data          = &eth_data,
-       },
-       .resource       = eth_resources,
-       .num_resources  = ARRAY_SIZE(eth_resources),
-};
-
-void __init at91_add_device_eth(struct macb_platform_data *data)
-{
-       if (!data)
-               return;
-
-       if (gpio_is_valid(data->phy_irq_pin)) {
-               at91_set_gpio_input(data->phy_irq_pin, 0);
-               at91_set_deglitch(data->phy_irq_pin, 1);
-       }
-
-       /* Pins used for MII and RMII */
-       at91_set_A_periph(AT91_PIN_PB21, 0);    /* ETXCK_EREFCK */
-       at91_set_A_periph(AT91_PIN_PB22, 0);    /* ERXDV */
-       at91_set_A_periph(AT91_PIN_PB25, 0);    /* ERX0 */
-       at91_set_A_periph(AT91_PIN_PB26, 0);    /* ERX1 */
-       at91_set_A_periph(AT91_PIN_PB27, 0);    /* ERXER */
-       at91_set_A_periph(AT91_PIN_PB28, 0);    /* ETXEN */
-       at91_set_A_periph(AT91_PIN_PB23, 0);    /* ETX0 */
-       at91_set_A_periph(AT91_PIN_PB24, 0);    /* ETX1 */
-       at91_set_A_periph(AT91_PIN_PB30, 0);    /* EMDIO */
-       at91_set_A_periph(AT91_PIN_PB29, 0);    /* EMDC */
-
-       if (!data->is_rmii) {
-               at91_set_B_periph(AT91_PIN_PC25, 0);    /* ECRS */
-               at91_set_B_periph(AT91_PIN_PC26, 0);    /* ECOL */
-               at91_set_B_periph(AT91_PIN_PC22, 0);    /* ERX2 */
-               at91_set_B_periph(AT91_PIN_PC23, 0);    /* ERX3 */
-               at91_set_B_periph(AT91_PIN_PC27, 0);    /* ERXCK */
-               at91_set_B_periph(AT91_PIN_PC20, 0);    /* ETX2 */
-               at91_set_B_periph(AT91_PIN_PC21, 0);    /* ETX3 */
-               at91_set_B_periph(AT91_PIN_PC24, 0);    /* ETXER */
-       }
-
-       eth_data = *data;
-       platform_device_register(&at91cap9_eth_device);
-}
-#else
-void __init at91_add_device_eth(struct macb_platform_data *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  MMC / SD
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
-static u64 mmc_dmamask = DMA_BIT_MASK(32);
-static struct at91_mmc_data mmc0_data, mmc1_data;
-
-static struct resource mmc0_resources[] = {
-       [0] = {
-               .start  = AT91CAP9_BASE_MCI0,
-               .end    = AT91CAP9_BASE_MCI0 + SZ_16K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91CAP9_ID_MCI0,
-               .end    = AT91CAP9_ID_MCI0,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device at91cap9_mmc0_device = {
-       .name           = "at91_mci",
-       .id             = 0,
-       .dev            = {
-                               .dma_mask               = &mmc_dmamask,
-                               .coherent_dma_mask      = DMA_BIT_MASK(32),
-                               .platform_data          = &mmc0_data,
-       },
-       .resource       = mmc0_resources,
-       .num_resources  = ARRAY_SIZE(mmc0_resources),
-};
-
-static struct resource mmc1_resources[] = {
-       [0] = {
-               .start  = AT91CAP9_BASE_MCI1,
-               .end    = AT91CAP9_BASE_MCI1 + SZ_16K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91CAP9_ID_MCI1,
-               .end    = AT91CAP9_ID_MCI1,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device at91cap9_mmc1_device = {
-       .name           = "at91_mci",
-       .id             = 1,
-       .dev            = {
-                               .dma_mask               = &mmc_dmamask,
-                               .coherent_dma_mask      = DMA_BIT_MASK(32),
-                               .platform_data          = &mmc1_data,
-       },
-       .resource       = mmc1_resources,
-       .num_resources  = ARRAY_SIZE(mmc1_resources),
-};
-
-void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
-{
-       if (!data)
-               return;
-
-       /* input/irq */
-       if (gpio_is_valid(data->det_pin)) {
-               at91_set_gpio_input(data->det_pin, 1);
-               at91_set_deglitch(data->det_pin, 1);
-       }
-       if (gpio_is_valid(data->wp_pin))
-               at91_set_gpio_input(data->wp_pin, 1);
-       if (gpio_is_valid(data->vcc_pin))
-               at91_set_gpio_output(data->vcc_pin, 0);
-
-       if (mmc_id == 0) {              /* MCI0 */
-               /* CLK */
-               at91_set_A_periph(AT91_PIN_PA2, 0);
-
-               /* CMD */
-               at91_set_A_periph(AT91_PIN_PA1, 1);
-
-               /* DAT0, maybe DAT1..DAT3 */
-               at91_set_A_periph(AT91_PIN_PA0, 1);
-               if (data->wire4) {
-                       at91_set_A_periph(AT91_PIN_PA3, 1);
-                       at91_set_A_periph(AT91_PIN_PA4, 1);
-                       at91_set_A_periph(AT91_PIN_PA5, 1);
-               }
-
-               mmc0_data = *data;
-               platform_device_register(&at91cap9_mmc0_device);
-       } else {                        /* MCI1 */
-               /* CLK */
-               at91_set_A_periph(AT91_PIN_PA16, 0);
-
-               /* CMD */
-               at91_set_A_periph(AT91_PIN_PA17, 1);
-
-               /* DAT0, maybe DAT1..DAT3 */
-               at91_set_A_periph(AT91_PIN_PA18, 1);
-               if (data->wire4) {
-                       at91_set_A_periph(AT91_PIN_PA19, 1);
-                       at91_set_A_periph(AT91_PIN_PA20, 1);
-                       at91_set_A_periph(AT91_PIN_PA21, 1);
-               }
-
-               mmc1_data = *data;
-               platform_device_register(&at91cap9_mmc1_device);
-       }
-}
-#else
-void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  NAND / SmartMedia
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
-static struct atmel_nand_data nand_data;
-
-#define NAND_BASE      AT91_CHIPSELECT_3
-
-static struct resource nand_resources[] = {
-       [0] = {
-               .start  = NAND_BASE,
-               .end    = NAND_BASE + SZ_256M - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91CAP9_BASE_ECC,
-               .end    = AT91CAP9_BASE_ECC + SZ_512 - 1,
-               .flags  = IORESOURCE_MEM,
-       }
-};
-
-static struct platform_device at91cap9_nand_device = {
-       .name           = "atmel_nand",
-       .id             = -1,
-       .dev            = {
-                               .platform_data  = &nand_data,
-       },
-       .resource       = nand_resources,
-       .num_resources  = ARRAY_SIZE(nand_resources),
-};
-
-void __init at91_add_device_nand(struct atmel_nand_data *data)
-{
-       unsigned long csa;
-
-       if (!data)
-               return;
-
-       csa = at91_sys_read(AT91_MATRIX_EBICSA);
-       at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
-
-       /* enable pin */
-       if (gpio_is_valid(data->enable_pin))
-               at91_set_gpio_output(data->enable_pin, 1);
-
-       /* ready/busy pin */
-       if (gpio_is_valid(data->rdy_pin))
-               at91_set_gpio_input(data->rdy_pin, 1);
-
-       /* card detect pin */
-       if (gpio_is_valid(data->det_pin))
-               at91_set_gpio_input(data->det_pin, 1);
-
-       nand_data = *data;
-       platform_device_register(&at91cap9_nand_device);
-}
-#else
-void __init at91_add_device_nand(struct atmel_nand_data *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  TWI (i2c)
- * -------------------------------------------------------------------- */
-
-/*
- * Prefer the GPIO code since the TWI controller isn't robust
- * (gets overruns and underruns under load) and can only issue
- * repeated STARTs in one scenario (the driver doesn't yet handle them).
- */
-#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
-
-static struct i2c_gpio_platform_data pdata = {
-       .sda_pin                = AT91_PIN_PB4,
-       .sda_is_open_drain      = 1,
-       .scl_pin                = AT91_PIN_PB5,
-       .scl_is_open_drain      = 1,
-       .udelay                 = 2,            /* ~100 kHz */
-};
-
-static struct platform_device at91cap9_twi_device = {
-       .name                   = "i2c-gpio",
-       .id                     = -1,
-       .dev.platform_data      = &pdata,
-};
-
-void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
-{
-       at91_set_GPIO_periph(AT91_PIN_PB4, 1);          /* TWD (SDA) */
-       at91_set_multi_drive(AT91_PIN_PB4, 1);
-
-       at91_set_GPIO_periph(AT91_PIN_PB5, 1);          /* TWCK (SCL) */
-       at91_set_multi_drive(AT91_PIN_PB5, 1);
-
-       i2c_register_board_info(0, devices, nr_devices);
-       platform_device_register(&at91cap9_twi_device);
-}
-
-#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
-
-static struct resource twi_resources[] = {
-       [0] = {
-               .start  = AT91CAP9_BASE_TWI,
-               .end    = AT91CAP9_BASE_TWI + SZ_16K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91CAP9_ID_TWI,
-               .end    = AT91CAP9_ID_TWI,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device at91cap9_twi_device = {
-       .name           = "at91_i2c",
-       .id             = -1,
-       .resource       = twi_resources,
-       .num_resources  = ARRAY_SIZE(twi_resources),
-};
-
-void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
-{
-       /* pins used for TWI interface */
-       at91_set_B_periph(AT91_PIN_PB4, 0);             /* TWD */
-       at91_set_multi_drive(AT91_PIN_PB4, 1);
-
-       at91_set_B_periph(AT91_PIN_PB5, 0);             /* TWCK */
-       at91_set_multi_drive(AT91_PIN_PB5, 1);
-
-       i2c_register_board_info(0, devices, nr_devices);
-       platform_device_register(&at91cap9_twi_device);
-}
-#else
-void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
-#endif
-
-/* --------------------------------------------------------------------
- *  SPI
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
-static u64 spi_dmamask = DMA_BIT_MASK(32);
-
-static struct resource spi0_resources[] = {
-       [0] = {
-               .start  = AT91CAP9_BASE_SPI0,
-               .end    = AT91CAP9_BASE_SPI0 + SZ_16K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91CAP9_ID_SPI0,
-               .end    = AT91CAP9_ID_SPI0,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device at91cap9_spi0_device = {
-       .name           = "atmel_spi",
-       .id             = 0,
-       .dev            = {
-                               .dma_mask               = &spi_dmamask,
-                               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       },
-       .resource       = spi0_resources,
-       .num_resources  = ARRAY_SIZE(spi0_resources),
-};
-
-static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PD0, AT91_PIN_PD1 };
-
-static struct resource spi1_resources[] = {
-       [0] = {
-               .start  = AT91CAP9_BASE_SPI1,
-               .end    = AT91CAP9_BASE_SPI1 + SZ_16K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91CAP9_ID_SPI1,
-               .end    = AT91CAP9_ID_SPI1,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device at91cap9_spi1_device = {
-       .name           = "atmel_spi",
-       .id             = 1,
-       .dev            = {
-                               .dma_mask               = &spi_dmamask,
-                               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       },
-       .resource       = spi1_resources,
-       .num_resources  = ARRAY_SIZE(spi1_resources),
-};
-
-static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 };
-
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
-{
-       int i;
-       unsigned long cs_pin;
-       short enable_spi0 = 0;
-       short enable_spi1 = 0;
-
-       /* Choose SPI chip-selects */
-       for (i = 0; i < nr_devices; i++) {
-               if (devices[i].controller_data)
-                       cs_pin = (unsigned long) devices[i].controller_data;
-               else if (devices[i].bus_num == 0)
-                       cs_pin = spi0_standard_cs[devices[i].chip_select];
-               else
-                       cs_pin = spi1_standard_cs[devices[i].chip_select];
-
-               if (devices[i].bus_num == 0)
-                       enable_spi0 = 1;
-               else
-                       enable_spi1 = 1;
-
-               /* enable chip-select pin */
-               at91_set_gpio_output(cs_pin, 1);
-
-               /* pass chip-select pin to driver */
-               devices[i].controller_data = (void *) cs_pin;
-       }
-
-       spi_register_board_info(devices, nr_devices);
-
-       /* Configure SPI bus(es) */
-       if (enable_spi0) {
-               at91_set_B_periph(AT91_PIN_PA0, 0);     /* SPI0_MISO */
-               at91_set_B_periph(AT91_PIN_PA1, 0);     /* SPI0_MOSI */
-               at91_set_B_periph(AT91_PIN_PA2, 0);     /* SPI0_SPCK */
-
-               platform_device_register(&at91cap9_spi0_device);
-       }
-       if (enable_spi1) {
-               at91_set_A_periph(AT91_PIN_PB12, 0);    /* SPI1_MISO */
-               at91_set_A_periph(AT91_PIN_PB13, 0);    /* SPI1_MOSI */
-               at91_set_A_periph(AT91_PIN_PB14, 0);    /* SPI1_SPCK */
-
-               platform_device_register(&at91cap9_spi1_device);
-       }
-}
-#else
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  Timer/Counter block
- * -------------------------------------------------------------------- */
-
-#ifdef CONFIG_ATMEL_TCLIB
-
-static struct resource tcb_resources[] = {
-       [0] = {
-               .start  = AT91CAP9_BASE_TCB0,
-               .end    = AT91CAP9_BASE_TCB0 + SZ_16K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91CAP9_ID_TCB,
-               .end    = AT91CAP9_ID_TCB,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device at91cap9_tcb_device = {
-       .name           = "atmel_tcb",
-       .id             = 0,
-       .resource       = tcb_resources,
-       .num_resources  = ARRAY_SIZE(tcb_resources),
-};
-
-static void __init at91_add_device_tc(void)
-{
-       platform_device_register(&at91cap9_tcb_device);
-}
-#else
-static void __init at91_add_device_tc(void) { }
-#endif
-
-
-/* --------------------------------------------------------------------
- *  RTT
- * -------------------------------------------------------------------- */
-
-static struct resource rtt_resources[] = {
-       {
-               .start  = AT91CAP9_BASE_RTT,
-               .end    = AT91CAP9_BASE_RTT + SZ_16 - 1,
-               .flags  = IORESOURCE_MEM,
-       }
-};
-
-static struct platform_device at91cap9_rtt_device = {
-       .name           = "at91_rtt",
-       .id             = 0,
-       .resource       = rtt_resources,
-       .num_resources  = ARRAY_SIZE(rtt_resources),
-};
-
-static void __init at91_add_device_rtt(void)
-{
-       platform_device_register(&at91cap9_rtt_device);
-}
-
-
-/* --------------------------------------------------------------------
- *  Watchdog
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
-static struct resource wdt_resources[] = {
-       {
-               .start  = AT91CAP9_BASE_WDT,
-               .end    = AT91CAP9_BASE_WDT + SZ_16 - 1,
-               .flags  = IORESOURCE_MEM,
-       }
-};
-
-static struct platform_device at91cap9_wdt_device = {
-       .name           = "at91_wdt",
-       .id             = -1,
-       .resource       = wdt_resources,
-       .num_resources  = ARRAY_SIZE(wdt_resources),
-};
-
-static void __init at91_add_device_watchdog(void)
-{
-       platform_device_register(&at91cap9_wdt_device);
-}
-#else
-static void __init at91_add_device_watchdog(void) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  PWM
- * --------------------------------------------------------------------*/
-
-#if defined(CONFIG_ATMEL_PWM)
-static u32 pwm_mask;
-
-static struct resource pwm_resources[] = {
-       [0] = {
-               .start  = AT91CAP9_BASE_PWMC,
-               .end    = AT91CAP9_BASE_PWMC + SZ_16K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91CAP9_ID_PWMC,
-               .end    = AT91CAP9_ID_PWMC,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device at91cap9_pwm0_device = {
-       .name   = "atmel_pwm",
-       .id     = -1,
-       .dev    = {
-               .platform_data          = &pwm_mask,
-       },
-       .resource       = pwm_resources,
-       .num_resources  = ARRAY_SIZE(pwm_resources),
-};
-
-void __init at91_add_device_pwm(u32 mask)
-{
-       if (mask & (1 << AT91_PWM0))
-               at91_set_A_periph(AT91_PIN_PB19, 1);    /* enable PWM0 */
-
-       if (mask & (1 << AT91_PWM1))
-               at91_set_B_periph(AT91_PIN_PB8, 1);     /* enable PWM1 */
-
-       if (mask & (1 << AT91_PWM2))
-               at91_set_B_periph(AT91_PIN_PC29, 1);    /* enable PWM2 */
-
-       if (mask & (1 << AT91_PWM3))
-               at91_set_B_periph(AT91_PIN_PA11, 1);    /* enable PWM3 */
-
-       pwm_mask = mask;
-
-       platform_device_register(&at91cap9_pwm0_device);
-}
-#else
-void __init at91_add_device_pwm(u32 mask) {}
-#endif
-
-
-
-/* --------------------------------------------------------------------
- *  AC97
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
-static u64 ac97_dmamask = DMA_BIT_MASK(32);
-static struct ac97c_platform_data ac97_data;
-
-static struct resource ac97_resources[] = {
-       [0] = {
-               .start  = AT91CAP9_BASE_AC97C,
-               .end    = AT91CAP9_BASE_AC97C + SZ_16K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91CAP9_ID_AC97C,
-               .end    = AT91CAP9_ID_AC97C,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device at91cap9_ac97_device = {
-       .name           = "atmel_ac97c",
-       .id             = 1,
-       .dev            = {
-                               .dma_mask               = &ac97_dmamask,
-                               .coherent_dma_mask      = DMA_BIT_MASK(32),
-                               .platform_data          = &ac97_data,
-       },
-       .resource       = ac97_resources,
-       .num_resources  = ARRAY_SIZE(ac97_resources),
-};
-
-void __init at91_add_device_ac97(struct ac97c_platform_data *data)
-{
-       if (!data)
-               return;
-
-       at91_set_A_periph(AT91_PIN_PA6, 0);     /* AC97FS */
-       at91_set_A_periph(AT91_PIN_PA7, 0);     /* AC97CK */
-       at91_set_A_periph(AT91_PIN_PA8, 0);     /* AC97TX */
-       at91_set_A_periph(AT91_PIN_PA9, 0);     /* AC97RX */
-
-       /* reset */
-       if (gpio_is_valid(data->reset_pin))
-               at91_set_gpio_output(data->reset_pin, 0);
-
-       ac97_data = *data;
-       platform_device_register(&at91cap9_ac97_device);
-}
-#else
-void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  LCD Controller
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
-static u64 lcdc_dmamask = DMA_BIT_MASK(32);
-static struct atmel_lcdfb_info lcdc_data;
-
-static struct resource lcdc_resources[] = {
-       [0] = {
-               .start  = AT91CAP9_LCDC_BASE,
-               .end    = AT91CAP9_LCDC_BASE + SZ_4K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91CAP9_ID_LCDC,
-               .end    = AT91CAP9_ID_LCDC,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device at91_lcdc_device = {
-       .name           = "atmel_lcdfb",
-       .id             = 0,
-       .dev            = {
-                               .dma_mask               = &lcdc_dmamask,
-                               .coherent_dma_mask      = DMA_BIT_MASK(32),
-                               .platform_data          = &lcdc_data,
-       },
-       .resource       = lcdc_resources,
-       .num_resources  = ARRAY_SIZE(lcdc_resources),
-};
-
-void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
-{
-       if (!data)
-               return;
-
-       if (cpu_is_at91cap9_revB())
-               irq_set_irq_type(AT91CAP9_ID_LCDC, IRQ_TYPE_LEVEL_HIGH);
-
-       at91_set_A_periph(AT91_PIN_PC1, 0);     /* LCDHSYNC */
-       at91_set_A_periph(AT91_PIN_PC2, 0);     /* LCDDOTCK */
-       at91_set_A_periph(AT91_PIN_PC3, 0);     /* LCDDEN */
-       at91_set_B_periph(AT91_PIN_PB9, 0);     /* LCDCC */
-       at91_set_A_periph(AT91_PIN_PC6, 0);     /* LCDD2 */
-       at91_set_A_periph(AT91_PIN_PC7, 0);     /* LCDD3 */
-       at91_set_A_periph(AT91_PIN_PC8, 0);     /* LCDD4 */
-       at91_set_A_periph(AT91_PIN_PC9, 0);     /* LCDD5 */
-       at91_set_A_periph(AT91_PIN_PC10, 0);    /* LCDD6 */
-       at91_set_A_periph(AT91_PIN_PC11, 0);    /* LCDD7 */
-       at91_set_A_periph(AT91_PIN_PC14, 0);    /* LCDD10 */
-       at91_set_A_periph(AT91_PIN_PC15, 0);    /* LCDD11 */
-       at91_set_A_periph(AT91_PIN_PC16, 0);    /* LCDD12 */
-       at91_set_A_periph(AT91_PIN_PC17, 0);    /* LCDD13 */
-       at91_set_A_periph(AT91_PIN_PC18, 0);    /* LCDD14 */
-       at91_set_A_periph(AT91_PIN_PC19, 0);    /* LCDD15 */
-       at91_set_A_periph(AT91_PIN_PC22, 0);    /* LCDD18 */
-       at91_set_A_periph(AT91_PIN_PC23, 0);    /* LCDD19 */
-       at91_set_A_periph(AT91_PIN_PC24, 0);    /* LCDD20 */
-       at91_set_A_periph(AT91_PIN_PC25, 0);    /* LCDD21 */
-       at91_set_A_periph(AT91_PIN_PC26, 0);    /* LCDD22 */
-       at91_set_A_periph(AT91_PIN_PC27, 0);    /* LCDD23 */
-
-       lcdc_data = *data;
-       platform_device_register(&at91_lcdc_device);
-}
-#else
-void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  SSC -- Synchronous Serial Controller
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
-static u64 ssc0_dmamask = DMA_BIT_MASK(32);
-
-static struct resource ssc0_resources[] = {
-       [0] = {
-               .start  = AT91CAP9_BASE_SSC0,
-               .end    = AT91CAP9_BASE_SSC0 + SZ_16K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91CAP9_ID_SSC0,
-               .end    = AT91CAP9_ID_SSC0,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device at91cap9_ssc0_device = {
-       .name   = "ssc",
-       .id     = 0,
-       .dev    = {
-               .dma_mask               = &ssc0_dmamask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       },
-       .resource       = ssc0_resources,
-       .num_resources  = ARRAY_SIZE(ssc0_resources),
-};
-
-static inline void configure_ssc0_pins(unsigned pins)
-{
-       if (pins & ATMEL_SSC_TF)
-               at91_set_A_periph(AT91_PIN_PB0, 1);
-       if (pins & ATMEL_SSC_TK)
-               at91_set_A_periph(AT91_PIN_PB1, 1);
-       if (pins & ATMEL_SSC_TD)
-               at91_set_A_periph(AT91_PIN_PB2, 1);
-       if (pins & ATMEL_SSC_RD)
-               at91_set_A_periph(AT91_PIN_PB3, 1);
-       if (pins & ATMEL_SSC_RK)
-               at91_set_A_periph(AT91_PIN_PB4, 1);
-       if (pins & ATMEL_SSC_RF)
-               at91_set_A_periph(AT91_PIN_PB5, 1);
-}
-
-static u64 ssc1_dmamask = DMA_BIT_MASK(32);
-
-static struct resource ssc1_resources[] = {
-       [0] = {
-               .start  = AT91CAP9_BASE_SSC1,
-               .end    = AT91CAP9_BASE_SSC1 + SZ_16K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91CAP9_ID_SSC1,
-               .end    = AT91CAP9_ID_SSC1,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device at91cap9_ssc1_device = {
-       .name   = "ssc",
-       .id     = 1,
-       .dev    = {
-               .dma_mask               = &ssc1_dmamask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       },
-       .resource       = ssc1_resources,
-       .num_resources  = ARRAY_SIZE(ssc1_resources),
-};
-
-static inline void configure_ssc1_pins(unsigned pins)
-{
-       if (pins & ATMEL_SSC_TF)
-               at91_set_A_periph(AT91_PIN_PB6, 1);
-       if (pins & ATMEL_SSC_TK)
-               at91_set_A_periph(AT91_PIN_PB7, 1);
-       if (pins & ATMEL_SSC_TD)
-               at91_set_A_periph(AT91_PIN_PB8, 1);
-       if (pins & ATMEL_SSC_RD)
-               at91_set_A_periph(AT91_PIN_PB9, 1);
-       if (pins & ATMEL_SSC_RK)
-               at91_set_A_periph(AT91_PIN_PB10, 1);
-       if (pins & ATMEL_SSC_RF)
-               at91_set_A_periph(AT91_PIN_PB11, 1);
-}
-
-/*
- * SSC controllers are accessed through library code, instead of any
- * kind of all-singing/all-dancing driver.  For example one could be
- * used by a particular I2S audio codec's driver, while another one
- * on the same system might be used by a custom data capture driver.
- */
-void __init at91_add_device_ssc(unsigned id, unsigned pins)
-{
-       struct platform_device *pdev;
-
-       /*
-        * NOTE: caller is responsible for passing information matching
-        * "pins" to whatever will be using each particular controller.
-        */
-       switch (id) {
-       case AT91CAP9_ID_SSC0:
-               pdev = &at91cap9_ssc0_device;
-               configure_ssc0_pins(pins);
-               break;
-       case AT91CAP9_ID_SSC1:
-               pdev = &at91cap9_ssc1_device;
-               configure_ssc1_pins(pins);
-               break;
-       default:
-               return;
-       }
-
-       platform_device_register(pdev);
-}
-
-#else
-void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  UART
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_SERIAL_ATMEL)
-static struct resource dbgu_resources[] = {
-       [0] = {
-               .start  = AT91CAP9_BASE_DBGU,
-               .end    = AT91CAP9_BASE_DBGU + SZ_512 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91_ID_SYS,
-               .end    = AT91_ID_SYS,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct atmel_uart_data dbgu_data = {
-       .use_dma_tx     = 0,
-       .use_dma_rx     = 0,            /* DBGU not capable of receive DMA */
-};
-
-static u64 dbgu_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device at91cap9_dbgu_device = {
-       .name           = "atmel_usart",
-       .id             = 0,
-       .dev            = {
-                               .dma_mask               = &dbgu_dmamask,
-                               .coherent_dma_mask      = DMA_BIT_MASK(32),
-                               .platform_data          = &dbgu_data,
-       },
-       .resource       = dbgu_resources,
-       .num_resources  = ARRAY_SIZE(dbgu_resources),
-};
-
-static inline void configure_dbgu_pins(void)
-{
-       at91_set_A_periph(AT91_PIN_PC30, 0);            /* DRXD */
-       at91_set_A_periph(AT91_PIN_PC31, 1);            /* DTXD */
-}
-
-static struct resource uart0_resources[] = {
-       [0] = {
-               .start  = AT91CAP9_BASE_US0,
-               .end    = AT91CAP9_BASE_US0 + SZ_16K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91CAP9_ID_US0,
-               .end    = AT91CAP9_ID_US0,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct atmel_uart_data uart0_data = {
-       .use_dma_tx     = 1,
-       .use_dma_rx     = 1,
-};
-
-static u64 uart0_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device at91cap9_uart0_device = {
-       .name           = "atmel_usart",
-       .id             = 1,
-       .dev            = {
-                               .dma_mask               = &uart0_dmamask,
-                               .coherent_dma_mask      = DMA_BIT_MASK(32),
-                               .platform_data          = &uart0_data,
-       },
-       .resource       = uart0_resources,
-       .num_resources  = ARRAY_SIZE(uart0_resources),
-};
-
-static inline void configure_usart0_pins(unsigned pins)
-{
-       at91_set_A_periph(AT91_PIN_PA22, 1);            /* TXD0 */
-       at91_set_A_periph(AT91_PIN_PA23, 0);            /* RXD0 */
-
-       if (pins & ATMEL_UART_RTS)
-               at91_set_A_periph(AT91_PIN_PA24, 0);    /* RTS0 */
-       if (pins & ATMEL_UART_CTS)
-               at91_set_A_periph(AT91_PIN_PA25, 0);    /* CTS0 */
-}
-
-static struct resource uart1_resources[] = {
-       [0] = {
-               .start  = AT91CAP9_BASE_US1,
-               .end    = AT91CAP9_BASE_US1 + SZ_16K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91CAP9_ID_US1,
-               .end    = AT91CAP9_ID_US1,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct atmel_uart_data uart1_data = {
-       .use_dma_tx     = 1,
-       .use_dma_rx     = 1,
-};
-
-static u64 uart1_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device at91cap9_uart1_device = {
-       .name           = "atmel_usart",
-       .id             = 2,
-       .dev            = {
-                               .dma_mask               = &uart1_dmamask,
-                               .coherent_dma_mask      = DMA_BIT_MASK(32),
-                               .platform_data          = &uart1_data,
-       },
-       .resource       = uart1_resources,
-       .num_resources  = ARRAY_SIZE(uart1_resources),
-};
-
-static inline void configure_usart1_pins(unsigned pins)
-{
-       at91_set_A_periph(AT91_PIN_PD0, 1);             /* TXD1 */
-       at91_set_A_periph(AT91_PIN_PD1, 0);             /* RXD1 */
-
-       if (pins & ATMEL_UART_RTS)
-               at91_set_B_periph(AT91_PIN_PD7, 0);     /* RTS1 */
-       if (pins & ATMEL_UART_CTS)
-               at91_set_B_periph(AT91_PIN_PD8, 0);     /* CTS1 */
-}
-
-static struct resource uart2_resources[] = {
-       [0] = {
-               .start  = AT91CAP9_BASE_US2,
-               .end    = AT91CAP9_BASE_US2 + SZ_16K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = AT91CAP9_ID_US2,
-               .end    = AT91CAP9_ID_US2,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct atmel_uart_data uart2_data = {
-       .use_dma_tx     = 1,
-       .use_dma_rx     = 1,
-};
-
-static u64 uart2_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device at91cap9_uart2_device = {
-       .name           = "atmel_usart",
-       .id             = 3,
-       .dev            = {
-                               .dma_mask               = &uart2_dmamask,
-                               .coherent_dma_mask      = DMA_BIT_MASK(32),
-                               .platform_data          = &uart2_data,
-       },
-       .resource       = uart2_resources,
-       .num_resources  = ARRAY_SIZE(uart2_resources),
-};
-
-static inline void configure_usart2_pins(unsigned pins)
-{
-       at91_set_A_periph(AT91_PIN_PD2, 1);             /* TXD2 */
-       at91_set_A_periph(AT91_PIN_PD3, 0);             /* RXD2 */
-
-       if (pins & ATMEL_UART_RTS)
-               at91_set_B_periph(AT91_PIN_PD5, 0);     /* RTS2 */
-       if (pins & ATMEL_UART_CTS)
-               at91_set_B_periph(AT91_PIN_PD6, 0);     /* CTS2 */
-}
-
-static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART];  /* the UARTs to use */
-struct platform_device *atmel_default_console_device;  /* the serial console device */
-
-void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
-{
-       struct platform_device *pdev;
-       struct atmel_uart_data *pdata;
-
-       switch (id) {
-               case 0:         /* DBGU */
-                       pdev = &at91cap9_dbgu_device;
-                       configure_dbgu_pins();
-                       break;
-               case AT91CAP9_ID_US0:
-                       pdev = &at91cap9_uart0_device;
-                       configure_usart0_pins(pins);
-                       break;
-               case AT91CAP9_ID_US1:
-                       pdev = &at91cap9_uart1_device;
-                       configure_usart1_pins(pins);
-                       break;
-               case AT91CAP9_ID_US2:
-                       pdev = &at91cap9_uart2_device;
-                       configure_usart2_pins(pins);
-                       break;
-               default:
-                       return;
-       }
-       pdata = pdev->dev.platform_data;
-       pdata->num = portnr;            /* update to mapped ID */
-
-       if (portnr < ATMEL_MAX_UART)
-               at91_uarts[portnr] = pdev;
-}
-
-void __init at91_set_serial_console(unsigned portnr)
-{
-       if (portnr < ATMEL_MAX_UART) {
-               atmel_default_console_device = at91_uarts[portnr];
-               at91cap9_set_console_clock(at91_uarts[portnr]->id);
-       }
-}
-
-void __init at91_add_device_serial(void)
-{
-       int i;
-
-       for (i = 0; i < ATMEL_MAX_UART; i++) {
-               if (at91_uarts[i])
-                       platform_device_register(at91_uarts[i]);
-       }
-
-       if (!atmel_default_console_device)
-               printk(KERN_INFO "AT91: No default serial console defined.\n");
-}
-#else
-void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
-void __init at91_set_serial_console(unsigned portnr) {}
-void __init at91_add_device_serial(void) {}
-#endif
-
-
-/* -------------------------------------------------------------------- */
-/*
- * These devices are always present and don't need any board-specific
- * setup.
- */
-static int __init at91_add_standard_devices(void)
-{
-       at91_add_device_rtt();
-       at91_add_device_watchdog();
-       at91_add_device_tc();
-       return 0;
-}
-
-arch_initcall(at91_add_standard_devices);
index dd6e2de134204a5ccf5c28df3bfe41d9b8170314..0df1045311e420e2e96670e62f182f44d39f5481 100644 (file)
@@ -295,7 +295,7 @@ static void at91rm9200_idle(void)
         * Disable the processor clock.  The processor will be automatically
         * re-enabled by an interrupt or by a reset.
         */
-       at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+       at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK);
 }
 
 static void at91rm9200_restart(char mode, const char *cmd)
@@ -303,8 +303,8 @@ static void at91rm9200_restart(char mode, const char *cmd)
        /*
         * Perform a hardware reset with the use of the Watchdog timer.
         */
-       at91_sys_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1);
-       at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
+       at91_st_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1);
+       at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
 }
 
 /* --------------------------------------------------------------------
@@ -319,6 +319,8 @@ static void __init at91rm9200_map_io(void)
 
 static void __init at91rm9200_ioremap_registers(void)
 {
+       at91rm9200_ioremap_st(AT91RM9200_BASE_ST);
+       at91_ioremap_ramc(0, AT91RM9200_BASE_MC, 256);
 }
 
 static void __init at91rm9200_initialize(void)
index 97676bdae9983c98b79f77cb85dd88e833756789..99ce5c955e39d94d24f50005b875459739ef6ce5 100644 (file)
@@ -21,6 +21,7 @@
 #include <mach/board.h>
 #include <mach/at91rm9200.h>
 #include <mach/at91rm9200_mc.h>
+#include <mach/at91_ramc.h>
 
 #include "generic.h"
 
@@ -241,15 +242,15 @@ void __init at91_add_device_cf(struct at91_cf_data *data)
        data->chipselect = 4;           /* can only use EBI ChipSelect 4 */
 
        /* CF takes over CS4, CS5, CS6 */
-       csa = at91_sys_read(AT91_EBI_CSA);
-       at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH);
+       csa = at91_ramc_read(0, AT91_EBI_CSA);
+       at91_ramc_write(0, AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH);
 
        /*
         * Static memory controller timing adjustments.
         * REVISIT:  these timings are in terms of MCK cycles, so
         * when MCK changes (cpufreq etc) so must these values...
         */
-       at91_sys_write(AT91_SMC_CSR(4),
+       at91_ramc_write(0, AT91_SMC_CSR(4),
                                  AT91_SMC_ACSS_STD
                                | AT91_SMC_DBW_16
                                | AT91_SMC_BAT
@@ -407,11 +408,11 @@ void __init at91_add_device_nand(struct atmel_nand_data *data)
                return;
 
        /* enable the address range of CS3 */
-       csa = at91_sys_read(AT91_EBI_CSA);
-       at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS3A_SMC_SMARTMEDIA);
+       csa = at91_ramc_read(0, AT91_EBI_CSA);
+       at91_ramc_write(0, AT91_EBI_CSA, csa | AT91_EBI_CS3A_SMC_SMARTMEDIA);
 
        /* set the bus interface characteristics */
-       at91_sys_write(AT91_SMC_CSR(3), AT91_SMC_ACSS_STD | AT91_SMC_DBW_8 | AT91_SMC_WSEN
+       at91_ramc_write(0, AT91_SMC_CSR(3), AT91_SMC_ACSS_STD | AT91_SMC_DBW_8 | AT91_SMC_WSEN
                | AT91_SMC_NWS_(5)
                | AT91_SMC_TDF_(1)
                | AT91_SMC_RWSETUP_(0)  /* tDS Data Set up Time 30 - ns */
@@ -1114,7 +1115,6 @@ static inline void configure_usart3_pins(unsigned pins)
 }
 
 static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART];  /* the UARTs to use */
-struct platform_device *atmel_default_console_device;  /* the serial console device */
 
 void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
 {
index a028cdf8f9749d8ad4da1aef23386da5850330c4..dd7f782b0b91731202c3d8e10f02597b7d89518c 100644 (file)
@@ -43,9 +43,9 @@ static inline unsigned long read_CRTR(void)
 {
        unsigned long x1, x2;
 
-       x1 = at91_sys_read(AT91_ST_CRTR);
+       x1 = at91_st_read(AT91_ST_CRTR);
        do {
-               x2 = at91_sys_read(AT91_ST_CRTR);
+               x2 = at91_st_read(AT91_ST_CRTR);
                if (x1 == x2)
                        break;
                x1 = x2;
@@ -58,7 +58,7 @@ static inline unsigned long read_CRTR(void)
  */
 static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
 {
-       u32     sr = at91_sys_read(AT91_ST_SR) & irqmask;
+       u32     sr = at91_st_read(AT91_ST_SR) & irqmask;
 
        /*
         * irqs should be disabled here, but as the irq is shared they are only
@@ -110,22 +110,22 @@ static void
 clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
 {
        /* Disable and flush pending timer interrupts */
-       at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS);
-       (void) at91_sys_read(AT91_ST_SR);
+       at91_st_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS);
+       at91_st_read(AT91_ST_SR);
 
        last_crtr = read_CRTR();
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
                /* PIT for periodic irqs; fixed rate of 1/HZ */
                irqmask = AT91_ST_PITS;
-               at91_sys_write(AT91_ST_PIMR, RM9200_TIMER_LATCH);
+               at91_st_write(AT91_ST_PIMR, RM9200_TIMER_LATCH);
                break;
        case CLOCK_EVT_MODE_ONESHOT:
                /* ALM for oneshot irqs, set by next_event()
                 * before 32 seconds have passed
                 */
                irqmask = AT91_ST_ALMS;
-               at91_sys_write(AT91_ST_RTAR, last_crtr);
+               at91_st_write(AT91_ST_RTAR, last_crtr);
                break;
        case CLOCK_EVT_MODE_SHUTDOWN:
        case CLOCK_EVT_MODE_UNUSED:
@@ -133,7 +133,7 @@ clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
                irqmask = 0;
                break;
        }
-       at91_sys_write(AT91_ST_IER, irqmask);
+       at91_st_write(AT91_ST_IER, irqmask);
 }
 
 static int
@@ -156,12 +156,12 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
        alm = read_CRTR();
 
        /* Cancel any pending alarm; flush any pending IRQ */
-       at91_sys_write(AT91_ST_RTAR, alm);
-       (void) at91_sys_read(AT91_ST_SR);
+       at91_st_write(AT91_ST_RTAR, alm);
+       at91_st_read(AT91_ST_SR);
 
        /* Schedule alarm by writing RTAR. */
        alm += delta;
-       at91_sys_write(AT91_ST_RTAR, alm);
+       at91_st_write(AT91_ST_RTAR, alm);
 
        return status;
 }
@@ -175,15 +175,24 @@ static struct clock_event_device clkevt = {
        .set_mode       = clkevt32k_mode,
 };
 
+void __iomem *at91_st_base;
+
+void __init at91rm9200_ioremap_st(u32 addr)
+{
+       at91_st_base = ioremap(addr, 256);
+       if (!at91_st_base)
+               panic("Impossible to ioremap ST\n");
+}
+
 /*
  * ST (system timer) module supports both clockevents and clocksource.
  */
 void __init at91rm9200_timer_init(void)
 {
        /* Disable all timer interrupts, and clear any pending ones */
-       at91_sys_write(AT91_ST_IDR,
+       at91_st_write(AT91_ST_IDR,
                AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS);
-       (void) at91_sys_read(AT91_ST_SR);
+       at91_st_read(AT91_ST_SR);
 
        /* Make IRQs happen for the system timer */
        setup_irq(AT91_ID_SYS, &at91rm9200_timer_irq);
@@ -192,7 +201,7 @@ void __init at91rm9200_timer_init(void)
         * directly for the clocksource and all clockevents, after adjusting
         * its prescaler from the 1 Hz default.
         */
-       at91_sys_write(AT91_ST_RTMR, 1);
+       at91_st_write(AT91_ST_RTMR, 1);
 
        /* Setup timer clockevent, with minimum of two ticks (important!!) */
        clkevt.mult = div_sc(AT91_SLOW_CLOCK, NSEC_PER_SEC, clkevt.shift);
index 9ac8c6fe3363b6af723c8366108d6d863bcb9415..d1e5750a6a047f5160022dceb4ea5ad065461488 100644 (file)
@@ -209,6 +209,14 @@ static struct clk_lookup periph_clocks_lookups[] = {
        CLKDEV_CON_DEV_ID("usart", "fffd0000.serial", &usart3_clk),
        CLKDEV_CON_DEV_ID("usart", "fffd4000.serial", &usart4_clk),
        CLKDEV_CON_DEV_ID("usart", "fffd8000.serial", &usart5_clk),
+       /* more tc lookup table for DT entries */
+       CLKDEV_CON_DEV_ID("t0_clk", "fffa0000.timer", &tc0_clk),
+       CLKDEV_CON_DEV_ID("t1_clk", "fffa0000.timer", &tc1_clk),
+       CLKDEV_CON_DEV_ID("t2_clk", "fffa0000.timer", &tc2_clk),
+       CLKDEV_CON_DEV_ID("t0_clk", "fffdc000.timer", &tc3_clk),
+       CLKDEV_CON_DEV_ID("t1_clk", "fffdc000.timer", &tc4_clk),
+       CLKDEV_CON_DEV_ID("t2_clk", "fffdc000.timer", &tc5_clk),
+       CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &ohci_clk),
        /* fake hclk clock */
        CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
        CLKDEV_CON_ID("pioA", &pioA_clk),
@@ -310,34 +318,27 @@ static void __init at91sam9xe_map_io(void)
 
 static void __init at91sam9260_map_io(void)
 {
-       if (cpu_is_at91sam9xe()) {
+       if (cpu_is_at91sam9xe())
                at91sam9xe_map_io();
-       } else if (cpu_is_at91sam9g20()) {
-               at91_init_sram(0, AT91SAM9G20_SRAM0_BASE, AT91SAM9G20_SRAM0_SIZE);
-               at91_init_sram(1, AT91SAM9G20_SRAM1_BASE, AT91SAM9G20_SRAM1_SIZE);
-       } else {
-               at91_init_sram(0, AT91SAM9260_SRAM0_BASE, AT91SAM9260_SRAM0_SIZE);
-               at91_init_sram(1, AT91SAM9260_SRAM1_BASE, AT91SAM9260_SRAM1_SIZE);
-       }
+       else if (cpu_is_at91sam9g20())
+               at91_init_sram(0, AT91SAM9G20_SRAM_BASE, AT91SAM9G20_SRAM_SIZE);
+       else
+               at91_init_sram(0, AT91SAM9260_SRAM_BASE, AT91SAM9260_SRAM_SIZE);
 }
 
 static void __init at91sam9260_ioremap_registers(void)
 {
        at91_ioremap_shdwc(AT91SAM9260_BASE_SHDWC);
        at91_ioremap_rstc(AT91SAM9260_BASE_RSTC);
+       at91_ioremap_ramc(0, AT91SAM9260_BASE_SDRAMC, 512);
        at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT);
        at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC);
-}
-
-static void at91sam9260_idle(void)
-{
-       at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
-       cpu_do_idle();
+       at91_ioremap_matrix(AT91SAM9260_BASE_MATRIX);
 }
 
 static void __init at91sam9260_initialize(void)
 {
-       arm_pm_idle = at91sam9260_idle;
+       arm_pm_idle = at91sam9_idle;
        arm_pm_restart = at91sam9_alt_restart;
        at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1)
                        | (1 << AT91SAM9260_ID_IRQ2);
index 5a24f0b4554db2b7e4ea50e620b464e2e9b9363a..7e5651ee9f859f9689b76f07ca5bc834d3aa871a 100644 (file)
@@ -21,6 +21,7 @@
 #include <mach/cpu.h>
 #include <mach/at91sam9260.h>
 #include <mach/at91sam9260_matrix.h>
+#include <mach/at91_matrix.h>
 #include <mach/at91sam9_smc.h>
 
 #include "generic.h"
@@ -422,8 +423,8 @@ void __init at91_add_device_nand(struct atmel_nand_data *data)
        if (!data)
                return;
 
-       csa = at91_sys_read(AT91_MATRIX_EBICSA);
-       at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
+       csa = at91_matrix_read(AT91_MATRIX_EBICSA);
+       at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
 
        /* enable pin */
        if (gpio_is_valid(data->enable_pin))
@@ -641,7 +642,7 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
 static struct resource tcb0_resources[] = {
        [0] = {
                .start  = AT91SAM9260_BASE_TCB0,
-               .end    = AT91SAM9260_BASE_TCB0 + SZ_16K - 1,
+               .end    = AT91SAM9260_BASE_TCB0 + SZ_256 - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -671,7 +672,7 @@ static struct platform_device at91sam9260_tcb0_device = {
 static struct resource tcb1_resources[] = {
        [0] = {
                .start  = AT91SAM9260_BASE_TCB1,
-               .end    = AT91SAM9260_BASE_TCB1 + SZ_16K - 1,
+               .end    = AT91SAM9260_BASE_TCB1 + SZ_256 - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -698,8 +699,25 @@ static struct platform_device at91sam9260_tcb1_device = {
        .num_resources  = ARRAY_SIZE(tcb1_resources),
 };
 
+#if defined(CONFIG_OF)
+static struct of_device_id tcb_ids[] = {
+       { .compatible = "atmel,at91rm9200-tcb" },
+       { /*sentinel*/ }
+};
+#endif
+
 static void __init at91_add_device_tc(void)
 {
+#if defined(CONFIG_OF)
+       struct device_node *np;
+
+       np = of_find_matching_node(NULL, tcb_ids);
+       if (np) {
+               of_node_put(np);
+               return;
+       }
+#endif
+
        platform_device_register(&at91sam9260_tcb0_device);
        platform_device_register(&at91sam9260_tcb1_device);
 }
@@ -717,18 +735,42 @@ static struct resource rtt_resources[] = {
                .start  = AT91SAM9260_BASE_RTT,
                .end    = AT91SAM9260_BASE_RTT + SZ_16 - 1,
                .flags  = IORESOURCE_MEM,
-       }
+       }, {
+               .flags  = IORESOURCE_MEM,
+       },
 };
 
 static struct platform_device at91sam9260_rtt_device = {
        .name           = "at91_rtt",
        .id             = 0,
        .resource       = rtt_resources,
-       .num_resources  = ARRAY_SIZE(rtt_resources),
 };
 
+
+#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9)
+static void __init at91_add_device_rtt_rtc(void)
+{
+       at91sam9260_rtt_device.name = "rtc-at91sam9";
+       /*
+        * The second resource is needed:
+        * GPBR will serve as the storage for RTC time offset
+        */
+       at91sam9260_rtt_device.num_resources = 2;
+       rtt_resources[1].start = AT91SAM9260_BASE_GPBR +
+                                4 * CONFIG_RTC_DRV_AT91SAM9_GPBR;
+       rtt_resources[1].end = rtt_resources[1].start + 3;
+}
+#else
+static void __init at91_add_device_rtt_rtc(void)
+{
+       /* Only one resource is needed: RTT not used as RTC */
+       at91sam9260_rtt_device.num_resources = 1;
+}
+#endif
+
 static void __init at91_add_device_rtt(void)
 {
+       at91_add_device_rtt_rtc();
        platform_device_register(&at91sam9260_rtt_device);
 }
 
@@ -1139,7 +1181,6 @@ static inline void configure_usart5_pins(void)
 }
 
 static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART];  /* the UARTs to use */
-struct platform_device *atmel_default_console_device;  /* the serial console device */
 
 void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
 {
@@ -1264,7 +1305,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data)
        if (!data)
                return;
 
-       csa = at91_sys_read(AT91_MATRIX_EBICSA);
+       csa = at91_matrix_read(AT91_MATRIX_EBICSA);
 
        switch (data->chipselect) {
        case 4:
@@ -1287,7 +1328,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data)
                return;
        }
 
-       at91_sys_write(AT91_MATRIX_EBICSA, csa);
+       at91_matrix_write(AT91_MATRIX_EBICSA, csa);
 
        if (gpio_is_valid(data->rst_pin)) {
                at91_set_multi_drive(data->rst_pin, 0);
index ab76868f01f5ee8e48b80359d3064e531ae3c86d..684c5dfd92ac5a00eaf736ed5d5949769f4bdbd4 100644 (file)
@@ -283,19 +283,15 @@ static void __init at91sam9261_ioremap_registers(void)
 {
        at91_ioremap_shdwc(AT91SAM9261_BASE_SHDWC);
        at91_ioremap_rstc(AT91SAM9261_BASE_RSTC);
+       at91_ioremap_ramc(0, AT91SAM9261_BASE_SDRAMC, 512);
        at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT);
        at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC);
-}
-
-static void at91sam9261_idle(void)
-{
-       at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
-       cpu_do_idle();
+       at91_ioremap_matrix(AT91SAM9261_BASE_MATRIX);
 }
 
 static void __init at91sam9261_initialize(void)
 {
-       arm_pm_idle = at91sam9261_idle;
+       arm_pm_idle = at91sam9_idle;
        arm_pm_restart = at91sam9_alt_restart;
        at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
                        | (1 << AT91SAM9261_ID_IRQ2);
index 1e28bed8f425063e99af8ac417035e5e6d01900f..096da87dc00d41359fa793f6dd25f541516dd86c 100644 (file)
@@ -24,6 +24,7 @@
 #include <mach/board.h>
 #include <mach/at91sam9261.h>
 #include <mach/at91sam9261_matrix.h>
+#include <mach/at91_matrix.h>
 #include <mach/at91sam9_smc.h>
 
 #include "generic.h"
@@ -236,8 +237,8 @@ void __init at91_add_device_nand(struct atmel_nand_data *data)
        if (!data)
                return;
 
-       csa = at91_sys_read(AT91_MATRIX_EBICSA);
-       at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
+       csa = at91_matrix_read(AT91_MATRIX_EBICSA);
+       at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
 
        /* enable pin */
        if (gpio_is_valid(data->enable_pin))
@@ -603,6 +604,8 @@ static struct resource rtt_resources[] = {
                .start  = AT91SAM9261_BASE_RTT,
                .end    = AT91SAM9261_BASE_RTT + SZ_16 - 1,
                .flags  = IORESOURCE_MEM,
+       }, {
+               .flags  = IORESOURCE_MEM,
        }
 };
 
@@ -610,11 +613,32 @@ static struct platform_device at91sam9261_rtt_device = {
        .name           = "at91_rtt",
        .id             = 0,
        .resource       = rtt_resources,
-       .num_resources  = ARRAY_SIZE(rtt_resources),
 };
 
+#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9)
+static void __init at91_add_device_rtt_rtc(void)
+{
+       at91sam9261_rtt_device.name = "rtc-at91sam9";
+       /*
+        * The second resource is needed:
+        * GPBR will serve as the storage for RTC time offset
+        */
+       at91sam9261_rtt_device.num_resources = 2;
+       rtt_resources[1].start = AT91SAM9261_BASE_GPBR +
+                                4 * CONFIG_RTC_DRV_AT91SAM9_GPBR;
+       rtt_resources[1].end = rtt_resources[1].start + 3;
+}
+#else
+static void __init at91_add_device_rtt_rtc(void)
+{
+       /* Only one resource is needed: RTT not used as RTC */
+       at91sam9261_rtt_device.num_resources = 1;
+}
+#endif
+
 static void __init at91_add_device_rtt(void)
 {
+       at91_add_device_rtt_rtc();
        platform_device_register(&at91sam9261_rtt_device);
 }
 
@@ -991,7 +1015,6 @@ static inline void configure_usart2_pins(unsigned pins)
 }
 
 static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART];  /* the UARTs to use */
-struct platform_device *atmel_default_console_device;  /* the serial console device */
 
 void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
 {
index 247ab633abccc72918d0e23be60c7e937deb5b61..0b4fa5a7f685907d03aa4efc89a758e0e26d4230 100644 (file)
@@ -303,20 +303,17 @@ static void __init at91sam9263_ioremap_registers(void)
 {
        at91_ioremap_shdwc(AT91SAM9263_BASE_SHDWC);
        at91_ioremap_rstc(AT91SAM9263_BASE_RSTC);
+       at91_ioremap_ramc(0, AT91SAM9263_BASE_SDRAMC0, 512);
+       at91_ioremap_ramc(1, AT91SAM9263_BASE_SDRAMC1, 512);
        at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT);
        at91sam9_ioremap_smc(0, AT91SAM9263_BASE_SMC0);
        at91sam9_ioremap_smc(1, AT91SAM9263_BASE_SMC1);
-}
-
-static void at91sam9263_idle(void)
-{
-       at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
-       cpu_do_idle();
+       at91_ioremap_matrix(AT91SAM9263_BASE_MATRIX);
 }
 
 static void __init at91sam9263_initialize(void)
 {
-       arm_pm_idle = at91sam9263_idle;
+       arm_pm_idle = at91sam9_idle;
        arm_pm_restart = at91sam9_alt_restart;
        at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1);
 
index 366a7765635b380538c103e3c0027519550521d0..53688c46f95652f02fced22b9d1979cd6799df1b 100644 (file)
@@ -23,6 +23,7 @@
 #include <mach/board.h>
 #include <mach/at91sam9263.h>
 #include <mach/at91sam9263_matrix.h>
+#include <mach/at91_matrix.h>
 #include <mach/at91sam9_smc.h>
 
 #include "generic.h"
@@ -409,7 +410,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data)
         * we assume SMC timings are configured by board code,
         * except True IDE where timings are controlled by driver
         */
-       ebi0_csa = at91_sys_read(AT91_MATRIX_EBI0CSA);
+       ebi0_csa = at91_matrix_read(AT91_MATRIX_EBI0CSA);
        switch (data->chipselect) {
        case 4:
                at91_set_A_periph(AT91_PIN_PD6, 0);  /* EBI0_NCS4/CFCS0 */
@@ -428,7 +429,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data)
                       data->chipselect);
                return;
        }
-       at91_sys_write(AT91_MATRIX_EBI0CSA, ebi0_csa);
+       at91_matrix_write(AT91_MATRIX_EBI0CSA, ebi0_csa);
 
        if (gpio_is_valid(data->det_pin)) {
                at91_set_gpio_input(data->det_pin, 1);
@@ -496,8 +497,8 @@ void __init at91_add_device_nand(struct atmel_nand_data *data)
        if (!data)
                return;
 
-       csa = at91_sys_read(AT91_MATRIX_EBI0CSA);
-       at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA);
+       csa = at91_matrix_read(AT91_MATRIX_EBI0CSA);
+       at91_matrix_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA);
 
        /* enable pin */
        if (gpio_is_valid(data->enable_pin))
@@ -891,7 +892,8 @@ static struct platform_device at91sam9263_isi_device = {
        .num_resources  = ARRAY_SIZE(isi_resources),
 };
 
-void __init at91_add_device_isi(void)
+void __init at91_add_device_isi(struct isi_platform_data *data,
+               bool use_pck_as_mck)
 {
        at91_set_A_periph(AT91_PIN_PE0, 0);     /* ISI_D0 */
        at91_set_A_periph(AT91_PIN_PE1, 0);     /* ISI_D1 */
@@ -904,14 +906,20 @@ void __init at91_add_device_isi(void)
        at91_set_A_periph(AT91_PIN_PE8, 0);     /* ISI_PCK */
        at91_set_A_periph(AT91_PIN_PE9, 0);     /* ISI_HSYNC */
        at91_set_A_periph(AT91_PIN_PE10, 0);    /* ISI_VSYNC */
-       at91_set_B_periph(AT91_PIN_PE11, 0);    /* ISI_MCK (PCK3) */
        at91_set_B_periph(AT91_PIN_PE12, 0);    /* ISI_PD8 */
        at91_set_B_periph(AT91_PIN_PE13, 0);    /* ISI_PD9 */
        at91_set_B_periph(AT91_PIN_PE14, 0);    /* ISI_PD10 */
        at91_set_B_periph(AT91_PIN_PE15, 0);    /* ISI_PD11 */
+
+       if (use_pck_as_mck) {
+               at91_set_B_periph(AT91_PIN_PE11, 0);    /* ISI_MCK (PCK3) */
+
+               /* TODO: register the PCK for ISI_MCK and set its parent */
+       }
 }
 #else
-void __init at91_add_device_isi(void) {}
+void __init at91_add_device_isi(struct isi_platform_data *data,
+               bool use_pck_as_mck) {}
 #endif
 
 
@@ -959,6 +967,8 @@ static struct resource rtt0_resources[] = {
                .start  = AT91SAM9263_BASE_RTT0,
                .end    = AT91SAM9263_BASE_RTT0 + SZ_16 - 1,
                .flags  = IORESOURCE_MEM,
+       }, {
+               .flags  = IORESOURCE_MEM,
        }
 };
 
@@ -966,7 +976,6 @@ static struct platform_device at91sam9263_rtt0_device = {
        .name           = "at91_rtt",
        .id             = 0,
        .resource       = rtt0_resources,
-       .num_resources  = ARRAY_SIZE(rtt0_resources),
 };
 
 static struct resource rtt1_resources[] = {
@@ -974,6 +983,8 @@ static struct resource rtt1_resources[] = {
                .start  = AT91SAM9263_BASE_RTT1,
                .end    = AT91SAM9263_BASE_RTT1 + SZ_16 - 1,
                .flags  = IORESOURCE_MEM,
+       }, {
+               .flags  = IORESOURCE_MEM,
        }
 };
 
@@ -981,11 +992,53 @@ static struct platform_device at91sam9263_rtt1_device = {
        .name           = "at91_rtt",
        .id             = 1,
        .resource       = rtt1_resources,
-       .num_resources  = ARRAY_SIZE(rtt1_resources),
 };
 
+#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9)
+static void __init at91_add_device_rtt_rtc(void)
+{
+       struct platform_device *pdev;
+       struct resource *r;
+
+       switch (CONFIG_RTC_DRV_AT91SAM9_RTT) {
+       case 0:
+               /*
+                * The second resource is needed only for the chosen RTT:
+                * GPBR will serve as the storage for RTC time offset
+                */
+               at91sam9263_rtt0_device.num_resources = 2;
+               at91sam9263_rtt1_device.num_resources = 1;
+               pdev = &at91sam9263_rtt0_device;
+               r = rtt0_resources;
+               break;
+       case 1:
+               at91sam9263_rtt0_device.num_resources = 1;
+               at91sam9263_rtt1_device.num_resources = 2;
+               pdev = &at91sam9263_rtt1_device;
+               r = rtt1_resources;
+               break;
+       default:
+               pr_err("at91sam9263: only supports 2 RTT (%d)\n",
+                      CONFIG_RTC_DRV_AT91SAM9_RTT);
+               return;
+       }
+
+       pdev->name = "rtc-at91sam9";
+       r[1].start = AT91SAM9263_BASE_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR;
+       r[1].end = r[1].start + 3;
+}
+#else
+static void __init at91_add_device_rtt_rtc(void)
+{
+       /* Only one resource is needed: RTT not used as RTC */
+       at91sam9263_rtt0_device.num_resources = 1;
+       at91sam9263_rtt1_device.num_resources = 1;
+}
+#endif
+
 static void __init at91_add_device_rtt(void)
 {
+       at91_add_device_rtt_rtc();
        platform_device_register(&at91sam9263_rtt0_device);
        platform_device_register(&at91sam9263_rtt1_device);
 }
@@ -1371,7 +1424,6 @@ static inline void configure_usart2_pins(unsigned pins)
 }
 
 static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART];  /* the UARTs to use */
-struct platform_device *atmel_default_console_device;  /* the serial console device */
 
 void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
 {
index d89ead740a99756b51492064eb7b3922226526e2..a94758b42737a3d33a3cdce0bee439103ea8f7ab 100644 (file)
@@ -14,6 +14,9 @@
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/clockchips.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 
 #include <asm/mach/time.h>
 
@@ -133,7 +136,8 @@ static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id)
 static struct irqaction at91sam926x_pit_irq = {
        .name           = "at91_tick",
        .flags          = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-       .handler        = at91sam926x_pit_interrupt
+       .handler        = at91sam926x_pit_interrupt,
+       .irq            = AT91_ID_SYS,
 };
 
 static void at91sam926x_pit_reset(void)
@@ -149,6 +153,51 @@ static void at91sam926x_pit_reset(void)
        pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN);
 }
 
+#ifdef CONFIG_OF
+static struct of_device_id pit_timer_ids[] = {
+       { .compatible = "atmel,at91sam9260-pit" },
+       { /* sentinel */ }
+};
+
+static int __init of_at91sam926x_pit_init(void)
+{
+       struct device_node      *np;
+       int                     ret;
+
+       np = of_find_matching_node(NULL, pit_timer_ids);
+       if (!np)
+               goto err;
+
+       pit_base_addr = of_iomap(np, 0);
+       if (!pit_base_addr)
+               goto node_err;
+
+       /* Get the interrupts property */
+       ret = irq_of_parse_and_map(np, 0);
+       if (!ret) {
+               pr_crit("AT91: PIT: Unable to get IRQ from DT\n");
+               goto ioremap_err;
+       }
+       at91sam926x_pit_irq.irq = ret;
+
+       of_node_put(np);
+
+       return 0;
+
+ioremap_err:
+       iounmap(pit_base_addr);
+node_err:
+       of_node_put(np);
+err:
+       return -EINVAL;
+}
+#else
+static int __init of_at91sam926x_pit_init(void)
+{
+       return -EINVAL;
+}
+#endif
+
 /*
  * Set up both clocksource and clockevent support.
  */
@@ -156,6 +205,10 @@ static void __init at91sam926x_pit_init(void)
 {
        unsigned long   pit_rate;
        unsigned        bits;
+       int             ret;
+
+       /* For device tree enabled device: initialize here */
+       of_at91sam926x_pit_init();
 
        /*
         * Use our actual MCK to figure out how many MCK/16 ticks per
@@ -177,7 +230,9 @@ static void __init at91sam926x_pit_init(void)
        clocksource_register_hz(&pit_clk, pit_rate);
 
        /* Set up irq handler */
-       setup_irq(AT91_ID_SYS, &at91sam926x_pit_irq);
+       ret = setup_irq(at91sam926x_pit_irq.irq, &at91sam926x_pit_irq);
+       if (ret)
+               pr_crit("AT91: PIT: Unable to setup IRQ\n");
 
        /* Set up and register clockevents */
        pit_clkevt.mult = div_sc(pit_rate, NSEC_PER_SEC, pit_clkevt.shift);
@@ -193,6 +248,15 @@ static void at91sam926x_pit_suspend(void)
 
 void __init at91sam926x_ioremap_pit(u32 addr)
 {
+#if defined(CONFIG_OF)
+       struct device_node *np =
+               of_find_matching_node(NULL, pit_timer_ids);
+
+       if (np) {
+               of_node_put(np);
+               return;
+       }
+#endif
        pit_base_addr = ioremap(addr, 16);
 
        if (!pit_base_addr)
index 518e42377171c8fb25e5888c8863f7b363721a99..7af2e108b8a057d65deb5b49a725b3881e9b00cd 100644 (file)
 
 #include <linux/linkage.h>
 #include <mach/hardware.h>
-#include <mach/at91sam9_sdramc.h>
+#include <mach/at91_ramc.h>
 #include <mach/at91_rstc.h>
 
                        .arm
 
                        .globl  at91sam9_alt_restart
 
-at91sam9_alt_restart:  ldr     r0, .at91_va_base_sdramc        @ preload constants
-                       ldr     r1, =at91_rstc_base
-                       ldr     r1, [r1]
+at91sam9_alt_restart:  ldr     r0, =at91_ramc_base             @ preload constants
+                       ldr     r0, [r0]
+                       ldr     r4, =at91_rstc_base
+                       ldr     r1, [r4]
 
                        mov     r2, #1
                        mov     r3, #AT91_SDRAMC_LPCB_POWER_DOWN
@@ -37,6 +38,3 @@ at91sam9_alt_restart: ldr     r0, .at91_va_base_sdramc        @ preload constants
                        str     r4, [r1, #AT91_RSTC_CR]         @ reset processor
 
                        b       .
-
-.at91_va_base_sdramc:
-       .word AT91_VA_BASE_SYS + AT91_SDRAMC0
index 5b12192e52ecc59e8fde425146f8811469149179..df3bceacc86c13ce560135010deb7f1d54c5ef08 100644 (file)
@@ -229,6 +229,11 @@ static struct clk_lookup periph_clocks_lookups[] = {
        CLKDEV_CON_DEV_ID("usart", "fff90000.serial", &usart1_clk),
        CLKDEV_CON_DEV_ID("usart", "fff94000.serial", &usart2_clk),
        CLKDEV_CON_DEV_ID("usart", "fff98000.serial", &usart3_clk),
+       /* more tc lookup table for DT entries */
+       CLKDEV_CON_DEV_ID("t0_clk", "fff7c000.timer", &tcb0_clk),
+       CLKDEV_CON_DEV_ID("t0_clk", "fffd4000.timer", &tcb0_clk),
+       CLKDEV_CON_DEV_ID("hclk", "700000.ohci", &uhphs_clk),
+       CLKDEV_CON_DEV_ID("ehci_clk", "800000.ehci", &uhphs_clk),
        /* fake hclk clock */
        CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk),
        CLKDEV_CON_ID("pioA", &pioA_clk),
@@ -317,12 +322,6 @@ static struct at91_gpio_bank at91sam9g45_gpio[] __initdata = {
        }
 };
 
-static void at91sam9g45_idle(void)
-{
-       at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
-       cpu_do_idle();
-}
-
 /* --------------------------------------------------------------------
  *  AT91SAM9G45 processor initialization
  * -------------------------------------------------------------------- */
@@ -337,13 +336,16 @@ static void __init at91sam9g45_ioremap_registers(void)
 {
        at91_ioremap_shdwc(AT91SAM9G45_BASE_SHDWC);
        at91_ioremap_rstc(AT91SAM9G45_BASE_RSTC);
+       at91_ioremap_ramc(0, AT91SAM9G45_BASE_DDRSDRC1, 512);
+       at91_ioremap_ramc(1, AT91SAM9G45_BASE_DDRSDRC0, 512);
        at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT);
        at91sam9_ioremap_smc(0, AT91SAM9G45_BASE_SMC);
+       at91_ioremap_matrix(AT91SAM9G45_BASE_MATRIX);
 }
 
 static void __init at91sam9g45_initialize(void)
 {
-       arm_pm_idle = at91sam9g45_idle;
+       arm_pm_idle = at91sam9_idle;
        arm_pm_restart = at91sam9g45_restart;
        at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0);
 
index 96e2adcd5a841907be15beda7bdbb67dd87b5259..4320b2096789c73a4c5110af51324472f80890c4 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/dma-mapping.h>
 #include <linux/gpio.h>
+#include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/i2c-gpio.h>
 #include <linux/atmel-mci.h>
 #include <mach/board.h>
 #include <mach/at91sam9g45.h>
 #include <mach/at91sam9g45_matrix.h>
+#include <mach/at91_matrix.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/at_hdmac.h>
 #include <mach/atmel-mci.h>
 
+#include <media/atmel-isi.h>
+
 #include "generic.h"
+#include "clock.h"
 
 
 /* --------------------------------------------------------------------
@@ -553,8 +558,8 @@ void __init at91_add_device_nand(struct atmel_nand_data *data)
        if (!data)
                return;
 
-       csa = at91_sys_read(AT91_MATRIX_EBICSA);
-       at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
+       csa = at91_matrix_read(AT91_MATRIX_EBICSA);
+       at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
 
        /* enable pin */
        if (gpio_is_valid(data->enable_pin))
@@ -870,6 +875,96 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data)
 void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
 #endif
 
+/* --------------------------------------------------------------------
+ *  Image Sensor Interface
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_VIDEO_ATMEL_ISI) || defined(CONFIG_VIDEO_ATMEL_ISI_MODULE)
+static u64 isi_dmamask = DMA_BIT_MASK(32);
+static struct isi_platform_data isi_data;
+
+struct resource isi_resources[] = {
+       [0] = {
+               .start  = AT91SAM9G45_BASE_ISI,
+               .end    = AT91SAM9G45_BASE_ISI + SZ_16K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT91SAM9G45_ID_ISI,
+               .end    = AT91SAM9G45_ID_ISI,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device at91sam9g45_isi_device = {
+       .name           = "atmel_isi",
+       .id             = 0,
+       .dev            = {
+                       .dma_mask               = &isi_dmamask,
+                       .coherent_dma_mask      = DMA_BIT_MASK(32),
+                       .platform_data          = &isi_data,
+       },
+       .resource       = isi_resources,
+       .num_resources  = ARRAY_SIZE(isi_resources),
+};
+
+static struct clk_lookup isi_mck_lookups[] = {
+       CLKDEV_CON_DEV_ID("isi_mck", "atmel_isi.0", NULL),
+};
+
+void __init at91_add_device_isi(struct isi_platform_data *data,
+               bool use_pck_as_mck)
+{
+       struct clk *pck;
+       struct clk *parent;
+
+       if (!data)
+               return;
+       isi_data = *data;
+
+       at91_set_A_periph(AT91_PIN_PB20, 0);    /* ISI_D0 */
+       at91_set_A_periph(AT91_PIN_PB21, 0);    /* ISI_D1 */
+       at91_set_A_periph(AT91_PIN_PB22, 0);    /* ISI_D2 */
+       at91_set_A_periph(AT91_PIN_PB23, 0);    /* ISI_D3 */
+       at91_set_A_periph(AT91_PIN_PB24, 0);    /* ISI_D4 */
+       at91_set_A_periph(AT91_PIN_PB25, 0);    /* ISI_D5 */
+       at91_set_A_periph(AT91_PIN_PB26, 0);    /* ISI_D6 */
+       at91_set_A_periph(AT91_PIN_PB27, 0);    /* ISI_D7 */
+       at91_set_A_periph(AT91_PIN_PB28, 0);    /* ISI_PCK */
+       at91_set_A_periph(AT91_PIN_PB30, 0);    /* ISI_HSYNC */
+       at91_set_A_periph(AT91_PIN_PB29, 0);    /* ISI_VSYNC */
+       at91_set_B_periph(AT91_PIN_PB8, 0);     /* ISI_PD8 */
+       at91_set_B_periph(AT91_PIN_PB9, 0);     /* ISI_PD9 */
+       at91_set_B_periph(AT91_PIN_PB10, 0);    /* ISI_PD10 */
+       at91_set_B_periph(AT91_PIN_PB11, 0);    /* ISI_PD11 */
+
+       platform_device_register(&at91sam9g45_isi_device);
+
+       if (use_pck_as_mck) {
+               at91_set_B_periph(AT91_PIN_PB31, 0);    /* ISI_MCK (PCK1) */
+
+               pck = clk_get(NULL, "pck1");
+               parent = clk_get(NULL, "plla");
+
+               BUG_ON(IS_ERR(pck) || IS_ERR(parent));
+
+               if (clk_set_parent(pck, parent)) {
+                       pr_err("Failed to set PCK's parent\n");
+               } else {
+                       /* Register PCK as ISI_MCK */
+                       isi_mck_lookups[0].clk = pck;
+                       clkdev_add_table(isi_mck_lookups,
+                                       ARRAY_SIZE(isi_mck_lookups));
+               }
+
+               clk_put(pck);
+               clk_put(parent);
+       }
+}
+#else
+void __init at91_add_device_isi(struct isi_platform_data *data,
+               bool use_pck_as_mck) {}
+#endif
+
 
 /* --------------------------------------------------------------------
  *  LCD Controller
@@ -957,7 +1052,7 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
 static struct resource tcb0_resources[] = {
        [0] = {
                .start  = AT91SAM9G45_BASE_TCB0,
-               .end    = AT91SAM9G45_BASE_TCB0 + SZ_16K - 1,
+               .end    = AT91SAM9G45_BASE_TCB0 + SZ_256 - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -978,7 +1073,7 @@ static struct platform_device at91sam9g45_tcb0_device = {
 static struct resource tcb1_resources[] = {
        [0] = {
                .start  = AT91SAM9G45_BASE_TCB1,
-               .end    = AT91SAM9G45_BASE_TCB1 + SZ_16K - 1,
+               .end    = AT91SAM9G45_BASE_TCB1 + SZ_256 - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -995,8 +1090,25 @@ static struct platform_device at91sam9g45_tcb1_device = {
        .num_resources  = ARRAY_SIZE(tcb1_resources),
 };
 
+#if defined(CONFIG_OF)
+static struct of_device_id tcb_ids[] = {
+       { .compatible = "atmel,at91rm9200-tcb" },
+       { /*sentinel*/ }
+};
+#endif
+
 static void __init at91_add_device_tc(void)
 {
+#if defined(CONFIG_OF)
+       struct device_node *np;
+
+       np = of_find_matching_node(NULL, tcb_ids);
+       if (np) {
+               of_node_put(np);
+               return;
+       }
+#endif
+
        platform_device_register(&at91sam9g45_tcb0_device);
        platform_device_register(&at91sam9g45_tcb1_device);
 }
@@ -1099,6 +1211,8 @@ static struct resource rtt_resources[] = {
                .start  = AT91SAM9G45_BASE_RTT,
                .end    = AT91SAM9G45_BASE_RTT + SZ_16 - 1,
                .flags  = IORESOURCE_MEM,
+       }, {
+               .flags  = IORESOURCE_MEM,
        }
 };
 
@@ -1106,11 +1220,32 @@ static struct platform_device at91sam9g45_rtt_device = {
        .name           = "at91_rtt",
        .id             = 0,
        .resource       = rtt_resources,
-       .num_resources  = ARRAY_SIZE(rtt_resources),
 };
 
+#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9)
+static void __init at91_add_device_rtt_rtc(void)
+{
+       at91sam9g45_rtt_device.name = "rtc-at91sam9";
+       /*
+        * The second resource is needed:
+        * GPBR will serve as the storage for RTC time offset
+        */
+       at91sam9g45_rtt_device.num_resources = 2;
+       rtt_resources[1].start = AT91SAM9G45_BASE_GPBR +
+                                4 * CONFIG_RTC_DRV_AT91SAM9_GPBR;
+       rtt_resources[1].end = rtt_resources[1].start + 3;
+}
+#else
+static void __init at91_add_device_rtt_rtc(void)
+{
+       /* Only one resource is needed: RTT not used as RTC */
+       at91sam9g45_rtt_device.num_resources = 1;
+}
+#endif
+
 static void __init at91_add_device_rtt(void)
 {
+       at91_add_device_rtt_rtc();
        platform_device_register(&at91sam9g45_rtt_device);
 }
 
@@ -1565,7 +1700,6 @@ static inline void configure_usart3_pins(unsigned pins)
 }
 
 static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART];  /* the UARTs to use */
-struct platform_device *atmel_default_console_device;  /* the serial console device */
 
 void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
 {
index 0468be10980b57dce18e057817cf3879fb39a545..9d457182c86c73f7ab5d3a0daef884781a518bbb 100644 (file)
@@ -12,7 +12,7 @@
 
 #include <linux/linkage.h>
 #include <mach/hardware.h>
-#include <mach/at91sam9_ddrsdr.h>
+#include <mach/at91_ramc.h>
 #include <mach/at91_rstc.h>
 
                        .arm
                        .globl  at91sam9g45_restart
 
 at91sam9g45_restart:
-                       ldr     r0, .at91_va_base_sdramc0       @ preload constants
-                       ldr     r1, =at91_rstc_base
-                       ldr     r1, [r1]
+                       ldr     r5, =at91_ramc_base             @ preload constants
+                       ldr     r0, [r5]
+                       ldr     r4, =at91_rstc_base
+                       ldr     r1, [r4]
 
                        mov     r2, #1
                        mov     r3, #AT91_DDRSDRC_LPCB_POWER_DOWN
@@ -35,6 +36,3 @@ at91sam9g45_restart:
                        str     r4, [r1, #AT91_RSTC_CR]         @ reset processor
 
                        b       .
-
-.at91_va_base_sdramc0:
-       .word AT91_VA_BASE_SYS + AT91_DDRSDRC0
index fd60e226a987d1533504327dfe22e17a6a08b9d2..63d9372eb18efe2f9d476aa85c7d9e4f724ef4b7 100644 (file)
@@ -288,19 +288,15 @@ static void __init at91sam9rl_ioremap_registers(void)
 {
        at91_ioremap_shdwc(AT91SAM9RL_BASE_SHDWC);
        at91_ioremap_rstc(AT91SAM9RL_BASE_RSTC);
+       at91_ioremap_ramc(0, AT91SAM9RL_BASE_SDRAMC, 512);
        at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT);
        at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC);
-}
-
-static void at91sam9rl_idle(void)
-{
-       at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
-       cpu_do_idle();
+       at91_ioremap_matrix(AT91SAM9RL_BASE_MATRIX);
 }
 
 static void __init at91sam9rl_initialize(void)
 {
-       arm_pm_idle = at91sam9rl_idle;
+       arm_pm_idle = at91sam9_idle;
        arm_pm_restart = at91sam9_alt_restart;
        at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0);
 
index 9be71c11d0f098ddaadf4528cc2cdc1d17b52a3c..eda72e83037dc7dd176c859e7f4ad874a9506a75 100644 (file)
@@ -20,6 +20,7 @@
 #include <mach/board.h>
 #include <mach/at91sam9rl.h>
 #include <mach/at91sam9rl_matrix.h>
+#include <mach/at91_matrix.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/at_hdmac.h>
 
@@ -265,8 +266,8 @@ void __init at91_add_device_nand(struct atmel_nand_data *data)
        if (!data)
                return;
 
-       csa = at91_sys_read(AT91_MATRIX_EBICSA);
-       at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
+       csa = at91_matrix_read(AT91_MATRIX_EBICSA);
+       at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
 
        /* enable pin */
        if (gpio_is_valid(data->enable_pin))
@@ -682,6 +683,8 @@ static struct resource rtt_resources[] = {
                .start  = AT91SAM9RL_BASE_RTT,
                .end    = AT91SAM9RL_BASE_RTT + SZ_16 - 1,
                .flags  = IORESOURCE_MEM,
+       }, {
+               .flags  = IORESOURCE_MEM,
        }
 };
 
@@ -689,11 +692,32 @@ static struct platform_device at91sam9rl_rtt_device = {
        .name           = "at91_rtt",
        .id             = 0,
        .resource       = rtt_resources,
-       .num_resources  = ARRAY_SIZE(rtt_resources),
 };
 
+#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9)
+static void __init at91_add_device_rtt_rtc(void)
+{
+       at91sam9rl_rtt_device.name = "rtc-at91sam9";
+       /*
+        * The second resource is needed:
+        * GPBR will serve as the storage for RTC time offset
+        */
+       at91sam9rl_rtt_device.num_resources = 2;
+       rtt_resources[1].start = AT91SAM9RL_BASE_GPBR +
+                                4 * CONFIG_RTC_DRV_AT91SAM9_GPBR;
+       rtt_resources[1].end = rtt_resources[1].start + 3;
+}
+#else
+static void __init at91_add_device_rtt_rtc(void)
+{
+       /* Only one resource is needed: RTT not used as RTC */
+       at91sam9rl_rtt_device.num_resources = 1;
+}
+#endif
+
 static void __init at91_add_device_rtt(void)
 {
+       at91_add_device_rtt_rtc();
        platform_device_register(&at91sam9rl_rtt_device);
 }
 
@@ -1128,7 +1152,6 @@ static inline void configure_usart3_pins(unsigned pins)
 }
 
 static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART];  /* the UARTs to use */
-struct platform_device *atmel_default_console_device;  /* the serial console device */
 
 void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
 {
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c
new file mode 100644 (file)
index 0000000..b6831ee
--- /dev/null
@@ -0,0 +1,359 @@
+/*
+ *  Chip-specific setup code for the AT91SAM9x5 family
+ *
+ *  Copyright (C) 2010-2012 Atmel Corporation.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/at91sam9x5.h>
+#include <mach/at91_pmc.h>
+#include <mach/cpu.h>
+#include <mach/board.h>
+
+#include "soc.h"
+#include "generic.h"
+#include "clock.h"
+#include "sam9_smc.h"
+
+/* --------------------------------------------------------------------
+ *  Clocks
+ * -------------------------------------------------------------------- */
+
+/*
+ * The peripheral clocks.
+ */
+static struct clk pioAB_clk = {
+       .name           = "pioAB_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_PIOAB,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioCD_clk = {
+       .name           = "pioCD_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_PIOCD,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk smd_clk = {
+       .name           = "smd_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_SMD,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart0_clk = {
+       .name           = "usart0_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_USART0,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart1_clk = {
+       .name           = "usart1_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_USART1,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart2_clk = {
+       .name           = "usart2_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_USART2,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+/* USART3 clock - Only for sam9g25/sam9x25 */
+static struct clk usart3_clk = {
+       .name           = "usart3_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_USART3,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi0_clk = {
+       .name           = "twi0_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_TWI0,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi1_clk = {
+       .name           = "twi1_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_TWI1,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi2_clk = {
+       .name           = "twi2_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_TWI2,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc0_clk = {
+       .name           = "mci0_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_MCI0,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi0_clk = {
+       .name           = "spi0_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_SPI0,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi1_clk = {
+       .name           = "spi1_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_SPI1,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk uart0_clk = {
+       .name           = "uart0_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_UART0,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk uart1_clk = {
+       .name           = "uart1_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_UART1,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tcb0_clk = {
+       .name           = "tcb0_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_TCB,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pwm_clk = {
+       .name           = "pwm_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_PWM,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk adc_clk = {
+       .name           = "adc_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_ADC,
+       .type   = CLK_TYPE_PERIPHERAL,
+};
+static struct clk dma0_clk = {
+       .name           = "dma0_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_DMA0,
+       .type   = CLK_TYPE_PERIPHERAL,
+};
+static struct clk dma1_clk = {
+       .name           = "dma1_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_DMA1,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk uhphs_clk = {
+       .name           = "uhphs",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_UHPHS,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk udphs_clk = {
+       .name           = "udphs_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_UDPHS,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+/* emac0 clock - Only for sam9g25/sam9x25/sam9g35/sam9x35 */
+static struct clk macb0_clk = {
+       .name           = "pclk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_EMAC0,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+/* lcd clock - Only for sam9g15/sam9g35/sam9x35 */
+static struct clk lcdc_clk = {
+       .name           = "lcdc_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_LCDC,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+/* isi clock - Only for sam9g25 */
+static struct clk isi_clk = {
+       .name           = "isi_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_ISI,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc1_clk = {
+       .name           = "mci1_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_MCI1,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+/* emac1 clock - Only for sam9x25 */
+static struct clk macb1_clk = {
+       .name           = "pclk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_EMAC1,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc_clk = {
+       .name           = "ssc_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_SSC,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+/* can0 clock - Only for sam9x35 */
+static struct clk can0_clk = {
+       .name           = "can0_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_CAN0,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+/* can1 clock - Only for sam9x35 */
+static struct clk can1_clk = {
+       .name           = "can1_clk",
+       .pmc_mask       = 1 << AT91SAM9X5_ID_CAN1,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+
+static struct clk *periph_clocks[] __initdata = {
+       &pioAB_clk,
+       &pioCD_clk,
+       &smd_clk,
+       &usart0_clk,
+       &usart1_clk,
+       &usart2_clk,
+       &twi0_clk,
+       &twi1_clk,
+       &twi2_clk,
+       &mmc0_clk,
+       &spi0_clk,
+       &spi1_clk,
+       &uart0_clk,
+       &uart1_clk,
+       &tcb0_clk,
+       &pwm_clk,
+       &adc_clk,
+       &dma0_clk,
+       &dma1_clk,
+       &uhphs_clk,
+       &udphs_clk,
+       &mmc1_clk,
+       &ssc_clk,
+       // irq0
+};
+
+static struct clk_lookup periph_clocks_lookups[] = {
+       /* lookup table for DT entries */
+       CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
+       CLKDEV_CON_DEV_ID("usart", "f801c000.serial", &usart0_clk),
+       CLKDEV_CON_DEV_ID("usart", "f8020000.serial", &usart1_clk),
+       CLKDEV_CON_DEV_ID("usart", "f8024000.serial", &usart2_clk),
+       CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk),
+       CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb0_clk),
+       CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk),
+       CLKDEV_CON_ID("pioA", &pioAB_clk),
+       CLKDEV_CON_ID("pioB", &pioAB_clk),
+       CLKDEV_CON_ID("pioC", &pioCD_clk),
+       CLKDEV_CON_ID("pioD", &pioCD_clk),
+       /* additional fake clock for macb_hclk */
+       CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb0_clk),
+       CLKDEV_CON_DEV_ID("hclk", "f8030000.ethernet", &macb1_clk),
+       CLKDEV_CON_DEV_ID("hclk", "600000.ohci", &uhphs_clk),
+       CLKDEV_CON_DEV_ID("ohci_clk", "600000.ohci", &uhphs_clk),
+       CLKDEV_CON_DEV_ID("ehci_clk", "700000.ehci", &uhphs_clk),
+};
+
+/*
+ * The two programmable clocks.
+ * You must configure pin multiplexing to bring these signals out.
+ */
+static struct clk pck0 = {
+       .name           = "pck0",
+       .pmc_mask       = AT91_PMC_PCK0,
+       .type           = CLK_TYPE_PROGRAMMABLE,
+       .id             = 0,
+};
+static struct clk pck1 = {
+       .name           = "pck1",
+       .pmc_mask       = AT91_PMC_PCK1,
+       .type           = CLK_TYPE_PROGRAMMABLE,
+       .id             = 1,
+};
+
+static void __init at91sam9x5_register_clocks(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
+               clk_register(periph_clocks[i]);
+
+       clkdev_add_table(periph_clocks_lookups,
+                        ARRAY_SIZE(periph_clocks_lookups));
+
+       if (cpu_is_at91sam9g25()
+       || cpu_is_at91sam9x25())
+               clk_register(&usart3_clk);
+
+       if (cpu_is_at91sam9g25()
+       || cpu_is_at91sam9x25()
+       || cpu_is_at91sam9g35()
+       || cpu_is_at91sam9x35())
+               clk_register(&macb0_clk);
+
+       if (cpu_is_at91sam9g15()
+       || cpu_is_at91sam9g35()
+       || cpu_is_at91sam9x35())
+               clk_register(&lcdc_clk);
+
+       if (cpu_is_at91sam9g25())
+               clk_register(&isi_clk);
+
+       if (cpu_is_at91sam9x25())
+               clk_register(&macb1_clk);
+
+       if (cpu_is_at91sam9x25()
+       || cpu_is_at91sam9x35()) {
+               clk_register(&can0_clk);
+               clk_register(&can1_clk);
+       }
+
+       clk_register(&pck0);
+       clk_register(&pck1);
+}
+
+/* --------------------------------------------------------------------
+ *  AT91SAM9x5 processor initialization
+ * -------------------------------------------------------------------- */
+
+static void __init at91sam9x5_map_io(void)
+{
+       at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE);
+}
+
+void __init at91sam9x5_initialize(void)
+{
+       at91_extern_irq = (1 << AT91SAM9X5_ID_IRQ0);
+
+       /* Register GPIO subsystem (using DT) */
+       at91_gpio_init(NULL, 0);
+}
+
+/* --------------------------------------------------------------------
+ *  Interrupt initialization
+ * -------------------------------------------------------------------- */
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static unsigned int at91sam9x5_default_irq_priority[NR_AIC_IRQS] __initdata = {
+       7,      /* Advanced Interrupt Controller (FIQ) */
+       7,      /* System Peripherals */
+       1,      /* Parallel IO Controller A and B */
+       1,      /* Parallel IO Controller C and D */
+       4,      /* Soft Modem */
+       5,      /* USART 0 */
+       5,      /* USART 1 */
+       5,      /* USART 2 */
+       5,      /* USART 3 */
+       6,      /* Two-Wire Interface 0 */
+       6,      /* Two-Wire Interface 1 */
+       6,      /* Two-Wire Interface 2 */
+       0,      /* Multimedia Card Interface 0 */
+       5,      /* Serial Peripheral Interface 0 */
+       5,      /* Serial Peripheral Interface 1 */
+       5,      /* UART 0 */
+       5,      /* UART 1 */
+       0,      /* Timer Counter 0, 1, 2, 3, 4 and 5 */
+       0,      /* Pulse Width Modulation Controller */
+       0,      /* ADC Controller */
+       0,      /* DMA Controller 0 */
+       0,      /* DMA Controller 1 */
+       2,      /* USB Host High Speed port */
+       2,      /* USB Device High speed port */
+       3,      /* Ethernet MAC 0 */
+       3,      /* LDC Controller or Image Sensor Interface */
+       0,      /* Multimedia Card Interface 1 */
+       3,      /* Ethernet MAC 1 */
+       4,      /* Synchronous Serial Interface */
+       4,      /* CAN Controller 0 */
+       4,      /* CAN Controller 1 */
+       0,      /* Advanced Interrupt Controller (IRQ0) */
+};
+
+struct at91_init_soc __initdata at91sam9x5_soc = {
+       .map_io = at91sam9x5_map_io,
+       .default_irq_priority = at91sam9x5_default_irq_priority,
+       .register_clocks = at91sam9x5_register_clocks,
+       .init = at91sam9x5_initialize,
+};
index 0154b7f44ff199a72483c70a94dcffe11bfb60cf..5400a1d6503566d7258a801e6b8aca3e6c636021 100644 (file)
@@ -44,7 +44,7 @@ static void at91x40_idle(void)
         * Disable the processor clock.  The processor will be automatically
         * re-enabled by an interrupt or by a reset.
         */
-       at91_sys_write(AT91_PS_CR, AT91_PS_CR_CPU);
+       __raw_writel(AT91_PS_CR_CPU, AT91_PS_CR);
        cpu_do_idle();
 }
 
index dfff2895f4b286c4134a2a9f6425c90ce27e76ca..6ca680a1d5d112bb32cfa347c08c845f4d24ff6f 100644 (file)
 #include <asm/mach/time.h>
 #include <mach/at91_tc.h>
 
+#define at91_tc_read(field) \
+       __raw_readl(AT91_TC + field)
+
+#define at91_tc_write(field, value) \
+       __raw_writel(value, AT91_TC + field);
+
 /*
  *     3 counter/timer units present.
  */
 
 static unsigned long at91x40_gettimeoffset(void)
 {
-       return (at91_sys_read(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CV) * 1000000 / (AT91X40_MASTER_CLOCK / 128));
+       return (at91_tc_read(AT91_TC_CLK1BASE + AT91_TC_CV) * 1000000 / (AT91X40_MASTER_CLOCK / 128));
 }
 
 static irqreturn_t at91x40_timer_interrupt(int irq, void *dev_id)
 {
-       at91_sys_read(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_SR);
+       at91_tc_read(AT91_TC_CLK1BASE + AT91_TC_SR);
        timer_tick();
        return IRQ_HANDLED;
 }
@@ -57,20 +63,20 @@ void __init at91x40_timer_init(void)
 {
        unsigned int v;
 
-       at91_sys_write(AT91_TC + AT91_TC_BCR, 0);
-       v = at91_sys_read(AT91_TC + AT91_TC_BMR);
+       at91_tc_write(AT91_TC_BCR, 0);
+       v = at91_tc_read(AT91_TC_BMR);
        v = (v & ~AT91_TC_TC1XC1S) | AT91_TC_TC1XC1S_NONE;
-       at91_sys_write(AT91_TC + AT91_TC_BMR, v);
+       at91_tc_write(AT91_TC_BMR, v);
 
-       at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CCR, AT91_TC_CLKDIS);
-       at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CMR, (AT91_TC_TIMER_CLOCK4 | AT91_TC_CPCTRG));
-       at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_IDR, 0xffffffff);
-       at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_RC, (AT91X40_MASTER_CLOCK / 128) / HZ - 1);
-       at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_IER, (1<<4));
+       at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_CCR, AT91_TC_CLKDIS);
+       at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_CMR, (AT91_TC_TIMER_CLOCK4 | AT91_TC_CPCTRG));
+       at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_IDR, 0xffffffff);
+       at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_RC, (AT91X40_MASTER_CLOCK / 128) / HZ - 1);
+       at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_IER, (1<<4));
 
        setup_irq(AT91X40_ID_TC1, &at91x40_timer_irq);
 
-       at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CCR, (AT91_TC_SWTRG | AT91_TC_CLKEN));
+       at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_CCR, (AT91_TC_SWTRG | AT91_TC_CLKEN));
 }
 
 struct sys_timer at91x40_timer = {
index 3bb40694b02db20599fa4c87f2867b0513e1bff0..161efbaa10290fe31bb10e7f88692f6842fad231 100644 (file)
@@ -138,6 +138,7 @@ static struct atmel_nand_data __initdata afeb9260_nand_data = {
        .rdy_pin        = AT91_PIN_PC13,
        .enable_pin     = AT91_PIN_PC14,
        .bus_width_16   = 0,
+       .ecc_mode       = NAND_ECC_SOFT,
        .parts          = afeb9260_nand_partition,
        .num_parts      = ARRAY_SIZE(afeb9260_nand_partition),
        .det_pin        = -EINVAL,
index 8510e9e54988da5109a093689400cc724566a73f..c6d44ee0c77e7ad053267b4114ed04b1d73d8dfd 100644 (file)
@@ -140,6 +140,7 @@ static struct atmel_nand_data __initdata cam60_nand_data = {
        .det_pin        = -EINVAL,
        .rdy_pin        = AT91_PIN_PA9,
        .enable_pin     = AT91_PIN_PA7,
+       .ecc_mode       = NAND_ECC_SOFT,
        .parts          = cam60_nand_partition,
        .num_parts      = ARRAY_SIZE(cam60_nand_partition),
 };
diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c
deleted file mode 100644 (file)
index ac3de4f..0000000
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * linux/arch/arm/mach-at91/board-cap9adk.c
- *
- *  Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
- *  Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
- *  Copyright (C) 2005 SAN People
- *  Copyright (C) 2007 Atmel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/types.h>
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/ads7846.h>
-#include <linux/fb.h>
-#include <linux/mtd/physmap.h>
-
-#include <video/atmel_lcdc.h>
-
-#include <mach/hardware.h>
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/board.h>
-#include <mach/at91cap9_matrix.h>
-#include <mach/at91sam9_smc.h>
-#include <mach/system_rev.h>
-
-#include "sam9_smc.h"
-#include "generic.h"
-
-
-static void __init cap9adk_init_early(void)
-{
-       /* Initialize processor: 12 MHz crystal */
-       at91_initialize(12000000);
-
-       /* Setup the LEDs: USER1 and USER2 LED for cpu/timer... */
-       at91_init_leds(AT91_PIN_PA10, AT91_PIN_PA11);
-       /* ... POWER LED always on */
-       at91_set_gpio_output(AT91_PIN_PC29, 1);
-
-       /* Setup the serial ports and console */
-       at91_register_uart(0, 0, 0);            /* DBGU = ttyS0 */
-       at91_set_serial_console(0);
-}
-
-/*
- * USB Host port
- */
-static struct at91_usbh_data __initdata cap9adk_usbh_data = {
-       .ports          = 2,
-       .vbus_pin       = {-EINVAL, -EINVAL},
-       .overcurrent_pin= {-EINVAL, -EINVAL},
-};
-
-/*
- * USB HS Device port
- */
-static struct usba_platform_data __initdata cap9adk_usba_udc_data = {
-       .vbus_pin       = AT91_PIN_PB31,
-};
-
-/*
- * ADS7846 Touchscreen
- */
-#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
-static int ads7843_pendown_state(void)
-{
-       return !at91_get_gpio_value(AT91_PIN_PC4);      /* Touchscreen PENIRQ */
-}
-
-static struct ads7846_platform_data ads_info = {
-       .model                  = 7843,
-       .x_min                  = 150,
-       .x_max                  = 3830,
-       .y_min                  = 190,
-       .y_max                  = 3830,
-       .vref_delay_usecs       = 100,
-       .x_plate_ohms           = 450,
-       .y_plate_ohms           = 250,
-       .pressure_max           = 15000,
-       .debounce_max           = 1,
-       .debounce_rep           = 0,
-       .debounce_tol           = (~0),
-       .get_pendown_state      = ads7843_pendown_state,
-};
-
-static void __init cap9adk_add_device_ts(void)
-{
-       at91_set_gpio_input(AT91_PIN_PC4, 1);   /* Touchscreen PENIRQ */
-       at91_set_gpio_input(AT91_PIN_PC5, 1);   /* Touchscreen BUSY */
-}
-#else
-static void __init cap9adk_add_device_ts(void) {}
-#endif
-
-
-/*
- * SPI devices.
- */
-static struct spi_board_info cap9adk_spi_devices[] = {
-#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
-       {       /* DataFlash card */
-               .modalias       = "mtd_dataflash",
-               .chip_select    = 0,
-               .max_speed_hz   = 15 * 1000 * 1000,
-               .bus_num        = 0,
-       },
-#endif
-#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
-       {
-               .modalias       = "ads7846",
-               .chip_select    = 3,            /* can be 2 or 3, depending on J2 jumper */
-               .max_speed_hz   = 125000 * 26,  /* (max sample rate @ 3V) * (cmd + data + overhead) */
-               .bus_num        = 0,
-               .platform_data  = &ads_info,
-               .irq            = AT91_PIN_PC4,
-       },
-#endif
-};
-
-
-/*
- * MCI (SD/MMC)
- */
-static struct at91_mmc_data __initdata cap9adk_mmc_data = {
-       .wire4          = 1,
-       .det_pin        = -EINVAL,
-       .wp_pin         = -EINVAL,
-       .vcc_pin        = -EINVAL,
-};
-
-
-/*
- * MACB Ethernet device
- */
-static struct macb_platform_data __initdata cap9adk_macb_data = {
-       .phy_irq_pin    = -EINVAL,
-       .is_rmii        = 1,
-};
-
-
-/*
- * NAND flash
- */
-static struct mtd_partition __initdata cap9adk_nand_partitions[] = {
-       {
-               .name   = "NAND partition",
-               .offset = 0,
-               .size   = MTDPART_SIZ_FULL,
-       },
-};
-
-static struct atmel_nand_data __initdata cap9adk_nand_data = {
-       .ale            = 21,
-       .cle            = 22,
-       .det_pin        = -EINVAL,
-       .rdy_pin        = -EINVAL,
-       .enable_pin     = AT91_PIN_PD15,
-       .parts          = cap9adk_nand_partitions,
-       .num_parts      = ARRAY_SIZE(cap9adk_nand_partitions),
-};
-
-static struct sam9_smc_config __initdata cap9adk_nand_smc_config = {
-       .ncs_read_setup         = 1,
-       .nrd_setup              = 2,
-       .ncs_write_setup        = 1,
-       .nwe_setup              = 2,
-
-       .ncs_read_pulse         = 6,
-       .nrd_pulse              = 4,
-       .ncs_write_pulse        = 6,
-       .nwe_pulse              = 4,
-
-       .read_cycle             = 8,
-       .write_cycle            = 8,
-
-       .mode                   = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
-       .tdf_cycles             = 1,
-};
-
-static void __init cap9adk_add_device_nand(void)
-{
-       unsigned long csa;
-
-       csa = at91_sys_read(AT91_MATRIX_EBICSA);
-       at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V);
-
-       cap9adk_nand_data.bus_width_16 = board_have_nand_16bit();
-       /* setup bus-width (8 or 16) */
-       if (cap9adk_nand_data.bus_width_16)
-               cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_16;
-       else
-               cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_8;
-
-       /* configure chip-select 3 (NAND) */
-       sam9_smc_configure(0, 3, &cap9adk_nand_smc_config);
-
-       at91_add_device_nand(&cap9adk_nand_data);
-}
-
-
-/*
- * NOR flash
- */
-static struct mtd_partition cap9adk_nor_partitions[] = {
-       {
-               .name           = "NOR partition",
-               .offset         = 0,
-               .size           = MTDPART_SIZ_FULL,
-       },
-};
-
-static struct physmap_flash_data cap9adk_nor_data = {
-       .width          = 2,
-       .parts          = cap9adk_nor_partitions,
-       .nr_parts       = ARRAY_SIZE(cap9adk_nor_partitions),
-};
-
-#define NOR_BASE       AT91_CHIPSELECT_0
-#define NOR_SIZE       SZ_8M
-
-static struct resource nor_flash_resources[] = {
-       {
-               .start  = NOR_BASE,
-               .end    = NOR_BASE + NOR_SIZE - 1,
-               .flags  = IORESOURCE_MEM,
-       }
-};
-
-static struct platform_device cap9adk_nor_flash = {
-       .name           = "physmap-flash",
-       .id             = 0,
-       .dev            = {
-                               .platform_data  = &cap9adk_nor_data,
-       },
-       .resource       = nor_flash_resources,
-       .num_resources  = ARRAY_SIZE(nor_flash_resources),
-};
-
-static struct sam9_smc_config __initdata cap9adk_nor_smc_config = {
-       .ncs_read_setup         = 2,
-       .nrd_setup              = 4,
-       .ncs_write_setup        = 2,
-       .nwe_setup              = 4,
-
-       .ncs_read_pulse         = 10,
-       .nrd_pulse              = 8,
-       .ncs_write_pulse        = 10,
-       .nwe_pulse              = 8,
-
-       .read_cycle             = 16,
-       .write_cycle            = 16,
-
-       .mode                   = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | AT91_SMC_DBW_16,
-       .tdf_cycles             = 1,
-};
-
-static __init void cap9adk_add_device_nor(void)
-{
-       unsigned long csa;
-
-       csa = at91_sys_read(AT91_MATRIX_EBICSA);
-       at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V);
-
-       /* configure chip-select 0 (NOR) */
-       sam9_smc_configure(0, 0, &cap9adk_nor_smc_config);
-
-       platform_device_register(&cap9adk_nor_flash);
-}
-
-
-/*
- * LCD Controller
- */
-#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
-static struct fb_videomode at91_tft_vga_modes[] = {
-       {
-               .name           = "TX09D50VM1CCA @ 60",
-               .refresh        = 60,
-               .xres           = 240,          .yres           = 320,
-               .pixclock       = KHZ2PICOS(4965),
-
-               .left_margin    = 1,            .right_margin   = 33,
-               .upper_margin   = 1,            .lower_margin   = 0,
-               .hsync_len      = 5,            .vsync_len      = 1,
-
-               .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-               .vmode          = FB_VMODE_NONINTERLACED,
-       },
-};
-
-static struct fb_monspecs at91fb_default_monspecs = {
-       .manufacturer   = "HIT",
-       .monitor        = "TX09D70VM1CCA",
-
-       .modedb         = at91_tft_vga_modes,
-       .modedb_len     = ARRAY_SIZE(at91_tft_vga_modes),
-       .hfmin          = 15000,
-       .hfmax          = 64000,
-       .vfmin          = 50,
-       .vfmax          = 150,
-};
-
-#define AT91CAP9_DEFAULT_LCDCON2       (ATMEL_LCDC_MEMOR_LITTLE \
-                                       | ATMEL_LCDC_DISTYPE_TFT    \
-                                       | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
-
-static void at91_lcdc_power_control(int on)
-{
-       if (on)
-               at91_set_gpio_value(AT91_PIN_PC0, 0);   /* power up */
-       else
-               at91_set_gpio_value(AT91_PIN_PC0, 1);   /* power down */
-}
-
-/* Driver datas */
-static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data = {
-       .default_bpp                    = 16,
-       .default_dmacon                 = ATMEL_LCDC_DMAEN,
-       .default_lcdcon2                = AT91CAP9_DEFAULT_LCDCON2,
-       .default_monspecs               = &at91fb_default_monspecs,
-       .atmel_lcdfb_power_control      = at91_lcdc_power_control,
-       .guard_time                     = 1,
-};
-
-#else
-static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data;
-#endif
-
-
-/*
- * AC97
- */
-static struct ac97c_platform_data cap9adk_ac97_data = {
-       .reset_pin      = -EINVAL,
-};
-
-
-static void __init cap9adk_board_init(void)
-{
-       /* Serial */
-       at91_add_device_serial();
-       /* USB Host */
-       at91_add_device_usbh(&cap9adk_usbh_data);
-       /* USB HS */
-       at91_add_device_usba(&cap9adk_usba_udc_data);
-       /* SPI */
-       at91_add_device_spi(cap9adk_spi_devices, ARRAY_SIZE(cap9adk_spi_devices));
-       /* Touchscreen */
-       cap9adk_add_device_ts();
-       /* MMC */
-       at91_add_device_mmc(1, &cap9adk_mmc_data);
-       /* Ethernet */
-       at91_add_device_eth(&cap9adk_macb_data);
-       /* NAND */
-       cap9adk_add_device_nand();
-       /* NOR Flash */
-       cap9adk_add_device_nor();
-       /* I2C */
-       at91_add_device_i2c(NULL, 0);
-       /* LCD Controller */
-       at91_add_device_lcdc(&cap9adk_lcdc_data);
-       /* AC97 */
-       at91_add_device_ac97(&cap9adk_ac97_data);
-}
-
-MACHINE_START(AT91CAP9ADK, "Atmel AT91CAP9A-DK")
-       /* Maintainer: Stelian Pop <stelian.pop@leadtechdesign.com> */
-       .timer          = &at91sam926x_timer,
-       .map_io         = at91_map_io,
-       .init_early     = cap9adk_init_early,
-       .init_irq       = at91_init_irq_default,
-       .init_machine   = cap9adk_board_init,
-MACHINE_END
index 9ab3d1ea326d445bfe36bda16e37e47119a94f7a..5f3680e7c883e3a4e50b60ec22a5e283ecd78ed2 100644 (file)
@@ -43,6 +43,7 @@
 #include <mach/board.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/at91sam9260_matrix.h>
+#include <mach/at91_matrix.h>
 
 #include "sam9_smc.h"
 #include "generic.h"
@@ -116,6 +117,7 @@ static struct atmel_nand_data __initdata cpu9krea_nand_data = {
        .enable_pin     = AT91_PIN_PC14,
        .bus_width_16   = 0,
        .det_pin        = -EINVAL,
+       .ecc_mode       = NAND_ECC_SOFT,
 };
 
 #ifdef CONFIG_MACH_CPU9260
@@ -238,8 +240,8 @@ static __init void cpu9krea_add_device_nor(void)
 {
        unsigned long csa;
 
-       csa = at91_sys_read(AT91_MATRIX_EBICSA);
-       at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_VDDIOMSEL_3_3V);
+       csa = at91_matrix_read(AT91_MATRIX_EBICSA);
+       at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_VDDIOMSEL_3_3V);
 
        /* configure chip-select 0 (NOR) */
        sam9_smc_configure(0, 0, &cpu9krea_nor_smc_config);
index 368e1427ad998af7be547ed2689c6b5a0d0aacf4..e094cc81fe251d099fc31ceef5af8d9d2bfe1dd0 100644 (file)
@@ -38,6 +38,7 @@
 
 #include <mach/board.h>
 #include <mach/at91rm9200_mc.h>
+#include <mach/at91_ramc.h>
 #include <mach/cpu.h>
 
 #include "generic.h"
index bb6b434ec0c1c6c868be388603f7b63cfe37b01b..c18d4d3078012d584ec75aa927bcbebe8a1b4a23 100644 (file)
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/gpio.h>
-#include <linux/irqdomain.h>
+#include <linux/of.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 
-#include <mach/hardware.h>
 #include <mach/board.h>
-#include <mach/system_rev.h>
-#include <mach/at91sam9_smc.h>
 
 #include <asm/setup.h>
 #include <asm/irq.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include "sam9_smc.h"
 #include "generic.h"
 
 
-static void __init ek_init_early(void)
-{
-       /* Initialize processor: 12.000 MHz crystal */
-       at91_initialize(12000000);
-
-       /* DGBU on ttyS0. (Rx & Tx only) */
-       at91_register_uart(0, 0, 0);
-
-       /* set serial console to ttyS0 (ie, DBGU) */
-       at91_set_serial_console(0);
-}
-
-/* det_pin is not connected */
-static struct atmel_nand_data __initdata ek_nand_data = {
-       .ale            = 21,
-       .cle            = 22,
-       .det_pin        = -EINVAL,
-       .rdy_pin        = AT91_PIN_PC8,
-       .enable_pin     = AT91_PIN_PC14,
-};
-
-static struct sam9_smc_config __initdata ek_nand_smc_config = {
-       .ncs_read_setup         = 0,
-       .nrd_setup              = 2,
-       .ncs_write_setup        = 0,
-       .nwe_setup              = 2,
-
-       .ncs_read_pulse         = 4,
-       .nrd_pulse              = 4,
-       .ncs_write_pulse        = 4,
-       .nwe_pulse              = 4,
-
-       .read_cycle             = 7,
-       .write_cycle            = 7,
+static const struct of_device_id irq_of_match[] __initconst = {
 
-       .mode                   = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
-       .tdf_cycles             = 3,
-};
-
-static void __init ek_add_device_nand(void)
-{
-       ek_nand_data.bus_width_16 = board_have_nand_16bit();
-       /* setup bus-width (8 or 16) */
-       if (ek_nand_data.bus_width_16)
-               ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
-       else
-               ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
-
-       /* configure chip-select 3 (NAND) */
-       sam9_smc_configure(0, 3, &ek_nand_smc_config);
-
-       at91_add_device_nand(&ek_nand_data);
-}
-
-static const struct of_device_id aic_of_match[] __initconst = {
-       { .compatible = "atmel,at91rm9200-aic", },
-       {},
+       { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init },
+       { .compatible = "atmel,at91rm9200-gpio", .data = at91_gpio_of_irq_setup },
+       { .compatible = "atmel,at91sam9x5-gpio", .data = at91_gpio_of_irq_setup },
+       { /*sentinel*/ }
 };
 
 static void __init at91_dt_init_irq(void)
 {
-       irq_domain_generate_simple(aic_of_match, 0xfffff000, 0);
-       at91_init_irq_default();
+       of_irq_init(irq_of_match);
 }
 
 static void __init at91_dt_device_init(void)
 {
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-
-       /* NAND */
-       ek_add_device_nand();
 }
 
 static const char *at91_dt_board_compat[] __initdata = {
        "atmel,at91sam9m10g45ek",
+       "atmel,at91sam9x5ek",
        "calao,usb-a9g20",
        NULL
 };
@@ -117,7 +59,7 @@ DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)")
        /* Maintainer: Atmel */
        .timer          = &at91sam926x_timer,
        .map_io         = at91_map_io,
-       .init_early     = ek_init_early,
+       .init_early     = at91_dt_initialize,
        .init_irq       = at91_dt_init_irq,
        .init_machine   = at91_dt_device_init,
        .dt_compat      = at91_dt_board_compat,
index 07ef35b0ec2cdceecf7e124e705cb842c31b1b62..f23aabef8551d69fc395dcf88b5eabdf152fe2f8 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <mach/board.h>
 #include <mach/at91rm9200_mc.h>
+#include <mach/at91_ramc.h>
 #include <mach/cpu.h>
 
 #include "generic.h"
@@ -110,7 +111,7 @@ static void __init eco920_board_init(void)
        at91_add_device_mmc(0, &eco920_mmc_data);
        platform_device_register(&eco920_flash);
 
-       at91_sys_write(AT91_SMC_CSR(7), AT91_SMC_RWHOLD_(1)
+       at91_ramc_write(0, AT91_SMC_CSR(7),     AT91_SMC_RWHOLD_(1)
                                | AT91_SMC_RWSETUP_(1)
                                | AT91_SMC_DBW_8
                                | AT91_SMC_WSEN
@@ -122,7 +123,7 @@ static void __init eco920_board_init(void)
        at91_set_deglitch(AT91_PIN_PA23, 1);
 
 /* Initialization of the Static Memory Controller for Chip Select 3 */
-       at91_sys_write(AT91_SMC_CSR(3),
+       at91_ramc_write(0, AT91_SMC_CSR(3),
                AT91_SMC_DBW_16  |      /* 16 bit */
                AT91_SMC_WSEN    |
                AT91_SMC_NWS_(5) |      /* wait states */
index eec02cd57ced7fe60291f8938a64259f61b0f22a..1815152001f74c62d3d4dd409252a2c81aa197b0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * linux/arch/arm/mach-at91/board-flexibity.c
  *
- *  Copyright (C) 2010 Flexibity
+ *  Copyright (C) 2010-2011 Flexibity
  *  Copyright (C) 2005 SAN People
  *  Copyright (C) 2006 Atmel
  *
@@ -62,6 +62,13 @@ static struct at91_udc_data __initdata flexibity_udc_data = {
        .pullup_pin     = -EINVAL,              /* pull-up driven by UDC */
 };
 
+/* I2C devices */
+static struct i2c_board_info __initdata flexibity_i2c_devices[] = {
+       {
+               I2C_BOARD_INFO("ds1307", 0x68),
+       },
+};
+
 /* SPI devices */
 static struct spi_board_info flexibity_spi_devices[] = {
        {       /* DataFlash chip */
@@ -141,6 +148,9 @@ static void __init flexibity_board_init(void)
        at91_add_device_usbh(&flexibity_usbh_data);
        /* USB Device */
        at91_add_device_udc(&flexibity_udc_data);
+       /* I2C */
+       at91_add_device_i2c(flexibity_i2c_devices,
+               ARRAY_SIZE(flexibity_i2c_devices));
        /* SPI */
        at91_add_device_spi(flexibity_spi_devices,
                ARRAY_SIZE(flexibity_spi_devices));
index d75a4a2ad9c20bc9d1e13067c5f6db4d689bbc9c..59b92aab9bcf8eb94a52d9806716995160f3bbe1 100644 (file)
@@ -38,6 +38,7 @@
 #include <mach/board.h>
 #include <mach/cpu.h>
 #include <mach/at91rm9200_mc.h>
+#include <mach/at91_ramc.h>
 
 #include "generic.h"
 
@@ -107,6 +108,7 @@ static struct atmel_nand_data __initdata kb9202_nand_data = {
        .det_pin        = -EINVAL,
        .rdy_pin        = AT91_PIN_PC29,
        .enable_pin     = AT91_PIN_PC28,
+       .ecc_mode       = NAND_ECC_SOFT,
        .parts          = kb9202_nand_partition,
        .num_parts      = ARRAY_SIZE(kb9202_nand_partition),
 };
index 3f8617c0e04e27849634c168e34ff2a6b7305e36..57d5f6a4726a5b38fead2eebd2b567c02b72e3eb 100644 (file)
@@ -190,6 +190,7 @@ static struct atmel_nand_data __initdata neocore926_nand_data = {
        .rdy_pin                = AT91_PIN_PB19,
        .rdy_pin_active_low     = 1,
        .enable_pin             = AT91_PIN_PD15,
+       .ecc_mode               = NAND_ECC_SOFT,
        .parts                  = neocore926_nand_partition,
        .num_parts              = ARRAY_SIZE(neocore926_nand_partition),
        .det_pin                = -EINVAL,
index ab024fa11d5c7d1011086070178b1e7dc3f04ca6..59e35dd1486301b556f20befed659a5bea9525b2 100644 (file)
@@ -39,6 +39,7 @@
 
 #include <mach/board.h>
 #include <mach/at91rm9200_mc.h>
+#include <mach/at91_ramc.h>
 
 #include "generic.h"
 
index e029d220cb84d4befab36f98fa0b1104da6461a2..b6ed5ed7081ac9d514336a19f3ca668ce8776d5e 100644 (file)
@@ -138,6 +138,8 @@ static struct atmel_nand_data __initdata ek_nand_data = {
        .det_pin        = -EINVAL,
        .rdy_pin        = AT91_PIN_PC13,
        .enable_pin     = AT91_PIN_PC14,
+       .ecc_mode       = NAND_ECC_SOFT,
+       .on_flash_bbt   = 1,
        .parts          = ek_nand_partition,
        .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
index 782f37946af5b561ea066d491ce51f4cd645c44e..01332aa538b2a00cb4a7e38207abd1a387e87ec7 100644 (file)
@@ -41,6 +41,7 @@
 #include <mach/hardware.h>
 #include <mach/board.h>
 #include <mach/at91rm9200_mc.h>
+#include <mach/at91_ramc.h>
 
 #include "generic.h"
 
@@ -149,6 +150,8 @@ static struct atmel_nand_data __initdata dk_nand_data = {
        .det_pin        = AT91_PIN_PB1,
        .rdy_pin        = AT91_PIN_PC2,
        .enable_pin     = -EINVAL,
+       .ecc_mode       = NAND_ECC_SOFT,
+       .on_flash_bbt   = 1,
        .parts          = dk_nand_partition,
        .num_parts      = ARRAY_SIZE(dk_nand_partition),
 };
index ef7c12a922464d3accbd06e263a2e548115906ac..11cbaa8946fe0e269877104aac08da9fe03818e9 100644 (file)
@@ -41,6 +41,7 @@
 #include <mach/hardware.h>
 #include <mach/board.h>
 #include <mach/at91rm9200_mc.h>
+#include <mach/at91_ramc.h>
 
 #include "generic.h"
 
index 84bce587735fd408f1c34e39ee615e82f6bb92bd..e8b116b6cba6c3c15dc873d41079c6f2519efdb8 100644 (file)
@@ -139,6 +139,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
        .det_pin        = -EINVAL,
        .rdy_pin        = AT91_PIN_PC13,
        .enable_pin     = AT91_PIN_PC14,
+       .ecc_mode       = NAND_ECC_SOFT,
        .parts          = ek_nand_partition,
        .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
index be8233bcabdcc1d56b96bf632b8a91dfd6c97a47..d5aec55b0eb4903a06c6045169cd21af24bb3824 100644 (file)
@@ -181,6 +181,8 @@ static struct atmel_nand_data __initdata ek_nand_data = {
        .det_pin        = -EINVAL,
        .rdy_pin        = AT91_PIN_PC13,
        .enable_pin     = AT91_PIN_PC14,
+       .ecc_mode       = NAND_ECC_SOFT,
+       .on_flash_bbt   = 1,
        .parts          = ek_nand_partition,
        .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
index 40895072a1a754c520608427faa5fdfe708a0fdf..c3f9944628642050c34c0a5f31388854511921e4 100644 (file)
@@ -187,6 +187,8 @@ static struct atmel_nand_data __initdata ek_nand_data = {
        .det_pin        = -EINVAL,
        .rdy_pin        = AT91_PIN_PC15,
        .enable_pin     = AT91_PIN_PC14,
+       .ecc_mode       = NAND_ECC_SOFT,
+       .on_flash_bbt   = 1,
        .parts          = ek_nand_partition,
        .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
index 29f66052fe63b57d275cc40ae694b1f0199b83bf..66f0ddf4b2ae416102626e02514a660576164d22 100644 (file)
@@ -187,6 +187,8 @@ static struct atmel_nand_data __initdata ek_nand_data = {
        .det_pin        = -EINVAL,
        .rdy_pin        = AT91_PIN_PA22,
        .enable_pin     = AT91_PIN_PD15,
+       .ecc_mode       = NAND_ECC_SOFT,
+       .on_flash_bbt   = 1,
        .parts          = ek_nand_partition,
        .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
index 843d6286c6f452bc6f84dd2b2f7b5fe43b16f6a0..8923ec9f5831b79ab8efc14b86ff1718f222f1fa 100644 (file)
@@ -166,6 +166,8 @@ static struct atmel_nand_data __initdata ek_nand_data = {
        .rdy_pin        = AT91_PIN_PC13,
        .enable_pin     = AT91_PIN_PC14,
        .det_pin        = -EINVAL,
+       .ecc_mode       = NAND_ECC_SOFT,
+       .on_flash_bbt   = 1,
        .parts          = ek_nand_partition,
        .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
index ea0d1b9c2b7bd0327326a227509f7d4f1c896263..e1bea73e6b30bb3e0c3c9f192a42c9eeb0b0da0c 100644 (file)
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/leds.h>
-#include <linux/clk.h>
 #include <linux/atmel-mci.h>
+#include <linux/delay.h>
 
 #include <mach/hardware.h>
 #include <video/atmel_lcdc.h>
+#include <media/soc_camera.h>
+#include <media/atmel-isi.h>
 
 #include <asm/setup.h>
 #include <asm/mach-types.h>
@@ -146,6 +148,8 @@ static struct atmel_nand_data __initdata ek_nand_data = {
        .rdy_pin        = AT91_PIN_PC8,
        .enable_pin     = AT91_PIN_PC14,
        .det_pin        = -EINVAL,
+       .ecc_mode       = NAND_ECC_SOFT,
+       .on_flash_bbt   = 1,
        .parts          = ek_nand_partition,
        .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
@@ -184,6 +188,71 @@ static void __init ek_add_device_nand(void)
 }
 
 
+/*
+ *  ISI
+ */
+static struct isi_platform_data __initdata isi_data = {
+       .frate                  = ISI_CFG1_FRATE_CAPTURE_ALL,
+       /* to use codec and preview path simultaneously */
+       .full_mode              = 1,
+       .data_width_flags       = ISI_DATAWIDTH_8 | ISI_DATAWIDTH_10,
+       /* ISI_MCK is provided by programmable clock or external clock */
+       .mck_hz                 = 25000000,
+};
+
+
+/*
+ * soc-camera OV2640
+ */
+#if defined(CONFIG_SOC_CAMERA_OV2640) || \
+       defined(CONFIG_SOC_CAMERA_OV2640_MODULE)
+static unsigned long isi_camera_query_bus_param(struct soc_camera_link *link)
+{
+       /* ISI board for ek using default 8-bits connection */
+       return SOCAM_DATAWIDTH_8;
+}
+
+static int i2c_camera_power(struct device *dev, int on)
+{
+       /* enable or disable the camera */
+       pr_debug("%s: %s the camera\n", __func__, on ? "ENABLE" : "DISABLE");
+       at91_set_gpio_output(AT91_PIN_PD13, !on);
+
+       if (!on)
+               goto out;
+
+       /* If enabled, give a reset impulse */
+       at91_set_gpio_output(AT91_PIN_PD12, 0);
+       msleep(20);
+       at91_set_gpio_output(AT91_PIN_PD12, 1);
+       msleep(100);
+
+out:
+       return 0;
+}
+
+static struct i2c_board_info i2c_camera = {
+       I2C_BOARD_INFO("ov2640", 0x30),
+};
+
+static struct soc_camera_link iclink_ov2640 = {
+       .bus_id                 = 0,
+       .board_info             = &i2c_camera,
+       .i2c_adapter_id         = 0,
+       .power                  = i2c_camera_power,
+       .query_bus_param        = isi_camera_query_bus_param,
+};
+
+static struct platform_device isi_ov2640 = {
+       .name   = "soc-camera-pdrv",
+       .id     = 0,
+       .dev    = {
+               .platform_data = &iclink_ov2640,
+       },
+};
+#endif
+
+
 /*
  * LCD Controller
  */
@@ -377,7 +446,12 @@ static struct gpio_led ek_pwm_led[] = {
 #endif
 };
 
-
+static struct platform_device *devices[] __initdata = {
+#if defined(CONFIG_SOC_CAMERA_OV2640) || \
+       defined(CONFIG_SOC_CAMERA_OV2640_MODULE)
+       &isi_ov2640,
+#endif
+};
 
 static void __init ek_board_init(void)
 {
@@ -399,6 +473,8 @@ static void __init ek_board_init(void)
        ek_add_device_nand();
        /* I2C */
        at91_add_device_i2c(0, NULL, 0);
+       /* ISI, using programmable clock as ISI_MCK */
+       at91_add_device_isi(&isi_data, true);
        /* LCD Controller */
        at91_add_device_lcdc(&ek_lcdc_data);
        /* Touch Screen */
@@ -410,6 +486,8 @@ static void __init ek_board_init(void)
        /* LEDs */
        at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
        at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
+       /* Other platform devices */
+       platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
 MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK")
index c1366d0032bf46a7bcafedaac099b1b6f6210b6e..b109ce2ba864640f8eee20dfebc3d4813fb58e3d 100644 (file)
@@ -94,6 +94,8 @@ static struct atmel_nand_data __initdata ek_nand_data = {
        .det_pin        = -EINVAL,
        .rdy_pin        = AT91_PIN_PD17,
        .enable_pin     = AT91_PIN_PB6,
+       .ecc_mode       = NAND_ECC_SOFT,
+       .on_flash_bbt   = 1,
        .parts          = ek_nand_partition,
        .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
index 4770db08e5a6c1895b52794d02eba84b499da56c..ebc9d01ce742f26bed12f958647934bc378c46c0 100644 (file)
@@ -110,6 +110,7 @@ static struct atmel_nand_data __initdata snapper9260_nand_data = {
        .bus_width_16   = 0,
        .enable_pin     = -EINVAL,
        .det_pin        = -EINVAL,
+       .ecc_mode       = NAND_ECC_SOFT,
 };
 
 static struct sam9_smc_config __initdata snapper9260_nand_smc_config = {
@@ -145,11 +146,11 @@ static struct i2c_board_info __initdata snapper9260_i2c_devices[] = {
                /* Audio codec */
                I2C_BOARD_INFO("tlv320aic23", 0x1a),
        },
-       {
+};
+
+static struct i2c_board_info __initdata snapper9260_i2c_isl1208 = {
                /* RTC */
                I2C_BOARD_INFO("isl1208", 0x6f),
-               .irq = gpio_to_irq(AT91_PIN_PA31),
-       },
 };
 
 static void __init snapper9260_add_device_nand(void)
@@ -163,6 +164,10 @@ static void __init snapper9260_board_init(void)
 {
        at91_add_device_i2c(snapper9260_i2c_devices,
                            ARRAY_SIZE(snapper9260_i2c_devices));
+
+       snapper9260_i2c_isl1208.irq = gpio_to_irq(AT91_PIN_PA31);
+       i2c_register_board_info(0, &snapper9260_i2c_isl1208, 1);
+
        at91_add_device_serial();
        at91_add_device_usbh(&snapper9260_usbh_data);
        at91_add_device_udc(&snapper9260_udc_data);
index 72eb3b4d9ab6f800b9edc49c38a17defb0b61897..7640049410a04b505ba7fd9f55d7ebfbb5aa1538 100644 (file)
@@ -86,6 +86,7 @@ static struct atmel_nand_data __initdata nand_data = {
        .enable_pin     = AT91_PIN_PC14,
        .bus_width_16   = 0,
        .det_pin        = -EINVAL,
+       .ecc_mode       = NAND_ECC_SOFT,
 };
 
 static struct sam9_smc_config __initdata nand_smc_config = {
index 26c36fc2d1e539b8c0c5d31ffd281a32f9ba587d..b7483a3d09803183e625844140659cc363f652a0 100644 (file)
@@ -198,6 +198,8 @@ static struct atmel_nand_data __initdata ek_nand_data = {
        .det_pin        = -EINVAL,
        .rdy_pin        = AT91_PIN_PA22,
        .enable_pin     = AT91_PIN_PD15,
+       .ecc_mode       = NAND_ECC_SOFT,
+       .on_flash_bbt   = 1,
        .parts          = ek_nand_partition,
        .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
index bbd553e1cd93d024cc4b8c5931f989c3a5becbfa..38dd279d30b25657004177bfa488b4906d4c525d 100644 (file)
@@ -45,6 +45,7 @@
 #include <mach/hardware.h>
 #include <mach/board.h>
 #include <mach/at91rm9200_mc.h>
+#include <mach/at91_ramc.h>
 #include <mach/cpu.h>
 
 #include "generic.h"
@@ -181,6 +182,7 @@ static struct atmel_nand_data __initdata yl9200_nand_data = {
        .det_pin        = -EINVAL,
        .rdy_pin        = AT91_PIN_PC14,        /* R/!B (Sheet10) */
        .enable_pin     = AT91_PIN_PC15,        /* !CE  (Sheet10) */
+       .ecc_mode       = NAND_ECC_SOFT,
        .parts          = yl9200_nand_partition,
        .num_parts      = ARRAY_SIZE(yl9200_nand_partition),
 };
@@ -393,7 +395,7 @@ static void yl9200_init_video(void)
        at91_set_A_periph(AT91_PIN_PC6, 0);
 
        /* Initialization of the Static Memory Controller for Chip Select 2 */
-       at91_sys_write(AT91_SMC_CSR(2), AT91_SMC_DBW_16         /* 16 bit */
+       at91_ramc_write(0, AT91_SMC_CSR(2), AT91_SMC_DBW_16             /* 16 bit */
                        | AT91_SMC_WSEN | AT91_SMC_NWS_(0x4)    /* wait states */
                        | AT91_SMC_TDF_(0x100)                  /* float time */
        );
index 61873f3aa92d74f2aaa327a4f0e7d0021f502d02..a0f4d7424cdcf4cfbebbc0c81185fb615862e9b5 100644 (file)
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/of_address.h>
 
 #include <mach/hardware.h>
 #include <mach/at91_pmc.h>
 #include <mach/cpu.h>
 
+#include <asm/proc-fns.h>
+
 #include "clock.h"
 #include "generic.h"
 
+void __iomem *at91_pmc_base;
 
 /*
  * There's a lot more which can be done with clocks, including cpufreq
 /*
  * Chips have some kind of clocks : group them by functionality
  */
-#define cpu_has_utmi()         (  cpu_is_at91cap9() \
-                               || cpu_is_at91sam9rl() \
-                               || cpu_is_at91sam9g45())
+#define cpu_has_utmi()         (  cpu_is_at91sam9rl() \
+                               || cpu_is_at91sam9g45() \
+                               || cpu_is_at91sam9x5())
 
 #define cpu_has_800M_plla()    (  cpu_is_at91sam9g20() \
-                               || cpu_is_at91sam9g45())
+                               || cpu_is_at91sam9g45() \
+                               || cpu_is_at91sam9x5())
 
 #define cpu_has_300M_plla()    (cpu_is_at91sam9g10())
 
 #define cpu_has_pllb()         (!(cpu_is_at91sam9rl() \
-                               || cpu_is_at91sam9g45()))
+                               || cpu_is_at91sam9g45() \
+                               || cpu_is_at91sam9x5()))
 
-#define cpu_has_upll()         (cpu_is_at91sam9g45())
+#define cpu_has_upll()         (cpu_is_at91sam9g45() \
+                               || cpu_is_at91sam9x5())
 
 /* USB host HS & FS */
 #define cpu_has_uhp()          (!cpu_is_at91sam9rl())
 
 /* USB device FS only */
 #define cpu_has_udpfs()                (!(cpu_is_at91sam9rl() \
-                               || cpu_is_at91sam9g45()))
+                               || cpu_is_at91sam9g45() \
+                               || cpu_is_at91sam9x5()))
+
+#define cpu_has_plladiv2()     (cpu_is_at91sam9g45() \
+                               || cpu_is_at91sam9x5())
+
+#define cpu_has_mdiv3()                (cpu_is_at91sam9g45() \
+                               || cpu_is_at91sam9x5())
+
+#define cpu_has_alt_prescaler()        (cpu_is_at91sam9x5())
 
 static LIST_HEAD(clocks);
 static DEFINE_SPINLOCK(clk_lock);
@@ -111,11 +127,11 @@ static void pllb_mode(struct clk *clk, int is_on)
                value = 0;
 
        // REVISIT: Add work-around for AT91RM9200 Errata #26 ?
-       at91_sys_write(AT91_CKGR_PLLBR, value);
+       at91_pmc_write(AT91_CKGR_PLLBR, value);
 
        do {
                cpu_relax();
-       } while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != is_on);
+       } while ((at91_pmc_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != is_on);
 }
 
 static struct clk pllb = {
@@ -130,31 +146,24 @@ static struct clk pllb = {
 static void pmc_sys_mode(struct clk *clk, int is_on)
 {
        if (is_on)
-               at91_sys_write(AT91_PMC_SCER, clk->pmc_mask);
+               at91_pmc_write(AT91_PMC_SCER, clk->pmc_mask);
        else
-               at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask);
+               at91_pmc_write(AT91_PMC_SCDR, clk->pmc_mask);
 }
 
 static void pmc_uckr_mode(struct clk *clk, int is_on)
 {
-       unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR);
-
-       if (cpu_is_at91sam9g45()) {
-               if (is_on)
-                       uckr |= AT91_PMC_BIASEN;
-               else
-                       uckr &= ~AT91_PMC_BIASEN;
-       }
+       unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR);
 
        if (is_on) {
                is_on = AT91_PMC_LOCKU;
-               at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask);
+               at91_pmc_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask);
        } else
-               at91_sys_write(AT91_CKGR_UCKR, uckr & ~(clk->pmc_mask));
+               at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(clk->pmc_mask));
 
        do {
                cpu_relax();
-       } while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKU) != is_on);
+       } while ((at91_pmc_read(AT91_PMC_SR) & AT91_PMC_LOCKU) != is_on);
 }
 
 /* USB function clocks (PLLB must be 48 MHz) */
@@ -190,9 +199,9 @@ struct clk mck = {
 static void pmc_periph_mode(struct clk *clk, int is_on)
 {
        if (is_on)
-               at91_sys_write(AT91_PMC_PCER, clk->pmc_mask);
+               at91_pmc_write(AT91_PMC_PCER, clk->pmc_mask);
        else
-               at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask);
+               at91_pmc_write(AT91_PMC_PCDR, clk->pmc_mask);
 }
 
 static struct clk __init *at91_css_to_clk(unsigned long css)
@@ -210,11 +219,24 @@ static struct clk __init *at91_css_to_clk(unsigned long css)
                                return &utmi_clk;
                        else if (cpu_has_pllb())
                                return &pllb;
+                       break;
+               /* alternate PMC: can use master clock */
+               case AT91_PMC_CSS_MASTER:
+                       return &mck;
        }
 
        return NULL;
 }
 
+static int pmc_prescaler_divider(u32 reg)
+{
+       if (cpu_has_alt_prescaler()) {
+               return 1 << ((reg & AT91_PMC_ALT_PRES) >> PMC_ALT_PRES_OFFSET);
+       } else {
+               return 1 << ((reg & AT91_PMC_PRES) >> PMC_PRES_OFFSET);
+       }
+}
+
 static void __clk_enable(struct clk *clk)
 {
        if (clk->parent)
@@ -316,12 +338,22 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 {
        unsigned long   flags;
        unsigned        prescale;
+       unsigned long   prescale_offset, css_mask;
        unsigned long   actual;
 
        if (!clk_is_programmable(clk))
                return -EINVAL;
        if (clk->users)
                return -EBUSY;
+
+       if (cpu_has_alt_prescaler()) {
+               prescale_offset = PMC_ALT_PRES_OFFSET;
+               css_mask = AT91_PMC_ALT_PCKR_CSS;
+       } else {
+               prescale_offset = PMC_PRES_OFFSET;
+               css_mask = AT91_PMC_CSS;
+       }
+
        spin_lock_irqsave(&clk_lock, flags);
 
        actual = clk->parent->rate_hz;
@@ -329,10 +361,10 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
                if (actual && actual <= rate) {
                        u32     pckr;
 
-                       pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
-                       pckr &= AT91_PMC_CSS;   /* clock selection */
-                       pckr |= prescale << 2;
-                       at91_sys_write(AT91_PMC_PCKR(clk->id), pckr);
+                       pckr = at91_pmc_read(AT91_PMC_PCKR(clk->id));
+                       pckr &= css_mask;       /* keep clock selection */
+                       pckr |= prescale << prescale_offset;
+                       at91_pmc_write(AT91_PMC_PCKR(clk->id), pckr);
                        clk->rate_hz = actual;
                        break;
                }
@@ -366,7 +398,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
 
        clk->rate_hz = parent->rate_hz;
        clk->parent = parent;
-       at91_sys_write(AT91_PMC_PCKR(clk->id), parent->id);
+       at91_pmc_write(AT91_PMC_PCKR(clk->id), parent->id);
 
        spin_unlock_irqrestore(&clk_lock, flags);
        return 0;
@@ -378,11 +410,17 @@ static void __init init_programmable_clock(struct clk *clk)
 {
        struct clk      *parent;
        u32             pckr;
+       unsigned int    css_mask;
+
+       if (cpu_has_alt_prescaler())
+               css_mask = AT91_PMC_ALT_PCKR_CSS;
+       else
+               css_mask = AT91_PMC_CSS;
 
-       pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
-       parent = at91_css_to_clk(pckr & AT91_PMC_CSS);
+       pckr = at91_pmc_read(AT91_PMC_PCKR(clk->id));
+       parent = at91_css_to_clk(pckr & css_mask);
        clk->parent = parent;
-       clk->rate_hz = parent->rate_hz / (1 << ((pckr & AT91_PMC_PRES) >> 2));
+       clk->rate_hz = parent->rate_hz / pmc_prescaler_divider(pckr);
 }
 
 #endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
@@ -396,19 +434,24 @@ static int at91_clk_show(struct seq_file *s, void *unused)
        u32             scsr, pcsr, uckr = 0, sr;
        struct clk      *clk;
 
-       seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR));
-       seq_printf(s, "PCSR = %8x\n", pcsr = at91_sys_read(AT91_PMC_PCSR));
-       seq_printf(s, "MOR  = %8x\n", at91_sys_read(AT91_CKGR_MOR));
-       seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR));
-       seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR));
+       scsr = at91_pmc_read(AT91_PMC_SCSR);
+       pcsr = at91_pmc_read(AT91_PMC_PCSR);
+       sr = at91_pmc_read(AT91_PMC_SR);
+       seq_printf(s, "SCSR = %8x\n", scsr);
+       seq_printf(s, "PCSR = %8x\n", pcsr);
+       seq_printf(s, "MOR  = %8x\n", at91_pmc_read(AT91_CKGR_MOR));
+       seq_printf(s, "MCFR = %8x\n", at91_pmc_read(AT91_CKGR_MCFR));
+       seq_printf(s, "PLLA = %8x\n", at91_pmc_read(AT91_CKGR_PLLAR));
        if (cpu_has_pllb())
-               seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR));
-       if (cpu_has_utmi())
-               seq_printf(s, "UCKR = %8x\n", uckr = at91_sys_read(AT91_CKGR_UCKR));
-       seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR));
+               seq_printf(s, "PLLB = %8x\n", at91_pmc_read(AT91_CKGR_PLLBR));
+       if (cpu_has_utmi()) {
+               uckr = at91_pmc_read(AT91_CKGR_UCKR);
+               seq_printf(s, "UCKR = %8x\n", uckr);
+       }
+       seq_printf(s, "MCKR = %8x\n", at91_pmc_read(AT91_PMC_MCKR));
        if (cpu_has_upll())
-               seq_printf(s, "USB  = %8x\n", at91_sys_read(AT91_PMC_USB));
-       seq_printf(s, "SR   = %8x\n", sr = at91_sys_read(AT91_PMC_SR));
+               seq_printf(s, "USB  = %8x\n", at91_pmc_read(AT91_PMC_USB));
+       seq_printf(s, "SR   = %8x\n", sr);
 
        seq_printf(s, "\n");
 
@@ -596,16 +639,14 @@ static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock)
        if (cpu_is_at91rm9200()) {
                uhpck.pmc_mask = AT91RM9200_PMC_UHP;
                udpck.pmc_mask = AT91RM9200_PMC_UDP;
-               at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
+               at91_pmc_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
        } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() ||
                   cpu_is_at91sam9263() || cpu_is_at91sam9g20() ||
                   cpu_is_at91sam9g10()) {
                uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
                udpck.pmc_mask = AT91SAM926x_PMC_UDP;
-       } else if (cpu_is_at91cap9()) {
-               uhpck.pmc_mask = AT91CAP9_PMC_UHP;
        }
-       at91_sys_write(AT91_CKGR_PLLBR, 0);
+       at91_pmc_write(AT91_CKGR_PLLBR, 0);
 
        udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
        uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
@@ -622,16 +663,16 @@ static void __init at91_upll_usbfs_clock_init(unsigned long main_clock)
        /* Setup divider by 10 to reach 48 MHz */
        usbr |= ((10 - 1) << 8) & AT91_PMC_OHCIUSBDIV;
 
-       at91_sys_write(AT91_PMC_USB, usbr);
+       at91_pmc_write(AT91_PMC_USB, usbr);
 
        /* Now set uhpck values */
        uhpck.parent = &utmi_clk;
        uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
        uhpck.rate_hz = utmi_clk.rate_hz;
-       uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8);
+       uhpck.rate_hz /= 1 + ((at91_pmc_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8);
 }
 
-int __init at91_clock_init(unsigned long main_clock)
+static int __init at91_pmc_init(unsigned long main_clock)
 {
        unsigned tmp, freq, mckr;
        int i;
@@ -645,14 +686,14 @@ int __init at91_clock_init(unsigned long main_clock)
         */
        if (!main_clock) {
                do {
-                       tmp = at91_sys_read(AT91_CKGR_MCFR);
+                       tmp = at91_pmc_read(AT91_CKGR_MCFR);
                } while (!(tmp & AT91_PMC_MAINRDY));
                main_clock = (tmp & AT91_PMC_MAINF) * (AT91_SLOW_CLOCK / 16);
        }
        main_clk.rate_hz = main_clock;
 
        /* report if PLLA is more than mildly overclocked */
-       plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR));
+       plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_pmc_read(AT91_CKGR_PLLAR));
        if (cpu_has_300M_plla()) {
                if (plla.rate_hz > 300000000)
                        pll_overclock = true;
@@ -666,8 +707,8 @@ int __init at91_clock_init(unsigned long main_clock)
        if (pll_overclock)
                pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
 
-       if (cpu_is_at91sam9g45()) {
-               mckr = at91_sys_read(AT91_PMC_MCKR);
+       if (cpu_has_plladiv2()) {
+               mckr = at91_pmc_read(AT91_PMC_MCKR);
                plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12));      /* plla divisor by 2 */
        }
 
@@ -688,6 +729,10 @@ int __init at91_clock_init(unsigned long main_clock)
                 * (obtain the USB High Speed 480 MHz when input is 12 MHz)
                 */
                utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz;
+
+               /* UTMI bias and PLL are managed at the same time */
+               if (cpu_has_upll())
+                       utmi_clk.pmc_mask |= AT91_PMC_BIASEN;
        }
 
        /*
@@ -703,10 +748,10 @@ int __init at91_clock_init(unsigned long main_clock)
         * MCK and CPU derive from one of those primary clocks.
         * For now, assume this parentage won't change.
         */
-       mckr = at91_sys_read(AT91_PMC_MCKR);
+       mckr = at91_pmc_read(AT91_PMC_MCKR);
        mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
        freq = mck.parent->rate_hz;
-       freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2));                           /* prescale */
+       freq /= pmc_prescaler_divider(mckr);                                    /* prescale */
        if (cpu_is_at91rm9200()) {
                mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8));       /* mdiv */
        } else if (cpu_is_at91sam9g20()) {
@@ -714,13 +759,19 @@ int __init at91_clock_init(unsigned long main_clock)
                        freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq;    /* mdiv ; (x >> 7) = ((x >> 8) * 2) */
                if (mckr & AT91_PMC_PDIV)
                        freq /= 2;              /* processor clock division */
-       } else if (cpu_is_at91sam9g45()) {
+       } else if (cpu_has_mdiv3()) {
                mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ?
                        freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
        } else {
                mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8));              /* mdiv */
        }
 
+       if (cpu_has_alt_prescaler()) {
+               /* Programmable clocks can use MCK */
+               mck.type |= CLK_TYPE_PRIMARY;
+               mck.id = 4;
+       }
+
        /* Register the PMC's standard clocks */
        for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
                at91_clk_add(standard_pmc_clocks[i]);
@@ -748,6 +799,55 @@ int __init at91_clock_init(unsigned long main_clock)
        return 0;
 }
 
+#if defined(CONFIG_OF)
+static struct of_device_id pmc_ids[] = {
+       { .compatible = "atmel,at91rm9200-pmc" },
+       { /*sentinel*/ }
+};
+
+static struct of_device_id osc_ids[] = {
+       { .compatible = "atmel,osc" },
+       { /*sentinel*/ }
+};
+
+int __init at91_dt_clock_init(void)
+{
+       struct device_node *np;
+       u32 main_clock = 0;
+
+       np = of_find_matching_node(NULL, pmc_ids);
+       if (!np)
+               panic("unable to find compatible pmc node in dtb\n");
+
+       at91_pmc_base = of_iomap(np, 0);
+       if (!at91_pmc_base)
+               panic("unable to map pmc cpu registers\n");
+
+       of_node_put(np);
+
+       /* retrieve the freqency of fixed clocks from device tree */
+       np = of_find_matching_node(NULL, osc_ids);
+       if (np) {
+               u32 rate;
+               if (!of_property_read_u32(np, "clock-frequency", &rate))
+                       main_clock = rate;
+       }
+
+       of_node_put(np);
+
+       return at91_pmc_init(main_clock);
+}
+#endif
+
+int __init at91_clock_init(unsigned long main_clock)
+{
+       at91_pmc_base = ioremap(AT91_PMC, 256);
+       if (!at91_pmc_base)
+               panic("Impossible to ioremap AT91_PMC 0x%x\n", AT91_PMC);
+
+       return at91_pmc_init(main_clock);
+}
+
 /*
  * Several unused clocks may be active.  Turn them off.
  */
@@ -770,9 +870,15 @@ static int __init at91_clock_reset(void)
                pr_debug("Clocks: disable unused %s\n", clk->name);
        }
 
-       at91_sys_write(AT91_PMC_PCDR, pcdr);
-       at91_sys_write(AT91_PMC_SCDR, scdr);
+       at91_pmc_write(AT91_PMC_PCDR, pcdr);
+       at91_pmc_write(AT91_PMC_SCDR, scdr);
 
        return 0;
 }
 late_initcall(at91_clock_reset);
+
+void at91sam9_idle(void)
+{
+       at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+       cpu_do_idle();
+}
index a851e6c984218d14533fd5157c7e58fc76c5fc81..555d956b3a574b3a4d96be46c199c087d991080d 100644 (file)
@@ -39,20 +39,15 @@ static int at91_enter_idle(struct cpuidle_device *dev,
 {
        struct timeval before, after;
        int idle_time;
-       u32 saved_lpr;
 
        local_irq_disable();
        do_gettimeofday(&before);
        if (index == 0)
                /* Wait for interrupt state */
                cpu_do_idle();
-       else if (index == 1) {
-               asm("b 1f; .align 5; 1:");
-               asm("mcr p15, 0, r0, c7, c10, 4");      /* drain write buffer */
-               saved_lpr = sdram_selfrefresh_enable();
-               cpu_do_idle();
-               sdram_selfrefresh_disable(saved_lpr);
-       }
+       else if (index == 1)
+               at91_standby();
+
        do_gettimeofday(&after);
        local_irq_enable();
        idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
index 594133451c0c88498d50d30b223f22341c132cb2..dd9b346c451d2b005b7241a4c04af01376e09f1d 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/clkdev.h>
+#include <linux/of.h>
 
  /* Map io */
 extern void __init at91_map_io(void);
@@ -19,15 +20,20 @@ extern void __init at91_init_sram(int bank, unsigned long base,
 extern void __init at91rm9200_set_type(int type);
 extern void __init at91_initialize(unsigned long main_clock);
 extern void __init at91x40_initialize(unsigned long main_clock);
+extern void __init at91_dt_initialize(void);
 
  /* Interrupts */
 extern void __init at91_init_irq_default(void);
 extern void __init at91_init_interrupts(unsigned int priority[]);
 extern void __init at91x40_init_interrupts(unsigned int priority[]);
 extern void __init at91_aic_init(unsigned int priority[]);
+extern int  __init at91_aic_of_init(struct device_node *node,
+                                   struct device_node *parent);
+
 
  /* Timer */
 struct sys_timer;
+extern void at91rm9200_ioremap_st(u32 addr);
 extern struct sys_timer at91rm9200_timer;
 extern void at91sam926x_ioremap_pit(u32 addr);
 extern struct sys_timer at91sam926x_timer;
@@ -45,9 +51,9 @@ extern void __init at91sam9261_set_console_clock(int id);
 extern void __init at91sam9263_set_console_clock(int id);
 extern void __init at91sam9rl_set_console_clock(int id);
 extern void __init at91sam9g45_set_console_clock(int id);
-extern void __init at91cap9_set_console_clock(int id);
 #ifdef CONFIG_AT91_PMC_UNIT
 extern int __init at91_clock_init(unsigned long main_clock);
+extern int __init at91_dt_clock_init(void);
 #else
 static int inline at91_clock_init(unsigned long main_clock) { return 0; }
 #endif
@@ -57,6 +63,9 @@ struct device;
 extern void at91_irq_suspend(void);
 extern void at91_irq_resume(void);
 
+/* idle */
+extern void at91sam9_idle(void);
+
 /* reset */
 extern void at91_ioremap_rstc(u32 base_addr);
 extern void at91sam9_alt_restart(char, const char *);
@@ -65,6 +74,12 @@ extern void at91sam9g45_restart(char, const char *);
 /* shutdown */
 extern void at91_ioremap_shdwc(u32 base_addr);
 
+/* Matrix */
+extern void at91_ioremap_matrix(u32 base_addr);
+
+/* Ram Controler */
+extern void at91_ioremap_ramc(int id, u32 addr, u32 size);
+
  /* GPIO */
 #define AT91RM9200_PQFP                3       /* AT91RM9200 PQFP package has 3 banks */
 #define AT91RM9200_BGA         4       /* AT91RM9200 BGA package has 4 banks */
@@ -75,5 +90,7 @@ struct at91_gpio_bank {
 };
 extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks);
 extern void __init at91_gpio_irq_setup(void);
+extern int  __init at91_gpio_of_irq_setup(struct device_node *node,
+                                         struct device_node *parent);
 
 extern int at91_extern_irq;
index 74d6783eeabbb976c4261d299fcfe11b70d83984..325837a264c930fdbe1787d3ed2e61d3f75d1772 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/clk.h>
 #include <linux/errno.h>
+#include <linux/device.h>
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/io.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
 
 #include <mach/hardware.h>
 #include <mach/at91_pio.h>
 struct at91_gpio_chip {
        struct gpio_chip        chip;
        struct at91_gpio_chip   *next;          /* Bank sharing same clock */
-       int                     id;             /* ID of register bank */
-       void __iomem            *regbase;       /* Base of register bank */
+       int                     pioc_hwirq;     /* PIO bank interrupt identifier on AIC */
+       int                     pioc_virq;      /* PIO bank Linux virtual interrupt */
+       int                     pioc_idx;       /* PIO bank index */
+       void __iomem            *regbase;       /* PIO bank virtual address */
        struct clk              *clock;         /* associated clock */
+       struct irq_domain       *domain;        /* associated irq domain */
 };
 
 #define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip)
@@ -43,8 +51,9 @@ static int at91_gpiolib_direction_output(struct gpio_chip *chip,
                                         unsigned offset, int val);
 static int at91_gpiolib_direction_input(struct gpio_chip *chip,
                                        unsigned offset);
+static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset);
 
-#define AT91_GPIO_CHIP(name, base_gpio, nr_gpio)                       \
+#define AT91_GPIO_CHIP(name, nr_gpio)                                  \
        {                                                               \
                .chip = {                                               \
                        .label            = name,                       \
@@ -53,20 +62,28 @@ static int at91_gpiolib_direction_input(struct gpio_chip *chip,
                        .get              = at91_gpiolib_get,           \
                        .set              = at91_gpiolib_set,           \
                        .dbg_show         = at91_gpiolib_dbg_show,      \
-                       .base             = base_gpio,                  \
+                       .to_irq           = at91_gpiolib_to_irq,        \
                        .ngpio            = nr_gpio,                    \
                },                                                      \
        }
 
 static struct at91_gpio_chip gpio_chip[] = {
-       AT91_GPIO_CHIP("pioA", 0x00, 32),
-       AT91_GPIO_CHIP("pioB", 0x20, 32),
-       AT91_GPIO_CHIP("pioC", 0x40, 32),
-       AT91_GPIO_CHIP("pioD", 0x60, 32),
-       AT91_GPIO_CHIP("pioE", 0x80, 32),
+       AT91_GPIO_CHIP("pioA", 32),
+       AT91_GPIO_CHIP("pioB", 32),
+       AT91_GPIO_CHIP("pioC", 32),
+       AT91_GPIO_CHIP("pioD", 32),
+       AT91_GPIO_CHIP("pioE", 32),
 };
 
 static int gpio_banks;
+static unsigned long at91_gpio_caps;
+
+/* All PIO controllers support PIO3 features */
+#define AT91_GPIO_CAP_PIO3     (1 <<  0)
+
+#define has_pio3()     (at91_gpio_caps & AT91_GPIO_CAP_PIO3)
+
+/*--------------------------------------------------------------------------*/
 
 static inline void __iomem *pin_to_controller(unsigned pin)
 {
@@ -83,6 +100,25 @@ static inline unsigned pin_to_mask(unsigned pin)
 }
 
 
+static char peripheral_function(void __iomem *pio, unsigned mask)
+{
+       char    ret = 'X';
+       u8      select;
+
+       if (pio) {
+               if (has_pio3()) {
+                       select = !!(__raw_readl(pio + PIO_ABCDSR1) & mask);
+                       select |= (!!(__raw_readl(pio + PIO_ABCDSR2) & mask) << 1);
+                       ret = 'A' + select;
+               } else {
+                       ret = __raw_readl(pio + PIO_ABSR) & mask ?
+                                                       'B' : 'A';
+               }
+       }
+
+       return ret;
+}
+
 /*--------------------------------------------------------------------------*/
 
 /* Not all hardware capabilities are exposed through these calls; they
@@ -130,7 +166,14 @@ int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup)
 
        __raw_writel(mask, pio + PIO_IDR);
        __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
-       __raw_writel(mask, pio + PIO_ASR);
+       if (has_pio3()) {
+               __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask,
+                                                       pio + PIO_ABCDSR1);
+               __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask,
+                                                       pio + PIO_ABCDSR2);
+       } else {
+               __raw_writel(mask, pio + PIO_ASR);
+       }
        __raw_writel(mask, pio + PIO_PDR);
        return 0;
 }
@@ -150,7 +193,14 @@ int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup)
 
        __raw_writel(mask, pio + PIO_IDR);
        __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
-       __raw_writel(mask, pio + PIO_BSR);
+       if (has_pio3()) {
+               __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask,
+                                                       pio + PIO_ABCDSR1);
+               __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask,
+                                                       pio + PIO_ABCDSR2);
+       } else {
+               __raw_writel(mask, pio + PIO_BSR);
+       }
        __raw_writel(mask, pio + PIO_PDR);
        return 0;
 }
@@ -158,8 +208,50 @@ EXPORT_SYMBOL(at91_set_B_periph);
 
 
 /*
- * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
- * configure it for an input.
+ * mux the pin to the "C" internal peripheral role.
+ */
+int __init_or_module at91_set_C_periph(unsigned pin, int use_pullup)
+{
+       void __iomem    *pio = pin_to_controller(pin);
+       unsigned        mask = pin_to_mask(pin);
+
+       if (!pio || !has_pio3())
+               return -EINVAL;
+
+       __raw_writel(mask, pio + PIO_IDR);
+       __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
+       __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask, pio + PIO_ABCDSR1);
+       __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2);
+       __raw_writel(mask, pio + PIO_PDR);
+       return 0;
+}
+EXPORT_SYMBOL(at91_set_C_periph);
+
+
+/*
+ * mux the pin to the "D" internal peripheral role.
+ */
+int __init_or_module at91_set_D_periph(unsigned pin, int use_pullup)
+{
+       void __iomem    *pio = pin_to_controller(pin);
+       unsigned        mask = pin_to_mask(pin);
+
+       if (!pio || !has_pio3())
+               return -EINVAL;
+
+       __raw_writel(mask, pio + PIO_IDR);
+       __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
+       __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask, pio + PIO_ABCDSR1);
+       __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2);
+       __raw_writel(mask, pio + PIO_PDR);
+       return 0;
+}
+EXPORT_SYMBOL(at91_set_D_periph);
+
+
+/*
+ * mux the pin to the gpio controller (instead of "A", "B", "C"
+ * or "D" peripheral), and configure it for an input.
  */
 int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup)
 {
@@ -179,8 +271,8 @@ EXPORT_SYMBOL(at91_set_gpio_input);
 
 
 /*
- * mux the pin to the gpio controller (instead of "A" or "B" peripheral),
- * and configure it for an output.
+ * mux the pin to the gpio controller (instead of "A", "B", "C"
+ * or "D" peripheral), and configure it for an output.
  */
 int __init_or_module at91_set_gpio_output(unsigned pin, int value)
 {
@@ -210,11 +302,36 @@ int __init_or_module at91_set_deglitch(unsigned pin, int is_on)
 
        if (!pio)
                return -EINVAL;
+
+       if (has_pio3() && is_on)
+               __raw_writel(mask, pio + PIO_IFSCDR);
        __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR));
        return 0;
 }
 EXPORT_SYMBOL(at91_set_deglitch);
 
+/*
+ * enable/disable the debounce filter;
+ */
+int __init_or_module at91_set_debounce(unsigned pin, int is_on, int div)
+{
+       void __iomem    *pio = pin_to_controller(pin);
+       unsigned        mask = pin_to_mask(pin);
+
+       if (!pio || !has_pio3())
+               return -EINVAL;
+
+       if (is_on) {
+               __raw_writel(mask, pio + PIO_IFSCER);
+               __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR);
+               __raw_writel(mask, pio + PIO_IFER);
+       } else {
+               __raw_writel(mask, pio + PIO_IFDR);
+       }
+       return 0;
+}
+EXPORT_SYMBOL(at91_set_debounce);
+
 /*
  * enable/disable the multi-driver; This is only valid for output and
  * allows the output pin to run as an open collector output.
@@ -232,6 +349,41 @@ int __init_or_module at91_set_multi_drive(unsigned pin, int is_on)
 }
 EXPORT_SYMBOL(at91_set_multi_drive);
 
+/*
+ * enable/disable the pull-down.
+ * If pull-up already enabled while calling the function, we disable it.
+ */
+int __init_or_module at91_set_pulldown(unsigned pin, int is_on)
+{
+       void __iomem    *pio = pin_to_controller(pin);
+       unsigned        mask = pin_to_mask(pin);
+
+       if (!pio || !has_pio3())
+               return -EINVAL;
+
+       /* Disable pull-up anyway */
+       __raw_writel(mask, pio + PIO_PUDR);
+       __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR));
+       return 0;
+}
+EXPORT_SYMBOL(at91_set_pulldown);
+
+/*
+ * disable Schmitt trigger
+ */
+int __init_or_module at91_disable_schmitt_trig(unsigned pin)
+{
+       void __iomem    *pio = pin_to_controller(pin);
+       unsigned        mask = pin_to_mask(pin);
+
+       if (!pio || !has_pio3())
+               return -EINVAL;
+
+       __raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT);
+       return 0;
+}
+EXPORT_SYMBOL(at91_disable_schmitt_trig);
+
 /*
  * assuming the pin is muxed as a gpio output, set its value.
  */
@@ -273,9 +425,9 @@ static u32 backups[MAX_GPIO_BANKS];
 
 static int gpio_irq_set_wake(struct irq_data *d, unsigned state)
 {
-       unsigned        pin = irq_to_gpio(d->irq);
-       unsigned        mask = pin_to_mask(pin);
-       unsigned        bank = pin / 32;
+       struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
+       unsigned        mask = 1 << d->hwirq;
+       unsigned        bank = at91_gpio->pioc_idx;
 
        if (unlikely(bank >= MAX_GPIO_BANKS))
                return -EINVAL;
@@ -285,7 +437,7 @@ static int gpio_irq_set_wake(struct irq_data *d, unsigned state)
        else
                wakeups[bank] &= ~mask;
 
-       irq_set_irq_wake(gpio_chip[bank].id, state);
+       irq_set_irq_wake(at91_gpio->pioc_virq, state);
 
        return 0;
 }
@@ -301,9 +453,10 @@ void at91_gpio_suspend(void)
                __raw_writel(backups[i], pio + PIO_IDR);
                __raw_writel(wakeups[i], pio + PIO_IER);
 
-               if (!wakeups[i])
+               if (!wakeups[i]) {
+                       clk_unprepare(gpio_chip[i].clock);
                        clk_disable(gpio_chip[i].clock);
-               else {
+               else {
 #ifdef CONFIG_PM_DEBUG
                        printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]);
 #endif
@@ -318,8 +471,10 @@ void at91_gpio_resume(void)
        for (i = 0; i < gpio_banks; i++) {
                void __iomem    *pio = gpio_chip[i].regbase;
 
-               if (!wakeups[i])
-                       clk_enable(gpio_chip[i].clock);
+               if (!wakeups[i]) {
+                       if (clk_prepare(gpio_chip[i].clock) == 0)
+                               clk_enable(gpio_chip[i].clock);
+               }
 
                __raw_writel(wakeups[i], pio + PIO_IDR);
                __raw_writel(backups[i], pio + PIO_IER);
@@ -335,7 +490,10 @@ void at91_gpio_resume(void)
  * To use any AT91_PIN_* as an externally triggered IRQ, first call
  * at91_set_gpio_input() then maybe enable its glitch filter.
  * Then just request_irq() with the pin ID; it works like any ARM IRQ
- * handler, though it always triggers on rising and falling edges.
+ * handler.
+ * First implementation always triggers on rising and falling edges
+ * whereas the newer PIO3 can be additionally configured to trigger on
+ * level, edge with any polarity.
  *
  * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after
  * configuring them with at91_set_a_periph() or at91_set_b_periph().
@@ -344,9 +502,9 @@ void at91_gpio_resume(void)
 
 static void gpio_irq_mask(struct irq_data *d)
 {
-       unsigned        pin = irq_to_gpio(d->irq);
-       void __iomem    *pio = pin_to_controller(pin);
-       unsigned        mask = pin_to_mask(pin);
+       struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
+       void __iomem    *pio = at91_gpio->regbase;
+       unsigned        mask = 1 << d->hwirq;
 
        if (pio)
                __raw_writel(mask, pio + PIO_IDR);
@@ -354,9 +512,9 @@ static void gpio_irq_mask(struct irq_data *d)
 
 static void gpio_irq_unmask(struct irq_data *d)
 {
-       unsigned        pin = irq_to_gpio(d->irq);
-       void __iomem    *pio = pin_to_controller(pin);
-       unsigned        mask = pin_to_mask(pin);
+       struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
+       void __iomem    *pio = at91_gpio->regbase;
+       unsigned        mask = 1 << d->hwirq;
 
        if (pio)
                __raw_writel(mask, pio + PIO_IER);
@@ -373,23 +531,66 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
        }
 }
 
+/* Alternate irq type for PIO3 support */
+static int alt_gpio_irq_type(struct irq_data *d, unsigned type)
+{
+       struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
+       void __iomem    *pio = at91_gpio->regbase;
+       unsigned        mask = 1 << d->hwirq;
+
+       switch (type) {
+       case IRQ_TYPE_EDGE_RISING:
+               __raw_writel(mask, pio + PIO_ESR);
+               __raw_writel(mask, pio + PIO_REHLSR);
+               break;
+       case IRQ_TYPE_EDGE_FALLING:
+               __raw_writel(mask, pio + PIO_ESR);
+               __raw_writel(mask, pio + PIO_FELLSR);
+               break;
+       case IRQ_TYPE_LEVEL_LOW:
+               __raw_writel(mask, pio + PIO_LSR);
+               __raw_writel(mask, pio + PIO_FELLSR);
+               break;
+       case IRQ_TYPE_LEVEL_HIGH:
+               __raw_writel(mask, pio + PIO_LSR);
+               __raw_writel(mask, pio + PIO_REHLSR);
+               break;
+       case IRQ_TYPE_EDGE_BOTH:
+               /*
+                * disable additional interrupt modes:
+                * fall back to default behavior
+                */
+               __raw_writel(mask, pio + PIO_AIMDR);
+               return 0;
+       case IRQ_TYPE_NONE:
+       default:
+               pr_warn("AT91: No type for irq %d\n", gpio_to_irq(d->irq));
+               return -EINVAL;
+       }
+
+       /* enable additional interrupt modes */
+       __raw_writel(mask, pio + PIO_AIMER);
+
+       return 0;
+}
+
 static struct irq_chip gpio_irqchip = {
        .name           = "GPIO",
        .irq_disable    = gpio_irq_mask,
        .irq_mask       = gpio_irq_mask,
        .irq_unmask     = gpio_irq_unmask,
-       .irq_set_type   = gpio_irq_type,
+       /* .irq_set_type is set dynamically */
        .irq_set_wake   = gpio_irq_set_wake,
 };
 
 static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 {
-       unsigned        irq_pin;
        struct irq_data *idata = irq_desc_get_irq_data(desc);
        struct irq_chip *chip = irq_data_get_irq_chip(idata);
        struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata);
        void __iomem    *pio = at91_gpio->regbase;
-       u32             isr;
+       unsigned long   isr;
+       int             n;
 
        /* temporarily mask (level sensitive) parent IRQ */
        chip->irq_ack(idata);
@@ -407,13 +608,10 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
                        continue;
                }
 
-               irq_pin = gpio_to_irq(at91_gpio->chip.base);
-
-               while (isr) {
-                       if (isr & 1)
-                               generic_handle_irq(irq_pin);
-                       irq_pin++;
-                       isr >>= 1;
+               n = find_first_bit(&isr, BITS_PER_LONG);
+               while (n < BITS_PER_LONG) {
+                       generic_handle_irq(irq_find_mapping(at91_gpio->domain, n));
+                       n = find_next_bit(&isr, BITS_PER_LONG, n + 1);
                }
        }
        chip->irq_unmask(idata);
@@ -424,6 +622,33 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 
 #ifdef CONFIG_DEBUG_FS
 
+static void gpio_printf(struct seq_file *s, void __iomem *pio, unsigned mask)
+{
+       char    *trigger = NULL;
+       char    *polarity = NULL;
+
+       if (__raw_readl(pio + PIO_IMR) & mask) {
+               if (!has_pio3() || !(__raw_readl(pio + PIO_AIMMR) & mask )) {
+                       trigger = "edge";
+                       polarity = "both";
+               } else {
+                       if (__raw_readl(pio + PIO_ELSR) & mask) {
+                               trigger = "level";
+                               polarity = __raw_readl(pio + PIO_FRLHSR) & mask ?
+                                       "high" : "low";
+                       } else {
+                               trigger = "edge";
+                               polarity = __raw_readl(pio + PIO_FRLHSR) & mask ?
+                                               "rising" : "falling";
+                       }
+               }
+               seq_printf(s, "IRQ:%s-%s\t", trigger, polarity);
+       } else {
+               seq_printf(s, "GPIO:%s\t\t",
+                               __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0");
+       }
+}
+
 static int at91_gpio_show(struct seq_file *s, void *unused)
 {
        int bank, j;
@@ -431,7 +656,7 @@ static int at91_gpio_show(struct seq_file *s, void *unused)
        /* print heading */
        seq_printf(s, "Pin\t");
        for (bank = 0; bank < gpio_banks; bank++) {
-               seq_printf(s, "PIO%c\t", 'A' + bank);
+               seq_printf(s, "PIO%c\t\t", 'A' + bank);
        };
        seq_printf(s, "\n\n");
 
@@ -445,11 +670,10 @@ static int at91_gpio_show(struct seq_file *s, void *unused)
                        unsigned        mask = pin_to_mask(pin);
 
                        if (__raw_readl(pio + PIO_PSR) & mask)
-                               seq_printf(s, "GPIO:%s", __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0");
+                               gpio_printf(s, pio, mask);
                        else
-                               seq_printf(s, "%s", __raw_readl(pio + PIO_ABSR) & mask ? "B" : "A");
-
-                       seq_printf(s, "\t");
+                               seq_printf(s, "%c\t\t",
+                                               peripheral_function(pio, mask));
                }
 
                seq_printf(s, "\n");
@@ -488,46 +712,152 @@ postcore_initcall(at91_gpio_debugfs_init);
  */
 static struct lock_class_key gpio_lock_class;
 
+#if defined(CONFIG_OF)
+static int at91_gpio_irq_map(struct irq_domain *h, unsigned int virq,
+                                                       irq_hw_number_t hw)
+{
+       struct at91_gpio_chip   *at91_gpio = h->host_data;
+
+       irq_set_lockdep_class(virq, &gpio_lock_class);
+
+       /*
+        * Can use the "simple" and not "edge" handler since it's
+        * shorter, and the AIC handles interrupts sanely.
+        */
+       irq_set_chip_and_handler(virq, &gpio_irqchip,
+                                handle_simple_irq);
+       set_irq_flags(virq, IRQF_VALID);
+       irq_set_chip_data(virq, at91_gpio);
+
+       return 0;
+}
+
+static struct irq_domain_ops at91_gpio_ops = {
+       .map    = at91_gpio_irq_map,
+       .xlate  = irq_domain_xlate_twocell,
+};
+
+int __init at91_gpio_of_irq_setup(struct device_node *node,
+                                    struct device_node *parent)
+{
+       struct at91_gpio_chip   *prev = NULL;
+       int                     alias_idx = of_alias_get_id(node, "gpio");
+       struct at91_gpio_chip   *at91_gpio = &gpio_chip[alias_idx];
+
+       /* Setup proper .irq_set_type function */
+       if (has_pio3())
+               gpio_irqchip.irq_set_type = alt_gpio_irq_type;
+       else
+               gpio_irqchip.irq_set_type = gpio_irq_type;
+
+       /* Disable irqs of this PIO controller */
+       __raw_writel(~0, at91_gpio->regbase + PIO_IDR);
+
+       /* Setup irq domain */
+       at91_gpio->domain = irq_domain_add_linear(node, at91_gpio->chip.ngpio,
+                                               &at91_gpio_ops, at91_gpio);
+       if (!at91_gpio->domain)
+               panic("at91_gpio.%d: couldn't allocate irq domain (DT).\n",
+                       at91_gpio->pioc_idx);
+
+       /* Setup chained handler */
+       if (at91_gpio->pioc_idx)
+               prev = &gpio_chip[at91_gpio->pioc_idx - 1];
+
+       /* The toplevel handler handles one bank of GPIOs, except
+        * on some SoC it can handles up to three...
+        * We only set up the handler for the first of the list.
+        */
+       if (prev && prev->next == at91_gpio)
+               return 0;
+
+       at91_gpio->pioc_virq = irq_create_mapping(irq_find_host(parent),
+                                                       at91_gpio->pioc_hwirq);
+       irq_set_chip_data(at91_gpio->pioc_virq, at91_gpio);
+       irq_set_chained_handler(at91_gpio->pioc_virq, gpio_irq_handler);
+
+       return 0;
+}
+#else
+int __init at91_gpio_of_irq_setup(struct device_node *node,
+                                    struct device_node *parent)
+{
+       return -EINVAL;
+}
+#endif
+
+/*
+ * irqdomain initialization: pile up irqdomains on top of AIC range
+ */
+static void __init at91_gpio_irqdomain(struct at91_gpio_chip *at91_gpio)
+{
+       int irq_base;
+
+       irq_base = irq_alloc_descs(-1, 0, at91_gpio->chip.ngpio, 0);
+       if (irq_base < 0)
+               panic("at91_gpio.%d: error %d: couldn't allocate IRQ numbers.\n",
+                       at91_gpio->pioc_idx, irq_base);
+       at91_gpio->domain = irq_domain_add_legacy(NULL, at91_gpio->chip.ngpio,
+                                                 irq_base, 0,
+                                                 &irq_domain_simple_ops, NULL);
+       if (!at91_gpio->domain)
+               panic("at91_gpio.%d: couldn't allocate irq domain.\n",
+                       at91_gpio->pioc_idx);
+}
+
 /*
  * Called from the processor-specific init to enable GPIO interrupt support.
  */
 void __init at91_gpio_irq_setup(void)
 {
-       unsigned                pioc, irq = gpio_to_irq(0);
+       unsigned                pioc;
+       int                     gpio_irqnbr = 0;
        struct at91_gpio_chip   *this, *prev;
 
+       /* Setup proper .irq_set_type function */
+       if (has_pio3())
+               gpio_irqchip.irq_set_type = alt_gpio_irq_type;
+       else
+               gpio_irqchip.irq_set_type = gpio_irq_type;
+
        for (pioc = 0, this = gpio_chip, prev = NULL;
                        pioc++ < gpio_banks;
                        prev = this, this++) {
-               unsigned        id = this->id;
-               unsigned        i;
+               int offset;
 
                __raw_writel(~0, this->regbase + PIO_IDR);
 
-               for (i = 0, irq = gpio_to_irq(this->chip.base); i < 32;
-                    i++, irq++) {
-                       irq_set_lockdep_class(irq, &gpio_lock_class);
+               /* setup irq domain for this GPIO controller */
+               at91_gpio_irqdomain(this);
+
+               for (offset = 0; offset < this->chip.ngpio; offset++) {
+                       unsigned int virq = irq_find_mapping(this->domain, offset);
+                       irq_set_lockdep_class(virq, &gpio_lock_class);
 
                        /*
                         * Can use the "simple" and not "edge" handler since it's
                         * shorter, and the AIC handles interrupts sanely.
                         */
-                       irq_set_chip_and_handler(irq, &gpio_irqchip,
+                       irq_set_chip_and_handler(virq, &gpio_irqchip,
                                                 handle_simple_irq);
-                       set_irq_flags(irq, IRQF_VALID);
+                       set_irq_flags(virq, IRQF_VALID);
+                       irq_set_chip_data(virq, this);
+
+                       gpio_irqnbr++;
                }
 
                /* The toplevel handler handles one bank of GPIOs, except
-                * AT91SAM9263_ID_PIOCDE handles three... PIOC is first in
-                * the list, so we only set up that handler.
+                * on some SoC it can handles up to three...
+                * We only set up the handler for the first of the list.
                 */
                if (prev && prev->next == this)
                        continue;
 
-               irq_set_chip_data(id, this);
-               irq_set_chained_handler(id, gpio_irq_handler);
+               this->pioc_virq = irq_create_mapping(NULL, this->pioc_hwirq);
+               irq_set_chip_data(this->pioc_virq, this);
+               irq_set_chained_handler(this->pioc_virq, gpio_irq_handler);
        }
-       pr_info("AT91: %d gpio irqs in %d banks\n", irq - gpio_to_irq(0), gpio_banks);
+       pr_info("AT91: %d gpio irqs in %d banks\n", gpio_irqnbr, gpio_banks);
 }
 
 /* gpiolib support */
@@ -593,48 +923,175 @@ static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
                                           at91_get_gpio_value(pin) ?
                                           "set" : "clear");
                        else
-                               seq_printf(s, "[periph %s]\n",
-                                          __raw_readl(pio + PIO_ABSR) &
-                                          mask ? "B" : "A");
+                               seq_printf(s, "[periph %c]\n",
+                                          peripheral_function(pio, mask));
                }
        }
 }
 
+static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+       struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+       int virq;
+
+       if (offset < chip->ngpio)
+               virq = irq_create_mapping(at91_gpio->domain, offset);
+       else
+               virq = -ENXIO;
+
+       dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n",
+                               chip->label, offset + chip->base, virq);
+       return virq;
+}
+
+static int __init at91_gpio_setup_clk(int idx)
+{
+       struct at91_gpio_chip *at91_gpio = &gpio_chip[idx];
+
+       /* retreive PIO controller's clock */
+       at91_gpio->clock = clk_get_sys(NULL, at91_gpio->chip.label);
+       if (IS_ERR(at91_gpio->clock)) {
+               pr_err("at91_gpio.%d, failed to get clock, ignoring.\n", idx);
+               goto err;
+       }
+
+       if (clk_prepare(at91_gpio->clock))
+               goto clk_prep_err;
+
+       /* enable PIO controller's clock */
+       if (clk_enable(at91_gpio->clock)) {
+               pr_err("at91_gpio.%d, failed to enable clock, ignoring.\n", idx);
+               goto clk_err;
+       }
+
+       return 0;
+
+clk_err:
+       clk_unprepare(at91_gpio->clock);
+clk_prep_err:
+       clk_put(at91_gpio->clock);
+err:
+       return -EINVAL;
+}
+
+#ifdef CONFIG_OF_GPIO
+static void __init of_at91_gpio_init_one(struct device_node *np)
+{
+       int alias_idx;
+       struct at91_gpio_chip *at91_gpio;
+
+       if (!np)
+               return;
+
+       alias_idx = of_alias_get_id(np, "gpio");
+       if (alias_idx >= MAX_GPIO_BANKS) {
+               pr_err("at91_gpio, failed alias idx(%d) > MAX_GPIO_BANKS(%d), ignoring.\n",
+                                               alias_idx, MAX_GPIO_BANKS);
+               return;
+       }
+
+       at91_gpio = &gpio_chip[alias_idx];
+       at91_gpio->chip.base = alias_idx * at91_gpio->chip.ngpio;
+
+       at91_gpio->regbase = of_iomap(np, 0);
+       if (!at91_gpio->regbase) {
+               pr_err("at91_gpio.%d, failed to map registers, ignoring.\n",
+                                                               alias_idx);
+               return;
+       }
+
+       /* Get the interrupts property */
+       if (of_property_read_u32(np, "interrupts", &at91_gpio->pioc_hwirq)) {
+               pr_err("at91_gpio.%d, failed to get interrupts property, ignoring.\n",
+                                                               alias_idx);
+               goto ioremap_err;
+       }
+
+       /* Get capabilities from compatibility property */
+       if (of_device_is_compatible(np, "atmel,at91sam9x5-gpio"))
+               at91_gpio_caps |= AT91_GPIO_CAP_PIO3;
+
+       /* Setup clock */
+       if (at91_gpio_setup_clk(alias_idx))
+               goto ioremap_err;
+
+       at91_gpio->chip.of_node = np;
+       gpio_banks = max(gpio_banks, alias_idx + 1);
+       at91_gpio->pioc_idx = alias_idx;
+       return;
+
+ioremap_err:
+       iounmap(at91_gpio->regbase);
+}
+
+static int __init of_at91_gpio_init(void)
+{
+       struct device_node *np = NULL;
+
+       /*
+        * This isn't ideal, but it gets things hooked up until this
+        * driver is converted into a platform_device
+        */
+       for_each_compatible_node(np, NULL, "atmel,at91rm9200-gpio")
+               of_at91_gpio_init_one(np);
+
+       return gpio_banks > 0 ? 0 : -EINVAL;
+}
+#else
+static int __init of_at91_gpio_init(void)
+{
+       return -EINVAL;
+}
+#endif
+
+static void __init at91_gpio_init_one(int idx, u32 regbase, int pioc_hwirq)
+{
+       struct at91_gpio_chip *at91_gpio = &gpio_chip[idx];
+
+       at91_gpio->chip.base = idx * at91_gpio->chip.ngpio;
+       at91_gpio->pioc_hwirq = pioc_hwirq;
+       at91_gpio->pioc_idx = idx;
+
+       at91_gpio->regbase = ioremap(regbase, 512);
+       if (!at91_gpio->regbase) {
+               pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", idx);
+               return;
+       }
+
+       if (at91_gpio_setup_clk(idx))
+               goto ioremap_err;
+
+       gpio_banks = max(gpio_banks, idx + 1);
+       return;
+
+ioremap_err:
+       iounmap(at91_gpio->regbase);
+}
+
 /*
  * Called from the processor-specific init to enable GPIO pin support.
  */
 void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
 {
-       unsigned                i;
+       unsigned i;
        struct at91_gpio_chip *at91_gpio, *last = NULL;
 
        BUG_ON(nr_banks > MAX_GPIO_BANKS);
 
-       gpio_banks = nr_banks;
+       if (of_at91_gpio_init() < 0) {
+               /* No GPIO controller found in device tree */
+               for (i = 0; i < nr_banks; i++)
+                       at91_gpio_init_one(i, data[i].regbase, data[i].id);
+       }
 
-       for (i = 0; i < nr_banks; i++) {
+       for (i = 0; i < gpio_banks; i++) {
                at91_gpio = &gpio_chip[i];
 
-               at91_gpio->id = data[i].id;
-               at91_gpio->chip.base = i * 32;
-
-               at91_gpio->regbase = ioremap(data[i].regbase, 512);
-               if (!at91_gpio->regbase) {
-                       pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", i);
-                       continue;
-               }
-
-               at91_gpio->clock = clk_get_sys(NULL, at91_gpio->chip.label);
-               if (!at91_gpio->clock) {
-                       pr_err("at91_gpio.%d, failed to get clock, ignoring.\n", i);
-                       continue;
-               }
-
-               /* enable PIO controller's clock */
-               clk_enable(at91_gpio->clock);
-
-               /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */
-               if (last && last->id == at91_gpio->id)
+               /*
+                * GPIO controller are grouped on some SoC:
+                * PIOC, PIOD and PIOE can share the same IRQ line
+                */
+               if (last && last->pioc_hwirq == at91_gpio->pioc_hwirq)
                        last->next = at91_gpio;
                last = at91_gpio;
 
diff --git a/arch/arm/mach-at91/include/mach/at91_matrix.h b/arch/arm/mach-at91/include/mach/at91_matrix.h
new file mode 100644 (file)
index 0000000..02fae9d
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Under GPLv2
+ */
+
+#ifndef __MACH_AT91_MATRIX_H__
+#define __MACH_AT91_MATRIX_H__
+
+#ifndef __ASSEMBLY__
+extern void __iomem *at91_matrix_base;
+
+#define at91_matrix_read(field) \
+       __raw_readl(at91_matrix_base + field)
+
+#define at91_matrix_write(field, value) \
+       __raw_writel(value, at91_matrix_base + field);
+
+#else
+.extern at91_matrix_base
+#endif
+
+#endif /* __MACH_AT91_MATRIX_H__ */
index c6a31bf8a5c6973b93ba8856191ca2bf04bde665..732b11c37f1a68f081508be3e6787ebb637a9540 100644 (file)
 #define PIO_PUER       0x64    /* Pull-up Enable Register */
 #define PIO_PUSR       0x68    /* Pull-up Status Register */
 #define PIO_ASR                0x70    /* Peripheral A Select Register */
+#define PIO_ABCDSR1    0x70    /* Peripheral ABCD Select Register 1 [some sam9 only] */
 #define PIO_BSR                0x74    /* Peripheral B Select Register */
+#define PIO_ABCDSR2    0x74    /* Peripheral ABCD Select Register 2 [some sam9 only] */
 #define PIO_ABSR       0x78    /* AB Status Register */
+#define PIO_IFSCDR     0x80    /* Input Filter Slow Clock Disable Register */
+#define PIO_IFSCER     0x84    /* Input Filter Slow Clock Enable Register */
+#define PIO_IFSCSR     0x88    /* Input Filter Slow Clock Status Register */
+#define PIO_SCDR       0x8c    /* Slow Clock Divider Debouncing Register */
+#define                PIO_SCDR_DIV    (0x3fff <<  0)          /* Slow Clock Divider Mask */
+#define PIO_PPDDR      0x90    /* Pad Pull-down Disable Register */
+#define PIO_PPDER      0x94    /* Pad Pull-down Enable Register */
+#define PIO_PPDSR      0x98    /* Pad Pull-down Status Register */
 #define PIO_OWER       0xa0    /* Output Write Enable Register */
 #define PIO_OWDR       0xa4    /* Output Write Disable Register */
 #define PIO_OWSR       0xa8    /* Output Write Status Register */
+#define PIO_AIMER      0xb0    /* Additional Interrupt Modes Enable Register */
+#define PIO_AIMDR      0xb4    /* Additional Interrupt Modes Disable Register */
+#define PIO_AIMMR      0xb8    /* Additional Interrupt Modes Mask Register */
+#define PIO_ESR                0xc0    /* Edge Select Register */
+#define PIO_LSR                0xc4    /* Level Select Register */
+#define PIO_ELSR       0xc8    /* Edge/Level Status Register */
+#define PIO_FELLSR     0xd0    /* Falling Edge/Low Level Select Register */
+#define PIO_REHLSR     0xd4    /* Rising Edge/ High Level Select Register */
+#define PIO_FRLHSR     0xd8    /* Fall/Rise - Low/High Status Register */
+#define PIO_SCHMITT    0x100   /* Schmitt Trigger Register */
+
+#define ABCDSR_PERIPH_A        0x0
+#define ABCDSR_PERIPH_B        0x1
+#define ABCDSR_PERIPH_C        0x2
+#define ABCDSR_PERIPH_D        0x3
 
 #endif
index e46f93e34aab4666b14932a9c6c451847b2c8b54..36604782a78f0e52d4bed0d6af21c787dacf418f 100644 (file)
 #ifndef AT91_PMC_H
 #define AT91_PMC_H
 
-#define        AT91_PMC_SCER           (AT91_PMC + 0x00)       /* System Clock Enable Register */
-#define        AT91_PMC_SCDR           (AT91_PMC + 0x04)       /* System Clock Disable Register */
+#ifndef __ASSEMBLY__
+extern void __iomem *at91_pmc_base;
 
-#define        AT91_PMC_SCSR           (AT91_PMC + 0x08)       /* System Clock Status Register */
+#define at91_pmc_read(field) \
+       __raw_readl(at91_pmc_base + field)
+
+#define at91_pmc_write(field, value) \
+       __raw_writel(value, at91_pmc_base + field)
+#else
+.extern at91_aic_base
+#endif
+
+#define        AT91_PMC_SCER           0x00                    /* System Clock Enable Register */
+#define        AT91_PMC_SCDR           0x04                    /* System Clock Disable Register */
+
+#define        AT91_PMC_SCSR           0x08                    /* System Clock Status Register */
 #define                AT91_PMC_PCK            (1 <<  0)               /* Processor Clock */
 #define                AT91RM9200_PMC_UDP      (1 <<  1)               /* USB Devcice Port Clock [AT91RM9200 only] */
 #define                AT91RM9200_PMC_MCKUDP   (1 <<  2)               /* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */
-#define                AT91CAP9_PMC_DDR        (1 <<  2)               /* DDR Clock [CAP9 revC & some SAM9 only] */
 #define                AT91RM9200_PMC_UHP      (1 <<  4)               /* USB Host Port Clock [AT91RM9200 only] */
 #define                AT91SAM926x_PMC_UHP     (1 <<  6)               /* USB Host Port Clock [AT91SAM926x only] */
-#define                AT91CAP9_PMC_UHP        (1 <<  6)               /* USB Host Port Clock [AT91CAP9 only] */
 #define                AT91SAM926x_PMC_UDP     (1 <<  7)               /* USB Devcice Port Clock [AT91SAM926x only] */
 #define                AT91_PMC_PCK0           (1 <<  8)               /* Programmable Clock 0 */
 #define                AT91_PMC_PCK1           (1 <<  9)               /* Programmable Clock 1 */
 #define                AT91_PMC_HCK0           (1 << 16)               /* AHB Clock (USB host) [AT91SAM9261 only] */
 #define                AT91_PMC_HCK1           (1 << 17)               /* AHB Clock (LCD) [AT91SAM9261 only] */
 
-#define        AT91_PMC_PCER           (AT91_PMC + 0x10)       /* Peripheral Clock Enable Register */
-#define        AT91_PMC_PCDR           (AT91_PMC + 0x14)       /* Peripheral Clock Disable Register */
-#define        AT91_PMC_PCSR           (AT91_PMC + 0x18)       /* Peripheral Clock Status Register */
+#define        AT91_PMC_PCER           0x10                    /* Peripheral Clock Enable Register */
+#define        AT91_PMC_PCDR           0x14                    /* Peripheral Clock Disable Register */
+#define        AT91_PMC_PCSR           0x18                    /* Peripheral Clock Status Register */
 
-#define        AT91_CKGR_UCKR          (AT91_PMC + 0x1C)       /* UTMI Clock Register [some SAM9, CAP9] */
+#define        AT91_CKGR_UCKR          0x1C                    /* UTMI Clock Register [some SAM9] */
 #define                AT91_PMC_UPLLEN         (1   << 16)             /* UTMI PLL Enable */
 #define                AT91_PMC_UPLLCOUNT      (0xf << 20)             /* UTMI PLL Start-up Time */
 #define                AT91_PMC_BIASEN         (1   << 24)             /* UTMI BIAS Enable */
 #define                AT91_PMC_BIASCOUNT      (0xf << 28)             /* UTMI BIAS Start-up Time */
 
-#define        AT91_CKGR_MOR           (AT91_PMC + 0x20)       /* Main Oscillator Register [not on SAM9RL] */
-#define                AT91_PMC_MOSCEN         (1    << 0)             /* Main Oscillator Enable */
-#define                AT91_PMC_OSCBYPASS      (1    << 1)             /* Oscillator Bypass [SAM9x, CAP9] */
-#define                AT91_PMC_OSCOUNT        (0xff << 8)             /* Main Oscillator Start-up Time */
+#define        AT91_CKGR_MOR           0x20                    /* Main Oscillator Register [not on SAM9RL] */
+#define                AT91_PMC_MOSCEN         (1    <<  0)            /* Main Oscillator Enable */
+#define                AT91_PMC_OSCBYPASS      (1    <<  1)            /* Oscillator Bypass */
+#define                AT91_PMC_MOSCRCEN       (1    <<  3)            /* Main On-Chip RC Oscillator Enable [some SAM9] */
+#define                AT91_PMC_OSCOUNT        (0xff <<  8)            /* Main Oscillator Start-up Time */
+#define                AT91_PMC_KEY            (0x37 << 16)            /* MOR Writing Key */
+#define                AT91_PMC_MOSCSEL        (1    << 24)            /* Main Oscillator Selection [some SAM9] */
+#define                AT91_PMC_CFDEN          (1    << 25)            /* Clock Failure Detector Enable [some SAM9] */
 
-#define        AT91_CKGR_MCFR          (AT91_PMC + 0x24)       /* Main Clock Frequency Register */
+#define        AT91_CKGR_MCFR          0x24                    /* Main Clock Frequency Register */
 #define                AT91_PMC_MAINF          (0xffff <<  0)          /* Main Clock Frequency */
 #define                AT91_PMC_MAINRDY        (1      << 16)          /* Main Clock Ready */
 
-#define        AT91_CKGR_PLLAR         (AT91_PMC + 0x28)       /* PLL A Register */
-#define        AT91_CKGR_PLLBR         (AT91_PMC + 0x2c)       /* PLL B Register */
+#define        AT91_CKGR_PLLAR         0x28                    /* PLL A Register */
+#define        AT91_CKGR_PLLBR         0x2c                    /* PLL B Register */
 #define                AT91_PMC_DIV            (0xff  <<  0)           /* Divider */
 #define                AT91_PMC_PLLCOUNT       (0x3f  <<  8)           /* PLL Counter */
 #define                AT91_PMC_OUT            (3     << 14)           /* PLL Clock Frequency Range */
 #define                        AT91_PMC_USBDIV_4               (2 << 28)
 #define                AT91_PMC_USB96M         (1     << 28)           /* Divider by 2 Enable (PLLB only) */
 
-#define        AT91_PMC_MCKR           (AT91_PMC + 0x30)       /* Master Clock Register */
+#define        AT91_PMC_MCKR           0x30                    /* Master Clock Register */
 #define                AT91_PMC_CSS            (3 <<  0)               /* Master Clock Selection */
 #define                        AT91_PMC_CSS_SLOW               (0 << 0)
 #define                        AT91_PMC_CSS_MAIN               (1 << 0)
 #define                        AT91_PMC_CSS_PLLA               (2 << 0)
 #define                        AT91_PMC_CSS_PLLB               (3 << 0)
 #define                        AT91_PMC_CSS_UPLL               (3 << 0)        /* [some SAM9 only] */
-#define                AT91_PMC_PRES           (7 <<  2)               /* Master Clock Prescaler */
-#define                        AT91_PMC_PRES_1                 (0 << 2)
-#define                        AT91_PMC_PRES_2                 (1 << 2)
-#define                        AT91_PMC_PRES_4                 (2 << 2)
-#define                        AT91_PMC_PRES_8                 (3 << 2)
-#define                        AT91_PMC_PRES_16                (4 << 2)
-#define                        AT91_PMC_PRES_32                (5 << 2)
-#define                        AT91_PMC_PRES_64                (6 << 2)
+#define                PMC_PRES_OFFSET         2
+#define                AT91_PMC_PRES           (7 <<  PMC_PRES_OFFSET)         /* Master Clock Prescaler */
+#define                        AT91_PMC_PRES_1                 (0 << PMC_PRES_OFFSET)
+#define                        AT91_PMC_PRES_2                 (1 << PMC_PRES_OFFSET)
+#define                        AT91_PMC_PRES_4                 (2 << PMC_PRES_OFFSET)
+#define                        AT91_PMC_PRES_8                 (3 << PMC_PRES_OFFSET)
+#define                        AT91_PMC_PRES_16                (4 << PMC_PRES_OFFSET)
+#define                        AT91_PMC_PRES_32                (5 << PMC_PRES_OFFSET)
+#define                        AT91_PMC_PRES_64                (6 << PMC_PRES_OFFSET)
+#define                PMC_ALT_PRES_OFFSET     4
+#define                AT91_PMC_ALT_PRES       (7 <<  PMC_ALT_PRES_OFFSET)             /* Master Clock Prescaler [alternate location] */
+#define                        AT91_PMC_ALT_PRES_1             (0 << PMC_ALT_PRES_OFFSET)
+#define                        AT91_PMC_ALT_PRES_2             (1 << PMC_ALT_PRES_OFFSET)
+#define                        AT91_PMC_ALT_PRES_4             (2 << PMC_ALT_PRES_OFFSET)
+#define                        AT91_PMC_ALT_PRES_8             (3 << PMC_ALT_PRES_OFFSET)
+#define                        AT91_PMC_ALT_PRES_16            (4 << PMC_ALT_PRES_OFFSET)
+#define                        AT91_PMC_ALT_PRES_32            (5 << PMC_ALT_PRES_OFFSET)
+#define                        AT91_PMC_ALT_PRES_64            (6 << PMC_ALT_PRES_OFFSET)
 #define                AT91_PMC_MDIV           (3 <<  8)               /* Master Clock Division */
 #define                        AT91RM9200_PMC_MDIV_1           (0 << 8)        /* [AT91RM9200 only] */
 #define                        AT91RM9200_PMC_MDIV_2           (1 << 8)
 #define                        AT91RM9200_PMC_MDIV_3           (2 << 8)
 #define                        AT91RM9200_PMC_MDIV_4           (3 << 8)
-#define                        AT91SAM9_PMC_MDIV_1             (0 << 8)        /* [SAM9,CAP9 only] */
+#define                        AT91SAM9_PMC_MDIV_1             (0 << 8)        /* [SAM9 only] */
 #define                        AT91SAM9_PMC_MDIV_2             (1 << 8)
 #define                        AT91SAM9_PMC_MDIV_4             (2 << 8)
 #define                        AT91SAM9_PMC_MDIV_6             (3 << 8)        /* [some SAM9 only] */
 #define                        AT91_PMC_PLLADIV2_OFF           (0 << 12)
 #define                        AT91_PMC_PLLADIV2_ON            (1 << 12)
 
-#define        AT91_PMC_USB            (AT91_PMC + 0x38)       /* USB Clock Register [some SAM9 only] */
+#define        AT91_PMC_USB            0x38                    /* USB Clock Register [some SAM9 only] */
 #define                AT91_PMC_USBS           (0x1 <<  0)             /* USB OHCI Input clock selection */
 #define                        AT91_PMC_USBS_PLLA              (0 << 0)
 #define                        AT91_PMC_USBS_UPLL              (1 << 0)
 #define                AT91_PMC_OHCIUSBDIV     (0xF <<  8)             /* Divider for USB OHCI Clock */
 
-#define        AT91_PMC_PCKR(n)        (AT91_PMC + 0x40 + ((n) * 4))   /* Programmable Clock 0-N Registers */
+#define        AT91_PMC_SMD            0x3c                    /* Soft Modem Clock Register [some SAM9 only] */
+#define                AT91_PMC_SMDS           (0x1  <<  0)            /* SMD input clock selection */
+#define                AT91_PMC_SMD_DIV        (0x1f <<  8)            /* SMD input clock divider */
+#define                AT91_PMC_SMDDIV(n)      (((n) <<  8) & AT91_PMC_SMD_DIV)
+
+#define        AT91_PMC_PCKR(n)        (0x40 + ((n) * 4))      /* Programmable Clock 0-N Registers */
+#define                AT91_PMC_ALT_PCKR_CSS   (0x7 <<  0)             /* Programmable Clock Source Selection [alternate length] */
+#define                        AT91_PMC_CSS_MASTER             (4 << 0)        /* [some SAM9 only] */
 #define                AT91_PMC_CSSMCK         (0x1 <<  8)             /* CSS or Master Clock Selection */
 #define                        AT91_PMC_CSSMCK_CSS             (0 << 8)
 #define                        AT91_PMC_CSSMCK_MCK             (1 << 8)
 
-#define        AT91_PMC_IER            (AT91_PMC + 0x60)       /* Interrupt Enable Register */
-#define        AT91_PMC_IDR            (AT91_PMC + 0x64)       /* Interrupt Disable Register */
-#define        AT91_PMC_SR             (AT91_PMC + 0x68)       /* Status Register */
+#define        AT91_PMC_IER            0x60                    /* Interrupt Enable Register */
+#define        AT91_PMC_IDR            0x64                    /* Interrupt Disable Register */
+#define        AT91_PMC_SR             0x68                    /* Status Register */
 #define                AT91_PMC_MOSCS          (1 <<  0)               /* MOSCS Flag */
 #define                AT91_PMC_LOCKA          (1 <<  1)               /* PLLA Lock */
 #define                AT91_PMC_LOCKB          (1 <<  2)               /* PLLB Lock */
 #define                AT91_PMC_MCKRDY         (1 <<  3)               /* Master Clock */
-#define                AT91_PMC_LOCKU          (1 <<  6)               /* UPLL Lock [some SAM9, AT91CAP9 only] */
-#define                AT91_PMC_OSCSEL         (1 <<  7)               /* Slow Clock Oscillator [AT91CAP9 revC only] */
+#define                AT91_PMC_LOCKU          (1 <<  6)               /* UPLL Lock [some SAM9] */
 #define                AT91_PMC_PCK0RDY        (1 <<  8)               /* Programmable Clock 0 */
 #define                AT91_PMC_PCK1RDY        (1 <<  9)               /* Programmable Clock 1 */
 #define                AT91_PMC_PCK2RDY        (1 << 10)               /* Programmable Clock 2 */
 #define                AT91_PMC_PCK3RDY        (1 << 11)               /* Programmable Clock 3 */
-#define        AT91_PMC_IMR            (AT91_PMC + 0x6c)       /* Interrupt Mask Register */
+#define                AT91_PMC_MOSCSELS       (1 << 16)               /* Main Oscillator Selection [some SAM9] */
+#define                AT91_PMC_MOSCRCS        (1 << 17)               /* Main On-Chip RC [some SAM9] */
+#define                AT91_PMC_CFDEV          (1 << 18)               /* Clock Failure Detector Event [some SAM9] */
+#define        AT91_PMC_IMR            0x6c                    /* Interrupt Mask Register */
+
+#define AT91_PMC_PROT          0xe4                    /* Write Protect Mode Register [some SAM9] */
+#define                AT91_PMC_WPEN           (0x1  <<  0)            /* Write Protect Enable */
+#define                AT91_PMC_WPKEY          (0xffffff << 8)         /* Write Protect Key */
+#define                AT91_PMC_PROTKEY        (0x504d43 << 8)         /* Activation Code */
 
-#define AT91_PMC_PROT          (AT91_PMC + 0xe4)       /* Protect Register [AT91CAP9 revC only] */
-#define                AT91_PMC_PROTKEY        0x504d4301      /* Activation Code */
+#define AT91_PMC_WPSR          0xe8                    /* Write Protect Status Register [some SAM9] */
+#define                AT91_PMC_WPVS           (0x1  <<  0)            /* Write Protect Violation Status */
+#define                AT91_PMC_WPVSRC         (0xffff  <<  8)         /* Write Protect Violation Source */
 
-#define AT91_PMC_VER           (AT91_PMC + 0xfc)       /* PMC Module Version [AT91CAP9 only] */
+#define AT91_PMC_PCR           0x10c                   /* Peripheral Control Register [some SAM9] */
+#define                AT91_PMC_PCR_PID        (0x3f  <<  0)           /* Peripheral ID */
+#define                AT91_PMC_PCR_CMD        (0x1  <<  12)           /* Command */
+#define                AT91_PMC_PCR_DIV        (0x3  <<  16)           /* Divisor Value */
+#define                AT91_PMC_PCRDIV(n)      (((n) <<  16) & AT91_PMC_PCR_DIV)
+#define                AT91_PMC_PCR_EN         (0x1  <<  28)           /* Enable */
 
 #endif
diff --git a/arch/arm/mach-at91/include/mach/at91_ramc.h b/arch/arm/mach-at91/include/mach/at91_ramc.h
new file mode 100644 (file)
index 0000000..d8aeb27
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Header file for the Atmel RAM Controller
+ *
+ * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ */
+
+#ifndef __AT91_RAMC_H__
+#define __AT91_RAMC_H__
+
+#ifndef __ASSEMBLY__
+extern void __iomem *at91_ramc_base[];
+
+#define at91_ramc_read(id, field) \
+       __raw_readl(at91_ramc_base[id] + field)
+
+#define at91_ramc_write(id, field, value) \
+       __raw_writel(value, at91_ramc_base[id] + field)
+#else
+.extern at91_ramc_base
+#endif
+
+#define AT91_MEMCTRL_MC                0
+#define AT91_MEMCTRL_SDRAMC    1
+#define AT91_MEMCTRL_DDRSDR    2
+
+#include <mach/at91rm9200_sdramc.h>
+#include <mach/at91sam9_ddrsdr.h>
+#include <mach/at91sam9_sdramc.h>
+
+#endif /* __AT91_RAMC_H__ */
index 1d4fe822c77a50fb6ac877b546f1846d1a79f3e9..60478ea8bd46a0b11f2f5f8571b7f66dd095db5b 100644 (file)
@@ -36,9 +36,11 @@ extern void __iomem *at91_shdwc_base;
 #define                        AT91_SHDW_WKMODE0_HIGH          1
 #define                        AT91_SHDW_WKMODE0_LOW           2
 #define                        AT91_SHDW_WKMODE0_ANYLEVEL      3
-#define                AT91_SHDW_CPTWK0        (0xf << 4)              /* Counter On Wake Up 0 */
+#define                AT91_SHDW_CPTWK0_MAX    0xf                     /* Maximum Counter On Wake Up 0 */
+#define                AT91_SHDW_CPTWK0        (AT91_SHDW_CPTWK0_MAX << 4) /* Counter On Wake Up 0 */
 #define                        AT91_SHDW_CPTWK0_(x)    ((x) << 4)
 #define                AT91_SHDW_RTTWKEN       (1   << 16)             /* Real Time Timer Wake-up Enable */
+#define                AT91_SHDW_RTCWKEN       (1   << 17)             /* Real Time Clock Wake-up Enable */
 
 #define AT91_SHDW_SR           0x08                    /* Shut Down Status Register */
 #define                AT91_SHDW_WAKEUP0       (1 <<  0)               /* Wake-up 0 Status */
index 8847173e4101b1977c78752eafc40560a0bc6046..969aac27109fbabe5bd991f2990cae6a4e4666a2 100644 (file)
 #ifndef AT91_ST_H
 #define AT91_ST_H
 
-#define        AT91_ST_CR              (AT91_ST + 0x00)        /* Control Register */
+#ifndef __ASSEMBLY__
+extern void __iomem *at91_st_base;
+
+#define at91_st_read(field) \
+       __raw_readl(at91_st_base + field)
+
+#define at91_st_write(field, value) \
+       __raw_writel(value, at91_st_base + field);
+#else
+.extern at91_st_base
+#endif
+
+#define        AT91_ST_CR              0x00                    /* Control Register */
 #define        AT91_ST_WDRST           (1 << 0)                /* Watchdog Timer Restart */
 
-#define        AT91_ST_PIMR            (AT91_ST + 0x04)        /* Period Interval Mode Register */
+#define        AT91_ST_PIMR            0x04                    /* Period Interval Mode Register */
 #define                AT91_ST_PIV             (0xffff <<  0)          /* Period Interval Value */
 
-#define        AT91_ST_WDMR            (AT91_ST + 0x08)        /* Watchdog Mode Register */
+#define        AT91_ST_WDMR            0x08                    /* Watchdog Mode Register */
 #define                AT91_ST_WDV             (0xffff <<  0)          /* Watchdog Counter Value */
 #define                AT91_ST_RSTEN           (1      << 16)          /* Reset Enable */
 #define                AT91_ST_EXTEN           (1      << 17)          /* External Signal Assertion Enable */
 
-#define        AT91_ST_RTMR            (AT91_ST + 0x0c)        /* Real-time Mode Register */
+#define        AT91_ST_RTMR            0x0c                    /* Real-time Mode Register */
 #define                AT91_ST_RTPRES          (0xffff <<  0)          /* Real-time Prescalar Value */
 
-#define        AT91_ST_SR              (AT91_ST + 0x10)        /* Status Register */
+#define        AT91_ST_SR              0x10                    /* Status Register */
 #define                AT91_ST_PITS            (1 << 0)                /* Period Interval Timer Status */
 #define                AT91_ST_WDOVF           (1 << 1)                /* Watchdog Overflow */
 #define                AT91_ST_RTTINC          (1 << 2)                /* Real-time Timer Increment */
 #define                AT91_ST_ALMS            (1 << 3)                /* Alarm Status */
 
-#define        AT91_ST_IER             (AT91_ST + 0x14)        /* Interrupt Enable Register */
-#define        AT91_ST_IDR             (AT91_ST + 0x18)        /* Interrupt Disable Register */
-#define        AT91_ST_IMR             (AT91_ST + 0x1c)        /* Interrupt Mask Register */
+#define        AT91_ST_IER             0x14                    /* Interrupt Enable Register */
+#define        AT91_ST_IDR             0x18                    /* Interrupt Disable Register */
+#define        AT91_ST_IMR             0x1c                    /* Interrupt Mask Register */
 
-#define        AT91_ST_RTAR            (AT91_ST + 0x20)        /* Real-time Alarm Register */
+#define        AT91_ST_RTAR            0x20                    /* Real-time Alarm Register */
 #define                AT91_ST_ALMV            (0xfffff << 0)          /* Alarm Value */
 
-#define        AT91_ST_CRTR            (AT91_ST + 0x24)        /* Current Real-time Register */
+#define        AT91_ST_CRTR            0x24                    /* Current Real-time Register */
 #define                AT91_ST_CRTV            (0xfffff << 0)          /* Current Real-Time Value */
 
 #endif
diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h
deleted file mode 100644 (file)
index 61d9529..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/at91cap9.h
- *
- *  Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
- *  Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
- *  Copyright (C) 2007 Atmel Corporation.
- *
- * Common definitions.
- * Based on AT91CAP9 datasheet revision B (Preliminary).
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef AT91CAP9_H
-#define AT91CAP9_H
-
-/*
- * Peripheral identifiers/interrupts.
- */
-#define AT91CAP9_ID_PIOABCD    2       /* Parallel IO Controller A, B, C and D */
-#define AT91CAP9_ID_MPB0       3       /* MP Block Peripheral 0 */
-#define AT91CAP9_ID_MPB1       4       /* MP Block Peripheral 1 */
-#define AT91CAP9_ID_MPB2       5       /* MP Block Peripheral 2 */
-#define AT91CAP9_ID_MPB3       6       /* MP Block Peripheral 3 */
-#define AT91CAP9_ID_MPB4       7       /* MP Block Peripheral 4 */
-#define AT91CAP9_ID_US0                8       /* USART 0 */
-#define AT91CAP9_ID_US1                9       /* USART 1 */
-#define AT91CAP9_ID_US2                10      /* USART 2 */
-#define AT91CAP9_ID_MCI0       11      /* Multimedia Card Interface 0 */
-#define AT91CAP9_ID_MCI1       12      /* Multimedia Card Interface 1 */
-#define AT91CAP9_ID_CAN                13      /* CAN */
-#define AT91CAP9_ID_TWI                14      /* Two-Wire Interface */
-#define AT91CAP9_ID_SPI0       15      /* Serial Peripheral Interface 0 */
-#define AT91CAP9_ID_SPI1       16      /* Serial Peripheral Interface 0 */
-#define AT91CAP9_ID_SSC0       17      /* Serial Synchronous Controller 0 */
-#define AT91CAP9_ID_SSC1       18      /* Serial Synchronous Controller 1 */
-#define AT91CAP9_ID_AC97C      19      /* AC97 Controller */
-#define AT91CAP9_ID_TCB                20      /* Timer Counter 0, 1 and 2 */
-#define AT91CAP9_ID_PWMC       21      /* Pulse Width Modulation Controller */
-#define AT91CAP9_ID_EMAC       22      /* Ethernet */
-#define AT91CAP9_ID_AESTDES    23      /* Advanced Encryption Standard, Triple DES */
-#define AT91CAP9_ID_ADC                24      /* Analog-to-Digital Converter */
-#define AT91CAP9_ID_ISI                25      /* Image Sensor Interface */
-#define AT91CAP9_ID_LCDC       26      /* LCD Controller */
-#define AT91CAP9_ID_DMA                27      /* DMA Controller */
-#define AT91CAP9_ID_UDPHS      28      /* USB High Speed Device Port */
-#define AT91CAP9_ID_UHP                29      /* USB Host Port */
-#define AT91CAP9_ID_IRQ0       30      /* Advanced Interrupt Controller (IRQ0) */
-#define AT91CAP9_ID_IRQ1       31      /* Advanced Interrupt Controller (IRQ1) */
-
-/*
- * User Peripheral physical base addresses.
- */
-#define AT91CAP9_BASE_UDPHS            0xfff78000
-#define AT91CAP9_BASE_TCB0             0xfff7c000
-#define AT91CAP9_BASE_TC0              0xfff7c000
-#define AT91CAP9_BASE_TC1              0xfff7c040
-#define AT91CAP9_BASE_TC2              0xfff7c080
-#define AT91CAP9_BASE_MCI0             0xfff80000
-#define AT91CAP9_BASE_MCI1             0xfff84000
-#define AT91CAP9_BASE_TWI              0xfff88000
-#define AT91CAP9_BASE_US0              0xfff8c000
-#define AT91CAP9_BASE_US1              0xfff90000
-#define AT91CAP9_BASE_US2              0xfff94000
-#define AT91CAP9_BASE_SSC0             0xfff98000
-#define AT91CAP9_BASE_SSC1             0xfff9c000
-#define AT91CAP9_BASE_AC97C            0xfffa0000
-#define AT91CAP9_BASE_SPI0             0xfffa4000
-#define AT91CAP9_BASE_SPI1             0xfffa8000
-#define AT91CAP9_BASE_CAN              0xfffac000
-#define AT91CAP9_BASE_PWMC             0xfffb8000
-#define AT91CAP9_BASE_EMAC             0xfffbc000
-#define AT91CAP9_BASE_ADC              0xfffc0000
-#define AT91CAP9_BASE_ISI              0xfffc4000
-
-/*
- * System Peripherals (offset from AT91_BASE_SYS)
- */
-#define AT91_BCRAMC    (0xffffe400 - AT91_BASE_SYS)
-#define AT91_DDRSDRC0  (0xffffe600 - AT91_BASE_SYS)
-#define AT91_MATRIX    (0xffffea00 - AT91_BASE_SYS)
-#define AT91_PMC       (0xfffffc00 - AT91_BASE_SYS)
-#define AT91_GPBR      (cpu_is_at91cap9_revB() ?       \
-                       (0xfffffd50 - AT91_BASE_SYS) :  \
-                       (0xfffffd60 - AT91_BASE_SYS))
-
-#define AT91CAP9_BASE_ECC      0xffffe200
-#define AT91CAP9_BASE_DMA      0xffffec00
-#define AT91CAP9_BASE_SMC      0xffffe800
-#define AT91CAP9_BASE_DBGU     AT91_BASE_DBGU1
-#define AT91CAP9_BASE_PIOA     0xfffff200
-#define AT91CAP9_BASE_PIOB     0xfffff400
-#define AT91CAP9_BASE_PIOC     0xfffff600
-#define AT91CAP9_BASE_PIOD     0xfffff800
-#define AT91CAP9_BASE_RSTC     0xfffffd00
-#define AT91CAP9_BASE_SHDWC    0xfffffd10
-#define AT91CAP9_BASE_RTT      0xfffffd20
-#define AT91CAP9_BASE_PIT      0xfffffd30
-#define AT91CAP9_BASE_WDT      0xfffffd40
-
-#define AT91_USART0    AT91CAP9_BASE_US0
-#define AT91_USART1    AT91CAP9_BASE_US1
-#define AT91_USART2    AT91CAP9_BASE_US2
-
-
-/*
- * Internal Memory.
- */
-#define AT91CAP9_SRAM_BASE     0x00100000      /* Internal SRAM base address */
-#define AT91CAP9_SRAM_SIZE     (32 * SZ_1K)    /* Internal SRAM size (32Kb) */
-
-#define AT91CAP9_ROM_BASE      0x00400000      /* Internal ROM base address */
-#define AT91CAP9_ROM_SIZE      (32 * SZ_1K)    /* Internal ROM size (32Kb) */
-
-#define AT91CAP9_LCDC_BASE     0x00500000      /* LCD Controller */
-#define AT91CAP9_UDPHS_FIFO    0x00600000      /* USB High Speed Device Port */
-#define AT91CAP9_UHP_BASE      0x00700000      /* USB Host controller */
-
-#endif
diff --git a/arch/arm/mach-at91/include/mach/at91cap9_matrix.h b/arch/arm/mach-at91/include/mach/at91cap9_matrix.h
deleted file mode 100644 (file)
index 4b9d4af..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/at91cap9_matrix.h
- *
- *  Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
- *  Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
- *  Copyright (C) 2006 Atmel Corporation.
- *
- * Memory Controllers (MATRIX, EBI) - System peripherals registers.
- * Based on AT91CAP9 datasheet revision B (Preliminary).
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef AT91CAP9_MATRIX_H
-#define AT91CAP9_MATRIX_H
-
-#define AT91_MATRIX_MCFG0      (AT91_MATRIX + 0x00)    /* Master Configuration Register 0 */
-#define AT91_MATRIX_MCFG1      (AT91_MATRIX + 0x04)    /* Master Configuration Register 1 */
-#define AT91_MATRIX_MCFG2      (AT91_MATRIX + 0x08)    /* Master Configuration Register 2 */
-#define AT91_MATRIX_MCFG3      (AT91_MATRIX + 0x0C)    /* Master Configuration Register 3 */
-#define AT91_MATRIX_MCFG4      (AT91_MATRIX + 0x10)    /* Master Configuration Register 4 */
-#define AT91_MATRIX_MCFG5      (AT91_MATRIX + 0x14)    /* Master Configuration Register 5 */
-#define AT91_MATRIX_MCFG6      (AT91_MATRIX + 0x18)    /* Master Configuration Register 6 */
-#define AT91_MATRIX_MCFG7      (AT91_MATRIX + 0x1C)    /* Master Configuration Register 7 */
-#define AT91_MATRIX_MCFG8      (AT91_MATRIX + 0x20)    /* Master Configuration Register 8 */
-#define AT91_MATRIX_MCFG9      (AT91_MATRIX + 0x24)    /* Master Configuration Register 9 */
-#define AT91_MATRIX_MCFG10     (AT91_MATRIX + 0x28)    /* Master Configuration Register 10 */
-#define AT91_MATRIX_MCFG11     (AT91_MATRIX + 0x2C)    /* Master Configuration Register 11 */
-#define                AT91_MATRIX_ULBT        (7 << 0)        /* Undefined Length Burst Type */
-#define                        AT91_MATRIX_ULBT_INFINITE       (0 << 0)
-#define                        AT91_MATRIX_ULBT_SINGLE         (1 << 0)
-#define                        AT91_MATRIX_ULBT_FOUR           (2 << 0)
-#define                        AT91_MATRIX_ULBT_EIGHT          (3 << 0)
-#define                        AT91_MATRIX_ULBT_SIXTEEN        (4 << 0)
-
-#define AT91_MATRIX_SCFG0      (AT91_MATRIX + 0x40)    /* Slave Configuration Register 0 */
-#define AT91_MATRIX_SCFG1      (AT91_MATRIX + 0x44)    /* Slave Configuration Register 1 */
-#define AT91_MATRIX_SCFG2      (AT91_MATRIX + 0x48)    /* Slave Configuration Register 2 */
-#define AT91_MATRIX_SCFG3      (AT91_MATRIX + 0x4C)    /* Slave Configuration Register 3 */
-#define AT91_MATRIX_SCFG4      (AT91_MATRIX + 0x50)    /* Slave Configuration Register 4 */
-#define AT91_MATRIX_SCFG5      (AT91_MATRIX + 0x54)    /* Slave Configuration Register 5 */
-#define AT91_MATRIX_SCFG6      (AT91_MATRIX + 0x58)    /* Slave Configuration Register 6 */
-#define AT91_MATRIX_SCFG7      (AT91_MATRIX + 0x5C)    /* Slave Configuration Register 7 */
-#define AT91_MATRIX_SCFG8      (AT91_MATRIX + 0x60)    /* Slave Configuration Register 8 */
-#define AT91_MATRIX_SCFG9      (AT91_MATRIX + 0x64)    /* Slave Configuration Register 9 */
-#define                AT91_MATRIX_SLOT_CYCLE          (0xff << 0)     /* Maximum Number of Allowed Cycles for a Burst */
-#define                AT91_MATRIX_DEFMSTR_TYPE        (3    << 16)    /* Default Master Type */
-#define                        AT91_MATRIX_DEFMSTR_TYPE_NONE   (0 << 16)
-#define                        AT91_MATRIX_DEFMSTR_TYPE_LAST   (1 << 16)
-#define                        AT91_MATRIX_DEFMSTR_TYPE_FIXED  (2 << 16)
-#define                AT91_MATRIX_FIXED_DEFMSTR       (0xf  << 18)    /* Fixed Index of Default Master */
-#define                AT91_MATRIX_ARBT                (3    << 24)    /* Arbitration Type */
-#define                        AT91_MATRIX_ARBT_ROUND_ROBIN    (0 << 24)
-#define                        AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24)
-
-#define AT91_MATRIX_PRAS0      (AT91_MATRIX + 0x80)    /* Priority Register A for Slave 0 */
-#define AT91_MATRIX_PRBS0      (AT91_MATRIX + 0x84)    /* Priority Register B for Slave 0 */
-#define AT91_MATRIX_PRAS1      (AT91_MATRIX + 0x88)    /* Priority Register A for Slave 1 */
-#define AT91_MATRIX_PRBS1      (AT91_MATRIX + 0x8C)    /* Priority Register B for Slave 1 */
-#define AT91_MATRIX_PRAS2      (AT91_MATRIX + 0x90)    /* Priority Register A for Slave 2 */
-#define AT91_MATRIX_PRBS2      (AT91_MATRIX + 0x94)    /* Priority Register B for Slave 2 */
-#define AT91_MATRIX_PRAS3      (AT91_MATRIX + 0x98)    /* Priority Register A for Slave 3 */
-#define AT91_MATRIX_PRBS3      (AT91_MATRIX + 0x9C)    /* Priority Register B for Slave 3 */
-#define AT91_MATRIX_PRAS4      (AT91_MATRIX + 0xA0)    /* Priority Register A for Slave 4 */
-#define AT91_MATRIX_PRBS4      (AT91_MATRIX + 0xA4)    /* Priority Register B for Slave 4 */
-#define AT91_MATRIX_PRAS5      (AT91_MATRIX + 0xA8)    /* Priority Register A for Slave 5 */
-#define AT91_MATRIX_PRBS5      (AT91_MATRIX + 0xAC)    /* Priority Register B for Slave 5 */
-#define AT91_MATRIX_PRAS6      (AT91_MATRIX + 0xB0)    /* Priority Register A for Slave 6 */
-#define AT91_MATRIX_PRBS6      (AT91_MATRIX + 0xB4)    /* Priority Register B for Slave 6 */
-#define AT91_MATRIX_PRAS7      (AT91_MATRIX + 0xB8)    /* Priority Register A for Slave 7 */
-#define AT91_MATRIX_PRBS7      (AT91_MATRIX + 0xBC)    /* Priority Register B for Slave 7 */
-#define AT91_MATRIX_PRAS8      (AT91_MATRIX + 0xC0)    /* Priority Register A for Slave 8 */
-#define AT91_MATRIX_PRBS8      (AT91_MATRIX + 0xC4)    /* Priority Register B for Slave 8 */
-#define AT91_MATRIX_PRAS9      (AT91_MATRIX + 0xC8)    /* Priority Register A for Slave 9 */
-#define AT91_MATRIX_PRBS9      (AT91_MATRIX + 0xCC)    /* Priority Register B for Slave 9 */
-#define                AT91_MATRIX_M0PR                (3 << 0)        /* Master 0 Priority */
-#define                AT91_MATRIX_M1PR                (3 << 4)        /* Master 1 Priority */
-#define                AT91_MATRIX_M2PR                (3 << 8)        /* Master 2 Priority */
-#define                AT91_MATRIX_M3PR                (3 << 12)       /* Master 3 Priority */
-#define                AT91_MATRIX_M4PR                (3 << 16)       /* Master 4 Priority */
-#define                AT91_MATRIX_M5PR                (3 << 20)       /* Master 5 Priority */
-#define                AT91_MATRIX_M6PR                (3 << 24)       /* Master 6 Priority */
-#define                AT91_MATRIX_M7PR                (3 << 28)       /* Master 7 Priority */
-#define                AT91_MATRIX_M8PR                (3 << 0)        /* Master 8 Priority (in Register B) */
-#define                AT91_MATRIX_M9PR                (3 << 4)        /* Master 9 Priority (in Register B) */
-#define                AT91_MATRIX_M10PR               (3 << 8)        /* Master 10 Priority (in Register B) */
-#define                AT91_MATRIX_M11PR               (3 << 12)       /* Master 11 Priority (in Register B) */
-
-#define AT91_MATRIX_MRCR       (AT91_MATRIX + 0x100)   /* Master Remap Control Register */
-#define                AT91_MATRIX_RCB0                (1 << 0)        /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
-#define                AT91_MATRIX_RCB1                (1 << 1)        /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
-#define                AT91_MATRIX_RCB2                (1 << 2)
-#define                AT91_MATRIX_RCB3                (1 << 3)
-#define                AT91_MATRIX_RCB4                (1 << 4)
-#define                AT91_MATRIX_RCB5                (1 << 5)
-#define                AT91_MATRIX_RCB6                (1 << 6)
-#define                AT91_MATRIX_RCB7                (1 << 7)
-#define                AT91_MATRIX_RCB8                (1 << 8)
-#define                AT91_MATRIX_RCB9                (1 << 9)
-#define                AT91_MATRIX_RCB10               (1 << 10)
-#define                AT91_MATRIX_RCB11               (1 << 11)
-
-#define AT91_MPBS0_SFR         (AT91_MATRIX + 0x114)   /* MPBlock Slave 0 Special Function Register */
-#define AT91_MPBS1_SFR         (AT91_MATRIX + 0x11C)   /* MPBlock Slave 1 Special Function Register */
-
-#define AT91_MATRIX_UDPHS      (AT91_MATRIX + 0x118)   /* USBHS Special Function Register [AT91CAP9 only] */
-#define                AT91_MATRIX_SELECT_UDPHS        (0 << 31)       /* select High Speed UDP */
-#define                AT91_MATRIX_SELECT_UDP          (1 << 31)       /* select standard UDP */
-#define                AT91_MATRIX_UDPHS_BYPASS_LOCK   (1 << 30)       /* bypass lock bit */
-
-#define AT91_MATRIX_EBICSA     (AT91_MATRIX + 0x120)   /* EBI Chip Select Assignment Register */
-#define                AT91_MATRIX_EBI_CS1A            (1 << 1)        /* Chip Select 1 Assignment */
-#define                        AT91_MATRIX_EBI_CS1A_SMC                (0 << 1)
-#define                        AT91_MATRIX_EBI_CS1A_BCRAMC             (1 << 1)
-#define                AT91_MATRIX_EBI_CS3A            (1 << 3)        /* Chip Select 3 Assignment */
-#define                        AT91_MATRIX_EBI_CS3A_SMC                (0 << 3)
-#define                        AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA     (1 << 3)
-#define                AT91_MATRIX_EBI_CS4A            (1 << 4)        /* Chip Select 4 Assignment */
-#define                        AT91_MATRIX_EBI_CS4A_SMC                (0 << 4)
-#define                        AT91_MATRIX_EBI_CS4A_SMC_CF1            (1 << 4)
-#define                AT91_MATRIX_EBI_CS5A            (1 << 5)        /* Chip Select 5 Assignment */
-#define                        AT91_MATRIX_EBI_CS5A_SMC                (0 << 5)
-#define                        AT91_MATRIX_EBI_CS5A_SMC_CF2            (1 << 5)
-#define                AT91_MATRIX_EBI_DBPUC           (1 << 8)        /* Data Bus Pull-up Configuration */
-#define                AT91_MATRIX_EBI_DQSPDC          (1 << 9)        /* Data Qualifier Strobe Pull-Down Configuration */
-#define                AT91_MATRIX_EBI_VDDIOMSEL       (1 << 16)       /* Memory voltage selection */
-#define                        AT91_MATRIX_EBI_VDDIOMSEL_1_8V          (0 << 16)
-#define                        AT91_MATRIX_EBI_VDDIOMSEL_3_3V          (1 << 16)
-
-#define AT91_MPBS2_SFR         (AT91_MATRIX + 0x12C)   /* MPBlock Slave 2 Special Function Register */
-#define AT91_MPBS3_SFR         (AT91_MATRIX + 0x130)   /* MPBlock Slave 3 Special Function Register */
-#define AT91_APB_SFR           (AT91_MATRIX + 0x134)   /* APB Bridge Special Function Register */
-
-#endif
index bacb511418194eef2665579555bc3ffa2b608383..603e6aac2a4fb9d9a55c6d37b639ff19649e9e81 100644 (file)
 
 
 /*
- * System Peripherals (offset from AT91_BASE_SYS)
+ * System Peripherals
  */
-#define AT91_PMC       (0xfffffc00 - AT91_BASE_SYS)    /* Power Management Controller */
-#define AT91_ST                (0xfffffd00 - AT91_BASE_SYS)    /* System Timer */
-#define AT91_MC                (0xffffff00 - AT91_BASE_SYS)    /* Memory Controllers */
-
 #define AT91RM9200_BASE_DBGU   AT91_BASE_DBGU0 /* Debug Unit */
 #define AT91RM9200_BASE_PIOA   0xfffff400      /* PIO Controller A */
 #define AT91RM9200_BASE_PIOB   0xfffff600      /* PIO Controller B */
 #define AT91RM9200_BASE_PIOC   0xfffff800      /* PIO Controller C */
 #define AT91RM9200_BASE_PIOD   0xfffffa00      /* PIO Controller D */
+#define AT91RM9200_BASE_ST     0xfffffd00      /* System Timer */
 #define AT91RM9200_BASE_RTC    0xfffffe00      /* Real-Time Clock */
+#define AT91RM9200_BASE_MC     0xffffff00      /* Memory Controllers */
 
 #define AT91_USART0    AT91RM9200_BASE_US0
 #define AT91_USART1    AT91RM9200_BASE_US1
 #define AT91_USART2    AT91RM9200_BASE_US2
 #define AT91_USART3    AT91RM9200_BASE_US3
 
-#define AT91_MATRIX    0       /* not supported */
-
 /*
  * Internal Memory.
  */
index d34e4ed89349639fc1c6bb5e3656da50c242006d..aeaadfb452afd00051522c24f191dad32a7dd4f6 100644 (file)
 #define AT91RM9200_MC_H
 
 /* Memory Controller */
-#define AT91_MC_RCR            (AT91_MC + 0x00)        /* MC Remap Control Register */
+#define AT91_MC_RCR            0x00                    /* MC Remap Control Register */
 #define                AT91_MC_RCB             (1 <<  0)               /* Remap Command Bit */
 
-#define AT91_MC_ASR            (AT91_MC + 0x04)        /* MC Abort Status Register */
+#define AT91_MC_ASR            0x04                    /* MC Abort Status Register */
 #define                AT91_MC_UNADD           (1 <<  0)               /* Undefined Address Abort Status */
 #define                AT91_MC_MISADD          (1 <<  1)               /* Misaligned Address Abort Status */
 #define                AT91_MC_ABTSZ           (3 <<  8)               /* Abort Size Status */
 #define                AT91_MC_SVMST2          (1 << 26)               /* Saved UHP Abort Source */
 #define                AT91_MC_SVMST3          (1 << 27)               /* Saved EMAC Abort Source */
 
-#define AT91_MC_AASR           (AT91_MC + 0x08)        /* MC Abort Address Status Register */
+#define AT91_MC_AASR           0x08                    /* MC Abort Address Status Register */
 
-#define AT91_MC_MPR            (AT91_MC + 0x0c)        /* MC Master Priority Register */
+#define AT91_MC_MPR            0x0c                    /* MC Master Priority Register */
 #define                AT91_MPR_MSTP0          (7 <<  0)               /* ARM920T Priority */
 #define                AT91_MPR_MSTP1          (7 <<  4)               /* PDC Priority */
 #define                AT91_MPR_MSTP2          (7 <<  8)               /* UHP Priority */
 #define                AT91_MPR_MSTP3          (7 << 12)               /* EMAC Priority */
 
 /* External Bus Interface (EBI) registers */
-#define AT91_EBI_CSA           (AT91_MC + 0x60)        /* Chip Select Assignment Register */
+#define AT91_EBI_CSA           0x60                    /* Chip Select Assignment Register */
 #define                AT91_EBI_CS0A           (1 << 0)                /* Chip Select 0 Assignment */
 #define                        AT91_EBI_CS0A_SMC               (0 << 0)
 #define                        AT91_EBI_CS0A_BFC               (1 << 0)
@@ -66,7 +66,7 @@
 #define                AT91_EBI_DBPUC          (1 << 0)                /* Data Bus Pull-Up Configuration */
 
 /* Static Memory Controller (SMC) registers */
-#define        AT91_SMC_CSR(n)         (AT91_MC + 0x70 + ((n) * 4))/* SMC Chip Select Register */
+#define        AT91_SMC_CSR(n)         (0x70 + ((n) * 4))      /* SMC Chip Select Register */
 #define                AT91_SMC_NWS            (0x7f <<  0)            /* Number of Wait States */
 #define                        AT91_SMC_NWS_(x)        ((x) << 0)
 #define                AT91_SMC_WSEN           (1    <<  7)            /* Wait State Enable */
 #define                AT91_SMC_RWHOLD         (7 << 28)               /* Read & Write Signal Hold Time */
 #define                        AT91_SMC_RWHOLD_(x)     ((x) << 28)
 
-/* SDRAM Controller registers */
-#define AT91_SDRAMC_MR         (AT91_MC + 0x90)        /* Mode Register */
-#define                AT91_SDRAMC_MODE        (0xf << 0)              /* Command Mode */
-#define                        AT91_SDRAMC_MODE_NORMAL         (0 << 0)
-#define                        AT91_SDRAMC_MODE_NOP            (1 << 0)
-#define                        AT91_SDRAMC_MODE_PRECHARGE      (2 << 0)
-#define                        AT91_SDRAMC_MODE_LMR            (3 << 0)
-#define                        AT91_SDRAMC_MODE_REFRESH        (4 << 0)
-#define                AT91_SDRAMC_DBW         (1   << 4)              /* Data Bus Width */
-#define                        AT91_SDRAMC_DBW_32      (0 << 4)
-#define                        AT91_SDRAMC_DBW_16      (1 << 4)
-
-#define AT91_SDRAMC_TR         (AT91_MC + 0x94)        /* Refresh Timer Register */
-#define                AT91_SDRAMC_COUNT       (0xfff << 0)            /* Refresh Timer Count */
-
-#define AT91_SDRAMC_CR         (AT91_MC + 0x98)        /* Configuration Register */
-#define                AT91_SDRAMC_NC          (3   <<  0)             /* Number of Column Bits */
-#define                        AT91_SDRAMC_NC_8        (0 << 0)
-#define                        AT91_SDRAMC_NC_9        (1 << 0)
-#define                        AT91_SDRAMC_NC_10       (2 << 0)
-#define                        AT91_SDRAMC_NC_11       (3 << 0)
-#define                AT91_SDRAMC_NR          (3   <<  2)             /* Number of Row Bits */
-#define                        AT91_SDRAMC_NR_11       (0 << 2)
-#define                        AT91_SDRAMC_NR_12       (1 << 2)
-#define                        AT91_SDRAMC_NR_13       (2 << 2)
-#define                AT91_SDRAMC_NB          (1   <<  4)             /* Number of Banks */
-#define                        AT91_SDRAMC_NB_2        (0 << 4)
-#define                        AT91_SDRAMC_NB_4        (1 << 4)
-#define                AT91_SDRAMC_CAS         (3   <<  5)             /* CAS Latency */
-#define                        AT91_SDRAMC_CAS_2       (2 << 5)
-#define                AT91_SDRAMC_TWR         (0xf <<  7)             /* Write Recovery Delay */
-#define                AT91_SDRAMC_TRC         (0xf << 11)             /* Row Cycle Delay */
-#define                AT91_SDRAMC_TRP         (0xf << 15)             /* Row Precharge Delay */
-#define                AT91_SDRAMC_TRCD        (0xf << 19)             /* Row to Column Delay */
-#define                AT91_SDRAMC_TRAS        (0xf << 23)             /* Active to Precharge Delay */
-#define                AT91_SDRAMC_TXSR        (0xf << 27)             /* Exit Self Refresh to Active Delay */
-
-#define AT91_SDRAMC_SRR                (AT91_MC + 0x9c)        /* Self Refresh Register */
-#define AT91_SDRAMC_LPR                (AT91_MC + 0xa0)        /* Low Power Register */
-#define AT91_SDRAMC_IER                (AT91_MC + 0xa4)        /* Interrupt Enable Register */
-#define AT91_SDRAMC_IDR                (AT91_MC + 0xa8)        /* Interrupt Disable Register */
-#define AT91_SDRAMC_IMR                (AT91_MC + 0xac)        /* Interrupt Mask Register */
-#define AT91_SDRAMC_ISR                (AT91_MC + 0xb0)        /* Interrupt Status Register */
-
 /* Burst Flash Controller register */
-#define AT91_BFC_MR            (AT91_MC + 0xc0)        /* Mode Register */
+#define AT91_BFC_MR            0xc0                    /* Mode Register */
 #define                AT91_BFC_BFCOM          (3   <<  0)             /* Burst Flash Controller Operating Mode */
 #define                        AT91_BFC_BFCOM_DISABLED (0 << 0)
 #define                        AT91_BFC_BFCOM_ASYNC    (1 << 0)
diff --git a/arch/arm/mach-at91/include/mach/at91rm9200_sdramc.h b/arch/arm/mach-at91/include/mach/at91rm9200_sdramc.h
new file mode 100644 (file)
index 0000000..aa047f4
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91rm9200_sdramc.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * Memory Controllers (SDRAMC only) - System peripherals registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef AT91RM9200_SDRAMC_H
+#define AT91RM9200_SDRAMC_H
+
+/* SDRAM Controller registers */
+#define AT91RM9200_SDRAMC_MR           0x90                    /* Mode Register */
+#define                AT91RM9200_SDRAMC_MODE  (0xf << 0)              /* Command Mode */
+#define                        AT91RM9200_SDRAMC_MODE_NORMAL           (0 << 0)
+#define                        AT91RM9200_SDRAMC_MODE_NOP              (1 << 0)
+#define                        AT91RM9200_SDRAMC_MODE_PRECHARGE        (2 << 0)
+#define                        AT91RM9200_SDRAMC_MODE_LMR              (3 << 0)
+#define                        AT91RM9200_SDRAMC_MODE_REFRESH  (4 << 0)
+#define                AT91RM9200_SDRAMC_DBW           (1   << 4)              /* Data Bus Width */
+#define                        AT91RM9200_SDRAMC_DBW_32        (0 << 4)
+#define                        AT91RM9200_SDRAMC_DBW_16        (1 << 4)
+
+#define AT91RM9200_SDRAMC_TR           0x94                    /* Refresh Timer Register */
+#define                AT91RM9200_SDRAMC_COUNT (0xfff << 0)            /* Refresh Timer Count */
+
+#define AT91RM9200_SDRAMC_CR           0x98                    /* Configuration Register */
+#define                AT91RM9200_SDRAMC_NC            (3   <<  0)             /* Number of Column Bits */
+#define                        AT91RM9200_SDRAMC_NC_8  (0 << 0)
+#define                        AT91RM9200_SDRAMC_NC_9  (1 << 0)
+#define                        AT91RM9200_SDRAMC_NC_10 (2 << 0)
+#define                        AT91RM9200_SDRAMC_NC_11 (3 << 0)
+#define                AT91RM9200_SDRAMC_NR            (3   <<  2)             /* Number of Row Bits */
+#define                        AT91RM9200_SDRAMC_NR_11 (0 << 2)
+#define                        AT91RM9200_SDRAMC_NR_12 (1 << 2)
+#define                        AT91RM9200_SDRAMC_NR_13 (2 << 2)
+#define                AT91RM9200_SDRAMC_NB            (1   <<  4)             /* Number of Banks */
+#define                        AT91RM9200_SDRAMC_NB_2  (0 << 4)
+#define                        AT91RM9200_SDRAMC_NB_4  (1 << 4)
+#define                AT91RM9200_SDRAMC_CAS           (3   <<  5)             /* CAS Latency */
+#define                        AT91RM9200_SDRAMC_CAS_2 (2 << 5)
+#define                AT91RM9200_SDRAMC_TWR           (0xf <<  7)             /* Write Recovery Delay */
+#define                AT91RM9200_SDRAMC_TRC           (0xf << 11)             /* Row Cycle Delay */
+#define                AT91RM9200_SDRAMC_TRP           (0xf << 15)             /* Row Precharge Delay */
+#define                AT91RM9200_SDRAMC_TRCD  (0xf << 19)             /* Row to Column Delay */
+#define                AT91RM9200_SDRAMC_TRAS  (0xf << 23)             /* Active to Precharge Delay */
+#define                AT91RM9200_SDRAMC_TXSR  (0xf << 27)             /* Exit Self Refresh to Active Delay */
+
+#define AT91RM9200_SDRAMC_SRR          0x9c                    /* Self Refresh Register */
+#define AT91RM9200_SDRAMC_LPR          0xa0                    /* Low Power Register */
+#define AT91RM9200_SDRAMC_IER          0xa4                    /* Interrupt Enable Register */
+#define AT91RM9200_SDRAMC_IDR          0xa8                    /* Interrupt Disable Register */
+#define AT91RM9200_SDRAMC_IMR          0xac                    /* Interrupt Mask Register */
+#define AT91RM9200_SDRAMC_ISR          0xb0                    /* Interrupt Status Register */
+
+#endif
index fa5ca278adebf726a2cf849e162e33a82bc101b6..08ae9afd00fed48852fe6c62d851cb96683080cc 100644 (file)
 #define AT91SAM9260_BASE_ADC           0xfffe0000
 
 /*
- * System Peripherals (offset from AT91_BASE_SYS)
+ * System Peripherals
  */
-#define AT91_SDRAMC0   (0xffffea00 - AT91_BASE_SYS)
-#define AT91_MATRIX    (0xffffee00 - AT91_BASE_SYS)
-#define AT91_PMC       (0xfffffc00 - AT91_BASE_SYS)
-#define AT91_GPBR      (0xfffffd50 - AT91_BASE_SYS)
-
 #define AT91SAM9260_BASE_ECC   0xffffe800
+#define AT91SAM9260_BASE_SDRAMC        0xffffea00
 #define AT91SAM9260_BASE_SMC   0xffffec00
+#define AT91SAM9260_BASE_MATRIX        0xffffee00
 #define AT91SAM9260_BASE_DBGU  AT91_BASE_DBGU0
 #define AT91SAM9260_BASE_PIOA  0xfffff400
 #define AT91SAM9260_BASE_PIOB  0xfffff600
@@ -96,6 +93,7 @@
 #define AT91SAM9260_BASE_RTT   0xfffffd20
 #define AT91SAM9260_BASE_PIT   0xfffffd30
 #define AT91SAM9260_BASE_WDT   0xfffffd40
+#define AT91SAM9260_BASE_GPBR  0xfffffd50
 
 #define AT91_USART0    AT91SAM9260_BASE_US0
 #define AT91_USART1    AT91SAM9260_BASE_US1
 #define AT91SAM9260_SRAM0_SIZE SZ_4K           /* Internal SRAM 0 size (4Kb) */
 #define AT91SAM9260_SRAM1_BASE 0x00300000      /* Internal SRAM 1 base address */
 #define AT91SAM9260_SRAM1_SIZE SZ_4K           /* Internal SRAM 1 size (4Kb) */
+#define AT91SAM9260_SRAM_BASE  0x002FF000      /* Internal SRAM base address */
+#define AT91SAM9260_SRAM_SIZE  SZ_8K           /* Internal SRAM size (8Kb) */
 
 #define AT91SAM9260_UHP_BASE   0x00500000      /* USB Host controller */
 
 #define AT91SAM9G20_SRAM0_SIZE SZ_16K          /* Internal SRAM 0 size (16Kb) */
 #define AT91SAM9G20_SRAM1_BASE 0x00300000      /* Internal SRAM 1 base address */
 #define AT91SAM9G20_SRAM1_SIZE SZ_16K          /* Internal SRAM 1 size (16Kb) */
+#define AT91SAM9G20_SRAM_BASE  0x002FC000      /* Internal SRAM base address */
+#define AT91SAM9G20_SRAM_SIZE  SZ_32K          /* Internal SRAM size (32Kb) */
 
 #define AT91SAM9G20_UHP_BASE   0x00500000      /* USB Host controller */
 
index 020f02ed921a85590b03bb8a9c27552992354096..f459df4206291fbecd2b8d190170454b607a57ee 100644 (file)
 #ifndef AT91SAM9260_MATRIX_H
 #define AT91SAM9260_MATRIX_H
 
-#define AT91_MATRIX_MCFG0      (AT91_MATRIX + 0x00)    /* Master Configuration Register 0 */
-#define AT91_MATRIX_MCFG1      (AT91_MATRIX + 0x04)    /* Master Configuration Register 1 */
-#define AT91_MATRIX_MCFG2      (AT91_MATRIX + 0x08)    /* Master Configuration Register 2 */
-#define AT91_MATRIX_MCFG3      (AT91_MATRIX + 0x0C)    /* Master Configuration Register 3 */
-#define AT91_MATRIX_MCFG4      (AT91_MATRIX + 0x10)    /* Master Configuration Register 4 */
-#define AT91_MATRIX_MCFG5      (AT91_MATRIX + 0x14)    /* Master Configuration Register 5 */
+#define AT91_MATRIX_MCFG0      0x00                    /* Master Configuration Register 0 */
+#define AT91_MATRIX_MCFG1      0x04                    /* Master Configuration Register 1 */
+#define AT91_MATRIX_MCFG2      0x08                    /* Master Configuration Register 2 */
+#define AT91_MATRIX_MCFG3      0x0C                    /* Master Configuration Register 3 */
+#define AT91_MATRIX_MCFG4      0x10                    /* Master Configuration Register 4 */
+#define AT91_MATRIX_MCFG5      0x14                    /* Master Configuration Register 5 */
 #define                AT91_MATRIX_ULBT                (7 << 0)        /* Undefined Length Burst Type */
 #define                        AT91_MATRIX_ULBT_INFINITE       (0 << 0)
 #define                        AT91_MATRIX_ULBT_SINGLE         (1 << 0)
 #define                        AT91_MATRIX_ULBT_EIGHT          (3 << 0)
 #define                        AT91_MATRIX_ULBT_SIXTEEN        (4 << 0)
 
-#define AT91_MATRIX_SCFG0      (AT91_MATRIX + 0x40)    /* Slave Configuration Register 0 */
-#define AT91_MATRIX_SCFG1      (AT91_MATRIX + 0x44)    /* Slave Configuration Register 1 */
-#define AT91_MATRIX_SCFG2      (AT91_MATRIX + 0x48)    /* Slave Configuration Register 2 */
-#define AT91_MATRIX_SCFG3      (AT91_MATRIX + 0x4C)    /* Slave Configuration Register 3 */
-#define AT91_MATRIX_SCFG4      (AT91_MATRIX + 0x50)    /* Slave Configuration Register 4 */
+#define AT91_MATRIX_SCFG0      0x40                    /* Slave Configuration Register 0 */
+#define AT91_MATRIX_SCFG1      0x44                    /* Slave Configuration Register 1 */
+#define AT91_MATRIX_SCFG2      0x48                    /* Slave Configuration Register 2 */
+#define AT91_MATRIX_SCFG3      0x4C                    /* Slave Configuration Register 3 */
+#define AT91_MATRIX_SCFG4      0x50                    /* Slave Configuration Register 4 */
 #define                AT91_MATRIX_SLOT_CYCLE          (0xff <<  0)    /* Maximum Number of Allowed Cycles for a Burst */
 #define                AT91_MATRIX_DEFMSTR_TYPE        (3    << 16)    /* Default Master Type */
 #define                        AT91_MATRIX_DEFMSTR_TYPE_NONE   (0 << 16)
 #define                        AT91_MATRIX_ARBT_ROUND_ROBIN    (0 << 24)
 #define                        AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24)
 
-#define AT91_MATRIX_PRAS0      (AT91_MATRIX + 0x80)    /* Priority Register A for Slave 0 */
-#define AT91_MATRIX_PRAS1      (AT91_MATRIX + 0x88)    /* Priority Register A for Slave 1 */
-#define AT91_MATRIX_PRAS2      (AT91_MATRIX + 0x90)    /* Priority Register A for Slave 2 */
-#define AT91_MATRIX_PRAS3      (AT91_MATRIX + 0x98)    /* Priority Register A for Slave 3 */
-#define AT91_MATRIX_PRAS4      (AT91_MATRIX + 0xA0)    /* Priority Register A for Slave 4 */
+#define AT91_MATRIX_PRAS0      0x80                    /* Priority Register A for Slave 0 */
+#define AT91_MATRIX_PRAS1      0x88                    /* Priority Register A for Slave 1 */
+#define AT91_MATRIX_PRAS2      0x90                    /* Priority Register A for Slave 2 */
+#define AT91_MATRIX_PRAS3      0x98                    /* Priority Register A for Slave 3 */
+#define AT91_MATRIX_PRAS4      0xA0                    /* Priority Register A for Slave 4 */
 #define                AT91_MATRIX_M0PR                (3 << 0)        /* Master 0 Priority */
 #define                AT91_MATRIX_M1PR                (3 << 4)        /* Master 1 Priority */
 #define                AT91_MATRIX_M2PR                (3 << 8)        /* Master 2 Priority */
 #define                AT91_MATRIX_M4PR                (3 << 16)       /* Master 4 Priority */
 #define                AT91_MATRIX_M5PR                (3 << 20)       /* Master 5 Priority */
 
-#define AT91_MATRIX_MRCR       (AT91_MATRIX + 0x100)   /* Master Remap Control Register */
+#define AT91_MATRIX_MRCR       0x100                   /* Master Remap Control Register */
 #define                AT91_MATRIX_RCB0                (1 << 0)        /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
 #define                AT91_MATRIX_RCB1                (1 << 1)        /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
 
-#define AT91_MATRIX_EBICSA     (AT91_MATRIX + 0x11C)   /* EBI Chip Select Assignment Register */
+#define AT91_MATRIX_EBICSA     0x11C                   /* EBI Chip Select Assignment Register */
 #define                AT91_MATRIX_CS1A                (1 << 1)        /* Chip Select 1 Assignment */
 #define                        AT91_MATRIX_CS1A_SMC            (0 << 1)
 #define                        AT91_MATRIX_CS1A_SDRAMC         (1 << 1)
index 7cde2d36570eeee50049e54ff4a2f61ac853a69c..44fbdc12ee6247b4581efc51df0883677fd46cbe 100644 (file)
 
 
 /*
- * System Peripherals (offset from AT91_BASE_SYS)
+ * System Peripherals
  */
-#define AT91_SDRAMC0   (0xffffea00 - AT91_BASE_SYS)
-#define AT91_MATRIX    (0xffffee00 - AT91_BASE_SYS)
-#define AT91_PMC       (0xfffffc00 - AT91_BASE_SYS)
-#define AT91_GPBR      (0xfffffd50 - AT91_BASE_SYS)
-
 #define AT91SAM9261_BASE_SMC   0xffffec00
+#define AT91SAM9261_BASE_MATRIX        0xffffee00
+#define AT91SAM9261_BASE_SDRAMC        0xffffea00
 #define AT91SAM9261_BASE_DBGU  AT91_BASE_DBGU0
 #define AT91SAM9261_BASE_PIOA  0xfffff400
 #define AT91SAM9261_BASE_PIOB  0xfffff600
@@ -80,6 +77,7 @@
 #define AT91SAM9261_BASE_RTT   0xfffffd20
 #define AT91SAM9261_BASE_PIT   0xfffffd30
 #define AT91SAM9261_BASE_WDT   0xfffffd40
+#define AT91SAM9261_BASE_GPBR  0xfffffd50
 
 #define AT91_USART0    AT91SAM9261_BASE_US0
 #define AT91_USART1    AT91SAM9261_BASE_US1
index 69c6501915d90af928427a0d58da6fe5cb8c6c1a..a50cdf8b8ca49c753f1b332450f63cba443e5b2d 100644 (file)
 #ifndef AT91SAM9261_MATRIX_H
 #define AT91SAM9261_MATRIX_H
 
-#define AT91_MATRIX_MCFG       (AT91_MATRIX + 0x00)    /* Master Configuration Register */
+#define AT91_MATRIX_MCFG       0x00                    /* Master Configuration Register */
 #define                AT91_MATRIX_RCB0        (1 << 0)                /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
 #define                AT91_MATRIX_RCB1        (1 << 1)                /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
 
-#define AT91_MATRIX_SCFG0      (AT91_MATRIX + 0x04)    /* Slave Configuration Register 0 */
-#define AT91_MATRIX_SCFG1      (AT91_MATRIX + 0x08)    /* Slave Configuration Register 1 */
-#define AT91_MATRIX_SCFG2      (AT91_MATRIX + 0x0C)    /* Slave Configuration Register 2 */
-#define AT91_MATRIX_SCFG3      (AT91_MATRIX + 0x10)    /* Slave Configuration Register 3 */
-#define AT91_MATRIX_SCFG4      (AT91_MATRIX + 0x14)    /* Slave Configuration Register 4 */
+#define AT91_MATRIX_SCFG0      0x04                    /* Slave Configuration Register 0 */
+#define AT91_MATRIX_SCFG1      0x08                    /* Slave Configuration Register 1 */
+#define AT91_MATRIX_SCFG2      0x0C                    /* Slave Configuration Register 2 */
+#define AT91_MATRIX_SCFG3      0x10                    /* Slave Configuration Register 3 */
+#define AT91_MATRIX_SCFG4      0x14                    /* Slave Configuration Register 4 */
 #define                AT91_MATRIX_SLOT_CYCLE          (0xff << 0)     /* Maximum Number of Allowed Cycles for a Burst */
 #define                AT91_MATRIX_DEFMSTR_TYPE        (3    << 16)    /* Default Master Type */
 #define                        AT91_MATRIX_DEFMSTR_TYPE_NONE   (0 << 16)
@@ -31,7 +31,7 @@
 #define                        AT91_MATRIX_DEFMSTR_TYPE_FIXED  (2 << 16)
 #define                AT91_MATRIX_FIXED_DEFMSTR       (7    << 18)    /* Fixed Index of Default Master */
 
-#define AT91_MATRIX_TCR                (AT91_MATRIX + 0x24)    /* TCM Configuration Register */
+#define AT91_MATRIX_TCR                0x24                    /* TCM Configuration Register */
 #define                AT91_MATRIX_ITCM_SIZE           (0xf << 0)      /* Size of ITCM enabled memory block */
 #define                        AT91_MATRIX_ITCM_0              (0 << 0)
 #define                        AT91_MATRIX_ITCM_16             (5 << 0)
@@ -43,7 +43,7 @@
 #define                        AT91_MATRIX_DTCM_32             (6 << 4)
 #define                        AT91_MATRIX_DTCM_64             (7 << 4)
 
-#define AT91_MATRIX_EBICSA     (AT91_MATRIX + 0x30)    /* EBI Chip Select Assignment Register */
+#define AT91_MATRIX_EBICSA     0x30                    /* EBI Chip Select Assignment Register */
 #define                AT91_MATRIX_CS1A                (1 << 1)        /* Chip Select 1 Assignment */
 #define                        AT91_MATRIX_CS1A_SMC            (0 << 1)
 #define                        AT91_MATRIX_CS1A_SDRAMC         (1 << 1)
@@ -58,7 +58,7 @@
 #define                        AT91_MATRIX_CS5A_SMC_CF2        (1 << 5)
 #define                AT91_MATRIX_DBPUC               (1 << 8)        /* Data Bus Pull-up Configuration */
 
-#define AT91_MATRIX_USBPUCR    (AT91_MATRIX + 0x34)    /* USB Pad Pull-Up Control Register */
+#define AT91_MATRIX_USBPUCR    0x34                    /* USB Pad Pull-Up Control Register */
 #define                AT91_MATRIX_USBPUCR_PUON        (1 << 30)       /* USB Device PAD Pull-up Enable */
 
 #endif
index 5949abda962b2affffaa44c59bfbf4e7138e610f..d96cbb2e03c49a88f936a6ebc8105089366288b8 100644 (file)
 #define AT91SAM9263_BASE_2DGE          0xfffc8000
 
 /*
- * System Peripherals (offset from AT91_BASE_SYS)
+ * System Peripherals
  */
-#define AT91_SDRAMC0   (0xffffe200 - AT91_BASE_SYS)
-#define AT91_SDRAMC1   (0xffffe800 - AT91_BASE_SYS)
-#define AT91_MATRIX    (0xffffec00 - AT91_BASE_SYS)
-#define AT91_PMC       (0xfffffc00 - AT91_BASE_SYS)
-#define AT91_GPBR      (0xfffffd60 - AT91_BASE_SYS)
-
 #define AT91SAM9263_BASE_ECC0  0xffffe000
+#define AT91SAM9263_BASE_SDRAMC0 0xffffe200
 #define AT91SAM9263_BASE_SMC0  0xffffe400
 #define AT91SAM9263_BASE_ECC1  0xffffe600
+#define AT91SAM9263_BASE_SDRAMC1 0xffffe800
 #define AT91SAM9263_BASE_SMC1  0xffffea00
+#define AT91SAM9263_BASE_MATRIX        0xffffec00
 #define AT91SAM9263_BASE_DBGU  AT91_BASE_DBGU1
 #define AT91SAM9263_BASE_PIOA  0xfffff200
 #define AT91SAM9263_BASE_PIOB  0xfffff400
@@ -96,6 +93,7 @@
 #define AT91SAM9263_BASE_PIT   0xfffffd30
 #define AT91SAM9263_BASE_WDT   0xfffffd40
 #define AT91SAM9263_BASE_RTT1  0xfffffd50
+#define AT91SAM9263_BASE_GPBR  0xfffffd60
 
 #define AT91_USART0    AT91SAM9263_BASE_US0
 #define AT91_USART1    AT91SAM9263_BASE_US1
index 9b3efd3eb2f39e121591fe7a5aa3e5f97adc9f44..ebb5fdb565e0c71a9164429608913bdfce736544 100644 (file)
 #ifndef AT91SAM9263_MATRIX_H
 #define AT91SAM9263_MATRIX_H
 
-#define AT91_MATRIX_MCFG0      (AT91_MATRIX + 0x00)    /* Master Configuration Register 0 */
-#define AT91_MATRIX_MCFG1      (AT91_MATRIX + 0x04)    /* Master Configuration Register 1 */
-#define AT91_MATRIX_MCFG2      (AT91_MATRIX + 0x08)    /* Master Configuration Register 2 */
-#define AT91_MATRIX_MCFG3      (AT91_MATRIX + 0x0C)    /* Master Configuration Register 3 */
-#define AT91_MATRIX_MCFG4      (AT91_MATRIX + 0x10)    /* Master Configuration Register 4 */
-#define AT91_MATRIX_MCFG5      (AT91_MATRIX + 0x14)    /* Master Configuration Register 5 */
-#define AT91_MATRIX_MCFG6      (AT91_MATRIX + 0x18)    /* Master Configuration Register 6 */
-#define AT91_MATRIX_MCFG7      (AT91_MATRIX + 0x1C)    /* Master Configuration Register 7 */
-#define AT91_MATRIX_MCFG8      (AT91_MATRIX + 0x20)    /* Master Configuration Register 8 */
+#define AT91_MATRIX_MCFG0      0x00                    /* Master Configuration Register 0 */
+#define AT91_MATRIX_MCFG1      0x04                    /* Master Configuration Register 1 */
+#define AT91_MATRIX_MCFG2      0x08                    /* Master Configuration Register 2 */
+#define AT91_MATRIX_MCFG3      0x0C                    /* Master Configuration Register 3 */
+#define AT91_MATRIX_MCFG4      0x10                    /* Master Configuration Register 4 */
+#define AT91_MATRIX_MCFG5      0x14                    /* Master Configuration Register 5 */
+#define AT91_MATRIX_MCFG6      0x18                    /* Master Configuration Register 6 */
+#define AT91_MATRIX_MCFG7      0x1C                    /* Master Configuration Register 7 */
+#define AT91_MATRIX_MCFG8      0x20                    /* Master Configuration Register 8 */
 #define                AT91_MATRIX_ULBT        (7 << 0)        /* Undefined Length Burst Type */
 #define                        AT91_MATRIX_ULBT_INFINITE       (0 << 0)
 #define                        AT91_MATRIX_ULBT_SINGLE         (1 << 0)
 #define                        AT91_MATRIX_ULBT_EIGHT          (3 << 0)
 #define                        AT91_MATRIX_ULBT_SIXTEEN        (4 << 0)
 
-#define AT91_MATRIX_SCFG0      (AT91_MATRIX + 0x40)    /* Slave Configuration Register 0 */
-#define AT91_MATRIX_SCFG1      (AT91_MATRIX + 0x44)    /* Slave Configuration Register 1 */
-#define AT91_MATRIX_SCFG2      (AT91_MATRIX + 0x48)    /* Slave Configuration Register 2 */
-#define AT91_MATRIX_SCFG3      (AT91_MATRIX + 0x4C)    /* Slave Configuration Register 3 */
-#define AT91_MATRIX_SCFG4      (AT91_MATRIX + 0x50)    /* Slave Configuration Register 4 */
-#define AT91_MATRIX_SCFG5      (AT91_MATRIX + 0x54)    /* Slave Configuration Register 5 */
-#define AT91_MATRIX_SCFG6      (AT91_MATRIX + 0x58)    /* Slave Configuration Register 6 */
-#define AT91_MATRIX_SCFG7      (AT91_MATRIX + 0x5C)    /* Slave Configuration Register 7 */
+#define AT91_MATRIX_SCFG0      0x40                    /* Slave Configuration Register 0 */
+#define AT91_MATRIX_SCFG1      0x44                    /* Slave Configuration Register 1 */
+#define AT91_MATRIX_SCFG2      0x48                    /* Slave Configuration Register 2 */
+#define AT91_MATRIX_SCFG3      0x4C                    /* Slave Configuration Register 3 */
+#define AT91_MATRIX_SCFG4      0x50                    /* Slave Configuration Register 4 */
+#define AT91_MATRIX_SCFG5      0x54                    /* Slave Configuration Register 5 */
+#define AT91_MATRIX_SCFG6      0x58                    /* Slave Configuration Register 6 */
+#define AT91_MATRIX_SCFG7      0x5C                    /* Slave Configuration Register 7 */
 #define                AT91_MATRIX_SLOT_CYCLE          (0xff << 0)     /* Maximum Number of Allowed Cycles for a Burst */
 #define                AT91_MATRIX_DEFMSTR_TYPE        (3    << 16)    /* Default Master Type */
 #define                        AT91_MATRIX_DEFMSTR_TYPE_NONE   (0 << 16)
 #define                        AT91_MATRIX_ARBT_ROUND_ROBIN    (0 << 24)
 #define                        AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24)
 
-#define AT91_MATRIX_PRAS0      (AT91_MATRIX + 0x80)    /* Priority Register A for Slave 0 */
-#define AT91_MATRIX_PRBS0      (AT91_MATRIX + 0x84)    /* Priority Register B for Slave 0 */
-#define AT91_MATRIX_PRAS1      (AT91_MATRIX + 0x88)    /* Priority Register A for Slave 1 */
-#define AT91_MATRIX_PRBS1      (AT91_MATRIX + 0x8C)    /* Priority Register B for Slave 1 */
-#define AT91_MATRIX_PRAS2      (AT91_MATRIX + 0x90)    /* Priority Register A for Slave 2 */
-#define AT91_MATRIX_PRBS2      (AT91_MATRIX + 0x94)    /* Priority Register B for Slave 2 */
-#define AT91_MATRIX_PRAS3      (AT91_MATRIX + 0x98)    /* Priority Register A for Slave 3 */
-#define AT91_MATRIX_PRBS3      (AT91_MATRIX + 0x9C)    /* Priority Register B for Slave 3 */
-#define AT91_MATRIX_PRAS4      (AT91_MATRIX + 0xA0)    /* Priority Register A for Slave 4 */
-#define AT91_MATRIX_PRBS4      (AT91_MATRIX + 0xA4)    /* Priority Register B for Slave 4 */
-#define AT91_MATRIX_PRAS5      (AT91_MATRIX + 0xA8)    /* Priority Register A for Slave 5 */
-#define AT91_MATRIX_PRBS5      (AT91_MATRIX + 0xAC)    /* Priority Register B for Slave 5 */
-#define AT91_MATRIX_PRAS6      (AT91_MATRIX + 0xB0)    /* Priority Register A for Slave 6 */
-#define AT91_MATRIX_PRBS6      (AT91_MATRIX + 0xB4)    /* Priority Register B for Slave 6 */
-#define AT91_MATRIX_PRAS7      (AT91_MATRIX + 0xB8)    /* Priority Register A for Slave 7 */
-#define AT91_MATRIX_PRBS7      (AT91_MATRIX + 0xBC)    /* Priority Register B for Slave 7 */
+#define AT91_MATRIX_PRAS0      0x80                    /* Priority Register A for Slave 0 */
+#define AT91_MATRIX_PRBS0      0x84                    /* Priority Register B for Slave 0 */
+#define AT91_MATRIX_PRAS1      0x88                    /* Priority Register A for Slave 1 */
+#define AT91_MATRIX_PRBS1      0x8C                    /* Priority Register B for Slave 1 */
+#define AT91_MATRIX_PRAS2      0x90                    /* Priority Register A for Slave 2 */
+#define AT91_MATRIX_PRBS2      0x94                    /* Priority Register B for Slave 2 */
+#define AT91_MATRIX_PRAS3      0x98                    /* Priority Register A for Slave 3 */
+#define AT91_MATRIX_PRBS3      0x9C                    /* Priority Register B for Slave 3 */
+#define AT91_MATRIX_PRAS4      0xA0                    /* Priority Register A for Slave 4 */
+#define AT91_MATRIX_PRBS4      0xA4                    /* Priority Register B for Slave 4 */
+#define AT91_MATRIX_PRAS5      0xA8                    /* Priority Register A for Slave 5 */
+#define AT91_MATRIX_PRBS5      0xAC                    /* Priority Register B for Slave 5 */
+#define AT91_MATRIX_PRAS6      0xB0                    /* Priority Register A for Slave 6 */
+#define AT91_MATRIX_PRBS6      0xB4                    /* Priority Register B for Slave 6 */
+#define AT91_MATRIX_PRAS7      0xB8                    /* Priority Register A for Slave 7 */
+#define AT91_MATRIX_PRBS7      0xBC                    /* Priority Register B for Slave 7 */
 #define                AT91_MATRIX_M0PR                (3 << 0)        /* Master 0 Priority */
 #define                AT91_MATRIX_M1PR                (3 << 4)        /* Master 1 Priority */
 #define                AT91_MATRIX_M2PR                (3 << 8)        /* Master 2 Priority */
@@ -75,7 +75,7 @@
 #define                AT91_MATRIX_M7PR                (3 << 28)       /* Master 7 Priority */
 #define                AT91_MATRIX_M8PR                (3 << 0)        /* Master 8 Priority (in Register B) */
 
-#define AT91_MATRIX_MRCR       (AT91_MATRIX + 0x100)   /* Master Remap Control Register */
+#define AT91_MATRIX_MRCR       0x100                   /* Master Remap Control Register */
 #define                AT91_MATRIX_RCB0                (1 << 0)        /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
 #define                AT91_MATRIX_RCB1                (1 << 1)        /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
 #define                AT91_MATRIX_RCB2                (1 << 2)
@@ -86,7 +86,7 @@
 #define                AT91_MATRIX_RCB7                (1 << 7)
 #define                AT91_MATRIX_RCB8                (1 << 8)
 
-#define AT91_MATRIX_TCMR       (AT91_MATRIX + 0x114)   /* TCM Configuration Register */
+#define AT91_MATRIX_TCMR       0x114                   /* TCM Configuration Register */
 #define                AT91_MATRIX_ITCM_SIZE           (0xf << 0)      /* Size of ITCM enabled memory block */
 #define                        AT91_MATRIX_ITCM_0              (0 << 0)
 #define                        AT91_MATRIX_ITCM_16             (5 << 0)
@@ -96,7 +96,7 @@
 #define                        AT91_MATRIX_DTCM_16             (5 << 4)
 #define                        AT91_MATRIX_DTCM_32             (6 << 4)
 
-#define AT91_MATRIX_EBI0CSA    (AT91_MATRIX + 0x120)   /* EBI0 Chip Select Assignment Register */
+#define AT91_MATRIX_EBI0CSA    0x120                   /* EBI0 Chip Select Assignment Register */
 #define                AT91_MATRIX_EBI0_CS1A           (1 << 1)        /* Chip Select 1 Assignment */
 #define                        AT91_MATRIX_EBI0_CS1A_SMC               (0 << 1)
 #define                        AT91_MATRIX_EBI0_CS1A_SDRAMC            (1 << 1)
 #define                        AT91_MATRIX_EBI0_VDDIOMSEL_1_8V         (0 << 16)
 #define                        AT91_MATRIX_EBI0_VDDIOMSEL_3_3V         (1 << 16)
 
-#define AT91_MATRIX_EBI1CSA    (AT91_MATRIX + 0x124)   /* EBI1 Chip Select Assignment Register */
+#define AT91_MATRIX_EBI1CSA    0x124                   /* EBI1 Chip Select Assignment Register */
 #define                AT91_MATRIX_EBI1_CS1A           (1 << 1)        /* Chip Select 1 Assignment */
 #define                        AT91_MATRIX_EBI1_CS1A_SMC               (0 << 1)
 #define                        AT91_MATRIX_EBI1_CS1A_SDRAMC            (1 << 1)
index e2f8da8ce5bc81f8b0447b0529c5b9338d5c447f..0210797abf2e95e88f67dd480ae24597325842d3 100644 (file)
@@ -59,7 +59,6 @@
 #define                AT91_DDRSDRC_TRP        (0xf << 16)             /* Row precharge delay */
 #define                AT91_DDRSDRC_TRRD       (0xf << 20)             /* Active BankA to BankB */
 #define                AT91_DDRSDRC_TWTR       (0x7 << 24)             /* Internal Write to Read delay */
-#define                AT91CAP9_DDRSDRC_TWTR   (1   << 24)             /* Internal Write to Read delay */
 #define                AT91_DDRSDRC_RED_WRRD   (0x1 << 27)             /* Reduce Write to Read Delay [SAM9 Only] */
 #define                AT91_DDRSDRC_TMRD       (0xf << 28)             /* Load mode to active/refresh delay */
 
@@ -76,7 +75,6 @@
 #define                AT91_DDRSDRC_TRTP       (0x7  << 12)            /* Read to Precharge delay */
 
 #define AT91_DDRSDRC_LPR       0x1C    /* Low Power Register */
-#define AT91CAP9_DDRSDRC_LPR   0x18    /* Low Power Register */
 #define                AT91_DDRSDRC_LPCB       (3 << 0)                /* Low-power Configurations */
 #define                        AT91_DDRSDRC_LPCB_DISABLE               0
 #define                        AT91_DDRSDRC_LPCB_SELF_REFRESH          1
 #define                AT91_DDRSDRC_UPD_MR     (3 << 20)        /* Update load mode register and extended mode register */
 
 #define AT91_DDRSDRC_MDR       0x20    /* Memory Device Register */
-#define AT91CAP9_DDRSDRC_MDR   0x1C    /* Memory Device Register */
 #define                AT91_DDRSDRC_MD         (3 << 0)                /* Memory Device Type */
 #define                        AT91_DDRSDRC_MD_SDR             0
 #define                        AT91_DDRSDRC_MD_LOW_POWER_SDR   1
-#define                        AT91CAP9_DDRSDRC_MD_DDR         2
 #define                        AT91_DDRSDRC_MD_LOW_POWER_DDR   3
 #define                        AT91_DDRSDRC_MD_DDR2            6       /* [SAM9 Only] */
 #define                AT91_DDRSDRC_DBW        (1 << 4)                /* Data Bus Width */
 #define                        AT91_DDRSDRC_DBW_16BITS         (1 <<  4)
 
 #define AT91_DDRSDRC_DLL       0x24    /* DLL Information Register */
-#define AT91CAP9_DDRSDRC_DLL   0x20    /* DLL Information Register */
 #define                AT91_DDRSDRC_MDINC      (1 << 0)                /* Master Delay increment */
 #define                AT91_DDRSDRC_MDDEC      (1 << 1)                /* Master Delay decrement */
 #define                AT91_DDRSDRC_MDOVF      (1 << 2)                /* Master Delay Overflow */
-#define                AT91CAP9_DDRSDRC_SDCOVF (1 << 3)                /* Slave Delay Correction Overflow */
-#define                AT91CAP9_DDRSDRC_SDCUDF (1 << 4)                /* Slave Delay Correction Underflow */
-#define                AT91CAP9_DDRSDRC_SDERF  (1 << 5)                /* Slave Delay Correction error */
 #define                AT91_DDRSDRC_MDVAL      (0xff <<  8)            /* Master Delay value */
-#define                AT91CAP9_DDRSDRC_SDVAL  (0xff << 16)            /* Slave Delay value */
-#define                AT91CAP9_DDRSDRC_SDCVAL (0xff << 24)            /* Slave Delay Correction value */
 
 #define AT91_DDRSDRC_HS                0x2C    /* High Speed Register [SAM9 Only] */
 #define                AT91_DDRSDRC_DIS_ATCP_RD        (1 << 2)        /* Anticip read access is disabled */
 #define                AT91_DDRSDRC_WPVS       (1 << 0)                /* Write protect violation status */
 #define                AT91_DDRSDRC_WPVSRC     (0xffff << 8)           /* Write protect violation source */
 
-/* Register access macros */
-#define at91_ramc_read(num, reg) \
-       at91_sys_read(AT91_DDRSDRC##num + reg)
-#define at91_ramc_write(num, reg, value) \
-       at91_sys_write(AT91_DDRSDRC##num + reg, value)
-
 #endif
index 100f5a592926356db536780996a7796ff6856e91..3d085a9a74509c6703b7614df35108cf7f9e39ce 100644 (file)
 #define                        AT91_SDRAMC_MD_SDRAM            0
 #define                        AT91_SDRAMC_MD_LOW_POWER_SDRAM  1
 
-/* Register access macros */
-#define at91_ramc_read(num, reg) \
-       at91_sys_read(AT91_SDRAMC##num + reg)
-#define at91_ramc_write(num, reg, value) \
-       at91_sys_write(AT91_SDRAMC##num + reg, value)
-
 #endif
index dd9c95ea0862d7233c4d669b2262c05cd6d3021d..d052abcff852134fee95d54defa164f66af8b074 100644 (file)
 #define AT91SAM9G45_BASE_TC5           0xfffd4080
 
 /*
- * System Peripherals (offset from AT91_BASE_SYS)
+ * System Peripherals
  */
-#define AT91_DDRSDRC1  (0xffffe400 - AT91_BASE_SYS)
-#define AT91_DDRSDRC0  (0xffffe600 - AT91_BASE_SYS)
-#define AT91_MATRIX    (0xffffea00 - AT91_BASE_SYS)
-#define AT91_PMC       (0xfffffc00 - AT91_BASE_SYS)
-#define AT91_GPBR      (0xfffffd60 - AT91_BASE_SYS)
-
 #define AT91SAM9G45_BASE_ECC   0xffffe200
+#define AT91SAM9G45_BASE_DDRSDRC1 0xffffe400
+#define AT91SAM9G45_BASE_DDRSDRC0 0xffffe600
 #define AT91SAM9G45_BASE_DMA   0xffffec00
 #define AT91SAM9G45_BASE_SMC   0xffffe800
+#define AT91SAM9G45_BASE_MATRIX        0xffffea00
 #define AT91SAM9G45_BASE_DBGU  AT91_BASE_DBGU1
 #define AT91SAM9G45_BASE_PIOA  0xfffff200
 #define AT91SAM9G45_BASE_PIOB  0xfffff400
 #define AT91SAM9G45_BASE_PIT   0xfffffd30
 #define AT91SAM9G45_BASE_WDT   0xfffffd40
 #define AT91SAM9G45_BASE_RTC   0xfffffdb0
+#define AT91SAM9G45_BASE_GPBR  0xfffffd60
 
 #define AT91_USART0    AT91SAM9G45_BASE_US0
 #define AT91_USART1    AT91SAM9G45_BASE_US1
index c972d60e0aebbc9bc724160333b4e29232e2827d..b76e2ed2fbc2263f7a18ee3e07e9521bea2f4c48 100644 (file)
 #ifndef AT91SAM9G45_MATRIX_H
 #define AT91SAM9G45_MATRIX_H
 
-#define AT91_MATRIX_MCFG0      (AT91_MATRIX + 0x00)    /* Master Configuration Register 0 */
-#define AT91_MATRIX_MCFG1      (AT91_MATRIX + 0x04)    /* Master Configuration Register 1 */
-#define AT91_MATRIX_MCFG2      (AT91_MATRIX + 0x08)    /* Master Configuration Register 2 */
-#define AT91_MATRIX_MCFG3      (AT91_MATRIX + 0x0C)    /* Master Configuration Register 3 */
-#define AT91_MATRIX_MCFG4      (AT91_MATRIX + 0x10)    /* Master Configuration Register 4 */
-#define AT91_MATRIX_MCFG5      (AT91_MATRIX + 0x14)    /* Master Configuration Register 5 */
-#define AT91_MATRIX_MCFG6      (AT91_MATRIX + 0x18)    /* Master Configuration Register 6 */
-#define AT91_MATRIX_MCFG7      (AT91_MATRIX + 0x1C)    /* Master Configuration Register 7 */
-#define AT91_MATRIX_MCFG8      (AT91_MATRIX + 0x20)    /* Master Configuration Register 8 */
-#define AT91_MATRIX_MCFG9      (AT91_MATRIX + 0x24)    /* Master Configuration Register 9 */
-#define AT91_MATRIX_MCFG10     (AT91_MATRIX + 0x28)    /* Master Configuration Register 10 */
-#define AT91_MATRIX_MCFG11     (AT91_MATRIX + 0x2C)    /* Master Configuration Register 11 */
+#define AT91_MATRIX_MCFG0      0x00                    /* Master Configuration Register 0 */
+#define AT91_MATRIX_MCFG1      0x04                    /* Master Configuration Register 1 */
+#define AT91_MATRIX_MCFG2      0x08                    /* Master Configuration Register 2 */
+#define AT91_MATRIX_MCFG3      0x0C                    /* Master Configuration Register 3 */
+#define AT91_MATRIX_MCFG4      0x10                    /* Master Configuration Register 4 */
+#define AT91_MATRIX_MCFG5      0x14                    /* Master Configuration Register 5 */
+#define AT91_MATRIX_MCFG6      0x18                    /* Master Configuration Register 6 */
+#define AT91_MATRIX_MCFG7      0x1C                    /* Master Configuration Register 7 */
+#define AT91_MATRIX_MCFG8      0x20                    /* Master Configuration Register 8 */
+#define AT91_MATRIX_MCFG9      0x24                    /* Master Configuration Register 9 */
+#define AT91_MATRIX_MCFG10     0x28                    /* Master Configuration Register 10 */
+#define AT91_MATRIX_MCFG11     0x2C                    /* Master Configuration Register 11 */
 #define                AT91_MATRIX_ULBT        (7 << 0)        /* Undefined Length Burst Type */
 #define                        AT91_MATRIX_ULBT_INFINITE       (0 << 0)
 #define                        AT91_MATRIX_ULBT_SINGLE         (1 << 0)
 #define                        AT91_MATRIX_ULBT_SIXTYFOUR      (6 << 0)
 #define                        AT91_MATRIX_ULBT_128            (7 << 0)
 
-#define AT91_MATRIX_SCFG0      (AT91_MATRIX + 0x40)    /* Slave Configuration Register 0 */
-#define AT91_MATRIX_SCFG1      (AT91_MATRIX + 0x44)    /* Slave Configuration Register 1 */
-#define AT91_MATRIX_SCFG2      (AT91_MATRIX + 0x48)    /* Slave Configuration Register 2 */
-#define AT91_MATRIX_SCFG3      (AT91_MATRIX + 0x4C)    /* Slave Configuration Register 3 */
-#define AT91_MATRIX_SCFG4      (AT91_MATRIX + 0x50)    /* Slave Configuration Register 4 */
-#define AT91_MATRIX_SCFG5      (AT91_MATRIX + 0x54)    /* Slave Configuration Register 5 */
-#define AT91_MATRIX_SCFG6      (AT91_MATRIX + 0x58)    /* Slave Configuration Register 6 */
-#define AT91_MATRIX_SCFG7      (AT91_MATRIX + 0x5C)    /* Slave Configuration Register 7 */
+#define AT91_MATRIX_SCFG0      0x40                    /* Slave Configuration Register 0 */
+#define AT91_MATRIX_SCFG1      0x44                    /* Slave Configuration Register 1 */
+#define AT91_MATRIX_SCFG2      0x48                    /* Slave Configuration Register 2 */
+#define AT91_MATRIX_SCFG3      0x4C                    /* Slave Configuration Register 3 */
+#define AT91_MATRIX_SCFG4      0x50                    /* Slave Configuration Register 4 */
+#define AT91_MATRIX_SCFG5      0x54                    /* Slave Configuration Register 5 */
+#define AT91_MATRIX_SCFG6      0x58                    /* Slave Configuration Register 6 */
+#define AT91_MATRIX_SCFG7      0x5C                    /* Slave Configuration Register 7 */
 #define                AT91_MATRIX_SLOT_CYCLE          (0x1ff << 0)    /* Maximum Number of Allowed Cycles for a Burst */
 #define                AT91_MATRIX_DEFMSTR_TYPE        (3    << 16)    /* Default Master Type */
 #define                        AT91_MATRIX_DEFMSTR_TYPE_NONE   (0 << 16)
 #define                        AT91_MATRIX_DEFMSTR_TYPE_FIXED  (2 << 16)
 #define                AT91_MATRIX_FIXED_DEFMSTR       (0xf  << 18)    /* Fixed Index of Default Master */
 
-#define AT91_MATRIX_PRAS0      (AT91_MATRIX + 0x80)    /* Priority Register A for Slave 0 */
-#define AT91_MATRIX_PRBS0      (AT91_MATRIX + 0x84)    /* Priority Register B for Slave 0 */
-#define AT91_MATRIX_PRAS1      (AT91_MATRIX + 0x88)    /* Priority Register A for Slave 1 */
-#define AT91_MATRIX_PRBS1      (AT91_MATRIX + 0x8C)    /* Priority Register B for Slave 1 */
-#define AT91_MATRIX_PRAS2      (AT91_MATRIX + 0x90)    /* Priority Register A for Slave 2 */
-#define AT91_MATRIX_PRBS2      (AT91_MATRIX + 0x94)    /* Priority Register B for Slave 2 */
-#define AT91_MATRIX_PRAS3      (AT91_MATRIX + 0x98)    /* Priority Register A for Slave 3 */
-#define AT91_MATRIX_PRBS3      (AT91_MATRIX + 0x9C)    /* Priority Register B for Slave 3 */
-#define AT91_MATRIX_PRAS4      (AT91_MATRIX + 0xA0)    /* Priority Register A for Slave 4 */
-#define AT91_MATRIX_PRBS4      (AT91_MATRIX + 0xA4)    /* Priority Register B for Slave 4 */
-#define AT91_MATRIX_PRAS5      (AT91_MATRIX + 0xA8)    /* Priority Register A for Slave 5 */
-#define AT91_MATRIX_PRBS5      (AT91_MATRIX + 0xAC)    /* Priority Register B for Slave 5 */
-#define AT91_MATRIX_PRAS6      (AT91_MATRIX + 0xB0)    /* Priority Register A for Slave 6 */
-#define AT91_MATRIX_PRBS6      (AT91_MATRIX + 0xB4)    /* Priority Register B for Slave 6 */
-#define AT91_MATRIX_PRAS7      (AT91_MATRIX + 0xB8)    /* Priority Register A for Slave 7 */
-#define AT91_MATRIX_PRBS7      (AT91_MATRIX + 0xBC)    /* Priority Register B for Slave 7 */
+#define AT91_MATRIX_PRAS0      0x80                    /* Priority Register A for Slave 0 */
+#define AT91_MATRIX_PRBS0      0x84                    /* Priority Register B for Slave 0 */
+#define AT91_MATRIX_PRAS1      0x88                    /* Priority Register A for Slave 1 */
+#define AT91_MATRIX_PRBS1      0x8C                    /* Priority Register B for Slave 1 */
+#define AT91_MATRIX_PRAS2      0x90                    /* Priority Register A for Slave 2 */
+#define AT91_MATRIX_PRBS2      0x94                    /* Priority Register B for Slave 2 */
+#define AT91_MATRIX_PRAS3      0x98                    /* Priority Register A for Slave 3 */
+#define AT91_MATRIX_PRBS3      0x9C                    /* Priority Register B for Slave 3 */
+#define AT91_MATRIX_PRAS4      0xA0                    /* Priority Register A for Slave 4 */
+#define AT91_MATRIX_PRBS4      0xA4                    /* Priority Register B for Slave 4 */
+#define AT91_MATRIX_PRAS5      0xA8                    /* Priority Register A for Slave 5 */
+#define AT91_MATRIX_PRBS5      0xAC                    /* Priority Register B for Slave 5 */
+#define AT91_MATRIX_PRAS6      0xB0                    /* Priority Register A for Slave 6 */
+#define AT91_MATRIX_PRBS6      0xB4                    /* Priority Register B for Slave 6 */
+#define AT91_MATRIX_PRAS7      0xB8                    /* Priority Register A for Slave 7 */
+#define AT91_MATRIX_PRBS7      0xBC                    /* Priority Register B for Slave 7 */
 #define                AT91_MATRIX_M0PR                (3 << 0)        /* Master 0 Priority */
 #define                AT91_MATRIX_M1PR                (3 << 4)        /* Master 1 Priority */
 #define                AT91_MATRIX_M2PR                (3 << 8)        /* Master 2 Priority */
@@ -81,7 +81,7 @@
 #define                AT91_MATRIX_M10PR               (3 << 8)        /* Master 10 Priority (in Register B) */
 #define                AT91_MATRIX_M11PR               (3 << 12)       /* Master 11 Priority (in Register B) */
 
-#define AT91_MATRIX_MRCR       (AT91_MATRIX + 0x100)   /* Master Remap Control Register */
+#define AT91_MATRIX_MRCR       0x100                   /* Master Remap Control Register */
 #define                AT91_MATRIX_RCB0                (1 << 0)        /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
 #define                AT91_MATRIX_RCB1                (1 << 1)        /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
 #define                AT91_MATRIX_RCB2                (1 << 2)
@@ -95,7 +95,7 @@
 #define                AT91_MATRIX_RCB10               (1 << 10)
 #define                AT91_MATRIX_RCB11               (1 << 11)
 
-#define AT91_MATRIX_TCMR       (AT91_MATRIX + 0x110)   /* TCM Configuration Register */
+#define AT91_MATRIX_TCMR       0x110                   /* TCM Configuration Register */
 #define                AT91_MATRIX_ITCM_SIZE           (0xf << 0)      /* Size of ITCM enabled memory block */
 #define                        AT91_MATRIX_ITCM_0              (0 << 0)
 #define                        AT91_MATRIX_ITCM_32             (6 << 0)
 #define                        AT91_MATRIX_TCM_NO_WS           (0x0 << 11)
 #define                        AT91_MATRIX_TCM_ONE_WS          (0x1 << 11)
 
-#define AT91_MATRIX_VIDEO      (AT91_MATRIX + 0x118)   /* Video Mode Configuration Register */
+#define AT91_MATRIX_VIDEO      0x118                   /* Video Mode Configuration Register */
 #define                AT91C_VDEC_SEL                  (0x1 <<  0) /* Video Mode Selection */
 #define                        AT91C_VDEC_SEL_OFF              (0 << 0)
 #define                        AT91C_VDEC_SEL_ON               (1 << 0)
 
-#define AT91_MATRIX_EBICSA     (AT91_MATRIX + 0x128)   /* EBI Chip Select Assignment Register */
+#define AT91_MATRIX_EBICSA     0x128                   /* EBI Chip Select Assignment Register */
 #define                AT91_MATRIX_EBI_CS1A            (1 << 1)        /* Chip Select 1 Assignment */
 #define                        AT91_MATRIX_EBI_CS1A_SMC                (0 << 1)
 #define                        AT91_MATRIX_EBI_CS1A_SDRAMC             (1 << 1)
 #define                        AT91_MATRIX_EBI_DDR_IOSR_REDUCED        (0 << 18)
 #define                        AT91_MATRIX_EBI_DDR_IOSR_NORMAL         (1 << 18)
 
-#define AT91_MATRIX_WPMR       (AT91_MATRIX + 0x1E4)   /* Write Protect Mode Register */
+#define AT91_MATRIX_WPMR       0x1E4                   /* Write Protect Mode Register */
 #define                AT91_MATRIX_WPMR_WPEN           (1 << 0)        /* Write Protect ENable */
 #define                        AT91_MATRIX_WPMR_WP_WPDIS               (0 << 0)
 #define                        AT91_MATRIX_WPMR_WP_WPEN                (1 << 0)
 #define                AT91_MATRIX_WPMR_WPKEY          (0xFFFFFF << 8) /* Write Protect KEY */
 
-#define AT91_MATRIX_WPSR       (AT91_MATRIX + 0x1E8)   /* Write Protect Status Register */
+#define AT91_MATRIX_WPSR       0x1E8                   /* Write Protect Status Register */
 #define                AT91_MATRIX_WPSR_WPVS           (1 << 0)        /* Write Protect Violation Status */
 #define                        AT91_MATRIX_WPSR_NO_WPV         (0 << 0)
 #define                        AT91_MATRIX_WPSR_WPV            (1 << 0)
index d7bead7118da85873c4ef43388432ce80f24a9f1..e0073eb10144d87e754c5e261ded43fb908a51dd 100644 (file)
 /*
  * System Peripherals (offset from AT91_BASE_SYS)
  */
-#define AT91_SDRAMC0   (0xffffea00 - AT91_BASE_SYS)
-#define AT91_MATRIX    (0xffffee00 - AT91_BASE_SYS)
-#define AT91_PMC       (0xfffffc00 - AT91_BASE_SYS)
 #define AT91_SCKCR     (0xfffffd50 - AT91_BASE_SYS)
-#define AT91_GPBR      (0xfffffd60 - AT91_BASE_SYS)
 
 #define AT91SAM9RL_BASE_DMA    0xffffe600
 #define AT91SAM9RL_BASE_ECC    0xffffe800
+#define AT91SAM9RL_BASE_SDRAMC 0xffffea00
 #define AT91SAM9RL_BASE_SMC    0xffffec00
+#define AT91SAM9RL_BASE_MATRIX 0xffffee00
 #define AT91SAM9RL_BASE_DBGU   AT91_BASE_DBGU0
 #define AT91SAM9RL_BASE_PIOA   0xfffff400
 #define AT91SAM9RL_BASE_PIOB   0xfffff600
@@ -88,6 +86,7 @@
 #define AT91SAM9RL_BASE_RTT    0xfffffd20
 #define AT91SAM9RL_BASE_PIT    0xfffffd30
 #define AT91SAM9RL_BASE_WDT    0xfffffd40
+#define AT91SAM9RL_BASE_GPBR   0xfffffd60
 #define AT91SAM9RL_BASE_RTC    0xfffffe00
 
 #define AT91_USART0    AT91SAM9RL_BASE_US0
index 5f9149071fe5eaa1b2f4d438391e52d5a1f75eaa..6d160adadafc1b068d23270322b7464e30f16abd 100644 (file)
 #ifndef AT91SAM9RL_MATRIX_H
 #define AT91SAM9RL_MATRIX_H
 
-#define AT91_MATRIX_MCFG0      (AT91_MATRIX + 0x00)    /* Master Configuration Register 0 */
-#define AT91_MATRIX_MCFG1      (AT91_MATRIX + 0x04)    /* Master Configuration Register 1 */
-#define AT91_MATRIX_MCFG2      (AT91_MATRIX + 0x08)    /* Master Configuration Register 2 */
-#define AT91_MATRIX_MCFG3      (AT91_MATRIX + 0x0C)    /* Master Configuration Register 3 */
-#define AT91_MATRIX_MCFG4      (AT91_MATRIX + 0x10)    /* Master Configuration Register 4 */
-#define AT91_MATRIX_MCFG5      (AT91_MATRIX + 0x14)    /* Master Configuration Register 5 */
+#define AT91_MATRIX_MCFG0      0x00                    /* Master Configuration Register 0 */
+#define AT91_MATRIX_MCFG1      0x04                    /* Master Configuration Register 1 */
+#define AT91_MATRIX_MCFG2      0x08                    /* Master Configuration Register 2 */
+#define AT91_MATRIX_MCFG3      0x0C                    /* Master Configuration Register 3 */
+#define AT91_MATRIX_MCFG4      0x10                    /* Master Configuration Register 4 */
+#define AT91_MATRIX_MCFG5      0x14                    /* Master Configuration Register 5 */
 #define                AT91_MATRIX_ULBT        (7 << 0)        /* Undefined Length Burst Type */
 #define                        AT91_MATRIX_ULBT_INFINITE       (0 << 0)
 #define                        AT91_MATRIX_ULBT_SINGLE         (1 << 0)
 #define                        AT91_MATRIX_ULBT_EIGHT          (3 << 0)
 #define                        AT91_MATRIX_ULBT_SIXTEEN        (4 << 0)
 
-#define AT91_MATRIX_SCFG0      (AT91_MATRIX + 0x40)    /* Slave Configuration Register 0 */
-#define AT91_MATRIX_SCFG1      (AT91_MATRIX + 0x44)    /* Slave Configuration Register 1 */
-#define AT91_MATRIX_SCFG2      (AT91_MATRIX + 0x48)    /* Slave Configuration Register 2 */
-#define AT91_MATRIX_SCFG3      (AT91_MATRIX + 0x4C)    /* Slave Configuration Register 3 */
-#define AT91_MATRIX_SCFG4      (AT91_MATRIX + 0x50)    /* Slave Configuration Register 4 */
-#define AT91_MATRIX_SCFG5      (AT91_MATRIX + 0x54)    /* Slave Configuration Register 5 */
+#define AT91_MATRIX_SCFG0      0x40                    /* Slave Configuration Register 0 */
+#define AT91_MATRIX_SCFG1      0x44                    /* Slave Configuration Register 1 */
+#define AT91_MATRIX_SCFG2      0x48                    /* Slave Configuration Register 2 */
+#define AT91_MATRIX_SCFG3      0x4C                    /* Slave Configuration Register 3 */
+#define AT91_MATRIX_SCFG4      0x50                    /* Slave Configuration Register 4 */
+#define AT91_MATRIX_SCFG5      0x54                    /* Slave Configuration Register 5 */
 #define                AT91_MATRIX_SLOT_CYCLE          (0xff << 0)     /* Maximum Number of Allowed Cycles for a Burst */
 #define                AT91_MATRIX_DEFMSTR_TYPE        (3    << 16)    /* Default Master Type */
 #define                        AT91_MATRIX_DEFMSTR_TYPE_NONE   (0 << 16)
 #define                        AT91_MATRIX_ARBT_ROUND_ROBIN    (0 << 24)
 #define                        AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24)
 
-#define AT91_MATRIX_PRAS0      (AT91_MATRIX + 0x80)    /* Priority Register A for Slave 0 */
-#define AT91_MATRIX_PRAS1      (AT91_MATRIX + 0x88)    /* Priority Register A for Slave 1 */
-#define AT91_MATRIX_PRAS2      (AT91_MATRIX + 0x90)    /* Priority Register A for Slave 2 */
-#define AT91_MATRIX_PRAS3      (AT91_MATRIX + 0x98)    /* Priority Register A for Slave 3 */
-#define AT91_MATRIX_PRAS4      (AT91_MATRIX + 0xA0)    /* Priority Register A for Slave 4 */
-#define AT91_MATRIX_PRAS5      (AT91_MATRIX + 0xA8)    /* Priority Register A for Slave 5 */
+#define AT91_MATRIX_PRAS0      0x80                    /* Priority Register A for Slave 0 */
+#define AT91_MATRIX_PRAS1      0x88                    /* Priority Register A for Slave 1 */
+#define AT91_MATRIX_PRAS2      0x90                    /* Priority Register A for Slave 2 */
+#define AT91_MATRIX_PRAS3      0x98                    /* Priority Register A for Slave 3 */
+#define AT91_MATRIX_PRAS4      0xA0                    /* Priority Register A for Slave 4 */
+#define AT91_MATRIX_PRAS5      0xA8                    /* Priority Register A for Slave 5 */
 #define                AT91_MATRIX_M0PR                (3 << 0)        /* Master 0 Priority */
 #define                AT91_MATRIX_M1PR                (3 << 4)        /* Master 1 Priority */
 #define                AT91_MATRIX_M2PR                (3 << 8)        /* Master 2 Priority */
@@ -56,7 +56,7 @@
 #define                AT91_MATRIX_M4PR                (3 << 16)       /* Master 4 Priority */
 #define                AT91_MATRIX_M5PR                (3 << 20)       /* Master 5 Priority */
 
-#define AT91_MATRIX_MRCR       (AT91_MATRIX + 0x100)   /* Master Remap Control Register */
+#define AT91_MATRIX_MRCR       0x100                   /* Master Remap Control Register */
 #define                AT91_MATRIX_RCB0                (1 << 0)        /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
 #define                AT91_MATRIX_RCB1                (1 << 1)        /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
 #define                AT91_MATRIX_RCB2                (1 << 2)
@@ -64,7 +64,7 @@
 #define                AT91_MATRIX_RCB4                (1 << 4)
 #define                AT91_MATRIX_RCB5                (1 << 5)
 
-#define AT91_MATRIX_TCMR       (AT91_MATRIX + 0x114)   /* TCM Configuration Register */
+#define AT91_MATRIX_TCMR       0x114                   /* TCM Configuration Register */
 #define                AT91_MATRIX_ITCM_SIZE           (0xf << 0)      /* Size of ITCM enabled memory block */
 #define                        AT91_MATRIX_ITCM_0              (0 << 0)
 #define                        AT91_MATRIX_ITCM_16             (5 << 0)
@@ -74,7 +74,7 @@
 #define                        AT91_MATRIX_DTCM_16             (5 << 4)
 #define                        AT91_MATRIX_DTCM_32             (6 << 4)
 
-#define AT91_MATRIX_EBICSA     (AT91_MATRIX + 0x120)   /* EBI0 Chip Select Assignment Register */
+#define AT91_MATRIX_EBICSA     0x120                   /* EBI0 Chip Select Assignment Register */
 #define                AT91_MATRIX_CS1A                (1 << 1)        /* Chip Select 1 Assignment */
 #define                        AT91_MATRIX_CS1A_SMC            (0 << 1)
 #define                        AT91_MATRIX_CS1A_SDRAMC         (1 << 1)
diff --git a/arch/arm/mach-at91/include/mach/at91sam9x5.h b/arch/arm/mach-at91/include/mach/at91sam9x5.h
new file mode 100644 (file)
index 0000000..88e43d5
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Chip-specific header file for the AT91SAM9x5 family
+ *
+ *  Copyright (C) 2009-2012 Atmel Corporation.
+ *
+ * Common definitions.
+ * Based on AT91SAM9x5 datasheet.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef AT91SAM9X5_H
+#define AT91SAM9X5_H
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define AT91SAM9X5_ID_PIOAB    2       /* Parallel I/O Controller A and B */
+#define AT91SAM9X5_ID_PIOCD    3       /* Parallel I/O Controller C and D */
+#define AT91SAM9X5_ID_SMD      4       /* SMD Soft Modem (SMD) */
+#define AT91SAM9X5_ID_USART0   5       /* USART 0 */
+#define AT91SAM9X5_ID_USART1   6       /* USART 1 */
+#define AT91SAM9X5_ID_USART2   7       /* USART 2 */
+#define AT91SAM9X5_ID_USART3   8       /* USART 3 */
+#define AT91SAM9X5_ID_TWI0     9       /* Two-Wire Interface 0 */
+#define AT91SAM9X5_ID_TWI1     10      /* Two-Wire Interface 1 */
+#define AT91SAM9X5_ID_TWI2     11      /* Two-Wire Interface 2 */
+#define AT91SAM9X5_ID_MCI0     12      /* High Speed Multimedia Card Interface 0 */
+#define AT91SAM9X5_ID_SPI0     13      /* Serial Peripheral Interface 0 */
+#define AT91SAM9X5_ID_SPI1     14      /* Serial Peripheral Interface 1 */
+#define AT91SAM9X5_ID_UART0    15      /* UART 0 */
+#define AT91SAM9X5_ID_UART1    16      /* UART 1 */
+#define AT91SAM9X5_ID_TCB      17      /* Timer Counter 0, 1, 2, 3, 4 and 5 */
+#define AT91SAM9X5_ID_PWM      18      /* Pulse Width Modulation Controller */
+#define AT91SAM9X5_ID_ADC      19      /* ADC Controller */
+#define AT91SAM9X5_ID_DMA0     20      /* DMA Controller 0 */
+#define AT91SAM9X5_ID_DMA1     21      /* DMA Controller 1 */
+#define AT91SAM9X5_ID_UHPHS    22      /* USB Host High Speed */
+#define AT91SAM9X5_ID_UDPHS    23      /* USB Device High Speed */
+#define AT91SAM9X5_ID_EMAC0    24      /* Ethernet MAC0 */
+#define AT91SAM9X5_ID_LCDC     25      /* LCD Controller */
+#define AT91SAM9X5_ID_ISI      25      /* Image Sensor Interface */
+#define AT91SAM9X5_ID_MCI1     26      /* High Speed Multimedia Card Interface 1 */
+#define AT91SAM9X5_ID_EMAC1    27      /* Ethernet MAC1 */
+#define AT91SAM9X5_ID_SSC      28      /* Synchronous Serial Controller */
+#define AT91SAM9X5_ID_CAN0     29      /* CAN Controller 0 */
+#define AT91SAM9X5_ID_CAN1     30      /* CAN Controller 1 */
+#define AT91SAM9X5_ID_IRQ0     31      /* Advanced Interrupt Controller */
+
+/*
+ * User Peripheral physical base addresses.
+ */
+#define AT91SAM9X5_BASE_USART0 0xf801c000
+#define AT91SAM9X5_BASE_USART1 0xf8020000
+#define AT91SAM9X5_BASE_USART2 0xf8024000
+
+/*
+ * Base addresses for early serial code (uncompress.h)
+ */
+#define AT91_DBGU      AT91_BASE_DBGU0
+#define AT91_USART0    AT91SAM9X5_BASE_USART0
+#define AT91_USART1    AT91SAM9X5_BASE_USART1
+#define AT91_USART2    AT91SAM9X5_BASE_USART2
+
+/*
+ * Internal Memory.
+ */
+#define AT91SAM9X5_SRAM_BASE   0x00300000      /* Internal SRAM base address */
+#define AT91SAM9X5_SRAM_SIZE   SZ_32K          /* Internal SRAM size (32Kb) */
+
+#define AT91SAM9X5_ROM_BASE    0x00400000      /* Internal ROM base address */
+#define AT91SAM9X5_ROM_SIZE    SZ_64K          /* Internal ROM size (64Kb) */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h
new file mode 100644 (file)
index 0000000..a606d39
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Matrix-centric header file for the AT91SAM9x5 family
+ *
+ *  Copyright (C) 2009-2012 Atmel Corporation.
+ *
+ * Only EBI related registers.
+ * Write Protect register definitions may be useful.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef AT91SAM9X5_MATRIX_H
+#define AT91SAM9X5_MATRIX_H
+
+#define AT91_MATRIX_EBICSA     (AT91_MATRIX + 0x120)   /* EBI Chip Select Assignment Register */
+#define                AT91_MATRIX_EBI_CS1A            (1 << 1)        /* Chip Select 1 Assignment */
+#define                        AT91_MATRIX_EBI_CS1A_SMC                (0 << 1)
+#define                        AT91_MATRIX_EBI_CS1A_SDRAMC             (1 << 1)
+#define                AT91_MATRIX_EBI_CS3A            (1 << 3)        /* Chip Select 3 Assignment */
+#define                        AT91_MATRIX_EBI_CS3A_SMC                (0 << 3)
+#define                        AT91_MATRIX_EBI_CS3A_SMC_NANDFLASH      (1 << 3)
+#define                AT91_MATRIX_EBI_DBPUC           (1 << 8)        /* Data Bus Pull-up Configuration */
+#define                        AT91_MATRIX_EBI_DBPU_ON                 (0 << 8)
+#define                        AT91_MATRIX_EBI_DBPU_OFF                (1 << 8)
+#define                AT91_MATRIX_EBI_VDDIOMSEL       (1 << 16)       /* Memory voltage selection */
+#define                        AT91_MATRIX_EBI_VDDIOMSEL_1_8V          (0 << 16)
+#define                        AT91_MATRIX_EBI_VDDIOMSEL_3_3V          (1 << 16)
+#define                AT91_MATRIX_EBI_EBI_IOSR        (1 << 17)       /* EBI I/O slew rate selection */
+#define                        AT91_MATRIX_EBI_EBI_IOSR_REDUCED        (0 << 17)
+#define                        AT91_MATRIX_EBI_EBI_IOSR_NORMAL         (1 << 17)
+#define                AT91_MATRIX_EBI_DDR_IOSR        (1 << 18)       /* DDR2 dedicated port I/O slew rate selection */
+#define                        AT91_MATRIX_EBI_DDR_IOSR_REDUCED        (0 << 18)
+#define                        AT91_MATRIX_EBI_DDR_IOSR_NORMAL         (1 << 18)
+#define                AT91_MATRIX_NFD0_SELECT         (1 << 24)       /* NAND Flash Data Bus Selection */
+#define                        AT91_MATRIX_NFD0_ON_D0                  (0 << 24)
+#define                        AT91_MATRIX_NFD0_ON_D16                 (1 << 24)
+#define                AT91_MATRIX_DDR_MP_EN           (1 << 25)       /* DDR Multi-port Enable */
+#define                        AT91_MATRIX_MP_OFF                      (0 << 25)
+#define                        AT91_MATRIX_MP_ON                       (1 << 25)
+
+#define AT91_MATRIX_WPMR       (AT91_MATRIX + 0x1E4)   /* Write Protect Mode Register */
+#define                AT91_MATRIX_WPMR_WPEN           (1 << 0)        /* Write Protect ENable */
+#define                        AT91_MATRIX_WPMR_WP_WPDIS               (0 << 0)
+#define                        AT91_MATRIX_WPMR_WP_WPEN                (1 << 0)
+#define                AT91_MATRIX_WPMR_WPKEY          (0xFFFFFF << 8) /* Write Protect KEY */
+
+#define AT91_MATRIX_WPSR       (AT91_MATRIX + 0x1E8)   /* Write Protect Status Register */
+#define                AT91_MATRIX_WPSR_WPVS           (1 << 0)        /* Write Protect Violation Status */
+#define                        AT91_MATRIX_WPSR_NO_WPV         (0 << 0)
+#define                        AT91_MATRIX_WPSR_WPV            (1 << 0)
+#define                AT91_MATRIX_WPSR_WPVSRC         (0xFFFF << 8)   /* Write Protect Violation Source */
+
+#endif
index a57829f4fd184ffb8a82cee37a2140c2c97115de..90680217064eea8e1248f909e201596887a2c2f5 100644 (file)
 #define AT91X40_ID_IRQ2                18      /* External IRQ 2 */
 
 /*
- * System Peripherals (offset from AT91_BASE_SYS)
+ * System Peripherals
  */
 #define AT91_BASE_SYS  0xffc00000
 
-#define AT91_EBI       (0xffe00000 - AT91_BASE_SYS)    /* External Bus Interface */
-#define AT91_SF                (0xfff00000 - AT91_BASE_SYS)    /* Special Function */
-#define AT91_USART1    (0xfffcc000 - AT91_BASE_SYS)    /* USART 1 */
-#define AT91_USART0    (0xfffd0000 - AT91_BASE_SYS)    /* USART 0 */
-#define AT91_TC                (0xfffe0000 - AT91_BASE_SYS)    /* Timer Counter */
-#define AT91_PIOA      (0xffff0000 - AT91_BASE_SYS)    /* PIO Controller A */
-#define AT91_PS                (0xffff4000 - AT91_BASE_SYS)    /* Power Save */
-#define AT91_WD                (0xffff8000 - AT91_BASE_SYS)    /* Watchdog Timer */
+#define AT91_EBI       0xffe00000      /* External Bus Interface */
+#define AT91_SF                0xfff00000      /* Special Function */
+#define AT91_USART1    0xfffcc000      /* USART 1 */
+#define AT91_USART0    0xfffd0000      /* USART 0 */
+#define AT91_TC                0xfffe0000      /* Timer Counter */
+#define AT91_PIOA      0xffff0000      /* PIO Controller A */
+#define AT91_PS                0xffff4000      /* Power Save */
+#define AT91_WD                0xffff8000      /* Watchdog Timer */
 
 /*
  * The AT91x40 series doesn't have a debug unit like the other AT91 parts.
index 3b33f07b1e1189ab4a49644741715731b095461f..544a5d5ce4165e9117f8a7ab1cdcbaea79b2df22 100644 (file)
@@ -41,6 +41,7 @@
 #include <sound/atmel-ac97c.h>
 #include <linux/serial.h>
 #include <linux/platform_data/macb.h>
+#include <linux/platform_data/atmel.h>
 
  /* USB Device */
 struct at91_udc_data {
@@ -98,18 +99,6 @@ extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
 extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data);
 extern void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data);
 
- /* NAND / SmartMedia */
-struct atmel_nand_data {
-       int             enable_pin;     /* chip enable */
-       int             det_pin;        /* card detect */
-       int             rdy_pin;        /* ready/busy */
-       u8              rdy_pin_active_low;     /* rdy_pin value is inverted */
-       u8              ale;            /* address line number connected to ALE */
-       u8              cle;            /* address line number connected to CLE */
-       u8              bus_width_16;   /* buswidth is 16 bit */
-       struct mtd_partition *parts;
-       unsigned int    num_parts;
-};
 extern void __init at91_add_device_nand(struct atmel_nand_data *data);
 
  /* I2C*/
@@ -179,7 +168,9 @@ extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data);
 extern void __init at91_add_device_ac97(struct ac97c_platform_data *data);
 
  /* ISI */
-extern void __init at91_add_device_isi(void);
+struct isi_platform_data;
+extern void __init at91_add_device_isi(struct isi_platform_data *data,
+               bool use_pck_as_mck);
 
  /* Touchscreen Controller */
 struct at91_tsadcc_data {
index f6ce936dba2bdd646aaafabf42a08d952918c0ce..0118c33385525149754c45e453881f69c518af49 100644 (file)
@@ -25,7 +25,6 @@
 #define ARCH_ID_AT91SAM9G45MRL 0x819b05a2      /* aka 9G45-ES2 & non ES lots */
 #define ARCH_ID_AT91SAM9G45ES  0x819b05a1      /* 9G45-ES (Engineering Sample) */
 #define ARCH_ID_AT91SAM9X5     0x819a05a0
-#define ARCH_ID_AT91CAP9       0x039A03A0
 
 #define ARCH_ID_AT91SAM9XE128  0x329973a0
 #define ARCH_ID_AT91SAM9XE256  0x329a93a0
 #define ARCH_FAMILY_AT91SAM9   0x01900000
 #define ARCH_FAMILY_AT91SAM9XE 0x02900000
 
-/* PMC revision */
-#define ARCH_REVISION_CAP9_B   0x399
-#define ARCH_REVISION_CAP9_C   0x601
-
 /* RM9200 type */
 #define ARCH_REVISON_9200_BGA  (0 << 0)
 #define ARCH_REVISON_9200_PQFP (1 << 0)
@@ -63,9 +58,6 @@ enum at91_soc_type {
        /* 920T */
        AT91_SOC_RM9200,
 
-       /* CAP */
-       AT91_SOC_CAP9,
-
        /* SAM92xx */
        AT91_SOC_SAM9260, AT91_SOC_SAM9261, AT91_SOC_SAM9263,
 
@@ -86,9 +78,6 @@ enum at91_soc_subtype {
        /* RM9200 */
        AT91_SOC_RM9200_BGA, AT91_SOC_RM9200_PQFP,
 
-       /* CAP9 */
-       AT91_SOC_CAP9_REV_B, AT91_SOC_CAP9_REV_C,
-
        /* SAM9260 */
        AT91_SOC_SAM9XE,
 
@@ -195,16 +184,6 @@ static inline int at91_soc_is_detected(void)
 #define cpu_is_at91sam9x25()   (0)
 #endif
 
-#ifdef CONFIG_ARCH_AT91CAP9
-#define cpu_is_at91cap9()      (at91_soc_initdata.type == AT91_SOC_CAP9)
-#define cpu_is_at91cap9_revB() (at91_soc_initdata.subtype == AT91_SOC_CAP9_REV_B)
-#define cpu_is_at91cap9_revC() (at91_soc_initdata.subtype == AT91_SOC_CAP9_REV_C)
-#else
-#define cpu_is_at91cap9()      (0)
-#define cpu_is_at91cap9_revB() (0)
-#define cpu_is_at91cap9_revC() (0)
-#endif
-
 /*
  * Since this is ARM, we will never run on any AVR32 CPU. But these
  * definitions may reduce clutter in common drivers.
index e3fd225121c748f7f592b0ebedfe095028e5845b..eed465ab0dd7d14c589880f4a242ce74138e7030 100644 (file)
 extern int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup);
 extern int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup);
 extern int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup);
+extern int __init_or_module at91_set_C_periph(unsigned pin, int use_pullup);
+extern int __init_or_module at91_set_D_periph(unsigned pin, int use_pullup);
 extern int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup);
 extern int __init_or_module at91_set_gpio_output(unsigned pin, int value);
 extern int __init_or_module at91_set_deglitch(unsigned pin, int is_on);
+extern int __init_or_module at91_set_debounce(unsigned pin, int is_on, int div);
 extern int __init_or_module at91_set_multi_drive(unsigned pin, int is_on);
+extern int __init_or_module at91_set_pulldown(unsigned pin, int is_on);
+extern int __init_or_module at91_disable_schmitt_trig(unsigned pin);
 
 /* callable at any time */
 extern int at91_set_gpio_value(unsigned pin, int value);
@@ -204,18 +209,6 @@ extern int at91_get_gpio_value(unsigned pin);
 extern void at91_gpio_suspend(void);
 extern void at91_gpio_resume(void);
 
-/*-------------------------------------------------------------------------*/
-
-/* wrappers for "new style" GPIO calls. the old AT91-specific ones should
- * eventually be removed (along with this errno.h inclusion), and the
- * gpio request/free calls should probably be implemented.
- */
-
-#include <asm/errno.h>
-
-#define gpio_to_irq(gpio) (gpio + NR_AIC_IRQS)
-#define irq_to_gpio(irq)  (irq - NR_AIC_IRQS)
-
 #endif /* __ASSEMBLY__ */
 
 #endif
index 2d0e4e99856624415d72e1ddcae38bb1f6dadb32..e9e29a6c3868eb6ea462c8df13073915440ac36e 100644 (file)
@@ -19,7 +19,7 @@
 /* DBGU base */
 /* rm9200, 9260/9g20, 9261/9g10, 9rl */
 #define AT91_BASE_DBGU0        0xfffff200
-/* 9263, 9g45, cap9 */
+/* 9263, 9g45 */
 #define AT91_BASE_DBGU1        0xffffee00
 
 #if defined(CONFIG_ARCH_AT91RM9200)
@@ -34,8 +34,8 @@
 #include <mach/at91sam9rl.h>
 #elif defined(CONFIG_ARCH_AT91SAM9G45)
 #include <mach/at91sam9g45.h>
-#elif defined(CONFIG_ARCH_AT91CAP9)
-#include <mach/at91cap9.h>
+#elif defined(CONFIG_ARCH_AT91SAM9X5)
+#include <mach/at91sam9x5.h>
 #elif defined(CONFIG_ARCH_AT91X40)
 #include <mach/at91x40.h>
 #else
 
 /*
  * On all at91 have the Advanced Interrupt Controller starts at address
- * 0xfffff000
+ * 0xfffff000 and the Power Management Controller starts at 0xfffffc00
  */
 #define AT91_AIC       0xfffff000
+#define AT91_PMC       0xfffffc00
 
 /*
  * Peripheral identifiers/interrupts.
index 4ca09ef7ca2906e39654fe9867405c04c824ed6f..4003001eca3d55f26dcf3906db9e0e87307321a2 100644 (file)
 #define __io(a)                __typesafe_io(a)
 #define __mem_pci(a)   (a)
 
-#ifndef __ASSEMBLY__
-
-static inline unsigned int at91_sys_read(unsigned int reg_offset)
-{
-       void __iomem *addr = (void __iomem *)AT91_VA_BASE_SYS;
-
-       return __raw_readl(addr + reg_offset);
-}
-
-static inline void at91_sys_write(unsigned int reg_offset, unsigned long value)
-{
-       void __iomem *addr = (void __iomem *)AT91_VA_BASE_SYS;
-
-       __raw_writel(value, addr + reg_offset);
-}
-
-#endif
-
 #endif
index be6b639ecd7b7ac431d289b79f993c9f023b1479..cfcfcbe362699d1ed04be46e2d9680bc89917e58 100644 (file)
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/types.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/err.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach/map.h>
 
 void __iomem *at91_aic_base;
+static struct irq_domain *at91_aic_domain;
+static struct device_node *at91_aic_np;
 
 static void at91_aic_mask_irq(struct irq_data *d)
 {
        /* Disable interrupt on AIC */
-       at91_aic_write(AT91_AIC_IDCR, 1 << d->irq);
+       at91_aic_write(AT91_AIC_IDCR, 1 << d->hwirq);
 }
 
 static void at91_aic_unmask_irq(struct irq_data *d)
 {
        /* Enable interrupt on AIC */
-       at91_aic_write(AT91_AIC_IECR, 1 << d->irq);
+       at91_aic_write(AT91_AIC_IECR, 1 << d->hwirq);
 }
 
 unsigned int at91_extern_irq;
 
-#define is_extern_irq(irq) ((1 << (irq)) & at91_extern_irq)
+#define is_extern_irq(hwirq) ((1 << (hwirq)) & at91_extern_irq)
 
 static int at91_aic_set_type(struct irq_data *d, unsigned type)
 {
@@ -63,13 +71,13 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type)
                srctype = AT91_AIC_SRCTYPE_RISING;
                break;
        case IRQ_TYPE_LEVEL_LOW:
-               if ((d->irq == AT91_ID_FIQ) || is_extern_irq(d->irq))           /* only supported on external interrupts */
+               if ((d->hwirq == AT91_ID_FIQ) || is_extern_irq(d->hwirq))               /* only supported on external interrupts */
                        srctype = AT91_AIC_SRCTYPE_LOW;
                else
                        return -EINVAL;
                break;
        case IRQ_TYPE_EDGE_FALLING:
-               if ((d->irq == AT91_ID_FIQ) || is_extern_irq(d->irq))           /* only supported on external interrupts */
+               if ((d->hwirq == AT91_ID_FIQ) || is_extern_irq(d->hwirq))               /* only supported on external interrupts */
                        srctype = AT91_AIC_SRCTYPE_FALLING;
                else
                        return -EINVAL;
@@ -78,8 +86,8 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type)
                return -EINVAL;
        }
 
-       smr = at91_aic_read(AT91_AIC_SMR(d->irq)) & ~AT91_AIC_SRCTYPE;
-       at91_aic_write(AT91_AIC_SMR(d->irq), smr | srctype);
+       smr = at91_aic_read(AT91_AIC_SMR(d->hwirq)) & ~AT91_AIC_SRCTYPE;
+       at91_aic_write(AT91_AIC_SMR(d->hwirq), smr | srctype);
        return 0;
 }
 
@@ -90,13 +98,13 @@ static u32 backups;
 
 static int at91_aic_set_wake(struct irq_data *d, unsigned value)
 {
-       if (unlikely(d->irq >= 32))
+       if (unlikely(d->hwirq >= NR_AIC_IRQS))
                return -EINVAL;
 
        if (value)
-               wakeups |= (1 << d->irq);
+               wakeups |= (1 << d->hwirq);
        else
-               wakeups &= ~(1 << d->irq);
+               wakeups &= ~(1 << d->hwirq);
 
        return 0;
 }
@@ -127,46 +135,112 @@ static struct irq_chip at91_aic_chip = {
        .irq_set_wake   = at91_aic_set_wake,
 };
 
+static void __init at91_aic_hw_init(unsigned int spu_vector)
+{
+       int i;
+
+       /*
+        * Perform 8 End Of Interrupt Command to make sure AIC
+        * will not Lock out nIRQ
+        */
+       for (i = 0; i < 8; i++)
+               at91_aic_write(AT91_AIC_EOICR, 0);
+
+       /*
+        * Spurious Interrupt ID in Spurious Vector Register.
+        * When there is no current interrupt, the IRQ Vector Register
+        * reads the value stored in AIC_SPU
+        */
+       at91_aic_write(AT91_AIC_SPU, spu_vector);
+
+       /* No debugging in AIC: Debug (Protect) Control Register */
+       at91_aic_write(AT91_AIC_DCR, 0);
+
+       /* Disable and clear all interrupts initially */
+       at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF);
+       at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF);
+}
+
+#if defined(CONFIG_OF)
+static int at91_aic_irq_map(struct irq_domain *h, unsigned int virq,
+                                                       irq_hw_number_t hw)
+{
+       /* Put virq number in Source Vector Register */
+       at91_aic_write(AT91_AIC_SVR(hw), virq);
+
+       /* Active Low interrupt, without priority */
+       at91_aic_write(AT91_AIC_SMR(hw), AT91_AIC_SRCTYPE_LOW);
+
+       irq_set_chip_and_handler(virq, &at91_aic_chip, handle_level_irq);
+       set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
+
+       return 0;
+}
+
+static struct irq_domain_ops at91_aic_irq_ops = {
+       .map    = at91_aic_irq_map,
+       .xlate  = irq_domain_xlate_twocell,
+};
+
+int __init at91_aic_of_init(struct device_node *node,
+                                    struct device_node *parent)
+{
+       at91_aic_base = of_iomap(node, 0);
+       at91_aic_np = node;
+
+       at91_aic_domain = irq_domain_add_linear(at91_aic_np, NR_AIC_IRQS,
+                                               &at91_aic_irq_ops, NULL);
+       if (!at91_aic_domain)
+               panic("Unable to add AIC irq domain (DT)\n");
+
+       irq_set_default_host(at91_aic_domain);
+
+       at91_aic_hw_init(NR_AIC_IRQS);
+
+       return 0;
+}
+#endif
+
 /*
  * Initialize the AIC interrupt controller.
  */
 void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
 {
        unsigned int i;
+       int irq_base;
 
        at91_aic_base = ioremap(AT91_AIC, 512);
-
        if (!at91_aic_base)
-               panic("Impossible to ioremap AT91_AIC\n");
+               panic("Unable to ioremap AIC registers\n");
+
+       /* Add irq domain for AIC */
+       irq_base = irq_alloc_descs(-1, 0, NR_AIC_IRQS, 0);
+       if (irq_base < 0) {
+               WARN(1, "Cannot allocate irq_descs, assuming pre-allocated\n");
+               irq_base = 0;
+       }
+       at91_aic_domain = irq_domain_add_legacy(at91_aic_np, NR_AIC_IRQS,
+                                               irq_base, 0,
+                                               &irq_domain_simple_ops, NULL);
+
+       if (!at91_aic_domain)
+               panic("Unable to add AIC irq domain\n");
+
+       irq_set_default_host(at91_aic_domain);
 
        /*
         * The IVR is used by macro get_irqnr_and_base to read and verify.
         * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred.
         */
        for (i = 0; i < NR_AIC_IRQS; i++) {
-               /* Put irq number in Source Vector Register: */
+               /* Put hardware irq number in Source Vector Register: */
                at91_aic_write(AT91_AIC_SVR(i), i);
                /* Active Low interrupt, with the specified priority */
                at91_aic_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]);
 
                irq_set_chip_and_handler(i, &at91_aic_chip, handle_level_irq);
                set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
-
-               /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */
-               if (i < 8)
-                       at91_aic_write(AT91_AIC_EOICR, 0);
        }
 
-       /*
-        * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS
-        * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU
-        */
-       at91_aic_write(AT91_AIC_SPU, NR_AIC_IRQS);
-
-       /* No debugging in AIC: Debug (Protect) Control Register */
-       at91_aic_write(AT91_AIC_DCR, 0);
-
-       /* Disable and clear all interrupts initially */
-       at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF);
-       at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF);
+       at91_aic_hw_init(NR_AIC_IRQS);
 }
index 1606379ac28462dd33f31ba8e0756a9d6ec4d21a..f630250c6b8779d0f0fc528adb1ba7631a42df37 100644 (file)
@@ -136,7 +136,7 @@ static int at91_pm_verify_clocks(void)
        unsigned long scsr;
        int i;
 
-       scsr = at91_sys_read(AT91_PMC_SCSR);
+       scsr = at91_pmc_read(AT91_PMC_SCSR);
 
        /* USB must not be using PLLB */
        if (cpu_is_at91rm9200()) {
@@ -150,11 +150,6 @@ static int at91_pm_verify_clocks(void)
                        pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
                        return 0;
                }
-       } else if (cpu_is_at91cap9()) {
-               if ((scsr & AT91CAP9_PMC_UHP) != 0) {
-                       pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
-                       return 0;
-               }
        }
 
 #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
@@ -165,7 +160,7 @@ static int at91_pm_verify_clocks(void)
                if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
                        continue;
 
-               css = at91_sys_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
+               css = at91_pmc_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
                if (css != AT91_PMC_CSS_SLOW) {
                        pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
                        return 0;
@@ -193,23 +188,23 @@ int at91_suspend_entering_slow_clock(void)
 EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
 
 
-static void (*slow_clock)(void);
+static void (*slow_clock)(void __iomem *pmc, void __iomem *ramc0,
+                         void __iomem *ramc1, int memctrl);
 
 #ifdef CONFIG_AT91_SLOW_CLOCK
-extern void at91_slow_clock(void);
+extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0,
+                           void __iomem *ramc1, int memctrl);
 extern u32 at91_slow_clock_sz;
 #endif
 
-
 static int at91_pm_enter(suspend_state_t state)
 {
-       u32 saved_lpr;
        at91_gpio_suspend();
        at91_irq_suspend();
 
        pr_debug("AT91: PM - wake mask %08x, pm state %d\n",
                        /* remember all the always-wake irqs */
-                       (at91_sys_read(AT91_PMC_PCSR)
+                       (at91_pmc_read(AT91_PMC_PCSR)
                                        | (1 << AT91_ID_FIQ)
                                        | (1 << AT91_ID_SYS)
                                        | (at91_extern_irq))
@@ -234,11 +229,18 @@ static int at91_pm_enter(suspend_state_t state)
                         * turning off the main oscillator; reverse on wakeup.
                         */
                        if (slow_clock) {
+                               int memctrl = AT91_MEMCTRL_SDRAMC;
+
+                               if (cpu_is_at91rm9200())
+                                       memctrl = AT91_MEMCTRL_MC;
+                               else if (cpu_is_at91sam9g45())
+                                       memctrl = AT91_MEMCTRL_DDRSDR;
 #ifdef CONFIG_AT91_SLOW_CLOCK
                                /* copy slow_clock handler to SRAM, and call it */
                                memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz);
 #endif
-                               slow_clock();
+                               slow_clock(at91_pmc_base, at91_ramc_base[0],
+                                          at91_ramc_base[1], memctrl);
                                break;
                        } else {
                                pr_info("AT91: PM - no slow clock mode enabled ...\n");
@@ -259,16 +261,7 @@ static int at91_pm_enter(suspend_state_t state)
                         * For ARM 926 based chips, this requirement is weaker
                         * as at91sam9 can access a RAM in self-refresh mode.
                         */
-                       asm volatile (  "mov r0, #0\n\t"
-                                       "b 1f\n\t"
-                                       ".align 5\n\t"
-                                       "1: mcr p15, 0, r0, c7, c10, 4\n\t"
-                                       : /* no output */
-                                       : /* no input */
-                                       : "r0");
-                       saved_lpr = sdram_selfrefresh_enable();
-                       wait_for_interrupt_enable();
-                       sdram_selfrefresh_disable(saved_lpr);
+                       at91_standby();
                        break;
 
                case PM_SUSPEND_ON:
@@ -316,7 +309,7 @@ static int __init at91_pm_init(void)
 
 #ifdef CONFIG_ARCH_AT91RM9200
        /* AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. */
-       at91_sys_write(AT91_SDRAMC_LPR, 0);
+       at91_ramc_write(0, AT91RM9200_SDRAMC_LPR, 0);
 #endif
 
        suspend_set_ops(&at91_pm_ops);
index 7eb40d24242f2ae54fbd9ab8197d6166f98381eb..89f56f3a802e4d0726ae6f60db62bf41881a57f4 100644 (file)
@@ -1,5 +1,19 @@
+/*
+ * AT91 Power Management
+ *
+ * Copyright (C) 2005 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __ARCH_ARM_MACH_AT91_PM
+#define __ARCH_ARM_MACH_AT91_PM
+
+#include <mach/at91_ramc.h>
 #ifdef CONFIG_ARCH_AT91RM9200
-#include <mach/at91rm9200_mc.h>
+#include <mach/at91rm9200_sdramc.h>
 
 /*
  * The AT91RM9200 goes into self-refresh mode with this command, and will
  * still in self-refresh is "not recommended", but seems to work.
  */
 
-static inline u32 sdram_selfrefresh_enable(void)
+static inline void at91rm9200_standby(void)
 {
-       u32 saved_lpr = at91_sys_read(AT91_SDRAMC_LPR);
-
-       at91_sys_write(AT91_SDRAMC_LPR, 0);
-       at91_sys_write(AT91_SDRAMC_SRR, 1);
-       return saved_lpr;
+       u32 lpr = at91_ramc_read(0, AT91RM9200_SDRAMC_LPR);
+
+       asm volatile(
+               "b    1f\n\t"
+               ".align    5\n\t"
+               "1:  mcr    p15, 0, %0, c7, c10, 4\n\t"
+               "    str    %0, [%1, %2]\n\t"
+               "    str    %3, [%1, %4]\n\t"
+               "    mcr    p15, 0, %0, c7, c0, 4\n\t"
+               "    str    %5, [%1, %2]"
+               :
+               : "r" (0), "r" (AT91_BASE_SYS), "r" (AT91RM9200_SDRAMC_LPR),
+                 "r" (1), "r" (AT91RM9200_SDRAMC_SRR),
+                 "r" (lpr));
 }
 
-#define sdram_selfrefresh_disable(saved_lpr)   at91_sys_write(AT91_SDRAMC_LPR, saved_lpr)
-#define wait_for_interrupt_enable()            asm volatile ("mcr p15, 0, %0, c7, c0, 4" \
-                                                               : : "r" (0))
-
-#elif defined(CONFIG_ARCH_AT91CAP9)
-#include <mach/at91sam9_ddrsdr.h>
-
-
-static inline u32 sdram_selfrefresh_enable(void)
-{
-       u32 saved_lpr, lpr;
-
-       saved_lpr = at91_ramc_read(0, AT91CAP9_DDRSDRC_LPR);
-
-       lpr = saved_lpr & ~AT91_DDRSDRC_LPCB;
-       at91_ramc_write(0, AT91CAP9_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH);
-       return saved_lpr;
-}
-
-#define sdram_selfrefresh_disable(saved_lpr)   at91_ramc_write(0, AT91CAP9_DDRSDRC_LPR, saved_lpr)
-#define wait_for_interrupt_enable()            cpu_do_idle()
+#define at91_standby at91rm9200_standby
 
 #elif defined(CONFIG_ARCH_AT91SAM9G45)
-#include <mach/at91sam9_ddrsdr.h>
 
 /* We manage both DDRAM/SDRAM controllers, we need more than one value to
  * remember.
  */
-static u32 saved_lpr1;
-
-static inline u32 sdram_selfrefresh_enable(void)
+static inline void at91sam9g45_standby(void)
 {
-       /* Those tow values allow us to delay self-refresh activation
+       /* Those two values allow us to delay self-refresh activation
         * to the maximum. */
        u32 lpr0, lpr1;
-       u32 saved_lpr0;
+       u32 saved_lpr0, saved_lpr1;
 
        saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
        lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
@@ -69,18 +69,15 @@ static inline u32 sdram_selfrefresh_enable(void)
        at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
        at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
 
-       return saved_lpr0;
+       cpu_do_idle();
+
+       at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
+       at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
 }
 
-#define sdram_selfrefresh_disable(saved_lpr0)  \
-       do { \
-               at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); \
-               at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); \
-       } while (0)
-#define wait_for_interrupt_enable()            cpu_do_idle()
+#define at91_standby at91sam9g45_standby
 
 #else
-#include <mach/at91sam9_sdramc.h>
 
 #ifdef CONFIG_ARCH_AT91SAM9263
 /*
@@ -90,18 +87,23 @@ static inline u32 sdram_selfrefresh_enable(void)
 #warning Assuming EB1 SDRAM controller is *NOT* used
 #endif
 
-static inline u32 sdram_selfrefresh_enable(void)
+static inline void at91sam9_standby(void)
 {
        u32 saved_lpr, lpr;
 
        saved_lpr = at91_ramc_read(0, AT91_SDRAMC_LPR);
 
        lpr = saved_lpr & ~AT91_SDRAMC_LPCB;
-       at91_ramc_write(0, AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH);
-       return saved_lpr;
+       at91_ramc_write(0, AT91_SDRAMC_LPR, lpr |
+                       AT91_SDRAMC_LPCB_SELF_REFRESH);
+
+       cpu_do_idle();
+
+       at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr);
 }
 
-#define sdram_selfrefresh_disable(saved_lpr)   at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr)
-#define wait_for_interrupt_enable()            cpu_do_idle()
+#define at91_standby at91sam9_standby
+
+#endif
 
 #endif
index 92dfb8461392a66541a1370de2c7dce11c03a039..db5452123f17b5e564f6378db72dd6a75e8931ed 100644 (file)
 #include <linux/linkage.h>
 #include <mach/hardware.h>
 #include <mach/at91_pmc.h>
-
-#if defined(CONFIG_ARCH_AT91RM9200)
-#include <mach/at91rm9200_mc.h>
-#elif defined(CONFIG_ARCH_AT91CAP9) \
-       || defined(CONFIG_ARCH_AT91SAM9G45)
-#include <mach/at91sam9_ddrsdr.h>
-#else
-#include <mach/at91sam9_sdramc.h>
-#endif
+#include <mach/at91_ramc.h>
 
 
 #ifdef CONFIG_ARCH_AT91SAM9263
 #define PLLALOCK_TIMEOUT       1000
 #define PLLBLOCK_TIMEOUT       1000
 
+pmc    .req    r0
+sdramc .req    r1
+ramc1  .req    r2
+memctrl        .req    r3
+tmp1   .req    r4
+tmp2   .req    r5
 
 /*
  * Wait until master clock is ready (after switching master clock source)
  */
        .macro wait_mckrdy
-       mov     r4, #MCKRDY_TIMEOUT
-1:     sub     r4, r4, #1
-       cmp     r4, #0
+       mov     tmp2, #MCKRDY_TIMEOUT
+1:     sub     tmp2, tmp2, #1
+       cmp     tmp2, #0
        beq     2f
-       ldr     r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
-       tst     r3, #AT91_PMC_MCKRDY
+       ldr     tmp1, [pmc, #AT91_PMC_SR]
+       tst     tmp1, #AT91_PMC_MCKRDY
        beq     1b
 2:
        .endm
  * Wait until master oscillator has stabilized.
  */
        .macro wait_moscrdy
-       mov     r4, #MOSCRDY_TIMEOUT
-1:     sub     r4, r4, #1
-       cmp     r4, #0
+       mov     tmp2, #MOSCRDY_TIMEOUT
+1:     sub     tmp2, tmp2, #1
+       cmp     tmp2, #0
        beq     2f
-       ldr     r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
-       tst     r3, #AT91_PMC_MOSCS
+       ldr     tmp1, [pmc, #AT91_PMC_SR]
+       tst     tmp1, #AT91_PMC_MOSCS
        beq     1b
 2:
        .endm
  * Wait until PLLA has locked.
  */
        .macro wait_pllalock
-       mov     r4, #PLLALOCK_TIMEOUT
-1:     sub     r4, r4, #1
-       cmp     r4, #0
+       mov     tmp2, #PLLALOCK_TIMEOUT
+1:     sub     tmp2, tmp2, #1
+       cmp     tmp2, #0
        beq     2f
-       ldr     r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
-       tst     r3, #AT91_PMC_LOCKA
+       ldr     tmp1, [pmc, #AT91_PMC_SR]
+       tst     tmp1, #AT91_PMC_LOCKA
        beq     1b
 2:
        .endm
  * Wait until PLLB has locked.
  */
        .macro wait_pllblock
-       mov     r4, #PLLBLOCK_TIMEOUT
-1:     sub     r4, r4, #1
-       cmp     r4, #0
+       mov     tmp2, #PLLBLOCK_TIMEOUT
+1:     sub     tmp2, tmp2, #1
+       cmp     tmp2, #0
        beq     2f
-       ldr     r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
-       tst     r3, #AT91_PMC_LOCKB
+       ldr     tmp1, [pmc, #AT91_PMC_SR]
+       tst     tmp1, #AT91_PMC_LOCKB
        beq     1b
 2:
        .endm
 
        .text
 
+/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc,
+ *                     void __iomem *ramc1, int memctrl)
+ */
 ENTRY(at91_slow_clock)
        /* Save registers on stack */
-       stmfd   sp!, {r0 - r12, lr}
+       stmfd   sp!, {r4 - r12, lr}
 
        /*
         * Register usage:
-        *  R1 = Base address of AT91_PMC
-        *  R2 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
-        *  R3 = temporary register
+        *  R0 = Base address of AT91_PMC
+        *  R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
+        *  R2 = Base address of second RAM Controller or 0 if not present
+        *  R3 = Memory controller
         *  R4 = temporary register
-        *  R5 = Base address of second RAM Controller or 0 if not present
+        *  R5 = temporary register
         */
-       ldr     r1, .at91_va_base_pmc
-       ldr     r2, .at91_va_base_sdramc
-       ldr     r5, .at91_va_base_ramc1
 
        /* Drain write buffer */
-       mov     r0, #0
-       mcr     p15, 0, r0, c7, c10, 4
+       mov     tmp1, #0
+       mcr     p15, 0, tmp1, c7, c10, 4
+
+       cmp     memctrl, #AT91_MEMCTRL_MC
+       bne     ddr_sr_enable
 
-#ifdef CONFIG_ARCH_AT91RM9200
+       /*
+        * at91rm9200 Memory controller
+        */
        /* Put SDRAM in self-refresh mode */
-       mov     r3, #1
-       str     r3, [r2, #AT91_SDRAMC_SRR]
-#elif defined(CONFIG_ARCH_AT91CAP9) \
-       || defined(CONFIG_ARCH_AT91SAM9G45)
+       mov     tmp1, #1
+       str     tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR]
+       b       sdr_sr_done
+
+       /*
+        * DDRSDR Memory controller
+        */
+ddr_sr_enable:
+       cmp     memctrl, #AT91_MEMCTRL_DDRSDR
+       bne     sdr_sr_enable
 
        /* prepare for DDRAM self-refresh mode */
-       ldr     r3, [r2, #AT91_DDRSDRC_LPR]
-       str     r3, .saved_sam9_lpr
-       bic     r3, #AT91_DDRSDRC_LPCB
-       orr     r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
+       ldr     tmp1, [sdramc, #AT91_DDRSDRC_LPR]
+       str     tmp1, .saved_sam9_lpr
+       bic     tmp1, #AT91_DDRSDRC_LPCB
+       orr     tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH
 
        /* figure out if we use the second ram controller */
-       cmp     r5, #0
-       ldrne   r4, [r5, #AT91_DDRSDRC_LPR]
-       strne   r4, .saved_sam9_lpr1
-       bicne   r4, #AT91_DDRSDRC_LPCB
-       orrne   r4, #AT91_DDRSDRC_LPCB_SELF_REFRESH
+       cmp     ramc1, #0
+       ldrne   tmp2, [ramc1, #AT91_DDRSDRC_LPR]
+       strne   tmp2, .saved_sam9_lpr1
+       bicne   tmp2, #AT91_DDRSDRC_LPCB
+       orrne   tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
 
        /* Enable DDRAM self-refresh mode */
-       str     r3, [r2, #AT91_DDRSDRC_LPR]
-       strne   r4, [r5, #AT91_DDRSDRC_LPR]
-#else
+       str     tmp1, [sdramc, #AT91_DDRSDRC_LPR]
+       strne   tmp2, [ramc1, #AT91_DDRSDRC_LPR]
+
+       b       sdr_sr_done
+
+       /*
+        * SDRAMC Memory controller
+        */
+sdr_sr_enable:
        /* Enable SDRAM self-refresh mode */
-       ldr     r3, [r2, #AT91_SDRAMC_LPR]
-       str     r3, .saved_sam9_lpr
+       ldr     tmp1, [sdramc, #AT91_SDRAMC_LPR]
+       str     tmp1, .saved_sam9_lpr
 
-       bic     r3, #AT91_SDRAMC_LPCB
-       orr     r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
-       str     r3, [r2, #AT91_SDRAMC_LPR]
-#endif
+       bic     tmp1, #AT91_SDRAMC_LPCB
+       orr     tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH
+       str     tmp1, [sdramc, #AT91_SDRAMC_LPR]
 
+sdr_sr_done:
        /* Save Master clock setting */
-       ldr     r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
-       str     r3, .saved_mckr
+       ldr     tmp1, [pmc, #AT91_PMC_MCKR]
+       str     tmp1, .saved_mckr
 
        /*
         * Set the Master clock source to slow clock
         */
-       bic     r3, r3, #AT91_PMC_CSS
-       str     r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
+       bic     tmp1, tmp1, #AT91_PMC_CSS
+       str     tmp1, [pmc, #AT91_PMC_MCKR]
 
        wait_mckrdy
 
@@ -177,61 +193,61 @@ ENTRY(at91_slow_clock)
         *
         * See AT91RM9200 errata #27 and #28 for details.
         */
-       mov     r3, #0
-       str     r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
+       mov     tmp1, #0
+       str     tmp1, [pmc, #AT91_PMC_MCKR]
 
        wait_mckrdy
 #endif
 
        /* Save PLLA setting and disable it */
-       ldr     r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
-       str     r3, .saved_pllar
+       ldr     tmp1, [pmc, #AT91_CKGR_PLLAR]
+       str     tmp1, .saved_pllar
 
-       mov     r3, #AT91_PMC_PLLCOUNT
-       orr     r3, r3, #(1 << 29)              /* bit 29 always set */
-       str     r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
+       mov     tmp1, #AT91_PMC_PLLCOUNT
+       orr     tmp1, tmp1, #(1 << 29)          /* bit 29 always set */
+       str     tmp1, [pmc, #AT91_CKGR_PLLAR]
 
        /* Save PLLB setting and disable it */
-       ldr     r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
-       str     r3, .saved_pllbr
+       ldr     tmp1, [pmc, #AT91_CKGR_PLLBR]
+       str     tmp1, .saved_pllbr
 
-       mov     r3, #AT91_PMC_PLLCOUNT
-       str     r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
+       mov     tmp1, #AT91_PMC_PLLCOUNT
+       str     tmp1, [pmc, #AT91_CKGR_PLLBR]
 
        /* Turn off the main oscillator */
-       ldr     r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
-       bic     r3, r3, #AT91_PMC_MOSCEN
-       str     r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
+       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
+       bic     tmp1, tmp1, #AT91_PMC_MOSCEN
+       str     tmp1, [pmc, #AT91_CKGR_MOR]
 
        /* Wait for interrupt */
-       mcr     p15, 0, r0, c7, c0, 4
+       mcr     p15, 0, tmp1, c7, c0, 4
 
        /* Turn on the main oscillator */
-       ldr     r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
-       orr     r3, r3, #AT91_PMC_MOSCEN
-       str     r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
+       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
+       orr     tmp1, tmp1, #AT91_PMC_MOSCEN
+       str     tmp1, [pmc, #AT91_CKGR_MOR]
 
        wait_moscrdy
 
        /* Restore PLLB setting */
-       ldr     r3, .saved_pllbr
-       str     r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
+       ldr     tmp1, .saved_pllbr
+       str     tmp1, [pmc, #AT91_CKGR_PLLBR]
 
-       tst     r3, #(AT91_PMC_MUL &  0xff0000)
+       tst     tmp1, #(AT91_PMC_MUL &  0xff0000)
        bne     1f
-       tst     r3, #(AT91_PMC_MUL & ~0xff0000)
+       tst     tmp1, #(AT91_PMC_MUL & ~0xff0000)
        beq     2f
 1:
        wait_pllblock
 2:
 
        /* Restore PLLA setting */
-       ldr     r3, .saved_pllar
-       str     r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
+       ldr     tmp1, .saved_pllar
+       str     tmp1, [pmc, #AT91_CKGR_PLLAR]
 
-       tst     r3, #(AT91_PMC_MUL &  0xff0000)
+       tst     tmp1, #(AT91_PMC_MUL &  0xff0000)
        bne     3f
-       tst     r3, #(AT91_PMC_MUL & ~0xff0000)
+       tst     tmp1, #(AT91_PMC_MUL & ~0xff0000)
        beq     4f
 3:
        wait_pllalock
@@ -244,11 +260,11 @@ ENTRY(at91_slow_clock)
         *
         * See AT91RM9200 errata #27 and #28 for details.
         */
-       ldr     r3, .saved_mckr
-       tst     r3, #AT91_PMC_PRES
+       ldr     tmp1, .saved_mckr
+       tst     tmp1, #AT91_PMC_PRES
        beq     2f
-       and     r3, r3, #AT91_PMC_PRES
-       str     r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
+       and     tmp1, tmp1, #AT91_PMC_PRES
+       str     tmp1, [pmc, #AT91_PMC_MCKR]
 
        wait_mckrdy
 #endif
@@ -256,32 +272,45 @@ ENTRY(at91_slow_clock)
        /*
         * Restore master clock setting
         */
-2:     ldr     r3, .saved_mckr
-       str     r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
+2:     ldr     tmp1, .saved_mckr
+       str     tmp1, [pmc, #AT91_PMC_MCKR]
 
        wait_mckrdy
 
-#ifdef CONFIG_ARCH_AT91RM9200
-       /* Do nothing - self-refresh is automatically disabled. */
-#elif defined(CONFIG_ARCH_AT91CAP9) \
-       || defined(CONFIG_ARCH_AT91SAM9G45)
+       /*
+        * at91rm9200 Memory controller
+        * Do nothing - self-refresh is automatically disabled.
+        */
+       cmp     memctrl, #AT91_MEMCTRL_MC
+       beq     ram_restored
+
+       /*
+        * DDRSDR Memory controller
+        */
+       cmp     memctrl, #AT91_MEMCTRL_DDRSDR
+       bne     sdr_en_restore
        /* Restore LPR on AT91 with DDRAM */
-       ldr     r3, .saved_sam9_lpr
-       str     r3, [r2, #AT91_DDRSDRC_LPR]
+       ldr     tmp1, .saved_sam9_lpr
+       str     tmp1, [sdramc, #AT91_DDRSDRC_LPR]
 
        /* if we use the second ram controller */
-       cmp     r5, #0
-       ldrne   r4, .saved_sam9_lpr1
-       strne   r4, [r5, #AT91_DDRSDRC_LPR]
+       cmp     ramc1, #0
+       ldrne   tmp2, .saved_sam9_lpr1
+       strne   tmp2, [ramc1, #AT91_DDRSDRC_LPR]
+
+       b       ram_restored
 
-#else
+       /*
+        * SDRAMC Memory controller
+        */
+sdr_en_restore:
        /* Restore LPR on AT91 with SDRAM */
-       ldr     r3, .saved_sam9_lpr
-       str     r3, [r2, #AT91_SDRAMC_LPR]
-#endif
+       ldr     tmp1, .saved_sam9_lpr
+       str     tmp1, [sdramc, #AT91_SDRAMC_LPR]
 
+ram_restored:
        /* Restore registers, and return */
-       ldmfd   sp!, {r0 - r12, pc}
+       ldmfd   sp!, {r4 - r12, pc}
 
 
 .saved_mckr:
@@ -299,27 +328,5 @@ ENTRY(at91_slow_clock)
 .saved_sam9_lpr1:
        .word 0
 
-.at91_va_base_pmc:
-       .word AT91_VA_BASE_SYS + AT91_PMC
-
-#ifdef CONFIG_ARCH_AT91RM9200
-.at91_va_base_sdramc:
-       .word AT91_VA_BASE_SYS
-#elif defined(CONFIG_ARCH_AT91CAP9) \
-       || defined(CONFIG_ARCH_AT91SAM9G45)
-.at91_va_base_sdramc:
-       .word AT91_VA_BASE_SYS + AT91_DDRSDRC0
-#else
-.at91_va_base_sdramc:
-       .word AT91_VA_BASE_SYS + AT91_SDRAMC0
-#endif
-
-.at91_va_base_ramc1:
-#if defined(CONFIG_ARCH_AT91SAM9G45)
-       .word AT91_VA_BASE_SYS + AT91_DDRSDRC1
-#else
-       .word 0
-#endif
-
 ENTRY(at91_slow_clock_sz)
        .word .-at91_slow_clock
index 69d3fc4c46f372ff99c2468f5e8eda6cc110bfd5..1083739e30650185ccaed48d7f242e1bee4ce506 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/io.h>
 #include <linux/mm.h>
 #include <linux/pm.h>
+#include <linux/of_address.h>
 
 #include <asm/mach/map.h>
 
@@ -51,6 +52,19 @@ void __init at91_init_interrupts(unsigned int *priority)
        at91_gpio_irq_setup();
 }
 
+void __iomem *at91_ramc_base[2];
+
+void __init at91_ioremap_ramc(int id, u32 addr, u32 size)
+{
+       if (id < 0 || id > 1) {
+               pr_emerg("Wrong RAM controller id (%d), cannot continue\n", id);
+               BUG();
+       }
+       at91_ramc_base[id] = ioremap(addr, size);
+       if (!at91_ramc_base[id])
+               panic("Impossible to ioremap ramc.%d 0x%x\n", id, addr);
+}
+
 static struct map_desc sram_desc[2] __initdata;
 
 void __init at91_init_sram(int bank, unsigned long base, unsigned int length)
@@ -86,20 +100,6 @@ static void __init soc_detect(u32 dbgu_base)
        socid = cidr & ~AT91_CIDR_VERSION;
 
        switch (socid) {
-       case ARCH_ID_AT91CAP9: {
-#ifdef CONFIG_AT91_PMC_UNIT
-               u32 pmc_ver = at91_sys_read(AT91_PMC_VER);
-
-               if (pmc_ver == ARCH_REVISION_CAP9_B)
-                       at91_soc_initdata.subtype = AT91_SOC_CAP9_REV_B;
-               else if (pmc_ver == ARCH_REVISION_CAP9_C)
-                       at91_soc_initdata.subtype = AT91_SOC_CAP9_REV_C;
-#endif
-               at91_soc_initdata.type = AT91_SOC_CAP9;
-               at91_boot_soc = at91cap9_soc;
-               break;
-       }
-
        case ARCH_ID_AT91RM9200:
                at91_soc_initdata.type = AT91_SOC_RM9200;
                at91_boot_soc = at91rm9200_soc;
@@ -200,7 +200,6 @@ static void __init soc_detect(u32 dbgu_base)
 
 static const char *soc_name[] = {
        [AT91_SOC_RM9200]       = "at91rm9200",
-       [AT91_SOC_CAP9]         = "at91cap9",
        [AT91_SOC_SAM9260]      = "at91sam9260",
        [AT91_SOC_SAM9261]      = "at91sam9261",
        [AT91_SOC_SAM9263]      = "at91sam9263",
@@ -221,8 +220,6 @@ EXPORT_SYMBOL(at91_get_soc_type);
 static const char *soc_subtype_name[] = {
        [AT91_SOC_RM9200_BGA]   = "at91rm9200 BGA",
        [AT91_SOC_RM9200_PQFP]  = "at91rm9200 PQFP",
-       [AT91_SOC_CAP9_REV_B]   = "at91cap9 revB",
-       [AT91_SOC_CAP9_REV_C]   = "at91cap9 revC",
        [AT91_SOC_SAM9XE]       = "at91sam9xe",
        [AT91_SOC_SAM9G45ES]    = "at91sam9g45es",
        [AT91_SOC_SAM9M10]      = "at91sam9m10",
@@ -293,6 +290,159 @@ void __init at91_ioremap_rstc(u32 base_addr)
                panic("Impossible to ioremap at91_rstc_base\n");
 }
 
+void __iomem *at91_matrix_base;
+
+void __init at91_ioremap_matrix(u32 base_addr)
+{
+       at91_matrix_base = ioremap(base_addr, 512);
+       if (!at91_matrix_base)
+               panic("Impossible to ioremap at91_matrix_base\n");
+}
+
+#if defined(CONFIG_OF)
+static struct of_device_id rstc_ids[] = {
+       { .compatible = "atmel,at91sam9260-rstc", .data = at91sam9_alt_restart },
+       { .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart },
+       { /*sentinel*/ }
+};
+
+static void at91_dt_rstc(void)
+{
+       struct device_node *np;
+       const struct of_device_id *of_id;
+
+       np = of_find_matching_node(NULL, rstc_ids);
+       if (!np)
+               panic("unable to find compatible rstc node in dtb\n");
+
+       at91_rstc_base = of_iomap(np, 0);
+       if (!at91_rstc_base)
+               panic("unable to map rstc cpu registers\n");
+
+       of_id = of_match_node(rstc_ids, np);
+       if (!of_id)
+               panic("AT91: rtsc no restart function availlable\n");
+
+       arm_pm_restart = of_id->data;
+
+       of_node_put(np);
+}
+
+static struct of_device_id ramc_ids[] = {
+       { .compatible = "atmel,at91sam9260-sdramc" },
+       { .compatible = "atmel,at91sam9g45-ddramc" },
+       { /*sentinel*/ }
+};
+
+static void at91_dt_ramc(void)
+{
+       struct device_node *np;
+
+       np = of_find_matching_node(NULL, ramc_ids);
+       if (!np)
+               panic("unable to find compatible ram conroller node in dtb\n");
+
+       at91_ramc_base[0] = of_iomap(np, 0);
+       if (!at91_ramc_base[0])
+               panic("unable to map ramc[0] cpu registers\n");
+       /* the controller may have 2 banks */
+       at91_ramc_base[1] = of_iomap(np, 1);
+
+       of_node_put(np);
+}
+
+static struct of_device_id shdwc_ids[] = {
+       { .compatible = "atmel,at91sam9260-shdwc", },
+       { .compatible = "atmel,at91sam9rl-shdwc", },
+       { .compatible = "atmel,at91sam9x5-shdwc", },
+       { /*sentinel*/ }
+};
+
+static const char *shdwc_wakeup_modes[] = {
+       [AT91_SHDW_WKMODE0_NONE]        = "none",
+       [AT91_SHDW_WKMODE0_HIGH]        = "high",
+       [AT91_SHDW_WKMODE0_LOW]         = "low",
+       [AT91_SHDW_WKMODE0_ANYLEVEL]    = "any",
+};
+
+const int at91_dtget_shdwc_wakeup_mode(struct device_node *np)
+{
+       const char *pm;
+       int err, i;
+
+       err = of_property_read_string(np, "atmel,wakeup-mode", &pm);
+       if (err < 0)
+               return AT91_SHDW_WKMODE0_ANYLEVEL;
+
+       for (i = 0; i < ARRAY_SIZE(shdwc_wakeup_modes); i++)
+               if (!strcasecmp(pm, shdwc_wakeup_modes[i]))
+                       return i;
+
+       return -ENODEV;
+}
+
+static void at91_dt_shdwc(void)
+{
+       struct device_node *np;
+       int wakeup_mode;
+       u32 reg;
+       u32 mode = 0;
+
+       np = of_find_matching_node(NULL, shdwc_ids);
+       if (!np) {
+               pr_debug("AT91: unable to find compatible shutdown (shdwc) conroller node in dtb\n");
+               return;
+       }
+
+       at91_shdwc_base = of_iomap(np, 0);
+       if (!at91_shdwc_base)
+               panic("AT91: unable to map shdwc cpu registers\n");
+
+       wakeup_mode = at91_dtget_shdwc_wakeup_mode(np);
+       if (wakeup_mode < 0) {
+               pr_warn("AT91: shdwc unknown wakeup mode\n");
+               goto end;
+       }
+
+       if (!of_property_read_u32(np, "atmel,wakeup-counter", &reg)) {
+               if (reg > AT91_SHDW_CPTWK0_MAX) {
+                       pr_warn("AT91: shdwc wakeup conter 0x%x > 0x%x reduce it to 0x%x\n",
+                               reg, AT91_SHDW_CPTWK0_MAX, AT91_SHDW_CPTWK0_MAX);
+                       reg = AT91_SHDW_CPTWK0_MAX;
+               }
+               mode |= AT91_SHDW_CPTWK0_(reg);
+       }
+
+       if (of_property_read_bool(np, "atmel,wakeup-rtc-timer"))
+                       mode |= AT91_SHDW_RTCWKEN;
+
+       if (of_property_read_bool(np, "atmel,wakeup-rtt-timer"))
+                       mode |= AT91_SHDW_RTTWKEN;
+
+       at91_shdwc_write(AT91_SHDW_MR, wakeup_mode | mode);
+
+end:
+       pm_power_off = at91sam9_poweroff;
+
+       of_node_put(np);
+}
+
+void __init at91_dt_initialize(void)
+{
+       at91_dt_rstc();
+       at91_dt_ramc();
+       at91_dt_shdwc();
+
+       /* Init clock subsystem */
+       at91_dt_clock_init();
+
+       /* Register the processor-specific clocks */
+       at91_boot_soc.register_clocks();
+
+       at91_boot_soc.init();
+}
+#endif
+
 void __init at91_initialize(unsigned long main_clock)
 {
        at91_boot_soc.ioremap_registers();
index 4588ae6f7acd0fda38afa0fee51eb57ac4eb6fa6..5db4aa45404aaeecca0e4fa11de1cf1bc9260dcb 100644 (file)
@@ -13,7 +13,6 @@ struct at91_init_soc {
 };
 
 extern struct at91_init_soc at91_boot_soc;
-extern struct at91_init_soc at91cap9_soc;
 extern struct at91_init_soc at91rm9200_soc;
 extern struct at91_init_soc at91sam9260_soc;
 extern struct at91_init_soc at91sam9261_soc;
@@ -27,10 +26,6 @@ static inline int at91_soc_is_enabled(void)
        return at91_boot_soc.init != NULL;
 }
 
-#if !defined(CONFIG_ARCH_AT91CAP9)
-#define at91cap9_soc   at91_boot_soc
-#endif
-
 #if !defined(CONFIG_ARCH_AT91RM9200)
 #define at91rm9200_soc at91_boot_soc
 #endif
index 275341f159fb6ee6cc0ddef2ca04bf14349eb913..82ed753fb36088936014a434c85378890647aefa 100644 (file)
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/dm355.h>
 #include <mach/i2c.h>
 #include <mach/serial.h>
 #include <mach/nand.h>
 #include <mach/mmc.h>
 #include <mach/usb.h>
 
+#include "davinci.h"
+
 /* NOTE:  this is geared for the standard config, with a socketed
  * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors.  If you
  * swap chips, maybe with a different block size, partitioning may
index e99db28181ae8ad518a08dfafbb57fa6de4d09f0..d74a8b3445fbc2cfd6958248cadf6fd04398000c 100644 (file)
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/dm355.h>
 #include <mach/i2c.h>
 #include <mach/serial.h>
 #include <mach/nand.h>
 #include <mach/mmc.h>
 #include <mach/usb.h>
 
+#include "davinci.h"
+
 /* NOTE:  this is geared for the standard config, with a socketed
  * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors.  If you
  * swap chips, maybe with a different block size, partitioning may
index 849311d3cb7c184f59adb7df85fe36876b4e3cb3..5bce2b83bb4fcde59938104b12f76caae6de8594 100644 (file)
@@ -32,7 +32,6 @@
 #include <asm/mach/arch.h>
 
 #include <mach/mux.h>
-#include <mach/dm365.h>
 #include <mach/common.h>
 #include <mach/i2c.h>
 #include <mach/serial.h>
@@ -42,6 +41,8 @@
 
 #include <media/tvp514x.h>
 
+#include "davinci.h"
+
 static inline int have_imager(void)
 {
        /* REVISIT when it's supported, trigger via Kconfig */
index 1247ecdcf752d57c7d6aa476a699b34c158a4324..3683306e02453e4d0bf5feb8b943c79a031745b8 100644 (file)
@@ -30,7 +30,6 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/dm644x.h>
 #include <mach/common.h>
 #include <mach/i2c.h>
 #include <mach/serial.h>
@@ -40,6 +39,8 @@
 #include <mach/usb.h>
 #include <mach/aemif.h>
 
+#include "davinci.h"
+
 #define DM644X_EVM_PHY_ID              "davinci_mdio-0:01"
 #define LXT971_PHY_ID  (0x001378e2)
 #define LXT971_PHY_MASK        (0xfffffff0)
@@ -189,7 +190,7 @@ static struct platform_device davinci_fb_device = {
        .num_resources = 0,
 };
 
-static struct tvp514x_platform_data tvp5146_pdata = {
+static struct tvp514x_platform_data dm644xevm_tvp5146_pdata = {
        .clk_polarity = 0,
        .hs_polarity = 1,
        .vs_polarity = 1
@@ -197,7 +198,7 @@ static struct tvp514x_platform_data tvp5146_pdata = {
 
 #define TVP514X_STD_ALL        (V4L2_STD_NTSC | V4L2_STD_PAL)
 /* Inputs available at the TVP5146 */
-static struct v4l2_input tvp5146_inputs[] = {
+static struct v4l2_input dm644xevm_tvp5146_inputs[] = {
        {
                .index = 0,
                .name = "Composite",
@@ -217,7 +218,7 @@ static struct v4l2_input tvp5146_inputs[] = {
  * ouput that goes to vpfe. There is a one to one correspondence
  * with tvp5146_inputs
  */
-static struct vpfe_route tvp5146_routes[] = {
+static struct vpfe_route dm644xevm_tvp5146_routes[] = {
        {
                .input = INPUT_CVBS_VI2B,
                .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
@@ -228,13 +229,13 @@ static struct vpfe_route tvp5146_routes[] = {
        },
 };
 
-static struct vpfe_subdev_info vpfe_sub_devs[] = {
+static struct vpfe_subdev_info dm644xevm_vpfe_sub_devs[] = {
        {
                .name = "tvp5146",
                .grp_id = 0,
-               .num_inputs = ARRAY_SIZE(tvp5146_inputs),
-               .inputs = tvp5146_inputs,
-               .routes = tvp5146_routes,
+               .num_inputs = ARRAY_SIZE(dm644xevm_tvp5146_inputs),
+               .inputs = dm644xevm_tvp5146_inputs,
+               .routes = dm644xevm_tvp5146_routes,
                .can_route = 1,
                .ccdc_if_params = {
                        .if_type = VPFE_BT656,
@@ -243,15 +244,15 @@ static struct vpfe_subdev_info vpfe_sub_devs[] = {
                },
                .board_info = {
                        I2C_BOARD_INFO("tvp5146", 0x5d),
-                       .platform_data = &tvp5146_pdata,
+                       .platform_data = &dm644xevm_tvp5146_pdata,
                },
        },
 };
 
-static struct vpfe_config vpfe_cfg = {
-       .num_subdevs = ARRAY_SIZE(vpfe_sub_devs),
+static struct vpfe_config dm644xevm_capture_cfg = {
+       .num_subdevs = ARRAY_SIZE(dm644xevm_vpfe_sub_devs),
        .i2c_adapter_id = 1,
-       .sub_devs = vpfe_sub_devs,
+       .sub_devs = dm644xevm_vpfe_sub_devs,
        .card_name = "DM6446 EVM",
        .ccdc = "DM6446 CCDC",
 };
@@ -612,6 +613,113 @@ static void __init evm_init_i2c(void)
        i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
 }
 
+#define VENC_STD_ALL   (V4L2_STD_NTSC | V4L2_STD_PAL)
+
+/* venc standard timings */
+static struct vpbe_enc_mode_info dm644xevm_enc_std_timing[] = {
+       {
+               .name           = "ntsc",
+               .timings_type   = VPBE_ENC_STD,
+               .timings        = {V4L2_STD_525_60},
+               .interlaced     = 1,
+               .xres           = 720,
+               .yres           = 480,
+               .aspect         = {11, 10},
+               .fps            = {30000, 1001},
+               .left_margin    = 0x79,
+               .upper_margin   = 0x10,
+       },
+       {
+               .name           = "pal",
+               .timings_type   = VPBE_ENC_STD,
+               .timings        = {V4L2_STD_625_50},
+               .interlaced     = 1,
+               .xres           = 720,
+               .yres           = 576,
+               .aspect         = {54, 59},
+               .fps            = {25, 1},
+               .left_margin    = 0x7e,
+               .upper_margin   = 0x16,
+       },
+};
+
+/* venc dv preset timings */
+static struct vpbe_enc_mode_info dm644xevm_enc_preset_timing[] = {
+       {
+               .name           = "480p59_94",
+               .timings_type   = VPBE_ENC_DV_PRESET,
+               .timings        = {V4L2_DV_480P59_94},
+               .interlaced     = 0,
+               .xres           = 720,
+               .yres           = 480,
+               .aspect         = {1, 1},
+               .fps            = {5994, 100},
+               .left_margin    = 0x80,
+               .upper_margin   = 0x20,
+       },
+       {
+               .name           = "576p50",
+               .timings_type   = VPBE_ENC_DV_PRESET,
+               .timings        = {V4L2_DV_576P50},
+               .interlaced     = 0,
+               .xres           = 720,
+               .yres           = 576,
+               .aspect         = {1, 1},
+               .fps            = {50, 1},
+               .left_margin    = 0x7e,
+               .upper_margin   = 0x30,
+       },
+};
+
+/*
+ * The outputs available from VPBE + encoders. Keep the order same
+ * as that of encoders. First those from venc followed by that from
+ * encoders. Index in the output refers to index on a particular encoder.
+ * Driver uses this index to pass it to encoder when it supports more
+ * than one output. Userspace applications use index of the array to
+ * set an output.
+ */
+static struct vpbe_output dm644xevm_vpbe_outputs[] = {
+       {
+               .output         = {
+                       .index          = 0,
+                       .name           = "Composite",
+                       .type           = V4L2_OUTPUT_TYPE_ANALOG,
+                       .std            = VENC_STD_ALL,
+                       .capabilities   = V4L2_OUT_CAP_STD,
+               },
+               .subdev_name    = VPBE_VENC_SUBDEV_NAME,
+               .default_mode   = "ntsc",
+               .num_modes      = ARRAY_SIZE(dm644xevm_enc_std_timing),
+               .modes          = dm644xevm_enc_std_timing,
+       },
+       {
+               .output         = {
+                       .index          = 1,
+                       .name           = "Component",
+                       .type           = V4L2_OUTPUT_TYPE_ANALOG,
+                       .capabilities   = V4L2_OUT_CAP_PRESETS,
+               },
+               .subdev_name    = VPBE_VENC_SUBDEV_NAME,
+               .default_mode   = "480p59_94",
+               .num_modes      = ARRAY_SIZE(dm644xevm_enc_preset_timing),
+               .modes          = dm644xevm_enc_preset_timing,
+       },
+};
+
+static struct vpbe_config dm644xevm_display_cfg = {
+       .module_name    = "dm644x-vpbe-display",
+       .i2c_adapter_id = 1,
+       .osd            = {
+               .module_name    = VPBE_OSD_SUBDEV_NAME,
+       },
+       .venc           = {
+               .module_name    = VPBE_VENC_SUBDEV_NAME,
+       },
+       .num_outputs    = ARRAY_SIZE(dm644xevm_vpbe_outputs),
+       .outputs        = dm644xevm_vpbe_outputs,
+};
+
 static struct platform_device *davinci_evm_devices[] __initdata = {
        &davinci_fb_device,
        &rtc_dev,
@@ -624,8 +732,6 @@ static struct davinci_uart_config uart_config __initdata = {
 static void __init
 davinci_evm_map_io(void)
 {
-       /* setup input configuration for VPFE input devices */
-       dm644x_set_vpfe_config(&vpfe_cfg);
        dm644x_init();
 }
 
@@ -697,6 +803,7 @@ static __init void davinci_evm_init(void)
        evm_init_i2c();
 
        davinci_setup_mmc(0, &dm6446evm_mmc_config);
+       dm644x_init_video(&dm644xevm_capture_cfg, &dm644xevm_display_cfg);
 
        davinci_serial_init(&uart_config);
        dm644x_init_asp(&dm644x_evm_snd_data);
index 872ac69fa0490af84501ac13d73a792bf5f6aea7..d72ab948d6309a26f7b79fdef5208d7e0ca6f88a 100644 (file)
@@ -36,7 +36,6 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/dm646x.h>
 #include <mach/common.h>
 #include <mach/serial.h>
 #include <mach/i2c.h>
@@ -45,6 +44,7 @@
 #include <mach/cdce949.h>
 #include <mach/aemif.h>
 
+#include "davinci.h"
 #include "clock.h"
 
 #define NAND_BLOCK_SIZE                SZ_128K
@@ -410,8 +410,6 @@ static struct davinci_i2c_platform_data i2c_pdata = {
        .bus_delay      = 0 /* usec */,
 };
 
-#define VIDCLKCTL_OFFSET       (DAVINCI_SYSTEM_MODULE_BASE + 0x38)
-#define VSCLKDIS_OFFSET                (DAVINCI_SYSTEM_MODULE_BASE + 0x6c)
 #define VCH2CLK_MASK           (BIT_MASK(10) | BIT_MASK(9) | BIT_MASK(8))
 #define VCH2CLK_SYSCLK8                (BIT(9))
 #define VCH2CLK_AUXCLK         (BIT(9) | BIT(8))
@@ -429,8 +427,6 @@ static struct davinci_i2c_platform_data i2c_pdata = {
 #define TVP5147_CH0            "tvp514x-0"
 #define TVP5147_CH1            "tvp514x-1"
 
-static void __iomem *vpif_vidclkctl_reg;
-static void __iomem *vpif_vsclkdis_reg;
 /* spin lock for updating above registers */
 static spinlock_t vpif_reg_lock;
 
@@ -441,14 +437,14 @@ static int set_vpif_clock(int mux_mode, int hd)
        int val = 0;
        int err = 0;
 
-       if (!vpif_vidclkctl_reg || !vpif_vsclkdis_reg || !cpld_client)
+       if (!cpld_client)
                return -ENXIO;
 
        /* disable the clock */
        spin_lock_irqsave(&vpif_reg_lock, flags);
-       value = __raw_readl(vpif_vsclkdis_reg);
+       value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS));
        value |= (VIDCH3CLK | VIDCH2CLK);
-       __raw_writel(value, vpif_vsclkdis_reg);
+       __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS));
        spin_unlock_irqrestore(&vpif_reg_lock, flags);
 
        val = i2c_smbus_read_byte(cpld_client);
@@ -464,7 +460,7 @@ static int set_vpif_clock(int mux_mode, int hd)
        if (err)
                return err;
 
-       value = __raw_readl(vpif_vidclkctl_reg);
+       value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL));
        value &= ~(VCH2CLK_MASK);
        value &= ~(VCH3CLK_MASK);
 
@@ -473,13 +469,13 @@ static int set_vpif_clock(int mux_mode, int hd)
        else
                value |= (VCH2CLK_AUXCLK | VCH3CLK_AUXCLK);
 
-       __raw_writel(value, vpif_vidclkctl_reg);
+       __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL));
 
        spin_lock_irqsave(&vpif_reg_lock, flags);
-       value = __raw_readl(vpif_vsclkdis_reg);
+       value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS));
        /* enable the clock */
        value &= ~(VIDCH3CLK | VIDCH2CLK);
-       __raw_writel(value, vpif_vsclkdis_reg);
+       __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS));
        spin_unlock_irqrestore(&vpif_reg_lock, flags);
 
        return 0;
@@ -564,7 +560,7 @@ static int setup_vpif_input_channel_mode(int mux_mode)
        int val;
        u32 value;
 
-       if (!vpif_vidclkctl_reg || !cpld_client)
+       if (!cpld_client)
                return -ENXIO;
 
        val = i2c_smbus_read_byte(cpld_client);
@@ -572,7 +568,7 @@ static int setup_vpif_input_channel_mode(int mux_mode)
                return val;
 
        spin_lock_irqsave(&vpif_reg_lock, flags);
-       value = __raw_readl(vpif_vidclkctl_reg);
+       value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL));
        if (mux_mode) {
                val &= VPIF_INPUT_TWO_CHANNEL;
                value |= VIDCH1CLK;
@@ -580,7 +576,7 @@ static int setup_vpif_input_channel_mode(int mux_mode)
                val |= VPIF_INPUT_ONE_CHANNEL;
                value &= ~VIDCH1CLK;
        }
-       __raw_writel(value, vpif_vidclkctl_reg);
+       __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL));
        spin_unlock_irqrestore(&vpif_reg_lock, flags);
 
        err = i2c_smbus_write_byte(cpld_client, val);
@@ -674,12 +670,6 @@ static struct vpif_capture_config dm646x_vpif_capture_cfg = {
 
 static void __init evm_init_video(void)
 {
-       vpif_vidclkctl_reg = ioremap(VIDCLKCTL_OFFSET, 4);
-       vpif_vsclkdis_reg = ioremap(VSCLKDIS_OFFSET, 4);
-       if (!vpif_vidclkctl_reg || !vpif_vsclkdis_reg) {
-               pr_err("Can't map VPIF VIDCLKCTL or VSCLKDIS registers\n");
-               return;
-       }
        spin_lock_init(&vpif_reg_lock);
 
        dm646x_setup_vpif(&dm646x_vpif_display_config,
index 8d34f513d41507b7bf2562739d8f824cc1e40c35..a772bb45570a7e92de29de7aa70a1a2f4250951f 100644 (file)
@@ -30,7 +30,6 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/dm644x.h>
 #include <mach/common.h>
 #include <mach/i2c.h>
 #include <mach/serial.h>
@@ -39,6 +38,8 @@
 #include <mach/mmc.h>
 #include <mach/usb.h>
 
+#include "davinci.h"
+
 #define NEUROS_OSD2_PHY_ID             "davinci_mdio-0:01"
 #define LXT971_PHY_ID                  0x001378e2
 #define LXT971_PHY_MASK                        0xfffffff0
index 31da3c5b2ba37f4934c09fa50bc2aa1cad775631..76e675096104d8edc85c664d776bf341327909a6 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 
-#include <mach/dm644x.h>
 #include <mach/common.h>
 #include <mach/i2c.h>
 #include <mach/serial.h>
 #include <mach/mux.h>
 #include <mach/usb.h>
 
+#include "davinci.h"
+
 #define SFFSDR_PHY_ID          "davinci_mdio-0:01"
 static struct mtd_partition davinci_sffsdr_nandflash_partition[] = {
        /* U-Boot Environment: Block 0
index 5bba7070f2714a87ab4f5c4f5cb902c7b7642622..031048fec9f5e2d175707eea2c4ed0d2edd395a2 100644 (file)
@@ -95,7 +95,7 @@ static int davinci_target(struct cpufreq_policy *policy,
        if (freqs.old == freqs.new)
                return ret;
 
-       dev_dbg(&cpufreq.dev, "transition: %u --> %u\n", freqs.old, freqs.new);
+       dev_dbg(cpufreq.dev, "transition: %u --> %u\n", freqs.old, freqs.new);
 
        ret = cpufreq_frequency_table_target(policy, pdata->freq_table,
                                                freqs.new, relation, &idx);
index 992c4c4101856db5f8f503cdd34aa5fbd5196806..b44dc844e15e0c2ce8c404486c75494749dfec51 100644 (file)
@@ -1026,7 +1026,7 @@ static int da850_round_armrate(struct clk *clk, unsigned long rate)
 }
 #endif
 
-int da850_register_pm(struct platform_device *pdev)
+int __init da850_register_pm(struct platform_device *pdev)
 {
        int ret;
        struct davinci_pm_config *pdata = pdev->dev.platform_data;
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
new file mode 100644 (file)
index 0000000..3e519da
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * This file contains the processor specific definitions
+ * of the TI DM644x, DM355, DM365, and DM646x.
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated
+ * Copyright (c) 2007 Deep Root Systems, LLC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __DAVINCI_H
+#define __DAVINCI_H
+
+#include <linux/clk.h>
+#include <linux/videodev2.h>
+#include <linux/davinci_emac.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+
+#include <mach/asp.h>
+#include <mach/keyscan.h>
+#include <mach/hardware.h>
+
+#include <media/davinci/vpfe_capture.h>
+#include <media/davinci/vpif_types.h>
+#include <media/davinci/vpss.h>
+#include <media/davinci/vpbe_types.h>
+#include <media/davinci/vpbe_venc.h>
+#include <media/davinci/vpbe.h>
+#include <media/davinci/vpbe_osd.h>
+
+#define DAVINCI_SYSTEM_MODULE_BASE     0x01c40000
+#define SYSMOD_VIDCLKCTL               0x38
+#define SYSMOD_VPSS_CLKCTL             0x44
+#define SYSMOD_VDD3P3VPWDN             0x48
+#define SYSMOD_VSCLKDIS                        0x6c
+#define SYSMOD_PUPDCTL1                        0x7c
+
+extern void __iomem *davinci_sysmod_base;
+#define DAVINCI_SYSMOD_VIRT(x) (davinci_sysmod_base + (x))
+void davinci_map_sysmod(void);
+
+/* DM355 base addresses */
+#define DM355_ASYNC_EMIF_CONTROL_BASE  0x01e10000
+#define DM355_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
+
+#define ASP1_TX_EVT_EN 1
+#define ASP1_RX_EVT_EN 2
+
+/* DM365 base addresses */
+#define DM365_ASYNC_EMIF_CONTROL_BASE  0x01d10000
+#define DM365_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
+#define DM365_ASYNC_EMIF_DATA_CE1_BASE 0x04000000
+
+/* DM644x base addresses */
+#define DM644X_ASYNC_EMIF_CONTROL_BASE 0x01e00000
+#define DM644X_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
+#define DM644X_ASYNC_EMIF_DATA_CE1_BASE 0x04000000
+#define DM644X_ASYNC_EMIF_DATA_CE2_BASE 0x06000000
+#define DM644X_ASYNC_EMIF_DATA_CE3_BASE 0x08000000
+
+/* DM646x base addresses */
+#define DM646X_ASYNC_EMIF_CONTROL_BASE 0x20008000
+#define DM646X_ASYNC_EMIF_CS2_SPACE_BASE 0x42000000
+
+/* DM355 function declarations */
+void __init dm355_init(void);
+void dm355_init_spi0(unsigned chipselect_mask,
+               struct spi_board_info *info, unsigned len);
+void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata);
+void dm355_set_vpfe_config(struct vpfe_config *cfg);
+
+/* DM365 function declarations */
+void __init dm365_init(void);
+void __init dm365_init_asp(struct snd_platform_data *pdata);
+void __init dm365_init_vc(struct snd_platform_data *pdata);
+void __init dm365_init_ks(struct davinci_ks_platform_data *pdata);
+void __init dm365_init_rtc(void);
+void dm365_init_spi0(unsigned chipselect_mask,
+                       struct spi_board_info *info, unsigned len);
+void dm365_set_vpfe_config(struct vpfe_config *cfg);
+
+/* DM644x function declarations */
+void __init dm644x_init(void);
+void __init dm644x_init_asp(struct snd_platform_data *pdata);
+int __init dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
+
+/* DM646x function declarations */
+void __init dm646x_init(void);
+void __init dm646x_init_mcasp0(struct snd_platform_data *pdata);
+void __init dm646x_init_mcasp1(struct snd_platform_data *pdata);
+int __init dm646x_init_edma(struct edma_rsv_info *rsv);
+void dm646x_video_init(void);
+void dm646x_setup_vpif(struct vpif_display_config *,
+                      struct vpif_capture_config *);
+#endif /*__DAVINCI_H */
index 50c0156b42628db2402967054430dcce027004bf..d2f9666284a70868dcfe42346657c56fa82f9f9f 100644 (file)
@@ -23,6 +23,7 @@
 #include <mach/mmc.h>
 #include <mach/time.h>
 
+#include "davinci.h"
 #include "clock.h"
 
 #define DAVINCI_I2C_BASE            0x01C21000
 #define DM365_MMCSD0_BASE           0x01D11000
 #define DM365_MMCSD1_BASE           0x01D00000
 
-/* System control register offsets */
-#define DM64XX_VDD3P3V_PWDN    0x48
+void __iomem  *davinci_sysmod_base;
+
+void davinci_map_sysmod(void)
+{
+       davinci_sysmod_base = ioremap_nocache(DAVINCI_SYSTEM_MODULE_BASE,
+                                             0x800);
+       /*
+        * Throw a bug since a lot of board initialization code depends
+        * on system module availability. ioremap() failing this early
+        * need careful looking into anyway.
+        */
+       BUG_ON(!davinci_sysmod_base);
+}
 
 static struct resource i2c_resources[] = {
        {
@@ -212,12 +224,12 @@ void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
                        davinci_cfg_reg(DM355_SD1_DATA2);
                        davinci_cfg_reg(DM355_SD1_DATA3);
                } else if (cpu_is_davinci_dm365()) {
-                       void __iomem *pupdctl1 =
-                               IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE + 0x7c);
-
                        /* Configure pull down control */
-                       __raw_writel((__raw_readl(pupdctl1) & ~0xfc0),
-                                       pupdctl1);
+                       unsigned v;
+
+                       v = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_PUPDCTL1));
+                       __raw_writel(v & ~0xfc0,
+                                       DAVINCI_SYSMOD_VIRT(SYSMOD_PUPDCTL1));
 
                        mmcsd1_resources[0].start = DM365_MMCSD1_BASE;
                        mmcsd1_resources[0].end = DM365_MMCSD1_BASE +
@@ -246,11 +258,9 @@ void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
                        mmcsd0_resources[2].start = IRQ_DM365_SDIOINT0;
                } else if (cpu_is_davinci_dm644x()) {
                        /* REVISIT: should this be in board-init code? */
-                       void __iomem *base =
-                               IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE);
-
                        /* Power-on 3.3V IO cells */
-                       __raw_writel(0, base + DM64XX_VDD3P3V_PWDN);
+                       __raw_writel(0,
+                               DAVINCI_SYSMOD_VIRT(SYSMOD_VDD3P3VPWDN));
                        /*Set up the pull regiter for MMC */
                        davinci_cfg_reg(DM644X_MSTK);
                }
index 19667cfc5de0ec9ed10829a97ba225f7d2143037..fd3d09aa6cde4f6c07a518ed89251b4f9a12ab12 100644 (file)
@@ -18,7 +18,6 @@
 
 #include <asm/mach/map.h>
 
-#include <mach/dm355.h>
 #include <mach/cputype.h>
 #include <mach/edma.h>
 #include <mach/psc.h>
@@ -31,6 +30,7 @@
 #include <mach/spi.h>
 #include <mach/gpio-davinci.h>
 
+#include "davinci.h"
 #include "clock.h"
 #include "mux.h"
 
@@ -871,6 +871,7 @@ void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata)
 void __init dm355_init(void)
 {
        davinci_common_init(&davinci_soc_info_dm355);
+       davinci_map_sysmod();
 }
 
 static int __init dm355_init_devices(void)
index f15b435cc655c79003607cde11e599938cb05129..1a2e953082b3f95220572b2fb67d624ff88ea23d 100644 (file)
@@ -21,7 +21,6 @@
 
 #include <asm/mach/map.h>
 
-#include <mach/dm365.h>
 #include <mach/cputype.h>
 #include <mach/edma.h>
 #include <mach/psc.h>
 #include <mach/spi.h>
 #include <mach/gpio-davinci.h>
 
+#include "davinci.h"
 #include "clock.h"
 #include "mux.h"
 
 #define DM365_REF_FREQ         24000000        /* 24 MHz on the DM365 EVM */
 
+/* Base of key scan register bank */
+#define DM365_KEYSCAN_BASE             0x01c69400
+
+#define DM365_RTC_BASE                 0x01c69000
+
+#define DAVINCI_DM365_VC_BASE          0x01d0c000
+#define DAVINCI_DMA_VC_TX              2
+#define DAVINCI_DMA_VC_RX              3
+
+#define DM365_EMAC_BASE                        0x01d07000
+#define DM365_EMAC_MDIO_BASE           (DM365_EMAC_BASE + 0x4000)
+#define DM365_EMAC_CNTRL_OFFSET                0x0000
+#define DM365_EMAC_CNTRL_MOD_OFFSET    0x3000
+#define DM365_EMAC_CNTRL_RAM_OFFSET    0x1000
+#define DM365_EMAC_CNTRL_RAM_SIZE      0x2000
+
 static struct pll_data pll1_data = {
        .num            = 1,
        .phys_base      = DAVINCI_PLL1_BASE,
@@ -1122,6 +1138,7 @@ void __init dm365_init_rtc(void)
 void __init dm365_init(void)
 {
        davinci_common_init(&davinci_soc_info_dm365);
+       davinci_map_sysmod();
 }
 
 static struct resource dm365_vpss_resources[] = {
index 43a48ee1917bcf0ca1cabd5f15b2e231664ccd4d..c8b866657fcbf1a2d240c3711fce4bba1093c775 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <asm/mach/map.h>
 
-#include <mach/dm644x.h>
 #include <mach/cputype.h>
 #include <mach/edma.h>
 #include <mach/irqs.h>
@@ -27,6 +26,7 @@
 #include <mach/asp.h>
 #include <mach/gpio-davinci.h>
 
+#include "davinci.h"
 #include "clock.h"
 #include "mux.h"
 
  */
 #define DM644X_REF_FREQ                27000000
 
+#define DM644X_EMAC_BASE               0x01c80000
+#define DM644X_EMAC_MDIO_BASE          (DM644X_EMAC_BASE + 0x4000)
+#define DM644X_EMAC_CNTRL_OFFSET       0x0000
+#define DM644X_EMAC_CNTRL_MOD_OFFSET   0x1000
+#define DM644X_EMAC_CNTRL_RAM_OFFSET   0x2000
+#define DM644X_EMAC_CNTRL_RAM_SIZE     0x2000
+
 static struct pll_data pll1_data = {
        .num       = 1,
        .phys_base = DAVINCI_PLL1_BASE,
@@ -587,13 +594,15 @@ static struct platform_device dm644x_asp_device = {
        .resource       = dm644x_asp_resources,
 };
 
+#define DM644X_VPSS_BASE       0x01c73400
+
 static struct resource dm644x_vpss_resources[] = {
        {
                /* VPSS Base address */
                .name           = "vpss",
-               .start          = 0x01c73400,
-               .end            = 0x01c73400 + 0xff,
-               .flags          = IORESOURCE_MEM,
+               .start          = DM644X_VPSS_BASE,
+               .end            = DM644X_VPSS_BASE + 0xff,
+               .flags          = IORESOURCE_MEM,
        },
 };
 
@@ -605,7 +614,7 @@ static struct platform_device dm644x_vpss_device = {
        .resource               = dm644x_vpss_resources,
 };
 
-static struct resource vpfe_resources[] = {
+static struct resource dm644x_vpfe_resources[] = {
        {
                .start          = IRQ_VDINT0,
                .end            = IRQ_VDINT0,
@@ -618,7 +627,7 @@ static struct resource vpfe_resources[] = {
        },
 };
 
-static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
+static u64 dm644x_video_dma_mask = DMA_BIT_MASK(32);
 static struct resource dm644x_ccdc_resource[] = {
        /* CCDC Base address */
        {
@@ -634,27 +643,149 @@ static struct platform_device dm644x_ccdc_dev = {
        .num_resources  = ARRAY_SIZE(dm644x_ccdc_resource),
        .resource       = dm644x_ccdc_resource,
        .dev = {
-               .dma_mask               = &vpfe_capture_dma_mask,
+               .dma_mask               = &dm644x_video_dma_mask,
                .coherent_dma_mask      = DMA_BIT_MASK(32),
        },
 };
 
-static struct platform_device vpfe_capture_dev = {
+static struct platform_device dm644x_vpfe_dev = {
        .name           = CAPTURE_DRV_NAME,
        .id             = -1,
-       .num_resources  = ARRAY_SIZE(vpfe_resources),
-       .resource       = vpfe_resources,
+       .num_resources  = ARRAY_SIZE(dm644x_vpfe_resources),
+       .resource       = dm644x_vpfe_resources,
        .dev = {
-               .dma_mask               = &vpfe_capture_dma_mask,
+               .dma_mask               = &dm644x_video_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+
+#define DM644X_OSD_BASE                0x01c72600
+
+static struct resource dm644x_osd_resources[] = {
+       {
+               .start  = DM644X_OSD_BASE,
+               .end    = DM644X_OSD_BASE + 0x1ff,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct osd_platform_data dm644x_osd_data = {
+       .vpbe_type     = VPBE_VERSION_1,
+};
+
+static struct platform_device dm644x_osd_dev = {
+       .name           = VPBE_OSD_SUBDEV_NAME,
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(dm644x_osd_resources),
+       .resource       = dm644x_osd_resources,
+       .dev            = {
+               .dma_mask               = &dm644x_video_dma_mask,
                .coherent_dma_mask      = DMA_BIT_MASK(32),
+               .platform_data          = &dm644x_osd_data,
        },
 };
 
-void dm644x_set_vpfe_config(struct vpfe_config *cfg)
+#define DM644X_VENC_BASE               0x01c72400
+
+static struct resource dm644x_venc_resources[] = {
+       {
+               .start  = DM644X_VENC_BASE,
+               .end    = DM644X_VENC_BASE + 0x17f,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+#define DM644X_VPSS_MUXSEL_PLL2_MODE          BIT(0)
+#define DM644X_VPSS_MUXSEL_VPBECLK_MODE       BIT(1)
+#define DM644X_VPSS_VENCLKEN                  BIT(3)
+#define DM644X_VPSS_DACCLKEN                  BIT(4)
+
+static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type,
+                                  unsigned int mode)
 {
-       vpfe_capture_dev.dev.platform_data = cfg;
+       int ret = 0;
+       u32 v = DM644X_VPSS_VENCLKEN;
+
+       switch (type) {
+       case VPBE_ENC_STD:
+               v |= DM644X_VPSS_DACCLKEN;
+               writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
+               break;
+       case VPBE_ENC_DV_PRESET:
+               switch (mode) {
+               case V4L2_DV_480P59_94:
+               case V4L2_DV_576P50:
+                       v |= DM644X_VPSS_MUXSEL_PLL2_MODE |
+                            DM644X_VPSS_DACCLKEN;
+                       writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
+                       break;
+               case V4L2_DV_720P60:
+               case V4L2_DV_1080I60:
+               case V4L2_DV_1080P30:
+                       /*
+                        * For HD, use external clock source since
+                        * HD requires higher clock rate
+                        */
+                       v |= DM644X_VPSS_MUXSEL_VPBECLK_MODE;
+                       writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
+                       break;
+               default:
+                       ret = -EINVAL;
+                       break;
+               }
+               break;
+       default:
+               ret  = -EINVAL;
+       }
+
+       return ret;
 }
 
+static struct resource dm644x_v4l2_disp_resources[] = {
+       {
+               .start  = IRQ_VENCINT,
+               .end    = IRQ_VENCINT,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device dm644x_vpbe_display = {
+       .name           = "vpbe-v4l2",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(dm644x_v4l2_disp_resources),
+       .resource       = dm644x_v4l2_disp_resources,
+       .dev            = {
+               .dma_mask               = &dm644x_video_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+
+static struct venc_platform_data dm644x_venc_pdata = {
+       .venc_type      = VPBE_VERSION_1,
+       .setup_clock    = dm644x_venc_setup_clock,
+};
+
+static struct platform_device dm644x_venc_dev = {
+       .name           = VPBE_VENC_SUBDEV_NAME,
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(dm644x_venc_resources),
+       .resource       = dm644x_venc_resources,
+       .dev            = {
+               .dma_mask               = &dm644x_video_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+               .platform_data          = &dm644x_venc_pdata,
+       },
+};
+
+static struct platform_device dm644x_vpbe_dev = {
+       .name           = "vpbe_controller",
+       .id             = -1,
+       .dev            = {
+               .dma_mask               = &dm644x_video_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+
 /*----------------------------------------------------------------------*/
 
 static struct map_desc dm644x_io_desc[] = {
@@ -779,6 +910,35 @@ void __init dm644x_init_asp(struct snd_platform_data *pdata)
 void __init dm644x_init(void)
 {
        davinci_common_init(&davinci_soc_info_dm644x);
+       davinci_map_sysmod();
+}
+
+int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
+                               struct vpbe_config *vpbe_cfg)
+{
+       if (vpfe_cfg || vpbe_cfg)
+               platform_device_register(&dm644x_vpss_device);
+
+       if (vpfe_cfg) {
+               dm644x_vpfe_dev.dev.platform_data = vpfe_cfg;
+               platform_device_register(&dm644x_ccdc_dev);
+               platform_device_register(&dm644x_vpfe_dev);
+               /* Add ccdc clock aliases */
+               clk_add_alias("master", dm644x_ccdc_dev.name,
+                             "vpss_master", NULL);
+               clk_add_alias("slave", dm644x_ccdc_dev.name,
+                             "vpss_slave", NULL);
+       }
+
+       if (vpbe_cfg) {
+               dm644x_vpbe_dev.dev.platform_data = vpbe_cfg;
+               platform_device_register(&dm644x_osd_dev);
+               platform_device_register(&dm644x_venc_dev);
+               platform_device_register(&dm644x_vpbe_dev);
+               platform_device_register(&dm644x_vpbe_display);
+       }
+
+       return 0;
 }
 
 static int __init dm644x_init_devices(void)
@@ -786,9 +946,6 @@ static int __init dm644x_init_devices(void)
        if (!cpu_is_davinci_dm644x())
                return 0;
 
-       /* Add ccdc clock aliases */
-       clk_add_alias("master", dm644x_ccdc_dev.name, "vpss_master", NULL);
-       clk_add_alias("slave", dm644x_ccdc_dev.name, "vpss_slave", NULL);
        platform_device_register(&dm644x_edma_device);
 
        platform_device_register(&dm644x_mdio_device);
@@ -796,10 +953,6 @@ static int __init dm644x_init_devices(void)
        clk_add_alias(NULL, dev_name(&dm644x_mdio_device.dev),
                      NULL, &dm644x_emac_device.dev);
 
-       platform_device_register(&dm644x_vpss_device);
-       platform_device_register(&dm644x_ccdc_dev);
-       platform_device_register(&vpfe_capture_dev);
-
        return 0;
 }
 postcore_initcall(dm644x_init_devices);
index 00f774394b167808a9d9adc2096fa7f94b20f4bf..9eb87c1d1edd1e1deacefc64d240469987e2f0d6 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <asm/mach/map.h>
 
-#include <mach/dm646x.h>
 #include <mach/cputype.h>
 #include <mach/edma.h>
 #include <mach/irqs.h>
 #include <mach/asp.h>
 #include <mach/gpio-davinci.h>
 
+#include "davinci.h"
 #include "clock.h"
 #include "mux.h"
 
 #define DAVINCI_VPIF_BASE       (0x01C12000)
-#define VDD3P3V_PWDN_OFFSET    (0x48)
-#define VSCLKDIS_OFFSET                (0x6C)
 
 #define VDD3P3V_VID_MASK       (BIT_MASK(3) | BIT_MASK(2) | BIT_MASK(1) |\
                                        BIT_MASK(0))
 #define DM646X_REF_FREQ                27000000
 #define DM646X_AUX_FREQ                24000000
 
+#define DM646X_EMAC_BASE               0x01c80000
+#define DM646X_EMAC_MDIO_BASE          (DM646X_EMAC_BASE + 0x4000)
+#define DM646X_EMAC_CNTRL_OFFSET       0x0000
+#define DM646X_EMAC_CNTRL_MOD_OFFSET   0x1000
+#define DM646X_EMAC_CNTRL_RAM_OFFSET   0x2000
+#define DM646X_EMAC_CNTRL_RAM_SIZE     0x2000
+
 static struct pll_data pll1_data = {
        .num       = 1,
        .phys_base = DAVINCI_PLL1_BASE,
@@ -873,15 +878,14 @@ void dm646x_setup_vpif(struct vpif_display_config *display_config,
                       struct vpif_capture_config *capture_config)
 {
        unsigned int value;
-       void __iomem *base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE);
 
-       value = __raw_readl(base + VSCLKDIS_OFFSET);
+       value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS));
        value &= ~VSCLKDIS_MASK;
-       __raw_writel(value, base + VSCLKDIS_OFFSET);
+       __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS));
 
-       value = __raw_readl(base + VDD3P3V_PWDN_OFFSET);
+       value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VDD3P3VPWDN));
        value &= ~VDD3P3V_VID_MASK;
-       __raw_writel(value, base + VDD3P3V_PWDN_OFFSET);
+       __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VDD3P3VPWDN));
 
        davinci_cfg_reg(DM646X_STSOMUX_DISABLE);
        davinci_cfg_reg(DM646X_STSIMUX_DISABLE);
@@ -905,6 +909,7 @@ int __init dm646x_init_edma(struct edma_rsv_info *rsv)
 void __init dm646x_init(void)
 {
        davinci_common_init(&davinci_soc_info_dm646x);
+       davinci_map_sysmod();
 }
 
 static int __init dm646x_init_devices(void)
index da90103a313dc2a7d3b2e7e2f5e99d418cbd02d2..fd33919c95d4ef4a1ae9c7ad3437f52526713730 100644 (file)
@@ -1508,12 +1508,8 @@ static int __init edma_probe(struct platform_device *pdev)
                        goto fail;
                }
 
-               /* Everything lives on transfer controller 1 until otherwise
-                * specified. This way, long transfers on the low priority queue
-                * started by the codec engine will not cause audio defects.
-                */
                for (i = 0; i < edma_cc[j]->num_channels; i++)
-                       map_dmach_queue(j, i, EVENTQ_1);
+                       map_dmach_queue(j, i, info[j]->default_queue);
 
                queue_tc_mapping = info[j]->queue_tc_mapping;
                queue_priority_mapping = info[j]->queue_priority_mapping;
diff --git a/arch/arm/mach-davinci/include/mach/dm355.h b/arch/arm/mach-davinci/include/mach/dm355.h
deleted file mode 100644 (file)
index 36dff4a..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Chip specific defines for DM355 SoC
- *
- * Author: Kevin Hilman, Deep Root Systems, LLC
- *
- * 2007 (c) Deep Root Systems, LLC. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-#ifndef __ASM_ARCH_DM355_H
-#define __ASM_ARCH_DM355_H
-
-#include <mach/hardware.h>
-#include <mach/asp.h>
-#include <media/davinci/vpfe_capture.h>
-
-#define DM355_ASYNC_EMIF_CONTROL_BASE  0x01E10000
-#define DM355_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
-
-#define ASP1_TX_EVT_EN 1
-#define ASP1_RX_EVT_EN 2
-
-struct spi_board_info;
-
-void __init dm355_init(void);
-void dm355_init_spi0(unsigned chipselect_mask,
-               struct spi_board_info *info, unsigned len);
-void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata);
-void dm355_set_vpfe_config(struct vpfe_config *cfg);
-
-#endif /* __ASM_ARCH_DM355_H */
index 2563bf4e93a10e1cc655f0cff4ca7b04f188a5b7..b9bf3d6a4423d1df178b343db065f55237dd4f8a 100644 (file)
@@ -1,52 +1 @@
-/*
- * Copyright (C) 2009 Texas Instruments Incorporated
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-#ifndef __ASM_ARCH_DM365_H
-#define __ASM_ARCH_DM665_H
-
-#include <linux/platform_device.h>
-#include <linux/davinci_emac.h>
-#include <mach/hardware.h>
-#include <mach/asp.h>
-#include <mach/keyscan.h>
-#include <media/davinci/vpfe_capture.h>
-
-#define DM365_EMAC_BASE                        (0x01D07000)
-#define DM365_EMAC_MDIO_BASE           (DM365_EMAC_BASE + 0x4000)
-#define DM365_EMAC_CNTRL_OFFSET                (0x0000)
-#define DM365_EMAC_CNTRL_MOD_OFFSET    (0x3000)
-#define DM365_EMAC_CNTRL_RAM_OFFSET    (0x1000)
-#define DM365_EMAC_CNTRL_RAM_SIZE      (0x2000)
-
-/* Base of key scan register bank */
-#define DM365_KEYSCAN_BASE             (0x01C69400)
-
-#define DM365_RTC_BASE                 (0x01C69000)
-
-#define DAVINCI_DM365_VC_BASE          (0x01D0C000)
-#define DAVINCI_DMA_VC_TX              2
-#define DAVINCI_DMA_VC_RX              3
-
-#define DM365_ASYNC_EMIF_CONTROL_BASE  0x01D10000
-#define DM365_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
-#define DM365_ASYNC_EMIF_DATA_CE1_BASE 0x04000000
-
-void __init dm365_init(void);
-void __init dm365_init_asp(struct snd_platform_data *pdata);
-void __init dm365_init_vc(struct snd_platform_data *pdata);
-void __init dm365_init_ks(struct davinci_ks_platform_data *pdata);
-void __init dm365_init_rtc(void);
-void dm365_init_spi0(unsigned chipselect_mask,
-                       struct spi_board_info *info, unsigned len);
-
-void dm365_set_vpfe_config(struct vpfe_config *cfg);
-#endif /* __ASM_ARCH_DM365_H */
+/* empty, remove once unused */
diff --git a/arch/arm/mach-davinci/include/mach/dm644x.h b/arch/arm/mach-davinci/include/mach/dm644x.h
deleted file mode 100644 (file)
index 5a1b26d..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * This file contains the processor specific definitions
- * of the TI DM644x.
- *
- * Copyright (C) 2008 Texas Instruments.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-#ifndef __ASM_ARCH_DM644X_H
-#define __ASM_ARCH_DM644X_H
-
-#include <linux/davinci_emac.h>
-#include <mach/hardware.h>
-#include <mach/asp.h>
-#include <media/davinci/vpfe_capture.h>
-
-#define DM644X_EMAC_BASE               (0x01C80000)
-#define DM644X_EMAC_MDIO_BASE          (DM644X_EMAC_BASE + 0x4000)
-#define DM644X_EMAC_CNTRL_OFFSET       (0x0000)
-#define DM644X_EMAC_CNTRL_MOD_OFFSET   (0x1000)
-#define DM644X_EMAC_CNTRL_RAM_OFFSET   (0x2000)
-#define DM644X_EMAC_CNTRL_RAM_SIZE     (0x2000)
-
-#define DM644X_ASYNC_EMIF_CONTROL_BASE 0x01E00000
-#define DM644X_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
-#define DM644X_ASYNC_EMIF_DATA_CE1_BASE 0x04000000
-#define DM644X_ASYNC_EMIF_DATA_CE2_BASE 0x06000000
-#define DM644X_ASYNC_EMIF_DATA_CE3_BASE 0x08000000
-
-void __init dm644x_init(void);
-void __init dm644x_init_asp(struct snd_platform_data *pdata);
-void dm644x_set_vpfe_config(struct vpfe_config *cfg);
-
-#endif /* __ASM_ARCH_DM644X_H */
index a8ee6c9f0bb01d15c0a5c8b32e16246522475fc9..b9bf3d6a4423d1df178b343db065f55237dd4f8a 100644 (file)
@@ -1,41 +1 @@
-/*
- * Chip specific defines for DM646x SoC
- *
- * Author: Kevin Hilman, Deep Root Systems, LLC
- *
- * 2007 (c) Deep Root Systems, LLC. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-#ifndef __ASM_ARCH_DM646X_H
-#define __ASM_ARCH_DM646X_H
-
-#include <mach/hardware.h>
-#include <mach/asp.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <linux/davinci_emac.h>
-#include <media/davinci/vpif_types.h>
-
-#define DM646X_EMAC_BASE               (0x01C80000)
-#define DM646X_EMAC_MDIO_BASE          (DM646X_EMAC_BASE + 0x4000)
-#define DM646X_EMAC_CNTRL_OFFSET       (0x0000)
-#define DM646X_EMAC_CNTRL_MOD_OFFSET   (0x1000)
-#define DM646X_EMAC_CNTRL_RAM_OFFSET   (0x2000)
-#define DM646X_EMAC_CNTRL_RAM_SIZE     (0x2000)
-
-#define DM646X_ASYNC_EMIF_CONTROL_BASE 0x20008000
-#define DM646X_ASYNC_EMIF_CS2_SPACE_BASE 0x42000000
-
-void __init dm646x_init(void);
-void __init dm646x_init_mcasp0(struct snd_platform_data *pdata);
-void __init dm646x_init_mcasp1(struct snd_platform_data *pdata);
-int __init dm646x_init_edma(struct edma_rsv_info *rsv);
-
-void dm646x_video_init(void);
-
-void dm646x_setup_vpif(struct vpif_display_config *,
-                      struct vpif_capture_config *);
-
-#endif /* __ASM_ARCH_DM646X_H */
+/* empty, remove once unused */
index 20c77f29bf0f3a74c36ca48eb16085d0e87abacb..7e84c906ceff4046aef96e484d9bc0b5dd895711 100644 (file)
@@ -250,6 +250,11 @@ struct edma_soc_info {
        unsigned        n_slot;
        unsigned        n_tc;
        unsigned        n_cc;
+       /*
+        * Default queue is expected to be a low-priority queue.
+        * This way, long transfers on the default queue started
+        * by the codec engine will not cause audio defects.
+        */
        enum dma_event_q        default_queue;
 
        /* Resource reservation for other cores */
index 414e0b93e741f5a8bd1ce8c76b88ebf5ca8a6bcd..0209b1fc22a1dad995e4fdefc2221b7d6ca32561 100644 (file)
@@ -19,8 +19,6 @@
  * and the chip/board init code should then explicitly include
  * <chipname>.h
  */
-#define DAVINCI_SYSTEM_MODULE_BASE        0x01C40000
-
 /*
  * I/O mapping
  */
index 804c9122b7b3626e76eadcd3c950429612e87969..e400d75d11aee5eb0e575bf1268e99a79259387f 100644 (file)
 
 #include <asm/mach/time.h>
 
-#define IRQ_MASK               0xfe000000      /* read */
-#define IRQ_MSET               0xfe000000      /* write */
-#define IRQ_STAT               0xff000000      /* read */
-#define IRQ_MCLR               0xff000000      /* write */
+#include "core.h"
 
 static void ebsa110_mask_irq(struct irq_data *d)
 {
@@ -79,22 +76,22 @@ static struct map_desc ebsa110_io_desc[] __initdata = {
        {       /* IRQ_STAT/IRQ_MCLR */
                .virtual        = IRQ_STAT,
                .pfn            = __phys_to_pfn(TRICK4_PHYS),
-               .length         = PGDIR_SIZE,
+               .length         = TRICK4_SIZE,
                .type           = MT_DEVICE
        }, {    /* IRQ_MASK/IRQ_MSET */
                .virtual        = IRQ_MASK,
                .pfn            = __phys_to_pfn(TRICK3_PHYS),
-               .length         = PGDIR_SIZE,
+               .length         = TRICK3_SIZE,
                .type           = MT_DEVICE
        }, {    /* SOFT_BASE */
                .virtual        = SOFT_BASE,
                .pfn            = __phys_to_pfn(TRICK1_PHYS),
-               .length         = PGDIR_SIZE,
+               .length         = TRICK1_SIZE,
                .type           = MT_DEVICE
        }, {    /* PIT_BASE */
                .virtual        = PIT_BASE,
                .pfn            = __phys_to_pfn(TRICK0_PHYS),
-               .length         = PGDIR_SIZE,
+               .length         = TRICK0_SIZE,
                .type           = MT_DEVICE
        },
 
diff --git a/arch/arm/mach-ebsa110/core.h b/arch/arm/mach-ebsa110/core.h
new file mode 100644 (file)
index 0000000..c93c9e4
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  Copyright (C) 1996-2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains the core hardware definitions of the EBSA-110.
+ */
+#ifndef CORE_H
+#define CORE_H
+
+/* Physical addresses/sizes */
+#define ISAMEM_PHYS            0xe0000000
+#define ISAMEM_SIZE            0x10000000
+
+#define ISAIO_PHYS             0xf0000000
+#define ISAIO_SIZE             PGDIR_SIZE
+
+#define TRICK0_PHYS            0xf2000000
+#define TRICK0_SIZE            PGDIR_SIZE
+#define TRICK1_PHYS            0xf2400000
+#define TRICK1_SIZE            PGDIR_SIZE
+#define TRICK2_PHYS            0xf2800000
+#define TRICK3_PHYS            0xf2c00000
+#define TRICK3_SIZE            PGDIR_SIZE
+#define TRICK4_PHYS            0xf3000000
+#define TRICK4_SIZE            PGDIR_SIZE
+#define TRICK5_PHYS            0xf3400000
+#define TRICK6_PHYS            0xf3800000
+#define TRICK7_PHYS            0xf3c00000
+
+/* Virtual addresses */
+#define PIT_BASE               0xfc000000      /* trick 0 */
+#define SOFT_BASE              0xfd000000      /* trick 1 */
+#define IRQ_MASK               0xfe000000      /* trick 3 - read */
+#define IRQ_MSET               0xfe000000      /* trick 3 - write */
+#define IRQ_STAT               0xff000000      /* trick 4 - read */
+#define IRQ_MCLR               0xff000000      /* trick 4 - write */
+
+#endif
index 4b2fb7743909793e125c7836e84bd215488f04a0..f4e5407bd004ae960965bdd73e332500b1fe1f6f 100644 (file)
 #ifndef __ASM_ARCH_HARDWARE_H
 #define __ASM_ARCH_HARDWARE_H
 
-/*
- * The EBSA110 has a weird "ISA IO" region:
- *
- * Region 0 (addr = 0xf0000000 + io << 2)
- * --------------------------------------------------------
- * Physical region     IO region
- * f0000fe0 - f0000ffc 3f8 - 3ff  ttyS0
- * f0000e60 - f0000e64 398 - 399
- * f0000de0 - f0000dfc 378 - 37f  lp0
- * f0000be0 - f0000bfc 2f8 - 2ff  ttyS1
- *
- * Region 1 (addr = 0xf0000000 + (io & ~1) << 1 + (io & 1))
- * --------------------------------------------------------
- * Physical region     IO region
- * f00014f1             a79        pnp write data
- * f00007c0 - f00007c1 3e0 - 3e1  pcmcia
- * f00004f1            279        pnp address
- * f0000440 - f000046c  220 - 236  eth0
- * f0000405            203        pnp read data
- */
-
-#define ISAMEM_PHYS            0xe0000000
-#define ISAMEM_SIZE            0x10000000
-
-#define ISAIO_PHYS             0xf0000000
-#define ISAIO_SIZE             PGDIR_SIZE
-
-#define TRICK0_PHYS            0xf2000000
-#define TRICK1_PHYS            0xf2400000
-#define TRICK2_PHYS            0xf2800000
-#define TRICK3_PHYS            0xf2c00000
-#define TRICK4_PHYS            0xf3000000
-#define TRICK5_PHYS            0xf3400000
-#define TRICK6_PHYS            0xf3800000
-#define TRICK7_PHYS            0xf3c00000
-
 #define ISAMEM_BASE            0xe0000000
 #define ISAIO_BASE             0xf0000000
 
-#define PIT_BASE               0xfc000000
-#define SOFT_BASE              0xfd000000
-
 /*
  * RAM definitions
  */
index c52e3047a7eb7ccc32a4094c1a1de8498ad37cbd..756cc377a73dcd8d4ad33ecc8f6e7ed30ac825dd 100644 (file)
@@ -177,6 +177,26 @@ void writesl(void __iomem *addr, const void *data, int len)
 }
 EXPORT_SYMBOL(writesl);
 
+/*
+ * The EBSA110 has a weird "ISA IO" region:
+ *
+ * Region 0 (addr = 0xf0000000 + io << 2)
+ * --------------------------------------------------------
+ * Physical region     IO region
+ * f0000fe0 - f0000ffc 3f8 - 3ff  ttyS0
+ * f0000e60 - f0000e64 398 - 399
+ * f0000de0 - f0000dfc 378 - 37f  lp0
+ * f0000be0 - f0000bfc 2f8 - 2ff  ttyS1
+ *
+ * Region 1 (addr = 0xf0000000 + (io & ~1) << 1 + (io & 1))
+ * --------------------------------------------------------
+ * Physical region     IO region
+ * f00014f1             a79        pnp write data
+ * f00007c0 - f00007c1 3e0 - 3e1  pcmcia
+ * f00004f1            279        pnp address
+ * f0000440 - f000046c  220 - 236  eth0
+ * f0000405            203        pnp read data
+ */
 #define SUPERIO_PORT(p) \
        (((p) >> 3) == (0x3f8 >> 3) || \
         ((p) >> 3) == (0x2f8 >> 3) || \
index 6a6ea57c2a4e9a79700b45c45d3893e723c20c3a..d43121a30aa783065e52dd7f87a5f09cbcc277a9 100644 (file)
@@ -20,6 +20,8 @@
 #include <asm/system.h>
 #include <asm/mach-types.h>
 
+#include "core.h"
+
 static spinlock_t leds_lock;
 
 static void ebsa110_leds_event(led_event_t ledevt)
index 574209d9e2460c7a75696ec8665faba5d819bfc9..0dc51f9462ded5223839c8172d887da5b01fb063 100644 (file)
@@ -8,6 +8,9 @@ obj-                    :=
 
 obj-$(CONFIG_EP93XX_DMA)       += dma.o
 
+obj-$(CONFIG_CRUNCH)           += crunch.o crunch-bits.o
+AFLAGS_crunch-bits.o           := -Wa,-mcpu=ep9312
+
 obj-$(CONFIG_MACH_ADSSPHERE)   += adssphere.o
 obj-$(CONFIG_MACH_EDB93XX)     += edb93xx.o
 obj-$(CONFIG_MACH_GESBC9312)   += gesbc9312.o
index 681e939407d4bc907dfb99f528992c12bb462eec..2d45947a3034b260bede63835a0db4606154c1cd 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+#include "soc.h"
 
 static struct ep93xx_eth_data __initdata adssphere_eth_data = {
        .phy_id         = 1,
index ca4de71050973184945297febfc7b2111103f76c..c95dbce2468e62010c8df64e3be4751869bd7abc 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <asm/div64.h>
 
+#include "soc.h"
 
 struct clk {
        struct clk      *parent;
index c6a6ae89b8b91a5f1a08c516be91057b439c00a5..8d2589588713d6c0b717c278660c212cd9f6e17b 100644 (file)
@@ -46,6 +46,7 @@
 
 #include <asm/hardware/vic.h>
 
+#include "soc.h"
 
 /*************************************************************************
  * Static I/O mappings that are needed for all EP93xx platforms
@@ -204,7 +205,6 @@ void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg)
 
        spin_unlock_irqrestore(&syscon_swlock, flags);
 }
-EXPORT_SYMBOL(ep93xx_syscon_swlocked_write);
 
 void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits)
 {
@@ -221,7 +221,6 @@ void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits)
 
        spin_unlock_irqrestore(&syscon_swlock, flags);
 }
-EXPORT_SYMBOL(ep93xx_devcfg_set_clear);
 
 /**
  * ep93xx_chip_revision() - returns the EP93xx chip revision
@@ -648,9 +647,19 @@ static struct platform_device ep93xx_fb_device = {
        .resource               = ep93xx_fb_resource,
 };
 
+/* The backlight use a single register in the framebuffer's register space */
+#define EP93XX_RASTER_REG_BRIGHTNESS 0x20
+
+static struct resource ep93xx_bl_resources[] = {
+       DEFINE_RES_MEM(EP93XX_RASTER_PHYS_BASE +
+                      EP93XX_RASTER_REG_BRIGHTNESS, 0x04),
+};
+
 static struct platform_device ep93xx_bl_device = {
        .name           = "ep93xx-bl",
        .id             = -1,
+       .num_resources  = ARRAY_SIZE(ep93xx_bl_resources),
+       .resource       = ep93xx_bl_resources,
 };
 
 /**
@@ -864,6 +873,13 @@ void __init ep93xx_init_devices(void)
        /* Disallow access to MaverickCrunch initially */
        ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA);
 
+       /* Default all ports to GPIO */
+       ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS |
+                              EP93XX_SYSCON_DEVCFG_GONK |
+                              EP93XX_SYSCON_DEVCFG_EONIDE |
+                              EP93XX_SYSCON_DEVCFG_GONIDE |
+                              EP93XX_SYSCON_DEVCFG_HONIDE);
+
        /* Get the GPIO working early, other devices need it */
        platform_device_register(&ep93xx_gpio_device);
 
diff --git a/arch/arm/mach-ep93xx/crunch-bits.S b/arch/arm/mach-ep93xx/crunch-bits.S
new file mode 100644 (file)
index 0000000..0ec9bb4
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ * arch/arm/kernel/crunch-bits.S
+ * Cirrus MaverickCrunch context switching and handling
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * Shamelessly stolen from the iWMMXt code by Nicolas Pitre, which is
+ * Copyright (c) 2003-2004, MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
+#include <mach/ep93xx-regs.h>
+
+/*
+ * We can't use hex constants here due to a bug in gas.
+ */
+#define CRUNCH_MVDX0           0
+#define CRUNCH_MVDX1           8
+#define CRUNCH_MVDX2           16
+#define CRUNCH_MVDX3           24
+#define CRUNCH_MVDX4           32
+#define CRUNCH_MVDX5           40
+#define CRUNCH_MVDX6           48
+#define CRUNCH_MVDX7           56
+#define CRUNCH_MVDX8           64
+#define CRUNCH_MVDX9           72
+#define CRUNCH_MVDX10          80
+#define CRUNCH_MVDX11          88
+#define CRUNCH_MVDX12          96
+#define CRUNCH_MVDX13          104
+#define CRUNCH_MVDX14          112
+#define CRUNCH_MVDX15          120
+#define CRUNCH_MVAX0L          128
+#define CRUNCH_MVAX0M          132
+#define CRUNCH_MVAX0H          136
+#define CRUNCH_MVAX1L          140
+#define CRUNCH_MVAX1M          144
+#define CRUNCH_MVAX1H          148
+#define CRUNCH_MVAX2L          152
+#define CRUNCH_MVAX2M          156
+#define CRUNCH_MVAX2H          160
+#define CRUNCH_MVAX3L          164
+#define CRUNCH_MVAX3M          168
+#define CRUNCH_MVAX3H          172
+#define CRUNCH_DSPSC           176
+
+#define CRUNCH_SIZE            184
+
+       .text
+
+/*
+ * Lazy switching of crunch coprocessor context
+ *
+ * r10 = struct thread_info pointer
+ * r9  = ret_from_exception
+ * lr  = undefined instr exit
+ *
+ * called from prefetch exception handler with interrupts disabled
+ */
+ENTRY(crunch_task_enable)
+       ldr     r8, =(EP93XX_APB_VIRT_BASE + 0x00130000)        @ syscon addr
+
+       ldr     r1, [r8, #0x80]
+       tst     r1, #0x00800000                 @ access to crunch enabled?
+       movne   pc, lr                          @ if so no business here
+       mov     r3, #0xaa                       @ unlock syscon swlock
+       str     r3, [r8, #0xc0]
+       orr     r1, r1, #0x00800000             @ enable access to crunch
+       str     r1, [r8, #0x80]
+
+       ldr     r3, =crunch_owner
+       add     r0, r10, #TI_CRUNCH_STATE       @ get task crunch save area
+       ldr     r2, [sp, #60]                   @ current task pc value
+       ldr     r1, [r3]                        @ get current crunch owner
+       str     r0, [r3]                        @ this task now owns crunch
+       sub     r2, r2, #4                      @ adjust pc back
+       str     r2, [sp, #60]
+
+       ldr     r2, [r8, #0x80]
+       mov     r2, r2                          @ flush out enable (@@@)
+
+       teq     r1, #0                          @ test for last ownership
+       mov     lr, r9                          @ normal exit from exception
+       beq     crunch_load                     @ no owner, skip save
+
+crunch_save:
+       cfstr64         mvdx0, [r1, #CRUNCH_MVDX0]      @ save 64b registers
+       cfstr64         mvdx1, [r1, #CRUNCH_MVDX1]
+       cfstr64         mvdx2, [r1, #CRUNCH_MVDX2]
+       cfstr64         mvdx3, [r1, #CRUNCH_MVDX3]
+       cfstr64         mvdx4, [r1, #CRUNCH_MVDX4]
+       cfstr64         mvdx5, [r1, #CRUNCH_MVDX5]
+       cfstr64         mvdx6, [r1, #CRUNCH_MVDX6]
+       cfstr64         mvdx7, [r1, #CRUNCH_MVDX7]
+       cfstr64         mvdx8, [r1, #CRUNCH_MVDX8]
+       cfstr64         mvdx9, [r1, #CRUNCH_MVDX9]
+       cfstr64         mvdx10, [r1, #CRUNCH_MVDX10]
+       cfstr64         mvdx11, [r1, #CRUNCH_MVDX11]
+       cfstr64         mvdx12, [r1, #CRUNCH_MVDX12]
+       cfstr64         mvdx13, [r1, #CRUNCH_MVDX13]
+       cfstr64         mvdx14, [r1, #CRUNCH_MVDX14]
+       cfstr64         mvdx15, [r1, #CRUNCH_MVDX15]
+
+#ifdef __ARMEB__
+#error fix me for ARMEB
+#endif
+
+       cfmv32al        mvfx0, mvax0                    @ save 72b accumulators
+       cfstr32         mvfx0, [r1, #CRUNCH_MVAX0L]
+       cfmv32am        mvfx0, mvax0
+       cfstr32         mvfx0, [r1, #CRUNCH_MVAX0M]
+       cfmv32ah        mvfx0, mvax0
+       cfstr32         mvfx0, [r1, #CRUNCH_MVAX0H]
+       cfmv32al        mvfx0, mvax1
+       cfstr32         mvfx0, [r1, #CRUNCH_MVAX1L]
+       cfmv32am        mvfx0, mvax1
+       cfstr32         mvfx0, [r1, #CRUNCH_MVAX1M]
+       cfmv32ah        mvfx0, mvax1
+       cfstr32         mvfx0, [r1, #CRUNCH_MVAX1H]
+       cfmv32al        mvfx0, mvax2
+       cfstr32         mvfx0, [r1, #CRUNCH_MVAX2L]
+       cfmv32am        mvfx0, mvax2
+       cfstr32         mvfx0, [r1, #CRUNCH_MVAX2M]
+       cfmv32ah        mvfx0, mvax2
+       cfstr32         mvfx0, [r1, #CRUNCH_MVAX2H]
+       cfmv32al        mvfx0, mvax3
+       cfstr32         mvfx0, [r1, #CRUNCH_MVAX3L]
+       cfmv32am        mvfx0, mvax3
+       cfstr32         mvfx0, [r1, #CRUNCH_MVAX3M]
+       cfmv32ah        mvfx0, mvax3
+       cfstr32         mvfx0, [r1, #CRUNCH_MVAX3H]
+
+       cfmv32sc        mvdx0, dspsc                    @ save status word
+       cfstr64         mvdx0, [r1, #CRUNCH_DSPSC]
+
+       teq             r0, #0                          @ anything to load?
+       cfldr64eq       mvdx0, [r1, #CRUNCH_MVDX0]      @ mvdx0 was clobbered
+       moveq           pc, lr
+
+crunch_load:
+       cfldr64         mvdx0, [r0, #CRUNCH_DSPSC]      @ load status word
+       cfmvsc32        dspsc, mvdx0
+
+       cfldr32         mvfx0, [r0, #CRUNCH_MVAX0L]     @ load 72b accumulators
+       cfmval32        mvax0, mvfx0
+       cfldr32         mvfx0, [r0, #CRUNCH_MVAX0M]
+       cfmvam32        mvax0, mvfx0
+       cfldr32         mvfx0, [r0, #CRUNCH_MVAX0H]
+       cfmvah32        mvax0, mvfx0
+       cfldr32         mvfx0, [r0, #CRUNCH_MVAX1L]
+       cfmval32        mvax1, mvfx0
+       cfldr32         mvfx0, [r0, #CRUNCH_MVAX1M]
+       cfmvam32        mvax1, mvfx0
+       cfldr32         mvfx0, [r0, #CRUNCH_MVAX1H]
+       cfmvah32        mvax1, mvfx0
+       cfldr32         mvfx0, [r0, #CRUNCH_MVAX2L]
+       cfmval32        mvax2, mvfx0
+       cfldr32         mvfx0, [r0, #CRUNCH_MVAX2M]
+       cfmvam32        mvax2, mvfx0
+       cfldr32         mvfx0, [r0, #CRUNCH_MVAX2H]
+       cfmvah32        mvax2, mvfx0
+       cfldr32         mvfx0, [r0, #CRUNCH_MVAX3L]
+       cfmval32        mvax3, mvfx0
+       cfldr32         mvfx0, [r0, #CRUNCH_MVAX3M]
+       cfmvam32        mvax3, mvfx0
+       cfldr32         mvfx0, [r0, #CRUNCH_MVAX3H]
+       cfmvah32        mvax3, mvfx0
+
+       cfldr64         mvdx0, [r0, #CRUNCH_MVDX0]      @ load 64b registers
+       cfldr64         mvdx1, [r0, #CRUNCH_MVDX1]
+       cfldr64         mvdx2, [r0, #CRUNCH_MVDX2]
+       cfldr64         mvdx3, [r0, #CRUNCH_MVDX3]
+       cfldr64         mvdx4, [r0, #CRUNCH_MVDX4]
+       cfldr64         mvdx5, [r0, #CRUNCH_MVDX5]
+       cfldr64         mvdx6, [r0, #CRUNCH_MVDX6]
+       cfldr64         mvdx7, [r0, #CRUNCH_MVDX7]
+       cfldr64         mvdx8, [r0, #CRUNCH_MVDX8]
+       cfldr64         mvdx9, [r0, #CRUNCH_MVDX9]
+       cfldr64         mvdx10, [r0, #CRUNCH_MVDX10]
+       cfldr64         mvdx11, [r0, #CRUNCH_MVDX11]
+       cfldr64         mvdx12, [r0, #CRUNCH_MVDX12]
+       cfldr64         mvdx13, [r0, #CRUNCH_MVDX13]
+       cfldr64         mvdx14, [r0, #CRUNCH_MVDX14]
+       cfldr64         mvdx15, [r0, #CRUNCH_MVDX15]
+
+       mov     pc, lr
+
+/*
+ * Back up crunch regs to save area and disable access to them
+ * (mainly for gdb or sleep mode usage)
+ *
+ * r0 = struct thread_info pointer of target task or NULL for any
+ */
+ENTRY(crunch_task_disable)
+       stmfd   sp!, {r4, r5, lr}
+
+       mrs     ip, cpsr
+       orr     r2, ip, #PSR_I_BIT              @ disable interrupts
+       msr     cpsr_c, r2
+
+       ldr     r4, =(EP93XX_APB_VIRT_BASE + 0x00130000)        @ syscon addr
+
+       ldr     r3, =crunch_owner
+       add     r2, r0, #TI_CRUNCH_STATE        @ get task crunch save area
+       ldr     r1, [r3]                        @ get current crunch owner
+       teq     r1, #0                          @ any current owner?
+       beq     1f                              @ no: quit
+       teq     r0, #0                          @ any owner?
+       teqne   r1, r2                          @ or specified one?
+       bne     1f                              @ no: quit
+
+       ldr     r5, [r4, #0x80]                 @ enable access to crunch
+       mov     r2, #0xaa
+       str     r2, [r4, #0xc0]
+       orr     r5, r5, #0x00800000
+       str     r5, [r4, #0x80]
+
+       mov     r0, #0                          @ nothing to load
+       str     r0, [r3]                        @ no more current owner
+       ldr     r2, [r4, #0x80]                 @ flush out enable (@@@)
+       mov     r2, r2
+       bl      crunch_save
+
+       mov     r2, #0xaa                       @ disable access to crunch
+       str     r2, [r4, #0xc0]
+       bic     r5, r5, #0x00800000
+       str     r5, [r4, #0x80]
+       ldr     r5, [r4, #0x80]                 @ flush out enable (@@@)
+       mov     r5, r5
+
+1:     msr     cpsr_c, ip                      @ restore interrupt mode
+       ldmfd   sp!, {r4, r5, pc}
+
+/*
+ * Copy crunch state to given memory address
+ *
+ * r0 = struct thread_info pointer of target task
+ * r1 = memory address where to store crunch state
+ *
+ * this is called mainly in the creation of signal stack frames
+ */
+ENTRY(crunch_task_copy)
+       mrs     ip, cpsr
+       orr     r2, ip, #PSR_I_BIT              @ disable interrupts
+       msr     cpsr_c, r2
+
+       ldr     r3, =crunch_owner
+       add     r2, r0, #TI_CRUNCH_STATE        @ get task crunch save area
+       ldr     r3, [r3]                        @ get current crunch owner
+       teq     r2, r3                          @ does this task own it...
+       beq     1f
+
+       @ current crunch values are in the task save area
+       msr     cpsr_c, ip                      @ restore interrupt mode
+       mov     r0, r1
+       mov     r1, r2
+       mov     r2, #CRUNCH_SIZE
+       b       memcpy
+
+1:     @ this task owns crunch regs -- grab a copy from there
+       mov     r0, #0                          @ nothing to load
+       mov     r3, lr                          @ preserve return address
+       bl      crunch_save
+       msr     cpsr_c, ip                      @ restore interrupt mode
+       mov     pc, r3
+
+/*
+ * Restore crunch state from given memory address
+ *
+ * r0 = struct thread_info pointer of target task
+ * r1 = memory address where to get crunch state from
+ *
+ * this is used to restore crunch state when unwinding a signal stack frame
+ */
+ENTRY(crunch_task_restore)
+       mrs     ip, cpsr
+       orr     r2, ip, #PSR_I_BIT              @ disable interrupts
+       msr     cpsr_c, r2
+
+       ldr     r3, =crunch_owner
+       add     r2, r0, #TI_CRUNCH_STATE        @ get task crunch save area
+       ldr     r3, [r3]                        @ get current crunch owner
+       teq     r2, r3                          @ does this task own it...
+       beq     1f
+
+       @ this task doesn't own crunch regs -- use its save area
+       msr     cpsr_c, ip                      @ restore interrupt mode
+       mov     r0, r2
+       mov     r2, #CRUNCH_SIZE
+       b       memcpy
+
+1:     @ this task owns crunch regs -- load them directly
+       mov     r0, r1
+       mov     r1, #0                          @ nothing to save
+       mov     r3, lr                          @ preserve return address
+       bl      crunch_load
+       msr     cpsr_c, ip                      @ restore interrupt mode
+       mov     pc, r3
diff --git a/arch/arm/mach-ep93xx/crunch.c b/arch/arm/mach-ep93xx/crunch.c
new file mode 100644 (file)
index 0000000..74753e2
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * arch/arm/kernel/crunch.c
+ * Cirrus MaverickCrunch context switching and handling
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/thread_notify.h>
+
+#include "soc.h"
+
+struct crunch_state *crunch_owner;
+
+void crunch_task_release(struct thread_info *thread)
+{
+       local_irq_disable();
+       if (crunch_owner == &thread->crunchstate)
+               crunch_owner = NULL;
+       local_irq_enable();
+}
+
+static int crunch_enabled(u32 devcfg)
+{
+       return !!(devcfg & EP93XX_SYSCON_DEVCFG_CPENA);
+}
+
+static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t)
+{
+       struct thread_info *thread = (struct thread_info *)t;
+       struct crunch_state *crunch_state;
+       u32 devcfg;
+
+       crunch_state = &thread->crunchstate;
+
+       switch (cmd) {
+       case THREAD_NOTIFY_FLUSH:
+               memset(crunch_state, 0, sizeof(*crunch_state));
+
+               /*
+                * FALLTHROUGH: Ensure we don't try to overwrite our newly
+                * initialised state information on the first fault.
+                */
+
+       case THREAD_NOTIFY_EXIT:
+               crunch_task_release(thread);
+               break;
+
+       case THREAD_NOTIFY_SWITCH:
+               devcfg = __raw_readl(EP93XX_SYSCON_DEVCFG);
+               if (crunch_enabled(devcfg) || crunch_owner == crunch_state) {
+                       /*
+                        * We don't use ep93xx_syscon_swlocked_write() here
+                        * because we are on the context switch path and
+                        * preemption is already disabled.
+                        */
+                       devcfg ^= EP93XX_SYSCON_DEVCFG_CPENA;
+                       __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
+                       __raw_writel(devcfg, EP93XX_SYSCON_DEVCFG);
+               }
+               break;
+       }
+
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block crunch_notifier_block = {
+       .notifier_call  = crunch_do,
+};
+
+static int __init crunch_init(void)
+{
+       thread_register_notifier(&crunch_notifier_block);
+       elf_hwcap |= HWCAP_CRUNCH;
+
+       return 0;
+}
+
+late_initcall(crunch_init);
index 5a2570881255ef7851ee73c8c9c06ce60b4090b7..16976d7bdc8a18bbe62694d01070bcea29f8c01a 100644 (file)
@@ -28,6 +28,8 @@
 #include <mach/dma.h>
 #include <mach/hardware.h>
 
+#include "soc.h"
+
 #define DMA_CHANNEL(_name, _base, _irq) \
        { .name = (_name), .base = (_base), .irq = (_irq) }
 
index d115653edca3e3cd9632fcfb14ebb616dad7a985..da9047d726f07dc1e064409df07a46c3bd4eb8b5 100644 (file)
@@ -43,6 +43,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+#include "soc.h"
 
 static void __init edb93xx_register_flash(void)
 {
index af46970dc58e78c2a484c4db0351c1eb8f94ab4b..fcdffbe49dcc8b17423b39e84bfa44a74f8826e0 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+#include "soc.h"
 
 static struct ep93xx_eth_data __initdata gesbc9312_eth_data = {
        .phy_id         = 1,
index e9271a7e26743ac7320794f584ae88837fd6f148..c64d74246602450a5116179f07e347ba004e1826 100644 (file)
@@ -5,40 +5,6 @@
 #ifndef __ASM_ARCH_EP93XX_REGS_H
 #define __ASM_ARCH_EP93XX_REGS_H
 
-/*
- * EP93xx Physical Memory Map:
- *
- * The ASDO pin is sampled at system reset to select a synchronous or
- * asynchronous boot configuration.  When ASDO is "1" (i.e. pulled-up)
- * the synchronous boot mode is selected.  When ASDO is "0" (i.e
- * pulled-down) the asynchronous boot mode is selected.
- *
- * In synchronous boot mode nSDCE3 is decoded starting at physical address
- * 0x00000000 and nCS0 is decoded starting at 0xf0000000.  For asynchronous
- * boot mode they are swapped with nCS0 decoded at 0x00000000 ann nSDCE3
- * decoded at 0xf0000000.
- *
- * There is known errata for the EP93xx dealing with External Memory
- * Configurations.  Please refer to "AN273: EP93xx Silicon Rev E Design
- * Guidelines" for more information.  This document can be found at:
- *
- *     http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf
- */
-
-#define EP93XX_CS0_PHYS_BASE_ASYNC     0x00000000      /* ASDO Pin = 0 */
-#define EP93XX_SDCE3_PHYS_BASE_SYNC    0x00000000      /* ASDO Pin = 1 */
-#define EP93XX_CS1_PHYS_BASE           0x10000000
-#define EP93XX_CS2_PHYS_BASE           0x20000000
-#define EP93XX_CS3_PHYS_BASE           0x30000000
-#define EP93XX_PCMCIA_PHYS_BASE                0x40000000
-#define EP93XX_CS6_PHYS_BASE           0x60000000
-#define EP93XX_CS7_PHYS_BASE           0x70000000
-#define EP93XX_SDCE0_PHYS_BASE         0xc0000000
-#define EP93XX_SDCE1_PHYS_BASE         0xd0000000
-#define EP93XX_SDCE2_PHYS_BASE         0xe0000000
-#define EP93XX_SDCE3_PHYS_BASE_ASYNC   0xf0000000      /* ASDO Pin = 0 */
-#define EP93XX_CS0_PHYS_BASE_SYNC      0xf0000000      /* ASDO Pin = 1 */
-
 /*
  * EP93xx linux memory map:
  *
 #define EP93XX_APB_PHYS(x)             (EP93XX_APB_PHYS_BASE + (x))
 #define EP93XX_APB_IOMEM(x)            IOMEM(EP93XX_APB_VIRT_BASE + (x))
 
-
-/* AHB peripherals */
-#define EP93XX_DMA_BASE                        EP93XX_AHB_IOMEM(0x00000000)
-
-#define EP93XX_ETHERNET_PHYS_BASE      EP93XX_AHB_PHYS(0x00010000)
-#define EP93XX_ETHERNET_BASE           EP93XX_AHB_IOMEM(0x00010000)
-
-#define EP93XX_USB_PHYS_BASE           EP93XX_AHB_PHYS(0x00020000)
-#define EP93XX_USB_BASE                        EP93XX_AHB_IOMEM(0x00020000)
-
-#define EP93XX_RASTER_PHYS_BASE                EP93XX_AHB_PHYS(0x00030000)
-#define EP93XX_RASTER_BASE             EP93XX_AHB_IOMEM(0x00030000)
-
-#define EP93XX_GRAPHICS_ACCEL_BASE     EP93XX_AHB_IOMEM(0x00040000)
-
-#define EP93XX_SDRAM_CONTROLLER_BASE   EP93XX_AHB_IOMEM(0x00060000)
-
-#define EP93XX_PCMCIA_CONTROLLER_BASE  EP93XX_AHB_IOMEM(0x00080000)
-
-#define EP93XX_BOOT_ROM_BASE           EP93XX_AHB_IOMEM(0x00090000)
-
-#define EP93XX_IDE_BASE                        EP93XX_AHB_IOMEM(0x000a0000)
-
-#define EP93XX_VIC1_BASE               EP93XX_AHB_IOMEM(0x000b0000)
-
-#define EP93XX_VIC2_BASE               EP93XX_AHB_IOMEM(0x000c0000)
-
-
-/* APB peripherals */
-#define EP93XX_TIMER_BASE              EP93XX_APB_IOMEM(0x00010000)
-
-#define EP93XX_I2S_PHYS_BASE           EP93XX_APB_PHYS(0x00020000)
-#define EP93XX_I2S_BASE                        EP93XX_APB_IOMEM(0x00020000)
-
-#define EP93XX_SECURITY_BASE           EP93XX_APB_IOMEM(0x00030000)
-
-#define EP93XX_GPIO_PHYS_BASE          EP93XX_APB_PHYS(0x00040000)
-#define EP93XX_GPIO_BASE               EP93XX_APB_IOMEM(0x00040000)
-#define EP93XX_GPIO_REG(x)             (EP93XX_GPIO_BASE + (x))
-#define EP93XX_GPIO_F_INT_STATUS       EP93XX_GPIO_REG(0x5c)
-#define EP93XX_GPIO_A_INT_STATUS       EP93XX_GPIO_REG(0xa0)
-#define EP93XX_GPIO_B_INT_STATUS       EP93XX_GPIO_REG(0xbc)
-#define EP93XX_GPIO_EEDRIVE            EP93XX_GPIO_REG(0xc8)
-
-#define EP93XX_AAC_PHYS_BASE           EP93XX_APB_PHYS(0x00080000)
-#define EP93XX_AAC_BASE                        EP93XX_APB_IOMEM(0x00080000)
-
-#define EP93XX_SPI_PHYS_BASE           EP93XX_APB_PHYS(0x000a0000)
-#define EP93XX_SPI_BASE                        EP93XX_APB_IOMEM(0x000a0000)
-
-#define EP93XX_IRDA_BASE               EP93XX_APB_IOMEM(0x000b0000)
-
+/* APB UARTs */
 #define EP93XX_UART1_PHYS_BASE         EP93XX_APB_PHYS(0x000c0000)
 #define EP93XX_UART1_BASE              EP93XX_APB_IOMEM(0x000c0000)
 
 #define EP93XX_UART3_PHYS_BASE         EP93XX_APB_PHYS(0x000e0000)
 #define EP93XX_UART3_BASE              EP93XX_APB_IOMEM(0x000e0000)
 
-#define EP93XX_KEY_MATRIX_PHYS_BASE    EP93XX_APB_PHYS(0x000f0000)
-#define EP93XX_KEY_MATRIX_BASE         EP93XX_APB_IOMEM(0x000f0000)
-
-#define EP93XX_ADC_BASE                        EP93XX_APB_IOMEM(0x00100000)
-#define EP93XX_TOUCHSCREEN_BASE                EP93XX_APB_IOMEM(0x00100000)
-
-#define EP93XX_PWM_PHYS_BASE           EP93XX_APB_PHYS(0x00110000)
-#define EP93XX_PWM_BASE                        EP93XX_APB_IOMEM(0x00110000)
-
-#define EP93XX_RTC_PHYS_BASE           EP93XX_APB_PHYS(0x00120000)
-#define EP93XX_RTC_BASE                        EP93XX_APB_IOMEM(0x00120000)
-
-#define EP93XX_SYSCON_BASE             EP93XX_APB_IOMEM(0x00130000)
-#define EP93XX_SYSCON_REG(x)           (EP93XX_SYSCON_BASE + (x))
-#define EP93XX_SYSCON_POWER_STATE      EP93XX_SYSCON_REG(0x00)
-#define EP93XX_SYSCON_PWRCNT           EP93XX_SYSCON_REG(0x04)
-#define EP93XX_SYSCON_PWRCNT_FIR_EN    (1<<31)
-#define EP93XX_SYSCON_PWRCNT_UARTBAUD  (1<<29)
-#define EP93XX_SYSCON_PWRCNT_USH_EN    (1<<28)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2M1  (1<<27)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2M0  (1<<26)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P8  (1<<25)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P9  (1<<24)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P6  (1<<23)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P7  (1<<22)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P4  (1<<21)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P5  (1<<20)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P2  (1<<19)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P3  (1<<18)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P0  (1<<17)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P1  (1<<16)
-#define EP93XX_SYSCON_HALT             EP93XX_SYSCON_REG(0x08)
-#define EP93XX_SYSCON_STANDBY          EP93XX_SYSCON_REG(0x0c)
-#define EP93XX_SYSCON_CLKSET1          EP93XX_SYSCON_REG(0x20)
-#define EP93XX_SYSCON_CLKSET1_NBYP1    (1<<23)
-#define EP93XX_SYSCON_CLKSET2          EP93XX_SYSCON_REG(0x24)
-#define EP93XX_SYSCON_CLKSET2_NBYP2    (1<<19)
-#define EP93XX_SYSCON_CLKSET2_PLL2_EN  (1<<18)
-#define EP93XX_SYSCON_DEVCFG           EP93XX_SYSCON_REG(0x80)
-#define EP93XX_SYSCON_DEVCFG_SWRST     (1<<31)
-#define EP93XX_SYSCON_DEVCFG_D1ONG     (1<<30)
-#define EP93XX_SYSCON_DEVCFG_D0ONG     (1<<29)
-#define EP93XX_SYSCON_DEVCFG_IONU2     (1<<28)
-#define EP93XX_SYSCON_DEVCFG_GONK      (1<<27)
-#define EP93XX_SYSCON_DEVCFG_TONG      (1<<26)
-#define EP93XX_SYSCON_DEVCFG_MONG      (1<<25)
-#define EP93XX_SYSCON_DEVCFG_U3EN      (1<<24)
-#define EP93XX_SYSCON_DEVCFG_CPENA     (1<<23)
-#define EP93XX_SYSCON_DEVCFG_A2ONG     (1<<22)
-#define EP93XX_SYSCON_DEVCFG_A1ONG     (1<<21)
-#define EP93XX_SYSCON_DEVCFG_U2EN      (1<<20)
-#define EP93XX_SYSCON_DEVCFG_EXVC      (1<<19)
-#define EP93XX_SYSCON_DEVCFG_U1EN      (1<<18)
-#define EP93XX_SYSCON_DEVCFG_TIN       (1<<17)
-#define EP93XX_SYSCON_DEVCFG_HC3IN     (1<<15)
-#define EP93XX_SYSCON_DEVCFG_HC3EN     (1<<14)
-#define EP93XX_SYSCON_DEVCFG_HC1IN     (1<<13)
-#define EP93XX_SYSCON_DEVCFG_HC1EN     (1<<12)
-#define EP93XX_SYSCON_DEVCFG_HONIDE    (1<<11)
-#define EP93XX_SYSCON_DEVCFG_GONIDE    (1<<10)
-#define EP93XX_SYSCON_DEVCFG_PONG      (1<<9)
-#define EP93XX_SYSCON_DEVCFG_EONIDE    (1<<8)
-#define EP93XX_SYSCON_DEVCFG_I2SONSSP  (1<<7)
-#define EP93XX_SYSCON_DEVCFG_I2SONAC97 (1<<6)
-#define EP93XX_SYSCON_DEVCFG_RASONP3   (1<<4)
-#define EP93XX_SYSCON_DEVCFG_RAS       (1<<3)
-#define EP93XX_SYSCON_DEVCFG_ADCPD     (1<<2)
-#define EP93XX_SYSCON_DEVCFG_KEYS      (1<<1)
-#define EP93XX_SYSCON_DEVCFG_SHENA     (1<<0)
-#define EP93XX_SYSCON_VIDCLKDIV                EP93XX_SYSCON_REG(0x84)
-#define EP93XX_SYSCON_CLKDIV_ENABLE    (1<<15)
-#define EP93XX_SYSCON_CLKDIV_ESEL      (1<<14)
-#define EP93XX_SYSCON_CLKDIV_PSEL      (1<<13)
-#define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT        8
-#define EP93XX_SYSCON_I2SCLKDIV                EP93XX_SYSCON_REG(0x8c)
-#define EP93XX_SYSCON_I2SCLKDIV_SENA   (1<<31)
-#define EP93XX_SYSCON_I2SCLKDIV_ORIDE   (1<<29)
-#define EP93XX_SYSCON_I2SCLKDIV_SPOL   (1<<19)
-#define EP93XX_I2SCLKDIV_SDIV          (1 << 16)
-#define EP93XX_I2SCLKDIV_LRDIV32       (0 << 17)
-#define EP93XX_I2SCLKDIV_LRDIV64       (1 << 17)
-#define EP93XX_I2SCLKDIV_LRDIV128      (2 << 17)
-#define EP93XX_I2SCLKDIV_LRDIV_MASK    (3 << 17)
-#define EP93XX_SYSCON_KEYTCHCLKDIV     EP93XX_SYSCON_REG(0x90)
-#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN        (1<<31)
-#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV        (1<<16)
-#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN (1<<15)
-#define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV        (1<<0)
-#define EP93XX_SYSCON_SYSCFG           EP93XX_SYSCON_REG(0x9c)
-#define EP93XX_SYSCON_SYSCFG_REV_MASK  (0xf0000000)
-#define EP93XX_SYSCON_SYSCFG_REV_SHIFT (28)
-#define EP93XX_SYSCON_SYSCFG_SBOOT     (1<<8)
-#define EP93XX_SYSCON_SYSCFG_LCSN7     (1<<7)
-#define EP93XX_SYSCON_SYSCFG_LCSN6     (1<<6)
-#define EP93XX_SYSCON_SYSCFG_LASDO     (1<<5)
-#define EP93XX_SYSCON_SYSCFG_LEEDA     (1<<4)
-#define EP93XX_SYSCON_SYSCFG_LEECLK    (1<<3)
-#define EP93XX_SYSCON_SYSCFG_LCSN2     (1<<1)
-#define EP93XX_SYSCON_SYSCFG_LCSN1     (1<<0)
-#define EP93XX_SYSCON_SWLOCK           EP93XX_SYSCON_REG(0xc0)
-
-#define EP93XX_WATCHDOG_PHYS_BASE      EP93XX_APB_PHYS(0x00140000)
-#define EP93XX_WATCHDOG_BASE           EP93XX_APB_IOMEM(0x00140000)
-
-
 #endif
index 8aff2ea35877876bfb99e31f433df5bc867e3cb3..6d7c571a519f5a7e85305d3dae9ae6a57b19a13a 100644 (file)
@@ -3,6 +3,16 @@
 #ifndef __GPIO_EP93XX_H
 #define __GPIO_EP93XX_H
 
+#include <mach/ep93xx-regs.h>
+
+#define EP93XX_GPIO_PHYS_BASE          EP93XX_APB_PHYS(0x00040000)
+#define EP93XX_GPIO_BASE               EP93XX_APB_IOMEM(0x00040000)
+#define EP93XX_GPIO_REG(x)             (EP93XX_GPIO_BASE + (x))
+#define EP93XX_GPIO_F_INT_STATUS       EP93XX_GPIO_REG(0x5c)
+#define EP93XX_GPIO_A_INT_STATUS       EP93XX_GPIO_REG(0xa0)
+#define EP93XX_GPIO_B_INT_STATUS       EP93XX_GPIO_REG(0xbc)
+#define EP93XX_GPIO_EEDRIVE            EP93XX_GPIO_REG(0xc8)
+
 /* GPIO port A.  */
 #define EP93XX_GPIO_LINE_A(x)          ((x) + 0)
 #define EP93XX_GPIO_LINE_EGPIO0                EP93XX_GPIO_LINE_A(0)
index 4df842897eae8900408fe79469b20dd5e651211a..efcd47815a9110d9b37c6c917ae03bd9d056562d 100644 (file)
@@ -5,7 +5,6 @@
 #ifndef __ASM_ARCH_HARDWARE_H
 #define __ASM_ARCH_HARDWARE_H
 
-#include <mach/ep93xx-regs.h>
 #include <mach/platform.h>
 
 /*
index ad63d4be693fbfeca164a080a73e871118df2425..602bd87fd0ab4dc386dfd2481b5de71b292cbcf4 100644 (file)
@@ -21,20 +21,6 @@ struct ep93xx_eth_data
 void ep93xx_map_io(void);
 void ep93xx_init_irq(void);
 
-/* EP93xx System Controller software locked register write */
-void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg);
-void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits);
-
-static inline void ep93xx_devcfg_set_bits(unsigned int bits)
-{
-       ep93xx_devcfg_set_clear(bits, 0x00);
-}
-
-static inline void ep93xx_devcfg_clear_bits(unsigned int bits)
-{
-       ep93xx_devcfg_set_clear(0x00, bits);
-}
-
 #define EP93XX_CHIP_REV_D0     3
 #define EP93XX_CHIP_REV_D1     4
 #define EP93XX_CHIP_REV_E0     5
index 7b98084f0c97bf14e8830a30b3dd18b10d5a3163..dc431c5f04cee416a7fa102658189cc27949628e 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+#include "soc.h"
 
 /*************************************************************************
  * Micro9 NOR Flash
index f4e553eca21c7d7c4cfdfd406489a34623945592..f40c2987e5451f2f55fa613a603f1d03e1382229 100644 (file)
@@ -29,6 +29,8 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+#include "soc.h"
+
 static struct ep93xx_eth_data __initdata simone_eth_data = {
        .phy_id         = 1,
 };
index fd846331ddff9119023c2a726adae50a16578f6f..0c00852ef160ba73dc19519e9365170c76a4d299 100644 (file)
@@ -35,6 +35,8 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+#include "soc.h"
+
 #define SNAPPERCL15_NAND_BASE  (EP93XX_CS7_PHYS_BASE + SZ_16M)
 
 #define SNAPPERCL15_NAND_WPN   (1 << 8)  /* Write protect (active low) */
diff --git a/arch/arm/mach-ep93xx/soc.h b/arch/arm/mach-ep93xx/soc.h
new file mode 100644 (file)
index 0000000..979fba7
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * arch/arm/mach-ep93xx/soc.h
+ *
+ * Copyright (C) 2012 Open Kernel Labs <www.ok-labs.com>
+ * Copyright (C) 2012 Ryan Mallon <rmallon@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef _EP93XX_SOC_H
+#define _EP93XX_SOC_H
+
+#include <mach/ep93xx-regs.h>
+
+/*
+ * EP93xx Physical Memory Map:
+ *
+ * The ASDO pin is sampled at system reset to select a synchronous or
+ * asynchronous boot configuration.  When ASDO is "1" (i.e. pulled-up)
+ * the synchronous boot mode is selected.  When ASDO is "0" (i.e
+ * pulled-down) the asynchronous boot mode is selected.
+ *
+ * In synchronous boot mode nSDCE3 is decoded starting at physical address
+ * 0x00000000 and nCS0 is decoded starting at 0xf0000000.  For asynchronous
+ * boot mode they are swapped with nCS0 decoded at 0x00000000 ann nSDCE3
+ * decoded at 0xf0000000.
+ *
+ * There is known errata for the EP93xx dealing with External Memory
+ * Configurations.  Please refer to "AN273: EP93xx Silicon Rev E Design
+ * Guidelines" for more information.  This document can be found at:
+ *
+ *     http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf
+ */
+
+#define EP93XX_CS0_PHYS_BASE_ASYNC     0x00000000      /* ASDO Pin = 0 */
+#define EP93XX_SDCE3_PHYS_BASE_SYNC    0x00000000      /* ASDO Pin = 1 */
+#define EP93XX_CS1_PHYS_BASE           0x10000000
+#define EP93XX_CS2_PHYS_BASE           0x20000000
+#define EP93XX_CS3_PHYS_BASE           0x30000000
+#define EP93XX_PCMCIA_PHYS_BASE                0x40000000
+#define EP93XX_CS6_PHYS_BASE           0x60000000
+#define EP93XX_CS7_PHYS_BASE           0x70000000
+#define EP93XX_SDCE0_PHYS_BASE         0xc0000000
+#define EP93XX_SDCE1_PHYS_BASE         0xd0000000
+#define EP93XX_SDCE2_PHYS_BASE         0xe0000000
+#define EP93XX_SDCE3_PHYS_BASE_ASYNC   0xf0000000      /* ASDO Pin = 0 */
+#define EP93XX_CS0_PHYS_BASE_SYNC      0xf0000000      /* ASDO Pin = 1 */
+
+/* AHB peripherals */
+#define EP93XX_DMA_BASE                        EP93XX_AHB_IOMEM(0x00000000)
+
+#define EP93XX_ETHERNET_PHYS_BASE      EP93XX_AHB_PHYS(0x00010000)
+#define EP93XX_ETHERNET_BASE           EP93XX_AHB_IOMEM(0x00010000)
+
+#define EP93XX_USB_PHYS_BASE           EP93XX_AHB_PHYS(0x00020000)
+#define EP93XX_USB_BASE                        EP93XX_AHB_IOMEM(0x00020000)
+
+#define EP93XX_RASTER_PHYS_BASE                EP93XX_AHB_PHYS(0x00030000)
+#define EP93XX_RASTER_BASE             EP93XX_AHB_IOMEM(0x00030000)
+
+#define EP93XX_GRAPHICS_ACCEL_BASE     EP93XX_AHB_IOMEM(0x00040000)
+
+#define EP93XX_SDRAM_CONTROLLER_BASE   EP93XX_AHB_IOMEM(0x00060000)
+
+#define EP93XX_PCMCIA_CONTROLLER_BASE  EP93XX_AHB_IOMEM(0x00080000)
+
+#define EP93XX_BOOT_ROM_BASE           EP93XX_AHB_IOMEM(0x00090000)
+
+#define EP93XX_IDE_BASE                        EP93XX_AHB_IOMEM(0x000a0000)
+
+#define EP93XX_VIC1_BASE               EP93XX_AHB_IOMEM(0x000b0000)
+
+#define EP93XX_VIC2_BASE               EP93XX_AHB_IOMEM(0x000c0000)
+
+/* APB peripherals */
+#define EP93XX_TIMER_BASE              EP93XX_APB_IOMEM(0x00010000)
+
+#define EP93XX_I2S_PHYS_BASE           EP93XX_APB_PHYS(0x00020000)
+#define EP93XX_I2S_BASE                        EP93XX_APB_IOMEM(0x00020000)
+
+#define EP93XX_SECURITY_BASE           EP93XX_APB_IOMEM(0x00030000)
+
+#define EP93XX_AAC_PHYS_BASE           EP93XX_APB_PHYS(0x00080000)
+#define EP93XX_AAC_BASE                        EP93XX_APB_IOMEM(0x00080000)
+
+#define EP93XX_SPI_PHYS_BASE           EP93XX_APB_PHYS(0x000a0000)
+#define EP93XX_SPI_BASE                        EP93XX_APB_IOMEM(0x000a0000)
+
+#define EP93XX_IRDA_BASE               EP93XX_APB_IOMEM(0x000b0000)
+
+#define EP93XX_KEY_MATRIX_PHYS_BASE    EP93XX_APB_PHYS(0x000f0000)
+#define EP93XX_KEY_MATRIX_BASE         EP93XX_APB_IOMEM(0x000f0000)
+
+#define EP93XX_ADC_BASE                        EP93XX_APB_IOMEM(0x00100000)
+#define EP93XX_TOUCHSCREEN_BASE                EP93XX_APB_IOMEM(0x00100000)
+
+#define EP93XX_PWM_PHYS_BASE           EP93XX_APB_PHYS(0x00110000)
+#define EP93XX_PWM_BASE                        EP93XX_APB_IOMEM(0x00110000)
+
+#define EP93XX_RTC_PHYS_BASE           EP93XX_APB_PHYS(0x00120000)
+#define EP93XX_RTC_BASE                        EP93XX_APB_IOMEM(0x00120000)
+
+#define EP93XX_WATCHDOG_PHYS_BASE      EP93XX_APB_PHYS(0x00140000)
+#define EP93XX_WATCHDOG_BASE           EP93XX_APB_IOMEM(0x00140000)
+
+/* System controller */
+#define EP93XX_SYSCON_BASE             EP93XX_APB_IOMEM(0x00130000)
+#define EP93XX_SYSCON_REG(x)           (EP93XX_SYSCON_BASE + (x))
+#define EP93XX_SYSCON_POWER_STATE      EP93XX_SYSCON_REG(0x00)
+#define EP93XX_SYSCON_PWRCNT           EP93XX_SYSCON_REG(0x04)
+#define EP93XX_SYSCON_PWRCNT_FIR_EN    (1<<31)
+#define EP93XX_SYSCON_PWRCNT_UARTBAUD  (1<<29)
+#define EP93XX_SYSCON_PWRCNT_USH_EN    (1<<28)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2M1  (1<<27)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2M0  (1<<26)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P8  (1<<25)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P9  (1<<24)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P6  (1<<23)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P7  (1<<22)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P4  (1<<21)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P5  (1<<20)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P2  (1<<19)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P3  (1<<18)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P0  (1<<17)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P1  (1<<16)
+#define EP93XX_SYSCON_HALT             EP93XX_SYSCON_REG(0x08)
+#define EP93XX_SYSCON_STANDBY          EP93XX_SYSCON_REG(0x0c)
+#define EP93XX_SYSCON_CLKSET1          EP93XX_SYSCON_REG(0x20)
+#define EP93XX_SYSCON_CLKSET1_NBYP1    (1<<23)
+#define EP93XX_SYSCON_CLKSET2          EP93XX_SYSCON_REG(0x24)
+#define EP93XX_SYSCON_CLKSET2_NBYP2    (1<<19)
+#define EP93XX_SYSCON_CLKSET2_PLL2_EN  (1<<18)
+#define EP93XX_SYSCON_DEVCFG           EP93XX_SYSCON_REG(0x80)
+#define EP93XX_SYSCON_DEVCFG_SWRST     (1<<31)
+#define EP93XX_SYSCON_DEVCFG_D1ONG     (1<<30)
+#define EP93XX_SYSCON_DEVCFG_D0ONG     (1<<29)
+#define EP93XX_SYSCON_DEVCFG_IONU2     (1<<28)
+#define EP93XX_SYSCON_DEVCFG_GONK      (1<<27)
+#define EP93XX_SYSCON_DEVCFG_TONG      (1<<26)
+#define EP93XX_SYSCON_DEVCFG_MONG      (1<<25)
+#define EP93XX_SYSCON_DEVCFG_U3EN      (1<<24)
+#define EP93XX_SYSCON_DEVCFG_CPENA     (1<<23)
+#define EP93XX_SYSCON_DEVCFG_A2ONG     (1<<22)
+#define EP93XX_SYSCON_DEVCFG_A1ONG     (1<<21)
+#define EP93XX_SYSCON_DEVCFG_U2EN      (1<<20)
+#define EP93XX_SYSCON_DEVCFG_EXVC      (1<<19)
+#define EP93XX_SYSCON_DEVCFG_U1EN      (1<<18)
+#define EP93XX_SYSCON_DEVCFG_TIN       (1<<17)
+#define EP93XX_SYSCON_DEVCFG_HC3IN     (1<<15)
+#define EP93XX_SYSCON_DEVCFG_HC3EN     (1<<14)
+#define EP93XX_SYSCON_DEVCFG_HC1IN     (1<<13)
+#define EP93XX_SYSCON_DEVCFG_HC1EN     (1<<12)
+#define EP93XX_SYSCON_DEVCFG_HONIDE    (1<<11)
+#define EP93XX_SYSCON_DEVCFG_GONIDE    (1<<10)
+#define EP93XX_SYSCON_DEVCFG_PONG      (1<<9)
+#define EP93XX_SYSCON_DEVCFG_EONIDE    (1<<8)
+#define EP93XX_SYSCON_DEVCFG_I2SONSSP  (1<<7)
+#define EP93XX_SYSCON_DEVCFG_I2SONAC97 (1<<6)
+#define EP93XX_SYSCON_DEVCFG_RASONP3   (1<<4)
+#define EP93XX_SYSCON_DEVCFG_RAS       (1<<3)
+#define EP93XX_SYSCON_DEVCFG_ADCPD     (1<<2)
+#define EP93XX_SYSCON_DEVCFG_KEYS      (1<<1)
+#define EP93XX_SYSCON_DEVCFG_SHENA     (1<<0)
+#define EP93XX_SYSCON_VIDCLKDIV                EP93XX_SYSCON_REG(0x84)
+#define EP93XX_SYSCON_CLKDIV_ENABLE    (1<<15)
+#define EP93XX_SYSCON_CLKDIV_ESEL      (1<<14)
+#define EP93XX_SYSCON_CLKDIV_PSEL      (1<<13)
+#define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT        8
+#define EP93XX_SYSCON_I2SCLKDIV                EP93XX_SYSCON_REG(0x8c)
+#define EP93XX_SYSCON_I2SCLKDIV_SENA   (1<<31)
+#define EP93XX_SYSCON_I2SCLKDIV_ORIDE   (1<<29)
+#define EP93XX_SYSCON_I2SCLKDIV_SPOL   (1<<19)
+#define EP93XX_I2SCLKDIV_SDIV          (1 << 16)
+#define EP93XX_I2SCLKDIV_LRDIV32       (0 << 17)
+#define EP93XX_I2SCLKDIV_LRDIV64       (1 << 17)
+#define EP93XX_I2SCLKDIV_LRDIV128      (2 << 17)
+#define EP93XX_I2SCLKDIV_LRDIV_MASK    (3 << 17)
+#define EP93XX_SYSCON_KEYTCHCLKDIV     EP93XX_SYSCON_REG(0x90)
+#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN        (1<<31)
+#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV        (1<<16)
+#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN (1<<15)
+#define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV        (1<<0)
+#define EP93XX_SYSCON_SYSCFG           EP93XX_SYSCON_REG(0x9c)
+#define EP93XX_SYSCON_SYSCFG_REV_MASK  (0xf0000000)
+#define EP93XX_SYSCON_SYSCFG_REV_SHIFT (28)
+#define EP93XX_SYSCON_SYSCFG_SBOOT     (1<<8)
+#define EP93XX_SYSCON_SYSCFG_LCSN7     (1<<7)
+#define EP93XX_SYSCON_SYSCFG_LCSN6     (1<<6)
+#define EP93XX_SYSCON_SYSCFG_LASDO     (1<<5)
+#define EP93XX_SYSCON_SYSCFG_LEEDA     (1<<4)
+#define EP93XX_SYSCON_SYSCFG_LEECLK    (1<<3)
+#define EP93XX_SYSCON_SYSCFG_LCSN2     (1<<1)
+#define EP93XX_SYSCON_SYSCFG_LCSN1     (1<<0)
+#define EP93XX_SYSCON_SWLOCK           EP93XX_SYSCON_REG(0xc0)
+
+/* EP93xx System Controller software locked register write */
+void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg);
+void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits);
+
+static inline void ep93xx_devcfg_set_bits(unsigned int bits)
+{
+       ep93xx_devcfg_set_clear(bits, 0x00);
+}
+
+static inline void ep93xx_devcfg_clear_bits(unsigned int bits)
+{
+       ep93xx_devcfg_set_clear(0x00, bits);
+}
+
+#endif /* _EP93XX_SOC_H */
index 79f8ecf07a190a082ac4da524ef185faea62715a..5ea790942e9476cdf313ee35fc2e1baf1fc83ee6 100644 (file)
@@ -28,6 +28,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/arch.h>
 
+#include "soc.h"
 
 static struct map_desc ts72xx_io_desc[] __initdata = {
        {
index d67d0b4feb6f3fa2266e66cb878444724d97c069..ba156eb225e89c647acf87159262a44939c9d4e9 100644 (file)
@@ -39,6 +39,8 @@
 #include <asm/mach/map.h>
 #include <asm/mach/arch.h>
 
+#include "soc.h"
+
 /*************************************************************************
  * Static I/O mappings for the FPGA
  *************************************************************************/
index dfad6538b2737f5acdc4c2644342627d2d6010f2..0491ceef1cda8a77bbaf60409416d906fc701620 100644 (file)
@@ -11,18 +11,19 @@ if ARCH_EXYNOS
 
 menu "SAMSUNG EXYNOS SoCs Support"
 
-choice
-       prompt "EXYNOS System Type"
-       default ARCH_EXYNOS4
-
 config ARCH_EXYNOS4
        bool "SAMSUNG EXYNOS4"
+       default y
        select HAVE_SMP
        select MIGHT_HAVE_CACHE_L2X0
        help
          Samsung EXYNOS4 SoCs based systems
 
-endchoice
+config ARCH_EXYNOS5
+       bool "SAMSUNG EXYNOS5"
+       select HAVE_SMP
+       help
+         Samsung EXYNOS5 (Cortex-A15) SoC based systems
 
 comment "EXYNOS SoCs"
 
@@ -42,6 +43,7 @@ config SOC_EXYNOS4212
        bool "SAMSUNG EXYNOS4212"
        default y
        depends on ARCH_EXYNOS4
+       select SAMSUNG_DMADEV
        select S5P_PM if PM
        select S5P_SLEEP if PM
        help
@@ -51,9 +53,17 @@ config SOC_EXYNOS4412
        bool "SAMSUNG EXYNOS4412"
        default y
        depends on ARCH_EXYNOS4
+       select SAMSUNG_DMADEV
        help
          Enable EXYNOS4412 SoC support
 
+config SOC_EXYNOS5250
+       bool "SAMSUNG EXYNOS5250"
+       default y
+       depends on ARCH_EXYNOS5
+       help
+         Enable EXYNOS5250 SoC support
+
 config EXYNOS4_MCT
        bool
        default y
@@ -179,7 +189,9 @@ config MACH_SMDKV310
        select S5P_DEV_FIMC1
        select S5P_DEV_FIMC2
        select S5P_DEV_FIMC3
+       select S5P_DEV_G2D
        select S5P_DEV_I2C_HDMIPHY
+       select S5P_DEV_JPEG
        select S5P_DEV_MFC
        select S5P_DEV_TV
        select S5P_DEV_USB_EHCI
@@ -225,7 +237,9 @@ config MACH_UNIVERSAL_C210
        select S5P_DEV_FIMC1
        select S5P_DEV_FIMC2
        select S5P_DEV_FIMC3
+       select S5P_DEV_G2D
        select S5P_DEV_CSIS0
+       select S5P_DEV_JPEG
        select S5P_DEV_FIMD0
        select S3C_DEV_HSMMC
        select S3C_DEV_HSMMC2
@@ -262,11 +276,14 @@ config MACH_NURI
        select S3C_DEV_I2C1
        select S3C_DEV_I2C3
        select S3C_DEV_I2C5
+       select S3C_DEV_I2C6
        select S5P_DEV_CSIS0
+       select S5P_DEV_JPEG
        select S5P_DEV_FIMC0
        select S5P_DEV_FIMC1
        select S5P_DEV_FIMC2
        select S5P_DEV_FIMC3
+       select S5P_DEV_G2D
        select S5P_DEV_MFC
        select S5P_DEV_USB_EHCI
        select S5P_SETUP_MIPIPHY
@@ -276,6 +293,7 @@ config MACH_NURI
        select EXYNOS4_SETUP_I2C1
        select EXYNOS4_SETUP_I2C3
        select EXYNOS4_SETUP_I2C5
+       select EXYNOS4_SETUP_I2C6
        select EXYNOS4_SETUP_SDHCI
        select EXYNOS4_SETUP_USB_PHY
        select S5P_SETUP_MIPIPHY
@@ -296,7 +314,9 @@ config MACH_ORIGEN
        select S5P_DEV_FIMC2
        select S5P_DEV_FIMC3
        select S5P_DEV_FIMD0
+       select S5P_DEV_G2D
        select S5P_DEV_I2C_HDMIPHY
+       select S5P_DEV_JPEG
        select S5P_DEV_MFC
        select S5P_DEV_TV
        select S5P_DEV_USB_EHCI
@@ -325,6 +345,7 @@ config MACH_SMDK4212
        select SAMSUNG_DEV_BACKLIGHT
        select SAMSUNG_DEV_KEYPAD
        select SAMSUNG_DEV_PWM
+       select EXYNOS4_DEV_DMA
        select EXYNOS4_SETUP_I2C1
        select EXYNOS4_SETUP_I2C3
        select EXYNOS4_SETUP_I2C7
@@ -343,7 +364,7 @@ config MACH_SMDK4412
          Machine support for Samsung SMDK4412
 endif
 
-comment "Flattened Device Tree based board for Exynos4 based SoC"
+comment "Flattened Device Tree based board for EXYNOS SoCs"
 
 config MACH_EXYNOS4_DT
        bool "Samsung Exynos4 Machine using device tree"
@@ -357,6 +378,15 @@ config MACH_EXYNOS4_DT
          Note: This is under development and not all peripherals can be supported
          with this machine file.
 
+config MACH_EXYNOS5_DT
+       bool "SAMSUNG EXYNOS5 Machine using device tree"
+       select SOC_EXYNOS5250
+       select USE_OF
+       select ARM_AMBA
+       help
+         Machine support for Samsung Exynos4 machine with device tree enabled.
+         Select this if a fdt blob is available for the EXYNOS4 SoC based board.
+
 if ARCH_EXYNOS4
 
 comment "Configuration for HSMMC 8-bit bus width"
index d9191f9a7af8560c69d60f39a703e687cd9bfca6..8631840d1b5e85ce8d959430bcdbdeadb339afbb 100644 (file)
@@ -12,7 +12,9 @@ obj-                          :=
 
 # Core
 
-obj-$(CONFIG_ARCH_EXYNOS4)     += common.o clock.o
+obj-$(CONFIG_ARCH_EXYNOS)      += common.o
+obj-$(CONFIG_ARCH_EXYNOS4)     += clock-exynos4.o
+obj-$(CONFIG_ARCH_EXYNOS5)     += clock-exynos5.o
 obj-$(CONFIG_CPU_EXYNOS4210)   += clock-exynos4210.o
 obj-$(CONFIG_SOC_EXYNOS4212)   += clock-exynos4212.o
 
@@ -41,9 +43,11 @@ obj-$(CONFIG_MACH_SMDK4212)          += mach-smdk4x12.o
 obj-$(CONFIG_MACH_SMDK4412)            += mach-smdk4x12.o
 
 obj-$(CONFIG_MACH_EXYNOS4_DT)          += mach-exynos4-dt.o
+obj-$(CONFIG_MACH_EXYNOS5_DT)          += mach-exynos5-dt.o
 
 # device support
 
+obj-y                                  += dev-uart.o
 obj-$(CONFIG_ARCH_EXYNOS4)             += dev-audio.o
 obj-$(CONFIG_EXYNOS4_DEV_AHCI)         += dev-ahci.o
 obj-$(CONFIG_EXYNOS4_DEV_SYSMMU)       += dev-sysmmu.o
@@ -51,7 +55,7 @@ obj-$(CONFIG_EXYNOS4_DEV_DWMCI)               += dev-dwmci.o
 obj-$(CONFIG_EXYNOS4_DEV_DMA)          += dma.o
 obj-$(CONFIG_EXYNOS4_DEV_USB_OHCI)     += dev-ohci.o
 
-obj-$(CONFIG_ARCH_EXYNOS4)             += setup-i2c0.o
+obj-$(CONFIG_ARCH_EXYNOS             += setup-i2c0.o
 obj-$(CONFIG_EXYNOS4_SETUP_FIMC)       += setup-fimc.o
 obj-$(CONFIG_EXYNOS4_SETUP_FIMD0)      += setup-fimd0.o
 obj-$(CONFIG_EXYNOS4_SETUP_I2C1)       += setup-i2c1.o
diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
new file mode 100644 (file)
index 0000000..df54c2a
--- /dev/null
@@ -0,0 +1,1581 @@
+/*
+ * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/pm.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/sysmmu.h>
+
+#include "common.h"
+#include "clock-exynos4.h"
+
+#ifdef CONFIG_PM_SLEEP
+static struct sleep_save exynos4_clock_save[] = {
+       SAVE_ITEM(EXYNOS4_CLKDIV_LEFTBUS),
+       SAVE_ITEM(EXYNOS4_CLKGATE_IP_LEFTBUS),
+       SAVE_ITEM(EXYNOS4_CLKDIV_RIGHTBUS),
+       SAVE_ITEM(EXYNOS4_CLKGATE_IP_RIGHTBUS),
+       SAVE_ITEM(EXYNOS4_CLKSRC_TOP0),
+       SAVE_ITEM(EXYNOS4_CLKSRC_TOP1),
+       SAVE_ITEM(EXYNOS4_CLKSRC_CAM),
+       SAVE_ITEM(EXYNOS4_CLKSRC_TV),
+       SAVE_ITEM(EXYNOS4_CLKSRC_MFC),
+       SAVE_ITEM(EXYNOS4_CLKSRC_G3D),
+       SAVE_ITEM(EXYNOS4_CLKSRC_LCD0),
+       SAVE_ITEM(EXYNOS4_CLKSRC_MAUDIO),
+       SAVE_ITEM(EXYNOS4_CLKSRC_FSYS),
+       SAVE_ITEM(EXYNOS4_CLKSRC_PERIL0),
+       SAVE_ITEM(EXYNOS4_CLKSRC_PERIL1),
+       SAVE_ITEM(EXYNOS4_CLKDIV_CAM),
+       SAVE_ITEM(EXYNOS4_CLKDIV_TV),
+       SAVE_ITEM(EXYNOS4_CLKDIV_MFC),
+       SAVE_ITEM(EXYNOS4_CLKDIV_G3D),
+       SAVE_ITEM(EXYNOS4_CLKDIV_LCD0),
+       SAVE_ITEM(EXYNOS4_CLKDIV_MAUDIO),
+       SAVE_ITEM(EXYNOS4_CLKDIV_FSYS0),
+       SAVE_ITEM(EXYNOS4_CLKDIV_FSYS1),
+       SAVE_ITEM(EXYNOS4_CLKDIV_FSYS2),
+       SAVE_ITEM(EXYNOS4_CLKDIV_FSYS3),
+       SAVE_ITEM(EXYNOS4_CLKDIV_PERIL0),
+       SAVE_ITEM(EXYNOS4_CLKDIV_PERIL1),
+       SAVE_ITEM(EXYNOS4_CLKDIV_PERIL2),
+       SAVE_ITEM(EXYNOS4_CLKDIV_PERIL3),
+       SAVE_ITEM(EXYNOS4_CLKDIV_PERIL4),
+       SAVE_ITEM(EXYNOS4_CLKDIV_PERIL5),
+       SAVE_ITEM(EXYNOS4_CLKDIV_TOP),
+       SAVE_ITEM(EXYNOS4_CLKSRC_MASK_TOP),
+       SAVE_ITEM(EXYNOS4_CLKSRC_MASK_CAM),
+       SAVE_ITEM(EXYNOS4_CLKSRC_MASK_TV),
+       SAVE_ITEM(EXYNOS4_CLKSRC_MASK_LCD0),
+       SAVE_ITEM(EXYNOS4_CLKSRC_MASK_MAUDIO),
+       SAVE_ITEM(EXYNOS4_CLKSRC_MASK_FSYS),
+       SAVE_ITEM(EXYNOS4_CLKSRC_MASK_PERIL0),
+       SAVE_ITEM(EXYNOS4_CLKSRC_MASK_PERIL1),
+       SAVE_ITEM(EXYNOS4_CLKDIV2_RATIO),
+       SAVE_ITEM(EXYNOS4_CLKGATE_SCLKCAM),
+       SAVE_ITEM(EXYNOS4_CLKGATE_IP_CAM),
+       SAVE_ITEM(EXYNOS4_CLKGATE_IP_TV),
+       SAVE_ITEM(EXYNOS4_CLKGATE_IP_MFC),
+       SAVE_ITEM(EXYNOS4_CLKGATE_IP_G3D),
+       SAVE_ITEM(EXYNOS4_CLKGATE_IP_LCD0),
+       SAVE_ITEM(EXYNOS4_CLKGATE_IP_FSYS),
+       SAVE_ITEM(EXYNOS4_CLKGATE_IP_GPS),
+       SAVE_ITEM(EXYNOS4_CLKGATE_IP_PERIL),
+       SAVE_ITEM(EXYNOS4_CLKGATE_BLOCK),
+       SAVE_ITEM(EXYNOS4_CLKSRC_MASK_DMC),
+       SAVE_ITEM(EXYNOS4_CLKSRC_DMC),
+       SAVE_ITEM(EXYNOS4_CLKDIV_DMC0),
+       SAVE_ITEM(EXYNOS4_CLKDIV_DMC1),
+       SAVE_ITEM(EXYNOS4_CLKGATE_IP_DMC),
+       SAVE_ITEM(EXYNOS4_CLKSRC_CPU),
+       SAVE_ITEM(EXYNOS4_CLKDIV_CPU),
+       SAVE_ITEM(EXYNOS4_CLKDIV_CPU + 0x4),
+       SAVE_ITEM(EXYNOS4_CLKGATE_SCLKCPU),
+       SAVE_ITEM(EXYNOS4_CLKGATE_IP_CPU),
+};
+#endif
+
+static struct clk exynos4_clk_sclk_hdmi27m = {
+       .name           = "sclk_hdmi27m",
+       .rate           = 27000000,
+};
+
+static struct clk exynos4_clk_sclk_hdmiphy = {
+       .name           = "sclk_hdmiphy",
+};
+
+static struct clk exynos4_clk_sclk_usbphy0 = {
+       .name           = "sclk_usbphy0",
+       .rate           = 27000000,
+};
+
+static struct clk exynos4_clk_sclk_usbphy1 = {
+       .name           = "sclk_usbphy1",
+};
+
+static struct clk dummy_apb_pclk = {
+       .name           = "apb_pclk",
+       .id             = -1,
+};
+
+static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_TOP, clk, enable);
+}
+
+static int exynos4_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_CAM, clk, enable);
+}
+
+static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_LCD0, clk, enable);
+}
+
+int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_FSYS, clk, enable);
+}
+
+static int exynos4_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_PERIL0, clk, enable);
+}
+
+static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_PERIL1, clk, enable);
+}
+
+static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_MFC, clk, enable);
+}
+
+static int exynos4_clksrc_mask_tv_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_TV, clk, enable);
+}
+
+static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_CAM, clk, enable);
+}
+
+static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_TV, clk, enable);
+}
+
+static int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_IMAGE, clk, enable);
+}
+
+static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_LCD0, clk, enable);
+}
+
+int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS4210_CLKGATE_IP_LCD1, clk, enable);
+}
+
+int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_FSYS, clk, enable);
+}
+
+static int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIL, clk, enable);
+}
+
+static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIR, clk, enable);
+}
+
+static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
+}
+
+static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable);
+}
+
+/* Core list of CMU_CPU side */
+
+static struct clksrc_clk exynos4_clk_mout_apll = {
+       .clk    = {
+               .name           = "mout_apll",
+       },
+       .sources = &clk_src_apll,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 0, .size = 1 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_apll = {
+       .clk    = {
+               .name           = "sclk_apll",
+               .parent         = &exynos4_clk_mout_apll.clk,
+       },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 24, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_mout_epll = {
+       .clk    = {
+               .name           = "mout_epll",
+       },
+       .sources = &clk_src_epll,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 4, .size = 1 },
+};
+
+struct clksrc_clk exynos4_clk_mout_mpll = {
+       .clk    = {
+               .name           = "mout_mpll",
+       },
+       .sources = &clk_src_mpll,
+
+       /* reg_src will be added in each SoCs' clock */
+};
+
+static struct clk *exynos4_clkset_moutcore_list[] = {
+       [0] = &exynos4_clk_mout_apll.clk,
+       [1] = &exynos4_clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_moutcore = {
+       .sources        = exynos4_clkset_moutcore_list,
+       .nr_sources     = ARRAY_SIZE(exynos4_clkset_moutcore_list),
+};
+
+static struct clksrc_clk exynos4_clk_moutcore = {
+       .clk    = {
+               .name           = "moutcore",
+       },
+       .sources = &exynos4_clkset_moutcore,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 16, .size = 1 },
+};
+
+static struct clksrc_clk exynos4_clk_coreclk = {
+       .clk    = {
+               .name           = "core_clk",
+               .parent         = &exynos4_clk_moutcore.clk,
+       },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_armclk = {
+       .clk    = {
+               .name           = "armclk",
+               .parent         = &exynos4_clk_coreclk.clk,
+       },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_corem0 = {
+       .clk    = {
+               .name           = "aclk_corem0",
+               .parent         = &exynos4_clk_coreclk.clk,
+       },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 4, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_cores = {
+       .clk    = {
+               .name           = "aclk_cores",
+               .parent         = &exynos4_clk_coreclk.clk,
+       },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 4, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_corem1 = {
+       .clk    = {
+               .name           = "aclk_corem1",
+               .parent         = &exynos4_clk_coreclk.clk,
+       },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 8, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_periphclk = {
+       .clk    = {
+               .name           = "periphclk",
+               .parent         = &exynos4_clk_coreclk.clk,
+       },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 12, .size = 3 },
+};
+
+/* Core list of CMU_CORE side */
+
+static struct clk *exynos4_clkset_corebus_list[] = {
+       [0] = &exynos4_clk_mout_mpll.clk,
+       [1] = &exynos4_clk_sclk_apll.clk,
+};
+
+struct clksrc_sources exynos4_clkset_mout_corebus = {
+       .sources        = exynos4_clkset_corebus_list,
+       .nr_sources     = ARRAY_SIZE(exynos4_clkset_corebus_list),
+};
+
+static struct clksrc_clk exynos4_clk_mout_corebus = {
+       .clk    = {
+               .name           = "mout_corebus",
+       },
+       .sources = &exynos4_clkset_mout_corebus,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 4, .size = 1 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_dmc = {
+       .clk    = {
+               .name           = "sclk_dmc",
+               .parent         = &exynos4_clk_mout_corebus.clk,
+       },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 12, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_cored = {
+       .clk    = {
+               .name           = "aclk_cored",
+               .parent         = &exynos4_clk_sclk_dmc.clk,
+       },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 16, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_corep = {
+       .clk    = {
+               .name           = "aclk_corep",
+               .parent         = &exynos4_clk_aclk_cored.clk,
+       },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 20, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_acp = {
+       .clk    = {
+               .name           = "aclk_acp",
+               .parent         = &exynos4_clk_mout_corebus.clk,
+       },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_pclk_acp = {
+       .clk    = {
+               .name           = "pclk_acp",
+               .parent         = &exynos4_clk_aclk_acp.clk,
+       },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 4, .size = 3 },
+};
+
+/* Core list of CMU_TOP side */
+
+struct clk *exynos4_clkset_aclk_top_list[] = {
+       [0] = &exynos4_clk_mout_mpll.clk,
+       [1] = &exynos4_clk_sclk_apll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_aclk = {
+       .sources        = exynos4_clkset_aclk_top_list,
+       .nr_sources     = ARRAY_SIZE(exynos4_clkset_aclk_top_list),
+};
+
+static struct clksrc_clk exynos4_clk_aclk_200 = {
+       .clk    = {
+               .name           = "aclk_200",
+       },
+       .sources = &exynos4_clkset_aclk,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 12, .size = 1 },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_100 = {
+       .clk    = {
+               .name           = "aclk_100",
+       },
+       .sources = &exynos4_clkset_aclk,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 16, .size = 1 },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 4, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_160 = {
+       .clk    = {
+               .name           = "aclk_160",
+       },
+       .sources = &exynos4_clkset_aclk,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 20, .size = 1 },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 8, .size = 3 },
+};
+
+struct clksrc_clk exynos4_clk_aclk_133 = {
+       .clk    = {
+               .name           = "aclk_133",
+       },
+       .sources = &exynos4_clkset_aclk,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 24, .size = 1 },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 12, .size = 3 },
+};
+
+static struct clk *exynos4_clkset_vpllsrc_list[] = {
+       [0] = &clk_fin_vpll,
+       [1] = &exynos4_clk_sclk_hdmi27m,
+};
+
+static struct clksrc_sources exynos4_clkset_vpllsrc = {
+       .sources        = exynos4_clkset_vpllsrc_list,
+       .nr_sources     = ARRAY_SIZE(exynos4_clkset_vpllsrc_list),
+};
+
+static struct clksrc_clk exynos4_clk_vpllsrc = {
+       .clk    = {
+               .name           = "vpll_src",
+               .enable         = exynos4_clksrc_mask_top_ctrl,
+               .ctrlbit        = (1 << 0),
+       },
+       .sources = &exynos4_clkset_vpllsrc,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_TOP1, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_sclk_vpll_list[] = {
+       [0] = &exynos4_clk_vpllsrc.clk,
+       [1] = &clk_fout_vpll,
+};
+
+static struct clksrc_sources exynos4_clkset_sclk_vpll = {
+       .sources        = exynos4_clkset_sclk_vpll_list,
+       .nr_sources     = ARRAY_SIZE(exynos4_clkset_sclk_vpll_list),
+};
+
+static struct clksrc_clk exynos4_clk_sclk_vpll = {
+       .clk    = {
+               .name           = "sclk_vpll",
+       },
+       .sources = &exynos4_clkset_sclk_vpll,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 8, .size = 1 },
+};
+
+static struct clk exynos4_init_clocks_off[] = {
+       {
+               .name           = "timers",
+               .parent         = &exynos4_clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1<<24),
+       }, {
+               .name           = "csis",
+               .devname        = "s5p-mipi-csis.0",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "csis",
+               .devname        = "s5p-mipi-csis.1",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "jpeg",
+               .id             = 0,
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "fimc",
+               .devname        = "exynos4-fimc.0",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "fimc",
+               .devname        = "exynos4-fimc.1",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "fimc",
+               .devname        = "exynos4-fimc.2",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "fimc",
+               .devname        = "exynos4-fimc.3",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "hsmmc",
+               .devname        = "s3c-sdhci.0",
+               .parent         = &exynos4_clk_aclk_133.clk,
+               .enable         = exynos4_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "hsmmc",
+               .devname        = "s3c-sdhci.1",
+               .parent         = &exynos4_clk_aclk_133.clk,
+               .enable         = exynos4_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "hsmmc",
+               .devname        = "s3c-sdhci.2",
+               .parent         = &exynos4_clk_aclk_133.clk,
+               .enable         = exynos4_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "hsmmc",
+               .devname        = "s3c-sdhci.3",
+               .parent         = &exynos4_clk_aclk_133.clk,
+               .enable         = exynos4_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "dwmmc",
+               .parent         = &exynos4_clk_aclk_133.clk,
+               .enable         = exynos4_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 9),
+       }, {
+               .name           = "dac",
+               .devname        = "s5p-sdo",
+               .enable         = exynos4_clk_ip_tv_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "mixer",
+               .devname        = "s5p-mixer",
+               .enable         = exynos4_clk_ip_tv_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "vp",
+               .devname        = "s5p-mixer",
+               .enable         = exynos4_clk_ip_tv_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "hdmi",
+               .devname        = "exynos4-hdmi",
+               .enable         = exynos4_clk_ip_tv_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "hdmiphy",
+               .devname        = "exynos4-hdmi",
+               .enable         = exynos4_clk_hdmiphy_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "dacphy",
+               .devname        = "s5p-sdo",
+               .enable         = exynos4_clk_dac_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "adc",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 15),
+       }, {
+               .name           = "keypad",
+               .enable         = exynos4_clk_ip_perir_ctrl,
+               .ctrlbit        = (1 << 16),
+       }, {
+               .name           = "rtc",
+               .enable         = exynos4_clk_ip_perir_ctrl,
+               .ctrlbit        = (1 << 15),
+       }, {
+               .name           = "watchdog",
+               .parent         = &exynos4_clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_perir_ctrl,
+               .ctrlbit        = (1 << 14),
+       }, {
+               .name           = "usbhost",
+               .enable         = exynos4_clk_ip_fsys_ctrl ,
+               .ctrlbit        = (1 << 12),
+       }, {
+               .name           = "otg",
+               .enable         = exynos4_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 13),
+       }, {
+               .name           = "spi",
+               .devname        = "s3c64xx-spi.0",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 16),
+       }, {
+               .name           = "spi",
+               .devname        = "s3c64xx-spi.1",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 17),
+       }, {
+               .name           = "spi",
+               .devname        = "s3c64xx-spi.2",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 18),
+       }, {
+               .name           = "iis",
+               .devname        = "samsung-i2s.0",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 19),
+       }, {
+               .name           = "iis",
+               .devname        = "samsung-i2s.1",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 20),
+       }, {
+               .name           = "iis",
+               .devname        = "samsung-i2s.2",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 21),
+       }, {
+               .name           = "ac97",
+               .devname        = "samsung-ac97",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 27),
+       }, {
+               .name           = "fimg2d",
+               .enable         = exynos4_clk_ip_image_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "mfc",
+               .devname        = "s5p-mfc",
+               .enable         = exynos4_clk_ip_mfc_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.0",
+               .parent         = &exynos4_clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.1",
+               .parent         = &exynos4_clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.2",
+               .parent         = &exynos4_clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.3",
+               .parent         = &exynos4_clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 9),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.4",
+               .parent         = &exynos4_clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 10),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.5",
+               .parent         = &exynos4_clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 11),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.6",
+               .parent         = &exynos4_clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 12),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.7",
+               .parent         = &exynos4_clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 13),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-hdmiphy-i2c",
+               .parent         = &exynos4_clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 14),
+       }, {
+               .name           = "SYSMMU_MDMA",
+               .enable         = exynos4_clk_ip_image_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "SYSMMU_FIMC0",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "SYSMMU_FIMC1",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "SYSMMU_FIMC2",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 9),
+       }, {
+               .name           = "SYSMMU_FIMC3",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 10),
+       }, {
+               .name           = "SYSMMU_JPEG",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 11),
+       }, {
+               .name           = "SYSMMU_FIMD0",
+               .enable         = exynos4_clk_ip_lcd0_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "SYSMMU_FIMD1",
+               .enable         = exynos4_clk_ip_lcd1_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "SYSMMU_PCIe",
+               .enable         = exynos4_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 18),
+       }, {
+               .name           = "SYSMMU_G2D",
+               .enable         = exynos4_clk_ip_image_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "SYSMMU_ROTATOR",
+               .enable         = exynos4_clk_ip_image_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "SYSMMU_TV",
+               .enable         = exynos4_clk_ip_tv_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "SYSMMU_MFC_L",
+               .enable         = exynos4_clk_ip_mfc_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "SYSMMU_MFC_R",
+               .enable         = exynos4_clk_ip_mfc_ctrl,
+               .ctrlbit        = (1 << 2),
+       }
+};
+
+static struct clk exynos4_init_clocks_on[] = {
+       {
+               .name           = "uart",
+               .devname        = "s5pv210-uart.0",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "uart",
+               .devname        = "s5pv210-uart.1",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "uart",
+               .devname        = "s5pv210-uart.2",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "uart",
+               .devname        = "s5pv210-uart.3",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "uart",
+               .devname        = "s5pv210-uart.4",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "uart",
+               .devname        = "s5pv210-uart.5",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 5),
+       }
+};
+
+static struct clk exynos4_clk_pdma0 = {
+       .name           = "dma",
+       .devname        = "dma-pl330.0",
+       .enable         = exynos4_clk_ip_fsys_ctrl,
+       .ctrlbit        = (1 << 0),
+};
+
+static struct clk exynos4_clk_pdma1 = {
+       .name           = "dma",
+       .devname        = "dma-pl330.1",
+       .enable         = exynos4_clk_ip_fsys_ctrl,
+       .ctrlbit        = (1 << 1),
+};
+
+static struct clk exynos4_clk_mdma1 = {
+       .name           = "dma",
+       .devname        = "dma-pl330.2",
+       .enable         = exynos4_clk_ip_image_ctrl,
+       .ctrlbit        = ((1 << 8) | (1 << 5) | (1 << 2)),
+};
+
+static struct clk exynos4_clk_fimd0 = {
+       .name           = "fimd",
+       .devname        = "exynos4-fb.0",
+       .enable         = exynos4_clk_ip_lcd0_ctrl,
+       .ctrlbit        = (1 << 0),
+};
+
+struct clk *exynos4_clkset_group_list[] = {
+       [0] = &clk_ext_xtal_mux,
+       [1] = &clk_xusbxti,
+       [2] = &exynos4_clk_sclk_hdmi27m,
+       [3] = &exynos4_clk_sclk_usbphy0,
+       [4] = &exynos4_clk_sclk_usbphy1,
+       [5] = &exynos4_clk_sclk_hdmiphy,
+       [6] = &exynos4_clk_mout_mpll.clk,
+       [7] = &exynos4_clk_mout_epll.clk,
+       [8] = &exynos4_clk_sclk_vpll.clk,
+};
+
+struct clksrc_sources exynos4_clkset_group = {
+       .sources        = exynos4_clkset_group_list,
+       .nr_sources     = ARRAY_SIZE(exynos4_clkset_group_list),
+};
+
+static struct clk *exynos4_clkset_mout_g2d0_list[] = {
+       [0] = &exynos4_clk_mout_mpll.clk,
+       [1] = &exynos4_clk_sclk_apll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_g2d0 = {
+       .sources        = exynos4_clkset_mout_g2d0_list,
+       .nr_sources     = ARRAY_SIZE(exynos4_clkset_mout_g2d0_list),
+};
+
+static struct clksrc_clk exynos4_clk_mout_g2d0 = {
+       .clk    = {
+               .name           = "mout_g2d0",
+       },
+       .sources = &exynos4_clkset_mout_g2d0,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_mout_g2d1_list[] = {
+       [0] = &exynos4_clk_mout_epll.clk,
+       [1] = &exynos4_clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_g2d1 = {
+       .sources        = exynos4_clkset_mout_g2d1_list,
+       .nr_sources     = ARRAY_SIZE(exynos4_clkset_mout_g2d1_list),
+};
+
+static struct clksrc_clk exynos4_clk_mout_g2d1 = {
+       .clk    = {
+               .name           = "mout_g2d1",
+       },
+       .sources = &exynos4_clkset_mout_g2d1,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 4, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_mout_g2d_list[] = {
+       [0] = &exynos4_clk_mout_g2d0.clk,
+       [1] = &exynos4_clk_mout_g2d1.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_g2d = {
+       .sources        = exynos4_clkset_mout_g2d_list,
+       .nr_sources     = ARRAY_SIZE(exynos4_clkset_mout_g2d_list),
+};
+
+static struct clk *exynos4_clkset_mout_mfc0_list[] = {
+       [0] = &exynos4_clk_mout_mpll.clk,
+       [1] = &exynos4_clk_sclk_apll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_mfc0 = {
+       .sources        = exynos4_clkset_mout_mfc0_list,
+       .nr_sources     = ARRAY_SIZE(exynos4_clkset_mout_mfc0_list),
+};
+
+static struct clksrc_clk exynos4_clk_mout_mfc0 = {
+       .clk    = {
+               .name           = "mout_mfc0",
+       },
+       .sources = &exynos4_clkset_mout_mfc0,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_mout_mfc1_list[] = {
+       [0] = &exynos4_clk_mout_epll.clk,
+       [1] = &exynos4_clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_mfc1 = {
+       .sources        = exynos4_clkset_mout_mfc1_list,
+       .nr_sources     = ARRAY_SIZE(exynos4_clkset_mout_mfc1_list),
+};
+
+static struct clksrc_clk exynos4_clk_mout_mfc1 = {
+       .clk    = {
+               .name           = "mout_mfc1",
+       },
+       .sources = &exynos4_clkset_mout_mfc1,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 4, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_mout_mfc_list[] = {
+       [0] = &exynos4_clk_mout_mfc0.clk,
+       [1] = &exynos4_clk_mout_mfc1.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_mfc = {
+       .sources        = exynos4_clkset_mout_mfc_list,
+       .nr_sources     = ARRAY_SIZE(exynos4_clkset_mout_mfc_list),
+};
+
+static struct clk *exynos4_clkset_sclk_dac_list[] = {
+       [0] = &exynos4_clk_sclk_vpll.clk,
+       [1] = &exynos4_clk_sclk_hdmiphy,
+};
+
+static struct clksrc_sources exynos4_clkset_sclk_dac = {
+       .sources        = exynos4_clkset_sclk_dac_list,
+       .nr_sources     = ARRAY_SIZE(exynos4_clkset_sclk_dac_list),
+};
+
+static struct clksrc_clk exynos4_clk_sclk_dac = {
+       .clk            = {
+               .name           = "sclk_dac",
+               .enable         = exynos4_clksrc_mask_tv_ctrl,
+               .ctrlbit        = (1 << 8),
+       },
+       .sources = &exynos4_clkset_sclk_dac,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 8, .size = 1 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_pixel = {
+       .clk            = {
+               .name           = "sclk_pixel",
+               .parent         = &exynos4_clk_sclk_vpll.clk,
+       },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_TV, .shift = 0, .size = 4 },
+};
+
+static struct clk *exynos4_clkset_sclk_hdmi_list[] = {
+       [0] = &exynos4_clk_sclk_pixel.clk,
+       [1] = &exynos4_clk_sclk_hdmiphy,
+};
+
+static struct clksrc_sources exynos4_clkset_sclk_hdmi = {
+       .sources        = exynos4_clkset_sclk_hdmi_list,
+       .nr_sources     = ARRAY_SIZE(exynos4_clkset_sclk_hdmi_list),
+};
+
+static struct clksrc_clk exynos4_clk_sclk_hdmi = {
+       .clk            = {
+               .name           = "sclk_hdmi",
+               .enable         = exynos4_clksrc_mask_tv_ctrl,
+               .ctrlbit        = (1 << 0),
+       },
+       .sources = &exynos4_clkset_sclk_hdmi,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_sclk_mixer_list[] = {
+       [0] = &exynos4_clk_sclk_dac.clk,
+       [1] = &exynos4_clk_sclk_hdmi.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_sclk_mixer = {
+       .sources        = exynos4_clkset_sclk_mixer_list,
+       .nr_sources     = ARRAY_SIZE(exynos4_clkset_sclk_mixer_list),
+};
+
+static struct clksrc_clk exynos4_clk_sclk_mixer = {
+       .clk    = {
+               .name           = "sclk_mixer",
+               .enable         = exynos4_clksrc_mask_tv_ctrl,
+               .ctrlbit        = (1 << 4),
+       },
+       .sources = &exynos4_clkset_sclk_mixer,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 4, .size = 1 },
+};
+
+static struct clksrc_clk *exynos4_sclk_tv[] = {
+       &exynos4_clk_sclk_dac,
+       &exynos4_clk_sclk_pixel,
+       &exynos4_clk_sclk_hdmi,
+       &exynos4_clk_sclk_mixer,
+};
+
+static struct clksrc_clk exynos4_clk_dout_mmc0 = {
+       .clk    = {
+               .name           = "dout_mmc0",
+       },
+       .sources = &exynos4_clkset_group,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 0, .size = 4 },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_dout_mmc1 = {
+       .clk    = {
+               .name           = "dout_mmc1",
+       },
+       .sources = &exynos4_clkset_group,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 4, .size = 4 },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_dout_mmc2 = {
+       .clk    = {
+               .name           = "dout_mmc2",
+       },
+       .sources = &exynos4_clkset_group,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 8, .size = 4 },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_dout_mmc3 = {
+       .clk    = {
+               .name           = "dout_mmc3",
+       },
+       .sources = &exynos4_clkset_group,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 12, .size = 4 },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_dout_mmc4 = {
+       .clk            = {
+               .name           = "dout_mmc4",
+       },
+       .sources = &exynos4_clkset_group,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 16, .size = 4 },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clksrcs[] = {
+       {
+               .clk    = {
+                       .name           = "sclk_pwm",
+                       .enable         = exynos4_clksrc_mask_peril0_ctrl,
+                       .ctrlbit        = (1 << 24),
+               },
+               .sources = &exynos4_clkset_group,
+               .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 24, .size = 4 },
+               .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL3, .shift = 0, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_csis",
+                       .devname        = "s5p-mipi-csis.0",
+                       .enable         = exynos4_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 24),
+               },
+               .sources = &exynos4_clkset_group,
+               .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 24, .size = 4 },
+               .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 24, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_csis",
+                       .devname        = "s5p-mipi-csis.1",
+                       .enable         = exynos4_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 28),
+               },
+               .sources = &exynos4_clkset_group,
+               .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 28, .size = 4 },
+               .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 28, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_cam0",
+                       .enable         = exynos4_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 16),
+               },
+               .sources = &exynos4_clkset_group,
+               .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 16, .size = 4 },
+               .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 16, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_cam1",
+                       .enable         = exynos4_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 20),
+               },
+               .sources = &exynos4_clkset_group,
+               .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 20, .size = 4 },
+               .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 20, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimc",
+                       .devname        = "exynos4-fimc.0",
+                       .enable         = exynos4_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 0),
+               },
+               .sources = &exynos4_clkset_group,
+               .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 0, .size = 4 },
+               .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 0, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimc",
+                       .devname        = "exynos4-fimc.1",
+                       .enable         = exynos4_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 4),
+               },
+               .sources = &exynos4_clkset_group,
+               .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 4, .size = 4 },
+               .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 4, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimc",
+                       .devname        = "exynos4-fimc.2",
+                       .enable         = exynos4_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 8),
+               },
+               .sources = &exynos4_clkset_group,
+               .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 8, .size = 4 },
+               .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 8, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimc",
+                       .devname        = "exynos4-fimc.3",
+                       .enable         = exynos4_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 12),
+               },
+               .sources = &exynos4_clkset_group,
+               .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 12, .size = 4 },
+               .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 12, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimd",
+                       .devname        = "exynos4-fb.0",
+                       .enable         = exynos4_clksrc_mask_lcd0_ctrl,
+                       .ctrlbit        = (1 << 0),
+               },
+               .sources = &exynos4_clkset_group,
+               .reg_src = { .reg = EXYNOS4_CLKSRC_LCD0, .shift = 0, .size = 4 },
+               .reg_div = { .reg = EXYNOS4_CLKDIV_LCD0, .shift = 0, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimg2d",
+               },
+               .sources = &exynos4_clkset_mout_g2d,
+               .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 8, .size = 1 },
+               .reg_div = { .reg = EXYNOS4_CLKDIV_IMAGE, .shift = 0, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_mfc",
+                       .devname        = "s5p-mfc",
+               },
+               .sources = &exynos4_clkset_mout_mfc,
+               .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 8, .size = 1 },
+               .reg_div = { .reg = EXYNOS4_CLKDIV_MFC, .shift = 0, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_dwmmc",
+                       .parent         = &exynos4_clk_dout_mmc4.clk,
+                       .enable         = exynos4_clksrc_mask_fsys_ctrl,
+                       .ctrlbit        = (1 << 16),
+               },
+               .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 8, .size = 8 },
+       }
+};
+
+static struct clksrc_clk exynos4_clk_sclk_uart0 = {
+       .clk    = {
+               .name           = "uclk1",
+               .devname        = "exynos4210-uart.0",
+               .enable         = exynos4_clksrc_mask_peril0_ctrl,
+               .ctrlbit        = (1 << 0),
+       },
+       .sources = &exynos4_clkset_group,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 0, .size = 4 },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_uart1 = {
+       .clk    = {
+               .name           = "uclk1",
+               .devname        = "exynos4210-uart.1",
+               .enable         = exynos4_clksrc_mask_peril0_ctrl,
+               .ctrlbit        = (1 << 4),
+       },
+       .sources = &exynos4_clkset_group,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 4, .size = 4 },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 4, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_uart2 = {
+       .clk    = {
+               .name           = "uclk1",
+               .devname        = "exynos4210-uart.2",
+               .enable         = exynos4_clksrc_mask_peril0_ctrl,
+               .ctrlbit        = (1 << 8),
+       },
+       .sources = &exynos4_clkset_group,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 8, .size = 4 },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_uart3 = {
+       .clk    = {
+               .name           = "uclk1",
+               .devname        = "exynos4210-uart.3",
+               .enable         = exynos4_clksrc_mask_peril0_ctrl,
+               .ctrlbit        = (1 << 12),
+       },
+       .sources = &exynos4_clkset_group,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 12, .size = 4 },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 12, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_mmc0 = {
+       .clk    = {
+               .name           = "sclk_mmc",
+               .devname        = "s3c-sdhci.0",
+               .parent         = &exynos4_clk_dout_mmc0.clk,
+               .enable         = exynos4_clksrc_mask_fsys_ctrl,
+               .ctrlbit        = (1 << 0),
+       },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 8, .size = 8 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_mmc1 = {
+       .clk    = {
+               .name           = "sclk_mmc",
+               .devname        = "s3c-sdhci.1",
+               .parent         = &exynos4_clk_dout_mmc1.clk,
+               .enable         = exynos4_clksrc_mask_fsys_ctrl,
+               .ctrlbit        = (1 << 4),
+       },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 24, .size = 8 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_mmc2 = {
+       .clk    = {
+               .name           = "sclk_mmc",
+               .devname        = "s3c-sdhci.2",
+               .parent         = &exynos4_clk_dout_mmc2.clk,
+               .enable         = exynos4_clksrc_mask_fsys_ctrl,
+               .ctrlbit        = (1 << 8),
+       },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 8, .size = 8 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_mmc3 = {
+       .clk    = {
+               .name           = "sclk_mmc",
+               .devname        = "s3c-sdhci.3",
+               .parent         = &exynos4_clk_dout_mmc3.clk,
+               .enable         = exynos4_clksrc_mask_fsys_ctrl,
+               .ctrlbit        = (1 << 12),
+       },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 24, .size = 8 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_spi0 = {
+       .clk    = {
+               .name           = "sclk_spi",
+               .devname        = "s3c64xx-spi.0",
+               .enable         = exynos4_clksrc_mask_peril1_ctrl,
+               .ctrlbit        = (1 << 16),
+       },
+       .sources = &exynos4_clkset_group,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 16, .size = 4 },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_spi1 = {
+       .clk    = {
+               .name           = "sclk_spi",
+               .devname        = "s3c64xx-spi.1",
+               .enable         = exynos4_clksrc_mask_peril1_ctrl,
+               .ctrlbit        = (1 << 20),
+       },
+       .sources = &exynos4_clkset_group,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 20, .size = 4 },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_spi2 = {
+       .clk    = {
+               .name           = "sclk_spi",
+               .devname        = "s3c64xx-spi.2",
+               .enable         = exynos4_clksrc_mask_peril1_ctrl,
+               .ctrlbit        = (1 << 24),
+       },
+       .sources = &exynos4_clkset_group,
+       .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 24, .size = 4 },
+       .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2, .shift = 0, .size = 4 },
+};
+
+/* Clock initialization code */
+static struct clksrc_clk *exynos4_sysclks[] = {
+       &exynos4_clk_mout_apll,
+       &exynos4_clk_sclk_apll,
+       &exynos4_clk_mout_epll,
+       &exynos4_clk_mout_mpll,
+       &exynos4_clk_moutcore,
+       &exynos4_clk_coreclk,
+       &exynos4_clk_armclk,
+       &exynos4_clk_aclk_corem0,
+       &exynos4_clk_aclk_cores,
+       &exynos4_clk_aclk_corem1,
+       &exynos4_clk_periphclk,
+       &exynos4_clk_mout_corebus,
+       &exynos4_clk_sclk_dmc,
+       &exynos4_clk_aclk_cored,
+       &exynos4_clk_aclk_corep,
+       &exynos4_clk_aclk_acp,
+       &exynos4_clk_pclk_acp,
+       &exynos4_clk_vpllsrc,
+       &exynos4_clk_sclk_vpll,
+       &exynos4_clk_aclk_200,
+       &exynos4_clk_aclk_100,
+       &exynos4_clk_aclk_160,
+       &exynos4_clk_aclk_133,
+       &exynos4_clk_dout_mmc0,
+       &exynos4_clk_dout_mmc1,
+       &exynos4_clk_dout_mmc2,
+       &exynos4_clk_dout_mmc3,
+       &exynos4_clk_dout_mmc4,
+       &exynos4_clk_mout_mfc0,
+       &exynos4_clk_mout_mfc1,
+};
+
+static struct clk *exynos4_clk_cdev[] = {
+       &exynos4_clk_pdma0,
+       &exynos4_clk_pdma1,
+       &exynos4_clk_mdma1,
+       &exynos4_clk_fimd0,
+};
+
+static struct clksrc_clk *exynos4_clksrc_cdev[] = {
+       &exynos4_clk_sclk_uart0,
+       &exynos4_clk_sclk_uart1,
+       &exynos4_clk_sclk_uart2,
+       &exynos4_clk_sclk_uart3,
+       &exynos4_clk_sclk_mmc0,
+       &exynos4_clk_sclk_mmc1,
+       &exynos4_clk_sclk_mmc2,
+       &exynos4_clk_sclk_mmc3,
+       &exynos4_clk_sclk_spi0,
+       &exynos4_clk_sclk_spi1,
+       &exynos4_clk_sclk_spi2,
+
+};
+
+static struct clk_lookup exynos4_clk_lookup[] = {
+       CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &exynos4_clk_sclk_uart0.clk),
+       CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos4_clk_sclk_uart1.clk),
+       CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos4_clk_sclk_uart2.clk),
+       CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos4_clk_sclk_uart3.clk),
+       CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &exynos4_clk_sclk_mmc0.clk),
+       CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &exynos4_clk_sclk_mmc1.clk),
+       CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &exynos4_clk_sclk_mmc2.clk),
+       CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &exynos4_clk_sclk_mmc3.clk),
+       CLKDEV_INIT("exynos4-fb.0", "lcd", &exynos4_clk_fimd0),
+       CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos4_clk_pdma0),
+       CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos4_clk_pdma1),
+       CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos4_clk_mdma1),
+       CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk0", &exynos4_clk_sclk_spi0.clk),
+       CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk0", &exynos4_clk_sclk_spi1.clk),
+       CLKDEV_INIT("s3c64xx-spi.2", "spi_busclk0", &exynos4_clk_sclk_spi2.clk),
+};
+
+static int xtal_rate;
+
+static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
+{
+       if (soc_is_exynos4210())
+               return s5p_get_pll45xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0),
+                                       pll_4508);
+       else if (soc_is_exynos4212() || soc_is_exynos4412())
+               return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0));
+       else
+               return 0;
+}
+
+static struct clk_ops exynos4_fout_apll_ops = {
+       .get_rate = exynos4_fout_apll_get_rate,
+};
+
+static u32 exynos4_vpll_div[][8] = {
+       {  54000000, 3, 53, 3, 1024, 0, 17, 0 },
+       { 108000000, 3, 53, 2, 1024, 0, 17, 0 },
+};
+
+static unsigned long exynos4_vpll_get_rate(struct clk *clk)
+{
+       return clk->rate;
+}
+
+static int exynos4_vpll_set_rate(struct clk *clk, unsigned long rate)
+{
+       unsigned int vpll_con0, vpll_con1 = 0;
+       unsigned int i;
+
+       /* Return if nothing changed */
+       if (clk->rate == rate)
+               return 0;
+
+       vpll_con0 = __raw_readl(EXYNOS4_VPLL_CON0);
+       vpll_con0 &= ~(0x1 << 27 |                                      \
+                       PLL90XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |       \
+                       PLL90XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |       \
+                       PLL90XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
+
+       vpll_con1 = __raw_readl(EXYNOS4_VPLL_CON1);
+       vpll_con1 &= ~(PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT |  \
+                       PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT | \
+                       PLL4650C_KDIV_MASK << PLL46XX_KDIV_SHIFT);
+
+       for (i = 0; i < ARRAY_SIZE(exynos4_vpll_div); i++) {
+               if (exynos4_vpll_div[i][0] == rate) {
+                       vpll_con0 |= exynos4_vpll_div[i][1] << PLL46XX_PDIV_SHIFT;
+                       vpll_con0 |= exynos4_vpll_div[i][2] << PLL46XX_MDIV_SHIFT;
+                       vpll_con0 |= exynos4_vpll_div[i][3] << PLL46XX_SDIV_SHIFT;
+                       vpll_con1 |= exynos4_vpll_div[i][4] << PLL46XX_KDIV_SHIFT;
+                       vpll_con1 |= exynos4_vpll_div[i][5] << PLL46XX_MFR_SHIFT;
+                       vpll_con1 |= exynos4_vpll_div[i][6] << PLL46XX_MRR_SHIFT;
+                       vpll_con0 |= exynos4_vpll_div[i][7] << 27;
+                       break;
+               }
+       }
+
+       if (i == ARRAY_SIZE(exynos4_vpll_div)) {
+               printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n",
+                               __func__);
+               return -EINVAL;
+       }
+
+       __raw_writel(vpll_con0, EXYNOS4_VPLL_CON0);
+       __raw_writel(vpll_con1, EXYNOS4_VPLL_CON1);
+
+       /* Wait for VPLL lock */
+       while (!(__raw_readl(EXYNOS4_VPLL_CON0) & (1 << PLL46XX_LOCKED_SHIFT)))
+               continue;
+
+       clk->rate = rate;
+       return 0;
+}
+
+static struct clk_ops exynos4_vpll_ops = {
+       .get_rate = exynos4_vpll_get_rate,
+       .set_rate = exynos4_vpll_set_rate,
+};
+
+void __init_or_cpufreq exynos4_setup_clocks(void)
+{
+       struct clk *xtal_clk;
+       unsigned long apll = 0;
+       unsigned long mpll = 0;
+       unsigned long epll = 0;
+       unsigned long vpll = 0;
+       unsigned long vpllsrc;
+       unsigned long xtal;
+       unsigned long armclk;
+       unsigned long sclk_dmc;
+       unsigned long aclk_200;
+       unsigned long aclk_100;
+       unsigned long aclk_160;
+       unsigned long aclk_133;
+       unsigned int ptr;
+
+       printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+
+       xtal_clk = clk_get(NULL, "xtal");
+       BUG_ON(IS_ERR(xtal_clk));
+
+       xtal = clk_get_rate(xtal_clk);
+
+       xtal_rate = xtal;
+
+       clk_put(xtal_clk);
+
+       printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+
+       if (soc_is_exynos4210()) {
+               apll = s5p_get_pll45xx(xtal, __raw_readl(EXYNOS4_APLL_CON0),
+                                       pll_4508);
+               mpll = s5p_get_pll45xx(xtal, __raw_readl(EXYNOS4_MPLL_CON0),
+                                       pll_4508);
+               epll = s5p_get_pll46xx(xtal, __raw_readl(EXYNOS4_EPLL_CON0),
+                                       __raw_readl(EXYNOS4_EPLL_CON1), pll_4600);
+
+               vpllsrc = clk_get_rate(&exynos4_clk_vpllsrc.clk);
+               vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(EXYNOS4_VPLL_CON0),
+                                       __raw_readl(EXYNOS4_VPLL_CON1), pll_4650c);
+       } else if (soc_is_exynos4212() || soc_is_exynos4412()) {
+               apll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS4_APLL_CON0));
+               mpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS4_MPLL_CON0));
+               epll = s5p_get_pll36xx(xtal, __raw_readl(EXYNOS4_EPLL_CON0),
+                                       __raw_readl(EXYNOS4_EPLL_CON1));
+
+               vpllsrc = clk_get_rate(&exynos4_clk_vpllsrc.clk);
+               vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(EXYNOS4_VPLL_CON0),
+                                       __raw_readl(EXYNOS4_VPLL_CON1));
+       } else {
+               /* nothing */
+       }
+
+       clk_fout_apll.ops = &exynos4_fout_apll_ops;
+       clk_fout_mpll.rate = mpll;
+       clk_fout_epll.rate = epll;
+       clk_fout_vpll.ops = &exynos4_vpll_ops;
+       clk_fout_vpll.rate = vpll;
+
+       printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
+                       apll, mpll, epll, vpll);
+
+       armclk = clk_get_rate(&exynos4_clk_armclk.clk);
+       sclk_dmc = clk_get_rate(&exynos4_clk_sclk_dmc.clk);
+
+       aclk_200 = clk_get_rate(&exynos4_clk_aclk_200.clk);
+       aclk_100 = clk_get_rate(&exynos4_clk_aclk_100.clk);
+       aclk_160 = clk_get_rate(&exynos4_clk_aclk_160.clk);
+       aclk_133 = clk_get_rate(&exynos4_clk_aclk_133.clk);
+
+       printk(KERN_INFO "EXYNOS4: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
+                        "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
+                       armclk, sclk_dmc, aclk_200,
+                       aclk_100, aclk_160, aclk_133);
+
+       clk_f.rate = armclk;
+       clk_h.rate = sclk_dmc;
+       clk_p.rate = aclk_100;
+
+       for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clksrcs); ptr++)
+               s3c_set_clksrc(&exynos4_clksrcs[ptr], true);
+}
+
+static struct clk *exynos4_clks[] __initdata = {
+       &exynos4_clk_sclk_hdmi27m,
+       &exynos4_clk_sclk_hdmiphy,
+       &exynos4_clk_sclk_usbphy0,
+       &exynos4_clk_sclk_usbphy1,
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int exynos4_clock_suspend(void)
+{
+       s3c_pm_do_save(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
+       return 0;
+}
+
+static void exynos4_clock_resume(void)
+{
+       s3c_pm_do_restore_core(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
+}
+
+#else
+#define exynos4_clock_suspend NULL
+#define exynos4_clock_resume NULL
+#endif
+
+static struct syscore_ops exynos4_clock_syscore_ops = {
+       .suspend        = exynos4_clock_suspend,
+       .resume         = exynos4_clock_resume,
+};
+
+void __init exynos4_register_clocks(void)
+{
+       int ptr;
+
+       s3c24xx_register_clocks(exynos4_clks, ARRAY_SIZE(exynos4_clks));
+
+       for (ptr = 0; ptr < ARRAY_SIZE(exynos4_sysclks); ptr++)
+               s3c_register_clksrc(exynos4_sysclks[ptr], 1);
+
+       for (ptr = 0; ptr < ARRAY_SIZE(exynos4_sclk_tv); ptr++)
+               s3c_register_clksrc(exynos4_sclk_tv[ptr], 1);
+
+       for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clksrc_cdev); ptr++)
+               s3c_register_clksrc(exynos4_clksrc_cdev[ptr], 1);
+
+       s3c_register_clksrc(exynos4_clksrcs, ARRAY_SIZE(exynos4_clksrcs));
+       s3c_register_clocks(exynos4_init_clocks_on, ARRAY_SIZE(exynos4_init_clocks_on));
+
+       s3c24xx_register_clocks(exynos4_clk_cdev, ARRAY_SIZE(exynos4_clk_cdev));
+       for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clk_cdev); ptr++)
+               s3c_disable_clocks(exynos4_clk_cdev[ptr], 1);
+
+       s3c_register_clocks(exynos4_init_clocks_off, ARRAY_SIZE(exynos4_init_clocks_off));
+       s3c_disable_clocks(exynos4_init_clocks_off, ARRAY_SIZE(exynos4_init_clocks_off));
+       clkdev_add_table(exynos4_clk_lookup, ARRAY_SIZE(exynos4_clk_lookup));
+
+       register_syscore_ops(&exynos4_clock_syscore_ops);
+       s3c24xx_register_clock(&dummy_apb_pclk);
+
+       s3c_pwmclk_init();
+}
diff --git a/arch/arm/mach-exynos/clock-exynos4.h b/arch/arm/mach-exynos/clock-exynos4.h
new file mode 100644 (file)
index 0000000..cb71c29
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Header file for exynos4 clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_CLOCK_H
+#define __ASM_ARCH_CLOCK_H __FILE__
+
+#include <linux/clk.h>
+
+extern struct clksrc_clk exynos4_clk_aclk_133;
+extern struct clksrc_clk exynos4_clk_mout_mpll;
+
+extern struct clksrc_sources exynos4_clkset_mout_corebus;
+extern struct clksrc_sources exynos4_clkset_group;
+
+extern struct clk *exynos4_clkset_aclk_top_list[];
+extern struct clk *exynos4_clkset_group_list[];
+
+extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable);
+extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable);
+extern int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable);
+
+#endif /* __ASM_ARCH_CLOCK_H */
index 13312ccb2d9366f30e1295d403e0212c4f6b3e24..3b131e4b6ef57ec6e21428a640f4ad092f27e2fb 100644 (file)
@@ -1,7 +1,5 @@
 /*
- * linux/arch/arm/mach-exynos4/clock-exynos4210.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
  *
  * EXYNOS4210 - Clock support
 #include <mach/hardware.h>
 #include <mach/map.h>
 #include <mach/regs-clock.h>
-#include <mach/exynos4-clock.h>
 
 #include "common.h"
+#include "clock-exynos4.h"
 
 #ifdef CONFIG_PM_SLEEP
 static struct sleep_save exynos4210_clock_save[] = {
-       SAVE_ITEM(S5P_CLKSRC_IMAGE),
-       SAVE_ITEM(S5P_CLKSRC_LCD1),
-       SAVE_ITEM(S5P_CLKDIV_IMAGE),
-       SAVE_ITEM(S5P_CLKDIV_LCD1),
-       SAVE_ITEM(S5P_CLKSRC_MASK_LCD1),
-       SAVE_ITEM(S5P_CLKGATE_IP_IMAGE_4210),
-       SAVE_ITEM(S5P_CLKGATE_IP_LCD1),
-       SAVE_ITEM(S5P_CLKGATE_IP_PERIR_4210),
+       SAVE_ITEM(EXYNOS4_CLKSRC_IMAGE),
+       SAVE_ITEM(EXYNOS4_CLKDIV_IMAGE),
+       SAVE_ITEM(EXYNOS4210_CLKSRC_LCD1),
+       SAVE_ITEM(EXYNOS4210_CLKDIV_LCD1),
+       SAVE_ITEM(EXYNOS4210_CLKSRC_MASK_LCD1),
+       SAVE_ITEM(EXYNOS4210_CLKGATE_IP_IMAGE),
+       SAVE_ITEM(EXYNOS4210_CLKGATE_IP_LCD1),
+       SAVE_ITEM(EXYNOS4210_CLKGATE_IP_PERIR),
 };
 #endif
 
@@ -51,7 +49,7 @@ static struct clksrc_clk *sysclks[] = {
 
 static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
 {
-       return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable);
+       return s5p_gatectrl(EXYNOS4210_CLKSRC_MASK_LCD1, clk, enable);
 }
 
 static struct clksrc_clk clksrcs[] = {
@@ -62,9 +60,9 @@ static struct clksrc_clk clksrcs[] = {
                        .enable         = exynos4_clksrc_mask_fsys_ctrl,
                        .ctrlbit        = (1 << 24),
                },
-               .sources = &clkset_mout_corebus,
-               .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 },
-               .reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 },
+               .sources = &exynos4_clkset_mout_corebus,
+               .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 24, .size = 1 },
+               .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS0, .shift = 20, .size = 4 },
        }, {
                .clk            = {
                        .name           = "sclk_fimd",
@@ -72,9 +70,9 @@ static struct clksrc_clk clksrcs[] = {
                        .enable         = exynos4_clksrc_mask_lcd1_ctrl,
                        .ctrlbit        = (1 << 0),
                },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 },
+               .sources = &exynos4_clkset_group,
+               .reg_src = { .reg = EXYNOS4210_CLKSRC_LCD1, .shift = 0, .size = 4 },
+               .reg_div = { .reg = EXYNOS4210_CLKDIV_LCD1, .shift = 0, .size = 4 },
        },
 };
 
@@ -82,13 +80,13 @@ static struct clk init_clocks_off[] = {
        {
                .name           = "sataphy",
                .id             = -1,
-               .parent         = &clk_aclk_133.clk,
+               .parent         = &exynos4_clk_aclk_133.clk,
                .enable         = exynos4_clk_ip_fsys_ctrl,
                .ctrlbit        = (1 << 3),
        }, {
                .name           = "sata",
                .id             = -1,
-               .parent         = &clk_aclk_133.clk,
+               .parent         = &exynos4_clk_aclk_133.clk,
                .enable         = exynos4_clk_ip_fsys_ctrl,
                .ctrlbit        = (1 << 10),
        }, {
@@ -117,7 +115,7 @@ static void exynos4210_clock_resume(void)
 #define exynos4210_clock_resume NULL
 #endif
 
-struct syscore_ops exynos4210_clock_syscore_ops = {
+static struct syscore_ops exynos4210_clock_syscore_ops = {
        .suspend        = exynos4210_clock_suspend,
        .resume         = exynos4210_clock_resume,
 };
@@ -126,9 +124,9 @@ void __init exynos4210_register_clocks(void)
 {
        int ptr;
 
-       clk_mout_mpll.reg_src.reg = S5P_CLKSRC_CPU;
-       clk_mout_mpll.reg_src.shift = 8;
-       clk_mout_mpll.reg_src.size = 1;
+       exynos4_clk_mout_mpll.reg_src.reg = EXYNOS4_CLKSRC_CPU;
+       exynos4_clk_mout_mpll.reg_src.shift = 8;
+       exynos4_clk_mout_mpll.reg_src.size = 1;
 
        for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
                s3c_register_clksrc(sysclks[ptr], 1);
index 48af28566fa168703083ed900c7fc8a2a9701998..3ecc01e06f7497c1408f795023bdf78dba8de7bb 100644 (file)
@@ -1,7 +1,5 @@
 /*
- * linux/arch/arm/mach-exynos4/clock-exynos4212.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
  *
  * EXYNOS4212 - Clock support
 #include <mach/hardware.h>
 #include <mach/map.h>
 #include <mach/regs-clock.h>
-#include <mach/exynos4-clock.h>
 
 #include "common.h"
+#include "clock-exynos4.h"
 
 #ifdef CONFIG_PM_SLEEP
 static struct sleep_save exynos4212_clock_save[] = {
-       SAVE_ITEM(S5P_CLKSRC_IMAGE),
-       SAVE_ITEM(S5P_CLKDIV_IMAGE),
-       SAVE_ITEM(S5P_CLKGATE_IP_IMAGE_4212),
-       SAVE_ITEM(S5P_CLKGATE_IP_PERIR_4212),
+       SAVE_ITEM(EXYNOS4_CLKSRC_IMAGE),
+       SAVE_ITEM(EXYNOS4_CLKDIV_IMAGE),
+       SAVE_ITEM(EXYNOS4212_CLKGATE_IP_IMAGE),
+       SAVE_ITEM(EXYNOS4212_CLKGATE_IP_PERIR),
 };
 #endif
 
 static struct clk *clk_src_mpll_user_list[] = {
        [0] = &clk_fin_mpll,
-       [1] = &clk_mout_mpll.clk,
+       [1] = &exynos4_clk_mout_mpll.clk,
 };
 
 static struct clksrc_sources clk_src_mpll_user = {
@@ -56,7 +54,7 @@ static struct clksrc_clk clk_mout_mpll_user = {
                .name           = "mout_mpll_user",
        },
        .sources        = &clk_src_mpll_user,
-       .reg_src        = { .reg = S5P_CLKSRC_CPU, .shift = 24, .size = 1 },
+       .reg_src        = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 24, .size = 1 },
 };
 
 static struct clksrc_clk *sysclks[] = {
@@ -89,7 +87,7 @@ static void exynos4212_clock_resume(void)
 #define exynos4212_clock_resume NULL
 #endif
 
-struct syscore_ops exynos4212_clock_syscore_ops = {
+static struct syscore_ops exynos4212_clock_syscore_ops = {
        .suspend        = exynos4212_clock_suspend,
        .resume         = exynos4212_clock_resume,
 };
@@ -99,15 +97,15 @@ void __init exynos4212_register_clocks(void)
        int ptr;
 
        /* usbphy1 is removed */
-       clkset_group_list[4] = NULL;
+       exynos4_clkset_group_list[4] = NULL;
 
        /* mout_mpll_user is used */
-       clkset_group_list[6] = &clk_mout_mpll_user.clk;
-       clkset_aclk_top_list[0] = &clk_mout_mpll_user.clk;
+       exynos4_clkset_group_list[6] = &clk_mout_mpll_user.clk;
+       exynos4_clkset_aclk_top_list[0] = &clk_mout_mpll_user.clk;
 
-       clk_mout_mpll.reg_src.reg = S5P_CLKSRC_DMC;
-       clk_mout_mpll.reg_src.shift = 12;
-       clk_mout_mpll.reg_src.size = 1;
+       exynos4_clk_mout_mpll.reg_src.reg = EXYNOS4_CLKSRC_DMC;
+       exynos4_clk_mout_mpll.reg_src.shift = 12;
+       exynos4_clk_mout_mpll.reg_src.size = 1;
 
        for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
                s3c_register_clksrc(sysclks[ptr], 1);
diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c
new file mode 100644 (file)
index 0000000..d013982
--- /dev/null
@@ -0,0 +1,1247 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Clock support for EXYNOS5 SoCs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/pm.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/sysmmu.h>
+
+#include "common.h"
+
+#ifdef CONFIG_PM_SLEEP
+static struct sleep_save exynos5_clock_save[] = {
+       /* will be implemented */
+};
+#endif
+
+static struct clk exynos5_clk_sclk_dptxphy = {
+       .name           = "sclk_dptx",
+};
+
+static struct clk exynos5_clk_sclk_hdmi24m = {
+       .name           = "sclk_hdmi24m",
+       .rate           = 24000000,
+};
+
+static struct clk exynos5_clk_sclk_hdmi27m = {
+       .name           = "sclk_hdmi27m",
+       .rate           = 27000000,
+};
+
+static struct clk exynos5_clk_sclk_hdmiphy = {
+       .name           = "sclk_hdmiphy",
+};
+
+static struct clk exynos5_clk_sclk_usbphy = {
+       .name           = "sclk_usbphy",
+       .rate           = 48000000,
+};
+
+static int exynos5_clksrc_mask_top_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_TOP, clk, enable);
+}
+
+static int exynos5_clksrc_mask_disp1_0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_DISP1_0, clk, enable);
+}
+
+static int exynos5_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_FSYS, clk, enable);
+}
+
+static int exynos5_clksrc_mask_gscl_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_GSCL, clk, enable);
+}
+
+static int exynos5_clksrc_mask_peric0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_PERIC0, clk, enable);
+}
+
+static int exynos5_clk_ip_core_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_CORE, clk, enable);
+}
+
+static int exynos5_clk_ip_disp1_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_DISP1, clk, enable);
+}
+
+static int exynos5_clk_ip_fsys_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_FSYS, clk, enable);
+}
+
+static int exynos5_clk_block_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS5_CLKGATE_BLOCK, clk, enable);
+}
+
+static int exynos5_clk_ip_gen_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GEN, clk, enable);
+}
+
+static int exynos5_clk_ip_gps_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GPS, clk, enable);
+}
+
+static int exynos5_clk_ip_mfc_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_MFC, clk, enable);
+}
+
+static int exynos5_clk_ip_peric_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIC, clk, enable);
+}
+
+static int exynos5_clk_ip_peris_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIS, clk, enable);
+}
+
+/* Core list of CMU_CPU side */
+
+static struct clksrc_clk exynos5_clk_mout_apll = {
+       .clk    = {
+               .name           = "mout_apll",
+       },
+       .sources = &clk_src_apll,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_CPU, .shift = 0, .size = 1 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_apll = {
+       .clk    = {
+               .name           = "sclk_apll",
+               .parent         = &exynos5_clk_mout_apll.clk,
+       },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 24, .size = 3 },
+};
+
+static struct clksrc_clk exynos5_clk_mout_bpll = {
+       .clk    = {
+               .name           = "mout_bpll",
+       },
+       .sources = &clk_src_bpll,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos5_clk_src_bpll_user_list[] = {
+       [0] = &clk_fin_mpll,
+       [1] = &exynos5_clk_mout_bpll.clk,
+};
+
+static struct clksrc_sources exynos5_clk_src_bpll_user = {
+       .sources        = exynos5_clk_src_bpll_user_list,
+       .nr_sources     = ARRAY_SIZE(exynos5_clk_src_bpll_user_list),
+};
+
+static struct clksrc_clk exynos5_clk_mout_bpll_user = {
+       .clk    = {
+               .name           = "mout_bpll_user",
+       },
+       .sources = &exynos5_clk_src_bpll_user,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 24, .size = 1 },
+};
+
+static struct clksrc_clk exynos5_clk_mout_cpll = {
+       .clk    = {
+               .name           = "mout_cpll",
+       },
+       .sources = &clk_src_cpll,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 8, .size = 1 },
+};
+
+static struct clksrc_clk exynos5_clk_mout_epll = {
+       .clk    = {
+               .name           = "mout_epll",
+       },
+       .sources = &clk_src_epll,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 12, .size = 1 },
+};
+
+struct clksrc_clk exynos5_clk_mout_mpll = {
+       .clk = {
+               .name           = "mout_mpll",
+       },
+       .sources = &clk_src_mpll,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_CORE1, .shift = 8, .size = 1 },
+};
+
+static struct clk *exynos_clkset_vpllsrc_list[] = {
+       [0] = &clk_fin_vpll,
+       [1] = &exynos5_clk_sclk_hdmi27m,
+};
+
+static struct clksrc_sources exynos5_clkset_vpllsrc = {
+       .sources        = exynos_clkset_vpllsrc_list,
+       .nr_sources     = ARRAY_SIZE(exynos_clkset_vpllsrc_list),
+};
+
+static struct clksrc_clk exynos5_clk_vpllsrc = {
+       .clk    = {
+               .name           = "vpll_src",
+               .enable         = exynos5_clksrc_mask_top_ctrl,
+               .ctrlbit        = (1 << 0),
+       },
+       .sources = &exynos5_clkset_vpllsrc,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos5_clkset_sclk_vpll_list[] = {
+       [0] = &exynos5_clk_vpllsrc.clk,
+       [1] = &clk_fout_vpll,
+};
+
+static struct clksrc_sources exynos5_clkset_sclk_vpll = {
+       .sources        = exynos5_clkset_sclk_vpll_list,
+       .nr_sources     = ARRAY_SIZE(exynos5_clkset_sclk_vpll_list),
+};
+
+static struct clksrc_clk exynos5_clk_sclk_vpll = {
+       .clk    = {
+               .name           = "sclk_vpll",
+       },
+       .sources = &exynos5_clkset_sclk_vpll,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 16, .size = 1 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_pixel = {
+       .clk    = {
+               .name           = "sclk_pixel",
+               .parent         = &exynos5_clk_sclk_vpll.clk,
+       },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_DISP1_0, .shift = 28, .size = 4 },
+};
+
+static struct clk *exynos5_clkset_sclk_hdmi_list[] = {
+       [0] = &exynos5_clk_sclk_pixel.clk,
+       [1] = &exynos5_clk_sclk_hdmiphy,
+};
+
+static struct clksrc_sources exynos5_clkset_sclk_hdmi = {
+       .sources        = exynos5_clkset_sclk_hdmi_list,
+       .nr_sources     = ARRAY_SIZE(exynos5_clkset_sclk_hdmi_list),
+};
+
+static struct clksrc_clk exynos5_clk_sclk_hdmi = {
+       .clk    = {
+               .name           = "sclk_hdmi",
+               .enable         = exynos5_clksrc_mask_disp1_0_ctrl,
+               .ctrlbit        = (1 << 20),
+       },
+       .sources = &exynos5_clkset_sclk_hdmi,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_DISP1_0, .shift = 20, .size = 1 },
+};
+
+static struct clksrc_clk *exynos5_sclk_tv[] = {
+       &exynos5_clk_sclk_pixel,
+       &exynos5_clk_sclk_hdmi,
+};
+
+static struct clk *exynos5_clk_src_mpll_user_list[] = {
+       [0] = &clk_fin_mpll,
+       [1] = &exynos5_clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources exynos5_clk_src_mpll_user = {
+       .sources        = exynos5_clk_src_mpll_user_list,
+       .nr_sources     = ARRAY_SIZE(exynos5_clk_src_mpll_user_list),
+};
+
+static struct clksrc_clk exynos5_clk_mout_mpll_user = {
+       .clk    = {
+               .name           = "mout_mpll_user",
+       },
+       .sources = &exynos5_clk_src_mpll_user,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 20, .size = 1 },
+};
+
+static struct clk *exynos5_clkset_mout_cpu_list[] = {
+       [0] = &exynos5_clk_mout_apll.clk,
+       [1] = &exynos5_clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources exynos5_clkset_mout_cpu = {
+       .sources        = exynos5_clkset_mout_cpu_list,
+       .nr_sources     = ARRAY_SIZE(exynos5_clkset_mout_cpu_list),
+};
+
+static struct clksrc_clk exynos5_clk_mout_cpu = {
+       .clk    = {
+               .name           = "mout_cpu",
+       },
+       .sources = &exynos5_clkset_mout_cpu,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_CPU, .shift = 16, .size = 1 },
+};
+
+static struct clksrc_clk exynos5_clk_dout_armclk = {
+       .clk    = {
+               .name           = "dout_armclk",
+               .parent         = &exynos5_clk_mout_cpu.clk,
+       },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk exynos5_clk_dout_arm2clk = {
+       .clk    = {
+               .name           = "dout_arm2clk",
+               .parent         = &exynos5_clk_dout_armclk.clk,
+       },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 28, .size = 3 },
+};
+
+static struct clk exynos5_clk_armclk = {
+       .name           = "armclk",
+       .parent         = &exynos5_clk_dout_arm2clk.clk,
+};
+
+/* Core list of CMU_CDREX side */
+
+static struct clk *exynos5_clkset_cdrex_list[] = {
+       [0] = &exynos5_clk_mout_mpll.clk,
+       [1] = &exynos5_clk_mout_bpll.clk,
+};
+
+static struct clksrc_sources exynos5_clkset_cdrex = {
+       .sources        = exynos5_clkset_cdrex_list,
+       .nr_sources     = ARRAY_SIZE(exynos5_clkset_cdrex_list),
+};
+
+static struct clksrc_clk exynos5_clk_cdrex = {
+       .clk    = {
+               .name           = "clk_cdrex",
+       },
+       .sources = &exynos5_clkset_cdrex,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 4, .size = 1 },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_CDREX, .shift = 16, .size = 3 },
+};
+
+static struct clksrc_clk exynos5_clk_aclk_acp = {
+       .clk    = {
+               .name           = "aclk_acp",
+               .parent         = &exynos5_clk_mout_mpll.clk,
+       },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_ACP, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk exynos5_clk_pclk_acp = {
+       .clk    = {
+               .name           = "pclk_acp",
+               .parent         = &exynos5_clk_aclk_acp.clk,
+       },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_ACP, .shift = 4, .size = 3 },
+};
+
+/* Core list of CMU_TOP side */
+
+struct clk *exynos5_clkset_aclk_top_list[] = {
+       [0] = &exynos5_clk_mout_mpll_user.clk,
+       [1] = &exynos5_clk_mout_bpll_user.clk,
+};
+
+struct clksrc_sources exynos5_clkset_aclk = {
+       .sources        = exynos5_clkset_aclk_top_list,
+       .nr_sources     = ARRAY_SIZE(exynos5_clkset_aclk_top_list),
+};
+
+static struct clksrc_clk exynos5_clk_aclk_400 = {
+       .clk    = {
+               .name           = "aclk_400",
+       },
+       .sources = &exynos5_clkset_aclk,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 20, .size = 1 },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 },
+};
+
+struct clk *exynos5_clkset_aclk_333_166_list[] = {
+       [0] = &exynos5_clk_mout_cpll.clk,
+       [1] = &exynos5_clk_mout_mpll_user.clk,
+};
+
+struct clksrc_sources exynos5_clkset_aclk_333_166 = {
+       .sources        = exynos5_clkset_aclk_333_166_list,
+       .nr_sources     = ARRAY_SIZE(exynos5_clkset_aclk_333_166_list),
+};
+
+static struct clksrc_clk exynos5_clk_aclk_333 = {
+       .clk    = {
+               .name           = "aclk_333",
+       },
+       .sources = &exynos5_clkset_aclk_333_166,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 16, .size = 1 },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 20, .size = 3 },
+};
+
+static struct clksrc_clk exynos5_clk_aclk_166 = {
+       .clk    = {
+               .name           = "aclk_166",
+       },
+       .sources = &exynos5_clkset_aclk_333_166,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 8, .size = 1 },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 8, .size = 3 },
+};
+
+static struct clksrc_clk exynos5_clk_aclk_266 = {
+       .clk    = {
+               .name           = "aclk_266",
+               .parent         = &exynos5_clk_mout_mpll_user.clk,
+       },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 16, .size = 3 },
+};
+
+static struct clksrc_clk exynos5_clk_aclk_200 = {
+       .clk    = {
+               .name           = "aclk_200",
+       },
+       .sources = &exynos5_clkset_aclk,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 12, .size = 1 },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 12, .size = 3 },
+};
+
+static struct clksrc_clk exynos5_clk_aclk_66_pre = {
+       .clk    = {
+               .name           = "aclk_66_pre",
+               .parent         = &exynos5_clk_mout_mpll_user.clk,
+       },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_TOP1, .shift = 24, .size = 3 },
+};
+
+static struct clksrc_clk exynos5_clk_aclk_66 = {
+       .clk    = {
+               .name           = "aclk_66",
+               .parent         = &exynos5_clk_aclk_66_pre.clk,
+       },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 0, .size = 3 },
+};
+
+static struct clk exynos5_init_clocks_off[] = {
+       {
+               .name           = "timers",
+               .parent         = &exynos5_clk_aclk_66.clk,
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 24),
+       }, {
+               .name           = "rtc",
+               .parent         = &exynos5_clk_aclk_66.clk,
+               .enable         = exynos5_clk_ip_peris_ctrl,
+               .ctrlbit        = (1 << 20),
+       }, {
+               .name           = "hsmmc",
+               .devname        = "s3c-sdhci.0",
+               .parent         = &exynos5_clk_aclk_200.clk,
+               .enable         = exynos5_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 12),
+       }, {
+               .name           = "hsmmc",
+               .devname        = "s3c-sdhci.1",
+               .parent         = &exynos5_clk_aclk_200.clk,
+               .enable         = exynos5_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 13),
+       }, {
+               .name           = "hsmmc",
+               .devname        = "s3c-sdhci.2",
+               .parent         = &exynos5_clk_aclk_200.clk,
+               .enable         = exynos5_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 14),
+       }, {
+               .name           = "hsmmc",
+               .devname        = "s3c-sdhci.3",
+               .parent         = &exynos5_clk_aclk_200.clk,
+               .enable         = exynos5_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 15),
+       }, {
+               .name           = "dwmci",
+               .parent         = &exynos5_clk_aclk_200.clk,
+               .enable         = exynos5_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 16),
+       }, {
+               .name           = "sata",
+               .devname        = "ahci",
+               .enable         = exynos5_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "sata_phy",
+               .enable         = exynos5_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 24),
+       }, {
+               .name           = "sata_phy_i2c",
+               .enable         = exynos5_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 25),
+       }, {
+               .name           = "mfc",
+               .devname        = "s5p-mfc",
+               .enable         = exynos5_clk_ip_mfc_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "hdmi",
+               .devname        = "exynos4-hdmi",
+               .enable         = exynos5_clk_ip_disp1_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "mixer",
+               .devname        = "s5p-mixer",
+               .enable         = exynos5_clk_ip_disp1_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "jpeg",
+               .enable         = exynos5_clk_ip_gen_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "dsim0",
+               .enable         = exynos5_clk_ip_disp1_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "iis",
+               .devname        = "samsung-i2s.1",
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 20),
+       }, {
+               .name           = "iis",
+               .devname        = "samsung-i2s.2",
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 21),
+       }, {
+               .name           = "pcm",
+               .devname        = "samsung-pcm.1",
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 22),
+       }, {
+               .name           = "pcm",
+               .devname        = "samsung-pcm.2",
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 23),
+       }, {
+               .name           = "spdif",
+               .devname        = "samsung-spdif",
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 26),
+       }, {
+               .name           = "ac97",
+               .devname        = "samsung-ac97",
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 27),
+       }, {
+               .name           = "usbhost",
+               .enable         = exynos5_clk_ip_fsys_ctrl ,
+               .ctrlbit        = (1 << 18),
+       }, {
+               .name           = "usbotg",
+               .enable         = exynos5_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "gps",
+               .enable         = exynos5_clk_ip_gps_ctrl,
+               .ctrlbit        = ((1 << 3) | (1 << 2) | (1 << 0)),
+       }, {
+               .name           = "nfcon",
+               .enable         = exynos5_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 22),
+       }, {
+               .name           = "iop",
+               .enable         = exynos5_clk_ip_fsys_ctrl,
+               .ctrlbit        = ((1 << 30) | (1 << 26) | (1 << 23)),
+       }, {
+               .name           = "core_iop",
+               .enable         = exynos5_clk_ip_core_ctrl,
+               .ctrlbit        = ((1 << 21) | (1 << 3)),
+       }, {
+               .name           = "mcu_iop",
+               .enable         = exynos5_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.0",
+               .parent         = &exynos5_clk_aclk_66.clk,
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.1",
+               .parent         = &exynos5_clk_aclk_66.clk,
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.2",
+               .parent         = &exynos5_clk_aclk_66.clk,
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.3",
+               .parent         = &exynos5_clk_aclk_66.clk,
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 9),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.4",
+               .parent         = &exynos5_clk_aclk_66.clk,
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 10),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.5",
+               .parent         = &exynos5_clk_aclk_66.clk,
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 11),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.6",
+               .parent         = &exynos5_clk_aclk_66.clk,
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 12),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.7",
+               .parent         = &exynos5_clk_aclk_66.clk,
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 13),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-hdmiphy-i2c",
+               .parent         = &exynos5_clk_aclk_66.clk,
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 14),
+       }
+};
+
+static struct clk exynos5_init_clocks_on[] = {
+       {
+               .name           = "uart",
+               .devname        = "s5pv210-uart.0",
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "uart",
+               .devname        = "s5pv210-uart.1",
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "uart",
+               .devname        = "s5pv210-uart.2",
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "uart",
+               .devname        = "s5pv210-uart.3",
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "uart",
+               .devname        = "s5pv210-uart.4",
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "uart",
+               .devname        = "s5pv210-uart.5",
+               .enable         = exynos5_clk_ip_peric_ctrl,
+               .ctrlbit        = (1 << 5),
+       }
+};
+
+static struct clk exynos5_clk_pdma0 = {
+       .name           = "dma",
+       .devname        = "dma-pl330.0",
+       .enable         = exynos5_clk_ip_fsys_ctrl,
+       .ctrlbit        = (1 << 1),
+};
+
+static struct clk exynos5_clk_pdma1 = {
+       .name           = "dma",
+       .devname        = "dma-pl330.1",
+       .enable         = exynos5_clk_ip_fsys_ctrl,
+       .ctrlbit        = (1 << 1),
+};
+
+static struct clk exynos5_clk_mdma1 = {
+       .name           = "dma",
+       .devname        = "dma-pl330.2",
+       .enable         = exynos5_clk_ip_gen_ctrl,
+       .ctrlbit        = (1 << 4),
+};
+
+struct clk *exynos5_clkset_group_list[] = {
+       [0] = &clk_ext_xtal_mux,
+       [1] = NULL,
+       [2] = &exynos5_clk_sclk_hdmi24m,
+       [3] = &exynos5_clk_sclk_dptxphy,
+       [4] = &exynos5_clk_sclk_usbphy,
+       [5] = &exynos5_clk_sclk_hdmiphy,
+       [6] = &exynos5_clk_mout_mpll_user.clk,
+       [7] = &exynos5_clk_mout_epll.clk,
+       [8] = &exynos5_clk_sclk_vpll.clk,
+       [9] = &exynos5_clk_mout_cpll.clk,
+};
+
+struct clksrc_sources exynos5_clkset_group = {
+       .sources        = exynos5_clkset_group_list,
+       .nr_sources     = ARRAY_SIZE(exynos5_clkset_group_list),
+};
+
+/* Possible clock sources for aclk_266_gscl_sub Mux */
+static struct clk *clk_src_gscl_266_list[] = {
+       [0] = &clk_ext_xtal_mux,
+       [1] = &exynos5_clk_aclk_266.clk,
+};
+
+static struct clksrc_sources clk_src_gscl_266 = {
+       .sources        = clk_src_gscl_266_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_gscl_266_list),
+};
+
+static struct clksrc_clk exynos5_clk_dout_mmc0 = {
+       .clk            = {
+               .name           = "dout_mmc0",
+       },
+       .sources = &exynos5_clkset_group,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 0, .size = 4 },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_dout_mmc1 = {
+       .clk            = {
+               .name           = "dout_mmc1",
+       },
+       .sources = &exynos5_clkset_group,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 4, .size = 4 },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_dout_mmc2 = {
+       .clk            = {
+               .name           = "dout_mmc2",
+       },
+       .sources = &exynos5_clkset_group,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 8, .size = 4 },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_dout_mmc3 = {
+       .clk            = {
+               .name           = "dout_mmc3",
+       },
+       .sources = &exynos5_clkset_group,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 12, .size = 4 },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_dout_mmc4 = {
+       .clk            = {
+               .name           = "dout_mmc4",
+       },
+       .sources = &exynos5_clkset_group,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 16, .size = 4 },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS3, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_uart0 = {
+       .clk    = {
+               .name           = "uclk1",
+               .devname        = "exynos4210-uart.0",
+               .enable         = exynos5_clksrc_mask_peric0_ctrl,
+               .ctrlbit        = (1 << 0),
+       },
+       .sources = &exynos5_clkset_group,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 0, .size = 4 },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_uart1 = {
+       .clk    = {
+               .name           = "uclk1",
+               .devname        = "exynos4210-uart.1",
+               .enable         = exynos5_clksrc_mask_peric0_ctrl,
+               .ctrlbit        = (1 << 4),
+       },
+       .sources = &exynos5_clkset_group,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 4, .size = 4 },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 4, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_uart2 = {
+       .clk    = {
+               .name           = "uclk1",
+               .devname        = "exynos4210-uart.2",
+               .enable         = exynos5_clksrc_mask_peric0_ctrl,
+               .ctrlbit        = (1 << 8),
+       },
+       .sources = &exynos5_clkset_group,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 8, .size = 4 },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_uart3 = {
+       .clk    = {
+               .name           = "uclk1",
+               .devname        = "exynos4210-uart.3",
+               .enable         = exynos5_clksrc_mask_peric0_ctrl,
+               .ctrlbit        = (1 << 12),
+       },
+       .sources = &exynos5_clkset_group,
+       .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 12, .size = 4 },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 12, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_mmc0 = {
+       .clk    = {
+               .name           = "sclk_mmc",
+               .devname        = "s3c-sdhci.0",
+               .parent         = &exynos5_clk_dout_mmc0.clk,
+               .enable         = exynos5_clksrc_mask_fsys_ctrl,
+               .ctrlbit        = (1 << 0),
+       },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 8, .size = 8 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_mmc1 = {
+       .clk    = {
+               .name           = "sclk_mmc",
+               .devname        = "s3c-sdhci.1",
+               .parent         = &exynos5_clk_dout_mmc1.clk,
+               .enable         = exynos5_clksrc_mask_fsys_ctrl,
+               .ctrlbit        = (1 << 4),
+       },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 24, .size = 8 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_mmc2 = {
+       .clk    = {
+               .name           = "sclk_mmc",
+               .devname        = "s3c-sdhci.2",
+               .parent         = &exynos5_clk_dout_mmc2.clk,
+               .enable         = exynos5_clksrc_mask_fsys_ctrl,
+               .ctrlbit        = (1 << 8),
+       },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 8, .size = 8 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_mmc3 = {
+       .clk    = {
+               .name           = "sclk_mmc",
+               .devname        = "s3c-sdhci.3",
+               .parent         = &exynos5_clk_dout_mmc3.clk,
+               .enable         = exynos5_clksrc_mask_fsys_ctrl,
+               .ctrlbit        = (1 << 12),
+       },
+       .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 24, .size = 8 },
+};
+
+static struct clksrc_clk exynos5_clksrcs[] = {
+       {
+               .clk    = {
+                       .name           = "sclk_dwmci",
+                       .parent         = &exynos5_clk_dout_mmc4.clk,
+                       .enable         = exynos5_clksrc_mask_fsys_ctrl,
+                       .ctrlbit        = (1 << 16),
+               },
+               .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS3, .shift = 8, .size = 8 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimd",
+                       .devname        = "s3cfb.1",
+                       .enable         = exynos5_clksrc_mask_disp1_0_ctrl,
+                       .ctrlbit        = (1 << 0),
+               },
+               .sources = &exynos5_clkset_group,
+               .reg_src = { .reg = EXYNOS5_CLKSRC_DISP1_0, .shift = 0, .size = 4 },
+               .reg_div = { .reg = EXYNOS5_CLKDIV_DISP1_0, .shift = 0, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "aclk_266_gscl",
+               },
+               .sources = &clk_src_gscl_266,
+               .reg_src = { .reg = EXYNOS5_CLKSRC_TOP3, .shift = 8, .size = 1 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_g3d",
+                       .devname        = "mali-t604.0",
+                       .enable         = exynos5_clk_block_ctrl,
+                       .ctrlbit        = (1 << 1),
+               },
+               .sources = &exynos5_clkset_aclk,
+               .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 20, .size = 1 },
+               .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_gscl_wrap",
+                       .devname        = "s5p-mipi-csis.0",
+                       .enable         = exynos5_clksrc_mask_gscl_ctrl,
+                       .ctrlbit        = (1 << 24),
+               },
+               .sources = &exynos5_clkset_group,
+               .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 24, .size = 4 },
+               .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 24, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_gscl_wrap",
+                       .devname        = "s5p-mipi-csis.1",
+                       .enable         = exynos5_clksrc_mask_gscl_ctrl,
+                       .ctrlbit        = (1 << 28),
+               },
+               .sources = &exynos5_clkset_group,
+               .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 28, .size = 4 },
+               .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 28, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_cam0",
+                       .enable         = exynos5_clksrc_mask_gscl_ctrl,
+                       .ctrlbit        = (1 << 16),
+               },
+               .sources = &exynos5_clkset_group,
+               .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 16, .size = 4 },
+               .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 16, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_cam1",
+                       .enable         = exynos5_clksrc_mask_gscl_ctrl,
+                       .ctrlbit        = (1 << 20),
+               },
+               .sources = &exynos5_clkset_group,
+               .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 20, .size = 4 },
+               .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 20, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_jpeg",
+                       .parent         = &exynos5_clk_mout_cpll.clk,
+               },
+               .reg_div = { .reg = EXYNOS5_CLKDIV_GEN, .shift = 4, .size = 3 },
+       },
+};
+
+/* Clock initialization code */
+static struct clksrc_clk *exynos5_sysclks[] = {
+       &exynos5_clk_mout_apll,
+       &exynos5_clk_sclk_apll,
+       &exynos5_clk_mout_bpll,
+       &exynos5_clk_mout_bpll_user,
+       &exynos5_clk_mout_cpll,
+       &exynos5_clk_mout_epll,
+       &exynos5_clk_mout_mpll,
+       &exynos5_clk_mout_mpll_user,
+       &exynos5_clk_vpllsrc,
+       &exynos5_clk_sclk_vpll,
+       &exynos5_clk_mout_cpu,
+       &exynos5_clk_dout_armclk,
+       &exynos5_clk_dout_arm2clk,
+       &exynos5_clk_cdrex,
+       &exynos5_clk_aclk_400,
+       &exynos5_clk_aclk_333,
+       &exynos5_clk_aclk_266,
+       &exynos5_clk_aclk_200,
+       &exynos5_clk_aclk_166,
+       &exynos5_clk_aclk_66_pre,
+       &exynos5_clk_aclk_66,
+       &exynos5_clk_dout_mmc0,
+       &exynos5_clk_dout_mmc1,
+       &exynos5_clk_dout_mmc2,
+       &exynos5_clk_dout_mmc3,
+       &exynos5_clk_dout_mmc4,
+       &exynos5_clk_aclk_acp,
+       &exynos5_clk_pclk_acp,
+};
+
+static struct clk *exynos5_clk_cdev[] = {
+       &exynos5_clk_pdma0,
+       &exynos5_clk_pdma1,
+       &exynos5_clk_mdma1,
+};
+
+static struct clksrc_clk *exynos5_clksrc_cdev[] = {
+       &exynos5_clk_sclk_uart0,
+       &exynos5_clk_sclk_uart1,
+       &exynos5_clk_sclk_uart2,
+       &exynos5_clk_sclk_uart3,
+       &exynos5_clk_sclk_mmc0,
+       &exynos5_clk_sclk_mmc1,
+       &exynos5_clk_sclk_mmc2,
+       &exynos5_clk_sclk_mmc3,
+};
+
+static struct clk_lookup exynos5_clk_lookup[] = {
+       CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &exynos5_clk_sclk_uart0.clk),
+       CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos5_clk_sclk_uart1.clk),
+       CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos5_clk_sclk_uart2.clk),
+       CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos5_clk_sclk_uart3.clk),
+       CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &exynos5_clk_sclk_mmc0.clk),
+       CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &exynos5_clk_sclk_mmc1.clk),
+       CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &exynos5_clk_sclk_mmc2.clk),
+       CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &exynos5_clk_sclk_mmc3.clk),
+       CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos5_clk_pdma0),
+       CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos5_clk_pdma1),
+       CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos5_clk_mdma1),
+};
+
+static unsigned long exynos5_epll_get_rate(struct clk *clk)
+{
+       return clk->rate;
+}
+
+static struct clk *exynos5_clks[] __initdata = {
+       &exynos5_clk_sclk_hdmi27m,
+       &exynos5_clk_sclk_hdmiphy,
+       &clk_fout_bpll,
+       &clk_fout_cpll,
+       &exynos5_clk_armclk,
+};
+
+static u32 epll_div[][6] = {
+       { 192000000, 0, 48, 3, 1, 0 },
+       { 180000000, 0, 45, 3, 1, 0 },
+       {  73728000, 1, 73, 3, 3, 47710 },
+       {  67737600, 1, 90, 4, 3, 20762 },
+       {  49152000, 0, 49, 3, 3, 9961 },
+       {  45158400, 0, 45, 3, 3, 10381 },
+       { 180633600, 0, 45, 3, 1, 10381 },
+};
+
+static int exynos5_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+       unsigned int epll_con, epll_con_k;
+       unsigned int i;
+       unsigned int tmp;
+       unsigned int epll_rate;
+       unsigned int locktime;
+       unsigned int lockcnt;
+
+       /* Return if nothing changed */
+       if (clk->rate == rate)
+               return 0;
+
+       if (clk->parent)
+               epll_rate = clk_get_rate(clk->parent);
+       else
+               epll_rate = clk_ext_xtal_mux.rate;
+
+       if (epll_rate != 24000000) {
+               pr_err("Invalid Clock : recommended clock is 24MHz.\n");
+               return -EINVAL;
+       }
+
+       epll_con = __raw_readl(EXYNOS5_EPLL_CON0);
+       epll_con &= ~(0x1 << 27 | \
+                       PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |   \
+                       PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \
+                       PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
+
+       for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+               if (epll_div[i][0] == rate) {
+                       epll_con_k = epll_div[i][5] << 0;
+                       epll_con |= epll_div[i][1] << 27;
+                       epll_con |= epll_div[i][2] << PLL46XX_MDIV_SHIFT;
+                       epll_con |= epll_div[i][3] << PLL46XX_PDIV_SHIFT;
+                       epll_con |= epll_div[i][4] << PLL46XX_SDIV_SHIFT;
+                       break;
+               }
+       }
+
+       if (i == ARRAY_SIZE(epll_div)) {
+               printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
+                               __func__);
+               return -EINVAL;
+       }
+
+       epll_rate /= 1000000;
+
+       /* 3000 max_cycls : specification data */
+       locktime = 3000 / epll_rate * epll_div[i][3];
+       lockcnt = locktime * 10000 / (10000 / epll_rate);
+
+       __raw_writel(lockcnt, EXYNOS5_EPLL_LOCK);
+
+       __raw_writel(epll_con, EXYNOS5_EPLL_CON0);
+       __raw_writel(epll_con_k, EXYNOS5_EPLL_CON1);
+
+       do {
+               tmp = __raw_readl(EXYNOS5_EPLL_CON0);
+       } while (!(tmp & 0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT));
+
+       clk->rate = rate;
+
+       return 0;
+}
+
+static struct clk_ops exynos5_epll_ops = {
+       .get_rate = exynos5_epll_get_rate,
+       .set_rate = exynos5_epll_set_rate,
+};
+
+static int xtal_rate;
+
+static unsigned long exynos5_fout_apll_get_rate(struct clk *clk)
+{
+       return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS5_APLL_CON0));
+}
+
+static struct clk_ops exynos5_fout_apll_ops = {
+       .get_rate = exynos5_fout_apll_get_rate,
+};
+
+#ifdef CONFIG_PM
+static int exynos5_clock_suspend(void)
+{
+       s3c_pm_do_save(exynos5_clock_save, ARRAY_SIZE(exynos5_clock_save));
+
+       return 0;
+}
+
+static void exynos5_clock_resume(void)
+{
+       s3c_pm_do_restore_core(exynos5_clock_save, ARRAY_SIZE(exynos5_clock_save));
+}
+#else
+#define exynos5_clock_suspend NULL
+#define exynos5_clock_resume NULL
+#endif
+
+struct syscore_ops exynos5_clock_syscore_ops = {
+       .suspend        = exynos5_clock_suspend,
+       .resume         = exynos5_clock_resume,
+};
+
+void __init_or_cpufreq exynos5_setup_clocks(void)
+{
+       struct clk *xtal_clk;
+       unsigned long apll;
+       unsigned long bpll;
+       unsigned long cpll;
+       unsigned long mpll;
+       unsigned long epll;
+       unsigned long vpll;
+       unsigned long vpllsrc;
+       unsigned long xtal;
+       unsigned long armclk;
+       unsigned long mout_cdrex;
+       unsigned long aclk_400;
+       unsigned long aclk_333;
+       unsigned long aclk_266;
+       unsigned long aclk_200;
+       unsigned long aclk_166;
+       unsigned long aclk_66;
+       unsigned int ptr;
+
+       printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+
+       xtal_clk = clk_get(NULL, "xtal");
+       BUG_ON(IS_ERR(xtal_clk));
+
+       xtal = clk_get_rate(xtal_clk);
+
+       xtal_rate = xtal;
+
+       clk_put(xtal_clk);
+
+       printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+
+       apll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_APLL_CON0));
+       bpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_BPLL_CON0));
+       cpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_CPLL_CON0));
+       mpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_MPLL_CON0));
+       epll = s5p_get_pll36xx(xtal, __raw_readl(EXYNOS5_EPLL_CON0),
+                       __raw_readl(EXYNOS5_EPLL_CON1));
+
+       vpllsrc = clk_get_rate(&exynos5_clk_vpllsrc.clk);
+       vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(EXYNOS5_VPLL_CON0),
+                       __raw_readl(EXYNOS5_VPLL_CON1));
+
+       clk_fout_apll.ops = &exynos5_fout_apll_ops;
+       clk_fout_bpll.rate = bpll;
+       clk_fout_cpll.rate = cpll;
+       clk_fout_mpll.rate = mpll;
+       clk_fout_epll.rate = epll;
+       clk_fout_vpll.rate = vpll;
+
+       printk(KERN_INFO "EXYNOS5: PLL settings, A=%ld, B=%ld, C=%ld\n"
+                       "M=%ld, E=%ld V=%ld",
+                       apll, bpll, cpll, mpll, epll, vpll);
+
+       armclk = clk_get_rate(&exynos5_clk_armclk);
+       mout_cdrex = clk_get_rate(&exynos5_clk_cdrex.clk);
+
+       aclk_400 = clk_get_rate(&exynos5_clk_aclk_400.clk);
+       aclk_333 = clk_get_rate(&exynos5_clk_aclk_333.clk);
+       aclk_266 = clk_get_rate(&exynos5_clk_aclk_266.clk);
+       aclk_200 = clk_get_rate(&exynos5_clk_aclk_200.clk);
+       aclk_166 = clk_get_rate(&exynos5_clk_aclk_166.clk);
+       aclk_66 = clk_get_rate(&exynos5_clk_aclk_66.clk);
+
+       printk(KERN_INFO "EXYNOS5: ARMCLK=%ld, CDREX=%ld, ACLK400=%ld\n"
+                       "ACLK333=%ld, ACLK266=%ld, ACLK200=%ld\n"
+                       "ACLK166=%ld, ACLK66=%ld\n",
+                       armclk, mout_cdrex, aclk_400,
+                       aclk_333, aclk_266, aclk_200,
+                       aclk_166, aclk_66);
+
+
+       clk_fout_epll.ops = &exynos5_epll_ops;
+
+       if (clk_set_parent(&exynos5_clk_mout_epll.clk, &clk_fout_epll))
+               printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+                               clk_fout_epll.name, exynos5_clk_mout_epll.clk.name);
+
+       clk_set_rate(&exynos5_clk_sclk_apll.clk, 100000000);
+       clk_set_rate(&exynos5_clk_aclk_266.clk, 300000000);
+
+       clk_set_rate(&exynos5_clk_aclk_acp.clk, 267000000);
+       clk_set_rate(&exynos5_clk_pclk_acp.clk, 134000000);
+
+       for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clksrcs); ptr++)
+               s3c_set_clksrc(&exynos5_clksrcs[ptr], true);
+}
+
+void __init exynos5_register_clocks(void)
+{
+       int ptr;
+
+       s3c24xx_register_clocks(exynos5_clks, ARRAY_SIZE(exynos5_clks));
+
+       for (ptr = 0; ptr < ARRAY_SIZE(exynos5_sysclks); ptr++)
+               s3c_register_clksrc(exynos5_sysclks[ptr], 1);
+
+       for (ptr = 0; ptr < ARRAY_SIZE(exynos5_sclk_tv); ptr++)
+               s3c_register_clksrc(exynos5_sclk_tv[ptr], 1);
+
+       for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clksrc_cdev); ptr++)
+               s3c_register_clksrc(exynos5_clksrc_cdev[ptr], 1);
+
+       s3c_register_clksrc(exynos5_clksrcs, ARRAY_SIZE(exynos5_clksrcs));
+       s3c_register_clocks(exynos5_init_clocks_on, ARRAY_SIZE(exynos5_init_clocks_on));
+
+       s3c24xx_register_clocks(exynos5_clk_cdev, ARRAY_SIZE(exynos5_clk_cdev));
+       for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clk_cdev); ptr++)
+               s3c_disable_clocks(exynos5_clk_cdev[ptr], 1);
+
+       s3c_register_clocks(exynos5_init_clocks_off, ARRAY_SIZE(exynos5_init_clocks_off));
+       s3c_disable_clocks(exynos5_init_clocks_off, ARRAY_SIZE(exynos5_init_clocks_off));
+       clkdev_add_table(exynos5_clk_lookup, ARRAY_SIZE(exynos5_clk_lookup));
+
+       register_syscore_ops(&exynos5_clock_syscore_ops);
+       s3c_pwmclk_init();
+}
diff --git a/arch/arm/mach-exynos/clock.c b/arch/arm/mach-exynos/clock.c
deleted file mode 100644 (file)
index 187287a..0000000
+++ /dev/null
@@ -1,1564 +0,0 @@
-/* linux/arch/arm/mach-exynos4/clock.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - Clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/syscore_ops.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-#include <plat/s5p-clock.h>
-#include <plat/clock-clksrc.h>
-#include <plat/pm.h>
-
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-#include <mach/sysmmu.h>
-#include <mach/exynos4-clock.h>
-
-#include "common.h"
-
-#ifdef CONFIG_PM_SLEEP
-static struct sleep_save exynos4_clock_save[] = {
-       SAVE_ITEM(S5P_CLKDIV_LEFTBUS),
-       SAVE_ITEM(S5P_CLKGATE_IP_LEFTBUS),
-       SAVE_ITEM(S5P_CLKDIV_RIGHTBUS),
-       SAVE_ITEM(S5P_CLKGATE_IP_RIGHTBUS),
-       SAVE_ITEM(S5P_CLKSRC_TOP0),
-       SAVE_ITEM(S5P_CLKSRC_TOP1),
-       SAVE_ITEM(S5P_CLKSRC_CAM),
-       SAVE_ITEM(S5P_CLKSRC_TV),
-       SAVE_ITEM(S5P_CLKSRC_MFC),
-       SAVE_ITEM(S5P_CLKSRC_G3D),
-       SAVE_ITEM(S5P_CLKSRC_LCD0),
-       SAVE_ITEM(S5P_CLKSRC_MAUDIO),
-       SAVE_ITEM(S5P_CLKSRC_FSYS),
-       SAVE_ITEM(S5P_CLKSRC_PERIL0),
-       SAVE_ITEM(S5P_CLKSRC_PERIL1),
-       SAVE_ITEM(S5P_CLKDIV_CAM),
-       SAVE_ITEM(S5P_CLKDIV_TV),
-       SAVE_ITEM(S5P_CLKDIV_MFC),
-       SAVE_ITEM(S5P_CLKDIV_G3D),
-       SAVE_ITEM(S5P_CLKDIV_LCD0),
-       SAVE_ITEM(S5P_CLKDIV_MAUDIO),
-       SAVE_ITEM(S5P_CLKDIV_FSYS0),
-       SAVE_ITEM(S5P_CLKDIV_FSYS1),
-       SAVE_ITEM(S5P_CLKDIV_FSYS2),
-       SAVE_ITEM(S5P_CLKDIV_FSYS3),
-       SAVE_ITEM(S5P_CLKDIV_PERIL0),
-       SAVE_ITEM(S5P_CLKDIV_PERIL1),
-       SAVE_ITEM(S5P_CLKDIV_PERIL2),
-       SAVE_ITEM(S5P_CLKDIV_PERIL3),
-       SAVE_ITEM(S5P_CLKDIV_PERIL4),
-       SAVE_ITEM(S5P_CLKDIV_PERIL5),
-       SAVE_ITEM(S5P_CLKDIV_TOP),
-       SAVE_ITEM(S5P_CLKSRC_MASK_TOP),
-       SAVE_ITEM(S5P_CLKSRC_MASK_CAM),
-       SAVE_ITEM(S5P_CLKSRC_MASK_TV),
-       SAVE_ITEM(S5P_CLKSRC_MASK_LCD0),
-       SAVE_ITEM(S5P_CLKSRC_MASK_MAUDIO),
-       SAVE_ITEM(S5P_CLKSRC_MASK_FSYS),
-       SAVE_ITEM(S5P_CLKSRC_MASK_PERIL0),
-       SAVE_ITEM(S5P_CLKSRC_MASK_PERIL1),
-       SAVE_ITEM(S5P_CLKDIV2_RATIO),
-       SAVE_ITEM(S5P_CLKGATE_SCLKCAM),
-       SAVE_ITEM(S5P_CLKGATE_IP_CAM),
-       SAVE_ITEM(S5P_CLKGATE_IP_TV),
-       SAVE_ITEM(S5P_CLKGATE_IP_MFC),
-       SAVE_ITEM(S5P_CLKGATE_IP_G3D),
-       SAVE_ITEM(S5P_CLKGATE_IP_LCD0),
-       SAVE_ITEM(S5P_CLKGATE_IP_FSYS),
-       SAVE_ITEM(S5P_CLKGATE_IP_GPS),
-       SAVE_ITEM(S5P_CLKGATE_IP_PERIL),
-       SAVE_ITEM(S5P_CLKGATE_BLOCK),
-       SAVE_ITEM(S5P_CLKSRC_MASK_DMC),
-       SAVE_ITEM(S5P_CLKSRC_DMC),
-       SAVE_ITEM(S5P_CLKDIV_DMC0),
-       SAVE_ITEM(S5P_CLKDIV_DMC1),
-       SAVE_ITEM(S5P_CLKGATE_IP_DMC),
-       SAVE_ITEM(S5P_CLKSRC_CPU),
-       SAVE_ITEM(S5P_CLKDIV_CPU),
-       SAVE_ITEM(S5P_CLKDIV_CPU + 0x4),
-       SAVE_ITEM(S5P_CLKGATE_SCLKCPU),
-       SAVE_ITEM(S5P_CLKGATE_IP_CPU),
-};
-#endif
-
-struct clk clk_sclk_hdmi27m = {
-       .name           = "sclk_hdmi27m",
-       .rate           = 27000000,
-};
-
-struct clk clk_sclk_hdmiphy = {
-       .name           = "sclk_hdmiphy",
-};
-
-struct clk clk_sclk_usbphy0 = {
-       .name           = "sclk_usbphy0",
-       .rate           = 27000000,
-};
-
-struct clk clk_sclk_usbphy1 = {
-       .name           = "sclk_usbphy1",
-};
-
-static struct clk dummy_apb_pclk = {
-       .name           = "apb_pclk",
-       .id             = -1,
-};
-
-static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
-}
-
-static int exynos4_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKSRC_MASK_CAM, clk, enable);
-}
-
-static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable);
-}
-
-int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable);
-}
-
-static int exynos4_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable);
-}
-
-static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL1, clk, enable);
-}
-
-static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP_MFC, clk, enable);
-}
-
-static int exynos4_clksrc_mask_tv_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKSRC_MASK_TV, clk, enable);
-}
-
-static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable);
-}
-
-static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP_TV, clk, enable);
-}
-
-static int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable);
-}
-
-static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable);
-}
-
-int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable);
-}
-
-int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable);
-}
-
-static int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable);
-}
-
-static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
-}
-
-static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
-}
-
-static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable);
-}
-
-/* Core list of CMU_CPU side */
-
-static struct clksrc_clk clk_mout_apll = {
-       .clk    = {
-               .name           = "mout_apll",
-       },
-       .sources        = &clk_src_apll,
-       .reg_src        = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 },
-};
-
-struct clksrc_clk clk_sclk_apll = {
-       .clk    = {
-               .name           = "sclk_apll",
-               .parent         = &clk_mout_apll.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 },
-};
-
-struct clksrc_clk clk_mout_epll = {
-       .clk    = {
-               .name           = "mout_epll",
-       },
-       .sources        = &clk_src_epll,
-       .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 4, .size = 1 },
-};
-
-struct clksrc_clk clk_mout_mpll = {
-       .clk = {
-               .name           = "mout_mpll",
-       },
-       .sources        = &clk_src_mpll,
-
-       /* reg_src will be added in each SoCs' clock */
-};
-
-static struct clk *clkset_moutcore_list[] = {
-       [0] = &clk_mout_apll.clk,
-       [1] = &clk_mout_mpll.clk,
-};
-
-static struct clksrc_sources clkset_moutcore = {
-       .sources        = clkset_moutcore_list,
-       .nr_sources     = ARRAY_SIZE(clkset_moutcore_list),
-};
-
-static struct clksrc_clk clk_moutcore = {
-       .clk    = {
-               .name           = "moutcore",
-       },
-       .sources        = &clkset_moutcore,
-       .reg_src        = { .reg = S5P_CLKSRC_CPU, .shift = 16, .size = 1 },
-};
-
-static struct clksrc_clk clk_coreclk = {
-       .clk    = {
-               .name           = "core_clk",
-               .parent         = &clk_moutcore.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk clk_armclk = {
-       .clk    = {
-               .name           = "armclk",
-               .parent         = &clk_coreclk.clk,
-       },
-};
-
-static struct clksrc_clk clk_aclk_corem0 = {
-       .clk    = {
-               .name           = "aclk_corem0",
-               .parent         = &clk_coreclk.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_cores = {
-       .clk    = {
-               .name           = "aclk_cores",
-               .parent         = &clk_coreclk.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_corem1 = {
-       .clk    = {
-               .name           = "aclk_corem1",
-               .parent         = &clk_coreclk.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 8, .size = 3 },
-};
-
-static struct clksrc_clk clk_periphclk = {
-       .clk    = {
-               .name           = "periphclk",
-               .parent         = &clk_coreclk.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 },
-};
-
-/* Core list of CMU_CORE side */
-
-struct clk *clkset_corebus_list[] = {
-       [0] = &clk_mout_mpll.clk,
-       [1] = &clk_sclk_apll.clk,
-};
-
-struct clksrc_sources clkset_mout_corebus = {
-       .sources        = clkset_corebus_list,
-       .nr_sources     = ARRAY_SIZE(clkset_corebus_list),
-};
-
-static struct clksrc_clk clk_mout_corebus = {
-       .clk    = {
-               .name           = "mout_corebus",
-       },
-       .sources        = &clkset_mout_corebus,
-       .reg_src        = { .reg = S5P_CLKSRC_DMC, .shift = 4, .size = 1 },
-};
-
-static struct clksrc_clk clk_sclk_dmc = {
-       .clk    = {
-               .name           = "sclk_dmc",
-               .parent         = &clk_mout_corebus.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 12, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_cored = {
-       .clk    = {
-               .name           = "aclk_cored",
-               .parent         = &clk_sclk_dmc.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 16, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_corep = {
-       .clk    = {
-               .name           = "aclk_corep",
-               .parent         = &clk_aclk_cored.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 20, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_acp = {
-       .clk    = {
-               .name           = "aclk_acp",
-               .parent         = &clk_mout_corebus.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk clk_pclk_acp = {
-       .clk    = {
-               .name           = "pclk_acp",
-               .parent         = &clk_aclk_acp.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 4, .size = 3 },
-};
-
-/* Core list of CMU_TOP side */
-
-struct clk *clkset_aclk_top_list[] = {
-       [0] = &clk_mout_mpll.clk,
-       [1] = &clk_sclk_apll.clk,
-};
-
-struct clksrc_sources clkset_aclk = {
-       .sources        = clkset_aclk_top_list,
-       .nr_sources     = ARRAY_SIZE(clkset_aclk_top_list),
-};
-
-static struct clksrc_clk clk_aclk_200 = {
-       .clk    = {
-               .name           = "aclk_200",
-       },
-       .sources        = &clkset_aclk,
-       .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 },
-       .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_100 = {
-       .clk    = {
-               .name           = "aclk_100",
-       },
-       .sources        = &clkset_aclk,
-       .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 },
-       .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 },
-};
-
-static struct clksrc_clk clk_aclk_160 = {
-       .clk    = {
-               .name           = "aclk_160",
-       },
-       .sources        = &clkset_aclk,
-       .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 },
-       .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 },
-};
-
-struct clksrc_clk clk_aclk_133 = {
-       .clk    = {
-               .name           = "aclk_133",
-       },
-       .sources        = &clkset_aclk,
-       .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 },
-       .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 },
-};
-
-static struct clk *clkset_vpllsrc_list[] = {
-       [0] = &clk_fin_vpll,
-       [1] = &clk_sclk_hdmi27m,
-};
-
-static struct clksrc_sources clkset_vpllsrc = {
-       .sources        = clkset_vpllsrc_list,
-       .nr_sources     = ARRAY_SIZE(clkset_vpllsrc_list),
-};
-
-static struct clksrc_clk clk_vpllsrc = {
-       .clk    = {
-               .name           = "vpll_src",
-               .enable         = exynos4_clksrc_mask_top_ctrl,
-               .ctrlbit        = (1 << 0),
-       },
-       .sources        = &clkset_vpllsrc,
-       .reg_src        = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 },
-};
-
-static struct clk *clkset_sclk_vpll_list[] = {
-       [0] = &clk_vpllsrc.clk,
-       [1] = &clk_fout_vpll,
-};
-
-static struct clksrc_sources clkset_sclk_vpll = {
-       .sources        = clkset_sclk_vpll_list,
-       .nr_sources     = ARRAY_SIZE(clkset_sclk_vpll_list),
-};
-
-struct clksrc_clk clk_sclk_vpll = {
-       .clk    = {
-               .name           = "sclk_vpll",
-       },
-       .sources        = &clkset_sclk_vpll,
-       .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 },
-};
-
-static struct clk init_clocks_off[] = {
-       {
-               .name           = "timers",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1<<24),
-       }, {
-               .name           = "csis",
-               .devname        = "s5p-mipi-csis.0",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "csis",
-               .devname        = "s5p-mipi-csis.1",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 5),
-       }, {
-               .name           = "fimc",
-               .devname        = "exynos4-fimc.0",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "fimc",
-               .devname        = "exynos4-fimc.1",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 1),
-       }, {
-               .name           = "fimc",
-               .devname        = "exynos4-fimc.2",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 2),
-       }, {
-               .name           = "fimc",
-               .devname        = "exynos4-fimc.3",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 3),
-       }, {
-               .name           = "fimd",
-               .devname        = "exynos4-fb.0",
-               .enable         = exynos4_clk_ip_lcd0_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "hsmmc",
-               .devname        = "s3c-sdhci.0",
-               .parent         = &clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 5),
-       }, {
-               .name           = "hsmmc",
-               .devname        = "s3c-sdhci.1",
-               .parent         = &clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 6),
-       }, {
-               .name           = "hsmmc",
-               .devname        = "s3c-sdhci.2",
-               .parent         = &clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 7),
-       }, {
-               .name           = "hsmmc",
-               .devname        = "s3c-sdhci.3",
-               .parent         = &clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 8),
-       }, {
-               .name           = "dwmmc",
-               .parent         = &clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 9),
-       }, {
-               .name           = "dac",
-               .devname        = "s5p-sdo",
-               .enable         = exynos4_clk_ip_tv_ctrl,
-               .ctrlbit        = (1 << 2),
-       }, {
-               .name           = "mixer",
-               .devname        = "s5p-mixer",
-               .enable         = exynos4_clk_ip_tv_ctrl,
-               .ctrlbit        = (1 << 1),
-       }, {
-               .name           = "vp",
-               .devname        = "s5p-mixer",
-               .enable         = exynos4_clk_ip_tv_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "hdmi",
-               .devname        = "exynos4-hdmi",
-               .enable         = exynos4_clk_ip_tv_ctrl,
-               .ctrlbit        = (1 << 3),
-       }, {
-               .name           = "hdmiphy",
-               .devname        = "exynos4-hdmi",
-               .enable         = exynos4_clk_hdmiphy_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "dacphy",
-               .devname        = "s5p-sdo",
-               .enable         = exynos4_clk_dac_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "adc",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 15),
-       }, {
-               .name           = "keypad",
-               .enable         = exynos4_clk_ip_perir_ctrl,
-               .ctrlbit        = (1 << 16),
-       }, {
-               .name           = "rtc",
-               .enable         = exynos4_clk_ip_perir_ctrl,
-               .ctrlbit        = (1 << 15),
-       }, {
-               .name           = "watchdog",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_perir_ctrl,
-               .ctrlbit        = (1 << 14),
-       }, {
-               .name           = "usbhost",
-               .enable         = exynos4_clk_ip_fsys_ctrl ,
-               .ctrlbit        = (1 << 12),
-       }, {
-               .name           = "otg",
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 13),
-       }, {
-               .name           = "spi",
-               .devname        = "s3c64xx-spi.0",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 16),
-       }, {
-               .name           = "spi",
-               .devname        = "s3c64xx-spi.1",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 17),
-       }, {
-               .name           = "spi",
-               .devname        = "s3c64xx-spi.2",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 18),
-       }, {
-               .name           = "iis",
-               .devname        = "samsung-i2s.0",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 19),
-       }, {
-               .name           = "iis",
-               .devname        = "samsung-i2s.1",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 20),
-       }, {
-               .name           = "iis",
-               .devname        = "samsung-i2s.2",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 21),
-       }, {
-               .name           = "ac97",
-               .devname        = "samsung-ac97",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 27),
-       }, {
-               .name           = "fimg2d",
-               .enable         = exynos4_clk_ip_image_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "mfc",
-               .devname        = "s5p-mfc",
-               .enable         = exynos4_clk_ip_mfc_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.0",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 6),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.1",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 7),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.2",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 8),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.3",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 9),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.4",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 10),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.5",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 11),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.6",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 12),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.7",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 13),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-hdmiphy-i2c",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 14),
-       }, {
-               .name           = "SYSMMU_MDMA",
-               .enable         = exynos4_clk_ip_image_ctrl,
-               .ctrlbit        = (1 << 5),
-       }, {
-               .name           = "SYSMMU_FIMC0",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 7),
-       }, {
-               .name           = "SYSMMU_FIMC1",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 8),
-       }, {
-               .name           = "SYSMMU_FIMC2",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 9),
-       }, {
-               .name           = "SYSMMU_FIMC3",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 10),
-       }, {
-               .name           = "SYSMMU_JPEG",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 11),
-       }, {
-               .name           = "SYSMMU_FIMD0",
-               .enable         = exynos4_clk_ip_lcd0_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "SYSMMU_FIMD1",
-               .enable         = exynos4_clk_ip_lcd1_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "SYSMMU_PCIe",
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 18),
-       }, {
-               .name           = "SYSMMU_G2D",
-               .enable         = exynos4_clk_ip_image_ctrl,
-               .ctrlbit        = (1 << 3),
-       }, {
-               .name           = "SYSMMU_ROTATOR",
-               .enable         = exynos4_clk_ip_image_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "SYSMMU_TV",
-               .enable         = exynos4_clk_ip_tv_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "SYSMMU_MFC_L",
-               .enable         = exynos4_clk_ip_mfc_ctrl,
-               .ctrlbit        = (1 << 1),
-       }, {
-               .name           = "SYSMMU_MFC_R",
-               .enable         = exynos4_clk_ip_mfc_ctrl,
-               .ctrlbit        = (1 << 2),
-       }
-};
-
-static struct clk init_clocks[] = {
-       {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.0",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.1",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 1),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.2",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 2),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.3",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 3),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.4",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.5",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 5),
-       }
-};
-
-static struct clk clk_pdma0 = {
-       .name           = "dma",
-       .devname        = "dma-pl330.0",
-       .enable         = exynos4_clk_ip_fsys_ctrl,
-       .ctrlbit        = (1 << 0),
-};
-
-static struct clk clk_pdma1 = {
-       .name           = "dma",
-       .devname        = "dma-pl330.1",
-       .enable         = exynos4_clk_ip_fsys_ctrl,
-       .ctrlbit        = (1 << 1),
-};
-
-struct clk *clkset_group_list[] = {
-       [0] = &clk_ext_xtal_mux,
-       [1] = &clk_xusbxti,
-       [2] = &clk_sclk_hdmi27m,
-       [3] = &clk_sclk_usbphy0,
-       [4] = &clk_sclk_usbphy1,
-       [5] = &clk_sclk_hdmiphy,
-       [6] = &clk_mout_mpll.clk,
-       [7] = &clk_mout_epll.clk,
-       [8] = &clk_sclk_vpll.clk,
-};
-
-struct clksrc_sources clkset_group = {
-       .sources        = clkset_group_list,
-       .nr_sources     = ARRAY_SIZE(clkset_group_list),
-};
-
-static struct clk *clkset_mout_g2d0_list[] = {
-       [0] = &clk_mout_mpll.clk,
-       [1] = &clk_sclk_apll.clk,
-};
-
-static struct clksrc_sources clkset_mout_g2d0 = {
-       .sources        = clkset_mout_g2d0_list,
-       .nr_sources     = ARRAY_SIZE(clkset_mout_g2d0_list),
-};
-
-static struct clksrc_clk clk_mout_g2d0 = {
-       .clk    = {
-               .name           = "mout_g2d0",
-       },
-       .sources        = &clkset_mout_g2d0,
-       .reg_src        = { .reg = S5P_CLKSRC_IMAGE, .shift = 0, .size = 1 },
-};
-
-static struct clk *clkset_mout_g2d1_list[] = {
-       [0] = &clk_mout_epll.clk,
-       [1] = &clk_sclk_vpll.clk,
-};
-
-static struct clksrc_sources clkset_mout_g2d1 = {
-       .sources        = clkset_mout_g2d1_list,
-       .nr_sources     = ARRAY_SIZE(clkset_mout_g2d1_list),
-};
-
-static struct clksrc_clk clk_mout_g2d1 = {
-       .clk    = {
-               .name           = "mout_g2d1",
-       },
-       .sources        = &clkset_mout_g2d1,
-       .reg_src        = { .reg = S5P_CLKSRC_IMAGE, .shift = 4, .size = 1 },
-};
-
-static struct clk *clkset_mout_g2d_list[] = {
-       [0] = &clk_mout_g2d0.clk,
-       [1] = &clk_mout_g2d1.clk,
-};
-
-static struct clksrc_sources clkset_mout_g2d = {
-       .sources        = clkset_mout_g2d_list,
-       .nr_sources     = ARRAY_SIZE(clkset_mout_g2d_list),
-};
-
-static struct clk *clkset_mout_mfc0_list[] = {
-       [0] = &clk_mout_mpll.clk,
-       [1] = &clk_sclk_apll.clk,
-};
-
-static struct clksrc_sources clkset_mout_mfc0 = {
-       .sources        = clkset_mout_mfc0_list,
-       .nr_sources     = ARRAY_SIZE(clkset_mout_mfc0_list),
-};
-
-static struct clksrc_clk clk_mout_mfc0 = {
-       .clk    = {
-               .name           = "mout_mfc0",
-       },
-       .sources        = &clkset_mout_mfc0,
-       .reg_src        = { .reg = S5P_CLKSRC_MFC, .shift = 0, .size = 1 },
-};
-
-static struct clk *clkset_mout_mfc1_list[] = {
-       [0] = &clk_mout_epll.clk,
-       [1] = &clk_sclk_vpll.clk,
-};
-
-static struct clksrc_sources clkset_mout_mfc1 = {
-       .sources        = clkset_mout_mfc1_list,
-       .nr_sources     = ARRAY_SIZE(clkset_mout_mfc1_list),
-};
-
-static struct clksrc_clk clk_mout_mfc1 = {
-       .clk    = {
-               .name           = "mout_mfc1",
-       },
-       .sources        = &clkset_mout_mfc1,
-       .reg_src        = { .reg = S5P_CLKSRC_MFC, .shift = 4, .size = 1 },
-};
-
-static struct clk *clkset_mout_mfc_list[] = {
-       [0] = &clk_mout_mfc0.clk,
-       [1] = &clk_mout_mfc1.clk,
-};
-
-static struct clksrc_sources clkset_mout_mfc = {
-       .sources        = clkset_mout_mfc_list,
-       .nr_sources     = ARRAY_SIZE(clkset_mout_mfc_list),
-};
-
-static struct clk *clkset_sclk_dac_list[] = {
-       [0] = &clk_sclk_vpll.clk,
-       [1] = &clk_sclk_hdmiphy,
-};
-
-static struct clksrc_sources clkset_sclk_dac = {
-       .sources        = clkset_sclk_dac_list,
-       .nr_sources     = ARRAY_SIZE(clkset_sclk_dac_list),
-};
-
-static struct clksrc_clk clk_sclk_dac = {
-       .clk            = {
-               .name           = "sclk_dac",
-               .enable         = exynos4_clksrc_mask_tv_ctrl,
-               .ctrlbit        = (1 << 8),
-       },
-       .sources = &clkset_sclk_dac,
-       .reg_src = { .reg = S5P_CLKSRC_TV, .shift = 8, .size = 1 },
-};
-
-static struct clksrc_clk clk_sclk_pixel = {
-       .clk            = {
-               .name           = "sclk_pixel",
-               .parent = &clk_sclk_vpll.clk,
-       },
-       .reg_div = { .reg = S5P_CLKDIV_TV, .shift = 0, .size = 4 },
-};
-
-static struct clk *clkset_sclk_hdmi_list[] = {
-       [0] = &clk_sclk_pixel.clk,
-       [1] = &clk_sclk_hdmiphy,
-};
-
-static struct clksrc_sources clkset_sclk_hdmi = {
-       .sources        = clkset_sclk_hdmi_list,
-       .nr_sources     = ARRAY_SIZE(clkset_sclk_hdmi_list),
-};
-
-static struct clksrc_clk clk_sclk_hdmi = {
-       .clk            = {
-               .name           = "sclk_hdmi",
-               .enable         = exynos4_clksrc_mask_tv_ctrl,
-               .ctrlbit        = (1 << 0),
-       },
-       .sources = &clkset_sclk_hdmi,
-       .reg_src = { .reg = S5P_CLKSRC_TV, .shift = 0, .size = 1 },
-};
-
-static struct clk *clkset_sclk_mixer_list[] = {
-       [0] = &clk_sclk_dac.clk,
-       [1] = &clk_sclk_hdmi.clk,
-};
-
-static struct clksrc_sources clkset_sclk_mixer = {
-       .sources        = clkset_sclk_mixer_list,
-       .nr_sources     = ARRAY_SIZE(clkset_sclk_mixer_list),
-};
-
-static struct clksrc_clk clk_sclk_mixer = {
-       .clk            = {
-               .name           = "sclk_mixer",
-               .enable         = exynos4_clksrc_mask_tv_ctrl,
-               .ctrlbit        = (1 << 4),
-       },
-       .sources = &clkset_sclk_mixer,
-       .reg_src = { .reg = S5P_CLKSRC_TV, .shift = 4, .size = 1 },
-};
-
-static struct clksrc_clk *sclk_tv[] = {
-       &clk_sclk_dac,
-       &clk_sclk_pixel,
-       &clk_sclk_hdmi,
-       &clk_sclk_mixer,
-};
-
-static struct clksrc_clk clk_dout_mmc0 = {
-       .clk            = {
-               .name           = "dout_mmc0",
-       },
-       .sources = &clkset_group,
-       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 0, .size = 4 },
-       .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk clk_dout_mmc1 = {
-       .clk            = {
-               .name           = "dout_mmc1",
-       },
-       .sources = &clkset_group,
-       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 4, .size = 4 },
-       .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk clk_dout_mmc2 = {
-       .clk            = {
-               .name           = "dout_mmc2",
-       },
-       .sources = &clkset_group,
-       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 8, .size = 4 },
-       .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk clk_dout_mmc3 = {
-       .clk            = {
-               .name           = "dout_mmc3",
-       },
-       .sources = &clkset_group,
-       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 12, .size = 4 },
-       .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk clk_dout_mmc4 = {
-       .clk            = {
-               .name           = "dout_mmc4",
-       },
-       .sources = &clkset_group,
-       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 16, .size = 4 },
-       .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk clksrcs[] = {
-       {
-               .clk            = {
-                       .name           = "sclk_pwm",
-                       .enable         = exynos4_clksrc_mask_peril0_ctrl,
-                       .ctrlbit        = (1 << 24),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_csis",
-                       .devname        = "s5p-mipi-csis.0",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 24),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 24, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 24, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_csis",
-                       .devname        = "s5p-mipi-csis.1",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 28),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 28, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 28, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_cam0",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 16),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 16, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 16, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_cam1",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 20),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 20, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 20, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_fimc",
-                       .devname        = "exynos4-fimc.0",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 0),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 0, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 0, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_fimc",
-                       .devname        = "exynos4-fimc.1",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 4),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 4, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 4, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_fimc",
-                       .devname        = "exynos4-fimc.2",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 8),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 8, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 8, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_fimc",
-                       .devname        = "exynos4-fimc.3",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 12),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 12, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 12, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_fimd",
-                       .devname        = "exynos4-fb.0",
-                       .enable         = exynos4_clksrc_mask_lcd0_ctrl,
-                       .ctrlbit        = (1 << 0),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_LCD0, .shift = 0, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_fimg2d",
-               },
-               .sources = &clkset_mout_g2d,
-               .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 8, .size = 1 },
-               .reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_mfc",
-                       .devname        = "s5p-mfc",
-               },
-               .sources = &clkset_mout_mfc,
-               .reg_src = { .reg = S5P_CLKSRC_MFC, .shift = 8, .size = 1 },
-               .reg_div = { .reg = S5P_CLKDIV_MFC, .shift = 0, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_dwmmc",
-                       .parent         = &clk_dout_mmc4.clk,
-                       .enable         = exynos4_clksrc_mask_fsys_ctrl,
-                       .ctrlbit        = (1 << 16),
-               },
-               .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 8, .size = 8 },
-       }
-};
-
-static struct clksrc_clk clk_sclk_uart0 = {
-       .clk    = {
-               .name           = "uclk1",
-               .devname        = "exynos4210-uart.0",
-               .enable         = exynos4_clksrc_mask_peril0_ctrl,
-               .ctrlbit        = (1 << 0),
-       },
-       .sources = &clkset_group,
-       .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
-       .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk clk_sclk_uart1 = {
-       .clk            = {
-               .name           = "uclk1",
-               .devname        = "exynos4210-uart.1",
-               .enable         = exynos4_clksrc_mask_peril0_ctrl,
-               .ctrlbit        = (1 << 4),
-       },
-       .sources = &clkset_group,
-       .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
-       .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
-};
-
-static struct clksrc_clk clk_sclk_uart2 = {
-       .clk            = {
-               .name           = "uclk1",
-               .devname        = "exynos4210-uart.2",
-               .enable         = exynos4_clksrc_mask_peril0_ctrl,
-               .ctrlbit        = (1 << 8),
-       },
-       .sources = &clkset_group,
-       .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
-       .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
-};
-
-static struct clksrc_clk clk_sclk_uart3 = {
-       .clk            = {
-               .name           = "uclk1",
-               .devname        = "exynos4210-uart.3",
-               .enable         = exynos4_clksrc_mask_peril0_ctrl,
-               .ctrlbit        = (1 << 12),
-       },
-       .sources = &clkset_group,
-       .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
-       .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
-};
-
-static struct clksrc_clk clk_sclk_mmc0 = {
-       .clk            = {
-               .name           = "sclk_mmc",
-               .devname        = "s3c-sdhci.0",
-               .parent         = &clk_dout_mmc0.clk,
-               .enable         = exynos4_clksrc_mask_fsys_ctrl,
-               .ctrlbit        = (1 << 0),
-       },
-       .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
-};
-
-static struct clksrc_clk clk_sclk_mmc1 = {
-       .clk            = {
-               .name           = "sclk_mmc",
-               .devname        = "s3c-sdhci.1",
-               .parent         = &clk_dout_mmc1.clk,
-               .enable         = exynos4_clksrc_mask_fsys_ctrl,
-               .ctrlbit        = (1 << 4),
-       },
-       .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
-};
-
-static struct clksrc_clk clk_sclk_mmc2 = {
-       .clk            = {
-               .name           = "sclk_mmc",
-               .devname        = "s3c-sdhci.2",
-               .parent         = &clk_dout_mmc2.clk,
-               .enable         = exynos4_clksrc_mask_fsys_ctrl,
-               .ctrlbit        = (1 << 8),
-       },
-       .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
-};
-
-static struct clksrc_clk clk_sclk_mmc3 = {
-       .clk            = {
-               .name           = "sclk_mmc",
-               .devname        = "s3c-sdhci.3",
-               .parent         = &clk_dout_mmc3.clk,
-               .enable         = exynos4_clksrc_mask_fsys_ctrl,
-               .ctrlbit        = (1 << 12),
-       },
-       .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
-};
-
-static struct clksrc_clk clk_sclk_spi0 = {
-       .clk            = {
-               .name           = "sclk_spi",
-               .devname                = "s3c64xx-spi.0",
-               .enable         = exynos4_clksrc_mask_peril1_ctrl,
-               .ctrlbit                = (1 << 16),
-       },
-       .sources = &clkset_group,
-       .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 },
-       .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk clk_sclk_spi1 = {
-       .clk            = {
-               .name           = "sclk_spi",
-               .devname                = "s3c64xx-spi.1",
-               .enable         = exynos4_clksrc_mask_peril1_ctrl,
-               .ctrlbit                = (1 << 20),
-       },
-       .sources = &clkset_group,
-       .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 },
-       .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk clk_sclk_spi2 = {
-       .clk            = {
-               .name           = "sclk_spi",
-               .devname                = "s3c64xx-spi.2",
-               .enable         = exynos4_clksrc_mask_peril1_ctrl,
-               .ctrlbit                = (1 << 24),
-       },
-       .sources = &clkset_group,
-       .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 },
-       .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 },
-};
-
-/* Clock initialization code */
-static struct clksrc_clk *sysclks[] = {
-       &clk_mout_apll,
-       &clk_sclk_apll,
-       &clk_mout_epll,
-       &clk_mout_mpll,
-       &clk_moutcore,
-       &clk_coreclk,
-       &clk_armclk,
-       &clk_aclk_corem0,
-       &clk_aclk_cores,
-       &clk_aclk_corem1,
-       &clk_periphclk,
-       &clk_mout_corebus,
-       &clk_sclk_dmc,
-       &clk_aclk_cored,
-       &clk_aclk_corep,
-       &clk_aclk_acp,
-       &clk_pclk_acp,
-       &clk_vpllsrc,
-       &clk_sclk_vpll,
-       &clk_aclk_200,
-       &clk_aclk_100,
-       &clk_aclk_160,
-       &clk_aclk_133,
-       &clk_dout_mmc0,
-       &clk_dout_mmc1,
-       &clk_dout_mmc2,
-       &clk_dout_mmc3,
-       &clk_dout_mmc4,
-       &clk_mout_mfc0,
-       &clk_mout_mfc1,
-};
-
-static struct clk *clk_cdev[] = {
-       &clk_pdma0,
-       &clk_pdma1,
-};
-
-static struct clksrc_clk *clksrc_cdev[] = {
-       &clk_sclk_uart0,
-       &clk_sclk_uart1,
-       &clk_sclk_uart2,
-       &clk_sclk_uart3,
-       &clk_sclk_mmc0,
-       &clk_sclk_mmc1,
-       &clk_sclk_mmc2,
-       &clk_sclk_mmc3,
-       &clk_sclk_spi0,
-       &clk_sclk_spi1,
-       &clk_sclk_spi2,
-
-};
-
-static struct clk_lookup exynos4_clk_lookup[] = {
-       CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &clk_sclk_uart0.clk),
-       CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &clk_sclk_uart1.clk),
-       CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &clk_sclk_uart2.clk),
-       CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &clk_sclk_uart3.clk),
-       CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
-       CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
-       CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
-       CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &clk_sclk_mmc3.clk),
-       CLKDEV_INIT("dma-pl330.0", "apb_pclk", &clk_pdma0),
-       CLKDEV_INIT("dma-pl330.1", "apb_pclk", &clk_pdma1),
-       CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk0", &clk_sclk_spi0.clk),
-       CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk0", &clk_sclk_spi1.clk),
-       CLKDEV_INIT("s3c64xx-spi.2", "spi_busclk0", &clk_sclk_spi2.clk),
-};
-
-static int xtal_rate;
-
-static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
-{
-       if (soc_is_exynos4210())
-               return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0),
-                                       pll_4508);
-       else if (soc_is_exynos4212() || soc_is_exynos4412())
-               return s5p_get_pll35xx(xtal_rate, __raw_readl(S5P_APLL_CON0));
-       else
-               return 0;
-}
-
-static struct clk_ops exynos4_fout_apll_ops = {
-       .get_rate = exynos4_fout_apll_get_rate,
-};
-
-static u32 vpll_div[][8] = {
-       {  54000000, 3, 53, 3, 1024, 0, 17, 0 },
-       { 108000000, 3, 53, 2, 1024, 0, 17, 0 },
-};
-
-static unsigned long exynos4_vpll_get_rate(struct clk *clk)
-{
-       return clk->rate;
-}
-
-static int exynos4_vpll_set_rate(struct clk *clk, unsigned long rate)
-{
-       unsigned int vpll_con0, vpll_con1 = 0;
-       unsigned int i;
-
-       /* Return if nothing changed */
-       if (clk->rate == rate)
-               return 0;
-
-       vpll_con0 = __raw_readl(S5P_VPLL_CON0);
-       vpll_con0 &= ~(0x1 << 27 |                                      \
-                       PLL90XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |       \
-                       PLL90XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |       \
-                       PLL90XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
-
-       vpll_con1 = __raw_readl(S5P_VPLL_CON1);
-       vpll_con1 &= ~(PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT |  \
-                       PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT | \
-                       PLL4650C_KDIV_MASK << PLL46XX_KDIV_SHIFT);
-
-       for (i = 0; i < ARRAY_SIZE(vpll_div); i++) {
-               if (vpll_div[i][0] == rate) {
-                       vpll_con0 |= vpll_div[i][1] << PLL46XX_PDIV_SHIFT;
-                       vpll_con0 |= vpll_div[i][2] << PLL46XX_MDIV_SHIFT;
-                       vpll_con0 |= vpll_div[i][3] << PLL46XX_SDIV_SHIFT;
-                       vpll_con1 |= vpll_div[i][4] << PLL46XX_KDIV_SHIFT;
-                       vpll_con1 |= vpll_div[i][5] << PLL46XX_MFR_SHIFT;
-                       vpll_con1 |= vpll_div[i][6] << PLL46XX_MRR_SHIFT;
-                       vpll_con0 |= vpll_div[i][7] << 27;
-                       break;
-               }
-       }
-
-       if (i == ARRAY_SIZE(vpll_div)) {
-               printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n",
-                               __func__);
-               return -EINVAL;
-       }
-
-       __raw_writel(vpll_con0, S5P_VPLL_CON0);
-       __raw_writel(vpll_con1, S5P_VPLL_CON1);
-
-       /* Wait for VPLL lock */
-       while (!(__raw_readl(S5P_VPLL_CON0) & (1 << PLL46XX_LOCKED_SHIFT)))
-               continue;
-
-       clk->rate = rate;
-       return 0;
-}
-
-static struct clk_ops exynos4_vpll_ops = {
-       .get_rate = exynos4_vpll_get_rate,
-       .set_rate = exynos4_vpll_set_rate,
-};
-
-void __init_or_cpufreq exynos4_setup_clocks(void)
-{
-       struct clk *xtal_clk;
-       unsigned long apll = 0;
-       unsigned long mpll = 0;
-       unsigned long epll = 0;
-       unsigned long vpll = 0;
-       unsigned long vpllsrc;
-       unsigned long xtal;
-       unsigned long armclk;
-       unsigned long sclk_dmc;
-       unsigned long aclk_200;
-       unsigned long aclk_100;
-       unsigned long aclk_160;
-       unsigned long aclk_133;
-       unsigned int ptr;
-
-       printk(KERN_DEBUG "%s: registering clocks\n", __func__);
-
-       xtal_clk = clk_get(NULL, "xtal");
-       BUG_ON(IS_ERR(xtal_clk));
-
-       xtal = clk_get_rate(xtal_clk);
-
-       xtal_rate = xtal;
-
-       clk_put(xtal_clk);
-
-       printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
-
-       if (soc_is_exynos4210()) {
-               apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0),
-                                       pll_4508);
-               mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0),
-                                       pll_4508);
-               epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0),
-                                       __raw_readl(S5P_EPLL_CON1), pll_4600);
-
-               vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
-               vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
-                                       __raw_readl(S5P_VPLL_CON1), pll_4650c);
-       } else if (soc_is_exynos4212() || soc_is_exynos4412()) {
-               apll = s5p_get_pll35xx(xtal, __raw_readl(S5P_APLL_CON0));
-               mpll = s5p_get_pll35xx(xtal, __raw_readl(S5P_MPLL_CON0));
-               epll = s5p_get_pll36xx(xtal, __raw_readl(S5P_EPLL_CON0),
-                                       __raw_readl(S5P_EPLL_CON1));
-
-               vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
-               vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
-                                       __raw_readl(S5P_VPLL_CON1));
-       } else {
-               /* nothing */
-       }
-
-       clk_fout_apll.ops = &exynos4_fout_apll_ops;
-       clk_fout_mpll.rate = mpll;
-       clk_fout_epll.rate = epll;
-       clk_fout_vpll.ops = &exynos4_vpll_ops;
-       clk_fout_vpll.rate = vpll;
-
-       printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
-                       apll, mpll, epll, vpll);
-
-       armclk = clk_get_rate(&clk_armclk.clk);
-       sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk);
-
-       aclk_200 = clk_get_rate(&clk_aclk_200.clk);
-       aclk_100 = clk_get_rate(&clk_aclk_100.clk);
-       aclk_160 = clk_get_rate(&clk_aclk_160.clk);
-       aclk_133 = clk_get_rate(&clk_aclk_133.clk);
-
-       printk(KERN_INFO "EXYNOS4: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
-                        "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
-                       armclk, sclk_dmc, aclk_200,
-                       aclk_100, aclk_160, aclk_133);
-
-       clk_f.rate = armclk;
-       clk_h.rate = sclk_dmc;
-       clk_p.rate = aclk_100;
-
-       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
-               s3c_set_clksrc(&clksrcs[ptr], true);
-}
-
-static struct clk *clks[] __initdata = {
-       &clk_sclk_hdmi27m,
-       &clk_sclk_hdmiphy,
-       &clk_sclk_usbphy0,
-       &clk_sclk_usbphy1,
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int exynos4_clock_suspend(void)
-{
-       s3c_pm_do_save(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
-       return 0;
-}
-
-static void exynos4_clock_resume(void)
-{
-       s3c_pm_do_restore_core(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
-}
-
-#else
-#define exynos4_clock_suspend NULL
-#define exynos4_clock_resume NULL
-#endif
-
-struct syscore_ops exynos4_clock_syscore_ops = {
-       .suspend        = exynos4_clock_suspend,
-       .resume         = exynos4_clock_resume,
-};
-
-void __init exynos4_register_clocks(void)
-{
-       int ptr;
-
-       s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
-
-       for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
-               s3c_register_clksrc(sysclks[ptr], 1);
-
-       for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
-               s3c_register_clksrc(sclk_tv[ptr], 1);
-
-       for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
-               s3c_register_clksrc(clksrc_cdev[ptr], 1);
-
-       s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
-       s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
-
-       s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev));
-       for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++)
-               s3c_disable_clocks(clk_cdev[ptr], 1);
-
-       s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-       s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-       clkdev_add_table(exynos4_clk_lookup, ARRAY_SIZE(exynos4_clk_lookup));
-
-       register_syscore_ops(&exynos4_clock_syscore_ops);
-       s3c24xx_register_clock(&dummy_apb_pclk);
-
-       s3c_pwmclk_init();
-}
index 93fa2d532e4ad6b1caafff8724e715b40182f7f3..e6cc50e94a58f86cff1e5d60cc1fc9fd5d1eebeb 100644 (file)
 #include <asm/hardware/gic.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
+#include <asm/cacheflush.h>
 
 #include <mach/regs-irq.h>
 #include <mach/regs-pmu.h>
 #include <mach/regs-gpio.h>
+#include <mach/pmu.h>
 
 #include <plat/cpu.h>
 #include <plat/clock.h>
 #include <plat/regs-serial.h>
 
 #include "common.h"
+#define L2_AUX_VAL 0x7C470001
+#define L2_AUX_MASK 0xC200ffff
 
 static const char name_exynos4210[] = "EXYNOS4210";
 static const char name_exynos4212[] = "EXYNOS4212";
 static const char name_exynos4412[] = "EXYNOS4412";
+static const char name_exynos5250[] = "EXYNOS5250";
+
+static void exynos4_map_io(void);
+static void exynos5_map_io(void);
+static void exynos4_init_clocks(int xtal);
+static void exynos5_init_clocks(int xtal);
+static void exynos_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+static int exynos_init(void);
 
 static struct cpu_table cpu_ids[] __initdata = {
        {
@@ -56,7 +68,7 @@ static struct cpu_table cpu_ids[] __initdata = {
                .idmask         = EXYNOS4_CPU_MASK,
                .map_io         = exynos4_map_io,
                .init_clocks    = exynos4_init_clocks,
-               .init_uarts     = exynos4_init_uarts,
+               .init_uarts     = exynos_init_uarts,
                .init           = exynos_init,
                .name           = name_exynos4210,
        }, {
@@ -64,7 +76,7 @@ static struct cpu_table cpu_ids[] __initdata = {
                .idmask         = EXYNOS4_CPU_MASK,
                .map_io         = exynos4_map_io,
                .init_clocks    = exynos4_init_clocks,
-               .init_uarts     = exynos4_init_uarts,
+               .init_uarts     = exynos_init_uarts,
                .init           = exynos_init,
                .name           = name_exynos4212,
        }, {
@@ -72,9 +84,17 @@ static struct cpu_table cpu_ids[] __initdata = {
                .idmask         = EXYNOS4_CPU_MASK,
                .map_io         = exynos4_map_io,
                .init_clocks    = exynos4_init_clocks,
-               .init_uarts     = exynos4_init_uarts,
+               .init_uarts     = exynos_init_uarts,
                .init           = exynos_init,
                .name           = name_exynos4412,
+       }, {
+               .idcode         = EXYNOS5250_SOC_ID,
+               .idmask         = EXYNOS5_SOC_MASK,
+               .map_io         = exynos5_map_io,
+               .init_clocks    = exynos5_init_clocks,
+               .init_uarts     = exynos_init_uarts,
+               .init           = exynos_init,
+               .name           = name_exynos5250,
        },
 };
 
@@ -83,10 +103,14 @@ static struct cpu_table cpu_ids[] __initdata = {
 static struct map_desc exynos_iodesc[] __initdata = {
        {
                .virtual        = (unsigned long)S5P_VA_CHIPID,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_CHIPID),
+               .pfn            = __phys_to_pfn(EXYNOS_PA_CHIPID),
                .length         = SZ_4K,
                .type           = MT_DEVICE,
-       }, {
+       },
+};
+
+static struct map_desc exynos4_iodesc[] __initdata = {
+       {
                .virtual        = (unsigned long)S3C_VA_SYS,
                .pfn            = __phys_to_pfn(EXYNOS4_PA_SYSCON),
                .length         = SZ_64K,
@@ -136,11 +160,7 @@ static struct map_desc exynos_iodesc[] __initdata = {
                .pfn            = __phys_to_pfn(EXYNOS4_PA_UART),
                .length         = SZ_512K,
                .type           = MT_DEVICE,
-       },
-};
-
-static struct map_desc exynos4_iodesc[] __initdata = {
-       {
+       }, {
                .virtual        = (unsigned long)S5P_VA_CMU,
                .pfn            = __phys_to_pfn(EXYNOS4_PA_CMU),
                .length         = SZ_128K,
@@ -155,25 +175,15 @@ static struct map_desc exynos4_iodesc[] __initdata = {
                .pfn            = __phys_to_pfn(EXYNOS4_PA_L2CC),
                .length         = SZ_4K,
                .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_GPIO1,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_GPIO1),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_GPIO2,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_GPIO2),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_GPIO3,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_GPIO3),
-               .length         = SZ_256,
-               .type           = MT_DEVICE,
        }, {
                .virtual        = (unsigned long)S5P_VA_DMC0,
                .pfn            = __phys_to_pfn(EXYNOS4_PA_DMC0),
-               .length         = SZ_4K,
+               .length         = SZ_64K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_DMC1,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_DMC1),
+               .length         = SZ_64K,
                .type           = MT_DEVICE,
        }, {
                .virtual        = (unsigned long)S3C_VA_USB_HSPHY,
@@ -201,11 +211,80 @@ static struct map_desc exynos4_iodesc1[] __initdata = {
        },
 };
 
+static struct map_desc exynos5_iodesc[] __initdata = {
+       {
+               .virtual        = (unsigned long)S3C_VA_SYS,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_SYSCON),
+               .length         = SZ_64K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S3C_VA_TIMER,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_TIMER),
+               .length         = SZ_16K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S3C_VA_WATCHDOG,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_WATCHDOG),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_SROMC,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_SROMC),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_SYSTIMER,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_SYSTIMER),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_SYSRAM,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_SYSRAM),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_CMU,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_CMU),
+               .length         = 144 * SZ_1K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_PMU,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_PMU),
+               .length         = SZ_64K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_COMBINER_BASE,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_COMBINER),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S3C_VA_UART,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_UART),
+               .length         = SZ_512K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_GIC_CPU,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_GIC_CPU),
+               .length         = SZ_64K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_GIC_DIST,
+               .pfn            = __phys_to_pfn(EXYNOS5_PA_GIC_DIST),
+               .length         = SZ_64K,
+               .type           = MT_DEVICE,
+       },
+};
+
 void exynos4_restart(char mode, const char *cmd)
 {
        __raw_writel(0x1, S5P_SWRESET);
 }
 
+void exynos5_restart(char mode, const char *cmd)
+{
+       __raw_writel(0x1, EXYNOS_SWRESET);
+}
+
 /*
  * exynos_map_io
  *
@@ -225,7 +304,7 @@ void __init exynos_init_io(struct map_desc *mach_desc, int size)
        s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
 }
 
-void __init exynos4_map_io(void)
+static void __init exynos4_map_io(void)
 {
        iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
 
@@ -256,7 +335,22 @@ void __init exynos4_map_io(void)
        s5p_hdmi_setname("exynos4-hdmi");
 }
 
-void __init exynos4_init_clocks(int xtal)
+static void __init exynos5_map_io(void)
+{
+       iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
+
+       s3c_device_i2c0.resource[0].start = EXYNOS5_PA_IIC(0);
+       s3c_device_i2c0.resource[0].end   = EXYNOS5_PA_IIC(0) + SZ_4K - 1;
+       s3c_device_i2c0.resource[1].start = EXYNOS5_IRQ_IIC;
+       s3c_device_i2c0.resource[1].end   = EXYNOS5_IRQ_IIC;
+
+       /* The I2C bus controllers are directly compatible with s3c2440 */
+       s3c_i2c0_setname("s3c2440-i2c");
+       s3c_i2c1_setname("s3c2440-i2c");
+       s3c_i2c2_setname("s3c2440-i2c");
+}
+
+static void __init exynos4_init_clocks(int xtal)
 {
        printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
 
@@ -272,6 +366,17 @@ void __init exynos4_init_clocks(int xtal)
        exynos4_setup_clocks();
 }
 
+static void __init exynos5_init_clocks(int xtal)
+{
+       printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+       s3c24xx_register_baseclocks(xtal);
+       s5p_register_clocks(xtal);
+
+       exynos5_register_clocks();
+       exynos5_setup_clocks();
+}
+
 #define COMBINER_ENABLE_SET    0x0
 #define COMBINER_ENABLE_CLEAR  0x4
 #define COMBINER_INT_STATUS    0xC
@@ -345,7 +450,14 @@ static struct irq_chip combiner_chip = {
 
 static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
 {
-       if (combiner_nr >= MAX_COMBINER_NR)
+       unsigned int max_nr;
+
+       if (soc_is_exynos5250())
+               max_nr = EXYNOS5_MAX_COMBINER_NR;
+       else
+               max_nr = EXYNOS4_MAX_COMBINER_NR;
+
+       if (combiner_nr >= max_nr)
                BUG();
        if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0)
                BUG();
@@ -356,8 +468,14 @@ static void __init combiner_init(unsigned int combiner_nr, void __iomem *base,
                          unsigned int irq_start)
 {
        unsigned int i;
+       unsigned int max_nr;
 
-       if (combiner_nr >= MAX_COMBINER_NR)
+       if (soc_is_exynos5250())
+               max_nr = EXYNOS5_MAX_COMBINER_NR;
+       else
+               max_nr = EXYNOS4_MAX_COMBINER_NR;
+
+       if (combiner_nr >= max_nr)
                BUG();
 
        combiner_data[combiner_nr].base = base;
@@ -400,7 +518,7 @@ void __init exynos4_init_irq(void)
                of_irq_init(exynos4_dt_irq_match);
 #endif
 
-       for (irq = 0; irq < MAX_COMBINER_NR; irq++) {
+       for (irq = 0; irq < EXYNOS4_MAX_COMBINER_NR; irq++) {
 
                combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
                                COMBINER_IRQ(irq, 0));
@@ -415,56 +533,144 @@ void __init exynos4_init_irq(void)
        s5p_init_irq(NULL, 0);
 }
 
+void __init exynos5_init_irq(void)
+{
+       int irq;
+
+       gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
+
+       for (irq = 0; irq < EXYNOS5_MAX_COMBINER_NR; irq++) {
+               combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
+                               COMBINER_IRQ(irq, 0));
+               combiner_cascade_irq(irq, IRQ_SPI(irq));
+       }
+
+       /*
+        * The parameters of s5p_init_irq() are for VIC init.
+        * Theses parameters should be NULL and 0 because EXYNOS4
+        * uses GIC instead of VIC.
+        */
+       s5p_init_irq(NULL, 0);
+}
+
 struct bus_type exynos4_subsys = {
        .name           = "exynos4-core",
        .dev_name       = "exynos4-core",
 };
 
+struct bus_type exynos5_subsys = {
+       .name           = "exynos5-core",
+       .dev_name       = "exynos5-core",
+};
+
 static struct device exynos4_dev = {
        .bus    = &exynos4_subsys,
 };
 
-static int __init exynos4_core_init(void)
+static struct device exynos5_dev = {
+       .bus    = &exynos5_subsys,
+};
+
+static int __init exynos_core_init(void)
 {
-       return subsys_system_register(&exynos4_subsys, NULL);
+       if (soc_is_exynos5250())
+               return subsys_system_register(&exynos5_subsys, NULL);
+       else
+               return subsys_system_register(&exynos4_subsys, NULL);
 }
-core_initcall(exynos4_core_init);
+core_initcall(exynos_core_init);
 
 #ifdef CONFIG_CACHE_L2X0
 static int __init exynos4_l2x0_cache_init(void)
 {
-       /* TAG, Data Latency Control: 2cycle */
-       __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
+       if (soc_is_exynos5250())
+               return 0;
+
+       int ret;
+       ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
+       if (!ret) {
+               l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
+               clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
+               return 0;
+       }
 
-       if (soc_is_exynos4210())
-               __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
-       else if (soc_is_exynos4212() || soc_is_exynos4412())
-               __raw_writel(0x120, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
+       if (!(__raw_readl(S5P_VA_L2CC + L2X0_CTRL) & 0x1)) {
+               l2x0_saved_regs.phy_base = EXYNOS4_PA_L2CC;
+               /* TAG, Data Latency Control: 2 cycles */
+               l2x0_saved_regs.tag_latency = 0x110;
+
+               if (soc_is_exynos4212() || soc_is_exynos4412())
+                       l2x0_saved_regs.data_latency = 0x120;
+               else
+                       l2x0_saved_regs.data_latency = 0x110;
+
+               l2x0_saved_regs.prefetch_ctrl = 0x30000007;
+               l2x0_saved_regs.pwr_ctrl =
+                       (L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN);
 
-       /* L2X0 Prefetch Control */
-       __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
+               l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
 
-       /* L2X0 Power Control */
-       __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
-                    S5P_VA_L2CC + L2X0_POWER_CTRL);
+               __raw_writel(l2x0_saved_regs.tag_latency,
+                               S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
+               __raw_writel(l2x0_saved_regs.data_latency,
+                               S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
 
-       l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff);
+               /* L2X0 Prefetch Control */
+               __raw_writel(l2x0_saved_regs.prefetch_ctrl,
+                               S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
 
+               /* L2X0 Power Control */
+               __raw_writel(l2x0_saved_regs.pwr_ctrl,
+                               S5P_VA_L2CC + L2X0_POWER_CTRL);
+
+               clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
+               clean_dcache_area(&l2x0_saved_regs, sizeof(struct l2x0_regs));
+       }
+
+       l2x0_init(S5P_VA_L2CC, L2_AUX_VAL, L2_AUX_MASK);
        return 0;
 }
-
 early_initcall(exynos4_l2x0_cache_init);
 #endif
 
-int __init exynos_init(void)
+static int __init exynos5_l2_cache_init(void)
+{
+       unsigned int val;
+
+       if (!soc_is_exynos5250())
+               return 0;
+
+       asm volatile("mrc p15, 0, %0, c1, c0, 0\n"
+                    "bic %0, %0, #(1 << 2)\n"  /* cache disable */
+                    "mcr p15, 0, %0, c1, c0, 0\n"
+                    "mrc p15, 1, %0, c9, c0, 2\n"
+                    : "=r"(val));
+
+       val |= (1 << 9) | (1 << 5) | (2 << 6) | (2 << 0);
+
+       asm volatile("mcr p15, 1, %0, c9, c0, 2\n" : : "r"(val));
+       asm volatile("mrc p15, 0, %0, c1, c0, 0\n"
+                    "orr %0, %0, #(1 << 2)\n"  /* cache enable */
+                    "mcr p15, 0, %0, c1, c0, 0\n"
+                    : : "r"(val));
+
+       return 0;
+}
+early_initcall(exynos5_l2_cache_init);
+
+static int __init exynos_init(void)
 {
        printk(KERN_INFO "EXYNOS: Initializing architecture\n");
-       return device_register(&exynos4_dev);
+
+       if (soc_is_exynos5250())
+               return device_register(&exynos5_dev);
+       else
+               return device_register(&exynos4_dev);
 }
 
 /* uart registration process */
 
-void __init exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+static void __init exynos_init_uarts(struct s3c2410_uartcfg *cfg, int no)
 {
        struct s3c2410_uartcfg *tcfg = cfg;
        u32 ucnt;
@@ -472,69 +678,138 @@ void __init exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no)
        for (ucnt = 0; ucnt < no; ucnt++, tcfg++)
                tcfg->has_fracval = 1;
 
-       s3c24xx_init_uartdevs("exynos4210-uart", s5p_uart_resources, cfg, no);
+       if (soc_is_exynos5250())
+               s3c24xx_init_uartdevs("exynos4210-uart", exynos5_uart_resources, cfg, no);
+       else
+               s3c24xx_init_uartdevs("exynos4210-uart", exynos4_uart_resources, cfg, no);
 }
 
+static void __iomem *exynos_eint_base;
+
 static DEFINE_SPINLOCK(eint_lock);
 
 static unsigned int eint0_15_data[16];
 
-static unsigned int exynos4_get_irq_nr(unsigned int number)
+static inline int exynos4_irq_to_gpio(unsigned int irq)
 {
-       u32 ret = 0;
+       if (irq < IRQ_EINT(0))
+               return -EINVAL;
 
-       switch (number) {
-       case 0 ... 3:
-               ret = (number + IRQ_EINT0);
-               break;
-       case 4 ... 7:
-               ret = (number + (IRQ_EINT4 - 4));
-               break;
-       case 8 ... 15:
-               ret = (number + (IRQ_EINT8 - 8));
-               break;
-       default:
-               printk(KERN_ERR "number available : %d\n", number);
-       }
+       irq -= IRQ_EINT(0);
+       if (irq < 8)
+               return EXYNOS4_GPX0(irq);
+
+       irq -= 8;
+       if (irq < 8)
+               return EXYNOS4_GPX1(irq);
+
+       irq -= 8;
+       if (irq < 8)
+               return EXYNOS4_GPX2(irq);
+
+       irq -= 8;
+       if (irq < 8)
+               return EXYNOS4_GPX3(irq);
+
+       return -EINVAL;
+}
+
+static inline int exynos5_irq_to_gpio(unsigned int irq)
+{
+       if (irq < IRQ_EINT(0))
+               return -EINVAL;
+
+       irq -= IRQ_EINT(0);
+       if (irq < 8)
+               return EXYNOS5_GPX0(irq);
+
+       irq -= 8;
+       if (irq < 8)
+               return EXYNOS5_GPX1(irq);
 
-       return ret;
+       irq -= 8;
+       if (irq < 8)
+               return EXYNOS5_GPX2(irq);
+
+       irq -= 8;
+       if (irq < 8)
+               return EXYNOS5_GPX3(irq);
+
+       return -EINVAL;
 }
 
-static inline void exynos4_irq_eint_mask(struct irq_data *data)
+static unsigned int exynos4_eint0_15_src_int[16] = {
+       EXYNOS4_IRQ_EINT0,
+       EXYNOS4_IRQ_EINT1,
+       EXYNOS4_IRQ_EINT2,
+       EXYNOS4_IRQ_EINT3,
+       EXYNOS4_IRQ_EINT4,
+       EXYNOS4_IRQ_EINT5,
+       EXYNOS4_IRQ_EINT6,
+       EXYNOS4_IRQ_EINT7,
+       EXYNOS4_IRQ_EINT8,
+       EXYNOS4_IRQ_EINT9,
+       EXYNOS4_IRQ_EINT10,
+       EXYNOS4_IRQ_EINT11,
+       EXYNOS4_IRQ_EINT12,
+       EXYNOS4_IRQ_EINT13,
+       EXYNOS4_IRQ_EINT14,
+       EXYNOS4_IRQ_EINT15,
+};
+
+static unsigned int exynos5_eint0_15_src_int[16] = {
+       EXYNOS5_IRQ_EINT0,
+       EXYNOS5_IRQ_EINT1,
+       EXYNOS5_IRQ_EINT2,
+       EXYNOS5_IRQ_EINT3,
+       EXYNOS5_IRQ_EINT4,
+       EXYNOS5_IRQ_EINT5,
+       EXYNOS5_IRQ_EINT6,
+       EXYNOS5_IRQ_EINT7,
+       EXYNOS5_IRQ_EINT8,
+       EXYNOS5_IRQ_EINT9,
+       EXYNOS5_IRQ_EINT10,
+       EXYNOS5_IRQ_EINT11,
+       EXYNOS5_IRQ_EINT12,
+       EXYNOS5_IRQ_EINT13,
+       EXYNOS5_IRQ_EINT14,
+       EXYNOS5_IRQ_EINT15,
+};
+static inline void exynos_irq_eint_mask(struct irq_data *data)
 {
        u32 mask;
 
        spin_lock(&eint_lock);
-       mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
-       mask |= eint_irq_to_bit(data->irq);
-       __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+       mask = __raw_readl(EINT_MASK(exynos_eint_base, data->irq));
+       mask |= EINT_OFFSET_BIT(data->irq);
+       __raw_writel(mask, EINT_MASK(exynos_eint_base, data->irq));
        spin_unlock(&eint_lock);
 }
 
-static void exynos4_irq_eint_unmask(struct irq_data *data)
+static void exynos_irq_eint_unmask(struct irq_data *data)
 {
        u32 mask;
 
        spin_lock(&eint_lock);
-       mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
-       mask &= ~(eint_irq_to_bit(data->irq));
-       __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+       mask = __raw_readl(EINT_MASK(exynos_eint_base, data->irq));
+       mask &= ~(EINT_OFFSET_BIT(data->irq));
+       __raw_writel(mask, EINT_MASK(exynos_eint_base, data->irq));
        spin_unlock(&eint_lock);
 }
 
-static inline void exynos4_irq_eint_ack(struct irq_data *data)
+static inline void exynos_irq_eint_ack(struct irq_data *data)
 {
-       __raw_writel(eint_irq_to_bit(data->irq),
-                    S5P_EINT_PEND(EINT_REG_NR(data->irq)));
+       __raw_writel(EINT_OFFSET_BIT(data->irq),
+                    EINT_PEND(exynos_eint_base, data->irq));
 }
 
-static void exynos4_irq_eint_maskack(struct irq_data *data)
+static void exynos_irq_eint_maskack(struct irq_data *data)
 {
-       exynos4_irq_eint_mask(data);
-       exynos4_irq_eint_ack(data);
+       exynos_irq_eint_mask(data);
+       exynos_irq_eint_ack(data);
 }
 
-static int exynos4_irq_eint_set_type(struct irq_data *data, unsigned int type)
+static int exynos_irq_eint_set_type(struct irq_data *data, unsigned int type)
 {
        int offs = EINT_OFFSET(data->irq);
        int shift;
@@ -571,39 +846,27 @@ static int exynos4_irq_eint_set_type(struct irq_data *data, unsigned int type)
        mask = 0x7 << shift;
 
        spin_lock(&eint_lock);
-       ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq)));
+       ctrl = __raw_readl(EINT_CON(exynos_eint_base, data->irq));
        ctrl &= ~mask;
        ctrl |= newvalue << shift;
-       __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq)));
+       __raw_writel(ctrl, EINT_CON(exynos_eint_base, data->irq));
        spin_unlock(&eint_lock);
 
-       switch (offs) {
-       case 0 ... 7:
-               s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE);
-               break;
-       case 8 ... 15:
-               s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE);
-               break;
-       case 16 ... 23:
-               s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE);
-               break;
-       case 24 ... 31:
-               s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE);
-               break;
-       default:
-               printk(KERN_ERR "No such irq number %d", offs);
-       }
+       if (soc_is_exynos5250())
+               s3c_gpio_cfgpin(exynos5_irq_to_gpio(data->irq), S3C_GPIO_SFN(0xf));
+       else
+               s3c_gpio_cfgpin(exynos4_irq_to_gpio(data->irq), S3C_GPIO_SFN(0xf));
 
        return 0;
 }
 
-static struct irq_chip exynos4_irq_eint = {
-       .name           = "exynos4-eint",
-       .irq_mask       = exynos4_irq_eint_mask,
-       .irq_unmask     = exynos4_irq_eint_unmask,
-       .irq_mask_ack   = exynos4_irq_eint_maskack,
-       .irq_ack        = exynos4_irq_eint_ack,
-       .irq_set_type   = exynos4_irq_eint_set_type,
+static struct irq_chip exynos_irq_eint = {
+       .name           = "exynos-eint",
+       .irq_mask       = exynos_irq_eint_mask,
+       .irq_unmask     = exynos_irq_eint_unmask,
+       .irq_mask_ack   = exynos_irq_eint_maskack,
+       .irq_ack        = exynos_irq_eint_ack,
+       .irq_set_type   = exynos_irq_eint_set_type,
 #ifdef CONFIG_PM
        .irq_set_wake   = s3c_irqext_wake,
 #endif
@@ -618,12 +881,12 @@ static struct irq_chip exynos4_irq_eint = {
  *
  * Each EINT pend/mask registers handle eight of them.
  */
-static inline void exynos4_irq_demux_eint(unsigned int start)
+static inline void exynos_irq_demux_eint(unsigned int start)
 {
        unsigned int irq;
 
-       u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start)));
-       u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start)));
+       u32 status = __raw_readl(EINT_PEND(exynos_eint_base, start));
+       u32 mask = __raw_readl(EINT_MASK(exynos_eint_base, start));
 
        status &= ~mask;
        status &= 0xff;
@@ -635,16 +898,16 @@ static inline void exynos4_irq_demux_eint(unsigned int start)
        }
 }
 
-static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
+static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
 {
        struct irq_chip *chip = irq_get_chip(irq);
        chained_irq_enter(chip, desc);
-       exynos4_irq_demux_eint(IRQ_EINT(16));
-       exynos4_irq_demux_eint(IRQ_EINT(24));
+       exynos_irq_demux_eint(IRQ_EINT(16));
+       exynos_irq_demux_eint(IRQ_EINT(24));
        chained_irq_exit(chip, desc);
 }
 
-static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
+static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
 {
        u32 *irq_data = irq_get_handler_data(irq);
        struct irq_chip *chip = irq_get_chip(irq);
@@ -661,27 +924,44 @@ static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
        chained_irq_exit(chip, desc);
 }
 
-int __init exynos4_init_irq_eint(void)
+static int __init exynos_init_irq_eint(void)
 {
        int irq;
 
+       if (soc_is_exynos5250())
+               exynos_eint_base = ioremap(EXYNOS5_PA_GPIO1, SZ_4K);
+       else
+               exynos_eint_base = ioremap(EXYNOS4_PA_GPIO2, SZ_4K);
+
+       if (exynos_eint_base == NULL) {
+               pr_err("unable to ioremap for EINT base address\n");
+               return -ENOMEM;
+       }
+
        for (irq = 0 ; irq <= 31 ; irq++) {
-               irq_set_chip_and_handler(IRQ_EINT(irq), &exynos4_irq_eint,
+               irq_set_chip_and_handler(IRQ_EINT(irq), &exynos_irq_eint,
                                         handle_level_irq);
                set_irq_flags(IRQ_EINT(irq), IRQF_VALID);
        }
 
-       irq_set_chained_handler(IRQ_EINT16_31, exynos4_irq_demux_eint16_31);
+       irq_set_chained_handler(EXYNOS_IRQ_EINT16_31, exynos_irq_demux_eint16_31);
 
        for (irq = 0 ; irq <= 15 ; irq++) {
                eint0_15_data[irq] = IRQ_EINT(irq);
 
-               irq_set_handler_data(exynos4_get_irq_nr(irq),
-                                    &eint0_15_data[irq]);
-               irq_set_chained_handler(exynos4_get_irq_nr(irq),
-                                       exynos4_irq_eint0_15);
+               if (soc_is_exynos5250()) {
+                       irq_set_handler_data(exynos5_eint0_15_src_int[irq],
+                                            &eint0_15_data[irq]);
+                       irq_set_chained_handler(exynos5_eint0_15_src_int[irq],
+                                               exynos_irq_eint0_15);
+               } else {
+                       irq_set_handler_data(exynos4_eint0_15_src_int[irq],
+                                            &eint0_15_data[irq]);
+                       irq_set_chained_handler(exynos4_eint0_15_src_int[irq],
+                                               exynos_irq_eint0_15);
+               }
        }
 
        return 0;
 }
-arch_initcall(exynos4_init_irq_eint);
+arch_initcall(exynos_init_irq_eint);
index 1ac49de0f39803a257b4a5a82a7e5bbaf70619e8..677b5467df186298ecd2a8f0046e4e6f46c9fdc5 100644 (file)
 #ifndef __ARCH_ARM_MACH_EXYNOS_COMMON_H
 #define __ARCH_ARM_MACH_EXYNOS_COMMON_H
 
+extern struct sys_timer exynos4_timer;
+
 void exynos_init_io(struct map_desc *mach_desc, int size);
 void exynos4_init_irq(void);
+void exynos5_init_irq(void);
+void exynos4_restart(char mode, const char *cmd);
+void exynos5_restart(char mode, const char *cmd);
 
+#ifdef CONFIG_ARCH_EXYNOS4
 void exynos4_register_clocks(void);
 void exynos4_setup_clocks(void);
 
-void exynos4210_register_clocks(void);
-void exynos4212_register_clocks(void);
+#else
+#define exynos4_register_clocks()
+#define exynos4_setup_clocks()
+#endif
 
-void exynos4_restart(char mode, const char *cmd);
+#ifdef CONFIG_ARCH_EXYNOS5
+void exynos5_register_clocks(void);
+void exynos5_setup_clocks(void);
 
-extern struct sys_timer exynos4_timer;
+#else
+#define exynos5_register_clocks()
+#define exynos5_setup_clocks()
+#endif
+
+#ifdef CONFIG_CPU_EXYNOS4210
+void exynos4210_register_clocks(void);
 
-#ifdef CONFIG_ARCH_EXYNOS
-extern  int exynos_init(void);
-extern void exynos4_map_io(void);
-extern void exynos4_init_clocks(int xtal);
-extern void exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+#else
+#define exynos4210_register_clocks()
+#endif
+
+#ifdef CONFIG_SOC_EXYNOS4212
+void exynos4212_register_clocks(void);
 
 #else
-#define exynos4_init_clocks NULL
-#define exynos4_init_uarts NULL
-#define exynos4_map_io NULL
-#define exynos_init NULL
+#define exynos4212_register_clocks()
 #endif
 
 #endif /* __ARCH_ARM_MACH_EXYNOS_COMMON_H */
index 4ebb382c597918e1053a221b35bd52a9e9d1b39a..33ab4e7558af2e6bceb23eadbf2c3fd6f4c9538d 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
 #include <linux/io.h>
 #include <linux/export.h>
 #include <linux/time.h>
 
 #include <asm/proc-fns.h>
+#include <asm/smp_scu.h>
+#include <asm/suspend.h>
+#include <asm/unified.h>
+#include <mach/regs-pmu.h>
+#include <mach/pmu.h>
+
+#include <plat/cpu.h>
+
+#define REG_DIRECTGO_ADDR      (samsung_rev() == EXYNOS4210_REV_1_1 ? \
+                       S5P_INFORM7 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \
+                       (S5P_VA_SYSRAM + 0x24) : S5P_INFORM0))
+#define REG_DIRECTGO_FLAG      (samsung_rev() == EXYNOS4210_REV_1_1 ? \
+                       S5P_INFORM6 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \
+                       (S5P_VA_SYSRAM + 0x20) : S5P_INFORM1))
+
+#define S5P_CHECK_AFTR         0xFCBA0D10
 
 static int exynos4_enter_idle(struct cpuidle_device *dev,
                        struct cpuidle_driver *drv,
                              int index);
+static int exynos4_enter_lowpower(struct cpuidle_device *dev,
+                               struct cpuidle_driver *drv,
+                               int index);
 
-static struct cpuidle_state exynos4_cpuidle_set[] = {
+static struct cpuidle_state exynos4_cpuidle_set[] __initdata = {
        [0] = {
                .enter                  = exynos4_enter_idle,
                .exit_latency           = 1,
                .target_residency       = 100000,
                .flags                  = CPUIDLE_FLAG_TIME_VALID,
-               .name                   = "IDLE",
+               .name                   = "C0",
                .desc                   = "ARM clock gating(WFI)",
        },
+       [1] = {
+               .enter                  = exynos4_enter_lowpower,
+               .exit_latency           = 300,
+               .target_residency       = 100000,
+               .flags                  = CPUIDLE_FLAG_TIME_VALID,
+               .name                   = "C1",
+               .desc                   = "ARM power down",
+       },
 };
 
 static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device);
@@ -39,9 +67,102 @@ static struct cpuidle_driver exynos4_idle_driver = {
        .owner          = THIS_MODULE,
 };
 
+/* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
+static void exynos4_set_wakeupmask(void)
+{
+       __raw_writel(0x0000ff3e, S5P_WAKEUP_MASK);
+}
+
+static unsigned int g_pwr_ctrl, g_diag_reg;
+
+static void save_cpu_arch_register(void)
+{
+       /*read power control register*/
+       asm("mrc p15, 0, %0, c15, c0, 0" : "=r"(g_pwr_ctrl) : : "cc");
+       /*read diagnostic register*/
+       asm("mrc p15, 0, %0, c15, c0, 1" : "=r"(g_diag_reg) : : "cc");
+       return;
+}
+
+static void restore_cpu_arch_register(void)
+{
+       /*write power control register*/
+       asm("mcr p15, 0, %0, c15, c0, 0" : : "r"(g_pwr_ctrl) : "cc");
+       /*write diagnostic register*/
+       asm("mcr p15, 0, %0, c15, c0, 1" : : "r"(g_diag_reg) : "cc");
+       return;
+}
+
+static int idle_finisher(unsigned long flags)
+{
+       cpu_do_idle();
+       return 1;
+}
+
+static int exynos4_enter_core0_aftr(struct cpuidle_device *dev,
+                               struct cpuidle_driver *drv,
+                               int index)
+{
+       struct timeval before, after;
+       int idle_time;
+       unsigned long tmp;
+
+       local_irq_disable();
+       do_gettimeofday(&before);
+
+       exynos4_set_wakeupmask();
+
+       /* Set value of power down register for aftr mode */
+       exynos4_sys_powerdown_conf(SYS_AFTR);
+
+       __raw_writel(virt_to_phys(s3c_cpu_resume), REG_DIRECTGO_ADDR);
+       __raw_writel(S5P_CHECK_AFTR, REG_DIRECTGO_FLAG);
+
+       save_cpu_arch_register();
+
+       /* Setting Central Sequence Register for power down mode */
+       tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
+       tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
+       __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
+
+       cpu_pm_enter();
+       cpu_suspend(0, idle_finisher);
+
+#ifdef CONFIG_SMP
+       scu_enable(S5P_VA_SCU);
+#endif
+       cpu_pm_exit();
+
+       restore_cpu_arch_register();
+
+       /*
+        * If PMU failed while entering sleep mode, WFI will be
+        * ignored by PMU and then exiting cpu_do_idle().
+        * S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically
+        * in this situation.
+        */
+       tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
+       if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) {
+               tmp |= S5P_CENTRAL_LOWPWR_CFG;
+               __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
+       }
+
+       /* Clear wakeup state register */
+       __raw_writel(0x0, S5P_WAKEUP_STAT);
+
+       do_gettimeofday(&after);
+
+       local_irq_enable();
+       idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+                   (after.tv_usec - before.tv_usec);
+
+       dev->last_residency = idle_time;
+       return index;
+}
+
 static int exynos4_enter_idle(struct cpuidle_device *dev,
                                struct cpuidle_driver *drv,
-                             int index)
+                               int index)
 {
        struct timeval before, after;
        int idle_time;
@@ -60,6 +181,22 @@ static int exynos4_enter_idle(struct cpuidle_device *dev,
        return index;
 }
 
+static int exynos4_enter_lowpower(struct cpuidle_device *dev,
+                               struct cpuidle_driver *drv,
+                               int index)
+{
+       int new_index = index;
+
+       /* This mode only can be entered when other core's are offline */
+       if (num_online_cpus() > 1)
+               new_index = drv->safe_state_index;
+
+       if (new_index == 0)
+               return exynos4_enter_idle(dev, drv, new_index);
+       else
+               return exynos4_enter_core0_aftr(dev, drv, new_index);
+}
+
 static int __init exynos4_init_cpuidle(void)
 {
        int i, max_cpuidle_state, cpu_id;
@@ -74,19 +211,25 @@ static int __init exynos4_init_cpuidle(void)
                memcpy(&drv->states[i], &exynos4_cpuidle_set[i],
                                sizeof(struct cpuidle_state));
        }
+       drv->safe_state_index = 0;
        cpuidle_register_driver(&exynos4_idle_driver);
 
        for_each_cpu(cpu_id, cpu_online_mask) {
                device = &per_cpu(exynos4_cpuidle_device, cpu_id);
                device->cpu = cpu_id;
 
-               device->state_count = drv->state_count;
+               if (cpu_id == 0)
+                       device->state_count = (sizeof(exynos4_cpuidle_set) /
+                                              sizeof(struct cpuidle_state));
+               else
+                       device->state_count = 1;        /* Support IDLE only */
 
                if (cpuidle_register_device(device)) {
                        printk(KERN_ERR "CPUidle register device failed\n,");
                        return -EIO;
                }
        }
+
        return 0;
 }
 device_initcall(exynos4_init_cpuidle);
index f57a3de8e1d28acd584d76e1fb4dc4a810c94c73..50ce5b0adcf1e7639643d92720ee92c5cc23ba54 100644 (file)
@@ -242,8 +242,8 @@ static struct resource exynos4_ahci_resource[] = {
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = IRQ_SATA,
-               .end    = IRQ_SATA,
+               .start  = EXYNOS4_IRQ_SATA,
+               .end    = EXYNOS4_IRQ_SATA,
                .flags  = IORESOURCE_IRQ,
        },
 };
index 5a9f9c2e53bfd4ae2eb47eeaa78f7b20369f965f..7199e1ae79b436339b06bf93ba0c513b91f12186 100644 (file)
@@ -304,8 +304,8 @@ static struct resource exynos4_ac97_resource[] = {
                .flags  = IORESOURCE_DMA,
        },
        [4] = {
-               .start  = IRQ_AC97,
-               .end    = IRQ_AC97,
+               .start  = EXYNOS4_IRQ_AC97,
+               .end    = EXYNOS4_IRQ_AC97,
                .flags  = IORESOURCE_IRQ,
        },
 };
diff --git a/arch/arm/mach-exynos/dev-uart.c b/arch/arm/mach-exynos/dev-uart.c
new file mode 100644 (file)
index 0000000..2e85c02
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Base EXYNOS UART resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+#define EXYNOS_UART_RESOURCE(_series, _nr)     \
+static struct resource exynos##_series##_uart##_nr##_resource[] = {    \
+       [0] = DEFINE_RES_MEM(EXYNOS##_series##_PA_UART##_nr, EXYNOS##_series##_SZ_UART),        \
+       [1] = DEFINE_RES_IRQ(EXYNOS##_series##_IRQ_UART##_nr),  \
+};
+
+EXYNOS_UART_RESOURCE(4, 0)
+EXYNOS_UART_RESOURCE(4, 1)
+EXYNOS_UART_RESOURCE(4, 2)
+EXYNOS_UART_RESOURCE(4, 3)
+
+struct s3c24xx_uart_resources exynos4_uart_resources[] __initdata = {
+       [0] = {
+               .resources      = exynos4_uart0_resource,
+               .nr_resources   = ARRAY_SIZE(exynos4_uart0_resource),
+       },
+       [1] = {
+               .resources      = exynos4_uart1_resource,
+               .nr_resources   = ARRAY_SIZE(exynos4_uart1_resource),
+       },
+       [2] = {
+               .resources      = exynos4_uart2_resource,
+               .nr_resources   = ARRAY_SIZE(exynos4_uart2_resource),
+       },
+       [3] = {
+               .resources      = exynos4_uart3_resource,
+               .nr_resources   = ARRAY_SIZE(exynos4_uart3_resource),
+       },
+};
+
+EXYNOS_UART_RESOURCE(5, 0)
+EXYNOS_UART_RESOURCE(5, 1)
+EXYNOS_UART_RESOURCE(5, 2)
+EXYNOS_UART_RESOURCE(5, 3)
+
+struct s3c24xx_uart_resources exynos5_uart_resources[] __initdata = {
+       [0] = {
+               .resources      = exynos5_uart0_resource,
+               .nr_resources   = ARRAY_SIZE(exynos5_uart0_resource),
+       },
+       [1] = {
+               .resources      = exynos5_uart1_resource,
+               .nr_resources   = ARRAY_SIZE(exynos5_uart0_resource),
+       },
+       [2] = {
+               .resources      = exynos5_uart2_resource,
+               .nr_resources   = ARRAY_SIZE(exynos5_uart2_resource),
+       },
+       [3] = {
+               .resources      = exynos5_uart3_resource,
+               .nr_resources   = ARRAY_SIZE(exynos5_uart3_resource),
+       },
+};
index 91370def4a70997fa2a8aea0f3184115a052bc0c..3983abee4264fb629b0dc16c083307703e71085b 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/irq.h>
 #include <plat/devs.h>
 #include <plat/irqs.h>
+#include <plat/cpu.h>
 
 #include <mach/map.h>
 #include <mach/irqs.h>
@@ -36,7 +37,7 @@
 
 static u64 dma_dmamask = DMA_BIT_MASK(32);
 
-u8 pdma0_peri[] = {
+static u8 exynos4210_pdma0_peri[] = {
        DMACH_PCM0_RX,
        DMACH_PCM0_TX,
        DMACH_PCM2_RX,
@@ -69,15 +70,47 @@ u8 pdma0_peri[] = {
        DMACH_AC97_PCMOUT,
 };
 
-struct dma_pl330_platdata exynos4_pdma0_pdata = {
-       .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
-       .peri_id = pdma0_peri,
+static u8 exynos4212_pdma0_peri[] = {
+       DMACH_PCM0_RX,
+       DMACH_PCM0_TX,
+       DMACH_PCM2_RX,
+       DMACH_PCM2_TX,
+       DMACH_MIPI_HSI0,
+       DMACH_MIPI_HSI1,
+       DMACH_SPI0_RX,
+       DMACH_SPI0_TX,
+       DMACH_SPI2_RX,
+       DMACH_SPI2_TX,
+       DMACH_I2S0S_TX,
+       DMACH_I2S0_RX,
+       DMACH_I2S0_TX,
+       DMACH_I2S2_RX,
+       DMACH_I2S2_TX,
+       DMACH_UART0_RX,
+       DMACH_UART0_TX,
+       DMACH_UART2_RX,
+       DMACH_UART2_TX,
+       DMACH_UART4_RX,
+       DMACH_UART4_TX,
+       DMACH_SLIMBUS0_RX,
+       DMACH_SLIMBUS0_TX,
+       DMACH_SLIMBUS2_RX,
+       DMACH_SLIMBUS2_TX,
+       DMACH_SLIMBUS4_RX,
+       DMACH_SLIMBUS4_TX,
+       DMACH_AC97_MICIN,
+       DMACH_AC97_PCMIN,
+       DMACH_AC97_PCMOUT,
+       DMACH_MIPI_HSI4,
+       DMACH_MIPI_HSI5,
 };
 
-AMBA_AHB_DEVICE(exynos4_pdma0, "dma-pl330.0", 0x00041330, EXYNOS4_PA_PDMA0,
-       {IRQ_PDMA0}, &exynos4_pdma0_pdata);
+struct dma_pl330_platdata exynos4_pdma0_pdata;
+
+static AMBA_AHB_DEVICE(exynos4_pdma0, "dma-pl330.0", 0x00041330,
+       EXYNOS4_PA_PDMA0, {EXYNOS4_IRQ_PDMA0}, &exynos4_pdma0_pdata);
 
-u8 pdma1_peri[] = {
+static u8 exynos4210_pdma1_peri[] = {
        DMACH_PCM0_RX,
        DMACH_PCM0_TX,
        DMACH_PCM1_RX,
@@ -105,19 +138,84 @@ u8 pdma1_peri[] = {
        DMACH_SLIMBUS5_TX,
 };
 
-struct dma_pl330_platdata exynos4_pdma1_pdata = {
-       .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
-       .peri_id = pdma1_peri,
+static u8 exynos4212_pdma1_peri[] = {
+       DMACH_PCM0_RX,
+       DMACH_PCM0_TX,
+       DMACH_PCM1_RX,
+       DMACH_PCM1_TX,
+       DMACH_MIPI_HSI2,
+       DMACH_MIPI_HSI3,
+       DMACH_SPI1_RX,
+       DMACH_SPI1_TX,
+       DMACH_I2S0S_TX,
+       DMACH_I2S0_RX,
+       DMACH_I2S0_TX,
+       DMACH_I2S1_RX,
+       DMACH_I2S1_TX,
+       DMACH_UART0_RX,
+       DMACH_UART0_TX,
+       DMACH_UART1_RX,
+       DMACH_UART1_TX,
+       DMACH_UART3_RX,
+       DMACH_UART3_TX,
+       DMACH_SLIMBUS1_RX,
+       DMACH_SLIMBUS1_TX,
+       DMACH_SLIMBUS3_RX,
+       DMACH_SLIMBUS3_TX,
+       DMACH_SLIMBUS5_RX,
+       DMACH_SLIMBUS5_TX,
+       DMACH_SLIMBUS0AUX_RX,
+       DMACH_SLIMBUS0AUX_TX,
+       DMACH_SPDIF,
+       DMACH_MIPI_HSI6,
+       DMACH_MIPI_HSI7,
+};
+
+static struct dma_pl330_platdata exynos4_pdma1_pdata;
+
+static AMBA_AHB_DEVICE(exynos4_pdma1,  "dma-pl330.1", 0x00041330,
+       EXYNOS4_PA_PDMA1, {EXYNOS4_IRQ_PDMA1}, &exynos4_pdma1_pdata);
+
+static u8 mdma_peri[] = {
+       DMACH_MTOM_0,
+       DMACH_MTOM_1,
+       DMACH_MTOM_2,
+       DMACH_MTOM_3,
+       DMACH_MTOM_4,
+       DMACH_MTOM_5,
+       DMACH_MTOM_6,
+       DMACH_MTOM_7,
 };
 
-AMBA_AHB_DEVICE(exynos4_pdma1,  "dma-pl330.1", 0x00041330, EXYNOS4_PA_PDMA1,
-       {IRQ_PDMA1}, &exynos4_pdma1_pdata);
+static struct dma_pl330_platdata exynos4_mdma1_pdata = {
+       .nr_valid_peri = ARRAY_SIZE(mdma_peri),
+       .peri_id = mdma_peri,
+};
+
+static AMBA_AHB_DEVICE(exynos4_mdma1,  "dma-pl330.2", 0x00041330,
+       EXYNOS4_PA_MDMA1, {EXYNOS4_IRQ_MDMA1}, &exynos4_mdma1_pdata);
 
 static int __init exynos4_dma_init(void)
 {
        if (of_have_populated_dt())
                return 0;
 
+       if (soc_is_exynos4210()) {
+               exynos4_pdma0_pdata.nr_valid_peri =
+                       ARRAY_SIZE(exynos4210_pdma0_peri);
+               exynos4_pdma0_pdata.peri_id = exynos4210_pdma0_peri;
+               exynos4_pdma1_pdata.nr_valid_peri =
+                       ARRAY_SIZE(exynos4210_pdma1_peri);
+               exynos4_pdma1_pdata.peri_id = exynos4210_pdma1_peri;
+       } else if (soc_is_exynos4212() || soc_is_exynos4412()) {
+               exynos4_pdma0_pdata.nr_valid_peri =
+                       ARRAY_SIZE(exynos4212_pdma0_peri);
+               exynos4_pdma0_pdata.peri_id = exynos4212_pdma0_peri;
+               exynos4_pdma1_pdata.nr_valid_peri =
+                       ARRAY_SIZE(exynos4212_pdma1_peri);
+               exynos4_pdma1_pdata.peri_id = exynos4212_pdma1_peri;
+       }
+
        dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask);
        dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask);
        amba_device_register(&exynos4_pdma0_device, &iomem_resource);
@@ -126,6 +224,9 @@ static int __init exynos4_dma_init(void)
        dma_cap_set(DMA_CYCLIC, exynos4_pdma1_pdata.cap_mask);
        amba_device_register(&exynos4_pdma1_device, &iomem_resource);
 
+       dma_cap_set(DMA_MEMCPY, exynos4_mdma1_pdata.cap_mask);
+       amba_device_register(&exynos4_mdma1_device, &iomem_resource);
+
        return 0;
 }
 arch_initcall(exynos4_dma_init);
index 6cacf16a67a6e2e4bab156f6dfeffedd04f7746e..6c857ff0b5d84670f65287230801a7bf2cf5d974 100644 (file)
         */
 
        .macro addruart, rp, rv, tmp
-               ldr     \rp, = S3C_PA_UART
-               ldr     \rv, = S3C_VA_UART
+               mov     \rp, #0x10000000
+               ldr     \rp, [\rp, #0x0]
+               and     \rp, \rp, #0xf00000
+               teq     \rp, #0x500000          @@ EXYNOS5
+               ldreq   \rp, =EXYNOS5_PA_UART
+               movne   \rp, #EXYNOS4_PA_UART   @@ EXYNOS4
+               ldr     \rv, =S3C_VA_UART
 #if CONFIG_DEBUG_S3C_UART != 0
                add     \rp, \rp, #(0x10000 * CONFIG_DEBUG_S3C_UART)
                add     \rv, \rv, #(0x10000 * CONFIG_DEBUG_S3C_UART)
diff --git a/arch/arm/mach-exynos/include/mach/exynos4-clock.h b/arch/arm/mach-exynos/include/mach/exynos4-clock.h
deleted file mode 100644 (file)
index a07fcbf..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/include/mach/exynos4-clock.h
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Header file for exynos4 clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_CLOCK_H
-#define __ASM_ARCH_CLOCK_H __FILE__
-
-#include <linux/clk.h>
-
-extern struct clk clk_sclk_hdmi27m;
-extern struct clk clk_sclk_usbphy0;
-extern struct clk clk_sclk_usbphy1;
-extern struct clk clk_sclk_hdmiphy;
-
-extern struct clksrc_clk clk_sclk_apll;
-extern struct clksrc_clk clk_mout_mpll;
-extern struct clksrc_clk clk_aclk_133;
-extern struct clksrc_clk clk_mout_epll;
-extern struct clksrc_clk clk_sclk_vpll;
-
-extern struct clk *clkset_corebus_list[];
-extern struct clksrc_sources clkset_mout_corebus;
-
-extern struct clk *clkset_aclk_top_list[];
-extern struct clksrc_sources clkset_aclk;
-
-extern struct clk *clkset_group_list[];
-extern struct clksrc_sources clkset_group;
-
-extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable);
-extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable);
-extern int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable);
-
-#endif /* __ASM_ARCH_CLOCK_H */
index 80523ca9bb49b87030220b9725e3c58b4922ed53..d7498afe036ad4acd92c3c7a5a6c7b3f441a9d8b 100644 (file)
@@ -1,9 +1,8 @@
-/* linux/arch/arm/mach-exynos4/include/mach/gpio.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+/*
+ * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
  *
- * EXYNOS4 - GPIO lib support
+ * EXYNOS - GPIO lib support
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 #ifndef __ASM_ARCH_GPIO_H
 #define __ASM_ARCH_GPIO_H __FILE__
 
-/* Practically, GPIO banks up to GPZ are the configurable gpio banks */
+/* Macro for EXYNOS GPIO numbering */
+
+#define EXYNOS_GPIO_NEXT(__gpio) \
+       ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+/* EXYNOS4 GPIO bank sizes */
 
-/* GPIO bank sizes */
 #define EXYNOS4_GPIO_A0_NR     (8)
 #define EXYNOS4_GPIO_A1_NR     (6)
 #define EXYNOS4_GPIO_B_NR      (8)
 #define EXYNOS4_GPIO_Y6_NR     (8)
 #define EXYNOS4_GPIO_Z_NR      (7)
 
-/* GPIO bank numbers */
-
-#define EXYNOS4_GPIO_NEXT(__gpio) \
-       ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+/* EXYNOS4 GPIO bank numbers */
 
-enum s5p_gpio_number {
+enum exynos4_gpio_number {
        EXYNOS4_GPIO_A0_START   = 0,
-       EXYNOS4_GPIO_A1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A0),
-       EXYNOS4_GPIO_B_START    = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A1),
-       EXYNOS4_GPIO_C0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_B),
-       EXYNOS4_GPIO_C1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C0),
-       EXYNOS4_GPIO_D0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C1),
-       EXYNOS4_GPIO_D1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D0),
-       EXYNOS4_GPIO_E0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D1),
-       EXYNOS4_GPIO_E1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E0),
-       EXYNOS4_GPIO_E2_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E1),
-       EXYNOS4_GPIO_E3_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E2),
-       EXYNOS4_GPIO_E4_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E3),
-       EXYNOS4_GPIO_F0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E4),
-       EXYNOS4_GPIO_F1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F0),
-       EXYNOS4_GPIO_F2_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F1),
-       EXYNOS4_GPIO_F3_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F2),
-       EXYNOS4_GPIO_J0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F3),
-       EXYNOS4_GPIO_J1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_J0),
-       EXYNOS4_GPIO_K0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_J1),
-       EXYNOS4_GPIO_K1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K0),
-       EXYNOS4_GPIO_K2_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K1),
-       EXYNOS4_GPIO_K3_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K2),
-       EXYNOS4_GPIO_L0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K3),
-       EXYNOS4_GPIO_L1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L0),
-       EXYNOS4_GPIO_L2_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L1),
-       EXYNOS4_GPIO_X0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L2),
-       EXYNOS4_GPIO_X1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X0),
-       EXYNOS4_GPIO_X2_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X1),
-       EXYNOS4_GPIO_X3_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X2),
-       EXYNOS4_GPIO_Y0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X3),
-       EXYNOS4_GPIO_Y1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y0),
-       EXYNOS4_GPIO_Y2_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y1),
-       EXYNOS4_GPIO_Y3_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y2),
-       EXYNOS4_GPIO_Y4_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y3),
-       EXYNOS4_GPIO_Y5_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y4),
-       EXYNOS4_GPIO_Y6_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y5),
-       EXYNOS4_GPIO_Z_START    = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y6),
+       EXYNOS4_GPIO_A1_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_A0),
+       EXYNOS4_GPIO_B_START    = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_A1),
+       EXYNOS4_GPIO_C0_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_B),
+       EXYNOS4_GPIO_C1_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_C0),
+       EXYNOS4_GPIO_D0_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_C1),
+       EXYNOS4_GPIO_D1_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_D0),
+       EXYNOS4_GPIO_E0_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_D1),
+       EXYNOS4_GPIO_E1_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E0),
+       EXYNOS4_GPIO_E2_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E1),
+       EXYNOS4_GPIO_E3_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E2),
+       EXYNOS4_GPIO_E4_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E3),
+       EXYNOS4_GPIO_F0_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E4),
+       EXYNOS4_GPIO_F1_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F0),
+       EXYNOS4_GPIO_F2_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F1),
+       EXYNOS4_GPIO_F3_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F2),
+       EXYNOS4_GPIO_J0_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F3),
+       EXYNOS4_GPIO_J1_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_J0),
+       EXYNOS4_GPIO_K0_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_J1),
+       EXYNOS4_GPIO_K1_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K0),
+       EXYNOS4_GPIO_K2_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K1),
+       EXYNOS4_GPIO_K3_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K2),
+       EXYNOS4_GPIO_L0_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K3),
+       EXYNOS4_GPIO_L1_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_L0),
+       EXYNOS4_GPIO_L2_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_L1),
+       EXYNOS4_GPIO_X0_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_L2),
+       EXYNOS4_GPIO_X1_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X0),
+       EXYNOS4_GPIO_X2_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X1),
+       EXYNOS4_GPIO_X3_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X2),
+       EXYNOS4_GPIO_Y0_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X3),
+       EXYNOS4_GPIO_Y1_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y0),
+       EXYNOS4_GPIO_Y2_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y1),
+       EXYNOS4_GPIO_Y3_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y2),
+       EXYNOS4_GPIO_Y4_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y3),
+       EXYNOS4_GPIO_Y5_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y4),
+       EXYNOS4_GPIO_Y6_START   = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y5),
+       EXYNOS4_GPIO_Z_START    = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y6),
 };
 
 /* EXYNOS4 GPIO number definitions */
+
 #define EXYNOS4_GPA0(_nr)      (EXYNOS4_GPIO_A0_START + (_nr))
 #define EXYNOS4_GPA1(_nr)      (EXYNOS4_GPIO_A1_START + (_nr))
 #define EXYNOS4_GPB(_nr)       (EXYNOS4_GPIO_B_START + (_nr))
@@ -139,11 +140,147 @@ enum s5p_gpio_number {
 #define EXYNOS4_GPZ(_nr)       (EXYNOS4_GPIO_Z_START + (_nr))
 
 /* the end of the EXYNOS4 specific gpios */
+
 #define EXYNOS4_GPIO_END       (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) + 1)
-#define S3C_GPIO_END           EXYNOS4_GPIO_END
 
-/* define the number of gpios we need to the one after the GPZ() range */
-#define ARCH_NR_GPIOS          (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) +       \
-                                CONFIG_SAMSUNG_GPIO_EXTRA + 1)
+/* EXYNOS5 GPIO bank sizes */
+
+#define EXYNOS5_GPIO_A0_NR     (8)
+#define EXYNOS5_GPIO_A1_NR     (6)
+#define EXYNOS5_GPIO_A2_NR     (8)
+#define EXYNOS5_GPIO_B0_NR     (5)
+#define EXYNOS5_GPIO_B1_NR     (5)
+#define EXYNOS5_GPIO_B2_NR     (4)
+#define EXYNOS5_GPIO_B3_NR     (4)
+#define EXYNOS5_GPIO_C0_NR     (7)
+#define EXYNOS5_GPIO_C1_NR     (7)
+#define EXYNOS5_GPIO_C2_NR     (7)
+#define EXYNOS5_GPIO_C3_NR     (7)
+#define EXYNOS5_GPIO_D0_NR     (8)
+#define EXYNOS5_GPIO_D1_NR     (8)
+#define EXYNOS5_GPIO_Y0_NR     (6)
+#define EXYNOS5_GPIO_Y1_NR     (4)
+#define EXYNOS5_GPIO_Y2_NR     (6)
+#define EXYNOS5_GPIO_Y3_NR     (8)
+#define EXYNOS5_GPIO_Y4_NR     (8)
+#define EXYNOS5_GPIO_Y5_NR     (8)
+#define EXYNOS5_GPIO_Y6_NR     (8)
+#define EXYNOS5_GPIO_X0_NR     (8)
+#define EXYNOS5_GPIO_X1_NR     (8)
+#define EXYNOS5_GPIO_X2_NR     (8)
+#define EXYNOS5_GPIO_X3_NR     (8)
+#define EXYNOS5_GPIO_E0_NR     (8)
+#define EXYNOS5_GPIO_E1_NR     (2)
+#define EXYNOS5_GPIO_F0_NR     (4)
+#define EXYNOS5_GPIO_F1_NR     (4)
+#define EXYNOS5_GPIO_G0_NR     (8)
+#define EXYNOS5_GPIO_G1_NR     (8)
+#define EXYNOS5_GPIO_G2_NR     (2)
+#define EXYNOS5_GPIO_H0_NR     (4)
+#define EXYNOS5_GPIO_H1_NR     (8)
+#define EXYNOS5_GPIO_V0_NR     (8)
+#define EXYNOS5_GPIO_V1_NR     (8)
+#define EXYNOS5_GPIO_V2_NR     (8)
+#define EXYNOS5_GPIO_V3_NR     (8)
+#define EXYNOS5_GPIO_V4_NR     (2)
+#define EXYNOS5_GPIO_Z_NR      (7)
+
+/* EXYNOS5 GPIO bank numbers */
+
+enum exynos5_gpio_number {
+       EXYNOS5_GPIO_A0_START           = 0,
+       EXYNOS5_GPIO_A1_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_A0),
+       EXYNOS5_GPIO_A2_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_A1),
+       EXYNOS5_GPIO_B0_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_A2),
+       EXYNOS5_GPIO_B1_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B0),
+       EXYNOS5_GPIO_B2_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B1),
+       EXYNOS5_GPIO_B3_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B2),
+       EXYNOS5_GPIO_C0_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B3),
+       EXYNOS5_GPIO_C1_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C0),
+       EXYNOS5_GPIO_C2_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C1),
+       EXYNOS5_GPIO_C3_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C2),
+       EXYNOS5_GPIO_D0_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C3),
+       EXYNOS5_GPIO_D1_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D0),
+       EXYNOS5_GPIO_Y0_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D1),
+       EXYNOS5_GPIO_Y1_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y0),
+       EXYNOS5_GPIO_Y2_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y1),
+       EXYNOS5_GPIO_Y3_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y2),
+       EXYNOS5_GPIO_Y4_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y3),
+       EXYNOS5_GPIO_Y5_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y4),
+       EXYNOS5_GPIO_Y6_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y5),
+       EXYNOS5_GPIO_X0_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y6),
+       EXYNOS5_GPIO_X1_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X0),
+       EXYNOS5_GPIO_X2_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X1),
+       EXYNOS5_GPIO_X3_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X2),
+       EXYNOS5_GPIO_E0_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X3),
+       EXYNOS5_GPIO_E1_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_E0),
+       EXYNOS5_GPIO_F0_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_E1),
+       EXYNOS5_GPIO_F1_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_F0),
+       EXYNOS5_GPIO_G0_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_F1),
+       EXYNOS5_GPIO_G1_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_G0),
+       EXYNOS5_GPIO_G2_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_G1),
+       EXYNOS5_GPIO_H0_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_G2),
+       EXYNOS5_GPIO_H1_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_H0),
+       EXYNOS5_GPIO_V0_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_H1),
+       EXYNOS5_GPIO_V1_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V0),
+       EXYNOS5_GPIO_V2_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V1),
+       EXYNOS5_GPIO_V3_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V2),
+       EXYNOS5_GPIO_V4_START           = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V3),
+       EXYNOS5_GPIO_Z_START            = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V4),
+};
+
+/* EXYNOS5 GPIO number definitions */
+
+#define EXYNOS5_GPA0(_nr)      (EXYNOS5_GPIO_A0_START + (_nr))
+#define EXYNOS5_GPA1(_nr)      (EXYNOS5_GPIO_A1_START + (_nr))
+#define EXYNOS5_GPA2(_nr)      (EXYNOS5_GPIO_A2_START + (_nr))
+#define EXYNOS5_GPB0(_nr)      (EXYNOS5_GPIO_B0_START + (_nr))
+#define EXYNOS5_GPB1(_nr)      (EXYNOS5_GPIO_B1_START + (_nr))
+#define EXYNOS5_GPB2(_nr)      (EXYNOS5_GPIO_B2_START + (_nr))
+#define EXYNOS5_GPB3(_nr)      (EXYNOS5_GPIO_B3_START + (_nr))
+#define EXYNOS5_GPC0(_nr)      (EXYNOS5_GPIO_C0_START + (_nr))
+#define EXYNOS5_GPC1(_nr)      (EXYNOS5_GPIO_C1_START + (_nr))
+#define EXYNOS5_GPC2(_nr)      (EXYNOS5_GPIO_C2_START + (_nr))
+#define EXYNOS5_GPC3(_nr)      (EXYNOS5_GPIO_C3_START + (_nr))
+#define EXYNOS5_GPD0(_nr)      (EXYNOS5_GPIO_D0_START + (_nr))
+#define EXYNOS5_GPD1(_nr)      (EXYNOS5_GPIO_D1_START + (_nr))
+#define EXYNOS5_GPY0(_nr)      (EXYNOS5_GPIO_Y0_START + (_nr))
+#define EXYNOS5_GPY1(_nr)      (EXYNOS5_GPIO_Y1_START + (_nr))
+#define EXYNOS5_GPY2(_nr)      (EXYNOS5_GPIO_Y2_START + (_nr))
+#define EXYNOS5_GPY3(_nr)      (EXYNOS5_GPIO_Y3_START + (_nr))
+#define EXYNOS5_GPY4(_nr)      (EXYNOS5_GPIO_Y4_START + (_nr))
+#define EXYNOS5_GPY5(_nr)      (EXYNOS5_GPIO_Y5_START + (_nr))
+#define EXYNOS5_GPY6(_nr)      (EXYNOS5_GPIO_Y6_START + (_nr))
+#define EXYNOS5_GPX0(_nr)      (EXYNOS5_GPIO_X0_START + (_nr))
+#define EXYNOS5_GPX1(_nr)      (EXYNOS5_GPIO_X1_START + (_nr))
+#define EXYNOS5_GPX2(_nr)      (EXYNOS5_GPIO_X2_START + (_nr))
+#define EXYNOS5_GPX3(_nr)      (EXYNOS5_GPIO_X3_START + (_nr))
+#define EXYNOS5_GPE0(_nr)      (EXYNOS5_GPIO_E0_START + (_nr))
+#define EXYNOS5_GPE1(_nr)      (EXYNOS5_GPIO_E1_START + (_nr))
+#define EXYNOS5_GPF0(_nr)      (EXYNOS5_GPIO_F0_START + (_nr))
+#define EXYNOS5_GPF1(_nr)      (EXYNOS5_GPIO_F1_START + (_nr))
+#define EXYNOS5_GPG0(_nr)      (EXYNOS5_GPIO_G0_START + (_nr))
+#define EXYNOS5_GPG1(_nr)      (EXYNOS5_GPIO_G1_START + (_nr))
+#define EXYNOS5_GPG2(_nr)      (EXYNOS5_GPIO_G2_START + (_nr))
+#define EXYNOS5_GPH0(_nr)      (EXYNOS5_GPIO_H0_START + (_nr))
+#define EXYNOS5_GPH1(_nr)      (EXYNOS5_GPIO_H1_START + (_nr))
+#define EXYNOS5_GPV0(_nr)      (EXYNOS5_GPIO_V0_START + (_nr))
+#define EXYNOS5_GPV1(_nr)      (EXYNOS5_GPIO_V1_START + (_nr))
+#define EXYNOS5_GPV2(_nr)      (EXYNOS5_GPIO_V2_START + (_nr))
+#define EXYNOS5_GPV3(_nr)      (EXYNOS5_GPIO_V3_START + (_nr))
+#define EXYNOS5_GPV4(_nr)      (EXYNOS5_GPIO_V4_START + (_nr))
+#define EXYNOS5_GPZ(_nr)       (EXYNOS5_GPIO_Z_START + (_nr))
+
+/* the end of the EXYNOS5 specific gpios */
+
+#define EXYNOS5_GPIO_END       (EXYNOS5_GPZ(EXYNOS5_GPIO_Z_NR) + 1)
+
+/* actually, EXYNOS5_GPIO_END is bigger than EXYNOS4 */
+
+#define S3C_GPIO_END           (EXYNOS5_GPIO_END)
+
+/* define the number of gpios */
+
+#define ARCH_NR_GPIOS          (CONFIG_SAMSUNG_GPIO_EXTRA + S3C_GPIO_END)
 
 #endif /* __ASM_ARCH_GPIO_H */
index f77bce04789aadc8ade57f9ed88f16e85f31e4a2..9bee8535d9e0aa994960de244002b198975a8709 100644 (file)
@@ -1,9 +1,8 @@
-/* linux/arch/arm/mach-exynos4/include/mach/irqs.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+/*
+ * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
  *
- * EXYNOS4 - IRQ definitions
+ * EXYNOS - IRQ definitions
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 
 /* PPI: Private Peripheral Interrupt */
 
-#define IRQ_PPI(x)             (x+16)
-
-#define IRQ_MCT_LOCALTIMER     IRQ_PPI(12)
+#define IRQ_PPI(x)                     (x + 16)
 
 /* SPI: Shared Peripheral Interrupt */
 
-#define IRQ_SPI(x)             (x+32)
-
-#define IRQ_EINT0              IRQ_SPI(16)
-#define IRQ_EINT1              IRQ_SPI(17)
-#define IRQ_EINT2              IRQ_SPI(18)
-#define IRQ_EINT3              IRQ_SPI(19)
-#define IRQ_EINT4              IRQ_SPI(20)
-#define IRQ_EINT5              IRQ_SPI(21)
-#define IRQ_EINT6              IRQ_SPI(22)
-#define IRQ_EINT7              IRQ_SPI(23)
-#define IRQ_EINT8              IRQ_SPI(24)
-#define IRQ_EINT9              IRQ_SPI(25)
-#define IRQ_EINT10             IRQ_SPI(26)
-#define IRQ_EINT11             IRQ_SPI(27)
-#define IRQ_EINT12             IRQ_SPI(28)
-#define IRQ_EINT13             IRQ_SPI(29)
-#define IRQ_EINT14             IRQ_SPI(30)
-#define IRQ_EINT15             IRQ_SPI(31)
-#define IRQ_EINT16_31          IRQ_SPI(32)
-
-#define IRQ_PDMA0              IRQ_SPI(35)
-#define IRQ_PDMA1              IRQ_SPI(36)
-#define IRQ_TIMER0_VIC         IRQ_SPI(37)
-#define IRQ_TIMER1_VIC         IRQ_SPI(38)
-#define IRQ_TIMER2_VIC         IRQ_SPI(39)
-#define IRQ_TIMER3_VIC         IRQ_SPI(40)
-#define IRQ_TIMER4_VIC         IRQ_SPI(41)
-#define IRQ_MCT_L0             IRQ_SPI(42)
-#define IRQ_WDT                        IRQ_SPI(43)
-#define IRQ_RTC_ALARM          IRQ_SPI(44)
-#define IRQ_RTC_TIC            IRQ_SPI(45)
-#define IRQ_GPIO_XB            IRQ_SPI(46)
-#define IRQ_GPIO_XA            IRQ_SPI(47)
-#define IRQ_MCT_L1             IRQ_SPI(48)
-
-#define IRQ_UART0              IRQ_SPI(52)
-#define IRQ_UART1              IRQ_SPI(53)
-#define IRQ_UART2              IRQ_SPI(54)
-#define IRQ_UART3              IRQ_SPI(55)
-#define IRQ_UART4              IRQ_SPI(56)
-#define IRQ_MCT_G0             IRQ_SPI(57)
-#define IRQ_IIC                        IRQ_SPI(58)
-#define IRQ_IIC1               IRQ_SPI(59)
-#define IRQ_IIC2               IRQ_SPI(60)
-#define IRQ_IIC3               IRQ_SPI(61)
-#define IRQ_IIC4               IRQ_SPI(62)
-#define IRQ_IIC5               IRQ_SPI(63)
-#define IRQ_IIC6               IRQ_SPI(64)
-#define IRQ_IIC7               IRQ_SPI(65)
-#define IRQ_SPI0               IRQ_SPI(66)
-#define IRQ_SPI1               IRQ_SPI(67)
-#define IRQ_SPI2               IRQ_SPI(68)
-
-#define IRQ_USB_HOST           IRQ_SPI(70)
-#define IRQ_USB_HSOTG          IRQ_SPI(71)
-#define IRQ_MODEM_IF           IRQ_SPI(72)
-#define IRQ_HSMMC0             IRQ_SPI(73)
-#define IRQ_HSMMC1             IRQ_SPI(74)
-#define IRQ_HSMMC2             IRQ_SPI(75)
-#define IRQ_HSMMC3             IRQ_SPI(76)
-#define IRQ_DWMCI              IRQ_SPI(77)
-
-#define IRQ_MIPI_CSIS0         IRQ_SPI(78)
-#define IRQ_MIPI_CSIS1         IRQ_SPI(80)
-
-#define IRQ_ONENAND_AUDI       IRQ_SPI(82)
-#define IRQ_ROTATOR            IRQ_SPI(83)
-#define IRQ_FIMC0              IRQ_SPI(84)
-#define IRQ_FIMC1              IRQ_SPI(85)
-#define IRQ_FIMC2              IRQ_SPI(86)
-#define IRQ_FIMC3              IRQ_SPI(87)
-#define IRQ_JPEG               IRQ_SPI(88)
-#define IRQ_2D                 IRQ_SPI(89)
-#define IRQ_PCIE               IRQ_SPI(90)
-
-#define IRQ_MIXER              IRQ_SPI(91)
-#define IRQ_HDMI               IRQ_SPI(92)
-#define IRQ_IIC_HDMIPHY                IRQ_SPI(93)
-#define IRQ_MFC                        IRQ_SPI(94)
-#define IRQ_SDO                        IRQ_SPI(95)
-
-#define IRQ_AUDIO_SS           IRQ_SPI(96)
-#define IRQ_I2S0               IRQ_SPI(97)
-#define IRQ_I2S1               IRQ_SPI(98)
-#define IRQ_I2S2               IRQ_SPI(99)
-#define IRQ_AC97               IRQ_SPI(100)
-
-#define IRQ_SPDIF              IRQ_SPI(104)
-#define IRQ_ADC0               IRQ_SPI(105)
-#define IRQ_PEN0               IRQ_SPI(106)
-#define IRQ_ADC1               IRQ_SPI(107)
-#define IRQ_PEN1               IRQ_SPI(108)
-#define IRQ_KEYPAD             IRQ_SPI(109)
-#define IRQ_PMU                        IRQ_SPI(110)
-#define IRQ_GPS                        IRQ_SPI(111)
-#define IRQ_INTFEEDCTRL_SSS    IRQ_SPI(112)
-#define IRQ_SLIMBUS            IRQ_SPI(113)
-
-#define IRQ_TSI                        IRQ_SPI(115)
-#define IRQ_SATA               IRQ_SPI(116)
-
-#define MAX_IRQ_IN_COMBINER    8
-#define COMBINER_GROUP(x)      ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(128))
-#define COMBINER_IRQ(x, y)     (COMBINER_GROUP(x) + y)
-
-#define IRQ_SYSMMU_MDMA0_0     COMBINER_IRQ(4, 0)
-#define IRQ_SYSMMU_SSS_0       COMBINER_IRQ(4, 1)
-#define IRQ_SYSMMU_FIMC0_0     COMBINER_IRQ(4, 2)
-#define IRQ_SYSMMU_FIMC1_0     COMBINER_IRQ(4, 3)
-#define IRQ_SYSMMU_FIMC2_0     COMBINER_IRQ(4, 4)
-#define IRQ_SYSMMU_FIMC3_0     COMBINER_IRQ(4, 5)
-#define IRQ_SYSMMU_JPEG_0      COMBINER_IRQ(4, 6)
-#define IRQ_SYSMMU_2D_0                COMBINER_IRQ(4, 7)
-
-#define IRQ_SYSMMU_ROTATOR_0   COMBINER_IRQ(5, 0)
-#define IRQ_SYSMMU_MDMA1_0     COMBINER_IRQ(5, 1)
-#define IRQ_SYSMMU_LCD0_M0_0   COMBINER_IRQ(5, 2)
-#define IRQ_SYSMMU_LCD1_M1_0   COMBINER_IRQ(5, 3)
-#define IRQ_SYSMMU_TV_M0_0     COMBINER_IRQ(5, 4)
-#define IRQ_SYSMMU_MFC_M0_0    COMBINER_IRQ(5, 5)
-#define IRQ_SYSMMU_MFC_M1_0    COMBINER_IRQ(5, 6)
-#define IRQ_SYSMMU_PCIE_0      COMBINER_IRQ(5, 7)
-
-#define IRQ_FIMD0_FIFO         COMBINER_IRQ(11, 0)
-#define IRQ_FIMD0_VSYNC                COMBINER_IRQ(11, 1)
-#define IRQ_FIMD0_SYSTEM       COMBINER_IRQ(11, 2)
-
-#define MAX_COMBINER_NR                16
-
-#define IRQ_ADC                        IRQ_ADC0
-#define IRQ_TC                 IRQ_PEN0
-
-#define S5P_IRQ_EINT_BASE      COMBINER_IRQ(MAX_COMBINER_NR, 0)
-
-#define S5P_EINT_BASE1         (S5P_IRQ_EINT_BASE + 0)
-#define S5P_EINT_BASE2         (S5P_IRQ_EINT_BASE + 16)
-
-/* optional GPIO interrupts */
-#define S5P_GPIOINT_BASE       (S5P_IRQ_EINT_BASE + 32)
-#define IRQ_GPIO1_NR_GROUPS    16
-#define IRQ_GPIO2_NR_GROUPS    9
-#define IRQ_GPIO_END           (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT)
-
-#define IRQ_TIMER_BASE         (IRQ_GPIO_END + 64)
+#define IRQ_SPI(x)                     (x + 32)
+
+/* COMBINER */
+
+#define MAX_IRQ_IN_COMBINER            8
+#define COMBINER_GROUP(x)              ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(128))
+#define COMBINER_IRQ(x, y)             (COMBINER_GROUP(x) + y)
+
+/* For EXYNOS4 and EXYNOS5 */
+
+#define EXYNOS_IRQ_MCT_LOCALTIMER      IRQ_PPI(12)
+
+#define EXYNOS_IRQ_EINT16_31           IRQ_SPI(32)
+
+/* For EXYNOS4 SoCs */
+
+#define EXYNOS4_IRQ_EINT0              IRQ_SPI(16)
+#define EXYNOS4_IRQ_EINT1              IRQ_SPI(17)
+#define EXYNOS4_IRQ_EINT2              IRQ_SPI(18)
+#define EXYNOS4_IRQ_EINT3              IRQ_SPI(19)
+#define EXYNOS4_IRQ_EINT4              IRQ_SPI(20)
+#define EXYNOS4_IRQ_EINT5              IRQ_SPI(21)
+#define EXYNOS4_IRQ_EINT6              IRQ_SPI(22)
+#define EXYNOS4_IRQ_EINT7              IRQ_SPI(23)
+#define EXYNOS4_IRQ_EINT8              IRQ_SPI(24)
+#define EXYNOS4_IRQ_EINT9              IRQ_SPI(25)
+#define EXYNOS4_IRQ_EINT10             IRQ_SPI(26)
+#define EXYNOS4_IRQ_EINT11             IRQ_SPI(27)
+#define EXYNOS4_IRQ_EINT12             IRQ_SPI(28)
+#define EXYNOS4_IRQ_EINT13             IRQ_SPI(29)
+#define EXYNOS4_IRQ_EINT14             IRQ_SPI(30)
+#define EXYNOS4_IRQ_EINT15             IRQ_SPI(31)
+
+#define EXYNOS4_IRQ_MDMA0              IRQ_SPI(33)
+#define EXYNOS4_IRQ_MDMA1              IRQ_SPI(34)
+#define EXYNOS4_IRQ_PDMA0              IRQ_SPI(35)
+#define EXYNOS4_IRQ_PDMA1              IRQ_SPI(36)
+#define EXYNOS4_IRQ_TIMER0_VIC         IRQ_SPI(37)
+#define EXYNOS4_IRQ_TIMER1_VIC         IRQ_SPI(38)
+#define EXYNOS4_IRQ_TIMER2_VIC         IRQ_SPI(39)
+#define EXYNOS4_IRQ_TIMER3_VIC         IRQ_SPI(40)
+#define EXYNOS4_IRQ_TIMER4_VIC         IRQ_SPI(41)
+#define EXYNOS4_IRQ_MCT_L0             IRQ_SPI(42)
+#define EXYNOS4_IRQ_WDT                        IRQ_SPI(43)
+#define EXYNOS4_IRQ_RTC_ALARM          IRQ_SPI(44)
+#define EXYNOS4_IRQ_RTC_TIC            IRQ_SPI(45)
+#define EXYNOS4_IRQ_GPIO_XB            IRQ_SPI(46)
+#define EXYNOS4_IRQ_GPIO_XA            IRQ_SPI(47)
+#define EXYNOS4_IRQ_MCT_L1             IRQ_SPI(48)
+
+#define EXYNOS4_IRQ_UART0              IRQ_SPI(52)
+#define EXYNOS4_IRQ_UART1              IRQ_SPI(53)
+#define EXYNOS4_IRQ_UART2              IRQ_SPI(54)
+#define EXYNOS4_IRQ_UART3              IRQ_SPI(55)
+#define EXYNOS4_IRQ_UART4              IRQ_SPI(56)
+#define EXYNOS4_IRQ_MCT_G0             IRQ_SPI(57)
+#define EXYNOS4_IRQ_IIC                        IRQ_SPI(58)
+#define EXYNOS4_IRQ_IIC1               IRQ_SPI(59)
+#define EXYNOS4_IRQ_IIC2               IRQ_SPI(60)
+#define EXYNOS4_IRQ_IIC3               IRQ_SPI(61)
+#define EXYNOS4_IRQ_IIC4               IRQ_SPI(62)
+#define EXYNOS4_IRQ_IIC5               IRQ_SPI(63)
+#define EXYNOS4_IRQ_IIC6               IRQ_SPI(64)
+#define EXYNOS4_IRQ_IIC7               IRQ_SPI(65)
+#define EXYNOS4_IRQ_SPI0               IRQ_SPI(66)
+#define EXYNOS4_IRQ_SPI1               IRQ_SPI(67)
+#define EXYNOS4_IRQ_SPI2               IRQ_SPI(68)
+
+#define EXYNOS4_IRQ_USB_HOST           IRQ_SPI(70)
+#define EXYNOS4_IRQ_USB_HSOTG          IRQ_SPI(71)
+#define EXYNOS4_IRQ_MODEM_IF           IRQ_SPI(72)
+#define EXYNOS4_IRQ_HSMMC0             IRQ_SPI(73)
+#define EXYNOS4_IRQ_HSMMC1             IRQ_SPI(74)
+#define EXYNOS4_IRQ_HSMMC2             IRQ_SPI(75)
+#define EXYNOS4_IRQ_HSMMC3             IRQ_SPI(76)
+#define EXYNOS4_IRQ_DWMCI              IRQ_SPI(77)
+
+#define EXYNOS4_IRQ_MIPI_CSIS0         IRQ_SPI(78)
+#define EXYNOS4_IRQ_MIPI_CSIS1         IRQ_SPI(80)
+
+#define EXYNOS4_IRQ_ONENAND_AUDI       IRQ_SPI(82)
+#define EXYNOS4_IRQ_ROTATOR            IRQ_SPI(83)
+#define EXYNOS4_IRQ_FIMC0              IRQ_SPI(84)
+#define EXYNOS4_IRQ_FIMC1              IRQ_SPI(85)
+#define EXYNOS4_IRQ_FIMC2              IRQ_SPI(86)
+#define EXYNOS4_IRQ_FIMC3              IRQ_SPI(87)
+#define EXYNOS4_IRQ_JPEG               IRQ_SPI(88)
+#define EXYNOS4_IRQ_2D                 IRQ_SPI(89)
+#define EXYNOS4_IRQ_PCIE               IRQ_SPI(90)
+
+#define EXYNOS4_IRQ_MIXER              IRQ_SPI(91)
+#define EXYNOS4_IRQ_HDMI               IRQ_SPI(92)
+#define EXYNOS4_IRQ_IIC_HDMIPHY                IRQ_SPI(93)
+#define EXYNOS4_IRQ_MFC                        IRQ_SPI(94)
+#define EXYNOS4_IRQ_SDO                        IRQ_SPI(95)
+
+#define EXYNOS4_IRQ_AUDIO_SS           IRQ_SPI(96)
+#define EXYNOS4_IRQ_I2S0               IRQ_SPI(97)
+#define EXYNOS4_IRQ_I2S1               IRQ_SPI(98)
+#define EXYNOS4_IRQ_I2S2               IRQ_SPI(99)
+#define EXYNOS4_IRQ_AC97               IRQ_SPI(100)
+
+#define EXYNOS4_IRQ_SPDIF              IRQ_SPI(104)
+#define EXYNOS4_IRQ_ADC0               IRQ_SPI(105)
+#define EXYNOS4_IRQ_PEN0               IRQ_SPI(106)
+#define EXYNOS4_IRQ_ADC1               IRQ_SPI(107)
+#define EXYNOS4_IRQ_PEN1               IRQ_SPI(108)
+#define EXYNOS4_IRQ_KEYPAD             IRQ_SPI(109)
+#define EXYNOS4_IRQ_PMU                        IRQ_SPI(110)
+#define EXYNOS4_IRQ_GPS                        IRQ_SPI(111)
+#define EXYNOS4_IRQ_INTFEEDCTRL_SSS    IRQ_SPI(112)
+#define EXYNOS4_IRQ_SLIMBUS            IRQ_SPI(113)
+
+#define EXYNOS4_IRQ_TSI                        IRQ_SPI(115)
+#define EXYNOS4_IRQ_SATA               IRQ_SPI(116)
+
+#define EXYNOS4_IRQ_SYSMMU_MDMA0_0     COMBINER_IRQ(4, 0)
+#define EXYNOS4_IRQ_SYSMMU_SSS_0       COMBINER_IRQ(4, 1)
+#define EXYNOS4_IRQ_SYSMMU_FIMC0_0     COMBINER_IRQ(4, 2)
+#define EXYNOS4_IRQ_SYSMMU_FIMC1_0     COMBINER_IRQ(4, 3)
+#define EXYNOS4_IRQ_SYSMMU_FIMC2_0     COMBINER_IRQ(4, 4)
+#define EXYNOS4_IRQ_SYSMMU_FIMC3_0     COMBINER_IRQ(4, 5)
+#define EXYNOS4_IRQ_SYSMMU_JPEG_0      COMBINER_IRQ(4, 6)
+#define EXYNOS4_IRQ_SYSMMU_2D_0                COMBINER_IRQ(4, 7)
+
+#define EXYNOS4_IRQ_SYSMMU_ROTATOR_0   COMBINER_IRQ(5, 0)
+#define EXYNOS4_IRQ_SYSMMU_MDMA1_0     COMBINER_IRQ(5, 1)
+#define EXYNOS4_IRQ_SYSMMU_LCD0_M0_0   COMBINER_IRQ(5, 2)
+#define EXYNOS4_IRQ_SYSMMU_LCD1_M1_0   COMBINER_IRQ(5, 3)
+#define EXYNOS4_IRQ_SYSMMU_TV_M0_0     COMBINER_IRQ(5, 4)
+#define EXYNOS4_IRQ_SYSMMU_MFC_M0_0    COMBINER_IRQ(5, 5)
+#define EXYNOS4_IRQ_SYSMMU_MFC_M1_0    COMBINER_IRQ(5, 6)
+#define EXYNOS4_IRQ_SYSMMU_PCIE_0      COMBINER_IRQ(5, 7)
+
+#define EXYNOS4_IRQ_FIMD0_FIFO         COMBINER_IRQ(11, 0)
+#define EXYNOS4_IRQ_FIMD0_VSYNC                COMBINER_IRQ(11, 1)
+#define EXYNOS4_IRQ_FIMD0_SYSTEM       COMBINER_IRQ(11, 2)
+
+#define EXYNOS4_MAX_COMBINER_NR                16
+
+#define EXYNOS4_IRQ_GPIO1_NR_GROUPS    16
+#define EXYNOS4_IRQ_GPIO2_NR_GROUPS    9
+
+/*
+ * For Compatibility:
+ * the default is for EXYNOS4, and
+ * for exynos5, should be re-mapped at function
+ */
+
+#define IRQ_TIMER0_VIC                 EXYNOS4_IRQ_TIMER0_VIC
+#define IRQ_TIMER1_VIC                 EXYNOS4_IRQ_TIMER1_VIC
+#define IRQ_TIMER2_VIC                 EXYNOS4_IRQ_TIMER2_VIC
+#define IRQ_TIMER3_VIC                 EXYNOS4_IRQ_TIMER3_VIC
+#define IRQ_TIMER4_VIC                 EXYNOS4_IRQ_TIMER4_VIC
+
+#define IRQ_WDT                                EXYNOS4_IRQ_WDT
+#define IRQ_RTC_ALARM                  EXYNOS4_IRQ_RTC_ALARM
+#define IRQ_RTC_TIC                    EXYNOS4_IRQ_RTC_TIC
+#define IRQ_GPIO_XB                    EXYNOS4_IRQ_GPIO_XB
+#define IRQ_GPIO_XA                    EXYNOS4_IRQ_GPIO_XA
+
+#define IRQ_IIC                                EXYNOS4_IRQ_IIC
+#define IRQ_IIC1                       EXYNOS4_IRQ_IIC1
+#define IRQ_IIC3                       EXYNOS4_IRQ_IIC3
+#define IRQ_IIC5                       EXYNOS4_IRQ_IIC5
+#define IRQ_IIC6                       EXYNOS4_IRQ_IIC6
+#define IRQ_IIC7                       EXYNOS4_IRQ_IIC7
+
+#define IRQ_USB_HOST                   EXYNOS4_IRQ_USB_HOST
+
+#define IRQ_HSMMC0                     EXYNOS4_IRQ_HSMMC0
+#define IRQ_HSMMC1                     EXYNOS4_IRQ_HSMMC1
+#define IRQ_HSMMC2                     EXYNOS4_IRQ_HSMMC2
+#define IRQ_HSMMC3                     EXYNOS4_IRQ_HSMMC3
+
+#define IRQ_MIPI_CSIS0                 EXYNOS4_IRQ_MIPI_CSIS0
+
+#define IRQ_ONENAND_AUDI               EXYNOS4_IRQ_ONENAND_AUDI
+
+#define IRQ_FIMC0                      EXYNOS4_IRQ_FIMC0
+#define IRQ_FIMC1                      EXYNOS4_IRQ_FIMC1
+#define IRQ_FIMC2                      EXYNOS4_IRQ_FIMC2
+#define IRQ_FIMC3                      EXYNOS4_IRQ_FIMC3
+#define IRQ_JPEG                       EXYNOS4_IRQ_JPEG
+#define IRQ_2D                         EXYNOS4_IRQ_2D
+
+#define IRQ_MIXER                      EXYNOS4_IRQ_MIXER
+#define IRQ_HDMI                       EXYNOS4_IRQ_HDMI
+#define IRQ_IIC_HDMIPHY                        EXYNOS4_IRQ_IIC_HDMIPHY
+#define IRQ_MFC                                EXYNOS4_IRQ_MFC
+#define IRQ_SDO                                EXYNOS4_IRQ_SDO
+
+#define IRQ_ADC                                EXYNOS4_IRQ_ADC0
+#define IRQ_TC                         EXYNOS4_IRQ_PEN0
+
+#define IRQ_KEYPAD                     EXYNOS4_IRQ_KEYPAD
+#define IRQ_PMU                                EXYNOS4_IRQ_PMU
+
+#define IRQ_SYSMMU_MDMA0_0             EXYNOS4_IRQ_SYSMMU_MDMA0_0
+#define IRQ_SYSMMU_SSS_0                EXYNOS4_IRQ_SYSMMU_SSS_0
+#define IRQ_SYSMMU_FIMC0_0              EXYNOS4_IRQ_SYSMMU_FIMC0_0
+#define IRQ_SYSMMU_FIMC1_0              EXYNOS4_IRQ_SYSMMU_FIMC1_0
+#define IRQ_SYSMMU_FIMC2_0              EXYNOS4_IRQ_SYSMMU_FIMC2_0
+#define IRQ_SYSMMU_FIMC3_0              EXYNOS4_IRQ_SYSMMU_FIMC3_0
+#define IRQ_SYSMMU_JPEG_0               EXYNOS4_IRQ_SYSMMU_JPEG_0
+#define IRQ_SYSMMU_2D_0                 EXYNOS4_IRQ_SYSMMU_2D_0
+
+#define IRQ_SYSMMU_ROTATOR_0            EXYNOS4_IRQ_SYSMMU_ROTATOR_0
+#define IRQ_SYSMMU_MDMA1_0              EXYNOS4_IRQ_SYSMMU_MDMA1_0
+#define IRQ_SYSMMU_LCD0_M0_0            EXYNOS4_IRQ_SYSMMU_LCD0_M0_0
+#define IRQ_SYSMMU_LCD1_M1_0            EXYNOS4_IRQ_SYSMMU_LCD1_M1_0
+#define IRQ_SYSMMU_TV_M0_0              EXYNOS4_IRQ_SYSMMU_TV_M0_0
+#define IRQ_SYSMMU_MFC_M0_0             EXYNOS4_IRQ_SYSMMU_MFC_M0_0
+#define IRQ_SYSMMU_MFC_M1_0             EXYNOS4_IRQ_SYSMMU_MFC_M1_0
+#define IRQ_SYSMMU_PCIE_0               EXYNOS4_IRQ_SYSMMU_PCIE_0
+
+#define IRQ_FIMD0_FIFO                 EXYNOS4_IRQ_FIMD0_FIFO
+#define IRQ_FIMD0_VSYNC                        EXYNOS4_IRQ_FIMD0_VSYNC
+#define IRQ_FIMD0_SYSTEM               EXYNOS4_IRQ_FIMD0_SYSTEM
+
+#define IRQ_GPIO1_NR_GROUPS            EXYNOS4_IRQ_GPIO1_NR_GROUPS
+#define IRQ_GPIO2_NR_GROUPS            EXYNOS4_IRQ_GPIO2_NR_GROUPS
+
+/* For EXYNOS5 SoCs */
+
+#define EXYNOS5_IRQ_MDMA0              IRQ_SPI(33)
+#define EXYNOS5_IRQ_PDMA0              IRQ_SPI(34)
+#define EXYNOS5_IRQ_PDMA1              IRQ_SPI(35)
+#define EXYNOS5_IRQ_TIMER0_VIC         IRQ_SPI(36)
+#define EXYNOS5_IRQ_TIMER1_VIC         IRQ_SPI(37)
+#define EXYNOS5_IRQ_TIMER2_VIC         IRQ_SPI(38)
+#define EXYNOS5_IRQ_TIMER3_VIC         IRQ_SPI(39)
+#define EXYNOS5_IRQ_TIMER4_VIC         IRQ_SPI(40)
+#define EXYNOS5_IRQ_RTIC               IRQ_SPI(41)
+#define EXYNOS5_IRQ_WDT                        IRQ_SPI(42)
+#define EXYNOS5_IRQ_RTC_ALARM          IRQ_SPI(43)
+#define EXYNOS5_IRQ_RTC_TIC            IRQ_SPI(44)
+#define EXYNOS5_IRQ_GPIO_XB            IRQ_SPI(45)
+#define EXYNOS5_IRQ_GPIO_XA            IRQ_SPI(46)
+#define EXYNOS5_IRQ_GPIO               IRQ_SPI(47)
+#define EXYNOS5_IRQ_IEM_IEC            IRQ_SPI(48)
+#define EXYNOS5_IRQ_IEM_APC            IRQ_SPI(49)
+#define EXYNOS5_IRQ_GPIO_C2C           IRQ_SPI(50)
+#define EXYNOS5_IRQ_UART0              IRQ_SPI(51)
+#define EXYNOS5_IRQ_UART1              IRQ_SPI(52)
+#define EXYNOS5_IRQ_UART2              IRQ_SPI(53)
+#define EXYNOS5_IRQ_UART3              IRQ_SPI(54)
+#define EXYNOS5_IRQ_UART4              IRQ_SPI(55)
+#define EXYNOS5_IRQ_IIC                        IRQ_SPI(56)
+#define EXYNOS5_IRQ_IIC1               IRQ_SPI(57)
+#define EXYNOS5_IRQ_IIC2               IRQ_SPI(58)
+#define EXYNOS5_IRQ_IIC3               IRQ_SPI(59)
+#define EXYNOS5_IRQ_IIC4               IRQ_SPI(60)
+#define EXYNOS5_IRQ_IIC5               IRQ_SPI(61)
+#define EXYNOS5_IRQ_IIC6               IRQ_SPI(62)
+#define EXYNOS5_IRQ_IIC7               IRQ_SPI(63)
+#define EXYNOS5_IRQ_IIC_HDMIPHY                IRQ_SPI(64)
+#define EXYNOS5_IRQ_TMU                        IRQ_SPI(65)
+#define EXYNOS5_IRQ_FIQ_0              IRQ_SPI(66)
+#define EXYNOS5_IRQ_FIQ_1              IRQ_SPI(67)
+#define EXYNOS5_IRQ_SPI0               IRQ_SPI(68)
+#define EXYNOS5_IRQ_SPI1               IRQ_SPI(69)
+#define EXYNOS5_IRQ_SPI2               IRQ_SPI(70)
+#define EXYNOS5_IRQ_USB_HOST           IRQ_SPI(71)
+#define EXYNOS5_IRQ_USB3_DRD           IRQ_SPI(72)
+#define EXYNOS5_IRQ_MIPI_HSI           IRQ_SPI(73)
+#define EXYNOS5_IRQ_USB_HSOTG          IRQ_SPI(74)
+#define EXYNOS5_IRQ_HSMMC0             IRQ_SPI(75)
+#define EXYNOS5_IRQ_HSMMC1             IRQ_SPI(76)
+#define EXYNOS5_IRQ_HSMMC2             IRQ_SPI(77)
+#define EXYNOS5_IRQ_HSMMC3             IRQ_SPI(78)
+#define EXYNOS5_IRQ_MIPICSI0           IRQ_SPI(79)
+#define EXYNOS5_IRQ_MIPICSI1           IRQ_SPI(80)
+#define EXYNOS5_IRQ_EFNFCON_DMA_ABORT  IRQ_SPI(81)
+#define EXYNOS5_IRQ_MIPIDSI0           IRQ_SPI(82)
+#define EXYNOS5_IRQ_ROTATOR            IRQ_SPI(84)
+#define EXYNOS5_IRQ_GSC0               IRQ_SPI(85)
+#define EXYNOS5_IRQ_GSC1               IRQ_SPI(86)
+#define EXYNOS5_IRQ_GSC2               IRQ_SPI(87)
+#define EXYNOS5_IRQ_GSC3               IRQ_SPI(88)
+#define EXYNOS5_IRQ_JPEG               IRQ_SPI(89)
+#define EXYNOS5_IRQ_EFNFCON_DMA                IRQ_SPI(90)
+#define EXYNOS5_IRQ_2D                 IRQ_SPI(91)
+#define EXYNOS5_IRQ_SFMC0              IRQ_SPI(92)
+#define EXYNOS5_IRQ_SFMC1              IRQ_SPI(93)
+#define EXYNOS5_IRQ_MIXER              IRQ_SPI(94)
+#define EXYNOS5_IRQ_HDMI               IRQ_SPI(95)
+#define EXYNOS5_IRQ_MFC                        IRQ_SPI(96)
+#define EXYNOS5_IRQ_AUDIO_SS           IRQ_SPI(97)
+#define EXYNOS5_IRQ_I2S0               IRQ_SPI(98)
+#define EXYNOS5_IRQ_I2S1               IRQ_SPI(99)
+#define EXYNOS5_IRQ_I2S2               IRQ_SPI(100)
+#define EXYNOS5_IRQ_AC97               IRQ_SPI(101)
+#define EXYNOS5_IRQ_PCM0               IRQ_SPI(102)
+#define EXYNOS5_IRQ_PCM1               IRQ_SPI(103)
+#define EXYNOS5_IRQ_PCM2               IRQ_SPI(104)
+#define EXYNOS5_IRQ_SPDIF              IRQ_SPI(105)
+#define EXYNOS5_IRQ_ADC0               IRQ_SPI(106)
+
+#define EXYNOS5_IRQ_SATA_PHY           IRQ_SPI(108)
+#define EXYNOS5_IRQ_SATA_PMEMREQ       IRQ_SPI(109)
+#define EXYNOS5_IRQ_CAM_C              IRQ_SPI(110)
+#define EXYNOS5_IRQ_EAGLE_PMU          IRQ_SPI(111)
+#define EXYNOS5_IRQ_INTFEEDCTRL_SSS    IRQ_SPI(112)
+#define EXYNOS5_IRQ_DP1_INTP1          IRQ_SPI(113)
+#define EXYNOS5_IRQ_CEC                        IRQ_SPI(114)
+#define EXYNOS5_IRQ_SATA               IRQ_SPI(115)
+#define EXYNOS5_IRQ_NFCON              IRQ_SPI(116)
+
+#define EXYNOS5_IRQ_MMC44              IRQ_SPI(123)
+#define EXYNOS5_IRQ_MDMA1              IRQ_SPI(124)
+#define EXYNOS5_IRQ_FIMC_LITE0         IRQ_SPI(125)
+#define EXYNOS5_IRQ_FIMC_LITE1         IRQ_SPI(126)
+#define EXYNOS5_IRQ_RP_TIMER           IRQ_SPI(127)
+
+#define EXYNOS5_IRQ_PMU                        COMBINER_IRQ(1, 2)
+#define EXYNOS5_IRQ_PMU_CPU1           COMBINER_IRQ(1, 6)
+
+#define EXYNOS5_IRQ_SYSMMU_GSC0_0      COMBINER_IRQ(2, 0)
+#define EXYNOS5_IRQ_SYSMMU_GSC0_1      COMBINER_IRQ(2, 1)
+#define EXYNOS5_IRQ_SYSMMU_GSC1_0      COMBINER_IRQ(2, 2)
+#define EXYNOS5_IRQ_SYSMMU_GSC1_1      COMBINER_IRQ(2, 3)
+#define EXYNOS5_IRQ_SYSMMU_GSC2_0      COMBINER_IRQ(2, 4)
+#define EXYNOS5_IRQ_SYSMMU_GSC2_1      COMBINER_IRQ(2, 5)
+#define EXYNOS5_IRQ_SYSMMU_GSC3_0      COMBINER_IRQ(2, 6)
+#define EXYNOS5_IRQ_SYSMMU_GSC3_1      COMBINER_IRQ(2, 7)
+
+#define EXYNOS5_IRQ_SYSMMU_FIMD1_0     COMBINER_IRQ(3, 2)
+#define EXYNOS5_IRQ_SYSMMU_FIMD1_1     COMBINER_IRQ(3, 3)
+#define EXYNOS5_IRQ_SYSMMU_LITE0_0     COMBINER_IRQ(3, 4)
+#define EXYNOS5_IRQ_SYSMMU_LITE0_1     COMBINER_IRQ(3, 5)
+#define EXYNOS5_IRQ_SYSMMU_SCALERPISP_0        COMBINER_IRQ(3, 6)
+#define EXYNOS5_IRQ_SYSMMU_SCALERPISP_1        COMBINER_IRQ(3, 7)
+
+#define EXYNOS5_IRQ_SYSMMU_ROTATOR_0   COMBINER_IRQ(4, 0)
+#define EXYNOS5_IRQ_SYSMMU_ROTATOR_1   COMBINER_IRQ(4, 1)
+#define EXYNOS5_IRQ_SYSMMU_JPEG_0      COMBINER_IRQ(4, 2)
+#define EXYNOS5_IRQ_SYSMMU_JPEG_1      COMBINER_IRQ(4, 3)
+
+#define EXYNOS5_IRQ_SYSMMU_FD_0                COMBINER_IRQ(5, 0)
+#define EXYNOS5_IRQ_SYSMMU_FD_1                COMBINER_IRQ(5, 1)
+#define EXYNOS5_IRQ_SYSMMU_SCALERCISP_0        COMBINER_IRQ(5, 2)
+#define EXYNOS5_IRQ_SYSMMU_SCALERCISP_1        COMBINER_IRQ(5, 3)
+#define EXYNOS5_IRQ_SYSMMU_MCUISP_0    COMBINER_IRQ(5, 4)
+#define EXYNOS5_IRQ_SYSMMU_MCUISP_1    COMBINER_IRQ(5, 5)
+#define EXYNOS5_IRQ_SYSMMU_3DNR_0      COMBINER_IRQ(5, 6)
+#define EXYNOS5_IRQ_SYSMMU_3DNR_1      COMBINER_IRQ(5, 7)
+
+#define EXYNOS5_IRQ_SYSMMU_ARM_0       COMBINER_IRQ(6, 0)
+#define EXYNOS5_IRQ_SYSMMU_ARM_1       COMBINER_IRQ(6, 1)
+#define EXYNOS5_IRQ_SYSMMU_MFC_L_0     COMBINER_IRQ(6, 2)
+#define EXYNOS5_IRQ_SYSMMU_MFC_L_1     COMBINER_IRQ(6, 3)
+#define EXYNOS5_IRQ_SYSMMU_RTIC_0      COMBINER_IRQ(6, 4)
+#define EXYNOS5_IRQ_SYSMMU_RTIC_1      COMBINER_IRQ(6, 5)
+#define EXYNOS5_IRQ_SYSMMU_SSS_0       COMBINER_IRQ(6, 6)
+#define EXYNOS5_IRQ_SYSMMU_SSS_1       COMBINER_IRQ(6, 7)
+
+#define EXYNOS5_IRQ_SYSMMU_MDMA0_0     COMBINER_IRQ(7, 0)
+#define EXYNOS5_IRQ_SYSMMU_MDMA0_1     COMBINER_IRQ(7, 1)
+#define EXYNOS5_IRQ_SYSMMU_MDMA1_0     COMBINER_IRQ(7, 2)
+#define EXYNOS5_IRQ_SYSMMU_MDMA1_1     COMBINER_IRQ(7, 3)
+#define EXYNOS5_IRQ_SYSMMU_TV_0                COMBINER_IRQ(7, 4)
+#define EXYNOS5_IRQ_SYSMMU_TV_1                COMBINER_IRQ(7, 5)
+#define EXYNOS5_IRQ_SYSMMU_GPSX_0      COMBINER_IRQ(7, 6)
+#define EXYNOS5_IRQ_SYSMMU_GPSX_1      COMBINER_IRQ(7, 7)
+
+#define EXYNOS5_IRQ_SYSMMU_MFC_R_0     COMBINER_IRQ(8, 5)
+#define EXYNOS5_IRQ_SYSMMU_MFC_R_1     COMBINER_IRQ(8, 6)
+
+#define EXYNOS5_IRQ_SYSMMU_DIS1_0      COMBINER_IRQ(9, 4)
+#define EXYNOS5_IRQ_SYSMMU_DIS1_1      COMBINER_IRQ(9, 5)
+
+#define EXYNOS5_IRQ_DP                 COMBINER_IRQ(10, 3)
+#define EXYNOS5_IRQ_SYSMMU_DIS0_0      COMBINER_IRQ(10, 4)
+#define EXYNOS5_IRQ_SYSMMU_DIS0_1      COMBINER_IRQ(10, 5)
+#define EXYNOS5_IRQ_SYSMMU_ISP_0       COMBINER_IRQ(10, 6)
+#define EXYNOS5_IRQ_SYSMMU_ISP_1       COMBINER_IRQ(10, 7)
+
+#define EXYNOS5_IRQ_SYSMMU_ODC_0       COMBINER_IRQ(11, 0)
+#define EXYNOS5_IRQ_SYSMMU_ODC_1       COMBINER_IRQ(11, 1)
+#define EXYNOS5_IRQ_SYSMMU_DRC_0       COMBINER_IRQ(11, 6)
+#define EXYNOS5_IRQ_SYSMMU_DRC_1       COMBINER_IRQ(11, 7)
+
+#define EXYNOS5_IRQ_FIMD1_FIFO         COMBINER_IRQ(18, 4)
+#define EXYNOS5_IRQ_FIMD1_VSYNC                COMBINER_IRQ(18, 5)
+#define EXYNOS5_IRQ_FIMD1_SYSTEM       COMBINER_IRQ(18, 6)
+
+#define EXYNOS5_IRQ_EINT0              COMBINER_IRQ(23, 0)
+#define EXYNOS5_IRQ_MCT_L0             COMBINER_IRQ(23, 1)
+#define EXYNOS5_IRQ_MCT_L1             COMBINER_IRQ(23, 2)
+#define EXYNOS5_IRQ_MCT_G0             COMBINER_IRQ(23, 3)
+#define EXYNOS5_IRQ_MCT_G1             COMBINER_IRQ(23, 4)
+#define EXYNOS5_IRQ_MCT_G2             COMBINER_IRQ(23, 5)
+#define EXYNOS5_IRQ_MCT_G3             COMBINER_IRQ(23, 6)
+
+#define EXYNOS5_IRQ_EINT1              COMBINER_IRQ(24, 0)
+#define EXYNOS5_IRQ_SYSMMU_LITE1_0     COMBINER_IRQ(24, 1)
+#define EXYNOS5_IRQ_SYSMMU_LITE1_1     COMBINER_IRQ(24, 2)
+#define EXYNOS5_IRQ_SYSMMU_2D_0                COMBINER_IRQ(24, 5)
+#define EXYNOS5_IRQ_SYSMMU_2D_1                COMBINER_IRQ(24, 6)
+
+#define EXYNOS5_IRQ_EINT2              COMBINER_IRQ(25, 0)
+#define EXYNOS5_IRQ_EINT3              COMBINER_IRQ(25, 1)
+
+#define EXYNOS5_IRQ_EINT4              COMBINER_IRQ(26, 0)
+#define EXYNOS5_IRQ_EINT5              COMBINER_IRQ(26, 1)
+
+#define EXYNOS5_IRQ_EINT6              COMBINER_IRQ(27, 0)
+#define EXYNOS5_IRQ_EINT7              COMBINER_IRQ(27, 1)
+
+#define EXYNOS5_IRQ_EINT8              COMBINER_IRQ(28, 0)
+#define EXYNOS5_IRQ_EINT9              COMBINER_IRQ(28, 1)
+
+#define EXYNOS5_IRQ_EINT10             COMBINER_IRQ(29, 0)
+#define EXYNOS5_IRQ_EINT11             COMBINER_IRQ(29, 1)
+
+#define EXYNOS5_IRQ_EINT12             COMBINER_IRQ(30, 0)
+#define EXYNOS5_IRQ_EINT13             COMBINER_IRQ(30, 1)
+
+#define EXYNOS5_IRQ_EINT14             COMBINER_IRQ(31, 0)
+#define EXYNOS5_IRQ_EINT15             COMBINER_IRQ(31, 1)
+
+#define EXYNOS5_MAX_COMBINER_NR                32
+
+#define EXYNOS5_IRQ_GPIO1_NR_GROUPS    13
+#define EXYNOS5_IRQ_GPIO2_NR_GROUPS    9
+#define EXYNOS5_IRQ_GPIO3_NR_GROUPS    5
+#define EXYNOS5_IRQ_GPIO4_NR_GROUPS    1
+
+#define MAX_COMBINER_NR                        (EXYNOS4_MAX_COMBINER_NR > EXYNOS5_MAX_COMBINER_NR ? \
+                                       EXYNOS4_MAX_COMBINER_NR : EXYNOS5_MAX_COMBINER_NR)
+
+#define S5P_EINT_BASE1                 COMBINER_IRQ(MAX_COMBINER_NR, 0)
+#define S5P_EINT_BASE2                 (S5P_EINT_BASE1 + 16)
+#define S5P_GPIOINT_BASE               (S5P_EINT_BASE1 + 32)
+#define IRQ_GPIO_END                   (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT)
+#define IRQ_TIMER_BASE                 (IRQ_GPIO_END + 64)
 
 /* Set the default NR_IRQS */
-#define NR_IRQS                        (IRQ_TIMER_BASE + IRQ_TIMER_COUNT)
+
+#define NR_IRQS                                (IRQ_TIMER_BASE + IRQ_TIMER_COUNT)
 
 #endif /* __ASM_ARCH_IRQS_H */
index c754a22a2bb3898af376f730f76a6d0cff169b61..024d38ff17183fed96447aebcbeb27f1cc04fb62 100644 (file)
 
 #define EXYNOS4_PA_SYSRAM0             0x02025000
 #define EXYNOS4_PA_SYSRAM1             0x02020000
+#define EXYNOS5_PA_SYSRAM              0x02020000
 
 #define EXYNOS4_PA_FIMC0               0x11800000
 #define EXYNOS4_PA_FIMC1               0x11810000
 #define EXYNOS4_PA_FIMC2               0x11820000
 #define EXYNOS4_PA_FIMC3               0x11830000
 
+#define EXYNOS4_PA_JPEG                        0x11840000
+
+#define EXYNOS4_PA_G2D                 0x12800000
+
 #define EXYNOS4_PA_I2S0                        0x03830000
 #define EXYNOS4_PA_I2S1                        0xE3100000
 #define EXYNOS4_PA_I2S2                        0xE2A00000
 #define EXYNOS4_PA_ONENAND             0x0C000000
 #define EXYNOS4_PA_ONENAND_DMA         0x0C600000
 
-#define EXYNOS4_PA_CHIPID              0x10000000
+#define EXYNOS_PA_CHIPID               0x10000000
 
 #define EXYNOS4_PA_SYSCON              0x10010000
+#define EXYNOS5_PA_SYSCON              0x10050100
+
 #define EXYNOS4_PA_PMU                 0x10020000
+#define EXYNOS5_PA_PMU                 0x10040000
+
 #define EXYNOS4_PA_CMU                 0x10030000
+#define EXYNOS5_PA_CMU                 0x10010000
 
 #define EXYNOS4_PA_SYSTIMER            0x10050000
+#define EXYNOS5_PA_SYSTIMER            0x101C0000
+
 #define EXYNOS4_PA_WATCHDOG            0x10060000
+#define EXYNOS5_PA_WATCHDOG            0x101D0000
+
 #define EXYNOS4_PA_RTC                 0x10070000
 
 #define EXYNOS4_PA_KEYPAD              0x100A0000
 
 #define EXYNOS4_PA_DMC0                        0x10400000
+#define EXYNOS4_PA_DMC1                        0x10410000
 
 #define EXYNOS4_PA_COMBINER            0x10440000
+#define EXYNOS5_PA_COMBINER            0x10440000
 
 #define EXYNOS4_PA_GIC_CPU             0x10480000
 #define EXYNOS4_PA_GIC_DIST            0x10490000
+#define EXYNOS5_PA_GIC_CPU             0x10480000
+#define EXYNOS5_PA_GIC_DIST            0x10490000
 
 #define EXYNOS4_PA_COREPERI            0x10500000
 #define EXYNOS4_PA_TWD                 0x10500600
 #define EXYNOS4_PA_L2CC                        0x10502000
 
-#define EXYNOS4_PA_MDMA                        0x10810000
+#define EXYNOS4_PA_MDMA0               0x10810000
+#define EXYNOS4_PA_MDMA1               0x12840000
 #define EXYNOS4_PA_PDMA0               0x12680000
 #define EXYNOS4_PA_PDMA1               0x12690000
 
 #define EXYNOS4_PA_SPI1                        0x13930000
 #define EXYNOS4_PA_SPI2                        0x13940000
 
-
 #define EXYNOS4_PA_GPIO1               0x11400000
 #define EXYNOS4_PA_GPIO2               0x11000000
 #define EXYNOS4_PA_GPIO3               0x03860000
+#define EXYNOS5_PA_GPIO1               0x11400000
+#define EXYNOS5_PA_GPIO2               0x13400000
+#define EXYNOS5_PA_GPIO3               0x10D10000
+#define EXYNOS5_PA_GPIO4               0x03860000
 
 #define EXYNOS4_PA_MIPI_CSIS0          0x11880000
 #define EXYNOS4_PA_MIPI_CSIS1          0x11890000
 #define EXYNOS4_PA_SATAPHY_CTRL                0x126B0000
 
 #define EXYNOS4_PA_SROMC               0x12570000
+#define EXYNOS5_PA_SROMC               0x12250000
 
 #define EXYNOS4_PA_EHCI                        0x12580000
 #define EXYNOS4_PA_OHCI                        0x12590000
 #define EXYNOS4_PA_MFC                 0x13400000
 
 #define EXYNOS4_PA_UART                        0x13800000
+#define EXYNOS5_PA_UART                        0x12C00000
 
 #define EXYNOS4_PA_VP                  0x12C00000
 #define EXYNOS4_PA_MIXER               0x12C10000
 #define EXYNOS4_PA_IIC_HDMIPHY         0x138E0000
 
 #define EXYNOS4_PA_IIC(x)              (0x13860000 + ((x) * 0x10000))
+#define EXYNOS5_PA_IIC(x)              (0x12C60000 + ((x) * 0x10000))
 
 #define EXYNOS4_PA_ADC                 0x13910000
 #define EXYNOS4_PA_ADC1                        0x13911000
 #define EXYNOS4_PA_SPDIF               0x139B0000
 
 #define EXYNOS4_PA_TIMER               0x139D0000
+#define EXYNOS5_PA_TIMER               0x12DD0000
 
 #define EXYNOS4_PA_SDRAM               0x40000000
+#define EXYNOS5_PA_SDRAM               0x40000000
 
 /* Compatibiltiy Defines */
 
 #define S3C_PA_IIC7                    EXYNOS4_PA_IIC(7)
 #define S3C_PA_RTC                     EXYNOS4_PA_RTC
 #define S3C_PA_WDT                     EXYNOS4_PA_WATCHDOG
-#define S3C_PA_UART                    EXYNOS4_PA_UART
 #define S3C_PA_SPI0                    EXYNOS4_PA_SPI0
 #define S3C_PA_SPI1                    EXYNOS4_PA_SPI1
 #define S3C_PA_SPI2                    EXYNOS4_PA_SPI2
 #define S5P_PA_FIMC1                   EXYNOS4_PA_FIMC1
 #define S5P_PA_FIMC2                   EXYNOS4_PA_FIMC2
 #define S5P_PA_FIMC3                   EXYNOS4_PA_FIMC3
+#define S5P_PA_JPEG                    EXYNOS4_PA_JPEG
+#define S5P_PA_G2D                     EXYNOS4_PA_G2D
 #define S5P_PA_FIMD0                   EXYNOS4_PA_FIMD0
 #define S5P_PA_HDMI                    EXYNOS4_PA_HDMI
 #define S5P_PA_IIC_HDMIPHY             EXYNOS4_PA_IIC_HDMIPHY
 
 /* Compatibility UART */
 
-#define S3C_VA_UARTx(x)                        (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
+#define EXYNOS4_PA_UART0               0x13800000
+#define EXYNOS4_PA_UART1               0x13810000
+#define EXYNOS4_PA_UART2               0x13820000
+#define EXYNOS4_PA_UART3               0x13830000
+#define EXYNOS4_SZ_UART                        SZ_256
 
-#define S5P_PA_UART(x)                 (EXYNOS4_PA_UART + ((x) * S3C_UART_OFFSET))
-#define S5P_PA_UART0                   S5P_PA_UART(0)
-#define S5P_PA_UART1                   S5P_PA_UART(1)
-#define S5P_PA_UART2                   S5P_PA_UART(2)
-#define S5P_PA_UART3                   S5P_PA_UART(3)
-#define S5P_PA_UART4                   S5P_PA_UART(4)
+#define EXYNOS5_PA_UART0               0x12C00000
+#define EXYNOS5_PA_UART1               0x12C10000
+#define EXYNOS5_PA_UART2               0x12C20000
+#define EXYNOS5_PA_UART3               0x12C30000
+#define EXYNOS5_SZ_UART                        SZ_256
 
-#define S5P_SZ_UART                    SZ_256
+#define S3C_VA_UARTx(x)                        (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
 
 #endif /* __ASM_ARCH_MAP_H */
index 632dd56301382ad0164972489495446ba0f2eabd..e76b7faba66b08da7f5da4c73816a15b924d7b3e 100644 (file)
@@ -22,11 +22,13 @@ enum sys_powerdown {
        NUM_SYS_POWERDOWN,
 };
 
+extern unsigned long l2x0_regs_phys;
 struct exynos4_pmu_conf {
        void __iomem *reg;
        unsigned int val[NUM_SYS_POWERDOWN];
 };
 
 extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode);
+extern void s3c_cpu_resume(void);
 
 #endif /* __ASM_ARCH_PMU_H */
index 6c37ebe94829acc3c3368142091cb0d044f19d44..e141c1fd68d84ce00a4dcca450c2e904867709f7 100644 (file)
 #include <plat/cpu.h>
 #include <mach/map.h>
 
-#define S5P_CLKREG(x)                  (S5P_VA_CMU + (x))
-
-#define S5P_CLKDIV_LEFTBUS             S5P_CLKREG(0x04500)
-#define S5P_CLKDIV_STAT_LEFTBUS                S5P_CLKREG(0x04600)
-#define S5P_CLKGATE_IP_LEFTBUS         S5P_CLKREG(0x04800)
-
-#define S5P_CLKDIV_RIGHTBUS            S5P_CLKREG(0x08500)
-#define S5P_CLKDIV_STAT_RIGHTBUS       S5P_CLKREG(0x08600)
-#define S5P_CLKGATE_IP_RIGHTBUS                S5P_CLKREG(0x08800)
-
-#define S5P_EPLL_LOCK                  S5P_CLKREG(0x0C010)
-#define S5P_VPLL_LOCK                  S5P_CLKREG(0x0C020)
-
-#define S5P_EPLL_CON0                  S5P_CLKREG(0x0C110)
-#define S5P_EPLL_CON1                  S5P_CLKREG(0x0C114)
-#define S5P_VPLL_CON0                  S5P_CLKREG(0x0C120)
-#define S5P_VPLL_CON1                  S5P_CLKREG(0x0C124)
-
-#define S5P_CLKSRC_TOP0                        S5P_CLKREG(0x0C210)
-#define S5P_CLKSRC_TOP1                        S5P_CLKREG(0x0C214)
-#define S5P_CLKSRC_CAM                 S5P_CLKREG(0x0C220)
-#define S5P_CLKSRC_TV                  S5P_CLKREG(0x0C224)
-#define S5P_CLKSRC_MFC                 S5P_CLKREG(0x0C228)
-#define S5P_CLKSRC_G3D                 S5P_CLKREG(0x0C22C)
-#define S5P_CLKSRC_IMAGE               S5P_CLKREG(0x0C230)
-#define S5P_CLKSRC_LCD0                        S5P_CLKREG(0x0C234)
-#define S5P_CLKSRC_MAUDIO              S5P_CLKREG(0x0C23C)
-#define S5P_CLKSRC_FSYS                        S5P_CLKREG(0x0C240)
-#define S5P_CLKSRC_PERIL0              S5P_CLKREG(0x0C250)
-#define S5P_CLKSRC_PERIL1              S5P_CLKREG(0x0C254)
-
-#define S5P_CLKSRC_MASK_TOP            S5P_CLKREG(0x0C310)
-#define S5P_CLKSRC_MASK_CAM            S5P_CLKREG(0x0C320)
-#define S5P_CLKSRC_MASK_TV             S5P_CLKREG(0x0C324)
-#define S5P_CLKSRC_MASK_LCD0           S5P_CLKREG(0x0C334)
-#define S5P_CLKSRC_MASK_MAUDIO         S5P_CLKREG(0x0C33C)
-#define S5P_CLKSRC_MASK_FSYS           S5P_CLKREG(0x0C340)
-#define S5P_CLKSRC_MASK_PERIL0         S5P_CLKREG(0x0C350)
-#define S5P_CLKSRC_MASK_PERIL1         S5P_CLKREG(0x0C354)
-
-#define S5P_CLKDIV_TOP                 S5P_CLKREG(0x0C510)
-#define S5P_CLKDIV_CAM                 S5P_CLKREG(0x0C520)
-#define S5P_CLKDIV_TV                  S5P_CLKREG(0x0C524)
-#define S5P_CLKDIV_MFC                 S5P_CLKREG(0x0C528)
-#define S5P_CLKDIV_G3D                 S5P_CLKREG(0x0C52C)
-#define S5P_CLKDIV_IMAGE               S5P_CLKREG(0x0C530)
-#define S5P_CLKDIV_LCD0                        S5P_CLKREG(0x0C534)
-#define S5P_CLKDIV_MAUDIO              S5P_CLKREG(0x0C53C)
-#define S5P_CLKDIV_FSYS0               S5P_CLKREG(0x0C540)
-#define S5P_CLKDIV_FSYS1               S5P_CLKREG(0x0C544)
-#define S5P_CLKDIV_FSYS2               S5P_CLKREG(0x0C548)
-#define S5P_CLKDIV_FSYS3               S5P_CLKREG(0x0C54C)
-#define S5P_CLKDIV_PERIL0              S5P_CLKREG(0x0C550)
-#define S5P_CLKDIV_PERIL1              S5P_CLKREG(0x0C554)
-#define S5P_CLKDIV_PERIL2              S5P_CLKREG(0x0C558)
-#define S5P_CLKDIV_PERIL3              S5P_CLKREG(0x0C55C)
-#define S5P_CLKDIV_PERIL4              S5P_CLKREG(0x0C560)
-#define S5P_CLKDIV_PERIL5              S5P_CLKREG(0x0C564)
-#define S5P_CLKDIV2_RATIO              S5P_CLKREG(0x0C580)
-
-#define S5P_CLKDIV_STAT_TOP            S5P_CLKREG(0x0C610)
-
-#define S5P_CLKGATE_SCLKCAM            S5P_CLKREG(0x0C820)
-#define S5P_CLKGATE_IP_CAM             S5P_CLKREG(0x0C920)
-#define S5P_CLKGATE_IP_TV              S5P_CLKREG(0x0C924)
-#define S5P_CLKGATE_IP_MFC             S5P_CLKREG(0x0C928)
-#define S5P_CLKGATE_IP_G3D             S5P_CLKREG(0x0C92C)
-#define S5P_CLKGATE_IP_IMAGE           (soc_is_exynos4210() ? \
-                                       S5P_CLKREG(0x0C930) : \
-                                       S5P_CLKREG(0x04930))
-#define S5P_CLKGATE_IP_IMAGE_4210      S5P_CLKREG(0x0C930)
-#define S5P_CLKGATE_IP_IMAGE_4212      S5P_CLKREG(0x04930)
-#define S5P_CLKGATE_IP_LCD0            S5P_CLKREG(0x0C934)
-#define S5P_CLKGATE_IP_FSYS            S5P_CLKREG(0x0C940)
-#define S5P_CLKGATE_IP_GPS             S5P_CLKREG(0x0C94C)
-#define S5P_CLKGATE_IP_PERIL           S5P_CLKREG(0x0C950)
-#define S5P_CLKGATE_IP_PERIR           (soc_is_exynos4210() ? \
-                                       S5P_CLKREG(0x0C960) : \
-                                       S5P_CLKREG(0x08960))
-#define S5P_CLKGATE_IP_PERIR_4210      S5P_CLKREG(0x0C960)
-#define S5P_CLKGATE_IP_PERIR_4212      S5P_CLKREG(0x08960)
-#define S5P_CLKGATE_BLOCK              S5P_CLKREG(0x0C970)
-
-#define S5P_CLKSRC_MASK_DMC            S5P_CLKREG(0x10300)
-#define S5P_CLKSRC_DMC                 S5P_CLKREG(0x10200)
-#define S5P_CLKDIV_DMC0                        S5P_CLKREG(0x10500)
-#define S5P_CLKDIV_DMC1                        S5P_CLKREG(0x10504)
-#define S5P_CLKDIV_STAT_DMC0           S5P_CLKREG(0x10600)
-#define S5P_CLKGATE_IP_DMC             S5P_CLKREG(0x10900)
-
-#define S5P_APLL_LOCK                  S5P_CLKREG(0x14000)
-#define S5P_MPLL_LOCK                  (soc_is_exynos4210() ? \
-                                       S5P_CLKREG(0x14004) :  \
-                                       S5P_CLKREG(0x10008))
-#define S5P_APLL_CON0                  S5P_CLKREG(0x14100)
-#define S5P_APLL_CON1                  S5P_CLKREG(0x14104)
-#define S5P_MPLL_CON0                  (soc_is_exynos4210() ? \
-                                       S5P_CLKREG(0x14108) : \
-                                       S5P_CLKREG(0x10108))
-#define S5P_MPLL_CON1                  (soc_is_exynos4210() ? \
-                                       S5P_CLKREG(0x1410C) : \
-                                       S5P_CLKREG(0x1010C))
-
-#define S5P_CLKSRC_CPU                 S5P_CLKREG(0x14200)
-#define S5P_CLKMUX_STATCPU             S5P_CLKREG(0x14400)
-
-#define S5P_CLKDIV_CPU                 S5P_CLKREG(0x14500)
-#define S5P_CLKDIV_CPU1                        S5P_CLKREG(0x14504)
-#define S5P_CLKDIV_STATCPU             S5P_CLKREG(0x14600)
-#define S5P_CLKDIV_STATCPU1            S5P_CLKREG(0x14604)
-
-#define S5P_CLKGATE_SCLKCPU            S5P_CLKREG(0x14800)
-#define S5P_CLKGATE_IP_CPU             S5P_CLKREG(0x14900)
-
-#define S5P_APLL_LOCKTIME              (0x1C20)        /* 300us */
-
-#define S5P_APLLCON0_ENABLE_SHIFT      (31)
-#define S5P_APLLCON0_LOCKED_SHIFT      (29)
-#define S5P_APLL_VAL_1000              ((250 << 16) | (6 << 8) | 1)
-#define S5P_APLL_VAL_800               ((200 << 16) | (6 << 8) | 1)
-
-#define S5P_EPLLCON0_ENABLE_SHIFT      (31)
-#define S5P_EPLLCON0_LOCKED_SHIFT      (29)
-
-#define S5P_VPLLCON0_ENABLE_SHIFT      (31)
-#define S5P_VPLLCON0_LOCKED_SHIFT      (29)
-
-#define S5P_CLKSRC_CPU_MUXCORE_SHIFT   (16)
-#define S5P_CLKMUX_STATCPU_MUXCORE_MASK        (0x7 << S5P_CLKSRC_CPU_MUXCORE_SHIFT)
-
-#define S5P_CLKDIV_CPU0_CORE_SHIFT     (0)
-#define S5P_CLKDIV_CPU0_CORE_MASK      (0x7 << S5P_CLKDIV_CPU0_CORE_SHIFT)
-#define S5P_CLKDIV_CPU0_COREM0_SHIFT   (4)
-#define S5P_CLKDIV_CPU0_COREM0_MASK    (0x7 << S5P_CLKDIV_CPU0_COREM0_SHIFT)
-#define S5P_CLKDIV_CPU0_COREM1_SHIFT   (8)
-#define S5P_CLKDIV_CPU0_COREM1_MASK    (0x7 << S5P_CLKDIV_CPU0_COREM1_SHIFT)
-#define S5P_CLKDIV_CPU0_PERIPH_SHIFT   (12)
-#define S5P_CLKDIV_CPU0_PERIPH_MASK    (0x7 << S5P_CLKDIV_CPU0_PERIPH_SHIFT)
-#define S5P_CLKDIV_CPU0_ATB_SHIFT      (16)
-#define S5P_CLKDIV_CPU0_ATB_MASK       (0x7 << S5P_CLKDIV_CPU0_ATB_SHIFT)
-#define S5P_CLKDIV_CPU0_PCLKDBG_SHIFT  (20)
-#define S5P_CLKDIV_CPU0_PCLKDBG_MASK   (0x7 << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT)
-#define S5P_CLKDIV_CPU0_APLL_SHIFT     (24)
-#define S5P_CLKDIV_CPU0_APLL_MASK      (0x7 << S5P_CLKDIV_CPU0_APLL_SHIFT)
-
-#define S5P_CLKDIV_DMC0_ACP_SHIFT      (0)
-#define S5P_CLKDIV_DMC0_ACP_MASK       (0x7 << S5P_CLKDIV_DMC0_ACP_SHIFT)
-#define S5P_CLKDIV_DMC0_ACPPCLK_SHIFT  (4)
-#define S5P_CLKDIV_DMC0_ACPPCLK_MASK   (0x7 << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT)
-#define S5P_CLKDIV_DMC0_DPHY_SHIFT     (8)
-#define S5P_CLKDIV_DMC0_DPHY_MASK      (0x7 << S5P_CLKDIV_DMC0_DPHY_SHIFT)
-#define S5P_CLKDIV_DMC0_DMC_SHIFT      (12)
-#define S5P_CLKDIV_DMC0_DMC_MASK       (0x7 << S5P_CLKDIV_DMC0_DMC_SHIFT)
-#define S5P_CLKDIV_DMC0_DMCD_SHIFT     (16)
-#define S5P_CLKDIV_DMC0_DMCD_MASK      (0x7 << S5P_CLKDIV_DMC0_DMCD_SHIFT)
-#define S5P_CLKDIV_DMC0_DMCP_SHIFT     (20)
-#define S5P_CLKDIV_DMC0_DMCP_MASK      (0x7 << S5P_CLKDIV_DMC0_DMCP_SHIFT)
-#define S5P_CLKDIV_DMC0_COPY2_SHIFT    (24)
-#define S5P_CLKDIV_DMC0_COPY2_MASK     (0x7 << S5P_CLKDIV_DMC0_COPY2_SHIFT)
-#define S5P_CLKDIV_DMC0_CORETI_SHIFT   (28)
-#define S5P_CLKDIV_DMC0_CORETI_MASK    (0x7 << S5P_CLKDIV_DMC0_CORETI_SHIFT)
-
-#define S5P_CLKDIV_TOP_ACLK200_SHIFT   (0)
-#define S5P_CLKDIV_TOP_ACLK200_MASK    (0x7 << S5P_CLKDIV_TOP_ACLK200_SHIFT)
-#define S5P_CLKDIV_TOP_ACLK100_SHIFT   (4)
-#define S5P_CLKDIV_TOP_ACLK100_MASK    (0xf << S5P_CLKDIV_TOP_ACLK100_SHIFT)
-#define S5P_CLKDIV_TOP_ACLK160_SHIFT   (8)
-#define S5P_CLKDIV_TOP_ACLK160_MASK    (0x7 << S5P_CLKDIV_TOP_ACLK160_SHIFT)
-#define S5P_CLKDIV_TOP_ACLK133_SHIFT   (12)
-#define S5P_CLKDIV_TOP_ACLK133_MASK    (0x7 << S5P_CLKDIV_TOP_ACLK133_SHIFT)
-#define S5P_CLKDIV_TOP_ONENAND_SHIFT   (16)
-#define S5P_CLKDIV_TOP_ONENAND_MASK    (0x7 << S5P_CLKDIV_TOP_ONENAND_SHIFT)
-
-#define S5P_CLKDIV_BUS_GDLR_SHIFT      (0)
-#define S5P_CLKDIV_BUS_GDLR_MASK       (0x7 << S5P_CLKDIV_BUS_GDLR_SHIFT)
-#define S5P_CLKDIV_BUS_GPLR_SHIFT      (4)
-#define S5P_CLKDIV_BUS_GPLR_MASK       (0x7 << S5P_CLKDIV_BUS_GPLR_SHIFT)
+#define EXYNOS_CLKREG(x)                       (S5P_VA_CMU + (x))
+
+#define EXYNOS4_CLKDIV_LEFTBUS                 EXYNOS_CLKREG(0x04500)
+#define EXYNOS4_CLKDIV_STAT_LEFTBUS            EXYNOS_CLKREG(0x04600)
+#define EXYNOS4_CLKGATE_IP_LEFTBUS             EXYNOS_CLKREG(0x04800)
+
+#define EXYNOS4_CLKDIV_RIGHTBUS                        EXYNOS_CLKREG(0x08500)
+#define EXYNOS4_CLKDIV_STAT_RIGHTBUS           EXYNOS_CLKREG(0x08600)
+#define EXYNOS4_CLKGATE_IP_RIGHTBUS            EXYNOS_CLKREG(0x08800)
+
+#define EXYNOS4_EPLL_LOCK                      EXYNOS_CLKREG(0x0C010)
+#define EXYNOS4_VPLL_LOCK                      EXYNOS_CLKREG(0x0C020)
+
+#define EXYNOS4_EPLL_CON0                      EXYNOS_CLKREG(0x0C110)
+#define EXYNOS4_EPLL_CON1                      EXYNOS_CLKREG(0x0C114)
+#define EXYNOS4_VPLL_CON0                      EXYNOS_CLKREG(0x0C120)
+#define EXYNOS4_VPLL_CON1                      EXYNOS_CLKREG(0x0C124)
+
+#define EXYNOS4_CLKSRC_TOP0                    EXYNOS_CLKREG(0x0C210)
+#define EXYNOS4_CLKSRC_TOP1                    EXYNOS_CLKREG(0x0C214)
+#define EXYNOS4_CLKSRC_CAM                     EXYNOS_CLKREG(0x0C220)
+#define EXYNOS4_CLKSRC_TV                      EXYNOS_CLKREG(0x0C224)
+#define EXYNOS4_CLKSRC_MFC                     EXYNOS_CLKREG(0x0C228)
+#define EXYNOS4_CLKSRC_G3D                     EXYNOS_CLKREG(0x0C22C)
+#define EXYNOS4_CLKSRC_IMAGE                   EXYNOS_CLKREG(0x0C230)
+#define EXYNOS4_CLKSRC_LCD0                    EXYNOS_CLKREG(0x0C234)
+#define EXYNOS4_CLKSRC_MAUDIO                  EXYNOS_CLKREG(0x0C23C)
+#define EXYNOS4_CLKSRC_FSYS                    EXYNOS_CLKREG(0x0C240)
+#define EXYNOS4_CLKSRC_PERIL0                  EXYNOS_CLKREG(0x0C250)
+#define EXYNOS4_CLKSRC_PERIL1                  EXYNOS_CLKREG(0x0C254)
+
+#define EXYNOS4_CLKSRC_MASK_TOP                        EXYNOS_CLKREG(0x0C310)
+#define EXYNOS4_CLKSRC_MASK_CAM                        EXYNOS_CLKREG(0x0C320)
+#define EXYNOS4_CLKSRC_MASK_TV                 EXYNOS_CLKREG(0x0C324)
+#define EXYNOS4_CLKSRC_MASK_LCD0               EXYNOS_CLKREG(0x0C334)
+#define EXYNOS4_CLKSRC_MASK_MAUDIO             EXYNOS_CLKREG(0x0C33C)
+#define EXYNOS4_CLKSRC_MASK_FSYS               EXYNOS_CLKREG(0x0C340)
+#define EXYNOS4_CLKSRC_MASK_PERIL0             EXYNOS_CLKREG(0x0C350)
+#define EXYNOS4_CLKSRC_MASK_PERIL1             EXYNOS_CLKREG(0x0C354)
+
+#define EXYNOS4_CLKDIV_TOP                     EXYNOS_CLKREG(0x0C510)
+#define EXYNOS4_CLKDIV_CAM                     EXYNOS_CLKREG(0x0C520)
+#define EXYNOS4_CLKDIV_TV                      EXYNOS_CLKREG(0x0C524)
+#define EXYNOS4_CLKDIV_MFC                     EXYNOS_CLKREG(0x0C528)
+#define EXYNOS4_CLKDIV_G3D                     EXYNOS_CLKREG(0x0C52C)
+#define EXYNOS4_CLKDIV_IMAGE                   EXYNOS_CLKREG(0x0C530)
+#define EXYNOS4_CLKDIV_LCD0                    EXYNOS_CLKREG(0x0C534)
+#define EXYNOS4_CLKDIV_MAUDIO                  EXYNOS_CLKREG(0x0C53C)
+#define EXYNOS4_CLKDIV_FSYS0                   EXYNOS_CLKREG(0x0C540)
+#define EXYNOS4_CLKDIV_FSYS1                   EXYNOS_CLKREG(0x0C544)
+#define EXYNOS4_CLKDIV_FSYS2                   EXYNOS_CLKREG(0x0C548)
+#define EXYNOS4_CLKDIV_FSYS3                   EXYNOS_CLKREG(0x0C54C)
+#define EXYNOS4_CLKDIV_PERIL0                  EXYNOS_CLKREG(0x0C550)
+#define EXYNOS4_CLKDIV_PERIL1                  EXYNOS_CLKREG(0x0C554)
+#define EXYNOS4_CLKDIV_PERIL2                  EXYNOS_CLKREG(0x0C558)
+#define EXYNOS4_CLKDIV_PERIL3                  EXYNOS_CLKREG(0x0C55C)
+#define EXYNOS4_CLKDIV_PERIL4                  EXYNOS_CLKREG(0x0C560)
+#define EXYNOS4_CLKDIV_PERIL5                  EXYNOS_CLKREG(0x0C564)
+#define EXYNOS4_CLKDIV2_RATIO                  EXYNOS_CLKREG(0x0C580)
+
+#define EXYNOS4_CLKDIV_STAT_TOP                        EXYNOS_CLKREG(0x0C610)
+#define EXYNOS4_CLKDIV_STAT_MFC                        EXYNOS_CLKREG(0x0C628)
+
+#define EXYNOS4_CLKGATE_SCLKCAM                        EXYNOS_CLKREG(0x0C820)
+#define EXYNOS4_CLKGATE_IP_CAM                 EXYNOS_CLKREG(0x0C920)
+#define EXYNOS4_CLKGATE_IP_TV                  EXYNOS_CLKREG(0x0C924)
+#define EXYNOS4_CLKGATE_IP_MFC                 EXYNOS_CLKREG(0x0C928)
+#define EXYNOS4_CLKGATE_IP_G3D                 EXYNOS_CLKREG(0x0C92C)
+#define EXYNOS4_CLKGATE_IP_IMAGE               (soc_is_exynos4210() ? \
+                                               EXYNOS_CLKREG(0x0C930) : \
+                                               EXYNOS_CLKREG(0x04930))
+#define EXYNOS4210_CLKGATE_IP_IMAGE            EXYNOS_CLKREG(0x0C930)
+#define EXYNOS4212_CLKGATE_IP_IMAGE            EXYNOS_CLKREG(0x04930)
+#define EXYNOS4_CLKGATE_IP_LCD0                        EXYNOS_CLKREG(0x0C934)
+#define EXYNOS4_CLKGATE_IP_FSYS                        EXYNOS_CLKREG(0x0C940)
+#define EXYNOS4_CLKGATE_IP_GPS                 EXYNOS_CLKREG(0x0C94C)
+#define EXYNOS4_CLKGATE_IP_PERIL               EXYNOS_CLKREG(0x0C950)
+#define EXYNOS4_CLKGATE_IP_PERIR               (soc_is_exynos4210() ? \
+                                               EXYNOS_CLKREG(0x0C960) : \
+                                               EXYNOS_CLKREG(0x08960))
+#define EXYNOS4210_CLKGATE_IP_PERIR            EXYNOS_CLKREG(0x0C960)
+#define EXYNOS4212_CLKGATE_IP_PERIR            EXYNOS_CLKREG(0x08960)
+#define EXYNOS4_CLKGATE_BLOCK                  EXYNOS_CLKREG(0x0C970)
+
+#define EXYNOS4_CLKSRC_MASK_DMC                        EXYNOS_CLKREG(0x10300)
+#define EXYNOS4_CLKSRC_DMC                     EXYNOS_CLKREG(0x10200)
+#define EXYNOS4_CLKDIV_DMC0                    EXYNOS_CLKREG(0x10500)
+#define EXYNOS4_CLKDIV_DMC1                    EXYNOS_CLKREG(0x10504)
+#define EXYNOS4_CLKDIV_STAT_DMC0               EXYNOS_CLKREG(0x10600)
+#define EXYNOS4_CLKDIV_STAT_DMC1               EXYNOS_CLKREG(0x10604)
+#define EXYNOS4_CLKGATE_IP_DMC                 EXYNOS_CLKREG(0x10900)
+
+#define EXYNOS4_DMC_PAUSE_CTRL                 EXYNOS_CLKREG(0x11094)
+#define EXYNOS4_DMC_PAUSE_ENABLE               (1 << 0)
+
+#define EXYNOS4_APLL_LOCK                      EXYNOS_CLKREG(0x14000)
+#define EXYNOS4_MPLL_LOCK                      (soc_is_exynos4210() ? \
+                                               EXYNOS_CLKREG(0x14004) :  \
+                                               EXYNOS_CLKREG(0x10008))
+#define EXYNOS4_APLL_CON0                      EXYNOS_CLKREG(0x14100)
+#define EXYNOS4_APLL_CON1                      EXYNOS_CLKREG(0x14104)
+#define EXYNOS4_MPLL_CON0                      (soc_is_exynos4210() ? \
+                                               EXYNOS_CLKREG(0x14108) : \
+                                               EXYNOS_CLKREG(0x10108))
+#define EXYNOS4_MPLL_CON1                      (soc_is_exynos4210() ? \
+                                               EXYNOS_CLKREG(0x1410C) : \
+                                               EXYNOS_CLKREG(0x1010C))
+
+#define EXYNOS4_CLKSRC_CPU                     EXYNOS_CLKREG(0x14200)
+#define EXYNOS4_CLKMUX_STATCPU                 EXYNOS_CLKREG(0x14400)
+
+#define EXYNOS4_CLKDIV_CPU                     EXYNOS_CLKREG(0x14500)
+#define EXYNOS4_CLKDIV_CPU1                    EXYNOS_CLKREG(0x14504)
+#define EXYNOS4_CLKDIV_STATCPU                 EXYNOS_CLKREG(0x14600)
+#define EXYNOS4_CLKDIV_STATCPU1                        EXYNOS_CLKREG(0x14604)
+
+#define EXYNOS4_CLKGATE_SCLKCPU                        EXYNOS_CLKREG(0x14800)
+#define EXYNOS4_CLKGATE_IP_CPU                 EXYNOS_CLKREG(0x14900)
+
+#define EXYNOS4_APLL_LOCKTIME                  (0x1C20)        /* 300us */
+
+#define EXYNOS4_APLLCON0_ENABLE_SHIFT          (31)
+#define EXYNOS4_APLLCON0_LOCKED_SHIFT          (29)
+#define EXYNOS4_APLL_VAL_1000                  ((250 << 16) | (6 << 8) | 1)
+#define EXYNOS4_APLL_VAL_800                   ((200 << 16) | (6 << 8) | 1)
+
+#define EXYNOS4_EPLLCON0_ENABLE_SHIFT          (31)
+#define EXYNOS4_EPLLCON0_LOCKED_SHIFT          (29)
+
+#define EXYNOS4_VPLLCON0_ENABLE_SHIFT          (31)
+#define EXYNOS4_VPLLCON0_LOCKED_SHIFT          (29)
+
+#define EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT       (16)
+#define EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK    (0x7 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT)
+
+#define EXYNOS4_CLKDIV_CPU0_CORE_SHIFT         (0)
+#define EXYNOS4_CLKDIV_CPU0_CORE_MASK          (0x7 << EXYNOS4_CLKDIV_CPU0_CORE_SHIFT)
+#define EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT       (4)
+#define EXYNOS4_CLKDIV_CPU0_COREM0_MASK                (0x7 << EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT)
+#define EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT       (8)
+#define EXYNOS4_CLKDIV_CPU0_COREM1_MASK                (0x7 << EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT)
+#define EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT       (12)
+#define EXYNOS4_CLKDIV_CPU0_PERIPH_MASK                (0x7 << EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT)
+#define EXYNOS4_CLKDIV_CPU0_ATB_SHIFT          (16)
+#define EXYNOS4_CLKDIV_CPU0_ATB_MASK           (0x7 << EXYNOS4_CLKDIV_CPU0_ATB_SHIFT)
+#define EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT      (20)
+#define EXYNOS4_CLKDIV_CPU0_PCLKDBG_MASK       (0x7 << EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT)
+#define EXYNOS4_CLKDIV_CPU0_APLL_SHIFT         (24)
+#define EXYNOS4_CLKDIV_CPU0_APLL_MASK          (0x7 << EXYNOS4_CLKDIV_CPU0_APLL_SHIFT)
+#define EXYNOS4_CLKDIV_CPU0_CORE2_SHIFT                28
+#define EXYNOS4_CLKDIV_CPU0_CORE2_MASK         (0x7 << EXYNOS4_CLKDIV_CPU0_CORE2_SHIFT)
+
+#define EXYNOS4_CLKDIV_CPU1_COPY_SHIFT         0
+#define EXYNOS4_CLKDIV_CPU1_COPY_MASK          (0x7 << EXYNOS4_CLKDIV_CPU1_COPY_SHIFT)
+#define EXYNOS4_CLKDIV_CPU1_HPM_SHIFT          4
+#define EXYNOS4_CLKDIV_CPU1_HPM_MASK           (0x7 << EXYNOS4_CLKDIV_CPU1_HPM_SHIFT)
+#define EXYNOS4_CLKDIV_CPU1_CORES_SHIFT                8
+#define EXYNOS4_CLKDIV_CPU1_CORES_MASK         (0x7 << EXYNOS4_CLKDIV_CPU1_CORES_SHIFT)
+
+#define EXYNOS4_CLKDIV_DMC0_ACP_SHIFT          (0)
+#define EXYNOS4_CLKDIV_DMC0_ACP_MASK           (0x7 << EXYNOS4_CLKDIV_DMC0_ACP_SHIFT)
+#define EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT      (4)
+#define EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK       (0x7 << EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT)
+#define EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT         (8)
+#define EXYNOS4_CLKDIV_DMC0_DPHY_MASK          (0x7 << EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT)
+#define EXYNOS4_CLKDIV_DMC0_DMC_SHIFT          (12)
+#define EXYNOS4_CLKDIV_DMC0_DMC_MASK           (0x7 << EXYNOS4_CLKDIV_DMC0_DMC_SHIFT)
+#define EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT         (16)
+#define EXYNOS4_CLKDIV_DMC0_DMCD_MASK          (0x7 << EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT)
+#define EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT         (20)
+#define EXYNOS4_CLKDIV_DMC0_DMCP_MASK          (0x7 << EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT)
+#define EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT                (24)
+#define EXYNOS4_CLKDIV_DMC0_COPY2_MASK         (0x7 << EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT)
+#define EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT       (28)
+#define EXYNOS4_CLKDIV_DMC0_CORETI_MASK                (0x7 << EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT)
+
+#define EXYNOS4_CLKDIV_DMC1_G2D_ACP_SHIFT      (0)
+#define EXYNOS4_CLKDIV_DMC1_G2D_ACP_MASK       (0xf << EXYNOS4_CLKDIV_DMC1_G2D_ACP_SHIFT)
+#define EXYNOS4_CLKDIV_DMC1_C2C_SHIFT          (4)
+#define EXYNOS4_CLKDIV_DMC1_C2C_MASK           (0x7 << EXYNOS4_CLKDIV_DMC1_C2C_SHIFT)
+#define EXYNOS4_CLKDIV_DMC1_PWI_SHIFT          (8)
+#define EXYNOS4_CLKDIV_DMC1_PWI_MASK           (0xf << EXYNOS4_CLKDIV_DMC1_PWI_SHIFT)
+#define EXYNOS4_CLKDIV_DMC1_C2CACLK_SHIFT      (12)
+#define EXYNOS4_CLKDIV_DMC1_C2CACLK_MASK       (0x7 << EXYNOS4_CLKDIV_DMC1_C2CACLK_SHIFT)
+#define EXYNOS4_CLKDIV_DMC1_DVSEM_SHIFT                (16)
+#define EXYNOS4_CLKDIV_DMC1_DVSEM_MASK         (0x7f << EXYNOS4_CLKDIV_DMC1_DVSEM_SHIFT)
+#define EXYNOS4_CLKDIV_DMC1_DPM_SHIFT          (24)
+#define EXYNOS4_CLKDIV_DMC1_DPM_MASK           (0x7f << EXYNOS4_CLKDIV_DMC1_DPM_SHIFT)
+
+#define EXYNOS4_CLKDIV_MFC_SHIFT               (0)
+#define EXYNOS4_CLKDIV_MFC_MASK                        (0x7 << EXYNOS4_CLKDIV_MFC_SHIFT)
+
+#define EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT       (0)
+#define EXYNOS4_CLKDIV_TOP_ACLK200_MASK                (0x7 << EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT)
+#define EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT       (4)
+#define EXYNOS4_CLKDIV_TOP_ACLK100_MASK                (0xF << EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT)
+#define EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT       (8)
+#define EXYNOS4_CLKDIV_TOP_ACLK160_MASK                (0x7 << EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT)
+#define EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT       (12)
+#define EXYNOS4_CLKDIV_TOP_ACLK133_MASK                (0x7 << EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT)
+#define EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT       (16)
+#define EXYNOS4_CLKDIV_TOP_ONENAND_MASK                (0x7 << EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT)
+#define EXYNOS4_CLKDIV_TOP_ACLK266_GPS_SHIFT   (20)
+#define EXYNOS4_CLKDIV_TOP_ACLK266_GPS_MASK    (0x7 << EXYNOS4_CLKDIV_TOP_ACLK266_GPS_SHIFT)
+#define EXYNOS4_CLKDIV_TOP_ACLK400_MCUISP_SHIFT        (24)
+#define EXYNOS4_CLKDIV_TOP_ACLK400_MCUISP_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK400_MCUISP_SHIFT)
+
+#define EXYNOS4_CLKDIV_BUS_GDLR_SHIFT          (0)
+#define EXYNOS4_CLKDIV_BUS_GDLR_MASK           (0x7 << EXYNOS4_CLKDIV_BUS_GDLR_SHIFT)
+#define EXYNOS4_CLKDIV_BUS_GPLR_SHIFT          (4)
+#define EXYNOS4_CLKDIV_BUS_GPLR_MASK           (0x7 << EXYNOS4_CLKDIV_BUS_GPLR_SHIFT)
+
+#define EXYNOS4_CLKDIV_CAM_FIMC0_SHIFT         (0)
+#define EXYNOS4_CLKDIV_CAM_FIMC0_MASK          (0xf << EXYNOS4_CLKDIV_CAM_FIMC0_SHIFT)
+#define EXYNOS4_CLKDIV_CAM_FIMC1_SHIFT         (4)
+#define EXYNOS4_CLKDIV_CAM_FIMC1_MASK          (0xf << EXYNOS4_CLKDIV_CAM_FIMC1_SHIFT)
+#define EXYNOS4_CLKDIV_CAM_FIMC2_SHIFT         (8)
+#define EXYNOS4_CLKDIV_CAM_FIMC2_MASK          (0xf << EXYNOS4_CLKDIV_CAM_FIMC2_SHIFT)
+#define EXYNOS4_CLKDIV_CAM_FIMC3_SHIFT         (12)
+#define EXYNOS4_CLKDIV_CAM_FIMC3_MASK          (0xf << EXYNOS4_CLKDIV_CAM_FIMC3_SHIFT)
 
 /* Only for EXYNOS4210 */
 
-#define S5P_CLKSRC_LCD1                        S5P_CLKREG(0x0C238)
-#define S5P_CLKSRC_MASK_LCD1           S5P_CLKREG(0x0C338)
-#define S5P_CLKDIV_LCD1                        S5P_CLKREG(0x0C538)
-#define S5P_CLKGATE_IP_LCD1            S5P_CLKREG(0x0C938)
+#define EXYNOS4210_CLKSRC_LCD1                 EXYNOS_CLKREG(0x0C238)
+#define EXYNOS4210_CLKSRC_MASK_LCD1            EXYNOS_CLKREG(0x0C338)
+#define EXYNOS4210_CLKDIV_LCD1                 EXYNOS_CLKREG(0x0C538)
+#define EXYNOS4210_CLKGATE_IP_LCD1             EXYNOS_CLKREG(0x0C938)
+
+/* Only for EXYNOS4212 */
+
+#define EXYNOS4_CLKDIV_CAM1                    EXYNOS_CLKREG(0x0C568)
+
+#define EXYNOS4_CLKDIV_STAT_CAM1               EXYNOS_CLKREG(0x0C668)
+
+#define EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT         (0)
+#define EXYNOS4_CLKDIV_CAM1_JPEG_MASK          (0xf << EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT)
+
+/* For EXYNOS5250 */
+
+#define EXYNOS5_APLL_CON0                      EXYNOS_CLKREG(0x00100)
+#define EXYNOS5_CLKSRC_CPU                     EXYNOS_CLKREG(0x00200)
+#define EXYNOS5_CLKDIV_CPU0                    EXYNOS_CLKREG(0x00500)
+#define EXYNOS5_MPLL_CON0                      EXYNOS_CLKREG(0x04100)
+#define EXYNOS5_CLKSRC_CORE1                   EXYNOS_CLKREG(0x04204)
+
+#define EXYNOS5_CLKGATE_IP_CORE                        EXYNOS_CLKREG(0x04900)
+
+#define EXYNOS5_CLKDIV_ACP                     EXYNOS_CLKREG(0x08500)
+
+#define EXYNOS5_CLKSRC_TOP2                    EXYNOS_CLKREG(0x10218)
+#define EXYNOS5_EPLL_CON0                      EXYNOS_CLKREG(0x10130)
+#define EXYNOS5_EPLL_CON1                      EXYNOS_CLKREG(0x10134)
+#define EXYNOS5_VPLL_CON0                      EXYNOS_CLKREG(0x10140)
+#define EXYNOS5_VPLL_CON1                      EXYNOS_CLKREG(0x10144)
+#define EXYNOS5_CPLL_CON0                      EXYNOS_CLKREG(0x10120)
+
+#define EXYNOS5_CLKSRC_TOP0                    EXYNOS_CLKREG(0x10210)
+#define EXYNOS5_CLKSRC_TOP3                    EXYNOS_CLKREG(0x1021C)
+#define EXYNOS5_CLKSRC_GSCL                    EXYNOS_CLKREG(0x10220)
+#define EXYNOS5_CLKSRC_DISP1_0                 EXYNOS_CLKREG(0x1022C)
+#define EXYNOS5_CLKSRC_FSYS                    EXYNOS_CLKREG(0x10244)
+#define EXYNOS5_CLKSRC_PERIC0                  EXYNOS_CLKREG(0x10250)
+
+#define EXYNOS5_CLKSRC_MASK_TOP                        EXYNOS_CLKREG(0x10310)
+#define EXYNOS5_CLKSRC_MASK_GSCL               EXYNOS_CLKREG(0x10320)
+#define EXYNOS5_CLKSRC_MASK_DISP1_0            EXYNOS_CLKREG(0x1032C)
+#define EXYNOS5_CLKSRC_MASK_FSYS               EXYNOS_CLKREG(0x10340)
+#define EXYNOS5_CLKSRC_MASK_PERIC0             EXYNOS_CLKREG(0x10350)
+
+#define EXYNOS5_CLKDIV_TOP0                    EXYNOS_CLKREG(0x10510)
+#define EXYNOS5_CLKDIV_TOP1                    EXYNOS_CLKREG(0x10514)
+#define EXYNOS5_CLKDIV_GSCL                    EXYNOS_CLKREG(0x10520)
+#define EXYNOS5_CLKDIV_DISP1_0                 EXYNOS_CLKREG(0x1052C)
+#define EXYNOS5_CLKDIV_GEN                     EXYNOS_CLKREG(0x1053C)
+#define EXYNOS5_CLKDIV_FSYS0                   EXYNOS_CLKREG(0x10548)
+#define EXYNOS5_CLKDIV_FSYS1                   EXYNOS_CLKREG(0x1054C)
+#define EXYNOS5_CLKDIV_FSYS2                   EXYNOS_CLKREG(0x10550)
+#define EXYNOS5_CLKDIV_FSYS3                   EXYNOS_CLKREG(0x10554)
+#define EXYNOS5_CLKDIV_PERIC0                  EXYNOS_CLKREG(0x10558)
+
+#define EXYNOS5_CLKGATE_IP_ACP                 EXYNOS_CLKREG(0x08800)
+#define EXYNOS5_CLKGATE_IP_GSCL                        EXYNOS_CLKREG(0x10920)
+#define EXYNOS5_CLKGATE_IP_DISP1               EXYNOS_CLKREG(0x10928)
+#define EXYNOS5_CLKGATE_IP_MFC                 EXYNOS_CLKREG(0x1092C)
+#define EXYNOS5_CLKGATE_IP_GEN                 EXYNOS_CLKREG(0x10934)
+#define EXYNOS5_CLKGATE_IP_FSYS                        EXYNOS_CLKREG(0x10944)
+#define EXYNOS5_CLKGATE_IP_GPS                 EXYNOS_CLKREG(0x1094C)
+#define EXYNOS5_CLKGATE_IP_PERIC               EXYNOS_CLKREG(0x10950)
+#define EXYNOS5_CLKGATE_IP_PERIS               EXYNOS_CLKREG(0x10960)
+#define EXYNOS5_CLKGATE_BLOCK                  EXYNOS_CLKREG(0x10980)
+
+#define EXYNOS5_BPLL_CON0                      EXYNOS_CLKREG(0x20110)
+#define EXYNOS5_CLKSRC_CDREX                   EXYNOS_CLKREG(0x20200)
+#define EXYNOS5_CLKDIV_CDREX                   EXYNOS_CLKREG(0x20500)
+
+#define EXYNOS5_EPLL_LOCK                      EXYNOS_CLKREG(0x10030)
+
+#define EXYNOS5_EPLLCON0_LOCKED_SHIFT          (29)
 
 /* Compatibility defines and inclusion */
 
 #include <mach/regs-pmu.h>
 
-#define S5P_EPLL_CON                   S5P_EPLL_CON0
+#define S5P_EPLL_CON                           EXYNOS4_EPLL_CON0
 
 #endif /* __ASM_ARCH_REGS_CLOCK_H */
index 1401b21663a547a4e2f0547092301dfb5c6ecc7a..e4b5b60dcb8506f67157dfdef2e4008d1a626e6e 100644 (file)
 #include <mach/map.h>
 #include <mach/irqs.h>
 
+#define EINT_REG_NR(x)                 (EINT_OFFSET(x) >> 3)
+#define EINT_CON(b, x)                 (b + 0xE00 + (EINT_REG_NR(x) * 4))
+#define EINT_FLTCON(b, x)              (b + 0xE80 + (EINT_REG_NR(x) * 4))
+#define EINT_MASK(b, x)                        (b + 0xF00 + (EINT_REG_NR(x) * 4))
+#define EINT_PEND(b, x)                        (b + 0xF40 + (EINT_REG_NR(x) * 4))
+
+#define EINT_OFFSET_BIT(x)             (1 << (EINT_OFFSET(x) & 0x7))
+
+/* compatibility for plat-s5p/irq-pm.c */
 #define EXYNOS4_EINT40CON              (S5P_VA_GPIO2 + 0xE00)
 #define S5P_EINT_CON(x)                        (EXYNOS4_EINT40CON + ((x) * 0x4))
 
 #define EXYNOS4_EINT40PEND             (S5P_VA_GPIO2 + 0xF40)
 #define S5P_EINT_PEND(x)               (EXYNOS4_EINT40PEND + ((x) * 0x4))
 
-#define EINT_REG_NR(x)                 (EINT_OFFSET(x) >> 3)
-
-#define eint_irq_to_bit(irq)           (1 << (EINT_OFFSET(irq) & 0x7))
-
-#define EINT_MODE                      S3C_GPIO_SFN(0xf)
-
-#define EINT_GPIO_0(x)                 EXYNOS4_GPX0(x)
-#define EINT_GPIO_1(x)                 EXYNOS4_GPX1(x)
-#define EINT_GPIO_2(x)                 EXYNOS4_GPX2(x)
-#define EINT_GPIO_3(x)                 EXYNOS4_GPX3(x)
-
 #endif /* __ASM_ARCH_REGS_GPIO_H */
index 4fff8e938fecb8c2d839ee4990834229fd44df44..4c53f38b5a9e962f2c81bdedf726cee5dbe4017d 100644 (file)
@@ -31,6 +31,7 @@
 #define S5P_USE_STANDBYWFE_ISP_ARM             (1 << 26)
 
 #define S5P_SWRESET                            S5P_PMUREG(0x0400)
+#define EXYNOS_SWRESET                         S5P_PMUREG(0x0400)
 
 #define S5P_WAKEUP_STAT                                S5P_PMUREG(0x0600)
 #define S5P_EINT_WAKEUP_MASK                   S5P_PMUREG(0x0604)
index 21d97bcd9acb4b09c9ac75033edb120faf701cf2..493f4f365ddfe65a8ceab62908bc2ff6725a1ef1 100644 (file)
@@ -1,9 +1,8 @@
-/* linux/arch/arm/mach-exynos4/include/mach/uncompress.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+/*
+ * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
  *
- * EXYNOS4 - uncompress code
+ * EXYNOS - uncompress code
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 #ifndef __ASM_ARCH_UNCOMPRESS_H
 #define __ASM_ARCH_UNCOMPRESS_H __FILE__
 
+#include <asm/mach-types.h>
+
 #include <mach/map.h>
+
+volatile u8 *uart_base;
+
 #include <plat/uncompress.h>
 
 static void arch_detect_cpu(void)
 {
-       /* we do not need to do any cpu detection here at the moment. */
+       if (machine_is_smdk5250())
+               uart_base = (volatile u8 *)EXYNOS5_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT);
+       else
+               uart_base = (volatile u8 *)EXYNOS4_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT);
 
        /*
         * For preventing FIFO overrun or infinite loop of UART console,
index e6b02fdf1b090ea75f7c5b9c2f14d13fc4c4ebcb..8245f1c761d9f5dd5124b83f189f6f95c20c501e 100644 (file)
  * data from the device tree.
  */
 static const struct of_dev_auxdata exynos4210_auxdata_lookup[] __initconst = {
-       OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART0,
+       OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART0,
                                "exynos4210-uart.0", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART1,
+       OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART1,
                                "exynos4210-uart.1", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART2,
+       OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART2,
                                "exynos4210-uart.2", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART3,
+       OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART3,
                                "exynos4210-uart.3", NULL),
        OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(0),
                                "exynos4-sdhci.0", NULL),
diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c
new file mode 100644 (file)
index 0000000..0d26f50
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * SAMSUNG EXYNOS5250 Flattened Device Tree enabled machine
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/of_platform.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/arch.h>
+#include <asm/hardware/gic.h>
+#include <mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/regs-serial.h>
+
+#include "common.h"
+
+/*
+ * The following lookup table is used to override device names when devices
+ * are registered from device tree. This is temporarily added to enable
+ * device tree support addition for the EXYNOS5 architecture.
+ *
+ * For drivers that require platform data to be provided from the machine
+ * file, a platform data pointer can also be supplied along with the
+ * devices names. Usually, the platform data elements that cannot be parsed
+ * from the device tree by the drivers (example: function pointers) are
+ * supplied. But it should be noted that this is a temporary mechanism and
+ * at some point, the drivers should be capable of parsing all the platform
+ * data from the device tree.
+ */
+static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = {
+       OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART0,
+                               "exynos4210-uart.0", NULL),
+       OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART1,
+                               "exynos4210-uart.1", NULL),
+       OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART2,
+                               "exynos4210-uart.2", NULL),
+       OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART3,
+                               "exynos4210-uart.3", NULL),
+       OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL),
+       OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL),
+       OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.2", NULL),
+       {},
+};
+
+static void __init exynos5250_dt_map_io(void)
+{
+       exynos_init_io(NULL, 0);
+       s3c24xx_init_clocks(24000000);
+}
+
+static void __init exynos5250_dt_machine_init(void)
+{
+       of_platform_populate(NULL, of_default_bus_match_table,
+                               exynos5250_auxdata_lookup, NULL);
+}
+
+static char const *exynos5250_dt_compat[] __initdata = {
+       "samsung,exynos5250",
+       NULL
+};
+
+DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)")
+       /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+       .init_irq       = exynos5_init_irq,
+       .map_io         = exynos5250_dt_map_io,
+       .handle_irq     = gic_handle_irq,
+       .init_machine   = exynos5250_dt_machine_init,
+       .timer          = &exynos4_timer,
+       .dt_compat      = exynos5250_dt_compat,
+       .restart        = exynos5_restart,
+MACHINE_END
index aa37179d776c6fd3ae0bd8daeec51a80ee134bc7..82ea6fccfb3450e54487b24ead9e12c2af589e9b 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <video/platform_lcd.h>
 #include <media/m5mols.h>
+#include <media/s5k6aa.h>
 #include <media/s5p_fimc.h>
 #include <media/v4l2-mediabus.h>
 
@@ -75,6 +76,7 @@ enum fixed_regulator_id {
        FIXED_REG_ID_MAX8903,
        FIXED_REG_ID_CAM_A28V,
        FIXED_REG_ID_CAM_12V,
+       FIXED_REG_ID_CAM_VT_15V,
 };
 
 static struct s3c2410_uartcfg nuri_uartcfgs[] __initdata = {
@@ -115,7 +117,7 @@ static struct s3c_sdhci_platdata nuri_hsmmc0_data __initdata = {
 };
 
 static struct regulator_consumer_supply emmc_supplies[] = {
-       REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
+       REGULATOR_SUPPLY("vmmc", "exynos4-sdhci.0"),
        REGULATOR_SUPPLY("vmmc", "dw_mmc"),
 };
 
@@ -399,6 +401,9 @@ static struct regulator_consumer_supply __initdata max8997_ldo4_[] = {
 static struct regulator_consumer_supply __initdata max8997_ldo5_[] = {
        REGULATOR_SUPPLY("vhsic", "modemctl"), /* MODEM */
 };
+static struct regulator_consumer_supply nuri_max8997_ldo6_consumer[] = {
+       REGULATOR_SUPPLY("vdd_reg", "6-003c"), /* S5K6AA camera */
+};
 static struct regulator_consumer_supply __initdata max8997_ldo7_[] = {
        REGULATOR_SUPPLY("dig_18", "0-001f"), /* HCD803 */
 };
@@ -413,7 +418,7 @@ static struct regulator_consumer_supply __initdata max8997_ldo12_[] = {
        REGULATOR_SUPPLY("vddio", "6-003c"), /* HDC802 */
 };
 static struct regulator_consumer_supply __initdata max8997_ldo13_[] = {
-       REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"), /* TFLASH */
+       REGULATOR_SUPPLY("vmmc", "exynos4-sdhci.2"), /* TFLASH */
 };
 static struct regulator_consumer_supply __initdata max8997_ldo14_[] = {
        REGULATOR_SUPPLY("inmotor", "max8997-haptic"),
@@ -431,7 +436,7 @@ static struct regulator_consumer_supply __initdata max8997_buck1_[] = {
        REGULATOR_SUPPLY("vdd_arm", NULL), /* CPUFREQ */
 };
 static struct regulator_consumer_supply __initdata max8997_buck2_[] = {
-       REGULATOR_SUPPLY("vdd_int", NULL), /* CPUFREQ */
+       REGULATOR_SUPPLY("vdd_int", "exynos4210-busfreq.0"), /* CPUFREQ */
 };
 static struct regulator_consumer_supply __initdata max8997_buck3_[] = {
        REGULATOR_SUPPLY("vdd", "mali_dev.0"), /* G3D of Exynos 4 */
@@ -546,6 +551,8 @@ static struct regulator_init_data __initdata max8997_ldo6_data = {
                        .enabled        = 1,
                },
        },
+       .num_consumer_supplies  = ARRAY_SIZE(nuri_max8997_ldo6_consumer),
+       .consumer_supplies      = nuri_max8997_ldo6_consumer,
 };
 
 static struct regulator_init_data __initdata max8997_ldo7_data = {
@@ -742,7 +749,7 @@ static struct regulator_init_data __initdata max8997_buck2_data = {
        .constraints    = {
                .name           = "VINT_1.1V_C210",
                .min_uV         = 900000,
-               .max_uV         = 1100000,
+               .max_uV         = 1200000,
                .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
                .always_on      = 1,
                .state_mem      = {
@@ -957,7 +964,6 @@ static struct max8997_platform_data __initdata nuri_max8997_pdata = {
        .regulators             = nuri_max8997_regulators,
 
        .buck125_gpios = { EXYNOS4_GPX0(5), EXYNOS4_GPX0(6), EXYNOS4_GPL0(0) },
-       .buck2_gpiodvs = true,
 
        .buck1_voltage[0] = 1350000, /* 1.35V */
        .buck1_voltage[1] = 1300000, /* 1.3V */
@@ -1116,7 +1122,30 @@ static void __init nuri_ehci_init(void)
 }
 
 /* CAMERA */
+static struct regulator_consumer_supply cam_vt_cam15_supply =
+       REGULATOR_SUPPLY("vdd_core", "6-003c");
+
+static struct regulator_init_data cam_vt_cam15_reg_init_data = {
+       .constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
+       .num_consumer_supplies = 1,
+       .consumer_supplies = &cam_vt_cam15_supply,
+};
+
+static struct fixed_voltage_config cam_vt_cam15_fixed_voltage_cfg = {
+       .supply_name    = "VT_CAM_1.5V",
+       .microvolts     = 1500000,
+       .gpio           = EXYNOS4_GPE2(2), /* VT_CAM_1.5V_EN */
+       .enable_high    = 1,
+       .init_data      = &cam_vt_cam15_reg_init_data,
+};
+
+static struct platform_device cam_vt_cam15_fixed_rdev = {
+       .name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_VT_15V,
+       .dev = { .platform_data = &cam_vt_cam15_fixed_voltage_cfg },
+};
+
 static struct regulator_consumer_supply cam_vdda_supply[] = {
+       REGULATOR_SUPPLY("vdda", "6-003c"),
        REGULATOR_SUPPLY("a_sensor", "0-001f"),
 };
 
@@ -1173,6 +1202,21 @@ static struct s5p_platform_mipi_csis mipi_csis_platdata = {
 
 #define GPIO_CAM_MEGA_RST      EXYNOS4_GPY3(7) /* ISP_RESET */
 #define GPIO_CAM_8M_ISP_INT    EXYNOS4_GPL2(5)
+#define GPIO_CAM_VT_NSTBY      EXYNOS4_GPL2(0)
+#define GPIO_CAM_VT_NRST       EXYNOS4_GPL2(1)
+
+static struct s5k6aa_platform_data s5k6aa_pldata = {
+       .mclk_frequency = 24000000UL,
+       .gpio_reset     = { GPIO_CAM_VT_NRST, 0 },
+       .gpio_stby      = { GPIO_CAM_VT_NSTBY, 0 },
+       .bus_type       = V4L2_MBUS_PARALLEL,
+       .horiz_flip     = 1,
+};
+
+static struct i2c_board_info s5k6aa_board_info = {
+       I2C_BOARD_INFO("S5K6AA", 0x3c),
+       .platform_data = &s5k6aa_pldata,
+};
 
 static struct m5mols_platform_data m5mols_platdata = {
        .gpio_reset = GPIO_CAM_MEGA_RST,
@@ -1185,6 +1229,13 @@ static struct i2c_board_info m5mols_board_info = {
 
 static struct s5p_fimc_isp_info nuri_camera_sensors[] = {
        {
+               .flags          = V4L2_MBUS_PCLK_SAMPLE_RISING |
+                                 V4L2_MBUS_VSYNC_ACTIVE_LOW,
+               .bus_type       = FIMC_ITU_601,
+               .board_info     = &s5k6aa_board_info,
+               .clk_frequency  = 24000000UL,
+               .i2c_bus_num    = 6,
+       }, {
                .flags          = V4L2_MBUS_PCLK_SAMPLE_FALLING |
                                  V4L2_MBUS_VSYNC_ACTIVE_LOW,
                .bus_type       = FIMC_MIPI_CSI2,
@@ -1200,11 +1251,13 @@ static struct s5p_platform_fimc fimc_md_platdata = {
 };
 
 static struct gpio nuri_camera_gpios[] = {
+       { GPIO_CAM_VT_NSTBY,    GPIOF_OUT_INIT_LOW, "CAM_VGA_NSTBY" },
+       { GPIO_CAM_VT_NRST,     GPIOF_OUT_INIT_LOW, "CAM_VGA_NRST"  },
        { GPIO_CAM_8M_ISP_INT,  GPIOF_IN,           "8M_ISP_INT"  },
        { GPIO_CAM_MEGA_RST,    GPIOF_OUT_INIT_LOW, "CAM_8M_NRST" },
 };
 
-static void nuri_camera_init(void)
+static void __init nuri_camera_init(void)
 {
        s3c_set_platdata(&mipi_csis_platdata, sizeof(mipi_csis_platdata),
                         &s5p_device_mipi_csis0);
@@ -1224,6 +1277,8 @@ static void nuri_camera_init(void)
                pr_err("%s: Failed to configure 8M_ISP_INT GPIO\n", __func__);
 
        /* Free GPIOs controlled directly by the sensor drivers. */
+       gpio_free(GPIO_CAM_VT_NRST);
+       gpio_free(GPIO_CAM_VT_NSTBY);
        gpio_free(GPIO_CAM_MEGA_RST);
 
        if (exynos4_fimc_setup_gpio(S5P_CAMPORT_A)) {
@@ -1234,15 +1289,27 @@ static void nuri_camera_init(void)
        s5p_gpio_set_drvstr(EXYNOS4_GPJ1(3), S5P_GPIO_DRVSTR_LV4);
 }
 
+static struct s3c2410_platform_i2c nuri_i2c6_platdata __initdata = {
+       .frequency      = 400000U,
+       .sda_delay      = 200,
+       .bus_num        = 6,
+};
+
 static struct s3c2410_platform_i2c nuri_i2c0_platdata __initdata = {
        .frequency      = 400000U,
        .sda_delay      = 200,
 };
 
+/* DEVFREQ controlling memory/bus */
+static struct platform_device exynos4_bus_devfreq = {
+       .name                   = "exynos4210-busfreq",
+};
+
 static struct platform_device *nuri_devices[] __initdata = {
        /* Samsung Platform Devices */
        &s3c_device_i2c5, /* PMIC should initialize first */
        &s3c_device_i2c0,
+       &s3c_device_i2c6,
        &emmc_fixed_voltage,
        &s5p_device_mipi_csis0,
        &s5p_device_fimc0,
@@ -1259,6 +1326,8 @@ static struct platform_device *nuri_devices[] __initdata = {
        &s3c_device_i2c3,
        &i2c9_gpio,
        &s3c_device_adc,
+       &s5p_device_g2d,
+       &s5p_device_jpeg,
        &s3c_device_rtc,
        &s5p_device_mfc,
        &s5p_device_mfc_l,
@@ -1271,8 +1340,10 @@ static struct platform_device *nuri_devices[] __initdata = {
        &nuri_backlight_device,
        &max8903_fixed_reg_dev,
        &nuri_max8903_device,
+       &cam_vt_cam15_fixed_rdev,
        &cam_vdda_fixed_rdev,
        &cam_8m_12v_fixed_rdev,
+       &exynos4_bus_devfreq,
 };
 
 static void __init nuri_map_io(void)
@@ -1302,6 +1373,7 @@ static void __init nuri_machine_init(void)
        i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
        i2c9_devs[I2C9_MAX17042].irq = gpio_to_irq(EXYNOS4_GPX2(3));
        i2c_register_board_info(9, i2c9_devs, ARRAY_SIZE(i2c9_devs));
+       s3c_i2c6_set_platdata(&nuri_i2c6_platdata);
 
        s5p_fimd0_set_platdata(&nuri_fb_pdata);
 
index fa5c4a59b0aadfcd3022c304c5d0cb49fe7fa5ad..878d4c99142da9fb7809bf4ee1bfdc843837ac94 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/regulator/machine.h>
 #include <linux/mfd/max8997.h>
 #include <linux/lcd.h>
+#include <linux/rfkill-gpio.h>
 
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
@@ -235,6 +236,7 @@ static struct regulator_init_data __initdata max8997_ldo9_data = {
                .min_uV         = 2800000,
                .max_uV         = 2800000,
                .apply_uV       = 1,
+               .always_on      = 1,
                .valid_ops_mask = REGULATOR_CHANGE_STATUS,
                .state_mem      = {
                        .disabled       = 1,
@@ -278,6 +280,7 @@ static struct regulator_init_data __initdata max8997_ldo14_data = {
                .min_uV         = 1800000,
                .max_uV         = 1800000,
                .apply_uV       = 1,
+               .always_on      = 1,
                .valid_ops_mask = REGULATOR_CHANGE_STATUS,
                .state_mem      = {
                        .disabled       = 1,
@@ -293,6 +296,7 @@ static struct regulator_init_data __initdata max8997_ldo17_data = {
                .min_uV         = 3300000,
                .max_uV         = 3300000,
                .apply_uV       = 1,
+               .always_on      = 1,
                .valid_ops_mask = REGULATOR_CHANGE_STATUS,
                .state_mem      = {
                        .disabled       = 1,
@@ -412,7 +416,7 @@ static struct max8997_regulator_data __initdata origen_max8997_regulators[] = {
        { MAX8997_BUCK7,        &max8997_buck7_data },
 };
 
-struct max8997_platform_data __initdata origen_max8997_pdata = {
+static struct max8997_platform_data __initdata origen_max8997_pdata = {
        .num_regulators = ARRAY_SIZE(origen_max8997_regulators),
        .regulators     = origen_max8997_regulators,
 
@@ -602,6 +606,23 @@ static struct s3c_fb_platdata origen_lcd_pdata __initdata = {
        .setup_gpio     = exynos4_fimd0_gpio_setup_24bpp,
 };
 
+/* Bluetooth rfkill gpio platform data */
+struct rfkill_gpio_platform_data origen_bt_pdata = {
+       .reset_gpio     = EXYNOS4_GPX2(2),
+       .shutdown_gpio  = -1,
+       .type           = RFKILL_TYPE_BLUETOOTH,
+       .name           = "origen-bt",
+};
+
+/* Bluetooth Platform device */
+static struct platform_device origen_device_bluetooth = {
+       .name           = "rfkill_gpio",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &origen_bt_pdata,
+       },
+};
+
 static struct platform_device *origen_devices[] __initdata = {
        &s3c_device_hsmmc2,
        &s3c_device_hsmmc0,
@@ -613,9 +634,12 @@ static struct platform_device *origen_devices[] __initdata = {
        &s5p_device_fimc1,
        &s5p_device_fimc2,
        &s5p_device_fimc3,
+       &s5p_device_fimc_md,
        &s5p_device_fimd0,
+       &s5p_device_g2d,
        &s5p_device_hdmi,
        &s5p_device_i2c_hdmiphy,
+       &s5p_device_jpeg,
        &s5p_device_mfc,
        &s5p_device_mfc_l,
        &s5p_device_mfc_r,
@@ -623,6 +647,7 @@ static struct platform_device *origen_devices[] __initdata = {
        &exynos4_device_ohci,
        &origen_device_gpiokeys,
        &origen_lcd_hv070wsa,
+       &origen_device_bluetooth,
 };
 
 /* LCD Backlight data */
@@ -636,6 +661,16 @@ static struct platform_pwm_backlight_data origen_bl_data = {
        .pwm_period_ns  = 1000,
 };
 
+static void __init origen_bt_setup(void)
+{
+       gpio_request(EXYNOS4_GPA0(0), "GPIO BT_UART");
+       /* 4 UART Pins configuration */
+       s3c_gpio_cfgrange_nopull(EXYNOS4_GPA0(0), 4, S3C_GPIO_SFN(2));
+       /* Setup BT Reset, this gpio will be requesed by rfkill-gpio */
+       s3c_gpio_cfgpin(EXYNOS4_GPX2(2), S3C_GPIO_OUTPUT);
+       s3c_gpio_setpull(EXYNOS4_GPX2(2), S3C_GPIO_PULL_NONE);
+}
+
 static void s5p_tv_setup(void)
 {
        /* Direct HPD to HDMI chip */
@@ -689,6 +724,8 @@ static void __init origen_machine_init(void)
        platform_add_devices(origen_devices, ARRAY_SIZE(origen_devices));
 
        samsung_bl_set(&origen_bl_gpio_info, &origen_bl_data);
+
+       origen_bt_setup();
 }
 
 MACHINE_START(ORIGEN, "ORIGEN")
index 5258b85636765bd24e9e5e478ec7fb586bf55cc9..83b91fa777c1aeb4ca5ee95ff81f244a1641e904 100644 (file)
@@ -270,6 +270,9 @@ static struct platform_device *smdkv310_devices[] __initdata = {
        &s5p_device_fimc1,
        &s5p_device_fimc2,
        &s5p_device_fimc3,
+       &s5p_device_fimc_md,
+       &s5p_device_g2d,
+       &s5p_device_jpeg,
        &exynos4_device_ac97,
        &exynos4_device_i2s0,
        &exynos4_device_ohci,
index b2d495b31094f5f2a82498c122dfc30a64398ec9..28658da9f4230e8d17c000e4fec5ca696fb39373 100644 (file)
@@ -47,6 +47,7 @@
 #include <media/v4l2-mediabus.h>
 #include <media/s5p_fimc.h>
 #include <media/m5mols.h>
+#include <media/s5k6aa.h>
 
 #include "common.h"
 
@@ -123,8 +124,10 @@ static struct regulator_consumer_supply lp3974_buck1_consumer =
 static struct regulator_consumer_supply lp3974_buck2_consumer =
        REGULATOR_SUPPLY("vddg3d", NULL);
 
-static struct regulator_consumer_supply lp3974_buck3_consumer =
-       REGULATOR_SUPPLY("vdet", "s5p-sdo");
+static struct regulator_consumer_supply lp3974_buck3_consumer[] = {
+       REGULATOR_SUPPLY("vdet", "s5p-sdo"),
+       REGULATOR_SUPPLY("vdd_reg", "0-003c"),
+};
 
 static struct regulator_init_data lp3974_buck1_data = {
        .constraints    = {
@@ -169,8 +172,8 @@ static struct regulator_init_data lp3974_buck3_data = {
                        .enabled        = 1,
                },
        },
-       .num_consumer_supplies = 1,
-       .consumer_supplies = &lp3974_buck3_consumer,
+       .num_consumer_supplies = ARRAY_SIZE(lp3974_buck3_consumer),
+       .consumer_supplies = lp3974_buck3_consumer,
 };
 
 static struct regulator_init_data lp3974_buck4_data = {
@@ -303,6 +306,9 @@ static struct regulator_init_data lp3974_ldo8_data = {
        .consumer_supplies = lp3974_ldo8_consumer,
 };
 
+static struct regulator_consumer_supply lp3974_ldo9_consumer =
+       REGULATOR_SUPPLY("vddio", "0-003c");
+
 static struct regulator_init_data lp3974_ldo9_data = {
        .constraints    = {
                .name           = "VCC_2.8V",
@@ -314,6 +320,8 @@ static struct regulator_init_data lp3974_ldo9_data = {
                        .enabled        = 1,
                },
        },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &lp3974_ldo9_consumer,
 };
 
 static struct regulator_init_data lp3974_ldo10_data = {
@@ -412,6 +420,7 @@ static struct regulator_init_data lp3974_ldo15_data = {
 };
 
 static struct regulator_consumer_supply lp3974_ldo16_consumer[] = {
+       REGULATOR_SUPPLY("vdda", "0-003c"),
        REGULATOR_SUPPLY("a_sensor", "0-001f"),
 };
 
@@ -743,7 +752,7 @@ static struct s3c_sdhci_platdata universal_hsmmc0_data __initdata = {
 };
 
 static struct regulator_consumer_supply mmc0_supplies[] = {
-       REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
+       REGULATOR_SUPPLY("vmmc", "exynos4-sdhci.0"),
 };
 
 static struct regulator_init_data mmc0_fixed_voltage_init_data = {
@@ -819,6 +828,8 @@ static struct s3c_fb_pd_win universal_fb_win0 = {
        },
        .max_bpp        = 32,
        .default_bpp    = 16,
+       .virtual_x      = 480,
+       .virtual_y      = 2 * 800,
 };
 
 static struct s3c_fb_platdata universal_lcd_pdata __initdata = {
@@ -830,6 +841,28 @@ static struct s3c_fb_platdata universal_lcd_pdata __initdata = {
        .setup_gpio     = exynos4_fimd0_gpio_setup_24bpp,
 };
 
+static struct regulator_consumer_supply cam_vt_dio_supply =
+       REGULATOR_SUPPLY("vdd_core", "0-003c");
+
+static struct regulator_init_data cam_vt_dio_reg_init_data = {
+       .constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
+       .num_consumer_supplies = 1,
+       .consumer_supplies = &cam_vt_dio_supply,
+};
+
+static struct fixed_voltage_config cam_vt_dio_fixed_voltage_cfg = {
+       .supply_name    = "CAM_VT_D_IO",
+       .microvolts     = 2800000,
+       .gpio           = EXYNOS4_GPE2(1), /* CAM_PWR_EN2 */
+       .enable_high    = 1,
+       .init_data      = &cam_vt_dio_reg_init_data,
+};
+
+static struct platform_device cam_vt_dio_fixed_reg_dev = {
+       .name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_VT_DIO,
+       .dev = { .platform_data = &cam_vt_dio_fixed_voltage_cfg },
+};
+
 static struct regulator_consumer_supply cam_i_core_supply =
        REGULATOR_SUPPLY("core", "0-001f");
 
@@ -885,6 +918,28 @@ static struct s5p_platform_mipi_csis mipi_csis_platdata = {
 #define GPIO_CAM_LEVEL_EN(n)   EXYNOS4_GPE4(n + 3)
 #define GPIO_CAM_8M_ISP_INT    EXYNOS4_GPX1(5) /* XEINT_13 */
 #define GPIO_CAM_MEGA_nRST     EXYNOS4_GPE2(5)
+#define GPIO_CAM_VGA_NRST      EXYNOS4_GPE4(7)
+#define GPIO_CAM_VGA_NSTBY     EXYNOS4_GPE4(6)
+
+static int s5k6aa_set_power(int on)
+{
+       gpio_set_value(GPIO_CAM_LEVEL_EN(2), !!on);
+       return 0;
+}
+
+static struct s5k6aa_platform_data s5k6aa_platdata = {
+       .mclk_frequency = 21600000UL,
+       .gpio_reset     = { GPIO_CAM_VGA_NRST, 0 },
+       .gpio_stby      = { GPIO_CAM_VGA_NSTBY, 0 },
+       .bus_type       = V4L2_MBUS_PARALLEL,
+       .horiz_flip     = 1,
+       .set_power      = s5k6aa_set_power,
+};
+
+static struct i2c_board_info s5k6aa_board_info = {
+       I2C_BOARD_INFO("S5K6AA", 0x3C),
+       .platform_data = &s5k6aa_platdata,
+};
 
 static int m5mols_set_power(struct device *dev, int on)
 {
@@ -906,6 +961,14 @@ static struct i2c_board_info m5mols_board_info = {
 
 static struct s5p_fimc_isp_info universal_camera_sensors[] = {
        {
+               .mux_id         = 0,
+               .flags          = V4L2_MBUS_PCLK_SAMPLE_FALLING |
+                                 V4L2_MBUS_VSYNC_ACTIVE_LOW,
+               .bus_type       = FIMC_ITU_601,
+               .board_info     = &s5k6aa_board_info,
+               .i2c_bus_num    = 0,
+               .clk_frequency  = 24000000UL,
+       }, {
                .mux_id         = 0,
                .flags          = V4L2_MBUS_PCLK_SAMPLE_FALLING |
                                  V4L2_MBUS_VSYNC_ACTIVE_LOW,
@@ -927,9 +990,11 @@ static struct gpio universal_camera_gpios[] = {
        { GPIO_CAM_LEVEL_EN(2), GPIOF_OUT_INIT_LOW,  "CAM_LVL_EN2" },
        { GPIO_CAM_8M_ISP_INT,  GPIOF_IN,            "8M_ISP_INT"  },
        { GPIO_CAM_MEGA_nRST,   GPIOF_OUT_INIT_LOW,  "CAM_8M_NRST" },
+       { GPIO_CAM_VGA_NRST,    GPIOF_OUT_INIT_LOW,  "CAM_VGA_NRST"  },
+       { GPIO_CAM_VGA_NSTBY,   GPIOF_OUT_INIT_LOW,  "CAM_VGA_NSTBY" },
 };
 
-static void universal_camera_init(void)
+static void __init universal_camera_init(void)
 {
        s3c_set_platdata(&mipi_csis_platdata, sizeof(mipi_csis_platdata),
                         &s5p_device_mipi_csis0);
@@ -950,6 +1015,8 @@ static void universal_camera_init(void)
        /* Free GPIOs controlled directly by the sensor drivers. */
        gpio_free(GPIO_CAM_MEGA_nRST);
        gpio_free(GPIO_CAM_8M_ISP_INT);
+       gpio_free(GPIO_CAM_VGA_NRST);
+       gpio_free(GPIO_CAM_VGA_NSTBY);
 
        if (exynos4_fimc_setup_gpio(S5P_CAMPORT_A))
                pr_err("Camera port A setup failed\n");
@@ -962,6 +1029,7 @@ static struct platform_device *universal_devices[] __initdata = {
        &s5p_device_fimc1,
        &s5p_device_fimc2,
        &s5p_device_fimc3,
+       &s5p_device_g2d,
        &mmc0_fixed_voltage,
        &s3c_device_hsmmc0,
        &s3c_device_hsmmc2,
@@ -980,9 +1048,11 @@ static struct platform_device *universal_devices[] __initdata = {
        &universal_gpio_keys,
        &s5p_device_onenand,
        &s5p_device_fimd0,
+       &s5p_device_jpeg,
        &s5p_device_mfc,
        &s5p_device_mfc_l,
        &s5p_device_mfc_r,
+       &cam_vt_dio_fixed_reg_dev,
        &cam_i_core_fixed_reg_dev,
        &cam_s_if_fixed_reg_dev,
        &s5p_device_fimc_md,
@@ -995,7 +1065,7 @@ static void __init universal_map_io(void)
        s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
 }
 
-void s5p_tv_setup(void)
+static void s5p_tv_setup(void)
 {
        /* direct HPD to HDMI chip */
        gpio_request_one(EXYNOS4_GPX3(7), GPIOF_IN, "hpd-plug");
index 85b5527d0918e4bea1ca7b9abea9362dd64c357d..897d9a9cf2265bf6d2d3bf1c73dff584e647d551 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/percpu.h>
 
 #include <asm/hardware/gic.h>
+#include <asm/localtimer.h>
 
 #include <plat/cpu.h>
 
 #include <mach/regs-mct.h>
 #include <asm/mach/time.h>
 
+#define TICK_BASE_CNT  1
+
 enum {
        MCT_INT_SPI,
        MCT_INT_PPI
 };
 
-static unsigned long clk_cnt_per_tick;
 static unsigned long clk_rate;
 static unsigned int mct_int_type;
 
@@ -205,11 +207,14 @@ static int exynos4_comp_set_next_event(unsigned long cycles,
 static void exynos4_comp_set_mode(enum clock_event_mode mode,
                                  struct clock_event_device *evt)
 {
+       unsigned long cycles_per_jiffy;
        exynos4_mct_comp0_stop();
 
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
-               exynos4_mct_comp0_start(mode, clk_cnt_per_tick);
+               cycles_per_jiffy =
+                       (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
+               exynos4_mct_comp0_start(mode, cycles_per_jiffy);
                break;
 
        case CLOCK_EVT_MODE_ONESHOT:
@@ -248,9 +253,7 @@ static struct irqaction mct_comp_event_irq = {
 
 static void exynos4_clockevent_init(void)
 {
-       clk_cnt_per_tick = clk_rate / 2 / HZ;
-
-       clockevents_calc_mult_shift(&mct_comp_device, clk_rate / 2, 5);
+       clockevents_calc_mult_shift(&mct_comp_device, clk_rate, 5);
        mct_comp_device.max_delta_ns =
                clockevent_delta2ns(0xffffffff, &mct_comp_device);
        mct_comp_device.min_delta_ns =
@@ -258,7 +261,10 @@ static void exynos4_clockevent_init(void)
        mct_comp_device.cpumask = cpumask_of(0);
        clockevents_register_device(&mct_comp_device);
 
-       setup_irq(IRQ_MCT_G0, &mct_comp_event_irq);
+       if (soc_is_exynos5250())
+               setup_irq(EXYNOS5_IRQ_MCT_G0, &mct_comp_event_irq);
+       else
+               setup_irq(EXYNOS4_IRQ_MCT_G0, &mct_comp_event_irq);
 }
 
 #ifdef CONFIG_LOCAL_TIMERS
@@ -314,12 +320,15 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
                                         struct clock_event_device *evt)
 {
        struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
+       unsigned long cycles_per_jiffy;
 
        exynos4_mct_tick_stop(mevt);
 
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
-               exynos4_mct_tick_start(clk_cnt_per_tick, mevt);
+               cycles_per_jiffy =
+                       (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
+               exynos4_mct_tick_start(cycles_per_jiffy, mevt);
                break;
 
        case CLOCK_EVT_MODE_ONESHOT:
@@ -375,7 +384,7 @@ static struct irqaction mct_tick1_event_irq = {
        .handler        = exynos4_mct_tick_isr,
 };
 
-static void exynos4_mct_tick_init(struct clock_event_device *evt)
+static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
 {
        struct mct_clock_event_device *mevt;
        unsigned int cpu = smp_processor_id();
@@ -393,7 +402,7 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
        evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
        evt->rating = 450;
 
-       clockevents_calc_mult_shift(evt, clk_rate / 2, 5);
+       clockevents_calc_mult_shift(evt, clk_rate / (TICK_BASE_CNT + 1), 5);
        evt->max_delta_ns =
                clockevent_delta2ns(0x7fffffff, evt);
        evt->min_delta_ns =
@@ -401,33 +410,27 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
 
        clockevents_register_device(evt);
 
-       exynos4_mct_write(0x1, mevt->base + MCT_L_TCNTB_OFFSET);
+       exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
 
        if (mct_int_type == MCT_INT_SPI) {
                if (cpu == 0) {
                        mct_tick0_event_irq.dev_id = mevt;
-                       evt->irq = IRQ_MCT_L0;
-                       setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq);
+                       evt->irq = EXYNOS4_IRQ_MCT_L0;
+                       setup_irq(EXYNOS4_IRQ_MCT_L0, &mct_tick0_event_irq);
                } else {
                        mct_tick1_event_irq.dev_id = mevt;
-                       evt->irq = IRQ_MCT_L1;
-                       setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq);
-                       irq_set_affinity(IRQ_MCT_L1, cpumask_of(1));
+                       evt->irq = EXYNOS4_IRQ_MCT_L1;
+                       setup_irq(EXYNOS4_IRQ_MCT_L1, &mct_tick1_event_irq);
+                       irq_set_affinity(EXYNOS4_IRQ_MCT_L1, cpumask_of(1));
                }
        } else {
-               enable_percpu_irq(IRQ_MCT_LOCALTIMER, 0);
+               enable_percpu_irq(EXYNOS_IRQ_MCT_LOCALTIMER, 0);
        }
-}
-
-/* Setup the local clock events for a CPU */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-       exynos4_mct_tick_init(evt);
 
        return 0;
 }
 
-void local_timer_stop(struct clock_event_device *evt)
+static void exynos4_local_timer_stop(struct clock_event_device *evt)
 {
        unsigned int cpu = smp_processor_id();
        evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
@@ -437,8 +440,13 @@ void local_timer_stop(struct clock_event_device *evt)
                else
                        remove_irq(evt->irq, &mct_tick1_event_irq);
        else
-               disable_percpu_irq(IRQ_MCT_LOCALTIMER);
+               disable_percpu_irq(EXYNOS_IRQ_MCT_LOCALTIMER);
 }
+
+static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {
+       .setup  = exynos4_local_timer_setup,
+       .stop   = exynos4_local_timer_stop,
+};
 #endif /* CONFIG_LOCAL_TIMERS */
 
 static void __init exynos4_timer_resources(void)
@@ -452,12 +460,14 @@ static void __init exynos4_timer_resources(void)
        if (mct_int_type == MCT_INT_PPI) {
                int err;
 
-               err = request_percpu_irq(IRQ_MCT_LOCALTIMER,
+               err = request_percpu_irq(EXYNOS_IRQ_MCT_LOCALTIMER,
                                         exynos4_mct_tick_isr, "MCT",
                                         &percpu_mct_tick);
                WARN(err, "MCT: can't request IRQ %d (%d)\n",
-                    IRQ_MCT_LOCALTIMER, err);
+                    EXYNOS_IRQ_MCT_LOCALTIMER, err);
        }
+
+       local_timer_register(&exynos4_mct_tick_ops);
 #endif /* CONFIG_LOCAL_TIMERS */
 }
 
index 0f2035a1eb6e5f31cf7bdbd16270af5efd4abee4..36c3984aaa47909e5e02b12a317cbe1f373897e2 100644 (file)
@@ -166,7 +166,10 @@ void __init smp_init_cpus(void)
        void __iomem *scu_base = scu_base_addr();
        unsigned int i, ncores;
 
-       ncores = scu_base ? scu_get_core_count(scu_base) : 1;
+       if (soc_is_exynos5250())
+               ncores = 2;
+       else
+               ncores = scu_base ? scu_get_core_count(scu_base) : 1;
 
        /* sanity check */
        if (ncores > nr_cpu_ids) {
@@ -183,8 +186,8 @@ void __init smp_init_cpus(void)
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 {
-
-       scu_enable(scu_base_addr());
+       if (!soc_is_exynos5250())
+               scu_enable(scu_base_addr());
 
        /*
         * Write the address of secondary startup into the
index e190130517727ea9bcdfb9541496922093a9d672..428cfeb577248a5e812e7c954b8faa7584bbbe3a 100644 (file)
 #include <mach/pmu.h>
 
 static struct sleep_save exynos4_set_clksrc[] = {
-       { .reg = S5P_CLKSRC_MASK_TOP                    , .val = 0x00000001, },
-       { .reg = S5P_CLKSRC_MASK_CAM                    , .val = 0x11111111, },
-       { .reg = S5P_CLKSRC_MASK_TV                     , .val = 0x00000111, },
-       { .reg = S5P_CLKSRC_MASK_LCD0                   , .val = 0x00001111, },
-       { .reg = S5P_CLKSRC_MASK_MAUDIO                 , .val = 0x00000001, },
-       { .reg = S5P_CLKSRC_MASK_FSYS                   , .val = 0x01011111, },
-       { .reg = S5P_CLKSRC_MASK_PERIL0                 , .val = 0x01111111, },
-       { .reg = S5P_CLKSRC_MASK_PERIL1                 , .val = 0x01110111, },
-       { .reg = S5P_CLKSRC_MASK_DMC                    , .val = 0x00010000, },
+       { .reg = EXYNOS4_CLKSRC_MASK_TOP                , .val = 0x00000001, },
+       { .reg = EXYNOS4_CLKSRC_MASK_CAM                , .val = 0x11111111, },
+       { .reg = EXYNOS4_CLKSRC_MASK_TV                 , .val = 0x00000111, },
+       { .reg = EXYNOS4_CLKSRC_MASK_LCD0               , .val = 0x00001111, },
+       { .reg = EXYNOS4_CLKSRC_MASK_MAUDIO             , .val = 0x00000001, },
+       { .reg = EXYNOS4_CLKSRC_MASK_FSYS               , .val = 0x01011111, },
+       { .reg = EXYNOS4_CLKSRC_MASK_PERIL0             , .val = 0x01111111, },
+       { .reg = EXYNOS4_CLKSRC_MASK_PERIL1             , .val = 0x01110111, },
+       { .reg = EXYNOS4_CLKSRC_MASK_DMC                , .val = 0x00010000, },
 };
 
 static struct sleep_save exynos4210_set_clksrc[] = {
-       { .reg = S5P_CLKSRC_MASK_LCD1                   , .val = 0x00001111, },
+       { .reg = EXYNOS4210_CLKSRC_MASK_LCD1            , .val = 0x00001111, },
 };
 
 static struct sleep_save exynos4_epll_save[] = {
-       SAVE_ITEM(S5P_EPLL_CON0),
-       SAVE_ITEM(S5P_EPLL_CON1),
+       SAVE_ITEM(EXYNOS4_EPLL_CON0),
+       SAVE_ITEM(EXYNOS4_EPLL_CON1),
 };
 
 static struct sleep_save exynos4_vpll_save[] = {
-       SAVE_ITEM(S5P_VPLL_CON0),
-       SAVE_ITEM(S5P_VPLL_CON1),
+       SAVE_ITEM(EXYNOS4_VPLL_CON0),
+       SAVE_ITEM(EXYNOS4_VPLL_CON1),
 };
 
 static struct sleep_save exynos4_core_save[] = {
@@ -155,13 +155,6 @@ static struct sleep_save exynos4_core_save[] = {
        SAVE_ITEM(S5P_SROM_BC3),
 };
 
-static struct sleep_save exynos4_l2cc_save[] = {
-       SAVE_ITEM(S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL),
-       SAVE_ITEM(S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL),
-       SAVE_ITEM(S5P_VA_L2CC + L2X0_PREFETCH_CTRL),
-       SAVE_ITEM(S5P_VA_L2CC + L2X0_POWER_CTRL),
-       SAVE_ITEM(S5P_VA_L2CC + L2X0_AUX_CTRL),
-};
 
 /* For Cortex-A9 Diagnostic and Power control register */
 static unsigned int save_arm_register[2];
@@ -182,7 +175,6 @@ static void exynos4_pm_prepare(void)
        u32 tmp;
 
        s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save));
-       s3c_pm_do_save(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
        s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save));
        s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save));
 
@@ -239,7 +231,7 @@ static void exynos4_restore_pll(void)
                locktime = (3000 / pll_in_rate) * p_div;
                lockcnt = locktime * 10000 / (10000 / pll_in_rate);
 
-               __raw_writel(lockcnt, S5P_EPLL_LOCK);
+               __raw_writel(lockcnt, EXYNOS4_EPLL_LOCK);
 
                s3c_pm_do_restore_core(exynos4_epll_save,
                                        ARRAY_SIZE(exynos4_epll_save));
@@ -257,7 +249,7 @@ static void exynos4_restore_pll(void)
                locktime = 750;
                lockcnt = locktime * 10000 / (10000 / pll_in_rate);
 
-               __raw_writel(lockcnt, S5P_VPLL_LOCK);
+               __raw_writel(lockcnt, EXYNOS4_VPLL_LOCK);
 
                s3c_pm_do_restore_core(exynos4_vpll_save,
                                        ARRAY_SIZE(exynos4_vpll_save));
@@ -268,14 +260,14 @@ static void exynos4_restore_pll(void)
 
        do {
                if (epll_wait) {
-                       pll_con = __raw_readl(S5P_EPLL_CON0);
-                       if (pll_con & (1 << S5P_EPLLCON0_LOCKED_SHIFT))
+                       pll_con = __raw_readl(EXYNOS4_EPLL_CON0);
+                       if (pll_con & (1 << EXYNOS4_EPLLCON0_LOCKED_SHIFT))
                                epll_wait = 0;
                }
 
                if (vpll_wait) {
-                       pll_con = __raw_readl(S5P_VPLL_CON0);
-                       if (pll_con & (1 << S5P_VPLLCON0_LOCKED_SHIFT))
+                       pll_con = __raw_readl(EXYNOS4_VPLL_CON0);
+                       if (pll_con & (1 << EXYNOS4_VPLLCON0_LOCKED_SHIFT))
                                vpll_wait = 0;
                }
        } while (epll_wait || vpll_wait);
@@ -388,13 +380,6 @@ static void exynos4_pm_resume(void)
        scu_enable(S5P_VA_SCU);
 #endif
 
-#ifdef CONFIG_CACHE_L2X0
-       s3c_pm_do_restore_core(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
-       outer_inv_all();
-       /* enable L2X0*/
-       writel_relaxed(1, S5P_VA_L2CC + L2X0_CTRL);
-#endif
-
 early_wakeup:
        return;
 }
index 0b04af2b13ccdb0cb49d646d56f146ab1f32f88e..13b306808b42b45606ae33cf6e1b101e1baa8382 100644 (file)
@@ -182,6 +182,12 @@ static __init int exynos4_pm_init_power_domain(void)
 #endif
 #ifdef CONFIG_S5P_DEV_CSIS1
        exynos_pm_add_dev_to_genpd(&s5p_device_mipi_csis1, &exynos4_pd_cam);
+#endif
+#ifdef CONFIG_S5P_DEV_G2D
+       exynos_pm_add_dev_to_genpd(&s5p_device_g2d, &exynos4_pd_lcd0);
+#endif
+#ifdef CONFIG_S5P_DEV_JPEG
+       exynos_pm_add_dev_to_genpd(&s5p_device_jpeg, &exynos4_pd_cam);
 #endif
        return 0;
 }
index d395bd17c38becccd313a0ce22e6f0b3cc7ec415..b90d94c17f7cbc7af586304047dd07e0f58d0496 100644 (file)
@@ -1,7 +1,5 @@
 /*
- * linux/arch/arm/mach-exynos4/setup-i2c0.c
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2009-2012 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com/
  *
  * I2C0 GPIO configuration.
@@ -18,9 +16,14 @@ struct platform_device; /* don't need the contents */
 #include <linux/gpio.h>
 #include <plat/iic.h>
 #include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
 
 void s3c_i2c0_cfg_gpio(struct platform_device *dev)
 {
+       if (soc_is_exynos5250())
+               /* will be implemented with gpio function */
+               return;
+
        s3c_gpio_cfgall_range(EXYNOS4_GPD1(0), 2,
                              S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
 }
index 986958a5a7201035da296736d4f9387afb8931e6..f8437dd238c2865adb462f8c1d23d575bda93cf1 100644 (file)
@@ -1,6 +1,5 @@
 obj-y                                  := clock.o highbank.o system.o
 obj-$(CONFIG_DEBUG_HIGHBANK_UART)      += lluart.o
 obj-$(CONFIG_SMP)                      += platsmp.o
-obj-$(CONFIG_LOCAL_TIMERS)             += localtimer.o
 obj-$(CONFIG_HOTPLUG_CPU)              += hotplug.o
 obj-$(CONFIG_PM_SLEEP)                 += pm.o
index 8394d512a40227e0d5526fd6cc731137f1d108d6..808b055289b2b0443cf5f197e47f3eac11aa6679 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/cacheflush.h>
 #include <asm/smp_plat.h>
 #include <asm/smp_scu.h>
+#include <asm/smp_twd.h>
 #include <asm/hardware/arm_timer.h>
 #include <asm/hardware/timer-sp.h>
 #include <asm/hardware/gic.h>
@@ -109,8 +110,10 @@ static void __init highbank_timer_init(void)
 
        highbank_clocks_init();
 
-       sp804_clocksource_init(timer_base + 0x20, "timer1");
+       sp804_clocksource_and_sched_clock_init(timer_base + 0x20, "timer1");
        sp804_clockevents_init(timer_base, irq, "timer0");
+
+       twd_local_timer_of_register();
 }
 
 static struct sys_timer highbank_timer = {
diff --git a/arch/arm/mach-highbank/include/mach/memory.h b/arch/arm/mach-highbank/include/mach/memory.h
deleted file mode 100644 (file)
index 40a8c17..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/* empty */
diff --git a/arch/arm/mach-highbank/localtimer.c b/arch/arm/mach-highbank/localtimer.c
deleted file mode 100644 (file)
index 5a00e79..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2010-2011 Calxeda, Inc.
- * Based on localtimer.c, Copyright (C) 2002 ARM Ltd.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-#include <linux/init.h>
-#include <linux/clockchips.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-
-#include <asm/smp_twd.h>
-
-/*
- * Setup the local clock events for a CPU.
- */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-       struct device_node *np;
-
-       np = of_find_compatible_node(NULL, NULL, "arm,smp-twd");
-       if (!twd_base) {
-               twd_base = of_iomap(np, 0);
-               WARN_ON(!twd_base);
-       }
-       evt->irq = irq_of_parse_and_map(np, 0);
-       twd_timer_setup(evt);
-       return 0;
-}
index 3919fba52ac80c30196eb1abe5bc152b7edd0f0b..52359f80c42d1b2e2bbe06fc93d1e72d389649e3 100644 (file)
@@ -298,6 +298,7 @@ config MACH_MX27_3DS
        select IMX_HAVE_PLATFORM_IMX_I2C
        select IMX_HAVE_PLATFORM_IMX_KEYPAD
        select IMX_HAVE_PLATFORM_IMX_UART
+       select IMX_HAVE_PLATFORM_MX2_CAMERA
        select IMX_HAVE_PLATFORM_MXC_EHCI
        select IMX_HAVE_PLATFORM_MXC_MMC
        select IMX_HAVE_PLATFORM_SPI_IMX
@@ -314,8 +315,10 @@ config MACH_IMX27_VISSTRIM_M10
        select IMX_HAVE_PLATFORM_IMX_I2C
        select IMX_HAVE_PLATFORM_IMX_SSI
        select IMX_HAVE_PLATFORM_IMX_UART
-       select IMX_HAVE_PLATFORM_MXC_MMC
+       select IMX_HAVE_PLATFORM_MX2_CAMERA
        select IMX_HAVE_PLATFORM_MXC_EHCI
+       select IMX_HAVE_PLATFORM_MXC_MMC
+       select LEDS_GPIO_REGISTER
        help
          Include support for Visstrim_m10 platform and its different variants.
          This includes specific configurations for the board and its
@@ -370,6 +373,14 @@ config MACH_IMX27IPCAM
          Include support for IMX27 IPCAM platform. This includes specific
          configurations for the board and its peripherals.
 
+config MACH_IMX27_DT
+       bool "Support i.MX27 platforms from device tree"
+       select SOC_IMX27
+       select USE_OF
+       help
+         Include support for Freescale i.MX27 based platforms
+         using the device tree for discovery
+
 endif
 
 if ARCH_IMX_V6_V7
@@ -486,6 +497,7 @@ config MACH_MX31MOBOARD
        bool "Support mx31moboard platforms (EPFL Mobots group)"
        select SOC_IMX31
        select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+       select IMX_HAVE_PLATFORM_IMX2_WDT
        select IMX_HAVE_PLATFORM_IMX_I2C
        select IMX_HAVE_PLATFORM_IMX_UART
        select IMX_HAVE_PLATFORM_IPU_CORE
index 55db9c488f2b408162e4bcca36f44d7cdb444ac0..35fc450fa263c2eb1e3d08d4bccd2c389e9b2105 100644 (file)
@@ -8,8 +8,8 @@ obj-$(CONFIG_SOC_IMX25) += clock-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o
 obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o
 obj-$(CONFIG_SOC_IMX27) += clock-imx27.o mm-imx27.o ehci-imx27.o
 
-obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o
-obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o
+obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o
+obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-imx3.o
 
 obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
 
@@ -41,6 +41,7 @@ obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o
 obj-$(CONFIG_MACH_PCA100) += mach-pca100.o
 obj-$(CONFIG_MACH_MXT_TD60) += mach-mxt_td60.o
 obj-$(CONFIG_MACH_IMX27IPCAM) += mach-imx27ipcam.o
+obj-$(CONFIG_MACH_IMX27_DT) += imx27-dt.o
 
 # i.MX31 based machines
 obj-$(CONFIG_MACH_MX31ADS) += mach-mx31ads.o
@@ -71,7 +72,6 @@ obj-$(CONFIG_CPU_V7) += head-v7.o
 AFLAGS_head-v7.o :=-Wa,-march=armv7-a
 obj-$(CONFIG_SMP) += platsmp.o
 obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
-obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
 obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o
 
 ifeq ($(CONFIG_PM),y)
index 6dfdbcc83afd7d4fb9e8245dfceed489e0c6970e..3851d8a27875996ac55946bda8d93d11af9f54c2 100644 (file)
@@ -38,5 +38,8 @@ zreladdr-$(CONFIG_SOC_IMX6Q)  += 0x10008000
 params_phys-$(CONFIG_SOC_IMX6Q)        := 0x10000100
 initrd_phys-$(CONFIG_SOC_IMX6Q)        := 0x10800000
 
+dtb-$(CONFIG_MACH_IMX51_DT) += imx51-babbage.dtb
+dtb-$(CONFIG_MACH_IMX53_DT) += imx53-ard.dtb imx53-evk.dtb \
+                              imx53-qsb.dtb imx53-smd.dtb
 dtb-$(CONFIG_SOC_IMX6Q)        += imx6q-arm2.dtb \
                           imx6q-sabrelite.dtb
index dc2d7a511d9bbde2c026866a75f0ccaffe5ffbc7..b9a95ed75553a73e4fcea686bf8f38a1e3216081 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/clkdev.h>
+#include <linux/of.h>
 
 #include <asm/div64.h>
 
@@ -764,3 +765,20 @@ int __init mx27_clocks_init(unsigned long fref)
        return 0;
 }
 
+#ifdef CONFIG_OF
+int __init mx27_clocks_init_dt(void)
+{
+       struct device_node *np;
+       u32 fref = 26000000; /* default */
+
+       for_each_compatible_node(np, NULL, "fixed-clock") {
+               if (!of_device_is_compatible(np, "fsl,imx-osc26m"))
+                       continue;
+
+               if (!of_property_read_u32(np, "clock-frequency", &fref))
+                       break;
+       }
+
+       return mx27_clocks_init(fref);
+}
+#endif
index 988a28178d4c8e2aff5dfaada74f604b86914d95..3a943cd4159fdd3bb6c640ca6fcf495828fb665c 100644 (file)
@@ -32,7 +32,7 @@
 #include <mach/mx31.h>
 #include <mach/common.h>
 
-#include "crmregs-imx31.h"
+#include "crmregs-imx3.h"
 
 #define PRE_DIV_MIN_FREQ    10000000 /* Minimum Frequency after Predivider */
 
index ac8238caecb98a98bf6c326e267fae24d88bb861..1e279af656ad034dc46abf13c836077f0c754eca 100644 (file)
 #include <mach/hardware.h>
 #include <mach/common.h>
 
-#define CCM_BASE       MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR)
-
-#define CCM_CCMR        0x00
-#define CCM_PDR0        0x04
-#define CCM_PDR1        0x08
-#define CCM_PDR2        0x0C
-#define CCM_PDR3        0x10
-#define CCM_PDR4        0x14
-#define CCM_RCSR        0x18
-#define CCM_MPCTL       0x1C
-#define CCM_PPCTL       0x20
-#define CCM_ACMR        0x24
-#define CCM_COSR        0x28
-#define CCM_CGR0        0x2C
-#define CCM_CGR1        0x30
-#define CCM_CGR2        0x34
-#define CCM_CGR3        0x38
+#include "crmregs-imx3.h"
 
 #ifdef HAVE_SET_RATE_SUPPORT
 static void calc_dividers(u32 div, u32 *pre, u32 *post, u32 maxpost)
@@ -111,14 +95,14 @@ static void calc_dividers_3_3(u32 div, u32 *pre, u32 *post)
 
 static unsigned long get_rate_mpll(void)
 {
-       ulong mpctl = __raw_readl(CCM_BASE + CCM_MPCTL);
+       ulong mpctl = __raw_readl(MX35_CCM_MPCTL);
 
        return mxc_decode_pll(mpctl, 24000000);
 }
 
 static unsigned long get_rate_ppll(void)
 {
-       ulong ppctl = __raw_readl(CCM_BASE + CCM_PPCTL);
+       ulong ppctl = __raw_readl(MX35_CCM_PPCTL);
 
        return mxc_decode_pll(ppctl, 24000000);
 }
@@ -148,7 +132,7 @@ static struct arm_ahb_div clk_consumer[] = {
 
 static unsigned long get_rate_arm(void)
 {
-       unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
+       unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0);
        struct arm_ahb_div *aad;
        unsigned long fref = get_rate_mpll();
 
@@ -161,7 +145,7 @@ static unsigned long get_rate_arm(void)
 
 static unsigned long get_rate_ahb(struct clk *clk)
 {
-       unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
+       unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0);
        struct arm_ahb_div *aad;
        unsigned long fref = get_rate_arm();
 
@@ -177,8 +161,8 @@ static unsigned long get_rate_ipg(struct clk *clk)
 
 static unsigned long get_rate_uart(struct clk *clk)
 {
-       unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
-       unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
+       unsigned long pdr3 = __raw_readl(MX35_CCM_PDR3);
+       unsigned long pdr4 = __raw_readl(MX35_CCM_PDR4);
        unsigned long div = ((pdr4 >> 10) & 0x3f) + 1;
 
        if (pdr3 & (1 << 14))
@@ -189,7 +173,7 @@ static unsigned long get_rate_uart(struct clk *clk)
 
 static unsigned long get_rate_sdhc(struct clk *clk)
 {
-       unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
+       unsigned long pdr3 = __raw_readl(MX35_CCM_PDR3);
        unsigned long div, rate;
 
        if (pdr3 & (1 << 6))
@@ -215,7 +199,7 @@ static unsigned long get_rate_sdhc(struct clk *clk)
 
 static unsigned long get_rate_mshc(struct clk *clk)
 {
-       unsigned long pdr1 = __raw_readl(CCM_BASE + CCM_PDR1);
+       unsigned long pdr1 = __raw_readl(MXC_CCM_PDR1);
        unsigned long div1, div2, rate;
 
        if (pdr1 & (1 << 7))
@@ -231,7 +215,7 @@ static unsigned long get_rate_mshc(struct clk *clk)
 
 static unsigned long get_rate_ssi(struct clk *clk)
 {
-       unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
+       unsigned long pdr2 = __raw_readl(MX35_CCM_PDR2);
        unsigned long div1, div2, rate;
 
        if (pdr2 & (1 << 6))
@@ -256,7 +240,7 @@ static unsigned long get_rate_ssi(struct clk *clk)
 
 static unsigned long get_rate_csi(struct clk *clk)
 {
-       unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
+       unsigned long pdr2 = __raw_readl(MX35_CCM_PDR2);
        unsigned long rate;
 
        if (pdr2 & (1 << 7))
@@ -269,7 +253,7 @@ static unsigned long get_rate_csi(struct clk *clk)
 
 static unsigned long get_rate_otg(struct clk *clk)
 {
-       unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
+       unsigned long pdr4 = __raw_readl(MX35_CCM_PDR4);
        unsigned long rate;
 
        if (pdr4 & (1 << 9))
@@ -282,8 +266,8 @@ static unsigned long get_rate_otg(struct clk *clk)
 
 static unsigned long get_rate_ipg_per(struct clk *clk)
 {
-       unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
-       unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
+       unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0);
+       unsigned long pdr4 = __raw_readl(MX35_CCM_PDR4);
        unsigned long div;
 
        if (pdr0 & (1 << 26)) {
@@ -297,7 +281,7 @@ static unsigned long get_rate_ipg_per(struct clk *clk)
 
 static unsigned long get_rate_hsp(struct clk *clk)
 {
-       unsigned long hsp_podf = (__raw_readl(CCM_BASE + CCM_PDR0) >> 20) & 0x03;
+       unsigned long hsp_podf = (__raw_readl(MXC_CCM_PDR0) >> 20) & 0x03;
        unsigned long fref = get_rate_mpll();
 
        if (fref > 400 * 1000 * 1000) {
@@ -345,7 +329,7 @@ static void clk_cgr_disable(struct clk *clk)
 #define DEFINE_CLOCK(name, i, er, es, gr, sr)          \
        static struct clk name = {                      \
                .id             = i,                    \
-               .enable_reg     = CCM_BASE + er,        \
+               .enable_reg     = er,                   \
                .enable_shift   = es,                   \
                .get_rate       = gr,                   \
                .set_rate       = sr,                   \
@@ -353,59 +337,59 @@ static void clk_cgr_disable(struct clk *clk)
                .disable        = clk_cgr_disable,      \
        }
 
-DEFINE_CLOCK(asrc_clk,   0, CCM_CGR0,  0, NULL, NULL);
-DEFINE_CLOCK(pata_clk,    0, CCM_CGR0,  2, get_rate_ipg, NULL);
-/* DEFINE_CLOCK(audmux_clk, 0, CCM_CGR0,  4, NULL, NULL); */
-DEFINE_CLOCK(can1_clk,   0, CCM_CGR0,  6, get_rate_ipg, NULL);
-DEFINE_CLOCK(can2_clk,   1, CCM_CGR0,  8, get_rate_ipg, NULL);
-DEFINE_CLOCK(cspi1_clk,  0, CCM_CGR0, 10, get_rate_ipg, NULL);
-DEFINE_CLOCK(cspi2_clk,  1, CCM_CGR0, 12, get_rate_ipg, NULL);
-DEFINE_CLOCK(ect_clk,    0, CCM_CGR0, 14, get_rate_ipg, NULL);
-DEFINE_CLOCK(edio_clk,   0, CCM_CGR0, 16, NULL, NULL);
-DEFINE_CLOCK(emi_clk,    0, CCM_CGR0, 18, get_rate_ipg, NULL);
-DEFINE_CLOCK(epit1_clk,  0, CCM_CGR0, 20, get_rate_ipg, NULL);
-DEFINE_CLOCK(epit2_clk,  1, CCM_CGR0, 22, get_rate_ipg, NULL);
-DEFINE_CLOCK(esai_clk,   0, CCM_CGR0, 24, NULL, NULL);
-DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGR0, 26, get_rate_sdhc, NULL);
-DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGR0, 28, get_rate_sdhc, NULL);
-DEFINE_CLOCK(esdhc3_clk, 2, CCM_CGR0, 30, get_rate_sdhc, NULL);
-
-DEFINE_CLOCK(fec_clk,    0, CCM_CGR1,  0, get_rate_ipg, NULL);
-DEFINE_CLOCK(gpio1_clk,  0, CCM_CGR1,  2, NULL, NULL);
-DEFINE_CLOCK(gpio2_clk,  1, CCM_CGR1,  4, NULL, NULL);
-DEFINE_CLOCK(gpio3_clk,  2, CCM_CGR1,  6, NULL, NULL);
-DEFINE_CLOCK(gpt_clk,    0, CCM_CGR1,  8, get_rate_ipg, NULL);
-DEFINE_CLOCK(i2c1_clk,   0, CCM_CGR1, 10, get_rate_ipg_per, NULL);
-DEFINE_CLOCK(i2c2_clk,   1, CCM_CGR1, 12, get_rate_ipg_per, NULL);
-DEFINE_CLOCK(i2c3_clk,   2, CCM_CGR1, 14, get_rate_ipg_per, NULL);
-DEFINE_CLOCK(iomuxc_clk, 0, CCM_CGR1, 16, NULL, NULL);
-DEFINE_CLOCK(ipu_clk,    0, CCM_CGR1, 18, get_rate_hsp, NULL);
-DEFINE_CLOCK(kpp_clk,    0, CCM_CGR1, 20, get_rate_ipg, NULL);
-DEFINE_CLOCK(mlb_clk,    0, CCM_CGR1, 22, get_rate_ahb, NULL);
-DEFINE_CLOCK(mshc_clk,   0, CCM_CGR1, 24, get_rate_mshc, NULL);
-DEFINE_CLOCK(owire_clk,  0, CCM_CGR1, 26, get_rate_ipg_per, NULL);
-DEFINE_CLOCK(pwm_clk,    0, CCM_CGR1, 28, get_rate_ipg_per, NULL);
-DEFINE_CLOCK(rngc_clk,   0, CCM_CGR1, 30, get_rate_ipg, NULL);
-
-DEFINE_CLOCK(rtc_clk,    0, CCM_CGR2,  0, get_rate_ipg, NULL);
-DEFINE_CLOCK(rtic_clk,   0, CCM_CGR2,  2, get_rate_ahb, NULL);
-DEFINE_CLOCK(scc_clk,    0, CCM_CGR2,  4, get_rate_ipg, NULL);
-DEFINE_CLOCK(sdma_clk,   0, CCM_CGR2,  6, NULL, NULL);
-DEFINE_CLOCK(spba_clk,   0, CCM_CGR2,  8, get_rate_ipg, NULL);
-DEFINE_CLOCK(spdif_clk,  0, CCM_CGR2, 10, NULL, NULL);
-DEFINE_CLOCK(ssi1_clk,   0, CCM_CGR2, 12, get_rate_ssi, NULL);
-DEFINE_CLOCK(ssi2_clk,   1, CCM_CGR2, 14, get_rate_ssi, NULL);
-DEFINE_CLOCK(uart1_clk,  0, CCM_CGR2, 16, get_rate_uart, NULL);
-DEFINE_CLOCK(uart2_clk,  1, CCM_CGR2, 18, get_rate_uart, NULL);
-DEFINE_CLOCK(uart3_clk,  2, CCM_CGR2, 20, get_rate_uart, NULL);
-DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, get_rate_otg, NULL);
-DEFINE_CLOCK(wdog_clk,   0, CCM_CGR2, 24, NULL, NULL);
-DEFINE_CLOCK(max_clk,    0, CCM_CGR2, 26, NULL, NULL);
-DEFINE_CLOCK(audmux_clk, 0, CCM_CGR2, 30, NULL, NULL);
-
-DEFINE_CLOCK(csi_clk,    0, CCM_CGR3,  0, get_rate_csi, NULL);
-DEFINE_CLOCK(iim_clk,    0, CCM_CGR3,  2, NULL, NULL);
-DEFINE_CLOCK(gpu2d_clk,  0, CCM_CGR3,  4, NULL, NULL);
+DEFINE_CLOCK(asrc_clk,   0, MX35_CCM_CGR0,  0, NULL, NULL);
+DEFINE_CLOCK(pata_clk,    0, MX35_CCM_CGR0,  2, get_rate_ipg, NULL);
+/* DEFINE_CLOCK(audmux_clk, 0, MX35_CCM_CGR0,  4, NULL, NULL); */
+DEFINE_CLOCK(can1_clk,   0, MX35_CCM_CGR0,  6, get_rate_ipg, NULL);
+DEFINE_CLOCK(can2_clk,   1, MX35_CCM_CGR0,  8, get_rate_ipg, NULL);
+DEFINE_CLOCK(cspi1_clk,  0, MX35_CCM_CGR0, 10, get_rate_ipg, NULL);
+DEFINE_CLOCK(cspi2_clk,  1, MX35_CCM_CGR0, 12, get_rate_ipg, NULL);
+DEFINE_CLOCK(ect_clk,    0, MX35_CCM_CGR0, 14, get_rate_ipg, NULL);
+DEFINE_CLOCK(edio_clk,   0, MX35_CCM_CGR0, 16, NULL, NULL);
+DEFINE_CLOCK(emi_clk,    0, MX35_CCM_CGR0, 18, get_rate_ipg, NULL);
+DEFINE_CLOCK(epit1_clk,  0, MX35_CCM_CGR0, 20, get_rate_ipg, NULL);
+DEFINE_CLOCK(epit2_clk,  1, MX35_CCM_CGR0, 22, get_rate_ipg, NULL);
+DEFINE_CLOCK(esai_clk,   0, MX35_CCM_CGR0, 24, NULL, NULL);
+DEFINE_CLOCK(esdhc1_clk, 0, MX35_CCM_CGR0, 26, get_rate_sdhc, NULL);
+DEFINE_CLOCK(esdhc2_clk, 1, MX35_CCM_CGR0, 28, get_rate_sdhc, NULL);
+DEFINE_CLOCK(esdhc3_clk, 2, MX35_CCM_CGR0, 30, get_rate_sdhc, NULL);
+
+DEFINE_CLOCK(fec_clk,    0, MX35_CCM_CGR1,  0, get_rate_ipg, NULL);
+DEFINE_CLOCK(gpio1_clk,  0, MX35_CCM_CGR1,  2, NULL, NULL);
+DEFINE_CLOCK(gpio2_clk,  1, MX35_CCM_CGR1,  4, NULL, NULL);
+DEFINE_CLOCK(gpio3_clk,  2, MX35_CCM_CGR1,  6, NULL, NULL);
+DEFINE_CLOCK(gpt_clk,    0, MX35_CCM_CGR1,  8, get_rate_ipg, NULL);
+DEFINE_CLOCK(i2c1_clk,   0, MX35_CCM_CGR1, 10, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(i2c2_clk,   1, MX35_CCM_CGR1, 12, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(i2c3_clk,   2, MX35_CCM_CGR1, 14, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(iomuxc_clk, 0, MX35_CCM_CGR1, 16, NULL, NULL);
+DEFINE_CLOCK(ipu_clk,    0, MX35_CCM_CGR1, 18, get_rate_hsp, NULL);
+DEFINE_CLOCK(kpp_clk,    0, MX35_CCM_CGR1, 20, get_rate_ipg, NULL);
+DEFINE_CLOCK(mlb_clk,    0, MX35_CCM_CGR1, 22, get_rate_ahb, NULL);
+DEFINE_CLOCK(mshc_clk,   0, MX35_CCM_CGR1, 24, get_rate_mshc, NULL);
+DEFINE_CLOCK(owire_clk,  0, MX35_CCM_CGR1, 26, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(pwm_clk,    0, MX35_CCM_CGR1, 28, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(rngc_clk,   0, MX35_CCM_CGR1, 30, get_rate_ipg, NULL);
+
+DEFINE_CLOCK(rtc_clk,    0, MX35_CCM_CGR2,  0, get_rate_ipg, NULL);
+DEFINE_CLOCK(rtic_clk,   0, MX35_CCM_CGR2,  2, get_rate_ahb, NULL);
+DEFINE_CLOCK(scc_clk,    0, MX35_CCM_CGR2,  4, get_rate_ipg, NULL);
+DEFINE_CLOCK(sdma_clk,   0, MX35_CCM_CGR2,  6, NULL, NULL);
+DEFINE_CLOCK(spba_clk,   0, MX35_CCM_CGR2,  8, get_rate_ipg, NULL);
+DEFINE_CLOCK(spdif_clk,  0, MX35_CCM_CGR2, 10, NULL, NULL);
+DEFINE_CLOCK(ssi1_clk,   0, MX35_CCM_CGR2, 12, get_rate_ssi, NULL);
+DEFINE_CLOCK(ssi2_clk,   1, MX35_CCM_CGR2, 14, get_rate_ssi, NULL);
+DEFINE_CLOCK(uart1_clk,  0, MX35_CCM_CGR2, 16, get_rate_uart, NULL);
+DEFINE_CLOCK(uart2_clk,  1, MX35_CCM_CGR2, 18, get_rate_uart, NULL);
+DEFINE_CLOCK(uart3_clk,  2, MX35_CCM_CGR2, 20, get_rate_uart, NULL);
+DEFINE_CLOCK(usbotg_clk, 0, MX35_CCM_CGR2, 22, get_rate_otg, NULL);
+DEFINE_CLOCK(wdog_clk,   0, MX35_CCM_CGR2, 24, NULL, NULL);
+DEFINE_CLOCK(max_clk,    0, MX35_CCM_CGR2, 26, NULL, NULL);
+DEFINE_CLOCK(audmux_clk, 0, MX35_CCM_CGR2, 30, NULL, NULL);
+
+DEFINE_CLOCK(csi_clk,    0, MX35_CCM_CGR3,  0, get_rate_csi, NULL);
+DEFINE_CLOCK(iim_clk,    0, MX35_CCM_CGR3,  2, NULL, NULL);
+DEFINE_CLOCK(gpu2d_clk,  0, MX35_CCM_CGR3,  4, NULL, NULL);
 
 DEFINE_CLOCK(usbahb_clk, 0, 0,         0, get_rate_ahb, NULL);
 
@@ -422,7 +406,7 @@ static unsigned long get_rate_nfc(struct clk *clk)
 {
        unsigned long div1;
 
-       div1 = (__raw_readl(CCM_BASE + CCM_PDR4) >> 28) + 1;
+       div1 = (__raw_readl(MX35_CCM_PDR4) >> 28) + 1;
 
        return get_rate_ahb(NULL) / div1;
 }
@@ -518,11 +502,11 @@ int __init mx35_clocks_init()
        /* Turn off all clocks except the ones we need to survive, namely:
         * EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart
         */
-       __raw_writel((3 << 18), CCM_BASE + CCM_CGR0);
+       __raw_writel((3 << 18), MX35_CCM_CGR0);
        __raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16),
-                       CCM_BASE + CCM_CGR1);
-       __raw_writel(cgr2, CCM_BASE + CCM_CGR2);
-       __raw_writel(0, CCM_BASE + CCM_CGR3);
+                       MX35_CCM_CGR1);
+       __raw_writel(cgr2, MX35_CCM_CGR2);
+       __raw_writel(0, MX35_CCM_CGR3);
 
        clk_enable(&iim_clk);
        imx_print_silicon_rev("i.MX35", mx35_revision());
@@ -533,7 +517,7 @@ int __init mx35_clocks_init()
         * extra clocks turned on, otherwise the MX35 boot ROM code will
         * hang after a watchdog reset.
         */
-       if (!(__raw_readl(CCM_BASE + CCM_RCSR) & (3 << 10))) {
+       if (!(__raw_readl(MX35_CCM_RCSR) & (3 << 10))) {
                /* Additionally turn on UART1, SCC, and IIM clocks */
                clk_enable(&iim_clk);
                clk_enable(&uart1_clk);
index 2d88f8b9a454994bee6841cda4828d81286bac5e..111c328f542004fcec8c6391d8f35fac974f1886 100644 (file)
 #define BM_CLPCR_MASK_SCU_IDLE         (0x1 << 26)
 #define BM_CLPCR_MASK_L2CC_IDLE                (0x1 << 27)
 
+#define BP_CCOSR_CKO1_EN               7
+#define BP_CCOSR_CKO1_PODF             4
+#define BM_CCOSR_CKO1_PODF             (0x7 << 4)
+#define BP_CCOSR_CKO1_SEL              0
+#define BM_CCOSR_CKO1_SEL              (0xf << 0)
+
 #define FREQ_480M      480000000
 #define FREQ_528M      528000000
 #define FREQ_594M      594000000
@@ -393,6 +399,7 @@ static struct clk ipu1_di1_clk;
 static struct clk ipu2_di0_clk;
 static struct clk ipu2_di1_clk;
 static struct clk enfc_clk;
+static struct clk cko1_clk;
 static struct clk dummy_clk = {};
 
 static unsigned long external_high_reference;
@@ -938,6 +945,24 @@ static void _clk_disable(struct clk *clk)
        writel_relaxed(reg, clk->enable_reg);
 }
 
+static int _clk_enable_1b(struct clk *clk)
+{
+       u32 reg;
+       reg = readl_relaxed(clk->enable_reg);
+       reg |= 0x1 << clk->enable_shift;
+       writel_relaxed(reg, clk->enable_reg);
+
+       return 0;
+}
+
+static void _clk_disable_1b(struct clk *clk)
+{
+       u32 reg;
+       reg = readl_relaxed(clk->enable_reg);
+       reg &= ~(0x1 << clk->enable_shift);
+       writel_relaxed(reg, clk->enable_reg);
+}
+
 struct divider {
        struct clk *clk;
        void __iomem *reg;
@@ -983,6 +1008,7 @@ DEF_CLK_DIV1(ipu2_di0_pre_div,     &ipu2_di0_pre_clk,      CSCDR2, IPU2_DI0_PRE);
 DEF_CLK_DIV1(ipu2_di1_pre_div, &ipu2_di1_pre_clk,      CSCDR2, IPU2_DI1_PRE);
 DEF_CLK_DIV1(ipu1_div,         &ipu1_clk,              CSCDR3, IPU1_HSP);
 DEF_CLK_DIV1(ipu2_div,         &ipu2_clk,              CSCDR3, IPU2_HSP);
+DEF_CLK_DIV1(cko1_div,         &cko1_clk,              CCOSR, CKO1);
 
 #define DEF_CLK_DIV2(d, c, r, b)                               \
        static struct divider d = {                             \
@@ -1038,6 +1064,7 @@ static struct divider *dividers[] = {
        &enfc_div,
        &spdif_div,
        &asrc_serial_div,
+       &cko1_div,
 };
 
 static unsigned long ldb_di_clk_get_rate(struct clk *clk)
@@ -1625,6 +1652,32 @@ DEF_IPU_DI_MUX(CSCDR2, 2, 1);
 DEF_IPU_MUX(1);
 DEF_IPU_MUX(2);
 
+static struct multiplexer cko1_mux = {
+       .clk = &cko1_clk,
+       .reg = CCOSR,
+       .bp = BP_CCOSR_CKO1_SEL,
+       .bm = BM_CCOSR_CKO1_SEL,
+       .parents = {
+               &pll3_usb_otg,
+               &pll2_bus,
+               &pll1_sys,
+               &pll5_video,
+               &dummy_clk,
+               &axi_clk,
+               &enfc_clk,
+               &ipu1_di0_clk,
+               &ipu1_di1_clk,
+               &ipu2_di0_clk,
+               &ipu2_di1_clk,
+               &ahb_clk,
+               &ipg_clk,
+               &ipg_perclk,
+               &ckil_clk,
+               &pll4_audio,
+               NULL
+       },
+};
+
 static struct multiplexer *multiplexers[] = {
        &axi_mux,
        &periph_mux,
@@ -1667,6 +1720,7 @@ static struct multiplexer *multiplexers[] = {
        &ipu2_di1_mux,
        &ipu1_mux,
        &ipu2_mux,
+       &cko1_mux,
 };
 
 static int _clk_set_parent(struct clk *clk, struct clk *parent)
@@ -1690,7 +1744,7 @@ static int _clk_set_parent(struct clk *clk, struct clk *parent)
                        break;
                i++;
        }
-       if (!m->parents[i])
+       if (!m->parents[i] || m->parents[i] == &dummy_clk)
                return -EINVAL;
 
        val = readl_relaxed(m->reg);
@@ -1745,6 +1799,20 @@ DEF_NG_CLK(asrc_serial_clk,      &pll3_usb_otg);
                .secondary      = s,                    \
        }
 
+#define DEF_CLK_1B(name, er, es, p, s)                 \
+       static struct clk name = {                      \
+               .enable_reg     = er,                   \
+               .enable_shift   = es,                   \
+               .enable         = _clk_enable_1b,       \
+               .disable        = _clk_disable_1b,      \
+               .get_rate       = _clk_get_rate,        \
+               .set_rate       = _clk_set_rate,        \
+               .round_rate     = _clk_round_rate,      \
+               .set_parent     = _clk_set_parent,      \
+               .parent         = p,                    \
+               .secondary      = s,                    \
+       }
+
 DEF_CLK(aips_tz1_clk,    CCGR0, CG0,  &ahb_clk,          NULL);
 DEF_CLK(aips_tz2_clk,    CCGR0, CG1,  &ahb_clk,          NULL);
 DEF_CLK(apbh_dma_clk,    CCGR0, CG2,  &ahb_clk,          NULL);
@@ -1811,6 +1879,7 @@ DEF_CLK(usdhc4_clk,         CCGR6, CG4,  &pll2_pfd_400m,    NULL);
 DEF_CLK(emi_slow_clk,    CCGR6, CG5,  &axi_clk,          NULL);
 DEF_CLK(vdo_axi_clk,     CCGR6, CG6,  &axi_clk,          NULL);
 DEF_CLK(vpu_clk,         CCGR6, CG7,  &axi_clk,          NULL);
+DEF_CLK_1B(cko1_clk,     CCOSR, BP_CCOSR_CKO1_EN, &pll2_bus, NULL);
 
 static int pcie_clk_enable(struct clk *clk)
 {
@@ -1922,6 +1991,7 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK(NULL, "gpmi_io_clk", gpmi_io_clk),
        _REGISTER_CLOCK(NULL, "usboh3_clk", usboh3_clk),
        _REGISTER_CLOCK(NULL, "sata_clk", sata_clk),
+       _REGISTER_CLOCK(NULL, "cko1_clk", cko1_clk),
 };
 
 int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
@@ -2029,6 +2099,8 @@ int __init mx6q_clocks_init(void)
        clk_set_rate(&usdhc3_clk, 49500000);
        clk_set_rate(&usdhc4_clk, 49500000);
 
+       clk_set_parent(&cko1_clk, &ahb_clk);
+
        np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt");
        base = of_iomap(np, 0);
        WARN_ON(!base);
index 5e2e7a8438606f43015d90115046e555eee1a3c5..aa15c517d06e9338293b2669b78b8f486ffba232 100644 (file)
@@ -149,39 +149,3 @@ int mx50_revision(void)
        return mx5_cpu_rev;
 }
 EXPORT_SYMBOL(mx50_revision);
-
-static int __init post_cpu_init(void)
-{
-       unsigned int reg;
-       void __iomem *base;
-
-       if (cpu_is_mx51() || cpu_is_mx53()) {
-               if (cpu_is_mx51())
-                       base = MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR);
-               else
-                       base = MX53_IO_ADDRESS(MX53_AIPS1_BASE_ADDR);
-
-               __raw_writel(0x0, base + 0x40);
-               __raw_writel(0x0, base + 0x44);
-               __raw_writel(0x0, base + 0x48);
-               __raw_writel(0x0, base + 0x4C);
-               reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
-               __raw_writel(reg, base + 0x50);
-
-               if (cpu_is_mx51())
-                       base = MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR);
-               else
-                       base = MX53_IO_ADDRESS(MX53_AIPS2_BASE_ADDR);
-
-               __raw_writel(0x0, base + 0x40);
-               __raw_writel(0x0, base + 0x44);
-               __raw_writel(0x0, base + 0x48);
-               __raw_writel(0x0, base + 0x4C);
-               reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
-               __raw_writel(reg, base + 0x50);
-       }
-
-       return 0;
-}
-
-postcore_initcall(post_cpu_init);
diff --git a/arch/arm/mach-imx/crmregs-imx3.h b/arch/arm/mach-imx/crmregs-imx3.h
new file mode 100644 (file)
index 0000000..5314127
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ARCH_ARM_MACH_MX3_CRM_REGS_H__
+#define __ARCH_ARM_MACH_MX3_CRM_REGS_H__
+
+#define CKIH_CLK_FREQ           26000000
+#define CKIH_CLK_FREQ_27MHZ     27000000
+#define CKIL_CLK_FREQ           32768
+
+#define MXC_CCM_BASE           (cpu_is_mx31() ? \
+MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR) : MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR))
+
+/* Register addresses */
+#define MXC_CCM_CCMR           (MXC_CCM_BASE + 0x00)
+#define MXC_CCM_PDR0           (MXC_CCM_BASE + 0x04)
+#define MXC_CCM_PDR1           (MXC_CCM_BASE + 0x08)
+#define MX35_CCM_PDR2          (MXC_CCM_BASE + 0x0C)
+#define MXC_CCM_RCSR           (MXC_CCM_BASE + 0x0C)
+#define MX35_CCM_PDR3          (MXC_CCM_BASE + 0x10)
+#define MXC_CCM_MPCTL          (MXC_CCM_BASE + 0x10)
+#define MX35_CCM_PDR4          (MXC_CCM_BASE + 0x14)
+#define MXC_CCM_UPCTL          (MXC_CCM_BASE + 0x14)
+#define MX35_CCM_RCSR          (MXC_CCM_BASE + 0x18)
+#define MXC_CCM_SRPCTL         (MXC_CCM_BASE + 0x18)
+#define MX35_CCM_MPCTL         (MXC_CCM_BASE + 0x1C)
+#define MXC_CCM_COSR           (MXC_CCM_BASE + 0x1C)
+#define MX35_CCM_PPCTL         (MXC_CCM_BASE + 0x20)
+#define MXC_CCM_CGR0           (MXC_CCM_BASE + 0x20)
+#define MX35_CCM_ACMR          (MXC_CCM_BASE + 0x24)
+#define MXC_CCM_CGR1           (MXC_CCM_BASE + 0x24)
+#define MX35_CCM_COSR          (MXC_CCM_BASE + 0x28)
+#define MXC_CCM_CGR2           (MXC_CCM_BASE + 0x28)
+#define MX35_CCM_CGR0          (MXC_CCM_BASE + 0x2C)
+#define MXC_CCM_WIMR           (MXC_CCM_BASE + 0x2C)
+#define MX35_CCM_CGR1          (MXC_CCM_BASE + 0x30)
+#define MXC_CCM_LDC            (MXC_CCM_BASE + 0x30)
+#define MX35_CCM_CGR2          (MXC_CCM_BASE + 0x34)
+#define MXC_CCM_DCVR0          (MXC_CCM_BASE + 0x34)
+#define MX35_CCM_CGR3          (MXC_CCM_BASE + 0x38)
+#define MXC_CCM_DCVR1          (MXC_CCM_BASE + 0x38)
+#define MXC_CCM_DCVR2          (MXC_CCM_BASE + 0x3C)
+#define MXC_CCM_DCVR3          (MXC_CCM_BASE + 0x40)
+#define MXC_CCM_LTR0           (MXC_CCM_BASE + 0x44)
+#define MXC_CCM_LTR1           (MXC_CCM_BASE + 0x48)
+#define MXC_CCM_LTR2           (MXC_CCM_BASE + 0x4C)
+#define MXC_CCM_LTR3           (MXC_CCM_BASE + 0x50)
+#define MXC_CCM_LTBR0          (MXC_CCM_BASE + 0x54)
+#define MXC_CCM_LTBR1          (MXC_CCM_BASE + 0x58)
+#define MXC_CCM_PMCR0          (MXC_CCM_BASE + 0x5C)
+#define MXC_CCM_PMCR1          (MXC_CCM_BASE + 0x60)
+#define MXC_CCM_PDR2           (MXC_CCM_BASE + 0x64)
+
+/* Register bit definitions */
+#define MXC_CCM_CCMR_WBEN                       (1 << 27)
+#define MXC_CCM_CCMR_CSCS                       (1 << 25)
+#define MXC_CCM_CCMR_PERCS                      (1 << 24)
+#define MXC_CCM_CCMR_SSI1S_OFFSET               18
+#define MXC_CCM_CCMR_SSI1S_MASK                 (0x3 << 18)
+#define MXC_CCM_CCMR_SSI2S_OFFSET               21
+#define MXC_CCM_CCMR_SSI2S_MASK                 (0x3 << 21)
+#define MXC_CCM_CCMR_LPM_OFFSET                 14
+#define MXC_CCM_CCMR_LPM_MASK                   (0x3 << 14)
+#define MXC_CCM_CCMR_LPM_WAIT_MX35             (0x1 << 14)
+#define MXC_CCM_CCMR_FIRS_OFFSET                11
+#define MXC_CCM_CCMR_FIRS_MASK                  (0x3 << 11)
+#define MXC_CCM_CCMR_UPE                        (1 << 9)
+#define MXC_CCM_CCMR_SPE                        (1 << 8)
+#define MXC_CCM_CCMR_MDS                        (1 << 7)
+#define MXC_CCM_CCMR_SBYCS                      (1 << 4)
+#define MXC_CCM_CCMR_MPE                        (1 << 3)
+#define MXC_CCM_CCMR_PRCS_OFFSET                1
+#define MXC_CCM_CCMR_PRCS_MASK                  (0x3 << 1)
+
+#define MXC_CCM_PDR0_CSI_PODF_OFFSET            26
+#define MXC_CCM_PDR0_CSI_PODF_MASK              (0x3F << 26)
+#define MXC_CCM_PDR0_CSI_PRDF_OFFSET            23
+#define MXC_CCM_PDR0_CSI_PRDF_MASK              (0x7 << 23)
+#define MXC_CCM_PDR0_PER_PODF_OFFSET            16
+#define MXC_CCM_PDR0_PER_PODF_MASK              (0x1F << 16)
+#define MXC_CCM_PDR0_HSP_PODF_OFFSET            11
+#define MXC_CCM_PDR0_HSP_PODF_MASK              (0x7 << 11)
+#define MXC_CCM_PDR0_NFC_PODF_OFFSET            8
+#define MXC_CCM_PDR0_NFC_PODF_MASK              (0x7 << 8)
+#define MXC_CCM_PDR0_IPG_PODF_OFFSET            6
+#define MXC_CCM_PDR0_IPG_PODF_MASK              (0x3 << 6)
+#define MXC_CCM_PDR0_MAX_PODF_OFFSET            3
+#define MXC_CCM_PDR0_MAX_PODF_MASK              (0x7 << 3)
+#define MXC_CCM_PDR0_MCU_PODF_OFFSET            0
+#define MXC_CCM_PDR0_MCU_PODF_MASK              0x7
+
+#define MXC_CCM_PDR1_USB_PRDF_OFFSET            30
+#define MXC_CCM_PDR1_USB_PRDF_MASK              (0x3 << 30)
+#define MXC_CCM_PDR1_USB_PODF_OFFSET            27
+#define MXC_CCM_PDR1_USB_PODF_MASK              (0x7 << 27)
+#define MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET       24
+#define MXC_CCM_PDR1_FIRI_PRE_PODF_MASK         (0x7 << 24)
+#define MXC_CCM_PDR1_FIRI_PODF_OFFSET           18
+#define MXC_CCM_PDR1_FIRI_PODF_MASK             (0x3F << 18)
+#define MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET       15
+#define MXC_CCM_PDR1_SSI2_PRE_PODF_MASK         (0x7 << 15)
+#define MXC_CCM_PDR1_SSI2_PODF_OFFSET           9
+#define MXC_CCM_PDR1_SSI2_PODF_MASK             (0x3F << 9)
+#define MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET       6
+#define MXC_CCM_PDR1_SSI1_PRE_PODF_MASK         (0x7 << 6)
+#define MXC_CCM_PDR1_SSI1_PODF_OFFSET           0
+#define MXC_CCM_PDR1_SSI1_PODF_MASK             0x3F
+
+/* Bit definitions for RCSR */
+#define MXC_CCM_RCSR_NF16B                     0x80000000
+
+/*
+ * LTR0 register offsets
+ */
+#define MXC_CCM_LTR0_DIV3CK_OFFSET              1
+#define MXC_CCM_LTR0_DIV3CK_MASK                (0x3 << 1)
+#define MXC_CCM_LTR0_DNTHR_OFFSET               16
+#define MXC_CCM_LTR0_DNTHR_MASK                 (0x3F << 16)
+#define MXC_CCM_LTR0_UPTHR_OFFSET               22
+#define MXC_CCM_LTR0_UPTHR_MASK                 (0x3F << 22)
+
+/*
+ * LTR1 register offsets
+ */
+#define MXC_CCM_LTR1_PNCTHR_OFFSET              0
+#define MXC_CCM_LTR1_PNCTHR_MASK                0x3F
+#define MXC_CCM_LTR1_UPCNT_OFFSET               6
+#define MXC_CCM_LTR1_UPCNT_MASK                 (0xFF << 6)
+#define MXC_CCM_LTR1_DNCNT_OFFSET               14
+#define MXC_CCM_LTR1_DNCNT_MASK                 (0xFF << 14)
+#define MXC_CCM_LTR1_LTBRSR_MASK                0x400000
+#define MXC_CCM_LTR1_LTBRSR_OFFSET              22
+#define MXC_CCM_LTR1_LTBRSR                     0x400000
+#define MXC_CCM_LTR1_LTBRSH                     0x800000
+
+/*
+ * LTR2 bit definitions. x ranges from 0 for WSW9 to 6 for WSW15
+ */
+#define MXC_CCM_LTR2_WSW_OFFSET(x)              (11 + (x) * 3)
+#define MXC_CCM_LTR2_WSW_MASK(x)                (0x7 << \
+                                       MXC_CCM_LTR2_WSW_OFFSET((x)))
+#define MXC_CCM_LTR2_EMAC_OFFSET                0
+#define MXC_CCM_LTR2_EMAC_MASK                  0x1FF
+
+/*
+ * LTR3 bit definitions. x ranges from 0 for WSW0 to 8 for WSW8
+ */
+#define MXC_CCM_LTR3_WSW_OFFSET(x)              (5 + (x) * 3)
+#define MXC_CCM_LTR3_WSW_MASK(x)                (0x7 << \
+                                       MXC_CCM_LTR3_WSW_OFFSET((x)))
+
+#define MXC_CCM_PMCR0_DFSUP1                    0x80000000
+#define MXC_CCM_PMCR0_DFSUP1_SPLL               (0 << 31)
+#define MXC_CCM_PMCR0_DFSUP1_MPLL               (1 << 31)
+#define MXC_CCM_PMCR0_DFSUP0                    0x40000000
+#define MXC_CCM_PMCR0_DFSUP0_PLL                (0 << 30)
+#define MXC_CCM_PMCR0_DFSUP0_PDR                (1 << 30)
+#define MXC_CCM_PMCR0_DFSUP_MASK                (0x3 << 30)
+
+#define DVSUP_TURBO                            0
+#define DVSUP_HIGH                             1
+#define DVSUP_MEDIUM                           2
+#define DVSUP_LOW                              3
+#define MXC_CCM_PMCR0_DVSUP_TURBO               (DVSUP_TURBO << 28)
+#define MXC_CCM_PMCR0_DVSUP_HIGH                (DVSUP_HIGH << 28)
+#define MXC_CCM_PMCR0_DVSUP_MEDIUM              (DVSUP_MEDIUM << 28)
+#define MXC_CCM_PMCR0_DVSUP_LOW                 (DVSUP_LOW << 28)
+#define MXC_CCM_PMCR0_DVSUP_OFFSET              28
+#define MXC_CCM_PMCR0_DVSUP_MASK                (0x3 << 28)
+#define MXC_CCM_PMCR0_UDSC                      0x08000000
+#define MXC_CCM_PMCR0_UDSC_MASK                 (1 << 27)
+#define MXC_CCM_PMCR0_UDSC_UP                   (1 << 27)
+#define MXC_CCM_PMCR0_UDSC_DOWN                 (0 << 27)
+
+#define MXC_CCM_PMCR0_VSCNT_1                   (0x0 << 24)
+#define MXC_CCM_PMCR0_VSCNT_2                   (0x1 << 24)
+#define MXC_CCM_PMCR0_VSCNT_3                   (0x2 << 24)
+#define MXC_CCM_PMCR0_VSCNT_4                   (0x3 << 24)
+#define MXC_CCM_PMCR0_VSCNT_5                   (0x4 << 24)
+#define MXC_CCM_PMCR0_VSCNT_6                   (0x5 << 24)
+#define MXC_CCM_PMCR0_VSCNT_7                   (0x6 << 24)
+#define MXC_CCM_PMCR0_VSCNT_8                   (0x7 << 24)
+#define MXC_CCM_PMCR0_VSCNT_OFFSET              24
+#define MXC_CCM_PMCR0_VSCNT_MASK                (0x7 << 24)
+#define MXC_CCM_PMCR0_DVFEV                     0x00800000
+#define MXC_CCM_PMCR0_DVFIS                     0x00400000
+#define MXC_CCM_PMCR0_LBMI                      0x00200000
+#define MXC_CCM_PMCR0_LBFL                      0x00100000
+#define MXC_CCM_PMCR0_LBCF_4                    (0x0 << 18)
+#define MXC_CCM_PMCR0_LBCF_8                    (0x1 << 18)
+#define MXC_CCM_PMCR0_LBCF_12                   (0x2 << 18)
+#define MXC_CCM_PMCR0_LBCF_16                   (0x3 << 18)
+#define MXC_CCM_PMCR0_LBCF_OFFSET               18
+#define MXC_CCM_PMCR0_LBCF_MASK                 (0x3 << 18)
+#define MXC_CCM_PMCR0_PTVIS                     0x00020000
+#define MXC_CCM_PMCR0_UPDTEN                    0x00010000
+#define MXC_CCM_PMCR0_UPDTEN_MASK               (0x1 << 16)
+#define MXC_CCM_PMCR0_FSVAIM                    0x00008000
+#define MXC_CCM_PMCR0_FSVAI_OFFSET              13
+#define MXC_CCM_PMCR0_FSVAI_MASK                (0x3 << 13)
+#define MXC_CCM_PMCR0_DPVCR                     0x00001000
+#define MXC_CCM_PMCR0_DPVV                      0x00000800
+#define MXC_CCM_PMCR0_WFIM                      0x00000400
+#define MXC_CCM_PMCR0_DRCE3                     0x00000200
+#define MXC_CCM_PMCR0_DRCE2                     0x00000100
+#define MXC_CCM_PMCR0_DRCE1                     0x00000080
+#define MXC_CCM_PMCR0_DRCE0                     0x00000040
+#define MXC_CCM_PMCR0_DCR                       0x00000020
+#define MXC_CCM_PMCR0_DVFEN                     0x00000010
+#define MXC_CCM_PMCR0_PTVAIM                    0x00000008
+#define MXC_CCM_PMCR0_PTVAI_OFFSET              1
+#define MXC_CCM_PMCR0_PTVAI_MASK                (0x3 << 1)
+#define MXC_CCM_PMCR0_DPTEN                     0x00000001
+
+#define MXC_CCM_PMCR1_DVGP_OFFSET               0
+#define MXC_CCM_PMCR1_DVGP_MASK                 (0xF)
+
+#define MXC_CCM_PMCR1_PLLRDIS                      (0x1 << 7)
+#define MXC_CCM_PMCR1_EMIRQ_EN                      (0x1 << 8)
+
+#define MXC_CCM_DCVR_ULV_MASK                   (0x3FF << 22)
+#define MXC_CCM_DCVR_ULV_OFFSET                 22
+#define MXC_CCM_DCVR_LLV_MASK                   (0x3FF << 12)
+#define MXC_CCM_DCVR_LLV_OFFSET                 12
+#define MXC_CCM_DCVR_ELV_MASK                   (0x3FF << 2)
+#define MXC_CCM_DCVR_ELV_OFFSET                 2
+
+#define MXC_CCM_PDR2_MST2_PDF_MASK              (0x3F << 7)
+#define MXC_CCM_PDR2_MST2_PDF_OFFSET            7
+#define MXC_CCM_PDR2_MST1_PDF_MASK              0x3F
+#define MXC_CCM_PDR2_MST1_PDF_OFFSET            0
+
+#define MXC_CCM_COSR_CLKOSEL_MASK               0x0F
+#define MXC_CCM_COSR_CLKOSEL_OFFSET             0
+#define MXC_CCM_COSR_CLKOUTDIV_MASK             (0x07 << 6)
+#define MXC_CCM_COSR_CLKOUTDIV_OFFSET           6
+#define MXC_CCM_COSR_CLKOEN                     (1 << 9)
+
+/*
+ * PMCR0 register offsets
+ */
+#define MXC_CCM_PMCR0_LBFL_OFFSET   20
+#define MXC_CCM_PMCR0_DFSUP0_OFFSET 30
+#define MXC_CCM_PMCR0_DFSUP1_OFFSET 31
+
+#endif                         /* __ARCH_ARM_MACH_MX3_CRM_REGS_H__ */
diff --git a/arch/arm/mach-imx/crmregs-imx31.h b/arch/arm/mach-imx/crmregs-imx31.h
deleted file mode 100644 (file)
index 37a8a07..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#ifndef __ARCH_ARM_MACH_MX3_CRM_REGS_H__
-#define __ARCH_ARM_MACH_MX3_CRM_REGS_H__
-
-#define CKIH_CLK_FREQ           26000000
-#define CKIH_CLK_FREQ_27MHZ     27000000
-#define CKIL_CLK_FREQ           32768
-
-#define MXC_CCM_BASE           MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR)
-
-/* Register addresses */
-#define MXC_CCM_CCMR           (MXC_CCM_BASE + 0x00)
-#define MXC_CCM_PDR0           (MXC_CCM_BASE + 0x04)
-#define MXC_CCM_PDR1           (MXC_CCM_BASE + 0x08)
-#define MXC_CCM_RCSR           (MXC_CCM_BASE + 0x0C)
-#define MXC_CCM_MPCTL          (MXC_CCM_BASE + 0x10)
-#define MXC_CCM_UPCTL          (MXC_CCM_BASE + 0x14)
-#define MXC_CCM_SRPCTL         (MXC_CCM_BASE + 0x18)
-#define MXC_CCM_COSR           (MXC_CCM_BASE + 0x1C)
-#define MXC_CCM_CGR0           (MXC_CCM_BASE + 0x20)
-#define MXC_CCM_CGR1           (MXC_CCM_BASE + 0x24)
-#define MXC_CCM_CGR2           (MXC_CCM_BASE + 0x28)
-#define MXC_CCM_WIMR           (MXC_CCM_BASE + 0x2C)
-#define MXC_CCM_LDC            (MXC_CCM_BASE + 0x30)
-#define MXC_CCM_DCVR0          (MXC_CCM_BASE + 0x34)
-#define MXC_CCM_DCVR1          (MXC_CCM_BASE + 0x38)
-#define MXC_CCM_DCVR2          (MXC_CCM_BASE + 0x3C)
-#define MXC_CCM_DCVR3          (MXC_CCM_BASE + 0x40)
-#define MXC_CCM_LTR0           (MXC_CCM_BASE + 0x44)
-#define MXC_CCM_LTR1           (MXC_CCM_BASE + 0x48)
-#define MXC_CCM_LTR2           (MXC_CCM_BASE + 0x4C)
-#define MXC_CCM_LTR3           (MXC_CCM_BASE + 0x50)
-#define MXC_CCM_LTBR0          (MXC_CCM_BASE + 0x54)
-#define MXC_CCM_LTBR1          (MXC_CCM_BASE + 0x58)
-#define MXC_CCM_PMCR0          (MXC_CCM_BASE + 0x5C)
-#define MXC_CCM_PMCR1          (MXC_CCM_BASE + 0x60)
-#define MXC_CCM_PDR2           (MXC_CCM_BASE + 0x64)
-
-/* Register bit definitions */
-#define MXC_CCM_CCMR_WBEN                       (1 << 27)
-#define MXC_CCM_CCMR_CSCS                       (1 << 25)
-#define MXC_CCM_CCMR_PERCS                      (1 << 24)
-#define MXC_CCM_CCMR_SSI1S_OFFSET               18
-#define MXC_CCM_CCMR_SSI1S_MASK                 (0x3 << 18)
-#define MXC_CCM_CCMR_SSI2S_OFFSET               21
-#define MXC_CCM_CCMR_SSI2S_MASK                 (0x3 << 21)
-#define MXC_CCM_CCMR_LPM_OFFSET                 14
-#define MXC_CCM_CCMR_LPM_MASK                   (0x3 << 14)
-#define MXC_CCM_CCMR_FIRS_OFFSET                11
-#define MXC_CCM_CCMR_FIRS_MASK                  (0x3 << 11)
-#define MXC_CCM_CCMR_UPE                        (1 << 9)
-#define MXC_CCM_CCMR_SPE                        (1 << 8)
-#define MXC_CCM_CCMR_MDS                        (1 << 7)
-#define MXC_CCM_CCMR_SBYCS                      (1 << 4)
-#define MXC_CCM_CCMR_MPE                        (1 << 3)
-#define MXC_CCM_CCMR_PRCS_OFFSET                1
-#define MXC_CCM_CCMR_PRCS_MASK                  (0x3 << 1)
-
-#define MXC_CCM_PDR0_CSI_PODF_OFFSET            26
-#define MXC_CCM_PDR0_CSI_PODF_MASK              (0x3F << 26)
-#define MXC_CCM_PDR0_CSI_PRDF_OFFSET            23
-#define MXC_CCM_PDR0_CSI_PRDF_MASK              (0x7 << 23)
-#define MXC_CCM_PDR0_PER_PODF_OFFSET            16
-#define MXC_CCM_PDR0_PER_PODF_MASK              (0x1F << 16)
-#define MXC_CCM_PDR0_HSP_PODF_OFFSET            11
-#define MXC_CCM_PDR0_HSP_PODF_MASK              (0x7 << 11)
-#define MXC_CCM_PDR0_NFC_PODF_OFFSET            8
-#define MXC_CCM_PDR0_NFC_PODF_MASK              (0x7 << 8)
-#define MXC_CCM_PDR0_IPG_PODF_OFFSET            6
-#define MXC_CCM_PDR0_IPG_PODF_MASK              (0x3 << 6)
-#define MXC_CCM_PDR0_MAX_PODF_OFFSET            3
-#define MXC_CCM_PDR0_MAX_PODF_MASK              (0x7 << 3)
-#define MXC_CCM_PDR0_MCU_PODF_OFFSET            0
-#define MXC_CCM_PDR0_MCU_PODF_MASK              0x7
-
-#define MXC_CCM_PDR1_USB_PRDF_OFFSET            30
-#define MXC_CCM_PDR1_USB_PRDF_MASK              (0x3 << 30)
-#define MXC_CCM_PDR1_USB_PODF_OFFSET            27
-#define MXC_CCM_PDR1_USB_PODF_MASK              (0x7 << 27)
-#define MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET       24
-#define MXC_CCM_PDR1_FIRI_PRE_PODF_MASK         (0x7 << 24)
-#define MXC_CCM_PDR1_FIRI_PODF_OFFSET           18
-#define MXC_CCM_PDR1_FIRI_PODF_MASK             (0x3F << 18)
-#define MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET       15
-#define MXC_CCM_PDR1_SSI2_PRE_PODF_MASK         (0x7 << 15)
-#define MXC_CCM_PDR1_SSI2_PODF_OFFSET           9
-#define MXC_CCM_PDR1_SSI2_PODF_MASK             (0x3F << 9)
-#define MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET       6
-#define MXC_CCM_PDR1_SSI1_PRE_PODF_MASK         (0x7 << 6)
-#define MXC_CCM_PDR1_SSI1_PODF_OFFSET           0
-#define MXC_CCM_PDR1_SSI1_PODF_MASK             0x3F
-
-/* Bit definitions for RCSR */
-#define MXC_CCM_RCSR_NF16B                     0x80000000
-
-/*
- * LTR0 register offsets
- */
-#define MXC_CCM_LTR0_DIV3CK_OFFSET              1
-#define MXC_CCM_LTR0_DIV3CK_MASK                (0x3 << 1)
-#define MXC_CCM_LTR0_DNTHR_OFFSET               16
-#define MXC_CCM_LTR0_DNTHR_MASK                 (0x3F << 16)
-#define MXC_CCM_LTR0_UPTHR_OFFSET               22
-#define MXC_CCM_LTR0_UPTHR_MASK                 (0x3F << 22)
-
-/*
- * LTR1 register offsets
- */
-#define MXC_CCM_LTR1_PNCTHR_OFFSET              0
-#define MXC_CCM_LTR1_PNCTHR_MASK                0x3F
-#define MXC_CCM_LTR1_UPCNT_OFFSET               6
-#define MXC_CCM_LTR1_UPCNT_MASK                 (0xFF << 6)
-#define MXC_CCM_LTR1_DNCNT_OFFSET               14
-#define MXC_CCM_LTR1_DNCNT_MASK                 (0xFF << 14)
-#define MXC_CCM_LTR1_LTBRSR_MASK                0x400000
-#define MXC_CCM_LTR1_LTBRSR_OFFSET              22
-#define MXC_CCM_LTR1_LTBRSR                     0x400000
-#define MXC_CCM_LTR1_LTBRSH                     0x800000
-
-/*
- * LTR2 bit definitions. x ranges from 0 for WSW9 to 6 for WSW15
- */
-#define MXC_CCM_LTR2_WSW_OFFSET(x)              (11 + (x) * 3)
-#define MXC_CCM_LTR2_WSW_MASK(x)                (0x7 << \
-                                       MXC_CCM_LTR2_WSW_OFFSET((x)))
-#define MXC_CCM_LTR2_EMAC_OFFSET                0
-#define MXC_CCM_LTR2_EMAC_MASK                  0x1FF
-
-/*
- * LTR3 bit definitions. x ranges from 0 for WSW0 to 8 for WSW8
- */
-#define MXC_CCM_LTR3_WSW_OFFSET(x)              (5 + (x) * 3)
-#define MXC_CCM_LTR3_WSW_MASK(x)                (0x7 << \
-                                       MXC_CCM_LTR3_WSW_OFFSET((x)))
-
-#define MXC_CCM_PMCR0_DFSUP1                    0x80000000
-#define MXC_CCM_PMCR0_DFSUP1_SPLL               (0 << 31)
-#define MXC_CCM_PMCR0_DFSUP1_MPLL               (1 << 31)
-#define MXC_CCM_PMCR0_DFSUP0                    0x40000000
-#define MXC_CCM_PMCR0_DFSUP0_PLL                (0 << 30)
-#define MXC_CCM_PMCR0_DFSUP0_PDR                (1 << 30)
-#define MXC_CCM_PMCR0_DFSUP_MASK                (0x3 << 30)
-
-#define DVSUP_TURBO                            0
-#define DVSUP_HIGH                             1
-#define DVSUP_MEDIUM                           2
-#define DVSUP_LOW                              3
-#define MXC_CCM_PMCR0_DVSUP_TURBO               (DVSUP_TURBO << 28)
-#define MXC_CCM_PMCR0_DVSUP_HIGH                (DVSUP_HIGH << 28)
-#define MXC_CCM_PMCR0_DVSUP_MEDIUM              (DVSUP_MEDIUM << 28)
-#define MXC_CCM_PMCR0_DVSUP_LOW                 (DVSUP_LOW << 28)
-#define MXC_CCM_PMCR0_DVSUP_OFFSET              28
-#define MXC_CCM_PMCR0_DVSUP_MASK                (0x3 << 28)
-#define MXC_CCM_PMCR0_UDSC                      0x08000000
-#define MXC_CCM_PMCR0_UDSC_MASK                 (1 << 27)
-#define MXC_CCM_PMCR0_UDSC_UP                   (1 << 27)
-#define MXC_CCM_PMCR0_UDSC_DOWN                 (0 << 27)
-
-#define MXC_CCM_PMCR0_VSCNT_1                   (0x0 << 24)
-#define MXC_CCM_PMCR0_VSCNT_2                   (0x1 << 24)
-#define MXC_CCM_PMCR0_VSCNT_3                   (0x2 << 24)
-#define MXC_CCM_PMCR0_VSCNT_4                   (0x3 << 24)
-#define MXC_CCM_PMCR0_VSCNT_5                   (0x4 << 24)
-#define MXC_CCM_PMCR0_VSCNT_6                   (0x5 << 24)
-#define MXC_CCM_PMCR0_VSCNT_7                   (0x6 << 24)
-#define MXC_CCM_PMCR0_VSCNT_8                   (0x7 << 24)
-#define MXC_CCM_PMCR0_VSCNT_OFFSET              24
-#define MXC_CCM_PMCR0_VSCNT_MASK                (0x7 << 24)
-#define MXC_CCM_PMCR0_DVFEV                     0x00800000
-#define MXC_CCM_PMCR0_DVFIS                     0x00400000
-#define MXC_CCM_PMCR0_LBMI                      0x00200000
-#define MXC_CCM_PMCR0_LBFL                      0x00100000
-#define MXC_CCM_PMCR0_LBCF_4                    (0x0 << 18)
-#define MXC_CCM_PMCR0_LBCF_8                    (0x1 << 18)
-#define MXC_CCM_PMCR0_LBCF_12                   (0x2 << 18)
-#define MXC_CCM_PMCR0_LBCF_16                   (0x3 << 18)
-#define MXC_CCM_PMCR0_LBCF_OFFSET               18
-#define MXC_CCM_PMCR0_LBCF_MASK                 (0x3 << 18)
-#define MXC_CCM_PMCR0_PTVIS                     0x00020000
-#define MXC_CCM_PMCR0_UPDTEN                    0x00010000
-#define MXC_CCM_PMCR0_UPDTEN_MASK               (0x1 << 16)
-#define MXC_CCM_PMCR0_FSVAIM                    0x00008000
-#define MXC_CCM_PMCR0_FSVAI_OFFSET              13
-#define MXC_CCM_PMCR0_FSVAI_MASK                (0x3 << 13)
-#define MXC_CCM_PMCR0_DPVCR                     0x00001000
-#define MXC_CCM_PMCR0_DPVV                      0x00000800
-#define MXC_CCM_PMCR0_WFIM                      0x00000400
-#define MXC_CCM_PMCR0_DRCE3                     0x00000200
-#define MXC_CCM_PMCR0_DRCE2                     0x00000100
-#define MXC_CCM_PMCR0_DRCE1                     0x00000080
-#define MXC_CCM_PMCR0_DRCE0                     0x00000040
-#define MXC_CCM_PMCR0_DCR                       0x00000020
-#define MXC_CCM_PMCR0_DVFEN                     0x00000010
-#define MXC_CCM_PMCR0_PTVAIM                    0x00000008
-#define MXC_CCM_PMCR0_PTVAI_OFFSET              1
-#define MXC_CCM_PMCR0_PTVAI_MASK                (0x3 << 1)
-#define MXC_CCM_PMCR0_DPTEN                     0x00000001
-
-#define MXC_CCM_PMCR1_DVGP_OFFSET               0
-#define MXC_CCM_PMCR1_DVGP_MASK                 (0xF)
-
-#define MXC_CCM_PMCR1_PLLRDIS                      (0x1 << 7)
-#define MXC_CCM_PMCR1_EMIRQ_EN                      (0x1 << 8)
-
-#define MXC_CCM_DCVR_ULV_MASK                   (0x3FF << 22)
-#define MXC_CCM_DCVR_ULV_OFFSET                 22
-#define MXC_CCM_DCVR_LLV_MASK                   (0x3FF << 12)
-#define MXC_CCM_DCVR_LLV_OFFSET                 12
-#define MXC_CCM_DCVR_ELV_MASK                   (0x3FF << 2)
-#define MXC_CCM_DCVR_ELV_OFFSET                 2
-
-#define MXC_CCM_PDR2_MST2_PDF_MASK              (0x3F << 7)
-#define MXC_CCM_PDR2_MST2_PDF_OFFSET            7
-#define MXC_CCM_PDR2_MST1_PDF_MASK              0x3F
-#define MXC_CCM_PDR2_MST1_PDF_OFFSET            0
-
-#define MXC_CCM_COSR_CLKOSEL_MASK               0x0F
-#define MXC_CCM_COSR_CLKOSEL_OFFSET             0
-#define MXC_CCM_COSR_CLKOUTDIV_MASK             (0x07 << 6)
-#define MXC_CCM_COSR_CLKOUTDIV_OFFSET           6
-#define MXC_CCM_COSR_CLKOEN                     (1 << 9)
-
-/*
- * PMCR0 register offsets
- */
-#define MXC_CCM_PMCR0_LBFL_OFFSET   20
-#define MXC_CCM_PMCR0_DFSUP0_OFFSET 30
-#define MXC_CCM_PMCR0_DFSUP1_OFFSET 31
-
-#endif                         /* __ARCH_ARM_MACH_MX3_CRM_REGS_H__ */
diff --git a/arch/arm/mach-imx/imx27-dt.c b/arch/arm/mach-imx/imx27-dt.c
new file mode 100644 (file)
index 0000000..861ceb8
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2012 Sascha Hauer, Pengutronix
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+#include <mach/mx27.h>
+
+static const struct of_dev_auxdata imx27_auxdata_lookup[] __initconst = {
+       OF_DEV_AUXDATA("fsl,imx27-uart", MX27_UART1_BASE_ADDR, "imx21-uart.0", NULL),
+       OF_DEV_AUXDATA("fsl,imx27-uart", MX27_UART2_BASE_ADDR, "imx21-uart.1", NULL),
+       OF_DEV_AUXDATA("fsl,imx27-uart", MX27_UART3_BASE_ADDR, "imx21-uart.2", NULL),
+       OF_DEV_AUXDATA("fsl,imx27-fec", MX27_FEC_BASE_ADDR, "imx27-fec.0", NULL),
+       OF_DEV_AUXDATA("fsl,imx27-i2c", MX27_I2C1_BASE_ADDR, "imx-i2c.0", NULL),
+       OF_DEV_AUXDATA("fsl,imx27-i2c", MX27_I2C2_BASE_ADDR, "imx-i2c.1", NULL),
+       OF_DEV_AUXDATA("fsl,imx27-cspi", MX27_CSPI1_BASE_ADDR, "imx27-cspi.0", NULL),
+       OF_DEV_AUXDATA("fsl,imx27-cspi", MX27_CSPI2_BASE_ADDR, "imx27-cspi.1", NULL),
+       OF_DEV_AUXDATA("fsl,imx27-cspi", MX27_CSPI3_BASE_ADDR, "imx27-cspi.2", NULL),
+       OF_DEV_AUXDATA("fsl,imx27-wdt", MX27_WDOG_BASE_ADDR, "imx2-wdt.0", NULL),
+       { /* sentinel */ }
+};
+
+static int __init imx27_avic_add_irq_domain(struct device_node *np,
+                               struct device_node *interrupt_parent)
+{
+       irq_domain_add_simple(np, 0);
+       return 0;
+}
+
+static int __init imx27_gpio_add_irq_domain(struct device_node *np,
+                               struct device_node *interrupt_parent)
+{
+       static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
+
+       irq_domain_add_simple(np, gpio_irq_base);
+
+       return 0;
+}
+
+static const struct of_device_id imx27_irq_match[] __initconst = {
+       { .compatible = "fsl,imx27-avic", .data = imx27_avic_add_irq_domain, },
+       { .compatible = "fsl,imx27-gpio", .data = imx27_gpio_add_irq_domain, },
+       { /* sentinel */ }
+};
+
+static void __init imx27_dt_init(void)
+{
+       of_irq_init(imx27_irq_match);
+
+       of_platform_populate(NULL, of_default_bus_match_table,
+                            imx27_auxdata_lookup, NULL);
+}
+
+static void __init imx27_timer_init(void)
+{
+       mx27_clocks_init_dt();
+}
+
+static struct sys_timer imx27_timer = {
+       .init = imx27_timer_init,
+};
+
+static const char *imx27_dt_board_compat[] __initdata = {
+       "fsl,imx27",
+       NULL
+};
+
+DT_MACHINE_START(IMX27_DT, "Freescale i.MX27 (Device Tree Support)")
+       .map_io         = mx27_map_io,
+       .init_early     = imx27_init_early,
+       .init_irq       = mx27_init_irq,
+       .handle_irq     = imx27_handle_irq,
+       .timer          = &imx27_timer,
+       .init_machine   = imx27_dt_init,
+       .dt_compat      = imx27_dt_board_compat,
+       .restart        = mxc_restart,
+MACHINE_END
index 1e03ef42faa09f46ca01090e1d26669ca0c7e45e..5cca573964f08fa5caaf372eabfddf5a55c867a6 100644 (file)
@@ -104,6 +104,7 @@ static struct sys_timer imx51_timer = {
 
 static const char *imx51_dt_board_compat[] __initdata = {
        "fsl,imx51-babbage",
+       "fsl,imx51",
        NULL
 };
 
index fd5be0f20fbb7ea149588fa85760f16e7118afbf..4172279b3900f60f4ddf981ff82887819451487a 100644 (file)
@@ -114,6 +114,7 @@ static const char *imx53_dt_board_compat[] __initdata = {
        "fsl,imx53-evk",
        "fsl,imx53-qsb",
        "fsl,imx53-smd",
+       "fsl,imx53",
        NULL
 };
 
index d4ab6f29a7664250b0a3d11b40f273dee3de055b..0213f8dcee81752291551bf37103b1b16a3a664f 100644 (file)
@@ -17,7 +17,7 @@
 #include <mach/hardware.h>
 
 static struct map_desc imx_lluart_desc = {
-#ifdef CONFIG_DEBUG_IMX6Q_UART
+#ifdef CONFIG_DEBUG_IMX6Q_UART4
        .virtual        = MX6Q_IO_P2V(MX6Q_UART4_BASE_ADDR),
        .pfn            = __phys_to_pfn(MX6Q_UART4_BASE_ADDR),
        .length         = MX6Q_UART4_SIZE,
diff --git a/arch/arm/mach-imx/localtimer.c b/arch/arm/mach-imx/localtimer.c
deleted file mode 100644 (file)
index 3a16351..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2011 Freescale Semiconductor, Inc.
- * Copyright 2011 Linaro Ltd.
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-#include <linux/init.h>
-#include <linux/clockchips.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <asm/smp_twd.h>
-
-/*
- * Setup the local clock events for a CPU.
- */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-       struct device_node *np;
-
-       np = of_find_compatible_node(NULL, NULL, "arm,smp-twd");
-       if (!twd_base) {
-               twd_base = of_iomap(np, 0);
-               WARN_ON(!twd_base);
-       }
-       evt->irq = irq_of_parse_and_map(np, 0);
-       twd_timer_setup(evt);
-
-       return 0;
-}
index e4f426a09899175a948134e006d84a2edcc5c3ae..27bc27e6ea4124a7163f34600c6bf8dacfbbd2c6 100644 (file)
@@ -51,7 +51,7 @@
 #include <mach/ulpi.h>
 
 #include "devices-imx31.h"
-#include "crmregs-imx31.h"
+#include "crmregs-imx3.h"
 
 static int armadillo5x0_pins[] = {
        /* UART1 */
index 428459fbca4b5351701be89b1a136074bf9a4db6..f7b074f496f070b5654a6ab99407f4281dfe04d7 100644 (file)
 #include <linux/input.h>
 #include <linux/gpio.h>
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/leds.h>
+#include <linux/memblock.h>
+#include <media/soc_camera.h>
 #include <sound/tlv320aic32x4.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -39,6 +43,8 @@
 
 #include "devices-imx27.h"
 
+#define TVP5150_RSTN (GPIO_PORTC + 18)
+#define TVP5150_PWDN (GPIO_PORTC + 19)
 #define OTG_PHY_CS_GPIO (GPIO_PORTF + 17)
 #define SDHC1_IRQ IRQ_GPIOB(25)
 
@@ -100,8 +106,99 @@ static const int visstrim_m10_pins[] __initconst = {
        PE1_PF_USBOTG_STP,
        PB23_PF_USB_PWR,
        PB24_PF_USB_OC,
+       /* CSI */
+       PB10_PF_CSI_D0,
+       PB11_PF_CSI_D1,
+       PB12_PF_CSI_D2,
+       PB13_PF_CSI_D3,
+       PB14_PF_CSI_D4,
+       PB15_PF_CSI_MCLK,
+       PB16_PF_CSI_PIXCLK,
+       PB17_PF_CSI_D5,
+       PB18_PF_CSI_D6,
+       PB19_PF_CSI_D7,
+       PB20_PF_CSI_VSYNC,
+       PB21_PF_CSI_HSYNC,
 };
 
+/* Camera */
+static int visstrim_camera_power(struct device *dev, int on)
+{
+       gpio_set_value(TVP5150_PWDN, on);
+
+       return 0;
+};
+
+static int visstrim_camera_reset(struct device *dev)
+{
+       gpio_set_value(TVP5150_RSTN, 0);
+       ndelay(500);
+       gpio_set_value(TVP5150_RSTN, 1);
+
+       return 0;
+};
+
+static struct i2c_board_info visstrim_i2c_camera =  {
+       I2C_BOARD_INFO("tvp5150", 0x5d),
+};
+
+static struct soc_camera_link iclink_tvp5150 = {
+       .bus_id         = 0,
+       .board_info     = &visstrim_i2c_camera,
+       .i2c_adapter_id = 0,
+       .power = visstrim_camera_power,
+       .reset = visstrim_camera_reset,
+};
+
+static struct mx2_camera_platform_data visstrim_camera = {
+       .flags = MX2_CAMERA_CCIR | MX2_CAMERA_CCIR_INTERLACE |
+                       MX2_CAMERA_SWAP16 | MX2_CAMERA_PCLK_SAMPLE_RISING,
+       .clk = 100000,
+};
+
+static phys_addr_t mx2_camera_base __initdata;
+#define MX2_CAMERA_BUF_SIZE SZ_8M
+
+static void __init visstrim_camera_init(void)
+{
+       struct platform_device *pdev;
+       int dma;
+
+       /* Initialize tvp5150 gpios */
+       mxc_gpio_mode(TVP5150_RSTN | GPIO_GPIO | GPIO_OUT);
+       mxc_gpio_mode(TVP5150_PWDN | GPIO_GPIO | GPIO_OUT);
+       gpio_set_value(TVP5150_RSTN, 1);
+       gpio_set_value(TVP5150_PWDN, 0);
+       ndelay(1);
+
+       gpio_set_value(TVP5150_PWDN, 1);
+       ndelay(1);
+       gpio_set_value(TVP5150_RSTN, 0);
+       ndelay(500);
+       gpio_set_value(TVP5150_RSTN, 1);
+       ndelay(200000);
+
+       pdev = imx27_add_mx2_camera(&visstrim_camera);
+       if (IS_ERR(pdev))
+               return;
+
+       dma = dma_declare_coherent_memory(&pdev->dev,
+                               mx2_camera_base, mx2_camera_base,
+                               MX2_CAMERA_BUF_SIZE,
+                               DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+       if (!(dma & DMA_MEMORY_MAP))
+               return;
+}
+
+static void __init visstrim_reserve(void)
+{
+       /* reserve 4 MiB for mx2-camera */
+       mx2_camera_base = memblock_alloc(MX2_CAMERA_BUF_SIZE,
+                       MX2_CAMERA_BUF_SIZE);
+       memblock_free(mx2_camera_base, MX2_CAMERA_BUF_SIZE);
+       memblock_remove(mx2_camera_base, MX2_CAMERA_BUF_SIZE);
+}
+
 /* GPIOs used as events for applications */
 static struct gpio_keys_button visstrim_gpio_keys[] = {
        {
@@ -136,6 +233,35 @@ static const struct gpio_keys_platform_data
        .nbuttons       = ARRAY_SIZE(visstrim_gpio_keys),
 };
 
+/* led */
+static const struct gpio_led visstrim_m10_leds[] __initconst = {
+       {
+               .name = "visstrim:ld0",
+               .default_trigger = "nand-disk",
+               .gpio = (GPIO_PORTC + 29),
+       },
+       {
+               .name = "visstrim:ld1",
+               .default_trigger = "nand-disk",
+               .gpio = (GPIO_PORTC + 24),
+       },
+       {
+               .name = "visstrim:ld2",
+               .default_trigger = "nand-disk",
+               .gpio = (GPIO_PORTC + 28),
+       },
+       {
+               .name = "visstrim:ld3",
+               .default_trigger = "nand-disk",
+               .gpio = (GPIO_PORTC + 25),
+       },
+};
+
+static const struct gpio_led_platform_data visstrim_m10_led_data __initconst = {
+       .leds = visstrim_m10_leds,
+       .num_leds = ARRAY_SIZE(visstrim_m10_leds),
+};
+
 /* Visstrim_SM10 has a microSD slot connected to sdhc1 */
 static int visstrim_m10_sdhc1_init(struct device *dev,
                irq_handler_t detect_irq, void *data)
@@ -216,6 +342,9 @@ static struct i2c_board_info visstrim_m10_i2c_devices[] = {
        {
                I2C_BOARD_INFO("tlv320aic32x4", 0x18),
                .platform_data = &visstrim_m10_aic32x4_pdata,
+       },
+       {
+                I2C_BOARD_INFO("m41t00", 0x68),
        }
 };
 
@@ -254,16 +383,21 @@ static void __init visstrim_m10_board_init(void)
        imx27_add_imx_ssi(0, &visstrim_m10_ssi_pdata);
        imx27_add_imx_uart0(&uart_pdata);
 
-       i2c_register_board_info(0, visstrim_m10_i2c_devices,
-                               ARRAY_SIZE(visstrim_m10_i2c_devices));
        imx27_add_imx_i2c(0, &visstrim_m10_i2c_data);
        imx27_add_imx_i2c(1, &visstrim_m10_i2c_data);
+       i2c_register_board_info(0, visstrim_m10_i2c_devices,
+                               ARRAY_SIZE(visstrim_m10_i2c_devices));
+
        imx27_add_mxc_mmc(0, &visstrim_m10_sdhc_pdata);
        imx27_add_mxc_ehci_otg(&visstrim_m10_usbotg_pdata);
        imx27_add_fec(NULL);
        imx_add_gpio_keys(&visstrim_gpio_keys_platform_data);
        platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
        imx_add_platform_device("mx27vis", 0, NULL, 0, NULL, 0);
+       platform_device_register_resndata(NULL, "soc-camera-pdrv", 0, NULL, 0,
+                                     &iclink_tvp5150, sizeof(iclink_tvp5150));
+       gpio_led_register_device(0, &visstrim_m10_led_data);
+       visstrim_camera_init();
 }
 
 static void __init visstrim_m10_timer_init(void)
@@ -277,6 +411,7 @@ static struct sys_timer visstrim_m10_timer = {
 
 MACHINE_START(IMX27_VISSTRIM_M10, "Vista Silicon Visstrim_M10")
        .atag_offset = 0x100,
+       .reserve = visstrim_reserve,
        .map_io = mx27_map_io,
        .init_early = imx27_init_early,
        .init_irq = mx27_init_irq,
index 6075d4d62dd6a108dbb263d87793885162a1133c..7696dfa2bdbabad8eb3280b9be8f8077eaa822aa 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/of_platform.h>
 #include <linux/phy.h>
 #include <linux/micrel_phy.h>
+#include <asm/smp_twd.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/hardware/gic.h>
 #include <asm/mach/arch.h>
@@ -120,6 +121,7 @@ static void __init imx6q_init_irq(void)
 static void __init imx6q_timer_init(void)
 {
        mx6q_clocks_init();
+       twd_local_timer_of_register();
 }
 
 static struct sys_timer imx6q_timer = {
@@ -129,6 +131,7 @@ static struct sys_timer imx6q_timer = {
 static const char *imx6q_dt_compat[] __initdata = {
        "fsl,imx6q-arm2",
        "fsl,imx6q-sabrelite",
+       "fsl,imx6q",
        NULL,
 };
 
index 8d9f95514b1f1410997b7ecadfcc3918b9b5f613..e432d4acee1fb72711485002f3108c5b33575d99 100644 (file)
@@ -37,8 +37,8 @@
 #define MX21ADS_REG_ADDR(offset)    (void __force __iomem *) \
                (MX21ADS_MMIO_BASE_ADDR + (offset))
 
+#define MX21ADS_CS8900A_MMIO_SIZE   0x200000
 #define MX21ADS_CS8900A_IRQ         IRQ_GPIOE(11)
-#define MX21ADS_CS8900A_IOBASE_REG  MX21ADS_REG_ADDR(0x000000)
 #define MX21ADS_ST16C255_IOBASE_REG MX21ADS_REG_ADDR(0x200000)
 #define MX21ADS_VERSION_REG         MX21ADS_REG_ADDR(0x400000)
 #define MX21ADS_IO_REG              MX21ADS_REG_ADDR(0x800000)
@@ -159,6 +159,18 @@ static struct platform_device mx21ads_nor_mtd_device = {
        .resource = &mx21ads_flash_resource,
 };
 
+static const struct resource mx21ads_cs8900_resources[] __initconst = {
+       DEFINE_RES_MEM(MX21_CS1_BASE_ADDR, MX21ADS_CS8900A_MMIO_SIZE),
+       DEFINE_RES_IRQ(MX21ADS_CS8900A_IRQ),
+};
+
+static const struct platform_device_info mx21ads_cs8900_devinfo __initconst = {
+       .name = "cs89x0",
+       .id = 0,
+       .res = mx21ads_cs8900_resources,
+       .num_res = ARRAY_SIZE(mx21ads_cs8900_resources),
+};
+
 static const struct imxuart_platform_data uart_pdata_rts __initconst = {
        .flags = IMXUART_HAVE_RTSCTS,
 };
@@ -292,6 +304,8 @@ static void __init mx21ads_board_init(void)
        imx21_add_mxc_nand(&mx21ads_nand_board_info);
 
        platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+       platform_device_register_full(
+                       (struct platform_device_info *)&mx21ads_cs8900_devinfo);
 }
 
 static void __init mx21ads_timer_init(void)
index 18f35816706a1e77771d2a57992bee32a006c694..c6d385c522576f1052eeb474fc2d69a86faa7a0e 100644 (file)
@@ -31,6 +31,8 @@
 #include <linux/regulator/machine.h>
 #include <linux/spi/l4f00242t03.h>
 
+#include <media/soc_camera.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
@@ -52,6 +54,8 @@
 #define SD1_CD                 IMX_GPIO_NR(2, 26)
 #define LCD_RESET              IMX_GPIO_NR(1, 3)
 #define LCD_ENABLE             IMX_GPIO_NR(1, 31)
+#define CSI_PWRDWN             IMX_GPIO_NR(4, 19)
+#define CSI_RESET              IMX_GPIO_NR(3, 6)
 
 static const int mx27pdk_pins[] __initconst = {
        /* UART1 */
@@ -141,6 +145,26 @@ static const int mx27pdk_pins[] __initconst = {
        PA30_PF_CONTRAST,
        LCD_ENABLE | GPIO_GPIO | GPIO_OUT,
        LCD_RESET | GPIO_GPIO | GPIO_OUT,
+       /* CSI */
+       PB10_PF_CSI_D0,
+       PB11_PF_CSI_D1,
+       PB12_PF_CSI_D2,
+       PB13_PF_CSI_D3,
+       PB14_PF_CSI_D4,
+       PB15_PF_CSI_MCLK,
+       PB16_PF_CSI_PIXCLK,
+       PB17_PF_CSI_D5,
+       PB18_PF_CSI_D6,
+       PB19_PF_CSI_D7,
+       PB20_PF_CSI_VSYNC,
+       PB21_PF_CSI_HSYNC,
+       CSI_PWRDWN | GPIO_GPIO | GPIO_OUT,
+       CSI_RESET | GPIO_GPIO | GPIO_OUT,
+};
+
+static struct gpio mx27_3ds_camera_gpios[] = {
+       { CSI_PWRDWN, GPIOF_OUT_INIT_HIGH, "camera-power" },
+       { CSI_RESET, GPIOF_OUT_INIT_HIGH, "camera-reset" },
 };
 
 static const struct imxuart_platform_data uart_pdata __initconst = {
@@ -242,6 +266,7 @@ static struct regulator_init_data gpo_init = {
 
 static struct regulator_consumer_supply vmmc1_consumers[] = {
        REGULATOR_SUPPLY("vcore", "spi0.0"),
+       REGULATOR_SUPPLY("cmos_2v8", "soc-camera-pdrv.0"),
 };
 
 static struct regulator_init_data vmmc1_init = {
@@ -270,6 +295,22 @@ static struct regulator_init_data vgen_init = {
        .consumer_supplies = vgen_consumers,
 };
 
+static struct regulator_consumer_supply vvib_consumers[] = {
+       REGULATOR_SUPPLY("cmos_vcore", "soc-camera-pdrv.0"),
+};
+
+static struct regulator_init_data vvib_init = {
+       .constraints = {
+               .min_uV = 1300000,
+               .max_uV = 1300000,
+               .apply_uV = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+                                 REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies = ARRAY_SIZE(vvib_consumers),
+       .consumer_supplies = vvib_consumers,
+};
+
 static struct mc13xxx_regulator_init_data mx27_3ds_regulators[] = {
        {
                .id = MC13783_REG_VMMC1,
@@ -283,6 +324,9 @@ static struct mc13xxx_regulator_init_data mx27_3ds_regulators[] = {
        }, {
                .id = MC13783_REG_GPO3, /* Turn on 3.3V */
                .init_data = &gpo_init,
+       }, {
+               .id = MC13783_REG_VVIB,  /* Power OV2640 */
+               .init_data = &vvib_init,
        },
 };
 
@@ -311,6 +355,51 @@ static const struct spi_imx_master spi2_pdata __initconst = {
        .num_chipselect = ARRAY_SIZE(spi2_chipselect),
 };
 
+static int mx27_3ds_camera_power(struct device *dev, int on)
+{
+       /* enable or disable the camera */
+       pr_debug("%s: %s the camera\n", __func__, on ? "ENABLE" : "DISABLE");
+       gpio_set_value(CSI_PWRDWN, on ? 0 : 1);
+
+       if (!on)
+               goto out;
+
+       /* If enabled, give a reset impulse */
+       gpio_set_value(CSI_RESET, 0);
+       msleep(20);
+       gpio_set_value(CSI_RESET, 1);
+       msleep(100);
+
+out:
+       return 0;
+}
+
+static struct i2c_board_info mx27_3ds_i2c_camera = {
+       I2C_BOARD_INFO("ov2640", 0x30),
+};
+
+static struct regulator_bulk_data mx27_3ds_camera_regs[] = {
+       { .supply = "cmos_vcore" },
+       { .supply = "cmos_2v8" },
+};
+
+static struct soc_camera_link iclink_ov2640 = {
+       .bus_id         = 0,
+       .board_info     = &mx27_3ds_i2c_camera,
+       .i2c_adapter_id = 0,
+       .power          = mx27_3ds_camera_power,
+       .regulators     = mx27_3ds_camera_regs,
+       .num_regulators = ARRAY_SIZE(mx27_3ds_camera_regs),
+};
+
+static struct platform_device mx27_3ds_ov2640 = {
+       .name   = "soc-camera-pdrv",
+       .id     = 0,
+       .dev    = {
+               .platform_data = &iclink_ov2640,
+       },
+};
+
 static struct imx_fb_videomode mx27_3ds_modes[] = {
        {       /* 480x640 @ 60 Hz */
                .mode = {
@@ -367,12 +456,21 @@ static struct spi_board_info mx27_3ds_spi_devs[] __initdata = {
        },
 };
 
+static struct platform_device *devices[] __initdata = {
+       &mx27_3ds_ov2640,
+};
+
+static const struct mx2_camera_platform_data mx27_3ds_cam_pdata __initconst = {
+       .clk = 26000000,
+};
+
 static const struct imxi2c_platform_data mx27_3ds_i2c0_data __initconst = {
        .bitrate = 100000,
 };
 
 static void __init mx27pdk_init(void)
 {
+       int ret;
        imx27_soc_init();
 
        mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins),
@@ -404,7 +502,17 @@ static void __init mx27pdk_init(void)
        if (mxc_expio_init(MX27_CS5_BASE_ADDR, EXPIO_PARENT_INT))
                pr_warn("Init of the debugboard failed, all devices on the debugboard are unusable.\n");
        imx27_add_imx_i2c(0, &mx27_3ds_i2c0_data);
+       platform_add_devices(devices, ARRAY_SIZE(devices));
        imx27_add_imx_fb(&mx27_3ds_fb_data);
+
+       ret = gpio_request_array(mx27_3ds_camera_gpios,
+                                ARRAY_SIZE(mx27_3ds_camera_gpios));
+       if (ret) {
+               pr_err("Failed to request camera gpios");
+               iclink_ov2640.power = NULL;
+       }
+
+       imx27_add_mx2_camera(&mx27_3ds_cam_pdata);
 }
 
 static void __init mx27pdk_timer_init(void)
index 4917aab0e2539609a57bbcdc94bf8b24fccb37aa..4518e544822731c19b941927067265184c59ff0b 100644 (file)
@@ -28,7 +28,6 @@
 #include <asm/memory.h>
 #include <asm/mach/map.h>
 #include <mach/common.h>
-#include <mach/board-mx31ads.h>
 #include <mach/iomux-mx3.h>
 
 #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
@@ -39,6 +38,9 @@
 
 #include "devices-imx31.h"
 
+/* Base address of PBC controller */
+#define PBC_BASE_ADDRESS       MX31_CS4_BASE_ADDR_VIRT
+
 /* PBC Board interrupt status register */
 #define PBC_INTSTATUS           0x000016
 
@@ -62,6 +64,7 @@
 #define PBC_INTMASK_CLEAR_REG  (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS)
 #define EXPIO_PARENT_INT       IOMUX_TO_IRQ(MX31_PIN_GPIO1_4)
 
+#define MXC_EXP_IO_BASE                MXC_BOARD_IRQ_START
 #define MXC_IRQ_TO_EXPIO(irq)  ((irq) - MXC_EXP_IO_BASE)
 
 #define EXPIO_INT_XUART_INTA   (MXC_EXP_IO_BASE + 10)
 
 #define MXC_MAX_EXP_IO_LINES   16
 
+/* CS8900 */
+#define EXPIO_INT_ENET_INT     (MXC_EXP_IO_BASE + 8)
+#define CS4_CS8900_MMIO_START  0x20000
+
 /*
  * The serial port definition structure.
  */
@@ -101,11 +108,29 @@ static struct platform_device serial_device = {
        },
 };
 
+static const struct resource mx31ads_cs8900_resources[] __initconst = {
+       DEFINE_RES_MEM(MX31_CS4_BASE_ADDR + CS4_CS8900_MMIO_START, SZ_64K),
+       DEFINE_RES_IRQ(EXPIO_INT_ENET_INT),
+};
+
+static const struct platform_device_info mx31ads_cs8900_devinfo __initconst = {
+       .name = "cs89x0",
+       .id = 0,
+       .res = mx31ads_cs8900_resources,
+       .num_res = ARRAY_SIZE(mx31ads_cs8900_resources),
+};
+
 static int __init mxc_init_extuart(void)
 {
        return platform_device_register(&serial_device);
 }
 
+static void __init mxc_init_ext_ethernet(void)
+{
+       platform_device_register_full(
+               (struct platform_device_info *)&mx31ads_cs8900_devinfo);
+}
+
 static const struct imxuart_platform_data uart_pdata __initconst = {
        .flags = IMXUART_HAVE_RTSCTS,
 };
@@ -492,12 +517,15 @@ static void __init mxc_init_audio(void)
        mxc_iomux_setup_multiple_pins(ssi_pins, ARRAY_SIZE(ssi_pins), "ssi");
 }
 
-/* static mappings */
+/*
+ * Static mappings, starting from the CS4 start address up to the start address
+ * of the CS8900.
+ */
 static struct map_desc mx31ads_io_desc[] __initdata = {
        {
                .virtual        = MX31_CS4_BASE_ADDR_VIRT,
                .pfn            = __phys_to_pfn(MX31_CS4_BASE_ADDR),
-               .length         = MX31_CS4_SIZE / 2,
+               .length         = CS4_CS8900_MMIO_START,
                .type           = MT_DEVICE
        },
 };
@@ -522,6 +550,7 @@ static void __init mx31ads_init(void)
        mxc_init_imx_uart();
        mxc_init_i2c();
        mxc_init_audio();
+       mxc_init_ext_ethernet();
 }
 
 static void __init mx31ads_timer_init(void)
index f225262b5c38551cb6ec424e01cb71139f9a551f..f17a15f28316519a1dd01f793742ca1293286df2 100644 (file)
@@ -507,7 +507,7 @@ static void mx31moboard_poweroff(void)
        struct clk *clk = clk_get_sys("imx2-wdt.0", NULL);
 
        if (!IS_ERR(clk))
-               clk_enable(clk);
+               clk_prepare_enable(clk);
 
        mxc_iomux_mode(MX31_PIN_WATCHDOG_RST__WATCHDOG_RST);
 
@@ -530,6 +530,8 @@ static void __init mx31moboard_init(void)
        platform_add_devices(devices, ARRAY_SIZE(devices));
        gpio_led_register_device(-1, &mx31moboard_led_pdata);
 
+       imx31_add_imx2_wdt(NULL);
+
        imx31_add_imx_uart0(&uart0_pdata);
        imx31_add_imx_uart4(&uart4_pdata);
 
@@ -590,7 +592,7 @@ static void __init mx31moboard_reserve(void)
 }
 
 MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard")
-       /* Maintainer: Valentin Longchamp, EPFL Mobots group */
+       /* Maintainer: Philippe Retornaz, EPFL Mobots group */
        .atag_offset = 0x100,
        .reserve = mx31moboard_reserve,
        .map_io = mx31_map_io,
index 0af6c9c5b3fdd443748d625db5529409074e124d..e14291d89e4fda86ec6c885a902e467ad53ad401 100644 (file)
@@ -4,6 +4,11 @@
  *
  * Author: Fabio Estevam <fabio.estevam@freescale.com>
  *
+ * Copyright (C) 2011 Meprolight, Ltd.
+ * Alex Gershgorin <alexg@meprolight.com>
+ *
+ * Modified from i.MX31 3-Stack Development System
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
+#include <asm/memblock.h>
 
 #include <mach/hardware.h>
 #include <mach/common.h>
 #include <mach/iomux-mx35.h>
 #include <mach/irqs.h>
 #include <mach/3ds_debugboard.h>
+#include <video/platform_lcd.h>
+
+#include <media/soc_camera.h>
 
 #include "devices-imx35.h"
 
+#define GPIO_MC9S08DZ60_GPS_ENABLE 0
+#define GPIO_MC9S08DZ60_HDD_ENABLE 4
+#define GPIO_MC9S08DZ60_WIFI_ENABLE 5
+#define GPIO_MC9S08DZ60_LCD_ENABLE 6
+#define GPIO_MC9S08DZ60_SPEAKER_ENABLE 8
+
+static const struct fb_videomode fb_modedb[] = {
+       {
+                /* 800x480 @ 55 Hz */
+               .name = "Ceramate-CLAA070VC01",
+               .refresh = 55,
+               .xres = 800,
+               .yres = 480,
+               .pixclock = 40000,
+               .left_margin = 40,
+               .right_margin = 40,
+               .upper_margin = 5,
+               .lower_margin = 5,
+               .hsync_len = 20,
+               .vsync_len = 10,
+               .sync = FB_SYNC_OE_ACT_HIGH,
+               .vmode = FB_VMODE_NONINTERLACED,
+               .flag = 0,
+        },
+};
+
+static const struct ipu_platform_data mx3_ipu_data __initconst = {
+       .irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct mx3fb_platform_data mx3fb_pdata __initdata = {
+       .name = "Ceramate-CLAA070VC01",
+       .mode = fb_modedb,
+       .num_modes = ARRAY_SIZE(fb_modedb),
+};
+
+static struct i2c_board_info __initdata i2c_devices_3ds[] = {
+       {
+               I2C_BOARD_INFO("mc9s08dz60", 0x69),
+       },
+};
+
+static int lcd_power_gpio = -ENXIO;
+
+static int mc9s08dz60_gpiochip_match(struct gpio_chip *chip,
+                                                    void *data)
+{
+       return !strcmp(chip->label, data);
+}
+
+static void mx35_3ds_lcd_set_power(
+                               struct plat_lcd_data *pd, unsigned int power)
+{
+       struct gpio_chip *chip;
+
+       if (!gpio_is_valid(lcd_power_gpio)) {
+               chip = gpiochip_find(
+                               "mc9s08dz60", mc9s08dz60_gpiochip_match);
+               if (chip) {
+                       lcd_power_gpio =
+                               chip->base + GPIO_MC9S08DZ60_LCD_ENABLE;
+                       if (gpio_request(lcd_power_gpio, "lcd_power") < 0) {
+                               pr_err("error: gpio already requested!\n");
+                               lcd_power_gpio = -ENXIO;
+                       }
+               } else {
+                       pr_err("error: didn't find mc9s08dz60 gpio chip\n");
+               }
+       }
+
+       if (gpio_is_valid(lcd_power_gpio))
+               gpio_set_value_cansleep(lcd_power_gpio, power);
+}
+
+static struct plat_lcd_data mx35_3ds_lcd_data = {
+       .set_power = mx35_3ds_lcd_set_power,
+};
+
+static struct platform_device mx35_3ds_lcd = {
+       .name = "platform-lcd",
+       .dev.platform_data = &mx35_3ds_lcd_data,
+};
+
 #define EXPIO_PARENT_INT       gpio_to_irq(IMX_GPIO_NR(1, 1))
 
 static const struct imxuart_platform_data uart_pdata __initconst = {
@@ -120,6 +212,109 @@ static iomux_v3_cfg_t mx35pdk_pads[] = {
        /* I2C1 */
        MX35_PAD_I2C1_CLK__I2C1_SCL,
        MX35_PAD_I2C1_DAT__I2C1_SDA,
+       /* Display */
+       MX35_PAD_LD0__IPU_DISPB_DAT_0,
+       MX35_PAD_LD1__IPU_DISPB_DAT_1,
+       MX35_PAD_LD2__IPU_DISPB_DAT_2,
+       MX35_PAD_LD3__IPU_DISPB_DAT_3,
+       MX35_PAD_LD4__IPU_DISPB_DAT_4,
+       MX35_PAD_LD5__IPU_DISPB_DAT_5,
+       MX35_PAD_LD6__IPU_DISPB_DAT_6,
+       MX35_PAD_LD7__IPU_DISPB_DAT_7,
+       MX35_PAD_LD8__IPU_DISPB_DAT_8,
+       MX35_PAD_LD9__IPU_DISPB_DAT_9,
+       MX35_PAD_LD10__IPU_DISPB_DAT_10,
+       MX35_PAD_LD11__IPU_DISPB_DAT_11,
+       MX35_PAD_LD12__IPU_DISPB_DAT_12,
+       MX35_PAD_LD13__IPU_DISPB_DAT_13,
+       MX35_PAD_LD14__IPU_DISPB_DAT_14,
+       MX35_PAD_LD15__IPU_DISPB_DAT_15,
+       MX35_PAD_LD16__IPU_DISPB_DAT_16,
+       MX35_PAD_LD17__IPU_DISPB_DAT_17,
+       MX35_PAD_D3_HSYNC__IPU_DISPB_D3_HSYNC,
+       MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK,
+       MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY,
+       MX35_PAD_CONTRAST__IPU_DISPB_CONTR,
+       MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC,
+       MX35_PAD_D3_REV__IPU_DISPB_D3_REV,
+       MX35_PAD_D3_CLS__IPU_DISPB_D3_CLS,
+       /* CSI */
+       MX35_PAD_TX1__IPU_CSI_D_6,
+       MX35_PAD_TX0__IPU_CSI_D_7,
+       MX35_PAD_CSI_D8__IPU_CSI_D_8,
+       MX35_PAD_CSI_D9__IPU_CSI_D_9,
+       MX35_PAD_CSI_D10__IPU_CSI_D_10,
+       MX35_PAD_CSI_D11__IPU_CSI_D_11,
+       MX35_PAD_CSI_D12__IPU_CSI_D_12,
+       MX35_PAD_CSI_D13__IPU_CSI_D_13,
+       MX35_PAD_CSI_D14__IPU_CSI_D_14,
+       MX35_PAD_CSI_D15__IPU_CSI_D_15,
+       MX35_PAD_CSI_HSYNC__IPU_CSI_HSYNC,
+       MX35_PAD_CSI_MCLK__IPU_CSI_MCLK,
+       MX35_PAD_CSI_PIXCLK__IPU_CSI_PIXCLK,
+       MX35_PAD_CSI_VSYNC__IPU_CSI_VSYNC,
+};
+
+/*
+ * Camera support
+*/
+static phys_addr_t mx3_camera_base __initdata;
+#define MX35_3DS_CAMERA_BUF_SIZE SZ_8M
+
+static const struct mx3_camera_pdata mx35_3ds_camera_pdata __initconst = {
+       .flags = MX3_CAMERA_DATAWIDTH_8,
+       .mclk_10khz = 2000,
+};
+
+static int __init imx35_3ds_init_camera(void)
+{
+       int dma, ret = -ENOMEM;
+       struct platform_device *pdev =
+               imx35_alloc_mx3_camera(&mx35_3ds_camera_pdata);
+
+       if (IS_ERR(pdev))
+               return PTR_ERR(pdev);
+
+       if (!mx3_camera_base)
+               goto err;
+
+       dma = dma_declare_coherent_memory(&pdev->dev,
+                                       mx3_camera_base, mx3_camera_base,
+                                       MX35_3DS_CAMERA_BUF_SIZE,
+                                       DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+
+       if (!(dma & DMA_MEMORY_MAP))
+               goto err;
+
+       ret = platform_device_add(pdev);
+       if (ret)
+err:
+               platform_device_put(pdev);
+
+       return ret;
+}
+
+static const struct ipu_platform_data mx35_3ds_ipu_data __initconst = {
+       .irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct i2c_board_info mx35_3ds_i2c_camera = {
+       I2C_BOARD_INFO("ov2640", 0x30),
+};
+
+static struct soc_camera_link iclink_ov2640 = {
+       .bus_id         = 0,
+       .board_info     = &mx35_3ds_i2c_camera,
+       .i2c_adapter_id = 0,
+       .power          = NULL,
+};
+
+static struct platform_device mx35_3ds_ov2640 = {
+       .name   = "soc-camera-pdrv",
+       .id     = 0,
+       .dev    = {
+               .platform_data = &iclink_ov2640,
+       },
 };
 
 static int mx35_3ds_otg_init(struct platform_device *pdev)
@@ -179,6 +374,8 @@ static const struct imxi2c_platform_data mx35_3ds_i2c0_data __initconst = {
  */
 static void __init mx35_3ds_init(void)
 {
+       struct platform_device *imx35_fb_pdev;
+
        imx35_soc_init();
 
        mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads));
@@ -204,6 +401,17 @@ static void __init mx35_3ds_init(void)
                pr_warn("Init of the debugboard failed, all "
                                "devices on the debugboard are unusable.\n");
        imx35_add_imx_i2c0(&mx35_3ds_i2c0_data);
+
+       i2c_register_board_info(
+               0, i2c_devices_3ds, ARRAY_SIZE(i2c_devices_3ds));
+
+       imx35_add_ipu_core(&mx35_3ds_ipu_data);
+       platform_device_register(&mx35_3ds_ov2640);
+       imx35_3ds_init_camera();
+
+       imx35_fb_pdev = imx35_add_mx3_sdc_fb(&mx3fb_pdata);
+       mx35_3ds_lcd.dev.parent = &imx35_fb_pdev->dev;
+       platform_device_register(&mx35_3ds_lcd);
 }
 
 static void __init mx35pdk_timer_init(void)
@@ -215,6 +423,13 @@ struct sys_timer mx35pdk_timer = {
        .init   = mx35pdk_timer_init,
 };
 
+static void __init mx35_3ds_reserve(void)
+{
+       /* reserve MX35_3DS_CAMERA_BUF_SIZE bytes for mx3-camera */
+       mx3_camera_base = arm_memblock_steal(MX35_3DS_CAMERA_BUF_SIZE,
+                                        MX35_3DS_CAMERA_BUF_SIZE);
+}
+
 MACHINE_START(MX35_3DS, "Freescale MX35PDK")
        /* Maintainer: Freescale Semiconductor, Inc */
        .atag_offset = 0x100,
@@ -224,5 +439,6 @@ MACHINE_START(MX35_3DS, "Freescale MX35PDK")
        .handle_irq = imx35_handle_irq,
        .timer = &mx35pdk_timer,
        .init_machine = mx35_3ds_init,
+       .reserve = mx35_3ds_reserve,
        .restart        = mxc_restart,
 MACHINE_END
index 16f126da9f8f543abf7d175477778b5636bb0a55..2f3debe2a11335f60de6f2913cb4ba9452127567 100644 (file)
@@ -233,7 +233,7 @@ static struct regulator_init_data sdhc1_data = {
 
 static struct regulator_consumer_supply cam_consumers[] = {
        {
-               .dev    = NULL,
+               .dev_name = NULL,
                .supply = "imx_cam_vcc",
        },
 };
index 9c9b7f9f43dc9790d10f295ffbab01da323a4014..f8ca96c354f2280aa1ba10af200b3e443fce51fb 100644 (file)
@@ -34,6 +34,8 @@ static void imx3_idle(void)
 {
        unsigned long reg = 0;
 
+       mx3_cpu_lp_set(MX3_WAIT);
+
        __asm__ __volatile__(
                /* disable I and D cache */
                "mrc p15, 0, %0, c1, c0, 0\n"
@@ -76,7 +78,7 @@ static void __iomem *imx3_ioremap(unsigned long phys_addr, size_t size,
        return __arm_ioremap(phys_addr, size, mtype);
 }
 
-void imx3_init_l2x0(void)
+void __init imx3_init_l2x0(void)
 {
        void __iomem *l2x0_base;
        void __iomem *clkctl_base;
@@ -177,6 +179,10 @@ void __init imx31_soc_init(void)
        }
 
        imx_add_imx_sdma("imx31-sdma", MX31_SDMA_BASE_ADDR, MX31_INT_SDMA, &imx31_sdma_pdata);
+
+       imx_set_aips(MX31_IO_ADDRESS(MX31_AIPS1_BASE_ADDR));
+       imx_set_aips(MX31_IO_ADDRESS(MX31_AIPS2_BASE_ADDR));
+
        platform_device_register_simple("imx31-audmux", 0, imx31_audmux_res,
                                        ARRAY_SIZE(imx31_audmux_res));
 }
@@ -267,6 +273,11 @@ void __init imx35_soc_init(void)
        }
 
        imx_add_imx_sdma("imx35-sdma", MX35_SDMA_BASE_ADDR, MX35_INT_SDMA, &imx35_sdma_pdata);
+
+       /* Setup AIPS registers */
+       imx_set_aips(MX35_IO_ADDRESS(MX35_AIPS1_BASE_ADDR));
+       imx_set_aips(MX35_IO_ADDRESS(MX35_AIPS2_BASE_ADDR));
+
        /* i.mx35 has the i.mx31 type audmux */
        platform_device_register_simple("imx31-audmux", 0, imx35_audmux_res,
                                        ARRAY_SIZE(imx35_audmux_res));
index dc7c4ed815312a3a9cfda690b87ad646d587da84..51af9fa56944cf6daf19dc295e7d7ec7f1efd9d4 100644 (file)
@@ -201,6 +201,11 @@ void __init imx51_soc_init(void)
 
        /* i.mx51 has the i.mx35 type sdma */
        imx_add_imx_sdma("imx35-sdma", MX51_SDMA_BASE_ADDR, MX51_INT_SDMA, &imx51_sdma_pdata);
+
+       /* Setup AIPS registers */
+       imx_set_aips(MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR));
+       imx_set_aips(MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR));
+
        /* i.mx51 has the i.mx31 type audmux */
        platform_device_register_simple("imx31-audmux", 0, imx51_audmux_res,
                                        ARRAY_SIZE(imx51_audmux_res));
@@ -219,6 +224,11 @@ void __init imx53_soc_init(void)
 
        /* i.mx53 has the i.mx35 type sdma */
        imx_add_imx_sdma("imx35-sdma", MX53_SDMA_BASE_ADDR, MX53_INT_SDMA, &imx53_sdma_pdata);
+
+       /* Setup AIPS registers */
+       imx_set_aips(MX53_IO_ADDRESS(MX53_AIPS1_BASE_ADDR));
+       imx_set_aips(MX53_IO_ADDRESS(MX53_AIPS2_BASE_ADDR));
+
        /* i.mx53 has the i.mx31 type audmux */
        platform_device_register_simple("imx31-audmux", 0, imx53_audmux_res,
                                        ARRAY_SIZE(imx53_audmux_res));
diff --git a/arch/arm/mach-imx/pm-imx3.c b/arch/arm/mach-imx/pm-imx3.c
new file mode 100644 (file)
index 0000000..b375243
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/io.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#include "crmregs-imx3.h"
+
+/*
+ * Set cpu low power mode before WFI instruction. This function is called
+ * mx3 because it can be used for mx31 and mx35.
+ * Currently only WAIT_MODE is supported.
+ */
+void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode)
+{
+       int reg = __raw_readl(MXC_CCM_CCMR);
+       reg &= ~MXC_CCM_CCMR_LPM_MASK;
+
+       switch (mode) {
+       case MX3_WAIT:
+               if (cpu_is_mx35())
+                       reg |= MXC_CCM_CCMR_LPM_WAIT_MX35;
+               __raw_writel(reg, MXC_CCM_CCMR);
+               break;
+       default:
+               pr_err("Unknown cpu power mode: %d\n", mode);
+               return;
+       }
+}
index 6dc0934480577363a2d49a4a5646d69d6cc62729..e26a9cb05ed811098e25244e58349b094ba0dc7b 100644 (file)
@@ -89,7 +89,7 @@ void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
 
 static int mx5_suspend_prepare(void)
 {
-       return clk_enable(gpc_dvfs_clk);
+       return clk_prepare_enable(gpc_dvfs_clk);
 }
 
 static int mx5_suspend_enter(suspend_state_t state)
@@ -119,7 +119,7 @@ static int mx5_suspend_enter(suspend_state_t state)
 
 static void mx5_suspend_finish(void)
 {
-       clk_disable(gpc_dvfs_clk);
+       clk_disable_unprepare(gpc_dvfs_clk);
 }
 
 static int mx5_pm_valid(suspend_state_t state)
index 7fc603b468916014d12499c26825e945655a1941..90ceab761929e7839c3968e9e7403c1c56dc7710 100644 (file)
@@ -44,6 +44,20 @@ config MACH_GURUPLUG
          Say 'Y' here if you want your kernel to support the
          Marvell GuruPlug Reference Board.
 
+config ARCH_KIRKWOOD_DT
+       bool "Marvell Kirkwood Flattened Device Tree"
+       select USE_OF
+       help
+         Say 'Y' here if you want your kernel to support the
+         Marvell Kirkwood using flattened device tree.
+
+config MACH_DREAMPLUG_DT
+       bool "Marvell DreamPlug (Flattened Device Tree)"
+       select ARCH_KIRKWOOD_DT
+       help
+         Say 'Y' here if you want your kernel to support the
+         Marvell DreamPlug (Flattened Device Tree).
+
 config MACH_TS219
        bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS"
        help
index 5dcaa81a2ec39f0f6b60a13438651ab381fc6eb4..e299a9576bf0d00b8c6cbd77191367bc2cc40e06 100644 (file)
@@ -20,3 +20,5 @@ obj-$(CONFIG_MACH_NET5BIG_V2)         += netxbig_v2-setup.o lacie_v2-common.o
 obj-$(CONFIG_MACH_T5325)               += t5325-setup.o
 
 obj-$(CONFIG_CPU_IDLE)                 += cpuidle.o
+obj-$(CONFIG_ARCH_KIRKWOOD_DT)         += board-dt.o
+obj-$(CONFIG_MACH_DREAMPLUG_DT)                += board-dreamplug.o
index 760a0efe7580b0dd194ff9bfe4295624336bb806..16f938522304ededdb6a498730e0616f082d3ff6 100644 (file)
@@ -1,3 +1,5 @@
    zreladdr-y  += 0x00008000
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
+
+dtb-$(CONFIG_MACH_DREAMPLUG_DT) += kirkwood-dreamplug.dtb
diff --git a/arch/arm/mach-kirkwood/board-dreamplug.c b/arch/arm/mach-kirkwood/board-dreamplug.c
new file mode 100644 (file)
index 0000000..9854539
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2012 (C), Jason Cooper <jason@lakedaemon.net>
+ *
+ * arch/arm/mach-kirkwood/board-dreamplug.c
+ *
+ * Marvell DreamPlug Reference Board Init for drivers not converted to
+ * flattened device tree yet.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/orion_spi.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/kirkwood.h>
+#include <mach/bridge-regs.h>
+#include <plat/mvsdio.h>
+#include "common.h"
+#include "mpp.h"
+
+struct mtd_partition dreamplug_partitions[] = {
+       {
+               .name   = "u-boot",
+               .size   = SZ_512K,
+               .offset = 0,
+       },
+       {
+               .name   = "u-boot env",
+               .size   = SZ_64K,
+               .offset = SZ_512K + SZ_512K,
+       },
+       {
+               .name   = "dtb",
+               .size   = SZ_64K,
+               .offset = SZ_512K + SZ_512K + SZ_512K,
+       },
+};
+
+static const struct flash_platform_data dreamplug_spi_slave_data = {
+       .type           = "mx25l1606e",
+       .name           = "spi_flash",
+       .parts          = dreamplug_partitions,
+       .nr_parts       = ARRAY_SIZE(dreamplug_partitions),
+};
+
+static struct spi_board_info __initdata dreamplug_spi_slave_info[] = {
+       {
+               .modalias       = "m25p80",
+               .platform_data  = &dreamplug_spi_slave_data,
+               .irq            = -1,
+               .max_speed_hz   = 50000000,
+               .bus_num        = 0,
+               .chip_select    = 0,
+       },
+};
+
+static struct mv643xx_eth_platform_data dreamplug_ge00_data = {
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(0),
+};
+
+static struct mv643xx_eth_platform_data dreamplug_ge01_data = {
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(1),
+};
+
+static struct mv_sata_platform_data dreamplug_sata_data = {
+       .n_ports        = 1,
+};
+
+static struct mvsdio_platform_data dreamplug_mvsdio_data = {
+       /* unfortunately the CD signal has not been connected */
+};
+
+static struct gpio_led dreamplug_led_pins[] = {
+       {
+               .name                   = "dreamplug:blue:bluetooth",
+               .gpio                   = 47,
+               .active_low             = 1,
+       },
+       {
+               .name                   = "dreamplug:green:wifi",
+               .gpio                   = 48,
+               .active_low             = 1,
+       },
+       {
+               .name                   = "dreamplug:green:wifi_ap",
+               .gpio                   = 49,
+               .active_low             = 1,
+       },
+};
+
+static struct gpio_led_platform_data dreamplug_led_data = {
+       .leds           = dreamplug_led_pins,
+       .num_leds       = ARRAY_SIZE(dreamplug_led_pins),
+};
+
+static struct platform_device dreamplug_leds = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &dreamplug_led_data,
+       }
+};
+
+static unsigned int dreamplug_mpp_config[] __initdata = {
+       MPP0_SPI_SCn,
+       MPP1_SPI_MOSI,
+       MPP2_SPI_SCK,
+       MPP3_SPI_MISO,
+       MPP47_GPIO,     /* Bluetooth LED */
+       MPP48_GPIO,     /* Wifi LED */
+       MPP49_GPIO,     /* Wifi AP LED */
+       0
+};
+
+void __init dreamplug_init(void)
+{
+       /*
+        * Basic setup. Needs to be called early.
+        */
+       kirkwood_mpp_conf(dreamplug_mpp_config);
+
+       spi_register_board_info(dreamplug_spi_slave_info,
+                               ARRAY_SIZE(dreamplug_spi_slave_info));
+       kirkwood_spi_init();
+
+       kirkwood_ehci_init();
+       kirkwood_ge00_init(&dreamplug_ge00_data);
+       kirkwood_ge01_init(&dreamplug_ge01_data);
+       kirkwood_sata_init(&dreamplug_sata_data);
+       kirkwood_sdio_init(&dreamplug_mvsdio_data);
+
+       platform_device_register(&dreamplug_leds);
+}
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
new file mode 100644 (file)
index 0000000..1c672d9
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2012 (C), Jason Cooper <jason@lakedaemon.net>
+ *
+ * arch/arm/mach-kirkwood/board-dt.c
+ *
+ * Flattened Device Tree board initialization
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/bridge-regs.h>
+#include "common.h"
+
+static struct of_device_id kirkwood_dt_match_table[] __initdata = {
+       { .compatible = "simple-bus", },
+       { }
+};
+
+static void __init kirkwood_dt_init(void)
+{
+       pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk);
+
+       /*
+        * Disable propagation of mbus errors to the CPU local bus,
+        * as this causes mbus errors (which can occur for example
+        * for PCI aborts) to throw CPU aborts, which we're not set
+        * up to deal with.
+        */
+       writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
+
+       kirkwood_setup_cpu_mbus();
+
+#ifdef CONFIG_CACHE_FEROCEON_L2
+       kirkwood_l2_init();
+#endif
+
+       /* internal devices that every board has */
+       kirkwood_wdt_init();
+       kirkwood_xor0_init();
+       kirkwood_xor1_init();
+       kirkwood_crypto_init();
+
+#ifdef CONFIG_KEXEC
+       kexec_reinit = kirkwood_enable_pcie;
+#endif
+
+       if (of_machine_is_compatible("globalscale,dreamplug"))
+               dreamplug_init();
+
+       of_platform_populate(NULL, kirkwood_dt_match_table, NULL, NULL);
+}
+
+static const char *kirkwood_dt_board_compat[] = {
+       "globalscale,dreamplug",
+       NULL
+};
+
+DT_MACHINE_START(KIRKWOOD_DT, "Marvell Kirkwood (Flattened Device Tree)")
+       /* Maintainer: Jason Cooper <jason@lakedaemon.net> */
+       .map_io         = kirkwood_map_io,
+       .init_early     = kirkwood_init_early,
+       .init_irq       = kirkwood_init_irq,
+       .timer          = &kirkwood_timer,
+       .init_machine   = kirkwood_dt_init,
+       .restart        = kirkwood_restart,
+       .dt_compat      = kirkwood_dt_board_compat,
+MACHINE_END
index 77d4852e19f283e3b06f1fd63e9ff61707f99146..a02cae881f2fe199929f789b3275e7ad9cd17d69 100644 (file)
@@ -279,7 +279,7 @@ void __init kirkwood_crypto_init(void)
 /*****************************************************************************
  * XOR0
  ****************************************************************************/
-static void __init kirkwood_xor0_init(void)
+void __init kirkwood_xor0_init(void)
 {
        kirkwood_clk_ctrl |= CGC_XOR0;
 
@@ -291,7 +291,7 @@ static void __init kirkwood_xor0_init(void)
 /*****************************************************************************
  * XOR1
  ****************************************************************************/
-static void __init kirkwood_xor1_init(void)
+void __init kirkwood_xor1_init(void)
 {
        kirkwood_clk_ctrl |= CGC_XOR1;
 
@@ -303,7 +303,7 @@ static void __init kirkwood_xor1_init(void)
 /*****************************************************************************
  * Watchdog
  ****************************************************************************/
-static void __init kirkwood_wdt_init(void)
+void __init kirkwood_wdt_init(void)
 {
        orion_wdt_init(kirkwood_tclk);
 }
@@ -392,7 +392,7 @@ void __init kirkwood_audio_init(void)
 /*
  * Identify device ID and revision.
  */
-static char * __init kirkwood_id(void)
+char * __init kirkwood_id(void)
 {
        u32 dev, rev;
 
@@ -435,7 +435,7 @@ static char * __init kirkwood_id(void)
        }
 }
 
-static void __init kirkwood_l2_init(void)
+void __init kirkwood_l2_init(void)
 {
 #ifdef CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH
        writel(readl(L2_CONFIG_REG) | L2_WRITETHROUGH, L2_CONFIG_REG);
@@ -450,7 +450,6 @@ void __init kirkwood_init(void)
 {
        printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n",
                kirkwood_id(), kirkwood_tclk);
-       kirkwood_i2s_data.tclk = kirkwood_tclk;
 
        /*
         * Disable propagation of mbus errors to the CPU local bus,
index 9071a397136d85a1235767efba393dc7df83efec..fa8e7689c4369a414cb9e6f0d77d887f0845bd27 100644 (file)
@@ -51,6 +51,21 @@ void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, int (*dev
 void kirkwood_audio_init(void);
 void kirkwood_restart(char, const char *);
 
+/* board init functions for boards not fully converted to fdt */
+#ifdef CONFIG_MACH_DREAMPLUG_DT
+void dreamplug_init(void);
+#else
+static inline void dreamplug_init(void) {};
+#endif
+
+/* early init functions not converted to fdt yet */
+char *kirkwood_id(void);
+void kirkwood_l2_init(void);
+void kirkwood_wdt_init(void);
+void kirkwood_xor0_init(void);
+void kirkwood_xor1_init(void);
+void kirkwood_crypto_init(void);
+
 extern int kirkwood_tclk;
 extern struct sys_timer kirkwood_timer;
 
index fde66350869638210881a6e07a85478e1408ee53..75946ac89ee9216103de2daf08f3a09bd22daf88 100644 (file)
@@ -29,5 +29,30 @@ config ARCH_LPC32XX_UART6_SELECT
 
 endmenu
 
+menu "LPC32XX chip components"
+
+config ARCH_LPC32XX_IRAM_FOR_NET
+       bool "Use IRAM for network buffers"
+       default y
+       help
+         Say Y here to use the LPC internal fast IRAM (i.e. 256KB SRAM) as
+         network buffer.  If the total combined required buffer sizes is
+         larger than the size of IRAM, then SDRAM will be used instead.
+
+         This can be enabled safely if the IRAM is not intended for other
+         uses.
+
+config ARCH_LPC32XX_MII_SUPPORT
+       bool "Check to enable MII support or leave disabled for RMII support"
+       help
+         Say Y here to enable MII support, or N for RMII support. Regardless of
+         which support is selected, the ethernet interface driver needs to be
+         selected in the device driver networking section.
+
+         The PHY3250 reference board uses RMII, so users of this board should
+         say N.
+
+endmenu
+
 endif
 
index 1e027514096d0d9e15f87152a0e92761f1e959e8..b7ef51119d37580839f9773431f69c4282bdbae0 100644 (file)
  *   will also impact the individual peripheral rates.
  */
 
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/device.h>
+#include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/amba/bus.h>
 #include "clock.h"
 #include "common.h"
 
+static DEFINE_SPINLOCK(global_clkregs_lock);
+
+static int usb_pll_enable, usb_pll_valid;
+
 static struct clk clk_armpll;
 static struct clk clk_usbpll;
-static DEFINE_MUTEX(clkm_lock);
 
 /*
  * Post divider values for PLLs based on selected register value
@@ -127,7 +132,7 @@ static struct clk osc_32KHz = {
 static int local_pll397_enable(struct clk *clk, int enable)
 {
        u32 reg;
-       unsigned long timeout = 1 + msecs_to_jiffies(10);
+       unsigned long timeout = jiffies + msecs_to_jiffies(10);
 
        reg = __raw_readl(LPC32XX_CLKPWR_PLL397_CTRL);
 
@@ -142,7 +147,7 @@ static int local_pll397_enable(struct clk *clk, int enable)
                /* Wait for PLL397 lock */
                while (((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) &
                        LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0) &&
-                       (timeout > jiffies))
+                       time_before(jiffies, timeout))
                        cpu_relax();
 
                if ((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) &
@@ -156,7 +161,7 @@ static int local_pll397_enable(struct clk *clk, int enable)
 static int local_oscmain_enable(struct clk *clk, int enable)
 {
        u32 reg;
-       unsigned long timeout = 1 + msecs_to_jiffies(10);
+       unsigned long timeout = jiffies + msecs_to_jiffies(10);
 
        reg = __raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL);
 
@@ -171,7 +176,7 @@ static int local_oscmain_enable(struct clk *clk, int enable)
                /* Wait for main oscillator to start */
                while (((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) &
                        LPC32XX_CLKPWR_MOSC_DISABLE) != 0) &&
-                       (timeout > jiffies))
+                       time_before(jiffies, timeout))
                        cpu_relax();
 
                if ((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) &
@@ -382,30 +387,62 @@ static u32 local_clk_usbpll_setup(struct clk_pll_setup *pHCLKPllSetup)
 static int local_usbpll_enable(struct clk *clk, int enable)
 {
        u32 reg;
-       int ret = -ENODEV;
-       unsigned long timeout = 1 + msecs_to_jiffies(10);
+       int ret = 0;
+       unsigned long timeout = jiffies + msecs_to_jiffies(20);
 
        reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
 
-       if (enable == 0) {
-               reg &= ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN1 |
-                       LPC32XX_CLKPWR_USBCTRL_CLK_EN2);
-               __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
-       } else if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP) {
+       __raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN2 |
+               LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP),
+               LPC32XX_CLKPWR_USB_CTRL);
+       __raw_writel(reg & ~LPC32XX_CLKPWR_USBCTRL_CLK_EN1,
+               LPC32XX_CLKPWR_USB_CTRL);
+
+       if (enable && usb_pll_valid && usb_pll_enable) {
+               ret = -ENODEV;
+               /*
+                * If the PLL rate has been previously set, then the rate
+                * in the PLL register is valid and can be enabled here.
+                * Otherwise, it needs to be enabled as part of setrate.
+                */
+
+               /*
+                * Gate clock into PLL
+                */
                reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1;
                __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
 
-               /* Wait for PLL lock */
-               while ((timeout > jiffies) & (ret == -ENODEV)) {
+               /*
+                * Enable PLL
+                */
+               reg |= LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP;
+               __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
+
+               /*
+                * Wait for PLL to lock
+                */
+               while (time_before(jiffies, timeout) && (ret == -ENODEV)) {
                        reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
                        if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_STS)
                                ret = 0;
+                       else
+                               udelay(10);
                }
 
+               /*
+                * Gate clock from PLL if PLL is locked
+                */
                if (ret == 0) {
-                       reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN2;
-                       __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
+                       __raw_writel(reg | LPC32XX_CLKPWR_USBCTRL_CLK_EN2,
+                               LPC32XX_CLKPWR_USB_CTRL);
+               } else {
+                       __raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN1 |
+                               LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP),
+                               LPC32XX_CLKPWR_USB_CTRL);
                }
+       } else if ((enable == 0) && usb_pll_valid  && usb_pll_enable) {
+               usb_pll_valid = 0;
+               usb_pll_enable = 0;
        }
 
        return ret;
@@ -423,7 +460,7 @@ static unsigned long local_usbpll_round_rate(struct clk *clk,
         */
        rate = rate * 1000;
 
-       clkin = clk->parent->rate;
+       clkin = clk->get_rate(clk);
        usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) &
                LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1;
        clkin = clkin / usbdiv;
@@ -437,7 +474,8 @@ static unsigned long local_usbpll_round_rate(struct clk *clk,
 
 static int local_usbpll_set_rate(struct clk *clk, unsigned long rate)
 {
-       u32 clkin, reg, usbdiv;
+       int ret = -ENODEV;
+       u32 clkin, usbdiv;
        struct clk_pll_setup pllsetup;
 
        /*
@@ -446,7 +484,7 @@ static int local_usbpll_set_rate(struct clk *clk, unsigned long rate)
         */
        rate = rate * 1000;
 
-       clkin = clk->get_rate(clk);
+       clkin = clk->get_rate(clk->parent);
        usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) &
                LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1;
        clkin = clkin / usbdiv;
@@ -455,22 +493,25 @@ static int local_usbpll_set_rate(struct clk *clk, unsigned long rate)
        if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0)
                return -EINVAL;
 
+       /*
+        * Disable PLL clocks during PLL change
+        */
        local_usbpll_enable(clk, 0);
-
-       reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
-       reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1;
-       __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
-
-       pllsetup.analog_on = 1;
+       pllsetup.analog_on = 0;
        local_clk_usbpll_setup(&pllsetup);
 
-       clk->rate = clk_check_pll_setup(clkin, &pllsetup);
+       /*
+        * Start USB PLL and check PLL status
+        */
+
+       usb_pll_valid = 1;
+       usb_pll_enable = 1;
 
-       reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
-       reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN2;
-       __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
+       ret = local_usbpll_enable(clk, 1);
+       if (ret >= 0)
+               clk->rate = clk_check_pll_setup(clkin, &pllsetup);
 
-       return 0;
+       return ret;
 }
 
 static struct clk clk_usbpll = {
@@ -719,6 +760,41 @@ static struct clk clk_tsc = {
        .get_rate       = local_return_parent_rate,
 };
 
+static int adc_onoff_enable(struct clk *clk, int enable)
+{
+       u32 tmp;
+       u32 divider;
+
+       /* Use PERIPH_CLOCK */
+       tmp = __raw_readl(LPC32XX_CLKPWR_ADC_CLK_CTRL_1);
+       tmp |= LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL;
+       /*
+        * Set clock divider so that we have equal to or less than
+        * 4.5MHz clock at ADC
+        */
+       divider = clk->get_rate(clk) / 4500000 + 1;
+       tmp |= divider;
+       __raw_writel(tmp, LPC32XX_CLKPWR_ADC_CLK_CTRL_1);
+
+       /* synchronize rate of this clock w/ actual HW setting */
+       clk->rate = clk->get_rate(clk->parent) / divider;
+
+       if (enable == 0)
+               __raw_writel(0, clk->enable_reg);
+       else
+               __raw_writel(clk->enable_mask, clk->enable_reg);
+
+       return 0;
+}
+
+static struct clk clk_adc = {
+       .parent         = &clk_pclk,
+       .enable         = adc_onoff_enable,
+       .enable_reg     = LPC32XX_CLKPWR_ADC_CLK_CTRL,
+       .enable_mask    = LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN,
+       .get_rate       = local_return_parent_rate,
+};
+
 static int mmc_onoff_enable(struct clk *clk, int enable)
 {
        u32 tmp;
@@ -891,20 +967,8 @@ static struct clk clk_lcd = {
        .enable_mask    = LPC32XX_CLKPWR_LCDCTRL_CLK_EN,
 };
 
-static inline void clk_lock(void)
-{
-       mutex_lock(&clkm_lock);
-}
-
-static inline void clk_unlock(void)
-{
-       mutex_unlock(&clkm_lock);
-}
-
 static void local_clk_disable(struct clk *clk)
 {
-       WARN_ON(clk->usecount == 0);
-
        /* Don't attempt to disable clock if it has no users */
        if (clk->usecount > 0) {
                clk->usecount--;
@@ -947,10 +1011,11 @@ static int local_clk_enable(struct clk *clk)
 int clk_enable(struct clk *clk)
 {
        int ret;
+       unsigned long flags;
 
-       clk_lock();
+       spin_lock_irqsave(&global_clkregs_lock, flags);
        ret = local_clk_enable(clk);
-       clk_unlock();
+       spin_unlock_irqrestore(&global_clkregs_lock, flags);
 
        return ret;
 }
@@ -961,9 +1026,11 @@ EXPORT_SYMBOL(clk_enable);
  */
 void clk_disable(struct clk *clk)
 {
-       clk_lock();
+       unsigned long flags;
+
+       spin_lock_irqsave(&global_clkregs_lock, flags);
        local_clk_disable(clk);
-       clk_unlock();
+       spin_unlock_irqrestore(&global_clkregs_lock, flags);
 }
 EXPORT_SYMBOL(clk_disable);
 
@@ -972,13 +1039,7 @@ EXPORT_SYMBOL(clk_disable);
  */
 unsigned long clk_get_rate(struct clk *clk)
 {
-       unsigned long rate;
-
-       clk_lock();
-       rate = clk->get_rate(clk);
-       clk_unlock();
-
-       return rate;
+       return clk->get_rate(clk);
 }
 EXPORT_SYMBOL(clk_get_rate);
 
@@ -994,11 +1055,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
         * the actual rate set as part of the peripheral dividers
         * instead of high level clock control
         */
-       if (clk->set_rate) {
-               clk_lock();
+       if (clk->set_rate)
                ret = clk->set_rate(clk, rate);
-               clk_unlock();
-       }
 
        return ret;
 }
@@ -1009,15 +1067,11 @@ EXPORT_SYMBOL(clk_set_rate);
  */
 long clk_round_rate(struct clk *clk, unsigned long rate)
 {
-       clk_lock();
-
        if (clk->round_rate)
                rate = clk->round_rate(clk, rate);
        else
                rate = clk->get_rate(clk);
 
-       clk_unlock();
-
        return rate;
 }
 EXPORT_SYMBOL(clk_round_rate);
@@ -1075,10 +1129,11 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK("dev:ssp1", NULL, clk_ssp1)
        _REGISTER_CLOCK("lpc32xx_keys.0", NULL, clk_kscan)
        _REGISTER_CLOCK("lpc32xx-nand.0", "nand_ck", clk_nand)
-       _REGISTER_CLOCK("tbd", "i2s0_ck", clk_i2s0)
-       _REGISTER_CLOCK("tbd", "i2s1_ck", clk_i2s1)
+       _REGISTER_CLOCK("lpc32xx-adc", NULL, clk_adc)
+       _REGISTER_CLOCK(NULL, "i2s0_ck", clk_i2s0)
+       _REGISTER_CLOCK(NULL, "i2s1_ck", clk_i2s1)
        _REGISTER_CLOCK("ts-lpc32xx", NULL, clk_tsc)
-       _REGISTER_CLOCK("dev:mmc0", "MCLK", clk_mmc)
+       _REGISTER_CLOCK("dev:mmc0", NULL, clk_mmc)
        _REGISTER_CLOCK("lpc-net.0", NULL, clk_net)
        _REGISTER_CLOCK("dev:clcd", NULL, clk_lcd)
        _REGISTER_CLOCK("lpc32xx_udc", "ck_usbd", clk_usbd)
index 369b152896cd7d7c4311a5766ded9428b2e74c87..bbbf063a74c2f36ff1e86fc7bbd5812038239a0e 100644 (file)
@@ -137,6 +137,75 @@ struct platform_device lpc32xx_rtc_device = {
        .resource = lpc32xx_rtc_resources,
 };
 
+/*
+ * ADC support
+ */
+static struct resource adc_resources[] = {
+       {
+               .start = LPC32XX_ADC_BASE,
+               .end = LPC32XX_ADC_BASE + SZ_4K - 1,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = IRQ_LPC32XX_TS_IRQ,
+               .end = IRQ_LPC32XX_TS_IRQ,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device lpc32xx_adc_device = {
+       .name =  "lpc32xx-adc",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(adc_resources),
+       .resource = adc_resources,
+};
+
+/*
+ * USB support
+ */
+/* The dmamask must be set for OHCI to work */
+static u64 ohci_dmamask = ~(u32) 0;
+static struct resource ohci_resources[] = {
+       {
+               .start = IO_ADDRESS(LPC32XX_USB_BASE),
+               .end = IO_ADDRESS(LPC32XX_USB_BASE + 0x100 - 1),
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = IRQ_LPC32XX_USB_HOST,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+struct platform_device lpc32xx_ohci_device = {
+       .name = "usb-ohci",
+       .id = -1,
+       .dev = {
+               .dma_mask = &ohci_dmamask,
+               .coherent_dma_mask = 0xFFFFFFFF,
+       },
+       .num_resources = ARRAY_SIZE(ohci_resources),
+       .resource = ohci_resources,
+};
+
+/*
+ * Network Support
+ */
+static struct resource net_resources[] = {
+       [0] = DEFINE_RES_MEM(LPC32XX_ETHERNET_BASE, SZ_4K),
+       [1] = DEFINE_RES_MEM(LPC32XX_IRAM_BASE, SZ_128K),
+       [2] = DEFINE_RES_IRQ(IRQ_LPC32XX_ETHERNET),
+};
+
+static u64 lpc32xx_mac_dma_mask = 0xffffffffUL;
+struct platform_device lpc32xx_net_device = {
+       .name = "lpc-eth",
+       .id = 0,
+       .dev = {
+               .dma_mask = &lpc32xx_mac_dma_mask,
+               .coherent_dma_mask = 0xffffffffUL,
+       },
+       .num_resources = ARRAY_SIZE(net_resources),
+       .resource = net_resources,
+};
+
 /*
  * Returns the unique ID for the device
  */
index 4b4e700343c14f89ecefb18af80810d031ba5a2d..68e45e8c9486139d2906a74622ee1d62f02a2c95 100644 (file)
@@ -19,6 +19,7 @@
 #ifndef __LPC32XX_COMMON_H
 #define __LPC32XX_COMMON_H
 
+#include <mach/board.h>
 #include <linux/platform_device.h>
 
 /*
@@ -29,7 +30,10 @@ extern struct platform_device lpc32xx_i2c0_device;
 extern struct platform_device lpc32xx_i2c1_device;
 extern struct platform_device lpc32xx_i2c2_device;
 extern struct platform_device lpc32xx_tsc_device;
+extern struct platform_device lpc32xx_adc_device;
 extern struct platform_device lpc32xx_rtc_device;
+extern struct platform_device lpc32xx_ohci_device;
+extern struct platform_device lpc32xx_net_device;
 
 /*
  * Other arch specific structures and functions
@@ -65,9 +69,7 @@ extern u32 clk_get_pclk_div(void);
  */
 extern void lpc32xx_get_uid(u32 devid[4]);
 
-extern void lpc32xx_watchdog_reset(void);
 extern u32 lpc32xx_return_iram_size(void);
-
 /*
  * Pointers used for sizing and copying suspend function data
  */
diff --git a/arch/arm/mach-lpc32xx/include/mach/board.h b/arch/arm/mach-lpc32xx/include/mach/board.h
new file mode 100644 (file)
index 0000000..52531ca
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * arm/arch/mach-lpc32xx/include/mach/board.h
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ASM_ARCH_BOARD_H
+#define __ASM_ARCH_BOARD_H
+
+extern u32 lpc32xx_return_iram_size(void);
+
+#endif  /* __ASM_ARCH_BOARD_H */
index 14ea8d1aadb55a577f2b2427ec5e4f05c5d8180f..c584f5bb164fe5d8cedf6bb9cc3d05767c8faac3 100644 (file)
 /*
  * Timer/counter register offsets
  */
-#define LCP32XX_TIMER_IR(x)                    io_p2v((x) + 0x00)
-#define LCP32XX_TIMER_TCR(x)                   io_p2v((x) + 0x04)
-#define LCP32XX_TIMER_TC(x)                    io_p2v((x) + 0x08)
-#define LCP32XX_TIMER_PR(x)                    io_p2v((x) + 0x0C)
-#define LCP32XX_TIMER_PC(x)                    io_p2v((x) + 0x10)
-#define LCP32XX_TIMER_MCR(x)                   io_p2v((x) + 0x14)
-#define LCP32XX_TIMER_MR0(x)                   io_p2v((x) + 0x18)
-#define LCP32XX_TIMER_MR1(x)                   io_p2v((x) + 0x1C)
-#define LCP32XX_TIMER_MR2(x)                   io_p2v((x) + 0x20)
-#define LCP32XX_TIMER_MR3(x)                   io_p2v((x) + 0x24)
-#define LCP32XX_TIMER_CCR(x)                   io_p2v((x) + 0x28)
-#define LCP32XX_TIMER_CR0(x)                   io_p2v((x) + 0x2C)
-#define LCP32XX_TIMER_CR1(x)                   io_p2v((x) + 0x30)
-#define LCP32XX_TIMER_CR2(x)                   io_p2v((x) + 0x34)
-#define LCP32XX_TIMER_CR3(x)                   io_p2v((x) + 0x38)
-#define LCP32XX_TIMER_EMR(x)                   io_p2v((x) + 0x3C)
-#define LCP32XX_TIMER_CTCR(x)                  io_p2v((x) + 0x70)
+#define LPC32XX_TIMER_IR(x)                    io_p2v((x) + 0x00)
+#define LPC32XX_TIMER_TCR(x)                   io_p2v((x) + 0x04)
+#define LPC32XX_TIMER_TC(x)                    io_p2v((x) + 0x08)
+#define LPC32XX_TIMER_PR(x)                    io_p2v((x) + 0x0C)
+#define LPC32XX_TIMER_PC(x)                    io_p2v((x) + 0x10)
+#define LPC32XX_TIMER_MCR(x)                   io_p2v((x) + 0x14)
+#define LPC32XX_TIMER_MR0(x)                   io_p2v((x) + 0x18)
+#define LPC32XX_TIMER_MR1(x)                   io_p2v((x) + 0x1C)
+#define LPC32XX_TIMER_MR2(x)                   io_p2v((x) + 0x20)
+#define LPC32XX_TIMER_MR3(x)                   io_p2v((x) + 0x24)
+#define LPC32XX_TIMER_CCR(x)                   io_p2v((x) + 0x28)
+#define LPC32XX_TIMER_CR0(x)                   io_p2v((x) + 0x2C)
+#define LPC32XX_TIMER_CR1(x)                   io_p2v((x) + 0x30)
+#define LPC32XX_TIMER_CR2(x)                   io_p2v((x) + 0x34)
+#define LPC32XX_TIMER_CR3(x)                   io_p2v((x) + 0x38)
+#define LPC32XX_TIMER_EMR(x)                   io_p2v((x) + 0x3C)
+#define LPC32XX_TIMER_CTCR(x)                  io_p2v((x) + 0x70)
 
 /*
  * ir register definitions
  */
-#define LCP32XX_TIMER_CNTR_MTCH_BIT(n)         (1 << ((n) & 0x3))
-#define LCP32XX_TIMER_CNTR_CAPT_BIT(n)         (1 << (4 + ((n) & 0x3)))
+#define LPC32XX_TIMER_CNTR_MTCH_BIT(n)         (1 << ((n) & 0x3))
+#define LPC32XX_TIMER_CNTR_CAPT_BIT(n)         (1 << (4 + ((n) & 0x3)))
 
 /*
  * tcr register definitions
  */
-#define LCP32XX_TIMER_CNTR_TCR_EN              0x1
-#define LCP32XX_TIMER_CNTR_TCR_RESET           0x2
+#define LPC32XX_TIMER_CNTR_TCR_EN              0x1
+#define LPC32XX_TIMER_CNTR_TCR_RESET           0x2
 
 /*
  * mcr register definitions
  */
-#define LCP32XX_TIMER_CNTR_MCR_MTCH(n)         (0x1 << ((n) * 3))
-#define LCP32XX_TIMER_CNTR_MCR_RESET(n)                (0x1 << (((n) * 3) + 1))
-#define LCP32XX_TIMER_CNTR_MCR_STOP(n)         (0x1 << (((n) * 3) + 2))
+#define LPC32XX_TIMER_CNTR_MCR_MTCH(n)         (0x1 << ((n) * 3))
+#define LPC32XX_TIMER_CNTR_MCR_RESET(n)                (0x1 << (((n) * 3) + 1))
+#define LPC32XX_TIMER_CNTR_MCR_STOP(n)         (0x1 << (((n) * 3) + 2))
 
 /*
  * Standard UART register offsets
 #define LPC32XX_GPIO_P1_MUX_SET                        _GPREG(0x130)
 #define LPC32XX_GPIO_P1_MUX_CLR                        _GPREG(0x134)
 #define LPC32XX_GPIO_P1_MUX_STATE              _GPREG(0x138)
+#define LPC32XX_GPIO_P2_MUX_SET                        _GPREG(0x028)
+#define LPC32XX_GPIO_P2_MUX_CLR                        _GPREG(0x02C)
+#define LPC32XX_GPIO_P2_MUX_STATE              _GPREG(0x030)
 
 #endif
index c74de01ab5b61bf2cd95dbdb6559545ab85e8f96..d080cb1123dd184bef219710a730df47e123c27e 100644 (file)
@@ -150,6 +150,10 @@ static const struct lpc32xx_event_info lpc32xx_events[NR_IRQS] = {
                .event_group = &lpc32xx_event_int_regs,
                .mask = LPC32XX_CLKPWR_INTSRC_KEY_BIT,
        },
+       [IRQ_LPC32XX_ETHERNET] = {
+               .event_group = &lpc32xx_event_int_regs,
+               .mask = LPC32XX_CLKPWR_INTSRC_MAC_BIT,
+       },
        [IRQ_LPC32XX_USB_OTG_ATX] = {
                .event_group = &lpc32xx_event_int_regs,
                .mask = LPC32XX_CLKPWR_INTSRC_USBATXINT_BIT,
index 5d51c102c255ba8d7f71c58ee728fb79d15c980f..7f7401ec7487f58d6e932fd702e914ef3e4a2599 100644 (file)
@@ -37,6 +37,7 @@
 
 #include <mach/hardware.h>
 #include <mach/platform.h>
+#include <mach/board.h>
 #include <mach/gpio-lpc32xx.h>
 #include "common.h"
 
@@ -247,11 +248,16 @@ static struct platform_device lpc32xx_gpio_led_device = {
 };
 
 static struct platform_device *phy3250_devs[] __initdata = {
+       &lpc32xx_rtc_device,
+       &lpc32xx_tsc_device,
        &lpc32xx_i2c0_device,
        &lpc32xx_i2c1_device,
        &lpc32xx_i2c2_device,
        &lpc32xx_watchdog_device,
        &lpc32xx_gpio_led_device,
+       &lpc32xx_adc_device,
+       &lpc32xx_ohci_device,
+       &lpc32xx_net_device,
 };
 
 static struct amba_device *amba_devs[] __initdata = {
index b9c80597b7bf231841e572befd9fb83f1ba53fde..207e81275ff01277331eec126c736c397831a370 100644 (file)
@@ -13,7 +13,7 @@
 /*
  * LPC32XX CPU and system power management
  *
- * The LCP32XX has three CPU modes for controlling system power: run,
+ * The LPC32XX has three CPU modes for controlling system power: run,
  * direct-run, and halt modes. When switching between halt and run modes,
  * the CPU transistions through direct-run mode. For Linux, direct-run
  * mode is not used in normal operation. Halt mode is used when the
index b42c909bbeeb12634394ab4d1fcf1f4a5bb3d9ec..c40667c33161700450f9a93874efe5a30fc0d5a5 100644 (file)
 static int lpc32xx_clkevt_next_event(unsigned long delta,
     struct clock_event_device *dev)
 {
-       __raw_writel(LCP32XX_TIMER_CNTR_TCR_RESET,
-               LCP32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
-       __raw_writel(delta, LCP32XX_TIMER_PR(LPC32XX_TIMER0_BASE));
-       __raw_writel(LCP32XX_TIMER_CNTR_TCR_EN,
-               LCP32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
+       __raw_writel(LPC32XX_TIMER_CNTR_TCR_RESET,
+               LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
+       __raw_writel(delta, LPC32XX_TIMER_PR(LPC32XX_TIMER0_BASE));
+       __raw_writel(LPC32XX_TIMER_CNTR_TCR_EN,
+               LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
 
        return 0;
 }
@@ -58,7 +58,7 @@ static void lpc32xx_clkevt_mode(enum clock_event_mode mode,
                 * disable the timer to wait for the first call to
                 * set_next_event().
                 */
-               __raw_writel(0, LCP32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
+               __raw_writel(0, LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
                break;
 
        case CLOCK_EVT_MODE_UNUSED:
@@ -81,8 +81,8 @@ static irqreturn_t lpc32xx_timer_interrupt(int irq, void *dev_id)
        struct clock_event_device *evt = &lpc32xx_clkevt;
 
        /* Clear match */
-       __raw_writel(LCP32XX_TIMER_CNTR_MTCH_BIT(0),
-               LCP32XX_TIMER_IR(LPC32XX_TIMER0_BASE));
+       __raw_writel(LPC32XX_TIMER_CNTR_MTCH_BIT(0),
+               LPC32XX_TIMER_IR(LPC32XX_TIMER0_BASE));
 
        evt->event_handler(evt);
 
@@ -128,14 +128,14 @@ static void __init lpc32xx_timer_init(void)
        clkrate = clkrate / clk_get_pclk_div();
 
        /* Initial timer setup */
-       __raw_writel(0, LCP32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
-       __raw_writel(LCP32XX_TIMER_CNTR_MTCH_BIT(0),
-               LCP32XX_TIMER_IR(LPC32XX_TIMER0_BASE));
-       __raw_writel(1, LCP32XX_TIMER_MR0(LPC32XX_TIMER0_BASE));
-       __raw_writel(LCP32XX_TIMER_CNTR_MCR_MTCH(0) |
-               LCP32XX_TIMER_CNTR_MCR_STOP(0) |
-               LCP32XX_TIMER_CNTR_MCR_RESET(0),
-               LCP32XX_TIMER_MCR(LPC32XX_TIMER0_BASE));
+       __raw_writel(0, LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
+       __raw_writel(LPC32XX_TIMER_CNTR_MTCH_BIT(0),
+               LPC32XX_TIMER_IR(LPC32XX_TIMER0_BASE));
+       __raw_writel(1, LPC32XX_TIMER_MR0(LPC32XX_TIMER0_BASE));
+       __raw_writel(LPC32XX_TIMER_CNTR_MCR_MTCH(0) |
+               LPC32XX_TIMER_CNTR_MCR_STOP(0) |
+               LPC32XX_TIMER_CNTR_MCR_RESET(0),
+               LPC32XX_TIMER_MCR(LPC32XX_TIMER0_BASE));
 
        /* Setup tick interrupt */
        setup_irq(IRQ_LPC32XX_TIMER0, &lpc32xx_timer_irq);
@@ -151,14 +151,14 @@ static void __init lpc32xx_timer_init(void)
        clockevents_register_device(&lpc32xx_clkevt);
 
        /* Use timer1 as clock source. */
-       __raw_writel(LCP32XX_TIMER_CNTR_TCR_RESET,
-               LCP32XX_TIMER_TCR(LPC32XX_TIMER1_BASE));
-       __raw_writel(0, LCP32XX_TIMER_PR(LPC32XX_TIMER1_BASE));
-       __raw_writel(0, LCP32XX_TIMER_MCR(LPC32XX_TIMER1_BASE));
-       __raw_writel(LCP32XX_TIMER_CNTR_TCR_EN,
-               LCP32XX_TIMER_TCR(LPC32XX_TIMER1_BASE));
-
-       clocksource_mmio_init(LCP32XX_TIMER_TC(LPC32XX_TIMER1_BASE),
+       __raw_writel(LPC32XX_TIMER_CNTR_TCR_RESET,
+               LPC32XX_TIMER_TCR(LPC32XX_TIMER1_BASE));
+       __raw_writel(0, LPC32XX_TIMER_PR(LPC32XX_TIMER1_BASE));
+       __raw_writel(0, LPC32XX_TIMER_MCR(LPC32XX_TIMER1_BASE));
+       __raw_writel(LPC32XX_TIMER_CNTR_TCR_EN,
+               LPC32XX_TIMER_TCR(LPC32XX_TIMER1_BASE));
+
+       clocksource_mmio_init(LPC32XX_TIMER_TC(LPC32XX_TIMER1_BASE),
                "lpc32xx_clksrc", clkrate, 300, 32, clocksource_mmio_readl_up);
 }
 
index 323d4c9e9f44b5ad41cd8bc5b8e3777cb509a24c..5a90b9a3ab6efa753ef830171f8f5b6f97df9b5d 100644 (file)
@@ -2,6 +2,16 @@ if ARCH_MMP
 
 menu "Marvell PXA168/910/MMP2 Implmentations"
 
+config MACH_MMP_DT
+       bool "Support MMP2 platforms from device tree"
+       select CPU_PXA168
+       select CPU_PXA910
+       select USE_OF
+       help
+         Include support for Marvell MMP2 based platforms using
+         the device tree. Needn't select any other machine while
+         MACH_MMP_DT is enabled.
+
 config MACH_ASPENITE
        bool "Marvell's PXA168 Aspenite Development Board"
        select CPU_PXA168
index ba254a71691a6a1e81fb0f57a31c36578d18d64a..4fc0ff5dc96d70f4a700873a3a54f1f0e19cc69a 100644 (file)
@@ -18,5 +18,6 @@ obj-$(CONFIG_MACH_TTC_DKB)    += ttc_dkb.o
 obj-$(CONFIG_MACH_BROWNSTONE)  += brownstone.o
 obj-$(CONFIG_MACH_FLINT)       += flint.o
 obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o
+obj-$(CONFIG_MACH_MMP_DT)      += mmp-dt.o
 obj-$(CONFIG_MACH_TETON_BGA)   += teton_bga.o
 obj-$(CONFIG_MACH_GPLUGD)      += gplugd.o
index 4de13abef7bbf5a6413ca8fec3f647aee96a209e..e2e1f1e5e1249f908f7a8b531862d921abb00359 100644 (file)
@@ -22,6 +22,7 @@ extern struct pxa_device_desc pxa910_device_pwm4;
 extern struct pxa_device_desc pxa910_device_nand;
 
 extern struct platform_device pxa910_device_gpio;
+extern struct platform_device pxa910_device_rtc;
 
 static inline int pxa910_add_uart(int id)
 {
index 1a96585336ba12da9583e9ce10c9a6160fb932d2..8a37fb003655846a8491ca1b1aef5d851c1c0d26 100644 (file)
@@ -57,6 +57,7 @@
 #define APBC_PXA910_SSP1       APBC_REG(0x01c)
 #define APBC_PXA910_SSP2       APBC_REG(0x020)
 #define APBC_PXA910_IPC                APBC_REG(0x024)
+#define APBC_PXA910_RTC                APBC_REG(0x028)
 #define APBC_PXA910_TWSI0      APBC_REG(0x02c)
 #define APBC_PXA910_KPC                APBC_REG(0x030)
 #define APBC_PXA910_TIMERS     APBC_REG(0x034)
diff --git a/arch/arm/mach-mmp/include/mach/regs-rtc.h b/arch/arm/mach-mmp/include/mach/regs-rtc.h
new file mode 100644 (file)
index 0000000..5bff886
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef __ASM_MACH_REGS_RTC_H
+#define __ASM_MACH_REGS_RTC_H
+
+#include <mach/addr-map.h>
+
+#define RTC_VIRT_BASE  (APB_VIRT_BASE + 0x10000)
+#define RTC_REG(x)     (*((volatile u32 __iomem *)(RTC_VIRT_BASE + (x))))
+
+/*
+ * Real Time Clock
+ */
+
+#define RCNR           RTC_REG(0x00)   /* RTC Count Register */
+#define RTAR           RTC_REG(0x04)   /* RTC Alarm Register */
+#define RTSR           RTC_REG(0x08)   /* RTC Status Register */
+#define RTTR           RTC_REG(0x0C)   /* RTC Timer Trim Register */
+
+#define RTSR_HZE       (1 << 3)        /* HZ interrupt enable */
+#define RTSR_ALE       (1 << 2)        /* RTC alarm interrupt enable */
+#define RTSR_HZ                (1 << 1)        /* HZ rising-edge detected */
+#define RTSR_AL                (1 << 0)        /* RTC alarm detected */
+
+#endif /* __ASM_MACH_REGS_RTC_H */
diff --git a/arch/arm/mach-mmp/mmp-dt.c b/arch/arm/mach-mmp/mmp-dt.c
new file mode 100644 (file)
index 0000000..6707539
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *  linux/arch/arm/mach-mmp/mmp-dt.c
+ *
+ *  Copyright (C) 2012 Marvell Technology Group Ltd.
+ *  Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <mach/irqs.h>
+
+#include "common.h"
+
+extern struct sys_timer pxa168_timer;
+extern void __init icu_init_irq(void);
+
+static const struct of_dev_auxdata mmp_auxdata_lookup[] __initconst = {
+       OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.0", NULL),
+       OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.1", NULL),
+       OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4026000, "pxa2xx-uart.2", NULL),
+       OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL),
+       OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4025000, "pxa2xx-i2c.1", NULL),
+       OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "pxa-gpio", NULL),
+       OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd4010000, "sa1100-rtc", NULL),
+       {}
+};
+
+static int __init mmp_intc_add_irq_domain(struct device_node *np,
+                                          struct device_node *parent)
+{
+       irq_domain_add_simple(np, 0);
+       return 0;
+}
+
+static int __init mmp_gpio_add_irq_domain(struct device_node *np,
+                                          struct device_node *parent)
+{
+       irq_domain_add_simple(np, IRQ_GPIO_START);
+       return 0;
+}
+
+static const struct of_device_id mmp_irq_match[] __initconst = {
+       { .compatible = "mrvl,mmp-intc", .data = mmp_intc_add_irq_domain, },
+       { .compatible = "mrvl,mmp-gpio", .data = mmp_gpio_add_irq_domain, },
+       {}
+};
+
+static void __init mmp_dt_init(void)
+{
+
+       of_irq_init(mmp_irq_match);
+
+       of_platform_populate(NULL, of_default_bus_match_table,
+                            mmp_auxdata_lookup, NULL);
+}
+
+static const char *pxa168_dt_board_compat[] __initdata = {
+       "mrvl,pxa168-aspenite",
+       NULL,
+};
+
+DT_MACHINE_START(PXA168_DT, "Marvell PXA168 (Device Tree Support)")
+       .map_io         = mmp_map_io,
+       .init_irq       = icu_init_irq,
+       .timer          = &pxa168_timer,
+       .init_machine   = mmp_dt_init,
+       .dt_compat      = pxa168_dt_board_compat,
+MACHINE_END
index 617c60a170a4c1787327e738d428c042ada56869..c709a24a9d256fceaab077914ccc0e8cffc7b634 100644 (file)
@@ -223,6 +223,7 @@ struct resource mmp2_resource_gpio[] = {
        }, {
                .start  = IRQ_MMP2_GPIO,
                .end    = IRQ_MMP2_GPIO,
+               .name   = "gpio_mux",
                .flags  = IORESOURCE_IRQ,
        },
 };
index ada1213982b4a6da1d3abae4235385a724c3e235..f7d59c03fc670c18b9c82a978d4a44eacce00019 100644 (file)
@@ -64,6 +64,7 @@ static APBC_CLK(ssp4, PXA168_SSP4, 4, 0);
 static APBC_CLK(ssp5, PXA168_SSP5, 4, 0);
 static APBC_CLK(gpio, PXA168_GPIO, 0, 13000000);
 static APBC_CLK(keypad, PXA168_KPC, 0, 32000);
+static APBC_CLK(rtc, PXA168_RTC, 8, 32768);
 
 static APMU_CLK(nand, NAND, 0x19b, 156000000);
 static APMU_CLK(lcd, LCD, 0x7f, 312000000);
@@ -92,6 +93,7 @@ static struct clk_lookup pxa168_clkregs[] = {
        INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL),
        INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"),
        INIT_CLKREG(&clk_usb, "pxa168-ehci", "PXA168-USBCLK"),
+       INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
 };
 
 static int __init pxa168_init(void)
@@ -166,6 +168,7 @@ struct resource pxa168_resource_gpio[] = {
        }, {
                .start  = IRQ_PXA168_GPIOX,
                .end    = IRQ_PXA168_GPIOX,
+               .name   = "gpio_mux",
                .flags  = IORESOURCE_IRQ,
        },
 };
index 3241a25784d09b6c5ba83ba88752fcee5c7f9dd0..43f8bcc29b67734a733260381f256db6b1ce19e7 100644 (file)
@@ -92,6 +92,7 @@ static APBC_CLK(pwm2, PXA910_PWM2, 1, 13000000);
 static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000);
 static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000);
 static APBC_CLK(gpio, PXA910_GPIO, 0, 13000000);
+static APBC_CLK(rtc, PXA910_RTC, 8, 32768);
 
 static APMU_CLK(nand, NAND, 0x19b, 156000000);
 static APMU_CLK(u2o, USB, 0x1b, 480000000);
@@ -109,6 +110,7 @@ static struct clk_lookup pxa910_clkregs[] = {
        INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
        INIT_CLKREG(&clk_gpio, "pxa-gpio", NULL),
        INIT_CLKREG(&clk_u2o, "pxa-u2o", "U2OCLK"),
+       INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
 };
 
 static int __init pxa910_init(void)
@@ -173,6 +175,7 @@ struct resource pxa910_resource_gpio[] = {
        }, {
                .start  = IRQ_PXA910_AP_GPIO,
                .end    = IRQ_PXA910_AP_GPIO,
+               .name   = "gpio_mux",
                .flags  = IORESOURCE_IRQ,
        },
 };
@@ -183,3 +186,28 @@ struct platform_device pxa910_device_gpio = {
        .num_resources  = ARRAY_SIZE(pxa910_resource_gpio),
        .resource       = pxa910_resource_gpio,
 };
+
+static struct resource pxa910_resource_rtc[] = {
+       {
+               .start  = 0xd4010000,
+               .end    = 0xd401003f,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = IRQ_PXA910_RTC_INT,
+               .end    = IRQ_PXA910_RTC_INT,
+               .name   = "rtc 1Hz",
+               .flags  = IORESOURCE_IRQ,
+       }, {
+               .start  = IRQ_PXA910_RTC_ALARM,
+               .end    = IRQ_PXA910_RTC_ALARM,
+               .name   = "rtc alarm",
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device pxa910_device_rtc = {
+       .name           = "sa1100-rtc",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(pxa910_resource_rtc),
+       .resource       = pxa910_resource_rtc,
+};
index 5ac5d5832e450b7b4a6db27941c5eabd8a3f7816..e72c709da44f3e2461e6817c504ed571b909fecd 100644 (file)
@@ -124,6 +124,7 @@ static struct platform_device ttc_dkb_device_onenand = {
 
 static struct platform_device *ttc_dkb_devices[] = {
        &pxa910_device_gpio,
+       &pxa910_device_rtc,
        &ttc_dkb_device_onenand,
 };
 
index 11d0d8f2656cb92b4af676db094d758b1591094f..75f4be40b3e5d8f8ed98ab87e33282b685009999 100644 (file)
@@ -127,6 +127,45 @@ static struct clocksource msm_clocksource = {
        .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+#ifdef CONFIG_LOCAL_TIMERS
+static int __cpuinit msm_local_timer_setup(struct clock_event_device *evt)
+{
+       /* Use existing clock_event for cpu 0 */
+       if (!smp_processor_id())
+               return 0;
+
+       writel_relaxed(0, event_base + TIMER_ENABLE);
+       writel_relaxed(0, event_base + TIMER_CLEAR);
+       writel_relaxed(~0, event_base + TIMER_MATCH_VAL);
+       evt->irq = msm_clockevent.irq;
+       evt->name = "local_timer";
+       evt->features = msm_clockevent.features;
+       evt->rating = msm_clockevent.rating;
+       evt->set_mode = msm_timer_set_mode;
+       evt->set_next_event = msm_timer_set_next_event;
+       evt->shift = msm_clockevent.shift;
+       evt->mult = div_sc(GPT_HZ, NSEC_PER_SEC, evt->shift);
+       evt->max_delta_ns = clockevent_delta2ns(0xf0000000, evt);
+       evt->min_delta_ns = clockevent_delta2ns(4, evt);
+
+       *__this_cpu_ptr(msm_evt.percpu_evt) = evt;
+       clockevents_register_device(evt);
+       enable_percpu_irq(evt->irq, 0);
+       return 0;
+}
+
+static void msm_local_timer_stop(struct clock_event_device *evt)
+{
+       evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
+       disable_percpu_irq(evt->irq);
+}
+
+static struct local_timer_ops msm_local_timer_ops __cpuinitdata = {
+       .setup  = msm_local_timer_setup,
+       .stop   = msm_local_timer_stop,
+};
+#endif /* CONFIG_LOCAL_TIMERS */
+
 static void __init msm_timer_init(void)
 {
        struct clock_event_device *ce = &msm_clockevent;
@@ -173,8 +212,12 @@ static void __init msm_timer_init(void)
                *__this_cpu_ptr(msm_evt.percpu_evt) = ce;
                res = request_percpu_irq(ce->irq, msm_timer_interrupt,
                                         ce->name, msm_evt.percpu_evt);
-               if (!res)
+               if (!res) {
                        enable_percpu_irq(ce->irq, 0);
+#ifdef CONFIG_LOCAL_TIMERS
+                       local_timer_register(&msm_local_timer_ops);
+#endif
+               }
        } else {
                msm_evt.evt = ce;
                res = request_irq(ce->irq, msm_timer_interrupt,
@@ -191,40 +234,6 @@ err:
                pr_err("clocksource_register failed\n");
 }
 
-#ifdef CONFIG_LOCAL_TIMERS
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-       /* Use existing clock_event for cpu 0 */
-       if (!smp_processor_id())
-               return 0;
-
-       writel_relaxed(0, event_base + TIMER_ENABLE);
-       writel_relaxed(0, event_base + TIMER_CLEAR);
-       writel_relaxed(~0, event_base + TIMER_MATCH_VAL);
-       evt->irq = msm_clockevent.irq;
-       evt->name = "local_timer";
-       evt->features = msm_clockevent.features;
-       evt->rating = msm_clockevent.rating;
-       evt->set_mode = msm_timer_set_mode;
-       evt->set_next_event = msm_timer_set_next_event;
-       evt->shift = msm_clockevent.shift;
-       evt->mult = div_sc(GPT_HZ, NSEC_PER_SEC, evt->shift);
-       evt->max_delta_ns = clockevent_delta2ns(0xf0000000, evt);
-       evt->min_delta_ns = clockevent_delta2ns(4, evt);
-
-       *__this_cpu_ptr(msm_evt.percpu_evt) = evt;
-       clockevents_register_device(evt);
-       enable_percpu_irq(evt->irq, 0);
-       return 0;
-}
-
-void local_timer_stop(struct clock_event_device *evt)
-{
-       evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
-       disable_percpu_irq(evt->irq);
-}
-#endif /* CONFIG_LOCAL_TIMERS */
-
 struct sys_timer msm_timer = {
        .init = msm_timer_init
 };
index cf00b3e3be85177cd089bee0ec41b876069bf7da..c57f9964a713677ac0a5d93fdc0c89d0e16fe048 100644 (file)
@@ -83,6 +83,18 @@ config MODULE_M28
        select MXS_HAVE_PLATFORM_MXSFB
        select MXS_OCOTP
 
+config MODULE_APX4
+       bool
+       select SOC_IMX28
+       select LEDS_GPIO_REGISTER
+       select MXS_HAVE_AMBA_DUART
+       select MXS_HAVE_PLATFORM_AUART
+       select MXS_HAVE_PLATFORM_FEC
+       select MXS_HAVE_PLATFORM_MXS_I2C
+       select MXS_HAVE_PLATFORM_MXS_MMC
+       select MXS_HAVE_PLATFORM_MXS_SAIF
+       select MXS_OCOTP
+
 config MACH_TX28
        bool "Ka-Ro TX28 module"
        select MODULE_TX28
@@ -91,4 +103,8 @@ config MACH_M28EVK
        bool "Support DENX M28EVK Platform"
        select MODULE_M28
 
+config MACH_APX4DEVKIT
+       bool "Support Bluegiga APX4 Development Kit"
+       select MODULE_APX4
+
 endif
index 8c93b24896bf8571c02614cc5cc163d5eb0b888e..908bf9a567f18f490a81c708be9ddb9c4744fc40 100644 (file)
@@ -11,6 +11,7 @@ obj-$(CONFIG_MACH_STMP378X_DEVB) += mach-stmp378x_devb.o
 obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
 obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
 obj-$(CONFIG_MACH_M28EVK)    += mach-m28evk.o
+obj-$(CONFIG_MACH_APX4DEVKIT) += mach-apx4devkit.o
 obj-$(CONFIG_MODULE_TX28) += module-tx28.o
 obj-$(CONFIG_MACH_TX28)    += mach-tx28.o
 
index e12e11231dc7d8ace7fcdee3b2288a1b8efb7796..e3ac52c3401971678e8150ba1cea532218b75c8c 100644 (file)
@@ -223,7 +223,6 @@ static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
 {
        u32 reg, bm_busy, div_max, d, f, div, frac;
        unsigned long diff, parent_rate, calc_rate;
-       int i;
 
        parent_rate = clk_get_rate(clk->parent);
 
@@ -275,14 +274,7 @@ static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
        reg |= div << BP_CLKCTRL_CPU_DIV_CPU;
        __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
 
-       for (i = 10000; i; i--)
-               if (!(__raw_readl(CLKCTRL_BASE_ADDR +
-                                       HW_CLKCTRL_CPU) & bm_busy))
-                       break;
-       if (!i) {
-               pr_err("%s: divider writing timeout\n", __func__);
-               return -ETIMEDOUT;
-       }
+       mxs_clkctrl_timeout(HW_CLKCTRL_CPU, bm_busy);
 
        return 0;
 }
@@ -292,7 +284,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)             \
 {                                                                      \
        u32 reg, div_max, div;                                          \
        unsigned long parent_rate;                                      \
-       int i;                                                          \
                                                                        \
        parent_rate = clk_get_rate(clk->parent);                        \
        div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;       \
@@ -310,15 +301,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)            \
        }                                                               \
        __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);         \
                                                                        \
-       for (i = 10000; i; i--)                                         \
-               if (!(__raw_readl(CLKCTRL_BASE_ADDR +                   \
-                       HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY))     \
-                       break;                                          \
-       if (!i) {                                                       \
-               pr_err("%s: divider writing timeout\n", __func__);      \
-               return -ETIMEDOUT;                                      \
-       }                                                               \
-                                                                       \
+       mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY);   \
        return 0;                                                       \
 }
 
@@ -456,12 +439,13 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK("mxs-pwm.3", NULL, pwm_clk)
        _REGISTER_CLOCK("mxs-pwm.4", NULL, pwm_clk)
        _REGISTER_CLOCK("imx23-fb", NULL, lcdif_clk)
+       _REGISTER_CLOCK("imx23-gpmi-nand", NULL, gpmi_clk)
 };
 
 static int clk_misc_init(void)
 {
        u32 reg;
-       int i;
+       int ret;
 
        /* Fix up parent per register setting */
        reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
@@ -510,14 +494,7 @@ static int clk_misc_init(void)
        reg |= 3 << BP_CLKCTRL_HBUS_DIV;
        __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
 
-       for (i = 10000; i; i--)
-               if (!(__raw_readl(CLKCTRL_BASE_ADDR +
-                       HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_BUSY))
-                       break;
-       if (!i) {
-               pr_err("%s: divider writing timeout\n", __func__);
-               return -ETIMEDOUT;
-       }
+       ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_BUSY);
 
        /* Gate off cpu clock in WFI for power saving */
        __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
@@ -532,7 +509,7 @@ static int clk_misc_init(void)
        reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC;
        __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
 
-       return 0;
+       return ret;
 }
 
 int __init mx23_clocks_init(void)
index 5d68e415222026c327dd1cd47d285d74c673fcc9..cea29c99e2143c05d8ce878a9226604d16b346a8 100644 (file)
@@ -322,7 +322,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)             \
 {                                                                      \
        u32 reg, bm_busy, div_max, d, f, div, frac;                     \
        unsigned long diff, parent_rate, calc_rate;                     \
-       int i;                                                          \
                                                                        \
        div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;       \
        bm_busy = BM_CLKCTRL_##dr##_BUSY;                               \
@@ -396,16 +395,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)            \
        }                                                               \
        __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);         \
                                                                        \
-       for (i = 10000; i; i--)                                         \
-               if (!(__raw_readl(CLKCTRL_BASE_ADDR +                   \
-                       HW_CLKCTRL_##dr) & bm_busy))                    \
-                       break;                                          \
-       if (!i) {                                                       \
-               pr_err("%s: divider writing timeout\n", __func__);      \
-               return -ETIMEDOUT;                                      \
-       }                                                               \
-                                                                       \
-       return 0;                                                       \
+       return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, bm_busy);           \
 }
 
 _CLK_SET_RATE(cpu_clk, CPU, FRAC0, CPU)
@@ -421,7 +411,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)             \
 {                                                                      \
        u32 reg, div_max, div;                                          \
        unsigned long parent_rate;                                      \
-       int i;                                                          \
                                                                        \
        parent_rate = clk_get_rate(clk->parent);                        \
        div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;       \
@@ -439,16 +428,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)            \
        }                                                               \
        __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);         \
                                                                        \
-       for (i = 10000; i; i--)                                         \
-               if (!(__raw_readl(CLKCTRL_BASE_ADDR +                   \
-                       HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY))     \
-                       break;                                          \
-       if (!i) {                                                       \
-               pr_err("%s: divider writing timeout\n", __func__);      \
-               return -ETIMEDOUT;                                      \
-       }                                                               \
-                                                                       \
-       return 0;                                                       \
+       return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY);\
 }
 
 _CLK_SET_RATE1(xbus_clk, XBUS)
@@ -461,7 +441,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)             \
        u32 reg;                                                        \
        u64 lrate;                                                      \
        unsigned long parent_rate;                                      \
-       int i;                                                          \
                                                                        \
        parent_rate = clk_get_rate(clk->parent);                        \
        if (rate > parent_rate)                                         \
@@ -477,18 +456,13 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)           \
        reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);         \
        reg &= ~BM_CLKCTRL_##rs##_DIV;                                  \
        reg |= div << BP_CLKCTRL_##rs##_DIV;                            \
-       __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);         \
-                                                                       \
-       for (i = 10000; i; i--)                                         \
-               if (!(__raw_readl(CLKCTRL_BASE_ADDR +                   \
-                       HW_CLKCTRL_##rs) & BM_CLKCTRL_##rs##_BUSY))     \
-                       break;                                          \
-       if (!i) {                                                       \
-               pr_err("%s: divider writing timeout\n", __func__);      \
-               return -ETIMEDOUT;                                      \
+       if (reg & (1 << clk->enable_shift)) {                           \
+               pr_err("%s: clock is gated\n", __func__);               \
+               return -EINVAL;                                         \
        }                                                               \
+       __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);         \
                                                                        \
-       return 0;                                                       \
+       return mxs_clkctrl_timeout(HW_CLKCTRL_##rs, BM_CLKCTRL_##rs##_BUSY);\
 }
 
 _CLK_SET_RATE_SAIF(saif0_clk, SAIF0)
@@ -643,6 +617,7 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK("duart", NULL, uart_clk)
        _REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk)
        _REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk)
+       _REGISTER_CLOCK("imx28-gpmi-nand", NULL, gpmi_clk)
        _REGISTER_CLOCK("mxs-auart.0", NULL, uart_clk)
        _REGISTER_CLOCK("mxs-auart.1", NULL, uart_clk)
        _REGISTER_CLOCK("mxs-auart.2", NULL, uart_clk)
@@ -654,6 +629,8 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
        _REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk)
        _REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk)
+       _REGISTER_CLOCK("mxs-mmc.2", NULL, ssp2_clk)
+       _REGISTER_CLOCK("mxs-mmc.3", NULL, ssp3_clk)
        _REGISTER_CLOCK("flexcan.0", NULL, can0_clk)
        _REGISTER_CLOCK("flexcan.1", NULL, can1_clk)
        _REGISTER_CLOCK(NULL, "usb0", usb0_clk)
@@ -676,7 +653,7 @@ static struct clk_lookup lookups[] = {
 static int clk_misc_init(void)
 {
        u32 reg;
-       int i;
+       int ret;
 
        /* Fix up parent per register setting */
        reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
@@ -756,14 +733,7 @@ static int clk_misc_init(void)
        reg |= 3 << BP_CLKCTRL_HBUS_DIV;
        __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
 
-       for (i = 10000; i; i--)
-               if (!(__raw_readl(CLKCTRL_BASE_ADDR +
-                       HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_ASM_BUSY))
-                       break;
-       if (!i) {
-               pr_err("%s: divider writing timeout\n", __func__);
-               return -ETIMEDOUT;
-       }
+       ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_ASM_BUSY);
 
        /* Gate off cpu clock in WFI for power saving */
        __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
@@ -790,7 +760,7 @@ static int clk_misc_init(void)
        reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC;
        __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
 
-       return 0;
+       return ret;
 }
 
 int __init mx28_clocks_init(void)
@@ -803,6 +773,8 @@ int __init mx28_clocks_init(void)
         */
        clk_set_parent(&ssp0_clk, &ref_io0_clk);
        clk_set_parent(&ssp1_clk, &ref_io0_clk);
+       clk_set_parent(&ssp2_clk, &ref_io1_clk);
+       clk_set_parent(&ssp3_clk, &ref_io1_clk);
 
        clk_prepare_enable(&cpu_clk);
        clk_prepare_enable(&hbus_clk);
index 3fa651d2c994064df280a11109716b9f0b8e4282..4d1329d59287f543a845f453aac239c0bfc1875a 100644 (file)
@@ -21,6 +21,10 @@ extern const struct mxs_auart_data mx23_auart_data[] __initconst;
 #define mx23_add_auart0()              mx23_add_auart(0)
 #define mx23_add_auart1()              mx23_add_auart(1)
 
+extern const struct mxs_gpmi_nand_data mx23_gpmi_nand_data __initconst;
+#define mx23_add_gpmi_nand(pdata)      \
+       mxs_add_gpmi_nand(pdata, &mx23_gpmi_nand_data)
+
 extern const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst;
 #define mx23_add_mxs_mmc(id, pdata) \
        mxs_add_mxs_mmc(&mx23_mxs_mmc_data[id], pdata)
index 4f50094e293d35aa9cd28e980ae647e63c0beb8c..9dbeae130842b626522466764241b85cea105a75 100644 (file)
@@ -34,6 +34,10 @@ extern const struct mxs_flexcan_data mx28_flexcan_data[] __initconst;
 #define mx28_add_flexcan0(pdata)       mx28_add_flexcan(0, pdata)
 #define mx28_add_flexcan1(pdata)       mx28_add_flexcan(1, pdata)
 
+extern const struct mxs_gpmi_nand_data mx28_gpmi_nand_data __initconst;
+#define mx28_add_gpmi_nand(pdata)      \
+       mxs_add_gpmi_nand(pdata, &mx28_gpmi_nand_data)
+
 extern const struct mxs_mxs_i2c_data mx28_mxs_i2c_data[] __initconst;
 #define mx28_add_mxs_i2c(id)           mxs_add_mxs_i2c(&mx28_mxs_i2c_data[id])
 
index 18b6bf526a272242b1a0d03a78ee4b64b4209f7a..b8913df4cfa209402affd945457517f1b1ef8677 100644 (file)
@@ -12,6 +12,9 @@ config MXS_HAVE_PLATFORM_FLEXCAN
        select HAVE_CAN_FLEXCAN if CAN
        bool
 
+config MXS_HAVE_PLATFORM_GPMI_NAND
+       bool
+
 config MXS_HAVE_PLATFORM_MXS_I2C
        bool
 
index f52e3e53baecea42559efed2051e3ca6270cf944..c8f5c9541a302461ee56dcaf0d8bdff83445a38d 100644 (file)
@@ -3,6 +3,7 @@ obj-$(CONFIG_MXS_HAVE_PLATFORM_AUART) += platform-auart.o
 obj-y += platform-dma.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_GPMI_NAND) += platform-gpmi-nand.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_I2C) += platform-mxs-i2c.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_MMC) += platform-mxs-mmc.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_PWM) += platform-mxs-pwm.o
diff --git a/arch/arm/mach-mxs/devices/platform-gpmi-nand.c b/arch/arm/mach-mxs/devices/platform-gpmi-nand.c
new file mode 100644 (file)
index 0000000..3e22df5
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <asm/sizes.h>
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+#include <linux/dma-mapping.h>
+
+#ifdef CONFIG_SOC_IMX23
+const struct mxs_gpmi_nand_data mx23_gpmi_nand_data __initconst = {
+       .devid = "imx23-gpmi-nand",
+       .res = {
+               /* GPMI */
+               DEFINE_RES_MEM_NAMED(MX23_GPMI_BASE_ADDR, SZ_8K,
+                                       GPMI_NAND_GPMI_REGS_ADDR_RES_NAME),
+               DEFINE_RES_IRQ_NAMED(MX23_INT_GPMI_ATTENTION,
+                                       GPMI_NAND_GPMI_INTERRUPT_RES_NAME),
+               /* BCH */
+               DEFINE_RES_MEM_NAMED(MX23_BCH_BASE_ADDR, SZ_8K,
+                                       GPMI_NAND_BCH_REGS_ADDR_RES_NAME),
+               DEFINE_RES_IRQ_NAMED(MX23_INT_BCH,
+                                       GPMI_NAND_BCH_INTERRUPT_RES_NAME),
+               /* DMA */
+               DEFINE_RES_NAMED(MX23_DMA_GPMI0,
+                                       MX23_DMA_GPMI3 - MX23_DMA_GPMI0 + 1,
+                                       GPMI_NAND_DMA_CHANNELS_RES_NAME,
+                                       IORESOURCE_DMA),
+               DEFINE_RES_IRQ_NAMED(MX23_INT_GPMI_DMA,
+                                       GPMI_NAND_DMA_INTERRUPT_RES_NAME),
+       },
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_gpmi_nand_data mx28_gpmi_nand_data __initconst = {
+       .devid = "imx28-gpmi-nand",
+       .res = {
+               /* GPMI */
+               DEFINE_RES_MEM_NAMED(MX28_GPMI_BASE_ADDR, SZ_8K,
+                                       GPMI_NAND_GPMI_REGS_ADDR_RES_NAME),
+               DEFINE_RES_IRQ_NAMED(MX28_INT_GPMI,
+                                       GPMI_NAND_GPMI_INTERRUPT_RES_NAME),
+               /* BCH */
+               DEFINE_RES_MEM_NAMED(MX28_BCH_BASE_ADDR, SZ_8K,
+                                       GPMI_NAND_BCH_REGS_ADDR_RES_NAME),
+               DEFINE_RES_IRQ_NAMED(MX28_INT_BCH,
+                                       GPMI_NAND_BCH_INTERRUPT_RES_NAME),
+               /* DMA */
+               DEFINE_RES_NAMED(MX28_DMA_GPMI0,
+                                       MX28_DMA_GPMI7 - MX28_DMA_GPMI0 + 1,
+                                       GPMI_NAND_DMA_CHANNELS_RES_NAME,
+                                       IORESOURCE_DMA),
+               DEFINE_RES_IRQ_NAMED(MX28_INT_GPMI_DMA,
+                                       GPMI_NAND_DMA_INTERRUPT_RES_NAME),
+       },
+};
+#endif
+
+struct platform_device *__init
+mxs_add_gpmi_nand(const struct gpmi_nand_platform_data *pdata,
+               const struct mxs_gpmi_nand_data *data)
+{
+       return mxs_add_platform_device_dmamask(data->devid, -1,
+                               data->res, GPMI_NAND_RES_SIZE,
+                               pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
index 382dacbeca2107f5ef5d553b39566f1493dc0477..bef9d923f54e89e9288366ee2f54fa85c688d7d3 100644 (file)
@@ -41,6 +41,8 @@ const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst = {
 const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst = {
        mxs_mxs_mmc_data_entry(MX28, 0, 0),
        mxs_mxs_mmc_data_entry(MX28, 1, 1),
+       mxs_mxs_mmc_data_entry(MX28, 2, 2),
+       mxs_mxs_mmc_data_entry(MX28, 3, 3),
 };
 #endif
 
index e1237ab25862416f52de15a7812485d97f6a5f6c..c50c3ea28a9d843d3e84cab939a9371ed11c7221 100644 (file)
@@ -31,4 +31,6 @@ extern void mx28_init_irq(void);
 
 extern void icoll_init_irq(void);
 
+extern int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask);
+
 #endif /* __MACH_MXS_COMMON_H__ */
index dc369c1239fc3eac5a1c7d27968a3bf5c27f3912..f2e383955d88576b66ecb55962f9956908b11759 100644 (file)
@@ -66,6 +66,16 @@ struct platform_device *__init mxs_add_flexcan(
                const struct mxs_flexcan_data *data,
                const struct flexcan_platform_data *pdata);
 
+/* gpmi-nand */
+#include <linux/mtd/gpmi-nand.h>
+struct mxs_gpmi_nand_data {
+       const char *devid;
+       const struct resource res[GPMI_NAND_RES_SIZE];
+};
+struct platform_device *__init
+mxs_add_gpmi_nand(const struct gpmi_nand_platform_data *pdata,
+               const struct mxs_gpmi_nand_data *data);
+
 /* i2c */
 struct mxs_mxs_i2c_data {
        int id;
index 49a888c65d6df5d2b55c044e0f82099a9ab2dd06..17964066303f4f5b21ae80d56605148f00e70af5 100644 (file)
@@ -18,4 +18,5 @@
 #define HW_DIGCTL_CTRL                 0x0
 #define  BP_DIGCTL_CTRL_SAIF_CLKMUX    10
 #define  BM_DIGCTL_CTRL_SAIF_CLKMUX    (0x3 << 10)
+#define HW_DIGCTL_CHIPID               0x310
 #endif
index bde5f6634747c639af514ecf9d699b1176891802..7d4fb6d0afdafd189515639c01ffb0e86d6ea4e5 100644 (file)
 #include <linux/io.h>
 #endif
 #include <asm/mach-types.h>
+#include <mach/digctl.h>
 #include <mach/hardware.h>
 
-/*
- * MXS CPU types
- */
-#define cpu_is_mx23()          (                                       \
-               machine_is_mx23evk() ||                                 \
-               machine_is_stmp378x() ||                                \
-               0)
-#define cpu_is_mx28()          (                                       \
-               machine_is_mx28evk() ||                                 \
-               machine_is_m28evk() ||                                  \
-               machine_is_tx28() ||                                    \
-               0)
-
 /*
  * IO addresses common to MXS-based
  */
@@ -109,6 +97,21 @@ static inline void __mxs_togl(u32 mask, void __iomem *reg)
 {
        __raw_writel(mask, reg + MXS_TOG_ADDR);
 }
+
+/*
+ * MXS CPU types
+ */
+#define MXS_CHIPID (MXS_IO_ADDRESS(MXS_DIGCTL_BASE_ADDR) + HW_DIGCTL_CHIPID)
+
+static inline int cpu_is_mx23(void)
+{
+       return ((__raw_readl(MXS_CHIPID) >> 16) == 0x3780);
+}
+
+static inline int cpu_is_mx28(void)
+{
+       return ((__raw_readl(MXS_CHIPID) >> 16) == 0x2800);
+}
 #endif
 
 #endif /* __MACH_MXS_H__ */
index 67776746f143df5c4e2669cd5e10621aee0b90bf..ef28114954467007d2d6083a7b3540e5309ba490 100644 (file)
@@ -18,8 +18,6 @@
 #ifndef __MACH_MXS_UNCOMPRESS_H__
 #define __MACH_MXS_UNCOMPRESS_H__
 
-#include <asm/mach-types.h>
-
 unsigned long mxs_duart_base;
 
 #define MXS_DUART(x)   (*(volatile unsigned long *)(mxs_duart_base + (x)))
@@ -55,16 +53,17 @@ static inline void flush(void)
 
 #define MX23_DUART_BASE_ADDR   0x80070000
 #define MX28_DUART_BASE_ADDR   0x80074000
+#define MXS_DIGCTL_CHIPID      0x8001c310
 
 static inline void __arch_decomp_setup(unsigned long arch_id)
 {
-       switch (arch_id) {
-       case MACH_TYPE_MX23EVK:
+       u16 chipid = (*(volatile unsigned long *) MXS_DIGCTL_CHIPID) >> 16;
+
+       switch (chipid) {
+       case 0x3780:
                mxs_duart_base = MX23_DUART_BASE_ADDR;
                break;
-       case MACH_TYPE_MX28EVK:
-       case MACH_TYPE_M28EVK:
-       case MACH_TYPE_TX28:
+       case 0x2800:
                mxs_duart_base = MX28_DUART_BASE_ADDR;
                break;
        default:
diff --git a/arch/arm/mach-mxs/mach-apx4devkit.c b/arch/arm/mach-mxs/mach-apx4devkit.c
new file mode 100644 (file)
index 0000000..48a7fab
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2011-2012
+ * Lauri Hintsala, Bluegiga, <lauri.hintsala@bluegiga.com>
+ * Veli-Pekka Peltola, Bluegiga, <veli-pekka.peltola@bluegiga.com>
+ *
+ * based on: mach-mx28evk.c
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/micrel_phy.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/digctl.h>
+#include <mach/iomux-mx28.h>
+
+#include "devices-mx28.h"
+
+#define APX4DEVKIT_GPIO_USERLED        MXS_GPIO_NR(3, 28)
+
+static const iomux_cfg_t apx4devkit_pads[] __initconst = {
+       /* duart */
+       MX28_PAD_PWM0__DUART_RX | MXS_PAD_CTRL,
+       MX28_PAD_PWM1__DUART_TX | MXS_PAD_CTRL,
+
+       /* auart0 */
+       MX28_PAD_AUART0_RX__AUART0_RX | MXS_PAD_CTRL,
+       MX28_PAD_AUART0_TX__AUART0_TX | MXS_PAD_CTRL,
+       MX28_PAD_AUART0_CTS__AUART0_CTS | MXS_PAD_CTRL,
+       MX28_PAD_AUART0_RTS__AUART0_RTS | MXS_PAD_CTRL,
+
+       /* auart1 */
+       MX28_PAD_AUART1_RX__AUART1_RX | MXS_PAD_CTRL,
+       MX28_PAD_AUART1_TX__AUART1_TX | MXS_PAD_CTRL,
+
+       /* auart2 */
+       MX28_PAD_SSP2_SCK__AUART2_RX | MXS_PAD_CTRL,
+       MX28_PAD_SSP2_MOSI__AUART2_TX | MXS_PAD_CTRL,
+
+       /* auart3 */
+       MX28_PAD_SSP2_MISO__AUART3_RX | MXS_PAD_CTRL,
+       MX28_PAD_SSP2_SS0__AUART3_TX | MXS_PAD_CTRL,
+
+#define MXS_PAD_FEC    (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP)
+       /* fec0 */
+       MX28_PAD_ENET0_MDC__ENET0_MDC | MXS_PAD_FEC,
+       MX28_PAD_ENET0_MDIO__ENET0_MDIO | MXS_PAD_FEC,
+       MX28_PAD_ENET0_RX_EN__ENET0_RX_EN | MXS_PAD_FEC,
+       MX28_PAD_ENET0_RXD0__ENET0_RXD0 | MXS_PAD_FEC,
+       MX28_PAD_ENET0_RXD1__ENET0_RXD1 | MXS_PAD_FEC,
+       MX28_PAD_ENET0_TX_EN__ENET0_TX_EN | MXS_PAD_FEC,
+       MX28_PAD_ENET0_TXD0__ENET0_TXD0 | MXS_PAD_FEC,
+       MX28_PAD_ENET0_TXD1__ENET0_TXD1 | MXS_PAD_FEC,
+       MX28_PAD_ENET_CLK__CLKCTRL_ENET | MXS_PAD_FEC,
+
+       /* i2c */
+       MX28_PAD_I2C0_SCL__I2C0_SCL,
+       MX28_PAD_I2C0_SDA__I2C0_SDA,
+
+       /* mmc0 */
+       MX28_PAD_SSP0_DATA0__SSP0_D0 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SSP0_DATA1__SSP0_D1 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SSP0_DATA2__SSP0_D2 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SSP0_DATA3__SSP0_D3 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SSP0_DATA4__SSP0_D4 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SSP0_DATA5__SSP0_D5 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SSP0_DATA6__SSP0_D6 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SSP0_DATA7__SSP0_D7 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SSP0_CMD__SSP0_CMD |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+       MX28_PAD_SSP0_SCK__SSP0_SCK |
+               (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+
+       /* led */
+       MX28_PAD_PWM3__GPIO_3_28 | MXS_PAD_CTRL,
+
+       /* saif0 & saif1 */
+       MX28_PAD_SAIF0_MCLK__SAIF0_MCLK |
+               (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK |
+               (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK |
+               (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0 |
+               (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0 |
+               (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+};
+
+/* led */
+static const struct gpio_led apx4devkit_leds[] __initconst = {
+       {
+               .name = "user-led",
+               .default_trigger = "heartbeat",
+               .gpio = APX4DEVKIT_GPIO_USERLED,
+       },
+};
+
+static const struct gpio_led_platform_data apx4devkit_led_data __initconst = {
+       .leds = apx4devkit_leds,
+       .num_leds = ARRAY_SIZE(apx4devkit_leds),
+};
+
+static const struct fec_platform_data mx28_fec_pdata __initconst = {
+       .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static const struct mxs_mmc_platform_data apx4devkit_mmc_pdata __initconst = {
+       .wp_gpio = -EINVAL,
+       .flags = SLOTF_4_BIT_CAPABLE,
+};
+
+static const struct i2c_board_info apx4devkit_i2c_boardinfo[] __initconst = {
+       { I2C_BOARD_INFO("sgtl5000", 0x0a) }, /* ASoC */
+       { I2C_BOARD_INFO("pcf8563", 0x51) }, /* RTC */
+};
+
+#if defined(CONFIG_REGULATOR_FIXED_VOLTAGE) || \
+               defined(CONFIG_REGULATOR_FIXED_VOLTAGE_MODULE)
+static struct regulator_consumer_supply apx4devkit_audio_consumer_supplies[] = {
+       REGULATOR_SUPPLY("VDDA", "0-000a"),
+       REGULATOR_SUPPLY("VDDIO", "0-000a"),
+};
+
+static struct regulator_init_data apx4devkit_vdd_reg_init_data = {
+       .constraints    = {
+               .name   = "3V3",
+               .always_on = 1,
+       },
+       .consumer_supplies = apx4devkit_audio_consumer_supplies,
+       .num_consumer_supplies = ARRAY_SIZE(apx4devkit_audio_consumer_supplies),
+};
+
+static struct fixed_voltage_config apx4devkit_vdd_pdata = {
+       .supply_name    = "board-3V3",
+       .microvolts     = 3300000,
+       .gpio           = -EINVAL,
+       .enabled_at_boot = 1,
+       .init_data      = &apx4devkit_vdd_reg_init_data,
+};
+
+static struct platform_device apx4devkit_voltage_regulator = {
+       .name           = "reg-fixed-voltage",
+       .id             = -1,
+       .num_resources  = 0,
+       .dev            = {
+               .platform_data  = &apx4devkit_vdd_pdata,
+       },
+};
+
+static void __init apx4devkit_add_regulators(void)
+{
+       platform_device_register(&apx4devkit_voltage_regulator);
+}
+#else
+static void __init apx4devkit_add_regulators(void) {}
+#endif
+
+static const struct mxs_saif_platform_data
+                       apx4devkit_mxs_saif_pdata[] __initconst = {
+       /* working on EXTMSTR0 mode (saif0 master, saif1 slave) */
+       {
+               .master_mode = 1,
+               .master_id = 0,
+       }, {
+               .master_mode = 0,
+               .master_id = 0,
+       },
+};
+
+static int apx4devkit_phy_fixup(struct phy_device *phy)
+{
+       phy->dev_flags |= MICREL_PHY_50MHZ_CLK;
+       return 0;
+}
+
+static void __init apx4devkit_init(void)
+{
+       mxs_iomux_setup_multiple_pads(apx4devkit_pads,
+                       ARRAY_SIZE(apx4devkit_pads));
+
+       mx28_add_duart();
+       mx28_add_auart0();
+       mx28_add_auart1();
+       mx28_add_auart2();
+       mx28_add_auart3();
+
+       /*
+        * Register fixup for the Micrel KS8031 PHY clock
+        * (shares same ID with KS8051)
+        */
+       phy_register_fixup_for_uid(PHY_ID_KS8051, MICREL_PHY_ID_MASK,
+                       apx4devkit_phy_fixup);
+
+       mx28_add_fec(0, &mx28_fec_pdata);
+
+       mx28_add_mxs_mmc(0, &apx4devkit_mmc_pdata);
+
+       gpio_led_register_device(0, &apx4devkit_led_data);
+
+       mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0);
+       mx28_add_saif(0, &apx4devkit_mxs_saif_pdata[0]);
+       mx28_add_saif(1, &apx4devkit_mxs_saif_pdata[1]);
+
+       apx4devkit_add_regulators();
+
+       mx28_add_mxs_i2c(0);
+       i2c_register_board_info(0, apx4devkit_i2c_boardinfo,
+                       ARRAY_SIZE(apx4devkit_i2c_boardinfo));
+
+       mxs_add_platform_device("mxs-sgtl5000", 0, NULL, 0, NULL, 0);
+}
+
+static void __init apx4devkit_timer_init(void)
+{
+       mx28_clocks_init();
+}
+
+static struct sys_timer apx4devkit_timer = {
+       .init   = apx4devkit_timer_init,
+};
+
+MACHINE_START(APX4DEVKIT, "Bluegiga APX4 Development Kit")
+       .map_io         = mx28_map_io,
+       .init_irq       = mx28_init_irq,
+       .timer          = &apx4devkit_timer,
+       .init_machine   = apx4devkit_init,
+       .restart        = mxs_restart,
+MACHINE_END
index 2f2758230edf83f4cd98ae5a80817dd2b6c4e0ad..06d79963611ca0e4c0c174ad5a979280fc78b4e1 100644 (file)
@@ -247,18 +247,15 @@ static int __init m28evk_fec_get_mac(void)
        u32 val;
        const u32 *ocotp = mxs_get_ocotp();
 
-       if (!ocotp) {
-               pr_err("%s: timeout when reading fec mac from OCOTP\n",
-                       __func__);
+       if (!ocotp)
                return -ETIMEDOUT;
-       }
 
        /*
         * OCOTP only stores the last 4 octets for each mac address,
         * so hard-code DENX OUI (C0:E5:4E) here.
         */
        for (i = 0; i < 2; i++) {
-               val = ocotp[i * 4];
+               val = ocotp[i];
                mx28_fec_pdata[i].mac[0] = 0xC0;
                mx28_fec_pdata[i].mac[1] = 0xE5;
                mx28_fec_pdata[i].mac[2] = 0x4E;
index fdb0a5664dd68f7af7b6158c9db5ca94ffc1e174..e386c142f93c3f48286b5266e48fd56af788b63b 100644 (file)
@@ -223,7 +223,6 @@ static const struct gpio_led_platform_data mx28evk_led_data __initconst = {
 /* fec */
 static void __init mx28evk_fec_reset(void)
 {
-       int ret;
        struct clk *clk;
 
        /* Enable fec phy clock */
@@ -231,32 +230,7 @@ static void __init mx28evk_fec_reset(void)
        if (!IS_ERR(clk))
                clk_prepare_enable(clk);
 
-       /* Power up fec phy */
-       ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
-       if (ret) {
-               pr_err("Failed to request gpio fec-phy-%s: %d\n", "power", ret);
-               return;
-       }
-
-       ret = gpio_direction_output(MX28EVK_FEC_PHY_POWER, 0);
-       if (ret) {
-               pr_err("Failed to drive gpio fec-phy-%s: %d\n", "power", ret);
-               return;
-       }
-
-       /* Reset fec phy */
-       ret = gpio_request(MX28EVK_FEC_PHY_RESET, "fec-phy-reset");
-       if (ret) {
-               pr_err("Failed to request gpio fec-phy-%s: %d\n", "reset", ret);
-               return;
-       }
-
-       gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0);
-       if (ret) {
-               pr_err("Failed to drive gpio fec-phy-%s: %d\n", "reset", ret);
-               return;
-       }
-
+       gpio_set_value(MX28EVK_FEC_PHY_RESET, 0);
        mdelay(1);
        gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
 }
@@ -278,14 +252,14 @@ static int __init mx28evk_fec_get_mac(void)
        const u32 *ocotp = mxs_get_ocotp();
 
        if (!ocotp)
-               goto error;
+               return -ETIMEDOUT;
 
        /*
         * OCOTP only stores the last 4 octets for each mac address,
         * so hard-code Freescale OUI (00:04:9f) here.
         */
        for (i = 0; i < 2; i++) {
-               val = ocotp[i * 4];
+               val = ocotp[i];
                mx28_fec_pdata[i].mac[0] = 0x00;
                mx28_fec_pdata[i].mac[1] = 0x04;
                mx28_fec_pdata[i].mac[2] = 0x9f;
@@ -295,10 +269,6 @@ static int __init mx28evk_fec_get_mac(void)
        }
 
        return 0;
-
-error:
-       pr_err("%s: timeout when reading fec mac from OCOTP\n", __func__);
-       return -ETIMEDOUT;
 }
 
 /*
@@ -417,9 +387,14 @@ static void __init mx28evk_add_regulators(void)
 static void __init mx28evk_add_regulators(void) {}
 #endif
 
-static struct gpio mx28evk_lcd_gpios[] = {
+static const struct gpio mx28evk_gpios[] __initconst = {
        { MX28EVK_LCD_ENABLE, GPIOF_OUT_INIT_HIGH, "lcd-enable" },
        { MX28EVK_BL_ENABLE, GPIOF_OUT_INIT_HIGH, "bl-enable" },
+       { MX28EVK_FLEXCAN_SWITCH, GPIOF_DIR_OUT, "flexcan-switch" },
+       { MX28EVK_MMC0_SLOT_POWER, GPIOF_OUT_INIT_LOW, "mmc0-slot-power" },
+       { MX28EVK_MMC1_SLOT_POWER, GPIOF_OUT_INIT_LOW, "mmc1-slot-power" },
+       { MX28EVK_FEC_PHY_POWER, GPIOF_OUT_INIT_LOW, "fec-phy-power" },
+       { MX28EVK_FEC_PHY_RESET, GPIOF_DIR_OUT, "fec-phy-reset" },
 };
 
 static const struct mxs_saif_platform_data
@@ -447,25 +422,18 @@ static void __init mx28evk_init(void)
        if (mx28evk_fec_get_mac())
                pr_warn("%s: failed on fec mac setup\n", __func__);
 
+       ret = gpio_request_array(mx28evk_gpios, ARRAY_SIZE(mx28evk_gpios));
+       if (ret)
+               pr_err("One or more GPIOs failed to be requested: %d\n", ret);
+
        mx28evk_fec_reset();
        mx28_add_fec(0, &mx28_fec_pdata[0]);
        mx28_add_fec(1, &mx28_fec_pdata[1]);
 
-       ret = gpio_request_one(MX28EVK_FLEXCAN_SWITCH, GPIOF_DIR_OUT,
-                               "flexcan-switch");
-       if (ret) {
-               pr_err("failed to request gpio flexcan-switch: %d\n", ret);
-       } else {
-               mx28_add_flexcan(0, &mx28evk_flexcan_pdata[0]);
-               mx28_add_flexcan(1, &mx28evk_flexcan_pdata[1]);
-       }
+       mx28_add_flexcan(0, &mx28evk_flexcan_pdata[0]);
+       mx28_add_flexcan(1, &mx28evk_flexcan_pdata[1]);
 
-       ret = gpio_request_array(mx28evk_lcd_gpios,
-                                ARRAY_SIZE(mx28evk_lcd_gpios));
-       if (ret)
-               pr_warn("failed to request gpio pins for lcd: %d\n", ret);
-       else
-               mx28_add_mxsfb(&mx28evk_mxsfb_pdata);
+       mx28_add_mxsfb(&mx28evk_mxsfb_pdata);
 
        mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0);
        mx28_add_saif(0, &mx28evk_mxs_saif_pdata[0]);
@@ -480,20 +448,8 @@ static void __init mx28evk_init(void)
        mxs_add_platform_device("mxs-sgtl5000", 0, NULL, 0,
                        NULL, 0);
 
-       /* power on mmc slot by writing 0 to the gpio */
-       ret = gpio_request_one(MX28EVK_MMC0_SLOT_POWER, GPIOF_OUT_INIT_LOW,
-                              "mmc0-slot-power");
-       if (ret)
-               pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret);
-       else
-               mx28_add_mxs_mmc(0, &mx28evk_mmc_pdata[0]);
-
-       ret = gpio_request_one(MX28EVK_MMC1_SLOT_POWER, GPIOF_OUT_INIT_LOW,
-                              "mmc1-slot-power");
-       if (ret)
-               pr_warn("failed to request gpio mmc1-slot-power: %d\n", ret);
-       else
-               mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]);
+       mx28_add_mxs_mmc(0, &mx28evk_mmc_pdata[0]);
+       mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]);
 
        mx28_add_rtc_stmp3xxx();
 
index 54f91ad1c9655eb734d7bd7eb410ce1c032bafe7..7aa5ac5d78bf13db1a7cab575708863e8820cd2b 100644 (file)
@@ -37,6 +37,8 @@
 #define MXS_MODULE_CLKGATE             (1 << 30)
 #define MXS_MODULE_SFTRST              (1 << 31)
 
+#define CLKCTRL_TIMEOUT                10      /* 10 ms */
+
 static void __iomem *mxs_clkctrl_reset_addr;
 
 /*
@@ -137,3 +139,17 @@ error:
        return -ETIMEDOUT;
 }
 EXPORT_SYMBOL(mxs_reset_block);
+
+int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask)
+{
+       unsigned long timeout = jiffies + msecs_to_jiffies(CLKCTRL_TIMEOUT);
+       while (readl_relaxed(MXS_IO_ADDRESS(MXS_CLKCTRL_BASE_ADDR)
+                                               + reg_offset) & mask) {
+               if (time_after(jiffies, timeout)) {
+                       pr_err("Timeout at CLKCTRL + 0x%x\n", reg_offset);
+                       return -ETIMEDOUT;
+               }
+       }
+
+       return 0;
+}
index f6f74adbe8c40ea7861abf8f3ed87297c3a56472..58cacafcf6628758a27623abb8f8be1b1b240317 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
+#include <asm/mach/time.h>
 
 #include <plat/gpio-nomadik.h>
 #include <plat/mtu.h>
 
-#include <mach/setup.h>
 #include <mach/nand.h>
 #include <mach/fsmc.h>
 
@@ -246,10 +246,7 @@ static void __init nomadik_timer_init(void)
        src_cr |= SRC_CR_INIT_VAL;
        writel(src_cr, io_p2v(NOMADIK_SRC_BASE));
 
-       /* Save global pointer to mtu, used by platform timer code */
-       mtu_base = io_p2v(NOMADIK_MTU0_BASE);
-
-       nmdk_timer_init();
+       nmdk_timer_init(io_p2v(NOMADIK_MTU0_BASE));
 }
 
 static struct sys_timer nomadik_timer = {
diff --git a/arch/arm/mach-nomadik/include/mach/setup.h b/arch/arm/mach-nomadik/include/mach/setup.h
deleted file mode 100644 (file)
index bcaeaf4..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-
-/*
- * These symbols are needed for board-specific files to call their
- * own cpu-specific files
- */
-
-#ifndef __ASM_ARCH_SETUP_H
-#define __ASM_ARCH_SETUP_H
-
-#include <asm/mach/time.h>
-#include <linux/init.h>
-
-#ifdef CONFIG_NOMADIK_8815
-
-extern void nmdk_timer_init(void);
-
-#endif /* NOMADIK_8815 */
-
-#endif /*  __ASM_ARCH_SETUP_H */
index 922ab0dc2bcd339ef888e23c1839d5cb25efe6f2..dfab466ebd1d5b779357602b3fd39b2da026e652 100644 (file)
@@ -152,6 +152,10 @@ config MACH_AMS_DELTA
        bool "Amstrad E3 (Delta)"
        depends on ARCH_OMAP1 && ARCH_OMAP15XX
        select FIQ
+       select GPIO_GENERIC_PLATFORM
+       select LEDS_GPIO_REGISTER
+       select REGULATOR
+       select REGULATOR_FIXED_VOLTAGE
        help
          Support for the Amstrad E3 (codename Delta) videophone. Say Y here
          if you have such a device.
index c1c5fb6a5b4c511531775d0fff1dc2c69930e0f8..399c4c49722f91b093a05322bcd8bfb7dd64ed0b 100644 (file)
 
 #include <linux/linkage.h>
 
-#include <plat/io.h>
 #include <plat/board-ams-delta.h>
 
 #include <mach/ams-delta-fiq.h>
 
+#include "iomap.h"
+
 /*
  * GPIO related definitions, copied from arch/arm/plat-omap/gpio.c.
  * Unfortunately, those were not placed in a separate header file.
index 152b32c15e28be149c56a13b1dceee9e8148a730..fcce7ff3763052204587f43cdf8f9345c8cb1763 100644 (file)
@@ -22,6 +22,7 @@
 #include <plat/board-ams-delta.h>
 
 #include <asm/fiq.h>
+
 #include <mach/ams-delta-fiq.h>
 
 static struct fiq_handler fh = {
index e0e8245f3c9fd9c8510b772c4ddf44f0de752b2f..c1b681ef4cba80870ccec99715b14eb0ddfad07a 100644 (file)
@@ -11,6 +11,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/basic_mmio_gpio.h>
 #include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/leds.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
 #include <linux/serial_8250.h>
 #include <linux/export.h>
 #include <linux/omapfb.h>
+#include <linux/io.h>
 
 #include <media/soc_camera.h>
 
 #include <asm/serial.h>
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <plat/io.h>
 #include <plat/board-ams-delta.h>
 #include <plat/keypad.h>
 #include <plat/mux.h>
 #include <plat/usb.h>
 #include <plat/board.h>
-#include "common.h"
-#include <mach/camera.h>
 
+#include <mach/hardware.h>
 #include <mach/ams-delta-fiq.h>
+#include <mach/camera.h>
 
-static u8 ams_delta_latch1_reg;
-static u16 ams_delta_latch2_reg;
+#include "iomap.h"
+#include "common.h"
 
 static const unsigned int ams_delta_keymap[] = {
        KEY(0, 0, KEY_F1),              /* Advert    */
@@ -122,54 +125,188 @@ static const unsigned int ams_delta_keymap[] = {
        KEY(7, 3, KEY_LEFTCTRL),        /* Vol down  */
 };
 
-void ams_delta_latch1_write(u8 mask, u8 value)
-{
-       ams_delta_latch1_reg &= ~mask;
-       ams_delta_latch1_reg |= value;
-       *(volatile __u8 *) AMS_DELTA_LATCH1_VIRT = ams_delta_latch1_reg;
-}
-
-void ams_delta_latch2_write(u16 mask, u16 value)
-{
-       ams_delta_latch2_reg &= ~mask;
-       ams_delta_latch2_reg |= value;
-       *(volatile __u16 *) AMS_DELTA_LATCH2_VIRT = ams_delta_latch2_reg;
-}
+#define LATCH1_PHYS    0x01000000
+#define LATCH1_VIRT    0xEA000000
+#define MODEM_PHYS     0x04000000
+#define MODEM_VIRT     0xEB000000
+#define LATCH2_PHYS    0x08000000
+#define LATCH2_VIRT    0xEC000000
 
 static struct map_desc ams_delta_io_desc[] __initdata = {
        /* AMS_DELTA_LATCH1 */
        {
-               .virtual        = AMS_DELTA_LATCH1_VIRT,
-               .pfn            = __phys_to_pfn(AMS_DELTA_LATCH1_PHYS),
+               .virtual        = LATCH1_VIRT,
+               .pfn            = __phys_to_pfn(LATCH1_PHYS),
                .length         = 0x01000000,
                .type           = MT_DEVICE
        },
        /* AMS_DELTA_LATCH2 */
        {
-               .virtual        = AMS_DELTA_LATCH2_VIRT,
-               .pfn            = __phys_to_pfn(AMS_DELTA_LATCH2_PHYS),
+               .virtual        = LATCH2_VIRT,
+               .pfn            = __phys_to_pfn(LATCH2_PHYS),
                .length         = 0x01000000,
                .type           = MT_DEVICE
        },
        /* AMS_DELTA_MODEM */
        {
-               .virtual        = AMS_DELTA_MODEM_VIRT,
-               .pfn            = __phys_to_pfn(AMS_DELTA_MODEM_PHYS),
+               .virtual        = MODEM_VIRT,
+               .pfn            = __phys_to_pfn(MODEM_PHYS),
                .length         = 0x01000000,
                .type           = MT_DEVICE
        }
 };
 
-static struct omap_lcd_config ams_delta_lcd_config = {
+static struct omap_lcd_config ams_delta_lcd_config __initdata = {
        .ctrl_name      = "internal",
 };
 
-static struct omap_usb_config ams_delta_usb_config __initdata = {
+static struct omap_usb_config ams_delta_usb_config = {
        .register_host  = 1,
        .hmc_mode       = 16,
        .pins[0]        = 2,
 };
 
+#define LATCH1_GPIO_BASE       232
+#define LATCH1_NGPIO           8
+
+static struct resource latch1_resources[] = {
+       [0] = {
+               .name   = "dat",
+               .start  = LATCH1_PHYS,
+               .end    = LATCH1_PHYS + (LATCH1_NGPIO - 1) / 8,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct bgpio_pdata latch1_pdata = {
+       .base   = LATCH1_GPIO_BASE,
+       .ngpio  = LATCH1_NGPIO,
+};
+
+static struct platform_device latch1_gpio_device = {
+       .name           = "basic-mmio-gpio",
+       .id             = 0,
+       .resource       = latch1_resources,
+       .num_resources  = ARRAY_SIZE(latch1_resources),
+       .dev            = {
+               .platform_data  = &latch1_pdata,
+       },
+};
+
+static struct resource latch2_resources[] = {
+       [0] = {
+               .name   = "dat",
+               .start  = LATCH2_PHYS,
+               .end    = LATCH2_PHYS + (AMS_DELTA_LATCH2_NGPIO - 1) / 8,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct bgpio_pdata latch2_pdata = {
+       .base   = AMS_DELTA_LATCH2_GPIO_BASE,
+       .ngpio  = AMS_DELTA_LATCH2_NGPIO,
+};
+
+static struct platform_device latch2_gpio_device = {
+       .name           = "basic-mmio-gpio",
+       .id             = 1,
+       .resource       = latch2_resources,
+       .num_resources  = ARRAY_SIZE(latch2_resources),
+       .dev            = {
+               .platform_data  = &latch2_pdata,
+       },
+};
+
+static const struct gpio latch_gpios[] __initconst = {
+       {
+               .gpio   = LATCH1_GPIO_BASE + 6,
+               .flags  = GPIOF_OUT_INIT_LOW,
+               .label  = "dockit1",
+       },
+       {
+               .gpio   = LATCH1_GPIO_BASE + 7,
+               .flags  = GPIOF_OUT_INIT_LOW,
+               .label  = "dockit2",
+       },
+       {
+               .gpio   = AMS_DELTA_GPIO_PIN_SCARD_RSTIN,
+               .flags  = GPIOF_OUT_INIT_LOW,
+               .label  = "scard_rstin",
+       },
+       {
+               .gpio   = AMS_DELTA_GPIO_PIN_SCARD_CMDVCC,
+               .flags  = GPIOF_OUT_INIT_LOW,
+               .label  = "scard_cmdvcc",
+       },
+       {
+               .gpio   = AMS_DELTA_GPIO_PIN_MODEM_CODEC,
+               .flags  = GPIOF_OUT_INIT_LOW,
+               .label  = "modem_codec",
+       },
+       {
+               .gpio   = AMS_DELTA_LATCH2_GPIO_BASE + 14,
+               .flags  = GPIOF_OUT_INIT_LOW,
+               .label  = "hookflash1",
+       },
+       {
+               .gpio   = AMS_DELTA_LATCH2_GPIO_BASE + 15,
+               .flags  = GPIOF_OUT_INIT_LOW,
+               .label  = "hookflash2",
+       },
+};
+
+static struct regulator_consumer_supply modem_nreset_consumers[] = {
+       REGULATOR_SUPPLY("RESET#", "serial8250.1"),
+       REGULATOR_SUPPLY("POR", "cx20442-codec"),
+};
+
+static struct regulator_init_data modem_nreset_data = {
+       .constraints            = {
+               .valid_ops_mask         = REGULATOR_CHANGE_STATUS,
+               .boot_on                = 1,
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(modem_nreset_consumers),
+       .consumer_supplies      = modem_nreset_consumers,
+};
+
+static struct fixed_voltage_config modem_nreset_config = {
+       .supply_name            = "modem_nreset",
+       .microvolts             = 3300000,
+       .gpio                   = AMS_DELTA_GPIO_PIN_MODEM_NRESET,
+       .startup_delay          = 25000,
+       .enable_high            = 1,
+       .enabled_at_boot        = 1,
+       .init_data              = &modem_nreset_data,
+};
+
+static struct platform_device modem_nreset_device = {
+       .name   = "reg-fixed-voltage",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &modem_nreset_config,
+       },
+};
+
+struct modem_private_data {
+       struct regulator *regulator;
+};
+
+static struct modem_private_data modem_priv;
+
+void ams_delta_latch_write(int base, int ngpio, u16 mask, u16 value)
+{
+       int bit = 0;
+       u16 bitpos = 1 << bit;
+
+       for (; bit < ngpio; bit++, bitpos = bitpos << 1) {
+               if (!(mask & bitpos))
+                       continue;
+               else
+                       gpio_set_value(base + bit, (value & bitpos) != 0);
+       }
+}
+EXPORT_SYMBOL(ams_delta_latch_write);
+
 static struct resource ams_delta_nand_resources[] = {
        [0] = {
                .start  = OMAP1_MPUIO_BASE,
@@ -199,7 +336,7 @@ static const struct matrix_keymap_data ams_delta_keymap_data = {
        .keymap_size    = ARRAY_SIZE(ams_delta_keymap),
 };
 
-static struct omap_kp_platform_data ams_delta_kp_data __initdata = {
+static struct omap_kp_platform_data ams_delta_kp_data = {
        .rows           = 8,
        .cols           = 8,
        .keymap_data    = &ams_delta_keymap_data,
@@ -221,9 +358,45 @@ static struct platform_device ams_delta_lcd_device = {
        .id     = -1,
 };
 
-static struct platform_device ams_delta_led_device = {
-       .name   = "ams-delta-led",
-       .id     = -1
+static const struct gpio_led gpio_leds[] __initconst = {
+       {
+               .name            = "camera",
+               .gpio            = LATCH1_GPIO_BASE + 0,
+               .default_state   = LEDS_GPIO_DEFSTATE_OFF,
+#ifdef CONFIG_LEDS_TRIGGERS
+               .default_trigger = "ams_delta_camera",
+#endif
+       },
+       {
+               .name            = "advert",
+               .gpio            = LATCH1_GPIO_BASE + 1,
+               .default_state   = LEDS_GPIO_DEFSTATE_OFF,
+       },
+       {
+               .name            = "email",
+               .gpio            = LATCH1_GPIO_BASE + 2,
+               .default_state   = LEDS_GPIO_DEFSTATE_OFF,
+       },
+       {
+               .name            = "handsfree",
+               .gpio            = LATCH1_GPIO_BASE + 3,
+               .default_state   = LEDS_GPIO_DEFSTATE_OFF,
+       },
+       {
+               .name            = "voicemail",
+               .gpio            = LATCH1_GPIO_BASE + 4,
+               .default_state   = LEDS_GPIO_DEFSTATE_OFF,
+       },
+       {
+               .name            = "voice",
+               .gpio            = LATCH1_GPIO_BASE + 5,
+               .default_state   = LEDS_GPIO_DEFSTATE_OFF,
+       },
+};
+
+static const struct gpio_led_platform_data leds_pdata __initconst = {
+       .leds           = gpio_leds,
+       .num_leds       = ARRAY_SIZE(gpio_leds),
 };
 
 static struct i2c_board_info ams_delta_camera_board_info[] = {
@@ -272,13 +445,17 @@ static struct omap1_cam_platform_data ams_delta_camera_platform_data = {
 };
 
 static struct platform_device *ams_delta_devices[] __initdata = {
-       &ams_delta_nand_device,
+       &latch1_gpio_device,
+       &latch2_gpio_device,
        &ams_delta_kp_device,
-       &ams_delta_lcd_device,
-       &ams_delta_led_device,
        &ams_delta_camera_device,
 };
 
+static struct platform_device *late_devices[] __initdata = {
+       &ams_delta_nand_device,
+       &ams_delta_lcd_device,
+};
+
 static void __init ams_delta_init(void)
 {
        /* mux pins for uarts */
@@ -302,15 +479,13 @@ static void __init ams_delta_init(void)
        omap_serial_init();
        omap_register_i2c_bus(1, 100, NULL, 0);
 
-       /* Clear latch2 (NAND, LCD, modem enable) */
-       ams_delta_latch2_write(~0, 0);
-
        omap1_usb_init(&ams_delta_usb_config);
        omap1_set_camera_info(&ams_delta_camera_platform_data);
 #ifdef CONFIG_LEDS_TRIGGERS
        led_trigger_register_simple("ams_delta_camera",
                        &ams_delta_camera_led_trigger);
 #endif
+       gpio_led_register_device(-1, &leds_pdata);
        platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
 
        ams_delta_init_fiq();
@@ -320,16 +495,34 @@ static void __init ams_delta_init(void)
        omapfb_set_lcd_config(&ams_delta_lcd_config);
 }
 
+static void modem_pm(struct uart_port *port, unsigned int state, unsigned old)
+{
+       struct modem_private_data *priv = port->private_data;
+
+       if (IS_ERR(priv->regulator))
+               return;
+
+       if (state == old)
+               return;
+
+       if (state == 0)
+               regulator_enable(priv->regulator);
+       else if (old == 0)
+               regulator_disable(priv->regulator);
+}
+
 static struct plat_serial8250_port ams_delta_modem_ports[] = {
        {
-               .membase        = IOMEM(AMS_DELTA_MODEM_VIRT),
-               .mapbase        = AMS_DELTA_MODEM_PHYS,
+               .membase        = IOMEM(MODEM_VIRT),
+               .mapbase        = MODEM_PHYS,
                .irq            = -EINVAL, /* changed later */
                .flags          = UPF_BOOT_AUTOCONF,
                .irqflags       = IRQF_TRIGGER_RISING,
                .iotype         = UPIO_MEM,
                .regshift       = 1,
                .uartclk        = BASE_BAUD * 16,
+               .pm             = modem_pm,
+               .private_data   = &modem_priv,
        },
        { },
 };
@@ -342,13 +535,27 @@ static struct platform_device ams_delta_modem_device = {
        },
 };
 
-static int __init ams_delta_modem_init(void)
+static int __init late_init(void)
 {
        int err;
 
        if (!machine_is_ams_delta())
                return -ENODEV;
 
+       err = gpio_request_array(latch_gpios, ARRAY_SIZE(latch_gpios));
+       if (err) {
+               pr_err("Couldn't take over latch1/latch2 GPIO pins\n");
+               return err;
+       }
+
+       platform_add_devices(late_devices, ARRAY_SIZE(late_devices));
+
+       err = platform_device_register(&modem_nreset_device);
+       if (err) {
+               pr_err("Couldn't register the modem regulator device\n");
+               return err;
+       }
+
        omap_cfg_reg(M14_1510_GPIO2);
        ams_delta_modem_ports[0].irq =
                        gpio_to_irq(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
@@ -360,13 +567,35 @@ static int __init ams_delta_modem_init(void)
        }
        gpio_direction_input(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
 
-       ams_delta_latch2_write(
-               AMS_DELTA_LATCH2_MODEM_NRESET | AMS_DELTA_LATCH2_MODEM_CODEC,
-               AMS_DELTA_LATCH2_MODEM_NRESET | AMS_DELTA_LATCH2_MODEM_CODEC);
+       /* Initialize the modem_nreset regulator consumer before use */
+       modem_priv.regulator = ERR_PTR(-ENODEV);
+
+       ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC,
+                       AMS_DELTA_LATCH2_MODEM_CODEC);
 
-       return platform_device_register(&ams_delta_modem_device);
+       err = platform_device_register(&ams_delta_modem_device);
+       if (err)
+               goto gpio_free;
+
+       /*
+        * Once the modem device is registered, the modem_nreset
+        * regulator can be requested on behalf of that device.
+        */
+       modem_priv.regulator = regulator_get(&ams_delta_modem_device.dev,
+                       "RESET#");
+       if (IS_ERR(modem_priv.regulator)) {
+               err = PTR_ERR(modem_priv.regulator);
+               goto unregister;
+       }
+       return 0;
+
+unregister:
+       platform_device_unregister(&ams_delta_modem_device);
+gpio_free:
+       gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
+       return err;
 }
-arch_initcall(ams_delta_modem_init);
+late_initcall(late_init);
 
 static void __init ams_delta_map_io(void)
 {
@@ -385,6 +614,3 @@ MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
        .timer          = &omap1_timer,
        .restart        = omap1_restart,
 MACHINE_END
-
-EXPORT_SYMBOL(ams_delta_latch1_write);
-EXPORT_SYMBOL(ams_delta_latch2_write);
index 7afaf3c5bdc6f8bb0b99afc8609b1892015e9620..80bd43c7f4ec9563b3599f84ca9f51d614170cb8 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/smc91x.h>
 #include <linux/omapfb.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <plat/flash.h>
 #include <plat/fpga.h>
 #include <plat/keypad.h>
-#include "common.h"
 #include <plat/board.h>
 
+#include <mach/hardware.h>
+
+#include "iomap.h"
+#include "common.h"
+
 /* fsample is pretty close to p2-sample */
 
 #define fsample_cpld_read(reg) __raw_readb(reg)
index af2be8c12c072ab5fd69948183b4b88814f2c960..c3068622fdcbe8f06377a6f38984af5c39e77656 100644 (file)
@@ -32,8 +32,6 @@
 #include <linux/smc91x.h>
 #include <linux/omapfb.h>
 
-#include <mach/hardware.h>
-
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <plat/irda.h>
 #include <plat/usb.h>
 #include <plat/keypad.h>
-#include "common.h"
 #include <plat/flash.h>
 
+#include <mach/hardware.h>
+
+#include "common.h"
 #include "board-h2.h"
 
 /* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
index 7cfd25b90735cb6cbc00989083d8185bbc7d7c2c..64b8584f64cea13ba471b66890726d5199fd545f 100644 (file)
 
 #include <asm/setup.h>
 #include <asm/page.h>
-#include <mach/hardware.h>
-
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/irqs.h>
 #include <plat/mux.h>
 #include <plat/tc.h>
 #include <plat/usb.h>
 #include <plat/keypad.h>
 #include <plat/dma.h>
-#include "common.h"
 #include <plat/flash.h>
 
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+#include "common.h"
 #include "board-h3.h"
 
 /* In OMAP1710 H3 the Ethernet is directly connected to CS1 */
index af2afcf24f75ccee3fa306f3a8dc6dfa9e41bd5d..827d83a96af83a8510a9e680fbb3ad802b22e2ad 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
-#include <linux/io.h>
+#include <linux/delay.h>
 #include <linux/gpio.h>
 #include <linux/gpio_keys.h>
 #include <linux/i2c.h>
@@ -42,7 +42,6 @@
 #include <asm/mach/arch.h>
 
 #include <plat/omap7xx.h>
-#include "common.h"
 #include <plat/board.h>
 #include <plat/keypad.h>
 #include <plat/usb.h>
@@ -50,7 +49,7 @@
 
 #include <mach/irqs.h>
 
-#include <linux/delay.h>
+#include "common.h"
 
 /* LCD register definition */
 #define       OMAP_LCDC_CONTROL               (0xfffec000 + 0x00)
index 1d5ab6606b9f28c89830e0de61172e3df45a8e7e..61219182d16a5def3427d5b65c7812a36f8ba044 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/smc91x.h>
 #include <linux/omapfb.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <plat/tc.h>
 #include <plat/usb.h>
 #include <plat/keypad.h>
-#include "common.h"
 #include <plat/mmc.h>
 
+#include <mach/hardware.h>
+
+#include "iomap.h"
+#include "common.h"
+
 /* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
 #define INNOVATOR1610_ETHR_START       0x04000300
 
index 9b6332a31fb6e3769a861ef5fe1295e375705a47..fe95ec5f6f03f3597511be1a54c8cf8b90d464c8 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/workqueue.h>
 #include <linux/delay.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <plat/usb.h>
 #include <plat/board.h>
 #include <plat/keypad.h>
-#include "common.h"
 #include <plat/lcd_mipid.h>
 #include <plat/mmc.h>
 #include <plat/clock.h>
 
+#include <mach/hardware.h>
+
+#include "common.h"
+
 #define ADS7846_PENDOWN_GPIO   15
 
 static const unsigned int nokia770_keymap[] = {
index ef874655fbd3bd835068aa7324aa36d957ebe1fd..1fe347396f4d05a4b694f0e9476445c81a908417 100644 (file)
 #include <linux/leds.h>
 #include <linux/smc91x.h>
 #include <linux/omapfb.h>
-
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
-
 #include <linux/i2c/tps65010.h>
 
-#include <mach/hardware.h>
-
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -52,6 +48,9 @@
 #include <plat/usb.h>
 #include <plat/mux.h>
 #include <plat/tc.h>
+
+#include <mach/hardware.h>
+
 #include "common.h"
 
 /* At OMAP5912 OSK the Ethernet is directly connected to CS1 */
index 612342cb2a2d2598a41e2a8be4e787e7b9ae16c2..0863d8e2bdf147ed70467bb8a7fb5748e5b6c701 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/apm-emulation.h>
 #include <linux/omapfb.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -42,6 +41,9 @@
 #include <plat/board.h>
 #include <plat/irda.h>
 #include <plat/keypad.h>
+
+#include <mach/hardware.h>
+
 #include "common.h"
 
 #define PALMTE_USBDETECT_GPIO  0
index b63350bc88fd2c6f90f062597804a033ab083cdb..4ff699c509c0ebbce98a5c600e067e3a50ecc54b 100644 (file)
@@ -25,8 +25,9 @@
 #include <linux/mtd/physmap.h>
 #include <linux/leds.h>
 #include <linux/omapfb.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <plat/board.h>
 #include <plat/irda.h>
 #include <plat/keypad.h>
-#include "common.h"
 
-#include <linux/spi/spi.h>
-#include <linux/spi/ads7846.h>
+#include <mach/hardware.h>
+
+#include "common.h"
 
 #define PALMTT_USBDETECT_GPIO  0
 #define PALMTT_CABLE_GPIO      1
index 9924c70af09f1c13fe3ab8a37e663af7b288264a..abcbbd339aeb1df2baed04bbc34e8df47ed05cc8 100644 (file)
@@ -28,8 +28,9 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
 #include <linux/omapfb.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <plat/board.h>
 #include <plat/irda.h>
 #include <plat/keypad.h>
-#include "common.h"
 
-#include <linux/spi/spi.h>
-#include <linux/spi/ads7846.h>
+#include <mach/hardware.h>
+
+#include "common.h"
 
 #define PALMZ71_USBDETECT_GPIO 0
 #define PALMZ71_PENIRQ_GPIO    6
index 8e0153447c6d3aabc3df97049e14405899023980..76d4ee05a814783c9b12ecfb47bcfe9e5d43dc05 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/smc91x.h>
 #include <linux/omapfb.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <plat/fpga.h>
 #include <plat/flash.h>
 #include <plat/keypad.h>
-#include "common.h"
 #include <plat/board.h>
 
+#include <mach/hardware.h>
+
+#include "iomap.h"
+#include "common.h"
+
 static const unsigned int p2_keymap[] = {
        KEY(0, 0, KEY_UP),
        KEY(1, 0, KEY_RIGHT),
index 0c76e12337d92a780bd6ee7d600f867c9bd2dbb1..f34cb74a9f41d12cbe3983dcd121fa11f4ccb5cd 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/export.h>
 #include <linux/omapfb.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <plat/usb.h>
 #include <plat/tc.h>
 #include <plat/board.h>
-#include "common.h"
 #include <plat/keypad.h>
 #include <plat/board-sx1.h>
 
+#include <mach/hardware.h>
+
+#include "common.h"
+
 /* Write to I2C device */
 int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value)
 {
index f83a502dc93c7a45866ccbbc9c30c9c82afb9130..659d0f75de2c9e7965d0983e27a20eb833a7363f 100644 (file)
 #include <linux/smc91x.h>
 #include <linux/export.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
 #include <plat/board-voiceblue.h>
-#include "common.h"
 #include <plat/flash.h>
 #include <plat/mux.h>
 #include <plat/tc.h>
 #include <plat/usb.h>
 
+#include <mach/hardware.h>
+
+#include "common.h"
+
 static struct plat_serial8250_port voiceblue_ports[] = {
        {
                .mapbase        = (unsigned long)(OMAP_CS1_PHYS + 0x40000),
index 0c50df05d13559c059526341c2decbe274011f6a..67382ddd8c83fe7a4464a2c36d1a2d22979e437a 100644 (file)
@@ -15,8 +15,8 @@
 #include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/err.h>
-#include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/clk.h>
 #include <linux/clkdev.h>
 
 #include <asm/mach-types.h>
@@ -27,6 +27,9 @@
 #include <plat/sram.h>
 #include <plat/clkdev_omap.h>
 
+#include <mach/hardware.h>
+
+#include "iomap.h"
 #include "clock.h"
 #include "opp.h"
 
index 94699a82a7342a68140b7bb834e0de6a038101b7..c6ce93f71d08d5bb1bb1d546024dfdb2f363d1d0 100644 (file)
  */
 
 #include <linux/kernel.h>
+#include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/cpufreq.h>
 #include <linux/delay.h>
-#include <linux/io.h>
 
 #include <asm/mach-types.h>  /* for machine_is_* */
 
@@ -28,6 +28,9 @@
 #include <plat/sram.h> /* for omap_sram_reprogram_clock() */
 #include <plat/usb.h>   /* for OTG_BASE */
 
+#include <mach/hardware.h>
+
+#include "iomap.h"
 #include "clock.h"
 
 /* Some ARM_IDLECT1 bit shifts - used in struct arm_idlect1_clk */
index a9a5146dd2d4d3877f021780ef02b323b3669c9a..af658ad338ec8d253f3da5b649a3a6a27ae7df59 100644 (file)
@@ -58,5 +58,6 @@ void omap1_restart(char, const char *);
 
 extern struct sys_timer omap1_timer;
 extern bool omap_32k_timer_init(void);
+extern void __init omap_init_consistent_dma_size(void);
 
 #endif /* __ARCH_ARM_MACH_OMAP1_COMMON_H */
index 187b2fe132e98c08d0fd822532e8d7dfb2ac99c1..dcd8ddbec2bbc92b7577bc6f143d4085e3ec426f 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/io.h>
 #include <linux/spi/spi.h>
 
-#include <mach/camera.h>
-#include <mach/hardware.h>
 #include <asm/mach/map.h>
 
-#include "common.h"
 #include <plat/tc.h>
 #include <plat/board.h>
 #include <plat/mux.h>
 #include <plat/mmc.h>
 #include <plat/omap7xx.h>
 
+#include <mach/camera.h>
+#include <mach/hardware.h>
+
+#include "common.h"
 #include "clock.h"
 
 /*-------------------------------------------------------------------------*/
index f5a52204b89fa8e85908ab8f2566594575324027..3ef7d52316b49a959bce42fd142a3b8a61d9fd01 100644 (file)
  */
 
 #include <linux/err.h>
-#include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/io.h>
 
 #include <plat/dma.h>
 #include <plat/tc.h>
index 1749cb37dda0365985e6da1cc79e632f8564061b..f9bf78d4fdfb9681dd38f534477335f0617b9206 100644 (file)
@@ -6,13 +6,15 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 
-#include <plat/io.h>
 #include <plat/tc.h>
 #include <plat/flash.h>
 
+#include <mach/hardware.h>
+
 void omap1_set_vpp(struct platform_device *pdev, int enable)
 {
        static int count;
index 0a17a1a7e00d106aa80f169e3db59191ab5dbd65..76c67b3f9f61b9c4f00ffe12a5045195b58776a2 100644 (file)
 #include <linux/errno.h>
 #include <linux/io.h>
 
-#include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 
 #include <plat/fpga.h>
 
+#include <mach/hardware.h>
+
+#include "iomap.h"
+
 static void fpga_mask_irq(struct irq_data *d)
 {
        unsigned int irq = d->irq - OMAP_FPGA_IRQ_BASE;
index 399da4ce017bfb39d9134e869002710da6f28e20..634903ef82922686b67c2528ea21140e9e0957f8 100644 (file)
@@ -42,11 +42,12 @@ static struct omap_gpio_reg_offs omap15xx_mpuio_regs = {
        .irqstatus      = OMAP_MPUIO_GPIO_INT,
        .irqenable      = OMAP_MPUIO_GPIO_MASKIT,
        .irqenable_inv  = true,
+       .irqctrl        = OMAP_MPUIO_GPIO_INT_EDGE,
 };
 
 static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = {
        .virtual_irq_start      = IH_MPUIO_BASE,
-       .bank_type              = METHOD_MPUIO,
+       .is_mpuio               = true,
        .bank_width             = 16,
        .bank_stride            = 1,
        .regs                   = &omap15xx_mpuio_regs,
@@ -83,11 +84,12 @@ static struct omap_gpio_reg_offs omap15xx_gpio_regs = {
        .irqstatus      = OMAP1510_GPIO_INT_STATUS,
        .irqenable      = OMAP1510_GPIO_INT_MASK,
        .irqenable_inv  = true,
+       .irqctrl        = OMAP1510_GPIO_INT_CONTROL,
+       .pinctrl        = OMAP1510_GPIO_PIN_CONTROL,
 };
 
 static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = {
        .virtual_irq_start      = IH_GPIO_BASE,
-       .bank_type              = METHOD_GPIO_1510,
        .bank_width             = 16,
        .regs                   = &omap15xx_gpio_regs,
 };
@@ -115,7 +117,6 @@ static int __init omap15xx_gpio_init(void)
        platform_device_register(&omap15xx_mpu_gpio);
        platform_device_register(&omap15xx_gpio);
 
-       gpio_bank_count = 2;
        return 0;
 }
 postcore_initcall(omap15xx_gpio_init);
index 0f399bd0e70e7be70ee1eebc2603f8f877c63f4f..1fb3b9ad496e97c1af14317cdfd38d4bd9d9d503 100644 (file)
@@ -24,6 +24,9 @@
 #define OMAP1610_GPIO4_BASE            0xfffbbc00
 #define OMAP1_MPUIO_VBASE              OMAP1_MPUIO_BASE
 
+/* smart idle, enable wakeup */
+#define SYSCONFIG_WORD                 0x14
+
 /* mpu gpio */
 static struct __initdata resource omap16xx_mpu_gpio_resources[] = {
        {
@@ -45,11 +48,12 @@ static struct omap_gpio_reg_offs omap16xx_mpuio_regs = {
        .irqstatus      = OMAP_MPUIO_GPIO_INT,
        .irqenable      = OMAP_MPUIO_GPIO_MASKIT,
        .irqenable_inv  = true,
+       .irqctrl        = OMAP_MPUIO_GPIO_INT_EDGE,
 };
 
 static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = {
        .virtual_irq_start      = IH_MPUIO_BASE,
-       .bank_type              = METHOD_MPUIO,
+       .is_mpuio               = true,
        .bank_width             = 16,
        .bank_stride            = 1,
        .regs                   = &omap16xx_mpuio_regs,
@@ -89,11 +93,13 @@ static struct omap_gpio_reg_offs omap16xx_gpio_regs = {
        .irqenable      = OMAP1610_GPIO_IRQENABLE1,
        .set_irqenable  = OMAP1610_GPIO_SET_IRQENABLE1,
        .clr_irqenable  = OMAP1610_GPIO_CLEAR_IRQENABLE1,
+       .wkup_en        = OMAP1610_GPIO_WAKEUPENABLE,
+       .edgectrl1      = OMAP1610_GPIO_EDGE_CTRL1,
+       .edgectrl2      = OMAP1610_GPIO_EDGE_CTRL2,
 };
 
 static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = {
        .virtual_irq_start      = IH_GPIO_BASE,
-       .bank_type              = METHOD_GPIO_1610,
        .bank_width             = 16,
        .regs                   = &omap16xx_gpio_regs,
 };
@@ -123,7 +129,6 @@ static struct __initdata resource omap16xx_gpio2_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = {
        .virtual_irq_start      = IH_GPIO_BASE + 16,
-       .bank_type              = METHOD_GPIO_1610,
        .bank_width             = 16,
        .regs                   = &omap16xx_gpio_regs,
 };
@@ -153,7 +158,6 @@ static struct __initdata resource omap16xx_gpio3_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = {
        .virtual_irq_start      = IH_GPIO_BASE + 32,
-       .bank_type              = METHOD_GPIO_1610,
        .bank_width             = 16,
        .regs                   = &omap16xx_gpio_regs,
 };
@@ -183,7 +187,6 @@ static struct __initdata resource omap16xx_gpio4_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = {
        .virtual_irq_start      = IH_GPIO_BASE + 48,
-       .bank_type              = METHOD_GPIO_1610,
        .bank_width             = 16,
        .regs                   = &omap16xx_gpio_regs,
 };
@@ -214,14 +217,42 @@ static struct __initdata platform_device * omap16xx_gpio_dev[] = {
 static int __init omap16xx_gpio_init(void)
 {
        int i;
+       void __iomem *base;
+       struct resource *res;
+       struct platform_device *pdev;
+       struct omap_gpio_platform_data *pdata;
 
        if (!cpu_is_omap16xx())
                return -EINVAL;
 
-       for (i = 0; i < ARRAY_SIZE(omap16xx_gpio_dev); i++)
-               platform_device_register(omap16xx_gpio_dev[i]);
+       /*
+        * Enable system clock for GPIO module.
+        * The CAM_CLK_CTRL *is* really the right place.
+        */
+       omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04,
+                                       ULPD_CAM_CLK_CTRL);
+
+       for (i = 0; i < ARRAY_SIZE(omap16xx_gpio_dev); i++) {
+               pdev = omap16xx_gpio_dev[i];
+               pdata = pdev->dev.platform_data;
+
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+               if (unlikely(!res)) {
+                       dev_err(&pdev->dev, "Invalid mem resource.\n");
+                       return -ENODEV;
+               }
 
-       gpio_bank_count = ARRAY_SIZE(omap16xx_gpio_dev);
+               base = ioremap(res->start, resource_size(res));
+               if (unlikely(!base)) {
+                       dev_err(&pdev->dev, "ioremap failed.\n");
+                       return -ENOMEM;
+               }
+
+               __raw_writel(SYSCONFIG_WORD, base + OMAP1610_GPIO_SYSCONFIG);
+               iounmap(base);
+
+               platform_device_register(omap16xx_gpio_dev[i]);
+       }
 
        return 0;
 }
index 5ab63eab0ff5f18b52476172d90db7ee0d6afeeb..4771d6b68b96eb4c08820b1eab8c97790d306f5d 100644 (file)
@@ -47,12 +47,13 @@ static struct omap_gpio_reg_offs omap7xx_mpuio_regs = {
        .irqstatus      = OMAP_MPUIO_GPIO_INT / 2,
        .irqenable      = OMAP_MPUIO_GPIO_MASKIT / 2,
        .irqenable_inv  = true,
+       .irqctrl        = OMAP_MPUIO_GPIO_INT_EDGE >> 1,
 };
 
 static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = {
        .virtual_irq_start      = IH_MPUIO_BASE,
-       .bank_type              = METHOD_MPUIO,
-       .bank_width             = 32,
+       .is_mpuio               = true,
+       .bank_width             = 16,
        .bank_stride            = 2,
        .regs                   = &omap7xx_mpuio_regs,
 };
@@ -88,11 +89,11 @@ static struct omap_gpio_reg_offs omap7xx_gpio_regs = {
        .irqstatus      = OMAP7XX_GPIO_INT_STATUS,
        .irqenable      = OMAP7XX_GPIO_INT_MASK,
        .irqenable_inv  = true,
+       .irqctrl        = OMAP7XX_GPIO_INT_CONTROL,
 };
 
 static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = {
        .virtual_irq_start      = IH_GPIO_BASE,
-       .bank_type              = METHOD_GPIO_7XX,
        .bank_width             = 32,
        .regs                   = &omap7xx_gpio_regs,
 };
@@ -122,7 +123,6 @@ static struct __initdata resource omap7xx_gpio2_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = {
        .virtual_irq_start      = IH_GPIO_BASE + 32,
-       .bank_type              = METHOD_GPIO_7XX,
        .bank_width             = 32,
        .regs                   = &omap7xx_gpio_regs,
 };
@@ -152,7 +152,6 @@ static struct __initdata resource omap7xx_gpio3_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = {
        .virtual_irq_start      = IH_GPIO_BASE + 64,
-       .bank_type              = METHOD_GPIO_7XX,
        .bank_width             = 32,
        .regs                   = &omap7xx_gpio_regs,
 };
@@ -182,7 +181,6 @@ static struct __initdata resource omap7xx_gpio4_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = {
        .virtual_irq_start      = IH_GPIO_BASE + 96,
-       .bank_type              = METHOD_GPIO_7XX,
        .bank_width             = 32,
        .regs                   = &omap7xx_gpio_regs,
 };
@@ -212,7 +210,6 @@ static struct __initdata resource omap7xx_gpio5_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = {
        .virtual_irq_start      = IH_GPIO_BASE + 128,
-       .bank_type              = METHOD_GPIO_7XX,
        .bank_width             = 32,
        .regs                   = &omap7xx_gpio_regs,
 };
@@ -242,7 +239,6 @@ static struct __initdata resource omap7xx_gpio6_resources[] = {
 
 static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = {
        .virtual_irq_start      = IH_GPIO_BASE + 160,
-       .bank_type              = METHOD_GPIO_7XX,
        .bank_width             = 32,
        .regs                   = &omap7xx_gpio_regs,
 };
@@ -282,8 +278,6 @@ static int __init omap7xx_gpio_init(void)
        for (i = 0; i < ARRAY_SIZE(omap7xx_gpio_dev); i++)
                platform_device_register(omap7xx_gpio_dev[i]);
 
-       gpio_bank_count = ARRAY_SIZE(omap7xx_gpio_dev);
-
        return 0;
 }
 postcore_initcall(omap7xx_gpio_init);
index a0e3560b39db1e0cde7aff284927f5ba93db7d8d..f24c1e2c5044a37022ceee1f86ca774b6c257067 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
+
 #include <plat/cpu.h>
 
+#include <mach/hardware.h>
+
 #define OMAP_DIE_ID_0          0xfffe1800
 #define OMAP_DIE_ID_1          0xfffe1804
 #define OMAP_PRODUCTION_ID_0   0xfffe2000
index 83c0250c530a5c3cb0df6ca4b13ac2d544db3c15..fa0f32a686aa73669c9de53945461647b57044e1 100644 (file)
@@ -9,10 +9,12 @@
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
+
 #include <mach/hardware.h>
 #include <mach/io.h>
 #include <mach/irqs.h>
-#include <asm/hardware/gic.h>
+
+#include "../../iomap.h"
 
                .macro  get_irqnr_preamble, base, tmp
                .endm
index a3f6287b2007c608e97bda220b357d78e36243b9..01e35fa106b82c9a68c9c09304facdd65855810c 100644 (file)
@@ -2,4 +2,40 @@
  * arch/arm/mach-omap1/include/mach/hardware.h
  */
 
+#ifndef __MACH_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+#ifndef __ASSEMBLER__
+/*
+ * NOTE: Please use ioremap + __raw_read/write where possible instead of these
+ */
+extern u8 omap_readb(u32 pa);
+extern u16 omap_readw(u32 pa);
+extern u32 omap_readl(u32 pa);
+extern void omap_writeb(u8 v, u32 pa);
+extern void omap_writew(u16 v, u32 pa);
+extern void omap_writel(u32 v, u32 pa);
+
+#include <plat/tc.h>
+
+/* Almost all documentation for chip and board memory maps assumes
+ * BM is clear.  Most devel boards have a switch to control booting
+ * from NOR flash (using external chipselect 3) rather than mask ROM,
+ * which uses BM to interchange the physical CS0 and CS3 addresses.
+ */
+static inline u32 omap_cs0m_phys(void)
+{
+       return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM)
+                       ?  OMAP_CS3_PHYS : 0;
+}
+
+static inline u32 omap_cs3_phys(void)
+{
+       return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM)
+                       ? 0 : OMAP_CS3_PHYS;
+}
+
+#endif
+#endif
+
 #include <plat/hardware.h>
index 57bdf74a3e6469fe4a7040cbc4c299311cabf48a..37b12e1fd022e0755673503a1fe881781f486005 100644 (file)
@@ -1,5 +1,46 @@
 /*
  * arch/arm/mach-omap1/include/mach/io.h
+ *
+ * IO definitions for TI OMAP processors and boards
+ *
+ * Copied from arch/arm/mach-sa1100/include/mach/io.h
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Modifications:
+ *  06-12-1997 RMK     Created.
+ *  07-04-1999 RMK     Major cleanup
  */
 
-#include <plat/io.h>
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a)                __typesafe_io(a)
+#define __mem_pci(a)   (a)
+
+#endif
index c6337645ba8ad82026b82905262cc5617ca5a17c..901082def9bd1ef72de49654a141e50724c7d22e 100644 (file)
@@ -18,7 +18,8 @@
  * Note that the is_lbus_device() test is not very efficient on 1510
  * because of the strncmp().
  */
-#ifdef CONFIG_ARCH_OMAP15XX
+#if defined(CONFIG_ARCH_OMAP15XX) && !defined(__ASSEMBLER__)
+#include <plat/cpu.h>
 
 /*
  * OMAP-1510 Local Bus address offset
index 8e55b6fb3478becc4c18a02dc976451fcf4adb1e..d969a7203d14ad1e0387e034c2b025d517ba46df 100644 (file)
 
 #include <asm/tlb.h>
 #include <asm/mach/map.h>
+
 #include <plat/mux.h>
 #include <plat/tc.h>
 
+#include "iomap.h"
+#include "common.h"
 #include "clock.h"
 
 extern void omap_check_revision(void);
@@ -118,7 +121,7 @@ void __init omap16xx_map_io(void)
 /*
  * Common low-level hardware init for omap1.
  */
-void omap1_init_early(void)
+void __init omap1_init_early(void)
 {
        omap_check_revision();
 
diff --git a/arch/arm/mach-omap1/iomap.h b/arch/arm/mach-omap1/iomap.h
new file mode 100644 (file)
index 0000000..d681757
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * IO mappings for OMAP1
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the  GNU General Public License along
+ * with this program; if not, write  to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef __ASSEMBLER__
+#define IOMEM(x)               (x)
+#else
+#define IOMEM(x)               ((void __force __iomem *)(x))
+#endif
+
+#define OMAP1_IO_OFFSET                0x01000000      /* Virtual IO = 0xfefb0000 */
+#define OMAP1_IO_ADDRESS(pa)   IOMEM((pa) - OMAP1_IO_OFFSET)
+
+/*
+ * ----------------------------------------------------------------------------
+ * Omap1 specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
+
+#define OMAP1_IO_PHYS          0xFFFB0000
+#define OMAP1_IO_SIZE          0x40000
+#define OMAP1_IO_VIRT          (OMAP1_IO_PHYS - OMAP1_IO_OFFSET)
index e5b104b7fce65e1ca7e6ad1db216950905024ddd..4448114fab722979bbe915e0341c06f62d8c912a 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/io.h>
 
-#include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
+
 #include <plat/cpu.h>
 
+#include <mach/hardware.h>
+
 #define IRQ_BANK(irq) ((irq) >> 5)
 #define IRQ_BIT(irq)  ((irq) & 0x1f)
 
index 4c5ce7d829c2414d508825e9d1a816713e301420..86ace9aaa6631374dc527ed758e600d251f328e8 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/io.h>
 
+#include <plat/dma.h>
+
 #include <mach/hardware.h>
 #include <mach/lcdc.h>
-#include <plat/dma.h>
 
 int omap_lcd_dma_running(void)
 {
index 3e8410a999903cec5a24d11510b1cd67c7f3c303..adf00975b9bb0f6610af0d71b927122f21d45810 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
-#include <mach/irqs.h>
 #include <plat/dma.h>
 #include <plat/mux.h>
 #include <plat/cpu.h>
 #include <plat/mcbsp.h>
 
+#include <mach/irqs.h>
+
+#include "iomap.h"
+
 #define DPS_RSTCT2_PER_EN      (1 << 0)
 #define DSP_RSTCT2_WD_PER_EN   (1 << 1)
 
index 0c2c3669d594db171cd855b4a03247f9f88b9267..306beaca14c57ef169feaf0c06651d93b9000d36 100644 (file)
@@ -49,7 +49,6 @@
 #include <asm/mach/irq.h>
 
 #include <plat/cpu.h>
-#include <mach/irqs.h>
 #include <plat/clock.h>
 #include <plat/sram.h>
 #include <plat/tc.h>
@@ -57,6 +56,9 @@
 #include <plat/dma.h>
 #include <plat/dmtimer.h>
 
+#include <mach/irqs.h>
+
+#include "iomap.h"
 #include "pm.h"
 
 static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
index 91d199b6497935acf85192494b6d2c116e43b694..f255b153b863ca3c371582974d7a44a04b1837f2 100644 (file)
@@ -4,9 +4,10 @@
 #include <linux/kernel.h>
 #include <linux/io.h>
 
-#include <mach/hardware.h>
 #include <plat/prcm.h>
 
+#include <mach/hardware.h>
+
 void omap1_restart(char mode, const char *cmd)
 {
        /*
index c875bdc902c556d1414fbfe8e33c8d932e203d1a..0779db150da7ccbaa90115ff41ea3a5f1179d8e6 100644 (file)
  */
 
 #include <linux/linkage.h>
+
 #include <asm/assembler.h>
+
 #include <mach/io.h>
+
+#include "iomap.h"
 #include "pm.h"
 
                .text
index 692587d07ea5c8e2b2795872bc4f4c30166cb6b7..2ce0b9ab20e51ceb8af03e738d71cd0ecffb4141 100644 (file)
@@ -9,10 +9,14 @@
  */
 
 #include <linux/linkage.h>
+
 #include <asm/assembler.h>
+
 #include <mach/io.h>
 #include <mach/hardware.h>
 
+#include "iomap.h"
+
        .text
 
 /*
index b8faffa44f9e55551e87ee0e070abbbe0eaaebb4..2fae6a2740f18e0e1b2fa6c910adccd48dae3d7b 100644 (file)
 #include <linux/io.h>
 
 #include <asm/system.h>
-#include <mach/hardware.h>
 #include <asm/leds.h>
 #include <asm/irq.h>
 #include <asm/sched_clock.h>
 
+#include <mach/hardware.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
 
+#include "iomap.h"
 #include "common.h"
 
 #ifdef CONFIG_OMAP_MPU_TIMER
index 9a54ef4dcf5e638fb4777b24e09285501a8a7064..a2e6d0709df25386b3c1f4cabb348ad9b08b3190 100644 (file)
 #include <linux/io.h>
 
 #include <asm/system.h>
-#include <mach/hardware.h>
 #include <asm/leds.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
-#include "common.h"
+
 #include <plat/dmtimer.h>
 
+#include <mach/hardware.h>
+
+#include "common.h"
+
 /*
  * ---------------------------------------------------------------------------
  * 32KHz OS timer
index e20c8ab80b0e189e4960599a1b7ee79875815a9f..8141b76283a6fc5dfef016efdd7b3a0f575d2b90 100644 (file)
@@ -32,7 +32,7 @@ config ARCH_OMAP3
        depends on ARCH_OMAP2PLUS
        default y
        select CPU_V7
-       select USB_ARCH_HAS_EHCI
+       select USB_ARCH_HAS_EHCI if USB_SUPPORT
        select ARCH_HAS_OPP
        select PM_OPP if PM
        select ARM_CPU_SUSPEND if PM
@@ -52,7 +52,7 @@ config ARCH_OMAP4
        select ARM_ERRATA_720789
        select ARCH_HAS_OPP
        select PM_OPP if PM
-       select USB_ARCH_HAS_EHCI
+       select USB_ARCH_HAS_EHCI if USB_SUPPORT
        select ARM_CPU_SUSPEND if PM
 
 comment "OMAP Core Type"
@@ -117,7 +117,6 @@ comment "OMAP Board Type"
 config MACH_OMAP_GENERIC
        bool "Generic OMAP2+ board"
        depends on ARCH_OMAP2PLUS
-       select USE_OF
        default y
        help
          Support for generic TI OMAP2+ boards using Flattened Device Tree.
@@ -245,10 +244,11 @@ config MACH_NOKIA_N8X0
        select MACH_NOKIA_N810_WIMAX
 
 config MACH_NOKIA_RM680
-       bool "Nokia RM-680 board"
+       bool "Nokia RM-680/696 board"
        depends on ARCH_OMAP3
        default y
        select OMAP_PACKAGE_CBB
+       select MACH_NOKIA_RM696
 
 config MACH_NOKIA_RX51
        bool "Nokia RX-51 board"
index 06326a6e460d0bcf539977fa3f3951718d6de8a8..49f92bc1c311fd41078da192afbb84f2878f4ee7 100644 (file)
@@ -4,7 +4,7 @@
 
 # Common support
 obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer.o pm.o \
-        common.o gpio.o dma.o wd_timer.o display.o
+        common.o gpio.o dma.o wd_timer.o display.o i2c.o
 
 omap-2-3-common                                = irq.o sdrc.o
 hwmod-common                           = omap_hwmod.o \
@@ -25,7 +25,6 @@ obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
 
 # SMP support ONLY available for OMAP4
 obj-$(CONFIG_SMP)                      += omap-smp.o omap-headsmp.o
-obj-$(CONFIG_LOCAL_TIMERS)             += timer-mpu.o
 obj-$(CONFIG_HOTPLUG_CPU)              += omap-hotplug.o
 obj-$(CONFIG_ARCH_OMAP4)               += omap4-common.o omap-wakeupgen.o \
                                           sleep44xx.o
@@ -184,9 +183,6 @@ obj-$(CONFIG_OMAP_IOMMU)            += iommu2.o
 iommu-$(CONFIG_OMAP_IOMMU)             := omap-iommu.o
 obj-y                                  += $(iommu-m) $(iommu-y)
 
-i2c-omap-$(CONFIG_I2C_OMAP)            := i2c.o
-obj-y                                  += $(i2c-omap-m) $(i2c-omap-y)
-
 ifneq ($(CONFIG_TIDSPBRIDGE),)
 obj-y                                  += dsp.o
 endif
@@ -270,6 +266,11 @@ obj-y                                      += $(smc91x-m) $(smc91x-y)
 
 smsc911x-$(CONFIG_SMSC911X)            := gpmc-smsc911x.o
 obj-y                                  += $(smsc911x-m) $(smsc911x-y)
-obj-$(CONFIG_ARCH_OMAP4)               += hwspinlock.o
+ifneq ($(CONFIG_HWSPINLOCK_OMAP),)
+obj-y                                  += hwspinlock.o
+endif
+
+emac-$(CONFIG_TI_DAVINCI_EMAC)         := am35xx-emac.o
+obj-y                                  += $(emac-m) $(emac-y)
 
 obj-y                                  += common-board-devices.o twl-common.o
diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c
new file mode 100644 (file)
index 0000000..1f97e74
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2011 Ilya Yanok, Emcraft Systems
+ *
+ * Based on mach-omap2/board-am3517evm.c
+ * Copyright (C) 2009 Texas Instruments Incorporated
+ * Author: Ranjith Lohithakshan <ranjithl@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
+ * whether express or implied; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/davinci_emac.h>
+#include <linux/platform_device.h>
+#include <plat/irqs.h>
+#include <mach/am35xx.h>
+
+#include "control.h"
+
+static struct mdio_platform_data am35xx_emac_mdio_pdata;
+
+static struct resource am35xx_emac_mdio_resources[] = {
+       DEFINE_RES_MEM(AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET, SZ_4K),
+};
+
+static struct platform_device am35xx_emac_mdio_device = {
+       .name           = "davinci_mdio",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(am35xx_emac_mdio_resources),
+       .resource       = am35xx_emac_mdio_resources,
+       .dev.platform_data = &am35xx_emac_mdio_pdata,
+};
+
+static void am35xx_enable_emac_int(void)
+{
+       u32 regval;
+
+       regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
+       regval = (regval | AM35XX_CPGMAC_C0_RX_PULSE_CLR |
+                 AM35XX_CPGMAC_C0_TX_PULSE_CLR |
+                 AM35XX_CPGMAC_C0_MISC_PULSE_CLR |
+                 AM35XX_CPGMAC_C0_RX_THRESH_CLR);
+       omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
+       regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
+}
+
+static void am35xx_disable_emac_int(void)
+{
+       u32 regval;
+
+       regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
+       regval = (regval | AM35XX_CPGMAC_C0_RX_PULSE_CLR |
+                 AM35XX_CPGMAC_C0_TX_PULSE_CLR);
+       omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
+       regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
+}
+
+static struct emac_platform_data am35xx_emac_pdata = {
+       .ctrl_reg_offset        = AM35XX_EMAC_CNTRL_OFFSET,
+       .ctrl_mod_reg_offset    = AM35XX_EMAC_CNTRL_MOD_OFFSET,
+       .ctrl_ram_offset        = AM35XX_EMAC_CNTRL_RAM_OFFSET,
+       .ctrl_ram_size          = AM35XX_EMAC_CNTRL_RAM_SIZE,
+       .hw_ram_addr            = AM35XX_EMAC_HW_RAM_ADDR,
+       .version                = EMAC_VERSION_2,
+       .interrupt_enable       = am35xx_enable_emac_int,
+       .interrupt_disable      = am35xx_disable_emac_int,
+};
+
+static struct resource am35xx_emac_resources[] = {
+       DEFINE_RES_MEM(AM35XX_IPSS_EMAC_BASE, 0x30000),
+       DEFINE_RES_IRQ(INT_35XX_EMAC_C0_RXTHRESH_IRQ),
+       DEFINE_RES_IRQ(INT_35XX_EMAC_C0_RX_PULSE_IRQ),
+       DEFINE_RES_IRQ(INT_35XX_EMAC_C0_TX_PULSE_IRQ),
+       DEFINE_RES_IRQ(INT_35XX_EMAC_C0_MISC_PULSE_IRQ),
+};
+
+static struct platform_device am35xx_emac_device = {
+       .name           = "davinci_emac",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(am35xx_emac_resources),
+       .resource       = am35xx_emac_resources,
+       .dev            = {
+               .platform_data  = &am35xx_emac_pdata,
+       },
+};
+
+void __init am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en)
+{
+       unsigned int regval;
+       int err;
+
+       am35xx_emac_pdata.rmii_en = rmii_en;
+       am35xx_emac_mdio_pdata.bus_freq = mdio_bus_freq;
+       err = platform_device_register(&am35xx_emac_device);
+       if (err) {
+               pr_err("AM35x: failed registering EMAC device: %d\n", err);
+               return;
+       }
+
+       err = platform_device_register(&am35xx_emac_mdio_device);
+       if (err) {
+               pr_err("AM35x: failed registering EMAC MDIO device: %d\n", err);
+               platform_device_unregister(&am35xx_emac_device);
+               return;
+       }
+
+       regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
+       regval = regval & (~(AM35XX_CPGMACSS_SW_RST));
+       omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
+       regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
+}
diff --git a/arch/arm/mach-omap2/am35xx-emac.h b/arch/arm/mach-omap2/am35xx-emac.h
new file mode 100644 (file)
index 0000000..15c6f9c
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2011 Ilya Yanok, Emcraft Systems
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define AM35XX_DEFAULT_MDIO_FREQUENCY  1000000
+
+#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE)
+void am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en);
+#else
+static inline void am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en) {}
+#endif
index 7370983f809fc3994a8722970f2c6f7f1a85f08e..c8bda62900d8dd87d9d383edf305651ae21bd354 100644 (file)
@@ -279,7 +279,7 @@ static void __init omap_2430sdp_init(void)
        platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
        omap_serial_init();
        omap_sdrc_init(NULL, NULL);
-       omap2_hsmmc_init(mmc);
+       omap_hsmmc_init(mmc);
        omap2_usbfs_init(&sdp2430_usb_config);
 
        omap_mux_init_signal("usb0hs_stp", OMAP_PULL_ENA | OMAP_PULL_UP);
index 383717ba63b9ae7f72bcf3d8999bf371abed4032..da75f239873ece08a66e598bc0f9694ff49fbf8b 100644 (file)
@@ -232,11 +232,13 @@ static struct omap2_hsmmc_info mmc[] = {
                 */
                .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
                .gpio_wp        = 4,
+               .deferred       = true,
        },
        {
                .mmc            = 2,
                .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
                .gpio_wp        = 7,
+               .deferred       = true,
        },
        {}      /* Terminator */
 };
@@ -249,7 +251,7 @@ static int sdp3430_twl_gpio_setup(struct device *dev,
         */
        mmc[0].gpio_cd = gpio + 0;
        mmc[1].gpio_cd = gpio + 1;
-       omap2_hsmmc_init(mmc);
+       omap_hsmmc_late_init(mmc);
 
        /* gpio + 7 is "sub_lcd_en_bkl" (output/PWM1) */
        gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "sub_lcd_en_bkl");
@@ -606,6 +608,7 @@ static void __init omap_3430sdp_init(void)
        omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
        omap_board_config = sdp3430_config;
        omap_board_config_size = ARRAY_SIZE(sdp3430_config);
+       omap_hsmmc_init(mmc);
        omap3430_i2c_init();
        omap_display_init(&sdp3430_dss_data);
        if (omap_rev() > OMAP3430_REV_ES1_0)
index 44cf1893829a4b22c7fe416d773e589b3921ec3e..30768c2f53fd2bdb81d7c3f403c713fb501595ea 100644 (file)
@@ -324,7 +324,10 @@ static struct spi_board_info sdp4430_spi_board_info[] __initdata = {
                .bus_num                = 1,
                .chip_select            = 0,
                .max_speed_hz           = 24000000,
-               .irq                    = ETH_KS8851_IRQ,
+               /*
+                * .irq is set to gpio_to_irq(ETH_KS8851_IRQ)
+                * in omap_4430sdp_init
+                */
        },
 };
 
@@ -521,9 +524,9 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
 {
        struct omap2_hsmmc_info *c;
 
-       omap2_hsmmc_init(controllers);
+       omap_hsmmc_init(controllers);
        for (c = controllers; c->mmc; c++)
-               omap4_twl6030_hsmmc_set_late_init(c->dev);
+               omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev);
 
        return 0;
 }
index 4b1cfe32e6baf4b4ab4e6d0eeb41f0c4f4d17ffa..3645285a3e2bb830fafdf5c0bdee445522967acd 100644 (file)
 #include <video/omap-panel-generic-dpi.h>
 #include <video/omap-panel-dvi.h>
 
+#include "am35xx-emac.h"
 #include "mux.h"
 #include "control.h"
 #include "hsmmc.h"
 
-#define AM35XX_EVM_MDIO_FREQUENCY      (1000000)
-
-static struct mdio_platform_data am3517_evm_mdio_pdata = {
-       .bus_freq       = AM35XX_EVM_MDIO_FREQUENCY,
-};
-
-static struct resource am3517_mdio_resources[] = {
-       {
-               .start  = AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET,
-               .end    = AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET +
-                         SZ_4K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-};
-
-static struct platform_device am3517_mdio_device = {
-       .name           = "davinci_mdio",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(am3517_mdio_resources),
-       .resource       = am3517_mdio_resources,
-       .dev.platform_data = &am3517_evm_mdio_pdata,
-};
-
-static struct emac_platform_data am3517_evm_emac_pdata = {
-       .rmii_en        = 1,
-};
-
-static struct resource am3517_emac_resources[] = {
-       {
-               .start  = AM35XX_IPSS_EMAC_BASE,
-               .end    = AM35XX_IPSS_EMAC_BASE + 0x2FFFF,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .start  = INT_35XX_EMAC_C0_RXTHRESH_IRQ,
-               .end    = INT_35XX_EMAC_C0_RXTHRESH_IRQ,
-               .flags  = IORESOURCE_IRQ,
-       },
-       {
-               .start  = INT_35XX_EMAC_C0_RX_PULSE_IRQ,
-               .end    = INT_35XX_EMAC_C0_RX_PULSE_IRQ,
-               .flags  = IORESOURCE_IRQ,
-       },
-       {
-               .start  = INT_35XX_EMAC_C0_TX_PULSE_IRQ,
-               .end    = INT_35XX_EMAC_C0_TX_PULSE_IRQ,
-               .flags  = IORESOURCE_IRQ,
-       },
-       {
-               .start  = INT_35XX_EMAC_C0_MISC_PULSE_IRQ,
-               .end    = INT_35XX_EMAC_C0_MISC_PULSE_IRQ,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device am3517_emac_device = {
-       .name           = "davinci_emac",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(am3517_emac_resources),
-       .resource       = am3517_emac_resources,
-};
-
-static void am3517_enable_ethernet_int(void)
-{
-       u32 regval;
-
-       regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
-       regval = (regval | AM35XX_CPGMAC_C0_RX_PULSE_CLR |
-               AM35XX_CPGMAC_C0_TX_PULSE_CLR |
-               AM35XX_CPGMAC_C0_MISC_PULSE_CLR |
-               AM35XX_CPGMAC_C0_RX_THRESH_CLR);
-       omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
-       regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
-}
-
-static void am3517_disable_ethernet_int(void)
-{
-       u32 regval;
-
-       regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
-       regval = (regval | AM35XX_CPGMAC_C0_RX_PULSE_CLR |
-               AM35XX_CPGMAC_C0_TX_PULSE_CLR);
-       omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
-       regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
-}
-
-static void am3517_evm_ethernet_init(struct emac_platform_data *pdata)
-{
-       unsigned int regval;
-
-       pdata->ctrl_reg_offset          = AM35XX_EMAC_CNTRL_OFFSET;
-       pdata->ctrl_mod_reg_offset      = AM35XX_EMAC_CNTRL_MOD_OFFSET;
-       pdata->ctrl_ram_offset          = AM35XX_EMAC_CNTRL_RAM_OFFSET;
-       pdata->ctrl_ram_size            = AM35XX_EMAC_CNTRL_RAM_SIZE;
-       pdata->version                  = EMAC_VERSION_2;
-       pdata->hw_ram_addr              = AM35XX_EMAC_HW_RAM_ADDR;
-       pdata->interrupt_enable         = am3517_enable_ethernet_int;
-       pdata->interrupt_disable        = am3517_disable_ethernet_int;
-       am3517_emac_device.dev.platform_data    = pdata;
-       platform_device_register(&am3517_emac_device);
-       platform_device_register(&am3517_mdio_device);
-       clk_add_alias(NULL, dev_name(&am3517_mdio_device.dev),
-                     NULL, &am3517_emac_device.dev);
-
-       regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
-       regval = regval & (~(AM35XX_CPGMACSS_SW_RST));
-       omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
-       regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
-
-       return ;
-}
-
-
-
 #define LCD_PANEL_PWR          176
 #define LCD_PANEL_BKLIGHT_PWR  182
 #define LCD_PANEL_PWM          181
@@ -498,13 +385,13 @@ static void __init am3517_evm_init(void)
        i2c_register_board_info(1, am3517evm_i2c1_boardinfo,
                                ARRAY_SIZE(am3517evm_i2c1_boardinfo));
        /*Ethernet*/
-       am3517_evm_ethernet_init(&am3517_evm_emac_pdata);
+       am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1);
 
        /* MUSB */
        am3517_evm_musb_init();
 
        /* MMC init function */
-       omap2_hsmmc_init(mmc);
+       omap_hsmmc_init(mmc);
 }
 
 MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
index d73316ed4207c600378cb538b73ae0daf04dcb2e..41b0a2fe0b04b2de9d2953e3d938426068bbb0c5 100644 (file)
@@ -280,7 +280,6 @@ static struct omap_dss_board_info cm_t35_dss_data = {
 
 static struct omap2_mcspi_device_config tdo24m_mcspi_config = {
        .turbo_mode     = 0,
-       .single_channel = 1,    /* 0: slave, 1: master */
 };
 
 static struct tdo24m_platform_data tdo24m_config = {
@@ -413,7 +412,7 @@ static struct omap2_hsmmc_info mmc[] = {
                .caps           = MMC_CAP_4_BIT_DATA,
                .gpio_cd        = -EINVAL,
                .gpio_wp        = -EINVAL,
-
+               .deferred       = true,
        },
        {
                .mmc            = 2,
@@ -471,7 +470,7 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
 
        /* gpio + 0 is "mmc0_cd" (input/IRQ) */
        mmc[0].gpio_cd = gpio + 0;
-       omap2_hsmmc_init(mmc);
+       omap_hsmmc_late_init(mmc);
 
        return 0;
 }
@@ -639,6 +638,7 @@ static void __init cm_t3x_common_init(void)
        omap_serial_init();
        omap_sdrc_init(mt46h32m32lf6_sdrc_params,
                             mt46h32m32lf6_sdrc_params);
+       omap_hsmmc_init(mmc);
        cm_t35_init_i2c();
        omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
        cm_t35_init_ethernet();
index f36d694d21590e069aa390a66eb56024d113d8f7..9e66e167e4f39f67a75b4a130e6207a3ec7edcf1 100644 (file)
@@ -49,6 +49,7 @@
 #include "mux.h"
 #include "control.h"
 #include "common-board-devices.h"
+#include "am35xx-emac.h"
 
 #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
 static struct gpio_led cm_t3517_leds[] = {
@@ -291,6 +292,7 @@ static void __init cm_t3517_init(void)
        cm_t3517_init_rtc();
        cm_t3517_init_usbh();
        cm_t3517_init_hecc();
+       am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1);
 }
 
 MACHINE_START(CM_T3517, "Compulab CM-T3517")
index e873063f4fdaf4cac7fffe5d18ca718a79cb84fe..11cd2a8060939e640c3be752c126fc987b08553b 100644 (file)
@@ -100,6 +100,7 @@ static struct omap2_hsmmc_info mmc[] = {
                .mmc            = 1,
                .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
                .gpio_wp        = 29,
+               .deferred       = true,
        },
        {}      /* Terminator */
 };
@@ -228,7 +229,7 @@ static int devkit8000_twl_gpio_setup(struct device *dev,
 
        /* gpio + 0 is "mmc0_cd" (input/IRQ) */
        mmc[0].gpio_cd = gpio + 0;
-       omap2_hsmmc_init(mmc);
+       omap_hsmmc_late_init(mmc);
 
        /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
        gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
@@ -636,6 +637,7 @@ static void __init devkit8000_init(void)
 
        omap_dm9000_init();
 
+       omap_hsmmc_init(mmc);
        devkit8000_i2c_init();
        platform_add_devices(devkit8000_devices,
                        ARRAY_SIZE(devkit8000_devices));
index 30a6f527510c05e624a692c936642693badba97e..0349fd2b68d86afd6fd0dccf805d24f425769e2f 100644 (file)
@@ -189,7 +189,7 @@ unmap:
  *
  * @return - void.
  */
-void board_flash_init(struct flash_partitions partition_info[],
+void __init board_flash_init(struct flash_partitions partition_info[],
                        char chip_sel_board[][GPMC_CS_NUM], int nand_type)
 {
        u8              cs = 0;
index 45fdfe2bd9d5b18ccf2452362e23be27c62715c2..74e1687b51706317672694d80ac79aa92f0c416f 100644 (file)
@@ -12,6 +12,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/io.h>
+#include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/irqdomain.h>
 #include <linux/i2c/twl.h>
 #include "common.h"
 #include "common-board-devices.h"
 
-/*
- * XXX: Still needed to boot until the i2c & twl driver is adapted to
- * device-tree
- */
-#ifdef CONFIG_ARCH_OMAP4
-static struct twl4030_platform_data sdp4430_twldata = {
-       .irq_base       = TWL6030_IRQ_BASE,
-       .irq_end        = TWL6030_IRQ_END,
-};
-
-static void __init omap4_i2c_init(void)
-{
-       omap4_pmic_init("twl6030", &sdp4430_twldata);
-}
+#if !(defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3))
+#define omap_intc_of_init      NULL
+#endif
+#ifndef CONFIG_ARCH_OMAP4
+#define gic_of_init            NULL
 #endif
 
-#ifdef CONFIG_ARCH_OMAP3
-static struct twl4030_platform_data beagle_twldata = {
-       .irq_base       = TWL4030_IRQ_BASE,
-       .irq_end        = TWL4030_IRQ_END,
+static struct of_device_id irq_match[] __initdata = {
+       { .compatible = "ti,omap2-intc", .data = omap_intc_of_init, },
+       { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
+       { }
 };
 
-static void __init omap3_i2c_init(void)
+static void __init omap_init_irq(void)
 {
-       omap3_pmic_init("twl4030", &beagle_twldata);
+       of_irq_init(irq_match);
 }
-#endif
 
 static struct of_device_id omap_dt_match_table[] __initdata = {
        { .compatible = "simple-bus", },
@@ -58,51 +49,24 @@ static struct of_device_id omap_dt_match_table[] __initdata = {
        { }
 };
 
-static struct of_device_id intc_match[] __initdata = {
-       { .compatible = "ti,omap3-intc", },
-       { .compatible = "arm,cortex-a9-gic", },
-       { }
-};
-
 static void __init omap_generic_init(void)
 {
-       struct device_node *node = of_find_matching_node(NULL, intc_match);
-       if (node)
-               irq_domain_add_legacy(node, 32, 0, 0, &irq_domain_simple_ops, NULL);
-
        omap_sdrc_init(NULL, NULL);
 
        of_platform_populate(NULL, omap_dt_match_table, NULL, NULL);
 }
 
-#ifdef CONFIG_ARCH_OMAP4
-static void __init omap4_init(void)
-{
-       omap4_i2c_init();
-       omap_generic_init();
-}
-#endif
-
-#ifdef CONFIG_ARCH_OMAP3
-static void __init omap3_init(void)
-{
-       omap3_i2c_init();
-       omap_generic_init();
-}
-#endif
-
-#if defined(CONFIG_SOC_OMAP2420)
+#ifdef CONFIG_SOC_OMAP2420
 static const char *omap242x_boards_compat[] __initdata = {
        "ti,omap2420",
        NULL,
 };
 
 DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)")
-       .atag_offset    = 0x100,
        .reserve        = omap_reserve,
        .map_io         = omap242x_map_io,
        .init_early     = omap2420_init_early,
-       .init_irq       = omap2_init_irq,
+       .init_irq       = omap_init_irq,
        .handle_irq     = omap2_intc_handle_irq,
        .init_machine   = omap_generic_init,
        .timer          = &omap2_timer,
@@ -111,18 +75,17 @@ DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)")
 MACHINE_END
 #endif
 
-#if defined(CONFIG_SOC_OMAP2430)
+#ifdef CONFIG_SOC_OMAP2430
 static const char *omap243x_boards_compat[] __initdata = {
        "ti,omap2430",
        NULL,
 };
 
 DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)")
-       .atag_offset    = 0x100,
        .reserve        = omap_reserve,
        .map_io         = omap243x_map_io,
        .init_early     = omap2430_init_early,
-       .init_irq       = omap2_init_irq,
+       .init_irq       = omap_init_irq,
        .handle_irq     = omap2_intc_handle_irq,
        .init_machine   = omap_generic_init,
        .timer          = &omap2_timer,
@@ -131,18 +94,33 @@ DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)")
 MACHINE_END
 #endif
 
-#if defined(CONFIG_ARCH_OMAP3)
+#ifdef CONFIG_ARCH_OMAP3
+static struct twl4030_platform_data beagle_twldata = {
+       .irq_base       = TWL4030_IRQ_BASE,
+       .irq_end        = TWL4030_IRQ_END,
+};
+
+static void __init omap3_i2c_init(void)
+{
+       omap3_pmic_init("twl4030", &beagle_twldata);
+}
+
+static void __init omap3_init(void)
+{
+       omap3_i2c_init();
+       omap_generic_init();
+}
+
 static const char *omap3_boards_compat[] __initdata = {
        "ti,omap3",
        NULL,
 };
 
 DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
-       .atag_offset    = 0x100,
        .reserve        = omap_reserve,
        .map_io         = omap3_map_io,
        .init_early     = omap3430_init_early,
-       .init_irq       = omap3_init_irq,
+       .init_irq       = omap_init_irq,
        .handle_irq     = omap3_intc_handle_irq,
        .init_machine   = omap3_init,
        .timer          = &omap3_timer,
@@ -151,18 +129,33 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
 MACHINE_END
 #endif
 
-#if defined(CONFIG_ARCH_OMAP4)
+#ifdef CONFIG_ARCH_OMAP4
+static struct twl4030_platform_data sdp4430_twldata = {
+       .irq_base       = TWL6030_IRQ_BASE,
+       .irq_end        = TWL6030_IRQ_END,
+};
+
+static void __init omap4_i2c_init(void)
+{
+       omap4_pmic_init("twl6030", &sdp4430_twldata);
+}
+
+static void __init omap4_init(void)
+{
+       omap4_i2c_init();
+       omap_generic_init();
+}
+
 static const char *omap4_boards_compat[] __initdata = {
        "ti,omap4",
        NULL,
 };
 
 DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)")
-       .atag_offset    = 0x100,
        .reserve        = omap_reserve,
        .map_io         = omap4_map_io,
        .init_early     = omap4430_init_early,
-       .init_irq       = gic_init_irq,
+       .init_irq       = omap_init_irq,
        .handle_irq     = gic_handle_irq,
        .init_machine   = omap4_init,
        .timer          = &omap4_timer,
index a59ace0ed560a57cdf1009cd15d596b94d71c76d..e558800adfdf58bdd69b55398ed8a7f3c4b332b0 100644 (file)
@@ -295,6 +295,7 @@ static struct omap2_hsmmc_info mmc[] = {
                .caps           = MMC_CAP_4_BIT_DATA,
                .gpio_cd        = -EINVAL,
                .gpio_wp        = -EINVAL,
+               .deferred       = true,
        },
 #if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
        {
@@ -402,7 +403,7 @@ static int igep_twl_gpio_setup(struct device *dev,
 
        /* gpio + 0 is "mmc0_cd" (input/IRQ) */
        mmc[0].gpio_cd = gpio + 0;
-       omap2_hsmmc_init(mmc);
+       omap_hsmmc_late_init(mmc);
 
        /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
 #if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
@@ -639,6 +640,9 @@ static void __init igep_init(void)
 
        /* Get IGEP2 hardware revision */
        igep2_get_revision();
+
+       omap_hsmmc_init(mmc);
+
        /* Register I2C busses and drivers */
        igep_i2c_init();
        platform_add_devices(igep_devices, ARRAY_SIZE(igep_devices));
index 2d2a61f7dcbf8e3d799fee8054a39011d94ab603..d50a562adfa0b08c4eed8318711384833385571f 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/io.h>
 #include <linux/smsc911x.h>
 #include <linux/mmc/host.h>
-#include <linux/gpio.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -424,7 +423,7 @@ static void __init omap_ldp_init(void)
        board_nand_init(ldp_nand_partitions,
                ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0);
 
-       omap2_hsmmc_init(mmc);
+       omap_hsmmc_init(mmc);
        ldp_display_init();
 }
 
index 672262717601e012affe2a2f7e952c917ec22871..518091c5f77c74fe20df08f2714746062a8b004f 100644 (file)
 
 #include "mux.h"
 
-static int slot1_cover_open;
-static int slot2_cover_open;
-static struct device *mmc_device;
-
 #define TUSB6010_ASYNC_CS      1
 #define TUSB6010_SYNC_CS       4
 #define TUSB6010_GPIO_INT      58
@@ -137,7 +133,6 @@ static void __init n8x0_usb_init(void) {}
 
 static struct omap2_mcspi_device_config p54spi_mcspi_config = {
        .turbo_mode     = 0,
-       .single_channel = 1,
 };
 
 static struct spi_board_info n800_spi_board_info[] __initdata = {
@@ -211,6 +206,10 @@ static struct omap_onenand_platform_data board_onenand_data[] = {
 #define N810_EMMC_VSD_GPIO     23
 #define N810_EMMC_VIO_GPIO     9
 
+static int slot1_cover_open;
+static int slot2_cover_open;
+static struct device *mmc_device;
+
 static int n8x0_mmc_switch_slot(struct device *dev, int slot)
 {
 #ifdef CONFIG_MMC_DEBUG
index 7ffcd2839e7ba872d872e0a53476b2e95832c2a2..7be8d659d91dc59f7b592108fe342d6436814cc6 100644 (file)
@@ -253,6 +253,7 @@ static struct omap2_hsmmc_info mmc[] = {
                .mmc            = 1,
                .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
                .gpio_wp        = -EINVAL,
+               .deferred       = true,
        },
        {}      /* Terminator */
 };
@@ -272,12 +273,10 @@ static int beagle_twl_gpio_setup(struct device *dev,
 {
        int r;
 
-       if (beagle_config.mmc1_gpio_wp != -EINVAL)
-               omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT);
        mmc[0].gpio_wp = beagle_config.mmc1_gpio_wp;
        /* gpio + 0 is "mmc0_cd" (input/IRQ) */
        mmc[0].gpio_cd = gpio + 0;
-       omap2_hsmmc_init(mmc);
+       omap_hsmmc_late_init(mmc);
 
        /*
         * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active
@@ -521,6 +520,11 @@ static void __init omap3_beagle_init(void)
 {
        omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
        omap3_beagle_init_rev();
+
+       if (beagle_config.mmc1_gpio_wp != -EINVAL)
+               omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT);
+       omap_hsmmc_init(mmc);
+
        omap3_beagle_i2c_init();
 
        gpio_buttons[0].gpio = beagle_config.usr_button_gpio;
index c877236a8442d235a4803c0903eb913d69ca3096..a659e198892beca6dd98ec167b4eee3e02ba77c0 100644 (file)
@@ -317,6 +317,7 @@ static struct omap2_hsmmc_info mmc[] = {
                .caps           = MMC_CAP_4_BIT_DATA,
                .gpio_cd        = -EINVAL,
                .gpio_wp        = 63,
+               .deferred       = true,
        },
 #ifdef CONFIG_WL12XX_PLATFORM_DATA
        {
@@ -361,9 +362,8 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
        int r, lcd_bl_en;
 
        /* gpio + 0 is "mmc0_cd" (input/IRQ) */
-       omap_mux_init_gpio(63, OMAP_PIN_INPUT);
        mmc[0].gpio_cd = gpio + 0;
-       omap2_hsmmc_init(mmc);
+       omap_hsmmc_late_init(mmc);
 
        /*
         * Most GPIOs are for USB OTG.  Some are mostly sent to
@@ -644,6 +644,9 @@ static void __init omap3_evm_init(void)
        omap_board_config = omap3_evm_config;
        omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
 
+       omap_mux_init_gpio(63, OMAP_PIN_INPUT);
+       omap_hsmmc_init(mmc);
+
        omap3_evm_i2c_init();
 
        omap_display_init(&omap3_evm_dss_data);
index 4198dd017d8fdfde7fd00b2a8a00d5f9d7e766fb..4a7d8c8a75da5298e2647e30aed3c4b87d8c5fef 100644 (file)
@@ -128,7 +128,7 @@ static void __init board_mmc_init(void)
                return;
        }
 
-       omap2_hsmmc_init(board_mmc_info);
+       omap_hsmmc_init(board_mmc_info);
 }
 
 static struct omap_smsc911x_platform_data __initdata board_smsc911x_data = {
@@ -205,6 +205,7 @@ static void __init omap3logic_init(void)
 
 MACHINE_START(OMAP3_TORPEDO, "Logic OMAP3 Torpedo board")
        .atag_offset    = 0x100,
+       .reserve        = omap_reserve,
        .map_io         = omap3_map_io,
        .init_early     = omap35xx_init_early,
        .init_irq       = omap3_init_irq,
@@ -216,6 +217,7 @@ MACHINE_END
 
 MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board")
        .atag_offset    = 0x100,
+       .reserve        = omap_reserve,
        .map_io         = omap3_map_io,
        .init_early     = omap35xx_init_early,
        .init_irq       = omap3_init_irq,
index 1644b73017fcafbdc0e7b87a503ac35f92e8f992..33d995d0f0755e73f2a920c1af2ea59df4ea2430 100644 (file)
@@ -121,6 +121,11 @@ static struct platform_device pandora_leds_gpio = {
        },
 };
 
+static struct platform_device pandora_backlight = {
+       .name   = "pandora-backlight",
+       .id     = -1,
+};
+
 #define GPIO_BUTTON(gpio_num, ev_type, ev_code, act_low, descr)        \
 {                                                              \
        .gpio           = gpio_num,                             \
@@ -273,6 +278,7 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = {
                .gpio_cd        = -EINVAL,
                .gpio_wp        = 126,
                .ext_clock      = 0,
+               .deferred       = true,
        },
        {
                .mmc            = 2,
@@ -281,6 +287,7 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = {
                .gpio_wp        = 127,
                .ext_clock      = 1,
                .transceiver    = true,
+               .deferred       = true,
        },
        {
                .mmc            = 3,
@@ -300,7 +307,7 @@ static int omap3pandora_twl_gpio_setup(struct device *dev,
        /* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */
        omap3pandora_mmc[0].gpio_cd = gpio + 0;
        omap3pandora_mmc[1].gpio_cd = gpio + 1;
-       omap2_hsmmc_init(omap3pandora_mmc);
+       omap_hsmmc_late_init(omap3pandora_mmc);
 
        /* gpio + 13 drives 32kHz buffer for wifi module */
        gpio_32khz = gpio + 13;
@@ -343,7 +350,7 @@ static struct regulator_consumer_supply pandora_vcc_lcd_supply[] = {
 };
 
 static struct regulator_consumer_supply pandora_usb_phy_supply[] = {
-       REGULATOR_SUPPLY("hsusb0", "ehci-omap.0"),
+       REGULATOR_SUPPLY("hsusb1", "ehci-omap.0"),
 };
 
 /* ads7846 on SPI and 2 nub controllers on I2C */
@@ -476,6 +483,10 @@ static struct platform_device pandora_vwlan_device = {
 
 static struct twl4030_bci_platform_data pandora_bci_data;
 
+static struct twl4030_power_data pandora_power_data = {
+       .use_poweroff   = true,
+};
+
 static struct twl4030_platform_data omap3pandora_twldata = {
        .gpio           = &omap3pandora_gpio_data,
        .vmmc1          = &pandora_vmmc1,
@@ -486,6 +497,7 @@ static struct twl4030_platform_data omap3pandora_twldata = {
        .vsim           = &pandora_vsim,
        .keypad         = &pandora_kp_data,
        .bci            = &pandora_bci_data,
+       .power          = &pandora_power_data,
 };
 
 static struct i2c_board_info __initdata omap3pandora_i2c3_boardinfo[] = {
@@ -557,17 +569,18 @@ static struct platform_device *omap3pandora_devices[] __initdata = {
        &pandora_leds_gpio,
        &pandora_keys_gpio,
        &pandora_vwlan_device,
+       &pandora_backlight,
 };
 
 static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
 
-       .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
-       .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
+       .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
+       .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
        .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
 
        .phy_reset  = true,
-       .reset_gpio_port[0]  = 16,
-       .reset_gpio_port[1]  = -EINVAL,
+       .reset_gpio_port[0]  = -EINVAL,
+       .reset_gpio_port[1]  = 16,
        .reset_gpio_port[2]  = -EINVAL
 };
 
@@ -580,6 +593,7 @@ static struct omap_board_mux board_mux[] __initdata = {
 static void __init omap3pandora_init(void)
 {
        omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+       omap_hsmmc_init(omap3pandora_mmc);
        omap3pandora_i2c_init();
        pandora_wl1251_init();
        platform_add_devices(omap3pandora_devices,
index cb089a46f62f691cceec4c20f9f035111dded5a3..641004380795f458c9432bf1056dd63187a5a33e 100644 (file)
@@ -209,10 +209,11 @@ static struct regulator_init_data omap3stalker_vsim = {
 
 static struct omap2_hsmmc_info mmc[] = {
        {
-        .mmc           = 1,
-        .caps          = MMC_CAP_4_BIT_DATA,
-        .gpio_cd       = -EINVAL,
-        .gpio_wp       = 23,
+               .mmc            = 1,
+               .caps           = MMC_CAP_4_BIT_DATA,
+               .gpio_cd        = -EINVAL,
+               .gpio_wp        = 23,
+               .deferred       = true,
         },
        {}                      /* Terminator */
 };
@@ -282,9 +283,8 @@ omap3stalker_twl_gpio_setup(struct device *dev,
                            unsigned gpio, unsigned ngpio)
 {
        /* gpio + 0 is "mmc0_cd" (input/IRQ) */
-       omap_mux_init_gpio(23, OMAP_PIN_INPUT);
        mmc[0].gpio_cd = gpio + 0;
-       omap2_hsmmc_init(mmc);
+       omap_hsmmc_late_init(mmc);
 
        /*
         * Most GPIOs are for USB OTG.  Some are mostly sent to
@@ -425,6 +425,9 @@ static void __init omap3_stalker_init(void)
        omap_board_config = omap3_stalker_config;
        omap_board_config_size = ARRAY_SIZE(omap3_stalker_config);
 
+       omap_mux_init_gpio(23, OMAP_PIN_INPUT);
+       omap_hsmmc_init(mmc);
+
        omap3_stalker_i2c_init();
 
        platform_add_devices(omap3_stalker_devices,
index a0b851aafccad1bc87d900d9474cfa689e8cf39d..8842e04aef013a9d6efce34a16f64c9c79b27321 100644 (file)
@@ -100,6 +100,7 @@ static struct omap2_hsmmc_info mmc[] = {
                .mmc            = 1,
                .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
                .gpio_wp        = 29,
+               .deferred       = true,
        },
        {}      /* Terminator */
 };
@@ -117,15 +118,9 @@ static struct gpio_led gpio_leds[];
 static int touchbook_twl_gpio_setup(struct device *dev,
                unsigned gpio, unsigned ngpio)
 {
-       if (system_rev >= 0x20 && system_rev <= 0x34301000) {
-               omap_mux_init_gpio(23, OMAP_PIN_INPUT);
-               mmc[0].gpio_wp = 23;
-       } else {
-               omap_mux_init_gpio(29, OMAP_PIN_INPUT);
-       }
        /* gpio + 0 is "mmc0_cd" (input/IRQ) */
        mmc[0].gpio_cd = gpio + 0;
-       omap2_hsmmc_init(mmc);
+       omap_hsmmc_late_init(mmc);
 
        /* REVISIT: need ehci-omap hooks for external VBUS
         * power switch and overcurrent detect
@@ -351,6 +346,14 @@ static void __init omap3_touchbook_init(void)
 
        pm_power_off = omap3_touchbook_poweroff;
 
+       if (system_rev >= 0x20 && system_rev <= 0x34301000) {
+               omap_mux_init_gpio(23, OMAP_PIN_INPUT);
+               mmc[0].gpio_wp = 23;
+       } else {
+               omap_mux_init_gpio(29, OMAP_PIN_INPUT);
+       }
+       omap_hsmmc_init(mmc);
+
        omap3_touchbook_i2c_init();
        platform_add_devices(omap3_touchbook_devices,
                        ARRAY_SIZE(omap3_touchbook_devices));
index e4415917693f3d04cfa096283c031d8780b56321..e9071a57c37b669ca69561a255773c401f487c5b 100644 (file)
@@ -116,10 +116,16 @@ static struct platform_device panda_abe_audio = {
        },
 };
 
+static struct platform_device btwilink_device = {
+       .name   = "btwilink",
+       .id     = -1,
+};
+
 static struct platform_device *panda_devices[] __initdata = {
        &leds_gpio,
        &wl1271_device,
        &panda_abe_audio,
+       &btwilink_device,
 };
 
 static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
@@ -271,9 +277,9 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
 {
        struct omap2_hsmmc_info *c;
 
-       omap2_hsmmc_init(controllers);
+       omap_hsmmc_init(controllers);
        for (c = controllers; c->mmc; c++)
-               omap4_twl6030_hsmmc_set_late_init(c->dev);
+               omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev);
 
        return 0;
 }
@@ -504,7 +510,7 @@ static struct omap_dss_board_info omap4_panda_dss_data = {
        .default_device = &omap4_panda_dvi_device,
 };
 
-void omap4_panda_display_init(void)
+void __init omap4_panda_display_init(void)
 {
        int r;
 
index 52c0cef77165cb2cbc8a658d8fd63b260ec5662a..668533e2a3791442e3582696d365e964179124e8 100644 (file)
@@ -407,8 +407,6 @@ static inline void __init overo_init_keys(void) { return; }
 static int overo_twl_gpio_setup(struct device *dev,
                unsigned gpio, unsigned ngpio)
 {
-       omap2_hsmmc_init(mmc);
-
 #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
        /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
        gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
@@ -505,6 +503,7 @@ static void __init overo_init(void)
        int ret;
 
        omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+       omap_hsmmc_init(mmc);
        overo_i2c_init();
        omap_display_init(&overo_dss_data);
        omap_serial_init();
index 8678b386c6a2ab8e7a0b664546f837eb9966d36f..ae53d71f0ce076bace77dd6fcf26895083dc0b16 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Board support file for Nokia RM-680.
+ * Board support file for Nokia RM-680/696.
  *
  * Copyright (C) 2010 Nokia
  *
@@ -120,7 +120,7 @@ static void __init rm680_peripherals_init(void)
                                ARRAY_SIZE(rm680_peripherals_devices));
        rm680_i2c_init();
        gpmc_onenand_init(board_onenand_data);
-       omap2_hsmmc_init(mmc);
+       omap_hsmmc_init(mmc);
 }
 
 #ifdef CONFIG_OMAP_MUX
@@ -154,3 +154,15 @@ MACHINE_START(NOKIA_RM680, "Nokia RM-680 board")
        .timer          = &omap3_timer,
        .restart        = omap_prcm_restart,
 MACHINE_END
+
+MACHINE_START(NOKIA_RM696, "Nokia RM-696 board")
+       .atag_offset    = 0x100,
+       .reserve        = omap_reserve,
+       .map_io         = omap3_map_io,
+       .init_early     = omap3630_init_early,
+       .init_irq       = omap3_init_irq,
+       .handle_irq     = omap3_intc_handle_irq,
+       .init_machine   = rm680_init,
+       .timer          = &omap3_timer,
+       .restart        = omap_prcm_restart,
+MACHINE_END
index acb4e77b39efd088538ef6d7c6542f64ab6411e1..16aebfb8a7ec7f5061fc0ba77a94469796f666b4 100644 (file)
@@ -138,17 +138,14 @@ static struct lp5523_platform_data rx51_lp5523_platform_data = {
 
 static struct omap2_mcspi_device_config wl1251_mcspi_config = {
        .turbo_mode     = 0,
-       .single_channel = 1,
 };
 
 static struct omap2_mcspi_device_config mipid_mcspi_config = {
        .turbo_mode     = 0,
-       .single_channel = 1,
 };
 
 static struct omap2_mcspi_device_config tsc2005_mcspi_config = {
        .turbo_mode     = 0,
-       .single_channel = 1,
 };
 
 static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = {
@@ -1105,6 +1102,11 @@ static struct tsc2005_platform_data tsc2005_pdata = {
        .esd_timeout_ms         = 8000,
 };
 
+static struct gpio rx51_tsc2005_gpios[] __initdata = {
+       { RX51_TSC2005_IRQ_GPIO,   GPIOF_IN,            "tsc2005 IRQ"   },
+       { RX51_TSC2005_RESET_GPIO, GPIOF_OUT_INIT_HIGH, "tsc2005 reset" },
+};
+
 static void rx51_tsc2005_set_reset(bool enable)
 {
        gpio_set_value(RX51_TSC2005_RESET_GPIO, enable);
@@ -1114,20 +1116,18 @@ static void __init rx51_init_tsc2005(void)
 {
        int r;
 
-       r = gpio_request_one(RX51_TSC2005_IRQ_GPIO, GPIOF_IN, "tsc2005 IRQ");
-       if (r < 0) {
-               printk(KERN_ERR "unable to get %s GPIO\n", "tsc2005 IRQ");
-               rx51_peripherals_spi_board_info[RX51_SPI_TSC2005].irq = 0;
-       }
+       omap_mux_init_gpio(RX51_TSC2005_RESET_GPIO, OMAP_PIN_OUTPUT);
+       omap_mux_init_gpio(RX51_TSC2005_IRQ_GPIO, OMAP_PIN_INPUT_PULLUP);
 
-       r = gpio_request_one(RX51_TSC2005_RESET_GPIO, GPIOF_OUT_INIT_HIGH,
-               "tsc2005 reset");
-       if (r >= 0) {
-               tsc2005_pdata.set_reset = rx51_tsc2005_set_reset;
-       } else {
-               printk(KERN_ERR "unable to get %s GPIO\n", "tsc2005 reset");
+       r = gpio_request_array(rx51_tsc2005_gpios,
+                              ARRAY_SIZE(rx51_tsc2005_gpios));
+       if (r < 0) {
+               printk(KERN_ERR "tsc2005 board initialization failed\n");
                tsc2005_pdata.esd_timeout_ms = 0;
+               return;
        }
+
+       tsc2005_pdata.set_reset = rx51_tsc2005_set_reset;
 }
 
 void __init rx51_peripherals_init(void)
@@ -1145,7 +1145,7 @@ void __init rx51_peripherals_init(void)
 
        partition = omap_mux_get("core");
        if (partition)
-               omap2_hsmmc_init(mmc);
+               omap_hsmmc_init(mmc);
 
        rx51_charger_init();
 }
index d4683ba5f72182aa47ef94267ff9dc97c446b043..a43a765dd0921d1d1fee5fb5d195f0dfdfd68f60 100644 (file)
@@ -55,6 +55,7 @@ static void zoom_panel_disable_lcd(struct omap_dss_device *dssdev)
 
 static int zoom_set_bl_intensity(struct omap_dss_device *dssdev, int level)
 {
+#ifdef CONFIG_TWL4030_CORE
        unsigned char c;
        u8 mux_pwm, enb_pwm;
 
@@ -90,6 +91,9 @@ static int zoom_set_bl_intensity(struct omap_dss_device *dssdev, int level)
        c = ((50 * (100 - level)) / 100) + 1;
        twl_i2c_write_u8(TWL4030_MODULE_PWM1, 0x7F, TWL_LED_PWMOFF);
        twl_i2c_write_u8(TWL4030_MODULE_PWM1, c, TWL_LED_PWMON);
+#else
+       pr_warn("Backlight not enabled\n");
+#endif
 
        return 0;
 }
@@ -117,7 +121,6 @@ static struct omap_dss_board_info zoom_dss_data = {
 
 static struct omap2_mcspi_device_config dss_lcd_mcspi_config = {
        .turbo_mode             = 1,
-       .single_channel = 1,  /* 0: slave, 1: master */
 };
 
 static struct spi_board_info nec_8048_spi_board_info[] __initdata = {
index c126461836ac5d2134314b82c80dae0eb41fcf60..3d39cdb2e25021704b511ca3c6b45dce606243b0 100644 (file)
@@ -205,6 +205,7 @@ static struct omap2_hsmmc_info mmc[] = {
                .caps           = MMC_CAP_4_BIT_DATA,
                .gpio_wp        = -EINVAL,
                .power_saving   = true,
+               .deferred       = true,
        },
        {
                .name           = "internal",
@@ -233,7 +234,7 @@ static int zoom_twl_gpio_setup(struct device *dev,
 
        /* gpio + 0 is "mmc0_cd" (input/IRQ) */
        mmc[0].gpio_cd = gpio + 0;
-       omap2_hsmmc_init(mmc);
+       omap_hsmmc_late_init(mmc);
 
        ret = gpio_request_one(LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW,
                               "lcd enable");
@@ -301,6 +302,7 @@ void __init zoom_peripherals_init(void)
        if (ret)
                pr_err("error setting wl12xx data: %d\n", ret);
 
+       omap_hsmmc_init(mmc);
        omap_i2c_init();
        platform_device_register(&omap_vwlan_device);
        usb_musb_init(NULL);
index 39f9d5a58d0cdb123fd8c161747ed6bd68b69b54..7072e0d651b12356ec889158dde5102c5e7d6100 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/cpufreq.h>
 #include <linux/slab.h>
 
+#include <plat/cpu.h>
 #include <plat/clock.h>
 #include <plat/sram.h>
 #include <plat/sdrc.h>
index e25364de028a8ba7a1eb0f418177d7cdb7dee4d6..04d551b1f7f75fd43f91ed49abf1b017dfcf95e6 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/errno.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/bug.h>
 
 #include <plat/clock.h>
 
index e069a9be93dfe0e9aafc3411e560de700529e13a..cd7fd0f911495103bb066faa35eb1f68456f59ba 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/div64.h>
 
 #include <plat/clock.h>
+#include <plat/cpu.h>
 
 #include "clock.h"
 #include "cm-regbits-24xx.h"
index 61ad3855f10a61e479e994d547e9d0955aed166d..bace9308a4db89616b780f310738f35c6cee5644 100644 (file)
  */
 
 #include <linux/kernel.h>
+#include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/list.h>
 
+#include <plat/hardware.h>
 #include <plat/clkdev_omap.h>
 
+#include "iomap.h"
 #include "clock.h"
 #include "clock2xxx.h"
 #include "opp2xxx.h"
index d87bc9cb2a3621fda942c7976ee7c16d6e8f5f6e..dfda9a3f2cb2885a6a4664577ee6036e7f360ffd 100644 (file)
 #include <linux/clk.h>
 #include <linux/io.h>
 
+#include <plat/hardware.h>
 #include <plat/clock.h>
 
+#include "iomap.h"
 #include "clock.h"
 #include "clock2xxx.h"
 #include "cm2xxx_3xxx.h"
index 0cc12879e7b955b1bee0e256e597d34c42b51f57..3b4d09a5039905687b2723adbad0d76add914221 100644 (file)
 #include <linux/clk.h>
 #include <linux/list.h>
 
+#include <plat/hardware.h>
 #include <plat/clkdev_omap.h>
 
+#include "iomap.h"
 #include "clock.h"
 #include "clock2xxx.h"
 #include "opp2xxx.h"
index 80bb0f0e92e6e5c47b89fdd87df7eaed27a8e9f0..12500097378dcd64fd90c784aaa2c46977607522 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 
+#include <plat/cpu.h>
 #include <plat/clock.h>
 
 #include "clock.h"
index 952c3e01c9eb93239725173def94f8fbbf31853e..794d82702c85902fdd4d71a999b09be3abd73704 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 
+#include <plat/hardware.h>
 #include <plat/clock.h>
 
 #include "clock.h"
index d75e5f6b8a0104969d285e8ff80e162ab53bb475..981b9f9111a417e959aec8e111bce0e61238e9be 100644 (file)
 #include <linux/clk.h>
 #include <linux/list.h>
 
+#include <plat/hardware.h>
 #include <plat/clkdev_omap.h>
 
+#include "iomap.h"
 #include "clock.h"
 #include "clock3xxx.h"
 #include "clock34xx.h"
 #include "clock36xx.h"
 #include "clock3517.h"
-
 #include "cm2xxx_3xxx.h"
 #include "cm-regbits-34xx.h"
 #include "prm2xxx_3xxx.h"
index 08e86d793a1f3e86671546a63f080b8c84573ce4..79b98f22f207825c896dddac914f8e7a0536dea1 100644 (file)
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/clk.h>
+
+#include <plat/hardware.h>
 #include <plat/clkdev_omap.h>
 
+#include "iomap.h"
 #include "clock.h"
 #include "clock44xx.h"
 #include "cm1_44xx.h"
index 04d39cdd211204325856727b45b234d5edc0cdd1..389f9f8b570c751dcdbf94d50e8e09521588dec7 100644 (file)
 #include <linux/err.h>
 #include <linux/io.h>
 
-#include "common.h"
+#include <plat/hardware.h>
 
+#include "iomap.h"
+#include "common.h"
 #include "cm.h"
 #include "cm2xxx_3xxx.h"
 #include "cm-regbits-24xx.h"
index 6a836303252cb62aef1ced08fb3edcb0bcbe75ee..535d66e2822c26ebe37f2fcaf509d678bb9570b4 100644 (file)
@@ -18,8 +18,8 @@
 #include <linux/err.h>
 #include <linux/io.h>
 
+#include "iomap.h"
 #include "common.h"
-
 #include "cm.h"
 #include "cm1_44xx.h"
 #include "cm2_44xx.h"
index 6204deaf85b1f06daba9d0b9db758cf31cdb1fb3..bd8810c3753f2436b1268eddfaf788149147fbbf 100644 (file)
@@ -20,8 +20,8 @@
 #include <linux/err.h>
 #include <linux/io.h>
 
+#include "iomap.h"
 #include "common.h"
-
 #include "cm.h"
 #include "cm1_44xx.h"
 #include "cm2_44xx.h"
index bcb0c5817167095b7d2b0edc536ab663a9463bd3..9498b0f5fbd081403d88569bfc314a331f9f3cd9 100644 (file)
@@ -33,7 +33,6 @@
        defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
 static struct omap2_mcspi_device_config ads7846_mcspi_config = {
        .turbo_mode     = 0,
-       .single_channel = 1,    /* 0: slave, 1: master */
 };
 
 static struct ads7846_platform_data ads7846_config = {
@@ -76,13 +75,15 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
                        gpio_set_debounce(gpio_pendown, gpio_debounce);
        }
 
-       ads7846_config.gpio_pendown = gpio_pendown;
-
        spi_bi->bus_num = bus_num;
        spi_bi->irq     = OMAP_GPIO_IRQ(gpio_pendown);
 
-       if (board_pdata)
+       if (board_pdata) {
+               board_pdata->gpio_pendown = gpio_pendown;
                spi_bi->platform_data = board_pdata;
+       } else {
+               ads7846_config.gpio_pendown = gpio_pendown;
+       }
 
        spi_register_board_info(&ads7846_spi_board_info, 1);
 }
index aaf421178c919ad0c4b77fda64f18fe446c509a8..1549c11000d32687190c7f86e742f018a8eba95f 100644 (file)
 #include <linux/clk.h>
 #include <linux/io.h>
 
-#include "common.h"
+#include <plat/hardware.h>
 #include <plat/board.h>
 #include <plat/mux.h>
-
 #include <plat/clock.h>
 
+#include "iomap.h"
+#include "common.h"
 #include "sdrc.h"
 #include "control.h"
 
index 7e9338e8d684c7ff442a517be55de218ba34e8c7..57da7f406e28c9cca72cbfb397db288704a019de 100644 (file)
@@ -134,6 +134,8 @@ void omap4_map_io(void);
 void ti81xx_map_io(void);
 void omap_barriers_init(void);
 
+extern void __init omap_init_consistent_dma_size(void);
+
 /**
  * omap_test_timeout - busy-loop, testing a condition
  * @cond: condition to test until it evaluates to true
@@ -175,6 +177,18 @@ void omap3_intc_handle_irq(struct pt_regs *regs);
 extern void __iomem *omap4_get_l2cache_base(void);
 #endif
 
+struct device_node;
+#ifdef CONFIG_OF
+int __init omap_intc_of_init(struct device_node *node,
+                            struct device_node *parent);
+#else
+int __init omap_intc_of_init(struct device_node *node,
+                            struct device_node *parent)
+{
+       return 0;
+}
+#endif
+
 #ifdef CONFIG_SMP
 extern void __iomem *omap4_get_scu_base(void);
 #else
@@ -236,5 +250,10 @@ static inline u32 omap4_mpuss_read_prev_context_state(void)
        return 0;
 }
 #endif
+
+struct omap_sdrc_params;
+extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
+                                     struct omap_sdrc_params *sdrc_cs1);
+
 #endif /* __ASSEMBLER__ */
 #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */
index 114c037e433c77f33673c39c599dd3d32190187e..08e674bb04171c2e6b81d97be51a7cab6e697d0c 100644 (file)
 #include <linux/kernel.h>
 #include <linux/io.h>
 
-#include "common.h"
+#include <plat/hardware.h>
 #include <plat/sdrc.h>
 
+#include "iomap.h"
+#include "common.h"
 #include "cm-regbits-34xx.h"
 #include "prm-regbits-34xx.h"
 #include "prm2xxx_3xxx.h"
index 0ba68d3764bc932b3ff85091203559b5f0d323be..a406fd045ce13e18649b488a663cc21c6520a415 100644 (file)
@@ -16,7 +16,6 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_CONTROL_H
 #define __ARCH_ARM_MACH_OMAP2_CONTROL_H
 
-#include <mach/io.h>
 #include <mach/ctrl_module_core_44xx.h>
 #include <mach/ctrl_module_wkup_44xx.h>
 #include <mach/ctrl_module_pad_core_44xx.h>
 #define AM35XX_HECC_SW_RST             BIT(3)
 #define AM35XX_VPFE_PCLK_SW_RST                BIT(4)
 
+/*
+ * CONTROL AM33XX STATUS register
+ */
+#define AM33XX_CONTROL_STATUS          0x040
+
 /*
  * CONTROL OMAP STATUS register to identify OMAP3 features
  */
index f713818be06fea194324f5f9eaadbc3357d0946d..e4336035c0ea85f94ce4e9d4e6b1cd0752e1f5e4 100644 (file)
@@ -25,7 +25,7 @@
 #include <asm/mach/map.h>
 #include <asm/pmu.h>
 
-#include <plat/tc.h>
+#include "iomap.h"
 #include <plat/board.h>
 #include <plat/mmc.h>
 #include <plat/dma.h>
@@ -276,7 +276,7 @@ int __init omap4_keyboard_init(struct omap4_keypad_platform_data
 }
 
 #if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE)
-static inline void omap_init_mbox(void)
+static inline void __init omap_init_mbox(void)
 {
        struct omap_hwmod *oh;
        struct platform_device *pdev;
@@ -316,7 +316,7 @@ static inline void omap_init_audio(void) {}
 #if defined(CONFIG_SND_OMAP_SOC_MCPDM) || \
                defined(CONFIG_SND_OMAP_SOC_MCPDM_MODULE)
 
-static void omap_init_mcpdm(void)
+static void __init omap_init_mcpdm(void)
 {
        struct omap_hwmod *oh;
        struct platform_device *pdev;
@@ -337,7 +337,7 @@ static inline void omap_init_mcpdm(void) {}
 #if defined(CONFIG_SND_OMAP_SOC_DMIC) || \
                defined(CONFIG_SND_OMAP_SOC_DMIC_MODULE)
 
-static void omap_init_dmic(void)
+static void __init omap_init_dmic(void)
 {
        struct omap_hwmod *oh;
        struct platform_device *pdev;
@@ -359,7 +359,7 @@ static inline void omap_init_dmic(void) {}
 
 #include <plat/mcspi.h>
 
-static int omap_mcspi_init(struct omap_hwmod *oh, void *unused)
+static int __init omap_mcspi_init(struct omap_hwmod *oh, void *unused)
 {
        struct platform_device *pdev;
        char *name = "omap2_mcspi";
@@ -633,9 +633,7 @@ void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data)
 /*-------------------------------------------------------------------------*/
 
 #if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE)
-#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430)
 #define OMAP_HDQ_BASE  0x480B2000
-#endif
 static struct resource omap_hdq_resources[] = {
        {
                .start          = OMAP_HDQ_BASE,
@@ -658,7 +656,10 @@ static struct platform_device omap_hdq_dev = {
 };
 static inline void omap_hdq_init(void)
 {
-       (void) platform_device_register(&omap_hdq_dev);
+       if (cpu_is_omap2420())
+               return;
+
+       platform_device_register(&omap_hdq_dev);
 }
 #else
 static inline void omap_hdq_init(void) {}
index 3677b1f58b85f32c25e9c4f1e886a0e259ee9102..9706c648bc19b53c7f9d7b2abd5d4d411e956fac 100644 (file)
@@ -30,6 +30,7 @@
 #include <plat/omap-pm.h>
 #include "common.h"
 
+#include "iomap.h"
 #include "mux.h"
 #include "control.h"
 #include "display.h"
@@ -124,7 +125,7 @@ static void omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
        }
 }
 
-static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
+static int __init omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
 {
        u32 enable_mask, enable_shift;
        u32 pipd_mask, pipd_shift;
@@ -157,7 +158,7 @@ static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
        return 0;
 }
 
-int omap_hdmi_init(enum omap_hdmi_flags flags)
+int __init omap_hdmi_init(enum omap_hdmi_flags flags)
 {
        if (cpu_is_omap44xx())
                omap4_hdmi_mux_pads(flags);
@@ -165,7 +166,7 @@ int omap_hdmi_init(enum omap_hdmi_flags flags)
        return 0;
 }
 
-static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
+static int __init omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
 {
        if (cpu_is_omap44xx())
                return omap4_dsi_mux_pads(dsi_id, lane_mask);
@@ -173,7 +174,7 @@ static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
        return 0;
 }
 
-static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
+static void __init omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
 {
        if (cpu_is_omap44xx())
                omap4_dsi_mux_pads(dsi_id, 0);
index a59a45a0096ef77276811c6641a39e8149ceef5c..b19d8496c16ed2dd1e62eb4afb29a08c27052110 100644 (file)
@@ -227,7 +227,7 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
 
        dma_stride              = OMAP2_DMA_STRIDE;
        dma_common_ch_start     = CSDP;
-       if (cpu_is_omap3630() || cpu_is_omap4430())
+       if (cpu_is_omap3630() || cpu_is_omap44xx())
                dma_common_ch_end = CCDN;
        else
                dma_common_ch_end = CCFN;
index ce91aad4cdad5048548c28c8e224f93e2e28bf48..e28e761b7ab9ef8fc3366a28736b26eb40c62f1d 100644 (file)
 #include <linux/clk.h>
 #include <linux/err.h>
 
+#include <mach/hardware.h>
+
+#include "iomap.h"
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Alexander Shishkin");
 
index 8cbfbc2918ce3b88168dadd29cdc90d0e530ffe7..2f994e5194e85c932836421f79b90fe7efe0ce4c 100644 (file)
 
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
+#include <plat/omap-pm.h>
 
-static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
+#include "powerdomain.h"
+
+static int __init omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
 {
        struct platform_device *pdev;
        struct omap_gpio_platform_data *pdata;
        struct omap_gpio_dev_attr *dev_attr;
        char *name = "omap_gpio";
        int id;
+       struct powerdomain *pwrdm;
 
        /*
         * extract the device id from name field available in the
@@ -52,7 +56,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
        pdata->bank_width = dev_attr->bank_width;
        pdata->dbck_flag = dev_attr->dbck_flag;
        pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1);
-
+       pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
        pdata->regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL);
        if (!pdata) {
                pr_err("gpio%d: Memory allocation failed\n", id);
@@ -61,8 +65,15 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
 
        switch (oh->class->rev) {
        case 0:
+               if (id == 1)
+                       /* non-wakeup GPIO pins for OMAP2 Bank1 */
+                       pdata->non_wakeup_gpios = 0xe203ffc0;
+               else if (id == 2)
+                       /* non-wakeup GPIO pins for OMAP2 Bank2 */
+                       pdata->non_wakeup_gpios = 0x08700040;
+               /* fall through */
+
        case 1:
-               pdata->bank_type = METHOD_GPIO_24XX;
                pdata->regs->revision = OMAP24XX_GPIO_REVISION;
                pdata->regs->direction = OMAP24XX_GPIO_OE;
                pdata->regs->datain = OMAP24XX_GPIO_DATAIN;
@@ -72,13 +83,19 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
                pdata->regs->irqstatus = OMAP24XX_GPIO_IRQSTATUS1;
                pdata->regs->irqstatus2 = OMAP24XX_GPIO_IRQSTATUS2;
                pdata->regs->irqenable = OMAP24XX_GPIO_IRQENABLE1;
+               pdata->regs->irqenable2 = OMAP24XX_GPIO_IRQENABLE2;
                pdata->regs->set_irqenable = OMAP24XX_GPIO_SETIRQENABLE1;
                pdata->regs->clr_irqenable = OMAP24XX_GPIO_CLEARIRQENABLE1;
                pdata->regs->debounce = OMAP24XX_GPIO_DEBOUNCE_VAL;
                pdata->regs->debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN;
+               pdata->regs->ctrl = OMAP24XX_GPIO_CTRL;
+               pdata->regs->wkup_en = OMAP24XX_GPIO_WAKE_EN;
+               pdata->regs->leveldetect0 = OMAP24XX_GPIO_LEVELDETECT0;
+               pdata->regs->leveldetect1 = OMAP24XX_GPIO_LEVELDETECT1;
+               pdata->regs->risingdetect = OMAP24XX_GPIO_RISINGDETECT;
+               pdata->regs->fallingdetect = OMAP24XX_GPIO_FALLINGDETECT;
                break;
        case 2:
-               pdata->bank_type = METHOD_GPIO_44XX;
                pdata->regs->revision = OMAP4_GPIO_REVISION;
                pdata->regs->direction = OMAP4_GPIO_OE;
                pdata->regs->datain = OMAP4_GPIO_DATAIN;
@@ -88,10 +105,17 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
                pdata->regs->irqstatus = OMAP4_GPIO_IRQSTATUS0;
                pdata->regs->irqstatus2 = OMAP4_GPIO_IRQSTATUS1;
                pdata->regs->irqenable = OMAP4_GPIO_IRQSTATUSSET0;
+               pdata->regs->irqenable2 = OMAP4_GPIO_IRQSTATUSSET1;
                pdata->regs->set_irqenable = OMAP4_GPIO_IRQSTATUSSET0;
                pdata->regs->clr_irqenable = OMAP4_GPIO_IRQSTATUSCLR0;
                pdata->regs->debounce = OMAP4_GPIO_DEBOUNCINGTIME;
                pdata->regs->debounce_en = OMAP4_GPIO_DEBOUNCENABLE;
+               pdata->regs->ctrl = OMAP4_GPIO_CTRL;
+               pdata->regs->wkup_en = OMAP4_GPIO_IRQWAKEN0;
+               pdata->regs->leveldetect0 = OMAP4_GPIO_LEVELDETECT0;
+               pdata->regs->leveldetect1 = OMAP4_GPIO_LEVELDETECT1;
+               pdata->regs->risingdetect = OMAP4_GPIO_RISINGDETECT;
+               pdata->regs->fallingdetect = OMAP4_GPIO_FALLINGDETECT;
                break;
        default:
                WARN(1, "Invalid gpio bank_type\n");
@@ -99,6 +123,9 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
                return -EINVAL;
        }
 
+       pwrdm = omap_hwmod_get_pwrdm(oh);
+       pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm);
+
        pdev = omap_device_build(name, id - 1, oh, pdata,
                                sizeof(*pdata), NULL, 0, false);
        kfree(pdata);
@@ -109,9 +136,6 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
                return PTR_ERR(pdev);
        }
 
-       omap_device_disable_idle_on_suspend(pdev);
-
-       gpio_bank_count++;
        return 0;
 }
 
index 8ad210bda9a996072df12625382875fee0b75c26..386dec8d2351635c2004e9ff082048c2a09264de 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <asm/mach/flash.h>
 
+#include <plat/cpu.h>
 #include <plat/nand.h>
 #include <plat/board.h>
 #include <plat/gpmc.h>
index 5cdce10d61835d50f9ebca84d108f6b31509cb5b..385b3e02c4a696b0a28a218b54027daf98def1b4 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <asm/mach/flash.h>
 
+#include <plat/cpu.h>
 #include <plat/onenand.h>
 #include <plat/board.h>
 #include <plat/gpmc.h>
index bbb870c04a5e3ed3aa4f61777c187f3e33358ee9..5e5880d6d099e9a17e29436f7515f27ad2f94093 100644 (file)
@@ -101,10 +101,13 @@ void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *board_data)
 
        gpmc_cfg = board_data;
 
-       ret = platform_device_register(&gpmc_smsc911x_regulator);
-       if (ret < 0) {
-               pr_err("Unable to register smsc911x regulators: %d\n", ret);
-               return;
+       if (!gpmc_cfg->id) {
+               ret = platform_device_register(&gpmc_smsc911x_regulator);
+               if (ret < 0) {
+                       pr_err("Unable to register smsc911x regulators: %d\n",
+                              ret);
+                       return;
+               }
        }
 
        if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) {
index dfffbbf4c009624c87375b6322a2a7285cd8a2e7..00d510858e287fa41c2f3a893553e59dc205a7a8 100644 (file)
@@ -888,6 +888,7 @@ int gpmc_enable_hwecc(int cs, int mode, int dev_width, int ecc_size)
        gpmc_write_reg(GPMC_ECC_CONFIG, val);
        return 0;
 }
+EXPORT_SYMBOL_GPL(gpmc_enable_hwecc);
 
 /**
  * gpmc_calculate_ecc - generate non-inverted ecc bytes
@@ -918,3 +919,4 @@ int gpmc_calculate_ecc(int cs, const u_char *dat, u_char *ecc_code)
        gpmc_ecc_used = -EINVAL;
        return 0;
 }
+EXPORT_SYMBOL_GPL(gpmc_calculate_ecc);
index 19dd1657245c58634dc3ac1e8005e823e7360dd5..8121720e942ffdb10d14cd6fdde29aa691f7446e 100644 (file)
@@ -293,8 +293,8 @@ static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller,
        }
 }
 
-static int omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
-                                struct omap_mmc_platform_data *mmc)
+static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
+                                       struct omap_mmc_platform_data *mmc)
 {
        char *hc_name;
 
@@ -429,66 +429,131 @@ static int omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
 }
 
 static int omap_hsmmc_done;
+
+void omap_hsmmc_late_init(struct omap2_hsmmc_info *c)
+{
+       struct platform_device *pdev;
+       struct omap_mmc_platform_data *mmc_pdata;
+       int res;
+
+       if (omap_hsmmc_done != 1)
+               return;
+
+       omap_hsmmc_done++;
+
+       for (; c->mmc; c++) {
+               if (!c->deferred)
+                       continue;
+
+               pdev = c->pdev;
+               if (!pdev)
+                       continue;
+
+               mmc_pdata = pdev->dev.platform_data;
+               if (!mmc_pdata)
+                       continue;
+
+               mmc_pdata->slots[0].switch_pin = c->gpio_cd;
+               mmc_pdata->slots[0].gpio_wp = c->gpio_wp;
+
+               res = omap_device_register(pdev);
+               if (res)
+                       pr_err("Could not late init MMC %s\n",
+                              c->name);
+       }
+}
+
 #define MAX_OMAP_MMC_HWMOD_NAME_LEN            16
 
-void omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
+static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo,
+                                       int ctrl_nr)
 {
        struct omap_hwmod *oh;
+       struct omap_hwmod *ohs[1];
+       struct omap_device *od;
        struct platform_device *pdev;
        char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN];
        struct omap_mmc_platform_data *mmc_data;
        struct omap_mmc_dev_attr *mmc_dev_attr;
        char *name;
-       int l;
+       int res;
 
        mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
        if (!mmc_data) {
                pr_err("Cannot allocate memory for mmc device!\n");
-               goto done;
+               return;
        }
 
-       if (omap_hsmmc_pdata_init(hsmmcinfo, mmc_data) < 0) {
-               pr_err("%s fails!\n", __func__);
-               goto done;
-       }
+       res = omap_hsmmc_pdata_init(hsmmcinfo, mmc_data);
+       if (res < 0)
+               goto free_mmc;
+
        omap_hsmmc_mux(mmc_data, (ctrl_nr - 1));
 
        name = "omap_hsmmc";
-
-       l = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN,
+       res = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN,
                     "mmc%d", ctrl_nr);
-       WARN(l >= MAX_OMAP_MMC_HWMOD_NAME_LEN,
+       WARN(res >= MAX_OMAP_MMC_HWMOD_NAME_LEN,
             "String buffer overflow in MMC%d device setup\n", ctrl_nr);
+
        oh = omap_hwmod_lookup(oh_name);
        if (!oh) {
                pr_err("Could not look up %s\n", oh_name);
-               kfree(mmc_data->slots[0].name);
-               goto done;
+               goto free_name;
        }
-
+       ohs[0] = oh;
        if (oh->dev_attr != NULL) {
                mmc_dev_attr = oh->dev_attr;
                mmc_data->controller_flags = mmc_dev_attr->flags;
        }
 
-       pdev = omap_device_build(name, ctrl_nr - 1, oh, mmc_data,
-               sizeof(struct omap_mmc_platform_data), NULL, 0, false);
-       if (IS_ERR(pdev)) {
-               WARN(1, "Can't build omap_device for %s:%s.\n", name, oh->name);
-               kfree(mmc_data->slots[0].name);
-               goto done;
+       pdev = platform_device_alloc(name, ctrl_nr - 1);
+       if (!pdev) {
+               pr_err("Could not allocate pdev for %s\n", name);
+               goto free_name;
        }
-       /*
-        * return device handle to board setup code
-        * required to populate for regulator framework structure
-        */
-       hsmmcinfo->dev = &pdev->dev;
+       dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
+
+       od = omap_device_alloc(pdev, ohs, 1, NULL, 0);
+       if (!od) {
+               pr_err("Could not allocate od for %s\n", name);
+               goto put_pdev;
+       }
+
+       res = platform_device_add_data(pdev, mmc_data,
+                             sizeof(struct omap_mmc_platform_data));
+       if (res) {
+               pr_err("Could not add pdata for %s\n", name);
+               goto put_pdev;
+       }
+
+       hsmmcinfo->pdev = pdev;
+
+       if (hsmmcinfo->deferred)
+               goto free_mmc;
+
+       res = omap_device_register(pdev);
+       if (res) {
+               pr_err("Could not register od for %s\n", name);
+               goto free_od;
+       }
+
+       goto free_mmc;
+
+free_od:
+       omap_device_delete(od);
+
+put_pdev:
+       platform_device_put(pdev);
+
+free_name:
+       kfree(mmc_data->slots[0].name);
 
-done:
+free_mmc:
        kfree(mmc_data);
 }
 
-void omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
+void __init omap_hsmmc_init(struct omap2_hsmmc_info *controllers)
 {
        u32 reg;
 
@@ -521,7 +586,7 @@ void omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
        }
 
        for (; controllers->mmc; controllers++)
-               omap_init_hsmmc(controllers, controllers->mmc);
+               omap_hsmmc_init_one(controllers, controllers->mmc);
 
 }
 
index c4409730c4bb6ea18d4c0b93f9bd7fab612e20a5..07831cc3c171d39bcc96b1f3fa8e20615ac804ba 100644 (file)
@@ -21,10 +21,11 @@ struct omap2_hsmmc_info {
        bool    no_off;         /* power_saving and power is not to go off */
        bool    no_off_init;    /* no power off when not in MMC sleep state */
        bool    vcc_aux_disable_is_sleep; /* Regulator off remapped to sleep */
+       bool    deferred;       /* mmc needs a deferred probe */
        int     gpio_cd;        /* or -EINVAL */
        int     gpio_wp;        /* or -EINVAL */
        char    *name;          /* or NULL for default */
-       struct device *dev;     /* returned: pointer to mmc adapter */
+       struct platform_device *pdev;   /* mmc controller instance */
        int     ocr_mask;       /* temporary HACK */
        /* Remux (pad configuration) when powering on/off */
        void (*remux)(struct device *dev, int slot, int power_on);
@@ -34,11 +35,16 @@ struct omap2_hsmmc_info {
 
 #if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
 
-void omap2_hsmmc_init(struct omap2_hsmmc_info *);
+void omap_hsmmc_init(struct omap2_hsmmc_info *);
+void omap_hsmmc_late_init(struct omap2_hsmmc_info *);
 
 #else
 
-static inline void omap2_hsmmc_init(struct omap2_hsmmc_info *info)
+static inline void omap_hsmmc_init(struct omap2_hsmmc_info *info)
+{
+}
+
+static inline void omap_hsmmc_late_init(struct omap2_hsmmc_info *info)
 {
 }
 
index 719ee423abe22be6439cb4b3dd0ce78dcecb41b5..0e79b7bc6aa441b7ddc47507440e821752a52079 100644 (file)
@@ -29,7 +29,7 @@
 #include "control.h"
 
 static unsigned int omap_revision;
-
+static const char *cpu_rev;
 u32 omap_features;
 
 unsigned int omap_rev(void)
@@ -44,6 +44,8 @@ int omap_type(void)
 
        if (cpu_is_omap24xx()) {
                val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
+       } else if (cpu_is_am33xx()) {
+               val = omap_ctrl_readl(AM33XX_CONTROL_STATUS);
        } else if (cpu_is_omap34xx()) {
                val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS);
        } else if (cpu_is_omap44xx()) {
@@ -112,7 +114,7 @@ void omap_get_die_id(struct omap_die_id *odi)
        odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_3);
 }
 
-static void __init omap24xx_check_revision(void)
+void __init omap2xxx_check_revision(void)
 {
        int i, j;
        u32 idcode, prod_id;
@@ -166,13 +168,63 @@ static void __init omap24xx_check_revision(void)
        pr_info("\n");
 }
 
+#define OMAP3_SHOW_FEATURE(feat)               \
+       if (omap3_has_ ##feat())                \
+               printk(#feat" ");
+
+static void __init omap3_cpuinfo(void)
+{
+       const char *cpu_name;
+
+       /*
+        * OMAP3430 and OMAP3530 are assumed to be same.
+        *
+        * OMAP3525, OMAP3515 and OMAP3503 can be detected only based
+        * on available features. Upon detection, update the CPU id
+        * and CPU class bits.
+        */
+       if (cpu_is_omap3630()) {
+               cpu_name = "OMAP3630";
+       } else if (cpu_is_omap3517()) {
+               /* AM35xx devices */
+               cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505";
+       } else if (cpu_is_ti816x()) {
+               cpu_name = "TI816X";
+       } else if (cpu_is_am335x()) {
+               cpu_name =  "AM335X";
+       } else if (cpu_is_ti814x()) {
+               cpu_name = "TI814X";
+       } else if (omap3_has_iva() && omap3_has_sgx()) {
+               /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */
+               cpu_name = "OMAP3430/3530";
+       } else if (omap3_has_iva()) {
+               cpu_name = "OMAP3525";
+       } else if (omap3_has_sgx()) {
+               cpu_name = "OMAP3515";
+       } else {
+               cpu_name = "OMAP3503";
+       }
+
+       /* Print verbose information */
+       pr_info("%s ES%s (", cpu_name, cpu_rev);
+
+       OMAP3_SHOW_FEATURE(l2cache);
+       OMAP3_SHOW_FEATURE(iva);
+       OMAP3_SHOW_FEATURE(sgx);
+       OMAP3_SHOW_FEATURE(neon);
+       OMAP3_SHOW_FEATURE(isp);
+       OMAP3_SHOW_FEATURE(192mhz_clk);
+
+       printk(")\n");
+}
+
 #define OMAP3_CHECK_FEATURE(status,feat)                               \
        if (((status & OMAP3_ ##feat## _MASK)                           \
                >> OMAP3_ ##feat## _SHIFT) != FEAT_ ##feat## _NONE) {   \
                omap_features |= OMAP3_HAS_ ##feat;                     \
        }
 
-static void __init omap3_check_features(void)
+void __init omap3xxx_check_features(void)
 {
        u32 status;
 
@@ -199,9 +251,11 @@ static void __init omap3_check_features(void)
         * TODO: Get additional info (where applicable)
         *       e.g. Size of L2 cache.
         */
+
+       omap3_cpuinfo();
 }
 
-static void __init omap4_check_features(void)
+void __init omap4xxx_check_features(void)
 {
        u32 si_type;
 
@@ -226,12 +280,13 @@ static void __init omap4_check_features(void)
        }
 }
 
-static void __init ti81xx_check_features(void)
+void __init ti81xx_check_features(void)
 {
        omap_features = OMAP3_HAS_NEON;
+       omap3_cpuinfo();
 }
 
-static void __init omap3_check_revision(const char **cpu_rev)
+void __init omap3xxx_check_revision(void)
 {
        u32 cpuid, idcode;
        u16 hawkeye;
@@ -245,7 +300,7 @@ static void __init omap3_check_revision(const char **cpu_rev)
        cpuid = read_cpuid(CPUID_ID);
        if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) {
                omap_revision = OMAP3430_REV_ES1_0;
-               *cpu_rev = "1.0";
+               cpu_rev = "1.0";
                return;
        }
 
@@ -266,26 +321,26 @@ static void __init omap3_check_revision(const char **cpu_rev)
                case 0: /* Take care of early samples */
                case 1:
                        omap_revision = OMAP3430_REV_ES2_0;
-                       *cpu_rev = "2.0";
+                       cpu_rev = "2.0";
                        break;
                case 2:
                        omap_revision = OMAP3430_REV_ES2_1;
-                       *cpu_rev = "2.1";
+                       cpu_rev = "2.1";
                        break;
                case 3:
                        omap_revision = OMAP3430_REV_ES3_0;
-                       *cpu_rev = "3.0";
+                       cpu_rev = "3.0";
                        break;
                case 4:
                        omap_revision = OMAP3430_REV_ES3_1;
-                       *cpu_rev = "3.1";
+                       cpu_rev = "3.1";
                        break;
                case 7:
                /* FALLTHROUGH */
                default:
                        /* Use the latest known revision as default */
                        omap_revision = OMAP3430_REV_ES3_1_2;
-                       *cpu_rev = "3.1.2";
+                       cpu_rev = "3.1.2";
                }
                break;
        case 0xb868:
@@ -298,13 +353,13 @@ static void __init omap3_check_revision(const char **cpu_rev)
                switch (rev) {
                case 0:
                        omap_revision = OMAP3517_REV_ES1_0;
-                       *cpu_rev = "1.0";
+                       cpu_rev = "1.0";
                        break;
                case 1:
                /* FALLTHROUGH */
                default:
                        omap_revision = OMAP3517_REV_ES1_1;
-                       *cpu_rev = "1.1";
+                       cpu_rev = "1.1";
                }
                break;
        case 0xb891:
@@ -313,36 +368,36 @@ static void __init omap3_check_revision(const char **cpu_rev)
                switch(rev) {
                case 0: /* Take care of early samples */
                        omap_revision = OMAP3630_REV_ES1_0;
-                       *cpu_rev = "1.0";
+                       cpu_rev = "1.0";
                        break;
                case 1:
                        omap_revision = OMAP3630_REV_ES1_1;
-                       *cpu_rev = "1.1";
+                       cpu_rev = "1.1";
                        break;
                case 2:
                /* FALLTHROUGH */
                default:
                        omap_revision = OMAP3630_REV_ES1_2;
-                       *cpu_rev = "1.2";
+                       cpu_rev = "1.2";
                }
                break;
        case 0xb81e:
                switch (rev) {
                case 0:
                        omap_revision = TI8168_REV_ES1_0;
-                       *cpu_rev = "1.0";
+                       cpu_rev = "1.0";
                        break;
                case 1:
                /* FALLTHROUGH */
                default:
                        omap_revision = TI8168_REV_ES1_1;
-                       *cpu_rev = "1.1";
+                       cpu_rev = "1.1";
                        break;
                }
                break;
        case 0xb944:
                omap_revision = AM335X_REV_ES1_0;
-               *cpu_rev = "1.0";
+               cpu_rev = "1.0";
                break;
        case 0xb8f2:
                switch (rev) {
@@ -350,29 +405,29 @@ static void __init omap3_check_revision(const char **cpu_rev)
                /* FALLTHROUGH */
                case 1:
                        omap_revision = TI8148_REV_ES1_0;
-                       *cpu_rev = "1.0";
+                       cpu_rev = "1.0";
                        break;
                case 2:
                        omap_revision = TI8148_REV_ES2_0;
-                       *cpu_rev = "2.0";
+                       cpu_rev = "2.0";
                        break;
                case 3:
                /* FALLTHROUGH */
                default:
                        omap_revision = TI8148_REV_ES2_1;
-                       *cpu_rev = "2.1";
+                       cpu_rev = "2.1";
                        break;
                }
                break;
        default:
                /* Unknown default to latest silicon rev as default */
                omap_revision = OMAP3630_REV_ES1_2;
-               *cpu_rev = "1.2";
+               cpu_rev = "1.2";
                pr_warn("Warning: unknown chip type; assuming OMAP3630ES1.2\n");
        }
 }
 
-static void __init omap4_check_revision(void)
+void __init omap4xxx_check_revision(void)
 {
        u32 idcode;
        u16 hawkeye;
@@ -445,89 +500,6 @@ static void __init omap4_check_revision(void)
                ((omap_rev() >> 12) & 0xf), ((omap_rev() >> 8) & 0xf));
 }
 
-#define OMAP3_SHOW_FEATURE(feat)               \
-       if (omap3_has_ ##feat())                \
-               printk(#feat" ");
-
-static void __init omap3_cpuinfo(const char *cpu_rev)
-{
-       const char *cpu_name;
-
-       /*
-        * OMAP3430 and OMAP3530 are assumed to be same.
-        *
-        * OMAP3525, OMAP3515 and OMAP3503 can be detected only based
-        * on available features. Upon detection, update the CPU id
-        * and CPU class bits.
-        */
-       if (cpu_is_omap3630()) {
-               cpu_name = "OMAP3630";
-       } else if (cpu_is_omap3517()) {
-               /* AM35xx devices */
-               cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505";
-       } else if (cpu_is_ti816x()) {
-               cpu_name = "TI816X";
-       } else if (cpu_is_am335x()) {
-               cpu_name =  "AM335X";
-       } else if (cpu_is_ti814x()) {
-               cpu_name = "TI814X";
-       } else if (omap3_has_iva() && omap3_has_sgx()) {
-               /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */
-               cpu_name = "OMAP3430/3530";
-       } else if (omap3_has_iva()) {
-               cpu_name = "OMAP3525";
-       } else if (omap3_has_sgx()) {
-               cpu_name = "OMAP3515";
-       } else {
-               cpu_name = "OMAP3503";
-       }
-
-       /* Print verbose information */
-       pr_info("%s ES%s (", cpu_name, cpu_rev);
-
-       OMAP3_SHOW_FEATURE(l2cache);
-       OMAP3_SHOW_FEATURE(iva);
-       OMAP3_SHOW_FEATURE(sgx);
-       OMAP3_SHOW_FEATURE(neon);
-       OMAP3_SHOW_FEATURE(isp);
-       OMAP3_SHOW_FEATURE(192mhz_clk);
-
-       printk(")\n");
-}
-
-/*
- * Try to detect the exact revision of the omap we're running on
- */
-void __init omap2_check_revision(void)
-{
-       const char *cpu_rev;
-
-       /*
-        * At this point we have an idea about the processor revision set
-        * earlier with omap2_set_globals_tap().
-        */
-       if (cpu_is_omap24xx()) {
-               omap24xx_check_revision();
-       } else if (cpu_is_omap34xx()) {
-               omap3_check_revision(&cpu_rev);
-
-               /* TI81XX doesn't have feature register */
-               if (!cpu_is_ti81xx())
-                       omap3_check_features();
-               else
-                       ti81xx_check_features();
-
-               omap3_cpuinfo(cpu_rev);
-               return;
-       } else if (cpu_is_omap44xx()) {
-               omap4_check_revision();
-               omap4_check_features();
-               return;
-       } else {
-               pr_err("OMAP revision unknown, please fix!\n");
-       }
-}
-
 /*
  * Set up things for map_io and processor detection later on. Gets called
  * pretty much first thing from board init. For multi-omap, this gets
index fd78f31aa1ad822305568c2c3e240743411dfd64..b8758c8a93940de051a93d5d4364c2d12e3d1367 100644 (file)
@@ -1,5 +1,49 @@
 /*
  * arch/arm/mach-omap2/include/mach/io.h
+ *
+ * IO definitions for TI OMAP processors and boards
+ *
+ * Copied from arch/arm/mach-sa1100/include/mach/io.h
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Modifications:
+ *  06-12-1997 RMK     Created.
+ *  07-04-1999 RMK     Major cleanup
  */
 
-#include <plat/io.h>
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a)                __typesafe_io(a)
+#define __mem_pci(a)   (a)
+
+#endif
index e501b4972a6473a1cf5eed9626ce98eb4f637365..065bd768987cfbc9dabd513f4dc41cef54d7dc9d 100644 (file)
 #include <linux/clk.h>
 
 #include <asm/tlb.h>
-
 #include <asm/mach/map.h>
 
 #include <plat/sram.h>
 #include <plat/sdrc.h>
 #include <plat/serial.h>
-
-#include "clock2xxx.h"
-#include "clock3xxx.h"
-#include "clock44xx.h"
-
-#include "common.h"
 #include <plat/omap-pm.h>
+#include <plat/omap_hwmod.h>
+#include <plat/multi.h>
+
+#include "iomap.h"
 #include "voltage.h"
 #include "powerdomain.h"
-
 #include "clockdomain.h"
-#include <plat/omap_hwmod.h>
-#include <plat/multi.h>
 #include "common.h"
+#include "clock2xxx.h"
+#include "clock3xxx.h"
+#include "clock44xx.h"
 
 /*
  * The machine specific code may provide the extra mapping besides the
  * default mapping provided here.
  */
 
-#ifdef CONFIG_ARCH_OMAP2
+#if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430)
 static struct map_desc omap24xx_io_desc[] __initdata = {
        {
                .virtual        = L3_24XX_VIRT,
@@ -351,7 +348,6 @@ static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data)
 
 static void __init omap_common_init_early(void)
 {
-       omap2_check_revision();
        omap_init_consistent_dma_size();
 }
 
@@ -392,6 +388,7 @@ static void __init omap_hwmod_init_postsetup(void)
 void __init omap2420_init_early(void)
 {
        omap2_set_globals_242x();
+       omap2xxx_check_revision();
        omap_common_init_early();
        omap2xxx_voltagedomains_init();
        omap242x_powerdomains_init();
@@ -406,6 +403,7 @@ void __init omap2420_init_early(void)
 void __init omap2430_init_early(void)
 {
        omap2_set_globals_243x();
+       omap2xxx_check_revision();
        omap_common_init_early();
        omap2xxx_voltagedomains_init();
        omap243x_powerdomains_init();
@@ -424,6 +422,8 @@ void __init omap2430_init_early(void)
 void __init omap3_init_early(void)
 {
        omap2_set_globals_3xxx();
+       omap3xxx_check_revision();
+       omap3xxx_check_features();
        omap_common_init_early();
        omap3xxx_voltagedomains_init();
        omap3xxx_powerdomains_init();
@@ -456,6 +456,8 @@ void __init am35xx_init_early(void)
 void __init ti81xx_init_early(void)
 {
        omap2_set_globals_ti81xx();
+       omap3xxx_check_revision();
+       ti81xx_check_features();
        omap_common_init_early();
        omap3xxx_voltagedomains_init();
        omap3xxx_powerdomains_init();
@@ -470,6 +472,8 @@ void __init ti81xx_init_early(void)
 void __init omap4430_init_early(void)
 {
        omap2_set_globals_443x();
+       omap4xxx_check_revision();
+       omap4xxx_check_features();
        omap_common_init_early();
        omap44xx_voltagedomains_init();
        omap44xx_powerdomains_init();
@@ -490,43 +494,3 @@ void __init omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
                _omap2_init_reprogram_sdrc();
        }
 }
-
-/*
- * NOTE: Please use ioremap + __raw_read/write where possible instead of these
- */
-
-u8 omap_readb(u32 pa)
-{
-       return __raw_readb(OMAP2_L4_IO_ADDRESS(pa));
-}
-EXPORT_SYMBOL(omap_readb);
-
-u16 omap_readw(u32 pa)
-{
-       return __raw_readw(OMAP2_L4_IO_ADDRESS(pa));
-}
-EXPORT_SYMBOL(omap_readw);
-
-u32 omap_readl(u32 pa)
-{
-       return __raw_readl(OMAP2_L4_IO_ADDRESS(pa));
-}
-EXPORT_SYMBOL(omap_readl);
-
-void omap_writeb(u8 v, u32 pa)
-{
-       __raw_writeb(v, OMAP2_L4_IO_ADDRESS(pa));
-}
-EXPORT_SYMBOL(omap_writeb);
-
-void omap_writew(u16 v, u32 pa)
-{
-       __raw_writew(v, OMAP2_L4_IO_ADDRESS(pa));
-}
-EXPORT_SYMBOL(omap_writew);
-
-void omap_writel(u32 v, u32 pa)
-{
-       __raw_writel(v, OMAP2_L4_IO_ADDRESS(pa));
-}
-EXPORT_SYMBOL(omap_writel);
diff --git a/arch/arm/mach-omap2/iomap.h b/arch/arm/mach-omap2/iomap.h
new file mode 100644 (file)
index 0000000..e6f9581
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * IO mappings for OMAP2+
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the  GNU General Public License along
+ * with this program; if not, write  to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef __ASSEMBLER__
+#define IOMEM(x)               (x)
+#else
+#define IOMEM(x)               ((void __force __iomem *)(x))
+#endif
+
+#define OMAP2_L3_IO_OFFSET     0x90000000
+#define OMAP2_L3_IO_ADDRESS(pa)        IOMEM((pa) + OMAP2_L3_IO_OFFSET) /* L3 */
+
+#define OMAP2_L4_IO_OFFSET     0xb2000000
+#define OMAP2_L4_IO_ADDRESS(pa)        IOMEM((pa) + OMAP2_L4_IO_OFFSET) /* L4 */
+
+#define OMAP4_L3_IO_OFFSET     0xb4000000
+#define OMAP4_L3_IO_ADDRESS(pa)        IOMEM((pa) + OMAP4_L3_IO_OFFSET) /* L3 */
+
+#define AM33XX_L4_WK_IO_OFFSET 0xb5000000
+#define AM33XX_L4_WK_IO_ADDRESS(pa)    IOMEM((pa) + AM33XX_L4_WK_IO_OFFSET)
+
+#define OMAP4_L3_PER_IO_OFFSET 0xb1100000
+#define OMAP4_L3_PER_IO_ADDRESS(pa)    IOMEM((pa) + OMAP4_L3_PER_IO_OFFSET)
+
+#define OMAP4_GPMC_IO_OFFSET           0xa9000000
+#define OMAP4_GPMC_IO_ADDRESS(pa)      IOMEM((pa) + OMAP4_GPMC_IO_OFFSET)
+
+#define OMAP2_EMU_IO_OFFSET            0xaa800000      /* Emulation */
+#define OMAP2_EMU_IO_ADDRESS(pa)       IOMEM((pa) + OMAP2_EMU_IO_OFFSET)
+
+/*
+ * ----------------------------------------------------------------------------
+ * Omap2 specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
+
+/* We map both L3 and L4 on OMAP2 */
+#define L3_24XX_PHYS   L3_24XX_BASE    /* 0x68000000 --> 0xf8000000*/
+#define L3_24XX_VIRT   (L3_24XX_PHYS + OMAP2_L3_IO_OFFSET)
+#define L3_24XX_SIZE   SZ_1M           /* 44kB of 128MB used, want 1MB sect */
+#define L4_24XX_PHYS   L4_24XX_BASE    /* 0x48000000 --> 0xfa000000 */
+#define L4_24XX_VIRT   (L4_24XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_24XX_SIZE   SZ_1M           /* 1MB of 128MB used, want 1MB sect */
+
+#define L4_WK_243X_PHYS                L4_WK_243X_BASE /* 0x49000000 --> 0xfb000000 */
+#define L4_WK_243X_VIRT                (L4_WK_243X_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_WK_243X_SIZE                SZ_1M
+#define OMAP243X_GPMC_PHYS     OMAP243X_GPMC_BASE
+#define OMAP243X_GPMC_VIRT     (OMAP243X_GPMC_PHYS + OMAP2_L3_IO_OFFSET)
+                                               /* 0x6e000000 --> 0xfe000000 */
+#define OMAP243X_GPMC_SIZE     SZ_1M
+#define OMAP243X_SDRC_PHYS     OMAP243X_SDRC_BASE
+                                               /* 0x6D000000 --> 0xfd000000 */
+#define OMAP243X_SDRC_VIRT     (OMAP243X_SDRC_PHYS + OMAP2_L3_IO_OFFSET)
+#define OMAP243X_SDRC_SIZE     SZ_1M
+#define OMAP243X_SMS_PHYS      OMAP243X_SMS_BASE
+                                               /* 0x6c000000 --> 0xfc000000 */
+#define OMAP243X_SMS_VIRT      (OMAP243X_SMS_PHYS + OMAP2_L3_IO_OFFSET)
+#define OMAP243X_SMS_SIZE      SZ_1M
+
+/* 2420 IVA */
+#define DSP_MEM_2420_PHYS      OMAP2420_DSP_MEM_BASE
+                                               /* 0x58000000 --> 0xfc100000 */
+#define DSP_MEM_2420_VIRT      0xfc100000
+#define DSP_MEM_2420_SIZE      0x28000
+#define DSP_IPI_2420_PHYS      OMAP2420_DSP_IPI_BASE
+                                               /* 0x59000000 --> 0xfc128000 */
+#define DSP_IPI_2420_VIRT      0xfc128000
+#define DSP_IPI_2420_SIZE      SZ_4K
+#define DSP_MMU_2420_PHYS      OMAP2420_DSP_MMU_BASE
+                                               /* 0x5a000000 --> 0xfc129000 */
+#define DSP_MMU_2420_VIRT      0xfc129000
+#define DSP_MMU_2420_SIZE      SZ_4K
+
+/* 2430 IVA2.1 - currently unmapped */
+
+/*
+ * ----------------------------------------------------------------------------
+ * Omap3 specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
+
+/* We map both L3 and L4 on OMAP3 */
+#define L3_34XX_PHYS           L3_34XX_BASE    /* 0x68000000 --> 0xf8000000 */
+#define L3_34XX_VIRT           (L3_34XX_PHYS + OMAP2_L3_IO_OFFSET)
+#define L3_34XX_SIZE           SZ_1M   /* 44kB of 128MB used, want 1MB sect */
+
+#define L4_34XX_PHYS           L4_34XX_BASE    /* 0x48000000 --> 0xfa000000 */
+#define L4_34XX_VIRT           (L4_34XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_34XX_SIZE           SZ_4M   /* 1MB of 128MB used, want 1MB sect */
+
+/*
+ * ----------------------------------------------------------------------------
+ * AM33XX specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
+#define L4_WK_AM33XX_PHYS      L4_WK_AM33XX_BASE
+#define L4_WK_AM33XX_VIRT      (L4_WK_AM33XX_PHYS + AM33XX_L4_WK_IO_OFFSET)
+#define L4_WK_AM33XX_SIZE      SZ_4M   /* 1MB of 128MB used, want 1MB sect */
+
+/*
+ * Need to look at the Size 4M for L4.
+ * VPOM3430 was not working for Int controller
+ */
+
+#define L4_PER_34XX_PHYS       L4_PER_34XX_BASE
+                                               /* 0x49000000 --> 0xfb000000 */
+#define L4_PER_34XX_VIRT       (L4_PER_34XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_PER_34XX_SIZE       SZ_1M
+
+#define L4_EMU_34XX_PHYS       L4_EMU_34XX_BASE
+                                               /* 0x54000000 --> 0xfe800000 */
+#define L4_EMU_34XX_VIRT       (L4_EMU_34XX_PHYS + OMAP2_EMU_IO_OFFSET)
+#define L4_EMU_34XX_SIZE       SZ_8M
+
+#define OMAP34XX_GPMC_PHYS     OMAP34XX_GPMC_BASE
+                                               /* 0x6e000000 --> 0xfe000000 */
+#define OMAP34XX_GPMC_VIRT     (OMAP34XX_GPMC_PHYS + OMAP2_L3_IO_OFFSET)
+#define OMAP34XX_GPMC_SIZE     SZ_1M
+
+#define OMAP343X_SMS_PHYS      OMAP343X_SMS_BASE
+                                               /* 0x6c000000 --> 0xfc000000 */
+#define OMAP343X_SMS_VIRT      (OMAP343X_SMS_PHYS + OMAP2_L3_IO_OFFSET)
+#define OMAP343X_SMS_SIZE      SZ_1M
+
+#define OMAP343X_SDRC_PHYS     OMAP343X_SDRC_BASE
+                                               /* 0x6D000000 --> 0xfd000000 */
+#define OMAP343X_SDRC_VIRT     (OMAP343X_SDRC_PHYS + OMAP2_L3_IO_OFFSET)
+#define OMAP343X_SDRC_SIZE     SZ_1M
+
+/* 3430 IVA - currently unmapped */
+
+/*
+ * ----------------------------------------------------------------------------
+ * Omap4 specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
+
+/* We map both L3 and L4 on OMAP4 */
+#define L3_44XX_PHYS           L3_44XX_BASE    /* 0x44000000 --> 0xf8000000 */
+#define L3_44XX_VIRT           (L3_44XX_PHYS + OMAP4_L3_IO_OFFSET)
+#define L3_44XX_SIZE           SZ_1M
+
+#define L4_44XX_PHYS           L4_44XX_BASE    /* 0x4a000000 --> 0xfc000000 */
+#define L4_44XX_VIRT           (L4_44XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_44XX_SIZE           SZ_4M
+
+#define L4_PER_44XX_PHYS       L4_PER_44XX_BASE
+                                               /* 0x48000000 --> 0xfa000000 */
+#define L4_PER_44XX_VIRT       (L4_PER_44XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_PER_44XX_SIZE       SZ_4M
+
+#define L4_ABE_44XX_PHYS       L4_ABE_44XX_BASE
+                                               /* 0x49000000 --> 0xfb000000 */
+#define L4_ABE_44XX_VIRT       (L4_ABE_44XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_ABE_44XX_SIZE       SZ_1M
+
+#define L4_EMU_44XX_PHYS       L4_EMU_44XX_BASE
+                                               /* 0x54000000 --> 0xfe800000 */
+#define L4_EMU_44XX_VIRT       (L4_EMU_44XX_PHYS + OMAP2_EMU_IO_OFFSET)
+#define L4_EMU_44XX_SIZE       SZ_8M
+
+#define OMAP44XX_GPMC_PHYS     OMAP44XX_GPMC_BASE
+                                               /* 0x50000000 --> 0xf9000000 */
+#define OMAP44XX_GPMC_VIRT     (OMAP44XX_GPMC_PHYS + OMAP4_GPMC_IO_OFFSET)
+#define OMAP44XX_GPMC_SIZE     SZ_1M
+
+
+#define OMAP44XX_EMIF1_PHYS    OMAP44XX_EMIF1_BASE
+                                               /* 0x4c000000 --> 0xfd100000 */
+#define OMAP44XX_EMIF1_VIRT    (OMAP44XX_EMIF1_PHYS + OMAP4_L3_PER_IO_OFFSET)
+#define OMAP44XX_EMIF1_SIZE    SZ_1M
+
+#define OMAP44XX_EMIF2_PHYS    OMAP44XX_EMIF2_BASE
+                                               /* 0x4d000000 --> 0xfd200000 */
+#define OMAP44XX_EMIF2_SIZE    SZ_1M
+#define OMAP44XX_EMIF2_VIRT    (OMAP44XX_EMIF1_VIRT + OMAP44XX_EMIF1_SIZE)
+
+#define OMAP44XX_DMM_PHYS      OMAP44XX_DMM_BASE
+                                               /* 0x4e000000 --> 0xfd300000 */
+#define OMAP44XX_DMM_SIZE      SZ_1M
+#define OMAP44XX_DMM_VIRT      (OMAP44XX_EMIF2_VIRT + OMAP44XX_EMIF2_SIZE)
index 1fef061f7927929be28987d7ca10b270f05f04d3..65f0d2571c9a2c88aa0d84327d4498b113272d8d 100644 (file)
  * for more details.
  */
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
-#include <mach/hardware.h>
+
 #include <asm/exception.h>
 #include <asm/mach/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 
+#include <mach/hardware.h>
+
+#include "iomap.h"
 
 /* selected INTC register offsets */
 
@@ -57,6 +64,8 @@ static struct omap_irq_bank {
        },
 };
 
+static struct irq_domain *domain;
+
 /* Structure to save interrupt controller context */
 struct omap3_intc_regs {
        u32 sysconfig;
@@ -147,17 +156,27 @@ omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
                                IRQ_NOREQUEST | IRQ_NOPROBE, 0);
 }
 
-static void __init omap_init_irq(u32 base, int nr_irqs)
+static void __init omap_init_irq(u32 base, int nr_irqs,
+                                struct device_node *node)
 {
        void __iomem *omap_irq_base;
        unsigned long nr_of_irqs = 0;
        unsigned int nr_banks = 0;
-       int i, j;
+       int i, j, irq_base;
 
        omap_irq_base = ioremap(base, SZ_4K);
        if (WARN_ON(!omap_irq_base))
                return;
 
+       irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
+       if (irq_base < 0) {
+               pr_warn("Couldn't allocate IRQ numbers\n");
+               irq_base = 0;
+       }
+
+       domain = irq_domain_add_legacy(node, nr_irqs, irq_base, 0,
+                                      &irq_domain_simple_ops, NULL);
+
        for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
                struct omap_irq_bank *bank = irq_banks + i;
 
@@ -166,36 +185,36 @@ static void __init omap_init_irq(u32 base, int nr_irqs)
                /* Static mapping, never released */
                bank->base_reg = ioremap(base, SZ_4K);
                if (!bank->base_reg) {
-                       printk(KERN_ERR "Could not ioremap irq bank%i\n", i);
+                       pr_err("Could not ioremap irq bank%i\n", i);
                        continue;
                }
 
                omap_irq_bank_init_one(bank);
 
                for (j = 0; j < bank->nr_irqs; j += 32)
-                       omap_alloc_gc(bank->base_reg + j, j, 32);
+                       omap_alloc_gc(bank->base_reg + j, j + irq_base, 32);
 
                nr_of_irqs += bank->nr_irqs;
                nr_banks++;
        }
 
-       printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n",
-              nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : "");
+       pr_info("Total of %ld interrupts on %d active controller%s\n",
+               nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : "");
 }
 
 void __init omap2_init_irq(void)
 {
-       omap_init_irq(OMAP24XX_IC_BASE, 96);
+       omap_init_irq(OMAP24XX_IC_BASE, 96, NULL);
 }
 
 void __init omap3_init_irq(void)
 {
-       omap_init_irq(OMAP34XX_IC_BASE, 96);
+       omap_init_irq(OMAP34XX_IC_BASE, 96, NULL);
 }
 
 void __init ti81xx_init_irq(void)
 {
-       omap_init_irq(OMAP34XX_IC_BASE, 128);
+       omap_init_irq(OMAP34XX_IC_BASE, 128, NULL);
 }
 
 static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs)
@@ -225,8 +244,10 @@ out:
                irqnr = readl_relaxed(base_addr + INTCPS_SIR_IRQ_OFFSET);
                irqnr &= ACTIVEIRQ_MASK;
 
-               if (irqnr)
+               if (irqnr) {
+                       irqnr = irq_find_mapping(domain, irqnr);
                        handle_IRQ(irqnr, regs);
+               }
        } while (irqnr);
 }
 
@@ -236,6 +257,28 @@ asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs *regs
        omap_intc_handle_irq(base_addr, regs);
 }
 
+int __init omap_intc_of_init(struct device_node *node,
+                            struct device_node *parent)
+{
+       struct resource res;
+       u32 nr_irqs = 96;
+
+       if (WARN_ON(!node))
+               return -ENODEV;
+
+       if (of_address_to_resource(node, 0, &res)) {
+               WARN(1, "unable to get intc registers\n");
+               return -EINVAL;
+       }
+
+       if (of_property_read_u32(node, "ti,intc-size", &nr_irqs))
+               pr_warn("unable to get intc-size, default to %d\n", nr_irqs);
+
+       omap_init_irq(res.start, nr_irqs, of_node_get(node));
+
+       return 0;
+}
+
 #ifdef CONFIG_ARCH_OMAP3
 static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)];
 
index ecc039e794db4cdc8b3f284292f0a59f1445fe8e..577cb77db26c0adc207284321407b1b1a1a2c36a 100644 (file)
@@ -158,7 +158,7 @@ static int omap3_enable_st_clock(unsigned int id, bool enable)
        return 0;
 }
 
-static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
+static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
 {
        int id, count = 1;
        char *name = "omap-mcbsp";
index 611a0e3d54ca34c47f8180faed43932191df26cf..f26b2faa16947c042fe1563fed8b9d5b23b8488e 100644 (file)
@@ -100,8 +100,8 @@ void omap_mux_write_array(struct omap_mux_partition *partition,
 
 static char *omap_mux_options;
 
-static int _omap_mux_init_gpio(struct omap_mux_partition *partition,
-                              int gpio, int val)
+static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition,
+                                     int gpio, int val)
 {
        struct omap_mux_entry *e;
        struct omap_mux *gpio_mux = NULL;
@@ -145,7 +145,7 @@ static int _omap_mux_init_gpio(struct omap_mux_partition *partition,
        return 0;
 }
 
-int omap_mux_init_gpio(int gpio, int val)
+int __init omap_mux_init_gpio(int gpio, int val)
 {
        struct omap_mux_partition *partition;
        int ret;
@@ -159,9 +159,9 @@ int omap_mux_init_gpio(int gpio, int val)
        return -ENODEV;
 }
 
-static int _omap_mux_get_by_name(struct omap_mux_partition *partition,
-                                const char *muxname,
-                                struct omap_mux **found_mux)
+static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition,
+                                       const char *muxname,
+                                       struct omap_mux **found_mux)
 {
        struct omap_mux *mux = NULL;
        struct omap_mux_entry *e;
@@ -218,7 +218,7 @@ static int _omap_mux_get_by_name(struct omap_mux_partition *partition,
        return -ENODEV;
 }
 
-static int
+static int __init
 omap_mux_get_by_name(const char *muxname,
                        struct omap_mux_partition **found_partition,
                        struct omap_mux **found_mux)
@@ -240,7 +240,7 @@ omap_mux_get_by_name(const char *muxname,
        return -ENODEV;
 }
 
-int omap_mux_init_signal(const char *muxname, int val)
+int __init omap_mux_init_signal(const char *muxname, int val)
 {
        struct omap_mux_partition *partition = NULL;
        struct omap_mux *mux = NULL;
index 2132308ad1e41fffc14856b48294ffd42e748c8b..69fe060a0b755204875f42a9fd1e1ffc943736f9 100644 (file)
@@ -246,7 +246,7 @@ static inline void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
 {
 }
 
-static struct omap_board_mux *board_mux __initdata __maybe_unused;
+static struct omap_board_mux *board_mux __maybe_unused;
 
 #endif
 
index adbe4d8c7cafdcd64d52c5880530f096ffacaebd..56c345b8b931b1d00b926152ea1459390884c500 100644 (file)
@@ -33,7 +33,7 @@ int platform_cpu_kill(unsigned int cpu)
  * platform-specific code to shutdown a CPU
  * Called with IRQs disabled
  */
-void platform_cpu_die(unsigned int cpu)
+void __ref platform_cpu_die(unsigned int cpu)
 {
        unsigned int this_cpu;
 
index 1d5d01056558fa0581410a35ba09d4bfeeff8cc0..63ab686834c12cf42520e13af6da51b659c305f8 100644 (file)
@@ -263,12 +263,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
         * In MPUSS OSWR or device OFF, interrupt controller  contest is lost.
         */
        mpuss_clear_prev_logic_pwrst();
-       pwrdm_clear_all_prev_pwrst(mpuss_pd);
        if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
                (pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF))
                save_state = 2;
 
-       clear_cpu_prev_pwrst(cpu);
        cpu_clear_prev_logic_pwrst(cpu);
        set_cpu_next_pwrst(cpu, power_state);
        set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume));
@@ -300,7 +298,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
  * @cpu : CPU ID
  * @power_state: CPU low power state.
  */
-int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
+int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
 {
        unsigned int cpu_state = 0;
 
index c1bf3ef0ba02d5ffe0ea8af5642b9a078d9f0b66..deffbf1c9627f8baa0acfa2890954263237fc899 100644 (file)
 #include <asm/cacheflush.h>
 #include <asm/hardware/gic.h>
 #include <asm/smp_scu.h>
+
 #include <mach/hardware.h>
 #include <mach/omap-secure.h>
 
+#include "iomap.h"
 #include "common.h"
-
 #include "clockdomain.h"
 
 /* SCU base address */
index d3d8971d7f30ee10293385d9bd997ca30a30144b..42cd7fb52414b961ad0535004a9f1f83333130ea 100644 (file)
@@ -43,7 +43,6 @@
 
 static void __iomem *wakeupgen_base;
 static void __iomem *sar_base;
-static DEFINE_PER_CPU(u32 [NR_REG_BANKS], irqmasks);
 static DEFINE_SPINLOCK(wakeupgen_lock);
 static unsigned int irq_target_cpu[NR_IRQS];
 
@@ -67,14 +66,6 @@ static inline void sar_writel(u32 val, u32 offset, u8 idx)
        __raw_writel(val, sar_base + offset + (idx * 4));
 }
 
-static void _wakeupgen_set_all(unsigned int cpu, unsigned int reg)
-{
-       u8 i;
-
-       for (i = 0; i < NR_REG_BANKS; i++)
-               wakeupgen_writel(reg, i, cpu);
-}
-
 static inline int _wakeupgen_get_irq_info(u32 irq, u32 *bit_posn, u8 *reg_index)
 {
        unsigned int spi_irq;
@@ -130,22 +121,6 @@ static void _wakeupgen_set(unsigned int irq, unsigned int cpu)
        wakeupgen_writel(val, i, cpu);
 }
 
-static void _wakeupgen_save_masks(unsigned int cpu)
-{
-       u8 i;
-
-       for (i = 0; i < NR_REG_BANKS; i++)
-               per_cpu(irqmasks, cpu)[i] = wakeupgen_readl(i, cpu);
-}
-
-static void _wakeupgen_restore_masks(unsigned int cpu)
-{
-       u8 i;
-
-       for (i = 0; i < NR_REG_BANKS; i++)
-               wakeupgen_writel(per_cpu(irqmasks, cpu)[i], i, cpu);
-}
-
 /*
  * Architecture specific Mask extension
  */
@@ -170,6 +145,33 @@ static void wakeupgen_unmask(struct irq_data *d)
        spin_unlock_irqrestore(&wakeupgen_lock, flags);
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+static DEFINE_PER_CPU(u32 [NR_REG_BANKS], irqmasks);
+
+static void _wakeupgen_save_masks(unsigned int cpu)
+{
+       u8 i;
+
+       for (i = 0; i < NR_REG_BANKS; i++)
+               per_cpu(irqmasks, cpu)[i] = wakeupgen_readl(i, cpu);
+}
+
+static void _wakeupgen_restore_masks(unsigned int cpu)
+{
+       u8 i;
+
+       for (i = 0; i < NR_REG_BANKS; i++)
+               wakeupgen_writel(per_cpu(irqmasks, cpu)[i], i, cpu);
+}
+
+static void _wakeupgen_set_all(unsigned int cpu, unsigned int reg)
+{
+       u8 i;
+
+       for (i = 0; i < NR_REG_BANKS; i++)
+               wakeupgen_writel(reg, i, cpu);
+}
+
 /*
  * Mask or unmask all interrupts on given CPU.
  *     0 = Mask all interrupts on the 'cpu'
@@ -191,6 +193,7 @@ static void wakeupgen_irqmask_all(unsigned int cpu, unsigned int set)
        }
        spin_unlock_irqrestore(&wakeupgen_lock, flags);
 }
+#endif
 
 #ifdef CONFIG_CPU_PM
 /*
index 3c8dd928628efd7c01cad5a1d2743c7ddc34a660..34b9766d1d231845356b2c71626fa234a731bee6 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "omap_hwmod_common_data.h"
 
+#include "smartreflex.h"
 #include "prm-regbits-34xx.h"
 #include "cm-regbits-34xx.h"
 #include "wd_timer.h"
@@ -376,6 +377,16 @@ static struct omap_hwmod_ocp_if omap3_l4_core__i2c3 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+static struct omap_hwmod_irq_info omap3_smartreflex_mpu_irqs[] = {
+       { .irq = 18},
+       { .irq = -1 }
+};
+
+static struct omap_hwmod_irq_info omap3_smartreflex_core_irqs[] = {
+       { .irq = 19},
+       { .irq = -1 }
+};
+
 /* L4 CORE -> SR1 interface */
 static struct omap_hwmod_addr_space omap3_sr1_addr_space[] = {
        {
@@ -2664,6 +2675,10 @@ static struct omap_hwmod_class omap36xx_smartreflex_hwmod_class = {
 };
 
 /* SR1 */
+static struct omap_smartreflex_dev_attr sr1_dev_attr = {
+       .sensor_voltdm_name   = "mpu_iva",
+};
+
 static struct omap_hwmod_ocp_if *omap3_sr1_slaves[] = {
        &omap3_l4_core__sr1,
 };
@@ -2672,7 +2687,6 @@ static struct omap_hwmod omap34xx_sr1_hwmod = {
        .name           = "sr1_hwmod",
        .class          = &omap34xx_smartreflex_hwmod_class,
        .main_clk       = "sr1_fck",
-       .vdd_name       = "mpu_iva",
        .prcm           = {
                .omap2 = {
                        .prcm_reg_id = 1,
@@ -2684,6 +2698,8 @@ static struct omap_hwmod omap34xx_sr1_hwmod = {
        },
        .slaves         = omap3_sr1_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap3_sr1_slaves),
+       .dev_attr       = &sr1_dev_attr,
+       .mpu_irqs       = omap3_smartreflex_mpu_irqs,
        .flags          = HWMOD_SET_DEFAULT_CLOCKACT,
 };
 
@@ -2691,7 +2707,6 @@ static struct omap_hwmod omap36xx_sr1_hwmod = {
        .name           = "sr1_hwmod",
        .class          = &omap36xx_smartreflex_hwmod_class,
        .main_clk       = "sr1_fck",
-       .vdd_name       = "mpu_iva",
        .prcm           = {
                .omap2 = {
                        .prcm_reg_id = 1,
@@ -2703,9 +2718,15 @@ static struct omap_hwmod omap36xx_sr1_hwmod = {
        },
        .slaves         = omap3_sr1_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap3_sr1_slaves),
+       .dev_attr       = &sr1_dev_attr,
+       .mpu_irqs       = omap3_smartreflex_mpu_irqs,
 };
 
 /* SR2 */
+static struct omap_smartreflex_dev_attr sr2_dev_attr = {
+       .sensor_voltdm_name     = "core",
+};
+
 static struct omap_hwmod_ocp_if *omap3_sr2_slaves[] = {
        &omap3_l4_core__sr2,
 };
@@ -2714,7 +2735,6 @@ static struct omap_hwmod omap34xx_sr2_hwmod = {
        .name           = "sr2_hwmod",
        .class          = &omap34xx_smartreflex_hwmod_class,
        .main_clk       = "sr2_fck",
-       .vdd_name       = "core",
        .prcm           = {
                .omap2 = {
                        .prcm_reg_id = 1,
@@ -2726,6 +2746,8 @@ static struct omap_hwmod omap34xx_sr2_hwmod = {
        },
        .slaves         = omap3_sr2_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap3_sr2_slaves),
+       .dev_attr       = &sr2_dev_attr,
+       .mpu_irqs       = omap3_smartreflex_core_irqs,
        .flags          = HWMOD_SET_DEFAULT_CLOCKACT,
 };
 
@@ -2733,7 +2755,6 @@ static struct omap_hwmod omap36xx_sr2_hwmod = {
        .name           = "sr2_hwmod",
        .class          = &omap36xx_smartreflex_hwmod_class,
        .main_clk       = "sr2_fck",
-       .vdd_name       = "core",
        .prcm           = {
                .omap2 = {
                        .prcm_reg_id = 1,
@@ -2745,6 +2766,8 @@ static struct omap_hwmod omap36xx_sr2_hwmod = {
        },
        .slaves         = omap3_sr2_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap3_sr2_slaves),
+       .dev_attr       = &sr2_dev_attr,
+       .mpu_irqs       = omap3_smartreflex_core_irqs,
 };
 
 /*
index ef0524c10a840296b089f4e3ca81d291f737a503..08daa5e0eb5fdbd1fa3a20c5c1ba4dd1112b3d90 100644 (file)
 #include <plat/mcspi.h>
 #include <plat/mcbsp.h>
 #include <plat/mmc.h>
-#include <plat/i2c.h>
 #include <plat/dmtimer.h>
 #include <plat/common.h>
 
 #include "omap_hwmod_common_data.h"
 
+#include "smartreflex.h"
 #include "cm1_44xx.h"
 #include "cm2_44xx.h"
 #include "prm44xx.h"
@@ -3963,6 +3963,10 @@ static struct omap_hwmod_class omap44xx_smartreflex_hwmod_class = {
 };
 
 /* smartreflex_core */
+static struct omap_smartreflex_dev_attr smartreflex_core_dev_attr = {
+       .sensor_voltdm_name   = "core",
+};
+
 static struct omap_hwmod omap44xx_smartreflex_core_hwmod;
 static struct omap_hwmod_irq_info omap44xx_smartreflex_core_irqs[] = {
        { .irq = 19 + OMAP44XX_IRQ_GIC_START },
@@ -3999,7 +4003,6 @@ static struct omap_hwmod omap44xx_smartreflex_core_hwmod = {
        .mpu_irqs       = omap44xx_smartreflex_core_irqs,
 
        .main_clk       = "smartreflex_core_fck",
-       .vdd_name       = "core",
        .prcm = {
                .omap4 = {
                        .clkctrl_offs = OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET,
@@ -4009,9 +4012,14 @@ static struct omap_hwmod omap44xx_smartreflex_core_hwmod = {
        },
        .slaves         = omap44xx_smartreflex_core_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap44xx_smartreflex_core_slaves),
+       .dev_attr       = &smartreflex_core_dev_attr,
 };
 
 /* smartreflex_iva */
+static struct omap_smartreflex_dev_attr smartreflex_iva_dev_attr = {
+       .sensor_voltdm_name     = "iva",
+};
+
 static struct omap_hwmod omap44xx_smartreflex_iva_hwmod;
 static struct omap_hwmod_irq_info omap44xx_smartreflex_iva_irqs[] = {
        { .irq = 102 + OMAP44XX_IRQ_GIC_START },
@@ -4047,7 +4055,6 @@ static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = {
        .clkdm_name     = "l4_ao_clkdm",
        .mpu_irqs       = omap44xx_smartreflex_iva_irqs,
        .main_clk       = "smartreflex_iva_fck",
-       .vdd_name       = "iva",
        .prcm = {
                .omap4 = {
                        .clkctrl_offs = OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET,
@@ -4057,9 +4064,14 @@ static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = {
        },
        .slaves         = omap44xx_smartreflex_iva_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap44xx_smartreflex_iva_slaves),
+       .dev_attr       = &smartreflex_iva_dev_attr,
 };
 
 /* smartreflex_mpu */
+static struct omap_smartreflex_dev_attr smartreflex_mpu_dev_attr = {
+       .sensor_voltdm_name     = "mpu",
+};
+
 static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod;
 static struct omap_hwmod_irq_info omap44xx_smartreflex_mpu_irqs[] = {
        { .irq = 18 + OMAP44XX_IRQ_GIC_START },
@@ -4095,7 +4107,6 @@ static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = {
        .clkdm_name     = "l4_ao_clkdm",
        .mpu_irqs       = omap44xx_smartreflex_mpu_irqs,
        .main_clk       = "smartreflex_mpu_fck",
-       .vdd_name       = "mpu",
        .prcm = {
                .omap4 = {
                        .clkctrl_offs = OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET,
@@ -4105,6 +4116,7 @@ static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = {
        },
        .slaves         = omap44xx_smartreflex_mpu_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap44xx_smartreflex_mpu_slaves),
+       .dev_attr       = &smartreflex_mpu_dev_attr,
 };
 
 /*
index e6dda694fd5ca6e960bd8e7e4cd8294b27185509..5037e76e4e23ebe10a0915f099530c7ac1460388 100644 (file)
@@ -28,6 +28,8 @@
  *     http://repository.maemo.org/pool/diablo/free/k/kernel-source-diablo/
  */
 
+#include <plat/hardware.h>
+
 #include "opp2xxx.h"
 #include "sdrc.h"
 #include "clock.h"
index 1b9596ae201ef5f05fa3cf6ab003abd5f82f17c4..750805c528d8c256f2d9cfe5fe9e186a7f5e0aab 100644 (file)
@@ -26,6 +26,8 @@
  * This is technically part of the OMAP2xxx clock code.
  */
 
+#include <plat/hardware.h>
+
 #include "opp2xxx.h"
 #include "sdrc.h"
 #include "clock.h"
index 4411163e012dd362298981182bde2a9d8d8b08ea..814bcd90159686a18a914e82de7a93ca6cda1e79 100644 (file)
@@ -220,8 +220,8 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *dir)
                return 0;
 
        d = debugfs_create_dir(pwrdm->name, (struct dentry *)dir);
-
-       (void) debugfs_create_file("suspend", S_IRUGO|S_IWUSR, d,
+       if (!(IS_ERR_OR_NULL(d)))
+               (void) debugfs_create_file("suspend", S_IRUGO|S_IWUSR, d,
                        (void *)pwrdm, &pwrdm_suspend_fops);
 
        return 0;
@@ -264,7 +264,7 @@ static int __init pm_dbg_init(void)
                return 0;
 
        d = debugfs_create_dir("pm_debug", NULL);
-       if (IS_ERR(d))
+       if (IS_ERR_OR_NULL(d))
                return PTR_ERR(d);
 
        (void) debugfs_create_file("count", S_IRUGO,
index 5a65dd04aa38ba8298168a5cb80e1d50766f1136..a7bdec69a2b3b45d169fca4176b272599f1c6ec8 100644 (file)
 #include <linux/err.h>
 #include <linux/opp.h>
 #include <linux/export.h>
+#include <linux/suspend.h>
 
 #include <plat/omap-pm.h>
 #include <plat/omap_device.h>
 #include "common.h"
 
+#include "prcm-common.h"
 #include "voltage.h"
 #include "powerdomain.h"
 #include "clockdomain.h"
 
 static struct omap_device_pm_latency *pm_lats;
 
-static int _init_omap_device(char *name)
+/*
+ * omap_pm_suspend: points to a function that does the SoC-specific
+ * suspend work
+ */
+int (*omap_pm_suspend)(void);
+
+static int __init _init_omap_device(char *name)
 {
        struct omap_hwmod *oh;
        struct platform_device *pdev;
@@ -49,7 +57,7 @@ static int _init_omap_device(char *name)
 /*
  * Build omap_devices for processors and bus.
  */
-static void omap2_init_processor_devices(void)
+static void __init omap2_init_processor_devices(void)
 {
        _init_omap_device("mpu");
        if (omap3_has_iva())
@@ -68,32 +76,41 @@ static void omap2_init_processor_devices(void)
 #define FORCEWAKEUP_SWITCH     0
 #define LOWPOWERSTATE_SWITCH   1
 
+int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
+{
+       if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
+               clkdm_allow_idle(clkdm);
+       else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
+                atomic_read(&clkdm->usecount) == 0)
+               clkdm_sleep(clkdm);
+       return 0;
+}
+
 /*
  * This sets pwrdm state (other than mpu & core. Currently only ON &
  * RET are supported.
  */
-int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
+int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 pwrst)
 {
-       u32 cur_state;
-       int sleep_switch = -1;
-       int ret = 0;
-       int hwsup = 0;
+       u8 curr_pwrst, next_pwrst;
+       int sleep_switch = -1, ret = 0, hwsup = 0;
 
-       if (pwrdm == NULL || IS_ERR(pwrdm))
+       if (!pwrdm || IS_ERR(pwrdm))
                return -EINVAL;
 
-       while (!(pwrdm->pwrsts & (1 << state))) {
-               if (state == PWRDM_POWER_OFF)
+       while (!(pwrdm->pwrsts & (1 << pwrst))) {
+               if (pwrst == PWRDM_POWER_OFF)
                        return ret;
-               state--;
+               pwrst--;
        }
 
-       cur_state = pwrdm_read_next_pwrst(pwrdm);
-       if (cur_state == state)
+       next_pwrst = pwrdm_read_next_pwrst(pwrdm);
+       if (next_pwrst == pwrst)
                return ret;
 
-       if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) {
-               if ((pwrdm_read_pwrst(pwrdm) > state) &&
+       curr_pwrst = pwrdm_read_pwrst(pwrdm);
+       if (curr_pwrst < PWRDM_POWER_ON) {
+               if ((curr_pwrst > pwrst) &&
                        (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
                        sleep_switch = LOWPOWERSTATE_SWITCH;
                } else {
@@ -103,12 +120,10 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
                }
        }
 
-       ret = pwrdm_set_next_pwrst(pwrdm, state);
-       if (ret) {
-               pr_err("%s: unable to set state of powerdomain: %s\n",
+       ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
+       if (ret)
+               pr_err("%s: unable to set power state of powerdomain: %s\n",
                       __func__, pwrdm->name);
-               goto err;
-       }
 
        switch (sleep_switch) {
        case FORCEWAKEUP_SWITCH:
@@ -119,16 +134,16 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
                break;
        case LOWPOWERSTATE_SWITCH:
                pwrdm_set_lowpwrstchange(pwrdm);
+               pwrdm_wait_transition(pwrdm);
+               pwrdm_state_switch(pwrdm);
                break;
-       default:
-               return ret;
        }
 
-       pwrdm_state_switch(pwrdm);
-err:
        return ret;
 }
 
+
+
 /*
  * This API is to be called during init to set the various voltage
  * domains to the voltage as per the opp table. Typically we boot up
@@ -199,6 +214,56 @@ exit:
        return -EINVAL;
 }
 
+#ifdef CONFIG_SUSPEND
+static int omap_pm_enter(suspend_state_t suspend_state)
+{
+       int ret = 0;
+
+       if (!omap_pm_suspend)
+               return -ENOENT; /* XXX doublecheck */
+
+       switch (suspend_state) {
+       case PM_SUSPEND_STANDBY:
+       case PM_SUSPEND_MEM:
+               ret = omap_pm_suspend();
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+static int omap_pm_begin(suspend_state_t state)
+{
+       disable_hlt();
+       if (cpu_is_omap34xx())
+               omap_prcm_irq_prepare();
+       return 0;
+}
+
+static void omap_pm_end(void)
+{
+       enable_hlt();
+       return;
+}
+
+static void omap_pm_finish(void)
+{
+       if (cpu_is_omap34xx())
+               omap_prcm_irq_complete();
+}
+
+static const struct platform_suspend_ops omap_pm_ops = {
+       .begin          = omap_pm_begin,
+       .end            = omap_pm_end,
+       .enter          = omap_pm_enter,
+       .finish         = omap_pm_finish,
+       .valid          = suspend_valid_only_mem,
+};
+
+#endif /* CONFIG_SUSPEND */
+
 static void __init omap3_init_voltages(void)
 {
        if (!cpu_is_omap34xx())
@@ -230,6 +295,14 @@ postcore_initcall(omap2_common_pm_init);
 
 static int __init omap2_common_pm_late_init(void)
 {
+       /*
+        * In the case of DT, the PMIC and SR initialization will be done using
+        * a completely different mechanism.
+        * Disable this part if a DT blob is available.
+        */
+       if (of_have_populated_dt())
+               return 0;
+
        /* Init the voltage layer */
        omap_pmic_late_init();
        omap_voltage_late_init();
@@ -241,6 +314,10 @@ static int __init omap2_common_pm_late_init(void)
        /* Smartreflex device init */
        omap_devinit_smartreflex();
 
+#ifdef CONFIG_SUSPEND
+       suspend_set_ops(&omap_pm_ops);
+#endif
+
        return 0;
 }
 late_initcall(omap2_common_pm_late_init);
index b737b11e4499f37a47176445649ffaa9614b7fcd..36fa90b6ece80ee09522a44ed68b5da5384821a6 100644 (file)
 extern void *omap3_secure_ram_storage;
 extern void omap3_pm_off_mode_enable(int);
 extern void omap_sram_idle(void);
-extern int omap3_can_sleep(void);
 extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
 extern int omap3_idle_init(void);
 extern int omap4_idle_init(void);
+extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused);
+extern int (*omap_pm_suspend)(void);
 
 #if defined(CONFIG_PM_OPP)
 extern int omap3_opp_init(void);
index a4eb5c280435701d571b25a2b5f95c2d7f2b6fec..5ca45ca76946fa777a046e45443b74395d4e0238 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
-#include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/time.h>
 #include <linux/gpio.h>
 #include <asm/mach/irq.h>
 #include <asm/mach-types.h>
 
-#include <mach/irqs.h>
 #include <plat/clock.h>
 #include <plat/sram.h>
 #include <plat/dma.h>
 #include <plat/board.h>
 
+#include <mach/irqs.h>
+
 #include "common.h"
 #include "prm2xxx_3xxx.h"
 #include "prm-regbits-24xx.h"
 #include "sdrc.h"
 #include "pm.h"
 #include "control.h"
-
 #include "powerdomain.h"
 #include "clockdomain.h"
 
-#ifdef CONFIG_SUSPEND
-static suspend_state_t suspend_state = PM_SUSPEND_ON;
-static inline bool is_suspending(void)
-{
-       return (suspend_state != PM_SUSPEND_ON);
-}
-#else
-static inline bool is_suspending(void)
-{
-       return false;
-}
-#endif
-
 static void (*omap2_sram_idle)(void);
 static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl,
                                  void __iomem *sdrc_power);
@@ -85,7 +71,7 @@ static int omap2_fclks_active(void)
        return (f1 | f2) ? 1 : 0;
 }
 
-static void omap2_enter_full_retention(void)
+static int omap2_enter_full_retention(void)
 {
        u32 l;
 
@@ -148,6 +134,8 @@ no_sleep:
 
        /* Mask future PRCM-to-MPU interrupts */
        omap2_prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
+
+       return 0;
 }
 
 static int omap2_i2c_active(void)
@@ -244,77 +232,6 @@ out:
        local_fiq_enable();
 }
 
-#ifdef CONFIG_SUSPEND
-static int omap2_pm_begin(suspend_state_t state)
-{
-       disable_hlt();
-       suspend_state = state;
-       return 0;
-}
-
-static int omap2_pm_suspend(void)
-{
-       u32 wken_wkup, mir1;
-
-       wken_wkup = omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
-       wken_wkup &= ~OMAP24XX_EN_GPT1_MASK;
-       omap2_prm_write_mod_reg(wken_wkup, WKUP_MOD, PM_WKEN);
-
-       /* Mask GPT1 */
-       mir1 = omap_readl(0x480fe0a4);
-       omap_writel(1 << 5, 0x480fe0ac);
-
-       omap2_enter_full_retention();
-
-       omap_writel(mir1, 0x480fe0a4);
-       omap2_prm_write_mod_reg(wken_wkup, WKUP_MOD, PM_WKEN);
-
-       return 0;
-}
-
-static int omap2_pm_enter(suspend_state_t state)
-{
-       int ret = 0;
-
-       switch (state) {
-       case PM_SUSPEND_STANDBY:
-       case PM_SUSPEND_MEM:
-               ret = omap2_pm_suspend();
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-static void omap2_pm_end(void)
-{
-       suspend_state = PM_SUSPEND_ON;
-       enable_hlt();
-}
-
-static const struct platform_suspend_ops omap_pm_ops = {
-       .begin          = omap2_pm_begin,
-       .enter          = omap2_pm_enter,
-       .end            = omap2_pm_end,
-       .valid          = suspend_valid_only_mem,
-};
-#else
-static const struct platform_suspend_ops __initdata omap_pm_ops;
-#endif /* CONFIG_SUSPEND */
-
-/* XXX This function should be shareable between OMAP2xxx and OMAP3 */
-static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
-{
-       if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
-               clkdm_allow_idle(clkdm);
-       else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
-                atomic_read(&clkdm->usecount) == 0)
-               clkdm_sleep(clkdm);
-       return 0;
-}
-
 static void __init prcm_setup_regs(void)
 {
        int i, num_mem_banks;
@@ -356,9 +273,13 @@ static void __init prcm_setup_regs(void)
        clkdm_sleep(gfx_clkdm);
 
        /* Enable hardware-supervised idle for all clkdms */
-       clkdm_for_each(clkdms_setup, NULL);
+       clkdm_for_each(omap_pm_clkdms_setup, NULL);
        clkdm_add_wkdep(mpu_clkdm, wkup_clkdm);
 
+#ifdef CONFIG_SUSPEND
+       omap_pm_suspend = omap2_enter_full_retention;
+#endif
+
        /* REVISIT: Configure number of 32 kHz clock cycles for sys_clk
         * stabilisation */
        omap2_prm_write_mod_reg(15 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD,
@@ -459,7 +380,6 @@ static int __init omap2_pm_init(void)
                                                    omap24xx_cpu_suspend_sz);
        }
 
-       suspend_set_ops(&omap_pm_ops);
        arm_pm_idle = omap2_pm_idle;
 
        return 0;
index b77df735fa6c760c56bcae09643008cc49c93e22..027a537d72b282f533a35e05bbc15b771dfb8ff8 100644 (file)
 #include "sdrc.h"
 #include "control.h"
 
-#ifdef CONFIG_SUSPEND
-static suspend_state_t suspend_state = PM_SUSPEND_ON;
-#endif
-
 /* pm34xx errata defined in pm.h */
 u16 pm34xx_errata;
 
@@ -75,16 +71,6 @@ static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
 static struct powerdomain *core_pwrdm, *per_pwrdm;
 static struct powerdomain *cam_pwrdm;
 
-static inline void omap3_per_save_context(void)
-{
-       omap_gpio_save_context();
-}
-
-static inline void omap3_per_restore_context(void)
-{
-       omap_gpio_restore_context();
-}
-
 static void omap3_enable_io_chain(void)
 {
        int timeout = 0;
@@ -290,11 +276,6 @@ void omap_sram_idle(void)
        int core_prev_state, per_prev_state;
        u32 sdrc_pwr = 0;
 
-       pwrdm_clear_all_prev_pwrst(mpu_pwrdm);
-       pwrdm_clear_all_prev_pwrst(neon_pwrdm);
-       pwrdm_clear_all_prev_pwrst(core_pwrdm);
-       pwrdm_clear_all_prev_pwrst(per_pwrdm);
-
        mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
        switch (mpu_next_state) {
        case PWRDM_POWER_ON:
@@ -332,8 +313,6 @@ void omap_sram_idle(void)
        if (per_next_state < PWRDM_POWER_ON) {
                per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
                omap2_gpio_prepare_for_idle(per_going_off);
-               if (per_next_state == PWRDM_POWER_OFF)
-                               omap3_per_save_context();
        }
 
        /* CORE */
@@ -399,8 +378,6 @@ void omap_sram_idle(void)
        if (per_next_state < PWRDM_POWER_ON) {
                per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm);
                omap2_gpio_resume_after_idle();
-               if (per_prev_state == PWRDM_POWER_OFF)
-                       omap3_per_restore_context();
        }
 
        /* Disable IO-PAD and IO-CHAIN wakeup */
@@ -477,50 +454,6 @@ restore:
        return ret;
 }
 
-static int omap3_pm_enter(suspend_state_t unused)
-{
-       int ret = 0;
-
-       switch (suspend_state) {
-       case PM_SUSPEND_STANDBY:
-       case PM_SUSPEND_MEM:
-               ret = omap3_pm_suspend();
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-/* Hooks to enable / disable UART interrupts during suspend */
-static int omap3_pm_begin(suspend_state_t state)
-{
-       disable_hlt();
-       suspend_state = state;
-       omap_prcm_irq_prepare();
-       return 0;
-}
-
-static void omap3_pm_end(void)
-{
-       suspend_state = PM_SUSPEND_ON;
-       enable_hlt();
-       return;
-}
-
-static void omap3_pm_finish(void)
-{
-       omap_prcm_irq_complete();
-}
-
-static const struct platform_suspend_ops omap_pm_ops = {
-       .begin          = omap3_pm_begin,
-       .end            = omap3_pm_end,
-       .enter          = omap3_pm_enter,
-       .finish         = omap3_pm_finish,
-       .valid          = suspend_valid_only_mem,
-};
 #endif /* CONFIG_SUSPEND */
 
 
@@ -740,21 +673,6 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
        return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
 }
 
-/*
- * Enable hw supervised mode for all clockdomains if it's
- * supported. Initiate sleep transition for other clockdomains, if
- * they are not used
- */
-static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
-{
-       if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
-               clkdm_allow_idle(clkdm);
-       else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
-                atomic_read(&clkdm->usecount) == 0)
-               clkdm_sleep(clkdm);
-       return 0;
-}
-
 /*
  * Push functions to SRAM
  *
@@ -824,7 +742,7 @@ static int __init omap3_pm_init(void)
                goto err2;
        }
 
-       (void) clkdm_for_each(clkdms_setup, NULL);
+       (void) clkdm_for_each(omap_pm_clkdms_setup, NULL);
 
        mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
        if (mpu_pwrdm == NULL) {
@@ -843,8 +761,8 @@ static int __init omap3_pm_init(void)
        core_clkdm = clkdm_lookup("core_clkdm");
 
 #ifdef CONFIG_SUSPEND
-       suspend_set_ops(&omap_pm_ops);
-#endif /* CONFIG_SUSPEND */
+       omap_pm_suspend = omap3_pm_suspend;
+#endif
 
        arm_pm_idle = omap3_pm_idle;
        omap3_idle_init();
index c840689df24ae5256da6e81c4fd232d28fcf6fa2..91e0b1c9b76c6c594f4e4d3a200d090f32f5401a 100644 (file)
@@ -83,59 +83,8 @@ static int omap4_pm_suspend(void)
 
        return 0;
 }
-
-static int omap4_pm_enter(suspend_state_t suspend_state)
-{
-       int ret = 0;
-
-       switch (suspend_state) {
-       case PM_SUSPEND_STANDBY:
-       case PM_SUSPEND_MEM:
-               ret = omap4_pm_suspend();
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-static int omap4_pm_begin(suspend_state_t state)
-{
-       disable_hlt();
-       return 0;
-}
-
-static void omap4_pm_end(void)
-{
-       enable_hlt();
-       return;
-}
-
-static const struct platform_suspend_ops omap_pm_ops = {
-       .begin          = omap4_pm_begin,
-       .end            = omap4_pm_end,
-       .enter          = omap4_pm_enter,
-       .valid          = suspend_valid_only_mem,
-};
 #endif /* CONFIG_SUSPEND */
 
-/*
- * Enable hardware supervised mode for all clockdomains if it's
- * supported. Initiate sleep transition for other clockdomains, if
- * they are not used
- */
-static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
-{
-       if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
-               clkdm_allow_idle(clkdm);
-       else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
-                       atomic_read(&clkdm->usecount) == 0)
-               clkdm_sleep(clkdm);
-       return 0;
-}
-
-
 static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 {
        struct power_state *pwrst;
@@ -247,11 +196,11 @@ static int __init omap4_pm_init(void)
                goto err2;
        }
 
-       (void) clkdm_for_each(clkdms_setup, NULL);
+       (void) clkdm_for_each(omap_pm_clkdms_setup, NULL);
 
 #ifdef CONFIG_SUSPEND
-       suspend_set_ops(&omap_pm_ops);
-#endif /* CONFIG_SUSPEND */
+       omap_pm_suspend = omap4_pm_suspend;
+#endif
 
        /* Overwrite the default cpu_do_idle() */
        arm_pm_idle = omap_default_idle;
index f97afff68d6dc172cbceff966ee6ead2820787d3..c0aeabfcf0091251b2f9893149f9482ac2c2f023 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <linux/bug.h>
 #include "pm.h"
 #include "cm.h"
 #include "cm-regbits-34xx.h"
index 6a17e4ca1d793817a96f870e70a3b87e73d0ca8a..0f0a9f1592fea28acbfa723919196a7527e918de 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
+#include <linux/bug.h>
 
 #include <plat/prcm.h>
 
index a7880af4b3d9f18164e48e6497587a2ed45f24a3..601325b852a422c1c44cff441989ad42d1d8f9e9 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
+#include <linux/bug.h>
 
 #include "powerdomain.h"
 #include <plat/prcm.h>
index 8ef26daeed68f966b64fb410e346dc073e940fe3..b7ea468eea326aa02537572139b9cc50da183b81 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/bug.h>
 
 #include <plat/cpu.h>
 
index ca669b50f3907182cfff3bf097e7354dd3fd3fc9..928dbd4f20ed7d7809eb21bd0abb061d944259d5 100644 (file)
@@ -15,8 +15,8 @@
 #include <linux/err.h>
 #include <linux/io.h>
 
+#include "iomap.h"
 #include "common.h"
-
 #include "prcm_mpu44xx.h"
 #include "cm-regbits-44xx.h"
 
index a1d6154dc120af3ceb056e0616c6d55eee6b17b9..eac623c7c3d86c58869c4804f63ad576631c129a 100644 (file)
 #include <linux/err.h>
 #include <linux/io.h>
 
-#include "common.h"
 #include <plat/cpu.h>
 #include <plat/irqs.h>
 #include <plat/prcm.h>
 
+#include "iomap.h"
+#include "common.h"
 #include "vp.h"
 #include "prm44xx.h"
 #include "prm-regbits-44xx.h"
index f6de5bc6b12ae2c116819aba0287f4e261560f4e..9b3898a3ac9b5a5a1e6787fe1f663ebc12efaac9 100644 (file)
@@ -16,8 +16,8 @@
 #include <linux/err.h>
 #include <linux/io.h>
 
+#include "iomap.h"
 #include "common.h"
-
 #include "prm44xx.h"
 #include "prminst44xx.h"
 #include "prm-regbits-44xx.h"
index 7479d7ea1379f6b2e29140d0683c381368d1dec1..845c4fd2b125238fd9516297c152a004300bc1e6 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/err.h>
 #include <linux/io.h>
 
-#include <plat/io.h>
 #include "common.h"
 #include <plat/clock.h>
 #include <plat/sdrc.h>
index 791a63cdceb281fc165279b39bec613e8bb2b260..1133bb2f632b8316d9bf12011569df3cad982070 100644 (file)
 #include <linux/clk.h>
 #include <linux/io.h>
 
-#include "common.h"
+#include <plat/hardware.h>
 #include <plat/clock.h>
 #include <plat/sram.h>
+#include <plat/sdrc.h>
 
+#include "iomap.h"
+#include "common.h"
 #include "prm2xxx_3xxx.h"
 #include "clock.h"
-#include <plat/sdrc.h>
 #include "sdrc.h"
 
 /* Memory timing, DLL mode flags */
index f590afc1f673f3afdb3c43cc89f0338ccb2fcc07..0cdd359a128ee855e357daee257ec38231a05658 100644 (file)
 
 struct omap_uart_state {
        int num;
-       int can_sleep;
 
        struct list_head node;
        struct omap_hwmod *oh;
-       struct platform_device *pdev;
 };
 
 static LIST_HEAD(uart_list);
@@ -381,8 +379,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,
 
        oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
 
-       uart->pdev = pdev;
-
        oh->dev_attr = uart;
 
        if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads)
index b5071a47ec395d2619f432eef9226b44a17a8bf7..d4bf904d84abbfb2bead1f2188da266f9a00e592 100644 (file)
@@ -27,7 +27,6 @@
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-#include <mach/io.h>
 
 #include <plat/omap24xx.h>
 
index f2ea1bd1c6918d72079a029fb00fc8725f4fafa4..1f62f23673fbab18b6676a56e3c5ea11273755f8 100644 (file)
  * MA 02111-1307 USA
  */
 #include <linux/linkage.h>
+
 #include <asm/assembler.h>
+
+#include <plat/hardware.h>
 #include <plat/sram.h>
-#include <mach/io.h>
 
+#include "iomap.h"
 #include "cm2xxx_3xxx.h"
 #include "prm2xxx_3xxx.h"
 #include "sdrc.h"
index 53d9d0a5b39d1a66fcb797161a3b24c0beeaf1f4..955566eefac4ac515516957e3f6d65cbc3353c35 100644 (file)
@@ -29,6 +29,7 @@ static int sr_class3_enable(struct voltagedomain *voltdm)
 
 static int sr_class3_disable(struct voltagedomain *voltdm, int is_volt_reset)
 {
+       sr_disable_errgen(voltdm);
        omap_vp_disable(voltdm);
        sr_disable(voltdm);
        if (is_volt_reset)
index 7e755bb0ffc4c6a9bbfa906609cc370e383fdbf1..008fbd7b9352271d46b385a303dfb53112489655 100644 (file)
 #define SR_DISABLE_TIMEOUT     200
 
 struct omap_sr {
+       struct list_head                node;
+       struct platform_device          *pdev;
+       struct omap_sr_nvalue_table     *nvalue_table;
+       struct voltagedomain            *voltdm;
+       struct dentry                   *dbg_dir;
+       unsigned int                    irq;
        int                             srid;
        int                             ip_type;
        int                             nvalue_count;
@@ -49,13 +55,7 @@ struct omap_sr {
        u32                             senp_avgweight;
        u32                             senp_mod;
        u32                             senn_mod;
-       unsigned int                    irq;
        void __iomem                    *base;
-       struct platform_device          *pdev;
-       struct list_head                node;
-       struct omap_sr_nvalue_table     *nvalue_table;
-       struct voltagedomain            *voltdm;
-       struct dentry                   *dbg_dir;
 };
 
 /* sr_list contains all the instances of smartreflex module */
@@ -74,10 +74,6 @@ static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask,
                                        u32 value)
 {
        u32 reg_val;
-       u32 errconfig_offs = 0, errconfig_mask = 0;
-
-       reg_val = __raw_readl(sr->base + offset);
-       reg_val &= ~mask;
 
        /*
         * Smartreflex error config register is special as it contains
@@ -88,16 +84,15 @@ static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask,
         * if they are currently set, but does allow the caller to write
         * those bits.
         */
-       if (sr->ip_type == SR_TYPE_V1) {
-               errconfig_offs = ERRCONFIG_V1;
-               errconfig_mask = ERRCONFIG_STATUS_V1_MASK;
-       } else if (sr->ip_type == SR_TYPE_V2) {
-               errconfig_offs = ERRCONFIG_V2;
-               errconfig_mask = ERRCONFIG_VPBOUNDINTST_V2;
-       }
+       if (sr->ip_type == SR_TYPE_V1 && offset == ERRCONFIG_V1)
+               mask |= ERRCONFIG_STATUS_V1_MASK;
+       else if (sr->ip_type == SR_TYPE_V2 && offset == ERRCONFIG_V2)
+               mask |= ERRCONFIG_VPBOUNDINTST_V2;
+
+       reg_val = __raw_readl(sr->base + offset);
+       reg_val &= ~mask;
 
-       if (offset == errconfig_offs)
-               reg_val &= ~errconfig_mask;
+       value &= mask;
 
        reg_val |= value;
 
@@ -128,21 +123,28 @@ static struct omap_sr *_sr_lookup(struct voltagedomain *voltdm)
 
 static irqreturn_t sr_interrupt(int irq, void *data)
 {
-       struct omap_sr *sr_info = (struct omap_sr *)data;
+       struct omap_sr *sr_info = data;
        u32 status = 0;
 
-       if (sr_info->ip_type == SR_TYPE_V1) {
+       switch (sr_info->ip_type) {
+       case SR_TYPE_V1:
                /* Read the status bits */
                status = sr_read_reg(sr_info, ERRCONFIG_V1);
 
                /* Clear them by writing back */
                sr_write_reg(sr_info, ERRCONFIG_V1, status);
-       } else if (sr_info->ip_type == SR_TYPE_V2) {
+               break;
+       case SR_TYPE_V2:
                /* Read the status bits */
                status = sr_read_reg(sr_info, IRQSTATUS);
 
                /* Clear them by writing back */
                sr_write_reg(sr_info, IRQSTATUS, status);
+               break;
+       default:
+               dev_err(&sr_info->pdev->dev, "UNKNOWN IP type %d\n",
+                       sr_info->ip_type);
+               return IRQ_NONE;
        }
 
        if (sr_class->notify)
@@ -166,6 +168,7 @@ static void sr_set_clk_length(struct omap_sr *sr)
                        __func__);
                return;
        }
+
        sys_clk_speed = clk_get_rate(sys_ck);
        clk_put(sys_ck);
 
@@ -267,7 +270,7 @@ static int sr_late_init(struct omap_sr *sr_info)
                        goto error;
                }
                ret = request_irq(sr_info->irq, sr_interrupt,
-                               0, name, (void *)sr_info);
+                               0, name, sr_info);
                if (ret)
                        goto error;
                disable_irq(sr_info->irq);
@@ -288,12 +291,15 @@ error:
                "not function as desired\n", __func__);
        kfree(name);
        kfree(sr_info);
+
        return ret;
 }
 
 static void sr_v1_disable(struct omap_sr *sr)
 {
        int timeout = 0;
+       int errconf_val = ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST |
+                       ERRCONFIG_MCUBOUNDINTST;
 
        /* Enable MCUDisableAcknowledge interrupt */
        sr_modify_reg(sr, ERRCONFIG_V1,
@@ -302,13 +308,13 @@ static void sr_v1_disable(struct omap_sr *sr)
        /* SRCONFIG - disable SR */
        sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
 
-       /* Disable all other SR interrupts and clear the status */
+       /* Disable all other SR interrupts and clear the status as needed */
+       if (sr_read_reg(sr, ERRCONFIG_V1) & ERRCONFIG_VPBOUNDINTST_V1)
+               errconf_val |= ERRCONFIG_VPBOUNDINTST_V1;
        sr_modify_reg(sr, ERRCONFIG_V1,
                        (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
                        ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN_V1),
-                       (ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST |
-                       ERRCONFIG_MCUBOUNDINTST |
-                       ERRCONFIG_VPBOUNDINTST_V1));
+                       errconf_val);
 
        /*
         * Wait for SR to be disabled.
@@ -337,9 +343,17 @@ static void sr_v2_disable(struct omap_sr *sr)
        /* SRCONFIG - disable SR */
        sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
 
-       /* Disable all other SR interrupts and clear the status */
-       sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2,
+       /*
+        * Disable all other SR interrupts and clear the status
+        * write to status register ONLY on need basis - only if status
+        * is set.
+        */
+       if (sr_read_reg(sr, ERRCONFIG_V2) & ERRCONFIG_VPBOUNDINTST_V2)
+               sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2,
                        ERRCONFIG_VPBOUNDINTST_V2);
+       else
+               sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2,
+                               0x0);
        sr_write_reg(sr, IRQENABLE_CLR, (IRQENABLE_MCUACCUMINT |
                        IRQENABLE_MCUVALIDINT |
                        IRQENABLE_MCUBOUNDSINT));
@@ -398,15 +412,16 @@ static u32 sr_retrieve_nvalue(struct omap_sr *sr, u32 efuse_offs)
  */
 int sr_configure_errgen(struct voltagedomain *voltdm)
 {
-       u32 sr_config, sr_errconfig, errconfig_offs, vpboundint_en;
-       u32 vpboundint_st, senp_en = 0, senn_en = 0;
+       u32 sr_config, sr_errconfig, errconfig_offs;
+       u32 vpboundint_en, vpboundint_st;
+       u32 senp_en = 0, senn_en = 0;
        u8 senp_shift, senn_shift;
        struct omap_sr *sr = _sr_lookup(voltdm);
 
        if (IS_ERR(sr)) {
                pr_warning("%s: omap_sr struct for sr_%s not found\n",
                        __func__, voltdm->name);
-               return -EINVAL;
+               return PTR_ERR(sr);
        }
 
        if (!sr->clk_length)
@@ -418,20 +433,23 @@ int sr_configure_errgen(struct voltagedomain *voltdm)
        sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
                SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN;
 
-       if (sr->ip_type == SR_TYPE_V1) {
+       switch (sr->ip_type) {
+       case SR_TYPE_V1:
                sr_config |= SRCONFIG_DELAYCTRL;
                senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT;
                senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT;
                errconfig_offs = ERRCONFIG_V1;
                vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1;
                vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1;
-       } else if (sr->ip_type == SR_TYPE_V2) {
+               break;
+       case SR_TYPE_V2:
                senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT;
                senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT;
                errconfig_offs = ERRCONFIG_V2;
                vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2;
                vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2;
-       } else {
+               break;
+       default:
                dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
                        "module without specifying the ip\n", __func__);
                return -EINVAL;
@@ -447,8 +465,55 @@ int sr_configure_errgen(struct voltagedomain *voltdm)
                sr_errconfig);
 
        /* Enabling the interrupts if the ERROR module is used */
-       sr_modify_reg(sr, errconfig_offs,
-               vpboundint_en, (vpboundint_en | vpboundint_st));
+       sr_modify_reg(sr, errconfig_offs, (vpboundint_en | vpboundint_st),
+                     vpboundint_en);
+
+       return 0;
+}
+
+/**
+ * sr_disable_errgen() - Disables SmartReflex AVS module's errgen component
+ * @voltdm:    VDD pointer to which the SR module to be configured belongs to.
+ *
+ * This API is to be called from the smartreflex class driver to
+ * disable the error generator module inside the smartreflex module.
+ *
+ * Returns 0 on success and error value in case of failure.
+ */
+int sr_disable_errgen(struct voltagedomain *voltdm)
+{
+       u32 errconfig_offs;
+       u32 vpboundint_en, vpboundint_st;
+       struct omap_sr *sr = _sr_lookup(voltdm);
+
+       if (IS_ERR(sr)) {
+               pr_warning("%s: omap_sr struct for sr_%s not found\n",
+                       __func__, voltdm->name);
+               return PTR_ERR(sr);
+       }
+
+       switch (sr->ip_type) {
+       case SR_TYPE_V1:
+               errconfig_offs = ERRCONFIG_V1;
+               vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1;
+               vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1;
+               break;
+       case SR_TYPE_V2:
+               errconfig_offs = ERRCONFIG_V2;
+               vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2;
+               vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2;
+               break;
+       default:
+               dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
+                       "module without specifying the ip\n", __func__);
+               return -EINVAL;
+       }
+
+       /* Disable the interrupts of ERROR module */
+       sr_modify_reg(sr, errconfig_offs, vpboundint_en | vpboundint_st, 0);
+
+       /* Disable the Sensor and errorgen */
+       sr_modify_reg(sr, SRCONFIG, SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN, 0);
 
        return 0;
 }
@@ -475,7 +540,7 @@ int sr_configure_minmax(struct voltagedomain *voltdm)
        if (IS_ERR(sr)) {
                pr_warning("%s: omap_sr struct for sr_%s not found\n",
                        __func__, voltdm->name);
-               return -EINVAL;
+               return PTR_ERR(sr);
        }
 
        if (!sr->clk_length)
@@ -488,14 +553,17 @@ int sr_configure_minmax(struct voltagedomain *voltdm)
                SRCONFIG_SENENABLE |
                (sr->accum_data << SRCONFIG_ACCUMDATA_SHIFT);
 
-       if (sr->ip_type == SR_TYPE_V1) {
+       switch (sr->ip_type) {
+       case SR_TYPE_V1:
                sr_config |= SRCONFIG_DELAYCTRL;
                senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT;
                senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT;
-       } else if (sr->ip_type == SR_TYPE_V2) {
+               break;
+       case SR_TYPE_V2:
                senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT;
                senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT;
-       } else {
+               break;
+       default:
                dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
                        "module without specifying the ip\n", __func__);
                return -EINVAL;
@@ -511,20 +579,27 @@ int sr_configure_minmax(struct voltagedomain *voltdm)
         * Enabling the interrupts if MINMAXAVG module is used.
         * TODO: check if all the interrupts are mandatory
         */
-       if (sr->ip_type == SR_TYPE_V1) {
+       switch (sr->ip_type) {
+       case SR_TYPE_V1:
                sr_modify_reg(sr, ERRCONFIG_V1,
                        (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
                        ERRCONFIG_MCUBOUNDINTEN),
                        (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUACCUMINTST |
                         ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUVALIDINTST |
                         ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_MCUBOUNDINTST));
-       } else if (sr->ip_type == SR_TYPE_V2) {
+               break;
+       case SR_TYPE_V2:
                sr_write_reg(sr, IRQSTATUS,
                        IRQSTATUS_MCUACCUMINT | IRQSTATUS_MCVALIDINT |
                        IRQSTATUS_MCBOUNDSINT | IRQSTATUS_MCUDISABLEACKINT);
                sr_write_reg(sr, IRQENABLE_SET,
                        IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT |
                        IRQENABLE_MCUBOUNDSINT | IRQENABLE_MCUDISABLEACKINT);
+               break;
+       default:
+               dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
+                       "module without specifying the ip\n", __func__);
+               return -EINVAL;
        }
 
        return 0;
@@ -543,15 +618,15 @@ int sr_configure_minmax(struct voltagedomain *voltdm)
  */
 int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
 {
-       u32 nvalue_reciprocal;
        struct omap_volt_data *volt_data;
        struct omap_sr *sr = _sr_lookup(voltdm);
+       u32 nvalue_reciprocal;
        int ret;
 
        if (IS_ERR(sr)) {
                pr_warning("%s: omap_sr struct for sr_%s not found\n",
                        __func__, voltdm->name);
-               return -EINVAL;
+               return PTR_ERR(sr);
        }
 
        volt_data = omap_voltage_get_voltdata(sr->voltdm, volt);
@@ -559,7 +634,7 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
        if (IS_ERR(volt_data)) {
                dev_warn(&sr->pdev->dev, "%s: Unable to get voltage table"
                        "for nominal voltage %ld\n", __func__, volt);
-               return -ENODATA;
+               return PTR_ERR(volt_data);
        }
 
        nvalue_reciprocal = sr_retrieve_nvalue(sr, volt_data->sr_efuse_offs);
@@ -617,10 +692,17 @@ void sr_disable(struct voltagedomain *voltdm)
         * disable the clocks.
         */
        if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE) {
-               if (sr->ip_type == SR_TYPE_V1)
+               switch (sr->ip_type) {
+               case SR_TYPE_V1:
                        sr_v1_disable(sr);
-               else if (sr->ip_type == SR_TYPE_V2)
+                       break;
+               case SR_TYPE_V2:
                        sr_v2_disable(sr);
+                       break;
+               default:
+                       dev_err(&sr->pdev->dev, "UNKNOWN IP type %d\n",
+                               sr->ip_type);
+               }
        }
 
        pm_runtime_put_sync_suspend(&sr->pdev->dev);
@@ -779,10 +861,10 @@ void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data)
        sr_pmic_data = pmic_data;
 }
 
-/* PM Debug Fs enteries to enable disable smartreflex. */
+/* PM Debug FS entries to enable and disable smartreflex. */
 static int omap_sr_autocomp_show(void *data, u64 *val)
 {
-       struct omap_sr *sr_info = (struct omap_sr *) data;
+       struct omap_sr *sr_info = data;
 
        if (!sr_info) {
                pr_warning("%s: omap_sr struct not found\n", __func__);
@@ -796,7 +878,7 @@ static int omap_sr_autocomp_show(void *data, u64 *val)
 
 static int omap_sr_autocomp_store(void *data, u64 val)
 {
-       struct omap_sr *sr_info = (struct omap_sr *) data;
+       struct omap_sr *sr_info = data;
 
        if (!sr_info) {
                pr_warning("%s: omap_sr struct not found\n", __func__);
@@ -804,7 +886,7 @@ static int omap_sr_autocomp_store(void *data, u64 val)
        }
 
        /* Sanity check */
-       if (val && (val != 1)) {
+       if (val > 1) {
                pr_warning("%s: Invalid argument %lld\n", __func__, val);
                return -EINVAL;
        }
@@ -821,11 +903,11 @@ static int omap_sr_autocomp_store(void *data, u64 val)
 }
 
 DEFINE_SIMPLE_ATTRIBUTE(pm_sr_fops, omap_sr_autocomp_show,
-               omap_sr_autocomp_store, "%llu\n");
+                       omap_sr_autocomp_store, "%llu\n");
 
 static int __init omap_sr_probe(struct platform_device *pdev)
 {
-       struct omap_sr *sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
+       struct omap_sr *sr_info;
        struct omap_sr_data *pdata = pdev->dev.platform_data;
        struct resource *mem, *irq;
        struct dentry *nvalue_dir;
@@ -833,12 +915,15 @@ static int __init omap_sr_probe(struct platform_device *pdev)
        int i, ret = 0;
        char *name;
 
+       sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
        if (!sr_info) {
                dev_err(&pdev->dev, "%s: unable to allocate sr_info\n",
                        __func__);
                return -ENOMEM;
        }
 
+       platform_set_drvdata(pdev, sr_info);
+
        if (!pdata) {
                dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
                ret = -EINVAL;
@@ -904,7 +989,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
        dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__);
        if (!sr_dbg_dir) {
                sr_dbg_dir = debugfs_create_dir("smartreflex", NULL);
-               if (!sr_dbg_dir) {
+               if (IS_ERR_OR_NULL(sr_dbg_dir)) {
                        ret = PTR_ERR(sr_dbg_dir);
                        pr_err("%s:sr debugfs dir creation failed(%d)\n",
                                __func__, ret);
@@ -921,7 +1006,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
        }
        sr_info->dbg_dir = debugfs_create_dir(name, sr_dbg_dir);
        kfree(name);
-       if (IS_ERR(sr_info->dbg_dir)) {
+       if (IS_ERR_OR_NULL(sr_info->dbg_dir)) {
                dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
                        __func__);
                ret = PTR_ERR(sr_info->dbg_dir);
@@ -938,7 +1023,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
                        &sr_info->err_minlimit);
 
        nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir);
-       if (IS_ERR(nvalue_dir)) {
+       if (IS_ERR_OR_NULL(nvalue_dir)) {
                dev_err(&pdev->dev, "%s: Unable to create debugfs directory"
                        "for n-values\n", __func__);
                ret = PTR_ERR(nvalue_dir);
@@ -994,7 +1079,7 @@ static int __devexit omap_sr_remove(struct platform_device *pdev)
        if (IS_ERR(sr_info)) {
                dev_warn(&pdev->dev, "%s: omap_sr struct not found\n",
                        __func__);
-               return -EINVAL;
+               return PTR_ERR(sr_info);
        }
 
        if (sr_info->autocomp_active)
@@ -1011,8 +1096,32 @@ static int __devexit omap_sr_remove(struct platform_device *pdev)
        return 0;
 }
 
+static void __devexit omap_sr_shutdown(struct platform_device *pdev)
+{
+       struct omap_sr_data *pdata = pdev->dev.platform_data;
+       struct omap_sr *sr_info;
+
+       if (!pdata) {
+               dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
+               return;
+       }
+
+       sr_info = _sr_lookup(pdata->voltdm);
+       if (IS_ERR(sr_info)) {
+               dev_warn(&pdev->dev, "%s: omap_sr struct not found\n",
+                       __func__);
+               return;
+       }
+
+       if (sr_info->autocomp_active)
+               sr_stop_vddautocomp(sr_info);
+
+       return;
+}
+
 static struct platform_driver smartreflex_driver = {
-       .remove         = omap_sr_remove,
+       .remove         = __devexit_p(omap_sr_remove),
+       .shutdown       = __devexit_p(omap_sr_shutdown),
        .driver         = {
                .name   = "smartreflex",
        },
@@ -1042,12 +1151,12 @@ static int __init sr_init(void)
 
        return 0;
 }
+late_initcall(sr_init);
 
 static void __exit sr_exit(void)
 {
        platform_driver_unregister(&smartreflex_driver);
 }
-late_initcall(sr_init);
 module_exit(sr_exit);
 
 MODULE_DESCRIPTION("OMAP Smartreflex Driver");
index 5f35b9e2555603fcbd44f1150439a371c31bbde1..5809141171f8c6f0553a6c0607964ab1e443780f 100644 (file)
@@ -152,6 +152,15 @@ struct omap_sr_pmic_data {
        void (*sr_pmic_init) (void);
 };
 
+/**
+ * struct omap_smartreflex_dev_attr - Smartreflex Device attribute.
+ *
+ * @sensor_voltdm_name:       Name of voltdomain of SR instance
+ */
+struct omap_smartreflex_dev_attr {
+       const char      *sensor_voltdm_name;
+};
+
 #ifdef CONFIG_OMAP_SMARTREFLEX
 /*
  * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR.
@@ -231,6 +240,7 @@ void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data);
 int sr_enable(struct voltagedomain *voltdm, unsigned long volt);
 void sr_disable(struct voltagedomain *voltdm);
 int sr_configure_errgen(struct voltagedomain *voltdm);
+int sr_disable_errgen(struct voltagedomain *voltdm);
 int sr_configure_minmax(struct voltagedomain *voltdm);
 
 /* API to register the smartreflex class driver with the smartreflex driver */
index 9f43fcc05d3e5825b78e194e1929dd2d85c8799b..a503e1e8358c1f011b193a22f33c48ff38ce89d2 100644 (file)
@@ -69,11 +69,12 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
        sr_data->nvalue_count = count;
 }
 
-static int sr_dev_init(struct omap_hwmod *oh, void *user)
+static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
 {
        struct omap_sr_data *sr_data;
        struct platform_device *pdev;
        struct omap_volt_data *volt_data;
+       struct omap_smartreflex_dev_attr *sr_dev_attr;
        char *name = "smartreflex";
        static int i;
 
@@ -84,9 +85,11 @@ static int sr_dev_init(struct omap_hwmod *oh, void *user)
                return -ENOMEM;
        }
 
-       if (!oh->vdd_name) {
+       sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr;
+       if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) {
                pr_err("%s: No voltage domain specified for %s."
-                       "Cannot initialize\n", __func__, oh->name);
+                               "Cannot initialize\n", __func__,
+                                       oh->name);
                goto exit;
        }
 
@@ -94,10 +97,10 @@ static int sr_dev_init(struct omap_hwmod *oh, void *user)
        sr_data->senn_mod = 0x1;
        sr_data->senp_mod = 0x1;
 
-       sr_data->voltdm = voltdm_lookup(oh->vdd_name);
+       sr_data->voltdm = voltdm_lookup(sr_dev_attr->sensor_voltdm_name);
        if (IS_ERR(sr_data->voltdm)) {
                pr_err("%s: Unable to get voltage domain pointer for VDD %s\n",
-                       __func__, oh->vdd_name);
+                       __func__, sr_dev_attr->sensor_voltdm_name);
                goto exit;
        }
 
index ff9b9dbcb30efa9e2a10707b7247646261b40524..ee0bfcc1410f89a38f449f35338b381b6773cd4c 100644 (file)
  * These crashes may be intermittent.
  */
 #include <linux/linkage.h>
+
 #include <asm/assembler.h>
-#include <mach/io.h>
+
 #include <mach/hardware.h>
 
+#include "iomap.h"
 #include "prm2xxx_3xxx.h"
 #include "cm2xxx_3xxx.h"
 #include "sdrc.h"
index 76730209fa0e4ed29820d9608eea2bdab643c04c..d4d39ef04769c806716c14eee04e73ac4bc8ce0f 100644 (file)
  * These crashes may be intermittent.
  */
 #include <linux/linkage.h>
+
 #include <asm/assembler.h>
-#include <mach/io.h>
+
 #include <mach/hardware.h>
 
+#include "iomap.h"
 #include "prm2xxx_3xxx.h"
 #include "cm2xxx_3xxx.h"
 #include "sdrc.h"
index 6f5849aaa7c00b0cc2e7a270dc8f4401addb35b6..df5a21322b0ac1b68d8446c9da3b331a5c5957cd 100644 (file)
  * MA 02111-1307 USA
  */
 #include <linux/linkage.h>
+
 #include <asm/assembler.h>
-#include <mach/hardware.h>
 
-#include <mach/io.h>
+#include <mach/hardware.h>
 
+#include "iomap.h"
 #include "sdrc.h"
 #include "cm2xxx_3xxx.h"
 
diff --git a/arch/arm/mach-omap2/timer-mpu.c b/arch/arm/mach-omap2/timer-mpu.c
deleted file mode 100644 (file)
index 31c0ac4..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * The MPU local timer source file. In OMAP4, both cortex-a9 cores have
- * own timer in it's MPU domain. These timers will be driving the
- * linux kernel SMP tick framework when active. These timers are not
- * part of the wake up domain.
- *
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Author:
- *      Santosh Shilimkar <santosh.shilimkar@ti.com>
- *
- * This file is based on arm realview smp platform file.
- * Copyright (C) 2002 ARM Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/clockchips.h>
-#include <asm/irq.h>
-#include <asm/smp_twd.h>
-#include <asm/localtimer.h>
-
-/*
- * Setup the local clock events for a CPU.
- */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-       /* Local timers are not supprted on OMAP4430 ES1.0 */
-       if (omap_rev() == OMAP4430_REV_ES1_0)
-               return -ENXIO;
-
-       evt->irq = OMAP44XX_IRQ_LOCALTIMER;
-       twd_timer_setup(evt);
-       return 0;
-}
-
index 5c9acea957619196d502baaa3fd591e96a1db01d..c512bac69ec587a12137071cf3b60297955583bb 100644 (file)
@@ -39,7 +39,7 @@
 
 #include <asm/mach/time.h>
 #include <plat/dmtimer.h>
-#include <asm/localtimer.h>
+#include <asm/smp_twd.h>
 #include <asm/sched_clock.h>
 #include "common.h"
 #include <plat/omap_hwmod.h>
@@ -324,14 +324,26 @@ OMAP_SYS_TIMER(3_secure)
 #endif
 
 #ifdef CONFIG_ARCH_OMAP4
-static void __init omap4_timer_init(void)
-{
 #ifdef CONFIG_LOCAL_TIMERS
-       twd_base = ioremap(OMAP44XX_LOCAL_TWD_BASE, SZ_256);
-       BUG_ON(!twd_base);
+static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
+                             OMAP44XX_LOCAL_TWD_BASE,
+                             OMAP44XX_IRQ_LOCALTIMER);
 #endif
+
+static void __init omap4_timer_init(void)
+{
        omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE);
        omap2_gp_clocksource_init(2, OMAP4_MPU_SOURCE);
+#ifdef CONFIG_LOCAL_TIMERS
+       /* Local timers are not supprted on OMAP4430 ES1.0 */
+       if (omap_rev() != OMAP4430_REV_ES1_0) {
+               int err;
+
+               err = twd_local_timer_register(&twd_local_timer);
+               if (err)
+                       pr_err("twd_local_timer_register failed %d\n", err);
+       }
+#endif
 }
 OMAP_SYS_TIMER(4)
 #endif
index 175b7d86d86ac3673d926745dc67e42a4e0ad899..84da34f9a7cff598ab059a604fb3bf14ec5ddea4 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/bug.h>
 
 #include <plat/cpu.h>
 
index 0df88820978d5d509ded718d3311659e8ab079d4..f95c1bad9dc6363a573fee56f6addaa17a0accfd 100644 (file)
@@ -61,8 +61,8 @@ void __init omap_vp_init(struct voltagedomain *voltdm)
        vddmin = voltdm->pmic->vp_vddmin;
        vddmax = voltdm->pmic->vp_vddmax;
 
-       waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) *
-                   sys_clk_rate) / 1000;
+       waittime = DIV_ROUND_UP(voltdm->pmic->step_size * sys_clk_rate,
+                               1000 * voltdm->pmic->slew_rate);
        vstepmin = voltdm->pmic->vp_vstepmin;
        vstepmax = voltdm->pmic->vp_vstepmax;
 
index 5bc13121eac5d15eb239e3992b18f90720f67416..84f2d7015cfeced0850588ba7572968f1943f630 100644 (file)
@@ -406,20 +406,17 @@ static struct resource pxa_rtc_resources[] = {
        [1] = {
                .start  = IRQ_RTC1Hz,
                .end    = IRQ_RTC1Hz,
+               .name   = "rtc 1Hz",
                .flags  = IORESOURCE_IRQ,
        },
        [2] = {
                .start  = IRQ_RTCAlrm,
                .end    = IRQ_RTCAlrm,
+               .name   = "rtc alarm",
                .flags  = IORESOURCE_IRQ,
        },
 };
 
-struct platform_device sa1100_device_rtc = {
-       .name           = "sa1100-rtc",
-       .id             = -1,
-};
-
 struct platform_device pxa_device_rtc = {
        .name           = "pxa-rtc",
        .id             = -1,
@@ -427,6 +424,27 @@ struct platform_device pxa_device_rtc = {
        .resource       = pxa_rtc_resources,
 };
 
+static struct resource sa1100_rtc_resources[] = {
+       {
+               .start  = IRQ_RTC1Hz,
+               .end    = IRQ_RTC1Hz,
+               .name   = "rtc 1Hz",
+               .flags  = IORESOURCE_IRQ,
+       }, {
+               .start  = IRQ_RTCAlrm,
+               .end    = IRQ_RTCAlrm,
+               .name   = "rtc alarm",
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device sa1100_device_rtc = {
+       .name           = "sa1100-rtc",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(sa1100_rtc_resources),
+       .resource       = sa1100_rtc_resources,
+};
+
 static struct resource pxa_ac97_resources[] = {
        [0] = {
                .start  = 0x40500000,
index 208eef1c04858a8ec76c40adcaddc131e5b5fb7f..3fa929d4a4f5b748ec9885c11d255d33aa00b6cd 100644 (file)
@@ -28,7 +28,8 @@
 #include <linux/mtd/physmap.h>
 #include <linux/pda_power.h>
 #include <linux/pwm_backlight.h>
-#include <linux/regulator/bq24022.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/gpio-regulator.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/max1586.h>
 #include <linux/spi/ads7846.h>
@@ -97,9 +98,9 @@ static unsigned long hx4700_pin_config[] __initdata = {
 
        /* BTUART */
        GPIO42_BTUART_RXD,
-       GPIO43_BTUART_TXD,
+       GPIO43_BTUART_TXD_LPM_LOW,
        GPIO44_BTUART_CTS,
-       GPIO45_BTUART_RTS,
+       GPIO45_BTUART_RTS_LPM_LOW,
 
        /* PWM 1 (Backlight) */
        GPIO17_PWM1_OUT,
@@ -245,6 +246,21 @@ static u16 asic3_gpio_config[] = {
        ASIC3_GPIOD15_nPIOW,
 };
 
+static struct asic3_led asic3_leds[ASIC3_NUM_LEDS] = {
+       [0] = {
+               .name = "hx4700:amber",
+               .default_trigger = "ds2760-battery.0-charging-blink-full-solid",
+       },
+       [1] = {
+               .name = "hx4700:green",
+               .default_trigger = "unused",
+       },
+       [2] = {
+               .name = "hx4700:blue",
+               .default_trigger = "hx4700-radio",
+       },
+};
+
 static struct resource asic3_resources[] = {
        /* GPIO part */
        [0] = {
@@ -275,6 +291,7 @@ static struct asic3_platform_data asic3_platform_data = {
        .gpio_config_num = ARRAY_SIZE(asic3_gpio_config),
        .irq_base        = IRQ_BOARD_START,
        .gpio_base       = HX4700_ASIC3_GPIO_BASE,
+       .leds            = asic3_leds,
 };
 
 static struct platform_device asic3 = {
@@ -682,14 +699,34 @@ static struct regulator_init_data bq24022_init_data = {
        .consumer_supplies      = bq24022_consumers,
 };
 
-static struct bq24022_mach_info bq24022_info = {
-       .gpio_nce   = GPIO72_HX4700_BQ24022_nCHARGE_EN,
-       .gpio_iset2 = GPIO96_HX4700_BQ24022_ISET2,
-       .init_data  = &bq24022_init_data,
+static struct gpio bq24022_gpios[] = {
+       { GPIO96_HX4700_BQ24022_ISET2, GPIOF_OUT_INIT_LOW, "bq24022_iset2" },
+};
+
+static struct gpio_regulator_state bq24022_states[] = {
+       { .value = 100000, .gpios = (0 << 0) },
+       { .value = 500000, .gpios = (1 << 0) },
+};
+
+static struct gpio_regulator_config bq24022_info = {
+       .supply_name = "bq24022",
+
+       .enable_gpio = GPIO72_HX4700_BQ24022_nCHARGE_EN,
+       .enable_high = 0,
+       .enabled_at_boot = 0,
+
+       .gpios = bq24022_gpios,
+       .nr_gpios = ARRAY_SIZE(bq24022_gpios),
+
+       .states = bq24022_states,
+       .nr_states = ARRAY_SIZE(bq24022_states),
+
+       .type = REGULATOR_CURRENT,
+       .init_data = &bq24022_init_data,
 };
 
 static struct platform_device bq24022 = {
-       .name = "bq24022",
+       .name = "gpio-regulator",
        .id   = -1,
        .dev  = {
                .platform_data = &bq24022_info,
@@ -705,10 +742,9 @@ static void hx4700_set_vpp(struct platform_device *pdev, int vpp)
        gpio_set_value(GPIO91_HX4700_FLASH_VPEN, vpp);
 }
 
-static struct resource strataflash_resource = {
-       .start = PXA_CS0_PHYS,
-       .end   = PXA_CS0_PHYS + SZ_128M - 1,
-       .flags = IORESOURCE_MEM,
+static struct resource strataflash_resource[] = {
+       [0] = DEFINE_RES_MEM(PXA_CS0_PHYS, SZ_64M),
+       [1] = DEFINE_RES_MEM(PXA_CS0_PHYS + SZ_64M, SZ_64M),
 };
 
 static struct physmap_flash_data strataflash_data = {
@@ -719,8 +755,8 @@ static struct physmap_flash_data strataflash_data = {
 static struct platform_device strataflash = {
        .name          = "physmap-flash",
        .id            = -1,
-       .resource      = &strataflash_resource,
-       .num_resources = 1,
+       .resource      = strataflash_resource,
+       .num_resources = ARRAY_SIZE(strataflash_resource),
        .dev = {
                .platform_data = &strataflash_data,
        },
@@ -787,17 +823,6 @@ static struct platform_device audio = {
 };
 
 
-/*
- * PCMCIA
- */
-
-static struct platform_device pcmcia = {
-       .name = "hx4700-pcmcia",
-       .dev  = {
-               .parent = &asic3.dev,
-       },
-};
-
 /*
  * Platform devices
  */
@@ -814,7 +839,6 @@ static struct platform_device *devices[] __initdata = {
        &power_supply,
        &strataflash,
        &audio,
-       &pcmcia,
 };
 
 static struct gpio global_gpios[] = {
@@ -830,7 +854,6 @@ static struct gpio global_gpios[] = {
        { GPIO32_HX4700_RS232_ON,         GPIOF_OUT_INIT_HIGH, "RS232_ON" },
        { GPIO71_HX4700_ASIC3_nRESET,     GPIOF_OUT_INIT_HIGH, "ASIC3_nRESET" },
        { GPIO82_HX4700_EUART_RESET,      GPIOF_OUT_INIT_HIGH, "EUART_RESET" },
-       { GPIO105_HX4700_nIR_ON,          GPIOF_OUT_INIT_HIGH, "nIR_EN" },
 };
 
 static void __init hx4700_init(void)
index ec0f0b0b6744b9afba76c6b482cf888b7b530b81..a65867209aa0da3e251b3791377e4f8966b37d72 100644 (file)
 #define GPIO44_BTUART_CTS      MFP_CFG_IN(GPIO44, AF1)
 #define GPIO42_BTUART_RXD      MFP_CFG_IN(GPIO42, AF1)
 #define GPIO45_BTUART_RTS      MFP_CFG_OUT(GPIO45, AF2, DRIVE_HIGH)
+#define GPIO45_BTUART_RTS_LPM_LOW      MFP_CFG_OUT(GPIO45, AF2, DRIVE_LOW)
 #define GPIO43_BTUART_TXD      MFP_CFG_OUT(GPIO43, AF2, DRIVE_HIGH)
+#define GPIO43_BTUART_TXD_LPM_LOW      MFP_CFG_OUT(GPIO43, AF2, DRIVE_LOW)
 
 /* STUART */
 #define GPIO46_STUART_RXD      MFP_CFG_IN(GPIO46, AF2)
index 6ebd276aebeb484a93923689657d35867f3cf7d5..6bb3f47b1f14e7070cfeb5c3dbaff57949adac10 100644 (file)
@@ -223,6 +223,7 @@ static struct resource sa1111_resources[] = {
 
 static struct sa1111_platform_data sa1111_info = {
        .irq_base       = LUBBOCK_SA1111_IRQ_BASE,
+       .disable_devs   = SA1111_DEVID_SAC,
 };
 
 static struct platform_device sa1111_device = {
index 3d6baf91396cd2cd52f2b41163f17a17cea6aa5d..5e26f3e93fddf5f8e4a56adb3cc53806839b6e36 100644 (file)
@@ -25,7 +25,8 @@
 #include <linux/mtd/physmap.h>
 #include <linux/pda_power.h>
 #include <linux/pwm_backlight.h>
-#include <linux/regulator/bq24022.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/gpio-regulator.h>
 #include <linux/regulator/machine.h>
 #include <linux/usb/gpio_vbus.h>
 #include <linux/i2c/pxa-i2c.h>
@@ -596,14 +597,34 @@ static struct regulator_init_data bq24022_init_data = {
        .consumer_supplies      = bq24022_consumers,
 };
 
-static struct bq24022_mach_info bq24022_info = {
-       .gpio_nce   = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
-       .gpio_iset2 = EGPIO_MAGICIAN_BQ24022_ISET2,
-       .init_data  = &bq24022_init_data,
+static struct gpio bq24022_gpios[] = {
+       { EGPIO_MAGICIAN_BQ24022_ISET2, GPIOF_OUT_INIT_LOW, "bq24022_iset2" },
+};
+
+static struct gpio_regulator_state bq24022_states[] = {
+       { .value = 100000, .gpios = (0 << 0) },
+       { .value = 500000, .gpios = (1 << 0) },
+};
+
+static struct gpio_regulator_config bq24022_info = {
+       .supply_name = "bq24022",
+
+       .enable_gpio = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
+       .enable_high = 0,
+       .enabled_at_boot = 0,
+
+       .gpios = bq24022_gpios,
+       .nr_gpios = ARRAY_SIZE(bq24022_gpios),
+
+       .states = bq24022_states,
+       .nr_states = ARRAY_SIZE(bq24022_states),
+
+       .type = REGULATOR_CURRENT,
+       .init_data = &bq24022_init_data,
 };
 
 static struct platform_device bq24022 = {
-       .name = "bq24022",
+       .name = "gpio-regulator",
        .id   = -1,
        .dev  = {
                .platform_data = &bq24022_info,
index 3918a672238e4a368f0474c699ebc1c2cb680bb7..1570d457fea3b87f52629ce2b1982c27229c3d40 100644 (file)
@@ -89,6 +89,7 @@ static struct clk_lookup pxa3xx_clkregs[] = {
        INIT_CLKREG(&clk_pxa3xx_mmc2, "pxa2xx-mci.1", NULL),
        INIT_CLKREG(&clk_pxa3xx_smemc, "pxa2xx-pcmcia", NULL),
        INIT_CLKREG(&clk_pxa3xx_gpio, "pxa-gpio", NULL),
+       INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
 };
 
 #ifdef CONFIG_PM
index 5ce434b95e87a52941f38ca8e023753b940802e5..47601f80e6e7e9b64c8236541695dd68e0f24979 100644 (file)
@@ -231,6 +231,7 @@ static struct clk_lookup pxa95x_clkregs[] = {
        INIT_CLKREG(&clk_pxa95x_pwm0, "pxa27x-pwm.0", NULL),
        INIT_CLKREG(&clk_pxa95x_pwm1, "pxa27x-pwm.1", NULL),
        INIT_CLKREG(&clk_pxa95x_gpio, "pxa-gpio", NULL),
+       INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
 };
 
 void __init pxa95x_init_irq(void)
index 157e1bc6e83c17197ffbdbc48d4cdbe2572404c5..baf382c5e77601957b2ef8982ccdd61552f9b2f2 100644 (file)
@@ -36,7 +36,7 @@
 #include <asm/pgtable.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/cache-l2x0.h>
-#include <asm/localtimer.h>
+#include <asm/smp_twd.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -383,6 +383,23 @@ static void realview_eb11mp_fixup(void)
        realview_eb_isp1761_resources[1].end    = IRQ_EB11MP_USB;
 }
 
+#ifdef CONFIG_HAVE_ARM_TWD
+static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
+                             REALVIEW_EB11MP_TWD_BASE,
+                             IRQ_LOCALTIMER);
+
+static void __init realview_eb_twd_init(void)
+{
+       if (core_tile_eb11mp() || core_tile_a9mp()) {
+               int err = twd_local_timer_register(&twd_local_timer);
+               if (err)
+                       pr_err("twd_local_timer_register failed %d\n", err);
+       }
+}
+#else
+#define realview_eb_twd_init() do { } while(0)
+#endif
+
 static void __init realview_eb_timer_init(void)
 {
        unsigned int timer_irq;
@@ -392,15 +409,13 @@ static void __init realview_eb_timer_init(void)
        timer2_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE);
        timer3_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE) + 0x20;
 
-       if (core_tile_eb11mp() || core_tile_a9mp()) {
-#ifdef CONFIG_LOCAL_TIMERS
-               twd_base = __io_address(REALVIEW_EB11MP_TWD_BASE);
-#endif
+       if (core_tile_eb11mp() || core_tile_a9mp())
                timer_irq = IRQ_EB11MP_TIMER0_1;
-       else
+       else
                timer_irq = IRQ_EB_TIMER0_1;
 
        realview_timer_init(timer_irq);
+       realview_eb_twd_init();
 }
 
 static struct sys_timer realview_eb_timer = {
index ae7fe54f6eb635ce3312423d77a5f9c6bc7b1186..a98c536e3327afa9823a2b29ffd081258be2ae5a 100644 (file)
@@ -36,7 +36,7 @@
 #include <asm/pgtable.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/cache-l2x0.h>
-#include <asm/localtimer.h>
+#include <asm/smp_twd.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
@@ -290,6 +290,21 @@ static void __init gic_init_irq(void)
        gic_cascade_irq(1, IRQ_TC11MP_PB_IRQ1);
 }
 
+#ifdef CONFIG_HAVE_ARM_TWD
+static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
+                             REALVIEW_TC11MP_TWD_BASE,
+                             IRQ_LOCALTIMER);
+
+static void __init realview_pb11mp_twd_init(void)
+{
+       int err = twd_local_timer_register(&twd_local_timer);
+       if (err)
+               pr_err("twd_local_timer_register failed %d\n", err);
+}
+#else
+#define realview_pb11mp_twd_init()     do {} while(0)
+#endif
+
 static void __init realview_pb11mp_timer_init(void)
 {
        timer0_va_base = __io_address(REALVIEW_PB11MP_TIMER0_1_BASE);
@@ -297,10 +312,8 @@ static void __init realview_pb11mp_timer_init(void)
        timer2_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE);
        timer3_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE) + 0x20;
 
-#ifdef CONFIG_LOCAL_TIMERS
-       twd_base = __io_address(REALVIEW_TC11MP_TWD_BASE);
-#endif
        realview_timer_init(IRQ_TC11MP_TIMER0_1);
+       realview_pb11mp_twd_init();
 }
 
 static struct sys_timer realview_pb11mp_timer = {
index 1cd9956f58751f81c004895d352951b237422574..3f2f605624e95270fd1039e64a3a0a2d2180cd06 100644 (file)
@@ -298,6 +298,21 @@ static void __init gic_init_irq(void)
        }
 }
 
+#ifdef CONFIG_HAVE_ARM_TWD
+static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
+                             REALVIEW_PBX_TILE_TWD_BASE,
+                             IRQ_LOCALTIMER);
+
+static void __init realview_pbx_twd_init(void)
+{
+       int err = twd_local_timer_register(&twd_local_timer);
+       if (err)
+               pr_err("twd_local_timer_register failed %d\n", err);
+}
+#else
+#define realview_pbx_twd_init()        do { } while(0)
+#endif
+
 static void __init realview_pbx_timer_init(void)
 {
        timer0_va_base = __io_address(REALVIEW_PBX_TIMER0_1_BASE);
@@ -305,11 +320,8 @@ static void __init realview_pbx_timer_init(void)
        timer2_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE);
        timer3_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE) + 0x20;
 
-#ifdef CONFIG_LOCAL_TIMERS
-       if (core_tile_pbx11mp() || core_tile_pbxa9mp())
-               twd_base = __io_address(REALVIEW_PBX_TILE_TWD_BASE);
-#endif
        realview_timer_init(IRQ_PBX_TIMER0_1);
+       realview_pbx_twd_init();
 }
 
 static struct sys_timer realview_pbx_timer = {
index dfa405c0cfde10b356579c8fec842d76c98a301d..992e28b4ae9a54ddab9ea92b2d0c92d6b303964e 100644 (file)
@@ -4,7 +4,7 @@
 
 # Object file lists.
 
-obj-y                  := dma.o fiq.o irq.o riscpc.o
+obj-y                  := dma.o ecard.o fiq.o irq.o riscpc.o time.o
 obj-m                  :=
 obj-n                  :=
 obj-                   :=
diff --git a/arch/arm/mach-rpc/ecard.c b/arch/arm/mach-rpc/ecard.c
new file mode 100644 (file)
index 0000000..b91bc87
--- /dev/null
@@ -0,0 +1,1138 @@
+/*
+ *  linux/arch/arm/kernel/ecard.c
+ *
+ *  Copyright 1995-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Find all installed expansion cards, and handle interrupts from them.
+ *
+ *  Created from information from Acorns RiscOS3 PRMs
+ *
+ *  08-Dec-1996        RMK     Added code for the 9'th expansion card - the ether
+ *                     podule slot.
+ *  06-May-1997        RMK     Added blacklist for cards whose loader doesn't work.
+ *  12-Sep-1997        RMK     Created new handling of interrupt enables/disables
+ *                     - cards can now register their own routine to control
+ *                     interrupts (recommended).
+ *  29-Sep-1997        RMK     Expansion card interrupt hardware not being re-enabled
+ *                     on reset from Linux. (Caused cards not to respond
+ *                     under RiscOS without hard reset).
+ *  15-Feb-1998        RMK     Added DMA support
+ *  12-Sep-1998        RMK     Added EASI support
+ *  10-Jan-1999        RMK     Run loaders in a simulated RISC OS environment.
+ *  17-Apr-1999        RMK     Support for EASI Type C cycles.
+ */
+#define ECARD_C
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <linux/reboot.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/kthread.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/dma.h>
+#include <asm/ecard.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mmu_context.h>
+#include <asm/mach/irq.h>
+#include <asm/tlbflush.h>
+
+#include "ecard.h"
+
+struct ecard_request {
+       void            (*fn)(struct ecard_request *);
+       ecard_t         *ec;
+       unsigned int    address;
+       unsigned int    length;
+       unsigned int    use_loader;
+       void            *buffer;
+       struct completion *complete;
+};
+
+struct expcard_blacklist {
+       unsigned short   manufacturer;
+       unsigned short   product;
+       const char      *type;
+};
+
+static ecard_t *cards;
+static ecard_t *slot_to_expcard[MAX_ECARDS];
+static unsigned int ectcr;
+
+/* List of descriptions of cards which don't have an extended
+ * identification, or chunk directories containing a description.
+ */
+static struct expcard_blacklist __initdata blacklist[] = {
+       { MANU_ACORN, PROD_ACORN_ETHER1, "Acorn Ether1" }
+};
+
+asmlinkage extern int
+ecard_loader_reset(unsigned long base, loader_t loader);
+asmlinkage extern int
+ecard_loader_read(int off, unsigned long base, loader_t loader);
+
+static inline unsigned short ecard_getu16(unsigned char *v)
+{
+       return v[0] | v[1] << 8;
+}
+
+static inline signed long ecard_gets24(unsigned char *v)
+{
+       return v[0] | v[1] << 8 | v[2] << 16 | ((v[2] & 0x80) ? 0xff000000 : 0);
+}
+
+static inline ecard_t *slot_to_ecard(unsigned int slot)
+{
+       return slot < MAX_ECARDS ? slot_to_expcard[slot] : NULL;
+}
+
+/* ===================== Expansion card daemon ======================== */
+/*
+ * Since the loader programs on the expansion cards need to be run
+ * in a specific environment, create a separate task with this
+ * environment up, and pass requests to this task as and when we
+ * need to.
+ *
+ * This should allow 99% of loaders to be called from Linux.
+ *
+ * From a security standpoint, we trust the card vendors.  This
+ * may be a misplaced trust.
+ */
+static void ecard_task_reset(struct ecard_request *req)
+{
+       struct expansion_card *ec = req->ec;
+       struct resource *res;
+
+       res = ec->slot_no == 8
+               ? &ec->resource[ECARD_RES_MEMC]
+               : ec->easi
+                 ? &ec->resource[ECARD_RES_EASI]
+                 : &ec->resource[ECARD_RES_IOCSYNC];
+
+       ecard_loader_reset(res->start, ec->loader);
+}
+
+static void ecard_task_readbytes(struct ecard_request *req)
+{
+       struct expansion_card *ec = req->ec;
+       unsigned char *buf = req->buffer;
+       unsigned int len = req->length;
+       unsigned int off = req->address;
+
+       if (ec->slot_no == 8) {
+               void __iomem *base = (void __iomem *)
+                               ec->resource[ECARD_RES_MEMC].start;
+
+               /*
+                * The card maintains an index which increments the address
+                * into a 4096-byte page on each access.  We need to keep
+                * track of the counter.
+                */
+               static unsigned int index;
+               unsigned int page;
+
+               page = (off >> 12) * 4;
+               if (page > 256 * 4)
+                       return;
+
+               off &= 4095;
+
+               /*
+                * If we are reading offset 0, or our current index is
+                * greater than the offset, reset the hardware index counter.
+                */
+               if (off == 0 || index > off) {
+                       writeb(0, base);
+                       index = 0;
+               }
+
+               /*
+                * Increment the hardware index counter until we get to the
+                * required offset.  The read bytes are discarded.
+                */
+               while (index < off) {
+                       readb(base + page);
+                       index += 1;
+               }
+
+               while (len--) {
+                       *buf++ = readb(base + page);
+                       index += 1;
+               }
+       } else {
+               unsigned long base = (ec->easi
+                        ? &ec->resource[ECARD_RES_EASI]
+                        : &ec->resource[ECARD_RES_IOCSYNC])->start;
+               void __iomem *pbase = (void __iomem *)base;
+
+               if (!req->use_loader || !ec->loader) {
+                       off *= 4;
+                       while (len--) {
+                               *buf++ = readb(pbase + off);
+                               off += 4;
+                       }
+               } else {
+                       while(len--) {
+                               /*
+                                * The following is required by some
+                                * expansion card loader programs.
+                                */
+                               *(unsigned long *)0x108 = 0;
+                               *buf++ = ecard_loader_read(off++, base,
+                                                          ec->loader);
+                       }
+               }
+       }
+
+}
+
+static DECLARE_WAIT_QUEUE_HEAD(ecard_wait);
+static struct ecard_request *ecard_req;
+static DEFINE_MUTEX(ecard_mutex);
+
+/*
+ * Set up the expansion card daemon's page tables.
+ */
+static void ecard_init_pgtables(struct mm_struct *mm)
+{
+       struct vm_area_struct vma;
+
+       /* We want to set up the page tables for the following mapping:
+        *  Virtual     Physical
+        *  0x03000000  0x03000000
+        *  0x03010000  unmapped
+        *  0x03210000  0x03210000
+        *  0x03400000  unmapped
+        *  0x08000000  0x08000000
+        *  0x10000000  unmapped
+        *
+        * FIXME: we don't follow this 100% yet.
+        */
+       pgd_t *src_pgd, *dst_pgd;
+
+       src_pgd = pgd_offset(mm, (unsigned long)IO_BASE);
+       dst_pgd = pgd_offset(mm, IO_START);
+
+       memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (IO_SIZE / PGDIR_SIZE));
+
+       src_pgd = pgd_offset(mm, (unsigned long)EASI_BASE);
+       dst_pgd = pgd_offset(mm, EASI_START);
+
+       memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (EASI_SIZE / PGDIR_SIZE));
+
+       vma.vm_flags = VM_EXEC;
+       vma.vm_mm = mm;
+
+       flush_tlb_range(&vma, IO_START, IO_START + IO_SIZE);
+       flush_tlb_range(&vma, EASI_START, EASI_START + EASI_SIZE);
+}
+
+static int ecard_init_mm(void)
+{
+       struct mm_struct * mm = mm_alloc();
+       struct mm_struct *active_mm = current->active_mm;
+
+       if (!mm)
+               return -ENOMEM;
+
+       current->mm = mm;
+       current->active_mm = mm;
+       activate_mm(active_mm, mm);
+       mmdrop(active_mm);
+       ecard_init_pgtables(mm);
+       return 0;
+}
+
+static int
+ecard_task(void * unused)
+{
+       /*
+        * Allocate a mm.  We're not a lazy-TLB kernel task since we need
+        * to set page table entries where the user space would be.  Note
+        * that this also creates the page tables.  Failure is not an
+        * option here.
+        */
+       if (ecard_init_mm())
+               panic("kecardd: unable to alloc mm\n");
+
+       while (1) {
+               struct ecard_request *req;
+
+               wait_event_interruptible(ecard_wait, ecard_req != NULL);
+
+               req = xchg(&ecard_req, NULL);
+               if (req != NULL) {
+                       req->fn(req);
+                       complete(req->complete);
+               }
+       }
+}
+
+/*
+ * Wake the expansion card daemon to action our request.
+ *
+ * FIXME: The test here is not sufficient to detect if the
+ * kcardd is running.
+ */
+static void ecard_call(struct ecard_request *req)
+{
+       DECLARE_COMPLETION_ONSTACK(completion);
+
+       req->complete = &completion;
+
+       mutex_lock(&ecard_mutex);
+       ecard_req = req;
+       wake_up(&ecard_wait);
+
+       /*
+        * Now wait for kecardd to run.
+        */
+       wait_for_completion(&completion);
+       mutex_unlock(&ecard_mutex);
+}
+
+/* ======================= Mid-level card control ===================== */
+
+static void
+ecard_readbytes(void *addr, ecard_t *ec, int off, int len, int useld)
+{
+       struct ecard_request req;
+
+       req.fn          = ecard_task_readbytes;
+       req.ec          = ec;
+       req.address     = off;
+       req.length      = len;
+       req.use_loader  = useld;
+       req.buffer      = addr;
+
+       ecard_call(&req);
+}
+
+int ecard_readchunk(struct in_chunk_dir *cd, ecard_t *ec, int id, int num)
+{
+       struct ex_chunk_dir excd;
+       int index = 16;
+       int useld = 0;
+
+       if (!ec->cid.cd)
+               return 0;
+
+       while(1) {
+               ecard_readbytes(&excd, ec, index, 8, useld);
+               index += 8;
+               if (c_id(&excd) == 0) {
+                       if (!useld && ec->loader) {
+                               useld = 1;
+                               index = 0;
+                               continue;
+                       }
+                       return 0;
+               }
+               if (c_id(&excd) == 0xf0) { /* link */
+                       index = c_start(&excd);
+                       continue;
+               }
+               if (c_id(&excd) == 0x80) { /* loader */
+                       if (!ec->loader) {
+                               ec->loader = kmalloc(c_len(&excd),
+                                                              GFP_KERNEL);
+                               if (ec->loader)
+                                       ecard_readbytes(ec->loader, ec,
+                                                       (int)c_start(&excd),
+                                                       c_len(&excd), useld);
+                               else
+                                       return 0;
+                       }
+                       continue;
+               }
+               if (c_id(&excd) == id && num-- == 0)
+                       break;
+       }
+
+       if (c_id(&excd) & 0x80) {
+               switch (c_id(&excd) & 0x70) {
+               case 0x70:
+                       ecard_readbytes((unsigned char *)excd.d.string, ec,
+                                       (int)c_start(&excd), c_len(&excd),
+                                       useld);
+                       break;
+               case 0x00:
+                       break;
+               }
+       }
+       cd->start_offset = c_start(&excd);
+       memcpy(cd->d.string, excd.d.string, 256);
+       return 1;
+}
+
+/* ======================= Interrupt control ============================ */
+
+static void ecard_def_irq_enable(ecard_t *ec, int irqnr)
+{
+}
+
+static void ecard_def_irq_disable(ecard_t *ec, int irqnr)
+{
+}
+
+static int ecard_def_irq_pending(ecard_t *ec)
+{
+       return !ec->irqmask || readb(ec->irqaddr) & ec->irqmask;
+}
+
+static void ecard_def_fiq_enable(ecard_t *ec, int fiqnr)
+{
+       panic("ecard_def_fiq_enable called - impossible");
+}
+
+static void ecard_def_fiq_disable(ecard_t *ec, int fiqnr)
+{
+       panic("ecard_def_fiq_disable called - impossible");
+}
+
+static int ecard_def_fiq_pending(ecard_t *ec)
+{
+       return !ec->fiqmask || readb(ec->fiqaddr) & ec->fiqmask;
+}
+
+static expansioncard_ops_t ecard_default_ops = {
+       ecard_def_irq_enable,
+       ecard_def_irq_disable,
+       ecard_def_irq_pending,
+       ecard_def_fiq_enable,
+       ecard_def_fiq_disable,
+       ecard_def_fiq_pending
+};
+
+/*
+ * Enable and disable interrupts from expansion cards.
+ * (interrupts are disabled for these functions).
+ *
+ * They are not meant to be called directly, but via enable/disable_irq.
+ */
+static void ecard_irq_unmask(struct irq_data *d)
+{
+       ecard_t *ec = irq_data_get_irq_chip_data(d);
+
+       if (ec) {
+               if (!ec->ops)
+                       ec->ops = &ecard_default_ops;
+
+               if (ec->claimed && ec->ops->irqenable)
+                       ec->ops->irqenable(ec, d->irq);
+               else
+                       printk(KERN_ERR "ecard: rejecting request to "
+                               "enable IRQs for %d\n", d->irq);
+       }
+}
+
+static void ecard_irq_mask(struct irq_data *d)
+{
+       ecard_t *ec = irq_data_get_irq_chip_data(d);
+
+       if (ec) {
+               if (!ec->ops)
+                       ec->ops = &ecard_default_ops;
+
+               if (ec->ops && ec->ops->irqdisable)
+                       ec->ops->irqdisable(ec, d->irq);
+       }
+}
+
+static struct irq_chip ecard_chip = {
+       .name           = "ECARD",
+       .irq_ack        = ecard_irq_mask,
+       .irq_mask       = ecard_irq_mask,
+       .irq_unmask     = ecard_irq_unmask,
+};
+
+void ecard_enablefiq(unsigned int fiqnr)
+{
+       ecard_t *ec = slot_to_ecard(fiqnr);
+
+       if (ec) {
+               if (!ec->ops)
+                       ec->ops = &ecard_default_ops;
+
+               if (ec->claimed && ec->ops->fiqenable)
+                       ec->ops->fiqenable(ec, fiqnr);
+               else
+                       printk(KERN_ERR "ecard: rejecting request to "
+                               "enable FIQs for %d\n", fiqnr);
+       }
+}
+
+void ecard_disablefiq(unsigned int fiqnr)
+{
+       ecard_t *ec = slot_to_ecard(fiqnr);
+
+       if (ec) {
+               if (!ec->ops)
+                       ec->ops = &ecard_default_ops;
+
+               if (ec->ops->fiqdisable)
+                       ec->ops->fiqdisable(ec, fiqnr);
+       }
+}
+
+static void ecard_dump_irq_state(void)
+{
+       ecard_t *ec;
+
+       printk("Expansion card IRQ state:\n");
+
+       for (ec = cards; ec; ec = ec->next) {
+               if (ec->slot_no == 8)
+                       continue;
+
+               printk("  %d: %sclaimed, ",
+                      ec->slot_no, ec->claimed ? "" : "not ");
+
+               if (ec->ops && ec->ops->irqpending &&
+                   ec->ops != &ecard_default_ops)
+                       printk("irq %spending\n",
+                              ec->ops->irqpending(ec) ? "" : "not ");
+               else
+                       printk("irqaddr %p, mask = %02X, status = %02X\n",
+                              ec->irqaddr, ec->irqmask, readb(ec->irqaddr));
+       }
+}
+
+static void ecard_check_lockup(struct irq_desc *desc)
+{
+       static unsigned long last;
+       static int lockup;
+
+       /*
+        * If the timer interrupt has not run since the last million
+        * unrecognised expansion card interrupts, then there is
+        * something seriously wrong.  Disable the expansion card
+        * interrupts so at least we can continue.
+        *
+        * Maybe we ought to start a timer to re-enable them some time
+        * later?
+        */
+       if (last == jiffies) {
+               lockup += 1;
+               if (lockup > 1000000) {
+                       printk(KERN_ERR "\nInterrupt lockup detected - "
+                              "disabling all expansion card interrupts\n");
+
+                       desc->irq_data.chip->irq_mask(&desc->irq_data);
+                       ecard_dump_irq_state();
+               }
+       } else
+               lockup = 0;
+
+       /*
+        * If we did not recognise the source of this interrupt,
+        * warn the user, but don't flood the user with these messages.
+        */
+       if (!last || time_after(jiffies, last + 5*HZ)) {
+               last = jiffies;
+               printk(KERN_WARNING "Unrecognised interrupt from backplane\n");
+               ecard_dump_irq_state();
+       }
+}
+
+static void
+ecard_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+       ecard_t *ec;
+       int called = 0;
+
+       desc->irq_data.chip->irq_mask(&desc->irq_data);
+       for (ec = cards; ec; ec = ec->next) {
+               int pending;
+
+               if (!ec->claimed || !ec->irq || ec->slot_no == 8)
+                       continue;
+
+               if (ec->ops && ec->ops->irqpending)
+                       pending = ec->ops->irqpending(ec);
+               else
+                       pending = ecard_default_ops.irqpending(ec);
+
+               if (pending) {
+                       generic_handle_irq(ec->irq);
+                       called ++;
+               }
+       }
+       desc->irq_data.chip->irq_unmask(&desc->irq_data);
+
+       if (called == 0)
+               ecard_check_lockup(desc);
+}
+
+static void __iomem *__ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
+{
+       void __iomem *address = NULL;
+       int slot = ec->slot_no;
+
+       if (ec->slot_no == 8)
+               return ECARD_MEMC8_BASE;
+
+       ectcr &= ~(1 << slot);
+
+       switch (type) {
+       case ECARD_MEMC:
+               if (slot < 4)
+                       address = ECARD_MEMC_BASE + (slot << 14);
+               break;
+
+       case ECARD_IOC:
+               if (slot < 4)
+                       address = ECARD_IOC_BASE + (slot << 14);
+               else
+                       address = ECARD_IOC4_BASE + ((slot - 4) << 14);
+               if (address)
+                       address += speed << 19;
+               break;
+
+       case ECARD_EASI:
+               address = ECARD_EASI_BASE + (slot << 24);
+               if (speed == ECARD_FAST)
+                       ectcr |= 1 << slot;
+               break;
+
+       default:
+               break;
+       }
+
+#ifdef IOMD_ECTCR
+       iomd_writeb(ectcr, IOMD_ECTCR);
+#endif
+       return address;
+}
+
+static int ecard_prints(struct seq_file *m, ecard_t *ec)
+{
+       seq_printf(m, "  %d: %s ", ec->slot_no, ec->easi ? "EASI" : "    ");
+
+       if (ec->cid.id == 0) {
+               struct in_chunk_dir incd;
+
+               seq_printf(m, "[%04X:%04X] ",
+                       ec->cid.manufacturer, ec->cid.product);
+
+               if (!ec->card_desc && ec->cid.cd &&
+                   ecard_readchunk(&incd, ec, 0xf5, 0)) {
+                       ec->card_desc = kmalloc(strlen(incd.d.string)+1, GFP_KERNEL);
+
+                       if (ec->card_desc)
+                               strcpy((char *)ec->card_desc, incd.d.string);
+               }
+
+               seq_printf(m, "%s\n", ec->card_desc ? ec->card_desc : "*unknown*");
+       } else
+               seq_printf(m, "Simple card %d\n", ec->cid.id);
+
+       return 0;
+}
+
+static int ecard_devices_proc_show(struct seq_file *m, void *v)
+{
+       ecard_t *ec = cards;
+
+       while (ec) {
+               ecard_prints(m, ec);
+               ec = ec->next;
+       }
+       return 0;
+}
+
+static int ecard_devices_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, ecard_devices_proc_show, NULL);
+}
+
+static const struct file_operations bus_ecard_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = ecard_devices_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static struct proc_dir_entry *proc_bus_ecard_dir = NULL;
+
+static void ecard_proc_init(void)
+{
+       proc_bus_ecard_dir = proc_mkdir("bus/ecard", NULL);
+       proc_create("devices", 0, proc_bus_ecard_dir, &bus_ecard_proc_fops);
+}
+
+#define ec_set_resource(ec,nr,st,sz)                           \
+       do {                                                    \
+               (ec)->resource[nr].name = dev_name(&ec->dev);   \
+               (ec)->resource[nr].start = st;                  \
+               (ec)->resource[nr].end = (st) + (sz) - 1;       \
+               (ec)->resource[nr].flags = IORESOURCE_MEM;      \
+       } while (0)
+
+static void __init ecard_free_card(struct expansion_card *ec)
+{
+       int i;
+
+       for (i = 0; i < ECARD_NUM_RESOURCES; i++)
+               if (ec->resource[i].flags)
+                       release_resource(&ec->resource[i]);
+
+       kfree(ec);
+}
+
+static struct expansion_card *__init ecard_alloc_card(int type, int slot)
+{
+       struct expansion_card *ec;
+       unsigned long base;
+       int i;
+
+       ec = kzalloc(sizeof(ecard_t), GFP_KERNEL);
+       if (!ec) {
+               ec = ERR_PTR(-ENOMEM);
+               goto nomem;
+       }
+
+       ec->slot_no = slot;
+       ec->easi = type == ECARD_EASI;
+       ec->irq = 0;
+       ec->fiq = 0;
+       ec->dma = NO_DMA;
+       ec->ops = &ecard_default_ops;
+
+       dev_set_name(&ec->dev, "ecard%d", slot);
+       ec->dev.parent = NULL;
+       ec->dev.bus = &ecard_bus_type;
+       ec->dev.dma_mask = &ec->dma_mask;
+       ec->dma_mask = (u64)0xffffffff;
+       ec->dev.coherent_dma_mask = ec->dma_mask;
+
+       if (slot < 4) {
+               ec_set_resource(ec, ECARD_RES_MEMC,
+                               PODSLOT_MEMC_BASE + (slot << 14),
+                               PODSLOT_MEMC_SIZE);
+               base = PODSLOT_IOC0_BASE + (slot << 14);
+       } else
+               base = PODSLOT_IOC4_BASE + ((slot - 4) << 14);
+
+#ifdef CONFIG_ARCH_RPC
+       if (slot < 8) {
+               ec_set_resource(ec, ECARD_RES_EASI,
+                               PODSLOT_EASI_BASE + (slot << 24),
+                               PODSLOT_EASI_SIZE);
+       }
+
+       if (slot == 8) {
+               ec_set_resource(ec, ECARD_RES_MEMC, NETSLOT_BASE, NETSLOT_SIZE);
+       } else
+#endif
+
+       for (i = 0; i <= ECARD_RES_IOCSYNC - ECARD_RES_IOCSLOW; i++)
+               ec_set_resource(ec, i + ECARD_RES_IOCSLOW,
+                               base + (i << 19), PODSLOT_IOC_SIZE);
+
+       for (i = 0; i < ECARD_NUM_RESOURCES; i++) {
+               if (ec->resource[i].flags &&
+                   request_resource(&iomem_resource, &ec->resource[i])) {
+                       dev_err(&ec->dev, "resource(s) not available\n");
+                       ec->resource[i].end -= ec->resource[i].start;
+                       ec->resource[i].start = 0;
+                       ec->resource[i].flags = 0;
+               }
+       }
+
+ nomem:
+       return ec;
+}
+
+static ssize_t ecard_show_irq(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct expansion_card *ec = ECARD_DEV(dev);
+       return sprintf(buf, "%u\n", ec->irq);
+}
+
+static ssize_t ecard_show_dma(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct expansion_card *ec = ECARD_DEV(dev);
+       return sprintf(buf, "%u\n", ec->dma);
+}
+
+static ssize_t ecard_show_resources(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct expansion_card *ec = ECARD_DEV(dev);
+       char *str = buf;
+       int i;
+
+       for (i = 0; i < ECARD_NUM_RESOURCES; i++)
+               str += sprintf(str, "%08x %08x %08lx\n",
+                               ec->resource[i].start,
+                               ec->resource[i].end,
+                               ec->resource[i].flags);
+
+       return str - buf;
+}
+
+static ssize_t ecard_show_vendor(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct expansion_card *ec = ECARD_DEV(dev);
+       return sprintf(buf, "%u\n", ec->cid.manufacturer);
+}
+
+static ssize_t ecard_show_device(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct expansion_card *ec = ECARD_DEV(dev);
+       return sprintf(buf, "%u\n", ec->cid.product);
+}
+
+static ssize_t ecard_show_type(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct expansion_card *ec = ECARD_DEV(dev);
+       return sprintf(buf, "%s\n", ec->easi ? "EASI" : "IOC");
+}
+
+static struct device_attribute ecard_dev_attrs[] = {
+       __ATTR(device,   S_IRUGO, ecard_show_device,    NULL),
+       __ATTR(dma,      S_IRUGO, ecard_show_dma,       NULL),
+       __ATTR(irq,      S_IRUGO, ecard_show_irq,       NULL),
+       __ATTR(resource, S_IRUGO, ecard_show_resources, NULL),
+       __ATTR(type,     S_IRUGO, ecard_show_type,      NULL),
+       __ATTR(vendor,   S_IRUGO, ecard_show_vendor,    NULL),
+       __ATTR_NULL,
+};
+
+
+int ecard_request_resources(struct expansion_card *ec)
+{
+       int i, err = 0;
+
+       for (i = 0; i < ECARD_NUM_RESOURCES; i++) {
+               if (ecard_resource_end(ec, i) &&
+                   !request_mem_region(ecard_resource_start(ec, i),
+                                       ecard_resource_len(ec, i),
+                                       ec->dev.driver->name)) {
+                       err = -EBUSY;
+                       break;
+               }
+       }
+
+       if (err) {
+               while (i--)
+                       if (ecard_resource_end(ec, i))
+                               release_mem_region(ecard_resource_start(ec, i),
+                                                  ecard_resource_len(ec, i));
+       }
+       return err;
+}
+EXPORT_SYMBOL(ecard_request_resources);
+
+void ecard_release_resources(struct expansion_card *ec)
+{
+       int i;
+
+       for (i = 0; i < ECARD_NUM_RESOURCES; i++)
+               if (ecard_resource_end(ec, i))
+                       release_mem_region(ecard_resource_start(ec, i),
+                                          ecard_resource_len(ec, i));
+}
+EXPORT_SYMBOL(ecard_release_resources);
+
+void ecard_setirq(struct expansion_card *ec, const struct expansion_card_ops *ops, void *irq_data)
+{
+       ec->irq_data = irq_data;
+       barrier();
+       ec->ops = ops;
+}
+EXPORT_SYMBOL(ecard_setirq);
+
+void __iomem *ecardm_iomap(struct expansion_card *ec, unsigned int res,
+                          unsigned long offset, unsigned long maxsize)
+{
+       unsigned long start = ecard_resource_start(ec, res);
+       unsigned long end = ecard_resource_end(ec, res);
+
+       if (offset > (end - start))
+               return NULL;
+
+       start += offset;
+       if (maxsize && end - start > maxsize)
+               end = start + maxsize;
+       
+       return devm_ioremap(&ec->dev, start, end - start);
+}
+EXPORT_SYMBOL(ecardm_iomap);
+
+/*
+ * Probe for an expansion card.
+ *
+ * If bit 1 of the first byte of the card is set, then the
+ * card does not exist.
+ */
+static int __init ecard_probe(int slot, unsigned irq, card_type_t type)
+{
+       ecard_t **ecp;
+       ecard_t *ec;
+       struct ex_ecid cid;
+       void __iomem *addr;
+       int i, rc;
+
+       ec = ecard_alloc_card(type, slot);
+       if (IS_ERR(ec)) {
+               rc = PTR_ERR(ec);
+               goto nomem;
+       }
+
+       rc = -ENODEV;
+       if ((addr = __ecard_address(ec, type, ECARD_SYNC)) == NULL)
+               goto nodev;
+
+       cid.r_zero = 1;
+       ecard_readbytes(&cid, ec, 0, 16, 0);
+       if (cid.r_zero)
+               goto nodev;
+
+       ec->cid.id      = cid.r_id;
+       ec->cid.cd      = cid.r_cd;
+       ec->cid.is      = cid.r_is;
+       ec->cid.w       = cid.r_w;
+       ec->cid.manufacturer = ecard_getu16(cid.r_manu);
+       ec->cid.product = ecard_getu16(cid.r_prod);
+       ec->cid.country = cid.r_country;
+       ec->cid.irqmask = cid.r_irqmask;
+       ec->cid.irqoff  = ecard_gets24(cid.r_irqoff);
+       ec->cid.fiqmask = cid.r_fiqmask;
+       ec->cid.fiqoff  = ecard_gets24(cid.r_fiqoff);
+       ec->fiqaddr     =
+       ec->irqaddr     = addr;
+
+       if (ec->cid.is) {
+               ec->irqmask = ec->cid.irqmask;
+               ec->irqaddr += ec->cid.irqoff;
+               ec->fiqmask = ec->cid.fiqmask;
+               ec->fiqaddr += ec->cid.fiqoff;
+       } else {
+               ec->irqmask = 1;
+               ec->fiqmask = 4;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(blacklist); i++)
+               if (blacklist[i].manufacturer == ec->cid.manufacturer &&
+                   blacklist[i].product == ec->cid.product) {
+                       ec->card_desc = blacklist[i].type;
+                       break;
+               }
+
+       ec->irq = irq;
+
+       /*
+        * hook the interrupt handlers
+        */
+       if (slot < 8) {
+               irq_set_chip_and_handler(ec->irq, &ecard_chip,
+                                        handle_level_irq);
+               irq_set_chip_data(ec->irq, ec);
+               set_irq_flags(ec->irq, IRQF_VALID);
+       }
+
+#ifdef CONFIG_ARCH_RPC
+       /* On RiscPC, only first two slots have DMA capability */
+       if (slot < 2)
+               ec->dma = 2 + slot;
+#endif
+
+       for (ecp = &cards; *ecp; ecp = &(*ecp)->next);
+
+       *ecp = ec;
+       slot_to_expcard[slot] = ec;
+
+       device_register(&ec->dev);
+
+       return 0;
+
+ nodev:
+       ecard_free_card(ec);
+ nomem:
+       return rc;
+}
+
+/*
+ * Initialise the expansion card system.
+ * Locate all hardware - interrupt management and
+ * actual cards.
+ */
+static int __init ecard_init(void)
+{
+       struct task_struct *task;
+       int slot, irqbase;
+
+       irqbase = irq_alloc_descs(-1, 0, 8, -1);
+       if (irqbase < 0)
+               return irqbase;
+
+       task = kthread_run(ecard_task, NULL, "kecardd");
+       if (IS_ERR(task)) {
+               printk(KERN_ERR "Ecard: unable to create kernel thread: %ld\n",
+                      PTR_ERR(task));
+               irq_free_descs(irqbase, 8);
+               return PTR_ERR(task);
+       }
+
+       printk("Probing expansion cards\n");
+
+       for (slot = 0; slot < 8; slot ++) {
+               if (ecard_probe(slot, irqbase + slot, ECARD_EASI) == -ENODEV)
+                       ecard_probe(slot, irqbase + slot, ECARD_IOC);
+       }
+
+       ecard_probe(8, 11, ECARD_IOC);
+
+       irq_set_chained_handler(IRQ_EXPANSIONCARD, ecard_irq_handler);
+
+       ecard_proc_init();
+
+       return 0;
+}
+
+subsys_initcall(ecard_init);
+
+/*
+ *     ECARD "bus"
+ */
+static const struct ecard_id *
+ecard_match_device(const struct ecard_id *ids, struct expansion_card *ec)
+{
+       int i;
+
+       for (i = 0; ids[i].manufacturer != 65535; i++)
+               if (ec->cid.manufacturer == ids[i].manufacturer &&
+                   ec->cid.product == ids[i].product)
+                       return ids + i;
+
+       return NULL;
+}
+
+static int ecard_drv_probe(struct device *dev)
+{
+       struct expansion_card *ec = ECARD_DEV(dev);
+       struct ecard_driver *drv = ECARD_DRV(dev->driver);
+       const struct ecard_id *id;
+       int ret;
+
+       id = ecard_match_device(drv->id_table, ec);
+
+       ec->claimed = 1;
+       ret = drv->probe(ec, id);
+       if (ret)
+               ec->claimed = 0;
+       return ret;
+}
+
+static int ecard_drv_remove(struct device *dev)
+{
+       struct expansion_card *ec = ECARD_DEV(dev);
+       struct ecard_driver *drv = ECARD_DRV(dev->driver);
+
+       drv->remove(ec);
+       ec->claimed = 0;
+
+       /*
+        * Restore the default operations.  We ensure that the
+        * ops are set before we change the data.
+        */
+       ec->ops = &ecard_default_ops;
+       barrier();
+       ec->irq_data = NULL;
+
+       return 0;
+}
+
+/*
+ * Before rebooting, we must make sure that the expansion card is in a
+ * sensible state, so it can be re-detected.  This means that the first
+ * page of the ROM must be visible.  We call the expansion cards reset
+ * handler, if any.
+ */
+static void ecard_drv_shutdown(struct device *dev)
+{
+       struct expansion_card *ec = ECARD_DEV(dev);
+       struct ecard_driver *drv = ECARD_DRV(dev->driver);
+       struct ecard_request req;
+
+       if (dev->driver) {
+               if (drv->shutdown)
+                       drv->shutdown(ec);
+               ec->claimed = 0;
+       }
+
+       /*
+        * If this card has a loader, call the reset handler.
+        */
+       if (ec->loader) {
+               req.fn = ecard_task_reset;
+               req.ec = ec;
+               ecard_call(&req);
+       }
+}
+
+int ecard_register_driver(struct ecard_driver *drv)
+{
+       drv->drv.bus = &ecard_bus_type;
+
+       return driver_register(&drv->drv);
+}
+
+void ecard_remove_driver(struct ecard_driver *drv)
+{
+       driver_unregister(&drv->drv);
+}
+
+static int ecard_match(struct device *_dev, struct device_driver *_drv)
+{
+       struct expansion_card *ec = ECARD_DEV(_dev);
+       struct ecard_driver *drv = ECARD_DRV(_drv);
+       int ret;
+
+       if (drv->id_table) {
+               ret = ecard_match_device(drv->id_table, ec) != NULL;
+       } else {
+               ret = ec->cid.id == drv->id;
+       }
+
+       return ret;
+}
+
+struct bus_type ecard_bus_type = {
+       .name           = "ecard",
+       .dev_attrs      = ecard_dev_attrs,
+       .match          = ecard_match,
+       .probe          = ecard_drv_probe,
+       .remove         = ecard_drv_remove,
+       .shutdown       = ecard_drv_shutdown,
+};
+
+static int ecard_bus_init(void)
+{
+       return bus_register(&ecard_bus_type);
+}
+
+postcore_initcall(ecard_bus_init);
+
+EXPORT_SYMBOL(ecard_readchunk);
+EXPORT_SYMBOL(ecard_register_driver);
+EXPORT_SYMBOL(ecard_remove_driver);
+EXPORT_SYMBOL(ecard_bus_type);
diff --git a/arch/arm/mach-rpc/ecard.h b/arch/arm/mach-rpc/ecard.h
new file mode 100644 (file)
index 0000000..4642d43
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ *  ecard.h
+ *
+ *  Copyright 2007 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* Definitions internal to ecard.c - for it's use only!!
+ *
+ * External expansion card header as read from the card
+ */
+struct ex_ecid {
+       unsigned char   r_irq:1;
+       unsigned char   r_zero:1;
+       unsigned char   r_fiq:1;
+       unsigned char   r_id:4;
+       unsigned char   r_a:1;
+
+       unsigned char   r_cd:1;
+       unsigned char   r_is:1;
+       unsigned char   r_w:2;
+       unsigned char   r_r1:4;
+
+       unsigned char   r_r2:8;
+
+       unsigned char   r_prod[2];
+
+       unsigned char   r_manu[2];
+
+       unsigned char   r_country;
+
+       unsigned char   r_fiqmask;
+       unsigned char   r_fiqoff[3];
+
+       unsigned char   r_irqmask;
+       unsigned char   r_irqoff[3];
+};
+
+/*
+ * Chunk directory entry as read from the card
+ */
+struct ex_chunk_dir {
+       unsigned char r_id;
+       unsigned char r_len[3];
+       unsigned long r_start;
+       union {
+               char string[256];
+               char data[1];
+       } d;
+#define c_id(x)                ((x)->r_id)
+#define c_len(x)       ((x)->r_len[0]|((x)->r_len[1]<<8)|((x)->r_len[2]<<16))
+#define c_start(x)     ((x)->r_start)
+};
+
+typedef enum ecard_type {              /* Cards address space          */
+       ECARD_IOC,
+       ECARD_MEMC,
+       ECARD_EASI
+} card_type_t;
+
+typedef enum {                         /* Speed for ECARD_IOC space    */
+       ECARD_SLOW       = 0,
+       ECARD_MEDIUM     = 1,
+       ECARD_FAST       = 2,
+       ECARD_SYNC       = 3
+} card_speed_t;
index 3d2037496e38cd4955f29ecb9ca1f09e715e7608..6868e178274d93893983874e076730aa753e6f06 100644 (file)
@@ -42,6 +42,4 @@
  */
 #define FIQ_START              64
 
-#define IRQ_TIMER              IRQ_TIMER0
-
 #define NR_IRQS                        128
index 3d44a59fc0df38e10bcf492f987c274e17c5da1e..731552d68adfe76a5a8b2f2d1235c0a90c03c350 100644 (file)
@@ -98,15 +98,9 @@ static void __init rpc_map_io(void)
 }
 
 static struct resource acornfb_resources[] = {
-       {       /* VIDC */
-               .start          = 0x03400000,
-               .end            = 0x035fffff,
-               .flags          = IORESOURCE_MEM,
-       }, {
-               .start          = IRQ_VSYNCPULSE,
-               .end            = IRQ_VSYNCPULSE,
-               .flags          = IORESOURCE_IRQ,
-       },
+       /* VIDC */
+       DEFINE_RES_MEM(0x03400000, 0x00200000),
+       DEFINE_RES_IRQ(IRQ_VSYNCPULSE),
 };
 
 static struct platform_device acornfb_device = {
@@ -120,11 +114,7 @@ static struct platform_device acornfb_device = {
 };
 
 static struct resource iomd_resources[] = {
-       {
-               .start          = 0x03200000,
-               .end            = 0x0320ffff,
-               .flags          = IORESOURCE_MEM,
-       },
+       DEFINE_RES_MEM(0x03200000, 0x10000),
 };
 
 static struct platform_device iomd_device = {
@@ -134,18 +124,25 @@ static struct platform_device iomd_device = {
        .resource               = iomd_resources,
 };
 
+static struct resource iomd_kart_resources[] = {
+       DEFINE_RES_IRQ(IRQ_KEYBOARDRX),
+       DEFINE_RES_IRQ(IRQ_KEYBOARDTX),
+};
+
 static struct platform_device kbd_device = {
        .name                   = "kart",
        .id                     = -1,
        .dev                    = {
                .parent         = &iomd_device.dev,
        },
+       .num_resources          = ARRAY_SIZE(iomd_kart_resources),
+       .resource               = iomd_kart_resources,
 };
 
 static struct plat_serial8250_port serial_platform_data[] = {
        {
                .mapbase        = 0x03010fe0,
-               .irq            = 10,
+               .irq            = IRQ_SERIALPORT,
                .uartclk        = 1843200,
                .regshift       = 2,
                .iotype         = UPIO_MEM,
@@ -167,21 +164,9 @@ static struct pata_platform_info pata_platform_data = {
 };
 
 static struct resource pata_resources[] = {
-       [0] = {
-               .start          = 0x030107c0,
-               .end            = 0x030107df,
-               .flags          = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start          = 0x03010fd8,
-               .end            = 0x03010fdb,
-               .flags          = IORESOURCE_MEM,
-       },
-       [2] = {
-               .start          = IRQ_HARDDISK,
-               .end            = IRQ_HARDDISK,
-               .flags          = IORESOURCE_IRQ,
-       },
+       DEFINE_RES_MEM(0x030107c0, 0x20),
+       DEFINE_RES_MEM(0x03010fd8, 0x04),
+       DEFINE_RES_IRQ(IRQ_HARDDISK),
 };
 
 static struct platform_device pata_device = {
diff --git a/arch/arm/mach-rpc/time.c b/arch/arm/mach-rpc/time.c
new file mode 100644 (file)
index 0000000..581fca9
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ *  linux/arch/arm/common/time-acorn.c
+ *
+ *  Copyright (c) 1996-2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Changelog:
+ *   24-Sep-1996       RMK     Created
+ *   10-Oct-1996       RMK     Brought up to date with arch-sa110eval
+ *   04-Dec-1997       RMK     Updated for new arch/arm/time.c
+ *   13=Jun-2004       DS      Moved to arch/arm/common b/c shared w/CLPS7500
+ */
+#include <linux/timex.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/hardware/ioc.h>
+
+#include <asm/mach/time.h>
+
+unsigned long ioc_timer_gettimeoffset(void)
+{
+       unsigned int count1, count2, status;
+       long offset;
+
+       ioc_writeb (0, IOC_T0LATCH);
+       barrier ();
+       count1 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
+       barrier ();
+       status = ioc_readb(IOC_IRQREQA);
+       barrier ();
+       ioc_writeb (0, IOC_T0LATCH);
+       barrier ();
+       count2 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
+
+       offset = count2;
+       if (count2 < count1) {
+               /*
+                * We have not had an interrupt between reading count1
+                * and count2.
+                */
+               if (status & (1 << 5))
+                       offset -= LATCH;
+       } else if (count2 > count1) {
+               /*
+                * We have just had another interrupt between reading
+                * count1 and count2.
+                */
+               offset -= LATCH;
+       }
+
+       offset = (LATCH - offset) * (tick_nsec / 1000);
+       return (offset + LATCH/2) / LATCH;
+}
+
+void __init ioctime_init(void)
+{
+       ioc_writeb(LATCH & 255, IOC_T0LTCHL);
+       ioc_writeb(LATCH >> 8, IOC_T0LTCHH);
+       ioc_writeb(0, IOC_T0GO);
+}
+
+static irqreturn_t
+ioc_timer_interrupt(int irq, void *dev_id)
+{
+       timer_tick();
+       return IRQ_HANDLED;
+}
+
+static struct irqaction ioc_timer_irq = {
+       .name           = "timer",
+       .flags          = IRQF_DISABLED,
+       .handler        = ioc_timer_interrupt
+};
+
+/*
+ * Set up timer interrupt.
+ */
+static void __init ioc_timer_init(void)
+{
+       ioctime_init();
+       setup_irq(IRQ_TIMER0, &ioc_timer_irq);
+}
+
+struct sys_timer ioc_timer = {
+       .init           = ioc_timer_init,
+       .offset         = ioc_timer_gettimeoffset,
+};
+
index 5261a7ed09991fd9feba227432a851e22ec2bb59..68d89cb96af0281009d5b84fc26aaf85a61ddfad 100644 (file)
@@ -2,42 +2,6 @@
 #
 # Licensed under GPLv2
 
-config CPU_S3C2410
-       bool
-       depends on ARCH_S3C2410
-       select CPU_ARM920T
-       select S3C2410_CLOCK
-       select CPU_LLSERIAL_S3C2410
-       select S3C2410_PM if PM
-       select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX
-       help
-         Support for S3C2410 and S3C2410A family from the S3C24XX line
-         of Samsung Mobile CPUs.
-
-config CPU_S3C2410_DMA
-       bool
-       depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442)
-       default y if CPU_S3C2410 || CPU_S3C2442
-       help
-         DMA device selection for S3C2410 and compatible CPUs
-
-config S3C2410_PM
-       bool
-       help
-         Power Management code common to S3C2410 and better
-
-config SIMTEC_NOR
-       bool
-       help
-         Internal node to specify machine has simtec NOR mapping
-
-config MACH_BAST_IDE
-       bool
-       select HAVE_PATA_PLATFORM
-       help
-         Internal node for machines with an BAST style IDE
-         interface
-
 # cpu frequency scaling support
 
 config S3C2410_CPUFREQ
@@ -54,121 +18,3 @@ config S3C2410_PLLTABLE
        help
          Select the PLL table for the S3C2410
 
-menu "S3C2410 Machines"
-
-config ARCH_SMDK2410
-       bool "SMDK2410/A9M2410"
-       select CPU_S3C2410
-       select MACH_SMDK
-       help
-          Say Y here if you are using the SMDK2410 or the derived module A9M2410
-           <http://www.fsforth.de>
-
-config ARCH_H1940
-       bool "IPAQ H1940"
-       select CPU_S3C2410
-       select PM_H1940 if PM
-       select S3C_DEV_USB_HOST
-       select S3C_DEV_NAND
-       select S3C2410_SETUP_TS
-       help
-         Say Y here if you are using the HP IPAQ H1940
-
-config H1940BT
-        tristate "Control the state of H1940 bluetooth chip"
-        depends on ARCH_H1940
-        select RFKILL
-        help
-          This is a simple driver that is able to control
-          the state of built in bluetooth chip on h1940.
-
-config PM_H1940
-       bool
-       help
-         Internal node for H1940 and related PM
-
-config MACH_N30
-       bool "Acer N30 family"
-       select CPU_S3C2410
-       select MACH_N35
-       select S3C_DEV_USB_HOST
-       select S3C_DEV_NAND
-       help
-         Say Y here if you want suppt for the Acer N30, Acer N35,
-         Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs.
-
-config MACH_N35
-       bool
-       help
-         Internal node in order to enable support for Acer N35 if Acer N30 is
-         selected.
-
-config ARCH_BAST
-       bool "Simtec Electronics BAST (EB2410ITX)"
-       select CPU_S3C2410
-       select S3C2410_IOTIMING if S3C2410_CPUFREQ
-       select PM_SIMTEC if PM
-       select SIMTEC_NOR
-       select MACH_BAST_IDE
-       select S3C24XX_DCLK
-       select ISA
-       select S3C_DEV_HWMON
-       select S3C_DEV_USB_HOST
-       select S3C_DEV_NAND
-       help
-         Say Y here if you are using the Simtec Electronics EB2410ITX
-         development board (also known as BAST)
-
-config MACH_OTOM
-       bool "NexVision OTOM Board"
-       select CPU_S3C2410
-       select S3C_DEV_USB_HOST
-       select S3C_DEV_NAND
-       help
-         Say Y here if you are using the Nex Vision OTOM board
-
-config MACH_AML_M5900
-       bool "AML M5900 Series"
-       select CPU_S3C2410
-       select PM_SIMTEC if PM
-       select S3C_DEV_USB_HOST
-       help
-          Say Y here if you are using the American Microsystems M5900 Series
-           <http://www.amltd.com>
-
-config BAST_PC104_IRQ
-       bool "BAST PC104 IRQ support"
-       depends on ARCH_BAST
-       default y
-       help
-         Say Y here to enable the PC104 IRQ routing on the
-         Simtec BAST (EB2410ITX)
-
-config MACH_TCT_HAMMER
-       bool "TCT Hammer Board"
-       select CPU_S3C2410
-       select S3C_DEV_USB_HOST
-       help
-          Say Y here if you are using the TinCanTools Hammer Board
-           <http://www.tincantools.com>
-
-config MACH_VR1000
-       bool "Thorcom VR1000"
-       select PM_SIMTEC if PM
-       select S3C24XX_DCLK
-       select SIMTEC_NOR
-       select MACH_BAST_IDE
-       select CPU_S3C2410
-       select S3C_DEV_USB_HOST
-       help
-         Say Y here if you are using the Thorcom VR1000 board.
-
-config MACH_QT2410
-       bool "QT2410"
-       select CPU_S3C2410
-       select S3C_DEV_USB_HOST
-       select S3C_DEV_NAND
-       help
-          Say Y here if you are using the Armzone QT2410
-
-endmenu
index 782fd81144e99591096b80fab4b662ef3a8df02b..6b9a316e0041b9004c47ff4fb07a8972d9c790e2 100644 (file)
@@ -9,32 +9,6 @@ obj-m                          :=
 obj-n                          :=
 obj-                           :=
 
-obj-$(CONFIG_CPU_S3C2410)      += s3c2410.o
-obj-$(CONFIG_CPU_S3C2410_DMA)  += dma.o
-obj-$(CONFIG_CPU_S3C2410_DMA)  += dma.o
-obj-$(CONFIG_S3C2410_PM)       += pm.o sleep.o
 obj-$(CONFIG_S3C2410_CPUFREQ)  += cpu-freq.o
 obj-$(CONFIG_S3C2410_PLLTABLE) += pll.o
 
-# Machine support
-
-obj-$(CONFIG_ARCH_SMDK2410)    += mach-smdk2410.o
-obj-$(CONFIG_ARCH_H1940)       += mach-h1940.o
-obj-$(CONFIG_H1940BT)          += h1940-bluetooth.o
-obj-$(CONFIG_PM_H1940)         += pm-h1940.o
-obj-$(CONFIG_MACH_N30)         += mach-n30.o
-obj-$(CONFIG_ARCH_BAST)                += mach-bast.o usb-simtec.o
-obj-$(CONFIG_MACH_OTOM)                += mach-otom.o
-obj-$(CONFIG_MACH_AML_M5900)   += mach-amlm5900.o
-obj-$(CONFIG_BAST_PC104_IRQ)   += bast-irq.o
-obj-$(CONFIG_MACH_TCT_HAMMER)  += mach-tct_hammer.o
-obj-$(CONFIG_MACH_VR1000)      += mach-vr1000.o usb-simtec.o
-obj-$(CONFIG_MACH_QT2410)      += mach-qt2410.o
-
-# Common bits of machine support
-
-obj-$(CONFIG_SIMTEC_NOR)       += nor-simtec.o
-
-# machine additions
-
-obj-$(CONFIG_MACH_BAST_IDE)    += bast-ide.o
diff --git a/arch/arm/mach-s3c2410/Makefile.boot b/arch/arm/mach-s3c2410/Makefile.boot
deleted file mode 100644 (file)
index 4457605..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-ifeq ($(CONFIG_PM_H1940),y)
-       zreladdr-y      += 0x30108000
-       params_phys-y   := 0x30100100
-else
-       zreladdr-y      += 0x30008000
-       params_phys-y   := 0x30000100
-endif
diff --git a/arch/arm/mach-s3c2410/bast-ide.c b/arch/arm/mach-s3c2410/bast-ide.c
deleted file mode 100644 (file)
index 298ecec..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/bast-ide.c
- *
- * Copyright 2007 Simtec Electronics
- *     http://www.simtec.co.uk/products/EB2410ITX/
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-
-#include <linux/platform_device.h>
-#include <linux/ata_platform.h>
-
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/map.h>
-#include <mach/bast-map.h>
-#include <mach/bast-irq.h>
-
-/* IDE ports */
-
-static struct pata_platform_info bast_ide_platdata = {
-       .ioport_shift   = 5,
-};
-
-#define IDE_CS S3C2410_CS5
-
-static struct resource bast_ide0_resource[] = {
-       [0]     = {
-               .start  = IDE_CS + BAST_PA_IDEPRI,
-               .end    = IDE_CS + BAST_PA_IDEPRI + (8 * 0x20) - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1]     = {
-               .start  = IDE_CS + BAST_PA_IDEPRIAUX + (6 * 0x20) ,
-               .end    = IDE_CS + BAST_PA_IDEPRIAUX + (7 * 0x20) - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [2]     = {
-               .start  = IRQ_IDE0,
-               .end    = IRQ_IDE0,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device bast_device_ide0 = {
-       .name           = "pata_platform",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(bast_ide0_resource),
-       .resource       = bast_ide0_resource,
-       .dev            = {
-               .platform_data = &bast_ide_platdata,
-               .coherent_dma_mask = ~0,
-       }
-
-};
-
-static struct resource bast_ide1_resource[] = {
-       [0]     = {
-               .start  = IDE_CS + BAST_PA_IDESEC,
-               .end    = IDE_CS + BAST_PA_IDESEC + (8 * 0x20) - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1]     = {
-               .start  = IDE_CS + BAST_PA_IDESECAUX + (6 * 0x20),
-               .end    = IDE_CS + BAST_PA_IDESECAUX + (7 * 0x20) - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [2]     = {
-               .start  = IRQ_IDE1,
-               .end    = IRQ_IDE1,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device bast_device_ide1 = {
-       .name           = "pata_platform",
-       .id             = 1,
-       .num_resources  = ARRAY_SIZE(bast_ide1_resource),
-       .resource       = bast_ide1_resource,
-       .dev            = {
-               .platform_data = &bast_ide_platdata,
-               .coherent_dma_mask = ~0,
-       }
-};
-
-static struct platform_device *bast_ide_devices[] __initdata = {
-       &bast_device_ide0,
-       &bast_device_ide1,
-};
-
-static __init int bast_ide_init(void)
-{
-       if (machine_is_bast() || machine_is_vr1000())
-               return platform_add_devices(bast_ide_devices,
-                                           ARRAY_SIZE(bast_ide_devices));
-
-       return 0;
-}
-
-fs_initcall(bast_ide_init);
diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c
deleted file mode 100644 (file)
index ac7b2ad..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/bast-irq.c
- *
- * Copyright 2003-2005 Simtec Electronics
- *   Ben Dooks <ben@simtec.co.uk>
- *
- * http://www.simtec.co.uk/products/EB2410ITX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/io.h>
-
-#include <asm/mach-types.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <asm/mach/irq.h>
-
-#include <mach/regs-irq.h>
-#include <mach/bast-map.h>
-#include <mach/bast-irq.h>
-
-#include <plat/irq.h>
-
-#if 0
-#include <asm/debug-ll.h>
-#endif
-
-#define irqdbf(x...)
-#define irqdbf2(x...)
-
-
-/* handle PC104 ISA interrupts from the system CPLD */
-
-/* table of ISA irq nos to the relevant mask... zero means
- * the irq is not implemented
-*/
-static unsigned char bast_pc104_irqmasks[] = {
-       0,   /* 0 */
-       0,   /* 1 */
-       0,   /* 2 */
-       1,   /* 3 */
-       0,   /* 4 */
-       2,   /* 5 */
-       0,   /* 6 */
-       4,   /* 7 */
-       0,   /* 8 */
-       0,   /* 9 */
-       8,   /* 10 */
-       0,   /* 11 */
-       0,   /* 12 */
-       0,   /* 13 */
-       0,   /* 14 */
-       0,   /* 15 */
-};
-
-static unsigned char bast_pc104_irqs[] = { 3, 5, 7, 10 };
-
-static void
-bast_pc104_mask(struct irq_data *data)
-{
-       unsigned long temp;
-
-       temp = __raw_readb(BAST_VA_PC104_IRQMASK);
-       temp &= ~bast_pc104_irqmasks[data->irq];
-       __raw_writeb(temp, BAST_VA_PC104_IRQMASK);
-}
-
-static void
-bast_pc104_maskack(struct irq_data *data)
-{
-       struct irq_desc *desc = irq_desc + IRQ_ISA;
-
-       bast_pc104_mask(data);
-       desc->irq_data.chip->irq_ack(&desc->irq_data);
-}
-
-static void
-bast_pc104_unmask(struct irq_data *data)
-{
-       unsigned long temp;
-
-       temp = __raw_readb(BAST_VA_PC104_IRQMASK);
-       temp |= bast_pc104_irqmasks[data->irq];
-       __raw_writeb(temp, BAST_VA_PC104_IRQMASK);
-}
-
-static struct irq_chip  bast_pc104_chip = {
-       .irq_mask       = bast_pc104_mask,
-       .irq_unmask     = bast_pc104_unmask,
-       .irq_ack        = bast_pc104_maskack
-};
-
-static void
-bast_irq_pc104_demux(unsigned int irq,
-                    struct irq_desc *desc)
-{
-       unsigned int stat;
-       unsigned int irqno;
-       int i;
-
-       stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf;
-
-       if (unlikely(stat == 0)) {
-               /* ack if we get an irq with nothing (ie, startup) */
-
-               desc = irq_desc + IRQ_ISA;
-               desc->irq_data.chip->irq_ack(&desc->irq_data);
-       } else {
-               /* handle the IRQ */
-
-               for (i = 0; stat != 0; i++, stat >>= 1) {
-                       if (stat & 1) {
-                               irqno = bast_pc104_irqs[i];
-                               generic_handle_irq(irqno);
-                       }
-               }
-       }
-}
-
-static __init int bast_irq_init(void)
-{
-       unsigned int i;
-
-       if (machine_is_bast()) {
-               printk(KERN_INFO "BAST PC104 IRQ routing, Copyright 2005 Simtec Electronics\n");
-
-               /* zap all the IRQs */
-
-               __raw_writeb(0x0, BAST_VA_PC104_IRQMASK);
-
-               irq_set_chained_handler(IRQ_ISA, bast_irq_pc104_demux);
-
-               /* register our IRQs */
-
-               for (i = 0; i < 4; i++) {
-                       unsigned int irqno = bast_pc104_irqs[i];
-
-                       irq_set_chip_and_handler(irqno, &bast_pc104_chip,
-                                                handle_level_irq);
-                       set_irq_flags(irqno, IRQF_VALID);
-               }
-       }
-
-       return 0;
-}
-
-arch_initcall(bast_irq_init);
diff --git a/arch/arm/mach-s3c2410/common.h b/arch/arm/mach-s3c2410/common.h
deleted file mode 100644 (file)
index f65dc80..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Common Header for S3C2410 machines
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ARCH_ARM_MACH_S3C2410_COMMON_H
-#define __ARCH_ARM_MACH_S3C2410_COMMON_H
-
-void s3c2410_restart(char mode, const char *cmd);
-
-#endif /* __ARCH_ARM_MACH_S3C2410_COMMON_H */
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
deleted file mode 100644 (file)
index 4803338..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/dma.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 DMA selection
- *
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/serial_core.h>
-
-#include <mach/map.h>
-#include <mach/dma.h>
-
-#include <plat/cpu.h>
-#include <plat/dma-s3c24xx.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <plat/regs-ac97.h>
-#include <plat/regs-dma.h>
-#include <mach/regs-mem.h>
-#include <mach/regs-lcd.h>
-#include <mach/regs-sdi.h>
-#include <plat/regs-iis.h>
-#include <plat/regs-spi.h>
-
-static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
-       [DMACH_XD0] = {
-               .name           = "xdreq0",
-               .channels[0]    = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
-       },
-       [DMACH_XD1] = {
-               .name           = "xdreq1",
-               .channels[1]    = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
-       },
-       [DMACH_SDI] = {
-               .name           = "sdi",
-               .channels[0]    = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
-               .channels[2]    = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
-               .channels[3]    = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
-       },
-       [DMACH_SPI0] = {
-               .name           = "spi0",
-               .channels[1]    = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
-       },
-       [DMACH_SPI1] = {
-               .name           = "spi1",
-               .channels[3]    = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
-       },
-       [DMACH_UART0] = {
-               .name           = "uart0",
-               .channels[0]    = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
-       },
-       [DMACH_UART1] = {
-               .name           = "uart1",
-               .channels[1]    = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
-       },
-       [DMACH_UART2] = {
-               .name           = "uart2",
-               .channels[3]    = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
-       },
-       [DMACH_TIMER] = {
-               .name           = "timer",
-               .channels[0]    = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
-               .channels[2]    = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
-               .channels[3]    = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
-       },
-       [DMACH_I2S_IN] = {
-               .name           = "i2s-sdi",
-               .channels[1]    = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
-               .channels[2]    = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
-       },
-       [DMACH_I2S_OUT] = {
-               .name           = "i2s-sdo",
-               .channels[2]    = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
-       },
-       [DMACH_USB_EP1] = {
-               .name           = "usb-ep1",
-               .channels[0]    = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
-       },
-       [DMACH_USB_EP2] = {
-               .name           = "usb-ep2",
-               .channels[1]    = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
-       },
-       [DMACH_USB_EP3] = {
-               .name           = "usb-ep3",
-               .channels[2]    = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
-       },
-       [DMACH_USB_EP4] = {
-               .name           = "usb-ep4",
-               .channels[3]    =S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
-       },
-};
-
-static void s3c2410_dma_select(struct s3c2410_dma_chan *chan,
-                              struct s3c24xx_dma_map *map)
-{
-       chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
-}
-
-static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = {
-       .select         = s3c2410_dma_select,
-       .dcon_mask      = 7 << 24,
-       .map            = s3c2410_dma_mappings,
-       .map_size       = ARRAY_SIZE(s3c2410_dma_mappings),
-};
-
-static struct s3c24xx_dma_order __initdata s3c2410_dma_order = {
-       .channels       = {
-               [DMACH_SDI]     = {
-                       .list   = {
-                               [0]     = 3 | DMA_CH_VALID,
-                               [1]     = 2 | DMA_CH_VALID,
-                               [2]     = 0 | DMA_CH_VALID,
-                       },
-               },
-               [DMACH_I2S_IN]  = {
-                       .list   = {
-                               [0]     = 1 | DMA_CH_VALID,
-                               [1]     = 2 | DMA_CH_VALID,
-                       },
-               },
-       },
-};
-
-static int __init s3c2410_dma_add(struct device *dev,
-                                 struct subsys_interface *sif)
-{
-       s3c2410_dma_init();
-       s3c24xx_dma_order_set(&s3c2410_dma_order);
-       return s3c24xx_dma_init_map(&s3c2410_dma_sel);
-}
-
-#if defined(CONFIG_CPU_S3C2410)
-static struct subsys_interface s3c2410_dma_interface = {
-       .name           = "s3c2410_dma",
-       .subsys         = &s3c2410_subsys,
-       .add_dev        = s3c2410_dma_add,
-};
-
-static int __init s3c2410_dma_drvinit(void)
-{
-       return subsys_interface_register(&s3c2410_dma_interface);
-}
-
-arch_initcall(s3c2410_dma_drvinit);
-
-static struct subsys_interface s3c2410a_dma_interface = {
-       .name           = "s3c2410a_dma",
-       .subsys         = &s3c2410a_subsys,
-       .add_dev        = s3c2410_dma_add,
-};
-
-static int __init s3c2410a_dma_drvinit(void)
-{
-       return subsys_interface_register(&s3c2410a_dma_interface);
-}
-
-arch_initcall(s3c2410a_dma_drvinit);
-#endif
-
-#if defined(CONFIG_CPU_S3C2442)
-/* S3C2442 DMA contains the same selection table as the S3C2410 */
-static struct subsys_interface s3c2442_dma_interface = {
-       .name           = "s3c2442_dma",
-       .subsys         = &s3c2442_subsys,
-       .add_dev        = s3c2410_dma_add,
-};
-
-static int __init s3c2442_dma_drvinit(void)
-{
-       return subsys_interface_register(&s3c2442_dma_interface);
-}
-
-arch_initcall(s3c2442_dma_drvinit);
-#endif
-
diff --git a/arch/arm/mach-s3c2410/h1940-bluetooth.c b/arch/arm/mach-s3c2410/h1940-bluetooth.c
deleted file mode 100644 (file)
index a5eeb62..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * arch/arm/mach-s3c2410/h1940-bluetooth.c
- * Copyright (c) Arnaud Patard <arnaud.patard@rtp-net.org>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file COPYING in the main directory of this archive for
- * more details.
- *
- *         S3C2410 bluetooth "driver"
- *
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/leds.h>
-#include <linux/gpio.h>
-#include <linux/rfkill.h>
-
-#include <mach/regs-gpio.h>
-#include <mach/hardware.h>
-#include <mach/h1940-latch.h>
-#include <mach/h1940.h>
-
-#define DRV_NAME "h1940-bt"
-
-/* Bluetooth control */
-static void h1940bt_enable(int on)
-{
-       if (on) {
-               /* Power on the chip */
-               gpio_set_value(H1940_LATCH_BLUETOOTH_POWER, 1);
-               /* Reset the chip */
-               mdelay(10);
-
-               gpio_set_value(S3C2410_GPH(1), 1);
-               mdelay(10);
-               gpio_set_value(S3C2410_GPH(1), 0);
-
-               h1940_led_blink_set(-EINVAL, GPIO_LED_BLINK, NULL, NULL);
-       }
-       else {
-               gpio_set_value(S3C2410_GPH(1), 1);
-               mdelay(10);
-               gpio_set_value(S3C2410_GPH(1), 0);
-               mdelay(10);
-               gpio_set_value(H1940_LATCH_BLUETOOTH_POWER, 0);
-
-               h1940_led_blink_set(-EINVAL, GPIO_LED_NO_BLINK_LOW, NULL, NULL);
-       }
-}
-
-static int h1940bt_set_block(void *data, bool blocked)
-{
-       h1940bt_enable(!blocked);
-       return 0;
-}
-
-static const struct rfkill_ops h1940bt_rfkill_ops = {
-       .set_block = h1940bt_set_block,
-};
-
-static int __devinit h1940bt_probe(struct platform_device *pdev)
-{
-       struct rfkill *rfk;
-       int ret = 0;
-
-       ret = gpio_request(S3C2410_GPH(1), dev_name(&pdev->dev));
-       if (ret) {
-               dev_err(&pdev->dev, "could not get GPH1\n");
-               return ret;
-       }
-
-       ret = gpio_request(H1940_LATCH_BLUETOOTH_POWER, dev_name(&pdev->dev));
-       if (ret) {
-               gpio_free(S3C2410_GPH(1));
-               dev_err(&pdev->dev, "could not get BT_POWER\n");
-               return ret;
-       }
-
-       /* Configures BT serial port GPIOs */
-       s3c_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0);
-       s3c_gpio_setpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE);
-       s3c_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT);
-       s3c_gpio_setpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE);
-       s3c_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0);
-       s3c_gpio_setpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE);
-       s3c_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0);
-       s3c_gpio_setpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE);
-
-       rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH,
-                       &h1940bt_rfkill_ops, NULL);
-       if (!rfk) {
-               ret = -ENOMEM;
-               goto err_rfk_alloc;
-       }
-
-       ret = rfkill_register(rfk);
-       if (ret)
-               goto err_rfkill;
-
-       platform_set_drvdata(pdev, rfk);
-
-       return 0;
-
-err_rfkill:
-       rfkill_destroy(rfk);
-err_rfk_alloc:
-       return ret;
-}
-
-static int h1940bt_remove(struct platform_device *pdev)
-{
-       struct rfkill *rfk = platform_get_drvdata(pdev);
-
-       platform_set_drvdata(pdev, NULL);
-       gpio_free(S3C2410_GPH(1));
-
-       if (rfk) {
-               rfkill_unregister(rfk);
-               rfkill_destroy(rfk);
-       }
-       rfk = NULL;
-
-       h1940bt_enable(0);
-
-       return 0;
-}
-
-
-static struct platform_driver h1940bt_driver = {
-       .driver         = {
-               .name   = DRV_NAME,
-       },
-       .probe          = h1940bt_probe,
-       .remove         = h1940bt_remove,
-};
-
-
-static int __init h1940bt_init(void)
-{
-       return platform_driver_register(&h1940bt_driver);
-}
-
-static void __exit h1940bt_exit(void)
-{
-       platform_driver_unregister(&h1940bt_driver);
-}
-
-module_init(h1940bt_init);
-module_exit(h1940bt_exit);
-
-MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
-MODULE_DESCRIPTION("Driver for the iPAQ H1940 bluetooth chip");
-MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-s3c2410/include/mach/anubis-cpld.h b/arch/arm/mach-s3c2410/include/mach/anubis-cpld.h
deleted file mode 100644 (file)
index 1b614d5..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/anubis-cpld.h
- *
- * Copyright (c) 2005 Simtec Electronics
- *     http://www.simtec.co.uk/products/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * ANUBIS - CPLD control constants
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_ANUBISCPLD_H
-#define __ASM_ARCH_ANUBISCPLD_H
-
-/* CTRL2 - NAND WP control, IDE Reset assert/check */
-
-#define ANUBIS_CTRL1_NANDSEL           (0x3)
-
-/* IDREG - revision */
-
-#define ANUBIS_IDREG_REVMASK           (0x7)
-
-#endif /* __ASM_ARCH_ANUBISCPLD_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/anubis-irq.h b/arch/arm/mach-s3c2410/include/mach/anubis-irq.h
deleted file mode 100644 (file)
index a2a3281..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/anubis-irq.h
- *
- * Copyright (c) 2005 Simtec Electronics
- *     http://www.simtec.co.uk/products/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- *  ANUBIS - IRQ Number definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_ANUBISIRQ_H
-#define __ASM_ARCH_ANUBISIRQ_H
-
-#define IRQ_IDE0       IRQ_EINT2
-#define IRQ_IDE1       IRQ_EINT3
-#define IRQ_ASIX       IRQ_EINT1
-
-#endif /* __ASM_ARCH_ANUBISIRQ_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/anubis-map.h b/arch/arm/mach-s3c2410/include/mach/anubis-map.h
deleted file mode 100644 (file)
index c9deb3a..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/anubis-map.h
- *
- * Copyright (c) 2005 Simtec Electronics
- *     http://www.simtec.co.uk/products/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * ANUBIS - Memory map definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* needs arch/map.h including with this */
-
-#ifndef __ASM_ARCH_ANUBISMAP_H
-#define __ASM_ARCH_ANUBISMAP_H
-
-/* start peripherals off after the S3C2410 */
-
-#define ANUBIS_IOADDR(x)       (S3C2410_ADDR((x) + 0x01800000))
-
-#define ANUBIS_PA_CPLD         (S3C2410_CS1 | (1<<26))
-
-/* we put the CPLD registers next, to get them out of the way */
-
-#define ANUBIS_VA_CTRL1            ANUBIS_IOADDR(0x00000000)    /* 0x01800000 */
-#define ANUBIS_PA_CTRL1            (ANUBIS_PA_CPLD)
-
-#define ANUBIS_VA_IDREG            ANUBIS_IOADDR(0x00300000)    /* 0x01B00000 */
-#define ANUBIS_PA_IDREG            (ANUBIS_PA_CPLD + (3<<23))
-
-#define ANUBIS_IDEPRI      ANUBIS_IOADDR(0x01000000)
-#define ANUBIS_IDEPRIAUX    ANUBIS_IOADDR(0x01100000)
-#define ANUBIS_IDESEC      ANUBIS_IOADDR(0x01200000)
-#define ANUBIS_IDESECAUX    ANUBIS_IOADDR(0x01300000)
-
-#endif /* __ASM_ARCH_ANUBISMAP_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/bast-cpld.h b/arch/arm/mach-s3c2410/include/mach/bast-cpld.h
deleted file mode 100644 (file)
index bee2a7a..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/bast-cpld.h
- *
- * Copyright (c) 2003-2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * BAST - CPLD control constants
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_BASTCPLD_H
-#define __ASM_ARCH_BASTCPLD_H
-
-/* CTRL1 - Audio LR routing */
-
-#define BAST_CPLD_CTRL1_LRCOFF     (0x00)
-#define BAST_CPLD_CTRL1_LRCADC     (0x01)
-#define BAST_CPLD_CTRL1_LRCDAC     (0x02)
-#define BAST_CPLD_CTRL1_LRCARM     (0x03)
-#define BAST_CPLD_CTRL1_LRMASK     (0x03)
-
-/* CTRL2 - NAND WP control, IDE Reset assert/check */
-
-#define BAST_CPLD_CTRL2_WNAND       (0x04)
-#define BAST_CPLD_CTLR2_IDERST      (0x08)
-
-/* CTRL3 - rom write control, CPLD identity */
-
-#define BAST_CPLD_CTRL3_IDMASK      (0x0e)
-#define BAST_CPLD_CTRL3_ROMWEN      (0x01)
-
-/* CTRL4 - 8bit LCD interface control/status */
-
-#define BAST_CPLD_CTRL4_LLAT       (0x01)
-#define BAST_CPLD_CTRL4_LCDRW      (0x02)
-#define BAST_CPLD_CTRL4_LCDCMD     (0x04)
-#define BAST_CPLD_CTRL4_LCDE2      (0x01)
-
-/* CTRL5 - DMA routing */
-
-#define BAST_CPLD_DMA0_PRIIDE      (0<<0)
-#define BAST_CPLD_DMA0_SECIDE      (1<<0)
-#define BAST_CPLD_DMA0_ISA15       (2<<0)
-#define BAST_CPLD_DMA0_ISA36       (3<<0)
-
-#define BAST_CPLD_DMA1_PRIIDE      (0<<2)
-#define BAST_CPLD_DMA1_SECIDE      (1<<2)
-#define BAST_CPLD_DMA1_ISA15       (2<<2)
-#define BAST_CPLD_DMA1_ISA36       (3<<2)
-
-#endif /* __ASM_ARCH_BASTCPLD_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/bast-irq.h b/arch/arm/mach-s3c2410/include/mach/bast-irq.h
deleted file mode 100644 (file)
index cac428c..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/bast-irq.h
- *
- * Copyright (c) 2003-2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Machine BAST - IRQ Number definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_BASTIRQ_H
-#define __ASM_ARCH_BASTIRQ_H
-
-/* irq numbers to onboard peripherals */
-
-#define IRQ_USBOC      IRQ_EINT18
-#define IRQ_IDE0       IRQ_EINT16
-#define IRQ_IDE1       IRQ_EINT17
-#define IRQ_PCSERIAL1  IRQ_EINT15
-#define IRQ_PCSERIAL2  IRQ_EINT14
-#define IRQ_PCPARALLEL IRQ_EINT13
-#define IRQ_ASIX       IRQ_EINT11
-#define IRQ_DM9000     IRQ_EINT10
-#define IRQ_ISA               IRQ_EINT9
-#define IRQ_SMALERT    IRQ_EINT8
-
-#endif /* __ASM_ARCH_BASTIRQ_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/bast-map.h b/arch/arm/mach-s3c2410/include/mach/bast-map.h
deleted file mode 100644 (file)
index 6e7dc9d..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/bast-map.h
- *
- * Copyright (c) 2003-2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Machine BAST - Memory map definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* needs arch/map.h including with this */
-
-/* ok, we've used up to 0x13000000, now we need to find space for the
- * peripherals that live in the nGCS[x] areas, which are quite numerous
- * in their space. We also have the board's CPLD to find register space
- * for.
- */
-
-#ifndef __ASM_ARCH_BASTMAP_H
-#define __ASM_ARCH_BASTMAP_H
-
-#define BAST_IOADDR(x)    (S3C2410_ADDR((x) + 0x01300000))
-
-/* we put the CPLD registers next, to get them out of the way */
-
-#define BAST_VA_CTRL1      BAST_IOADDR(0x00000000)      /* 0x01300000 */
-#define BAST_PA_CTRL1      (S3C2410_CS5 | 0x7800000)
-
-#define BAST_VA_CTRL2      BAST_IOADDR(0x00100000)      /* 0x01400000 */
-#define BAST_PA_CTRL2      (S3C2410_CS1 | 0x6000000)
-
-#define BAST_VA_CTRL3      BAST_IOADDR(0x00200000)      /* 0x01500000 */
-#define BAST_PA_CTRL3      (S3C2410_CS1 | 0x6800000)
-
-#define BAST_VA_CTRL4      BAST_IOADDR(0x00300000)      /* 0x01600000 */
-#define BAST_PA_CTRL4      (S3C2410_CS1 | 0x7000000)
-
-/* next, we have the PC104 ISA interrupt registers */
-
-#define BAST_PA_PC104_IRQREQ  (S3C2410_CS5 | 0x6000000) /* 0x01700000 */
-#define BAST_VA_PC104_IRQREQ  BAST_IOADDR(0x00400000)
-
-#define BAST_PA_PC104_IRQRAW  (S3C2410_CS5 | 0x6800000) /* 0x01800000 */
-#define BAST_VA_PC104_IRQRAW  BAST_IOADDR(0x00500000)
-
-#define BAST_PA_PC104_IRQMASK (S3C2410_CS5 | 0x7000000) /* 0x01900000 */
-#define BAST_VA_PC104_IRQMASK BAST_IOADDR(0x00600000)
-
-#define BAST_PA_LCD_RCMD1     (0x8800000)
-#define BAST_VA_LCD_RCMD1     BAST_IOADDR(0x00700000)
-
-#define BAST_PA_LCD_WCMD1     (0x8000000)
-#define BAST_VA_LCD_WCMD1     BAST_IOADDR(0x00800000)
-
-#define BAST_PA_LCD_RDATA1    (0x9800000)
-#define BAST_VA_LCD_RDATA1    BAST_IOADDR(0x00900000)
-
-#define BAST_PA_LCD_WDATA1    (0x9000000)
-#define BAST_VA_LCD_WDATA1    BAST_IOADDR(0x00A00000)
-
-#define BAST_PA_LCD_RCMD2     (0xA800000)
-#define BAST_VA_LCD_RCMD2     BAST_IOADDR(0x00B00000)
-
-#define BAST_PA_LCD_WCMD2     (0xA000000)
-#define BAST_VA_LCD_WCMD2     BAST_IOADDR(0x00C00000)
-
-#define BAST_PA_LCD_RDATA2    (0xB800000)
-#define BAST_VA_LCD_RDATA2    BAST_IOADDR(0x00D00000)
-
-#define BAST_PA_LCD_WDATA2    (0xB000000)
-#define BAST_VA_LCD_WDATA2    BAST_IOADDR(0x00E00000)
-
-
-/* 0xE0000000 contains the IO space that is split by speed and
- * wether the access is for 8 or 16bit IO... this ensures that
- * the correct access is made
- *
- * 0x10000000 of space, partitioned as so:
- *
- * 0x00000000 to 0x04000000  8bit,  slow
- * 0x04000000 to 0x08000000  16bit, slow
- * 0x08000000 to 0x0C000000  16bit, net
- * 0x0C000000 to 0x10000000  16bit, fast
- *
- * each of these spaces has the following in:
- *
- * 0x00000000 to 0x01000000 16MB ISA IO space
- * 0x01000000 to 0x02000000 16MB ISA memory space
- * 0x02000000 to 0x02100000 1MB  IDE primary channel
- * 0x02100000 to 0x02200000 1MB  IDE primary channel aux
- * 0x02200000 to 0x02400000 1MB  IDE secondary channel
- * 0x02300000 to 0x02400000 1MB  IDE secondary channel aux
- * 0x02400000 to 0x02500000 1MB  ASIX ethernet controller
- * 0x02500000 to 0x02600000 1MB  Davicom DM9000 ethernet controller
- * 0x02600000 to 0x02700000 1MB  PC SuperIO controller
- *
- * the phyiscal layout of the zones are:
- *  nGCS2 - 8bit, slow
- *  nGCS3 - 16bit, slow
- *  nGCS4 - 16bit, net
- *  nGCS5 - 16bit, fast
- */
-
-#define BAST_VA_MULTISPACE (0xE0000000)
-
-#define BAST_VA_ISAIO     (BAST_VA_MULTISPACE + 0x00000000)
-#define BAST_VA_ISAMEM    (BAST_VA_MULTISPACE + 0x01000000)
-#define BAST_VA_IDEPRI    (BAST_VA_MULTISPACE + 0x02000000)
-#define BAST_VA_IDEPRIAUX  (BAST_VA_MULTISPACE + 0x02100000)
-#define BAST_VA_IDESEC    (BAST_VA_MULTISPACE + 0x02200000)
-#define BAST_VA_IDESECAUX  (BAST_VA_MULTISPACE + 0x02300000)
-#define BAST_VA_ASIXNET           (BAST_VA_MULTISPACE + 0x02400000)
-#define BAST_VA_DM9000    (BAST_VA_MULTISPACE + 0x02500000)
-#define BAST_VA_SUPERIO           (BAST_VA_MULTISPACE + 0x02600000)
-
-#define BAST_VA_MULTISPACE (0xE0000000)
-
-#define BAST_VAM_CS2 (0x00000000)
-#define BAST_VAM_CS3 (0x04000000)
-#define BAST_VAM_CS4 (0x08000000)
-#define BAST_VAM_CS5 (0x0C000000)
-
-/* physical offset addresses for the peripherals */
-
-#define BAST_PA_ISAIO    (0x00000000)
-#define BAST_PA_ASIXNET          (0x01000000)
-#define BAST_PA_SUPERIO          (0x01800000)
-#define BAST_PA_IDEPRI   (0x02000000)
-#define BAST_PA_IDEPRIAUX (0x02800000)
-#define BAST_PA_IDESEC   (0x03000000)
-#define BAST_PA_IDESECAUX (0x03800000)
-#define BAST_PA_ISAMEM   (0x04000000)
-#define BAST_PA_DM9000   (0x05000000)
-
-/* some configurations for the peripherals */
-
-#define BAST_PCSIO (BAST_VA_SUPERIO + BAST_VAM_CS2)
-/*  */
-
-#define BAST_ASIXNET_CS  BAST_VAM_CS5
-#define BAST_IDE_CS     BAST_VAM_CS5
-#define BAST_DM9000_CS  BAST_VAM_CS4
-
-#endif /* __ASM_ARCH_BASTMAP_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/bast-pmu.h b/arch/arm/mach-s3c2410/include/mach/bast-pmu.h
deleted file mode 100644 (file)
index 4c38b39..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/bast-pmu.h
- *
- * Copyright (c) 2003-2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     Vincent Sanders <vince@simtec.co.uk>
- *
- * Machine BAST - Power Management chip
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_BASTPMU_H
-#define __ASM_ARCH_BASTPMU_H "08_OCT_2004"
-
-#define BASTPMU_REG_IDENT      (0x00)
-#define BASTPMU_REG_VERSION    (0x01)
-#define BASTPMU_REG_DDCCTRL    (0x02)
-#define BASTPMU_REG_POWER      (0x03)
-#define BASTPMU_REG_RESET      (0x04)
-#define BASTPMU_REG_GWO                (0x05)
-#define BASTPMU_REG_WOL                (0x06)
-#define BASTPMU_REG_WOR                (0x07)
-#define BASTPMU_REG_UID                (0x09)
-
-#define BASTPMU_EEPROM         (0xC0)
-
-#define BASTPMU_EEP_UID                (BASTPMU_EEPROM + 0)
-#define BASTPMU_EEP_WOL                (BASTPMU_EEPROM + 8)
-#define BASTPMU_EEP_WOR                (BASTPMU_EEPROM + 9)
-
-#define BASTPMU_IDENT_0                0x53
-#define BASTPMU_IDENT_1                0x42
-#define BASTPMU_IDENT_2                0x50
-#define BASTPMU_IDENT_3                0x4d
-
-#define BASTPMU_RESET_GUARD    (0x55)
-
-#endif /* __ASM_ARCH_BASTPMU_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/debug-macro.S b/arch/arm/mach-s3c2410/include/mach/debug-macro.S
deleted file mode 100644 (file)
index 4135de8..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/debug-macro.S
- *
- * Debugging macro include header
- *
- *  Copyright (C) 1994-1999 Russell King
- *  Copyright (C) 2005 Simtec Electronics
- *
- *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <mach/map.h>
-#include <mach/regs-gpio.h>
-#include <plat/regs-serial.h>
-
-#define S3C2410_UART1_OFF (0x4000)
-#define SHIFT_2440TXF (14-9)
-
-       .macro addruart, rp, rv, tmp
-               ldr     \rp, = S3C24XX_PA_UART
-               ldr     \rv, = S3C24XX_VA_UART
-#if CONFIG_DEBUG_S3C_UART != 0
-               add     \rp, \rp, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART)
-               add     \rv, \rv, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART)
-#endif
-       .endm
-
-       .macro fifo_full_s3c24xx rd, rx
-               @ check for arm920 vs arm926. currently assume all arm926
-               @ devices have an 64 byte FIFO identical to the s3c2440
-               mrc     p15, 0, \rd, c0, c0
-               and     \rd, \rd, #0xff0
-               teq     \rd, #0x260
-               beq     1004f
-               mrc     p15, 0, \rd, c1, c0
-               tst     \rd, #1
-               addeq   \rd, \rx, #(S3C24XX_PA_GPIO - S3C24XX_PA_UART)
-               addne   \rd, \rx, #(S3C24XX_VA_GPIO - S3C24XX_VA_UART)
-               bic     \rd, \rd, #0xff000
-               ldr     \rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ]
-               and     \rd, \rd, #0x00ff0000
-               teq     \rd, #0x00440000                @ is it 2440?
-1004:
-               ldr     \rd, [ \rx, # S3C2410_UFSTAT ]
-               moveq   \rd, \rd, lsr #SHIFT_2440TXF
-               tst     \rd, #S3C2410_UFSTAT_TXFULL
-       .endm
-
-       .macro  fifo_full_s3c2410 rd, rx
-               ldr     \rd, [ \rx, # S3C2410_UFSTAT ]
-               tst     \rd, #S3C2410_UFSTAT_TXFULL
-       .endm
-
-/* fifo level reading */
-
-       .macro fifo_level_s3c24xx rd, rx
-               @ check for arm920 vs arm926. currently assume all arm926
-               @ devices have an 64 byte FIFO identical to the s3c2440
-               mrc     p15, 0, \rd, c0, c0
-               and     \rd, \rd, #0xff0
-               teq     \rd, #0x260
-               beq     10000f
-               mrc     p15, 0, \rd, c1, c0
-               tst     \rd, #1
-               addeq   \rd, \rx, #(S3C24XX_PA_GPIO - S3C24XX_PA_UART)
-               addne   \rd, \rx, #(S3C24XX_VA_GPIO - S3C24XX_VA_UART)
-               bic     \rd, \rd, #0xff000
-               ldr     \rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ]
-               and     \rd, \rd, #0x00ff0000
-               teq     \rd, #0x00440000                @ is it 2440?
-
-10000:
-               ldr     \rd, [ \rx, # S3C2410_UFSTAT ]
-               andne   \rd, \rd, #S3C2410_UFSTAT_TXMASK
-               andeq   \rd, \rd, #S3C2440_UFSTAT_TXMASK
-       .endm
-
-       .macro fifo_level_s3c2410 rd, rx
-               ldr     \rd, [ \rx, # S3C2410_UFSTAT ]
-               and     \rd, \rd, #S3C2410_UFSTAT_TXMASK
-       .endm
-
-/* Select the correct implementation depending on the configuration. The
- * S3C2440 will get selected by default, as these are the most widely
- * used variants of these
-*/
-
-#if defined(CONFIG_CPU_LLSERIAL_S3C2410_ONLY)
-#define fifo_full  fifo_full_s3c2410
-#define fifo_level fifo_level_s3c2410
-#elif !defined(CONFIG_CPU_LLSERIAL_S3C2440_ONLY)
-#define fifo_full  fifo_full_s3c24xx
-#define fifo_level fifo_level_s3c24xx
-#endif
-
-/* include the reset of the code which will do the work */
-
-#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h
deleted file mode 100644 (file)
index acbdfec..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/dma.h
- *
- * Copyright (C) 2003-2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C24XX DMA support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H __FILE__
-
-#include <linux/device.h>
-
-#define MAX_DMA_TRANSFER_SIZE   0x100000 /* Data Unit is half word  */
-
-/* We use `virtual` dma channels to hide the fact we have only a limited
- * number of DMA channels, and not of all of them (dependent on the device)
- * can be attached to any DMA source. We therefore let the DMA core handle
- * the allocation of hardware channels to clients.
-*/
-
-enum dma_ch {
-       DMACH_XD0,
-       DMACH_XD1,
-       DMACH_SDI,
-       DMACH_SPI0,
-       DMACH_SPI1,
-       DMACH_UART0,
-       DMACH_UART1,
-       DMACH_UART2,
-       DMACH_TIMER,
-       DMACH_I2S_IN,
-       DMACH_I2S_OUT,
-       DMACH_PCM_IN,
-       DMACH_PCM_OUT,
-       DMACH_MIC_IN,
-       DMACH_USB_EP1,
-       DMACH_USB_EP2,
-       DMACH_USB_EP3,
-       DMACH_USB_EP4,
-       DMACH_UART0_SRC2,       /* s3c2412 second uart sources */
-       DMACH_UART1_SRC2,
-       DMACH_UART2_SRC2,
-       DMACH_UART3,            /* s3c2443 has extra uart */
-       DMACH_UART3_SRC2,
-       DMACH_MAX,              /* the end entry */
-};
-
-static inline bool samsung_dma_has_circular(void)
-{
-       return false;
-}
-
-static inline bool samsung_dma_is_dmadev(void)
-{
-       return false;
-}
-
-#include <plat/dma.h>
-
-#define DMACH_LOW_LEVEL        (1<<28) /* use this to specifiy hardware ch no */
-
-/* we have 4 dma channels */
-#if !defined(CONFIG_CPU_S3C2443) && !defined(CONFIG_CPU_S3C2416)
-#define S3C_DMA_CHANNELS               (4)
-#else
-#define S3C_DMA_CHANNELS               (6)
-#endif
-
-/* types */
-
-enum s3c2410_dma_state {
-       S3C2410_DMA_IDLE,
-       S3C2410_DMA_RUNNING,
-       S3C2410_DMA_PAUSED
-};
-
-/* enum s3c2410_dma_loadst
- *
- * This represents the state of the DMA engine, wrt to the loaded / running
- * transfers. Since we don't have any way of knowing exactly the state of
- * the DMA transfers, we need to know the state to make decisions on wether
- * we can
- *
- * S3C2410_DMA_NONE
- *
- * There are no buffers loaded (the channel should be inactive)
- *
- * S3C2410_DMA_1LOADED
- *
- * There is one buffer loaded, however it has not been confirmed to be
- * loaded by the DMA engine. This may be because the channel is not
- * yet running, or the DMA driver decided that it was too costly to
- * sit and wait for it to happen.
- *
- * S3C2410_DMA_1RUNNING
- *
- * The buffer has been confirmed running, and not finisged
- *
- * S3C2410_DMA_1LOADED_1RUNNING
- *
- * There is a buffer waiting to be loaded by the DMA engine, and one
- * currently running.
-*/
-
-enum s3c2410_dma_loadst {
-       S3C2410_DMALOAD_NONE,
-       S3C2410_DMALOAD_1LOADED,
-       S3C2410_DMALOAD_1RUNNING,
-       S3C2410_DMALOAD_1LOADED_1RUNNING,
-};
-
-
-/* flags */
-
-#define S3C2410_DMAF_SLOW         (1<<0)   /* slow, so don't worry about
-                                           * waiting for reloads */
-#define S3C2410_DMAF_AUTOSTART    (1<<1)   /* auto-start if buffer queued */
-
-#define S3C2410_DMAF_CIRCULAR  (1 << 2)        /* no circular dma support */
-
-/* dma buffer */
-
-struct s3c2410_dma_buf;
-
-/* s3c2410_dma_buf
- *
- * internally used buffer structure to describe a queued or running
- * buffer.
-*/
-
-struct s3c2410_dma_buf {
-       struct s3c2410_dma_buf  *next;
-       int                      magic;         /* magic */
-       int                      size;          /* buffer size in bytes */
-       dma_addr_t               data;          /* start of DMA data */
-       dma_addr_t               ptr;           /* where the DMA got to [1] */
-       void                    *id;            /* client's id */
-};
-
-/* [1] is this updated for both recv/send modes? */
-
-struct s3c2410_dma_stats {
-       unsigned long           loads;
-       unsigned long           timeout_longest;
-       unsigned long           timeout_shortest;
-       unsigned long           timeout_avg;
-       unsigned long           timeout_failed;
-};
-
-struct s3c2410_dma_map;
-
-/* struct s3c2410_dma_chan
- *
- * full state information for each DMA channel
-*/
-
-struct s3c2410_dma_chan {
-       /* channel state flags and information */
-       unsigned char            number;      /* number of this dma channel */
-       unsigned char            in_use;      /* channel allocated */
-       unsigned char            irq_claimed; /* irq claimed for channel */
-       unsigned char            irq_enabled; /* irq enabled for channel */
-       unsigned char            xfer_unit;   /* size of an transfer */
-
-       /* channel state */
-
-       enum s3c2410_dma_state   state;
-       enum s3c2410_dma_loadst  load_state;
-       struct s3c2410_dma_client *client;
-
-       /* channel configuration */
-       enum dma_data_direction  source;
-       enum dma_ch              req_ch;
-       unsigned long            dev_addr;
-       unsigned long            load_timeout;
-       unsigned int             flags;         /* channel flags */
-
-       struct s3c24xx_dma_map  *map;           /* channel hw maps */
-
-       /* channel's hardware position and configuration */
-       void __iomem            *regs;          /* channels registers */
-       void __iomem            *addr_reg;      /* data address register */
-       unsigned int             irq;           /* channel irq */
-       unsigned long            dcon;          /* default value of DCON */
-
-       /* driver handles */
-       s3c2410_dma_cbfn_t       callback_fn;   /* buffer done callback */
-       s3c2410_dma_opfn_t       op_fn;         /* channel op callback */
-
-       /* stats gathering */
-       struct s3c2410_dma_stats *stats;
-       struct s3c2410_dma_stats  stats_store;
-
-       /* buffer list and information */
-       struct s3c2410_dma_buf  *curr;          /* current dma buffer */
-       struct s3c2410_dma_buf  *next;          /* next buffer to load */
-       struct s3c2410_dma_buf  *end;           /* end of queue */
-
-       /* system device */
-       struct device   dev;
-};
-
-typedef unsigned long dma_device_t;
-
-#endif /* __ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/entry-macro.S b/arch/arm/mach-s3c2410/include/mach/entry-macro.S
deleted file mode 100644 (file)
index 7615a14..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * arch/arm/mach-s3c2410/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for S3C2410-based platforms
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
-*/
-
-/* We have a problem that the INTOFFSET register does not always
- * show one interrupt. Occasionally we get two interrupts through
- * the prioritiser, and this causes the INTOFFSET register to show
- * what looks like the logical-or of the two interrupt numbers.
- *
- * Thanks to Klaus, Shannon, et al for helping to debug this problem
-*/
-
-#define INTPND         (0x10)
-#define INTOFFSET      (0x14)
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-       .macro  get_irqnr_preamble, base, tmp
-       .endm
-
-       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-               mov     \base, #S3C24XX_VA_IRQ
-
-               @@ try the interrupt offset register, since it is there
-
-               ldr     \irqstat, [ \base, #INTPND ]
-               teq     \irqstat, #0
-               beq     1002f
-               ldr     \irqnr, [ \base, #INTOFFSET ]
-               mov     \tmp, #1
-               tst     \irqstat, \tmp, lsl \irqnr
-               bne     1001f
-
-               @@ the number specified is not a valid irq, so try
-               @@ and work it out for ourselves
-
-               mov     \irqnr, #0              @@ start here
-
-               @@ work out which irq (if any) we got
-
-               movs    \tmp, \irqstat, lsl#16
-               addeq   \irqnr, \irqnr, #16
-               moveq   \irqstat, \irqstat, lsr#16
-               tst     \irqstat, #0xff
-               addeq   \irqnr, \irqnr, #8
-               moveq   \irqstat, \irqstat, lsr#8
-               tst     \irqstat, #0xf
-               addeq   \irqnr, \irqnr, #4
-               moveq   \irqstat, \irqstat, lsr#4
-               tst     \irqstat, #0x3
-               addeq   \irqnr, \irqnr, #2
-               moveq   \irqstat, \irqstat, lsr#2
-               tst     \irqstat, #0x1
-               addeq   \irqnr, \irqnr, #1
-
-               @@ we have the value
-1001:
-               adds    \irqnr, \irqnr, #IRQ_EINT0
-1002:
-               @@ exit here, Z flag unset if IRQ
-
-       .endm
diff --git a/arch/arm/mach-s3c2410/include/mach/fb.h b/arch/arm/mach-s3c2410/include/mach/fb.h
deleted file mode 100644 (file)
index a957bc8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <plat/fb-s3c2410.h>
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-fns.h b/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
deleted file mode 100644 (file)
index c53ad34..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <plat/gpio-fns.h>
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
deleted file mode 100644 (file)
index 019ea86..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
- *
- * Copyright (c) 2008 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - GPIO bank numbering
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __MACH_GPIONRS_H
-#define __MACH_GPIONRS_H
-
-#define S3C2410_GPIONO(bank,offset) ((bank) + (offset))
-
-#define S3C2410_GPIO_BANKG   (32*6)
-#define S3C2410_GPIO_BANKH   (32*7)
-
-/* GPIO sizes for various SoCs:
- *
- *             2442
- *   2410 2412 2440 2443 2416
- *   ---- ---- ---- ---- ----
- * A 23   22   25   16   25
- * B 11   11   11   11   9
- * C 16   15   16   16   16
- * D 16   16   16   16   16
- * E 16   16   16   16   16
- * F 8    8    8    8    8
- * G 16   16   16   16   8
- * H 11   11   9    15   15
- * J --   --   13   16   --
- * K --   --   --   --   16
- * L --   --   --   15   7
- * M --   --   --   2    2
- */
-
-/* GPIO bank sizes */
-#define S3C2410_GPIO_A_NR      (32)
-#define S3C2410_GPIO_B_NR      (32)
-#define S3C2410_GPIO_C_NR      (32)
-#define S3C2410_GPIO_D_NR      (32)
-#define S3C2410_GPIO_E_NR      (32)
-#define S3C2410_GPIO_F_NR      (32)
-#define S3C2410_GPIO_G_NR      (32)
-#define S3C2410_GPIO_H_NR      (32)
-#define S3C2410_GPIO_J_NR      (32)    /* technically 16. */
-#define S3C2410_GPIO_K_NR      (32)    /* technically 16. */
-#define S3C2410_GPIO_L_NR      (32)    /* technically 15. */
-#define S3C2410_GPIO_M_NR      (32)    /* technically 2. */
-
-#if CONFIG_S3C_GPIO_SPACE != 0
-#error CONFIG_S3C_GPIO_SPACE cannot be nonzero at the moment
-#endif
-
-#define S3C2410_GPIO_NEXT(__gpio) \
-       ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 0)
-
-#ifndef __ASSEMBLY__
-
-enum s3c_gpio_number {
-       S3C2410_GPIO_A_START = 0,
-       S3C2410_GPIO_B_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_A),
-       S3C2410_GPIO_C_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_B),
-       S3C2410_GPIO_D_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_C),
-       S3C2410_GPIO_E_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_D),
-       S3C2410_GPIO_F_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_E),
-       S3C2410_GPIO_G_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_F),
-       S3C2410_GPIO_H_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_G),
-       S3C2410_GPIO_J_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_H),
-       S3C2410_GPIO_K_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_J),
-       S3C2410_GPIO_L_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_K),
-       S3C2410_GPIO_M_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_L),
-};
-
-#endif /* __ASSEMBLY__ */
-
-/* S3C2410 GPIO number definitions. */
-
-#define S3C2410_GPA(_nr)       (S3C2410_GPIO_A_START + (_nr))
-#define S3C2410_GPB(_nr)       (S3C2410_GPIO_B_START + (_nr))
-#define S3C2410_GPC(_nr)       (S3C2410_GPIO_C_START + (_nr))
-#define S3C2410_GPD(_nr)       (S3C2410_GPIO_D_START + (_nr))
-#define S3C2410_GPE(_nr)       (S3C2410_GPIO_E_START + (_nr))
-#define S3C2410_GPF(_nr)       (S3C2410_GPIO_F_START + (_nr))
-#define S3C2410_GPG(_nr)       (S3C2410_GPIO_G_START + (_nr))
-#define S3C2410_GPH(_nr)       (S3C2410_GPIO_H_START + (_nr))
-#define S3C2410_GPJ(_nr)       (S3C2410_GPIO_J_START + (_nr))
-#define S3C2410_GPK(_nr)       (S3C2410_GPIO_K_START + (_nr))
-#define S3C2410_GPL(_nr)       (S3C2410_GPIO_L_START + (_nr))
-#define S3C2410_GPM(_nr)       (S3C2410_GPIO_M_START + (_nr))
-
-/* compatibility until drivers can be modified */
-
-#define S3C2410_GPA0   S3C2410_GPA(0)
-#define S3C2410_GPA1   S3C2410_GPA(1)
-#define S3C2410_GPA3   S3C2410_GPA(3)
-#define S3C2410_GPA7   S3C2410_GPA(7)
-
-#define S3C2410_GPE0   S3C2410_GPE(0)
-#define S3C2410_GPE1   S3C2410_GPE(1)
-#define S3C2410_GPE2   S3C2410_GPE(2)
-#define S3C2410_GPE3   S3C2410_GPE(3)
-#define S3C2410_GPE4   S3C2410_GPE(4)
-#define S3C2410_GPE5   S3C2410_GPE(5)
-#define S3C2410_GPE6   S3C2410_GPE(6)
-#define S3C2410_GPE7   S3C2410_GPE(7)
-#define S3C2410_GPE8   S3C2410_GPE(8)
-#define S3C2410_GPE9   S3C2410_GPE(9)
-#define S3C2410_GPE10  S3C2410_GPE(10)
-
-#define S3C2410_GPH10  S3C2410_GPH(10)
-
-#endif /* __MACH_GPIONRS_H */
-
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-track.h b/arch/arm/mach-s3c2410/include/mach/gpio-track.h
deleted file mode 100644 (file)
index c410a07..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* arch/arm/mach-s3c24100/include/mach/gpio-core.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C2410 - GPIO core support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_GPIO_CORE_H
-#define __ASM_ARCH_GPIO_CORE_H __FILE__
-
-#include <mach/regs-gpio.h>
-
-extern struct samsung_gpio_chip s3c24xx_gpios[];
-
-static inline struct samsung_gpio_chip *samsung_gpiolib_getchip(unsigned int pin)
-{
-       struct samsung_gpio_chip *chip;
-
-       if (pin > S3C_GPIO_END)
-               return NULL;
-
-       chip = &s3c24xx_gpios[pin/32];
-       return ((pin - chip->chip.base) < chip->chip.ngpio) ? chip : NULL;
-}
-
-#endif /* __ASM_ARCH_GPIO_CORE_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio.h b/arch/arm/mach-s3c2410/include/mach/gpio.h
deleted file mode 100644 (file)
index 6fac70f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/gpio.h
- *
- * Copyright (c) 2008 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - GPIO lib support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* some boards require extra gpio capacity to support external
- * devices that need GPIO.
- */
-
-#ifdef CONFIG_CPU_S3C244X
-#define ARCH_NR_GPIOS  (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA)
-#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
-#define ARCH_NR_GPIOS  (32 * 12 + CONFIG_S3C24XX_GPIO_EXTRA)
-#else
-#define ARCH_NR_GPIOS  (256 + CONFIG_S3C24XX_GPIO_EXTRA)
-#endif
-
-#include <mach/gpio-nrs.h>
-#include <mach/gpio-fns.h>
-
-#ifdef CONFIG_CPU_S3C244X
-#define S3C_GPIO_END   (S3C2410_GPJ(0) + 32)
-#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
-#define S3C_GPIO_END   (S3C2410_GPM(0) + 32)
-#else
-#define S3C_GPIO_END   (S3C2410_GPH(0) + 32)
-#endif
diff --git a/arch/arm/mach-s3c2410/include/mach/h1940-latch.h b/arch/arm/mach-s3c2410/include/mach/h1940-latch.h
deleted file mode 100644 (file)
index fc897d3..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/h1940-latch.h
- *
- * Copyright (c) 2005 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- *  iPAQ H1940 series - latch definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_H1940_LATCH_H
-#define __ASM_ARCH_H1940_LATCH_H
-
-#include <asm/gpio.h>
-
-#define H1940_LATCH_GPIO(x)            (S3C_GPIO_END + (x))
-
-/* SD layer latch */
-
-#define H1940_LATCH_LCD_P0             H1940_LATCH_GPIO(0)
-#define H1940_LATCH_LCD_P1             H1940_LATCH_GPIO(1)
-#define H1940_LATCH_LCD_P2             H1940_LATCH_GPIO(2)
-#define H1940_LATCH_LCD_P3             H1940_LATCH_GPIO(3)
-#define H1940_LATCH_MAX1698_nSHUTDOWN  H1940_LATCH_GPIO(4)
-#define H1940_LATCH_LED_RED            H1940_LATCH_GPIO(5)
-#define H1940_LATCH_SDQ7               H1940_LATCH_GPIO(6)
-#define H1940_LATCH_USB_DP             H1940_LATCH_GPIO(7)
-
-/* CPU layer latch */
-
-#define H1940_LATCH_UDA_POWER          H1940_LATCH_GPIO(8)
-#define H1940_LATCH_AUDIO_POWER                H1940_LATCH_GPIO(9)
-#define H1940_LATCH_SM803_ENABLE       H1940_LATCH_GPIO(10)
-#define H1940_LATCH_LCD_P4             H1940_LATCH_GPIO(11)
-#define H1940_LATCH_SD_POWER           H1940_LATCH_GPIO(12)
-#define H1940_LATCH_BLUETOOTH_POWER    H1940_LATCH_GPIO(13)
-#define H1940_LATCH_LED_GREEN          H1940_LATCH_GPIO(14)
-#define H1940_LATCH_LED_FLASH          H1940_LATCH_GPIO(15)
-
-#endif /* __ASM_ARCH_H1940_LATCH_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/h1940.h b/arch/arm/mach-s3c2410/include/mach/h1940.h
deleted file mode 100644 (file)
index 2aa683c..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/h1940.h
- *
- * Copyright 2006 Ben Dooks <ben-linux@fluff.org>
- *
- * H1940 definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_H1940_H
-#define __ASM_ARCH_H1940_H
-
-#define H1940_SUSPEND_CHECKSUM         (0x30003ff8)
-#define H1940_SUSPEND_RESUMEAT         (0x30081000)
-#define H1940_SUSPEND_CHECK            (0x30080000)
-
-extern void h1940_pm_return(void);
-extern int h1940_led_blink_set(unsigned gpio, int state,
-       unsigned long *delay_on, unsigned long *delay_off);
-
-
-#endif /* __ASM_ARCH_H1940_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/hardware.h b/arch/arm/mach-s3c2410/include/mach/hardware.h
deleted file mode 100644 (file)
index aef5631..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/hardware.h
- *
- * Copyright (c) 2003 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - hardware
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-#ifndef __ASSEMBLY__
-
-extern unsigned int s3c2410_modify_misccr(unsigned int clr, unsigned int chg);
-
-#ifdef CONFIG_CPU_S3C2440
-
-extern int s3c2440_set_dsc(unsigned int pin, unsigned int value);
-
-#endif /* CONFIG_CPU_S3C2440 */
-
-#ifdef CONFIG_CPU_S3C2412
-
-extern int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state);
-
-#endif /* CONFIG_CPU_S3C2412 */
-
-#endif /* __ASSEMBLY__ */
-
-#include <asm/sizes.h>
-#include <mach/map.h>
-
-/* machine specific hardware definitions should go after this */
-
-/* currently here until moved into config (todo) */
-#define CONFIG_NO_MULTIWORD_IO
-
-#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/idle.h b/arch/arm/mach-s3c2410/include/mach/idle.h
deleted file mode 100644 (file)
index e9ddd70..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/idle.h
- *
- * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
- *             http://www.simtec.co.uk/products/SWLINUX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2410 CPU Idle controls
-*/
-
-#ifndef __ASM_ARCH_IDLE_H
-#define __ASM_ARCH_IDLE_H __FILE__
-
-/* This allows the over-ride of the default idle code, in case there
- * is any other things to be done over idle (like DVS)
-*/
-
-extern void (*s3c24xx_idle)(void);
-
-extern void s3c24xx_default_idle(void);
-
-#endif /* __ASM_ARCH_IDLE_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/io.h b/arch/arm/mach-s3c2410/include/mach/io.h
deleted file mode 100644 (file)
index 118749f..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * arch/arm/mach-s3c2410/include/mach/io.h
- *  from arch/arm/mach-rpc/include/mach/io.h
- *
- * Copyright (C) 1997 Russell King
- *          (C) 2003 Simtec Electronics
-*/
-
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-#include <mach/hardware.h>
-
-#define IO_SPACE_LIMIT 0xffffffff
-
-/*
- * We use two different types of addressing - PC style addresses, and ARM
- * addresses.  PC style accesses the PC hardware with the normal PC IO
- * addresses, eg 0x3f8 for serial#1.  ARM addresses are above A28
- * and are translated to the start of IO.  Note that all addresses are
- * not shifted left!
- */
-
-#define __PORT_PCIO(x) ((x) < (1<<28))
-
-#define PCIO_BASE       (S3C24XX_VA_ISA_WORD)
-#define PCIO_BASE_b     (S3C24XX_VA_ISA_BYTE)
-#define PCIO_BASE_w     (S3C24XX_VA_ISA_WORD)
-#define PCIO_BASE_l     (S3C24XX_VA_ISA_WORD)
-/*
- * Dynamic IO functions - let the compiler
- * optimize the expressions
- */
-
-#define DECLARE_DYN_OUT(sz,fnsuffix,instr) \
-static inline void __out##fnsuffix (unsigned int val, unsigned int port) \
-{ \
-       unsigned long temp;                                   \
-       __asm__ __volatile__(                                 \
-       "cmp    %2, #(1<<28)\n\t"                             \
-       "mov    %0, %2\n\t"                                   \
-       "addcc  %0, %0, %3\n\t"                               \
-       "str" instr " %1, [%0, #0 ]     @ out" #fnsuffix      \
-       : "=&r" (temp)                                        \
-       : "r" (val), "r" (port), "Ir" (PCIO_BASE_##fnsuffix)  \
-       : "cc");                                              \
-}
-
-
-#define DECLARE_DYN_IN(sz,fnsuffix,instr)                              \
-static inline unsigned sz __in##fnsuffix (unsigned int port)           \
-{                                                                      \
-       unsigned long temp, value;                                      \
-       __asm__ __volatile__(                                           \
-       "cmp    %2, #(1<<28)\n\t"                                       \
-       "mov    %0, %2\n\t"                                             \
-       "addcc  %0, %0, %3\n\t"                                         \
-       "ldr" instr "   %1, [%0, #0 ]   @ in" #fnsuffix         \
-       : "=&r" (temp), "=r" (value)                                    \
-       : "r" (port), "Ir" (PCIO_BASE_##fnsuffix)       \
-       : "cc");                                                        \
-       return (unsigned sz)value;                                      \
-}
-
-static inline void __iomem *__ioaddr (unsigned long port)
-{
-       return __PORT_PCIO(port) ? (PCIO_BASE + port) : (void __iomem *)port;
-}
-
-#define DECLARE_IO(sz,fnsuffix,instr)  \
-       DECLARE_DYN_IN(sz,fnsuffix,instr) \
-       DECLARE_DYN_OUT(sz,fnsuffix,instr)
-
-DECLARE_IO(char,b,"b")
-DECLARE_IO(short,w,"h")
-DECLARE_IO(int,l,"")
-
-#undef DECLARE_IO
-#undef DECLARE_DYN_IN
-
-/*
- * Constant address IO functions
- *
- * These have to be macros for the 'J' constraint to work -
- * +/-4096 immediate operand.
- */
-#define __outbc(value,port)                                            \
-({                                                                     \
-       if (__PORT_PCIO((port)))                                        \
-               __asm__ __volatile__(                                   \
-               "strb   %0, [%1, %2]    @ outbc"                        \
-               : : "r" (value), "r" (PCIO_BASE), "Jr" ((port)));       \
-       else                                                            \
-               __asm__ __volatile__(                                   \
-               "strb   %0, [%1, #0]    @ outbc"                        \
-               : : "r" (value), "r" ((port)));                         \
-})
-
-#define __inbc(port)                                                   \
-({                                                                     \
-       unsigned char result;                                           \
-       if (__PORT_PCIO((port)))                                        \
-               __asm__ __volatile__(                                   \
-               "ldrb   %0, [%1, %2]    @ inbc"                         \
-               : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port)));      \
-       else                                                            \
-               __asm__ __volatile__(                                   \
-               "ldrb   %0, [%1, #0]    @ inbc"                         \
-               : "=r" (result) : "r" ((port)));                        \
-       result;                                                         \
-})
-
-#define __outwc(value,port)                                            \
-({                                                                     \
-       unsigned long v = value;                                        \
-       if (__PORT_PCIO((port))) {                                      \
-               if ((port) < 256 && (port) > -256)                      \
-                       __asm__ __volatile__(                           \
-                       "strh   %0, [%1, %2]    @ outwc"                \
-                       : : "r" (v), "r" (PCIO_BASE), "Jr" ((port)));   \
-               else if ((port) > 0)                                    \
-                       __asm__ __volatile__(                           \
-                       "strh   %0, [%1, %2]    @ outwc"                \
-                       : : "r" (v),                                    \
-                           "r" (PCIO_BASE + ((port) & ~0xff)),         \
-                            "Jr" (((port) & 0xff)));                   \
-               else                                                    \
-                       __asm__ __volatile__(                           \
-                       "strh   %0, [%1, #0]    @ outwc"                \
-                       : : "r" (v),                                    \
-                           "r" (PCIO_BASE + (port)));                  \
-       } else                                                          \
-               __asm__ __volatile__(                                   \
-               "strh   %0, [%1, #0]    @ outwc"                        \
-               : : "r" (v), "r" ((port)));                             \
-})
-
-#define __inwc(port)                                                   \
-({                                                                     \
-       unsigned short result;                                          \
-       if (__PORT_PCIO((port))) {                                      \
-               if ((port) < 256 && (port) > -256 )                     \
-                       __asm__ __volatile__(                           \
-                       "ldrh   %0, [%1, %2]    @ inwc"                 \
-                       : "=r" (result)                                 \
-                       : "r" (PCIO_BASE),                              \
-                         "Jr" ((port)));                               \
-               else if ((port) > 0)                                    \
-                       __asm__ __volatile__(                           \
-                       "ldrh   %0, [%1, %2]    @ inwc"                 \
-                       : "=r" (result)                                 \
-                       : "r" (PCIO_BASE + ((port) & ~0xff)),           \
-                         "Jr" (((port) & 0xff)));                      \
-               else                                                    \
-                       __asm__ __volatile__(                           \
-                       "ldrh   %0, [%1, #0]    @ inwc"                 \
-                       : "=r" (result)                                 \
-                       : "r" (PCIO_BASE + ((port))));                  \
-       } else                                                          \
-               __asm__ __volatile__(                                   \
-               "ldrh   %0, [%1, #0]    @ inwc"                         \
-               : "=r" (result) : "r" ((port)));                        \
-       result;                                                         \
-})
-
-#define __outlc(value,port)                                            \
-({                                                                     \
-       unsigned long v = value;                                        \
-       if (__PORT_PCIO((port)))                                        \
-               __asm__ __volatile__(                                   \
-               "str    %0, [%1, %2]    @ outlc"                        \
-               : : "r" (v), "r" (PCIO_BASE), "Jr" ((port)));   \
-       else                                                            \
-               __asm__ __volatile__(                                   \
-               "str    %0, [%1, #0]    @ outlc"                        \
-               : : "r" (v), "r" ((port)));             \
-})
-
-#define __inlc(port)                                                   \
-({                                                                     \
-       unsigned long result;                                           \
-       if (__PORT_PCIO((port)))                                        \
-               __asm__ __volatile__(                                   \
-               "ldr    %0, [%1, %2]    @ inlc"                         \
-               : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port)));      \
-       else                                                            \
-               __asm__ __volatile__(                                   \
-               "ldr    %0, [%1, #0]    @ inlc"                         \
-               : "=r" (result) : "r" ((port)));                \
-       result;                                                         \
-})
-
-#define __ioaddrc(port)        ((__PORT_PCIO(port) ? PCIO_BASE + (port) : (void __iomem *)(port)))
-
-#define inb(p)         (__builtin_constant_p((p)) ? __inbc(p)     : __inb(p))
-#define inw(p)         (__builtin_constant_p((p)) ? __inwc(p)     : __inw(p))
-#define inl(p)         (__builtin_constant_p((p)) ? __inlc(p)     : __inl(p))
-#define outb(v,p)      (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))
-#define outw(v,p)      (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
-#define outl(v,p)      (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
-#define __ioaddr(p)    (__builtin_constant_p((p)) ? __ioaddr(p)  : __ioaddrc(p))
-
-#define insb(p,d,l)    __raw_readsb(__ioaddr(p),d,l)
-#define insw(p,d,l)    __raw_readsw(__ioaddr(p),d,l)
-#define insl(p,d,l)    __raw_readsl(__ioaddr(p),d,l)
-
-#define outsb(p,d,l)   __raw_writesb(__ioaddr(p),d,l)
-#define outsw(p,d,l)   __raw_writesw(__ioaddr(p),d,l)
-#define outsl(p,d,l)   __raw_writesl(__ioaddr(p),d,l)
-
-/*
- * 1:1 mapping for ioremapped regions.
- */
-#define __mem_pci(x)   (x)
-
-#endif
diff --git a/arch/arm/mach-s3c2410/include/mach/irqs.h b/arch/arm/mach-s3c2410/include/mach/irqs.h
deleted file mode 100644 (file)
index e53b217..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/irqs.h
- *
- * Copyright (c) 2003-2005 Simtec Electronics
- *   Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-
-#ifndef __ASM_ARCH_IRQS_H
-#define __ASM_ARCH_IRQS_H __FILE__
-
-/* we keep the first set of CPU IRQs out of the range of
- * the ISA space, so that the PC104 has them to itself
- * and we don't end up having to do horrible things to the
- * standard ISA drivers....
- */
-
-#define S3C2410_CPUIRQ_OFFSET   (16)
-
-#define S3C2410_IRQ(x) ((x) + S3C2410_CPUIRQ_OFFSET)
-
-/* main cpu interrupts */
-#define IRQ_EINT0      S3C2410_IRQ(0)      /* 16 */
-#define IRQ_EINT1      S3C2410_IRQ(1)
-#define IRQ_EINT2      S3C2410_IRQ(2)
-#define IRQ_EINT3      S3C2410_IRQ(3)
-#define IRQ_EINT4t7    S3C2410_IRQ(4)      /* 20 */
-#define IRQ_EINT8t23   S3C2410_IRQ(5)
-#define IRQ_RESERVED6  S3C2410_IRQ(6)      /* for s3c2410 */
-#define IRQ_CAM        S3C2410_IRQ(6)      /* for s3c2440,s3c2443 */
-#define IRQ_BATT_FLT   S3C2410_IRQ(7)
-#define IRQ_TICK       S3C2410_IRQ(8)      /* 24 */
-#define IRQ_WDT               S3C2410_IRQ(9)       /* WDT/AC97 for s3c2443 */
-#define IRQ_TIMER0     S3C2410_IRQ(10)
-#define IRQ_TIMER1     S3C2410_IRQ(11)
-#define IRQ_TIMER2     S3C2410_IRQ(12)
-#define IRQ_TIMER3     S3C2410_IRQ(13)
-#define IRQ_TIMER4     S3C2410_IRQ(14)
-#define IRQ_UART2      S3C2410_IRQ(15)
-#define IRQ_LCD               S3C2410_IRQ(16)      /* 32 */
-#define IRQ_DMA0       S3C2410_IRQ(17)     /* IRQ_DMA for s3c2443 */
-#define IRQ_DMA1       S3C2410_IRQ(18)
-#define IRQ_DMA2       S3C2410_IRQ(19)
-#define IRQ_DMA3       S3C2410_IRQ(20)
-#define IRQ_SDI               S3C2410_IRQ(21)
-#define IRQ_SPI0       S3C2410_IRQ(22)
-#define IRQ_UART1      S3C2410_IRQ(23)
-#define IRQ_RESERVED24 S3C2410_IRQ(24)     /* 40 */
-#define IRQ_NFCON      S3C2410_IRQ(24)     /* for s3c2440 */
-#define IRQ_USBD       S3C2410_IRQ(25)
-#define IRQ_USBH       S3C2410_IRQ(26)
-#define IRQ_IIC               S3C2410_IRQ(27)
-#define IRQ_UART0      S3C2410_IRQ(28)     /* 44 */
-#define IRQ_SPI1       S3C2410_IRQ(29)
-#define IRQ_RTC               S3C2410_IRQ(30)
-#define IRQ_ADCPARENT  S3C2410_IRQ(31)
-
-/* interrupts generated from the external interrupts sources */
-#define IRQ_EINT4      S3C2410_IRQ(32)    /* 48 */
-#define IRQ_EINT5      S3C2410_IRQ(33)
-#define IRQ_EINT6      S3C2410_IRQ(34)
-#define IRQ_EINT7      S3C2410_IRQ(35)
-#define IRQ_EINT8      S3C2410_IRQ(36)
-#define IRQ_EINT9      S3C2410_IRQ(37)
-#define IRQ_EINT10     S3C2410_IRQ(38)
-#define IRQ_EINT11     S3C2410_IRQ(39)
-#define IRQ_EINT12     S3C2410_IRQ(40)
-#define IRQ_EINT13     S3C2410_IRQ(41)
-#define IRQ_EINT14     S3C2410_IRQ(42)
-#define IRQ_EINT15     S3C2410_IRQ(43)
-#define IRQ_EINT16     S3C2410_IRQ(44)
-#define IRQ_EINT17     S3C2410_IRQ(45)
-#define IRQ_EINT18     S3C2410_IRQ(46)
-#define IRQ_EINT19     S3C2410_IRQ(47)
-#define IRQ_EINT20     S3C2410_IRQ(48)    /* 64 */
-#define IRQ_EINT21     S3C2410_IRQ(49)
-#define IRQ_EINT22     S3C2410_IRQ(50)
-#define IRQ_EINT23     S3C2410_IRQ(51)
-
-#define IRQ_EINT_BIT(x)        ((x) - IRQ_EINT4 + 4)
-#define IRQ_EINT(x)    (((x) >= 4) ? (IRQ_EINT4 + (x) - 4) : (IRQ_EINT0 + (x)))
-
-#define IRQ_LCD_FIFO   S3C2410_IRQ(52)
-#define IRQ_LCD_FRAME  S3C2410_IRQ(53)
-
-/* IRQs for the interal UARTs, and ADC
- * these need to be ordered in number of appearance in the
- * SUBSRC mask register
-*/
-
-#define S3C2410_IRQSUB(x)      S3C2410_IRQ((x)+54)
-
-#define IRQ_S3CUART_RX0                S3C2410_IRQSUB(0)       /* 70 */
-#define IRQ_S3CUART_TX0                S3C2410_IRQSUB(1)
-#define IRQ_S3CUART_ERR0       S3C2410_IRQSUB(2)
-
-#define IRQ_S3CUART_RX1                S3C2410_IRQSUB(3)       /* 73 */
-#define IRQ_S3CUART_TX1                S3C2410_IRQSUB(4)
-#define IRQ_S3CUART_ERR1       S3C2410_IRQSUB(5)
-
-#define IRQ_S3CUART_RX2                S3C2410_IRQSUB(6)       /* 76 */
-#define IRQ_S3CUART_TX2                S3C2410_IRQSUB(7)
-#define IRQ_S3CUART_ERR2       S3C2410_IRQSUB(8)
-
-#define IRQ_TC                 S3C2410_IRQSUB(9)
-#define IRQ_ADC                        S3C2410_IRQSUB(10)
-
-/* extra irqs for s3c2412 */
-
-#define IRQ_S3C2412_CFSDI      S3C2410_IRQ(21)
-
-#define IRQ_S3C2412_SDI                S3C2410_IRQSUB(13)
-#define IRQ_S3C2412_CF         S3C2410_IRQSUB(14)
-
-
-#define IRQ_S3C2416_EINT8t15   S3C2410_IRQ(5)
-#define IRQ_S3C2416_DMA                S3C2410_IRQ(17)
-#define IRQ_S3C2416_UART3      S3C2410_IRQ(18)
-#define IRQ_S3C2416_SDI1       S3C2410_IRQ(20)
-#define IRQ_S3C2416_SDI0       S3C2410_IRQ(21)
-
-#define IRQ_S3C2416_LCD2       S3C2410_IRQSUB(15)
-#define IRQ_S3C2416_LCD3       S3C2410_IRQSUB(16)
-#define IRQ_S3C2416_LCD4       S3C2410_IRQSUB(17)
-#define IRQ_S3C2416_DMA0       S3C2410_IRQSUB(18)
-#define IRQ_S3C2416_DMA1       S3C2410_IRQSUB(19)
-#define IRQ_S3C2416_DMA2       S3C2410_IRQSUB(20)
-#define IRQ_S3C2416_DMA3       S3C2410_IRQSUB(21)
-#define IRQ_S3C2416_DMA4       S3C2410_IRQSUB(22)
-#define IRQ_S3C2416_DMA5       S3C2410_IRQSUB(23)
-#define IRQ_S32416_WDT         S3C2410_IRQSUB(27)
-#define IRQ_S32416_AC97                S3C2410_IRQSUB(28)
-
-
-/* extra irqs for s3c2440 */
-
-#define IRQ_S3C2440_CAM_C      S3C2410_IRQSUB(11)      /* S3C2443 too */
-#define IRQ_S3C2440_CAM_P      S3C2410_IRQSUB(12)      /* S3C2443 too */
-#define IRQ_S3C2440_WDT                S3C2410_IRQSUB(13)
-#define IRQ_S3C2440_AC97       S3C2410_IRQSUB(14)
-
-/* irqs for s3c2443 */
-
-#define IRQ_S3C2443_DMA                S3C2410_IRQ(17)         /* IRQ_DMA1 */
-#define IRQ_S3C2443_UART3      S3C2410_IRQ(18)         /* IRQ_DMA2 */
-#define IRQ_S3C2443_CFCON      S3C2410_IRQ(19)         /* IRQ_DMA3 */
-#define IRQ_S3C2443_HSMMC      S3C2410_IRQ(20)         /* IRQ_SDI */
-#define IRQ_S3C2443_NAND       S3C2410_IRQ(24)         /* reserved */
-
-#define IRQ_S3C2416_HSMMC0     S3C2410_IRQ(21)         /* S3C2416/S3C2450 */
-
-#define IRQ_HSMMC0             IRQ_S3C2416_HSMMC0
-#define IRQ_HSMMC1             IRQ_S3C2443_HSMMC
-
-#define IRQ_S3C2443_LCD1       S3C2410_IRQSUB(14)
-#define IRQ_S3C2443_LCD2       S3C2410_IRQSUB(15)
-#define IRQ_S3C2443_LCD3       S3C2410_IRQSUB(16)
-#define IRQ_S3C2443_LCD4       S3C2410_IRQSUB(17)
-
-#define IRQ_S3C2443_DMA0       S3C2410_IRQSUB(18)
-#define IRQ_S3C2443_DMA1       S3C2410_IRQSUB(19)
-#define IRQ_S3C2443_DMA2       S3C2410_IRQSUB(20)
-#define IRQ_S3C2443_DMA3       S3C2410_IRQSUB(21)
-#define IRQ_S3C2443_DMA4       S3C2410_IRQSUB(22)
-#define IRQ_S3C2443_DMA5       S3C2410_IRQSUB(23)
-
-/* UART3 */
-#define IRQ_S3C2443_RX3                S3C2410_IRQSUB(24)
-#define IRQ_S3C2443_TX3                S3C2410_IRQSUB(25)
-#define IRQ_S3C2443_ERR3       S3C2410_IRQSUB(26)
-
-#define IRQ_S3C2443_WDT                S3C2410_IRQSUB(27)
-#define IRQ_S3C2443_AC97       S3C2410_IRQSUB(28)
-
-#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
-#define NR_IRQS (IRQ_S3C2443_AC97+1)
-#else
-#define NR_IRQS (IRQ_S3C2440_AC97+1)
-#endif
-
-/* compatibility define. */
-#define IRQ_UART3              IRQ_S3C2443_UART3
-#define IRQ_S3CUART_RX3                IRQ_S3C2443_RX3
-#define IRQ_S3CUART_TX3                IRQ_S3C2443_TX3
-#define IRQ_S3CUART_ERR3       IRQ_S3C2443_ERR3
-
-#define IRQ_LCD_VSYNC          IRQ_S3C2443_LCD3
-#define IRQ_LCD_SYSTEM         IRQ_S3C2443_LCD2
-
-#ifdef CONFIG_CPU_S3C2440
-#define IRQ_S3C244X_AC97 IRQ_S3C2440_AC97
-#else
-#define IRQ_S3C244X_AC97 IRQ_S3C2443_AC97
-#endif
-
-/* Our FIQs are routable from IRQ_EINT0 to IRQ_ADCPARENT */
-#define FIQ_START              IRQ_EINT0
-
-#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/leds-gpio.h b/arch/arm/mach-s3c2410/include/mach/leds-gpio.h
deleted file mode 100644 (file)
index d8a7672..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/leds-gpio.h
- *
- * Copyright (c) 2006 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C24XX - LEDs GPIO connector
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_LEDSGPIO_H
-#define __ASM_ARCH_LEDSGPIO_H "leds-gpio.h"
-
-#define S3C24XX_LEDF_ACTLOW    (1<<0)          /* LED is on when GPIO low */
-#define S3C24XX_LEDF_TRISTATE  (1<<1)          /* tristate to turn off */
-
-struct s3c24xx_led_platdata {
-       unsigned int             gpio;
-       unsigned int             flags;
-
-       char                    *name;
-       char                    *def_trigger;
-};
-
-#endif /* __ASM_ARCH_LEDSGPIO_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h
deleted file mode 100644 (file)
index 78ae807..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/map.h
- *
- * Copyright (c) 2003 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - Memory map definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_MAP_H
-#define __ASM_ARCH_MAP_H
-
-#include <plat/map-base.h>
-
-/*
- * S3C2410 UART offset is 0x4000 but the other SoCs are 0x400.
- * So need to define it, and here is to avoid redefinition warning.
- */
-#define S3C_UART_OFFSET                (0x4000)
-
-#include <plat/map-s3c.h>
-
-/*
- * interrupt controller is the first thing we put in, to make
- * the assembly code for the irq detection easier
- */
-#define S3C2410_PA_IRQ         (0x4A000000)
-#define S3C24XX_SZ_IRQ         SZ_1M
-
-/* memory controller registers */
-#define S3C2410_PA_MEMCTRL     (0x48000000)
-#define S3C24XX_SZ_MEMCTRL     SZ_1M
-
-/* UARTs */
-#define S3C_VA_UARTx(uart)     (S3C_VA_UART + ((uart * S3C_UART_OFFSET)))
-
-/* Timers */
-#define S3C2410_PA_TIMER       (0x51000000)
-#define S3C24XX_SZ_TIMER       SZ_1M
-
-/* Clock and Power management */
-#define S3C24XX_SZ_CLKPWR      SZ_1M
-
-/* USB Device port */
-#define S3C2410_PA_USBDEV      (0x52000000)
-#define S3C24XX_SZ_USBDEV      SZ_1M
-
-/* Watchdog */
-#define S3C2410_PA_WATCHDOG    (0x53000000)
-#define S3C24XX_SZ_WATCHDOG    SZ_1M
-
-/* Standard size definitions for peripheral blocks. */
-
-#define S3C24XX_SZ_UART                SZ_1M
-#define S3C24XX_SZ_IIS         SZ_1M
-#define S3C24XX_SZ_ADC         SZ_1M
-#define S3C24XX_SZ_SPI         SZ_1M
-#define S3C24XX_SZ_SDI         SZ_1M
-#define S3C24XX_SZ_NAND                SZ_1M
-#define S3C24XX_SZ_GPIO                SZ_1M
-
-/* USB host controller */
-#define S3C2410_PA_USBHOST (0x49000000)
-
-/* S3C2416/S3C2443/S3C2450 High-Speed USB Gadget */
-#define S3C2416_PA_HSUDC       (0x49800000)
-#define S3C2416_SZ_HSUDC       (SZ_4K)
-
-/* DMA controller */
-#define S3C2410_PA_DMA    (0x4B000000)
-#define S3C24XX_SZ_DMA    SZ_1M
-
-/* Clock and Power management */
-#define S3C2410_PA_CLKPWR  (0x4C000000)
-
-/* LCD controller */
-#define S3C2410_PA_LCD    (0x4D000000)
-#define S3C24XX_SZ_LCD    SZ_1M
-
-/* NAND flash controller */
-#define S3C2410_PA_NAND           (0x4E000000)
-
-/* IIC hardware controller */
-#define S3C2410_PA_IIC    (0x54000000)
-
-/* IIS controller */
-#define S3C2410_PA_IIS    (0x55000000)
-
-/* RTC */
-#define S3C2410_PA_RTC    (0x57000000)
-#define S3C24XX_SZ_RTC    SZ_1M
-
-/* ADC */
-#define S3C2410_PA_ADC    (0x58000000)
-
-/* SPI */
-#define S3C2410_PA_SPI    (0x59000000)
-
-/* SDI */
-#define S3C2410_PA_SDI    (0x5A000000)
-
-/* CAMIF */
-#define S3C2440_PA_CAMIF   (0x4F000000)
-#define S3C2440_SZ_CAMIF   SZ_1M
-
-/* AC97 */
-
-#define S3C2440_PA_AC97           (0x5B000000)
-#define S3C2440_SZ_AC97           SZ_1M
-
-/* S3C2443/S3C2416 High-speed SD/MMC */
-#define S3C2443_PA_HSMMC   (0x4A800000)
-#define S3C2416_PA_HSMMC0  (0x4AC00000)
-
-#define        S3C2443_PA_FB   (0x4C800000)
-
-/* S3C2412 memory and IO controls */
-#define S3C2412_PA_SSMC        (0x4F000000)
-
-#define S3C2412_PA_EBI (0x48800000)
-
-/* physical addresses of all the chip-select areas */
-
-#define S3C2410_CS0 (0x00000000)
-#define S3C2410_CS1 (0x08000000)
-#define S3C2410_CS2 (0x10000000)
-#define S3C2410_CS3 (0x18000000)
-#define S3C2410_CS4 (0x20000000)
-#define S3C2410_CS5 (0x28000000)
-#define S3C2410_CS6 (0x30000000)
-#define S3C2410_CS7 (0x38000000)
-
-#define S3C2410_SDRAM_PA    (S3C2410_CS6)
-
-/* Use a single interface for common resources between S3C24XX cpus */
-
-#define S3C24XX_PA_IRQ      S3C2410_PA_IRQ
-#define S3C24XX_PA_MEMCTRL  S3C2410_PA_MEMCTRL
-#define S3C24XX_PA_DMA      S3C2410_PA_DMA
-#define S3C24XX_PA_CLKPWR   S3C2410_PA_CLKPWR
-#define S3C24XX_PA_LCD      S3C2410_PA_LCD
-#define S3C24XX_PA_TIMER    S3C2410_PA_TIMER
-#define S3C24XX_PA_USBDEV   S3C2410_PA_USBDEV
-#define S3C24XX_PA_WATCHDOG S3C2410_PA_WATCHDOG
-#define S3C24XX_PA_IIS      S3C2410_PA_IIS
-#define S3C24XX_PA_RTC      S3C2410_PA_RTC
-#define S3C24XX_PA_ADC      S3C2410_PA_ADC
-#define S3C24XX_PA_SPI      S3C2410_PA_SPI
-#define S3C24XX_PA_SPI1                (S3C2410_PA_SPI + S3C2410_SPI1)
-#define S3C24XX_PA_SDI      S3C2410_PA_SDI
-#define S3C24XX_PA_NAND            S3C2410_PA_NAND
-
-#define S3C_PA_FB          S3C2443_PA_FB
-#define S3C_PA_IIC          S3C2410_PA_IIC
-#define S3C_PA_UART        S3C24XX_PA_UART
-#define S3C_PA_USBHOST S3C2410_PA_USBHOST
-#define S3C_PA_HSMMC0      S3C2416_PA_HSMMC0
-#define S3C_PA_HSMMC1      S3C2443_PA_HSMMC
-#define S3C_PA_WDT         S3C2410_PA_WATCHDOG
-#define S3C_PA_NAND        S3C24XX_PA_NAND
-
-#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/osiris-cpld.h b/arch/arm/mach-s3c2410/include/mach/osiris-cpld.h
deleted file mode 100644 (file)
index e9e36b0..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/osiris-cpld.h
- *
- * Copyright 2005 Simtec Electronics
- *     http://www.simtec.co.uk/products/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * OSIRIS - CPLD control constants
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_OSIRISCPLD_H
-#define __ASM_ARCH_OSIRISCPLD_H
-
-/* CTRL0 - NAND WP control */
-
-#define OSIRIS_CTRL0_NANDSEL           (0x3)
-#define OSIRIS_CTRL0_BOOT_INT          (1<<3)
-#define OSIRIS_CTRL0_PCMCIA            (1<<4)
-#define OSIRIS_CTRL0_FIX8              (1<<5)
-#define OSIRIS_CTRL0_PCMCIA_nWAIT      (1<<6)
-#define OSIRIS_CTRL0_PCMCIA_nIOIS16    (1<<7)
-
-#define OSIRIS_CTRL1_FIX8              (1<<0)
-
-#define OSIRIS_ID_REVMASK              (0x7)
-
-#endif /* __ASM_ARCH_OSIRISCPLD_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/osiris-map.h b/arch/arm/mach-s3c2410/include/mach/osiris-map.h
deleted file mode 100644 (file)
index 17380f8..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/osiris-map.h
- *
- * Copyright 2005 Simtec Electronics
- *     http://www.simtec.co.uk/products/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * OSIRIS - Memory map definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* needs arch/map.h including with this */
-
-#ifndef __ASM_ARCH_OSIRISMAP_H
-#define __ASM_ARCH_OSIRISMAP_H
-
-/* start peripherals off after the S3C2410 */
-
-#define OSIRIS_IOADDR(x)       (S3C2410_ADDR((x) + 0x04000000))
-
-#define OSIRIS_PA_CPLD         (S3C2410_CS1 | (1<<26))
-
-/* we put the CPLD registers next, to get them out of the way */
-
-#define OSIRIS_VA_CTRL0                OSIRIS_IOADDR(0x00000000)
-#define OSIRIS_PA_CTRL0                (OSIRIS_PA_CPLD)
-
-#define OSIRIS_VA_CTRL1                OSIRIS_IOADDR(0x00100000)
-#define OSIRIS_PA_CTRL1                (OSIRIS_PA_CPLD + (1<<23))
-
-#define OSIRIS_VA_CTRL2                OSIRIS_IOADDR(0x00200000)
-#define OSIRIS_PA_CTRL2                (OSIRIS_PA_CPLD + (2<<23))
-
-#define OSIRIS_VA_CTRL3                OSIRIS_IOADDR(0x00300000)
-#define OSIRIS_PA_CTRL3                (OSIRIS_PA_CPLD + (2<<23))
-
-#define OSIRIS_VA_IDREG                OSIRIS_IOADDR(0x00700000)
-#define OSIRIS_PA_IDREG                (OSIRIS_PA_CPLD + (7<<23))
-
-#endif /* __ASM_ARCH_OSIRISMAP_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/otom-map.h b/arch/arm/mach-s3c2410/include/mach/otom-map.h
deleted file mode 100644 (file)
index f9277a5..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/otom-map.h
- *
- * (c) 2005 Guillaume GOURAT / NexVision
- *          guillaume.gourat@nexvision.fr
- *
- * NexVision OTOM board memory map definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* needs arch/map.h including with this */
-
-/* ok, we've used up to 0x01300000, now we need to find space for the
- * peripherals that live in the nGCS[x] areas, which are quite numerous
- * in their space.
- */
-
-#ifndef __ASM_ARCH_OTOMMAP_H
-#define __ASM_ARCH_OTOMMAP_H
-
-#define OTOM_PA_CS8900A_BASE       (S3C2410_CS3 + 0x01000000)  /* nGCS3 +0x01000000 */
-#define OTOM_VA_CS8900A_BASE       S3C2410_ADDR(0x04000000)            /* 0xF4000000 */
-
-/* physical offset addresses for the peripherals */
-
-#define OTOM_PA_FLASH0_BASE        (S3C2410_CS0)                               /* Bank 0 */
-
-#endif /* __ASM_ARCH_OTOMMAP_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/pm-core.h b/arch/arm/mach-s3c2410/include/mach/pm-core.h
deleted file mode 100644 (file)
index 2eef7e6..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/include/pm-core.h
- *
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C24xx - PM core support for arch/arm/plat-s3c/pm.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-static inline void s3c_pm_debug_init_uart(void)
-{
-       unsigned long tmp = __raw_readl(S3C2410_CLKCON);
-
-       /* re-start uart clocks */
-       tmp |= S3C2410_CLKCON_UART0;
-       tmp |= S3C2410_CLKCON_UART1;
-       tmp |= S3C2410_CLKCON_UART2;
-
-       __raw_writel(tmp, S3C2410_CLKCON);
-       udelay(10);
-}
-
-static inline void s3c_pm_arch_prepare_irqs(void)
-{
-       __raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);
-       __raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK);
-
-       /* ack any outstanding external interrupts before we go to sleep */
-
-       __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
-       __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
-       __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
-
-}
-
-static inline void s3c_pm_arch_stop_clocks(void)
-{
-       __raw_writel(0x00, S3C2410_CLKCON);  /* turn off clocks over sleep */
-}
-
-static void s3c_pm_show_resume_irqs(int start, unsigned long which,
-                                   unsigned long mask);
-
-static inline void s3c_pm_arch_show_resume_irqs(void)
-{
-       S3C_PMDBG("post sleep: IRQs 0x%08x, 0x%08x\n",
-                 __raw_readl(S3C2410_SRCPND),
-                 __raw_readl(S3C2410_EINTPEND));
-
-       s3c_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
-                               s3c_irqwake_intmask);
-
-       s3c_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
-                               s3c_irqwake_eintmask);
-}
-
-static inline void s3c_pm_arch_update_uart(void __iomem *regs,
-                                          struct pm_uart_save *save)
-{
-}
-
-static inline void s3c_pm_restored_gpios(void) { }
-static inline void samsung_pm_saved_gpios(void) { }
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-clock.h
deleted file mode 100644 (file)
index 3415b60..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-clock.h
- *
- * Copyright (c) 2003-2006 Simtec Electronics <linux@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2410 clock register definitions
-*/
-
-#ifndef __ASM_ARM_REGS_CLOCK
-#define __ASM_ARM_REGS_CLOCK
-
-#define S3C2410_CLKREG(x) ((x) + S3C24XX_VA_CLKPWR)
-
-#define S3C2410_PLLVAL(_m,_p,_s) ((_m) << 12 | ((_p) << 4) | ((_s)))
-
-#define S3C2410_LOCKTIME    S3C2410_CLKREG(0x00)
-#define S3C2410_MPLLCON            S3C2410_CLKREG(0x04)
-#define S3C2410_UPLLCON            S3C2410_CLKREG(0x08)
-#define S3C2410_CLKCON     S3C2410_CLKREG(0x0C)
-#define S3C2410_CLKSLOW            S3C2410_CLKREG(0x10)
-#define S3C2410_CLKDIVN            S3C2410_CLKREG(0x14)
-
-#define S3C2410_CLKCON_IDLE         (1<<2)
-#define S3C2410_CLKCON_POWER        (1<<3)
-#define S3C2410_CLKCON_NAND         (1<<4)
-#define S3C2410_CLKCON_LCDC         (1<<5)
-#define S3C2410_CLKCON_USBH         (1<<6)
-#define S3C2410_CLKCON_USBD         (1<<7)
-#define S3C2410_CLKCON_PWMT         (1<<8)
-#define S3C2410_CLKCON_SDI          (1<<9)
-#define S3C2410_CLKCON_UART0        (1<<10)
-#define S3C2410_CLKCON_UART1        (1<<11)
-#define S3C2410_CLKCON_UART2        (1<<12)
-#define S3C2410_CLKCON_GPIO         (1<<13)
-#define S3C2410_CLKCON_RTC          (1<<14)
-#define S3C2410_CLKCON_ADC          (1<<15)
-#define S3C2410_CLKCON_IIC          (1<<16)
-#define S3C2410_CLKCON_IIS          (1<<17)
-#define S3C2410_CLKCON_SPI          (1<<18)
-
-/* DCLKCON register addresses in gpio.h */
-
-#define S3C2410_DCLKCON_DCLK0EN             (1<<0)
-#define S3C2410_DCLKCON_DCLK0_PCLK   (0<<1)
-#define S3C2410_DCLKCON_DCLK0_UCLK   (1<<1)
-#define S3C2410_DCLKCON_DCLK0_DIV(x) (((x) - 1 )<<4)
-#define S3C2410_DCLKCON_DCLK0_CMP(x) (((x) - 1 )<<8)
-#define S3C2410_DCLKCON_DCLK0_DIV_MASK ((0xf)<<4)
-#define S3C2410_DCLKCON_DCLK0_CMP_MASK ((0xf)<<8)
-
-#define S3C2410_DCLKCON_DCLK1EN             (1<<16)
-#define S3C2410_DCLKCON_DCLK1_PCLK   (0<<17)
-#define S3C2410_DCLKCON_DCLK1_UCLK   (1<<17)
-#define S3C2410_DCLKCON_DCLK1_DIV(x) (((x) - 1) <<20)
-#define S3C2410_DCLKCON_DCLK1_CMP(x) (((x) - 1) <<24)
-#define S3C2410_DCLKCON_DCLK1_DIV_MASK ((0xf) <<20)
-#define S3C2410_DCLKCON_DCLK1_CMP_MASK ((0xf) <<24)
-
-#define S3C2410_CLKDIVN_PDIVN       (1<<0)
-#define S3C2410_CLKDIVN_HDIVN       (1<<1)
-
-#define S3C2410_CLKSLOW_UCLK_OFF       (1<<7)
-#define S3C2410_CLKSLOW_MPLL_OFF       (1<<5)
-#define S3C2410_CLKSLOW_SLOW           (1<<4)
-#define S3C2410_CLKSLOW_SLOWVAL(x)     (x)
-#define S3C2410_CLKSLOW_GET_SLOWVAL(x) ((x) & 7)
-
-#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
-
-/* extra registers */
-#define S3C2440_CAMDIVN            S3C2410_CLKREG(0x18)
-
-#define S3C2440_CLKCON_CAMERA        (1<<19)
-#define S3C2440_CLKCON_AC97          (1<<20)
-
-#define S3C2440_CLKDIVN_PDIVN       (1<<0)
-#define S3C2440_CLKDIVN_HDIVN_MASK   (3<<1)
-#define S3C2440_CLKDIVN_HDIVN_1      (0<<1)
-#define S3C2440_CLKDIVN_HDIVN_2      (1<<1)
-#define S3C2440_CLKDIVN_HDIVN_4_8    (2<<1)
-#define S3C2440_CLKDIVN_HDIVN_3_6    (3<<1)
-#define S3C2440_CLKDIVN_UCLK         (1<<3)
-
-#define S3C2440_CAMDIVN_CAMCLK_MASK  (0xf<<0)
-#define S3C2440_CAMDIVN_CAMCLK_SEL   (1<<4)
-#define S3C2440_CAMDIVN_HCLK3_HALF   (1<<8)
-#define S3C2440_CAMDIVN_HCLK4_HALF   (1<<9)
-#define S3C2440_CAMDIVN_DVSEN        (1<<12)
-
-#define S3C2442_CAMDIVN_CAMCLK_DIV3  (1<<5)
-
-#endif /* CONFIG_CPU_S3C2440 or CONFIG_CPU_S3C2442 */
-
-#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
-
-#define S3C2412_OSCSET         S3C2410_CLKREG(0x18)
-#define S3C2412_CLKSRC         S3C2410_CLKREG(0x1C)
-
-#define S3C2412_PLLCON_OFF             (1<<20)
-
-#define S3C2412_CLKDIVN_PDIVN          (1<<2)
-#define S3C2412_CLKDIVN_HDIVN_MASK     (3<<0)
-#define S3C2412_CLKDIVN_ARMDIVN                (1<<3)
-#define S3C2412_CLKDIVN_DVSEN          (1<<4)
-#define S3C2412_CLKDIVN_HALFHCLK       (1<<5)
-#define S3C2412_CLKDIVN_USB48DIV       (1<<6)
-#define S3C2412_CLKDIVN_UARTDIV_MASK   (15<<8)
-#define S3C2412_CLKDIVN_UARTDIV_SHIFT  (8)
-#define S3C2412_CLKDIVN_I2SDIV_MASK    (15<<12)
-#define S3C2412_CLKDIVN_I2SDIV_SHIFT   (12)
-#define S3C2412_CLKDIVN_CAMDIV_MASK    (15<<16)
-#define S3C2412_CLKDIVN_CAMDIV_SHIFT   (16)
-
-#define S3C2412_CLKCON_WDT             (1<<28)
-#define S3C2412_CLKCON_SPI             (1<<27)
-#define S3C2412_CLKCON_IIS             (1<<26)
-#define S3C2412_CLKCON_IIC             (1<<25)
-#define S3C2412_CLKCON_ADC             (1<<24)
-#define S3C2412_CLKCON_RTC             (1<<23)
-#define S3C2412_CLKCON_GPIO            (1<<22)
-#define S3C2412_CLKCON_UART2           (1<<21)
-#define S3C2412_CLKCON_UART1           (1<<20)
-#define S3C2412_CLKCON_UART0           (1<<19)
-#define S3C2412_CLKCON_SDI             (1<<18)
-#define S3C2412_CLKCON_PWMT            (1<<17)
-#define S3C2412_CLKCON_USBD            (1<<16)
-#define S3C2412_CLKCON_CAMCLK          (1<<15)
-#define S3C2412_CLKCON_UARTCLK         (1<<14)
-/* missing 13 */
-#define S3C2412_CLKCON_USB_HOST48      (1<<12)
-#define S3C2412_CLKCON_USB_DEV48       (1<<11)
-#define S3C2412_CLKCON_HCLKdiv2                (1<<10)
-#define S3C2412_CLKCON_HCLKx2          (1<<9)
-#define S3C2412_CLKCON_SDRAM           (1<<8)
-/* missing 7 */
-#define S3C2412_CLKCON_USBH            S3C2410_CLKCON_USBH
-#define S3C2412_CLKCON_LCDC            S3C2410_CLKCON_LCDC
-#define S3C2412_CLKCON_NAND            S3C2410_CLKCON_NAND
-#define S3C2412_CLKCON_DMA3            (1<<3)
-#define S3C2412_CLKCON_DMA2            (1<<2)
-#define S3C2412_CLKCON_DMA1            (1<<1)
-#define S3C2412_CLKCON_DMA0            (1<<0)
-
-/* clock sourec controls */
-
-#define S3C2412_CLKSRC_EXTCLKDIV_MASK          (7 << 0)
-#define S3C2412_CLKSRC_EXTCLKDIV_SHIFT         (0)
-#define S3C2412_CLKSRC_MDIVCLK_EXTCLKDIV       (1<<3)
-#define S3C2412_CLKSRC_MSYSCLK_MPLL            (1<<4)
-#define S3C2412_CLKSRC_USYSCLK_UPLL            (1<<5)
-#define S3C2412_CLKSRC_UARTCLK_MPLL            (1<<8)
-#define S3C2412_CLKSRC_I2SCLK_MPLL             (1<<9)
-#define S3C2412_CLKSRC_USBCLK_HCLK             (1<<10)
-#define S3C2412_CLKSRC_CAMCLK_HCLK             (1<<11)
-#define S3C2412_CLKSRC_UREFCLK_EXTCLK  (1<<12)
-#define S3C2412_CLKSRC_EREFCLK_EXTCLK  (1<<14)
-
-#endif /* CONFIG_CPU_S3C2412 | CONFIG_CPU_S3C2413 */
-
-#define S3C2416_CLKDIV2                S3C2410_CLKREG(0x28)
-
-#endif /* __ASM_ARM_REGS_CLOCK */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-dsc.h b/arch/arm/mach-s3c2410/include/mach/regs-dsc.h
deleted file mode 100644 (file)
index 98fd4a0..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-dsc.h
- *
- * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
- *                   http://www.simtec.co.uk/products/SWLINUX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2440/S3C2412 Signal Drive Strength Control
-*/
-
-
-#ifndef __ASM_ARCH_REGS_DSC_H
-#define __ASM_ARCH_REGS_DSC_H "2440-dsc"
-
-#if defined(CONFIG_CPU_S3C2412)
-#define S3C2412_DSC0      S3C2410_GPIOREG(0xdc)
-#define S3C2412_DSC1      S3C2410_GPIOREG(0xe0)
-#endif
-
-#if defined(CONFIG_CPU_S3C2416)
-#define S3C2416_DSC0      S3C2410_GPIOREG(0xc0)
-#define S3C2416_DSC1      S3C2410_GPIOREG(0xc4)
-#define S3C2416_DSC2      S3C2410_GPIOREG(0xc8)
-#define S3C2416_DSC3      S3C2410_GPIOREG(0x110)
-
-#define S3C2416_SELECT_DSC0    (0 << 30)
-#define S3C2416_SELECT_DSC1    (1 << 30)
-#define S3C2416_SELECT_DSC2    (2 << 30)
-#define S3C2416_SELECT_DSC3    (3 << 30)
-
-#define S3C2416_DSC_GETSHIFT(x)        (x & 30)
-
-#define S3C2416_DSC0_CF                (S3C2416_SELECT_DSC0 | 28)
-#define        S3C2416_DSC0_CF_5mA     (0 << 28)
-#define        S3C2416_DSC0_CF_10mA    (1 << 28)
-#define        S3C2416_DSC0_CF_15mA    (2 << 28)
-#define        S3C2416_DSC0_CF_21mA    (3 << 28)
-#define        S3C2416_DSC0_CF_MASK    (3 << 28)
-
-#define S3C2416_DSC0_nRBE      (S3C2416_SELECT_DSC0 | 26)
-#define        S3C2416_DSC0_nRBE_5mA   (0 << 26)
-#define        S3C2416_DSC0_nRBE_10mA  (1 << 26)
-#define        S3C2416_DSC0_nRBE_15mA  (2 << 26)
-#define        S3C2416_DSC0_nRBE_21mA  (3 << 26)
-#define        S3C2416_DSC0_nRBE_MASK  (3 << 26)
-
-#define S3C2416_DSC0_nROE      (S3C2416_SELECT_DSC0 | 24)
-#define        S3C2416_DSC0_nROE_5mA   (0 << 24)
-#define        S3C2416_DSC0_nROE_10mA  (1 << 24)
-#define        S3C2416_DSC0_nROE_15mA  (2 << 24)
-#define        S3C2416_DSC0_nROE_21mA  (3 << 24)
-#define        S3C2416_DSC0_nROE_MASK  (3 << 24)
-
-#endif
-
-#if defined(CONFIG_CPU_S3C244X)
-
-#define S3C2440_DSC0      S3C2410_GPIOREG(0xc4)
-#define S3C2440_DSC1      S3C2410_GPIOREG(0xc8)
-
-#define S3C2440_SELECT_DSC0 (0)
-#define S3C2440_SELECT_DSC1 (1<<31)
-
-#define S3C2440_DSC_GETSHIFT(x) ((x) & 31)
-
-#define S3C2440_DSC0_DISABLE   (1<<31)
-
-#define S3C2440_DSC0_ADDR       (S3C2440_SELECT_DSC0 | 8)
-#define S3C2440_DSC0_ADDR_12mA  (0<<8)
-#define S3C2440_DSC0_ADDR_10mA  (1<<8)
-#define S3C2440_DSC0_ADDR_8mA   (2<<8)
-#define S3C2440_DSC0_ADDR_6mA   (3<<8)
-#define S3C2440_DSC0_ADDR_MASK  (3<<8)
-
-/* D24..D31 */
-#define S3C2440_DSC0_DATA3      (S3C2440_SELECT_DSC0 | 6)
-#define S3C2440_DSC0_DATA3_12mA (0<<6)
-#define S3C2440_DSC0_DATA3_10mA (1<<6)
-#define S3C2440_DSC0_DATA3_8mA  (2<<6)
-#define S3C2440_DSC0_DATA3_6mA  (3<<6)
-#define S3C2440_DSC0_DATA3_MASK (3<<6)
-
-/* D16..D23 */
-#define S3C2440_DSC0_DATA2      (S3C2440_SELECT_DSC0 | 4)
-#define S3C2440_DSC0_DATA2_12mA (0<<4)
-#define S3C2440_DSC0_DATA2_10mA (1<<4)
-#define S3C2440_DSC0_DATA2_8mA  (2<<4)
-#define S3C2440_DSC0_DATA2_6mA  (3<<4)
-#define S3C2440_DSC0_DATA2_MASK (3<<4)
-
-/* D8..D15 */
-#define S3C2440_DSC0_DATA1      (S3C2440_SELECT_DSC0 | 2)
-#define S3C2440_DSC0_DATA1_12mA (0<<2)
-#define S3C2440_DSC0_DATA1_10mA (1<<2)
-#define S3C2440_DSC0_DATA1_8mA  (2<<2)
-#define S3C2440_DSC0_DATA1_6mA  (3<<2)
-#define S3C2440_DSC0_DATA1_MASK (3<<2)
-
-/* D0..D7 */
-#define S3C2440_DSC0_DATA0      (S3C2440_SELECT_DSC0 | 0)
-#define S3C2440_DSC0_DATA0_12mA (0<<0)
-#define S3C2440_DSC0_DATA0_10mA (1<<0)
-#define S3C2440_DSC0_DATA0_8mA  (2<<0)
-#define S3C2440_DSC0_DATA0_6mA  (3<<0)
-#define S3C2440_DSC0_DATA0_MASK (3<<0)
-
-#define S3C2440_DSC1_SCK1       (S3C2440_SELECT_DSC1 | 28)
-#define S3C2440_DSC1_SCK1_12mA  (0<<28)
-#define S3C2440_DSC1_SCK1_10mA  (1<<28)
-#define S3C2440_DSC1_SCK1_8mA   (2<<28)
-#define S3C2440_DSC1_SCK1_6mA   (3<<28)
-#define S3C2440_DSC1_SCK1_MASK  (3<<28)
-
-#define S3C2440_DSC1_SCK0       (S3C2440_SELECT_DSC1 | 26)
-#define S3C2440_DSC1_SCK0_12mA  (0<<26)
-#define S3C2440_DSC1_SCK0_10mA  (1<<26)
-#define S3C2440_DSC1_SCK0_8mA   (2<<26)
-#define S3C2440_DSC1_SCK0_6mA   (3<<26)
-#define S3C2440_DSC1_SCK0_MASK  (3<<26)
-
-#define S3C2440_DSC1_SCKE       (S3C2440_SELECT_DSC1 | 24)
-#define S3C2440_DSC1_SCKE_10mA  (0<<24)
-#define S3C2440_DSC1_SCKE_8mA   (1<<24)
-#define S3C2440_DSC1_SCKE_6mA   (2<<24)
-#define S3C2440_DSC1_SCKE_4mA   (3<<24)
-#define S3C2440_DSC1_SCKE_MASK  (3<<24)
-
-/* SDRAM nRAS/nCAS */
-#define S3C2440_DSC1_SDR        (S3C2440_SELECT_DSC1 | 22)
-#define S3C2440_DSC1_SDR_10mA   (0<<22)
-#define S3C2440_DSC1_SDR_8mA    (1<<22)
-#define S3C2440_DSC1_SDR_6mA    (2<<22)
-#define S3C2440_DSC1_SDR_4mA    (3<<22)
-#define S3C2440_DSC1_SDR_MASK   (3<<22)
-
-/* NAND Flash Controller */
-#define S3C2440_DSC1_NFC        (S3C2440_SELECT_DSC1 | 20)
-#define S3C2440_DSC1_NFC_10mA   (0<<20)
-#define S3C2440_DSC1_NFC_8mA    (1<<20)
-#define S3C2440_DSC1_NFC_6mA    (2<<20)
-#define S3C2440_DSC1_NFC_4mA    (3<<20)
-#define S3C2440_DSC1_NFC_MASK   (3<<20)
-
-/* nBE[0..3] */
-#define S3C2440_DSC1_nBE        (S3C2440_SELECT_DSC1 | 18)
-#define S3C2440_DSC1_nBE_10mA   (0<<18)
-#define S3C2440_DSC1_nBE_8mA    (1<<18)
-#define S3C2440_DSC1_nBE_6mA    (2<<18)
-#define S3C2440_DSC1_nBE_4mA    (3<<18)
-#define S3C2440_DSC1_nBE_MASK   (3<<18)
-
-#define S3C2440_DSC1_WOE        (S3C2440_SELECT_DSC1 | 16)
-#define S3C2440_DSC1_WOE_10mA   (0<<16)
-#define S3C2440_DSC1_WOE_8mA    (1<<16)
-#define S3C2440_DSC1_WOE_6mA    (2<<16)
-#define S3C2440_DSC1_WOE_4mA    (3<<16)
-#define S3C2440_DSC1_WOE_MASK   (3<<16)
-
-#define S3C2440_DSC1_CS7        (S3C2440_SELECT_DSC1 | 14)
-#define S3C2440_DSC1_CS7_10mA   (0<<14)
-#define S3C2440_DSC1_CS7_8mA    (1<<14)
-#define S3C2440_DSC1_CS7_6mA    (2<<14)
-#define S3C2440_DSC1_CS7_4mA    (3<<14)
-#define S3C2440_DSC1_CS7_MASK   (3<<14)
-
-#define S3C2440_DSC1_CS6        (S3C2440_SELECT_DSC1 | 12)
-#define S3C2440_DSC1_CS6_10mA   (0<<12)
-#define S3C2440_DSC1_CS6_8mA    (1<<12)
-#define S3C2440_DSC1_CS6_6mA    (2<<12)
-#define S3C2440_DSC1_CS6_4mA    (3<<12)
-#define S3C2440_DSC1_CS6_MASK   (3<<12)
-
-#define S3C2440_DSC1_CS5        (S3C2440_SELECT_DSC1 | 10)
-#define S3C2440_DSC1_CS5_10mA   (0<<10)
-#define S3C2440_DSC1_CS5_8mA    (1<<10)
-#define S3C2440_DSC1_CS5_6mA    (2<<10)
-#define S3C2440_DSC1_CS5_4mA    (3<<10)
-#define S3C2440_DSC1_CS5_MASK   (3<<10)
-
-#define S3C2440_DSC1_CS4        (S3C2440_SELECT_DSC1 | 8)
-#define S3C2440_DSC1_CS4_10mA   (0<<8)
-#define S3C2440_DSC1_CS4_8mA    (1<<8)
-#define S3C2440_DSC1_CS4_6mA    (2<<8)
-#define S3C2440_DSC1_CS4_4mA    (3<<8)
-#define S3C2440_DSC1_CS4_MASK   (3<<8)
-
-#define S3C2440_DSC1_CS3        (S3C2440_SELECT_DSC1 | 6)
-#define S3C2440_DSC1_CS3_10mA   (0<<6)
-#define S3C2440_DSC1_CS3_8mA    (1<<6)
-#define S3C2440_DSC1_CS3_6mA    (2<<6)
-#define S3C2440_DSC1_CS3_4mA    (3<<6)
-#define S3C2440_DSC1_CS3_MASK   (3<<6)
-
-#define S3C2440_DSC1_CS2        (S3C2440_SELECT_DSC1 | 4)
-#define S3C2440_DSC1_CS2_10mA   (0<<4)
-#define S3C2440_DSC1_CS2_8mA    (1<<4)
-#define S3C2440_DSC1_CS2_6mA    (2<<4)
-#define S3C2440_DSC1_CS2_4mA    (3<<4)
-#define S3C2440_DSC1_CS2_MASK   (3<<4)
-
-#define S3C2440_DSC1_CS1        (S3C2440_SELECT_DSC1 | 2)
-#define S3C2440_DSC1_CS1_10mA   (0<<2)
-#define S3C2440_DSC1_CS1_8mA    (1<<2)
-#define S3C2440_DSC1_CS1_6mA    (2<<2)
-#define S3C2440_DSC1_CS1_4mA    (3<<2)
-#define S3C2440_DSC1_CS1_MASK   (3<<2)
-
-#define S3C2440_DSC1_CS0        (S3C2440_SELECT_DSC1 | 0)
-#define S3C2440_DSC1_CS0_10mA   (0<<0)
-#define S3C2440_DSC1_CS0_8mA    (1<<0)
-#define S3C2440_DSC1_CS0_6mA    (2<<0)
-#define S3C2440_DSC1_CS0_4mA    (3<<0)
-#define S3C2440_DSC1_CS0_MASK   (3<<0)
-
-#endif /* CONFIG_CPU_S3C2440 */
-
-#endif /* __ASM_ARCH_REGS_DSC_H */
-
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
deleted file mode 100644 (file)
index cac1ad6..0000000
+++ /dev/null
@@ -1,602 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-gpio.h
- *
- * Copyright (c) 2003-2004 Simtec Electronics <linux@simtec.co.uk>
- *     http://www.simtec.co.uk/products/SWLINUX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2410 GPIO register definitions
-*/
-
-
-#ifndef __ASM_ARCH_REGS_GPIO_H
-#define __ASM_ARCH_REGS_GPIO_H
-
-#include <mach/gpio-nrs.h>
-
-#define S3C24XX_MISCCR         S3C24XX_GPIOREG2(0x80)
-
-/* general configuration options */
-
-#define S3C2410_GPIO_LEAVE   (0xFFFFFFFF)
-#define S3C2410_GPIO_INPUT   (0xFFFFFFF0)      /* not available on A */
-#define S3C2410_GPIO_OUTPUT  (0xFFFFFFF1)
-#define S3C2410_GPIO_IRQ     (0xFFFFFFF2)      /* not available for all */
-#define S3C2410_GPIO_SFN2    (0xFFFFFFF2)      /* bank A => addr/cs/nand */
-#define S3C2410_GPIO_SFN3    (0xFFFFFFF3)      /* not available on A */
-
-/* register address for the GPIO registers.
- * S3C24XX_GPIOREG2 is for the second set of registers in the
- * GPIO which move between s3c2410 and s3c2412 type systems */
-
-#define S3C2410_GPIOREG(x) ((x) + S3C24XX_VA_GPIO)
-#define S3C24XX_GPIOREG2(x) ((x) + S3C24XX_VA_GPIO2)
-
-
-/* configure GPIO ports A..G */
-
-/* port A - S3C2410: 22bits, zero in bit X makes pin X output
- * 1 makes port special function, this is default
-*/
-#define S3C2410_GPACON    S3C2410_GPIOREG(0x00)
-#define S3C2410_GPADAT    S3C2410_GPIOREG(0x04)
-
-#define S3C2410_GPA0_ADDR0   (1<<0)
-#define S3C2410_GPA1_ADDR16  (1<<1)
-#define S3C2410_GPA2_ADDR17  (1<<2)
-#define S3C2410_GPA3_ADDR18  (1<<3)
-#define S3C2410_GPA4_ADDR19  (1<<4)
-#define S3C2410_GPA5_ADDR20  (1<<5)
-#define S3C2410_GPA6_ADDR21  (1<<6)
-#define S3C2410_GPA7_ADDR22  (1<<7)
-#define S3C2410_GPA8_ADDR23  (1<<8)
-#define S3C2410_GPA9_ADDR24  (1<<9)
-#define S3C2410_GPA10_ADDR25 (1<<10)
-#define S3C2410_GPA11_ADDR26 (1<<11)
-#define S3C2410_GPA12_nGCS1  (1<<12)
-#define S3C2410_GPA13_nGCS2  (1<<13)
-#define S3C2410_GPA14_nGCS3  (1<<14)
-#define S3C2410_GPA15_nGCS4  (1<<15)
-#define S3C2410_GPA16_nGCS5  (1<<16)
-#define S3C2410_GPA17_CLE    (1<<17)
-#define S3C2410_GPA18_ALE    (1<<18)
-#define S3C2410_GPA19_nFWE   (1<<19)
-#define S3C2410_GPA20_nFRE   (1<<20)
-#define S3C2410_GPA21_nRSTOUT (1<<21)
-#define S3C2410_GPA22_nFCE   (1<<22)
-
-/* 0x08 and 0x0c are reserved on S3C2410 */
-
-/* S3C2410:
- * GPB is 10 IO pins, each configured by 2 bits each in GPBCON.
- *   00 = input, 01 = output, 10=special function, 11=reserved
-
- * bit 0,1 = pin 0, 2,3= pin 1...
- *
- * CPBUP = pull up resistor control, 1=disabled, 0=enabled
-*/
-
-#define S3C2410_GPBCON    S3C2410_GPIOREG(0x10)
-#define S3C2410_GPBDAT    S3C2410_GPIOREG(0x14)
-#define S3C2410_GPBUP     S3C2410_GPIOREG(0x18)
-
-/* no i/o pin in port b can have value 3 (unless it is a s3c2443) ! */
-
-#define S3C2410_GPB0_TOUT0   (0x02 << 0)
-
-#define S3C2410_GPB1_TOUT1   (0x02 << 2)
-
-#define S3C2410_GPB2_TOUT2   (0x02 << 4)
-
-#define S3C2410_GPB3_TOUT3   (0x02 << 6)
-
-#define S3C2410_GPB4_TCLK0   (0x02 << 8)
-#define S3C2410_GPB4_MASK    (0x03 << 8)
-
-#define S3C2410_GPB5_nXBACK  (0x02 << 10)
-#define S3C2443_GPB5_XBACK   (0x03 << 10)
-
-#define S3C2410_GPB6_nXBREQ  (0x02 << 12)
-#define S3C2443_GPB6_XBREQ   (0x03 << 12)
-
-#define S3C2410_GPB7_nXDACK1 (0x02 << 14)
-#define S3C2443_GPB7_XDACK1  (0x03 << 14)
-
-#define S3C2410_GPB8_nXDREQ1 (0x02 << 16)
-
-#define S3C2410_GPB9_nXDACK0 (0x02 << 18)
-#define S3C2443_GPB9_XDACK0  (0x03 << 18)
-
-#define S3C2410_GPB10_nXDRE0 (0x02 << 20)
-#define S3C2443_GPB10_XDREQ0 (0x03 << 20)
-
-#define S3C2410_GPB_PUPDIS(x)  (1<<(x))
-
-/* Port C consits of 16 GPIO/Special function
- *
- * almost identical setup to port b, but the special functions are mostly
- * to do with the video system's sync/etc.
-*/
-
-#define S3C2410_GPCCON    S3C2410_GPIOREG(0x20)
-#define S3C2410_GPCDAT    S3C2410_GPIOREG(0x24)
-#define S3C2410_GPCUP     S3C2410_GPIOREG(0x28)
-#define S3C2410_GPC0_LEND      (0x02 << 0)
-#define S3C2410_GPC1_VCLK      (0x02 << 2)
-#define S3C2410_GPC2_VLINE     (0x02 << 4)
-#define S3C2410_GPC3_VFRAME    (0x02 << 6)
-#define S3C2410_GPC4_VM                (0x02 << 8)
-#define S3C2410_GPC5_LCDVF0    (0x02 << 10)
-#define S3C2410_GPC6_LCDVF1    (0x02 << 12)
-#define S3C2410_GPC7_LCDVF2    (0x02 << 14)
-#define S3C2410_GPC8_VD0       (0x02 << 16)
-#define S3C2410_GPC9_VD1       (0x02 << 18)
-#define S3C2410_GPC10_VD2      (0x02 << 20)
-#define S3C2410_GPC11_VD3      (0x02 << 22)
-#define S3C2410_GPC12_VD4      (0x02 << 24)
-#define S3C2410_GPC13_VD5      (0x02 << 26)
-#define S3C2410_GPC14_VD6      (0x02 << 28)
-#define S3C2410_GPC15_VD7      (0x02 << 30)
-#define S3C2410_GPC_PUPDIS(x)  (1<<(x))
-
-/*
- * S3C2410: Port D consists of 16 GPIO/Special function
- *
- * almost identical setup to port b, but the special functions are mostly
- * to do with the video system's data.
- *
- * almost identical setup to port c
-*/
-
-#define S3C2410_GPDCON    S3C2410_GPIOREG(0x30)
-#define S3C2410_GPDDAT    S3C2410_GPIOREG(0x34)
-#define S3C2410_GPDUP     S3C2410_GPIOREG(0x38)
-
-#define S3C2410_GPD0_VD8       (0x02 << 0)
-#define S3C2442_GPD0_nSPICS1   (0x03 << 0)
-
-#define S3C2410_GPD1_VD9       (0x02 << 2)
-#define S3C2442_GPD1_SPICLK1   (0x03 << 2)
-
-#define S3C2410_GPD2_VD10      (0x02 << 4)
-
-#define S3C2410_GPD3_VD11      (0x02 << 6)
-
-#define S3C2410_GPD4_VD12      (0x02 << 8)
-
-#define S3C2410_GPD5_VD13      (0x02 << 10)
-
-#define S3C2410_GPD6_VD14      (0x02 << 12)
-
-#define S3C2410_GPD7_VD15      (0x02 << 14)
-
-#define S3C2410_GPD8_VD16      (0x02 << 16)
-#define S3C2440_GPD8_SPIMISO1  (0x03 << 16)
-
-#define S3C2410_GPD9_VD17      (0x02 << 18)
-#define S3C2440_GPD9_SPIMOSI1  (0x03 << 18)
-
-#define S3C2410_GPD10_VD18     (0x02 << 20)
-#define S3C2440_GPD10_SPICLK1  (0x03 << 20)
-
-#define S3C2410_GPD11_VD19     (0x02 << 22)
-
-#define S3C2410_GPD12_VD20     (0x02 << 24)
-
-#define S3C2410_GPD13_VD21     (0x02 << 26)
-
-#define S3C2410_GPD14_VD22     (0x02 << 28)
-#define S3C2410_GPD14_nSS1     (0x03 << 28)
-
-#define S3C2410_GPD15_VD23     (0x02 << 30)
-#define S3C2410_GPD15_nSS0     (0x03 << 30)
-
-#define S3C2410_GPD_PUPDIS(x)  (1<<(x))
-
-/* S3C2410:
- * Port E consists of 16 GPIO/Special function
- *
- * again, the same as port B, but dealing with I2S, SDI, and
- * more miscellaneous functions
- *
- * GPIO / interrupt inputs
-*/
-
-#define S3C2410_GPECON    S3C2410_GPIOREG(0x40)
-#define S3C2410_GPEDAT    S3C2410_GPIOREG(0x44)
-#define S3C2410_GPEUP     S3C2410_GPIOREG(0x48)
-
-#define S3C2410_GPE0_I2SLRCK   (0x02 << 0)
-#define S3C2443_GPE0_AC_nRESET (0x03 << 0)
-#define S3C2410_GPE0_MASK      (0x03 << 0)
-
-#define S3C2410_GPE1_I2SSCLK   (0x02 << 2)
-#define S3C2443_GPE1_AC_SYNC   (0x03 << 2)
-#define S3C2410_GPE1_MASK      (0x03 << 2)
-
-#define S3C2410_GPE2_CDCLK     (0x02 << 4)
-#define S3C2443_GPE2_AC_BITCLK (0x03 << 4)
-
-#define S3C2410_GPE3_I2SSDI    (0x02 << 6)
-#define S3C2443_GPE3_AC_SDI    (0x03 << 6)
-#define S3C2410_GPE3_nSS0      (0x03 << 6)
-#define S3C2410_GPE3_MASK      (0x03 << 6)
-
-#define S3C2410_GPE4_I2SSDO    (0x02 << 8)
-#define S3C2443_GPE4_AC_SDO    (0x03 << 8)
-#define S3C2410_GPE4_I2SSDI    (0x03 << 8)
-#define S3C2410_GPE4_MASK      (0x03 << 8)
-
-#define S3C2410_GPE5_SDCLK     (0x02 << 10)
-#define S3C2443_GPE5_SD1_CLK   (0x02 << 10)
-#define S3C2443_GPE5_AC_BITCLK (0x03 << 10)
-
-#define S3C2410_GPE6_SDCMD     (0x02 << 12)
-#define S3C2443_GPE6_SD1_CMD   (0x02 << 12)
-#define S3C2443_GPE6_AC_SDI    (0x03 << 12)
-
-#define S3C2410_GPE7_SDDAT0    (0x02 << 14)
-#define S3C2443_GPE5_SD1_DAT0  (0x02 << 14)
-#define S3C2443_GPE7_AC_SDO    (0x03 << 14)
-
-#define S3C2410_GPE8_SDDAT1    (0x02 << 16)
-#define S3C2443_GPE8_SD1_DAT1  (0x02 << 16)
-#define S3C2443_GPE8_AC_SYNC   (0x03 << 16)
-
-#define S3C2410_GPE9_SDDAT2    (0x02 << 18)
-#define S3C2443_GPE9_SD1_DAT2  (0x02 << 18)
-#define S3C2443_GPE9_AC_nRESET (0x03 << 18)
-
-#define S3C2410_GPE10_SDDAT3   (0x02 << 20)
-#define S3C2443_GPE10_SD1_DAT3 (0x02 << 20)
-
-#define S3C2410_GPE11_SPIMISO0 (0x02 << 22)
-
-#define S3C2410_GPE12_SPIMOSI0 (0x02 << 24)
-
-#define S3C2410_GPE13_SPICLK0  (0x02 << 26)
-
-#define S3C2410_GPE14_IICSCL   (0x02 << 28)
-#define S3C2410_GPE14_MASK     (0x03 << 28)
-
-#define S3C2410_GPE15_IICSDA   (0x02 << 30)
-#define S3C2410_GPE15_MASK     (0x03 << 30)
-
-#define S3C2440_GPE0_ACSYNC    (0x03 << 0)
-#define S3C2440_GPE1_ACBITCLK  (0x03 << 2)
-#define S3C2440_GPE2_ACRESET   (0x03 << 4)
-#define S3C2440_GPE3_ACIN      (0x03 << 6)
-#define S3C2440_GPE4_ACOUT     (0x03 << 8)
-
-#define S3C2410_GPE_PUPDIS(x)  (1<<(x))
-
-/* S3C2410:
- * Port F consists of 8 GPIO/Special function
- *
- * GPIO / interrupt inputs
- *
- * GPFCON has 2 bits for each of the input pins on port F
- *   00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 undefined
- *
- * pull up works like all other ports.
- *
- * GPIO/serial/misc pins
-*/
-
-#define S3C2410_GPFCON    S3C2410_GPIOREG(0x50)
-#define S3C2410_GPFDAT    S3C2410_GPIOREG(0x54)
-#define S3C2410_GPFUP     S3C2410_GPIOREG(0x58)
-
-#define S3C2410_GPF0_EINT0  (0x02 << 0)
-#define S3C2410_GPF1_EINT1  (0x02 << 2)
-#define S3C2410_GPF2_EINT2  (0x02 << 4)
-#define S3C2410_GPF3_EINT3  (0x02 << 6)
-#define S3C2410_GPF4_EINT4  (0x02 << 8)
-#define S3C2410_GPF5_EINT5  (0x02 << 10)
-#define S3C2410_GPF6_EINT6  (0x02 << 12)
-#define S3C2410_GPF7_EINT7  (0x02 << 14)
-#define S3C2410_GPF_PUPDIS(x)  (1<<(x))
-
-/* S3C2410:
- * Port G consists of 8 GPIO/IRQ/Special function
- *
- * GPGCON has 2 bits for each of the input pins on port F
- *   00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 special func
- *
- * pull up works like all other ports.
-*/
-
-#define S3C2410_GPGCON    S3C2410_GPIOREG(0x60)
-#define S3C2410_GPGDAT    S3C2410_GPIOREG(0x64)
-#define S3C2410_GPGUP     S3C2410_GPIOREG(0x68)
-
-#define S3C2410_GPG0_EINT8    (0x02 << 0)
-
-#define S3C2410_GPG1_EINT9    (0x02 << 2)
-
-#define S3C2410_GPG2_EINT10   (0x02 << 4)
-#define S3C2410_GPG2_nSS0     (0x03 << 4)
-
-#define S3C2410_GPG3_EINT11   (0x02 << 6)
-#define S3C2410_GPG3_nSS1     (0x03 << 6)
-
-#define S3C2410_GPG4_EINT12   (0x02 << 8)
-#define S3C2410_GPG4_LCDPWREN (0x03 << 8)
-#define S3C2443_GPG4_LCDPWRDN (0x03 << 8)
-
-#define S3C2410_GPG5_EINT13   (0x02 << 10)
-#define S3C2410_GPG5_SPIMISO1 (0x03 << 10)     /* not s3c2443 */
-
-#define S3C2410_GPG6_EINT14   (0x02 << 12)
-#define S3C2410_GPG6_SPIMOSI1 (0x03 << 12)
-
-#define S3C2410_GPG7_EINT15   (0x02 << 14)
-#define S3C2410_GPG7_SPICLK1  (0x03 << 14)
-
-#define S3C2410_GPG8_EINT16   (0x02 << 16)
-
-#define S3C2410_GPG9_EINT17   (0x02 << 18)
-
-#define S3C2410_GPG10_EINT18  (0x02 << 20)
-
-#define S3C2410_GPG11_EINT19  (0x02 << 22)
-#define S3C2410_GPG11_TCLK1   (0x03 << 22)
-#define S3C2443_GPG11_CF_nIREQ (0x03 << 22)
-
-#define S3C2410_GPG12_EINT20  (0x02 << 24)
-#define S3C2410_GPG12_XMON    (0x03 << 24)
-#define S3C2442_GPG12_nSPICS0 (0x03 << 24)
-#define S3C2443_GPG12_nINPACK (0x03 << 24)
-
-#define S3C2410_GPG13_EINT21  (0x02 << 26)
-#define S3C2410_GPG13_nXPON   (0x03 << 26)
-#define S3C2443_GPG13_CF_nREG (0x03 << 26)
-
-#define S3C2410_GPG14_EINT22  (0x02 << 28)
-#define S3C2410_GPG14_YMON    (0x03 << 28)
-#define S3C2443_GPG14_CF_RESET (0x03 << 28)
-
-#define S3C2410_GPG15_EINT23  (0x02 << 30)
-#define S3C2410_GPG15_nYPON   (0x03 << 30)
-#define S3C2443_GPG15_CF_PWR  (0x03 << 30)
-
-#define S3C2410_GPG_PUPDIS(x)  (1<<(x))
-
-/* Port H consists of11 GPIO/serial/Misc pins
- *
- * GPGCON has 2 bits for each of the input pins on port F
- *   00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 special func
- *
- * pull up works like all other ports.
-*/
-
-#define S3C2410_GPHCON    S3C2410_GPIOREG(0x70)
-#define S3C2410_GPHDAT    S3C2410_GPIOREG(0x74)
-#define S3C2410_GPHUP     S3C2410_GPIOREG(0x78)
-
-#define S3C2410_GPH0_nCTS0  (0x02 << 0)
-#define S3C2416_GPH0_TXD0  (0x02 << 0)
-
-#define S3C2410_GPH1_nRTS0  (0x02 << 2)
-#define S3C2416_GPH1_RXD0  (0x02 << 2)
-
-#define S3C2410_GPH2_TXD0   (0x02 << 4)
-#define S3C2416_GPH2_TXD1   (0x02 << 4)
-
-#define S3C2410_GPH3_RXD0   (0x02 << 6)
-#define S3C2416_GPH3_RXD1   (0x02 << 6)
-
-#define S3C2410_GPH4_TXD1   (0x02 << 8)
-#define S3C2416_GPH4_TXD2   (0x02 << 8)
-
-#define S3C2410_GPH5_RXD1   (0x02 << 10)
-#define S3C2416_GPH5_RXD2   (0x02 << 10)
-
-#define S3C2410_GPH6_TXD2   (0x02 << 12)
-#define S3C2416_GPH6_TXD3   (0x02 << 12)
-#define S3C2410_GPH6_nRTS1  (0x03 << 12)
-#define S3C2416_GPH6_nRTS2  (0x03 << 12)
-
-#define S3C2410_GPH7_RXD2   (0x02 << 14)
-#define S3C2416_GPH7_RXD3   (0x02 << 14)
-#define S3C2410_GPH7_nCTS1  (0x03 << 14)
-#define S3C2416_GPH7_nCTS2  (0x03 << 14)
-
-#define S3C2410_GPH8_UCLK   (0x02 << 16)
-#define S3C2416_GPH8_nCTS0  (0x02 << 16)
-
-#define S3C2410_GPH9_CLKOUT0  (0x02 << 18)
-#define S3C2442_GPH9_nSPICS0  (0x03 << 18)
-#define S3C2416_GPH9_nRTS0    (0x02 << 18)
-
-#define S3C2410_GPH10_CLKOUT1 (0x02 << 20)
-#define S3C2416_GPH10_nCTS1   (0x02 << 20)
-
-#define S3C2416_GPH11_nRTS1   (0x02 << 22)
-
-#define S3C2416_GPH12_EXTUARTCLK (0x02 << 24)
-
-#define S3C2416_GPH13_CLKOUT0 (0x02 << 26)
-
-#define S3C2416_GPH14_CLKOUT1 (0x02 << 28)
-
-/* The S3C2412 and S3C2413 move the GPJ register set to after
- * GPH, which means all registers after 0x80 are now offset by 0x10
- * for the 2412/2413 from the 2410/2440/2442
-*/
-
-/* S3C2443 and above */
-#define S3C2440_GPJCON    S3C2410_GPIOREG(0xD0)
-#define S3C2440_GPJDAT    S3C2410_GPIOREG(0xD4)
-#define S3C2440_GPJUP     S3C2410_GPIOREG(0xD8)
-
-#define S3C2443_GPKCON    S3C2410_GPIOREG(0xE0)
-#define S3C2443_GPKDAT    S3C2410_GPIOREG(0xE4)
-#define S3C2443_GPKUP     S3C2410_GPIOREG(0xE8)
-
-#define S3C2443_GPLCON    S3C2410_GPIOREG(0xF0)
-#define S3C2443_GPLDAT    S3C2410_GPIOREG(0xF4)
-#define S3C2443_GPLUP     S3C2410_GPIOREG(0xF8)
-
-#define S3C2443_GPMCON    S3C2410_GPIOREG(0x100)
-#define S3C2443_GPMDAT    S3C2410_GPIOREG(0x104)
-#define S3C2443_GPMUP     S3C2410_GPIOREG(0x108)
-
-/* miscellaneous control */
-#define S3C2410_MISCCR    S3C2410_GPIOREG(0x80)
-#define S3C2410_DCLKCON           S3C2410_GPIOREG(0x84)
-
-#define S3C24XX_DCLKCON           S3C24XX_GPIOREG2(0x84)
-
-/* see clock.h for dclk definitions */
-
-/* pullup control on databus */
-#define S3C2410_MISCCR_SPUCR_HEN    (0<<0)
-#define S3C2410_MISCCR_SPUCR_HDIS   (1<<0)
-#define S3C2410_MISCCR_SPUCR_LEN    (0<<1)
-#define S3C2410_MISCCR_SPUCR_LDIS   (1<<1)
-
-#define S3C2410_MISCCR_USBDEV      (0<<3)
-#define S3C2410_MISCCR_USBHOST     (1<<3)
-
-#define S3C2410_MISCCR_CLK0_MPLL    (0<<4)
-#define S3C2410_MISCCR_CLK0_UPLL    (1<<4)
-#define S3C2410_MISCCR_CLK0_FCLK    (2<<4)
-#define S3C2410_MISCCR_CLK0_HCLK    (3<<4)
-#define S3C2410_MISCCR_CLK0_PCLK    (4<<4)
-#define S3C2410_MISCCR_CLK0_DCLK0   (5<<4)
-#define S3C2410_MISCCR_CLK0_MASK    (7<<4)
-
-#define S3C2412_MISCCR_CLK0_RTC            (2<<4)
-
-#define S3C2410_MISCCR_CLK1_MPLL    (0<<8)
-#define S3C2410_MISCCR_CLK1_UPLL    (1<<8)
-#define S3C2410_MISCCR_CLK1_FCLK    (2<<8)
-#define S3C2410_MISCCR_CLK1_HCLK    (3<<8)
-#define S3C2410_MISCCR_CLK1_PCLK    (4<<8)
-#define S3C2410_MISCCR_CLK1_DCLK1   (5<<8)
-#define S3C2410_MISCCR_CLK1_MASK    (7<<8)
-
-#define S3C2412_MISCCR_CLK1_CLKsrc  (0<<8)
-
-#define S3C2410_MISCCR_USBSUSPND0   (1<<12)
-#define S3C2416_MISCCR_SEL_SUSPND   (1<<12)
-#define S3C2410_MISCCR_USBSUSPND1   (1<<13)
-
-#define S3C2410_MISCCR_nRSTCON     (1<<16)
-
-#define S3C2410_MISCCR_nEN_SCLK0    (1<<17)
-#define S3C2410_MISCCR_nEN_SCLK1    (1<<18)
-#define S3C2410_MISCCR_nEN_SCLKE    (1<<19)    /* not 2412 */
-#define S3C2410_MISCCR_SDSLEEP     (7<<17)
-
-#define S3C2416_MISCCR_FLT_I2C      (1<<24)
-#define S3C2416_MISCCR_HSSPI_EN2    (1<<31)
-
-/* external interrupt control... */
-/* S3C2410_EXTINT0 -> irq sense control for EINT0..EINT7
- * S3C2410_EXTINT1 -> irq sense control for EINT8..EINT15
- * S3C2410_EXTINT2 -> irq sense control for EINT16..EINT23
- *
- * note S3C2410_EXTINT2 has filtering options for EINT16..EINT23
- *
- * Samsung datasheet p9-25
-*/
-#define S3C2410_EXTINT0           S3C2410_GPIOREG(0x88)
-#define S3C2410_EXTINT1           S3C2410_GPIOREG(0x8C)
-#define S3C2410_EXTINT2           S3C2410_GPIOREG(0x90)
-
-#define S3C24XX_EXTINT0           S3C24XX_GPIOREG2(0x88)
-#define S3C24XX_EXTINT1           S3C24XX_GPIOREG2(0x8C)
-#define S3C24XX_EXTINT2           S3C24XX_GPIOREG2(0x90)
-
-/* interrupt filtering conrrol for EINT16..EINT23 */
-#define S3C2410_EINFLT0           S3C2410_GPIOREG(0x94)
-#define S3C2410_EINFLT1           S3C2410_GPIOREG(0x98)
-#define S3C2410_EINFLT2           S3C2410_GPIOREG(0x9C)
-#define S3C2410_EINFLT3           S3C2410_GPIOREG(0xA0)
-
-#define S3C24XX_EINFLT0           S3C24XX_GPIOREG2(0x94)
-#define S3C24XX_EINFLT1           S3C24XX_GPIOREG2(0x98)
-#define S3C24XX_EINFLT2           S3C24XX_GPIOREG2(0x9C)
-#define S3C24XX_EINFLT3           S3C24XX_GPIOREG2(0xA0)
-
-/* values for interrupt filtering */
-#define S3C2410_EINTFLT_PCLK           (0x00)
-#define S3C2410_EINTFLT_EXTCLK         (1<<7)
-#define S3C2410_EINTFLT_WIDTHMSK(x)    ((x) & 0x3f)
-
-/* removed EINTxxxx defs from here, not meant for this */
-
-/* GSTATUS have miscellaneous information in them
- *
- * These move between s3c2410 and s3c2412 style systems.
- */
-
-#define S3C2410_GSTATUS0   S3C2410_GPIOREG(0x0AC)
-#define S3C2410_GSTATUS1   S3C2410_GPIOREG(0x0B0)
-#define S3C2410_GSTATUS2   S3C2410_GPIOREG(0x0B4)
-#define S3C2410_GSTATUS3   S3C2410_GPIOREG(0x0B8)
-#define S3C2410_GSTATUS4   S3C2410_GPIOREG(0x0BC)
-
-#define S3C2412_GSTATUS0   S3C2410_GPIOREG(0x0BC)
-#define S3C2412_GSTATUS1   S3C2410_GPIOREG(0x0C0)
-#define S3C2412_GSTATUS2   S3C2410_GPIOREG(0x0C4)
-#define S3C2412_GSTATUS3   S3C2410_GPIOREG(0x0C8)
-#define S3C2412_GSTATUS4   S3C2410_GPIOREG(0x0CC)
-
-#define S3C24XX_GSTATUS0   S3C24XX_GPIOREG2(0x0AC)
-#define S3C24XX_GSTATUS1   S3C24XX_GPIOREG2(0x0B0)
-#define S3C24XX_GSTATUS2   S3C24XX_GPIOREG2(0x0B4)
-#define S3C24XX_GSTATUS3   S3C24XX_GPIOREG2(0x0B8)
-#define S3C24XX_GSTATUS4   S3C24XX_GPIOREG2(0x0BC)
-
-#define S3C2410_GSTATUS0_nWAIT    (1<<3)
-#define S3C2410_GSTATUS0_NCON     (1<<2)
-#define S3C2410_GSTATUS0_RnB      (1<<1)
-#define S3C2410_GSTATUS0_nBATTFLT  (1<<0)
-
-#define S3C2410_GSTATUS1_IDMASK           (0xffff0000)
-#define S3C2410_GSTATUS1_2410     (0x32410000)
-#define S3C2410_GSTATUS1_2412     (0x32412001)
-#define S3C2410_GSTATUS1_2416     (0x32416003)
-#define S3C2410_GSTATUS1_2440     (0x32440000)
-#define S3C2410_GSTATUS1_2442     (0x32440aaa)
-/* some 2416 CPUs report this value also */
-#define S3C2410_GSTATUS1_2450     (0x32450003)
-
-#define S3C2410_GSTATUS2_WTRESET   (1<<2)
-#define S3C2410_GSTATUS2_OFFRESET  (1<<1)
-#define S3C2410_GSTATUS2_PONRESET  (1<<0)
-
-/* 2412/2413 sleep configuration registers */
-
-#define S3C2412_GPBSLPCON      S3C2410_GPIOREG(0x1C)
-#define S3C2412_GPCSLPCON      S3C2410_GPIOREG(0x2C)
-#define S3C2412_GPDSLPCON      S3C2410_GPIOREG(0x3C)
-#define S3C2412_GPFSLPCON      S3C2410_GPIOREG(0x5C)
-#define S3C2412_GPGSLPCON      S3C2410_GPIOREG(0x6C)
-#define S3C2412_GPHSLPCON      S3C2410_GPIOREG(0x7C)
-
-/* definitions for each pin bit */
-#define S3C2412_GPIO_SLPCON_LOW         ( 0x00 )
-#define S3C2412_GPIO_SLPCON_HIGH ( 0x01 )
-#define S3C2412_GPIO_SLPCON_IN   ( 0x02 )
-#define S3C2412_GPIO_SLPCON_PULL ( 0x03 )
-
-#define S3C2412_SLPCON_LOW(x)  ( 0x00 << ((x) * 2))
-#define S3C2412_SLPCON_HIGH(x) ( 0x01 << ((x) * 2))
-#define S3C2412_SLPCON_IN(x)   ( 0x02 << ((x) * 2))
-#define S3C2412_SLPCON_PULL(x) ( 0x03 << ((x) * 2))
-#define S3C2412_SLPCON_EINT(x) ( 0x02 << ((x) * 2))  /* only IRQ pins */
-#define S3C2412_SLPCON_MASK(x) ( 0x03 << ((x) * 2))
-
-#define S3C2412_SLPCON_ALL_LOW (0x0)
-#define S3C2412_SLPCON_ALL_HIGH        (0x11111111 | 0x44444444)
-#define S3C2412_SLPCON_ALL_IN          (0x22222222 | 0x88888888)
-#define S3C2412_SLPCON_ALL_PULL        (0x33333333)
-
-#endif /* __ASM_ARCH_REGS_GPIO_H */
-
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h b/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
deleted file mode 100644 (file)
index 19575e0..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
- *
- * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
- *                   http://www.simtec.co.uk/products/SWLINUX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2440 GPIO J register definitions
-*/
-
-
-#ifndef __ASM_ARCH_REGS_GPIOJ_H
-#define __ASM_ARCH_REGS_GPIOJ_H "gpioj"
-
-/* Port J consists of 13 GPIO/Camera pins
- *
- * GPJCON has 2 bits for each of the input pins on port F
- *   00 = 0 input, 1 output, 2 Camera
- *
- * pull up works like all other ports.
-*/
-
-#define S3C2413_GPJCON         S3C2410_GPIOREG(0x80)
-#define S3C2413_GPJDAT         S3C2410_GPIOREG(0x84)
-#define S3C2413_GPJUP          S3C2410_GPIOREG(0x88)
-#define S3C2413_GPJSLPCON      S3C2410_GPIOREG(0x8C)
-
-#define S3C2440_GPJ0_OUTP       (0x01 << 0)
-#define S3C2440_GPJ0_CAMDATA0   (0x02 << 0)
-
-#define S3C2440_GPJ1_OUTP       (0x01 << 2)
-#define S3C2440_GPJ1_CAMDATA1   (0x02 << 2)
-
-#define S3C2440_GPJ2_OUTP       (0x01 << 4)
-#define S3C2440_GPJ2_CAMDATA2   (0x02 << 4)
-
-#define S3C2440_GPJ3_OUTP       (0x01 << 6)
-#define S3C2440_GPJ3_CAMDATA3   (0x02 << 6)
-
-#define S3C2440_GPJ4_OUTP       (0x01 << 8)
-#define S3C2440_GPJ4_CAMDATA4   (0x02 << 8)
-
-#define S3C2440_GPJ5_OUTP       (0x01 << 10)
-#define S3C2440_GPJ5_CAMDATA5   (0x02 << 10)
-
-#define S3C2440_GPJ6_OUTP       (0x01 << 12)
-#define S3C2440_GPJ6_CAMDATA6   (0x02 << 12)
-
-#define S3C2440_GPJ7_OUTP       (0x01 << 14)
-#define S3C2440_GPJ7_CAMDATA7   (0x02 << 14)
-
-#define S3C2440_GPJ8_OUTP       (0x01 << 16)
-#define S3C2440_GPJ8_CAMPCLK    (0x02 << 16)
-
-#define S3C2440_GPJ9_OUTP       (0x01 << 18)
-#define S3C2440_GPJ9_CAMVSYNC   (0x02 << 18)
-
-#define S3C2440_GPJ10_OUTP      (0x01 << 20)
-#define S3C2440_GPJ10_CAMHREF   (0x02 << 20)
-
-#define S3C2440_GPJ11_OUTP      (0x01 << 22)
-#define S3C2440_GPJ11_CAMCLKOUT (0x02 << 22)
-
-#define S3C2440_GPJ12_OUTP      (0x01 << 24)
-#define S3C2440_GPJ12_CAMRESET  (0x02 << 24)
-
-#endif /* __ASM_ARCH_REGS_GPIOJ_H */
-
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-irq.h b/arch/arm/mach-s3c2410/include/mach/regs-irq.h
deleted file mode 100644 (file)
index 0f07ba3..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-irq.h
- *
- * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
- *                   http://www.simtec.co.uk/products/SWLINUX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-
-#ifndef ___ASM_ARCH_REGS_IRQ_H
-#define ___ASM_ARCH_REGS_IRQ_H
-
-/* interrupt controller */
-
-#define S3C2410_IRQREG(x)   ((x) + S3C24XX_VA_IRQ)
-#define S3C2410_EINTREG(x)  ((x) + S3C24XX_VA_GPIO)
-#define S3C24XX_EINTREG(x)  ((x) + S3C24XX_VA_GPIO2)
-
-#define S3C2410_SRCPND        S3C2410_IRQREG(0x000)
-#define S3C2410_INTMOD        S3C2410_IRQREG(0x004)
-#define S3C2410_INTMSK        S3C2410_IRQREG(0x008)
-#define S3C2410_PRIORITY       S3C2410_IRQREG(0x00C)
-#define S3C2410_INTPND        S3C2410_IRQREG(0x010)
-#define S3C2410_INTOFFSET      S3C2410_IRQREG(0x014)
-#define S3C2410_SUBSRCPND      S3C2410_IRQREG(0x018)
-#define S3C2410_INTSUBMSK      S3C2410_IRQREG(0x01C)
-
-#define S3C2416_PRIORITY_MODE1         S3C2410_IRQREG(0x030)
-#define S3C2416_PRIORITY_UPDATE1       S3C2410_IRQREG(0x034)
-#define S3C2416_SRCPND2                        S3C2410_IRQREG(0x040)
-#define S3C2416_INTMOD2                        S3C2410_IRQREG(0x044)
-#define S3C2416_INTMSK2                        S3C2410_IRQREG(0x048)
-#define S3C2416_INTPND2                        S3C2410_IRQREG(0x050)
-#define S3C2416_INTOFFSET2             S3C2410_IRQREG(0x054)
-#define S3C2416_PRIORITY_MODE2         S3C2410_IRQREG(0x070)
-#define S3C2416_PRIORITY_UPDATE2       S3C2410_IRQREG(0x074)
-
-/* mask: 0=enable, 1=disable
- * 1 bit EINT, 4=EINT4, 23=EINT23
- * EINT0,1,2,3 are not handled here.
-*/
-
-#define S3C2410_EINTMASK       S3C2410_EINTREG(0x0A4)
-#define S3C2410_EINTPEND       S3C2410_EINTREG(0X0A8)
-#define S3C2412_EINTMASK       S3C2410_EINTREG(0x0B4)
-#define S3C2412_EINTPEND       S3C2410_EINTREG(0X0B8)
-
-#define S3C24XX_EINTMASK       S3C24XX_EINTREG(0x0A4)
-#define S3C24XX_EINTPEND       S3C24XX_EINTREG(0X0A8)
-
-#endif /* ___ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-lcd.h b/arch/arm/mach-s3c2410/include/mach/regs-lcd.h
deleted file mode 100644 (file)
index ee8f040..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-lcd.h
- *
- * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
- *                   http://www.simtec.co.uk/products/SWLINUX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-
-#ifndef ___ASM_ARCH_REGS_LCD_H
-#define ___ASM_ARCH_REGS_LCD_H
-
-#define S3C2410_LCDREG(x)      (x)
-
-/* LCD control registers */
-#define S3C2410_LCDCON1            S3C2410_LCDREG(0x00)
-#define S3C2410_LCDCON2            S3C2410_LCDREG(0x04)
-#define S3C2410_LCDCON3            S3C2410_LCDREG(0x08)
-#define S3C2410_LCDCON4            S3C2410_LCDREG(0x0C)
-#define S3C2410_LCDCON5            S3C2410_LCDREG(0x10)
-
-#define S3C2410_LCDCON1_CLKVAL(x)  ((x) << 8)
-#define S3C2410_LCDCON1_MMODE     (1<<7)
-#define S3C2410_LCDCON1_DSCAN4    (0<<5)
-#define S3C2410_LCDCON1_STN4      (1<<5)
-#define S3C2410_LCDCON1_STN8      (2<<5)
-#define S3C2410_LCDCON1_TFT       (3<<5)
-
-#define S3C2410_LCDCON1_STN1BPP           (0<<1)
-#define S3C2410_LCDCON1_STN2GREY   (1<<1)
-#define S3C2410_LCDCON1_STN4GREY   (2<<1)
-#define S3C2410_LCDCON1_STN8BPP           (3<<1)
-#define S3C2410_LCDCON1_STN12BPP   (4<<1)
-
-#define S3C2410_LCDCON1_TFT1BPP           (8<<1)
-#define S3C2410_LCDCON1_TFT2BPP           (9<<1)
-#define S3C2410_LCDCON1_TFT4BPP           (10<<1)
-#define S3C2410_LCDCON1_TFT8BPP           (11<<1)
-#define S3C2410_LCDCON1_TFT16BPP   (12<<1)
-#define S3C2410_LCDCON1_TFT24BPP   (13<<1)
-
-#define S3C2410_LCDCON1_ENVID     (1)
-
-#define S3C2410_LCDCON1_MODEMASK    0x1E
-
-#define S3C2410_LCDCON2_VBPD(x)            ((x) << 24)
-#define S3C2410_LCDCON2_LINEVAL(x)  ((x) << 14)
-#define S3C2410_LCDCON2_VFPD(x)            ((x) << 6)
-#define S3C2410_LCDCON2_VSPW(x)            ((x) << 0)
-
-#define S3C2410_LCDCON2_GET_VBPD(x) ( ((x) >> 24) & 0xFF)
-#define S3C2410_LCDCON2_GET_VFPD(x) ( ((x) >>  6) & 0xFF)
-#define S3C2410_LCDCON2_GET_VSPW(x) ( ((x) >>  0) & 0x3F)
-
-#define S3C2410_LCDCON3_HBPD(x)            ((x) << 19)
-#define S3C2410_LCDCON3_WDLY(x)            ((x) << 19)
-#define S3C2410_LCDCON3_HOZVAL(x)   ((x) << 8)
-#define S3C2410_LCDCON3_HFPD(x)            ((x) << 0)
-#define S3C2410_LCDCON3_LINEBLANK(x)((x) << 0)
-
-#define S3C2410_LCDCON3_GET_HBPD(x) ( ((x) >> 19) & 0x7F)
-#define S3C2410_LCDCON3_GET_HFPD(x) ( ((x) >>  0) & 0xFF)
-
-/* LDCCON4 changes for STN mode on the S3C2412 */
-
-#define S3C2410_LCDCON4_MVAL(x)            ((x) << 8)
-#define S3C2410_LCDCON4_HSPW(x)            ((x) << 0)
-#define S3C2410_LCDCON4_WLH(x)     ((x) << 0)
-
-#define S3C2410_LCDCON4_GET_HSPW(x) ( ((x) >>  0) & 0xFF)
-
-#define S3C2410_LCDCON5_BPP24BL            (1<<12)
-#define S3C2410_LCDCON5_FRM565     (1<<11)
-#define S3C2410_LCDCON5_INVVCLK            (1<<10)
-#define S3C2410_LCDCON5_INVVLINE    (1<<9)
-#define S3C2410_LCDCON5_INVVFRAME   (1<<8)
-#define S3C2410_LCDCON5_INVVD      (1<<7)
-#define S3C2410_LCDCON5_INVVDEN            (1<<6)
-#define S3C2410_LCDCON5_INVPWREN    (1<<5)
-#define S3C2410_LCDCON5_INVLEND            (1<<4)
-#define S3C2410_LCDCON5_PWREN      (1<<3)
-#define S3C2410_LCDCON5_ENLEND     (1<<2)
-#define S3C2410_LCDCON5_BSWP       (1<<1)
-#define S3C2410_LCDCON5_HWSWP      (1<<0)
-
-/* framebuffer start addressed */
-#define S3C2410_LCDSADDR1   S3C2410_LCDREG(0x14)
-#define S3C2410_LCDSADDR2   S3C2410_LCDREG(0x18)
-#define S3C2410_LCDSADDR3   S3C2410_LCDREG(0x1C)
-
-#define S3C2410_LCDBANK(x)     ((x) << 21)
-#define S3C2410_LCDBASEU(x)    (x)
-
-#define S3C2410_OFFSIZE(x)     ((x) << 11)
-#define S3C2410_PAGEWIDTH(x)   (x)
-
-/* colour lookup and miscellaneous controls */
-
-#define S3C2410_REDLUT    S3C2410_LCDREG(0x20)
-#define S3C2410_GREENLUT   S3C2410_LCDREG(0x24)
-#define S3C2410_BLUELUT           S3C2410_LCDREG(0x28)
-
-#define S3C2410_DITHMODE   S3C2410_LCDREG(0x4C)
-#define S3C2410_TPAL      S3C2410_LCDREG(0x50)
-
-#define S3C2410_TPAL_EN                (1<<24)
-
-/* interrupt info */
-#define S3C2410_LCDINTPND  S3C2410_LCDREG(0x54)
-#define S3C2410_LCDSRCPND  S3C2410_LCDREG(0x58)
-#define S3C2410_LCDINTMSK  S3C2410_LCDREG(0x5C)
-#define S3C2410_LCDINT_FIWSEL  (1<<2)
-#define        S3C2410_LCDINT_FRSYNC   (1<<1)
-#define S3C2410_LCDINT_FICNT   (1<<0)
-
-/* s3c2442 extra stn registers */
-
-#define S3C2442_REDLUT         S3C2410_LCDREG(0x20)
-#define S3C2442_GREENLUT       S3C2410_LCDREG(0x24)
-#define S3C2442_BLUELUT                S3C2410_LCDREG(0x28)
-#define S3C2442_DITHMODE       S3C2410_LCDREG(0x20)
-
-#define S3C2410_LPCSEL    S3C2410_LCDREG(0x60)
-
-#define S3C2410_TFTPAL(x)  S3C2410_LCDREG((0x400 + (x)*4))
-
-/* S3C2412 registers */
-
-#define S3C2412_TPAL           S3C2410_LCDREG(0x20)
-
-#define S3C2412_LCDINTPND      S3C2410_LCDREG(0x24)
-#define S3C2412_LCDSRCPND      S3C2410_LCDREG(0x28)
-#define S3C2412_LCDINTMSK      S3C2410_LCDREG(0x2C)
-
-#define S3C2412_TCONSEL                S3C2410_LCDREG(0x30)
-
-#define S3C2412_LCDCON6                S3C2410_LCDREG(0x34)
-#define S3C2412_LCDCON7                S3C2410_LCDREG(0x38)
-#define S3C2412_LCDCON8                S3C2410_LCDREG(0x3C)
-#define S3C2412_LCDCON9                S3C2410_LCDREG(0x40)
-
-#define S3C2412_REDLUT(x)      S3C2410_LCDREG(0x44 + ((x)*4))
-#define S3C2412_GREENLUT(x)    S3C2410_LCDREG(0x60 + ((x)*4))
-#define S3C2412_BLUELUT(x)     S3C2410_LCDREG(0x98 + ((x)*4))
-
-#define S3C2412_FRCPAT(x)      S3C2410_LCDREG(0xB4 + ((x)*4))
-
-/* general registers */
-
-/* base of the LCD registers, where INTPND, INTSRC and then INTMSK
- * are available. */
-
-#define S3C2410_LCDINTBASE     S3C2410_LCDREG(0x54)
-#define S3C2412_LCDINTBASE     S3C2410_LCDREG(0x24)
-
-#define S3C24XX_LCDINTPND      (0x00)
-#define S3C24XX_LCDSRCPND      (0x04)
-#define S3C24XX_LCDINTMSK      (0x08)
-
-#endif /* ___ASM_ARCH_REGS_LCD_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-mem.h
deleted file mode 100644 (file)
index e0c67b0..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-mem.h
- *
- * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
- *             http://www.simtec.co.uk/products/SWLINUX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2410 Memory Control register definitions
-*/
-
-#ifndef __ASM_ARM_MEMREGS_H
-#define __ASM_ARM_MEMREGS_H
-
-#ifndef S3C2410_MEMREG
-#define S3C2410_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
-#endif
-
-/* bus width, and wait state control */
-#define S3C2410_BWSCON                 S3C2410_MEMREG(0x0000)
-
-/* bank zero config - note, pinstrapped from OM pins! */
-#define S3C2410_BWSCON_DW0_16          (1<<1)
-#define S3C2410_BWSCON_DW0_32          (2<<1)
-
-/* bank one configs */
-#define S3C2410_BWSCON_DW1_8           (0<<4)
-#define S3C2410_BWSCON_DW1_16          (1<<4)
-#define S3C2410_BWSCON_DW1_32          (2<<4)
-#define S3C2410_BWSCON_WS1             (1<<6)
-#define S3C2410_BWSCON_ST1             (1<<7)
-
-/* bank 2 configurations */
-#define S3C2410_BWSCON_DW2_8           (0<<8)
-#define S3C2410_BWSCON_DW2_16          (1<<8)
-#define S3C2410_BWSCON_DW2_32          (2<<8)
-#define S3C2410_BWSCON_WS2             (1<<10)
-#define S3C2410_BWSCON_ST2             (1<<11)
-
-/* bank 3 configurations */
-#define S3C2410_BWSCON_DW3_8           (0<<12)
-#define S3C2410_BWSCON_DW3_16          (1<<12)
-#define S3C2410_BWSCON_DW3_32          (2<<12)
-#define S3C2410_BWSCON_WS3             (1<<14)
-#define S3C2410_BWSCON_ST3             (1<<15)
-
-/* bank 4 configurations */
-#define S3C2410_BWSCON_DW4_8           (0<<16)
-#define S3C2410_BWSCON_DW4_16          (1<<16)
-#define S3C2410_BWSCON_DW4_32          (2<<16)
-#define S3C2410_BWSCON_WS4             (1<<18)
-#define S3C2410_BWSCON_ST4             (1<<19)
-
-/* bank 5 configurations */
-#define S3C2410_BWSCON_DW5_8           (0<<20)
-#define S3C2410_BWSCON_DW5_16          (1<<20)
-#define S3C2410_BWSCON_DW5_32          (2<<20)
-#define S3C2410_BWSCON_WS5             (1<<22)
-#define S3C2410_BWSCON_ST5             (1<<23)
-
-/* bank 6 configurations */
-#define S3C2410_BWSCON_DW6_8           (0<<24)
-#define S3C2410_BWSCON_DW6_16          (1<<24)
-#define S3C2410_BWSCON_DW6_32          (2<<24)
-#define S3C2410_BWSCON_WS6             (1<<26)
-#define S3C2410_BWSCON_ST6             (1<<27)
-
-/* bank 7 configurations */
-#define S3C2410_BWSCON_DW7_8           (0<<28)
-#define S3C2410_BWSCON_DW7_16          (1<<28)
-#define S3C2410_BWSCON_DW7_32          (2<<28)
-#define S3C2410_BWSCON_WS7             (1<<30)
-#define S3C2410_BWSCON_ST7             (1<<31)
-
-/* accesor functions for getting BANK(n) configuration. (n != 0) */
-
-#define S3C2410_BWSCON_GET(_bwscon, _bank) (((_bwscon) >> ((_bank) * 4)) & 0xf)
-
-#define S3C2410_BWSCON_DW8             (0)
-#define S3C2410_BWSCON_DW16            (1)
-#define S3C2410_BWSCON_DW32            (2)
-#define S3C2410_BWSCON_WS              (1 << 2)
-#define S3C2410_BWSCON_ST              (1 << 3)
-
-/* memory set (rom, ram) */
-#define S3C2410_BANKCON0               S3C2410_MEMREG(0x0004)
-#define S3C2410_BANKCON1               S3C2410_MEMREG(0x0008)
-#define S3C2410_BANKCON2               S3C2410_MEMREG(0x000C)
-#define S3C2410_BANKCON3               S3C2410_MEMREG(0x0010)
-#define S3C2410_BANKCON4               S3C2410_MEMREG(0x0014)
-#define S3C2410_BANKCON5               S3C2410_MEMREG(0x0018)
-#define S3C2410_BANKCON6               S3C2410_MEMREG(0x001C)
-#define S3C2410_BANKCON7               S3C2410_MEMREG(0x0020)
-
-/* bank configuration registers */
-
-#define S3C2410_BANKCON_PMCnorm                (0x00)
-#define S3C2410_BANKCON_PMC4           (0x01)
-#define S3C2410_BANKCON_PMC8           (0x02)
-#define S3C2410_BANKCON_PMC16          (0x03)
-
-/* bank configurations for banks 0..7, note banks
- * 6 and 7 have different configurations depending on
- * the memory type bits */
-
-#define S3C2410_BANKCON_Tacp2          (0x0 << 2)
-#define S3C2410_BANKCON_Tacp3          (0x1 << 2)
-#define S3C2410_BANKCON_Tacp4          (0x2 << 2)
-#define S3C2410_BANKCON_Tacp6          (0x3 << 2)
-#define S3C2410_BANKCON_Tacp_SHIFT     (2)
-
-#define S3C2410_BANKCON_Tcah0          (0x0 << 4)
-#define S3C2410_BANKCON_Tcah1          (0x1 << 4)
-#define S3C2410_BANKCON_Tcah2          (0x2 << 4)
-#define S3C2410_BANKCON_Tcah4          (0x3 << 4)
-#define S3C2410_BANKCON_Tcah_SHIFT     (4)
-
-#define S3C2410_BANKCON_Tcoh0          (0x0 << 6)
-#define S3C2410_BANKCON_Tcoh1          (0x1 << 6)
-#define S3C2410_BANKCON_Tcoh2          (0x2 << 6)
-#define S3C2410_BANKCON_Tcoh4          (0x3 << 6)
-#define S3C2410_BANKCON_Tcoh_SHIFT     (6)
-
-#define S3C2410_BANKCON_Tacc1          (0x0 << 8)
-#define S3C2410_BANKCON_Tacc2          (0x1 << 8)
-#define S3C2410_BANKCON_Tacc3          (0x2 << 8)
-#define S3C2410_BANKCON_Tacc4          (0x3 << 8)
-#define S3C2410_BANKCON_Tacc6          (0x4 << 8)
-#define S3C2410_BANKCON_Tacc8          (0x5 << 8)
-#define S3C2410_BANKCON_Tacc10         (0x6 << 8)
-#define S3C2410_BANKCON_Tacc14         (0x7 << 8)
-#define S3C2410_BANKCON_Tacc_SHIFT     (8)
-
-#define S3C2410_BANKCON_Tcos0          (0x0 << 11)
-#define S3C2410_BANKCON_Tcos1          (0x1 << 11)
-#define S3C2410_BANKCON_Tcos2          (0x2 << 11)
-#define S3C2410_BANKCON_Tcos4          (0x3 << 11)
-#define S3C2410_BANKCON_Tcos_SHIFT     (11)
-
-#define S3C2410_BANKCON_Tacs0          (0x0 << 13)
-#define S3C2410_BANKCON_Tacs1          (0x1 << 13)
-#define S3C2410_BANKCON_Tacs2          (0x2 << 13)
-#define S3C2410_BANKCON_Tacs4          (0x3 << 13)
-#define S3C2410_BANKCON_Tacs_SHIFT     (13)
-
-#define S3C2410_BANKCON_SRAM           (0x0 << 15)
-#define S3C2410_BANKCON_SDRAM          (0x3 << 15)
-
-/* next bits only for SDRAM in 6,7 */
-#define S3C2410_BANKCON_Trcd2          (0x00 << 2)
-#define S3C2410_BANKCON_Trcd3          (0x01 << 2)
-#define S3C2410_BANKCON_Trcd4          (0x02 << 2)
-
-/* control column address select */
-#define S3C2410_BANKCON_SCANb8         (0x00 << 0)
-#define S3C2410_BANKCON_SCANb9         (0x01 << 0)
-#define S3C2410_BANKCON_SCANb10                (0x02 << 0)
-
-#define S3C2410_REFRESH                        S3C2410_MEMREG(0x0024)
-#define S3C2410_BANKSIZE               S3C2410_MEMREG(0x0028)
-#define S3C2410_MRSRB6                 S3C2410_MEMREG(0x002C)
-#define S3C2410_MRSRB7                 S3C2410_MEMREG(0x0030)
-
-/* refresh control */
-
-#define S3C2410_REFRESH_REFEN          (1<<23)
-#define S3C2410_REFRESH_SELF           (1<<22)
-#define S3C2410_REFRESH_REFCOUNTER     ((1<<11)-1)
-
-#define S3C2410_REFRESH_TRP_MASK       (3<<20)
-#define S3C2410_REFRESH_TRP_2clk       (0<<20)
-#define S3C2410_REFRESH_TRP_3clk       (1<<20)
-#define S3C2410_REFRESH_TRP_4clk       (2<<20)
-
-#define S3C2410_REFRESH_TSRC_MASK      (3<<18)
-#define S3C2410_REFRESH_TSRC_4clk      (0<<18)
-#define S3C2410_REFRESH_TSRC_5clk      (1<<18)
-#define S3C2410_REFRESH_TSRC_6clk      (2<<18)
-#define S3C2410_REFRESH_TSRC_7clk      (3<<18)
-
-
-/* mode select register(s) */
-
-#define  S3C2410_MRSRB_CL1             (0x00 << 4)
-#define  S3C2410_MRSRB_CL2             (0x02 << 4)
-#define  S3C2410_MRSRB_CL3             (0x03 << 4)
-
-/* bank size register */
-#define S3C2410_BANKSIZE_128M          (0x2 << 0)
-#define S3C2410_BANKSIZE_64M           (0x1 << 0)
-#define S3C2410_BANKSIZE_32M           (0x0 << 0)
-#define S3C2410_BANKSIZE_16M           (0x7 << 0)
-#define S3C2410_BANKSIZE_8M            (0x6 << 0)
-#define S3C2410_BANKSIZE_4M            (0x5 << 0)
-#define S3C2410_BANKSIZE_2M            (0x4 << 0)
-#define S3C2410_BANKSIZE_MASK          (0x7 << 0)
-#define S3C2410_BANKSIZE_SCLK_EN       (1<<4)
-#define S3C2410_BANKSIZE_SCKE_EN       (1<<5)
-#define S3C2410_BANKSIZE_BURST         (1<<7)
-
-#endif /* __ASM_ARM_MEMREGS_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-power.h b/arch/arm/mach-s3c2410/include/mach/regs-power.h
deleted file mode 100644 (file)
index 4932b87..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-power.h
- *
- * Copyright (c) 2003-2006 Simtec Electronics <linux@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C24XX power control register definitions
-*/
-
-#ifndef __ASM_ARM_REGS_PWR
-#define __ASM_ARM_REGS_PWR __FILE__
-
-#define S3C24XX_PWRREG(x) ((x) + S3C24XX_VA_CLKPWR)
-
-#define S3C2412_PWRMODECON     S3C24XX_PWRREG(0x20)
-#define S3C2412_PWRCFG         S3C24XX_PWRREG(0x24)
-
-#define S3C2412_INFORM0                S3C24XX_PWRREG(0x70)
-#define S3C2412_INFORM1                S3C24XX_PWRREG(0x74)
-#define S3C2412_INFORM2                S3C24XX_PWRREG(0x78)
-#define S3C2412_INFORM3                S3C24XX_PWRREG(0x7C)
-
-#define S3C2412_PWRCFG_BATF_IRQ                        (1<<0)
-#define S3C2412_PWRCFG_BATF_IGNORE             (2<<0)
-#define S3C2412_PWRCFG_BATF_SLEEP              (3<<0)
-#define S3C2412_PWRCFG_BATF_MASK               (3<<0)
-
-#define S3C2412_PWRCFG_STANDBYWFI_IGNORE       (0<<6)
-#define S3C2412_PWRCFG_STANDBYWFI_IDLE         (1<<6)
-#define S3C2412_PWRCFG_STANDBYWFI_STOP         (2<<6)
-#define S3C2412_PWRCFG_STANDBYWFI_SLEEP                (3<<6)
-#define S3C2412_PWRCFG_STANDBYWFI_MASK         (3<<6)
-
-#define S3C2412_PWRCFG_RTC_MASKIRQ             (1<<8)
-#define S3C2412_PWRCFG_NAND_NORST              (1<<9)
-
-#endif /* __ASM_ARM_REGS_PWR */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h
deleted file mode 100644 (file)
index fb63525..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h
- *
- * Copyright (c) 2008 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2412 memory register definitions
-*/
-
-#ifndef __ASM_ARM_REGS_S3C2412_MEM
-#define __ASM_ARM_REGS_S3C2412_MEM
-
-#define S3C2412_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
-#define S3C2412_EBIREG(x) (S3C2412_VA_EBI + (x))
-
-#define S3C2412_SSMCREG(x) (S3C2412_VA_SSMC + (x))
-#define S3C2412_SSMC(x, o) (S3C2412_SSMCREG((x * 0x20) + (o)))
-
-#define S3C2412_BANKCFG                        S3C2412_MEMREG(0x00)
-#define S3C2412_BANKCON1               S3C2412_MEMREG(0x04)
-#define S3C2412_BANKCON2               S3C2412_MEMREG(0x08)
-#define S3C2412_BANKCON3               S3C2412_MEMREG(0x0C)
-
-#define S3C2412_REFRESH                        S3C2412_MEMREG(0x10)
-#define S3C2412_TIMEOUT                        S3C2412_MEMREG(0x14)
-
-/* EBI control registers */
-
-#define S3C2412_EBI_PR                 S3C2412_EBIREG(0x00)
-#define S3C2412_EBI_BANKCFG            S3C2412_EBIREG(0x04)
-
-/* SSMC control registers */
-
-#define S3C2412_SSMC_BANK(x)           S3C2412_SSMC(x, 0x00)
-#define S3C2412_SMIDCYR(x)             S3C2412_SSMC(x, 0x00)
-#define S3C2412_SMBWSTRD(x)            S3C2412_SSMC(x, 0x04)
-#define S3C2412_SMBWSTWRR(x)           S3C2412_SSMC(x, 0x08)
-#define S3C2412_SMBWSTOENR(x)          S3C2412_SSMC(x, 0x0C)
-#define S3C2412_SMBWSTWENR(x)          S3C2412_SSMC(x, 0x10)
-#define S3C2412_SMBCR(x)               S3C2412_SSMC(x, 0x14)
-#define S3C2412_SMBSR(x)               S3C2412_SSMC(x, 0x18)
-#define S3C2412_SMBWSTBRDR(x)          S3C2412_SSMC(x, 0x1C)
-
-#endif /*  __ASM_ARM_REGS_S3C2412_MEM */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2412.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2412.h
deleted file mode 100644 (file)
index aa69dc7..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-s3c2412.h
- *
- * Copyright 2007 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2412 specific register definitions
-*/
-
-#ifndef __ASM_ARCH_REGS_S3C2412_H
-#define __ASM_ARCH_REGS_S3C2412_H "s3c2412"
-
-#define S3C2412_SWRST          (S3C24XX_VA_CLKPWR + 0x30)
-#define S3C2412_SWRST_RESET    (0x533C2412)
-
-/* see regs-power.h for the other registers in the power block. */
-
-#endif /* __ASM_ARCH_REGS_S3C2412_H */
-
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
deleted file mode 100644 (file)
index 2f31b74..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
- *
- * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
- *     as part of OpenInkpot project
- * Copyright (c) 2009 Promwad Innovation Company
- *     Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2416 memory register definitions
-*/
-
-#ifndef __ASM_ARM_REGS_S3C2416_MEM
-#define __ASM_ARM_REGS_S3C2416_MEM
-
-#ifndef S3C2416_MEMREG
-#define S3C2416_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
-#endif
-
-#define S3C2416_BANKCFG                        S3C2416_MEMREG(0x00)
-#define S3C2416_BANKCON1               S3C2416_MEMREG(0x04)
-#define S3C2416_BANKCON2               S3C2416_MEMREG(0x08)
-#define S3C2416_BANKCON3               S3C2416_MEMREG(0x0C)
-
-#define S3C2416_REFRESH                        S3C2416_MEMREG(0x10)
-#define S3C2416_TIMEOUT                        S3C2416_MEMREG(0x14)
-
-#endif /*  __ASM_ARM_REGS_S3C2416_MEM */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
deleted file mode 100644 (file)
index e443167..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
- *
- * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
- *     as part of OpenInkpot project
- * Copyright (c) 2009 Promwad Innovation Company
- *     Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2416 specific register definitions
-*/
-
-#ifndef __ASM_ARCH_REGS_S3C2416_H
-#define __ASM_ARCH_REGS_S3C2416_H "s3c2416"
-
-#define S3C2416_SWRST          (S3C24XX_VA_CLKPWR + 0x44)
-#define S3C2416_SWRST_RESET    (0x533C2416)
-
-/* see regs-power.h for the other registers in the power block. */
-
-#endif /* __ASM_ARCH_REGS_S3C2416_H */
-
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
deleted file mode 100644 (file)
index c3feff3..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
- *
- * Copyright (c) 2007 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2443 clock register definitions
-*/
-
-#ifndef __ASM_ARM_REGS_S3C2443_CLOCK
-#define __ASM_ARM_REGS_S3C2443_CLOCK
-
-#define S3C2443_CLKREG(x)              ((x) + S3C24XX_VA_CLKPWR)
-
-#define S3C2443_PLLCON_MDIVSHIFT       16
-#define S3C2443_PLLCON_PDIVSHIFT       8
-#define S3C2443_PLLCON_SDIVSHIFT       0
-#define S3C2443_PLLCON_MDIVMASK                ((1<<(1+(23-16)))-1)
-#define S3C2443_PLLCON_PDIVMASK                ((1<<(1+(9-8)))-1)
-#define S3C2443_PLLCON_SDIVMASK                (3)
-
-#define S3C2443_MPLLCON                        S3C2443_CLKREG(0x10)
-#define S3C2443_EPLLCON                        S3C2443_CLKREG(0x18)
-#define S3C2443_CLKSRC                 S3C2443_CLKREG(0x20)
-#define S3C2443_CLKDIV0                        S3C2443_CLKREG(0x24)
-#define S3C2443_CLKDIV1                        S3C2443_CLKREG(0x28)
-#define S3C2443_HCLKCON                        S3C2443_CLKREG(0x30)
-#define S3C2443_PCLKCON                        S3C2443_CLKREG(0x34)
-#define S3C2443_SCLKCON                        S3C2443_CLKREG(0x38)
-#define S3C2443_PWRMODE                        S3C2443_CLKREG(0x40)
-#define S3C2443_SWRST                  S3C2443_CLKREG(0x44)
-#define S3C2443_BUSPRI0                        S3C2443_CLKREG(0x50)
-#define S3C2443_SYSID                  S3C2443_CLKREG(0x5C)
-#define S3C2443_PWRCFG                 S3C2443_CLKREG(0x60)
-#define S3C2443_RSTCON                 S3C2443_CLKREG(0x64)
-#define S3C2443_PHYCTRL                        S3C2443_CLKREG(0x80)
-#define S3C2443_PHYPWR                 S3C2443_CLKREG(0x84)
-#define S3C2443_URSTCON                        S3C2443_CLKREG(0x88)
-#define S3C2443_UCLKCON                        S3C2443_CLKREG(0x8C)
-
-#define S3C2443_SWRST_RESET            (0x533c2443)
-
-#define S3C2443_PLLCON_OFF             (1<<24)
-
-#define S3C2443_CLKSRC_EPLLREF_XTAL    (2<<7)
-#define S3C2443_CLKSRC_EPLLREF_EXTCLK  (3<<7)
-#define S3C2443_CLKSRC_EPLLREF_MPLLREF (0<<7)
-#define S3C2443_CLKSRC_EPLLREF_MPLLREF2        (1<<7)
-#define S3C2443_CLKSRC_EPLLREF_MASK    (3<<7)
-
-#define S3C2443_CLKSRC_EXTCLK_DIV      (1<<3)
-
-#define S3C2443_CLKDIV0_HALF_HCLK      (1<<3)
-#define S3C2443_CLKDIV0_HALF_PCLK      (1<<2)
-
-#define S3C2443_CLKDIV0_HCLKDIV_MASK   (3<<0)
-
-#define S3C2443_CLKDIV0_EXTDIV_MASK    (3<<6)
-#define S3C2443_CLKDIV0_EXTDIV_SHIFT   (6)
-
-#define S3C2443_CLKDIV0_PREDIV_MASK    (3<<4)
-#define S3C2443_CLKDIV0_PREDIV_SHIFT   (4)
-
-#define S3C2416_CLKDIV0_ARMDIV_MASK    (7 << 9)
-#define S3C2443_CLKDIV0_ARMDIV_MASK    (15<<9)
-#define S3C2443_CLKDIV0_ARMDIV_SHIFT   (9)
-#define S3C2443_CLKDIV0_ARMDIV_1       (0<<9)
-#define S3C2443_CLKDIV0_ARMDIV_2       (8<<9)
-#define S3C2443_CLKDIV0_ARMDIV_3       (2<<9)
-#define S3C2443_CLKDIV0_ARMDIV_4       (9<<9)
-#define S3C2443_CLKDIV0_ARMDIV_6       (10<<9)
-#define S3C2443_CLKDIV0_ARMDIV_8       (11<<9)
-#define S3C2443_CLKDIV0_ARMDIV_12      (13<<9)
-#define S3C2443_CLKDIV0_ARMDIV_16      (15<<9)
-
-/* S3C2443_CLKDIV1 removed, only used in clock.c code */
-
-#define S3C2443_CLKCON_NAND
-
-#define S3C2443_HCLKCON_DMA0           (1<<0)
-#define S3C2443_HCLKCON_DMA1           (1<<1)
-#define S3C2443_HCLKCON_DMA2           (1<<2)
-#define S3C2443_HCLKCON_DMA3           (1<<3)
-#define S3C2443_HCLKCON_DMA4           (1<<4)
-#define S3C2443_HCLKCON_DMA5           (1<<5)
-#define S3C2443_HCLKCON_CAMIF          (1<<8)
-#define S3C2443_HCLKCON_LCDC           (1<<9)
-#define S3C2443_HCLKCON_USBH           (1<<11)
-#define S3C2443_HCLKCON_USBD           (1<<12)
-#define S3C2416_HCLKCON_HSMMC0         (1<<15)
-#define S3C2443_HCLKCON_HSMMC          (1<<16)
-#define S3C2443_HCLKCON_CFC            (1<<17)
-#define S3C2443_HCLKCON_SSMC           (1<<18)
-#define S3C2443_HCLKCON_DRAMC          (1<<19)
-
-#define S3C2443_PCLKCON_UART0          (1<<0)
-#define S3C2443_PCLKCON_UART1          (1<<1)
-#define S3C2443_PCLKCON_UART2          (1<<2)
-#define S3C2443_PCLKCON_UART3          (1<<3)
-#define S3C2443_PCLKCON_IIC            (1<<4)
-#define S3C2443_PCLKCON_SDI            (1<<5)
-#define S3C2443_PCLKCON_HSSPI          (1<<6)
-#define S3C2443_PCLKCON_ADC            (1<<7)
-#define S3C2443_PCLKCON_AC97           (1<<8)
-#define S3C2443_PCLKCON_IIS            (1<<9)
-#define S3C2443_PCLKCON_PWMT           (1<<10)
-#define S3C2443_PCLKCON_WDT            (1<<11)
-#define S3C2443_PCLKCON_RTC            (1<<12)
-#define S3C2443_PCLKCON_GPIO           (1<<13)
-#define S3C2443_PCLKCON_SPI0           (1<<14)
-#define S3C2443_PCLKCON_SPI1           (1<<15)
-
-#define S3C2443_SCLKCON_DDRCLK         (1<<16)
-#define S3C2443_SCLKCON_SSMCCLK                (1<<15)
-#define S3C2443_SCLKCON_HSSPICLK       (1<<14)
-#define S3C2443_SCLKCON_HSMMCCLK_EXT   (1<<13)
-#define S3C2443_SCLKCON_HSMMCCLK_EPLL  (1<<12)
-#define S3C2443_SCLKCON_CAMCLK         (1<<11)
-#define S3C2443_SCLKCON_DISPCLK                (1<<10)
-#define S3C2443_SCLKCON_I2SCLK         (1<<9)
-#define S3C2443_SCLKCON_UARTCLK                (1<<8)
-#define S3C2443_SCLKCON_USBHOST                (1<<1)
-
-#define S3C2443_PWRCFG_SLEEP           (1<<15)
-
-#define S3C2443_PWRCFG_USBPHY          (1 << 4)
-
-#define S3C2443_URSTCON_FUNCRST                (1 << 2)
-#define S3C2443_URSTCON_PHYRST         (1 << 0)
-
-#define S3C2443_PHYCTRL_CLKSEL         (1 << 3)
-#define S3C2443_PHYCTRL_EXTCLK         (1 << 2)
-#define S3C2443_PHYCTRL_PLLSEL         (1 << 1)
-#define S3C2443_PHYCTRL_DSPORT         (1 << 0)
-
-#define S3C2443_PHYPWR_COMMON_ON       (1 << 31)
-#define S3C2443_PHYPWR_ANALOG_PD       (1 << 4)
-#define S3C2443_PHYPWR_PLL_REFCLK      (1 << 3)
-#define S3C2443_PHYPWR_XO_ON           (1 << 2)
-#define S3C2443_PHYPWR_PLL_PWRDN       (1 << 1)
-#define S3C2443_PHYPWR_FSUSPEND                (1 << 0)
-
-#define S3C2443_UCLKCON_DETECT_VBUS    (1 << 31)
-#define S3C2443_UCLKCON_FUNC_CLKEN     (1 << 2)
-#define S3C2443_UCLKCON_TCLKEN         (1 << 0)
-
-#include <asm/div64.h>
-
-static inline unsigned int
-s3c2443_get_mpll(unsigned int pllval, unsigned int baseclk)
-{
-       unsigned int mdiv, pdiv, sdiv;
-       uint64_t fvco;
-
-       mdiv = pllval >> S3C2443_PLLCON_MDIVSHIFT;
-       pdiv = pllval >> S3C2443_PLLCON_PDIVSHIFT;
-       sdiv = pllval >> S3C2443_PLLCON_SDIVSHIFT;
-
-       mdiv &= S3C2443_PLLCON_MDIVMASK;
-       pdiv &= S3C2443_PLLCON_PDIVMASK;
-       sdiv &= S3C2443_PLLCON_SDIVMASK;
-
-       fvco = (uint64_t)baseclk * (2 * (mdiv + 8));
-       do_div(fvco, pdiv << sdiv);
-
-       return (unsigned int)fvco;
-}
-
-static inline unsigned int
-s3c2443_get_epll(unsigned int pllval, unsigned int baseclk)
-{
-       unsigned int mdiv, pdiv, sdiv;
-       uint64_t fvco;
-
-       mdiv = pllval >> S3C2443_PLLCON_MDIVSHIFT;
-       pdiv = pllval >> S3C2443_PLLCON_PDIVSHIFT;
-       sdiv = pllval >> S3C2443_PLLCON_SDIVSHIFT;
-
-       mdiv &= S3C2443_PLLCON_MDIVMASK;
-       pdiv &= S3C2443_PLLCON_PDIVMASK;
-       sdiv &= S3C2443_PLLCON_SDIVMASK;
-
-       fvco = (uint64_t)baseclk * (mdiv + 8);
-       do_div(fvco, (pdiv + 2) << sdiv);
-
-       return (unsigned int)fvco;
-}
-
-#endif /*  __ASM_ARM_REGS_S3C2443_CLOCK */
-
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-sdi.h b/arch/arm/mach-s3c2410/include/mach/regs-sdi.h
deleted file mode 100644 (file)
index cbf2d88..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-sdi.h
- *
- * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
- *                   http://www.simtec.co.uk/products/SWLINUX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2410 MMC/SDIO register definitions
-*/
-
-#ifndef __ASM_ARM_REGS_SDI
-#define __ASM_ARM_REGS_SDI "regs-sdi.h"
-
-#define S3C2410_SDICON                (0x00)
-#define S3C2410_SDIPRE                (0x04)
-#define S3C2410_SDICMDARG             (0x08)
-#define S3C2410_SDICMDCON             (0x0C)
-#define S3C2410_SDICMDSTAT            (0x10)
-#define S3C2410_SDIRSP0               (0x14)
-#define S3C2410_SDIRSP1               (0x18)
-#define S3C2410_SDIRSP2               (0x1C)
-#define S3C2410_SDIRSP3               (0x20)
-#define S3C2410_SDITIMER              (0x24)
-#define S3C2410_SDIBSIZE              (0x28)
-#define S3C2410_SDIDCON               (0x2C)
-#define S3C2410_SDIDCNT               (0x30)
-#define S3C2410_SDIDSTA               (0x34)
-#define S3C2410_SDIFSTA               (0x38)
-
-#define S3C2410_SDIDATA               (0x3C)
-#define S3C2410_SDIIMSK               (0x40)
-
-#define S3C2440_SDIDATA               (0x40)
-#define S3C2440_SDIIMSK               (0x3C)
-
-#define S3C2440_SDICON_SDRESET        (1<<8)
-#define S3C2440_SDICON_MMCCLOCK       (1<<5)
-#define S3C2410_SDICON_BYTEORDER      (1<<4)
-#define S3C2410_SDICON_SDIOIRQ        (1<<3)
-#define S3C2410_SDICON_RWAITEN        (1<<2)
-#define S3C2410_SDICON_FIFORESET      (1<<1)
-#define S3C2410_SDICON_CLOCKTYPE      (1<<0)
-
-#define S3C2410_SDICMDCON_ABORT       (1<<12)
-#define S3C2410_SDICMDCON_WITHDATA    (1<<11)
-#define S3C2410_SDICMDCON_LONGRSP     (1<<10)
-#define S3C2410_SDICMDCON_WAITRSP     (1<<9)
-#define S3C2410_SDICMDCON_CMDSTART    (1<<8)
-#define S3C2410_SDICMDCON_SENDERHOST  (1<<6)
-#define S3C2410_SDICMDCON_INDEX       (0x3f)
-
-#define S3C2410_SDICMDSTAT_CRCFAIL    (1<<12)
-#define S3C2410_SDICMDSTAT_CMDSENT    (1<<11)
-#define S3C2410_SDICMDSTAT_CMDTIMEOUT (1<<10)
-#define S3C2410_SDICMDSTAT_RSPFIN     (1<<9)
-#define S3C2410_SDICMDSTAT_XFERING    (1<<8)
-#define S3C2410_SDICMDSTAT_INDEX      (0xff)
-
-#define S3C2440_SDIDCON_DS_BYTE       (0<<22)
-#define S3C2440_SDIDCON_DS_HALFWORD   (1<<22)
-#define S3C2440_SDIDCON_DS_WORD       (2<<22)
-#define S3C2410_SDIDCON_IRQPERIOD     (1<<21)
-#define S3C2410_SDIDCON_TXAFTERRESP   (1<<20)
-#define S3C2410_SDIDCON_RXAFTERCMD    (1<<19)
-#define S3C2410_SDIDCON_BUSYAFTERCMD  (1<<18)
-#define S3C2410_SDIDCON_BLOCKMODE     (1<<17)
-#define S3C2410_SDIDCON_WIDEBUS       (1<<16)
-#define S3C2410_SDIDCON_DMAEN         (1<<15)
-#define S3C2410_SDIDCON_STOP          (1<<14)
-#define S3C2440_SDIDCON_DATSTART      (1<<14)
-#define S3C2410_SDIDCON_DATMODE              (3<<12)
-#define S3C2410_SDIDCON_BLKNUM        (0x7ff)
-
-/* constants for S3C2410_SDIDCON_DATMODE */
-#define S3C2410_SDIDCON_XFER_READY    (0<<12)
-#define S3C2410_SDIDCON_XFER_CHKSTART (1<<12)
-#define S3C2410_SDIDCON_XFER_RXSTART  (2<<12)
-#define S3C2410_SDIDCON_XFER_TXSTART  (3<<12)
-
-#define S3C2410_SDIDCON_BLKNUM_MASK   (0xFFF)
-#define S3C2410_SDIDCNT_BLKNUM_SHIFT  (12)
-
-#define S3C2410_SDIDSTA_RDYWAITREQ    (1<<10)
-#define S3C2410_SDIDSTA_SDIOIRQDETECT (1<<9)
-#define S3C2410_SDIDSTA_FIFOFAIL      (1<<8)   /* reserved on 2440 */
-#define S3C2410_SDIDSTA_CRCFAIL       (1<<7)
-#define S3C2410_SDIDSTA_RXCRCFAIL     (1<<6)
-#define S3C2410_SDIDSTA_DATATIMEOUT   (1<<5)
-#define S3C2410_SDIDSTA_XFERFINISH    (1<<4)
-#define S3C2410_SDIDSTA_BUSYFINISH    (1<<3)
-#define S3C2410_SDIDSTA_SBITERR       (1<<2)   /* reserved on 2410a/2440 */
-#define S3C2410_SDIDSTA_TXDATAON      (1<<1)
-#define S3C2410_SDIDSTA_RXDATAON      (1<<0)
-
-#define S3C2440_SDIFSTA_FIFORESET      (1<<16)
-#define S3C2440_SDIFSTA_FIFOFAIL       (3<<14)  /* 3 is correct (2 bits) */
-#define S3C2410_SDIFSTA_TFDET          (1<<13)
-#define S3C2410_SDIFSTA_RFDET          (1<<12)
-#define S3C2410_SDIFSTA_TFHALF         (1<<11)
-#define S3C2410_SDIFSTA_TFEMPTY        (1<<10)
-#define S3C2410_SDIFSTA_RFLAST         (1<<9)
-#define S3C2410_SDIFSTA_RFFULL         (1<<8)
-#define S3C2410_SDIFSTA_RFHALF         (1<<7)
-#define S3C2410_SDIFSTA_COUNTMASK      (0x7f)
-
-#define S3C2410_SDIIMSK_RESPONSECRC    (1<<17)
-#define S3C2410_SDIIMSK_CMDSENT        (1<<16)
-#define S3C2410_SDIIMSK_CMDTIMEOUT     (1<<15)
-#define S3C2410_SDIIMSK_RESPONSEND     (1<<14)
-#define S3C2410_SDIIMSK_READWAIT       (1<<13)
-#define S3C2410_SDIIMSK_SDIOIRQ        (1<<12)
-#define S3C2410_SDIIMSK_FIFOFAIL       (1<<11)
-#define S3C2410_SDIIMSK_CRCSTATUS      (1<<10)
-#define S3C2410_SDIIMSK_DATACRC        (1<<9)
-#define S3C2410_SDIIMSK_DATATIMEOUT    (1<<8)
-#define S3C2410_SDIIMSK_DATAFINISH     (1<<7)
-#define S3C2410_SDIIMSK_BUSYFINISH     (1<<6)
-#define S3C2410_SDIIMSK_SBITERR        (1<<5)  /* reserved 2440/2410a */
-#define S3C2410_SDIIMSK_TXFIFOHALF     (1<<4)
-#define S3C2410_SDIIMSK_TXFIFOEMPTY    (1<<3)
-#define S3C2410_SDIIMSK_RXFIFOLAST     (1<<2)
-#define S3C2410_SDIIMSK_RXFIFOFULL     (1<<1)
-#define S3C2410_SDIIMSK_RXFIFOHALF     (1<<0)
-
-#endif /* __ASM_ARM_REGS_SDI */
diff --git a/arch/arm/mach-s3c2410/include/mach/spi.h b/arch/arm/mach-s3c2410/include/mach/spi.h
deleted file mode 100644 (file)
index 4d95883..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/spi.h
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - SPI Controller platform_device info
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_SPI_H
-#define __ASM_ARCH_SPI_H __FILE__
-
-struct s3c2410_spi_info {
-       int                      pin_cs;        /* simple gpio cs */
-       unsigned int             num_cs;        /* total chipselects */
-       int                      bus_num;       /* bus number to use. */
-
-       unsigned int             use_fiq:1;     /* use fiq */
-
-       void (*gpio_setup)(struct s3c2410_spi_info *spi, int enable);
-       void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol);
-};
-
-/* Standard setup / suspend routines for SPI GPIO pins. */
-
-extern void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi,
-                                                int enable);
-
-extern void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi,
-                                             int enable);
-
-extern void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi,
-                                              int enable);
-
-#endif /* __ASM_ARCH_SPI_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/tick.h b/arch/arm/mach-s3c2410/include/mach/tick.h
deleted file mode 100644 (file)
index 544da41..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/include/mach/tick.h
- *
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C2410 - timer tick support
- */
-
-#define SRCPND_TIMER4 (1<<(IRQ_TIMER4 - IRQ_EINT0))
-
-static inline int s3c24xx_ostimer_pending(void)
-{
-       return __raw_readl(S3C2410_SRCPND) & SRCPND_TIMER4;
-}
diff --git a/arch/arm/mach-s3c2410/include/mach/timex.h b/arch/arm/mach-s3c2410/include/mach/timex.h
deleted file mode 100644 (file)
index fe9ca1f..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/timex.h
- *
- * Copyright (c) 2003-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - time parameters
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_TIMEX_H
-#define __ASM_ARCH_TIMEX_H
-
-/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
- * a variable is useless. It seems as long as we make our timers an
- * exact multiple of HZ, any value that makes a 1->1 correspondence
- * for the time conversion functions to/from jiffies is acceptable.
-*/
-
-#define CLOCK_TICK_RATE 12000000
-
-#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/uncompress.h b/arch/arm/mach-s3c2410/include/mach/uncompress.h
deleted file mode 100644 (file)
index 8b283f8..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/uncompress.h
- *
- * Copyright (c) 2003-2007 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - uncompress code
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_UNCOMPRESS_H
-#define __ASM_ARCH_UNCOMPRESS_H
-
-#include <mach/regs-gpio.h>
-#include <mach/map.h>
-
-/* working in physical space... */
-#undef S3C2410_GPIOREG
-#define S3C2410_GPIOREG(x) ((S3C24XX_PA_GPIO + (x)))
-
-#include <plat/uncompress.h>
-
-static inline int is_arm926(void)
-{
-       unsigned int cpuid;
-
-       asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r" (cpuid));
-
-       return ((cpuid & 0xff0) == 0x260);
-}
-
-static void arch_detect_cpu(void)
-{
-       unsigned int cpuid;
-
-       cpuid = *((volatile unsigned int *)S3C2410_GSTATUS1);
-       cpuid &= S3C2410_GSTATUS1_IDMASK;
-
-       if (is_arm926() || cpuid == S3C2410_GSTATUS1_2440 ||
-           cpuid == S3C2410_GSTATUS1_2442 ||
-           cpuid == S3C2410_GSTATUS1_2416 ||
-           cpuid == S3C2410_GSTATUS1_2450) {
-               fifo_mask = S3C2440_UFSTAT_TXMASK;
-               fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
-       } else {
-               fifo_mask = S3C2410_UFSTAT_TXMASK;
-               fifo_max = 15 << S3C2410_UFSTAT_TXSHIFT;
-       }
-}
-
-#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/vr1000-cpld.h b/arch/arm/mach-s3c2410/include/mach/vr1000-cpld.h
deleted file mode 100644 (file)
index e411991..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/vr1000-cpld.h
- *
- * Copyright (c) 2003 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * VR1000 - CPLD control constants
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_VR1000CPLD_H
-#define __ASM_ARCH_VR1000CPLD_H
-
-#define VR1000_CPLD_CTRL2_RAMWEN     (0x04)   /* SRAM Write Enable */
-
-#endif /* __ASM_ARCH_VR1000CPLD_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/vr1000-irq.h b/arch/arm/mach-s3c2410/include/mach/vr1000-irq.h
deleted file mode 100644 (file)
index 47add13..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/vr1000-irq.h
- *
- * Copyright (c) 2003-2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Machine VR1000 - IRQ Number definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_VR1000IRQ_H
-#define __ASM_ARCH_VR1000IRQ_H
-
-/* irq numbers to onboard peripherals */
-
-#define IRQ_USBOC           IRQ_EINT19
-#define IRQ_IDE0            IRQ_EINT16
-#define IRQ_IDE1            IRQ_EINT17
-#define IRQ_VR1000_SERIAL    IRQ_EINT12
-#define IRQ_VR1000_DM9000A   IRQ_EINT10
-#define IRQ_VR1000_DM9000N   IRQ_EINT9
-#define IRQ_SMALERT         IRQ_EINT8
-
-#endif /* __ASM_ARCH_VR1000IRQ_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/vr1000-map.h b/arch/arm/mach-s3c2410/include/mach/vr1000-map.h
deleted file mode 100644 (file)
index 99612fc..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/vr1000-map.h
- *
- * Copyright (c) 2003-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Machine VR1000 - Memory map definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* needs arch/map.h including with this */
-
-/* ok, we've used up to 0x13000000, now we need to find space for the
- * peripherals that live in the nGCS[x] areas, which are quite numerous
- * in their space. We also have the board's CPLD to find register space
- * for.
- */
-
-#ifndef __ASM_ARCH_VR1000MAP_H
-#define __ASM_ARCH_VR1000MAP_H
-
-#include <mach/bast-map.h>
-
-#define VR1000_IOADDR(x) BAST_IOADDR(x)
-
-/* we put the CPLD registers next, to get them out of the way */
-
-#define VR1000_VA_CTRL1            VR1000_IOADDR(0x00000000)    /* 0x01300000 */
-#define VR1000_PA_CTRL1            (S3C2410_CS5 | 0x7800000)
-
-#define VR1000_VA_CTRL2            VR1000_IOADDR(0x00100000)    /* 0x01400000 */
-#define VR1000_PA_CTRL2            (S3C2410_CS1 | 0x6000000)
-
-#define VR1000_VA_CTRL3            VR1000_IOADDR(0x00200000)    /* 0x01500000 */
-#define VR1000_PA_CTRL3            (S3C2410_CS1 | 0x6800000)
-
-#define VR1000_VA_CTRL4            VR1000_IOADDR(0x00300000)    /* 0x01600000 */
-#define VR1000_PA_CTRL4            (S3C2410_CS1 | 0x7000000)
-
-/* next, we have the PC104 ISA interrupt registers */
-
-#define VR1000_PA_PC104_IRQREQ  (S3C2410_CS5 | 0x6000000) /* 0x01700000 */
-#define VR1000_VA_PC104_IRQREQ  VR1000_IOADDR(0x00400000)
-
-#define VR1000_PA_PC104_IRQRAW  (S3C2410_CS5 | 0x6800000) /* 0x01800000 */
-#define VR1000_VA_PC104_IRQRAW  VR1000_IOADDR(0x00500000)
-
-#define VR1000_PA_PC104_IRQMASK (S3C2410_CS5 | 0x7000000) /* 0x01900000 */
-#define VR1000_VA_PC104_IRQMASK VR1000_IOADDR(0x00600000)
-
-/* 0xE0000000 contains the IO space that is split by speed and
- * wether the access is for 8 or 16bit IO... this ensures that
- * the correct access is made
- *
- * 0x10000000 of space, partitioned as so:
- *
- * 0x00000000 to 0x04000000  8bit,  slow
- * 0x04000000 to 0x08000000  16bit, slow
- * 0x08000000 to 0x0C000000  16bit, net
- * 0x0C000000 to 0x10000000  16bit, fast
- *
- * each of these spaces has the following in:
- *
- * 0x02000000 to 0x02100000 1MB  IDE primary channel
- * 0x02100000 to 0x02200000 1MB  IDE primary channel aux
- * 0x02200000 to 0x02400000 1MB  IDE secondary channel
- * 0x02300000 to 0x02400000 1MB  IDE secondary channel aux
- * 0x02500000 to 0x02600000 1MB  Davicom DM9000 ethernet controllers
- * 0x02600000 to 0x02700000 1MB
- *
- * the phyiscal layout of the zones are:
- *  nGCS2 - 8bit, slow
- *  nGCS3 - 16bit, slow
- *  nGCS4 - 16bit, net
- *  nGCS5 - 16bit, fast
- */
-
-#define VR1000_VA_MULTISPACE (0xE0000000)
-
-#define VR1000_VA_ISAIO                   (VR1000_VA_MULTISPACE + 0x00000000)
-#define VR1000_VA_ISAMEM          (VR1000_VA_MULTISPACE + 0x01000000)
-#define VR1000_VA_IDEPRI          (VR1000_VA_MULTISPACE + 0x02000000)
-#define VR1000_VA_IDEPRIAUX       (VR1000_VA_MULTISPACE + 0x02100000)
-#define VR1000_VA_IDESEC          (VR1000_VA_MULTISPACE + 0x02200000)
-#define VR1000_VA_IDESECAUX       (VR1000_VA_MULTISPACE + 0x02300000)
-#define VR1000_VA_ASIXNET         (VR1000_VA_MULTISPACE + 0x02400000)
-#define VR1000_VA_DM9000          (VR1000_VA_MULTISPACE + 0x02500000)
-#define VR1000_VA_SUPERIO         (VR1000_VA_MULTISPACE + 0x02600000)
-
-/* physical offset addresses for the peripherals */
-
-#define VR1000_PA_IDEPRI          (0x02000000)
-#define VR1000_PA_IDEPRIAUX       (0x02800000)
-#define VR1000_PA_IDESEC          (0x03000000)
-#define VR1000_PA_IDESECAUX       (0x03800000)
-#define VR1000_PA_DM9000          (0x05000000)
-
-#define VR1000_PA_SERIAL          (0x11800000)
-#define VR1000_VA_SERIAL          (VR1000_IOADDR(0x00700000))
-
-/* VR1000 ram is in CS1, with A26..A24 = 2_101 */
-#define VR1000_PA_SRAM            (S3C2410_CS1 | 0x05000000)
-
-/* some configurations for the peripherals */
-
-#define VR1000_DM9000_CS        VR1000_VAM_CS4
-
-#endif /* __ASM_ARCH_VR1000MAP_H */
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
deleted file mode 100644 (file)
index 4220cc6..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/mach-amlm5900.c
- *
- * linux/arch/arm/mach-s3c2410/mach-amlm5900.c
- *
- * Copyright (c) 2006 American Microsystems Limited
- *     David Anders <danders@amltd.com>
-
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * @History:
- * derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by
- * Ben Dooks <ben@simtec.co.uk>
- *
- ***********************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/proc_fs.h>
-#include <linux/serial_core.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/flash.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-#include <mach/fb.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-lcd.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/gpio-cfg.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/physmap.h>
-
-#include "common.h"
-
-static struct resource amlm5900_nor_resource = {
-               .start = 0x00000000,
-               .end   = 0x01000000 - 1,
-               .flags = IORESOURCE_MEM,
-};
-
-
-
-static struct mtd_partition amlm5900_mtd_partitions[] = {
-       {
-               .name           = "System",
-               .size           = 0x240000,
-               .offset         = 0,
-               .mask_flags     = MTD_WRITEABLE,  /* force read-only */
-       }, {
-               .name           = "Kernel",
-               .size           = 0x100000,
-               .offset         = MTDPART_OFS_APPEND,
-       }, {
-               .name           = "Ramdisk",
-               .size           = 0x300000,
-               .offset         = MTDPART_OFS_APPEND,
-       }, {
-               .name           = "JFFS2",
-               .size           = 0x9A0000,
-               .offset         = MTDPART_OFS_APPEND,
-       }, {
-               .name           = "Settings",
-               .size           = MTDPART_SIZ_FULL,
-               .offset         = MTDPART_OFS_APPEND,
-       }
-};
-
-static struct physmap_flash_data amlm5900_flash_data = {
-       .width          = 2,
-       .parts          = amlm5900_mtd_partitions,
-       .nr_parts       = ARRAY_SIZE(amlm5900_mtd_partitions),
-};
-
-static struct platform_device amlm5900_device_nor = {
-       .name           = "physmap-flash",
-       .id             = 0,
-       .dev = {
-                       .platform_data = &amlm5900_flash_data,
-               },
-       .num_resources  = 1,
-       .resource       = &amlm5900_nor_resource,
-};
-
-static struct map_desc amlm5900_iodesc[] __initdata = {
-};
-
-#define UCON S3C2410_UCON_DEFAULT
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg amlm5900_uartcfgs[] = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       }
-};
-
-
-static struct platform_device *amlm5900_devices[] __initdata = {
-#ifdef CONFIG_FB_S3C2410
-       &s3c_device_lcd,
-#endif
-       &s3c_device_adc,
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_ohci,
-       &s3c_device_rtc,
-       &s3c_device_usbgadget,
-        &s3c_device_sdi,
-       &amlm5900_device_nor,
-};
-
-static void __init amlm5900_map_io(void)
-{
-       s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc));
-       s3c24xx_init_clocks(0);
-       s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs));
-}
-
-#ifdef CONFIG_FB_S3C2410
-static struct s3c2410fb_display __initdata amlm5900_lcd_info = {
-       .width          = 160,
-       .height         = 160,
-
-       .type           = S3C2410_LCDCON1_STN4,
-
-       .pixclock       = 680000, /* HCLK = 100MHz */
-       .xres           = 160,
-       .yres           = 160,
-       .bpp            = 4,
-       .left_margin    = 1 << (4 + 3),
-       .right_margin   = 8 << 3,
-       .hsync_len      = 48,
-       .upper_margin   = 0,
-       .lower_margin   = 0,
-
-       .lcdcon5        = 0x00000001,
-};
-
-static struct s3c2410fb_mach_info __initdata amlm5900_fb_info = {
-
-       .displays = &amlm5900_lcd_info,
-       .num_displays = 1,
-       .default_display = 0,
-
-       .gpccon =       0xaaaaaaaa,
-       .gpccon_mask =  0xffffffff,
-       .gpcup =        0x0000ffff,
-       .gpcup_mask =   0xffffffff,
-
-       .gpdcon =       0xaaaaaaaa,
-       .gpdcon_mask =  0xffffffff,
-       .gpdup =        0x0000ffff,
-       .gpdup_mask =   0xffffffff,
-};
-#endif
-
-static irqreturn_t
-amlm5900_wake_interrupt(int irq, void *ignored)
-{
-       return IRQ_HANDLED;
-}
-
-static void amlm5900_init_pm(void)
-{
-       int ret = 0;
-
-       ret = request_irq(IRQ_EINT9, &amlm5900_wake_interrupt,
-                               IRQF_TRIGGER_RISING | IRQF_SHARED,
-                               "amlm5900_wakeup", &amlm5900_wake_interrupt);
-       if (ret != 0) {
-               printk(KERN_ERR "AML-M5900: no wakeup irq, %d?\n", ret);
-       } else {
-               enable_irq_wake(IRQ_EINT9);
-               /* configure the suspend/resume status pin */
-               s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT);
-               s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_UP);
-       }
-}
-static void __init amlm5900_init(void)
-{
-       amlm5900_init_pm();
-#ifdef CONFIG_FB_S3C2410
-       s3c24xx_fb_set_platdata(&amlm5900_fb_info);
-#endif
-       s3c_i2c0_set_platdata(NULL);
-       platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices));
-}
-
-MACHINE_START(AML_M5900, "AML_M5900")
-       .atag_offset    = 0x100,
-       .map_io         = amlm5900_map_io,
-       .init_irq       = s3c24xx_init_irq,
-       .init_machine   = amlm5900_init,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c2410_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
deleted file mode 100644 (file)
index feeaf73..0000000
+++ /dev/null
@@ -1,645 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/mach-bast.c
- *
- * Copyright 2003-2008 Simtec Electronics
- *   Ben Dooks <ben@simtec.co.uk>
- *
- * http://www.simtec.co.uk/products/EB2410ITX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/syscore_ops.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/dm9000.h>
-#include <linux/ata_platform.h>
-#include <linux/i2c.h>
-#include <linux/io.h>
-
-#include <net/ax88796.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/bast-map.h>
-#include <mach/bast-irq.h>
-#include <mach/bast-cpld.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-//#include <asm/debug-ll.h>
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-mem.h>
-#include <mach/regs-lcd.h>
-
-#include <plat/hwmon.h>
-#include <plat/nand.h>
-#include <plat/iic.h>
-#include <mach/fb.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include <linux/serial_8250.h>
-
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/cpu-freq.h>
-#include <plat/gpio-cfg.h>
-#include <plat/audio-simtec.h>
-
-#include "usb-simtec.h"
-#include "nor-simtec.h"
-#include "common.h"
-
-#define COPYRIGHT ", Copyright 2004-2008 Simtec Electronics"
-
-/* macros for virtual address mods for the io space entries */
-#define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5)
-#define VA_C4(item) ((unsigned long)(item) + BAST_VAM_CS4)
-#define VA_C3(item) ((unsigned long)(item) + BAST_VAM_CS3)
-#define VA_C2(item) ((unsigned long)(item) + BAST_VAM_CS2)
-
-/* macros to modify the physical addresses for io space */
-
-#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2))
-#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3))
-#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4))
-#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5))
-
-static struct map_desc bast_iodesc[] __initdata = {
-  /* ISA IO areas */
-  {
-         .virtual      = (u32)S3C24XX_VA_ISA_BYTE,
-         .pfn          = PA_CS2(BAST_PA_ISAIO),
-         .length       = SZ_16M,
-         .type         = MT_DEVICE,
-  }, {
-         .virtual      = (u32)S3C24XX_VA_ISA_WORD,
-         .pfn          = PA_CS3(BAST_PA_ISAIO),
-         .length       = SZ_16M,
-         .type         = MT_DEVICE,
-  },
-  /* bast CPLD control registers, and external interrupt controls */
-  {
-         .virtual      = (u32)BAST_VA_CTRL1,
-         .pfn          = __phys_to_pfn(BAST_PA_CTRL1),
-         .length       = SZ_1M,
-         .type         = MT_DEVICE,
-  }, {
-         .virtual      = (u32)BAST_VA_CTRL2,
-         .pfn          = __phys_to_pfn(BAST_PA_CTRL2),
-         .length       = SZ_1M,
-         .type         = MT_DEVICE,
-  }, {
-         .virtual      = (u32)BAST_VA_CTRL3,
-         .pfn          = __phys_to_pfn(BAST_PA_CTRL3),
-         .length       = SZ_1M,
-         .type         = MT_DEVICE,
-  }, {
-         .virtual      = (u32)BAST_VA_CTRL4,
-         .pfn          = __phys_to_pfn(BAST_PA_CTRL4),
-         .length       = SZ_1M,
-         .type         = MT_DEVICE,
-  },
-  /* PC104 IRQ mux */
-  {
-         .virtual      = (u32)BAST_VA_PC104_IRQREQ,
-         .pfn          = __phys_to_pfn(BAST_PA_PC104_IRQREQ),
-         .length       = SZ_1M,
-         .type         = MT_DEVICE,
-  }, {
-         .virtual      = (u32)BAST_VA_PC104_IRQRAW,
-         .pfn          = __phys_to_pfn(BAST_PA_PC104_IRQRAW),
-         .length       = SZ_1M,
-         .type         = MT_DEVICE,
-  }, {
-         .virtual      = (u32)BAST_VA_PC104_IRQMASK,
-         .pfn          = __phys_to_pfn(BAST_PA_PC104_IRQMASK),
-         .length       = SZ_1M,
-         .type         = MT_DEVICE,
-  },
-
-  /* peripheral space... one for each of fast/slow/byte/16bit */
-  /* note, ide is only decoded in word space, even though some registers
-   * are only 8bit */
-
-  /* slow, byte */
-  { VA_C2(BAST_VA_ISAIO),   PA_CS2(BAST_PA_ISAIO),    SZ_16M, MT_DEVICE },
-  { VA_C2(BAST_VA_ISAMEM),  PA_CS2(BAST_PA_ISAMEM),   SZ_16M, MT_DEVICE },
-  { VA_C2(BAST_VA_SUPERIO), PA_CS2(BAST_PA_SUPERIO),  SZ_1M,  MT_DEVICE },
-
-  /* slow, word */
-  { VA_C3(BAST_VA_ISAIO),   PA_CS3(BAST_PA_ISAIO),    SZ_16M, MT_DEVICE },
-  { VA_C3(BAST_VA_ISAMEM),  PA_CS3(BAST_PA_ISAMEM),   SZ_16M, MT_DEVICE },
-  { VA_C3(BAST_VA_SUPERIO), PA_CS3(BAST_PA_SUPERIO),  SZ_1M,  MT_DEVICE },
-
-  /* fast, byte */
-  { VA_C4(BAST_VA_ISAIO),   PA_CS4(BAST_PA_ISAIO),    SZ_16M, MT_DEVICE },
-  { VA_C4(BAST_VA_ISAMEM),  PA_CS4(BAST_PA_ISAMEM),   SZ_16M, MT_DEVICE },
-  { VA_C4(BAST_VA_SUPERIO), PA_CS4(BAST_PA_SUPERIO),  SZ_1M,  MT_DEVICE },
-
-  /* fast, word */
-  { VA_C5(BAST_VA_ISAIO),   PA_CS5(BAST_PA_ISAIO),    SZ_16M, MT_DEVICE },
-  { VA_C5(BAST_VA_ISAMEM),  PA_CS5(BAST_PA_ISAMEM),   SZ_16M, MT_DEVICE },
-  { VA_C5(BAST_VA_SUPERIO), PA_CS5(BAST_PA_SUPERIO),  SZ_1M,  MT_DEVICE },
-};
-
-#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       /* port 2 is not actually used */
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       }
-};
-
-/* NAND Flash on BAST board */
-
-#ifdef CONFIG_PM
-static int bast_pm_suspend(void)
-{
-       /* ensure that an nRESET is not generated on resume. */
-       gpio_direction_output(S3C2410_GPA(21), 1);
-       return 0;
-}
-
-static void bast_pm_resume(void)
-{
-       s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
-}
-
-#else
-#define bast_pm_suspend NULL
-#define bast_pm_resume NULL
-#endif
-
-static struct syscore_ops bast_pm_syscore_ops = {
-       .suspend        = bast_pm_suspend,
-       .resume         = bast_pm_resume,
-};
-
-static int smartmedia_map[] = { 0 };
-static int chip0_map[] = { 1 };
-static int chip1_map[] = { 2 };
-static int chip2_map[] = { 3 };
-
-static struct mtd_partition __initdata bast_default_nand_part[] = {
-       [0] = {
-               .name   = "Boot Agent",
-               .size   = SZ_16K,
-               .offset = 0,
-       },
-       [1] = {
-               .name   = "/boot",
-               .size   = SZ_4M - SZ_16K,
-               .offset = SZ_16K,
-       },
-       [2] = {
-               .name   = "user",
-               .offset = SZ_4M,
-               .size   = MTDPART_SIZ_FULL,
-       }
-};
-
-/* the bast has 4 selectable slots for nand-flash, the three
- * on-board chip areas, as well as the external SmartMedia
- * slot.
- *
- * Note, there is no current hot-plug support for the SmartMedia
- * socket.
-*/
-
-static struct s3c2410_nand_set __initdata bast_nand_sets[] = {
-       [0] = {
-               .name           = "SmartMedia",
-               .nr_chips       = 1,
-               .nr_map         = smartmedia_map,
-               .options        = NAND_SCAN_SILENT_NODEV,
-               .nr_partitions  = ARRAY_SIZE(bast_default_nand_part),
-               .partitions     = bast_default_nand_part,
-       },
-       [1] = {
-               .name           = "chip0",
-               .nr_chips       = 1,
-               .nr_map         = chip0_map,
-               .nr_partitions  = ARRAY_SIZE(bast_default_nand_part),
-               .partitions     = bast_default_nand_part,
-       },
-       [2] = {
-               .name           = "chip1",
-               .nr_chips       = 1,
-               .nr_map         = chip1_map,
-               .options        = NAND_SCAN_SILENT_NODEV,
-               .nr_partitions  = ARRAY_SIZE(bast_default_nand_part),
-               .partitions     = bast_default_nand_part,
-       },
-       [3] = {
-               .name           = "chip2",
-               .nr_chips       = 1,
-               .nr_map         = chip2_map,
-               .options        = NAND_SCAN_SILENT_NODEV,
-               .nr_partitions  = ARRAY_SIZE(bast_default_nand_part),
-               .partitions     = bast_default_nand_part,
-       }
-};
-
-static void bast_nand_select(struct s3c2410_nand_set *set, int slot)
-{
-       unsigned int tmp;
-
-       slot = set->nr_map[slot] & 3;
-
-       pr_debug("bast_nand: selecting slot %d (set %p,%p)\n",
-                slot, set, set->nr_map);
-
-       tmp = __raw_readb(BAST_VA_CTRL2);
-       tmp &= BAST_CPLD_CTLR2_IDERST;
-       tmp |= slot;
-       tmp |= BAST_CPLD_CTRL2_WNAND;
-
-       pr_debug("bast_nand: ctrl2 now %02x\n", tmp);
-
-       __raw_writeb(tmp, BAST_VA_CTRL2);
-}
-
-static struct s3c2410_platform_nand __initdata bast_nand_info = {
-       .tacls          = 30,
-       .twrph0         = 60,
-       .twrph1         = 60,
-       .nr_sets        = ARRAY_SIZE(bast_nand_sets),
-       .sets           = bast_nand_sets,
-       .select_chip    = bast_nand_select,
-};
-
-/* DM9000 */
-
-static struct resource bast_dm9k_resource[] = {
-       [0] = {
-               .start = S3C2410_CS5 + BAST_PA_DM9000,
-               .end   = S3C2410_CS5 + BAST_PA_DM9000 + 3,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = S3C2410_CS5 + BAST_PA_DM9000 + 0x40,
-               .end   = S3C2410_CS5 + BAST_PA_DM9000 + 0x40 + 0x3f,
-               .flags = IORESOURCE_MEM,
-       },
-       [2] = {
-               .start = IRQ_DM9000,
-               .end   = IRQ_DM9000,
-               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-       }
-
-};
-
-/* for the moment we limit ourselves to 16bit IO until some
- * better IO routines can be written and tested
-*/
-
-static struct dm9000_plat_data bast_dm9k_platdata = {
-       .flags          = DM9000_PLATF_16BITONLY,
-};
-
-static struct platform_device bast_device_dm9k = {
-       .name           = "dm9000",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(bast_dm9k_resource),
-       .resource       = bast_dm9k_resource,
-       .dev            = {
-               .platform_data = &bast_dm9k_platdata,
-       }
-};
-
-/* serial devices */
-
-#define SERIAL_BASE  (S3C2410_CS2 + BAST_PA_SUPERIO)
-#define SERIAL_FLAGS (UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SHARE_IRQ)
-#define SERIAL_CLK   (1843200)
-
-static struct plat_serial8250_port bast_sio_data[] = {
-       [0] = {
-               .mapbase        = SERIAL_BASE + 0x2f8,
-               .irq            = IRQ_PCSERIAL1,
-               .flags          = SERIAL_FLAGS,
-               .iotype         = UPIO_MEM,
-               .regshift       = 0,
-               .uartclk        = SERIAL_CLK,
-       },
-       [1] = {
-               .mapbase        = SERIAL_BASE + 0x3f8,
-               .irq            = IRQ_PCSERIAL2,
-               .flags          = SERIAL_FLAGS,
-               .iotype         = UPIO_MEM,
-               .regshift       = 0,
-               .uartclk        = SERIAL_CLK,
-       },
-       { }
-};
-
-static struct platform_device bast_sio = {
-       .name                   = "serial8250",
-       .id                     = PLAT8250_DEV_PLATFORM,
-       .dev                    = {
-               .platform_data  = &bast_sio_data,
-       },
-};
-
-/* we have devices on the bus which cannot work much over the
- * standard 100KHz i2c bus frequency
-*/
-
-static struct s3c2410_platform_i2c __initdata bast_i2c_info = {
-       .flags          = 0,
-       .slave_addr     = 0x10,
-       .frequency      = 100*1000,
-};
-
-/* Asix AX88796 10/100 ethernet controller */
-
-static struct ax_plat_data bast_asix_platdata = {
-       .flags          = AXFLG_MAC_FROMDEV,
-       .wordlength     = 2,
-       .dcr_val        = 0x48,
-       .rcr_val        = 0x40,
-};
-
-static struct resource bast_asix_resource[] = {
-       [0] = {
-               .start = S3C2410_CS5 + BAST_PA_ASIXNET,
-               .end   = S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20) - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20),
-               .end   = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20),
-               .flags = IORESOURCE_MEM,
-       },
-       [2] = {
-               .start = IRQ_ASIX,
-               .end   = IRQ_ASIX,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-static struct platform_device bast_device_asix = {
-       .name           = "ax88796",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(bast_asix_resource),
-       .resource       = bast_asix_resource,
-       .dev            = {
-               .platform_data = &bast_asix_platdata
-       }
-};
-
-/* Asix AX88796 10/100 ethernet controller parallel port */
-
-static struct resource bast_asixpp_resource[] = {
-       [0] = {
-               .start = S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20),
-               .end   = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1b * 0x20) - 1,
-               .flags = IORESOURCE_MEM,
-       }
-};
-
-static struct platform_device bast_device_axpp = {
-       .name           = "ax88796-pp",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(bast_asixpp_resource),
-       .resource       = bast_asixpp_resource,
-};
-
-/* LCD/VGA controller */
-
-static struct s3c2410fb_display __initdata bast_lcd_info[] = {
-       {
-               .type           = S3C2410_LCDCON1_TFT,
-               .width          = 640,
-               .height         = 480,
-
-               .pixclock       = 33333,
-               .xres           = 640,
-               .yres           = 480,
-               .bpp            = 4,
-               .left_margin    = 40,
-               .right_margin   = 20,
-               .hsync_len      = 88,
-               .upper_margin   = 30,
-               .lower_margin   = 32,
-               .vsync_len      = 3,
-
-               .lcdcon5        = 0x00014b02,
-       },
-       {
-               .type           = S3C2410_LCDCON1_TFT,
-               .width          = 640,
-               .height         = 480,
-
-               .pixclock       = 33333,
-               .xres           = 640,
-               .yres           = 480,
-               .bpp            = 8,
-               .left_margin    = 40,
-               .right_margin   = 20,
-               .hsync_len      = 88,
-               .upper_margin   = 30,
-               .lower_margin   = 32,
-               .vsync_len      = 3,
-
-               .lcdcon5        = 0x00014b02,
-       },
-       {
-               .type           = S3C2410_LCDCON1_TFT,
-               .width          = 640,
-               .height         = 480,
-
-               .pixclock       = 33333,
-               .xres           = 640,
-               .yres           = 480,
-               .bpp            = 16,
-               .left_margin    = 40,
-               .right_margin   = 20,
-               .hsync_len      = 88,
-               .upper_margin   = 30,
-               .lower_margin   = 32,
-               .vsync_len      = 3,
-
-               .lcdcon5        = 0x00014b02,
-       },
-};
-
-/* LCD/VGA controller */
-
-static struct s3c2410fb_mach_info __initdata bast_fb_info = {
-
-       .displays = bast_lcd_info,
-       .num_displays = ARRAY_SIZE(bast_lcd_info),
-       .default_display = 1,
-};
-
-/* I2C devices fitted. */
-
-static struct i2c_board_info bast_i2c_devs[] __initdata = {
-       {
-               I2C_BOARD_INFO("tlv320aic23", 0x1a),
-       }, {
-               I2C_BOARD_INFO("simtec-pmu", 0x6b),
-       }, {
-               I2C_BOARD_INFO("ch7013", 0x75),
-       },
-};
-
-static struct s3c_hwmon_pdata bast_hwmon_info = {
-       /* LCD contrast (0-6.6V) */
-       .in[0] = &(struct s3c_hwmon_chcfg) {
-               .name           = "lcd-contrast",
-               .mult           = 3300,
-               .div            = 512,
-       },
-       /* LED current feedback */
-       .in[1] = &(struct s3c_hwmon_chcfg) {
-               .name           = "led-feedback",
-               .mult           = 3300,
-               .div            = 1024,
-       },
-       /* LCD feedback (0-6.6V) */
-       .in[2] = &(struct s3c_hwmon_chcfg) {
-               .name           = "lcd-feedback",
-               .mult           = 3300,
-               .div            = 512,
-       },
-       /* Vcore (1.8-2.0V), Vref 3.3V  */
-       .in[3] = &(struct s3c_hwmon_chcfg) {
-               .name           = "vcore",
-               .mult           = 3300,
-               .div            = 1024,
-       },
-};
-
-/* Standard BAST devices */
-// cat /sys/devices/platform/s3c24xx-adc/s3c-hwmon/in_0
-
-static struct platform_device *bast_devices[] __initdata = {
-       &s3c_device_ohci,
-       &s3c_device_lcd,
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_rtc,
-       &s3c_device_nand,
-       &s3c_device_adc,
-       &s3c_device_hwmon,
-       &bast_device_dm9k,
-       &bast_device_asix,
-       &bast_device_axpp,
-       &bast_sio,
-};
-
-static struct clk *bast_clocks[] __initdata = {
-       &s3c24xx_dclk0,
-       &s3c24xx_dclk1,
-       &s3c24xx_clkout0,
-       &s3c24xx_clkout1,
-       &s3c24xx_uclk,
-};
-
-static struct s3c_cpufreq_board __initdata bast_cpufreq = {
-       .refresh        = 7800, /* 7.8usec */
-       .auto_io        = 1,
-       .need_io        = 1,
-};
-
-static struct s3c24xx_audio_simtec_pdata __initdata bast_audio = {
-       .have_mic       = 1,
-       .have_lout      = 1,
-};
-
-static void __init bast_map_io(void)
-{
-       /* initialise the clocks */
-
-       s3c24xx_dclk0.parent = &clk_upll;
-       s3c24xx_dclk0.rate   = 12*1000*1000;
-
-       s3c24xx_dclk1.parent = &clk_upll;
-       s3c24xx_dclk1.rate   = 24*1000*1000;
-
-       s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
-       s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
-
-       s3c24xx_uclk.parent  = &s3c24xx_clkout1;
-
-       s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks));
-
-       s3c_hwmon_set_platdata(&bast_hwmon_info);
-
-       s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
-       s3c24xx_init_clocks(0);
-       s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
-}
-
-static void __init bast_init(void)
-{
-       register_syscore_ops(&bast_pm_syscore_ops);
-
-       s3c_i2c0_set_platdata(&bast_i2c_info);
-       s3c_nand_set_platdata(&bast_nand_info);
-       s3c24xx_fb_set_platdata(&bast_fb_info);
-       platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices));
-
-       i2c_register_board_info(0, bast_i2c_devs,
-                               ARRAY_SIZE(bast_i2c_devs));
-
-       usb_simtec_init();
-       nor_simtec_init();
-       simtec_audio_add(NULL, true, &bast_audio);
-
-       WARN_ON(gpio_request(S3C2410_GPA(21), "bast nreset"));
-       
-       s3c_cpufreq_setboard(&bast_cpufreq);
-}
-
-MACHINE_START(BAST, "Simtec-BAST")
-       /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
-       .atag_offset    = 0x100,
-       .map_io         = bast_map_io,
-       .init_irq       = s3c24xx_init_irq,
-       .init_machine   = bast_init,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c2410_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
deleted file mode 100644 (file)
index 41245a6..0000000
+++ /dev/null
@@ -1,757 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/mach-h1940.c
- *
- * Copyright (c) 2003-2005 Simtec Electronics
- *   Ben Dooks <ben@simtec.co.uk>
- *
- * http://www.handhelds.org/projects/h1940.html
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/memblock.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/input.h>
-#include <linux/gpio_keys.h>
-#include <linux/pwm_backlight.h>
-#include <linux/i2c.h>
-#include <linux/leds.h>
-#include <linux/pda_power.h>
-#include <linux/s3c_adc_battery.h>
-#include <linux/delay.h>
-
-#include <video/platform_lcd.h>
-
-#include <linux/mmc/host.h>
-#include <linux/export.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-lcd.h>
-#include <mach/regs-clock.h>
-
-#include <mach/regs-gpio.h>
-#include <mach/gpio-fns.h>
-#include <mach/gpio-nrs.h>
-
-#include <mach/h1940.h>
-#include <mach/h1940-latch.h>
-#include <mach/fb.h>
-#include <plat/udc.h>
-#include <plat/iic.h>
-
-#include <plat/gpio-cfg.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-#include <plat/pm.h>
-#include <plat/mci.h>
-#include <plat/ts.h>
-
-#include <sound/uda1380.h>
-
-#include "common.h"
-
-#define H1940_LATCH            ((void __force __iomem *)0xF8000000)
-
-#define H1940_PA_LATCH         S3C2410_CS2
-
-#define H1940_LATCH_BIT(x)     (1 << ((x) + 16 - S3C_GPIO_END))
-
-static struct map_desc h1940_iodesc[] __initdata = {
-       [0] = {
-               .virtual        = (unsigned long)H1940_LATCH,
-               .pfn            = __phys_to_pfn(H1940_PA_LATCH),
-               .length         = SZ_16K,
-               .type           = MT_DEVICE
-       },
-};
-
-#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg h1940_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = 0x245,
-               .ulcon       = 0x03,
-               .ufcon       = 0x00,
-       },
-       /* IR port */
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .uart_flags  = UPF_CONS_FLOW,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x43,
-               .ufcon       = 0x51,
-       }
-};
-
-/* Board control latch control */
-
-static unsigned int latch_state;
-
-static void h1940_latch_control(unsigned int clear, unsigned int set)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-
-       latch_state &= ~clear;
-       latch_state |= set;
-
-       __raw_writel(latch_state, H1940_LATCH);
-
-       local_irq_restore(flags);
-}
-
-static inline int h1940_gpiolib_to_latch(int offset)
-{
-       return 1 << (offset + 16);
-}
-
-static void h1940_gpiolib_latch_set(struct gpio_chip *chip,
-                                       unsigned offset, int value)
-{
-       int latch_bit = h1940_gpiolib_to_latch(offset);
-
-       h1940_latch_control(value ? 0 : latch_bit,
-               value ? latch_bit : 0);
-}
-
-static int h1940_gpiolib_latch_output(struct gpio_chip *chip,
-                                       unsigned offset, int value)
-{
-       h1940_gpiolib_latch_set(chip, offset, value);
-       return 0;
-}
-
-static int h1940_gpiolib_latch_get(struct gpio_chip *chip,
-                                       unsigned offset)
-{
-       return (latch_state >> (offset + 16)) & 1;
-}
-
-struct gpio_chip h1940_latch_gpiochip = {
-       .base                   = H1940_LATCH_GPIO(0),
-       .owner                  = THIS_MODULE,
-       .label                  = "H1940_LATCH",
-       .ngpio                  = 16,
-       .direction_output       = h1940_gpiolib_latch_output,
-       .set                    = h1940_gpiolib_latch_set,
-       .get                    = h1940_gpiolib_latch_get,
-};
-
-static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
-       .vbus_pin               = S3C2410_GPG(5),
-       .vbus_pin_inverted      = 1,
-       .pullup_pin             = H1940_LATCH_USB_DP,
-};
-
-static struct s3c2410_ts_mach_info h1940_ts_cfg __initdata = {
-               .delay = 10000,
-               .presc = 49,
-               .oversampling_shift = 2,
-               .cfg_gpio = s3c24xx_ts_cfg_gpio,
-};
-
-/**
- * Set lcd on or off
- **/
-static struct s3c2410fb_display h1940_lcd __initdata = {
-       .lcdcon5=       S3C2410_LCDCON5_FRM565 | \
-                       S3C2410_LCDCON5_INVVLINE | \
-                       S3C2410_LCDCON5_HWSWP,
-
-       .type =         S3C2410_LCDCON1_TFT,
-       .width =        240,
-       .height =       320,
-       .pixclock =     260000,
-       .xres =         240,
-       .yres =         320,
-       .bpp =          16,
-       .left_margin =  8,
-       .right_margin = 20,
-       .hsync_len =    4,
-       .upper_margin = 8,
-       .lower_margin = 7,
-       .vsync_len =    1,
-};
-
-static struct s3c2410fb_mach_info h1940_fb_info __initdata = {
-       .displays = &h1940_lcd,
-       .num_displays = 1,
-       .default_display = 0,
-
-       .lpcsel =       0x02,
-       .gpccon =       0xaa940659,
-       .gpccon_mask =  0xffffc0f0,
-       .gpcup =        0x0000ffff,
-       .gpcup_mask =   0xffffffff,
-       .gpdcon =       0xaa84aaa0,
-       .gpdcon_mask =  0xffffffff,
-       .gpdup =        0x0000faff,
-       .gpdup_mask =   0xffffffff,
-};
-
-static int power_supply_init(struct device *dev)
-{
-       return gpio_request(S3C2410_GPF(2), "cable plugged");
-}
-
-static int h1940_is_ac_online(void)
-{
-       return !gpio_get_value(S3C2410_GPF(2));
-}
-
-static void power_supply_exit(struct device *dev)
-{
-       gpio_free(S3C2410_GPF(2));
-}
-
-static char *h1940_supplicants[] = {
-       "main-battery",
-       "backup-battery",
-};
-
-static struct pda_power_pdata power_supply_info = {
-       .init                   = power_supply_init,
-       .is_ac_online           = h1940_is_ac_online,
-       .exit                   = power_supply_exit,
-       .supplied_to            = h1940_supplicants,
-       .num_supplicants        = ARRAY_SIZE(h1940_supplicants),
-};
-
-static struct resource power_supply_resources[] = {
-       [0] = {
-                       .name   = "ac",
-                       .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE |
-                                         IORESOURCE_IRQ_HIGHEDGE,
-                       .start  = IRQ_EINT2,
-                       .end    = IRQ_EINT2,
-       },
-};
-
-static struct platform_device power_supply = {
-       .name           = "pda-power",
-       .id             = -1,
-       .dev            = {
-                               .platform_data =
-                                       &power_supply_info,
-       },
-       .resource       = power_supply_resources,
-       .num_resources  = ARRAY_SIZE(power_supply_resources),
-};
-
-static const struct s3c_adc_bat_thresh bat_lut_noac[] = {
-       { .volt = 4070, .cur = 162, .level = 100},
-       { .volt = 4040, .cur = 165, .level = 95},
-       { .volt = 4016, .cur = 164, .level = 90},
-       { .volt = 3996, .cur = 166, .level = 85},
-       { .volt = 3971, .cur = 168, .level = 80},
-       { .volt = 3951, .cur = 168, .level = 75},
-       { .volt = 3931, .cur = 170, .level = 70},
-       { .volt = 3903, .cur = 172, .level = 65},
-       { .volt = 3886, .cur = 172, .level = 60},
-       { .volt = 3858, .cur = 176, .level = 55},
-       { .volt = 3842, .cur = 176, .level = 50},
-       { .volt = 3818, .cur = 176, .level = 45},
-       { .volt = 3789, .cur = 180, .level = 40},
-       { .volt = 3769, .cur = 180, .level = 35},
-       { .volt = 3749, .cur = 184, .level = 30},
-       { .volt = 3732, .cur = 184, .level = 25},
-       { .volt = 3716, .cur = 184, .level = 20},
-       { .volt = 3708, .cur = 184, .level = 15},
-       { .volt = 3716, .cur = 96, .level = 10},
-       { .volt = 3700, .cur = 96, .level = 5},
-       { .volt = 3684, .cur = 96, .level = 0},
-};
-
-static const struct s3c_adc_bat_thresh bat_lut_acin[] = {
-       { .volt = 4130, .cur = 0, .level = 100},
-       { .volt = 3982, .cur = 0, .level = 50},
-       { .volt = 3854, .cur = 0, .level = 10},
-       { .volt = 3841, .cur = 0, .level = 0},
-};
-
-int h1940_bat_init(void)
-{
-       int ret;
-
-       ret = gpio_request(H1940_LATCH_SM803_ENABLE, "h1940-charger-enable");
-       if (ret)
-               return ret;
-       gpio_direction_output(H1940_LATCH_SM803_ENABLE, 0);
-
-       return 0;
-
-}
-
-void h1940_bat_exit(void)
-{
-       gpio_free(H1940_LATCH_SM803_ENABLE);
-}
-
-void h1940_enable_charger(void)
-{
-       gpio_set_value(H1940_LATCH_SM803_ENABLE, 1);
-}
-
-void h1940_disable_charger(void)
-{
-       gpio_set_value(H1940_LATCH_SM803_ENABLE, 0);
-}
-
-static struct s3c_adc_bat_pdata h1940_bat_cfg = {
-       .init = h1940_bat_init,
-       .exit = h1940_bat_exit,
-       .enable_charger = h1940_enable_charger,
-       .disable_charger = h1940_disable_charger,
-       .gpio_charge_finished = S3C2410_GPF(3),
-       .gpio_inverted = 1,
-       .lut_noac = bat_lut_noac,
-       .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac),
-       .lut_acin = bat_lut_acin,
-       .lut_acin_cnt = ARRAY_SIZE(bat_lut_acin),
-       .volt_channel = 0,
-       .current_channel = 1,
-       .volt_mult = 4056,
-       .current_mult = 1893,
-       .internal_impedance = 200,
-       .backup_volt_channel = 3,
-       /* TODO Check backup volt multiplier */
-       .backup_volt_mult = 4056,
-       .backup_volt_min = 0,
-       .backup_volt_max = 4149288
-};
-
-static struct platform_device h1940_battery = {
-       .name             = "s3c-adc-battery",
-       .id               = -1,
-       .dev = {
-               .parent = &s3c_device_adc.dev,
-               .platform_data = &h1940_bat_cfg,
-       },
-};
-
-DEFINE_SPINLOCK(h1940_blink_spin);
-
-int h1940_led_blink_set(unsigned gpio, int state,
-       unsigned long *delay_on, unsigned long *delay_off)
-{
-       int blink_gpio, check_gpio1, check_gpio2;
-
-       switch (gpio) {
-       case H1940_LATCH_LED_GREEN:
-               blink_gpio = S3C2410_GPA(7);
-               check_gpio1 = S3C2410_GPA(1);
-               check_gpio2 = S3C2410_GPA(3);
-               break;
-       case H1940_LATCH_LED_RED:
-               blink_gpio = S3C2410_GPA(1);
-               check_gpio1 = S3C2410_GPA(7);
-               check_gpio2 = S3C2410_GPA(3);
-               break;
-       default:
-               blink_gpio = S3C2410_GPA(3);
-               check_gpio1 = S3C2410_GPA(1);
-               check_gpio1 = S3C2410_GPA(7);
-               break;
-       }
-
-       if (delay_on && delay_off && !*delay_on && !*delay_off)
-               *delay_on = *delay_off = 500;
-
-       spin_lock(&h1940_blink_spin);
-
-       switch (state) {
-       case GPIO_LED_NO_BLINK_LOW:
-       case GPIO_LED_NO_BLINK_HIGH:
-               if (!gpio_get_value(check_gpio1) &&
-                   !gpio_get_value(check_gpio2))
-                       gpio_set_value(H1940_LATCH_LED_FLASH, 0);
-               gpio_set_value(blink_gpio, 0);
-               if (gpio_is_valid(gpio))
-                       gpio_set_value(gpio, state);
-               break;
-       case GPIO_LED_BLINK:
-               if (gpio_is_valid(gpio))
-                       gpio_set_value(gpio, 0);
-               gpio_set_value(H1940_LATCH_LED_FLASH, 1);
-               gpio_set_value(blink_gpio, 1);
-               break;
-       }
-
-       spin_unlock(&h1940_blink_spin);
-
-       return 0;
-}
-EXPORT_SYMBOL(h1940_led_blink_set);
-
-static struct gpio_led h1940_leds_desc[] = {
-       {
-               .name                   = "Green",
-               .default_trigger        = "main-battery-full",
-               .gpio                   = H1940_LATCH_LED_GREEN,
-               .retain_state_suspended = 1,
-       },
-       {
-               .name                   = "Red",
-               .default_trigger
-                       = "main-battery-charging-blink-full-solid",
-               .gpio                   = H1940_LATCH_LED_RED,
-               .retain_state_suspended = 1,
-       },
-};
-
-static struct gpio_led_platform_data h1940_leds_pdata = {
-       .num_leds       = ARRAY_SIZE(h1940_leds_desc),
-       .leds           = h1940_leds_desc,
-       .gpio_blink_set = h1940_led_blink_set,
-};
-
-static struct platform_device h1940_device_leds = {
-       .name   = "leds-gpio",
-       .id     = -1,
-       .dev    = {
-                       .platform_data = &h1940_leds_pdata,
-       },
-};
-
-static struct platform_device h1940_device_bluetooth = {
-       .name             = "h1940-bt",
-       .id               = -1,
-};
-
-static void h1940_set_mmc_power(unsigned char power_mode, unsigned short vdd)
-{
-       switch (power_mode) {
-       case MMC_POWER_OFF:
-               gpio_set_value(H1940_LATCH_SD_POWER, 0);
-               break;
-       case MMC_POWER_UP:
-       case MMC_POWER_ON:
-               gpio_set_value(H1940_LATCH_SD_POWER, 1);
-               break;
-       default:
-               break;
-       };
-}
-
-static struct s3c24xx_mci_pdata h1940_mmc_cfg __initdata = {
-       .gpio_detect   = S3C2410_GPF(5),
-       .gpio_wprotect = S3C2410_GPH(8),
-       .set_power     = h1940_set_mmc_power,
-       .ocr_avail     = MMC_VDD_32_33,
-};
-
-static int h1940_backlight_init(struct device *dev)
-{
-       gpio_request(S3C2410_GPB(0), "Backlight");
-
-       gpio_direction_output(S3C2410_GPB(0), 0);
-       s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
-       s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
-       gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 1);
-
-       return 0;
-}
-
-static int h1940_backlight_notify(struct device *dev, int brightness)
-{
-       if (!brightness) {
-               gpio_direction_output(S3C2410_GPB(0), 1);
-               gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
-       } else {
-               gpio_direction_output(S3C2410_GPB(0), 0);
-               s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
-               s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
-               gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 1);
-       }
-       return brightness;
-}
-
-static void h1940_backlight_exit(struct device *dev)
-{
-       gpio_direction_output(S3C2410_GPB(0), 1);
-       gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
-}
-
-
-static struct platform_pwm_backlight_data backlight_data = {
-       .pwm_id         = 0,
-       .max_brightness = 100,
-       .dft_brightness = 50,
-       /* tcnt = 0x31 */
-       .pwm_period_ns  = 36296,
-       .init           = h1940_backlight_init,
-       .notify         = h1940_backlight_notify,
-       .exit           = h1940_backlight_exit,
-};
-
-static struct platform_device h1940_backlight = {
-       .name = "pwm-backlight",
-       .dev  = {
-               .parent = &s3c_device_timer[0].dev,
-               .platform_data = &backlight_data,
-       },
-       .id   = -1,
-};
-
-static void h1940_lcd_power_set(struct plat_lcd_data *pd,
-                                       unsigned int power)
-{
-       int value, retries = 100;
-
-       if (!power) {
-               gpio_set_value(S3C2410_GPC(0), 0);
-               /* wait for 3ac */
-               do {
-                       value = gpio_get_value(S3C2410_GPC(6));
-               } while (value && retries--);
-
-               gpio_set_value(H1940_LATCH_LCD_P2, 0);
-               gpio_set_value(H1940_LATCH_LCD_P3, 0);
-               gpio_set_value(H1940_LATCH_LCD_P4, 0);
-
-               gpio_direction_output(S3C2410_GPC(1), 0);
-               gpio_direction_output(S3C2410_GPC(4), 0);
-
-               gpio_set_value(H1940_LATCH_LCD_P1, 0);
-               gpio_set_value(H1940_LATCH_LCD_P0, 0);
-
-               gpio_set_value(S3C2410_GPC(5), 0);
-
-       } else {
-               gpio_set_value(H1940_LATCH_LCD_P0, 1);
-               gpio_set_value(H1940_LATCH_LCD_P1, 1);
-
-               gpio_direction_input(S3C2410_GPC(1));
-               gpio_direction_input(S3C2410_GPC(4));
-               mdelay(10);
-               s3c_gpio_cfgpin(S3C2410_GPC(1), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S3C2410_GPC(4), S3C_GPIO_SFN(2));
-
-               gpio_set_value(S3C2410_GPC(5), 1);
-               gpio_set_value(S3C2410_GPC(0), 1);
-
-               gpio_set_value(H1940_LATCH_LCD_P3, 1);
-               gpio_set_value(H1940_LATCH_LCD_P2, 1);
-               gpio_set_value(H1940_LATCH_LCD_P4, 1);
-       }
-}
-
-static struct plat_lcd_data h1940_lcd_power_data = {
-       .set_power      = h1940_lcd_power_set,
-};
-
-static struct platform_device h1940_lcd_powerdev = {
-       .name                   = "platform-lcd",
-       .dev.parent             = &s3c_device_lcd.dev,
-       .dev.platform_data      = &h1940_lcd_power_data,
-};
-
-static struct uda1380_platform_data uda1380_info = {
-       .gpio_power     = H1940_LATCH_UDA_POWER,
-       .gpio_reset     = S3C2410_GPA(12),
-       .dac_clk        = UDA1380_DAC_CLK_SYSCLK,
-};
-
-static struct i2c_board_info h1940_i2c_devices[] = {
-       {
-               I2C_BOARD_INFO("uda1380", 0x1a),
-               .platform_data = &uda1380_info,
-       },
-};
-
-#define DECLARE_BUTTON(p, k, n, w)     \
-       {                               \
-               .gpio           = p,    \
-               .code           = k,    \
-               .desc           = n,    \
-               .wakeup         = w,    \
-               .active_low     = 1,    \
-       }
-
-static struct gpio_keys_button h1940_buttons[] = {
-       DECLARE_BUTTON(S3C2410_GPF(0),       KEY_POWER,          "Power", 1),
-       DECLARE_BUTTON(S3C2410_GPF(6),       KEY_ENTER,         "Select", 1),
-       DECLARE_BUTTON(S3C2410_GPF(7),      KEY_RECORD,         "Record", 0),
-       DECLARE_BUTTON(S3C2410_GPG(0),         KEY_F11,       "Calendar", 0),
-       DECLARE_BUTTON(S3C2410_GPG(2),         KEY_F12,       "Contacts", 0),
-       DECLARE_BUTTON(S3C2410_GPG(3),        KEY_MAIL,           "Mail", 0),
-       DECLARE_BUTTON(S3C2410_GPG(6),        KEY_LEFT,     "Left_arrow", 0),
-       DECLARE_BUTTON(S3C2410_GPG(7),    KEY_HOMEPAGE,           "Home", 0),
-       DECLARE_BUTTON(S3C2410_GPG(8),       KEY_RIGHT,    "Right_arrow", 0),
-       DECLARE_BUTTON(S3C2410_GPG(9),          KEY_UP,       "Up_arrow", 0),
-       DECLARE_BUTTON(S3C2410_GPG(10),       KEY_DOWN,     "Down_arrow", 0),
-};
-
-static struct gpio_keys_platform_data h1940_buttons_data = {
-       .buttons        = h1940_buttons,
-       .nbuttons       = ARRAY_SIZE(h1940_buttons),
-};
-
-static struct platform_device h1940_dev_buttons = {
-       .name           = "gpio-keys",
-       .id             = -1,
-       .dev            = {
-               .platform_data  = &h1940_buttons_data,
-       }
-};
-
-static struct platform_device *h1940_devices[] __initdata = {
-       &h1940_dev_buttons,
-       &s3c_device_ohci,
-       &s3c_device_lcd,
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_iis,
-       &samsung_asoc_dma,
-       &s3c_device_usbgadget,
-       &h1940_device_leds,
-       &h1940_device_bluetooth,
-       &s3c_device_sdi,
-       &s3c_device_rtc,
-       &s3c_device_timer[0],
-       &h1940_backlight,
-       &h1940_lcd_powerdev,
-       &s3c_device_adc,
-       &s3c_device_ts,
-       &power_supply,
-       &h1940_battery,
-};
-
-static void __init h1940_map_io(void)
-{
-       s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
-       s3c24xx_init_clocks(0);
-       s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
-
-       /* setup PM */
-
-#ifdef CONFIG_PM_H1940
-       memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
-#endif
-       s3c_pm_init();
-
-       /* Add latch gpio chip, set latch initial value */
-       h1940_latch_control(0, 0);
-       WARN_ON(gpiochip_add(&h1940_latch_gpiochip));
-}
-
-/* H1940 and RX3715 need to reserve this for suspend */
-static void __init h1940_reserve(void)
-{
-       memblock_reserve(0x30003000, 0x1000);
-       memblock_reserve(0x30081000, 0x1000);
-}
-
-static void __init h1940_init_irq(void)
-{
-       s3c24xx_init_irq();
-}
-
-static void __init h1940_init(void)
-{
-       u32 tmp;
-
-       s3c24xx_fb_set_platdata(&h1940_fb_info);
-       s3c24xx_mci_set_platdata(&h1940_mmc_cfg);
-       s3c24xx_udc_set_platdata(&h1940_udc_cfg);
-       s3c24xx_ts_set_platdata(&h1940_ts_cfg);
-       s3c_i2c0_set_platdata(NULL);
-
-       /* Turn off suspend on both USB ports, and switch the
-        * selectable USB port to USB device mode. */
-
-       s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
-                             S3C2410_MISCCR_USBSUSPND0 |
-                             S3C2410_MISCCR_USBSUSPND1, 0x0);
-
-       tmp =   (0x78 << S3C24XX_PLL_MDIV_SHIFT)
-             | (0x02 << S3C24XX_PLL_PDIV_SHIFT)
-             | (0x03 << S3C24XX_PLL_SDIV_SHIFT);
-       writel(tmp, S3C2410_UPLLCON);
-
-       gpio_request(S3C2410_GPC(0), "LCD power");
-       gpio_request(S3C2410_GPC(1), "LCD power");
-       gpio_request(S3C2410_GPC(4), "LCD power");
-       gpio_request(S3C2410_GPC(5), "LCD power");
-       gpio_request(S3C2410_GPC(6), "LCD power");
-       gpio_request(H1940_LATCH_LCD_P0, "LCD power");
-       gpio_request(H1940_LATCH_LCD_P1, "LCD power");
-       gpio_request(H1940_LATCH_LCD_P2, "LCD power");
-       gpio_request(H1940_LATCH_LCD_P3, "LCD power");
-       gpio_request(H1940_LATCH_LCD_P4, "LCD power");
-       gpio_request(H1940_LATCH_MAX1698_nSHUTDOWN, "LCD power");
-       gpio_direction_output(S3C2410_GPC(0), 0);
-       gpio_direction_output(S3C2410_GPC(1), 0);
-       gpio_direction_output(S3C2410_GPC(4), 0);
-       gpio_direction_output(S3C2410_GPC(5), 0);
-       gpio_direction_input(S3C2410_GPC(6));
-       gpio_direction_output(H1940_LATCH_LCD_P0, 0);
-       gpio_direction_output(H1940_LATCH_LCD_P1, 0);
-       gpio_direction_output(H1940_LATCH_LCD_P2, 0);
-       gpio_direction_output(H1940_LATCH_LCD_P3, 0);
-       gpio_direction_output(H1940_LATCH_LCD_P4, 0);
-       gpio_direction_output(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
-
-       gpio_request(H1940_LATCH_SD_POWER, "SD power");
-       gpio_direction_output(H1940_LATCH_SD_POWER, 0);
-
-       platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
-
-       gpio_request(S3C2410_GPA(1), "Red LED blink");
-       gpio_request(S3C2410_GPA(3), "Blue LED blink");
-       gpio_request(S3C2410_GPA(7), "Green LED blink");
-       gpio_request(H1940_LATCH_LED_FLASH, "LED blink");
-       gpio_direction_output(S3C2410_GPA(1), 0);
-       gpio_direction_output(S3C2410_GPA(3), 0);
-       gpio_direction_output(S3C2410_GPA(7), 0);
-       gpio_direction_output(H1940_LATCH_LED_FLASH, 0);
-
-       i2c_register_board_info(0, h1940_i2c_devices,
-               ARRAY_SIZE(h1940_i2c_devices));
-}
-
-MACHINE_START(H1940, "IPAQ-H1940")
-       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
-       .atag_offset    = 0x100,
-       .map_io         = h1940_map_io,
-       .reserve        = h1940_reserve,
-       .init_irq       = h1940_init_irq,
-       .init_machine   = h1940_init,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c2410_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
deleted file mode 100644 (file)
index 383d00c..0000000
+++ /dev/null
@@ -1,608 +0,0 @@
-/* Machine specific code for the Acer n30, Acer N35, Navman PiN 570,
- * Yakumo AlphaX and Airis NC05 PDAs.
- *
- * Copyright (c) 2003-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Copyright (c) 2005-2008 Christer Weinigel <christer@weinigel.se>
- *
- * There is a wiki with more information about the n30 port at
- * http://handhelds.org/moin/moin.cgi/AcerN30Documentation .
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-
-#include <linux/gpio_keys.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/input.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/timer.h>
-#include <linux/io.h>
-#include <linux/mmc/host.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <mach/fb.h>
-#include <mach/leds-gpio.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-lcd.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/map.h>
-
-#include <plat/iic.h>
-#include <plat/regs-serial.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/mci.h>
-#include <plat/s3c2410.h>
-#include <plat/udc.h>
-
-#include "common.h"
-
-static struct map_desc n30_iodesc[] __initdata = {
-       /* nothing here yet */
-};
-
-static struct s3c2410_uartcfg n30_uartcfgs[] = {
-       /* Normal serial port */
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = 0x2c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       },
-       /* IR port */
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .uart_flags  = UPF_CONS_FLOW,
-               .ucon        = 0x2c5,
-               .ulcon       = 0x43,
-               .ufcon       = 0x51,
-       },
-       /* On the N30 the bluetooth controller is connected here.
-        * On the N35 and variants the GPS receiver is connected here. */
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = 0x2c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       },
-};
-
-static struct s3c2410_udc_mach_info n30_udc_cfg __initdata = {
-       .vbus_pin               = S3C2410_GPG(1),
-       .vbus_pin_inverted      = 0,
-       .pullup_pin             = S3C2410_GPB(3),
-};
-
-static struct gpio_keys_button n30_buttons[] = {
-       {
-               .gpio           = S3C2410_GPF(0),
-               .code           = KEY_POWER,
-               .desc           = "Power",
-               .active_low     = 0,
-       },
-       {
-               .gpio           = S3C2410_GPG(9),
-               .code           = KEY_UP,
-               .desc           = "Thumbwheel Up",
-               .active_low     = 0,
-       },
-       {
-               .gpio           = S3C2410_GPG(8),
-               .code           = KEY_DOWN,
-               .desc           = "Thumbwheel Down",
-               .active_low     = 0,
-       },
-       {
-               .gpio           = S3C2410_GPG(7),
-               .code           = KEY_ENTER,
-               .desc           = "Thumbwheel Press",
-               .active_low     = 0,
-       },
-       {
-               .gpio           = S3C2410_GPF(7),
-               .code           = KEY_HOMEPAGE,
-               .desc           = "Home",
-               .active_low     = 0,
-       },
-       {
-               .gpio           = S3C2410_GPF(6),
-               .code           = KEY_CALENDAR,
-               .desc           = "Calendar",
-               .active_low     = 0,
-       },
-       {
-               .gpio           = S3C2410_GPF(5),
-               .code           = KEY_ADDRESSBOOK,
-               .desc           = "Contacts",
-               .active_low     = 0,
-       },
-       {
-               .gpio           = S3C2410_GPF(4),
-               .code           = KEY_MAIL,
-               .desc           = "Mail",
-               .active_low     = 0,
-       },
-};
-
-static struct gpio_keys_platform_data n30_button_data = {
-       .buttons        = n30_buttons,
-       .nbuttons       = ARRAY_SIZE(n30_buttons),
-};
-
-static struct platform_device n30_button_device = {
-       .name           = "gpio-keys",
-       .id             = -1,
-       .dev            = {
-               .platform_data  = &n30_button_data,
-       }
-};
-
-static struct gpio_keys_button n35_buttons[] = {
-       {
-               .gpio           = S3C2410_GPF(0),
-               .code           = KEY_POWER,
-               .type           = EV_PWR,
-               .desc           = "Power",
-               .active_low     = 0,
-               .wakeup         = 1,
-       },
-       {
-               .gpio           = S3C2410_GPG(9),
-               .code           = KEY_UP,
-               .desc           = "Joystick Up",
-               .active_low     = 0,
-       },
-       {
-               .gpio           = S3C2410_GPG(8),
-               .code           = KEY_DOWN,
-               .desc           = "Joystick Down",
-               .active_low     = 0,
-       },
-       {
-               .gpio           = S3C2410_GPG(6),
-               .code           = KEY_DOWN,
-               .desc           = "Joystick Left",
-               .active_low     = 0,
-       },
-       {
-               .gpio           = S3C2410_GPG(5),
-               .code           = KEY_DOWN,
-               .desc           = "Joystick Right",
-               .active_low     = 0,
-       },
-       {
-               .gpio           = S3C2410_GPG(7),
-               .code           = KEY_ENTER,
-               .desc           = "Joystick Press",
-               .active_low     = 0,
-       },
-       {
-               .gpio           = S3C2410_GPF(7),
-               .code           = KEY_HOMEPAGE,
-               .desc           = "Home",
-               .active_low     = 0,
-       },
-       {
-               .gpio           = S3C2410_GPF(6),
-               .code           = KEY_CALENDAR,
-               .desc           = "Calendar",
-               .active_low     = 0,
-       },
-       {
-               .gpio           = S3C2410_GPF(5),
-               .code           = KEY_ADDRESSBOOK,
-               .desc           = "Contacts",
-               .active_low     = 0,
-       },
-       {
-               .gpio           = S3C2410_GPF(4),
-               .code           = KEY_MAIL,
-               .desc           = "Mail",
-               .active_low     = 0,
-       },
-       {
-               .gpio           = S3C2410_GPF(3),
-               .code           = SW_RADIO,
-               .desc           = "GPS Antenna",
-               .active_low     = 0,
-       },
-       {
-               .gpio           = S3C2410_GPG(2),
-               .code           = SW_HEADPHONE_INSERT,
-               .desc           = "Headphone",
-               .active_low     = 0,
-       },
-};
-
-static struct gpio_keys_platform_data n35_button_data = {
-       .buttons        = n35_buttons,
-       .nbuttons       = ARRAY_SIZE(n35_buttons),
-};
-
-static struct platform_device n35_button_device = {
-       .name           = "gpio-keys",
-       .id             = -1,
-       .num_resources  = 0,
-       .dev            = {
-               .platform_data  = &n35_button_data,
-       }
-};
-
-/* This is the bluetooth LED on the device. */
-static struct s3c24xx_led_platdata n30_blue_led_pdata = {
-       .name           = "blue_led",
-       .gpio           = S3C2410_GPG(6),
-       .def_trigger    = "",
-};
-
-/* This is the blue LED on the device. Originally used to indicate GPS activity
- * by flashing. */
-static struct s3c24xx_led_platdata n35_blue_led_pdata = {
-       .name           = "blue_led",
-       .gpio           = S3C2410_GPD(8),
-       .def_trigger    = "",
-};
-
-/* This LED is driven by the battery microcontroller, and is blinking
- * red, blinking green or solid green when the battery is low,
- * charging or full respectively.  By driving GPD9 low, it's possible
- * to force the LED to blink red, so call that warning LED.  */
-static struct s3c24xx_led_platdata n30_warning_led_pdata = {
-       .name           = "warning_led",
-       .flags          = S3C24XX_LEDF_ACTLOW,
-       .gpio           = S3C2410_GPD(9),
-       .def_trigger    = "",
-};
-
-static struct s3c24xx_led_platdata n35_warning_led_pdata = {
-       .name           = "warning_led",
-       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
-       .gpio           = S3C2410_GPD(9),
-       .def_trigger    = "",
-};
-
-static struct platform_device n30_blue_led = {
-       .name           = "s3c24xx_led",
-       .id             = 1,
-       .dev            = {
-               .platform_data  = &n30_blue_led_pdata,
-       },
-};
-
-static struct platform_device n35_blue_led = {
-       .name           = "s3c24xx_led",
-       .id             = 1,
-       .dev            = {
-               .platform_data  = &n35_blue_led_pdata,
-       },
-};
-
-static struct platform_device n30_warning_led = {
-       .name           = "s3c24xx_led",
-       .id             = 2,
-       .dev            = {
-               .platform_data  = &n30_warning_led_pdata,
-       },
-};
-
-static struct platform_device n35_warning_led = {
-       .name           = "s3c24xx_led",
-       .id             = 2,
-       .dev            = {
-               .platform_data  = &n35_warning_led_pdata,
-       },
-};
-
-static struct s3c2410fb_display n30_display __initdata = {
-       .type           = S3C2410_LCDCON1_TFT,
-       .width          = 240,
-       .height         = 320,
-       .pixclock       = 170000,
-
-       .xres           = 240,
-       .yres           = 320,
-       .bpp            = 16,
-       .left_margin    = 3,
-       .right_margin   = 40,
-       .hsync_len      = 40,
-       .upper_margin   = 2,
-       .lower_margin   = 3,
-       .vsync_len      = 2,
-
-       .lcdcon5 = S3C2410_LCDCON5_INVVLINE | S3C2410_LCDCON5_INVVFRAME,
-};
-
-static struct s3c2410fb_mach_info n30_fb_info __initdata = {
-       .displays       = &n30_display,
-       .num_displays   = 1,
-       .default_display = 0,
-       .lpcsel         = 0x06,
-};
-
-static void n30_sdi_set_power(unsigned char power_mode, unsigned short vdd)
-{
-       switch (power_mode) {
-       case MMC_POWER_ON:
-       case MMC_POWER_UP:
-               gpio_set_value(S3C2410_GPG(4), 1);
-               break;
-       case MMC_POWER_OFF:
-       default:
-               gpio_set_value(S3C2410_GPG(4), 0);
-               break;
-       }
-}
-
-static struct s3c24xx_mci_pdata n30_mci_cfg __initdata = {
-       .gpio_detect    = S3C2410_GPF(1),
-       .gpio_wprotect  = S3C2410_GPG(10),
-       .ocr_avail      = MMC_VDD_32_33,
-       .set_power      = n30_sdi_set_power,
-};
-
-static struct platform_device *n30_devices[] __initdata = {
-       &s3c_device_lcd,
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_iis,
-       &s3c_device_ohci,
-       &s3c_device_rtc,
-       &s3c_device_usbgadget,
-       &s3c_device_sdi,
-       &n30_button_device,
-       &n30_blue_led,
-       &n30_warning_led,
-};
-
-static struct platform_device *n35_devices[] __initdata = {
-       &s3c_device_lcd,
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_iis,
-       &s3c_device_rtc,
-       &s3c_device_usbgadget,
-       &s3c_device_sdi,
-       &n35_button_device,
-       &n35_blue_led,
-       &n35_warning_led,
-};
-
-static struct s3c2410_platform_i2c __initdata n30_i2ccfg = {
-       .flags          = 0,
-       .slave_addr     = 0x10,
-       .frequency      = 10*1000,
-};
-
-/* Lots of hardcoded stuff, but it sets up the hardware in a useful
- * state so that we can boot Linux directly from flash. */
-static void __init n30_hwinit(void)
-{
-       /* GPA0-11 special functions -- unknown what they do
-        * GPA12 N30 special function -- unknown what it does
-        *       N35/PiN output -- unknown what it does
-        *
-        * A12 is nGCS1 on the N30 and an output on the N35/PiN.  I
-        * don't think it does anything useful on the N30, so I ought
-        * to make it an output there too since it always driven to 0
-        * as far as I can tell. */
-       if (machine_is_n30())
-               __raw_writel(0x007fffff, S3C2410_GPACON);
-       if (machine_is_n35())
-               __raw_writel(0x007fefff, S3C2410_GPACON);
-       __raw_writel(0x00000000, S3C2410_GPADAT);
-
-       /* GPB0 TOUT0 backlight level
-        * GPB1 output 1=backlight on
-        * GPB2 output IrDA enable 0=transceiver enabled, 1=disabled
-        * GPB3 output USB D+ pull up 0=disabled, 1=enabled
-        * GPB4 N30 output -- unknown function
-        *      N30/PiN GPS control 0=GPS enabled, 1=GPS disabled
-        * GPB5 output -- unknown function
-        * GPB6 input -- unknown function
-        * GPB7 output -- unknown function
-        * GPB8 output -- probably LCD driver enable
-        * GPB9 output -- probably LCD VSYNC driver enable
-        * GPB10 output -- probably LCD HSYNC driver enable
-        */
-       __raw_writel(0x00154556, S3C2410_GPBCON);
-       __raw_writel(0x00000750, S3C2410_GPBDAT);
-       __raw_writel(0x00000073, S3C2410_GPBUP);
-
-       /* GPC0 input RS232 DCD/DSR/RI
-        * GPC1 LCD
-        * GPC2 output RS232 DTR?
-        * GPC3 input RS232 DCD/DSR/RI
-        * GPC4 LCD
-        * GPC5 output 0=NAND write enabled, 1=NAND write protect
-        * GPC6 input -- unknown function
-        * GPC7 input charger status 0=charger connected
-        *      this input can be triggered by power on the USB device
-        *      port too, but will go back to disconnected soon after.
-        * GPC8 N30/N35 output -- unknown function, always driven to 1
-        *      PiN input -- unknown function, always read as 1
-        *      Make it an input with a pull up for all models.
-        * GPC9-15 LCD
-        */
-       __raw_writel(0xaaa80618, S3C2410_GPCCON);
-       __raw_writel(0x0000014c, S3C2410_GPCDAT);
-       __raw_writel(0x0000fef2, S3C2410_GPCUP);
-
-       /* GPD0 input -- unknown function
-        * GPD1-D7 LCD
-        * GPD8 N30 output -- unknown function
-        *      N35/PiN output 1=GPS LED on
-        * GPD9 output 0=power led blinks red, 1=normal power led function
-        * GPD10 output -- unknown function
-        * GPD11-15 LCD drivers
-        */
-       __raw_writel(0xaa95aaa4, S3C2410_GPDCON);
-       __raw_writel(0x00000601, S3C2410_GPDDAT);
-       __raw_writel(0x0000fbfe, S3C2410_GPDUP);
-
-       /* GPE0-4 I2S audio bus
-        * GPE5-10 SD/MMC bus
-        * E11-13 outputs -- unknown function, probably power management
-        * E14-15 I2C bus connected to the battery controller
-        */
-       __raw_writel(0xa56aaaaa, S3C2410_GPECON);
-       __raw_writel(0x0000efc5, S3C2410_GPEDAT);
-       __raw_writel(0x0000f81f, S3C2410_GPEUP);
-
-       /* GPF0  input 0=power button pressed
-        * GPF1  input SD/MMC switch 0=card present
-        * GPF2  N30 1=reset button pressed (inverted compared to the rest)
-        *       N35/PiN 0=reset button pressed
-        * GPF3  N30/PiN input -- unknown function
-        *       N35 input GPS antenna position, 0=antenna closed, 1=open
-        * GPF4  input 0=button 4 pressed
-        * GPF5  input 0=button 3 pressed
-        * GPF6  input 0=button 2 pressed
-        * GPF7  input 0=button 1 pressed
-        */
-       __raw_writel(0x0000aaaa, S3C2410_GPFCON);
-       __raw_writel(0x00000000, S3C2410_GPFDAT);
-       __raw_writel(0x000000ff, S3C2410_GPFUP);
-
-       /* GPG0  input RS232 DCD/DSR/RI
-        * GPG1  input 1=USB gadget port has power from a host
-        * GPG2  N30 input -- unknown function
-        *       N35/PiN input 0=headphones plugged in, 1=not plugged in
-        * GPG3  N30 output -- unknown function
-        *       N35/PiN input with unknown function
-        * GPG4  N30 output 0=MMC enabled, 1=MMC disabled
-        * GPG5  N30 output 0=BlueTooth chip disabled, 1=enabled
-        *       N35/PiN input joystick right
-        * GPG6  N30 output 0=blue led on, 1=off
-        *       N35/PiN input joystick left
-        * GPG7  input 0=thumbwheel pressed
-        * GPG8  input 0=thumbwheel down
-        * GPG9  input 0=thumbwheel up
-        * GPG10 input SD/MMC write protect switch
-        * GPG11 N30 input -- unknown function
-        *       N35 output 0=GPS antenna powered, 1=not powered
-        *       PiN output -- unknown function
-        * GPG12-15 touch screen functions
-        *
-        * The pullups differ between the models, so enable all
-        * pullups that are enabled on any of the models.
-        */
-       if (machine_is_n30())
-               __raw_writel(0xff0a956a, S3C2410_GPGCON);
-       if (machine_is_n35())
-               __raw_writel(0xff4aa92a, S3C2410_GPGCON);
-       __raw_writel(0x0000e800, S3C2410_GPGDAT);
-       __raw_writel(0x0000f86f, S3C2410_GPGUP);
-
-       /* GPH0/1/2/3 RS232 serial port
-        * GPH4/5 IrDA serial port
-        * GPH6/7  N30 BlueTooth serial port
-        *         N35/PiN GPS receiver
-        * GPH8 input -- unknown function
-        * GPH9 CLKOUT0 HCLK -- unknown use
-        * GPH10 CLKOUT1 FCLK -- unknown use
-        *
-        * The pull ups for H6/H7 are enabled on N30 but not on the
-        * N35/PiN.  I suppose is useful for a budget model of the N30
-        * with no bluetooh.  It doesn't hurt to have the pull ups
-        * enabled on the N35, so leave them enabled for all models.
-        */
-       __raw_writel(0x0028aaaa, S3C2410_GPHCON);
-       __raw_writel(0x000005ef, S3C2410_GPHDAT);
-       __raw_writel(0x0000063f, S3C2410_GPHUP);
-}
-
-static void __init n30_map_io(void)
-{
-       s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
-       n30_hwinit();
-       s3c24xx_init_clocks(0);
-       s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
-}
-
-/* GPB3 is the line that controls the pull-up for the USB D+ line */
-
-static void __init n30_init(void)
-{
-       WARN_ON(gpio_request(S3C2410_GPG(4), "mmc power"));
-
-       s3c24xx_fb_set_platdata(&n30_fb_info);
-       s3c24xx_udc_set_platdata(&n30_udc_cfg);
-       s3c24xx_mci_set_platdata(&n30_mci_cfg);
-       s3c_i2c0_set_platdata(&n30_i2ccfg);
-
-       /* Turn off suspend on both USB ports, and switch the
-        * selectable USB port to USB device mode. */
-
-       s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
-                             S3C2410_MISCCR_USBSUSPND0 |
-                             S3C2410_MISCCR_USBSUSPND1, 0x0);
-
-       if (machine_is_n30()) {
-               /* Turn off suspend on both USB ports, and switch the
-                * selectable USB port to USB device mode. */
-               s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
-                                     S3C2410_MISCCR_USBSUSPND0 |
-                                     S3C2410_MISCCR_USBSUSPND1, 0x0);
-
-               platform_add_devices(n30_devices, ARRAY_SIZE(n30_devices));
-       }
-
-       if (machine_is_n35()) {
-               /* Turn off suspend and switch the selectable USB port
-                * to USB device mode.  Turn on suspend for the host
-                * port since it is not connected on the N35.
-                *
-                * Actually, the host port is available at some pads
-                * on the back of the device, so it would actually be
-                * possible to add a USB device inside the N35 if you
-                * are willing to do some hardware modifications. */
-               s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
-                                     S3C2410_MISCCR_USBSUSPND0 |
-                                     S3C2410_MISCCR_USBSUSPND1,
-                                     S3C2410_MISCCR_USBSUSPND0);
-
-               platform_add_devices(n35_devices, ARRAY_SIZE(n35_devices));
-       }
-}
-
-MACHINE_START(N30, "Acer-N30")
-       /* Maintainer: Christer Weinigel <christer@weinigel.se>,
-                               Ben Dooks <ben-linux@fluff.org>
-       */
-       .atag_offset    = 0x100,
-       .timer          = &s3c24xx_timer,
-       .init_machine   = n30_init,
-       .init_irq       = s3c24xx_init_irq,
-       .map_io         = n30_map_io,
-       .restart        = s3c2410_restart,
-MACHINE_END
-
-MACHINE_START(N35, "Acer-N35")
-       /* Maintainer: Christer Weinigel <christer@weinigel.se>
-       */
-       .atag_offset    = 0x100,
-       .timer          = &s3c24xx_timer,
-       .init_machine   = n30_init,
-       .init_irq       = s3c24xx_init_irq,
-       .map_io         = n30_map_io,
-       .restart        = s3c2410_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c
deleted file mode 100644 (file)
index 5f1e0ee..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/mach-otom.c
- *
- * Copyright (c) 2004 Nex Vision
- *   Guillaume GOURAT <guillaume.gourat@nexvision.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/otom-map.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/s3c2410.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/iic.h>
-#include <plat/cpu.h>
-
-#include "common.h"
-
-static struct map_desc otom11_iodesc[] __initdata = {
-  /* Device area */
-       { (u32)OTOM_VA_CS8900A_BASE, OTOM_PA_CS8900A_BASE, SZ_16M, MT_DEVICE },
-};
-
-#define UCON S3C2410_UCON_DEFAULT
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg otom11_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       /* port 2 is not actually used */
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       }
-};
-
-/* NOR Flash on NexVision OTOM board */
-
-static struct resource otom_nor_resource[] = {
-       [0] = {
-               .start = S3C2410_CS0,
-               .end   = S3C2410_CS0 + (4*1024*1024) - 1,
-               .flags = IORESOURCE_MEM,
-       }
-};
-
-static struct platform_device otom_device_nor = {
-       .name           = "mtd-flash",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(otom_nor_resource),
-       .resource       = otom_nor_resource,
-};
-
-/* Standard OTOM devices */
-
-static struct platform_device *otom11_devices[] __initdata = {
-       &s3c_device_ohci,
-       &s3c_device_lcd,
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_iis,
-       &s3c_device_rtc,
-       &otom_device_nor,
-};
-
-static void __init otom11_map_io(void)
-{
-       s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc));
-       s3c24xx_init_clocks(0);
-       s3c24xx_init_uarts(otom11_uartcfgs, ARRAY_SIZE(otom11_uartcfgs));
-}
-
-static void __init otom11_init(void)
-{
-       s3c_i2c0_set_platdata(NULL);
-       platform_add_devices(otom11_devices, ARRAY_SIZE(otom11_devices));
-}
-
-MACHINE_START(OTOM, "Nex Vision - Otom 1.1")
-       /* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
-       .atag_offset    = 0x100,
-       .map_io         = otom11_map_io,
-       .init_machine   = otom11_init,
-       .init_irq       = s3c24xx_init_irq,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c2410_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
deleted file mode 100644 (file)
index 91c16d9..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/mach-qt2410.c
- *
- * Copyright (C) 2006 by OpenMoko, Inc.
- * Author: Harald Welte <laforge@openmoko.org>
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/spi_gpio.h>
-#include <linux/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <mach/regs-gpio.h>
-#include <mach/leds-gpio.h>
-#include <mach/regs-lcd.h>
-#include <plat/regs-serial.h>
-#include <mach/fb.h>
-#include <plat/nand.h>
-#include <plat/udc.h>
-#include <plat/iic.h>
-
-#include <plat/common-smdk.h>
-#include <plat/gpio-cfg.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/pm.h>
-
-#include "common.h"
-
-static struct map_desc qt2410_iodesc[] __initdata = {
-       { 0xe0000000, __phys_to_pfn(S3C2410_CS3+0x01000000), SZ_1M, MT_DEVICE }
-};
-
-#define UCON S3C2410_UCON_DEFAULT
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       }
-};
-
-/* LCD driver info */
-
-static struct s3c2410fb_display qt2410_lcd_cfg[] __initdata = {
-       {
-               /* Configuration for 640x480 SHARP LQ080V3DG01 */
-               .lcdcon5 = S3C2410_LCDCON5_FRM565 |
-                          S3C2410_LCDCON5_INVVLINE |
-                          S3C2410_LCDCON5_INVVFRAME |
-                          S3C2410_LCDCON5_PWREN |
-                          S3C2410_LCDCON5_HWSWP,
-
-               .type           = S3C2410_LCDCON1_TFT,
-               .width          = 640,
-               .height         = 480,
-
-               .pixclock       = 40000, /* HCLK/4 */
-               .xres           = 640,
-               .yres           = 480,
-               .bpp            = 16,
-               .left_margin    = 44,
-               .right_margin   = 116,
-               .hsync_len      = 96,
-               .upper_margin   = 19,
-               .lower_margin   = 11,
-               .vsync_len      = 15,
-       },
-       {
-               /* Configuration for 480x640 toppoly TD028TTEC1 */
-               .lcdcon5 = S3C2410_LCDCON5_FRM565 |
-                          S3C2410_LCDCON5_INVVLINE |
-                          S3C2410_LCDCON5_INVVFRAME |
-                          S3C2410_LCDCON5_PWREN |
-                          S3C2410_LCDCON5_HWSWP,
-
-               .type           = S3C2410_LCDCON1_TFT,
-               .width          = 480,
-               .height         = 640,
-               .pixclock       = 40000, /* HCLK/4 */
-               .xres           = 480,
-               .yres           = 640,
-               .bpp            = 16,
-               .left_margin    = 8,
-               .right_margin   = 24,
-               .hsync_len      = 8,
-               .upper_margin   = 2,
-               .lower_margin   = 4,
-               .vsync_len      = 2,
-       },
-       {
-               /* Config for 240x320 LCD */
-               .lcdcon5 = S3C2410_LCDCON5_FRM565 |
-                          S3C2410_LCDCON5_INVVLINE |
-                          S3C2410_LCDCON5_INVVFRAME |
-                          S3C2410_LCDCON5_PWREN |
-                          S3C2410_LCDCON5_HWSWP,
-
-               .type           = S3C2410_LCDCON1_TFT,
-               .width          = 240,
-               .height         = 320,
-               .pixclock       = 100000, /* HCLK/10 */
-               .xres           = 240,
-               .yres           = 320,
-               .bpp            = 16,
-               .left_margin    = 13,
-               .right_margin   = 8,
-               .hsync_len      = 4,
-               .upper_margin   = 2,
-               .lower_margin   = 7,
-               .vsync_len      = 4,
-       },
-};
-
-
-static struct s3c2410fb_mach_info qt2410_fb_info __initdata = {
-       .displays       = qt2410_lcd_cfg,
-       .num_displays   = ARRAY_SIZE(qt2410_lcd_cfg),
-       .default_display = 0,
-
-       .lpcsel         = ((0xCE6) & ~7) | 1<<4,
-};
-
-/* CS8900 */
-
-static struct resource qt2410_cs89x0_resources[] = {
-       [0] = {
-               .start  = 0x19000000,
-               .end    = 0x19000000 + 16,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_EINT9,
-               .end    = IRQ_EINT9,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device qt2410_cs89x0 = {
-       .name           = "cirrus-cs89x0",
-       .num_resources  = ARRAY_SIZE(qt2410_cs89x0_resources),
-       .resource       = qt2410_cs89x0_resources,
-};
-
-/* LED */
-
-static struct s3c24xx_led_platdata qt2410_pdata_led = {
-       .gpio           = S3C2410_GPB(0),
-       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
-       .name           = "led",
-       .def_trigger    = "timer",
-};
-
-static struct platform_device qt2410_led = {
-       .name           = "s3c24xx_led",
-       .id             = 0,
-       .dev            = {
-               .platform_data = &qt2410_pdata_led,
-       },
-};
-
-/* SPI */
-
-static struct spi_gpio_platform_data spi_gpio_cfg = {
-       .sck            = S3C2410_GPG(7),
-       .mosi           = S3C2410_GPG(6),
-       .miso           = S3C2410_GPG(5),
-};
-
-static struct platform_device qt2410_spi = {
-       .name           = "spi-gpio",
-       .id             = 1,
-       .dev.platform_data = &spi_gpio_cfg,
-};
-
-/* Board devices */
-
-static struct platform_device *qt2410_devices[] __initdata = {
-       &s3c_device_ohci,
-       &s3c_device_lcd,
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_iis,
-       &s3c_device_sdi,
-       &s3c_device_usbgadget,
-       &qt2410_spi,
-       &qt2410_cs89x0,
-       &qt2410_led,
-};
-
-static struct mtd_partition __initdata qt2410_nand_part[] = {
-       [0] = {
-               .name   = "U-Boot",
-               .size   = 0x30000,
-               .offset = 0,
-       },
-       [1] = {
-               .name   = "U-Boot environment",
-               .offset = 0x30000,
-               .size   = 0x4000,
-       },
-       [2] = {
-               .name   = "kernel",
-               .offset = 0x34000,
-               .size   = SZ_2M,
-       },
-       [3] = {
-               .name   = "initrd",
-               .offset = 0x234000,
-               .size   = SZ_4M,
-       },
-       [4] = {
-               .name   = "jffs2",
-               .offset = 0x634000,
-               .size   = 0x39cc000,
-       },
-};
-
-static struct s3c2410_nand_set __initdata qt2410_nand_sets[] = {
-       [0] = {
-               .name           = "NAND",
-               .nr_chips       = 1,
-               .nr_partitions  = ARRAY_SIZE(qt2410_nand_part),
-               .partitions     = qt2410_nand_part,
-       },
-};
-
-/* choose a set of timings which should suit most 512Mbit
- * chips and beyond.
- */
-
-static struct s3c2410_platform_nand __initdata qt2410_nand_info = {
-       .tacls          = 20,
-       .twrph0         = 60,
-       .twrph1         = 20,
-       .nr_sets        = ARRAY_SIZE(qt2410_nand_sets),
-       .sets           = qt2410_nand_sets,
-};
-
-/* UDC */
-
-static struct s3c2410_udc_mach_info qt2410_udc_cfg = {
-};
-
-static char tft_type = 's';
-
-static int __init qt2410_tft_setup(char *str)
-{
-       tft_type = str[0];
-       return 1;
-}
-
-__setup("tft=", qt2410_tft_setup);
-
-static void __init qt2410_map_io(void)
-{
-       s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc));
-       s3c24xx_init_clocks(12*1000*1000);
-       s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
-}
-
-static void __init qt2410_machine_init(void)
-{
-       s3c_nand_set_platdata(&qt2410_nand_info);
-
-       switch (tft_type) {
-       case 'p': /* production */
-               qt2410_fb_info.default_display = 1;
-               break;
-       case 'b': /* big */
-               qt2410_fb_info.default_display = 0;
-               break;
-       case 's': /* small */
-       default:
-               qt2410_fb_info.default_display = 2;
-               break;
-       }
-       s3c24xx_fb_set_platdata(&qt2410_fb_info);
-
-       s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
-       s3c2410_gpio_setpin(S3C2410_GPB(0), 1);
-
-       s3c24xx_udc_set_platdata(&qt2410_udc_cfg);
-       s3c_i2c0_set_platdata(NULL);
-
-       WARN_ON(gpio_request(S3C2410_GPB(5), "spi cs"));
-       gpio_direction_output(S3C2410_GPB(5), 1);
-
-       platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices));
-       s3c_pm_init();
-}
-
-MACHINE_START(QT2410, "QT2410")
-       .atag_offset    = 0x100,
-       .map_io         = qt2410_map_io,
-       .init_irq       = s3c24xx_init_irq,
-       .init_machine   = qt2410_machine_init,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c2410_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
deleted file mode 100644 (file)
index bdc27e7..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/mach-smdk2410.c
- *
- * linux/arch/arm/mach-s3c2410/mach-smdk2410.c
- *
- * Copyright (C) 2004 by FS Forth-Systeme GmbH
- * All rights reserved.
- *
- * @Author: Jonas Dietsche
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * @History:
- * derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by
- * Ben Dooks <ben@simtec.co.uk>
- *
- ***********************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <plat/iic.h>
-
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#include <plat/common-smdk.h>
-
-#include "common.h"
-
-static struct map_desc smdk2410_iodesc[] __initdata = {
-  /* nothing here yet */
-};
-
-#define UCON S3C2410_UCON_DEFAULT
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg smdk2410_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       }
-};
-
-static struct platform_device *smdk2410_devices[] __initdata = {
-       &s3c_device_ohci,
-       &s3c_device_lcd,
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_iis,
-};
-
-static void __init smdk2410_map_io(void)
-{
-       s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
-       s3c24xx_init_clocks(0);
-       s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
-}
-
-static void __init smdk2410_init(void)
-{
-       s3c_i2c0_set_platdata(NULL);
-       platform_add_devices(smdk2410_devices, ARRAY_SIZE(smdk2410_devices));
-       smdk_machine_init();
-}
-
-MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
-                                   * to SMDK2410 */
-       /* Maintainer: Jonas Dietsche */
-       .atag_offset    = 0x100,
-       .map_io         = smdk2410_map_io,
-       .init_irq       = s3c24xx_init_irq,
-       .init_machine   = smdk2410_init,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c2410_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-tct_hammer.c b/arch/arm/mach-s3c2410/mach-tct_hammer.c
deleted file mode 100644 (file)
index 1114666..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/mach-tct_hammer.c
- *
- * Copyright (c) 2007 TinCanTools
- *     David Anders <danders@amltd.com>
-
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * @History:
- * derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by
- * Ben Dooks <ben@simtec.co.uk>
- *
- ***********************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/flash.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/physmap.h>
-
-#include "common.h"
-
-static struct resource tct_hammer_nor_resource = {
-               .start = 0x00000000,
-               .end   = 0x01000000 - 1,
-               .flags = IORESOURCE_MEM,
-};
-
-static struct mtd_partition tct_hammer_mtd_partitions[] = {
-       {
-               .name           = "System",
-               .size           = 0x240000,
-               .offset         = 0,
-               .mask_flags     = MTD_WRITEABLE,  /* force read-only */
-       }, {
-               .name           = "JFFS2",
-               .size           = MTDPART_SIZ_FULL,
-               .offset         = MTDPART_OFS_APPEND,
-       }
-};
-
-static struct physmap_flash_data tct_hammer_flash_data = {
-       .width          = 2,
-       .parts          = tct_hammer_mtd_partitions,
-       .nr_parts       = ARRAY_SIZE(tct_hammer_mtd_partitions),
-};
-
-static struct platform_device tct_hammer_device_nor = {
-       .name           = "physmap-flash",
-       .id             = 0,
-       .dev = {
-                       .platform_data = &tct_hammer_flash_data,
-               },
-       .num_resources  = 1,
-       .resource       = &tct_hammer_nor_resource,
-};
-
-static struct map_desc tct_hammer_iodesc[] __initdata = {
-};
-
-#define UCON S3C2410_UCON_DEFAULT
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg tct_hammer_uartcfgs[] = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       }
-};
-
-
-static struct platform_device *tct_hammer_devices[] __initdata = {
-       &s3c_device_adc,
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_ohci,
-       &s3c_device_rtc,
-       &s3c_device_usbgadget,
-       &s3c_device_sdi,
-       &tct_hammer_device_nor,
-};
-
-static void __init tct_hammer_map_io(void)
-{
-       s3c24xx_init_io(tct_hammer_iodesc, ARRAY_SIZE(tct_hammer_iodesc));
-       s3c24xx_init_clocks(0);
-       s3c24xx_init_uarts(tct_hammer_uartcfgs, ARRAY_SIZE(tct_hammer_uartcfgs));
-}
-
-static void __init tct_hammer_init(void)
-{
-       s3c_i2c0_set_platdata(NULL);
-       platform_add_devices(tct_hammer_devices, ARRAY_SIZE(tct_hammer_devices));
-}
-
-MACHINE_START(TCT_HAMMER, "TCT_HAMMER")
-       .atag_offset    = 0x100,
-       .map_io         = tct_hammer_map_io,
-       .init_irq       = s3c24xx_init_irq,
-       .init_machine   = tct_hammer_init,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c2410_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
deleted file mode 100644 (file)
index dbe668a..0000000
+++ /dev/null
@@ -1,386 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/mach-vr1000.c
- *
- * Copyright (c) 2003-2008 Simtec Electronics
- *   Ben Dooks <ben@simtec.co.uk>
- *
- * Machine support for Thorcom VR1000 board. Designed for Thorcom by
- * Simtec Electronics, http://www.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/dm9000.h>
-#include <linux/i2c.h>
-
-#include <linux/serial.h>
-#include <linux/tty.h>
-#include <linux/serial_8250.h>
-#include <linux/serial_reg.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/bast-map.h>
-#include <mach/vr1000-map.h>
-#include <mach/vr1000-irq.h>
-#include <mach/vr1000-cpld.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <mach/leds-gpio.h>
-
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/iic.h>
-#include <plat/audio-simtec.h>
-
-#include "usb-simtec.h"
-#include "nor-simtec.h"
-#include "common.h"
-
-/* macros for virtual address mods for the io space entries */
-#define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5)
-#define VA_C4(item) ((unsigned long)(item) + BAST_VAM_CS4)
-#define VA_C3(item) ((unsigned long)(item) + BAST_VAM_CS3)
-#define VA_C2(item) ((unsigned long)(item) + BAST_VAM_CS2)
-
-/* macros to modify the physical addresses for io space */
-
-#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2))
-#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3))
-#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4))
-#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5))
-
-static struct map_desc vr1000_iodesc[] __initdata = {
-  /* ISA IO areas */
-  {
-         .virtual      = (u32)S3C24XX_VA_ISA_BYTE,
-         .pfn          = PA_CS2(BAST_PA_ISAIO),
-         .length       = SZ_16M,
-         .type         = MT_DEVICE,
-  }, {
-         .virtual      = (u32)S3C24XX_VA_ISA_WORD,
-         .pfn          = PA_CS3(BAST_PA_ISAIO),
-         .length       = SZ_16M,
-         .type         = MT_DEVICE,
-  },
-
-  /*  CPLD control registers, and external interrupt controls */
-  {
-         .virtual      = (u32)VR1000_VA_CTRL1,
-         .pfn          = __phys_to_pfn(VR1000_PA_CTRL1),
-         .length       = SZ_1M,
-         .type         = MT_DEVICE,
-  }, {
-         .virtual      = (u32)VR1000_VA_CTRL2,
-         .pfn          = __phys_to_pfn(VR1000_PA_CTRL2),
-         .length       = SZ_1M,
-         .type         = MT_DEVICE,
-  }, {
-         .virtual      = (u32)VR1000_VA_CTRL3,
-         .pfn          = __phys_to_pfn(VR1000_PA_CTRL3),
-         .length       = SZ_1M,
-         .type         = MT_DEVICE,
-  }, {
-         .virtual      = (u32)VR1000_VA_CTRL4,
-         .pfn          = __phys_to_pfn(VR1000_PA_CTRL4),
-         .length       = SZ_1M,
-         .type         = MT_DEVICE,
-  },
-};
-
-#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       /* port 2 is not actually used */
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       }
-};
-
-/* definitions for the vr1000 extra 16550 serial ports */
-
-#define VR1000_BAUDBASE (3692307)
-
-#define VR1000_SERIAL_MAPBASE(x) (VR1000_PA_SERIAL + 0x80 + ((x) << 5))
-
-static struct plat_serial8250_port serial_platform_data[] = {
-       [0] = {
-               .mapbase        = VR1000_SERIAL_MAPBASE(0),
-               .irq            = IRQ_VR1000_SERIAL + 0,
-               .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
-               .iotype         = UPIO_MEM,
-               .regshift       = 0,
-               .uartclk        = VR1000_BAUDBASE,
-       },
-       [1] = {
-               .mapbase        = VR1000_SERIAL_MAPBASE(1),
-               .irq            = IRQ_VR1000_SERIAL + 1,
-               .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
-               .iotype         = UPIO_MEM,
-               .regshift       = 0,
-               .uartclk        = VR1000_BAUDBASE,
-       },
-       [2] = {
-               .mapbase        = VR1000_SERIAL_MAPBASE(2),
-               .irq            = IRQ_VR1000_SERIAL + 2,
-               .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
-               .iotype         = UPIO_MEM,
-               .regshift       = 0,
-               .uartclk        = VR1000_BAUDBASE,
-       },
-       [3] = {
-               .mapbase        = VR1000_SERIAL_MAPBASE(3),
-               .irq            = IRQ_VR1000_SERIAL + 3,
-               .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
-               .iotype         = UPIO_MEM,
-               .regshift       = 0,
-               .uartclk        = VR1000_BAUDBASE,
-       },
-       { },
-};
-
-static struct platform_device serial_device = {
-       .name                   = "serial8250",
-       .id                     = PLAT8250_DEV_PLATFORM,
-       .dev                    = {
-               .platform_data  = serial_platform_data,
-       },
-};
-
-/* DM9000 ethernet devices */
-
-static struct resource vr1000_dm9k0_resource[] = {
-       [0] = {
-               .start = S3C2410_CS5 + VR1000_PA_DM9000,
-               .end   = S3C2410_CS5 + VR1000_PA_DM9000 + 3,
-               .flags = IORESOURCE_MEM
-       },
-       [1] = {
-               .start = S3C2410_CS5 + VR1000_PA_DM9000 + 0x40,
-               .end   = S3C2410_CS5 + VR1000_PA_DM9000 + 0x7f,
-               .flags = IORESOURCE_MEM
-       },
-       [2] = {
-               .start = IRQ_VR1000_DM9000A,
-               .end   = IRQ_VR1000_DM9000A,
-               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-       }
-
-};
-
-static struct resource vr1000_dm9k1_resource[] = {
-       [0] = {
-               .start = S3C2410_CS5 + VR1000_PA_DM9000 + 0x80,
-               .end   = S3C2410_CS5 + VR1000_PA_DM9000 + 0x83,
-               .flags = IORESOURCE_MEM
-       },
-       [1] = {
-               .start = S3C2410_CS5 + VR1000_PA_DM9000 + 0xC0,
-               .end   = S3C2410_CS5 + VR1000_PA_DM9000 + 0xFF,
-               .flags = IORESOURCE_MEM
-       },
-       [2] = {
-               .start = IRQ_VR1000_DM9000N,
-               .end   = IRQ_VR1000_DM9000N,
-               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-       }
-};
-
-/* for the moment we limit ourselves to 16bit IO until some
- * better IO routines can be written and tested
-*/
-
-static struct dm9000_plat_data vr1000_dm9k_platdata = {
-       .flags          = DM9000_PLATF_16BITONLY,
-};
-
-static struct platform_device vr1000_dm9k0 = {
-       .name           = "dm9000",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(vr1000_dm9k0_resource),
-       .resource       = vr1000_dm9k0_resource,
-       .dev            = {
-               .platform_data = &vr1000_dm9k_platdata,
-       }
-};
-
-static struct platform_device vr1000_dm9k1 = {
-       .name           = "dm9000",
-       .id             = 1,
-       .num_resources  = ARRAY_SIZE(vr1000_dm9k1_resource),
-       .resource       = vr1000_dm9k1_resource,
-       .dev            = {
-               .platform_data = &vr1000_dm9k_platdata,
-       }
-};
-
-/* LEDS */
-
-static struct s3c24xx_led_platdata vr1000_led1_pdata = {
-       .name           = "led1",
-       .gpio           = S3C2410_GPB(0),
-       .def_trigger    = "",
-};
-
-static struct s3c24xx_led_platdata vr1000_led2_pdata = {
-       .name           = "led2",
-       .gpio           = S3C2410_GPB(1),
-       .def_trigger    = "",
-};
-
-static struct s3c24xx_led_platdata vr1000_led3_pdata = {
-       .name           = "led3",
-       .gpio           = S3C2410_GPB(2),
-       .def_trigger    = "",
-};
-
-static struct platform_device vr1000_led1 = {
-       .name           = "s3c24xx_led",
-       .id             = 1,
-       .dev            = {
-               .platform_data  = &vr1000_led1_pdata,
-       },
-};
-
-static struct platform_device vr1000_led2 = {
-       .name           = "s3c24xx_led",
-       .id             = 2,
-       .dev            = {
-               .platform_data  = &vr1000_led2_pdata,
-       },
-};
-
-static struct platform_device vr1000_led3 = {
-       .name           = "s3c24xx_led",
-       .id             = 3,
-       .dev            = {
-               .platform_data  = &vr1000_led3_pdata,
-       },
-};
-
-/* I2C devices. */
-
-static struct i2c_board_info vr1000_i2c_devs[] __initdata = {
-       {
-               I2C_BOARD_INFO("tlv320aic23", 0x1a),
-       }, {
-               I2C_BOARD_INFO("tmp101", 0x48),
-       }, {
-               I2C_BOARD_INFO("m41st87", 0x68),
-       },
-};
-
-/* devices for this board */
-
-static struct platform_device *vr1000_devices[] __initdata = {
-       &s3c_device_ohci,
-       &s3c_device_lcd,
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_adc,
-       &serial_device,
-       &vr1000_dm9k0,
-       &vr1000_dm9k1,
-       &vr1000_led1,
-       &vr1000_led2,
-       &vr1000_led3,
-};
-
-static struct clk *vr1000_clocks[] __initdata = {
-       &s3c24xx_dclk0,
-       &s3c24xx_dclk1,
-       &s3c24xx_clkout0,
-       &s3c24xx_clkout1,
-       &s3c24xx_uclk,
-};
-
-static void vr1000_power_off(void)
-{
-       gpio_direction_output(S3C2410_GPB(9), 1);
-}
-
-static void __init vr1000_map_io(void)
-{
-       /* initialise clock sources */
-
-       s3c24xx_dclk0.parent = &clk_upll;
-       s3c24xx_dclk0.rate   = 12*1000*1000;
-
-       s3c24xx_dclk1.parent = NULL;
-       s3c24xx_dclk1.rate   = 3692307;
-
-       s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
-       s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
-
-       s3c24xx_uclk.parent  = &s3c24xx_clkout1;
-
-       s3c24xx_register_clocks(vr1000_clocks, ARRAY_SIZE(vr1000_clocks));
-
-       pm_power_off = vr1000_power_off;
-
-       s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
-       s3c24xx_init_clocks(0);
-       s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
-}
-
-static void __init vr1000_init(void)
-{
-       s3c_i2c0_set_platdata(NULL);
-       platform_add_devices(vr1000_devices, ARRAY_SIZE(vr1000_devices));
-
-       i2c_register_board_info(0, vr1000_i2c_devs,
-                               ARRAY_SIZE(vr1000_i2c_devs));
-
-       nor_simtec_init();
-       simtec_audio_add(NULL, true, NULL);
-
-       WARN_ON(gpio_request(S3C2410_GPB(9), "power off"));
-}
-
-MACHINE_START(VR1000, "Thorcom-VR1000")
-       /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
-       .atag_offset    = 0x100,
-       .map_io         = vr1000_map_io,
-       .init_machine   = vr1000_init,
-       .init_irq       = s3c24xx_init_irq,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c2410_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2410/nor-simtec.c b/arch/arm/mach-s3c2410/nor-simtec.c
deleted file mode 100644 (file)
index ad9f750..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/nor-simtec.c
- *
- * Copyright (c) 2008 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Simtec NOR mapping
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/physmap.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/map.h>
-#include <mach/bast-map.h>
-#include <mach/bast-cpld.h>
-
-#include "nor-simtec.h"
-
-static void simtec_nor_vpp(struct platform_device *pdev, int vpp)
-{
-       unsigned int val;
-       unsigned long flags;
-
-       local_irq_save(flags);
-       val = __raw_readb(BAST_VA_CTRL3);
-
-       printk(KERN_DEBUG "%s(%d)\n", __func__, vpp);
-
-       if (vpp)
-               val |= BAST_CPLD_CTRL3_ROMWEN;
-       else
-               val &= ~BAST_CPLD_CTRL3_ROMWEN;
-
-       __raw_writeb(val, BAST_VA_CTRL3);
-       local_irq_restore(flags);
-}
-
-static struct physmap_flash_data simtec_nor_pdata = {
-       .width          = 2,
-       .set_vpp        = simtec_nor_vpp,
-       .nr_parts       = 0,
-};
-
-static struct resource simtec_nor_resource[] = {
-       [0] = {
-               .start = S3C2410_CS1 + 0x4000000,
-               .end   = S3C2410_CS1 + 0x4000000 + SZ_8M - 1,
-               .flags = IORESOURCE_MEM,
-       }
-};
-
-static struct platform_device simtec_device_nor = {
-       .name           = "physmap-flash",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(simtec_nor_resource),
-       .resource       = simtec_nor_resource,
-       .dev            = {
-               .platform_data = &simtec_nor_pdata,
-       },
-};
-
-void __init nor_simtec_init(void)
-{
-       int ret;
-
-       ret = platform_device_register(&simtec_device_nor);
-       if (ret < 0)
-               printk(KERN_ERR "failed to register physmap-flash device\n");
-       else
-               simtec_nor_vpp(NULL, 1);
-}
diff --git a/arch/arm/mach-s3c2410/nor-simtec.h b/arch/arm/mach-s3c2410/nor-simtec.h
deleted file mode 100644 (file)
index f619c1e..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/nor-simtec.h
- *
- * Copyright (c) 2008 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Simtec NOR mapping
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-extern void nor_simtec_init(void);
diff --git a/arch/arm/mach-s3c2410/pm-h1940.S b/arch/arm/mach-s3c2410/pm-h1940.S
deleted file mode 100644 (file)
index c93bf2d..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/pm-h1940.S
- *
- * Copyright (c) 2006 Ben Dooks <ben-linux@fluff.org>
- *
- * H1940 Suspend to RAM
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <mach/regs-gpio.h>
-
-       .text
-       .global h1940_pm_return
-
-h1940_pm_return:
-       mov     r0, #S3C2410_PA_GPIO
-       ldr     pc, [ r0, #S3C2410_GSTATUS3 - S3C24XX_VA_GPIO ]
diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c
deleted file mode 100644 (file)
index 03f706d..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/pm.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/init.h>
-#include <linux/suspend.h>
-#include <linux/errno.h>
-#include <linux/time.h>
-#include <linux/device.h>
-#include <linux/syscore_ops.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-
-#include <asm/mach-types.h>
-
-#include <mach/regs-gpio.h>
-#include <mach/h1940.h>
-
-#include <plat/cpu.h>
-#include <plat/pm.h>
-
-static void s3c2410_pm_prepare(void)
-{
-       /* ensure at least GSTATUS3 has the resume address */
-
-       __raw_writel(virt_to_phys(s3c_cpu_resume), S3C2410_GSTATUS3);
-
-       S3C_PMDBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
-       S3C_PMDBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
-
-       if (machine_is_h1940()) {
-               void *base = phys_to_virt(H1940_SUSPEND_CHECK);
-               unsigned long ptr;
-               unsigned long calc = 0;
-
-               /* generate check for the bootloader to check on resume */
-
-               for (ptr = 0; ptr < 0x40000; ptr += 0x400)
-                       calc += __raw_readl(base+ptr);
-
-               __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
-       }
-
-       /* RX3715 and RX1950 use similar to H1940 code and the
-        * same offsets for resume and checksum pointers */
-
-       if (machine_is_rx3715() || machine_is_rx1950()) {
-               void *base = phys_to_virt(H1940_SUSPEND_CHECK);
-               unsigned long ptr;
-               unsigned long calc = 0;
-
-               /* generate check for the bootloader to check on resume */
-
-               for (ptr = 0; ptr < 0x40000; ptr += 0x4)
-                       calc += __raw_readl(base+ptr);
-
-               __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
-       }
-
-       if ( machine_is_aml_m5900() )
-               s3c2410_gpio_setpin(S3C2410_GPF(2), 1);
-
-       if (machine_is_rx1950()) {
-               /* According to S3C2442 user's manual, page 7-17,
-                * when the system is operating in NAND boot mode,
-                * the hardware pin configuration - EINT[23:21] â€“
-                * must be set as input for starting up after
-                * wakeup from sleep mode
-                */
-               s3c_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_INPUT);
-               s3c_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPIO_INPUT);
-               s3c_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPIO_INPUT);
-       }
-}
-
-static void s3c2410_pm_resume(void)
-{
-       unsigned long tmp;
-
-       /* unset the return-from-sleep flag, to ensure reset */
-
-       tmp = __raw_readl(S3C2410_GSTATUS2);
-       tmp &= S3C2410_GSTATUS2_OFFRESET;
-       __raw_writel(tmp, S3C2410_GSTATUS2);
-
-       if ( machine_is_aml_m5900() )
-               s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
-}
-
-struct syscore_ops s3c2410_pm_syscore_ops = {
-       .resume         = s3c2410_pm_resume,
-};
-
-static int s3c2410_pm_add(struct device *dev, struct subsys_interface *sif)
-{
-       pm_cpu_prep = s3c2410_pm_prepare;
-       pm_cpu_sleep = s3c2410_cpu_suspend;
-
-       return 0;
-}
-
-#if defined(CONFIG_CPU_S3C2410)
-static struct subsys_interface s3c2410_pm_interface = {
-       .name           = "s3c2410_pm",
-       .subsys         = &s3c2410_subsys,
-       .add_dev        = s3c2410_pm_add,
-};
-
-/* register ourselves */
-
-static int __init s3c2410_pm_drvinit(void)
-{
-       return subsys_interface_register(&s3c2410_pm_interface);
-}
-
-arch_initcall(s3c2410_pm_drvinit);
-
-static struct subsys_interface s3c2410a_pm_interface = {
-       .name           = "s3c2410a_pm",
-       .subsys         = &s3c2410a_subsys,
-       .add_dev        = s3c2410_pm_add,
-};
-
-static int __init s3c2410a_pm_drvinit(void)
-{
-       return subsys_interface_register(&s3c2410a_pm_interface);
-}
-
-arch_initcall(s3c2410a_pm_drvinit);
-#endif
-
-#if defined(CONFIG_CPU_S3C2440)
-static struct subsys_interface s3c2440_pm_interface = {
-       .name           = "s3c2440_pm",
-       .subsys         = &s3c2440_subsys,
-       .add_dev        = s3c2410_pm_add,
-};
-
-static int __init s3c2440_pm_drvinit(void)
-{
-       return subsys_interface_register(&s3c2440_pm_interface);
-}
-
-arch_initcall(s3c2440_pm_drvinit);
-#endif
-
-#if defined(CONFIG_CPU_S3C2442)
-static struct subsys_interface s3c2442_pm_interface = {
-       .name           = "s3c2442_pm",
-       .subsys         = &s3c2442_subsys,
-       .add_dev        = s3c2410_pm_add,
-};
-
-static int __init s3c2442_pm_drvinit(void)
-{
-       return subsys_interface_register(&s3c2442_pm_interface);
-}
-
-arch_initcall(s3c2442_pm_drvinit);
-#endif
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
deleted file mode 100644 (file)
index 061b6bb..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/s3c2410.c
- *
- * Copyright (c) 2003-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * http://www.simtec.co.uk/products/EB2410ITX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/clk.h>
-#include <linux/device.h>
-#include <linux/syscore_ops.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <plat/cpu-freq.h>
-
-#include <mach/regs-clock.h>
-#include <plat/regs-serial.h>
-
-#include <plat/s3c2410.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/clock.h>
-#include <plat/pll.h>
-#include <plat/pm.h>
-#include <plat/watchdog-reset.h>
-
-#include <plat/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-
-/* Initial IO mappings */
-
-static struct map_desc s3c2410_iodesc[] __initdata = {
-       IODESC_ENT(CLKPWR),
-       IODESC_ENT(TIMER),
-       IODESC_ENT(WATCHDOG),
-};
-
-/* our uart devices */
-
-/* uart registration process */
-
-void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
-       s3c24xx_init_uartdevs("s3c2410-uart", s3c2410_uart_resources, cfg, no);
-}
-
-/* s3c2410_map_io
- *
- * register the standard cpu IO areas, and any passed in from the
- * machine specific initialisation.
-*/
-
-void __init s3c2410_map_io(void)
-{
-       s3c24xx_gpiocfg_default.set_pull = s3c24xx_gpio_setpull_1up;
-       s3c24xx_gpiocfg_default.get_pull = s3c24xx_gpio_getpull_1up;
-
-       iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
-}
-
-void __init_or_cpufreq s3c2410_setup_clocks(void)
-{
-       struct clk *xtal_clk;
-       unsigned long tmp;
-       unsigned long xtal;
-       unsigned long fclk;
-       unsigned long hclk;
-       unsigned long pclk;
-
-       xtal_clk = clk_get(NULL, "xtal");
-       xtal = clk_get_rate(xtal_clk);
-       clk_put(xtal_clk);
-
-       /* now we've got our machine bits initialised, work out what
-        * clocks we've got */
-
-       fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal);
-
-       tmp = __raw_readl(S3C2410_CLKDIVN);
-
-       /* work out clock scalings */
-
-       hclk = fclk / ((tmp & S3C2410_CLKDIVN_HDIVN) ? 2 : 1);
-       pclk = hclk / ((tmp & S3C2410_CLKDIVN_PDIVN) ? 2 : 1);
-
-       /* print brieft summary of clocks, etc */
-
-       printk("S3C2410: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
-              print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
-
-       /* initialise the clocks here, to allow other things like the
-        * console to use them
-        */
-
-       s3c24xx_setup_clocks(fclk, hclk, pclk);
-}
-
-/* fake ARMCLK for use with cpufreq, etc. */
-
-static struct clk s3c2410_armclk = {
-       .name   = "armclk",
-       .parent = &clk_f,
-       .id     = -1,
-};
-
-static struct clk_lookup s3c2410_clk_lookup[] = {
-       CLKDEV_INIT(NULL, "clk_uart_baud0", &clk_p),
-       CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
-};
-
-void __init s3c2410_init_clocks(int xtal)
-{
-       s3c24xx_register_baseclocks(xtal);
-       s3c2410_setup_clocks();
-       s3c2410_baseclk_add();
-       s3c24xx_register_clock(&s3c2410_armclk);
-       clkdev_add_table(s3c2410_clk_lookup, ARRAY_SIZE(s3c2410_clk_lookup));
-}
-
-struct bus_type s3c2410_subsys = {
-       .name = "s3c2410-core",
-       .dev_name = "s3c2410-core",
-};
-
-/* Note, we would have liked to name this s3c2410-core, but we cannot
- * register two subsystems with the same name.
- */
-struct bus_type s3c2410a_subsys = {
-       .name = "s3c2410a-core",
-       .dev_name = "s3c2410a-core",
-};
-
-static struct device s3c2410_dev = {
-       .bus            = &s3c2410_subsys,
-};
-
-/* need to register the subsystem before we actually register the device, and
- * we also need to ensure that it has been initialised before any of the
- * drivers even try to use it (even if not on an s3c2410 based system)
- * as a driver which may support both 2410 and 2440 may try and use it.
-*/
-
-static int __init s3c2410_core_init(void)
-{
-       return subsys_system_register(&s3c2410_subsys, NULL);
-}
-
-core_initcall(s3c2410_core_init);
-
-static int __init s3c2410a_core_init(void)
-{
-       return subsys_system_register(&s3c2410a_subsys, NULL);
-}
-
-core_initcall(s3c2410a_core_init);
-
-int __init s3c2410_init(void)
-{
-       printk("S3C2410: Initialising architecture\n");
-
-#ifdef CONFIG_PM
-       register_syscore_ops(&s3c2410_pm_syscore_ops);
-#endif
-       register_syscore_ops(&s3c24xx_irq_syscore_ops);
-
-       return device_register(&s3c2410_dev);
-}
-
-int __init s3c2410a_init(void)
-{
-       s3c2410_dev.bus = &s3c2410a_subsys;
-       return s3c2410_init();
-}
-
-void s3c2410_restart(char mode, const char *cmd)
-{
-       if (mode == 's') {
-               soft_restart(0);
-       }
-
-       arch_wdt_reset();
-
-       /* we'll take a jump through zero as a poor second */
-       soft_restart(0);
-}
diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S
deleted file mode 100644 (file)
index dd5b638..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/sleep.S
- *
- * Copyright (c) 2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 Power Manager (Suspend-To-RAM) support
- *
- * Based on PXA/SA1100 sleep code by:
- *     Nicolas Pitre, (c) 2002 Monta Vista Software Inc
- *     Cliff Brake, (c) 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <mach/regs-gpio.h>
-#include <mach/regs-clock.h>
-#include <mach/regs-mem.h>
-#include <plat/regs-serial.h>
-
-       /* s3c2410_cpu_suspend
-        *
-        * put the cpu into sleep mode
-       */
-
-ENTRY(s3c2410_cpu_suspend)
-       @@ prepare cpu to sleep
-
-       ldr     r4, =S3C2410_REFRESH
-       ldr     r5, =S3C24XX_MISCCR
-       ldr     r6, =S3C2410_CLKCON
-       ldr     r7, [ r4 ]              @ get REFRESH (and ensure in TLB)
-       ldr     r8, [ r5 ]              @ get MISCCR (and ensure in TLB)
-       ldr     r9, [ r6 ]              @ get CLKCON (and ensure in TLB)
-
-       orr     r7, r7, #S3C2410_REFRESH_SELF   @ SDRAM sleep command
-       orr     r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
-       orr     r9, r9, #S3C2410_CLKCON_POWER   @ power down command
-
-       teq     pc, #0                  @ first as a trial-run to load cache
-       bl      s3c2410_do_sleep
-       teq     r0, r0                  @ now do it for real
-       b       s3c2410_do_sleep        @
-
-       @@ align next bit of code to cache line
-       .align  5
-s3c2410_do_sleep:
-       streq   r7, [ r4 ]                      @ SDRAM sleep command
-       streq   r8, [ r5 ]                      @ SDRAM power-down config
-       streq   r9, [ r6 ]                      @ CPU sleep
-1:     beq     1b
-       mov     pc, r14
diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c
deleted file mode 100644 (file)
index 29bd3d9..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/usb-simtec.c
- *
- * Copyright 2004-2005 Simtec Electronics
- *   Ben Dooks <ben@simtec.co.uk>
- *
- * http://www.simtec.co.uk/products/EB2410ITX/
- *
- * Simtec BAST and Thorcom VR1000 USB port support functions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define DEBUG
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/gpio.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/bast-map.h>
-#include <mach/bast-irq.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <plat/usb-control.h>
-#include <plat/devs.h>
-
-#include "usb-simtec.h"
-
-/* control power and monitor over-current events on various Simtec
- * designed boards.
-*/
-
-static unsigned int power_state[2];
-
-static void
-usb_simtec_powercontrol(int port, int to)
-{
-       pr_debug("usb_simtec_powercontrol(%d,%d)\n", port, to);
-
-       power_state[port] = to;
-
-       if (power_state[0] && power_state[1])
-               gpio_set_value(S3C2410_GPB(4), 0);
-       else
-               gpio_set_value(S3C2410_GPB(4), 1);
-}
-
-static irqreturn_t
-usb_simtec_ocirq(int irq, void *pw)
-{
-       struct s3c2410_hcd_info *info = pw;
-
-       if (gpio_get_value(S3C2410_GPG(10)) == 0) {
-               pr_debug("usb_simtec: over-current irq (oc detected)\n");
-               s3c2410_usb_report_oc(info, 3);
-       } else {
-               pr_debug("usb_simtec: over-current irq (oc cleared)\n");
-               s3c2410_usb_report_oc(info, 0);
-       }
-
-       return IRQ_HANDLED;
-}
-
-static void usb_simtec_enableoc(struct s3c2410_hcd_info *info, int on)
-{
-       int ret;
-
-       if (on) {
-               ret = request_irq(IRQ_USBOC, usb_simtec_ocirq,
-                                 IRQF_DISABLED | IRQF_TRIGGER_RISING |
-                                  IRQF_TRIGGER_FALLING,
-                                 "USB Over-current", info);
-               if (ret != 0) {
-                       printk(KERN_ERR "failed to request usb oc irq\n");
-               }
-       } else {
-               free_irq(IRQ_USBOC, info);
-       }
-}
-
-static struct s3c2410_hcd_info usb_simtec_info __initdata = {
-       .port[0]        = {
-               .flags  = S3C_HCDFLG_USED
-       },
-       .port[1]        = {
-               .flags  = S3C_HCDFLG_USED
-       },
-
-       .power_control  = usb_simtec_powercontrol,
-       .enable_oc      = usb_simtec_enableoc,
-};
-
-
-int usb_simtec_init(void)
-{
-       int ret;
-
-       printk("USB Power Control, Copyright 2004 Simtec Electronics\n");
-
-       ret = gpio_request(S3C2410_GPB(4), "USB power control");
-       if (ret < 0) {
-               pr_err("%s: failed to get GPB4\n", __func__);
-               return ret;
-       }
-
-       ret = gpio_request(S3C2410_GPG(10), "USB overcurrent");
-       if (ret < 0) {
-               pr_err("%s: failed to get GPG10\n", __func__);
-               gpio_free(S3C2410_GPB(4));
-               return ret;
-       }
-
-       /* turn power on */
-       gpio_direction_output(S3C2410_GPB(4), 1);
-       gpio_direction_input(S3C2410_GPG(10));
-
-       s3c_ohci_set_platdata(&usb_simtec_info);
-       return 0;
-}
diff --git a/arch/arm/mach-s3c2410/usb-simtec.h b/arch/arm/mach-s3c2410/usb-simtec.h
deleted file mode 100644 (file)
index 03842ed..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/usb-simtec.h
- *
- * Copyright (c) 2004 Simtec Electronics
- *   Ben Dooks <ben@simtec.co.uk>
- *
- * http://www.simtec.co.uk/products/EB2410ITX/
- *
- * Simtec BAST and Thorcom VR1000 USB port support functions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-extern int usb_simtec_init(void);
-
index b8b9029e9f2d7d7a0446bb869948a7590e65d2ac..c5256f4e90bb26be110c214593f66373aa8b2640 100644 (file)
@@ -2,41 +2,6 @@
 #
 # Licensed under GPLv2
 
-config CPU_S3C2412
-       bool
-       depends on ARCH_S3C2410
-       select CPU_ARM926T
-       select CPU_LLSERIAL_S3C2440
-       select S3C2412_PM if PM
-       select S3C2412_DMA if S3C2410_DMA
-       help
-         Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
-
-config CPU_S3C2412_ONLY
-       bool
-       depends on ARCH_S3C2410 && !CPU_S3C2410 && \
-                  !CPU_S3C2416 && !CPU_S3C2440 && !CPU_S3C2442 && \
-                  !CPU_S3C2443 && CPU_S3C2412
-       default y if CPU_S3C2412
-
-config S3C2412_DMA
-       bool
-       depends on CPU_S3C2412
-       help
-         Internal config node for S3C2412 DMA support
-
-config S3C2412_PM
-       bool
-       select S3C2412_PM_SLEEP
-       help
-         Internal config node to apply S3C2412 power management
-
-config S3C2412_PM_SLEEP
-       bool
-       help
-         Internal config node to apply sleep for S3C2412 power management.
-         Can be selected by another SoCs with similar sleep procedure.
-
 # Note, the S3C2412 IOtiming support is in plat-s3c24xx
 
 config S3C2412_CPUFREQ
@@ -46,53 +11,3 @@ config S3C2412_CPUFREQ
        default y
        help
          CPU Frequency scaling support for S3C2412 and S3C2413 SoC CPUs.
-
-menu "S3C2412 Machines"
-
-config MACH_JIVE
-       bool "Logitech Jive"
-       select CPU_S3C2412
-       select S3C_DEV_USB_HOST
-       select S3C_DEV_NAND
-       help
-         Say Y here if you are using the Logitech Jive.
-
-config MACH_JIVE_SHOW_BOOTLOADER
-       bool "Allow access to bootloader partitions in MTD (EXPERIMENTAL)"
-       depends on MACH_JIVE && EXPERIMENTAL
-
-config MACH_SMDK2413
-       bool "SMDK2413"
-       select CPU_S3C2412
-       select MACH_S3C2413
-       select MACH_SMDK
-       select S3C_DEV_USB_HOST
-       select S3C_DEV_NAND
-       help
-         Say Y here if you are using an SMDK2413
-
-config MACH_S3C2413
-       bool
-       help
-         Internal node for S3C2413 version of SMDK2413, so that
-         machine_is_s3c2413() will work when MACH_SMDK2413 is
-         selected
-
-config MACH_SMDK2412
-       bool "SMDK2412"
-       select MACH_SMDK2413
-       help
-         Say Y here if you are using an SMDK2412
-
-         Note, this shares support with SMDK2413, so will automatically
-         select MACH_SMDK2413.
-
-config MACH_VSTMS
-       bool "VMSTMS"
-       select CPU_S3C2412
-       select S3C_DEV_USB_HOST
-       select S3C_DEV_NAND
-       help
-         Say Y here if you are using an VSTMS board
-
-endmenu
index 7e4d95fa8a97f0d2668f4a6146ddcb8d8b4f548d..41a6c279fb2f99317646ddc0bae2a9f0d622d32d 100644 (file)
@@ -9,16 +9,4 @@ obj-m                          :=
 obj-n                          :=
 obj-                           :=
 
-obj-$(CONFIG_CPU_S3C2412)      += s3c2412.o
-obj-$(CONFIG_CPU_S3C2412)      += irq.o
-obj-$(CONFIG_CPU_S3C2412)      += clock.o
-obj-$(CONFIG_S3C2412_DMA)      += dma.o
-obj-$(CONFIG_S3C2412_PM)       += pm.o
-obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep.o
 obj-$(CONFIG_S3C2412_CPUFREQ)  += cpu-freq.o
-
-# Machine support
-
-obj-$(CONFIG_MACH_JIVE)                += mach-jive.o
-obj-$(CONFIG_MACH_SMDK2413)    += mach-smdk2413.o
-obj-$(CONFIG_MACH_VSTMS)       += mach-vstms.o
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c
deleted file mode 100644 (file)
index d10b695..0000000
+++ /dev/null
@@ -1,763 +0,0 @@
-/* linux/arch/arm/mach-s3c2412/clock.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2412,S3C2413 Clock control support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/serial_core.h>
-#include <linux/io.h>
-
-#include <asm/mach/map.h>
-
-#include <mach/hardware.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-clock.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/s3c2412.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-/* We currently have to assume that the system is running
- * from the XTPll input, and that all ***REFCLKs are being
- * fed from it, as we cannot read the state of OM[4] from
- * software.
- *
- * It would be possible for each board initialisation to
- * set the correct muxing at initialisation
-*/
-
-static int s3c2412_clkcon_enable(struct clk *clk, int enable)
-{
-       unsigned int clocks = clk->ctrlbit;
-       unsigned long clkcon;
-
-       clkcon = __raw_readl(S3C2410_CLKCON);
-
-       if (enable)
-               clkcon |= clocks;
-       else
-               clkcon &= ~clocks;
-
-       __raw_writel(clkcon, S3C2410_CLKCON);
-
-       return 0;
-}
-
-static int s3c2412_upll_enable(struct clk *clk, int enable)
-{
-       unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
-       unsigned long orig = upllcon;
-
-       if (!enable)
-               upllcon |= S3C2412_PLLCON_OFF;
-       else
-               upllcon &= ~S3C2412_PLLCON_OFF;
-
-       __raw_writel(upllcon, S3C2410_UPLLCON);
-
-       /* allow ~150uS for the PLL to settle and lock */
-
-       if (enable && (orig & S3C2412_PLLCON_OFF))
-               udelay(150);
-
-       return 0;
-}
-
-/* clock selections */
-
-static struct clk clk_erefclk = {
-       .name           = "erefclk",
-};
-
-static struct clk clk_urefclk = {
-       .name           = "urefclk",
-};
-
-static int s3c2412_setparent_usysclk(struct clk *clk, struct clk *parent)
-{
-       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
-
-       if (parent == &clk_urefclk)
-               clksrc &= ~S3C2412_CLKSRC_USYSCLK_UPLL;
-       else if (parent == &clk_upll)
-               clksrc |= S3C2412_CLKSRC_USYSCLK_UPLL;
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       __raw_writel(clksrc, S3C2412_CLKSRC);
-       return 0;
-}
-
-static struct clk clk_usysclk = {
-       .name           = "usysclk",
-       .parent         = &clk_xtal,
-       .ops            = &(struct clk_ops) {
-               .set_parent     = s3c2412_setparent_usysclk,
-       },
-};
-
-static struct clk clk_mrefclk = {
-       .name           = "mrefclk",
-       .parent         = &clk_xtal,
-};
-
-static struct clk clk_mdivclk = {
-       .name           = "mdivclk",
-       .parent         = &clk_xtal,
-};
-
-static int s3c2412_setparent_usbsrc(struct clk *clk, struct clk *parent)
-{
-       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
-
-       if (parent == &clk_usysclk)
-               clksrc &= ~S3C2412_CLKSRC_USBCLK_HCLK;
-       else if (parent == &clk_h)
-               clksrc |= S3C2412_CLKSRC_USBCLK_HCLK;
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       __raw_writel(clksrc, S3C2412_CLKSRC);
-       return 0;
-}
-
-static unsigned long s3c2412_roundrate_usbsrc(struct clk *clk,
-                                             unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       int div;
-
-       if (rate > parent_rate)
-               return parent_rate;
-
-       div = parent_rate / rate;
-       if (div > 2)
-               div = 2;
-
-       return parent_rate / div;
-}
-
-static unsigned long s3c2412_getrate_usbsrc(struct clk *clk)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long div = __raw_readl(S3C2410_CLKDIVN);
-
-       return parent_rate / ((div & S3C2412_CLKDIVN_USB48DIV) ? 2 : 1);
-}
-
-static int s3c2412_setrate_usbsrc(struct clk *clk, unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
-
-       rate = s3c2412_roundrate_usbsrc(clk, rate);
-
-       if ((parent_rate / rate) == 2)
-               clkdivn |= S3C2412_CLKDIVN_USB48DIV;
-       else
-               clkdivn &= ~S3C2412_CLKDIVN_USB48DIV;
-
-       __raw_writel(clkdivn, S3C2410_CLKDIVN);
-       return 0;
-}
-
-static struct clk clk_usbsrc = {
-       .name           = "usbsrc",
-       .ops            = &(struct clk_ops) {
-               .get_rate       = s3c2412_getrate_usbsrc,
-               .set_rate       = s3c2412_setrate_usbsrc,
-               .round_rate     = s3c2412_roundrate_usbsrc,
-               .set_parent     = s3c2412_setparent_usbsrc,
-       },
-};
-
-static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent)
-{
-       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
-
-       if (parent == &clk_mdivclk)
-               clksrc &= ~S3C2412_CLKSRC_MSYSCLK_MPLL;
-       else if (parent == &clk_mpll)
-               clksrc |= S3C2412_CLKSRC_MSYSCLK_MPLL;
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       __raw_writel(clksrc, S3C2412_CLKSRC);
-       return 0;
-}
-
-static struct clk clk_msysclk = {
-       .name           = "msysclk",
-       .ops            = &(struct clk_ops) {
-               .set_parent     = s3c2412_setparent_msysclk,
-       },
-};
-
-static int s3c2412_setparent_armclk(struct clk *clk, struct clk *parent)
-{
-       unsigned long flags;
-       unsigned long clkdiv;
-       unsigned long dvs;
-
-       /* Note, we current equate fclk andf msysclk for S3C2412 */
-
-       if (parent == &clk_msysclk || parent == &clk_f)
-               dvs = 0;
-       else if (parent == &clk_h)
-               dvs = S3C2412_CLKDIVN_DVSEN;
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       /* update this under irq lockdown, clkdivn is not protected
-        * by the clock system. */
-
-       local_irq_save(flags);
-
-       clkdiv  = __raw_readl(S3C2410_CLKDIVN);
-       clkdiv &= ~S3C2412_CLKDIVN_DVSEN;
-       clkdiv |= dvs;
-       __raw_writel(clkdiv, S3C2410_CLKDIVN);
-
-       local_irq_restore(flags);
-
-       return 0;
-}
-
-static struct clk clk_armclk = {
-       .name           = "armclk",
-       .parent         = &clk_msysclk,
-       .ops            = &(struct clk_ops) {
-               .set_parent     = s3c2412_setparent_armclk,
-       },
-};
-
-/* these next clocks have an divider immediately after them,
- * so we can register them with their divider and leave out the
- * intermediate clock stage
-*/
-static unsigned long s3c2412_roundrate_clksrc(struct clk *clk,
-                                             unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       int div;
-
-       if (rate > parent_rate)
-               return parent_rate;
-
-       /* note, we remove the +/- 1 calculations as they cancel out */
-
-       div = (rate / parent_rate);
-
-       if (div < 1)
-               div = 1;
-       else if (div > 16)
-               div = 16;
-
-       return parent_rate / div;
-}
-
-static int s3c2412_setparent_uart(struct clk *clk, struct clk *parent)
-{
-       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
-
-       if (parent == &clk_erefclk)
-               clksrc &= ~S3C2412_CLKSRC_UARTCLK_MPLL;
-       else if (parent == &clk_mpll)
-               clksrc |= S3C2412_CLKSRC_UARTCLK_MPLL;
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       __raw_writel(clksrc, S3C2412_CLKSRC);
-       return 0;
-}
-
-static unsigned long s3c2412_getrate_uart(struct clk *clk)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long div = __raw_readl(S3C2410_CLKDIVN);
-
-       div &= S3C2412_CLKDIVN_UARTDIV_MASK;
-       div >>= S3C2412_CLKDIVN_UARTDIV_SHIFT;
-
-       return parent_rate / (div + 1);
-}
-
-static int s3c2412_setrate_uart(struct clk *clk, unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
-
-       rate = s3c2412_roundrate_clksrc(clk, rate);
-
-       clkdivn &= ~S3C2412_CLKDIVN_UARTDIV_MASK;
-       clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_UARTDIV_SHIFT;
-
-       __raw_writel(clkdivn, S3C2410_CLKDIVN);
-       return 0;
-}
-
-static struct clk clk_uart = {
-       .name           = "uartclk",
-       .ops            = &(struct clk_ops) {
-               .get_rate       = s3c2412_getrate_uart,
-               .set_rate       = s3c2412_setrate_uart,
-               .set_parent     = s3c2412_setparent_uart,
-               .round_rate     = s3c2412_roundrate_clksrc,
-       },
-};
-
-static int s3c2412_setparent_i2s(struct clk *clk, struct clk *parent)
-{
-       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
-
-       if (parent == &clk_erefclk)
-               clksrc &= ~S3C2412_CLKSRC_I2SCLK_MPLL;
-       else if (parent == &clk_mpll)
-               clksrc |= S3C2412_CLKSRC_I2SCLK_MPLL;
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       __raw_writel(clksrc, S3C2412_CLKSRC);
-       return 0;
-}
-
-static unsigned long s3c2412_getrate_i2s(struct clk *clk)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long div = __raw_readl(S3C2410_CLKDIVN);
-
-       div &= S3C2412_CLKDIVN_I2SDIV_MASK;
-       div >>= S3C2412_CLKDIVN_I2SDIV_SHIFT;
-
-       return parent_rate / (div + 1);
-}
-
-static int s3c2412_setrate_i2s(struct clk *clk, unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
-
-       rate = s3c2412_roundrate_clksrc(clk, rate);
-
-       clkdivn &= ~S3C2412_CLKDIVN_I2SDIV_MASK;
-       clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_I2SDIV_SHIFT;
-
-       __raw_writel(clkdivn, S3C2410_CLKDIVN);
-       return 0;
-}
-
-static struct clk clk_i2s = {
-       .name           = "i2sclk",
-       .ops            = &(struct clk_ops) {
-               .get_rate       = s3c2412_getrate_i2s,
-               .set_rate       = s3c2412_setrate_i2s,
-               .set_parent     = s3c2412_setparent_i2s,
-               .round_rate     = s3c2412_roundrate_clksrc,
-       },
-};
-
-static int s3c2412_setparent_cam(struct clk *clk, struct clk *parent)
-{
-       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
-
-       if (parent == &clk_usysclk)
-               clksrc &= ~S3C2412_CLKSRC_CAMCLK_HCLK;
-       else if (parent == &clk_h)
-               clksrc |= S3C2412_CLKSRC_CAMCLK_HCLK;
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       __raw_writel(clksrc, S3C2412_CLKSRC);
-       return 0;
-}
-static unsigned long s3c2412_getrate_cam(struct clk *clk)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long div = __raw_readl(S3C2410_CLKDIVN);
-
-       div &= S3C2412_CLKDIVN_CAMDIV_MASK;
-       div >>= S3C2412_CLKDIVN_CAMDIV_SHIFT;
-
-       return parent_rate / (div + 1);
-}
-
-static int s3c2412_setrate_cam(struct clk *clk, unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
-
-       rate = s3c2412_roundrate_clksrc(clk, rate);
-
-       clkdivn &= ~S3C2412_CLKDIVN_CAMDIV_MASK;
-       clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_CAMDIV_SHIFT;
-
-       __raw_writel(clkdivn, S3C2410_CLKDIVN);
-       return 0;
-}
-
-static struct clk clk_cam = {
-       .name           = "camif-upll", /* same as 2440 name */
-       .ops            = &(struct clk_ops) {
-               .get_rate       = s3c2412_getrate_cam,
-               .set_rate       = s3c2412_setrate_cam,
-               .set_parent     = s3c2412_setparent_cam,
-               .round_rate     = s3c2412_roundrate_clksrc,
-       },
-};
-
-/* standard clock definitions */
-
-static struct clk init_clocks_disable[] = {
-       {
-               .name           = "nand",
-               .parent         = &clk_h,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_NAND,
-       }, {
-               .name           = "sdi",
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_SDI,
-       }, {
-               .name           = "adc",
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_ADC,
-       }, {
-               .name           = "i2c",
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_IIC,
-       }, {
-               .name           = "iis",
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_IIS,
-       }, {
-               .name           = "spi",
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_SPI,
-       }
-};
-
-static struct clk init_clocks[] = {
-       {
-               .name           = "dma",
-               .parent         = &clk_h,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_DMA0,
-       }, {
-               .name           = "dma",
-               .parent         = &clk_h,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_DMA1,
-       }, {
-               .name           = "dma",
-               .parent         = &clk_h,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_DMA2,
-       }, {
-               .name           = "dma",
-               .parent         = &clk_h,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_DMA3,
-       }, {
-               .name           = "lcd",
-               .parent         = &clk_h,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_LCDC,
-       }, {
-               .name           = "gpio",
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_GPIO,
-       }, {
-               .name           = "usb-host",
-               .parent         = &clk_h,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_USBH,
-       }, {
-               .name           = "usb-device",
-               .parent         = &clk_h,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_USBD,
-       }, {
-               .name           = "timers",
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_PWMT,
-       }, {
-               .name           = "uart",
-               .devname        = "s3c2412-uart.0",
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_UART0,
-       }, {
-               .name           = "uart",
-               .devname        = "s3c2412-uart.1",
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_UART1,
-       }, {
-               .name           = "uart",
-               .devname        = "s3c2412-uart.2",
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_UART2,
-       }, {
-               .name           = "rtc",
-               .parent         = &clk_p,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_RTC,
-       }, {
-               .name           = "watchdog",
-               .parent         = &clk_p,
-               .ctrlbit        = 0,
-       }, {
-               .name           = "usb-bus-gadget",
-               .parent         = &clk_usb_bus,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_USB_DEV48,
-       }, {
-               .name           = "usb-bus-host",
-               .parent         = &clk_usb_bus,
-               .enable         = s3c2412_clkcon_enable,
-               .ctrlbit        = S3C2412_CLKCON_USB_HOST48,
-       }
-};
-
-/* clocks to add where we need to check their parentage */
-
-struct clk_init {
-       struct clk      *clk;
-       unsigned int     bit;
-       struct clk      *src_0;
-       struct clk      *src_1;
-};
-
-static struct clk_init clks_src[] __initdata = {
-       {
-               .clk    = &clk_usysclk,
-               .bit    = S3C2412_CLKSRC_USBCLK_HCLK,
-               .src_0  = &clk_urefclk,
-               .src_1  = &clk_upll,
-       }, {
-               .clk    = &clk_i2s,
-               .bit    = S3C2412_CLKSRC_I2SCLK_MPLL,
-               .src_0  = &clk_erefclk,
-               .src_1  = &clk_mpll,
-       }, {
-               .clk    = &clk_cam,
-               .bit    = S3C2412_CLKSRC_CAMCLK_HCLK,
-               .src_0  = &clk_usysclk,
-               .src_1  = &clk_h,
-       }, {
-               .clk    = &clk_msysclk,
-               .bit    = S3C2412_CLKSRC_MSYSCLK_MPLL,
-               .src_0  = &clk_mdivclk,
-               .src_1  = &clk_mpll,
-       }, {
-               .clk    = &clk_uart,
-               .bit    = S3C2412_CLKSRC_UARTCLK_MPLL,
-               .src_0  = &clk_erefclk,
-               .src_1  = &clk_mpll,
-       }, {
-               .clk    = &clk_usbsrc,
-               .bit    = S3C2412_CLKSRC_USBCLK_HCLK,
-               .src_0  = &clk_usysclk,
-               .src_1  = &clk_h,
-       /* here we assume  OM[4] select xtal */
-       }, {
-               .clk    = &clk_erefclk,
-               .bit    = S3C2412_CLKSRC_EREFCLK_EXTCLK,
-               .src_0  = &clk_xtal,
-               .src_1  = &clk_ext,
-       }, {
-               .clk    = &clk_urefclk,
-               .bit    = S3C2412_CLKSRC_UREFCLK_EXTCLK,
-               .src_0  = &clk_xtal,
-               .src_1  = &clk_ext,
-       },
-};
-
-/* s3c2412_clk_initparents
- *
- * Initialise the parents for the clocks that we get at start-time
-*/
-
-static void __init s3c2412_clk_initparents(void)
-{
-       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
-       struct clk_init *cip = clks_src;
-       struct clk *src;
-       int ptr;
-       int ret;
-
-       for (ptr = 0; ptr < ARRAY_SIZE(clks_src); ptr++, cip++) {
-               ret = s3c24xx_register_clock(cip->clk);
-               if (ret < 0) {
-                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
-                              cip->clk->name, ret);
-               }
-
-               src = (clksrc & cip->bit) ? cip->src_1 : cip->src_0;
-
-               printk(KERN_INFO "%s: parent %s\n", cip->clk->name, src->name);
-               clk_set_parent(cip->clk, src);
-       }
-}
-
-/* clocks to add straight away */
-
-static struct clk *clks[] __initdata = {
-       &clk_ext,
-       &clk_usb_bus,
-       &clk_mrefclk,
-       &clk_armclk,
-};
-
-static struct clk_lookup s3c2412_clk_lookup[] = {
-       CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
-       CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
-       CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_usysclk),
-};
-
-int __init s3c2412_baseclk_add(void)
-{
-       unsigned long clkcon  = __raw_readl(S3C2410_CLKCON);
-       unsigned int dvs;
-       struct clk *clkp;
-       int ret;
-       int ptr;
-
-       clk_upll.enable = s3c2412_upll_enable;
-       clk_usb_bus.parent = &clk_usbsrc;
-       clk_usb_bus.rate = 0x0;
-
-       clk_f.parent = &clk_msysclk;
-
-       s3c2412_clk_initparents();
-
-       for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
-               clkp = clks[ptr];
-
-               ret = s3c24xx_register_clock(clkp);
-               if (ret < 0) {
-                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
-                              clkp->name, ret);
-               }
-       }
-
-       /* set the dvs state according to what we got at boot time */
-
-       dvs = __raw_readl(S3C2410_CLKDIVN) & S3C2412_CLKDIVN_DVSEN;
-
-       if (dvs)
-               clk_armclk.parent = &clk_h;
-
-       printk(KERN_INFO "S3C2412: DVS is %s\n", dvs ? "on" : "off");
-
-       /* ensure usb bus clock is within correct rate of 48MHz */
-
-       if (clk_get_rate(&clk_usb_bus) != (48 * 1000 * 1000)) {
-               printk(KERN_INFO "Warning: USB bus clock not at 48MHz\n");
-
-               /* for the moment, let's use the UPLL, and see if we can
-                * get 48MHz */
-
-               clk_set_parent(&clk_usysclk, &clk_upll);
-               clk_set_parent(&clk_usbsrc, &clk_usysclk);
-               clk_set_rate(&clk_usbsrc, 48*1000*1000);
-       }
-
-       printk("S3C2412: upll %s, %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
-              (__raw_readl(S3C2410_UPLLCON) & S3C2412_PLLCON_OFF) ? "off":"on",
-              print_mhz(clk_get_rate(&clk_upll)),
-              print_mhz(clk_get_rate(&clk_usb_bus)));
-
-       /* register clocks from clock array */
-
-       clkp = init_clocks;
-       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
-               /* ensure that we note the clock state */
-
-               clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
-
-               ret = s3c24xx_register_clock(clkp);
-               if (ret < 0) {
-                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
-                              clkp->name, ret);
-               }
-       }
-
-       /* We must be careful disabling the clocks we are not intending to
-        * be using at boot time, as subsystems such as the LCD which do
-        * their own DMA requests to the bus can cause the system to lockup
-        * if they where in the middle of requesting bus access.
-        *
-        * Disabling the LCD clock if the LCD is active is very dangerous,
-        * and therefore the bootloader should be careful to not enable
-        * the LCD clock if it is not needed.
-       */
-
-       /* install (and disable) the clocks we do not need immediately */
-
-       clkp = init_clocks_disable;
-       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
-
-               ret = s3c24xx_register_clock(clkp);
-               if (ret < 0) {
-                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
-                              clkp->name, ret);
-               }
-
-               s3c2412_clkcon_enable(clkp, 0);
-       }
-
-       clkdev_add_table(s3c2412_clk_lookup, ARRAY_SIZE(s3c2412_clk_lookup));
-       s3c_pwmclk_init();
-       return 0;
-}
diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c
deleted file mode 100644 (file)
index 38472ac..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/* linux/arch/arm/mach-s3c2412/dma.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2412 DMA selection
- *
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/serial_core.h>
-#include <linux/io.h>
-
-#include <mach/dma.h>
-
-#include <plat/dma-s3c24xx.h>
-#include <plat/cpu.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <plat/regs-ac97.h>
-#include <plat/regs-dma.h>
-#include <mach/regs-mem.h>
-#include <mach/regs-lcd.h>
-#include <mach/regs-sdi.h>
-#include <plat/regs-iis.h>
-#include <plat/regs-spi.h>
-
-#define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID }
-
-static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
-       [DMACH_XD0] = {
-               .name           = "xdreq0",
-               .channels       = MAP(S3C2412_DMAREQSEL_XDREQ0),
-               .channels_rx    = MAP(S3C2412_DMAREQSEL_XDREQ0),
-       },
-       [DMACH_XD1] = {
-               .name           = "xdreq1",
-               .channels       = MAP(S3C2412_DMAREQSEL_XDREQ1),
-               .channels_rx    = MAP(S3C2412_DMAREQSEL_XDREQ1),
-       },
-       [DMACH_SDI] = {
-               .name           = "sdi",
-               .channels       = MAP(S3C2412_DMAREQSEL_SDI),
-               .channels_rx    = MAP(S3C2412_DMAREQSEL_SDI),
-       },
-       [DMACH_SPI0] = {
-               .name           = "spi0",
-               .channels       = MAP(S3C2412_DMAREQSEL_SPI0TX),
-               .channels_rx    = MAP(S3C2412_DMAREQSEL_SPI0RX),
-       },
-       [DMACH_SPI1] = {
-               .name           = "spi1",
-               .channels       = MAP(S3C2412_DMAREQSEL_SPI1TX),
-               .channels_rx    = MAP(S3C2412_DMAREQSEL_SPI1RX),
-       },
-       [DMACH_UART0] = {
-               .name           = "uart0",
-               .channels       = MAP(S3C2412_DMAREQSEL_UART0_0),
-               .channels_rx    = MAP(S3C2412_DMAREQSEL_UART0_0),
-       },
-       [DMACH_UART1] = {
-               .name           = "uart1",
-               .channels       = MAP(S3C2412_DMAREQSEL_UART1_0),
-               .channels_rx    = MAP(S3C2412_DMAREQSEL_UART1_0),
-       },
-       [DMACH_UART2] = {
-               .name           = "uart2",
-               .channels       = MAP(S3C2412_DMAREQSEL_UART2_0),
-               .channels_rx    = MAP(S3C2412_DMAREQSEL_UART2_0),
-       },
-       [DMACH_UART0_SRC2] = {
-               .name           = "uart0",
-               .channels       = MAP(S3C2412_DMAREQSEL_UART0_1),
-               .channels_rx    = MAP(S3C2412_DMAREQSEL_UART0_1),
-       },
-       [DMACH_UART1_SRC2] = {
-               .name           = "uart1",
-               .channels       = MAP(S3C2412_DMAREQSEL_UART1_1),
-               .channels_rx    = MAP(S3C2412_DMAREQSEL_UART1_1),
-       },
-       [DMACH_UART2_SRC2] = {
-               .name           = "uart2",
-               .channels       = MAP(S3C2412_DMAREQSEL_UART2_1),
-               .channels_rx    = MAP(S3C2412_DMAREQSEL_UART2_1),
-       },
-       [DMACH_TIMER] = {
-               .name           = "timer",
-               .channels       = MAP(S3C2412_DMAREQSEL_TIMER),
-               .channels_rx    = MAP(S3C2412_DMAREQSEL_TIMER),
-       },
-       [DMACH_I2S_IN] = {
-               .name           = "i2s-sdi",
-               .channels       = MAP(S3C2412_DMAREQSEL_I2SRX),
-               .channels_rx    = MAP(S3C2412_DMAREQSEL_I2SRX),
-       },
-       [DMACH_I2S_OUT] = {
-               .name           = "i2s-sdo",
-               .channels       = MAP(S3C2412_DMAREQSEL_I2STX),
-               .channels_rx    = MAP(S3C2412_DMAREQSEL_I2STX),
-       },
-       [DMACH_USB_EP1] = {
-               .name           = "usb-ep1",
-               .channels       = MAP(S3C2412_DMAREQSEL_USBEP1),
-               .channels_rx    = MAP(S3C2412_DMAREQSEL_USBEP1),
-       },
-       [DMACH_USB_EP2] = {
-               .name           = "usb-ep2",
-               .channels       = MAP(S3C2412_DMAREQSEL_USBEP2),
-               .channels_rx    = MAP(S3C2412_DMAREQSEL_USBEP2),
-       },
-       [DMACH_USB_EP3] = {
-               .name           = "usb-ep3",
-               .channels       = MAP(S3C2412_DMAREQSEL_USBEP3),
-               .channels_rx    = MAP(S3C2412_DMAREQSEL_USBEP3),
-       },
-       [DMACH_USB_EP4] = {
-               .name           = "usb-ep4",
-               .channels       = MAP(S3C2412_DMAREQSEL_USBEP4),
-               .channels_rx    = MAP(S3C2412_DMAREQSEL_USBEP4),
-       },
-};
-
-static void s3c2412_dma_direction(struct s3c2410_dma_chan *chan,
-                                 struct s3c24xx_dma_map *map,
-                                 enum dma_data_direction dir)
-{
-       unsigned long chsel;
-
-       if (dir == DMA_FROM_DEVICE)
-               chsel = map->channels_rx[0];
-       else
-               chsel = map->channels[0];
-
-       chsel &= ~DMA_CH_VALID;
-       chsel |= S3C2412_DMAREQSEL_HW;
-
-       writel(chsel, chan->regs + S3C2412_DMA_DMAREQSEL);
-}
-
-static void s3c2412_dma_select(struct s3c2410_dma_chan *chan,
-                              struct s3c24xx_dma_map *map)
-{
-       s3c2412_dma_direction(chan, map, chan->source);
-}
-
-static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = {
-       .select         = s3c2412_dma_select,
-       .direction      = s3c2412_dma_direction,
-       .dcon_mask      = 0,
-       .map            = s3c2412_dma_mappings,
-       .map_size       = ARRAY_SIZE(s3c2412_dma_mappings),
-};
-
-static int __init s3c2412_dma_add(struct device *dev,
-                                 struct subsys_interface *sif)
-{
-       s3c2410_dma_init();
-       return s3c24xx_dma_init_map(&s3c2412_dma_sel);
-}
-
-static struct subsys_interface s3c2412_dma_interface = {
-       .name           = "s3c2412_dma",
-       .subsys         = &s3c2412_subsys,
-       .add_dev        = s3c2412_dma_add,
-};
-
-static int __init s3c2412_dma_init(void)
-{
-       return subsys_interface_register(&s3c2412_dma_interface);
-}
-
-arch_initcall(s3c2412_dma_init);
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c
deleted file mode 100644 (file)
index e65619d..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/* linux/arch/arm/mach-s3c2412/irq.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <asm/mach/irq.h>
-
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-power.h>
-
-#include <plat/cpu.h>
-#include <plat/irq.h>
-#include <plat/pm.h>
-
-#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
-#define INTMSK_SUB(start, end) (INTMSK(start, end) << ((start - S3C2410_IRQSUB(0))))
-
-/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by
- * having them turn up in both the INT* and the EINT* registers. Whilst
- * both show the status, they both now need to be acked when the IRQs
- * go off.
-*/
-
-static void
-s3c2412_irq_mask(struct irq_data *data)
-{
-       unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
-       unsigned long mask;
-
-       mask = __raw_readl(S3C2410_INTMSK);
-       __raw_writel(mask | bitval, S3C2410_INTMSK);
-
-       mask = __raw_readl(S3C2412_EINTMASK);
-       __raw_writel(mask | bitval, S3C2412_EINTMASK);
-}
-
-static inline void
-s3c2412_irq_ack(struct irq_data *data)
-{
-       unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
-
-       __raw_writel(bitval, S3C2412_EINTPEND);
-       __raw_writel(bitval, S3C2410_SRCPND);
-       __raw_writel(bitval, S3C2410_INTPND);
-}
-
-static inline void
-s3c2412_irq_maskack(struct irq_data *data)
-{
-       unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
-       unsigned long mask;
-
-       mask = __raw_readl(S3C2410_INTMSK);
-       __raw_writel(mask|bitval, S3C2410_INTMSK);
-
-       mask = __raw_readl(S3C2412_EINTMASK);
-       __raw_writel(mask | bitval, S3C2412_EINTMASK);
-
-       __raw_writel(bitval, S3C2412_EINTPEND);
-       __raw_writel(bitval, S3C2410_SRCPND);
-       __raw_writel(bitval, S3C2410_INTPND);
-}
-
-static void
-s3c2412_irq_unmask(struct irq_data *data)
-{
-       unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
-       unsigned long mask;
-
-       mask = __raw_readl(S3C2412_EINTMASK);
-       __raw_writel(mask & ~bitval, S3C2412_EINTMASK);
-
-       mask = __raw_readl(S3C2410_INTMSK);
-       __raw_writel(mask & ~bitval, S3C2410_INTMSK);
-}
-
-static struct irq_chip s3c2412_irq_eint0t4 = {
-       .irq_ack        = s3c2412_irq_ack,
-       .irq_mask       = s3c2412_irq_mask,
-       .irq_unmask     = s3c2412_irq_unmask,
-       .irq_set_wake   = s3c_irq_wake,
-       .irq_set_type   = s3c_irqext_type,
-};
-
-#define INTBIT(x)      (1 << ((x) - S3C2410_IRQSUB(0)))
-
-/* CF and SDI sub interrupts */
-
-static void s3c2412_irq_demux_cfsdi(unsigned int irq, struct irq_desc *desc)
-{
-       unsigned int subsrc, submsk;
-
-       subsrc = __raw_readl(S3C2410_SUBSRCPND);
-       submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-       subsrc  &= ~submsk;
-
-       if (subsrc & INTBIT(IRQ_S3C2412_SDI))
-               generic_handle_irq(IRQ_S3C2412_SDI);
-
-       if (subsrc & INTBIT(IRQ_S3C2412_CF))
-               generic_handle_irq(IRQ_S3C2412_CF);
-}
-
-#define INTMSK_CFSDI   (1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0))
-#define SUBMSK_CFSDI   INTMSK_SUB(IRQ_S3C2412_SDI, IRQ_S3C2412_CF)
-
-static void s3c2412_irq_cfsdi_mask(struct irq_data *data)
-{
-       s3c_irqsub_mask(data->irq, INTMSK_CFSDI, SUBMSK_CFSDI);
-}
-
-static void s3c2412_irq_cfsdi_unmask(struct irq_data *data)
-{
-       s3c_irqsub_unmask(data->irq, INTMSK_CFSDI);
-}
-
-static void s3c2412_irq_cfsdi_ack(struct irq_data *data)
-{
-       s3c_irqsub_maskack(data->irq, INTMSK_CFSDI, SUBMSK_CFSDI);
-}
-
-static struct irq_chip s3c2412_irq_cfsdi = {
-       .name           = "s3c2412-cfsdi",
-       .irq_ack        = s3c2412_irq_cfsdi_ack,
-       .irq_mask       = s3c2412_irq_cfsdi_mask,
-       .irq_unmask     = s3c2412_irq_cfsdi_unmask,
-};
-
-static int s3c2412_irq_rtc_wake(struct irq_data *data, unsigned int state)
-{
-       unsigned long pwrcfg;
-
-       pwrcfg = __raw_readl(S3C2412_PWRCFG);
-       if (state)
-               pwrcfg &= ~S3C2412_PWRCFG_RTC_MASKIRQ;
-       else
-               pwrcfg |= S3C2412_PWRCFG_RTC_MASKIRQ;
-       __raw_writel(pwrcfg, S3C2412_PWRCFG);
-
-       return s3c_irq_chip.irq_set_wake(data, state);
-}
-
-static struct irq_chip s3c2412_irq_rtc_chip;
-
-static int s3c2412_irq_add(struct device *dev, struct subsys_interface *sif)
-{
-       unsigned int irqno;
-
-       for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
-               irq_set_chip_and_handler(irqno, &s3c2412_irq_eint0t4,
-                                        handle_edge_irq);
-               set_irq_flags(irqno, IRQF_VALID);
-       }
-
-       /* add demux support for CF/SDI */
-
-       irq_set_chained_handler(IRQ_S3C2412_CFSDI, s3c2412_irq_demux_cfsdi);
-
-       for (irqno = IRQ_S3C2412_SDI; irqno <= IRQ_S3C2412_CF; irqno++) {
-               irq_set_chip_and_handler(irqno, &s3c2412_irq_cfsdi,
-                                        handle_level_irq);
-               set_irq_flags(irqno, IRQF_VALID);
-       }
-
-       /* change RTC IRQ's set wake method */
-
-       s3c2412_irq_rtc_chip = s3c_irq_chip;
-       s3c2412_irq_rtc_chip.irq_set_wake = s3c2412_irq_rtc_wake;
-
-       irq_set_chip(IRQ_RTC, &s3c2412_irq_rtc_chip);
-
-       return 0;
-}
-
-static struct subsys_interface s3c2412_irq_interface = {
-       .name           = "s3c2412_irq",
-       .subsys         = &s3c2412_subsys,
-       .add_dev        = s3c2412_irq_add,
-};
-
-static int s3c2412_irq_init(void)
-{
-       return subsys_interface_register(&s3c2412_irq_interface);
-}
-
-arch_initcall(s3c2412_irq_init);
diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c
deleted file mode 100644 (file)
index ae73ba3..0000000
+++ /dev/null
@@ -1,666 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/mach-jive.c
- *
- * Copyright 2007 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/syscore_ops.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-
-#include <video/ili9320.h>
-
-#include <linux/spi/spi.h>
-#include <linux/spi/spi_gpio.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <plat/regs-serial.h>
-#include <plat/nand.h>
-#include <plat/iic.h>
-
-#include <mach/regs-power.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-mem.h>
-#include <mach/regs-lcd.h>
-#include <mach/fb.h>
-
-#include <asm/mach-types.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include <plat/s3c2412.h>
-#include <plat/gpio-cfg.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/udc.h>
-
-static struct map_desc jive_iodesc[] __initdata = {
-};
-
-#define UCON S3C2410_UCON_DEFAULT
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg jive_uartcfgs[] = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       }
-};
-
-/* Jive flash assignment
- *
- * 0x00000000-0x00028000 : uboot
- * 0x00028000-0x0002c000 : uboot env
- * 0x0002c000-0x00030000 : spare
- * 0x00030000-0x00200000 : zimage A
- * 0x00200000-0x01600000 : cramfs A
- * 0x01600000-0x017d0000 : zimage B
- * 0x017d0000-0x02bd0000 : cramfs B
- * 0x02bd0000-0x03fd0000 : yaffs
- */
-static struct mtd_partition __initdata jive_imageA_nand_part[] = {
-
-#ifdef CONFIG_MACH_JIVE_SHOW_BOOTLOADER
-       /* Don't allow access to the bootloader from linux */
-       {
-               .name           = "uboot",
-               .offset         = 0,
-               .size           = (160 * SZ_1K),
-               .mask_flags     = MTD_WRITEABLE, /* force read-only */
-       },
-
-       /* spare */
-        {
-                .name           = "spare",
-                .offset         = (176 * SZ_1K),
-                .size           = (16 * SZ_1K),
-        },
-#endif
-
-       /* booted images */
-        {
-               .name           = "kernel (ro)",
-               .offset         = (192 * SZ_1K),
-               .size           = (SZ_2M) - (192 * SZ_1K),
-               .mask_flags     = MTD_WRITEABLE, /* force read-only */
-        }, {
-                .name           = "root (ro)",
-                .offset         = (SZ_2M),
-                .size           = (20 * SZ_1M),
-               .mask_flags     = MTD_WRITEABLE, /* force read-only */
-        },
-
-       /* yaffs */
-       {
-               .name           = "yaffs",
-               .offset         = (44 * SZ_1M),
-               .size           = (20 * SZ_1M),
-       },
-
-       /* bootloader environment */
-       {
-                .name          = "env",
-               .offset         = (160 * SZ_1K),
-               .size           = (16 * SZ_1K),
-       },
-
-       /* upgrade images */
-        {
-               .name           = "zimage",
-               .offset         = (22 * SZ_1M),
-               .size           = (2 * SZ_1M) - (192 * SZ_1K),
-        }, {
-               .name           = "cramfs",
-               .offset         = (24 * SZ_1M) - (192*SZ_1K),
-               .size           = (20 * SZ_1M),
-        },
-};
-
-static struct mtd_partition __initdata jive_imageB_nand_part[] = {
-
-#ifdef CONFIG_MACH_JIVE_SHOW_BOOTLOADER
-       /* Don't allow access to the bootloader from linux */
-       {
-               .name           = "uboot",
-               .offset         = 0,
-               .size           = (160 * SZ_1K),
-               .mask_flags     = MTD_WRITEABLE, /* force read-only */
-       },
-
-       /* spare */
-        {
-                .name           = "spare",
-                .offset         = (176 * SZ_1K),
-                .size           = (16 * SZ_1K),
-        },
-#endif
-
-       /* booted images */
-        {
-               .name           = "kernel (ro)",
-               .offset         = (22 * SZ_1M),
-               .size           = (2 * SZ_1M) - (192 * SZ_1K),
-               .mask_flags     = MTD_WRITEABLE, /* force read-only */
-        },
-       {
-               .name           = "root (ro)",
-               .offset         = (24 * SZ_1M) - (192 * SZ_1K),
-                .size          = (20 * SZ_1M),
-               .mask_flags     = MTD_WRITEABLE, /* force read-only */
-       },
-
-       /* yaffs */
-       {
-               .name           = "yaffs",
-               .offset         = (44 * SZ_1M),
-               .size           = (20 * SZ_1M),
-        },
-
-       /* bootloader environment */
-       {
-               .name           = "env",
-               .offset         = (160 * SZ_1K),
-               .size           = (16 * SZ_1K),
-       },
-
-       /* upgrade images */
-       {
-               .name           = "zimage",
-               .offset         = (192 * SZ_1K),
-               .size           = (2 * SZ_1M) - (192 * SZ_1K),
-        }, {
-               .name           = "cramfs",
-               .offset         = (2 * SZ_1M),
-               .size           = (20 * SZ_1M),
-        },
-};
-
-static struct s3c2410_nand_set __initdata jive_nand_sets[] = {
-       [0] = {
-               .name           = "flash",
-               .nr_chips       = 1,
-               .nr_partitions  = ARRAY_SIZE(jive_imageA_nand_part),
-               .partitions     = jive_imageA_nand_part,
-       },
-};
-
-static struct s3c2410_platform_nand __initdata jive_nand_info = {
-       /* set taken from osiris nand timings, possibly still conservative */
-       .tacls          = 30,
-       .twrph0         = 55,
-       .twrph1         = 40,
-       .sets           = jive_nand_sets,
-       .nr_sets        = ARRAY_SIZE(jive_nand_sets),
-};
-
-static int __init jive_mtdset(char *options)
-{
-       struct s3c2410_nand_set *nand = &jive_nand_sets[0];
-       unsigned long set;
-
-       if (options == NULL || options[0] == '\0')
-               return 0;
-
-       if (strict_strtoul(options, 10, &set)) {
-               printk(KERN_ERR "failed to parse mtdset=%s\n", options);
-               return 0;
-       }
-
-       switch (set) {
-       case 1:
-               nand->nr_partitions = ARRAY_SIZE(jive_imageB_nand_part);
-               nand->partitions = jive_imageB_nand_part;
-       case 0:
-               /* this is already setup in the nand info */
-               break;
-       default:
-               printk(KERN_ERR "Unknown mtd set %ld specified,"
-                      "using default.", set);
-       }
-
-       return 0;
-}
-
-/* parse the mtdset= option given to the kernel command line */
-__setup("mtdset=", jive_mtdset);
-
-/* LCD timing and setup */
-
-#define LCD_XRES        (240)
-#define LCD_YRES        (320)
-#define LCD_LEFT_MARGIN  (12)
-#define LCD_RIGHT_MARGIN (12)
-#define LCD_LOWER_MARGIN (12)
-#define LCD_UPPER_MARGIN (12)
-#define LCD_VSYNC       (2)
-#define LCD_HSYNC       (2)
-
-#define LCD_REFRESH     (60)
-
-#define LCD_HTOT (LCD_HSYNC + LCD_LEFT_MARGIN + LCD_XRES + LCD_RIGHT_MARGIN)
-#define LCD_VTOT (LCD_VSYNC + LCD_LOWER_MARGIN + LCD_YRES + LCD_UPPER_MARGIN)
-
-static struct s3c2410fb_display jive_vgg2432a4_display[] = {
-       [0] = {
-               .width          = LCD_XRES,
-               .height         = LCD_YRES,
-               .xres           = LCD_XRES,
-               .yres           = LCD_YRES,
-               .left_margin    = LCD_LEFT_MARGIN,
-               .right_margin   = LCD_RIGHT_MARGIN,
-               .upper_margin   = LCD_UPPER_MARGIN,
-               .lower_margin   = LCD_LOWER_MARGIN,
-               .hsync_len      = LCD_HSYNC,
-               .vsync_len      = LCD_VSYNC,
-
-               .pixclock       = (1000000000000LL /
-                                  (LCD_REFRESH * LCD_HTOT * LCD_VTOT)),
-
-               .bpp            = 16,
-               .type           = (S3C2410_LCDCON1_TFT16BPP |
-                                  S3C2410_LCDCON1_TFT),
-
-               .lcdcon5        = (S3C2410_LCDCON5_FRM565 |
-                                  S3C2410_LCDCON5_INVVLINE |
-                                  S3C2410_LCDCON5_INVVFRAME |
-                                  S3C2410_LCDCON5_INVVDEN |
-                                  S3C2410_LCDCON5_PWREN),
-       },
-};
-
-/* todo - put into gpio header */
-
-#define S3C2410_GPCCON_MASK(x) (3 << ((x) * 2))
-#define S3C2410_GPDCON_MASK(x) (3 << ((x) * 2))
-
-static struct s3c2410fb_mach_info jive_lcd_config = {
-       .displays        = jive_vgg2432a4_display,
-       .num_displays    = ARRAY_SIZE(jive_vgg2432a4_display),
-       .default_display = 0,
-
-       /* Enable VD[2..7], VD[10..15], VD[18..23] and VCLK, syncs, VDEN
-        * and disable the pull down resistors on pins we are using for LCD
-        * data. */
-
-       .gpcup          = (0xf << 1) | (0x3f << 10),
-
-       .gpccon         = (S3C2410_GPC1_VCLK   | S3C2410_GPC2_VLINE |
-                          S3C2410_GPC3_VFRAME | S3C2410_GPC4_VM |
-                          S3C2410_GPC10_VD2   | S3C2410_GPC11_VD3 |
-                          S3C2410_GPC12_VD4   | S3C2410_GPC13_VD5 |
-                          S3C2410_GPC14_VD6   | S3C2410_GPC15_VD7),
-
-       .gpccon_mask    = (S3C2410_GPCCON_MASK(1)  | S3C2410_GPCCON_MASK(2)  |
-                          S3C2410_GPCCON_MASK(3)  | S3C2410_GPCCON_MASK(4)  |
-                          S3C2410_GPCCON_MASK(10) | S3C2410_GPCCON_MASK(11) |
-                          S3C2410_GPCCON_MASK(12) | S3C2410_GPCCON_MASK(13) |
-                          S3C2410_GPCCON_MASK(14) | S3C2410_GPCCON_MASK(15)),
-
-       .gpdup          = (0x3f << 2) | (0x3f << 10),
-
-       .gpdcon         = (S3C2410_GPD2_VD10  | S3C2410_GPD3_VD11 |
-                          S3C2410_GPD4_VD12  | S3C2410_GPD5_VD13 |
-                          S3C2410_GPD6_VD14  | S3C2410_GPD7_VD15 |
-                          S3C2410_GPD10_VD18 | S3C2410_GPD11_VD19 |
-                          S3C2410_GPD12_VD20 | S3C2410_GPD13_VD21 |
-                          S3C2410_GPD14_VD22 | S3C2410_GPD15_VD23),
-
-       .gpdcon_mask    = (S3C2410_GPDCON_MASK(2)  | S3C2410_GPDCON_MASK(3) |
-                          S3C2410_GPDCON_MASK(4)  | S3C2410_GPDCON_MASK(5) |
-                          S3C2410_GPDCON_MASK(6)  | S3C2410_GPDCON_MASK(7) |
-                          S3C2410_GPDCON_MASK(10) | S3C2410_GPDCON_MASK(11)|
-                          S3C2410_GPDCON_MASK(12) | S3C2410_GPDCON_MASK(13)|
-                          S3C2410_GPDCON_MASK(14) | S3C2410_GPDCON_MASK(15)),
-};
-
-/* ILI9320 support. */
-
-static void jive_lcm_reset(unsigned int set)
-{
-       printk(KERN_DEBUG "%s(%d)\n", __func__, set);
-
-       gpio_set_value(S3C2410_GPG(13), set);
-}
-
-#undef LCD_UPPER_MARGIN
-#define LCD_UPPER_MARGIN 2
-
-static struct ili9320_platdata jive_lcm_config = {
-       .hsize          = LCD_XRES,
-       .vsize          = LCD_YRES,
-
-       .reset          = jive_lcm_reset,
-       .suspend        = ILI9320_SUSPEND_DEEP,
-
-       .entry_mode     = ILI9320_ENTRYMODE_ID(3) | ILI9320_ENTRYMODE_BGR,
-       .display2       = (ILI9320_DISPLAY2_FP(LCD_UPPER_MARGIN) |
-                          ILI9320_DISPLAY2_BP(LCD_LOWER_MARGIN)),
-       .display3       = 0x0,
-       .display4       = 0x0,
-       .rgb_if1        = (ILI9320_RGBIF1_RIM_RGB18 |
-                          ILI9320_RGBIF1_RM | ILI9320_RGBIF1_CLK_RGBIF),
-       .rgb_if2        = ILI9320_RGBIF2_DPL,
-       .interface2     = 0x0,
-       .interface3     = 0x3,
-       .interface4     = (ILI9320_INTERFACE4_RTNE(16) |
-                          ILI9320_INTERFACE4_DIVE(1)),
-       .interface5     = 0x0,
-       .interface6     = 0x0,
-};
-
-/* LCD SPI support */
-
-static struct spi_gpio_platform_data jive_lcd_spi = {
-       .sck            = S3C2410_GPG(8),
-       .mosi           = S3C2410_GPB(8),
-       .miso           = SPI_GPIO_NO_MISO,
-};
-
-static struct platform_device jive_device_lcdspi = {
-       .name           = "spi-gpio",
-       .id             = 1,
-       .dev.platform_data = &jive_lcd_spi,
-};
-
-
-/* WM8750 audio code SPI definition */
-
-static struct spi_gpio_platform_data jive_wm8750_spi = {
-       .sck            = S3C2410_GPB(4),
-       .mosi           = S3C2410_GPB(9),
-       .miso           = SPI_GPIO_NO_MISO,
-};
-
-static struct platform_device jive_device_wm8750 = {
-       .name           = "spi-gpio",
-       .id             = 2,
-       .dev.platform_data = &jive_wm8750_spi,
-};
-
-/* JIVE SPI devices. */
-
-static struct spi_board_info __initdata jive_spi_devs[] = {
-       [0] = {
-               .modalias       = "VGG2432A4",
-               .bus_num        = 1,
-               .chip_select    = 0,
-               .mode           = SPI_MODE_3,   /* CPOL=1, CPHA=1 */
-               .max_speed_hz   = 100000,
-               .platform_data  = &jive_lcm_config,
-               .controller_data = (void *)S3C2410_GPB(7),
-       }, {
-               .modalias       = "WM8750",
-               .bus_num        = 2,
-               .chip_select    = 0,
-               .mode           = SPI_MODE_0,   /* CPOL=0, CPHA=0 */
-               .max_speed_hz   = 100000,
-               .controller_data = (void *)S3C2410_GPH(10),
-       },
-};
-
-/* I2C bus and device configuration. */
-
-static struct s3c2410_platform_i2c jive_i2c_cfg __initdata = {
-       .frequency      = 80 * 1000,
-       .flags          = S3C_IICFLG_FILTER,
-       .sda_delay      = 2,
-};
-
-static struct i2c_board_info jive_i2c_devs[] __initdata = {
-       [0] = {
-               I2C_BOARD_INFO("lis302dl", 0x1c),
-               .irq    = IRQ_EINT14,
-       },
-};
-
-/* The platform devices being used. */
-
-static struct platform_device *jive_devices[] __initdata = {
-       &s3c_device_ohci,
-       &s3c_device_rtc,
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_lcd,
-       &jive_device_lcdspi,
-       &jive_device_wm8750,
-       &s3c_device_nand,
-       &s3c_device_usbgadget,
-};
-
-static struct s3c2410_udc_mach_info jive_udc_cfg __initdata = {
-       .vbus_pin       = S3C2410_GPG(1),               /* detect is on GPG1 */
-};
-
-/* Jive power management device */
-
-#ifdef CONFIG_PM
-static int jive_pm_suspend(void)
-{
-       /* Write the magic value u-boot uses to check for resume into
-        * the INFORM0 register, and ensure INFORM1 is set to the
-        * correct address to resume from. */
-
-       __raw_writel(0x2BED, S3C2412_INFORM0);
-       __raw_writel(virt_to_phys(s3c_cpu_resume), S3C2412_INFORM1);
-
-       return 0;
-}
-
-static void jive_pm_resume(void)
-{
-       __raw_writel(0x0, S3C2412_INFORM0);
-}
-
-#else
-#define jive_pm_suspend NULL
-#define jive_pm_resume NULL
-#endif
-
-static struct syscore_ops jive_pm_syscore_ops = {
-       .suspend        = jive_pm_suspend,
-       .resume         = jive_pm_resume,
-};
-
-static void __init jive_map_io(void)
-{
-       s3c24xx_init_io(jive_iodesc, ARRAY_SIZE(jive_iodesc));
-       s3c24xx_init_clocks(12000000);
-       s3c24xx_init_uarts(jive_uartcfgs, ARRAY_SIZE(jive_uartcfgs));
-}
-
-static void jive_power_off(void)
-{
-       printk(KERN_INFO "powering system down...\n");
-
-       s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
-       s3c_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT);
-}
-
-static void __init jive_machine_init(void)
-{
-       /* register system core operations for managing low level suspend */
-
-       register_syscore_ops(&jive_pm_syscore_ops);
-
-       /* write our sleep configurations for the IO. Pull down all unused
-        * IO, ensure that we have turned off all peripherals we do not
-        * need, and configure the ones we do need. */
-
-       /* Port B sleep */
-
-       __raw_writel(S3C2412_SLPCON_IN(0)   |
-                    S3C2412_SLPCON_PULL(1) |
-                    S3C2412_SLPCON_HIGH(2) |
-                    S3C2412_SLPCON_PULL(3) |
-                    S3C2412_SLPCON_PULL(4) |
-                    S3C2412_SLPCON_PULL(5) |
-                    S3C2412_SLPCON_PULL(6) |
-                    S3C2412_SLPCON_HIGH(7) |
-                    S3C2412_SLPCON_PULL(8) |
-                    S3C2412_SLPCON_PULL(9) |
-                    S3C2412_SLPCON_PULL(10), S3C2412_GPBSLPCON);
-
-       /* Port C sleep */
-
-       __raw_writel(S3C2412_SLPCON_PULL(0) |
-                    S3C2412_SLPCON_PULL(1) |
-                    S3C2412_SLPCON_PULL(2) |
-                    S3C2412_SLPCON_PULL(3) |
-                    S3C2412_SLPCON_PULL(4) |
-                    S3C2412_SLPCON_PULL(5) |
-                    S3C2412_SLPCON_LOW(6)  |
-                    S3C2412_SLPCON_PULL(6) |
-                    S3C2412_SLPCON_PULL(7) |
-                    S3C2412_SLPCON_PULL(8) |
-                    S3C2412_SLPCON_PULL(9) |
-                    S3C2412_SLPCON_PULL(10) |
-                    S3C2412_SLPCON_PULL(11) |
-                    S3C2412_SLPCON_PULL(12) |
-                    S3C2412_SLPCON_PULL(13) |
-                    S3C2412_SLPCON_PULL(14) |
-                    S3C2412_SLPCON_PULL(15), S3C2412_GPCSLPCON);
-
-       /* Port D sleep */
-
-       __raw_writel(S3C2412_SLPCON_ALL_PULL, S3C2412_GPDSLPCON);
-
-       /* Port F sleep */
-
-       __raw_writel(S3C2412_SLPCON_LOW(0)  |
-                    S3C2412_SLPCON_LOW(1)  |
-                    S3C2412_SLPCON_LOW(2)  |
-                    S3C2412_SLPCON_EINT(3) |
-                    S3C2412_SLPCON_EINT(4) |
-                    S3C2412_SLPCON_EINT(5) |
-                    S3C2412_SLPCON_EINT(6) |
-                    S3C2412_SLPCON_EINT(7), S3C2412_GPFSLPCON);
-
-       /* Port G sleep */
-
-       __raw_writel(S3C2412_SLPCON_IN(0)    |
-                    S3C2412_SLPCON_IN(1)    |
-                    S3C2412_SLPCON_IN(2)    |
-                    S3C2412_SLPCON_IN(3)    |
-                    S3C2412_SLPCON_IN(4)    |
-                    S3C2412_SLPCON_IN(5)    |
-                    S3C2412_SLPCON_IN(6)    |
-                    S3C2412_SLPCON_IN(7)    |
-                    S3C2412_SLPCON_PULL(8)  |
-                    S3C2412_SLPCON_PULL(9)  |
-                    S3C2412_SLPCON_IN(10)   |
-                    S3C2412_SLPCON_PULL(11) |
-                    S3C2412_SLPCON_PULL(12) |
-                    S3C2412_SLPCON_PULL(13) |
-                    S3C2412_SLPCON_IN(14)   |
-                    S3C2412_SLPCON_PULL(15), S3C2412_GPGSLPCON);
-
-       /* Port H sleep */
-
-       __raw_writel(S3C2412_SLPCON_PULL(0) |
-                    S3C2412_SLPCON_PULL(1) |
-                    S3C2412_SLPCON_PULL(2) |
-                    S3C2412_SLPCON_PULL(3) |
-                    S3C2412_SLPCON_PULL(4) |
-                    S3C2412_SLPCON_PULL(5) |
-                    S3C2412_SLPCON_PULL(6) |
-                    S3C2412_SLPCON_IN(7)   |
-                    S3C2412_SLPCON_IN(8)   |
-                    S3C2412_SLPCON_PULL(9) |
-                    S3C2412_SLPCON_IN(10), S3C2412_GPHSLPCON);
-
-       /* initialise the power management now we've setup everything. */
-
-       s3c_pm_init();
-
-       /** TODO - check that this is after the cmdline option! */
-       s3c_nand_set_platdata(&jive_nand_info);
-
-       /* initialise the spi */
-
-       gpio_request(S3C2410_GPG(13), "lcm reset");
-       gpio_direction_output(S3C2410_GPG(13), 0);
-
-       gpio_request(S3C2410_GPB(7), "jive spi");
-       gpio_direction_output(S3C2410_GPB(7), 1);
-
-       s3c2410_gpio_setpin(S3C2410_GPB(6), 0);
-       s3c_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT);
-
-       s3c2410_gpio_setpin(S3C2410_GPG(8), 1);
-       s3c_gpio_cfgpin(S3C2410_GPG(8), S3C2410_GPIO_OUTPUT);
-
-       /* initialise the WM8750 spi */
-
-       gpio_request(S3C2410_GPH(10), "jive wm8750 spi");
-       gpio_direction_output(S3C2410_GPH(10), 1);
-
-       /* Turn off suspend on both USB ports, and switch the
-        * selectable USB port to USB device mode. */
-
-       s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
-                             S3C2410_MISCCR_USBSUSPND0 |
-                             S3C2410_MISCCR_USBSUSPND1, 0x0);
-
-       s3c24xx_udc_set_platdata(&jive_udc_cfg);
-       s3c24xx_fb_set_platdata(&jive_lcd_config);
-
-       spi_register_board_info(jive_spi_devs, ARRAY_SIZE(jive_spi_devs));
-
-       s3c_i2c0_set_platdata(&jive_i2c_cfg);
-       i2c_register_board_info(0, jive_i2c_devs, ARRAY_SIZE(jive_i2c_devs));
-
-       pm_power_off = jive_power_off;
-
-       platform_add_devices(jive_devices, ARRAY_SIZE(jive_devices));
-}
-
-MACHINE_START(JIVE, "JIVE")
-       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
-       .atag_offset    = 0x100,
-
-       .init_irq       = s3c24xx_init_irq,
-       .map_io         = jive_map_io,
-       .init_machine   = jive_machine_init,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c2412_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c
deleted file mode 100644 (file)
index b11451b..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/* linux/arch/arm/mach-s3c2412/mach-smdk2413.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Thanks to Dimity Andric (TomTom) and Steven Ryu (Samsung) for the
- * loans of SMDK2413 to work with.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/hardware/iomd.h>
-#include <asm/setup.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-//#include <asm/debug-ll.h>
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-lcd.h>
-
-#include <mach/idle.h>
-#include <plat/udc.h>
-#include <plat/iic.h>
-#include <mach/fb.h>
-
-#include <plat/s3c2410.h>
-#include <plat/s3c2412.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#include <plat/common-smdk.h>
-
-static struct map_desc smdk2413_iodesc[] __initdata = {
-};
-
-static struct s3c2410_uartcfg smdk2413_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       },
-       /* IR port */
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x43,
-               .ufcon       = 0x51,
-       }
-};
-
-
-static struct s3c2410_udc_mach_info smdk2413_udc_cfg __initdata = {
-       .pullup_pin = S3C2410_GPF(2),
-};
-
-
-static struct platform_device *smdk2413_devices[] __initdata = {
-       &s3c_device_ohci,
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_iis,
-       &s3c_device_usbgadget,
-};
-
-static void __init smdk2413_fixup(struct tag *tags, char **cmdline,
-                                 struct meminfo *mi)
-{
-       if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
-               mi->nr_banks=1;
-               mi->bank[0].start = 0x30000000;
-               mi->bank[0].size = SZ_64M;
-       }
-}
-
-static void __init smdk2413_map_io(void)
-{
-       s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc));
-       s3c24xx_init_clocks(12000000);
-       s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs));
-}
-
-static void __init smdk2413_machine_init(void)
-{      /* Turn off suspend on both USB ports, and switch the
-        * selectable USB port to USB device mode. */
-
-       s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
-                             S3C2410_MISCCR_USBSUSPND0 |
-                             S3C2410_MISCCR_USBSUSPND1, 0x0);
-
-
-       s3c24xx_udc_set_platdata(&smdk2413_udc_cfg);
-       s3c_i2c0_set_platdata(NULL);
-
-       platform_add_devices(smdk2413_devices, ARRAY_SIZE(smdk2413_devices));
-       smdk_machine_init();
-}
-
-MACHINE_START(S3C2413, "S3C2413")
-       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
-       .atag_offset    = 0x100,
-
-       .fixup          = smdk2413_fixup,
-       .init_irq       = s3c24xx_init_irq,
-       .map_io         = smdk2413_map_io,
-       .init_machine   = smdk2413_machine_init,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c2412_restart,
-MACHINE_END
-
-MACHINE_START(SMDK2412, "SMDK2412")
-       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
-       .atag_offset    = 0x100,
-
-       .fixup          = smdk2413_fixup,
-       .init_irq       = s3c24xx_init_irq,
-       .map_io         = smdk2413_map_io,
-       .init_machine   = smdk2413_machine_init,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c2412_restart,
-MACHINE_END
-
-MACHINE_START(SMDK2413, "SMDK2413")
-       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
-       .atag_offset    = 0x100,
-
-       .fixup          = smdk2413_fixup,
-       .init_irq       = s3c24xx_init_irq,
-       .map_io         = smdk2413_map_io,
-       .init_machine   = smdk2413_machine_init,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c2412_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2412/mach-vstms.c b/arch/arm/mach-s3c2412/mach-vstms.c
deleted file mode 100644 (file)
index 94bfaa1..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/* linux/arch/arm/mach-s3c2412/mach-vstms.c
- *
- * (C) 2006 Thomas Gleixner <tglx@linutronix.de>
- *
- * Derived from mach-smdk2413.c - (C) 2006 Simtec Electronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/setup.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-lcd.h>
-
-#include <mach/idle.h>
-#include <mach/fb.h>
-
-#include <plat/iic.h>
-#include <plat/nand.h>
-
-#include <plat/s3c2410.h>
-#include <plat/s3c2412.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-
-static struct map_desc vstms_iodesc[] __initdata = {
-};
-
-static struct s3c2410_uartcfg vstms_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       },
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       }
-};
-
-static struct mtd_partition __initdata vstms_nand_part[] = {
-       [0] = {
-               .name   = "Boot Agent",
-               .size   = 0x7C000,
-               .offset = 0,
-       },
-       [1] = {
-               .name   = "UBoot Config",
-               .offset = 0x7C000,
-               .size   = 0x4000,
-       },
-       [2] = {
-               .name   = "Kernel",
-               .offset = 0x80000,
-               .size   = 0x200000,
-       },
-       [3] = {
-               .name   = "RFS",
-               .offset = 0x280000,
-               .size   = 0x3d80000,
-       },
-};
-
-static struct s3c2410_nand_set __initdata vstms_nand_sets[] = {
-       [0] = {
-               .name           = "NAND",
-               .nr_chips       = 1,
-               .nr_partitions  = ARRAY_SIZE(vstms_nand_part),
-               .partitions     = vstms_nand_part,
-       },
-};
-
-/* choose a set of timings which should suit most 512Mbit
- * chips and beyond.
-*/
-
-static struct s3c2410_platform_nand __initdata vstms_nand_info = {
-       .tacls          = 20,
-       .twrph0         = 60,
-       .twrph1         = 20,
-       .nr_sets        = ARRAY_SIZE(vstms_nand_sets),
-       .sets           = vstms_nand_sets,
-};
-
-static struct platform_device *vstms_devices[] __initdata = {
-       &s3c_device_ohci,
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_iis,
-       &s3c_device_rtc,
-       &s3c_device_nand,
-};
-
-static void __init vstms_fixup(struct tag *tags, char **cmdline,
-                              struct meminfo *mi)
-{
-       if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
-               mi->nr_banks=1;
-               mi->bank[0].start = 0x30000000;
-               mi->bank[0].size = SZ_64M;
-       }
-}
-
-static void __init vstms_map_io(void)
-{
-       s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc));
-       s3c24xx_init_clocks(12000000);
-       s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs));
-}
-
-static void __init vstms_init(void)
-{
-       s3c_i2c0_set_platdata(NULL);
-       s3c_nand_set_platdata(&vstms_nand_info);
-
-       platform_add_devices(vstms_devices, ARRAY_SIZE(vstms_devices));
-}
-
-MACHINE_START(VSTMS, "VSTMS")
-       .atag_offset    = 0x100,
-
-       .fixup          = vstms_fixup,
-       .init_irq       = s3c24xx_init_irq,
-       .init_machine   = vstms_init,
-       .map_io         = vstms_map_io,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c2412_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2412/pm.c b/arch/arm/mach-s3c2412/pm.c
deleted file mode 100644 (file)
index d045885..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/* linux/arch/arm/mach-s3c2412/pm.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * http://armlinux.simtec.co.uk/.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/syscore_ops.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/cacheflush.h>
-#include <asm/irq.h>
-
-#include <mach/regs-power.h>
-#include <mach/regs-gpioj.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-dsc.h>
-
-#include <plat/cpu.h>
-#include <plat/pm.h>
-
-#include <plat/s3c2412.h>
-
-extern void s3c2412_sleep_enter(void);
-
-static int s3c2412_cpu_suspend(unsigned long arg)
-{
-       unsigned long tmp;
-
-       /* set our standby method to sleep */
-
-       tmp = __raw_readl(S3C2412_PWRCFG);
-       tmp |= S3C2412_PWRCFG_STANDBYWFI_SLEEP;
-       __raw_writel(tmp, S3C2412_PWRCFG);
-
-       s3c2412_sleep_enter();
-
-       panic("sleep resumed to originator?");
-}
-
-static void s3c2412_pm_prepare(void)
-{
-}
-
-static int s3c2412_pm_add(struct device *dev, struct subsys_interface *sif)
-{
-       pm_cpu_prep = s3c2412_pm_prepare;
-       pm_cpu_sleep = s3c2412_cpu_suspend;
-
-       return 0;
-}
-
-static struct sleep_save s3c2412_sleep[] = {
-       SAVE_ITEM(S3C2412_DSC0),
-       SAVE_ITEM(S3C2412_DSC1),
-       SAVE_ITEM(S3C2413_GPJDAT),
-       SAVE_ITEM(S3C2413_GPJCON),
-       SAVE_ITEM(S3C2413_GPJUP),
-
-       /* save the PWRCFG to get back to original sleep method */
-
-       SAVE_ITEM(S3C2412_PWRCFG),
-
-       /* save the sleep configuration anyway, just in case these
-        * get damaged during wakeup */
-
-       SAVE_ITEM(S3C2412_GPBSLPCON),
-       SAVE_ITEM(S3C2412_GPCSLPCON),
-       SAVE_ITEM(S3C2412_GPDSLPCON),
-       SAVE_ITEM(S3C2412_GPFSLPCON),
-       SAVE_ITEM(S3C2412_GPGSLPCON),
-       SAVE_ITEM(S3C2412_GPHSLPCON),
-       SAVE_ITEM(S3C2413_GPJSLPCON),
-};
-
-static struct subsys_interface s3c2412_pm_interface = {
-       .name           = "s3c2412_pm",
-       .subsys         = &s3c2412_subsys,
-       .add_dev        = s3c2412_pm_add,
-};
-
-static __init int s3c2412_pm_init(void)
-{
-       return subsys_interface_register(&s3c2412_pm_interface);
-}
-
-arch_initcall(s3c2412_pm_init);
-
-static int s3c2412_pm_suspend(void)
-{
-       s3c_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
-       return 0;
-}
-
-static void s3c2412_pm_resume(void)
-{
-       unsigned long tmp;
-
-       tmp = __raw_readl(S3C2412_PWRCFG);
-       tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
-       tmp |=  S3C2412_PWRCFG_STANDBYWFI_IDLE;
-       __raw_writel(tmp, S3C2412_PWRCFG);
-
-       s3c_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
-}
-
-struct syscore_ops s3c2412_pm_syscore_ops = {
-       .suspend        = s3c2412_pm_suspend,
-       .resume         = s3c2412_pm_resume,
-};
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
deleted file mode 100644 (file)
index c6eac98..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-/* linux/arch/arm/mach-s3c2412/s3c2412.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * http://armlinux.simtec.co.uk/.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/syscore_ops.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/proc-fns.h>
-#include <asm/irq.h>
-
-#include <plat/cpu-freq.h>
-
-#include <mach/regs-clock.h>
-#include <plat/regs-serial.h>
-#include <mach/regs-power.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-gpioj.h>
-#include <mach/regs-dsc.h>
-#include <plat/regs-spi.h>
-#include <mach/regs-s3c2412.h>
-
-#include <plat/s3c2412.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/clock.h>
-#include <plat/pm.h>
-#include <plat/pll.h>
-#include <plat/nand-core.h>
-
-#ifndef CONFIG_CPU_S3C2412_ONLY
-void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
-
-static inline void s3c2412_init_gpio2(void)
-{
-       s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10;
-}
-#else
-#define s3c2412_init_gpio2() do { } while(0)
-#endif
-
-/* Initial IO mappings */
-
-static struct map_desc s3c2412_iodesc[] __initdata = {
-       IODESC_ENT(CLKPWR),
-       IODESC_ENT(TIMER),
-       IODESC_ENT(WATCHDOG),
-       {
-               .virtual = (unsigned long)S3C2412_VA_SSMC,
-               .pfn     = __phys_to_pfn(S3C2412_PA_SSMC),
-               .length  = SZ_1M,
-               .type    = MT_DEVICE,
-       },
-       {
-               .virtual = (unsigned long)S3C2412_VA_EBI,
-               .pfn     = __phys_to_pfn(S3C2412_PA_EBI),
-               .length  = SZ_1M,
-               .type    = MT_DEVICE,
-       },
-};
-
-/* uart registration process */
-
-void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
-       s3c24xx_init_uartdevs("s3c2412-uart", s3c2410_uart_resources, cfg, no);
-
-       /* rename devices that are s3c2412/s3c2413 specific */
-       s3c_device_sdi.name  = "s3c2412-sdi";
-       s3c_device_lcd.name  = "s3c2412-lcd";
-       s3c_nand_setname("s3c2412-nand");
-
-       /* alter IRQ of SDI controller */
-
-       s3c_device_sdi.resource[1].start = IRQ_S3C2412_SDI;
-       s3c_device_sdi.resource[1].end   = IRQ_S3C2412_SDI;
-
-       /* spi channel related changes, s3c2412/13 specific */
-       s3c_device_spi0.name = "s3c2412-spi";
-       s3c_device_spi0.resource[0].end = S3C24XX_PA_SPI + 0x24;
-       s3c_device_spi1.name = "s3c2412-spi";
-       s3c_device_spi1.resource[0].start = S3C24XX_PA_SPI + S3C2412_SPI1;
-       s3c_device_spi1.resource[0].end = S3C24XX_PA_SPI + S3C2412_SPI1 + 0x24;
-
-}
-
-/* s3c2412_idle
- *
- * use the standard idle call by ensuring the idle mode
- * in power config, then issuing the idle co-processor
- * instruction
-*/
-
-static void s3c2412_idle(void)
-{
-       unsigned long tmp;
-
-       /* ensure our idle mode is to go to idle */
-
-       tmp = __raw_readl(S3C2412_PWRCFG);
-       tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
-       tmp |= S3C2412_PWRCFG_STANDBYWFI_IDLE;
-       __raw_writel(tmp, S3C2412_PWRCFG);
-
-       cpu_do_idle();
-}
-
-void s3c2412_restart(char mode, const char *cmd)
-{
-       if (mode == 's')
-               soft_restart(0);
-
-       /* errata "Watch-dog/Software Reset Problem" specifies that
-        * this reset must be done with the SYSCLK sourced from
-        * EXTCLK instead of FOUT to avoid a glitch in the reset
-        * mechanism.
-        *
-        * See the watchdog section of the S3C2412 manual for more
-        * information on this fix.
-        */
-
-       __raw_writel(0x00, S3C2412_CLKSRC);
-       __raw_writel(S3C2412_SWRST_RESET, S3C2412_SWRST);
-
-       mdelay(1);
-}
-
-/* s3c2412_map_io
- *
- * register the standard cpu IO areas, and any passed in from the
- * machine specific initialisation.
-*/
-
-void __init s3c2412_map_io(void)
-{
-       /* move base of IO */
-
-       s3c2412_init_gpio2();
-
-       /* set our idle function */
-
-       arm_pm_idle = s3c2412_idle;
-
-       /* register our io-tables */
-
-       iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
-}
-
-void __init_or_cpufreq s3c2412_setup_clocks(void)
-{
-       struct clk *xtal_clk;
-       unsigned long tmp;
-       unsigned long xtal;
-       unsigned long fclk;
-       unsigned long hclk;
-       unsigned long pclk;
-
-       xtal_clk = clk_get(NULL, "xtal");
-       xtal = clk_get_rate(xtal_clk);
-       clk_put(xtal_clk);
-
-       /* now we've got our machine bits initialised, work out what
-        * clocks we've got */
-
-       fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal * 2);
-
-       clk_mpll.rate = fclk;
-
-       tmp = __raw_readl(S3C2410_CLKDIVN);
-
-       /* work out clock scalings */
-
-       hclk = fclk / ((tmp & S3C2412_CLKDIVN_HDIVN_MASK) + 1);
-       hclk /= ((tmp & S3C2412_CLKDIVN_ARMDIVN) ? 2 : 1);
-       pclk = hclk / ((tmp & S3C2412_CLKDIVN_PDIVN) ? 2 : 1);
-
-       /* print brieft summary of clocks, etc */
-
-       printk("S3C2412: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
-              print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
-
-       s3c24xx_setup_clocks(fclk, hclk, pclk);
-}
-
-void __init s3c2412_init_clocks(int xtal)
-{
-       /* initialise the clocks here, to allow other things like the
-        * console to use them
-        */
-
-       s3c24xx_register_baseclocks(xtal);
-       s3c2412_setup_clocks();
-       s3c2412_baseclk_add();
-}
-
-/* need to register the subsystem before we actually register the device, and
- * we also need to ensure that it has been initialised before any of the
- * drivers even try to use it (even if not on an s3c2412 based system)
- * as a driver which may support both 2410 and 2440 may try and use it.
-*/
-
-struct bus_type s3c2412_subsys = {
-       .name = "s3c2412-core",
-       .dev_name = "s3c2412-core",
-};
-
-static int __init s3c2412_core_init(void)
-{
-       return subsys_system_register(&s3c2412_subsys, NULL);
-}
-
-core_initcall(s3c2412_core_init);
-
-static struct device s3c2412_dev = {
-       .bus            = &s3c2412_subsys,
-};
-
-int __init s3c2412_init(void)
-{
-       printk("S3C2412: Initialising architecture\n");
-
-#ifdef CONFIG_PM
-       register_syscore_ops(&s3c2412_pm_syscore_ops);
-#endif
-       register_syscore_ops(&s3c24xx_irq_syscore_ops);
-
-       return device_register(&s3c2412_dev);
-}
diff --git a/arch/arm/mach-s3c2412/sleep.S b/arch/arm/mach-s3c2412/sleep.S
deleted file mode 100644 (file)
index c82418e..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/* linux/arch/arm/mach-s3c2412/sleep.S
- *
- * Copyright (c) 2007 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2412 Power Manager low-level sleep support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <mach/regs-irq.h>
-
-       .text
-
-       .global s3c2412_sleep_enter
-
-s3c2412_sleep_enter:
-       mov     r0, #0                  /* argument for coprocessors */
-       ldr     r1, =S3C2410_INTPND
-       ldr     r2, =S3C2410_SRCPND
-       ldr     r3, =S3C2410_EINTPEND
-
-       teq     r0, r0
-       bl      s3c2412_sleep_enter1
-       teq     pc, r0
-       bl      s3c2412_sleep_enter1
-
-       .align  5
-
-       /* this is called twice, first with the Z flag to ensure that the
-        * instructions have been loaded into the cache, and the second
-        * time to try and suspend the system.
-       */
-s3c2412_sleep_enter1:
-       mcr     p15, 0, r0, c7, c10, 4
-       mcrne   p15, 0, r0, c7, c0, 4
-
-       /* if we return from here, it is because an interrupt was
-        * active when we tried to shutdown. Try and ack the IRQ and
-        * retry, as simply returning causes the system to lock.
-       */
-
-       ldrne   r9, [ r1 ]
-       strne   r9, [ r1 ]
-       ldrne   r9, [ r2 ]
-       strne   r9, [ r2 ]
-       ldrne   r9, [ r3 ]
-       strne   r9, [ r3 ]
-       bne     s3c2412_sleep_enter1
-
-       mov     pc, r14
diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig
deleted file mode 100644 (file)
index 84c7b03..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-# arch/arm/mach-s3c2416/Kconfig
-#
-# Copyright 2009 Yauhen Kharuzhy <jekhor@gmail.com>
-#
-# Licensed under GPLv2
-
-# note, this also supports the S3C2450 which is so similar it has the same
-# ID code as the S3C2416.
-
-config CPU_S3C2416
-       bool
-       depends on ARCH_S3C2410
-       select CPU_ARM926T
-       select S3C2416_DMA if S3C2410_DMA
-       select CPU_LLSERIAL_S3C2440
-       select SAMSUNG_CLKSRC
-       select S3C2443_CLOCK
-       help
-         Support for the S3C2416 SoC from the S3C24XX line
-
-config S3C2416_DMA
-       bool
-       depends on CPU_S3C2416
-       help
-         Internal config node for S3C2416 DMA support
-
-config S3C2416_PM
-       bool
-       select S3C2412_PM_SLEEP
-       help
-         Internal config node to apply S3C2416 power management
-
-config S3C2416_SETUP_SDHCI
-       bool
-       select S3C2416_SETUP_SDHCI_GPIO
-       help
-         Internal helper functions for S3C2416 based SDHCI systems
-
-config S3C2416_SETUP_SDHCI_GPIO
-       bool
-       help
-         Common setup code for SDHCI gpio.
-
-menu "S3C2416 Machines"
-
-config MACH_SMDK2416
-       bool "SMDK2416"
-       select CPU_S3C2416
-       select MACH_SMDK
-       select S3C_DEV_FB
-       select S3C_DEV_HSMMC
-       select S3C_DEV_HSMMC1
-       select S3C_DEV_NAND
-       select S3C_DEV_USB_HOST
-       select S3C2416_SETUP_SDHCI
-       select S3C2416_PM if PM
-       help
-         Say Y here if you are using an SMDK2416
-
-endmenu
diff --git a/arch/arm/mach-s3c2416/Makefile b/arch/arm/mach-s3c2416/Makefile
deleted file mode 100644 (file)
index ca0cd22..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# arch/arm/mach-s3c2416/Makefile
-#
-# Copyright 2009 Yauhen Kharuzhy <jekhor@gmail.com>
-#
-# Licensed under GPLv2
-
-obj-y                          :=
-obj-m                          :=
-obj-n                          :=
-obj-                           :=
-
-obj-$(CONFIG_CPU_S3C2416)      += s3c2416.o clock.o
-obj-$(CONFIG_CPU_S3C2416)      += irq.o
-obj-$(CONFIG_S3C2416_PM)       += pm.o
-#obj-$(CONFIG_S3C2416_DMA)     += dma.o
-
-# Device setup
-obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
-
-# Machine support
-
-obj-$(CONFIG_MACH_SMDK2416)    += mach-smdk2416.o
diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c
deleted file mode 100644 (file)
index 59f54d1..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/* linux/arch/arm/mach-s3c2416/clock.c
- *
- * Copyright (c) 2010 Simtec Electronics
- * Copyright (c) 2010 Ben Dooks <ben-linux@fluff.org>
- *
- * S3C2416 Clock control support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/init.h>
-#include <linux/clk.h>
-
-#include <plat/s3c2416.h>
-#include <plat/s3c2443.h>
-#include <plat/clock.h>
-#include <plat/clock-clksrc.h>
-#include <plat/cpu.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/pll.h>
-
-#include <asm/mach/map.h>
-
-#include <mach/regs-clock.h>
-#include <mach/regs-s3c2443-clock.h>
-
-/* armdiv
- *
- * this clock is sourced from msysclk and can have a number of
- * divider values applied to it to then be fed into armclk.
- * The real clock definition is done in s3c2443-clock.c,
- * only the armdiv divisor table must be defined here.
-*/
-
-static unsigned int armdiv[8] = {
-       [0] = 1,
-       [1] = 2,
-       [2] = 3,
-       [3] = 4,
-       [5] = 6,
-       [7] = 8,
-};
-
-static struct clksrc_clk hsspi_eplldiv = {
-       .clk = {
-               .name   = "hsspi-eplldiv",
-               .parent = &clk_esysclk.clk,
-               .ctrlbit = (1 << 14),
-               .enable = s3c2443_clkcon_enable_s,
-       },
-       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 24 },
-};
-
-static struct clk *hsspi_sources[] = {
-       [0] = &hsspi_eplldiv.clk,
-       [1] = NULL, /* to fix */
-};
-
-static struct clksrc_clk hsspi_mux = {
-       .clk    = {
-               .name   = "hsspi-if",
-       },
-       .sources = &(struct clksrc_sources) {
-               .sources = hsspi_sources,
-               .nr_sources = ARRAY_SIZE(hsspi_sources),
-       },
-       .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 18 },
-};
-
-static struct clksrc_clk hsmmc_div[] = {
-       [0] = {
-               .clk = {
-                       .name   = "hsmmc-div",
-                       .devname        = "s3c-sdhci.0",
-                       .parent = &clk_esysclk.clk,
-               },
-               .reg_div = { .reg = S3C2416_CLKDIV2, .size = 2, .shift = 6 },
-       },
-       [1] = {
-               .clk = {
-                       .name   = "hsmmc-div",
-                       .devname        = "s3c-sdhci.1",
-                       .parent = &clk_esysclk.clk,
-               },
-               .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
-       },
-};
-
-static struct clksrc_clk hsmmc_mux0 = {
-       .clk    = {
-               .name           = "hsmmc-if",
-               .devname        = "s3c-sdhci.0",
-               .ctrlbit        = (1 << 6),
-               .enable         = s3c2443_clkcon_enable_s,
-       },
-       .sources        = &(struct clksrc_sources) {
-               .nr_sources     = 2,
-               .sources        = (struct clk * []) {
-                       [0]     = &hsmmc_div[0].clk,
-                       [1]     = NULL, /* to fix */
-               },
-       },
-       .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 16 },
-};
-
-static struct clksrc_clk hsmmc_mux1 = {
-       .clk    = {
-               .name           = "hsmmc-if",
-               .devname        = "s3c-sdhci.1",
-               .ctrlbit        = (1 << 12),
-               .enable         = s3c2443_clkcon_enable_s,
-       },
-       .sources        = &(struct clksrc_sources) {
-               .nr_sources     = 2,
-               .sources        = (struct clk * []) {
-                       [0]     = &hsmmc_div[1].clk,
-                       [1]     = NULL, /* to fix */
-               },
-       },
-       .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 17 },
-};
-
-static struct clk hsmmc0_clk = {
-       .name           = "hsmmc",
-       .devname        = "s3c-sdhci.0",
-       .parent         = &clk_h,
-       .enable         = s3c2443_clkcon_enable_h,
-       .ctrlbit        = S3C2416_HCLKCON_HSMMC0,
-};
-
-void __init_or_cpufreq s3c2416_setup_clocks(void)
-{
-       s3c2443_common_setup_clocks(s3c2416_get_pll);
-}
-
-
-static struct clksrc_clk *clksrcs[] __initdata = {
-       &hsspi_eplldiv,
-       &hsspi_mux,
-       &hsmmc_div[0],
-       &hsmmc_div[1],
-       &hsmmc_mux0,
-       &hsmmc_mux1,
-};
-
-static struct clk_lookup s3c2416_clk_lookup[] = {
-       CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &hsmmc0_clk),
-       CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &hsmmc_mux0.clk),
-       CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &hsmmc_mux1.clk),
-};
-
-void __init s3c2416_init_clocks(int xtal)
-{
-       u32 epllcon = __raw_readl(S3C2443_EPLLCON);
-       u32 epllcon1 = __raw_readl(S3C2443_EPLLCON+4);
-       int ptr;
-
-       /* s3c2416 EPLL compatible with s3c64xx */
-       clk_epll.rate = s3c_get_pll6553x(xtal, epllcon, epllcon1);
-
-       clk_epll.parent = &clk_epllref.clk;
-
-       s3c2443_common_init_clocks(xtal, s3c2416_get_pll,
-                                  armdiv, ARRAY_SIZE(armdiv),
-                                  S3C2416_CLKDIV0_ARMDIV_MASK);
-
-       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
-               s3c_register_clksrc(clksrcs[ptr], 1);
-
-       s3c24xx_register_clock(&hsmmc0_clk);
-       clkdev_add_table(s3c2416_clk_lookup, ARRAY_SIZE(s3c2416_clk_lookup));
-
-       s3c_pwmclk_init();
-
-}
diff --git a/arch/arm/mach-s3c2416/irq.c b/arch/arm/mach-s3c2416/irq.c
deleted file mode 100644 (file)
index fd49f35..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-/* linux/arch/arm/mach-s3c2416/irq.c
- *
- * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
- *     as part of OpenInkpot project
- * Copyright (c) 2009 Promwad Innovation Company
- *     Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <asm/mach/irq.h>
-
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/irq.h>
-
-#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
-
-static inline void s3c2416_irq_demux(unsigned int irq, unsigned int len)
-{
-       unsigned int subsrc, submsk;
-       unsigned int end;
-
-       /* read the current pending interrupts, and the mask
-        * for what it is available */
-
-       subsrc = __raw_readl(S3C2410_SUBSRCPND);
-       submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-       subsrc  &= ~submsk;
-       subsrc >>= (irq - S3C2410_IRQSUB(0));
-       subsrc  &= (1 << len)-1;
-
-       end = len + irq;
-
-       for (; irq < end && subsrc; irq++) {
-               if (subsrc & 1)
-                       generic_handle_irq(irq);
-
-               subsrc >>= 1;
-       }
-}
-
-/* WDT/AC97 sub interrupts */
-
-static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
-{
-       s3c2416_irq_demux(IRQ_S3C2443_WDT, 4);
-}
-
-#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
-#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
-
-static void s3c2416_irq_wdtac97_mask(struct irq_data *data)
-{
-       s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static void s3c2416_irq_wdtac97_unmask(struct irq_data *data)
-{
-       s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
-}
-
-static void s3c2416_irq_wdtac97_ack(struct irq_data *data)
-{
-       s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static struct irq_chip s3c2416_irq_wdtac97 = {
-       .irq_mask       = s3c2416_irq_wdtac97_mask,
-       .irq_unmask     = s3c2416_irq_wdtac97_unmask,
-       .irq_ack        = s3c2416_irq_wdtac97_ack,
-};
-
-/* LCD sub interrupts */
-
-static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
-{
-       s3c2416_irq_demux(IRQ_S3C2443_LCD1, 4);
-}
-
-#define INTMSK_LCD     (1UL << (IRQ_LCD - IRQ_EINT0))
-#define SUBMSK_LCD     INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
-
-static void s3c2416_irq_lcd_mask(struct irq_data *data)
-{
-       s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static void s3c2416_irq_lcd_unmask(struct irq_data *data)
-{
-       s3c_irqsub_unmask(data->irq, INTMSK_LCD);
-}
-
-static void s3c2416_irq_lcd_ack(struct irq_data *data)
-{
-       s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static struct irq_chip s3c2416_irq_lcd = {
-       .irq_mask       = s3c2416_irq_lcd_mask,
-       .irq_unmask     = s3c2416_irq_lcd_unmask,
-       .irq_ack        = s3c2416_irq_lcd_ack,
-};
-
-/* DMA sub interrupts */
-
-static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
-{
-       s3c2416_irq_demux(IRQ_S3C2443_DMA0, 6);
-}
-
-#define INTMSK_DMA     (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
-#define SUBMSK_DMA     INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
-
-
-static void s3c2416_irq_dma_mask(struct irq_data *data)
-{
-       s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static void s3c2416_irq_dma_unmask(struct irq_data *data)
-{
-       s3c_irqsub_unmask(data->irq, INTMSK_DMA);
-}
-
-static void s3c2416_irq_dma_ack(struct irq_data *data)
-{
-       s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static struct irq_chip s3c2416_irq_dma = {
-       .irq_mask       = s3c2416_irq_dma_mask,
-       .irq_unmask     = s3c2416_irq_dma_unmask,
-       .irq_ack        = s3c2416_irq_dma_ack,
-};
-
-/* UART3 sub interrupts */
-
-static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
-{
-       s3c2416_irq_demux(IRQ_S3C2443_RX3, 3);
-}
-
-#define INTMSK_UART3   (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
-#define SUBMSK_UART3   (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
-
-static void s3c2416_irq_uart3_mask(struct irq_data *data)
-{
-       s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static void s3c2416_irq_uart3_unmask(struct irq_data *data)
-{
-       s3c_irqsub_unmask(data->irq, INTMSK_UART3);
-}
-
-static void s3c2416_irq_uart3_ack(struct irq_data *data)
-{
-       s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static struct irq_chip s3c2416_irq_uart3 = {
-       .irq_mask       = s3c2416_irq_uart3_mask,
-       .irq_unmask     = s3c2416_irq_uart3_unmask,
-       .irq_ack        = s3c2416_irq_uart3_ack,
-};
-
-/* IRQ initialisation code */
-
-static int __init s3c2416_add_sub(unsigned int base,
-                                  void (*demux)(unsigned int,
-                                                struct irq_desc *),
-                                  struct irq_chip *chip,
-                                  unsigned int start, unsigned int end)
-{
-       unsigned int irqno;
-
-       irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
-       irq_set_chained_handler(base, demux);
-
-       for (irqno = start; irqno <= end; irqno++) {
-               irq_set_chip_and_handler(irqno, chip, handle_level_irq);
-               set_irq_flags(irqno, IRQF_VALID);
-       }
-
-       return 0;
-}
-
-static int __init s3c2416_irq_add(struct device *dev,
-                                 struct subsys_interface *sif)
-{
-       printk(KERN_INFO "S3C2416: IRQ Support\n");
-
-       s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd,
-                       IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4);
-
-       s3c2416_add_sub(IRQ_S3C2443_DMA, s3c2416_irq_demux_dma,
-                       &s3c2416_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
-
-       s3c2416_add_sub(IRQ_S3C2443_UART3, s3c2416_irq_demux_uart3,
-                       &s3c2416_irq_uart3,
-                       IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
-
-       s3c2416_add_sub(IRQ_WDT, s3c2416_irq_demux_wdtac97,
-                       &s3c2416_irq_wdtac97,
-                       IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
-
-       return 0;
-}
-
-static struct subsys_interface s3c2416_irq_interface = {
-       .name           = "s3c2416_irq",
-       .subsys         = &s3c2416_subsys,
-       .add_dev        = s3c2416_irq_add,
-};
-
-static int __init s3c2416_irq_init(void)
-{
-       return subsys_interface_register(&s3c2416_irq_interface);
-}
-
-arch_initcall(s3c2416_irq_init);
-
diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c2416/mach-smdk2416.c
deleted file mode 100644 (file)
index eebe1e7..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/* linux/arch/arm/mach-s3c2416/mach-hanlin_v3c.c
- *
- * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
- *     as part of OpenInkpot project
- * Copyright (c) 2009 Promwad Innovation Company
- *     Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/mtd/partitions.h>
-#include <linux/gpio.h>
-#include <linux/fb.h>
-#include <linux/delay.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-lcd.h>
-#include <mach/regs-s3c2443-clock.h>
-
-#include <mach/idle.h>
-#include <mach/leds-gpio.h>
-#include <plat/iic.h>
-
-#include <plat/s3c2416.h>
-#include <plat/gpio-cfg.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/nand.h>
-#include <plat/sdhci.h>
-#include <plat/udc.h>
-#include <linux/platform_data/s3c-hsudc.h>
-
-#include <plat/regs-fb-v4.h>
-#include <plat/fb.h>
-
-#include <plat/common-smdk.h>
-
-static struct map_desc smdk2416_iodesc[] __initdata = {
-       /* ISA IO Space map (memory space selected by A24) */
-
-       {
-               .virtual        = (u32)S3C24XX_VA_ISA_WORD,
-               .pfn            = __phys_to_pfn(S3C2410_CS2),
-               .length         = 0x10000,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
-               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
-               .length         = SZ_4M,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
-               .pfn            = __phys_to_pfn(S3C2410_CS2),
-               .length         = 0x10000,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
-               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
-               .length         = SZ_4M,
-               .type           = MT_DEVICE,
-       }
-};
-
-#define UCON (S3C2410_UCON_DEFAULT     | \
-               S3C2440_UCON_PCLK       | \
-               S3C2443_UCON_RXERR_IRQEN)
-
-#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
-
-#define UFCON (S3C2410_UFCON_RXTRIG8   | \
-               S3C2410_UFCON_FIFOMODE  | \
-               S3C2440_UFCON_TXTRIG16)
-
-static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       /* IR port */
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON | 0x50,
-               .ufcon       = UFCON,
-       },
-       [3] = {
-               .hwport      = 3,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       }
-};
-
-void smdk2416_hsudc_gpio_init(void)
-{
-       s3c_gpio_setpull(S3C2410_GPH(14), S3C_GPIO_PULL_UP);
-       s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_NONE);
-       s3c_gpio_cfgpin(S3C2410_GPH(14), S3C_GPIO_SFN(1));
-       s3c2410_modify_misccr(S3C2416_MISCCR_SEL_SUSPND, 0);
-}
-
-void smdk2416_hsudc_gpio_uninit(void)
-{
-       s3c2410_modify_misccr(S3C2416_MISCCR_SEL_SUSPND, 1);
-       s3c_gpio_setpull(S3C2410_GPH(14), S3C_GPIO_PULL_NONE);
-       s3c_gpio_cfgpin(S3C2410_GPH(14), S3C_GPIO_SFN(0));
-}
-
-struct s3c24xx_hsudc_platdata smdk2416_hsudc_platdata = {
-       .epnum = 9,
-       .gpio_init = smdk2416_hsudc_gpio_init,
-       .gpio_uninit = smdk2416_hsudc_gpio_uninit,
-};
-
-struct s3c_fb_pd_win smdk2416_fb_win[] = {
-       [0] = {
-               /* think this is the same as the smdk6410 */
-               .win_mode       = {
-                       .pixclock       = 41094,
-                       .left_margin    = 8,
-                       .right_margin   = 13,
-                       .upper_margin   = 7,
-                       .lower_margin   = 5,
-                       .hsync_len      = 3,
-                       .vsync_len      = 1,
-                       .xres           = 800,
-                       .yres           = 480,
-               },
-               .default_bpp    = 16,
-               .max_bpp        = 32,
-       },
-};
-
-static void s3c2416_fb_gpio_setup_24bpp(void)
-{
-       unsigned int gpio;
-
-       for (gpio = S3C2410_GPC(1); gpio <= S3C2410_GPC(4); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
-
-       for (gpio = S3C2410_GPC(8); gpio <= S3C2410_GPC(15); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
-
-       for (gpio = S3C2410_GPD(0); gpio <= S3C2410_GPD(15); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
-}
-
-static struct s3c_fb_platdata smdk2416_fb_platdata = {
-       .win[0]         = &smdk2416_fb_win[0],
-       .setup_gpio     = s3c2416_fb_gpio_setup_24bpp,
-       .vidcon0        = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
-       .vidcon1        = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
-};
-
-static struct s3c_sdhci_platdata smdk2416_hsmmc0_pdata __initdata = {
-       .max_width              = 4,
-       .cd_type                = S3C_SDHCI_CD_GPIO,
-       .ext_cd_gpio            = S3C2410_GPF(1),
-       .ext_cd_gpio_invert     = 1,
-};
-
-static struct s3c_sdhci_platdata smdk2416_hsmmc1_pdata __initdata = {
-       .max_width              = 4,
-       .cd_type                = S3C_SDHCI_CD_NONE,
-};
-
-static struct platform_device *smdk2416_devices[] __initdata = {
-       &s3c_device_fb,
-       &s3c_device_wdt,
-       &s3c_device_ohci,
-       &s3c_device_i2c0,
-       &s3c_device_hsmmc0,
-       &s3c_device_hsmmc1,
-       &s3c_device_usb_hsudc,
-};
-
-static void __init smdk2416_map_io(void)
-{
-       s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc));
-       s3c24xx_init_clocks(12000000);
-       s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs));
-}
-
-static void __init smdk2416_machine_init(void)
-{
-       s3c_i2c0_set_platdata(NULL);
-       s3c_fb_set_platdata(&smdk2416_fb_platdata);
-
-       s3c_sdhci0_set_platdata(&smdk2416_hsmmc0_pdata);
-       s3c_sdhci1_set_platdata(&smdk2416_hsmmc1_pdata);
-
-       s3c24xx_hsudc_set_platdata(&smdk2416_hsudc_platdata);
-
-       gpio_request(S3C2410_GPB(4), "USBHost Power");
-       gpio_direction_output(S3C2410_GPB(4), 1);
-
-       gpio_request(S3C2410_GPB(3), "Display Power");
-       gpio_direction_output(S3C2410_GPB(3), 1);
-
-       gpio_request(S3C2410_GPB(1), "Display Reset");
-       gpio_direction_output(S3C2410_GPB(1), 1);
-
-       platform_add_devices(smdk2416_devices, ARRAY_SIZE(smdk2416_devices));
-       smdk_machine_init();
-}
-
-MACHINE_START(SMDK2416, "SMDK2416")
-       /* Maintainer: Yauhen Kharuzhy <jekhor@gmail.com> */
-       .atag_offset    = 0x100,
-
-       .init_irq       = s3c24xx_init_irq,
-       .map_io         = smdk2416_map_io,
-       .init_machine   = smdk2416_machine_init,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c2416_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2416/pm.c b/arch/arm/mach-s3c2416/pm.c
deleted file mode 100644 (file)
index 1bd4817..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/* linux/arch/arm/mach-s3c2416/pm.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * S3C2416 - PM support (Based on Ben Dooks' S3C2412 PM support)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/device.h>
-#include <linux/syscore_ops.h>
-#include <linux/io.h>
-
-#include <asm/cacheflush.h>
-
-#include <mach/regs-power.h>
-#include <mach/regs-s3c2443-clock.h>
-
-#include <plat/cpu.h>
-#include <plat/pm.h>
-
-extern void s3c2412_sleep_enter(void);
-
-static int s3c2416_cpu_suspend(unsigned long arg)
-{
-       /* enable wakeup sources regardless of battery state */
-       __raw_writel(S3C2443_PWRCFG_SLEEP, S3C2443_PWRCFG);
-
-       /* set the mode as sleep, 2BED represents "Go to BED" */
-       __raw_writel(0x2BED, S3C2443_PWRMODE);
-
-       s3c2412_sleep_enter();
-
-       panic("sleep resumed to originator?");
-}
-
-static void s3c2416_pm_prepare(void)
-{
-       /*
-        * write the magic value u-boot uses to check for resume into
-        * the INFORM0 register, and ensure INFORM1 is set to the
-        * correct address to resume from.
-        */
-       __raw_writel(0x2BED, S3C2412_INFORM0);
-       __raw_writel(virt_to_phys(s3c_cpu_resume), S3C2412_INFORM1);
-}
-
-static int s3c2416_pm_add(struct device *dev, struct subsys_interface *sif)
-{
-       pm_cpu_prep = s3c2416_pm_prepare;
-       pm_cpu_sleep = s3c2416_cpu_suspend;
-
-       return 0;
-}
-
-static struct subsys_interface s3c2416_pm_interface = {
-       .name           = "s3c2416_pm",
-       .subsys         = &s3c2416_subsys,
-       .add_dev        = s3c2416_pm_add,
-};
-
-static __init int s3c2416_pm_init(void)
-{
-       return subsys_interface_register(&s3c2416_pm_interface);
-}
-
-arch_initcall(s3c2416_pm_init);
-
-
-static void s3c2416_pm_resume(void)
-{
-       /* unset the return-from-sleep amd inform flags */
-       __raw_writel(0x0, S3C2443_PWRMODE);
-       __raw_writel(0x0, S3C2412_INFORM0);
-       __raw_writel(0x0, S3C2412_INFORM1);
-}
-
-struct syscore_ops s3c2416_pm_syscore_ops = {
-       .resume         = s3c2416_pm_resume,
-};
diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c
deleted file mode 100644 (file)
index 08bb035..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/* linux/arch/arm/mach-s3c2416/s3c2416.c
- *
- * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
- *     as part of OpenInkpot project
- * Copyright (c) 2009 Promwad Innovation Company
- *     Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
- *
- * Samsung S3C2416 Mobile CPU support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/device.h>
-#include <linux/syscore_ops.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/proc-fns.h>
-#include <asm/irq.h>
-
-#include <mach/regs-s3c2443-clock.h>
-
-#include <plat/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-#include <plat/s3c2416.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/sdhci.h>
-#include <plat/pm.h>
-
-#include <plat/iic-core.h>
-#include <plat/fb-core.h>
-#include <plat/nand-core.h>
-#include <plat/adc-core.h>
-
-static struct map_desc s3c2416_iodesc[] __initdata = {
-       IODESC_ENT(WATCHDOG),
-       IODESC_ENT(CLKPWR),
-       IODESC_ENT(TIMER),
-};
-
-struct bus_type s3c2416_subsys = {
-       .name = "s3c2416-core",
-       .dev_name = "s3c2416-core",
-};
-
-static struct device s3c2416_dev = {
-       .bus            = &s3c2416_subsys,
-};
-
-void s3c2416_restart(char mode, const char *cmd)
-{
-       if (mode == 's')
-               soft_restart(0);
-
-       __raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST);
-}
-
-int __init s3c2416_init(void)
-{
-       printk(KERN_INFO "S3C2416: Initializing architecture\n");
-
-       /* change WDT IRQ number */
-       s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT;
-       s3c_device_wdt.resource[1].end   = IRQ_S3C2443_WDT;
-
-       /* the i2c devices are directly compatible with s3c2440 */
-       s3c_i2c0_setname("s3c2440-i2c");
-       s3c_i2c1_setname("s3c2440-i2c");
-
-       s3c_fb_setname("s3c2443-fb");
-
-       s3c_adc_setname("s3c2416-adc");
-
-#ifdef CONFIG_PM
-       register_syscore_ops(&s3c2416_pm_syscore_ops);
-#endif
-       register_syscore_ops(&s3c24xx_irq_syscore_ops);
-
-       return device_register(&s3c2416_dev);
-}
-
-void __init s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
-       s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
-
-       s3c_nand_setname("s3c2412-nand");
-}
-
-/* s3c2416_map_io
- *
- * register the standard cpu IO areas, and any passed in from the
- * machine specific initialisation.
- */
-
-void __init s3c2416_map_io(void)
-{
-       s3c24xx_gpiocfg_default.set_pull = samsung_gpio_setpull_updown;
-       s3c24xx_gpiocfg_default.get_pull = samsung_gpio_getpull_updown;
-
-       /* initialize device information early */
-       s3c2416_default_sdhci0();
-       s3c2416_default_sdhci1();
-
-       iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc));
-}
-
-/* need to register the subsystem before we actually register the device, and
- * we also need to ensure that it has been initialised before any of the
- * drivers even try to use it (even if not on an s3c2416 based system)
- * as a driver which may support both 2443 and 2440 may try and use it.
-*/
-
-static int __init s3c2416_core_init(void)
-{
-       return subsys_system_register(&s3c2416_subsys, NULL);
-}
-
-core_initcall(s3c2416_core_init);
diff --git a/arch/arm/mach-s3c2416/setup-sdhci-gpio.c b/arch/arm/mach-s3c2416/setup-sdhci-gpio.c
deleted file mode 100644 (file)
index f65cb3e..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* linux/arch/arm/plat-s3c2416/setup-sdhci-gpio.c
- *
- * Copyright 2010 Promwad Innovation Company
- *     Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
- *
- * S3C2416 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
- *
- * Based on mach-s3c64xx/setup-sdhci-gpio.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-
-#include <mach/regs-gpio.h>
-#include <plat/gpio-cfg.h>
-
-void s3c2416_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
-{
-       s3c_gpio_cfgrange_nopull(S3C2410_GPE(5), 2 + width, S3C_GPIO_SFN(2));
-}
-
-void s3c2416_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
-{
-       s3c_gpio_cfgrange_nopull(S3C2410_GPL(0), width, S3C_GPIO_SFN(2));
-       s3c_gpio_cfgrange_nopull(S3C2410_GPL(8), 2, S3C_GPIO_SFN(2));
-}
index 914e620f1257a75d808077d41d91599466119a58..ece7a10fe3c64b2b233b982d091000ff0224e190 100644 (file)
@@ -2,35 +2,6 @@
 #
 # Licensed under GPLv2
 
-config CPU_S3C2440
-       bool
-       select CPU_ARM920T
-       select S3C2410_CLOCK
-       select S3C2410_PM if PM
-       select S3C2440_DMA if S3C2410_DMA
-       select CPU_S3C244X
-       select CPU_LLSERIAL_S3C2440
-       help
-         Support for S3C2440 Samsung Mobile CPU based systems.
-
-config CPU_S3C2442
-       bool
-       select CPU_ARM920T
-       select S3C2410_CLOCK
-       select S3C2410_PM if PM
-       select CPU_S3C244X
-       select CPU_LLSERIAL_S3C2440
-       help
-         Support for S3C2442 Samsung Mobile CPU based systems.
-
-config CPU_S3C244X
-       bool
-       depends on CPU_S3C2440 || CPU_S3C2442
-       help
-         Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
-
-
-
 config S3C2440_CPUFREQ
        bool "S3C2440/S3C2442 CPU Frequency scaling support"
        depends on CPU_FREQ_S3C24XX && (CPU_S3C2440 || CPU_S3C2442)
@@ -64,139 +35,3 @@ config S3C2440_PLL_16934400
        default y if CPU_FREQ_S3C24XX_PLL
        help
          PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals.
-
-config S3C2440_DMA
-       bool
-       depends on CPU_S3C2440
-       help
-         Support for S3C2440 specific DMA code5A
-
-menu "S3C2440 and S3C2442 Machines"
-
-config MACH_ANUBIS
-       bool "Simtec Electronics ANUBIS"
-       select CPU_S3C2440
-       select S3C24XX_DCLK
-       select PM_SIMTEC if PM
-       select HAVE_PATA_PLATFORM
-       select S3C24XX_GPIO_EXTRA64
-       select S3C2440_XTAL_12000000
-       select S3C_DEV_USB_HOST
-       help
-         Say Y here if you are using the Simtec Electronics ANUBIS
-         development system
-
-config MACH_NEO1973_GTA02
-       bool "Openmoko GTA02 / Freerunner phone"
-       select CPU_S3C2442
-       select MFD_PCF50633
-       select PCF50633_GPIO
-       select I2C
-       select POWER_SUPPLY
-       select MACH_NEO1973
-       select S3C2410_PWM
-       select S3C_DEV_USB_HOST
-       help
-          Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone
-
-config MACH_OSIRIS
-       bool "Simtec IM2440D20 (OSIRIS) module"
-       select CPU_S3C2440
-       select S3C24XX_DCLK
-       select PM_SIMTEC if PM
-       select S3C24XX_GPIO_EXTRA128
-       select S3C2440_XTAL_12000000
-       select S3C2410_IOTIMING if S3C2440_CPUFREQ
-       select S3C_DEV_USB_HOST
-       select S3C_DEV_NAND
-       help
-         Say Y here if you are using the Simtec IM2440D20 module, also
-         known as the Osiris.
-
-config MACH_OSIRIS_DVS
-       tristate "Simtec IM2440D20 (OSIRIS) Dynamic Voltage Scaling driver"
-       depends on MACH_OSIRIS
-       select TPS65010
-       help
-         Say Y/M here if you want to have dynamic voltage scaling support
-         on the Simtec IM2440D20 (OSIRIS) module via the TPS65011.
-
-         The DVS driver alters the voltage supplied to the ARM core
-         depending on the frequency it is running at. The driver itself
-         does not do any of the frequency alteration, which is left up
-         to the cpufreq driver.
-
-config MACH_RX3715
-       bool "HP iPAQ rx3715"
-       select CPU_S3C2440
-       select S3C2440_XTAL_16934400
-       select PM_H1940 if PM
-       select S3C_DEV_NAND
-       help
-         Say Y here if you are using the HP iPAQ rx3715.
-
-config ARCH_S3C2440
-       bool "SMDK2440"
-       select CPU_S3C2440
-       select S3C2440_XTAL_16934400
-       select MACH_SMDK
-       select S3C_DEV_USB_HOST
-       select S3C_DEV_NAND
-       help
-         Say Y here if you are using the SMDK2440.
-
-config MACH_NEXCODER_2440
-       bool "NexVision NEXCODER 2440 Light Board"
-       select CPU_S3C2440
-       select S3C2440_XTAL_12000000
-       select S3C_DEV_USB_HOST
-       select S3C_DEV_NAND
-       help
-         Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
-
-config SMDK2440_CPU2440
-       bool "SMDK2440 with S3C2440 CPU module"
-       default y if ARCH_S3C2440
-       select S3C2440_XTAL_16934400
-       select CPU_S3C2440
-
-config SMDK2440_CPU2442
-       bool "SMDM2440 with S3C2442 CPU module"
-       select CPU_S3C2442
-
-config MACH_AT2440EVB
-       bool "Avantech AT2440EVB development board"
-       select CPU_S3C2440
-       select S3C_DEV_USB_HOST
-       select S3C_DEV_NAND
-       help
-         Say Y here if you are using the AT2440EVB development board
-
-config MACH_MINI2440
-       bool "MINI2440 development board"
-       select CPU_S3C2440
-       select EEPROM_AT24
-       select NEW_LEDS
-       select LEDS_CLASS
-       select LEDS_TRIGGER
-       select LEDS_TRIGGER_BACKLIGHT
-       select S3C_DEV_NAND
-       select S3C_DEV_USB_HOST
-       help
-         Say Y here to select support for the MINI2440. Is a 10cm x 10cm board
-         available via various sources. It can come with a 3.5" or 7" touch LCD.
-
-config MACH_RX1950
-       bool "HP iPAQ rx1950"
-       select CPU_S3C2442
-       select S3C24XX_DCLK
-       select PM_H1940 if PM
-       select I2C
-       select S3C2410_PWM
-       select S3C_DEV_NAND
-       select S3C2410_IOTIMING if S3C2440_CPUFREQ
-       select S3C2440_XTAL_16934400
-       help
-          Say Y here if you're using HP iPAQ rx1950
-
-endmenu
index d5440fa34b045cb8a9e2b0d5ec75cb913ea21a0f..c46092439814777a6f03f5d80e92e124aec07144 100644 (file)
@@ -9,33 +9,9 @@ obj-m                          :=
 obj-n                          :=
 obj-                           :=
 
-obj-$(CONFIG_CPU_S3C2440)      += s3c2440.o dsc.o
-obj-$(CONFIG_CPU_S3C2442)      += s3c2442.o
+obj-$(CONFIG_CPU_S3C2440)      += dsc.o
 
-obj-$(CONFIG_CPU_S3C2440)      += irq.o
-obj-$(CONFIG_CPU_S3C2440)      += clock.o
-obj-$(CONFIG_S3C2440_DMA)      += dma.o
-
-obj-$(CONFIG_CPU_S3C244X)      += s3c244x.o
-obj-$(CONFIG_CPU_S3C244X)      += s3c244x-irq.o
-obj-$(CONFIG_CPU_S3C244X)      += s3c244x-clock.o
 obj-$(CONFIG_S3C2440_CPUFREQ)  += s3c2440-cpufreq.o
 
 obj-$(CONFIG_S3C2440_PLL_12000000) += s3c2440-pll-12000000.o
 obj-$(CONFIG_S3C2440_PLL_16934400) += s3c2440-pll-16934400.o
-
-# Machine support
-
-obj-$(CONFIG_MACH_ANUBIS)      += mach-anubis.o
-obj-$(CONFIG_MACH_OSIRIS)      += mach-osiris.o
-obj-$(CONFIG_MACH_RX3715)      += mach-rx3715.o
-obj-$(CONFIG_ARCH_S3C2440)     += mach-smdk2440.o
-obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
-obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o
-obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o
-obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o
-obj-$(CONFIG_MACH_RX1950) += mach-rx1950.o
-
-# extra machine support
-
-obj-$(CONFIG_MACH_OSIRIS_DVS)  += mach-osiris-dvs.o
diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c
deleted file mode 100644 (file)
index 414364e..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/* linux/arch/arm/mach-s3c2440/clock.c
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2440 Clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/mutex.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/serial_core.h>
-
-#include <mach/hardware.h>
-#include <linux/atomic.h>
-#include <asm/irq.h>
-
-#include <mach/regs-clock.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/regs-serial.h>
-
-/* S3C2440 extended clock support */
-
-static unsigned long s3c2440_camif_upll_round(struct clk *clk,
-                                             unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       int div;
-
-       if (rate > parent_rate)
-               return parent_rate;
-
-       /* note, we remove the +/- 1 calculations for the divisor */
-
-       div = (parent_rate / rate) / 2;
-
-       if (div < 1)
-               div = 1;
-       else if (div > 16)
-               div = 16;
-
-       return parent_rate / (div * 2);
-}
-
-static int s3c2440_camif_upll_setrate(struct clk *clk, unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
-
-       rate = s3c2440_camif_upll_round(clk, rate);
-
-       camdivn &= ~(S3C2440_CAMDIVN_CAMCLK_SEL | S3C2440_CAMDIVN_CAMCLK_MASK);
-
-       if (rate != parent_rate) {
-               camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
-               camdivn |= (((parent_rate / rate) / 2) - 1);
-       }
-
-       __raw_writel(camdivn, S3C2440_CAMDIVN);
-
-       return 0;
-}
-
-/* Extra S3C2440 clocks */
-
-static struct clk s3c2440_clk_cam = {
-       .name           = "camif",
-       .enable         = s3c2410_clkcon_enable,
-       .ctrlbit        = S3C2440_CLKCON_CAMERA,
-};
-
-static struct clk s3c2440_clk_cam_upll = {
-       .name           = "camif-upll",
-       .ops            = &(struct clk_ops) {
-               .set_rate       = s3c2440_camif_upll_setrate,
-               .round_rate     = s3c2440_camif_upll_round,
-       },
-};
-
-static struct clk s3c2440_clk_ac97 = {
-       .name           = "ac97",
-       .enable         = s3c2410_clkcon_enable,
-       .ctrlbit        = S3C2440_CLKCON_CAMERA,
-};
-
-static unsigned long  s3c2440_fclk_n_getrate(struct clk *clk)
-{
-       unsigned long ucon0, ucon1, ucon2, divisor;
-
-       /* the fun of calculating the uart divisors on the s3c2440 */
-       ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON);
-       ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON);
-       ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON);
-
-       ucon0 &= S3C2440_UCON0_DIVMASK;
-       ucon1 &= S3C2440_UCON1_DIVMASK;
-       ucon2 &= S3C2440_UCON2_DIVMASK;
-
-       if (ucon0 != 0)
-               divisor = (ucon0 >> S3C2440_UCON_DIVSHIFT) + 6;
-       else if (ucon1 != 0)
-               divisor = (ucon1 >> S3C2440_UCON_DIVSHIFT) + 21;
-       else if (ucon2 != 0)
-               divisor = (ucon2 >> S3C2440_UCON_DIVSHIFT) + 36;
-       else
-               /* manual calims 44, seems to be 9 */
-               divisor = 9;
-
-       return clk_get_rate(clk->parent) / divisor;
-}
-
-static struct clk s3c2440_clk_fclk_n = {
-       .name           = "fclk_n",
-       .parent         = &clk_f,
-       .ops            = &(struct clk_ops) {
-               .get_rate       = s3c2440_fclk_n_getrate,
-       },
-};
-
-static struct clk_lookup s3c2440_clk_lookup[] = {
-       CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
-       CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
-       CLKDEV_INIT(NULL, "clk_uart_baud3", &s3c2440_clk_fclk_n),
-};
-
-static int s3c2440_clk_add(struct device *dev, struct subsys_interface *sif)
-{
-       struct clk *clock_upll;
-       struct clk *clock_h;
-       struct clk *clock_p;
-
-       clock_p = clk_get(NULL, "pclk");
-       clock_h = clk_get(NULL, "hclk");
-       clock_upll = clk_get(NULL, "upll");
-
-       if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
-               printk(KERN_ERR "S3C2440: Failed to get parent clocks\n");
-               return -EINVAL;
-       }
-
-       s3c2440_clk_cam.parent = clock_h;
-       s3c2440_clk_ac97.parent = clock_p;
-       s3c2440_clk_cam_upll.parent = clock_upll;
-       s3c24xx_register_clock(&s3c2440_clk_fclk_n);
-
-       s3c24xx_register_clock(&s3c2440_clk_ac97);
-       s3c24xx_register_clock(&s3c2440_clk_cam);
-       s3c24xx_register_clock(&s3c2440_clk_cam_upll);
-       clkdev_add_table(s3c2440_clk_lookup, ARRAY_SIZE(s3c2440_clk_lookup));
-
-       clk_disable(&s3c2440_clk_ac97);
-       clk_disable(&s3c2440_clk_cam);
-
-       return 0;
-}
-
-static struct subsys_interface s3c2440_clk_interface = {
-       .name           = "s3c2440_clk",
-       .subsys         = &s3c2440_subsys,
-       .add_dev        = s3c2440_clk_add,
-};
-
-static __init int s3c24xx_clk_init(void)
-{
-       return subsys_interface_register(&s3c2440_clk_interface);
-}
-
-arch_initcall(s3c24xx_clk_init);
diff --git a/arch/arm/mach-s3c2440/common.h b/arch/arm/mach-s3c2440/common.h
deleted file mode 100644 (file)
index 0c1eb1d..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Common Header for S3C2440 machines
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ARCH_ARM_MACH_S3C2440_COMMON_H
-#define __ARCH_ARM_MACH_S3C2440_COMMON_H
-
-void s3c244x_restart(char mode, const char *cmd);
-
-#endif /* __ARCH_ARM_MACH_S3C2440_COMMON_H */
diff --git a/arch/arm/mach-s3c2440/dma.c b/arch/arm/mach-s3c2440/dma.c
deleted file mode 100644 (file)
index 5f0a0c8..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/* linux/arch/arm/mach-s3c2440/dma.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2440 DMA selection
- *
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/serial_core.h>
-
-#include <mach/map.h>
-#include <mach/dma.h>
-
-#include <plat/dma-s3c24xx.h>
-#include <plat/cpu.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <plat/regs-ac97.h>
-#include <plat/regs-dma.h>
-#include <mach/regs-mem.h>
-#include <mach/regs-lcd.h>
-#include <mach/regs-sdi.h>
-#include <plat/regs-iis.h>
-#include <plat/regs-spi.h>
-
-static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = {
-       [DMACH_XD0] = {
-               .name           = "xdreq0",
-               .channels[0]    = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
-       },
-       [DMACH_XD1] = {
-               .name           = "xdreq1",
-               .channels[1]    = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
-       },
-       [DMACH_SDI] = {
-               .name           = "sdi",
-               .channels[0]    = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
-               .channels[1]    = S3C2440_DCON_CH1_SDI | DMA_CH_VALID,
-               .channels[2]    = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
-               .channels[3]    = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
-       },
-       [DMACH_SPI0] = {
-               .name           = "spi0",
-               .channels[1]    = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
-       },
-       [DMACH_SPI1] = {
-               .name           = "spi1",
-               .channels[3]    = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
-       },
-       [DMACH_UART0] = {
-               .name           = "uart0",
-               .channels[0]    = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
-       },
-       [DMACH_UART1] = {
-               .name           = "uart1",
-               .channels[1]    = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
-       },
-       [DMACH_UART2] = {
-               .name           = "uart2",
-               .channels[3]    = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
-       },
-       [DMACH_TIMER] = {
-               .name           = "timer",
-               .channels[0]    = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
-               .channels[2]    = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
-               .channels[3]    = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
-       },
-       [DMACH_I2S_IN] = {
-               .name           = "i2s-sdi",
-               .channels[1]    = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
-               .channels[2]    = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
-       },
-       [DMACH_I2S_OUT] = {
-               .name           = "i2s-sdo",
-               .channels[0]    = S3C2440_DCON_CH0_I2SSDO | DMA_CH_VALID,
-               .channels[2]    = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
-       },
-       [DMACH_PCM_IN] = {
-               .name           = "pcm-in",
-               .channels[0]    = S3C2440_DCON_CH0_PCMIN | DMA_CH_VALID,
-               .channels[2]    = S3C2440_DCON_CH2_PCMIN | DMA_CH_VALID,
-       },
-       [DMACH_PCM_OUT] = {
-               .name           = "pcm-out",
-               .channels[1]    = S3C2440_DCON_CH1_PCMOUT | DMA_CH_VALID,
-               .channels[3]    = S3C2440_DCON_CH3_PCMOUT | DMA_CH_VALID,
-       },
-       [DMACH_MIC_IN] = {
-               .name           = "mic-in",
-               .channels[2]    = S3C2440_DCON_CH2_MICIN | DMA_CH_VALID,
-               .channels[3]    = S3C2440_DCON_CH3_MICIN | DMA_CH_VALID,
-       },
-       [DMACH_USB_EP1] = {
-               .name           = "usb-ep1",
-               .channels[0]    = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
-       },
-       [DMACH_USB_EP2] = {
-               .name           = "usb-ep2",
-               .channels[1]    = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
-       },
-       [DMACH_USB_EP3] = {
-               .name           = "usb-ep3",
-               .channels[2]    = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
-       },
-       [DMACH_USB_EP4] = {
-               .name           = "usb-ep4",
-               .channels[3]    = S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
-       },
-};
-
-static void s3c2440_dma_select(struct s3c2410_dma_chan *chan,
-                              struct s3c24xx_dma_map *map)
-{
-       chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
-}
-
-static struct s3c24xx_dma_selection __initdata s3c2440_dma_sel = {
-       .select         = s3c2440_dma_select,
-       .dcon_mask      = 7 << 24,
-       .map            = s3c2440_dma_mappings,
-       .map_size       = ARRAY_SIZE(s3c2440_dma_mappings),
-};
-
-static struct s3c24xx_dma_order __initdata s3c2440_dma_order = {
-       .channels       = {
-               [DMACH_SDI]     = {
-                       .list   = {
-                               [0]     = 3 | DMA_CH_VALID,
-                               [1]     = 2 | DMA_CH_VALID,
-                               [2]     = 1 | DMA_CH_VALID,
-                               [3]     = 0 | DMA_CH_VALID,
-                       },
-               },
-               [DMACH_I2S_IN]  = {
-                       .list   = {
-                               [0]     = 1 | DMA_CH_VALID,
-                               [1]     = 2 | DMA_CH_VALID,
-                       },
-               },
-               [DMACH_I2S_OUT] = {
-                       .list   = {
-                               [0]     = 2 | DMA_CH_VALID,
-                               [1]     = 1 | DMA_CH_VALID,
-                       },
-               },
-               [DMACH_PCM_IN] = {
-                       .list   = {
-                               [0]     = 2 | DMA_CH_VALID,
-                               [1]     = 1 | DMA_CH_VALID,
-                       },
-               },
-               [DMACH_PCM_OUT] = {
-                       .list   = {
-                               [0]     = 1 | DMA_CH_VALID,
-                               [1]     = 3 | DMA_CH_VALID,
-                       },
-               },
-               [DMACH_MIC_IN] = {
-                       .list   = {
-                               [0]     = 3 | DMA_CH_VALID,
-                               [1]     = 2 | DMA_CH_VALID,
-                       },
-               },
-       },
-};
-
-static int __init s3c2440_dma_add(struct device *dev,
-                                 struct subsys_interface *sif)
-{
-       s3c2410_dma_init();
-       s3c24xx_dma_order_set(&s3c2440_dma_order);
-       return s3c24xx_dma_init_map(&s3c2440_dma_sel);
-}
-
-static struct subsys_interface s3c2440_dma_interface = {
-       .name           = "s3c2440_dma",
-       .subsys         = &s3c2440_subsys,
-       .add_dev        = s3c2440_dma_add,
-};
-
-static int __init s3c2440_dma_init(void)
-{
-       return subsys_interface_register(&s3c2440_dma_interface);
-}
-
-arch_initcall(s3c2440_dma_init);
-
diff --git a/arch/arm/mach-s3c2440/include/mach/gta02.h b/arch/arm/mach-s3c2440/include/mach/gta02.h
deleted file mode 100644 (file)
index 3a56a22..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-#ifndef _GTA02_H
-#define _GTA02_H
-
-#include <mach/regs-gpio.h>
-
-/* Different hardware revisions, passed in ATAG_REVISION by u-boot */
-#define GTA02v1_SYSTEM_REV     0x00000310
-#define GTA02v2_SYSTEM_REV     0x00000320
-#define GTA02v3_SYSTEM_REV     0x00000330
-#define GTA02v4_SYSTEM_REV     0x00000340
-#define GTA02v5_SYSTEM_REV     0x00000350
-/* since A7 is basically same as A6, we use A6 PCB ID */
-#define GTA02v6_SYSTEM_REV     0x00000360
-
-#define GTA02_GPIO_n3DL_GSM    S3C2410_GPA(13) /* v1 + v2 + v3 only */
-
-#define GTA02_GPIO_PWR_LED1    S3C2410_GPB(0)
-#define GTA02_GPIO_PWR_LED2    S3C2410_GPB(1)
-#define GTA02_GPIO_AUX_LED     S3C2410_GPB(2)
-#define GTA02_GPIO_VIBRATOR_ON S3C2410_GPB(3)
-#define GTA02_GPIO_MODEM_RST   S3C2410_GPB(5)
-#define GTA02_GPIO_BT_EN       S3C2410_GPB(6)
-#define GTA02_GPIO_MODEM_ON    S3C2410_GPB(7)
-#define GTA02_GPIO_EXTINT8     S3C2410_GPB(8)
-#define GTA02_GPIO_USB_PULLUP  S3C2410_GPB(9)
-
-#define GTA02_GPIO_PIO5                S3C2410_GPC(5)  /* v3 + v4 only */
-
-#define GTA02v3_GPIO_nG1_CS    S3C2410_GPD(12) /* v3 + v4 only */
-#define GTA02v3_GPIO_nG2_CS    S3C2410_GPD(13) /* v3 + v4 only */
-#define GTA02v5_GPIO_HDQ       S3C2410_GPD(14)   /* v5 + */
-
-#define GTA02_GPIO_nG1_INT     S3C2410_GPF(0)
-#define GTA02_GPIO_IO1         S3C2410_GPF(1)
-#define GTA02_GPIO_PIO_2       S3C2410_GPF(2)  /* v2 + v3 + v4 only */
-#define GTA02_GPIO_JACK_INSERT S3C2410_GPF(4)
-#define GTA02_GPIO_WLAN_GPIO1  S3C2410_GPF(5)  /* v2 + v3 + v4 only */
-#define GTA02_GPIO_AUX_KEY     S3C2410_GPF(6)
-#define GTA02_GPIO_HOLD_KEY    S3C2410_GPF(7)
-
-#define GTA02_GPIO_3D_IRQ      S3C2410_GPG(4)
-#define GTA02v2_GPIO_nG2_INT   S3C2410_GPG(8)  /* v2 + v3 + v4 only */
-#define GTA02v3_GPIO_nUSB_OC   S3C2410_GPG(9)  /* v3 + v4 only */
-#define GTA02v3_GPIO_nUSB_FLT  S3C2410_GPG(10) /* v3 + v4 only */
-#define GTA02v3_GPIO_nGSM_OC   S3C2410_GPG(11) /* v3 + v4 only */
-
-#define GTA02_GPIO_AMP_SHUT    S3C2410_GPJ(1)  /* v2 + v3 + v4 only */
-#define GTA02v1_GPIO_WLAN_GPIO10       S3C2410_GPJ(2)
-#define GTA02_GPIO_HP_IN       S3C2410_GPJ(2)  /* v2 + v3 + v4 only */
-#define GTA02_GPIO_INT0                S3C2410_GPJ(3)  /* v2 + v3 + v4 only */
-#define GTA02_GPIO_nGSM_EN     S3C2410_GPJ(4)
-#define GTA02_GPIO_3D_RESET    S3C2410_GPJ(5)
-#define GTA02_GPIO_nDL_GSM     S3C2410_GPJ(6)  /* v4 + v5 only */
-#define GTA02_GPIO_WLAN_GPIO0  S3C2410_GPJ(7)
-#define GTA02v1_GPIO_BAT_ID    S3C2410_GPJ(8)
-#define GTA02_GPIO_KEEPACT     S3C2410_GPJ(8)
-#define GTA02v1_GPIO_HP_IN     S3C2410_GPJ(10)
-#define GTA02_CHIP_PWD         S3C2410_GPJ(11) /* v2 + v3 + v4 only */
-#define GTA02_GPIO_nWLAN_RESET S3C2410_GPJ(12) /* v2 + v3 + v4 only */
-
-#define GTA02_IRQ_GSENSOR_1    IRQ_EINT0
-#define GTA02_IRQ_MODEM                IRQ_EINT1
-#define GTA02_IRQ_PIO_2                IRQ_EINT2       /* v2 + v3 + v4 only */
-#define GTA02_IRQ_nJACK_INSERT IRQ_EINT4
-#define GTA02_IRQ_WLAN_GPIO1   IRQ_EINT5
-#define GTA02_IRQ_AUX          IRQ_EINT6
-#define GTA02_IRQ_nHOLD                IRQ_EINT7
-#define GTA02_IRQ_PCF50633     IRQ_EINT9
-#define GTA02_IRQ_3D           IRQ_EINT12
-#define GTA02_IRQ_GSENSOR_2    IRQ_EINT16      /* v2 + v3 + v4 only */
-#define GTA02v3_IRQ_nUSB_OC    IRQ_EINT17      /* v3 + v4 only */
-#define GTA02v3_IRQ_nUSB_FLT   IRQ_EINT18      /* v3 + v4 only */
-#define GTA02v3_IRQ_nGSM_OC    IRQ_EINT19      /* v3 + v4 only */
-
-/* returns 00 000 on GTA02 A5 and earlier, A6 returns 01 001 */
-#define GTA02_PCB_ID1_0                S3C2410_GPC(13)
-#define GTA02_PCB_ID1_1                S3C2410_GPC(15)
-#define GTA02_PCB_ID1_2                S3C2410_GPD(0)
-#define GTA02_PCB_ID2_0                S3C2410_GPD(3)
-#define GTA02_PCB_ID2_1                S3C2410_GPD(4)
-
-int gta02_get_pcb_revision(void);
-
-#endif /* _GTA02_H */
diff --git a/arch/arm/mach-s3c2440/irq.c b/arch/arm/mach-s3c2440/irq.c
deleted file mode 100644 (file)
index 4a18cde..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/* linux/arch/arm/mach-s3c2440/irq.c
- *
- * Copyright (c) 2003-2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <asm/mach/irq.h>
-
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/irq.h>
-
-/* WDT/AC97 */
-
-static void s3c_irq_demux_wdtac97(unsigned int irq,
-                                 struct irq_desc *desc)
-{
-       unsigned int subsrc, submsk;
-
-       /* read the current pending interrupts, and the mask
-        * for what it is available */
-
-       subsrc = __raw_readl(S3C2410_SUBSRCPND);
-       submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-       subsrc &= ~submsk;
-       subsrc >>= 13;
-       subsrc &= 3;
-
-       if (subsrc != 0) {
-               if (subsrc & 1) {
-                       generic_handle_irq(IRQ_S3C2440_WDT);
-               }
-               if (subsrc & 2) {
-                       generic_handle_irq(IRQ_S3C2440_AC97);
-               }
-       }
-}
-
-
-#define INTMSK_WDT      (1UL << (IRQ_WDT - IRQ_EINT0))
-
-static void
-s3c_irq_wdtac97_mask(struct irq_data *data)
-{
-       s3c_irqsub_mask(data->irq, INTMSK_WDT, 3 << 13);
-}
-
-static void
-s3c_irq_wdtac97_unmask(struct irq_data *data)
-{
-       s3c_irqsub_unmask(data->irq, INTMSK_WDT);
-}
-
-static void
-s3c_irq_wdtac97_ack(struct irq_data *data)
-{
-       s3c_irqsub_maskack(data->irq, INTMSK_WDT, 3 << 13);
-}
-
-static struct irq_chip s3c_irq_wdtac97 = {
-       .irq_mask       = s3c_irq_wdtac97_mask,
-       .irq_unmask     = s3c_irq_wdtac97_unmask,
-       .irq_ack        = s3c_irq_wdtac97_ack,
-};
-
-static int s3c2440_irq_add(struct device *dev, struct subsys_interface *sif)
-{
-       unsigned int irqno;
-
-       printk("S3C2440: IRQ Support\n");
-
-       /* add new chained handler for wdt, ac7 */
-
-       irq_set_chip_and_handler(IRQ_WDT, &s3c_irq_level_chip,
-                                handle_level_irq);
-       irq_set_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97);
-
-       for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) {
-               irq_set_chip_and_handler(irqno, &s3c_irq_wdtac97,
-                                        handle_level_irq);
-               set_irq_flags(irqno, IRQF_VALID);
-       }
-
-       return 0;
-}
-
-static struct subsys_interface s3c2440_irq_interface = {
-       .name           = "s3c2440_irq",
-       .subsys         = &s3c2440_subsys,
-       .add_dev        = s3c2440_irq_add,
-};
-
-static int s3c2440_irq_init(void)
-{
-       return subsys_interface_register(&s3c2440_irq_interface);
-}
-
-arch_initcall(s3c2440_irq_init);
-
diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c
deleted file mode 100644 (file)
index 19b577b..0000000
+++ /dev/null
@@ -1,491 +0,0 @@
-/* linux/arch/arm/mach-s3c2440/mach-anubis.c
- *
- * Copyright 2003-2009 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/ata_platform.h>
-#include <linux/i2c.h>
-#include <linux/io.h>
-#include <linux/sm501.h>
-#include <linux/sm501-regs.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/anubis-map.h>
-#include <mach/anubis-irq.h>
-#include <mach/anubis-cpld.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-mem.h>
-#include <mach/regs-lcd.h>
-#include <plat/nand.h>
-#include <plat/iic.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include <net/ax88796.h>
-
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/audio-simtec.h>
-
-#include "common.h"
-
-#define COPYRIGHT ", Copyright 2005-2009 Simtec Electronics"
-
-static struct map_desc anubis_iodesc[] __initdata = {
-  /* ISA IO areas */
-
-  {
-       .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
-       .pfn            = __phys_to_pfn(0x0),
-       .length         = SZ_4M,
-       .type           = MT_DEVICE,
-  }, {
-       .virtual        = (u32)S3C24XX_VA_ISA_WORD,
-       .pfn            = __phys_to_pfn(0x0),
-       .length         = SZ_4M,
-       .type           = MT_DEVICE,
-  },
-
-  /* we could possibly compress the next set down into a set of smaller tables
-   * pagetables, but that would mean using an L2 section, and it still means
-   * we cannot actually feed the same register to an LDR due to 16K spacing
-   */
-
-  /* CPLD control registers */
-
-  {
-       .virtual        = (u32)ANUBIS_VA_CTRL1,
-       .pfn            = __phys_to_pfn(ANUBIS_PA_CTRL1),
-       .length         = SZ_4K,
-       .type           = MT_DEVICE,
-  }, {
-       .virtual        = (u32)ANUBIS_VA_IDREG,
-       .pfn            = __phys_to_pfn(ANUBIS_PA_IDREG),
-       .length         = SZ_4K,
-       .type           = MT_DEVICE,
-  },
-};
-
-#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-               .clk_sel        = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
-       },
-       [1] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-               .clk_sel        = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
-       },
-};
-
-/* NAND Flash on Anubis board */
-
-static int external_map[]   = { 2 };
-static int chip0_map[]      = { 0 };
-static int chip1_map[]      = { 1 };
-
-static struct mtd_partition __initdata anubis_default_nand_part[] = {
-       [0] = {
-               .name   = "Boot Agent",
-               .size   = SZ_16K,
-               .offset = 0,
-       },
-       [1] = {
-               .name   = "/boot",
-               .size   = SZ_4M - SZ_16K,
-               .offset = SZ_16K,
-       },
-       [2] = {
-               .name   = "user1",
-               .offset = SZ_4M,
-               .size   = SZ_32M - SZ_4M,
-       },
-       [3] = {
-               .name   = "user2",
-               .offset = SZ_32M,
-               .size   = MTDPART_SIZ_FULL,
-       }
-};
-
-static struct mtd_partition __initdata anubis_default_nand_part_large[] = {
-       [0] = {
-               .name   = "Boot Agent",
-               .size   = SZ_128K,
-               .offset = 0,
-       },
-       [1] = {
-               .name   = "/boot",
-               .size   = SZ_4M - SZ_128K,
-               .offset = SZ_128K,
-       },
-       [2] = {
-               .name   = "user1",
-               .offset = SZ_4M,
-               .size   = SZ_32M - SZ_4M,
-       },
-       [3] = {
-               .name   = "user2",
-               .offset = SZ_32M,
-               .size   = MTDPART_SIZ_FULL,
-       }
-};
-
-/* the Anubis has 3 selectable slots for nand-flash, the two
- * on-board chip areas, as well as the external slot.
- *
- * Note, there is no current hot-plug support for the External
- * socket.
-*/
-
-static struct s3c2410_nand_set __initdata anubis_nand_sets[] = {
-       [1] = {
-               .name           = "External",
-               .nr_chips       = 1,
-               .nr_map         = external_map,
-               .nr_partitions  = ARRAY_SIZE(anubis_default_nand_part),
-               .partitions     = anubis_default_nand_part,
-       },
-       [0] = {
-               .name           = "chip0",
-               .nr_chips       = 1,
-               .nr_map         = chip0_map,
-               .nr_partitions  = ARRAY_SIZE(anubis_default_nand_part),
-               .partitions     = anubis_default_nand_part,
-       },
-       [2] = {
-               .name           = "chip1",
-               .nr_chips       = 1,
-               .nr_map         = chip1_map,
-               .nr_partitions  = ARRAY_SIZE(anubis_default_nand_part),
-               .partitions     = anubis_default_nand_part,
-       },
-};
-
-static void anubis_nand_select(struct s3c2410_nand_set *set, int slot)
-{
-       unsigned int tmp;
-
-       slot = set->nr_map[slot] & 3;
-
-       pr_debug("anubis_nand: selecting slot %d (set %p,%p)\n",
-                slot, set, set->nr_map);
-
-       tmp = __raw_readb(ANUBIS_VA_CTRL1);
-       tmp &= ~ANUBIS_CTRL1_NANDSEL;
-       tmp |= slot;
-
-       pr_debug("anubis_nand: ctrl1 now %02x\n", tmp);
-
-       __raw_writeb(tmp, ANUBIS_VA_CTRL1);
-}
-
-static struct s3c2410_platform_nand __initdata anubis_nand_info = {
-       .tacls          = 25,
-       .twrph0         = 55,
-       .twrph1         = 40,
-       .nr_sets        = ARRAY_SIZE(anubis_nand_sets),
-       .sets           = anubis_nand_sets,
-       .select_chip    = anubis_nand_select,
-};
-
-/* IDE channels */
-
-static struct pata_platform_info anubis_ide_platdata = {
-       .ioport_shift   = 5,
-};
-
-static struct resource anubis_ide0_resource[] = {
-       {
-               .start  = S3C2410_CS3,
-               .end    = S3C2410_CS3 + (8*32) - 1,
-               .flags  = IORESOURCE_MEM,
-       }, {
-               .start  = S3C2410_CS3 + (1<<26) + (6*32),
-               .end    = S3C2410_CS3 + (1<<26) + (7*32) - 1,
-               .flags  = IORESOURCE_MEM,
-       }, {
-               .start  = IRQ_IDE0,
-               .end    = IRQ_IDE0,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device anubis_device_ide0 = {
-       .name           = "pata_platform",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(anubis_ide0_resource),
-       .resource       = anubis_ide0_resource,
-       .dev    = {
-               .platform_data = &anubis_ide_platdata,
-               .coherent_dma_mask = ~0,
-       },
-};
-
-static struct resource anubis_ide1_resource[] = {
-       {
-               .start  = S3C2410_CS4,
-               .end    = S3C2410_CS4 + (8*32) - 1,
-               .flags  = IORESOURCE_MEM,
-       }, {
-               .start  = S3C2410_CS4 + (1<<26) + (6*32),
-               .end    = S3C2410_CS4 + (1<<26) + (7*32) - 1,
-               .flags  = IORESOURCE_MEM,
-       }, {
-               .start  = IRQ_IDE0,
-               .end    = IRQ_IDE0,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device anubis_device_ide1 = {
-       .name           = "pata_platform",
-       .id             = 1,
-       .num_resources  = ARRAY_SIZE(anubis_ide1_resource),
-       .resource       = anubis_ide1_resource,
-       .dev    = {
-               .platform_data = &anubis_ide_platdata,
-               .coherent_dma_mask = ~0,
-       },
-};
-
-/* Asix AX88796 10/100 ethernet controller */
-
-static struct ax_plat_data anubis_asix_platdata = {
-       .flags          = AXFLG_MAC_FROMDEV,
-       .wordlength     = 2,
-       .dcr_val        = 0x48,
-       .rcr_val        = 0x40,
-};
-
-static struct resource anubis_asix_resource[] = {
-       [0] = {
-               .start = S3C2410_CS5,
-               .end   = S3C2410_CS5 + (0x20 * 0x20) -1,
-               .flags = IORESOURCE_MEM
-       },
-       [1] = {
-               .start = IRQ_ASIX,
-               .end   = IRQ_ASIX,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-static struct platform_device anubis_device_asix = {
-       .name           = "ax88796",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(anubis_asix_resource),
-       .resource       = anubis_asix_resource,
-       .dev            = {
-               .platform_data = &anubis_asix_platdata,
-       }
-};
-
-/* SM501 */
-
-static struct resource anubis_sm501_resource[] = {
-       [0] = {
-               .start  = S3C2410_CS2,
-               .end    = S3C2410_CS2 + SZ_8M,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = S3C2410_CS2 + SZ_64M - SZ_2M,
-               .end    = S3C2410_CS2 + SZ_64M - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [2] = {
-               .start  = IRQ_EINT0,
-               .end    = IRQ_EINT0,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct sm501_initdata anubis_sm501_initdata = {
-       .gpio_high      = {
-               .set    = 0x3F000000,           /* 24bit panel */
-               .mask   = 0x0,
-       },
-       .misc_timing    = {
-               .set    = 0x010100,             /* SDRAM timing */
-               .mask   = 0x1F1F00,
-       },
-       .misc_control   = {
-               .set    = SM501_MISC_PNL_24BIT,
-               .mask   = 0,
-       },
-
-       .devices        = SM501_USE_GPIO,
-
-       /* set the SDRAM and bus clocks */
-       .mclk           = 72 * MHZ,
-       .m1xclk         = 144 * MHZ,
-};
-
-static struct sm501_platdata_gpio_i2c anubis_sm501_gpio_i2c[] = {
-       [0] = {
-               .bus_num        = 1,
-               .pin_scl        = 44,
-               .pin_sda        = 45,
-       },
-       [1] = {
-               .bus_num        = 2,
-               .pin_scl        = 40,
-               .pin_sda        = 41,
-       },
-};
-
-static struct sm501_platdata anubis_sm501_platdata = {
-       .init           = &anubis_sm501_initdata,
-       .gpio_base      = -1,
-       .gpio_i2c       = anubis_sm501_gpio_i2c,
-       .gpio_i2c_nr    = ARRAY_SIZE(anubis_sm501_gpio_i2c),
-};
-
-static struct platform_device anubis_device_sm501 = {
-       .name           = "sm501",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(anubis_sm501_resource),
-       .resource       = anubis_sm501_resource,
-       .dev            = {
-               .platform_data = &anubis_sm501_platdata,
-       },
-};
-
-/* Standard Anubis devices */
-
-static struct platform_device *anubis_devices[] __initdata = {
-       &s3c_device_ohci,
-       &s3c_device_wdt,
-       &s3c_device_adc,
-       &s3c_device_i2c0,
-       &s3c_device_rtc,
-       &s3c_device_nand,
-       &anubis_device_ide0,
-       &anubis_device_ide1,
-       &anubis_device_asix,
-       &anubis_device_sm501,
-};
-
-static struct clk *anubis_clocks[] __initdata = {
-       &s3c24xx_dclk0,
-       &s3c24xx_dclk1,
-       &s3c24xx_clkout0,
-       &s3c24xx_clkout1,
-       &s3c24xx_uclk,
-};
-
-/* I2C devices. */
-
-static struct i2c_board_info anubis_i2c_devs[] __initdata = {
-       {
-               I2C_BOARD_INFO("tps65011", 0x48),
-               .irq    = IRQ_EINT20,
-       }
-};
-
-/* Audio setup */
-static struct s3c24xx_audio_simtec_pdata __initdata anubis_audio = {
-       .have_mic       = 1,
-       .have_lout      = 1,
-       .output_cdclk   = 1,
-       .use_mpllin     = 1,
-       .amp_gpio       = S3C2410_GPB(2),
-       .amp_gain[0]    = S3C2410_GPD(10),
-       .amp_gain[1]    = S3C2410_GPD(11),
-};
-
-static void __init anubis_map_io(void)
-{
-       /* initialise the clocks */
-
-       s3c24xx_dclk0.parent = &clk_upll;
-       s3c24xx_dclk0.rate   = 12*1000*1000;
-
-       s3c24xx_dclk1.parent = &clk_upll;
-       s3c24xx_dclk1.rate   = 24*1000*1000;
-
-       s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
-       s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
-
-       s3c24xx_uclk.parent  = &s3c24xx_clkout1;
-
-       s3c24xx_register_clocks(anubis_clocks, ARRAY_SIZE(anubis_clocks));
-
-       s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
-       s3c24xx_init_clocks(0);
-       s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
-
-       /* check for the newer revision boards with large page nand */
-
-       if ((__raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK) >= 4) {
-               printk(KERN_INFO "ANUBIS-B detected (revision %d)\n",
-                      __raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK);
-               anubis_nand_sets[0].partitions = anubis_default_nand_part_large;
-               anubis_nand_sets[0].nr_partitions = ARRAY_SIZE(anubis_default_nand_part_large);
-       } else {
-               /* ensure that the GPIO is setup */
-               s3c2410_gpio_setpin(S3C2410_GPA(0), 1);
-       }
-}
-
-static void __init anubis_init(void)
-{
-       s3c_i2c0_set_platdata(NULL);
-       s3c_nand_set_platdata(&anubis_nand_info);
-       simtec_audio_add(NULL, false, &anubis_audio);
-
-       platform_add_devices(anubis_devices, ARRAY_SIZE(anubis_devices));
-
-       i2c_register_board_info(0, anubis_i2c_devs,
-                               ARRAY_SIZE(anubis_i2c_devs));
-}
-
-
-MACHINE_START(ANUBIS, "Simtec-Anubis")
-       /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
-       .atag_offset    = 0x100,
-       .map_io         = anubis_map_io,
-       .init_machine   = anubis_init,
-       .init_irq       = s3c24xx_init_irq,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c244x_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-at2440evb.c b/arch/arm/mach-s3c2440/mach-at2440evb.c
deleted file mode 100644 (file)
index d7ae49c..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/* linux/arch/arm/mach-s3c2440/mach-at2440evb.c
- *
- * Copyright (c) 2008 Ramax Lo <ramaxlo@gmail.com>
- *      Based on mach-anubis.c by Ben Dooks <ben@simtec.co.uk>
- *      and modifications by SBZ <sbz@spgui.org> and
- *      Weibing <http://weibing.blogbus.com>
- *
- * For product information, visit http://www.arm.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/serial_core.h>
-#include <linux/dm9000.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/fb.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-mem.h>
-#include <mach/regs-lcd.h>
-#include <plat/nand.h>
-#include <plat/iic.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/mci.h>
-
-#include "common.h"
-
-static struct map_desc at2440evb_iodesc[] __initdata = {
-       /* Nothing here */
-};
-
-#define UCON S3C2410_UCON_DEFAULT
-#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
-#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
-
-static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-               .clk_sel        = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-               .clk_sel        = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
-       },
-};
-
-/* NAND Flash on AT2440EVB board */
-
-static struct mtd_partition __initdata at2440evb_default_nand_part[] = {
-       [0] = {
-               .name   = "Boot Agent",
-               .size   = SZ_256K,
-               .offset = 0,
-       },
-       [1] = {
-               .name   = "Kernel",
-               .size   = SZ_2M,
-               .offset = SZ_256K,
-       },
-       [2] = {
-               .name   = "Root",
-               .offset = SZ_256K + SZ_2M,
-               .size   = MTDPART_SIZ_FULL,
-       },
-};
-
-static struct s3c2410_nand_set __initdata at2440evb_nand_sets[] = {
-       [0] = {
-               .name           = "nand",
-               .nr_chips       = 1,
-               .nr_partitions  = ARRAY_SIZE(at2440evb_default_nand_part),
-               .partitions     = at2440evb_default_nand_part,
-       },
-};
-
-static struct s3c2410_platform_nand __initdata at2440evb_nand_info = {
-       .tacls          = 25,
-       .twrph0         = 55,
-       .twrph1         = 40,
-       .nr_sets        = ARRAY_SIZE(at2440evb_nand_sets),
-       .sets           = at2440evb_nand_sets,
-};
-
-/* DM9000AEP 10/100 ethernet controller */
-
-static struct resource at2440evb_dm9k_resource[] = {
-       [0] = {
-               .start = S3C2410_CS3,
-               .end   = S3C2410_CS3 + 3,
-               .flags = IORESOURCE_MEM
-       },
-       [1] = {
-               .start = S3C2410_CS3 + 4,
-               .end   = S3C2410_CS3 + 7,
-               .flags = IORESOURCE_MEM
-       },
-       [2] = {
-               .start = IRQ_EINT7,
-               .end   = IRQ_EINT7,
-               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
-       }
-};
-
-static struct dm9000_plat_data at2440evb_dm9k_pdata = {
-       .flags          = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
-};
-
-static struct platform_device at2440evb_device_eth = {
-       .name           = "dm9000",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(at2440evb_dm9k_resource),
-       .resource       = at2440evb_dm9k_resource,
-       .dev            = {
-               .platform_data  = &at2440evb_dm9k_pdata,
-       },
-};
-
-static struct s3c24xx_mci_pdata at2440evb_mci_pdata __initdata = {
-       .gpio_detect    = S3C2410_GPG(10),
-};
-
-/* 7" LCD panel */
-
-static struct s3c2410fb_display at2440evb_lcd_cfg __initdata = {
-
-       .lcdcon5        = S3C2410_LCDCON5_FRM565 |
-                         S3C2410_LCDCON5_INVVLINE |
-                         S3C2410_LCDCON5_INVVFRAME |
-                         S3C2410_LCDCON5_PWREN |
-                         S3C2410_LCDCON5_HWSWP,
-
-       .type           = S3C2410_LCDCON1_TFT,
-
-       .width          = 800,
-       .height         = 480,
-
-       .pixclock       = 33333, /* HCLK 60 MHz, divisor 2 */
-       .xres           = 800,
-       .yres           = 480,
-       .bpp            = 16,
-       .left_margin    = 88,
-       .right_margin   = 40,
-       .hsync_len      = 128,
-       .upper_margin   = 32,
-       .lower_margin   = 11,
-       .vsync_len      = 2,
-};
-
-static struct s3c2410fb_mach_info at2440evb_fb_info __initdata = {
-       .displays       = &at2440evb_lcd_cfg,
-       .num_displays   = 1,
-       .default_display = 0,
-};
-
-static struct platform_device *at2440evb_devices[] __initdata = {
-       &s3c_device_ohci,
-       &s3c_device_wdt,
-       &s3c_device_adc,
-       &s3c_device_i2c0,
-       &s3c_device_rtc,
-       &s3c_device_nand,
-       &s3c_device_sdi,
-       &s3c_device_lcd,
-       &at2440evb_device_eth,
-};
-
-static void __init at2440evb_map_io(void)
-{
-       s3c24xx_init_io(at2440evb_iodesc, ARRAY_SIZE(at2440evb_iodesc));
-       s3c24xx_init_clocks(16934400);
-       s3c24xx_init_uarts(at2440evb_uartcfgs, ARRAY_SIZE(at2440evb_uartcfgs));
-}
-
-static void __init at2440evb_init(void)
-{
-       s3c24xx_fb_set_platdata(&at2440evb_fb_info);
-       s3c24xx_mci_set_platdata(&at2440evb_mci_pdata);
-       s3c_nand_set_platdata(&at2440evb_nand_info);
-       s3c_i2c0_set_platdata(NULL);
-
-       platform_add_devices(at2440evb_devices, ARRAY_SIZE(at2440evb_devices));
-}
-
-
-MACHINE_START(AT2440EVB, "AT2440EVB")
-       .atag_offset    = 0x100,
-       .map_io         = at2440evb_map_io,
-       .init_machine   = at2440evb_init,
-       .init_irq       = s3c24xx_init_irq,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c244x_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
deleted file mode 100644 (file)
index 9a4a5bc..0000000
+++ /dev/null
@@ -1,605 +0,0 @@
-/*
- * linux/arch/arm/mach-s3c2442/mach-gta02.c
- *
- * S3C2442 Machine Support for Openmoko GTA02 / FreeRunner.
- *
- * Copyright (C) 2006-2009 by Openmoko, Inc.
- * Authors: Harald Welte <laforge@openmoko.org>
- *          Andy Green <andy@openmoko.org>
- *          Werner Almesberger <werner@openmoko.org>
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/spi/spi.h>
-
-#include <linux/mmc/host.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
-#include <linux/io.h>
-
-#include <linux/i2c.h>
-#include <linux/regulator/machine.h>
-
-#include <linux/mfd/pcf50633/core.h>
-#include <linux/mfd/pcf50633/mbc.h>
-#include <linux/mfd/pcf50633/adc.h>
-#include <linux/mfd/pcf50633/gpio.h>
-#include <linux/mfd/pcf50633/pmic.h>
-#include <linux/mfd/pcf50633/backlight.h>
-
-#include <linux/input.h>
-#include <linux/gpio_keys.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-gpioj.h>
-#include <mach/fb.h>
-
-#include <mach/spi.h>
-#include <plat/usb-control.h>
-#include <mach/regs-mem.h>
-#include <mach/hardware.h>
-
-#include <mach/gta02.h>
-
-#include <plat/regs-serial.h>
-#include <plat/nand.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/udc.h>
-#include <plat/gpio-cfg.h>
-#include <plat/iic.h>
-#include <plat/ts.h>
-
-#include "common.h"
-
-static struct pcf50633 *gta02_pcf;
-
-/*
- * This gets called frequently when we paniced.
- */
-
-static long gta02_panic_blink(int state)
-{
-       long delay = 0;
-       char led;
-
-       led = (state) ? 1 : 0;
-       gpio_direction_output(GTA02_GPIO_AUX_LED, led);
-
-       return delay;
-}
-
-
-static struct map_desc gta02_iodesc[] __initdata = {
-       {
-               .virtual        = 0xe0000000,
-               .pfn            = __phys_to_pfn(S3C2410_CS3 + 0x01000000),
-               .length         = SZ_1M,
-               .type           = MT_DEVICE
-       },
-};
-
-#define UCON (S3C2410_UCON_DEFAULT | S3C2443_UCON_RXERR_IRQEN)
-#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
-#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
-
-static struct s3c2410_uartcfg gta02_uartcfgs[] = {
-       [0] = {
-               .hwport         = 0,
-               .flags          = 0,
-               .ucon           = UCON,
-               .ulcon          = ULCON,
-               .ufcon          = UFCON,
-       },
-       [1] = {
-               .hwport         = 1,
-               .flags          = 0,
-               .ucon           = UCON,
-               .ulcon          = ULCON,
-               .ufcon          = UFCON,
-       },
-       [2] = {
-               .hwport         = 2,
-               .flags          = 0,
-               .ucon           = UCON,
-               .ulcon          = ULCON,
-               .ufcon          = UFCON,
-       },
-};
-
-#ifdef CONFIG_CHARGER_PCF50633
-/*
- * On GTA02 the 1A charger features a 48K resistor to 0V on the ID pin.
- * We use this to recognize that we can pull 1A from the USB socket.
- *
- * These constants are the measured pcf50633 ADC levels with the 1A
- * charger / 48K resistor, and with no pulldown resistor.
- */
-
-#define ADC_NOM_CHG_DETECT_1A 6
-#define ADC_NOM_CHG_DETECT_USB 43
-
-static void
-gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res)
-{
-       int  ma;
-
-       /* Interpret charger type */
-       if (res < ((ADC_NOM_CHG_DETECT_USB + ADC_NOM_CHG_DETECT_1A) / 2)) {
-
-               /*
-                * Sanity - stop GPO driving out now that we have a 1A charger
-                * GPO controls USB Host power generation on GTA02
-                */
-               pcf50633_gpio_set(pcf, PCF50633_GPO, 0);
-
-               ma = 1000;
-       } else
-               ma = 100;
-
-       pcf50633_mbc_usb_curlim_set(pcf, ma);
-}
-
-static struct delayed_work gta02_charger_work;
-static int gta02_usb_vbus_draw;
-
-static void gta02_charger_worker(struct work_struct *work)
-{
-       if (gta02_usb_vbus_draw) {
-               pcf50633_mbc_usb_curlim_set(gta02_pcf, gta02_usb_vbus_draw);
-               return;
-       }
-
-#ifdef CONFIG_PCF50633_ADC
-       pcf50633_adc_async_read(gta02_pcf,
-                               PCF50633_ADCC1_MUX_ADCIN1,
-                               PCF50633_ADCC1_AVERAGE_16,
-                               gta02_configure_pmu_for_charger,
-                               NULL);
-#else
-       /*
-        * If the PCF50633 ADC is disabled we fallback to a
-        * 100mA limit for safety.
-        */
-       pcf50633_mbc_usb_curlim_set(pcf, 100);
-#endif
-}
-
-#define GTA02_CHARGER_CONFIGURE_TIMEOUT ((3000 * HZ) / 1000)
-
-static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq)
-{
-       if (irq == PCF50633_IRQ_USBINS) {
-               schedule_delayed_work(&gta02_charger_work,
-                                     GTA02_CHARGER_CONFIGURE_TIMEOUT);
-
-               return;
-       }
-
-       if (irq == PCF50633_IRQ_USBREM) {
-               cancel_delayed_work_sync(&gta02_charger_work);
-               gta02_usb_vbus_draw = 0;
-       }
-}
-
-static void gta02_udc_vbus_draw(unsigned int ma)
-{
-       if (!gta02_pcf)
-               return;
-
-       gta02_usb_vbus_draw = ma;
-
-       schedule_delayed_work(&gta02_charger_work,
-                             GTA02_CHARGER_CONFIGURE_TIMEOUT);
-}
-#else /* !CONFIG_CHARGER_PCF50633 */
-#define gta02_pmu_event_callback       NULL
-#define gta02_udc_vbus_draw            NULL
-#endif
-
-/*
- * This is called when pc50633 is probed, unfortunately quite late in the
- * day since it is an I2C bus device. Here we can belatedly define some
- * platform devices with the advantage that we can mark the pcf50633 as the
- * parent. This makes them get suspended and resumed with their parent
- * the pcf50633 still around.
- */
-
-static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf);
-
-
-static char *gta02_batteries[] = {
-       "battery",
-};
-
-static struct pcf50633_bl_platform_data gta02_backlight_data = {
-       .default_brightness = 0x3f,
-       .default_brightness_limit = 0,
-       .ramp_time = 5,
-};
-
-struct pcf50633_platform_data gta02_pcf_pdata = {
-       .resumers = {
-               [0] =   PCF50633_INT1_USBINS |
-                       PCF50633_INT1_USBREM |
-                       PCF50633_INT1_ALARM,
-               [1] =   PCF50633_INT2_ONKEYF,
-               [2] =   PCF50633_INT3_ONKEY1S,
-               [3] =   PCF50633_INT4_LOWSYS |
-                       PCF50633_INT4_LOWBAT |
-                       PCF50633_INT4_HIGHTMP,
-       },
-
-       .batteries = gta02_batteries,
-       .num_batteries = ARRAY_SIZE(gta02_batteries),
-
-       .charger_reference_current_ma = 1000,
-
-       .backlight_data = &gta02_backlight_data,
-
-       .reg_init_data = {
-               [PCF50633_REGULATOR_AUTO] = {
-                       .constraints = {
-                               .min_uV = 3300000,
-                               .max_uV = 3300000,
-                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
-                               .always_on = 1,
-                               .apply_uV = 1,
-                       },
-               },
-               [PCF50633_REGULATOR_DOWN1] = {
-                       .constraints = {
-                               .min_uV = 1300000,
-                               .max_uV = 1600000,
-                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
-                               .always_on = 1,
-                               .apply_uV = 1,
-                       },
-               },
-               [PCF50633_REGULATOR_DOWN2] = {
-                       .constraints = {
-                               .min_uV = 1800000,
-                               .max_uV = 1800000,
-                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
-                               .apply_uV = 1,
-                               .always_on = 1,
-                       },
-               },
-               [PCF50633_REGULATOR_HCLDO] = {
-                       .constraints = {
-                               .min_uV = 2000000,
-                               .max_uV = 3300000,
-                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
-                               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
-                                               REGULATOR_CHANGE_STATUS,
-                       },
-               },
-               [PCF50633_REGULATOR_LDO1] = {
-                       .constraints = {
-                               .min_uV = 3300000,
-                               .max_uV = 3300000,
-                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
-                               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-                               .apply_uV = 1,
-                       },
-               },
-               [PCF50633_REGULATOR_LDO2] = {
-                       .constraints = {
-                               .min_uV = 3300000,
-                               .max_uV = 3300000,
-                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
-                               .apply_uV = 1,
-                       },
-               },
-               [PCF50633_REGULATOR_LDO3] = {
-                       .constraints = {
-                               .min_uV = 3000000,
-                               .max_uV = 3000000,
-                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
-                               .apply_uV = 1,
-                       },
-               },
-               [PCF50633_REGULATOR_LDO4] = {
-                       .constraints = {
-                               .min_uV = 3200000,
-                               .max_uV = 3200000,
-                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
-                               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-                               .apply_uV = 1,
-                       },
-               },
-               [PCF50633_REGULATOR_LDO5] = {
-                       .constraints = {
-                               .min_uV = 3000000,
-                               .max_uV = 3000000,
-                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
-                               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-                               .apply_uV = 1,
-                       },
-               },
-               [PCF50633_REGULATOR_LDO6] = {
-                       .constraints = {
-                               .min_uV = 3000000,
-                               .max_uV = 3000000,
-                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
-                       },
-               },
-               [PCF50633_REGULATOR_MEMLDO] = {
-                       .constraints = {
-                               .min_uV = 1800000,
-                               .max_uV = 1800000,
-                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
-                       },
-               },
-
-       },
-       .probe_done = gta02_pmu_attach_child_devices,
-       .mbc_event_callback = gta02_pmu_event_callback,
-};
-
-
-/* NOR Flash. */
-
-#define GTA02_FLASH_BASE       0x18000000 /* GCS3 */
-#define GTA02_FLASH_SIZE       0x200000 /* 2MBytes */
-
-static struct physmap_flash_data gta02_nor_flash_data = {
-       .width          = 2,
-};
-
-static struct resource gta02_nor_flash_resource = {
-       .start          = GTA02_FLASH_BASE,
-       .end            = GTA02_FLASH_BASE + GTA02_FLASH_SIZE - 1,
-       .flags          = IORESOURCE_MEM,
-};
-
-static struct platform_device gta02_nor_flash = {
-       .name           = "physmap-flash",
-       .id             = 0,
-       .dev            = {
-               .platform_data  = &gta02_nor_flash_data,
-       },
-       .resource       = &gta02_nor_flash_resource,
-       .num_resources  = 1,
-};
-
-
-struct platform_device s3c24xx_pwm_device = {
-       .name           = "s3c24xx_pwm",
-       .num_resources  = 0,
-};
-
-static struct platform_device gta02_dfbmcs320_device = {
-       .name = "dfbmcs320",
-};
-
-static struct i2c_board_info gta02_i2c_devs[] __initdata = {
-       {
-               I2C_BOARD_INFO("pcf50633", 0x73),
-               .irq = GTA02_IRQ_PCF50633,
-               .platform_data = &gta02_pcf_pdata,
-       },
-       {
-               I2C_BOARD_INFO("wm8753", 0x1a),
-       },
-};
-
-static struct s3c2410_nand_set __initdata gta02_nand_sets[] = {
-       [0] = {
-               /*
-                * This name is also hard-coded in the boot loaders, so
-                * changing it would would require all users to upgrade
-                * their boot loaders, some of which are stored in a NOR
-                * that is considered to be immutable.
-                */
-               .name           = "neo1973-nand",
-               .nr_chips       = 1,
-               .flash_bbt      = 1,
-       },
-};
-
-/*
- * Choose a set of timings derived from S3C@2442B MCP54
- * data sheet (K5D2G13ACM-D075 MCP Memory).
- */
-
-static struct s3c2410_platform_nand __initdata gta02_nand_info = {
-       .tacls          = 0,
-       .twrph0         = 25,
-       .twrph1         = 15,
-       .nr_sets        = ARRAY_SIZE(gta02_nand_sets),
-       .sets           = gta02_nand_sets,
-};
-
-
-/* Get PMU to set USB current limit accordingly. */
-static struct s3c2410_udc_mach_info gta02_udc_cfg __initdata = {
-       .vbus_draw      = gta02_udc_vbus_draw,
-       .pullup_pin = GTA02_GPIO_USB_PULLUP,
-};
-
-/* USB */
-static struct s3c2410_hcd_info gta02_usb_info __initdata = {
-       .port[0]        = {
-               .flags  = S3C_HCDFLG_USED,
-       },
-       .port[1]        = {
-               .flags  = 0,
-       },
-};
-
-/* Touchscreen */
-static struct s3c2410_ts_mach_info gta02_ts_info = {
-       .delay                  = 10000,
-       .presc                  = 0xff, /* slow as we can go */
-       .oversampling_shift     = 2,
-};
-
-/* Buttons */
-static struct gpio_keys_button gta02_buttons[] = {
-       {
-               .gpio = GTA02_GPIO_AUX_KEY,
-               .code = KEY_PHONE,
-               .desc = "Aux",
-               .type = EV_KEY,
-               .debounce_interval = 100,
-       },
-       {
-               .gpio = GTA02_GPIO_HOLD_KEY,
-               .code = KEY_PAUSE,
-               .desc = "Hold",
-               .type = EV_KEY,
-               .debounce_interval = 100,
-       },
-};
-
-static struct gpio_keys_platform_data gta02_buttons_pdata = {
-       .buttons = gta02_buttons,
-       .nbuttons = ARRAY_SIZE(gta02_buttons),
-};
-
-static struct platform_device gta02_buttons_device = {
-       .name = "gpio-keys",
-       .id = -1,
-       .dev = {
-               .platform_data = &gta02_buttons_pdata,
-       },
-};
-
-static void __init gta02_map_io(void)
-{
-       s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc));
-       s3c24xx_init_clocks(12000000);
-       s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs));
-}
-
-
-/* These are the guys that don't need to be children of PMU. */
-
-static struct platform_device *gta02_devices[] __initdata = {
-       &s3c_device_ohci,
-       &s3c_device_wdt,
-       &s3c_device_sdi,
-       &s3c_device_usbgadget,
-       &s3c_device_nand,
-       &gta02_nor_flash,
-       &s3c24xx_pwm_device,
-       &s3c_device_iis,
-       &samsung_asoc_dma,
-       &s3c_device_i2c0,
-       &gta02_dfbmcs320_device,
-       &gta02_buttons_device,
-       &s3c_device_adc,
-       &s3c_device_ts,
-};
-
-/* These guys DO need to be children of PMU. */
-
-static struct platform_device *gta02_devices_pmu_children[] = {
-};
-
-
-/*
- * This is called when pc50633 is probed, quite late in the day since it is an
- * I2C bus device.  Here we can define platform devices with the advantage that
- * we can mark the pcf50633 as the parent.  This makes them get suspended and
- * resumed with their parent the pcf50633 still around.  All devices whose
- * operation depends on something from pcf50633 must have this relationship
- * made explicit like this, or suspend and resume will become an unreliable
- * hellworld.
- */
-
-static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf)
-{
-       int n;
-
-       /* Grab a copy of the now probed PMU pointer. */
-       gta02_pcf = pcf;
-
-       for (n = 0; n < ARRAY_SIZE(gta02_devices_pmu_children); n++)
-               gta02_devices_pmu_children[n]->dev.parent = pcf->dev;
-
-       platform_add_devices(gta02_devices_pmu_children,
-                            ARRAY_SIZE(gta02_devices_pmu_children));
-}
-
-static void gta02_poweroff(void)
-{
-       pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1);
-}
-
-static void __init gta02_machine_init(void)
-{
-       /* Set the panic callback to turn AUX LED on or off. */
-       panic_blink = gta02_panic_blink;
-
-       s3c_pm_init();
-
-#ifdef CONFIG_CHARGER_PCF50633
-       INIT_DELAYED_WORK(&gta02_charger_work, gta02_charger_worker);
-#endif
-
-       s3c24xx_udc_set_platdata(&gta02_udc_cfg);
-       s3c24xx_ts_set_platdata(&gta02_ts_info);
-       s3c_ohci_set_platdata(&gta02_usb_info);
-       s3c_nand_set_platdata(&gta02_nand_info);
-       s3c_i2c0_set_platdata(NULL);
-
-       i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs));
-
-       platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
-       pm_power_off = gta02_poweroff;
-
-       regulator_has_full_constraints();
-}
-
-
-MACHINE_START(NEO1973_GTA02, "GTA02")
-       /* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */
-       .atag_offset    = 0x100,
-       .map_io         = gta02_map_io,
-       .init_irq       = s3c24xx_init_irq,
-       .init_machine   = gta02_machine_init,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c244x_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c2440/mach-mini2440.c
deleted file mode 100644 (file)
index 5d66fb2..0000000
+++ /dev/null
@@ -1,705 +0,0 @@
-/* linux/arch/arm/mach-s3c2440/mach-mini2440.c
- *
- * Copyright (c) 2008 Ramax Lo <ramaxlo@gmail.com>
- *      Based on mach-anubis.c by Ben Dooks <ben@simtec.co.uk>
- *      and modifications by SBZ <sbz@spgui.org> and
- *      Weibing <http://weibing.blogbus.com> and
- *      Michel Pollet <buserror@gmail.com>
- *
- * For product information, visit http://code.google.com/p/mini2440/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/input.h>
-#include <linux/io.h>
-#include <linux/serial_core.h>
-#include <linux/dm9000.h>
-#include <linux/i2c/at24.h>
-#include <linux/platform_device.h>
-#include <linux/gpio_keys.h>
-#include <linux/i2c.h>
-#include <linux/mmc/host.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/hardware.h>
-#include <mach/fb.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <mach/leds-gpio.h>
-#include <mach/regs-mem.h>
-#include <mach/regs-lcd.h>
-#include <mach/irqs.h>
-#include <plat/nand.h>
-#include <plat/iic.h>
-#include <plat/mci.h>
-#include <plat/udc.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include <plat/gpio-cfg.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#include <sound/s3c24xx_uda134x.h>
-
-#include "common.h"
-
-#define MACH_MINI2440_DM9K_BASE (S3C2410_CS4 + 0x300)
-
-static struct map_desc mini2440_iodesc[] __initdata = {
-       /* nothing to declare, move along */
-};
-
-#define UCON S3C2410_UCON_DEFAULT
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-
-static struct s3c2410_uartcfg mini2440_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-};
-
-/* USB device UDC support */
-
-static struct s3c2410_udc_mach_info mini2440_udc_cfg __initdata = {
-       .pullup_pin = S3C2410_GPC(5),
-};
-
-
-/* LCD timing and setup */
-
-/*
- * This macro simplifies the table bellow
- */
-#define _LCD_DECLARE(_clock,_xres,margin_left,margin_right,hsync, \
-                       _yres,margin_top,margin_bottom,vsync, refresh) \
-       .width = _xres, \
-       .xres = _xres, \
-       .height = _yres, \
-       .yres = _yres, \
-       .left_margin    = margin_left,  \
-       .right_margin   = margin_right, \
-       .upper_margin   = margin_top,   \
-       .lower_margin   = margin_bottom,        \
-       .hsync_len      = hsync,        \
-       .vsync_len      = vsync,        \
-       .pixclock       = ((_clock*100000000000LL) /    \
-                          ((refresh) * \
-                          (hsync + margin_left + _xres + margin_right) * \
-                          (vsync + margin_top + _yres + margin_bottom))), \
-       .bpp            = 16,\
-       .type           = (S3C2410_LCDCON1_TFT16BPP |\
-                          S3C2410_LCDCON1_TFT)
-
-static struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = {
-       [0] = { /* mini2440 + 3.5" TFT + touchscreen */
-               _LCD_DECLARE(
-                       7,                      /* The 3.5 is quite fast */
-                       240, 21, 38, 6,         /* x timing */
-                       320, 4, 4, 2,           /* y timing */
-                       60),                    /* refresh rate */
-               .lcdcon5        = (S3C2410_LCDCON5_FRM565 |
-                                  S3C2410_LCDCON5_INVVLINE |
-                                  S3C2410_LCDCON5_INVVFRAME |
-                                  S3C2410_LCDCON5_INVVDEN |
-                                  S3C2410_LCDCON5_PWREN),
-       },
-       [1] = { /* mini2440 + 7" TFT + touchscreen */
-               _LCD_DECLARE(
-                       10,                     /* the 7" runs slower */
-                       800, 40, 40, 48,        /* x timing */
-                       480, 29, 3, 3,          /* y timing */
-                       50),                    /* refresh rate */
-               .lcdcon5        = (S3C2410_LCDCON5_FRM565 |
-                                  S3C2410_LCDCON5_INVVLINE |
-                                  S3C2410_LCDCON5_INVVFRAME |
-                                  S3C2410_LCDCON5_PWREN),
-       },
-       /* The VGA shield can outout at several resolutions. All share 
-        * the same timings, however, anything smaller than 1024x768
-        * will only be displayed in the top left corner of a 1024x768
-        * XGA output unless you add optional dip switches to the shield.
-        * Therefore timings for other resolutions have been omitted here.
-        */
-       [2] = {
-               _LCD_DECLARE(
-                       10,
-                       1024, 1, 2, 2,          /* y timing */
-                       768, 200, 16, 16,       /* x timing */
-                       24),    /* refresh rate, maximum stable,
-                                tested with the FPGA shield */
-               .lcdcon5        = (S3C2410_LCDCON5_FRM565 |
-                                  S3C2410_LCDCON5_HWSWP),
-       },
-       /* mini2440 + 3.5" TFT (LCD-W35i, LQ035Q1DG06 type) + touchscreen*/
-       [3] = {
-               _LCD_DECLARE(
-                       /* clock */
-                       7,
-                       /* xres, margin_right, margin_left, hsync */
-                       320, 68, 66, 4,
-                       /* yres, margin_top, margin_bottom, vsync */
-                       240, 4, 4, 9,
-                       /* refresh rate */
-                       60),
-               .lcdcon5        = (S3C2410_LCDCON5_FRM565 |
-                                  S3C2410_LCDCON5_INVVDEN |
-                                  S3C2410_LCDCON5_INVVFRAME |
-                                  S3C2410_LCDCON5_INVVLINE |
-                                  S3C2410_LCDCON5_INVVCLK |
-                                  S3C2410_LCDCON5_HWSWP),
-       },
-};
-
-/* todo - put into gpio header */
-
-#define S3C2410_GPCCON_MASK(x) (3 << ((x) * 2))
-#define S3C2410_GPDCON_MASK(x) (3 << ((x) * 2))
-
-static struct s3c2410fb_mach_info mini2440_fb_info __initdata = {
-       .displays        = &mini2440_lcd_cfg[0], /* not constant! see init */
-       .num_displays    = 1,
-       .default_display = 0,
-
-       /* Enable VD[2..7], VD[10..15], VD[18..23] and VCLK, syncs, VDEN
-        * and disable the pull down resistors on pins we are using for LCD
-        * data. */
-
-       .gpcup          = (0xf << 1) | (0x3f << 10),
-
-       .gpccon         = (S3C2410_GPC1_VCLK   | S3C2410_GPC2_VLINE |
-                          S3C2410_GPC3_VFRAME | S3C2410_GPC4_VM |
-                          S3C2410_GPC10_VD2   | S3C2410_GPC11_VD3 |
-                          S3C2410_GPC12_VD4   | S3C2410_GPC13_VD5 |
-                          S3C2410_GPC14_VD6   | S3C2410_GPC15_VD7),
-
-       .gpccon_mask    = (S3C2410_GPCCON_MASK(1)  | S3C2410_GPCCON_MASK(2)  |
-                          S3C2410_GPCCON_MASK(3)  | S3C2410_GPCCON_MASK(4)  |
-                          S3C2410_GPCCON_MASK(10) | S3C2410_GPCCON_MASK(11) |
-                          S3C2410_GPCCON_MASK(12) | S3C2410_GPCCON_MASK(13) |
-                          S3C2410_GPCCON_MASK(14) | S3C2410_GPCCON_MASK(15)),
-
-       .gpdup          = (0x3f << 2) | (0x3f << 10),
-
-       .gpdcon         = (S3C2410_GPD2_VD10  | S3C2410_GPD3_VD11 |
-                          S3C2410_GPD4_VD12  | S3C2410_GPD5_VD13 |
-                          S3C2410_GPD6_VD14  | S3C2410_GPD7_VD15 |
-                          S3C2410_GPD10_VD18 | S3C2410_GPD11_VD19 |
-                          S3C2410_GPD12_VD20 | S3C2410_GPD13_VD21 |
-                          S3C2410_GPD14_VD22 | S3C2410_GPD15_VD23),
-
-       .gpdcon_mask    = (S3C2410_GPDCON_MASK(2)  | S3C2410_GPDCON_MASK(3) |
-                          S3C2410_GPDCON_MASK(4)  | S3C2410_GPDCON_MASK(5) |
-                          S3C2410_GPDCON_MASK(6)  | S3C2410_GPDCON_MASK(7) |
-                          S3C2410_GPDCON_MASK(10) | S3C2410_GPDCON_MASK(11)|
-                          S3C2410_GPDCON_MASK(12) | S3C2410_GPDCON_MASK(13)|
-                          S3C2410_GPDCON_MASK(14) | S3C2410_GPDCON_MASK(15)),
-};
-
-/* MMC/SD  */
-
-static struct s3c24xx_mci_pdata mini2440_mmc_cfg __initdata = {
-   .gpio_detect   = S3C2410_GPG(8),
-   .gpio_wprotect = S3C2410_GPH(8),
-   .set_power     = NULL,
-   .ocr_avail     = MMC_VDD_32_33|MMC_VDD_33_34,
-};
-
-/* NAND Flash on MINI2440 board */
-
-static struct mtd_partition mini2440_default_nand_part[] __initdata = {
-       [0] = {
-               .name   = "u-boot",
-               .size   = SZ_256K,
-               .offset = 0,
-       },
-       [1] = {
-               .name   = "u-boot-env",
-               .size   = SZ_128K,
-               .offset = SZ_256K,
-       },
-       [2] = {
-               .name   = "kernel",
-               /* 5 megabytes, for a kernel with no modules
-                * or a uImage with a ramdisk attached */
-               .size   = 0x00500000,
-               .offset = SZ_256K + SZ_128K,
-       },
-       [3] = {
-               .name   = "root",
-               .offset = SZ_256K + SZ_128K + 0x00500000,
-               .size   = MTDPART_SIZ_FULL,
-       },
-};
-
-static struct s3c2410_nand_set mini2440_nand_sets[] __initdata = {
-       [0] = {
-               .name           = "nand",
-               .nr_chips       = 1,
-               .nr_partitions  = ARRAY_SIZE(mini2440_default_nand_part),
-               .partitions     = mini2440_default_nand_part,
-               .flash_bbt      = 1, /* we use u-boot to create a BBT */
-       },
-};
-
-static struct s3c2410_platform_nand mini2440_nand_info __initdata = {
-       .tacls          = 0,
-       .twrph0         = 25,
-       .twrph1         = 15,
-       .nr_sets        = ARRAY_SIZE(mini2440_nand_sets),
-       .sets           = mini2440_nand_sets,
-       .ignore_unset_ecc = 1,
-};
-
-/* DM9000AEP 10/100 ethernet controller */
-
-static struct resource mini2440_dm9k_resource[] = {
-       [0] = {
-               .start = MACH_MINI2440_DM9K_BASE,
-               .end   = MACH_MINI2440_DM9K_BASE + 3,
-               .flags = IORESOURCE_MEM
-       },
-       [1] = {
-               .start = MACH_MINI2440_DM9K_BASE + 4,
-               .end   = MACH_MINI2440_DM9K_BASE + 7,
-               .flags = IORESOURCE_MEM
-       },
-       [2] = {
-               .start = IRQ_EINT7,
-               .end   = IRQ_EINT7,
-               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
-       }
-};
-
-/*
- * The DM9000 has no eeprom, and it's MAC address is set by
- * the bootloader before starting the kernel.
- */
-static struct dm9000_plat_data mini2440_dm9k_pdata = {
-       .flags          = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
-};
-
-static struct platform_device mini2440_device_eth = {
-       .name           = "dm9000",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(mini2440_dm9k_resource),
-       .resource       = mini2440_dm9k_resource,
-       .dev            = {
-               .platform_data  = &mini2440_dm9k_pdata,
-       },
-};
-
-/*  CON5
- *     +--+     /-----\
- *     |  |    |       |
- *     |  |    |  BAT  |
- *     |  |     \_____/
- *     |  |
- *     |  |  +----+  +----+
- *     |  |  | K5 |  | K1 |
- *     |  |  +----+  +----+
- *     |  |  +----+  +----+
- *     |  |  | K4 |  | K2 |
- *     |  |  +----+  +----+
- *     |  |  +----+  +----+
- *     |  |  | K6 |  | K3 |
- *     |  |  +----+  +----+
- *       .....
- */
-static struct gpio_keys_button mini2440_buttons[] = {
-       {
-               .gpio           = S3C2410_GPG(0),               /* K1 */
-               .code           = KEY_F1,
-               .desc           = "Button 1",
-               .active_low     = 1,
-       },
-       {
-               .gpio           = S3C2410_GPG(3),               /* K2 */
-               .code           = KEY_F2,
-               .desc           = "Button 2",
-               .active_low     = 1,
-       },
-       {
-               .gpio           = S3C2410_GPG(5),               /* K3 */
-               .code           = KEY_F3,
-               .desc           = "Button 3",
-               .active_low     = 1,
-       },
-       {
-               .gpio           = S3C2410_GPG(6),               /* K4 */
-               .code           = KEY_POWER,
-               .desc           = "Power",
-               .active_low     = 1,
-       },
-       {
-               .gpio           = S3C2410_GPG(7),               /* K5 */
-               .code           = KEY_F5,
-               .desc           = "Button 5",
-               .active_low     = 1,
-       },
-#if 0
-       /* this pin is also known as TCLK1 and seems to already
-        * marked as "in use" somehow in the kernel -- possibly wrongly */
-       {
-               .gpio           = S3C2410_GPG(11),      /* K6 */
-               .code           = KEY_F6,
-               .desc           = "Button 6",
-               .active_low     = 1,
-       },
-#endif
-};
-
-static struct gpio_keys_platform_data mini2440_button_data = {
-       .buttons        = mini2440_buttons,
-       .nbuttons       = ARRAY_SIZE(mini2440_buttons),
-};
-
-static struct platform_device mini2440_button_device = {
-       .name           = "gpio-keys",
-       .id             = -1,
-       .dev            = {
-               .platform_data  = &mini2440_button_data,
-       }
-};
-
-/* LEDS */
-
-static struct s3c24xx_led_platdata mini2440_led1_pdata = {
-       .name           = "led1",
-       .gpio           = S3C2410_GPB(5),
-       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
-       .def_trigger    = "heartbeat",
-};
-
-static struct s3c24xx_led_platdata mini2440_led2_pdata = {
-       .name           = "led2",
-       .gpio           = S3C2410_GPB(6),
-       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
-       .def_trigger    = "nand-disk",
-};
-
-static struct s3c24xx_led_platdata mini2440_led3_pdata = {
-       .name           = "led3",
-       .gpio           = S3C2410_GPB(7),
-       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
-       .def_trigger    = "mmc0",
-};
-
-static struct s3c24xx_led_platdata mini2440_led4_pdata = {
-       .name           = "led4",
-       .gpio           = S3C2410_GPB(8),
-       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
-       .def_trigger    = "",
-};
-
-static struct s3c24xx_led_platdata mini2440_led_backlight_pdata = {
-       .name           = "backlight",
-       .gpio           = S3C2410_GPG(4),
-       .def_trigger    = "backlight",
-};
-
-static struct platform_device mini2440_led1 = {
-       .name           = "s3c24xx_led",
-       .id             = 1,
-       .dev            = {
-               .platform_data  = &mini2440_led1_pdata,
-       },
-};
-
-static struct platform_device mini2440_led2 = {
-       .name           = "s3c24xx_led",
-       .id             = 2,
-       .dev            = {
-               .platform_data  = &mini2440_led2_pdata,
-       },
-};
-
-static struct platform_device mini2440_led3 = {
-       .name           = "s3c24xx_led",
-       .id             = 3,
-       .dev            = {
-               .platform_data  = &mini2440_led3_pdata,
-       },
-};
-
-static struct platform_device mini2440_led4 = {
-       .name           = "s3c24xx_led",
-       .id             = 4,
-       .dev            = {
-               .platform_data  = &mini2440_led4_pdata,
-       },
-};
-
-static struct platform_device mini2440_led_backlight = {
-       .name           = "s3c24xx_led",
-       .id             = 5,
-       .dev            = {
-               .platform_data  = &mini2440_led_backlight_pdata,
-       },
-};
-
-/* AUDIO */
-
-static struct s3c24xx_uda134x_platform_data mini2440_audio_pins = {
-       .l3_clk = S3C2410_GPB(4),
-       .l3_mode = S3C2410_GPB(2),
-       .l3_data = S3C2410_GPB(3),
-       .model = UDA134X_UDA1341
-};
-
-static struct platform_device mini2440_audio = {
-       .name           = "s3c24xx_uda134x",
-       .id             = 0,
-       .dev            = {
-               .platform_data  = &mini2440_audio_pins,
-       },
-};
-
-/*
- * I2C devices
- */
-static struct at24_platform_data at24c08 = {
-       .byte_len       = SZ_8K / 8,
-       .page_size      = 16,
-};
-
-static struct i2c_board_info mini2440_i2c_devs[] __initdata = {
-       {
-               I2C_BOARD_INFO("24c08", 0x50),
-               .platform_data = &at24c08,
-       },
-};
-
-static struct platform_device uda1340_codec = {
-               .name = "uda134x-codec",
-               .id = -1,
-};
-
-static struct platform_device *mini2440_devices[] __initdata = {
-       &s3c_device_ohci,
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_rtc,
-       &s3c_device_usbgadget,
-       &mini2440_device_eth,
-       &mini2440_led1,
-       &mini2440_led2,
-       &mini2440_led3,
-       &mini2440_led4,
-       &mini2440_button_device,
-       &s3c_device_nand,
-       &s3c_device_sdi,
-       &s3c_device_iis,
-       &uda1340_codec,
-       &mini2440_audio,
-       &samsung_asoc_dma,
-};
-
-static void __init mini2440_map_io(void)
-{
-       s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc));
-       s3c24xx_init_clocks(12000000);
-       s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs));
-}
-
-/*
- * mini2440_features string
- *
- * t = Touchscreen present
- * b = backlight control
- * c = camera [TODO]
- * 0-9 LCD configuration
- *
- */
-static char mini2440_features_str[12] __initdata = "0tb";
-
-static int __init mini2440_features_setup(char *str)
-{
-       if (str)
-               strlcpy(mini2440_features_str, str, sizeof(mini2440_features_str));
-       return 1;
-}
-
-__setup("mini2440=", mini2440_features_setup);
-
-#define FEATURE_SCREEN (1 << 0)
-#define FEATURE_BACKLIGHT (1 << 1)
-#define FEATURE_TOUCH (1 << 2)
-#define FEATURE_CAMERA (1 << 3)
-
-struct mini2440_features_t {
-       int count;
-       int done;
-       int lcd_index;
-       struct platform_device *optional[8];
-};
-
-static void __init mini2440_parse_features(
-               struct mini2440_features_t * features,
-               const char * features_str )
-{
-       const char * fp = features_str;
-
-       features->count = 0;
-       features->done = 0;
-       features->lcd_index = -1;
-
-       while (*fp) {
-               char f = *fp++;
-
-               switch (f) {
-               case '0'...'9': /* tft screen */
-                       if (features->done & FEATURE_SCREEN) {
-                               printk(KERN_INFO "MINI2440: '%c' ignored, "
-                                       "screen type already set\n", f);
-                       } else {
-                               int li = f - '0';
-                               if (li >= ARRAY_SIZE(mini2440_lcd_cfg))
-                                       printk(KERN_INFO "MINI2440: "
-                                               "'%c' out of range LCD mode\n", f);
-                               else {
-                                       features->optional[features->count++] =
-                                                       &s3c_device_lcd;
-                                       features->lcd_index = li;
-                               }
-                       }
-                       features->done |= FEATURE_SCREEN;
-                       break;
-               case 'b':
-                       if (features->done & FEATURE_BACKLIGHT)
-                               printk(KERN_INFO "MINI2440: '%c' ignored, "
-                                       "backlight already set\n", f);
-                       else {
-                               features->optional[features->count++] =
-                                               &mini2440_led_backlight;
-                       }
-                       features->done |= FEATURE_BACKLIGHT;
-                       break;
-               case 't':
-                       printk(KERN_INFO "MINI2440: '%c' ignored, "
-                               "touchscreen not compiled in\n", f);
-                       break;
-               case 'c':
-                       if (features->done & FEATURE_CAMERA)
-                               printk(KERN_INFO "MINI2440: '%c' ignored, "
-                                       "camera already registered\n", f);
-                       else
-                               features->optional[features->count++] =
-                                       &s3c_device_camif;
-                       features->done |= FEATURE_CAMERA;
-                       break;
-               }
-       }
-}
-
-static void __init mini2440_init(void)
-{
-       struct mini2440_features_t features = { 0 };
-       int i;
-
-       printk(KERN_INFO "MINI2440: Option string mini2440=%s\n",
-                       mini2440_features_str);
-
-       /* Parse the feature string */
-       mini2440_parse_features(&features, mini2440_features_str);
-
-       /* turn LCD on */
-       s3c_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);
-
-       /* Turn the backlight early on */
-       WARN_ON(gpio_request(S3C2410_GPG(4), "backlight"));
-       gpio_direction_output(S3C2410_GPG(4), 1);
-
-       /* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */
-       s3c_gpio_setpull(S3C2410_GPB(1), S3C_GPIO_PULL_UP);
-       s3c2410_gpio_setpin(S3C2410_GPB(1), 0);
-       s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT);
-
-       /* mark the key as input, without pullups (there is one on the board) */
-       for (i = 0; i < ARRAY_SIZE(mini2440_buttons); i++) {
-               s3c_gpio_setpull(mini2440_buttons[i].gpio, S3C_GPIO_PULL_UP);
-               s3c_gpio_cfgpin(mini2440_buttons[i].gpio, S3C2410_GPIO_INPUT);
-       }
-       if (features.lcd_index != -1) {
-               int li;
-
-               mini2440_fb_info.displays =
-                       &mini2440_lcd_cfg[features.lcd_index];
-
-               printk(KERN_INFO "MINI2440: LCD");
-               for (li = 0; li < ARRAY_SIZE(mini2440_lcd_cfg); li++)
-                       if (li == features.lcd_index)
-                               printk(" [%d:%dx%d]", li,
-                                       mini2440_lcd_cfg[li].width,
-                                       mini2440_lcd_cfg[li].height);
-                       else
-                               printk(" %d:%dx%d", li,
-                                       mini2440_lcd_cfg[li].width,
-                                       mini2440_lcd_cfg[li].height);
-               printk("\n");
-               s3c24xx_fb_set_platdata(&mini2440_fb_info);
-       }
-
-       s3c24xx_udc_set_platdata(&mini2440_udc_cfg);
-       s3c24xx_mci_set_platdata(&mini2440_mmc_cfg);
-       s3c_nand_set_platdata(&mini2440_nand_info);
-       s3c_i2c0_set_platdata(NULL);
-
-       i2c_register_board_info(0, mini2440_i2c_devs,
-                               ARRAY_SIZE(mini2440_i2c_devs));
-
-       platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));
-
-       if (features.count)     /* the optional features */
-               platform_add_devices(features.optional, features.count);
-
-}
-
-
-MACHINE_START(MINI2440, "MINI2440")
-       /* Maintainer: Michel Pollet <buserror@gmail.com> */
-       .atag_offset    = 0x100,
-       .map_io         = mini2440_map_io,
-       .init_machine   = mini2440_init,
-       .init_irq       = s3c24xx_init_irq,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c244x_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c
deleted file mode 100644 (file)
index 5198e3e..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/* linux/arch/arm/mach-s3c2440/mach-nexcoder.c
- *
- * Copyright (c) 2004 Nex Vision
- *   Guillaume GOURAT <guillaume.gourat@nexvision.tv>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Modifications:
- *     15-10-2004 GG  Created initial version
- *     12-03-2005 BJD Updated for release
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/string.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <linux/mtd/map.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/setup.h>
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-//#include <asm/debug-ll.h>
-#include <mach/regs-gpio.h>
-#include <plat/regs-serial.h>
-#include <plat/iic.h>
-
-#include <plat/gpio-cfg.h>
-#include <plat/s3c2410.h>
-#include <plat/s3c244x.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#include "common.h"
-
-static struct map_desc nexcoder_iodesc[] __initdata = {
-       /* nothing here yet */
-};
-
-#define UCON S3C2410_UCON_DEFAULT
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg nexcoder_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       },
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-       }
-};
-
-/* NOR Flash on NexVision NexCoder 2440 board */
-
-static struct resource nexcoder_nor_resource[] = {
-       [0] = {
-               .start = S3C2410_CS0,
-               .end   = S3C2410_CS0 + (8*1024*1024) - 1,
-               .flags = IORESOURCE_MEM,
-       }
-};
-
-static struct map_info nexcoder_nor_map = {
-       .bankwidth = 2,
-};
-
-static struct platform_device nexcoder_device_nor = {
-       .name           = "mtd-flash",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(nexcoder_nor_resource),
-       .resource       = nexcoder_nor_resource,
-       .dev =
-       {
-               .platform_data = &nexcoder_nor_map,
-       }
-};
-
-/* Standard Nexcoder devices */
-
-static struct platform_device *nexcoder_devices[] __initdata = {
-       &s3c_device_ohci,
-       &s3c_device_lcd,
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_iis,
-       &s3c_device_rtc,
-       &s3c_device_camif,
-       &s3c_device_spi0,
-       &s3c_device_spi1,
-       &nexcoder_device_nor,
-};
-
-static void __init nexcoder_sensorboard_init(void)
-{
-       // Initialize SCCB bus
-       s3c2410_gpio_setpin(S3C2410_GPE(14), 1); // IICSCL
-       s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_OUTPUT);
-       s3c2410_gpio_setpin(S3C2410_GPE(15), 1); // IICSDA
-       s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_OUTPUT);
-
-       // Power up the sensor board
-       s3c2410_gpio_setpin(S3C2410_GPF(1), 1);
-       s3c_gpio_cfgpin(S3C2410_GPF(1), S3C2410_GPIO_OUTPUT); // CAM_GPIO7 => nLDO_PWRDN
-       s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
-       s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); // CAM_GPIO6 => CAM_PWRDN
-}
-
-static void __init nexcoder_map_io(void)
-{
-       s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
-       s3c24xx_init_clocks(0);
-       s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs));
-
-       nexcoder_sensorboard_init();
-}
-
-static void __init nexcoder_init(void)
-{
-       s3c_i2c0_set_platdata(NULL);
-       platform_add_devices(nexcoder_devices, ARRAY_SIZE(nexcoder_devices));
-};
-
-MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
-       /* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
-       .atag_offset    = 0x100,
-       .map_io         = nexcoder_map_io,
-       .init_machine   = nexcoder_init,
-       .init_irq       = s3c24xx_init_irq,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c244x_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-osiris-dvs.c b/arch/arm/mach-s3c2440/mach-osiris-dvs.c
deleted file mode 100644 (file)
index ad2792d..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/* linux/arch/arm/mach-s3c2440/mach-osiris-dvs.c
- *
- * Copyright (c) 2009 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Simtec Osiris Dynamic Voltage Scaling support.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/cpufreq.h>
-#include <linux/gpio.h>
-
-#include <linux/i2c/tps65010.h>
-
-#include <plat/cpu-freq.h>
-
-#define OSIRIS_GPIO_DVS        S3C2410_GPB(5)
-
-static bool dvs_en;
-
-static void osiris_dvs_tps_setdvs(bool on)
-{
-       unsigned vregs1 = 0, vdcdc2 = 0;
-
-       if (!on) {
-               vdcdc2 = TPS_VCORE_DISCH | TPS_LP_COREOFF;
-               vregs1 = TPS_LDO1_OFF;  /* turn off in low-power mode */
-       }
-
-       dvs_en = on;
-       vdcdc2 |= TPS_VCORE_1_3V | TPS_VCORE_LP_1_0V;
-       vregs1 |= TPS_LDO2_ENABLE | TPS_LDO1_ENABLE;
-
-       tps65010_config_vregs1(vregs1);
-       tps65010_config_vdcdc2(vdcdc2);
-}
-
-static bool is_dvs(struct s3c_freq *f)
-{
-       /* at the moment, we assume ARMCLK = HCLK => DVS */
-       return f->armclk == f->hclk;
-}
-
-/* keep track of current state */
-static bool cur_dvs = false;
-
-static int osiris_dvs_notify(struct notifier_block *nb,
-                             unsigned long val, void *data)
-{
-       struct cpufreq_freqs *cf = data;
-       struct s3c_cpufreq_freqs *freqs = to_s3c_cpufreq(cf);
-       bool old_dvs = is_dvs(&freqs->old);
-       bool new_dvs = is_dvs(&freqs->new);
-       int ret = 0;
-
-       if (!dvs_en)
-               return 0;
-
-       printk(KERN_DEBUG "%s: old %ld,%ld new %ld,%ld\n", __func__,
-              freqs->old.armclk, freqs->old.hclk,
-              freqs->new.armclk, freqs->new.hclk);
-
-       switch (val) {
-       case CPUFREQ_PRECHANGE:
-               if (old_dvs & !new_dvs ||
-                   cur_dvs & !new_dvs) {
-                       pr_debug("%s: exiting dvs\n", __func__);
-                       cur_dvs = false;
-                       gpio_set_value(OSIRIS_GPIO_DVS, 1);
-               }
-               break;
-       case CPUFREQ_POSTCHANGE:
-               if (!old_dvs & new_dvs ||
-                   !cur_dvs & new_dvs) {
-                       pr_debug("entering dvs\n");
-                       cur_dvs = true;
-                       gpio_set_value(OSIRIS_GPIO_DVS, 0);
-               }
-               break;
-       }
-
-       return ret;
-}
-
-static struct notifier_block osiris_dvs_nb = {
-       .notifier_call  = osiris_dvs_notify,
-};
-
-static int __devinit osiris_dvs_probe(struct platform_device *pdev)
-{
-       int ret;
-
-       dev_info(&pdev->dev, "initialising\n");
-
-       ret = gpio_request(OSIRIS_GPIO_DVS, "osiris-dvs");
-       if (ret) {
-               dev_err(&pdev->dev, "cannot claim gpio\n");
-               goto err_nogpio;
-       }
-
-       /* start with dvs disabled */
-       gpio_direction_output(OSIRIS_GPIO_DVS, 1);
-
-       ret = cpufreq_register_notifier(&osiris_dvs_nb,
-                                       CPUFREQ_TRANSITION_NOTIFIER);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to register with cpufreq\n");
-               goto err_nofreq;
-       }
-
-       osiris_dvs_tps_setdvs(true);
-
-       return 0;
-
-err_nofreq:
-       gpio_free(OSIRIS_GPIO_DVS);
-
-err_nogpio:
-       return ret;
-}
-
-static int __devexit osiris_dvs_remove(struct platform_device *pdev)
-{
-       dev_info(&pdev->dev, "exiting\n");
-
-       /* disable any current dvs */
-       gpio_set_value(OSIRIS_GPIO_DVS, 1);
-       osiris_dvs_tps_setdvs(false);
-
-       cpufreq_unregister_notifier(&osiris_dvs_nb,
-                                   CPUFREQ_TRANSITION_NOTIFIER);
-
-       gpio_free(OSIRIS_GPIO_DVS);
-
-       return 0;
-}
-
-/* the CONFIG_PM block is so small, it isn't worth actaully compiling it
- * out if the configuration isn't set. */
-
-static int osiris_dvs_suspend(struct device *dev)
-{
-       gpio_set_value(OSIRIS_GPIO_DVS, 1);
-       osiris_dvs_tps_setdvs(false);
-       cur_dvs = false;
-
-       return 0;
-}
-
-static int osiris_dvs_resume(struct device *dev)
-{
-       osiris_dvs_tps_setdvs(true);
-       return 0;
-}
-
-static const struct dev_pm_ops osiris_dvs_pm = {
-       .suspend        = osiris_dvs_suspend,
-       .resume         = osiris_dvs_resume,
-};
-
-static struct platform_driver osiris_dvs_driver = {
-       .probe          = osiris_dvs_probe,
-       .remove         = __devexit_p(osiris_dvs_remove),
-       .driver         = {
-               .name   = "osiris-dvs",
-               .owner  = THIS_MODULE,
-               .pm     = &osiris_dvs_pm,
-       },
-};
-
-static int __init osiris_dvs_init(void)
-{
-       return platform_driver_register(&osiris_dvs_driver);
-}
-
-static void __exit osiris_dvs_exit(void)
-{
-       platform_driver_unregister(&osiris_dvs_driver);
-}
-
-module_init(osiris_dvs_init);
-module_exit(osiris_dvs_exit);
-
-MODULE_DESCRIPTION("Simtec OSIRIS DVS support");
-MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:osiris-dvs");
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
deleted file mode 100644 (file)
index c5daeb6..0000000
+++ /dev/null
@@ -1,440 +0,0 @@
-/* linux/arch/arm/mach-s3c2440/mach-osiris.c
- *
- * Copyright (c) 2005-2008 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/device.h>
-#include <linux/syscore_ops.h>
-#include <linux/serial_core.h>
-#include <linux/clk.h>
-#include <linux/i2c.h>
-#include <linux/io.h>
-
-#include <linux/i2c/tps65010.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/osiris-map.h>
-#include <mach/osiris-cpld.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-mem.h>
-#include <mach/regs-lcd.h>
-#include <plat/nand.h>
-#include <plat/iic.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include <plat/gpio-cfg.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#include "common.h"
-
-/* onboard perihperal map */
-
-static struct map_desc osiris_iodesc[] __initdata = {
-  /* ISA IO areas (may be over-written later) */
-
-  {
-         .virtual      = (u32)S3C24XX_VA_ISA_BYTE,
-         .pfn          = __phys_to_pfn(S3C2410_CS5),
-         .length       = SZ_16M,
-         .type         = MT_DEVICE,
-  }, {
-         .virtual      = (u32)S3C24XX_VA_ISA_WORD,
-         .pfn          = __phys_to_pfn(S3C2410_CS5),
-         .length       = SZ_16M,
-         .type         = MT_DEVICE,
-  },
-
-  /* CPLD control registers */
-
-  {
-         .virtual      = (u32)OSIRIS_VA_CTRL0,
-         .pfn          = __phys_to_pfn(OSIRIS_PA_CTRL0),
-         .length       = SZ_16K,
-         .type         = MT_DEVICE,
-  }, {
-         .virtual      = (u32)OSIRIS_VA_CTRL1,
-         .pfn          = __phys_to_pfn(OSIRIS_PA_CTRL1),
-         .length       = SZ_16K,
-         .type         = MT_DEVICE,
-  }, {
-         .virtual      = (u32)OSIRIS_VA_CTRL2,
-         .pfn          = __phys_to_pfn(OSIRIS_PA_CTRL2),
-         .length       = SZ_16K,
-         .type         = MT_DEVICE,
-  }, {
-         .virtual      = (u32)OSIRIS_VA_IDREG,
-         .pfn          = __phys_to_pfn(OSIRIS_PA_IDREG),
-         .length       = SZ_16K,
-         .type         = MT_DEVICE,
-  },
-};
-
-#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-               .clk_sel        = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-               .clk_sel        = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
-       },
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = UCON,
-               .ulcon       = ULCON,
-               .ufcon       = UFCON,
-               .clk_sel        = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
-       }
-};
-
-/* NAND Flash on Osiris board */
-
-static int external_map[]   = { 2 };
-static int chip0_map[]      = { 0 };
-static int chip1_map[]      = { 1 };
-
-static struct mtd_partition __initdata osiris_default_nand_part[] = {
-       [0] = {
-               .name   = "Boot Agent",
-               .size   = SZ_16K,
-               .offset = 0,
-       },
-       [1] = {
-               .name   = "/boot",
-               .size   = SZ_4M - SZ_16K,
-               .offset = SZ_16K,
-       },
-       [2] = {
-               .name   = "user1",
-               .offset = SZ_4M,
-               .size   = SZ_32M - SZ_4M,
-       },
-       [3] = {
-               .name   = "user2",
-               .offset = SZ_32M,
-               .size   = MTDPART_SIZ_FULL,
-       }
-};
-
-static struct mtd_partition __initdata osiris_default_nand_part_large[] = {
-       [0] = {
-               .name   = "Boot Agent",
-               .size   = SZ_128K,
-               .offset = 0,
-       },
-       [1] = {
-               .name   = "/boot",
-               .size   = SZ_4M - SZ_128K,
-               .offset = SZ_128K,
-       },
-       [2] = {
-               .name   = "user1",
-               .offset = SZ_4M,
-               .size   = SZ_32M - SZ_4M,
-       },
-       [3] = {
-               .name   = "user2",
-               .offset = SZ_32M,
-               .size   = MTDPART_SIZ_FULL,
-       }
-};
-
-/* the Osiris has 3 selectable slots for nand-flash, the two
- * on-board chip areas, as well as the external slot.
- *
- * Note, there is no current hot-plug support for the External
- * socket.
-*/
-
-static struct s3c2410_nand_set __initdata osiris_nand_sets[] = {
-       [1] = {
-               .name           = "External",
-               .nr_chips       = 1,
-               .nr_map         = external_map,
-               .options        = NAND_SCAN_SILENT_NODEV,
-               .nr_partitions  = ARRAY_SIZE(osiris_default_nand_part),
-               .partitions     = osiris_default_nand_part,
-       },
-       [0] = {
-               .name           = "chip0",
-               .nr_chips       = 1,
-               .nr_map         = chip0_map,
-               .nr_partitions  = ARRAY_SIZE(osiris_default_nand_part),
-               .partitions     = osiris_default_nand_part,
-       },
-       [2] = {
-               .name           = "chip1",
-               .nr_chips       = 1,
-               .nr_map         = chip1_map,
-               .options        = NAND_SCAN_SILENT_NODEV,
-               .nr_partitions  = ARRAY_SIZE(osiris_default_nand_part),
-               .partitions     = osiris_default_nand_part,
-       },
-};
-
-static void osiris_nand_select(struct s3c2410_nand_set *set, int slot)
-{
-       unsigned int tmp;
-
-       slot = set->nr_map[slot] & 3;
-
-       pr_debug("osiris_nand: selecting slot %d (set %p,%p)\n",
-                slot, set, set->nr_map);
-
-       tmp = __raw_readb(OSIRIS_VA_CTRL0);
-       tmp &= ~OSIRIS_CTRL0_NANDSEL;
-       tmp |= slot;
-
-       pr_debug("osiris_nand: ctrl0 now %02x\n", tmp);
-
-       __raw_writeb(tmp, OSIRIS_VA_CTRL0);
-}
-
-static struct s3c2410_platform_nand __initdata osiris_nand_info = {
-       .tacls          = 25,
-       .twrph0         = 60,
-       .twrph1         = 60,
-       .nr_sets        = ARRAY_SIZE(osiris_nand_sets),
-       .sets           = osiris_nand_sets,
-       .select_chip    = osiris_nand_select,
-};
-
-/* PCMCIA control and configuration */
-
-static struct resource osiris_pcmcia_resource[] = {
-       [0] = {
-               .start  = 0x0f000000,
-               .end    = 0x0f100000,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = 0x0c000000,
-               .end    = 0x0c100000,
-               .flags  = IORESOURCE_MEM,
-       }
-};
-
-static struct platform_device osiris_pcmcia = {
-       .name           = "osiris-pcmcia",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(osiris_pcmcia_resource),
-       .resource       = osiris_pcmcia_resource,
-};
-
-/* Osiris power management device */
-
-#ifdef CONFIG_PM
-static unsigned char pm_osiris_ctrl0;
-
-static int osiris_pm_suspend(void)
-{
-       unsigned int tmp;
-
-       pm_osiris_ctrl0 = __raw_readb(OSIRIS_VA_CTRL0);
-       tmp = pm_osiris_ctrl0 & ~OSIRIS_CTRL0_NANDSEL;
-
-       /* ensure correct NAND slot is selected on resume */
-       if ((pm_osiris_ctrl0 & OSIRIS_CTRL0_BOOT_INT) == 0)
-               tmp |= 2;
-
-       __raw_writeb(tmp, OSIRIS_VA_CTRL0);
-
-       /* ensure that an nRESET is not generated on resume. */
-       s3c2410_gpio_setpin(S3C2410_GPA(21), 1);
-       s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
-
-       return 0;
-}
-
-static void osiris_pm_resume(void)
-{
-       if (pm_osiris_ctrl0 & OSIRIS_CTRL0_FIX8)
-               __raw_writeb(OSIRIS_CTRL1_FIX8, OSIRIS_VA_CTRL1);
-
-       __raw_writeb(pm_osiris_ctrl0, OSIRIS_VA_CTRL0);
-
-       s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
-}
-
-#else
-#define osiris_pm_suspend NULL
-#define osiris_pm_resume NULL
-#endif
-
-static struct syscore_ops osiris_pm_syscore_ops = {
-       .suspend        = osiris_pm_suspend,
-       .resume         = osiris_pm_resume,
-};
-
-/* Link for DVS driver to TPS65011 */
-
-static void osiris_tps_release(struct device *dev)
-{
-       /* static device, do not need to release anything */
-}
-
-static struct platform_device osiris_tps_device = {
-       .name   = "osiris-dvs",
-       .id     = -1,
-       .dev.release = osiris_tps_release,
-};
-
-static int osiris_tps_setup(struct i2c_client *client, void *context)
-{
-       osiris_tps_device.dev.parent = &client->dev;
-       return platform_device_register(&osiris_tps_device);
-}
-
-static int osiris_tps_remove(struct i2c_client *client, void *context)
-{
-       platform_device_unregister(&osiris_tps_device);
-       return 0;
-}
-
-static struct tps65010_board osiris_tps_board = {
-       .base           = -1,   /* GPIO can go anywhere at the moment */
-       .setup          = osiris_tps_setup,
-       .teardown       = osiris_tps_remove,
-};
-
-/* I2C devices fitted. */
-
-static struct i2c_board_info osiris_i2c_devs[] __initdata = {
-       {
-               I2C_BOARD_INFO("tps65011", 0x48),
-               .irq    = IRQ_EINT20,
-               .platform_data = &osiris_tps_board,
-       },
-};
-
-/* Standard Osiris devices */
-
-static struct platform_device *osiris_devices[] __initdata = {
-       &s3c_device_i2c0,
-       &s3c_device_wdt,
-       &s3c_device_nand,
-       &osiris_pcmcia,
-};
-
-static struct clk *osiris_clocks[] __initdata = {
-       &s3c24xx_dclk0,
-       &s3c24xx_dclk1,
-       &s3c24xx_clkout0,
-       &s3c24xx_clkout1,
-       &s3c24xx_uclk,
-};
-
-static struct s3c_cpufreq_board __initdata osiris_cpufreq = {
-       .refresh        = 7800, /* refresh period is 7.8usec */
-       .auto_io        = 1,
-       .need_io        = 1,
-};
-
-static void __init osiris_map_io(void)
-{
-       unsigned long flags;
-
-       /* initialise the clocks */
-
-       s3c24xx_dclk0.parent = &clk_upll;
-       s3c24xx_dclk0.rate   = 12*1000*1000;
-
-       s3c24xx_dclk1.parent = &clk_upll;
-       s3c24xx_dclk1.rate   = 24*1000*1000;
-
-       s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
-       s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
-
-       s3c24xx_uclk.parent  = &s3c24xx_clkout1;
-
-       s3c24xx_register_clocks(osiris_clocks, ARRAY_SIZE(osiris_clocks));
-
-       s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc));
-       s3c24xx_init_clocks(0);
-       s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
-
-       /* check for the newer revision boards with large page nand */
-
-       if ((__raw_readb(OSIRIS_VA_IDREG) & OSIRIS_ID_REVMASK) >= 4) {
-               printk(KERN_INFO "OSIRIS-B detected (revision %d)\n",
-                      __raw_readb(OSIRIS_VA_IDREG) & OSIRIS_ID_REVMASK);
-               osiris_nand_sets[0].partitions = osiris_default_nand_part_large;
-               osiris_nand_sets[0].nr_partitions = ARRAY_SIZE(osiris_default_nand_part_large);
-       } else {
-               /* write-protect line to the NAND */
-               s3c2410_gpio_setpin(S3C2410_GPA(0), 1);
-       }
-
-       /* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */
-
-       local_irq_save(flags);
-       __raw_writel(__raw_readl(S3C2410_BWSCON) | S3C2410_BWSCON_ST1 | S3C2410_BWSCON_ST2 | S3C2410_BWSCON_ST3 | S3C2410_BWSCON_ST4 | S3C2410_BWSCON_ST5, S3C2410_BWSCON);
-       local_irq_restore(flags);
-}
-
-static void __init osiris_init(void)
-{
-       register_syscore_ops(&osiris_pm_syscore_ops);
-
-       s3c_i2c0_set_platdata(NULL);
-       s3c_nand_set_platdata(&osiris_nand_info);
-
-       s3c_cpufreq_setboard(&osiris_cpufreq);
-
-       i2c_register_board_info(0, osiris_i2c_devs,
-                               ARRAY_SIZE(osiris_i2c_devs));
-
-       platform_add_devices(osiris_devices, ARRAY_SIZE(osiris_devices));
-};
-
-MACHINE_START(OSIRIS, "Simtec-OSIRIS")
-       /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
-       .atag_offset    = 0x100,
-       .map_io         = osiris_map_io,
-       .init_irq       = s3c24xx_init_irq,
-       .init_machine   = osiris_init,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c244x_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c
deleted file mode 100644 (file)
index 6f68abf..0000000
+++ /dev/null
@@ -1,826 +0,0 @@
-/* linux/arch/arm/mach-s3c2440/mach-rx1950.c
- *
- * Copyright (c) 2006-2009 Victor Chukhantsev, Denis Grigoriev,
- * Copyright (c) 2007-2010 Vasily Khoruzhick
- *
- * based on smdk2440 written by Ben Dooks
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/memblock.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/input.h>
-#include <linux/gpio_keys.h>
-#include <linux/device.h>
-#include <linux/pda_power.h>
-#include <linux/pwm_backlight.h>
-#include <linux/pwm.h>
-#include <linux/s3c_adc_battery.h>
-#include <linux/leds.h>
-#include <linux/i2c.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-#include <linux/mmc/host.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach-types.h>
-
-#include <mach/regs-gpio.h>
-#include <mach/regs-gpioj.h>
-#include <mach/regs-lcd.h>
-#include <mach/h1940.h>
-#include <mach/fb.h>
-
-#include <plat/clock.h>
-#include <plat/regs-serial.h>
-#include <plat/regs-iic.h>
-#include <plat/mci.h>
-#include <plat/udc.h>
-#include <plat/nand.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/irq.h>
-#include <plat/ts.h>
-
-#include <sound/uda1380.h>
-
-#include "common.h"
-
-#define LCD_PWM_PERIOD 192960
-#define LCD_PWM_DUTY 127353
-
-static struct map_desc rx1950_iodesc[] __initdata = {
-};
-
-static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
-       [0] = {
-              .hwport = 0,
-              .flags = 0,
-              .ucon = 0x3c5,
-              .ulcon = 0x03,
-              .ufcon = 0x51,
-               .clk_sel = S3C2410_UCON_CLKSEL3,
-       },
-       [1] = {
-              .hwport = 1,
-              .flags = 0,
-              .ucon = 0x3c5,
-              .ulcon = 0x03,
-              .ufcon = 0x51,
-               .clk_sel = S3C2410_UCON_CLKSEL3,
-       },
-       /* IR port */
-       [2] = {
-              .hwport = 2,
-              .flags = 0,
-              .ucon = 0x3c5,
-              .ulcon = 0x43,
-              .ufcon = 0xf1,
-               .clk_sel = S3C2410_UCON_CLKSEL3,
-       },
-};
-
-static struct s3c2410fb_display rx1950_display = {
-       .type = S3C2410_LCDCON1_TFT,
-       .width = 240,
-       .height = 320,
-       .xres = 240,
-       .yres = 320,
-       .bpp = 16,
-
-       .pixclock = 260000,
-       .left_margin = 10,
-       .right_margin = 20,
-       .hsync_len = 10,
-       .upper_margin = 2,
-       .lower_margin = 2,
-       .vsync_len = 2,
-
-       .lcdcon5 = S3C2410_LCDCON5_FRM565 |
-                          S3C2410_LCDCON5_INVVCLK |
-                          S3C2410_LCDCON5_INVVLINE |
-                          S3C2410_LCDCON5_INVVFRAME |
-                          S3C2410_LCDCON5_HWSWP |
-                          (0x02 << 13) |
-                          (0x02 << 15),
-
-};
-
-static int power_supply_init(struct device *dev)
-{
-       return gpio_request(S3C2410_GPF(2), "cable plugged");
-}
-
-static int rx1950_is_ac_online(void)
-{
-       return !gpio_get_value(S3C2410_GPF(2));
-}
-
-static void power_supply_exit(struct device *dev)
-{
-       gpio_free(S3C2410_GPF(2));
-}
-
-static char *rx1950_supplicants[] = {
-       "main-battery"
-};
-
-static struct pda_power_pdata power_supply_info = {
-       .init                   = power_supply_init,
-       .is_ac_online           = rx1950_is_ac_online,
-       .exit                   = power_supply_exit,
-       .supplied_to            = rx1950_supplicants,
-       .num_supplicants        = ARRAY_SIZE(rx1950_supplicants),
-};
-
-static struct resource power_supply_resources[] = {
-       [0] = {
-                       .name   = "ac",
-                       .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE |
-                                         IORESOURCE_IRQ_HIGHEDGE,
-                       .start  = IRQ_EINT2,
-                       .end    = IRQ_EINT2,
-       },
-};
-
-static struct platform_device power_supply = {
-       .name                   = "pda-power",
-       .id                     = -1,
-       .dev                    = {
-                                       .platform_data =
-                                               &power_supply_info,
-       },
-       .resource               = power_supply_resources,
-       .num_resources          = ARRAY_SIZE(power_supply_resources),
-};
-
-static const struct s3c_adc_bat_thresh bat_lut_noac[] = {
-       { .volt = 4100, .cur = 156, .level = 100},
-       { .volt = 4050, .cur = 156, .level = 95},
-       { .volt = 4025, .cur = 141, .level = 90},
-       { .volt = 3995, .cur = 144, .level = 85},
-       { .volt = 3957, .cur = 162, .level = 80},
-       { .volt = 3931, .cur = 147, .level = 75},
-       { .volt = 3902, .cur = 147, .level = 70},
-       { .volt = 3863, .cur = 153, .level = 65},
-       { .volt = 3838, .cur = 150, .level = 60},
-       { .volt = 3800, .cur = 153, .level = 55},
-       { .volt = 3765, .cur = 153, .level = 50},
-       { .volt = 3748, .cur = 172, .level = 45},
-       { .volt = 3740, .cur = 153, .level = 40},
-       { .volt = 3714, .cur = 175, .level = 35},
-       { .volt = 3710, .cur = 156, .level = 30},
-       { .volt = 3963, .cur = 156, .level = 25},
-       { .volt = 3672, .cur = 178, .level = 20},
-       { .volt = 3651, .cur = 178, .level = 15},
-       { .volt = 3629, .cur = 178, .level = 10},
-       { .volt = 3612, .cur = 162, .level = 5},
-       { .volt = 3605, .cur = 162, .level = 0},
-};
-
-static const struct s3c_adc_bat_thresh bat_lut_acin[] = {
-       { .volt = 4200, .cur = 0, .level = 100},
-       { .volt = 4190, .cur = 0, .level = 99},
-       { .volt = 4178, .cur = 0, .level = 95},
-       { .volt = 4110, .cur = 0, .level = 70},
-       { .volt = 4076, .cur = 0, .level = 65},
-       { .volt = 4046, .cur = 0, .level = 60},
-       { .volt = 4021, .cur = 0, .level = 55},
-       { .volt = 3999, .cur = 0, .level = 50},
-       { .volt = 3982, .cur = 0, .level = 45},
-       { .volt = 3965, .cur = 0, .level = 40},
-       { .volt = 3957, .cur = 0, .level = 35},
-       { .volt = 3948, .cur = 0, .level = 30},
-       { .volt = 3936, .cur = 0, .level = 25},
-       { .volt = 3927, .cur = 0, .level = 20},
-       { .volt = 3906, .cur = 0, .level = 15},
-       { .volt = 3880, .cur = 0, .level = 10},
-       { .volt = 3829, .cur = 0, .level = 5},
-       { .volt = 3820, .cur = 0, .level = 0},
-};
-
-int rx1950_bat_init(void)
-{
-       int ret;
-
-       ret = gpio_request(S3C2410_GPJ(2), "rx1950-charger-enable-1");
-       if (ret)
-               goto err_gpio1;
-       ret = gpio_request(S3C2410_GPJ(3), "rx1950-charger-enable-2");
-       if (ret)
-               goto err_gpio2;
-
-       return 0;
-
-err_gpio2:
-       gpio_free(S3C2410_GPJ(2));
-err_gpio1:
-       return ret;
-}
-
-void rx1950_bat_exit(void)
-{
-       gpio_free(S3C2410_GPJ(2));
-       gpio_free(S3C2410_GPJ(3));
-}
-
-void rx1950_enable_charger(void)
-{
-       gpio_direction_output(S3C2410_GPJ(2), 1);
-       gpio_direction_output(S3C2410_GPJ(3), 1);
-}
-
-void rx1950_disable_charger(void)
-{
-       gpio_direction_output(S3C2410_GPJ(2), 0);
-       gpio_direction_output(S3C2410_GPJ(3), 0);
-}
-
-DEFINE_SPINLOCK(rx1950_blink_spin);
-
-static int rx1950_led_blink_set(unsigned gpio, int state,
-       unsigned long *delay_on, unsigned long *delay_off)
-{
-       int blink_gpio, check_gpio;
-
-       switch (gpio) {
-       case S3C2410_GPA(6):
-               blink_gpio = S3C2410_GPA(4);
-               check_gpio = S3C2410_GPA(3);
-               break;
-       case S3C2410_GPA(7):
-               blink_gpio = S3C2410_GPA(3);
-               check_gpio = S3C2410_GPA(4);
-               break;
-       default:
-               return -EINVAL;
-               break;
-       }
-
-       if (delay_on && delay_off && !*delay_on && !*delay_off)
-               *delay_on = *delay_off = 500;
-
-       spin_lock(&rx1950_blink_spin);
-
-       switch (state) {
-       case GPIO_LED_NO_BLINK_LOW:
-       case GPIO_LED_NO_BLINK_HIGH:
-               if (!gpio_get_value(check_gpio))
-                       gpio_set_value(S3C2410_GPJ(6), 0);
-               gpio_set_value(blink_gpio, 0);
-               gpio_set_value(gpio, state);
-               break;
-       case GPIO_LED_BLINK:
-               gpio_set_value(gpio, 0);
-               gpio_set_value(S3C2410_GPJ(6), 1);
-               gpio_set_value(blink_gpio, 1);
-               break;
-       }
-
-       spin_unlock(&rx1950_blink_spin);
-
-       return 0;
-}
-
-static struct gpio_led rx1950_leds_desc[] = {
-       {
-               .name                   = "Green",
-               .default_trigger        = "main-battery-full",
-               .gpio                   = S3C2410_GPA(6),
-               .retain_state_suspended = 1,
-       },
-       {
-               .name                   = "Red",
-               .default_trigger
-                       = "main-battery-charging-blink-full-solid",
-               .gpio                   = S3C2410_GPA(7),
-               .retain_state_suspended = 1,
-       },
-       {
-               .name                   = "Blue",
-               .default_trigger        = "rx1950-acx-mem",
-               .gpio                   = S3C2410_GPA(11),
-               .retain_state_suspended = 1,
-       },
-};
-
-static struct gpio_led_platform_data rx1950_leds_pdata = {
-       .num_leds       = ARRAY_SIZE(rx1950_leds_desc),
-       .leds           = rx1950_leds_desc,
-       .gpio_blink_set = rx1950_led_blink_set,
-};
-
-static struct platform_device rx1950_leds = {
-       .name   = "leds-gpio",
-       .id             = -1,
-       .dev    = {
-                               .platform_data = &rx1950_leds_pdata,
-       },
-};
-
-static struct s3c_adc_bat_pdata rx1950_bat_cfg = {
-       .init = rx1950_bat_init,
-       .exit = rx1950_bat_exit,
-       .enable_charger = rx1950_enable_charger,
-       .disable_charger = rx1950_disable_charger,
-       .gpio_charge_finished = S3C2410_GPF(3),
-       .lut_noac = bat_lut_noac,
-       .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac),
-       .lut_acin = bat_lut_acin,
-       .lut_acin_cnt = ARRAY_SIZE(bat_lut_acin),
-       .volt_channel = 0,
-       .current_channel = 1,
-       .volt_mult = 4235,
-       .current_mult = 2900,
-       .internal_impedance = 200,
-};
-
-static struct platform_device rx1950_battery = {
-       .name             = "s3c-adc-battery",
-       .id               = -1,
-       .dev = {
-               .parent = &s3c_device_adc.dev,
-               .platform_data = &rx1950_bat_cfg,
-       },
-};
-
-static struct s3c2410fb_mach_info rx1950_lcd_cfg = {
-       .displays = &rx1950_display,
-       .num_displays = 1,
-       .default_display = 0,
-
-       .lpcsel = 0x02,
-       .gpccon = 0xaa9556a9,
-       .gpccon_mask = 0xffc003fc,
-       .gpcup = 0x0000ffff,
-       .gpcup_mask = 0xffffffff,
-
-       .gpdcon = 0xaa90aaa1,
-       .gpdcon_mask = 0xffc0fff0,
-       .gpdup = 0x0000fcfd,
-       .gpdup_mask = 0xffffffff,
-
-};
-
-static struct pwm_device *lcd_pwm;
-
-void rx1950_lcd_power(int enable)
-{
-       int i;
-       static int enabled;
-       if (enabled == enable)
-               return;
-       if (!enable) {
-
-               /* GPC11-GPC15->OUTPUT */
-               for (i = 11; i < 16; i++)
-                       gpio_direction_output(S3C2410_GPC(i), 1);
-
-               /* Wait a bit here... */
-               mdelay(100);
-
-               /* GPD2-GPD7->OUTPUT */
-               /* GPD11-GPD15->OUTPUT */
-               /* GPD2-GPD7->1, GPD11-GPD15->1 */
-               for (i = 2; i < 8; i++)
-                       gpio_direction_output(S3C2410_GPD(i), 1);
-               for (i = 11; i < 16; i++)
-                       gpio_direction_output(S3C2410_GPD(i), 1);
-
-               /* Wait a bit here...*/
-               mdelay(100);
-
-               /* GPB0->OUTPUT, GPB0->0 */
-               gpio_direction_output(S3C2410_GPB(0), 0);
-
-               /* GPC1-GPC4->OUTPUT, GPC1-4->0 */
-               for (i = 1; i < 5; i++)
-                       gpio_direction_output(S3C2410_GPC(i), 0);
-
-               /* GPC15-GPC11->0 */
-               for (i = 11; i < 16; i++)
-                       gpio_direction_output(S3C2410_GPC(i), 0);
-
-               /* GPD15-GPD11->0, GPD2->GPD7->0 */
-               for (i = 11; i < 16; i++)
-                       gpio_direction_output(S3C2410_GPD(i), 0);
-
-               for (i = 2; i < 8; i++)
-                       gpio_direction_output(S3C2410_GPD(i), 0);
-
-               /* GPC6->0, GPC7->0, GPC5->0 */
-               gpio_direction_output(S3C2410_GPC(6), 0);
-               gpio_direction_output(S3C2410_GPC(7), 0);
-               gpio_direction_output(S3C2410_GPC(5), 0);
-
-               /* GPB1->OUTPUT, GPB1->0 */
-               gpio_direction_output(S3C2410_GPB(1), 0);
-               pwm_config(lcd_pwm, 0, LCD_PWM_PERIOD);
-               pwm_disable(lcd_pwm);
-
-               /* GPC0->0, GPC10->0 */
-               gpio_direction_output(S3C2410_GPC(0), 0);
-               gpio_direction_output(S3C2410_GPC(10), 0);
-       } else {
-               pwm_config(lcd_pwm, LCD_PWM_DUTY, LCD_PWM_PERIOD);
-               pwm_enable(lcd_pwm);
-
-               gpio_direction_output(S3C2410_GPC(0), 1);
-               gpio_direction_output(S3C2410_GPC(5), 1);
-
-               s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPB1_TOUT1);
-               gpio_direction_output(S3C2410_GPC(7), 1);
-
-               for (i = 1; i < 5; i++)
-                       s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2));
-
-               for (i = 11; i < 16; i++)
-                       s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2));
-
-               for (i = 2; i < 8; i++)
-                       s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2));
-
-               for (i = 11; i < 16; i++)
-                       s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2));
-
-               gpio_direction_output(S3C2410_GPC(10), 1);
-               gpio_direction_output(S3C2410_GPC(6), 1);
-       }
-       enabled = enable;
-}
-
-static void rx1950_bl_power(int enable)
-{
-       static int enabled;
-       if (enabled == enable)
-               return;
-       if (!enable) {
-                       gpio_direction_output(S3C2410_GPB(0), 0);
-       } else {
-                       /* LED driver need a "push" to power on */
-                       gpio_direction_output(S3C2410_GPB(0), 1);
-                       /* Warm up backlight for one period of PWM.
-                        * Without this trick its almost impossible to
-                        * enable backlight with low brightness value
-                        */
-                       ndelay(48000);
-                       s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
-       }
-       enabled = enable;
-}
-
-static int rx1950_backlight_init(struct device *dev)
-{
-       WARN_ON(gpio_request(S3C2410_GPB(0), "Backlight"));
-       lcd_pwm = pwm_request(1, "RX1950 LCD");
-       if (IS_ERR(lcd_pwm)) {
-               dev_err(dev, "Unable to request PWM for LCD power!\n");
-               return PTR_ERR(lcd_pwm);
-       }
-
-       rx1950_lcd_power(1);
-       rx1950_bl_power(1);
-
-       return 0;
-}
-
-static void rx1950_backlight_exit(struct device *dev)
-{
-       rx1950_bl_power(0);
-       rx1950_lcd_power(0);
-
-       pwm_free(lcd_pwm);
-       gpio_free(S3C2410_GPB(0));
-}
-
-
-static int rx1950_backlight_notify(struct device *dev, int brightness)
-{
-       if (!brightness) {
-               rx1950_bl_power(0);
-               rx1950_lcd_power(0);
-       } else {
-               rx1950_lcd_power(1);
-               rx1950_bl_power(1);
-       }
-       return brightness;
-}
-
-static struct platform_pwm_backlight_data rx1950_backlight_data = {
-       .pwm_id = 0,
-       .max_brightness = 24,
-       .dft_brightness = 4,
-       .pwm_period_ns = 48000,
-       .init = rx1950_backlight_init,
-       .notify = rx1950_backlight_notify,
-       .exit = rx1950_backlight_exit,
-};
-
-static struct platform_device rx1950_backlight = {
-       .name = "pwm-backlight",
-       .dev = {
-               .parent = &s3c_device_timer[0].dev,
-               .platform_data = &rx1950_backlight_data,
-       },
-};
-
-static void rx1950_set_mmc_power(unsigned char power_mode, unsigned short vdd)
-{
-       switch (power_mode) {
-       case MMC_POWER_OFF:
-               gpio_direction_output(S3C2410_GPJ(1), 0);
-               break;
-       case MMC_POWER_UP:
-       case MMC_POWER_ON:
-               gpio_direction_output(S3C2410_GPJ(1), 1);
-               break;
-       default:
-               break;
-       }
-}
-
-static struct s3c24xx_mci_pdata rx1950_mmc_cfg __initdata = {
-       .gpio_detect = S3C2410_GPF(5),
-       .gpio_wprotect = S3C2410_GPH(8),
-       .set_power = rx1950_set_mmc_power,
-       .ocr_avail = MMC_VDD_32_33,
-};
-
-static struct mtd_partition rx1950_nand_part[] = {
-       [0] = {
-                       .name = "Boot0",
-                       .offset = 0,
-                       .size = 0x4000,
-                       .mask_flags = MTD_WRITEABLE,
-       },
-       [1] = {
-                       .name = "Boot1",
-                       .offset = MTDPART_OFS_APPEND,
-                       .size = 0x40000,
-                       .mask_flags = MTD_WRITEABLE,
-       },
-       [2] = {
-                       .name = "Kernel",
-                       .offset = MTDPART_OFS_APPEND,
-                       .size = 0x300000,
-                       .mask_flags = 0,
-       },
-       [3] = {
-                       .name = "Filesystem",
-                       .offset = MTDPART_OFS_APPEND,
-                       .size = MTDPART_SIZ_FULL,
-                       .mask_flags = 0,
-       },
-};
-
-static struct s3c2410_nand_set rx1950_nand_sets[] = {
-       [0] = {
-                       .name = "Internal",
-                       .nr_chips = 1,
-                       .nr_partitions = ARRAY_SIZE(rx1950_nand_part),
-                       .partitions = rx1950_nand_part,
-       },
-};
-
-static struct s3c2410_platform_nand rx1950_nand_info = {
-       .tacls = 25,
-       .twrph0 = 50,
-       .twrph1 = 15,
-       .nr_sets = ARRAY_SIZE(rx1950_nand_sets),
-       .sets = rx1950_nand_sets,
-};
-
-static struct s3c2410_udc_mach_info rx1950_udc_cfg __initdata = {
-       .vbus_pin = S3C2410_GPG(5),
-       .vbus_pin_inverted = 1,
-       .pullup_pin = S3C2410_GPJ(5),
-};
-
-static struct s3c2410_ts_mach_info rx1950_ts_cfg __initdata = {
-       .delay = 10000,
-       .presc = 49,
-       .oversampling_shift = 3,
-};
-
-static struct gpio_keys_button rx1950_gpio_keys_table[] = {
-       {
-               .code           = KEY_POWER,
-               .gpio           = S3C2410_GPF(0),
-               .active_low     = 1,
-               .desc           = "Power button",
-               .wakeup         = 1,
-       },
-       {
-               .code           = KEY_F5,
-               .gpio           = S3C2410_GPF(7),
-               .active_low     = 1,
-               .desc           = "Record button",
-       },
-       {
-               .code           = KEY_F1,
-               .gpio           = S3C2410_GPG(0),
-               .active_low     = 1,
-               .desc           = "Calendar button",
-       },
-       {
-               .code           = KEY_F2,
-               .gpio           = S3C2410_GPG(2),
-               .active_low     = 1,
-               .desc           = "Contacts button",
-       },
-       {
-               .code           = KEY_F3,
-               .gpio           = S3C2410_GPG(3),
-               .active_low     = 1,
-               .desc           = "Mail button",
-       },
-       {
-               .code           = KEY_F4,
-               .gpio           = S3C2410_GPG(7),
-               .active_low     = 1,
-               .desc           = "WLAN button",
-       },
-       {
-               .code           = KEY_LEFT,
-               .gpio           = S3C2410_GPG(10),
-               .active_low     = 1,
-               .desc           = "Left button",
-       },
-       {
-               .code           = KEY_RIGHT,
-               .gpio           = S3C2410_GPG(11),
-               .active_low     = 1,
-               .desc           = "Right button",
-       },
-       {
-               .code           = KEY_UP,
-               .gpio           = S3C2410_GPG(4),
-               .active_low     = 1,
-               .desc           = "Up button",
-       },
-       {
-               .code           = KEY_DOWN,
-               .gpio           = S3C2410_GPG(6),
-               .active_low     = 1,
-               .desc           = "Down button",
-       },
-       {
-               .code           = KEY_ENTER,
-               .gpio           = S3C2410_GPG(9),
-               .active_low     = 1,
-               .desc           = "Ok button"
-       },
-};
-
-static struct gpio_keys_platform_data rx1950_gpio_keys_data = {
-       .buttons = rx1950_gpio_keys_table,
-       .nbuttons = ARRAY_SIZE(rx1950_gpio_keys_table),
-};
-
-static struct platform_device rx1950_device_gpiokeys = {
-       .name = "gpio-keys",
-       .dev.platform_data = &rx1950_gpio_keys_data,
-};
-
-static struct uda1380_platform_data uda1380_info = {
-       .gpio_power     = S3C2410_GPJ(0),
-       .gpio_reset     = S3C2410_GPD(0),
-       .dac_clk        = UDA1380_DAC_CLK_SYSCLK,
-};
-
-static struct i2c_board_info rx1950_i2c_devices[] = {
-       {
-               I2C_BOARD_INFO("uda1380", 0x1a),
-               .platform_data = &uda1380_info,
-       },
-};
-
-static struct platform_device *rx1950_devices[] __initdata = {
-       &s3c_device_lcd,
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_iis,
-       &samsung_asoc_dma,
-       &s3c_device_usbgadget,
-       &s3c_device_rtc,
-       &s3c_device_nand,
-       &s3c_device_sdi,
-       &s3c_device_adc,
-       &s3c_device_ts,
-       &s3c_device_timer[0],
-       &s3c_device_timer[1],
-       &rx1950_backlight,
-       &rx1950_device_gpiokeys,
-       &power_supply,
-       &rx1950_battery,
-       &rx1950_leds,
-};
-
-static struct clk *rx1950_clocks[] __initdata = {
-       &s3c24xx_clkout0,
-       &s3c24xx_clkout1,
-};
-
-static void __init rx1950_map_io(void)
-{
-       s3c24xx_clkout0.parent  = &clk_h;
-       s3c24xx_clkout1.parent  = &clk_f;
-
-       s3c24xx_register_clocks(rx1950_clocks, ARRAY_SIZE(rx1950_clocks));
-
-       s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc));
-       s3c24xx_init_clocks(16934000);
-       s3c24xx_init_uarts(rx1950_uartcfgs, ARRAY_SIZE(rx1950_uartcfgs));
-
-       /* setup PM */
-
-#ifdef CONFIG_PM_H1940
-       memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 8);
-#endif
-
-       s3c_pm_init();
-}
-
-static void __init rx1950_init_machine(void)
-{
-       int i;
-
-       s3c24xx_fb_set_platdata(&rx1950_lcd_cfg);
-       s3c24xx_udc_set_platdata(&rx1950_udc_cfg);
-       s3c24xx_ts_set_platdata(&rx1950_ts_cfg);
-       s3c24xx_mci_set_platdata(&rx1950_mmc_cfg);
-       s3c_i2c0_set_platdata(NULL);
-       s3c_nand_set_platdata(&rx1950_nand_info);
-
-       /* Turn off suspend on both USB ports, and switch the
-        * selectable USB port to USB device mode. */
-       s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
-                                               S3C2410_MISCCR_USBSUSPND0 |
-                                               S3C2410_MISCCR_USBSUSPND1, 0x0);
-
-       /* mmc power is disabled by default */
-       WARN_ON(gpio_request(S3C2410_GPJ(1), "MMC power"));
-       gpio_direction_output(S3C2410_GPJ(1), 0);
-
-       for (i = 0; i < 8; i++)
-               WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power"));
-
-       for (i = 10; i < 16; i++)
-               WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power"));
-
-       for (i = 2; i < 8; i++)
-               WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power"));
-
-       for (i = 11; i < 16; i++)
-               WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power"));
-
-       WARN_ON(gpio_request(S3C2410_GPB(1), "LCD power"));
-
-       WARN_ON(gpio_request(S3C2410_GPA(3), "Red blink"));
-       WARN_ON(gpio_request(S3C2410_GPA(4), "Green blink"));
-       WARN_ON(gpio_request(S3C2410_GPJ(6), "LED blink"));
-       gpio_direction_output(S3C2410_GPA(3), 0);
-       gpio_direction_output(S3C2410_GPA(4), 0);
-       gpio_direction_output(S3C2410_GPJ(6), 0);
-
-       platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices));
-
-       i2c_register_board_info(0, rx1950_i2c_devices,
-               ARRAY_SIZE(rx1950_i2c_devices));
-}
-
-/* H1940 and RX3715 need to reserve this for suspend */
-static void __init rx1950_reserve(void)
-{
-       memblock_reserve(0x30003000, 0x1000);
-       memblock_reserve(0x30081000, 0x1000);
-}
-
-MACHINE_START(RX1950, "HP iPAQ RX1950")
-    /* Maintainers: Vasily Khoruzhick */
-       .atag_offset = 0x100,
-       .map_io = rx1950_map_io,
-       .reserve        = rx1950_reserve,
-       .init_irq = s3c24xx_init_irq,
-       .init_machine = rx1950_init_machine,
-       .timer = &s3c24xx_timer,
-       .restart        = s3c244x_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
deleted file mode 100644 (file)
index 56af354..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-/* linux/arch/arm/mach-s3c2440/mach-rx3715.c
- *
- * Copyright (c) 2003-2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * http://www.handhelds.org/projects/rx3715.html
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/memblock.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/serial.h>
-#include <linux/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-lcd.h>
-
-#include <mach/h1940.h>
-#include <plat/nand.h>
-#include <mach/fb.h>
-
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/pm.h>
-
-#include "common.h"
-
-static struct map_desc rx3715_iodesc[] __initdata = {
-       /* dump ISA space somewhere unused */
-
-       {
-               .virtual        = (u32)S3C24XX_VA_ISA_WORD,
-               .pfn            = __phys_to_pfn(S3C2410_CS3),
-               .length         = SZ_1M,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
-               .pfn            = __phys_to_pfn(S3C2410_CS3),
-               .length         = SZ_1M,
-               .type           = MT_DEVICE,
-       },
-};
-
-static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-               .clk_sel        = S3C2410_UCON_CLKSEL3,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x00,
-               .clk_sel        = S3C2410_UCON_CLKSEL3,
-       },
-       /* IR port */
-       [2] = {
-               .hwport      = 2,
-               .uart_flags  = UPF_CONS_FLOW,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x43,
-               .ufcon       = 0x51,
-               .clk_sel        = S3C2410_UCON_CLKSEL3,
-       }
-};
-
-/* framebuffer lcd controller information */
-
-static struct s3c2410fb_display rx3715_lcdcfg __initdata = {
-       .lcdcon5 =      S3C2410_LCDCON5_INVVLINE |
-                       S3C2410_LCDCON5_FRM565 |
-                       S3C2410_LCDCON5_HWSWP,
-
-       .type           = S3C2410_LCDCON1_TFT,
-       .width          = 240,
-       .height         = 320,
-
-       .pixclock       = 260000,
-       .xres           = 240,
-       .yres           = 320,
-       .bpp            = 16,
-       .left_margin    = 36,
-       .right_margin   = 36,
-       .hsync_len      = 8,
-       .upper_margin   = 6,
-       .lower_margin   = 7,
-       .vsync_len      = 3,
-};
-
-static struct s3c2410fb_mach_info rx3715_fb_info __initdata = {
-
-       .displays =     &rx3715_lcdcfg,
-       .num_displays = 1,
-       .default_display = 0,
-
-       .lpcsel =       0xf82,
-
-       .gpccon =       0xaa955699,
-       .gpccon_mask =  0xffc003cc,
-       .gpcup =        0x0000ffff,
-       .gpcup_mask =   0xffffffff,
-
-       .gpdcon =       0xaa95aaa1,
-       .gpdcon_mask =  0xffc0fff0,
-       .gpdup =        0x0000faff,
-       .gpdup_mask =   0xffffffff,
-};
-
-static struct mtd_partition __initdata rx3715_nand_part[] = {
-       [0] = {
-               .name           = "Whole Flash",
-               .offset         = 0,
-               .size           = MTDPART_SIZ_FULL,
-               .mask_flags     = MTD_WRITEABLE,
-       }
-};
-
-static struct s3c2410_nand_set __initdata rx3715_nand_sets[] = {
-       [0] = {
-               .name           = "Internal",
-               .nr_chips       = 1,
-               .nr_partitions  = ARRAY_SIZE(rx3715_nand_part),
-               .partitions     = rx3715_nand_part,
-       },
-};
-
-static struct s3c2410_platform_nand __initdata rx3715_nand_info = {
-       .tacls          = 25,
-       .twrph0         = 50,
-       .twrph1         = 15,
-       .nr_sets        = ARRAY_SIZE(rx3715_nand_sets),
-       .sets           = rx3715_nand_sets,
-};
-
-static struct platform_device *rx3715_devices[] __initdata = {
-       &s3c_device_ohci,
-       &s3c_device_lcd,
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_iis,
-       &s3c_device_nand,
-};
-
-static void __init rx3715_map_io(void)
-{
-       s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
-       s3c24xx_init_clocks(16934000);
-       s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
-}
-
-/* H1940 and RX3715 need to reserve this for suspend */
-static void __init rx3715_reserve(void)
-{
-       memblock_reserve(0x30003000, 0x1000);
-       memblock_reserve(0x30081000, 0x1000);
-}
-
-static void __init rx3715_init_irq(void)
-{
-       s3c24xx_init_irq();
-}
-
-static void __init rx3715_init_machine(void)
-{
-#ifdef CONFIG_PM_H1940
-       memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
-#endif
-       s3c_pm_init();
-
-       s3c_nand_set_platdata(&rx3715_nand_info);
-       s3c24xx_fb_set_platdata(&rx3715_fb_info);
-       platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices));
-}
-
-MACHINE_START(RX3715, "IPAQ-RX3715")
-       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
-       .atag_offset    = 0x100,
-       .map_io         = rx3715_map_io,
-       .reserve        = rx3715_reserve,
-       .init_irq       = rx3715_init_irq,
-       .init_machine   = rx3715_init_machine,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c244x_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c
deleted file mode 100644 (file)
index 83a1036..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-/* linux/arch/arm/mach-s3c2440/mach-smdk2440.c
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * http://www.fluff.org/ben/smdk2440/
- *
- * Thanks to Dimity Andric and TomTom for the loan of an SMDK2440.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-lcd.h>
-
-#include <mach/idle.h>
-#include <mach/fb.h>
-#include <plat/iic.h>
-
-#include <plat/s3c2410.h>
-#include <plat/s3c244x.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#include <plat/common-smdk.h>
-
-#include "common.h"
-
-static struct map_desc smdk2440_iodesc[] __initdata = {
-       /* ISA IO Space map (memory space selected by A24) */
-
-       {
-               .virtual        = (u32)S3C24XX_VA_ISA_WORD,
-               .pfn            = __phys_to_pfn(S3C2410_CS2),
-               .length         = 0x10000,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
-               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
-               .length         = SZ_4M,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
-               .pfn            = __phys_to_pfn(S3C2410_CS2),
-               .length         = 0x10000,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
-               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
-               .length         = SZ_4M,
-               .type           = MT_DEVICE,
-       }
-};
-
-#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       },
-       /* IR port */
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x43,
-               .ufcon       = 0x51,
-       }
-};
-
-/* LCD driver info */
-
-static struct s3c2410fb_display smdk2440_lcd_cfg __initdata = {
-
-       .lcdcon5        = S3C2410_LCDCON5_FRM565 |
-                         S3C2410_LCDCON5_INVVLINE |
-                         S3C2410_LCDCON5_INVVFRAME |
-                         S3C2410_LCDCON5_PWREN |
-                         S3C2410_LCDCON5_HWSWP,
-
-       .type           = S3C2410_LCDCON1_TFT,
-
-       .width          = 240,
-       .height         = 320,
-
-       .pixclock       = 166667, /* HCLK 60 MHz, divisor 10 */
-       .xres           = 240,
-       .yres           = 320,
-       .bpp            = 16,
-       .left_margin    = 20,
-       .right_margin   = 8,
-       .hsync_len      = 4,
-       .upper_margin   = 8,
-       .lower_margin   = 7,
-       .vsync_len      = 4,
-};
-
-static struct s3c2410fb_mach_info smdk2440_fb_info __initdata = {
-       .displays       = &smdk2440_lcd_cfg,
-       .num_displays   = 1,
-       .default_display = 0,
-
-#if 0
-       /* currently setup by downloader */
-       .gpccon         = 0xaa940659,
-       .gpccon_mask    = 0xffffffff,
-       .gpcup          = 0x0000ffff,
-       .gpcup_mask     = 0xffffffff,
-       .gpdcon         = 0xaa84aaa0,
-       .gpdcon_mask    = 0xffffffff,
-       .gpdup          = 0x0000faff,
-       .gpdup_mask     = 0xffffffff,
-#endif
-
-       .lpcsel         = ((0xCE6) & ~7) | 1<<4,
-};
-
-static struct platform_device *smdk2440_devices[] __initdata = {
-       &s3c_device_ohci,
-       &s3c_device_lcd,
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_iis,
-};
-
-static void __init smdk2440_map_io(void)
-{
-       s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
-       s3c24xx_init_clocks(16934400);
-       s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
-}
-
-static void __init smdk2440_machine_init(void)
-{
-       s3c24xx_fb_set_platdata(&smdk2440_fb_info);
-       s3c_i2c0_set_platdata(NULL);
-
-       platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
-       smdk_machine_init();
-}
-
-MACHINE_START(S3C2440, "SMDK2440")
-       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
-       .atag_offset    = 0x100,
-
-       .init_irq       = s3c24xx_init_irq,
-       .map_io         = smdk2440_map_io,
-       .init_machine   = smdk2440_machine_init,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c244x_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c
deleted file mode 100644 (file)
index 2b3dddb..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/* linux/arch/arm/mach-s3c2440/s3c2440.c
- *
- * Copyright (c) 2004-2006 Simtec Electronics
- *   Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C2440 Mobile CPU support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/device.h>
-#include <linux/syscore_ops.h>
-#include <linux/gpio.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/s3c244x.h>
-#include <plat/pm.h>
-
-#include <plat/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-
-static struct device s3c2440_dev = {
-       .bus            = &s3c2440_subsys,
-};
-
-int __init s3c2440_init(void)
-{
-       printk("S3C2440: Initialising architecture\n");
-
-       /* change irq for watchdog */
-
-       s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
-       s3c_device_wdt.resource[1].end   = IRQ_S3C2440_WDT;
-
-       /* register suspend/resume handlers */
-
-#ifdef CONFIG_PM
-       register_syscore_ops(&s3c2410_pm_syscore_ops);
-#endif
-       register_syscore_ops(&s3c244x_pm_syscore_ops);
-       register_syscore_ops(&s3c24xx_irq_syscore_ops);
-
-       /* register our system device for everything else */
-
-       return device_register(&s3c2440_dev);
-}
-
-void __init s3c2440_map_io(void)
-{
-       s3c244x_map_io();
-
-       s3c24xx_gpiocfg_default.set_pull = s3c24xx_gpio_setpull_1up;
-       s3c24xx_gpiocfg_default.get_pull = s3c24xx_gpio_getpull_1up;
-}
diff --git a/arch/arm/mach-s3c2440/s3c2442.c b/arch/arm/mach-s3c2440/s3c2442.c
deleted file mode 100644 (file)
index 22cb7c9..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-/* linux/arch/arm/mach-s3c2442/s3c2442.c
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2442 core and lock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/syscore_ops.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/mutex.h>
-#include <linux/gpio.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <linux/atomic.h>
-#include <asm/irq.h>
-
-#include <mach/regs-clock.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/s3c244x.h>
-#include <plat/pm.h>
-
-#include <plat/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-
-/* S3C2442 extended clock support */
-
-static unsigned long s3c2442_camif_upll_round(struct clk *clk,
-                                             unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       int div;
-
-       if (rate > parent_rate)
-               return parent_rate;
-
-       div = parent_rate / rate;
-
-       if (div == 3)
-               return parent_rate / 3;
-
-       /* note, we remove the +/- 1 calculations for the divisor */
-
-       div /= 2;
-
-       if (div < 1)
-               div = 1;
-       else if (div > 16)
-               div = 16;
-
-       return parent_rate / (div * 2);
-}
-
-static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
-
-       rate = s3c2442_camif_upll_round(clk, rate);
-
-       camdivn &= ~S3C2442_CAMDIVN_CAMCLK_DIV3;
-
-       if (rate == parent_rate) {
-               camdivn &= ~S3C2440_CAMDIVN_CAMCLK_SEL;
-       } else if ((parent_rate / rate) == 3) {
-               camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
-               camdivn |= S3C2442_CAMDIVN_CAMCLK_DIV3;
-       } else {
-               camdivn &= ~S3C2440_CAMDIVN_CAMCLK_MASK;
-               camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
-               camdivn |= (((parent_rate / rate) / 2) - 1);
-       }
-
-       __raw_writel(camdivn, S3C2440_CAMDIVN);
-
-       return 0;
-}
-
-/* Extra S3C2442 clocks */
-
-static struct clk s3c2442_clk_cam = {
-       .name           = "camif",
-       .id             = -1,
-       .enable         = s3c2410_clkcon_enable,
-       .ctrlbit        = S3C2440_CLKCON_CAMERA,
-};
-
-static struct clk s3c2442_clk_cam_upll = {
-       .name           = "camif-upll",
-       .id             = -1,
-       .ops            = &(struct clk_ops) {
-               .set_rate       = s3c2442_camif_upll_setrate,
-               .round_rate     = s3c2442_camif_upll_round,
-       },
-};
-
-static int s3c2442_clk_add(struct device *dev, struct subsys_interface *sif)
-{
-       struct clk *clock_upll;
-       struct clk *clock_h;
-       struct clk *clock_p;
-
-       clock_p = clk_get(NULL, "pclk");
-       clock_h = clk_get(NULL, "hclk");
-       clock_upll = clk_get(NULL, "upll");
-
-       if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
-               printk(KERN_ERR "S3C2442: Failed to get parent clocks\n");
-               return -EINVAL;
-       }
-
-       s3c2442_clk_cam.parent = clock_h;
-       s3c2442_clk_cam_upll.parent = clock_upll;
-
-       s3c24xx_register_clock(&s3c2442_clk_cam);
-       s3c24xx_register_clock(&s3c2442_clk_cam_upll);
-
-       clk_disable(&s3c2442_clk_cam);
-
-       return 0;
-}
-
-static struct subsys_interface s3c2442_clk_interface = {
-       .name           = "s3c2442_clk",
-       .subsys         = &s3c2442_subsys,
-       .add_dev        = s3c2442_clk_add,
-};
-
-static __init int s3c2442_clk_init(void)
-{
-       return subsys_interface_register(&s3c2442_clk_interface);
-}
-
-arch_initcall(s3c2442_clk_init);
-
-
-static struct device s3c2442_dev = {
-       .bus            = &s3c2442_subsys,
-};
-
-int __init s3c2442_init(void)
-{
-       printk("S3C2442: Initialising architecture\n");
-
-#ifdef CONFIG_PM
-       register_syscore_ops(&s3c2410_pm_syscore_ops);
-#endif
-       register_syscore_ops(&s3c244x_pm_syscore_ops);
-       register_syscore_ops(&s3c24xx_irq_syscore_ops);
-
-       return device_register(&s3c2442_dev);
-}
-
-void __init s3c2442_map_io(void)
-{
-       s3c244x_map_io();
-
-       s3c24xx_gpiocfg_default.set_pull = s3c24xx_gpio_setpull_1down;
-       s3c24xx_gpiocfg_default.get_pull = s3c24xx_gpio_getpull_1down;
-}
diff --git a/arch/arm/mach-s3c2440/s3c244x-clock.c b/arch/arm/mach-s3c2440/s3c244x-clock.c
deleted file mode 100644 (file)
index 6d9b688..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/s3c24xx-clock.c
- *
- * Copyright (c) 2004-2008 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2440/S3C2442 Common clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <linux/atomic.h>
-#include <asm/irq.h>
-
-#include <mach/regs-clock.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent)
-{
-       unsigned long camdivn;
-       unsigned long dvs;
-
-       if (parent == &clk_f)
-               dvs = 0;
-       else if (parent == &clk_h)
-               dvs = S3C2440_CAMDIVN_DVSEN;
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       camdivn  = __raw_readl(S3C2440_CAMDIVN);
-       camdivn &= ~S3C2440_CAMDIVN_DVSEN;
-       camdivn |= dvs;
-       __raw_writel(camdivn, S3C2440_CAMDIVN);
-
-       return 0;
-}
-
-static struct clk clk_arm = {
-       .name           = "armclk",
-       .id             = -1,
-       .ops            = &(struct clk_ops) {
-               .set_parent     = s3c2440_setparent_armclk,
-       },
-};
-
-static int s3c244x_clk_add(struct device *dev, struct subsys_interface *sif)
-{
-       unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
-       unsigned long clkdivn;
-       struct clk *clock_upll;
-       int ret;
-
-       printk("S3C244X: Clock Support, DVS %s\n",
-              (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
-
-       clk_arm.parent = (camdivn & S3C2440_CAMDIVN_DVSEN) ? &clk_h : &clk_f;
-
-       ret = s3c24xx_register_clock(&clk_arm);
-       if (ret < 0) {
-               printk(KERN_ERR "S3C24XX: Failed to add armclk (%d)\n", ret);
-               return ret;
-       }
-
-       clock_upll = clk_get(NULL, "upll");
-       if (IS_ERR(clock_upll)) {
-               printk(KERN_ERR "S3C244X: Failed to get upll clock\n");
-               return -ENOENT;
-       }
-
-       /* check rate of UPLL, and if it is near 96MHz, then change
-        * to using half the UPLL rate for the system */
-
-       if (clk_get_rate(clock_upll) > (94 * MHZ)) {
-               clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
-
-               spin_lock(&clocks_lock);
-
-               clkdivn = __raw_readl(S3C2410_CLKDIVN);
-               clkdivn |= S3C2440_CLKDIVN_UCLK;
-               __raw_writel(clkdivn, S3C2410_CLKDIVN);
-
-               spin_unlock(&clocks_lock);
-       }
-
-       return 0;
-}
-
-static struct subsys_interface s3c2440_clk_interface = {
-       .name           = "s3c2440_clk",
-       .subsys         = &s3c2440_subsys,
-       .add_dev        = s3c244x_clk_add,
-};
-
-static int s3c2440_clk_init(void)
-{
-       return subsys_interface_register(&s3c2440_clk_interface);
-}
-
-arch_initcall(s3c2440_clk_init);
-
-static struct subsys_interface s3c2442_clk_interface = {
-       .name           = "s3c2442_clk",
-       .subsys         = &s3c2442_subsys,
-       .add_dev        = s3c244x_clk_add,
-};
-
-static int s3c2442_clk_init(void)
-{
-       return subsys_interface_register(&s3c2442_clk_interface);
-}
-
-arch_initcall(s3c2442_clk_init);
diff --git a/arch/arm/mach-s3c2440/s3c244x-irq.c b/arch/arm/mach-s3c2440/s3c244x-irq.c
deleted file mode 100644 (file)
index 5fe8e58..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/s3c244x-irq.c
- *
- * Copyright (c) 2003-2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <asm/mach/irq.h>
-
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/irq.h>
-
-/* camera irq */
-
-static void s3c_irq_demux_cam(unsigned int irq,
-                             struct irq_desc *desc)
-{
-       unsigned int subsrc, submsk;
-
-       /* read the current pending interrupts, and the mask
-        * for what it is available */
-
-       subsrc = __raw_readl(S3C2410_SUBSRCPND);
-       submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-       subsrc &= ~submsk;
-       subsrc >>= 11;
-       subsrc &= 3;
-
-       if (subsrc != 0) {
-               if (subsrc & 1) {
-                       generic_handle_irq(IRQ_S3C2440_CAM_C);
-               }
-               if (subsrc & 2) {
-                       generic_handle_irq(IRQ_S3C2440_CAM_P);
-               }
-       }
-}
-
-#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
-
-static void
-s3c_irq_cam_mask(struct irq_data *data)
-{
-       s3c_irqsub_mask(data->irq, INTMSK_CAM, 3 << 11);
-}
-
-static void
-s3c_irq_cam_unmask(struct irq_data *data)
-{
-       s3c_irqsub_unmask(data->irq, INTMSK_CAM);
-}
-
-static void
-s3c_irq_cam_ack(struct irq_data *data)
-{
-       s3c_irqsub_maskack(data->irq, INTMSK_CAM, 3 << 11);
-}
-
-static struct irq_chip s3c_irq_cam = {
-       .irq_mask       = s3c_irq_cam_mask,
-       .irq_unmask     = s3c_irq_cam_unmask,
-       .irq_ack        = s3c_irq_cam_ack,
-};
-
-static int s3c244x_irq_add(struct device *dev, struct subsys_interface *sif)
-{
-       unsigned int irqno;
-
-       irq_set_chip_and_handler(IRQ_NFCON, &s3c_irq_level_chip,
-                                handle_level_irq);
-       set_irq_flags(IRQ_NFCON, IRQF_VALID);
-
-       /* add chained handler for camera */
-
-       irq_set_chip_and_handler(IRQ_CAM, &s3c_irq_level_chip,
-                                handle_level_irq);
-       irq_set_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
-
-       for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
-               irq_set_chip_and_handler(irqno, &s3c_irq_cam,
-                                        handle_level_irq);
-               set_irq_flags(irqno, IRQF_VALID);
-       }
-
-       return 0;
-}
-
-static struct subsys_interface s3c2440_irq_interface = {
-       .name           = "s3c2440_irq",
-       .subsys         = &s3c2440_subsys,
-       .add_dev        = s3c244x_irq_add,
-};
-
-static int s3c2440_irq_init(void)
-{
-       return subsys_interface_register(&s3c2440_irq_interface);
-}
-
-arch_initcall(s3c2440_irq_init);
-
-static struct subsys_interface s3c2442_irq_interface = {
-       .name           = "s3c2442_irq",
-       .subsys         = &s3c2442_subsys,
-       .add_dev        = s3c244x_irq_add,
-};
-
-
-static int s3c2442_irq_init(void)
-{
-       return subsys_interface_register(&s3c2442_irq_interface);
-}
-
-arch_initcall(s3c2442_irq_init);
diff --git a/arch/arm/mach-s3c2440/s3c244x.c b/arch/arm/mach-s3c2440/s3c244x.c
deleted file mode 100644 (file)
index d15852f..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/s3c244x.c
- *
- * Copyright (c) 2004-2006 Simtec Electronics
- *   Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C2440 and S3C2442 Mobile CPU support (not S3C2443)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/device.h>
-#include <linux/syscore_ops.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <plat/cpu-freq.h>
-
-#include <mach/regs-clock.h>
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-gpioj.h>
-#include <mach/regs-dsc.h>
-
-#include <plat/s3c2410.h>
-#include <plat/s3c244x.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/pll.h>
-#include <plat/nand-core.h>
-#include <plat/watchdog-reset.h>
-
-static struct map_desc s3c244x_iodesc[] __initdata = {
-       IODESC_ENT(CLKPWR),
-       IODESC_ENT(TIMER),
-       IODESC_ENT(WATCHDOG),
-};
-
-/* uart initialisation */
-
-void __init s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
-       s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
-}
-
-void __init s3c244x_map_io(void)
-{
-       /* register our io-tables */
-
-       iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc));
-
-       /* rename any peripherals used differing from the s3c2410 */
-
-       s3c_device_sdi.name  = "s3c2440-sdi";
-       s3c_device_i2c0.name  = "s3c2440-i2c";
-       s3c_nand_setname("s3c2440-nand");
-       s3c_device_ts.name = "s3c2440-ts";
-       s3c_device_usbgadget.name = "s3c2440-usbgadget";
-}
-
-void __init_or_cpufreq s3c244x_setup_clocks(void)
-{
-       struct clk *xtal_clk;
-       unsigned long clkdiv;
-       unsigned long camdiv;
-       unsigned long xtal;
-       unsigned long hclk, fclk, pclk;
-       int hdiv = 1;
-
-       xtal_clk = clk_get(NULL, "xtal");
-       xtal = clk_get_rate(xtal_clk);
-       clk_put(xtal_clk);
-
-       fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
-
-       clkdiv = __raw_readl(S3C2410_CLKDIVN);
-       camdiv = __raw_readl(S3C2440_CAMDIVN);
-
-       /* work out clock scalings */
-
-       switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
-       case S3C2440_CLKDIVN_HDIVN_1:
-               hdiv = 1;
-               break;
-
-       case S3C2440_CLKDIVN_HDIVN_2:
-               hdiv = 2;
-               break;
-
-       case S3C2440_CLKDIVN_HDIVN_4_8:
-               hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
-               break;
-
-       case S3C2440_CLKDIVN_HDIVN_3_6:
-               hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
-               break;
-       }
-
-       hclk = fclk / hdiv;
-       pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN) ? 2 : 1);
-
-       /* print brief summary of clocks, etc */
-
-       printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
-              print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
-
-       s3c24xx_setup_clocks(fclk, hclk, pclk);
-}
-
-void __init s3c244x_init_clocks(int xtal)
-{
-       /* initialise the clocks here, to allow other things like the
-        * console to use them, and to add new ones after the initialisation
-        */
-
-       s3c24xx_register_baseclocks(xtal);
-       s3c244x_setup_clocks();
-       s3c2410_baseclk_add();
-}
-
-/* Since the S3C2442 and S3C2440 share items, put both subsystems here */
-
-struct bus_type s3c2440_subsys = {
-       .name           = "s3c2440-core",
-       .dev_name       = "s3c2440-core",
-};
-
-struct bus_type s3c2442_subsys = {
-       .name           = "s3c2442-core",
-       .dev_name       = "s3c2442-core",
-};
-
-/* need to register the subsystem before we actually register the device, and
- * we also need to ensure that it has been initialised before any of the
- * drivers even try to use it (even if not on an s3c2440 based system)
- * as a driver which may support both 2410 and 2440 may try and use it.
-*/
-
-static int __init s3c2440_core_init(void)
-{
-       return subsys_system_register(&s3c2440_subsys, NULL);
-}
-
-core_initcall(s3c2440_core_init);
-
-static int __init s3c2442_core_init(void)
-{
-       return subsys_system_register(&s3c2442_subsys, NULL);
-}
-
-core_initcall(s3c2442_core_init);
-
-
-#ifdef CONFIG_PM
-static struct sleep_save s3c244x_sleep[] = {
-       SAVE_ITEM(S3C2440_DSC0),
-       SAVE_ITEM(S3C2440_DSC1),
-       SAVE_ITEM(S3C2440_GPJDAT),
-       SAVE_ITEM(S3C2440_GPJCON),
-       SAVE_ITEM(S3C2440_GPJUP)
-};
-
-static int s3c244x_suspend(void)
-{
-       s3c_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
-       return 0;
-}
-
-static void s3c244x_resume(void)
-{
-       s3c_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
-}
-#else
-#define s3c244x_suspend NULL
-#define s3c244x_resume  NULL
-#endif
-
-struct syscore_ops s3c244x_pm_syscore_ops = {
-       .suspend        = s3c244x_suspend,
-       .resume         = s3c244x_resume,
-};
-
-void s3c244x_restart(char mode, const char *cmd)
-{
-       if (mode == 's')
-               soft_restart(0);
-
-       arch_wdt_reset();
-
-       /* we'll take a jump through zero as a poor second */
-       soft_restart(0);
-}
diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig
deleted file mode 100644 (file)
index 8814031..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright 2007 Simtec Electronics
-#
-# Licensed under GPLv2
-
-config CPU_S3C2443
-       bool
-       depends on ARCH_S3C2410
-       select CPU_ARM920T
-       select S3C2443_DMA if S3C2410_DMA
-       select CPU_LLSERIAL_S3C2440
-       select SAMSUNG_CLKSRC
-       select S3C2443_CLOCK
-       help
-         Support for the S3C2443 SoC from the S3C24XX line
-
-config S3C2443_DMA
-       bool
-       depends on CPU_S3C2443
-       help
-         Internal config node for S3C2443 DMA support
-
-menu "S3C2443 Machines"
-
-config MACH_SMDK2443
-       bool "SMDK2443"
-       select CPU_S3C2443
-       select MACH_SMDK
-       select S3C_DEV_HSMMC1
-       help
-         Say Y here if you are using an SMDK2443
-
-endmenu
diff --git a/arch/arm/mach-s3c2443/Makefile b/arch/arm/mach-s3c2443/Makefile
deleted file mode 100644 (file)
index d1843c9..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-# arch/arm/mach-s3c2443/Makefile
-#
-# Copyright 2007 Simtec Electronics
-#
-# Licensed under GPLv2
-
-obj-y                          :=
-obj-m                          :=
-obj-n                          :=
-obj-                           :=
-
-obj-$(CONFIG_CPU_S3C2443)      += s3c2443.o
-obj-$(CONFIG_CPU_S3C2443)      += irq.o
-obj-$(CONFIG_CPU_S3C2443)      += clock.o
-
-obj-$(CONFIG_S3C2443_DMA)      += dma.o
-
-# Machine support
-
-obj-$(CONFIG_MACH_SMDK2443)    += mach-smdk2443.o
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
deleted file mode 100644 (file)
index 6dde269..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-/* linux/arch/arm/mach-s3c2443/clock.c
- *
- * Copyright (c) 2007, 2010 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2443 Clock control support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/init.h>
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-#include <linux/serial_core.h>
-#include <linux/io.h>
-
-#include <asm/mach/map.h>
-
-#include <mach/hardware.h>
-
-#include <mach/regs-s3c2443-clock.h>
-
-#include <plat/cpu-freq.h>
-
-#include <plat/s3c2443.h>
-#include <plat/clock.h>
-#include <plat/clock-clksrc.h>
-#include <plat/cpu.h>
-
-/* We currently have to assume that the system is running
- * from the XTPll input, and that all ***REFCLKs are being
- * fed from it, as we cannot read the state of OM[4] from
- * software.
- *
- * It would be possible for each board initialisation to
- * set the correct muxing at initialisation
-*/
-
-/* clock selections */
-
-/* armdiv
- *
- * this clock is sourced from msysclk and can have a number of
- * divider values applied to it to then be fed into armclk.
- * The real clock definition is done in s3c2443-clock.c,
- * only the armdiv divisor table must be defined here.
-*/
-
-static unsigned int armdiv[16] = {
-       [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 1,
-       [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 2,
-       [S3C2443_CLKDIV0_ARMDIV_3 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 3,
-       [S3C2443_CLKDIV0_ARMDIV_4 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 4,
-       [S3C2443_CLKDIV0_ARMDIV_6 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 6,
-       [S3C2443_CLKDIV0_ARMDIV_8 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 8,
-       [S3C2443_CLKDIV0_ARMDIV_12 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]     = 12,
-       [S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]     = 16,
-};
-
-/* hsspi
- *
- * high-speed spi clock, sourced from esysclk
-*/
-
-static struct clksrc_clk clk_hsspi = {
-       .clk    = {
-               .name           = "hsspi-if",
-               .parent         = &clk_esysclk.clk,
-               .ctrlbit        = S3C2443_SCLKCON_HSSPICLK,
-               .enable         = s3c2443_clkcon_enable_s,
-       },
-       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
-};
-
-
-/* clk_hsmcc_div
- *
- * this clock is sourced from epll, and is fed through a divider,
- * to a mux controlled by sclkcon where either it or a extclk can
- * be fed to the hsmmc block
-*/
-
-static struct clksrc_clk clk_hsmmc_div = {
-       .clk    = {
-               .name           = "hsmmc-div",
-               .devname        = "s3c-sdhci.1",
-               .parent         = &clk_esysclk.clk,
-       },
-       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
-};
-
-static int s3c2443_setparent_hsmmc(struct clk *clk, struct clk *parent)
-{
-       unsigned long clksrc = __raw_readl(S3C2443_SCLKCON);
-
-       clksrc &= ~(S3C2443_SCLKCON_HSMMCCLK_EXT |
-                   S3C2443_SCLKCON_HSMMCCLK_EPLL);
-
-       if (parent == &clk_epll)
-               clksrc |= S3C2443_SCLKCON_HSMMCCLK_EPLL;
-       else if (parent == &clk_ext)
-               clksrc |= S3C2443_SCLKCON_HSMMCCLK_EXT;
-       else
-               return -EINVAL;
-
-       if (clk->usage > 0) {
-               __raw_writel(clksrc, S3C2443_SCLKCON);
-       }
-
-       clk->parent = parent;
-       return 0;
-}
-
-static int s3c2443_enable_hsmmc(struct clk *clk, int enable)
-{
-       return s3c2443_setparent_hsmmc(clk, clk->parent);
-}
-
-static struct clk clk_hsmmc = {
-       .name           = "hsmmc-if",
-       .devname        = "s3c-sdhci.1",
-       .parent         = &clk_hsmmc_div.clk,
-       .enable         = s3c2443_enable_hsmmc,
-       .ops            = &(struct clk_ops) {
-               .set_parent     = s3c2443_setparent_hsmmc,
-       },
-};
-
-/* standard clock definitions */
-
-static struct clk init_clocks_off[] = {
-       {
-               .name           = "sdi",
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_SDI,
-       }, {
-               .name           = "spi",
-               .devname        = "s3c2410-spi.0",
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_SPI0,
-       }, {
-               .name           = "spi",
-               .devname        = "s3c2410-spi.1",
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_SPI1,
-       }
-};
-
-/* clocks to add straight away */
-
-static struct clksrc_clk *clksrcs[] __initdata = {
-       &clk_hsspi,
-       &clk_hsmmc_div,
-};
-
-static struct clk *clks[] __initdata = {
-       &clk_hsmmc,
-};
-
-void __init_or_cpufreq s3c2443_setup_clocks(void)
-{
-       s3c2443_common_setup_clocks(s3c2443_get_mpll);
-}
-
-void __init s3c2443_init_clocks(int xtal)
-{
-       unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
-       int ptr;
-
-       clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
-       clk_epll.parent = &clk_epllref.clk;
-
-       s3c2443_common_init_clocks(xtal, s3c2443_get_mpll,
-                                  armdiv, ARRAY_SIZE(armdiv),
-                                  S3C2443_CLKDIV0_ARMDIV_MASK);
-
-       s3c2443_setup_clocks();
-
-       s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
-
-       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
-               s3c_register_clksrc(clksrcs[ptr], 1);
-
-       /* We must be careful disabling the clocks we are not intending to
-        * be using at boot time, as subsystems such as the LCD which do
-        * their own DMA requests to the bus can cause the system to lockup
-        * if they where in the middle of requesting bus access.
-        *
-        * Disabling the LCD clock if the LCD is active is very dangerous,
-        * and therefore the bootloader should be careful to not enable
-        * the LCD clock if it is not needed.
-       */
-
-       /* install (and disable) the clocks we do not need immediately */
-
-       s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-       s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-
-       s3c_pwmclk_init();
-}
diff --git a/arch/arm/mach-s3c2443/dma.c b/arch/arm/mach-s3c2443/dma.c
deleted file mode 100644 (file)
index 1422451..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-/* linux/arch/arm/mach-s3c2443/dma.c
- *
- * Copyright (c) 2007 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2443 DMA selection
- *
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/serial_core.h>
-#include <linux/io.h>
-
-#include <mach/dma.h>
-
-#include <plat/dma-s3c24xx.h>
-#include <plat/cpu.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <plat/regs-ac97.h>
-#include <plat/regs-dma.h>
-#include <mach/regs-mem.h>
-#include <mach/regs-lcd.h>
-#include <mach/regs-sdi.h>
-#include <plat/regs-iis.h>
-#include <plat/regs-spi.h>
-
-#define MAP(x) { \
-               [0]     = (x) | DMA_CH_VALID,   \
-               [1]     = (x) | DMA_CH_VALID,   \
-               [2]     = (x) | DMA_CH_VALID,   \
-               [3]     = (x) | DMA_CH_VALID,   \
-               [4]     = (x) | DMA_CH_VALID,   \
-               [5]     = (x) | DMA_CH_VALID,   \
-       }
-
-static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = {
-       [DMACH_XD0] = {
-               .name           = "xdreq0",
-               .channels       = MAP(S3C2443_DMAREQSEL_XDREQ0),
-       },
-       [DMACH_XD1] = {
-               .name           = "xdreq1",
-               .channels       = MAP(S3C2443_DMAREQSEL_XDREQ1),
-       },
-       [DMACH_SDI] = {
-               .name           = "sdi",
-               .channels       = MAP(S3C2443_DMAREQSEL_SDI),
-       },
-       [DMACH_SPI0] = {
-               .name           = "spi0",
-               .channels       = MAP(S3C2443_DMAREQSEL_SPI0TX),
-       },
-       [DMACH_SPI1] = {
-               .name           = "spi1",
-               .channels       = MAP(S3C2443_DMAREQSEL_SPI1TX),
-       },
-       [DMACH_UART0] = {
-               .name           = "uart0",
-               .channels       = MAP(S3C2443_DMAREQSEL_UART0_0),
-       },
-       [DMACH_UART1] = {
-               .name           = "uart1",
-               .channels       = MAP(S3C2443_DMAREQSEL_UART1_0),
-       },
-       [DMACH_UART2] = {
-               .name           = "uart2",
-               .channels       = MAP(S3C2443_DMAREQSEL_UART2_0),
-       },
-       [DMACH_UART3] = {
-               .name           = "uart3",
-               .channels       = MAP(S3C2443_DMAREQSEL_UART3_0),
-       },
-       [DMACH_UART0_SRC2] = {
-               .name           = "uart0",
-               .channels       = MAP(S3C2443_DMAREQSEL_UART0_1),
-       },
-       [DMACH_UART1_SRC2] = {
-               .name           = "uart1",
-               .channels       = MAP(S3C2443_DMAREQSEL_UART1_1),
-       },
-       [DMACH_UART2_SRC2] = {
-               .name           = "uart2",
-               .channels       = MAP(S3C2443_DMAREQSEL_UART2_1),
-       },
-       [DMACH_UART3_SRC2] = {
-               .name           = "uart3",
-               .channels       = MAP(S3C2443_DMAREQSEL_UART3_1),
-       },
-       [DMACH_TIMER] = {
-               .name           = "timer",
-               .channels       = MAP(S3C2443_DMAREQSEL_TIMER),
-       },
-       [DMACH_I2S_IN] = {
-               .name           = "i2s-sdi",
-               .channels       = MAP(S3C2443_DMAREQSEL_I2SRX),
-       },
-       [DMACH_I2S_OUT] = {
-               .name           = "i2s-sdo",
-               .channels       = MAP(S3C2443_DMAREQSEL_I2STX),
-       },
-       [DMACH_PCM_IN] = {
-               .name           = "pcm-in",
-               .channels       = MAP(S3C2443_DMAREQSEL_PCMIN),
-       },
-       [DMACH_PCM_OUT] = {
-               .name           = "pcm-out",
-               .channels       = MAP(S3C2443_DMAREQSEL_PCMOUT),
-       },
-       [DMACH_MIC_IN] = {
-               .name           = "mic-in",
-               .channels       = MAP(S3C2443_DMAREQSEL_MICIN),
-       },
-};
-
-static void s3c2443_dma_select(struct s3c2410_dma_chan *chan,
-                              struct s3c24xx_dma_map *map)
-{
-       writel(map->channels[0] | S3C2443_DMAREQSEL_HW,
-              chan->regs + S3C2443_DMA_DMAREQSEL);
-}
-
-static struct s3c24xx_dma_selection __initdata s3c2443_dma_sel = {
-       .select         = s3c2443_dma_select,
-       .dcon_mask      = 0,
-       .map            = s3c2443_dma_mappings,
-       .map_size       = ARRAY_SIZE(s3c2443_dma_mappings),
-};
-
-static int __init s3c2443_dma_add(struct device *dev,
-                                 struct subsys_interface *sif)
-{
-       s3c24xx_dma_init(6, IRQ_S3C2443_DMA0, 0x100);
-       return s3c24xx_dma_init_map(&s3c2443_dma_sel);
-}
-
-static struct subsys_interface s3c2443_dma_interface = {
-       .name           = "s3c2443_dma",
-       .subsys         = &s3c2443_subsys,
-       .add_dev        = s3c2443_dma_add,
-};
-
-static int __init s3c2443_dma_init(void)
-{
-       return subsys_interface_register(&s3c2443_dma_interface);
-}
-
-arch_initcall(s3c2443_dma_init);
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
deleted file mode 100644 (file)
index ac2829f..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-/* linux/arch/arm/mach-s3c2443/irq.c
- *
- * Copyright (c) 2007 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <asm/mach/irq.h>
-
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/irq.h>
-
-#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
-
-static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len)
-{
-       unsigned int subsrc, submsk;
-       unsigned int end;
-
-       /* read the current pending interrupts, and the mask
-        * for what it is available */
-
-       subsrc = __raw_readl(S3C2410_SUBSRCPND);
-       submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-       subsrc  &= ~submsk;
-       subsrc >>= (irq - S3C2410_IRQSUB(0));
-       subsrc  &= (1 << len)-1;
-
-       end = len + irq;
-
-       for (; irq < end && subsrc; irq++) {
-               if (subsrc & 1)
-                       generic_handle_irq(irq);
-
-               subsrc >>= 1;
-       }
-}
-
-/* WDT/AC97 sub interrupts */
-
-static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
-{
-       s3c2443_irq_demux(IRQ_S3C2443_WDT, 4);
-}
-
-#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
-#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
-
-static void s3c2443_irq_wdtac97_mask(struct irq_data *data)
-{
-       s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static void s3c2443_irq_wdtac97_unmask(struct irq_data *data)
-{
-       s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
-}
-
-static void s3c2443_irq_wdtac97_ack(struct irq_data *data)
-{
-       s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
-}
-
-static struct irq_chip s3c2443_irq_wdtac97 = {
-       .irq_mask       = s3c2443_irq_wdtac97_mask,
-       .irq_unmask     = s3c2443_irq_wdtac97_unmask,
-       .irq_ack        = s3c2443_irq_wdtac97_ack,
-};
-
-/* LCD sub interrupts */
-
-static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
-{
-       s3c2443_irq_demux(IRQ_S3C2443_LCD1, 4);
-}
-
-#define INTMSK_LCD     (1UL << (IRQ_LCD - IRQ_EINT0))
-#define SUBMSK_LCD     INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
-
-static void s3c2443_irq_lcd_mask(struct irq_data *data)
-{
-       s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static void s3c2443_irq_lcd_unmask(struct irq_data *data)
-{
-       s3c_irqsub_unmask(data->irq, INTMSK_LCD);
-}
-
-static void s3c2443_irq_lcd_ack(struct irq_data *data)
-{
-       s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
-}
-
-static struct irq_chip s3c2443_irq_lcd = {
-       .irq_mask       = s3c2443_irq_lcd_mask,
-       .irq_unmask     = s3c2443_irq_lcd_unmask,
-       .irq_ack        = s3c2443_irq_lcd_ack,
-};
-
-/* DMA sub interrupts */
-
-static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
-{
-       s3c2443_irq_demux(IRQ_S3C2443_DMA0, 6);
-}
-
-#define INTMSK_DMA     (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
-#define SUBMSK_DMA     INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
-
-static void s3c2443_irq_dma_mask(struct irq_data *data)
-{
-       s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static void s3c2443_irq_dma_unmask(struct irq_data *data)
-{
-       s3c_irqsub_unmask(data->irq, INTMSK_DMA);
-}
-
-static void s3c2443_irq_dma_ack(struct irq_data *data)
-{
-       s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
-}
-
-static struct irq_chip s3c2443_irq_dma = {
-       .irq_mask       = s3c2443_irq_dma_mask,
-       .irq_unmask     = s3c2443_irq_dma_unmask,
-       .irq_ack        = s3c2443_irq_dma_ack,
-};
-
-/* UART3 sub interrupts */
-
-static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
-{
-       s3c2443_irq_demux(IRQ_S3C2443_RX3, 3);
-}
-
-#define INTMSK_UART3   (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
-#define SUBMSK_UART3   (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
-
-static void s3c2443_irq_uart3_mask(struct irq_data *data)
-{
-       s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static void s3c2443_irq_uart3_unmask(struct irq_data *data)
-{
-       s3c_irqsub_unmask(data->irq, INTMSK_UART3);
-}
-
-static void s3c2443_irq_uart3_ack(struct irq_data *data)
-{
-       s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
-}
-
-static struct irq_chip s3c2443_irq_uart3 = {
-       .irq_mask       = s3c2443_irq_uart3_mask,
-       .irq_unmask     = s3c2443_irq_uart3_unmask,
-       .irq_ack        = s3c2443_irq_uart3_ack,
-};
-
-/* CAM sub interrupts */
-
-static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
-{
-       s3c2443_irq_demux(IRQ_S3C2440_CAM_C, 4);
-}
-
-#define INTMSK_CAM     (1UL << (IRQ_CAM - IRQ_EINT0))
-#define SUBMSK_CAM     INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
-
-static void s3c2443_irq_cam_mask(struct irq_data *data)
-{
-       s3c_irqsub_mask(data->irq, INTMSK_CAM, SUBMSK_CAM);
-}
-
-static void s3c2443_irq_cam_unmask(struct irq_data *data)
-{
-       s3c_irqsub_unmask(data->irq, INTMSK_CAM);
-}
-
-static void s3c2443_irq_cam_ack(struct irq_data *data)
-{
-       s3c_irqsub_maskack(data->irq, INTMSK_CAM, SUBMSK_CAM);
-}
-
-static struct irq_chip s3c2443_irq_cam = {
-       .irq_mask       = s3c2443_irq_cam_mask,
-       .irq_unmask     = s3c2443_irq_cam_unmask,
-       .irq_ack        = s3c2443_irq_cam_ack,
-};
-
-/* IRQ initialisation code */
-
-static int __init s3c2443_add_sub(unsigned int base,
-                                  void (*demux)(unsigned int,
-                                                struct irq_desc *),
-                                  struct irq_chip *chip,
-                                  unsigned int start, unsigned int end)
-{
-       unsigned int irqno;
-
-       irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
-       irq_set_chained_handler(base, demux);
-
-       for (irqno = start; irqno <= end; irqno++) {
-               irq_set_chip_and_handler(irqno, chip, handle_level_irq);
-               set_irq_flags(irqno, IRQF_VALID);
-       }
-
-       return 0;
-}
-
-static int __init s3c2443_irq_add(struct device *dev,
-                                 struct subsys_interface *sif)
-{
-       printk("S3C2443: IRQ Support\n");
-
-       s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam,
-                       IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P);
-
-       s3c2443_add_sub(IRQ_LCD, s3c2443_irq_demux_lcd, &s3c2443_irq_lcd,
-                       IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4);
-
-       s3c2443_add_sub(IRQ_S3C2443_DMA, s3c2443_irq_demux_dma,
-                       &s3c2443_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
-
-       s3c2443_add_sub(IRQ_S3C2443_UART3, s3c2443_irq_demux_uart3,
-                       &s3c2443_irq_uart3,
-                       IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
-
-       s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97,
-                       &s3c2443_irq_wdtac97,
-                       IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
-
-       return 0;
-}
-
-static struct subsys_interface s3c2443_irq_interface = {
-       .name           = "s3c2443_irq",
-       .subsys         = &s3c2443_subsys,
-       .add_dev        = s3c2443_irq_add,
-};
-
-static int __init s3c2443_irq_init(void)
-{
-       return subsys_interface_register(&s3c2443_irq_interface);
-}
-
-arch_initcall(s3c2443_irq_init);
-
diff --git a/arch/arm/mach-s3c2443/mach-smdk2443.c b/arch/arm/mach-s3c2443/mach-smdk2443.c
deleted file mode 100644 (file)
index 2092369..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/* linux/arch/arm/mach-s3c2443/mach-smdk2443.c
- *
- * Copyright (c) 2007 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * http://www.fluff.org/ben/smdk2443/
- *
- * Thanks to Samsung for the loan of an SMDK2443
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-lcd.h>
-
-#include <mach/idle.h>
-#include <mach/fb.h>
-#include <plat/iic.h>
-
-#include <plat/s3c2410.h>
-#include <plat/s3c2443.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#include <plat/common-smdk.h>
-
-static struct map_desc smdk2443_iodesc[] __initdata = {
-       /* ISA IO Space map (memory space selected by A24) */
-
-       {
-               .virtual        = (u32)S3C24XX_VA_ISA_WORD,
-               .pfn            = __phys_to_pfn(S3C2410_CS2),
-               .length         = 0x10000,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
-               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
-               .length         = SZ_4M,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
-               .pfn            = __phys_to_pfn(S3C2410_CS2),
-               .length         = 0x10000,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
-               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
-               .length         = SZ_4M,
-               .type           = MT_DEVICE,
-       }
-};
-
-#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
-#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
-#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
-
-static struct s3c2410_uartcfg smdk2443_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport      = 0,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       },
-       [1] = {
-               .hwport      = 1,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       },
-       /* IR port */
-       [2] = {
-               .hwport      = 2,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x43,
-               .ufcon       = 0x51,
-       },
-       [3] = {
-               .hwport      = 3,
-               .flags       = 0,
-               .ucon        = 0x3c5,
-               .ulcon       = 0x03,
-               .ufcon       = 0x51,
-       }
-};
-
-static struct platform_device *smdk2443_devices[] __initdata = {
-       &s3c_device_wdt,
-       &s3c_device_i2c0,
-       &s3c_device_hsmmc1,
-#ifdef CONFIG_SND_SOC_SMDK2443_WM9710
-       &s3c_device_ac97,
-#endif
-};
-
-static void __init smdk2443_map_io(void)
-{
-       s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc));
-       s3c24xx_init_clocks(12000000);
-       s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs));
-}
-
-static void __init smdk2443_machine_init(void)
-{
-       s3c_i2c0_set_platdata(NULL);
-
-#ifdef CONFIG_SND_SOC_SMDK2443_WM9710
-       s3c24xx_ac97_setup_gpio(S3C24XX_AC97_GPE0);
-#endif
-
-       platform_add_devices(smdk2443_devices, ARRAY_SIZE(smdk2443_devices));
-       smdk_machine_init();
-}
-
-MACHINE_START(SMDK2443, "SMDK2443")
-       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
-       .atag_offset    = 0x100,
-
-       .init_irq       = s3c24xx_init_irq,
-       .map_io         = smdk2443_map_io,
-       .init_machine   = smdk2443_machine_init,
-       .timer          = &s3c24xx_timer,
-       .restart        = s3c2443_restart,
-MACHINE_END
diff --git a/arch/arm/mach-s3c2443/s3c2443.c b/arch/arm/mach-s3c2443/s3c2443.c
deleted file mode 100644 (file)
index b9deaeb..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/* linux/arch/arm/mach-s3c2443/s3c2443.c
- *
- * Copyright (c) 2007 Simtec Electronics
- *   Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C2443 Mobile CPU support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/device.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <mach/regs-s3c2443-clock.h>
-
-#include <plat/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-#include <plat/s3c2443.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/fb-core.h>
-#include <plat/nand-core.h>
-#include <plat/adc-core.h>
-
-static struct map_desc s3c2443_iodesc[] __initdata = {
-       IODESC_ENT(WATCHDOG),
-       IODESC_ENT(CLKPWR),
-       IODESC_ENT(TIMER),
-};
-
-struct bus_type s3c2443_subsys = {
-       .name = "s3c2443-core",
-       .dev_name = "s3c2443-core",
-};
-
-static struct device s3c2443_dev = {
-       .bus            = &s3c2443_subsys,
-};
-
-void s3c2443_restart(char mode, const char *cmd)
-{
-       if (mode == 's')
-               soft_restart(0);
-
-       __raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST);
-}
-
-int __init s3c2443_init(void)
-{
-       printk("S3C2443: Initialising architecture\n");
-
-       s3c_nand_setname("s3c2412-nand");
-       s3c_fb_setname("s3c2443-fb");
-
-       s3c_adc_setname("s3c2443-adc");
-
-       /* change WDT IRQ number */
-       s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT;
-       s3c_device_wdt.resource[1].end   = IRQ_S3C2443_WDT;
-
-       return device_register(&s3c2443_dev);
-}
-
-void __init s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
-       s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
-}
-
-/* s3c2443_map_io
- *
- * register the standard cpu IO areas, and any passed in from the
- * machine specific initialisation.
- */
-
-void __init s3c2443_map_io(void)
-{
-       s3c24xx_gpiocfg_default.set_pull = s3c2443_gpio_setpull;
-       s3c24xx_gpiocfg_default.get_pull = s3c2443_gpio_getpull;
-
-       iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc));
-}
-
-/* need to register the subsystem before we actually register the device, and
- * we also need to ensure that it has been initialised before any of the
- * drivers even try to use it (even if not on an s3c2443 based system)
- * as a driver which may support both 2443 and 2440 may try and use it.
-*/
-
-static int __init s3c2443_core_init(void)
-{
-       return subsys_system_register(&s3c2443_subsys, NULL);
-}
-
-core_initcall(s3c2443_core_init);
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
new file mode 100644 (file)
index 0000000..0f3a327
--- /dev/null
@@ -0,0 +1,538 @@
+# arch/arm/mach-s3c24xx/Kconfig
+#
+# Copyright (c) 2012 Samsung Electronics Co., Ltd.
+#              http://www.samsung.com/
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+if ARCH_S3C24XX
+
+menu "SAMSUNG S3C24XX SoCs Support"
+
+comment "S3C24XX SoCs"
+
+config CPU_S3C2410
+       bool "SAMSUNG S3C2410"
+       default y
+       select CPU_ARM920T
+       select S3C2410_CLOCK
+       select CPU_LLSERIAL_S3C2410
+       select S3C2410_PM if PM
+       select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX
+       help
+         Support for S3C2410 and S3C2410A family from the S3C24XX line
+         of Samsung Mobile CPUs.
+
+config CPU_S3C2412
+       bool "SAMSUNG S3C2412"
+       depends on ARCH_S3C24XX
+       select CPU_ARM926T
+       select CPU_LLSERIAL_S3C2440
+       select S3C2412_PM if PM
+       select S3C2412_DMA if S3C24XX_DMA
+       help
+         Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
+
+config CPU_S3C2416
+       bool "SAMSUNG S3C2416/S3C2450"
+       depends on ARCH_S3C24XX
+       select CPU_ARM926T
+       select CPU_LLSERIAL_S3C2440
+       select SAMSUNG_CLKSRC
+       select S3C2443_COMMON
+       select S3C2443_DMA if S3C24XX_DMA
+       select S3C2416_PM if PM
+       help
+         Support for the S3C2416 SoC from the S3C24XX line
+
+config CPU_S3C2440
+       bool "SAMSUNG S3C2440"
+       select CPU_ARM920T
+       select CPU_LLSERIAL_S3C2440
+       select S3C2410_CLOCK
+       select S3C2410_PM if PM
+       select S3C2440_DMA if S3C24XX_DMA
+       help
+         Support for S3C2440 Samsung Mobile CPU based systems.
+
+config CPU_S3C2442
+       bool "SAMSUNG S3C2442"
+       select CPU_ARM920T
+       select CPU_LLSERIAL_S3C2440
+       select S3C2410_CLOCK
+       select S3C2410_PM if PM
+       help
+         Support for S3C2442 Samsung Mobile CPU based systems.
+
+config CPU_S3C244X
+       def_bool y
+       depends on CPU_S3C2440 || CPU_S3C2442
+
+config CPU_S3C2443
+       bool "SAMSUNG S3C2443"
+       depends on ARCH_S3C24XX
+       select CPU_ARM920T
+       select CPU_LLSERIAL_S3C2440
+       select SAMSUNG_CLKSRC
+       select S3C2443_COMMON
+       select S3C2443_DMA if S3C24XX_DMA
+       help
+         Support for the S3C2443 SoC from the S3C24XX line
+
+# common code
+
+config S3C24XX_SMDK
+       bool
+       help
+         Common machine code for SMDK2410 and SMDK2440
+
+config S3C24XX_SIMTEC_AUDIO
+       bool
+       depends on (ARCH_BAST || MACH_VR1000 || MACH_OSIRIS || MACH_ANUBIS)
+       default y
+       help
+         Add audio devices for common Simtec S3C24XX boards
+
+config S3C24XX_SIMTEC_PM
+       bool
+       help
+         Common power management code for systems that are
+         compatible with the Simtec style of power management
+
+config S3C24XX_SIMTEC_USB
+       bool
+       help
+         USB management code for common Simtec S3C24XX boards
+
+config S3C24XX_SETUP_TS
+       bool
+       help
+         Compile in platform device definition for Samsung TouchScreen.
+
+# cpu-specific sections
+
+if CPU_S3C2410
+
+config S3C2410_DMA
+       bool
+       depends on S3C24XX_DMA && (CPU_S3C2410 || CPU_S3C2442)
+       default y if CPU_S3C2410 || CPU_S3C2442
+       help
+         DMA device selection for S3C2410 and compatible CPUs
+
+config S3C2410_PM
+       bool
+       help
+         Power Management code common to S3C2410 and better
+
+config S3C24XX_SIMTEC_NOR
+       bool
+       help
+         Internal node to specify machine has simtec NOR mapping
+
+config MACH_BAST_IDE
+       bool
+       select HAVE_PATA_PLATFORM
+       help
+         Internal node for machines with an BAST style IDE
+         interface
+
+comment "S3C2410 Boards"
+
+#
+# The "S3C2410 Boards" list is ordered alphabetically by option text.
+# (without ARCH_ or MACH_)
+#
+
+config MACH_AML_M5900
+       bool "AML M5900 Series"
+       select S3C24XX_SIMTEC_PM if PM
+       select S3C_DEV_USB_HOST
+       help
+         Say Y here if you are using the American Microsystems M5900 Series
+         <http://www.amltd.com>
+
+config ARCH_BAST
+       bool "Simtec Electronics BAST (EB2410ITX)"
+       select S3C2410_IOTIMING if S3C2410_CPUFREQ
+       select S3C24XX_SIMTEC_PM if PM
+       select S3C24XX_SIMTEC_NOR
+       select S3C24XX_SIMTEC_USB
+       select MACH_BAST_IDE
+       select S3C24XX_DCLK
+       select ISA
+       select S3C_DEV_HWMON
+       select S3C_DEV_USB_HOST
+       select S3C_DEV_NAND
+       help
+         Say Y here if you are using the Simtec Electronics EB2410ITX
+         development board (also known as BAST)
+
+config BAST_PC104_IRQ
+       bool "BAST PC104 IRQ support"
+       depends on ARCH_BAST
+       default y
+       help
+         Say Y here to enable the PC104 IRQ routing on the
+         Simtec BAST (EB2410ITX)
+
+config ARCH_H1940
+       bool "IPAQ H1940"
+       select PM_H1940 if PM
+       select S3C_DEV_USB_HOST
+       select S3C_DEV_NAND
+       select S3C24XX_SETUP_TS
+       help
+         Say Y here if you are using the HP IPAQ H1940
+
+config H1940BT
+       tristate "Control the state of H1940 bluetooth chip"
+       depends on ARCH_H1940
+       select RFKILL
+       help
+         This is a simple driver that is able to control
+         the state of built in bluetooth chip on h1940.
+
+config PM_H1940
+       bool
+       help
+         Internal node for H1940 and related PM
+
+config MACH_N30
+       bool "Acer N30 family"
+       select MACH_N35
+       select S3C_DEV_USB_HOST
+       select S3C_DEV_NAND
+       help
+         Say Y here if you want suppt for the Acer N30, Acer N35,
+         Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs.
+
+config MACH_OTOM
+       bool "NexVision OTOM Board"
+       select S3C_DEV_USB_HOST
+       select S3C_DEV_NAND
+       help
+         Say Y here if you are using the Nex Vision OTOM board
+
+config MACH_QT2410
+       bool "QT2410"
+       select S3C_DEV_USB_HOST
+       select S3C_DEV_NAND
+       help
+         Say Y here if you are using the Armzone QT2410
+
+config ARCH_SMDK2410
+       bool "SMDK2410/A9M2410"
+       select S3C24XX_SMDK
+       help
+         Say Y here if you are using the SMDK2410 or the derived module A9M2410
+         <http://www.fsforth.de>
+
+config MACH_TCT_HAMMER
+       bool "TCT Hammer Board"
+       select S3C_DEV_USB_HOST
+       help
+         Say Y here if you are using the TinCanTools Hammer Board
+         <http://www.tincantools.com>
+
+config MACH_VR1000
+       bool "Thorcom VR1000"
+       select S3C24XX_SIMTEC_PM if PM
+       select S3C24XX_DCLK
+       select S3C24XX_SIMTEC_NOR
+       select MACH_BAST_IDE
+       select S3C_DEV_USB_HOST
+       select S3C24XX_SIMTEC_USB
+       help
+         Say Y here if you are using the Thorcom VR1000 board.
+
+endif  # CPU_S3C2410
+
+config S3C2412_PM_SLEEP
+       bool
+       help
+         Internal config node to apply sleep for S3C2412 power management.
+         Can be selected by another SoCs such as S3C2416 with similar
+         sleep procedure.
+
+if CPU_S3C2412
+
+config CPU_S3C2412_ONLY
+       bool
+       depends on ARCH_S3C24XX && !CPU_S3C2410 && \
+                  !CPU_S3C2416 && !CPU_S3C2440 && !CPU_S3C2442 && \
+                  !CPU_S3C2443 && CPU_S3C2412
+       default y
+
+config S3C2412_DMA
+       bool
+       help
+         Internal config node for S3C2412 DMA support
+
+config S3C2412_PM
+       bool
+       help
+         Internal config node to apply S3C2412 power management
+
+comment "S3C2412 Boards"
+
+#
+# The "S3C2412 Boards" list is ordered alphabetically by option text.
+# (without ARCH_ or MACH_)
+#
+
+config MACH_JIVE
+       bool "Logitech Jive"
+       select S3C_DEV_USB_HOST
+       select S3C_DEV_NAND
+       help
+         Say Y here if you are using the Logitech Jive.
+
+config MACH_JIVE_SHOW_BOOTLOADER
+       bool "Allow access to bootloader partitions in MTD (EXPERIMENTAL)"
+       depends on MACH_JIVE && EXPERIMENTAL
+
+config MACH_S3C2413
+       bool
+       help
+         Internal node for S3C2413 version of SMDK2413, so that
+         machine_is_s3c2413() will work when MACH_SMDK2413 is
+         selected
+
+config MACH_SMDK2412
+       bool "SMDK2412"
+       select MACH_SMDK2413
+       help
+         Say Y here if you are using an SMDK2412
+
+         Note, this shares support with SMDK2413, so will automatically
+         select MACH_SMDK2413.
+
+config MACH_SMDK2413
+       bool "SMDK2413"
+       select MACH_S3C2413
+       select S3C24XX_SMDK
+       select S3C_DEV_USB_HOST
+       select S3C_DEV_NAND
+       help
+         Say Y here if you are using an SMDK2413
+
+config MACH_VSTMS
+       bool "VMSTMS"
+       select S3C_DEV_USB_HOST
+       select S3C_DEV_NAND
+       help
+         Say Y here if you are using an VSTMS board
+
+endif  # CPU_S3C2412
+
+if CPU_S3C2416
+
+config S3C2416_PM
+       bool
+       select S3C2412_PM_SLEEP
+       help
+         Internal config node to apply S3C2416 power management
+
+config S3C2416_SETUP_SDHCI
+       bool
+       select S3C2416_SETUP_SDHCI_GPIO
+       help
+         Internal helper functions for S3C2416 based SDHCI systems
+
+config S3C2416_SETUP_SDHCI_GPIO
+       bool
+       help
+         Common setup code for SDHCI gpio.
+
+comment "S3C2416 Boards"
+
+config MACH_SMDK2416
+       bool "SMDK2416"
+       select S3C24XX_SMDK
+       select S3C_DEV_FB
+       select S3C_DEV_HSMMC
+       select S3C_DEV_HSMMC1
+       select S3C_DEV_NAND
+       select S3C_DEV_USB_HOST
+       select S3C2416_SETUP_SDHCI
+       help
+         Say Y here if you are using an SMDK2416
+
+endif  # CPU_S3C2416
+
+if CPU_S3C2440
+
+config S3C2440_DMA
+       bool
+       help
+         Support for S3C2440 specific DMA code5A
+
+comment "S3C2440 Boards"
+
+#
+# The "S3C2440 Boards" list is ordered alphabetically by option text.
+# (without ARCH_ or MACH_)
+#
+
+config MACH_ANUBIS
+       bool "Simtec Electronics ANUBIS"
+       select S3C24XX_DCLK
+       select S3C24XX_SIMTEC_PM if PM
+       select HAVE_PATA_PLATFORM
+       select S3C24XX_GPIO_EXTRA64
+       select S3C2440_XTAL_12000000
+       select S3C_DEV_USB_HOST
+       help
+         Say Y here if you are using the Simtec Electronics ANUBIS
+         development system
+
+config MACH_AT2440EVB
+       bool "Avantech AT2440EVB development board"
+       select S3C_DEV_USB_HOST
+       select S3C_DEV_NAND
+       help
+         Say Y here if you are using the AT2440EVB development board
+
+config MACH_MINI2440
+       bool "MINI2440 development board"
+       select EEPROM_AT24
+       select NEW_LEDS
+       select LEDS_CLASS
+       select LEDS_TRIGGER
+       select LEDS_TRIGGER_BACKLIGHT
+       select S3C_DEV_NAND
+       select S3C_DEV_USB_HOST
+       help
+         Say Y here to select support for the MINI2440. Is a 10cm x 10cm board
+         available via various sources. It can come with a 3.5" or 7" touch LCD.
+
+config MACH_NEXCODER_2440
+       bool "NexVision NEXCODER 2440 Light Board"
+       select S3C2440_XTAL_12000000
+       select S3C_DEV_USB_HOST
+       select S3C_DEV_NAND
+       help
+         Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
+
+config MACH_OSIRIS
+       bool "Simtec IM2440D20 (OSIRIS) module"
+       select S3C24XX_DCLK
+       select S3C24XX_SIMTEC_PM if PM
+       select S3C24XX_GPIO_EXTRA128
+       select S3C2440_XTAL_12000000
+       select S3C2410_IOTIMING if S3C2440_CPUFREQ
+       select S3C_DEV_USB_HOST
+       select S3C_DEV_NAND
+       help
+         Say Y here if you are using the Simtec IM2440D20 module, also
+         known as the Osiris.
+
+config MACH_OSIRIS_DVS
+       tristate "Simtec IM2440D20 (OSIRIS) Dynamic Voltage Scaling driver"
+       depends on MACH_OSIRIS
+       select TPS65010
+       help
+         Say Y/M here if you want to have dynamic voltage scaling support
+         on the Simtec IM2440D20 (OSIRIS) module via the TPS65011.
+
+         The DVS driver alters the voltage supplied to the ARM core
+         depending on the frequency it is running at. The driver itself
+         does not do any of the frequency alteration, which is left up
+         to the cpufreq driver.
+
+config MACH_RX3715
+       bool "HP iPAQ rx3715"
+       select S3C2440_XTAL_16934400
+       select PM_H1940 if PM
+       select S3C_DEV_NAND
+       help
+         Say Y here if you are using the HP iPAQ rx3715.
+
+config ARCH_S3C2440
+       bool "SMDK2440"
+       select S3C2440_XTAL_16934400
+       select S3C24XX_SMDK
+       select S3C_DEV_USB_HOST
+       select S3C_DEV_NAND
+       help
+         Say Y here if you are using the SMDK2440.
+
+config SMDK2440_CPU2440
+       bool "SMDK2440 with S3C2440 CPU module"
+       default y if ARCH_S3C2440
+       select S3C2440_XTAL_16934400
+
+endif  # CPU_S3C2440
+
+if CPU_S3C2442
+
+comment "S3C2442 Boards"
+
+#
+# The "S3C2442 Boards" list is ordered alphabetically by option text.
+# (without ARCH_ or MACH_)
+#
+
+config MACH_NEO1973_GTA02
+       bool "Openmoko GTA02 / Freerunner phone"
+       select MFD_PCF50633
+       select PCF50633_GPIO
+       select I2C
+       select POWER_SUPPLY
+       select MACH_NEO1973
+       select S3C2410_PWM
+       select S3C_DEV_USB_HOST
+       help
+          Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone
+
+config MACH_RX1950
+       bool "HP iPAQ rx1950"
+       select S3C24XX_DCLK
+       select PM_H1940 if PM
+       select I2C
+       select S3C2410_PWM
+       select S3C_DEV_NAND
+       select S3C2410_IOTIMING if S3C2440_CPUFREQ
+       select S3C2440_XTAL_16934400
+       help
+          Say Y here if you're using HP iPAQ rx1950
+
+config SMDK2440_CPU2442
+       bool "SMDM2440 with S3C2442 CPU module"
+
+endif  # CPU_S3C2440
+
+if CPU_S3C2443 || CPU_S3C2416
+
+config S3C2443_COMMON
+       bool
+       help
+         Common code for the S3C2443 and similar processors, which includes
+         the S3C2416 and S3C2450.
+
+config S3C2443_DMA
+       bool
+       help
+         Internal config node for S3C2443 DMA support
+
+endif  # CPU_S3C2443 || CPU_S3C2416
+
+if CPU_S3C2443
+
+comment "S3C2443 Boards"
+
+config MACH_SMDK2443
+       bool "SMDK2443"
+       select S3C24XX_SMDK
+       select S3C_DEV_HSMMC1
+       help
+         Say Y here if you are using an SMDK2443
+
+endif  # CPU_S3C2443
+
+endmenu        # SAMSUNG S3C24XX SoCs Support
+
+endif  # ARCH_S3C24XX
diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
new file mode 100644 (file)
index 0000000..3518fe8
--- /dev/null
@@ -0,0 +1,95 @@
+# arch/arm/mach-s3c24xx/Makefile
+#
+# Copyright (c) 2012 Samsung Electronics Co., Ltd.
+#              http://www.samsung.com/
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y                          :=
+obj-m                          :=
+obj-n                          :=
+obj-                           :=
+
+# core
+
+obj-$(CONFIG_CPU_S3C2410)      += s3c2410.o
+obj-$(CONFIG_S3C2410_DMA)      += dma-s3c2410.o
+obj-$(CONFIG_S3C2410_PM)       += pm-s3c2410.o sleep-s3c2410.o
+
+obj-$(CONFIG_CPU_S3C2412)      += s3c2412.o irq-s3c2412.o clock-s3c2412.o
+obj-$(CONFIG_S3C2412_DMA)      += dma-s3c2412.o
+obj-$(CONFIG_S3C2412_PM)       += pm-s3c2412.o
+obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep-s3c2412.o
+
+obj-$(CONFIG_CPU_S3C2416)      += s3c2416.o irq-s3c2416.o clock-s3c2416.o
+obj-$(CONFIG_S3C2416_PM)       += pm-s3c2416.o
+
+obj-$(CONFIG_CPU_S3C2440)      += s3c2440.o irq-s3c2440.o clock-s3c2440.o
+obj-$(CONFIG_CPU_S3C2442)      += s3c2442.o
+obj-$(CONFIG_CPU_S3C244X)      += s3c244x.o irq-s3c244x.o clock-s3c244x.o
+obj-$(CONFIG_S3C2440_DMA)      += dma-s3c2440.o
+
+obj-$(CONFIG_CPU_S3C2443)      += s3c2443.o irq-s3c2443.o clock-s3c2443.o
+
+# common code
+
+obj-$(CONFIG_S3C2443_COMMON)   += common-s3c2443.o
+obj-$(CONFIG_S3C2443_DMA)      += dma-s3c2443.o
+
+#
+# machine support
+# following is ordered alphabetically by option text.
+#
+
+obj-$(CONFIG_MACH_AML_M5900)           += mach-amlm5900.o
+obj-$(CONFIG_ARCH_BAST)                        += mach-bast.o
+obj-$(CONFIG_BAST_PC104_IRQ)           += bast-irq.o
+obj-$(CONFIG_ARCH_H1940)               += mach-h1940.o
+obj-$(CONFIG_H1940BT)                  += h1940-bluetooth.o
+obj-$(CONFIG_PM_H1940)                 += pm-h1940.o
+obj-$(CONFIG_MACH_N30)                 += mach-n30.o
+obj-$(CONFIG_MACH_OTOM)                        += mach-otom.o
+obj-$(CONFIG_MACH_QT2410)              += mach-qt2410.o
+obj-$(CONFIG_ARCH_SMDK2410)            += mach-smdk2410.o
+obj-$(CONFIG_MACH_TCT_HAMMER)          += mach-tct_hammer.o
+obj-$(CONFIG_MACH_VR1000)              += mach-vr1000.o
+
+obj-$(CONFIG_MACH_JIVE)                        += mach-jive.o
+obj-$(CONFIG_MACH_SMDK2413)            += mach-smdk2413.o
+obj-$(CONFIG_MACH_VSTMS)               += mach-vstms.o
+
+obj-$(CONFIG_MACH_SMDK2416)            += mach-smdk2416.o
+
+obj-$(CONFIG_MACH_ANUBIS)              += mach-anubis.o
+obj-$(CONFIG_MACH_AT2440EVB)           += mach-at2440evb.o
+obj-$(CONFIG_MACH_MINI2440)            += mach-mini2440.o
+obj-$(CONFIG_MACH_NEXCODER_2440)       += mach-nexcoder.o
+obj-$(CONFIG_MACH_OSIRIS)              += mach-osiris.o
+obj-$(CONFIG_MACH_RX3715)              += mach-rx3715.o
+obj-$(CONFIG_ARCH_S3C2440)             += mach-smdk2440.o
+
+obj-$(CONFIG_MACH_NEO1973_GTA02)       += mach-gta02.o
+obj-$(CONFIG_MACH_RX1950)              += mach-rx1950.o
+
+obj-$(CONFIG_MACH_SMDK2443)            += mach-smdk2443.o
+
+# common bits of machine support
+
+obj-$(CONFIG_S3C24XX_SMDK)             += common-smdk.o
+obj-$(CONFIG_S3C24XX_SIMTEC_AUDIO)     += simtec-audio.o
+obj-$(CONFIG_S3C24XX_SIMTEC_NOR)       += simtec-nor.o
+obj-$(CONFIG_S3C24XX_SIMTEC_PM)                += simtec-pm.o
+obj-$(CONFIG_S3C24XX_SIMTEC_USB)       += simtec-usb.o
+
+# machine additions
+
+obj-$(CONFIG_MACH_BAST_IDE)            += bast-ide.o
+obj-$(CONFIG_MACH_OSIRIS_DVS)          += mach-osiris-dvs.o
+
+# device setup
+
+obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
+obj-$(CONFIG_ARCH_S3C24XX)             += setup-i2c.o
+obj-$(CONFIG_S3C24XX_SETUP_TS)         += setup-ts.o
diff --git a/arch/arm/mach-s3c24xx/Makefile.boot b/arch/arm/mach-s3c24xx/Makefile.boot
new file mode 100644 (file)
index 0000000..4457605
--- /dev/null
@@ -0,0 +1,7 @@
+ifeq ($(CONFIG_PM_H1940),y)
+       zreladdr-y      += 0x30108000
+       params_phys-y   := 0x30100100
+else
+       zreladdr-y      += 0x30008000
+       params_phys-y   := 0x30000100
+endif
diff --git a/arch/arm/mach-s3c24xx/bast-ide.c b/arch/arm/mach-s3c24xx/bast-ide.c
new file mode 100644 (file)
index 0000000..298ecec
--- /dev/null
@@ -0,0 +1,112 @@
+/* linux/arch/arm/mach-s3c2410/bast-ide.c
+ *
+ * Copyright 2007 Simtec Electronics
+ *     http://www.simtec.co.uk/products/EB2410ITX/
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/map.h>
+#include <mach/bast-map.h>
+#include <mach/bast-irq.h>
+
+/* IDE ports */
+
+static struct pata_platform_info bast_ide_platdata = {
+       .ioport_shift   = 5,
+};
+
+#define IDE_CS S3C2410_CS5
+
+static struct resource bast_ide0_resource[] = {
+       [0]     = {
+               .start  = IDE_CS + BAST_PA_IDEPRI,
+               .end    = IDE_CS + BAST_PA_IDEPRI + (8 * 0x20) - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1]     = {
+               .start  = IDE_CS + BAST_PA_IDEPRIAUX + (6 * 0x20) ,
+               .end    = IDE_CS + BAST_PA_IDEPRIAUX + (7 * 0x20) - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [2]     = {
+               .start  = IRQ_IDE0,
+               .end    = IRQ_IDE0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bast_device_ide0 = {
+       .name           = "pata_platform",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(bast_ide0_resource),
+       .resource       = bast_ide0_resource,
+       .dev            = {
+               .platform_data = &bast_ide_platdata,
+               .coherent_dma_mask = ~0,
+       }
+
+};
+
+static struct resource bast_ide1_resource[] = {
+       [0]     = {
+               .start  = IDE_CS + BAST_PA_IDESEC,
+               .end    = IDE_CS + BAST_PA_IDESEC + (8 * 0x20) - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1]     = {
+               .start  = IDE_CS + BAST_PA_IDESECAUX + (6 * 0x20),
+               .end    = IDE_CS + BAST_PA_IDESECAUX + (7 * 0x20) - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [2]     = {
+               .start  = IRQ_IDE1,
+               .end    = IRQ_IDE1,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bast_device_ide1 = {
+       .name           = "pata_platform",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(bast_ide1_resource),
+       .resource       = bast_ide1_resource,
+       .dev            = {
+               .platform_data = &bast_ide_platdata,
+               .coherent_dma_mask = ~0,
+       }
+};
+
+static struct platform_device *bast_ide_devices[] __initdata = {
+       &bast_device_ide0,
+       &bast_device_ide1,
+};
+
+static __init int bast_ide_init(void)
+{
+       if (machine_is_bast() || machine_is_vr1000())
+               return platform_add_devices(bast_ide_devices,
+                                           ARRAY_SIZE(bast_ide_devices));
+
+       return 0;
+}
+
+fs_initcall(bast_ide_init);
diff --git a/arch/arm/mach-s3c24xx/bast-irq.c b/arch/arm/mach-s3c24xx/bast-irq.c
new file mode 100644 (file)
index 0000000..ac7b2ad
--- /dev/null
@@ -0,0 +1,166 @@
+/* linux/arch/arm/mach-s3c2410/bast-irq.c
+ *
+ * Copyright 2003-2005 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.simtec.co.uk/products/EB2410ITX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/io.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/regs-irq.h>
+#include <mach/bast-map.h>
+#include <mach/bast-irq.h>
+
+#include <plat/irq.h>
+
+#if 0
+#include <asm/debug-ll.h>
+#endif
+
+#define irqdbf(x...)
+#define irqdbf2(x...)
+
+
+/* handle PC104 ISA interrupts from the system CPLD */
+
+/* table of ISA irq nos to the relevant mask... zero means
+ * the irq is not implemented
+*/
+static unsigned char bast_pc104_irqmasks[] = {
+       0,   /* 0 */
+       0,   /* 1 */
+       0,   /* 2 */
+       1,   /* 3 */
+       0,   /* 4 */
+       2,   /* 5 */
+       0,   /* 6 */
+       4,   /* 7 */
+       0,   /* 8 */
+       0,   /* 9 */
+       8,   /* 10 */
+       0,   /* 11 */
+       0,   /* 12 */
+       0,   /* 13 */
+       0,   /* 14 */
+       0,   /* 15 */
+};
+
+static unsigned char bast_pc104_irqs[] = { 3, 5, 7, 10 };
+
+static void
+bast_pc104_mask(struct irq_data *data)
+{
+       unsigned long temp;
+
+       temp = __raw_readb(BAST_VA_PC104_IRQMASK);
+       temp &= ~bast_pc104_irqmasks[data->irq];
+       __raw_writeb(temp, BAST_VA_PC104_IRQMASK);
+}
+
+static void
+bast_pc104_maskack(struct irq_data *data)
+{
+       struct irq_desc *desc = irq_desc + IRQ_ISA;
+
+       bast_pc104_mask(data);
+       desc->irq_data.chip->irq_ack(&desc->irq_data);
+}
+
+static void
+bast_pc104_unmask(struct irq_data *data)
+{
+       unsigned long temp;
+
+       temp = __raw_readb(BAST_VA_PC104_IRQMASK);
+       temp |= bast_pc104_irqmasks[data->irq];
+       __raw_writeb(temp, BAST_VA_PC104_IRQMASK);
+}
+
+static struct irq_chip  bast_pc104_chip = {
+       .irq_mask       = bast_pc104_mask,
+       .irq_unmask     = bast_pc104_unmask,
+       .irq_ack        = bast_pc104_maskack
+};
+
+static void
+bast_irq_pc104_demux(unsigned int irq,
+                    struct irq_desc *desc)
+{
+       unsigned int stat;
+       unsigned int irqno;
+       int i;
+
+       stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf;
+
+       if (unlikely(stat == 0)) {
+               /* ack if we get an irq with nothing (ie, startup) */
+
+               desc = irq_desc + IRQ_ISA;
+               desc->irq_data.chip->irq_ack(&desc->irq_data);
+       } else {
+               /* handle the IRQ */
+
+               for (i = 0; stat != 0; i++, stat >>= 1) {
+                       if (stat & 1) {
+                               irqno = bast_pc104_irqs[i];
+                               generic_handle_irq(irqno);
+                       }
+               }
+       }
+}
+
+static __init int bast_irq_init(void)
+{
+       unsigned int i;
+
+       if (machine_is_bast()) {
+               printk(KERN_INFO "BAST PC104 IRQ routing, Copyright 2005 Simtec Electronics\n");
+
+               /* zap all the IRQs */
+
+               __raw_writeb(0x0, BAST_VA_PC104_IRQMASK);
+
+               irq_set_chained_handler(IRQ_ISA, bast_irq_pc104_demux);
+
+               /* register our IRQs */
+
+               for (i = 0; i < 4; i++) {
+                       unsigned int irqno = bast_pc104_irqs[i];
+
+                       irq_set_chip_and_handler(irqno, &bast_pc104_chip,
+                                                handle_level_irq);
+                       set_irq_flags(irqno, IRQF_VALID);
+               }
+       }
+
+       return 0;
+}
+
+arch_initcall(bast_irq_init);
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2412.c b/arch/arm/mach-s3c24xx/clock-s3c2412.c
new file mode 100644 (file)
index 0000000..d10b695
--- /dev/null
@@ -0,0 +1,763 @@
+/* linux/arch/arm/mach-s3c2412/clock.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2412,S3C2413 Clock control support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/s3c2412.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+/* We currently have to assume that the system is running
+ * from the XTPll input, and that all ***REFCLKs are being
+ * fed from it, as we cannot read the state of OM[4] from
+ * software.
+ *
+ * It would be possible for each board initialisation to
+ * set the correct muxing at initialisation
+*/
+
+static int s3c2412_clkcon_enable(struct clk *clk, int enable)
+{
+       unsigned int clocks = clk->ctrlbit;
+       unsigned long clkcon;
+
+       clkcon = __raw_readl(S3C2410_CLKCON);
+
+       if (enable)
+               clkcon |= clocks;
+       else
+               clkcon &= ~clocks;
+
+       __raw_writel(clkcon, S3C2410_CLKCON);
+
+       return 0;
+}
+
+static int s3c2412_upll_enable(struct clk *clk, int enable)
+{
+       unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
+       unsigned long orig = upllcon;
+
+       if (!enable)
+               upllcon |= S3C2412_PLLCON_OFF;
+       else
+               upllcon &= ~S3C2412_PLLCON_OFF;
+
+       __raw_writel(upllcon, S3C2410_UPLLCON);
+
+       /* allow ~150uS for the PLL to settle and lock */
+
+       if (enable && (orig & S3C2412_PLLCON_OFF))
+               udelay(150);
+
+       return 0;
+}
+
+/* clock selections */
+
+static struct clk clk_erefclk = {
+       .name           = "erefclk",
+};
+
+static struct clk clk_urefclk = {
+       .name           = "urefclk",
+};
+
+static int s3c2412_setparent_usysclk(struct clk *clk, struct clk *parent)
+{
+       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+       if (parent == &clk_urefclk)
+               clksrc &= ~S3C2412_CLKSRC_USYSCLK_UPLL;
+       else if (parent == &clk_upll)
+               clksrc |= S3C2412_CLKSRC_USYSCLK_UPLL;
+       else
+               return -EINVAL;
+
+       clk->parent = parent;
+
+       __raw_writel(clksrc, S3C2412_CLKSRC);
+       return 0;
+}
+
+static struct clk clk_usysclk = {
+       .name           = "usysclk",
+       .parent         = &clk_xtal,
+       .ops            = &(struct clk_ops) {
+               .set_parent     = s3c2412_setparent_usysclk,
+       },
+};
+
+static struct clk clk_mrefclk = {
+       .name           = "mrefclk",
+       .parent         = &clk_xtal,
+};
+
+static struct clk clk_mdivclk = {
+       .name           = "mdivclk",
+       .parent         = &clk_xtal,
+};
+
+static int s3c2412_setparent_usbsrc(struct clk *clk, struct clk *parent)
+{
+       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+       if (parent == &clk_usysclk)
+               clksrc &= ~S3C2412_CLKSRC_USBCLK_HCLK;
+       else if (parent == &clk_h)
+               clksrc |= S3C2412_CLKSRC_USBCLK_HCLK;
+       else
+               return -EINVAL;
+
+       clk->parent = parent;
+
+       __raw_writel(clksrc, S3C2412_CLKSRC);
+       return 0;
+}
+
+static unsigned long s3c2412_roundrate_usbsrc(struct clk *clk,
+                                             unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       int div;
+
+       if (rate > parent_rate)
+               return parent_rate;
+
+       div = parent_rate / rate;
+       if (div > 2)
+               div = 2;
+
+       return parent_rate / div;
+}
+
+static unsigned long s3c2412_getrate_usbsrc(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2410_CLKDIVN);
+
+       return parent_rate / ((div & S3C2412_CLKDIVN_USB48DIV) ? 2 : 1);
+}
+
+static int s3c2412_setrate_usbsrc(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
+
+       rate = s3c2412_roundrate_usbsrc(clk, rate);
+
+       if ((parent_rate / rate) == 2)
+               clkdivn |= S3C2412_CLKDIVN_USB48DIV;
+       else
+               clkdivn &= ~S3C2412_CLKDIVN_USB48DIV;
+
+       __raw_writel(clkdivn, S3C2410_CLKDIVN);
+       return 0;
+}
+
+static struct clk clk_usbsrc = {
+       .name           = "usbsrc",
+       .ops            = &(struct clk_ops) {
+               .get_rate       = s3c2412_getrate_usbsrc,
+               .set_rate       = s3c2412_setrate_usbsrc,
+               .round_rate     = s3c2412_roundrate_usbsrc,
+               .set_parent     = s3c2412_setparent_usbsrc,
+       },
+};
+
+static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent)
+{
+       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+       if (parent == &clk_mdivclk)
+               clksrc &= ~S3C2412_CLKSRC_MSYSCLK_MPLL;
+       else if (parent == &clk_mpll)
+               clksrc |= S3C2412_CLKSRC_MSYSCLK_MPLL;
+       else
+               return -EINVAL;
+
+       clk->parent = parent;
+
+       __raw_writel(clksrc, S3C2412_CLKSRC);
+       return 0;
+}
+
+static struct clk clk_msysclk = {
+       .name           = "msysclk",
+       .ops            = &(struct clk_ops) {
+               .set_parent     = s3c2412_setparent_msysclk,
+       },
+};
+
+static int s3c2412_setparent_armclk(struct clk *clk, struct clk *parent)
+{
+       unsigned long flags;
+       unsigned long clkdiv;
+       unsigned long dvs;
+
+       /* Note, we current equate fclk andf msysclk for S3C2412 */
+
+       if (parent == &clk_msysclk || parent == &clk_f)
+               dvs = 0;
+       else if (parent == &clk_h)
+               dvs = S3C2412_CLKDIVN_DVSEN;
+       else
+               return -EINVAL;
+
+       clk->parent = parent;
+
+       /* update this under irq lockdown, clkdivn is not protected
+        * by the clock system. */
+
+       local_irq_save(flags);
+
+       clkdiv  = __raw_readl(S3C2410_CLKDIVN);
+       clkdiv &= ~S3C2412_CLKDIVN_DVSEN;
+       clkdiv |= dvs;
+       __raw_writel(clkdiv, S3C2410_CLKDIVN);
+
+       local_irq_restore(flags);
+
+       return 0;
+}
+
+static struct clk clk_armclk = {
+       .name           = "armclk",
+       .parent         = &clk_msysclk,
+       .ops            = &(struct clk_ops) {
+               .set_parent     = s3c2412_setparent_armclk,
+       },
+};
+
+/* these next clocks have an divider immediately after them,
+ * so we can register them with their divider and leave out the
+ * intermediate clock stage
+*/
+static unsigned long s3c2412_roundrate_clksrc(struct clk *clk,
+                                             unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       int div;
+
+       if (rate > parent_rate)
+               return parent_rate;
+
+       /* note, we remove the +/- 1 calculations as they cancel out */
+
+       div = (rate / parent_rate);
+
+       if (div < 1)
+               div = 1;
+       else if (div > 16)
+               div = 16;
+
+       return parent_rate / div;
+}
+
+static int s3c2412_setparent_uart(struct clk *clk, struct clk *parent)
+{
+       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+       if (parent == &clk_erefclk)
+               clksrc &= ~S3C2412_CLKSRC_UARTCLK_MPLL;
+       else if (parent == &clk_mpll)
+               clksrc |= S3C2412_CLKSRC_UARTCLK_MPLL;
+       else
+               return -EINVAL;
+
+       clk->parent = parent;
+
+       __raw_writel(clksrc, S3C2412_CLKSRC);
+       return 0;
+}
+
+static unsigned long s3c2412_getrate_uart(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2410_CLKDIVN);
+
+       div &= S3C2412_CLKDIVN_UARTDIV_MASK;
+       div >>= S3C2412_CLKDIVN_UARTDIV_SHIFT;
+
+       return parent_rate / (div + 1);
+}
+
+static int s3c2412_setrate_uart(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
+
+       rate = s3c2412_roundrate_clksrc(clk, rate);
+
+       clkdivn &= ~S3C2412_CLKDIVN_UARTDIV_MASK;
+       clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_UARTDIV_SHIFT;
+
+       __raw_writel(clkdivn, S3C2410_CLKDIVN);
+       return 0;
+}
+
+static struct clk clk_uart = {
+       .name           = "uartclk",
+       .ops            = &(struct clk_ops) {
+               .get_rate       = s3c2412_getrate_uart,
+               .set_rate       = s3c2412_setrate_uart,
+               .set_parent     = s3c2412_setparent_uart,
+               .round_rate     = s3c2412_roundrate_clksrc,
+       },
+};
+
+static int s3c2412_setparent_i2s(struct clk *clk, struct clk *parent)
+{
+       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+       if (parent == &clk_erefclk)
+               clksrc &= ~S3C2412_CLKSRC_I2SCLK_MPLL;
+       else if (parent == &clk_mpll)
+               clksrc |= S3C2412_CLKSRC_I2SCLK_MPLL;
+       else
+               return -EINVAL;
+
+       clk->parent = parent;
+
+       __raw_writel(clksrc, S3C2412_CLKSRC);
+       return 0;
+}
+
+static unsigned long s3c2412_getrate_i2s(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2410_CLKDIVN);
+
+       div &= S3C2412_CLKDIVN_I2SDIV_MASK;
+       div >>= S3C2412_CLKDIVN_I2SDIV_SHIFT;
+
+       return parent_rate / (div + 1);
+}
+
+static int s3c2412_setrate_i2s(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
+
+       rate = s3c2412_roundrate_clksrc(clk, rate);
+
+       clkdivn &= ~S3C2412_CLKDIVN_I2SDIV_MASK;
+       clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_I2SDIV_SHIFT;
+
+       __raw_writel(clkdivn, S3C2410_CLKDIVN);
+       return 0;
+}
+
+static struct clk clk_i2s = {
+       .name           = "i2sclk",
+       .ops            = &(struct clk_ops) {
+               .get_rate       = s3c2412_getrate_i2s,
+               .set_rate       = s3c2412_setrate_i2s,
+               .set_parent     = s3c2412_setparent_i2s,
+               .round_rate     = s3c2412_roundrate_clksrc,
+       },
+};
+
+static int s3c2412_setparent_cam(struct clk *clk, struct clk *parent)
+{
+       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+       if (parent == &clk_usysclk)
+               clksrc &= ~S3C2412_CLKSRC_CAMCLK_HCLK;
+       else if (parent == &clk_h)
+               clksrc |= S3C2412_CLKSRC_CAMCLK_HCLK;
+       else
+               return -EINVAL;
+
+       clk->parent = parent;
+
+       __raw_writel(clksrc, S3C2412_CLKSRC);
+       return 0;
+}
+static unsigned long s3c2412_getrate_cam(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2410_CLKDIVN);
+
+       div &= S3C2412_CLKDIVN_CAMDIV_MASK;
+       div >>= S3C2412_CLKDIVN_CAMDIV_SHIFT;
+
+       return parent_rate / (div + 1);
+}
+
+static int s3c2412_setrate_cam(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
+
+       rate = s3c2412_roundrate_clksrc(clk, rate);
+
+       clkdivn &= ~S3C2412_CLKDIVN_CAMDIV_MASK;
+       clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_CAMDIV_SHIFT;
+
+       __raw_writel(clkdivn, S3C2410_CLKDIVN);
+       return 0;
+}
+
+static struct clk clk_cam = {
+       .name           = "camif-upll", /* same as 2440 name */
+       .ops            = &(struct clk_ops) {
+               .get_rate       = s3c2412_getrate_cam,
+               .set_rate       = s3c2412_setrate_cam,
+               .set_parent     = s3c2412_setparent_cam,
+               .round_rate     = s3c2412_roundrate_clksrc,
+       },
+};
+
+/* standard clock definitions */
+
+static struct clk init_clocks_disable[] = {
+       {
+               .name           = "nand",
+               .parent         = &clk_h,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_NAND,
+       }, {
+               .name           = "sdi",
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_SDI,
+       }, {
+               .name           = "adc",
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_ADC,
+       }, {
+               .name           = "i2c",
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_IIC,
+       }, {
+               .name           = "iis",
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_IIS,
+       }, {
+               .name           = "spi",
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_SPI,
+       }
+};
+
+static struct clk init_clocks[] = {
+       {
+               .name           = "dma",
+               .parent         = &clk_h,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_DMA0,
+       }, {
+               .name           = "dma",
+               .parent         = &clk_h,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_DMA1,
+       }, {
+               .name           = "dma",
+               .parent         = &clk_h,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_DMA2,
+       }, {
+               .name           = "dma",
+               .parent         = &clk_h,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_DMA3,
+       }, {
+               .name           = "lcd",
+               .parent         = &clk_h,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_LCDC,
+       }, {
+               .name           = "gpio",
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_GPIO,
+       }, {
+               .name           = "usb-host",
+               .parent         = &clk_h,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_USBH,
+       }, {
+               .name           = "usb-device",
+               .parent         = &clk_h,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_USBD,
+       }, {
+               .name           = "timers",
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_PWMT,
+       }, {
+               .name           = "uart",
+               .devname        = "s3c2412-uart.0",
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_UART0,
+       }, {
+               .name           = "uart",
+               .devname        = "s3c2412-uart.1",
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_UART1,
+       }, {
+               .name           = "uart",
+               .devname        = "s3c2412-uart.2",
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_UART2,
+       }, {
+               .name           = "rtc",
+               .parent         = &clk_p,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_RTC,
+       }, {
+               .name           = "watchdog",
+               .parent         = &clk_p,
+               .ctrlbit        = 0,
+       }, {
+               .name           = "usb-bus-gadget",
+               .parent         = &clk_usb_bus,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_USB_DEV48,
+       }, {
+               .name           = "usb-bus-host",
+               .parent         = &clk_usb_bus,
+               .enable         = s3c2412_clkcon_enable,
+               .ctrlbit        = S3C2412_CLKCON_USB_HOST48,
+       }
+};
+
+/* clocks to add where we need to check their parentage */
+
+struct clk_init {
+       struct clk      *clk;
+       unsigned int     bit;
+       struct clk      *src_0;
+       struct clk      *src_1;
+};
+
+static struct clk_init clks_src[] __initdata = {
+       {
+               .clk    = &clk_usysclk,
+               .bit    = S3C2412_CLKSRC_USBCLK_HCLK,
+               .src_0  = &clk_urefclk,
+               .src_1  = &clk_upll,
+       }, {
+               .clk    = &clk_i2s,
+               .bit    = S3C2412_CLKSRC_I2SCLK_MPLL,
+               .src_0  = &clk_erefclk,
+               .src_1  = &clk_mpll,
+       }, {
+               .clk    = &clk_cam,
+               .bit    = S3C2412_CLKSRC_CAMCLK_HCLK,
+               .src_0  = &clk_usysclk,
+               .src_1  = &clk_h,
+       }, {
+               .clk    = &clk_msysclk,
+               .bit    = S3C2412_CLKSRC_MSYSCLK_MPLL,
+               .src_0  = &clk_mdivclk,
+               .src_1  = &clk_mpll,
+       }, {
+               .clk    = &clk_uart,
+               .bit    = S3C2412_CLKSRC_UARTCLK_MPLL,
+               .src_0  = &clk_erefclk,
+               .src_1  = &clk_mpll,
+       }, {
+               .clk    = &clk_usbsrc,
+               .bit    = S3C2412_CLKSRC_USBCLK_HCLK,
+               .src_0  = &clk_usysclk,
+               .src_1  = &clk_h,
+       /* here we assume  OM[4] select xtal */
+       }, {
+               .clk    = &clk_erefclk,
+               .bit    = S3C2412_CLKSRC_EREFCLK_EXTCLK,
+               .src_0  = &clk_xtal,
+               .src_1  = &clk_ext,
+       }, {
+               .clk    = &clk_urefclk,
+               .bit    = S3C2412_CLKSRC_UREFCLK_EXTCLK,
+               .src_0  = &clk_xtal,
+               .src_1  = &clk_ext,
+       },
+};
+
+/* s3c2412_clk_initparents
+ *
+ * Initialise the parents for the clocks that we get at start-time
+*/
+
+static void __init s3c2412_clk_initparents(void)
+{
+       unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+       struct clk_init *cip = clks_src;
+       struct clk *src;
+       int ptr;
+       int ret;
+
+       for (ptr = 0; ptr < ARRAY_SIZE(clks_src); ptr++, cip++) {
+               ret = s3c24xx_register_clock(cip->clk);
+               if (ret < 0) {
+                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
+                              cip->clk->name, ret);
+               }
+
+               src = (clksrc & cip->bit) ? cip->src_1 : cip->src_0;
+
+               printk(KERN_INFO "%s: parent %s\n", cip->clk->name, src->name);
+               clk_set_parent(cip->clk, src);
+       }
+}
+
+/* clocks to add straight away */
+
+static struct clk *clks[] __initdata = {
+       &clk_ext,
+       &clk_usb_bus,
+       &clk_mrefclk,
+       &clk_armclk,
+};
+
+static struct clk_lookup s3c2412_clk_lookup[] = {
+       CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
+       CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
+       CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_usysclk),
+};
+
+int __init s3c2412_baseclk_add(void)
+{
+       unsigned long clkcon  = __raw_readl(S3C2410_CLKCON);
+       unsigned int dvs;
+       struct clk *clkp;
+       int ret;
+       int ptr;
+
+       clk_upll.enable = s3c2412_upll_enable;
+       clk_usb_bus.parent = &clk_usbsrc;
+       clk_usb_bus.rate = 0x0;
+
+       clk_f.parent = &clk_msysclk;
+
+       s3c2412_clk_initparents();
+
+       for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
+               clkp = clks[ptr];
+
+               ret = s3c24xx_register_clock(clkp);
+               if (ret < 0) {
+                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
+                              clkp->name, ret);
+               }
+       }
+
+       /* set the dvs state according to what we got at boot time */
+
+       dvs = __raw_readl(S3C2410_CLKDIVN) & S3C2412_CLKDIVN_DVSEN;
+
+       if (dvs)
+               clk_armclk.parent = &clk_h;
+
+       printk(KERN_INFO "S3C2412: DVS is %s\n", dvs ? "on" : "off");
+
+       /* ensure usb bus clock is within correct rate of 48MHz */
+
+       if (clk_get_rate(&clk_usb_bus) != (48 * 1000 * 1000)) {
+               printk(KERN_INFO "Warning: USB bus clock not at 48MHz\n");
+
+               /* for the moment, let's use the UPLL, and see if we can
+                * get 48MHz */
+
+               clk_set_parent(&clk_usysclk, &clk_upll);
+               clk_set_parent(&clk_usbsrc, &clk_usysclk);
+               clk_set_rate(&clk_usbsrc, 48*1000*1000);
+       }
+
+       printk("S3C2412: upll %s, %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
+              (__raw_readl(S3C2410_UPLLCON) & S3C2412_PLLCON_OFF) ? "off":"on",
+              print_mhz(clk_get_rate(&clk_upll)),
+              print_mhz(clk_get_rate(&clk_usb_bus)));
+
+       /* register clocks from clock array */
+
+       clkp = init_clocks;
+       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
+               /* ensure that we note the clock state */
+
+               clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
+
+               ret = s3c24xx_register_clock(clkp);
+               if (ret < 0) {
+                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
+                              clkp->name, ret);
+               }
+       }
+
+       /* We must be careful disabling the clocks we are not intending to
+        * be using at boot time, as subsystems such as the LCD which do
+        * their own DMA requests to the bus can cause the system to lockup
+        * if they where in the middle of requesting bus access.
+        *
+        * Disabling the LCD clock if the LCD is active is very dangerous,
+        * and therefore the bootloader should be careful to not enable
+        * the LCD clock if it is not needed.
+       */
+
+       /* install (and disable) the clocks we do not need immediately */
+
+       clkp = init_clocks_disable;
+       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+
+               ret = s3c24xx_register_clock(clkp);
+               if (ret < 0) {
+                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
+                              clkp->name, ret);
+               }
+
+               s3c2412_clkcon_enable(clkp, 0);
+       }
+
+       clkdev_add_table(s3c2412_clk_lookup, ARRAY_SIZE(s3c2412_clk_lookup));
+       s3c_pwmclk_init();
+       return 0;
+}
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2416.c b/arch/arm/mach-s3c24xx/clock-s3c2416.c
new file mode 100644 (file)
index 0000000..dbc9ab4
--- /dev/null
@@ -0,0 +1,172 @@
+/* linux/arch/arm/mach-s3c2416/clock.c
+ *
+ * Copyright (c) 2010 Simtec Electronics
+ * Copyright (c) 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * S3C2416 Clock control support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+
+#include <plat/s3c2416.h>
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/cpu.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/pll.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-s3c2443-clock.h>
+
+/* armdiv
+ *
+ * this clock is sourced from msysclk and can have a number of
+ * divider values applied to it to then be fed into armclk.
+ * The real clock definition is done in s3c2443-clock.c,
+ * only the armdiv divisor table must be defined here.
+*/
+
+static unsigned int armdiv[8] = {
+       [0] = 1,
+       [1] = 2,
+       [2] = 3,
+       [3] = 4,
+       [5] = 6,
+       [7] = 8,
+};
+
+static struct clksrc_clk hsspi_eplldiv = {
+       .clk = {
+               .name   = "hsspi-eplldiv",
+               .parent = &clk_esysclk.clk,
+               .ctrlbit = (1 << 14),
+               .enable = s3c2443_clkcon_enable_s,
+       },
+       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 24 },
+};
+
+static struct clk *hsspi_sources[] = {
+       [0] = &hsspi_eplldiv.clk,
+       [1] = NULL, /* to fix */
+};
+
+static struct clksrc_clk hsspi_mux = {
+       .clk    = {
+               .name   = "hsspi-if",
+       },
+       .sources = &(struct clksrc_sources) {
+               .sources = hsspi_sources,
+               .nr_sources = ARRAY_SIZE(hsspi_sources),
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 18 },
+};
+
+static struct clksrc_clk hsmmc_div[] = {
+       [0] = {
+               .clk = {
+                       .name   = "hsmmc-div",
+                       .devname        = "s3c-sdhci.0",
+                       .parent = &clk_esysclk.clk,
+               },
+               .reg_div = { .reg = S3C2416_CLKDIV2, .size = 2, .shift = 6 },
+       },
+       [1] = {
+               .clk = {
+                       .name   = "hsmmc-div",
+                       .devname        = "s3c-sdhci.1",
+                       .parent = &clk_esysclk.clk,
+               },
+               .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
+       },
+};
+
+static struct clksrc_clk hsmmc_mux0 = {
+       .clk    = {
+               .name           = "hsmmc-if",
+               .devname        = "s3c-sdhci.0",
+               .ctrlbit        = (1 << 6),
+               .enable         = s3c2443_clkcon_enable_s,
+       },
+       .sources        = &(struct clksrc_sources) {
+               .nr_sources     = 2,
+               .sources        = (struct clk * []) {
+                       [0]     = &hsmmc_div[0].clk,
+                       [1]     = NULL, /* to fix */
+               },
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 16 },
+};
+
+static struct clksrc_clk hsmmc_mux1 = {
+       .clk    = {
+               .name           = "hsmmc-if",
+               .devname        = "s3c-sdhci.1",
+               .ctrlbit        = (1 << 12),
+               .enable         = s3c2443_clkcon_enable_s,
+       },
+       .sources        = &(struct clksrc_sources) {
+               .nr_sources     = 2,
+               .sources        = (struct clk * []) {
+                       [0]     = &hsmmc_div[1].clk,
+                       [1]     = NULL, /* to fix */
+               },
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 17 },
+};
+
+static struct clk hsmmc0_clk = {
+       .name           = "hsmmc",
+       .devname        = "s3c-sdhci.0",
+       .parent         = &clk_h,
+       .enable         = s3c2443_clkcon_enable_h,
+       .ctrlbit        = S3C2416_HCLKCON_HSMMC0,
+};
+
+static struct clksrc_clk *clksrcs[] __initdata = {
+       &hsspi_eplldiv,
+       &hsspi_mux,
+       &hsmmc_div[0],
+       &hsmmc_div[1],
+       &hsmmc_mux0,
+       &hsmmc_mux1,
+};
+
+static struct clk_lookup s3c2416_clk_lookup[] = {
+       CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &hsmmc0_clk),
+       CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &hsmmc_mux0.clk),
+       CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &hsmmc_mux1.clk),
+};
+
+void __init s3c2416_init_clocks(int xtal)
+{
+       u32 epllcon = __raw_readl(S3C2443_EPLLCON);
+       u32 epllcon1 = __raw_readl(S3C2443_EPLLCON+4);
+       int ptr;
+
+       /* s3c2416 EPLL compatible with s3c64xx */
+       clk_epll.rate = s3c_get_pll6553x(xtal, epllcon, epllcon1);
+
+       clk_epll.parent = &clk_epllref.clk;
+
+       s3c2443_common_init_clocks(xtal, s3c2416_get_pll,
+                                  armdiv, ARRAY_SIZE(armdiv),
+                                  S3C2416_CLKDIV0_ARMDIV_MASK);
+
+       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+               s3c_register_clksrc(clksrcs[ptr], 1);
+
+       s3c24xx_register_clock(&hsmmc0_clk);
+       clkdev_add_table(s3c2416_clk_lookup, ARRAY_SIZE(s3c2416_clk_lookup));
+
+       s3c_pwmclk_init();
+
+}
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2440.c b/arch/arm/mach-s3c24xx/clock-s3c2440.c
new file mode 100644 (file)
index 0000000..414364e
--- /dev/null
@@ -0,0 +1,194 @@
+/* linux/arch/arm/mach-s3c2440/clock.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2440 Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/serial_core.h>
+
+#include <mach/hardware.h>
+#include <linux/atomic.h>
+#include <asm/irq.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/regs-serial.h>
+
+/* S3C2440 extended clock support */
+
+static unsigned long s3c2440_camif_upll_round(struct clk *clk,
+                                             unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       int div;
+
+       if (rate > parent_rate)
+               return parent_rate;
+
+       /* note, we remove the +/- 1 calculations for the divisor */
+
+       div = (parent_rate / rate) / 2;
+
+       if (div < 1)
+               div = 1;
+       else if (div > 16)
+               div = 16;
+
+       return parent_rate / (div * 2);
+}
+
+static int s3c2440_camif_upll_setrate(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
+
+       rate = s3c2440_camif_upll_round(clk, rate);
+
+       camdivn &= ~(S3C2440_CAMDIVN_CAMCLK_SEL | S3C2440_CAMDIVN_CAMCLK_MASK);
+
+       if (rate != parent_rate) {
+               camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+               camdivn |= (((parent_rate / rate) / 2) - 1);
+       }
+
+       __raw_writel(camdivn, S3C2440_CAMDIVN);
+
+       return 0;
+}
+
+/* Extra S3C2440 clocks */
+
+static struct clk s3c2440_clk_cam = {
+       .name           = "camif",
+       .enable         = s3c2410_clkcon_enable,
+       .ctrlbit        = S3C2440_CLKCON_CAMERA,
+};
+
+static struct clk s3c2440_clk_cam_upll = {
+       .name           = "camif-upll",
+       .ops            = &(struct clk_ops) {
+               .set_rate       = s3c2440_camif_upll_setrate,
+               .round_rate     = s3c2440_camif_upll_round,
+       },
+};
+
+static struct clk s3c2440_clk_ac97 = {
+       .name           = "ac97",
+       .enable         = s3c2410_clkcon_enable,
+       .ctrlbit        = S3C2440_CLKCON_CAMERA,
+};
+
+static unsigned long  s3c2440_fclk_n_getrate(struct clk *clk)
+{
+       unsigned long ucon0, ucon1, ucon2, divisor;
+
+       /* the fun of calculating the uart divisors on the s3c2440 */
+       ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON);
+       ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON);
+       ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON);
+
+       ucon0 &= S3C2440_UCON0_DIVMASK;
+       ucon1 &= S3C2440_UCON1_DIVMASK;
+       ucon2 &= S3C2440_UCON2_DIVMASK;
+
+       if (ucon0 != 0)
+               divisor = (ucon0 >> S3C2440_UCON_DIVSHIFT) + 6;
+       else if (ucon1 != 0)
+               divisor = (ucon1 >> S3C2440_UCON_DIVSHIFT) + 21;
+       else if (ucon2 != 0)
+               divisor = (ucon2 >> S3C2440_UCON_DIVSHIFT) + 36;
+       else
+               /* manual calims 44, seems to be 9 */
+               divisor = 9;
+
+       return clk_get_rate(clk->parent) / divisor;
+}
+
+static struct clk s3c2440_clk_fclk_n = {
+       .name           = "fclk_n",
+       .parent         = &clk_f,
+       .ops            = &(struct clk_ops) {
+               .get_rate       = s3c2440_fclk_n_getrate,
+       },
+};
+
+static struct clk_lookup s3c2440_clk_lookup[] = {
+       CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
+       CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
+       CLKDEV_INIT(NULL, "clk_uart_baud3", &s3c2440_clk_fclk_n),
+};
+
+static int s3c2440_clk_add(struct device *dev, struct subsys_interface *sif)
+{
+       struct clk *clock_upll;
+       struct clk *clock_h;
+       struct clk *clock_p;
+
+       clock_p = clk_get(NULL, "pclk");
+       clock_h = clk_get(NULL, "hclk");
+       clock_upll = clk_get(NULL, "upll");
+
+       if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
+               printk(KERN_ERR "S3C2440: Failed to get parent clocks\n");
+               return -EINVAL;
+       }
+
+       s3c2440_clk_cam.parent = clock_h;
+       s3c2440_clk_ac97.parent = clock_p;
+       s3c2440_clk_cam_upll.parent = clock_upll;
+       s3c24xx_register_clock(&s3c2440_clk_fclk_n);
+
+       s3c24xx_register_clock(&s3c2440_clk_ac97);
+       s3c24xx_register_clock(&s3c2440_clk_cam);
+       s3c24xx_register_clock(&s3c2440_clk_cam_upll);
+       clkdev_add_table(s3c2440_clk_lookup, ARRAY_SIZE(s3c2440_clk_lookup));
+
+       clk_disable(&s3c2440_clk_ac97);
+       clk_disable(&s3c2440_clk_cam);
+
+       return 0;
+}
+
+static struct subsys_interface s3c2440_clk_interface = {
+       .name           = "s3c2440_clk",
+       .subsys         = &s3c2440_subsys,
+       .add_dev        = s3c2440_clk_add,
+};
+
+static __init int s3c24xx_clk_init(void)
+{
+       return subsys_interface_register(&s3c2440_clk_interface);
+}
+
+arch_initcall(s3c24xx_clk_init);
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2443.c b/arch/arm/mach-s3c24xx/clock-s3c2443.c
new file mode 100644 (file)
index 0000000..efb3ac3
--- /dev/null
@@ -0,0 +1,215 @@
+/* linux/arch/arm/mach-s3c2443/clock.c
+ *
+ * Copyright (c) 2007, 2010 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2443 Clock control support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/init.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/cpu-freq.h>
+
+#include <plat/s3c2443.h>
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/cpu.h>
+
+/* We currently have to assume that the system is running
+ * from the XTPll input, and that all ***REFCLKs are being
+ * fed from it, as we cannot read the state of OM[4] from
+ * software.
+ *
+ * It would be possible for each board initialisation to
+ * set the correct muxing at initialisation
+*/
+
+/* clock selections */
+
+/* armdiv
+ *
+ * this clock is sourced from msysclk and can have a number of
+ * divider values applied to it to then be fed into armclk.
+ * The real clock definition is done in s3c2443-clock.c,
+ * only the armdiv divisor table must be defined here.
+*/
+
+static unsigned int armdiv[16] = {
+       [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 1,
+       [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 2,
+       [S3C2443_CLKDIV0_ARMDIV_3 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 3,
+       [S3C2443_CLKDIV0_ARMDIV_4 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 4,
+       [S3C2443_CLKDIV0_ARMDIV_6 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 6,
+       [S3C2443_CLKDIV0_ARMDIV_8 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 8,
+       [S3C2443_CLKDIV0_ARMDIV_12 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]     = 12,
+       [S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]     = 16,
+};
+
+/* hsspi
+ *
+ * high-speed spi clock, sourced from esysclk
+*/
+
+static struct clksrc_clk clk_hsspi = {
+       .clk    = {
+               .name           = "hsspi-if",
+               .parent         = &clk_esysclk.clk,
+               .ctrlbit        = S3C2443_SCLKCON_HSSPICLK,
+               .enable         = s3c2443_clkcon_enable_s,
+       },
+       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
+};
+
+
+/* clk_hsmcc_div
+ *
+ * this clock is sourced from epll, and is fed through a divider,
+ * to a mux controlled by sclkcon where either it or a extclk can
+ * be fed to the hsmmc block
+*/
+
+static struct clksrc_clk clk_hsmmc_div = {
+       .clk    = {
+               .name           = "hsmmc-div",
+               .devname        = "s3c-sdhci.1",
+               .parent         = &clk_esysclk.clk,
+       },
+       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
+};
+
+static int s3c2443_setparent_hsmmc(struct clk *clk, struct clk *parent)
+{
+       unsigned long clksrc = __raw_readl(S3C2443_SCLKCON);
+
+       clksrc &= ~(S3C2443_SCLKCON_HSMMCCLK_EXT |
+                   S3C2443_SCLKCON_HSMMCCLK_EPLL);
+
+       if (parent == &clk_epll)
+               clksrc |= S3C2443_SCLKCON_HSMMCCLK_EPLL;
+       else if (parent == &clk_ext)
+               clksrc |= S3C2443_SCLKCON_HSMMCCLK_EXT;
+       else
+               return -EINVAL;
+
+       if (clk->usage > 0) {
+               __raw_writel(clksrc, S3C2443_SCLKCON);
+       }
+
+       clk->parent = parent;
+       return 0;
+}
+
+static int s3c2443_enable_hsmmc(struct clk *clk, int enable)
+{
+       return s3c2443_setparent_hsmmc(clk, clk->parent);
+}
+
+static struct clk clk_hsmmc = {
+       .name           = "hsmmc-if",
+       .devname        = "s3c-sdhci.1",
+       .parent         = &clk_hsmmc_div.clk,
+       .enable         = s3c2443_enable_hsmmc,
+       .ops            = &(struct clk_ops) {
+               .set_parent     = s3c2443_setparent_hsmmc,
+       },
+};
+
+/* standard clock definitions */
+
+static struct clk init_clocks_off[] = {
+       {
+               .name           = "sdi",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_SDI,
+       }, {
+               .name           = "spi",
+               .devname        = "s3c2410-spi.0",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_SPI0,
+       }, {
+               .name           = "spi",
+               .devname        = "s3c2410-spi.1",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_SPI1,
+       }
+};
+
+/* clocks to add straight away */
+
+static struct clksrc_clk *clksrcs[] __initdata = {
+       &clk_hsspi,
+       &clk_hsmmc_div,
+};
+
+static struct clk *clks[] __initdata = {
+       &clk_hsmmc,
+};
+
+void __init s3c2443_init_clocks(int xtal)
+{
+       unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
+       int ptr;
+
+       clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
+       clk_epll.parent = &clk_epllref.clk;
+
+       s3c2443_common_init_clocks(xtal, s3c2443_get_mpll,
+                                  armdiv, ARRAY_SIZE(armdiv),
+                                  S3C2443_CLKDIV0_ARMDIV_MASK);
+
+       s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+               s3c_register_clksrc(clksrcs[ptr], 1);
+
+       /* We must be careful disabling the clocks we are not intending to
+        * be using at boot time, as subsystems such as the LCD which do
+        * their own DMA requests to the bus can cause the system to lockup
+        * if they where in the middle of requesting bus access.
+        *
+        * Disabling the LCD clock if the LCD is active is very dangerous,
+        * and therefore the bootloader should be careful to not enable
+        * the LCD clock if it is not needed.
+       */
+
+       /* install (and disable) the clocks we do not need immediately */
+
+       s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+       s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+
+       s3c_pwmclk_init();
+}
diff --git a/arch/arm/mach-s3c24xx/clock-s3c244x.c b/arch/arm/mach-s3c24xx/clock-s3c244x.c
new file mode 100644 (file)
index 0000000..6d9b688
--- /dev/null
@@ -0,0 +1,141 @@
+/* linux/arch/arm/plat-s3c24xx/s3c24xx-clock.c
+ *
+ * Copyright (c) 2004-2008 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2440/S3C2442 Common clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <linux/atomic.h>
+#include <asm/irq.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent)
+{
+       unsigned long camdivn;
+       unsigned long dvs;
+
+       if (parent == &clk_f)
+               dvs = 0;
+       else if (parent == &clk_h)
+               dvs = S3C2440_CAMDIVN_DVSEN;
+       else
+               return -EINVAL;
+
+       clk->parent = parent;
+
+       camdivn  = __raw_readl(S3C2440_CAMDIVN);
+       camdivn &= ~S3C2440_CAMDIVN_DVSEN;
+       camdivn |= dvs;
+       __raw_writel(camdivn, S3C2440_CAMDIVN);
+
+       return 0;
+}
+
+static struct clk clk_arm = {
+       .name           = "armclk",
+       .id             = -1,
+       .ops            = &(struct clk_ops) {
+               .set_parent     = s3c2440_setparent_armclk,
+       },
+};
+
+static int s3c244x_clk_add(struct device *dev, struct subsys_interface *sif)
+{
+       unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
+       unsigned long clkdivn;
+       struct clk *clock_upll;
+       int ret;
+
+       printk("S3C244X: Clock Support, DVS %s\n",
+              (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
+
+       clk_arm.parent = (camdivn & S3C2440_CAMDIVN_DVSEN) ? &clk_h : &clk_f;
+
+       ret = s3c24xx_register_clock(&clk_arm);
+       if (ret < 0) {
+               printk(KERN_ERR "S3C24XX: Failed to add armclk (%d)\n", ret);
+               return ret;
+       }
+
+       clock_upll = clk_get(NULL, "upll");
+       if (IS_ERR(clock_upll)) {
+               printk(KERN_ERR "S3C244X: Failed to get upll clock\n");
+               return -ENOENT;
+       }
+
+       /* check rate of UPLL, and if it is near 96MHz, then change
+        * to using half the UPLL rate for the system */
+
+       if (clk_get_rate(clock_upll) > (94 * MHZ)) {
+               clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
+
+               spin_lock(&clocks_lock);
+
+               clkdivn = __raw_readl(S3C2410_CLKDIVN);
+               clkdivn |= S3C2440_CLKDIVN_UCLK;
+               __raw_writel(clkdivn, S3C2410_CLKDIVN);
+
+               spin_unlock(&clocks_lock);
+       }
+
+       return 0;
+}
+
+static struct subsys_interface s3c2440_clk_interface = {
+       .name           = "s3c2440_clk",
+       .subsys         = &s3c2440_subsys,
+       .add_dev        = s3c244x_clk_add,
+};
+
+static int s3c2440_clk_init(void)
+{
+       return subsys_interface_register(&s3c2440_clk_interface);
+}
+
+arch_initcall(s3c2440_clk_init);
+
+static struct subsys_interface s3c2442_clk_interface = {
+       .name           = "s3c2442_clk",
+       .subsys         = &s3c2442_subsys,
+       .add_dev        = s3c244x_clk_add,
+};
+
+static int s3c2442_clk_init(void)
+{
+       return subsys_interface_register(&s3c2442_clk_interface);
+}
+
+arch_initcall(s3c2442_clk_init);
diff --git a/arch/arm/mach-s3c24xx/common-s3c2443.c b/arch/arm/mach-s3c24xx/common-s3c2443.c
new file mode 100644 (file)
index 0000000..4604315
--- /dev/null
@@ -0,0 +1,670 @@
+/*
+ * Common code for SoCs starting with the S3C2443
+ *
+ * Copyright (c) 2007, 2010 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/cpu.h>
+
+#include <plat/cpu-freq.h>
+
+
+static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
+{
+       u32 ctrlbit = clk->ctrlbit;
+       u32 con = __raw_readl(reg);
+
+       if (enable)
+               con |= ctrlbit;
+       else
+               con &= ~ctrlbit;
+
+       __raw_writel(con, reg);
+       return 0;
+}
+
+int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
+{
+       return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
+}
+
+int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
+{
+       return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
+}
+
+int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
+{
+       return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
+}
+
+/* mpllref is a direct descendant of clk_xtal by default, but it is not
+ * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
+ * such directly equating the two source clocks is impossible.
+ */
+static struct clk clk_mpllref = {
+       .name           = "mpllref",
+       .parent         = &clk_xtal,
+};
+
+static struct clk *clk_epllref_sources[] = {
+       [0] = &clk_mpllref,
+       [1] = &clk_mpllref,
+       [2] = &clk_xtal,
+       [3] = &clk_ext,
+};
+
+struct clksrc_clk clk_epllref = {
+       .clk    = {
+               .name           = "epllref",
+       },
+       .sources = &(struct clksrc_sources) {
+               .sources = clk_epllref_sources,
+               .nr_sources = ARRAY_SIZE(clk_epllref_sources),
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
+};
+
+/* esysclk
+ *
+ * this is sourced from either the EPLL or the EPLLref clock
+*/
+
+static struct clk *clk_sysclk_sources[] = {
+       [0] = &clk_epllref.clk,
+       [1] = &clk_epll,
+};
+
+struct clksrc_clk clk_esysclk = {
+       .clk    = {
+               .name           = "esysclk",
+               .parent         = &clk_epll,
+       },
+       .sources = &(struct clksrc_sources) {
+               .sources = clk_sysclk_sources,
+               .nr_sources = ARRAY_SIZE(clk_sysclk_sources),
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
+};
+
+static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2443_CLKDIV0);
+
+       div  &= S3C2443_CLKDIV0_EXTDIV_MASK;
+       div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1);       /* x2 */
+
+       return parent_rate / (div + 1);
+}
+
+static struct clk clk_mdivclk = {
+       .name           = "mdivclk",
+       .parent         = &clk_mpllref,
+       .ops            = &(struct clk_ops) {
+               .get_rate       = s3c2443_getrate_mdivclk,
+       },
+};
+
+static struct clk *clk_msysclk_sources[] = {
+       [0] = &clk_mpllref,
+       [1] = &clk_mpll,
+       [2] = &clk_mdivclk,
+       [3] = &clk_mpllref,
+};
+
+struct clksrc_clk clk_msysclk = {
+       .clk    = {
+               .name           = "msysclk",
+               .parent         = &clk_xtal,
+       },
+       .sources = &(struct clksrc_sources) {
+               .sources = clk_msysclk_sources,
+               .nr_sources = ARRAY_SIZE(clk_msysclk_sources),
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
+};
+
+/* prediv
+ *
+ * this divides the msysclk down to pass to h/p/etc.
+ */
+
+static unsigned long s3c2443_prediv_getrate(struct clk *clk)
+{
+       unsigned long rate = clk_get_rate(clk->parent);
+       unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+
+       clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
+       clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
+
+       return rate / (clkdiv0 + 1);
+}
+
+static struct clk clk_prediv = {
+       .name           = "prediv",
+       .parent         = &clk_msysclk.clk,
+       .ops            = &(struct clk_ops) {
+               .get_rate       = s3c2443_prediv_getrate,
+       },
+};
+
+/* hclk divider
+ *
+ * divides the prediv and provides the hclk.
+ */
+
+static unsigned long s3c2443_hclkdiv_getrate(struct clk *clk)
+{
+       unsigned long rate = clk_get_rate(clk->parent);
+       unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+
+       clkdiv0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
+
+       return rate / (clkdiv0 + 1);
+}
+
+static struct clk_ops clk_h_ops = {
+       .get_rate       = s3c2443_hclkdiv_getrate,
+};
+
+/* pclk divider
+ *
+ * divides the hclk and provides the pclk.
+ */
+
+static unsigned long s3c2443_pclkdiv_getrate(struct clk *clk)
+{
+       unsigned long rate = clk_get_rate(clk->parent);
+       unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+
+       clkdiv0 = ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 1 : 0);
+
+       return rate / (clkdiv0 + 1);
+}
+
+static struct clk_ops clk_p_ops = {
+       .get_rate       = s3c2443_pclkdiv_getrate,
+};
+
+/* armdiv
+ *
+ * this clock is sourced from msysclk and can have a number of
+ * divider values applied to it to then be fed into armclk.
+*/
+
+static unsigned int *armdiv;
+static int nr_armdiv;
+static int armdivmask;
+
+static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
+                                             unsigned long rate)
+{
+       unsigned long parent = clk_get_rate(clk->parent);
+       unsigned long calc;
+       unsigned best = 256; /* bigger than any value */
+       unsigned div;
+       int ptr;
+
+       if (!nr_armdiv)
+               return -EINVAL;
+
+       for (ptr = 0; ptr < nr_armdiv; ptr++) {
+               div = armdiv[ptr];
+               if (div) {
+                       /* cpufreq provides 266mhz as 266666000 not 266666666 */
+                       calc = (parent / div / 1000) * 1000;
+                       if (calc <= rate && div < best)
+                               best = div;
+               }
+       }
+
+       return parent / best;
+}
+
+static unsigned long s3c2443_armclk_getrate(struct clk *clk)
+{
+       unsigned long rate = clk_get_rate(clk->parent);
+       unsigned long clkcon0;
+       int val;
+
+       if (!nr_armdiv || !armdivmask)
+               return -EINVAL;
+
+       clkcon0 = __raw_readl(S3C2443_CLKDIV0);
+       clkcon0 &= armdivmask;
+       val = clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT;
+
+       return rate / armdiv[val];
+}
+
+static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent = clk_get_rate(clk->parent);
+       unsigned long calc;
+       unsigned div;
+       unsigned best = 256; /* bigger than any value */
+       int ptr;
+       int val = -1;
+
+       if (!nr_armdiv || !armdivmask)
+               return -EINVAL;
+
+       for (ptr = 0; ptr < nr_armdiv; ptr++) {
+               div = armdiv[ptr];
+               if (div) {
+                       /* cpufreq provides 266mhz as 266666000 not 266666666 */
+                       calc = (parent / div / 1000) * 1000;
+                       if (calc <= rate && div < best) {
+                               best = div;
+                               val = ptr;
+                       }
+               }
+       }
+
+       if (val >= 0) {
+               unsigned long clkcon0;
+
+               clkcon0 = __raw_readl(S3C2443_CLKDIV0);
+               clkcon0 &= ~armdivmask;
+               clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT;
+               __raw_writel(clkcon0, S3C2443_CLKDIV0);
+       }
+
+       return (val == -1) ? -EINVAL : 0;
+}
+
+static struct clk clk_armdiv = {
+       .name           = "armdiv",
+       .parent         = &clk_msysclk.clk,
+       .ops            = &(struct clk_ops) {
+               .round_rate = s3c2443_armclk_roundrate,
+               .get_rate = s3c2443_armclk_getrate,
+               .set_rate = s3c2443_armclk_setrate,
+       },
+};
+
+/* armclk
+ *
+ * this is the clock fed into the ARM core itself, from armdiv or from hclk.
+ */
+
+static struct clk *clk_arm_sources[] = {
+       [0] = &clk_armdiv,
+       [1] = &clk_h,
+};
+
+static struct clksrc_clk clk_arm = {
+       .clk    = {
+               .name           = "armclk",
+       },
+       .sources = &(struct clksrc_sources) {
+               .sources = clk_arm_sources,
+               .nr_sources = ARRAY_SIZE(clk_arm_sources),
+       },
+       .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
+};
+
+/* usbhost
+ *
+ * usb host bus-clock, usually 48MHz to provide USB bus clock timing
+*/
+
+static struct clksrc_clk clk_usb_bus_host = {
+       .clk    = {
+               .name           = "usb-bus-host-parent",
+               .parent         = &clk_esysclk.clk,
+               .ctrlbit        = S3C2443_SCLKCON_USBHOST,
+               .enable         = s3c2443_clkcon_enable_s,
+       },
+       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
+};
+
+/* common clksrc clocks */
+
+static struct clksrc_clk clksrc_clks[] = {
+       {
+               /* camera interface bus-clock, divided down from esysclk */
+               .clk    = {
+                       .name           = "camif-upll", /* same as 2440 name */
+                       .parent         = &clk_esysclk.clk,
+                       .ctrlbit        = S3C2443_SCLKCON_CAMCLK,
+                       .enable         = s3c2443_clkcon_enable_s,
+               },
+               .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
+       }, {
+               .clk    = {
+                       .name           = "display-if",
+                       .parent         = &clk_esysclk.clk,
+                       .ctrlbit        = S3C2443_SCLKCON_DISPCLK,
+                       .enable         = s3c2443_clkcon_enable_s,
+               },
+               .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
+       },
+};
+
+static struct clksrc_clk clk_esys_uart = {
+       /* ART baud-rate clock sourced from esysclk via a divisor */
+       .clk    = {
+               .name           = "uartclk",
+               .parent         = &clk_esysclk.clk,
+       },
+       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
+};
+
+static struct clk clk_i2s_ext = {
+       .name           = "i2s-ext",
+};
+
+/* i2s_eplldiv
+ *
+ * This clock is the output from the I2S divisor of ESYSCLK, and is separate
+ * from the mux that comes after it (cannot merge into one single clock)
+*/
+
+static struct clksrc_clk clk_i2s_eplldiv = {
+       .clk    = {
+               .name           = "i2s-eplldiv",
+               .parent         = &clk_esysclk.clk,
+       },
+       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 12, },
+};
+
+/* i2s-ref
+ *
+ * i2s bus reference clock, selectable from external, esysclk or epllref
+ *
+ * Note, this used to be two clocks, but was compressed into one.
+*/
+
+static struct clk *clk_i2s_srclist[] = {
+       [0] = &clk_i2s_eplldiv.clk,
+       [1] = &clk_i2s_ext,
+       [2] = &clk_epllref.clk,
+       [3] = &clk_epllref.clk,
+};
+
+static struct clksrc_clk clk_i2s = {
+       .clk    = {
+               .name           = "i2s-if",
+               .ctrlbit        = S3C2443_SCLKCON_I2SCLK,
+               .enable         = s3c2443_clkcon_enable_s,
+
+       },
+       .sources = &(struct clksrc_sources) {
+               .sources = clk_i2s_srclist,
+               .nr_sources = ARRAY_SIZE(clk_i2s_srclist),
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
+};
+
+static struct clk init_clocks_off[] = {
+       {
+               .name           = "iis",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_IIS,
+       }, {
+               .name           = "hsspi",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_HSSPI,
+       }, {
+               .name           = "adc",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_ADC,
+       }, {
+               .name           = "i2c",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_IIC,
+       }
+};
+
+static struct clk init_clocks[] = {
+       {
+               .name           = "dma",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA0,
+       }, {
+               .name           = "dma",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA1,
+       }, {
+               .name           = "dma",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA2,
+       }, {
+               .name           = "dma",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA3,
+       }, {
+               .name           = "dma",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA4,
+       }, {
+               .name           = "dma",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA5,
+       }, {
+               .name           = "gpio",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_GPIO,
+       }, {
+               .name           = "usb-host",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_USBH,
+       }, {
+               .name           = "usb-device",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_USBD,
+       }, {
+               .name           = "lcd",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_LCDC,
+
+       }, {
+               .name           = "timers",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_PWMT,
+       }, {
+               .name           = "cfc",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_CFC,
+       }, {
+               .name           = "ssmc",
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_SSMC,
+       }, {
+               .name           = "uart",
+               .devname        = "s3c2440-uart.0",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_UART0,
+       }, {
+               .name           = "uart",
+               .devname        = "s3c2440-uart.1",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_UART1,
+       }, {
+               .name           = "uart",
+               .devname        = "s3c2440-uart.2",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_UART2,
+       }, {
+               .name           = "uart",
+               .devname        = "s3c2440-uart.3",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_UART3,
+       }, {
+               .name           = "rtc",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_RTC,
+       }, {
+               .name           = "watchdog",
+               .parent         = &clk_p,
+               .ctrlbit        = S3C2443_PCLKCON_WDT,
+       }, {
+               .name           = "ac97",
+               .parent         = &clk_p,
+               .ctrlbit        = S3C2443_PCLKCON_AC97,
+       }, {
+               .name           = "nand",
+               .parent         = &clk_h,
+       }, {
+               .name           = "usb-bus-host",
+               .parent         = &clk_usb_bus_host.clk,
+       }
+};
+
+static struct clk hsmmc1_clk = {
+       .name           = "hsmmc",
+       .devname        = "s3c-sdhci.1",
+       .parent         = &clk_h,
+       .enable         = s3c2443_clkcon_enable_h,
+       .ctrlbit        = S3C2443_HCLKCON_HSMMC,
+};
+
+/* EPLLCON compatible enough to get on/off information */
+
+void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll)
+{
+       unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
+       unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
+       struct clk *xtal_clk;
+       unsigned long xtal;
+       unsigned long pll;
+       int ptr;
+
+       xtal_clk = clk_get(NULL, "xtal");
+       xtal = clk_get_rate(xtal_clk);
+       clk_put(xtal_clk);
+
+       pll = get_mpll(mpllcon, xtal);
+       clk_msysclk.clk.rate = pll;
+       clk_mpll.rate = pll;
+
+       printk("CPU: MPLL %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
+              (mpllcon & S3C2443_PLLCON_OFF) ? "off" : "on",
+              print_mhz(pll), print_mhz(clk_get_rate(&clk_armdiv)),
+              print_mhz(clk_get_rate(&clk_h)),
+              print_mhz(clk_get_rate(&clk_p)));
+
+       for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++)
+               s3c_set_clksrc(&clksrc_clks[ptr], true);
+
+       /* ensure usb bus clock is within correct rate of 48MHz */
+
+       if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
+               printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
+               clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
+       }
+
+       printk("CPU: EPLL %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
+              (epllcon & S3C2443_PLLCON_OFF) ? "off" : "on",
+              print_mhz(clk_get_rate(&clk_epll)),
+              print_mhz(clk_get_rate(&clk_usb_bus)));
+}
+
+static struct clk *clks[] __initdata = {
+       &clk_prediv,
+       &clk_mpllref,
+       &clk_mdivclk,
+       &clk_ext,
+       &clk_epll,
+       &clk_usb_bus,
+       &clk_armdiv,
+       &hsmmc1_clk,
+};
+
+static struct clksrc_clk *clksrcs[] __initdata = {
+       &clk_i2s_eplldiv,
+       &clk_i2s,
+       &clk_usb_bus_host,
+       &clk_epllref,
+       &clk_esysclk,
+       &clk_msysclk,
+       &clk_arm,
+};
+
+static struct clk_lookup s3c2443_clk_lookup[] = {
+       CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
+       CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
+       CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk),
+       CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &hsmmc1_clk),
+};
+
+void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
+                                      unsigned int *divs, int nr_divs,
+                                      int divmask)
+{
+       int ptr;
+
+       armdiv = divs;
+       nr_armdiv = nr_divs;
+       armdivmask = divmask;
+
+       /* s3c2443 parents h clock from prediv */
+       clk_h.parent = &clk_prediv;
+       clk_h.ops = &clk_h_ops;
+
+       /* and p clock from h clock */
+       clk_p.parent = &clk_h;
+       clk_p.ops = &clk_p_ops;
+
+       clk_usb_bus.parent = &clk_usb_bus_host.clk;
+       clk_epll.parent = &clk_epllref.clk;
+
+       s3c24xx_register_baseclocks(xtal);
+       s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+               s3c_register_clksrc(clksrcs[ptr], 1);
+
+       s3c_register_clksrc(clksrc_clks, ARRAY_SIZE(clksrc_clks));
+       s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+       /* See s3c2443/etc notes on disabling clocks at init time */
+       s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+       s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+       clkdev_add_table(s3c2443_clk_lookup, ARRAY_SIZE(s3c2443_clk_lookup));
+
+       s3c2443_common_setup_clocks(get_mpll);
+}
diff --git a/arch/arm/mach-s3c24xx/common-smdk.c b/arch/arm/mach-s3c24xx/common-smdk.c
new file mode 100644 (file)
index 0000000..084604b
--- /dev/null
@@ -0,0 +1,207 @@
+/* linux/arch/arm/plat-s3c24xx/common-smdk.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Common code for SMDK2410 and SMDK2440 boards
+ *
+ * http://www.fluff.org/ben/smdk2440/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/leds-gpio.h>
+
+#include <plat/nand.h>
+
+#include <plat/common-smdk.h>
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <plat/pm.h>
+
+/* LED devices */
+
+static struct s3c24xx_led_platdata smdk_pdata_led4 = {
+       .gpio           = S3C2410_GPF(4),
+       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+       .name           = "led4",
+       .def_trigger    = "timer",
+};
+
+static struct s3c24xx_led_platdata smdk_pdata_led5 = {
+       .gpio           = S3C2410_GPF(5),
+       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+       .name           = "led5",
+       .def_trigger    = "nand-disk",
+};
+
+static struct s3c24xx_led_platdata smdk_pdata_led6 = {
+       .gpio           = S3C2410_GPF(6),
+       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+       .name           = "led6",
+};
+
+static struct s3c24xx_led_platdata smdk_pdata_led7 = {
+       .gpio           = S3C2410_GPF(7),
+       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+       .name           = "led7",
+};
+
+static struct platform_device smdk_led4 = {
+       .name           = "s3c24xx_led",
+       .id             = 0,
+       .dev            = {
+               .platform_data = &smdk_pdata_led4,
+       },
+};
+
+static struct platform_device smdk_led5 = {
+       .name           = "s3c24xx_led",
+       .id             = 1,
+       .dev            = {
+               .platform_data = &smdk_pdata_led5,
+       },
+};
+
+static struct platform_device smdk_led6 = {
+       .name           = "s3c24xx_led",
+       .id             = 2,
+       .dev            = {
+               .platform_data = &smdk_pdata_led6,
+       },
+};
+
+static struct platform_device smdk_led7 = {
+       .name           = "s3c24xx_led",
+       .id             = 3,
+       .dev            = {
+               .platform_data = &smdk_pdata_led7,
+       },
+};
+
+/* NAND parititon from 2.4.18-swl5 */
+
+static struct mtd_partition smdk_default_nand_part[] = {
+       [0] = {
+               .name   = "Boot Agent",
+               .size   = SZ_16K,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "S3C2410 flash partition 1",
+               .offset = 0,
+               .size   = SZ_2M,
+       },
+       [2] = {
+               .name   = "S3C2410 flash partition 2",
+               .offset = SZ_4M,
+               .size   = SZ_4M,
+       },
+       [3] = {
+               .name   = "S3C2410 flash partition 3",
+               .offset = SZ_8M,
+               .size   = SZ_2M,
+       },
+       [4] = {
+               .name   = "S3C2410 flash partition 4",
+               .offset = SZ_1M * 10,
+               .size   = SZ_4M,
+       },
+       [5] = {
+               .name   = "S3C2410 flash partition 5",
+               .offset = SZ_1M * 14,
+               .size   = SZ_1M * 10,
+       },
+       [6] = {
+               .name   = "S3C2410 flash partition 6",
+               .offset = SZ_1M * 24,
+               .size   = SZ_1M * 24,
+       },
+       [7] = {
+               .name   = "S3C2410 flash partition 7",
+               .offset = SZ_1M * 48,
+               .size   = MTDPART_SIZ_FULL,
+       }
+};
+
+static struct s3c2410_nand_set smdk_nand_sets[] = {
+       [0] = {
+               .name           = "NAND",
+               .nr_chips       = 1,
+               .nr_partitions  = ARRAY_SIZE(smdk_default_nand_part),
+               .partitions     = smdk_default_nand_part,
+       },
+};
+
+/* choose a set of timings which should suit most 512Mbit
+ * chips and beyond.
+*/
+
+static struct s3c2410_platform_nand smdk_nand_info = {
+       .tacls          = 20,
+       .twrph0         = 60,
+       .twrph1         = 20,
+       .nr_sets        = ARRAY_SIZE(smdk_nand_sets),
+       .sets           = smdk_nand_sets,
+};
+
+/* devices we initialise */
+
+static struct platform_device __initdata *smdk_devs[] = {
+       &s3c_device_nand,
+       &smdk_led4,
+       &smdk_led5,
+       &smdk_led6,
+       &smdk_led7,
+};
+
+void __init smdk_machine_init(void)
+{
+       /* Configure the LEDs (even if we have no LED support)*/
+
+       s3c_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT);
+       s3c_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT);
+       s3c_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT);
+       s3c_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT);
+
+       s3c2410_gpio_setpin(S3C2410_GPF(4), 1);
+       s3c2410_gpio_setpin(S3C2410_GPF(5), 1);
+       s3c2410_gpio_setpin(S3C2410_GPF(6), 1);
+       s3c2410_gpio_setpin(S3C2410_GPF(7), 1);
+
+       if (machine_is_smdk2443())
+               smdk_nand_info.twrph0 = 50;
+
+       s3c_nand_set_platdata(&smdk_nand_info);
+
+       platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs));
+
+       s3c_pm_init();
+}
diff --git a/arch/arm/mach-s3c24xx/dma-s3c2410.c b/arch/arm/mach-s3c24xx/dma-s3c2410.c
new file mode 100644 (file)
index 0000000..4803338
--- /dev/null
@@ -0,0 +1,186 @@
+/* linux/arch/arm/mach-s3c2410/dma.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 DMA selection
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/serial_core.h>
+
+#include <mach/map.h>
+#include <mach/dma.h>
+
+#include <plat/cpu.h>
+#include <plat/dma-s3c24xx.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <plat/regs-ac97.h>
+#include <plat/regs-dma.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+#include <mach/regs-sdi.h>
+#include <plat/regs-iis.h>
+#include <plat/regs-spi.h>
+
+static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
+       [DMACH_XD0] = {
+               .name           = "xdreq0",
+               .channels[0]    = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
+       },
+       [DMACH_XD1] = {
+               .name           = "xdreq1",
+               .channels[1]    = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
+       },
+       [DMACH_SDI] = {
+               .name           = "sdi",
+               .channels[0]    = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
+               .channels[3]    = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
+       },
+       [DMACH_SPI0] = {
+               .name           = "spi0",
+               .channels[1]    = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
+       },
+       [DMACH_SPI1] = {
+               .name           = "spi1",
+               .channels[3]    = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
+       },
+       [DMACH_UART0] = {
+               .name           = "uart0",
+               .channels[0]    = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
+       },
+       [DMACH_UART1] = {
+               .name           = "uart1",
+               .channels[1]    = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
+       },
+       [DMACH_UART2] = {
+               .name           = "uart2",
+               .channels[3]    = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
+       },
+       [DMACH_TIMER] = {
+               .name           = "timer",
+               .channels[0]    = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
+               .channels[3]    = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
+       },
+       [DMACH_I2S_IN] = {
+               .name           = "i2s-sdi",
+               .channels[1]    = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
+       },
+       [DMACH_I2S_OUT] = {
+               .name           = "i2s-sdo",
+               .channels[2]    = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP1] = {
+               .name           = "usb-ep1",
+               .channels[0]    = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP2] = {
+               .name           = "usb-ep2",
+               .channels[1]    = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP3] = {
+               .name           = "usb-ep3",
+               .channels[2]    = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP4] = {
+               .name           = "usb-ep4",
+               .channels[3]    =S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
+       },
+};
+
+static void s3c2410_dma_select(struct s3c2410_dma_chan *chan,
+                              struct s3c24xx_dma_map *map)
+{
+       chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
+}
+
+static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = {
+       .select         = s3c2410_dma_select,
+       .dcon_mask      = 7 << 24,
+       .map            = s3c2410_dma_mappings,
+       .map_size       = ARRAY_SIZE(s3c2410_dma_mappings),
+};
+
+static struct s3c24xx_dma_order __initdata s3c2410_dma_order = {
+       .channels       = {
+               [DMACH_SDI]     = {
+                       .list   = {
+                               [0]     = 3 | DMA_CH_VALID,
+                               [1]     = 2 | DMA_CH_VALID,
+                               [2]     = 0 | DMA_CH_VALID,
+                       },
+               },
+               [DMACH_I2S_IN]  = {
+                       .list   = {
+                               [0]     = 1 | DMA_CH_VALID,
+                               [1]     = 2 | DMA_CH_VALID,
+                       },
+               },
+       },
+};
+
+static int __init s3c2410_dma_add(struct device *dev,
+                                 struct subsys_interface *sif)
+{
+       s3c2410_dma_init();
+       s3c24xx_dma_order_set(&s3c2410_dma_order);
+       return s3c24xx_dma_init_map(&s3c2410_dma_sel);
+}
+
+#if defined(CONFIG_CPU_S3C2410)
+static struct subsys_interface s3c2410_dma_interface = {
+       .name           = "s3c2410_dma",
+       .subsys         = &s3c2410_subsys,
+       .add_dev        = s3c2410_dma_add,
+};
+
+static int __init s3c2410_dma_drvinit(void)
+{
+       return subsys_interface_register(&s3c2410_dma_interface);
+}
+
+arch_initcall(s3c2410_dma_drvinit);
+
+static struct subsys_interface s3c2410a_dma_interface = {
+       .name           = "s3c2410a_dma",
+       .subsys         = &s3c2410a_subsys,
+       .add_dev        = s3c2410_dma_add,
+};
+
+static int __init s3c2410a_dma_drvinit(void)
+{
+       return subsys_interface_register(&s3c2410a_dma_interface);
+}
+
+arch_initcall(s3c2410a_dma_drvinit);
+#endif
+
+#if defined(CONFIG_CPU_S3C2442)
+/* S3C2442 DMA contains the same selection table as the S3C2410 */
+static struct subsys_interface s3c2442_dma_interface = {
+       .name           = "s3c2442_dma",
+       .subsys         = &s3c2442_subsys,
+       .add_dev        = s3c2410_dma_add,
+};
+
+static int __init s3c2442_dma_drvinit(void)
+{
+       return subsys_interface_register(&s3c2442_dma_interface);
+}
+
+arch_initcall(s3c2442_dma_drvinit);
+#endif
+
diff --git a/arch/arm/mach-s3c24xx/dma-s3c2412.c b/arch/arm/mach-s3c24xx/dma-s3c2412.c
new file mode 100644 (file)
index 0000000..38472ac
--- /dev/null
@@ -0,0 +1,180 @@
+/* linux/arch/arm/mach-s3c2412/dma.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2412 DMA selection
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <mach/dma.h>
+
+#include <plat/dma-s3c24xx.h>
+#include <plat/cpu.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <plat/regs-ac97.h>
+#include <plat/regs-dma.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+#include <mach/regs-sdi.h>
+#include <plat/regs-iis.h>
+#include <plat/regs-spi.h>
+
+#define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID }
+
+static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
+       [DMACH_XD0] = {
+               .name           = "xdreq0",
+               .channels       = MAP(S3C2412_DMAREQSEL_XDREQ0),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_XDREQ0),
+       },
+       [DMACH_XD1] = {
+               .name           = "xdreq1",
+               .channels       = MAP(S3C2412_DMAREQSEL_XDREQ1),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_XDREQ1),
+       },
+       [DMACH_SDI] = {
+               .name           = "sdi",
+               .channels       = MAP(S3C2412_DMAREQSEL_SDI),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_SDI),
+       },
+       [DMACH_SPI0] = {
+               .name           = "spi0",
+               .channels       = MAP(S3C2412_DMAREQSEL_SPI0TX),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_SPI0RX),
+       },
+       [DMACH_SPI1] = {
+               .name           = "spi1",
+               .channels       = MAP(S3C2412_DMAREQSEL_SPI1TX),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_SPI1RX),
+       },
+       [DMACH_UART0] = {
+               .name           = "uart0",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART0_0),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_UART0_0),
+       },
+       [DMACH_UART1] = {
+               .name           = "uart1",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART1_0),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_UART1_0),
+       },
+       [DMACH_UART2] = {
+               .name           = "uart2",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART2_0),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_UART2_0),
+       },
+       [DMACH_UART0_SRC2] = {
+               .name           = "uart0",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART0_1),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_UART0_1),
+       },
+       [DMACH_UART1_SRC2] = {
+               .name           = "uart1",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART1_1),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_UART1_1),
+       },
+       [DMACH_UART2_SRC2] = {
+               .name           = "uart2",
+               .channels       = MAP(S3C2412_DMAREQSEL_UART2_1),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_UART2_1),
+       },
+       [DMACH_TIMER] = {
+               .name           = "timer",
+               .channels       = MAP(S3C2412_DMAREQSEL_TIMER),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_TIMER),
+       },
+       [DMACH_I2S_IN] = {
+               .name           = "i2s-sdi",
+               .channels       = MAP(S3C2412_DMAREQSEL_I2SRX),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_I2SRX),
+       },
+       [DMACH_I2S_OUT] = {
+               .name           = "i2s-sdo",
+               .channels       = MAP(S3C2412_DMAREQSEL_I2STX),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_I2STX),
+       },
+       [DMACH_USB_EP1] = {
+               .name           = "usb-ep1",
+               .channels       = MAP(S3C2412_DMAREQSEL_USBEP1),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_USBEP1),
+       },
+       [DMACH_USB_EP2] = {
+               .name           = "usb-ep2",
+               .channels       = MAP(S3C2412_DMAREQSEL_USBEP2),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_USBEP2),
+       },
+       [DMACH_USB_EP3] = {
+               .name           = "usb-ep3",
+               .channels       = MAP(S3C2412_DMAREQSEL_USBEP3),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_USBEP3),
+       },
+       [DMACH_USB_EP4] = {
+               .name           = "usb-ep4",
+               .channels       = MAP(S3C2412_DMAREQSEL_USBEP4),
+               .channels_rx    = MAP(S3C2412_DMAREQSEL_USBEP4),
+       },
+};
+
+static void s3c2412_dma_direction(struct s3c2410_dma_chan *chan,
+                                 struct s3c24xx_dma_map *map,
+                                 enum dma_data_direction dir)
+{
+       unsigned long chsel;
+
+       if (dir == DMA_FROM_DEVICE)
+               chsel = map->channels_rx[0];
+       else
+               chsel = map->channels[0];
+
+       chsel &= ~DMA_CH_VALID;
+       chsel |= S3C2412_DMAREQSEL_HW;
+
+       writel(chsel, chan->regs + S3C2412_DMA_DMAREQSEL);
+}
+
+static void s3c2412_dma_select(struct s3c2410_dma_chan *chan,
+                              struct s3c24xx_dma_map *map)
+{
+       s3c2412_dma_direction(chan, map, chan->source);
+}
+
+static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = {
+       .select         = s3c2412_dma_select,
+       .direction      = s3c2412_dma_direction,
+       .dcon_mask      = 0,
+       .map            = s3c2412_dma_mappings,
+       .map_size       = ARRAY_SIZE(s3c2412_dma_mappings),
+};
+
+static int __init s3c2412_dma_add(struct device *dev,
+                                 struct subsys_interface *sif)
+{
+       s3c2410_dma_init();
+       return s3c24xx_dma_init_map(&s3c2412_dma_sel);
+}
+
+static struct subsys_interface s3c2412_dma_interface = {
+       .name           = "s3c2412_dma",
+       .subsys         = &s3c2412_subsys,
+       .add_dev        = s3c2412_dma_add,
+};
+
+static int __init s3c2412_dma_init(void)
+{
+       return subsys_interface_register(&s3c2412_dma_interface);
+}
+
+arch_initcall(s3c2412_dma_init);
diff --git a/arch/arm/mach-s3c24xx/dma-s3c2440.c b/arch/arm/mach-s3c24xx/dma-s3c2440.c
new file mode 100644 (file)
index 0000000..5f0a0c8
--- /dev/null
@@ -0,0 +1,197 @@
+/* linux/arch/arm/mach-s3c2440/dma.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2440 DMA selection
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/serial_core.h>
+
+#include <mach/map.h>
+#include <mach/dma.h>
+
+#include <plat/dma-s3c24xx.h>
+#include <plat/cpu.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <plat/regs-ac97.h>
+#include <plat/regs-dma.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+#include <mach/regs-sdi.h>
+#include <plat/regs-iis.h>
+#include <plat/regs-spi.h>
+
+static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = {
+       [DMACH_XD0] = {
+               .name           = "xdreq0",
+               .channels[0]    = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
+       },
+       [DMACH_XD1] = {
+               .name           = "xdreq1",
+               .channels[1]    = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
+       },
+       [DMACH_SDI] = {
+               .name           = "sdi",
+               .channels[0]    = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
+               .channels[1]    = S3C2440_DCON_CH1_SDI | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
+               .channels[3]    = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
+       },
+       [DMACH_SPI0] = {
+               .name           = "spi0",
+               .channels[1]    = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
+       },
+       [DMACH_SPI1] = {
+               .name           = "spi1",
+               .channels[3]    = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
+       },
+       [DMACH_UART0] = {
+               .name           = "uart0",
+               .channels[0]    = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
+       },
+       [DMACH_UART1] = {
+               .name           = "uart1",
+               .channels[1]    = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
+       },
+       [DMACH_UART2] = {
+               .name           = "uart2",
+               .channels[3]    = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
+       },
+       [DMACH_TIMER] = {
+               .name           = "timer",
+               .channels[0]    = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
+               .channels[3]    = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
+       },
+       [DMACH_I2S_IN] = {
+               .name           = "i2s-sdi",
+               .channels[1]    = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
+       },
+       [DMACH_I2S_OUT] = {
+               .name           = "i2s-sdo",
+               .channels[0]    = S3C2440_DCON_CH0_I2SSDO | DMA_CH_VALID,
+               .channels[2]    = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
+       },
+       [DMACH_PCM_IN] = {
+               .name           = "pcm-in",
+               .channels[0]    = S3C2440_DCON_CH0_PCMIN | DMA_CH_VALID,
+               .channels[2]    = S3C2440_DCON_CH2_PCMIN | DMA_CH_VALID,
+       },
+       [DMACH_PCM_OUT] = {
+               .name           = "pcm-out",
+               .channels[1]    = S3C2440_DCON_CH1_PCMOUT | DMA_CH_VALID,
+               .channels[3]    = S3C2440_DCON_CH3_PCMOUT | DMA_CH_VALID,
+       },
+       [DMACH_MIC_IN] = {
+               .name           = "mic-in",
+               .channels[2]    = S3C2440_DCON_CH2_MICIN | DMA_CH_VALID,
+               .channels[3]    = S3C2440_DCON_CH3_MICIN | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP1] = {
+               .name           = "usb-ep1",
+               .channels[0]    = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP2] = {
+               .name           = "usb-ep2",
+               .channels[1]    = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP3] = {
+               .name           = "usb-ep3",
+               .channels[2]    = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
+       },
+       [DMACH_USB_EP4] = {
+               .name           = "usb-ep4",
+               .channels[3]    = S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
+       },
+};
+
+static void s3c2440_dma_select(struct s3c2410_dma_chan *chan,
+                              struct s3c24xx_dma_map *map)
+{
+       chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
+}
+
+static struct s3c24xx_dma_selection __initdata s3c2440_dma_sel = {
+       .select         = s3c2440_dma_select,
+       .dcon_mask      = 7 << 24,
+       .map            = s3c2440_dma_mappings,
+       .map_size       = ARRAY_SIZE(s3c2440_dma_mappings),
+};
+
+static struct s3c24xx_dma_order __initdata s3c2440_dma_order = {
+       .channels       = {
+               [DMACH_SDI]     = {
+                       .list   = {
+                               [0]     = 3 | DMA_CH_VALID,
+                               [1]     = 2 | DMA_CH_VALID,
+                               [2]     = 1 | DMA_CH_VALID,
+                               [3]     = 0 | DMA_CH_VALID,
+                       },
+               },
+               [DMACH_I2S_IN]  = {
+                       .list   = {
+                               [0]     = 1 | DMA_CH_VALID,
+                               [1]     = 2 | DMA_CH_VALID,
+                       },
+               },
+               [DMACH_I2S_OUT] = {
+                       .list   = {
+                               [0]     = 2 | DMA_CH_VALID,
+                               [1]     = 1 | DMA_CH_VALID,
+                       },
+               },
+               [DMACH_PCM_IN] = {
+                       .list   = {
+                               [0]     = 2 | DMA_CH_VALID,
+                               [1]     = 1 | DMA_CH_VALID,
+                       },
+               },
+               [DMACH_PCM_OUT] = {
+                       .list   = {
+                               [0]     = 1 | DMA_CH_VALID,
+                               [1]     = 3 | DMA_CH_VALID,
+                       },
+               },
+               [DMACH_MIC_IN] = {
+                       .list   = {
+                               [0]     = 3 | DMA_CH_VALID,
+                               [1]     = 2 | DMA_CH_VALID,
+                       },
+               },
+       },
+};
+
+static int __init s3c2440_dma_add(struct device *dev,
+                                 struct subsys_interface *sif)
+{
+       s3c2410_dma_init();
+       s3c24xx_dma_order_set(&s3c2440_dma_order);
+       return s3c24xx_dma_init_map(&s3c2440_dma_sel);
+}
+
+static struct subsys_interface s3c2440_dma_interface = {
+       .name           = "s3c2440_dma",
+       .subsys         = &s3c2440_subsys,
+       .add_dev        = s3c2440_dma_add,
+};
+
+static int __init s3c2440_dma_init(void)
+{
+       return subsys_interface_register(&s3c2440_dma_interface);
+}
+
+arch_initcall(s3c2440_dma_init);
+
diff --git a/arch/arm/mach-s3c24xx/dma-s3c2443.c b/arch/arm/mach-s3c24xx/dma-s3c2443.c
new file mode 100644 (file)
index 0000000..e227c47
--- /dev/null
@@ -0,0 +1,174 @@
+/* linux/arch/arm/mach-s3c2443/dma.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2443 DMA selection
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <mach/dma.h>
+
+#include <plat/dma-s3c24xx.h>
+#include <plat/cpu.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <plat/regs-ac97.h>
+#include <plat/regs-dma.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+#include <mach/regs-sdi.h>
+#include <plat/regs-iis.h>
+#include <plat/regs-spi.h>
+
+#define MAP(x) { \
+               [0]     = (x) | DMA_CH_VALID,   \
+               [1]     = (x) | DMA_CH_VALID,   \
+               [2]     = (x) | DMA_CH_VALID,   \
+               [3]     = (x) | DMA_CH_VALID,   \
+               [4]     = (x) | DMA_CH_VALID,   \
+               [5]     = (x) | DMA_CH_VALID,   \
+       }
+
+static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = {
+       [DMACH_XD0] = {
+               .name           = "xdreq0",
+               .channels       = MAP(S3C2443_DMAREQSEL_XDREQ0),
+       },
+       [DMACH_XD1] = {
+               .name           = "xdreq1",
+               .channels       = MAP(S3C2443_DMAREQSEL_XDREQ1),
+       },
+       [DMACH_SDI] = { /* only on S3C2443 */
+               .name           = "sdi",
+               .channels       = MAP(S3C2443_DMAREQSEL_SDI),
+       },
+       [DMACH_SPI0] = {
+               .name           = "spi0",
+               .channels       = MAP(S3C2443_DMAREQSEL_SPI0TX),
+       },
+       [DMACH_SPI1] = { /* only on S3C2443/S3C2450 */
+               .name           = "spi1",
+               .channels       = MAP(S3C2443_DMAREQSEL_SPI1TX),
+       },
+       [DMACH_UART0] = {
+               .name           = "uart0",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART0_0),
+       },
+       [DMACH_UART1] = {
+               .name           = "uart1",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART1_0),
+       },
+       [DMACH_UART2] = {
+               .name           = "uart2",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART2_0),
+       },
+       [DMACH_UART3] = {
+               .name           = "uart3",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART3_0),
+       },
+       [DMACH_UART0_SRC2] = {
+               .name           = "uart0",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART0_1),
+       },
+       [DMACH_UART1_SRC2] = {
+               .name           = "uart1",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART1_1),
+       },
+       [DMACH_UART2_SRC2] = {
+               .name           = "uart2",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART2_1),
+       },
+       [DMACH_UART3_SRC2] = {
+               .name           = "uart3",
+               .channels       = MAP(S3C2443_DMAREQSEL_UART3_1),
+       },
+       [DMACH_TIMER] = {
+               .name           = "timer",
+               .channels       = MAP(S3C2443_DMAREQSEL_TIMER),
+       },
+       [DMACH_I2S_IN] = {
+               .name           = "i2s-sdi",
+               .channels       = MAP(S3C2443_DMAREQSEL_I2SRX),
+       },
+       [DMACH_I2S_OUT] = {
+               .name           = "i2s-sdo",
+               .channels       = MAP(S3C2443_DMAREQSEL_I2STX),
+       },
+       [DMACH_PCM_IN] = {
+               .name           = "pcm-in",
+               .channels       = MAP(S3C2443_DMAREQSEL_PCMIN),
+       },
+       [DMACH_PCM_OUT] = {
+               .name           = "pcm-out",
+               .channels       = MAP(S3C2443_DMAREQSEL_PCMOUT),
+       },
+       [DMACH_MIC_IN] = {
+               .name           = "mic-in",
+               .channels       = MAP(S3C2443_DMAREQSEL_MICIN),
+       },
+};
+
+static void s3c2443_dma_select(struct s3c2410_dma_chan *chan,
+                              struct s3c24xx_dma_map *map)
+{
+       writel(map->channels[0] | S3C2443_DMAREQSEL_HW,
+              chan->regs + S3C2443_DMA_DMAREQSEL);
+}
+
+static struct s3c24xx_dma_selection __initdata s3c2443_dma_sel = {
+       .select         = s3c2443_dma_select,
+       .dcon_mask      = 0,
+       .map            = s3c2443_dma_mappings,
+       .map_size       = ARRAY_SIZE(s3c2443_dma_mappings),
+};
+
+static int __init s3c2443_dma_add(struct device *dev,
+                                 struct subsys_interface *sif)
+{
+       s3c24xx_dma_init(6, IRQ_S3C2443_DMA0, 0x100);
+       return s3c24xx_dma_init_map(&s3c2443_dma_sel);
+}
+
+#ifdef CONFIG_CPU_S3C2416
+/* S3C2416 DMA contains the same selection table as the S3C2443 */
+static struct subsys_interface s3c2416_dma_interface = {
+       .name           = "s3c2416_dma",
+       .subsys         = &s3c2416_subsys,
+       .add_dev        = s3c2443_dma_add,
+};
+
+static int __init s3c2416_dma_init(void)
+{
+       return subsys_interface_register(&s3c2416_dma_interface);
+}
+
+arch_initcall(s3c2416_dma_init);
+#endif
+
+#ifdef CONFIG_CPU_S3C2443
+static struct subsys_interface s3c2443_dma_interface = {
+       .name           = "s3c2443_dma",
+       .subsys         = &s3c2443_subsys,
+       .add_dev        = s3c2443_dma_add,
+};
+
+static int __init s3c2443_dma_init(void)
+{
+       return subsys_interface_register(&s3c2443_dma_interface);
+}
+
+arch_initcall(s3c2443_dma_init);
+#endif
diff --git a/arch/arm/mach-s3c24xx/h1940-bluetooth.c b/arch/arm/mach-s3c24xx/h1940-bluetooth.c
new file mode 100644 (file)
index 0000000..a5eeb62
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * arch/arm/mach-s3c2410/h1940-bluetooth.c
+ * Copyright (c) Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ *         S3C2410 bluetooth "driver"
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/rfkill.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/hardware.h>
+#include <mach/h1940-latch.h>
+#include <mach/h1940.h>
+
+#define DRV_NAME "h1940-bt"
+
+/* Bluetooth control */
+static void h1940bt_enable(int on)
+{
+       if (on) {
+               /* Power on the chip */
+               gpio_set_value(H1940_LATCH_BLUETOOTH_POWER, 1);
+               /* Reset the chip */
+               mdelay(10);
+
+               gpio_set_value(S3C2410_GPH(1), 1);
+               mdelay(10);
+               gpio_set_value(S3C2410_GPH(1), 0);
+
+               h1940_led_blink_set(-EINVAL, GPIO_LED_BLINK, NULL, NULL);
+       }
+       else {
+               gpio_set_value(S3C2410_GPH(1), 1);
+               mdelay(10);
+               gpio_set_value(S3C2410_GPH(1), 0);
+               mdelay(10);
+               gpio_set_value(H1940_LATCH_BLUETOOTH_POWER, 0);
+
+               h1940_led_blink_set(-EINVAL, GPIO_LED_NO_BLINK_LOW, NULL, NULL);
+       }
+}
+
+static int h1940bt_set_block(void *data, bool blocked)
+{
+       h1940bt_enable(!blocked);
+       return 0;
+}
+
+static const struct rfkill_ops h1940bt_rfkill_ops = {
+       .set_block = h1940bt_set_block,
+};
+
+static int __devinit h1940bt_probe(struct platform_device *pdev)
+{
+       struct rfkill *rfk;
+       int ret = 0;
+
+       ret = gpio_request(S3C2410_GPH(1), dev_name(&pdev->dev));
+       if (ret) {
+               dev_err(&pdev->dev, "could not get GPH1\n");
+               return ret;
+       }
+
+       ret = gpio_request(H1940_LATCH_BLUETOOTH_POWER, dev_name(&pdev->dev));
+       if (ret) {
+               gpio_free(S3C2410_GPH(1));
+               dev_err(&pdev->dev, "could not get BT_POWER\n");
+               return ret;
+       }
+
+       /* Configures BT serial port GPIOs */
+       s3c_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0);
+       s3c_gpio_setpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE);
+       s3c_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT);
+       s3c_gpio_setpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE);
+       s3c_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0);
+       s3c_gpio_setpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE);
+       s3c_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0);
+       s3c_gpio_setpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE);
+
+       rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH,
+                       &h1940bt_rfkill_ops, NULL);
+       if (!rfk) {
+               ret = -ENOMEM;
+               goto err_rfk_alloc;
+       }
+
+       ret = rfkill_register(rfk);
+       if (ret)
+               goto err_rfkill;
+
+       platform_set_drvdata(pdev, rfk);
+
+       return 0;
+
+err_rfkill:
+       rfkill_destroy(rfk);
+err_rfk_alloc:
+       return ret;
+}
+
+static int h1940bt_remove(struct platform_device *pdev)
+{
+       struct rfkill *rfk = platform_get_drvdata(pdev);
+
+       platform_set_drvdata(pdev, NULL);
+       gpio_free(S3C2410_GPH(1));
+
+       if (rfk) {
+               rfkill_unregister(rfk);
+               rfkill_destroy(rfk);
+       }
+       rfk = NULL;
+
+       h1940bt_enable(0);
+
+       return 0;
+}
+
+
+static struct platform_driver h1940bt_driver = {
+       .driver         = {
+               .name   = DRV_NAME,
+       },
+       .probe          = h1940bt_probe,
+       .remove         = h1940bt_remove,
+};
+
+
+static int __init h1940bt_init(void)
+{
+       return platform_driver_register(&h1940bt_driver);
+}
+
+static void __exit h1940bt_exit(void)
+{
+       platform_driver_unregister(&h1940bt_driver);
+}
+
+module_init(h1940bt_init);
+module_exit(h1940bt_exit);
+
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_DESCRIPTION("Driver for the iPAQ H1940 bluetooth chip");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-s3c24xx/include/mach/anubis-cpld.h b/arch/arm/mach-s3c24xx/include/mach/anubis-cpld.h
new file mode 100644 (file)
index 0000000..1b614d5
--- /dev/null
@@ -0,0 +1,25 @@
+/* arch/arm/mach-s3c2410/include/mach/anubis-cpld.h
+ *
+ * Copyright (c) 2005 Simtec Electronics
+ *     http://www.simtec.co.uk/products/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * ANUBIS - CPLD control constants
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_ANUBISCPLD_H
+#define __ASM_ARCH_ANUBISCPLD_H
+
+/* CTRL2 - NAND WP control, IDE Reset assert/check */
+
+#define ANUBIS_CTRL1_NANDSEL           (0x3)
+
+/* IDREG - revision */
+
+#define ANUBIS_IDREG_REVMASK           (0x7)
+
+#endif /* __ASM_ARCH_ANUBISCPLD_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/anubis-irq.h b/arch/arm/mach-s3c24xx/include/mach/anubis-irq.h
new file mode 100644 (file)
index 0000000..a2a3281
--- /dev/null
@@ -0,0 +1,21 @@
+/* arch/arm/mach-s3c2410/include/mach/anubis-irq.h
+ *
+ * Copyright (c) 2005 Simtec Electronics
+ *     http://www.simtec.co.uk/products/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ *  ANUBIS - IRQ Number definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_ANUBISIRQ_H
+#define __ASM_ARCH_ANUBISIRQ_H
+
+#define IRQ_IDE0       IRQ_EINT2
+#define IRQ_IDE1       IRQ_EINT3
+#define IRQ_ASIX       IRQ_EINT1
+
+#endif /* __ASM_ARCH_ANUBISIRQ_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/anubis-map.h b/arch/arm/mach-s3c24xx/include/mach/anubis-map.h
new file mode 100644 (file)
index 0000000..c9deb3a
--- /dev/null
@@ -0,0 +1,38 @@
+/* arch/arm/mach-s3c2410/include/mach/anubis-map.h
+ *
+ * Copyright (c) 2005 Simtec Electronics
+ *     http://www.simtec.co.uk/products/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * ANUBIS - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* needs arch/map.h including with this */
+
+#ifndef __ASM_ARCH_ANUBISMAP_H
+#define __ASM_ARCH_ANUBISMAP_H
+
+/* start peripherals off after the S3C2410 */
+
+#define ANUBIS_IOADDR(x)       (S3C2410_ADDR((x) + 0x01800000))
+
+#define ANUBIS_PA_CPLD         (S3C2410_CS1 | (1<<26))
+
+/* we put the CPLD registers next, to get them out of the way */
+
+#define ANUBIS_VA_CTRL1            ANUBIS_IOADDR(0x00000000)    /* 0x01800000 */
+#define ANUBIS_PA_CTRL1            (ANUBIS_PA_CPLD)
+
+#define ANUBIS_VA_IDREG            ANUBIS_IOADDR(0x00300000)    /* 0x01B00000 */
+#define ANUBIS_PA_IDREG            (ANUBIS_PA_CPLD + (3<<23))
+
+#define ANUBIS_IDEPRI      ANUBIS_IOADDR(0x01000000)
+#define ANUBIS_IDEPRIAUX    ANUBIS_IOADDR(0x01100000)
+#define ANUBIS_IDESEC      ANUBIS_IOADDR(0x01200000)
+#define ANUBIS_IDESECAUX    ANUBIS_IOADDR(0x01300000)
+
+#endif /* __ASM_ARCH_ANUBISMAP_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/bast-cpld.h b/arch/arm/mach-s3c24xx/include/mach/bast-cpld.h
new file mode 100644 (file)
index 0000000..bee2a7a
--- /dev/null
@@ -0,0 +1,53 @@
+/* arch/arm/mach-s3c2410/include/mach/bast-cpld.h
+ *
+ * Copyright (c) 2003-2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * BAST - CPLD control constants
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_BASTCPLD_H
+#define __ASM_ARCH_BASTCPLD_H
+
+/* CTRL1 - Audio LR routing */
+
+#define BAST_CPLD_CTRL1_LRCOFF     (0x00)
+#define BAST_CPLD_CTRL1_LRCADC     (0x01)
+#define BAST_CPLD_CTRL1_LRCDAC     (0x02)
+#define BAST_CPLD_CTRL1_LRCARM     (0x03)
+#define BAST_CPLD_CTRL1_LRMASK     (0x03)
+
+/* CTRL2 - NAND WP control, IDE Reset assert/check */
+
+#define BAST_CPLD_CTRL2_WNAND       (0x04)
+#define BAST_CPLD_CTLR2_IDERST      (0x08)
+
+/* CTRL3 - rom write control, CPLD identity */
+
+#define BAST_CPLD_CTRL3_IDMASK      (0x0e)
+#define BAST_CPLD_CTRL3_ROMWEN      (0x01)
+
+/* CTRL4 - 8bit LCD interface control/status */
+
+#define BAST_CPLD_CTRL4_LLAT       (0x01)
+#define BAST_CPLD_CTRL4_LCDRW      (0x02)
+#define BAST_CPLD_CTRL4_LCDCMD     (0x04)
+#define BAST_CPLD_CTRL4_LCDE2      (0x01)
+
+/* CTRL5 - DMA routing */
+
+#define BAST_CPLD_DMA0_PRIIDE      (0<<0)
+#define BAST_CPLD_DMA0_SECIDE      (1<<0)
+#define BAST_CPLD_DMA0_ISA15       (2<<0)
+#define BAST_CPLD_DMA0_ISA36       (3<<0)
+
+#define BAST_CPLD_DMA1_PRIIDE      (0<<2)
+#define BAST_CPLD_DMA1_SECIDE      (1<<2)
+#define BAST_CPLD_DMA1_ISA15       (2<<2)
+#define BAST_CPLD_DMA1_ISA36       (3<<2)
+
+#endif /* __ASM_ARCH_BASTCPLD_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/bast-irq.h b/arch/arm/mach-s3c24xx/include/mach/bast-irq.h
new file mode 100644 (file)
index 0000000..cac428c
--- /dev/null
@@ -0,0 +1,29 @@
+/* arch/arm/mach-s3c2410/include/mach/bast-irq.h
+ *
+ * Copyright (c) 2003-2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Machine BAST - IRQ Number definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_BASTIRQ_H
+#define __ASM_ARCH_BASTIRQ_H
+
+/* irq numbers to onboard peripherals */
+
+#define IRQ_USBOC      IRQ_EINT18
+#define IRQ_IDE0       IRQ_EINT16
+#define IRQ_IDE1       IRQ_EINT17
+#define IRQ_PCSERIAL1  IRQ_EINT15
+#define IRQ_PCSERIAL2  IRQ_EINT14
+#define IRQ_PCPARALLEL IRQ_EINT13
+#define IRQ_ASIX       IRQ_EINT11
+#define IRQ_DM9000     IRQ_EINT10
+#define IRQ_ISA               IRQ_EINT9
+#define IRQ_SMALERT    IRQ_EINT8
+
+#endif /* __ASM_ARCH_BASTIRQ_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/bast-map.h b/arch/arm/mach-s3c24xx/include/mach/bast-map.h
new file mode 100644 (file)
index 0000000..6e7dc9d
--- /dev/null
@@ -0,0 +1,146 @@
+/* arch/arm/mach-s3c2410/include/mach/bast-map.h
+ *
+ * Copyright (c) 2003-2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Machine BAST - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* needs arch/map.h including with this */
+
+/* ok, we've used up to 0x13000000, now we need to find space for the
+ * peripherals that live in the nGCS[x] areas, which are quite numerous
+ * in their space. We also have the board's CPLD to find register space
+ * for.
+ */
+
+#ifndef __ASM_ARCH_BASTMAP_H
+#define __ASM_ARCH_BASTMAP_H
+
+#define BAST_IOADDR(x)    (S3C2410_ADDR((x) + 0x01300000))
+
+/* we put the CPLD registers next, to get them out of the way */
+
+#define BAST_VA_CTRL1      BAST_IOADDR(0x00000000)      /* 0x01300000 */
+#define BAST_PA_CTRL1      (S3C2410_CS5 | 0x7800000)
+
+#define BAST_VA_CTRL2      BAST_IOADDR(0x00100000)      /* 0x01400000 */
+#define BAST_PA_CTRL2      (S3C2410_CS1 | 0x6000000)
+
+#define BAST_VA_CTRL3      BAST_IOADDR(0x00200000)      /* 0x01500000 */
+#define BAST_PA_CTRL3      (S3C2410_CS1 | 0x6800000)
+
+#define BAST_VA_CTRL4      BAST_IOADDR(0x00300000)      /* 0x01600000 */
+#define BAST_PA_CTRL4      (S3C2410_CS1 | 0x7000000)
+
+/* next, we have the PC104 ISA interrupt registers */
+
+#define BAST_PA_PC104_IRQREQ  (S3C2410_CS5 | 0x6000000) /* 0x01700000 */
+#define BAST_VA_PC104_IRQREQ  BAST_IOADDR(0x00400000)
+
+#define BAST_PA_PC104_IRQRAW  (S3C2410_CS5 | 0x6800000) /* 0x01800000 */
+#define BAST_VA_PC104_IRQRAW  BAST_IOADDR(0x00500000)
+
+#define BAST_PA_PC104_IRQMASK (S3C2410_CS5 | 0x7000000) /* 0x01900000 */
+#define BAST_VA_PC104_IRQMASK BAST_IOADDR(0x00600000)
+
+#define BAST_PA_LCD_RCMD1     (0x8800000)
+#define BAST_VA_LCD_RCMD1     BAST_IOADDR(0x00700000)
+
+#define BAST_PA_LCD_WCMD1     (0x8000000)
+#define BAST_VA_LCD_WCMD1     BAST_IOADDR(0x00800000)
+
+#define BAST_PA_LCD_RDATA1    (0x9800000)
+#define BAST_VA_LCD_RDATA1    BAST_IOADDR(0x00900000)
+
+#define BAST_PA_LCD_WDATA1    (0x9000000)
+#define BAST_VA_LCD_WDATA1    BAST_IOADDR(0x00A00000)
+
+#define BAST_PA_LCD_RCMD2     (0xA800000)
+#define BAST_VA_LCD_RCMD2     BAST_IOADDR(0x00B00000)
+
+#define BAST_PA_LCD_WCMD2     (0xA000000)
+#define BAST_VA_LCD_WCMD2     BAST_IOADDR(0x00C00000)
+
+#define BAST_PA_LCD_RDATA2    (0xB800000)
+#define BAST_VA_LCD_RDATA2    BAST_IOADDR(0x00D00000)
+
+#define BAST_PA_LCD_WDATA2    (0xB000000)
+#define BAST_VA_LCD_WDATA2    BAST_IOADDR(0x00E00000)
+
+
+/* 0xE0000000 contains the IO space that is split by speed and
+ * wether the access is for 8 or 16bit IO... this ensures that
+ * the correct access is made
+ *
+ * 0x10000000 of space, partitioned as so:
+ *
+ * 0x00000000 to 0x04000000  8bit,  slow
+ * 0x04000000 to 0x08000000  16bit, slow
+ * 0x08000000 to 0x0C000000  16bit, net
+ * 0x0C000000 to 0x10000000  16bit, fast
+ *
+ * each of these spaces has the following in:
+ *
+ * 0x00000000 to 0x01000000 16MB ISA IO space
+ * 0x01000000 to 0x02000000 16MB ISA memory space
+ * 0x02000000 to 0x02100000 1MB  IDE primary channel
+ * 0x02100000 to 0x02200000 1MB  IDE primary channel aux
+ * 0x02200000 to 0x02400000 1MB  IDE secondary channel
+ * 0x02300000 to 0x02400000 1MB  IDE secondary channel aux
+ * 0x02400000 to 0x02500000 1MB  ASIX ethernet controller
+ * 0x02500000 to 0x02600000 1MB  Davicom DM9000 ethernet controller
+ * 0x02600000 to 0x02700000 1MB  PC SuperIO controller
+ *
+ * the phyiscal layout of the zones are:
+ *  nGCS2 - 8bit, slow
+ *  nGCS3 - 16bit, slow
+ *  nGCS4 - 16bit, net
+ *  nGCS5 - 16bit, fast
+ */
+
+#define BAST_VA_MULTISPACE (0xE0000000)
+
+#define BAST_VA_ISAIO     (BAST_VA_MULTISPACE + 0x00000000)
+#define BAST_VA_ISAMEM    (BAST_VA_MULTISPACE + 0x01000000)
+#define BAST_VA_IDEPRI    (BAST_VA_MULTISPACE + 0x02000000)
+#define BAST_VA_IDEPRIAUX  (BAST_VA_MULTISPACE + 0x02100000)
+#define BAST_VA_IDESEC    (BAST_VA_MULTISPACE + 0x02200000)
+#define BAST_VA_IDESECAUX  (BAST_VA_MULTISPACE + 0x02300000)
+#define BAST_VA_ASIXNET           (BAST_VA_MULTISPACE + 0x02400000)
+#define BAST_VA_DM9000    (BAST_VA_MULTISPACE + 0x02500000)
+#define BAST_VA_SUPERIO           (BAST_VA_MULTISPACE + 0x02600000)
+
+#define BAST_VA_MULTISPACE (0xE0000000)
+
+#define BAST_VAM_CS2 (0x00000000)
+#define BAST_VAM_CS3 (0x04000000)
+#define BAST_VAM_CS4 (0x08000000)
+#define BAST_VAM_CS5 (0x0C000000)
+
+/* physical offset addresses for the peripherals */
+
+#define BAST_PA_ISAIO    (0x00000000)
+#define BAST_PA_ASIXNET          (0x01000000)
+#define BAST_PA_SUPERIO          (0x01800000)
+#define BAST_PA_IDEPRI   (0x02000000)
+#define BAST_PA_IDEPRIAUX (0x02800000)
+#define BAST_PA_IDESEC   (0x03000000)
+#define BAST_PA_IDESECAUX (0x03800000)
+#define BAST_PA_ISAMEM   (0x04000000)
+#define BAST_PA_DM9000   (0x05000000)
+
+/* some configurations for the peripherals */
+
+#define BAST_PCSIO (BAST_VA_SUPERIO + BAST_VAM_CS2)
+/*  */
+
+#define BAST_ASIXNET_CS  BAST_VAM_CS5
+#define BAST_IDE_CS     BAST_VAM_CS5
+#define BAST_DM9000_CS  BAST_VAM_CS4
+
+#endif /* __ASM_ARCH_BASTMAP_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/bast-pmu.h b/arch/arm/mach-s3c24xx/include/mach/bast-pmu.h
new file mode 100644 (file)
index 0000000..4c38b39
--- /dev/null
@@ -0,0 +1,40 @@
+/* arch/arm/mach-s3c2410/include/mach/bast-pmu.h
+ *
+ * Copyright (c) 2003-2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *     Vincent Sanders <vince@simtec.co.uk>
+ *
+ * Machine BAST - Power Management chip
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_BASTPMU_H
+#define __ASM_ARCH_BASTPMU_H "08_OCT_2004"
+
+#define BASTPMU_REG_IDENT      (0x00)
+#define BASTPMU_REG_VERSION    (0x01)
+#define BASTPMU_REG_DDCCTRL    (0x02)
+#define BASTPMU_REG_POWER      (0x03)
+#define BASTPMU_REG_RESET      (0x04)
+#define BASTPMU_REG_GWO                (0x05)
+#define BASTPMU_REG_WOL                (0x06)
+#define BASTPMU_REG_WOR                (0x07)
+#define BASTPMU_REG_UID                (0x09)
+
+#define BASTPMU_EEPROM         (0xC0)
+
+#define BASTPMU_EEP_UID                (BASTPMU_EEPROM + 0)
+#define BASTPMU_EEP_WOL                (BASTPMU_EEPROM + 8)
+#define BASTPMU_EEP_WOR                (BASTPMU_EEPROM + 9)
+
+#define BASTPMU_IDENT_0                0x53
+#define BASTPMU_IDENT_1                0x42
+#define BASTPMU_IDENT_2                0x50
+#define BASTPMU_IDENT_3                0x4d
+
+#define BASTPMU_RESET_GUARD    (0x55)
+
+#endif /* __ASM_ARCH_BASTPMU_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/debug-macro.S b/arch/arm/mach-s3c24xx/include/mach/debug-macro.S
new file mode 100644 (file)
index 0000000..4135de8
--- /dev/null
@@ -0,0 +1,101 @@
+/* arch/arm/mach-s3c2410/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Copyright (C) 2005 Simtec Electronics
+ *
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+#include <plat/regs-serial.h>
+
+#define S3C2410_UART1_OFF (0x4000)
+#define SHIFT_2440TXF (14-9)
+
+       .macro addruart, rp, rv, tmp
+               ldr     \rp, = S3C24XX_PA_UART
+               ldr     \rv, = S3C24XX_VA_UART
+#if CONFIG_DEBUG_S3C_UART != 0
+               add     \rp, \rp, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART)
+               add     \rv, \rv, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART)
+#endif
+       .endm
+
+       .macro fifo_full_s3c24xx rd, rx
+               @ check for arm920 vs arm926. currently assume all arm926
+               @ devices have an 64 byte FIFO identical to the s3c2440
+               mrc     p15, 0, \rd, c0, c0
+               and     \rd, \rd, #0xff0
+               teq     \rd, #0x260
+               beq     1004f
+               mrc     p15, 0, \rd, c1, c0
+               tst     \rd, #1
+               addeq   \rd, \rx, #(S3C24XX_PA_GPIO - S3C24XX_PA_UART)
+               addne   \rd, \rx, #(S3C24XX_VA_GPIO - S3C24XX_VA_UART)
+               bic     \rd, \rd, #0xff000
+               ldr     \rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ]
+               and     \rd, \rd, #0x00ff0000
+               teq     \rd, #0x00440000                @ is it 2440?
+1004:
+               ldr     \rd, [ \rx, # S3C2410_UFSTAT ]
+               moveq   \rd, \rd, lsr #SHIFT_2440TXF
+               tst     \rd, #S3C2410_UFSTAT_TXFULL
+       .endm
+
+       .macro  fifo_full_s3c2410 rd, rx
+               ldr     \rd, [ \rx, # S3C2410_UFSTAT ]
+               tst     \rd, #S3C2410_UFSTAT_TXFULL
+       .endm
+
+/* fifo level reading */
+
+       .macro fifo_level_s3c24xx rd, rx
+               @ check for arm920 vs arm926. currently assume all arm926
+               @ devices have an 64 byte FIFO identical to the s3c2440
+               mrc     p15, 0, \rd, c0, c0
+               and     \rd, \rd, #0xff0
+               teq     \rd, #0x260
+               beq     10000f
+               mrc     p15, 0, \rd, c1, c0
+               tst     \rd, #1
+               addeq   \rd, \rx, #(S3C24XX_PA_GPIO - S3C24XX_PA_UART)
+               addne   \rd, \rx, #(S3C24XX_VA_GPIO - S3C24XX_VA_UART)
+               bic     \rd, \rd, #0xff000
+               ldr     \rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ]
+               and     \rd, \rd, #0x00ff0000
+               teq     \rd, #0x00440000                @ is it 2440?
+
+10000:
+               ldr     \rd, [ \rx, # S3C2410_UFSTAT ]
+               andne   \rd, \rd, #S3C2410_UFSTAT_TXMASK
+               andeq   \rd, \rd, #S3C2440_UFSTAT_TXMASK
+       .endm
+
+       .macro fifo_level_s3c2410 rd, rx
+               ldr     \rd, [ \rx, # S3C2410_UFSTAT ]
+               and     \rd, \rd, #S3C2410_UFSTAT_TXMASK
+       .endm
+
+/* Select the correct implementation depending on the configuration. The
+ * S3C2440 will get selected by default, as these are the most widely
+ * used variants of these
+*/
+
+#if defined(CONFIG_CPU_LLSERIAL_S3C2410_ONLY)
+#define fifo_full  fifo_full_s3c2410
+#define fifo_level fifo_level_s3c2410
+#elif !defined(CONFIG_CPU_LLSERIAL_S3C2440_ONLY)
+#define fifo_full  fifo_full_s3c24xx
+#define fifo_level fifo_level_s3c24xx
+#endif
+
+/* include the reset of the code which will do the work */
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s3c24xx/include/mach/dma.h b/arch/arm/mach-s3c24xx/include/mach/dma.h
new file mode 100644 (file)
index 0000000..acbdfec
--- /dev/null
@@ -0,0 +1,210 @@
+/* arch/arm/mach-s3c2410/include/mach/dma.h
+ *
+ * Copyright (C) 2003-2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C24XX DMA support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H __FILE__
+
+#include <linux/device.h>
+
+#define MAX_DMA_TRANSFER_SIZE   0x100000 /* Data Unit is half word  */
+
+/* We use `virtual` dma channels to hide the fact we have only a limited
+ * number of DMA channels, and not of all of them (dependent on the device)
+ * can be attached to any DMA source. We therefore let the DMA core handle
+ * the allocation of hardware channels to clients.
+*/
+
+enum dma_ch {
+       DMACH_XD0,
+       DMACH_XD1,
+       DMACH_SDI,
+       DMACH_SPI0,
+       DMACH_SPI1,
+       DMACH_UART0,
+       DMACH_UART1,
+       DMACH_UART2,
+       DMACH_TIMER,
+       DMACH_I2S_IN,
+       DMACH_I2S_OUT,
+       DMACH_PCM_IN,
+       DMACH_PCM_OUT,
+       DMACH_MIC_IN,
+       DMACH_USB_EP1,
+       DMACH_USB_EP2,
+       DMACH_USB_EP3,
+       DMACH_USB_EP4,
+       DMACH_UART0_SRC2,       /* s3c2412 second uart sources */
+       DMACH_UART1_SRC2,
+       DMACH_UART2_SRC2,
+       DMACH_UART3,            /* s3c2443 has extra uart */
+       DMACH_UART3_SRC2,
+       DMACH_MAX,              /* the end entry */
+};
+
+static inline bool samsung_dma_has_circular(void)
+{
+       return false;
+}
+
+static inline bool samsung_dma_is_dmadev(void)
+{
+       return false;
+}
+
+#include <plat/dma.h>
+
+#define DMACH_LOW_LEVEL        (1<<28) /* use this to specifiy hardware ch no */
+
+/* we have 4 dma channels */
+#if !defined(CONFIG_CPU_S3C2443) && !defined(CONFIG_CPU_S3C2416)
+#define S3C_DMA_CHANNELS               (4)
+#else
+#define S3C_DMA_CHANNELS               (6)
+#endif
+
+/* types */
+
+enum s3c2410_dma_state {
+       S3C2410_DMA_IDLE,
+       S3C2410_DMA_RUNNING,
+       S3C2410_DMA_PAUSED
+};
+
+/* enum s3c2410_dma_loadst
+ *
+ * This represents the state of the DMA engine, wrt to the loaded / running
+ * transfers. Since we don't have any way of knowing exactly the state of
+ * the DMA transfers, we need to know the state to make decisions on wether
+ * we can
+ *
+ * S3C2410_DMA_NONE
+ *
+ * There are no buffers loaded (the channel should be inactive)
+ *
+ * S3C2410_DMA_1LOADED
+ *
+ * There is one buffer loaded, however it has not been confirmed to be
+ * loaded by the DMA engine. This may be because the channel is not
+ * yet running, or the DMA driver decided that it was too costly to
+ * sit and wait for it to happen.
+ *
+ * S3C2410_DMA_1RUNNING
+ *
+ * The buffer has been confirmed running, and not finisged
+ *
+ * S3C2410_DMA_1LOADED_1RUNNING
+ *
+ * There is a buffer waiting to be loaded by the DMA engine, and one
+ * currently running.
+*/
+
+enum s3c2410_dma_loadst {
+       S3C2410_DMALOAD_NONE,
+       S3C2410_DMALOAD_1LOADED,
+       S3C2410_DMALOAD_1RUNNING,
+       S3C2410_DMALOAD_1LOADED_1RUNNING,
+};
+
+
+/* flags */
+
+#define S3C2410_DMAF_SLOW         (1<<0)   /* slow, so don't worry about
+                                           * waiting for reloads */
+#define S3C2410_DMAF_AUTOSTART    (1<<1)   /* auto-start if buffer queued */
+
+#define S3C2410_DMAF_CIRCULAR  (1 << 2)        /* no circular dma support */
+
+/* dma buffer */
+
+struct s3c2410_dma_buf;
+
+/* s3c2410_dma_buf
+ *
+ * internally used buffer structure to describe a queued or running
+ * buffer.
+*/
+
+struct s3c2410_dma_buf {
+       struct s3c2410_dma_buf  *next;
+       int                      magic;         /* magic */
+       int                      size;          /* buffer size in bytes */
+       dma_addr_t               data;          /* start of DMA data */
+       dma_addr_t               ptr;           /* where the DMA got to [1] */
+       void                    *id;            /* client's id */
+};
+
+/* [1] is this updated for both recv/send modes? */
+
+struct s3c2410_dma_stats {
+       unsigned long           loads;
+       unsigned long           timeout_longest;
+       unsigned long           timeout_shortest;
+       unsigned long           timeout_avg;
+       unsigned long           timeout_failed;
+};
+
+struct s3c2410_dma_map;
+
+/* struct s3c2410_dma_chan
+ *
+ * full state information for each DMA channel
+*/
+
+struct s3c2410_dma_chan {
+       /* channel state flags and information */
+       unsigned char            number;      /* number of this dma channel */
+       unsigned char            in_use;      /* channel allocated */
+       unsigned char            irq_claimed; /* irq claimed for channel */
+       unsigned char            irq_enabled; /* irq enabled for channel */
+       unsigned char            xfer_unit;   /* size of an transfer */
+
+       /* channel state */
+
+       enum s3c2410_dma_state   state;
+       enum s3c2410_dma_loadst  load_state;
+       struct s3c2410_dma_client *client;
+
+       /* channel configuration */
+       enum dma_data_direction  source;
+       enum dma_ch              req_ch;
+       unsigned long            dev_addr;
+       unsigned long            load_timeout;
+       unsigned int             flags;         /* channel flags */
+
+       struct s3c24xx_dma_map  *map;           /* channel hw maps */
+
+       /* channel's hardware position and configuration */
+       void __iomem            *regs;          /* channels registers */
+       void __iomem            *addr_reg;      /* data address register */
+       unsigned int             irq;           /* channel irq */
+       unsigned long            dcon;          /* default value of DCON */
+
+       /* driver handles */
+       s3c2410_dma_cbfn_t       callback_fn;   /* buffer done callback */
+       s3c2410_dma_opfn_t       op_fn;         /* channel op callback */
+
+       /* stats gathering */
+       struct s3c2410_dma_stats *stats;
+       struct s3c2410_dma_stats  stats_store;
+
+       /* buffer list and information */
+       struct s3c2410_dma_buf  *curr;          /* current dma buffer */
+       struct s3c2410_dma_buf  *next;          /* next buffer to load */
+       struct s3c2410_dma_buf  *end;           /* end of queue */
+
+       /* system device */
+       struct device   dev;
+};
+
+typedef unsigned long dma_device_t;
+
+#endif /* __ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/entry-macro.S b/arch/arm/mach-s3c24xx/include/mach/entry-macro.S
new file mode 100644 (file)
index 0000000..7615a14
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * arch/arm/mach-s3c2410/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for S3C2410-based platforms
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+*/
+
+/* We have a problem that the INTOFFSET register does not always
+ * show one interrupt. Occasionally we get two interrupts through
+ * the prioritiser, and this causes the INTOFFSET register to show
+ * what looks like the logical-or of the two interrupt numbers.
+ *
+ * Thanks to Klaus, Shannon, et al for helping to debug this problem
+*/
+
+#define INTPND         (0x10)
+#define INTOFFSET      (0x14)
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+       .macro  get_irqnr_preamble, base, tmp
+       .endm
+
+       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+               mov     \base, #S3C24XX_VA_IRQ
+
+               @@ try the interrupt offset register, since it is there
+
+               ldr     \irqstat, [ \base, #INTPND ]
+               teq     \irqstat, #0
+               beq     1002f
+               ldr     \irqnr, [ \base, #INTOFFSET ]
+               mov     \tmp, #1
+               tst     \irqstat, \tmp, lsl \irqnr
+               bne     1001f
+
+               @@ the number specified is not a valid irq, so try
+               @@ and work it out for ourselves
+
+               mov     \irqnr, #0              @@ start here
+
+               @@ work out which irq (if any) we got
+
+               movs    \tmp, \irqstat, lsl#16
+               addeq   \irqnr, \irqnr, #16
+               moveq   \irqstat, \irqstat, lsr#16
+               tst     \irqstat, #0xff
+               addeq   \irqnr, \irqnr, #8
+               moveq   \irqstat, \irqstat, lsr#8
+               tst     \irqstat, #0xf
+               addeq   \irqnr, \irqnr, #4
+               moveq   \irqstat, \irqstat, lsr#4
+               tst     \irqstat, #0x3
+               addeq   \irqnr, \irqnr, #2
+               moveq   \irqstat, \irqstat, lsr#2
+               tst     \irqstat, #0x1
+               addeq   \irqnr, \irqnr, #1
+
+               @@ we have the value
+1001:
+               adds    \irqnr, \irqnr, #IRQ_EINT0
+1002:
+               @@ exit here, Z flag unset if IRQ
+
+       .endm
diff --git a/arch/arm/mach-s3c24xx/include/mach/fb.h b/arch/arm/mach-s3c24xx/include/mach/fb.h
new file mode 100644 (file)
index 0000000..a957bc8
--- /dev/null
@@ -0,0 +1 @@
+#include <plat/fb-s3c2410.h>
diff --git a/arch/arm/mach-s3c24xx/include/mach/gpio-fns.h b/arch/arm/mach-s3c24xx/include/mach/gpio-fns.h
new file mode 100644 (file)
index 0000000..c53ad34
--- /dev/null
@@ -0,0 +1 @@
+#include <plat/gpio-fns.h>
diff --git a/arch/arm/mach-s3c24xx/include/mach/gpio-nrs.h b/arch/arm/mach-s3c24xx/include/mach/gpio-nrs.h
new file mode 100644 (file)
index 0000000..019ea86
--- /dev/null
@@ -0,0 +1,118 @@
+/* arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - GPIO bank numbering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __MACH_GPIONRS_H
+#define __MACH_GPIONRS_H
+
+#define S3C2410_GPIONO(bank,offset) ((bank) + (offset))
+
+#define S3C2410_GPIO_BANKG   (32*6)
+#define S3C2410_GPIO_BANKH   (32*7)
+
+/* GPIO sizes for various SoCs:
+ *
+ *             2442
+ *   2410 2412 2440 2443 2416
+ *   ---- ---- ---- ---- ----
+ * A 23   22   25   16   25
+ * B 11   11   11   11   9
+ * C 16   15   16   16   16
+ * D 16   16   16   16   16
+ * E 16   16   16   16   16
+ * F 8    8    8    8    8
+ * G 16   16   16   16   8
+ * H 11   11   9    15   15
+ * J --   --   13   16   --
+ * K --   --   --   --   16
+ * L --   --   --   15   7
+ * M --   --   --   2    2
+ */
+
+/* GPIO bank sizes */
+#define S3C2410_GPIO_A_NR      (32)
+#define S3C2410_GPIO_B_NR      (32)
+#define S3C2410_GPIO_C_NR      (32)
+#define S3C2410_GPIO_D_NR      (32)
+#define S3C2410_GPIO_E_NR      (32)
+#define S3C2410_GPIO_F_NR      (32)
+#define S3C2410_GPIO_G_NR      (32)
+#define S3C2410_GPIO_H_NR      (32)
+#define S3C2410_GPIO_J_NR      (32)    /* technically 16. */
+#define S3C2410_GPIO_K_NR      (32)    /* technically 16. */
+#define S3C2410_GPIO_L_NR      (32)    /* technically 15. */
+#define S3C2410_GPIO_M_NR      (32)    /* technically 2. */
+
+#if CONFIG_S3C_GPIO_SPACE != 0
+#error CONFIG_S3C_GPIO_SPACE cannot be nonzero at the moment
+#endif
+
+#define S3C2410_GPIO_NEXT(__gpio) \
+       ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 0)
+
+#ifndef __ASSEMBLY__
+
+enum s3c_gpio_number {
+       S3C2410_GPIO_A_START = 0,
+       S3C2410_GPIO_B_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_A),
+       S3C2410_GPIO_C_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_B),
+       S3C2410_GPIO_D_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_C),
+       S3C2410_GPIO_E_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_D),
+       S3C2410_GPIO_F_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_E),
+       S3C2410_GPIO_G_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_F),
+       S3C2410_GPIO_H_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_G),
+       S3C2410_GPIO_J_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_H),
+       S3C2410_GPIO_K_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_J),
+       S3C2410_GPIO_L_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_K),
+       S3C2410_GPIO_M_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_L),
+};
+
+#endif /* __ASSEMBLY__ */
+
+/* S3C2410 GPIO number definitions. */
+
+#define S3C2410_GPA(_nr)       (S3C2410_GPIO_A_START + (_nr))
+#define S3C2410_GPB(_nr)       (S3C2410_GPIO_B_START + (_nr))
+#define S3C2410_GPC(_nr)       (S3C2410_GPIO_C_START + (_nr))
+#define S3C2410_GPD(_nr)       (S3C2410_GPIO_D_START + (_nr))
+#define S3C2410_GPE(_nr)       (S3C2410_GPIO_E_START + (_nr))
+#define S3C2410_GPF(_nr)       (S3C2410_GPIO_F_START + (_nr))
+#define S3C2410_GPG(_nr)       (S3C2410_GPIO_G_START + (_nr))
+#define S3C2410_GPH(_nr)       (S3C2410_GPIO_H_START + (_nr))
+#define S3C2410_GPJ(_nr)       (S3C2410_GPIO_J_START + (_nr))
+#define S3C2410_GPK(_nr)       (S3C2410_GPIO_K_START + (_nr))
+#define S3C2410_GPL(_nr)       (S3C2410_GPIO_L_START + (_nr))
+#define S3C2410_GPM(_nr)       (S3C2410_GPIO_M_START + (_nr))
+
+/* compatibility until drivers can be modified */
+
+#define S3C2410_GPA0   S3C2410_GPA(0)
+#define S3C2410_GPA1   S3C2410_GPA(1)
+#define S3C2410_GPA3   S3C2410_GPA(3)
+#define S3C2410_GPA7   S3C2410_GPA(7)
+
+#define S3C2410_GPE0   S3C2410_GPE(0)
+#define S3C2410_GPE1   S3C2410_GPE(1)
+#define S3C2410_GPE2   S3C2410_GPE(2)
+#define S3C2410_GPE3   S3C2410_GPE(3)
+#define S3C2410_GPE4   S3C2410_GPE(4)
+#define S3C2410_GPE5   S3C2410_GPE(5)
+#define S3C2410_GPE6   S3C2410_GPE(6)
+#define S3C2410_GPE7   S3C2410_GPE(7)
+#define S3C2410_GPE8   S3C2410_GPE(8)
+#define S3C2410_GPE9   S3C2410_GPE(9)
+#define S3C2410_GPE10  S3C2410_GPE(10)
+
+#define S3C2410_GPH10  S3C2410_GPH(10)
+
+#endif /* __MACH_GPIONRS_H */
+
diff --git a/arch/arm/mach-s3c24xx/include/mach/gpio-track.h b/arch/arm/mach-s3c24xx/include/mach/gpio-track.h
new file mode 100644 (file)
index 0000000..c410a07
--- /dev/null
@@ -0,0 +1,33 @@
+/* arch/arm/mach-s3c24100/include/mach/gpio-core.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C2410 - GPIO core support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_CORE_H
+#define __ASM_ARCH_GPIO_CORE_H __FILE__
+
+#include <mach/regs-gpio.h>
+
+extern struct samsung_gpio_chip s3c24xx_gpios[];
+
+static inline struct samsung_gpio_chip *samsung_gpiolib_getchip(unsigned int pin)
+{
+       struct samsung_gpio_chip *chip;
+
+       if (pin > S3C_GPIO_END)
+               return NULL;
+
+       chip = &s3c24xx_gpios[pin/32];
+       return ((pin - chip->chip.base) < chip->chip.ngpio) ? chip : NULL;
+}
+
+#endif /* __ASM_ARCH_GPIO_CORE_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/gpio.h b/arch/arm/mach-s3c24xx/include/mach/gpio.h
new file mode 100644 (file)
index 0000000..6fac70f
--- /dev/null
@@ -0,0 +1,35 @@
+/* arch/arm/mach-s3c2410/include/mach/gpio.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - GPIO lib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* some boards require extra gpio capacity to support external
+ * devices that need GPIO.
+ */
+
+#ifdef CONFIG_CPU_S3C244X
+#define ARCH_NR_GPIOS  (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA)
+#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
+#define ARCH_NR_GPIOS  (32 * 12 + CONFIG_S3C24XX_GPIO_EXTRA)
+#else
+#define ARCH_NR_GPIOS  (256 + CONFIG_S3C24XX_GPIO_EXTRA)
+#endif
+
+#include <mach/gpio-nrs.h>
+#include <mach/gpio-fns.h>
+
+#ifdef CONFIG_CPU_S3C244X
+#define S3C_GPIO_END   (S3C2410_GPJ(0) + 32)
+#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
+#define S3C_GPIO_END   (S3C2410_GPM(0) + 32)
+#else
+#define S3C_GPIO_END   (S3C2410_GPH(0) + 32)
+#endif
diff --git a/arch/arm/mach-s3c24xx/include/mach/gta02.h b/arch/arm/mach-s3c24xx/include/mach/gta02.h
new file mode 100644 (file)
index 0000000..3a56a22
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef _GTA02_H
+#define _GTA02_H
+
+#include <mach/regs-gpio.h>
+
+/* Different hardware revisions, passed in ATAG_REVISION by u-boot */
+#define GTA02v1_SYSTEM_REV     0x00000310
+#define GTA02v2_SYSTEM_REV     0x00000320
+#define GTA02v3_SYSTEM_REV     0x00000330
+#define GTA02v4_SYSTEM_REV     0x00000340
+#define GTA02v5_SYSTEM_REV     0x00000350
+/* since A7 is basically same as A6, we use A6 PCB ID */
+#define GTA02v6_SYSTEM_REV     0x00000360
+
+#define GTA02_GPIO_n3DL_GSM    S3C2410_GPA(13) /* v1 + v2 + v3 only */
+
+#define GTA02_GPIO_PWR_LED1    S3C2410_GPB(0)
+#define GTA02_GPIO_PWR_LED2    S3C2410_GPB(1)
+#define GTA02_GPIO_AUX_LED     S3C2410_GPB(2)
+#define GTA02_GPIO_VIBRATOR_ON S3C2410_GPB(3)
+#define GTA02_GPIO_MODEM_RST   S3C2410_GPB(5)
+#define GTA02_GPIO_BT_EN       S3C2410_GPB(6)
+#define GTA02_GPIO_MODEM_ON    S3C2410_GPB(7)
+#define GTA02_GPIO_EXTINT8     S3C2410_GPB(8)
+#define GTA02_GPIO_USB_PULLUP  S3C2410_GPB(9)
+
+#define GTA02_GPIO_PIO5                S3C2410_GPC(5)  /* v3 + v4 only */
+
+#define GTA02v3_GPIO_nG1_CS    S3C2410_GPD(12) /* v3 + v4 only */
+#define GTA02v3_GPIO_nG2_CS    S3C2410_GPD(13) /* v3 + v4 only */
+#define GTA02v5_GPIO_HDQ       S3C2410_GPD(14)   /* v5 + */
+
+#define GTA02_GPIO_nG1_INT     S3C2410_GPF(0)
+#define GTA02_GPIO_IO1         S3C2410_GPF(1)
+#define GTA02_GPIO_PIO_2       S3C2410_GPF(2)  /* v2 + v3 + v4 only */
+#define GTA02_GPIO_JACK_INSERT S3C2410_GPF(4)
+#define GTA02_GPIO_WLAN_GPIO1  S3C2410_GPF(5)  /* v2 + v3 + v4 only */
+#define GTA02_GPIO_AUX_KEY     S3C2410_GPF(6)
+#define GTA02_GPIO_HOLD_KEY    S3C2410_GPF(7)
+
+#define GTA02_GPIO_3D_IRQ      S3C2410_GPG(4)
+#define GTA02v2_GPIO_nG2_INT   S3C2410_GPG(8)  /* v2 + v3 + v4 only */
+#define GTA02v3_GPIO_nUSB_OC   S3C2410_GPG(9)  /* v3 + v4 only */
+#define GTA02v3_GPIO_nUSB_FLT  S3C2410_GPG(10) /* v3 + v4 only */
+#define GTA02v3_GPIO_nGSM_OC   S3C2410_GPG(11) /* v3 + v4 only */
+
+#define GTA02_GPIO_AMP_SHUT    S3C2410_GPJ(1)  /* v2 + v3 + v4 only */
+#define GTA02v1_GPIO_WLAN_GPIO10       S3C2410_GPJ(2)
+#define GTA02_GPIO_HP_IN       S3C2410_GPJ(2)  /* v2 + v3 + v4 only */
+#define GTA02_GPIO_INT0                S3C2410_GPJ(3)  /* v2 + v3 + v4 only */
+#define GTA02_GPIO_nGSM_EN     S3C2410_GPJ(4)
+#define GTA02_GPIO_3D_RESET    S3C2410_GPJ(5)
+#define GTA02_GPIO_nDL_GSM     S3C2410_GPJ(6)  /* v4 + v5 only */
+#define GTA02_GPIO_WLAN_GPIO0  S3C2410_GPJ(7)
+#define GTA02v1_GPIO_BAT_ID    S3C2410_GPJ(8)
+#define GTA02_GPIO_KEEPACT     S3C2410_GPJ(8)
+#define GTA02v1_GPIO_HP_IN     S3C2410_GPJ(10)
+#define GTA02_CHIP_PWD         S3C2410_GPJ(11) /* v2 + v3 + v4 only */
+#define GTA02_GPIO_nWLAN_RESET S3C2410_GPJ(12) /* v2 + v3 + v4 only */
+
+#define GTA02_IRQ_GSENSOR_1    IRQ_EINT0
+#define GTA02_IRQ_MODEM                IRQ_EINT1
+#define GTA02_IRQ_PIO_2                IRQ_EINT2       /* v2 + v3 + v4 only */
+#define GTA02_IRQ_nJACK_INSERT IRQ_EINT4
+#define GTA02_IRQ_WLAN_GPIO1   IRQ_EINT5
+#define GTA02_IRQ_AUX          IRQ_EINT6
+#define GTA02_IRQ_nHOLD                IRQ_EINT7
+#define GTA02_IRQ_PCF50633     IRQ_EINT9
+#define GTA02_IRQ_3D           IRQ_EINT12
+#define GTA02_IRQ_GSENSOR_2    IRQ_EINT16      /* v2 + v3 + v4 only */
+#define GTA02v3_IRQ_nUSB_OC    IRQ_EINT17      /* v3 + v4 only */
+#define GTA02v3_IRQ_nUSB_FLT   IRQ_EINT18      /* v3 + v4 only */
+#define GTA02v3_IRQ_nGSM_OC    IRQ_EINT19      /* v3 + v4 only */
+
+/* returns 00 000 on GTA02 A5 and earlier, A6 returns 01 001 */
+#define GTA02_PCB_ID1_0                S3C2410_GPC(13)
+#define GTA02_PCB_ID1_1                S3C2410_GPC(15)
+#define GTA02_PCB_ID1_2                S3C2410_GPD(0)
+#define GTA02_PCB_ID2_0                S3C2410_GPD(3)
+#define GTA02_PCB_ID2_1                S3C2410_GPD(4)
+
+int gta02_get_pcb_revision(void);
+
+#endif /* _GTA02_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/h1940-latch.h b/arch/arm/mach-s3c24xx/include/mach/h1940-latch.h
new file mode 100644 (file)
index 0000000..fc897d3
--- /dev/null
@@ -0,0 +1,43 @@
+/* arch/arm/mach-s3c2410/include/mach/h1940-latch.h
+ *
+ * Copyright (c) 2005 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ *  iPAQ H1940 series - latch definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_H1940_LATCH_H
+#define __ASM_ARCH_H1940_LATCH_H
+
+#include <asm/gpio.h>
+
+#define H1940_LATCH_GPIO(x)            (S3C_GPIO_END + (x))
+
+/* SD layer latch */
+
+#define H1940_LATCH_LCD_P0             H1940_LATCH_GPIO(0)
+#define H1940_LATCH_LCD_P1             H1940_LATCH_GPIO(1)
+#define H1940_LATCH_LCD_P2             H1940_LATCH_GPIO(2)
+#define H1940_LATCH_LCD_P3             H1940_LATCH_GPIO(3)
+#define H1940_LATCH_MAX1698_nSHUTDOWN  H1940_LATCH_GPIO(4)
+#define H1940_LATCH_LED_RED            H1940_LATCH_GPIO(5)
+#define H1940_LATCH_SDQ7               H1940_LATCH_GPIO(6)
+#define H1940_LATCH_USB_DP             H1940_LATCH_GPIO(7)
+
+/* CPU layer latch */
+
+#define H1940_LATCH_UDA_POWER          H1940_LATCH_GPIO(8)
+#define H1940_LATCH_AUDIO_POWER                H1940_LATCH_GPIO(9)
+#define H1940_LATCH_SM803_ENABLE       H1940_LATCH_GPIO(10)
+#define H1940_LATCH_LCD_P4             H1940_LATCH_GPIO(11)
+#define H1940_LATCH_SD_POWER           H1940_LATCH_GPIO(12)
+#define H1940_LATCH_BLUETOOTH_POWER    H1940_LATCH_GPIO(13)
+#define H1940_LATCH_LED_GREEN          H1940_LATCH_GPIO(14)
+#define H1940_LATCH_LED_FLASH          H1940_LATCH_GPIO(15)
+
+#endif /* __ASM_ARCH_H1940_LATCH_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/h1940.h b/arch/arm/mach-s3c24xx/include/mach/h1940.h
new file mode 100644 (file)
index 0000000..2aa683c
--- /dev/null
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s3c2410/include/mach/h1940.h
+ *
+ * Copyright 2006 Ben Dooks <ben-linux@fluff.org>
+ *
+ * H1940 definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_H1940_H
+#define __ASM_ARCH_H1940_H
+
+#define H1940_SUSPEND_CHECKSUM         (0x30003ff8)
+#define H1940_SUSPEND_RESUMEAT         (0x30081000)
+#define H1940_SUSPEND_CHECK            (0x30080000)
+
+extern void h1940_pm_return(void);
+extern int h1940_led_blink_set(unsigned gpio, int state,
+       unsigned long *delay_on, unsigned long *delay_off);
+
+
+#endif /* __ASM_ARCH_H1940_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/hardware.h b/arch/arm/mach-s3c24xx/include/mach/hardware.h
new file mode 100644 (file)
index 0000000..aef5631
--- /dev/null
@@ -0,0 +1,42 @@
+/* arch/arm/mach-s3c2410/include/mach/hardware.h
+ *
+ * Copyright (c) 2003 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - hardware
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#ifndef __ASSEMBLY__
+
+extern unsigned int s3c2410_modify_misccr(unsigned int clr, unsigned int chg);
+
+#ifdef CONFIG_CPU_S3C2440
+
+extern int s3c2440_set_dsc(unsigned int pin, unsigned int value);
+
+#endif /* CONFIG_CPU_S3C2440 */
+
+#ifdef CONFIG_CPU_S3C2412
+
+extern int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state);
+
+#endif /* CONFIG_CPU_S3C2412 */
+
+#endif /* __ASSEMBLY__ */
+
+#include <asm/sizes.h>
+#include <mach/map.h>
+
+/* machine specific hardware definitions should go after this */
+
+/* currently here until moved into config (todo) */
+#define CONFIG_NO_MULTIWORD_IO
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/idle.h b/arch/arm/mach-s3c24xx/include/mach/idle.h
new file mode 100644 (file)
index 0000000..e9ddd70
--- /dev/null
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s3c2410/include/mach/idle.h
+ *
+ * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
+ *             http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 CPU Idle controls
+*/
+
+#ifndef __ASM_ARCH_IDLE_H
+#define __ASM_ARCH_IDLE_H __FILE__
+
+/* This allows the over-ride of the default idle code, in case there
+ * is any other things to be done over idle (like DVS)
+*/
+
+extern void (*s3c24xx_idle)(void);
+
+extern void s3c24xx_default_idle(void);
+
+#endif /* __ASM_ARCH_IDLE_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/io.h b/arch/arm/mach-s3c24xx/include/mach/io.h
new file mode 100644 (file)
index 0000000..118749f
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * arch/arm/mach-s3c2410/include/mach/io.h
+ *  from arch/arm/mach-rpc/include/mach/io.h
+ *
+ * Copyright (C) 1997 Russell King
+ *          (C) 2003 Simtec Electronics
+*/
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#include <mach/hardware.h>
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We use two different types of addressing - PC style addresses, and ARM
+ * addresses.  PC style accesses the PC hardware with the normal PC IO
+ * addresses, eg 0x3f8 for serial#1.  ARM addresses are above A28
+ * and are translated to the start of IO.  Note that all addresses are
+ * not shifted left!
+ */
+
+#define __PORT_PCIO(x) ((x) < (1<<28))
+
+#define PCIO_BASE       (S3C24XX_VA_ISA_WORD)
+#define PCIO_BASE_b     (S3C24XX_VA_ISA_BYTE)
+#define PCIO_BASE_w     (S3C24XX_VA_ISA_WORD)
+#define PCIO_BASE_l     (S3C24XX_VA_ISA_WORD)
+/*
+ * Dynamic IO functions - let the compiler
+ * optimize the expressions
+ */
+
+#define DECLARE_DYN_OUT(sz,fnsuffix,instr) \
+static inline void __out##fnsuffix (unsigned int val, unsigned int port) \
+{ \
+       unsigned long temp;                                   \
+       __asm__ __volatile__(                                 \
+       "cmp    %2, #(1<<28)\n\t"                             \
+       "mov    %0, %2\n\t"                                   \
+       "addcc  %0, %0, %3\n\t"                               \
+       "str" instr " %1, [%0, #0 ]     @ out" #fnsuffix      \
+       : "=&r" (temp)                                        \
+       : "r" (val), "r" (port), "Ir" (PCIO_BASE_##fnsuffix)  \
+       : "cc");                                              \
+}
+
+
+#define DECLARE_DYN_IN(sz,fnsuffix,instr)                              \
+static inline unsigned sz __in##fnsuffix (unsigned int port)           \
+{                                                                      \
+       unsigned long temp, value;                                      \
+       __asm__ __volatile__(                                           \
+       "cmp    %2, #(1<<28)\n\t"                                       \
+       "mov    %0, %2\n\t"                                             \
+       "addcc  %0, %0, %3\n\t"                                         \
+       "ldr" instr "   %1, [%0, #0 ]   @ in" #fnsuffix         \
+       : "=&r" (temp), "=r" (value)                                    \
+       : "r" (port), "Ir" (PCIO_BASE_##fnsuffix)       \
+       : "cc");                                                        \
+       return (unsigned sz)value;                                      \
+}
+
+static inline void __iomem *__ioaddr (unsigned long port)
+{
+       return __PORT_PCIO(port) ? (PCIO_BASE + port) : (void __iomem *)port;
+}
+
+#define DECLARE_IO(sz,fnsuffix,instr)  \
+       DECLARE_DYN_IN(sz,fnsuffix,instr) \
+       DECLARE_DYN_OUT(sz,fnsuffix,instr)
+
+DECLARE_IO(char,b,"b")
+DECLARE_IO(short,w,"h")
+DECLARE_IO(int,l,"")
+
+#undef DECLARE_IO
+#undef DECLARE_DYN_IN
+
+/*
+ * Constant address IO functions
+ *
+ * These have to be macros for the 'J' constraint to work -
+ * +/-4096 immediate operand.
+ */
+#define __outbc(value,port)                                            \
+({                                                                     \
+       if (__PORT_PCIO((port)))                                        \
+               __asm__ __volatile__(                                   \
+               "strb   %0, [%1, %2]    @ outbc"                        \
+               : : "r" (value), "r" (PCIO_BASE), "Jr" ((port)));       \
+       else                                                            \
+               __asm__ __volatile__(                                   \
+               "strb   %0, [%1, #0]    @ outbc"                        \
+               : : "r" (value), "r" ((port)));                         \
+})
+
+#define __inbc(port)                                                   \
+({                                                                     \
+       unsigned char result;                                           \
+       if (__PORT_PCIO((port)))                                        \
+               __asm__ __volatile__(                                   \
+               "ldrb   %0, [%1, %2]    @ inbc"                         \
+               : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port)));      \
+       else                                                            \
+               __asm__ __volatile__(                                   \
+               "ldrb   %0, [%1, #0]    @ inbc"                         \
+               : "=r" (result) : "r" ((port)));                        \
+       result;                                                         \
+})
+
+#define __outwc(value,port)                                            \
+({                                                                     \
+       unsigned long v = value;                                        \
+       if (__PORT_PCIO((port))) {                                      \
+               if ((port) < 256 && (port) > -256)                      \
+                       __asm__ __volatile__(                           \
+                       "strh   %0, [%1, %2]    @ outwc"                \
+                       : : "r" (v), "r" (PCIO_BASE), "Jr" ((port)));   \
+               else if ((port) > 0)                                    \
+                       __asm__ __volatile__(                           \
+                       "strh   %0, [%1, %2]    @ outwc"                \
+                       : : "r" (v),                                    \
+                           "r" (PCIO_BASE + ((port) & ~0xff)),         \
+                            "Jr" (((port) & 0xff)));                   \
+               else                                                    \
+                       __asm__ __volatile__(                           \
+                       "strh   %0, [%1, #0]    @ outwc"                \
+                       : : "r" (v),                                    \
+                           "r" (PCIO_BASE + (port)));                  \
+       } else                                                          \
+               __asm__ __volatile__(                                   \
+               "strh   %0, [%1, #0]    @ outwc"                        \
+               : : "r" (v), "r" ((port)));                             \
+})
+
+#define __inwc(port)                                                   \
+({                                                                     \
+       unsigned short result;                                          \
+       if (__PORT_PCIO((port))) {                                      \
+               if ((port) < 256 && (port) > -256 )                     \
+                       __asm__ __volatile__(                           \
+                       "ldrh   %0, [%1, %2]    @ inwc"                 \
+                       : "=r" (result)                                 \
+                       : "r" (PCIO_BASE),                              \
+                         "Jr" ((port)));                               \
+               else if ((port) > 0)                                    \
+                       __asm__ __volatile__(                           \
+                       "ldrh   %0, [%1, %2]    @ inwc"                 \
+                       : "=r" (result)                                 \
+                       : "r" (PCIO_BASE + ((port) & ~0xff)),           \
+                         "Jr" (((port) & 0xff)));                      \
+               else                                                    \
+                       __asm__ __volatile__(                           \
+                       "ldrh   %0, [%1, #0]    @ inwc"                 \
+                       : "=r" (result)                                 \
+                       : "r" (PCIO_BASE + ((port))));                  \
+       } else                                                          \
+               __asm__ __volatile__(                                   \
+               "ldrh   %0, [%1, #0]    @ inwc"                         \
+               : "=r" (result) : "r" ((port)));                        \
+       result;                                                         \
+})
+
+#define __outlc(value,port)                                            \
+({                                                                     \
+       unsigned long v = value;                                        \
+       if (__PORT_PCIO((port)))                                        \
+               __asm__ __volatile__(                                   \
+               "str    %0, [%1, %2]    @ outlc"                        \
+               : : "r" (v), "r" (PCIO_BASE), "Jr" ((port)));   \
+       else                                                            \
+               __asm__ __volatile__(                                   \
+               "str    %0, [%1, #0]    @ outlc"                        \
+               : : "r" (v), "r" ((port)));             \
+})
+
+#define __inlc(port)                                                   \
+({                                                                     \
+       unsigned long result;                                           \
+       if (__PORT_PCIO((port)))                                        \
+               __asm__ __volatile__(                                   \
+               "ldr    %0, [%1, %2]    @ inlc"                         \
+               : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port)));      \
+       else                                                            \
+               __asm__ __volatile__(                                   \
+               "ldr    %0, [%1, #0]    @ inlc"                         \
+               : "=r" (result) : "r" ((port)));                \
+       result;                                                         \
+})
+
+#define __ioaddrc(port)        ((__PORT_PCIO(port) ? PCIO_BASE + (port) : (void __iomem *)(port)))
+
+#define inb(p)         (__builtin_constant_p((p)) ? __inbc(p)     : __inb(p))
+#define inw(p)         (__builtin_constant_p((p)) ? __inwc(p)     : __inw(p))
+#define inl(p)         (__builtin_constant_p((p)) ? __inlc(p)     : __inl(p))
+#define outb(v,p)      (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))
+#define outw(v,p)      (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
+#define outl(v,p)      (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
+#define __ioaddr(p)    (__builtin_constant_p((p)) ? __ioaddr(p)  : __ioaddrc(p))
+
+#define insb(p,d,l)    __raw_readsb(__ioaddr(p),d,l)
+#define insw(p,d,l)    __raw_readsw(__ioaddr(p),d,l)
+#define insl(p,d,l)    __raw_readsl(__ioaddr(p),d,l)
+
+#define outsb(p,d,l)   __raw_writesb(__ioaddr(p),d,l)
+#define outsw(p,d,l)   __raw_writesw(__ioaddr(p),d,l)
+#define outsl(p,d,l)   __raw_writesl(__ioaddr(p),d,l)
+
+/*
+ * 1:1 mapping for ioremapped regions.
+ */
+#define __mem_pci(x)   (x)
+
+#endif
diff --git a/arch/arm/mach-s3c24xx/include/mach/irqs.h b/arch/arm/mach-s3c24xx/include/mach/irqs.h
new file mode 100644 (file)
index 0000000..e53b217
--- /dev/null
@@ -0,0 +1,202 @@
+/* arch/arm/mach-s3c2410/include/mach/irqs.h
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H __FILE__
+
+/* we keep the first set of CPU IRQs out of the range of
+ * the ISA space, so that the PC104 has them to itself
+ * and we don't end up having to do horrible things to the
+ * standard ISA drivers....
+ */
+
+#define S3C2410_CPUIRQ_OFFSET   (16)
+
+#define S3C2410_IRQ(x) ((x) + S3C2410_CPUIRQ_OFFSET)
+
+/* main cpu interrupts */
+#define IRQ_EINT0      S3C2410_IRQ(0)      /* 16 */
+#define IRQ_EINT1      S3C2410_IRQ(1)
+#define IRQ_EINT2      S3C2410_IRQ(2)
+#define IRQ_EINT3      S3C2410_IRQ(3)
+#define IRQ_EINT4t7    S3C2410_IRQ(4)      /* 20 */
+#define IRQ_EINT8t23   S3C2410_IRQ(5)
+#define IRQ_RESERVED6  S3C2410_IRQ(6)      /* for s3c2410 */
+#define IRQ_CAM        S3C2410_IRQ(6)      /* for s3c2440,s3c2443 */
+#define IRQ_BATT_FLT   S3C2410_IRQ(7)
+#define IRQ_TICK       S3C2410_IRQ(8)      /* 24 */
+#define IRQ_WDT               S3C2410_IRQ(9)       /* WDT/AC97 for s3c2443 */
+#define IRQ_TIMER0     S3C2410_IRQ(10)
+#define IRQ_TIMER1     S3C2410_IRQ(11)
+#define IRQ_TIMER2     S3C2410_IRQ(12)
+#define IRQ_TIMER3     S3C2410_IRQ(13)
+#define IRQ_TIMER4     S3C2410_IRQ(14)
+#define IRQ_UART2      S3C2410_IRQ(15)
+#define IRQ_LCD               S3C2410_IRQ(16)      /* 32 */
+#define IRQ_DMA0       S3C2410_IRQ(17)     /* IRQ_DMA for s3c2443 */
+#define IRQ_DMA1       S3C2410_IRQ(18)
+#define IRQ_DMA2       S3C2410_IRQ(19)
+#define IRQ_DMA3       S3C2410_IRQ(20)
+#define IRQ_SDI               S3C2410_IRQ(21)
+#define IRQ_SPI0       S3C2410_IRQ(22)
+#define IRQ_UART1      S3C2410_IRQ(23)
+#define IRQ_RESERVED24 S3C2410_IRQ(24)     /* 40 */
+#define IRQ_NFCON      S3C2410_IRQ(24)     /* for s3c2440 */
+#define IRQ_USBD       S3C2410_IRQ(25)
+#define IRQ_USBH       S3C2410_IRQ(26)
+#define IRQ_IIC               S3C2410_IRQ(27)
+#define IRQ_UART0      S3C2410_IRQ(28)     /* 44 */
+#define IRQ_SPI1       S3C2410_IRQ(29)
+#define IRQ_RTC               S3C2410_IRQ(30)
+#define IRQ_ADCPARENT  S3C2410_IRQ(31)
+
+/* interrupts generated from the external interrupts sources */
+#define IRQ_EINT4      S3C2410_IRQ(32)    /* 48 */
+#define IRQ_EINT5      S3C2410_IRQ(33)
+#define IRQ_EINT6      S3C2410_IRQ(34)
+#define IRQ_EINT7      S3C2410_IRQ(35)
+#define IRQ_EINT8      S3C2410_IRQ(36)
+#define IRQ_EINT9      S3C2410_IRQ(37)
+#define IRQ_EINT10     S3C2410_IRQ(38)
+#define IRQ_EINT11     S3C2410_IRQ(39)
+#define IRQ_EINT12     S3C2410_IRQ(40)
+#define IRQ_EINT13     S3C2410_IRQ(41)
+#define IRQ_EINT14     S3C2410_IRQ(42)
+#define IRQ_EINT15     S3C2410_IRQ(43)
+#define IRQ_EINT16     S3C2410_IRQ(44)
+#define IRQ_EINT17     S3C2410_IRQ(45)
+#define IRQ_EINT18     S3C2410_IRQ(46)
+#define IRQ_EINT19     S3C2410_IRQ(47)
+#define IRQ_EINT20     S3C2410_IRQ(48)    /* 64 */
+#define IRQ_EINT21     S3C2410_IRQ(49)
+#define IRQ_EINT22     S3C2410_IRQ(50)
+#define IRQ_EINT23     S3C2410_IRQ(51)
+
+#define IRQ_EINT_BIT(x)        ((x) - IRQ_EINT4 + 4)
+#define IRQ_EINT(x)    (((x) >= 4) ? (IRQ_EINT4 + (x) - 4) : (IRQ_EINT0 + (x)))
+
+#define IRQ_LCD_FIFO   S3C2410_IRQ(52)
+#define IRQ_LCD_FRAME  S3C2410_IRQ(53)
+
+/* IRQs for the interal UARTs, and ADC
+ * these need to be ordered in number of appearance in the
+ * SUBSRC mask register
+*/
+
+#define S3C2410_IRQSUB(x)      S3C2410_IRQ((x)+54)
+
+#define IRQ_S3CUART_RX0                S3C2410_IRQSUB(0)       /* 70 */
+#define IRQ_S3CUART_TX0                S3C2410_IRQSUB(1)
+#define IRQ_S3CUART_ERR0       S3C2410_IRQSUB(2)
+
+#define IRQ_S3CUART_RX1                S3C2410_IRQSUB(3)       /* 73 */
+#define IRQ_S3CUART_TX1                S3C2410_IRQSUB(4)
+#define IRQ_S3CUART_ERR1       S3C2410_IRQSUB(5)
+
+#define IRQ_S3CUART_RX2                S3C2410_IRQSUB(6)       /* 76 */
+#define IRQ_S3CUART_TX2                S3C2410_IRQSUB(7)
+#define IRQ_S3CUART_ERR2       S3C2410_IRQSUB(8)
+
+#define IRQ_TC                 S3C2410_IRQSUB(9)
+#define IRQ_ADC                        S3C2410_IRQSUB(10)
+
+/* extra irqs for s3c2412 */
+
+#define IRQ_S3C2412_CFSDI      S3C2410_IRQ(21)
+
+#define IRQ_S3C2412_SDI                S3C2410_IRQSUB(13)
+#define IRQ_S3C2412_CF         S3C2410_IRQSUB(14)
+
+
+#define IRQ_S3C2416_EINT8t15   S3C2410_IRQ(5)
+#define IRQ_S3C2416_DMA                S3C2410_IRQ(17)
+#define IRQ_S3C2416_UART3      S3C2410_IRQ(18)
+#define IRQ_S3C2416_SDI1       S3C2410_IRQ(20)
+#define IRQ_S3C2416_SDI0       S3C2410_IRQ(21)
+
+#define IRQ_S3C2416_LCD2       S3C2410_IRQSUB(15)
+#define IRQ_S3C2416_LCD3       S3C2410_IRQSUB(16)
+#define IRQ_S3C2416_LCD4       S3C2410_IRQSUB(17)
+#define IRQ_S3C2416_DMA0       S3C2410_IRQSUB(18)
+#define IRQ_S3C2416_DMA1       S3C2410_IRQSUB(19)
+#define IRQ_S3C2416_DMA2       S3C2410_IRQSUB(20)
+#define IRQ_S3C2416_DMA3       S3C2410_IRQSUB(21)
+#define IRQ_S3C2416_DMA4       S3C2410_IRQSUB(22)
+#define IRQ_S3C2416_DMA5       S3C2410_IRQSUB(23)
+#define IRQ_S32416_WDT         S3C2410_IRQSUB(27)
+#define IRQ_S32416_AC97                S3C2410_IRQSUB(28)
+
+
+/* extra irqs for s3c2440 */
+
+#define IRQ_S3C2440_CAM_C      S3C2410_IRQSUB(11)      /* S3C2443 too */
+#define IRQ_S3C2440_CAM_P      S3C2410_IRQSUB(12)      /* S3C2443 too */
+#define IRQ_S3C2440_WDT                S3C2410_IRQSUB(13)
+#define IRQ_S3C2440_AC97       S3C2410_IRQSUB(14)
+
+/* irqs for s3c2443 */
+
+#define IRQ_S3C2443_DMA                S3C2410_IRQ(17)         /* IRQ_DMA1 */
+#define IRQ_S3C2443_UART3      S3C2410_IRQ(18)         /* IRQ_DMA2 */
+#define IRQ_S3C2443_CFCON      S3C2410_IRQ(19)         /* IRQ_DMA3 */
+#define IRQ_S3C2443_HSMMC      S3C2410_IRQ(20)         /* IRQ_SDI */
+#define IRQ_S3C2443_NAND       S3C2410_IRQ(24)         /* reserved */
+
+#define IRQ_S3C2416_HSMMC0     S3C2410_IRQ(21)         /* S3C2416/S3C2450 */
+
+#define IRQ_HSMMC0             IRQ_S3C2416_HSMMC0
+#define IRQ_HSMMC1             IRQ_S3C2443_HSMMC
+
+#define IRQ_S3C2443_LCD1       S3C2410_IRQSUB(14)
+#define IRQ_S3C2443_LCD2       S3C2410_IRQSUB(15)
+#define IRQ_S3C2443_LCD3       S3C2410_IRQSUB(16)
+#define IRQ_S3C2443_LCD4       S3C2410_IRQSUB(17)
+
+#define IRQ_S3C2443_DMA0       S3C2410_IRQSUB(18)
+#define IRQ_S3C2443_DMA1       S3C2410_IRQSUB(19)
+#define IRQ_S3C2443_DMA2       S3C2410_IRQSUB(20)
+#define IRQ_S3C2443_DMA3       S3C2410_IRQSUB(21)
+#define IRQ_S3C2443_DMA4       S3C2410_IRQSUB(22)
+#define IRQ_S3C2443_DMA5       S3C2410_IRQSUB(23)
+
+/* UART3 */
+#define IRQ_S3C2443_RX3                S3C2410_IRQSUB(24)
+#define IRQ_S3C2443_TX3                S3C2410_IRQSUB(25)
+#define IRQ_S3C2443_ERR3       S3C2410_IRQSUB(26)
+
+#define IRQ_S3C2443_WDT                S3C2410_IRQSUB(27)
+#define IRQ_S3C2443_AC97       S3C2410_IRQSUB(28)
+
+#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
+#define NR_IRQS (IRQ_S3C2443_AC97+1)
+#else
+#define NR_IRQS (IRQ_S3C2440_AC97+1)
+#endif
+
+/* compatibility define. */
+#define IRQ_UART3              IRQ_S3C2443_UART3
+#define IRQ_S3CUART_RX3                IRQ_S3C2443_RX3
+#define IRQ_S3CUART_TX3                IRQ_S3C2443_TX3
+#define IRQ_S3CUART_ERR3       IRQ_S3C2443_ERR3
+
+#define IRQ_LCD_VSYNC          IRQ_S3C2443_LCD3
+#define IRQ_LCD_SYSTEM         IRQ_S3C2443_LCD2
+
+#ifdef CONFIG_CPU_S3C2440
+#define IRQ_S3C244X_AC97 IRQ_S3C2440_AC97
+#else
+#define IRQ_S3C244X_AC97 IRQ_S3C2443_AC97
+#endif
+
+/* Our FIQs are routable from IRQ_EINT0 to IRQ_ADCPARENT */
+#define FIQ_START              IRQ_EINT0
+
+#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/leds-gpio.h b/arch/arm/mach-s3c24xx/include/mach/leds-gpio.h
new file mode 100644 (file)
index 0000000..d8a7672
--- /dev/null
@@ -0,0 +1,28 @@
+/* arch/arm/mach-s3c2410/include/mach/leds-gpio.h
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX - LEDs GPIO connector
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_LEDSGPIO_H
+#define __ASM_ARCH_LEDSGPIO_H "leds-gpio.h"
+
+#define S3C24XX_LEDF_ACTLOW    (1<<0)          /* LED is on when GPIO low */
+#define S3C24XX_LEDF_TRISTATE  (1<<1)          /* tristate to turn off */
+
+struct s3c24xx_led_platdata {
+       unsigned int             gpio;
+       unsigned int             flags;
+
+       char                    *name;
+       char                    *def_trigger;
+};
+
+#endif /* __ASM_ARCH_LEDSGPIO_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/map.h b/arch/arm/mach-s3c24xx/include/mach/map.h
new file mode 100644 (file)
index 0000000..78ae807
--- /dev/null
@@ -0,0 +1,165 @@
+/* arch/arm/mach-s3c2410/include/mach/map.h
+ *
+ * Copyright (c) 2003 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H
+
+#include <plat/map-base.h>
+
+/*
+ * S3C2410 UART offset is 0x4000 but the other SoCs are 0x400.
+ * So need to define it, and here is to avoid redefinition warning.
+ */
+#define S3C_UART_OFFSET                (0x4000)
+
+#include <plat/map-s3c.h>
+
+/*
+ * interrupt controller is the first thing we put in, to make
+ * the assembly code for the irq detection easier
+ */
+#define S3C2410_PA_IRQ         (0x4A000000)
+#define S3C24XX_SZ_IRQ         SZ_1M
+
+/* memory controller registers */
+#define S3C2410_PA_MEMCTRL     (0x48000000)
+#define S3C24XX_SZ_MEMCTRL     SZ_1M
+
+/* UARTs */
+#define S3C_VA_UARTx(uart)     (S3C_VA_UART + ((uart * S3C_UART_OFFSET)))
+
+/* Timers */
+#define S3C2410_PA_TIMER       (0x51000000)
+#define S3C24XX_SZ_TIMER       SZ_1M
+
+/* Clock and Power management */
+#define S3C24XX_SZ_CLKPWR      SZ_1M
+
+/* USB Device port */
+#define S3C2410_PA_USBDEV      (0x52000000)
+#define S3C24XX_SZ_USBDEV      SZ_1M
+
+/* Watchdog */
+#define S3C2410_PA_WATCHDOG    (0x53000000)
+#define S3C24XX_SZ_WATCHDOG    SZ_1M
+
+/* Standard size definitions for peripheral blocks. */
+
+#define S3C24XX_SZ_UART                SZ_1M
+#define S3C24XX_SZ_IIS         SZ_1M
+#define S3C24XX_SZ_ADC         SZ_1M
+#define S3C24XX_SZ_SPI         SZ_1M
+#define S3C24XX_SZ_SDI         SZ_1M
+#define S3C24XX_SZ_NAND                SZ_1M
+#define S3C24XX_SZ_GPIO                SZ_1M
+
+/* USB host controller */
+#define S3C2410_PA_USBHOST (0x49000000)
+
+/* S3C2416/S3C2443/S3C2450 High-Speed USB Gadget */
+#define S3C2416_PA_HSUDC       (0x49800000)
+#define S3C2416_SZ_HSUDC       (SZ_4K)
+
+/* DMA controller */
+#define S3C2410_PA_DMA    (0x4B000000)
+#define S3C24XX_SZ_DMA    SZ_1M
+
+/* Clock and Power management */
+#define S3C2410_PA_CLKPWR  (0x4C000000)
+
+/* LCD controller */
+#define S3C2410_PA_LCD    (0x4D000000)
+#define S3C24XX_SZ_LCD    SZ_1M
+
+/* NAND flash controller */
+#define S3C2410_PA_NAND           (0x4E000000)
+
+/* IIC hardware controller */
+#define S3C2410_PA_IIC    (0x54000000)
+
+/* IIS controller */
+#define S3C2410_PA_IIS    (0x55000000)
+
+/* RTC */
+#define S3C2410_PA_RTC    (0x57000000)
+#define S3C24XX_SZ_RTC    SZ_1M
+
+/* ADC */
+#define S3C2410_PA_ADC    (0x58000000)
+
+/* SPI */
+#define S3C2410_PA_SPI    (0x59000000)
+
+/* SDI */
+#define S3C2410_PA_SDI    (0x5A000000)
+
+/* CAMIF */
+#define S3C2440_PA_CAMIF   (0x4F000000)
+#define S3C2440_SZ_CAMIF   SZ_1M
+
+/* AC97 */
+
+#define S3C2440_PA_AC97           (0x5B000000)
+#define S3C2440_SZ_AC97           SZ_1M
+
+/* S3C2443/S3C2416 High-speed SD/MMC */
+#define S3C2443_PA_HSMMC   (0x4A800000)
+#define S3C2416_PA_HSMMC0  (0x4AC00000)
+
+#define        S3C2443_PA_FB   (0x4C800000)
+
+/* S3C2412 memory and IO controls */
+#define S3C2412_PA_SSMC        (0x4F000000)
+
+#define S3C2412_PA_EBI (0x48800000)
+
+/* physical addresses of all the chip-select areas */
+
+#define S3C2410_CS0 (0x00000000)
+#define S3C2410_CS1 (0x08000000)
+#define S3C2410_CS2 (0x10000000)
+#define S3C2410_CS3 (0x18000000)
+#define S3C2410_CS4 (0x20000000)
+#define S3C2410_CS5 (0x28000000)
+#define S3C2410_CS6 (0x30000000)
+#define S3C2410_CS7 (0x38000000)
+
+#define S3C2410_SDRAM_PA    (S3C2410_CS6)
+
+/* Use a single interface for common resources between S3C24XX cpus */
+
+#define S3C24XX_PA_IRQ      S3C2410_PA_IRQ
+#define S3C24XX_PA_MEMCTRL  S3C2410_PA_MEMCTRL
+#define S3C24XX_PA_DMA      S3C2410_PA_DMA
+#define S3C24XX_PA_CLKPWR   S3C2410_PA_CLKPWR
+#define S3C24XX_PA_LCD      S3C2410_PA_LCD
+#define S3C24XX_PA_TIMER    S3C2410_PA_TIMER
+#define S3C24XX_PA_USBDEV   S3C2410_PA_USBDEV
+#define S3C24XX_PA_WATCHDOG S3C2410_PA_WATCHDOG
+#define S3C24XX_PA_IIS      S3C2410_PA_IIS
+#define S3C24XX_PA_RTC      S3C2410_PA_RTC
+#define S3C24XX_PA_ADC      S3C2410_PA_ADC
+#define S3C24XX_PA_SPI      S3C2410_PA_SPI
+#define S3C24XX_PA_SPI1                (S3C2410_PA_SPI + S3C2410_SPI1)
+#define S3C24XX_PA_SDI      S3C2410_PA_SDI
+#define S3C24XX_PA_NAND            S3C2410_PA_NAND
+
+#define S3C_PA_FB          S3C2443_PA_FB
+#define S3C_PA_IIC          S3C2410_PA_IIC
+#define S3C_PA_UART        S3C24XX_PA_UART
+#define S3C_PA_USBHOST S3C2410_PA_USBHOST
+#define S3C_PA_HSMMC0      S3C2416_PA_HSMMC0
+#define S3C_PA_HSMMC1      S3C2443_PA_HSMMC
+#define S3C_PA_WDT         S3C2410_PA_WATCHDOG
+#define S3C_PA_NAND        S3C24XX_PA_NAND
+
+#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/osiris-cpld.h b/arch/arm/mach-s3c24xx/include/mach/osiris-cpld.h
new file mode 100644 (file)
index 0000000..e9e36b0
--- /dev/null
@@ -0,0 +1,30 @@
+/* arch/arm/mach-s3c2410/include/mach/osiris-cpld.h
+ *
+ * Copyright 2005 Simtec Electronics
+ *     http://www.simtec.co.uk/products/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * OSIRIS - CPLD control constants
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_OSIRISCPLD_H
+#define __ASM_ARCH_OSIRISCPLD_H
+
+/* CTRL0 - NAND WP control */
+
+#define OSIRIS_CTRL0_NANDSEL           (0x3)
+#define OSIRIS_CTRL0_BOOT_INT          (1<<3)
+#define OSIRIS_CTRL0_PCMCIA            (1<<4)
+#define OSIRIS_CTRL0_FIX8              (1<<5)
+#define OSIRIS_CTRL0_PCMCIA_nWAIT      (1<<6)
+#define OSIRIS_CTRL0_PCMCIA_nIOIS16    (1<<7)
+
+#define OSIRIS_CTRL1_FIX8              (1<<0)
+
+#define OSIRIS_ID_REVMASK              (0x7)
+
+#endif /* __ASM_ARCH_OSIRISCPLD_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/osiris-map.h b/arch/arm/mach-s3c24xx/include/mach/osiris-map.h
new file mode 100644 (file)
index 0000000..17380f8
--- /dev/null
@@ -0,0 +1,42 @@
+/* arch/arm/mach-s3c2410/include/mach/osiris-map.h
+ *
+ * Copyright 2005 Simtec Electronics
+ *     http://www.simtec.co.uk/products/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * OSIRIS - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* needs arch/map.h including with this */
+
+#ifndef __ASM_ARCH_OSIRISMAP_H
+#define __ASM_ARCH_OSIRISMAP_H
+
+/* start peripherals off after the S3C2410 */
+
+#define OSIRIS_IOADDR(x)       (S3C2410_ADDR((x) + 0x04000000))
+
+#define OSIRIS_PA_CPLD         (S3C2410_CS1 | (1<<26))
+
+/* we put the CPLD registers next, to get them out of the way */
+
+#define OSIRIS_VA_CTRL0                OSIRIS_IOADDR(0x00000000)
+#define OSIRIS_PA_CTRL0                (OSIRIS_PA_CPLD)
+
+#define OSIRIS_VA_CTRL1                OSIRIS_IOADDR(0x00100000)
+#define OSIRIS_PA_CTRL1                (OSIRIS_PA_CPLD + (1<<23))
+
+#define OSIRIS_VA_CTRL2                OSIRIS_IOADDR(0x00200000)
+#define OSIRIS_PA_CTRL2                (OSIRIS_PA_CPLD + (2<<23))
+
+#define OSIRIS_VA_CTRL3                OSIRIS_IOADDR(0x00300000)
+#define OSIRIS_PA_CTRL3                (OSIRIS_PA_CPLD + (2<<23))
+
+#define OSIRIS_VA_IDREG                OSIRIS_IOADDR(0x00700000)
+#define OSIRIS_PA_IDREG                (OSIRIS_PA_CPLD + (7<<23))
+
+#endif /* __ASM_ARCH_OSIRISMAP_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/otom-map.h b/arch/arm/mach-s3c24xx/include/mach/otom-map.h
new file mode 100644 (file)
index 0000000..f9277a5
--- /dev/null
@@ -0,0 +1,30 @@
+/* arch/arm/mach-s3c2410/include/mach/otom-map.h
+ *
+ * (c) 2005 Guillaume GOURAT / NexVision
+ *          guillaume.gourat@nexvision.fr
+ *
+ * NexVision OTOM board memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* needs arch/map.h including with this */
+
+/* ok, we've used up to 0x01300000, now we need to find space for the
+ * peripherals that live in the nGCS[x] areas, which are quite numerous
+ * in their space.
+ */
+
+#ifndef __ASM_ARCH_OTOMMAP_H
+#define __ASM_ARCH_OTOMMAP_H
+
+#define OTOM_PA_CS8900A_BASE       (S3C2410_CS3 + 0x01000000)  /* nGCS3 +0x01000000 */
+#define OTOM_VA_CS8900A_BASE       S3C2410_ADDR(0x04000000)            /* 0xF4000000 */
+
+/* physical offset addresses for the peripherals */
+
+#define OTOM_PA_FLASH0_BASE        (S3C2410_CS0)                               /* Bank 0 */
+
+#endif /* __ASM_ARCH_OTOMMAP_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/pm-core.h b/arch/arm/mach-s3c24xx/include/mach/pm-core.h
new file mode 100644 (file)
index 0000000..2eef7e6
--- /dev/null
@@ -0,0 +1,67 @@
+/* linux/arch/arm/mach-s3c2410/include/pm-core.h
+ *
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C24xx - PM core support for arch/arm/plat-s3c/pm.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+static inline void s3c_pm_debug_init_uart(void)
+{
+       unsigned long tmp = __raw_readl(S3C2410_CLKCON);
+
+       /* re-start uart clocks */
+       tmp |= S3C2410_CLKCON_UART0;
+       tmp |= S3C2410_CLKCON_UART1;
+       tmp |= S3C2410_CLKCON_UART2;
+
+       __raw_writel(tmp, S3C2410_CLKCON);
+       udelay(10);
+}
+
+static inline void s3c_pm_arch_prepare_irqs(void)
+{
+       __raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);
+       __raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK);
+
+       /* ack any outstanding external interrupts before we go to sleep */
+
+       __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
+       __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
+       __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
+
+}
+
+static inline void s3c_pm_arch_stop_clocks(void)
+{
+       __raw_writel(0x00, S3C2410_CLKCON);  /* turn off clocks over sleep */
+}
+
+static void s3c_pm_show_resume_irqs(int start, unsigned long which,
+                                   unsigned long mask);
+
+static inline void s3c_pm_arch_show_resume_irqs(void)
+{
+       S3C_PMDBG("post sleep: IRQs 0x%08x, 0x%08x\n",
+                 __raw_readl(S3C2410_SRCPND),
+                 __raw_readl(S3C2410_EINTPEND));
+
+       s3c_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
+                               s3c_irqwake_intmask);
+
+       s3c_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
+                               s3c_irqwake_eintmask);
+}
+
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+                                          struct pm_uart_save *save)
+{
+}
+
+static inline void s3c_pm_restored_gpios(void) { }
+static inline void samsung_pm_saved_gpios(void) { }
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-clock.h b/arch/arm/mach-s3c24xx/include/mach/regs-clock.h
new file mode 100644 (file)
index 0000000..3415b60
--- /dev/null
@@ -0,0 +1,166 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2003-2006 Simtec Electronics <linux@simtec.co.uk>
+ *     http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 clock register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_CLOCK
+#define __ASM_ARM_REGS_CLOCK
+
+#define S3C2410_CLKREG(x) ((x) + S3C24XX_VA_CLKPWR)
+
+#define S3C2410_PLLVAL(_m,_p,_s) ((_m) << 12 | ((_p) << 4) | ((_s)))
+
+#define S3C2410_LOCKTIME    S3C2410_CLKREG(0x00)
+#define S3C2410_MPLLCON            S3C2410_CLKREG(0x04)
+#define S3C2410_UPLLCON            S3C2410_CLKREG(0x08)
+#define S3C2410_CLKCON     S3C2410_CLKREG(0x0C)
+#define S3C2410_CLKSLOW            S3C2410_CLKREG(0x10)
+#define S3C2410_CLKDIVN            S3C2410_CLKREG(0x14)
+
+#define S3C2410_CLKCON_IDLE         (1<<2)
+#define S3C2410_CLKCON_POWER        (1<<3)
+#define S3C2410_CLKCON_NAND         (1<<4)
+#define S3C2410_CLKCON_LCDC         (1<<5)
+#define S3C2410_CLKCON_USBH         (1<<6)
+#define S3C2410_CLKCON_USBD         (1<<7)
+#define S3C2410_CLKCON_PWMT         (1<<8)
+#define S3C2410_CLKCON_SDI          (1<<9)
+#define S3C2410_CLKCON_UART0        (1<<10)
+#define S3C2410_CLKCON_UART1        (1<<11)
+#define S3C2410_CLKCON_UART2        (1<<12)
+#define S3C2410_CLKCON_GPIO         (1<<13)
+#define S3C2410_CLKCON_RTC          (1<<14)
+#define S3C2410_CLKCON_ADC          (1<<15)
+#define S3C2410_CLKCON_IIC          (1<<16)
+#define S3C2410_CLKCON_IIS          (1<<17)
+#define S3C2410_CLKCON_SPI          (1<<18)
+
+/* DCLKCON register addresses in gpio.h */
+
+#define S3C2410_DCLKCON_DCLK0EN             (1<<0)
+#define S3C2410_DCLKCON_DCLK0_PCLK   (0<<1)
+#define S3C2410_DCLKCON_DCLK0_UCLK   (1<<1)
+#define S3C2410_DCLKCON_DCLK0_DIV(x) (((x) - 1 )<<4)
+#define S3C2410_DCLKCON_DCLK0_CMP(x) (((x) - 1 )<<8)
+#define S3C2410_DCLKCON_DCLK0_DIV_MASK ((0xf)<<4)
+#define S3C2410_DCLKCON_DCLK0_CMP_MASK ((0xf)<<8)
+
+#define S3C2410_DCLKCON_DCLK1EN             (1<<16)
+#define S3C2410_DCLKCON_DCLK1_PCLK   (0<<17)
+#define S3C2410_DCLKCON_DCLK1_UCLK   (1<<17)
+#define S3C2410_DCLKCON_DCLK1_DIV(x) (((x) - 1) <<20)
+#define S3C2410_DCLKCON_DCLK1_CMP(x) (((x) - 1) <<24)
+#define S3C2410_DCLKCON_DCLK1_DIV_MASK ((0xf) <<20)
+#define S3C2410_DCLKCON_DCLK1_CMP_MASK ((0xf) <<24)
+
+#define S3C2410_CLKDIVN_PDIVN       (1<<0)
+#define S3C2410_CLKDIVN_HDIVN       (1<<1)
+
+#define S3C2410_CLKSLOW_UCLK_OFF       (1<<7)
+#define S3C2410_CLKSLOW_MPLL_OFF       (1<<5)
+#define S3C2410_CLKSLOW_SLOW           (1<<4)
+#define S3C2410_CLKSLOW_SLOWVAL(x)     (x)
+#define S3C2410_CLKSLOW_GET_SLOWVAL(x) ((x) & 7)
+
+#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
+
+/* extra registers */
+#define S3C2440_CAMDIVN            S3C2410_CLKREG(0x18)
+
+#define S3C2440_CLKCON_CAMERA        (1<<19)
+#define S3C2440_CLKCON_AC97          (1<<20)
+
+#define S3C2440_CLKDIVN_PDIVN       (1<<0)
+#define S3C2440_CLKDIVN_HDIVN_MASK   (3<<1)
+#define S3C2440_CLKDIVN_HDIVN_1      (0<<1)
+#define S3C2440_CLKDIVN_HDIVN_2      (1<<1)
+#define S3C2440_CLKDIVN_HDIVN_4_8    (2<<1)
+#define S3C2440_CLKDIVN_HDIVN_3_6    (3<<1)
+#define S3C2440_CLKDIVN_UCLK         (1<<3)
+
+#define S3C2440_CAMDIVN_CAMCLK_MASK  (0xf<<0)
+#define S3C2440_CAMDIVN_CAMCLK_SEL   (1<<4)
+#define S3C2440_CAMDIVN_HCLK3_HALF   (1<<8)
+#define S3C2440_CAMDIVN_HCLK4_HALF   (1<<9)
+#define S3C2440_CAMDIVN_DVSEN        (1<<12)
+
+#define S3C2442_CAMDIVN_CAMCLK_DIV3  (1<<5)
+
+#endif /* CONFIG_CPU_S3C2440 or CONFIG_CPU_S3C2442 */
+
+#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
+
+#define S3C2412_OSCSET         S3C2410_CLKREG(0x18)
+#define S3C2412_CLKSRC         S3C2410_CLKREG(0x1C)
+
+#define S3C2412_PLLCON_OFF             (1<<20)
+
+#define S3C2412_CLKDIVN_PDIVN          (1<<2)
+#define S3C2412_CLKDIVN_HDIVN_MASK     (3<<0)
+#define S3C2412_CLKDIVN_ARMDIVN                (1<<3)
+#define S3C2412_CLKDIVN_DVSEN          (1<<4)
+#define S3C2412_CLKDIVN_HALFHCLK       (1<<5)
+#define S3C2412_CLKDIVN_USB48DIV       (1<<6)
+#define S3C2412_CLKDIVN_UARTDIV_MASK   (15<<8)
+#define S3C2412_CLKDIVN_UARTDIV_SHIFT  (8)
+#define S3C2412_CLKDIVN_I2SDIV_MASK    (15<<12)
+#define S3C2412_CLKDIVN_I2SDIV_SHIFT   (12)
+#define S3C2412_CLKDIVN_CAMDIV_MASK    (15<<16)
+#define S3C2412_CLKDIVN_CAMDIV_SHIFT   (16)
+
+#define S3C2412_CLKCON_WDT             (1<<28)
+#define S3C2412_CLKCON_SPI             (1<<27)
+#define S3C2412_CLKCON_IIS             (1<<26)
+#define S3C2412_CLKCON_IIC             (1<<25)
+#define S3C2412_CLKCON_ADC             (1<<24)
+#define S3C2412_CLKCON_RTC             (1<<23)
+#define S3C2412_CLKCON_GPIO            (1<<22)
+#define S3C2412_CLKCON_UART2           (1<<21)
+#define S3C2412_CLKCON_UART1           (1<<20)
+#define S3C2412_CLKCON_UART0           (1<<19)
+#define S3C2412_CLKCON_SDI             (1<<18)
+#define S3C2412_CLKCON_PWMT            (1<<17)
+#define S3C2412_CLKCON_USBD            (1<<16)
+#define S3C2412_CLKCON_CAMCLK          (1<<15)
+#define S3C2412_CLKCON_UARTCLK         (1<<14)
+/* missing 13 */
+#define S3C2412_CLKCON_USB_HOST48      (1<<12)
+#define S3C2412_CLKCON_USB_DEV48       (1<<11)
+#define S3C2412_CLKCON_HCLKdiv2                (1<<10)
+#define S3C2412_CLKCON_HCLKx2          (1<<9)
+#define S3C2412_CLKCON_SDRAM           (1<<8)
+/* missing 7 */
+#define S3C2412_CLKCON_USBH            S3C2410_CLKCON_USBH
+#define S3C2412_CLKCON_LCDC            S3C2410_CLKCON_LCDC
+#define S3C2412_CLKCON_NAND            S3C2410_CLKCON_NAND
+#define S3C2412_CLKCON_DMA3            (1<<3)
+#define S3C2412_CLKCON_DMA2            (1<<2)
+#define S3C2412_CLKCON_DMA1            (1<<1)
+#define S3C2412_CLKCON_DMA0            (1<<0)
+
+/* clock sourec controls */
+
+#define S3C2412_CLKSRC_EXTCLKDIV_MASK          (7 << 0)
+#define S3C2412_CLKSRC_EXTCLKDIV_SHIFT         (0)
+#define S3C2412_CLKSRC_MDIVCLK_EXTCLKDIV       (1<<3)
+#define S3C2412_CLKSRC_MSYSCLK_MPLL            (1<<4)
+#define S3C2412_CLKSRC_USYSCLK_UPLL            (1<<5)
+#define S3C2412_CLKSRC_UARTCLK_MPLL            (1<<8)
+#define S3C2412_CLKSRC_I2SCLK_MPLL             (1<<9)
+#define S3C2412_CLKSRC_USBCLK_HCLK             (1<<10)
+#define S3C2412_CLKSRC_CAMCLK_HCLK             (1<<11)
+#define S3C2412_CLKSRC_UREFCLK_EXTCLK  (1<<12)
+#define S3C2412_CLKSRC_EREFCLK_EXTCLK  (1<<14)
+
+#endif /* CONFIG_CPU_S3C2412 | CONFIG_CPU_S3C2413 */
+
+#define S3C2416_CLKDIV2                S3C2410_CLKREG(0x28)
+
+#endif /* __ASM_ARM_REGS_CLOCK */
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-dsc.h b/arch/arm/mach-s3c24xx/include/mach/regs-dsc.h
new file mode 100644 (file)
index 0000000..98fd4a0
--- /dev/null
@@ -0,0 +1,220 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-dsc.h
+ *
+ * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
+ *                   http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2440/S3C2412 Signal Drive Strength Control
+*/
+
+
+#ifndef __ASM_ARCH_REGS_DSC_H
+#define __ASM_ARCH_REGS_DSC_H "2440-dsc"
+
+#if defined(CONFIG_CPU_S3C2412)
+#define S3C2412_DSC0      S3C2410_GPIOREG(0xdc)
+#define S3C2412_DSC1      S3C2410_GPIOREG(0xe0)
+#endif
+
+#if defined(CONFIG_CPU_S3C2416)
+#define S3C2416_DSC0      S3C2410_GPIOREG(0xc0)
+#define S3C2416_DSC1      S3C2410_GPIOREG(0xc4)
+#define S3C2416_DSC2      S3C2410_GPIOREG(0xc8)
+#define S3C2416_DSC3      S3C2410_GPIOREG(0x110)
+
+#define S3C2416_SELECT_DSC0    (0 << 30)
+#define S3C2416_SELECT_DSC1    (1 << 30)
+#define S3C2416_SELECT_DSC2    (2 << 30)
+#define S3C2416_SELECT_DSC3    (3 << 30)
+
+#define S3C2416_DSC_GETSHIFT(x)        (x & 30)
+
+#define S3C2416_DSC0_CF                (S3C2416_SELECT_DSC0 | 28)
+#define        S3C2416_DSC0_CF_5mA     (0 << 28)
+#define        S3C2416_DSC0_CF_10mA    (1 << 28)
+#define        S3C2416_DSC0_CF_15mA    (2 << 28)
+#define        S3C2416_DSC0_CF_21mA    (3 << 28)
+#define        S3C2416_DSC0_CF_MASK    (3 << 28)
+
+#define S3C2416_DSC0_nRBE      (S3C2416_SELECT_DSC0 | 26)
+#define        S3C2416_DSC0_nRBE_5mA   (0 << 26)
+#define        S3C2416_DSC0_nRBE_10mA  (1 << 26)
+#define        S3C2416_DSC0_nRBE_15mA  (2 << 26)
+#define        S3C2416_DSC0_nRBE_21mA  (3 << 26)
+#define        S3C2416_DSC0_nRBE_MASK  (3 << 26)
+
+#define S3C2416_DSC0_nROE      (S3C2416_SELECT_DSC0 | 24)
+#define        S3C2416_DSC0_nROE_5mA   (0 << 24)
+#define        S3C2416_DSC0_nROE_10mA  (1 << 24)
+#define        S3C2416_DSC0_nROE_15mA  (2 << 24)
+#define        S3C2416_DSC0_nROE_21mA  (3 << 24)
+#define        S3C2416_DSC0_nROE_MASK  (3 << 24)
+
+#endif
+
+#if defined(CONFIG_CPU_S3C244X)
+
+#define S3C2440_DSC0      S3C2410_GPIOREG(0xc4)
+#define S3C2440_DSC1      S3C2410_GPIOREG(0xc8)
+
+#define S3C2440_SELECT_DSC0 (0)
+#define S3C2440_SELECT_DSC1 (1<<31)
+
+#define S3C2440_DSC_GETSHIFT(x) ((x) & 31)
+
+#define S3C2440_DSC0_DISABLE   (1<<31)
+
+#define S3C2440_DSC0_ADDR       (S3C2440_SELECT_DSC0 | 8)
+#define S3C2440_DSC0_ADDR_12mA  (0<<8)
+#define S3C2440_DSC0_ADDR_10mA  (1<<8)
+#define S3C2440_DSC0_ADDR_8mA   (2<<8)
+#define S3C2440_DSC0_ADDR_6mA   (3<<8)
+#define S3C2440_DSC0_ADDR_MASK  (3<<8)
+
+/* D24..D31 */
+#define S3C2440_DSC0_DATA3      (S3C2440_SELECT_DSC0 | 6)
+#define S3C2440_DSC0_DATA3_12mA (0<<6)
+#define S3C2440_DSC0_DATA3_10mA (1<<6)
+#define S3C2440_DSC0_DATA3_8mA  (2<<6)
+#define S3C2440_DSC0_DATA3_6mA  (3<<6)
+#define S3C2440_DSC0_DATA3_MASK (3<<6)
+
+/* D16..D23 */
+#define S3C2440_DSC0_DATA2      (S3C2440_SELECT_DSC0 | 4)
+#define S3C2440_DSC0_DATA2_12mA (0<<4)
+#define S3C2440_DSC0_DATA2_10mA (1<<4)
+#define S3C2440_DSC0_DATA2_8mA  (2<<4)
+#define S3C2440_DSC0_DATA2_6mA  (3<<4)
+#define S3C2440_DSC0_DATA2_MASK (3<<4)
+
+/* D8..D15 */
+#define S3C2440_DSC0_DATA1      (S3C2440_SELECT_DSC0 | 2)
+#define S3C2440_DSC0_DATA1_12mA (0<<2)
+#define S3C2440_DSC0_DATA1_10mA (1<<2)
+#define S3C2440_DSC0_DATA1_8mA  (2<<2)
+#define S3C2440_DSC0_DATA1_6mA  (3<<2)
+#define S3C2440_DSC0_DATA1_MASK (3<<2)
+
+/* D0..D7 */
+#define S3C2440_DSC0_DATA0      (S3C2440_SELECT_DSC0 | 0)
+#define S3C2440_DSC0_DATA0_12mA (0<<0)
+#define S3C2440_DSC0_DATA0_10mA (1<<0)
+#define S3C2440_DSC0_DATA0_8mA  (2<<0)
+#define S3C2440_DSC0_DATA0_6mA  (3<<0)
+#define S3C2440_DSC0_DATA0_MASK (3<<0)
+
+#define S3C2440_DSC1_SCK1       (S3C2440_SELECT_DSC1 | 28)
+#define S3C2440_DSC1_SCK1_12mA  (0<<28)
+#define S3C2440_DSC1_SCK1_10mA  (1<<28)
+#define S3C2440_DSC1_SCK1_8mA   (2<<28)
+#define S3C2440_DSC1_SCK1_6mA   (3<<28)
+#define S3C2440_DSC1_SCK1_MASK  (3<<28)
+
+#define S3C2440_DSC1_SCK0       (S3C2440_SELECT_DSC1 | 26)
+#define S3C2440_DSC1_SCK0_12mA  (0<<26)
+#define S3C2440_DSC1_SCK0_10mA  (1<<26)
+#define S3C2440_DSC1_SCK0_8mA   (2<<26)
+#define S3C2440_DSC1_SCK0_6mA   (3<<26)
+#define S3C2440_DSC1_SCK0_MASK  (3<<26)
+
+#define S3C2440_DSC1_SCKE       (S3C2440_SELECT_DSC1 | 24)
+#define S3C2440_DSC1_SCKE_10mA  (0<<24)
+#define S3C2440_DSC1_SCKE_8mA   (1<<24)
+#define S3C2440_DSC1_SCKE_6mA   (2<<24)
+#define S3C2440_DSC1_SCKE_4mA   (3<<24)
+#define S3C2440_DSC1_SCKE_MASK  (3<<24)
+
+/* SDRAM nRAS/nCAS */
+#define S3C2440_DSC1_SDR        (S3C2440_SELECT_DSC1 | 22)
+#define S3C2440_DSC1_SDR_10mA   (0<<22)
+#define S3C2440_DSC1_SDR_8mA    (1<<22)
+#define S3C2440_DSC1_SDR_6mA    (2<<22)
+#define S3C2440_DSC1_SDR_4mA    (3<<22)
+#define S3C2440_DSC1_SDR_MASK   (3<<22)
+
+/* NAND Flash Controller */
+#define S3C2440_DSC1_NFC        (S3C2440_SELECT_DSC1 | 20)
+#define S3C2440_DSC1_NFC_10mA   (0<<20)
+#define S3C2440_DSC1_NFC_8mA    (1<<20)
+#define S3C2440_DSC1_NFC_6mA    (2<<20)
+#define S3C2440_DSC1_NFC_4mA    (3<<20)
+#define S3C2440_DSC1_NFC_MASK   (3<<20)
+
+/* nBE[0..3] */
+#define S3C2440_DSC1_nBE        (S3C2440_SELECT_DSC1 | 18)
+#define S3C2440_DSC1_nBE_10mA   (0<<18)
+#define S3C2440_DSC1_nBE_8mA    (1<<18)
+#define S3C2440_DSC1_nBE_6mA    (2<<18)
+#define S3C2440_DSC1_nBE_4mA    (3<<18)
+#define S3C2440_DSC1_nBE_MASK   (3<<18)
+
+#define S3C2440_DSC1_WOE        (S3C2440_SELECT_DSC1 | 16)
+#define S3C2440_DSC1_WOE_10mA   (0<<16)
+#define S3C2440_DSC1_WOE_8mA    (1<<16)
+#define S3C2440_DSC1_WOE_6mA    (2<<16)
+#define S3C2440_DSC1_WOE_4mA    (3<<16)
+#define S3C2440_DSC1_WOE_MASK   (3<<16)
+
+#define S3C2440_DSC1_CS7        (S3C2440_SELECT_DSC1 | 14)
+#define S3C2440_DSC1_CS7_10mA   (0<<14)
+#define S3C2440_DSC1_CS7_8mA    (1<<14)
+#define S3C2440_DSC1_CS7_6mA    (2<<14)
+#define S3C2440_DSC1_CS7_4mA    (3<<14)
+#define S3C2440_DSC1_CS7_MASK   (3<<14)
+
+#define S3C2440_DSC1_CS6        (S3C2440_SELECT_DSC1 | 12)
+#define S3C2440_DSC1_CS6_10mA   (0<<12)
+#define S3C2440_DSC1_CS6_8mA    (1<<12)
+#define S3C2440_DSC1_CS6_6mA    (2<<12)
+#define S3C2440_DSC1_CS6_4mA    (3<<12)
+#define S3C2440_DSC1_CS6_MASK   (3<<12)
+
+#define S3C2440_DSC1_CS5        (S3C2440_SELECT_DSC1 | 10)
+#define S3C2440_DSC1_CS5_10mA   (0<<10)
+#define S3C2440_DSC1_CS5_8mA    (1<<10)
+#define S3C2440_DSC1_CS5_6mA    (2<<10)
+#define S3C2440_DSC1_CS5_4mA    (3<<10)
+#define S3C2440_DSC1_CS5_MASK   (3<<10)
+
+#define S3C2440_DSC1_CS4        (S3C2440_SELECT_DSC1 | 8)
+#define S3C2440_DSC1_CS4_10mA   (0<<8)
+#define S3C2440_DSC1_CS4_8mA    (1<<8)
+#define S3C2440_DSC1_CS4_6mA    (2<<8)
+#define S3C2440_DSC1_CS4_4mA    (3<<8)
+#define S3C2440_DSC1_CS4_MASK   (3<<8)
+
+#define S3C2440_DSC1_CS3        (S3C2440_SELECT_DSC1 | 6)
+#define S3C2440_DSC1_CS3_10mA   (0<<6)
+#define S3C2440_DSC1_CS3_8mA    (1<<6)
+#define S3C2440_DSC1_CS3_6mA    (2<<6)
+#define S3C2440_DSC1_CS3_4mA    (3<<6)
+#define S3C2440_DSC1_CS3_MASK   (3<<6)
+
+#define S3C2440_DSC1_CS2        (S3C2440_SELECT_DSC1 | 4)
+#define S3C2440_DSC1_CS2_10mA   (0<<4)
+#define S3C2440_DSC1_CS2_8mA    (1<<4)
+#define S3C2440_DSC1_CS2_6mA    (2<<4)
+#define S3C2440_DSC1_CS2_4mA    (3<<4)
+#define S3C2440_DSC1_CS2_MASK   (3<<4)
+
+#define S3C2440_DSC1_CS1        (S3C2440_SELECT_DSC1 | 2)
+#define S3C2440_DSC1_CS1_10mA   (0<<2)
+#define S3C2440_DSC1_CS1_8mA    (1<<2)
+#define S3C2440_DSC1_CS1_6mA    (2<<2)
+#define S3C2440_DSC1_CS1_4mA    (3<<2)
+#define S3C2440_DSC1_CS1_MASK   (3<<2)
+
+#define S3C2440_DSC1_CS0        (S3C2440_SELECT_DSC1 | 0)
+#define S3C2440_DSC1_CS0_10mA   (0<<0)
+#define S3C2440_DSC1_CS0_8mA    (1<<0)
+#define S3C2440_DSC1_CS0_6mA    (2<<0)
+#define S3C2440_DSC1_CS0_4mA    (3<<0)
+#define S3C2440_DSC1_CS0_MASK   (3<<0)
+
+#endif /* CONFIG_CPU_S3C2440 */
+
+#endif /* __ASM_ARCH_REGS_DSC_H */
+
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h b/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h
new file mode 100644 (file)
index 0000000..cac1ad6
--- /dev/null
@@ -0,0 +1,602 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-gpio.h
+ *
+ * Copyright (c) 2003-2004 Simtec Electronics <linux@simtec.co.uk>
+ *     http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 GPIO register definitions
+*/
+
+
+#ifndef __ASM_ARCH_REGS_GPIO_H
+#define __ASM_ARCH_REGS_GPIO_H
+
+#include <mach/gpio-nrs.h>
+
+#define S3C24XX_MISCCR         S3C24XX_GPIOREG2(0x80)
+
+/* general configuration options */
+
+#define S3C2410_GPIO_LEAVE   (0xFFFFFFFF)
+#define S3C2410_GPIO_INPUT   (0xFFFFFFF0)      /* not available on A */
+#define S3C2410_GPIO_OUTPUT  (0xFFFFFFF1)
+#define S3C2410_GPIO_IRQ     (0xFFFFFFF2)      /* not available for all */
+#define S3C2410_GPIO_SFN2    (0xFFFFFFF2)      /* bank A => addr/cs/nand */
+#define S3C2410_GPIO_SFN3    (0xFFFFFFF3)      /* not available on A */
+
+/* register address for the GPIO registers.
+ * S3C24XX_GPIOREG2 is for the second set of registers in the
+ * GPIO which move between s3c2410 and s3c2412 type systems */
+
+#define S3C2410_GPIOREG(x) ((x) + S3C24XX_VA_GPIO)
+#define S3C24XX_GPIOREG2(x) ((x) + S3C24XX_VA_GPIO2)
+
+
+/* configure GPIO ports A..G */
+
+/* port A - S3C2410: 22bits, zero in bit X makes pin X output
+ * 1 makes port special function, this is default
+*/
+#define S3C2410_GPACON    S3C2410_GPIOREG(0x00)
+#define S3C2410_GPADAT    S3C2410_GPIOREG(0x04)
+
+#define S3C2410_GPA0_ADDR0   (1<<0)
+#define S3C2410_GPA1_ADDR16  (1<<1)
+#define S3C2410_GPA2_ADDR17  (1<<2)
+#define S3C2410_GPA3_ADDR18  (1<<3)
+#define S3C2410_GPA4_ADDR19  (1<<4)
+#define S3C2410_GPA5_ADDR20  (1<<5)
+#define S3C2410_GPA6_ADDR21  (1<<6)
+#define S3C2410_GPA7_ADDR22  (1<<7)
+#define S3C2410_GPA8_ADDR23  (1<<8)
+#define S3C2410_GPA9_ADDR24  (1<<9)
+#define S3C2410_GPA10_ADDR25 (1<<10)
+#define S3C2410_GPA11_ADDR26 (1<<11)
+#define S3C2410_GPA12_nGCS1  (1<<12)
+#define S3C2410_GPA13_nGCS2  (1<<13)
+#define S3C2410_GPA14_nGCS3  (1<<14)
+#define S3C2410_GPA15_nGCS4  (1<<15)
+#define S3C2410_GPA16_nGCS5  (1<<16)
+#define S3C2410_GPA17_CLE    (1<<17)
+#define S3C2410_GPA18_ALE    (1<<18)
+#define S3C2410_GPA19_nFWE   (1<<19)
+#define S3C2410_GPA20_nFRE   (1<<20)
+#define S3C2410_GPA21_nRSTOUT (1<<21)
+#define S3C2410_GPA22_nFCE   (1<<22)
+
+/* 0x08 and 0x0c are reserved on S3C2410 */
+
+/* S3C2410:
+ * GPB is 10 IO pins, each configured by 2 bits each in GPBCON.
+ *   00 = input, 01 = output, 10=special function, 11=reserved
+
+ * bit 0,1 = pin 0, 2,3= pin 1...
+ *
+ * CPBUP = pull up resistor control, 1=disabled, 0=enabled
+*/
+
+#define S3C2410_GPBCON    S3C2410_GPIOREG(0x10)
+#define S3C2410_GPBDAT    S3C2410_GPIOREG(0x14)
+#define S3C2410_GPBUP     S3C2410_GPIOREG(0x18)
+
+/* no i/o pin in port b can have value 3 (unless it is a s3c2443) ! */
+
+#define S3C2410_GPB0_TOUT0   (0x02 << 0)
+
+#define S3C2410_GPB1_TOUT1   (0x02 << 2)
+
+#define S3C2410_GPB2_TOUT2   (0x02 << 4)
+
+#define S3C2410_GPB3_TOUT3   (0x02 << 6)
+
+#define S3C2410_GPB4_TCLK0   (0x02 << 8)
+#define S3C2410_GPB4_MASK    (0x03 << 8)
+
+#define S3C2410_GPB5_nXBACK  (0x02 << 10)
+#define S3C2443_GPB5_XBACK   (0x03 << 10)
+
+#define S3C2410_GPB6_nXBREQ  (0x02 << 12)
+#define S3C2443_GPB6_XBREQ   (0x03 << 12)
+
+#define S3C2410_GPB7_nXDACK1 (0x02 << 14)
+#define S3C2443_GPB7_XDACK1  (0x03 << 14)
+
+#define S3C2410_GPB8_nXDREQ1 (0x02 << 16)
+
+#define S3C2410_GPB9_nXDACK0 (0x02 << 18)
+#define S3C2443_GPB9_XDACK0  (0x03 << 18)
+
+#define S3C2410_GPB10_nXDRE0 (0x02 << 20)
+#define S3C2443_GPB10_XDREQ0 (0x03 << 20)
+
+#define S3C2410_GPB_PUPDIS(x)  (1<<(x))
+
+/* Port C consits of 16 GPIO/Special function
+ *
+ * almost identical setup to port b, but the special functions are mostly
+ * to do with the video system's sync/etc.
+*/
+
+#define S3C2410_GPCCON    S3C2410_GPIOREG(0x20)
+#define S3C2410_GPCDAT    S3C2410_GPIOREG(0x24)
+#define S3C2410_GPCUP     S3C2410_GPIOREG(0x28)
+#define S3C2410_GPC0_LEND      (0x02 << 0)
+#define S3C2410_GPC1_VCLK      (0x02 << 2)
+#define S3C2410_GPC2_VLINE     (0x02 << 4)
+#define S3C2410_GPC3_VFRAME    (0x02 << 6)
+#define S3C2410_GPC4_VM                (0x02 << 8)
+#define S3C2410_GPC5_LCDVF0    (0x02 << 10)
+#define S3C2410_GPC6_LCDVF1    (0x02 << 12)
+#define S3C2410_GPC7_LCDVF2    (0x02 << 14)
+#define S3C2410_GPC8_VD0       (0x02 << 16)
+#define S3C2410_GPC9_VD1       (0x02 << 18)
+#define S3C2410_GPC10_VD2      (0x02 << 20)
+#define S3C2410_GPC11_VD3      (0x02 << 22)
+#define S3C2410_GPC12_VD4      (0x02 << 24)
+#define S3C2410_GPC13_VD5      (0x02 << 26)
+#define S3C2410_GPC14_VD6      (0x02 << 28)
+#define S3C2410_GPC15_VD7      (0x02 << 30)
+#define S3C2410_GPC_PUPDIS(x)  (1<<(x))
+
+/*
+ * S3C2410: Port D consists of 16 GPIO/Special function
+ *
+ * almost identical setup to port b, but the special functions are mostly
+ * to do with the video system's data.
+ *
+ * almost identical setup to port c
+*/
+
+#define S3C2410_GPDCON    S3C2410_GPIOREG(0x30)
+#define S3C2410_GPDDAT    S3C2410_GPIOREG(0x34)
+#define S3C2410_GPDUP     S3C2410_GPIOREG(0x38)
+
+#define S3C2410_GPD0_VD8       (0x02 << 0)
+#define S3C2442_GPD0_nSPICS1   (0x03 << 0)
+
+#define S3C2410_GPD1_VD9       (0x02 << 2)
+#define S3C2442_GPD1_SPICLK1   (0x03 << 2)
+
+#define S3C2410_GPD2_VD10      (0x02 << 4)
+
+#define S3C2410_GPD3_VD11      (0x02 << 6)
+
+#define S3C2410_GPD4_VD12      (0x02 << 8)
+
+#define S3C2410_GPD5_VD13      (0x02 << 10)
+
+#define S3C2410_GPD6_VD14      (0x02 << 12)
+
+#define S3C2410_GPD7_VD15      (0x02 << 14)
+
+#define S3C2410_GPD8_VD16      (0x02 << 16)
+#define S3C2440_GPD8_SPIMISO1  (0x03 << 16)
+
+#define S3C2410_GPD9_VD17      (0x02 << 18)
+#define S3C2440_GPD9_SPIMOSI1  (0x03 << 18)
+
+#define S3C2410_GPD10_VD18     (0x02 << 20)
+#define S3C2440_GPD10_SPICLK1  (0x03 << 20)
+
+#define S3C2410_GPD11_VD19     (0x02 << 22)
+
+#define S3C2410_GPD12_VD20     (0x02 << 24)
+
+#define S3C2410_GPD13_VD21     (0x02 << 26)
+
+#define S3C2410_GPD14_VD22     (0x02 << 28)
+#define S3C2410_GPD14_nSS1     (0x03 << 28)
+
+#define S3C2410_GPD15_VD23     (0x02 << 30)
+#define S3C2410_GPD15_nSS0     (0x03 << 30)
+
+#define S3C2410_GPD_PUPDIS(x)  (1<<(x))
+
+/* S3C2410:
+ * Port E consists of 16 GPIO/Special function
+ *
+ * again, the same as port B, but dealing with I2S, SDI, and
+ * more miscellaneous functions
+ *
+ * GPIO / interrupt inputs
+*/
+
+#define S3C2410_GPECON    S3C2410_GPIOREG(0x40)
+#define S3C2410_GPEDAT    S3C2410_GPIOREG(0x44)
+#define S3C2410_GPEUP     S3C2410_GPIOREG(0x48)
+
+#define S3C2410_GPE0_I2SLRCK   (0x02 << 0)
+#define S3C2443_GPE0_AC_nRESET (0x03 << 0)
+#define S3C2410_GPE0_MASK      (0x03 << 0)
+
+#define S3C2410_GPE1_I2SSCLK   (0x02 << 2)
+#define S3C2443_GPE1_AC_SYNC   (0x03 << 2)
+#define S3C2410_GPE1_MASK      (0x03 << 2)
+
+#define S3C2410_GPE2_CDCLK     (0x02 << 4)
+#define S3C2443_GPE2_AC_BITCLK (0x03 << 4)
+
+#define S3C2410_GPE3_I2SSDI    (0x02 << 6)
+#define S3C2443_GPE3_AC_SDI    (0x03 << 6)
+#define S3C2410_GPE3_nSS0      (0x03 << 6)
+#define S3C2410_GPE3_MASK      (0x03 << 6)
+
+#define S3C2410_GPE4_I2SSDO    (0x02 << 8)
+#define S3C2443_GPE4_AC_SDO    (0x03 << 8)
+#define S3C2410_GPE4_I2SSDI    (0x03 << 8)
+#define S3C2410_GPE4_MASK      (0x03 << 8)
+
+#define S3C2410_GPE5_SDCLK     (0x02 << 10)
+#define S3C2443_GPE5_SD1_CLK   (0x02 << 10)
+#define S3C2443_GPE5_AC_BITCLK (0x03 << 10)
+
+#define S3C2410_GPE6_SDCMD     (0x02 << 12)
+#define S3C2443_GPE6_SD1_CMD   (0x02 << 12)
+#define S3C2443_GPE6_AC_SDI    (0x03 << 12)
+
+#define S3C2410_GPE7_SDDAT0    (0x02 << 14)
+#define S3C2443_GPE5_SD1_DAT0  (0x02 << 14)
+#define S3C2443_GPE7_AC_SDO    (0x03 << 14)
+
+#define S3C2410_GPE8_SDDAT1    (0x02 << 16)
+#define S3C2443_GPE8_SD1_DAT1  (0x02 << 16)
+#define S3C2443_GPE8_AC_SYNC   (0x03 << 16)
+
+#define S3C2410_GPE9_SDDAT2    (0x02 << 18)
+#define S3C2443_GPE9_SD1_DAT2  (0x02 << 18)
+#define S3C2443_GPE9_AC_nRESET (0x03 << 18)
+
+#define S3C2410_GPE10_SDDAT3   (0x02 << 20)
+#define S3C2443_GPE10_SD1_DAT3 (0x02 << 20)
+
+#define S3C2410_GPE11_SPIMISO0 (0x02 << 22)
+
+#define S3C2410_GPE12_SPIMOSI0 (0x02 << 24)
+
+#define S3C2410_GPE13_SPICLK0  (0x02 << 26)
+
+#define S3C2410_GPE14_IICSCL   (0x02 << 28)
+#define S3C2410_GPE14_MASK     (0x03 << 28)
+
+#define S3C2410_GPE15_IICSDA   (0x02 << 30)
+#define S3C2410_GPE15_MASK     (0x03 << 30)
+
+#define S3C2440_GPE0_ACSYNC    (0x03 << 0)
+#define S3C2440_GPE1_ACBITCLK  (0x03 << 2)
+#define S3C2440_GPE2_ACRESET   (0x03 << 4)
+#define S3C2440_GPE3_ACIN      (0x03 << 6)
+#define S3C2440_GPE4_ACOUT     (0x03 << 8)
+
+#define S3C2410_GPE_PUPDIS(x)  (1<<(x))
+
+/* S3C2410:
+ * Port F consists of 8 GPIO/Special function
+ *
+ * GPIO / interrupt inputs
+ *
+ * GPFCON has 2 bits for each of the input pins on port F
+ *   00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 undefined
+ *
+ * pull up works like all other ports.
+ *
+ * GPIO/serial/misc pins
+*/
+
+#define S3C2410_GPFCON    S3C2410_GPIOREG(0x50)
+#define S3C2410_GPFDAT    S3C2410_GPIOREG(0x54)
+#define S3C2410_GPFUP     S3C2410_GPIOREG(0x58)
+
+#define S3C2410_GPF0_EINT0  (0x02 << 0)
+#define S3C2410_GPF1_EINT1  (0x02 << 2)
+#define S3C2410_GPF2_EINT2  (0x02 << 4)
+#define S3C2410_GPF3_EINT3  (0x02 << 6)
+#define S3C2410_GPF4_EINT4  (0x02 << 8)
+#define S3C2410_GPF5_EINT5  (0x02 << 10)
+#define S3C2410_GPF6_EINT6  (0x02 << 12)
+#define S3C2410_GPF7_EINT7  (0x02 << 14)
+#define S3C2410_GPF_PUPDIS(x)  (1<<(x))
+
+/* S3C2410:
+ * Port G consists of 8 GPIO/IRQ/Special function
+ *
+ * GPGCON has 2 bits for each of the input pins on port F
+ *   00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 special func
+ *
+ * pull up works like all other ports.
+*/
+
+#define S3C2410_GPGCON    S3C2410_GPIOREG(0x60)
+#define S3C2410_GPGDAT    S3C2410_GPIOREG(0x64)
+#define S3C2410_GPGUP     S3C2410_GPIOREG(0x68)
+
+#define S3C2410_GPG0_EINT8    (0x02 << 0)
+
+#define S3C2410_GPG1_EINT9    (0x02 << 2)
+
+#define S3C2410_GPG2_EINT10   (0x02 << 4)
+#define S3C2410_GPG2_nSS0     (0x03 << 4)
+
+#define S3C2410_GPG3_EINT11   (0x02 << 6)
+#define S3C2410_GPG3_nSS1     (0x03 << 6)
+
+#define S3C2410_GPG4_EINT12   (0x02 << 8)
+#define S3C2410_GPG4_LCDPWREN (0x03 << 8)
+#define S3C2443_GPG4_LCDPWRDN (0x03 << 8)
+
+#define S3C2410_GPG5_EINT13   (0x02 << 10)
+#define S3C2410_GPG5_SPIMISO1 (0x03 << 10)     /* not s3c2443 */
+
+#define S3C2410_GPG6_EINT14   (0x02 << 12)
+#define S3C2410_GPG6_SPIMOSI1 (0x03 << 12)
+
+#define S3C2410_GPG7_EINT15   (0x02 << 14)
+#define S3C2410_GPG7_SPICLK1  (0x03 << 14)
+
+#define S3C2410_GPG8_EINT16   (0x02 << 16)
+
+#define S3C2410_GPG9_EINT17   (0x02 << 18)
+
+#define S3C2410_GPG10_EINT18  (0x02 << 20)
+
+#define S3C2410_GPG11_EINT19  (0x02 << 22)
+#define S3C2410_GPG11_TCLK1   (0x03 << 22)
+#define S3C2443_GPG11_CF_nIREQ (0x03 << 22)
+
+#define S3C2410_GPG12_EINT20  (0x02 << 24)
+#define S3C2410_GPG12_XMON    (0x03 << 24)
+#define S3C2442_GPG12_nSPICS0 (0x03 << 24)
+#define S3C2443_GPG12_nINPACK (0x03 << 24)
+
+#define S3C2410_GPG13_EINT21  (0x02 << 26)
+#define S3C2410_GPG13_nXPON   (0x03 << 26)
+#define S3C2443_GPG13_CF_nREG (0x03 << 26)
+
+#define S3C2410_GPG14_EINT22  (0x02 << 28)
+#define S3C2410_GPG14_YMON    (0x03 << 28)
+#define S3C2443_GPG14_CF_RESET (0x03 << 28)
+
+#define S3C2410_GPG15_EINT23  (0x02 << 30)
+#define S3C2410_GPG15_nYPON   (0x03 << 30)
+#define S3C2443_GPG15_CF_PWR  (0x03 << 30)
+
+#define S3C2410_GPG_PUPDIS(x)  (1<<(x))
+
+/* Port H consists of11 GPIO/serial/Misc pins
+ *
+ * GPGCON has 2 bits for each of the input pins on port F
+ *   00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 special func
+ *
+ * pull up works like all other ports.
+*/
+
+#define S3C2410_GPHCON    S3C2410_GPIOREG(0x70)
+#define S3C2410_GPHDAT    S3C2410_GPIOREG(0x74)
+#define S3C2410_GPHUP     S3C2410_GPIOREG(0x78)
+
+#define S3C2410_GPH0_nCTS0  (0x02 << 0)
+#define S3C2416_GPH0_TXD0  (0x02 << 0)
+
+#define S3C2410_GPH1_nRTS0  (0x02 << 2)
+#define S3C2416_GPH1_RXD0  (0x02 << 2)
+
+#define S3C2410_GPH2_TXD0   (0x02 << 4)
+#define S3C2416_GPH2_TXD1   (0x02 << 4)
+
+#define S3C2410_GPH3_RXD0   (0x02 << 6)
+#define S3C2416_GPH3_RXD1   (0x02 << 6)
+
+#define S3C2410_GPH4_TXD1   (0x02 << 8)
+#define S3C2416_GPH4_TXD2   (0x02 << 8)
+
+#define S3C2410_GPH5_RXD1   (0x02 << 10)
+#define S3C2416_GPH5_RXD2   (0x02 << 10)
+
+#define S3C2410_GPH6_TXD2   (0x02 << 12)
+#define S3C2416_GPH6_TXD3   (0x02 << 12)
+#define S3C2410_GPH6_nRTS1  (0x03 << 12)
+#define S3C2416_GPH6_nRTS2  (0x03 << 12)
+
+#define S3C2410_GPH7_RXD2   (0x02 << 14)
+#define S3C2416_GPH7_RXD3   (0x02 << 14)
+#define S3C2410_GPH7_nCTS1  (0x03 << 14)
+#define S3C2416_GPH7_nCTS2  (0x03 << 14)
+
+#define S3C2410_GPH8_UCLK   (0x02 << 16)
+#define S3C2416_GPH8_nCTS0  (0x02 << 16)
+
+#define S3C2410_GPH9_CLKOUT0  (0x02 << 18)
+#define S3C2442_GPH9_nSPICS0  (0x03 << 18)
+#define S3C2416_GPH9_nRTS0    (0x02 << 18)
+
+#define S3C2410_GPH10_CLKOUT1 (0x02 << 20)
+#define S3C2416_GPH10_nCTS1   (0x02 << 20)
+
+#define S3C2416_GPH11_nRTS1   (0x02 << 22)
+
+#define S3C2416_GPH12_EXTUARTCLK (0x02 << 24)
+
+#define S3C2416_GPH13_CLKOUT0 (0x02 << 26)
+
+#define S3C2416_GPH14_CLKOUT1 (0x02 << 28)
+
+/* The S3C2412 and S3C2413 move the GPJ register set to after
+ * GPH, which means all registers after 0x80 are now offset by 0x10
+ * for the 2412/2413 from the 2410/2440/2442
+*/
+
+/* S3C2443 and above */
+#define S3C2440_GPJCON    S3C2410_GPIOREG(0xD0)
+#define S3C2440_GPJDAT    S3C2410_GPIOREG(0xD4)
+#define S3C2440_GPJUP     S3C2410_GPIOREG(0xD8)
+
+#define S3C2443_GPKCON    S3C2410_GPIOREG(0xE0)
+#define S3C2443_GPKDAT    S3C2410_GPIOREG(0xE4)
+#define S3C2443_GPKUP     S3C2410_GPIOREG(0xE8)
+
+#define S3C2443_GPLCON    S3C2410_GPIOREG(0xF0)
+#define S3C2443_GPLDAT    S3C2410_GPIOREG(0xF4)
+#define S3C2443_GPLUP     S3C2410_GPIOREG(0xF8)
+
+#define S3C2443_GPMCON    S3C2410_GPIOREG(0x100)
+#define S3C2443_GPMDAT    S3C2410_GPIOREG(0x104)
+#define S3C2443_GPMUP     S3C2410_GPIOREG(0x108)
+
+/* miscellaneous control */
+#define S3C2410_MISCCR    S3C2410_GPIOREG(0x80)
+#define S3C2410_DCLKCON           S3C2410_GPIOREG(0x84)
+
+#define S3C24XX_DCLKCON           S3C24XX_GPIOREG2(0x84)
+
+/* see clock.h for dclk definitions */
+
+/* pullup control on databus */
+#define S3C2410_MISCCR_SPUCR_HEN    (0<<0)
+#define S3C2410_MISCCR_SPUCR_HDIS   (1<<0)
+#define S3C2410_MISCCR_SPUCR_LEN    (0<<1)
+#define S3C2410_MISCCR_SPUCR_LDIS   (1<<1)
+
+#define S3C2410_MISCCR_USBDEV      (0<<3)
+#define S3C2410_MISCCR_USBHOST     (1<<3)
+
+#define S3C2410_MISCCR_CLK0_MPLL    (0<<4)
+#define S3C2410_MISCCR_CLK0_UPLL    (1<<4)
+#define S3C2410_MISCCR_CLK0_FCLK    (2<<4)
+#define S3C2410_MISCCR_CLK0_HCLK    (3<<4)
+#define S3C2410_MISCCR_CLK0_PCLK    (4<<4)
+#define S3C2410_MISCCR_CLK0_DCLK0   (5<<4)
+#define S3C2410_MISCCR_CLK0_MASK    (7<<4)
+
+#define S3C2412_MISCCR_CLK0_RTC            (2<<4)
+
+#define S3C2410_MISCCR_CLK1_MPLL    (0<<8)
+#define S3C2410_MISCCR_CLK1_UPLL    (1<<8)
+#define S3C2410_MISCCR_CLK1_FCLK    (2<<8)
+#define S3C2410_MISCCR_CLK1_HCLK    (3<<8)
+#define S3C2410_MISCCR_CLK1_PCLK    (4<<8)
+#define S3C2410_MISCCR_CLK1_DCLK1   (5<<8)
+#define S3C2410_MISCCR_CLK1_MASK    (7<<8)
+
+#define S3C2412_MISCCR_CLK1_CLKsrc  (0<<8)
+
+#define S3C2410_MISCCR_USBSUSPND0   (1<<12)
+#define S3C2416_MISCCR_SEL_SUSPND   (1<<12)
+#define S3C2410_MISCCR_USBSUSPND1   (1<<13)
+
+#define S3C2410_MISCCR_nRSTCON     (1<<16)
+
+#define S3C2410_MISCCR_nEN_SCLK0    (1<<17)
+#define S3C2410_MISCCR_nEN_SCLK1    (1<<18)
+#define S3C2410_MISCCR_nEN_SCLKE    (1<<19)    /* not 2412 */
+#define S3C2410_MISCCR_SDSLEEP     (7<<17)
+
+#define S3C2416_MISCCR_FLT_I2C      (1<<24)
+#define S3C2416_MISCCR_HSSPI_EN2    (1<<31)
+
+/* external interrupt control... */
+/* S3C2410_EXTINT0 -> irq sense control for EINT0..EINT7
+ * S3C2410_EXTINT1 -> irq sense control for EINT8..EINT15
+ * S3C2410_EXTINT2 -> irq sense control for EINT16..EINT23
+ *
+ * note S3C2410_EXTINT2 has filtering options for EINT16..EINT23
+ *
+ * Samsung datasheet p9-25
+*/
+#define S3C2410_EXTINT0           S3C2410_GPIOREG(0x88)
+#define S3C2410_EXTINT1           S3C2410_GPIOREG(0x8C)
+#define S3C2410_EXTINT2           S3C2410_GPIOREG(0x90)
+
+#define S3C24XX_EXTINT0           S3C24XX_GPIOREG2(0x88)
+#define S3C24XX_EXTINT1           S3C24XX_GPIOREG2(0x8C)
+#define S3C24XX_EXTINT2           S3C24XX_GPIOREG2(0x90)
+
+/* interrupt filtering conrrol for EINT16..EINT23 */
+#define S3C2410_EINFLT0           S3C2410_GPIOREG(0x94)
+#define S3C2410_EINFLT1           S3C2410_GPIOREG(0x98)
+#define S3C2410_EINFLT2           S3C2410_GPIOREG(0x9C)
+#define S3C2410_EINFLT3           S3C2410_GPIOREG(0xA0)
+
+#define S3C24XX_EINFLT0           S3C24XX_GPIOREG2(0x94)
+#define S3C24XX_EINFLT1           S3C24XX_GPIOREG2(0x98)
+#define S3C24XX_EINFLT2           S3C24XX_GPIOREG2(0x9C)
+#define S3C24XX_EINFLT3           S3C24XX_GPIOREG2(0xA0)
+
+/* values for interrupt filtering */
+#define S3C2410_EINTFLT_PCLK           (0x00)
+#define S3C2410_EINTFLT_EXTCLK         (1<<7)
+#define S3C2410_EINTFLT_WIDTHMSK(x)    ((x) & 0x3f)
+
+/* removed EINTxxxx defs from here, not meant for this */
+
+/* GSTATUS have miscellaneous information in them
+ *
+ * These move between s3c2410 and s3c2412 style systems.
+ */
+
+#define S3C2410_GSTATUS0   S3C2410_GPIOREG(0x0AC)
+#define S3C2410_GSTATUS1   S3C2410_GPIOREG(0x0B0)
+#define S3C2410_GSTATUS2   S3C2410_GPIOREG(0x0B4)
+#define S3C2410_GSTATUS3   S3C2410_GPIOREG(0x0B8)
+#define S3C2410_GSTATUS4   S3C2410_GPIOREG(0x0BC)
+
+#define S3C2412_GSTATUS0   S3C2410_GPIOREG(0x0BC)
+#define S3C2412_GSTATUS1   S3C2410_GPIOREG(0x0C0)
+#define S3C2412_GSTATUS2   S3C2410_GPIOREG(0x0C4)
+#define S3C2412_GSTATUS3   S3C2410_GPIOREG(0x0C8)
+#define S3C2412_GSTATUS4   S3C2410_GPIOREG(0x0CC)
+
+#define S3C24XX_GSTATUS0   S3C24XX_GPIOREG2(0x0AC)
+#define S3C24XX_GSTATUS1   S3C24XX_GPIOREG2(0x0B0)
+#define S3C24XX_GSTATUS2   S3C24XX_GPIOREG2(0x0B4)
+#define S3C24XX_GSTATUS3   S3C24XX_GPIOREG2(0x0B8)
+#define S3C24XX_GSTATUS4   S3C24XX_GPIOREG2(0x0BC)
+
+#define S3C2410_GSTATUS0_nWAIT    (1<<3)
+#define S3C2410_GSTATUS0_NCON     (1<<2)
+#define S3C2410_GSTATUS0_RnB      (1<<1)
+#define S3C2410_GSTATUS0_nBATTFLT  (1<<0)
+
+#define S3C2410_GSTATUS1_IDMASK           (0xffff0000)
+#define S3C2410_GSTATUS1_2410     (0x32410000)
+#define S3C2410_GSTATUS1_2412     (0x32412001)
+#define S3C2410_GSTATUS1_2416     (0x32416003)
+#define S3C2410_GSTATUS1_2440     (0x32440000)
+#define S3C2410_GSTATUS1_2442     (0x32440aaa)
+/* some 2416 CPUs report this value also */
+#define S3C2410_GSTATUS1_2450     (0x32450003)
+
+#define S3C2410_GSTATUS2_WTRESET   (1<<2)
+#define S3C2410_GSTATUS2_OFFRESET  (1<<1)
+#define S3C2410_GSTATUS2_PONRESET  (1<<0)
+
+/* 2412/2413 sleep configuration registers */
+
+#define S3C2412_GPBSLPCON      S3C2410_GPIOREG(0x1C)
+#define S3C2412_GPCSLPCON      S3C2410_GPIOREG(0x2C)
+#define S3C2412_GPDSLPCON      S3C2410_GPIOREG(0x3C)
+#define S3C2412_GPFSLPCON      S3C2410_GPIOREG(0x5C)
+#define S3C2412_GPGSLPCON      S3C2410_GPIOREG(0x6C)
+#define S3C2412_GPHSLPCON      S3C2410_GPIOREG(0x7C)
+
+/* definitions for each pin bit */
+#define S3C2412_GPIO_SLPCON_LOW         ( 0x00 )
+#define S3C2412_GPIO_SLPCON_HIGH ( 0x01 )
+#define S3C2412_GPIO_SLPCON_IN   ( 0x02 )
+#define S3C2412_GPIO_SLPCON_PULL ( 0x03 )
+
+#define S3C2412_SLPCON_LOW(x)  ( 0x00 << ((x) * 2))
+#define S3C2412_SLPCON_HIGH(x) ( 0x01 << ((x) * 2))
+#define S3C2412_SLPCON_IN(x)   ( 0x02 << ((x) * 2))
+#define S3C2412_SLPCON_PULL(x) ( 0x03 << ((x) * 2))
+#define S3C2412_SLPCON_EINT(x) ( 0x02 << ((x) * 2))  /* only IRQ pins */
+#define S3C2412_SLPCON_MASK(x) ( 0x03 << ((x) * 2))
+
+#define S3C2412_SLPCON_ALL_LOW (0x0)
+#define S3C2412_SLPCON_ALL_HIGH        (0x11111111 | 0x44444444)
+#define S3C2412_SLPCON_ALL_IN          (0x22222222 | 0x88888888)
+#define S3C2412_SLPCON_ALL_PULL        (0x33333333)
+
+#endif /* __ASM_ARCH_REGS_GPIO_H */
+
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-gpioj.h b/arch/arm/mach-s3c24xx/include/mach/regs-gpioj.h
new file mode 100644 (file)
index 0000000..19575e0
--- /dev/null
@@ -0,0 +1,70 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
+ *
+ * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
+ *                   http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2440 GPIO J register definitions
+*/
+
+
+#ifndef __ASM_ARCH_REGS_GPIOJ_H
+#define __ASM_ARCH_REGS_GPIOJ_H "gpioj"
+
+/* Port J consists of 13 GPIO/Camera pins
+ *
+ * GPJCON has 2 bits for each of the input pins on port F
+ *   00 = 0 input, 1 output, 2 Camera
+ *
+ * pull up works like all other ports.
+*/
+
+#define S3C2413_GPJCON         S3C2410_GPIOREG(0x80)
+#define S3C2413_GPJDAT         S3C2410_GPIOREG(0x84)
+#define S3C2413_GPJUP          S3C2410_GPIOREG(0x88)
+#define S3C2413_GPJSLPCON      S3C2410_GPIOREG(0x8C)
+
+#define S3C2440_GPJ0_OUTP       (0x01 << 0)
+#define S3C2440_GPJ0_CAMDATA0   (0x02 << 0)
+
+#define S3C2440_GPJ1_OUTP       (0x01 << 2)
+#define S3C2440_GPJ1_CAMDATA1   (0x02 << 2)
+
+#define S3C2440_GPJ2_OUTP       (0x01 << 4)
+#define S3C2440_GPJ2_CAMDATA2   (0x02 << 4)
+
+#define S3C2440_GPJ3_OUTP       (0x01 << 6)
+#define S3C2440_GPJ3_CAMDATA3   (0x02 << 6)
+
+#define S3C2440_GPJ4_OUTP       (0x01 << 8)
+#define S3C2440_GPJ4_CAMDATA4   (0x02 << 8)
+
+#define S3C2440_GPJ5_OUTP       (0x01 << 10)
+#define S3C2440_GPJ5_CAMDATA5   (0x02 << 10)
+
+#define S3C2440_GPJ6_OUTP       (0x01 << 12)
+#define S3C2440_GPJ6_CAMDATA6   (0x02 << 12)
+
+#define S3C2440_GPJ7_OUTP       (0x01 << 14)
+#define S3C2440_GPJ7_CAMDATA7   (0x02 << 14)
+
+#define S3C2440_GPJ8_OUTP       (0x01 << 16)
+#define S3C2440_GPJ8_CAMPCLK    (0x02 << 16)
+
+#define S3C2440_GPJ9_OUTP       (0x01 << 18)
+#define S3C2440_GPJ9_CAMVSYNC   (0x02 << 18)
+
+#define S3C2440_GPJ10_OUTP      (0x01 << 20)
+#define S3C2440_GPJ10_CAMHREF   (0x02 << 20)
+
+#define S3C2440_GPJ11_OUTP      (0x01 << 22)
+#define S3C2440_GPJ11_CAMCLKOUT (0x02 << 22)
+
+#define S3C2440_GPJ12_OUTP      (0x01 << 24)
+#define S3C2440_GPJ12_CAMRESET  (0x02 << 24)
+
+#endif /* __ASM_ARCH_REGS_GPIOJ_H */
+
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-irq.h b/arch/arm/mach-s3c24xx/include/mach/regs-irq.h
new file mode 100644 (file)
index 0000000..0f07ba3
--- /dev/null
@@ -0,0 +1,53 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-irq.h
+ *
+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
+ *                   http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+
+#ifndef ___ASM_ARCH_REGS_IRQ_H
+#define ___ASM_ARCH_REGS_IRQ_H
+
+/* interrupt controller */
+
+#define S3C2410_IRQREG(x)   ((x) + S3C24XX_VA_IRQ)
+#define S3C2410_EINTREG(x)  ((x) + S3C24XX_VA_GPIO)
+#define S3C24XX_EINTREG(x)  ((x) + S3C24XX_VA_GPIO2)
+
+#define S3C2410_SRCPND        S3C2410_IRQREG(0x000)
+#define S3C2410_INTMOD        S3C2410_IRQREG(0x004)
+#define S3C2410_INTMSK        S3C2410_IRQREG(0x008)
+#define S3C2410_PRIORITY       S3C2410_IRQREG(0x00C)
+#define S3C2410_INTPND        S3C2410_IRQREG(0x010)
+#define S3C2410_INTOFFSET      S3C2410_IRQREG(0x014)
+#define S3C2410_SUBSRCPND      S3C2410_IRQREG(0x018)
+#define S3C2410_INTSUBMSK      S3C2410_IRQREG(0x01C)
+
+#define S3C2416_PRIORITY_MODE1         S3C2410_IRQREG(0x030)
+#define S3C2416_PRIORITY_UPDATE1       S3C2410_IRQREG(0x034)
+#define S3C2416_SRCPND2                        S3C2410_IRQREG(0x040)
+#define S3C2416_INTMOD2                        S3C2410_IRQREG(0x044)
+#define S3C2416_INTMSK2                        S3C2410_IRQREG(0x048)
+#define S3C2416_INTPND2                        S3C2410_IRQREG(0x050)
+#define S3C2416_INTOFFSET2             S3C2410_IRQREG(0x054)
+#define S3C2416_PRIORITY_MODE2         S3C2410_IRQREG(0x070)
+#define S3C2416_PRIORITY_UPDATE2       S3C2410_IRQREG(0x074)
+
+/* mask: 0=enable, 1=disable
+ * 1 bit EINT, 4=EINT4, 23=EINT23
+ * EINT0,1,2,3 are not handled here.
+*/
+
+#define S3C2410_EINTMASK       S3C2410_EINTREG(0x0A4)
+#define S3C2410_EINTPEND       S3C2410_EINTREG(0X0A8)
+#define S3C2412_EINTMASK       S3C2410_EINTREG(0x0B4)
+#define S3C2412_EINTPEND       S3C2410_EINTREG(0X0B8)
+
+#define S3C24XX_EINTMASK       S3C24XX_EINTREG(0x0A4)
+#define S3C24XX_EINTPEND       S3C24XX_EINTREG(0X0A8)
+
+#endif /* ___ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-lcd.h b/arch/arm/mach-s3c24xx/include/mach/regs-lcd.h
new file mode 100644 (file)
index 0000000..ee8f040
--- /dev/null
@@ -0,0 +1,162 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-lcd.h
+ *
+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
+ *                   http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+
+#ifndef ___ASM_ARCH_REGS_LCD_H
+#define ___ASM_ARCH_REGS_LCD_H
+
+#define S3C2410_LCDREG(x)      (x)
+
+/* LCD control registers */
+#define S3C2410_LCDCON1            S3C2410_LCDREG(0x00)
+#define S3C2410_LCDCON2            S3C2410_LCDREG(0x04)
+#define S3C2410_LCDCON3            S3C2410_LCDREG(0x08)
+#define S3C2410_LCDCON4            S3C2410_LCDREG(0x0C)
+#define S3C2410_LCDCON5            S3C2410_LCDREG(0x10)
+
+#define S3C2410_LCDCON1_CLKVAL(x)  ((x) << 8)
+#define S3C2410_LCDCON1_MMODE     (1<<7)
+#define S3C2410_LCDCON1_DSCAN4    (0<<5)
+#define S3C2410_LCDCON1_STN4      (1<<5)
+#define S3C2410_LCDCON1_STN8      (2<<5)
+#define S3C2410_LCDCON1_TFT       (3<<5)
+
+#define S3C2410_LCDCON1_STN1BPP           (0<<1)
+#define S3C2410_LCDCON1_STN2GREY   (1<<1)
+#define S3C2410_LCDCON1_STN4GREY   (2<<1)
+#define S3C2410_LCDCON1_STN8BPP           (3<<1)
+#define S3C2410_LCDCON1_STN12BPP   (4<<1)
+
+#define S3C2410_LCDCON1_TFT1BPP           (8<<1)
+#define S3C2410_LCDCON1_TFT2BPP           (9<<1)
+#define S3C2410_LCDCON1_TFT4BPP           (10<<1)
+#define S3C2410_LCDCON1_TFT8BPP           (11<<1)
+#define S3C2410_LCDCON1_TFT16BPP   (12<<1)
+#define S3C2410_LCDCON1_TFT24BPP   (13<<1)
+
+#define S3C2410_LCDCON1_ENVID     (1)
+
+#define S3C2410_LCDCON1_MODEMASK    0x1E
+
+#define S3C2410_LCDCON2_VBPD(x)            ((x) << 24)
+#define S3C2410_LCDCON2_LINEVAL(x)  ((x) << 14)
+#define S3C2410_LCDCON2_VFPD(x)            ((x) << 6)
+#define S3C2410_LCDCON2_VSPW(x)            ((x) << 0)
+
+#define S3C2410_LCDCON2_GET_VBPD(x) ( ((x) >> 24) & 0xFF)
+#define S3C2410_LCDCON2_GET_VFPD(x) ( ((x) >>  6) & 0xFF)
+#define S3C2410_LCDCON2_GET_VSPW(x) ( ((x) >>  0) & 0x3F)
+
+#define S3C2410_LCDCON3_HBPD(x)            ((x) << 19)
+#define S3C2410_LCDCON3_WDLY(x)            ((x) << 19)
+#define S3C2410_LCDCON3_HOZVAL(x)   ((x) << 8)
+#define S3C2410_LCDCON3_HFPD(x)            ((x) << 0)
+#define S3C2410_LCDCON3_LINEBLANK(x)((x) << 0)
+
+#define S3C2410_LCDCON3_GET_HBPD(x) ( ((x) >> 19) & 0x7F)
+#define S3C2410_LCDCON3_GET_HFPD(x) ( ((x) >>  0) & 0xFF)
+
+/* LDCCON4 changes for STN mode on the S3C2412 */
+
+#define S3C2410_LCDCON4_MVAL(x)            ((x) << 8)
+#define S3C2410_LCDCON4_HSPW(x)            ((x) << 0)
+#define S3C2410_LCDCON4_WLH(x)     ((x) << 0)
+
+#define S3C2410_LCDCON4_GET_HSPW(x) ( ((x) >>  0) & 0xFF)
+
+#define S3C2410_LCDCON5_BPP24BL            (1<<12)
+#define S3C2410_LCDCON5_FRM565     (1<<11)
+#define S3C2410_LCDCON5_INVVCLK            (1<<10)
+#define S3C2410_LCDCON5_INVVLINE    (1<<9)
+#define S3C2410_LCDCON5_INVVFRAME   (1<<8)
+#define S3C2410_LCDCON5_INVVD      (1<<7)
+#define S3C2410_LCDCON5_INVVDEN            (1<<6)
+#define S3C2410_LCDCON5_INVPWREN    (1<<5)
+#define S3C2410_LCDCON5_INVLEND            (1<<4)
+#define S3C2410_LCDCON5_PWREN      (1<<3)
+#define S3C2410_LCDCON5_ENLEND     (1<<2)
+#define S3C2410_LCDCON5_BSWP       (1<<1)
+#define S3C2410_LCDCON5_HWSWP      (1<<0)
+
+/* framebuffer start addressed */
+#define S3C2410_LCDSADDR1   S3C2410_LCDREG(0x14)
+#define S3C2410_LCDSADDR2   S3C2410_LCDREG(0x18)
+#define S3C2410_LCDSADDR3   S3C2410_LCDREG(0x1C)
+
+#define S3C2410_LCDBANK(x)     ((x) << 21)
+#define S3C2410_LCDBASEU(x)    (x)
+
+#define S3C2410_OFFSIZE(x)     ((x) << 11)
+#define S3C2410_PAGEWIDTH(x)   (x)
+
+/* colour lookup and miscellaneous controls */
+
+#define S3C2410_REDLUT    S3C2410_LCDREG(0x20)
+#define S3C2410_GREENLUT   S3C2410_LCDREG(0x24)
+#define S3C2410_BLUELUT           S3C2410_LCDREG(0x28)
+
+#define S3C2410_DITHMODE   S3C2410_LCDREG(0x4C)
+#define S3C2410_TPAL      S3C2410_LCDREG(0x50)
+
+#define S3C2410_TPAL_EN                (1<<24)
+
+/* interrupt info */
+#define S3C2410_LCDINTPND  S3C2410_LCDREG(0x54)
+#define S3C2410_LCDSRCPND  S3C2410_LCDREG(0x58)
+#define S3C2410_LCDINTMSK  S3C2410_LCDREG(0x5C)
+#define S3C2410_LCDINT_FIWSEL  (1<<2)
+#define        S3C2410_LCDINT_FRSYNC   (1<<1)
+#define S3C2410_LCDINT_FICNT   (1<<0)
+
+/* s3c2442 extra stn registers */
+
+#define S3C2442_REDLUT         S3C2410_LCDREG(0x20)
+#define S3C2442_GREENLUT       S3C2410_LCDREG(0x24)
+#define S3C2442_BLUELUT                S3C2410_LCDREG(0x28)
+#define S3C2442_DITHMODE       S3C2410_LCDREG(0x20)
+
+#define S3C2410_LPCSEL    S3C2410_LCDREG(0x60)
+
+#define S3C2410_TFTPAL(x)  S3C2410_LCDREG((0x400 + (x)*4))
+
+/* S3C2412 registers */
+
+#define S3C2412_TPAL           S3C2410_LCDREG(0x20)
+
+#define S3C2412_LCDINTPND      S3C2410_LCDREG(0x24)
+#define S3C2412_LCDSRCPND      S3C2410_LCDREG(0x28)
+#define S3C2412_LCDINTMSK      S3C2410_LCDREG(0x2C)
+
+#define S3C2412_TCONSEL                S3C2410_LCDREG(0x30)
+
+#define S3C2412_LCDCON6                S3C2410_LCDREG(0x34)
+#define S3C2412_LCDCON7                S3C2410_LCDREG(0x38)
+#define S3C2412_LCDCON8                S3C2410_LCDREG(0x3C)
+#define S3C2412_LCDCON9                S3C2410_LCDREG(0x40)
+
+#define S3C2412_REDLUT(x)      S3C2410_LCDREG(0x44 + ((x)*4))
+#define S3C2412_GREENLUT(x)    S3C2410_LCDREG(0x60 + ((x)*4))
+#define S3C2412_BLUELUT(x)     S3C2410_LCDREG(0x98 + ((x)*4))
+
+#define S3C2412_FRCPAT(x)      S3C2410_LCDREG(0xB4 + ((x)*4))
+
+/* general registers */
+
+/* base of the LCD registers, where INTPND, INTSRC and then INTMSK
+ * are available. */
+
+#define S3C2410_LCDINTBASE     S3C2410_LCDREG(0x54)
+#define S3C2412_LCDINTBASE     S3C2410_LCDREG(0x24)
+
+#define S3C24XX_LCDINTPND      (0x00)
+#define S3C24XX_LCDSRCPND      (0x04)
+#define S3C24XX_LCDINTMSK      (0x08)
+
+#endif /* ___ASM_ARCH_REGS_LCD_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-mem.h b/arch/arm/mach-s3c24xx/include/mach/regs-mem.h
new file mode 100644 (file)
index 0000000..e0c67b0
--- /dev/null
@@ -0,0 +1,202 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-mem.h
+ *
+ * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
+ *             http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 Memory Control register definitions
+*/
+
+#ifndef __ASM_ARM_MEMREGS_H
+#define __ASM_ARM_MEMREGS_H
+
+#ifndef S3C2410_MEMREG
+#define S3C2410_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
+#endif
+
+/* bus width, and wait state control */
+#define S3C2410_BWSCON                 S3C2410_MEMREG(0x0000)
+
+/* bank zero config - note, pinstrapped from OM pins! */
+#define S3C2410_BWSCON_DW0_16          (1<<1)
+#define S3C2410_BWSCON_DW0_32          (2<<1)
+
+/* bank one configs */
+#define S3C2410_BWSCON_DW1_8           (0<<4)
+#define S3C2410_BWSCON_DW1_16          (1<<4)
+#define S3C2410_BWSCON_DW1_32          (2<<4)
+#define S3C2410_BWSCON_WS1             (1<<6)
+#define S3C2410_BWSCON_ST1             (1<<7)
+
+/* bank 2 configurations */
+#define S3C2410_BWSCON_DW2_8           (0<<8)
+#define S3C2410_BWSCON_DW2_16          (1<<8)
+#define S3C2410_BWSCON_DW2_32          (2<<8)
+#define S3C2410_BWSCON_WS2             (1<<10)
+#define S3C2410_BWSCON_ST2             (1<<11)
+
+/* bank 3 configurations */
+#define S3C2410_BWSCON_DW3_8           (0<<12)
+#define S3C2410_BWSCON_DW3_16          (1<<12)
+#define S3C2410_BWSCON_DW3_32          (2<<12)
+#define S3C2410_BWSCON_WS3             (1<<14)
+#define S3C2410_BWSCON_ST3             (1<<15)
+
+/* bank 4 configurations */
+#define S3C2410_BWSCON_DW4_8           (0<<16)
+#define S3C2410_BWSCON_DW4_16          (1<<16)
+#define S3C2410_BWSCON_DW4_32          (2<<16)
+#define S3C2410_BWSCON_WS4             (1<<18)
+#define S3C2410_BWSCON_ST4             (1<<19)
+
+/* bank 5 configurations */
+#define S3C2410_BWSCON_DW5_8           (0<<20)
+#define S3C2410_BWSCON_DW5_16          (1<<20)
+#define S3C2410_BWSCON_DW5_32          (2<<20)
+#define S3C2410_BWSCON_WS5             (1<<22)
+#define S3C2410_BWSCON_ST5             (1<<23)
+
+/* bank 6 configurations */
+#define S3C2410_BWSCON_DW6_8           (0<<24)
+#define S3C2410_BWSCON_DW6_16          (1<<24)
+#define S3C2410_BWSCON_DW6_32          (2<<24)
+#define S3C2410_BWSCON_WS6             (1<<26)
+#define S3C2410_BWSCON_ST6             (1<<27)
+
+/* bank 7 configurations */
+#define S3C2410_BWSCON_DW7_8           (0<<28)
+#define S3C2410_BWSCON_DW7_16          (1<<28)
+#define S3C2410_BWSCON_DW7_32          (2<<28)
+#define S3C2410_BWSCON_WS7             (1<<30)
+#define S3C2410_BWSCON_ST7             (1<<31)
+
+/* accesor functions for getting BANK(n) configuration. (n != 0) */
+
+#define S3C2410_BWSCON_GET(_bwscon, _bank) (((_bwscon) >> ((_bank) * 4)) & 0xf)
+
+#define S3C2410_BWSCON_DW8             (0)
+#define S3C2410_BWSCON_DW16            (1)
+#define S3C2410_BWSCON_DW32            (2)
+#define S3C2410_BWSCON_WS              (1 << 2)
+#define S3C2410_BWSCON_ST              (1 << 3)
+
+/* memory set (rom, ram) */
+#define S3C2410_BANKCON0               S3C2410_MEMREG(0x0004)
+#define S3C2410_BANKCON1               S3C2410_MEMREG(0x0008)
+#define S3C2410_BANKCON2               S3C2410_MEMREG(0x000C)
+#define S3C2410_BANKCON3               S3C2410_MEMREG(0x0010)
+#define S3C2410_BANKCON4               S3C2410_MEMREG(0x0014)
+#define S3C2410_BANKCON5               S3C2410_MEMREG(0x0018)
+#define S3C2410_BANKCON6               S3C2410_MEMREG(0x001C)
+#define S3C2410_BANKCON7               S3C2410_MEMREG(0x0020)
+
+/* bank configuration registers */
+
+#define S3C2410_BANKCON_PMCnorm                (0x00)
+#define S3C2410_BANKCON_PMC4           (0x01)
+#define S3C2410_BANKCON_PMC8           (0x02)
+#define S3C2410_BANKCON_PMC16          (0x03)
+
+/* bank configurations for banks 0..7, note banks
+ * 6 and 7 have different configurations depending on
+ * the memory type bits */
+
+#define S3C2410_BANKCON_Tacp2          (0x0 << 2)
+#define S3C2410_BANKCON_Tacp3          (0x1 << 2)
+#define S3C2410_BANKCON_Tacp4          (0x2 << 2)
+#define S3C2410_BANKCON_Tacp6          (0x3 << 2)
+#define S3C2410_BANKCON_Tacp_SHIFT     (2)
+
+#define S3C2410_BANKCON_Tcah0          (0x0 << 4)
+#define S3C2410_BANKCON_Tcah1          (0x1 << 4)
+#define S3C2410_BANKCON_Tcah2          (0x2 << 4)
+#define S3C2410_BANKCON_Tcah4          (0x3 << 4)
+#define S3C2410_BANKCON_Tcah_SHIFT     (4)
+
+#define S3C2410_BANKCON_Tcoh0          (0x0 << 6)
+#define S3C2410_BANKCON_Tcoh1          (0x1 << 6)
+#define S3C2410_BANKCON_Tcoh2          (0x2 << 6)
+#define S3C2410_BANKCON_Tcoh4          (0x3 << 6)
+#define S3C2410_BANKCON_Tcoh_SHIFT     (6)
+
+#define S3C2410_BANKCON_Tacc1          (0x0 << 8)
+#define S3C2410_BANKCON_Tacc2          (0x1 << 8)
+#define S3C2410_BANKCON_Tacc3          (0x2 << 8)
+#define S3C2410_BANKCON_Tacc4          (0x3 << 8)
+#define S3C2410_BANKCON_Tacc6          (0x4 << 8)
+#define S3C2410_BANKCON_Tacc8          (0x5 << 8)
+#define S3C2410_BANKCON_Tacc10         (0x6 << 8)
+#define S3C2410_BANKCON_Tacc14         (0x7 << 8)
+#define S3C2410_BANKCON_Tacc_SHIFT     (8)
+
+#define S3C2410_BANKCON_Tcos0          (0x0 << 11)
+#define S3C2410_BANKCON_Tcos1          (0x1 << 11)
+#define S3C2410_BANKCON_Tcos2          (0x2 << 11)
+#define S3C2410_BANKCON_Tcos4          (0x3 << 11)
+#define S3C2410_BANKCON_Tcos_SHIFT     (11)
+
+#define S3C2410_BANKCON_Tacs0          (0x0 << 13)
+#define S3C2410_BANKCON_Tacs1          (0x1 << 13)
+#define S3C2410_BANKCON_Tacs2          (0x2 << 13)
+#define S3C2410_BANKCON_Tacs4          (0x3 << 13)
+#define S3C2410_BANKCON_Tacs_SHIFT     (13)
+
+#define S3C2410_BANKCON_SRAM           (0x0 << 15)
+#define S3C2410_BANKCON_SDRAM          (0x3 << 15)
+
+/* next bits only for SDRAM in 6,7 */
+#define S3C2410_BANKCON_Trcd2          (0x00 << 2)
+#define S3C2410_BANKCON_Trcd3          (0x01 << 2)
+#define S3C2410_BANKCON_Trcd4          (0x02 << 2)
+
+/* control column address select */
+#define S3C2410_BANKCON_SCANb8         (0x00 << 0)
+#define S3C2410_BANKCON_SCANb9         (0x01 << 0)
+#define S3C2410_BANKCON_SCANb10                (0x02 << 0)
+
+#define S3C2410_REFRESH                        S3C2410_MEMREG(0x0024)
+#define S3C2410_BANKSIZE               S3C2410_MEMREG(0x0028)
+#define S3C2410_MRSRB6                 S3C2410_MEMREG(0x002C)
+#define S3C2410_MRSRB7                 S3C2410_MEMREG(0x0030)
+
+/* refresh control */
+
+#define S3C2410_REFRESH_REFEN          (1<<23)
+#define S3C2410_REFRESH_SELF           (1<<22)
+#define S3C2410_REFRESH_REFCOUNTER     ((1<<11)-1)
+
+#define S3C2410_REFRESH_TRP_MASK       (3<<20)
+#define S3C2410_REFRESH_TRP_2clk       (0<<20)
+#define S3C2410_REFRESH_TRP_3clk       (1<<20)
+#define S3C2410_REFRESH_TRP_4clk       (2<<20)
+
+#define S3C2410_REFRESH_TSRC_MASK      (3<<18)
+#define S3C2410_REFRESH_TSRC_4clk      (0<<18)
+#define S3C2410_REFRESH_TSRC_5clk      (1<<18)
+#define S3C2410_REFRESH_TSRC_6clk      (2<<18)
+#define S3C2410_REFRESH_TSRC_7clk      (3<<18)
+
+
+/* mode select register(s) */
+
+#define  S3C2410_MRSRB_CL1             (0x00 << 4)
+#define  S3C2410_MRSRB_CL2             (0x02 << 4)
+#define  S3C2410_MRSRB_CL3             (0x03 << 4)
+
+/* bank size register */
+#define S3C2410_BANKSIZE_128M          (0x2 << 0)
+#define S3C2410_BANKSIZE_64M           (0x1 << 0)
+#define S3C2410_BANKSIZE_32M           (0x0 << 0)
+#define S3C2410_BANKSIZE_16M           (0x7 << 0)
+#define S3C2410_BANKSIZE_8M            (0x6 << 0)
+#define S3C2410_BANKSIZE_4M            (0x5 << 0)
+#define S3C2410_BANKSIZE_2M            (0x4 << 0)
+#define S3C2410_BANKSIZE_MASK          (0x7 << 0)
+#define S3C2410_BANKSIZE_SCLK_EN       (1<<4)
+#define S3C2410_BANKSIZE_SCKE_EN       (1<<5)
+#define S3C2410_BANKSIZE_BURST         (1<<7)
+
+#endif /* __ASM_ARM_MEMREGS_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-power.h b/arch/arm/mach-s3c24xx/include/mach/regs-power.h
new file mode 100644 (file)
index 0000000..4932b87
--- /dev/null
@@ -0,0 +1,40 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-power.h
+ *
+ * Copyright (c) 2003-2006 Simtec Electronics <linux@simtec.co.uk>
+ *     http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C24XX power control register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_PWR
+#define __ASM_ARM_REGS_PWR __FILE__
+
+#define S3C24XX_PWRREG(x) ((x) + S3C24XX_VA_CLKPWR)
+
+#define S3C2412_PWRMODECON     S3C24XX_PWRREG(0x20)
+#define S3C2412_PWRCFG         S3C24XX_PWRREG(0x24)
+
+#define S3C2412_INFORM0                S3C24XX_PWRREG(0x70)
+#define S3C2412_INFORM1                S3C24XX_PWRREG(0x74)
+#define S3C2412_INFORM2                S3C24XX_PWRREG(0x78)
+#define S3C2412_INFORM3                S3C24XX_PWRREG(0x7C)
+
+#define S3C2412_PWRCFG_BATF_IRQ                        (1<<0)
+#define S3C2412_PWRCFG_BATF_IGNORE             (2<<0)
+#define S3C2412_PWRCFG_BATF_SLEEP              (3<<0)
+#define S3C2412_PWRCFG_BATF_MASK               (3<<0)
+
+#define S3C2412_PWRCFG_STANDBYWFI_IGNORE       (0<<6)
+#define S3C2412_PWRCFG_STANDBYWFI_IDLE         (1<<6)
+#define S3C2412_PWRCFG_STANDBYWFI_STOP         (2<<6)
+#define S3C2412_PWRCFG_STANDBYWFI_SLEEP                (3<<6)
+#define S3C2412_PWRCFG_STANDBYWFI_MASK         (3<<6)
+
+#define S3C2412_PWRCFG_RTC_MASKIRQ             (1<<8)
+#define S3C2412_PWRCFG_NAND_NORST              (1<<9)
+
+#endif /* __ASM_ARM_REGS_PWR */
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-s3c2412-mem.h b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2412-mem.h
new file mode 100644 (file)
index 0000000..fb63525
--- /dev/null
@@ -0,0 +1,48 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *     http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2412 memory register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_S3C2412_MEM
+#define __ASM_ARM_REGS_S3C2412_MEM
+
+#define S3C2412_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
+#define S3C2412_EBIREG(x) (S3C2412_VA_EBI + (x))
+
+#define S3C2412_SSMCREG(x) (S3C2412_VA_SSMC + (x))
+#define S3C2412_SSMC(x, o) (S3C2412_SSMCREG((x * 0x20) + (o)))
+
+#define S3C2412_BANKCFG                        S3C2412_MEMREG(0x00)
+#define S3C2412_BANKCON1               S3C2412_MEMREG(0x04)
+#define S3C2412_BANKCON2               S3C2412_MEMREG(0x08)
+#define S3C2412_BANKCON3               S3C2412_MEMREG(0x0C)
+
+#define S3C2412_REFRESH                        S3C2412_MEMREG(0x10)
+#define S3C2412_TIMEOUT                        S3C2412_MEMREG(0x14)
+
+/* EBI control registers */
+
+#define S3C2412_EBI_PR                 S3C2412_EBIREG(0x00)
+#define S3C2412_EBI_BANKCFG            S3C2412_EBIREG(0x04)
+
+/* SSMC control registers */
+
+#define S3C2412_SSMC_BANK(x)           S3C2412_SSMC(x, 0x00)
+#define S3C2412_SMIDCYR(x)             S3C2412_SSMC(x, 0x00)
+#define S3C2412_SMBWSTRD(x)            S3C2412_SSMC(x, 0x04)
+#define S3C2412_SMBWSTWRR(x)           S3C2412_SSMC(x, 0x08)
+#define S3C2412_SMBWSTOENR(x)          S3C2412_SSMC(x, 0x0C)
+#define S3C2412_SMBWSTWENR(x)          S3C2412_SSMC(x, 0x10)
+#define S3C2412_SMBCR(x)               S3C2412_SSMC(x, 0x14)
+#define S3C2412_SMBSR(x)               S3C2412_SSMC(x, 0x18)
+#define S3C2412_SMBWSTBRDR(x)          S3C2412_SSMC(x, 0x1C)
+
+#endif /*  __ASM_ARM_REGS_S3C2412_MEM */
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-s3c2412.h b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2412.h
new file mode 100644 (file)
index 0000000..aa69dc7
--- /dev/null
@@ -0,0 +1,23 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-s3c2412.h
+ *
+ * Copyright 2007 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2412 specific register definitions
+*/
+
+#ifndef __ASM_ARCH_REGS_S3C2412_H
+#define __ASM_ARCH_REGS_S3C2412_H "s3c2412"
+
+#define S3C2412_SWRST          (S3C24XX_VA_CLKPWR + 0x30)
+#define S3C2412_SWRST_RESET    (0x533C2412)
+
+/* see regs-power.h for the other registers in the power block. */
+
+#endif /* __ASM_ARCH_REGS_S3C2412_H */
+
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-s3c2416-mem.h b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2416-mem.h
new file mode 100644 (file)
index 0000000..2f31b74
--- /dev/null
@@ -0,0 +1,30 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ *     as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ *     Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2416 memory register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_S3C2416_MEM
+#define __ASM_ARM_REGS_S3C2416_MEM
+
+#ifndef S3C2416_MEMREG
+#define S3C2416_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
+#endif
+
+#define S3C2416_BANKCFG                        S3C2416_MEMREG(0x00)
+#define S3C2416_BANKCON1               S3C2416_MEMREG(0x04)
+#define S3C2416_BANKCON2               S3C2416_MEMREG(0x08)
+#define S3C2416_BANKCON3               S3C2416_MEMREG(0x0C)
+
+#define S3C2416_REFRESH                        S3C2416_MEMREG(0x10)
+#define S3C2416_TIMEOUT                        S3C2416_MEMREG(0x14)
+
+#endif /*  __ASM_ARM_REGS_S3C2416_MEM */
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-s3c2416.h b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2416.h
new file mode 100644 (file)
index 0000000..e443167
--- /dev/null
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ *     as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ *     Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2416 specific register definitions
+*/
+
+#ifndef __ASM_ARCH_REGS_S3C2416_H
+#define __ASM_ARCH_REGS_S3C2416_H "s3c2416"
+
+#define S3C2416_SWRST          (S3C24XX_VA_CLKPWR + 0x44)
+#define S3C2416_SWRST_RESET    (0x533C2416)
+
+/* see regs-power.h for the other registers in the power block. */
+
+#endif /* __ASM_ARCH_REGS_S3C2416_H */
+
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2443-clock.h
new file mode 100644 (file)
index 0000000..c3feff3
--- /dev/null
@@ -0,0 +1,194 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *     http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2443 clock register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_S3C2443_CLOCK
+#define __ASM_ARM_REGS_S3C2443_CLOCK
+
+#define S3C2443_CLKREG(x)              ((x) + S3C24XX_VA_CLKPWR)
+
+#define S3C2443_PLLCON_MDIVSHIFT       16
+#define S3C2443_PLLCON_PDIVSHIFT       8
+#define S3C2443_PLLCON_SDIVSHIFT       0
+#define S3C2443_PLLCON_MDIVMASK                ((1<<(1+(23-16)))-1)
+#define S3C2443_PLLCON_PDIVMASK                ((1<<(1+(9-8)))-1)
+#define S3C2443_PLLCON_SDIVMASK                (3)
+
+#define S3C2443_MPLLCON                        S3C2443_CLKREG(0x10)
+#define S3C2443_EPLLCON                        S3C2443_CLKREG(0x18)
+#define S3C2443_CLKSRC                 S3C2443_CLKREG(0x20)
+#define S3C2443_CLKDIV0                        S3C2443_CLKREG(0x24)
+#define S3C2443_CLKDIV1                        S3C2443_CLKREG(0x28)
+#define S3C2443_HCLKCON                        S3C2443_CLKREG(0x30)
+#define S3C2443_PCLKCON                        S3C2443_CLKREG(0x34)
+#define S3C2443_SCLKCON                        S3C2443_CLKREG(0x38)
+#define S3C2443_PWRMODE                        S3C2443_CLKREG(0x40)
+#define S3C2443_SWRST                  S3C2443_CLKREG(0x44)
+#define S3C2443_BUSPRI0                        S3C2443_CLKREG(0x50)
+#define S3C2443_SYSID                  S3C2443_CLKREG(0x5C)
+#define S3C2443_PWRCFG                 S3C2443_CLKREG(0x60)
+#define S3C2443_RSTCON                 S3C2443_CLKREG(0x64)
+#define S3C2443_PHYCTRL                        S3C2443_CLKREG(0x80)
+#define S3C2443_PHYPWR                 S3C2443_CLKREG(0x84)
+#define S3C2443_URSTCON                        S3C2443_CLKREG(0x88)
+#define S3C2443_UCLKCON                        S3C2443_CLKREG(0x8C)
+
+#define S3C2443_SWRST_RESET            (0x533c2443)
+
+#define S3C2443_PLLCON_OFF             (1<<24)
+
+#define S3C2443_CLKSRC_EPLLREF_XTAL    (2<<7)
+#define S3C2443_CLKSRC_EPLLREF_EXTCLK  (3<<7)
+#define S3C2443_CLKSRC_EPLLREF_MPLLREF (0<<7)
+#define S3C2443_CLKSRC_EPLLREF_MPLLREF2        (1<<7)
+#define S3C2443_CLKSRC_EPLLREF_MASK    (3<<7)
+
+#define S3C2443_CLKSRC_EXTCLK_DIV      (1<<3)
+
+#define S3C2443_CLKDIV0_HALF_HCLK      (1<<3)
+#define S3C2443_CLKDIV0_HALF_PCLK      (1<<2)
+
+#define S3C2443_CLKDIV0_HCLKDIV_MASK   (3<<0)
+
+#define S3C2443_CLKDIV0_EXTDIV_MASK    (3<<6)
+#define S3C2443_CLKDIV0_EXTDIV_SHIFT   (6)
+
+#define S3C2443_CLKDIV0_PREDIV_MASK    (3<<4)
+#define S3C2443_CLKDIV0_PREDIV_SHIFT   (4)
+
+#define S3C2416_CLKDIV0_ARMDIV_MASK    (7 << 9)
+#define S3C2443_CLKDIV0_ARMDIV_MASK    (15<<9)
+#define S3C2443_CLKDIV0_ARMDIV_SHIFT   (9)
+#define S3C2443_CLKDIV0_ARMDIV_1       (0<<9)
+#define S3C2443_CLKDIV0_ARMDIV_2       (8<<9)
+#define S3C2443_CLKDIV0_ARMDIV_3       (2<<9)
+#define S3C2443_CLKDIV0_ARMDIV_4       (9<<9)
+#define S3C2443_CLKDIV0_ARMDIV_6       (10<<9)
+#define S3C2443_CLKDIV0_ARMDIV_8       (11<<9)
+#define S3C2443_CLKDIV0_ARMDIV_12      (13<<9)
+#define S3C2443_CLKDIV0_ARMDIV_16      (15<<9)
+
+/* S3C2443_CLKDIV1 removed, only used in clock.c code */
+
+#define S3C2443_CLKCON_NAND
+
+#define S3C2443_HCLKCON_DMA0           (1<<0)
+#define S3C2443_HCLKCON_DMA1           (1<<1)
+#define S3C2443_HCLKCON_DMA2           (1<<2)
+#define S3C2443_HCLKCON_DMA3           (1<<3)
+#define S3C2443_HCLKCON_DMA4           (1<<4)
+#define S3C2443_HCLKCON_DMA5           (1<<5)
+#define S3C2443_HCLKCON_CAMIF          (1<<8)
+#define S3C2443_HCLKCON_LCDC           (1<<9)
+#define S3C2443_HCLKCON_USBH           (1<<11)
+#define S3C2443_HCLKCON_USBD           (1<<12)
+#define S3C2416_HCLKCON_HSMMC0         (1<<15)
+#define S3C2443_HCLKCON_HSMMC          (1<<16)
+#define S3C2443_HCLKCON_CFC            (1<<17)
+#define S3C2443_HCLKCON_SSMC           (1<<18)
+#define S3C2443_HCLKCON_DRAMC          (1<<19)
+
+#define S3C2443_PCLKCON_UART0          (1<<0)
+#define S3C2443_PCLKCON_UART1          (1<<1)
+#define S3C2443_PCLKCON_UART2          (1<<2)
+#define S3C2443_PCLKCON_UART3          (1<<3)
+#define S3C2443_PCLKCON_IIC            (1<<4)
+#define S3C2443_PCLKCON_SDI            (1<<5)
+#define S3C2443_PCLKCON_HSSPI          (1<<6)
+#define S3C2443_PCLKCON_ADC            (1<<7)
+#define S3C2443_PCLKCON_AC97           (1<<8)
+#define S3C2443_PCLKCON_IIS            (1<<9)
+#define S3C2443_PCLKCON_PWMT           (1<<10)
+#define S3C2443_PCLKCON_WDT            (1<<11)
+#define S3C2443_PCLKCON_RTC            (1<<12)
+#define S3C2443_PCLKCON_GPIO           (1<<13)
+#define S3C2443_PCLKCON_SPI0           (1<<14)
+#define S3C2443_PCLKCON_SPI1           (1<<15)
+
+#define S3C2443_SCLKCON_DDRCLK         (1<<16)
+#define S3C2443_SCLKCON_SSMCCLK                (1<<15)
+#define S3C2443_SCLKCON_HSSPICLK       (1<<14)
+#define S3C2443_SCLKCON_HSMMCCLK_EXT   (1<<13)
+#define S3C2443_SCLKCON_HSMMCCLK_EPLL  (1<<12)
+#define S3C2443_SCLKCON_CAMCLK         (1<<11)
+#define S3C2443_SCLKCON_DISPCLK                (1<<10)
+#define S3C2443_SCLKCON_I2SCLK         (1<<9)
+#define S3C2443_SCLKCON_UARTCLK                (1<<8)
+#define S3C2443_SCLKCON_USBHOST                (1<<1)
+
+#define S3C2443_PWRCFG_SLEEP           (1<<15)
+
+#define S3C2443_PWRCFG_USBPHY          (1 << 4)
+
+#define S3C2443_URSTCON_FUNCRST                (1 << 2)
+#define S3C2443_URSTCON_PHYRST         (1 << 0)
+
+#define S3C2443_PHYCTRL_CLKSEL         (1 << 3)
+#define S3C2443_PHYCTRL_EXTCLK         (1 << 2)
+#define S3C2443_PHYCTRL_PLLSEL         (1 << 1)
+#define S3C2443_PHYCTRL_DSPORT         (1 << 0)
+
+#define S3C2443_PHYPWR_COMMON_ON       (1 << 31)
+#define S3C2443_PHYPWR_ANALOG_PD       (1 << 4)
+#define S3C2443_PHYPWR_PLL_REFCLK      (1 << 3)
+#define S3C2443_PHYPWR_XO_ON           (1 << 2)
+#define S3C2443_PHYPWR_PLL_PWRDN       (1 << 1)
+#define S3C2443_PHYPWR_FSUSPEND                (1 << 0)
+
+#define S3C2443_UCLKCON_DETECT_VBUS    (1 << 31)
+#define S3C2443_UCLKCON_FUNC_CLKEN     (1 << 2)
+#define S3C2443_UCLKCON_TCLKEN         (1 << 0)
+
+#include <asm/div64.h>
+
+static inline unsigned int
+s3c2443_get_mpll(unsigned int pllval, unsigned int baseclk)
+{
+       unsigned int mdiv, pdiv, sdiv;
+       uint64_t fvco;
+
+       mdiv = pllval >> S3C2443_PLLCON_MDIVSHIFT;
+       pdiv = pllval >> S3C2443_PLLCON_PDIVSHIFT;
+       sdiv = pllval >> S3C2443_PLLCON_SDIVSHIFT;
+
+       mdiv &= S3C2443_PLLCON_MDIVMASK;
+       pdiv &= S3C2443_PLLCON_PDIVMASK;
+       sdiv &= S3C2443_PLLCON_SDIVMASK;
+
+       fvco = (uint64_t)baseclk * (2 * (mdiv + 8));
+       do_div(fvco, pdiv << sdiv);
+
+       return (unsigned int)fvco;
+}
+
+static inline unsigned int
+s3c2443_get_epll(unsigned int pllval, unsigned int baseclk)
+{
+       unsigned int mdiv, pdiv, sdiv;
+       uint64_t fvco;
+
+       mdiv = pllval >> S3C2443_PLLCON_MDIVSHIFT;
+       pdiv = pllval >> S3C2443_PLLCON_PDIVSHIFT;
+       sdiv = pllval >> S3C2443_PLLCON_SDIVSHIFT;
+
+       mdiv &= S3C2443_PLLCON_MDIVMASK;
+       pdiv &= S3C2443_PLLCON_PDIVMASK;
+       sdiv &= S3C2443_PLLCON_SDIVMASK;
+
+       fvco = (uint64_t)baseclk * (mdiv + 8);
+       do_div(fvco, (pdiv + 2) << sdiv);
+
+       return (unsigned int)fvco;
+}
+
+#endif /*  __ASM_ARM_REGS_S3C2443_CLOCK */
+
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-sdi.h b/arch/arm/mach-s3c24xx/include/mach/regs-sdi.h
new file mode 100644 (file)
index 0000000..cbf2d88
--- /dev/null
@@ -0,0 +1,127 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-sdi.h
+ *
+ * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
+ *                   http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 MMC/SDIO register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_SDI
+#define __ASM_ARM_REGS_SDI "regs-sdi.h"
+
+#define S3C2410_SDICON                (0x00)
+#define S3C2410_SDIPRE                (0x04)
+#define S3C2410_SDICMDARG             (0x08)
+#define S3C2410_SDICMDCON             (0x0C)
+#define S3C2410_SDICMDSTAT            (0x10)
+#define S3C2410_SDIRSP0               (0x14)
+#define S3C2410_SDIRSP1               (0x18)
+#define S3C2410_SDIRSP2               (0x1C)
+#define S3C2410_SDIRSP3               (0x20)
+#define S3C2410_SDITIMER              (0x24)
+#define S3C2410_SDIBSIZE              (0x28)
+#define S3C2410_SDIDCON               (0x2C)
+#define S3C2410_SDIDCNT               (0x30)
+#define S3C2410_SDIDSTA               (0x34)
+#define S3C2410_SDIFSTA               (0x38)
+
+#define S3C2410_SDIDATA               (0x3C)
+#define S3C2410_SDIIMSK               (0x40)
+
+#define S3C2440_SDIDATA               (0x40)
+#define S3C2440_SDIIMSK               (0x3C)
+
+#define S3C2440_SDICON_SDRESET        (1<<8)
+#define S3C2440_SDICON_MMCCLOCK       (1<<5)
+#define S3C2410_SDICON_BYTEORDER      (1<<4)
+#define S3C2410_SDICON_SDIOIRQ        (1<<3)
+#define S3C2410_SDICON_RWAITEN        (1<<2)
+#define S3C2410_SDICON_FIFORESET      (1<<1)
+#define S3C2410_SDICON_CLOCKTYPE      (1<<0)
+
+#define S3C2410_SDICMDCON_ABORT       (1<<12)
+#define S3C2410_SDICMDCON_WITHDATA    (1<<11)
+#define S3C2410_SDICMDCON_LONGRSP     (1<<10)
+#define S3C2410_SDICMDCON_WAITRSP     (1<<9)
+#define S3C2410_SDICMDCON_CMDSTART    (1<<8)
+#define S3C2410_SDICMDCON_SENDERHOST  (1<<6)
+#define S3C2410_SDICMDCON_INDEX       (0x3f)
+
+#define S3C2410_SDICMDSTAT_CRCFAIL    (1<<12)
+#define S3C2410_SDICMDSTAT_CMDSENT    (1<<11)
+#define S3C2410_SDICMDSTAT_CMDTIMEOUT (1<<10)
+#define S3C2410_SDICMDSTAT_RSPFIN     (1<<9)
+#define S3C2410_SDICMDSTAT_XFERING    (1<<8)
+#define S3C2410_SDICMDSTAT_INDEX      (0xff)
+
+#define S3C2440_SDIDCON_DS_BYTE       (0<<22)
+#define S3C2440_SDIDCON_DS_HALFWORD   (1<<22)
+#define S3C2440_SDIDCON_DS_WORD       (2<<22)
+#define S3C2410_SDIDCON_IRQPERIOD     (1<<21)
+#define S3C2410_SDIDCON_TXAFTERRESP   (1<<20)
+#define S3C2410_SDIDCON_RXAFTERCMD    (1<<19)
+#define S3C2410_SDIDCON_BUSYAFTERCMD  (1<<18)
+#define S3C2410_SDIDCON_BLOCKMODE     (1<<17)
+#define S3C2410_SDIDCON_WIDEBUS       (1<<16)
+#define S3C2410_SDIDCON_DMAEN         (1<<15)
+#define S3C2410_SDIDCON_STOP          (1<<14)
+#define S3C2440_SDIDCON_DATSTART      (1<<14)
+#define S3C2410_SDIDCON_DATMODE              (3<<12)
+#define S3C2410_SDIDCON_BLKNUM        (0x7ff)
+
+/* constants for S3C2410_SDIDCON_DATMODE */
+#define S3C2410_SDIDCON_XFER_READY    (0<<12)
+#define S3C2410_SDIDCON_XFER_CHKSTART (1<<12)
+#define S3C2410_SDIDCON_XFER_RXSTART  (2<<12)
+#define S3C2410_SDIDCON_XFER_TXSTART  (3<<12)
+
+#define S3C2410_SDIDCON_BLKNUM_MASK   (0xFFF)
+#define S3C2410_SDIDCNT_BLKNUM_SHIFT  (12)
+
+#define S3C2410_SDIDSTA_RDYWAITREQ    (1<<10)
+#define S3C2410_SDIDSTA_SDIOIRQDETECT (1<<9)
+#define S3C2410_SDIDSTA_FIFOFAIL      (1<<8)   /* reserved on 2440 */
+#define S3C2410_SDIDSTA_CRCFAIL       (1<<7)
+#define S3C2410_SDIDSTA_RXCRCFAIL     (1<<6)
+#define S3C2410_SDIDSTA_DATATIMEOUT   (1<<5)
+#define S3C2410_SDIDSTA_XFERFINISH    (1<<4)
+#define S3C2410_SDIDSTA_BUSYFINISH    (1<<3)
+#define S3C2410_SDIDSTA_SBITERR       (1<<2)   /* reserved on 2410a/2440 */
+#define S3C2410_SDIDSTA_TXDATAON      (1<<1)
+#define S3C2410_SDIDSTA_RXDATAON      (1<<0)
+
+#define S3C2440_SDIFSTA_FIFORESET      (1<<16)
+#define S3C2440_SDIFSTA_FIFOFAIL       (3<<14)  /* 3 is correct (2 bits) */
+#define S3C2410_SDIFSTA_TFDET          (1<<13)
+#define S3C2410_SDIFSTA_RFDET          (1<<12)
+#define S3C2410_SDIFSTA_TFHALF         (1<<11)
+#define S3C2410_SDIFSTA_TFEMPTY        (1<<10)
+#define S3C2410_SDIFSTA_RFLAST         (1<<9)
+#define S3C2410_SDIFSTA_RFFULL         (1<<8)
+#define S3C2410_SDIFSTA_RFHALF         (1<<7)
+#define S3C2410_SDIFSTA_COUNTMASK      (0x7f)
+
+#define S3C2410_SDIIMSK_RESPONSECRC    (1<<17)
+#define S3C2410_SDIIMSK_CMDSENT        (1<<16)
+#define S3C2410_SDIIMSK_CMDTIMEOUT     (1<<15)
+#define S3C2410_SDIIMSK_RESPONSEND     (1<<14)
+#define S3C2410_SDIIMSK_READWAIT       (1<<13)
+#define S3C2410_SDIIMSK_SDIOIRQ        (1<<12)
+#define S3C2410_SDIIMSK_FIFOFAIL       (1<<11)
+#define S3C2410_SDIIMSK_CRCSTATUS      (1<<10)
+#define S3C2410_SDIIMSK_DATACRC        (1<<9)
+#define S3C2410_SDIIMSK_DATATIMEOUT    (1<<8)
+#define S3C2410_SDIIMSK_DATAFINISH     (1<<7)
+#define S3C2410_SDIIMSK_BUSYFINISH     (1<<6)
+#define S3C2410_SDIIMSK_SBITERR        (1<<5)  /* reserved 2440/2410a */
+#define S3C2410_SDIIMSK_TXFIFOHALF     (1<<4)
+#define S3C2410_SDIIMSK_TXFIFOEMPTY    (1<<3)
+#define S3C2410_SDIIMSK_RXFIFOLAST     (1<<2)
+#define S3C2410_SDIIMSK_RXFIFOFULL     (1<<1)
+#define S3C2410_SDIIMSK_RXFIFOHALF     (1<<0)
+
+#endif /* __ASM_ARM_REGS_SDI */
diff --git a/arch/arm/mach-s3c24xx/include/mach/tick.h b/arch/arm/mach-s3c24xx/include/mach/tick.h
new file mode 100644 (file)
index 0000000..544da41
--- /dev/null
@@ -0,0 +1,15 @@
+/* linux/arch/arm/mach-s3c2410/include/mach/tick.h
+ *
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S3C2410 - timer tick support
+ */
+
+#define SRCPND_TIMER4 (1<<(IRQ_TIMER4 - IRQ_EINT0))
+
+static inline int s3c24xx_ostimer_pending(void)
+{
+       return __raw_readl(S3C2410_SRCPND) & SRCPND_TIMER4;
+}
diff --git a/arch/arm/mach-s3c24xx/include/mach/timex.h b/arch/arm/mach-s3c24xx/include/mach/timex.h
new file mode 100644 (file)
index 0000000..fe9ca1f
--- /dev/null
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s3c2410/include/mach/timex.h
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - time parameters
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/uncompress.h b/arch/arm/mach-s3c24xx/include/mach/uncompress.h
new file mode 100644 (file)
index 0000000..8b283f8
--- /dev/null
@@ -0,0 +1,54 @@
+/* arch/arm/mach-s3c2410/include/mach/uncompress.h
+ *
+ * Copyright (c) 2003-2007 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - uncompress code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/regs-gpio.h>
+#include <mach/map.h>
+
+/* working in physical space... */
+#undef S3C2410_GPIOREG
+#define S3C2410_GPIOREG(x) ((S3C24XX_PA_GPIO + (x)))
+
+#include <plat/uncompress.h>
+
+static inline int is_arm926(void)
+{
+       unsigned int cpuid;
+
+       asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r" (cpuid));
+
+       return ((cpuid & 0xff0) == 0x260);
+}
+
+static void arch_detect_cpu(void)
+{
+       unsigned int cpuid;
+
+       cpuid = *((volatile unsigned int *)S3C2410_GSTATUS1);
+       cpuid &= S3C2410_GSTATUS1_IDMASK;
+
+       if (is_arm926() || cpuid == S3C2410_GSTATUS1_2440 ||
+           cpuid == S3C2410_GSTATUS1_2442 ||
+           cpuid == S3C2410_GSTATUS1_2416 ||
+           cpuid == S3C2410_GSTATUS1_2450) {
+               fifo_mask = S3C2440_UFSTAT_TXMASK;
+               fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
+       } else {
+               fifo_mask = S3C2410_UFSTAT_TXMASK;
+               fifo_max = 15 << S3C2410_UFSTAT_TXSHIFT;
+       }
+}
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/vr1000-cpld.h b/arch/arm/mach-s3c24xx/include/mach/vr1000-cpld.h
new file mode 100644 (file)
index 0000000..e411991
--- /dev/null
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s3c2410/include/mach/vr1000-cpld.h
+ *
+ * Copyright (c) 2003 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * VR1000 - CPLD control constants
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_VR1000CPLD_H
+#define __ASM_ARCH_VR1000CPLD_H
+
+#define VR1000_CPLD_CTRL2_RAMWEN     (0x04)   /* SRAM Write Enable */
+
+#endif /* __ASM_ARCH_VR1000CPLD_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/vr1000-irq.h b/arch/arm/mach-s3c24xx/include/mach/vr1000-irq.h
new file mode 100644 (file)
index 0000000..47add13
--- /dev/null
@@ -0,0 +1,26 @@
+/* arch/arm/mach-s3c2410/include/mach/vr1000-irq.h
+ *
+ * Copyright (c) 2003-2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Machine VR1000 - IRQ Number definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_VR1000IRQ_H
+#define __ASM_ARCH_VR1000IRQ_H
+
+/* irq numbers to onboard peripherals */
+
+#define IRQ_USBOC           IRQ_EINT19
+#define IRQ_IDE0            IRQ_EINT16
+#define IRQ_IDE1            IRQ_EINT17
+#define IRQ_VR1000_SERIAL    IRQ_EINT12
+#define IRQ_VR1000_DM9000A   IRQ_EINT10
+#define IRQ_VR1000_DM9000N   IRQ_EINT9
+#define IRQ_SMALERT         IRQ_EINT8
+
+#endif /* __ASM_ARCH_VR1000IRQ_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/vr1000-map.h b/arch/arm/mach-s3c24xx/include/mach/vr1000-map.h
new file mode 100644 (file)
index 0000000..99612fc
--- /dev/null
@@ -0,0 +1,110 @@
+/* arch/arm/mach-s3c2410/include/mach/vr1000-map.h
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Machine VR1000 - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* needs arch/map.h including with this */
+
+/* ok, we've used up to 0x13000000, now we need to find space for the
+ * peripherals that live in the nGCS[x] areas, which are quite numerous
+ * in their space. We also have the board's CPLD to find register space
+ * for.
+ */
+
+#ifndef __ASM_ARCH_VR1000MAP_H
+#define __ASM_ARCH_VR1000MAP_H
+
+#include <mach/bast-map.h>
+
+#define VR1000_IOADDR(x) BAST_IOADDR(x)
+
+/* we put the CPLD registers next, to get them out of the way */
+
+#define VR1000_VA_CTRL1            VR1000_IOADDR(0x00000000)    /* 0x01300000 */
+#define VR1000_PA_CTRL1            (S3C2410_CS5 | 0x7800000)
+
+#define VR1000_VA_CTRL2            VR1000_IOADDR(0x00100000)    /* 0x01400000 */
+#define VR1000_PA_CTRL2            (S3C2410_CS1 | 0x6000000)
+
+#define VR1000_VA_CTRL3            VR1000_IOADDR(0x00200000)    /* 0x01500000 */
+#define VR1000_PA_CTRL3            (S3C2410_CS1 | 0x6800000)
+
+#define VR1000_VA_CTRL4            VR1000_IOADDR(0x00300000)    /* 0x01600000 */
+#define VR1000_PA_CTRL4            (S3C2410_CS1 | 0x7000000)
+
+/* next, we have the PC104 ISA interrupt registers */
+
+#define VR1000_PA_PC104_IRQREQ  (S3C2410_CS5 | 0x6000000) /* 0x01700000 */
+#define VR1000_VA_PC104_IRQREQ  VR1000_IOADDR(0x00400000)
+
+#define VR1000_PA_PC104_IRQRAW  (S3C2410_CS5 | 0x6800000) /* 0x01800000 */
+#define VR1000_VA_PC104_IRQRAW  VR1000_IOADDR(0x00500000)
+
+#define VR1000_PA_PC104_IRQMASK (S3C2410_CS5 | 0x7000000) /* 0x01900000 */
+#define VR1000_VA_PC104_IRQMASK VR1000_IOADDR(0x00600000)
+
+/* 0xE0000000 contains the IO space that is split by speed and
+ * wether the access is for 8 or 16bit IO... this ensures that
+ * the correct access is made
+ *
+ * 0x10000000 of space, partitioned as so:
+ *
+ * 0x00000000 to 0x04000000  8bit,  slow
+ * 0x04000000 to 0x08000000  16bit, slow
+ * 0x08000000 to 0x0C000000  16bit, net
+ * 0x0C000000 to 0x10000000  16bit, fast
+ *
+ * each of these spaces has the following in:
+ *
+ * 0x02000000 to 0x02100000 1MB  IDE primary channel
+ * 0x02100000 to 0x02200000 1MB  IDE primary channel aux
+ * 0x02200000 to 0x02400000 1MB  IDE secondary channel
+ * 0x02300000 to 0x02400000 1MB  IDE secondary channel aux
+ * 0x02500000 to 0x02600000 1MB  Davicom DM9000 ethernet controllers
+ * 0x02600000 to 0x02700000 1MB
+ *
+ * the phyiscal layout of the zones are:
+ *  nGCS2 - 8bit, slow
+ *  nGCS3 - 16bit, slow
+ *  nGCS4 - 16bit, net
+ *  nGCS5 - 16bit, fast
+ */
+
+#define VR1000_VA_MULTISPACE (0xE0000000)
+
+#define VR1000_VA_ISAIO                   (VR1000_VA_MULTISPACE + 0x00000000)
+#define VR1000_VA_ISAMEM          (VR1000_VA_MULTISPACE + 0x01000000)
+#define VR1000_VA_IDEPRI          (VR1000_VA_MULTISPACE + 0x02000000)
+#define VR1000_VA_IDEPRIAUX       (VR1000_VA_MULTISPACE + 0x02100000)
+#define VR1000_VA_IDESEC          (VR1000_VA_MULTISPACE + 0x02200000)
+#define VR1000_VA_IDESECAUX       (VR1000_VA_MULTISPACE + 0x02300000)
+#define VR1000_VA_ASIXNET         (VR1000_VA_MULTISPACE + 0x02400000)
+#define VR1000_VA_DM9000          (VR1000_VA_MULTISPACE + 0x02500000)
+#define VR1000_VA_SUPERIO         (VR1000_VA_MULTISPACE + 0x02600000)
+
+/* physical offset addresses for the peripherals */
+
+#define VR1000_PA_IDEPRI          (0x02000000)
+#define VR1000_PA_IDEPRIAUX       (0x02800000)
+#define VR1000_PA_IDESEC          (0x03000000)
+#define VR1000_PA_IDESECAUX       (0x03800000)
+#define VR1000_PA_DM9000          (0x05000000)
+
+#define VR1000_PA_SERIAL          (0x11800000)
+#define VR1000_VA_SERIAL          (VR1000_IOADDR(0x00700000))
+
+/* VR1000 ram is in CS1, with A26..A24 = 2_101 */
+#define VR1000_PA_SRAM            (S3C2410_CS1 | 0x05000000)
+
+/* some configurations for the peripherals */
+
+#define VR1000_DM9000_CS        VR1000_VAM_CS4
+
+#endif /* __ASM_ARCH_VR1000MAP_H */
diff --git a/arch/arm/mach-s3c24xx/irq-s3c2412.c b/arch/arm/mach-s3c24xx/irq-s3c2412.c
new file mode 100644 (file)
index 0000000..e65619d
--- /dev/null
@@ -0,0 +1,214 @@
+/* linux/arch/arm/mach-s3c2412/irq.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-power.h>
+
+#include <plat/cpu.h>
+#include <plat/irq.h>
+#include <plat/pm.h>
+
+#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+#define INTMSK_SUB(start, end) (INTMSK(start, end) << ((start - S3C2410_IRQSUB(0))))
+
+/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by
+ * having them turn up in both the INT* and the EINT* registers. Whilst
+ * both show the status, they both now need to be acked when the IRQs
+ * go off.
+*/
+
+static void
+s3c2412_irq_mask(struct irq_data *data)
+{
+       unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
+       unsigned long mask;
+
+       mask = __raw_readl(S3C2410_INTMSK);
+       __raw_writel(mask | bitval, S3C2410_INTMSK);
+
+       mask = __raw_readl(S3C2412_EINTMASK);
+       __raw_writel(mask | bitval, S3C2412_EINTMASK);
+}
+
+static inline void
+s3c2412_irq_ack(struct irq_data *data)
+{
+       unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
+
+       __raw_writel(bitval, S3C2412_EINTPEND);
+       __raw_writel(bitval, S3C2410_SRCPND);
+       __raw_writel(bitval, S3C2410_INTPND);
+}
+
+static inline void
+s3c2412_irq_maskack(struct irq_data *data)
+{
+       unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
+       unsigned long mask;
+
+       mask = __raw_readl(S3C2410_INTMSK);
+       __raw_writel(mask|bitval, S3C2410_INTMSK);
+
+       mask = __raw_readl(S3C2412_EINTMASK);
+       __raw_writel(mask | bitval, S3C2412_EINTMASK);
+
+       __raw_writel(bitval, S3C2412_EINTPEND);
+       __raw_writel(bitval, S3C2410_SRCPND);
+       __raw_writel(bitval, S3C2410_INTPND);
+}
+
+static void
+s3c2412_irq_unmask(struct irq_data *data)
+{
+       unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
+       unsigned long mask;
+
+       mask = __raw_readl(S3C2412_EINTMASK);
+       __raw_writel(mask & ~bitval, S3C2412_EINTMASK);
+
+       mask = __raw_readl(S3C2410_INTMSK);
+       __raw_writel(mask & ~bitval, S3C2410_INTMSK);
+}
+
+static struct irq_chip s3c2412_irq_eint0t4 = {
+       .irq_ack        = s3c2412_irq_ack,
+       .irq_mask       = s3c2412_irq_mask,
+       .irq_unmask     = s3c2412_irq_unmask,
+       .irq_set_wake   = s3c_irq_wake,
+       .irq_set_type   = s3c_irqext_type,
+};
+
+#define INTBIT(x)      (1 << ((x) - S3C2410_IRQSUB(0)))
+
+/* CF and SDI sub interrupts */
+
+static void s3c2412_irq_demux_cfsdi(unsigned int irq, struct irq_desc *desc)
+{
+       unsigned int subsrc, submsk;
+
+       subsrc = __raw_readl(S3C2410_SUBSRCPND);
+       submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+       subsrc  &= ~submsk;
+
+       if (subsrc & INTBIT(IRQ_S3C2412_SDI))
+               generic_handle_irq(IRQ_S3C2412_SDI);
+
+       if (subsrc & INTBIT(IRQ_S3C2412_CF))
+               generic_handle_irq(IRQ_S3C2412_CF);
+}
+
+#define INTMSK_CFSDI   (1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0))
+#define SUBMSK_CFSDI   INTMSK_SUB(IRQ_S3C2412_SDI, IRQ_S3C2412_CF)
+
+static void s3c2412_irq_cfsdi_mask(struct irq_data *data)
+{
+       s3c_irqsub_mask(data->irq, INTMSK_CFSDI, SUBMSK_CFSDI);
+}
+
+static void s3c2412_irq_cfsdi_unmask(struct irq_data *data)
+{
+       s3c_irqsub_unmask(data->irq, INTMSK_CFSDI);
+}
+
+static void s3c2412_irq_cfsdi_ack(struct irq_data *data)
+{
+       s3c_irqsub_maskack(data->irq, INTMSK_CFSDI, SUBMSK_CFSDI);
+}
+
+static struct irq_chip s3c2412_irq_cfsdi = {
+       .name           = "s3c2412-cfsdi",
+       .irq_ack        = s3c2412_irq_cfsdi_ack,
+       .irq_mask       = s3c2412_irq_cfsdi_mask,
+       .irq_unmask     = s3c2412_irq_cfsdi_unmask,
+};
+
+static int s3c2412_irq_rtc_wake(struct irq_data *data, unsigned int state)
+{
+       unsigned long pwrcfg;
+
+       pwrcfg = __raw_readl(S3C2412_PWRCFG);
+       if (state)
+               pwrcfg &= ~S3C2412_PWRCFG_RTC_MASKIRQ;
+       else
+               pwrcfg |= S3C2412_PWRCFG_RTC_MASKIRQ;
+       __raw_writel(pwrcfg, S3C2412_PWRCFG);
+
+       return s3c_irq_chip.irq_set_wake(data, state);
+}
+
+static struct irq_chip s3c2412_irq_rtc_chip;
+
+static int s3c2412_irq_add(struct device *dev, struct subsys_interface *sif)
+{
+       unsigned int irqno;
+
+       for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
+               irq_set_chip_and_handler(irqno, &s3c2412_irq_eint0t4,
+                                        handle_edge_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+
+       /* add demux support for CF/SDI */
+
+       irq_set_chained_handler(IRQ_S3C2412_CFSDI, s3c2412_irq_demux_cfsdi);
+
+       for (irqno = IRQ_S3C2412_SDI; irqno <= IRQ_S3C2412_CF; irqno++) {
+               irq_set_chip_and_handler(irqno, &s3c2412_irq_cfsdi,
+                                        handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+
+       /* change RTC IRQ's set wake method */
+
+       s3c2412_irq_rtc_chip = s3c_irq_chip;
+       s3c2412_irq_rtc_chip.irq_set_wake = s3c2412_irq_rtc_wake;
+
+       irq_set_chip(IRQ_RTC, &s3c2412_irq_rtc_chip);
+
+       return 0;
+}
+
+static struct subsys_interface s3c2412_irq_interface = {
+       .name           = "s3c2412_irq",
+       .subsys         = &s3c2412_subsys,
+       .add_dev        = s3c2412_irq_add,
+};
+
+static int s3c2412_irq_init(void)
+{
+       return subsys_interface_register(&s3c2412_irq_interface);
+}
+
+arch_initcall(s3c2412_irq_init);
diff --git a/arch/arm/mach-s3c24xx/irq-s3c2416.c b/arch/arm/mach-s3c24xx/irq-s3c2416.c
new file mode 100644 (file)
index 0000000..fd49f35
--- /dev/null
@@ -0,0 +1,250 @@
+/* linux/arch/arm/mach-s3c2416/irq.c
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ *     as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ *     Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+
+#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+
+static inline void s3c2416_irq_demux(unsigned int irq, unsigned int len)
+{
+       unsigned int subsrc, submsk;
+       unsigned int end;
+
+       /* read the current pending interrupts, and the mask
+        * for what it is available */
+
+       subsrc = __raw_readl(S3C2410_SUBSRCPND);
+       submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+       subsrc  &= ~submsk;
+       subsrc >>= (irq - S3C2410_IRQSUB(0));
+       subsrc  &= (1 << len)-1;
+
+       end = len + irq;
+
+       for (; irq < end && subsrc; irq++) {
+               if (subsrc & 1)
+                       generic_handle_irq(irq);
+
+               subsrc >>= 1;
+       }
+}
+
+/* WDT/AC97 sub interrupts */
+
+static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
+{
+       s3c2416_irq_demux(IRQ_S3C2443_WDT, 4);
+}
+
+#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
+#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
+
+static void s3c2416_irq_wdtac97_mask(struct irq_data *data)
+{
+       s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static void s3c2416_irq_wdtac97_unmask(struct irq_data *data)
+{
+       s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
+}
+
+static void s3c2416_irq_wdtac97_ack(struct irq_data *data)
+{
+       s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static struct irq_chip s3c2416_irq_wdtac97 = {
+       .irq_mask       = s3c2416_irq_wdtac97_mask,
+       .irq_unmask     = s3c2416_irq_wdtac97_unmask,
+       .irq_ack        = s3c2416_irq_wdtac97_ack,
+};
+
+/* LCD sub interrupts */
+
+static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
+{
+       s3c2416_irq_demux(IRQ_S3C2443_LCD1, 4);
+}
+
+#define INTMSK_LCD     (1UL << (IRQ_LCD - IRQ_EINT0))
+#define SUBMSK_LCD     INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
+
+static void s3c2416_irq_lcd_mask(struct irq_data *data)
+{
+       s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static void s3c2416_irq_lcd_unmask(struct irq_data *data)
+{
+       s3c_irqsub_unmask(data->irq, INTMSK_LCD);
+}
+
+static void s3c2416_irq_lcd_ack(struct irq_data *data)
+{
+       s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static struct irq_chip s3c2416_irq_lcd = {
+       .irq_mask       = s3c2416_irq_lcd_mask,
+       .irq_unmask     = s3c2416_irq_lcd_unmask,
+       .irq_ack        = s3c2416_irq_lcd_ack,
+};
+
+/* DMA sub interrupts */
+
+static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
+{
+       s3c2416_irq_demux(IRQ_S3C2443_DMA0, 6);
+}
+
+#define INTMSK_DMA     (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
+#define SUBMSK_DMA     INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
+
+
+static void s3c2416_irq_dma_mask(struct irq_data *data)
+{
+       s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static void s3c2416_irq_dma_unmask(struct irq_data *data)
+{
+       s3c_irqsub_unmask(data->irq, INTMSK_DMA);
+}
+
+static void s3c2416_irq_dma_ack(struct irq_data *data)
+{
+       s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static struct irq_chip s3c2416_irq_dma = {
+       .irq_mask       = s3c2416_irq_dma_mask,
+       .irq_unmask     = s3c2416_irq_dma_unmask,
+       .irq_ack        = s3c2416_irq_dma_ack,
+};
+
+/* UART3 sub interrupts */
+
+static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
+{
+       s3c2416_irq_demux(IRQ_S3C2443_RX3, 3);
+}
+
+#define INTMSK_UART3   (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
+#define SUBMSK_UART3   (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
+
+static void s3c2416_irq_uart3_mask(struct irq_data *data)
+{
+       s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static void s3c2416_irq_uart3_unmask(struct irq_data *data)
+{
+       s3c_irqsub_unmask(data->irq, INTMSK_UART3);
+}
+
+static void s3c2416_irq_uart3_ack(struct irq_data *data)
+{
+       s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static struct irq_chip s3c2416_irq_uart3 = {
+       .irq_mask       = s3c2416_irq_uart3_mask,
+       .irq_unmask     = s3c2416_irq_uart3_unmask,
+       .irq_ack        = s3c2416_irq_uart3_ack,
+};
+
+/* IRQ initialisation code */
+
+static int __init s3c2416_add_sub(unsigned int base,
+                                  void (*demux)(unsigned int,
+                                                struct irq_desc *),
+                                  struct irq_chip *chip,
+                                  unsigned int start, unsigned int end)
+{
+       unsigned int irqno;
+
+       irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
+       irq_set_chained_handler(base, demux);
+
+       for (irqno = start; irqno <= end; irqno++) {
+               irq_set_chip_and_handler(irqno, chip, handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+
+       return 0;
+}
+
+static int __init s3c2416_irq_add(struct device *dev,
+                                 struct subsys_interface *sif)
+{
+       printk(KERN_INFO "S3C2416: IRQ Support\n");
+
+       s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd,
+                       IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4);
+
+       s3c2416_add_sub(IRQ_S3C2443_DMA, s3c2416_irq_demux_dma,
+                       &s3c2416_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
+
+       s3c2416_add_sub(IRQ_S3C2443_UART3, s3c2416_irq_demux_uart3,
+                       &s3c2416_irq_uart3,
+                       IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
+
+       s3c2416_add_sub(IRQ_WDT, s3c2416_irq_demux_wdtac97,
+                       &s3c2416_irq_wdtac97,
+                       IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
+
+       return 0;
+}
+
+static struct subsys_interface s3c2416_irq_interface = {
+       .name           = "s3c2416_irq",
+       .subsys         = &s3c2416_subsys,
+       .add_dev        = s3c2416_irq_add,
+};
+
+static int __init s3c2416_irq_init(void)
+{
+       return subsys_interface_register(&s3c2416_irq_interface);
+}
+
+arch_initcall(s3c2416_irq_init);
+
diff --git a/arch/arm/mach-s3c24xx/irq-s3c2440.c b/arch/arm/mach-s3c24xx/irq-s3c2440.c
new file mode 100644 (file)
index 0000000..4a18cde
--- /dev/null
@@ -0,0 +1,128 @@
+/* linux/arch/arm/mach-s3c2440/irq.c
+ *
+ * Copyright (c) 2003-2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+
+/* WDT/AC97 */
+
+static void s3c_irq_demux_wdtac97(unsigned int irq,
+                                 struct irq_desc *desc)
+{
+       unsigned int subsrc, submsk;
+
+       /* read the current pending interrupts, and the mask
+        * for what it is available */
+
+       subsrc = __raw_readl(S3C2410_SUBSRCPND);
+       submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+       subsrc &= ~submsk;
+       subsrc >>= 13;
+       subsrc &= 3;
+
+       if (subsrc != 0) {
+               if (subsrc & 1) {
+                       generic_handle_irq(IRQ_S3C2440_WDT);
+               }
+               if (subsrc & 2) {
+                       generic_handle_irq(IRQ_S3C2440_AC97);
+               }
+       }
+}
+
+
+#define INTMSK_WDT      (1UL << (IRQ_WDT - IRQ_EINT0))
+
+static void
+s3c_irq_wdtac97_mask(struct irq_data *data)
+{
+       s3c_irqsub_mask(data->irq, INTMSK_WDT, 3 << 13);
+}
+
+static void
+s3c_irq_wdtac97_unmask(struct irq_data *data)
+{
+       s3c_irqsub_unmask(data->irq, INTMSK_WDT);
+}
+
+static void
+s3c_irq_wdtac97_ack(struct irq_data *data)
+{
+       s3c_irqsub_maskack(data->irq, INTMSK_WDT, 3 << 13);
+}
+
+static struct irq_chip s3c_irq_wdtac97 = {
+       .irq_mask       = s3c_irq_wdtac97_mask,
+       .irq_unmask     = s3c_irq_wdtac97_unmask,
+       .irq_ack        = s3c_irq_wdtac97_ack,
+};
+
+static int s3c2440_irq_add(struct device *dev, struct subsys_interface *sif)
+{
+       unsigned int irqno;
+
+       printk("S3C2440: IRQ Support\n");
+
+       /* add new chained handler for wdt, ac7 */
+
+       irq_set_chip_and_handler(IRQ_WDT, &s3c_irq_level_chip,
+                                handle_level_irq);
+       irq_set_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97);
+
+       for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) {
+               irq_set_chip_and_handler(irqno, &s3c_irq_wdtac97,
+                                        handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+
+       return 0;
+}
+
+static struct subsys_interface s3c2440_irq_interface = {
+       .name           = "s3c2440_irq",
+       .subsys         = &s3c2440_subsys,
+       .add_dev        = s3c2440_irq_add,
+};
+
+static int s3c2440_irq_init(void)
+{
+       return subsys_interface_register(&s3c2440_irq_interface);
+}
+
+arch_initcall(s3c2440_irq_init);
+
diff --git a/arch/arm/mach-s3c24xx/irq-s3c2443.c b/arch/arm/mach-s3c24xx/irq-s3c2443.c
new file mode 100644 (file)
index 0000000..ac2829f
--- /dev/null
@@ -0,0 +1,281 @@
+/* linux/arch/arm/mach-s3c2443/irq.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+
+#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+
+static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len)
+{
+       unsigned int subsrc, submsk;
+       unsigned int end;
+
+       /* read the current pending interrupts, and the mask
+        * for what it is available */
+
+       subsrc = __raw_readl(S3C2410_SUBSRCPND);
+       submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+       subsrc  &= ~submsk;
+       subsrc >>= (irq - S3C2410_IRQSUB(0));
+       subsrc  &= (1 << len)-1;
+
+       end = len + irq;
+
+       for (; irq < end && subsrc; irq++) {
+               if (subsrc & 1)
+                       generic_handle_irq(irq);
+
+               subsrc >>= 1;
+       }
+}
+
+/* WDT/AC97 sub interrupts */
+
+static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
+{
+       s3c2443_irq_demux(IRQ_S3C2443_WDT, 4);
+}
+
+#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
+#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
+
+static void s3c2443_irq_wdtac97_mask(struct irq_data *data)
+{
+       s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static void s3c2443_irq_wdtac97_unmask(struct irq_data *data)
+{
+       s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
+}
+
+static void s3c2443_irq_wdtac97_ack(struct irq_data *data)
+{
+       s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static struct irq_chip s3c2443_irq_wdtac97 = {
+       .irq_mask       = s3c2443_irq_wdtac97_mask,
+       .irq_unmask     = s3c2443_irq_wdtac97_unmask,
+       .irq_ack        = s3c2443_irq_wdtac97_ack,
+};
+
+/* LCD sub interrupts */
+
+static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
+{
+       s3c2443_irq_demux(IRQ_S3C2443_LCD1, 4);
+}
+
+#define INTMSK_LCD     (1UL << (IRQ_LCD - IRQ_EINT0))
+#define SUBMSK_LCD     INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
+
+static void s3c2443_irq_lcd_mask(struct irq_data *data)
+{
+       s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static void s3c2443_irq_lcd_unmask(struct irq_data *data)
+{
+       s3c_irqsub_unmask(data->irq, INTMSK_LCD);
+}
+
+static void s3c2443_irq_lcd_ack(struct irq_data *data)
+{
+       s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static struct irq_chip s3c2443_irq_lcd = {
+       .irq_mask       = s3c2443_irq_lcd_mask,
+       .irq_unmask     = s3c2443_irq_lcd_unmask,
+       .irq_ack        = s3c2443_irq_lcd_ack,
+};
+
+/* DMA sub interrupts */
+
+static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
+{
+       s3c2443_irq_demux(IRQ_S3C2443_DMA0, 6);
+}
+
+#define INTMSK_DMA     (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
+#define SUBMSK_DMA     INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
+
+static void s3c2443_irq_dma_mask(struct irq_data *data)
+{
+       s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static void s3c2443_irq_dma_unmask(struct irq_data *data)
+{
+       s3c_irqsub_unmask(data->irq, INTMSK_DMA);
+}
+
+static void s3c2443_irq_dma_ack(struct irq_data *data)
+{
+       s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static struct irq_chip s3c2443_irq_dma = {
+       .irq_mask       = s3c2443_irq_dma_mask,
+       .irq_unmask     = s3c2443_irq_dma_unmask,
+       .irq_ack        = s3c2443_irq_dma_ack,
+};
+
+/* UART3 sub interrupts */
+
+static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
+{
+       s3c2443_irq_demux(IRQ_S3C2443_RX3, 3);
+}
+
+#define INTMSK_UART3   (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
+#define SUBMSK_UART3   (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
+
+static void s3c2443_irq_uart3_mask(struct irq_data *data)
+{
+       s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static void s3c2443_irq_uart3_unmask(struct irq_data *data)
+{
+       s3c_irqsub_unmask(data->irq, INTMSK_UART3);
+}
+
+static void s3c2443_irq_uart3_ack(struct irq_data *data)
+{
+       s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static struct irq_chip s3c2443_irq_uart3 = {
+       .irq_mask       = s3c2443_irq_uart3_mask,
+       .irq_unmask     = s3c2443_irq_uart3_unmask,
+       .irq_ack        = s3c2443_irq_uart3_ack,
+};
+
+/* CAM sub interrupts */
+
+static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
+{
+       s3c2443_irq_demux(IRQ_S3C2440_CAM_C, 4);
+}
+
+#define INTMSK_CAM     (1UL << (IRQ_CAM - IRQ_EINT0))
+#define SUBMSK_CAM     INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
+
+static void s3c2443_irq_cam_mask(struct irq_data *data)
+{
+       s3c_irqsub_mask(data->irq, INTMSK_CAM, SUBMSK_CAM);
+}
+
+static void s3c2443_irq_cam_unmask(struct irq_data *data)
+{
+       s3c_irqsub_unmask(data->irq, INTMSK_CAM);
+}
+
+static void s3c2443_irq_cam_ack(struct irq_data *data)
+{
+       s3c_irqsub_maskack(data->irq, INTMSK_CAM, SUBMSK_CAM);
+}
+
+static struct irq_chip s3c2443_irq_cam = {
+       .irq_mask       = s3c2443_irq_cam_mask,
+       .irq_unmask     = s3c2443_irq_cam_unmask,
+       .irq_ack        = s3c2443_irq_cam_ack,
+};
+
+/* IRQ initialisation code */
+
+static int __init s3c2443_add_sub(unsigned int base,
+                                  void (*demux)(unsigned int,
+                                                struct irq_desc *),
+                                  struct irq_chip *chip,
+                                  unsigned int start, unsigned int end)
+{
+       unsigned int irqno;
+
+       irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
+       irq_set_chained_handler(base, demux);
+
+       for (irqno = start; irqno <= end; irqno++) {
+               irq_set_chip_and_handler(irqno, chip, handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+
+       return 0;
+}
+
+static int __init s3c2443_irq_add(struct device *dev,
+                                 struct subsys_interface *sif)
+{
+       printk("S3C2443: IRQ Support\n");
+
+       s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam,
+                       IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P);
+
+       s3c2443_add_sub(IRQ_LCD, s3c2443_irq_demux_lcd, &s3c2443_irq_lcd,
+                       IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4);
+
+       s3c2443_add_sub(IRQ_S3C2443_DMA, s3c2443_irq_demux_dma,
+                       &s3c2443_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
+
+       s3c2443_add_sub(IRQ_S3C2443_UART3, s3c2443_irq_demux_uart3,
+                       &s3c2443_irq_uart3,
+                       IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
+
+       s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97,
+                       &s3c2443_irq_wdtac97,
+                       IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
+
+       return 0;
+}
+
+static struct subsys_interface s3c2443_irq_interface = {
+       .name           = "s3c2443_irq",
+       .subsys         = &s3c2443_subsys,
+       .add_dev        = s3c2443_irq_add,
+};
+
+static int __init s3c2443_irq_init(void)
+{
+       return subsys_interface_register(&s3c2443_irq_interface);
+}
+
+arch_initcall(s3c2443_irq_init);
+
diff --git a/arch/arm/mach-s3c24xx/irq-s3c244x.c b/arch/arm/mach-s3c24xx/irq-s3c244x.c
new file mode 100644 (file)
index 0000000..5fe8e58
--- /dev/null
@@ -0,0 +1,142 @@
+/* linux/arch/arm/plat-s3c24xx/s3c244x-irq.c
+ *
+ * Copyright (c) 2003-2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+
+/* camera irq */
+
+static void s3c_irq_demux_cam(unsigned int irq,
+                             struct irq_desc *desc)
+{
+       unsigned int subsrc, submsk;
+
+       /* read the current pending interrupts, and the mask
+        * for what it is available */
+
+       subsrc = __raw_readl(S3C2410_SUBSRCPND);
+       submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+       subsrc &= ~submsk;
+       subsrc >>= 11;
+       subsrc &= 3;
+
+       if (subsrc != 0) {
+               if (subsrc & 1) {
+                       generic_handle_irq(IRQ_S3C2440_CAM_C);
+               }
+               if (subsrc & 2) {
+                       generic_handle_irq(IRQ_S3C2440_CAM_P);
+               }
+       }
+}
+
+#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
+
+static void
+s3c_irq_cam_mask(struct irq_data *data)
+{
+       s3c_irqsub_mask(data->irq, INTMSK_CAM, 3 << 11);
+}
+
+static void
+s3c_irq_cam_unmask(struct irq_data *data)
+{
+       s3c_irqsub_unmask(data->irq, INTMSK_CAM);
+}
+
+static void
+s3c_irq_cam_ack(struct irq_data *data)
+{
+       s3c_irqsub_maskack(data->irq, INTMSK_CAM, 3 << 11);
+}
+
+static struct irq_chip s3c_irq_cam = {
+       .irq_mask       = s3c_irq_cam_mask,
+       .irq_unmask     = s3c_irq_cam_unmask,
+       .irq_ack        = s3c_irq_cam_ack,
+};
+
+static int s3c244x_irq_add(struct device *dev, struct subsys_interface *sif)
+{
+       unsigned int irqno;
+
+       irq_set_chip_and_handler(IRQ_NFCON, &s3c_irq_level_chip,
+                                handle_level_irq);
+       set_irq_flags(IRQ_NFCON, IRQF_VALID);
+
+       /* add chained handler for camera */
+
+       irq_set_chip_and_handler(IRQ_CAM, &s3c_irq_level_chip,
+                                handle_level_irq);
+       irq_set_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
+
+       for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
+               irq_set_chip_and_handler(irqno, &s3c_irq_cam,
+                                        handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+
+       return 0;
+}
+
+static struct subsys_interface s3c2440_irq_interface = {
+       .name           = "s3c2440_irq",
+       .subsys         = &s3c2440_subsys,
+       .add_dev        = s3c244x_irq_add,
+};
+
+static int s3c2440_irq_init(void)
+{
+       return subsys_interface_register(&s3c2440_irq_interface);
+}
+
+arch_initcall(s3c2440_irq_init);
+
+static struct subsys_interface s3c2442_irq_interface = {
+       .name           = "s3c2442_irq",
+       .subsys         = &s3c2442_subsys,
+       .add_dev        = s3c244x_irq_add,
+};
+
+
+static int s3c2442_irq_init(void)
+{
+       return subsys_interface_register(&s3c2442_irq_interface);
+}
+
+arch_initcall(s3c2442_irq_init);
diff --git a/arch/arm/mach-s3c24xx/mach-amlm5900.c b/arch/arm/mach-s3c24xx/mach-amlm5900.c
new file mode 100644 (file)
index 0000000..4220cc6
--- /dev/null
@@ -0,0 +1,247 @@
+/* linux/arch/arm/mach-s3c2410/mach-amlm5900.c
+ *
+ * linux/arch/arm/mach-s3c2410/mach-amlm5900.c
+ *
+ * Copyright (c) 2006 American Microsystems Limited
+ *     David Anders <danders@amltd.com>
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * @History:
+ * derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ ***********************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <mach/fb.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-lcd.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/gpio-cfg.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/physmap.h>
+
+#include "common.h"
+
+static struct resource amlm5900_nor_resource = {
+               .start = 0x00000000,
+               .end   = 0x01000000 - 1,
+               .flags = IORESOURCE_MEM,
+};
+
+
+
+static struct mtd_partition amlm5900_mtd_partitions[] = {
+       {
+               .name           = "System",
+               .size           = 0x240000,
+               .offset         = 0,
+               .mask_flags     = MTD_WRITEABLE,  /* force read-only */
+       }, {
+               .name           = "Kernel",
+               .size           = 0x100000,
+               .offset         = MTDPART_OFS_APPEND,
+       }, {
+               .name           = "Ramdisk",
+               .size           = 0x300000,
+               .offset         = MTDPART_OFS_APPEND,
+       }, {
+               .name           = "JFFS2",
+               .size           = 0x9A0000,
+               .offset         = MTDPART_OFS_APPEND,
+       }, {
+               .name           = "Settings",
+               .size           = MTDPART_SIZ_FULL,
+               .offset         = MTDPART_OFS_APPEND,
+       }
+};
+
+static struct physmap_flash_data amlm5900_flash_data = {
+       .width          = 2,
+       .parts          = amlm5900_mtd_partitions,
+       .nr_parts       = ARRAY_SIZE(amlm5900_mtd_partitions),
+};
+
+static struct platform_device amlm5900_device_nor = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev = {
+                       .platform_data = &amlm5900_flash_data,
+               },
+       .num_resources  = 1,
+       .resource       = &amlm5900_nor_resource,
+};
+
+static struct map_desc amlm5900_iodesc[] __initdata = {
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg amlm5900_uartcfgs[] = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       }
+};
+
+
+static struct platform_device *amlm5900_devices[] __initdata = {
+#ifdef CONFIG_FB_S3C2410
+       &s3c_device_lcd,
+#endif
+       &s3c_device_adc,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_ohci,
+       &s3c_device_rtc,
+       &s3c_device_usbgadget,
+        &s3c_device_sdi,
+       &amlm5900_device_nor,
+};
+
+static void __init amlm5900_map_io(void)
+{
+       s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc));
+       s3c24xx_init_clocks(0);
+       s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs));
+}
+
+#ifdef CONFIG_FB_S3C2410
+static struct s3c2410fb_display __initdata amlm5900_lcd_info = {
+       .width          = 160,
+       .height         = 160,
+
+       .type           = S3C2410_LCDCON1_STN4,
+
+       .pixclock       = 680000, /* HCLK = 100MHz */
+       .xres           = 160,
+       .yres           = 160,
+       .bpp            = 4,
+       .left_margin    = 1 << (4 + 3),
+       .right_margin   = 8 << 3,
+       .hsync_len      = 48,
+       .upper_margin   = 0,
+       .lower_margin   = 0,
+
+       .lcdcon5        = 0x00000001,
+};
+
+static struct s3c2410fb_mach_info __initdata amlm5900_fb_info = {
+
+       .displays = &amlm5900_lcd_info,
+       .num_displays = 1,
+       .default_display = 0,
+
+       .gpccon =       0xaaaaaaaa,
+       .gpccon_mask =  0xffffffff,
+       .gpcup =        0x0000ffff,
+       .gpcup_mask =   0xffffffff,
+
+       .gpdcon =       0xaaaaaaaa,
+       .gpdcon_mask =  0xffffffff,
+       .gpdup =        0x0000ffff,
+       .gpdup_mask =   0xffffffff,
+};
+#endif
+
+static irqreturn_t
+amlm5900_wake_interrupt(int irq, void *ignored)
+{
+       return IRQ_HANDLED;
+}
+
+static void amlm5900_init_pm(void)
+{
+       int ret = 0;
+
+       ret = request_irq(IRQ_EINT9, &amlm5900_wake_interrupt,
+                               IRQF_TRIGGER_RISING | IRQF_SHARED,
+                               "amlm5900_wakeup", &amlm5900_wake_interrupt);
+       if (ret != 0) {
+               printk(KERN_ERR "AML-M5900: no wakeup irq, %d?\n", ret);
+       } else {
+               enable_irq_wake(IRQ_EINT9);
+               /* configure the suspend/resume status pin */
+               s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT);
+               s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_UP);
+       }
+}
+static void __init amlm5900_init(void)
+{
+       amlm5900_init_pm();
+#ifdef CONFIG_FB_S3C2410
+       s3c24xx_fb_set_platdata(&amlm5900_fb_info);
+#endif
+       s3c_i2c0_set_platdata(NULL);
+       platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices));
+}
+
+MACHINE_START(AML_M5900, "AML_M5900")
+       .atag_offset    = 0x100,
+       .map_io         = amlm5900_map_io,
+       .init_irq       = s3c24xx_init_irq,
+       .init_machine   = amlm5900_init,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c2410_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-anubis.c b/arch/arm/mach-s3c24xx/mach-anubis.c
new file mode 100644 (file)
index 0000000..60c72c5
--- /dev/null
@@ -0,0 +1,492 @@
+/* linux/arch/arm/mach-s3c2440/mach-anubis.c
+ *
+ * Copyright 2003-2009 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/sm501.h>
+#include <linux/sm501-regs.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/anubis-map.h>
+#include <mach/anubis-irq.h>
+#include <mach/anubis-cpld.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+#include <plat/nand.h>
+#include <plat/iic.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <net/ax88796.h>
+
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/audio-simtec.h>
+
+#include "simtec.h"
+#include "common.h"
+
+#define COPYRIGHT ", Copyright 2005-2009 Simtec Electronics"
+
+static struct map_desc anubis_iodesc[] __initdata = {
+  /* ISA IO areas */
+
+  {
+       .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
+       .pfn            = __phys_to_pfn(0x0),
+       .length         = SZ_4M,
+       .type           = MT_DEVICE,
+  }, {
+       .virtual        = (u32)S3C24XX_VA_ISA_WORD,
+       .pfn            = __phys_to_pfn(0x0),
+       .length         = SZ_4M,
+       .type           = MT_DEVICE,
+  },
+
+  /* we could possibly compress the next set down into a set of smaller tables
+   * pagetables, but that would mean using an L2 section, and it still means
+   * we cannot actually feed the same register to an LDR due to 16K spacing
+   */
+
+  /* CPLD control registers */
+
+  {
+       .virtual        = (u32)ANUBIS_VA_CTRL1,
+       .pfn            = __phys_to_pfn(ANUBIS_PA_CTRL1),
+       .length         = SZ_4K,
+       .type           = MT_DEVICE,
+  }, {
+       .virtual        = (u32)ANUBIS_VA_IDREG,
+       .pfn            = __phys_to_pfn(ANUBIS_PA_IDREG),
+       .length         = SZ_4K,
+       .type           = MT_DEVICE,
+  },
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+               .clk_sel        = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
+       },
+       [1] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+               .clk_sel        = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
+       },
+};
+
+/* NAND Flash on Anubis board */
+
+static int external_map[]   = { 2 };
+static int chip0_map[]      = { 0 };
+static int chip1_map[]      = { 1 };
+
+static struct mtd_partition __initdata anubis_default_nand_part[] = {
+       [0] = {
+               .name   = "Boot Agent",
+               .size   = SZ_16K,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "/boot",
+               .size   = SZ_4M - SZ_16K,
+               .offset = SZ_16K,
+       },
+       [2] = {
+               .name   = "user1",
+               .offset = SZ_4M,
+               .size   = SZ_32M - SZ_4M,
+       },
+       [3] = {
+               .name   = "user2",
+               .offset = SZ_32M,
+               .size   = MTDPART_SIZ_FULL,
+       }
+};
+
+static struct mtd_partition __initdata anubis_default_nand_part_large[] = {
+       [0] = {
+               .name   = "Boot Agent",
+               .size   = SZ_128K,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "/boot",
+               .size   = SZ_4M - SZ_128K,
+               .offset = SZ_128K,
+       },
+       [2] = {
+               .name   = "user1",
+               .offset = SZ_4M,
+               .size   = SZ_32M - SZ_4M,
+       },
+       [3] = {
+               .name   = "user2",
+               .offset = SZ_32M,
+               .size   = MTDPART_SIZ_FULL,
+       }
+};
+
+/* the Anubis has 3 selectable slots for nand-flash, the two
+ * on-board chip areas, as well as the external slot.
+ *
+ * Note, there is no current hot-plug support for the External
+ * socket.
+*/
+
+static struct s3c2410_nand_set __initdata anubis_nand_sets[] = {
+       [1] = {
+               .name           = "External",
+               .nr_chips       = 1,
+               .nr_map         = external_map,
+               .nr_partitions  = ARRAY_SIZE(anubis_default_nand_part),
+               .partitions     = anubis_default_nand_part,
+       },
+       [0] = {
+               .name           = "chip0",
+               .nr_chips       = 1,
+               .nr_map         = chip0_map,
+               .nr_partitions  = ARRAY_SIZE(anubis_default_nand_part),
+               .partitions     = anubis_default_nand_part,
+       },
+       [2] = {
+               .name           = "chip1",
+               .nr_chips       = 1,
+               .nr_map         = chip1_map,
+               .nr_partitions  = ARRAY_SIZE(anubis_default_nand_part),
+               .partitions     = anubis_default_nand_part,
+       },
+};
+
+static void anubis_nand_select(struct s3c2410_nand_set *set, int slot)
+{
+       unsigned int tmp;
+
+       slot = set->nr_map[slot] & 3;
+
+       pr_debug("anubis_nand: selecting slot %d (set %p,%p)\n",
+                slot, set, set->nr_map);
+
+       tmp = __raw_readb(ANUBIS_VA_CTRL1);
+       tmp &= ~ANUBIS_CTRL1_NANDSEL;
+       tmp |= slot;
+
+       pr_debug("anubis_nand: ctrl1 now %02x\n", tmp);
+
+       __raw_writeb(tmp, ANUBIS_VA_CTRL1);
+}
+
+static struct s3c2410_platform_nand __initdata anubis_nand_info = {
+       .tacls          = 25,
+       .twrph0         = 55,
+       .twrph1         = 40,
+       .nr_sets        = ARRAY_SIZE(anubis_nand_sets),
+       .sets           = anubis_nand_sets,
+       .select_chip    = anubis_nand_select,
+};
+
+/* IDE channels */
+
+static struct pata_platform_info anubis_ide_platdata = {
+       .ioport_shift   = 5,
+};
+
+static struct resource anubis_ide0_resource[] = {
+       {
+               .start  = S3C2410_CS3,
+               .end    = S3C2410_CS3 + (8*32) - 1,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = S3C2410_CS3 + (1<<26) + (6*32),
+               .end    = S3C2410_CS3 + (1<<26) + (7*32) - 1,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = IRQ_IDE0,
+               .end    = IRQ_IDE0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device anubis_device_ide0 = {
+       .name           = "pata_platform",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(anubis_ide0_resource),
+       .resource       = anubis_ide0_resource,
+       .dev    = {
+               .platform_data = &anubis_ide_platdata,
+               .coherent_dma_mask = ~0,
+       },
+};
+
+static struct resource anubis_ide1_resource[] = {
+       {
+               .start  = S3C2410_CS4,
+               .end    = S3C2410_CS4 + (8*32) - 1,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = S3C2410_CS4 + (1<<26) + (6*32),
+               .end    = S3C2410_CS4 + (1<<26) + (7*32) - 1,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = IRQ_IDE0,
+               .end    = IRQ_IDE0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device anubis_device_ide1 = {
+       .name           = "pata_platform",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(anubis_ide1_resource),
+       .resource       = anubis_ide1_resource,
+       .dev    = {
+               .platform_data = &anubis_ide_platdata,
+               .coherent_dma_mask = ~0,
+       },
+};
+
+/* Asix AX88796 10/100 ethernet controller */
+
+static struct ax_plat_data anubis_asix_platdata = {
+       .flags          = AXFLG_MAC_FROMDEV,
+       .wordlength     = 2,
+       .dcr_val        = 0x48,
+       .rcr_val        = 0x40,
+};
+
+static struct resource anubis_asix_resource[] = {
+       [0] = {
+               .start = S3C2410_CS5,
+               .end   = S3C2410_CS5 + (0x20 * 0x20) -1,
+               .flags = IORESOURCE_MEM
+       },
+       [1] = {
+               .start = IRQ_ASIX,
+               .end   = IRQ_ASIX,
+               .flags = IORESOURCE_IRQ
+       }
+};
+
+static struct platform_device anubis_device_asix = {
+       .name           = "ax88796",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(anubis_asix_resource),
+       .resource       = anubis_asix_resource,
+       .dev            = {
+               .platform_data = &anubis_asix_platdata,
+       }
+};
+
+/* SM501 */
+
+static struct resource anubis_sm501_resource[] = {
+       [0] = {
+               .start  = S3C2410_CS2,
+               .end    = S3C2410_CS2 + SZ_8M,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = S3C2410_CS2 + SZ_64M - SZ_2M,
+               .end    = S3C2410_CS2 + SZ_64M - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [2] = {
+               .start  = IRQ_EINT0,
+               .end    = IRQ_EINT0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct sm501_initdata anubis_sm501_initdata = {
+       .gpio_high      = {
+               .set    = 0x3F000000,           /* 24bit panel */
+               .mask   = 0x0,
+       },
+       .misc_timing    = {
+               .set    = 0x010100,             /* SDRAM timing */
+               .mask   = 0x1F1F00,
+       },
+       .misc_control   = {
+               .set    = SM501_MISC_PNL_24BIT,
+               .mask   = 0,
+       },
+
+       .devices        = SM501_USE_GPIO,
+
+       /* set the SDRAM and bus clocks */
+       .mclk           = 72 * MHZ,
+       .m1xclk         = 144 * MHZ,
+};
+
+static struct sm501_platdata_gpio_i2c anubis_sm501_gpio_i2c[] = {
+       [0] = {
+               .bus_num        = 1,
+               .pin_scl        = 44,
+               .pin_sda        = 45,
+       },
+       [1] = {
+               .bus_num        = 2,
+               .pin_scl        = 40,
+               .pin_sda        = 41,
+       },
+};
+
+static struct sm501_platdata anubis_sm501_platdata = {
+       .init           = &anubis_sm501_initdata,
+       .gpio_base      = -1,
+       .gpio_i2c       = anubis_sm501_gpio_i2c,
+       .gpio_i2c_nr    = ARRAY_SIZE(anubis_sm501_gpio_i2c),
+};
+
+static struct platform_device anubis_device_sm501 = {
+       .name           = "sm501",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(anubis_sm501_resource),
+       .resource       = anubis_sm501_resource,
+       .dev            = {
+               .platform_data = &anubis_sm501_platdata,
+       },
+};
+
+/* Standard Anubis devices */
+
+static struct platform_device *anubis_devices[] __initdata = {
+       &s3c_device_ohci,
+       &s3c_device_wdt,
+       &s3c_device_adc,
+       &s3c_device_i2c0,
+       &s3c_device_rtc,
+       &s3c_device_nand,
+       &anubis_device_ide0,
+       &anubis_device_ide1,
+       &anubis_device_asix,
+       &anubis_device_sm501,
+};
+
+static struct clk *anubis_clocks[] __initdata = {
+       &s3c24xx_dclk0,
+       &s3c24xx_dclk1,
+       &s3c24xx_clkout0,
+       &s3c24xx_clkout1,
+       &s3c24xx_uclk,
+};
+
+/* I2C devices. */
+
+static struct i2c_board_info anubis_i2c_devs[] __initdata = {
+       {
+               I2C_BOARD_INFO("tps65011", 0x48),
+               .irq    = IRQ_EINT20,
+       }
+};
+
+/* Audio setup */
+static struct s3c24xx_audio_simtec_pdata __initdata anubis_audio = {
+       .have_mic       = 1,
+       .have_lout      = 1,
+       .output_cdclk   = 1,
+       .use_mpllin     = 1,
+       .amp_gpio       = S3C2410_GPB(2),
+       .amp_gain[0]    = S3C2410_GPD(10),
+       .amp_gain[1]    = S3C2410_GPD(11),
+};
+
+static void __init anubis_map_io(void)
+{
+       /* initialise the clocks */
+
+       s3c24xx_dclk0.parent = &clk_upll;
+       s3c24xx_dclk0.rate   = 12*1000*1000;
+
+       s3c24xx_dclk1.parent = &clk_upll;
+       s3c24xx_dclk1.rate   = 24*1000*1000;
+
+       s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
+       s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
+
+       s3c24xx_uclk.parent  = &s3c24xx_clkout1;
+
+       s3c24xx_register_clocks(anubis_clocks, ARRAY_SIZE(anubis_clocks));
+
+       s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
+       s3c24xx_init_clocks(0);
+       s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
+
+       /* check for the newer revision boards with large page nand */
+
+       if ((__raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK) >= 4) {
+               printk(KERN_INFO "ANUBIS-B detected (revision %d)\n",
+                      __raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK);
+               anubis_nand_sets[0].partitions = anubis_default_nand_part_large;
+               anubis_nand_sets[0].nr_partitions = ARRAY_SIZE(anubis_default_nand_part_large);
+       } else {
+               /* ensure that the GPIO is setup */
+               s3c2410_gpio_setpin(S3C2410_GPA(0), 1);
+       }
+}
+
+static void __init anubis_init(void)
+{
+       s3c_i2c0_set_platdata(NULL);
+       s3c_nand_set_platdata(&anubis_nand_info);
+       simtec_audio_add(NULL, false, &anubis_audio);
+
+       platform_add_devices(anubis_devices, ARRAY_SIZE(anubis_devices));
+
+       i2c_register_board_info(0, anubis_i2c_devs,
+                               ARRAY_SIZE(anubis_i2c_devs));
+}
+
+
+MACHINE_START(ANUBIS, "Simtec-Anubis")
+       /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
+       .atag_offset    = 0x100,
+       .map_io         = anubis_map_io,
+       .init_machine   = anubis_init,
+       .init_irq       = s3c24xx_init_irq,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c244x_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-at2440evb.c b/arch/arm/mach-s3c24xx/mach-at2440evb.c
new file mode 100644 (file)
index 0000000..d7ae49c
--- /dev/null
@@ -0,0 +1,226 @@
+/* linux/arch/arm/mach-s3c2440/mach-at2440evb.c
+ *
+ * Copyright (c) 2008 Ramax Lo <ramaxlo@gmail.com>
+ *      Based on mach-anubis.c by Ben Dooks <ben@simtec.co.uk>
+ *      and modifications by SBZ <sbz@spgui.org> and
+ *      Weibing <http://weibing.blogbus.com>
+ *
+ * For product information, visit http://www.arm.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/serial_core.h>
+#include <linux/dm9000.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/fb.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+#include <plat/nand.h>
+#include <plat/iic.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/mci.h>
+
+#include "common.h"
+
+static struct map_desc at2440evb_iodesc[] __initdata = {
+       /* Nothing here */
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+               .clk_sel        = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+               .clk_sel        = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
+       },
+};
+
+/* NAND Flash on AT2440EVB board */
+
+static struct mtd_partition __initdata at2440evb_default_nand_part[] = {
+       [0] = {
+               .name   = "Boot Agent",
+               .size   = SZ_256K,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "Kernel",
+               .size   = SZ_2M,
+               .offset = SZ_256K,
+       },
+       [2] = {
+               .name   = "Root",
+               .offset = SZ_256K + SZ_2M,
+               .size   = MTDPART_SIZ_FULL,
+       },
+};
+
+static struct s3c2410_nand_set __initdata at2440evb_nand_sets[] = {
+       [0] = {
+               .name           = "nand",
+               .nr_chips       = 1,
+               .nr_partitions  = ARRAY_SIZE(at2440evb_default_nand_part),
+               .partitions     = at2440evb_default_nand_part,
+       },
+};
+
+static struct s3c2410_platform_nand __initdata at2440evb_nand_info = {
+       .tacls          = 25,
+       .twrph0         = 55,
+       .twrph1         = 40,
+       .nr_sets        = ARRAY_SIZE(at2440evb_nand_sets),
+       .sets           = at2440evb_nand_sets,
+};
+
+/* DM9000AEP 10/100 ethernet controller */
+
+static struct resource at2440evb_dm9k_resource[] = {
+       [0] = {
+               .start = S3C2410_CS3,
+               .end   = S3C2410_CS3 + 3,
+               .flags = IORESOURCE_MEM
+       },
+       [1] = {
+               .start = S3C2410_CS3 + 4,
+               .end   = S3C2410_CS3 + 7,
+               .flags = IORESOURCE_MEM
+       },
+       [2] = {
+               .start = IRQ_EINT7,
+               .end   = IRQ_EINT7,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+       }
+};
+
+static struct dm9000_plat_data at2440evb_dm9k_pdata = {
+       .flags          = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+};
+
+static struct platform_device at2440evb_device_eth = {
+       .name           = "dm9000",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(at2440evb_dm9k_resource),
+       .resource       = at2440evb_dm9k_resource,
+       .dev            = {
+               .platform_data  = &at2440evb_dm9k_pdata,
+       },
+};
+
+static struct s3c24xx_mci_pdata at2440evb_mci_pdata __initdata = {
+       .gpio_detect    = S3C2410_GPG(10),
+};
+
+/* 7" LCD panel */
+
+static struct s3c2410fb_display at2440evb_lcd_cfg __initdata = {
+
+       .lcdcon5        = S3C2410_LCDCON5_FRM565 |
+                         S3C2410_LCDCON5_INVVLINE |
+                         S3C2410_LCDCON5_INVVFRAME |
+                         S3C2410_LCDCON5_PWREN |
+                         S3C2410_LCDCON5_HWSWP,
+
+       .type           = S3C2410_LCDCON1_TFT,
+
+       .width          = 800,
+       .height         = 480,
+
+       .pixclock       = 33333, /* HCLK 60 MHz, divisor 2 */
+       .xres           = 800,
+       .yres           = 480,
+       .bpp            = 16,
+       .left_margin    = 88,
+       .right_margin   = 40,
+       .hsync_len      = 128,
+       .upper_margin   = 32,
+       .lower_margin   = 11,
+       .vsync_len      = 2,
+};
+
+static struct s3c2410fb_mach_info at2440evb_fb_info __initdata = {
+       .displays       = &at2440evb_lcd_cfg,
+       .num_displays   = 1,
+       .default_display = 0,
+};
+
+static struct platform_device *at2440evb_devices[] __initdata = {
+       &s3c_device_ohci,
+       &s3c_device_wdt,
+       &s3c_device_adc,
+       &s3c_device_i2c0,
+       &s3c_device_rtc,
+       &s3c_device_nand,
+       &s3c_device_sdi,
+       &s3c_device_lcd,
+       &at2440evb_device_eth,
+};
+
+static void __init at2440evb_map_io(void)
+{
+       s3c24xx_init_io(at2440evb_iodesc, ARRAY_SIZE(at2440evb_iodesc));
+       s3c24xx_init_clocks(16934400);
+       s3c24xx_init_uarts(at2440evb_uartcfgs, ARRAY_SIZE(at2440evb_uartcfgs));
+}
+
+static void __init at2440evb_init(void)
+{
+       s3c24xx_fb_set_platdata(&at2440evb_fb_info);
+       s3c24xx_mci_set_platdata(&at2440evb_mci_pdata);
+       s3c_nand_set_platdata(&at2440evb_nand_info);
+       s3c_i2c0_set_platdata(NULL);
+
+       platform_add_devices(at2440evb_devices, ARRAY_SIZE(at2440evb_devices));
+}
+
+
+MACHINE_START(AT2440EVB, "AT2440EVB")
+       .atag_offset    = 0x100,
+       .map_io         = at2440evb_map_io,
+       .init_machine   = at2440evb_init,
+       .init_irq       = s3c24xx_init_irq,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c244x_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-bast.c b/arch/arm/mach-s3c24xx/mach-bast.c
new file mode 100644 (file)
index 0000000..53219c0
--- /dev/null
@@ -0,0 +1,644 @@
+/* linux/arch/arm/mach-s3c2410/mach-bast.c
+ *
+ * Copyright 2003-2008 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.simtec.co.uk/products/EB2410ITX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/syscore_ops.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/dm9000.h>
+#include <linux/ata_platform.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+
+#include <net/ax88796.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/bast-map.h>
+#include <mach/bast-irq.h>
+#include <mach/bast-cpld.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+//#include <asm/debug-ll.h>
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+
+#include <plat/hwmon.h>
+#include <plat/nand.h>
+#include <plat/iic.h>
+#include <mach/fb.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <linux/serial_8250.h>
+
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/cpu-freq.h>
+#include <plat/gpio-cfg.h>
+#include <plat/audio-simtec.h>
+
+#include "simtec.h"
+#include "common.h"
+
+#define COPYRIGHT ", Copyright 2004-2008 Simtec Electronics"
+
+/* macros for virtual address mods for the io space entries */
+#define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5)
+#define VA_C4(item) ((unsigned long)(item) + BAST_VAM_CS4)
+#define VA_C3(item) ((unsigned long)(item) + BAST_VAM_CS3)
+#define VA_C2(item) ((unsigned long)(item) + BAST_VAM_CS2)
+
+/* macros to modify the physical addresses for io space */
+
+#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2))
+#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3))
+#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4))
+#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5))
+
+static struct map_desc bast_iodesc[] __initdata = {
+  /* ISA IO areas */
+  {
+         .virtual      = (u32)S3C24XX_VA_ISA_BYTE,
+         .pfn          = PA_CS2(BAST_PA_ISAIO),
+         .length       = SZ_16M,
+         .type         = MT_DEVICE,
+  }, {
+         .virtual      = (u32)S3C24XX_VA_ISA_WORD,
+         .pfn          = PA_CS3(BAST_PA_ISAIO),
+         .length       = SZ_16M,
+         .type         = MT_DEVICE,
+  },
+  /* bast CPLD control registers, and external interrupt controls */
+  {
+         .virtual      = (u32)BAST_VA_CTRL1,
+         .pfn          = __phys_to_pfn(BAST_PA_CTRL1),
+         .length       = SZ_1M,
+         .type         = MT_DEVICE,
+  }, {
+         .virtual      = (u32)BAST_VA_CTRL2,
+         .pfn          = __phys_to_pfn(BAST_PA_CTRL2),
+         .length       = SZ_1M,
+         .type         = MT_DEVICE,
+  }, {
+         .virtual      = (u32)BAST_VA_CTRL3,
+         .pfn          = __phys_to_pfn(BAST_PA_CTRL3),
+         .length       = SZ_1M,
+         .type         = MT_DEVICE,
+  }, {
+         .virtual      = (u32)BAST_VA_CTRL4,
+         .pfn          = __phys_to_pfn(BAST_PA_CTRL4),
+         .length       = SZ_1M,
+         .type         = MT_DEVICE,
+  },
+  /* PC104 IRQ mux */
+  {
+         .virtual      = (u32)BAST_VA_PC104_IRQREQ,
+         .pfn          = __phys_to_pfn(BAST_PA_PC104_IRQREQ),
+         .length       = SZ_1M,
+         .type         = MT_DEVICE,
+  }, {
+         .virtual      = (u32)BAST_VA_PC104_IRQRAW,
+         .pfn          = __phys_to_pfn(BAST_PA_PC104_IRQRAW),
+         .length       = SZ_1M,
+         .type         = MT_DEVICE,
+  }, {
+         .virtual      = (u32)BAST_VA_PC104_IRQMASK,
+         .pfn          = __phys_to_pfn(BAST_PA_PC104_IRQMASK),
+         .length       = SZ_1M,
+         .type         = MT_DEVICE,
+  },
+
+  /* peripheral space... one for each of fast/slow/byte/16bit */
+  /* note, ide is only decoded in word space, even though some registers
+   * are only 8bit */
+
+  /* slow, byte */
+  { VA_C2(BAST_VA_ISAIO),   PA_CS2(BAST_PA_ISAIO),    SZ_16M, MT_DEVICE },
+  { VA_C2(BAST_VA_ISAMEM),  PA_CS2(BAST_PA_ISAMEM),   SZ_16M, MT_DEVICE },
+  { VA_C2(BAST_VA_SUPERIO), PA_CS2(BAST_PA_SUPERIO),  SZ_1M,  MT_DEVICE },
+
+  /* slow, word */
+  { VA_C3(BAST_VA_ISAIO),   PA_CS3(BAST_PA_ISAIO),    SZ_16M, MT_DEVICE },
+  { VA_C3(BAST_VA_ISAMEM),  PA_CS3(BAST_PA_ISAMEM),   SZ_16M, MT_DEVICE },
+  { VA_C3(BAST_VA_SUPERIO), PA_CS3(BAST_PA_SUPERIO),  SZ_1M,  MT_DEVICE },
+
+  /* fast, byte */
+  { VA_C4(BAST_VA_ISAIO),   PA_CS4(BAST_PA_ISAIO),    SZ_16M, MT_DEVICE },
+  { VA_C4(BAST_VA_ISAMEM),  PA_CS4(BAST_PA_ISAMEM),   SZ_16M, MT_DEVICE },
+  { VA_C4(BAST_VA_SUPERIO), PA_CS4(BAST_PA_SUPERIO),  SZ_1M,  MT_DEVICE },
+
+  /* fast, word */
+  { VA_C5(BAST_VA_ISAIO),   PA_CS5(BAST_PA_ISAIO),    SZ_16M, MT_DEVICE },
+  { VA_C5(BAST_VA_ISAMEM),  PA_CS5(BAST_PA_ISAMEM),   SZ_16M, MT_DEVICE },
+  { VA_C5(BAST_VA_SUPERIO), PA_CS5(BAST_PA_SUPERIO),  SZ_1M,  MT_DEVICE },
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       /* port 2 is not actually used */
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       }
+};
+
+/* NAND Flash on BAST board */
+
+#ifdef CONFIG_PM
+static int bast_pm_suspend(void)
+{
+       /* ensure that an nRESET is not generated on resume. */
+       gpio_direction_output(S3C2410_GPA(21), 1);
+       return 0;
+}
+
+static void bast_pm_resume(void)
+{
+       s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
+}
+
+#else
+#define bast_pm_suspend NULL
+#define bast_pm_resume NULL
+#endif
+
+static struct syscore_ops bast_pm_syscore_ops = {
+       .suspend        = bast_pm_suspend,
+       .resume         = bast_pm_resume,
+};
+
+static int smartmedia_map[] = { 0 };
+static int chip0_map[] = { 1 };
+static int chip1_map[] = { 2 };
+static int chip2_map[] = { 3 };
+
+static struct mtd_partition __initdata bast_default_nand_part[] = {
+       [0] = {
+               .name   = "Boot Agent",
+               .size   = SZ_16K,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "/boot",
+               .size   = SZ_4M - SZ_16K,
+               .offset = SZ_16K,
+       },
+       [2] = {
+               .name   = "user",
+               .offset = SZ_4M,
+               .size   = MTDPART_SIZ_FULL,
+       }
+};
+
+/* the bast has 4 selectable slots for nand-flash, the three
+ * on-board chip areas, as well as the external SmartMedia
+ * slot.
+ *
+ * Note, there is no current hot-plug support for the SmartMedia
+ * socket.
+*/
+
+static struct s3c2410_nand_set __initdata bast_nand_sets[] = {
+       [0] = {
+               .name           = "SmartMedia",
+               .nr_chips       = 1,
+               .nr_map         = smartmedia_map,
+               .options        = NAND_SCAN_SILENT_NODEV,
+               .nr_partitions  = ARRAY_SIZE(bast_default_nand_part),
+               .partitions     = bast_default_nand_part,
+       },
+       [1] = {
+               .name           = "chip0",
+               .nr_chips       = 1,
+               .nr_map         = chip0_map,
+               .nr_partitions  = ARRAY_SIZE(bast_default_nand_part),
+               .partitions     = bast_default_nand_part,
+       },
+       [2] = {
+               .name           = "chip1",
+               .nr_chips       = 1,
+               .nr_map         = chip1_map,
+               .options        = NAND_SCAN_SILENT_NODEV,
+               .nr_partitions  = ARRAY_SIZE(bast_default_nand_part),
+               .partitions     = bast_default_nand_part,
+       },
+       [3] = {
+               .name           = "chip2",
+               .nr_chips       = 1,
+               .nr_map         = chip2_map,
+               .options        = NAND_SCAN_SILENT_NODEV,
+               .nr_partitions  = ARRAY_SIZE(bast_default_nand_part),
+               .partitions     = bast_default_nand_part,
+       }
+};
+
+static void bast_nand_select(struct s3c2410_nand_set *set, int slot)
+{
+       unsigned int tmp;
+
+       slot = set->nr_map[slot] & 3;
+
+       pr_debug("bast_nand: selecting slot %d (set %p,%p)\n",
+                slot, set, set->nr_map);
+
+       tmp = __raw_readb(BAST_VA_CTRL2);
+       tmp &= BAST_CPLD_CTLR2_IDERST;
+       tmp |= slot;
+       tmp |= BAST_CPLD_CTRL2_WNAND;
+
+       pr_debug("bast_nand: ctrl2 now %02x\n", tmp);
+
+       __raw_writeb(tmp, BAST_VA_CTRL2);
+}
+
+static struct s3c2410_platform_nand __initdata bast_nand_info = {
+       .tacls          = 30,
+       .twrph0         = 60,
+       .twrph1         = 60,
+       .nr_sets        = ARRAY_SIZE(bast_nand_sets),
+       .sets           = bast_nand_sets,
+       .select_chip    = bast_nand_select,
+};
+
+/* DM9000 */
+
+static struct resource bast_dm9k_resource[] = {
+       [0] = {
+               .start = S3C2410_CS5 + BAST_PA_DM9000,
+               .end   = S3C2410_CS5 + BAST_PA_DM9000 + 3,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = S3C2410_CS5 + BAST_PA_DM9000 + 0x40,
+               .end   = S3C2410_CS5 + BAST_PA_DM9000 + 0x40 + 0x3f,
+               .flags = IORESOURCE_MEM,
+       },
+       [2] = {
+               .start = IRQ_DM9000,
+               .end   = IRQ_DM9000,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+       }
+
+};
+
+/* for the moment we limit ourselves to 16bit IO until some
+ * better IO routines can be written and tested
+*/
+
+static struct dm9000_plat_data bast_dm9k_platdata = {
+       .flags          = DM9000_PLATF_16BITONLY,
+};
+
+static struct platform_device bast_device_dm9k = {
+       .name           = "dm9000",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(bast_dm9k_resource),
+       .resource       = bast_dm9k_resource,
+       .dev            = {
+               .platform_data = &bast_dm9k_platdata,
+       }
+};
+
+/* serial devices */
+
+#define SERIAL_BASE  (S3C2410_CS2 + BAST_PA_SUPERIO)
+#define SERIAL_FLAGS (UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SHARE_IRQ)
+#define SERIAL_CLK   (1843200)
+
+static struct plat_serial8250_port bast_sio_data[] = {
+       [0] = {
+               .mapbase        = SERIAL_BASE + 0x2f8,
+               .irq            = IRQ_PCSERIAL1,
+               .flags          = SERIAL_FLAGS,
+               .iotype         = UPIO_MEM,
+               .regshift       = 0,
+               .uartclk        = SERIAL_CLK,
+       },
+       [1] = {
+               .mapbase        = SERIAL_BASE + 0x3f8,
+               .irq            = IRQ_PCSERIAL2,
+               .flags          = SERIAL_FLAGS,
+               .iotype         = UPIO_MEM,
+               .regshift       = 0,
+               .uartclk        = SERIAL_CLK,
+       },
+       { }
+};
+
+static struct platform_device bast_sio = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_PLATFORM,
+       .dev                    = {
+               .platform_data  = &bast_sio_data,
+       },
+};
+
+/* we have devices on the bus which cannot work much over the
+ * standard 100KHz i2c bus frequency
+*/
+
+static struct s3c2410_platform_i2c __initdata bast_i2c_info = {
+       .flags          = 0,
+       .slave_addr     = 0x10,
+       .frequency      = 100*1000,
+};
+
+/* Asix AX88796 10/100 ethernet controller */
+
+static struct ax_plat_data bast_asix_platdata = {
+       .flags          = AXFLG_MAC_FROMDEV,
+       .wordlength     = 2,
+       .dcr_val        = 0x48,
+       .rcr_val        = 0x40,
+};
+
+static struct resource bast_asix_resource[] = {
+       [0] = {
+               .start = S3C2410_CS5 + BAST_PA_ASIXNET,
+               .end   = S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20) - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20),
+               .end   = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20),
+               .flags = IORESOURCE_MEM,
+       },
+       [2] = {
+               .start = IRQ_ASIX,
+               .end   = IRQ_ASIX,
+               .flags = IORESOURCE_IRQ
+       }
+};
+
+static struct platform_device bast_device_asix = {
+       .name           = "ax88796",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(bast_asix_resource),
+       .resource       = bast_asix_resource,
+       .dev            = {
+               .platform_data = &bast_asix_platdata
+       }
+};
+
+/* Asix AX88796 10/100 ethernet controller parallel port */
+
+static struct resource bast_asixpp_resource[] = {
+       [0] = {
+               .start = S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20),
+               .end   = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1b * 0x20) - 1,
+               .flags = IORESOURCE_MEM,
+       }
+};
+
+static struct platform_device bast_device_axpp = {
+       .name           = "ax88796-pp",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(bast_asixpp_resource),
+       .resource       = bast_asixpp_resource,
+};
+
+/* LCD/VGA controller */
+
+static struct s3c2410fb_display __initdata bast_lcd_info[] = {
+       {
+               .type           = S3C2410_LCDCON1_TFT,
+               .width          = 640,
+               .height         = 480,
+
+               .pixclock       = 33333,
+               .xres           = 640,
+               .yres           = 480,
+               .bpp            = 4,
+               .left_margin    = 40,
+               .right_margin   = 20,
+               .hsync_len      = 88,
+               .upper_margin   = 30,
+               .lower_margin   = 32,
+               .vsync_len      = 3,
+
+               .lcdcon5        = 0x00014b02,
+       },
+       {
+               .type           = S3C2410_LCDCON1_TFT,
+               .width          = 640,
+               .height         = 480,
+
+               .pixclock       = 33333,
+               .xres           = 640,
+               .yres           = 480,
+               .bpp            = 8,
+               .left_margin    = 40,
+               .right_margin   = 20,
+               .hsync_len      = 88,
+               .upper_margin   = 30,
+               .lower_margin   = 32,
+               .vsync_len      = 3,
+
+               .lcdcon5        = 0x00014b02,
+       },
+       {
+               .type           = S3C2410_LCDCON1_TFT,
+               .width          = 640,
+               .height         = 480,
+
+               .pixclock       = 33333,
+               .xres           = 640,
+               .yres           = 480,
+               .bpp            = 16,
+               .left_margin    = 40,
+               .right_margin   = 20,
+               .hsync_len      = 88,
+               .upper_margin   = 30,
+               .lower_margin   = 32,
+               .vsync_len      = 3,
+
+               .lcdcon5        = 0x00014b02,
+       },
+};
+
+/* LCD/VGA controller */
+
+static struct s3c2410fb_mach_info __initdata bast_fb_info = {
+
+       .displays = bast_lcd_info,
+       .num_displays = ARRAY_SIZE(bast_lcd_info),
+       .default_display = 1,
+};
+
+/* I2C devices fitted. */
+
+static struct i2c_board_info bast_i2c_devs[] __initdata = {
+       {
+               I2C_BOARD_INFO("tlv320aic23", 0x1a),
+       }, {
+               I2C_BOARD_INFO("simtec-pmu", 0x6b),
+       }, {
+               I2C_BOARD_INFO("ch7013", 0x75),
+       },
+};
+
+static struct s3c_hwmon_pdata bast_hwmon_info = {
+       /* LCD contrast (0-6.6V) */
+       .in[0] = &(struct s3c_hwmon_chcfg) {
+               .name           = "lcd-contrast",
+               .mult           = 3300,
+               .div            = 512,
+       },
+       /* LED current feedback */
+       .in[1] = &(struct s3c_hwmon_chcfg) {
+               .name           = "led-feedback",
+               .mult           = 3300,
+               .div            = 1024,
+       },
+       /* LCD feedback (0-6.6V) */
+       .in[2] = &(struct s3c_hwmon_chcfg) {
+               .name           = "lcd-feedback",
+               .mult           = 3300,
+               .div            = 512,
+       },
+       /* Vcore (1.8-2.0V), Vref 3.3V  */
+       .in[3] = &(struct s3c_hwmon_chcfg) {
+               .name           = "vcore",
+               .mult           = 3300,
+               .div            = 1024,
+       },
+};
+
+/* Standard BAST devices */
+// cat /sys/devices/platform/s3c24xx-adc/s3c-hwmon/in_0
+
+static struct platform_device *bast_devices[] __initdata = {
+       &s3c_device_ohci,
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_rtc,
+       &s3c_device_nand,
+       &s3c_device_adc,
+       &s3c_device_hwmon,
+       &bast_device_dm9k,
+       &bast_device_asix,
+       &bast_device_axpp,
+       &bast_sio,
+};
+
+static struct clk *bast_clocks[] __initdata = {
+       &s3c24xx_dclk0,
+       &s3c24xx_dclk1,
+       &s3c24xx_clkout0,
+       &s3c24xx_clkout1,
+       &s3c24xx_uclk,
+};
+
+static struct s3c_cpufreq_board __initdata bast_cpufreq = {
+       .refresh        = 7800, /* 7.8usec */
+       .auto_io        = 1,
+       .need_io        = 1,
+};
+
+static struct s3c24xx_audio_simtec_pdata __initdata bast_audio = {
+       .have_mic       = 1,
+       .have_lout      = 1,
+};
+
+static void __init bast_map_io(void)
+{
+       /* initialise the clocks */
+
+       s3c24xx_dclk0.parent = &clk_upll;
+       s3c24xx_dclk0.rate   = 12*1000*1000;
+
+       s3c24xx_dclk1.parent = &clk_upll;
+       s3c24xx_dclk1.rate   = 24*1000*1000;
+
+       s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
+       s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
+
+       s3c24xx_uclk.parent  = &s3c24xx_clkout1;
+
+       s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks));
+
+       s3c_hwmon_set_platdata(&bast_hwmon_info);
+
+       s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
+       s3c24xx_init_clocks(0);
+       s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
+}
+
+static void __init bast_init(void)
+{
+       register_syscore_ops(&bast_pm_syscore_ops);
+
+       s3c_i2c0_set_platdata(&bast_i2c_info);
+       s3c_nand_set_platdata(&bast_nand_info);
+       s3c24xx_fb_set_platdata(&bast_fb_info);
+       platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices));
+
+       i2c_register_board_info(0, bast_i2c_devs,
+                               ARRAY_SIZE(bast_i2c_devs));
+
+       usb_simtec_init();
+       nor_simtec_init();
+       simtec_audio_add(NULL, true, &bast_audio);
+
+       WARN_ON(gpio_request(S3C2410_GPA(21), "bast nreset"));
+       
+       s3c_cpufreq_setboard(&bast_cpufreq);
+}
+
+MACHINE_START(BAST, "Simtec-BAST")
+       /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
+       .atag_offset    = 0x100,
+       .map_io         = bast_map_io,
+       .init_irq       = s3c24xx_init_irq,
+       .init_machine   = bast_init,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c2410_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-gta02.c b/arch/arm/mach-s3c24xx/mach-gta02.c
new file mode 100644 (file)
index 0000000..ba5d853
--- /dev/null
@@ -0,0 +1,605 @@
+/*
+ * linux/arch/arm/mach-s3c2442/mach-gta02.c
+ *
+ * S3C2442 Machine Support for Openmoko GTA02 / FreeRunner.
+ *
+ * Copyright (C) 2006-2009 by Openmoko, Inc.
+ * Authors: Harald Welte <laforge@openmoko.org>
+ *          Andy Green <andy@openmoko.org>
+ *          Werner Almesberger <werner@openmoko.org>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/s3c24xx.h>
+
+#include <linux/mmc/host.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/io.h>
+
+#include <linux/i2c.h>
+#include <linux/regulator/machine.h>
+
+#include <linux/mfd/pcf50633/core.h>
+#include <linux/mfd/pcf50633/mbc.h>
+#include <linux/mfd/pcf50633/adc.h>
+#include <linux/mfd/pcf50633/gpio.h>
+#include <linux/mfd/pcf50633/pmic.h>
+#include <linux/mfd/pcf50633/backlight.h>
+
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-gpioj.h>
+#include <mach/fb.h>
+
+#include <plat/usb-control.h>
+#include <mach/regs-mem.h>
+#include <mach/hardware.h>
+
+#include <mach/gta02.h>
+
+#include <plat/regs-serial.h>
+#include <plat/nand.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/udc.h>
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
+#include <plat/ts.h>
+
+#include "common.h"
+
+static struct pcf50633 *gta02_pcf;
+
+/*
+ * This gets called frequently when we paniced.
+ */
+
+static long gta02_panic_blink(int state)
+{
+       long delay = 0;
+       char led;
+
+       led = (state) ? 1 : 0;
+       gpio_direction_output(GTA02_GPIO_AUX_LED, led);
+
+       return delay;
+}
+
+
+static struct map_desc gta02_iodesc[] __initdata = {
+       {
+               .virtual        = 0xe0000000,
+               .pfn            = __phys_to_pfn(S3C2410_CS3 + 0x01000000),
+               .length         = SZ_1M,
+               .type           = MT_DEVICE
+       },
+};
+
+#define UCON (S3C2410_UCON_DEFAULT | S3C2443_UCON_RXERR_IRQEN)
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c2410_uartcfg gta02_uartcfgs[] = {
+       [0] = {
+               .hwport         = 0,
+               .flags          = 0,
+               .ucon           = UCON,
+               .ulcon          = ULCON,
+               .ufcon          = UFCON,
+       },
+       [1] = {
+               .hwport         = 1,
+               .flags          = 0,
+               .ucon           = UCON,
+               .ulcon          = ULCON,
+               .ufcon          = UFCON,
+       },
+       [2] = {
+               .hwport         = 2,
+               .flags          = 0,
+               .ucon           = UCON,
+               .ulcon          = ULCON,
+               .ufcon          = UFCON,
+       },
+};
+
+#ifdef CONFIG_CHARGER_PCF50633
+/*
+ * On GTA02 the 1A charger features a 48K resistor to 0V on the ID pin.
+ * We use this to recognize that we can pull 1A from the USB socket.
+ *
+ * These constants are the measured pcf50633 ADC levels with the 1A
+ * charger / 48K resistor, and with no pulldown resistor.
+ */
+
+#define ADC_NOM_CHG_DETECT_1A 6
+#define ADC_NOM_CHG_DETECT_USB 43
+
+static void
+gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res)
+{
+       int  ma;
+
+       /* Interpret charger type */
+       if (res < ((ADC_NOM_CHG_DETECT_USB + ADC_NOM_CHG_DETECT_1A) / 2)) {
+
+               /*
+                * Sanity - stop GPO driving out now that we have a 1A charger
+                * GPO controls USB Host power generation on GTA02
+                */
+               pcf50633_gpio_set(pcf, PCF50633_GPO, 0);
+
+               ma = 1000;
+       } else
+               ma = 100;
+
+       pcf50633_mbc_usb_curlim_set(pcf, ma);
+}
+
+static struct delayed_work gta02_charger_work;
+static int gta02_usb_vbus_draw;
+
+static void gta02_charger_worker(struct work_struct *work)
+{
+       if (gta02_usb_vbus_draw) {
+               pcf50633_mbc_usb_curlim_set(gta02_pcf, gta02_usb_vbus_draw);
+               return;
+       }
+
+#ifdef CONFIG_PCF50633_ADC
+       pcf50633_adc_async_read(gta02_pcf,
+                               PCF50633_ADCC1_MUX_ADCIN1,
+                               PCF50633_ADCC1_AVERAGE_16,
+                               gta02_configure_pmu_for_charger,
+                               NULL);
+#else
+       /*
+        * If the PCF50633 ADC is disabled we fallback to a
+        * 100mA limit for safety.
+        */
+       pcf50633_mbc_usb_curlim_set(pcf, 100);
+#endif
+}
+
+#define GTA02_CHARGER_CONFIGURE_TIMEOUT ((3000 * HZ) / 1000)
+
+static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq)
+{
+       if (irq == PCF50633_IRQ_USBINS) {
+               schedule_delayed_work(&gta02_charger_work,
+                                     GTA02_CHARGER_CONFIGURE_TIMEOUT);
+
+               return;
+       }
+
+       if (irq == PCF50633_IRQ_USBREM) {
+               cancel_delayed_work_sync(&gta02_charger_work);
+               gta02_usb_vbus_draw = 0;
+       }
+}
+
+static void gta02_udc_vbus_draw(unsigned int ma)
+{
+       if (!gta02_pcf)
+               return;
+
+       gta02_usb_vbus_draw = ma;
+
+       schedule_delayed_work(&gta02_charger_work,
+                             GTA02_CHARGER_CONFIGURE_TIMEOUT);
+}
+#else /* !CONFIG_CHARGER_PCF50633 */
+#define gta02_pmu_event_callback       NULL
+#define gta02_udc_vbus_draw            NULL
+#endif
+
+/*
+ * This is called when pc50633 is probed, unfortunately quite late in the
+ * day since it is an I2C bus device. Here we can belatedly define some
+ * platform devices with the advantage that we can mark the pcf50633 as the
+ * parent. This makes them get suspended and resumed with their parent
+ * the pcf50633 still around.
+ */
+
+static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf);
+
+
+static char *gta02_batteries[] = {
+       "battery",
+};
+
+static struct pcf50633_bl_platform_data gta02_backlight_data = {
+       .default_brightness = 0x3f,
+       .default_brightness_limit = 0,
+       .ramp_time = 5,
+};
+
+static struct pcf50633_platform_data gta02_pcf_pdata = {
+       .resumers = {
+               [0] =   PCF50633_INT1_USBINS |
+                       PCF50633_INT1_USBREM |
+                       PCF50633_INT1_ALARM,
+               [1] =   PCF50633_INT2_ONKEYF,
+               [2] =   PCF50633_INT3_ONKEY1S,
+               [3] =   PCF50633_INT4_LOWSYS |
+                       PCF50633_INT4_LOWBAT |
+                       PCF50633_INT4_HIGHTMP,
+       },
+
+       .batteries = gta02_batteries,
+       .num_batteries = ARRAY_SIZE(gta02_batteries),
+
+       .charger_reference_current_ma = 1000,
+
+       .backlight_data = &gta02_backlight_data,
+
+       .reg_init_data = {
+               [PCF50633_REGULATOR_AUTO] = {
+                       .constraints = {
+                               .min_uV = 3300000,
+                               .max_uV = 3300000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .always_on = 1,
+                               .apply_uV = 1,
+                       },
+               },
+               [PCF50633_REGULATOR_DOWN1] = {
+                       .constraints = {
+                               .min_uV = 1300000,
+                               .max_uV = 1600000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .always_on = 1,
+                               .apply_uV = 1,
+                       },
+               },
+               [PCF50633_REGULATOR_DOWN2] = {
+                       .constraints = {
+                               .min_uV = 1800000,
+                               .max_uV = 1800000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .apply_uV = 1,
+                               .always_on = 1,
+                       },
+               },
+               [PCF50633_REGULATOR_HCLDO] = {
+                       .constraints = {
+                               .min_uV = 2000000,
+                               .max_uV = 3300000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+                                               REGULATOR_CHANGE_STATUS,
+                       },
+               },
+               [PCF50633_REGULATOR_LDO1] = {
+                       .constraints = {
+                               .min_uV = 3300000,
+                               .max_uV = 3300000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+                               .apply_uV = 1,
+                       },
+               },
+               [PCF50633_REGULATOR_LDO2] = {
+                       .constraints = {
+                               .min_uV = 3300000,
+                               .max_uV = 3300000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .apply_uV = 1,
+                       },
+               },
+               [PCF50633_REGULATOR_LDO3] = {
+                       .constraints = {
+                               .min_uV = 3000000,
+                               .max_uV = 3000000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .apply_uV = 1,
+                       },
+               },
+               [PCF50633_REGULATOR_LDO4] = {
+                       .constraints = {
+                               .min_uV = 3200000,
+                               .max_uV = 3200000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+                               .apply_uV = 1,
+                       },
+               },
+               [PCF50633_REGULATOR_LDO5] = {
+                       .constraints = {
+                               .min_uV = 3000000,
+                               .max_uV = 3000000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+                               .apply_uV = 1,
+                       },
+               },
+               [PCF50633_REGULATOR_LDO6] = {
+                       .constraints = {
+                               .min_uV = 3000000,
+                               .max_uV = 3000000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                       },
+               },
+               [PCF50633_REGULATOR_MEMLDO] = {
+                       .constraints = {
+                               .min_uV = 1800000,
+                               .max_uV = 1800000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                       },
+               },
+
+       },
+       .probe_done = gta02_pmu_attach_child_devices,
+       .mbc_event_callback = gta02_pmu_event_callback,
+};
+
+
+/* NOR Flash. */
+
+#define GTA02_FLASH_BASE       0x18000000 /* GCS3 */
+#define GTA02_FLASH_SIZE       0x200000 /* 2MBytes */
+
+static struct physmap_flash_data gta02_nor_flash_data = {
+       .width          = 2,
+};
+
+static struct resource gta02_nor_flash_resource = {
+       .start          = GTA02_FLASH_BASE,
+       .end            = GTA02_FLASH_BASE + GTA02_FLASH_SIZE - 1,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device gta02_nor_flash = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &gta02_nor_flash_data,
+       },
+       .resource       = &gta02_nor_flash_resource,
+       .num_resources  = 1,
+};
+
+
+static struct platform_device s3c24xx_pwm_device = {
+       .name           = "s3c24xx_pwm",
+       .num_resources  = 0,
+};
+
+static struct platform_device gta02_dfbmcs320_device = {
+       .name = "dfbmcs320",
+};
+
+static struct i2c_board_info gta02_i2c_devs[] __initdata = {
+       {
+               I2C_BOARD_INFO("pcf50633", 0x73),
+               .irq = GTA02_IRQ_PCF50633,
+               .platform_data = &gta02_pcf_pdata,
+       },
+       {
+               I2C_BOARD_INFO("wm8753", 0x1a),
+       },
+};
+
+static struct s3c2410_nand_set __initdata gta02_nand_sets[] = {
+       [0] = {
+               /*
+                * This name is also hard-coded in the boot loaders, so
+                * changing it would would require all users to upgrade
+                * their boot loaders, some of which are stored in a NOR
+                * that is considered to be immutable.
+                */
+               .name           = "neo1973-nand",
+               .nr_chips       = 1,
+               .flash_bbt      = 1,
+       },
+};
+
+/*
+ * Choose a set of timings derived from S3C@2442B MCP54
+ * data sheet (K5D2G13ACM-D075 MCP Memory).
+ */
+
+static struct s3c2410_platform_nand __initdata gta02_nand_info = {
+       .tacls          = 0,
+       .twrph0         = 25,
+       .twrph1         = 15,
+       .nr_sets        = ARRAY_SIZE(gta02_nand_sets),
+       .sets           = gta02_nand_sets,
+};
+
+
+/* Get PMU to set USB current limit accordingly. */
+static struct s3c2410_udc_mach_info gta02_udc_cfg __initdata = {
+       .vbus_draw      = gta02_udc_vbus_draw,
+       .pullup_pin = GTA02_GPIO_USB_PULLUP,
+};
+
+/* USB */
+static struct s3c2410_hcd_info gta02_usb_info __initdata = {
+       .port[0]        = {
+               .flags  = S3C_HCDFLG_USED,
+       },
+       .port[1]        = {
+               .flags  = 0,
+       },
+};
+
+/* Touchscreen */
+static struct s3c2410_ts_mach_info gta02_ts_info = {
+       .delay                  = 10000,
+       .presc                  = 0xff, /* slow as we can go */
+       .oversampling_shift     = 2,
+};
+
+/* Buttons */
+static struct gpio_keys_button gta02_buttons[] = {
+       {
+               .gpio = GTA02_GPIO_AUX_KEY,
+               .code = KEY_PHONE,
+               .desc = "Aux",
+               .type = EV_KEY,
+               .debounce_interval = 100,
+       },
+       {
+               .gpio = GTA02_GPIO_HOLD_KEY,
+               .code = KEY_PAUSE,
+               .desc = "Hold",
+               .type = EV_KEY,
+               .debounce_interval = 100,
+       },
+};
+
+static struct gpio_keys_platform_data gta02_buttons_pdata = {
+       .buttons = gta02_buttons,
+       .nbuttons = ARRAY_SIZE(gta02_buttons),
+};
+
+static struct platform_device gta02_buttons_device = {
+       .name = "gpio-keys",
+       .id = -1,
+       .dev = {
+               .platform_data = &gta02_buttons_pdata,
+       },
+};
+
+static void __init gta02_map_io(void)
+{
+       s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc));
+       s3c24xx_init_clocks(12000000);
+       s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs));
+}
+
+
+/* These are the guys that don't need to be children of PMU. */
+
+static struct platform_device *gta02_devices[] __initdata = {
+       &s3c_device_ohci,
+       &s3c_device_wdt,
+       &s3c_device_sdi,
+       &s3c_device_usbgadget,
+       &s3c_device_nand,
+       &gta02_nor_flash,
+       &s3c24xx_pwm_device,
+       &s3c_device_iis,
+       &samsung_asoc_dma,
+       &s3c_device_i2c0,
+       &gta02_dfbmcs320_device,
+       &gta02_buttons_device,
+       &s3c_device_adc,
+       &s3c_device_ts,
+};
+
+/* These guys DO need to be children of PMU. */
+
+static struct platform_device *gta02_devices_pmu_children[] = {
+};
+
+
+/*
+ * This is called when pc50633 is probed, quite late in the day since it is an
+ * I2C bus device.  Here we can define platform devices with the advantage that
+ * we can mark the pcf50633 as the parent.  This makes them get suspended and
+ * resumed with their parent the pcf50633 still around.  All devices whose
+ * operation depends on something from pcf50633 must have this relationship
+ * made explicit like this, or suspend and resume will become an unreliable
+ * hellworld.
+ */
+
+static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf)
+{
+       int n;
+
+       /* Grab a copy of the now probed PMU pointer. */
+       gta02_pcf = pcf;
+
+       for (n = 0; n < ARRAY_SIZE(gta02_devices_pmu_children); n++)
+               gta02_devices_pmu_children[n]->dev.parent = pcf->dev;
+
+       platform_add_devices(gta02_devices_pmu_children,
+                            ARRAY_SIZE(gta02_devices_pmu_children));
+}
+
+static void gta02_poweroff(void)
+{
+       pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1);
+}
+
+static void __init gta02_machine_init(void)
+{
+       /* Set the panic callback to turn AUX LED on or off. */
+       panic_blink = gta02_panic_blink;
+
+       s3c_pm_init();
+
+#ifdef CONFIG_CHARGER_PCF50633
+       INIT_DELAYED_WORK(&gta02_charger_work, gta02_charger_worker);
+#endif
+
+       s3c24xx_udc_set_platdata(&gta02_udc_cfg);
+       s3c24xx_ts_set_platdata(&gta02_ts_info);
+       s3c_ohci_set_platdata(&gta02_usb_info);
+       s3c_nand_set_platdata(&gta02_nand_info);
+       s3c_i2c0_set_platdata(NULL);
+
+       i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs));
+
+       platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
+       pm_power_off = gta02_poweroff;
+
+       regulator_has_full_constraints();
+}
+
+
+MACHINE_START(NEO1973_GTA02, "GTA02")
+       /* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */
+       .atag_offset    = 0x100,
+       .map_io         = gta02_map_io,
+       .init_irq       = s3c24xx_init_irq,
+       .init_machine   = gta02_machine_init,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c244x_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c
new file mode 100644 (file)
index 0000000..6b21ba1
--- /dev/null
@@ -0,0 +1,757 @@
+/* linux/arch/arm/mach-s3c2410/mach-h1940.c
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.handhelds.org/projects/h1940.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/memblock.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/pwm_backlight.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/pda_power.h>
+#include <linux/s3c_adc_battery.h>
+#include <linux/delay.h>
+
+#include <video/platform_lcd.h>
+
+#include <linux/mmc/host.h>
+#include <linux/export.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-lcd.h>
+#include <mach/regs-clock.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/gpio-fns.h>
+#include <mach/gpio-nrs.h>
+
+#include <mach/h1940.h>
+#include <mach/h1940-latch.h>
+#include <mach/fb.h>
+#include <plat/udc.h>
+#include <plat/iic.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/pm.h>
+#include <plat/mci.h>
+#include <plat/ts.h>
+
+#include <sound/uda1380.h>
+
+#include "common.h"
+
+#define H1940_LATCH            ((void __force __iomem *)0xF8000000)
+
+#define H1940_PA_LATCH         S3C2410_CS2
+
+#define H1940_LATCH_BIT(x)     (1 << ((x) + 16 - S3C_GPIO_END))
+
+static struct map_desc h1940_iodesc[] __initdata = {
+       [0] = {
+               .virtual        = (unsigned long)H1940_LATCH,
+               .pfn            = __phys_to_pfn(H1940_PA_LATCH),
+               .length         = SZ_16K,
+               .type           = MT_DEVICE
+       },
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg h1940_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = 0x245,
+               .ulcon       = 0x03,
+               .ufcon       = 0x00,
+       },
+       /* IR port */
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .uart_flags  = UPF_CONS_FLOW,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x43,
+               .ufcon       = 0x51,
+       }
+};
+
+/* Board control latch control */
+
+static unsigned int latch_state;
+
+static void h1940_latch_control(unsigned int clear, unsigned int set)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+
+       latch_state &= ~clear;
+       latch_state |= set;
+
+       __raw_writel(latch_state, H1940_LATCH);
+
+       local_irq_restore(flags);
+}
+
+static inline int h1940_gpiolib_to_latch(int offset)
+{
+       return 1 << (offset + 16);
+}
+
+static void h1940_gpiolib_latch_set(struct gpio_chip *chip,
+                                       unsigned offset, int value)
+{
+       int latch_bit = h1940_gpiolib_to_latch(offset);
+
+       h1940_latch_control(value ? 0 : latch_bit,
+               value ? latch_bit : 0);
+}
+
+static int h1940_gpiolib_latch_output(struct gpio_chip *chip,
+                                       unsigned offset, int value)
+{
+       h1940_gpiolib_latch_set(chip, offset, value);
+       return 0;
+}
+
+static int h1940_gpiolib_latch_get(struct gpio_chip *chip,
+                                       unsigned offset)
+{
+       return (latch_state >> (offset + 16)) & 1;
+}
+
+static struct gpio_chip h1940_latch_gpiochip = {
+       .base                   = H1940_LATCH_GPIO(0),
+       .owner                  = THIS_MODULE,
+       .label                  = "H1940_LATCH",
+       .ngpio                  = 16,
+       .direction_output       = h1940_gpiolib_latch_output,
+       .set                    = h1940_gpiolib_latch_set,
+       .get                    = h1940_gpiolib_latch_get,
+};
+
+static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
+       .vbus_pin               = S3C2410_GPG(5),
+       .vbus_pin_inverted      = 1,
+       .pullup_pin             = H1940_LATCH_USB_DP,
+};
+
+static struct s3c2410_ts_mach_info h1940_ts_cfg __initdata = {
+               .delay = 10000,
+               .presc = 49,
+               .oversampling_shift = 2,
+               .cfg_gpio = s3c24xx_ts_cfg_gpio,
+};
+
+/**
+ * Set lcd on or off
+ **/
+static struct s3c2410fb_display h1940_lcd __initdata = {
+       .lcdcon5=       S3C2410_LCDCON5_FRM565 | \
+                       S3C2410_LCDCON5_INVVLINE | \
+                       S3C2410_LCDCON5_HWSWP,
+
+       .type =         S3C2410_LCDCON1_TFT,
+       .width =        240,
+       .height =       320,
+       .pixclock =     260000,
+       .xres =         240,
+       .yres =         320,
+       .bpp =          16,
+       .left_margin =  8,
+       .right_margin = 20,
+       .hsync_len =    4,
+       .upper_margin = 8,
+       .lower_margin = 7,
+       .vsync_len =    1,
+};
+
+static struct s3c2410fb_mach_info h1940_fb_info __initdata = {
+       .displays = &h1940_lcd,
+       .num_displays = 1,
+       .default_display = 0,
+
+       .lpcsel =       0x02,
+       .gpccon =       0xaa940659,
+       .gpccon_mask =  0xffffc0f0,
+       .gpcup =        0x0000ffff,
+       .gpcup_mask =   0xffffffff,
+       .gpdcon =       0xaa84aaa0,
+       .gpdcon_mask =  0xffffffff,
+       .gpdup =        0x0000faff,
+       .gpdup_mask =   0xffffffff,
+};
+
+static int power_supply_init(struct device *dev)
+{
+       return gpio_request(S3C2410_GPF(2), "cable plugged");
+}
+
+static int h1940_is_ac_online(void)
+{
+       return !gpio_get_value(S3C2410_GPF(2));
+}
+
+static void power_supply_exit(struct device *dev)
+{
+       gpio_free(S3C2410_GPF(2));
+}
+
+static char *h1940_supplicants[] = {
+       "main-battery",
+       "backup-battery",
+};
+
+static struct pda_power_pdata power_supply_info = {
+       .init                   = power_supply_init,
+       .is_ac_online           = h1940_is_ac_online,
+       .exit                   = power_supply_exit,
+       .supplied_to            = h1940_supplicants,
+       .num_supplicants        = ARRAY_SIZE(h1940_supplicants),
+};
+
+static struct resource power_supply_resources[] = {
+       [0] = {
+                       .name   = "ac",
+                       .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE |
+                                         IORESOURCE_IRQ_HIGHEDGE,
+                       .start  = IRQ_EINT2,
+                       .end    = IRQ_EINT2,
+       },
+};
+
+static struct platform_device power_supply = {
+       .name           = "pda-power",
+       .id             = -1,
+       .dev            = {
+                               .platform_data =
+                                       &power_supply_info,
+       },
+       .resource       = power_supply_resources,
+       .num_resources  = ARRAY_SIZE(power_supply_resources),
+};
+
+static const struct s3c_adc_bat_thresh bat_lut_noac[] = {
+       { .volt = 4070, .cur = 162, .level = 100},
+       { .volt = 4040, .cur = 165, .level = 95},
+       { .volt = 4016, .cur = 164, .level = 90},
+       { .volt = 3996, .cur = 166, .level = 85},
+       { .volt = 3971, .cur = 168, .level = 80},
+       { .volt = 3951, .cur = 168, .level = 75},
+       { .volt = 3931, .cur = 170, .level = 70},
+       { .volt = 3903, .cur = 172, .level = 65},
+       { .volt = 3886, .cur = 172, .level = 60},
+       { .volt = 3858, .cur = 176, .level = 55},
+       { .volt = 3842, .cur = 176, .level = 50},
+       { .volt = 3818, .cur = 176, .level = 45},
+       { .volt = 3789, .cur = 180, .level = 40},
+       { .volt = 3769, .cur = 180, .level = 35},
+       { .volt = 3749, .cur = 184, .level = 30},
+       { .volt = 3732, .cur = 184, .level = 25},
+       { .volt = 3716, .cur = 184, .level = 20},
+       { .volt = 3708, .cur = 184, .level = 15},
+       { .volt = 3716, .cur = 96, .level = 10},
+       { .volt = 3700, .cur = 96, .level = 5},
+       { .volt = 3684, .cur = 96, .level = 0},
+};
+
+static const struct s3c_adc_bat_thresh bat_lut_acin[] = {
+       { .volt = 4130, .cur = 0, .level = 100},
+       { .volt = 3982, .cur = 0, .level = 50},
+       { .volt = 3854, .cur = 0, .level = 10},
+       { .volt = 3841, .cur = 0, .level = 0},
+};
+
+static int h1940_bat_init(void)
+{
+       int ret;
+
+       ret = gpio_request(H1940_LATCH_SM803_ENABLE, "h1940-charger-enable");
+       if (ret)
+               return ret;
+       gpio_direction_output(H1940_LATCH_SM803_ENABLE, 0);
+
+       return 0;
+
+}
+
+static void h1940_bat_exit(void)
+{
+       gpio_free(H1940_LATCH_SM803_ENABLE);
+}
+
+static void h1940_enable_charger(void)
+{
+       gpio_set_value(H1940_LATCH_SM803_ENABLE, 1);
+}
+
+static void h1940_disable_charger(void)
+{
+       gpio_set_value(H1940_LATCH_SM803_ENABLE, 0);
+}
+
+static struct s3c_adc_bat_pdata h1940_bat_cfg = {
+       .init = h1940_bat_init,
+       .exit = h1940_bat_exit,
+       .enable_charger = h1940_enable_charger,
+       .disable_charger = h1940_disable_charger,
+       .gpio_charge_finished = S3C2410_GPF(3),
+       .gpio_inverted = 1,
+       .lut_noac = bat_lut_noac,
+       .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac),
+       .lut_acin = bat_lut_acin,
+       .lut_acin_cnt = ARRAY_SIZE(bat_lut_acin),
+       .volt_channel = 0,
+       .current_channel = 1,
+       .volt_mult = 4056,
+       .current_mult = 1893,
+       .internal_impedance = 200,
+       .backup_volt_channel = 3,
+       /* TODO Check backup volt multiplier */
+       .backup_volt_mult = 4056,
+       .backup_volt_min = 0,
+       .backup_volt_max = 4149288
+};
+
+static struct platform_device h1940_battery = {
+       .name             = "s3c-adc-battery",
+       .id               = -1,
+       .dev = {
+               .parent = &s3c_device_adc.dev,
+               .platform_data = &h1940_bat_cfg,
+       },
+};
+
+static DEFINE_SPINLOCK(h1940_blink_spin);
+
+int h1940_led_blink_set(unsigned gpio, int state,
+       unsigned long *delay_on, unsigned long *delay_off)
+{
+       int blink_gpio, check_gpio1, check_gpio2;
+
+       switch (gpio) {
+       case H1940_LATCH_LED_GREEN:
+               blink_gpio = S3C2410_GPA(7);
+               check_gpio1 = S3C2410_GPA(1);
+               check_gpio2 = S3C2410_GPA(3);
+               break;
+       case H1940_LATCH_LED_RED:
+               blink_gpio = S3C2410_GPA(1);
+               check_gpio1 = S3C2410_GPA(7);
+               check_gpio2 = S3C2410_GPA(3);
+               break;
+       default:
+               blink_gpio = S3C2410_GPA(3);
+               check_gpio1 = S3C2410_GPA(1);
+               check_gpio1 = S3C2410_GPA(7);
+               break;
+       }
+
+       if (delay_on && delay_off && !*delay_on && !*delay_off)
+               *delay_on = *delay_off = 500;
+
+       spin_lock(&h1940_blink_spin);
+
+       switch (state) {
+       case GPIO_LED_NO_BLINK_LOW:
+       case GPIO_LED_NO_BLINK_HIGH:
+               if (!gpio_get_value(check_gpio1) &&
+                   !gpio_get_value(check_gpio2))
+                       gpio_set_value(H1940_LATCH_LED_FLASH, 0);
+               gpio_set_value(blink_gpio, 0);
+               if (gpio_is_valid(gpio))
+                       gpio_set_value(gpio, state);
+               break;
+       case GPIO_LED_BLINK:
+               if (gpio_is_valid(gpio))
+                       gpio_set_value(gpio, 0);
+               gpio_set_value(H1940_LATCH_LED_FLASH, 1);
+               gpio_set_value(blink_gpio, 1);
+               break;
+       }
+
+       spin_unlock(&h1940_blink_spin);
+
+       return 0;
+}
+EXPORT_SYMBOL(h1940_led_blink_set);
+
+static struct gpio_led h1940_leds_desc[] = {
+       {
+               .name                   = "Green",
+               .default_trigger        = "main-battery-full",
+               .gpio                   = H1940_LATCH_LED_GREEN,
+               .retain_state_suspended = 1,
+       },
+       {
+               .name                   = "Red",
+               .default_trigger
+                       = "main-battery-charging-blink-full-solid",
+               .gpio                   = H1940_LATCH_LED_RED,
+               .retain_state_suspended = 1,
+       },
+};
+
+static struct gpio_led_platform_data h1940_leds_pdata = {
+       .num_leds       = ARRAY_SIZE(h1940_leds_desc),
+       .leds           = h1940_leds_desc,
+       .gpio_blink_set = h1940_led_blink_set,
+};
+
+static struct platform_device h1940_device_leds = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+                       .platform_data = &h1940_leds_pdata,
+       },
+};
+
+static struct platform_device h1940_device_bluetooth = {
+       .name             = "h1940-bt",
+       .id               = -1,
+};
+
+static void h1940_set_mmc_power(unsigned char power_mode, unsigned short vdd)
+{
+       switch (power_mode) {
+       case MMC_POWER_OFF:
+               gpio_set_value(H1940_LATCH_SD_POWER, 0);
+               break;
+       case MMC_POWER_UP:
+       case MMC_POWER_ON:
+               gpio_set_value(H1940_LATCH_SD_POWER, 1);
+               break;
+       default:
+               break;
+       };
+}
+
+static struct s3c24xx_mci_pdata h1940_mmc_cfg __initdata = {
+       .gpio_detect   = S3C2410_GPF(5),
+       .gpio_wprotect = S3C2410_GPH(8),
+       .set_power     = h1940_set_mmc_power,
+       .ocr_avail     = MMC_VDD_32_33,
+};
+
+static int h1940_backlight_init(struct device *dev)
+{
+       gpio_request(S3C2410_GPB(0), "Backlight");
+
+       gpio_direction_output(S3C2410_GPB(0), 0);
+       s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
+       s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+       gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 1);
+
+       return 0;
+}
+
+static int h1940_backlight_notify(struct device *dev, int brightness)
+{
+       if (!brightness) {
+               gpio_direction_output(S3C2410_GPB(0), 1);
+               gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
+       } else {
+               gpio_direction_output(S3C2410_GPB(0), 0);
+               s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
+               s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+               gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 1);
+       }
+       return brightness;
+}
+
+static void h1940_backlight_exit(struct device *dev)
+{
+       gpio_direction_output(S3C2410_GPB(0), 1);
+       gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
+}
+
+
+static struct platform_pwm_backlight_data backlight_data = {
+       .pwm_id         = 0,
+       .max_brightness = 100,
+       .dft_brightness = 50,
+       /* tcnt = 0x31 */
+       .pwm_period_ns  = 36296,
+       .init           = h1940_backlight_init,
+       .notify         = h1940_backlight_notify,
+       .exit           = h1940_backlight_exit,
+};
+
+static struct platform_device h1940_backlight = {
+       .name = "pwm-backlight",
+       .dev  = {
+               .parent = &s3c_device_timer[0].dev,
+               .platform_data = &backlight_data,
+       },
+       .id   = -1,
+};
+
+static void h1940_lcd_power_set(struct plat_lcd_data *pd,
+                                       unsigned int power)
+{
+       int value, retries = 100;
+
+       if (!power) {
+               gpio_set_value(S3C2410_GPC(0), 0);
+               /* wait for 3ac */
+               do {
+                       value = gpio_get_value(S3C2410_GPC(6));
+               } while (value && retries--);
+
+               gpio_set_value(H1940_LATCH_LCD_P2, 0);
+               gpio_set_value(H1940_LATCH_LCD_P3, 0);
+               gpio_set_value(H1940_LATCH_LCD_P4, 0);
+
+               gpio_direction_output(S3C2410_GPC(1), 0);
+               gpio_direction_output(S3C2410_GPC(4), 0);
+
+               gpio_set_value(H1940_LATCH_LCD_P1, 0);
+               gpio_set_value(H1940_LATCH_LCD_P0, 0);
+
+               gpio_set_value(S3C2410_GPC(5), 0);
+
+       } else {
+               gpio_set_value(H1940_LATCH_LCD_P0, 1);
+               gpio_set_value(H1940_LATCH_LCD_P1, 1);
+
+               gpio_direction_input(S3C2410_GPC(1));
+               gpio_direction_input(S3C2410_GPC(4));
+               mdelay(10);
+               s3c_gpio_cfgpin(S3C2410_GPC(1), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S3C2410_GPC(4), S3C_GPIO_SFN(2));
+
+               gpio_set_value(S3C2410_GPC(5), 1);
+               gpio_set_value(S3C2410_GPC(0), 1);
+
+               gpio_set_value(H1940_LATCH_LCD_P3, 1);
+               gpio_set_value(H1940_LATCH_LCD_P2, 1);
+               gpio_set_value(H1940_LATCH_LCD_P4, 1);
+       }
+}
+
+static struct plat_lcd_data h1940_lcd_power_data = {
+       .set_power      = h1940_lcd_power_set,
+};
+
+static struct platform_device h1940_lcd_powerdev = {
+       .name                   = "platform-lcd",
+       .dev.parent             = &s3c_device_lcd.dev,
+       .dev.platform_data      = &h1940_lcd_power_data,
+};
+
+static struct uda1380_platform_data uda1380_info = {
+       .gpio_power     = H1940_LATCH_UDA_POWER,
+       .gpio_reset     = S3C2410_GPA(12),
+       .dac_clk        = UDA1380_DAC_CLK_SYSCLK,
+};
+
+static struct i2c_board_info h1940_i2c_devices[] = {
+       {
+               I2C_BOARD_INFO("uda1380", 0x1a),
+               .platform_data = &uda1380_info,
+       },
+};
+
+#define DECLARE_BUTTON(p, k, n, w)     \
+       {                               \
+               .gpio           = p,    \
+               .code           = k,    \
+               .desc           = n,    \
+               .wakeup         = w,    \
+               .active_low     = 1,    \
+       }
+
+static struct gpio_keys_button h1940_buttons[] = {
+       DECLARE_BUTTON(S3C2410_GPF(0),       KEY_POWER,          "Power", 1),
+       DECLARE_BUTTON(S3C2410_GPF(6),       KEY_ENTER,         "Select", 1),
+       DECLARE_BUTTON(S3C2410_GPF(7),      KEY_RECORD,         "Record", 0),
+       DECLARE_BUTTON(S3C2410_GPG(0),         KEY_F11,       "Calendar", 0),
+       DECLARE_BUTTON(S3C2410_GPG(2),         KEY_F12,       "Contacts", 0),
+       DECLARE_BUTTON(S3C2410_GPG(3),        KEY_MAIL,           "Mail", 0),
+       DECLARE_BUTTON(S3C2410_GPG(6),        KEY_LEFT,     "Left_arrow", 0),
+       DECLARE_BUTTON(S3C2410_GPG(7),    KEY_HOMEPAGE,           "Home", 0),
+       DECLARE_BUTTON(S3C2410_GPG(8),       KEY_RIGHT,    "Right_arrow", 0),
+       DECLARE_BUTTON(S3C2410_GPG(9),          KEY_UP,       "Up_arrow", 0),
+       DECLARE_BUTTON(S3C2410_GPG(10),       KEY_DOWN,     "Down_arrow", 0),
+};
+
+static struct gpio_keys_platform_data h1940_buttons_data = {
+       .buttons        = h1940_buttons,
+       .nbuttons       = ARRAY_SIZE(h1940_buttons),
+};
+
+static struct platform_device h1940_dev_buttons = {
+       .name           = "gpio-keys",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &h1940_buttons_data,
+       }
+};
+
+static struct platform_device *h1940_devices[] __initdata = {
+       &h1940_dev_buttons,
+       &s3c_device_ohci,
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_iis,
+       &samsung_asoc_dma,
+       &s3c_device_usbgadget,
+       &h1940_device_leds,
+       &h1940_device_bluetooth,
+       &s3c_device_sdi,
+       &s3c_device_rtc,
+       &s3c_device_timer[0],
+       &h1940_backlight,
+       &h1940_lcd_powerdev,
+       &s3c_device_adc,
+       &s3c_device_ts,
+       &power_supply,
+       &h1940_battery,
+};
+
+static void __init h1940_map_io(void)
+{
+       s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
+       s3c24xx_init_clocks(0);
+       s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
+
+       /* setup PM */
+
+#ifdef CONFIG_PM_H1940
+       memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
+#endif
+       s3c_pm_init();
+
+       /* Add latch gpio chip, set latch initial value */
+       h1940_latch_control(0, 0);
+       WARN_ON(gpiochip_add(&h1940_latch_gpiochip));
+}
+
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init h1940_reserve(void)
+{
+       memblock_reserve(0x30003000, 0x1000);
+       memblock_reserve(0x30081000, 0x1000);
+}
+
+static void __init h1940_init_irq(void)
+{
+       s3c24xx_init_irq();
+}
+
+static void __init h1940_init(void)
+{
+       u32 tmp;
+
+       s3c24xx_fb_set_platdata(&h1940_fb_info);
+       s3c24xx_mci_set_platdata(&h1940_mmc_cfg);
+       s3c24xx_udc_set_platdata(&h1940_udc_cfg);
+       s3c24xx_ts_set_platdata(&h1940_ts_cfg);
+       s3c_i2c0_set_platdata(NULL);
+
+       /* Turn off suspend on both USB ports, and switch the
+        * selectable USB port to USB device mode. */
+
+       s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+                             S3C2410_MISCCR_USBSUSPND0 |
+                             S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+       tmp =   (0x78 << S3C24XX_PLL_MDIV_SHIFT)
+             | (0x02 << S3C24XX_PLL_PDIV_SHIFT)
+             | (0x03 << S3C24XX_PLL_SDIV_SHIFT);
+       writel(tmp, S3C2410_UPLLCON);
+
+       gpio_request(S3C2410_GPC(0), "LCD power");
+       gpio_request(S3C2410_GPC(1), "LCD power");
+       gpio_request(S3C2410_GPC(4), "LCD power");
+       gpio_request(S3C2410_GPC(5), "LCD power");
+       gpio_request(S3C2410_GPC(6), "LCD power");
+       gpio_request(H1940_LATCH_LCD_P0, "LCD power");
+       gpio_request(H1940_LATCH_LCD_P1, "LCD power");
+       gpio_request(H1940_LATCH_LCD_P2, "LCD power");
+       gpio_request(H1940_LATCH_LCD_P3, "LCD power");
+       gpio_request(H1940_LATCH_LCD_P4, "LCD power");
+       gpio_request(H1940_LATCH_MAX1698_nSHUTDOWN, "LCD power");
+       gpio_direction_output(S3C2410_GPC(0), 0);
+       gpio_direction_output(S3C2410_GPC(1), 0);
+       gpio_direction_output(S3C2410_GPC(4), 0);
+       gpio_direction_output(S3C2410_GPC(5), 0);
+       gpio_direction_input(S3C2410_GPC(6));
+       gpio_direction_output(H1940_LATCH_LCD_P0, 0);
+       gpio_direction_output(H1940_LATCH_LCD_P1, 0);
+       gpio_direction_output(H1940_LATCH_LCD_P2, 0);
+       gpio_direction_output(H1940_LATCH_LCD_P3, 0);
+       gpio_direction_output(H1940_LATCH_LCD_P4, 0);
+       gpio_direction_output(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
+
+       gpio_request(H1940_LATCH_SD_POWER, "SD power");
+       gpio_direction_output(H1940_LATCH_SD_POWER, 0);
+
+       platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
+
+       gpio_request(S3C2410_GPA(1), "Red LED blink");
+       gpio_request(S3C2410_GPA(3), "Blue LED blink");
+       gpio_request(S3C2410_GPA(7), "Green LED blink");
+       gpio_request(H1940_LATCH_LED_FLASH, "LED blink");
+       gpio_direction_output(S3C2410_GPA(1), 0);
+       gpio_direction_output(S3C2410_GPA(3), 0);
+       gpio_direction_output(S3C2410_GPA(7), 0);
+       gpio_direction_output(H1940_LATCH_LED_FLASH, 0);
+
+       i2c_register_board_info(0, h1940_i2c_devices,
+               ARRAY_SIZE(h1940_i2c_devices));
+}
+
+MACHINE_START(H1940, "IPAQ-H1940")
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+       .atag_offset    = 0x100,
+       .map_io         = h1940_map_io,
+       .reserve        = h1940_reserve,
+       .init_irq       = h1940_init_irq,
+       .init_machine   = h1940_init,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c2410_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-jive.c b/arch/arm/mach-s3c24xx/mach-jive.c
new file mode 100644 (file)
index 0000000..ae73ba3
--- /dev/null
@@ -0,0 +1,666 @@
+/* linux/arch/arm/mach-s3c2410/mach-jive.c
+ *
+ * Copyright 2007 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/syscore_ops.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+
+#include <video/ili9320.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <plat/regs-serial.h>
+#include <plat/nand.h>
+#include <plat/iic.h>
+
+#include <mach/regs-power.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+#include <mach/fb.h>
+
+#include <asm/mach-types.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <plat/s3c2412.h>
+#include <plat/gpio-cfg.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/udc.h>
+
+static struct map_desc jive_iodesc[] __initdata = {
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg jive_uartcfgs[] = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       }
+};
+
+/* Jive flash assignment
+ *
+ * 0x00000000-0x00028000 : uboot
+ * 0x00028000-0x0002c000 : uboot env
+ * 0x0002c000-0x00030000 : spare
+ * 0x00030000-0x00200000 : zimage A
+ * 0x00200000-0x01600000 : cramfs A
+ * 0x01600000-0x017d0000 : zimage B
+ * 0x017d0000-0x02bd0000 : cramfs B
+ * 0x02bd0000-0x03fd0000 : yaffs
+ */
+static struct mtd_partition __initdata jive_imageA_nand_part[] = {
+
+#ifdef CONFIG_MACH_JIVE_SHOW_BOOTLOADER
+       /* Don't allow access to the bootloader from linux */
+       {
+               .name           = "uboot",
+               .offset         = 0,
+               .size           = (160 * SZ_1K),
+               .mask_flags     = MTD_WRITEABLE, /* force read-only */
+       },
+
+       /* spare */
+        {
+                .name           = "spare",
+                .offset         = (176 * SZ_1K),
+                .size           = (16 * SZ_1K),
+        },
+#endif
+
+       /* booted images */
+        {
+               .name           = "kernel (ro)",
+               .offset         = (192 * SZ_1K),
+               .size           = (SZ_2M) - (192 * SZ_1K),
+               .mask_flags     = MTD_WRITEABLE, /* force read-only */
+        }, {
+                .name           = "root (ro)",
+                .offset         = (SZ_2M),
+                .size           = (20 * SZ_1M),
+               .mask_flags     = MTD_WRITEABLE, /* force read-only */
+        },
+
+       /* yaffs */
+       {
+               .name           = "yaffs",
+               .offset         = (44 * SZ_1M),
+               .size           = (20 * SZ_1M),
+       },
+
+       /* bootloader environment */
+       {
+                .name          = "env",
+               .offset         = (160 * SZ_1K),
+               .size           = (16 * SZ_1K),
+       },
+
+       /* upgrade images */
+        {
+               .name           = "zimage",
+               .offset         = (22 * SZ_1M),
+               .size           = (2 * SZ_1M) - (192 * SZ_1K),
+        }, {
+               .name           = "cramfs",
+               .offset         = (24 * SZ_1M) - (192*SZ_1K),
+               .size           = (20 * SZ_1M),
+        },
+};
+
+static struct mtd_partition __initdata jive_imageB_nand_part[] = {
+
+#ifdef CONFIG_MACH_JIVE_SHOW_BOOTLOADER
+       /* Don't allow access to the bootloader from linux */
+       {
+               .name           = "uboot",
+               .offset         = 0,
+               .size           = (160 * SZ_1K),
+               .mask_flags     = MTD_WRITEABLE, /* force read-only */
+       },
+
+       /* spare */
+        {
+                .name           = "spare",
+                .offset         = (176 * SZ_1K),
+                .size           = (16 * SZ_1K),
+        },
+#endif
+
+       /* booted images */
+        {
+               .name           = "kernel (ro)",
+               .offset         = (22 * SZ_1M),
+               .size           = (2 * SZ_1M) - (192 * SZ_1K),
+               .mask_flags     = MTD_WRITEABLE, /* force read-only */
+        },
+       {
+               .name           = "root (ro)",
+               .offset         = (24 * SZ_1M) - (192 * SZ_1K),
+                .size          = (20 * SZ_1M),
+               .mask_flags     = MTD_WRITEABLE, /* force read-only */
+       },
+
+       /* yaffs */
+       {
+               .name           = "yaffs",
+               .offset         = (44 * SZ_1M),
+               .size           = (20 * SZ_1M),
+        },
+
+       /* bootloader environment */
+       {
+               .name           = "env",
+               .offset         = (160 * SZ_1K),
+               .size           = (16 * SZ_1K),
+       },
+
+       /* upgrade images */
+       {
+               .name           = "zimage",
+               .offset         = (192 * SZ_1K),
+               .size           = (2 * SZ_1M) - (192 * SZ_1K),
+        }, {
+               .name           = "cramfs",
+               .offset         = (2 * SZ_1M),
+               .size           = (20 * SZ_1M),
+        },
+};
+
+static struct s3c2410_nand_set __initdata jive_nand_sets[] = {
+       [0] = {
+               .name           = "flash",
+               .nr_chips       = 1,
+               .nr_partitions  = ARRAY_SIZE(jive_imageA_nand_part),
+               .partitions     = jive_imageA_nand_part,
+       },
+};
+
+static struct s3c2410_platform_nand __initdata jive_nand_info = {
+       /* set taken from osiris nand timings, possibly still conservative */
+       .tacls          = 30,
+       .twrph0         = 55,
+       .twrph1         = 40,
+       .sets           = jive_nand_sets,
+       .nr_sets        = ARRAY_SIZE(jive_nand_sets),
+};
+
+static int __init jive_mtdset(char *options)
+{
+       struct s3c2410_nand_set *nand = &jive_nand_sets[0];
+       unsigned long set;
+
+       if (options == NULL || options[0] == '\0')
+               return 0;
+
+       if (strict_strtoul(options, 10, &set)) {
+               printk(KERN_ERR "failed to parse mtdset=%s\n", options);
+               return 0;
+       }
+
+       switch (set) {
+       case 1:
+               nand->nr_partitions = ARRAY_SIZE(jive_imageB_nand_part);
+               nand->partitions = jive_imageB_nand_part;
+       case 0:
+               /* this is already setup in the nand info */
+               break;
+       default:
+               printk(KERN_ERR "Unknown mtd set %ld specified,"
+                      "using default.", set);
+       }
+
+       return 0;
+}
+
+/* parse the mtdset= option given to the kernel command line */
+__setup("mtdset=", jive_mtdset);
+
+/* LCD timing and setup */
+
+#define LCD_XRES        (240)
+#define LCD_YRES        (320)
+#define LCD_LEFT_MARGIN  (12)
+#define LCD_RIGHT_MARGIN (12)
+#define LCD_LOWER_MARGIN (12)
+#define LCD_UPPER_MARGIN (12)
+#define LCD_VSYNC       (2)
+#define LCD_HSYNC       (2)
+
+#define LCD_REFRESH     (60)
+
+#define LCD_HTOT (LCD_HSYNC + LCD_LEFT_MARGIN + LCD_XRES + LCD_RIGHT_MARGIN)
+#define LCD_VTOT (LCD_VSYNC + LCD_LOWER_MARGIN + LCD_YRES + LCD_UPPER_MARGIN)
+
+static struct s3c2410fb_display jive_vgg2432a4_display[] = {
+       [0] = {
+               .width          = LCD_XRES,
+               .height         = LCD_YRES,
+               .xres           = LCD_XRES,
+               .yres           = LCD_YRES,
+               .left_margin    = LCD_LEFT_MARGIN,
+               .right_margin   = LCD_RIGHT_MARGIN,
+               .upper_margin   = LCD_UPPER_MARGIN,
+               .lower_margin   = LCD_LOWER_MARGIN,
+               .hsync_len      = LCD_HSYNC,
+               .vsync_len      = LCD_VSYNC,
+
+               .pixclock       = (1000000000000LL /
+                                  (LCD_REFRESH * LCD_HTOT * LCD_VTOT)),
+
+               .bpp            = 16,
+               .type           = (S3C2410_LCDCON1_TFT16BPP |
+                                  S3C2410_LCDCON1_TFT),
+
+               .lcdcon5        = (S3C2410_LCDCON5_FRM565 |
+                                  S3C2410_LCDCON5_INVVLINE |
+                                  S3C2410_LCDCON5_INVVFRAME |
+                                  S3C2410_LCDCON5_INVVDEN |
+                                  S3C2410_LCDCON5_PWREN),
+       },
+};
+
+/* todo - put into gpio header */
+
+#define S3C2410_GPCCON_MASK(x) (3 << ((x) * 2))
+#define S3C2410_GPDCON_MASK(x) (3 << ((x) * 2))
+
+static struct s3c2410fb_mach_info jive_lcd_config = {
+       .displays        = jive_vgg2432a4_display,
+       .num_displays    = ARRAY_SIZE(jive_vgg2432a4_display),
+       .default_display = 0,
+
+       /* Enable VD[2..7], VD[10..15], VD[18..23] and VCLK, syncs, VDEN
+        * and disable the pull down resistors on pins we are using for LCD
+        * data. */
+
+       .gpcup          = (0xf << 1) | (0x3f << 10),
+
+       .gpccon         = (S3C2410_GPC1_VCLK   | S3C2410_GPC2_VLINE |
+                          S3C2410_GPC3_VFRAME | S3C2410_GPC4_VM |
+                          S3C2410_GPC10_VD2   | S3C2410_GPC11_VD3 |
+                          S3C2410_GPC12_VD4   | S3C2410_GPC13_VD5 |
+                          S3C2410_GPC14_VD6   | S3C2410_GPC15_VD7),
+
+       .gpccon_mask    = (S3C2410_GPCCON_MASK(1)  | S3C2410_GPCCON_MASK(2)  |
+                          S3C2410_GPCCON_MASK(3)  | S3C2410_GPCCON_MASK(4)  |
+                          S3C2410_GPCCON_MASK(10) | S3C2410_GPCCON_MASK(11) |
+                          S3C2410_GPCCON_MASK(12) | S3C2410_GPCCON_MASK(13) |
+                          S3C2410_GPCCON_MASK(14) | S3C2410_GPCCON_MASK(15)),
+
+       .gpdup          = (0x3f << 2) | (0x3f << 10),
+
+       .gpdcon         = (S3C2410_GPD2_VD10  | S3C2410_GPD3_VD11 |
+                          S3C2410_GPD4_VD12  | S3C2410_GPD5_VD13 |
+                          S3C2410_GPD6_VD14  | S3C2410_GPD7_VD15 |
+                          S3C2410_GPD10_VD18 | S3C2410_GPD11_VD19 |
+                          S3C2410_GPD12_VD20 | S3C2410_GPD13_VD21 |
+                          S3C2410_GPD14_VD22 | S3C2410_GPD15_VD23),
+
+       .gpdcon_mask    = (S3C2410_GPDCON_MASK(2)  | S3C2410_GPDCON_MASK(3) |
+                          S3C2410_GPDCON_MASK(4)  | S3C2410_GPDCON_MASK(5) |
+                          S3C2410_GPDCON_MASK(6)  | S3C2410_GPDCON_MASK(7) |
+                          S3C2410_GPDCON_MASK(10) | S3C2410_GPDCON_MASK(11)|
+                          S3C2410_GPDCON_MASK(12) | S3C2410_GPDCON_MASK(13)|
+                          S3C2410_GPDCON_MASK(14) | S3C2410_GPDCON_MASK(15)),
+};
+
+/* ILI9320 support. */
+
+static void jive_lcm_reset(unsigned int set)
+{
+       printk(KERN_DEBUG "%s(%d)\n", __func__, set);
+
+       gpio_set_value(S3C2410_GPG(13), set);
+}
+
+#undef LCD_UPPER_MARGIN
+#define LCD_UPPER_MARGIN 2
+
+static struct ili9320_platdata jive_lcm_config = {
+       .hsize          = LCD_XRES,
+       .vsize          = LCD_YRES,
+
+       .reset          = jive_lcm_reset,
+       .suspend        = ILI9320_SUSPEND_DEEP,
+
+       .entry_mode     = ILI9320_ENTRYMODE_ID(3) | ILI9320_ENTRYMODE_BGR,
+       .display2       = (ILI9320_DISPLAY2_FP(LCD_UPPER_MARGIN) |
+                          ILI9320_DISPLAY2_BP(LCD_LOWER_MARGIN)),
+       .display3       = 0x0,
+       .display4       = 0x0,
+       .rgb_if1        = (ILI9320_RGBIF1_RIM_RGB18 |
+                          ILI9320_RGBIF1_RM | ILI9320_RGBIF1_CLK_RGBIF),
+       .rgb_if2        = ILI9320_RGBIF2_DPL,
+       .interface2     = 0x0,
+       .interface3     = 0x3,
+       .interface4     = (ILI9320_INTERFACE4_RTNE(16) |
+                          ILI9320_INTERFACE4_DIVE(1)),
+       .interface5     = 0x0,
+       .interface6     = 0x0,
+};
+
+/* LCD SPI support */
+
+static struct spi_gpio_platform_data jive_lcd_spi = {
+       .sck            = S3C2410_GPG(8),
+       .mosi           = S3C2410_GPB(8),
+       .miso           = SPI_GPIO_NO_MISO,
+};
+
+static struct platform_device jive_device_lcdspi = {
+       .name           = "spi-gpio",
+       .id             = 1,
+       .dev.platform_data = &jive_lcd_spi,
+};
+
+
+/* WM8750 audio code SPI definition */
+
+static struct spi_gpio_platform_data jive_wm8750_spi = {
+       .sck            = S3C2410_GPB(4),
+       .mosi           = S3C2410_GPB(9),
+       .miso           = SPI_GPIO_NO_MISO,
+};
+
+static struct platform_device jive_device_wm8750 = {
+       .name           = "spi-gpio",
+       .id             = 2,
+       .dev.platform_data = &jive_wm8750_spi,
+};
+
+/* JIVE SPI devices. */
+
+static struct spi_board_info __initdata jive_spi_devs[] = {
+       [0] = {
+               .modalias       = "VGG2432A4",
+               .bus_num        = 1,
+               .chip_select    = 0,
+               .mode           = SPI_MODE_3,   /* CPOL=1, CPHA=1 */
+               .max_speed_hz   = 100000,
+               .platform_data  = &jive_lcm_config,
+               .controller_data = (void *)S3C2410_GPB(7),
+       }, {
+               .modalias       = "WM8750",
+               .bus_num        = 2,
+               .chip_select    = 0,
+               .mode           = SPI_MODE_0,   /* CPOL=0, CPHA=0 */
+               .max_speed_hz   = 100000,
+               .controller_data = (void *)S3C2410_GPH(10),
+       },
+};
+
+/* I2C bus and device configuration. */
+
+static struct s3c2410_platform_i2c jive_i2c_cfg __initdata = {
+       .frequency      = 80 * 1000,
+       .flags          = S3C_IICFLG_FILTER,
+       .sda_delay      = 2,
+};
+
+static struct i2c_board_info jive_i2c_devs[] __initdata = {
+       [0] = {
+               I2C_BOARD_INFO("lis302dl", 0x1c),
+               .irq    = IRQ_EINT14,
+       },
+};
+
+/* The platform devices being used. */
+
+static struct platform_device *jive_devices[] __initdata = {
+       &s3c_device_ohci,
+       &s3c_device_rtc,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_lcd,
+       &jive_device_lcdspi,
+       &jive_device_wm8750,
+       &s3c_device_nand,
+       &s3c_device_usbgadget,
+};
+
+static struct s3c2410_udc_mach_info jive_udc_cfg __initdata = {
+       .vbus_pin       = S3C2410_GPG(1),               /* detect is on GPG1 */
+};
+
+/* Jive power management device */
+
+#ifdef CONFIG_PM
+static int jive_pm_suspend(void)
+{
+       /* Write the magic value u-boot uses to check for resume into
+        * the INFORM0 register, and ensure INFORM1 is set to the
+        * correct address to resume from. */
+
+       __raw_writel(0x2BED, S3C2412_INFORM0);
+       __raw_writel(virt_to_phys(s3c_cpu_resume), S3C2412_INFORM1);
+
+       return 0;
+}
+
+static void jive_pm_resume(void)
+{
+       __raw_writel(0x0, S3C2412_INFORM0);
+}
+
+#else
+#define jive_pm_suspend NULL
+#define jive_pm_resume NULL
+#endif
+
+static struct syscore_ops jive_pm_syscore_ops = {
+       .suspend        = jive_pm_suspend,
+       .resume         = jive_pm_resume,
+};
+
+static void __init jive_map_io(void)
+{
+       s3c24xx_init_io(jive_iodesc, ARRAY_SIZE(jive_iodesc));
+       s3c24xx_init_clocks(12000000);
+       s3c24xx_init_uarts(jive_uartcfgs, ARRAY_SIZE(jive_uartcfgs));
+}
+
+static void jive_power_off(void)
+{
+       printk(KERN_INFO "powering system down...\n");
+
+       s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
+       s3c_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT);
+}
+
+static void __init jive_machine_init(void)
+{
+       /* register system core operations for managing low level suspend */
+
+       register_syscore_ops(&jive_pm_syscore_ops);
+
+       /* write our sleep configurations for the IO. Pull down all unused
+        * IO, ensure that we have turned off all peripherals we do not
+        * need, and configure the ones we do need. */
+
+       /* Port B sleep */
+
+       __raw_writel(S3C2412_SLPCON_IN(0)   |
+                    S3C2412_SLPCON_PULL(1) |
+                    S3C2412_SLPCON_HIGH(2) |
+                    S3C2412_SLPCON_PULL(3) |
+                    S3C2412_SLPCON_PULL(4) |
+                    S3C2412_SLPCON_PULL(5) |
+                    S3C2412_SLPCON_PULL(6) |
+                    S3C2412_SLPCON_HIGH(7) |
+                    S3C2412_SLPCON_PULL(8) |
+                    S3C2412_SLPCON_PULL(9) |
+                    S3C2412_SLPCON_PULL(10), S3C2412_GPBSLPCON);
+
+       /* Port C sleep */
+
+       __raw_writel(S3C2412_SLPCON_PULL(0) |
+                    S3C2412_SLPCON_PULL(1) |
+                    S3C2412_SLPCON_PULL(2) |
+                    S3C2412_SLPCON_PULL(3) |
+                    S3C2412_SLPCON_PULL(4) |
+                    S3C2412_SLPCON_PULL(5) |
+                    S3C2412_SLPCON_LOW(6)  |
+                    S3C2412_SLPCON_PULL(6) |
+                    S3C2412_SLPCON_PULL(7) |
+                    S3C2412_SLPCON_PULL(8) |
+                    S3C2412_SLPCON_PULL(9) |
+                    S3C2412_SLPCON_PULL(10) |
+                    S3C2412_SLPCON_PULL(11) |
+                    S3C2412_SLPCON_PULL(12) |
+                    S3C2412_SLPCON_PULL(13) |
+                    S3C2412_SLPCON_PULL(14) |
+                    S3C2412_SLPCON_PULL(15), S3C2412_GPCSLPCON);
+
+       /* Port D sleep */
+
+       __raw_writel(S3C2412_SLPCON_ALL_PULL, S3C2412_GPDSLPCON);
+
+       /* Port F sleep */
+
+       __raw_writel(S3C2412_SLPCON_LOW(0)  |
+                    S3C2412_SLPCON_LOW(1)  |
+                    S3C2412_SLPCON_LOW(2)  |
+                    S3C2412_SLPCON_EINT(3) |
+                    S3C2412_SLPCON_EINT(4) |
+                    S3C2412_SLPCON_EINT(5) |
+                    S3C2412_SLPCON_EINT(6) |
+                    S3C2412_SLPCON_EINT(7), S3C2412_GPFSLPCON);
+
+       /* Port G sleep */
+
+       __raw_writel(S3C2412_SLPCON_IN(0)    |
+                    S3C2412_SLPCON_IN(1)    |
+                    S3C2412_SLPCON_IN(2)    |
+                    S3C2412_SLPCON_IN(3)    |
+                    S3C2412_SLPCON_IN(4)    |
+                    S3C2412_SLPCON_IN(5)    |
+                    S3C2412_SLPCON_IN(6)    |
+                    S3C2412_SLPCON_IN(7)    |
+                    S3C2412_SLPCON_PULL(8)  |
+                    S3C2412_SLPCON_PULL(9)  |
+                    S3C2412_SLPCON_IN(10)   |
+                    S3C2412_SLPCON_PULL(11) |
+                    S3C2412_SLPCON_PULL(12) |
+                    S3C2412_SLPCON_PULL(13) |
+                    S3C2412_SLPCON_IN(14)   |
+                    S3C2412_SLPCON_PULL(15), S3C2412_GPGSLPCON);
+
+       /* Port H sleep */
+
+       __raw_writel(S3C2412_SLPCON_PULL(0) |
+                    S3C2412_SLPCON_PULL(1) |
+                    S3C2412_SLPCON_PULL(2) |
+                    S3C2412_SLPCON_PULL(3) |
+                    S3C2412_SLPCON_PULL(4) |
+                    S3C2412_SLPCON_PULL(5) |
+                    S3C2412_SLPCON_PULL(6) |
+                    S3C2412_SLPCON_IN(7)   |
+                    S3C2412_SLPCON_IN(8)   |
+                    S3C2412_SLPCON_PULL(9) |
+                    S3C2412_SLPCON_IN(10), S3C2412_GPHSLPCON);
+
+       /* initialise the power management now we've setup everything. */
+
+       s3c_pm_init();
+
+       /** TODO - check that this is after the cmdline option! */
+       s3c_nand_set_platdata(&jive_nand_info);
+
+       /* initialise the spi */
+
+       gpio_request(S3C2410_GPG(13), "lcm reset");
+       gpio_direction_output(S3C2410_GPG(13), 0);
+
+       gpio_request(S3C2410_GPB(7), "jive spi");
+       gpio_direction_output(S3C2410_GPB(7), 1);
+
+       s3c2410_gpio_setpin(S3C2410_GPB(6), 0);
+       s3c_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT);
+
+       s3c2410_gpio_setpin(S3C2410_GPG(8), 1);
+       s3c_gpio_cfgpin(S3C2410_GPG(8), S3C2410_GPIO_OUTPUT);
+
+       /* initialise the WM8750 spi */
+
+       gpio_request(S3C2410_GPH(10), "jive wm8750 spi");
+       gpio_direction_output(S3C2410_GPH(10), 1);
+
+       /* Turn off suspend on both USB ports, and switch the
+        * selectable USB port to USB device mode. */
+
+       s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+                             S3C2410_MISCCR_USBSUSPND0 |
+                             S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+       s3c24xx_udc_set_platdata(&jive_udc_cfg);
+       s3c24xx_fb_set_platdata(&jive_lcd_config);
+
+       spi_register_board_info(jive_spi_devs, ARRAY_SIZE(jive_spi_devs));
+
+       s3c_i2c0_set_platdata(&jive_i2c_cfg);
+       i2c_register_board_info(0, jive_i2c_devs, ARRAY_SIZE(jive_i2c_devs));
+
+       pm_power_off = jive_power_off;
+
+       platform_add_devices(jive_devices, ARRAY_SIZE(jive_devices));
+}
+
+MACHINE_START(JIVE, "JIVE")
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+       .atag_offset    = 0x100,
+
+       .init_irq       = s3c24xx_init_irq,
+       .map_io         = jive_map_io,
+       .init_machine   = jive_machine_init,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c2412_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c
new file mode 100644 (file)
index 0000000..5d66fb2
--- /dev/null
@@ -0,0 +1,705 @@
+/* linux/arch/arm/mach-s3c2440/mach-mini2440.c
+ *
+ * Copyright (c) 2008 Ramax Lo <ramaxlo@gmail.com>
+ *      Based on mach-anubis.c by Ben Dooks <ben@simtec.co.uk>
+ *      and modifications by SBZ <sbz@spgui.org> and
+ *      Weibing <http://weibing.blogbus.com> and
+ *      Michel Pollet <buserror@gmail.com>
+ *
+ * For product information, visit http://code.google.com/p/mini2440/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/serial_core.h>
+#include <linux/dm9000.h>
+#include <linux/i2c/at24.h>
+#include <linux/platform_device.h>
+#include <linux/gpio_keys.h>
+#include <linux/i2c.h>
+#include <linux/mmc/host.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/fb.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/leds-gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+#include <mach/irqs.h>
+#include <plat/nand.h>
+#include <plat/iic.h>
+#include <plat/mci.h>
+#include <plat/udc.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include <sound/s3c24xx_uda134x.h>
+
+#include "common.h"
+
+#define MACH_MINI2440_DM9K_BASE (S3C2410_CS4 + 0x300)
+
+static struct map_desc mini2440_iodesc[] __initdata = {
+       /* nothing to declare, move along */
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+
+static struct s3c2410_uartcfg mini2440_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+};
+
+/* USB device UDC support */
+
+static struct s3c2410_udc_mach_info mini2440_udc_cfg __initdata = {
+       .pullup_pin = S3C2410_GPC(5),
+};
+
+
+/* LCD timing and setup */
+
+/*
+ * This macro simplifies the table bellow
+ */
+#define _LCD_DECLARE(_clock,_xres,margin_left,margin_right,hsync, \
+                       _yres,margin_top,margin_bottom,vsync, refresh) \
+       .width = _xres, \
+       .xres = _xres, \
+       .height = _yres, \
+       .yres = _yres, \
+       .left_margin    = margin_left,  \
+       .right_margin   = margin_right, \
+       .upper_margin   = margin_top,   \
+       .lower_margin   = margin_bottom,        \
+       .hsync_len      = hsync,        \
+       .vsync_len      = vsync,        \
+       .pixclock       = ((_clock*100000000000LL) /    \
+                          ((refresh) * \
+                          (hsync + margin_left + _xres + margin_right) * \
+                          (vsync + margin_top + _yres + margin_bottom))), \
+       .bpp            = 16,\
+       .type           = (S3C2410_LCDCON1_TFT16BPP |\
+                          S3C2410_LCDCON1_TFT)
+
+static struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = {
+       [0] = { /* mini2440 + 3.5" TFT + touchscreen */
+               _LCD_DECLARE(
+                       7,                      /* The 3.5 is quite fast */
+                       240, 21, 38, 6,         /* x timing */
+                       320, 4, 4, 2,           /* y timing */
+                       60),                    /* refresh rate */
+               .lcdcon5        = (S3C2410_LCDCON5_FRM565 |
+                                  S3C2410_LCDCON5_INVVLINE |
+                                  S3C2410_LCDCON5_INVVFRAME |
+                                  S3C2410_LCDCON5_INVVDEN |
+                                  S3C2410_LCDCON5_PWREN),
+       },
+       [1] = { /* mini2440 + 7" TFT + touchscreen */
+               _LCD_DECLARE(
+                       10,                     /* the 7" runs slower */
+                       800, 40, 40, 48,        /* x timing */
+                       480, 29, 3, 3,          /* y timing */
+                       50),                    /* refresh rate */
+               .lcdcon5        = (S3C2410_LCDCON5_FRM565 |
+                                  S3C2410_LCDCON5_INVVLINE |
+                                  S3C2410_LCDCON5_INVVFRAME |
+                                  S3C2410_LCDCON5_PWREN),
+       },
+       /* The VGA shield can outout at several resolutions. All share 
+        * the same timings, however, anything smaller than 1024x768
+        * will only be displayed in the top left corner of a 1024x768
+        * XGA output unless you add optional dip switches to the shield.
+        * Therefore timings for other resolutions have been omitted here.
+        */
+       [2] = {
+               _LCD_DECLARE(
+                       10,
+                       1024, 1, 2, 2,          /* y timing */
+                       768, 200, 16, 16,       /* x timing */
+                       24),    /* refresh rate, maximum stable,
+                                tested with the FPGA shield */
+               .lcdcon5        = (S3C2410_LCDCON5_FRM565 |
+                                  S3C2410_LCDCON5_HWSWP),
+       },
+       /* mini2440 + 3.5" TFT (LCD-W35i, LQ035Q1DG06 type) + touchscreen*/
+       [3] = {
+               _LCD_DECLARE(
+                       /* clock */
+                       7,
+                       /* xres, margin_right, margin_left, hsync */
+                       320, 68, 66, 4,
+                       /* yres, margin_top, margin_bottom, vsync */
+                       240, 4, 4, 9,
+                       /* refresh rate */
+                       60),
+               .lcdcon5        = (S3C2410_LCDCON5_FRM565 |
+                                  S3C2410_LCDCON5_INVVDEN |
+                                  S3C2410_LCDCON5_INVVFRAME |
+                                  S3C2410_LCDCON5_INVVLINE |
+                                  S3C2410_LCDCON5_INVVCLK |
+                                  S3C2410_LCDCON5_HWSWP),
+       },
+};
+
+/* todo - put into gpio header */
+
+#define S3C2410_GPCCON_MASK(x) (3 << ((x) * 2))
+#define S3C2410_GPDCON_MASK(x) (3 << ((x) * 2))
+
+static struct s3c2410fb_mach_info mini2440_fb_info __initdata = {
+       .displays        = &mini2440_lcd_cfg[0], /* not constant! see init */
+       .num_displays    = 1,
+       .default_display = 0,
+
+       /* Enable VD[2..7], VD[10..15], VD[18..23] and VCLK, syncs, VDEN
+        * and disable the pull down resistors on pins we are using for LCD
+        * data. */
+
+       .gpcup          = (0xf << 1) | (0x3f << 10),
+
+       .gpccon         = (S3C2410_GPC1_VCLK   | S3C2410_GPC2_VLINE |
+                          S3C2410_GPC3_VFRAME | S3C2410_GPC4_VM |
+                          S3C2410_GPC10_VD2   | S3C2410_GPC11_VD3 |
+                          S3C2410_GPC12_VD4   | S3C2410_GPC13_VD5 |
+                          S3C2410_GPC14_VD6   | S3C2410_GPC15_VD7),
+
+       .gpccon_mask    = (S3C2410_GPCCON_MASK(1)  | S3C2410_GPCCON_MASK(2)  |
+                          S3C2410_GPCCON_MASK(3)  | S3C2410_GPCCON_MASK(4)  |
+                          S3C2410_GPCCON_MASK(10) | S3C2410_GPCCON_MASK(11) |
+                          S3C2410_GPCCON_MASK(12) | S3C2410_GPCCON_MASK(13) |
+                          S3C2410_GPCCON_MASK(14) | S3C2410_GPCCON_MASK(15)),
+
+       .gpdup          = (0x3f << 2) | (0x3f << 10),
+
+       .gpdcon         = (S3C2410_GPD2_VD10  | S3C2410_GPD3_VD11 |
+                          S3C2410_GPD4_VD12  | S3C2410_GPD5_VD13 |
+                          S3C2410_GPD6_VD14  | S3C2410_GPD7_VD15 |
+                          S3C2410_GPD10_VD18 | S3C2410_GPD11_VD19 |
+                          S3C2410_GPD12_VD20 | S3C2410_GPD13_VD21 |
+                          S3C2410_GPD14_VD22 | S3C2410_GPD15_VD23),
+
+       .gpdcon_mask    = (S3C2410_GPDCON_MASK(2)  | S3C2410_GPDCON_MASK(3) |
+                          S3C2410_GPDCON_MASK(4)  | S3C2410_GPDCON_MASK(5) |
+                          S3C2410_GPDCON_MASK(6)  | S3C2410_GPDCON_MASK(7) |
+                          S3C2410_GPDCON_MASK(10) | S3C2410_GPDCON_MASK(11)|
+                          S3C2410_GPDCON_MASK(12) | S3C2410_GPDCON_MASK(13)|
+                          S3C2410_GPDCON_MASK(14) | S3C2410_GPDCON_MASK(15)),
+};
+
+/* MMC/SD  */
+
+static struct s3c24xx_mci_pdata mini2440_mmc_cfg __initdata = {
+   .gpio_detect   = S3C2410_GPG(8),
+   .gpio_wprotect = S3C2410_GPH(8),
+   .set_power     = NULL,
+   .ocr_avail     = MMC_VDD_32_33|MMC_VDD_33_34,
+};
+
+/* NAND Flash on MINI2440 board */
+
+static struct mtd_partition mini2440_default_nand_part[] __initdata = {
+       [0] = {
+               .name   = "u-boot",
+               .size   = SZ_256K,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "u-boot-env",
+               .size   = SZ_128K,
+               .offset = SZ_256K,
+       },
+       [2] = {
+               .name   = "kernel",
+               /* 5 megabytes, for a kernel with no modules
+                * or a uImage with a ramdisk attached */
+               .size   = 0x00500000,
+               .offset = SZ_256K + SZ_128K,
+       },
+       [3] = {
+               .name   = "root",
+               .offset = SZ_256K + SZ_128K + 0x00500000,
+               .size   = MTDPART_SIZ_FULL,
+       },
+};
+
+static struct s3c2410_nand_set mini2440_nand_sets[] __initdata = {
+       [0] = {
+               .name           = "nand",
+               .nr_chips       = 1,
+               .nr_partitions  = ARRAY_SIZE(mini2440_default_nand_part),
+               .partitions     = mini2440_default_nand_part,
+               .flash_bbt      = 1, /* we use u-boot to create a BBT */
+       },
+};
+
+static struct s3c2410_platform_nand mini2440_nand_info __initdata = {
+       .tacls          = 0,
+       .twrph0         = 25,
+       .twrph1         = 15,
+       .nr_sets        = ARRAY_SIZE(mini2440_nand_sets),
+       .sets           = mini2440_nand_sets,
+       .ignore_unset_ecc = 1,
+};
+
+/* DM9000AEP 10/100 ethernet controller */
+
+static struct resource mini2440_dm9k_resource[] = {
+       [0] = {
+               .start = MACH_MINI2440_DM9K_BASE,
+               .end   = MACH_MINI2440_DM9K_BASE + 3,
+               .flags = IORESOURCE_MEM
+       },
+       [1] = {
+               .start = MACH_MINI2440_DM9K_BASE + 4,
+               .end   = MACH_MINI2440_DM9K_BASE + 7,
+               .flags = IORESOURCE_MEM
+       },
+       [2] = {
+               .start = IRQ_EINT7,
+               .end   = IRQ_EINT7,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+       }
+};
+
+/*
+ * The DM9000 has no eeprom, and it's MAC address is set by
+ * the bootloader before starting the kernel.
+ */
+static struct dm9000_plat_data mini2440_dm9k_pdata = {
+       .flags          = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+};
+
+static struct platform_device mini2440_device_eth = {
+       .name           = "dm9000",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(mini2440_dm9k_resource),
+       .resource       = mini2440_dm9k_resource,
+       .dev            = {
+               .platform_data  = &mini2440_dm9k_pdata,
+       },
+};
+
+/*  CON5
+ *     +--+     /-----\
+ *     |  |    |       |
+ *     |  |    |  BAT  |
+ *     |  |     \_____/
+ *     |  |
+ *     |  |  +----+  +----+
+ *     |  |  | K5 |  | K1 |
+ *     |  |  +----+  +----+
+ *     |  |  +----+  +----+
+ *     |  |  | K4 |  | K2 |
+ *     |  |  +----+  +----+
+ *     |  |  +----+  +----+
+ *     |  |  | K6 |  | K3 |
+ *     |  |  +----+  +----+
+ *       .....
+ */
+static struct gpio_keys_button mini2440_buttons[] = {
+       {
+               .gpio           = S3C2410_GPG(0),               /* K1 */
+               .code           = KEY_F1,
+               .desc           = "Button 1",
+               .active_low     = 1,
+       },
+       {
+               .gpio           = S3C2410_GPG(3),               /* K2 */
+               .code           = KEY_F2,
+               .desc           = "Button 2",
+               .active_low     = 1,
+       },
+       {
+               .gpio           = S3C2410_GPG(5),               /* K3 */
+               .code           = KEY_F3,
+               .desc           = "Button 3",
+               .active_low     = 1,
+       },
+       {
+               .gpio           = S3C2410_GPG(6),               /* K4 */
+               .code           = KEY_POWER,
+               .desc           = "Power",
+               .active_low     = 1,
+       },
+       {
+               .gpio           = S3C2410_GPG(7),               /* K5 */
+               .code           = KEY_F5,
+               .desc           = "Button 5",
+               .active_low     = 1,
+       },
+#if 0
+       /* this pin is also known as TCLK1 and seems to already
+        * marked as "in use" somehow in the kernel -- possibly wrongly */
+       {
+               .gpio           = S3C2410_GPG(11),      /* K6 */
+               .code           = KEY_F6,
+               .desc           = "Button 6",
+               .active_low     = 1,
+       },
+#endif
+};
+
+static struct gpio_keys_platform_data mini2440_button_data = {
+       .buttons        = mini2440_buttons,
+       .nbuttons       = ARRAY_SIZE(mini2440_buttons),
+};
+
+static struct platform_device mini2440_button_device = {
+       .name           = "gpio-keys",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &mini2440_button_data,
+       }
+};
+
+/* LEDS */
+
+static struct s3c24xx_led_platdata mini2440_led1_pdata = {
+       .name           = "led1",
+       .gpio           = S3C2410_GPB(5),
+       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+       .def_trigger    = "heartbeat",
+};
+
+static struct s3c24xx_led_platdata mini2440_led2_pdata = {
+       .name           = "led2",
+       .gpio           = S3C2410_GPB(6),
+       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+       .def_trigger    = "nand-disk",
+};
+
+static struct s3c24xx_led_platdata mini2440_led3_pdata = {
+       .name           = "led3",
+       .gpio           = S3C2410_GPB(7),
+       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+       .def_trigger    = "mmc0",
+};
+
+static struct s3c24xx_led_platdata mini2440_led4_pdata = {
+       .name           = "led4",
+       .gpio           = S3C2410_GPB(8),
+       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+       .def_trigger    = "",
+};
+
+static struct s3c24xx_led_platdata mini2440_led_backlight_pdata = {
+       .name           = "backlight",
+       .gpio           = S3C2410_GPG(4),
+       .def_trigger    = "backlight",
+};
+
+static struct platform_device mini2440_led1 = {
+       .name           = "s3c24xx_led",
+       .id             = 1,
+       .dev            = {
+               .platform_data  = &mini2440_led1_pdata,
+       },
+};
+
+static struct platform_device mini2440_led2 = {
+       .name           = "s3c24xx_led",
+       .id             = 2,
+       .dev            = {
+               .platform_data  = &mini2440_led2_pdata,
+       },
+};
+
+static struct platform_device mini2440_led3 = {
+       .name           = "s3c24xx_led",
+       .id             = 3,
+       .dev            = {
+               .platform_data  = &mini2440_led3_pdata,
+       },
+};
+
+static struct platform_device mini2440_led4 = {
+       .name           = "s3c24xx_led",
+       .id             = 4,
+       .dev            = {
+               .platform_data  = &mini2440_led4_pdata,
+       },
+};
+
+static struct platform_device mini2440_led_backlight = {
+       .name           = "s3c24xx_led",
+       .id             = 5,
+       .dev            = {
+               .platform_data  = &mini2440_led_backlight_pdata,
+       },
+};
+
+/* AUDIO */
+
+static struct s3c24xx_uda134x_platform_data mini2440_audio_pins = {
+       .l3_clk = S3C2410_GPB(4),
+       .l3_mode = S3C2410_GPB(2),
+       .l3_data = S3C2410_GPB(3),
+       .model = UDA134X_UDA1341
+};
+
+static struct platform_device mini2440_audio = {
+       .name           = "s3c24xx_uda134x",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &mini2440_audio_pins,
+       },
+};
+
+/*
+ * I2C devices
+ */
+static struct at24_platform_data at24c08 = {
+       .byte_len       = SZ_8K / 8,
+       .page_size      = 16,
+};
+
+static struct i2c_board_info mini2440_i2c_devs[] __initdata = {
+       {
+               I2C_BOARD_INFO("24c08", 0x50),
+               .platform_data = &at24c08,
+       },
+};
+
+static struct platform_device uda1340_codec = {
+               .name = "uda134x-codec",
+               .id = -1,
+};
+
+static struct platform_device *mini2440_devices[] __initdata = {
+       &s3c_device_ohci,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_rtc,
+       &s3c_device_usbgadget,
+       &mini2440_device_eth,
+       &mini2440_led1,
+       &mini2440_led2,
+       &mini2440_led3,
+       &mini2440_led4,
+       &mini2440_button_device,
+       &s3c_device_nand,
+       &s3c_device_sdi,
+       &s3c_device_iis,
+       &uda1340_codec,
+       &mini2440_audio,
+       &samsung_asoc_dma,
+};
+
+static void __init mini2440_map_io(void)
+{
+       s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc));
+       s3c24xx_init_clocks(12000000);
+       s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs));
+}
+
+/*
+ * mini2440_features string
+ *
+ * t = Touchscreen present
+ * b = backlight control
+ * c = camera [TODO]
+ * 0-9 LCD configuration
+ *
+ */
+static char mini2440_features_str[12] __initdata = "0tb";
+
+static int __init mini2440_features_setup(char *str)
+{
+       if (str)
+               strlcpy(mini2440_features_str, str, sizeof(mini2440_features_str));
+       return 1;
+}
+
+__setup("mini2440=", mini2440_features_setup);
+
+#define FEATURE_SCREEN (1 << 0)
+#define FEATURE_BACKLIGHT (1 << 1)
+#define FEATURE_TOUCH (1 << 2)
+#define FEATURE_CAMERA (1 << 3)
+
+struct mini2440_features_t {
+       int count;
+       int done;
+       int lcd_index;
+       struct platform_device *optional[8];
+};
+
+static void __init mini2440_parse_features(
+               struct mini2440_features_t * features,
+               const char * features_str )
+{
+       const char * fp = features_str;
+
+       features->count = 0;
+       features->done = 0;
+       features->lcd_index = -1;
+
+       while (*fp) {
+               char f = *fp++;
+
+               switch (f) {
+               case '0'...'9': /* tft screen */
+                       if (features->done & FEATURE_SCREEN) {
+                               printk(KERN_INFO "MINI2440: '%c' ignored, "
+                                       "screen type already set\n", f);
+                       } else {
+                               int li = f - '0';
+                               if (li >= ARRAY_SIZE(mini2440_lcd_cfg))
+                                       printk(KERN_INFO "MINI2440: "
+                                               "'%c' out of range LCD mode\n", f);
+                               else {
+                                       features->optional[features->count++] =
+                                                       &s3c_device_lcd;
+                                       features->lcd_index = li;
+                               }
+                       }
+                       features->done |= FEATURE_SCREEN;
+                       break;
+               case 'b':
+                       if (features->done & FEATURE_BACKLIGHT)
+                               printk(KERN_INFO "MINI2440: '%c' ignored, "
+                                       "backlight already set\n", f);
+                       else {
+                               features->optional[features->count++] =
+                                               &mini2440_led_backlight;
+                       }
+                       features->done |= FEATURE_BACKLIGHT;
+                       break;
+               case 't':
+                       printk(KERN_INFO "MINI2440: '%c' ignored, "
+                               "touchscreen not compiled in\n", f);
+                       break;
+               case 'c':
+                       if (features->done & FEATURE_CAMERA)
+                               printk(KERN_INFO "MINI2440: '%c' ignored, "
+                                       "camera already registered\n", f);
+                       else
+                               features->optional[features->count++] =
+                                       &s3c_device_camif;
+                       features->done |= FEATURE_CAMERA;
+                       break;
+               }
+       }
+}
+
+static void __init mini2440_init(void)
+{
+       struct mini2440_features_t features = { 0 };
+       int i;
+
+       printk(KERN_INFO "MINI2440: Option string mini2440=%s\n",
+                       mini2440_features_str);
+
+       /* Parse the feature string */
+       mini2440_parse_features(&features, mini2440_features_str);
+
+       /* turn LCD on */
+       s3c_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);
+
+       /* Turn the backlight early on */
+       WARN_ON(gpio_request(S3C2410_GPG(4), "backlight"));
+       gpio_direction_output(S3C2410_GPG(4), 1);
+
+       /* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */
+       s3c_gpio_setpull(S3C2410_GPB(1), S3C_GPIO_PULL_UP);
+       s3c2410_gpio_setpin(S3C2410_GPB(1), 0);
+       s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT);
+
+       /* mark the key as input, without pullups (there is one on the board) */
+       for (i = 0; i < ARRAY_SIZE(mini2440_buttons); i++) {
+               s3c_gpio_setpull(mini2440_buttons[i].gpio, S3C_GPIO_PULL_UP);
+               s3c_gpio_cfgpin(mini2440_buttons[i].gpio, S3C2410_GPIO_INPUT);
+       }
+       if (features.lcd_index != -1) {
+               int li;
+
+               mini2440_fb_info.displays =
+                       &mini2440_lcd_cfg[features.lcd_index];
+
+               printk(KERN_INFO "MINI2440: LCD");
+               for (li = 0; li < ARRAY_SIZE(mini2440_lcd_cfg); li++)
+                       if (li == features.lcd_index)
+                               printk(" [%d:%dx%d]", li,
+                                       mini2440_lcd_cfg[li].width,
+                                       mini2440_lcd_cfg[li].height);
+                       else
+                               printk(" %d:%dx%d", li,
+                                       mini2440_lcd_cfg[li].width,
+                                       mini2440_lcd_cfg[li].height);
+               printk("\n");
+               s3c24xx_fb_set_platdata(&mini2440_fb_info);
+       }
+
+       s3c24xx_udc_set_platdata(&mini2440_udc_cfg);
+       s3c24xx_mci_set_platdata(&mini2440_mmc_cfg);
+       s3c_nand_set_platdata(&mini2440_nand_info);
+       s3c_i2c0_set_platdata(NULL);
+
+       i2c_register_board_info(0, mini2440_i2c_devs,
+                               ARRAY_SIZE(mini2440_i2c_devs));
+
+       platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));
+
+       if (features.count)     /* the optional features */
+               platform_add_devices(features.optional, features.count);
+
+}
+
+
+MACHINE_START(MINI2440, "MINI2440")
+       /* Maintainer: Michel Pollet <buserror@gmail.com> */
+       .atag_offset    = 0x100,
+       .map_io         = mini2440_map_io,
+       .init_machine   = mini2440_init,
+       .init_irq       = s3c24xx_init_irq,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c244x_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-n30.c b/arch/arm/mach-s3c24xx/mach-n30.c
new file mode 100644 (file)
index 0000000..383d00c
--- /dev/null
@@ -0,0 +1,608 @@
+/* Machine specific code for the Acer n30, Acer N35, Navman PiN 570,
+ * Yakumo AlphaX and Airis NC05 PDAs.
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Copyright (c) 2005-2008 Christer Weinigel <christer@weinigel.se>
+ *
+ * There is a wiki with more information about the n30 port at
+ * http://handhelds.org/moin/moin.cgi/AcerN30Documentation .
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <linux/gpio_keys.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/timer.h>
+#include <linux/io.h>
+#include <linux/mmc/host.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/fb.h>
+#include <mach/leds-gpio.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+
+#include <plat/iic.h>
+#include <plat/regs-serial.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/mci.h>
+#include <plat/s3c2410.h>
+#include <plat/udc.h>
+
+#include "common.h"
+
+static struct map_desc n30_iodesc[] __initdata = {
+       /* nothing here yet */
+};
+
+static struct s3c2410_uartcfg n30_uartcfgs[] = {
+       /* Normal serial port */
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = 0x2c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       /* IR port */
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .uart_flags  = UPF_CONS_FLOW,
+               .ucon        = 0x2c5,
+               .ulcon       = 0x43,
+               .ufcon       = 0x51,
+       },
+       /* On the N30 the bluetooth controller is connected here.
+        * On the N35 and variants the GPS receiver is connected here. */
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = 0x2c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+};
+
+static struct s3c2410_udc_mach_info n30_udc_cfg __initdata = {
+       .vbus_pin               = S3C2410_GPG(1),
+       .vbus_pin_inverted      = 0,
+       .pullup_pin             = S3C2410_GPB(3),
+};
+
+static struct gpio_keys_button n30_buttons[] = {
+       {
+               .gpio           = S3C2410_GPF(0),
+               .code           = KEY_POWER,
+               .desc           = "Power",
+               .active_low     = 0,
+       },
+       {
+               .gpio           = S3C2410_GPG(9),
+               .code           = KEY_UP,
+               .desc           = "Thumbwheel Up",
+               .active_low     = 0,
+       },
+       {
+               .gpio           = S3C2410_GPG(8),
+               .code           = KEY_DOWN,
+               .desc           = "Thumbwheel Down",
+               .active_low     = 0,
+       },
+       {
+               .gpio           = S3C2410_GPG(7),
+               .code           = KEY_ENTER,
+               .desc           = "Thumbwheel Press",
+               .active_low     = 0,
+       },
+       {
+               .gpio           = S3C2410_GPF(7),
+               .code           = KEY_HOMEPAGE,
+               .desc           = "Home",
+               .active_low     = 0,
+       },
+       {
+               .gpio           = S3C2410_GPF(6),
+               .code           = KEY_CALENDAR,
+               .desc           = "Calendar",
+               .active_low     = 0,
+       },
+       {
+               .gpio           = S3C2410_GPF(5),
+               .code           = KEY_ADDRESSBOOK,
+               .desc           = "Contacts",
+               .active_low     = 0,
+       },
+       {
+               .gpio           = S3C2410_GPF(4),
+               .code           = KEY_MAIL,
+               .desc           = "Mail",
+               .active_low     = 0,
+       },
+};
+
+static struct gpio_keys_platform_data n30_button_data = {
+       .buttons        = n30_buttons,
+       .nbuttons       = ARRAY_SIZE(n30_buttons),
+};
+
+static struct platform_device n30_button_device = {
+       .name           = "gpio-keys",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &n30_button_data,
+       }
+};
+
+static struct gpio_keys_button n35_buttons[] = {
+       {
+               .gpio           = S3C2410_GPF(0),
+               .code           = KEY_POWER,
+               .type           = EV_PWR,
+               .desc           = "Power",
+               .active_low     = 0,
+               .wakeup         = 1,
+       },
+       {
+               .gpio           = S3C2410_GPG(9),
+               .code           = KEY_UP,
+               .desc           = "Joystick Up",
+               .active_low     = 0,
+       },
+       {
+               .gpio           = S3C2410_GPG(8),
+               .code           = KEY_DOWN,
+               .desc           = "Joystick Down",
+               .active_low     = 0,
+       },
+       {
+               .gpio           = S3C2410_GPG(6),
+               .code           = KEY_DOWN,
+               .desc           = "Joystick Left",
+               .active_low     = 0,
+       },
+       {
+               .gpio           = S3C2410_GPG(5),
+               .code           = KEY_DOWN,
+               .desc           = "Joystick Right",
+               .active_low     = 0,
+       },
+       {
+               .gpio           = S3C2410_GPG(7),
+               .code           = KEY_ENTER,
+               .desc           = "Joystick Press",
+               .active_low     = 0,
+       },
+       {
+               .gpio           = S3C2410_GPF(7),
+               .code           = KEY_HOMEPAGE,
+               .desc           = "Home",
+               .active_low     = 0,
+       },
+       {
+               .gpio           = S3C2410_GPF(6),
+               .code           = KEY_CALENDAR,
+               .desc           = "Calendar",
+               .active_low     = 0,
+       },
+       {
+               .gpio           = S3C2410_GPF(5),
+               .code           = KEY_ADDRESSBOOK,
+               .desc           = "Contacts",
+               .active_low     = 0,
+       },
+       {
+               .gpio           = S3C2410_GPF(4),
+               .code           = KEY_MAIL,
+               .desc           = "Mail",
+               .active_low     = 0,
+       },
+       {
+               .gpio           = S3C2410_GPF(3),
+               .code           = SW_RADIO,
+               .desc           = "GPS Antenna",
+               .active_low     = 0,
+       },
+       {
+               .gpio           = S3C2410_GPG(2),
+               .code           = SW_HEADPHONE_INSERT,
+               .desc           = "Headphone",
+               .active_low     = 0,
+       },
+};
+
+static struct gpio_keys_platform_data n35_button_data = {
+       .buttons        = n35_buttons,
+       .nbuttons       = ARRAY_SIZE(n35_buttons),
+};
+
+static struct platform_device n35_button_device = {
+       .name           = "gpio-keys",
+       .id             = -1,
+       .num_resources  = 0,
+       .dev            = {
+               .platform_data  = &n35_button_data,
+       }
+};
+
+/* This is the bluetooth LED on the device. */
+static struct s3c24xx_led_platdata n30_blue_led_pdata = {
+       .name           = "blue_led",
+       .gpio           = S3C2410_GPG(6),
+       .def_trigger    = "",
+};
+
+/* This is the blue LED on the device. Originally used to indicate GPS activity
+ * by flashing. */
+static struct s3c24xx_led_platdata n35_blue_led_pdata = {
+       .name           = "blue_led",
+       .gpio           = S3C2410_GPD(8),
+       .def_trigger    = "",
+};
+
+/* This LED is driven by the battery microcontroller, and is blinking
+ * red, blinking green or solid green when the battery is low,
+ * charging or full respectively.  By driving GPD9 low, it's possible
+ * to force the LED to blink red, so call that warning LED.  */
+static struct s3c24xx_led_platdata n30_warning_led_pdata = {
+       .name           = "warning_led",
+       .flags          = S3C24XX_LEDF_ACTLOW,
+       .gpio           = S3C2410_GPD(9),
+       .def_trigger    = "",
+};
+
+static struct s3c24xx_led_platdata n35_warning_led_pdata = {
+       .name           = "warning_led",
+       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+       .gpio           = S3C2410_GPD(9),
+       .def_trigger    = "",
+};
+
+static struct platform_device n30_blue_led = {
+       .name           = "s3c24xx_led",
+       .id             = 1,
+       .dev            = {
+               .platform_data  = &n30_blue_led_pdata,
+       },
+};
+
+static struct platform_device n35_blue_led = {
+       .name           = "s3c24xx_led",
+       .id             = 1,
+       .dev            = {
+               .platform_data  = &n35_blue_led_pdata,
+       },
+};
+
+static struct platform_device n30_warning_led = {
+       .name           = "s3c24xx_led",
+       .id             = 2,
+       .dev            = {
+               .platform_data  = &n30_warning_led_pdata,
+       },
+};
+
+static struct platform_device n35_warning_led = {
+       .name           = "s3c24xx_led",
+       .id             = 2,
+       .dev            = {
+               .platform_data  = &n35_warning_led_pdata,
+       },
+};
+
+static struct s3c2410fb_display n30_display __initdata = {
+       .type           = S3C2410_LCDCON1_TFT,
+       .width          = 240,
+       .height         = 320,
+       .pixclock       = 170000,
+
+       .xres           = 240,
+       .yres           = 320,
+       .bpp            = 16,
+       .left_margin    = 3,
+       .right_margin   = 40,
+       .hsync_len      = 40,
+       .upper_margin   = 2,
+       .lower_margin   = 3,
+       .vsync_len      = 2,
+
+       .lcdcon5 = S3C2410_LCDCON5_INVVLINE | S3C2410_LCDCON5_INVVFRAME,
+};
+
+static struct s3c2410fb_mach_info n30_fb_info __initdata = {
+       .displays       = &n30_display,
+       .num_displays   = 1,
+       .default_display = 0,
+       .lpcsel         = 0x06,
+};
+
+static void n30_sdi_set_power(unsigned char power_mode, unsigned short vdd)
+{
+       switch (power_mode) {
+       case MMC_POWER_ON:
+       case MMC_POWER_UP:
+               gpio_set_value(S3C2410_GPG(4), 1);
+               break;
+       case MMC_POWER_OFF:
+       default:
+               gpio_set_value(S3C2410_GPG(4), 0);
+               break;
+       }
+}
+
+static struct s3c24xx_mci_pdata n30_mci_cfg __initdata = {
+       .gpio_detect    = S3C2410_GPF(1),
+       .gpio_wprotect  = S3C2410_GPG(10),
+       .ocr_avail      = MMC_VDD_32_33,
+       .set_power      = n30_sdi_set_power,
+};
+
+static struct platform_device *n30_devices[] __initdata = {
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_iis,
+       &s3c_device_ohci,
+       &s3c_device_rtc,
+       &s3c_device_usbgadget,
+       &s3c_device_sdi,
+       &n30_button_device,
+       &n30_blue_led,
+       &n30_warning_led,
+};
+
+static struct platform_device *n35_devices[] __initdata = {
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_iis,
+       &s3c_device_rtc,
+       &s3c_device_usbgadget,
+       &s3c_device_sdi,
+       &n35_button_device,
+       &n35_blue_led,
+       &n35_warning_led,
+};
+
+static struct s3c2410_platform_i2c __initdata n30_i2ccfg = {
+       .flags          = 0,
+       .slave_addr     = 0x10,
+       .frequency      = 10*1000,
+};
+
+/* Lots of hardcoded stuff, but it sets up the hardware in a useful
+ * state so that we can boot Linux directly from flash. */
+static void __init n30_hwinit(void)
+{
+       /* GPA0-11 special functions -- unknown what they do
+        * GPA12 N30 special function -- unknown what it does
+        *       N35/PiN output -- unknown what it does
+        *
+        * A12 is nGCS1 on the N30 and an output on the N35/PiN.  I
+        * don't think it does anything useful on the N30, so I ought
+        * to make it an output there too since it always driven to 0
+        * as far as I can tell. */
+       if (machine_is_n30())
+               __raw_writel(0x007fffff, S3C2410_GPACON);
+       if (machine_is_n35())
+               __raw_writel(0x007fefff, S3C2410_GPACON);
+       __raw_writel(0x00000000, S3C2410_GPADAT);
+
+       /* GPB0 TOUT0 backlight level
+        * GPB1 output 1=backlight on
+        * GPB2 output IrDA enable 0=transceiver enabled, 1=disabled
+        * GPB3 output USB D+ pull up 0=disabled, 1=enabled
+        * GPB4 N30 output -- unknown function
+        *      N30/PiN GPS control 0=GPS enabled, 1=GPS disabled
+        * GPB5 output -- unknown function
+        * GPB6 input -- unknown function
+        * GPB7 output -- unknown function
+        * GPB8 output -- probably LCD driver enable
+        * GPB9 output -- probably LCD VSYNC driver enable
+        * GPB10 output -- probably LCD HSYNC driver enable
+        */
+       __raw_writel(0x00154556, S3C2410_GPBCON);
+       __raw_writel(0x00000750, S3C2410_GPBDAT);
+       __raw_writel(0x00000073, S3C2410_GPBUP);
+
+       /* GPC0 input RS232 DCD/DSR/RI
+        * GPC1 LCD
+        * GPC2 output RS232 DTR?
+        * GPC3 input RS232 DCD/DSR/RI
+        * GPC4 LCD
+        * GPC5 output 0=NAND write enabled, 1=NAND write protect
+        * GPC6 input -- unknown function
+        * GPC7 input charger status 0=charger connected
+        *      this input can be triggered by power on the USB device
+        *      port too, but will go back to disconnected soon after.
+        * GPC8 N30/N35 output -- unknown function, always driven to 1
+        *      PiN input -- unknown function, always read as 1
+        *      Make it an input with a pull up for all models.
+        * GPC9-15 LCD
+        */
+       __raw_writel(0xaaa80618, S3C2410_GPCCON);
+       __raw_writel(0x0000014c, S3C2410_GPCDAT);
+       __raw_writel(0x0000fef2, S3C2410_GPCUP);
+
+       /* GPD0 input -- unknown function
+        * GPD1-D7 LCD
+        * GPD8 N30 output -- unknown function
+        *      N35/PiN output 1=GPS LED on
+        * GPD9 output 0=power led blinks red, 1=normal power led function
+        * GPD10 output -- unknown function
+        * GPD11-15 LCD drivers
+        */
+       __raw_writel(0xaa95aaa4, S3C2410_GPDCON);
+       __raw_writel(0x00000601, S3C2410_GPDDAT);
+       __raw_writel(0x0000fbfe, S3C2410_GPDUP);
+
+       /* GPE0-4 I2S audio bus
+        * GPE5-10 SD/MMC bus
+        * E11-13 outputs -- unknown function, probably power management
+        * E14-15 I2C bus connected to the battery controller
+        */
+       __raw_writel(0xa56aaaaa, S3C2410_GPECON);
+       __raw_writel(0x0000efc5, S3C2410_GPEDAT);
+       __raw_writel(0x0000f81f, S3C2410_GPEUP);
+
+       /* GPF0  input 0=power button pressed
+        * GPF1  input SD/MMC switch 0=card present
+        * GPF2  N30 1=reset button pressed (inverted compared to the rest)
+        *       N35/PiN 0=reset button pressed
+        * GPF3  N30/PiN input -- unknown function
+        *       N35 input GPS antenna position, 0=antenna closed, 1=open
+        * GPF4  input 0=button 4 pressed
+        * GPF5  input 0=button 3 pressed
+        * GPF6  input 0=button 2 pressed
+        * GPF7  input 0=button 1 pressed
+        */
+       __raw_writel(0x0000aaaa, S3C2410_GPFCON);
+       __raw_writel(0x00000000, S3C2410_GPFDAT);
+       __raw_writel(0x000000ff, S3C2410_GPFUP);
+
+       /* GPG0  input RS232 DCD/DSR/RI
+        * GPG1  input 1=USB gadget port has power from a host
+        * GPG2  N30 input -- unknown function
+        *       N35/PiN input 0=headphones plugged in, 1=not plugged in
+        * GPG3  N30 output -- unknown function
+        *       N35/PiN input with unknown function
+        * GPG4  N30 output 0=MMC enabled, 1=MMC disabled
+        * GPG5  N30 output 0=BlueTooth chip disabled, 1=enabled
+        *       N35/PiN input joystick right
+        * GPG6  N30 output 0=blue led on, 1=off
+        *       N35/PiN input joystick left
+        * GPG7  input 0=thumbwheel pressed
+        * GPG8  input 0=thumbwheel down
+        * GPG9  input 0=thumbwheel up
+        * GPG10 input SD/MMC write protect switch
+        * GPG11 N30 input -- unknown function
+        *       N35 output 0=GPS antenna powered, 1=not powered
+        *       PiN output -- unknown function
+        * GPG12-15 touch screen functions
+        *
+        * The pullups differ between the models, so enable all
+        * pullups that are enabled on any of the models.
+        */
+       if (machine_is_n30())
+               __raw_writel(0xff0a956a, S3C2410_GPGCON);
+       if (machine_is_n35())
+               __raw_writel(0xff4aa92a, S3C2410_GPGCON);
+       __raw_writel(0x0000e800, S3C2410_GPGDAT);
+       __raw_writel(0x0000f86f, S3C2410_GPGUP);
+
+       /* GPH0/1/2/3 RS232 serial port
+        * GPH4/5 IrDA serial port
+        * GPH6/7  N30 BlueTooth serial port
+        *         N35/PiN GPS receiver
+        * GPH8 input -- unknown function
+        * GPH9 CLKOUT0 HCLK -- unknown use
+        * GPH10 CLKOUT1 FCLK -- unknown use
+        *
+        * The pull ups for H6/H7 are enabled on N30 but not on the
+        * N35/PiN.  I suppose is useful for a budget model of the N30
+        * with no bluetooh.  It doesn't hurt to have the pull ups
+        * enabled on the N35, so leave them enabled for all models.
+        */
+       __raw_writel(0x0028aaaa, S3C2410_GPHCON);
+       __raw_writel(0x000005ef, S3C2410_GPHDAT);
+       __raw_writel(0x0000063f, S3C2410_GPHUP);
+}
+
+static void __init n30_map_io(void)
+{
+       s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
+       n30_hwinit();
+       s3c24xx_init_clocks(0);
+       s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
+}
+
+/* GPB3 is the line that controls the pull-up for the USB D+ line */
+
+static void __init n30_init(void)
+{
+       WARN_ON(gpio_request(S3C2410_GPG(4), "mmc power"));
+
+       s3c24xx_fb_set_platdata(&n30_fb_info);
+       s3c24xx_udc_set_platdata(&n30_udc_cfg);
+       s3c24xx_mci_set_platdata(&n30_mci_cfg);
+       s3c_i2c0_set_platdata(&n30_i2ccfg);
+
+       /* Turn off suspend on both USB ports, and switch the
+        * selectable USB port to USB device mode. */
+
+       s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+                             S3C2410_MISCCR_USBSUSPND0 |
+                             S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+       if (machine_is_n30()) {
+               /* Turn off suspend on both USB ports, and switch the
+                * selectable USB port to USB device mode. */
+               s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+                                     S3C2410_MISCCR_USBSUSPND0 |
+                                     S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+               platform_add_devices(n30_devices, ARRAY_SIZE(n30_devices));
+       }
+
+       if (machine_is_n35()) {
+               /* Turn off suspend and switch the selectable USB port
+                * to USB device mode.  Turn on suspend for the host
+                * port since it is not connected on the N35.
+                *
+                * Actually, the host port is available at some pads
+                * on the back of the device, so it would actually be
+                * possible to add a USB device inside the N35 if you
+                * are willing to do some hardware modifications. */
+               s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+                                     S3C2410_MISCCR_USBSUSPND0 |
+                                     S3C2410_MISCCR_USBSUSPND1,
+                                     S3C2410_MISCCR_USBSUSPND0);
+
+               platform_add_devices(n35_devices, ARRAY_SIZE(n35_devices));
+       }
+}
+
+MACHINE_START(N30, "Acer-N30")
+       /* Maintainer: Christer Weinigel <christer@weinigel.se>,
+                               Ben Dooks <ben-linux@fluff.org>
+       */
+       .atag_offset    = 0x100,
+       .timer          = &s3c24xx_timer,
+       .init_machine   = n30_init,
+       .init_irq       = s3c24xx_init_irq,
+       .map_io         = n30_map_io,
+       .restart        = s3c2410_restart,
+MACHINE_END
+
+MACHINE_START(N35, "Acer-N35")
+       /* Maintainer: Christer Weinigel <christer@weinigel.se>
+       */
+       .atag_offset    = 0x100,
+       .timer          = &s3c24xx_timer,
+       .init_machine   = n30_init,
+       .init_irq       = s3c24xx_init_irq,
+       .map_io         = n30_map_io,
+       .restart        = s3c2410_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-nexcoder.c b/arch/arm/mach-s3c24xx/mach-nexcoder.c
new file mode 100644 (file)
index 0000000..5198e3e
--- /dev/null
@@ -0,0 +1,162 @@
+/* linux/arch/arm/mach-s3c2440/mach-nexcoder.c
+ *
+ * Copyright (c) 2004 Nex Vision
+ *   Guillaume GOURAT <guillaume.gourat@nexvision.tv>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Modifications:
+ *     15-10-2004 GG  Created initial version
+ *     12-03-2005 BJD Updated for release
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/string.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <linux/mtd/map.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/setup.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+//#include <asm/debug-ll.h>
+#include <mach/regs-gpio.h>
+#include <plat/regs-serial.h>
+#include <plat/iic.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/s3c2410.h>
+#include <plat/s3c244x.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include "common.h"
+
+static struct map_desc nexcoder_iodesc[] __initdata = {
+       /* nothing here yet */
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg nexcoder_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       }
+};
+
+/* NOR Flash on NexVision NexCoder 2440 board */
+
+static struct resource nexcoder_nor_resource[] = {
+       [0] = {
+               .start = S3C2410_CS0,
+               .end   = S3C2410_CS0 + (8*1024*1024) - 1,
+               .flags = IORESOURCE_MEM,
+       }
+};
+
+static struct map_info nexcoder_nor_map = {
+       .bankwidth = 2,
+};
+
+static struct platform_device nexcoder_device_nor = {
+       .name           = "mtd-flash",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(nexcoder_nor_resource),
+       .resource       = nexcoder_nor_resource,
+       .dev =
+       {
+               .platform_data = &nexcoder_nor_map,
+       }
+};
+
+/* Standard Nexcoder devices */
+
+static struct platform_device *nexcoder_devices[] __initdata = {
+       &s3c_device_ohci,
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_iis,
+       &s3c_device_rtc,
+       &s3c_device_camif,
+       &s3c_device_spi0,
+       &s3c_device_spi1,
+       &nexcoder_device_nor,
+};
+
+static void __init nexcoder_sensorboard_init(void)
+{
+       // Initialize SCCB bus
+       s3c2410_gpio_setpin(S3C2410_GPE(14), 1); // IICSCL
+       s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_OUTPUT);
+       s3c2410_gpio_setpin(S3C2410_GPE(15), 1); // IICSDA
+       s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_OUTPUT);
+
+       // Power up the sensor board
+       s3c2410_gpio_setpin(S3C2410_GPF(1), 1);
+       s3c_gpio_cfgpin(S3C2410_GPF(1), S3C2410_GPIO_OUTPUT); // CAM_GPIO7 => nLDO_PWRDN
+       s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
+       s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); // CAM_GPIO6 => CAM_PWRDN
+}
+
+static void __init nexcoder_map_io(void)
+{
+       s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
+       s3c24xx_init_clocks(0);
+       s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs));
+
+       nexcoder_sensorboard_init();
+}
+
+static void __init nexcoder_init(void)
+{
+       s3c_i2c0_set_platdata(NULL);
+       platform_add_devices(nexcoder_devices, ARRAY_SIZE(nexcoder_devices));
+};
+
+MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
+       /* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
+       .atag_offset    = 0x100,
+       .map_io         = nexcoder_map_io,
+       .init_machine   = nexcoder_init,
+       .init_irq       = s3c24xx_init_irq,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c244x_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-osiris-dvs.c b/arch/arm/mach-s3c24xx/mach-osiris-dvs.c
new file mode 100644 (file)
index 0000000..ad2792d
--- /dev/null
@@ -0,0 +1,194 @@
+/* linux/arch/arm/mach-s3c2440/mach-osiris-dvs.c
+ *
+ * Copyright (c) 2009 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Simtec Osiris Dynamic Voltage Scaling support.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/cpufreq.h>
+#include <linux/gpio.h>
+
+#include <linux/i2c/tps65010.h>
+
+#include <plat/cpu-freq.h>
+
+#define OSIRIS_GPIO_DVS        S3C2410_GPB(5)
+
+static bool dvs_en;
+
+static void osiris_dvs_tps_setdvs(bool on)
+{
+       unsigned vregs1 = 0, vdcdc2 = 0;
+
+       if (!on) {
+               vdcdc2 = TPS_VCORE_DISCH | TPS_LP_COREOFF;
+               vregs1 = TPS_LDO1_OFF;  /* turn off in low-power mode */
+       }
+
+       dvs_en = on;
+       vdcdc2 |= TPS_VCORE_1_3V | TPS_VCORE_LP_1_0V;
+       vregs1 |= TPS_LDO2_ENABLE | TPS_LDO1_ENABLE;
+
+       tps65010_config_vregs1(vregs1);
+       tps65010_config_vdcdc2(vdcdc2);
+}
+
+static bool is_dvs(struct s3c_freq *f)
+{
+       /* at the moment, we assume ARMCLK = HCLK => DVS */
+       return f->armclk == f->hclk;
+}
+
+/* keep track of current state */
+static bool cur_dvs = false;
+
+static int osiris_dvs_notify(struct notifier_block *nb,
+                             unsigned long val, void *data)
+{
+       struct cpufreq_freqs *cf = data;
+       struct s3c_cpufreq_freqs *freqs = to_s3c_cpufreq(cf);
+       bool old_dvs = is_dvs(&freqs->old);
+       bool new_dvs = is_dvs(&freqs->new);
+       int ret = 0;
+
+       if (!dvs_en)
+               return 0;
+
+       printk(KERN_DEBUG "%s: old %ld,%ld new %ld,%ld\n", __func__,
+              freqs->old.armclk, freqs->old.hclk,
+              freqs->new.armclk, freqs->new.hclk);
+
+       switch (val) {
+       case CPUFREQ_PRECHANGE:
+               if (old_dvs & !new_dvs ||
+                   cur_dvs & !new_dvs) {
+                       pr_debug("%s: exiting dvs\n", __func__);
+                       cur_dvs = false;
+                       gpio_set_value(OSIRIS_GPIO_DVS, 1);
+               }
+               break;
+       case CPUFREQ_POSTCHANGE:
+               if (!old_dvs & new_dvs ||
+                   !cur_dvs & new_dvs) {
+                       pr_debug("entering dvs\n");
+                       cur_dvs = true;
+                       gpio_set_value(OSIRIS_GPIO_DVS, 0);
+               }
+               break;
+       }
+
+       return ret;
+}
+
+static struct notifier_block osiris_dvs_nb = {
+       .notifier_call  = osiris_dvs_notify,
+};
+
+static int __devinit osiris_dvs_probe(struct platform_device *pdev)
+{
+       int ret;
+
+       dev_info(&pdev->dev, "initialising\n");
+
+       ret = gpio_request(OSIRIS_GPIO_DVS, "osiris-dvs");
+       if (ret) {
+               dev_err(&pdev->dev, "cannot claim gpio\n");
+               goto err_nogpio;
+       }
+
+       /* start with dvs disabled */
+       gpio_direction_output(OSIRIS_GPIO_DVS, 1);
+
+       ret = cpufreq_register_notifier(&osiris_dvs_nb,
+                                       CPUFREQ_TRANSITION_NOTIFIER);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register with cpufreq\n");
+               goto err_nofreq;
+       }
+
+       osiris_dvs_tps_setdvs(true);
+
+       return 0;
+
+err_nofreq:
+       gpio_free(OSIRIS_GPIO_DVS);
+
+err_nogpio:
+       return ret;
+}
+
+static int __devexit osiris_dvs_remove(struct platform_device *pdev)
+{
+       dev_info(&pdev->dev, "exiting\n");
+
+       /* disable any current dvs */
+       gpio_set_value(OSIRIS_GPIO_DVS, 1);
+       osiris_dvs_tps_setdvs(false);
+
+       cpufreq_unregister_notifier(&osiris_dvs_nb,
+                                   CPUFREQ_TRANSITION_NOTIFIER);
+
+       gpio_free(OSIRIS_GPIO_DVS);
+
+       return 0;
+}
+
+/* the CONFIG_PM block is so small, it isn't worth actaully compiling it
+ * out if the configuration isn't set. */
+
+static int osiris_dvs_suspend(struct device *dev)
+{
+       gpio_set_value(OSIRIS_GPIO_DVS, 1);
+       osiris_dvs_tps_setdvs(false);
+       cur_dvs = false;
+
+       return 0;
+}
+
+static int osiris_dvs_resume(struct device *dev)
+{
+       osiris_dvs_tps_setdvs(true);
+       return 0;
+}
+
+static const struct dev_pm_ops osiris_dvs_pm = {
+       .suspend        = osiris_dvs_suspend,
+       .resume         = osiris_dvs_resume,
+};
+
+static struct platform_driver osiris_dvs_driver = {
+       .probe          = osiris_dvs_probe,
+       .remove         = __devexit_p(osiris_dvs_remove),
+       .driver         = {
+               .name   = "osiris-dvs",
+               .owner  = THIS_MODULE,
+               .pm     = &osiris_dvs_pm,
+       },
+};
+
+static int __init osiris_dvs_init(void)
+{
+       return platform_driver_register(&osiris_dvs_driver);
+}
+
+static void __exit osiris_dvs_exit(void)
+{
+       platform_driver_unregister(&osiris_dvs_driver);
+}
+
+module_init(osiris_dvs_init);
+module_exit(osiris_dvs_exit);
+
+MODULE_DESCRIPTION("Simtec OSIRIS DVS support");
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:osiris-dvs");
diff --git a/arch/arm/mach-s3c24xx/mach-osiris.c b/arch/arm/mach-s3c24xx/mach-osiris.c
new file mode 100644 (file)
index 0000000..c5daeb6
--- /dev/null
@@ -0,0 +1,440 @@
+/* linux/arch/arm/mach-s3c2440/mach-osiris.c
+ *
+ * Copyright (c) 2005-2008 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/serial_core.h>
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+
+#include <linux/i2c/tps65010.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/osiris-map.h>
+#include <mach/osiris-cpld.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+#include <plat/nand.h>
+#include <plat/iic.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include "common.h"
+
+/* onboard perihperal map */
+
+static struct map_desc osiris_iodesc[] __initdata = {
+  /* ISA IO areas (may be over-written later) */
+
+  {
+         .virtual      = (u32)S3C24XX_VA_ISA_BYTE,
+         .pfn          = __phys_to_pfn(S3C2410_CS5),
+         .length       = SZ_16M,
+         .type         = MT_DEVICE,
+  }, {
+         .virtual      = (u32)S3C24XX_VA_ISA_WORD,
+         .pfn          = __phys_to_pfn(S3C2410_CS5),
+         .length       = SZ_16M,
+         .type         = MT_DEVICE,
+  },
+
+  /* CPLD control registers */
+
+  {
+         .virtual      = (u32)OSIRIS_VA_CTRL0,
+         .pfn          = __phys_to_pfn(OSIRIS_PA_CTRL0),
+         .length       = SZ_16K,
+         .type         = MT_DEVICE,
+  }, {
+         .virtual      = (u32)OSIRIS_VA_CTRL1,
+         .pfn          = __phys_to_pfn(OSIRIS_PA_CTRL1),
+         .length       = SZ_16K,
+         .type         = MT_DEVICE,
+  }, {
+         .virtual      = (u32)OSIRIS_VA_CTRL2,
+         .pfn          = __phys_to_pfn(OSIRIS_PA_CTRL2),
+         .length       = SZ_16K,
+         .type         = MT_DEVICE,
+  }, {
+         .virtual      = (u32)OSIRIS_VA_IDREG,
+         .pfn          = __phys_to_pfn(OSIRIS_PA_IDREG),
+         .length       = SZ_16K,
+         .type         = MT_DEVICE,
+  },
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+               .clk_sel        = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+               .clk_sel        = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
+       },
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+               .clk_sel        = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
+       }
+};
+
+/* NAND Flash on Osiris board */
+
+static int external_map[]   = { 2 };
+static int chip0_map[]      = { 0 };
+static int chip1_map[]      = { 1 };
+
+static struct mtd_partition __initdata osiris_default_nand_part[] = {
+       [0] = {
+               .name   = "Boot Agent",
+               .size   = SZ_16K,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "/boot",
+               .size   = SZ_4M - SZ_16K,
+               .offset = SZ_16K,
+       },
+       [2] = {
+               .name   = "user1",
+               .offset = SZ_4M,
+               .size   = SZ_32M - SZ_4M,
+       },
+       [3] = {
+               .name   = "user2",
+               .offset = SZ_32M,
+               .size   = MTDPART_SIZ_FULL,
+       }
+};
+
+static struct mtd_partition __initdata osiris_default_nand_part_large[] = {
+       [0] = {
+               .name   = "Boot Agent",
+               .size   = SZ_128K,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "/boot",
+               .size   = SZ_4M - SZ_128K,
+               .offset = SZ_128K,
+       },
+       [2] = {
+               .name   = "user1",
+               .offset = SZ_4M,
+               .size   = SZ_32M - SZ_4M,
+       },
+       [3] = {
+               .name   = "user2",
+               .offset = SZ_32M,
+               .size   = MTDPART_SIZ_FULL,
+       }
+};
+
+/* the Osiris has 3 selectable slots for nand-flash, the two
+ * on-board chip areas, as well as the external slot.
+ *
+ * Note, there is no current hot-plug support for the External
+ * socket.
+*/
+
+static struct s3c2410_nand_set __initdata osiris_nand_sets[] = {
+       [1] = {
+               .name           = "External",
+               .nr_chips       = 1,
+               .nr_map         = external_map,
+               .options        = NAND_SCAN_SILENT_NODEV,
+               .nr_partitions  = ARRAY_SIZE(osiris_default_nand_part),
+               .partitions     = osiris_default_nand_part,
+       },
+       [0] = {
+               .name           = "chip0",
+               .nr_chips       = 1,
+               .nr_map         = chip0_map,
+               .nr_partitions  = ARRAY_SIZE(osiris_default_nand_part),
+               .partitions     = osiris_default_nand_part,
+       },
+       [2] = {
+               .name           = "chip1",
+               .nr_chips       = 1,
+               .nr_map         = chip1_map,
+               .options        = NAND_SCAN_SILENT_NODEV,
+               .nr_partitions  = ARRAY_SIZE(osiris_default_nand_part),
+               .partitions     = osiris_default_nand_part,
+       },
+};
+
+static void osiris_nand_select(struct s3c2410_nand_set *set, int slot)
+{
+       unsigned int tmp;
+
+       slot = set->nr_map[slot] & 3;
+
+       pr_debug("osiris_nand: selecting slot %d (set %p,%p)\n",
+                slot, set, set->nr_map);
+
+       tmp = __raw_readb(OSIRIS_VA_CTRL0);
+       tmp &= ~OSIRIS_CTRL0_NANDSEL;
+       tmp |= slot;
+
+       pr_debug("osiris_nand: ctrl0 now %02x\n", tmp);
+
+       __raw_writeb(tmp, OSIRIS_VA_CTRL0);
+}
+
+static struct s3c2410_platform_nand __initdata osiris_nand_info = {
+       .tacls          = 25,
+       .twrph0         = 60,
+       .twrph1         = 60,
+       .nr_sets        = ARRAY_SIZE(osiris_nand_sets),
+       .sets           = osiris_nand_sets,
+       .select_chip    = osiris_nand_select,
+};
+
+/* PCMCIA control and configuration */
+
+static struct resource osiris_pcmcia_resource[] = {
+       [0] = {
+               .start  = 0x0f000000,
+               .end    = 0x0f100000,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = 0x0c000000,
+               .end    = 0x0c100000,
+               .flags  = IORESOURCE_MEM,
+       }
+};
+
+static struct platform_device osiris_pcmcia = {
+       .name           = "osiris-pcmcia",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(osiris_pcmcia_resource),
+       .resource       = osiris_pcmcia_resource,
+};
+
+/* Osiris power management device */
+
+#ifdef CONFIG_PM
+static unsigned char pm_osiris_ctrl0;
+
+static int osiris_pm_suspend(void)
+{
+       unsigned int tmp;
+
+       pm_osiris_ctrl0 = __raw_readb(OSIRIS_VA_CTRL0);
+       tmp = pm_osiris_ctrl0 & ~OSIRIS_CTRL0_NANDSEL;
+
+       /* ensure correct NAND slot is selected on resume */
+       if ((pm_osiris_ctrl0 & OSIRIS_CTRL0_BOOT_INT) == 0)
+               tmp |= 2;
+
+       __raw_writeb(tmp, OSIRIS_VA_CTRL0);
+
+       /* ensure that an nRESET is not generated on resume. */
+       s3c2410_gpio_setpin(S3C2410_GPA(21), 1);
+       s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
+
+       return 0;
+}
+
+static void osiris_pm_resume(void)
+{
+       if (pm_osiris_ctrl0 & OSIRIS_CTRL0_FIX8)
+               __raw_writeb(OSIRIS_CTRL1_FIX8, OSIRIS_VA_CTRL1);
+
+       __raw_writeb(pm_osiris_ctrl0, OSIRIS_VA_CTRL0);
+
+       s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
+}
+
+#else
+#define osiris_pm_suspend NULL
+#define osiris_pm_resume NULL
+#endif
+
+static struct syscore_ops osiris_pm_syscore_ops = {
+       .suspend        = osiris_pm_suspend,
+       .resume         = osiris_pm_resume,
+};
+
+/* Link for DVS driver to TPS65011 */
+
+static void osiris_tps_release(struct device *dev)
+{
+       /* static device, do not need to release anything */
+}
+
+static struct platform_device osiris_tps_device = {
+       .name   = "osiris-dvs",
+       .id     = -1,
+       .dev.release = osiris_tps_release,
+};
+
+static int osiris_tps_setup(struct i2c_client *client, void *context)
+{
+       osiris_tps_device.dev.parent = &client->dev;
+       return platform_device_register(&osiris_tps_device);
+}
+
+static int osiris_tps_remove(struct i2c_client *client, void *context)
+{
+       platform_device_unregister(&osiris_tps_device);
+       return 0;
+}
+
+static struct tps65010_board osiris_tps_board = {
+       .base           = -1,   /* GPIO can go anywhere at the moment */
+       .setup          = osiris_tps_setup,
+       .teardown       = osiris_tps_remove,
+};
+
+/* I2C devices fitted. */
+
+static struct i2c_board_info osiris_i2c_devs[] __initdata = {
+       {
+               I2C_BOARD_INFO("tps65011", 0x48),
+               .irq    = IRQ_EINT20,
+               .platform_data = &osiris_tps_board,
+       },
+};
+
+/* Standard Osiris devices */
+
+static struct platform_device *osiris_devices[] __initdata = {
+       &s3c_device_i2c0,
+       &s3c_device_wdt,
+       &s3c_device_nand,
+       &osiris_pcmcia,
+};
+
+static struct clk *osiris_clocks[] __initdata = {
+       &s3c24xx_dclk0,
+       &s3c24xx_dclk1,
+       &s3c24xx_clkout0,
+       &s3c24xx_clkout1,
+       &s3c24xx_uclk,
+};
+
+static struct s3c_cpufreq_board __initdata osiris_cpufreq = {
+       .refresh        = 7800, /* refresh period is 7.8usec */
+       .auto_io        = 1,
+       .need_io        = 1,
+};
+
+static void __init osiris_map_io(void)
+{
+       unsigned long flags;
+
+       /* initialise the clocks */
+
+       s3c24xx_dclk0.parent = &clk_upll;
+       s3c24xx_dclk0.rate   = 12*1000*1000;
+
+       s3c24xx_dclk1.parent = &clk_upll;
+       s3c24xx_dclk1.rate   = 24*1000*1000;
+
+       s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
+       s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
+
+       s3c24xx_uclk.parent  = &s3c24xx_clkout1;
+
+       s3c24xx_register_clocks(osiris_clocks, ARRAY_SIZE(osiris_clocks));
+
+       s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc));
+       s3c24xx_init_clocks(0);
+       s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
+
+       /* check for the newer revision boards with large page nand */
+
+       if ((__raw_readb(OSIRIS_VA_IDREG) & OSIRIS_ID_REVMASK) >= 4) {
+               printk(KERN_INFO "OSIRIS-B detected (revision %d)\n",
+                      __raw_readb(OSIRIS_VA_IDREG) & OSIRIS_ID_REVMASK);
+               osiris_nand_sets[0].partitions = osiris_default_nand_part_large;
+               osiris_nand_sets[0].nr_partitions = ARRAY_SIZE(osiris_default_nand_part_large);
+       } else {
+               /* write-protect line to the NAND */
+               s3c2410_gpio_setpin(S3C2410_GPA(0), 1);
+       }
+
+       /* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */
+
+       local_irq_save(flags);
+       __raw_writel(__raw_readl(S3C2410_BWSCON) | S3C2410_BWSCON_ST1 | S3C2410_BWSCON_ST2 | S3C2410_BWSCON_ST3 | S3C2410_BWSCON_ST4 | S3C2410_BWSCON_ST5, S3C2410_BWSCON);
+       local_irq_restore(flags);
+}
+
+static void __init osiris_init(void)
+{
+       register_syscore_ops(&osiris_pm_syscore_ops);
+
+       s3c_i2c0_set_platdata(NULL);
+       s3c_nand_set_platdata(&osiris_nand_info);
+
+       s3c_cpufreq_setboard(&osiris_cpufreq);
+
+       i2c_register_board_info(0, osiris_i2c_devs,
+                               ARRAY_SIZE(osiris_i2c_devs));
+
+       platform_add_devices(osiris_devices, ARRAY_SIZE(osiris_devices));
+};
+
+MACHINE_START(OSIRIS, "Simtec-OSIRIS")
+       /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
+       .atag_offset    = 0x100,
+       .map_io         = osiris_map_io,
+       .init_irq       = s3c24xx_init_irq,
+       .init_machine   = osiris_init,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c244x_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-otom.c b/arch/arm/mach-s3c24xx/mach-otom.c
new file mode 100644 (file)
index 0000000..5f1e0ee
--- /dev/null
@@ -0,0 +1,127 @@
+/* linux/arch/arm/mach-s3c2410/mach-otom.c
+ *
+ * Copyright (c) 2004 Nex Vision
+ *   Guillaume GOURAT <guillaume.gourat@nexvision.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/otom-map.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/s3c2410.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/iic.h>
+#include <plat/cpu.h>
+
+#include "common.h"
+
+static struct map_desc otom11_iodesc[] __initdata = {
+  /* Device area */
+       { (u32)OTOM_VA_CS8900A_BASE, OTOM_PA_CS8900A_BASE, SZ_16M, MT_DEVICE },
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg otom11_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       /* port 2 is not actually used */
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       }
+};
+
+/* NOR Flash on NexVision OTOM board */
+
+static struct resource otom_nor_resource[] = {
+       [0] = {
+               .start = S3C2410_CS0,
+               .end   = S3C2410_CS0 + (4*1024*1024) - 1,
+               .flags = IORESOURCE_MEM,
+       }
+};
+
+static struct platform_device otom_device_nor = {
+       .name           = "mtd-flash",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(otom_nor_resource),
+       .resource       = otom_nor_resource,
+};
+
+/* Standard OTOM devices */
+
+static struct platform_device *otom11_devices[] __initdata = {
+       &s3c_device_ohci,
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_iis,
+       &s3c_device_rtc,
+       &otom_device_nor,
+};
+
+static void __init otom11_map_io(void)
+{
+       s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc));
+       s3c24xx_init_clocks(0);
+       s3c24xx_init_uarts(otom11_uartcfgs, ARRAY_SIZE(otom11_uartcfgs));
+}
+
+static void __init otom11_init(void)
+{
+       s3c_i2c0_set_platdata(NULL);
+       platform_add_devices(otom11_devices, ARRAY_SIZE(otom11_devices));
+}
+
+MACHINE_START(OTOM, "Nex Vision - Otom 1.1")
+       /* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
+       .atag_offset    = 0x100,
+       .map_io         = otom11_map_io,
+       .init_machine   = otom11_init,
+       .init_irq       = s3c24xx_init_irq,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c2410_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-qt2410.c b/arch/arm/mach-s3c24xx/mach-qt2410.c
new file mode 100644 (file)
index 0000000..91c16d9
--- /dev/null
@@ -0,0 +1,356 @@
+/* linux/arch/arm/mach-s3c2410/mach-qt2410.c
+ *
+ * Copyright (C) 2006 by OpenMoko, Inc.
+ * Author: Harald Welte <laforge@openmoko.org>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/leds-gpio.h>
+#include <mach/regs-lcd.h>
+#include <plat/regs-serial.h>
+#include <mach/fb.h>
+#include <plat/nand.h>
+#include <plat/udc.h>
+#include <plat/iic.h>
+
+#include <plat/common-smdk.h>
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include "common.h"
+
+static struct map_desc qt2410_iodesc[] __initdata = {
+       { 0xe0000000, __phys_to_pfn(S3C2410_CS3+0x01000000), SZ_1M, MT_DEVICE }
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       }
+};
+
+/* LCD driver info */
+
+static struct s3c2410fb_display qt2410_lcd_cfg[] __initdata = {
+       {
+               /* Configuration for 640x480 SHARP LQ080V3DG01 */
+               .lcdcon5 = S3C2410_LCDCON5_FRM565 |
+                          S3C2410_LCDCON5_INVVLINE |
+                          S3C2410_LCDCON5_INVVFRAME |
+                          S3C2410_LCDCON5_PWREN |
+                          S3C2410_LCDCON5_HWSWP,
+
+               .type           = S3C2410_LCDCON1_TFT,
+               .width          = 640,
+               .height         = 480,
+
+               .pixclock       = 40000, /* HCLK/4 */
+               .xres           = 640,
+               .yres           = 480,
+               .bpp            = 16,
+               .left_margin    = 44,
+               .right_margin   = 116,
+               .hsync_len      = 96,
+               .upper_margin   = 19,
+               .lower_margin   = 11,
+               .vsync_len      = 15,
+       },
+       {
+               /* Configuration for 480x640 toppoly TD028TTEC1 */
+               .lcdcon5 = S3C2410_LCDCON5_FRM565 |
+                          S3C2410_LCDCON5_INVVLINE |
+                          S3C2410_LCDCON5_INVVFRAME |
+                          S3C2410_LCDCON5_PWREN |
+                          S3C2410_LCDCON5_HWSWP,
+
+               .type           = S3C2410_LCDCON1_TFT,
+               .width          = 480,
+               .height         = 640,
+               .pixclock       = 40000, /* HCLK/4 */
+               .xres           = 480,
+               .yres           = 640,
+               .bpp            = 16,
+               .left_margin    = 8,
+               .right_margin   = 24,
+               .hsync_len      = 8,
+               .upper_margin   = 2,
+               .lower_margin   = 4,
+               .vsync_len      = 2,
+       },
+       {
+               /* Config for 240x320 LCD */
+               .lcdcon5 = S3C2410_LCDCON5_FRM565 |
+                          S3C2410_LCDCON5_INVVLINE |
+                          S3C2410_LCDCON5_INVVFRAME |
+                          S3C2410_LCDCON5_PWREN |
+                          S3C2410_LCDCON5_HWSWP,
+
+               .type           = S3C2410_LCDCON1_TFT,
+               .width          = 240,
+               .height         = 320,
+               .pixclock       = 100000, /* HCLK/10 */
+               .xres           = 240,
+               .yres           = 320,
+               .bpp            = 16,
+               .left_margin    = 13,
+               .right_margin   = 8,
+               .hsync_len      = 4,
+               .upper_margin   = 2,
+               .lower_margin   = 7,
+               .vsync_len      = 4,
+       },
+};
+
+
+static struct s3c2410fb_mach_info qt2410_fb_info __initdata = {
+       .displays       = qt2410_lcd_cfg,
+       .num_displays   = ARRAY_SIZE(qt2410_lcd_cfg),
+       .default_display = 0,
+
+       .lpcsel         = ((0xCE6) & ~7) | 1<<4,
+};
+
+/* CS8900 */
+
+static struct resource qt2410_cs89x0_resources[] = {
+       [0] = {
+               .start  = 0x19000000,
+               .end    = 0x19000000 + 16,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_EINT9,
+               .end    = IRQ_EINT9,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device qt2410_cs89x0 = {
+       .name           = "cirrus-cs89x0",
+       .num_resources  = ARRAY_SIZE(qt2410_cs89x0_resources),
+       .resource       = qt2410_cs89x0_resources,
+};
+
+/* LED */
+
+static struct s3c24xx_led_platdata qt2410_pdata_led = {
+       .gpio           = S3C2410_GPB(0),
+       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+       .name           = "led",
+       .def_trigger    = "timer",
+};
+
+static struct platform_device qt2410_led = {
+       .name           = "s3c24xx_led",
+       .id             = 0,
+       .dev            = {
+               .platform_data = &qt2410_pdata_led,
+       },
+};
+
+/* SPI */
+
+static struct spi_gpio_platform_data spi_gpio_cfg = {
+       .sck            = S3C2410_GPG(7),
+       .mosi           = S3C2410_GPG(6),
+       .miso           = S3C2410_GPG(5),
+};
+
+static struct platform_device qt2410_spi = {
+       .name           = "spi-gpio",
+       .id             = 1,
+       .dev.platform_data = &spi_gpio_cfg,
+};
+
+/* Board devices */
+
+static struct platform_device *qt2410_devices[] __initdata = {
+       &s3c_device_ohci,
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_iis,
+       &s3c_device_sdi,
+       &s3c_device_usbgadget,
+       &qt2410_spi,
+       &qt2410_cs89x0,
+       &qt2410_led,
+};
+
+static struct mtd_partition __initdata qt2410_nand_part[] = {
+       [0] = {
+               .name   = "U-Boot",
+               .size   = 0x30000,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "U-Boot environment",
+               .offset = 0x30000,
+               .size   = 0x4000,
+       },
+       [2] = {
+               .name   = "kernel",
+               .offset = 0x34000,
+               .size   = SZ_2M,
+       },
+       [3] = {
+               .name   = "initrd",
+               .offset = 0x234000,
+               .size   = SZ_4M,
+       },
+       [4] = {
+               .name   = "jffs2",
+               .offset = 0x634000,
+               .size   = 0x39cc000,
+       },
+};
+
+static struct s3c2410_nand_set __initdata qt2410_nand_sets[] = {
+       [0] = {
+               .name           = "NAND",
+               .nr_chips       = 1,
+               .nr_partitions  = ARRAY_SIZE(qt2410_nand_part),
+               .partitions     = qt2410_nand_part,
+       },
+};
+
+/* choose a set of timings which should suit most 512Mbit
+ * chips and beyond.
+ */
+
+static struct s3c2410_platform_nand __initdata qt2410_nand_info = {
+       .tacls          = 20,
+       .twrph0         = 60,
+       .twrph1         = 20,
+       .nr_sets        = ARRAY_SIZE(qt2410_nand_sets),
+       .sets           = qt2410_nand_sets,
+};
+
+/* UDC */
+
+static struct s3c2410_udc_mach_info qt2410_udc_cfg = {
+};
+
+static char tft_type = 's';
+
+static int __init qt2410_tft_setup(char *str)
+{
+       tft_type = str[0];
+       return 1;
+}
+
+__setup("tft=", qt2410_tft_setup);
+
+static void __init qt2410_map_io(void)
+{
+       s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc));
+       s3c24xx_init_clocks(12*1000*1000);
+       s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
+}
+
+static void __init qt2410_machine_init(void)
+{
+       s3c_nand_set_platdata(&qt2410_nand_info);
+
+       switch (tft_type) {
+       case 'p': /* production */
+               qt2410_fb_info.default_display = 1;
+               break;
+       case 'b': /* big */
+               qt2410_fb_info.default_display = 0;
+               break;
+       case 's': /* small */
+       default:
+               qt2410_fb_info.default_display = 2;
+               break;
+       }
+       s3c24xx_fb_set_platdata(&qt2410_fb_info);
+
+       s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
+       s3c2410_gpio_setpin(S3C2410_GPB(0), 1);
+
+       s3c24xx_udc_set_platdata(&qt2410_udc_cfg);
+       s3c_i2c0_set_platdata(NULL);
+
+       WARN_ON(gpio_request(S3C2410_GPB(5), "spi cs"));
+       gpio_direction_output(S3C2410_GPB(5), 1);
+
+       platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices));
+       s3c_pm_init();
+}
+
+MACHINE_START(QT2410, "QT2410")
+       .atag_offset    = 0x100,
+       .map_io         = qt2410_map_io,
+       .init_irq       = s3c24xx_init_irq,
+       .init_machine   = qt2410_machine_init,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c2410_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c
new file mode 100644 (file)
index 0000000..200debb
--- /dev/null
@@ -0,0 +1,826 @@
+/* linux/arch/arm/mach-s3c2440/mach-rx1950.c
+ *
+ * Copyright (c) 2006-2009 Victor Chukhantsev, Denis Grigoriev,
+ * Copyright (c) 2007-2010 Vasily Khoruzhick
+ *
+ * based on smdk2440 written by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/memblock.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/device.h>
+#include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
+#include <linux/pwm.h>
+#include <linux/s3c_adc_battery.h>
+#include <linux/leds.h>
+#include <linux/i2c.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <linux/mmc/host.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-gpioj.h>
+#include <mach/regs-lcd.h>
+#include <mach/h1940.h>
+#include <mach/fb.h>
+
+#include <plat/clock.h>
+#include <plat/regs-serial.h>
+#include <plat/regs-iic.h>
+#include <plat/mci.h>
+#include <plat/udc.h>
+#include <plat/nand.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+#include <plat/ts.h>
+
+#include <sound/uda1380.h>
+
+#include "common.h"
+
+#define LCD_PWM_PERIOD 192960
+#define LCD_PWM_DUTY 127353
+
+static struct map_desc rx1950_iodesc[] __initdata = {
+};
+
+static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
+       [0] = {
+              .hwport = 0,
+              .flags = 0,
+              .ucon = 0x3c5,
+              .ulcon = 0x03,
+              .ufcon = 0x51,
+               .clk_sel = S3C2410_UCON_CLKSEL3,
+       },
+       [1] = {
+              .hwport = 1,
+              .flags = 0,
+              .ucon = 0x3c5,
+              .ulcon = 0x03,
+              .ufcon = 0x51,
+               .clk_sel = S3C2410_UCON_CLKSEL3,
+       },
+       /* IR port */
+       [2] = {
+              .hwport = 2,
+              .flags = 0,
+              .ucon = 0x3c5,
+              .ulcon = 0x43,
+              .ufcon = 0xf1,
+               .clk_sel = S3C2410_UCON_CLKSEL3,
+       },
+};
+
+static struct s3c2410fb_display rx1950_display = {
+       .type = S3C2410_LCDCON1_TFT,
+       .width = 240,
+       .height = 320,
+       .xres = 240,
+       .yres = 320,
+       .bpp = 16,
+
+       .pixclock = 260000,
+       .left_margin = 10,
+       .right_margin = 20,
+       .hsync_len = 10,
+       .upper_margin = 2,
+       .lower_margin = 2,
+       .vsync_len = 2,
+
+       .lcdcon5 = S3C2410_LCDCON5_FRM565 |
+                          S3C2410_LCDCON5_INVVCLK |
+                          S3C2410_LCDCON5_INVVLINE |
+                          S3C2410_LCDCON5_INVVFRAME |
+                          S3C2410_LCDCON5_HWSWP |
+                          (0x02 << 13) |
+                          (0x02 << 15),
+
+};
+
+static int power_supply_init(struct device *dev)
+{
+       return gpio_request(S3C2410_GPF(2), "cable plugged");
+}
+
+static int rx1950_is_ac_online(void)
+{
+       return !gpio_get_value(S3C2410_GPF(2));
+}
+
+static void power_supply_exit(struct device *dev)
+{
+       gpio_free(S3C2410_GPF(2));
+}
+
+static char *rx1950_supplicants[] = {
+       "main-battery"
+};
+
+static struct pda_power_pdata power_supply_info = {
+       .init                   = power_supply_init,
+       .is_ac_online           = rx1950_is_ac_online,
+       .exit                   = power_supply_exit,
+       .supplied_to            = rx1950_supplicants,
+       .num_supplicants        = ARRAY_SIZE(rx1950_supplicants),
+};
+
+static struct resource power_supply_resources[] = {
+       [0] = {
+                       .name   = "ac",
+                       .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE |
+                                         IORESOURCE_IRQ_HIGHEDGE,
+                       .start  = IRQ_EINT2,
+                       .end    = IRQ_EINT2,
+       },
+};
+
+static struct platform_device power_supply = {
+       .name                   = "pda-power",
+       .id                     = -1,
+       .dev                    = {
+                                       .platform_data =
+                                               &power_supply_info,
+       },
+       .resource               = power_supply_resources,
+       .num_resources          = ARRAY_SIZE(power_supply_resources),
+};
+
+static const struct s3c_adc_bat_thresh bat_lut_noac[] = {
+       { .volt = 4100, .cur = 156, .level = 100},
+       { .volt = 4050, .cur = 156, .level = 95},
+       { .volt = 4025, .cur = 141, .level = 90},
+       { .volt = 3995, .cur = 144, .level = 85},
+       { .volt = 3957, .cur = 162, .level = 80},
+       { .volt = 3931, .cur = 147, .level = 75},
+       { .volt = 3902, .cur = 147, .level = 70},
+       { .volt = 3863, .cur = 153, .level = 65},
+       { .volt = 3838, .cur = 150, .level = 60},
+       { .volt = 3800, .cur = 153, .level = 55},
+       { .volt = 3765, .cur = 153, .level = 50},
+       { .volt = 3748, .cur = 172, .level = 45},
+       { .volt = 3740, .cur = 153, .level = 40},
+       { .volt = 3714, .cur = 175, .level = 35},
+       { .volt = 3710, .cur = 156, .level = 30},
+       { .volt = 3963, .cur = 156, .level = 25},
+       { .volt = 3672, .cur = 178, .level = 20},
+       { .volt = 3651, .cur = 178, .level = 15},
+       { .volt = 3629, .cur = 178, .level = 10},
+       { .volt = 3612, .cur = 162, .level = 5},
+       { .volt = 3605, .cur = 162, .level = 0},
+};
+
+static const struct s3c_adc_bat_thresh bat_lut_acin[] = {
+       { .volt = 4200, .cur = 0, .level = 100},
+       { .volt = 4190, .cur = 0, .level = 99},
+       { .volt = 4178, .cur = 0, .level = 95},
+       { .volt = 4110, .cur = 0, .level = 70},
+       { .volt = 4076, .cur = 0, .level = 65},
+       { .volt = 4046, .cur = 0, .level = 60},
+       { .volt = 4021, .cur = 0, .level = 55},
+       { .volt = 3999, .cur = 0, .level = 50},
+       { .volt = 3982, .cur = 0, .level = 45},
+       { .volt = 3965, .cur = 0, .level = 40},
+       { .volt = 3957, .cur = 0, .level = 35},
+       { .volt = 3948, .cur = 0, .level = 30},
+       { .volt = 3936, .cur = 0, .level = 25},
+       { .volt = 3927, .cur = 0, .level = 20},
+       { .volt = 3906, .cur = 0, .level = 15},
+       { .volt = 3880, .cur = 0, .level = 10},
+       { .volt = 3829, .cur = 0, .level = 5},
+       { .volt = 3820, .cur = 0, .level = 0},
+};
+
+static int rx1950_bat_init(void)
+{
+       int ret;
+
+       ret = gpio_request(S3C2410_GPJ(2), "rx1950-charger-enable-1");
+       if (ret)
+               goto err_gpio1;
+       ret = gpio_request(S3C2410_GPJ(3), "rx1950-charger-enable-2");
+       if (ret)
+               goto err_gpio2;
+
+       return 0;
+
+err_gpio2:
+       gpio_free(S3C2410_GPJ(2));
+err_gpio1:
+       return ret;
+}
+
+static void rx1950_bat_exit(void)
+{
+       gpio_free(S3C2410_GPJ(2));
+       gpio_free(S3C2410_GPJ(3));
+}
+
+static void rx1950_enable_charger(void)
+{
+       gpio_direction_output(S3C2410_GPJ(2), 1);
+       gpio_direction_output(S3C2410_GPJ(3), 1);
+}
+
+static void rx1950_disable_charger(void)
+{
+       gpio_direction_output(S3C2410_GPJ(2), 0);
+       gpio_direction_output(S3C2410_GPJ(3), 0);
+}
+
+static DEFINE_SPINLOCK(rx1950_blink_spin);
+
+static int rx1950_led_blink_set(unsigned gpio, int state,
+       unsigned long *delay_on, unsigned long *delay_off)
+{
+       int blink_gpio, check_gpio;
+
+       switch (gpio) {
+       case S3C2410_GPA(6):
+               blink_gpio = S3C2410_GPA(4);
+               check_gpio = S3C2410_GPA(3);
+               break;
+       case S3C2410_GPA(7):
+               blink_gpio = S3C2410_GPA(3);
+               check_gpio = S3C2410_GPA(4);
+               break;
+       default:
+               return -EINVAL;
+               break;
+       }
+
+       if (delay_on && delay_off && !*delay_on && !*delay_off)
+               *delay_on = *delay_off = 500;
+
+       spin_lock(&rx1950_blink_spin);
+
+       switch (state) {
+       case GPIO_LED_NO_BLINK_LOW:
+       case GPIO_LED_NO_BLINK_HIGH:
+               if (!gpio_get_value(check_gpio))
+                       gpio_set_value(S3C2410_GPJ(6), 0);
+               gpio_set_value(blink_gpio, 0);
+               gpio_set_value(gpio, state);
+               break;
+       case GPIO_LED_BLINK:
+               gpio_set_value(gpio, 0);
+               gpio_set_value(S3C2410_GPJ(6), 1);
+               gpio_set_value(blink_gpio, 1);
+               break;
+       }
+
+       spin_unlock(&rx1950_blink_spin);
+
+       return 0;
+}
+
+static struct gpio_led rx1950_leds_desc[] = {
+       {
+               .name                   = "Green",
+               .default_trigger        = "main-battery-full",
+               .gpio                   = S3C2410_GPA(6),
+               .retain_state_suspended = 1,
+       },
+       {
+               .name                   = "Red",
+               .default_trigger
+                       = "main-battery-charging-blink-full-solid",
+               .gpio                   = S3C2410_GPA(7),
+               .retain_state_suspended = 1,
+       },
+       {
+               .name                   = "Blue",
+               .default_trigger        = "rx1950-acx-mem",
+               .gpio                   = S3C2410_GPA(11),
+               .retain_state_suspended = 1,
+       },
+};
+
+static struct gpio_led_platform_data rx1950_leds_pdata = {
+       .num_leds       = ARRAY_SIZE(rx1950_leds_desc),
+       .leds           = rx1950_leds_desc,
+       .gpio_blink_set = rx1950_led_blink_set,
+};
+
+static struct platform_device rx1950_leds = {
+       .name   = "leds-gpio",
+       .id             = -1,
+       .dev    = {
+                               .platform_data = &rx1950_leds_pdata,
+       },
+};
+
+static struct s3c_adc_bat_pdata rx1950_bat_cfg = {
+       .init = rx1950_bat_init,
+       .exit = rx1950_bat_exit,
+       .enable_charger = rx1950_enable_charger,
+       .disable_charger = rx1950_disable_charger,
+       .gpio_charge_finished = S3C2410_GPF(3),
+       .lut_noac = bat_lut_noac,
+       .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac),
+       .lut_acin = bat_lut_acin,
+       .lut_acin_cnt = ARRAY_SIZE(bat_lut_acin),
+       .volt_channel = 0,
+       .current_channel = 1,
+       .volt_mult = 4235,
+       .current_mult = 2900,
+       .internal_impedance = 200,
+};
+
+static struct platform_device rx1950_battery = {
+       .name             = "s3c-adc-battery",
+       .id               = -1,
+       .dev = {
+               .parent = &s3c_device_adc.dev,
+               .platform_data = &rx1950_bat_cfg,
+       },
+};
+
+static struct s3c2410fb_mach_info rx1950_lcd_cfg = {
+       .displays = &rx1950_display,
+       .num_displays = 1,
+       .default_display = 0,
+
+       .lpcsel = 0x02,
+       .gpccon = 0xaa9556a9,
+       .gpccon_mask = 0xffc003fc,
+       .gpcup = 0x0000ffff,
+       .gpcup_mask = 0xffffffff,
+
+       .gpdcon = 0xaa90aaa1,
+       .gpdcon_mask = 0xffc0fff0,
+       .gpdup = 0x0000fcfd,
+       .gpdup_mask = 0xffffffff,
+
+};
+
+static struct pwm_device *lcd_pwm;
+
+static void rx1950_lcd_power(int enable)
+{
+       int i;
+       static int enabled;
+       if (enabled == enable)
+               return;
+       if (!enable) {
+
+               /* GPC11-GPC15->OUTPUT */
+               for (i = 11; i < 16; i++)
+                       gpio_direction_output(S3C2410_GPC(i), 1);
+
+               /* Wait a bit here... */
+               mdelay(100);
+
+               /* GPD2-GPD7->OUTPUT */
+               /* GPD11-GPD15->OUTPUT */
+               /* GPD2-GPD7->1, GPD11-GPD15->1 */
+               for (i = 2; i < 8; i++)
+                       gpio_direction_output(S3C2410_GPD(i), 1);
+               for (i = 11; i < 16; i++)
+                       gpio_direction_output(S3C2410_GPD(i), 1);
+
+               /* Wait a bit here...*/
+               mdelay(100);
+
+               /* GPB0->OUTPUT, GPB0->0 */
+               gpio_direction_output(S3C2410_GPB(0), 0);
+
+               /* GPC1-GPC4->OUTPUT, GPC1-4->0 */
+               for (i = 1; i < 5; i++)
+                       gpio_direction_output(S3C2410_GPC(i), 0);
+
+               /* GPC15-GPC11->0 */
+               for (i = 11; i < 16; i++)
+                       gpio_direction_output(S3C2410_GPC(i), 0);
+
+               /* GPD15-GPD11->0, GPD2->GPD7->0 */
+               for (i = 11; i < 16; i++)
+                       gpio_direction_output(S3C2410_GPD(i), 0);
+
+               for (i = 2; i < 8; i++)
+                       gpio_direction_output(S3C2410_GPD(i), 0);
+
+               /* GPC6->0, GPC7->0, GPC5->0 */
+               gpio_direction_output(S3C2410_GPC(6), 0);
+               gpio_direction_output(S3C2410_GPC(7), 0);
+               gpio_direction_output(S3C2410_GPC(5), 0);
+
+               /* GPB1->OUTPUT, GPB1->0 */
+               gpio_direction_output(S3C2410_GPB(1), 0);
+               pwm_config(lcd_pwm, 0, LCD_PWM_PERIOD);
+               pwm_disable(lcd_pwm);
+
+               /* GPC0->0, GPC10->0 */
+               gpio_direction_output(S3C2410_GPC(0), 0);
+               gpio_direction_output(S3C2410_GPC(10), 0);
+       } else {
+               pwm_config(lcd_pwm, LCD_PWM_DUTY, LCD_PWM_PERIOD);
+               pwm_enable(lcd_pwm);
+
+               gpio_direction_output(S3C2410_GPC(0), 1);
+               gpio_direction_output(S3C2410_GPC(5), 1);
+
+               s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPB1_TOUT1);
+               gpio_direction_output(S3C2410_GPC(7), 1);
+
+               for (i = 1; i < 5; i++)
+                       s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2));
+
+               for (i = 11; i < 16; i++)
+                       s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2));
+
+               for (i = 2; i < 8; i++)
+                       s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2));
+
+               for (i = 11; i < 16; i++)
+                       s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2));
+
+               gpio_direction_output(S3C2410_GPC(10), 1);
+               gpio_direction_output(S3C2410_GPC(6), 1);
+       }
+       enabled = enable;
+}
+
+static void rx1950_bl_power(int enable)
+{
+       static int enabled;
+       if (enabled == enable)
+               return;
+       if (!enable) {
+                       gpio_direction_output(S3C2410_GPB(0), 0);
+       } else {
+                       /* LED driver need a "push" to power on */
+                       gpio_direction_output(S3C2410_GPB(0), 1);
+                       /* Warm up backlight for one period of PWM.
+                        * Without this trick its almost impossible to
+                        * enable backlight with low brightness value
+                        */
+                       ndelay(48000);
+                       s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+       }
+       enabled = enable;
+}
+
+static int rx1950_backlight_init(struct device *dev)
+{
+       WARN_ON(gpio_request(S3C2410_GPB(0), "Backlight"));
+       lcd_pwm = pwm_request(1, "RX1950 LCD");
+       if (IS_ERR(lcd_pwm)) {
+               dev_err(dev, "Unable to request PWM for LCD power!\n");
+               return PTR_ERR(lcd_pwm);
+       }
+
+       rx1950_lcd_power(1);
+       rx1950_bl_power(1);
+
+       return 0;
+}
+
+static void rx1950_backlight_exit(struct device *dev)
+{
+       rx1950_bl_power(0);
+       rx1950_lcd_power(0);
+
+       pwm_free(lcd_pwm);
+       gpio_free(S3C2410_GPB(0));
+}
+
+
+static int rx1950_backlight_notify(struct device *dev, int brightness)
+{
+       if (!brightness) {
+               rx1950_bl_power(0);
+               rx1950_lcd_power(0);
+       } else {
+               rx1950_lcd_power(1);
+               rx1950_bl_power(1);
+       }
+       return brightness;
+}
+
+static struct platform_pwm_backlight_data rx1950_backlight_data = {
+       .pwm_id = 0,
+       .max_brightness = 24,
+       .dft_brightness = 4,
+       .pwm_period_ns = 48000,
+       .init = rx1950_backlight_init,
+       .notify = rx1950_backlight_notify,
+       .exit = rx1950_backlight_exit,
+};
+
+static struct platform_device rx1950_backlight = {
+       .name = "pwm-backlight",
+       .dev = {
+               .parent = &s3c_device_timer[0].dev,
+               .platform_data = &rx1950_backlight_data,
+       },
+};
+
+static void rx1950_set_mmc_power(unsigned char power_mode, unsigned short vdd)
+{
+       switch (power_mode) {
+       case MMC_POWER_OFF:
+               gpio_direction_output(S3C2410_GPJ(1), 0);
+               break;
+       case MMC_POWER_UP:
+       case MMC_POWER_ON:
+               gpio_direction_output(S3C2410_GPJ(1), 1);
+               break;
+       default:
+               break;
+       }
+}
+
+static struct s3c24xx_mci_pdata rx1950_mmc_cfg __initdata = {
+       .gpio_detect = S3C2410_GPF(5),
+       .gpio_wprotect = S3C2410_GPH(8),
+       .set_power = rx1950_set_mmc_power,
+       .ocr_avail = MMC_VDD_32_33,
+};
+
+static struct mtd_partition rx1950_nand_part[] = {
+       [0] = {
+                       .name = "Boot0",
+                       .offset = 0,
+                       .size = 0x4000,
+                       .mask_flags = MTD_WRITEABLE,
+       },
+       [1] = {
+                       .name = "Boot1",
+                       .offset = MTDPART_OFS_APPEND,
+                       .size = 0x40000,
+                       .mask_flags = MTD_WRITEABLE,
+       },
+       [2] = {
+                       .name = "Kernel",
+                       .offset = MTDPART_OFS_APPEND,
+                       .size = 0x300000,
+                       .mask_flags = 0,
+       },
+       [3] = {
+                       .name = "Filesystem",
+                       .offset = MTDPART_OFS_APPEND,
+                       .size = MTDPART_SIZ_FULL,
+                       .mask_flags = 0,
+       },
+};
+
+static struct s3c2410_nand_set rx1950_nand_sets[] = {
+       [0] = {
+                       .name = "Internal",
+                       .nr_chips = 1,
+                       .nr_partitions = ARRAY_SIZE(rx1950_nand_part),
+                       .partitions = rx1950_nand_part,
+       },
+};
+
+static struct s3c2410_platform_nand rx1950_nand_info = {
+       .tacls = 25,
+       .twrph0 = 50,
+       .twrph1 = 15,
+       .nr_sets = ARRAY_SIZE(rx1950_nand_sets),
+       .sets = rx1950_nand_sets,
+};
+
+static struct s3c2410_udc_mach_info rx1950_udc_cfg __initdata = {
+       .vbus_pin = S3C2410_GPG(5),
+       .vbus_pin_inverted = 1,
+       .pullup_pin = S3C2410_GPJ(5),
+};
+
+static struct s3c2410_ts_mach_info rx1950_ts_cfg __initdata = {
+       .delay = 10000,
+       .presc = 49,
+       .oversampling_shift = 3,
+};
+
+static struct gpio_keys_button rx1950_gpio_keys_table[] = {
+       {
+               .code           = KEY_POWER,
+               .gpio           = S3C2410_GPF(0),
+               .active_low     = 1,
+               .desc           = "Power button",
+               .wakeup         = 1,
+       },
+       {
+               .code           = KEY_F5,
+               .gpio           = S3C2410_GPF(7),
+               .active_low     = 1,
+               .desc           = "Record button",
+       },
+       {
+               .code           = KEY_F1,
+               .gpio           = S3C2410_GPG(0),
+               .active_low     = 1,
+               .desc           = "Calendar button",
+       },
+       {
+               .code           = KEY_F2,
+               .gpio           = S3C2410_GPG(2),
+               .active_low     = 1,
+               .desc           = "Contacts button",
+       },
+       {
+               .code           = KEY_F3,
+               .gpio           = S3C2410_GPG(3),
+               .active_low     = 1,
+               .desc           = "Mail button",
+       },
+       {
+               .code           = KEY_F4,
+               .gpio           = S3C2410_GPG(7),
+               .active_low     = 1,
+               .desc           = "WLAN button",
+       },
+       {
+               .code           = KEY_LEFT,
+               .gpio           = S3C2410_GPG(10),
+               .active_low     = 1,
+               .desc           = "Left button",
+       },
+       {
+               .code           = KEY_RIGHT,
+               .gpio           = S3C2410_GPG(11),
+               .active_low     = 1,
+               .desc           = "Right button",
+       },
+       {
+               .code           = KEY_UP,
+               .gpio           = S3C2410_GPG(4),
+               .active_low     = 1,
+               .desc           = "Up button",
+       },
+       {
+               .code           = KEY_DOWN,
+               .gpio           = S3C2410_GPG(6),
+               .active_low     = 1,
+               .desc           = "Down button",
+       },
+       {
+               .code           = KEY_ENTER,
+               .gpio           = S3C2410_GPG(9),
+               .active_low     = 1,
+               .desc           = "Ok button"
+       },
+};
+
+static struct gpio_keys_platform_data rx1950_gpio_keys_data = {
+       .buttons = rx1950_gpio_keys_table,
+       .nbuttons = ARRAY_SIZE(rx1950_gpio_keys_table),
+};
+
+static struct platform_device rx1950_device_gpiokeys = {
+       .name = "gpio-keys",
+       .dev.platform_data = &rx1950_gpio_keys_data,
+};
+
+static struct uda1380_platform_data uda1380_info = {
+       .gpio_power     = S3C2410_GPJ(0),
+       .gpio_reset     = S3C2410_GPD(0),
+       .dac_clk        = UDA1380_DAC_CLK_SYSCLK,
+};
+
+static struct i2c_board_info rx1950_i2c_devices[] = {
+       {
+               I2C_BOARD_INFO("uda1380", 0x1a),
+               .platform_data = &uda1380_info,
+       },
+};
+
+static struct platform_device *rx1950_devices[] __initdata = {
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_iis,
+       &samsung_asoc_dma,
+       &s3c_device_usbgadget,
+       &s3c_device_rtc,
+       &s3c_device_nand,
+       &s3c_device_sdi,
+       &s3c_device_adc,
+       &s3c_device_ts,
+       &s3c_device_timer[0],
+       &s3c_device_timer[1],
+       &rx1950_backlight,
+       &rx1950_device_gpiokeys,
+       &power_supply,
+       &rx1950_battery,
+       &rx1950_leds,
+};
+
+static struct clk *rx1950_clocks[] __initdata = {
+       &s3c24xx_clkout0,
+       &s3c24xx_clkout1,
+};
+
+static void __init rx1950_map_io(void)
+{
+       s3c24xx_clkout0.parent  = &clk_h;
+       s3c24xx_clkout1.parent  = &clk_f;
+
+       s3c24xx_register_clocks(rx1950_clocks, ARRAY_SIZE(rx1950_clocks));
+
+       s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc));
+       s3c24xx_init_clocks(16934000);
+       s3c24xx_init_uarts(rx1950_uartcfgs, ARRAY_SIZE(rx1950_uartcfgs));
+
+       /* setup PM */
+
+#ifdef CONFIG_PM_H1940
+       memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 8);
+#endif
+
+       s3c_pm_init();
+}
+
+static void __init rx1950_init_machine(void)
+{
+       int i;
+
+       s3c24xx_fb_set_platdata(&rx1950_lcd_cfg);
+       s3c24xx_udc_set_platdata(&rx1950_udc_cfg);
+       s3c24xx_ts_set_platdata(&rx1950_ts_cfg);
+       s3c24xx_mci_set_platdata(&rx1950_mmc_cfg);
+       s3c_i2c0_set_platdata(NULL);
+       s3c_nand_set_platdata(&rx1950_nand_info);
+
+       /* Turn off suspend on both USB ports, and switch the
+        * selectable USB port to USB device mode. */
+       s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+                                               S3C2410_MISCCR_USBSUSPND0 |
+                                               S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+       /* mmc power is disabled by default */
+       WARN_ON(gpio_request(S3C2410_GPJ(1), "MMC power"));
+       gpio_direction_output(S3C2410_GPJ(1), 0);
+
+       for (i = 0; i < 8; i++)
+               WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power"));
+
+       for (i = 10; i < 16; i++)
+               WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power"));
+
+       for (i = 2; i < 8; i++)
+               WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power"));
+
+       for (i = 11; i < 16; i++)
+               WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power"));
+
+       WARN_ON(gpio_request(S3C2410_GPB(1), "LCD power"));
+
+       WARN_ON(gpio_request(S3C2410_GPA(3), "Red blink"));
+       WARN_ON(gpio_request(S3C2410_GPA(4), "Green blink"));
+       WARN_ON(gpio_request(S3C2410_GPJ(6), "LED blink"));
+       gpio_direction_output(S3C2410_GPA(3), 0);
+       gpio_direction_output(S3C2410_GPA(4), 0);
+       gpio_direction_output(S3C2410_GPJ(6), 0);
+
+       platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices));
+
+       i2c_register_board_info(0, rx1950_i2c_devices,
+               ARRAY_SIZE(rx1950_i2c_devices));
+}
+
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init rx1950_reserve(void)
+{
+       memblock_reserve(0x30003000, 0x1000);
+       memblock_reserve(0x30081000, 0x1000);
+}
+
+MACHINE_START(RX1950, "HP iPAQ RX1950")
+    /* Maintainers: Vasily Khoruzhick */
+       .atag_offset = 0x100,
+       .map_io = rx1950_map_io,
+       .reserve        = rx1950_reserve,
+       .init_irq = s3c24xx_init_irq,
+       .init_machine = rx1950_init_machine,
+       .timer = &s3c24xx_timer,
+       .restart        = s3c244x_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-rx3715.c b/arch/arm/mach-s3c24xx/mach-rx3715.c
new file mode 100644 (file)
index 0000000..56af354
--- /dev/null
@@ -0,0 +1,217 @@
+/* linux/arch/arm/mach-s3c2440/mach-rx3715.c
+ *
+ * Copyright (c) 2003-2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.handhelds.org/projects/rx3715.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/memblock.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+#include <linux/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/h1940.h>
+#include <plat/nand.h>
+#include <mach/fb.h>
+
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include "common.h"
+
+static struct map_desc rx3715_iodesc[] __initdata = {
+       /* dump ISA space somewhere unused */
+
+       {
+               .virtual        = (u32)S3C24XX_VA_ISA_WORD,
+               .pfn            = __phys_to_pfn(S3C2410_CS3),
+               .length         = SZ_1M,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
+               .pfn            = __phys_to_pfn(S3C2410_CS3),
+               .length         = SZ_1M,
+               .type           = MT_DEVICE,
+       },
+};
+
+static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+               .clk_sel        = S3C2410_UCON_CLKSEL3,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x00,
+               .clk_sel        = S3C2410_UCON_CLKSEL3,
+       },
+       /* IR port */
+       [2] = {
+               .hwport      = 2,
+               .uart_flags  = UPF_CONS_FLOW,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x43,
+               .ufcon       = 0x51,
+               .clk_sel        = S3C2410_UCON_CLKSEL3,
+       }
+};
+
+/* framebuffer lcd controller information */
+
+static struct s3c2410fb_display rx3715_lcdcfg __initdata = {
+       .lcdcon5 =      S3C2410_LCDCON5_INVVLINE |
+                       S3C2410_LCDCON5_FRM565 |
+                       S3C2410_LCDCON5_HWSWP,
+
+       .type           = S3C2410_LCDCON1_TFT,
+       .width          = 240,
+       .height         = 320,
+
+       .pixclock       = 260000,
+       .xres           = 240,
+       .yres           = 320,
+       .bpp            = 16,
+       .left_margin    = 36,
+       .right_margin   = 36,
+       .hsync_len      = 8,
+       .upper_margin   = 6,
+       .lower_margin   = 7,
+       .vsync_len      = 3,
+};
+
+static struct s3c2410fb_mach_info rx3715_fb_info __initdata = {
+
+       .displays =     &rx3715_lcdcfg,
+       .num_displays = 1,
+       .default_display = 0,
+
+       .lpcsel =       0xf82,
+
+       .gpccon =       0xaa955699,
+       .gpccon_mask =  0xffc003cc,
+       .gpcup =        0x0000ffff,
+       .gpcup_mask =   0xffffffff,
+
+       .gpdcon =       0xaa95aaa1,
+       .gpdcon_mask =  0xffc0fff0,
+       .gpdup =        0x0000faff,
+       .gpdup_mask =   0xffffffff,
+};
+
+static struct mtd_partition __initdata rx3715_nand_part[] = {
+       [0] = {
+               .name           = "Whole Flash",
+               .offset         = 0,
+               .size           = MTDPART_SIZ_FULL,
+               .mask_flags     = MTD_WRITEABLE,
+       }
+};
+
+static struct s3c2410_nand_set __initdata rx3715_nand_sets[] = {
+       [0] = {
+               .name           = "Internal",
+               .nr_chips       = 1,
+               .nr_partitions  = ARRAY_SIZE(rx3715_nand_part),
+               .partitions     = rx3715_nand_part,
+       },
+};
+
+static struct s3c2410_platform_nand __initdata rx3715_nand_info = {
+       .tacls          = 25,
+       .twrph0         = 50,
+       .twrph1         = 15,
+       .nr_sets        = ARRAY_SIZE(rx3715_nand_sets),
+       .sets           = rx3715_nand_sets,
+};
+
+static struct platform_device *rx3715_devices[] __initdata = {
+       &s3c_device_ohci,
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_iis,
+       &s3c_device_nand,
+};
+
+static void __init rx3715_map_io(void)
+{
+       s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
+       s3c24xx_init_clocks(16934000);
+       s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
+}
+
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init rx3715_reserve(void)
+{
+       memblock_reserve(0x30003000, 0x1000);
+       memblock_reserve(0x30081000, 0x1000);
+}
+
+static void __init rx3715_init_irq(void)
+{
+       s3c24xx_init_irq();
+}
+
+static void __init rx3715_init_machine(void)
+{
+#ifdef CONFIG_PM_H1940
+       memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
+#endif
+       s3c_pm_init();
+
+       s3c_nand_set_platdata(&rx3715_nand_info);
+       s3c24xx_fb_set_platdata(&rx3715_fb_info);
+       platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices));
+}
+
+MACHINE_START(RX3715, "IPAQ-RX3715")
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+       .atag_offset    = 0x100,
+       .map_io         = rx3715_map_io,
+       .reserve        = rx3715_reserve,
+       .init_irq       = rx3715_init_irq,
+       .init_machine   = rx3715_init_machine,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c244x_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2410.c b/arch/arm/mach-s3c24xx/mach-smdk2410.c
new file mode 100644 (file)
index 0000000..bdc27e7
--- /dev/null
@@ -0,0 +1,122 @@
+/* linux/arch/arm/mach-s3c2410/mach-smdk2410.c
+ *
+ * linux/arch/arm/mach-s3c2410/mach-smdk2410.c
+ *
+ * Copyright (C) 2004 by FS Forth-Systeme GmbH
+ * All rights reserved.
+ *
+ * @Author: Jonas Dietsche
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * @History:
+ * derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ ***********************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/iic.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include <plat/common-smdk.h>
+
+#include "common.h"
+
+static struct map_desc smdk2410_iodesc[] __initdata = {
+  /* nothing here yet */
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk2410_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       }
+};
+
+static struct platform_device *smdk2410_devices[] __initdata = {
+       &s3c_device_ohci,
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_iis,
+};
+
+static void __init smdk2410_map_io(void)
+{
+       s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
+       s3c24xx_init_clocks(0);
+       s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
+}
+
+static void __init smdk2410_init(void)
+{
+       s3c_i2c0_set_platdata(NULL);
+       platform_add_devices(smdk2410_devices, ARRAY_SIZE(smdk2410_devices));
+       smdk_machine_init();
+}
+
+MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
+                                   * to SMDK2410 */
+       /* Maintainer: Jonas Dietsche */
+       .atag_offset    = 0x100,
+       .map_io         = smdk2410_map_io,
+       .init_irq       = s3c24xx_init_irq,
+       .init_machine   = smdk2410_init,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c2410_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2413.c b/arch/arm/mach-s3c24xx/mach-smdk2413.c
new file mode 100644 (file)
index 0000000..b11451b
--- /dev/null
@@ -0,0 +1,162 @@
+/* linux/arch/arm/mach-s3c2412/mach-smdk2413.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Thanks to Dimity Andric (TomTom) and Steven Ryu (Samsung) for the
+ * loans of SMDK2413 to work with.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/hardware/iomd.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+//#include <asm/debug-ll.h>
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/idle.h>
+#include <plat/udc.h>
+#include <plat/iic.h>
+#include <mach/fb.h>
+
+#include <plat/s3c2410.h>
+#include <plat/s3c2412.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include <plat/common-smdk.h>
+
+static struct map_desc smdk2413_iodesc[] __initdata = {
+};
+
+static struct s3c2410_uartcfg smdk2413_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       /* IR port */
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x43,
+               .ufcon       = 0x51,
+       }
+};
+
+
+static struct s3c2410_udc_mach_info smdk2413_udc_cfg __initdata = {
+       .pullup_pin = S3C2410_GPF(2),
+};
+
+
+static struct platform_device *smdk2413_devices[] __initdata = {
+       &s3c_device_ohci,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_iis,
+       &s3c_device_usbgadget,
+};
+
+static void __init smdk2413_fixup(struct tag *tags, char **cmdline,
+                                 struct meminfo *mi)
+{
+       if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
+               mi->nr_banks=1;
+               mi->bank[0].start = 0x30000000;
+               mi->bank[0].size = SZ_64M;
+       }
+}
+
+static void __init smdk2413_map_io(void)
+{
+       s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc));
+       s3c24xx_init_clocks(12000000);
+       s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs));
+}
+
+static void __init smdk2413_machine_init(void)
+{      /* Turn off suspend on both USB ports, and switch the
+        * selectable USB port to USB device mode. */
+
+       s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+                             S3C2410_MISCCR_USBSUSPND0 |
+                             S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+
+       s3c24xx_udc_set_platdata(&smdk2413_udc_cfg);
+       s3c_i2c0_set_platdata(NULL);
+
+       platform_add_devices(smdk2413_devices, ARRAY_SIZE(smdk2413_devices));
+       smdk_machine_init();
+}
+
+MACHINE_START(S3C2413, "S3C2413")
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+       .atag_offset    = 0x100,
+
+       .fixup          = smdk2413_fixup,
+       .init_irq       = s3c24xx_init_irq,
+       .map_io         = smdk2413_map_io,
+       .init_machine   = smdk2413_machine_init,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c2412_restart,
+MACHINE_END
+
+MACHINE_START(SMDK2412, "SMDK2412")
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+       .atag_offset    = 0x100,
+
+       .fixup          = smdk2413_fixup,
+       .init_irq       = s3c24xx_init_irq,
+       .map_io         = smdk2413_map_io,
+       .init_machine   = smdk2413_machine_init,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c2412_restart,
+MACHINE_END
+
+MACHINE_START(SMDK2413, "SMDK2413")
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+       .atag_offset    = 0x100,
+
+       .fixup          = smdk2413_fixup,
+       .init_irq       = s3c24xx_init_irq,
+       .map_io         = smdk2413_map_io,
+       .init_machine   = smdk2413_machine_init,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c2412_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2416.c b/arch/arm/mach-s3c24xx/mach-smdk2416.c
new file mode 100644 (file)
index 0000000..30a44f8
--- /dev/null
@@ -0,0 +1,256 @@
+/* linux/arch/arm/mach-s3c2416/mach-hanlin_v3c.c
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ *     as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ *     Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mtd/partitions.h>
+#include <linux/gpio.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/regs-s3c2443-clock.h>
+
+#include <mach/idle.h>
+#include <mach/leds-gpio.h>
+#include <plat/iic.h>
+
+#include <plat/s3c2416.h>
+#include <plat/gpio-cfg.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/nand.h>
+#include <plat/sdhci.h>
+#include <plat/udc.h>
+#include <linux/platform_data/s3c-hsudc.h>
+
+#include <plat/regs-fb-v4.h>
+#include <plat/fb.h>
+
+#include <plat/common-smdk.h>
+
+static struct map_desc smdk2416_iodesc[] __initdata = {
+       /* ISA IO Space map (memory space selected by A24) */
+
+       {
+               .virtual        = (u32)S3C24XX_VA_ISA_WORD,
+               .pfn            = __phys_to_pfn(S3C2410_CS2),
+               .length         = 0x10000,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
+               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+               .length         = SZ_4M,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
+               .pfn            = __phys_to_pfn(S3C2410_CS2),
+               .length         = 0x10000,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
+               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+               .length         = SZ_4M,
+               .type           = MT_DEVICE,
+       }
+};
+
+#define UCON (S3C2410_UCON_DEFAULT     | \
+               S3C2440_UCON_PCLK       | \
+               S3C2443_UCON_RXERR_IRQEN)
+
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
+
+#define UFCON (S3C2410_UFCON_RXTRIG8   | \
+               S3C2410_UFCON_FIFOMODE  | \
+               S3C2440_UFCON_TXTRIG16)
+
+static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       /* IR port */
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON | 0x50,
+               .ufcon       = UFCON,
+       },
+       [3] = {
+               .hwport      = 3,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       }
+};
+
+static void smdk2416_hsudc_gpio_init(void)
+{
+       s3c_gpio_setpull(S3C2410_GPH(14), S3C_GPIO_PULL_UP);
+       s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_NONE);
+       s3c_gpio_cfgpin(S3C2410_GPH(14), S3C_GPIO_SFN(1));
+       s3c2410_modify_misccr(S3C2416_MISCCR_SEL_SUSPND, 0);
+}
+
+static void smdk2416_hsudc_gpio_uninit(void)
+{
+       s3c2410_modify_misccr(S3C2416_MISCCR_SEL_SUSPND, 1);
+       s3c_gpio_setpull(S3C2410_GPH(14), S3C_GPIO_PULL_NONE);
+       s3c_gpio_cfgpin(S3C2410_GPH(14), S3C_GPIO_SFN(0));
+}
+
+static struct s3c24xx_hsudc_platdata smdk2416_hsudc_platdata = {
+       .epnum = 9,
+       .gpio_init = smdk2416_hsudc_gpio_init,
+       .gpio_uninit = smdk2416_hsudc_gpio_uninit,
+};
+
+static struct s3c_fb_pd_win smdk2416_fb_win[] = {
+       [0] = {
+               /* think this is the same as the smdk6410 */
+               .win_mode       = {
+                       .pixclock       = 41094,
+                       .left_margin    = 8,
+                       .right_margin   = 13,
+                       .upper_margin   = 7,
+                       .lower_margin   = 5,
+                       .hsync_len      = 3,
+                       .vsync_len      = 1,
+                       .xres           = 800,
+                       .yres           = 480,
+               },
+               .default_bpp    = 16,
+               .max_bpp        = 32,
+       },
+};
+
+static void s3c2416_fb_gpio_setup_24bpp(void)
+{
+       unsigned int gpio;
+
+       for (gpio = S3C2410_GPC(1); gpio <= S3C2410_GPC(4); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+       }
+
+       for (gpio = S3C2410_GPC(8); gpio <= S3C2410_GPC(15); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+       }
+
+       for (gpio = S3C2410_GPD(0); gpio <= S3C2410_GPD(15); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+       }
+}
+
+static struct s3c_fb_platdata smdk2416_fb_platdata = {
+       .win[0]         = &smdk2416_fb_win[0],
+       .setup_gpio     = s3c2416_fb_gpio_setup_24bpp,
+       .vidcon0        = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+       .vidcon1        = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+static struct s3c_sdhci_platdata smdk2416_hsmmc0_pdata __initdata = {
+       .max_width              = 4,
+       .cd_type                = S3C_SDHCI_CD_GPIO,
+       .ext_cd_gpio            = S3C2410_GPF(1),
+       .ext_cd_gpio_invert     = 1,
+};
+
+static struct s3c_sdhci_platdata smdk2416_hsmmc1_pdata __initdata = {
+       .max_width              = 4,
+       .cd_type                = S3C_SDHCI_CD_NONE,
+};
+
+static struct platform_device *smdk2416_devices[] __initdata = {
+       &s3c_device_fb,
+       &s3c_device_wdt,
+       &s3c_device_ohci,
+       &s3c_device_i2c0,
+       &s3c_device_hsmmc0,
+       &s3c_device_hsmmc1,
+       &s3c_device_usb_hsudc,
+};
+
+static void __init smdk2416_map_io(void)
+{
+       s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc));
+       s3c24xx_init_clocks(12000000);
+       s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs));
+}
+
+static void __init smdk2416_machine_init(void)
+{
+       s3c_i2c0_set_platdata(NULL);
+       s3c_fb_set_platdata(&smdk2416_fb_platdata);
+
+       s3c_sdhci0_set_platdata(&smdk2416_hsmmc0_pdata);
+       s3c_sdhci1_set_platdata(&smdk2416_hsmmc1_pdata);
+
+       s3c24xx_hsudc_set_platdata(&smdk2416_hsudc_platdata);
+
+       gpio_request(S3C2410_GPB(4), "USBHost Power");
+       gpio_direction_output(S3C2410_GPB(4), 1);
+
+       gpio_request(S3C2410_GPB(3), "Display Power");
+       gpio_direction_output(S3C2410_GPB(3), 1);
+
+       gpio_request(S3C2410_GPB(1), "Display Reset");
+       gpio_direction_output(S3C2410_GPB(1), 1);
+
+       platform_add_devices(smdk2416_devices, ARRAY_SIZE(smdk2416_devices));
+       smdk_machine_init();
+}
+
+MACHINE_START(SMDK2416, "SMDK2416")
+       /* Maintainer: Yauhen Kharuzhy <jekhor@gmail.com> */
+       .atag_offset    = 0x100,
+
+       .init_irq       = s3c24xx_init_irq,
+       .map_io         = smdk2416_map_io,
+       .init_machine   = smdk2416_machine_init,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c2416_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2440.c b/arch/arm/mach-s3c24xx/mach-smdk2440.c
new file mode 100644 (file)
index 0000000..83a1036
--- /dev/null
@@ -0,0 +1,187 @@
+/* linux/arch/arm/mach-s3c2440/mach-smdk2440.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.fluff.org/ben/smdk2440/
+ *
+ * Thanks to Dimity Andric and TomTom for the loan of an SMDK2440.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/idle.h>
+#include <mach/fb.h>
+#include <plat/iic.h>
+
+#include <plat/s3c2410.h>
+#include <plat/s3c244x.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include <plat/common-smdk.h>
+
+#include "common.h"
+
+static struct map_desc smdk2440_iodesc[] __initdata = {
+       /* ISA IO Space map (memory space selected by A24) */
+
+       {
+               .virtual        = (u32)S3C24XX_VA_ISA_WORD,
+               .pfn            = __phys_to_pfn(S3C2410_CS2),
+               .length         = 0x10000,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
+               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+               .length         = SZ_4M,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
+               .pfn            = __phys_to_pfn(S3C2410_CS2),
+               .length         = 0x10000,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
+               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+               .length         = SZ_4M,
+               .type           = MT_DEVICE,
+       }
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       /* IR port */
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x43,
+               .ufcon       = 0x51,
+       }
+};
+
+/* LCD driver info */
+
+static struct s3c2410fb_display smdk2440_lcd_cfg __initdata = {
+
+       .lcdcon5        = S3C2410_LCDCON5_FRM565 |
+                         S3C2410_LCDCON5_INVVLINE |
+                         S3C2410_LCDCON5_INVVFRAME |
+                         S3C2410_LCDCON5_PWREN |
+                         S3C2410_LCDCON5_HWSWP,
+
+       .type           = S3C2410_LCDCON1_TFT,
+
+       .width          = 240,
+       .height         = 320,
+
+       .pixclock       = 166667, /* HCLK 60 MHz, divisor 10 */
+       .xres           = 240,
+       .yres           = 320,
+       .bpp            = 16,
+       .left_margin    = 20,
+       .right_margin   = 8,
+       .hsync_len      = 4,
+       .upper_margin   = 8,
+       .lower_margin   = 7,
+       .vsync_len      = 4,
+};
+
+static struct s3c2410fb_mach_info smdk2440_fb_info __initdata = {
+       .displays       = &smdk2440_lcd_cfg,
+       .num_displays   = 1,
+       .default_display = 0,
+
+#if 0
+       /* currently setup by downloader */
+       .gpccon         = 0xaa940659,
+       .gpccon_mask    = 0xffffffff,
+       .gpcup          = 0x0000ffff,
+       .gpcup_mask     = 0xffffffff,
+       .gpdcon         = 0xaa84aaa0,
+       .gpdcon_mask    = 0xffffffff,
+       .gpdup          = 0x0000faff,
+       .gpdup_mask     = 0xffffffff,
+#endif
+
+       .lpcsel         = ((0xCE6) & ~7) | 1<<4,
+};
+
+static struct platform_device *smdk2440_devices[] __initdata = {
+       &s3c_device_ohci,
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_iis,
+};
+
+static void __init smdk2440_map_io(void)
+{
+       s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
+       s3c24xx_init_clocks(16934400);
+       s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
+}
+
+static void __init smdk2440_machine_init(void)
+{
+       s3c24xx_fb_set_platdata(&smdk2440_fb_info);
+       s3c_i2c0_set_platdata(NULL);
+
+       platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
+       smdk_machine_init();
+}
+
+MACHINE_START(S3C2440, "SMDK2440")
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+       .atag_offset    = 0x100,
+
+       .init_irq       = s3c24xx_init_irq,
+       .map_io         = smdk2440_map_io,
+       .init_machine   = smdk2440_machine_init,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c244x_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2443.c b/arch/arm/mach-s3c24xx/mach-smdk2443.c
new file mode 100644 (file)
index 0000000..2092369
--- /dev/null
@@ -0,0 +1,149 @@
+/* linux/arch/arm/mach-s3c2443/mach-smdk2443.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.fluff.org/ben/smdk2443/
+ *
+ * Thanks to Samsung for the loan of an SMDK2443
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/idle.h>
+#include <mach/fb.h>
+#include <plat/iic.h>
+
+#include <plat/s3c2410.h>
+#include <plat/s3c2443.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include <plat/common-smdk.h>
+
+static struct map_desc smdk2443_iodesc[] __initdata = {
+       /* ISA IO Space map (memory space selected by A24) */
+
+       {
+               .virtual        = (u32)S3C24XX_VA_ISA_WORD,
+               .pfn            = __phys_to_pfn(S3C2410_CS2),
+               .length         = 0x10000,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
+               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+               .length         = SZ_4M,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
+               .pfn            = __phys_to_pfn(S3C2410_CS2),
+               .length         = 0x10000,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
+               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+               .length         = SZ_4M,
+               .type           = MT_DEVICE,
+       }
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk2443_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       /* IR port */
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x43,
+               .ufcon       = 0x51,
+       },
+       [3] = {
+               .hwport      = 3,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       }
+};
+
+static struct platform_device *smdk2443_devices[] __initdata = {
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_hsmmc1,
+#ifdef CONFIG_SND_SOC_SMDK2443_WM9710
+       &s3c_device_ac97,
+#endif
+};
+
+static void __init smdk2443_map_io(void)
+{
+       s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc));
+       s3c24xx_init_clocks(12000000);
+       s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs));
+}
+
+static void __init smdk2443_machine_init(void)
+{
+       s3c_i2c0_set_platdata(NULL);
+
+#ifdef CONFIG_SND_SOC_SMDK2443_WM9710
+       s3c24xx_ac97_setup_gpio(S3C24XX_AC97_GPE0);
+#endif
+
+       platform_add_devices(smdk2443_devices, ARRAY_SIZE(smdk2443_devices));
+       smdk_machine_init();
+}
+
+MACHINE_START(SMDK2443, "SMDK2443")
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+       .atag_offset    = 0x100,
+
+       .init_irq       = s3c24xx_init_irq,
+       .map_io         = smdk2443_map_io,
+       .init_machine   = smdk2443_machine_init,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c2443_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-tct_hammer.c b/arch/arm/mach-s3c24xx/mach-tct_hammer.c
new file mode 100644 (file)
index 0000000..1114666
--- /dev/null
@@ -0,0 +1,157 @@
+/* linux/arch/arm/mach-s3c2410/mach-tct_hammer.c
+ *
+ * Copyright (c) 2007 TinCanTools
+ *     David Anders <danders@amltd.com>
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * @History:
+ * derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ ***********************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/physmap.h>
+
+#include "common.h"
+
+static struct resource tct_hammer_nor_resource = {
+               .start = 0x00000000,
+               .end   = 0x01000000 - 1,
+               .flags = IORESOURCE_MEM,
+};
+
+static struct mtd_partition tct_hammer_mtd_partitions[] = {
+       {
+               .name           = "System",
+               .size           = 0x240000,
+               .offset         = 0,
+               .mask_flags     = MTD_WRITEABLE,  /* force read-only */
+       }, {
+               .name           = "JFFS2",
+               .size           = MTDPART_SIZ_FULL,
+               .offset         = MTDPART_OFS_APPEND,
+       }
+};
+
+static struct physmap_flash_data tct_hammer_flash_data = {
+       .width          = 2,
+       .parts          = tct_hammer_mtd_partitions,
+       .nr_parts       = ARRAY_SIZE(tct_hammer_mtd_partitions),
+};
+
+static struct platform_device tct_hammer_device_nor = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev = {
+                       .platform_data = &tct_hammer_flash_data,
+               },
+       .num_resources  = 1,
+       .resource       = &tct_hammer_nor_resource,
+};
+
+static struct map_desc tct_hammer_iodesc[] __initdata = {
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg tct_hammer_uartcfgs[] = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       }
+};
+
+
+static struct platform_device *tct_hammer_devices[] __initdata = {
+       &s3c_device_adc,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_ohci,
+       &s3c_device_rtc,
+       &s3c_device_usbgadget,
+       &s3c_device_sdi,
+       &tct_hammer_device_nor,
+};
+
+static void __init tct_hammer_map_io(void)
+{
+       s3c24xx_init_io(tct_hammer_iodesc, ARRAY_SIZE(tct_hammer_iodesc));
+       s3c24xx_init_clocks(0);
+       s3c24xx_init_uarts(tct_hammer_uartcfgs, ARRAY_SIZE(tct_hammer_uartcfgs));
+}
+
+static void __init tct_hammer_init(void)
+{
+       s3c_i2c0_set_platdata(NULL);
+       platform_add_devices(tct_hammer_devices, ARRAY_SIZE(tct_hammer_devices));
+}
+
+MACHINE_START(TCT_HAMMER, "TCT_HAMMER")
+       .atag_offset    = 0x100,
+       .map_io         = tct_hammer_map_io,
+       .init_irq       = s3c24xx_init_irq,
+       .init_machine   = tct_hammer_init,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c2410_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-vr1000.c b/arch/arm/mach-s3c24xx/mach-vr1000.c
new file mode 100644 (file)
index 0000000..87608d4
--- /dev/null
@@ -0,0 +1,385 @@
+/* linux/arch/arm/mach-s3c2410/mach-vr1000.c
+ *
+ * Copyright (c) 2003-2008 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * Machine support for Thorcom VR1000 board. Designed for Thorcom by
+ * Simtec Electronics, http://www.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/dm9000.h>
+#include <linux/i2c.h>
+
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/bast-map.h>
+#include <mach/vr1000-map.h>
+#include <mach/vr1000-irq.h>
+#include <mach/vr1000-cpld.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/leds-gpio.h>
+
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/iic.h>
+#include <plat/audio-simtec.h>
+
+#include "simtec.h"
+#include "common.h"
+
+/* macros for virtual address mods for the io space entries */
+#define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5)
+#define VA_C4(item) ((unsigned long)(item) + BAST_VAM_CS4)
+#define VA_C3(item) ((unsigned long)(item) + BAST_VAM_CS3)
+#define VA_C2(item) ((unsigned long)(item) + BAST_VAM_CS2)
+
+/* macros to modify the physical addresses for io space */
+
+#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2))
+#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3))
+#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4))
+#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5))
+
+static struct map_desc vr1000_iodesc[] __initdata = {
+  /* ISA IO areas */
+  {
+         .virtual      = (u32)S3C24XX_VA_ISA_BYTE,
+         .pfn          = PA_CS2(BAST_PA_ISAIO),
+         .length       = SZ_16M,
+         .type         = MT_DEVICE,
+  }, {
+         .virtual      = (u32)S3C24XX_VA_ISA_WORD,
+         .pfn          = PA_CS3(BAST_PA_ISAIO),
+         .length       = SZ_16M,
+         .type         = MT_DEVICE,
+  },
+
+  /*  CPLD control registers, and external interrupt controls */
+  {
+         .virtual      = (u32)VR1000_VA_CTRL1,
+         .pfn          = __phys_to_pfn(VR1000_PA_CTRL1),
+         .length       = SZ_1M,
+         .type         = MT_DEVICE,
+  }, {
+         .virtual      = (u32)VR1000_VA_CTRL2,
+         .pfn          = __phys_to_pfn(VR1000_PA_CTRL2),
+         .length       = SZ_1M,
+         .type         = MT_DEVICE,
+  }, {
+         .virtual      = (u32)VR1000_VA_CTRL3,
+         .pfn          = __phys_to_pfn(VR1000_PA_CTRL3),
+         .length       = SZ_1M,
+         .type         = MT_DEVICE,
+  }, {
+         .virtual      = (u32)VR1000_VA_CTRL4,
+         .pfn          = __phys_to_pfn(VR1000_PA_CTRL4),
+         .length       = SZ_1M,
+         .type         = MT_DEVICE,
+  },
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       /* port 2 is not actually used */
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       }
+};
+
+/* definitions for the vr1000 extra 16550 serial ports */
+
+#define VR1000_BAUDBASE (3692307)
+
+#define VR1000_SERIAL_MAPBASE(x) (VR1000_PA_SERIAL + 0x80 + ((x) << 5))
+
+static struct plat_serial8250_port serial_platform_data[] = {
+       [0] = {
+               .mapbase        = VR1000_SERIAL_MAPBASE(0),
+               .irq            = IRQ_VR1000_SERIAL + 0,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+               .iotype         = UPIO_MEM,
+               .regshift       = 0,
+               .uartclk        = VR1000_BAUDBASE,
+       },
+       [1] = {
+               .mapbase        = VR1000_SERIAL_MAPBASE(1),
+               .irq            = IRQ_VR1000_SERIAL + 1,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+               .iotype         = UPIO_MEM,
+               .regshift       = 0,
+               .uartclk        = VR1000_BAUDBASE,
+       },
+       [2] = {
+               .mapbase        = VR1000_SERIAL_MAPBASE(2),
+               .irq            = IRQ_VR1000_SERIAL + 2,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+               .iotype         = UPIO_MEM,
+               .regshift       = 0,
+               .uartclk        = VR1000_BAUDBASE,
+       },
+       [3] = {
+               .mapbase        = VR1000_SERIAL_MAPBASE(3),
+               .irq            = IRQ_VR1000_SERIAL + 3,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+               .iotype         = UPIO_MEM,
+               .regshift       = 0,
+               .uartclk        = VR1000_BAUDBASE,
+       },
+       { },
+};
+
+static struct platform_device serial_device = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_PLATFORM,
+       .dev                    = {
+               .platform_data  = serial_platform_data,
+       },
+};
+
+/* DM9000 ethernet devices */
+
+static struct resource vr1000_dm9k0_resource[] = {
+       [0] = {
+               .start = S3C2410_CS5 + VR1000_PA_DM9000,
+               .end   = S3C2410_CS5 + VR1000_PA_DM9000 + 3,
+               .flags = IORESOURCE_MEM
+       },
+       [1] = {
+               .start = S3C2410_CS5 + VR1000_PA_DM9000 + 0x40,
+               .end   = S3C2410_CS5 + VR1000_PA_DM9000 + 0x7f,
+               .flags = IORESOURCE_MEM
+       },
+       [2] = {
+               .start = IRQ_VR1000_DM9000A,
+               .end   = IRQ_VR1000_DM9000A,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+       }
+
+};
+
+static struct resource vr1000_dm9k1_resource[] = {
+       [0] = {
+               .start = S3C2410_CS5 + VR1000_PA_DM9000 + 0x80,
+               .end   = S3C2410_CS5 + VR1000_PA_DM9000 + 0x83,
+               .flags = IORESOURCE_MEM
+       },
+       [1] = {
+               .start = S3C2410_CS5 + VR1000_PA_DM9000 + 0xC0,
+               .end   = S3C2410_CS5 + VR1000_PA_DM9000 + 0xFF,
+               .flags = IORESOURCE_MEM
+       },
+       [2] = {
+               .start = IRQ_VR1000_DM9000N,
+               .end   = IRQ_VR1000_DM9000N,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+       }
+};
+
+/* for the moment we limit ourselves to 16bit IO until some
+ * better IO routines can be written and tested
+*/
+
+static struct dm9000_plat_data vr1000_dm9k_platdata = {
+       .flags          = DM9000_PLATF_16BITONLY,
+};
+
+static struct platform_device vr1000_dm9k0 = {
+       .name           = "dm9000",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(vr1000_dm9k0_resource),
+       .resource       = vr1000_dm9k0_resource,
+       .dev            = {
+               .platform_data = &vr1000_dm9k_platdata,
+       }
+};
+
+static struct platform_device vr1000_dm9k1 = {
+       .name           = "dm9000",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(vr1000_dm9k1_resource),
+       .resource       = vr1000_dm9k1_resource,
+       .dev            = {
+               .platform_data = &vr1000_dm9k_platdata,
+       }
+};
+
+/* LEDS */
+
+static struct s3c24xx_led_platdata vr1000_led1_pdata = {
+       .name           = "led1",
+       .gpio           = S3C2410_GPB(0),
+       .def_trigger    = "",
+};
+
+static struct s3c24xx_led_platdata vr1000_led2_pdata = {
+       .name           = "led2",
+       .gpio           = S3C2410_GPB(1),
+       .def_trigger    = "",
+};
+
+static struct s3c24xx_led_platdata vr1000_led3_pdata = {
+       .name           = "led3",
+       .gpio           = S3C2410_GPB(2),
+       .def_trigger    = "",
+};
+
+static struct platform_device vr1000_led1 = {
+       .name           = "s3c24xx_led",
+       .id             = 1,
+       .dev            = {
+               .platform_data  = &vr1000_led1_pdata,
+       },
+};
+
+static struct platform_device vr1000_led2 = {
+       .name           = "s3c24xx_led",
+       .id             = 2,
+       .dev            = {
+               .platform_data  = &vr1000_led2_pdata,
+       },
+};
+
+static struct platform_device vr1000_led3 = {
+       .name           = "s3c24xx_led",
+       .id             = 3,
+       .dev            = {
+               .platform_data  = &vr1000_led3_pdata,
+       },
+};
+
+/* I2C devices. */
+
+static struct i2c_board_info vr1000_i2c_devs[] __initdata = {
+       {
+               I2C_BOARD_INFO("tlv320aic23", 0x1a),
+       }, {
+               I2C_BOARD_INFO("tmp101", 0x48),
+       }, {
+               I2C_BOARD_INFO("m41st87", 0x68),
+       },
+};
+
+/* devices for this board */
+
+static struct platform_device *vr1000_devices[] __initdata = {
+       &s3c_device_ohci,
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_adc,
+       &serial_device,
+       &vr1000_dm9k0,
+       &vr1000_dm9k1,
+       &vr1000_led1,
+       &vr1000_led2,
+       &vr1000_led3,
+};
+
+static struct clk *vr1000_clocks[] __initdata = {
+       &s3c24xx_dclk0,
+       &s3c24xx_dclk1,
+       &s3c24xx_clkout0,
+       &s3c24xx_clkout1,
+       &s3c24xx_uclk,
+};
+
+static void vr1000_power_off(void)
+{
+       gpio_direction_output(S3C2410_GPB(9), 1);
+}
+
+static void __init vr1000_map_io(void)
+{
+       /* initialise clock sources */
+
+       s3c24xx_dclk0.parent = &clk_upll;
+       s3c24xx_dclk0.rate   = 12*1000*1000;
+
+       s3c24xx_dclk1.parent = NULL;
+       s3c24xx_dclk1.rate   = 3692307;
+
+       s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
+       s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
+
+       s3c24xx_uclk.parent  = &s3c24xx_clkout1;
+
+       s3c24xx_register_clocks(vr1000_clocks, ARRAY_SIZE(vr1000_clocks));
+
+       pm_power_off = vr1000_power_off;
+
+       s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
+       s3c24xx_init_clocks(0);
+       s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
+}
+
+static void __init vr1000_init(void)
+{
+       s3c_i2c0_set_platdata(NULL);
+       platform_add_devices(vr1000_devices, ARRAY_SIZE(vr1000_devices));
+
+       i2c_register_board_info(0, vr1000_i2c_devs,
+                               ARRAY_SIZE(vr1000_i2c_devs));
+
+       nor_simtec_init();
+       simtec_audio_add(NULL, true, NULL);
+
+       WARN_ON(gpio_request(S3C2410_GPB(9), "power off"));
+}
+
+MACHINE_START(VR1000, "Thorcom-VR1000")
+       /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
+       .atag_offset    = 0x100,
+       .map_io         = vr1000_map_io,
+       .init_machine   = vr1000_init,
+       .init_irq       = s3c24xx_init_irq,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c2410_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-vstms.c b/arch/arm/mach-s3c24xx/mach-vstms.c
new file mode 100644 (file)
index 0000000..94bfaa1
--- /dev/null
@@ -0,0 +1,166 @@
+/* linux/arch/arm/mach-s3c2412/mach-vstms.c
+ *
+ * (C) 2006 Thomas Gleixner <tglx@linutronix.de>
+ *
+ * Derived from mach-smdk2413.c - (C) 2006 Simtec Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/idle.h>
+#include <mach/fb.h>
+
+#include <plat/iic.h>
+#include <plat/nand.h>
+
+#include <plat/s3c2410.h>
+#include <plat/s3c2412.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+
+static struct map_desc vstms_iodesc[] __initdata = {
+};
+
+static struct s3c2410_uartcfg vstms_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       },
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = 0x3c5,
+               .ulcon       = 0x03,
+               .ufcon       = 0x51,
+       }
+};
+
+static struct mtd_partition __initdata vstms_nand_part[] = {
+       [0] = {
+               .name   = "Boot Agent",
+               .size   = 0x7C000,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "UBoot Config",
+               .offset = 0x7C000,
+               .size   = 0x4000,
+       },
+       [2] = {
+               .name   = "Kernel",
+               .offset = 0x80000,
+               .size   = 0x200000,
+       },
+       [3] = {
+               .name   = "RFS",
+               .offset = 0x280000,
+               .size   = 0x3d80000,
+       },
+};
+
+static struct s3c2410_nand_set __initdata vstms_nand_sets[] = {
+       [0] = {
+               .name           = "NAND",
+               .nr_chips       = 1,
+               .nr_partitions  = ARRAY_SIZE(vstms_nand_part),
+               .partitions     = vstms_nand_part,
+       },
+};
+
+/* choose a set of timings which should suit most 512Mbit
+ * chips and beyond.
+*/
+
+static struct s3c2410_platform_nand __initdata vstms_nand_info = {
+       .tacls          = 20,
+       .twrph0         = 60,
+       .twrph1         = 20,
+       .nr_sets        = ARRAY_SIZE(vstms_nand_sets),
+       .sets           = vstms_nand_sets,
+};
+
+static struct platform_device *vstms_devices[] __initdata = {
+       &s3c_device_ohci,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_iis,
+       &s3c_device_rtc,
+       &s3c_device_nand,
+};
+
+static void __init vstms_fixup(struct tag *tags, char **cmdline,
+                              struct meminfo *mi)
+{
+       if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
+               mi->nr_banks=1;
+               mi->bank[0].start = 0x30000000;
+               mi->bank[0].size = SZ_64M;
+       }
+}
+
+static void __init vstms_map_io(void)
+{
+       s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc));
+       s3c24xx_init_clocks(12000000);
+       s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs));
+}
+
+static void __init vstms_init(void)
+{
+       s3c_i2c0_set_platdata(NULL);
+       s3c_nand_set_platdata(&vstms_nand_info);
+
+       platform_add_devices(vstms_devices, ARRAY_SIZE(vstms_devices));
+}
+
+MACHINE_START(VSTMS, "VSTMS")
+       .atag_offset    = 0x100,
+
+       .fixup          = vstms_fixup,
+       .init_irq       = s3c24xx_init_irq,
+       .init_machine   = vstms_init,
+       .map_io         = vstms_map_io,
+       .timer          = &s3c24xx_timer,
+       .restart        = s3c2412_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/pm-h1940.S b/arch/arm/mach-s3c24xx/pm-h1940.S
new file mode 100644 (file)
index 0000000..c93bf2d
--- /dev/null
@@ -0,0 +1,33 @@
+/* linux/arch/arm/mach-s3c2410/pm-h1940.S
+ *
+ * Copyright (c) 2006 Ben Dooks <ben-linux@fluff.org>
+ *
+ * H1940 Suspend to RAM
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <mach/regs-gpio.h>
+
+       .text
+       .global h1940_pm_return
+
+h1940_pm_return:
+       mov     r0, #S3C2410_PA_GPIO
+       ldr     pc, [ r0, #S3C2410_GSTATUS3 - S3C24XX_VA_GPIO ]
diff --git a/arch/arm/mach-s3c24xx/pm-s3c2410.c b/arch/arm/mach-s3c24xx/pm-s3c2410.c
new file mode 100644 (file)
index 0000000..03f706d
--- /dev/null
@@ -0,0 +1,180 @@
+/* linux/arch/arm/mach-s3c2410/pm.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <linux/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/h1940.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+static void s3c2410_pm_prepare(void)
+{
+       /* ensure at least GSTATUS3 has the resume address */
+
+       __raw_writel(virt_to_phys(s3c_cpu_resume), S3C2410_GSTATUS3);
+
+       S3C_PMDBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
+       S3C_PMDBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
+
+       if (machine_is_h1940()) {
+               void *base = phys_to_virt(H1940_SUSPEND_CHECK);
+               unsigned long ptr;
+               unsigned long calc = 0;
+
+               /* generate check for the bootloader to check on resume */
+
+               for (ptr = 0; ptr < 0x40000; ptr += 0x400)
+                       calc += __raw_readl(base+ptr);
+
+               __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
+       }
+
+       /* RX3715 and RX1950 use similar to H1940 code and the
+        * same offsets for resume and checksum pointers */
+
+       if (machine_is_rx3715() || machine_is_rx1950()) {
+               void *base = phys_to_virt(H1940_SUSPEND_CHECK);
+               unsigned long ptr;
+               unsigned long calc = 0;
+
+               /* generate check for the bootloader to check on resume */
+
+               for (ptr = 0; ptr < 0x40000; ptr += 0x4)
+                       calc += __raw_readl(base+ptr);
+
+               __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
+       }
+
+       if ( machine_is_aml_m5900() )
+               s3c2410_gpio_setpin(S3C2410_GPF(2), 1);
+
+       if (machine_is_rx1950()) {
+               /* According to S3C2442 user's manual, page 7-17,
+                * when the system is operating in NAND boot mode,
+                * the hardware pin configuration - EINT[23:21] â€“
+                * must be set as input for starting up after
+                * wakeup from sleep mode
+                */
+               s3c_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_INPUT);
+               s3c_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPIO_INPUT);
+               s3c_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPIO_INPUT);
+       }
+}
+
+static void s3c2410_pm_resume(void)
+{
+       unsigned long tmp;
+
+       /* unset the return-from-sleep flag, to ensure reset */
+
+       tmp = __raw_readl(S3C2410_GSTATUS2);
+       tmp &= S3C2410_GSTATUS2_OFFRESET;
+       __raw_writel(tmp, S3C2410_GSTATUS2);
+
+       if ( machine_is_aml_m5900() )
+               s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
+}
+
+struct syscore_ops s3c2410_pm_syscore_ops = {
+       .resume         = s3c2410_pm_resume,
+};
+
+static int s3c2410_pm_add(struct device *dev, struct subsys_interface *sif)
+{
+       pm_cpu_prep = s3c2410_pm_prepare;
+       pm_cpu_sleep = s3c2410_cpu_suspend;
+
+       return 0;
+}
+
+#if defined(CONFIG_CPU_S3C2410)
+static struct subsys_interface s3c2410_pm_interface = {
+       .name           = "s3c2410_pm",
+       .subsys         = &s3c2410_subsys,
+       .add_dev        = s3c2410_pm_add,
+};
+
+/* register ourselves */
+
+static int __init s3c2410_pm_drvinit(void)
+{
+       return subsys_interface_register(&s3c2410_pm_interface);
+}
+
+arch_initcall(s3c2410_pm_drvinit);
+
+static struct subsys_interface s3c2410a_pm_interface = {
+       .name           = "s3c2410a_pm",
+       .subsys         = &s3c2410a_subsys,
+       .add_dev        = s3c2410_pm_add,
+};
+
+static int __init s3c2410a_pm_drvinit(void)
+{
+       return subsys_interface_register(&s3c2410a_pm_interface);
+}
+
+arch_initcall(s3c2410a_pm_drvinit);
+#endif
+
+#if defined(CONFIG_CPU_S3C2440)
+static struct subsys_interface s3c2440_pm_interface = {
+       .name           = "s3c2440_pm",
+       .subsys         = &s3c2440_subsys,
+       .add_dev        = s3c2410_pm_add,
+};
+
+static int __init s3c2440_pm_drvinit(void)
+{
+       return subsys_interface_register(&s3c2440_pm_interface);
+}
+
+arch_initcall(s3c2440_pm_drvinit);
+#endif
+
+#if defined(CONFIG_CPU_S3C2442)
+static struct subsys_interface s3c2442_pm_interface = {
+       .name           = "s3c2442_pm",
+       .subsys         = &s3c2442_subsys,
+       .add_dev        = s3c2410_pm_add,
+};
+
+static int __init s3c2442_pm_drvinit(void)
+{
+       return subsys_interface_register(&s3c2442_pm_interface);
+}
+
+arch_initcall(s3c2442_pm_drvinit);
+#endif
diff --git a/arch/arm/mach-s3c24xx/pm-s3c2412.c b/arch/arm/mach-s3c24xx/pm-s3c2412.c
new file mode 100644 (file)
index 0000000..d045885
--- /dev/null
@@ -0,0 +1,124 @@
+/* linux/arch/arm/mach-s3c2412/pm.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/cacheflush.h>
+#include <asm/irq.h>
+
+#include <mach/regs-power.h>
+#include <mach/regs-gpioj.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-dsc.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include <plat/s3c2412.h>
+
+extern void s3c2412_sleep_enter(void);
+
+static int s3c2412_cpu_suspend(unsigned long arg)
+{
+       unsigned long tmp;
+
+       /* set our standby method to sleep */
+
+       tmp = __raw_readl(S3C2412_PWRCFG);
+       tmp |= S3C2412_PWRCFG_STANDBYWFI_SLEEP;
+       __raw_writel(tmp, S3C2412_PWRCFG);
+
+       s3c2412_sleep_enter();
+
+       panic("sleep resumed to originator?");
+}
+
+static void s3c2412_pm_prepare(void)
+{
+}
+
+static int s3c2412_pm_add(struct device *dev, struct subsys_interface *sif)
+{
+       pm_cpu_prep = s3c2412_pm_prepare;
+       pm_cpu_sleep = s3c2412_cpu_suspend;
+
+       return 0;
+}
+
+static struct sleep_save s3c2412_sleep[] = {
+       SAVE_ITEM(S3C2412_DSC0),
+       SAVE_ITEM(S3C2412_DSC1),
+       SAVE_ITEM(S3C2413_GPJDAT),
+       SAVE_ITEM(S3C2413_GPJCON),
+       SAVE_ITEM(S3C2413_GPJUP),
+
+       /* save the PWRCFG to get back to original sleep method */
+
+       SAVE_ITEM(S3C2412_PWRCFG),
+
+       /* save the sleep configuration anyway, just in case these
+        * get damaged during wakeup */
+
+       SAVE_ITEM(S3C2412_GPBSLPCON),
+       SAVE_ITEM(S3C2412_GPCSLPCON),
+       SAVE_ITEM(S3C2412_GPDSLPCON),
+       SAVE_ITEM(S3C2412_GPFSLPCON),
+       SAVE_ITEM(S3C2412_GPGSLPCON),
+       SAVE_ITEM(S3C2412_GPHSLPCON),
+       SAVE_ITEM(S3C2413_GPJSLPCON),
+};
+
+static struct subsys_interface s3c2412_pm_interface = {
+       .name           = "s3c2412_pm",
+       .subsys         = &s3c2412_subsys,
+       .add_dev        = s3c2412_pm_add,
+};
+
+static __init int s3c2412_pm_init(void)
+{
+       return subsys_interface_register(&s3c2412_pm_interface);
+}
+
+arch_initcall(s3c2412_pm_init);
+
+static int s3c2412_pm_suspend(void)
+{
+       s3c_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
+       return 0;
+}
+
+static void s3c2412_pm_resume(void)
+{
+       unsigned long tmp;
+
+       tmp = __raw_readl(S3C2412_PWRCFG);
+       tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
+       tmp |=  S3C2412_PWRCFG_STANDBYWFI_IDLE;
+       __raw_writel(tmp, S3C2412_PWRCFG);
+
+       s3c_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
+}
+
+struct syscore_ops s3c2412_pm_syscore_ops = {
+       .suspend        = s3c2412_pm_suspend,
+       .resume         = s3c2412_pm_resume,
+};
diff --git a/arch/arm/mach-s3c24xx/pm-s3c2416.c b/arch/arm/mach-s3c24xx/pm-s3c2416.c
new file mode 100644 (file)
index 0000000..1bd4817
--- /dev/null
@@ -0,0 +1,83 @@
+/* linux/arch/arm/mach-s3c2416/pm.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S3C2416 - PM support (Based on Ben Dooks' S3C2412 PM support)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+
+#include <mach/regs-power.h>
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+extern void s3c2412_sleep_enter(void);
+
+static int s3c2416_cpu_suspend(unsigned long arg)
+{
+       /* enable wakeup sources regardless of battery state */
+       __raw_writel(S3C2443_PWRCFG_SLEEP, S3C2443_PWRCFG);
+
+       /* set the mode as sleep, 2BED represents "Go to BED" */
+       __raw_writel(0x2BED, S3C2443_PWRMODE);
+
+       s3c2412_sleep_enter();
+
+       panic("sleep resumed to originator?");
+}
+
+static void s3c2416_pm_prepare(void)
+{
+       /*
+        * write the magic value u-boot uses to check for resume into
+        * the INFORM0 register, and ensure INFORM1 is set to the
+        * correct address to resume from.
+        */
+       __raw_writel(0x2BED, S3C2412_INFORM0);
+       __raw_writel(virt_to_phys(s3c_cpu_resume), S3C2412_INFORM1);
+}
+
+static int s3c2416_pm_add(struct device *dev, struct subsys_interface *sif)
+{
+       pm_cpu_prep = s3c2416_pm_prepare;
+       pm_cpu_sleep = s3c2416_cpu_suspend;
+
+       return 0;
+}
+
+static struct subsys_interface s3c2416_pm_interface = {
+       .name           = "s3c2416_pm",
+       .subsys         = &s3c2416_subsys,
+       .add_dev        = s3c2416_pm_add,
+};
+
+static __init int s3c2416_pm_init(void)
+{
+       return subsys_interface_register(&s3c2416_pm_interface);
+}
+
+arch_initcall(s3c2416_pm_init);
+
+
+static void s3c2416_pm_resume(void)
+{
+       /* unset the return-from-sleep amd inform flags */
+       __raw_writel(0x0, S3C2443_PWRMODE);
+       __raw_writel(0x0, S3C2412_INFORM0);
+       __raw_writel(0x0, S3C2412_INFORM1);
+}
+
+struct syscore_ops s3c2416_pm_syscore_ops = {
+       .resume         = s3c2416_pm_resume,
+};
diff --git a/arch/arm/mach-s3c24xx/s3c2410.c b/arch/arm/mach-s3c24xx/s3c2410.c
new file mode 100644 (file)
index 0000000..061b6bb
--- /dev/null
@@ -0,0 +1,206 @@
+/* linux/arch/arm/mach-s3c2410/s3c2410.c
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.simtec.co.uk/products/EB2410ITX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+
+#include <mach/regs-clock.h>
+#include <plat/regs-serial.h>
+
+#include <plat/s3c2410.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/pll.h>
+#include <plat/pm.h>
+#include <plat/watchdog-reset.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+/* Initial IO mappings */
+
+static struct map_desc s3c2410_iodesc[] __initdata = {
+       IODESC_ENT(CLKPWR),
+       IODESC_ENT(TIMER),
+       IODESC_ENT(WATCHDOG),
+};
+
+/* our uart devices */
+
+/* uart registration process */
+
+void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+       s3c24xx_init_uartdevs("s3c2410-uart", s3c2410_uart_resources, cfg, no);
+}
+
+/* s3c2410_map_io
+ *
+ * register the standard cpu IO areas, and any passed in from the
+ * machine specific initialisation.
+*/
+
+void __init s3c2410_map_io(void)
+{
+       s3c24xx_gpiocfg_default.set_pull = s3c24xx_gpio_setpull_1up;
+       s3c24xx_gpiocfg_default.get_pull = s3c24xx_gpio_getpull_1up;
+
+       iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
+}
+
+void __init_or_cpufreq s3c2410_setup_clocks(void)
+{
+       struct clk *xtal_clk;
+       unsigned long tmp;
+       unsigned long xtal;
+       unsigned long fclk;
+       unsigned long hclk;
+       unsigned long pclk;
+
+       xtal_clk = clk_get(NULL, "xtal");
+       xtal = clk_get_rate(xtal_clk);
+       clk_put(xtal_clk);
+
+       /* now we've got our machine bits initialised, work out what
+        * clocks we've got */
+
+       fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal);
+
+       tmp = __raw_readl(S3C2410_CLKDIVN);
+
+       /* work out clock scalings */
+
+       hclk = fclk / ((tmp & S3C2410_CLKDIVN_HDIVN) ? 2 : 1);
+       pclk = hclk / ((tmp & S3C2410_CLKDIVN_PDIVN) ? 2 : 1);
+
+       /* print brieft summary of clocks, etc */
+
+       printk("S3C2410: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
+              print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
+
+       /* initialise the clocks here, to allow other things like the
+        * console to use them
+        */
+
+       s3c24xx_setup_clocks(fclk, hclk, pclk);
+}
+
+/* fake ARMCLK for use with cpufreq, etc. */
+
+static struct clk s3c2410_armclk = {
+       .name   = "armclk",
+       .parent = &clk_f,
+       .id     = -1,
+};
+
+static struct clk_lookup s3c2410_clk_lookup[] = {
+       CLKDEV_INIT(NULL, "clk_uart_baud0", &clk_p),
+       CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
+};
+
+void __init s3c2410_init_clocks(int xtal)
+{
+       s3c24xx_register_baseclocks(xtal);
+       s3c2410_setup_clocks();
+       s3c2410_baseclk_add();
+       s3c24xx_register_clock(&s3c2410_armclk);
+       clkdev_add_table(s3c2410_clk_lookup, ARRAY_SIZE(s3c2410_clk_lookup));
+}
+
+struct bus_type s3c2410_subsys = {
+       .name = "s3c2410-core",
+       .dev_name = "s3c2410-core",
+};
+
+/* Note, we would have liked to name this s3c2410-core, but we cannot
+ * register two subsystems with the same name.
+ */
+struct bus_type s3c2410a_subsys = {
+       .name = "s3c2410a-core",
+       .dev_name = "s3c2410a-core",
+};
+
+static struct device s3c2410_dev = {
+       .bus            = &s3c2410_subsys,
+};
+
+/* need to register the subsystem before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2410 based system)
+ * as a driver which may support both 2410 and 2440 may try and use it.
+*/
+
+static int __init s3c2410_core_init(void)
+{
+       return subsys_system_register(&s3c2410_subsys, NULL);
+}
+
+core_initcall(s3c2410_core_init);
+
+static int __init s3c2410a_core_init(void)
+{
+       return subsys_system_register(&s3c2410a_subsys, NULL);
+}
+
+core_initcall(s3c2410a_core_init);
+
+int __init s3c2410_init(void)
+{
+       printk("S3C2410: Initialising architecture\n");
+
+#ifdef CONFIG_PM
+       register_syscore_ops(&s3c2410_pm_syscore_ops);
+#endif
+       register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
+       return device_register(&s3c2410_dev);
+}
+
+int __init s3c2410a_init(void)
+{
+       s3c2410_dev.bus = &s3c2410a_subsys;
+       return s3c2410_init();
+}
+
+void s3c2410_restart(char mode, const char *cmd)
+{
+       if (mode == 's') {
+               soft_restart(0);
+       }
+
+       arch_wdt_reset();
+
+       /* we'll take a jump through zero as a poor second */
+       soft_restart(0);
+}
diff --git a/arch/arm/mach-s3c24xx/s3c2412.c b/arch/arm/mach-s3c24xx/s3c2412.c
new file mode 100644 (file)
index 0000000..c6eac98
--- /dev/null
@@ -0,0 +1,251 @@
+/* linux/arch/arm/mach-s3c2412/s3c2412.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/proc-fns.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+
+#include <mach/regs-clock.h>
+#include <plat/regs-serial.h>
+#include <mach/regs-power.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-gpioj.h>
+#include <mach/regs-dsc.h>
+#include <plat/regs-spi.h>
+#include <mach/regs-s3c2412.h>
+
+#include <plat/s3c2412.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/pm.h>
+#include <plat/pll.h>
+#include <plat/nand-core.h>
+
+#ifndef CONFIG_CPU_S3C2412_ONLY
+void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
+
+static inline void s3c2412_init_gpio2(void)
+{
+       s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10;
+}
+#else
+#define s3c2412_init_gpio2() do { } while(0)
+#endif
+
+/* Initial IO mappings */
+
+static struct map_desc s3c2412_iodesc[] __initdata = {
+       IODESC_ENT(CLKPWR),
+       IODESC_ENT(TIMER),
+       IODESC_ENT(WATCHDOG),
+       {
+               .virtual = (unsigned long)S3C2412_VA_SSMC,
+               .pfn     = __phys_to_pfn(S3C2412_PA_SSMC),
+               .length  = SZ_1M,
+               .type    = MT_DEVICE,
+       },
+       {
+               .virtual = (unsigned long)S3C2412_VA_EBI,
+               .pfn     = __phys_to_pfn(S3C2412_PA_EBI),
+               .length  = SZ_1M,
+               .type    = MT_DEVICE,
+       },
+};
+
+/* uart registration process */
+
+void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+       s3c24xx_init_uartdevs("s3c2412-uart", s3c2410_uart_resources, cfg, no);
+
+       /* rename devices that are s3c2412/s3c2413 specific */
+       s3c_device_sdi.name  = "s3c2412-sdi";
+       s3c_device_lcd.name  = "s3c2412-lcd";
+       s3c_nand_setname("s3c2412-nand");
+
+       /* alter IRQ of SDI controller */
+
+       s3c_device_sdi.resource[1].start = IRQ_S3C2412_SDI;
+       s3c_device_sdi.resource[1].end   = IRQ_S3C2412_SDI;
+
+       /* spi channel related changes, s3c2412/13 specific */
+       s3c_device_spi0.name = "s3c2412-spi";
+       s3c_device_spi0.resource[0].end = S3C24XX_PA_SPI + 0x24;
+       s3c_device_spi1.name = "s3c2412-spi";
+       s3c_device_spi1.resource[0].start = S3C24XX_PA_SPI + S3C2412_SPI1;
+       s3c_device_spi1.resource[0].end = S3C24XX_PA_SPI + S3C2412_SPI1 + 0x24;
+
+}
+
+/* s3c2412_idle
+ *
+ * use the standard idle call by ensuring the idle mode
+ * in power config, then issuing the idle co-processor
+ * instruction
+*/
+
+static void s3c2412_idle(void)
+{
+       unsigned long tmp;
+
+       /* ensure our idle mode is to go to idle */
+
+       tmp = __raw_readl(S3C2412_PWRCFG);
+       tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
+       tmp |= S3C2412_PWRCFG_STANDBYWFI_IDLE;
+       __raw_writel(tmp, S3C2412_PWRCFG);
+
+       cpu_do_idle();
+}
+
+void s3c2412_restart(char mode, const char *cmd)
+{
+       if (mode == 's')
+               soft_restart(0);
+
+       /* errata "Watch-dog/Software Reset Problem" specifies that
+        * this reset must be done with the SYSCLK sourced from
+        * EXTCLK instead of FOUT to avoid a glitch in the reset
+        * mechanism.
+        *
+        * See the watchdog section of the S3C2412 manual for more
+        * information on this fix.
+        */
+
+       __raw_writel(0x00, S3C2412_CLKSRC);
+       __raw_writel(S3C2412_SWRST_RESET, S3C2412_SWRST);
+
+       mdelay(1);
+}
+
+/* s3c2412_map_io
+ *
+ * register the standard cpu IO areas, and any passed in from the
+ * machine specific initialisation.
+*/
+
+void __init s3c2412_map_io(void)
+{
+       /* move base of IO */
+
+       s3c2412_init_gpio2();
+
+       /* set our idle function */
+
+       arm_pm_idle = s3c2412_idle;
+
+       /* register our io-tables */
+
+       iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
+}
+
+void __init_or_cpufreq s3c2412_setup_clocks(void)
+{
+       struct clk *xtal_clk;
+       unsigned long tmp;
+       unsigned long xtal;
+       unsigned long fclk;
+       unsigned long hclk;
+       unsigned long pclk;
+
+       xtal_clk = clk_get(NULL, "xtal");
+       xtal = clk_get_rate(xtal_clk);
+       clk_put(xtal_clk);
+
+       /* now we've got our machine bits initialised, work out what
+        * clocks we've got */
+
+       fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal * 2);
+
+       clk_mpll.rate = fclk;
+
+       tmp = __raw_readl(S3C2410_CLKDIVN);
+
+       /* work out clock scalings */
+
+       hclk = fclk / ((tmp & S3C2412_CLKDIVN_HDIVN_MASK) + 1);
+       hclk /= ((tmp & S3C2412_CLKDIVN_ARMDIVN) ? 2 : 1);
+       pclk = hclk / ((tmp & S3C2412_CLKDIVN_PDIVN) ? 2 : 1);
+
+       /* print brieft summary of clocks, etc */
+
+       printk("S3C2412: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
+              print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
+
+       s3c24xx_setup_clocks(fclk, hclk, pclk);
+}
+
+void __init s3c2412_init_clocks(int xtal)
+{
+       /* initialise the clocks here, to allow other things like the
+        * console to use them
+        */
+
+       s3c24xx_register_baseclocks(xtal);
+       s3c2412_setup_clocks();
+       s3c2412_baseclk_add();
+}
+
+/* need to register the subsystem before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2412 based system)
+ * as a driver which may support both 2410 and 2440 may try and use it.
+*/
+
+struct bus_type s3c2412_subsys = {
+       .name = "s3c2412-core",
+       .dev_name = "s3c2412-core",
+};
+
+static int __init s3c2412_core_init(void)
+{
+       return subsys_system_register(&s3c2412_subsys, NULL);
+}
+
+core_initcall(s3c2412_core_init);
+
+static struct device s3c2412_dev = {
+       .bus            = &s3c2412_subsys,
+};
+
+int __init s3c2412_init(void)
+{
+       printk("S3C2412: Initialising architecture\n");
+
+#ifdef CONFIG_PM
+       register_syscore_ops(&s3c2412_pm_syscore_ops);
+#endif
+       register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
+       return device_register(&s3c2412_dev);
+}
diff --git a/arch/arm/mach-s3c24xx/s3c2416.c b/arch/arm/mach-s3c24xx/s3c2416.c
new file mode 100644 (file)
index 0000000..0e9a71c
--- /dev/null
@@ -0,0 +1,148 @@
+/* linux/arch/arm/mach-s3c2416/s3c2416.c
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ *     as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ *     Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+ *
+ * Samsung S3C2416 Mobile CPU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/proc-fns.h>
+#include <asm/irq.h>
+
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <plat/s3c2416.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/sdhci.h>
+#include <plat/pm.h>
+
+#include <plat/iic-core.h>
+#include <plat/fb-core.h>
+#include <plat/nand-core.h>
+#include <plat/adc-core.h>
+#include <plat/rtc-core.h>
+
+static struct map_desc s3c2416_iodesc[] __initdata = {
+       IODESC_ENT(WATCHDOG),
+       IODESC_ENT(CLKPWR),
+       IODESC_ENT(TIMER),
+};
+
+struct bus_type s3c2416_subsys = {
+       .name = "s3c2416-core",
+       .dev_name = "s3c2416-core",
+};
+
+static struct device s3c2416_dev = {
+       .bus            = &s3c2416_subsys,
+};
+
+void s3c2416_restart(char mode, const char *cmd)
+{
+       if (mode == 's')
+               soft_restart(0);
+
+       __raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST);
+}
+
+int __init s3c2416_init(void)
+{
+       printk(KERN_INFO "S3C2416: Initializing architecture\n");
+
+       /* change WDT IRQ number */
+       s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT;
+       s3c_device_wdt.resource[1].end   = IRQ_S3C2443_WDT;
+
+       /* the i2c devices are directly compatible with s3c2440 */
+       s3c_i2c0_setname("s3c2440-i2c");
+       s3c_i2c1_setname("s3c2440-i2c");
+
+       s3c_fb_setname("s3c2443-fb");
+
+       s3c_adc_setname("s3c2416-adc");
+       s3c_rtc_setname("s3c2416-rtc");
+
+#ifdef CONFIG_PM
+       register_syscore_ops(&s3c2416_pm_syscore_ops);
+#endif
+       register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
+       return device_register(&s3c2416_dev);
+}
+
+void __init s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+       s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
+
+       s3c_nand_setname("s3c2412-nand");
+}
+
+/* s3c2416_map_io
+ *
+ * register the standard cpu IO areas, and any passed in from the
+ * machine specific initialisation.
+ */
+
+void __init s3c2416_map_io(void)
+{
+       s3c24xx_gpiocfg_default.set_pull = samsung_gpio_setpull_updown;
+       s3c24xx_gpiocfg_default.get_pull = samsung_gpio_getpull_updown;
+
+       /* initialize device information early */
+       s3c2416_default_sdhci0();
+       s3c2416_default_sdhci1();
+
+       iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc));
+}
+
+/* need to register the subsystem before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2416 based system)
+ * as a driver which may support both 2443 and 2440 may try and use it.
+*/
+
+static int __init s3c2416_core_init(void)
+{
+       return subsys_system_register(&s3c2416_subsys, NULL);
+}
+
+core_initcall(s3c2416_core_init);
diff --git a/arch/arm/mach-s3c24xx/s3c2440.c b/arch/arm/mach-s3c24xx/s3c2440.c
new file mode 100644 (file)
index 0000000..2b3dddb
--- /dev/null
@@ -0,0 +1,75 @@
+/* linux/arch/arm/mach-s3c2440/s3c2440.c
+ *
+ * Copyright (c) 2004-2006 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2440 Mobile CPU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/s3c244x.h>
+#include <plat/pm.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+static struct device s3c2440_dev = {
+       .bus            = &s3c2440_subsys,
+};
+
+int __init s3c2440_init(void)
+{
+       printk("S3C2440: Initialising architecture\n");
+
+       /* change irq for watchdog */
+
+       s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
+       s3c_device_wdt.resource[1].end   = IRQ_S3C2440_WDT;
+
+       /* register suspend/resume handlers */
+
+#ifdef CONFIG_PM
+       register_syscore_ops(&s3c2410_pm_syscore_ops);
+#endif
+       register_syscore_ops(&s3c244x_pm_syscore_ops);
+       register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
+       /* register our system device for everything else */
+
+       return device_register(&s3c2440_dev);
+}
+
+void __init s3c2440_map_io(void)
+{
+       s3c244x_map_io();
+
+       s3c24xx_gpiocfg_default.set_pull = s3c24xx_gpio_setpull_1up;
+       s3c24xx_gpiocfg_default.get_pull = s3c24xx_gpio_getpull_1up;
+}
diff --git a/arch/arm/mach-s3c24xx/s3c2442.c b/arch/arm/mach-s3c24xx/s3c2442.c
new file mode 100644 (file)
index 0000000..22cb7c9
--- /dev/null
@@ -0,0 +1,188 @@
+/* linux/arch/arm/mach-s3c2442/s3c2442.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2442 core and lock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/mutex.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <linux/atomic.h>
+#include <asm/irq.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/s3c244x.h>
+#include <plat/pm.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+/* S3C2442 extended clock support */
+
+static unsigned long s3c2442_camif_upll_round(struct clk *clk,
+                                             unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       int div;
+
+       if (rate > parent_rate)
+               return parent_rate;
+
+       div = parent_rate / rate;
+
+       if (div == 3)
+               return parent_rate / 3;
+
+       /* note, we remove the +/- 1 calculations for the divisor */
+
+       div /= 2;
+
+       if (div < 1)
+               div = 1;
+       else if (div > 16)
+               div = 16;
+
+       return parent_rate / (div * 2);
+}
+
+static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
+
+       rate = s3c2442_camif_upll_round(clk, rate);
+
+       camdivn &= ~S3C2442_CAMDIVN_CAMCLK_DIV3;
+
+       if (rate == parent_rate) {
+               camdivn &= ~S3C2440_CAMDIVN_CAMCLK_SEL;
+       } else if ((parent_rate / rate) == 3) {
+               camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+               camdivn |= S3C2442_CAMDIVN_CAMCLK_DIV3;
+       } else {
+               camdivn &= ~S3C2440_CAMDIVN_CAMCLK_MASK;
+               camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+               camdivn |= (((parent_rate / rate) / 2) - 1);
+       }
+
+       __raw_writel(camdivn, S3C2440_CAMDIVN);
+
+       return 0;
+}
+
+/* Extra S3C2442 clocks */
+
+static struct clk s3c2442_clk_cam = {
+       .name           = "camif",
+       .id             = -1,
+       .enable         = s3c2410_clkcon_enable,
+       .ctrlbit        = S3C2440_CLKCON_CAMERA,
+};
+
+static struct clk s3c2442_clk_cam_upll = {
+       .name           = "camif-upll",
+       .id             = -1,
+       .ops            = &(struct clk_ops) {
+               .set_rate       = s3c2442_camif_upll_setrate,
+               .round_rate     = s3c2442_camif_upll_round,
+       },
+};
+
+static int s3c2442_clk_add(struct device *dev, struct subsys_interface *sif)
+{
+       struct clk *clock_upll;
+       struct clk *clock_h;
+       struct clk *clock_p;
+
+       clock_p = clk_get(NULL, "pclk");
+       clock_h = clk_get(NULL, "hclk");
+       clock_upll = clk_get(NULL, "upll");
+
+       if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
+               printk(KERN_ERR "S3C2442: Failed to get parent clocks\n");
+               return -EINVAL;
+       }
+
+       s3c2442_clk_cam.parent = clock_h;
+       s3c2442_clk_cam_upll.parent = clock_upll;
+
+       s3c24xx_register_clock(&s3c2442_clk_cam);
+       s3c24xx_register_clock(&s3c2442_clk_cam_upll);
+
+       clk_disable(&s3c2442_clk_cam);
+
+       return 0;
+}
+
+static struct subsys_interface s3c2442_clk_interface = {
+       .name           = "s3c2442_clk",
+       .subsys         = &s3c2442_subsys,
+       .add_dev        = s3c2442_clk_add,
+};
+
+static __init int s3c2442_clk_init(void)
+{
+       return subsys_interface_register(&s3c2442_clk_interface);
+}
+
+arch_initcall(s3c2442_clk_init);
+
+
+static struct device s3c2442_dev = {
+       .bus            = &s3c2442_subsys,
+};
+
+int __init s3c2442_init(void)
+{
+       printk("S3C2442: Initialising architecture\n");
+
+#ifdef CONFIG_PM
+       register_syscore_ops(&s3c2410_pm_syscore_ops);
+#endif
+       register_syscore_ops(&s3c244x_pm_syscore_ops);
+       register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
+       return device_register(&s3c2442_dev);
+}
+
+void __init s3c2442_map_io(void)
+{
+       s3c244x_map_io();
+
+       s3c24xx_gpiocfg_default.set_pull = s3c24xx_gpio_setpull_1down;
+       s3c24xx_gpiocfg_default.get_pull = s3c24xx_gpio_getpull_1down;
+}
diff --git a/arch/arm/mach-s3c24xx/s3c2443.c b/arch/arm/mach-s3c24xx/s3c2443.c
new file mode 100644 (file)
index 0000000..b7778a9
--- /dev/null
@@ -0,0 +1,116 @@
+/* linux/arch/arm/mach-s3c2443/s3c2443.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2443 Mobile CPU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <plat/s3c2443.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/fb-core.h>
+#include <plat/nand-core.h>
+#include <plat/adc-core.h>
+#include <plat/rtc-core.h>
+
+static struct map_desc s3c2443_iodesc[] __initdata = {
+       IODESC_ENT(WATCHDOG),
+       IODESC_ENT(CLKPWR),
+       IODESC_ENT(TIMER),
+};
+
+struct bus_type s3c2443_subsys = {
+       .name = "s3c2443-core",
+       .dev_name = "s3c2443-core",
+};
+
+static struct device s3c2443_dev = {
+       .bus            = &s3c2443_subsys,
+};
+
+void s3c2443_restart(char mode, const char *cmd)
+{
+       if (mode == 's')
+               soft_restart(0);
+
+       __raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST);
+}
+
+int __init s3c2443_init(void)
+{
+       printk("S3C2443: Initialising architecture\n");
+
+       s3c_nand_setname("s3c2412-nand");
+       s3c_fb_setname("s3c2443-fb");
+
+       s3c_adc_setname("s3c2443-adc");
+       s3c_rtc_setname("s3c2443-rtc");
+
+       /* change WDT IRQ number */
+       s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT;
+       s3c_device_wdt.resource[1].end   = IRQ_S3C2443_WDT;
+
+       return device_register(&s3c2443_dev);
+}
+
+void __init s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+       s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
+}
+
+/* s3c2443_map_io
+ *
+ * register the standard cpu IO areas, and any passed in from the
+ * machine specific initialisation.
+ */
+
+void __init s3c2443_map_io(void)
+{
+       s3c24xx_gpiocfg_default.set_pull = s3c2443_gpio_setpull;
+       s3c24xx_gpiocfg_default.get_pull = s3c2443_gpio_getpull;
+
+       iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc));
+}
+
+/* need to register the subsystem before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2443 based system)
+ * as a driver which may support both 2443 and 2440 may try and use it.
+*/
+
+static int __init s3c2443_core_init(void)
+{
+       return subsys_system_register(&s3c2443_subsys, NULL);
+}
+
+core_initcall(s3c2443_core_init);
diff --git a/arch/arm/mach-s3c24xx/s3c244x.c b/arch/arm/mach-s3c24xx/s3c244x.c
new file mode 100644 (file)
index 0000000..d15852f
--- /dev/null
@@ -0,0 +1,210 @@
+/* linux/arch/arm/plat-s3c24xx/s3c244x.c
+ *
+ * Copyright (c) 2004-2006 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2440 and S3C2442 Mobile CPU support (not S3C2443)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+
+#include <mach/regs-clock.h>
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-gpioj.h>
+#include <mach/regs-dsc.h>
+
+#include <plat/s3c2410.h>
+#include <plat/s3c244x.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/pll.h>
+#include <plat/nand-core.h>
+#include <plat/watchdog-reset.h>
+
+static struct map_desc s3c244x_iodesc[] __initdata = {
+       IODESC_ENT(CLKPWR),
+       IODESC_ENT(TIMER),
+       IODESC_ENT(WATCHDOG),
+};
+
+/* uart initialisation */
+
+void __init s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+       s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
+}
+
+void __init s3c244x_map_io(void)
+{
+       /* register our io-tables */
+
+       iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc));
+
+       /* rename any peripherals used differing from the s3c2410 */
+
+       s3c_device_sdi.name  = "s3c2440-sdi";
+       s3c_device_i2c0.name  = "s3c2440-i2c";
+       s3c_nand_setname("s3c2440-nand");
+       s3c_device_ts.name = "s3c2440-ts";
+       s3c_device_usbgadget.name = "s3c2440-usbgadget";
+}
+
+void __init_or_cpufreq s3c244x_setup_clocks(void)
+{
+       struct clk *xtal_clk;
+       unsigned long clkdiv;
+       unsigned long camdiv;
+       unsigned long xtal;
+       unsigned long hclk, fclk, pclk;
+       int hdiv = 1;
+
+       xtal_clk = clk_get(NULL, "xtal");
+       xtal = clk_get_rate(xtal_clk);
+       clk_put(xtal_clk);
+
+       fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
+
+       clkdiv = __raw_readl(S3C2410_CLKDIVN);
+       camdiv = __raw_readl(S3C2440_CAMDIVN);
+
+       /* work out clock scalings */
+
+       switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
+       case S3C2440_CLKDIVN_HDIVN_1:
+               hdiv = 1;
+               break;
+
+       case S3C2440_CLKDIVN_HDIVN_2:
+               hdiv = 2;
+               break;
+
+       case S3C2440_CLKDIVN_HDIVN_4_8:
+               hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
+               break;
+
+       case S3C2440_CLKDIVN_HDIVN_3_6:
+               hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
+               break;
+       }
+
+       hclk = fclk / hdiv;
+       pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN) ? 2 : 1);
+
+       /* print brief summary of clocks, etc */
+
+       printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
+              print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
+
+       s3c24xx_setup_clocks(fclk, hclk, pclk);
+}
+
+void __init s3c244x_init_clocks(int xtal)
+{
+       /* initialise the clocks here, to allow other things like the
+        * console to use them, and to add new ones after the initialisation
+        */
+
+       s3c24xx_register_baseclocks(xtal);
+       s3c244x_setup_clocks();
+       s3c2410_baseclk_add();
+}
+
+/* Since the S3C2442 and S3C2440 share items, put both subsystems here */
+
+struct bus_type s3c2440_subsys = {
+       .name           = "s3c2440-core",
+       .dev_name       = "s3c2440-core",
+};
+
+struct bus_type s3c2442_subsys = {
+       .name           = "s3c2442-core",
+       .dev_name       = "s3c2442-core",
+};
+
+/* need to register the subsystem before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2440 based system)
+ * as a driver which may support both 2410 and 2440 may try and use it.
+*/
+
+static int __init s3c2440_core_init(void)
+{
+       return subsys_system_register(&s3c2440_subsys, NULL);
+}
+
+core_initcall(s3c2440_core_init);
+
+static int __init s3c2442_core_init(void)
+{
+       return subsys_system_register(&s3c2442_subsys, NULL);
+}
+
+core_initcall(s3c2442_core_init);
+
+
+#ifdef CONFIG_PM
+static struct sleep_save s3c244x_sleep[] = {
+       SAVE_ITEM(S3C2440_DSC0),
+       SAVE_ITEM(S3C2440_DSC1),
+       SAVE_ITEM(S3C2440_GPJDAT),
+       SAVE_ITEM(S3C2440_GPJCON),
+       SAVE_ITEM(S3C2440_GPJUP)
+};
+
+static int s3c244x_suspend(void)
+{
+       s3c_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+       return 0;
+}
+
+static void s3c244x_resume(void)
+{
+       s3c_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+}
+#else
+#define s3c244x_suspend NULL
+#define s3c244x_resume  NULL
+#endif
+
+struct syscore_ops s3c244x_pm_syscore_ops = {
+       .suspend        = s3c244x_suspend,
+       .resume         = s3c244x_resume,
+};
+
+void s3c244x_restart(char mode, const char *cmd)
+{
+       if (mode == 's')
+               soft_restart(0);
+
+       arch_wdt_reset();
+
+       /* we'll take a jump through zero as a poor second */
+       soft_restart(0);
+}
diff --git a/arch/arm/mach-s3c24xx/setup-i2c.c b/arch/arm/mach-s3c24xx/setup-i2c.c
new file mode 100644 (file)
index 0000000..9e90a7c
--- /dev/null
@@ -0,0 +1,27 @@
+/* linux/arch/arm/plat-s3c24xx/setup-i2c.c
+ *
+ * Copyright 2008 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX Base setup for i2c device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+
+struct platform_device;
+
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+{
+       s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA);
+       s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL);
+}
diff --git a/arch/arm/mach-s3c24xx/setup-sdhci-gpio.c b/arch/arm/mach-s3c24xx/setup-sdhci-gpio.c
new file mode 100644 (file)
index 0000000..f65cb3e
--- /dev/null
@@ -0,0 +1,34 @@
+/* linux/arch/arm/plat-s3c2416/setup-sdhci-gpio.c
+ *
+ * Copyright 2010 Promwad Innovation Company
+ *     Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+ *
+ * S3C2416 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
+ *
+ * Based on mach-s3c64xx/setup-sdhci-gpio.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/regs-gpio.h>
+#include <plat/gpio-cfg.h>
+
+void s3c2416_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
+{
+       s3c_gpio_cfgrange_nopull(S3C2410_GPE(5), 2 + width, S3C_GPIO_SFN(2));
+}
+
+void s3c2416_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
+{
+       s3c_gpio_cfgrange_nopull(S3C2410_GPL(0), width, S3C_GPIO_SFN(2));
+       s3c_gpio_cfgrange_nopull(S3C2410_GPL(8), 2, S3C_GPIO_SFN(2));
+}
diff --git a/arch/arm/mach-s3c24xx/setup-ts.c b/arch/arm/mach-s3c24xx/setup-ts.c
new file mode 100644 (file)
index 0000000..ed26386
--- /dev/null
@@ -0,0 +1,34 @@
+/* linux/arch/arm/plat-s3c24xx/setup-ts.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *                     http://www.samsung.com/
+ *
+ * Based on S3C24XX setup for i2c device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+
+/**
+ * s3c24xx_ts_cfg_gpio - configure gpio for s3c2410 systems
+ *
+ * Configure the GPIO for the S3C2410 system, where we have external FETs
+ * connected to the device (later systems such as the S3C2440 integrate
+ * these into the device).
+ */
+void s3c24xx_ts_cfg_gpio(struct platform_device *dev)
+{
+       s3c2410_gpio_cfgpin(S3C2410_GPG(12), S3C2410_GPG12_XMON);
+       s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPG13_nXPON);
+       s3c2410_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPG14_YMON);
+       s3c2410_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPG15_nYPON);
+}
diff --git a/arch/arm/mach-s3c24xx/simtec-audio.c b/arch/arm/mach-s3c24xx/simtec-audio.c
new file mode 100644 (file)
index 0000000..11881c9
--- /dev/null
@@ -0,0 +1,79 @@
+/* linux/arch/arm/plat-s3c24xx/simtec-audio.c
+ *
+ * Copyright (c) 2009 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Audio setup for various Simtec S3C24XX implementations
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/io.h>
+
+#include <mach/bast-map.h>
+#include <mach/bast-irq.h>
+#include <mach/bast-cpld.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/audio-simtec.h>
+#include <plat/devs.h>
+
+#include "simtec.h"
+
+/* platform ops for audio */
+
+static void simtec_audio_startup_lrroute(void)
+{
+       unsigned int tmp;
+       unsigned long flags;
+
+       local_irq_save(flags);
+
+       tmp = __raw_readb(BAST_VA_CTRL1);
+       tmp &= ~BAST_CPLD_CTRL1_LRMASK;
+       tmp |= BAST_CPLD_CTRL1_LRCDAC;
+       __raw_writeb(tmp, BAST_VA_CTRL1);
+
+       local_irq_restore(flags);
+}
+
+static struct s3c24xx_audio_simtec_pdata simtec_audio_platdata;
+static char our_name[32];
+
+static struct platform_device simtec_audio_dev = {
+       .name   = our_name,
+       .id     = -1,
+       .dev    = {
+               .parent         = &s3c_device_iis.dev,
+               .platform_data  = &simtec_audio_platdata,
+       },
+};
+
+int __init simtec_audio_add(const char *name, bool has_lr_routing,
+                           struct s3c24xx_audio_simtec_pdata *spd)
+{
+       if (!name)
+               name = "tlv320aic23";
+
+       snprintf(our_name, sizeof(our_name)-1, "s3c24xx-simtec-%s", name);
+
+       /* copy platform data so the source can be __initdata */
+       if (spd)
+               simtec_audio_platdata = *spd;
+
+       if (has_lr_routing)
+               simtec_audio_platdata.startup = simtec_audio_startup_lrroute;
+
+       platform_device_register(&s3c_device_iis);
+       platform_device_register(&simtec_audio_dev);
+       return 0;
+}
diff --git a/arch/arm/mach-s3c24xx/simtec-nor.c b/arch/arm/mach-s3c24xx/simtec-nor.c
new file mode 100644 (file)
index 0000000..2119ca6
--- /dev/null
@@ -0,0 +1,87 @@
+/* linux/arch/arm/mach-s3c2410/nor-simtec.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Simtec NOR mapping
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/map.h>
+#include <mach/bast-map.h>
+#include <mach/bast-cpld.h>
+
+#include "simtec.h"
+
+static void simtec_nor_vpp(struct platform_device *pdev, int vpp)
+{
+       unsigned int val;
+       unsigned long flags;
+
+       local_irq_save(flags);
+       val = __raw_readb(BAST_VA_CTRL3);
+
+       printk(KERN_DEBUG "%s(%d)\n", __func__, vpp);
+
+       if (vpp)
+               val |= BAST_CPLD_CTRL3_ROMWEN;
+       else
+               val &= ~BAST_CPLD_CTRL3_ROMWEN;
+
+       __raw_writeb(val, BAST_VA_CTRL3);
+       local_irq_restore(flags);
+}
+
+static struct physmap_flash_data simtec_nor_pdata = {
+       .width          = 2,
+       .set_vpp        = simtec_nor_vpp,
+       .nr_parts       = 0,
+};
+
+static struct resource simtec_nor_resource[] = {
+       [0] = {
+               .start = S3C2410_CS1 + 0x4000000,
+               .end   = S3C2410_CS1 + 0x4000000 + SZ_8M - 1,
+               .flags = IORESOURCE_MEM,
+       }
+};
+
+static struct platform_device simtec_device_nor = {
+       .name           = "physmap-flash",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(simtec_nor_resource),
+       .resource       = simtec_nor_resource,
+       .dev            = {
+               .platform_data = &simtec_nor_pdata,
+       },
+};
+
+void __init nor_simtec_init(void)
+{
+       int ret;
+
+       ret = platform_device_register(&simtec_device_nor);
+       if (ret < 0)
+               printk(KERN_ERR "failed to register physmap-flash device\n");
+       else
+               simtec_nor_vpp(NULL, 1);
+}
diff --git a/arch/arm/mach-s3c24xx/simtec-pm.c b/arch/arm/mach-s3c24xx/simtec-pm.c
new file mode 100644 (file)
index 0000000..699f931
--- /dev/null
@@ -0,0 +1,66 @@
+/* linux/arch/arm/plat-s3c24xx/pm-simtec.c
+ *
+ * Copyright 2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * Power Management helpers for Simtec S3C24XX implementations
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-mem.h>
+
+#include <asm/mach-types.h>
+
+#include <plat/pm.h>
+
+#define COPYRIGHT ", Copyright 2005 Simtec Electronics"
+
+/* pm_simtec_init
+ *
+ * enable the power management functions
+*/
+
+static __init int pm_simtec_init(void)
+{
+       unsigned long gstatus4;
+
+       /* check which machine we are running on */
+
+       if (!machine_is_bast() && !machine_is_vr1000() &&
+           !machine_is_anubis() && !machine_is_osiris() &&
+           !machine_is_aml_m5900())
+               return 0;
+
+       printk(KERN_INFO "Simtec Board Power Management" COPYRIGHT "\n");
+
+       gstatus4  = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30;
+       gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28;
+       gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK);
+
+       __raw_writel(gstatus4, S3C2410_GSTATUS4);
+
+       return s3c_pm_init();
+}
+
+arch_initcall(pm_simtec_init);
diff --git a/arch/arm/mach-s3c24xx/simtec-usb.c b/arch/arm/mach-s3c24xx/simtec-usb.c
new file mode 100644 (file)
index 0000000..d91c1a7
--- /dev/null
@@ -0,0 +1,132 @@
+/* linux/arch/arm/mach-s3c2410/usb-simtec.c
+ *
+ * Copyright 2004-2005 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.simtec.co.uk/products/EB2410ITX/
+ *
+ * Simtec BAST and Thorcom VR1000 USB port support functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define DEBUG
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/gpio.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/bast-map.h>
+#include <mach/bast-irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/usb-control.h>
+#include <plat/devs.h>
+
+#include "simtec.h"
+
+/* control power and monitor over-current events on various Simtec
+ * designed boards.
+*/
+
+static unsigned int power_state[2];
+
+static void
+usb_simtec_powercontrol(int port, int to)
+{
+       pr_debug("usb_simtec_powercontrol(%d,%d)\n", port, to);
+
+       power_state[port] = to;
+
+       if (power_state[0] && power_state[1])
+               gpio_set_value(S3C2410_GPB(4), 0);
+       else
+               gpio_set_value(S3C2410_GPB(4), 1);
+}
+
+static irqreturn_t
+usb_simtec_ocirq(int irq, void *pw)
+{
+       struct s3c2410_hcd_info *info = pw;
+
+       if (gpio_get_value(S3C2410_GPG(10)) == 0) {
+               pr_debug("usb_simtec: over-current irq (oc detected)\n");
+               s3c2410_usb_report_oc(info, 3);
+       } else {
+               pr_debug("usb_simtec: over-current irq (oc cleared)\n");
+               s3c2410_usb_report_oc(info, 0);
+       }
+
+       return IRQ_HANDLED;
+}
+
+static void usb_simtec_enableoc(struct s3c2410_hcd_info *info, int on)
+{
+       int ret;
+
+       if (on) {
+               ret = request_irq(IRQ_USBOC, usb_simtec_ocirq,
+                                 IRQF_DISABLED | IRQF_TRIGGER_RISING |
+                                  IRQF_TRIGGER_FALLING,
+                                 "USB Over-current", info);
+               if (ret != 0) {
+                       printk(KERN_ERR "failed to request usb oc irq\n");
+               }
+       } else {
+               free_irq(IRQ_USBOC, info);
+       }
+}
+
+static struct s3c2410_hcd_info usb_simtec_info __initdata = {
+       .port[0]        = {
+               .flags  = S3C_HCDFLG_USED
+       },
+       .port[1]        = {
+               .flags  = S3C_HCDFLG_USED
+       },
+
+       .power_control  = usb_simtec_powercontrol,
+       .enable_oc      = usb_simtec_enableoc,
+};
+
+
+int usb_simtec_init(void)
+{
+       int ret;
+
+       printk("USB Power Control, Copyright 2004 Simtec Electronics\n");
+
+       ret = gpio_request(S3C2410_GPB(4), "USB power control");
+       if (ret < 0) {
+               pr_err("%s: failed to get GPB4\n", __func__);
+               return ret;
+       }
+
+       ret = gpio_request(S3C2410_GPG(10), "USB overcurrent");
+       if (ret < 0) {
+               pr_err("%s: failed to get GPG10\n", __func__);
+               gpio_free(S3C2410_GPB(4));
+               return ret;
+       }
+
+       /* turn power on */
+       gpio_direction_output(S3C2410_GPB(4), 1);
+       gpio_direction_input(S3C2410_GPG(10));
+
+       s3c_ohci_set_platdata(&usb_simtec_info);
+       return 0;
+}
diff --git a/arch/arm/mach-s3c24xx/simtec.h b/arch/arm/mach-s3c24xx/simtec.h
new file mode 100644 (file)
index 0000000..ae8f4f9
--- /dev/null
@@ -0,0 +1,21 @@
+/* linux/arch/arm/mach-s3c2410/nor-simtec.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Simtec common functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct s3c24xx_audio_simtec_pdata;
+
+extern void nor_simtec_init(void);
+
+extern int usb_simtec_init(void);
+
+extern int simtec_audio_add(const char *codec_name, bool has_lr_routing,
+                           struct s3c24xx_audio_simtec_pdata *pdata);
diff --git a/arch/arm/mach-s3c24xx/sleep-s3c2410.S b/arch/arm/mach-s3c24xx/sleep-s3c2410.S
new file mode 100644 (file)
index 0000000..dd5b638
--- /dev/null
@@ -0,0 +1,68 @@
+/* linux/arch/arm/mach-s3c2410/sleep.S
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 Power Manager (Suspend-To-RAM) support
+ *
+ * Based on PXA/SA1100 sleep code by:
+ *     Nicolas Pitre, (c) 2002 Monta Vista Software Inc
+ *     Cliff Brake, (c) 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-mem.h>
+#include <plat/regs-serial.h>
+
+       /* s3c2410_cpu_suspend
+        *
+        * put the cpu into sleep mode
+       */
+
+ENTRY(s3c2410_cpu_suspend)
+       @@ prepare cpu to sleep
+
+       ldr     r4, =S3C2410_REFRESH
+       ldr     r5, =S3C24XX_MISCCR
+       ldr     r6, =S3C2410_CLKCON
+       ldr     r7, [ r4 ]              @ get REFRESH (and ensure in TLB)
+       ldr     r8, [ r5 ]              @ get MISCCR (and ensure in TLB)
+       ldr     r9, [ r6 ]              @ get CLKCON (and ensure in TLB)
+
+       orr     r7, r7, #S3C2410_REFRESH_SELF   @ SDRAM sleep command
+       orr     r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
+       orr     r9, r9, #S3C2410_CLKCON_POWER   @ power down command
+
+       teq     pc, #0                  @ first as a trial-run to load cache
+       bl      s3c2410_do_sleep
+       teq     r0, r0                  @ now do it for real
+       b       s3c2410_do_sleep        @
+
+       @@ align next bit of code to cache line
+       .align  5
+s3c2410_do_sleep:
+       streq   r7, [ r4 ]                      @ SDRAM sleep command
+       streq   r8, [ r5 ]                      @ SDRAM power-down config
+       streq   r9, [ r6 ]                      @ CPU sleep
+1:     beq     1b
+       mov     pc, r14
diff --git a/arch/arm/mach-s3c24xx/sleep-s3c2412.S b/arch/arm/mach-s3c24xx/sleep-s3c2412.S
new file mode 100644 (file)
index 0000000..c82418e
--- /dev/null
@@ -0,0 +1,68 @@
+/* linux/arch/arm/mach-s3c2412/sleep.S
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2412 Power Manager low-level sleep support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <mach/regs-irq.h>
+
+       .text
+
+       .global s3c2412_sleep_enter
+
+s3c2412_sleep_enter:
+       mov     r0, #0                  /* argument for coprocessors */
+       ldr     r1, =S3C2410_INTPND
+       ldr     r2, =S3C2410_SRCPND
+       ldr     r3, =S3C2410_EINTPEND
+
+       teq     r0, r0
+       bl      s3c2412_sleep_enter1
+       teq     pc, r0
+       bl      s3c2412_sleep_enter1
+
+       .align  5
+
+       /* this is called twice, first with the Z flag to ensure that the
+        * instructions have been loaded into the cache, and the second
+        * time to try and suspend the system.
+       */
+s3c2412_sleep_enter1:
+       mcr     p15, 0, r0, c7, c10, 4
+       mcrne   p15, 0, r0, c7, c0, 4
+
+       /* if we return from here, it is because an interrupt was
+        * active when we tried to shutdown. Try and ack the IRQ and
+        * retry, as simply returning causes the system to lock.
+       */
+
+       ldrne   r9, [ r1 ]
+       strne   r9, [ r1 ]
+       ldrne   r9, [ r2 ]
+       strne   r9, [ r2 ]
+       ldrne   r9, [ r3 ]
+       strne   r9, [ r3 ]
+       bne     s3c2412_sleep_enter1
+
+       mov     pc, r14
index dd20c66cd700b1a9739509245e92a6f91426a31f..82c0915729eeb1741c647ebe80a492d5df7475f1 100644 (file)
@@ -83,6 +83,11 @@ config S3C64XX_SETUP_SPI
        help
         Common setup code for SPI GPIO configurations
 
+config S3C64XX_SETUP_USB_PHY
+       bool
+       help
+         Common setup code for USB PHY controller
+
 # S36400 Macchine support
 
 config MACH_SMDK6400
@@ -157,6 +162,7 @@ config MACH_SMDK6410
        select S3C64XX_SETUP_IDE
        select S3C64XX_SETUP_FB_24BPP
        select S3C64XX_SETUP_KEYPAD
+       select S3C64XX_SETUP_USB_PHY
        help
          Machine support for the Samsung SMDK6410
 
@@ -256,6 +262,7 @@ config MACH_SMARTQ
        select S3C_DEV_USB_HOST
        select S3C64XX_SETUP_SDHCI
        select S3C64XX_SETUP_FB_24BPP
+       select S3C64XX_SETUP_USB_PHY
        select SAMSUNG_DEV_ADC
        select SAMSUNG_DEV_PWM
        select SAMSUNG_DEV_TS
@@ -283,6 +290,7 @@ config MACH_WLF_CRAGG_6410
        select S3C64XX_SETUP_FB_24BPP
        select S3C64XX_SETUP_KEYPAD
        select S3C64XX_SETUP_SPI
+       select S3C64XX_SETUP_USB_PHY
        select SAMSUNG_DEV_ADC
        select SAMSUNG_DEV_KEYPAD
        select S3C_DEV_USB_HOST
@@ -296,5 +304,6 @@ config MACH_WLF_CRAGG_6410
        select S3C64XX_DEV_SPI0
        select SAMSUNG_GPIO_EXTRA128
        select I2C
+       select LEDS_GPIO_REGISTER
        help
          Machine support for the Wolfson Cragganmore S3C6410 variant.
index 1822ac2eba318250f8b0cfd4163f516b18184eac..f9ce1dc28ce47692881233333ed472e4de8557a3 100644 (file)
@@ -22,6 +22,7 @@ obj-$(CONFIG_CPU_S3C6410)     += s3c6410.o
 # PM
 
 obj-$(CONFIG_PM)               += pm.o irq-pm.o sleep.o
+obj-$(CONFIG_CPU_IDLE)         += cpuidle.o
 
 # DMA support
 
@@ -42,6 +43,7 @@ obj-$(CONFIG_S3C64XX_SETUP_IDE)               += setup-ide.o
 obj-$(CONFIG_S3C64XX_SETUP_KEYPAD)     += setup-keypad.o
 obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
 obj-$(CONFIG_S3C64XX_SETUP_SPI)                += setup-spi.o
+obj-$(CONFIG_S3C64XX_SETUP_USB_PHY) += setup-usb-phy.o
 
 # Machine support
 
index aebbcc291b4e2ae35c5d8dee6035002fa038bd49..52f079a691cb4627b66eb6fa4bb7ad2d14327e9a 100644 (file)
@@ -206,6 +206,15 @@ static struct clk init_clocks_off[] = {
                .parent         = &clk_48m,
                .enable         = s3c64xx_sclk_ctrl,
                .ctrlbit        = S3C_CLKCON_SCLK_MMC2_48,
+       }, {
+               .name           = "ac97",
+               .parent         = &clk_p,
+               .ctrlbit        = S3C_CLKCON_PCLK_AC97,
+       }, {
+               .name           = "cfcon",
+               .parent         = &clk_h,
+               .enable         = s3c64xx_hclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_HCLK_IHOST,
        }, {
                .name           = "dma0",
                .parent         = &clk_h,
@@ -216,6 +225,107 @@ static struct clk init_clocks_off[] = {
                .parent         = &clk_h,
                .enable         = s3c64xx_hclk_ctrl,
                .ctrlbit        = S3C_CLKCON_HCLK_DMA1,
+       }, {
+               .name           = "3dse",
+               .parent         = &clk_h,
+               .enable         = s3c64xx_hclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_HCLK_3DSE,
+       }, {
+               .name           = "hclk_secur",
+               .parent         = &clk_h,
+               .enable         = s3c64xx_hclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_HCLK_SECUR,
+       }, {
+               .name           = "sdma1",
+               .parent         = &clk_h,
+               .enable         = s3c64xx_hclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_HCLK_SDMA1,
+       }, {
+               .name           = "sdma0",
+               .parent         = &clk_h,
+               .enable         = s3c64xx_hclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_HCLK_SDMA0,
+       }, {
+               .name           = "hclk_jpeg",
+               .parent         = &clk_h,
+               .enable         = s3c64xx_hclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_HCLK_JPEG,
+       }, {
+               .name           = "camif",
+               .parent         = &clk_h,
+               .enable         = s3c64xx_hclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_HCLK_CAMIF,
+       }, {
+               .name           = "hclk_scaler",
+               .parent         = &clk_h,
+               .enable         = s3c64xx_hclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_HCLK_SCALER,
+       }, {
+               .name           = "2d",
+               .parent         = &clk_h,
+               .enable         = s3c64xx_hclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_HCLK_2D,
+       }, {
+               .name           = "tv",
+               .parent         = &clk_h,
+               .enable         = s3c64xx_hclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_HCLK_TV,
+       }, {
+               .name           = "post0",
+               .parent         = &clk_h,
+               .enable         = s3c64xx_hclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_HCLK_POST0,
+       }, {
+               .name           = "rot",
+               .parent         = &clk_h,
+               .enable         = s3c64xx_hclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_HCLK_ROT,
+       }, {
+               .name           = "hclk_mfc",
+               .parent         = &clk_h,
+               .enable         = s3c64xx_hclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_HCLK_MFC,
+       }, {
+               .name           = "pclk_mfc",
+               .parent         = &clk_p,
+               .enable         = s3c64xx_pclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_PCLK_MFC,
+       }, {
+               .name           = "dac27",
+               .enable         = s3c64xx_sclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_SCLK_DAC27,
+       }, {
+               .name           = "tv27",
+               .enable         = s3c64xx_sclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_SCLK_TV27,
+       }, {
+               .name           = "scaler27",
+               .enable         = s3c64xx_sclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_SCLK_SCALER27,
+       }, {
+               .name           = "sclk_scaler",
+               .enable         = s3c64xx_sclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_SCLK_SCALER,
+       }, {
+               .name           = "post0_27",
+               .enable         = s3c64xx_sclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_SCLK_POST0_27,
+       }, {
+               .name           = "secur",
+               .enable         = s3c64xx_sclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_SCLK_SECUR,
+       }, {
+               .name           = "sclk_mfc",
+               .enable         = s3c64xx_sclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_SCLK_MFC,
+       }, {
+               .name           = "cam",
+               .enable         = s3c64xx_sclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_SCLK_CAM,
+       }, {
+               .name           = "sclk_jpeg",
+               .enable         = s3c64xx_sclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_SCLK_JPEG,
        },
 };
 
@@ -289,16 +399,7 @@ static struct clk init_clocks[] = {
                .name           = "watchdog",
                .parent         = &clk_p,
                .ctrlbit        = S3C_CLKCON_PCLK_WDT,
-       }, {
-               .name           = "ac97",
-               .parent         = &clk_p,
-               .ctrlbit        = S3C_CLKCON_PCLK_AC97,
-       }, {
-               .name           = "cfcon",
-               .parent         = &clk_h,
-               .enable         = s3c64xx_hclk_ctrl,
-               .ctrlbit        = S3C_CLKCON_HCLK_IHOST,
-       }
+       },
 };
 
 static struct clk clk_hsmmc0 = {
index 5eb9c9a7d73b3d8dd3123e88bedd2382d37f2f9c..7a10be629aba26723cb51bc28d460a0a5dc4ef53 100644 (file)
@@ -25,8 +25,6 @@ void s3c64xx_setup_clocks(void);
 
 void s3c64xx_restart(char mode, const char *cmd);
 
-extern struct syscore_ops s3c64xx_irq_syscore_ops;
-
 #ifdef CONFIG_CPU_S3C6400
 
 extern  int s3c6400_init(void);
diff --git a/arch/arm/mach-s3c64xx/cpuidle.c b/arch/arm/mach-s3c64xx/cpuidle.c
new file mode 100644 (file)
index 0000000..179460f
--- /dev/null
@@ -0,0 +1,91 @@
+/* linux/arch/arm/mach-s3c64xx/cpuidle.c
+ *
+ * Copyright (c) 2011 Wolfson Microelectronics, plc
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/cpuidle.h>
+#include <linux/io.h>
+#include <linux/export.h>
+#include <linux/time.h>
+
+#include <asm/proc-fns.h>
+
+#include <mach/map.h>
+
+#include <mach/regs-sys.h>
+#include <mach/regs-syscon-power.h>
+
+static int s3c64xx_enter_idle(struct cpuidle_device *dev,
+                             struct cpuidle_driver *drv,
+                             int index)
+{
+       struct timeval before, after;
+       unsigned long tmp;
+       int idle_time;
+
+       local_irq_disable();
+       do_gettimeofday(&before);
+
+       /* Setup PWRCFG to enter idle mode */
+       tmp = __raw_readl(S3C64XX_PWR_CFG);
+       tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
+       tmp |= S3C64XX_PWRCFG_CFG_WFI_IDLE;
+       __raw_writel(tmp, S3C64XX_PWR_CFG);
+
+       cpu_do_idle();
+
+       do_gettimeofday(&after);
+       local_irq_enable();
+       idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+                   (after.tv_usec - before.tv_usec);
+
+       dev->last_residency = idle_time;
+       return index;
+}
+
+static struct cpuidle_state s3c64xx_cpuidle_set[] = {
+       [0] = {
+               .enter                  = s3c64xx_enter_idle,
+               .exit_latency           = 1,
+               .target_residency       = 1,
+               .flags                  = CPUIDLE_FLAG_TIME_VALID,
+               .name                   = "IDLE",
+               .desc                   = "System active, ARM gated",
+       },
+};
+
+static struct cpuidle_driver s3c64xx_cpuidle_driver = {
+       .name           = "s3c64xx_cpuidle",
+       .owner          = THIS_MODULE,
+       .state_count    = ARRAY_SIZE(s3c64xx_cpuidle_set),
+};
+
+static struct cpuidle_device s3c64xx_cpuidle_device = {
+       .state_count    = ARRAY_SIZE(s3c64xx_cpuidle_set),
+};
+
+static int __init s3c64xx_init_cpuidle(void)
+{
+       int ret;
+
+       memcpy(s3c64xx_cpuidle_driver.states, s3c64xx_cpuidle_set,
+              sizeof(s3c64xx_cpuidle_set));
+       cpuidle_register_driver(&s3c64xx_cpuidle_driver);
+
+       ret = cpuidle_register_device(&s3c64xx_cpuidle_device);
+       if (ret) {
+               pr_err("Failed to register cpuidle device: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+device_initcall(s3c64xx_init_cpuidle);
index 8bec61e242c7a73b287a3db9b03e5f1b499180ed..0c7e1d960ca49f025bd1412039f2b0c21a142fa4 100644 (file)
@@ -96,7 +96,7 @@ static void s3c64xx_irq_pm_resume(void)
        S3C_PMDBG("%s: IRQ configuration restored\n", __func__);
 }
 
-struct syscore_ops s3c64xx_irq_syscore_ops = {
+static struct syscore_ops s3c64xx_irq_syscore_ops = {
        .suspend = s3c64xx_irq_pm_suspend,
        .resume  = s3c64xx_irq_pm_resume,
 };
index 32a30f38ba0ce65d243a7d3f6cbeaa70bf08dbec..b6a67728cc88f957a9ee7513596fd2e41cedf3be 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
+#include <linux/spi/spi.h>
 
 #include <linux/mfd/wm831x/irq.h>
 #include <linux/mfd/wm831x/gpio.h>
 #include <sound/wm8962.h>
 #include <sound/wm9081.h>
 
+#include <plat/s3c64xx-spi.h>
+
 #include <mach/crag6410.h>
 
+static struct s3c64xx_spi_csinfo wm0010_spi_csinfo = {
+       .set_level = gpio_set_value,
+       .line = S3C64XX_GPC(3),
+};
+
+static struct spi_board_info wm1253_devs[] = {
+       [0] = {
+               .modalias       = "wm0010",
+               .bus_num        = 0,
+               .chip_select    = 0,
+               .mode           = SPI_MODE_0,
+               .controller_data = &wm0010_spi_csinfo,
+       },
+};
+
 static struct wm5100_pdata wm5100_pdata = {
        .ldo_ena = S3C64XX_GPN(7),
        .irq_flags = IRQF_TRIGGER_HIGH,
@@ -159,14 +177,21 @@ static __devinitdata const struct {
        const char *name;
        const struct i2c_board_info *i2c_devs;
        int num_i2c_devs;
+       const struct spi_board_info *spi_devs;
+       int num_spi_devs;
 } gf_mods[] = {
        { .id = 0x01, .name = "1250-EV1 Springbank" },
        { .id = 0x02, .name = "1251-EV1 Jura" },
        { .id = 0x03, .name = "1252-EV1 Glenlivet" },
        { .id = 0x11, .name = "6249-EV2 Glenfarclas", },
+       { .id = 0x14, .name = "6271-EV1 Lochnagar" },
+       { .id = 0x15, .name = "XXXX-EV1 Bells" },
        { .id = 0x21, .name = "1275-EV1 Mortlach" },
        { .id = 0x25, .name = "1274-EV1 Glencadam" },
-       { .id = 0x31, .name = "1253-EV1 Tomatin", },
+       { .id = 0x31, .name = "1253-EV1 Tomatin",
+         .spi_devs = wm1253_devs, .num_spi_devs = ARRAY_SIZE(wm1253_devs) },
+       { .id = 0x32, .name = "XXXX-EV1 Caol Illa" },
+       { .id = 0x33, .name = "XXXX-EV1 Oban" },
        { .id = 0x39, .name = "1254-EV1 Dallas Dhu",
          .i2c_devs = wm1254_devs, .num_i2c_devs = ARRAY_SIZE(wm1254_devs) },
        { .id = 0x3a, .name = "1259-EV1 Tobermory",
@@ -198,12 +223,16 @@ static __devinit int wlf_gf_module_probe(struct i2c_client *i2c,
        if (i < ARRAY_SIZE(gf_mods)) {
                dev_info(&i2c->dev, "%s revision %d\n",
                         gf_mods[i].name, rev + 1);
+
                for (j = 0; j < gf_mods[i].num_i2c_devs; j++) {
                        if (!i2c_new_device(i2c->adapter,
                                            &(gf_mods[i].i2c_devs[j])))
                                dev_err(&i2c->dev,
                                        "Failed to register dev: %d\n", ret);
                }
+
+               spi_register_board_info(gf_mods[i].spi_devs,
+                                       gf_mods[i].num_spi_devs);
        } else {
                dev_warn(&i2c->dev, "Unknown module ID 0x%x revision %d\n",
                         id, rev + 1);
index 8077f650eb0e6c291ac607aff70a02b35dfa62b8..e20bf58353652fdc6d39d852c696f85e206ad68f 100644 (file)
@@ -19,7 +19,9 @@
 #include <linux/io.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
+#include <linux/leds.h>
 #include <linux/delay.h>
+#include <linux/mmc/host.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
 #include <linux/pwm_backlight.h>
@@ -59,6 +61,7 @@
 #include <plat/sdhci.h>
 #include <plat/gpio-cfg.h>
 #include <plat/s3c64xx-spi.h>
+#include <plat/udc-hs.h>
 
 #include <plat/keypad.h>
 #include <plat/clock.h>
@@ -298,6 +301,7 @@ static struct platform_device littlemill_device = {
 };
 
 static struct regulator_consumer_supply wallvdd_consumers[] = {
+       REGULATOR_SUPPLY("SPKVDD", "1-001a"),
        REGULATOR_SUPPLY("SPKVDD1", "1-001a"),
        REGULATOR_SUPPLY("SPKVDD2", "1-001a"),
        REGULATOR_SUPPLY("SPKVDDL", "1-001a"),
@@ -574,11 +578,19 @@ static struct s3c2410_platform_i2c i2c0_pdata = {
        .frequency = 400000,
 };
 
+static struct regulator_consumer_supply pvdd_1v2_consumers[] __initdata = {
+       REGULATOR_SUPPLY("DCVDD", "spi0.0"),
+       REGULATOR_SUPPLY("AVDD", "spi0.0"),
+};
+
 static struct regulator_init_data pvdd_1v2 __initdata = {
        .constraints = {
                .name = "PVDD_1V2",
-               .always_on = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
        },
+
+       .consumer_supplies = pvdd_1v2_consumers,
+       .num_consumer_supplies = ARRAY_SIZE(pvdd_1v2_consumers),
 };
 
 static struct regulator_consumer_supply pvdd_1v8_consumers[] __initdata = {
@@ -592,6 +604,7 @@ static struct regulator_consumer_supply pvdd_1v8_consumers[] __initdata = {
        REGULATOR_SUPPLY("AVDD2", "1-001a"),
        REGULATOR_SUPPLY("DCVDD", "1-001a"),
        REGULATOR_SUPPLY("AVDD", "1-001a"),
+       REGULATOR_SUPPLY("DBVDD", "spi0.0"),
 };
 
 static struct regulator_init_data pvdd_1v8 __initdata = {
@@ -681,6 +694,7 @@ static void __init crag6410_map_io(void)
 static struct s3c_sdhci_platdata crag6410_hsmmc2_pdata = {
        .max_width              = 4,
        .cd_type                = S3C_SDHCI_CD_PERMANENT,
+       .host_caps              = MMC_CAP_POWER_OFF_CARD,
 };
 
 static void crag6410_cfg_sdhci0(struct platform_device *dev, int width)
@@ -696,8 +710,59 @@ static struct s3c_sdhci_platdata crag6410_hsmmc0_pdata = {
        .max_width              = 4,
        .cd_type                = S3C_SDHCI_CD_INTERNAL,
        .cfg_gpio               = crag6410_cfg_sdhci0,
+       .host_caps              = MMC_CAP_POWER_OFF_CARD,
+};
+
+static const struct gpio_led gpio_leds[] = {
+       {
+               .name = "d13:green:",
+               .gpio = MMGPIO_GPIO_BASE + 0,
+               .default_state = LEDS_GPIO_DEFSTATE_ON,
+       },
+       {
+               .name = "d14:green:",
+               .gpio = MMGPIO_GPIO_BASE + 1,
+               .default_state = LEDS_GPIO_DEFSTATE_ON,
+       },
+       {
+               .name = "d15:green:",
+               .gpio = MMGPIO_GPIO_BASE + 2,
+               .default_state = LEDS_GPIO_DEFSTATE_ON,
+       },
+       {
+               .name = "d16:green:",
+               .gpio = MMGPIO_GPIO_BASE + 3,
+               .default_state = LEDS_GPIO_DEFSTATE_ON,
+       },
+       {
+               .name = "d17:green:",
+               .gpio = MMGPIO_GPIO_BASE + 4,
+               .default_state = LEDS_GPIO_DEFSTATE_ON,
+       },
+       {
+               .name = "d18:green:",
+               .gpio = MMGPIO_GPIO_BASE + 5,
+               .default_state = LEDS_GPIO_DEFSTATE_ON,
+       },
+       {
+               .name = "d19:green:",
+               .gpio = MMGPIO_GPIO_BASE + 6,
+               .default_state = LEDS_GPIO_DEFSTATE_ON,
+       },
+       {
+               .name = "d20:green:",
+               .gpio = MMGPIO_GPIO_BASE + 7,
+               .default_state = LEDS_GPIO_DEFSTATE_ON,
+       },
 };
 
+static const struct gpio_led_platform_data gpio_leds_pdata = {
+       .leds = gpio_leds,
+       .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct s3c_hsotg_plat crag6410_hsotg_pdata;
+
 static void __init crag6410_machine_init(void)
 {
        /* Open drain IRQs need pullups */
@@ -722,14 +787,18 @@ static void __init crag6410_machine_init(void)
        s3c_i2c0_set_platdata(&i2c0_pdata);
        s3c_i2c1_set_platdata(&i2c1_pdata);
        s3c_fb_set_platdata(&crag6410_lcd_pdata);
+       s3c_hsotg_set_platdata(&crag6410_hsotg_pdata);
 
        i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
        i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
 
        samsung_keypad_set_platdata(&crag6410_keypad_data);
+       s3c64xx_spi0_set_platdata(&s3c64xx_spi0_pdata, 0, 1);
 
        platform_add_devices(crag6410_devices, ARRAY_SIZE(crag6410_devices));
 
+       gpio_led_register_device(-1, &gpio_leds_pdata);
+
        regulator_has_full_constraints();
 
        s3c64xx_pm_init();
index ce31db136231774e5fda9da7ab1a8103209be02c..ce745e19aa2756e5a0bbc3f5094bc1ceba08060b 100644 (file)
@@ -187,6 +187,8 @@ static struct s3c_hwmon_pdata smartq_hwmon_pdata __initdata = {
        },
 };
 
+static struct s3c_hsotg_plat smartq_hsotg_pdata;
+
 static int __init smartq_lcd_setup_gpio(void)
 {
        int ret;
@@ -383,6 +385,7 @@ void __init smartq_map_io(void)
 void __init smartq_machine_init(void)
 {
        s3c_i2c0_set_platdata(NULL);
+       s3c_hsotg_set_platdata(&smartq_hsotg_pdata);
        s3c_hwmon_set_platdata(&smartq_hwmon_pdata);
        s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata);
        s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata);
index ca6fc204f0ea3317d0ac6a42a67aebe77409f484..d55bc96d9582f9d24301da64e64d90984c7c585a 100644 (file)
@@ -72,6 +72,7 @@
 #include <plat/keypad.h>
 #include <plat/backlight.h>
 #include <plat/regs-fb-v4.h>
+#include <plat/udc-hs.h>
 
 #include "common.h"
 
@@ -631,6 +632,8 @@ static struct platform_pwm_backlight_data smdk6410_bl_data = {
        .pwm_id = 1,
 };
 
+static struct s3c_hsotg_plat smdk6410_hsotg_pdata;
+
 static void __init smdk6410_map_io(void)
 {
        u32 tmp;
@@ -659,6 +662,7 @@ static void __init smdk6410_machine_init(void)
        s3c_i2c0_set_platdata(NULL);
        s3c_i2c1_set_platdata(NULL);
        s3c_fb_set_platdata(&smdk6410_lcd_pdata);
+       s3c_hsotg_set_platdata(&smdk6410_hsotg_pdata);
 
        samsung_keypad_set_platdata(&smdk6410_keypad_data);
 
diff --git a/arch/arm/mach-s3c64xx/setup-usb-phy.c b/arch/arm/mach-s3c64xx/setup-usb-phy.c
new file mode 100644 (file)
index 0000000..f6757e0
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <mach/map.h>
+#include <mach/regs-sys.h>
+#include <plat/cpu.h>
+#include <plat/regs-usb-hsotg-phy.h>
+#include <plat/usb-phy.h>
+
+static int s3c_usb_otgphy_init(struct platform_device *pdev)
+{
+       struct clk *xusbxti;
+       u32 phyclk;
+
+       writel(readl(S3C64XX_OTHERS) | S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS);
+
+       /* set clock frequency for PLL */
+       phyclk = readl(S3C_PHYCLK) & ~S3C_PHYCLK_CLKSEL_MASK;
+
+       xusbxti = clk_get(&pdev->dev, "xusbxti");
+       if (xusbxti && !IS_ERR(xusbxti)) {
+               switch (clk_get_rate(xusbxti)) {
+               case 12 * MHZ:
+                       phyclk |= S3C_PHYCLK_CLKSEL_12M;
+                       break;
+               case 24 * MHZ:
+                       phyclk |= S3C_PHYCLK_CLKSEL_24M;
+                       break;
+               default:
+               case 48 * MHZ:
+                       /* default reference clock */
+                       break;
+               }
+               clk_put(xusbxti);
+       }
+
+       /* TODO: select external clock/oscillator */
+       writel(phyclk | S3C_PHYCLK_CLK_FORCE, S3C_PHYCLK);
+
+       /* set to normal OTG PHY */
+       writel((readl(S3C_PHYPWR) & ~S3C_PHYPWR_NORMAL_MASK), S3C_PHYPWR);
+       mdelay(1);
+
+       /* reset OTG PHY and Link */
+       writel(S3C_RSTCON_PHY | S3C_RSTCON_HCLK | S3C_RSTCON_PHYCLK,
+                       S3C_RSTCON);
+       udelay(20);     /* at-least 10uS */
+       writel(0, S3C_RSTCON);
+
+       return 0;
+}
+
+static int s3c_usb_otgphy_exit(struct platform_device *pdev)
+{
+       writel((readl(S3C_PHYPWR) | S3C_PHYPWR_ANALOG_POWERDOWN |
+                               S3C_PHYPWR_OTG_DISABLE), S3C_PHYPWR);
+
+       writel(readl(S3C64XX_OTHERS) & ~S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS);
+
+       return 0;
+}
+
+int s5p_usb_phy_init(struct platform_device *pdev, int type)
+{
+       if (type == S5P_USB_PHY_DEVICE)
+               return s3c_usb_otgphy_init(pdev);
+
+       return -EINVAL;
+}
+
+int s5p_usb_phy_exit(struct platform_device *pdev, int type)
+{
+       if (type == S5P_USB_PHY_DEVICE)
+               return s3c_usb_otgphy_exit(pdev);
+
+       return -EINVAL;
+}
index 241d0e645c85d7998f4a8aa93a3cccd7c8ac16ab..57e718957ef347fe668d3d60a8c1387480c48315 100644 (file)
@@ -73,7 +73,7 @@ static const u32 clock_table[][3] = {
        {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P64X0_CLKDIV0_HCLK_SHIFT)},
 };
 
-unsigned long s5p64x0_armclk_get_rate(struct clk *clk)
+static unsigned long s5p64x0_armclk_get_rate(struct clk *clk)
 {
        unsigned long rate = clk_get_rate(clk->parent);
        u32 clkdiv;
@@ -84,7 +84,8 @@ unsigned long s5p64x0_armclk_get_rate(struct clk *clk)
        return rate / (clkdiv + 1);
 }
 
-unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate)
+static unsigned long s5p64x0_armclk_round_rate(struct clk *clk,
+                                              unsigned long rate)
 {
        u32 iter;
 
@@ -96,7 +97,7 @@ unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate)
        return clock_table[ARRAY_SIZE(clock_table) - 1][0];
 }
 
-int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate)
+static int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate)
 {
        u32 round_tmp;
        u32 iter;
@@ -148,7 +149,7 @@ int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate)
        return 0;
 }
 
-struct clk_ops s5p64x0_clkarm_ops = {
+static struct clk_ops s5p64x0_clkarm_ops = {
        .get_rate       = s5p64x0_armclk_get_rate,
        .set_rate       = s5p64x0_armclk_set_rate,
        .round_rate     = s5p64x0_armclk_round_rate,
@@ -173,7 +174,7 @@ struct clksrc_clk clk_dout_mpll = {
        .reg_div        = { .reg = S5P64X0_CLK_DIV0, .shift = 4, .size = 1 },
 };
 
-struct clk *clkset_hclk_low_list[] = {
+static struct clk *clkset_hclk_low_list[] = {
        &clk_mout_apll.clk,
        &clk_mout_mpll.clk,
 };
index f7f68ad77910662e494904d2f40db60b228b83a7..2ee5dc069b3754de7fdb922048a99c3d9156ee74 100644 (file)
@@ -38,7 +38,7 @@
 
 static u64 dma_dmamask = DMA_BIT_MASK(32);
 
-u8 s5p6440_pdma_peri[] = {
+static u8 s5p6440_pdma_peri[] = {
        DMACH_UART0_RX,
        DMACH_UART0_TX,
        DMACH_UART1_RX,
@@ -63,12 +63,12 @@ u8 s5p6440_pdma_peri[] = {
        DMACH_SPI1_RX,
 };
 
-struct dma_pl330_platdata s5p6440_pdma_pdata = {
+static struct dma_pl330_platdata s5p6440_pdma_pdata = {
        .nr_valid_peri = ARRAY_SIZE(s5p6440_pdma_peri),
        .peri_id = s5p6440_pdma_peri,
 };
 
-u8 s5p6450_pdma_peri[] = {
+static u8 s5p6450_pdma_peri[] = {
        DMACH_UART0_RX,
        DMACH_UART0_TX,
        DMACH_UART1_RX,
@@ -103,13 +103,13 @@ u8 s5p6450_pdma_peri[] = {
        DMACH_UART5_TX,
 };
 
-struct dma_pl330_platdata s5p6450_pdma_pdata = {
+static struct dma_pl330_platdata s5p6450_pdma_pdata = {
        .nr_valid_peri = ARRAY_SIZE(s5p6450_pdma_peri),
        .peri_id = s5p6450_pdma_peri,
 };
 
-AMBA_AHB_DEVICE(s5p64x0_pdma, "dma-pl330", 0x00041330, S5P64X0_PA_PDMA,
-       {IRQ_DMA0}, NULL);
+static AMBA_AHB_DEVICE(s5p64x0_pdma, "dma-pl330", 0x00041330,
+       S5P64X0_PA_PDMA, {IRQ_DMA0}, NULL);
 
 static int __init s5p64x0_dma_init(void)
 {
index ff85b4b6e8d97a7620210e0926b7789ef6a67bc6..0ef47d1b76701ca19ff137eba813c0e7bea3b518 100644 (file)
@@ -22,16 +22,9 @@ extern struct clksrc_clk clk_mout_epll;
 extern int s5p64x0_epll_enable(struct clk *clk, int enable);
 extern unsigned long s5p64x0_epll_get_rate(struct clk *clk);
 
-extern unsigned long s5p64x0_armclk_get_rate(struct clk *clk);
-extern unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate);
-extern int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate);
-
-extern struct clk_ops s5p64x0_clkarm_ops;
-
 extern struct clksrc_clk clk_armclk;
 extern struct clksrc_clk clk_dout_mpll;
 
-extern struct clk *clkset_hclk_low_list[];
 extern struct clksrc_sources clkset_hclk_low;
 
 extern int s5p64x0_pclk_ctrl(struct clk *clk, int enable);
index 247194dd366c202bfcf0bdbc583155b0eea675ff..16eca4ea201066b6498a503e1f53b1d4c0d7efd0 100644 (file)
@@ -170,7 +170,7 @@ static struct clk *clk_src_mout_am_list[] = {
        [1] = &clk_div_apll2.clk,
 };
 
-struct clksrc_sources clk_src_mout_am = {
+static struct clksrc_sources clk_src_mout_am = {
        .sources        = clk_src_mout_am_list,
        .nr_sources     = ARRAY_SIZE(clk_src_mout_am_list),
 };
@@ -212,7 +212,7 @@ static struct clk *clk_src_mout_onenand_list[] = {
        [1] = &clk_div_d1_bus.clk,
 };
 
-struct clksrc_sources clk_src_mout_onenand = {
+static struct clksrc_sources clk_src_mout_onenand = {
        .sources        = clk_src_mout_onenand_list,
        .nr_sources     = ARRAY_SIZE(clk_src_mout_onenand_list),
 };
@@ -756,7 +756,7 @@ static struct clk *clk_src_group1_list[] = {
        [3] = &clk_mout_hpll.clk,
 };
 
-struct clksrc_sources clk_src_group1 = {
+static struct clksrc_sources clk_src_group1 = {
        .sources        = clk_src_group1_list,
        .nr_sources     = ARRAY_SIZE(clk_src_group1_list),
 };
@@ -766,7 +766,7 @@ static struct clk *clk_src_group2_list[] = {
        [1] = &clk_div_mpll.clk,
 };
 
-struct clksrc_sources clk_src_group2 = {
+static struct clksrc_sources clk_src_group2 = {
        .sources        = clk_src_group2_list,
        .nr_sources     = ARRAY_SIZE(clk_src_group2_list),
 };
@@ -780,7 +780,7 @@ static struct clk *clk_src_group3_list[] = {
        [5] = &clk_mout_hpll.clk,
 };
 
-struct clksrc_sources clk_src_group3 = {
+static struct clksrc_sources clk_src_group3 = {
        .sources        = clk_src_group3_list,
        .nr_sources     = ARRAY_SIZE(clk_src_group3_list),
 };
@@ -806,7 +806,7 @@ static struct clk *clk_src_group4_list[] = {
        [5] = &clk_mout_hpll.clk,
 };
 
-struct clksrc_sources clk_src_group4 = {
+static struct clksrc_sources clk_src_group4 = {
        .sources        = clk_src_group4_list,
        .nr_sources     = ARRAY_SIZE(clk_src_group4_list),
 };
@@ -831,7 +831,7 @@ static struct clk *clk_src_group5_list[] = {
        [4] = &clk_mout_hpll.clk,
 };
 
-struct clksrc_sources clk_src_group5 = {
+static struct clksrc_sources clk_src_group5 = {
        .sources        = clk_src_group5_list,
        .nr_sources     = ARRAY_SIZE(clk_src_group5_list),
 };
@@ -854,7 +854,7 @@ static struct clk *clk_src_group6_list[] = {
        [2] = &clk_div_hdmi.clk,
 };
 
-struct clksrc_sources clk_src_group6 = {
+static struct clksrc_sources clk_src_group6 = {
        .sources        = clk_src_group6_list,
        .nr_sources     = ARRAY_SIZE(clk_src_group6_list),
 };
@@ -866,7 +866,7 @@ static struct clk *clk_src_group7_list[] = {
        [3] = &clk_vclk54m,
 };
 
-struct clksrc_sources clk_src_group7 = {
+static struct clksrc_sources clk_src_group7 = {
        .sources        = clk_src_group7_list,
        .nr_sources     = ARRAY_SIZE(clk_src_group7_list),
 };
@@ -877,7 +877,7 @@ static struct clk *clk_src_mmc0_list[] = {
        [2] = &clk_fin_epll,
 };
 
-struct clksrc_sources clk_src_mmc0 = {
+static struct clksrc_sources clk_src_mmc0 = {
        .sources        = clk_src_mmc0_list,
        .nr_sources     = ARRAY_SIZE(clk_src_mmc0_list),
 };
@@ -889,7 +889,7 @@ static struct clk *clk_src_mmc12_list[] = {
        [3] = &clk_mout_hpll.clk,
 };
 
-struct clksrc_sources clk_src_mmc12 = {
+static struct clksrc_sources clk_src_mmc12 = {
        .sources        = clk_src_mmc12_list,
        .nr_sources     = ARRAY_SIZE(clk_src_mmc12_list),
 };
@@ -901,7 +901,7 @@ static struct clk *clk_src_irda_usb_list[] = {
        [3] = &clk_mout_hpll.clk,
 };
 
-struct clksrc_sources clk_src_irda_usb = {
+static struct clksrc_sources clk_src_irda_usb = {
        .sources        = clk_src_irda_usb_list,
        .nr_sources     = ARRAY_SIZE(clk_src_irda_usb_list),
 };
@@ -912,7 +912,7 @@ static struct clk *clk_src_pwi_list[] = {
        [2] = &clk_div_mpll.clk,
 };
 
-struct clksrc_sources clk_src_pwi = {
+static struct clksrc_sources clk_src_pwi = {
        .sources        = clk_src_pwi_list,
        .nr_sources     = ARRAY_SIZE(clk_src_pwi_list),
 };
@@ -923,7 +923,7 @@ static struct clk *clk_sclk_spdif_list[] = {
        [2] = &clk_sclk_audio2.clk,
 };
 
-struct clksrc_sources clk_src_sclk_spdif = {
+static struct clksrc_sources clk_src_sclk_spdif = {
        .sources        = clk_sclk_spdif_list,
        .nr_sources     = ARRAY_SIZE(clk_sclk_spdif_list),
 };
index 96b1ab3dcd48365237520e27697897b3e683c890..afd8db2d599155720f0a8b1fafc7bec7a539bde8 100644 (file)
@@ -35,7 +35,7 @@
 
 static u64 dma_dmamask = DMA_BIT_MASK(32);
 
-u8 pdma0_peri[] = {
+static u8 pdma0_peri[] = {
        DMACH_UART0_RX,
        DMACH_UART0_TX,
        DMACH_UART1_RX,
@@ -68,15 +68,15 @@ u8 pdma0_peri[] = {
        DMACH_HSI_TX,
 };
 
-struct dma_pl330_platdata s5pc100_pdma0_pdata = {
+static struct dma_pl330_platdata s5pc100_pdma0_pdata = {
        .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
        .peri_id = pdma0_peri,
 };
 
-AMBA_AHB_DEVICE(s5pc100_pdma0,  "dma-pl330.0", 0x00041330, S5PC100_PA_PDMA0,
-       {IRQ_PDMA0}, &s5pc100_pdma0_pdata);
+static AMBA_AHB_DEVICE(s5pc100_pdma0,  "dma-pl330.0", 0x00041330,
+       S5PC100_PA_PDMA0, {IRQ_PDMA0}, &s5pc100_pdma0_pdata);
 
-u8 pdma1_peri[] = {
+static u8 pdma1_peri[] = {
        DMACH_UART0_RX,
        DMACH_UART0_TX,
        DMACH_UART1_RX,
@@ -109,13 +109,13 @@ u8 pdma1_peri[] = {
        DMACH_MSM_REQ3,
 };
 
-struct dma_pl330_platdata s5pc100_pdma1_pdata = {
+static struct dma_pl330_platdata s5pc100_pdma1_pdata = {
        .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
        .peri_id = pdma1_peri,
 };
 
-AMBA_AHB_DEVICE(s5pc100_pdma1, "dma-pl330.1", 0x00041330, S5PC100_PA_PDMA1,
-       {IRQ_PDMA1}, &s5pc100_pdma1_pdata);
+static AMBA_AHB_DEVICE(s5pc100_pdma1, "dma-pl330.1", 0x00041330,
+       S5PC100_PA_PDMA1, {IRQ_PDMA1}, &s5pc100_pdma1_pdata);
 
 static int __init s5pc100_dma_init(void)
 {
index 2cdc42e838b8deb663395966096f0f7b9ca6dd4b..29594fc4fdf4bce67aca77d38232678af91f2395 100644 (file)
@@ -65,6 +65,11 @@ config S5PV210_SETUP_SPI
        help
          Common setup code for SPI GPIO configurations.
 
+config S5PV210_SETUP_USB_PHY
+       bool
+       help
+         Common setup code for USB PHY controller
+
 menu "S5PC110 Machines"
 
 config MACH_AQUILA
@@ -107,6 +112,7 @@ config MACH_GONI
        select S5PV210_SETUP_KEYPAD
        select S5PV210_SETUP_SDHCI
        select S5PV210_SETUP_FIMC
+       select S5PV210_SETUP_USB_PHY
        help
          Machine support for Samsung GONI board
          S5PC110(MCP) is one of package option of S5PV210
@@ -118,6 +124,10 @@ config MACH_SMDKC110
        select S3C_DEV_I2C2
        select S3C_DEV_RTC
        select S3C_DEV_WDT
+       select S5P_DEV_FIMC0
+       select S5P_DEV_FIMC1
+       select S5P_DEV_FIMC2
+       select S5P_DEV_MFC
        select SAMSUNG_DEV_IDE
        select S5PV210_SETUP_I2C1
        select S5PV210_SETUP_I2C2
@@ -142,6 +152,11 @@ config MACH_SMDKV210
        select S3C_DEV_I2C2
        select S3C_DEV_RTC
        select S3C_DEV_WDT
+       select S5P_DEV_FIMC0
+       select S5P_DEV_FIMC1
+       select S5P_DEV_FIMC2
+       select S5P_DEV_JPEG
+       select S5P_DEV_MFC
        select SAMSUNG_DEV_ADC
        select SAMSUNG_DEV_BACKLIGHT
        select SAMSUNG_DEV_IDE
index 76a121dd52b434fd4ae865dbf8aa6685082c4d41..1c4e41998a1031f2dcc6de7e3b690494391bba17 100644 (file)
@@ -39,3 +39,4 @@ obj-$(CONFIG_S5PV210_SETUP_IDE)               += setup-ide.o
 obj-$(CONFIG_S5PV210_SETUP_KEYPAD)     += setup-keypad.o
 obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
 obj-$(CONFIG_S5PV210_SETUP_SPI)                += setup-spi.o
+obj-$(CONFIG_S5PV210_SETUP_USB_PHY) += setup-usb-phy.o
index b9ec0c35379f572ebf63fc9dd4d2af97c5a0d377..09609d50961d491c09f0f2e8926453e3db7cd0ce 100644 (file)
@@ -339,6 +339,11 @@ static struct clk init_clocks_off[] = {
                .parent         = &clk_hclk_dsys.clk,
                .enable         = s5pv210_clk_ip0_ctrl,
                .ctrlbit        = (1 << 26),
+       }, {
+               .name           = "jpeg",
+               .parent         = &clk_hclk_dsys.clk,
+               .enable         = s5pv210_clk_ip0_ctrl,
+               .ctrlbit        = (1 << 28),
        }, {
                .name           = "mfc",
                .devname        = "s5p-mfc",
index f6885d247d143ac6ae34d58b5796970cd04fd9e5..86ce62f66190fe5a67c2c5dad4f092db67b4818e 100644 (file)
@@ -35,7 +35,7 @@
 
 static u64 dma_dmamask = DMA_BIT_MASK(32);
 
-u8 pdma0_peri[] = {
+static u8 pdma0_peri[] = {
        DMACH_UART0_RX,
        DMACH_UART0_TX,
        DMACH_UART1_RX,
@@ -66,15 +66,15 @@ u8 pdma0_peri[] = {
        DMACH_SPDIF,
 };
 
-struct dma_pl330_platdata s5pv210_pdma0_pdata = {
+static struct dma_pl330_platdata s5pv210_pdma0_pdata = {
        .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
        .peri_id = pdma0_peri,
 };
 
-AMBA_AHB_DEVICE(s5pv210_pdma0, "dma-pl330.0", 0x00041330, S5PV210_PA_PDMA0,
-       {IRQ_PDMA0}, &s5pv210_pdma0_pdata);
+static AMBA_AHB_DEVICE(s5pv210_pdma0, "dma-pl330.0", 0x00041330,
+       S5PV210_PA_PDMA0, {IRQ_PDMA0}, &s5pv210_pdma0_pdata);
 
-u8 pdma1_peri[] = {
+static u8 pdma1_peri[] = {
        DMACH_UART0_RX,
        DMACH_UART0_TX,
        DMACH_UART1_RX,
@@ -109,13 +109,13 @@ u8 pdma1_peri[] = {
        DMACH_PCM2_TX,
 };
 
-struct dma_pl330_platdata s5pv210_pdma1_pdata = {
+static struct dma_pl330_platdata s5pv210_pdma1_pdata = {
        .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
        .peri_id = pdma1_peri,
 };
 
-AMBA_AHB_DEVICE(s5pv210_pdma1, "dma-pl330.1", 0x00041330, S5PV210_PA_PDMA1,
-       {IRQ_PDMA1}, &s5pv210_pdma1_pdata);
+static AMBA_AHB_DEVICE(s5pv210_pdma1, "dma-pl330.1", 0x00041330,
+       S5PV210_PA_PDMA1, {IRQ_PDMA1}, &s5pv210_pdma1_pdata);
 
 static int __init s5pv210_dma_init(void)
 {
index 89c34b8f73bfb24e9b6225f70cf07509cf32a116..b7c8a1917ffce5a4cff50beac3573ce88b9c782a 100644 (file)
@@ -90,6 +90,8 @@
 #define S5PV210_PA_FIMC1               0xFB300000
 #define S5PV210_PA_FIMC2               0xFB400000
 
+#define S5PV210_PA_JPEG                        0xFB600000
+
 #define S5PV210_PA_SDO                 0xF9000000
 #define S5PV210_PA_VP                  0xF9100000
 #define S5PV210_PA_MIXER               0xF9200000
 #define S5P_PA_SYSCON                  S5PV210_PA_SYSCON
 #define S5P_PA_TIMER                   S5PV210_PA_TIMER
 
+#define S5P_PA_JPEG                    S5PV210_PA_JPEG
+
 #define SAMSUNG_PA_ADC                 S5PV210_PA_ADC
 #define SAMSUNG_PA_CFCON               S5PV210_PA_CFCON
 #define SAMSUNG_PA_KEYPAD              S5PV210_PA_KEYPAD
index 26691d39d0f4cd41a2a2d48b3e9dd4d1180e2ba1..cccb1eddaa3838a959eb10ffc018b68713da3e8b 100644 (file)
@@ -13,7 +13,3 @@
 #define S5PV210_USB_PHY_CON    (S3C_VA_SYS + 0xE80C)
 #define S5PV210_USB_PHY0_EN    (1 << 0)
 #define S5PV210_USB_PHY1_EN    (1 << 1)
-
-/* compatibility defines for s3c-hsotg driver */
-#define S3C64XX_OTHERS         S5PV210_USB_PHY_CON
-#define S3C64XX_OTHERS_USBMASK S5PV210_USB_PHY0_EN
index 5e734d025a6a2c0926a292e2ce2f0f400f866e67..a9ea64e0da0d2758e7775a8590d431fc5725d563 100644 (file)
@@ -616,6 +616,7 @@ static struct platform_device *aquila_devices[] __initdata = {
        &s5p_device_fimc0,
        &s5p_device_fimc1,
        &s5p_device_fimc2,
+       &s5p_device_fimc_md,
        &s5pv210_device_iis0,
        &wm8994_fixed_voltage0,
        &wm8994_fixed_voltage1,
index ff91526104397edb89d159c32b0ae97ee134865a..2cf5ed75f3906ed21f6e5c028b7faaeb9f0c7bef 100644 (file)
@@ -844,7 +844,7 @@ static struct s5p_fimc_isp_info goni_camera_sensors[] = {
        },
 };
 
-struct s5p_platform_fimc goni_fimc_md_platdata __initdata = {
+static struct s5p_platform_fimc goni_fimc_md_platdata __initdata = {
        .isp_info       = goni_camera_sensors,
        .num_clients    = ARRAY_SIZE(goni_camera_sensors),
 };
index b323983b2c544d648a9e8142e5d35fee019b05a9..dfc29236321ca1c48b65412d413c62dd9199a96f 100644 (file)
@@ -31,6 +31,7 @@
 #include <plat/iic.h>
 #include <plat/pm.h>
 #include <plat/s5p-time.h>
+#include <plat/mfc.h>
 
 #include "common.h"
 
@@ -94,6 +95,13 @@ static struct platform_device *smdkc110_devices[] __initdata = {
        &s3c_device_i2c2,
        &s3c_device_rtc,
        &s3c_device_wdt,
+       &s5p_device_fimc0,
+       &s5p_device_fimc1,
+       &s5p_device_fimc2,
+       &s5p_device_fimc_md,
+       &s5p_device_mfc,
+       &s5p_device_mfc_l,
+       &s5p_device_mfc_r,
 };
 
 static struct i2c_board_info smdkc110_i2c_devs0[] __initdata = {
@@ -117,6 +125,11 @@ static void __init smdkc110_map_io(void)
        s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
 }
 
+static void __init smdkc110_reserve(void)
+{
+       s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20);
+}
+
 static void __init smdkc110_machine_init(void)
 {
        s3c_pm_init();
@@ -145,4 +158,5 @@ MACHINE_START(SMDKC110, "SMDKC110")
        .init_machine   = smdkc110_machine_init,
        .timer          = &s5p_timer,
        .restart        = s5pv210_restart,
+       .reserve        = &smdkc110_reserve,
 MACHINE_END
index dff9ea7b5bba1be2e729fd47f32f179414331f30..91d4ad8bcc73438befc6cb4f43f3812b50af1b26 100644 (file)
@@ -46,6 +46,7 @@
 #include <plat/s5p-time.h>
 #include <plat/backlight.h>
 #include <plat/regs-fb-v4.h>
+#include <plat/mfc.h>
 
 #include "common.h"
 
@@ -140,7 +141,7 @@ static struct dm9000_plat_data smdkv210_dm9000_platdata = {
        .dev_addr       = { 0x00, 0x09, 0xc0, 0xff, 0xec, 0x48 },
 };
 
-struct platform_device smdkv210_dm9000 = {
+static struct platform_device smdkv210_dm9000 = {
        .name           = "dm9000",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(smdkv210_dm9000_resources),
@@ -223,6 +224,14 @@ static struct platform_device *smdkv210_devices[] __initdata = {
        &s3c_device_rtc,
        &s3c_device_ts,
        &s3c_device_wdt,
+       &s5p_device_fimc0,
+       &s5p_device_fimc1,
+       &s5p_device_fimc2,
+       &s5p_device_fimc_md,
+       &s5p_device_jpeg,
+       &s5p_device_mfc,
+       &s5p_device_mfc_l,
+       &s5p_device_mfc_r,
        &s5pv210_device_ac97,
        &s5pv210_device_iis0,
        &s5pv210_device_spdif,
@@ -282,6 +291,11 @@ static void __init smdkv210_map_io(void)
        s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
 }
 
+static void __init smdkv210_reserve(void)
+{
+       s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20);
+}
+
 static void __init smdkv210_machine_init(void)
 {
        s3c_pm_init();
@@ -319,4 +333,5 @@ MACHINE_START(SMDKV210, "SMDKV210")
        .init_machine   = smdkv210_machine_init,
        .timer          = &s5p_timer,
        .restart        = s5pv210_restart,
+       .reserve        = &smdkv210_reserve,
 MACHINE_END
diff --git a/arch/arm/mach-s5pv210/setup-usb-phy.c b/arch/arm/mach-s5pv210/setup-usb-phy.c
new file mode 100644 (file)
index 0000000..be39cf4
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundationr
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <mach/map.h>
+#include <mach/regs-sys.h>
+#include <plat/cpu.h>
+#include <plat/regs-usb-hsotg-phy.h>
+#include <plat/usb-phy.h>
+
+static int s5pv210_usb_otgphy_init(struct platform_device *pdev)
+{
+       struct clk *xusbxti;
+       u32 phyclk;
+
+       writel(readl(S5PV210_USB_PHY_CON) | S5PV210_USB_PHY0_EN,
+                       S5PV210_USB_PHY_CON);
+
+       /* set clock frequency for PLL */
+       phyclk = readl(S3C_PHYCLK) & ~S3C_PHYCLK_CLKSEL_MASK;
+
+       xusbxti = clk_get(&pdev->dev, "xusbxti");
+       if (xusbxti && !IS_ERR(xusbxti)) {
+               switch (clk_get_rate(xusbxti)) {
+               case 12 * MHZ:
+                       phyclk |= S3C_PHYCLK_CLKSEL_12M;
+                       break;
+               case 24 * MHZ:
+                       phyclk |= S3C_PHYCLK_CLKSEL_24M;
+                       break;
+               default:
+               case 48 * MHZ:
+                       /* default reference clock */
+                       break;
+               }
+               clk_put(xusbxti);
+       }
+
+       /* TODO: select external clock/oscillator */
+       writel(phyclk | S3C_PHYCLK_CLK_FORCE, S3C_PHYCLK);
+
+       /* set to normal OTG PHY */
+       writel((readl(S3C_PHYPWR) & ~S3C_PHYPWR_NORMAL_MASK), S3C_PHYPWR);
+       mdelay(1);
+
+       /* reset OTG PHY and Link */
+       writel(S3C_RSTCON_PHY | S3C_RSTCON_HCLK | S3C_RSTCON_PHYCLK,
+                       S3C_RSTCON);
+       udelay(20);     /* at-least 10uS */
+       writel(0, S3C_RSTCON);
+
+       return 0;
+}
+
+static int s5pv210_usb_otgphy_exit(struct platform_device *pdev)
+{
+       writel((readl(S3C_PHYPWR) | S3C_PHYPWR_ANALOG_POWERDOWN |
+                               S3C_PHYPWR_OTG_DISABLE), S3C_PHYPWR);
+
+       writel(readl(S5PV210_USB_PHY_CON) & ~S5PV210_USB_PHY0_EN,
+                       S5PV210_USB_PHY_CON);
+
+       return 0;
+}
+
+int s5p_usb_phy_init(struct platform_device *pdev, int type)
+{
+       if (type == S5P_USB_PHY_DEVICE)
+               return s5pv210_usb_otgphy_init(pdev);
+
+       return -EINVAL;
+}
+
+int s5p_usb_phy_exit(struct platform_device *pdev, int type)
+{
+       if (type == S5P_USB_PHY_DEVICE)
+               return s5pv210_usb_otgphy_exit(pdev);
+
+       return -EINVAL;
+}
index ed7408d3216ce7aa2f8b2a6d2ae0ebf4d2d237cd..60b97ec01676fc7eff7471eebf415ae2a97f5696 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 # Common support
-obj-y := clock.o generic.o irq.o dma.o time.o #nmi-oopser.o
+obj-y := clock.o generic.o irq.o time.o #nmi-oopser.o
 obj-m :=
 obj-n :=
 obj-  :=
index 0c4b76ab4d8eba0037e305d5d8f9b17b36074fa7..375d3f779a88a6f213aa296fd12aef7fd0631d0f 100644 (file)
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/serial_core.h>
+#include <linux/mfd/ucb1x00.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
 
+#include <video/sa1100fb.h>
+
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <asm/irq.h>
 #include <asm/setup.h>
 #include <asm/page.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/mach/serial_sa1100.h>
 #include <mach/assabet.h>
 #include <mach/mcp.h>
+#include <mach/irqs.h>
 
 #include "generic.h"
 
 #define ASSABET_BCR_DB1110 \
-       (ASSABET_BCR_SPK_OFF    | ASSABET_BCR_QMUTE     | \
+       (ASSABET_BCR_SPK_OFF    | \
         ASSABET_BCR_LED_GREEN  | ASSABET_BCR_LED_RED   | \
         ASSABET_BCR_RS232EN    | ASSABET_BCR_LCD_12RGB | \
         ASSABET_BCR_IRDA_MD0)
 
 #define ASSABET_BCR_DB1111 \
-       (ASSABET_BCR_SPK_OFF    | ASSABET_BCR_QMUTE     | \
+       (ASSABET_BCR_SPK_OFF    | \
         ASSABET_BCR_LED_GREEN  | ASSABET_BCR_LED_RED   | \
         ASSABET_BCR_RS232EN    | ASSABET_BCR_LCD_12RGB | \
         ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_STEREO_LB | \
@@ -69,31 +72,10 @@ void ASSABET_BCR_frob(unsigned int mask, unsigned int val)
 
 EXPORT_SYMBOL(ASSABET_BCR_frob);
 
-static void assabet_backlight_power(int on)
-{
-#ifndef ASSABET_PAL_VIDEO
-       if (on)
-               ASSABET_BCR_set(ASSABET_BCR_LIGHT_ON);
-       else
-#endif
-               ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON);
-}
-
-/*
- * Turn on/off the backlight.  When turning the backlight on,
- * we wait 500us after turning it on so we don't cause the
- * supplies to droop when we enable the LCD controller (and
- * cause a hard reset.)
- */
-static void assabet_lcd_power(int on)
+static void assabet_ucb1x00_reset(enum ucb1x00_reset state)
 {
-#ifndef ASSABET_PAL_VIDEO
-       if (on) {
-               ASSABET_BCR_set(ASSABET_BCR_LCD_ON);
-               udelay(500);
-       } else
-#endif
-               ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
+       if (state == UCB_RST_PROBE)
+               ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
 }
 
 
@@ -152,15 +134,8 @@ static struct flash_platform_data assabet_flash_data = {
 };
 
 static struct resource assabet_flash_resources[] = {
-       {
-               .start  = SA1100_CS0_PHYS,
-               .end    = SA1100_CS0_PHYS + SZ_32M - 1,
-               .flags  = IORESOURCE_MEM,
-       }, {
-               .start  = SA1100_CS1_PHYS,
-               .end    = SA1100_CS1_PHYS + SZ_32M - 1,
-               .flags  = IORESOURCE_MEM,
-       }
+       DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M),
+       DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_32M),
 };
 
 
@@ -199,18 +174,126 @@ static struct irda_platform_data assabet_irda_data = {
        .set_speed      = assabet_irda_set_speed,
 };
 
+static struct ucb1x00_plat_data assabet_ucb1x00_data = {
+       .reset          = assabet_ucb1x00_reset,
+       .gpio_base      = -1,
+};
+
 static struct mcp_plat_data assabet_mcp_data = {
        .mccr0          = MCCR0_ADM,
        .sclk_rate      = 11981000,
+       .codec_pdata    = &assabet_ucb1x00_data,
+};
+
+static void assabet_lcd_set_visual(u32 visual)
+{
+       u_int is_true_color = visual == FB_VISUAL_TRUECOLOR;
+
+       if (machine_is_assabet()) {
+#if 1          // phase 4 or newer Assabet's
+               if (is_true_color)
+                       ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
+               else
+                       ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
+#else
+               // older Assabet's
+               if (is_true_color)
+                       ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
+               else
+                       ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
+#endif
+       }
+}
+
+#ifndef ASSABET_PAL_VIDEO
+static void assabet_lcd_backlight_power(int on)
+{
+       if (on)
+               ASSABET_BCR_set(ASSABET_BCR_LIGHT_ON);
+       else
+               ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON);
+}
+
+/*
+ * Turn on/off the backlight.  When turning the backlight on, we wait
+ * 500us after turning it on so we don't cause the supplies to droop
+ * when we enable the LCD controller (and cause a hard reset.)
+ */
+static void assabet_lcd_power(int on)
+{
+       if (on) {
+               ASSABET_BCR_set(ASSABET_BCR_LCD_ON);
+               udelay(500);
+       } else
+               ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
+}
+
+/*
+ * The assabet uses a sharp LQ039Q2DS54 LCD module.  It is actually
+ * takes an RGB666 signal, but we provide it with an RGB565 signal
+ * instead (def_rgb_16).
+ */
+static struct sa1100fb_mach_info lq039q2ds54_info = {
+       .pixclock       = 171521,       .bpp            = 16,
+       .xres           = 320,          .yres           = 240,
+
+       .hsync_len      = 5,            .vsync_len      = 1,
+       .left_margin    = 61,           .upper_margin   = 3,
+       .right_margin   = 9,            .lower_margin   = 0,
+
+       .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+       .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+       .lccr3          = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
+
+       .backlight_power = assabet_lcd_backlight_power,
+       .lcd_power = assabet_lcd_power,
+       .set_visual = assabet_lcd_set_visual,
+};
+#else
+static void assabet_pal_backlight_power(int on)
+{
+       ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON);
+}
+
+static void assabet_pal_power(int on)
+{
+       ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
+}
+
+static struct sa1100fb_mach_info pal_info = {
+       .pixclock       = 67797,        .bpp            = 16,
+       .xres           = 640,          .yres           = 512,
+
+       .hsync_len      = 64,           .vsync_len      = 6,
+       .left_margin    = 125,          .upper_margin   = 70,
+       .right_margin   = 115,          .lower_margin   = 36,
+
+       .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+       .lccr3          = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
+
+       .backlight_power = assabet_pal_backlight_power,
+       .lcd_power = assabet_pal_power,
+       .set_visual = assabet_lcd_set_visual,
 };
+#endif
+
+#ifdef CONFIG_ASSABET_NEPONSET
+static struct resource neponset_resources[] = {
+       DEFINE_RES_MEM(0x10000000, 0x08000000),
+       DEFINE_RES_MEM(0x18000000, 0x04000000),
+       DEFINE_RES_MEM(0x40000000, SZ_8K),
+       DEFINE_RES_IRQ(IRQ_GPIO25),
+};
+#endif
 
 static void __init assabet_init(void)
 {
        /*
         * Ensure that the power supply is in "high power" mode.
         */
-       GPDR |= GPIO_GPIO16;
        GPSR = GPIO_GPIO16;
+       GPDR |= GPIO_GPIO16;
 
        /*
         * Ensure that these pins are set as outputs and are driving
@@ -218,8 +301,16 @@ static void __init assabet_init(void)
         * the WS latch in the CPLD, and we don't float causing
         * excessive power drain.  --rmk
         */
-       GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
        GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
+       GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
+
+       /*
+        * Also set GPIO27 as an output; this is used to clock UART3
+        * via the FPGA and as otherwise has no pullups or pulldowns,
+        * so stop it floating.
+        */
+       GPCR = GPIO_GPIO27;
+       GPDR |= GPIO_GPIO27;
 
        /*
         * Set up registers for sleep mode.
@@ -231,8 +322,7 @@ static void __init assabet_init(void)
        PPDR |= PPC_TXD3 | PPC_TXD1;
        PPSR |= PPC_TXD3 | PPC_TXD1;
 
-       sa1100fb_lcd_power = assabet_lcd_power;
-       sa1100fb_backlight_power = assabet_backlight_power;
+       sa11x0_ppc_configure_mcp();
 
        if (machine_has_neponset()) {
                /*
@@ -246,9 +336,17 @@ static void __init assabet_init(void)
 #ifndef CONFIG_ASSABET_NEPONSET
                printk( "Warning: Neponset detected but full support "
                        "hasn't been configured in the kernel\n" );
+#else
+               platform_device_register_simple("neponset", 0,
+                       neponset_resources, ARRAY_SIZE(neponset_resources));
 #endif
        }
 
+#ifndef ASSABET_PAL_VIDEO
+       sa11x0_register_lcd(&lq039q2ds54_info);
+#else
+       sa11x0_register_lcd(&pal_video);
+#endif
        sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources,
                            ARRAY_SIZE(assabet_flash_resources));
        sa11x0_register_irda(&assabet_irda_data);
@@ -412,21 +510,8 @@ static void __init assabet_map_io(void)
         */
        Ser1SDCR0 |= SDCR0_SUS;
 
-       if (machine_has_neponset()) {
-#ifdef CONFIG_ASSABET_NEPONSET
-               extern void neponset_map_io(void);
-
-               /*
-                * We map Neponset registers even if it isn't present since
-                * many drivers will try to probe their stuff (and fail).
-                * This is still more friendly than a kernel paging request
-                * crash.
-                */
-               neponset_map_io();
-#endif
-       } else {
+       if (!machine_has_neponset())
                sa1100_register_uart_fns(&assabet_port_fns);
-       }
 
        /*
         * When Neponset is attached, the first UART should be
@@ -449,6 +534,7 @@ MACHINE_START(ASSABET, "Intel-Assabet")
        .atag_offset    = 0x100,
        .fixup          = fixup_assabet,
        .map_io         = assabet_map_io,
+       .nr_irqs        = SA1100_NR_IRQS,
        .init_irq       = sa1100_init_irq,
        .timer          = &sa1100_timer,
        .init_machine   = assabet_init,
index b07a2c024cb78682d944d025e6fb7c26c349c097..e0f0c030258c5614bedf2abc8bd5d05e946e4233 100644 (file)
 #include "generic.h"
 
 static struct resource sa1111_resources[] = {
-       [0] = {
-               .start          = BADGE4_SA1111_BASE,
-               .end            = BADGE4_SA1111_BASE + 0x00001fff,
-               .flags          = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start          = BADGE4_IRQ_GPIO_SA1111,
-               .end            = BADGE4_IRQ_GPIO_SA1111,
-               .flags          = IORESOURCE_IRQ,
-       },
+       [0] = DEFINE_RES_MEM(BADGE4_SA1111_BASE, 0x2000),
+       [1] = DEFINE_RES_IRQ(BADGE4_IRQ_GPIO_SA1111),
 };
 
+static int badge4_sa1111_enable(void *data, unsigned devid)
+{
+       if (devid == SA1111_DEVID_USB)
+               badge4_set_5V(BADGE4_5V_USB, 1);
+       return 0;
+}
+
+static void badge4_sa1111_disable(void *data, unsigned devid)
+{
+       if (devid == SA1111_DEVID_USB)
+               badge4_set_5V(BADGE4_5V_USB, 0);
+}
+
 static struct sa1111_platform_data sa1111_info = {
-       .irq_base       = IRQ_BOARD_END,
+       .disable_devs   = SA1111_DEVID_PS2_MSE,
+       .enable         = badge4_sa1111_enable,
+       .disable        = badge4_sa1111_disable,
 };
 
 static u64 sa1111_dmamask = 0xffffffffUL;
@@ -121,11 +128,8 @@ static struct flash_platform_data badge4_flash_data = {
        .nr_parts       = ARRAY_SIZE(badge4_partitions),
 };
 
-static struct resource badge4_flash_resource = {
-       .start          = SA1100_CS0_PHYS,
-       .end            = SA1100_CS0_PHYS + SZ_64M - 1,
-       .flags          = IORESOURCE_MEM,
-};
+static struct resource badge4_flash_resource =
+       DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_64M);
 
 static int five_v_on __initdata = 0;
 
@@ -269,11 +273,6 @@ static struct map_desc badge4_io_desc[] __initdata = {
                .pfn            = __phys_to_pfn(0x10000000),
                .length         = 0x00100000,
                .type           = MT_DEVICE
-       }, {    /* SA-1111      */
-               .virtual        = 0xf4000000,
-               .pfn            = __phys_to_pfn(0x48000000),
-               .length         = 0x00100000,
-               .type           = MT_DEVICE
        }
 };
 
@@ -304,6 +303,7 @@ static void __init badge4_map_io(void)
 MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4")
        .atag_offset    = 0x100,
        .map_io         = badge4_map_io,
+       .nr_irqs        = SA1100_NR_IRQS,
        .init_irq       = sa1100_init_irq,
        .timer          = &sa1100_timer,
 #ifdef CONFIG_SA1111
index 11bb6d0b9be377b6c926f3e759a03a21d2e9ffff..4a61f60e0502dc595dd54dc0a0a2e46a149227da 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 
-#include <asm/irq.h>
 #include <mach/hardware.h>
 #include <asm/setup.h>
 
 
 #include <mach/cerf.h>
 #include <mach/mcp.h>
+#include <mach/irqs.h>
 #include "generic.h"
 
 static struct resource cerfuart2_resources[] = {
-       [0] = {
-               .start  = 0x80030000,
-               .end    = 0x8003ffff,
-               .flags  = IORESOURCE_MEM,
-       },
+       [0] = DEFINE_RES_MEM(0x80030000, SZ_64K),
 };
 
 static struct platform_device cerfuart2_device = {
@@ -87,11 +83,8 @@ static struct flash_platform_data cerf_flash_data = {
        .nr_parts       = ARRAY_SIZE(cerf_partitions),
 };
 
-static struct resource cerf_flash_resource = {
-       .start          = SA1100_CS0_PHYS,
-       .end            = SA1100_CS0_PHYS + SZ_32M - 1,
-       .flags          = IORESOURCE_MEM,
-};
+static struct resource cerf_flash_resource =
+       DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
 
 static void __init cerf_init_irq(void)
 {
@@ -128,6 +121,7 @@ static struct mcp_plat_data cerf_mcp_data = {
 
 static void __init cerf_init(void)
 {
+       sa11x0_ppc_configure_mcp();
        platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices));
        sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1);
        sa11x0_register_mcp(&cerf_mcp_data);
@@ -136,6 +130,7 @@ static void __init cerf_init(void)
 MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube")
        /* Maintainer: support@intrinsyc.com */
        .map_io         = cerf_map_io,
+       .nr_irqs        = SA1100_NR_IRQS,
        .init_irq       = cerf_init_irq,
        .timer          = &sa1100_timer,
        .init_machine   = cerf_init,
index dab3c6347a8f2d8e80bafba18b6916f8f97161f9..172ebd0ee0a2c9d7fe5371b5bebc6c505c8e303d 100644 (file)
 #include <linux/clk.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
 
 #include <mach/hardware.h>
 
-/*
- * Very simple clock implementation - we only have one clock to deal with.
- */
+struct clkops {
+       void                    (*enable)(struct clk *);
+       void                    (*disable)(struct clk *);
+};
+
 struct clk {
+       const struct clkops     *ops;
        unsigned int            enabled;
 };
 
-static void clk_gpio27_enable(void)
+#define DEFINE_CLK(_name, _ops)                                \
+struct clk clk_##_name = {                             \
+               .ops    = _ops,                         \
+       }
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+static void clk_gpio27_enable(struct clk *clk)
 {
        /*
         * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
@@ -32,38 +44,24 @@ static void clk_gpio27_enable(void)
        TUCR = TUCR_3_6864MHz;
 }
 
-static void clk_gpio27_disable(void)
+static void clk_gpio27_disable(struct clk *clk)
 {
        TUCR = 0;
        GPDR &= ~GPIO_32_768kHz;
        GAFR &= ~GPIO_32_768kHz;
 }
 
-static struct clk clk_gpio27;
-
-static DEFINE_SPINLOCK(clocks_lock);
-
-struct clk *clk_get(struct device *dev, const char *id)
-{
-       const char *devname = dev_name(dev);
-
-       return strcmp(devname, "sa1111.0") ? ERR_PTR(-ENOENT) : &clk_gpio27;
-}
-EXPORT_SYMBOL(clk_get);
-
-void clk_put(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_put);
-
 int clk_enable(struct clk *clk)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&clocks_lock, flags);
-       if (clk->enabled++ == 0)
-               clk_gpio27_enable();
-       spin_unlock_irqrestore(&clocks_lock, flags);
+       if (clk) {
+               spin_lock_irqsave(&clocks_lock, flags);
+               if (clk->enabled++ == 0)
+                       clk->ops->enable(clk);
+               spin_unlock_irqrestore(&clocks_lock, flags);
+       }
+
        return 0;
 }
 EXPORT_SYMBOL(clk_enable);
@@ -72,17 +70,31 @@ void clk_disable(struct clk *clk)
 {
        unsigned long flags;
 
-       WARN_ON(clk->enabled == 0);
-
-       spin_lock_irqsave(&clocks_lock, flags);
-       if (--clk->enabled == 0)
-               clk_gpio27_disable();
-       spin_unlock_irqrestore(&clocks_lock, flags);
+       if (clk) {
+               WARN_ON(clk->enabled == 0);
+               spin_lock_irqsave(&clocks_lock, flags);
+               if (--clk->enabled == 0)
+                       clk->ops->disable(clk);
+               spin_unlock_irqrestore(&clocks_lock, flags);
+       }
 }
 EXPORT_SYMBOL(clk_disable);
 
-unsigned long clk_get_rate(struct clk *clk)
+const struct clkops clk_gpio27_ops = {
+       .enable         = clk_gpio27_enable,
+       .disable        = clk_gpio27_disable,
+};
+
+static DEFINE_CLK(gpio27, &clk_gpio27_ops);
+
+static struct clk_lookup sa11xx_clkregs[] = {
+       CLKDEV_INIT("sa1111.0", NULL, &clk_gpio27),
+       CLKDEV_INIT("sa1100-rtc", NULL, NULL),
+};
+
+static int __init sa11xx_clk_init(void)
 {
-       return 3686400;
+       clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs));
+       return 0;
 }
-EXPORT_SYMBOL(clk_get_rate);
+core_initcall(sa11xx_clk_init);
index fd5652118ed19565d5754ffdd16f1cfe0db59011..48885b7efd6b895e470d616b5e8f895483747a7b 100644 (file)
 #include <linux/tty.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
+#include <linux/mfd/ucb1x00.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/timer.h>
 #include <linux/gpio.h>
 #include <linux/pda_power.h>
 
+#include <video/sa1100fb.h>
+
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <asm/irq.h>
 #include <asm/page.h>
 #include <asm/setup.h>
 #include <mach/collie.h>
 #include <asm/mach/sharpsl_param.h>
 #include <asm/hardware/locomo.h>
 #include <mach/mcp.h>
+#include <mach/irqs.h>
 
 #include "generic.h"
 
 static struct resource collie_scoop_resources[] = {
-       [0] = {
-               .start          = 0x40800000,
-               .end            = 0x40800fff,
-               .flags          = IORESOURCE_MEM,
-       },
+       [0] = DEFINE_RES_MEM(0x40800000, SZ_4K),
 };
 
 static struct scoop_config collie_scoop_setup = {
@@ -85,10 +84,14 @@ static struct scoop_pcmcia_config collie_pcmcia_config = {
        .num_devs       = 1,
 };
 
+static struct ucb1x00_plat_data collie_ucb1x00_data = {
+       .gpio_base      = COLLIE_TC35143_GPIO_BASE,
+};
+
 static struct mcp_plat_data collie_mcp_data = {
        .mccr0          = MCCR0_ADM | MCCR0_ExtClk,
        .sclk_rate      = 9216000,
-       .gpio_base      = COLLIE_TC35143_GPIO_BASE,
+       .codec_pdata    = &collie_ucb1x00_data,
 };
 
 /*
@@ -221,16 +224,8 @@ device_initcall(collie_uart_init);
 
 
 static struct resource locomo_resources[] = {
-       [0] = {
-               .start          = 0x40000000,
-               .end            = 0x40001fff,
-               .flags          = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start          = IRQ_GPIO25,
-               .end            = IRQ_GPIO25,
-               .flags          = IORESOURCE_IRQ,
-       },
+       [0] = DEFINE_RES_MEM(0x40000000, SZ_8K),
+       [1] = DEFINE_RES_IRQ(IRQ_GPIO25),
 };
 
 static struct locomo_platform_data locomo_info = {
@@ -303,11 +298,21 @@ static struct flash_platform_data collie_flash_data = {
 };
 
 static struct resource collie_flash_resources[] = {
-       {
-               .start  = SA1100_CS0_PHYS,
-               .end    = SA1100_CS0_PHYS + SZ_32M - 1,
-               .flags  = IORESOURCE_MEM,
-       }
+       DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M),
+};
+
+static struct sa1100fb_mach_info collie_lcd_info = {
+       .pixclock       = 171521,       .bpp            = 16,
+       .xres           = 320,          .yres           = 240,
+
+       .hsync_len      = 5,            .vsync_len      = 1,
+       .left_margin    = 11,           .upper_margin   = 2,
+       .right_margin   = 30,           .lower_margin   = 0,
+
+       .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+       .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+       .lccr3          = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
 };
 
 static void __init collie_init(void)
@@ -341,6 +346,10 @@ static void __init collie_init(void)
 
        collie_power_resource[0].start = gpio_to_irq(COLLIE_GPIO_AC_IN);
        collie_power_resource[0].end = gpio_to_irq(COLLIE_GPIO_AC_IN);
+
+       sa11x0_ppc_configure_mcp();
+
+
        platform_scoop_config = &collie_pcmcia_config;
 
        ret = platform_add_devices(devices, ARRAY_SIZE(devices));
@@ -348,6 +357,7 @@ static void __init collie_init(void)
                printk(KERN_WARNING "collie: Unable to register LoCoMo device\n");
        }
 
+       sa11x0_register_lcd(&collie_lcd_info);
        sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
                            ARRAY_SIZE(collie_flash_resources));
        sa11x0_register_mcp(&collie_mcp_data);
@@ -383,6 +393,7 @@ static void __init collie_map_io(void)
 
 MACHINE_START(COLLIE, "Sharp-Collie")
        .map_io         = collie_map_io,
+       .nr_irqs        = SA1100_NR_IRQS,
        .init_irq       = sa1100_init_irq,
        .timer          = &sa1100_timer,
        .init_machine   = collie_init,
diff --git a/arch/arm/mach-sa1100/dma.c b/arch/arm/mach-sa1100/dma.c
deleted file mode 100644 (file)
index ad66035..0000000
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * arch/arm/mach-sa1100/dma.c
- *
- * Support functions for the SA11x0 internal DMA channels.
- *
- * Copyright (C) 2000, 2001 by Nicolas Pitre
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/errno.h>
-
-#include <asm/system.h>
-#include <asm/irq.h>
-#include <mach/hardware.h>
-#include <mach/dma.h>
-
-
-#undef DEBUG
-#ifdef DEBUG
-#define DPRINTK( s, arg... )  printk( "dma<%p>: " s, regs , ##arg )
-#else
-#define DPRINTK( x... )
-#endif
-
-
-typedef struct {
-       const char *device_id;          /* device name */
-       u_long device;                  /* this channel device, 0  if unused*/
-       dma_callback_t callback;        /* to call when DMA completes */
-       void *data;                     /* ... with private data ptr */
-} sa1100_dma_t;
-
-static sa1100_dma_t dma_chan[SA1100_DMA_CHANNELS];
-
-static DEFINE_SPINLOCK(dma_list_lock);
-
-
-static irqreturn_t dma_irq_handler(int irq, void *dev_id)
-{
-       dma_regs_t *dma_regs = dev_id;
-       sa1100_dma_t *dma = dma_chan + (((u_int)dma_regs >> 5) & 7);
-       int status = dma_regs->RdDCSR;
-
-       if (status & (DCSR_ERROR)) {
-               printk(KERN_CRIT "DMA on \"%s\" caused an error\n", dma->device_id);
-               dma_regs->ClrDCSR = DCSR_ERROR;
-       }
-
-       dma_regs->ClrDCSR = status & (DCSR_DONEA | DCSR_DONEB);
-       if (dma->callback) {
-               if (status & DCSR_DONEA)
-                       dma->callback(dma->data);
-               if (status & DCSR_DONEB)
-                       dma->callback(dma->data);
-       }
-       return IRQ_HANDLED;
-}
-
-
-/**
- *     sa1100_request_dma - allocate one of the SA11x0's DMA channels
- *     @device: The SA11x0 peripheral targeted by this request
- *     @device_id: An ascii name for the claiming device
- *     @callback: Function to be called when the DMA completes
- *     @data: A cookie passed back to the callback function
- *     @dma_regs: Pointer to the location of the allocated channel's identifier
- *
- *     This function will search for a free DMA channel and returns the
- *     address of the hardware registers for that channel as the channel
- *     identifier. This identifier is written to the location pointed by
- *     @dma_regs. The list of possible values for @device are listed into
- *     arch/arm/mach-sa1100/include/mach/dma.h as a dma_device_t enum.
- *
- *     Note that reading from a port and writing to the same port are
- *     actually considered as two different streams requiring separate
- *     DMA registrations.
- *
- *     The @callback function is called from interrupt context when one
- *     of the two possible DMA buffers in flight has terminated. That
- *     function has to be small and efficient while posponing more complex
- *     processing to a lower priority execution context.
- *
- *     If no channels are available, or if the desired @device is already in
- *     use by another DMA channel, then an error code is returned.  This
- *     function must be called before any other DMA calls.
- **/
-
-int sa1100_request_dma (dma_device_t device, const char *device_id,
-                       dma_callback_t callback, void *data,
-                       dma_regs_t **dma_regs)
-{
-       sa1100_dma_t *dma = NULL;
-       dma_regs_t *regs;
-       int i, err;
-
-       *dma_regs = NULL;
-
-       err = 0;
-       spin_lock(&dma_list_lock);
-       for (i = 0; i < SA1100_DMA_CHANNELS; i++) {
-               if (dma_chan[i].device == device) {
-                       err = -EBUSY;
-                       break;
-               } else if (!dma_chan[i].device && !dma) {
-                       dma = &dma_chan[i];
-               }
-       }
-       if (!err) {
-               if (dma)
-                       dma->device = device;
-               else
-                       err = -ENOSR;
-       }
-       spin_unlock(&dma_list_lock);
-       if (err)
-               return err;
-
-       i = dma - dma_chan;
-       regs = (dma_regs_t *)&DDAR(i);
-       err = request_irq(IRQ_DMA0 + i, dma_irq_handler, IRQF_DISABLED,
-                         device_id, regs);
-       if (err) {
-               printk(KERN_ERR
-                      "%s: unable to request IRQ %d for %s\n",
-                      __func__, IRQ_DMA0 + i, device_id);
-               dma->device = 0;
-               return err;
-       }
-
-       *dma_regs = regs;
-       dma->device_id = device_id;
-       dma->callback = callback;
-       dma->data = data;
-
-       regs->ClrDCSR =
-               (DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB |
-                DCSR_IE | DCSR_ERROR | DCSR_RUN);
-       regs->DDAR = device;
-
-       return 0;
-}
-
-
-/**
- *     sa1100_free_dma - free a SA11x0 DMA channel
- *     @regs: identifier for the channel to free
- *
- *     This clears all activities on a given DMA channel and releases it
- *     for future requests.  The @regs identifier is provided by a
- *     successful call to sa1100_request_dma().
- **/
-
-void sa1100_free_dma(dma_regs_t *regs)
-{
-       int i;
-
-       for (i = 0; i < SA1100_DMA_CHANNELS; i++)
-               if (regs == (dma_regs_t *)&DDAR(i))
-                       break;
-       if (i >= SA1100_DMA_CHANNELS) {
-               printk(KERN_ERR "%s: bad DMA identifier\n", __func__);
-               return;
-       }
-
-       if (!dma_chan[i].device) {
-               printk(KERN_ERR "%s: Trying to free free DMA\n", __func__);
-               return;
-       }
-
-       regs->ClrDCSR =
-               (DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB |
-                DCSR_IE | DCSR_ERROR | DCSR_RUN);
-       free_irq(IRQ_DMA0 + i, regs);
-       dma_chan[i].device = 0;
-}
-
-
-/**
- *     sa1100_start_dma - submit a data buffer for DMA
- *     @regs: identifier for the channel to use
- *     @dma_ptr: buffer physical (or bus) start address
- *     @size: buffer size
- *
- *     This function hands the given data buffer to the hardware for DMA
- *     access. If another buffer is already in flight then this buffer
- *     will be queued so the DMA engine will switch to it automatically
- *     when the previous one is done.  The DMA engine is actually toggling
- *     between two buffers so at most 2 successful calls can be made before
- *     one of them terminates and the callback function is called.
- *
- *     The @regs identifier is provided by a successful call to
- *     sa1100_request_dma().
- *
- *     The @size must not be larger than %MAX_DMA_SIZE.  If a given buffer
- *     is larger than that then it's the caller's responsibility to split
- *     it into smaller chunks and submit them separately. If this is the
- *     case then a @size of %CUT_DMA_SIZE is recommended to avoid ending
- *     up with too small chunks. The callback function can be used to chain
- *     submissions of buffer chunks.
- *
- *     Error return values:
- *     %-EOVERFLOW:    Given buffer size is too big.
- *     %-EBUSY:        Both DMA buffers are already in use.
- *     %-EAGAIN:       Both buffers were busy but one of them just completed
- *                     but the interrupt handler has to execute first.
- *
- *     This function returs 0 on success.
- **/
-
-int sa1100_start_dma(dma_regs_t *regs, dma_addr_t dma_ptr, u_int size)
-{
-       unsigned long flags;
-       u_long status;
-       int ret;
-
-       if (dma_ptr & 3)
-               printk(KERN_WARNING "DMA: unaligned start address (0x%08lx)\n",
-                      (unsigned long)dma_ptr);
-
-       if (size > MAX_DMA_SIZE)
-               return -EOVERFLOW;
-
-       local_irq_save(flags);
-       status = regs->RdDCSR;
-
-       /* If both DMA buffers are started, there's nothing else we can do. */
-       if ((status & (DCSR_STRTA | DCSR_STRTB)) == (DCSR_STRTA | DCSR_STRTB)) {
-               DPRINTK("start: st %#x busy\n", status);
-               ret = -EBUSY;
-               goto out;
-       }
-
-       if (((status & DCSR_BIU) && (status & DCSR_STRTB)) ||
-           (!(status & DCSR_BIU) && !(status & DCSR_STRTA))) {
-               if (status & DCSR_DONEA) {
-                       /* give a chance for the interrupt to be processed */
-                       ret = -EAGAIN;
-                       goto out;
-               }
-               regs->DBSA = dma_ptr;
-               regs->DBTA = size;
-               regs->SetDCSR = DCSR_STRTA | DCSR_IE | DCSR_RUN;
-               DPRINTK("start a=%#x s=%d on A\n", dma_ptr, size);
-       } else {
-               if (status & DCSR_DONEB) {
-                       /* give a chance for the interrupt to be processed */
-                       ret = -EAGAIN;
-                       goto out;
-               }
-               regs->DBSB = dma_ptr;
-               regs->DBTB = size;
-               regs->SetDCSR = DCSR_STRTB | DCSR_IE | DCSR_RUN;
-               DPRINTK("start a=%#x s=%d on B\n", dma_ptr, size);
-       }
-       ret = 0;
-
-out:
-       local_irq_restore(flags);
-       return ret;
-}
-
-
-/**
- *     sa1100_get_dma_pos - return current DMA position
- *     @regs: identifier for the channel to use
- *
- *     This function returns the current physical (or bus) address for the
- *     given DMA channel.  If the channel is running i.e. not in a stopped
- *     state then the caller must disable interrupts prior calling this
- *     function and process the returned value before re-enabling them to
- *     prevent races with the completion interrupt handler and the callback
- *     function. The validation of the returned value is the caller's
- *     responsibility as well -- the hardware seems to return out of range
- *     values when the DMA engine completes a buffer.
- *
- *     The @regs identifier is provided by a successful call to
- *     sa1100_request_dma().
- **/
-
-dma_addr_t sa1100_get_dma_pos(dma_regs_t *regs)
-{
-       int status;
-
-       /*
-        * We must determine whether buffer A or B is active.
-        * Two possibilities: either we are in the middle of
-        * a buffer, or the DMA controller just switched to the
-        * next toggle but the interrupt hasn't been serviced yet.
-        * The former case is straight forward.  In the later case,
-        * we'll do like if DMA is just at the end of the previous
-        * toggle since all registers haven't been reset yet.
-        * This goes around the edge case and since we're always
-        * a little behind anyways it shouldn't make a big difference.
-        * If DMA has been stopped prior calling this then the
-        * position is exact.
-        */
-       status = regs->RdDCSR;
-       if ((!(status & DCSR_BIU) &&  (status & DCSR_STRTA)) ||
-           ( (status & DCSR_BIU) && !(status & DCSR_STRTB)))
-               return regs->DBSA;
-       else
-               return regs->DBSB;
-}
-
-
-/**
- *     sa1100_reset_dma - reset a DMA channel
- *     @regs: identifier for the channel to use
- *
- *     This function resets and reconfigure the given DMA channel. This is
- *     particularly useful after a sleep/wakeup event.
- *
- *     The @regs identifier is provided by a successful call to
- *     sa1100_request_dma().
- **/
-
-void sa1100_reset_dma(dma_regs_t *regs)
-{
-       int i;
-
-       for (i = 0; i < SA1100_DMA_CHANNELS; i++)
-               if (regs == (dma_regs_t *)&DDAR(i))
-                       break;
-       if (i >= SA1100_DMA_CHANNELS) {
-               printk(KERN_ERR "%s: bad DMA identifier\n", __func__);
-               return;
-       }
-
-       regs->ClrDCSR =
-               (DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB |
-                DCSR_IE | DCSR_ERROR | DCSR_RUN);
-       regs->DDAR = dma_chan[i].device;
-}
-
-
-EXPORT_SYMBOL(sa1100_request_dma);
-EXPORT_SYMBOL(sa1100_free_dma);
-EXPORT_SYMBOL(sa1100_start_dma);
-EXPORT_SYMBOL(sa1100_get_dma_pos);
-EXPORT_SYMBOL(sa1100_reset_dma);
-
index bb10ee2cb89f11f82c801d7f9c1d8ced11c1c3b7..1d0f71b17a2670a9ac30aed6bcfc163bf810afc1 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <linux/pm.h>
 #include <linux/cpufreq.h>
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
 
+#include <video/sa1100fb.h>
+
 #include <asm/div64.h>
-#include <mach/hardware.h>
 #include <asm/system.h>
 #include <asm/mach/map.h>
 #include <asm/mach/flash.h>
 #include <asm/irq.h>
 
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
 #include "generic.h"
 
 unsigned int reset_status;
@@ -149,16 +154,8 @@ static void sa11x0_register_device(struct platform_device *dev, void *data)
 
 
 static struct resource sa11x0udc_resources[] = {
-       [0] = {
-               .start  = __PREG(Ser0UDCCR),
-               .end    = __PREG(Ser0UDCCR) + 0xffff,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_Ser0UDC,
-               .end    = IRQ_Ser0UDC,
-               .flags  = IORESOURCE_IRQ,
-       },
+       [0] = DEFINE_RES_MEM(__PREG(Ser0UDCCR), SZ_64K),
+       [1] = DEFINE_RES_IRQ(IRQ_Ser0UDC),
 };
 
 static u64 sa11x0udc_dma_mask = 0xffffffffUL;
@@ -175,16 +172,8 @@ static struct platform_device sa11x0udc_device = {
 };
 
 static struct resource sa11x0uart1_resources[] = {
-       [0] = {
-               .start  = __PREG(Ser1UTCR0),
-               .end    = __PREG(Ser1UTCR0) + 0xffff,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_Ser1UART,
-               .end    = IRQ_Ser1UART,
-               .flags  = IORESOURCE_IRQ,
-       },
+       [0] = DEFINE_RES_MEM(__PREG(Ser1UTCR0), SZ_64K),
+       [1] = DEFINE_RES_IRQ(IRQ_Ser1UART),
 };
 
 static struct platform_device sa11x0uart1_device = {
@@ -195,16 +184,8 @@ static struct platform_device sa11x0uart1_device = {
 };
 
 static struct resource sa11x0uart3_resources[] = {
-       [0] = {
-               .start  = __PREG(Ser3UTCR0),
-               .end    = __PREG(Ser3UTCR0) + 0xffff,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_Ser3UART,
-               .end    = IRQ_Ser3UART,
-               .flags  = IORESOURCE_IRQ,
-       },
+       [0] = DEFINE_RES_MEM(__PREG(Ser3UTCR0), SZ_64K),
+       [1] = DEFINE_RES_IRQ(IRQ_Ser3UART),
 };
 
 static struct platform_device sa11x0uart3_device = {
@@ -215,16 +196,9 @@ static struct platform_device sa11x0uart3_device = {
 };
 
 static struct resource sa11x0mcp_resources[] = {
-       [0] = {
-               .start  = __PREG(Ser4MCCR0),
-               .end    = __PREG(Ser4MCCR0) + 0xffff,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_Ser4MCP,
-               .end    = IRQ_Ser4MCP,
-               .flags  = IORESOURCE_IRQ,
-       },
+       [0] = DEFINE_RES_MEM(__PREG(Ser4MCCR0), SZ_64K),
+       [1] = DEFINE_RES_MEM(__PREG(Ser4MCCR1), 4),
+       [2] = DEFINE_RES_IRQ(IRQ_Ser4MCP),
 };
 
 static u64 sa11x0mcp_dma_mask = 0xffffffffUL;
@@ -240,22 +214,24 @@ static struct platform_device sa11x0mcp_device = {
        .resource       = sa11x0mcp_resources,
 };
 
+void __init sa11x0_ppc_configure_mcp(void)
+{
+       /* Setup the PPC unit for the MCP */
+       PPDR &= ~PPC_RXD4;
+       PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+       PSDR |= PPC_RXD4;
+       PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+       PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+}
+
 void sa11x0_register_mcp(struct mcp_plat_data *data)
 {
        sa11x0_register_device(&sa11x0mcp_device, data);
 }
 
 static struct resource sa11x0ssp_resources[] = {
-       [0] = {
-               .start  = 0x80070000,
-               .end    = 0x8007ffff,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_Ser4SSP,
-               .end    = IRQ_Ser4SSP,
-               .flags  = IORESOURCE_IRQ,
-       },
+       [0] = DEFINE_RES_MEM(0x80070000, SZ_64K),
+       [1] = DEFINE_RES_IRQ(IRQ_Ser4SSP),
 };
 
 static u64 sa11x0ssp_dma_mask = 0xffffffffUL;
@@ -272,16 +248,8 @@ static struct platform_device sa11x0ssp_device = {
 };
 
 static struct resource sa11x0fb_resources[] = {
-       [0] = {
-               .start  = 0xb0100000,
-               .end    = 0xb010ffff,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_LCD,
-               .end    = IRQ_LCD,
-               .flags  = IORESOURCE_IRQ,
-       },
+       [0] = DEFINE_RES_MEM(0xb0100000, SZ_64K),
+       [1] = DEFINE_RES_IRQ(IRQ_LCD),
 };
 
 static struct platform_device sa11x0fb_device = {
@@ -294,6 +262,11 @@ static struct platform_device sa11x0fb_device = {
        .resource       = sa11x0fb_resources,
 };
 
+void sa11x0_register_lcd(struct sa1100fb_mach_info *inf)
+{
+       sa11x0_register_device(&sa11x0fb_device, inf);
+}
+
 static struct platform_device sa11x0pcmcia_device = {
        .name           = "sa11x0-pcmcia",
        .id             = -1,
@@ -314,23 +287,10 @@ void sa11x0_register_mtd(struct flash_platform_data *flash,
 }
 
 static struct resource sa11x0ir_resources[] = {
-       {
-               .start  = __PREG(Ser2UTCR0),
-               .end    = __PREG(Ser2UTCR0) + 0x24 - 1,
-               .flags  = IORESOURCE_MEM,
-       }, {
-               .start  = __PREG(Ser2HSCR0),
-               .end    = __PREG(Ser2HSCR0) + 0x1c - 1,
-               .flags  = IORESOURCE_MEM,
-       }, {
-               .start  = __PREG(Ser2HSCR2),
-               .end    = __PREG(Ser2HSCR2) + 0x04 - 1,
-               .flags  = IORESOURCE_MEM,
-       }, {
-               .start  = IRQ_Ser2ICP,
-               .end    = IRQ_Ser2ICP,
-               .flags  = IORESOURCE_IRQ,
-       }
+       DEFINE_RES_MEM(__PREG(Ser2UTCR0), 0x24),
+       DEFINE_RES_MEM(__PREG(Ser2HSCR0), 0x1c),
+       DEFINE_RES_MEM(__PREG(Ser2HSCR2), 0x04),
+       DEFINE_RES_IRQ(IRQ_Ser2ICP),
 };
 
 static struct platform_device sa11x0ir_device = {
@@ -345,9 +305,40 @@ void sa11x0_register_irda(struct irda_platform_data *irda)
        sa11x0_register_device(&sa11x0ir_device, irda);
 }
 
+static struct resource sa1100_rtc_resources[] = {
+       DEFINE_RES_MEM(0x90010000, 0x9001003f),
+       DEFINE_RES_IRQ_NAMED(IRQ_RTC1Hz, "rtc 1Hz"),
+       DEFINE_RES_IRQ_NAMED(IRQ_RTCAlrm, "rtc alarm"),
+};
+
 static struct platform_device sa11x0rtc_device = {
        .name           = "sa1100-rtc",
        .id             = -1,
+       .num_resources  = ARRAY_SIZE(sa1100_rtc_resources),
+       .resource       = sa1100_rtc_resources,
+};
+
+static struct resource sa11x0dma_resources[] = {
+       DEFINE_RES_MEM(DMA_PHYS, DMA_SIZE),
+       DEFINE_RES_IRQ(IRQ_DMA0),
+       DEFINE_RES_IRQ(IRQ_DMA1),
+       DEFINE_RES_IRQ(IRQ_DMA2),
+       DEFINE_RES_IRQ(IRQ_DMA3),
+       DEFINE_RES_IRQ(IRQ_DMA4),
+       DEFINE_RES_IRQ(IRQ_DMA5),
+};
+
+static u64 sa11x0dma_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device sa11x0dma_device = {
+       .name           = "sa11x0-dma",
+       .id             = -1,
+       .dev = {
+               .dma_mask = &sa11x0dma_dma_mask,
+               .coherent_dma_mask = 0xffffffff,
+       },
+       .num_resources  = ARRAY_SIZE(sa11x0dma_resources),
+       .resource       = sa11x0dma_resources,
 };
 
 static struct platform_device *sa11x0_devices[] __initdata = {
@@ -356,8 +347,8 @@ static struct platform_device *sa11x0_devices[] __initdata = {
        &sa11x0uart3_device,
        &sa11x0ssp_device,
        &sa11x0pcmcia_device,
-       &sa11x0fb_device,
        &sa11x0rtc_device,
+       &sa11x0dma_device,
 };
 
 static int __init sa1100_init(void)
@@ -368,12 +359,6 @@ static int __init sa1100_init(void)
 
 arch_initcall(sa1100_init);
 
-void (*sa1100fb_backlight_power)(int on);
-void (*sa1100fb_lcd_power)(int on);
-
-EXPORT_SYMBOL(sa1100fb_backlight_power);
-EXPORT_SYMBOL(sa1100fb_lcd_power);
-
 
 /*
  * Common I/O mapping:
@@ -428,7 +413,7 @@ void __init sa1100_map_io(void)
  * the MBGNT signal false to ensure the SA1111 doesn't own the
  * SDRAM bus.
  */
-void __init sa1110_mb_disable(void)
+void sa1110_mb_disable(void)
 {
        unsigned long flags;
 
@@ -447,7 +432,7 @@ void __init sa1110_mb_disable(void)
  * If the system is going to use the SA-1111 DMA engines, set up
  * the memory bus request/grant pins.
  */
-void __devinit sa1110_mb_enable(void)
+void sa1110_mb_enable(void)
 {
        unsigned long flags;
 
index 33268cf6be368e3feab4195d3e9222834ad53802..9eb3b3cd5a63501f18297676fc8c32dbdca21b57 100644 (file)
@@ -16,9 +16,6 @@ extern void sa11x0_restart(char, const char *);
        mi->bank[__nr].start = (__start), \
        mi->bank[__nr].size = (__size)
 
-extern void (*sa1100fb_backlight_power)(int on);
-extern void (*sa1100fb_lcd_power)(int on);
-
 extern void sa1110_mb_enable(void);
 extern void sa1110_mb_disable(void);
 
@@ -39,4 +36,8 @@ struct irda_platform_data;
 void sa11x0_register_irda(struct irda_platform_data *irda);
 
 struct mcp_plat_data;
+void sa11x0_ppc_configure_mcp(void);
 void sa11x0_register_mcp(struct mcp_plat_data *data);
+
+struct sa1100fb_mach_info;
+void sa11x0_register_lcd(struct sa1100fb_mach_info *inf);
index 1e6b3c105ba660c82cf72f3718caf33be87b19a3..b2e8d0f418e09ef08ce2529d25defc7f9ef6aa9e 100644 (file)
 #include <linux/kernel.h>
 #include <linux/gpio.h>
 
+#include <video/sa1100fb.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/irda.h>
 
 #include <mach/h3xxx.h>
+#include <mach/irqs.h>
 
 #include "generic.h"
 
@@ -36,13 +39,28 @@ static void h3100_lcd_power(int enable)
        }
 }
 
+static struct sa1100fb_mach_info h3100_lcd_info = {
+       .pixclock       = 406977,       .bpp            = 4,
+       .xres           = 320,          .yres           = 240,
+
+       .hsync_len      = 26,           .vsync_len      = 41,
+       .left_margin    = 4,            .upper_margin   = 0,
+       .right_margin   = 4,            .lower_margin   = 0,
+
+       .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+       .cmap_greyscale = 1,
+       .cmap_inverse   = 1,
+
+       .lccr0          = LCCR0_Mono | LCCR0_4PixMono | LCCR0_Sngl | LCCR0_Pas,
+       .lccr3          = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
+
+       .lcd_power = h3100_lcd_power,
+};
 
 static void __init h3100_map_io(void)
 {
        h3xxx_map_io();
 
-       sa1100fb_lcd_power = h3100_lcd_power;
-
        /* Older bootldrs put GPIO2-9 in alternate mode on the
           assumption that they are used for video */
        GAFR &= ~0x000001fb;
@@ -80,12 +98,15 @@ static void __init h3100_mach_init(void)
 {
        h3xxx_init_gpio(h3100_default_gpio, ARRAY_SIZE(h3100_default_gpio));
        h3xxx_mach_init();
+
+       sa11x0_register_lcd(&h3100_lcd_info);
        sa11x0_register_irda(&h3100_irda_data);
 }
 
 MACHINE_START(H3100, "Compaq iPAQ H3100")
        .atag_offset    = 0x100,
        .map_io         = h3100_map_io,
+       .nr_irqs        = SA1100_NR_IRQS,
        .init_irq       = sa1100_init_irq,
        .timer          = &sa1100_timer,
        .init_machine   = h3100_mach_init,
index 6b58e7460ecf8cd384af16aabf4d4f9023373abf..cb6659f294fe37b35687fefd448d5d572a3ed274 100644 (file)
 #include <linux/kernel.h>
 #include <linux/gpio.h>
 
+#include <video/sa1100fb.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/irda.h>
 
 #include <mach/h3xxx.h>
+#include <mach/irqs.h>
 
 #include "generic.h"
 
@@ -56,11 +59,35 @@ err2:       gpio_free(H3XXX_EGPIO_LCD_ON);
 err1:  return;
 }
 
+static const struct sa1100fb_rgb h3600_rgb_16 = {
+       .red    = { .offset = 12, .length = 4, },
+       .green  = { .offset = 7,  .length = 4, },
+       .blue   = { .offset = 1,  .length = 4, },
+       .transp = { .offset = 0,  .length = 0, },
+};
+
+static struct sa1100fb_mach_info h3600_lcd_info = {
+       .pixclock       = 174757,       .bpp            = 16,
+       .xres           = 320,          .yres           = 240,
+
+       .hsync_len      = 3,            .vsync_len      = 3,
+       .left_margin    = 12,           .upper_margin   = 10,
+       .right_margin   = 17,           .lower_margin   = 1,
+
+       .cmap_static    = 1,
+
+       .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+       .lccr3          = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
+
+       .rgb[RGB_16] = &h3600_rgb_16,
+
+       .lcd_power = h3600_lcd_power,
+};
+
+
 static void __init h3600_map_io(void)
 {
        h3xxx_map_io();
-
-       sa1100fb_lcd_power = h3600_lcd_power;
 }
 
 /*
@@ -121,12 +148,15 @@ static void __init h3600_mach_init(void)
 {
        h3xxx_init_gpio(h3600_default_gpio, ARRAY_SIZE(h3600_default_gpio));
        h3xxx_mach_init();
+
+       sa11x0_register_lcd(&h3600_lcd_info);
        sa11x0_register_irda(&h3600_irda_data);
 }
 
 MACHINE_START(H3600, "Compaq iPAQ H3600")
        .atag_offset    = 0x100,
        .map_io         = h3600_map_io,
+       .nr_irqs        = SA1100_NR_IRQS,
        .init_irq       = sa1100_init_irq,
        .timer          = &sa1100_timer,
        .init_machine   = h3600_mach_init,
index b0784c974c2deda1ecc76f24d296a9937f13bd85..63150e1ffe9ecee4f45355ba41d92d3f02119216 100644 (file)
@@ -109,11 +109,8 @@ static struct flash_platform_data h3xxx_flash_data = {
        .nr_parts       = ARRAY_SIZE(h3xxx_partitions),
 };
 
-static struct resource h3xxx_flash_resource = {
-       .start          = SA1100_CS0_PHYS,
-       .end            = SA1100_CS0_PHYS + SZ_32M - 1,
-       .flags          = IORESOURCE_MEM,
-};
+static struct resource h3xxx_flash_resource =
+       DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
 
 
 /*
@@ -186,11 +183,7 @@ static struct sa1100_port_fns h3xxx_port_fns __initdata = {
  */
 
 static struct resource egpio_resources[] = {
-       [0] = {
-               .start  = H3600_EGPIO_PHYS,
-               .end    = H3600_EGPIO_PHYS + 0x4 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
+       [0] = DEFINE_RES_MEM(H3600_EGPIO_PHYS, 0x4),
 };
 
 static struct htc_egpio_chip egpio_chips[] = {
index c01bb36db94099357770feee2deb3ecbac4f5c6f..5535475bf58334b222733bd5fd6d16b76360aa66 100644 (file)
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/setup.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include <asm/irq.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
@@ -35,6 +33,9 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/serial_sa1100.h>
 
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
 #include "generic.h"
 
 /**********************************************************************
@@ -179,11 +180,8 @@ static struct flash_platform_data hackkit_flash_data = {
        .nr_parts       = ARRAY_SIZE(hackkit_partitions),
 };
 
-static struct resource hackkit_flash_resource = {
-       .start          = SA1100_CS0_PHYS,
-       .end            = SA1100_CS0_PHYS + SZ_32M,
-       .flags          = IORESOURCE_MEM,
-};
+static struct resource hackkit_flash_resource =
+       DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
 
 static void __init hackkit_init(void)
 {
@@ -197,6 +195,7 @@ static void __init hackkit_init(void)
 MACHINE_START(HACKKIT, "HackKit Cpu Board")
        .atag_offset    = 0x100,
        .map_io         = hackkit_map_io,
+       .nr_irqs        = SA1100_NR_IRQS,
        .init_irq       = sa1100_init_irq,
        .timer          = &sa1100_timer,
        .init_machine   = hackkit_init,
index bae8296f5dbf6afc30d6d169222d1a274d47bde8..3f2d1b60188c4a7573b18b1dd0bb4ad56a438c6a 100644 (file)
 
 /*
  * Direct Memory Access (DMA) control registers
- *
- * Registers
- *    DDAR0            Direct Memory Access (DMA) Device Address Register
- *                     channel 0 (read/write).
- *    DCSR0            Direct Memory Access (DMA) Control and Status
- *                     Register channel 0 (read/write).
- *    DBSA0            Direct Memory Access (DMA) Buffer Start address
- *                     register A channel 0 (read/write).
- *    DBTA0            Direct Memory Access (DMA) Buffer Transfer count
- *                     register A channel 0 (read/write).
- *    DBSB0            Direct Memory Access (DMA) Buffer Start address
- *                     register B channel 0 (read/write).
- *    DBTB0            Direct Memory Access (DMA) Buffer Transfer count
- *                     register B channel 0 (read/write).
- *
- *    DDAR1            Direct Memory Access (DMA) Device Address Register
- *                     channel 1 (read/write).
- *    DCSR1            Direct Memory Access (DMA) Control and Status
- *                     Register channel 1 (read/write).
- *    DBSA1            Direct Memory Access (DMA) Buffer Start address
- *                     register A channel 1 (read/write).
- *    DBTA1            Direct Memory Access (DMA) Buffer Transfer count
- *                     register A channel 1 (read/write).
- *    DBSB1            Direct Memory Access (DMA) Buffer Start address
- *                     register B channel 1 (read/write).
- *    DBTB1            Direct Memory Access (DMA) Buffer Transfer count
- *                     register B channel 1 (read/write).
- *
- *    DDAR2            Direct Memory Access (DMA) Device Address Register
- *                     channel 2 (read/write).
- *    DCSR2            Direct Memory Access (DMA) Control and Status
- *                     Register channel 2 (read/write).
- *    DBSA2            Direct Memory Access (DMA) Buffer Start address
- *                     register A channel 2 (read/write).
- *    DBTA2            Direct Memory Access (DMA) Buffer Transfer count
- *                     register A channel 2 (read/write).
- *    DBSB2            Direct Memory Access (DMA) Buffer Start address
- *                     register B channel 2 (read/write).
- *    DBTB2            Direct Memory Access (DMA) Buffer Transfer count
- *                     register B channel 2 (read/write).
- *
- *    DDAR3            Direct Memory Access (DMA) Device Address Register
- *                     channel 3 (read/write).
- *    DCSR3            Direct Memory Access (DMA) Control and Status
- *                     Register channel 3 (read/write).
- *    DBSA3            Direct Memory Access (DMA) Buffer Start address
- *                     register A channel 3 (read/write).
- *    DBTA3            Direct Memory Access (DMA) Buffer Transfer count
- *                     register A channel 3 (read/write).
- *    DBSB3            Direct Memory Access (DMA) Buffer Start address
- *                     register B channel 3 (read/write).
- *    DBTB3            Direct Memory Access (DMA) Buffer Transfer count
- *                     register B channel 3 (read/write).
- *
- *    DDAR4            Direct Memory Access (DMA) Device Address Register
- *                     channel 4 (read/write).
- *    DCSR4            Direct Memory Access (DMA) Control and Status
- *                     Register channel 4 (read/write).
- *    DBSA4            Direct Memory Access (DMA) Buffer Start address
- *                     register A channel 4 (read/write).
- *    DBTA4            Direct Memory Access (DMA) Buffer Transfer count
- *                     register A channel 4 (read/write).
- *    DBSB4            Direct Memory Access (DMA) Buffer Start address
- *                     register B channel 4 (read/write).
- *    DBTB4            Direct Memory Access (DMA) Buffer Transfer count
- *                     register B channel 4 (read/write).
- *
- *    DDAR5            Direct Memory Access (DMA) Device Address Register
- *                     channel 5 (read/write).
- *    DCSR5            Direct Memory Access (DMA) Control and Status
- *                     Register channel 5 (read/write).
- *    DBSA5            Direct Memory Access (DMA) Buffer Start address
- *                     register A channel 5 (read/write).
- *    DBTA5            Direct Memory Access (DMA) Buffer Transfer count
- *                     register A channel 5 (read/write).
- *    DBSB5            Direct Memory Access (DMA) Buffer Start address
- *                     register B channel 5 (read/write).
- *    DBTB5            Direct Memory Access (DMA) Buffer Transfer count
- *                     register B channel 5 (read/write).
  */
-
-#define DMASp          0x00000020      /* DMA control reg. Space [byte]   */
-
-#define DDAR(Nb)       __REG(0xB0000000 + (Nb)*DMASp)  /* DMA Device Address Reg. channel [0..5] */
-#define SetDCSR(Nb)    __REG(0xB0000004 + (Nb)*DMASp)  /* Set DMA Control & Status Reg. channel [0..5] (write) */
-#define ClrDCSR(Nb)    __REG(0xB0000008 + (Nb)*DMASp)  /* Clear DMA Control & Status Reg. channel [0..5] (write) */
-#define RdDCSR(Nb)     __REG(0xB000000C + (Nb)*DMASp)  /* Read DMA Control & Status Reg. channel [0..5] (read) */
-#define DBSA(Nb)       __REG(0xB0000010 + (Nb)*DMASp)  /* DMA Buffer Start address reg. A channel [0..5] */
-#define DBTA(Nb)       __REG(0xB0000014 + (Nb)*DMASp)  /* DMA Buffer Transfer count reg. A channel [0..5] */
-#define DBSB(Nb)       __REG(0xB0000018 + (Nb)*DMASp)  /* DMA Buffer Start address reg. B channel [0..5] */
-#define DBTB(Nb)       __REG(0xB000001C + (Nb)*DMASp)  /* DMA Buffer Transfer count reg. B channel [0..5] */
-
-#define DDAR_RW        0x00000001      /* device data Read/Write          */
-#define DDAR_DevWr     (DDAR_RW*0)     /*  Device data Write              */
-                                       /*  (memory -> device)             */
-#define DDAR_DevRd     (DDAR_RW*1)     /*  Device data Read               */
-                                       /*  (device -> memory)             */
-#define DDAR_E         0x00000002      /* big/little Endian device        */
-#define DDAR_LtlEnd    (DDAR_E*0)      /*  Little Endian device           */
-#define DDAR_BigEnd    (DDAR_E*1)      /*  Big Endian device              */
-#define DDAR_BS        0x00000004      /* device Burst Size               */
-#define DDAR_Brst4     (DDAR_BS*0)     /*  Burst-of-4 device              */
-#define DDAR_Brst8     (DDAR_BS*1)     /*  Burst-of-8 device              */
-#define DDAR_DW        0x00000008      /* device Data Width               */
-#define DDAR_8BitDev   (DDAR_DW*0)     /*  8-Bit Device                   */
-#define DDAR_16BitDev  (DDAR_DW*1)     /*  16-Bit Device                  */
-#define DDAR_DS        Fld (4, 4)      /* Device Select                   */
-#define DDAR_Ser0UDCTr                 /*  Ser. port 0 UDC Transmit       */ \
-                       (0x0 << FShft (DDAR_DS))
-#define DDAR_Ser0UDCRc                 /*  Ser. port 0 UDC Receive        */ \
-                       (0x1 << FShft (DDAR_DS))
-#define DDAR_Ser1SDLCTr                        /*  Ser. port 1 SDLC Transmit      */ \
-                       (0x2 << FShft (DDAR_DS))
-#define DDAR_Ser1SDLCRc                        /*  Ser. port 1 SDLC Receive       */ \
-                       (0x3 << FShft (DDAR_DS))
-#define DDAR_Ser1UARTTr                        /*  Ser. port 1 UART Transmit      */ \
-                       (0x4 << FShft (DDAR_DS))
-#define DDAR_Ser1UARTRc                        /*  Ser. port 1 UART Receive       */ \
-                       (0x5 << FShft (DDAR_DS))
-#define DDAR_Ser2ICPTr                 /*  Ser. port 2 ICP Transmit       */ \
-                       (0x6 << FShft (DDAR_DS))
-#define DDAR_Ser2ICPRc                 /*  Ser. port 2 ICP Receive        */ \
-                       (0x7 << FShft (DDAR_DS))
-#define DDAR_Ser3UARTTr                        /*  Ser. port 3 UART Transmit      */ \
-                       (0x8 << FShft (DDAR_DS))
-#define DDAR_Ser3UARTRc                        /*  Ser. port 3 UART Receive       */ \
-                       (0x9 << FShft (DDAR_DS))
-#define DDAR_Ser4MCP0Tr                        /*  Ser. port 4 MCP 0 Transmit     */ \
-                                       /*  (audio)                        */ \
-                       (0xA << FShft (DDAR_DS))
-#define DDAR_Ser4MCP0Rc                        /*  Ser. port 4 MCP 0 Receive      */ \
-                                       /*  (audio)                        */ \
-                       (0xB << FShft (DDAR_DS))
-#define DDAR_Ser4MCP1Tr                        /*  Ser. port 4 MCP 1 Transmit     */ \
-                                       /*  (telecom)                      */ \
-                       (0xC << FShft (DDAR_DS))
-#define DDAR_Ser4MCP1Rc                        /*  Ser. port 4 MCP 1 Receive      */ \
-                                       /*  (telecom)                      */ \
-                       (0xD << FShft (DDAR_DS))
-#define DDAR_Ser4SSPTr                 /*  Ser. port 4 SSP Transmit       */ \
-                       (0xE << FShft (DDAR_DS))
-#define DDAR_Ser4SSPRc                 /*  Ser. port 4 SSP Receive        */ \
-                       (0xF << FShft (DDAR_DS))
-#define DDAR_DA        Fld (24, 8)     /* Device Address                  */
-#define DDAR_DevAdd(Add)               /*  Device Address                 */ \
-                       (((Add) & 0xF0000000) | \
-                        (((Add) & 0X003FFFFC) << (FShft (DDAR_DA) - 2)))
-#define DDAR_Ser0UDCWr                 /* Ser. port 0 UDC Write           */ \
-                       (DDAR_DevWr + DDAR_Brst8 + DDAR_8BitDev + \
-                        DDAR_Ser0UDCTr + DDAR_DevAdd (__PREG(Ser0UDCDR)))
-#define DDAR_Ser0UDCRd                 /* Ser. port 0 UDC Read            */ \
-                       (DDAR_DevRd + DDAR_Brst8 + DDAR_8BitDev + \
-                        DDAR_Ser0UDCRc + DDAR_DevAdd (__PREG(Ser0UDCDR)))
-#define DDAR_Ser1UARTWr                        /* Ser. port 1 UART Write          */ \
-                       (DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \
-                        DDAR_Ser1UARTTr + DDAR_DevAdd (__PREG(Ser1UTDR)))
-#define DDAR_Ser1UARTRd                        /* Ser. port 1 UART Read           */ \
-                       (DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \
-                        DDAR_Ser1UARTRc + DDAR_DevAdd (__PREG(Ser1UTDR)))
-#define DDAR_Ser1SDLCWr                        /* Ser. port 1 SDLC Write          */ \
-                       (DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \
-                        DDAR_Ser1SDLCTr + DDAR_DevAdd (__PREG(Ser1SDDR)))
-#define DDAR_Ser1SDLCRd                        /* Ser. port 1 SDLC Read           */ \
-                       (DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \
-                        DDAR_Ser1SDLCRc + DDAR_DevAdd (__PREG(Ser1SDDR)))
-#define DDAR_Ser2UARTWr                        /* Ser. port 2 UART Write          */ \
-                       (DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \
-                        DDAR_Ser2ICPTr + DDAR_DevAdd (__PREG(Ser2UTDR)))
-#define DDAR_Ser2UARTRd                        /* Ser. port 2 UART Read           */ \
-                       (DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \
-                        DDAR_Ser2ICPRc + DDAR_DevAdd (__PREG(Ser2UTDR)))
-#define DDAR_Ser2HSSPWr                        /* Ser. port 2 HSSP Write          */ \
-                       (DDAR_DevWr + DDAR_Brst8 + DDAR_8BitDev + \
-                        DDAR_Ser2ICPTr + DDAR_DevAdd (__PREG(Ser2HSDR)))
-#define DDAR_Ser2HSSPRd                        /* Ser. port 2 HSSP Read           */ \
-                       (DDAR_DevRd + DDAR_Brst8 + DDAR_8BitDev + \
-                        DDAR_Ser2ICPRc + DDAR_DevAdd (__PREG(Ser2HSDR)))
-#define DDAR_Ser3UARTWr                        /* Ser. port 3 UART Write          */ \
-                       (DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \
-                        DDAR_Ser3UARTTr + DDAR_DevAdd (__PREG(Ser3UTDR)))
-#define DDAR_Ser3UARTRd                        /* Ser. port 3 UART Read           */ \
-                       (DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \
-                        DDAR_Ser3UARTRc + DDAR_DevAdd (__PREG(Ser3UTDR)))
-#define DDAR_Ser4MCP0Wr                        /* Ser. port 4 MCP 0 Write (audio) */ \
-                       (DDAR_DevWr + DDAR_Brst4 + DDAR_16BitDev + \
-                        DDAR_Ser4MCP0Tr + DDAR_DevAdd (__PREG(Ser4MCDR0)))
-#define DDAR_Ser4MCP0Rd                        /* Ser. port 4 MCP 0 Read (audio)  */ \
-                       (DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \
-                        DDAR_Ser4MCP0Rc + DDAR_DevAdd (__PREG(Ser4MCDR0)))
-#define DDAR_Ser4MCP1Wr                        /* Ser. port 4 MCP 1 Write         */ \
-                                       /* (telecom)                       */ \
-                       (DDAR_DevWr + DDAR_Brst4 + DDAR_16BitDev + \
-                        DDAR_Ser4MCP1Tr + DDAR_DevAdd (__PREG(Ser4MCDR1)))
-#define DDAR_Ser4MCP1Rd                        /* Ser. port 4 MCP 1 Read          */ \
-                                       /* (telecom)                       */ \
-                       (DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \
-                        DDAR_Ser4MCP1Rc + DDAR_DevAdd (__PREG(Ser4MCDR1)))
-#define DDAR_Ser4SSPWr                 /* Ser. port 4 SSP Write (16 bits) */ \
-                       (DDAR_DevWr + DDAR_Brst4 + DDAR_16BitDev + \
-                        DDAR_Ser4SSPTr + DDAR_DevAdd (__PREG(Ser4SSDR)))
-#define DDAR_Ser4SSPRd                 /* Ser. port 4 SSP Read (16 bits)  */ \
-                       (DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \
-                        DDAR_Ser4SSPRc + DDAR_DevAdd (__PREG(Ser4SSDR)))
-
-#define DCSR_RUN       0x00000001      /* DMA running                     */
-#define DCSR_IE        0x00000002      /* DMA Interrupt Enable            */
-#define DCSR_ERROR     0x00000004      /* DMA ERROR                       */
-#define DCSR_DONEA     0x00000008      /* DONE DMA transfer buffer A      */
-#define DCSR_STRTA     0x00000010      /* STaRTed DMA transfer buffer A   */
-#define DCSR_DONEB     0x00000020      /* DONE DMA transfer buffer B      */
-#define DCSR_STRTB     0x00000040      /* STaRTed DMA transfer buffer B   */
-#define DCSR_BIU       0x00000080      /* DMA Buffer In Use               */
-#define DCSR_BufA      (DCSR_BIU*0)    /*  DMA Buffer A in use            */
-#define DCSR_BufB      (DCSR_BIU*1)    /*  DMA Buffer B in use            */
-
-#define DBT_TC         Fld (13, 0)     /* Transfer Count                  */
-#define DBTA_TCA       DBT_TC          /* Transfer Count buffer A         */
-#define DBTB_TCB       DBT_TC          /* Transfer Count buffer B         */
+#define DMA_SIZE       (6 * 0x20)
+#define DMA_PHYS       0xb0000000
 
 
 /*
 #define LCD_Int100_0A  0xF             /* LCD Intensity = 100.0% =  1     */
                                        /* (Alternative)                   */
 
-#define LCCR0          __REG(0xB0100000)  /* LCD Control Reg. 0 */
-#define LCSR           __REG(0xB0100004)  /* LCD Status Reg. */
-#define DBAR1          __REG(0xB0100010)  /* LCD DMA Base Address Reg. channel 1 */
-#define DCAR1          __REG(0xB0100014)  /* LCD DMA Current Address Reg. channel 1 */
-#define DBAR2          __REG(0xB0100018)  /* LCD DMA Base Address Reg.  channel 2 */
-#define DCAR2          __REG(0xB010001C)  /* LCD DMA Current Address Reg. channel 2 */
-#define LCCR1          __REG(0xB0100020)  /* LCD Control Reg. 1 */
-#define LCCR2          __REG(0xB0100024)  /* LCD Control Reg. 2 */
-#define LCCR3          __REG(0xB0100028)  /* LCD Control Reg. 3 */
-
 #define LCCR0_LEN      0x00000001      /* LCD ENable                      */
 #define LCCR0_CMS      0x00000002      /* Color/Monochrome display Select */
 #define LCCR0_Color    (LCCR0_CMS*0)   /*  Color display                  */
diff --git a/arch/arm/mach-sa1100/include/mach/dma.h b/arch/arm/mach-sa1100/include/mach/dma.h
deleted file mode 100644 (file)
index dda1b35..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * arch/arm/mach-sa1100/include/mach/dma.h
- *
- * Generic SA1100 DMA support
- *
- * Copyright (C) 2000 Nicolas Pitre
- *
- */
-
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H
-
-#include "hardware.h"
-
-
-/*
- * The SA1100 has six internal DMA channels.
- */
-#define SA1100_DMA_CHANNELS    6
-
-/*
- * Maximum physical DMA buffer size
- */
-#define MAX_DMA_SIZE           0x1fff
-#define CUT_DMA_SIZE           0x1000
-
-/*
- * All possible SA1100 devices a DMA channel can be attached to.
- */
-typedef enum {
-       DMA_Ser0UDCWr  = DDAR_Ser0UDCWr,   /* Ser. port 0 UDC Write */
-       DMA_Ser0UDCRd  = DDAR_Ser0UDCRd,   /* Ser. port 0 UDC Read */
-       DMA_Ser1UARTWr = DDAR_Ser1UARTWr,  /* Ser. port 1 UART Write */
-       DMA_Ser1UARTRd = DDAR_Ser1UARTRd,  /* Ser. port 1 UART Read */
-       DMA_Ser1SDLCWr = DDAR_Ser1SDLCWr,  /* Ser. port 1 SDLC Write */
-       DMA_Ser1SDLCRd = DDAR_Ser1SDLCRd,  /* Ser. port 1 SDLC Read */
-       DMA_Ser2UARTWr = DDAR_Ser2UARTWr,  /* Ser. port 2 UART Write */
-       DMA_Ser2UARTRd = DDAR_Ser2UARTRd,  /* Ser. port 2 UART Read */
-       DMA_Ser2HSSPWr = DDAR_Ser2HSSPWr,  /* Ser. port 2 HSSP Write */
-       DMA_Ser2HSSPRd = DDAR_Ser2HSSPRd,  /* Ser. port 2 HSSP Read */
-       DMA_Ser3UARTWr = DDAR_Ser3UARTWr,  /* Ser. port 3 UART Write */
-       DMA_Ser3UARTRd = DDAR_Ser3UARTRd,  /* Ser. port 3 UART Read */
-       DMA_Ser4MCP0Wr = DDAR_Ser4MCP0Wr,  /* Ser. port 4 MCP 0 Write (audio) */
-       DMA_Ser4MCP0Rd = DDAR_Ser4MCP0Rd,  /* Ser. port 4 MCP 0 Read (audio) */
-       DMA_Ser4MCP1Wr = DDAR_Ser4MCP1Wr,  /* Ser. port 4 MCP 1 Write */
-       DMA_Ser4MCP1Rd = DDAR_Ser4MCP1Rd,  /* Ser. port 4 MCP 1 Read */
-       DMA_Ser4SSPWr  = DDAR_Ser4SSPWr,   /* Ser. port 4 SSP Write (16 bits) */
-       DMA_Ser4SSPRd  = DDAR_Ser4SSPRd    /* Ser. port 4 SSP Read (16 bits) */
-} dma_device_t;
-
-typedef struct {
-       volatile u_long DDAR;
-       volatile u_long SetDCSR;
-       volatile u_long ClrDCSR;
-       volatile u_long RdDCSR;
-       volatile dma_addr_t DBSA;
-       volatile u_long DBTA;
-       volatile dma_addr_t DBSB;
-       volatile u_long DBTB;
-} dma_regs_t;
-
-typedef void (*dma_callback_t)(void *data);
-
-/*
- * DMA function prototypes
- */
-
-extern int sa1100_request_dma( dma_device_t device, const char *device_id,
-                              dma_callback_t callback, void *data,
-                              dma_regs_t **regs );
-extern void sa1100_free_dma( dma_regs_t *regs );
-extern int sa1100_start_dma( dma_regs_t *regs, dma_addr_t dma_ptr, u_int size );
-extern dma_addr_t sa1100_get_dma_pos(dma_regs_t *regs);
-extern void sa1100_reset_dma(dma_regs_t *regs);
-
-/**
- *     sa1100_stop_dma - stop DMA in progress
- *     @regs: identifier for the channel to use
- *
- *     This stops DMA without clearing buffer pointers. Unlike
- *     sa1100_clear_dma() this allows subsequent use of sa1100_resume_dma()
- *     or sa1100_get_dma_pos().
- *
- *     The @regs identifier is provided by a successful call to
- *     sa1100_request_dma().
- **/
-
-#define sa1100_stop_dma(regs)  ((regs)->ClrDCSR = DCSR_IE|DCSR_RUN)
-
-/**
- *     sa1100_resume_dma - resume DMA on a stopped channel
- *     @regs: identifier for the channel to use
- *
- *     This resumes DMA on a channel previously stopped with
- *     sa1100_stop_dma().
- *
- *     The @regs identifier is provided by a successful call to
- *     sa1100_request_dma().
- **/
-
-#define sa1100_resume_dma(regs)        ((regs)->SetDCSR = DCSR_IE|DCSR_RUN)
-
-/**
- *     sa1100_clear_dma - clear DMA pointers
- *     @regs: identifier for the channel to use
- *
- *     This clear any DMA state so the DMA engine is ready to restart
- *     with new buffers through sa1100_start_dma(). Any buffers in flight
- *     are discarded.
- *
- *     The @regs identifier is provided by a successful call to
- *     sa1100_request_dma().
- **/
-
-#define sa1100_clear_dma(regs) ((regs)->ClrDCSR = DCSR_IE|DCSR_RUN|DCSR_STRTA|DCSR_STRTB)
-
-#endif /* _ASM_ARCH_DMA_H */
index d18f21abef80f51275922fc2ec9f5975720edd8b..3790298b7142abcadd36f7103c462966e1f62e68 100644 (file)
 /*
  * Figure out the MAX IRQ number.
  *
- * If we have an SA1111, the max IRQ is S1_BVD1_STSCHG+1.
- * If we have an LoCoMo, the max IRQ is IRQ_BOARD_START + 4
- * Otherwise, we have the standard IRQs only.
+ * Neponset, SA1111 and UCB1x00 are sparse IRQ aware, so can dynamically
+ * allocate their IRQs above NR_IRQS.
+ *
+ * LoCoMo has 4 additional IRQs, but is not sparse IRQ aware, and so has
+ * to be included in the NR_IRQS calculation.
  */
-#ifdef CONFIG_SA1111
-#define NR_IRQS                        (IRQ_BOARD_END + 55)
-#elif defined(CONFIG_SHARP_LOCOMO)
-#define NR_IRQS                        (IRQ_BOARD_START + 4)
+#ifdef CONFIG_SHARP_LOCOMO
+#define NR_IRQS_LOCOMO         4
 #else
-#define NR_IRQS                        (IRQ_BOARD_START)
+#define NR_IRQS_LOCOMO         0
 #endif
 
-/*
- * Board specific IRQs.  Define them here.
- * Do not surround them with ifdefs.
- */
-#define IRQ_NEPONSET_SMC9196   (IRQ_BOARD_START + 0)
-#define IRQ_NEPONSET_USAR      (IRQ_BOARD_START + 1)
-#define IRQ_NEPONSET_SA1111    (IRQ_BOARD_START + 2)
+#ifndef NR_IRQS
+#define NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)
+#endif
+#define SA1100_NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)
index ed1a331508a754bf2e802f537689a97ee2b524c5..4b2860ae3828ef7ab6b5e934de636626a64fcb55 100644 (file)
@@ -16,7 +16,7 @@ struct mcp_plat_data {
        u32 mccr0;
        u32 mccr1;
        unsigned int sclk_rate;
-       int gpio_base;
+       void *codec_pdata;
 };
 
 #endif
index ffe2bc45eed0a7b6fb4706251efef2b4d18691b6..5516a52a329d66e167fe6bc435f0130764747387 100644 (file)
 /*
  * Neponset definitions: 
  */
-
-#define NEPONSET_CPLD_BASE      (0x10000000)
-#define Nep_p2v( x )            ((x) - NEPONSET_CPLD_BASE + 0xf3000000)
-#define Nep_v2p( x )            ((x) - 0xf3000000 + NEPONSET_CPLD_BASE)
-
-#define _IRR                    0x10000024      /* Interrupt Reason Register */
-#define _AUD_CTL                0x100000c0      /* Audio controls (RW)       */
-#define _MDM_CTL_0              0x100000b0      /* Modem control 0 (RW)      */
-#define _MDM_CTL_1              0x100000b4      /* Modem control 1 (RW)      */
-#define _NCR_0                 0x100000a0      /* Control Register (RW)     */
-#define _KP_X_OUT               0x10000090      /* Keypad row write (RW)     */
-#define _KP_Y_IN                0x10000080      /* Keypad column read (RO)   */
-#define _SWPK                   0x10000020      /* Switch pack (RO)          */
-#define _WHOAMI                 0x10000000      /* System ID Register (RO)   */
-
-#define _LEDS                   0x10000010      /* LEDs [31:0] (WO)          */
-
-#define IRR                     (*((volatile u_char *) Nep_p2v(_IRR)))
-#define AUD_CTL                 (*((volatile u_char *) Nep_p2v(_AUD_CTL)))
-#define MDM_CTL_0               (*((volatile u_char *) Nep_p2v(_MDM_CTL_0)))
-#define MDM_CTL_1               (*((volatile u_char *) Nep_p2v(_MDM_CTL_1)))
-#define NCR_0                  (*((volatile u_char *) Nep_p2v(_NCR_0)))
-#define KP_X_OUT                (*((volatile u_char *) Nep_p2v(_KP_X_OUT)))
-#define KP_Y_IN                 (*((volatile u_char *) Nep_p2v(_KP_Y_IN)))
-#define SWPK                    (*((volatile u_char *) Nep_p2v(_SWPK)))
-#define WHOAMI                  (*((volatile u_char *) Nep_p2v(_WHOAMI)))
-
-#define LEDS                    (*((volatile Word   *) Nep_p2v(_LEDS)))
-
-#define IRR_ETHERNET           (1<<0)
-#define IRR_USAR               (1<<1)
-#define IRR_SA1111             (1<<2)
-
-#define AUD_SEL_1341            (1<<0)
-#define AUD_MUTE_1341           (1<<1)
-
-#define MDM_CTL0_RTS1          (1 << 0)
-#define MDM_CTL0_DTR1          (1 << 1)
-#define MDM_CTL0_RTS2          (1 << 2)
-#define MDM_CTL0_DTR2          (1 << 3)
-
-#define MDM_CTL1_CTS1          (1 << 0)
-#define MDM_CTL1_DSR1          (1 << 1)
-#define MDM_CTL1_DCD1          (1 << 2)
-#define MDM_CTL1_CTS2          (1 << 3)
-#define MDM_CTL1_DSR2          (1 << 4)
-#define MDM_CTL1_DCD2          (1 << 5)
-
 #define NCR_GP01_OFF           (1<<0)
 #define NCR_TP_PWR_EN          (1<<1)
 #define NCR_MS_PWR_EN          (1<<2)
@@ -71,4 +23,8 @@
 #define NCR_A0VPP              (1<<5)
 #define NCR_A1VPP              (1<<6)
 
+void neponset_ncr_frob(unsigned int, unsigned int);
+#define neponset_ncr_set(v)    neponset_ncr_frob(0, v)
+#define neponset_ncr_clear(v)  neponset_ncr_frob(v, 0)
+
 #endif
index 019f857a79384a49222bc115c7d651108967d889..fff39e02b4965667d73ef6bde31a9dfb0ff7412a 100644 (file)
@@ -21,7 +21,7 @@
 #define SHANNON_GPIO_U3_RTS            GPIO_GPIO (19)  /* ?? */
 #define SHANNON_GPIO_U3_CTS            GPIO_GPIO (20)  /* ?? */
 #define SHANNON_GPIO_SENSE_12V         GPIO_GPIO (21)  /* Input, 12v flash unprotect detected */
-#define SHANNON_GPIO_DISP_EN           GPIO_GPIO (22)  /* out */
+#define SHANNON_GPIO_DISP_EN           22              /* out */
 /* XXX GPIO 23 unaccounted for */
 #define SHANNON_GPIO_EJECT_0           24              /* in */
 #define SHANNON_GPIO_EJECT_1           25              /* in */
index dfbf824a69fab02326dbc52a8c1ac2799dbacc71..516ccc25d7fd0ae7df5f76f2ecf693a40be9f817 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/syscore_ops.h>
 
 #include <mach/hardware.h>
+#include <mach/irqs.h>
 #include <asm/mach/irq.h>
 
 #include "generic.h"
@@ -221,11 +222,8 @@ static struct irq_chip sa1100_normal_chip = {
        .irq_set_wake   = sa1100_set_wake,
 };
 
-static struct resource irq_resource = {
-       .name   = "irqs",
-       .start  = 0x90050000,
-       .end    = 0x9005ffff,
-};
+static struct resource irq_resource =
+       DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs");
 
 static struct sa1100irq_state {
        unsigned int    saved;
index ee121d6f048021489f014728924904990d07a858..ca7a7e834720a1cb3ef692f35f1d1b09ec2cf5f0 100644 (file)
@@ -23,9 +23,7 @@
 #include <linux/mtd/partitions.h>
 #include <video/s1d13xxxfb.h>
 
-#include <mach/hardware.h>
 #include <asm/hardware/sa1111.h>
-#include <asm/irq.h>
 #include <asm/page.h>
 #include <asm/mach-types.h>
 #include <asm/setup.h>
@@ -34,6 +32,9 @@
 #include <asm/mach/map.h>
 #include <asm/mach/serial_sa1100.h>
 
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
 #include "generic.h"
 
 /*
@@ -46,7 +47,7 @@
 
 /* memory space (line 52 of HP's doc) */
 #define SA1111REGSTART 0x40000000
-#define SA1111REGLEN   0x00001fff
+#define SA1111REGLEN   0x00002000
 #define EPSONREGSTART  0x48000000
 #define EPSONREGLEN    0x00100000
 #define EPSONFBSTART   0x48200000
@@ -174,16 +175,8 @@ static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
 };
 
 static struct resource s1d13xxxfb_resources[] = {
-       [0] = {
-               .start  = EPSONFBSTART,
-               .end    = EPSONFBSTART + EPSONFBLEN,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = EPSONREGSTART,
-               .end    = EPSONREGSTART + EPSONREGLEN,
-               .flags  = IORESOURCE_MEM,
-       }
+       [0] = DEFINE_RES_MEM(EPSONFBSTART, EPSONFBLEN),
+       [1] = DEFINE_RES_MEM(EPSONREGSTART, EPSONREGLEN),
 };
 
 static struct platform_device s1d13xxxfb_device = {
@@ -197,20 +190,12 @@ static struct platform_device s1d13xxxfb_device = {
 };
 
 static struct resource sa1111_resources[] = {
-       [0] = {
-               .start          = SA1111REGSTART,
-               .end            = SA1111REGSTART + SA1111REGLEN,
-               .flags          = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start          = IRQ_GPIO1,
-               .end            = IRQ_GPIO1,
-               .flags          = IORESOURCE_IRQ,
-       },
+       [0] = DEFINE_RES_MEM(SA1111REGSTART, SA1111REGLEN),
+       [1] = DEFINE_RES_IRQ(IRQ_GPIO1),
 };
 
 static struct sa1111_platform_data sa1111_info = {
-       .irq_base       = IRQ_BOARD_END,
+       .disable_devs   = SA1111_DEVID_PS2_MSE,
 };
 
 static u64 sa1111_dmamask = 0xffffffffUL;
@@ -284,11 +269,6 @@ static struct map_desc jornada720_io_desc[] __initdata = {
                .pfn            = __phys_to_pfn(EPSONFBSTART),
                .length         = EPSONFBLEN,
                .type           = MT_DEVICE
-       }, {    /* SA-1111 */
-               .virtual        = 0xf4000000,
-               .pfn            = __phys_to_pfn(SA1111REGSTART),
-               .length         = SA1111REGLEN,
-               .type           = MT_DEVICE
        }
 };
 
@@ -352,11 +332,8 @@ static struct flash_platform_data jornada720_flash_data = {
        .nr_parts       = ARRAY_SIZE(jornada720_partitions),
 };
 
-static struct resource jornada720_flash_resource = {
-       .start          = SA1100_CS0_PHYS,
-       .end            = SA1100_CS0_PHYS + SZ_32M - 1,
-       .flags          = IORESOURCE_MEM,
-};
+static struct resource jornada720_flash_resource =
+       DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
 
 static void __init jornada720_mach_init(void)
 {
@@ -367,6 +344,7 @@ MACHINE_START(JORNADA720, "HP Jornada 720")
        /* Maintainer: Kristoffer Ericson <Kristoffer.Ericson@gmail.com> */
        .atag_offset    = 0x100,
        .map_io         = jornada720_map_io,
+       .nr_irqs        = SA1100_NR_IRQS,
        .init_irq       = sa1100_init_irq,
        .timer          = &sa1100_timer,
        .init_machine   = jornada720_mach_init,
index af4e2761f3dbf4a6254bfab53f98080334e5f387..eb6534e0b0d01c64e1ee88fa65bd23fbadaea99d 100644 (file)
@@ -6,6 +6,8 @@
 #include <linux/kernel.h>
 #include <linux/tty.h>
 
+#include <video/sa1100fb.h>
+
 #include <mach/hardware.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
@@ -15,6 +17,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/serial_sa1100.h>
 #include <mach/mcp.h>
+#include <mach/irqs.h>
 
 #include "generic.h"
 
@@ -26,8 +29,86 @@ static struct mcp_plat_data lart_mcp_data = {
        .sclk_rate      = 11981000,
 };
 
+#ifdef LART_GREY_LCD
+static struct sa1100fb_mach_info lart_grey_info = {
+       .pixclock       = 150000,       .bpp            = 4,
+       .xres           = 320,          .yres           = 240,
+
+       .hsync_len      = 1,            .vsync_len      = 1,
+       .left_margin    = 4,            .upper_margin   = 0,
+       .right_margin   = 2,            .lower_margin   = 0,
+
+       .cmap_greyscale = 1,
+       .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+       .lccr0          = LCCR0_Mono | LCCR0_Sngl | LCCR0_Pas | LCCR0_4PixMono,
+       .lccr3          = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
+};
+#endif
+#ifdef LART_COLOR_LCD
+static struct sa1100fb_mach_info lart_color_info = {
+       .pixclock       = 150000,       .bpp            = 16,
+       .xres           = 320,          .yres           = 240,
+
+       .hsync_len      = 2,            .vsync_len      = 3,
+       .left_margin    = 69,           .upper_margin   = 14,
+       .right_margin   = 8,            .lower_margin   = 4,
+
+       .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+       .lccr3          = LCCR3_OutEnH | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
+};
+#endif
+#ifdef LART_VIDEO_OUT
+static struct sa1100fb_mach_info lart_video_info = {
+       .pixclock       = 39721,        .bpp            = 16,
+       .xres           = 640,          .yres           = 480,
+
+       .hsync_len      = 95,           .vsync_len      = 2,
+       .left_margin    = 40,           .upper_margin   = 32,
+       .right_margin   = 24,           .lower_margin   = 11,
+
+       .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+       .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+       .lccr3          = LCCR3_OutEnL | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
+};
+#endif
+
+#ifdef LART_KIT01_LCD
+static struct sa1100fb_mach_info lart_kit01_info = {
+       .pixclock       = 63291,        .bpp            = 16,
+       .xres           = 640,          .yres           = 480,
+
+       .hsync_len      = 64,           .vsync_len      = 3,
+       .left_margin    = 122,          .upper_margin   = 45,
+       .right_margin   = 10,           .lower_margin   = 10,
+
+       .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+       .lccr3          = LCCR3_OutEnH | LCCR3_PixFlEdg
+};
+#endif
+
 static void __init lart_init(void)
 {
+       struct sa1100fb_mach_info *inf = NULL;
+
+#ifdef LART_GREY_LCD
+       inf = &lart_grey_info;
+#endif
+#ifdef LART_COLOR_LCD
+       inf = &lart_color_info;
+#endif
+#ifdef LART_VIDEO_OUT
+       inf = &lart_video_info;
+#endif
+#ifdef LART_KIT01_LCD
+       inf = &lart_kit01_info;
+#endif
+
+       if (inf)
+               sa11x0_register_lcd(inf);
+
+       sa11x0_ppc_configure_mcp();
        sa11x0_register_mcp(&lart_mcp_data);
 }
 
@@ -63,6 +144,7 @@ static void __init lart_map_io(void)
 MACHINE_START(LART, "LART")
        .atag_offset    = 0x100,
        .map_io         = lart_map_io,
+       .nr_irqs        = SA1100_NR_IRQS,
        .init_irq       = sa1100_init_irq,
        .init_machine   = lart_init,
        .timer          = &sa1100_timer,
index 85f6ee672225956a38e9f275ec4c5aa34614b169..8f6446b9f025231669c19aa84ad2fed17d057e62 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <mach/hardware.h>
 #include <mach/nanoengine.h>
+#include <mach/irqs.h>
 
 #include "generic.h"
 
@@ -58,15 +59,8 @@ static struct flash_platform_data nanoengine_flash_data = {
 };
 
 static struct resource nanoengine_flash_resources[] = {
-       {
-               .start  = SA1100_CS0_PHYS,
-               .end    = SA1100_CS0_PHYS + SZ_32M - 1,
-               .flags  = IORESOURCE_MEM,
-       }, {
-               .start  = SA1100_CS1_PHYS,
-               .end    = SA1100_CS1_PHYS + SZ_32M - 1,
-               .flags  = IORESOURCE_MEM,
-       }
+       DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M),
+       DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_32M),
 };
 
 static struct map_desc nanoengine_io_desc[] __initdata = {
@@ -114,6 +108,7 @@ static void __init nanoengine_init(void)
 MACHINE_START(NANOENGINE, "BSE nanoEngine")
        .atag_offset    = 0x100,
        .map_io         = nanoengine_map_io,
+       .nr_irqs        = SA1100_NR_IRQS,
        .init_irq       = sa1100_init_irq,
        .timer          = &sa1100_timer,
        .init_machine   = nanoengine_init,
index b4fa53a1427e437a8592c9d4f8f947ba32742ad2..6c58f01b358a1064db6a869ee2cbac52b4b8ba0a 100644 (file)
 /*
  * linux/arch/arm/mach-sa1100/neponset.c
- *
  */
-#include <linux/kernel.h>
+#include <linux/err.h>
 #include <linux/init.h>
-#include <linux/tty.h>
 #include <linux/ioport.h>
-#include <linux/serial_core.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/serial_core.h>
+#include <linux/slab.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <asm/irq.h>
 #include <asm/mach/map.h>
-#include <asm/mach/irq.h>
 #include <asm/mach/serial_sa1100.h>
-#include <mach/assabet.h>
-#include <mach/neponset.h>
 #include <asm/hardware/sa1111.h>
 #include <asm/sizes.h>
 
-/*
- * Install handler for Neponset IRQ.  Note that we have to loop here
- * since the ETHERNET and USAR IRQs are level based, and we need to
- * ensure that the IRQ signal is deasserted before returning.  This
- * is rather unfortunate.
- */
-static void
-neponset_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
-       unsigned int irr;
-
-       while (1) {
-               /*
-                * Acknowledge the parent IRQ.
-                */
-               desc->irq_data.chip->irq_ack(&desc->irq_data);
-
-               /*
-                * Read the interrupt reason register.  Let's have all
-                * active IRQ bits high.  Note: there is a typo in the
-                * Neponset user's guide for the SA1111 IRR level.
-                */
-               irr = IRR ^ (IRR_ETHERNET | IRR_USAR);
-
-               if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0)
-                       break;
-
-               /*
-                * Since there is no individual mask, we have to
-                * mask the parent IRQ.  This is safe, since we'll
-                * recheck the register for any pending IRQs.
-                */
-               if (irr & (IRR_ETHERNET | IRR_USAR)) {
-                       desc->irq_data.chip->irq_mask(&desc->irq_data);
-
-                       /*
-                        * Ack the interrupt now to prevent re-entering
-                        * this neponset handler.  Again, this is safe
-                        * since we'll check the IRR register prior to
-                        * leaving.
-                        */
-                       desc->irq_data.chip->irq_ack(&desc->irq_data);
+#include <mach/hardware.h>
+#include <mach/assabet.h>
+#include <mach/neponset.h>
+#include <mach/irqs.h>
+
+#define NEP_IRQ_SMC91X 0
+#define NEP_IRQ_USAR   1
+#define NEP_IRQ_SA1111 2
+#define NEP_IRQ_NR     3
+
+#define WHOAMI         0x00
+#define LEDS           0x10
+#define SWPK           0x20
+#define IRR            0x24
+#define KP_Y_IN                0x80
+#define KP_X_OUT       0x90
+#define NCR_0          0xa0
+#define MDM_CTL_0      0xb0
+#define MDM_CTL_1      0xb4
+#define AUD_CTL                0xc0
+
+#define IRR_ETHERNET   (1 << 0)
+#define IRR_USAR       (1 << 1)
+#define IRR_SA1111     (1 << 2)
+
+#define MDM_CTL0_RTS1  (1 << 0)
+#define MDM_CTL0_DTR1  (1 << 1)
+#define MDM_CTL0_RTS2  (1 << 2)
+#define MDM_CTL0_DTR2  (1 << 3)
+
+#define MDM_CTL1_CTS1  (1 << 0)
+#define MDM_CTL1_DSR1  (1 << 1)
+#define MDM_CTL1_DCD1  (1 << 2)
+#define MDM_CTL1_CTS2  (1 << 3)
+#define MDM_CTL1_DSR2  (1 << 4)
+#define MDM_CTL1_DCD2  (1 << 5)
+
+#define AUD_SEL_1341   (1 << 0)
+#define AUD_MUTE_1341  (1 << 1)
 
-                       if (irr & IRR_ETHERNET) {
-                               generic_handle_irq(IRQ_NEPONSET_SMC9196);
-                       }
+extern void sa1110_mb_disable(void);
 
-                       if (irr & IRR_USAR) {
-                               generic_handle_irq(IRQ_NEPONSET_USAR);
-                       }
+struct neponset_drvdata {
+       void __iomem *base;
+       struct platform_device *sa1111;
+       struct platform_device *smc91x;
+       unsigned irq_base;
+#ifdef CONFIG_PM_SLEEP
+       u32 ncr0;
+       u32 mdm_ctl_0;
+#endif
+};
 
-                       desc->irq_data.chip->irq_unmask(&desc->irq_data);
-               }
+static void __iomem *nep_base;
 
-               if (irr & IRR_SA1111) {
-                       generic_handle_irq(IRQ_NEPONSET_SA1111);
-               }
+void neponset_ncr_frob(unsigned int mask, unsigned int val)
+{
+       void __iomem *base = nep_base;
+
+       if (base) {
+               unsigned long flags;
+               unsigned v;
+
+               local_irq_save(flags);
+               v = readb_relaxed(base + NCR_0);
+               writeb_relaxed((v & ~mask) | val, base + NCR_0);
+               local_irq_restore(flags);
+       } else {
+               WARN(1, "nep_base unset\n");
        }
 }
 
 static void neponset_set_mctrl(struct uart_port *port, u_int mctrl)
 {
-       u_int mdm_ctl0 = MDM_CTL_0;
+       void __iomem *base = nep_base;
+       u_int mdm_ctl0;
 
+       if (!base)
+               return;
+
+       mdm_ctl0 = readb_relaxed(base + MDM_CTL_0);
        if (port->mapbase == _Ser1UTCR0) {
                if (mctrl & TIOCM_RTS)
                        mdm_ctl0 &= ~MDM_CTL0_RTS2;
@@ -106,14 +121,19 @@ static void neponset_set_mctrl(struct uart_port *port, u_int mctrl)
                        mdm_ctl0 |= MDM_CTL0_DTR1;
        }
 
-       MDM_CTL_0 = mdm_ctl0;
+       writeb_relaxed(mdm_ctl0, base + MDM_CTL_0);
 }
 
 static u_int neponset_get_mctrl(struct uart_port *port)
 {
+       void __iomem *base = nep_base;
        u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
-       u_int mdm_ctl1 = MDM_CTL_1;
+       u_int mdm_ctl1;
+
+       if (!base)
+               return ret;
 
+       mdm_ctl1 = readb_relaxed(base + MDM_CTL_1);
        if (port->mapbase == _Ser1UTCR0) {
                if (mdm_ctl1 & MDM_CTL1_DCD2)
                        ret &= ~TIOCM_CD;
@@ -138,209 +158,278 @@ static struct sa1100_port_fns neponset_port_fns __devinitdata = {
        .get_mctrl      = neponset_get_mctrl,
 };
 
-static int __devinit neponset_probe(struct platform_device *dev)
+/*
+ * Install handler for Neponset IRQ.  Note that we have to loop here
+ * since the ETHERNET and USAR IRQs are level based, and we need to
+ * ensure that the IRQ signal is deasserted before returning.  This
+ * is rather unfortunate.
+ */
+static void neponset_irq_handler(unsigned int irq, struct irq_desc *desc)
 {
-       sa1100_register_uart_fns(&neponset_port_fns);
+       struct neponset_drvdata *d = irq_desc_get_handler_data(desc);
+       unsigned int irr;
 
-       /*
-        * Install handler for GPIO25.
-        */
-       irq_set_irq_type(IRQ_GPIO25, IRQ_TYPE_EDGE_RISING);
-       irq_set_chained_handler(IRQ_GPIO25, neponset_irq_handler);
+       while (1) {
+               /*
+                * Acknowledge the parent IRQ.
+                */
+               desc->irq_data.chip->irq_ack(&desc->irq_data);
 
-       /*
-        * We would set IRQ_GPIO25 to be a wake-up IRQ, but
-        * unfortunately something on the Neponset activates
-        * this IRQ on sleep (ethernet?)
-        */
-#if 0
-       enable_irq_wake(IRQ_GPIO25);
-#endif
+               /*
+                * Read the interrupt reason register.  Let's have all
+                * active IRQ bits high.  Note: there is a typo in the
+                * Neponset user's guide for the SA1111 IRR level.
+                */
+               irr = readb_relaxed(d->base + IRR);
+               irr ^= IRR_ETHERNET | IRR_USAR;
 
-       /*
-        * Setup other Neponset IRQs.  SA1111 will be done by the
-        * generic SA1111 code.
-        */
-       irq_set_handler(IRQ_NEPONSET_SMC9196, handle_simple_irq);
-       set_irq_flags(IRQ_NEPONSET_SMC9196, IRQF_VALID | IRQF_PROBE);
-       irq_set_handler(IRQ_NEPONSET_USAR, handle_simple_irq);
-       set_irq_flags(IRQ_NEPONSET_USAR, IRQF_VALID | IRQF_PROBE);
+               if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0)
+                       break;
 
-       /*
-        * Disable GPIO 0/1 drivers so the buttons work on the module.
-        */
-       NCR_0 = NCR_GP01_OFF;
+               /*
+                * Since there is no individual mask, we have to
+                * mask the parent IRQ.  This is safe, since we'll
+                * recheck the register for any pending IRQs.
+                */
+               if (irr & (IRR_ETHERNET | IRR_USAR)) {
+                       desc->irq_data.chip->irq_mask(&desc->irq_data);
 
-       return 0;
-}
+                       /*
+                        * Ack the interrupt now to prevent re-entering
+                        * this neponset handler.  Again, this is safe
+                        * since we'll check the IRR register prior to
+                        * leaving.
+                        */
+                       desc->irq_data.chip->irq_ack(&desc->irq_data);
 
-#ifdef CONFIG_PM
+                       if (irr & IRR_ETHERNET)
+                               generic_handle_irq(d->irq_base + NEP_IRQ_SMC91X);
 
-/*
- * LDM power management.
- */
-static unsigned int neponset_saved_state;
+                       if (irr & IRR_USAR)
+                               generic_handle_irq(d->irq_base + NEP_IRQ_USAR);
 
-static int neponset_suspend(struct platform_device *dev, pm_message_t state)
-{
-       /*
-        * Save state.
-        */
-       neponset_saved_state = NCR_0;
+                       desc->irq_data.chip->irq_unmask(&desc->irq_data);
+               }
 
-       return 0;
+               if (irr & IRR_SA1111)
+                       generic_handle_irq(d->irq_base + NEP_IRQ_SA1111);
+       }
 }
 
-static int neponset_resume(struct platform_device *dev)
+/* Yes, we really do not have any kind of masking or unmasking */
+static void nochip_noop(struct irq_data *irq)
 {
-       NCR_0 = neponset_saved_state;
-
-       return 0;
 }
 
-#else
-#define neponset_suspend NULL
-#define neponset_resume  NULL
-#endif
-
-static struct platform_driver neponset_device_driver = {
-       .probe          = neponset_probe,
-       .suspend        = neponset_suspend,
-       .resume         = neponset_resume,
-       .driver         = {
-               .name   = "neponset",
-       },
-};
-
-static struct resource neponset_resources[] = {
-       [0] = {
-               .start  = 0x10000000,
-               .end    = 0x17ffffff,
-               .flags  = IORESOURCE_MEM,
-       },
-};
-
-static struct platform_device neponset_device = {
-       .name           = "neponset",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(neponset_resources),
-       .resource       = neponset_resources,
-};
-
-static struct resource sa1111_resources[] = {
-       [0] = {
-               .start  = 0x40000000,
-               .end    = 0x40001fff,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_NEPONSET_SA1111,
-               .end    = IRQ_NEPONSET_SA1111,
-               .flags  = IORESOURCE_IRQ,
-       },
+static struct irq_chip nochip = {
+       .name = "neponset",
+       .irq_ack = nochip_noop,
+       .irq_mask = nochip_noop,
+       .irq_unmask = nochip_noop,
 };
 
 static struct sa1111_platform_data sa1111_info = {
-       .irq_base       = IRQ_BOARD_END,
+       .disable_devs   = SA1111_DEVID_PS2_MSE,
 };
 
-static u64 sa1111_dmamask = 0xffffffffUL;
+static int __devinit neponset_probe(struct platform_device *dev)
+{
+       struct neponset_drvdata *d;
+       struct resource *nep_res, *sa1111_res, *smc91x_res;
+       struct resource sa1111_resources[] = {
+               DEFINE_RES_MEM(0x40000000, SZ_8K),
+               { .flags = IORESOURCE_IRQ },
+       };
+       struct platform_device_info sa1111_devinfo = {
+               .parent = &dev->dev,
+               .name = "sa1111",
+               .id = 0,
+               .res = sa1111_resources,
+               .num_res = ARRAY_SIZE(sa1111_resources),
+               .data = &sa1111_info,
+               .size_data = sizeof(sa1111_info),
+               .dma_mask = 0xffffffffUL,
+       };
+       struct resource smc91x_resources[] = {
+               DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS,
+                       0x02000000, "smc91x-regs"),
+               DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS + 0x02000000,
+                       0x02000000, "smc91x-attrib"),
+               { .flags = IORESOURCE_IRQ },
+       };
+       struct platform_device_info smc91x_devinfo = {
+               .parent = &dev->dev,
+               .name = "smc91x",
+               .id = 0,
+               .res = smc91x_resources,
+               .num_res = ARRAY_SIZE(smc91x_resources),
+       };
+       int ret, irq;
+
+       if (nep_base)
+               return -EBUSY;
+
+       irq = ret = platform_get_irq(dev, 0);
+       if (ret < 0)
+               goto err_alloc;
+
+       nep_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       smc91x_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
+       sa1111_res = platform_get_resource(dev, IORESOURCE_MEM, 2);
+       if (!nep_res || !smc91x_res || !sa1111_res) {
+               ret = -ENXIO;
+               goto err_alloc;
+       }
 
-static struct platform_device sa1111_device = {
-       .name           = "sa1111",
-       .id             = 0,
-       .dev            = {
-               .dma_mask = &sa1111_dmamask,
-               .coherent_dma_mask = 0xffffffff,
-               .platform_data = &sa1111_info,
-       },
-       .num_resources  = ARRAY_SIZE(sa1111_resources),
-       .resource       = sa1111_resources,
-};
+       d = kzalloc(sizeof(*d), GFP_KERNEL);
+       if (!d) {
+               ret = -ENOMEM;
+               goto err_alloc;
+       }
 
-static struct resource smc91x_resources[] = {
-       [0] = {
-               .name   = "smc91x-regs",
-               .start  = SA1100_CS3_PHYS,
-               .end    = SA1100_CS3_PHYS + 0x01ffffff,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_NEPONSET_SMC9196,
-               .end    = IRQ_NEPONSET_SMC9196,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .name   = "smc91x-attrib",
-               .start  = SA1100_CS3_PHYS + 0x02000000,
-               .end    = SA1100_CS3_PHYS + 0x03ffffff,
-               .flags  = IORESOURCE_MEM,
-       },
-};
+       d->base = ioremap(nep_res->start, SZ_4K);
+       if (!d->base) {
+               ret = -ENOMEM;
+               goto err_ioremap;
+       }
 
-static struct platform_device smc91x_device = {
-       .name           = "smc91x",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(smc91x_resources),
-       .resource       = smc91x_resources,
-};
+       if (readb_relaxed(d->base + WHOAMI) != 0x11) {
+               dev_warn(&dev->dev, "Neponset board detected, but wrong ID: %02x\n",
+                        readb_relaxed(d->base + WHOAMI));
+               ret = -ENODEV;
+               goto err_id;
+       }
 
-static struct platform_device *devices[] __initdata = {
-       &neponset_device,
-       &sa1111_device,
-       &smc91x_device,
-};
+       ret = irq_alloc_descs(-1, IRQ_BOARD_START, NEP_IRQ_NR, -1);
+       if (ret <= 0) {
+               dev_err(&dev->dev, "unable to allocate %u irqs: %d\n",
+                       NEP_IRQ_NR, ret);
+               if (ret == 0)
+                       ret = -ENOMEM;
+               goto err_irq_alloc;
+       }
 
-extern void sa1110_mb_disable(void);
+       d->irq_base = ret;
 
-static int __init neponset_init(void)
-{
-       platform_driver_register(&neponset_device_driver);
+       irq_set_chip_and_handler(d->irq_base + NEP_IRQ_SMC91X, &nochip,
+               handle_simple_irq);
+       set_irq_flags(d->irq_base + NEP_IRQ_SMC91X, IRQF_VALID | IRQF_PROBE);
+       irq_set_chip_and_handler(d->irq_base + NEP_IRQ_USAR, &nochip,
+               handle_simple_irq);
+       set_irq_flags(d->irq_base + NEP_IRQ_USAR, IRQF_VALID | IRQF_PROBE);
+       irq_set_chip(d->irq_base + NEP_IRQ_SA1111, &nochip);
 
-       /*
-        * The Neponset is only present on the Assabet machine type.
-        */
-       if (!machine_is_assabet())
-               return -ENODEV;
+       irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
+       irq_set_handler_data(irq, d);
+       irq_set_chained_handler(irq, neponset_irq_handler);
 
        /*
-        * Ensure that the memory bus request/grant signals are setup,
-        * and the grant is held in its inactive state, whether or not
-        * we actually have a Neponset attached.
+        * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
+        * something on the Neponset activates this IRQ on sleep (eth?)
         */
+#if 0
+       enable_irq_wake(irq);
+#endif
+
+       dev_info(&dev->dev, "Neponset daughter board, providing IRQ%u-%u\n",
+                d->irq_base, d->irq_base + NEP_IRQ_NR - 1);
+       nep_base = d->base;
+
+       sa1100_register_uart_fns(&neponset_port_fns);
+
+       /* Ensure that the memory bus request/grant signals are setup */
        sa1110_mb_disable();
 
-       if (!machine_has_neponset()) {
-               printk(KERN_DEBUG "Neponset expansion board not present\n");
-               return -ENODEV;
-       }
+       /* Disable GPIO 0/1 drivers so the buttons work on the Assabet */
+       writeb_relaxed(NCR_GP01_OFF, d->base + NCR_0);
 
-       if (WHOAMI != 0x11) {
-               printk(KERN_WARNING "Neponset board detected, but "
-                       "wrong ID: %02x\n", WHOAMI);
-               return -ENODEV;
-       }
+       sa1111_resources[0].parent = sa1111_res;
+       sa1111_resources[1].start = d->irq_base + NEP_IRQ_SA1111;
+       sa1111_resources[1].end = d->irq_base + NEP_IRQ_SA1111;
+       d->sa1111 = platform_device_register_full(&sa1111_devinfo);
+
+       smc91x_resources[0].parent = smc91x_res;
+       smc91x_resources[1].parent = smc91x_res;
+       smc91x_resources[2].start = d->irq_base + NEP_IRQ_SMC91X;
+       smc91x_resources[2].end = d->irq_base + NEP_IRQ_SMC91X;
+       d->smc91x = platform_device_register_full(&smc91x_devinfo);
+
+       platform_set_drvdata(dev, d);
 
-       return platform_add_devices(devices, ARRAY_SIZE(devices));
+       return 0;
+
+ err_irq_alloc:
+ err_id:
+       iounmap(d->base);
+ err_ioremap:
+       kfree(d);
+ err_alloc:
+       return ret;
 }
 
-subsys_initcall(neponset_init);
+static int __devexit neponset_remove(struct platform_device *dev)
+{
+       struct neponset_drvdata *d = platform_get_drvdata(dev);
+       int irq = platform_get_irq(dev, 0);
+
+       if (!IS_ERR(d->sa1111))
+               platform_device_unregister(d->sa1111);
+       if (!IS_ERR(d->smc91x))
+               platform_device_unregister(d->smc91x);
+       irq_set_chained_handler(irq, NULL);
+       irq_free_descs(d->irq_base, NEP_IRQ_NR);
+       nep_base = NULL;
+       iounmap(d->base);
+       kfree(d);
 
-static struct map_desc neponset_io_desc[] __initdata = {
-       {       /* System Registers */
-               .virtual        =  0xf3000000,
-               .pfn            = __phys_to_pfn(0x10000000),
-               .length         = SZ_1M,
-               .type           = MT_DEVICE
-       }, {    /* SA-1111 */
-               .virtual        =  0xf4000000,
-               .pfn            = __phys_to_pfn(0x40000000),
-               .length         = SZ_1M,
-               .type           = MT_DEVICE
-       }
+       return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int neponset_suspend(struct device *dev)
+{
+       struct neponset_drvdata *d = dev_get_drvdata(dev);
+
+       d->ncr0 = readb_relaxed(d->base + NCR_0);
+       d->mdm_ctl_0 = readb_relaxed(d->base + MDM_CTL_0);
+
+       return 0;
+}
+
+static int neponset_resume(struct device *dev)
+{
+       struct neponset_drvdata *d = dev_get_drvdata(dev);
+
+       writeb_relaxed(d->ncr0, d->base + NCR_0);
+       writeb_relaxed(d->mdm_ctl_0, d->base + MDM_CTL_0);
+
+       return 0;
+}
+
+static const struct dev_pm_ops neponset_pm_ops = {
+       .suspend_noirq = neponset_suspend,
+       .resume_noirq = neponset_resume,
+       .freeze_noirq = neponset_suspend,
+       .restore_noirq = neponset_resume,
+};
+#define PM_OPS &neponset_pm_ops
+#else
+#define PM_OPS NULL
+#endif
+
+static struct platform_driver neponset_device_driver = {
+       .probe          = neponset_probe,
+       .remove         = __devexit_p(neponset_remove),
+       .driver         = {
+               .name   = "neponset",
+               .owner  = THIS_MODULE,
+               .pm     = PM_OPS,
+       },
 };
 
-void __init neponset_map_io(void)
+static int __init neponset_init(void)
 {
-       iotable_init(neponset_io_desc, ARRAY_SIZE(neponset_io_desc));
+       return platform_driver_register(&neponset_device_driver);
 }
+
+subsys_initcall(neponset_init);
index b466bca9c651a1dfed4d5ddb20850bba6bf5ae8b..b49108b890a822d99f97e45d17fc889fa1c58f35 100644 (file)
@@ -135,12 +135,8 @@ struct pci_bus * __init pci_nanoengine_scan_bus(int nr, struct pci_sys_data *sys
                                 &sys->resources);
 }
 
-static struct resource pci_io_ports = {
-       .name   = "PCI IO",
-       .start  = 0x400,
-       .end    = 0x7FF,
-       .flags  = IORESOURCE_IO,
-};
+static struct resource pci_io_ports =
+       DEFINE_RES_IO_NAMED(0x400, 0x400, "PCI IO");
 
 static struct resource pci_non_prefetchable_memory = {
        .name   = "PCI non-prefetchable",
index 9307df053533201d1bb5b71d39e196069b24426d..1602575a0d5c47f8c3be09387f1fff63c737e41e 100644 (file)
 #define IRQ_GPIO_ETH0_IRQ      IRQ_GPIO21
 
 static struct resource smc91x_resources[] = {
-       [0] = {
-               .start  = PLEB_ETH0_P,
-               .end    = PLEB_ETH0_P | 0x03ffffff,
-               .flags  = IORESOURCE_MEM,
-       },
+       [0] = DEFINE_RES_MEM(PLEB_ETH0_P, 0x04000000),
 #if 0 /* Autoprobe instead, to get rising/falling edge characteristic right */
-       [1] = {
-               .start  = IRQ_GPIO_ETH0_IRQ,
-               .end    = IRQ_GPIO_ETH0_IRQ,
-               .flags  = IORESOURCE_IRQ,
-       },
+       [1] = DEFINE_RES_IRQ(IRQ_GPIO_ETH0_IRQ),
 #endif
 };
 
@@ -70,16 +62,8 @@ static struct platform_device *devices[] __initdata = {
  * the two SA1100 lowest chip select outputs.
  */
 static struct resource pleb_flash_resources[] = {
-       [0] = {
-               .start = SA1100_CS0_PHYS,
-               .end   = SA1100_CS0_PHYS + SZ_8M - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = SA1100_CS1_PHYS,
-               .end   = SA1100_CS1_PHYS + SZ_8M - 1,
-               .flags = IORESOURCE_MEM,
-       }
+       [0] = DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_8M),
+       [1] = DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_8M),
 };
 
 
@@ -147,6 +131,7 @@ static void __init pleb_map_io(void)
 
 MACHINE_START(PLEB, "PLEB")
        .map_io         = pleb_map_io,
+       .nr_irqs        = SA1100_NR_IRQS,
        .init_irq       = sa1100_init_irq,
        .timer          = &sa1100_timer,
        .init_machine   = pleb_init,
index 318b2b766a0b3ee7b8921c2904b65c0fdd551c8c..ca8bf59b9047d0fe07a31d4fc9dda277271c4b07 100644 (file)
@@ -9,6 +9,8 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 
+#include <video/sa1100fb.h>
+
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/setup.h>
@@ -19,6 +21,7 @@
 #include <asm/mach/serial_sa1100.h>
 #include <mach/mcp.h>
 #include <mach/shannon.h>
+#include <mach/irqs.h>
 
 #include "generic.h"
 
@@ -46,19 +49,32 @@ static struct flash_platform_data shannon_flash_data = {
        .nr_parts       = ARRAY_SIZE(shannon_partitions),
 };
 
-static struct resource shannon_flash_resource = {
-       .start          = SA1100_CS0_PHYS,
-       .end            = SA1100_CS0_PHYS + SZ_4M - 1,
-       .flags          = IORESOURCE_MEM,
-};
+static struct resource shannon_flash_resource =
+       DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_4M);
 
 static struct mcp_plat_data shannon_mcp_data = {
        .mccr0          = MCCR0_ADM,
        .sclk_rate      = 11981000,
 };
 
+static struct sa1100fb_mach_info shannon_lcd_info = {
+       .pixclock       = 152500,       .bpp            = 8,
+       .xres           = 640,          .yres           = 480,
+
+       .hsync_len      = 4,            .vsync_len      = 3,
+       .left_margin    = 2,            .upper_margin   = 0,
+       .right_margin   = 1,            .lower_margin   = 0,
+
+       .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+       .lccr0          = LCCR0_Color | LCCR0_Dual | LCCR0_Pas,
+       .lccr3          = LCCR3_ACBsDiv(512),
+};
+
 static void __init shannon_init(void)
 {
+       sa11x0_ppc_configure_mcp();
+       sa11x0_register_lcd(&shannon_lcd_info);
        sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1);
        sa11x0_register_mcp(&shannon_mcp_data);
 }
@@ -84,6 +100,7 @@ static void __init shannon_map_io(void)
 MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)")
        .atag_offset    = 0x100,
        .map_io         = shannon_map_io,
+       .nr_irqs        = SA1100_NR_IRQS,
        .init_irq       = sa1100_init_irq,
        .timer          = &sa1100_timer,
        .init_machine   = shannon_init,
index e17c04d6e32428af6aa7c8eb1fbc35ca6d7a02d8..3efae03cb3d7defef1f3f88e7112b09addb3a1cf 100644 (file)
@@ -7,15 +7,15 @@
 #include <linux/kernel.h>
 #include <linux/tty.h>
 #include <linux/proc_fs.h>
-#include <linux/string.h> 
+#include <linux/string.h>
 #include <linux/pm.h>
 #include <linux/platform_device.h>
+#include <linux/mfd/ucb1x00.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
 
-#include <asm/irq.h>
 #include <mach/hardware.h>
 #include <asm/setup.h>
 
@@ -26,6 +26,7 @@
 #include <asm/mach/serial_sa1100.h>
 #include <mach/mcp.h>
 #include <mach/simpad.h>
+#include <mach/irqs.h>
 
 #include <linux/serial_core.h>
 #include <linux/ioport.h>
@@ -176,21 +177,18 @@ static struct flash_platform_data simpad_flash_data = {
 
 
 static struct resource simpad_flash_resources [] = {
-       {
-               .start     = SA1100_CS0_PHYS,
-               .end       = SA1100_CS0_PHYS + SZ_16M -1,
-               .flags     = IORESOURCE_MEM,
-       }, {
-               .start     = SA1100_CS1_PHYS,
-               .end       = SA1100_CS1_PHYS + SZ_16M -1,
-               .flags     = IORESOURCE_MEM,
-       }
+       DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_16M),
+       DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_16M),
+};
+
+static struct ucb1x00_plat_data simpad_ucb1x00_data = {
+       .gpio_base      = SIMPAD_UCB1X00_GPIO_BASE,
 };
 
 static struct mcp_plat_data simpad_mcp_data = {
        .mccr0          = MCCR0_ADM,
        .sclk_rate      = 11981000,
-       .gpio_base      = SIMPAD_UCB1X00_GPIO_BASE,
+       .codec_pdata    = &simpad_ucb1x00_data,
 };
 
 
@@ -376,6 +374,7 @@ static int __init simpad_init(void)
 
        pm_power_off = simpad_power_off;
 
+       sa11x0_ppc_configure_mcp();
        sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
                              ARRAY_SIZE(simpad_flash_resources));
        sa11x0_register_mcp(&simpad_mcp_data);
@@ -394,6 +393,7 @@ MACHINE_START(SIMPAD, "Simpad")
        /* Maintainer: Holger Freyther */
        .atag_offset    = 0x100,
        .map_io         = simpad_map_io,
+       .nr_irqs        = SA1100_NR_IRQS,
        .init_irq       = sa1100_init_irq,
        .timer          = &sa1100_timer,
        .restart        = sa11x0_restart,
index e8223315b44271ede96dc94a31d993edda913d6a..30cc6721665bf69821efaaacf92dcc78d220245e 100644 (file)
  *
  * Causes sa11x0 to enter sleep state
  *
+ * Must be aligned to a cacheline.
  */
-
+       .balign 32
 ENTRY(sa1100_finish_suspend)
        @ disable clock switching
        mcr     p15, 0, r1, c15, c2, 2
 
-        @ Adjust memory timing before lowering CPU clock
-       @ Clock speed adjustment without changing memory timing makes
-       @ CPU hang in some cases
-        ldr     r0, =MDREFR
-        ldr     r1, [r0]
-        orr     r1, r1, #MDREFR_K1DB2
-        str     r1, [r0]
+       ldr     r6, =MDREFR
+       ldr     r4, [r6]
+       orr     r4, r4, #MDREFR_K1DB2
+       ldr     r5, =PPCR
+
+       @ Pre-load __udelay into the I-cache
+       mov     r0, #1
+       bl      __udelay
+       mov     r0, r0
+
+       @ The following must all exist in a single cache line to
+       @ avoid accessing memory until this sequence is complete,
+       @ otherwise we occasionally hang.
+
+       @ Adjust memory timing before lowering CPU clock
+       str     r4, [r6]
 
        @ delay 90us and set CPU PLL to lowest speed
        @ fixes resume problem on high speed SA1110
        mov     r0, #90
        bl      __udelay
-       ldr     r0, =PPCR
        mov     r1, #0
-       str     r1, [r0]
+       str     r1, [r5]
        mov     r0, #90
        bl      __udelay
 
@@ -85,12 +94,10 @@ ENTRY(sa1100_finish_suspend)
        bic     r5, r5, #FMsk(MSC_RT)
        bic     r5, r5, #FMsk(MSC_RT)<<16
 
-       ldr     r6, =MDREFR
-
        ldr     r7, [r6]
-bic    r7, r7, #0x0000FF00
-bic    r7, r7, #0x000000F0
-orr    r8, r7, #MDREFR_SLFRSH
+       bic     r7, r7, #0x0000FF00
+       bic     r7, r7, #0x000000F0
+       orr     r8, r7, #MDREFR_SLFRSH
 
        ldr     r9, =MDCNFG
        ldr     r10, [r9]
index b20ff93b84a5a48d26e0e3cc858c803d23cdfdc1..e22fca9ad5ece87073fad090bbf8a11ddf6fbfe7 100644 (file)
@@ -19,8 +19,8 @@
 #include <linux/init.h>
 #include <linux/io.h>
 
-#include <asm/irq.h>
 #include <mach/hardware.h>
+#include <mach/irqs.h>
 #include <asm/hardware/ssp.h>
 
 #define TIMEOUT 100000
index 69e33535dee6df37f5f895274a815cd9ccce6788..6af26e8d55e65c768a8c65e65a88ceebf15f900c 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/mach/time.h>
 #include <asm/sched_clock.h>
 #include <mach/hardware.h>
+#include <mach/irqs.h>
 
 static u32 notrace sa1100_read_sched_clock(void)
 {
index 7ad6954c46cd2e5780528808bdfc20d921a2aa0d..e7c2590b75d9b50f7765760c2843dc10bf1be867 100644 (file)
@@ -16,7 +16,6 @@ obj-$(CONFIG_ARCH_R8A7779)    += setup-r8a7779.o clock-r8a7779.o intc-r8a7779.o
 # SMP objects
 smp-y                          := platsmp.o headsmp.o
 smp-$(CONFIG_HOTPLUG_CPU)      += hotplug.o
-smp-$(CONFIG_LOCAL_TIMERS)     += localtimer.o
 smp-$(CONFIG_ARCH_SH73A0)      += smp-sh73a0.o
 smp-$(CONFIG_ARCH_R8A7779)     += smp-r8a7779.o
 
index 12c431f3443fa590bae541d94e3de0c387221fa8..f50d7c8b1221bc2f9b32b6b3a0414d43a485c2ce 100644 (file)
@@ -47,8 +47,6 @@
 #include <mach/common.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/time.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/traps.h>
@@ -477,27 +475,6 @@ static struct platform_device *ag5evm_devices[] __initdata = {
        &sdhi1_device,
 };
 
-static struct map_desc ag5evm_io_desc[] __initdata = {
-       /* create a 1:1 entity map for 0xe6xxxxxx
-        * used by CPGA, INTC and PFC.
-        */
-       {
-               .virtual        = 0xe6000000,
-               .pfn            = __phys_to_pfn(0xe6000000),
-               .length         = 256 << 20,
-               .type           = MT_DEVICE_NONSHARED
-       },
-};
-
-static void __init ag5evm_map_io(void)
-{
-       iotable_init(ag5evm_io_desc, ARRAY_SIZE(ag5evm_io_desc));
-
-       /* setup early devices and console here as well */
-       sh73a0_add_early_devices();
-       shmobile_setup_console();
-}
-
 static void __init ag5evm_init(void)
 {
        sh73a0_pinmux_init();
@@ -613,22 +590,12 @@ static void __init ag5evm_init(void)
        platform_add_devices(ag5evm_devices, ARRAY_SIZE(ag5evm_devices));
 }
 
-static void __init ag5evm_timer_init(void)
-{
-       sh73a0_clock_init();
-       shmobile_timer.init();
-       return;
-}
-
-struct sys_timer ag5evm_timer = {
-       .init   = ag5evm_timer_init,
-};
-
 MACHINE_START(AG5EVM, "ag5evm")
-       .map_io         = ag5evm_map_io,
+       .map_io         = sh73a0_map_io,
+       .init_early     = sh73a0_add_early_devices,
        .nr_irqs        = NR_IRQS_LEGACY,
        .init_irq       = sh73a0_init_irq,
        .handle_irq     = gic_handle_irq,
        .init_machine   = ag5evm_init,
-       .timer          = &ag5evm_timer,
+       .timer          = &shmobile_timer,
 MACHINE_END
index f90ba5b850a37f300b4f13f93445dd95f6fcd9e1..b56dde2732bbd2b5215c101f6a1ce57f026a712d 100644 (file)
@@ -61,8 +61,6 @@
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/time.h>
 #include <asm/setup.h>
 
 /*
@@ -1188,26 +1186,6 @@ static struct i2c_board_info i2c1_devices[] = {
        },
 };
 
-static struct map_desc ap4evb_io_desc[] __initdata = {
-       /* create a 1:1 entity map for 0xe6xxxxxx
-        * used by CPGA, INTC and PFC.
-        */
-       {
-               .virtual        = 0xe6000000,
-               .pfn            = __phys_to_pfn(0xe6000000),
-               .length         = 256 << 20,
-               .type           = MT_DEVICE_NONSHARED
-       },
-};
-
-static void __init ap4evb_map_io(void)
-{
-       iotable_init(ap4evb_io_desc, ARRAY_SIZE(ap4evb_io_desc));
-
-       /* setup early devices and console here as well */
-       sh7372_add_early_devices();
-       shmobile_setup_console();
-}
 
 #define GPIO_PORT9CR   0xE6051009
 #define GPIO_PORT10CR  0xE605100A
@@ -1217,6 +1195,9 @@ static void __init ap4evb_init(void)
        u32 srcr4;
        struct clk *clk;
 
+       /* External clock source */
+       clk_set_rate(&sh7372_dv_clki_clk, 27000000);
+
        sh7372_pinmux_init();
 
        /* enable SCIFA0 */
@@ -1453,23 +1434,11 @@ static void __init ap4evb_init(void)
        pm_clk_add(&lcdc1_device.dev, "hdmi");
 }
 
-static void __init ap4evb_timer_init(void)
-{
-       sh7372_clock_init();
-       shmobile_timer.init();
-
-       /* External clock source */
-       clk_set_rate(&sh7372_dv_clki_clk, 27000000);
-}
-
-static struct sys_timer ap4evb_timer = {
-       .init           = ap4evb_timer_init,
-};
-
 MACHINE_START(AP4EVB, "ap4evb")
-       .map_io         = ap4evb_map_io,
+       .map_io         = sh7372_map_io,
+       .init_early     = sh7372_add_early_devices,
        .init_irq       = sh7372_init_irq,
        .handle_irq     = shmobile_handle_irq_intc,
        .init_machine   = ap4evb_init,
-       .timer          = &ap4evb_timer,
+       .timer          = &shmobile_timer,
 MACHINE_END
index c79baa9ef61b8ad707e36c20d73aa85d1f6d3245..8b2124da245d46ad2aca08c63e7431ce97e962a2 100644 (file)
@@ -328,28 +328,6 @@ static struct platform_device *bonito_base_devices[] __initdata = {
  * map I/O
  */
 static struct map_desc bonito_io_desc[] __initdata = {
-        /*
-         * for CPGA/INTC/PFC
-         * 0xe6000000-0xefffffff -> 0xe6000000-0xefffffff
-         */
-       {
-               .virtual        = 0xe6000000,
-               .pfn            = __phys_to_pfn(0xe6000000),
-               .length         = 160 << 20,
-               .type           = MT_DEVICE_NONSHARED
-       },
-#ifdef CONFIG_CACHE_L2X0
-       /*
-        * for l2x0_init()
-        * 0xf0100000-0xf0101000 -> 0xf0002000-0xf0003000
-        */
-       {
-               .virtual        = 0xf0002000,
-               .pfn            = __phys_to_pfn(0xf0100000),
-               .length         = PAGE_SIZE,
-               .type           = MT_DEVICE_NONSHARED
-       },
-#endif
        /*
         * for FPGA (0x1800000-0x19ffffff)
         * 0x18000000-0x18002000 -> 0xf0003000-0xf0005000
@@ -364,11 +342,8 @@ static struct map_desc bonito_io_desc[] __initdata = {
 
 static void __init bonito_map_io(void)
 {
+       r8a7740_map_io();
        iotable_init(bonito_io_desc, ARRAY_SIZE(bonito_io_desc));
-
-       /* setup early devices and console here as well */
-       r8a7740_add_early_devices();
-       shmobile_setup_console();
 }
 
 /*
@@ -492,7 +467,7 @@ static void __init bonito_init(void)
        }
 }
 
-static void __init bonito_timer_init(void)
+static void __init bonito_earlytimer_init(void)
 {
        u16 val;
        u8 md_ck = 0;
@@ -507,17 +482,22 @@ static void __init bonito_timer_init(void)
                md_ck |= MD_CK0;
 
        r8a7740_clock_init(md_ck);
-       shmobile_timer.init();
+       shmobile_earlytimer_init();
 }
 
-struct sys_timer bonito_timer = {
-       .init   = bonito_timer_init,
-};
+void __init bonito_add_early_devices(void)
+{
+       r8a7740_add_early_devices();
+
+       /* override timer setup with board-specific code */
+       shmobile_timer.init = bonito_earlytimer_init;
+}
 
 MACHINE_START(BONITO, "bonito")
        .map_io         = bonito_map_io,
+       .init_early     = bonito_add_early_devices,
        .init_irq       = r8a7740_init_irq,
        .handle_irq     = shmobile_handle_irq_intc,
        .init_machine   = bonito_init,
-       .timer          = &bonito_timer,
+       .timer          = &shmobile_timer,
 MACHINE_END
index 72d557281b1f1c115fea5fa538c175e8d20748b8..b627e89037f5e567d15101b1e3fe3051bbfa94c0 100644 (file)
@@ -37,8 +37,6 @@
 #include <mach/common.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/time.h>
 
 /*
  * IrDA
@@ -246,27 +244,6 @@ static struct platform_device *g3evm_devices[] __initdata = {
        &irda_device,
 };
 
-static struct map_desc g3evm_io_desc[] __initdata = {
-       /* create a 1:1 entity map for 0xe6xxxxxx
-        * used by CPGA, INTC and PFC.
-        */
-       {
-               .virtual        = 0xe6000000,
-               .pfn            = __phys_to_pfn(0xe6000000),
-               .length         = 256 << 20,
-               .type           = MT_DEVICE_NONSHARED
-       },
-};
-
-static void __init g3evm_map_io(void)
-{
-       iotable_init(g3evm_io_desc, ARRAY_SIZE(g3evm_io_desc));
-
-       /* setup early devices and console here as well */
-       sh7367_add_early_devices();
-       shmobile_setup_console();
-}
-
 static void __init g3evm_init(void)
 {
        sh7367_pinmux_init();
@@ -354,20 +331,11 @@ static void __init g3evm_init(void)
        platform_add_devices(g3evm_devices, ARRAY_SIZE(g3evm_devices));
 }
 
-static void __init g3evm_timer_init(void)
-{
-       sh7367_clock_init();
-       shmobile_timer.init();
-}
-
-static struct sys_timer g3evm_timer = {
-       .init           = g3evm_timer_init,
-};
-
 MACHINE_START(G3EVM, "g3evm")
-       .map_io         = g3evm_map_io,
+       .map_io         = sh7367_map_io,
+       .init_early     = sh7367_add_early_devices,
        .init_irq       = sh7367_init_irq,
        .handle_irq     = shmobile_handle_irq_intc,
        .init_machine   = g3evm_init,
-       .timer          = &g3evm_timer,
+       .timer          = &shmobile_timer,
 MACHINE_END
index 2220b885cff5731592f1cf6ca3a5a09779795220..46d757d2759d0120c37db14f79ce1d55b5015b11 100644 (file)
@@ -38,8 +38,6 @@
 #include <mach/common.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/time.h>
 
 /*
  * SDHI
@@ -260,27 +258,6 @@ static struct platform_device *g4evm_devices[] __initdata = {
        &sdhi1_device,
 };
 
-static struct map_desc g4evm_io_desc[] __initdata = {
-       /* create a 1:1 entity map for 0xe6xxxxxx
-        * used by CPGA, INTC and PFC.
-        */
-       {
-               .virtual        = 0xe6000000,
-               .pfn            = __phys_to_pfn(0xe6000000),
-               .length         = 256 << 20,
-               .type           = MT_DEVICE_NONSHARED
-       },
-};
-
-static void __init g4evm_map_io(void)
-{
-       iotable_init(g4evm_io_desc, ARRAY_SIZE(g4evm_io_desc));
-
-       /* setup early devices and console here as well */
-       sh7377_add_early_devices();
-       shmobile_setup_console();
-}
-
 #define GPIO_SDHID0_D0 0xe60520fc
 #define GPIO_SDHID0_D1 0xe60520fd
 #define GPIO_SDHID0_D2 0xe60520fe
@@ -397,20 +374,11 @@ static void __init g4evm_init(void)
        platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices));
 }
 
-static void __init g4evm_timer_init(void)
-{
-       sh7377_clock_init();
-       shmobile_timer.init();
-}
-
-static struct sys_timer g4evm_timer = {
-       .init           = g4evm_timer_init,
-};
-
 MACHINE_START(G4EVM, "g4evm")
-       .map_io         = g4evm_map_io,
+       .map_io         = sh7377_map_io,
+       .init_early     = sh7377_add_early_devices,
        .init_irq       = sh7377_init_irq,
        .handle_irq     = shmobile_handle_irq_intc,
        .init_machine   = g4evm_init,
-       .timer          = &g4evm_timer,
+       .timer          = &shmobile_timer,
 MACHINE_END
index c8e7ca23fc06f57794feca6900bf89a1445e41c4..61c067294660f41d36dad57557459f30471a1701 100644 (file)
@@ -43,7 +43,6 @@
 #include <mach/common.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
 #include <asm/mach/time.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -409,27 +408,6 @@ static struct platform_device *kota2_devices[] __initdata = {
        &sdhi1_device,
 };
 
-static struct map_desc kota2_io_desc[] __initdata = {
-       /* create a 1:1 entity map for 0xe6xxxxxx
-        * used by CPGA, INTC and PFC.
-        */
-       {
-               .virtual        = 0xe6000000,
-               .pfn            = __phys_to_pfn(0xe6000000),
-               .length         = 256 << 20,
-               .type           = MT_DEVICE_NONSHARED
-       },
-};
-
-static void __init kota2_map_io(void)
-{
-       iotable_init(kota2_io_desc, ARRAY_SIZE(kota2_io_desc));
-
-       /* setup early devices and console here as well */
-       sh73a0_add_early_devices();
-       shmobile_setup_console();
-}
-
 static void __init kota2_init(void)
 {
        sh73a0_pinmux_init();
@@ -535,22 +513,12 @@ static void __init kota2_init(void)
        platform_add_devices(kota2_devices, ARRAY_SIZE(kota2_devices));
 }
 
-static void __init kota2_timer_init(void)
-{
-       sh73a0_clock_init();
-       shmobile_timer.init();
-       return;
-}
-
-struct sys_timer kota2_timer = {
-       .init   = kota2_timer_init,
-};
-
 MACHINE_START(KOTA2, "kota2")
-       .map_io         = kota2_map_io,
+       .map_io         = sh73a0_map_io,
+       .init_early     = sh73a0_add_early_devices,
        .nr_irqs        = NR_IRQS_LEGACY,
        .init_irq       = sh73a0_init_irq,
        .handle_irq     = gic_handle_irq,
        .init_machine   = kota2_init,
-       .timer          = &kota2_timer,
+       .timer          = &shmobile_timer,
 MACHINE_END
index 865d56d96299317cf1e38551b2e31c2f852bb3b3..ca609502d6cdda92dda69a3cc421e58d25e9b4c7 100644 (file)
@@ -57,8 +57,6 @@
 #include <mach/sh7372.h>
 
 #include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
 #include <asm/mach-types.h>
 
 /*
@@ -1329,31 +1327,6 @@ static struct i2c_board_info i2c1_devices[] = {
        },
 };
 
-static struct map_desc mackerel_io_desc[] __initdata = {
-       /* create a 1:1 entity map for 0xe6xxxxxx
-        * used by CPGA, INTC and PFC.
-        */
-       {
-               .virtual        = 0xe6000000,
-               .pfn            = __phys_to_pfn(0xe6000000),
-               .length         = 256 << 20,
-               .type           = MT_DEVICE_NONSHARED
-       },
-};
-
-static void __init mackerel_map_io(void)
-{
-       iotable_init(mackerel_io_desc, ARRAY_SIZE(mackerel_io_desc));
-       /* DMA memory at 0xff200000 - 0xffdfffff. The default 2MB size isn't
-        * enough to allocate the frame buffer memory.
-        */
-       init_consistent_dma_size(12 << 20);
-
-       /* setup early devices and console here as well */
-       sh7372_add_early_devices();
-       shmobile_setup_console();
-}
-
 #define GPIO_PORT9CR   0xE6051009
 #define GPIO_PORT10CR  0xE605100A
 #define GPIO_PORT167CR 0xE60520A7
@@ -1366,6 +1339,9 @@ static void __init mackerel_init(void)
        struct clk *clk;
        int ret;
 
+       /* External clock source */
+       clk_set_rate(&sh7372_dv_clki_clk, 27000000);
+
        sh7372_pinmux_init();
 
        /* enable SCIFA0 */
@@ -1569,23 +1545,11 @@ static void __init mackerel_init(void)
        pm_clk_add(&hdmi_lcdc_device.dev, "hdmi");
 }
 
-static void __init mackerel_timer_init(void)
-{
-       sh7372_clock_init();
-       shmobile_timer.init();
-
-       /* External clock source */
-       clk_set_rate(&sh7372_dv_clki_clk, 27000000);
-}
-
-static struct sys_timer mackerel_timer = {
-       .init           = mackerel_timer_init,
-};
-
 MACHINE_START(MACKEREL, "mackerel")
-       .map_io         = mackerel_map_io,
+       .map_io         = sh7372_map_io,
+       .init_early     = sh7372_add_early_devices,
        .init_irq       = sh7372_init_irq,
        .handle_irq     = shmobile_handle_irq_intc,
        .init_machine   = mackerel_init,
-       .timer          = &mackerel_timer,
+       .timer          = &shmobile_timer,
 MACHINE_END
index f0e02c0ce99f0989261db03739a50a7b9ceeccd6..cbd5e4cd06d2b241a5d24ee67d578943234d4cf5 100644 (file)
@@ -33,8 +33,6 @@
 #include <mach/common.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/time.h>
 #include <asm/hardware/gic.h>
 #include <asm/traps.h>
 
@@ -72,49 +70,6 @@ static struct platform_device *marzen_devices[] __initdata = {
        &eth_device,
 };
 
-static struct map_desc marzen_io_desc[] __initdata = {
-       /* 2M entity map for 0xf0000000 (MPCORE) */
-       {
-               .virtual        = 0xf0000000,
-               .pfn            = __phys_to_pfn(0xf0000000),
-               .length         = SZ_2M,
-               .type           = MT_DEVICE_NONSHARED
-       },
-       /* 16M entity map for 0xfexxxxxx (DMAC-S/HPBREG/INTC2/LRAM/DBSC) */
-       {
-               .virtual        = 0xfe000000,
-               .pfn            = __phys_to_pfn(0xfe000000),
-               .length         = SZ_16M,
-               .type           = MT_DEVICE_NONSHARED
-       },
-};
-
-static void __init marzen_map_io(void)
-{
-       iotable_init(marzen_io_desc, ARRAY_SIZE(marzen_io_desc));
-}
-
-static void __init marzen_init_early(void)
-{
-       r8a7779_add_early_devices();
-
-       /* Early serial console setup is not included here due to
-        * memory map collisions. The SCIF serial ports in r8a7779
-        * are difficult to entity map 1:1 due to collision with the
-        * virtual memory range used by the coherent DMA code on ARM.
-        *
-        * Anyone wanting to debug early can remove UPF_IOREMAP from
-        * the sh-sci serial console platform data, adjust mapbase
-        * to a static M:N virt:phys mapping that needs to be added to
-        * the mappings passed with iotable_init() above.
-        *
-        * Then add a call to shmobile_setup_console() from this function.
-        *
-        * As a final step pass earlyprint=sh-sci.2,115200 on the kernel
-        * command line.
-        */
-}
-
 static void __init marzen_init(void)
 {
        r8a7779_pinmux_init();
@@ -135,23 +90,12 @@ static void __init marzen_init(void)
        platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
 }
 
-static void __init marzen_timer_init(void)
-{
-       r8a7779_clock_init();
-       shmobile_timer.init();
-       return;
-}
-
-struct sys_timer marzen_timer = {
-       .init   = marzen_timer_init,
-};
-
 MACHINE_START(MARZEN, "marzen")
-       .map_io         = marzen_map_io,
-       .init_early     = marzen_init_early,
+       .map_io         = r8a7779_map_io,
+       .init_early     = r8a7779_add_early_devices,
        .nr_irqs        = NR_IRQS_LEGACY,
        .init_irq       = r8a7779_init_irq,
        .handle_irq     = gic_handle_irq,
        .init_machine   = marzen_init,
-       .timer          = &marzen_timer,
+       .timer          = &shmobile_timer,
 MACHINE_END
index 3b35b9afc001c5daf8ccfd199e778dddda92b468..99c4d743a99c41a5d0e9206e4967e7e80417d44d 100644 (file)
@@ -93,7 +93,7 @@ static unsigned long div_recalc(struct clk *clk)
        return clk->parent->rate / (int)(clk->priv);
 }
 
-static struct clk_ops div_clk_ops = {
+static struct sh_clk_ops div_clk_ops = {
        .recalc = div_recalc,
 };
 
@@ -125,7 +125,7 @@ static struct clk extal2_div2_clk = {
        .parent = &extal2_clk,
 };
 
-static struct clk_ops followparent_clk_ops = {
+static struct sh_clk_ops followparent_clk_ops = {
        .recalc = followparent_recalc,
 };
 
@@ -156,7 +156,7 @@ static unsigned long pllc01_recalc(struct clk *clk)
        return clk->parent->rate * mult;
 }
 
-static struct clk_ops pllc01_clk_ops = {
+static struct sh_clk_ops pllc01_clk_ops = {
        .recalc         = pllc01_recalc,
 };
 
@@ -376,7 +376,7 @@ void __init r8a7740_clock_init(u8 md_ck)
        clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        if (!ret)
-               clk_init();
+               shmobile_clk_init();
        else
                panic("failed to setup r8a7740 clocks\n");
 }
index b4b0e8cd096ded26d640bcce8d82a70525de6a74..7d6e9fe47b56a812e7fbb7c1343da1eb9d045141 100644 (file)
@@ -107,7 +107,7 @@ static unsigned long mul4_recalc(struct clk *clk)
        return clk->parent->rate * 4;
 }
 
-static struct clk_ops mul4_clk_ops = {
+static struct sh_clk_ops mul4_clk_ops = {
        .recalc         = mul4_recalc,
 };
 
@@ -170,7 +170,7 @@ void __init r8a7779_clock_init(void)
        clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        if (!ret)
-               clk_init();
+               shmobile_clk_init();
        else
                panic("failed to setup r8a7779 clocks\n");
 }
index 5218c34a9cc6b77994d1f51966679a9b2e5fee73..006e7b5d304c36207780ebbcde9f34a833ea2605 100644 (file)
@@ -74,7 +74,7 @@ static unsigned long div2_recalc(struct clk *clk)
        return clk->parent->rate / 2;
 }
 
-static struct clk_ops div2_clk_ops = {
+static struct sh_clk_ops div2_clk_ops = {
        .recalc         = div2_recalc,
 };
 
@@ -101,7 +101,7 @@ static unsigned long pllc1_recalc(struct clk *clk)
        return clk->parent->rate * mult;
 }
 
-static struct clk_ops pllc1_clk_ops = {
+static struct sh_clk_ops pllc1_clk_ops = {
        .recalc         = pllc1_recalc,
 };
 
@@ -128,7 +128,7 @@ static unsigned long pllc2_recalc(struct clk *clk)
        return clk->parent->rate * mult;
 }
 
-static struct clk_ops pllc2_clk_ops = {
+static struct sh_clk_ops pllc2_clk_ops = {
        .recalc         = pllc2_recalc,
 };
 
@@ -349,7 +349,7 @@ void __init sh7367_clock_init(void)
        clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        if (!ret)
-               clk_init();
+               shmobile_clk_init();
        else
                panic("failed to setup sh7367 clocks\n");
 }
index 293456d8dcfddac245745cd27b54d126bda7ce7d..de243e3c83929311753e47f0dc1dc1d495e88761 100644 (file)
@@ -89,7 +89,7 @@ static unsigned long div2_recalc(struct clk *clk)
        return clk->parent->rate / 2;
 }
 
-static struct clk_ops div2_clk_ops = {
+static struct sh_clk_ops div2_clk_ops = {
        .recalc         = div2_recalc,
 };
 
@@ -128,7 +128,7 @@ static unsigned long pllc01_recalc(struct clk *clk)
        return clk->parent->rate * mult;
 }
 
-static struct clk_ops pllc01_clk_ops = {
+static struct sh_clk_ops pllc01_clk_ops = {
        .recalc         = pllc01_recalc,
 };
 
@@ -276,7 +276,7 @@ static int pllc2_set_parent(struct clk *clk, struct clk *parent)
        return 0;
 }
 
-static struct clk_ops pllc2_clk_ops = {
+static struct sh_clk_ops pllc2_clk_ops = {
        .recalc         = pllc2_recalc,
        .round_rate     = pllc2_round_rate,
        .set_rate       = pllc2_set_rate,
@@ -468,7 +468,7 @@ static int fsidiv_set_rate(struct clk *clk, unsigned long rate)
        return 0;
 }
 
-static struct clk_ops fsidiv_clk_ops = {
+static struct sh_clk_ops fsidiv_clk_ops = {
        .recalc         = fsidiv_recalc,
        .round_rate     = fsidiv_round_rate,
        .set_rate       = fsidiv_set_rate,
@@ -710,7 +710,7 @@ void __init sh7372_clock_init(void)
        clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        if (!ret)
-               clk_init();
+               shmobile_clk_init();
        else
                panic("failed to setup sh7372 clocks\n");
 
index 8cee7b151ae3fed0eec3840fdde5fe7f05195027..0798a15936c3cc41a6d51c70e909503d3f02afd8 100644 (file)
@@ -77,7 +77,7 @@ static unsigned long div2_recalc(struct clk *clk)
        return clk->parent->rate / 2;
 }
 
-static struct clk_ops div2_clk_ops = {
+static struct sh_clk_ops div2_clk_ops = {
        .recalc         = div2_recalc,
 };
 
@@ -110,7 +110,7 @@ static unsigned long pllc1_recalc(struct clk *clk)
        return clk->parent->rate * mult;
 }
 
-static struct clk_ops pllc1_clk_ops = {
+static struct sh_clk_ops pllc1_clk_ops = {
        .recalc         = pllc1_recalc,
 };
 
@@ -137,7 +137,7 @@ static unsigned long pllc2_recalc(struct clk *clk)
        return clk->parent->rate * mult;
 }
 
-static struct clk_ops pllc2_clk_ops = {
+static struct sh_clk_ops pllc2_clk_ops = {
        .recalc         = pllc2_recalc,
 };
 
@@ -360,7 +360,7 @@ void __init sh7377_clock_init(void)
        clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        if (!ret)
-               clk_init();
+               shmobile_clk_init();
        else
                panic("failed to setup sh7377 clocks\n");
 }
index 7727cca6136cf716a30e0d9be75241566fc6087c..472d1f5361e5390a58ecde58966c075d0532bf6d 100644 (file)
@@ -88,7 +88,7 @@ static unsigned long div2_recalc(struct clk *clk)
        return clk->parent->rate / 2;
 }
 
-static struct clk_ops div2_clk_ops = {
+static struct sh_clk_ops div2_clk_ops = {
        .recalc         = div2_recalc,
 };
 
@@ -97,7 +97,7 @@ static unsigned long div7_recalc(struct clk *clk)
        return clk->parent->rate / 7;
 }
 
-static struct clk_ops div7_clk_ops = {
+static struct sh_clk_ops div7_clk_ops = {
        .recalc         = div7_recalc,
 };
 
@@ -106,7 +106,7 @@ static unsigned long div13_recalc(struct clk *clk)
        return clk->parent->rate / 13;
 }
 
-static struct clk_ops div13_clk_ops = {
+static struct sh_clk_ops div13_clk_ops = {
        .recalc         = div13_recalc,
 };
 
@@ -122,7 +122,7 @@ static struct clk extal2_div2_clk = {
        .parent         = &sh73a0_extal2_clk,
 };
 
-static struct clk_ops main_clk_ops = {
+static struct sh_clk_ops main_clk_ops = {
        .recalc         = followparent_recalc,
 };
 
@@ -156,7 +156,7 @@ static unsigned long pll_recalc(struct clk *clk)
        return clk->parent->rate * mult;
 }
 
-static struct clk_ops pll_clk_ops = {
+static struct sh_clk_ops pll_clk_ops = {
        .recalc         = pll_recalc,
 };
 
@@ -438,7 +438,7 @@ static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
        return 0;
 }
 
-static struct clk_ops dsiphy_clk_ops = {
+static struct sh_clk_ops dsiphy_clk_ops = {
        .recalc         = dsiphy_recalc,
        .round_rate     = dsiphy_round_rate,
        .set_rate       = dsiphy_set_rate,
@@ -620,7 +620,7 @@ void __init sh73a0_clock_init(void)
        clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        if (!ret)
-               clk_init();
+               shmobile_clk_init();
        else
                panic("failed to setup sh73a0 clocks\n");
 }
index 31654d78b96b6331b8edaaf3a6576f043de408ae..e816ca9bd2131949e8847d82ba6028ceb147282c 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/sh_clk.h>
 #include <linux/export.h>
 
-int __init clk_init(void)
+int __init shmobile_clk_init(void)
 {
        /* Kick the child clocks.. */
        recalculate_root_clocks();
index e4b945e271e73db84b5fa608ce4eba82267d13dc..83ad3fe0a75fc120676b19ebca1d896611076d5a 100644 (file)
@@ -1,12 +1,15 @@
 #ifndef __ARCH_MACH_COMMON_H
 #define __ARCH_MACH_COMMON_H
 
+extern void shmobile_earlytimer_init(void);
 extern struct sys_timer shmobile_timer;
+struct twd_local_timer;
+void shmobile_twd_init(struct twd_local_timer *twd_local_timer);
 extern void shmobile_setup_console(void);
 extern void shmobile_secondary_vector(void);
 extern int shmobile_platform_cpu_kill(unsigned int cpu);
 struct clk;
-extern int clk_init(void);
+extern int shmobile_clk_init(void);
 extern void shmobile_handle_irq_intc(struct pt_regs *);
 extern struct platform_suspend_ops shmobile_suspend_ops;
 struct cpuidle_driver;
@@ -14,6 +17,7 @@ extern void (*shmobile_cpuidle_modes[])(void);
 extern void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv);
 
 extern void sh7367_init_irq(void);
+extern void sh7367_map_io(void);
 extern void sh7367_add_early_devices(void);
 extern void sh7367_add_standard_devices(void);
 extern void sh7367_clock_init(void);
@@ -22,6 +26,7 @@ extern struct clk sh7367_extalb1_clk;
 extern struct clk sh7367_extal2_clk;
 
 extern void sh7377_init_irq(void);
+extern void sh7377_map_io(void);
 extern void sh7377_add_early_devices(void);
 extern void sh7377_add_standard_devices(void);
 extern void sh7377_clock_init(void);
@@ -30,6 +35,7 @@ extern struct clk sh7377_extalc1_clk;
 extern struct clk sh7377_extal2_clk;
 
 extern void sh7372_init_irq(void);
+extern void sh7372_map_io(void);
 extern void sh7372_add_early_devices(void);
 extern void sh7372_add_standard_devices(void);
 extern void sh7372_clock_init(void);
@@ -41,6 +47,7 @@ extern struct clk sh7372_extal1_clk;
 extern struct clk sh7372_extal2_clk;
 
 extern void sh73a0_init_irq(void);
+extern void sh73a0_map_io(void);
 extern void sh73a0_add_early_devices(void);
 extern void sh73a0_add_standard_devices(void);
 extern void sh73a0_clock_init(void);
@@ -56,12 +63,14 @@ extern int sh73a0_boot_secondary(unsigned int cpu);
 extern void sh73a0_smp_prepare_cpus(void);
 
 extern void r8a7740_init_irq(void);
+extern void r8a7740_map_io(void);
 extern void r8a7740_add_early_devices(void);
 extern void r8a7740_add_standard_devices(void);
 extern void r8a7740_clock_init(u8 md_ck);
 extern void r8a7740_pinmux_init(void);
 
 extern void r8a7779_init_irq(void);
+extern void r8a7779_map_io(void);
 extern void r8a7779_add_early_devices(void);
 extern void r8a7779_add_standard_devices(void);
 extern void r8a7779_clock_init(void);
diff --git a/arch/arm/mach-shmobile/localtimer.c b/arch/arm/mach-shmobile/localtimer.c
deleted file mode 100644 (file)
index ad9ccc9..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * SMP support for R-Mobile / SH-Mobile - local timer portion
- *
- * Copyright (C) 2010  Magnus Damm
- *
- * Based on vexpress, Copyright (C) 2002 ARM Ltd, All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/clockchips.h>
-#include <asm/smp_twd.h>
-#include <asm/localtimer.h>
-
-/*
- * Setup the local clock events for a CPU.
- */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-       evt->irq = 29;
-       twd_timer_setup(evt);
-       return 0;
-}
index 993381257f69a6352adcc7e61df3d92d65b88643..45fa3924c6a1e231e12f4b9aa230b0f5af41c849 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/smp.h>
 #include <linux/io.h>
 #include <asm/hardware/gic.h>
-#include <asm/localtimer.h>
 #include <asm/mach-types.h>
 #include <mach/common.h>
 
index 986dca6b3fad8f384ada7c5a115b50e55ba2301a..74e52341dd1bda1352e70de479c75fa53a99356b 100644 (file)
 #include <linux/serial_sci.h>
 #include <linux/sh_timer.h>
 #include <mach/r8a7740.h>
+#include <mach/common.h>
 #include <asm/mach-types.h>
+#include <asm/mach/map.h>
 #include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+static struct map_desc r8a7740_io_desc[] __initdata = {
+        /*
+         * for CPGA/INTC/PFC
+         * 0xe6000000-0xefffffff -> 0xe6000000-0xefffffff
+         */
+       {
+               .virtual        = 0xe6000000,
+               .pfn            = __phys_to_pfn(0xe6000000),
+               .length         = 160 << 20,
+               .type           = MT_DEVICE_NONSHARED
+       },
+#ifdef CONFIG_CACHE_L2X0
+       /*
+        * for l2x0_init()
+        * 0xf0100000-0xf0101000 -> 0xf0002000-0xf0003000
+        */
+       {
+               .virtual        = 0xf0002000,
+               .pfn            = __phys_to_pfn(0xf0100000),
+               .length         = PAGE_SIZE,
+               .type           = MT_DEVICE_NONSHARED
+       },
+#endif
+};
+
+void __init r8a7740_map_io(void)
+{
+       iotable_init(r8a7740_io_desc, ARRAY_SIZE(r8a7740_io_desc));
+}
 
 /* SCIFA0 */
 static struct plat_sci_port scif0_platform_data = {
@@ -345,8 +378,20 @@ void __init r8a7740_add_standard_devices(void)
                             ARRAY_SIZE(r8a7740_late_devices));
 }
 
+static void __init r8a7740_earlytimer_init(void)
+{
+       r8a7740_clock_init(0);
+       shmobile_earlytimer_init();
+}
+
 void __init r8a7740_add_early_devices(void)
 {
        early_platform_add_devices(r8a7740_early_devices,
                                   ARRAY_SIZE(r8a7740_early_devices));
+
+       /* setup early console here as well */
+       shmobile_setup_console();
+
+       /* override timer setup with soc-specific code */
+       shmobile_timer.init = r8a7740_earlytimer_init;
 }
index 4725663bd032ffed23fe97bbb75d88437a202eec..6820d785493db3a2c1516cb4f1fc01461dae6579 100644 (file)
 #include <mach/common.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/cache-l2x0.h>
+
+static struct map_desc r8a7779_io_desc[] __initdata = {
+       /* 2M entity map for 0xf0000000 (MPCORE) */
+       {
+               .virtual        = 0xf0000000,
+               .pfn            = __phys_to_pfn(0xf0000000),
+               .length         = SZ_2M,
+               .type           = MT_DEVICE_NONSHARED
+       },
+       /* 16M entity map for 0xfexxxxxx (DMAC-S/HPBREG/INTC2/LRAM/DBSC) */
+       {
+               .virtual        = 0xfe000000,
+               .pfn            = __phys_to_pfn(0xfe000000),
+               .length         = SZ_16M,
+               .type           = MT_DEVICE_NONSHARED
+       },
+};
+
+void __init r8a7779_map_io(void)
+{
+       iotable_init(r8a7779_io_desc, ARRAY_SIZE(r8a7779_io_desc));
+}
 
 static struct plat_sci_port scif0_platform_data = {
        .mapbase        = 0xffe40000,
@@ -219,6 +244,10 @@ static struct platform_device *r8a7779_late_devices[] __initdata = {
 
 void __init r8a7779_add_standard_devices(void)
 {
+#ifdef CONFIG_CACHE_L2X0
+       /* Early BRESP enable, Shared attribute override enable, 64K*16way */
+       l2x0_init((void __iomem __force *)(0xf0100000), 0x40470000, 0x82000fff);
+#endif
        r8a7779_pm_init();
 
        r8a7779_init_pm_domain(&r8a7779_sh4a);
@@ -232,8 +261,33 @@ void __init r8a7779_add_standard_devices(void)
                            ARRAY_SIZE(r8a7779_late_devices));
 }
 
+static void __init r8a7779_earlytimer_init(void)
+{
+       r8a7779_clock_init();
+       shmobile_earlytimer_init();
+}
+
 void __init r8a7779_add_early_devices(void)
 {
        early_platform_add_devices(r8a7779_early_devices,
                                   ARRAY_SIZE(r8a7779_early_devices));
+
+       /* Early serial console setup is not included here due to
+        * memory map collisions. The SCIF serial ports in r8a7779
+        * are difficult to entity map 1:1 due to collision with the
+        * virtual memory range used by the coherent DMA code on ARM.
+        *
+        * Anyone wanting to debug early can remove UPF_IOREMAP from
+        * the sh-sci serial console platform data, adjust mapbase
+        * to a static M:N virt:phys mapping that needs to be added to
+        * the mappings passed with iotable_init() above.
+        *
+        * Then add a call to shmobile_setup_console() from this function.
+        *
+        * As a final step pass earlyprint=sh-sci.2,115200 on the kernel
+        * command line in case of the marzen board.
+        */
+
+       /* override timer setup with soc-specific code */
+       shmobile_timer.init = r8a7779_earlytimer_init;
 }
index e546017f15dea1202df2be20fa6303b69d70f1f4..a51e1a1e6996ddf7a3bd097a23fdbc3071261ae0 100644 (file)
 #include <linux/serial_sci.h>
 #include <linux/sh_timer.h>
 #include <mach/hardware.h>
+#include <mach/common.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+static struct map_desc sh7367_io_desc[] __initdata = {
+       /* create a 1:1 entity map for 0xe6xxxxxx
+        * used by CPGA, INTC and PFC.
+        */
+       {
+               .virtual        = 0xe6000000,
+               .pfn            = __phys_to_pfn(0xe6000000),
+               .length         = 256 << 20,
+               .type           = MT_DEVICE_NONSHARED
+       },
+};
+
+void __init sh7367_map_io(void)
+{
+       iotable_init(sh7367_io_desc, ARRAY_SIZE(sh7367_io_desc));
+}
 
 /* SCIFA0 */
 static struct plat_sci_port scif0_platform_data = {
@@ -435,6 +455,12 @@ void __init sh7367_add_standard_devices(void)
                            ARRAY_SIZE(sh7367_devices));
 }
 
+static void __init sh7367_earlytimer_init(void)
+{
+       sh7367_clock_init();
+       shmobile_earlytimer_init();
+}
+
 #define SYMSTPCR2 0xe6158048
 #define SYMSTPCR2_CMT1 (1 << 29)
 
@@ -445,4 +471,10 @@ void __init sh7367_add_early_devices(void)
 
        early_platform_add_devices(sh7367_early_devices,
                                   ARRAY_SIZE(sh7367_early_devices));
+
+       /* setup early console here as well */
+       shmobile_setup_console();
+
+       /* override timer setup with soc-specific code */
+       shmobile_timer.init = sh7367_earlytimer_init;
 }
index cccf91b8fae196e56cf4770b078f0f08cda9b538..4e818b7de7815fb466f0b4c5451fad7225859628 100644 (file)
 #include <linux/sh_intc.h>
 #include <linux/sh_timer.h>
 #include <linux/pm_domain.h>
+#include <linux/dma-mapping.h>
 #include <mach/hardware.h>
 #include <mach/sh7372.h>
+#include <mach/common.h>
+#include <asm/mach/map.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+static struct map_desc sh7372_io_desc[] __initdata = {
+       /* create a 1:1 entity map for 0xe6xxxxxx
+        * used by CPGA, INTC and PFC.
+        */
+       {
+               .virtual        = 0xe6000000,
+               .pfn            = __phys_to_pfn(0xe6000000),
+               .length         = 256 << 20,
+               .type           = MT_DEVICE_NONSHARED
+       },
+};
+
+void __init sh7372_map_io(void)
+{
+       iotable_init(sh7372_io_desc, ARRAY_SIZE(sh7372_io_desc));
+
+       /*
+        * DMA memory at 0xff200000 - 0xffdfffff. The default 2MB size isn't
+        * enough to allocate the frame buffer memory.
+        */
+       init_consistent_dma_size(12 << 20);
+}
 
 /* SCIFA0 */
 static struct plat_sci_port scif0_platform_data = {
@@ -1047,8 +1074,20 @@ void __init sh7372_add_standard_devices(void)
        sh7372_add_device_to_domain(&sh7372_a4r, &tmu01_device);
 }
 
+static void __init sh7372_earlytimer_init(void)
+{
+       sh7372_clock_init();
+       shmobile_earlytimer_init();
+}
+
 void __init sh7372_add_early_devices(void)
 {
        early_platform_add_devices(sh7372_early_devices,
                                   ARRAY_SIZE(sh7372_early_devices));
+
+       /* setup early console here as well */
+       shmobile_setup_console();
+
+       /* override timer setup with soc-specific code */
+       shmobile_timer.init = sh7372_earlytimer_init;
 }
index bb405b8e459be00c11ce956c0e67bf9e181557f2..9f146095098b258766bebe319b47adc225ec00ce 100644 (file)
 #include <linux/sh_intc.h>
 #include <linux/sh_timer.h>
 #include <mach/hardware.h>
+#include <mach/common.h>
+#include <asm/mach/map.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+static struct map_desc sh7377_io_desc[] __initdata = {
+       /* create a 1:1 entity map for 0xe6xxxxxx
+        * used by CPGA, INTC and PFC.
+        */
+       {
+               .virtual        = 0xe6000000,
+               .pfn            = __phys_to_pfn(0xe6000000),
+               .length         = 256 << 20,
+               .type           = MT_DEVICE_NONSHARED
+       },
+};
+
+void __init sh7377_map_io(void)
+{
+       iotable_init(sh7377_io_desc, ARRAY_SIZE(sh7377_io_desc));
+}
 
 /* SCIFA0 */
 static struct plat_sci_port scif0_platform_data = {
@@ -456,6 +476,12 @@ void __init sh7377_add_standard_devices(void)
                            ARRAY_SIZE(sh7377_devices));
 }
 
+static void __init sh7377_earlytimer_init(void)
+{
+       sh7377_clock_init();
+       shmobile_earlytimer_init();
+}
+
 #define SMSTPCR3 0xe615013c
 #define SMSTPCR3_CMT1 (1 << 29)
 
@@ -466,4 +492,10 @@ void __init sh7377_add_early_devices(void)
 
        early_platform_add_devices(sh7377_early_devices,
                                   ARRAY_SIZE(sh7377_early_devices));
+
+       /* setup early console here as well */
+       shmobile_setup_console();
+
+       /* override timer setup with soc-specific code */
+       shmobile_timer.init = sh7377_earlytimer_init;
 }
index 20e71e5cace4723dabc8276f47d3e1cfef8daf64..b6a0734a738e472c684b949ce9029a095c03eed2 100644 (file)
 #include <linux/sh_timer.h>
 #include <mach/hardware.h>
 #include <mach/sh73a0.h>
+#include <mach/common.h>
 #include <asm/mach-types.h>
+#include <asm/mach/map.h>
 #include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+static struct map_desc sh73a0_io_desc[] __initdata = {
+       /* create a 1:1 entity map for 0xe6xxxxxx
+        * used by CPGA, INTC and PFC.
+        */
+       {
+               .virtual        = 0xe6000000,
+               .pfn            = __phys_to_pfn(0xe6000000),
+               .length         = 256 << 20,
+               .type           = MT_DEVICE_NONSHARED
+       },
+};
+
+void __init sh73a0_map_io(void)
+{
+       iotable_init(sh73a0_io_desc, ARRAY_SIZE(sh73a0_io_desc));
+}
 
 static struct plat_sci_port scif0_platform_data = {
        .mapbase        = 0xe6c40000,
@@ -667,8 +687,20 @@ void __init sh73a0_add_standard_devices(void)
                            ARRAY_SIZE(sh73a0_late_devices));
 }
 
+static void __init sh73a0_earlytimer_init(void)
+{
+       sh73a0_clock_init();
+       shmobile_earlytimer_init();
+}
+
 void __init sh73a0_add_early_devices(void)
 {
        early_platform_add_devices(sh73a0_early_devices,
                                   ARRAY_SIZE(sh73a0_early_devices));
+
+       /* setup early console here as well */
+       shmobile_setup_console();
+
+       /* override timer setup with soc-specific code */
+       shmobile_timer.init = sh73a0_earlytimer_init;
 }
index 4fe2e9eaf5016e643aec46e6e1652828ad9e3ea9..9bb7b8575a1fed4c366dbc58f3dbafd72007670d 100644 (file)
@@ -64,6 +64,8 @@ static void __iomem *scu_base_addr(void)
 static DEFINE_SPINLOCK(scu_lock);
 static unsigned long tmp;
 
+static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29);
+
 static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
 {
        void __iomem *scu_base = scu_base_addr();
@@ -82,11 +84,7 @@ unsigned int __init r8a7779_get_core_count(void)
 {
        void __iomem *scu_base = scu_base_addr();
 
-#ifdef CONFIG_HAVE_ARM_TWD
-       /* twd_base needs to be initialized before percpu_timer_setup() */
-       twd_base = (void __iomem *)0xf0000600;
-#endif
-
+       shmobile_twd_init(&twd_local_timer);
        return scu_get_core_count(scu_base);
 }
 
index 2d0d4212be41b9bc5112ba9ae57e02bd798927a9..c0a9093ba3a8675f861871078bc50730fc4dae58 100644 (file)
@@ -42,6 +42,8 @@ static void __iomem *scu_base_addr(void)
 static DEFINE_SPINLOCK(scu_lock);
 static unsigned long tmp;
 
+static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29);
+
 static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
 {
        void __iomem *scu_base = scu_base_addr();
@@ -60,11 +62,7 @@ unsigned int __init sh73a0_get_core_count(void)
 {
        void __iomem *scu_base = scu_base_addr();
 
-#ifdef CONFIG_HAVE_ARM_TWD
-       /* twd_base needs to be initialized before percpu_timer_setup() */
-       twd_base = (void __iomem *)0xf0000600;
-#endif
-
+       shmobile_twd_init(&twd_local_timer);
        return scu_get_core_count(scu_base);
 }
 
index 895794b543cdcf7f1c567e8fc1635d6375c85134..2fba5f3d1c8ad705309a2e1f3287af5fbb1aee06 100644 (file)
@@ -20,6 +20,7 @@
  */
 #include <linux/platform_device.h>
 #include <asm/mach/time.h>
+#include <asm/smp_twd.h>
 
 static void __init shmobile_late_time_init(void)
 {
@@ -36,11 +37,24 @@ static void __init shmobile_late_time_init(void)
        early_platform_driver_probe("earlytimer", 2, 0);
 }
 
-static void __init shmobile_timer_init(void)
+void __init shmobile_earlytimer_init(void)
 {
        late_time_init = shmobile_late_time_init;
 }
 
+static void __init shmobile_timer_init(void)
+{
+}
+
+void __init shmobile_twd_init(struct twd_local_timer *twd_local_timer)
+{
+#ifdef CONFIG_HAVE_ARM_TWD
+       int err = twd_local_timer_register(twd_local_timer);
+       if (err)
+               pr_err("twd_local_timer_register failed %d\n", err);
+#endif
+}
+
 struct sys_timer shmobile_timer = {
        .init           = shmobile_timer_init,
 };
index ff4ae5ba00f19b7015163ca9d09d92fc3870e791..fbe298bd1d927ee31453817598f351b2629ca666 100644 (file)
@@ -5,11 +5,12 @@
 if ARCH_SPEAR6XX
 
 menu "SPEAr6xx Implementations"
-config BOARD_SPEAR600_EVB
-       bool "SPEAr600 Evaluation Board"
+config BOARD_SPEAR600_DT
+       bool "SPEAr600 generic board configured via device-tree"
        select MACH_SPEAR600
+       select USE_OF
        help
-         Supports ST SPEAr600 Evaluation Board
+         Supports ST SPEAr600 boards configured via the device-tree
 
 endmenu
 
index cc1a4d82d459040d9276f8dd923374f79549fa2b..76e5750552fcef01705786da3c0db2f7e2088151 100644 (file)
@@ -4,9 +4,3 @@
 
 # common files
 obj-y  += clock.o spear6xx.o
-
-# spear600 specific files
-obj-$(CONFIG_MACH_SPEAR600) += spear600.o
-
-# spear600 boards files
-obj-$(CONFIG_BOARD_SPEAR600_EVB) += spear600_evb.o
index ac70e0d88fef8a7a7616573788c9fdb727c252c4..358f2800f17b9023ba1666d305a83b84406f50da 100644 (file)
@@ -641,8 +641,8 @@ static struct clk_lookup spear_clk_lookups[] = {
        { .con_id = "gpt0_synth_clk",   .clk = &gpt0_synth_clk},
        { .con_id = "gpt2_synth_clk",   .clk = &gpt2_synth_clk},
        { .con_id = "gpt3_synth_clk",   .clk = &gpt3_synth_clk},
-       { .dev_id = "uart0",            .clk = &uart0_clk},
-       { .dev_id = "uart1",            .clk = &uart1_clk},
+       { .dev_id = "d0000000.serial",  .clk = &uart0_clk},
+       { .dev_id = "d0080000.serial",  .clk = &uart1_clk},
        { .dev_id = "firda",            .clk = &firda_clk},
        { .dev_id = "clcd",             .clk = &clcd_clk},
        { .dev_id = "gpt0",             .clk = &gpt0_clk},
@@ -655,20 +655,20 @@ static struct clk_lookup spear_clk_lookups[] = {
        { .con_id = "usbh.1_clk",       .clk = &usbh1_clk},
        /* clock derived from ahb clk */
        { .con_id = "apb_clk",          .clk = &apb_clk},
-       { .dev_id = "i2c_designware.0", .clk = &i2c_clk},
+       { .dev_id = "d0200000.i2c",     .clk = &i2c_clk},
        { .dev_id = "dma",              .clk = &dma_clk},
        { .dev_id = "jpeg",             .clk = &jpeg_clk},
        { .dev_id = "gmac",             .clk = &gmac_clk},
        { .dev_id = "smi",              .clk = &smi_clk},
-       { .con_id = "fsmc",             .clk = &fsmc_clk},
+       { .dev_id = "fsmc-nand",        .clk = &fsmc_clk},
        /* clock derived from apb clk */
        { .dev_id = "adc",              .clk = &adc_clk},
        { .dev_id = "ssp-pl022.0",      .clk = &ssp0_clk},
        { .dev_id = "ssp-pl022.1",      .clk = &ssp1_clk},
        { .dev_id = "ssp-pl022.2",      .clk = &ssp2_clk},
-       { .dev_id = "gpio0",            .clk = &gpio0_clk},
-       { .dev_id = "gpio1",            .clk = &gpio1_clk},
-       { .dev_id = "gpio2",            .clk = &gpio2_clk},
+       { .dev_id = "f0100000.gpio",    .clk = &gpio0_clk},
+       { .dev_id = "fc980000.gpio",    .clk = &gpio1_clk},
+       { .dev_id = "d8100000.gpio",    .clk = &gpio2_clk},
 };
 
 void __init spear6xx_clk_init(void)
diff --git a/arch/arm/mach-spear6xx/spear600.c b/arch/arm/mach-spear6xx/spear600.c
deleted file mode 100644 (file)
index d0e6eea..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * arch/arm/mach-spear6xx/spear600.c
- *
- * SPEAr600 machine source file
- *
- * Copyright (C) 2009 ST Microelectronics
- * Rajeev Kumar<rajeev-dlh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/ptrace.h>
-#include <asm/irq.h>
-#include <mach/generic.h>
-#include <mach/hardware.h>
-
-/* Add spear600 specific devices here */
-
-void __init spear600_init(void)
-{
-       /* call spear6xx family common init function */
-       spear6xx_init();
-}
diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c
deleted file mode 100644 (file)
index c6e4254..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * arch/arm/mach-spear6xx/spear600_evb.c
- *
- * SPEAr600 evaluation board source file
- *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <asm/hardware/vic.h>
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-#include <mach/generic.h>
-#include <mach/hardware.h>
-
-static struct amba_device *amba_devs[] __initdata = {
-       &gpio_device[0],
-       &gpio_device[1],
-       &gpio_device[2],
-       &uart_device[0],
-       &uart_device[1],
-};
-
-static struct platform_device *plat_devs[] __initdata = {
-};
-
-static void __init spear600_evb_init(void)
-{
-       unsigned int i;
-
-       /* call spear600 machine init function */
-       spear600_init();
-
-       /* Add Platform Devices */
-       platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
-
-       /* Add Amba Devices */
-       for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
-               amba_device_register(amba_devs[i], &iomem_resource);
-}
-
-MACHINE_START(SPEAR600, "ST-SPEAR600-EVB")
-       .atag_offset    =       0x100,
-       .map_io         =       spear6xx_map_io,
-       .init_irq       =       spear6xx_init_irq,
-       .handle_irq     =       vic_handle_irq,
-       .timer          =       &spear6xx_timer,
-       .init_machine   =       spear600_evb_init,
-       .restart        =       spear_restart,
-MACHINE_END
index b997b1b10ba0bd6fa63c378677138ab01a722cbd..2ed8b14c82c8a34d04b8e73eb7cdc1dc1ce6f5ec 100644 (file)
  * Copyright (C) 2009 ST Microelectronics
  * Rajeev Kumar<rajeev-dlh.kumar@st.com>
  *
+ * Copyright 2012 Stefan Roese <sr@denx.de>
+ *
  * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
 
-#include <linux/types.h>
-#include <linux/amba/pl061.h>
-#include <linux/ptrace.h>
-#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
 #include <asm/hardware/vic.h>
-#include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <mach/generic.h>
 #include <mach/hardware.h>
-#include <mach/irqs.h>
-
-/* Add spear6xx machines common devices here */
-/* uart device registration */
-struct amba_device uart_device[] = {
-       {
-               .dev = {
-                       .init_name = "uart0",
-               },
-               .res = {
-                       .start = SPEAR6XX_ICM1_UART0_BASE,
-                       .end = SPEAR6XX_ICM1_UART0_BASE + SZ_4K - 1,
-                       .flags = IORESOURCE_MEM,
-               },
-               .irq = {IRQ_UART_0},
-       }, {
-               .dev = {
-                       .init_name = "uart1",
-               },
-               .res = {
-                       .start = SPEAR6XX_ICM1_UART1_BASE,
-                       .end = SPEAR6XX_ICM1_UART1_BASE + SZ_4K - 1,
-                       .flags = IORESOURCE_MEM,
-               },
-               .irq = {IRQ_UART_1},
-       }
-};
-
-/* gpio device registration */
-static struct pl061_platform_data gpio_plat_data[] = {
-       {
-               .gpio_base      = 0,
-               .irq_base       = SPEAR_GPIO0_INT_BASE,
-       }, {
-               .gpio_base      = 8,
-               .irq_base       = SPEAR_GPIO1_INT_BASE,
-       }, {
-               .gpio_base      = 16,
-               .irq_base       = SPEAR_GPIO2_INT_BASE,
-       },
-};
-
-struct amba_device gpio_device[] = {
-       {
-               .dev = {
-                       .init_name = "gpio0",
-                       .platform_data = &gpio_plat_data[0],
-               },
-               .res = {
-                       .start = SPEAR6XX_CPU_GPIO_BASE,
-                       .end = SPEAR6XX_CPU_GPIO_BASE + SZ_4K - 1,
-                       .flags = IORESOURCE_MEM,
-               },
-               .irq = {IRQ_LOCAL_GPIO},
-       }, {
-               .dev = {
-                       .init_name = "gpio1",
-                       .platform_data = &gpio_plat_data[1],
-               },
-               .res = {
-                       .start = SPEAR6XX_ICM3_GPIO_BASE,
-                       .end = SPEAR6XX_ICM3_GPIO_BASE + SZ_4K - 1,
-                       .flags = IORESOURCE_MEM,
-               },
-               .irq = {IRQ_BASIC_GPIO},
-       }, {
-               .dev = {
-                       .init_name = "gpio2",
-                       .platform_data = &gpio_plat_data[2],
-               },
-               .res = {
-                       .start = SPEAR6XX_ICM2_GPIO_BASE,
-                       .end = SPEAR6XX_ICM2_GPIO_BASE + SZ_4K - 1,
-                       .flags = IORESOURCE_MEM,
-               },
-               .irq = {IRQ_APPL_GPIO},
-       }
-};
-
-/* This will add devices, and do machine specific tasks */
-void __init spear6xx_init(void)
-{
-       /* nothing to do for now */
-}
-
-/* This will initialize vic */
-void __init spear6xx_init_irq(void)
-{
-       vic_init((void __iomem *)VA_SPEAR6XX_CPU_VIC_PRI_BASE, 0, ~0, 0);
-       vic_init((void __iomem *)VA_SPEAR6XX_CPU_VIC_SEC_BASE, 32, ~0, 0);
-}
 
 /* Following will create static virtual/physical mappings */
 static struct map_desc spear6xx_io_desc[] __initdata = {
@@ -181,3 +91,33 @@ static void __init spear6xx_timer_init(void)
 struct sys_timer spear6xx_timer = {
        .init = spear6xx_timer_init,
 };
+
+static void __init spear600_dt_init(void)
+{
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char *spear600_dt_board_compat[] = {
+       "st,spear600",
+       NULL
+};
+
+static const struct of_device_id vic_of_match[] __initconst = {
+       { .compatible = "arm,pl190-vic", .data = vic_of_init, },
+       { /* Sentinel */ }
+};
+
+static void __init spear6xx_dt_init_irq(void)
+{
+       of_irq_init(vic_of_match);
+}
+
+DT_MACHINE_START(SPEAR600_DT, "ST SPEAr600 (Flattened Device Tree)")
+       .map_io         =       spear6xx_map_io,
+       .init_irq       =       spear6xx_dt_init_irq,
+       .handle_irq     =       vic_handle_irq,
+       .timer          =       &spear6xx_timer,
+       .init_machine   =       spear600_dt_init,
+       .restart        =       spear_restart,
+       .dt_compat      =       spear600_dt_board_compat,
+MACHINE_END
index 32b420a90c3dea5c49d5844b249d590c4246181c..d0f2546706ca1b53d6cae8d3eecb84dc89f79a17 100644 (file)
@@ -10,8 +10,16 @@ config ARCH_TEGRA_2x_SOC
        select PINCTRL
        select PINCTRL_TEGRA20
        select USB_ARCH_HAS_EHCI if USB_SUPPORT
-       select USB_ULPI if USB_SUPPORT
+       select USB_ULPI if USB
        select USB_ULPI_VIEWPORT if USB_SUPPORT
+       select ARM_ERRATA_720789
+       select ARM_ERRATA_742230
+       select ARM_ERRATA_751472
+       select ARM_ERRATA_754327
+       select ARM_ERRATA_764369
+       select PL310_ERRATA_727915 if CACHE_L2X0
+       select PL310_ERRATA_769419 if CACHE_L2X0
+       select CPU_FREQ_TABLE if CPU_FREQ
        help
          Support for NVIDIA Tegra AP20 and T20 processors, based on the
          ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
@@ -24,9 +32,15 @@ config ARCH_TEGRA_3x_SOC
        select PINCTRL
        select PINCTRL_TEGRA30
        select USB_ARCH_HAS_EHCI if USB_SUPPORT
-       select USB_ULPI if USB_SUPPORT
+       select USB_ULPI if USB
        select USB_ULPI_VIEWPORT if USB_SUPPORT
        select USE_OF
+       select ARM_ERRATA_743622
+       select ARM_ERRATA_751472
+       select ARM_ERRATA_754322
+       select ARM_ERRATA_764369
+       select PL310_ERRATA_769419 if CACHE_L2X0
+       select CPU_FREQ_TABLE if CPU_FREQ
        help
          Support for NVIDIA Tegra T30 processor family, based on the
          ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
index e120ff54f66377667928e5d2aa26583865782aef..d87d968115ec6c1adc477ebb61dc1c324ad4e6c9 100644 (file)
@@ -7,15 +7,21 @@ obj-y                                   += clock.o
 obj-y                                   += timer.o
 obj-y                                   += pinmux.o
 obj-y                                  += fuse.o
+obj-y                                  += pmc.o
+obj-y                                  += flowctrl.o
+obj-$(CONFIG_CPU_IDLE)                 += cpuidle.o
+obj-$(CONFIG_CPU_IDLE)                 += sleep.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += powergate.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra2_clocks.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += tegra2_emc.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += pinmux-tegra20-tables.o
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)                += pinmux-tegra30-tables.o
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)                += board-dt-tegra30.o
-obj-$(CONFIG_SMP)                       += platsmp.o localtimer.o headsmp.o
+obj-$(CONFIG_ARCH_TEGRA_3x_SOC)                += tegra30_clocks.o
+obj-$(CONFIG_SMP)                      += platsmp.o headsmp.o
+obj-$(CONFIG_SMP)                       += reset.o
 obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
-obj-$(CONFIG_TEGRA_SYSTEM_DMA)         += dma.o
+obj-$(CONFIG_TEGRA_SYSTEM_DMA)         += dma.o apbio.o
 obj-$(CONFIG_CPU_FREQ)                  += cpu-tegra.o
 obj-$(CONFIG_TEGRA_PCI)                        += pcie.o
 obj-$(CONFIG_USB_SUPPORT)              += usb_phy.o
diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
new file mode 100644 (file)
index 0000000..e75451e
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2010 NVIDIA Corporation.
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/spinlock.h>
+#include <linux/completion.h>
+#include <linux/sched.h>
+#include <linux/mutex.h>
+
+#include <mach/dma.h>
+#include <mach/iomap.h>
+
+#include "apbio.h"
+
+static DEFINE_MUTEX(tegra_apb_dma_lock);
+
+static struct tegra_dma_channel *tegra_apb_dma;
+static u32 *tegra_apb_bb;
+static dma_addr_t tegra_apb_bb_phys;
+static DECLARE_COMPLETION(tegra_apb_wait);
+
+bool tegra_apb_init(void)
+{
+       struct tegra_dma_channel *ch;
+
+       mutex_lock(&tegra_apb_dma_lock);
+
+       /* Check to see if we raced to setup */
+       if (tegra_apb_dma)
+               goto out;
+
+       ch = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT |
+               TEGRA_DMA_SHARED);
+
+       if (!ch)
+               goto out_fail;
+
+       tegra_apb_bb = dma_alloc_coherent(NULL, sizeof(u32),
+               &tegra_apb_bb_phys, GFP_KERNEL);
+       if (!tegra_apb_bb) {
+               pr_err("%s: can not allocate bounce buffer\n", __func__);
+               tegra_dma_free_channel(ch);
+               goto out_fail;
+       }
+
+       tegra_apb_dma = ch;
+out:
+       mutex_unlock(&tegra_apb_dma_lock);
+       return true;
+
+out_fail:
+       mutex_unlock(&tegra_apb_dma_lock);
+       return false;
+}
+
+static void apb_dma_complete(struct tegra_dma_req *req)
+{
+       complete(&tegra_apb_wait);
+}
+
+u32 tegra_apb_readl(unsigned long offset)
+{
+       struct tegra_dma_req req;
+       int ret;
+
+       if (!tegra_apb_dma && !tegra_apb_init())
+               return readl(IO_TO_VIRT(offset));
+
+       mutex_lock(&tegra_apb_dma_lock);
+       req.complete = apb_dma_complete;
+       req.to_memory = 1;
+       req.dest_addr = tegra_apb_bb_phys;
+       req.dest_bus_width = 32;
+       req.dest_wrap = 1;
+       req.source_addr = offset;
+       req.source_bus_width = 32;
+       req.source_wrap = 4;
+       req.req_sel = TEGRA_DMA_REQ_SEL_CNTR;
+       req.size = 4;
+
+       INIT_COMPLETION(tegra_apb_wait);
+
+       tegra_dma_enqueue_req(tegra_apb_dma, &req);
+
+       ret = wait_for_completion_timeout(&tegra_apb_wait,
+               msecs_to_jiffies(50));
+
+       if (WARN(ret == 0, "apb read dma timed out")) {
+               tegra_dma_dequeue_req(tegra_apb_dma, &req);
+               *(u32 *)tegra_apb_bb = 0;
+       }
+
+       mutex_unlock(&tegra_apb_dma_lock);
+       return *((u32 *)tegra_apb_bb);
+}
+
+void tegra_apb_writel(u32 value, unsigned long offset)
+{
+       struct tegra_dma_req req;
+       int ret;
+
+       if (!tegra_apb_dma && !tegra_apb_init()) {
+               writel(value, IO_TO_VIRT(offset));
+               return;
+       }
+
+       mutex_lock(&tegra_apb_dma_lock);
+       *((u32 *)tegra_apb_bb) = value;
+       req.complete = apb_dma_complete;
+       req.to_memory = 0;
+       req.dest_addr = offset;
+       req.dest_wrap = 4;
+       req.dest_bus_width = 32;
+       req.source_addr = tegra_apb_bb_phys;
+       req.source_bus_width = 32;
+       req.source_wrap = 1;
+       req.req_sel = TEGRA_DMA_REQ_SEL_CNTR;
+       req.size = 4;
+
+       INIT_COMPLETION(tegra_apb_wait);
+
+       tegra_dma_enqueue_req(tegra_apb_dma, &req);
+
+       ret = wait_for_completion_timeout(&tegra_apb_wait,
+               msecs_to_jiffies(50));
+
+       if (WARN(ret == 0, "apb write dma timed out"))
+               tegra_dma_dequeue_req(tegra_apb_dma, &req);
+
+       mutex_unlock(&tegra_apb_dma_lock);
+}
diff --git a/arch/arm/mach-tegra/apbio.h b/arch/arm/mach-tegra/apbio.h
new file mode 100644 (file)
index 0000000..8b49e8c
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 NVIDIA Corporation.
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_APBIO_H
+#define __MACH_TEGRA_APBIO_H
+
+#ifdef CONFIG_TEGRA_SYSTEM_DMA
+
+u32 tegra_apb_readl(unsigned long offset);
+void tegra_apb_writel(u32 value, unsigned long offset);
+
+#else
+#include <asm/io.h>
+#include <mach/io.h>
+
+static inline u32 tegra_apb_readl(unsigned long offset)
+{
+        return readl(IO_TO_VIRT(offset));
+}
+
+static inline void tegra_apb_writel(u32 value, unsigned long offset)
+{
+        writel(value, IO_TO_VIRT(offset));
+}
+#endif
+
+#endif
index 7a95e0bc4abaab251fb77cf1b21e09e94a04bdd6..e20b419d598342f55453f3526969e34120728517 100644 (file)
@@ -131,11 +131,7 @@ static void __init tegra_dt_init(void)
 }
 
 static const char *tegra20_dt_board_compat[] = {
-       "compulab,trimslice",
-       "nvidia,harmony",
-       "compal,paz00",
-       "nvidia,seaboard",
-       "nvidia,ventana",
+       "nvidia,tegra20",
        NULL
 };
 
index 3c197e2440b773f90f51f573e75d641dfe828862..5f7c03e972f3dc2654f82022d81129bb5982b0d7 100644 (file)
 #include <asm/hardware/gic.h>
 
 #include "board.h"
+#include "clock.h"
 
 static struct of_device_id tegra_dt_match_table[] __initdata = {
        { .compatible = "simple-bus", },
        {}
 };
 
+struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = {
+       OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000200, "sdhci-tegra.1", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000400, "sdhci-tegra.2", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000600, "sdhci-tegra.3", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C000, "tegra-i2c.0", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C400, "tegra-i2c.1", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C500, "tegra-i2c.2", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C700, "tegra-i2c.3", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000D000, "tegra-i2c.4", NULL),
+       {}
+};
+
+static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = {
+       /* name         parent          rate            enabled */
+       { "uarta",      "pll_p",        408000000,      true },
+       { NULL,         NULL,           0,              0},
+};
+
 static void __init tegra30_dt_init(void)
 {
+       tegra_clk_init_from_table(tegra_dt_clk_init_table);
+
        of_platform_populate(NULL, tegra_dt_match_table,
-                               NULL, NULL);
+                               tegra30_auxdata_lookup, NULL);
 }
 
 static const char *tegra30_dt_board_compat[] = {
-       "nvidia,cardhu",
+       "nvidia,tegra30",
        NULL
 };
 
index 465808c8ac0bd3f45ac03d9f0de5ad9ef92480ff..1af85bccc0f165302c3463d818b950298799c01e 100644 (file)
@@ -53,7 +53,7 @@ static struct tegra_pingroup_config harmony_pinmux[] = {
        {TEGRA_PINGROUP_GME,   TEGRA_MUX_SDIO4,         TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
        {TEGRA_PINGROUP_GPU,   TEGRA_MUX_GMI,           TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
        {TEGRA_PINGROUP_GPU7,  TEGRA_MUX_RTCK,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
-       {TEGRA_PINGROUP_GPV,   TEGRA_MUX_PCIE,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_GPV,   TEGRA_MUX_PCIE,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
        {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI,          TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
        {TEGRA_PINGROUP_I2CP,  TEGRA_MUX_I2C,           TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
        {TEGRA_PINGROUP_IRRX,  TEGRA_MUX_UARTA,         TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
@@ -112,10 +112,10 @@ static struct tegra_pingroup_config harmony_pinmux[] = {
        {TEGRA_PINGROUP_SDC,   TEGRA_MUX_PWM,           TEGRA_PUPD_PULL_UP,   TEGRA_TRI_NORMAL},
        {TEGRA_PINGROUP_SDD,   TEGRA_MUX_PWM,           TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
        {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1,         TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
-       {TEGRA_PINGROUP_SLXA,  TEGRA_MUX_PCIE,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_SLXA,  TEGRA_MUX_PCIE,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
        {TEGRA_PINGROUP_SLXC,  TEGRA_MUX_SPDIF,         TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
        {TEGRA_PINGROUP_SLXD,  TEGRA_MUX_SPDIF,         TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
-       {TEGRA_PINGROUP_SLXK,  TEGRA_MUX_PCIE,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_SLXK,  TEGRA_MUX_PCIE,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
        {TEGRA_PINGROUP_SPDI,  TEGRA_MUX_RSVD2,         TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
        {TEGRA_PINGROUP_SPDO,  TEGRA_MUX_RSVD2,         TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
        {TEGRA_PINGROUP_SPIA,  TEGRA_MUX_GMI,           TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
index 21d1285731b39a3e1cd71aa1a6367d72e3478b25..82f32300796c082fe4f76c938ba76ac9b4bb1ff2 100644 (file)
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
-#include <linux/io.h>
 #include <linux/regulator/machine.h>
 #include <linux/mfd/tps6586x.h>
 
-#include <mach/iomap.h>
 #include <mach/irqs.h>
 
 #include "board-harmony.h"
 
-#define PMC_CTRL               0x0
-#define PMC_CTRL_INTR_LOW      (1 << 17)
-
 static struct regulator_consumer_supply tps658621_ldo0_supply[] = {
        REGULATOR_SUPPLY("pex_clk", NULL),
 };
 
 static struct regulator_init_data ldo0_data = {
        .constraints = {
-               .min_uV = 1250 * 1000,
+               .min_uV = 3300 * 1000,
                .max_uV = 3300 * 1000,
                .valid_modes_mask = (REGULATOR_MODE_NORMAL |
                                     REGULATOR_MODE_STANDBY),
                .valid_ops_mask = (REGULATOR_CHANGE_MODE |
                                   REGULATOR_CHANGE_STATUS |
                                   REGULATOR_CHANGE_VOLTAGE),
+               .apply_uV = 1,
        },
        .num_consumer_supplies = ARRAY_SIZE(tps658621_ldo0_supply),
        .consumer_supplies = tps658621_ldo0_supply,
@@ -114,16 +110,6 @@ static struct i2c_board_info __initdata harmony_regulators[] = {
 
 int __init harmony_regulator_init(void)
 {
-       void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
-       u32 pmc_ctrl;
-
-       /*
-        * Configure the power management controller to trigger PMU
-        * interrupts when low
-        */
-       pmc_ctrl = readl(pmc + PMC_CTRL);
-       writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL);
-
        i2c_register_board_info(3, harmony_regulators, 1);
 
        return 0;
index 789bdc9e8f913ddb26e46e1a4b827a2b0b6f51fa..c00aadb01e097f70e63909e0fd05d43f35f12f44 100644 (file)
@@ -101,7 +101,6 @@ static struct wm8903_platform_data harmony_wm8903_pdata = {
 static struct i2c_board_info __initdata wm8903_board_info = {
        I2C_BOARD_INFO("wm8903", 0x1a),
        .platform_data = &harmony_wm8903_pdata,
-       .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ),
 };
 
 static void __init harmony_i2c_init(void)
@@ -111,6 +110,7 @@ static void __init harmony_i2c_init(void)
        platform_device_register(&tegra_i2c_device3);
        platform_device_register(&tegra_i2c_device4);
 
+       wm8903_board_info.irq = gpio_to_irq(TEGRA_GPIO_CDC_IRQ);
        i2c_register_board_info(0, &wm8903_board_info, 1);
 }
 
index ebac65f52510d4c4eb65093ab0fa79210e83940a..d669847f0485bdfffaf42e44290154777405f81b 100644 (file)
@@ -159,7 +159,6 @@ static struct platform_device *seaboard_devices[] __initdata = {
 
 static struct i2c_board_info __initdata isl29018_device = {
        I2C_BOARD_INFO("isl29018", 0x44),
-       .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_ISL29018_IRQ),
 };
 
 static struct i2c_board_info __initdata adt7461_device = {
@@ -183,7 +182,6 @@ static struct wm8903_platform_data wm8903_pdata = {
 static struct i2c_board_info __initdata wm8903_device = {
        I2C_BOARD_INFO("wm8903", 0x1a),
        .platform_data = &wm8903_pdata,
-       .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ),
 };
 
 static int seaboard_ehci_init(void)
@@ -214,7 +212,10 @@ static void __init seaboard_i2c_init(void)
        gpio_request(TEGRA_GPIO_ISL29018_IRQ, "isl29018");
        gpio_direction_input(TEGRA_GPIO_ISL29018_IRQ);
 
+       isl29018_device.irq = gpio_to_irq(TEGRA_GPIO_ISL29018_IRQ);
        i2c_register_board_info(0, &isl29018_device, 1);
+
+       wm8903_device.irq = gpio_to_irq(TEGRA_GPIO_CDC_IRQ);
        i2c_register_board_info(0, &wm8903_device, 1);
 
        i2c_register_board_info(3, &adt7461_device, 1);
index 8337068a4abebed1a1b693a3b6f5f2dd8af496e8..8dad8d18cb49cd26e12212718de9295a4f4e550a 100644 (file)
@@ -399,6 +399,28 @@ void tegra_periph_reset_assert(struct clk *c)
 }
 EXPORT_SYMBOL(tegra_periph_reset_assert);
 
+/* Several extended clock configuration bits (e.g., clock routing, clock
+ * phase control) are included in PLL and peripheral clock source
+ * registers. */
+int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
+{
+       int ret = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&c->spinlock, flags);
+
+       if (!c->ops || !c->ops->clk_cfg_ex) {
+               ret = -ENOSYS;
+               goto out;
+       }
+       ret = c->ops->clk_cfg_ex(c, p, setting);
+
+out:
+       spin_unlock_irqrestore(&c->spinlock, flags);
+
+       return ret;
+}
+
 #ifdef CONFIG_DEBUG_FS
 
 static int __clk_lock_all_spinlocks(void)
index 5c44106616c5bed12f0f53a3b54252868a2781ae..bc300657debaefe6b8eed297cb9e452bea618a74 100644 (file)
@@ -24,6 +24,8 @@
 #include <linux/list.h>
 #include <linux/spinlock.h>
 
+#include <mach/clk.h>
+
 #define DIV_BUS                        (1 << 0)
 #define DIV_U71                        (1 << 1)
 #define DIV_U71_FIXED          (1 << 2)
 #define PERIPH_MANUAL_RESET    (1 << 12)
 #define PLL_ALT_MISC_REG       (1 << 13)
 #define PLLU                   (1 << 14)
+#define PLLX                    (1 << 15)
+#define MUX_PWM                 (1 << 16)
+#define MUX8                    (1 << 17)
+#define DIV_U71_UART            (1 << 18)
+#define MUX_CLK_OUT             (1 << 19)
+#define PLLM                    (1 << 20)
+#define DIV_U71_INT             (1 << 21)
+#define DIV_U71_IDLE            (1 << 22)
 #define ENABLE_ON_INIT         (1 << 28)
+#define PERIPH_ON_APB           (1 << 29)
 
 struct clk;
 
@@ -65,6 +76,8 @@ struct clk_ops {
        int             (*set_rate)(struct clk *, unsigned long);
        long            (*round_rate)(struct clk *, unsigned long);
        void            (*reset)(struct clk *, bool);
+       int             (*clk_cfg_ex)(struct clk *,
+                               enum tegra_clk_ex_param, u32);
 };
 
 enum clk_state {
@@ -114,6 +127,7 @@ struct clk {
                        unsigned long                   vco_max;
                        const struct clk_pll_freq_table *freq_table;
                        int                             lock_delay;
+                       unsigned long                   fixed_rate;
                } pll;
                struct {
                        u32                             sel;
@@ -146,6 +160,7 @@ struct tegra_clk_init_table {
 };
 
 void tegra2_init_clocks(void);
+void tegra30_init_clocks(void);
 void clk_init(struct clk *clk);
 struct clk *tegra_get_clock_by_name(const char *name);
 int clk_reparent(struct clk *c, struct clk *parent);
index 2db20da1d585a98535046fe01e4911c80a108a17..22df10fb9972877069f92637ff5849ba990ad9f7 100644 (file)
 #include <asm/hardware/gic.h>
 
 #include <mach/iomap.h>
+#include <mach/powergate.h>
 
 #include "board.h"
 #include "clock.h"
 #include "fuse.h"
+#include "pmc.h"
+
+/*
+ * Storage for debug-macro.S's state.
+ *
+ * This must be in .data not .bss so that it gets initialized each time the
+ * kernel is loaded. The data is declared here rather than debug-macro.S so
+ * that multiple inclusions of debug-macro.S point at the same data.
+ */
+#define TEGRA_DEBUG_UART_OFFSET (TEGRA_DEBUG_UART_BASE & 0xFFFF)
+u32 tegra_uart_config[3] = {
+       /* Debug UART initialization required */
+       1,
+       /* Debug UART physical address */
+       (u32)(IO_APB_PHYS + TEGRA_DEBUG_UART_OFFSET),
+       /* Debug UART virtual address */
+       (u32)(IO_APB_VIRT + TEGRA_DEBUG_UART_OFFSET),
+};
 
 #ifdef CONFIG_OF
 static const struct of_device_id tegra_dt_irq_match[] __initconst = {
@@ -95,17 +114,21 @@ static void __init tegra_init_cache(u32 tag_latency, u32 data_latency)
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
 void __init tegra20_init_early(void)
 {
-       disable_hlt();  /* idle WFI usage needs to be confirmed */
-
        tegra_init_fuse();
        tegra2_init_clocks();
        tegra_clk_init_from_table(tegra20_clk_init_table);
        tegra_init_cache(0x331, 0x441);
+       tegra_pmc_init();
+       tegra_powergate_init();
 }
 #endif
 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
 void __init tegra30_init_early(void)
 {
+       tegra_init_fuse();
+       tegra30_init_clocks();
        tegra_init_cache(0x441, 0x551);
+       tegra_pmc_init();
+       tegra_powergate_init();
 }
 #endif
diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c
new file mode 100644 (file)
index 0000000..d83a8c0
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * arch/arm/mach-tegra/cpuidle.c
+ *
+ * CPU idle driver for Tegra CPUs
+ *
+ * Copyright (c) 2010-2012, NVIDIA Corporation.
+ * Copyright (c) 2011 Google, Inc.
+ * Author: Colin Cross <ccross@android.com>
+ *         Gary King <gking@nvidia.com>
+ *
+ * Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/cpu.h>
+#include <linux/cpuidle.h>
+#include <linux/hrtimer.h>
+
+#include <mach/iomap.h>
+
+extern void tegra_cpu_wfi(void);
+
+static int tegra_idle_enter_lp3(struct cpuidle_device *dev,
+                               struct cpuidle_driver *drv, int index);
+
+struct cpuidle_driver tegra_idle_driver = {
+       .name = "tegra_idle",
+       .owner = THIS_MODULE,
+       .state_count = 1,
+       .states = {
+               [0] = {
+                       .enter                  = tegra_idle_enter_lp3,
+                       .exit_latency           = 10,
+                       .target_residency       = 10,
+                       .power_usage            = 600,
+                       .flags                  = CPUIDLE_FLAG_TIME_VALID,
+                       .name                   = "LP3",
+                       .desc                   = "CPU flow-controlled",
+               },
+       },
+};
+
+static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device);
+
+static int tegra_idle_enter_lp3(struct cpuidle_device *dev,
+       struct cpuidle_driver *drv, int index)
+{
+       ktime_t enter, exit;
+       s64 us;
+
+       local_irq_disable();
+       local_fiq_disable();
+
+       enter = ktime_get();
+
+       tegra_cpu_wfi();
+
+       exit = ktime_sub(ktime_get(), enter);
+       us = ktime_to_us(exit);
+
+       local_fiq_enable();
+       local_irq_enable();
+
+       dev->last_residency = us;
+
+       return index;
+}
+
+static int __init tegra_cpuidle_init(void)
+{
+       int ret;
+       unsigned int cpu;
+       struct cpuidle_device *dev;
+       struct cpuidle_driver *drv = &tegra_idle_driver;
+
+       ret = cpuidle_register_driver(&tegra_idle_driver);
+       if (ret) {
+               pr_err("CPUidle driver registration failed\n");
+               return ret;
+       }
+
+       for_each_possible_cpu(cpu) {
+               dev = &per_cpu(tegra_idle_device, cpu);
+               dev->cpu = cpu;
+
+               dev->state_count = drv->state_count;
+               ret = cpuidle_register_device(dev);
+               if (ret) {
+                       pr_err("CPU%u: CPUidle device registration failed\n",
+                               cpu);
+                       return ret;
+               }
+       }
+       return 0;
+}
+device_initcall(tegra_cpuidle_init);
index c0cf967e47d3bced9577a43d87c3c42c9465e251..abea4f6e2dd5cbc47aeb3a516fea05d27afe08d4 100644 (file)
@@ -33,6 +33,8 @@
 #include <mach/iomap.h>
 #include <mach/suspend.h>
 
+#include "apbio.h"
+
 #define APB_DMA_GEN                            0x000
 #define GEN_ENABLE                             (1<<31)
 
@@ -50,8 +52,6 @@
 #define CSR_ONCE                               (1<<27)
 #define CSR_FLOW                               (1<<21)
 #define CSR_REQ_SEL_SHIFT                      16
-#define CSR_REQ_SEL_MASK                       (0x1F<<CSR_REQ_SEL_SHIFT)
-#define CSR_REQ_SEL_INVALID                    (31<<CSR_REQ_SEL_SHIFT)
 #define CSR_WCOUNT_SHIFT                       2
 #define CSR_WCOUNT_MASK                                0xFFFC
 
@@ -133,6 +133,7 @@ struct tegra_dma_channel {
 
 static bool tegra_dma_initialized;
 static DEFINE_MUTEX(tegra_dma_lock);
+static DEFINE_SPINLOCK(enable_lock);
 
 static DECLARE_BITMAP(channel_usage, NV_DMA_MAX_CHANNELS);
 static struct tegra_dma_channel dma_channels[NV_DMA_MAX_CHANNELS];
@@ -180,36 +181,94 @@ static void tegra_dma_stop(struct tegra_dma_channel *ch)
 
 static int tegra_dma_cancel(struct tegra_dma_channel *ch)
 {
-       u32 csr;
        unsigned long irq_flags;
 
        spin_lock_irqsave(&ch->lock, irq_flags);
        while (!list_empty(&ch->list))
                list_del(ch->list.next);
 
-       csr = readl(ch->addr + APB_DMA_CHAN_CSR);
-       csr &= ~CSR_REQ_SEL_MASK;
-       csr |= CSR_REQ_SEL_INVALID;
-       writel(csr, ch->addr + APB_DMA_CHAN_CSR);
-
        tegra_dma_stop(ch);
 
        spin_unlock_irqrestore(&ch->lock, irq_flags);
        return 0;
 }
 
+static unsigned int get_channel_status(struct tegra_dma_channel *ch,
+                       struct tegra_dma_req *req, bool is_stop_dma)
+{
+       void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_BASE);
+       unsigned int status;
+
+       if (is_stop_dma) {
+               /*
+                * STOP the DMA and get the transfer count.
+                * Getting the transfer count is tricky.
+                *  - Globally disable DMA on all channels
+                *  - Read the channel's status register to know the number
+                *    of pending bytes to be transfered.
+                *  - Stop the dma channel
+                *  - Globally re-enable DMA to resume other transfers
+                */
+               spin_lock(&enable_lock);
+               writel(0, addr + APB_DMA_GEN);
+               udelay(20);
+               status = readl(ch->addr + APB_DMA_CHAN_STA);
+               tegra_dma_stop(ch);
+               writel(GEN_ENABLE, addr + APB_DMA_GEN);
+               spin_unlock(&enable_lock);
+               if (status & STA_ISE_EOC) {
+                       pr_err("Got Dma Int here clearing");
+                       writel(status, ch->addr + APB_DMA_CHAN_STA);
+               }
+               req->status = TEGRA_DMA_REQ_ERROR_ABORTED;
+       } else {
+               status = readl(ch->addr + APB_DMA_CHAN_STA);
+       }
+       return status;
+}
+
+/* should be called with the channel lock held */
+static unsigned int dma_active_count(struct tegra_dma_channel *ch,
+       struct tegra_dma_req *req, unsigned int status)
+{
+       unsigned int to_transfer;
+       unsigned int req_transfer_count;
+       unsigned int bytes_transferred;
+
+       to_transfer = ((status & STA_COUNT_MASK) >> STA_COUNT_SHIFT) + 1;
+       req_transfer_count = ch->req_transfer_count + 1;
+       bytes_transferred = req_transfer_count;
+       if (status & STA_BUSY)
+               bytes_transferred -= to_transfer;
+       /*
+        * In continuous transfer mode, DMA only tracks the count of the
+        * half DMA buffer. So, if the DMA already finished half the DMA
+        * then add the half buffer to the completed count.
+        */
+       if (ch->mode & TEGRA_DMA_MODE_CONTINOUS) {
+               if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL)
+                       bytes_transferred += req_transfer_count;
+               if (status & STA_ISE_EOC)
+                       bytes_transferred += req_transfer_count;
+       }
+       bytes_transferred *= 4;
+       return bytes_transferred;
+}
+
 int tegra_dma_dequeue_req(struct tegra_dma_channel *ch,
        struct tegra_dma_req *_req)
 {
-       unsigned int csr;
        unsigned int status;
        struct tegra_dma_req *req = NULL;
        int found = 0;
        unsigned long irq_flags;
-       int to_transfer;
-       int req_transfer_count;
+       int stop = 0;
 
        spin_lock_irqsave(&ch->lock, irq_flags);
+
+       if (list_entry(ch->list.next, struct tegra_dma_req, node) == _req)
+               stop = 1;
+
        list_for_each_entry(req, &ch->list, node) {
                if (req == _req) {
                        list_del(&req->node);
@@ -222,47 +281,12 @@ int tegra_dma_dequeue_req(struct tegra_dma_channel *ch,
                return 0;
        }
 
-       /* STOP the DMA and get the transfer count.
-        * Getting the transfer count is tricky.
-        *  - Change the source selector to invalid to stop the DMA from
-        *    FIFO to memory.
-        *  - Read the status register to know the number of pending
-        *    bytes to be transferred.
-        *  - Finally stop or program the DMA to the next buffer in the
-        *    list.
-        */
-       csr = readl(ch->addr + APB_DMA_CHAN_CSR);
-       csr &= ~CSR_REQ_SEL_MASK;
-       csr |= CSR_REQ_SEL_INVALID;
-       writel(csr, ch->addr + APB_DMA_CHAN_CSR);
-
-       /* Get the transfer count */
-       status = readl(ch->addr + APB_DMA_CHAN_STA);
-       to_transfer = (status & STA_COUNT_MASK) >> STA_COUNT_SHIFT;
-       req_transfer_count = ch->req_transfer_count;
-       req_transfer_count += 1;
-       to_transfer += 1;
-
-       req->bytes_transferred = req_transfer_count;
-
-       if (status & STA_BUSY)
-               req->bytes_transferred -= to_transfer;
-
-       /* In continuous transfer mode, DMA only tracks the count of the
-        * half DMA buffer. So, if the DMA already finished half the DMA
-        * then add the half buffer to the completed count.
-        *
-        *      FIXME: There can be a race here. What if the req to
-        *      dequue happens at the same time as the DMA just moved to
-        *      the new buffer and SW didn't yet received the interrupt?
-        */
-       if (ch->mode & TEGRA_DMA_MODE_CONTINOUS)
-               if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL)
-                       req->bytes_transferred += req_transfer_count;
+       if (!stop)
+               goto skip_stop_dma;
 
-       req->bytes_transferred *= 4;
+       status = get_channel_status(ch, req, true);
+       req->bytes_transferred = dma_active_count(ch, req, status);
 
-       tegra_dma_stop(ch);
        if (!list_empty(&ch->list)) {
                /* if the list is not empty, queue the next request */
                struct tegra_dma_req *next_req;
@@ -270,6 +294,8 @@ int tegra_dma_dequeue_req(struct tegra_dma_channel *ch,
                        typeof(*next_req), node);
                tegra_dma_update_hw(ch, next_req);
        }
+
+skip_stop_dma:
        req->status = -TEGRA_DMA_REQ_ERROR_ABORTED;
 
        spin_unlock_irqrestore(&ch->lock, irq_flags);
@@ -357,7 +383,7 @@ struct tegra_dma_channel *tegra_dma_allocate_channel(int mode)
        int channel;
        struct tegra_dma_channel *ch = NULL;
 
-       if (WARN_ON(!tegra_dma_initialized))
+       if (!tegra_dma_initialized)
                return NULL;
 
        mutex_lock(&tegra_dma_lock);
diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c
new file mode 100644 (file)
index 0000000..fef66a7
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * arch/arm/mach-tegra/flowctrl.c
+ *
+ * functions and macros to control the flowcontroller
+ *
+ * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+
+#include <mach/iomap.h>
+
+#include "flowctrl.h"
+
+u8 flowctrl_offset_halt_cpu[] = {
+       FLOW_CTRL_HALT_CPU0_EVENTS,
+       FLOW_CTRL_HALT_CPU1_EVENTS,
+       FLOW_CTRL_HALT_CPU1_EVENTS + 8,
+       FLOW_CTRL_HALT_CPU1_EVENTS + 16,
+};
+
+u8 flowctrl_offset_cpu_csr[] = {
+       FLOW_CTRL_CPU0_CSR,
+       FLOW_CTRL_CPU1_CSR,
+       FLOW_CTRL_CPU1_CSR + 8,
+       FLOW_CTRL_CPU1_CSR + 16,
+};
+
+static void flowctrl_update(u8 offset, u32 value)
+{
+       void __iomem *addr = IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + offset;
+
+       writel(value, addr);
+
+       /* ensure the update has reached the flow controller */
+       wmb();
+       readl_relaxed(addr);
+}
+
+void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value)
+{
+       return flowctrl_update(flowctrl_offset_halt_cpu[cpuid], value);
+}
+
+void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value)
+{
+       return flowctrl_update(flowctrl_offset_cpu_csr[cpuid], value);
+}
diff --git a/arch/arm/mach-tegra/flowctrl.h b/arch/arm/mach-tegra/flowctrl.h
new file mode 100644 (file)
index 0000000..1942817
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/mach-tegra/flowctrl.h
+ *
+ * functions and macros to control the flowcontroller
+ *
+ * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MACH_TEGRA_FLOWCTRL_H
+#define __MACH_TEGRA_FLOWCTRL_H
+
+#define FLOW_CTRL_HALT_CPU0_EVENTS     0x0
+#define FLOW_CTRL_WAITEVENT            (2 << 29)
+#define FLOW_CTRL_WAIT_FOR_INTERRUPT   (4 << 29)
+#define FLOW_CTRL_JTAG_RESUME          (1 << 28)
+#define FLOW_CTRL_HALT_CPU_IRQ         (1 << 10)
+#define        FLOW_CTRL_HALT_CPU_FIQ          (1 << 8)
+#define FLOW_CTRL_CPU0_CSR             0x8
+#define        FLOW_CTRL_CSR_INTR_FLAG         (1 << 15)
+#define FLOW_CTRL_CSR_EVENT_FLAG       (1 << 14)
+#define FLOW_CTRL_CSR_ENABLE           (1 << 0)
+#define FLOW_CTRL_HALT_CPU1_EVENTS     0x14
+#define FLOW_CTRL_CPU1_CSR             0x18
+
+#ifndef __ASSEMBLY__
+void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value);
+void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value);
+#endif
+
+#endif
index ea49bd93c6b9dbdb374a2fbb72f6b79fc2be1ad6..f946d129423c7b407dab381906b219f5287200ca 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/io.h>
-#include <linux/module.h>
+#include <linux/export.h>
 
 #include <mach/iomap.h>
 
 #include "fuse.h"
+#include "apbio.h"
 
 #define FUSE_UID_LOW           0x108
 #define FUSE_UID_HIGH          0x10c
 #define FUSE_SKU_INFO          0x110
 #define FUSE_SPARE_BIT         0x200
 
-static inline u32 fuse_readl(unsigned long offset)
+int tegra_sku_id;
+int tegra_cpu_process_id;
+int tegra_core_process_id;
+int tegra_chip_id;
+enum tegra_revision tegra_revision;
+
+/* The BCT to use at boot is specified by board straps that can be read
+ * through a APB misc register and decoded. 2 bits, i.e. 4 possible BCTs.
+ */
+int tegra_bct_strapping;
+
+#define STRAP_OPT 0x008
+#define GMI_AD0 (1 << 4)
+#define GMI_AD1 (1 << 5)
+#define RAM_ID_MASK (GMI_AD0 | GMI_AD1)
+#define RAM_CODE_SHIFT 4
+
+static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
+       [TEGRA_REVISION_UNKNOWN] = "unknown",
+       [TEGRA_REVISION_A01]     = "A01",
+       [TEGRA_REVISION_A02]     = "A02",
+       [TEGRA_REVISION_A03]     = "A03",
+       [TEGRA_REVISION_A03p]    = "A03 prime",
+       [TEGRA_REVISION_A04]     = "A04",
+};
+
+static inline u32 tegra_fuse_readl(unsigned long offset)
 {
-       return readl(IO_TO_VIRT(TEGRA_FUSE_BASE + offset));
+       return tegra_apb_readl(TEGRA_FUSE_BASE + offset);
 }
 
-static inline void fuse_writel(u32 value, unsigned long offset)
+static inline bool get_spare_fuse(int bit)
 {
-       writel(value, IO_TO_VIRT(TEGRA_FUSE_BASE + offset));
+       return tegra_fuse_readl(FUSE_SPARE_BIT + bit * 4);
+}
+
+static enum tegra_revision tegra_get_revision(u32 id)
+{
+       u32 minor_rev = (id >> 16) & 0xf;
+
+       switch (minor_rev) {
+       case 1:
+               return TEGRA_REVISION_A01;
+       case 2:
+               return TEGRA_REVISION_A02;
+       case 3:
+               if (tegra_chip_id == TEGRA20 &&
+                       (get_spare_fuse(18) || get_spare_fuse(19)))
+                       return TEGRA_REVISION_A03p;
+               else
+                       return TEGRA_REVISION_A03;
+       case 4:
+               return TEGRA_REVISION_A04;
+       default:
+               return TEGRA_REVISION_UNKNOWN;
+       }
 }
 
 void tegra_init_fuse(void)
 {
+       u32 id;
+
        u32 reg = readl(IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48));
        reg |= 1 << 28;
        writel(reg, IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48));
 
-       pr_info("Tegra SKU: %d CPU Process: %d Core Process: %d\n",
-               tegra_sku_id(), tegra_cpu_process_id(),
-               tegra_core_process_id());
+       reg = tegra_fuse_readl(FUSE_SKU_INFO);
+       tegra_sku_id = reg & 0xFF;
+
+       reg = tegra_fuse_readl(FUSE_SPARE_BIT);
+       tegra_cpu_process_id = (reg >> 6) & 3;
+
+       reg = tegra_fuse_readl(FUSE_SPARE_BIT);
+       tegra_core_process_id = (reg >> 12) & 3;
+
+       reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT);
+       tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT;
+
+       id = readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804);
+       tegra_chip_id = (id >> 8) & 0xff;
+
+       tegra_revision = tegra_get_revision(id);
+
+       pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
+               tegra_revision_name[tegra_revision],
+               tegra_sku_id, tegra_cpu_process_id,
+               tegra_core_process_id);
 }
 
 unsigned long long tegra_chip_uid(void)
 {
        unsigned long long lo, hi;
 
-       lo = fuse_readl(FUSE_UID_LOW);
-       hi = fuse_readl(FUSE_UID_HIGH);
+       lo = tegra_fuse_readl(FUSE_UID_LOW);
+       hi = tegra_fuse_readl(FUSE_UID_HIGH);
        return (hi << 32ull) | lo;
 }
 EXPORT_SYMBOL(tegra_chip_uid);
-
-int tegra_sku_id(void)
-{
-       int sku_id;
-       u32 reg = fuse_readl(FUSE_SKU_INFO);
-       sku_id = reg & 0xFF;
-       return sku_id;
-}
-
-int tegra_cpu_process_id(void)
-{
-       int cpu_process_id;
-       u32 reg = fuse_readl(FUSE_SPARE_BIT);
-       cpu_process_id = (reg >> 6) & 3;
-       return cpu_process_id;
-}
-
-int tegra_core_process_id(void)
-{
-       int core_process_id;
-       u32 reg = fuse_readl(FUSE_SPARE_BIT);
-       core_process_id = (reg >> 12) & 3;
-       return core_process_id;
-}
index 584b2e27dbda5679078ce2f60d552f98a4c13f3c..d2107b2cb85adcae862e7945123d991076f64299 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * arch/arm/mach-tegra/fuse.c
- *
  * Copyright (C) 2010 Google, Inc.
  *
  * Author:
  *
  */
 
+#ifndef __MACH_TEGRA_FUSE_H
+#define __MACH_TEGRA_FUSE_H
+
+enum tegra_revision {
+       TEGRA_REVISION_UNKNOWN = 0,
+       TEGRA_REVISION_A01,
+       TEGRA_REVISION_A02,
+       TEGRA_REVISION_A03,
+       TEGRA_REVISION_A03p,
+       TEGRA_REVISION_A04,
+       TEGRA_REVISION_MAX,
+};
+
+#define SKU_ID_T20     8
+#define SKU_ID_T25SE   20
+#define SKU_ID_AP25    23
+#define SKU_ID_T25     24
+#define SKU_ID_AP25E   27
+#define SKU_ID_T25E    28
+
+#define TEGRA20                0x20
+#define TEGRA30                0x30
+
+extern int tegra_sku_id;
+extern int tegra_cpu_process_id;
+extern int tegra_core_process_id;
+extern int tegra_chip_id;
+extern enum tegra_revision tegra_revision;
+
+extern int tegra_bct_strapping;
+
 unsigned long long tegra_chip_uid(void);
-int tegra_sku_id(void);
-int tegra_cpu_process_id(void);
-int tegra_core_process_id(void);
 void tegra_init_fuse(void);
+
+#endif
index b5349b2f13d296893f6737e39d544b93e89472d3..fef9c2c5137092d3f09947c430b127a36dcb9749 100644 (file)
@@ -1,6 +1,23 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 
+#include <asm/cache.h>
+
+#include <mach/iomap.h>
+
+#include "flowctrl.h"
+#include "reset.h"
+
+#define APB_MISC_GP_HIDREV     0x804
+#define PMC_SCRATCH41  0x140
+
+#define RESET_DATA(x)  ((TEGRA_RESET_##x)*4)
+
+       .macro mov32, reg, val
+       movw    \reg, #:lower16:\val
+       movt    \reg, #:upper16:\val
+       .endm
+
         .section ".text.head", "ax"
        __CPUINIT
 
@@ -47,15 +64,149 @@ ENTRY(v7_invalidate_l1)
         mov     pc, lr
 ENDPROC(v7_invalidate_l1)
 
+
 ENTRY(tegra_secondary_startup)
-       msr     cpsr_fsxc, #0xd3
         bl      v7_invalidate_l1
-       mrc     p15, 0, r0, c0, c0, 5
-        and    r0, r0, #15
-        ldr     r1, =0x6000f100
-        str     r0, [r1]
-1:      ldr     r2, [r1]
-        cmp     r0, r2
-        beq     1b
+       /* Enable coresight */
+       mov32   r0, 0xC5ACCE55
+       mcr     p14, 0, r0, c7, c12, 6
         b       secondary_startup
 ENDPROC(tegra_secondary_startup)
+
+       .align L1_CACHE_SHIFT
+ENTRY(__tegra_cpu_reset_handler_start)
+
+/*
+ * __tegra_cpu_reset_handler:
+ *
+ * Common handler for all CPU reset events.
+ *
+ * Register usage within the reset handler:
+ *
+ *      R7  = CPU present (to the OS) mask
+ *      R8  = CPU in LP1 state mask
+ *      R9  = CPU in LP2 state mask
+ *      R10 = CPU number
+ *      R11 = CPU mask
+ *      R12 = pointer to reset handler data
+ *
+ * NOTE: This code is copied to IRAM. All code and data accesses
+ *       must be position-independent.
+ */
+
+       .align L1_CACHE_SHIFT
+ENTRY(__tegra_cpu_reset_handler)
+
+       cpsid   aif, 0x13                       @ SVC mode, interrupts disabled
+       mrc     p15, 0, r10, c0, c0, 5          @ MPIDR
+       and     r10, r10, #0x3                  @ R10 = CPU number
+       mov     r11, #1
+       mov     r11, r11, lsl r10               @ R11 = CPU mask
+       adr     r12, __tegra_cpu_reset_handler_data
+
+#ifdef CONFIG_SMP
+       /* Does the OS know about this CPU? */
+       ldr     r7, [r12, #RESET_DATA(MASK_PRESENT)]
+       tst     r7, r11                         @ if !present
+       bleq    __die                           @ CPU not present (to OS)
+#endif
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+       /* Are we on Tegra20? */
+       mov32   r6, TEGRA_APB_MISC_BASE
+       ldr     r0, [r6, #APB_MISC_GP_HIDREV]
+       and     r0, r0, #0xff00
+       cmp     r0, #(0x20 << 8)
+       bne     1f
+       /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
+       mov32   r6, TEGRA_PMC_BASE
+       mov     r0, #0
+       cmp     r10, #0
+       strne   r0, [r6, #PMC_SCRATCH41]
+1:
+#endif
+
+#ifdef CONFIG_SMP
+       /*
+        * Can only be secondary boot (initial or hotplug) but CPU 0
+        * cannot be here.
+        */
+       cmp     r10, #0
+       bleq    __die                           @ CPU0 cannot be here
+       ldr     lr, [r12, #RESET_DATA(STARTUP_SECONDARY)]
+       cmp     lr, #0
+       bleq    __die                           @ no secondary startup handler
+       bx      lr
+#endif
+
+/*
+ * We don't know why the CPU reset. Just kill it.
+ * The LR register will contain the address we died at + 4.
+ */
+
+__die:
+       sub     lr, lr, #4
+       mov32   r7, TEGRA_PMC_BASE
+       str     lr, [r7, #PMC_SCRATCH41]
+
+       mov32   r7, TEGRA_CLK_RESET_BASE
+
+       /* Are we on Tegra20? */
+       mov32   r6, TEGRA_APB_MISC_BASE
+       ldr     r0, [r6, #APB_MISC_GP_HIDREV]
+       and     r0, r0, #0xff00
+       cmp     r0, #(0x20 << 8)
+       bne     1f
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+       mov32   r0, 0x1111
+       mov     r1, r0, lsl r10
+       str     r1, [r7, #0x340]                @ CLK_RST_CPU_CMPLX_SET
+#endif
+1:
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+       mov32   r6, TEGRA_FLOW_CTRL_BASE
+
+       cmp     r10, #0
+       moveq   r1, #FLOW_CTRL_HALT_CPU0_EVENTS
+       moveq   r2, #FLOW_CTRL_CPU0_CSR
+       movne   r1, r10, lsl #3
+       addne   r2, r1, #(FLOW_CTRL_CPU1_CSR-8)
+       addne   r1, r1, #(FLOW_CTRL_HALT_CPU1_EVENTS-8)
+
+       /* Clear CPU "event" and "interrupt" flags and power gate
+          it when halting but not before it is in the "WFI" state. */
+       ldr     r0, [r6, +r2]
+       orr     r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
+       orr     r0, r0, #FLOW_CTRL_CSR_ENABLE
+       str     r0, [r6, +r2]
+
+       /* Unconditionally halt this CPU */
+       mov     r0, #FLOW_CTRL_WAITEVENT
+       str     r0, [r6, +r1]
+       ldr     r0, [r6, +r1]                   @ memory barrier
+
+       dsb
+       isb
+       wfi                                     @ CPU should be power gated here
+
+       /* If the CPU didn't power gate above just kill it's clock. */
+
+       mov     r0, r11, lsl #8
+       str     r0, [r7, #348]                  @ CLK_CPU_CMPLX_SET
+#endif
+
+       /* If the CPU still isn't dead, just spin here. */
+       b       .
+ENDPROC(__tegra_cpu_reset_handler)
+
+       .align L1_CACHE_SHIFT
+       .type   __tegra_cpu_reset_handler_data, %object
+       .globl  __tegra_cpu_reset_handler_data
+__tegra_cpu_reset_handler_data:
+       .rept   TEGRA_RESET_DATA_SIZE
+       .long   0
+       .endr
+       .align L1_CACHE_SHIFT
+
+ENTRY(__tegra_cpu_reset_handler_end)
index fc3ecb66de08607a938cb23d45190ac32263a6a2..d97e403303a0ef095c639042949f67e795e24c7e 100644 (file)
 
 struct clk;
 
+enum tegra_clk_ex_param {
+       TEGRA_CLK_VI_INP_SEL,
+       TEGRA_CLK_DTV_INVERT,
+       TEGRA_CLK_NAND_PAD_DIV2_ENB,
+       TEGRA_CLK_PLLD_CSI_OUT_ENB,
+       TEGRA_CLK_PLLD_DSI_OUT_ENB,
+       TEGRA_CLK_PLLD_MIPI_MUX_SEL,
+};
+
 void tegra_periph_reset_deassert(struct clk *c);
 void tegra_periph_reset_assert(struct clk *c);
 
 unsigned long clk_get_rate_all_locked(struct clk *c);
 void tegra2_sdmmc_tap_delay(struct clk *c, int delay);
+int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting);
 
 #endif
index 619abc63aee83748c918db3ce9cc08c1ea58d254..90069abd37bd84844c5fc29ce2fca73e66d9ec8e 100644 (file)
@@ -1,11 +1,17 @@
 /*
  * arch/arm/mach-tegra/include/mach/debug-macro.S
  *
- * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2010,2011 Google, Inc.
+ * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved.
  *
  * Author:
  *     Colin Cross <ccross@google.com>
  *     Erik Gilling <konkers@google.com>
+ *     Doug Anderson <dianders@chromium.org>
+ *     Stephen Warren <swarren@nvidia.com>
+ *
+ * Portions based on mach-omap2's debug-macro.S
+ * Copyright (C) 1994-1999 Russell King
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
  *
  */
 
+#include <linux/serial_reg.h>
+
 #include <mach/io.h>
 #include <mach/iomap.h>
+#include <mach/irammap.h>
+
+               .macro  addruart, rp, rv, tmp
+               adr     \rp, 99f                @ actual addr of 99f
+               ldr     \rv, [\rp]              @ linked addr is stored there
+               sub     \rv, \rv, \rp           @ offset between the two
+               ldr     \rp, [\rp, #4]          @ linked tegra_uart_config
+               sub     \tmp, \rp, \rv          @ actual tegra_uart_config
+               ldr     \rp, [\tmp]             @ Load tegra_uart_config
+               cmp     \rp, #1                 @ needs intitialization?
+               bne     100f                    @ no; go load the addresses
+               mov     \rv, #0                 @ yes; record init is done
+               str     \rv, [\tmp]
+               mov     \rp, #TEGRA_IRAM_BASE   @ See if cookie is in IRAM
+               ldr     \rv, [\rp, #TEGRA_IRAM_DEBUG_UART_OFFSET]
+               movw    \rp, #TEGRA_IRAM_DEBUG_UART_COOKIE & 0xffff
+               movt    \rp, #TEGRA_IRAM_DEBUG_UART_COOKIE >> 16
+               cmp     \rv, \rp                @ Cookie present?
+               bne     100f                    @ No, use default UART
+               mov     \rp, #TEGRA_IRAM_BASE   @ Load UART address from IRAM
+               ldr     \rv, [\rp, #TEGRA_IRAM_DEBUG_UART_OFFSET + 4]
+               str     \rv, [\tmp, #4]         @ Store in tegra_uart_phys
+               sub     \rv, \rv, #IO_APB_PHYS  @ Calculate virt address
+               add     \rv, \rv, #IO_APB_VIRT
+               str     \rv, [\tmp, #8]         @ Store in tegra_uart_virt
+               b       100f
+
+               .align
+99:            .word   .
+               .word   tegra_uart_config
+               .ltorg
+
+100:           ldr     \rp, [\tmp, #4]         @ Load tegra_uart_phys
+               ldr     \rv, [\tmp, #8]         @ Load tegra_uart_virt
+               .endm
+
+#define UART_SHIFT 2
+
+/*
+ * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra
+ * check to make sure that we aren't in the CONFIG_TEGRA_DEBUG_UART_NONE case.
+ * We use the fact that all 5 valid UART addresses all have something in the
+ * 2nd-to-lowest byte.
+ */
 
-       .macro  addruart, rp, rv, tmp
-        ldr     \rp, =IO_APB_PHYS       @ physical
-        ldr     \rv, =IO_APB_VIRT        @ virtual
-       orr     \rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF)
-       orr     \rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF00)
-       orr     \rv, \rv, #(TEGRA_DEBUG_UART_BASE & 0xFF)
-       orr     \rv, \rv, #(TEGRA_DEBUG_UART_BASE & 0xFF00)
-       .endm
+               .macro  senduart, rd, rx
+               tst     \rx, #0x0000ff00
+               strneb  \rd, [\rx, #UART_TX << UART_SHIFT]
+1001:
+               .endm
 
-#define UART_SHIFT     2
-#include <asm/hardware/debug-8250.S>
+               .macro  busyuart, rd, rx
+               tst     \rx, #0x0000ff00
+               beq     1002f
+1001:          ldrb    \rd, [\rx, #UART_LSR << UART_SHIFT]
+               and     \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
+               teq     \rd, #UART_LSR_TEMT | UART_LSR_THRE
+               bne     1001b
+1002:
+               .endm
 
+               .macro  waituart, rd, rx
+#ifdef FLOW_CONTROL
+               tst     \rx, #0x0000ff00
+               beq     1002f
+1001:          ldrb    \rd, [\rx, #UART_MSR << UART_SHIFT]
+               tst     \rd, #UART_MSR_CTS
+               beq     1001b
+1002:
+#endif
+               .endm
index 87d37fdf50846ef6d3baa66dd31e5e4b278babfa..6140820555e1a88ffbc058e6ae22a49e73ef0635 100644 (file)
@@ -25,8 +25,6 @@
 
 #define TEGRA_NR_GPIOS         INT_GPIO_NR
 
-#define TEGRA_GPIO_TO_IRQ(gpio) (INT_GPIO_BASE + (gpio))
-
 struct tegra_gpio_table {
        int     gpio;   /* GPIO number */
        bool    enable; /* Enable for GPIO at init? */
index 19dec3ac0854a49218d107b78f00b26857ef7329..cff672a344f4e70a0057da3163f6cca7b35fc60f 100644 (file)
@@ -74,6 +74,9 @@
 #define TEGRA_QUATERNARY_ICTLR_BASE    0x60004300
 #define TEGRA_QUATERNARY_ICTLR_SIZE    SZ_64
 
+#define TEGRA_QUINARY_ICTLR_BASE       0x60004400
+#define TEGRA_QUINARY_ICTLR_SIZE       SZ_64
+
 #define TEGRA_TMR1_BASE                        0x60005000
 #define TEGRA_TMR1_SIZE                        SZ_8
 
 #define TEGRA_AHB_GIZMO_BASE           0x6000C004
 #define TEGRA_AHB_GIZMO_SIZE           0x10C
 
+#define TEGRA_SB_BASE                  0x6000C200
+#define TEGRA_SB_SIZE                  256
+
 #define TEGRA_STATMON_BASE             0x6000C400
 #define TEGRA_STATMON_SIZE             SZ_1K
 
diff --git a/arch/arm/mach-tegra/include/mach/irammap.h b/arch/arm/mach-tegra/include/mach/irammap.h
new file mode 100644 (file)
index 0000000..0cbe632
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MACH_TEGRA_IRAMMAP_H
+#define __MACH_TEGRA_IRAMMAP_H
+
+#include <asm/sizes.h>
+
+/* The first 1K of IRAM is permanently reserved for the CPU reset handler */
+#define TEGRA_IRAM_RESET_HANDLER_OFFSET        0
+#define TEGRA_IRAM_RESET_HANDLER_SIZE  SZ_1K
+
+/*
+ * These locations are written to by uncompress.h, and read by debug-macro.S.
+ * The first word holds the cookie value if the data is valid. The second
+ * word holds the UART physical address.
+ */
+#define TEGRA_IRAM_DEBUG_UART_OFFSET   SZ_1K
+#define TEGRA_IRAM_DEBUG_UART_SIZE     8
+#define TEGRA_IRAM_DEBUG_UART_COOKIE   0x55415254
+
+#endif
index a2146cd6867dc2656791451fbef49fef6992b935..aad1a2c1d714520984c25a55ebd4b6727aef4f33 100644 (file)
 #define INT_QUAD_RES_30                        (INT_QUAD_BASE + 30)
 #define INT_QUAD_RES_31                        (INT_QUAD_BASE + 31)
 
-#define INT_MAIN_NR                    (INT_QUAD_BASE + 32 - INT_PRI_BASE)
-
+/* Tegra30 has 5 banks of 32 IRQs */
+#define INT_MAIN_NR                    (32 * 5)
 #define INT_GPIO_BASE                  (INT_PRI_BASE + INT_MAIN_NR)
 
-#define INT_GPIO_NR                    (28 * 8)
+/* Tegra30 has 8 banks of 32 GPIOs */
+#define INT_GPIO_NR                    (32 * 8)
 
 #define TEGRA_NR_IRQS                  (INT_GPIO_BASE + INT_GPIO_NR)
 
index 39c396d2ddb07fca100c2716abbde072f96793a4..4752b1a68f35503a80ce58703d03dadf897561bb 100644 (file)
 #define TEGRA_POWERGATE_VDEC   4
 #define TEGRA_POWERGATE_L2     5
 #define TEGRA_POWERGATE_MPE    6
-#define TEGRA_NUM_POWERGATE    7
+#define TEGRA_POWERGATE_HEG    7
+#define TEGRA_POWERGATE_SATA   8
+#define TEGRA_POWERGATE_CPU1   9
+#define TEGRA_POWERGATE_CPU2   10
+#define TEGRA_POWERGATE_CPU3   11
+#define TEGRA_POWERGATE_CELP   12
+#define TEGRA_POWERGATE_3D1    13
 
+#define TEGRA_POWERGATE_CPU0   TEGRA_POWERGATE_CPU
+#define TEGRA_POWERGATE_3D0    TEGRA_POWERGATE_3D
+
+int  __init tegra_powergate_init(void);
+
+int tegra_cpu_powergate_id(int cpuid);
+int tegra_powergate_is_powered(int id);
 int tegra_powergate_power_on(int id);
 int tegra_powergate_power_off(int id);
 int tegra_powergate_remove_clamping(int id);
index 4e8323770c79770b21f24f9dc1228a0186973a3c..5a440f315e575d29c43958fd1c84226843056447 100644 (file)
@@ -2,10 +2,14 @@
  * arch/arm/mach-tegra/include/mach/uncompress.h
  *
  * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved.
  *
  * Author:
  *     Colin Cross <ccross@google.com>
  *     Erik Gilling <konkers@google.com>
+ *     Doug Anderson <dianders@chromium.org>
+ *     Stephen Warren <swarren@nvidia.com>
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
 #include <linux/serial_reg.h>
 
 #include <mach/iomap.h>
+#include <mach/irammap.h>
+
+#define BIT(x) (1 << (x))
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+#define DEBUG_UART_SHIFT 2
+
+volatile u8 *uart;
 
 static void putc(int c)
 {
-       volatile u8 *uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE;
-       int shift = 2;
-
        if (uart == NULL)
                return;
 
-       while (!(uart[UART_LSR << shift] & UART_LSR_THRE))
+       while (!(uart[UART_LSR << DEBUG_UART_SHIFT] & UART_LSR_THRE))
                barrier();
-       uart[UART_TX << shift] = c;
+       uart[UART_TX << DEBUG_UART_SHIFT] = c;
 }
 
 static inline void flush(void)
 {
 }
 
+static inline void save_uart_address(void)
+{
+       u32 *buf = (u32 *)(TEGRA_IRAM_BASE + TEGRA_IRAM_DEBUG_UART_OFFSET);
+
+       if (uart) {
+               buf[0] = TEGRA_IRAM_DEBUG_UART_COOKIE;
+               buf[1] = (u32)uart;
+       } else
+               buf[0] = 0;
+}
+
+/*
+ * Setup before decompression.  This is where we do UART selection for
+ * earlyprintk and init the uart_base register.
+ */
 static inline void arch_decomp_setup(void)
 {
-       volatile u8 *uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE;
-       int shift = 2;
+       static const struct {
+               u32 base;
+               u32 reset_reg;
+               u32 clock_reg;
+               u32 bit;
+       } uarts[] = {
+               {
+                       TEGRA_UARTA_BASE,
+                       TEGRA_CLK_RESET_BASE + 0x04,
+                       TEGRA_CLK_RESET_BASE + 0x10,
+                       6,
+               },
+               {
+                       TEGRA_UARTB_BASE,
+                       TEGRA_CLK_RESET_BASE + 0x04,
+                       TEGRA_CLK_RESET_BASE + 0x10,
+                       7,
+               },
+               {
+                       TEGRA_UARTC_BASE,
+                       TEGRA_CLK_RESET_BASE + 0x08,
+                       TEGRA_CLK_RESET_BASE + 0x14,
+                       23,
+               },
+               {
+                       TEGRA_UARTD_BASE,
+                       TEGRA_CLK_RESET_BASE + 0x0c,
+                       TEGRA_CLK_RESET_BASE + 0x18,
+                       1,
+               },
+               {
+                       TEGRA_UARTE_BASE,
+                       TEGRA_CLK_RESET_BASE + 0x0c,
+                       TEGRA_CLK_RESET_BASE + 0x18,
+                       2,
+               },
+       };
+       int i;
+       volatile u32 *apb_misc = (volatile u32 *)TEGRA_APB_MISC_BASE;
+       u32 chip, div;
+
+       /*
+        * Look for the first UART that:
+        * a) Is not in reset.
+        * b) Is clocked.
+        * c) Has a 'D' in the scratchpad register.
+        *
+        * Note that on Tegra30, the first two conditions are required, since
+        * if not true, accesses to the UART scratch register will hang.
+        * Tegra20 doesn't have this issue.
+        *
+        * The intent is that the bootloader will tell the kernel which UART
+        * to use by setting up those conditions. If nothing found, we'll fall
+        * back to what's specified in TEGRA_DEBUG_UART_BASE.
+        */
+       for (i = 0; i < ARRAY_SIZE(uarts); i++) {
+               if (*(u8 *)uarts[i].reset_reg & BIT(uarts[i].bit))
+                       continue;
 
+               if (!(*(u8 *)uarts[i].clock_reg & BIT(uarts[i].bit)))
+                       continue;
+
+               uart = (volatile u8 *)uarts[i].base;
+               if (uart[UART_SCR << DEBUG_UART_SHIFT] != 'D')
+                       continue;
+
+               break;
+       }
+       if (i == ARRAY_SIZE(uarts))
+               uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE;
+       save_uart_address();
        if (uart == NULL)
                return;
 
-       uart[UART_LCR << shift] |= UART_LCR_DLAB;
-       uart[UART_DLL << shift] = 0x75;
-       uart[UART_DLM << shift] = 0x0;
-       uart[UART_LCR << shift] = 3;
+       chip = (apb_misc[0x804 / 4] >> 8) & 0xff;
+       if (chip == 0x20)
+               div = 0x0075;
+       else
+               div = 0x00dd;
+
+       uart[UART_LCR << DEBUG_UART_SHIFT] |= UART_LCR_DLAB;
+       uart[UART_DLL << DEBUG_UART_SHIFT] = div & 0xff;
+       uart[UART_DLM << DEBUG_UART_SHIFT] = div >> 8;
+       uart[UART_LCR << DEBUG_UART_SHIFT] = 3;
 }
 
 static inline void arch_decomp_wdog(void)
index 4e1afcd54faedd71ffb04276d78c9f025bc4b407..2f5bd2db8e1faa78a69cedd1bfdc144bec47b615 100644 (file)
 #define ICTLR_COP_IER_CLR      0x38
 #define ICTLR_COP_IEP_CLASS    0x3c
 
-#define NUM_ICTLRS 4
 #define FIRST_LEGACY_IRQ 32
 
+static int num_ictlrs;
+
 static void __iomem *ictlr_reg_base[] = {
        IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE),
        IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE),
        IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE),
        IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE),
+       IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE),
 };
 
 static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)
@@ -60,7 +62,7 @@ static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)
        u32 mask;
 
        BUG_ON(irq < FIRST_LEGACY_IRQ ||
-               irq >= FIRST_LEGACY_IRQ + NUM_ICTLRS * 32);
+               irq >= FIRST_LEGACY_IRQ + num_ictlrs * 32);
 
        base = ictlr_reg_base[(irq - FIRST_LEGACY_IRQ) / 32];
        mask = BIT((irq - FIRST_LEGACY_IRQ) % 32);
@@ -113,8 +115,18 @@ static int tegra_retrigger(struct irq_data *d)
 void __init tegra_init_irq(void)
 {
        int i;
+       void __iomem *distbase;
+
+       distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
+       num_ictlrs = readl_relaxed(distbase + GIC_DIST_CTR) & 0x1f;
+
+       if (num_ictlrs > ARRAY_SIZE(ictlr_reg_base)) {
+               WARN(1, "Too many (%d) interrupt controllers found. Maximum is %d.",
+                       num_ictlrs, ARRAY_SIZE(ictlr_reg_base));
+               num_ictlrs = ARRAY_SIZE(ictlr_reg_base);
+       }
 
-       for (i = 0; i < NUM_ICTLRS; i++) {
+       for (i = 0; i < num_ictlrs; i++) {
                void __iomem *ictlr = ictlr_reg_base[i];
                writel(~0, ictlr + ICTLR_CPU_IER_CLR);
                writel(0, ictlr + ICTLR_CPU_IEP_CLASS);
@@ -131,6 +143,6 @@ void __init tegra_init_irq(void)
         * initialized elsewhere under DT.
         */
        if (!of_have_populated_dt())
-               gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE),
+               gic_init(0, 29, distbase,
                        IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
 }
diff --git a/arch/arm/mach-tegra/localtimer.c b/arch/arm/mach-tegra/localtimer.c
deleted file mode 100644 (file)
index e91d681..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- *  arch/arm/mach-tegra/localtimer.c
- *
- *  Copyright (C) 2002 ARM Ltd.
- *  All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/clockchips.h>
-#include <asm/irq.h>
-#include <asm/smp_twd.h>
-#include <asm/localtimer.h>
-
-/*
- * Setup the local clock events for a CPU.
- */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-       evt->irq = IRQ_LOCALTIMER;
-       twd_timer_setup(evt);
-       return 0;
-}
index 14b29ab5d8f0d006ae4230088d9071b9ad41d234..54a816ff3847d9c128d70735a5b875a1a96b1819 100644 (file)
@@ -585,10 +585,10 @@ static void tegra_pcie_setup_translations(void)
        afi_writel(0, AFI_MSI_BAR_SZ);
 }
 
-static void tegra_pcie_enable_controller(void)
+static int tegra_pcie_enable_controller(void)
 {
        u32 val, reg;
-       int i;
+       int i, timeout;
 
        /* Enable slot clock and pulse the reset signals */
        for (i = 0, reg = AFI_PEX0_CTRL; i < 2; i++, reg += 0x8) {
@@ -639,8 +639,14 @@ static void tegra_pcie_enable_controller(void)
        pads_writel(0xfa5cfa5c, 0xc8);
 
        /* Wait for the PLL to lock */
+       timeout = 300;
        do {
                val = pads_readl(PADS_PLL_CTL);
+               usleep_range(1000, 1000);
+               if (--timeout == 0) {
+                       pr_err("Tegra PCIe error: timeout waiting for PLL\n");
+                       return -EBUSY;
+               }
        } while (!(val & PADS_PLL_CTL_LOCKDET));
 
        /* turn off IDDQ override */
@@ -671,7 +677,7 @@ static void tegra_pcie_enable_controller(void)
        /* Disable all execptions */
        afi_writel(0, AFI_FPCI_ERROR_MASKS);
 
-       return;
+       return 0;
 }
 
 static void tegra_pcie_xclk_clamp(bool clamp)
@@ -921,7 +927,9 @@ int __init tegra_pcie_init(bool init_port0, bool init_port1)
        if (err)
                return err;
 
-       tegra_pcie_enable_controller();
+       err = tegra_pcie_enable_controller();
+       if (err)
+               return err;
 
        /* setup the AFI address translations */
        tegra_pcie_setup_translations();
index 7d2b5d03c1dff6385ec08125e4ffa9d12f2cf8fd..1a208dbf682f95ee8359c1cbf3d1e70aae314ff6 100644 (file)
 #include <asm/mach-types.h>
 #include <asm/smp_scu.h>
 
+#include <mach/clk.h>
 #include <mach/iomap.h>
+#include <mach/powergate.h>
+
+#include "fuse.h"
+#include "flowctrl.h"
+#include "reset.h"
 
 extern void tegra_secondary_startup(void);
 
-static DEFINE_SPINLOCK(boot_lock);
 static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
 
 #define EVP_CPU_RESET_VECTOR \
        (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
 #define CLK_RST_CONTROLLER_CLK_CPU_CMPLX \
        (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x4c)
+#define CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET \
+       (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x340)
 #define CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR \
        (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x344)
+#define CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR \
+       (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x34c)
+
+#define CPU_CLOCK(cpu) (0x1<<(8+cpu))
+#define CPU_RESET(cpu) (0x1111ul<<(cpu))
 
 void __cpuinit platform_secondary_init(unsigned int cpu)
 {
@@ -47,63 +59,106 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
         */
        gic_secondary_init(0);
 
-       /*
-        * Synchronise with the boot thread.
-        */
-       spin_lock(&boot_lock);
-       spin_unlock(&boot_lock);
 }
 
-int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int tegra20_power_up_cpu(unsigned int cpu)
 {
-       unsigned long old_boot_vector;
-       unsigned long boot_vector;
-       unsigned long timeout;
        u32 reg;
 
-       /*
-        * set synchronisation state between this boot processor
-        * and the secondary one
-        */
-       spin_lock(&boot_lock);
+       /* Enable the CPU clock. */
+       reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
+       writel(reg & ~CPU_CLOCK(cpu), CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
+       barrier();
+       reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
 
+       /* Clear flow controller CSR. */
+       flowctrl_write_cpu_csr(cpu, 0);
 
-       /* set the reset vector to point to the secondary_startup routine */
+       return 0;
+}
 
-       boot_vector = virt_to_phys(tegra_secondary_startup);
-       old_boot_vector = readl(EVP_CPU_RESET_VECTOR);
-       writel(boot_vector, EVP_CPU_RESET_VECTOR);
+static int tegra30_power_up_cpu(unsigned int cpu)
+{
+       u32 reg;
+       int ret, pwrgateid;
+       unsigned long timeout;
 
-       /* enable cpu clock on cpu1 */
-       reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
-       writel(reg & ~(1<<9), CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
+       pwrgateid = tegra_cpu_powergate_id(cpu);
+       if (pwrgateid < 0)
+               return pwrgateid;
+
+       /* If this is the first boot, toggle powergates directly. */
+       if (!tegra_powergate_is_powered(pwrgateid)) {
+               ret = tegra_powergate_power_on(pwrgateid);
+               if (ret)
+                       return ret;
+
+               /* Wait for the power to come up. */
+               timeout = jiffies + 10*HZ;
+               while (tegra_powergate_is_powered(pwrgateid)) {
+                       if (time_after(jiffies, timeout))
+                               return -ETIMEDOUT;
+                       udelay(10);
+               }
+       }
 
-       reg = (1<<13) | (1<<9) | (1<<5) | (1<<1);
-       writel(reg, CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR);
+       /* CPU partition is powered. Enable the CPU clock. */
+       writel(CPU_CLOCK(cpu), CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR);
+       reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR);
+       udelay(10);
 
-       smp_wmb();
-       flush_cache_all();
+       /* Remove I/O clamps. */
+       ret = tegra_powergate_remove_clamping(pwrgateid);
+       udelay(10);
 
-       /* unhalt the cpu */
-       writel(0, IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + 0x14);
+       /* Clear flow controller CSR. */
+       flowctrl_write_cpu_csr(cpu, 0);
 
-       timeout = jiffies + (1 * HZ);
-       while (time_before(jiffies, timeout)) {
-               if (readl(EVP_CPU_RESET_VECTOR) != boot_vector)
-                       break;
-               udelay(10);
-       }
+       return 0;
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       int status;
 
-       /* put the old boot vector back */
-       writel(old_boot_vector, EVP_CPU_RESET_VECTOR);
+       /*
+        * Force the CPU into reset. The CPU must remain in reset when the
+        * flow controller state is cleared (which will cause the flow
+        * controller to stop driving reset if the CPU has been power-gated
+        * via the flow controller). This will have no effect on first boot
+        * of the CPU since it should already be in reset.
+        */
+       writel(CPU_RESET(cpu), CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET);
+       dmb();
 
        /*
-        * now the secondary core is starting up let it run its
-        * calibrations, then wait for it to finish
+        * Unhalt the CPU. If the flow controller was used to power-gate the
+        * CPU this will cause the flow controller to stop driving reset.
+        * The CPU will remain in reset because the clock and reset block
+        * is now driving reset.
         */
-       spin_unlock(&boot_lock);
+       flowctrl_write_cpu_halt(cpu, 0);
+
+       switch (tegra_chip_id) {
+       case TEGRA20:
+               status = tegra20_power_up_cpu(cpu);
+               break;
+       case TEGRA30:
+               status = tegra30_power_up_cpu(cpu);
+               break;
+       default:
+               status = -EINVAL;
+               break;
+       }
 
-       return 0;
+       if (status)
+               goto done;
+
+       /* Take the CPU out of reset. */
+       writel(CPU_RESET(cpu), CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR);
+       wmb();
+done:
+       return status;
 }
 
 /*
@@ -128,6 +183,6 @@ void __init smp_init_cpus(void)
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 {
-
+       tegra_cpu_reset_handler_init();
        scu_enable(scu_base);
 }
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
new file mode 100644 (file)
index 0000000..7af6a54
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include <mach/iomap.h>
+
+#define PMC_CTRL               0x0
+#define PMC_CTRL_INTR_LOW      (1 << 17)
+
+static inline u32 tegra_pmc_readl(u32 reg)
+{
+       return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg));
+}
+
+static inline void tegra_pmc_writel(u32 val, u32 reg)
+{
+       writel(val, IO_ADDRESS(TEGRA_PMC_BASE + reg));
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id matches[] __initconst = {
+       { .compatible = "nvidia,tegra20-pmc" },
+       { }
+};
+#endif
+
+void __init tegra_pmc_init(void)
+{
+       /*
+        * For now, Harmony is the only board that uses the PMC, and it wants
+        * the signal inverted. Seaboard would too if it used the PMC.
+        * Hopefully by the time other boards want to use the PMC, everything
+        * will be device-tree, or they also want it inverted.
+        */
+       bool invert_interrupt = true;
+       u32 val;
+
+#ifdef CONFIG_OF
+       if (of_have_populated_dt()) {
+               struct device_node *np;
+
+               invert_interrupt = false;
+
+               np = of_find_matching_node(NULL, matches);
+               if (np) {
+                       if (of_find_property(np, "nvidia,invert-interrupt",
+                                               NULL))
+                               invert_interrupt = true;
+               }
+       }
+#endif
+
+       val = tegra_pmc_readl(PMC_CTRL);
+       if (invert_interrupt)
+               val |= PMC_CTRL_INTR_LOW;
+       else
+               val &= ~PMC_CTRL_INTR_LOW;
+       tegra_pmc_writel(val, PMC_CTRL);
+}
diff --git a/arch/arm/mach-tegra/pmc.h b/arch/arm/mach-tegra/pmc.h
new file mode 100644 (file)
index 0000000..8995ee4
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __MACH_TEGRA_PMC_H
+#define __MACH_TEGRA_PMC_H
+
+void tegra_pmc_init(void);
+
+#endif
index 948306491a59ef405dfbfa348f7199eb8327c13a..c238699ae86f5021defde301911bcde0c0696a0f 100644 (file)
@@ -31,6 +31,8 @@
 #include <mach/iomap.h>
 #include <mach/powergate.h>
 
+#include "fuse.h"
+
 #define PWRGATE_TOGGLE         0x30
 #define  PWRGATE_TOGGLE_START  (1 << 8)
 
 
 #define PWRGATE_STATUS         0x38
 
+static int tegra_num_powerdomains;
+static int tegra_num_cpu_domains;
+static u8 *tegra_cpu_domains;
+static u8 tegra30_cpu_domains[] = {
+       TEGRA_POWERGATE_CPU0,
+       TEGRA_POWERGATE_CPU1,
+       TEGRA_POWERGATE_CPU2,
+       TEGRA_POWERGATE_CPU3,
+};
+
 static DEFINE_SPINLOCK(tegra_powergate_lock);
 
 static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
@@ -75,7 +87,7 @@ static int tegra_powergate_set(int id, bool new_state)
 
 int tegra_powergate_power_on(int id)
 {
-       if (id < 0 || id >= TEGRA_NUM_POWERGATE)
+       if (id < 0 || id >= tegra_num_powerdomains)
                return -EINVAL;
 
        return tegra_powergate_set(id, true);
@@ -83,17 +95,18 @@ int tegra_powergate_power_on(int id)
 
 int tegra_powergate_power_off(int id)
 {
-       if (id < 0 || id >= TEGRA_NUM_POWERGATE)
+       if (id < 0 || id >= tegra_num_powerdomains)
                return -EINVAL;
 
        return tegra_powergate_set(id, false);
 }
 
-static bool tegra_powergate_is_powered(int id)
+int tegra_powergate_is_powered(int id)
 {
        u32 status;
 
-       WARN_ON(id < 0 || id >= TEGRA_NUM_POWERGATE);
+       if (id < 0 || id >= tegra_num_powerdomains)
+               return -EINVAL;
 
        status = pmc_read(PWRGATE_STATUS) & (1 << id);
        return !!status;
@@ -103,7 +116,7 @@ int tegra_powergate_remove_clamping(int id)
 {
        u32 mask;
 
-       if (id < 0 || id >= TEGRA_NUM_POWERGATE)
+       if (id < 0 || id >= tegra_num_powerdomains)
                return -EINVAL;
 
        /*
@@ -156,6 +169,34 @@ err_power:
        return ret;
 }
 
+int tegra_cpu_powergate_id(int cpuid)
+{
+       if (cpuid > 0 && cpuid < tegra_num_cpu_domains)
+               return tegra_cpu_domains[cpuid];
+
+       return -EINVAL;
+}
+
+int __init tegra_powergate_init(void)
+{
+       switch (tegra_chip_id) {
+       case TEGRA20:
+               tegra_num_powerdomains = 7;
+               break;
+       case TEGRA30:
+               tegra_num_powerdomains = 14;
+               tegra_num_cpu_domains = 4;
+               tegra_cpu_domains = tegra30_cpu_domains;
+               break;
+       default:
+               /* Unknown Tegra variant. Disable powergating */
+               tegra_num_powerdomains = 0;
+               break;
+       }
+
+       return 0;
+}
+
 #ifdef CONFIG_DEBUG_FS
 
 static const char * const powergate_name[] = {
@@ -175,7 +216,7 @@ static int powergate_show(struct seq_file *s, void *data)
        seq_printf(s, " powergate powered\n");
        seq_printf(s, "------------------\n");
 
-       for (i = 0; i < TEGRA_NUM_POWERGATE; i++)
+       for (i = 0; i < tegra_num_powerdomains; i++)
                seq_printf(s, " %9s %7s\n", powergate_name[i],
                        tegra_powergate_is_powered(i) ? "yes" : "no");
        return 0;
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
new file mode 100644 (file)
index 0000000..4d6a2ee
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * arch/arm/mach-tegra/reset.c
+ *
+ * Copyright (C) 2011,2012 NVIDIA Corporation.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/cpumask.h>
+#include <linux/bitops.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include <mach/iomap.h>
+#include <mach/irammap.h>
+
+#include "reset.h"
+#include "fuse.h"
+
+#define TEGRA_IRAM_RESET_BASE (TEGRA_IRAM_BASE + \
+                               TEGRA_IRAM_RESET_HANDLER_OFFSET)
+
+static bool is_enabled;
+
+static void tegra_cpu_reset_handler_enable(void)
+{
+       void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE);
+       void __iomem *evp_cpu_reset =
+               IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE + 0x100);
+       void __iomem *sb_ctrl = IO_ADDRESS(TEGRA_SB_BASE);
+       u32 reg;
+
+       BUG_ON(is_enabled);
+       BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE);
+
+       memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start,
+                       tegra_cpu_reset_handler_size);
+
+       /*
+        * NOTE: This must be the one and only write to the EVP CPU reset
+        *       vector in the entire system.
+        */
+       writel(TEGRA_IRAM_RESET_BASE + tegra_cpu_reset_handler_offset,
+                       evp_cpu_reset);
+       wmb();
+       reg = readl(evp_cpu_reset);
+
+       /*
+        * Prevent further modifications to the physical reset vector.
+        *  NOTE: Has no effect on chips prior to Tegra30.
+        */
+       if (tegra_chip_id != TEGRA20) {
+               reg = readl(sb_ctrl);
+               reg |= 2;
+               writel(reg, sb_ctrl);
+               wmb();
+       }
+
+       is_enabled = true;
+}
+
+void __init tegra_cpu_reset_handler_init(void)
+{
+
+#ifdef CONFIG_SMP
+       __tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_PRESENT] =
+               *((u32 *)cpu_present_mask);
+       __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_SECONDARY] =
+               virt_to_phys((void *)tegra_secondary_startup);
+#endif
+
+       tegra_cpu_reset_handler_enable();
+}
diff --git a/arch/arm/mach-tegra/reset.h b/arch/arm/mach-tegra/reset.h
new file mode 100644 (file)
index 0000000..de88bf8
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * arch/arm/mach-tegra/reset.h
+ *
+ * CPU reset dispatcher.
+ *
+ * Copyright (c) 2011, NVIDIA Corporation.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_RESET_H
+#define __MACH_TEGRA_RESET_H
+
+#define TEGRA_RESET_MASK_PRESENT       0
+#define TEGRA_RESET_MASK_LP1           1
+#define TEGRA_RESET_MASK_LP2           2
+#define TEGRA_RESET_STARTUP_SECONDARY  3
+#define TEGRA_RESET_STARTUP_LP2                4
+#define TEGRA_RESET_STARTUP_LP1                5
+#define TEGRA_RESET_DATA_SIZE          6
+
+#ifndef __ASSEMBLY__
+
+extern unsigned long __tegra_cpu_reset_handler_data[TEGRA_RESET_DATA_SIZE];
+
+void __tegra_cpu_reset_handler_start(void);
+void __tegra_cpu_reset_handler(void);
+void __tegra_cpu_reset_handler_end(void);
+void tegra_secondary_startup(void);
+
+#define tegra_cpu_reset_handler_offset \
+               ((u32)__tegra_cpu_reset_handler - \
+                (u32)__tegra_cpu_reset_handler_start)
+
+#define tegra_cpu_reset_handler_size \
+               (__tegra_cpu_reset_handler_end - \
+                __tegra_cpu_reset_handler_start)
+
+void __init tegra_cpu_reset_handler_init(void);
+
+#endif
+#endif
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S
new file mode 100644 (file)
index 0000000..8f9fde1
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * arch/arm/mach-tegra/sleep.S
+ *
+ * Copyright (c) 2010-2011, NVIDIA Corporation.
+ * Copyright (c) 2011, Google, Inc.
+ *
+ * Author: Colin Cross <ccross@android.com>
+ *         Gary King <gking@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <linux/linkage.h>
+#include <mach/io.h>
+#include <mach/iomap.h>
+
+#include "flowctrl.h"
+
+#define TEGRA_FLOW_CTRL_VIRT (TEGRA_FLOW_CTRL_BASE - IO_PPSB_PHYS \
+                                       + IO_PPSB_VIRT)
+
+/* returns the offset of the flow controller halt register for a cpu */
+.macro cpu_to_halt_reg rd, rcpu
+       cmp     \rcpu, #0
+       subne   \rd, \rcpu, #1
+       movne   \rd, \rd, lsl #3
+       addne   \rd, \rd, #0x14
+       moveq   \rd, #0
+.endm
+
+/* returns the offset of the flow controller csr register for a cpu */
+.macro cpu_to_csr_reg rd, rcpu
+       cmp     \rcpu, #0
+       subne   \rd, \rcpu, #1
+       movne   \rd, \rd, lsl #3
+       addne   \rd, \rd, #0x18
+       moveq   \rd, #8
+.endm
+
+/* returns the ID of the current processor */
+.macro cpu_id, rd
+       mrc     p15, 0, \rd, c0, c0, 5
+       and     \rd, \rd, #0xF
+.endm
+
+/* loads a 32-bit value into a register without a data access */
+.macro mov32, reg, val
+       movw    \reg, #:lower16:\val
+       movt    \reg, #:upper16:\val
+.endm
+
+/*
+ * tegra_cpu_wfi
+ *
+ * puts current CPU in clock-gated wfi using the flow controller
+ *
+ * corrupts r0-r3
+ * must be called with MMU on
+ */
+
+ENTRY(tegra_cpu_wfi)
+       cpu_id  r0
+       cpu_to_halt_reg r1, r0
+       cpu_to_csr_reg r2, r0
+       mov32   r0, TEGRA_FLOW_CTRL_VIRT
+       mov     r3, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
+       str     r3, [r0, r2]    @ clear event & interrupt status
+       mov     r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT | FLOW_CTRL_JTAG_RESUME
+       str     r3, [r0, r1]    @ put flow controller in wait irq mode
+       dsb
+       wfi
+       mov     r3, #0
+       str     r3, [r0, r1]    @ clear flow controller halt status
+       mov     r3, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
+       str     r3, [r0, r2]    @ clear event & interrupt status
+       dsb
+       mov     pc, lr
+ENDPROC(tegra_cpu_wfi)
+
index ff9e6b6c046077012214778426a944a42db9806f..592a4eeb5328c6fa70f29dde7f53ba530995c488 100644 (file)
@@ -720,7 +720,7 @@ static void tegra2_pllx_clk_init(struct clk *c)
 {
        tegra2_pll_clk_init(c);
 
-       if (tegra_sku_id() == 7)
+       if (tegra_sku_id == 7)
                c->max_rate = 750000000;
 }
 
@@ -1143,15 +1143,35 @@ static void tegra2_emc_clk_init(struct clk *c)
 
 static long tegra2_emc_clk_round_rate(struct clk *c, unsigned long rate)
 {
-       long new_rate = rate;
+       long emc_rate;
+       long clk_rate;
 
-       new_rate = tegra_emc_round_rate(new_rate);
-       if (new_rate < 0)
+       /*
+        * The slowest entry in the EMC clock table that is at least as
+        * fast as rate.
+        */
+       emc_rate = tegra_emc_round_rate(rate);
+       if (emc_rate < 0)
                return c->max_rate;
 
-       BUG_ON(new_rate != tegra2_periph_clk_round_rate(c, new_rate));
+       /*
+        * The fastest rate the PLL will generate that is at most the
+        * requested rate.
+        */
+       clk_rate = tegra2_periph_clk_round_rate(c, emc_rate);
+
+       /*
+        * If this fails, and emc_rate > clk_rate, it's because the maximum
+        * rate in the EMC tables is larger than the maximum rate of the EMC
+        * clock. The EMC clock's max rate is the rate it was running when the
+        * kernel booted. Such a mismatch is probably due to using the wrong
+        * BCT, i.e. using a Tegra20 BCT with an EMC table written for Tegra25.
+        */
+       WARN_ONCE(emc_rate != clk_rate,
+               "emc_rate %ld != clk_rate %ld",
+               emc_rate, clk_rate);
 
-       return new_rate;
+       return emc_rate;
 }
 
 static int tegra2_emc_clk_set_rate(struct clk *c, unsigned long rate)
index 0f7ae6e90b5590c43d1e4c6f3de4ab8ffeda40aa..5070d833bdd1ebbf3df1763353f155e66b97d04a 100644 (file)
  */
 
 #include <linux/kernel.h>
+#include <linux/device.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/tegra_emc.h>
 
 #include <mach/iomap.h>
 
 #include "tegra2_emc.h"
+#include "fuse.h"
 
 #ifdef CONFIG_TEGRA_EMC_SCALING_ENABLE
 static bool emc_enable = true;
@@ -32,18 +37,17 @@ static bool emc_enable;
 #endif
 module_param(emc_enable, bool, 0644);
 
-static void __iomem *emc = IO_ADDRESS(TEGRA_EMC_BASE);
-static const struct tegra_emc_table *tegra_emc_table;
-static int tegra_emc_table_size;
+static struct platform_device *emc_pdev;
+static void __iomem *emc_regbase;
 
 static inline void emc_writel(u32 val, unsigned long addr)
 {
-       writel(val, emc + addr);
+       writel(val, emc_regbase + addr);
 }
 
 static inline u32 emc_readl(unsigned long addr)
 {
-       return readl(emc + addr);
+       return readl(emc_regbase + addr);
 }
 
 static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
@@ -98,15 +102,15 @@ static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
 /* Select the closest EMC rate that is higher than the requested rate */
 long tegra_emc_round_rate(unsigned long rate)
 {
+       struct tegra_emc_pdata *pdata;
        int i;
        int best = -1;
        unsigned long distance = ULONG_MAX;
 
-       if (!tegra_emc_table)
+       if (!emc_pdev)
                return -EINVAL;
 
-       if (!emc_enable)
-               return -EINVAL;
+       pdata = emc_pdev->dev.platform_data;
 
        pr_debug("%s: %lu\n", __func__, rate);
 
@@ -116,10 +120,10 @@ long tegra_emc_round_rate(unsigned long rate)
         */
        rate = rate / 2 / 1000;
 
-       for (i = 0; i < tegra_emc_table_size; i++) {
-               if (tegra_emc_table[i].rate >= rate &&
-                   (tegra_emc_table[i].rate - rate) < distance) {
-                       distance = tegra_emc_table[i].rate - rate;
+       for (i = 0; i < pdata->num_tables; i++) {
+               if (pdata->tables[i].rate >= rate &&
+                   (pdata->tables[i].rate - rate) < distance) {
+                       distance = pdata->tables[i].rate - rate;
                        best = i;
                }
        }
@@ -127,9 +131,9 @@ long tegra_emc_round_rate(unsigned long rate)
        if (best < 0)
                return -EINVAL;
 
-       pr_debug("%s: using %lu\n", __func__, tegra_emc_table[best].rate);
+       pr_debug("%s: using %lu\n", __func__, pdata->tables[best].rate);
 
-       return tegra_emc_table[best].rate * 2 * 1000;
+       return pdata->tables[best].rate * 2 * 1000;
 }
 
 /*
@@ -142,37 +146,211 @@ long tegra_emc_round_rate(unsigned long rate)
  */
 int tegra_emc_set_rate(unsigned long rate)
 {
+       struct tegra_emc_pdata *pdata;
        int i;
        int j;
 
-       if (!tegra_emc_table)
+       if (!emc_pdev)
                return -EINVAL;
 
+       pdata = emc_pdev->dev.platform_data;
+
        /*
         * The EMC clock rate is twice the bus rate, and the bus rate is
         * measured in kHz
         */
        rate = rate / 2 / 1000;
 
-       for (i = 0; i < tegra_emc_table_size; i++)
-               if (tegra_emc_table[i].rate == rate)
+       for (i = 0; i < pdata->num_tables; i++)
+               if (pdata->tables[i].rate == rate)
                        break;
 
-       if (i >= tegra_emc_table_size)
+       if (i >= pdata->num_tables)
                return -EINVAL;
 
        pr_debug("%s: setting to %lu\n", __func__, rate);
 
        for (j = 0; j < TEGRA_EMC_NUM_REGS; j++)
-               emc_writel(tegra_emc_table[i].regs[j], emc_reg_addr[j]);
+               emc_writel(pdata->tables[i].regs[j], emc_reg_addr[j]);
 
-       emc_readl(tegra_emc_table[i].regs[TEGRA_EMC_NUM_REGS - 1]);
+       emc_readl(pdata->tables[i].regs[TEGRA_EMC_NUM_REGS - 1]);
 
        return 0;
 }
 
-void tegra_init_emc(const struct tegra_emc_table *table, int table_size)
+#ifdef CONFIG_OF
+static struct device_node *tegra_emc_ramcode_devnode(struct device_node *np)
+{
+       struct device_node *iter;
+       u32 reg;
+
+       for_each_child_of_node(np, iter) {
+               if (of_property_read_u32(np, "nvidia,ram-code", &reg))
+                       continue;
+               if (reg == tegra_bct_strapping)
+                       return of_node_get(iter);
+       }
+
+       return NULL;
+}
+
+static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata(
+               struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       struct device_node *tnp, *iter;
+       struct tegra_emc_pdata *pdata;
+       int ret, i, num_tables;
+
+       if (!np)
+               return NULL;
+
+       if (of_find_property(np, "nvidia,use-ram-code", NULL)) {
+               tnp = tegra_emc_ramcode_devnode(np);
+               if (!tnp)
+                       dev_warn(&pdev->dev,
+                                "can't find emc table for ram-code 0x%02x\n",
+                                tegra_bct_strapping);
+       } else
+               tnp = of_node_get(np);
+
+       if (!tnp)
+               return NULL;
+
+       num_tables = 0;
+       for_each_child_of_node(tnp, iter)
+               if (of_device_is_compatible(iter, "nvidia,tegra20-emc-table"))
+                       num_tables++;
+
+       if (!num_tables) {
+               pdata = NULL;
+               goto out;
+       }
+
+       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+       pdata->tables = devm_kzalloc(&pdev->dev,
+                                    sizeof(*pdata->tables) * num_tables,
+                                    GFP_KERNEL);
+
+       i = 0;
+       for_each_child_of_node(tnp, iter) {
+               u32 prop;
+
+               ret = of_property_read_u32(iter, "clock-frequency", &prop);
+               if (ret) {
+                       dev_err(&pdev->dev, "no clock-frequency in %s\n",
+                               iter->full_name);
+                       continue;
+               }
+               pdata->tables[i].rate = prop;
+
+               ret = of_property_read_u32_array(iter, "nvidia,emc-registers",
+                                                pdata->tables[i].regs,
+                                                TEGRA_EMC_NUM_REGS);
+               if (ret) {
+                       dev_err(&pdev->dev,
+                               "malformed emc-registers property in %s\n",
+                               iter->full_name);
+                       continue;
+               }
+
+               i++;
+       }
+       pdata->num_tables = i;
+
+out:
+       of_node_put(tnp);
+       return pdata;
+}
+#else
+static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata(
+               struct platform_device *pdev)
+{
+       return NULL;
+}
+#endif
+
+static struct tegra_emc_pdata __devinit *tegra_emc_fill_pdata(struct platform_device *pdev)
+{
+       struct clk *c = clk_get_sys(NULL, "emc");
+       struct tegra_emc_pdata *pdata;
+       unsigned long khz;
+       int i;
+
+       WARN_ON(pdev->dev.platform_data);
+       BUG_ON(IS_ERR_OR_NULL(c));
+
+       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+       pdata->tables = devm_kzalloc(&pdev->dev, sizeof(*pdata->tables),
+                                    GFP_KERNEL);
+
+       pdata->tables[0].rate = clk_get_rate(c) / 2 / 1000;
+
+       for (i = 0; i < TEGRA_EMC_NUM_REGS; i++)
+               pdata->tables[0].regs[i] = emc_readl(emc_reg_addr[i]);
+
+       pdata->num_tables = 1;
+
+       khz = pdata->tables[0].rate;
+       dev_info(&pdev->dev, "no tables provided, using %ld kHz emc, "
+                "%ld kHz mem\n", khz * 2, khz);
+
+       return pdata;
+}
+
+static int __devinit tegra_emc_probe(struct platform_device *pdev)
+{
+       struct tegra_emc_pdata *pdata;
+       struct resource *res;
+
+       if (!emc_enable) {
+               dev_err(&pdev->dev, "disabled per module parameter\n");
+               return -ENODEV;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "missing register base\n");
+               return -ENOMEM;
+       }
+
+       emc_regbase = devm_request_and_ioremap(&pdev->dev, res);
+       if (!emc_regbase) {
+               dev_err(&pdev->dev, "failed to remap registers\n");
+               return -ENOMEM;
+       }
+
+       pdata = pdev->dev.platform_data;
+
+       if (!pdata)
+               pdata = tegra_emc_dt_parse_pdata(pdev);
+
+       if (!pdata)
+               pdata = tegra_emc_fill_pdata(pdev);
+
+       pdev->dev.platform_data = pdata;
+
+       emc_pdev = pdev;
+
+       return 0;
+}
+
+static struct of_device_id tegra_emc_of_match[] __devinitdata = {
+       { .compatible = "nvidia,tegra20-emc", },
+       { },
+};
+
+static struct platform_driver tegra_emc_driver = {
+       .driver         = {
+               .name   = "tegra-emc",
+               .owner  = THIS_MODULE,
+               .of_match_table = tegra_emc_of_match,
+       },
+       .probe          = tegra_emc_probe,
+};
+
+static int __init tegra_emc_init(void)
 {
-       tegra_emc_table = table;
-       tegra_emc_table_size = table_size;
+       return platform_driver_register(&tegra_emc_driver);
 }
+device_initcall(tegra_emc_init);
index 19f08cb3160383e3a19f4cb9ce430536d6099750..f61409b54cb7084b956caa37def09c3f04083884 100644 (file)
  *
  */
 
-#define TEGRA_EMC_NUM_REGS 46
-
-struct tegra_emc_table {
-       unsigned long rate;
-       u32 regs[TEGRA_EMC_NUM_REGS];
-};
+#ifndef __MACH_TEGRA_TEGRA2_EMC_H_
+#define __MACH_TEGRA_TEGRA2_EMC_H
 
 int tegra_emc_set_rate(unsigned long rate);
 long tegra_emc_round_rate(unsigned long rate);
-void tegra_init_emc(const struct tegra_emc_table *table, int table_size);
+
+#endif
diff --git a/arch/arm/mach-tegra/tegra30_clocks.c b/arch/arm/mach-tegra/tegra30_clocks.c
new file mode 100644 (file)
index 0000000..6d08b53
--- /dev/null
@@ -0,0 +1,3099 @@
+/*
+ * arch/arm/mach-tegra/tegra30_clocks.c
+ *
+ * Copyright (c) 2010-2011 NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/syscore_ops.h>
+
+#include <asm/clkdev.h>
+
+#include <mach/iomap.h>
+
+#include "clock.h"
+#include "fuse.h"
+
+#define USE_PLL_LOCK_BITS 0
+
+#define RST_DEVICES_L                  0x004
+#define RST_DEVICES_H                  0x008
+#define RST_DEVICES_U                  0x00C
+#define RST_DEVICES_V                  0x358
+#define RST_DEVICES_W                  0x35C
+#define RST_DEVICES_SET_L              0x300
+#define RST_DEVICES_CLR_L              0x304
+#define RST_DEVICES_SET_V              0x430
+#define RST_DEVICES_CLR_V              0x434
+#define RST_DEVICES_NUM                        5
+
+#define CLK_OUT_ENB_L                  0x010
+#define CLK_OUT_ENB_H                  0x014
+#define CLK_OUT_ENB_U                  0x018
+#define CLK_OUT_ENB_V                  0x360
+#define CLK_OUT_ENB_W                  0x364
+#define CLK_OUT_ENB_SET_L              0x320
+#define CLK_OUT_ENB_CLR_L              0x324
+#define CLK_OUT_ENB_SET_V              0x440
+#define CLK_OUT_ENB_CLR_V              0x444
+#define CLK_OUT_ENB_NUM                        5
+
+#define RST_DEVICES_V_SWR_CPULP_RST_DIS        (0x1 << 1)
+#define CLK_OUT_ENB_V_CLK_ENB_CPULP_EN (0x1 << 1)
+
+#define PERIPH_CLK_TO_BIT(c)           (1 << (c->u.periph.clk_num % 32))
+#define PERIPH_CLK_TO_RST_REG(c)       \
+       periph_clk_to_reg((c), RST_DEVICES_L, RST_DEVICES_V, 4)
+#define PERIPH_CLK_TO_RST_SET_REG(c)   \
+       periph_clk_to_reg((c), RST_DEVICES_SET_L, RST_DEVICES_SET_V, 8)
+#define PERIPH_CLK_TO_RST_CLR_REG(c)   \
+       periph_clk_to_reg((c), RST_DEVICES_CLR_L, RST_DEVICES_CLR_V, 8)
+
+#define PERIPH_CLK_TO_ENB_REG(c)       \
+       periph_clk_to_reg((c), CLK_OUT_ENB_L, CLK_OUT_ENB_V, 4)
+#define PERIPH_CLK_TO_ENB_SET_REG(c)   \
+       periph_clk_to_reg((c), CLK_OUT_ENB_SET_L, CLK_OUT_ENB_SET_V, 8)
+#define PERIPH_CLK_TO_ENB_CLR_REG(c)   \
+       periph_clk_to_reg((c), CLK_OUT_ENB_CLR_L, CLK_OUT_ENB_CLR_V, 8)
+
+#define CLK_MASK_ARM                   0x44
+#define MISC_CLK_ENB                   0x48
+
+#define OSC_CTRL                       0x50
+#define OSC_CTRL_OSC_FREQ_MASK         (0xF<<28)
+#define OSC_CTRL_OSC_FREQ_13MHZ                (0x0<<28)
+#define OSC_CTRL_OSC_FREQ_19_2MHZ      (0x4<<28)
+#define OSC_CTRL_OSC_FREQ_12MHZ                (0x8<<28)
+#define OSC_CTRL_OSC_FREQ_26MHZ                (0xC<<28)
+#define OSC_CTRL_OSC_FREQ_16_8MHZ      (0x1<<28)
+#define OSC_CTRL_OSC_FREQ_38_4MHZ      (0x5<<28)
+#define OSC_CTRL_OSC_FREQ_48MHZ                (0x9<<28)
+#define OSC_CTRL_MASK                  (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
+
+#define OSC_CTRL_PLL_REF_DIV_MASK      (3<<26)
+#define OSC_CTRL_PLL_REF_DIV_1         (0<<26)
+#define OSC_CTRL_PLL_REF_DIV_2         (1<<26)
+#define OSC_CTRL_PLL_REF_DIV_4         (2<<26)
+
+#define OSC_FREQ_DET                   0x58
+#define OSC_FREQ_DET_TRIG              (1<<31)
+
+#define OSC_FREQ_DET_STATUS            0x5C
+#define OSC_FREQ_DET_BUSY              (1<<31)
+#define OSC_FREQ_DET_CNT_MASK          0xFFFF
+
+#define PERIPH_CLK_SOURCE_I2S1         0x100
+#define PERIPH_CLK_SOURCE_EMC          0x19c
+#define PERIPH_CLK_SOURCE_OSC          0x1fc
+#define PERIPH_CLK_SOURCE_NUM1 \
+       ((PERIPH_CLK_SOURCE_OSC - PERIPH_CLK_SOURCE_I2S1) / 4)
+
+#define PERIPH_CLK_SOURCE_G3D2         0x3b0
+#define PERIPH_CLK_SOURCE_SE           0x42c
+#define PERIPH_CLK_SOURCE_NUM2 \
+       ((PERIPH_CLK_SOURCE_SE - PERIPH_CLK_SOURCE_G3D2) / 4 + 1)
+
+#define AUDIO_DLY_CLK                  0x49c
+#define AUDIO_SYNC_CLK_SPDIF           0x4b4
+#define PERIPH_CLK_SOURCE_NUM3 \
+       ((AUDIO_SYNC_CLK_SPDIF - AUDIO_DLY_CLK) / 4 + 1)
+
+#define PERIPH_CLK_SOURCE_NUM          (PERIPH_CLK_SOURCE_NUM1 + \
+                                        PERIPH_CLK_SOURCE_NUM2 + \
+                                        PERIPH_CLK_SOURCE_NUM3)
+
+#define CPU_SOFTRST_CTRL               0x380
+
+#define PERIPH_CLK_SOURCE_DIVU71_MASK  0xFF
+#define PERIPH_CLK_SOURCE_DIVU16_MASK  0xFFFF
+#define PERIPH_CLK_SOURCE_DIV_SHIFT    0
+#define PERIPH_CLK_SOURCE_DIVIDLE_SHIFT        8
+#define PERIPH_CLK_SOURCE_DIVIDLE_VAL  50
+#define PERIPH_CLK_UART_DIV_ENB                (1<<24)
+#define PERIPH_CLK_VI_SEL_EX_SHIFT     24
+#define PERIPH_CLK_VI_SEL_EX_MASK      (0x3<<PERIPH_CLK_VI_SEL_EX_SHIFT)
+#define PERIPH_CLK_NAND_DIV_EX_ENB     (1<<8)
+#define PERIPH_CLK_DTV_POLARITY_INV    (1<<25)
+
+#define AUDIO_SYNC_SOURCE_MASK         0x0F
+#define AUDIO_SYNC_DISABLE_BIT         0x10
+#define AUDIO_SYNC_TAP_NIBBLE_SHIFT(c) ((c->reg_shift - 24) * 4)
+
+#define PLL_BASE                       0x0
+#define PLL_BASE_BYPASS                        (1<<31)
+#define PLL_BASE_ENABLE                        (1<<30)
+#define PLL_BASE_REF_ENABLE            (1<<29)
+#define PLL_BASE_OVERRIDE              (1<<28)
+#define PLL_BASE_LOCK                  (1<<27)
+#define PLL_BASE_DIVP_MASK             (0x7<<20)
+#define PLL_BASE_DIVP_SHIFT            20
+#define PLL_BASE_DIVN_MASK             (0x3FF<<8)
+#define PLL_BASE_DIVN_SHIFT            8
+#define PLL_BASE_DIVM_MASK             (0x1F)
+#define PLL_BASE_DIVM_SHIFT            0
+
+#define PLL_OUT_RATIO_MASK             (0xFF<<8)
+#define PLL_OUT_RATIO_SHIFT            8
+#define PLL_OUT_OVERRIDE               (1<<2)
+#define PLL_OUT_CLKEN                  (1<<1)
+#define PLL_OUT_RESET_DISABLE          (1<<0)
+
+#define PLL_MISC(c)                    \
+       (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
+#define PLL_MISC_LOCK_ENABLE(c)        \
+       (((c)->flags & (PLLU | PLLD)) ? (1<<22) : (1<<18))
+
+#define PLL_MISC_DCCON_SHIFT           20
+#define PLL_MISC_CPCON_SHIFT           8
+#define PLL_MISC_CPCON_MASK            (0xF<<PLL_MISC_CPCON_SHIFT)
+#define PLL_MISC_LFCON_SHIFT           4
+#define PLL_MISC_LFCON_MASK            (0xF<<PLL_MISC_LFCON_SHIFT)
+#define PLL_MISC_VCOCON_SHIFT          0
+#define PLL_MISC_VCOCON_MASK           (0xF<<PLL_MISC_VCOCON_SHIFT)
+#define PLLD_MISC_CLKENABLE            (1<<30)
+
+#define PLLU_BASE_POST_DIV             (1<<20)
+
+#define PLLD_BASE_DSIB_MUX_SHIFT       25
+#define PLLD_BASE_DSIB_MUX_MASK                (1<<PLLD_BASE_DSIB_MUX_SHIFT)
+#define PLLD_BASE_CSI_CLKENABLE                (1<<26)
+#define PLLD_MISC_DSI_CLKENABLE                (1<<30)
+#define PLLD_MISC_DIV_RST              (1<<23)
+#define PLLD_MISC_DCCON_SHIFT          12
+
+#define PLLDU_LFCON_SET_DIVN           600
+
+/* FIXME: OUT_OF_TABLE_CPCON per pll */
+#define OUT_OF_TABLE_CPCON             0x8
+
+#define SUPER_CLK_MUX                  0x00
+#define SUPER_STATE_SHIFT              28
+#define SUPER_STATE_MASK               (0xF << SUPER_STATE_SHIFT)
+#define SUPER_STATE_STANDBY            (0x0 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_IDLE               (0x1 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_RUN                        (0x2 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_IRQ                        (0x3 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_FIQ                        (0x4 << SUPER_STATE_SHIFT)
+#define SUPER_LP_DIV2_BYPASS           (0x1 << 16)
+#define SUPER_SOURCE_MASK              0xF
+#define        SUPER_FIQ_SOURCE_SHIFT          12
+#define        SUPER_IRQ_SOURCE_SHIFT          8
+#define        SUPER_RUN_SOURCE_SHIFT          4
+#define        SUPER_IDLE_SOURCE_SHIFT         0
+
+#define SUPER_CLK_DIVIDER              0x04
+#define SUPER_CLOCK_DIV_U71_SHIFT      16
+#define SUPER_CLOCK_DIV_U71_MASK       (0xff << SUPER_CLOCK_DIV_U71_SHIFT)
+/* guarantees safe cpu backup */
+#define SUPER_CLOCK_DIV_U71_MIN                0x2
+
+#define BUS_CLK_DISABLE                        (1<<3)
+#define BUS_CLK_DIV_MASK               0x3
+
+#define PMC_CTRL                       0x0
+ #define PMC_CTRL_BLINK_ENB            (1 << 7)
+
+#define PMC_DPD_PADS_ORIDE             0x1c
+ #define PMC_DPD_PADS_ORIDE_BLINK_ENB  (1 << 20)
+
+#define PMC_BLINK_TIMER_DATA_ON_SHIFT  0
+#define PMC_BLINK_TIMER_DATA_ON_MASK   0x7fff
+#define PMC_BLINK_TIMER_ENB            (1 << 15)
+#define PMC_BLINK_TIMER_DATA_OFF_SHIFT 16
+#define PMC_BLINK_TIMER_DATA_OFF_MASK  0xffff
+
+#define PMC_PLLP_WB0_OVERRIDE                          0xf8
+#define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE              (1 << 12)
+
+#define UTMIP_PLL_CFG2                                 0x488
+#define UTMIP_PLL_CFG2_STABLE_COUNT(x)                 (((x) & 0xfff) << 6)
+#define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x)             (((x) & 0x3f) << 18)
+#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN       (1 << 0)
+#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN       (1 << 2)
+#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN       (1 << 4)
+
+#define UTMIP_PLL_CFG1                                 0x484
+#define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x)             (((x) & 0x1f) << 27)
+#define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x)              (((x) & 0xfff) << 0)
+#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN      (1 << 14)
+#define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN      (1 << 12)
+#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN            (1 << 16)
+
+#define PLLE_BASE_CML_ENABLE           (1<<31)
+#define PLLE_BASE_ENABLE               (1<<30)
+#define PLLE_BASE_DIVCML_SHIFT         24
+#define PLLE_BASE_DIVCML_MASK          (0xf<<PLLE_BASE_DIVCML_SHIFT)
+#define PLLE_BASE_DIVP_SHIFT           16
+#define PLLE_BASE_DIVP_MASK            (0x3f<<PLLE_BASE_DIVP_SHIFT)
+#define PLLE_BASE_DIVN_SHIFT           8
+#define PLLE_BASE_DIVN_MASK            (0xFF<<PLLE_BASE_DIVN_SHIFT)
+#define PLLE_BASE_DIVM_SHIFT           0
+#define PLLE_BASE_DIVM_MASK            (0xFF<<PLLE_BASE_DIVM_SHIFT)
+#define PLLE_BASE_DIV_MASK             \
+       (PLLE_BASE_DIVCML_MASK | PLLE_BASE_DIVP_MASK | \
+        PLLE_BASE_DIVN_MASK | PLLE_BASE_DIVM_MASK)
+#define PLLE_BASE_DIV(m, n, p, cml)            \
+        (((cml)<<PLLE_BASE_DIVCML_SHIFT) | ((p)<<PLLE_BASE_DIVP_SHIFT) | \
+         ((n)<<PLLE_BASE_DIVN_SHIFT) | ((m)<<PLLE_BASE_DIVM_SHIFT))
+
+#define PLLE_MISC_SETUP_BASE_SHIFT     16
+#define PLLE_MISC_SETUP_BASE_MASK      (0xFFFF<<PLLE_MISC_SETUP_BASE_SHIFT)
+#define PLLE_MISC_READY                        (1<<15)
+#define PLLE_MISC_LOCK                 (1<<11)
+#define PLLE_MISC_LOCK_ENABLE          (1<<9)
+#define PLLE_MISC_SETUP_EX_SHIFT       2
+#define PLLE_MISC_SETUP_EX_MASK                (0x3<<PLLE_MISC_SETUP_EX_SHIFT)
+#define PLLE_MISC_SETUP_MASK           \
+         (PLLE_MISC_SETUP_BASE_MASK | PLLE_MISC_SETUP_EX_MASK)
+#define PLLE_MISC_SETUP_VALUE          \
+         ((0x7<<PLLE_MISC_SETUP_BASE_SHIFT) | (0x0<<PLLE_MISC_SETUP_EX_SHIFT))
+
+#define PLLE_SS_CTRL                   0x68
+#define        PLLE_SS_INCINTRV_SHIFT          24
+#define        PLLE_SS_INCINTRV_MASK           (0x3f<<PLLE_SS_INCINTRV_SHIFT)
+#define        PLLE_SS_INC_SHIFT               16
+#define        PLLE_SS_INC_MASK                (0xff<<PLLE_SS_INC_SHIFT)
+#define        PLLE_SS_MAX_SHIFT               0
+#define        PLLE_SS_MAX_MASK                (0x1ff<<PLLE_SS_MAX_SHIFT)
+#define PLLE_SS_COEFFICIENTS_MASK      \
+       (PLLE_SS_INCINTRV_MASK | PLLE_SS_INC_MASK | PLLE_SS_MAX_MASK)
+#define PLLE_SS_COEFFICIENTS_12MHZ     \
+       ((0x18<<PLLE_SS_INCINTRV_SHIFT) | (0x1<<PLLE_SS_INC_SHIFT) | \
+        (0x24<<PLLE_SS_MAX_SHIFT))
+#define PLLE_SS_DISABLE                        ((1<<12) | (1<<11) | (1<<10))
+
+#define PLLE_AUX                       0x48c
+#define PLLE_AUX_PLLP_SEL              (1<<2)
+#define PLLE_AUX_CML_SATA_ENABLE       (1<<1)
+#define PLLE_AUX_CML_PCIE_ENABLE       (1<<0)
+
+#define        PMC_SATA_PWRGT                  0x1ac
+#define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE (1<<5)
+#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL (1<<4)
+
+#define ROUND_DIVIDER_UP       0
+#define ROUND_DIVIDER_DOWN     1
+
+/* FIXME: recommended safety delay after lock is detected */
+#define PLL_POST_LOCK_DELAY            100
+
+/**
+* Structure defining the fields for USB UTMI clocks Parameters.
+*/
+struct utmi_clk_param {
+       /* Oscillator Frequency in KHz */
+       u32 osc_frequency;
+       /* UTMIP PLL Enable Delay Count  */
+       u8 enable_delay_count;
+       /* UTMIP PLL Stable count */
+       u8 stable_count;
+       /*  UTMIP PLL Active delay count */
+       u8 active_delay_count;
+       /* UTMIP PLL Xtal frequency count */
+       u8 xtal_freq_count;
+};
+
+static const struct utmi_clk_param utmi_parameters[] = {
+       {
+               .osc_frequency = 13000000,
+               .enable_delay_count = 0x02,
+               .stable_count = 0x33,
+               .active_delay_count = 0x05,
+               .xtal_freq_count = 0x7F
+       },
+       {
+               .osc_frequency = 19200000,
+               .enable_delay_count = 0x03,
+               .stable_count = 0x4B,
+               .active_delay_count = 0x06,
+               .xtal_freq_count = 0xBB},
+       {
+               .osc_frequency = 12000000,
+               .enable_delay_count = 0x02,
+               .stable_count = 0x2F,
+               .active_delay_count = 0x04,
+               .xtal_freq_count = 0x76
+       },
+       {
+               .osc_frequency = 26000000,
+               .enable_delay_count = 0x04,
+               .stable_count = 0x66,
+               .active_delay_count = 0x09,
+               .xtal_freq_count = 0xFE
+       },
+       {
+               .osc_frequency = 16800000,
+               .enable_delay_count = 0x03,
+               .stable_count = 0x41,
+               .active_delay_count = 0x0A,
+               .xtal_freq_count = 0xA4
+       },
+};
+
+static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
+static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
+static void __iomem *misc_gp_hidrev_base = IO_ADDRESS(TEGRA_APB_MISC_BASE);
+
+#define MISC_GP_HIDREV                  0x804
+
+/*
+ * Some peripheral clocks share an enable bit, so refcount the enable bits
+ * in registers CLK_ENABLE_L, ... CLK_ENABLE_W
+ */
+static int tegra_periph_clk_enable_refcount[CLK_OUT_ENB_NUM * 32];
+
+#define clk_writel(value, reg) \
+       __raw_writel(value, (u32)reg_clk_base + (reg))
+#define clk_readl(reg) \
+       __raw_readl((u32)reg_clk_base + (reg))
+#define pmc_writel(value, reg) \
+       __raw_writel(value, (u32)reg_pmc_base + (reg))
+#define pmc_readl(reg) \
+       __raw_readl((u32)reg_pmc_base + (reg))
+#define chipid_readl() \
+       __raw_readl((u32)misc_gp_hidrev_base + MISC_GP_HIDREV)
+
+#define clk_writel_delay(value, reg)                                   \
+       do {                                                            \
+               __raw_writel((value), (u32)reg_clk_base + (reg));       \
+               udelay(2);                                              \
+       } while (0)
+
+
+static inline int clk_set_div(struct clk *c, u32 n)
+{
+       return clk_set_rate(c, (clk_get_rate(c->parent) + n-1) / n);
+}
+
+static inline u32 periph_clk_to_reg(
+       struct clk *c, u32 reg_L, u32 reg_V, int offs)
+{
+       u32 reg = c->u.periph.clk_num / 32;
+       BUG_ON(reg >= RST_DEVICES_NUM);
+       if (reg < 3)
+               reg = reg_L + (reg * offs);
+       else
+               reg = reg_V + ((reg - 3) * offs);
+       return reg;
+}
+
+static unsigned long clk_measure_input_freq(void)
+{
+       u32 clock_autodetect;
+       clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
+       do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
+       clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
+       if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) {
+               return 12000000;
+       } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) {
+               return 13000000;
+       } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) {
+               return 19200000;
+       } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) {
+               return 26000000;
+       } else if (clock_autodetect >= 1025 - 3 && clock_autodetect <= 1025 + 3) {
+               return 16800000;
+       } else if (clock_autodetect >= 2344 - 3 && clock_autodetect <= 2344 + 3) {
+               return 38400000;
+       } else if (clock_autodetect >= 2928 - 3 && clock_autodetect <= 2928 + 3) {
+               return 48000000;
+       } else {
+               pr_err("%s: Unexpected clock autodetect value %d", __func__,
+                       clock_autodetect);
+               BUG();
+               return 0;
+       }
+}
+
+static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate,
+                                u32 flags, u32 round_mode)
+{
+       s64 divider_u71 = parent_rate;
+       if (!rate)
+               return -EINVAL;
+
+       if (!(flags & DIV_U71_INT))
+               divider_u71 *= 2;
+       if (round_mode == ROUND_DIVIDER_UP)
+               divider_u71 += rate - 1;
+       do_div(divider_u71, rate);
+       if (flags & DIV_U71_INT)
+               divider_u71 *= 2;
+
+       if (divider_u71 - 2 < 0)
+               return 0;
+
+       if (divider_u71 - 2 > 255)
+               return -EINVAL;
+
+       return divider_u71 - 2;
+}
+
+static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
+{
+       s64 divider_u16;
+
+       divider_u16 = parent_rate;
+       if (!rate)
+               return -EINVAL;
+       divider_u16 += rate - 1;
+       do_div(divider_u16, rate);
+
+       if (divider_u16 - 1 < 0)
+               return 0;
+
+       if (divider_u16 - 1 > 0xFFFF)
+               return -EINVAL;
+
+       return divider_u16 - 1;
+}
+
+/* clk_m functions */
+static unsigned long tegra30_clk_m_autodetect_rate(struct clk *c)
+{
+       u32 osc_ctrl = clk_readl(OSC_CTRL);
+       u32 auto_clock_control = osc_ctrl & ~OSC_CTRL_OSC_FREQ_MASK;
+       u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK;
+
+       c->rate = clk_measure_input_freq();
+       switch (c->rate) {
+       case 12000000:
+               auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
+               BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
+               break;
+       case 13000000:
+               auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ;
+               BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
+               break;
+       case 19200000:
+               auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ;
+               BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
+               break;
+       case 26000000:
+               auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
+               BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
+               break;
+       case 16800000:
+               auto_clock_control |= OSC_CTRL_OSC_FREQ_16_8MHZ;
+               BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
+               break;
+       case 38400000:
+               auto_clock_control |= OSC_CTRL_OSC_FREQ_38_4MHZ;
+               BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_2);
+               break;
+       case 48000000:
+               auto_clock_control |= OSC_CTRL_OSC_FREQ_48MHZ;
+               BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_4);
+               break;
+       default:
+               pr_err("%s: Unexpected clock rate %ld", __func__, c->rate);
+               BUG();
+       }
+       clk_writel(auto_clock_control, OSC_CTRL);
+       return c->rate;
+}
+
+static void tegra30_clk_m_init(struct clk *c)
+{
+       pr_debug("%s on clock %s\n", __func__, c->name);
+       tegra30_clk_m_autodetect_rate(c);
+}
+
+static int tegra30_clk_m_enable(struct clk *c)
+{
+       pr_debug("%s on clock %s\n", __func__, c->name);
+       return 0;
+}
+
+static void tegra30_clk_m_disable(struct clk *c)
+{
+       pr_debug("%s on clock %s\n", __func__, c->name);
+       WARN(1, "Attempting to disable main SoC clock\n");
+}
+
+static struct clk_ops tegra_clk_m_ops = {
+       .init           = tegra30_clk_m_init,
+       .enable         = tegra30_clk_m_enable,
+       .disable        = tegra30_clk_m_disable,
+};
+
+static struct clk_ops tegra_clk_m_div_ops = {
+       .enable         = tegra30_clk_m_enable,
+};
+
+/* PLL reference divider functions */
+static void tegra30_pll_ref_init(struct clk *c)
+{
+       u32 pll_ref_div = clk_readl(OSC_CTRL) & OSC_CTRL_PLL_REF_DIV_MASK;
+       pr_debug("%s on clock %s\n", __func__, c->name);
+
+       switch (pll_ref_div) {
+       case OSC_CTRL_PLL_REF_DIV_1:
+               c->div = 1;
+               break;
+       case OSC_CTRL_PLL_REF_DIV_2:
+               c->div = 2;
+               break;
+       case OSC_CTRL_PLL_REF_DIV_4:
+               c->div = 4;
+               break;
+       default:
+               pr_err("%s: Invalid pll ref divider %d", __func__, pll_ref_div);
+               BUG();
+       }
+       c->mul = 1;
+       c->state = ON;
+}
+
+static struct clk_ops tegra_pll_ref_ops = {
+       .init           = tegra30_pll_ref_init,
+       .enable         = tegra30_clk_m_enable,
+       .disable        = tegra30_clk_m_disable,
+};
+
+/* super clock functions */
+/* "super clocks" on tegra30 have two-stage muxes, fractional 7.1 divider and
+ * clock skipping super divider.  We will ignore the clock skipping divider,
+ * since we can't lower the voltage when using the clock skip, but we can if
+ * we lower the PLL frequency. We will use 7.1 divider for CPU super-clock
+ * only when its parent is a fixed rate PLL, since we can't change PLL rate
+ * in this case.
+ */
+static void tegra30_super_clk_init(struct clk *c)
+{
+       u32 val;
+       int source;
+       int shift;
+       const struct clk_mux_sel *sel;
+       val = clk_readl(c->reg + SUPER_CLK_MUX);
+       c->state = ON;
+       BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
+               ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
+       shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
+               SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
+       source = (val >> shift) & SUPER_SOURCE_MASK;
+       if (c->flags & DIV_2)
+               source |= val & SUPER_LP_DIV2_BYPASS;
+       for (sel = c->inputs; sel->input != NULL; sel++) {
+               if (sel->value == source)
+                       break;
+       }
+       BUG_ON(sel->input == NULL);
+       c->parent = sel->input;
+
+       if (c->flags & DIV_U71) {
+               /* Init safe 7.1 divider value (does not affect PLLX path) */
+               clk_writel(SUPER_CLOCK_DIV_U71_MIN << SUPER_CLOCK_DIV_U71_SHIFT,
+                          c->reg + SUPER_CLK_DIVIDER);
+               c->mul = 2;
+               c->div = 2;
+               if (!(c->parent->flags & PLLX))
+                       c->div += SUPER_CLOCK_DIV_U71_MIN;
+       } else
+               clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
+}
+
+static int tegra30_super_clk_enable(struct clk *c)
+{
+       return 0;
+}
+
+static void tegra30_super_clk_disable(struct clk *c)
+{
+       /* since tegra 3 has 2 CPU super clocks - low power lp-mode clock and
+          geared up g-mode super clock - mode switch may request to disable
+          either of them; accept request with no affect on h/w */
+}
+
+static int tegra30_super_clk_set_parent(struct clk *c, struct clk *p)
+{
+       u32 val;
+       const struct clk_mux_sel *sel;
+       int shift;
+
+       val = clk_readl(c->reg + SUPER_CLK_MUX);
+       BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
+               ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
+       shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
+               SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
+       for (sel = c->inputs; sel->input != NULL; sel++) {
+               if (sel->input == p) {
+                       /* For LP mode super-clock switch between PLLX direct
+                          and divided-by-2 outputs is allowed only when other
+                          than PLLX clock source is current parent */
+                       if ((c->flags & DIV_2) && (p->flags & PLLX) &&
+                           ((sel->value ^ val) & SUPER_LP_DIV2_BYPASS)) {
+                               if (c->parent->flags & PLLX)
+                                       return -EINVAL;
+                               val ^= SUPER_LP_DIV2_BYPASS;
+                               clk_writel_delay(val, c->reg);
+                       }
+                       val &= ~(SUPER_SOURCE_MASK << shift);
+                       val |= (sel->value & SUPER_SOURCE_MASK) << shift;
+
+                       /* 7.1 divider for CPU super-clock does not affect
+                          PLLX path */
+                       if (c->flags & DIV_U71) {
+                               u32 div = 0;
+                               if (!(p->flags & PLLX)) {
+                                       div = clk_readl(c->reg +
+                                                       SUPER_CLK_DIVIDER);
+                                       div &= SUPER_CLOCK_DIV_U71_MASK;
+                                       div >>= SUPER_CLOCK_DIV_U71_SHIFT;
+                               }
+                               c->div = div + 2;
+                               c->mul = 2;
+                       }
+
+                       if (c->refcnt)
+                               clk_enable(p);
+
+                       clk_writel_delay(val, c->reg);
+
+                       if (c->refcnt && c->parent)
+                               clk_disable(c->parent);
+
+                       clk_reparent(c, p);
+                       return 0;
+               }
+       }
+       return -EINVAL;
+}
+
+/*
+ * Do not use super clocks "skippers", since dividing using a clock skipper
+ * does not allow the voltage to be scaled down. Instead adjust the rate of
+ * the parent clock. This requires that the parent of a super clock have no
+ * other children, otherwise the rate will change underneath the other
+ * children. Special case: if fixed rate PLL is CPU super clock parent the
+ * rate of this PLL can't be changed, and it has many other children. In
+ * this case use 7.1 fractional divider to adjust the super clock rate.
+ */
+static int tegra30_super_clk_set_rate(struct clk *c, unsigned long rate)
+{
+       if ((c->flags & DIV_U71) && (c->parent->flags & PLL_FIXED)) {
+               int div = clk_div71_get_divider(c->parent->u.pll.fixed_rate,
+                                       rate, c->flags, ROUND_DIVIDER_DOWN);
+               div = max(div, SUPER_CLOCK_DIV_U71_MIN);
+
+               clk_writel(div << SUPER_CLOCK_DIV_U71_SHIFT,
+                          c->reg + SUPER_CLK_DIVIDER);
+               c->div = div + 2;
+               c->mul = 2;
+               return 0;
+       }
+       return clk_set_rate(c->parent, rate);
+}
+
+static struct clk_ops tegra_super_ops = {
+       .init                   = tegra30_super_clk_init,
+       .enable                 = tegra30_super_clk_enable,
+       .disable                = tegra30_super_clk_disable,
+       .set_parent             = tegra30_super_clk_set_parent,
+       .set_rate               = tegra30_super_clk_set_rate,
+};
+
+static int tegra30_twd_clk_set_rate(struct clk *c, unsigned long rate)
+{
+       /* The input value 'rate' is the clock rate of the CPU complex. */
+       c->rate = (rate * c->mul) / c->div;
+       return 0;
+}
+
+static struct clk_ops tegra30_twd_ops = {
+       .set_rate       = tegra30_twd_clk_set_rate,
+};
+
+/* Blink output functions */
+
+static void tegra30_blink_clk_init(struct clk *c)
+{
+       u32 val;
+
+       val = pmc_readl(PMC_CTRL);
+       c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF;
+       c->mul = 1;
+       val = pmc_readl(c->reg);
+
+       if (val & PMC_BLINK_TIMER_ENB) {
+               unsigned int on_off;
+
+               on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) &
+                       PMC_BLINK_TIMER_DATA_ON_MASK;
+               val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
+               val &= PMC_BLINK_TIMER_DATA_OFF_MASK;
+               on_off += val;
+               /* each tick in the blink timer is 4 32KHz clocks */
+               c->div = on_off * 4;
+       } else {
+               c->div = 1;
+       }
+}
+
+static int tegra30_blink_clk_enable(struct clk *c)
+{
+       u32 val;
+
+       val = pmc_readl(PMC_DPD_PADS_ORIDE);
+       pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
+
+       val = pmc_readl(PMC_CTRL);
+       pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL);
+
+       return 0;
+}
+
+static void tegra30_blink_clk_disable(struct clk *c)
+{
+       u32 val;
+
+       val = pmc_readl(PMC_CTRL);
+       pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL);
+
+       val = pmc_readl(PMC_DPD_PADS_ORIDE);
+       pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
+}
+
+static int tegra30_blink_clk_set_rate(struct clk *c, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(c->parent);
+       if (rate >= parent_rate) {
+               c->div = 1;
+               pmc_writel(0, c->reg);
+       } else {
+               unsigned int on_off;
+               u32 val;
+
+               on_off = DIV_ROUND_UP(parent_rate / 8, rate);
+               c->div = on_off * 8;
+
+               val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) <<
+                       PMC_BLINK_TIMER_DATA_ON_SHIFT;
+               on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK;
+               on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
+               val |= on_off;
+               val |= PMC_BLINK_TIMER_ENB;
+               pmc_writel(val, c->reg);
+       }
+
+       return 0;
+}
+
+static struct clk_ops tegra_blink_clk_ops = {
+       .init                   = &tegra30_blink_clk_init,
+       .enable                 = &tegra30_blink_clk_enable,
+       .disable                = &tegra30_blink_clk_disable,
+       .set_rate               = &tegra30_blink_clk_set_rate,
+};
+
+/* PLL Functions */
+static int tegra30_pll_clk_wait_for_lock(struct clk *c, u32 lock_reg,
+                                        u32 lock_bit)
+{
+#if USE_PLL_LOCK_BITS
+       int i;
+       for (i = 0; i < c->u.pll.lock_delay; i++) {
+               if (clk_readl(lock_reg) & lock_bit) {
+                       udelay(PLL_POST_LOCK_DELAY);
+                       return 0;
+               }
+               udelay(2);              /* timeout = 2 * lock time */
+       }
+       pr_err("Timed out waiting for lock bit on pll %s", c->name);
+       return -1;
+#endif
+       udelay(c->u.pll.lock_delay);
+
+       return 0;
+}
+
+
+static void tegra30_utmi_param_configure(struct clk *c)
+{
+       u32 reg;
+       int i;
+       unsigned long main_rate =
+               clk_get_rate(c->parent->parent);
+
+       for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) {
+               if (main_rate == utmi_parameters[i].osc_frequency)
+                       break;
+       }
+
+       if (i >= ARRAY_SIZE(utmi_parameters)) {
+               pr_err("%s: Unexpected main rate %lu\n", __func__, main_rate);
+               return;
+       }
+
+       reg = clk_readl(UTMIP_PLL_CFG2);
+
+       /* Program UTMIP PLL stable and active counts */
+       /* [FIXME] arclk_rst.h says WRONG! This should be 1ms -> 0x50 Check! */
+       reg &= ~UTMIP_PLL_CFG2_STABLE_COUNT(~0);
+       reg |= UTMIP_PLL_CFG2_STABLE_COUNT(
+                       utmi_parameters[i].stable_count);
+
+       reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0);
+
+       reg |= UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(
+                       utmi_parameters[i].active_delay_count);
+
+       /* Remove power downs from UTMIP PLL control bits */
+       reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN;
+       reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN;
+       reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN;
+
+       clk_writel(reg, UTMIP_PLL_CFG2);
+
+       /* Program UTMIP PLL delay and oscillator frequency counts */
+       reg = clk_readl(UTMIP_PLL_CFG1);
+       reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0);
+
+       reg |= UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(
+               utmi_parameters[i].enable_delay_count);
+
+       reg &= ~UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(~0);
+       reg |= UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(
+               utmi_parameters[i].xtal_freq_count);
+
+       /* Remove power downs from UTMIP PLL control bits */
+       reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN;
+       reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN;
+       reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN;
+
+       clk_writel(reg, UTMIP_PLL_CFG1);
+}
+
+static void tegra30_pll_clk_init(struct clk *c)
+{
+       u32 val = clk_readl(c->reg + PLL_BASE);
+
+       c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
+
+       if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
+               const struct clk_pll_freq_table *sel;
+               unsigned long input_rate = clk_get_rate(c->parent);
+               for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
+                       if (sel->input_rate == input_rate &&
+                               sel->output_rate == c->u.pll.fixed_rate) {
+                               c->mul = sel->n;
+                               c->div = sel->m * sel->p;
+                               return;
+                       }
+               }
+               pr_err("Clock %s has unknown fixed frequency\n", c->name);
+               BUG();
+       } else if (val & PLL_BASE_BYPASS) {
+               c->mul = 1;
+               c->div = 1;
+       } else {
+               c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
+               c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
+               if (c->flags & PLLU)
+                       c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
+               else
+                       c->div *= (0x1 << ((val & PLL_BASE_DIVP_MASK) >>
+                                       PLL_BASE_DIVP_SHIFT));
+               if (c->flags & PLL_FIXED) {
+                       unsigned long rate = clk_get_rate_locked(c);
+                       BUG_ON(rate != c->u.pll.fixed_rate);
+               }
+       }
+
+       if (c->flags & PLLU)
+               tegra30_utmi_param_configure(c);
+}
+
+static int tegra30_pll_clk_enable(struct clk *c)
+{
+       u32 val;
+       pr_debug("%s on clock %s\n", __func__, c->name);
+
+#if USE_PLL_LOCK_BITS
+       val = clk_readl(c->reg + PLL_MISC(c));
+       val |= PLL_MISC_LOCK_ENABLE(c);
+       clk_writel(val, c->reg + PLL_MISC(c));
+#endif
+       val = clk_readl(c->reg + PLL_BASE);
+       val &= ~PLL_BASE_BYPASS;
+       val |= PLL_BASE_ENABLE;
+       clk_writel(val, c->reg + PLL_BASE);
+
+       if (c->flags & PLLM) {
+               val = pmc_readl(PMC_PLLP_WB0_OVERRIDE);
+               val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
+               pmc_writel(val, PMC_PLLP_WB0_OVERRIDE);
+       }
+
+       tegra30_pll_clk_wait_for_lock(c, c->reg + PLL_BASE, PLL_BASE_LOCK);
+
+       return 0;
+}
+
+static void tegra30_pll_clk_disable(struct clk *c)
+{
+       u32 val;
+       pr_debug("%s on clock %s\n", __func__, c->name);
+
+       val = clk_readl(c->reg);
+       val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
+       clk_writel(val, c->reg);
+
+       if (c->flags & PLLM) {
+               val = pmc_readl(PMC_PLLP_WB0_OVERRIDE);
+               val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
+               pmc_writel(val, PMC_PLLP_WB0_OVERRIDE);
+       }
+}
+
+static int tegra30_pll_clk_set_rate(struct clk *c, unsigned long rate)
+{
+       u32 val, p_div, old_base;
+       unsigned long input_rate;
+       const struct clk_pll_freq_table *sel;
+       struct clk_pll_freq_table cfg;
+
+       pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+
+       if (c->flags & PLL_FIXED) {
+               int ret = 0;
+               if (rate != c->u.pll.fixed_rate) {
+                       pr_err("%s: Can not change %s fixed rate %lu to %lu\n",
+                              __func__, c->name, c->u.pll.fixed_rate, rate);
+                       ret = -EINVAL;
+               }
+               return ret;
+       }
+
+       if (c->flags & PLLM) {
+               if (rate != clk_get_rate_locked(c)) {
+                       pr_err("%s: Can not change memory %s rate in flight\n",
+                              __func__, c->name);
+                       return -EINVAL;
+               }
+               return 0;
+       }
+
+       p_div = 0;
+       input_rate = clk_get_rate(c->parent);
+
+       /* Check if the target rate is tabulated */
+       for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
+               if (sel->input_rate == input_rate && sel->output_rate == rate) {
+                       if (c->flags & PLLU) {
+                               BUG_ON(sel->p < 1 || sel->p > 2);
+                               if (sel->p == 1)
+                                       p_div = PLLU_BASE_POST_DIV;
+                       } else {
+                               BUG_ON(sel->p < 1);
+                               for (val = sel->p; val > 1; val >>= 1)
+                                       p_div++;
+                               p_div <<= PLL_BASE_DIVP_SHIFT;
+                       }
+                       break;
+               }
+       }
+
+       /* Configure out-of-table rate */
+       if (sel->input_rate == 0) {
+               unsigned long cfreq;
+               BUG_ON(c->flags & PLLU);
+               sel = &cfg;
+
+               switch (input_rate) {
+               case 12000000:
+               case 26000000:
+                       cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2000000;
+                       break;
+               case 13000000:
+                       cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2600000;
+                       break;
+               case 16800000:
+               case 19200000:
+                       cfreq = (rate <= 1200000 * 1000) ? 1200000 : 2400000;
+                       break;
+               default:
+                       pr_err("%s: Unexpected reference rate %lu\n",
+                              __func__, input_rate);
+                       BUG();
+               }
+
+               /* Raise VCO to guarantee 0.5% accuracy */
+               for (cfg.output_rate = rate; cfg.output_rate < 200 * cfreq;
+                     cfg.output_rate <<= 1)
+                       p_div++;
+
+               cfg.p = 0x1 << p_div;
+               cfg.m = input_rate / cfreq;
+               cfg.n = cfg.output_rate / cfreq;
+               cfg.cpcon = OUT_OF_TABLE_CPCON;
+
+               if ((cfg.m > (PLL_BASE_DIVM_MASK >> PLL_BASE_DIVM_SHIFT)) ||
+                   (cfg.n > (PLL_BASE_DIVN_MASK >> PLL_BASE_DIVN_SHIFT)) ||
+                   (p_div > (PLL_BASE_DIVP_MASK >> PLL_BASE_DIVP_SHIFT)) ||
+                   (cfg.output_rate > c->u.pll.vco_max)) {
+                       pr_err("%s: Failed to set %s out-of-table rate %lu\n",
+                              __func__, c->name, rate);
+                       return -EINVAL;
+               }
+               p_div <<= PLL_BASE_DIVP_SHIFT;
+       }
+
+       c->mul = sel->n;
+       c->div = sel->m * sel->p;
+
+       old_base = val = clk_readl(c->reg + PLL_BASE);
+       val &= ~(PLL_BASE_DIVM_MASK | PLL_BASE_DIVN_MASK |
+                ((c->flags & PLLU) ? PLLU_BASE_POST_DIV : PLL_BASE_DIVP_MASK));
+       val |= (sel->m << PLL_BASE_DIVM_SHIFT) |
+               (sel->n << PLL_BASE_DIVN_SHIFT) | p_div;
+       if (val == old_base)
+               return 0;
+
+       if (c->state == ON) {
+               tegra30_pll_clk_disable(c);
+               val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
+       }
+       clk_writel(val, c->reg + PLL_BASE);
+
+       if (c->flags & PLL_HAS_CPCON) {
+               val = clk_readl(c->reg + PLL_MISC(c));
+               val &= ~PLL_MISC_CPCON_MASK;
+               val |= sel->cpcon << PLL_MISC_CPCON_SHIFT;
+               if (c->flags & (PLLU | PLLD)) {
+                       val &= ~PLL_MISC_LFCON_MASK;
+                       if (sel->n >= PLLDU_LFCON_SET_DIVN)
+                               val |= 0x1 << PLL_MISC_LFCON_SHIFT;
+               } else if (c->flags & (PLLX | PLLM)) {
+                       val &= ~(0x1 << PLL_MISC_DCCON_SHIFT);
+                       if (rate >= (c->u.pll.vco_max >> 1))
+                               val |= 0x1 << PLL_MISC_DCCON_SHIFT;
+               }
+               clk_writel(val, c->reg + PLL_MISC(c));
+       }
+
+       if (c->state == ON)
+               tegra30_pll_clk_enable(c);
+
+       return 0;
+}
+
+static struct clk_ops tegra_pll_ops = {
+       .init                   = tegra30_pll_clk_init,
+       .enable                 = tegra30_pll_clk_enable,
+       .disable                = tegra30_pll_clk_disable,
+       .set_rate               = tegra30_pll_clk_set_rate,
+};
+
+static int
+tegra30_plld_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
+{
+       u32 val, mask, reg;
+
+       switch (p) {
+       case TEGRA_CLK_PLLD_CSI_OUT_ENB:
+               mask = PLLD_BASE_CSI_CLKENABLE;
+               reg = c->reg + PLL_BASE;
+               break;
+       case TEGRA_CLK_PLLD_DSI_OUT_ENB:
+               mask = PLLD_MISC_DSI_CLKENABLE;
+               reg = c->reg + PLL_MISC(c);
+               break;
+       case TEGRA_CLK_PLLD_MIPI_MUX_SEL:
+               if (!(c->flags & PLL_ALT_MISC_REG)) {
+                       mask = PLLD_BASE_DSIB_MUX_MASK;
+                       reg = c->reg + PLL_BASE;
+                       break;
+               }
+       /* fall through - error since PLLD2 does not have MUX_SEL control */
+       default:
+               return -EINVAL;
+       }
+
+       val = clk_readl(reg);
+       if (setting)
+               val |= mask;
+       else
+               val &= ~mask;
+       clk_writel(val, reg);
+       return 0;
+}
+
+static struct clk_ops tegra_plld_ops = {
+       .init                   = tegra30_pll_clk_init,
+       .enable                 = tegra30_pll_clk_enable,
+       .disable                = tegra30_pll_clk_disable,
+       .set_rate               = tegra30_pll_clk_set_rate,
+       .clk_cfg_ex             = tegra30_plld_clk_cfg_ex,
+};
+
+static void tegra30_plle_clk_init(struct clk *c)
+{
+       u32 val;
+
+       val = clk_readl(PLLE_AUX);
+       c->parent = (val & PLLE_AUX_PLLP_SEL) ?
+               tegra_get_clock_by_name("pll_p") :
+               tegra_get_clock_by_name("pll_ref");
+
+       val = clk_readl(c->reg + PLL_BASE);
+       c->state = (val & PLLE_BASE_ENABLE) ? ON : OFF;
+       c->mul = (val & PLLE_BASE_DIVN_MASK) >> PLLE_BASE_DIVN_SHIFT;
+       c->div = (val & PLLE_BASE_DIVM_MASK) >> PLLE_BASE_DIVM_SHIFT;
+       c->div *= (val & PLLE_BASE_DIVP_MASK) >> PLLE_BASE_DIVP_SHIFT;
+}
+
+static void tegra30_plle_clk_disable(struct clk *c)
+{
+       u32 val;
+       pr_debug("%s on clock %s\n", __func__, c->name);
+
+       val = clk_readl(c->reg + PLL_BASE);
+       val &= ~(PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE);
+       clk_writel(val, c->reg + PLL_BASE);
+}
+
+static void tegra30_plle_training(struct clk *c)
+{
+       u32 val;
+
+       /* PLLE is already disabled, and setup cleared;
+        * create falling edge on PLLE IDDQ input */
+       val = pmc_readl(PMC_SATA_PWRGT);
+       val |= PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
+       pmc_writel(val, PMC_SATA_PWRGT);
+
+       val = pmc_readl(PMC_SATA_PWRGT);
+       val |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL;
+       pmc_writel(val, PMC_SATA_PWRGT);
+
+       val = pmc_readl(PMC_SATA_PWRGT);
+       val &= ~PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
+       pmc_writel(val, PMC_SATA_PWRGT);
+
+       do {
+               val = clk_readl(c->reg + PLL_MISC(c));
+       } while (!(val & PLLE_MISC_READY));
+}
+
+static int tegra30_plle_configure(struct clk *c, bool force_training)
+{
+       u32 val;
+       const struct clk_pll_freq_table *sel;
+       unsigned long rate = c->u.pll.fixed_rate;
+       unsigned long input_rate = clk_get_rate(c->parent);
+
+       for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
+               if (sel->input_rate == input_rate && sel->output_rate == rate)
+                       break;
+       }
+
+       if (sel->input_rate == 0)
+               return -ENOSYS;
+
+       /* disable PLLE, clear setup fiels */
+       tegra30_plle_clk_disable(c);
+
+       val = clk_readl(c->reg + PLL_MISC(c));
+       val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK);
+       clk_writel(val, c->reg + PLL_MISC(c));
+
+       /* training */
+       val = clk_readl(c->reg + PLL_MISC(c));
+       if (force_training || (!(val & PLLE_MISC_READY)))
+               tegra30_plle_training(c);
+
+       /* configure dividers, setup, disable SS */
+       val = clk_readl(c->reg + PLL_BASE);
+       val &= ~PLLE_BASE_DIV_MASK;
+       val |= PLLE_BASE_DIV(sel->m, sel->n, sel->p, sel->cpcon);
+       clk_writel(val, c->reg + PLL_BASE);
+       c->mul = sel->n;
+       c->div = sel->m * sel->p;
+
+       val = clk_readl(c->reg + PLL_MISC(c));
+       val |= PLLE_MISC_SETUP_VALUE;
+       val |= PLLE_MISC_LOCK_ENABLE;
+       clk_writel(val, c->reg + PLL_MISC(c));
+
+       val = clk_readl(PLLE_SS_CTRL);
+       val |= PLLE_SS_DISABLE;
+       clk_writel(val, PLLE_SS_CTRL);
+
+       /* enable and lock PLLE*/
+       val = clk_readl(c->reg + PLL_BASE);
+       val |= (PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE);
+       clk_writel(val, c->reg + PLL_BASE);
+
+       tegra30_pll_clk_wait_for_lock(c, c->reg + PLL_MISC(c), PLLE_MISC_LOCK);
+
+       return 0;
+}
+
+static int tegra30_plle_clk_enable(struct clk *c)
+{
+       pr_debug("%s on clock %s\n", __func__, c->name);
+       return tegra30_plle_configure(c, !c->set);
+}
+
+static struct clk_ops tegra_plle_ops = {
+       .init                   = tegra30_plle_clk_init,
+       .enable                 = tegra30_plle_clk_enable,
+       .disable                = tegra30_plle_clk_disable,
+};
+
+/* Clock divider ops */
+static void tegra30_pll_div_clk_init(struct clk *c)
+{
+       if (c->flags & DIV_U71) {
+               u32 divu71;
+               u32 val = clk_readl(c->reg);
+               val >>= c->reg_shift;
+               c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
+               if (!(val & PLL_OUT_RESET_DISABLE))
+                       c->state = OFF;
+
+               divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
+               c->div = (divu71 + 2);
+               c->mul = 2;
+       } else if (c->flags & DIV_2) {
+               c->state = ON;
+               if (c->flags & (PLLD | PLLX)) {
+                       c->div = 2;
+                       c->mul = 1;
+               } else
+                       BUG();
+       } else {
+               c->state = ON;
+               c->div = 1;
+               c->mul = 1;
+       }
+}
+
+static int tegra30_pll_div_clk_enable(struct clk *c)
+{
+       u32 val;
+       u32 new_val;
+
+       pr_debug("%s: %s\n", __func__, c->name);
+       if (c->flags & DIV_U71) {
+               val = clk_readl(c->reg);
+               new_val = val >> c->reg_shift;
+               new_val &= 0xFFFF;
+
+               new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
+
+               val &= ~(0xFFFF << c->reg_shift);
+               val |= new_val << c->reg_shift;
+               clk_writel_delay(val, c->reg);
+               return 0;
+       } else if (c->flags & DIV_2) {
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static void tegra30_pll_div_clk_disable(struct clk *c)
+{
+       u32 val;
+       u32 new_val;
+
+       pr_debug("%s: %s\n", __func__, c->name);
+       if (c->flags & DIV_U71) {
+               val = clk_readl(c->reg);
+               new_val = val >> c->reg_shift;
+               new_val &= 0xFFFF;
+
+               new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE);
+
+               val &= ~(0xFFFF << c->reg_shift);
+               val |= new_val << c->reg_shift;
+               clk_writel_delay(val, c->reg);
+       }
+}
+
+static int tegra30_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
+{
+       u32 val;
+       u32 new_val;
+       int divider_u71;
+       unsigned long parent_rate = clk_get_rate(c->parent);
+
+       pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+       if (c->flags & DIV_U71) {
+               divider_u71 = clk_div71_get_divider(
+                       parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
+               if (divider_u71 >= 0) {
+                       val = clk_readl(c->reg);
+                       new_val = val >> c->reg_shift;
+                       new_val &= 0xFFFF;
+                       if (c->flags & DIV_U71_FIXED)
+                               new_val |= PLL_OUT_OVERRIDE;
+                       new_val &= ~PLL_OUT_RATIO_MASK;
+                       new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT;
+
+                       val &= ~(0xFFFF << c->reg_shift);
+                       val |= new_val << c->reg_shift;
+                       clk_writel_delay(val, c->reg);
+                       c->div = divider_u71 + 2;
+                       c->mul = 2;
+                       return 0;
+               }
+       } else if (c->flags & DIV_2)
+               return clk_set_rate(c->parent, rate * 2);
+
+       return -EINVAL;
+}
+
+static long tegra30_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
+{
+       int divider;
+       unsigned long parent_rate = clk_get_rate(c->parent);
+       pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+
+       if (c->flags & DIV_U71) {
+               divider = clk_div71_get_divider(
+                       parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
+               if (divider < 0)
+                       return divider;
+               return DIV_ROUND_UP(parent_rate * 2, divider + 2);
+       } else if (c->flags & DIV_2)
+               /* no rounding - fixed DIV_2 dividers pass rate to parent PLL */
+               return rate;
+
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_pll_div_ops = {
+       .init                   = tegra30_pll_div_clk_init,
+       .enable                 = tegra30_pll_div_clk_enable,
+       .disable                = tegra30_pll_div_clk_disable,
+       .set_rate               = tegra30_pll_div_clk_set_rate,
+       .round_rate             = tegra30_pll_div_clk_round_rate,
+};
+
+/* Periph clk ops */
+static inline u32 periph_clk_source_mask(struct clk *c)
+{
+       if (c->flags & MUX8)
+               return 7 << 29;
+       else if (c->flags & MUX_PWM)
+               return 3 << 28;
+       else if (c->flags & MUX_CLK_OUT)
+               return 3 << (c->u.periph.clk_num + 4);
+       else if (c->flags & PLLD)
+               return PLLD_BASE_DSIB_MUX_MASK;
+       else
+               return 3 << 30;
+}
+
+static inline u32 periph_clk_source_shift(struct clk *c)
+{
+       if (c->flags & MUX8)
+               return 29;
+       else if (c->flags & MUX_PWM)
+               return 28;
+       else if (c->flags & MUX_CLK_OUT)
+               return c->u.periph.clk_num + 4;
+       else if (c->flags & PLLD)
+               return PLLD_BASE_DSIB_MUX_SHIFT;
+       else
+               return 30;
+}
+
+static void tegra30_periph_clk_init(struct clk *c)
+{
+       u32 val = clk_readl(c->reg);
+       const struct clk_mux_sel *mux = 0;
+       const struct clk_mux_sel *sel;
+       if (c->flags & MUX) {
+               for (sel = c->inputs; sel->input != NULL; sel++) {
+                       if (((val & periph_clk_source_mask(c)) >>
+                           periph_clk_source_shift(c)) == sel->value)
+                               mux = sel;
+               }
+               BUG_ON(!mux);
+
+               c->parent = mux->input;
+       } else {
+               c->parent = c->inputs[0].input;
+       }
+
+       if (c->flags & DIV_U71) {
+               u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
+               if ((c->flags & DIV_U71_UART) &&
+                   (!(val & PERIPH_CLK_UART_DIV_ENB))) {
+                       divu71 = 0;
+               }
+               if (c->flags & DIV_U71_IDLE) {
+                       val &= ~(PERIPH_CLK_SOURCE_DIVU71_MASK <<
+                               PERIPH_CLK_SOURCE_DIVIDLE_SHIFT);
+                       val |= (PERIPH_CLK_SOURCE_DIVIDLE_VAL <<
+                               PERIPH_CLK_SOURCE_DIVIDLE_SHIFT);
+                       clk_writel(val, c->reg);
+               }
+               c->div = divu71 + 2;
+               c->mul = 2;
+       } else if (c->flags & DIV_U16) {
+               u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
+               c->div = divu16 + 1;
+               c->mul = 1;
+       } else {
+               c->div = 1;
+               c->mul = 1;
+       }
+
+       c->state = ON;
+       if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c)))
+               c->state = OFF;
+       if (!(c->flags & PERIPH_NO_RESET))
+               if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) & PERIPH_CLK_TO_BIT(c))
+                       c->state = OFF;
+}
+
+static int tegra30_periph_clk_enable(struct clk *c)
+{
+       pr_debug("%s on clock %s\n", __func__, c->name);
+
+       tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++;
+       if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 1)
+               return 0;
+
+       clk_writel_delay(PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_SET_REG(c));
+       if (!(c->flags & PERIPH_NO_RESET) &&
+                !(c->flags & PERIPH_MANUAL_RESET)) {
+               if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) &
+                        PERIPH_CLK_TO_BIT(c)) {
+                       udelay(5);      /* reset propagation delay */
+                       clk_writel(PERIPH_CLK_TO_BIT(c),
+                                PERIPH_CLK_TO_RST_CLR_REG(c));
+               }
+       }
+       return 0;
+}
+
+static void tegra30_periph_clk_disable(struct clk *c)
+{
+       unsigned long val;
+       pr_debug("%s on clock %s\n", __func__, c->name);
+
+       if (c->refcnt)
+               tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--;
+
+       if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] == 0) {
+               /* If peripheral is in the APB bus then read the APB bus to
+                * flush the write operation in apb bus. This will avoid the
+                * peripheral access after disabling clock*/
+               if (c->flags & PERIPH_ON_APB)
+                       val = chipid_readl();
+
+               clk_writel_delay(
+                       PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_CLR_REG(c));
+       }
+}
+
+static void tegra30_periph_clk_reset(struct clk *c, bool assert)
+{
+       unsigned long val;
+       pr_debug("%s %s on clock %s\n", __func__,
+                assert ? "assert" : "deassert", c->name);
+
+       if (!(c->flags & PERIPH_NO_RESET)) {
+               if (assert) {
+                       /* If peripheral is in the APB bus then read the APB
+                        * bus to flush the write operation in apb bus. This
+                        * will avoid the peripheral access after disabling
+                        * clock */
+                       if (c->flags & PERIPH_ON_APB)
+                               val = chipid_readl();
+
+                       clk_writel(PERIPH_CLK_TO_BIT(c),
+                                  PERIPH_CLK_TO_RST_SET_REG(c));
+               } else
+                       clk_writel(PERIPH_CLK_TO_BIT(c),
+                                  PERIPH_CLK_TO_RST_CLR_REG(c));
+       }
+}
+
+static int tegra30_periph_clk_set_parent(struct clk *c, struct clk *p)
+{
+       u32 val;
+       const struct clk_mux_sel *sel;
+       pr_debug("%s: %s %s\n", __func__, c->name, p->name);
+
+       if (!(c->flags & MUX))
+               return (p == c->parent) ? 0 : (-EINVAL);
+
+       for (sel = c->inputs; sel->input != NULL; sel++) {
+               if (sel->input == p) {
+                       val = clk_readl(c->reg);
+                       val &= ~periph_clk_source_mask(c);
+                       val |= (sel->value << periph_clk_source_shift(c));
+
+                       if (c->refcnt)
+                               clk_enable(p);
+
+                       clk_writel_delay(val, c->reg);
+
+                       if (c->refcnt && c->parent)
+                               clk_disable(c->parent);
+
+                       clk_reparent(c, p);
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static int tegra30_periph_clk_set_rate(struct clk *c, unsigned long rate)
+{
+       u32 val;
+       int divider;
+       unsigned long parent_rate = clk_get_rate(c->parent);
+
+       if (c->flags & DIV_U71) {
+               divider = clk_div71_get_divider(
+                       parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
+               if (divider >= 0) {
+                       val = clk_readl(c->reg);
+                       val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
+                       val |= divider;
+                       if (c->flags & DIV_U71_UART) {
+                               if (divider)
+                                       val |= PERIPH_CLK_UART_DIV_ENB;
+                               else
+                                       val &= ~PERIPH_CLK_UART_DIV_ENB;
+                       }
+                       clk_writel_delay(val, c->reg);
+                       c->div = divider + 2;
+                       c->mul = 2;
+                       return 0;
+               }
+       } else if (c->flags & DIV_U16) {
+               divider = clk_div16_get_divider(parent_rate, rate);
+               if (divider >= 0) {
+                       val = clk_readl(c->reg);
+                       val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
+                       val |= divider;
+                       clk_writel_delay(val, c->reg);
+                       c->div = divider + 1;
+                       c->mul = 1;
+                       return 0;
+               }
+       } else if (parent_rate <= rate) {
+               c->div = 1;
+               c->mul = 1;
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static long tegra30_periph_clk_round_rate(struct clk *c,
+       unsigned long rate)
+{
+       int divider;
+       unsigned long parent_rate = clk_get_rate(c->parent);
+       pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+
+       if (c->flags & DIV_U71) {
+               divider = clk_div71_get_divider(
+                       parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
+               if (divider < 0)
+                       return divider;
+
+               return DIV_ROUND_UP(parent_rate * 2, divider + 2);
+       } else if (c->flags & DIV_U16) {
+               divider = clk_div16_get_divider(parent_rate, rate);
+               if (divider < 0)
+                       return divider;
+               return DIV_ROUND_UP(parent_rate, divider + 1);
+       }
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_periph_clk_ops = {
+       .init                   = &tegra30_periph_clk_init,
+       .enable                 = &tegra30_periph_clk_enable,
+       .disable                = &tegra30_periph_clk_disable,
+       .set_parent             = &tegra30_periph_clk_set_parent,
+       .set_rate               = &tegra30_periph_clk_set_rate,
+       .round_rate             = &tegra30_periph_clk_round_rate,
+       .reset                  = &tegra30_periph_clk_reset,
+};
+
+
+/* Periph extended clock configuration ops */
+static int
+tegra30_vi_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
+{
+       if (p == TEGRA_CLK_VI_INP_SEL) {
+               u32 val = clk_readl(c->reg);
+               val &= ~PERIPH_CLK_VI_SEL_EX_MASK;
+               val |= (setting << PERIPH_CLK_VI_SEL_EX_SHIFT) &
+                       PERIPH_CLK_VI_SEL_EX_MASK;
+               clk_writel(val, c->reg);
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_vi_clk_ops = {
+       .init                   = &tegra30_periph_clk_init,
+       .enable                 = &tegra30_periph_clk_enable,
+       .disable                = &tegra30_periph_clk_disable,
+       .set_parent             = &tegra30_periph_clk_set_parent,
+       .set_rate               = &tegra30_periph_clk_set_rate,
+       .round_rate             = &tegra30_periph_clk_round_rate,
+       .clk_cfg_ex             = &tegra30_vi_clk_cfg_ex,
+       .reset                  = &tegra30_periph_clk_reset,
+};
+
+static int
+tegra30_nand_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
+{
+       if (p == TEGRA_CLK_NAND_PAD_DIV2_ENB) {
+               u32 val = clk_readl(c->reg);
+               if (setting)
+                       val |= PERIPH_CLK_NAND_DIV_EX_ENB;
+               else
+                       val &= ~PERIPH_CLK_NAND_DIV_EX_ENB;
+               clk_writel(val, c->reg);
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_nand_clk_ops = {
+       .init                   = &tegra30_periph_clk_init,
+       .enable                 = &tegra30_periph_clk_enable,
+       .disable                = &tegra30_periph_clk_disable,
+       .set_parent             = &tegra30_periph_clk_set_parent,
+       .set_rate               = &tegra30_periph_clk_set_rate,
+       .round_rate             = &tegra30_periph_clk_round_rate,
+       .clk_cfg_ex             = &tegra30_nand_clk_cfg_ex,
+       .reset                  = &tegra30_periph_clk_reset,
+};
+
+
+static int
+tegra30_dtv_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
+{
+       if (p == TEGRA_CLK_DTV_INVERT) {
+               u32 val = clk_readl(c->reg);
+               if (setting)
+                       val |= PERIPH_CLK_DTV_POLARITY_INV;
+               else
+                       val &= ~PERIPH_CLK_DTV_POLARITY_INV;
+               clk_writel(val, c->reg);
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_dtv_clk_ops = {
+       .init                   = &tegra30_periph_clk_init,
+       .enable                 = &tegra30_periph_clk_enable,
+       .disable                = &tegra30_periph_clk_disable,
+       .set_parent             = &tegra30_periph_clk_set_parent,
+       .set_rate               = &tegra30_periph_clk_set_rate,
+       .round_rate             = &tegra30_periph_clk_round_rate,
+       .clk_cfg_ex             = &tegra30_dtv_clk_cfg_ex,
+       .reset                  = &tegra30_periph_clk_reset,
+};
+
+static int tegra30_dsib_clk_set_parent(struct clk *c, struct clk *p)
+{
+       const struct clk_mux_sel *sel;
+       struct clk *d = tegra_get_clock_by_name("pll_d");
+
+       pr_debug("%s: %s %s\n", __func__, c->name, p->name);
+
+       for (sel = c->inputs; sel->input != NULL; sel++) {
+               if (sel->input == p) {
+                       if (c->refcnt)
+                               clk_enable(p);
+
+                       /* The DSIB parent selection bit is in PLLD base
+                          register - can not do direct r-m-w, must be
+                          protected by PLLD lock */
+                       tegra_clk_cfg_ex(
+                               d, TEGRA_CLK_PLLD_MIPI_MUX_SEL, sel->value);
+
+                       if (c->refcnt && c->parent)
+                               clk_disable(c->parent);
+
+                       clk_reparent(c, p);
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_dsib_clk_ops = {
+       .init                   = &tegra30_periph_clk_init,
+       .enable                 = &tegra30_periph_clk_enable,
+       .disable                = &tegra30_periph_clk_disable,
+       .set_parent             = &tegra30_dsib_clk_set_parent,
+       .set_rate               = &tegra30_periph_clk_set_rate,
+       .round_rate             = &tegra30_periph_clk_round_rate,
+       .reset                  = &tegra30_periph_clk_reset,
+};
+
+/* pciex clock support only reset function */
+static struct clk_ops tegra_pciex_clk_ops = {
+       .reset    = tegra30_periph_clk_reset,
+};
+
+/* Output clock ops */
+
+static DEFINE_SPINLOCK(clk_out_lock);
+
+static void tegra30_clk_out_init(struct clk *c)
+{
+       const struct clk_mux_sel *mux = 0;
+       const struct clk_mux_sel *sel;
+       u32 val = pmc_readl(c->reg);
+
+       c->state = (val & (0x1 << c->u.periph.clk_num)) ? ON : OFF;
+       c->mul = 1;
+       c->div = 1;
+
+       for (sel = c->inputs; sel->input != NULL; sel++) {
+               if (((val & periph_clk_source_mask(c)) >>
+                    periph_clk_source_shift(c)) == sel->value)
+                       mux = sel;
+       }
+       BUG_ON(!mux);
+       c->parent = mux->input;
+}
+
+static int tegra30_clk_out_enable(struct clk *c)
+{
+       u32 val;
+       unsigned long flags;
+
+       pr_debug("%s on clock %s\n", __func__, c->name);
+
+       spin_lock_irqsave(&clk_out_lock, flags);
+       val = pmc_readl(c->reg);
+       val |= (0x1 << c->u.periph.clk_num);
+       pmc_writel(val, c->reg);
+       spin_unlock_irqrestore(&clk_out_lock, flags);
+
+       return 0;
+}
+
+static void tegra30_clk_out_disable(struct clk *c)
+{
+       u32 val;
+       unsigned long flags;
+
+       pr_debug("%s on clock %s\n", __func__, c->name);
+
+       spin_lock_irqsave(&clk_out_lock, flags);
+       val = pmc_readl(c->reg);
+       val &= ~(0x1 << c->u.periph.clk_num);
+       pmc_writel(val, c->reg);
+       spin_unlock_irqrestore(&clk_out_lock, flags);
+}
+
+static int tegra30_clk_out_set_parent(struct clk *c, struct clk *p)
+{
+       u32 val;
+       unsigned long flags;
+       const struct clk_mux_sel *sel;
+
+       pr_debug("%s: %s %s\n", __func__, c->name, p->name);
+
+       for (sel = c->inputs; sel->input != NULL; sel++) {
+               if (sel->input == p) {
+                       if (c->refcnt)
+                               clk_enable(p);
+
+                       spin_lock_irqsave(&clk_out_lock, flags);
+                       val = pmc_readl(c->reg);
+                       val &= ~periph_clk_source_mask(c);
+                       val |= (sel->value << periph_clk_source_shift(c));
+                       pmc_writel(val, c->reg);
+                       spin_unlock_irqrestore(&clk_out_lock, flags);
+
+                       if (c->refcnt && c->parent)
+                               clk_disable(c->parent);
+
+                       clk_reparent(c, p);
+                       return 0;
+               }
+       }
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_clk_out_ops = {
+       .init                   = &tegra30_clk_out_init,
+       .enable                 = &tegra30_clk_out_enable,
+       .disable                = &tegra30_clk_out_disable,
+       .set_parent             = &tegra30_clk_out_set_parent,
+};
+
+
+/* Clock doubler ops */
+static void tegra30_clk_double_init(struct clk *c)
+{
+       u32 val = clk_readl(c->reg);
+       c->mul = val & (0x1 << c->reg_shift) ? 1 : 2;
+       c->div = 1;
+       c->state = ON;
+       if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c)))
+               c->state = OFF;
+};
+
+static int tegra30_clk_double_set_rate(struct clk *c, unsigned long rate)
+{
+       u32 val;
+       unsigned long parent_rate = clk_get_rate(c->parent);
+       if (rate == parent_rate) {
+               val = clk_readl(c->reg) | (0x1 << c->reg_shift);
+               clk_writel(val, c->reg);
+               c->mul = 1;
+               c->div = 1;
+               return 0;
+       } else if (rate == 2 * parent_rate) {
+               val = clk_readl(c->reg) & (~(0x1 << c->reg_shift));
+               clk_writel(val, c->reg);
+               c->mul = 2;
+               c->div = 1;
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_clk_double_ops = {
+       .init                   = &tegra30_clk_double_init,
+       .enable                 = &tegra30_periph_clk_enable,
+       .disable                = &tegra30_periph_clk_disable,
+       .set_rate               = &tegra30_clk_double_set_rate,
+};
+
+/* Audio sync clock ops */
+static int tegra30_sync_source_set_rate(struct clk *c, unsigned long rate)
+{
+       c->rate = rate;
+       return 0;
+}
+
+static struct clk_ops tegra_sync_source_ops = {
+       .set_rate               = &tegra30_sync_source_set_rate,
+};
+
+static void tegra30_audio_sync_clk_init(struct clk *c)
+{
+       int source;
+       const struct clk_mux_sel *sel;
+       u32 val = clk_readl(c->reg);
+       c->state = (val & AUDIO_SYNC_DISABLE_BIT) ? OFF : ON;
+       source = val & AUDIO_SYNC_SOURCE_MASK;
+       for (sel = c->inputs; sel->input != NULL; sel++)
+               if (sel->value == source)
+                       break;
+       BUG_ON(sel->input == NULL);
+       c->parent = sel->input;
+}
+
+static int tegra30_audio_sync_clk_enable(struct clk *c)
+{
+       u32 val = clk_readl(c->reg);
+       clk_writel((val & (~AUDIO_SYNC_DISABLE_BIT)), c->reg);
+       return 0;
+}
+
+static void tegra30_audio_sync_clk_disable(struct clk *c)
+{
+       u32 val = clk_readl(c->reg);
+       clk_writel((val | AUDIO_SYNC_DISABLE_BIT), c->reg);
+}
+
+static int tegra30_audio_sync_clk_set_parent(struct clk *c, struct clk *p)
+{
+       u32 val;
+       const struct clk_mux_sel *sel;
+       for (sel = c->inputs; sel->input != NULL; sel++) {
+               if (sel->input == p) {
+                       val = clk_readl(c->reg);
+                       val &= ~AUDIO_SYNC_SOURCE_MASK;
+                       val |= sel->value;
+
+                       if (c->refcnt)
+                               clk_enable(p);
+
+                       clk_writel(val, c->reg);
+
+                       if (c->refcnt && c->parent)
+                               clk_disable(c->parent);
+
+                       clk_reparent(c, p);
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_audio_sync_clk_ops = {
+       .init       = tegra30_audio_sync_clk_init,
+       .enable     = tegra30_audio_sync_clk_enable,
+       .disable    = tegra30_audio_sync_clk_disable,
+       .set_parent = tegra30_audio_sync_clk_set_parent,
+};
+
+/* cml0 (pcie), and cml1 (sata) clock ops */
+static void tegra30_cml_clk_init(struct clk *c)
+{
+       u32 val = clk_readl(c->reg);
+       c->state = val & (0x1 << c->u.periph.clk_num) ? ON : OFF;
+}
+
+static int tegra30_cml_clk_enable(struct clk *c)
+{
+       u32 val = clk_readl(c->reg);
+       val |= (0x1 << c->u.periph.clk_num);
+       clk_writel(val, c->reg);
+       return 0;
+}
+
+static void tegra30_cml_clk_disable(struct clk *c)
+{
+       u32 val = clk_readl(c->reg);
+       val &= ~(0x1 << c->u.periph.clk_num);
+       clk_writel(val, c->reg);
+}
+
+static struct clk_ops tegra_cml_clk_ops = {
+       .init                   = &tegra30_cml_clk_init,
+       .enable                 = &tegra30_cml_clk_enable,
+       .disable                = &tegra30_cml_clk_disable,
+};
+
+/* Clock definitions */
+static struct clk tegra_clk_32k = {
+       .name = "clk_32k",
+       .rate = 32768,
+       .ops  = NULL,
+       .max_rate = 32768,
+};
+
+static struct clk tegra_clk_m = {
+       .name      = "clk_m",
+       .flags     = ENABLE_ON_INIT,
+       .ops       = &tegra_clk_m_ops,
+       .reg       = 0x1fc,
+       .reg_shift = 28,
+       .max_rate  = 48000000,
+};
+
+static struct clk tegra_clk_m_div2 = {
+       .name      = "clk_m_div2",
+       .ops       = &tegra_clk_m_div_ops,
+       .parent    = &tegra_clk_m,
+       .mul       = 1,
+       .div       = 2,
+       .state     = ON,
+       .max_rate  = 24000000,
+};
+
+static struct clk tegra_clk_m_div4 = {
+       .name      = "clk_m_div4",
+       .ops       = &tegra_clk_m_div_ops,
+       .parent    = &tegra_clk_m,
+       .mul       = 1,
+       .div       = 4,
+       .state     = ON,
+       .max_rate  = 12000000,
+};
+
+static struct clk tegra_pll_ref = {
+       .name      = "pll_ref",
+       .flags     = ENABLE_ON_INIT,
+       .ops       = &tegra_pll_ref_ops,
+       .parent    = &tegra_clk_m,
+       .max_rate  = 26000000,
+};
+
+static struct clk_pll_freq_table tegra_pll_c_freq_table[] = {
+       { 12000000, 1040000000, 520,  6, 1, 8},
+       { 13000000, 1040000000, 480,  6, 1, 8},
+       { 16800000, 1040000000, 495,  8, 1, 8},         /* actual: 1039.5 MHz */
+       { 19200000, 1040000000, 325,  6, 1, 6},
+       { 26000000, 1040000000, 520, 13, 1, 8},
+
+       { 12000000, 832000000, 416,  6, 1, 8},
+       { 13000000, 832000000, 832, 13, 1, 8},
+       { 16800000, 832000000, 396,  8, 1, 8},          /* actual: 831.6 MHz */
+       { 19200000, 832000000, 260,  6, 1, 8},
+       { 26000000, 832000000, 416, 13, 1, 8},
+
+       { 12000000, 624000000, 624, 12, 1, 8},
+       { 13000000, 624000000, 624, 13, 1, 8},
+       { 16800000, 600000000, 520, 14, 1, 8},
+       { 19200000, 624000000, 520, 16, 1, 8},
+       { 26000000, 624000000, 624, 26, 1, 8},
+
+       { 12000000, 600000000, 600, 12, 1, 8},
+       { 13000000, 600000000, 600, 13, 1, 8},
+       { 16800000, 600000000, 500, 14, 1, 8},
+       { 19200000, 600000000, 375, 12, 1, 6},
+       { 26000000, 600000000, 600, 26, 1, 8},
+
+       { 12000000, 520000000, 520, 12, 1, 8},
+       { 13000000, 520000000, 520, 13, 1, 8},
+       { 16800000, 520000000, 495, 16, 1, 8},          /* actual: 519.75 MHz */
+       { 19200000, 520000000, 325, 12, 1, 6},
+       { 26000000, 520000000, 520, 26, 1, 8},
+
+       { 12000000, 416000000, 416, 12, 1, 8},
+       { 13000000, 416000000, 416, 13, 1, 8},
+       { 16800000, 416000000, 396, 16, 1, 8},          /* actual: 415.8 MHz */
+       { 19200000, 416000000, 260, 12, 1, 6},
+       { 26000000, 416000000, 416, 26, 1, 8},
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_c = {
+       .name      = "pll_c",
+       .flags     = PLL_HAS_CPCON,
+       .ops       = &tegra_pll_ops,
+       .reg       = 0x80,
+       .parent    = &tegra_pll_ref,
+       .max_rate  = 1400000000,
+       .u.pll = {
+               .input_min = 2000000,
+               .input_max = 31000000,
+               .cf_min    = 1000000,
+               .cf_max    = 6000000,
+               .vco_min   = 20000000,
+               .vco_max   = 1400000000,
+               .freq_table = tegra_pll_c_freq_table,
+               .lock_delay = 300,
+       },
+};
+
+static struct clk tegra_pll_c_out1 = {
+       .name      = "pll_c_out1",
+       .ops       = &tegra_pll_div_ops,
+       .flags     = DIV_U71,
+       .parent    = &tegra_pll_c,
+       .reg       = 0x84,
+       .reg_shift = 0,
+       .max_rate  = 700000000,
+};
+
+static struct clk_pll_freq_table tegra_pll_m_freq_table[] = {
+       { 12000000, 666000000, 666, 12, 1, 8},
+       { 13000000, 666000000, 666, 13, 1, 8},
+       { 16800000, 666000000, 555, 14, 1, 8},
+       { 19200000, 666000000, 555, 16, 1, 8},
+       { 26000000, 666000000, 666, 26, 1, 8},
+       { 12000000, 600000000, 600, 12, 1, 8},
+       { 13000000, 600000000, 600, 13, 1, 8},
+       { 16800000, 600000000, 500, 14, 1, 8},
+       { 19200000, 600000000, 375, 12, 1, 6},
+       { 26000000, 600000000, 600, 26, 1, 8},
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_m = {
+       .name      = "pll_m",
+       .flags     = PLL_HAS_CPCON | PLLM,
+       .ops       = &tegra_pll_ops,
+       .reg       = 0x90,
+       .parent    = &tegra_pll_ref,
+       .max_rate  = 800000000,
+       .u.pll = {
+               .input_min = 2000000,
+               .input_max = 31000000,
+               .cf_min    = 1000000,
+               .cf_max    = 6000000,
+               .vco_min   = 20000000,
+               .vco_max   = 1200000000,
+               .freq_table = tegra_pll_m_freq_table,
+               .lock_delay = 300,
+       },
+};
+
+static struct clk tegra_pll_m_out1 = {
+       .name      = "pll_m_out1",
+       .ops       = &tegra_pll_div_ops,
+       .flags     = DIV_U71,
+       .parent    = &tegra_pll_m,
+       .reg       = 0x94,
+       .reg_shift = 0,
+       .max_rate  = 600000000,
+};
+
+static struct clk_pll_freq_table tegra_pll_p_freq_table[] = {
+       { 12000000, 216000000, 432, 12, 2, 8},
+       { 13000000, 216000000, 432, 13, 2, 8},
+       { 16800000, 216000000, 360, 14, 2, 8},
+       { 19200000, 216000000, 360, 16, 2, 8},
+       { 26000000, 216000000, 432, 26, 2, 8},
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_p = {
+       .name      = "pll_p",
+       .flags     = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON,
+       .ops       = &tegra_pll_ops,
+       .reg       = 0xa0,
+       .parent    = &tegra_pll_ref,
+       .max_rate  = 432000000,
+       .u.pll = {
+               .input_min = 2000000,
+               .input_max = 31000000,
+               .cf_min    = 1000000,
+               .cf_max    = 6000000,
+               .vco_min   = 20000000,
+               .vco_max   = 1400000000,
+               .freq_table = tegra_pll_p_freq_table,
+               .lock_delay = 300,
+               .fixed_rate = 408000000,
+       },
+};
+
+static struct clk tegra_pll_p_out1 = {
+       .name      = "pll_p_out1",
+       .ops       = &tegra_pll_div_ops,
+       .flags     = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+       .parent    = &tegra_pll_p,
+       .reg       = 0xa4,
+       .reg_shift = 0,
+       .max_rate  = 432000000,
+};
+
+static struct clk tegra_pll_p_out2 = {
+       .name      = "pll_p_out2",
+       .ops       = &tegra_pll_div_ops,
+       .flags     = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+       .parent    = &tegra_pll_p,
+       .reg       = 0xa4,
+       .reg_shift = 16,
+       .max_rate  = 432000000,
+};
+
+static struct clk tegra_pll_p_out3 = {
+       .name      = "pll_p_out3",
+       .ops       = &tegra_pll_div_ops,
+       .flags     = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+       .parent    = &tegra_pll_p,
+       .reg       = 0xa8,
+       .reg_shift = 0,
+       .max_rate  = 432000000,
+};
+
+static struct clk tegra_pll_p_out4 = {
+       .name      = "pll_p_out4",
+       .ops       = &tegra_pll_div_ops,
+       .flags     = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+       .parent    = &tegra_pll_p,
+       .reg       = 0xa8,
+       .reg_shift = 16,
+       .max_rate  = 432000000,
+};
+
+static struct clk_pll_freq_table tegra_pll_a_freq_table[] = {
+       { 9600000, 564480000, 294, 5, 1, 4},
+       { 9600000, 552960000, 288, 5, 1, 4},
+       { 9600000, 24000000,  5,   2, 1, 1},
+
+       { 28800000, 56448000, 49, 25, 1, 1},
+       { 28800000, 73728000, 64, 25, 1, 1},
+       { 28800000, 24000000,  5,  6, 1, 1},
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_a = {
+       .name      = "pll_a",
+       .flags     = PLL_HAS_CPCON,
+       .ops       = &tegra_pll_ops,
+       .reg       = 0xb0,
+       .parent    = &tegra_pll_p_out1,
+       .max_rate  = 700000000,
+       .u.pll = {
+               .input_min = 2000000,
+               .input_max = 31000000,
+               .cf_min    = 1000000,
+               .cf_max    = 6000000,
+               .vco_min   = 20000000,
+               .vco_max   = 1400000000,
+               .freq_table = tegra_pll_a_freq_table,
+               .lock_delay = 300,
+       },
+};
+
+static struct clk tegra_pll_a_out0 = {
+       .name      = "pll_a_out0",
+       .ops       = &tegra_pll_div_ops,
+       .flags     = DIV_U71,
+       .parent    = &tegra_pll_a,
+       .reg       = 0xb4,
+       .reg_shift = 0,
+       .max_rate  = 100000000,
+};
+
+static struct clk_pll_freq_table tegra_pll_d_freq_table[] = {
+       { 12000000, 216000000, 216, 12, 1, 4},
+       { 13000000, 216000000, 216, 13, 1, 4},
+       { 16800000, 216000000, 180, 14, 1, 4},
+       { 19200000, 216000000, 180, 16, 1, 4},
+       { 26000000, 216000000, 216, 26, 1, 4},
+
+       { 12000000, 594000000, 594, 12, 1, 8},
+       { 13000000, 594000000, 594, 13, 1, 8},
+       { 16800000, 594000000, 495, 14, 1, 8},
+       { 19200000, 594000000, 495, 16, 1, 8},
+       { 26000000, 594000000, 594, 26, 1, 8},
+
+       { 12000000, 1000000000, 1000, 12, 1, 12},
+       { 13000000, 1000000000, 1000, 13, 1, 12},
+       { 19200000, 1000000000, 625,  12, 1, 8},
+       { 26000000, 1000000000, 1000, 26, 1, 12},
+
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_d = {
+       .name      = "pll_d",
+       .flags     = PLL_HAS_CPCON | PLLD,
+       .ops       = &tegra_plld_ops,
+       .reg       = 0xd0,
+       .parent    = &tegra_pll_ref,
+       .max_rate  = 1000000000,
+       .u.pll = {
+               .input_min = 2000000,
+               .input_max = 40000000,
+               .cf_min    = 1000000,
+               .cf_max    = 6000000,
+               .vco_min   = 40000000,
+               .vco_max   = 1000000000,
+               .freq_table = tegra_pll_d_freq_table,
+               .lock_delay = 1000,
+       },
+};
+
+static struct clk tegra_pll_d_out0 = {
+       .name      = "pll_d_out0",
+       .ops       = &tegra_pll_div_ops,
+       .flags     = DIV_2 | PLLD,
+       .parent    = &tegra_pll_d,
+       .max_rate  = 500000000,
+};
+
+static struct clk tegra_pll_d2 = {
+       .name      = "pll_d2",
+       .flags     = PLL_HAS_CPCON | PLL_ALT_MISC_REG | PLLD,
+       .ops       = &tegra_plld_ops,
+       .reg       = 0x4b8,
+       .parent    = &tegra_pll_ref,
+       .max_rate  = 1000000000,
+       .u.pll = {
+               .input_min = 2000000,
+               .input_max = 40000000,
+               .cf_min    = 1000000,
+               .cf_max    = 6000000,
+               .vco_min   = 40000000,
+               .vco_max   = 1000000000,
+               .freq_table = tegra_pll_d_freq_table,
+               .lock_delay = 1000,
+       },
+};
+
+static struct clk tegra_pll_d2_out0 = {
+       .name      = "pll_d2_out0",
+       .ops       = &tegra_pll_div_ops,
+       .flags     = DIV_2 | PLLD,
+       .parent    = &tegra_pll_d2,
+       .max_rate  = 500000000,
+};
+
+static struct clk_pll_freq_table tegra_pll_u_freq_table[] = {
+       { 12000000, 480000000, 960, 12, 2, 12},
+       { 13000000, 480000000, 960, 13, 2, 12},
+       { 16800000, 480000000, 400, 7,  2, 5},
+       { 19200000, 480000000, 200, 4,  2, 3},
+       { 26000000, 480000000, 960, 26, 2, 12},
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_u = {
+       .name      = "pll_u",
+       .flags     = PLL_HAS_CPCON | PLLU,
+       .ops       = &tegra_pll_ops,
+       .reg       = 0xc0,
+       .parent    = &tegra_pll_ref,
+       .max_rate  = 480000000,
+       .u.pll = {
+               .input_min = 2000000,
+               .input_max = 40000000,
+               .cf_min    = 1000000,
+               .cf_max    = 6000000,
+               .vco_min   = 480000000,
+               .vco_max   = 960000000,
+               .freq_table = tegra_pll_u_freq_table,
+               .lock_delay = 1000,
+       },
+};
+
+static struct clk_pll_freq_table tegra_pll_x_freq_table[] = {
+       /* 1.7 GHz */
+       { 12000000, 1700000000, 850,  6,  1, 8},
+       { 13000000, 1700000000, 915,  7,  1, 8},        /* actual: 1699.2 MHz */
+       { 16800000, 1700000000, 708,  7,  1, 8},        /* actual: 1699.2 MHz */
+       { 19200000, 1700000000, 885,  10, 1, 8},        /* actual: 1699.2 MHz */
+       { 26000000, 1700000000, 850,  13, 1, 8},
+
+       /* 1.6 GHz */
+       { 12000000, 1600000000, 800,  6,  1, 8},
+       { 13000000, 1600000000, 738,  6,  1, 8},        /* actual: 1599.0 MHz */
+       { 16800000, 1600000000, 857,  9,  1, 8},        /* actual: 1599.7 MHz */
+       { 19200000, 1600000000, 500,  6,  1, 8},
+       { 26000000, 1600000000, 800,  13, 1, 8},
+
+       /* 1.5 GHz */
+       { 12000000, 1500000000, 750,  6,  1, 8},
+       { 13000000, 1500000000, 923,  8,  1, 8},        /* actual: 1499.8 MHz */
+       { 16800000, 1500000000, 625,  7,  1, 8},
+       { 19200000, 1500000000, 625,  8,  1, 8},
+       { 26000000, 1500000000, 750,  13, 1, 8},
+
+       /* 1.4 GHz */
+       { 12000000, 1400000000, 700,  6,  1, 8},
+       { 13000000, 1400000000, 969,  9,  1, 8},        /* actual: 1399.7 MHz */
+       { 16800000, 1400000000, 1000, 12, 1, 8},
+       { 19200000, 1400000000, 875,  12, 1, 8},
+       { 26000000, 1400000000, 700,  13, 1, 8},
+
+       /* 1.3 GHz */
+       { 12000000, 1300000000, 975,  9,  1, 8},
+       { 13000000, 1300000000, 1000, 10, 1, 8},
+       { 16800000, 1300000000, 928,  12, 1, 8},        /* actual: 1299.2 MHz */
+       { 19200000, 1300000000, 812,  12, 1, 8},        /* actual: 1299.2 MHz */
+       { 26000000, 1300000000, 650,  13, 1, 8},
+
+       /* 1.2 GHz */
+       { 12000000, 1200000000, 1000, 10, 1, 8},
+       { 13000000, 1200000000, 923,  10, 1, 8},        /* actual: 1199.9 MHz */
+       { 16800000, 1200000000, 1000, 14, 1, 8},
+       { 19200000, 1200000000, 1000, 16, 1, 8},
+       { 26000000, 1200000000, 600,  13, 1, 8},
+
+       /* 1.1 GHz */
+       { 12000000, 1100000000, 825,  9,  1, 8},
+       { 13000000, 1100000000, 846,  10, 1, 8},        /* actual: 1099.8 MHz */
+       { 16800000, 1100000000, 982,  15, 1, 8},        /* actual: 1099.8 MHz */
+       { 19200000, 1100000000, 859,  15, 1, 8},        /* actual: 1099.5 MHz */
+       { 26000000, 1100000000, 550,  13, 1, 8},
+
+       /* 1 GHz */
+       { 12000000, 1000000000, 1000, 12, 1, 8},
+       { 13000000, 1000000000, 1000, 13, 1, 8},
+       { 16800000, 1000000000, 833,  14, 1, 8},        /* actual: 999.6 MHz */
+       { 19200000, 1000000000, 625,  12, 1, 8},
+       { 26000000, 1000000000, 1000, 26, 1, 8},
+
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_x = {
+       .name      = "pll_x",
+       .flags     = PLL_HAS_CPCON | PLL_ALT_MISC_REG | PLLX,
+       .ops       = &tegra_pll_ops,
+       .reg       = 0xe0,
+       .parent    = &tegra_pll_ref,
+       .max_rate  = 1700000000,
+       .u.pll = {
+               .input_min = 2000000,
+               .input_max = 31000000,
+               .cf_min    = 1000000,
+               .cf_max    = 6000000,
+               .vco_min   = 20000000,
+               .vco_max   = 1700000000,
+               .freq_table = tegra_pll_x_freq_table,
+               .lock_delay = 300,
+       },
+};
+
+static struct clk tegra_pll_x_out0 = {
+       .name      = "pll_x_out0",
+       .ops       = &tegra_pll_div_ops,
+       .flags     = DIV_2 | PLLX,
+       .parent    = &tegra_pll_x,
+       .max_rate  = 850000000,
+};
+
+
+static struct clk_pll_freq_table tegra_pll_e_freq_table[] = {
+       /* PLLE special case: use cpcon field to store cml divider value */
+       { 12000000,  100000000, 150, 1,  18, 11},
+       { 216000000, 100000000, 200, 18, 24, 13},
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_e = {
+       .name      = "pll_e",
+       .flags     = PLL_ALT_MISC_REG,
+       .ops       = &tegra_plle_ops,
+       .reg       = 0xe8,
+       .max_rate  = 100000000,
+       .u.pll = {
+               .input_min = 12000000,
+               .input_max = 216000000,
+               .cf_min    = 12000000,
+               .cf_max    = 12000000,
+               .vco_min   = 1200000000,
+               .vco_max   = 2400000000U,
+               .freq_table = tegra_pll_e_freq_table,
+               .lock_delay = 300,
+               .fixed_rate = 100000000,
+       },
+};
+
+static struct clk tegra_cml0_clk = {
+       .name      = "cml0",
+       .parent    = &tegra_pll_e,
+       .ops       = &tegra_cml_clk_ops,
+       .reg       = PLLE_AUX,
+       .max_rate  = 100000000,
+       .u.periph  = {
+               .clk_num = 0,
+       },
+};
+
+static struct clk tegra_cml1_clk = {
+       .name      = "cml1",
+       .parent    = &tegra_pll_e,
+       .ops       = &tegra_cml_clk_ops,
+       .reg       = PLLE_AUX,
+       .max_rate  = 100000000,
+       .u.periph  = {
+               .clk_num   = 1,
+       },
+};
+
+static struct clk tegra_pciex_clk = {
+       .name      = "pciex",
+       .parent    = &tegra_pll_e,
+       .ops       = &tegra_pciex_clk_ops,
+       .max_rate  = 100000000,
+       .u.periph  = {
+               .clk_num   = 74,
+       },
+};
+
+/* Audio sync clocks */
+#define SYNC_SOURCE(_id)                               \
+       {                                               \
+               .name      = #_id "_sync",              \
+               .rate      = 24000000,                  \
+               .max_rate  = 24000000,                  \
+               .ops       = &tegra_sync_source_ops     \
+       }
+static struct clk tegra_sync_source_list[] = {
+       SYNC_SOURCE(spdif_in),
+       SYNC_SOURCE(i2s0),
+       SYNC_SOURCE(i2s1),
+       SYNC_SOURCE(i2s2),
+       SYNC_SOURCE(i2s3),
+       SYNC_SOURCE(i2s4),
+       SYNC_SOURCE(vimclk),
+};
+
+static struct clk_mux_sel mux_audio_sync_clk[] = {
+       { .input = &tegra_sync_source_list[0],  .value = 0},
+       { .input = &tegra_sync_source_list[1],  .value = 1},
+       { .input = &tegra_sync_source_list[2],  .value = 2},
+       { .input = &tegra_sync_source_list[3],  .value = 3},
+       { .input = &tegra_sync_source_list[4],  .value = 4},
+       { .input = &tegra_sync_source_list[5],  .value = 5},
+       { .input = &tegra_pll_a_out0,           .value = 6},
+       { .input = &tegra_sync_source_list[6],  .value = 7},
+       { 0, 0 }
+};
+
+#define AUDIO_SYNC_CLK(_id, _index)                    \
+       {                                               \
+               .name      = #_id,                      \
+               .inputs    = mux_audio_sync_clk,        \
+               .reg       = 0x4A0 + (_index) * 4,      \
+               .max_rate  = 24000000,                  \
+               .ops       = &tegra_audio_sync_clk_ops  \
+       }
+static struct clk tegra_clk_audio_list[] = {
+       AUDIO_SYNC_CLK(audio0, 0),
+       AUDIO_SYNC_CLK(audio1, 1),
+       AUDIO_SYNC_CLK(audio2, 2),
+       AUDIO_SYNC_CLK(audio3, 3),
+       AUDIO_SYNC_CLK(audio4, 4),
+       AUDIO_SYNC_CLK(audio, 5),       /* SPDIF */
+};
+
+#define AUDIO_SYNC_2X_CLK(_id, _index)                         \
+       {                                                       \
+               .name      = #_id "_2x",                        \
+               .flags     = PERIPH_NO_RESET,                   \
+               .max_rate  = 48000000,                          \
+               .ops       = &tegra_clk_double_ops,             \
+               .reg       = 0x49C,                             \
+               .reg_shift = 24 + (_index),                     \
+               .parent    = &tegra_clk_audio_list[(_index)],   \
+               .u.periph = {                                   \
+                       .clk_num = 113 + (_index),              \
+               },                                              \
+       }
+static struct clk tegra_clk_audio_2x_list[] = {
+       AUDIO_SYNC_2X_CLK(audio0, 0),
+       AUDIO_SYNC_2X_CLK(audio1, 1),
+       AUDIO_SYNC_2X_CLK(audio2, 2),
+       AUDIO_SYNC_2X_CLK(audio3, 3),
+       AUDIO_SYNC_2X_CLK(audio4, 4),
+       AUDIO_SYNC_2X_CLK(audio, 5),    /* SPDIF */
+};
+
+#define MUX_I2S_SPDIF(_id, _index)                                     \
+static struct clk_mux_sel mux_pllaout0_##_id##_2x_pllp_clkm[] = {      \
+       {.input = &tegra_pll_a_out0, .value = 0},                       \
+       {.input = &tegra_clk_audio_2x_list[(_index)], .value = 1},      \
+       {.input = &tegra_pll_p, .value = 2},                            \
+       {.input = &tegra_clk_m, .value = 3},                            \
+       { 0, 0},                                                        \
+}
+MUX_I2S_SPDIF(audio0, 0);
+MUX_I2S_SPDIF(audio1, 1);
+MUX_I2S_SPDIF(audio2, 2);
+MUX_I2S_SPDIF(audio3, 3);
+MUX_I2S_SPDIF(audio4, 4);
+MUX_I2S_SPDIF(audio, 5);               /* SPDIF */
+
+/* External clock outputs (through PMC) */
+#define MUX_EXTERN_OUT(_id)                                            \
+static struct clk_mux_sel mux_clkm_clkm2_clkm4_extern##_id[] = {       \
+       {.input = &tegra_clk_m,         .value = 0},                    \
+       {.input = &tegra_clk_m_div2,    .value = 1},                    \
+       {.input = &tegra_clk_m_div4,    .value = 2},                    \
+       {.input = NULL,                 .value = 3}, /* placeholder */  \
+       { 0, 0},                                                        \
+}
+MUX_EXTERN_OUT(1);
+MUX_EXTERN_OUT(2);
+MUX_EXTERN_OUT(3);
+
+static struct clk_mux_sel *mux_extern_out_list[] = {
+       mux_clkm_clkm2_clkm4_extern1,
+       mux_clkm_clkm2_clkm4_extern2,
+       mux_clkm_clkm2_clkm4_extern3,
+};
+
+#define CLK_OUT_CLK(_id)                                       \
+       {                                                       \
+               .name      = "clk_out_" #_id,                   \
+               .lookup    = {                                  \
+                       .dev_id    = "clk_out_" #_id,           \
+                       .con_id    = "extern" #_id,             \
+               },                                              \
+               .ops       = &tegra_clk_out_ops,                \
+               .reg       = 0x1a8,                             \
+               .inputs    = mux_clkm_clkm2_clkm4_extern##_id,  \
+               .flags     = MUX_CLK_OUT,                       \
+               .max_rate  = 216000000,                         \
+               .u.periph = {                                   \
+                       .clk_num   = (_id - 1) * 8 + 2,         \
+               },                                              \
+       }
+static struct clk tegra_clk_out_list[] = {
+       CLK_OUT_CLK(1),
+       CLK_OUT_CLK(2),
+       CLK_OUT_CLK(3),
+};
+
+/* called after peripheral external clocks are initialized */
+static void init_clk_out_mux(void)
+{
+       int i;
+       struct clk *c;
+
+       /* output clock con_id is the name of peripheral
+          external clock connected to input 3 of the output mux */
+       for (i = 0; i < ARRAY_SIZE(tegra_clk_out_list); i++) {
+               c = tegra_get_clock_by_name(
+                       tegra_clk_out_list[i].lookup.con_id);
+               if (!c)
+                       pr_err("%s: could not find clk %s\n", __func__,
+                              tegra_clk_out_list[i].lookup.con_id);
+               mux_extern_out_list[i][3].input = c;
+       }
+}
+
+/* Peripheral muxes */
+static struct clk_mux_sel mux_sclk[] = {
+       { .input = &tegra_clk_m,        .value = 0},
+       { .input = &tegra_pll_c_out1,   .value = 1},
+       { .input = &tegra_pll_p_out4,   .value = 2},
+       { .input = &tegra_pll_p_out3,   .value = 3},
+       { .input = &tegra_pll_p_out2,   .value = 4},
+       /* { .input = &tegra_clk_d,     .value = 5}, - no use on tegra30 */
+       { .input = &tegra_clk_32k,      .value = 6},
+       { .input = &tegra_pll_m_out1,   .value = 7},
+       { 0, 0},
+};
+
+static struct clk tegra_clk_sclk = {
+       .name   = "sclk",
+       .inputs = mux_sclk,
+       .reg    = 0x28,
+       .ops    = &tegra_super_ops,
+       .max_rate = 334000000,
+       .min_rate = 40000000,
+};
+
+static struct clk tegra_clk_blink = {
+       .name           = "blink",
+       .parent         = &tegra_clk_32k,
+       .reg            = 0x40,
+       .ops            = &tegra_blink_clk_ops,
+       .max_rate       = 32768,
+};
+
+static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
+       { .input = &tegra_pll_m, .value = 0},
+       { .input = &tegra_pll_c, .value = 1},
+       { .input = &tegra_pll_p, .value = 2},
+       { .input = &tegra_pll_a_out0, .value = 3},
+       { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = {
+       { .input = &tegra_pll_p, .value = 0},
+       { .input = &tegra_pll_c, .value = 1},
+       { .input = &tegra_pll_m, .value = 2},
+       { .input = &tegra_clk_m, .value = 3},
+       { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_clkm[] = {
+       { .input = &tegra_pll_p, .value = 0},
+       { .input = &tegra_clk_m, .value = 3},
+       { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = {
+       {.input = &tegra_pll_p, .value = 0},
+       {.input = &tegra_pll_d_out0, .value = 1},
+       {.input = &tegra_pll_c, .value = 2},
+       {.input = &tegra_clk_m, .value = 3},
+       { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = {
+       {.input = &tegra_pll_p, .value = 0},
+       {.input = &tegra_pll_m, .value = 1},
+       {.input = &tegra_pll_d_out0, .value = 2},
+       {.input = &tegra_pll_a_out0, .value = 3},
+       {.input = &tegra_pll_c, .value = 4},
+       {.input = &tegra_pll_d2_out0, .value = 5},
+       {.input = &tegra_clk_m, .value = 6},
+       { 0, 0},
+};
+
+static struct clk_mux_sel mux_plla_pllc_pllp_clkm[] = {
+       { .input = &tegra_pll_a_out0, .value = 0},
+       /* { .input = &tegra_pll_c, .value = 1}, no use on tegra30 */
+       { .input = &tegra_pll_p, .value = 2},
+       { .input = &tegra_clk_m, .value = 3},
+       { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllc_clk32_clkm[] = {
+       {.input = &tegra_pll_p,     .value = 0},
+       {.input = &tegra_pll_c,     .value = 1},
+       {.input = &tegra_clk_32k,   .value = 2},
+       {.input = &tegra_clk_m,     .value = 3},
+       { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllc_clkm_clk32[] = {
+       {.input = &tegra_pll_p,     .value = 0},
+       {.input = &tegra_pll_c,     .value = 1},
+       {.input = &tegra_clk_m,     .value = 2},
+       {.input = &tegra_clk_32k,   .value = 3},
+       { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllc_pllm[] = {
+       {.input = &tegra_pll_p,     .value = 0},
+       {.input = &tegra_pll_c,     .value = 1},
+       {.input = &tegra_pll_m,     .value = 2},
+       { 0, 0},
+};
+
+static struct clk_mux_sel mux_clk_m[] = {
+       { .input = &tegra_clk_m, .value = 0},
+       { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_out3[] = {
+       { .input = &tegra_pll_p_out3, .value = 0},
+       { 0, 0},
+};
+
+static struct clk_mux_sel mux_plld_out0[] = {
+       { .input = &tegra_pll_d_out0, .value = 0},
+       { 0, 0},
+};
+
+static struct clk_mux_sel mux_plld_out0_plld2_out0[] = {
+       { .input = &tegra_pll_d_out0,  .value = 0},
+       { .input = &tegra_pll_d2_out0, .value = 1},
+       { 0, 0},
+};
+
+static struct clk_mux_sel mux_clk_32k[] = {
+       { .input = &tegra_clk_32k, .value = 0},
+       { 0, 0},
+};
+
+static struct clk_mux_sel mux_plla_clk32_pllp_clkm_plle[] = {
+       { .input = &tegra_pll_a_out0, .value = 0},
+       { .input = &tegra_clk_32k,    .value = 1},
+       { .input = &tegra_pll_p,      .value = 2},
+       { .input = &tegra_clk_m,      .value = 3},
+       { .input = &tegra_pll_e,      .value = 4},
+       { 0, 0},
+};
+
+static struct clk_mux_sel mux_cclk_g[] = {
+       { .input = &tegra_clk_m,        .value = 0},
+       { .input = &tegra_pll_c,        .value = 1},
+       { .input = &tegra_clk_32k,      .value = 2},
+       { .input = &tegra_pll_m,        .value = 3},
+       { .input = &tegra_pll_p,        .value = 4},
+       { .input = &tegra_pll_p_out4,   .value = 5},
+       { .input = &tegra_pll_p_out3,   .value = 6},
+       { .input = &tegra_pll_x,        .value = 8},
+       { 0, 0},
+};
+
+static struct clk tegra_clk_cclk_g = {
+       .name   = "cclk_g",
+       .flags  = DIV_U71 | DIV_U71_INT,
+       .inputs = mux_cclk_g,
+       .reg    = 0x368,
+       .ops    = &tegra_super_ops,
+       .max_rate = 1700000000,
+};
+
+static struct clk tegra30_clk_twd = {
+       .parent   = &tegra_clk_cclk_g,
+       .name     = "twd",
+       .ops      = &tegra30_twd_ops,
+       .max_rate = 1400000000, /* Same as tegra_clk_cpu_cmplx.max_rate */
+       .mul      = 1,
+       .div      = 2,
+};
+
+#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \
+       {                                               \
+               .name      = _name,                     \
+               .lookup    = {                          \
+                       .dev_id    = _dev,              \
+                       .con_id    = _con,              \
+               },                                      \
+               .ops       = &tegra_periph_clk_ops,     \
+               .reg       = _reg,                      \
+               .inputs    = _inputs,                   \
+               .flags     = _flags,                    \
+               .max_rate  = _max,                      \
+               .u.periph = {                           \
+                       .clk_num   = _clk_num,          \
+               },                                      \
+       }
+
+#define PERIPH_CLK_EX(_name, _dev, _con, _clk_num, _reg, _max, _inputs,        \
+                       _flags, _ops)                                   \
+       {                                               \
+               .name      = _name,                     \
+               .lookup    = {                          \
+                       .dev_id    = _dev,              \
+                       .con_id    = _con,              \
+               },                                      \
+               .ops       = _ops,                      \
+               .reg       = _reg,                      \
+               .inputs    = _inputs,                   \
+               .flags     = _flags,                    \
+               .max_rate  = _max,                      \
+               .u.periph = {                           \
+                       .clk_num   = _clk_num,          \
+               },                                      \
+       }
+
+#define SHARED_CLK(_name, _dev, _con, _parent, _id, _div, _mode)\
+       {                                               \
+               .name      = _name,                     \
+               .lookup    = {                          \
+                       .dev_id    = _dev,              \
+                       .con_id    = _con,              \
+               },                                      \
+               .ops       = &tegra_clk_shared_bus_ops, \
+               .parent = _parent,                      \
+               .u.shared_bus_user = {                  \
+                       .client_id = _id,               \
+                       .client_div = _div,             \
+                       .mode = _mode,                  \
+               },                                      \
+       }
+struct clk tegra_list_clks[] = {
+       PERIPH_CLK("apbdma",    "tegra-dma",            NULL,   34,     0,      26000000,  mux_clk_m,                   0),
+       PERIPH_CLK("rtc",       "rtc-tegra",            NULL,   4,      0,      32768,     mux_clk_32k,                 PERIPH_NO_RESET | PERIPH_ON_APB),
+       PERIPH_CLK("kbc",       "tegra-kbc",            NULL,   36,     0,      32768,     mux_clk_32k,                 PERIPH_NO_RESET | PERIPH_ON_APB),
+       PERIPH_CLK("timer",     "timer",                NULL,   5,      0,      26000000,  mux_clk_m,                   0),
+       PERIPH_CLK("kfuse",     "kfuse-tegra",          NULL,   40,     0,      26000000,  mux_clk_m,                   0),
+       PERIPH_CLK("fuse",      "fuse-tegra",           "fuse", 39,     0,      26000000,  mux_clk_m,                   PERIPH_ON_APB),
+       PERIPH_CLK("fuse_burn", "fuse-tegra",           "fuse_burn",    39,     0,      26000000,  mux_clk_m,           PERIPH_ON_APB),
+       PERIPH_CLK("apbif",     "tegra30-ahub",         "apbif", 107,   0,      26000000,  mux_clk_m,                   0),
+       PERIPH_CLK("i2s0",      "tegra30-i2s.0",        NULL,   30,     0x1d8,  26000000,  mux_pllaout0_audio0_2x_pllp_clkm,    MUX | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("i2s1",      "tegra30-i2s.1",        NULL,   11,     0x100,  26000000,  mux_pllaout0_audio1_2x_pllp_clkm,    MUX | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("i2s2",      "tegra30-i2s.2",        NULL,   18,     0x104,  26000000,  mux_pllaout0_audio2_2x_pllp_clkm,    MUX | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("i2s3",      "tegra30-i2s.3",        NULL,   101,    0x3bc,  26000000,  mux_pllaout0_audio3_2x_pllp_clkm,    MUX | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("i2s4",      "tegra30-i2s.4",        NULL,   102,    0x3c0,  26000000,  mux_pllaout0_audio4_2x_pllp_clkm,    MUX | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("spdif_out", "tegra30-spdif",        "spdif_out",    10,     0x108,  100000000, mux_pllaout0_audio_2x_pllp_clkm,     MUX | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("spdif_in",  "tegra30-spdif",        "spdif_in",     10,     0x10c,  100000000, mux_pllp_pllc_pllm,          MUX | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("pwm",       "pwm",                  NULL,   17,     0x110,  432000000, mux_pllp_pllc_clk32_clkm,    MUX | MUX_PWM | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("d_audio",   "tegra30-ahub",         "d_audio", 106, 0x3d0,  48000000,  mux_plla_pllc_pllp_clkm,     MUX | DIV_U71),
+       PERIPH_CLK("dam0",      "tegra30-dam.0",        NULL,   108,    0x3d8,  48000000,  mux_plla_pllc_pllp_clkm,     MUX | DIV_U71),
+       PERIPH_CLK("dam1",      "tegra30-dam.1",        NULL,   109,    0x3dc,  48000000,  mux_plla_pllc_pllp_clkm,     MUX | DIV_U71),
+       PERIPH_CLK("dam2",      "tegra30-dam.2",        NULL,   110,    0x3e0,  48000000,  mux_plla_pllc_pllp_clkm,     MUX | DIV_U71),
+       PERIPH_CLK("hda",       "tegra30-hda",          "hda",   125,   0x428,  108000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
+       PERIPH_CLK("hda2codec_2x",      "tegra30-hda",  "hda2codec",   111,     0x3e4,  48000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
+       PERIPH_CLK("hda2hdmi",  "tegra30-hda",          "hda2hdmi",     128,    0,      48000000,  mux_clk_m,                   0),
+       PERIPH_CLK("sbc1",      "spi_tegra.0",          NULL,   41,     0x134,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("sbc2",      "spi_tegra.1",          NULL,   44,     0x118,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("sbc3",      "spi_tegra.2",          NULL,   46,     0x11c,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("sbc4",      "spi_tegra.3",          NULL,   68,     0x1b4,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("sbc5",      "spi_tegra.4",          NULL,   104,    0x3c8,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("sbc6",      "spi_tegra.5",          NULL,   105,    0x3cc,  160000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("sata_oob",  "tegra_sata_oob",       NULL,   123,    0x420,  216000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
+       PERIPH_CLK("sata",      "tegra_sata",           NULL,   124,    0x424,  216000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
+       PERIPH_CLK("sata_cold", "tegra_sata_cold",      NULL,   129,    0,      48000000,  mux_clk_m,                   0),
+       PERIPH_CLK_EX("ndflash", "tegra_nand",          NULL,   13,     0x160,  240000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71,  &tegra_nand_clk_ops),
+       PERIPH_CLK("ndspeed",   "tegra_nand_speed",     NULL,   80,     0x3f8,  240000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
+       PERIPH_CLK("vfir",      "vfir",                 NULL,   7,      0x168,  72000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("sdmmc1",    "sdhci-tegra.0",        NULL,   14,     0x150,  208000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* scales with voltage */
+       PERIPH_CLK("sdmmc2",    "sdhci-tegra.1",        NULL,   9,      0x154,  104000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* scales with voltage */
+       PERIPH_CLK("sdmmc3",    "sdhci-tegra.2",        NULL,   69,     0x1bc,  208000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* scales with voltage */
+       PERIPH_CLK("sdmmc4",    "sdhci-tegra.3",        NULL,   15,     0x164,  104000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* scales with voltage */
+       PERIPH_CLK("vcp",       "tegra-avp",            "vcp",  29,     0,      250000000, mux_clk_m,                   0),
+       PERIPH_CLK("bsea",      "tegra-avp",            "bsea", 62,     0,      250000000, mux_clk_m,                   0),
+       PERIPH_CLK("bsev",      "tegra-aes",            "bsev", 63,     0,      250000000, mux_clk_m,                   0),
+       PERIPH_CLK("vde",       "vde",                  NULL,   61,     0x1c8,  520000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_INT),
+       PERIPH_CLK("csite",     "csite",                NULL,   73,     0x1d4,  144000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* max rate ??? */
+       PERIPH_CLK("la",        "la",                   NULL,   76,     0x1f8,  26000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71),
+       PERIPH_CLK("owr",       "tegra_w1",             NULL,   71,     0x1cc,  26000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("nor",       "nor",                  NULL,   42,     0x1d0,  127000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71), /* requires min voltage */
+       PERIPH_CLK("mipi",      "mipi",                 NULL,   50,     0x174,  60000000,  mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | PERIPH_ON_APB), /* scales with voltage */
+       PERIPH_CLK("i2c1",      "tegra-i2c.0",          NULL,   12,     0x124,  26000000,  mux_pllp_clkm,               MUX | DIV_U16 | PERIPH_ON_APB),
+       PERIPH_CLK("i2c2",      "tegra-i2c.1",          NULL,   54,     0x198,  26000000,  mux_pllp_clkm,               MUX | DIV_U16 | PERIPH_ON_APB),
+       PERIPH_CLK("i2c3",      "tegra-i2c.2",          NULL,   67,     0x1b8,  26000000,  mux_pllp_clkm,               MUX | DIV_U16 | PERIPH_ON_APB),
+       PERIPH_CLK("i2c4",      "tegra-i2c.3",          NULL,   103,    0x3c4,  26000000,  mux_pllp_clkm,               MUX | DIV_U16 | PERIPH_ON_APB),
+       PERIPH_CLK("i2c5",      "tegra-i2c.4",          NULL,   47,     0x128,  26000000,  mux_pllp_clkm,               MUX | DIV_U16 | PERIPH_ON_APB),
+       PERIPH_CLK("uarta",     "tegra_uart.0",         NULL,   6,      0x178,  800000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+       PERIPH_CLK("uartb",     "tegra_uart.1",         NULL,   7,      0x17c,  800000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+       PERIPH_CLK("uartc",     "tegra_uart.2",         NULL,   55,     0x1a0,  800000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+       PERIPH_CLK("uartd",     "tegra_uart.3",         NULL,   65,     0x1c0,  800000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+       PERIPH_CLK("uarte",     "tegra_uart.4",         NULL,   66,     0x1c4,  800000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+       PERIPH_CLK("uarta_dbg", "serial8250.0",         "uarta", 6,     0x178,  800000000, mux_pllp_clkm,               MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+       PERIPH_CLK("uartb_dbg", "serial8250.0",         "uartb", 7,     0x17c,  800000000, mux_pllp_clkm,               MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+       PERIPH_CLK("uartc_dbg", "serial8250.0",         "uartc", 55,    0x1a0,  800000000, mux_pllp_clkm,               MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+       PERIPH_CLK("uartd_dbg", "serial8250.0",         "uartd", 65,    0x1c0,  800000000, mux_pllp_clkm,               MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+       PERIPH_CLK("uarte_dbg", "serial8250.0",         "uarte", 66,    0x1c4,  800000000, mux_pllp_clkm,               MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+       PERIPH_CLK_EX("vi",     "tegra_camera",         "vi",   20,     0x148,  425000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT,    &tegra_vi_clk_ops),
+       PERIPH_CLK("3d",        "3d",                   NULL,   24,     0x158,  520000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET),
+       PERIPH_CLK("3d2",       "3d2",                  NULL,   98,     0x3b0,  520000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET),
+       PERIPH_CLK("2d",        "2d",                   NULL,   21,     0x15c,  520000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE),
+       PERIPH_CLK("vi_sensor", "tegra_camera",         "vi_sensor",    20,     0x1a8,  150000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | PERIPH_NO_RESET),
+       PERIPH_CLK("epp",       "epp",                  NULL,   19,     0x16c,  520000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT),
+       PERIPH_CLK("mpe",       "mpe",                  NULL,   60,     0x170,  520000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT),
+       PERIPH_CLK("host1x",    "host1x",               NULL,   28,     0x180,  260000000, mux_pllm_pllc_pllp_plla,     MUX | DIV_U71 | DIV_U71_INT),
+       PERIPH_CLK("cve",       "cve",                  NULL,   49,     0x140,  250000000, mux_pllp_plld_pllc_clkm,     MUX | DIV_U71), /* requires min voltage */
+       PERIPH_CLK("tvo",       "tvo",                  NULL,   49,     0x188,  250000000, mux_pllp_plld_pllc_clkm,     MUX | DIV_U71), /* requires min voltage */
+       PERIPH_CLK_EX("dtv",    "dtv",                  NULL,   79,     0x1dc,  250000000, mux_clk_m,                   0,              &tegra_dtv_clk_ops),
+       PERIPH_CLK("hdmi",      "hdmi",                 NULL,   51,     0x18c,  148500000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm,     MUX | MUX8 | DIV_U71),
+       PERIPH_CLK("tvdac",     "tvdac",                NULL,   53,     0x194,  220000000, mux_pllp_plld_pllc_clkm,     MUX | DIV_U71), /* requires min voltage */
+       PERIPH_CLK("disp1",     "tegradc.0",            NULL,   27,     0x138,  600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm,     MUX | MUX8),
+       PERIPH_CLK("disp2",     "tegradc.1",            NULL,   26,     0x13c,  600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm,     MUX | MUX8),
+       PERIPH_CLK("usbd",      "fsl-tegra-udc",        NULL,   22,     0,      480000000, mux_clk_m,                   0), /* requires min voltage */
+       PERIPH_CLK("usb2",      "tegra-ehci.1",         NULL,   58,     0,      480000000, mux_clk_m,                   0), /* requires min voltage */
+       PERIPH_CLK("usb3",      "tegra-ehci.2",         NULL,   59,     0,      480000000, mux_clk_m,                   0), /* requires min voltage */
+       PERIPH_CLK("dsia",      "tegradc.0",            "dsia", 48,     0,      500000000, mux_plld_out0,               0),
+       PERIPH_CLK_EX("dsib",   "tegradc.1",            "dsib", 82,     0xd0,   500000000, mux_plld_out0_plld2_out0,    MUX | PLLD,     &tegra_dsib_clk_ops),
+       PERIPH_CLK("csi",       "tegra_camera",         "csi",  52,     0,      102000000, mux_pllp_out3,               0),
+       PERIPH_CLK("isp",       "tegra_camera",         "isp",  23,     0,      150000000, mux_clk_m,                   0), /* same frequency as VI */
+       PERIPH_CLK("csus",      "tegra_camera",         "csus", 92,     0,      150000000, mux_clk_m,                   PERIPH_NO_RESET),
+
+       PERIPH_CLK("tsensor",   "tegra-tsensor",        NULL,   100,    0x3b8,  216000000, mux_pllp_pllc_clkm_clk32,    MUX | DIV_U71),
+       PERIPH_CLK("actmon",    "actmon",               NULL,   119,    0x3e8,  216000000, mux_pllp_pllc_clk32_clkm,    MUX | DIV_U71),
+       PERIPH_CLK("extern1",   "extern1",              NULL,   120,    0x3ec,  216000000, mux_plla_clk32_pllp_clkm_plle,       MUX | MUX8 | DIV_U71),
+       PERIPH_CLK("extern2",   "extern2",              NULL,   121,    0x3f0,  216000000, mux_plla_clk32_pllp_clkm_plle,       MUX | MUX8 | DIV_U71),
+       PERIPH_CLK("extern3",   "extern3",              NULL,   122,    0x3f4,  216000000, mux_plla_clk32_pllp_clkm_plle,       MUX | MUX8 | DIV_U71),
+       PERIPH_CLK("i2cslow",   "i2cslow",              NULL,   81,     0x3fc,  26000000,  mux_pllp_pllc_clk32_clkm,    MUX | DIV_U71 | PERIPH_ON_APB),
+       PERIPH_CLK("pcie",      "tegra-pcie",           "pcie", 70,     0,      250000000, mux_clk_m,                   0),
+       PERIPH_CLK("afi",       "tegra-pcie",           "afi",  72,     0,      250000000, mux_clk_m,                   0),
+       PERIPH_CLK("se",        "se",                   NULL,   127,    0x42c,  520000000, mux_pllp_pllc_pllm_clkm,     MUX | DIV_U71 | DIV_U71_INT),
+};
+
+#define CLK_DUPLICATE(_name, _dev, _con)               \
+       {                                               \
+               .name   = _name,                        \
+               .lookup = {                             \
+                       .dev_id = _dev,                 \
+                       .con_id         = _con,         \
+               },                                      \
+       }
+
+/* Some clocks may be used by different drivers depending on the board
+ * configuration.  List those here to register them twice in the clock lookup
+ * table under two names.
+ */
+struct clk_duplicate tegra_clk_duplicates[] = {
+       CLK_DUPLICATE("usbd", "utmip-pad", NULL),
+       CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL),
+       CLK_DUPLICATE("usbd", "tegra-otg", NULL),
+       CLK_DUPLICATE("hdmi", "tegradc.0", "hdmi"),
+       CLK_DUPLICATE("hdmi", "tegradc.1", "hdmi"),
+       CLK_DUPLICATE("dsib", "tegradc.0", "dsib"),
+       CLK_DUPLICATE("dsia", "tegradc.1", "dsia"),
+       CLK_DUPLICATE("pwm", "tegra_pwm.0", NULL),
+       CLK_DUPLICATE("pwm", "tegra_pwm.1", NULL),
+       CLK_DUPLICATE("pwm", "tegra_pwm.2", NULL),
+       CLK_DUPLICATE("pwm", "tegra_pwm.3", NULL),
+       CLK_DUPLICATE("bsev", "tegra-avp", "bsev"),
+       CLK_DUPLICATE("bsev", "nvavp", "bsev"),
+       CLK_DUPLICATE("vde", "tegra-aes", "vde"),
+       CLK_DUPLICATE("bsea", "tegra-aes", "bsea"),
+       CLK_DUPLICATE("bsea", "nvavp", "bsea"),
+       CLK_DUPLICATE("cml1", "tegra_sata_cml", NULL),
+       CLK_DUPLICATE("cml0", "tegra_pcie", "cml"),
+       CLK_DUPLICATE("pciex", "tegra_pcie", "pciex"),
+       CLK_DUPLICATE("i2c1", "tegra-i2c-slave.0", NULL),
+       CLK_DUPLICATE("i2c2", "tegra-i2c-slave.1", NULL),
+       CLK_DUPLICATE("i2c3", "tegra-i2c-slave.2", NULL),
+       CLK_DUPLICATE("i2c4", "tegra-i2c-slave.3", NULL),
+       CLK_DUPLICATE("i2c5", "tegra-i2c-slave.4", NULL),
+       CLK_DUPLICATE("sbc1", "spi_slave_tegra.0", NULL),
+       CLK_DUPLICATE("sbc2", "spi_slave_tegra.1", NULL),
+       CLK_DUPLICATE("sbc3", "spi_slave_tegra.2", NULL),
+       CLK_DUPLICATE("sbc4", "spi_slave_tegra.3", NULL),
+       CLK_DUPLICATE("sbc5", "spi_slave_tegra.4", NULL),
+       CLK_DUPLICATE("sbc6", "spi_slave_tegra.5", NULL),
+       CLK_DUPLICATE("twd", "smp_twd", NULL),
+       CLK_DUPLICATE("vcp", "nvavp", "vcp"),
+};
+
+struct clk *tegra_ptr_clks[] = {
+       &tegra_clk_32k,
+       &tegra_clk_m,
+       &tegra_clk_m_div2,
+       &tegra_clk_m_div4,
+       &tegra_pll_ref,
+       &tegra_pll_m,
+       &tegra_pll_m_out1,
+       &tegra_pll_c,
+       &tegra_pll_c_out1,
+       &tegra_pll_p,
+       &tegra_pll_p_out1,
+       &tegra_pll_p_out2,
+       &tegra_pll_p_out3,
+       &tegra_pll_p_out4,
+       &tegra_pll_a,
+       &tegra_pll_a_out0,
+       &tegra_pll_d,
+       &tegra_pll_d_out0,
+       &tegra_pll_d2,
+       &tegra_pll_d2_out0,
+       &tegra_pll_u,
+       &tegra_pll_x,
+       &tegra_pll_x_out0,
+       &tegra_pll_e,
+       &tegra_clk_cclk_g,
+       &tegra_cml0_clk,
+       &tegra_cml1_clk,
+       &tegra_pciex_clk,
+       &tegra_clk_sclk,
+       &tegra_clk_blink,
+       &tegra30_clk_twd,
+};
+
+
+static void tegra30_init_one_clock(struct clk *c)
+{
+       clk_init(c);
+       INIT_LIST_HEAD(&c->shared_bus_list);
+       if (!c->lookup.dev_id && !c->lookup.con_id)
+               c->lookup.con_id = c->name;
+       c->lookup.clk = c;
+       clkdev_add(&c->lookup);
+}
+
+void __init tegra30_init_clocks(void)
+{
+       int i;
+       struct clk *c;
+
+       for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++)
+               tegra30_init_one_clock(tegra_ptr_clks[i]);
+
+       for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++)
+               tegra30_init_one_clock(&tegra_list_clks[i]);
+
+       for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
+               c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name);
+               if (!c) {
+                       pr_err("%s: Unknown duplicate clock %s\n", __func__,
+                               tegra_clk_duplicates[i].name);
+                       continue;
+               }
+
+               tegra_clk_duplicates[i].lookup.clk = c;
+               clkdev_add(&tegra_clk_duplicates[i].lookup);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(tegra_sync_source_list); i++)
+               tegra30_init_one_clock(&tegra_sync_source_list[i]);
+       for (i = 0; i < ARRAY_SIZE(tegra_clk_audio_list); i++)
+               tegra30_init_one_clock(&tegra_clk_audio_list[i]);
+       for (i = 0; i < ARRAY_SIZE(tegra_clk_audio_2x_list); i++)
+               tegra30_init_one_clock(&tegra_clk_audio_2x_list[i]);
+
+       init_clk_out_mux();
+       for (i = 0; i < ARRAY_SIZE(tegra_clk_out_list); i++)
+               tegra30_init_one_clock(&tegra_clk_out_list[i]);
+
+}
index 1d1acda4f3e0fe268d63f6291cdbf06cf0bba846..1eed8d4a80ef19fd034d72b69718640b59f85848 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/io.h>
 
 #include <asm/mach/time.h>
-#include <asm/localtimer.h>
+#include <asm/smp_twd.h>
 #include <asm/sched_clock.h>
 
 #include <mach/iomap.h>
@@ -162,6 +162,21 @@ static struct irqaction tegra_timer_irq = {
        .irq            = INT_TMR3,
 };
 
+#ifdef CONFIG_HAVE_ARM_TWD
+static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
+                             TEGRA_ARM_PERIF_BASE + 0x600,
+                             IRQ_LOCALTIMER);
+
+static void __init tegra_twd_init(void)
+{
+       int err = twd_local_timer_register(&twd_local_timer);
+       if (err)
+               pr_err("twd_local_timer_register failed %d\n", err);
+}
+#else
+#define tegra_twd_init()       do {} while(0)
+#endif
+
 static void __init tegra_init_timer(void)
 {
        struct clk *clk;
@@ -188,10 +203,6 @@ static void __init tegra_init_timer(void)
        else
                clk_enable(clk);
 
-#ifdef CONFIG_HAVE_ARM_TWD
-       twd_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x600);
-#endif
-
        switch (rate) {
        case 12000000:
                timer_writel(0x000b, TIMERUS_USEC_CFG);
@@ -231,6 +242,7 @@ static void __init tegra_init_timer(void)
        tegra_clockevent.cpumask = cpu_all_mask;
        tegra_clockevent.irq = tegra_timer_irq.irq;
        clockevents_register_device(&tegra_clockevent);
+       tegra_twd_init();
 }
 
 struct sys_timer tegra_timer = {
index ad321f9e2bb828a0bceea9ff3bf9a4efc3323273..c5b2ac04e2a05d63769c5a535e9ae1807f10b9fe 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
@@ -730,6 +731,7 @@ err0:
        kfree(phy);
        return ERR_PTR(err);
 }
+EXPORT_SYMBOL_GPL(tegra_usb_phy_open);
 
 int tegra_usb_phy_power_on(struct tegra_usb_phy *phy)
 {
@@ -738,6 +740,7 @@ int tegra_usb_phy_power_on(struct tegra_usb_phy *phy)
        else
                return utmi_phy_power_on(phy);
 }
+EXPORT_SYMBOL_GPL(tegra_usb_phy_power_on);
 
 void tegra_usb_phy_power_off(struct tegra_usb_phy *phy)
 {
@@ -746,18 +749,21 @@ void tegra_usb_phy_power_off(struct tegra_usb_phy *phy)
        else
                utmi_phy_power_off(phy);
 }
+EXPORT_SYMBOL_GPL(tegra_usb_phy_power_off);
 
 void tegra_usb_phy_preresume(struct tegra_usb_phy *phy)
 {
        if (!phy_is_ulpi(phy))
                utmi_phy_preresume(phy);
 }
+EXPORT_SYMBOL_GPL(tegra_usb_phy_preresume);
 
 void tegra_usb_phy_postresume(struct tegra_usb_phy *phy)
 {
        if (!phy_is_ulpi(phy))
                utmi_phy_postresume(phy);
 }
+EXPORT_SYMBOL_GPL(tegra_usb_phy_postresume);
 
 void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy,
                                 enum tegra_usb_phy_port_speed port_speed)
@@ -765,24 +771,28 @@ void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy,
        if (!phy_is_ulpi(phy))
                utmi_phy_restore_start(phy, port_speed);
 }
+EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_start);
 
 void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy)
 {
        if (!phy_is_ulpi(phy))
                utmi_phy_restore_end(phy);
 }
+EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_end);
 
 void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy)
 {
        if (!phy_is_ulpi(phy))
                utmi_phy_clk_disable(phy);
 }
+EXPORT_SYMBOL_GPL(tegra_usb_phy_clk_disable);
 
 void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy)
 {
        if (!phy_is_ulpi(phy))
                utmi_phy_clk_enable(phy);
 }
+EXPORT_SYMBOL_GPL(tegra_usb_phy_clk_enable);
 
 void tegra_usb_phy_close(struct tegra_usb_phy *phy)
 {
@@ -794,3 +804,4 @@ void tegra_usb_phy_close(struct tegra_usb_phy *phy)
        clk_put(phy->pll_u);
        kfree(phy);
 }
+EXPORT_SYMBOL_GPL(tegra_usb_phy_close);
index c59e8b892d6b9af1781f62666be3992885c6cfcf..880d02ec89d4e598afb2ef6014ab7f03e9b0a56f 100644 (file)
@@ -8,47 +8,62 @@ config UX500_SOC_COMMON
        select PL310_ERRATA_753970
        select ARM_ERRATA_754322
        select ARM_ERRATA_764369
-
-menu "Ux500 SoC"
+       select CACHE_L2X0
 
 config UX500_SOC_DB5500
-       bool "DB5500"
+       bool
        select MFD_DB5500_PRCMU
 
 config UX500_SOC_DB8500
-       bool "DB8500"
+       bool
        select MFD_DB8500_PRCMU
        select REGULATOR_DB8500_PRCMU
-
-endmenu
+       select CPU_FREQ_TABLE if CPU_FREQ
 
 menu "Ux500 target platform (boards)"
 
-config MACH_U8500
-       bool "U8500 Development platform"
-       depends on UX500_SOC_DB8500
-       select TPS6105X
+config MACH_MOP500
+       bool "U8500 Development platform, MOP500 versions"
+       select UX500_SOC_DB8500
+       select I2C
+       select I2C_NOMADIK
+       select SOC_BUS
        help
-         Include support for the mop500 development platform.
+         Include support for the MOP500 development platform.
 
 config MACH_HREFV60
-       bool "U85000 Development platform, HREFv60 version"
-       depends on UX500_SOC_DB8500
-       help
-         Include support for the HREFv60 new development platform.
+       bool "U8500 Development platform, HREFv60 version"
+       select MACH_MOP500
+       help
+         Include support for the HREFv60 new development platform.
+         Includes HREFv70, v71 etc.
 
 config MACH_SNOWBALL
        bool "U8500 Snowball platform"
-       depends on UX500_SOC_DB8500
-       select MACH_U8500
+       select MACH_MOP500
        help
          Include support for the snowball development platform.
 
 config MACH_U5500
        bool "U5500 Development platform"
-       depends on UX500_SOC_DB5500
+       select UX500_SOC_DB5500
        help
          Include support for the U5500 development platform.
+
+config UX500_AUTO_PLATFORM
+       def_bool y
+       depends on !MACH_U5500
+       select MACH_MOP500
+       help
+         At least one platform needs to be selected in order to build
+         a working kernel. If everything else is disabled, this
+         automatically enables MACH_MOP500.
+
+config MACH_UX500_DT
+       bool "Generic U8500 support using device tree"
+       depends on MACH_MOP500
+       select USE_OF
+
 endmenu
 
 config UX500_DEBUG_UART
index 6bd2f451c185518522f4b72b227b8075df9aed6c..465b9ec9510a298c336d3aa4c974f16df191310b 100644 (file)
@@ -7,7 +7,7 @@ obj-y                           := clock.o cpu.o devices.o devices-common.o \
 obj-$(CONFIG_CACHE_L2X0)       += cache-l2x0.o
 obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o
 obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o
-obj-$(CONFIG_MACH_U8500)       += board-mop500.o board-mop500-sdi.o \
+obj-$(CONFIG_MACH_MOP500)      += board-mop500.o board-mop500-sdi.o \
                                board-mop500-regulators.o \
                                board-mop500-uib.o board-mop500-stuib.o \
                                board-mop500-u8500uib.o \
@@ -15,7 +15,6 @@ obj-$(CONFIG_MACH_U8500)      += board-mop500.o board-mop500-sdi.o \
 obj-$(CONFIG_MACH_U5500)       += board-u5500.o board-u5500-sdi.o
 obj-$(CONFIG_SMP)              += platsmp.o headsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)      += hotplug.o
-obj-$(CONFIG_LOCAL_TIMERS)     += localtimer.o
 obj-$(CONFIG_U5500_MODEM_IRQ)  += modem-irq-db5500.o
 obj-$(CONFIG_U5500_MBOX)       += mbox-db5500.o
 
index ff0a4b5b0a82b5873a119ec072b3db781651ab86..dd5cd00e2554193483e15a7a34ec1f406295f2dd 100644 (file)
@@ -2,3 +2,4 @@
 params_phys-y  := 0x00000100
 initrd_phys-y  := 0x00800000
 
+dtb-$(CONFIG_MACH_SNOWBALL) += snowball.dtb
index 2735d03996cf46a9cdfc7da67378902130dd2aec..52426a4257871cf62e3f2681d7d36b3ca83bea22 100644 (file)
@@ -74,6 +74,26 @@ static struct regulator_consumer_supply ab8500_vtvout_consumers[] = {
        REGULATOR_SUPPLY("vddadc", "ab8500-gpadc.0"),
 };
 
+static struct regulator_consumer_supply ab8500_vaud_consumers[] = {
+       /* AB8500 audio-codec main supply */
+       REGULATOR_SUPPLY("vaud", "ab8500-codec.0"),
+};
+
+static struct regulator_consumer_supply ab8500_vamic1_consumers[] = {
+       /* AB8500 audio-codec Mic1 supply */
+       REGULATOR_SUPPLY("vamic1", "ab8500-codec.0"),
+};
+
+static struct regulator_consumer_supply ab8500_vamic2_consumers[] = {
+       /* AB8500 audio-codec Mic2 supply */
+       REGULATOR_SUPPLY("vamic2", "ab8500-codec.0"),
+};
+
+static struct regulator_consumer_supply ab8500_vdmic_consumers[] = {
+       /* AB8500 audio-codec DMic supply */
+       REGULATOR_SUPPLY("vdmic", "ab8500-codec.0"),
+};
+
 static struct regulator_consumer_supply ab8500_vintcore_consumers[] = {
        /* SoC core supply, no device */
        REGULATOR_SUPPLY("v-intcore", NULL),
@@ -323,6 +343,8 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = {
                        .name = "V-AUD",
                        .valid_ops_mask = REGULATOR_CHANGE_STATUS,
                },
+               .num_consumer_supplies = ARRAY_SIZE(ab8500_vaud_consumers),
+               .consumer_supplies = ab8500_vaud_consumers,
        },
        /* supply for v-anamic1 VAMic1-LDO */
        [AB8500_LDO_ANAMIC1] = {
@@ -330,6 +352,8 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = {
                        .name = "V-AMIC1",
                        .valid_ops_mask = REGULATOR_CHANGE_STATUS,
                },
+               .num_consumer_supplies = ARRAY_SIZE(ab8500_vamic1_consumers),
+               .consumer_supplies = ab8500_vamic1_consumers,
        },
        /* supply for v-amic2, VAMIC2 LDO, reuse constants for AMIC1 */
        [AB8500_LDO_ANAMIC2] = {
@@ -337,6 +361,8 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = {
                        .name = "V-AMIC2",
                        .valid_ops_mask = REGULATOR_CHANGE_STATUS,
                },
+               .num_consumer_supplies = ARRAY_SIZE(ab8500_vamic2_consumers),
+               .consumer_supplies = ab8500_vamic2_consumers,
        },
        /* supply for v-dmic, VDMIC LDO */
        [AB8500_LDO_DMIC] = {
@@ -344,6 +370,8 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = {
                        .name = "V-DMIC",
                        .valid_ops_mask = REGULATOR_CHANGE_STATUS,
                },
+               .num_consumer_supplies = ARRAY_SIZE(ab8500_vdmic_consumers),
+               .consumer_supplies = ab8500_vdmic_consumers,
        },
        /* supply for v-intcore12, VINTCORE12 LDO */
        [AB8500_LDO_INTCORE] = {
index 1daead3e583eb5de6c6d34f6571a9d78549847dd..920251cf834cd8859900417cd106d9af7e83a210 100644 (file)
@@ -99,7 +99,7 @@ static struct mmci_platform_data mop500_sdi0_data = {
 #endif
 };
 
-static void sdi0_configure(void)
+static void sdi0_configure(struct device *parent)
 {
        int ret;
 
@@ -118,15 +118,15 @@ static void sdi0_configure(void)
        gpio_direction_output(sdi0_en, 1);
 
        /* Add the device, force v2 to subrevision 1 */
-       db8500_add_sdi0(&mop500_sdi0_data, U8500_SDI_V2_PERIPHID);
+       db8500_add_sdi0(parent, &mop500_sdi0_data, U8500_SDI_V2_PERIPHID);
 }
 
-void mop500_sdi_tc35892_init(void)
+void mop500_sdi_tc35892_init(struct device *parent)
 {
        mop500_sdi0_data.gpio_cd = GPIO_SDMMC_CD;
        sdi0_en = GPIO_SDMMC_EN;
        sdi0_vsel = GPIO_SDMMC_1V8_3V_SEL;
-       sdi0_configure();
+       sdi0_configure(parent);
 }
 
 /*
@@ -241,12 +241,13 @@ static struct mmci_platform_data mop500_sdi4_data = {
 #endif
 };
 
-void __init mop500_sdi_init(void)
+void __init mop500_sdi_init(struct device *parent)
 {
        /* PoP:ed eMMC */
-       db8500_add_sdi2(&mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
+       db8500_add_sdi2(parent, &mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
        /* On-board eMMC */
-       db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
+       db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
+
        /*
         * On boards with the TC35892 GPIO expander, sdi0 will finally
         * be added when the TC35892 initializes and calls
@@ -254,31 +255,31 @@ void __init mop500_sdi_init(void)
         */
 }
 
-void __init snowball_sdi_init(void)
+void __init snowball_sdi_init(struct device *parent)
 {
        /* On Snowball MMC_CAP_SD_HIGHSPEED isn't supported (Hardware issue?) */
        mop500_sdi0_data.capabilities &= ~MMC_CAP_SD_HIGHSPEED;
        /* On-board eMMC */
-       db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
+       db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
        /* External Micro SD slot */
        mop500_sdi0_data.gpio_cd = SNOWBALL_SDMMC_CD_GPIO;
        mop500_sdi0_data.cd_invert = true;
        sdi0_en = SNOWBALL_SDMMC_EN_GPIO;
        sdi0_vsel = SNOWBALL_SDMMC_1V8_3V_GPIO;
-       sdi0_configure();
+       sdi0_configure(parent);
 }
 
-void __init hrefv60_sdi_init(void)
+void __init hrefv60_sdi_init(struct device *parent)
 {
        /* PoP:ed eMMC */
-       db8500_add_sdi2(&mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
+       db8500_add_sdi2(parent, &mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
        /* On-board eMMC */
-       db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
+       db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
        /* External Micro SD slot */
        mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO;
        sdi0_en = HREFV60_SDMMC_EN_GPIO;
        sdi0_vsel = HREFV60_SDMMC_1V8_3V_GPIO;
-       sdi0_configure();
+       sdi0_configure(parent);
        /* WLAN SDIO channel */
-       db8500_add_sdi1(&mop500_sdi1_data, U8500_SDI_V2_PERIPHID);
+       db8500_add_sdi1(parent, &mop500_sdi1_data, U8500_SDI_V2_PERIPHID);
 }
index feb5744d98b7d7658f3d58290b0b1c76ded8f295..ead91c968ff480367a145d5d7a5d8009774330cf 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
-#include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/mfd/tc3589x.h>
 #include <linux/input/matrix_keypad.h>
index 5c00712907d18ef715a74fa3caa27b38fba095f6..77d03c1fbd04551982dd97dcf055ef520ca664ea 100644 (file)
@@ -30,6 +30,9 @@
 #include <linux/gpio_keys.h>
 #include <linux/delay.h>
 
+#include <linux/of.h>
+#include <linux/of_platform.h>
+
 #include <linux/leds.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -72,7 +75,7 @@ static struct platform_device snowball_led_dev = {
 };
 
 static struct ab8500_gpio_platform_data ab8500_gpio_pdata = {
-       .gpio_base              = MOP500_AB8500_GPIO(0),
+       .gpio_base              = MOP500_AB8500_PIN_GPIO(1),
        .irq_base               = MOP500_AB8500_VIR_GPIO_IRQ_BASE,
        /* config_reg is the initial configuration of ab8500 pins.
         * The pins can be configured as GPIO or alt functions based
@@ -226,7 +229,12 @@ static struct tps6105x_platform_data mop500_tps61052_data = {
 
 static void mop500_tc35892_init(struct tc3589x *tc3589x, unsigned int base)
 {
-       mop500_sdi_tc35892_init();
+       struct device *parent = NULL;
+#if 0
+       /* FIXME: Is the sdi actually part of tc3589x? */
+       parent = tc3589x->dev;
+#endif
+       mop500_sdi_tc35892_init(parent);
 }
 
 static struct tc3589x_gpio_platform_data mop500_tc35892_gpio_data = {
@@ -353,12 +361,12 @@ U8500_I2C_CONTROLLER(1, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
 U8500_I2C_CONTROLLER(2,        0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
 U8500_I2C_CONTROLLER(3,        0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
 
-static void __init mop500_i2c_init(void)
+static void __init mop500_i2c_init(struct device *parent)
 {
-       db8500_add_i2c0(&u8500_i2c0_data);
-       db8500_add_i2c1(&u8500_i2c1_data);
-       db8500_add_i2c2(&u8500_i2c2_data);
-       db8500_add_i2c3(&u8500_i2c3_data);
+       db8500_add_i2c0(parent, &u8500_i2c0_data);
+       db8500_add_i2c1(parent, &u8500_i2c1_data);
+       db8500_add_i2c2(parent, &u8500_i2c2_data);
+       db8500_add_i2c3(parent, &u8500_i2c3_data);
 }
 
 static struct gpio_keys_button mop500_gpio_keys[] = {
@@ -435,7 +443,7 @@ static struct stedma40_chan_cfg ssp0_dma_cfg_tx = {
 };
 #endif
 
-static struct pl022_ssp_controller ssp0_platform_data = {
+static struct pl022_ssp_controller ssp0_plat = {
        .bus_id = 0,
 #ifdef CONFIG_STE_DMA40
        .enable_dma = 1,
@@ -451,9 +459,9 @@ static struct pl022_ssp_controller ssp0_platform_data = {
        .num_chipselect = 5,
 };
 
-static void __init mop500_spi_init(void)
+static void __init mop500_spi_init(struct device *parent)
 {
-       db8500_add_ssp0(&ssp0_platform_data);
+       db8500_add_ssp0(parent, &ssp0_plat);
 }
 
 #ifdef CONFIG_STE_DMA40
@@ -587,11 +595,11 @@ static struct amba_pl011_data uart2_plat = {
 #endif
 };
 
-static void __init mop500_uart_init(void)
+static void __init mop500_uart_init(struct device *parent)
 {
-       db8500_add_uart0(&uart0_plat);
-       db8500_add_uart1(&uart1_plat);
-       db8500_add_uart2(&uart2_plat);
+       db8500_add_uart0(parent, &uart0_plat);
+       db8500_add_uart1(parent, &uart1_plat);
+       db8500_add_uart2(parent, &uart2_plat);
 }
 
 static struct platform_device *snowball_platform_devs[] __initdata = {
@@ -603,21 +611,27 @@ static struct platform_device *snowball_platform_devs[] __initdata = {
 
 static void __init mop500_init_machine(void)
 {
+       struct device *parent = NULL;
        int i2c0_devs;
+       int i;
 
        mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR;
 
-       u8500_init_devices();
+       parent = u8500_init_devices();
 
        mop500_pins_init();
 
+       /* FIXME: parent of ab8500 should be prcmu */
+       for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)
+               mop500_platform_devs[i]->dev.parent = parent;
+
        platform_add_devices(mop500_platform_devs,
                        ARRAY_SIZE(mop500_platform_devs));
 
-       mop500_i2c_init();
-       mop500_sdi_init();
-       mop500_spi_init();
-       mop500_uart_init();
+       mop500_i2c_init(parent);
+       mop500_sdi_init(parent);
+       mop500_spi_init(parent);
+       mop500_uart_init(parent);
 
        i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
 
@@ -631,19 +645,24 @@ static void __init mop500_init_machine(void)
 
 static void __init snowball_init_machine(void)
 {
+       struct device *parent = NULL;
        int i2c0_devs;
+       int i;
 
-       u8500_init_devices();
+       parent = u8500_init_devices();
 
        snowball_pins_init();
 
+       for (i = 0; i < ARRAY_SIZE(snowball_platform_devs); i++)
+               snowball_platform_devs[i]->dev.parent = parent;
+
        platform_add_devices(snowball_platform_devs,
                        ARRAY_SIZE(snowball_platform_devs));
 
-       mop500_i2c_init();
-       snowball_sdi_init();
-       mop500_spi_init();
-       mop500_uart_init();
+       mop500_i2c_init(parent);
+       snowball_sdi_init(parent);
+       mop500_spi_init(parent);
+       mop500_uart_init(parent);
 
        i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
        i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs);
@@ -656,7 +675,9 @@ static void __init snowball_init_machine(void)
 
 static void __init hrefv60_init_machine(void)
 {
+       struct device *parent = NULL;
        int i2c0_devs;
+       int i;
 
        /*
         * The HREFv60 board removed a GPIO expander and routed
@@ -665,17 +686,20 @@ static void __init hrefv60_init_machine(void)
         */
        mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO;
 
-       u8500_init_devices();
+       parent = u8500_init_devices();
 
        hrefv60_pins_init();
 
+       for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)
+               mop500_platform_devs[i]->dev.parent = parent;
+
        platform_add_devices(mop500_platform_devs,
                        ARRAY_SIZE(mop500_platform_devs));
 
-       mop500_i2c_init();
-       hrefv60_sdi_init();
-       mop500_spi_init();
-       mop500_uart_init();
+       mop500_i2c_init(parent);
+       hrefv60_sdi_init(parent);
+       mop500_spi_init(parent);
+       mop500_uart_init(parent);
 
        i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
 
@@ -718,3 +742,94 @@ MACHINE_START(SNOWBALL, "Calao Systems Snowball platform")
        .handle_irq     = gic_handle_irq,
        .init_machine   = snowball_init_machine,
 MACHINE_END
+
+#ifdef CONFIG_MACH_UX500_DT
+
+struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
+       OF_DEV_AUXDATA("arm,pl011", 0x80120000, "uart0", &uart0_plat),
+       OF_DEV_AUXDATA("arm,pl011", 0x80121000, "uart1", &uart1_plat),
+       OF_DEV_AUXDATA("arm,pl011", 0x80007000, "uart2", &uart2_plat),
+       OF_DEV_AUXDATA("arm,pl022", 0x80002000, "ssp0",  &ssp0_plat),
+       {},
+};
+
+static const struct of_device_id u8500_soc_node[] = {
+       /* only create devices below soc node */
+       { .compatible = "stericsson,db8500", },
+       { },
+};
+
+static void __init u8500_init_machine(void)
+{
+       struct device *parent = NULL;
+       int i2c0_devs;
+       int i;
+
+       parent = u8500_init_devices();
+       i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
+
+       for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)
+               mop500_platform_devs[i]->dev.parent = parent;
+       for (i = 0; i < ARRAY_SIZE(snowball_platform_devs); i++)
+               snowball_platform_devs[i]->dev.parent = parent;
+
+       /* automatically probe child nodes of db8500 device */
+       of_platform_populate(NULL, u8500_soc_node, u8500_auxdata_lookup, parent);
+
+       if (of_machine_is_compatible("st-ericsson,mop500")) {
+               mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR;
+               mop500_pins_init();
+
+               platform_add_devices(mop500_platform_devs,
+                               ARRAY_SIZE(mop500_platform_devs));
+
+               mop500_sdi_init(parent);
+       } else if (of_machine_is_compatible("calaosystems,snowball-a9500")) {
+               snowball_pins_init();
+               platform_add_devices(snowball_platform_devs,
+                               ARRAY_SIZE(snowball_platform_devs));
+
+               snowball_sdi_init(parent);
+       } else if (of_machine_is_compatible("st-ericsson,hrefv60+")) {
+               /*
+                * The HREFv60 board removed a GPIO expander and routed
+                * all these GPIO pins to the internal GPIO controller
+                * instead.
+                */
+               mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO;
+               i2c0_devs -= NUM_PRE_V60_I2C0_DEVICES;
+               hrefv60_pins_init();
+               platform_add_devices(mop500_platform_devs,
+                               ARRAY_SIZE(mop500_platform_devs));
+
+               hrefv60_sdi_init(parent);
+       }
+       mop500_i2c_init(parent);
+
+       i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs);
+       i2c_register_board_info(2, mop500_i2c2_devices,
+                               ARRAY_SIZE(mop500_i2c2_devices));
+
+       /* This board has full regulator constraints */
+       regulator_has_full_constraints();
+}
+
+static const char * u8500_dt_board_compat[] = {
+       "calaosystems,snowball-a9500",
+       "st-ericsson,hrefv60+",
+       "st-ericsson,u8500",
+       "st-ericsson,mop500",
+       NULL,
+};
+
+
+DT_MACHINE_START(U8500_DT, "ST-Ericsson U8500 platform (Device Tree Support)")
+       .map_io         = u8500_map_io,
+       .init_irq       = ux500_init_irq,
+       /* we re-use nomadik timer here */
+       .timer          = &ux500_timer,
+       .handle_irq     = gic_handle_irq,
+       .init_machine   = u8500_init_machine,
+       .dt_compat      = u8500_dt_board_compat,
+MACHINE_END
+#endif
index f926d3db6207ed3a68a834eedddd61286c07bf70..fdcfa8721bb4358e84c2b5d361f30b3ef5503f0e 100644 (file)
@@ -63,7 +63,7 @@
  * because the AB8500 GPIO pins are enumbered starting from 1, so the value in
  * parens matches the GPIO pin number in the data sheet.
  */
-#define MOP500_AB8500_GPIO(x)          (MOP500_EGPIO_END + (x) - 1)
+#define MOP500_AB8500_PIN_GPIO(x)      (MOP500_EGPIO_END + (x) - 1)
 /*Snowball AB8500 GPIO */
 #define SNOWBALL_VSMPS2_1V8_GPIO       MOP500_AB8500_PIN_GPIO(1)       /* SYSCLKREQ2/GPIO1 */
 #define SNOWBALL_PM_GPIO1_GPIO         MOP500_AB8500_PIN_GPIO(2)       /* SYSCLKREQ3/GPIO2 */
 
 struct i2c_board_info;
 
-extern void mop500_sdi_init(void);
-extern void snowball_sdi_init(void);
-extern void hrefv60_sdi_init(void);
-extern void mop500_sdi_tc35892_init(void);
+extern void mop500_sdi_init(struct device *parent);
+extern void snowball_sdi_init(struct device *parent);
+extern void hrefv60_sdi_init(struct device *parent);
+extern void mop500_sdi_tc35892_init(struct device *parent);
 void __init mop500_u8500uib_init(void);
 void __init mop500_stuib_init(void);
 void __init mop500_pins_init(void);
index 63c3f8058ffcb370821f3d79a2f94dd7d0e44b88..836112eedde727bf10e3691044a31f258b5d7489 100644 (file)
@@ -66,9 +66,9 @@ static struct mmci_platform_data u5500_sdi0_data = {
 #endif
 };
 
-void __init u5500_sdi_init(void)
+void __init u5500_sdi_init(struct device *parent)
 {
        nmk_config_pins(u5500_sdi_pins, ARRAY_SIZE(u5500_sdi_pins));
 
-       db5500_add_sdi0(&u5500_sdi0_data);
+       db5500_add_sdi0(parent, &u5500_sdi0_data);
 }
index 9de9e9c4dbbbcf2322e0fbaf3140537e31b89d4a..0ff4be72a8093a3989e7dcc34769a003b9ed6dd7 100644 (file)
@@ -97,9 +97,9 @@ static struct i2c_board_info __initdata u5500_i2c2_devices[] = {
        },
 };
 
-static void __init u5500_i2c_init(void)
+static void __init u5500_i2c_init(struct device *parent)
 {
-       db5500_add_i2c2(&u5500_i2c2_data);
+       db5500_add_i2c2(parent, &u5500_i2c2_data);
        i2c_register_board_info(2, ARRAY_AND_SIZE(u5500_i2c2_devices));
 }
 
@@ -126,20 +126,27 @@ static struct platform_device *u5500_platform_devices[] __initdata = {
        &ab5500_device,
 };
 
-static void __init u5500_uart_init(void)
+static void __init u5500_uart_init(struct device *parent)
 {
-       db5500_add_uart0(NULL);
-       db5500_add_uart1(NULL);
-       db5500_add_uart2(NULL);
+       db5500_add_uart0(parent, NULL);
+       db5500_add_uart1(parent, NULL);
+       db5500_add_uart2(parent, NULL);
 }
 
 static void __init u5500_init_machine(void)
 {
-       u5500_init_devices();
+       struct device *parent = NULL;
+       int i;
+
+       parent = u5500_init_devices();
        nmk_config_pins(u5500_pins, ARRAY_SIZE(u5500_pins));
-       u5500_i2c_init();
-       u5500_sdi_init();
-       u5500_uart_init();
+
+       u5500_i2c_init(parent);
+       u5500_sdi_init(parent);
+       u5500_uart_init(parent);
+
+       for (i = 0; i < ARRAY_SIZE(u5500_platform_devices); i++)
+               u5500_platform_devices[i]->dev.parent = parent;
 
        platform_add_devices(u5500_platform_devices,
                ARRAY_SIZE(u5500_platform_devices));
index da5569d83d58d87216438bf65aa15de86a6f71ea..77a75ed0df6729ff85452ce216ab1ef9f354fd57 100644 (file)
@@ -5,6 +5,8 @@
  */
 
 #include <linux/io.h>
+#include <linux/of.h>
+
 #include <asm/cacheflush.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <mach/hardware.h>
@@ -45,7 +47,10 @@ static int __init ux500_l2x0_init(void)
        ux500_l2x0_unlock();
 
        /* 64KB way size, 8 way associativity, force WA */
-       l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
+       if (of_have_populated_dt())
+               l2x0_of_init(0x3e060000, 0xc0000fff);
+       else
+               l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
 
        /*
         * We can't disable l2 as we are in non secure mode, currently
index 7379075370040f623842f07a78724657131cdbce..ec35f0aa5665a99d23f11c73ec552ab6e83f3aca 100644 (file)
@@ -223,6 +223,13 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 }
 EXPORT_SYMBOL(clk_set_rate);
 
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+       /*TODO*/
+       return -ENOSYS;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
 static void clk_prcmu_enable(struct clk *clk)
 {
        void __iomem *cg_set_reg = __io_address(U8500_PRCMU_BASE)
index 074490705229a73a987b380441ad569d083d8ef1..d776ada08dbf1062b0cb8d5733a31c00dcc7a78b 100644 (file)
@@ -21,6 +21,7 @@ struct clkops {
        void (*enable) (struct clk *);
        void (*disable) (struct clk *);
        unsigned long (*get_rate) (struct clk *);
+       int (*set_parent)(struct clk *, struct clk *);
 };
 
 /**
index 18aa5c05c69ec1f42dd29ee1cd6ba42d890cb2c7..bca47f32082ff011e266ff42df702dec810c3540 100644 (file)
@@ -147,13 +147,13 @@ static resource_size_t __initdata db5500_gpio_base[] = {
        U5500_GPIOBANK7_BASE,
 };
 
-static void __init db5500_add_gpios(void)
+static void __init db5500_add_gpios(struct device *parent)
 {
        struct nmk_gpio_platform_data pdata = {
                /* No custom data yet */
        };
 
-       dbx500_add_gpios(ARRAY_AND_SIZE(db5500_gpio_base),
+       dbx500_add_gpios(parent, ARRAY_AND_SIZE(db5500_gpio_base),
                         IRQ_DB5500_GPIO0, &pdata);
 }
 
@@ -212,14 +212,36 @@ static int usb_db5500_tx_dma_cfg[] = {
        DB5500_DMA_DEV38_USB_OTG_OEP_8
 };
 
-void __init u5500_init_devices(void)
+static const char *db5500_read_soc_id(void)
 {
-       db5500_add_gpios();
+       return kasprintf(GFP_KERNEL, "u5500 currently unsupported\n");
+}
+
+static struct device * __init db5500_soc_device_init(void)
+{
+       const char *soc_id = db5500_read_soc_id();
+
+       return ux500_soc_device_init(soc_id);
+}
+
+struct device * __init u5500_init_devices(void)
+{
+       struct device *parent;
+       int i;
+
+       parent = db5500_soc_device_init();
+
+       db5500_add_gpios(parent);
        db5500_pmu_init();
-       db5500_dma_init();
-       db5500_add_rtc();
-       db5500_add_usb(usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg);
+       db5500_dma_init(parent);
+       db5500_add_rtc(parent);
+       db5500_add_usb(parent, usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg);
+
+       for (i = 0; i < ARRAY_SIZE(db5500_platform_devs); i++)
+               db5500_platform_devs[i]->dev.parent = parent;
 
        platform_add_devices(db5500_platform_devs,
                             ARRAY_SIZE(db5500_platform_devs));
+
+       return parent;
 }
index 7176ee7491abc6b1bc41bb259b1ceeec90a624f1..9bd8163896cfa241a76839aa7be5830b3f052eaf 100644 (file)
@@ -24,6 +24,7 @@
 #include <mach/setup.h>
 #include <mach/devices.h>
 #include <mach/usb.h>
+#include <mach/db8500-regs.h>
 
 #include "devices-db8500.h"
 #include "ste-dma40-db8500.h"
@@ -132,13 +133,13 @@ static resource_size_t __initdata db8500_gpio_base[] = {
        U8500_GPIOBANK8_BASE,
 };
 
-static void __init db8500_add_gpios(void)
+static void __init db8500_add_gpios(struct device *parent)
 {
        struct nmk_gpio_platform_data pdata = {
                .supports_sleepmode = true,
        };
 
-       dbx500_add_gpios(ARRAY_AND_SIZE(db8500_gpio_base),
+       dbx500_add_gpios(parent, ARRAY_AND_SIZE(db8500_gpio_base),
                         IRQ_DB8500_GPIO0, &pdata);
 }
 
@@ -164,17 +165,44 @@ static int usb_db8500_tx_dma_cfg[] = {
        DB8500_DMA_DEV39_USB_OTG_OEP_8
 };
 
+static const char *db8500_read_soc_id(void)
+{
+       void __iomem *uid = __io_address(U8500_BB_UID_BASE);
+
+       return kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x",
+                        readl((u32 *)uid+1),
+                        readl((u32 *)uid+1), readl((u32 *)uid+2),
+                        readl((u32 *)uid+3), readl((u32 *)uid+4));
+}
+
+static struct device * __init db8500_soc_device_init(void)
+{
+       const char *soc_id = db8500_read_soc_id();
+
+       return ux500_soc_device_init(soc_id);
+}
+
 /*
  * This function is called from the board init
  */
-void __init u8500_init_devices(void)
+struct device * __init u8500_init_devices(void)
 {
-       db8500_add_rtc();
-       db8500_add_gpios();
-       db8500_add_usb(usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg);
+       struct device *parent;
+       int i;
+
+       parent = db8500_soc_device_init();
+
+       db8500_add_rtc(parent);
+       db8500_add_gpios(parent);
+       db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg);
+
+       platform_device_register_data(parent,
+               "cpufreq-u8500", -1, NULL, 0);
+
+       for (i = 0; i < ARRAY_SIZE(platform_devs); i++)
+               platform_devs[i]->dev.parent = parent;
 
-       platform_device_register_simple("cpufreq-u8500", -1, NULL, 0);
        platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
 
-       return ;
+       return parent;
 }
index f4185749437533f5acd930dcc612113f57556eef..d11f3892a27dffe6a596a5c279ecdd355b44f280 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright (C) ST-Ericsson SA 2010
  *
  * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * Author: Lee Jones <lee.jones@linaro.org> for ST-Ericsson
  * License terms: GNU General Public License (GPL) version 2
  */
 
 #include <linux/mfd/db8500-prcmu.h>
 #include <linux/mfd/db5500-prcmu.h>
 #include <linux/clksrc-dbx500-prcmu.h>
+#include <linux/sys_soc.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
 
 #include <asm/hardware/gic.h>
 #include <asm/mach/map.h>
-#include <asm/localtimer.h>
 
 #include <mach/hardware.h>
 #include <mach/setup.h>
 
 void __iomem *_PRCMU_BASE;
 
+static const struct of_device_id ux500_dt_irq_match[] = {
+       { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
+       {},
+};
+
 void __init ux500_init_irq(void)
 {
        void __iomem *dist_base;
@@ -38,7 +49,12 @@ void __init ux500_init_irq(void)
        } else
                ux500_unknown_soc();
 
-       gic_init(0, 29, dist_base, cpu_base);
+#ifdef CONFIG_OF
+       if (of_have_populated_dt())
+               of_irq_init(ux500_dt_irq_match);
+       else
+#endif
+               gic_init(0, 29, dist_base, cpu_base);
 
        /*
         * Init clocks here so that they are available for system timer
@@ -50,3 +66,73 @@ void __init ux500_init_irq(void)
                db8500_prcmu_early_init();
        clk_init();
 }
+
+static const char * __init ux500_get_machine(void)
+{
+       return kasprintf(GFP_KERNEL, "DB%4x", dbx500_partnumber());
+}
+
+static const char * __init ux500_get_family(void)
+{
+       return kasprintf(GFP_KERNEL, "ux500");
+}
+
+static const char * __init ux500_get_revision(void)
+{
+       unsigned int rev = dbx500_revision();
+
+       if (rev == 0x01)
+               return kasprintf(GFP_KERNEL, "%s", "ED");
+       else if (rev >= 0xA0)
+               return kasprintf(GFP_KERNEL, "%d.%d",
+                                (rev >> 4) - 0xA + 1, rev & 0xf);
+
+       return kasprintf(GFP_KERNEL, "%s", "Unknown");
+}
+
+static ssize_t ux500_get_process(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       if (dbx500_id.process == 0x00)
+               return sprintf(buf, "Standard\n");
+
+       return sprintf(buf, "%02xnm\n", dbx500_id.process);
+}
+
+static void __init soc_info_populate(struct soc_device_attribute *soc_dev_attr,
+                                    const char *soc_id)
+{
+       soc_dev_attr->soc_id   = soc_id;
+       soc_dev_attr->machine  = ux500_get_machine();
+       soc_dev_attr->family   = ux500_get_family();
+       soc_dev_attr->revision = ux500_get_revision();
+}
+
+struct device_attribute ux500_soc_attr =
+       __ATTR(process,  S_IRUGO, ux500_get_process,  NULL);
+
+struct device * __init ux500_soc_device_init(const char *soc_id)
+{
+       struct device *parent;
+       struct soc_device *soc_dev;
+       struct soc_device_attribute *soc_dev_attr;
+
+       soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+       if (!soc_dev_attr)
+               return ERR_PTR(-ENOMEM);
+
+       soc_info_populate(soc_dev_attr, soc_id);
+
+       soc_dev = soc_device_register(soc_dev_attr);
+       if (IS_ERR_OR_NULL(soc_dev)) {
+               kfree(soc_dev_attr);
+               return NULL;
+       }
+
+       parent = soc_device_to_device(soc_dev);
+       if (!IS_ERR_OR_NULL(parent))
+               device_create_file(parent, &ux500_soc_attr);
+
+       return parent;
+}
index 898a64517b09ecc1386bd1e2e23d938cc4b6e72c..c5312a4b49f5487a229166de8c28acb3994d6c52 100644 (file)
@@ -20,8 +20,9 @@
 #include "devices-common.h"
 
 struct amba_device *
-dbx500_add_amba_device(const char *name, resource_size_t base,
-                      int irq, void *pdata, unsigned int periphid)
+dbx500_add_amba_device(struct device *parent, const char *name,
+                      resource_size_t base, int irq, void *pdata,
+                      unsigned int periphid)
 {
        struct amba_device *dev;
        int ret;
@@ -39,6 +40,8 @@ dbx500_add_amba_device(const char *name, resource_size_t base,
 
        dev->dev.platform_data = pdata;
 
+       dev->dev.parent = parent;
+
        ret = amba_device_add(dev, &iomem_resource);
        if (ret) {
                amba_device_put(dev);
@@ -49,60 +52,7 @@ dbx500_add_amba_device(const char *name, resource_size_t base,
 }
 
 static struct platform_device *
-dbx500_add_platform_device(const char *name, int id, void *pdata,
-                          struct resource *res, int resnum)
-{
-       struct platform_device *dev;
-       int ret;
-
-       dev = platform_device_alloc(name, id);
-       if (!dev)
-               return ERR_PTR(-ENOMEM);
-
-       dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
-       dev->dev.dma_mask = &dev->dev.coherent_dma_mask;
-
-       ret = platform_device_add_resources(dev, res, resnum);
-       if (ret)
-               goto out_free;
-
-       dev->dev.platform_data = pdata;
-
-       ret = platform_device_add(dev);
-       if (ret)
-               goto out_free;
-
-       return dev;
-
-out_free:
-       platform_device_put(dev);
-       return ERR_PTR(ret);
-}
-
-struct platform_device *
-dbx500_add_platform_device_4k1irq(const char *name, int id,
-                                 resource_size_t base,
-                                 int irq, void *pdata)
-{
-       struct resource resources[] = {
-               [0] = {
-                       .start  = base,
-                       .end    = base + SZ_4K - 1,
-                       .flags  = IORESOURCE_MEM,
-               },
-               [1] = {
-                       .start  = irq,
-                       .end    = irq,
-                       .flags  = IORESOURCE_IRQ,
-               }
-       };
-
-       return dbx500_add_platform_device(name, id, pdata, resources,
-                                         ARRAY_SIZE(resources));
-}
-
-static struct platform_device *
-dbx500_add_gpio(int id, resource_size_t addr, int irq,
+dbx500_add_gpio(struct device *parent, int id, resource_size_t addr, int irq,
                struct nmk_gpio_platform_data *pdata)
 {
        struct resource resources[] = {
@@ -118,13 +68,18 @@ dbx500_add_gpio(int id, resource_size_t addr, int irq,
                }
        };
 
-       return platform_device_register_resndata(NULL, "gpio", id,
-                               resources, ARRAY_SIZE(resources),
-                               pdata, sizeof(*pdata));
+       return platform_device_register_resndata(
+               parent,
+               "gpio",
+               id,
+               resources,
+               ARRAY_SIZE(resources),
+               pdata,
+               sizeof(*pdata));
 }
 
-void dbx500_add_gpios(resource_size_t *base, int num, int irq,
-                     struct nmk_gpio_platform_data *pdata)
+void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num,
+                     int irq, struct nmk_gpio_platform_data *pdata)
 {
        int first = 0;
        int i;
@@ -134,6 +89,6 @@ void dbx500_add_gpios(resource_size_t *base, int num, int irq,
                pdata->first_irq = NOMADIK_GPIO_TO_IRQ(first);
                pdata->num_gpio = 32;
 
-               dbx500_add_gpio(i, base[i], irq, pdata);
+               dbx500_add_gpio(parent, i, base[i], irq, pdata);
        }
 }
index 7825705033bfe6e18881e6e8fa15aaa2d8c4d82f..39c74ec82add9361f339bd8b57e6b90ad83e3936 100644 (file)
@@ -8,80 +8,89 @@
 #ifndef __DEVICES_COMMON_H
 #define __DEVICES_COMMON_H
 
-extern struct amba_device *
-dbx500_add_amba_device(const char *name, resource_size_t base,
-                      int irq, void *pdata, unsigned int periphid);
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/sys_soc.h>
+#include <plat/i2c.h>
 
-extern struct platform_device *
-dbx500_add_platform_device_4k1irq(const char *name, int id,
-                                 resource_size_t base,
-                                 int irq, void *pdata);
+extern struct amba_device *
+dbx500_add_amba_device(struct device *parent, const char *name,
+                      resource_size_t base, int irq, void *pdata,
+                      unsigned int periphid);
 
 struct spi_master_cntlr;
 
 static inline struct amba_device *
-dbx500_add_msp_spi(const char *name, resource_size_t base, int irq,
+dbx500_add_msp_spi(struct device *parent, const char *name,
+                  resource_size_t base, int irq,
                   struct spi_master_cntlr *pdata)
 {
-       return dbx500_add_amba_device(name, base, irq, pdata, 0);
+       return dbx500_add_amba_device(parent, name, base, irq,
+                                     pdata, 0);
 }
 
 static inline struct amba_device *
-dbx500_add_spi(const char *name, resource_size_t base, int irq,
-              struct spi_master_cntlr *pdata,
+dbx500_add_spi(struct device *parent, const char *name, resource_size_t base,
+              int irq, struct spi_master_cntlr *pdata,
               u32 periphid)
 {
-       return dbx500_add_amba_device(name, base, irq, pdata, periphid);
+       return dbx500_add_amba_device(parent, name, base, irq,
+                                     pdata, periphid);
 }
 
 struct mmci_platform_data;
 
 static inline struct amba_device *
-dbx500_add_sdi(const char *name, resource_size_t base, int irq,
-              struct mmci_platform_data *pdata,
-              u32 periphid)
+dbx500_add_sdi(struct device *parent, const char *name, resource_size_t base,
+              int irq, struct mmci_platform_data *pdata, u32 periphid)
 {
-       return dbx500_add_amba_device(name, base, irq, pdata, periphid);
+       return dbx500_add_amba_device(parent, name, base, irq,
+                                     pdata, periphid);
 }
 
 struct amba_pl011_data;
 
 static inline struct amba_device *
-dbx500_add_uart(const char *name, resource_size_t base, int irq,
-               struct amba_pl011_data *pdata)
+dbx500_add_uart(struct device *parent, const char *name, resource_size_t base,
+               int irq, struct amba_pl011_data *pdata)
 {
-       return dbx500_add_amba_device(name, base, irq, pdata, 0);
+       return dbx500_add_amba_device(parent, name, base, irq, pdata, 0);
 }
 
 struct nmk_i2c_controller;
 
 static inline struct platform_device *
-dbx500_add_i2c(int id, resource_size_t base, int irq,
-              struct nmk_i2c_controller *pdata)
-{
-       return dbx500_add_platform_device_4k1irq("nmk-i2c", id, base, irq,
-                                                pdata);
-}
-
-struct msp_i2s_platform_data;
-
-static inline struct platform_device *
-dbx500_add_msp_i2s(int id, resource_size_t base, int irq,
-                  struct msp_i2s_platform_data *pdata)
+dbx500_add_i2c(struct device *parent, int id, resource_size_t base, int irq,
+              struct nmk_i2c_controller *data)
 {
-       return dbx500_add_platform_device_4k1irq("MSP_I2S", id, base, irq,
-                                                pdata);
+       struct resource res[] = {
+               DEFINE_RES_MEM(base, SZ_4K),
+               DEFINE_RES_IRQ(irq),
+       };
+
+       struct platform_device_info pdevinfo = {
+               .parent = parent,
+               .name = "nmk-i2c",
+               .id = id,
+               .res = res,
+               .num_res = ARRAY_SIZE(res),
+               .data = data,
+               .size_data = sizeof(*data),
+               .dma_mask = DMA_BIT_MASK(32),
+       };
+
+       return platform_device_register_full(&pdevinfo);
 }
 
 static inline struct amba_device *
-dbx500_add_rtc(resource_size_t base, int irq)
+dbx500_add_rtc(struct device *parent, resource_size_t base, int irq)
 {
-       return dbx500_add_amba_device("rtc-pl031", base, irq, NULL, 0);
+       return dbx500_add_amba_device(parent, "rtc-pl031", base, irq, NULL, 0);
 }
 
 struct nmk_gpio_platform_data;
 
-void dbx500_add_gpios(resource_size_t *base, int num, int irq,
-                     struct nmk_gpio_platform_data *pdata);
+void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num,
+                     int irq, struct nmk_gpio_platform_data *pdata);
 
 #endif
index 0c4bccd02b90fe2836c4b8954235bf88d5eac270..e70955502c35e64d44a7b515503c34f3d4243d63 100644 (file)
 
 #include "devices-common.h"
 
-#define db5500_add_i2c1(pdata) \
-       dbx500_add_i2c(1, U5500_I2C1_BASE, IRQ_DB5500_I2C1, pdata)
-#define db5500_add_i2c2(pdata) \
-       dbx500_add_i2c(2, U5500_I2C2_BASE, IRQ_DB5500_I2C2, pdata)
-#define db5500_add_i2c3(pdata) \
-       dbx500_add_i2c(3, U5500_I2C3_BASE, IRQ_DB5500_I2C3, pdata)
+#define db5500_add_i2c1(parent, pdata) \
+       dbx500_add_i2c(parent, 1, U5500_I2C1_BASE, IRQ_DB5500_I2C1, pdata)
+#define db5500_add_i2c2(parent, pdata) \
+       dbx500_add_i2c(parent, 2, U5500_I2C2_BASE, IRQ_DB5500_I2C2, pdata)
+#define db5500_add_i2c3(parent, pdata) \
+       dbx500_add_i2c(parent, 3, U5500_I2C3_BASE, IRQ_DB5500_I2C3, pdata)
 
-#define db5500_add_msp0_i2s(pdata) \
-       dbx500_add_msp_i2s(0, U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata)
-#define db5500_add_msp1_i2s(pdata) \
-       dbx500_add_msp_i2s(1, U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata)
-#define db5500_add_msp2_i2s(pdata) \
-       dbx500_add_msp_i2s(2, U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata)
+#define db5500_add_msp0_spi(parent, pdata) \
+       dbx500_add_msp_spi(parent, "msp0", U5500_MSP0_BASE, \
+                          IRQ_DB5500_MSP0, pdata)
+#define db5500_add_msp1_spi(parent, pdata) \
+       dbx500_add_msp_spi(parent, "msp1", U5500_MSP1_BASE, \
+                          IRQ_DB5500_MSP1, pdata)
+#define db5500_add_msp2_spi(parent, pdata) \
+       dbx500_add_msp_spi(parent, "msp2", U5500_MSP2_BASE, \
+                          IRQ_DB5500_MSP2, pdata)
 
-#define db5500_add_msp0_spi(pdata) \
-       dbx500_add_msp_spi("msp0", U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata)
-#define db5500_add_msp1_spi(pdata) \
-       dbx500_add_msp_spi("msp1", U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata)
-#define db5500_add_msp2_spi(pdata) \
-       dbx500_add_msp_spi("msp2", U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata)
+#define db5500_add_msp0_spi(parent, pdata) \
+       dbx500_add_msp_spi(parent, "msp0", U5500_MSP0_BASE, \
+                         IRQ_DB5500_MSP0, pdata)
+#define db5500_add_msp1_spi(parent, pdata) \
+       dbx500_add_msp_spi(parent, "msp1", U5500_MSP1_BASE, \
+                         IRQ_DB5500_MSP1, pdata)
+#define db5500_add_msp2_spi(parent, pdata) \
+       dbx500_add_msp_spi(parent, "msp2", U5500_MSP2_BASE, \
+                         IRQ_DB5500_MSP2, pdata)
 
-#define db5500_add_rtc() \
-       dbx500_add_rtc(U5500_RTC_BASE, IRQ_DB5500_RTC);
+#define db5500_add_rtc(parent) \
+       dbx500_add_rtc(parent, U5500_RTC_BASE, IRQ_DB5500_RTC);
 
-#define db5500_add_usb(rx_cfg, tx_cfg) \
-       ux500_add_usb(U5500_USBOTG_BASE, IRQ_DB5500_USBOTG, rx_cfg, tx_cfg)
+#define db5500_add_usb(parent, rx_cfg, tx_cfg) \
+       ux500_add_usb(parent, U5500_USBOTG_BASE, \
+                     IRQ_DB5500_USBOTG, rx_cfg, tx_cfg)
 
-#define db5500_add_sdi0(pdata) \
-       dbx500_add_sdi("sdi0", U5500_SDI0_BASE, IRQ_DB5500_SDMMC0, pdata, \
+#define db5500_add_sdi0(parent, pdata) \
+       dbx500_add_sdi(parent, "sdi0", U5500_SDI0_BASE, \
+                      IRQ_DB5500_SDMMC0, pdata,        \
                       0x10480180)
-#define db5500_add_sdi1(pdata) \
-       dbx500_add_sdi("sdi1", U5500_SDI1_BASE, IRQ_DB5500_SDMMC1, pdata, \
+#define db5500_add_sdi1(parent, pdata) \
+       dbx500_add_sdi(parent, "sdi1", U5500_SDI1_BASE, \
+                      IRQ_DB5500_SDMMC1, pdata,        \
                       0x10480180)
-#define db5500_add_sdi2(pdata) \
-       dbx500_add_sdi("sdi2", U5500_SDI2_BASE, IRQ_DB5500_SDMMC2, pdata \
+#define db5500_add_sdi2(parent, pdata) \
+       dbx500_add_sdi(parent, "sdi2", U5500_SDI2_BASE, \
+                      IRQ_DB5500_SDMMC2, pdata         \
                       0x10480180)
-#define db5500_add_sdi3(pdata) \
-       dbx500_add_sdi("sdi3", U5500_SDI3_BASE, IRQ_DB5500_SDMMC3, pdata \
+#define db5500_add_sdi3(parent, pdata) \
+       dbx500_add_sdi(parent, "sdi3", U5500_SDI3_BASE, \
+                      IRQ_DB5500_SDMMC3, pdata         \
                       0x10480180)
-#define db5500_add_sdi4(pdata) \
-       dbx500_add_sdi("sdi4", U5500_SDI4_BASE, IRQ_DB5500_SDMMC4, pdata \
+#define db5500_add_sdi4(parent, pdata) \
+       dbx500_add_sdi(parent, "sdi4", U5500_SDI4_BASE, \
+                      IRQ_DB5500_SDMMC4, pdata         \
                       0x10480180)
 
 /* This one has a bad peripheral ID in the U5500 silicon */
-#define db5500_add_spi0(pdata) \
-       dbx500_add_spi("spi0", U5500_SPI0_BASE, IRQ_DB5500_SPI0, pdata, \
+#define db5500_add_spi0(parent, pdata) \
+       dbx500_add_spi(parent, "spi0", U5500_SPI0_BASE, \
+                      IRQ_DB5500_SPI0, pdata,          \
                       0x10080023)
-#define db5500_add_spi1(pdata) \
-       dbx500_add_spi("spi1", U5500_SPI1_BASE, IRQ_DB5500_SPI1, pdata, \
+#define db5500_add_spi1(parent, pdata) \
+       dbx500_add_spi(parent, "spi1", U5500_SPI1_BASE, \
+                      IRQ_DB5500_SPI1, pdata,          \
                       0x10080023)
-#define db5500_add_spi2(pdata) \
-       dbx500_add_spi("spi2", U5500_SPI2_BASE, IRQ_DB5500_SPI2, pdata \
+#define db5500_add_spi2(parent, pdata) \
+       dbx500_add_spi(parent, "spi2", U5500_SPI2_BASE, \
+                      IRQ_DB5500_SPI2, pdata           \
                       0x10080023)
-#define db5500_add_spi3(pdata) \
-       dbx500_add_spi("spi3", U5500_SPI3_BASE, IRQ_DB5500_SPI3, pdata \
+#define db5500_add_spi3(parent, pdata) \
+       dbx500_add_spi(parent, "spi3", U5500_SPI3_BASE, \
+                      IRQ_DB5500_SPI3, pdata           \
                       0x10080023)
 
-#define db5500_add_uart0(plat) \
-       dbx500_add_uart("uart0", U5500_UART0_BASE, IRQ_DB5500_UART0, plat)
-#define db5500_add_uart1(plat) \
-       dbx500_add_uart("uart1", U5500_UART1_BASE, IRQ_DB5500_UART1, plat)
-#define db5500_add_uart2(plat) \
-       dbx500_add_uart("uart2", U5500_UART2_BASE, IRQ_DB5500_UART2, plat)
-#define db5500_add_uart3(plat) \
-       dbx500_add_uart("uart3", U5500_UART3_BASE, IRQ_DB5500_UART3, plat)
+#define db5500_add_uart0(parent, plat) \
+       dbx500_add_uart(parent, "uart0", U5500_UART0_BASE, \
+                       IRQ_DB5500_UART0, plat)
+#define db5500_add_uart1(parent, plat) \
+       dbx500_add_uart(parent, "uart1", U5500_UART1_BASE, \
+                       IRQ_DB5500_UART1, plat)
+#define db5500_add_uart2(parent, plat) \
+       dbx500_add_uart(parent, "uart2", U5500_UART2_BASE, \
+                       IRQ_DB5500_UART2, plat)
+#define db5500_add_uart3(parent, plat) \
+       dbx500_add_uart(parent, "uart3", U5500_UART3_BASE, \
+                       IRQ_DB5500_UART3, plat)
 
 #endif
index a7c6cdc9b11e5cacfb846215f2f88af9835c00a4..6e66d3777ed51723deb030b45a4558518c5130c7 100644 (file)
@@ -101,6 +101,9 @@ static const dma_addr_t dma40_tx_map[DB8500_DMA_NR_DEV] = {
        [DB8500_DMA_DEV41_SD_MM3_TX] = -1,
        [DB8500_DMA_DEV42_SD_MM4_TX] = -1,
        [DB8500_DMA_DEV43_SD_MM5_TX] = -1,
+       [DB8500_DMA_DEV14_MSP2_TX] = U8500_MSP2_BASE + MSP_TX_RX_REG_OFFSET,
+       [DB8500_DMA_DEV30_MSP1_TX] = U8500_MSP1_BASE + MSP_TX_RX_REG_OFFSET,
+       [DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX] = U8500_MSP0_BASE + MSP_TX_RX_REG_OFFSET,
 };
 
 /* Mapping between source event lines and physical device address */
@@ -133,6 +136,9 @@ static const dma_addr_t dma40_rx_map[DB8500_DMA_NR_DEV] = {
        [DB8500_DMA_DEV41_SD_MM3_RX] = -1,
        [DB8500_DMA_DEV42_SD_MM4_RX] = -1,
        [DB8500_DMA_DEV43_SD_MM5_RX] = -1,
+       [DB8500_DMA_DEV14_MSP2_RX] = U8500_MSP2_BASE + MSP_TX_RX_REG_OFFSET,
+       [DB8500_DMA_DEV30_MSP3_RX] = U8500_MSP3_BASE + MSP_TX_RX_REG_OFFSET,
+       [DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX] = U8500_MSP0_BASE + MSP_TX_RX_REG_OFFSET,
 };
 
 /* Reserved event lines for memcpy only */
index cbd4a9ae81093a14e7ca73c67cadc0869c6d579d..9fd93e9da529084146a8b1590f1dab8023c9c7d8 100644 (file)
@@ -14,88 +14,114 @@ struct ske_keypad_platform_data;
 struct pl022_ssp_controller;
 
 static inline struct platform_device *
-db8500_add_ske_keypad(struct ske_keypad_platform_data *pdata)
+db8500_add_ske_keypad(struct device *parent,
+                     struct ske_keypad_platform_data *pdata,
+                     size_t size)
 {
-       return dbx500_add_platform_device_4k1irq("nmk-ske-keypad", -1,
-                                                U8500_SKE_BASE,
-                                                IRQ_DB8500_KB, pdata);
+       struct resource resources[] = {
+               DEFINE_RES_MEM(U8500_SKE_BASE, SZ_4K),
+               DEFINE_RES_IRQ(IRQ_DB8500_KB),
+       };
+
+       return platform_device_register_resndata(parent, "nmk-ske-keypad", -1,
+                                                resources, 2, pdata, size);
 }
 
 static inline struct amba_device *
-db8500_add_ssp(const char *name, resource_size_t base, int irq,
-              struct pl022_ssp_controller *pdata)
+db8500_add_ssp(struct device *parent, const char *name, resource_size_t base,
+              int irq, struct pl022_ssp_controller *pdata)
 {
-       return dbx500_add_amba_device(name, base, irq, pdata, 0);
+       return dbx500_add_amba_device(parent, name, base, irq, pdata, 0);
 }
 
 
-#define db8500_add_i2c0(pdata) \
-       dbx500_add_i2c(0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata)
-#define db8500_add_i2c1(pdata) \
-       dbx500_add_i2c(1, U8500_I2C1_BASE, IRQ_DB8500_I2C1, pdata)
-#define db8500_add_i2c2(pdata) \
-       dbx500_add_i2c(2, U8500_I2C2_BASE, IRQ_DB8500_I2C2, pdata)
-#define db8500_add_i2c3(pdata) \
-       dbx500_add_i2c(3, U8500_I2C3_BASE, IRQ_DB8500_I2C3, pdata)
-#define db8500_add_i2c4(pdata) \
-       dbx500_add_i2c(4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata)
-
-#define db8500_add_msp0_i2s(pdata) \
-       dbx500_add_msp_i2s(0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata)
-#define db8500_add_msp1_i2s(pdata) \
-       dbx500_add_msp_i2s(1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata)
-#define db8500_add_msp2_i2s(pdata) \
-       dbx500_add_msp_i2s(2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata)
-#define db8500_add_msp3_i2s(pdata) \
-       dbx500_add_msp_i2s(3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata)
-
-#define db8500_add_msp0_spi(pdata) \
-       dbx500_add_msp_spi("msp0", U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata)
-#define db8500_add_msp1_spi(pdata) \
-       dbx500_add_msp_spi("msp1", U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata)
-#define db8500_add_msp2_spi(pdata) \
-       dbx500_add_msp_spi("msp2", U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata)
-#define db8500_add_msp3_spi(pdata) \
-       dbx500_add_msp_spi("msp3", U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata)
-
-#define db8500_add_rtc() \
-       dbx500_add_rtc(U8500_RTC_BASE, IRQ_DB8500_RTC);
-
-#define db8500_add_usb(rx_cfg, tx_cfg) \
-       ux500_add_usb(U8500_USBOTG_BASE, IRQ_DB8500_USBOTG, rx_cfg, tx_cfg)
-
-#define db8500_add_sdi0(pdata, pid) \
-       dbx500_add_sdi("sdi0", U8500_SDI0_BASE, IRQ_DB8500_SDMMC0, pdata, pid)
-#define db8500_add_sdi1(pdata, pid) \
-       dbx500_add_sdi("sdi1", U8500_SDI1_BASE, IRQ_DB8500_SDMMC1, pdata, pid)
-#define db8500_add_sdi2(pdata, pid) \
-       dbx500_add_sdi("sdi2", U8500_SDI2_BASE, IRQ_DB8500_SDMMC2, pdata, pid)
-#define db8500_add_sdi3(pdata, pid) \
-       dbx500_add_sdi("sdi3", U8500_SDI3_BASE, IRQ_DB8500_SDMMC3, pdata, pid)
-#define db8500_add_sdi4(pdata, pid) \
-       dbx500_add_sdi("sdi4", U8500_SDI4_BASE, IRQ_DB8500_SDMMC4, pdata, pid)
-#define db8500_add_sdi5(pdata, pid) \
-       dbx500_add_sdi("sdi5", U8500_SDI5_BASE, IRQ_DB8500_SDMMC5, pdata, pid)
-
-#define db8500_add_ssp0(pdata) \
-       db8500_add_ssp("ssp0", U8500_SSP0_BASE, IRQ_DB8500_SSP0, pdata)
-#define db8500_add_ssp1(pdata) \
-       db8500_add_ssp("ssp1", U8500_SSP1_BASE, IRQ_DB8500_SSP1, pdata)
-
-#define db8500_add_spi0(pdata) \
-       dbx500_add_spi("spi0", U8500_SPI0_BASE, IRQ_DB8500_SPI0, pdata, 0)
-#define db8500_add_spi1(pdata) \
-       dbx500_add_spi("spi1", U8500_SPI1_BASE, IRQ_DB8500_SPI1, pdata, 0)
-#define db8500_add_spi2(pdata) \
-       dbx500_add_spi("spi2", U8500_SPI2_BASE, IRQ_DB8500_SPI2, pdata, 0)
-#define db8500_add_spi3(pdata) \
-       dbx500_add_spi("spi3", U8500_SPI3_BASE, IRQ_DB8500_SPI3, pdata, 0)
-
-#define db8500_add_uart0(pdata) \
-       dbx500_add_uart("uart0", U8500_UART0_BASE, IRQ_DB8500_UART0, pdata)
-#define db8500_add_uart1(pdata) \
-       dbx500_add_uart("uart1", U8500_UART1_BASE, IRQ_DB8500_UART1, pdata)
-#define db8500_add_uart2(pdata) \
-       dbx500_add_uart("uart2", U8500_UART2_BASE, IRQ_DB8500_UART2, pdata)
+#define db8500_add_i2c0(parent, pdata) \
+       dbx500_add_i2c(parent, 0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata)
+#define db8500_add_i2c1(parent, pdata) \
+       dbx500_add_i2c(parent, 1, U8500_I2C1_BASE, IRQ_DB8500_I2C1, pdata)
+#define db8500_add_i2c2(parent, pdata) \
+       dbx500_add_i2c(parent, 2, U8500_I2C2_BASE, IRQ_DB8500_I2C2, pdata)
+#define db8500_add_i2c3(parent, pdata) \
+       dbx500_add_i2c(parent, 3, U8500_I2C3_BASE, IRQ_DB8500_I2C3, pdata)
+#define db8500_add_i2c4(parent, pdata) \
+       dbx500_add_i2c(parent, 4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata)
+
+#define db8500_add_msp0_i2s(parent, pdata) \
+       dbx500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata)
+#define db8500_add_msp1_i2s(parent, pdata) \
+       dbx500_add_msp_i2s(parent, 1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata)
+#define db8500_add_msp2_i2s(parent, pdata) \
+       dbx500_add_msp_i2s(parent, 2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata)
+#define db8500_add_msp3_i2s(parent, pdata) \
+       dbx500_add_msp_i2s(parent, 3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata)
+
+#define db8500_add_msp0_spi(parent, pdata) \
+       dbx500_add_msp_spi(parent, "msp0", U8500_MSP0_BASE, \
+                          IRQ_DB8500_MSP0, pdata)
+#define db8500_add_msp1_spi(parent, pdata) \
+       dbx500_add_msp_spi(parent, "msp1", U8500_MSP1_BASE, \
+                          IRQ_DB8500_MSP1, pdata)
+#define db8500_add_msp2_spi(parent, pdata) \
+       dbx500_add_msp_spi(parent, "msp2", U8500_MSP2_BASE, \
+                          IRQ_DB8500_MSP2, pdata)
+#define db8500_add_msp3_spi(parent, pdata) \
+       dbx500_add_msp_spi(parent, "msp3", U8500_MSP3_BASE, \
+                          IRQ_DB8500_MSP1, pdata)
+
+#define db8500_add_rtc(parent) \
+       dbx500_add_rtc(parent, U8500_RTC_BASE, IRQ_DB8500_RTC);
+
+#define db8500_add_usb(parent, rx_cfg, tx_cfg) \
+       ux500_add_usb(parent, U8500_USBOTG_BASE, \
+                     IRQ_DB8500_USBOTG, rx_cfg, tx_cfg)
+
+#define db8500_add_sdi0(parent, pdata, pid) \
+       dbx500_add_sdi(parent, "sdi0", U8500_SDI0_BASE, \
+                      IRQ_DB8500_SDMMC0, pdata, pid)
+#define db8500_add_sdi1(parent, pdata, pid) \
+       dbx500_add_sdi(parent, "sdi1", U8500_SDI1_BASE, \
+                      IRQ_DB8500_SDMMC1, pdata, pid)
+#define db8500_add_sdi2(parent, pdata, pid) \
+       dbx500_add_sdi(parent, "sdi2", U8500_SDI2_BASE, \
+                      IRQ_DB8500_SDMMC2, pdata, pid)
+#define db8500_add_sdi3(parent, pdata, pid) \
+       dbx500_add_sdi(parent, "sdi3", U8500_SDI3_BASE, \
+                      IRQ_DB8500_SDMMC3, pdata, pid)
+#define db8500_add_sdi4(parent, pdata, pid) \
+       dbx500_add_sdi(parent, "sdi4", U8500_SDI4_BASE, \
+                      IRQ_DB8500_SDMMC4, pdata, pid)
+#define db8500_add_sdi5(parent, pdata, pid) \
+       dbx500_add_sdi(parent, "sdi5", U8500_SDI5_BASE, \
+                      IRQ_DB8500_SDMMC5, pdata, pid)
+
+#define db8500_add_ssp0(parent, pdata) \
+       db8500_add_ssp(parent, "ssp0", U8500_SSP0_BASE, \
+                      IRQ_DB8500_SSP0, pdata)
+#define db8500_add_ssp1(parent, pdata) \
+       db8500_add_ssp(parent, "ssp1", U8500_SSP1_BASE, \
+                      IRQ_DB8500_SSP1, pdata)
+
+#define db8500_add_spi0(parent, pdata) \
+       dbx500_add_spi(parent, "spi0", U8500_SPI0_BASE, \
+                      IRQ_DB8500_SPI0, pdata, 0)
+#define db8500_add_spi1(parent, pdata) \
+       dbx500_add_spi(parent, "spi1", U8500_SPI1_BASE, \
+                      IRQ_DB8500_SPI1, pdata, 0)
+#define db8500_add_spi2(parent, pdata) \
+       dbx500_add_spi(parent, "spi2", U8500_SPI2_BASE, \
+                      IRQ_DB8500_SPI2, pdata, 0)
+#define db8500_add_spi3(parent, pdata) \
+       dbx500_add_spi(parent, "spi3", U8500_SPI3_BASE, \
+                      IRQ_DB8500_SPI3, pdata, 0)
+
+#define db8500_add_uart0(parent, pdata) \
+       dbx500_add_uart(parent, "uart0", U8500_UART0_BASE, \
+                       IRQ_DB8500_UART0, pdata)
+#define db8500_add_uart1(parent, pdata) \
+       dbx500_add_uart(parent, "uart1", U8500_UART1_BASE, \
+                       IRQ_DB8500_UART1, pdata)
+#define db8500_add_uart2(parent, pdata) \
+       dbx500_add_uart(parent, "uart2", U8500_UART2_BASE, \
+                       IRQ_DB8500_UART2, pdata)
 
 #endif
index 1cfab68ae417506cb70905c24f92ab8217d878b5..41e9470fa0e6e327855204cdc54db49cfaf7da7f 100644 (file)
@@ -125,10 +125,11 @@ static struct platform_device dma40_device = {
        .resource       = dma40_resources
 };
 
-void __init db5500_dma_init(void)
+void __init db5500_dma_init(struct device *parent)
 {
        int ret;
 
+       dma40_device.dev.parent = parent;
        ret = platform_device_register(&dma40_device);
        if (ret)
                dev_err(&dma40_device.dev, "unable to register device: %d\n", ret);
index 80e10f50282ea47b9f7b95ffa5e751e500dfe879..9ec20b96d8f2bd33f256ae74e127dd592e6e6095 100644 (file)
 #define U8500_MODEM_BASE       0xe000000
 #define U8500_APE_BASE         0x6000000
 
+/* SoC identification number information */
+#define U8500_BB_UID_BASE      (U8500_BACKUPRAM1_BASE + 0xFC0)
+
 #endif
index b6ba26a1367da3ebffcc2cfa794a2f7c3497743c..d93d6dbef25b8a0a9c8c8a1647cb0bc93517ba0f 100644 (file)
@@ -30,6 +30,8 @@
 #include <mach/db8500-regs.h>
 #include <mach/db5500-regs.h>
 
+#define MSP_TX_RX_REG_OFFSET   0
+
 #ifndef __ASSEMBLY__
 
 #include <mach/id.h>
index 9db68d264c5f727c1fffc15f5a563d4b2a9d9a65..c23a6b5f0c4eefd58220620043316d999b3d651d 100644 (file)
@@ -43,7 +43,7 @@
 /* This will be overridden by board-specific irq headers */
 #define IRQ_BOARD_END          IRQ_BOARD_START
 
-#ifdef CONFIG_MACH_U8500
+#ifdef CONFIG_MACH_MOP500
 #include <mach/irqs-board-mop500.h>
 #endif
 
index a7d363fdb4cd7ba3f88591ffa7222f156e3c6a27..3dc00ffa7bfa5d54772dc5201757b1c3ff12bc27 100644 (file)
@@ -18,17 +18,16 @@ void __init ux500_map_io(void);
 extern void __init u5500_map_io(void);
 extern void __init u8500_map_io(void);
 
-extern void __init u5500_init_devices(void);
-extern void __init u8500_init_devices(void);
+extern struct device * __init u5500_init_devices(void);
+extern struct device * __init u8500_init_devices(void);
 
 extern void __init ux500_init_irq(void);
 
-extern void __init u5500_sdi_init(void);
+extern void __init u5500_sdi_init(struct device *parent);
 
-extern void __init db5500_dma_init(void);
+extern void __init db5500_dma_init(struct device *parent);
 
-/* We re-use nomadik_timer for this platform */
-extern void nmdk_timer_init(void);
+extern struct device *ux500_soc_device_init(const char *soc_id);
 
 struct amba_device;
 extern void __init amba_add_devices(struct amba_device *devs[], int num);
index d3739d418813f5ddf64f64dea4e99fea57961f24..4c1cc50a595a1cee719de30e8b936c87152b367b 100644 (file)
@@ -20,6 +20,6 @@ struct ux500_musb_board_data {
        bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
 };
 
-void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg,
-       int *dma_tx_cfg);
+void ux500_add_usb(struct device *parent, resource_size_t base,
+                  int irq, int *dma_rx_cfg, int *dma_tx_cfg);
 #endif
diff --git a/arch/arm/mach-ux500/localtimer.c b/arch/arm/mach-ux500/localtimer.c
deleted file mode 100644 (file)
index 5ba1133..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2008-2009 ST-Ericsson
- * Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
- *
- * This file is heavily based on relaview platform, almost a copy.
- *
- * Copyright (C) 2002 ARM Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/clockchips.h>
-
-#include <asm/irq.h>
-#include <asm/smp_twd.h>
-#include <asm/localtimer.h>
-
-/*
- * Setup the local clock events for a CPU.
- */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-       evt->irq = IRQ_LOCALTIMER;
-       twd_timer_setup(evt);
-       return 0;
-}
index aea467d04ff7399506d92594dd9ecbc2adc81765..d37df98b5c32588d65450867900e7d87a6f4aec9 100644 (file)
@@ -7,29 +7,52 @@
 #include <linux/io.h>
 #include <linux/errno.h>
 #include <linux/clksrc-dbx500-prcmu.h>
+#include <linux/of.h>
 
-#include <asm/localtimer.h>
+#include <asm/smp_twd.h>
 
 #include <plat/mtu.h>
 
 #include <mach/setup.h>
 #include <mach/hardware.h>
+#include <mach/irqs.h>
+
+#ifdef CONFIG_HAVE_ARM_TWD
+static DEFINE_TWD_LOCAL_TIMER(u5500_twd_local_timer,
+                             U5500_TWD_BASE, IRQ_LOCALTIMER);
+static DEFINE_TWD_LOCAL_TIMER(u8500_twd_local_timer,
+                             U8500_TWD_BASE, IRQ_LOCALTIMER);
+
+static void __init ux500_twd_init(void)
+{
+       struct twd_local_timer *twd_local_timer;
+       int err;
+
+       twd_local_timer = cpu_is_u5500() ? &u5500_twd_local_timer :
+                                          &u8500_twd_local_timer;
+
+       if (of_have_populated_dt())
+               twd_local_timer_of_register();
+       else {
+               err = twd_local_timer_register(twd_local_timer);
+               if (err)
+                       pr_err("twd_local_timer_register failed %d\n", err);
+       }
+}
+#else
+#define ux500_twd_init()       do { } while(0)
+#endif
 
 static void __init ux500_timer_init(void)
 {
+       void __iomem *mtu_timer_base;
        void __iomem *prcmu_timer_base;
 
        if (cpu_is_u5500()) {
-#ifdef CONFIG_LOCAL_TIMERS
-               twd_base = __io_address(U5500_TWD_BASE);
-#endif
-               mtu_base = __io_address(U5500_MTU0_BASE);
+               mtu_timer_base = __io_address(U5500_MTU0_BASE);
                prcmu_timer_base = __io_address(U5500_PRCMU_TIMER_3_BASE);
        } else if (cpu_is_u8500()) {
-#ifdef CONFIG_LOCAL_TIMERS
-               twd_base = __io_address(U8500_TWD_BASE);
-#endif
-               mtu_base = __io_address(U8500_MTU0_BASE);
+               mtu_timer_base = __io_address(U8500_MTU0_BASE);
                prcmu_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE);
        } else {
                ux500_unknown_soc();
@@ -52,8 +75,9 @@ static void __init ux500_timer_init(void)
         *
         */
 
-       nmdk_timer_init();
+       nmdk_timer_init(mtu_timer_base);
        clksrc_dbx500_prcmu_init(prcmu_timer_base);
+       ux500_twd_init();
 }
 
 static void ux500_timer_reset(void)
index 9f9e1c203061dc8cbe0cff19cd69420462b05810..a74af389bc63764df14498079c1e75e1df69d53a 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/platform_device.h>
 #include <linux/usb/musb.h>
 #include <linux/dma-mapping.h>
+
 #include <plat/ste_dma40.h>
 #include <mach/hardware.h>
 #include <mach/usb.h>
@@ -140,8 +141,8 @@ static inline void ux500_usb_dma_update_tx_ch_config(int *dst_dev_type)
                musb_dma_tx_ch[idx].dst_dev_type = dst_dev_type[idx];
 }
 
-void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg,
-       int *dma_tx_cfg)
+void ux500_add_usb(struct device *parent, resource_size_t base, int irq,
+                  int *dma_rx_cfg, int *dma_tx_cfg)
 {
        ux500_musb_device.resource[0].start = base;
        ux500_musb_device.resource[0].end = base + SZ_64K - 1;
@@ -151,5 +152,7 @@ void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg,
        ux500_usb_dma_update_rx_ch_config(dma_rx_cfg);
        ux500_usb_dma_update_tx_ch_config(dma_tx_cfg);
 
+       ux500_musb_device.dev.parent = parent;
+
        platform_device_register(&ux500_musb_device);
 }
index 88c3ba151e8716c93abbabebc8265f81db806ea8..cf8730d35e70bec50ff00d3a35aa4942b1d4d042 100644 (file)
@@ -1,14 +1,55 @@
 menu "Versatile Express platform type"
        depends on ARCH_VEXPRESS
 
+config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
+       bool
+       select ARM_ERRATA_720789
+       select ARM_ERRATA_751472
+       select PL310_ERRATA_753970 if CACHE_PL310
+       help
+         Provides common dependencies for Versatile Express platforms
+         based on Cortex-A5 and Cortex-A9 processors. In order to
+         build a working kernel, you must also enable relevant core
+         tile support or Flattened Device Tree based support options.
+
 config ARCH_VEXPRESS_CA9X4
        bool "Versatile Express Cortex-A9x4 tile"
+       select ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
+       select ARM_GIC
        select CPU_V7
+       select HAVE_SMP
+       select MIGHT_HAVE_CACHE_L2X0
+
+config ARCH_VEXPRESS_DT
+       bool "Device Tree support for Versatile Express platforms"
+       select ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
        select ARM_GIC
-       select ARM_ERRATA_720789
-       select ARM_ERRATA_751472
-       select PL310_ERRATA_753970
+       select ARM_PATCH_PHYS_VIRT
+       select AUTO_ZRELADDR
+       select CPU_V7
        select HAVE_SMP
        select MIGHT_HAVE_CACHE_L2X0
+       select USE_OF
+       help
+         New Versatile Express platforms require Flattened Device Tree to
+         be passed to the kernel.
+
+         This option enables support for systems using Cortex processor based
+         ARM core and logic (FPGA) tiles on the Versatile Express motherboard,
+         for example:
+
+         - CoreTile Express A5x2 (V2P-CA5s)
+         - CoreTile Express A9x4 (V2P-CA9)
+         - CoreTile Express A15x2 (V2P-CA15)
+         - LogicTile Express 13MG (V2F-2XV6) with A5, A7, A9 or A15 SMMs
+           (Soft Macrocell Models)
+         - Versatile Express RTSMs (Models)
+
+         You must boot using a Flattened Device Tree in order to use these
+         platforms. The traditional (ATAGs) boot method is not usable on
+         these boards with this option.
+
+         If your bootloader supports Flattened Device Tree based booting,
+         say Y here.
 
 endmenu
index 8630b3d10a4d0252968718da5302dfed7934d979..909f85ebf5f4c2871c17bfa82700238c3f613f04 100644 (file)
@@ -1,3 +1,9 @@
+# Those numbers are used only by the non-DT V2P-CA9 platform
+# The DT-enabled ones require CONFIG_AUTO_ZRELADDR=y
    zreladdr-y  += 0x60008000
 params_phys-y  := 0x60000100
 initrd_phys-y  := 0x60800000
+
+dtb-$(CONFIG_ARCH_VEXPRESS_DT) += vexpress-v2p-ca5s.dtb \
+                                  vexpress-v2p-ca9.dtb \
+                                  vexpress-v2p-ca15-tc1.dtb
index 9f0f2827c7111fad6f4825d633960224aa89a6cc..a3a4980770bdccf27cfb3a0fe426692ae999f218 100644 (file)
@@ -1,2 +1,7 @@
-#define __MMIO_P2V(x)  (((x) & 0xfffff) | (((x) & 0x0f000000) >> 4) | 0xf8000000)
-#define MMIO_P2V(x)    ((void __iomem *)__MMIO_P2V(x))
+/* 2MB large area for motherboard's peripherals static mapping */
+#define V2M_PERIPH 0xf8000000
+
+/* Tile's peripherals static mappings should start here */
+#define V2T_PERIPH 0xf8200000
+
+void vexpress_dt_smp_map_io(void);
index 1b1d2e4892b9c188677902ed0356c5d4bbbbd59a..c65cc3b462a5ddef5aad8e4421305c8d22104191 100644 (file)
 
 #include <plat/clcd.h>
 
-#define V2M_PA_CS7     0x10000000
-
 static struct map_desc ct_ca9x4_io_desc[] __initdata = {
        {
-               .virtual        = __MMIO_P2V(CT_CA9X4_MPIC),
-               .pfn            = __phys_to_pfn(CT_CA9X4_MPIC),
-               .length         = SZ_16K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = __MMIO_P2V(CT_CA9X4_SP804_TIMER),
-               .pfn            = __phys_to_pfn(CT_CA9X4_SP804_TIMER),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = __MMIO_P2V(CT_CA9X4_L2CC),
-               .pfn            = __phys_to_pfn(CT_CA9X4_L2CC),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
+               .virtual        = V2T_PERIPH,
+               .pfn            = __phys_to_pfn(CT_CA9X4_MPIC),
+               .length         = SZ_8K,
+               .type           = MT_DEVICE,
        },
 };
 
 static void __init ct_ca9x4_map_io(void)
 {
-#ifdef CONFIG_LOCAL_TIMERS
-       twd_base = MMIO_P2V(A9_MPCORE_TWD);
-#endif
        iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
 }
 
-static void __init ct_ca9x4_init_irq(void)
+#ifdef CONFIG_HAVE_ARM_TWD
+static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, A9_MPCORE_TWD, IRQ_LOCALTIMER);
+
+static void __init ca9x4_twd_init(void)
 {
-       gic_init(0, 29, MMIO_P2V(A9_MPCORE_GIC_DIST),
-                MMIO_P2V(A9_MPCORE_GIC_CPU));
+       int err = twd_local_timer_register(&twd_local_timer);
+       if (err)
+               pr_err("twd_local_timer_register failed %d\n", err);
 }
+#else
+#define ca9x4_twd_init()       do {} while(0)
+#endif
 
-#if 0
-static void __init ct_ca9x4_timer_init(void)
+static void __init ct_ca9x4_init_irq(void)
 {
-       writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL);
-       writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL);
-
-       sp804_clocksource_init(MMIO_P2V(CT_CA9X4_TIMER1), "ct-timer1");
-       sp804_clockevents_init(MMIO_P2V(CT_CA9X4_TIMER0), IRQ_CT_CA9X4_TIMER0,
-               "ct-timer0");
+       gic_init(0, 29, ioremap(A9_MPCORE_GIC_DIST, SZ_4K),
+                ioremap(A9_MPCORE_GIC_CPU, SZ_256));
+       ca9x4_twd_init();
 }
 
-static struct sys_timer ct_ca9x4_timer = {
-       .init   = ct_ca9x4_timer_init,
-};
-#endif
-
 static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
 {
        v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0);
@@ -201,7 +184,7 @@ static void __init ct_ca9x4_init(void)
        int i;
 
 #ifdef CONFIG_CACHE_L2X0
-       void __iomem *l2x0_base = MMIO_P2V(CT_CA9X4_L2CC);
+       void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K);
 
        /* set RAM latencies to 1 cycle for this core tile. */
        writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL);
@@ -217,9 +200,17 @@ static void __init ct_ca9x4_init(void)
 }
 
 #ifdef CONFIG_SMP
+static void *ct_ca9x4_scu_base __initdata;
+
 static void __init ct_ca9x4_init_cpu_map(void)
 {
-       int i, ncores = scu_get_core_count(MMIO_P2V(A9_MPCORE_SCU));
+       int i, ncores;
+
+       ct_ca9x4_scu_base = ioremap(A9_MPCORE_SCU, SZ_128);
+       if (WARN_ON(!ct_ca9x4_scu_base))
+               return;
+
+       ncores = scu_get_core_count(ct_ca9x4_scu_base);
 
        if (ncores > nr_cpu_ids) {
                pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
@@ -235,7 +226,7 @@ static void __init ct_ca9x4_init_cpu_map(void)
 
 static void __init ct_ca9x4_smp_enable(unsigned int max_cpus)
 {
-       scu_enable(MMIO_P2V(A9_MPCORE_SCU));
+       scu_enable(ct_ca9x4_scu_base);
 }
 #endif
 
index a40468f3b938f28fdeb4f10f5b94663e11015a05..84acf8439d4bf4cef4aeb60d678e1b8d6b6c04f7 100644 (file)
@@ -22,9 +22,6 @@
 #define CT_CA9X4_SYSWDT                (0x1e007000)
 #define CT_CA9X4_L2CC          (0x1e00a000)
 
-#define CT_CA9X4_TIMER0                (CT_CA9X4_SP804_TIMER + 0x000)
-#define CT_CA9X4_TIMER1                (CT_CA9X4_SP804_TIMER + 0x020)
-
 #define A9_MPCORE_SCU          (CT_CA9X4_MPIC + 0x0000)
 #define A9_MPCORE_GIC_CPU      (CT_CA9X4_MPIC + 0x0100)
 #define A9_MPCORE_GIT          (CT_CA9X4_MPIC + 0x0200)
index fd9e6c7ea49fb4c6df897c00d9193896948a52ef..fa8224794e0b75c6a6139d92f0102f5d79d6d829 100644 (file)
  * published by the Free Software Foundation.
  */
 
-#define DEBUG_LL_UART_OFFSET   0x00009000
+#define DEBUG_LL_PHYS_BASE             0x10000000
+#define DEBUG_LL_UART_OFFSET           0x00009000
+
+#define DEBUG_LL_PHYS_BASE_RS1         0x1c000000
+#define DEBUG_LL_UART_OFFSET_RS1       0x00090000
+
+#define DEBUG_LL_VIRT_BASE             0xf8000000
 
                .macro  addruart,rp,rv,tmp
-               mov     \rp, #DEBUG_LL_UART_OFFSET
-               orr     \rv, \rp, #0xf8000000   @ virtual base
-               orr     \rp, \rp, #0x10000000   @ physical base
+
+               @ Make an educated guess regarding the memory map:
+               @ - the original A9 core tile, which has MPCore peripherals
+               @   located at 0x1e000000, should use UART at 0x10009000
+               @ - all other (RS1 complaint) tiles use UART mapped
+               @   at 0x1c090000
+               mrc     p15, 4, \tmp, c15, c0, 0
+               cmp     \tmp, #0x1e000000
+
+               @ Original memory map
+               moveq   \rp, #DEBUG_LL_UART_OFFSET
+               orreq   \rv, \rp, #DEBUG_LL_VIRT_BASE
+               orreq   \rp, \rp, #DEBUG_LL_PHYS_BASE
+
+               @ RS1 memory map
+               movne   \rp, #DEBUG_LL_UART_OFFSET_RS1
+               orrne   \rv, \rp, #DEBUG_LL_VIRT_BASE
+               orrne   \rp, \rp, #DEBUG_LL_PHYS_BASE_RS1
+
                .endm
 
 #include <asm/hardware/debug-pl01x.S>
index 7054cbfc9de54c112f6fbb0d6cb960c57dbc65d0..4b10ee7657a66f463626170165ef8903788410bf 100644 (file)
@@ -1,4 +1,4 @@
 #define IRQ_LOCALTIMER         29
 #define IRQ_LOCALWDOG          30
 
-#define NR_IRQS        128
+#define NR_IRQS        256
index 0a3a375184052a81ea64f7588555919aeee899a4..31a92890893d79385dae0e72ed1a097f8e0f637d 100644 (file)
 #define V2M_CF                 (V2M_PA_CS7 + 0x0001a000)
 #define V2M_CLCD               (V2M_PA_CS7 + 0x0001f000)
 
-#define V2M_SYS_ID             (V2M_SYSREGS + 0x000)
-#define V2M_SYS_SW             (V2M_SYSREGS + 0x004)
-#define V2M_SYS_LED            (V2M_SYSREGS + 0x008)
-#define V2M_SYS_100HZ          (V2M_SYSREGS + 0x024)
-#define V2M_SYS_FLAGS          (V2M_SYSREGS + 0x030)
-#define V2M_SYS_FLAGSSET       (V2M_SYSREGS + 0x030)
-#define V2M_SYS_FLAGSCLR       (V2M_SYSREGS + 0x034)
-#define V2M_SYS_NVFLAGS                (V2M_SYSREGS + 0x038)
-#define V2M_SYS_NVFLAGSSET     (V2M_SYSREGS + 0x038)
-#define V2M_SYS_NVFLAGSCLR     (V2M_SYSREGS + 0x03c)
-#define V2M_SYS_MCI            (V2M_SYSREGS + 0x048)
-#define V2M_SYS_FLASH          (V2M_SYSREGS + 0x03c)
-#define V2M_SYS_CFGSW          (V2M_SYSREGS + 0x058)
-#define V2M_SYS_24MHZ          (V2M_SYSREGS + 0x05c)
-#define V2M_SYS_MISC           (V2M_SYSREGS + 0x060)
-#define V2M_SYS_DMA            (V2M_SYSREGS + 0x064)
-#define V2M_SYS_PROCID0                (V2M_SYSREGS + 0x084)
-#define V2M_SYS_PROCID1                (V2M_SYSREGS + 0x088)
-#define V2M_SYS_CFGDATA                (V2M_SYSREGS + 0x0a0)
-#define V2M_SYS_CFGCTRL                (V2M_SYSREGS + 0x0a4)
-#define V2M_SYS_CFGSTAT                (V2M_SYSREGS + 0x0a8)
-
-#define V2M_TIMER0             (V2M_TIMER01 + 0x000)
-#define V2M_TIMER1             (V2M_TIMER01 + 0x020)
-
-#define V2M_TIMER2             (V2M_TIMER23 + 0x000)
-#define V2M_TIMER3             (V2M_TIMER23 + 0x020)
+/*
+ * Offsets from SYSREGS base
+ */
+#define V2M_SYS_ID             0x000
+#define V2M_SYS_SW             0x004
+#define V2M_SYS_LED            0x008
+#define V2M_SYS_100HZ          0x024
+#define V2M_SYS_FLAGS          0x030
+#define V2M_SYS_FLAGSSET       0x030
+#define V2M_SYS_FLAGSCLR       0x034
+#define V2M_SYS_NVFLAGS                0x038
+#define V2M_SYS_NVFLAGSSET     0x038
+#define V2M_SYS_NVFLAGSCLR     0x03c
+#define V2M_SYS_MCI            0x048
+#define V2M_SYS_FLASH          0x03c
+#define V2M_SYS_CFGSW          0x058
+#define V2M_SYS_24MHZ          0x05c
+#define V2M_SYS_MISC           0x060
+#define V2M_SYS_DMA            0x064
+#define V2M_SYS_PROCID0                0x084
+#define V2M_SYS_PROCID1                0x088
+#define V2M_SYS_CFGDATA                0x0a0
+#define V2M_SYS_CFGCTRL                0x0a4
+#define V2M_SYS_CFGSTAT                0x0a8
 
 
 /*
 
 int v2m_cfg_write(u32 devfn, u32 data);
 int v2m_cfg_read(u32 devfn, u32 *data);
+void v2m_flags_set(u32 data);
+
+/*
+ * Miscellaneous
+ */
+#define SYS_MISC_MASTERSITE    (1 << 14)
+#define SYS_PROCIDx_HBI_MASK   0xfff
 
 /*
  * Core tile IDs
index 7972c5748d0ec237960be604f9fb7e5a26e3d4a7..7dab5596b86831936e59053207c9721c7dabbdd1 100644 (file)
 #define AMBA_UART_CR(base)     (*(volatile unsigned char *)((base) + 0x30))
 #define AMBA_UART_FR(base)     (*(volatile unsigned char *)((base) + 0x18))
 
-#define get_uart_base()        (0x10000000 + 0x00009000)
+#define UART_BASE      0x10009000
+#define UART_BASE_RS1  0x1c090000
+
+static unsigned long get_uart_base(void)
+{
+       unsigned long mpcore_periph;
+
+       /*
+        * Make an educated guess regarding the memory map:
+        * - the original A9 core tile, which has MPCore peripherals
+        *   located at 0x1e000000, should use UART at 0x10009000
+        * - all other (RS1 complaint) tiles use UART mapped
+        *   at 0x1c090000
+        */
+       asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (mpcore_periph));
+
+       if (mpcore_periph == 0x1e000000)
+               return UART_BASE;
+       else
+               return UART_BASE_RS1;
+}
 
 /*
  * This does not append a newline
index 124ffb16909382f1383673783812fd5a1354f70c..14ba1128ae8dd3e12c61ccfc0153e1fef0d624b7 100644 (file)
 #include <linux/errno.h>
 #include <linux/smp.h>
 #include <linux/io.h>
+#include <linux/of_fdt.h>
+
+#include <asm/smp_scu.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach/map.h>
 
 #include <mach/motherboard.h>
-#define V2M_PA_CS7 0x10000000
 
 #include "core.h"
 
 extern void versatile_secondary_startup(void);
 
+#if defined(CONFIG_OF)
+
+static enum {
+       GENERIC_SCU,
+       CORTEX_A9_SCU,
+} vexpress_dt_scu __initdata = GENERIC_SCU;
+
+static struct map_desc vexpress_dt_cortex_a9_scu_map __initdata = {
+       .virtual        = V2T_PERIPH,
+       /* .pfn set in vexpress_dt_init_cortex_a9_scu() */
+       .length         = SZ_128,
+       .type           = MT_DEVICE,
+};
+
+static void *vexpress_dt_cortex_a9_scu_base __initdata;
+
+const static char *vexpress_dt_cortex_a9_match[] __initconst = {
+       "arm,cortex-a5-scu",
+       "arm,cortex-a9-scu",
+       NULL
+};
+
+static int __init vexpress_dt_find_scu(unsigned long node,
+               const char *uname, int depth, void *data)
+{
+       if (of_flat_dt_match(node, vexpress_dt_cortex_a9_match)) {
+               phys_addr_t phys_addr;
+               __be32 *reg = of_get_flat_dt_prop(node, "reg", NULL);
+
+               if (WARN_ON(!reg))
+                       return -EINVAL;
+
+               phys_addr = be32_to_cpup(reg);
+               vexpress_dt_scu = CORTEX_A9_SCU;
+
+               vexpress_dt_cortex_a9_scu_map.pfn = __phys_to_pfn(phys_addr);
+               iotable_init(&vexpress_dt_cortex_a9_scu_map, 1);
+               vexpress_dt_cortex_a9_scu_base = ioremap(phys_addr, SZ_256);
+               if (WARN_ON(!vexpress_dt_cortex_a9_scu_base))
+                       return -EFAULT;
+       }
+
+       return 0;
+}
+
+void __init vexpress_dt_smp_map_io(void)
+{
+       if (initial_boot_params)
+               WARN_ON(of_scan_flat_dt(vexpress_dt_find_scu, NULL));
+}
+
+static int __init vexpress_dt_cpus_num(unsigned long node, const char *uname,
+               int depth, void *data)
+{
+       static int prev_depth = -1;
+       static int nr_cpus = -1;
+
+       if (prev_depth > depth && nr_cpus > 0)
+               return nr_cpus;
+
+       if (nr_cpus < 0 && strcmp(uname, "cpus") == 0)
+               nr_cpus = 0;
+
+       if (nr_cpus >= 0) {
+               const char *device_type = of_get_flat_dt_prop(node,
+                               "device_type", NULL);
+
+               if (device_type && strcmp(device_type, "cpu") == 0)
+                       nr_cpus++;
+       }
+
+       prev_depth = depth;
+
+       return 0;
+}
+
+static void __init vexpress_dt_smp_init_cpus(void)
+{
+       int ncores = 0, i;
+
+       switch (vexpress_dt_scu) {
+       case GENERIC_SCU:
+               ncores = of_scan_flat_dt(vexpress_dt_cpus_num, NULL);
+               break;
+       case CORTEX_A9_SCU:
+               ncores = scu_get_core_count(vexpress_dt_cortex_a9_scu_base);
+               break;
+       default:
+               WARN_ON(1);
+               break;
+       }
+
+       if (ncores < 2)
+               return;
+
+       if (ncores > nr_cpu_ids) {
+               pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
+                               ncores, nr_cpu_ids);
+               ncores = nr_cpu_ids;
+       }
+
+       for (i = 0; i < ncores; ++i)
+               set_cpu_possible(i, true);
+
+       set_smp_cross_call(gic_raise_softirq);
+}
+
+static void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus)
+{
+       int i;
+
+       switch (vexpress_dt_scu) {
+       case GENERIC_SCU:
+               for (i = 0; i < max_cpus; i++)
+                       set_cpu_present(i, true);
+               break;
+       case CORTEX_A9_SCU:
+               scu_enable(vexpress_dt_cortex_a9_scu_base);
+               break;
+       default:
+               WARN_ON(1);
+               break;
+       }
+}
+
+#else
+
+static void __init vexpress_dt_smp_init_cpus(void)
+{
+       WARN_ON(1);
+}
+
+void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus)
+{
+       WARN_ON(1);
+}
+
+#endif
+
 /*
  * Initialise the CPU possible map early - this describes the CPUs
  * which may be present or become present in the system.
  */
 void __init smp_init_cpus(void)
 {
-       ct_desc->init_cpu_map();
+       if (ct_desc)
+               ct_desc->init_cpu_map();
+       else
+               vexpress_dt_smp_init_cpus();
+
 }
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
@@ -35,7 +182,10 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
         * Initialise the present map, which describes the set of CPUs
         * actually populated at the present time.
         */
-       ct_desc->smp_enable(max_cpus);
+       if (ct_desc)
+               ct_desc->smp_enable(max_cpus);
+       else
+               vexpress_dt_smp_prepare_cpus(max_cpus);
 
        /*
         * Write the address of secondary startup into the
@@ -43,7 +193,5 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
         * until it receives a soft interrupt, and then the
         * secondary CPU branches to this address.
         */
-       writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
-       writel(virt_to_phys(versatile_secondary_startup),
-               MMIO_P2V(V2M_SYS_FLAGSSET));
+       v2m_flags_set(virt_to_phys(versatile_secondary_startup));
 }
index ad64f97a2003f007b9462df267731cbb872d0d73..47cdcca5a7e76ca59d727b6750564c23a43f2f5b 100644 (file)
@@ -6,6 +6,10 @@
 #include <linux/amba/mmci.h>
 #include <linux/io.h>
 #include <linux/init.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/ata_platform.h>
 #include <linux/smsc911x.h>
@@ -21,6 +25,8 @@
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 #include <asm/hardware/arm_timer.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/hardware/gic.h>
 #include <asm/hardware/timer-sp.h>
 #include <asm/hardware/sp810.h>
 #include <asm/hardware/gic.h>
 
 static struct map_desc v2m_io_desc[] __initdata = {
        {
-               .virtual        = __MMIO_P2V(V2M_PA_CS7),
+               .virtual        = V2M_PERIPH,
                .pfn            = __phys_to_pfn(V2M_PA_CS7),
                .length         = SZ_128K,
                .type           = MT_DEVICE,
        },
 };
 
-static void __init v2m_timer_init(void)
+static void __iomem *v2m_sysreg_base;
+
+static void __init v2m_sysctl_init(void __iomem *base)
 {
        u32 scctrl;
 
+       if (WARN_ON(!base))
+               return;
+
        /* Select 1MHz TIMCLK as the reference clock for SP804 timers */
-       scctrl = readl(MMIO_P2V(V2M_SYSCTL + SCCTRL));
+       scctrl = readl(base + SCCTRL);
        scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK;
        scctrl |= SCCTRL_TIMEREN1SEL_TIMCLK;
-       writel(scctrl, MMIO_P2V(V2M_SYSCTL + SCCTRL));
+       writel(scctrl, base + SCCTRL);
+}
+
+static void __init v2m_sp804_init(void __iomem *base, unsigned int irq)
+{
+       if (WARN_ON(!base || irq == NO_IRQ))
+               return;
+
+       writel(0, base + TIMER_1_BASE + TIMER_CTRL);
+       writel(0, base + TIMER_2_BASE + TIMER_CTRL);
 
-       writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL);
-       writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL);
+       sp804_clocksource_init(base + TIMER_2_BASE, "v2m-timer1");
+       sp804_clockevents_init(base + TIMER_1_BASE, irq, "v2m-timer0");
+}
 
-       sp804_clocksource_init(MMIO_P2V(V2M_TIMER1), "v2m-timer1");
-       sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0,
-               "v2m-timer0");
+static void __init v2m_timer_init(void)
+{
+       v2m_sysctl_init(ioremap(V2M_SYSCTL, SZ_4K));
+       v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0);
 }
 
 static struct sys_timer v2m_timer = {
@@ -82,14 +104,14 @@ int v2m_cfg_write(u32 devfn, u32 data)
        devfn |= SYS_CFG_START | SYS_CFG_WRITE;
 
        spin_lock(&v2m_cfg_lock);
-       val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
-       writel(val & ~SYS_CFG_COMPLETE, MMIO_P2V(V2M_SYS_CFGSTAT));
+       val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT);
+       writel(val & ~SYS_CFG_COMPLETE, v2m_sysreg_base + V2M_SYS_CFGSTAT);
 
-       writel(data, MMIO_P2V(V2M_SYS_CFGDATA));
-       writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL));
+       writel(data, v2m_sysreg_base +  V2M_SYS_CFGDATA);
+       writel(devfn, v2m_sysreg_base + V2M_SYS_CFGCTRL);
 
        do {
-               val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
+               val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT);
        } while (val == 0);
        spin_unlock(&v2m_cfg_lock);
 
@@ -103,22 +125,28 @@ int v2m_cfg_read(u32 devfn, u32 *data)
        devfn |= SYS_CFG_START;
 
        spin_lock(&v2m_cfg_lock);
-       writel(0, MMIO_P2V(V2M_SYS_CFGSTAT));
-       writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL));
+       writel(0, v2m_sysreg_base + V2M_SYS_CFGSTAT);
+       writel(devfn, v2m_sysreg_base + V2M_SYS_CFGCTRL);
 
        mb();
 
        do {
                cpu_relax();
-               val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
+               val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT);
        } while (val == 0);
 
-       *data = readl(MMIO_P2V(V2M_SYS_CFGDATA));
+       *data = readl(v2m_sysreg_base + V2M_SYS_CFGDATA);
        spin_unlock(&v2m_cfg_lock);
 
        return !!(val & SYS_CFG_ERR);
 }
 
+void __init v2m_flags_set(u32 data)
+{
+       writel(~0, v2m_sysreg_base + V2M_SYS_FLAGSCLR);
+       writel(data, v2m_sysreg_base + V2M_SYS_FLAGSSET);
+}
+
 
 static struct resource v2m_pcie_i2c_resource = {
        .start  = V2M_SERIAL_BUS_PCI,
@@ -204,7 +232,7 @@ static struct platform_device v2m_usb_device = {
 
 static void v2m_flash_set_vpp(struct platform_device *pdev, int on)
 {
-       writel(on != 0, MMIO_P2V(V2M_SYS_FLASH));
+       writel(on != 0, v2m_sysreg_base + V2M_SYS_FLASH);
 }
 
 static struct physmap_flash_data v2m_flash_data = {
@@ -258,7 +286,7 @@ static struct platform_device v2m_cf_device = {
 
 static unsigned int v2m_mmci_status(struct device *dev)
 {
-       return readl(MMIO_P2V(V2M_SYS_MCI)) & (1 << 0);
+       return readl(v2m_sysreg_base + V2M_SYS_MCI) & (1 << 0);
 }
 
 static struct mmci_platform_data v2m_mmci_data = {
@@ -371,7 +399,7 @@ static void __init v2m_init_early(void)
 {
        ct_desc->init_early();
        clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups));
-       versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
+       versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000);
 }
 
 static void v2m_power_off(void)
@@ -400,20 +428,23 @@ static void __init v2m_populate_ct_desc(void)
        u32 current_tile_id;
 
        ct_desc = NULL;
-       current_tile_id = readl(MMIO_P2V(V2M_SYS_PROCID0)) & V2M_CT_ID_MASK;
+       current_tile_id = readl(v2m_sysreg_base + V2M_SYS_PROCID0)
+                               & V2M_CT_ID_MASK;
 
        for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i)
                if (ct_descs[i]->id == current_tile_id)
                        ct_desc = ct_descs[i];
 
        if (!ct_desc)
-               panic("vexpress: failed to populate core tile description "
-                     "for tile ID 0x%8x\n", current_tile_id);
+               panic("vexpress: this kernel does not support core tile ID 0x%08x when booting via ATAGs.\n"
+                     "You may need a device tree blob or a different kernel to boot on this board.\n",
+                     current_tile_id);
 }
 
 static void __init v2m_map_io(void)
 {
        iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
+       v2m_sysreg_base = ioremap(V2M_SYSREGS, SZ_4K);
        v2m_populate_ct_desc();
        ct_desc->map_io();
 }
@@ -452,3 +483,205 @@ MACHINE_START(VEXPRESS, "ARM-Versatile Express")
        .init_machine   = v2m_init,
        .restart        = v2m_restart,
 MACHINE_END
+
+#if defined(CONFIG_ARCH_VEXPRESS_DT)
+
+static struct map_desc v2m_rs1_io_desc __initdata = {
+       .virtual        = V2M_PERIPH,
+       .pfn            = __phys_to_pfn(0x1c000000),
+       .length         = SZ_2M,
+       .type           = MT_DEVICE,
+};
+
+static int __init v2m_dt_scan_memory_map(unsigned long node, const char *uname,
+               int depth, void *data)
+{
+       const char **map = data;
+
+       if (strcmp(uname, "motherboard") != 0)
+               return 0;
+
+       *map = of_get_flat_dt_prop(node, "arm,v2m-memory-map", NULL);
+
+       return 1;
+}
+
+void __init v2m_dt_map_io(void)
+{
+       const char *map = NULL;
+
+       of_scan_flat_dt(v2m_dt_scan_memory_map, &map);
+
+       if (map && strcmp(map, "rs1") == 0)
+               iotable_init(&v2m_rs1_io_desc, 1);
+       else
+               iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
+
+#if defined(CONFIG_SMP)
+       vexpress_dt_smp_map_io();
+#endif
+}
+
+static struct clk_lookup v2m_dt_lookups[] = {
+       {       /* AMBA bus clock */
+               .con_id         = "apb_pclk",
+               .clk            = &dummy_apb_pclk,
+       }, {    /* SP804 timers */
+               .dev_id         = "sp804",
+               .con_id         = "v2m-timer0",
+               .clk            = &v2m_sp804_clk,
+       }, {    /* SP804 timers */
+               .dev_id         = "sp804",
+               .con_id         = "v2m-timer1",
+               .clk            = &v2m_sp804_clk,
+       }, {    /* PL180 MMCI */
+               .dev_id         = "mb:mmci", /* 10005000.mmci */
+               .clk            = &osc2_clk,
+       }, {    /* PL050 KMI0 */
+               .dev_id         = "10006000.kmi",
+               .clk            = &osc2_clk,
+       }, {    /* PL050 KMI1 */
+               .dev_id         = "10007000.kmi",
+               .clk            = &osc2_clk,
+       }, {    /* PL011 UART0 */
+               .dev_id         = "10009000.uart",
+               .clk            = &osc2_clk,
+       }, {    /* PL011 UART1 */
+               .dev_id         = "1000a000.uart",
+               .clk            = &osc2_clk,
+       }, {    /* PL011 UART2 */
+               .dev_id         = "1000b000.uart",
+               .clk            = &osc2_clk,
+       }, {    /* PL011 UART3 */
+               .dev_id         = "1000c000.uart",
+               .clk            = &osc2_clk,
+       }, {    /* SP805 WDT */
+               .dev_id         = "1000f000.wdt",
+               .clk            = &v2m_ref_clk,
+       }, {    /* PL111 CLCD */
+               .dev_id         = "1001f000.clcd",
+               .clk            = &osc1_clk,
+       },
+       /* RS1 memory map */
+       {       /* PL180 MMCI */
+               .dev_id         = "mb:mmci", /* 1c050000.mmci */
+               .clk            = &osc2_clk,
+       }, {    /* PL050 KMI0 */
+               .dev_id         = "1c060000.kmi",
+               .clk            = &osc2_clk,
+       }, {    /* PL050 KMI1 */
+               .dev_id         = "1c070000.kmi",
+               .clk            = &osc2_clk,
+       }, {    /* PL011 UART0 */
+               .dev_id         = "1c090000.uart",
+               .clk            = &osc2_clk,
+       }, {    /* PL011 UART1 */
+               .dev_id         = "1c0a0000.uart",
+               .clk            = &osc2_clk,
+       }, {    /* PL011 UART2 */
+               .dev_id         = "1c0b0000.uart",
+               .clk            = &osc2_clk,
+       }, {    /* PL011 UART3 */
+               .dev_id         = "1c0c0000.uart",
+               .clk            = &osc2_clk,
+       }, {    /* SP805 WDT */
+               .dev_id         = "1c0f0000.wdt",
+               .clk            = &v2m_ref_clk,
+       }, {    /* PL111 CLCD */
+               .dev_id         = "1c1f0000.clcd",
+               .clk            = &osc1_clk,
+       },
+};
+
+void __init v2m_dt_init_early(void)
+{
+       struct device_node *node;
+       u32 dt_hbi;
+
+       node = of_find_compatible_node(NULL, NULL, "arm,vexpress-sysreg");
+       v2m_sysreg_base = of_iomap(node, 0);
+       if (WARN_ON(!v2m_sysreg_base))
+               return;
+
+       /* Confirm board type against DT property, if available */
+       if (of_property_read_u32(allnodes, "arm,hbi", &dt_hbi) == 0) {
+               u32 misc = readl(v2m_sysreg_base + V2M_SYS_MISC);
+               u32 id = readl(v2m_sysreg_base + (misc & SYS_MISC_MASTERSITE ?
+                               V2M_SYS_PROCID1 : V2M_SYS_PROCID0));
+               u32 hbi = id & SYS_PROCIDx_HBI_MASK;
+
+               if (WARN_ON(dt_hbi != hbi))
+                       pr_warning("vexpress: DT HBI (%x) is not matching "
+                                       "hardware (%x)!\n", dt_hbi, hbi);
+       }
+
+       clkdev_add_table(v2m_dt_lookups, ARRAY_SIZE(v2m_dt_lookups));
+       versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000);
+}
+
+static  struct of_device_id vexpress_irq_match[] __initdata = {
+       { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
+       {}
+};
+
+static void __init v2m_dt_init_irq(void)
+{
+       of_irq_init(vexpress_irq_match);
+}
+
+static void __init v2m_dt_timer_init(void)
+{
+       struct device_node *node;
+       const char *path;
+       int err;
+
+       node = of_find_compatible_node(NULL, NULL, "arm,sp810");
+       v2m_sysctl_init(of_iomap(node, 0));
+
+       err = of_property_read_string(of_aliases, "arm,v2m_timer", &path);
+       if (WARN_ON(err))
+               return;
+       node = of_find_node_by_path(path);
+       v2m_sp804_init(of_iomap(node, 0), irq_of_parse_and_map(node, 0));
+}
+
+static struct sys_timer v2m_dt_timer = {
+       .init = v2m_dt_timer_init,
+};
+
+static struct of_dev_auxdata v2m_dt_auxdata_lookup[] __initdata = {
+       OF_DEV_AUXDATA("arm,vexpress-flash", V2M_NOR0, "physmap-flash",
+                       &v2m_flash_data),
+       OF_DEV_AUXDATA("arm,primecell", V2M_MMCI, "mb:mmci", &v2m_mmci_data),
+       /* RS1 memory map */
+       OF_DEV_AUXDATA("arm,vexpress-flash", 0x08000000, "physmap-flash",
+                       &v2m_flash_data),
+       OF_DEV_AUXDATA("arm,primecell", 0x1c050000, "mb:mmci", &v2m_mmci_data),
+       {}
+};
+
+static void __init v2m_dt_init(void)
+{
+       l2x0_of_init(0x00400000, 0xfe0fffff);
+       of_platform_populate(NULL, of_default_bus_match_table,
+                       v2m_dt_auxdata_lookup, NULL);
+       pm_power_off = v2m_power_off;
+}
+
+const static char *v2m_dt_match[] __initconst = {
+       "arm,vexpress",
+       NULL,
+};
+
+DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express")
+       .dt_compat      = v2m_dt_match,
+       .map_io         = v2m_dt_map_io,
+       .init_early     = v2m_dt_init_early,
+       .init_irq       = v2m_dt_init_irq,
+       .timer          = &v2m_dt_timer,
+       .init_machine   = v2m_dt_init,
+       .handle_irq     = gic_handle_irq,
+       .restart        = v2m_restart,
+MACHINE_END
+
+#endif
index 55f15699a3835cba42c5509fc62b031db4e033d7..689f81f9593bf436adbca616cc0904bfe8cb59b1 100644 (file)
@@ -60,7 +60,7 @@ static int avic_irq_set_priority(unsigned char irq, unsigned char prio)
        unsigned int mask = 0x0F << irq % 8 * 4;
 
        if (irq >= AVIC_NUM_IRQS)
-               return -EINVAL;;
+               return -EINVAL;
 
        temp = __raw_readl(avic_base + AVIC_NIPRIORITY(irq / 8));
        temp &= ~mask;
index f5b7e0fa237fba3686afb83b90aa4ff3eb18585c..220dd6f93126367efdbce0b1b7630fab4cec25d1 100644 (file)
@@ -1,5 +1,6 @@
 
 #include <linux/module.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
 
 unsigned int __mxc_cpu_type;
@@ -18,3 +19,26 @@ void imx_print_silicon_rev(const char *cpu, int srev)
                pr_info("CPU identified as %s, silicon rev %d.%d\n",
                                cpu, (srev >> 4) & 0xf, srev & 0xf);
 }
+
+void __init imx_set_aips(void __iomem *base)
+{
+       unsigned int reg;
+/*
+ * Set all MPROTx to be non-bufferable, trusted for R/W,
+ * not forced to user-mode.
+ */
+       __raw_writel(0x77777777, base + 0x0);
+       __raw_writel(0x77777777, base + 0x4);
+
+/*
+ * Set all OPACRx to be non-bufferable, to not require
+ * supervisor privilege level for access, allow for
+ * write access and untrusted master access.
+ */
+       __raw_writel(0x0, base + 0x40);
+       __raw_writel(0x0, base + 0x44);
+       __raw_writel(0x0, base + 0x48);
+       __raw_writel(0x0, base + 0x4C);
+       reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
+       __raw_writel(reg, base + 0x50);
+}
index d8a56aee521b3281ca9b3f62fea52e624973b804..ade4a1c4e2a39e4aac13479deb48af97fd142c0b 100644 (file)
@@ -60,9 +60,9 @@ static int imx_sata_init(struct device *dev, void __iomem *addr)
                dev_err(dev, "no sata clock.\n");
                return PTR_ERR(sata_clk);
        }
-       ret = clk_enable(sata_clk);
+       ret = clk_prepare_enable(sata_clk);
        if (ret) {
-               dev_err(dev, "can't enable sata clock.\n");
+               dev_err(dev, "can't prepare/enable sata clock.\n");
                goto put_sata_clk;
        }
 
@@ -73,9 +73,9 @@ static int imx_sata_init(struct device *dev, void __iomem *addr)
                ret = PTR_ERR(sata_ref_clk);
                goto release_sata_clk;
        }
-       ret = clk_enable(sata_ref_clk);
+       ret = clk_prepare_enable(sata_ref_clk);
        if (ret) {
-               dev_err(dev, "can't enable sata ref clock.\n");
+               dev_err(dev, "can't prepare/enable sata ref clock.\n");
                goto put_sata_ref_clk;
        }
 
@@ -104,11 +104,11 @@ static int imx_sata_init(struct device *dev, void __iomem *addr)
        return 0;
 
 release_sata_ref_clk:
-       clk_disable(sata_ref_clk);
+       clk_disable_unprepare(sata_ref_clk);
 put_sata_ref_clk:
        clk_put(sata_ref_clk);
 release_sata_clk:
-       clk_disable(sata_clk);
+       clk_disable_unprepare(sata_clk);
 put_sata_clk:
        clk_put(sata_clk);
 
@@ -117,10 +117,10 @@ put_sata_clk:
 
 static void imx_sata_exit(struct device *dev)
 {
-       clk_disable(sata_ref_clk);
+       clk_disable_unprepare(sata_ref_clk);
        clk_put(sata_ref_clk);
 
-       clk_disable(sata_clk);
+       clk_disable_unprepare(sata_clk);
        clk_put(sata_clk);
 
 }
index d3467f818c3397188075801d13343863182707ee..9129c9e7d532b2a08f2f464e489aeabad5f1badf 100644 (file)
@@ -203,7 +203,7 @@ static int __init epit_clockevent_init(struct clk *timer_clk)
 
 void __init epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
 {
-       clk_enable(timer_clk);
+       clk_prepare_enable(timer_clk);
 
        timer_base = base;
 
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31ads.h b/arch/arm/plat-mxc/include/mach/board-mx31ads.h
deleted file mode 100644 (file)
index 94b60dd..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_ARCH_MXC_BOARD_MX31ADS_H__
-#define __ASM_ARCH_MXC_BOARD_MX31ADS_H__
-
-#include <mach/hardware.h>
-
-/*
- * These symbols are used by drivers/net/cs89x0.c.
- * This is ugly as hell, but we have to provide them until
- * someone fixed the driver.
- */
-
-/* Base address of PBC controller */
-#define PBC_BASE_ADDRESS        MX31_CS4_BASE_ADDR_VIRT
-/* Offsets for the PBC Controller register */
-
-/* Ethernet Controller IO base address */
-#define PBC_CS8900A_IOBASE      0x020000
-
-#define MXC_EXP_IO_BASE                (MXC_BOARD_IRQ_START)
-
-#define EXPIO_INT_ENET_INT     (MXC_EXP_IO_BASE + 8)
-
-#endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */
index 1bf0df81bdc69dec5c08140454adcebc0f888dd0..0319c4a0cafaffc0869e2b74d632340ce2a05867 100644 (file)
@@ -65,6 +65,7 @@ extern int mx51_clocks_init(unsigned long ckil, unsigned long osc,
                        unsigned long ckih1, unsigned long ckih2);
 extern int mx53_clocks_init(unsigned long ckil, unsigned long osc,
                        unsigned long ckih1, unsigned long ckih2);
+extern int mx27_clocks_init_dt(void);
 extern int mx51_clocks_init_dt(void);
 extern int mx53_clocks_init_dt(void);
 extern int mx6q_clocks_init(void);
@@ -75,6 +76,7 @@ extern void mxc_restart(char, const char *);
 extern void mxc_arch_reset_init(void __iomem *);
 extern int mx53_revision(void);
 extern int mx53_display_revision(void);
+extern void imx_set_aips(void __iomem *);
 
 enum mxc_cpu_pwr_mode {
        WAIT_CLOCKED,           /* wfi only */
@@ -84,6 +86,14 @@ enum mxc_cpu_pwr_mode {
        STOP_POWER_OFF,         /* STOP + SRPG */
 };
 
+enum mx3_cpu_pwr_mode {
+       MX3_RUN,
+       MX3_WAIT,
+       MX3_DOZE,
+       MX3_SLEEP,
+};
+
+extern void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode);
 extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode);
 extern void imx_print_silicon_rev(const char *cpu, int srev);
 
index 6e192c4a391a2af315ab3ae6f73a6603b49040cc..8ddda365f1a0c3637b73e456312740dd3de13126 100644 (file)
@@ -24,7 +24,7 @@
 #define UART_PADDR     MX51_UART1_BASE_ADDR
 #elif defined (CONFIG_DEBUG_IMX50_IMX53_UART)
 #define UART_PADDR     MX53_UART1_BASE_ADDR
-#elif defined (CONFIG_DEBUG_IMX6Q_UART)
+#elif defined (CONFIG_DEBUG_IMX6Q_UART4)
 #define UART_PADDR     MX6Q_UART4_BASE_ADDR
 #endif
 
index 233d0a5e2d68f1451b29ce18e331a384fabaf5a5..1b9080385b4618b2b3c76ab057a7bf271df8d73d 100644 (file)
@@ -60,8 +60,7 @@ static inline int imx_dma_is_ipu(struct dma_chan *chan)
 
 static inline int imx_dma_is_general_purpose(struct dma_chan *chan)
 {
-       return !strcmp(dev_name(chan->device->dev), "imx31-sdma") ||
-               !strcmp(dev_name(chan->device->dev), "imx35-sdma") ||
+       return strstr(dev_name(chan->device->dev), "sdma") ||
                !strcmp(dev_name(chan->device->dev), "imx-dma");
 }
 
index f0726d48df2276f4ec4baa0ac76e4ec678ba96ce..c61ec0fc10d47899c1ffc8dfb361fa1de73f273a 100644 (file)
 #define MX25_PAD_NFRB__GPIO_3_31       IOMUX_PAD(0x27c, 0x084, 0x15, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_D15__D15              IOMUX_PAD(0x280, 0x088, 0x00, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_D15__LD16             IOMUX_PAD(0x280, 0x088, 0x01, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D15__LD16             IOMUX_PAD(0x280, 0x088, 0x01, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_D15__GPIO_4_5         IOMUX_PAD(0x280, 0x088, 0x05, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_D14__D14              IOMUX_PAD(0x284, 0x08c, 0x00, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_D14__LD17             IOMUX_PAD(0x284, 0x08c, 0x01, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D14__LD17             IOMUX_PAD(0x284, 0x08c, 0x01, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_D14__GPIO_4_6         IOMUX_PAD(0x284, 0x08c, 0x05, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_D13__D13              IOMUX_PAD(0x288, 0x090, 0x00, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_D13__LD18             IOMUX_PAD(0x288, 0x090, 0x01, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D13__LD18             IOMUX_PAD(0x288, 0x090, 0x01, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_D13__GPIO_4_7         IOMUX_PAD(0x288, 0x090, 0x05, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_D12__D12              IOMUX_PAD(0x28c, 0x094, 0x00, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_D0__D0                        IOMUX_PAD(0x2bc, 0x0c4, 0x00, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_D0__GPIO_4_20         IOMUX_PAD(0x2bc, 0x0c4, 0x05, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_LD0__LD0              IOMUX_PAD(0x2c0, 0x0c8, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD0__LD0              IOMUX_PAD(0x2c0, 0x0c8, 0x10, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_LD0__CSI_D0           IOMUX_PAD(0x2c0, 0x0c8, 0x12, 0x488, 0, NO_PAD_CTRL)
 #define MX25_PAD_LD0__GPIO_2_15                IOMUX_PAD(0x2c0, 0x0c8, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_LD1__LD1              IOMUX_PAD(0x2c4, 0x0cc, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD1__LD1              IOMUX_PAD(0x2c4, 0x0cc, 0x10, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_LD1__CSI_D1           IOMUX_PAD(0x2c4, 0x0cc, 0x12, 0x48c, 0, NO_PAD_CTRL)
 #define MX25_PAD_LD1__GPIO_2_16                IOMUX_PAD(0x2c4, 0x0cc, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_LD2__LD2              IOMUX_PAD(0x2c8, 0x0d0, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD2__LD2              IOMUX_PAD(0x2c8, 0x0d0, 0x10, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_LD2__GPIO_2_17                IOMUX_PAD(0x2c8, 0x0d0, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_LD3__LD3              IOMUX_PAD(0x2cc, 0x0d4, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD3__LD3              IOMUX_PAD(0x2cc, 0x0d4, 0x10, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_LD3__GPIO_2_18                IOMUX_PAD(0x2cc, 0x0d4, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_LD4__LD4              IOMUX_PAD(0x2d0, 0x0d8, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD4__LD4              IOMUX_PAD(0x2d0, 0x0d8, 0x10, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_LD4__GPIO_2_19                IOMUX_PAD(0x2d0, 0x0d8, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_LD5__LD5              IOMUX_PAD(0x2d4, 0x0dc, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD5__LD5              IOMUX_PAD(0x2d4, 0x0dc, 0x10, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_LD5__GPIO_1_19                IOMUX_PAD(0x2d4, 0x0dc, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_LD6__LD6              IOMUX_PAD(0x2d8, 0x0e0, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD6__LD6              IOMUX_PAD(0x2d8, 0x0e0, 0x10, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_LD6__GPIO_1_20                IOMUX_PAD(0x2d8, 0x0e0, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_LD7__LD7              IOMUX_PAD(0x2dc, 0x0e4, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD7__LD7              IOMUX_PAD(0x2dc, 0x0e4, 0x10, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_LD7__GPIO_1_21                IOMUX_PAD(0x2dc, 0x0e4, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_LD8__LD8              IOMUX_PAD(0x2e0, 0x0e8, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD8__LD8              IOMUX_PAD(0x2e0, 0x0e8, 0x10, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_LD8__FEC_TX_ERR       IOMUX_PAD(0x2e0, 0x0e8, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_LD9__LD9              IOMUX_PAD(0x2e4, 0x0ec, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD9__LD9              IOMUX_PAD(0x2e4, 0x0ec, 0x10, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_LD9__FEC_COL          IOMUX_PAD(0x2e4, 0x0ec, 0x15, 0x504, 1, NO_PAD_CTRL)
 
-#define MX25_PAD_LD10__LD10            IOMUX_PAD(0x2e8, 0x0f0, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD10__LD10            IOMUX_PAD(0x2e8, 0x0f0, 0x10, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_LD10__FEC_RX_ER       IOMUX_PAD(0x2e8, 0x0f0, 0x15, 0x518, 1, NO_PAD_CTRL)
 
-#define MX25_PAD_LD11__LD11            IOMUX_PAD(0x2ec, 0x0f4, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD11__LD11            IOMUX_PAD(0x2ec, 0x0f4, 0x10, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_LD11__FEC_RDATA2      IOMUX_PAD(0x2ec, 0x0f4, 0x15, 0x50c, 1, NO_PAD_CTRL)
 
-#define MX25_PAD_LD12__LD12            IOMUX_PAD(0x2f0, 0x0f8, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD12__LD12            IOMUX_PAD(0x2f0, 0x0f8, 0x10, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_LD12__FEC_RDATA3      IOMUX_PAD(0x2f0, 0x0f8, 0x15, 0x510, 1, NO_PAD_CTRL)
 
-#define MX25_PAD_LD13__LD13            IOMUX_PAD(0x2f4, 0x0fc, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD13__LD13            IOMUX_PAD(0x2f4, 0x0fc, 0x10, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_LD13__FEC_TDATA2      IOMUX_PAD(0x2f4, 0x0fc, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_LD14__LD14            IOMUX_PAD(0x2f8, 0x100, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD14__LD14            IOMUX_PAD(0x2f8, 0x100, 0x10, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_LD14__FEC_TDATA3      IOMUX_PAD(0x2f8, 0x100, 0x15, 0, 0, NO_PAD_CTRL)
 
-#define MX25_PAD_LD15__LD15            IOMUX_PAD(0x2fc, 0x104, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD15__LD15            IOMUX_PAD(0x2fc, 0x104, 0x10, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_LD15__FEC_RX_CLK      IOMUX_PAD(0x2fc, 0x104, 0x15, 0x514, 1, NO_PAD_CTRL)
 
 #define MX25_PAD_HSYNC__HSYNC          IOMUX_PAD(0x300, 0x108, 0x10, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_GPIO_C__CAN2_TX       IOMUX_PAD(0x3f8, 0x1fc, 0x16, 0, 0, PAD_CTL_PUS_22K_UP)
 
 #define MX25_PAD_GPIO_D__GPIO_D                IOMUX_PAD(0x3fc, 0x200, 0x10, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_GPIO_E__LD16          IOMUX_PAD(0x400, 0x204, 0x02, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_E__LD16          IOMUX_PAD(0x400, 0x204, 0x02, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_GPIO_D__CAN2_RX       IOMUX_PAD(0x3fc, 0x200, 0x16, 0x484, 1, PAD_CTL_PUS_22K_UP)
 
 #define MX25_PAD_GPIO_E__GPIO_E                IOMUX_PAD(0x400, 0x204, 0x10, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_GPIO_F__LD17          IOMUX_PAD(0x404, 0x208, 0x02, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_F__LD17          IOMUX_PAD(0x404, 0x208, 0x02, 0, 0, PAD_CTL_SRE_FAST)
 #define MX25_PAD_GPIO_E__AUD7_TXD      IOMUX_PAD(0x400, 0x204, 0x14, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_GPIO_F__GPIO_F                IOMUX_PAD(0x404, 0x208, 0x10, 0, 0, NO_PAD_CTRL)
index e032717f7d02c211ee8cad0d0200cec5f83974cf..c0cab2270dd171f64b713fb5b3a1700fb298900c 100644 (file)
@@ -132,7 +132,7 @@ int pwm_enable(struct pwm_device *pwm)
        int rc = 0;
 
        if (!pwm->clk_enabled) {
-               rc = clk_enable(pwm->clk);
+               rc = clk_prepare_enable(pwm->clk);
                if (!rc)
                        pwm->clk_enabled = 1;
        }
@@ -145,7 +145,7 @@ void pwm_disable(struct pwm_device *pwm)
        writel(0, pwm->mmio_base + MX3_PWMCR);
 
        if (pwm->clk_enabled) {
-               clk_disable(pwm->clk);
+               clk_disable_unprepare(pwm->clk);
                pwm->clk_enabled = 0;
        }
 }
index 3599bf2cfd4f7a351717bb3abdd2f54160d4d712..f30dcacbbd0aef44b68a26cbd82563b7b8320a8e 100644 (file)
@@ -48,7 +48,7 @@ void mxc_restart(char mode, const char *cmd)
 
                clk = clk_get_sys("imx2-wdt.0", NULL);
                if (!IS_ERR(clk))
-                       clk_enable(clk);
+                       clk_prepare_enable(clk);
                wcr_enable = (1 << 2);
        }
 
index 1c96cdb4c35e9036ff78e97a084a1423a720e1ca..7daf7c9a413bf62eb9a7ad86f659a0eadf016d44 100644 (file)
@@ -283,7 +283,7 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
 {
        uint32_t tctl_val;
 
-       clk_enable(timer_clk);
+       clk_prepare_enable(timer_clk);
 
        timer_base = base;
 
index 6508e7694a4b2275f2510ce25cea55028c02467e..582641f3dc01acf611f34edb846f741ded736d8c 100644 (file)
@@ -1,9 +1,7 @@
 #ifndef __PLAT_MTU_H
 #define __PLAT_MTU_H
 
-/* should be set by the platform code */
-extern void __iomem *mtu_base;
-
+void nmdk_timer_init(void __iomem *base);
 void nmdk_clkevt_reset(void);
 void nmdk_clksrc_reset(void);
 
index ad1b45b605a42b9441eb4b9d3d7a38485ba9ca9c..9222e5522a43e97236c86f55c28006c1bea3a8e2 100644 (file)
 #include <asm/mach/time.h>
 #include <asm/sched_clock.h>
 
-/*
- * Guaranteed runtime conversion range in seconds for
- * the clocksource and clockevent.
- */
-#define MTU_MIN_RANGE 4
-
 /*
  * The MTU device hosts four different counters, with 4 set of
  * registers. These are register names.
 #define MTU_PCELL2     0xff8
 #define MTU_PCELL3     0xffC
 
+static void __iomem *mtu_base;
 static bool clkevt_periodic;
 static u32 clk_prescale;
 static u32 nmdk_cycle;         /* write-once */
 
-void __iomem *mtu_base; /* Assigned by machine code */
-
 #ifdef CONFIG_NOMADIK_MTU_SCHED_CLOCK
 /*
  * Override the global weak sched_clock symbol with this
@@ -103,7 +96,6 @@ static int nmdk_clkevt_next(unsigned long evt, struct clock_event_device *ev)
 void nmdk_clkevt_reset(void)
 {
        if (clkevt_periodic) {
-
                /* Timer: configure load and background-load, and fire it up */
                writel(nmdk_cycle, mtu_base + MTU_LR(1));
                writel(nmdk_cycle, mtu_base + MTU_BGLR(1));
@@ -121,7 +113,6 @@ void nmdk_clkevt_reset(void)
 static void nmdk_clkevt_mode(enum clock_event_mode mode,
                             struct clock_event_device *dev)
 {
-
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
                clkevt_periodic = true;
@@ -183,15 +174,16 @@ void nmdk_clksrc_reset(void)
               mtu_base + MTU_CR(0));
 }
 
-void __init nmdk_timer_init(void)
+void __init nmdk_timer_init(void __iomem *base)
 {
        unsigned long rate;
        struct clk *clk0;
 
+       mtu_base = base;
        clk0 = clk_get_sys("mtu0", NULL);
        BUG_ON(IS_ERR(clk0));
-
-       clk_enable(clk0);
+       BUG_ON(clk_prepare(clk0) < 0);
+       BUG_ON(clk_enable(clk0) < 0);
 
        /*
         * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz
@@ -224,17 +216,8 @@ void __init nmdk_timer_init(void)
        setup_sched_clock(nomadik_read_sched_clock, 32, rate);
 #endif
 
-       /* Timer 1 is used for events */
-
-       clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE);
-
-       nmdk_clkevt.max_delta_ns =
-               clockevent_delta2ns(0xffffffff, &nmdk_clkevt);
-       nmdk_clkevt.min_delta_ns =
-               clockevent_delta2ns(0x00000002, &nmdk_clkevt);
-       nmdk_clkevt.cpumask     = cpumask_of(0);
-
-       /* Register irq and clockevents */
+       /* Timer 1 is used for events, register irq and clockevents */
        setup_irq(IRQ_MTU0, &nmdk_timer_irq);
-       clockevents_register_device(&nmdk_clkevt);
+       nmdk_clkevt.cpumask = cpumask_of(0);
+       clockevents_config_and_register(&nmdk_clkevt, rate, 2, 0xffffffffU);
 }
index 8f81503a4df77ee6cb1c0c9ad52d723db9aa3f89..ce1e9b96ba1a34903f79eed02c65122c98454a0b 100644 (file)
@@ -14,6 +14,7 @@ config ARCH_OMAP1
        select CLKDEV_LOOKUP
        select CLKSRC_MMIO
        select GENERIC_IRQ_CHIP
+       select IRQ_DOMAIN
        select HAVE_IDE
        select NEED_MACH_MEMORY_H
        help
@@ -24,6 +25,8 @@ config ARCH_OMAP2PLUS
        select CLKDEV_LOOKUP
        select GENERIC_IRQ_CHIP
        select OMAP_DM_TIMER
+       select USE_OF
+       select PROC_DEVICETREE if PROC_FS
        help
          "Systems based on OMAP2, OMAP3 or OMAP4"
 
index 567e4b54f245d9684d3525178eed385052d55d2d..56b6f8b7053e3f842ce8a67bdea2d3cb8663b11b 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/clk.h>
 #include <linux/mutex.h>
 #include <linux/cpufreq.h>
-#include <linux/debugfs.h>
 #include <linux/io.h>
 
 #include <plat/clock.h>
index 5f0f2292b7fb90ad6b7800901e05bcca9a907d62..5068fe5a69104c94294a12351a7117f357111612 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <asm/sched_clock.h>
 
+#include <plat/hardware.h>
 #include <plat/common.h>
 #include <plat/board.h>
 
index 002fb4d96bbc7020b6158b469040faf29c72b891..74300ae29b71e72c0ec1052b0e38094dafe260fe 100644 (file)
@@ -164,6 +164,8 @@ static inline void set_gdma_dev(int req, int dev)
 }
 #else
 #define set_gdma_dev(req, dev) do {} while (0)
+#define omap_readl(reg)                0
+#define omap_writel(val, reg)  do {} while (0)
 #endif
 
 void omap_set_dma_priority(int lch, int dst_port, int priority)
@@ -2125,7 +2127,7 @@ static int __devexit omap_system_dma_remove(struct platform_device *pdev)
 
 static struct platform_driver omap_system_dma_driver = {
        .probe          = omap_system_dma_probe,
-       .remove         = omap_system_dma_remove,
+       .remove         = __devexit_p(omap_system_dma_remove),
        .driver         = {
                .name   = "omap_dma_system"
        },
index af3b92be84593384f96c5c8c59f74d10c108e22d..652139c0339e2fe8fae6df508bbc3a548fd06172 100644 (file)
@@ -43,6 +43,8 @@
 
 #include <plat/dmtimer.h>
 
+#include <mach/hardware.h>
+
 static LIST_HEAD(omap_timer_list);
 static DEFINE_SPINLOCK(dm_timer_lock);
 
@@ -80,9 +82,9 @@ static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
 
 static void omap_timer_restore_context(struct omap_dm_timer *timer)
 {
-       omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_OFFSET,
-                               timer->context.tiocp_cfg);
-       if (timer->revision > 1)
+       __raw_writel(timer->context.tiocp_cfg,
+                       timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET);
+       if (timer->revision == 1)
                __raw_writel(timer->context.tistat, timer->sys_stat);
 
        __raw_writel(timer->context.tisr, timer->irq_stat);
@@ -357,6 +359,19 @@ int omap_dm_timer_stop(struct omap_dm_timer *timer)
 
        __omap_dm_timer_stop(timer, timer->posted, rate);
 
+       if (timer->loses_context && timer->get_context_loss_count)
+               timer->ctx_loss_count =
+                       timer->get_context_loss_count(&timer->pdev->dev);
+
+       /*
+        * Since the register values are computed and written within
+        * __omap_dm_timer_stop, we need to use read to retrieve the
+        * context.
+        */
+       timer->context.tclr =
+                       omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+       timer->context.tisr = __raw_readl(timer->irq_stat);
+       omap_dm_timer_disable(timer);
        return 0;
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
index 51b102dc906b62bee9241aa65a9325048ce69d21..ad6f865d1f161bedf714674ff11eaee77e0cf8be 100644 (file)
 
 #if defined (CONFIG_MACH_AMS_DELTA)
 
-#define AMS_DELTA_LATCH1_PHYS          0x01000000
-#define AMS_DELTA_LATCH1_VIRT          0xEA000000
-#define AMS_DELTA_MODEM_PHYS           0x04000000
-#define AMS_DELTA_MODEM_VIRT           0xEB000000
-#define AMS_DELTA_LATCH2_PHYS          0x08000000
-#define AMS_DELTA_LATCH2_VIRT          0xEC000000
-
-#define AMS_DELTA_LATCH1_LED_CAMERA    0x01
-#define AMS_DELTA_LATCH1_LED_ADVERT    0x02
-#define AMS_DELTA_LATCH1_LED_EMAIL     0x04
-#define AMS_DELTA_LATCH1_LED_HANDSFREE 0x08
-#define AMS_DELTA_LATCH1_LED_VOICEMAIL 0x10
-#define AMS_DELTA_LATCH1_LED_VOICE     0x20
-
-#define AMS_DELTA_LATCH2_LCD_VBLEN     0x0001
-#define AMS_DELTA_LATCH2_LCD_NDISP     0x0002
-#define AMS_DELTA_LATCH2_NAND_NCE      0x0004
-#define AMS_DELTA_LATCH2_NAND_NRE      0x0008
-#define AMS_DELTA_LATCH2_NAND_NWP      0x0010
-#define AMS_DELTA_LATCH2_NAND_NWE      0x0020
-#define AMS_DELTA_LATCH2_NAND_ALE      0x0040
-#define AMS_DELTA_LATCH2_NAND_CLE      0x0080
-#define AMD_DELTA_LATCH2_KEYBRD_PWR    0x0100
-#define AMD_DELTA_LATCH2_KEYBRD_DATA   0x0200
 #define AMD_DELTA_LATCH2_SCARD_RSTIN   0x0400
 #define AMD_DELTA_LATCH2_SCARD_CMDVCC  0x0800
-#define AMS_DELTA_LATCH2_MODEM_NRESET  0x1000
 #define AMS_DELTA_LATCH2_MODEM_CODEC   0x2000
 
 #define AMS_DELTA_GPIO_PIN_KEYBRD_DATA 0
 #define AMS_DELTA_GPIO_PIN_CONFIG      11
 #define AMS_DELTA_GPIO_PIN_NAND_RB     12
 
+#define AMS_DELTA_GPIO_PIN_LCD_VBLEN           240
+#define AMS_DELTA_GPIO_PIN_LCD_NDISP           241
+#define AMS_DELTA_GPIO_PIN_NAND_NCE            242
+#define AMS_DELTA_GPIO_PIN_NAND_NRE            243
+#define AMS_DELTA_GPIO_PIN_NAND_NWP            244
+#define AMS_DELTA_GPIO_PIN_NAND_NWE            245
+#define AMS_DELTA_GPIO_PIN_NAND_ALE            246
+#define AMS_DELTA_GPIO_PIN_NAND_CLE            247
+#define AMS_DELTA_GPIO_PIN_KEYBRD_PWR          248
+#define AMS_DELTA_GPIO_PIN_KEYBRD_DATAOUT      249
+#define AMS_DELTA_GPIO_PIN_SCARD_RSTIN         250
+#define AMS_DELTA_GPIO_PIN_SCARD_CMDVCC                251
+#define AMS_DELTA_GPIO_PIN_MODEM_NRESET                252
+#define AMS_DELTA_GPIO_PIN_MODEM_CODEC         253
+
+#define AMS_DELTA_LATCH2_GPIO_BASE     AMS_DELTA_GPIO_PIN_LCD_VBLEN
+#define AMS_DELTA_LATCH2_NGPIO         16
+
 #ifndef __ASSEMBLY__
-void ams_delta_latch1_write(u8 mask, u8 value);
-void ams_delta_latch2_write(u16 mask, u16 value);
+void ams_delta_latch_write(int base, int ngpio, u16 mask, u16 value);
+#define ams_delta_latch2_write(mask, value) \
+       ams_delta_latch_write(AMS_DELTA_LATCH2_GPIO_BASE, \
+                       AMS_DELTA_LATCH2_NGPIO, (mask), (value))
 #endif
 
 #endif /* CONFIG_MACH_AMS_DELTA */
index 6b51086fce18c9360fda3fb0bbc396422e3973ff..dc6a86bf2172747345f5cfe93bd2592f1868de38 100644 (file)
@@ -250,7 +250,6 @@ IS_AM_SUBCLASS(335x, 0x335)
  * cpu_is_omap2423():  True for OMAP2423
  * cpu_is_omap2430():  True for OMAP2430
  * cpu_is_omap3430():  True for OMAP3430
- * cpu_is_omap4430():  True for OMAP4430
  * cpu_is_omap3505():  True for OMAP3505
  * cpu_is_omap3517():  True for OMAP3517
  */
@@ -299,7 +298,6 @@ IS_OMAP_TYPE(3517, 0x3517)
 #define cpu_is_omap3505()              0
 #define cpu_is_omap3517()              0
 #define cpu_is_omap3430()              0
-#define cpu_is_omap4430()              0
 #define cpu_is_omap3630()              0
 
 /*
@@ -451,7 +449,12 @@ IS_OMAP_TYPE(3517, 0x3517)
 #define OMAP447X_CLASS         0x44700044
 #define OMAP4470_REV_ES1_0     (OMAP447X_CLASS | (0x10 << 8))
 
-void omap2_check_revision(void);
+void omap2xxx_check_revision(void);
+void omap3xxx_check_revision(void);
+void omap4xxx_check_revision(void);
+void omap3xxx_check_features(void);
+void ti81xx_check_features(void);
+void omap4xxx_check_features(void);
 
 /*
  * Runtime detection of OMAP3 features
index 9e86ee0aed0a05fb5ad448d144a84a93e21e5d53..cb75b657b04b73e214cb32ee6edf8149d2c78a33 100644 (file)
                                 IH_MPUIO_BASE + ((nr) & 0x0f) : \
                                 IH_GPIO_BASE + (nr))
 
-#define METHOD_MPUIO           0
-#define METHOD_GPIO_1510       1
-#define METHOD_GPIO_1610       2
-#define METHOD_GPIO_7XX                3
-#define METHOD_GPIO_24XX       5
-#define METHOD_GPIO_44XX       6
-
 struct omap_gpio_dev_attr {
        int bank_width;         /* GPIO bank width */
        bool dbck_flag;         /* dbck required or not - True for OMAP3&4 */
@@ -184,10 +177,21 @@ struct omap_gpio_reg_offs {
        u16 irqstatus;
        u16 irqstatus2;
        u16 irqenable;
+       u16 irqenable2;
        u16 set_irqenable;
        u16 clr_irqenable;
        u16 debounce;
        u16 debounce_en;
+       u16 ctrl;
+       u16 wkup_en;
+       u16 leveldetect0;
+       u16 leveldetect1;
+       u16 risingdetect;
+       u16 fallingdetect;
+       u16 irqctrl;
+       u16 edgectrl1;
+       u16 edgectrl2;
+       u16 pinctrl;
 
        bool irqenable_inv;
 };
@@ -198,19 +202,20 @@ struct omap_gpio_platform_data {
        int bank_width;         /* GPIO bank width */
        int bank_stride;        /* Only needed for omap1 MPUIO */
        bool dbck_flag;         /* dbck required or not - True for OMAP3&4 */
+       bool loses_context;     /* whether the bank would ever lose context */
+       bool is_mpuio;          /* whether the bank is of type MPUIO */
+       u32 non_wakeup_gpios;
 
        struct omap_gpio_reg_offs *regs;
-};
 
-/* TODO: Analyze removing gpio_bank_count usage from driver code */
-extern int gpio_bank_count;
+       /* Return context loss count due to PM states changing */
+       int (*get_context_loss_count)(struct device *dev);
+};
 
 extern void omap2_gpio_prepare_for_idle(int off_mode);
 extern void omap2_gpio_resume_after_idle(void);
 extern void omap_set_gpio_debounce(int gpio, int enable);
 extern void omap_set_gpio_debounce_time(int gpio, int enable);
-extern void omap_gpio_save_context(void);
-extern void omap_gpio_restore_context(void);
 /*-------------------------------------------------------------------------*/
 
 /* Wrappers for "new style" GPIO calls, using the new infrastructure
index e897978371c2719167eb7bfbe2625dc5d7bc6fdf..537b05ae1f51aaba0380b6186b7be9542ac9c667 100644 (file)
 #endif
 #include <plat/serial.h>
 
+#ifdef __ASSEMBLER__
+#define IOMEM(x)               (x)
+#else
+#define IOMEM(x)               ((void __force __iomem *)(x))
+#endif
+
 /*
  * ---------------------------------------------------------------------------
  * Common definitions for all OMAP processors
diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/plat-omap/include/plat/io.h
deleted file mode 100644 (file)
index 0696bae..0000000
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/io.h
- *
- * IO definitions for TI OMAP processors and boards
- *
- * Copied from arch/arm/mach-sa1100/include/mach/io.h
- * Copyright (C) 1997-1999 Russell King
- *
- * Copyright (C) 2009 Texas Instruments
- * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Modifications:
- *  06-12-1997 RMK     Created.
- *  07-04-1999 RMK     Major cleanup
- */
-
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-#include <mach/hardware.h>
-
-#define IO_SPACE_LIMIT 0xffffffff
-
-/*
- * We don't actually have real ISA nor PCI buses, but there is so many
- * drivers out there that might just work if we fake them...
- */
-#define __io(a)                __typesafe_io(a)
-#define __mem_pci(a)   (a)
-
-/*
- * ----------------------------------------------------------------------------
- * I/O mapping
- * ----------------------------------------------------------------------------
- */
-
-#ifdef __ASSEMBLER__
-#define IOMEM(x)               (x)
-#else
-#define IOMEM(x)               ((void __force __iomem *)(x))
-#endif
-
-#define OMAP1_IO_OFFSET                0x01000000      /* Virtual IO = 0xfefb0000 */
-#define OMAP1_IO_ADDRESS(pa)   IOMEM((pa) - OMAP1_IO_OFFSET)
-
-#define OMAP2_L3_IO_OFFSET     0x90000000
-#define OMAP2_L3_IO_ADDRESS(pa)        IOMEM((pa) + OMAP2_L3_IO_OFFSET) /* L3 */
-
-
-#define OMAP2_L4_IO_OFFSET     0xb2000000
-#define OMAP2_L4_IO_ADDRESS(pa)        IOMEM((pa) + OMAP2_L4_IO_OFFSET) /* L4 */
-
-#define OMAP4_L3_IO_OFFSET     0xb4000000
-#define OMAP4_L3_IO_ADDRESS(pa)        IOMEM((pa) + OMAP4_L3_IO_OFFSET) /* L3 */
-
-#define AM33XX_L4_WK_IO_OFFSET 0xb5000000
-#define AM33XX_L4_WK_IO_ADDRESS(pa)    IOMEM((pa) + AM33XX_L4_WK_IO_OFFSET)
-
-#define OMAP4_L3_PER_IO_OFFSET 0xb1100000
-#define OMAP4_L3_PER_IO_ADDRESS(pa)    IOMEM((pa) + OMAP4_L3_PER_IO_OFFSET)
-
-#define OMAP4_GPMC_IO_OFFSET           0xa9000000
-#define OMAP4_GPMC_IO_ADDRESS(pa)      IOMEM((pa) + OMAP4_GPMC_IO_OFFSET)
-
-#define OMAP2_EMU_IO_OFFSET            0xaa800000      /* Emulation */
-#define OMAP2_EMU_IO_ADDRESS(pa)       IOMEM((pa) + OMAP2_EMU_IO_OFFSET)
-
-/*
- * ----------------------------------------------------------------------------
- * Omap1 specific IO mapping
- * ----------------------------------------------------------------------------
- */
-
-#define OMAP1_IO_PHYS          0xFFFB0000
-#define OMAP1_IO_SIZE          0x40000
-#define OMAP1_IO_VIRT          (OMAP1_IO_PHYS - OMAP1_IO_OFFSET)
-
-/*
- * ----------------------------------------------------------------------------
- * Omap2 specific IO mapping
- * ----------------------------------------------------------------------------
- */
-
-/* We map both L3 and L4 on OMAP2 */
-#define L3_24XX_PHYS   L3_24XX_BASE    /* 0x68000000 --> 0xf8000000*/
-#define L3_24XX_VIRT   (L3_24XX_PHYS + OMAP2_L3_IO_OFFSET)
-#define L3_24XX_SIZE   SZ_1M           /* 44kB of 128MB used, want 1MB sect */
-#define L4_24XX_PHYS   L4_24XX_BASE    /* 0x48000000 --> 0xfa000000 */
-#define L4_24XX_VIRT   (L4_24XX_PHYS + OMAP2_L4_IO_OFFSET)
-#define L4_24XX_SIZE   SZ_1M           /* 1MB of 128MB used, want 1MB sect */
-
-#define L4_WK_243X_PHYS                L4_WK_243X_BASE /* 0x49000000 --> 0xfb000000 */
-#define L4_WK_243X_VIRT                (L4_WK_243X_PHYS + OMAP2_L4_IO_OFFSET)
-#define L4_WK_243X_SIZE                SZ_1M
-#define OMAP243X_GPMC_PHYS     OMAP243X_GPMC_BASE
-#define OMAP243X_GPMC_VIRT     (OMAP243X_GPMC_PHYS + OMAP2_L3_IO_OFFSET)
-                                               /* 0x6e000000 --> 0xfe000000 */
-#define OMAP243X_GPMC_SIZE     SZ_1M
-#define OMAP243X_SDRC_PHYS     OMAP243X_SDRC_BASE
-                                               /* 0x6D000000 --> 0xfd000000 */
-#define OMAP243X_SDRC_VIRT     (OMAP243X_SDRC_PHYS + OMAP2_L3_IO_OFFSET)
-#define OMAP243X_SDRC_SIZE     SZ_1M
-#define OMAP243X_SMS_PHYS      OMAP243X_SMS_BASE
-                                               /* 0x6c000000 --> 0xfc000000 */
-#define OMAP243X_SMS_VIRT      (OMAP243X_SMS_PHYS + OMAP2_L3_IO_OFFSET)
-#define OMAP243X_SMS_SIZE      SZ_1M
-
-/* 2420 IVA */
-#define DSP_MEM_2420_PHYS      OMAP2420_DSP_MEM_BASE
-                                               /* 0x58000000 --> 0xfc100000 */
-#define DSP_MEM_2420_VIRT      0xfc100000
-#define DSP_MEM_2420_SIZE      0x28000
-#define DSP_IPI_2420_PHYS      OMAP2420_DSP_IPI_BASE
-                                               /* 0x59000000 --> 0xfc128000 */
-#define DSP_IPI_2420_VIRT      0xfc128000
-#define DSP_IPI_2420_SIZE      SZ_4K
-#define DSP_MMU_2420_PHYS      OMAP2420_DSP_MMU_BASE
-                                               /* 0x5a000000 --> 0xfc129000 */
-#define DSP_MMU_2420_VIRT      0xfc129000
-#define DSP_MMU_2420_SIZE      SZ_4K
-
-/* 2430 IVA2.1 - currently unmapped */
-
-/*
- * ----------------------------------------------------------------------------
- * Omap3 specific IO mapping
- * ----------------------------------------------------------------------------
- */
-
-/* We map both L3 and L4 on OMAP3 */
-#define L3_34XX_PHYS           L3_34XX_BASE    /* 0x68000000 --> 0xf8000000 */
-#define L3_34XX_VIRT           (L3_34XX_PHYS + OMAP2_L3_IO_OFFSET)
-#define L3_34XX_SIZE           SZ_1M   /* 44kB of 128MB used, want 1MB sect */
-
-#define L4_34XX_PHYS           L4_34XX_BASE    /* 0x48000000 --> 0xfa000000 */
-#define L4_34XX_VIRT           (L4_34XX_PHYS + OMAP2_L4_IO_OFFSET)
-#define L4_34XX_SIZE           SZ_4M   /* 1MB of 128MB used, want 1MB sect */
-
-/*
- * ----------------------------------------------------------------------------
- * AM33XX specific IO mapping
- * ----------------------------------------------------------------------------
- */
-#define L4_WK_AM33XX_PHYS      L4_WK_AM33XX_BASE
-#define L4_WK_AM33XX_VIRT      (L4_WK_AM33XX_PHYS + AM33XX_L4_WK_IO_OFFSET)
-#define L4_WK_AM33XX_SIZE      SZ_4M   /* 1MB of 128MB used, want 1MB sect */
-
-/*
- * Need to look at the Size 4M for L4.
- * VPOM3430 was not working for Int controller
- */
-
-#define L4_PER_34XX_PHYS       L4_PER_34XX_BASE
-                                               /* 0x49000000 --> 0xfb000000 */
-#define L4_PER_34XX_VIRT       (L4_PER_34XX_PHYS + OMAP2_L4_IO_OFFSET)
-#define L4_PER_34XX_SIZE       SZ_1M
-
-#define L4_EMU_34XX_PHYS       L4_EMU_34XX_BASE
-                                               /* 0x54000000 --> 0xfe800000 */
-#define L4_EMU_34XX_VIRT       (L4_EMU_34XX_PHYS + OMAP2_EMU_IO_OFFSET)
-#define L4_EMU_34XX_SIZE       SZ_8M
-
-#define OMAP34XX_GPMC_PHYS     OMAP34XX_GPMC_BASE
-                                               /* 0x6e000000 --> 0xfe000000 */
-#define OMAP34XX_GPMC_VIRT     (OMAP34XX_GPMC_PHYS + OMAP2_L3_IO_OFFSET)
-#define OMAP34XX_GPMC_SIZE     SZ_1M
-
-#define OMAP343X_SMS_PHYS      OMAP343X_SMS_BASE
-                                               /* 0x6c000000 --> 0xfc000000 */
-#define OMAP343X_SMS_VIRT      (OMAP343X_SMS_PHYS + OMAP2_L3_IO_OFFSET)
-#define OMAP343X_SMS_SIZE      SZ_1M
-
-#define OMAP343X_SDRC_PHYS     OMAP343X_SDRC_BASE
-                                               /* 0x6D000000 --> 0xfd000000 */
-#define OMAP343X_SDRC_VIRT     (OMAP343X_SDRC_PHYS + OMAP2_L3_IO_OFFSET)
-#define OMAP343X_SDRC_SIZE     SZ_1M
-
-/* 3430 IVA - currently unmapped */
-
-/*
- * ----------------------------------------------------------------------------
- * Omap4 specific IO mapping
- * ----------------------------------------------------------------------------
- */
-
-/* We map both L3 and L4 on OMAP4 */
-#define L3_44XX_PHYS           L3_44XX_BASE    /* 0x44000000 --> 0xf8000000 */
-#define L3_44XX_VIRT           (L3_44XX_PHYS + OMAP4_L3_IO_OFFSET)
-#define L3_44XX_SIZE           SZ_1M
-
-#define L4_44XX_PHYS           L4_44XX_BASE    /* 0x4a000000 --> 0xfc000000 */
-#define L4_44XX_VIRT           (L4_44XX_PHYS + OMAP2_L4_IO_OFFSET)
-#define L4_44XX_SIZE           SZ_4M
-
-#define L4_PER_44XX_PHYS       L4_PER_44XX_BASE
-                                               /* 0x48000000 --> 0xfa000000 */
-#define L4_PER_44XX_VIRT       (L4_PER_44XX_PHYS + OMAP2_L4_IO_OFFSET)
-#define L4_PER_44XX_SIZE       SZ_4M
-
-#define L4_ABE_44XX_PHYS       L4_ABE_44XX_BASE
-                                               /* 0x49000000 --> 0xfb000000 */
-#define L4_ABE_44XX_VIRT       (L4_ABE_44XX_PHYS + OMAP2_L4_IO_OFFSET)
-#define L4_ABE_44XX_SIZE       SZ_1M
-
-#define L4_EMU_44XX_PHYS       L4_EMU_44XX_BASE
-                                               /* 0x54000000 --> 0xfe800000 */
-#define L4_EMU_44XX_VIRT       (L4_EMU_44XX_PHYS + OMAP2_EMU_IO_OFFSET)
-#define L4_EMU_44XX_SIZE       SZ_8M
-
-#define OMAP44XX_GPMC_PHYS     OMAP44XX_GPMC_BASE
-                                               /* 0x50000000 --> 0xf9000000 */
-#define OMAP44XX_GPMC_VIRT     (OMAP44XX_GPMC_PHYS + OMAP4_GPMC_IO_OFFSET)
-#define OMAP44XX_GPMC_SIZE     SZ_1M
-
-
-#define OMAP44XX_EMIF1_PHYS    OMAP44XX_EMIF1_BASE
-                                               /* 0x4c000000 --> 0xfd100000 */
-#define OMAP44XX_EMIF1_VIRT    (OMAP44XX_EMIF1_PHYS + OMAP4_L3_PER_IO_OFFSET)
-#define OMAP44XX_EMIF1_SIZE    SZ_1M
-
-#define OMAP44XX_EMIF2_PHYS    OMAP44XX_EMIF2_BASE
-                                               /* 0x4d000000 --> 0xfd200000 */
-#define OMAP44XX_EMIF2_SIZE    SZ_1M
-#define OMAP44XX_EMIF2_VIRT    (OMAP44XX_EMIF1_VIRT + OMAP44XX_EMIF1_SIZE)
-
-#define OMAP44XX_DMM_PHYS      OMAP44XX_DMM_BASE
-                                               /* 0x4e000000 --> 0xfd300000 */
-#define OMAP44XX_DMM_SIZE      SZ_1M
-#define OMAP44XX_DMM_VIRT      (OMAP44XX_EMIF2_VIRT + OMAP44XX_EMIF2_SIZE)
-/*
- * ----------------------------------------------------------------------------
- * Omap specific register access
- * ----------------------------------------------------------------------------
- */
-
-#ifndef __ASSEMBLER__
-
-/*
- * NOTE: Please use ioremap + __raw_read/write where possible instead of these
- */
-
-extern u8 omap_readb(u32 pa);
-extern u16 omap_readw(u32 pa);
-extern u32 omap_readl(u32 pa);
-extern void omap_writeb(u8 v, u32 pa);
-extern void omap_writew(u16 v, u32 pa);
-extern void omap_writel(u32 v, u32 pa);
-
-struct omap_sdrc_params;
-extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
-                                     struct omap_sdrc_params *sdrc_cs1);
-
-extern void __init omap_init_consistent_dma_size(void);
-
-#endif
-
-#endif
index 793ce9d5329485be9b64d550c2c0aaf1804367df..a6b21eddb212771641f09e13d9216b4d7c89803c 100644 (file)
@@ -12,6 +12,8 @@
 
 #ifndef CONFIG_ARCH_OMAP1
 #warning Please update the board to use matrix-keypad driver
+#define omap_readw(reg)                0
+#define omap_writew(val, reg)  do {} while (0)
 #endif
 #include <linux/input/matrix_keypad.h>
 
index 3d51b18131cc0416656b6a66e39ab0b3b76e7f90..a357eb26bd258dfd6a969bf218da86d322f41ba1 100644 (file)
@@ -18,9 +18,6 @@ struct omap2_mcspi_dev_attr {
 
 struct omap2_mcspi_device_config {
        unsigned turbo_mode:1;
-
-       /* Do we want one channel enabled at the same time? */
-       unsigned single_channel:1;
 };
 
 #endif
index 51423d2727a5f9b11ef886e1548905bc6a0e3ef4..4327b2c90c3db5b8fbe4dedb6ad80fcadabed0c7 100644 (file)
@@ -36,7 +36,7 @@
 
 #include <plat/omap_hwmod.h>
 
-extern struct device omap_device_parent;
+extern struct dev_pm_domain omap_device_pm_domain;
 
 /* omap_device._state values */
 #define OMAP_DEVICE_STATE_UNKNOWN      0
@@ -100,6 +100,13 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
                                         struct omap_device_pm_latency *pm_lats,
                                         int pm_lats_cnt, int is_early_device);
 
+struct omap_device *omap_device_alloc(struct platform_device *pdev,
+                                     struct omap_hwmod **ohs, int oh_cnt,
+                                     struct omap_device_pm_latency *pm_lats,
+                                     int pm_lats_cnt);
+void omap_device_delete(struct omap_device *od);
+int omap_device_register(struct platform_device *pdev);
+
 void __iomem *omap_device_get_rt_va(struct omap_device *od);
 struct device *omap_device_get_by_hwmod_name(const char *oh_name);
 
index 647010109afabd4d373ae96c357bf9f990ef3ccd..9e8e63d52aab9515a67882c534c7b563e29bbe9a 100644 (file)
@@ -484,7 +484,6 @@ struct omap_hwmod_class {
  * @main_clk: main clock: OMAP clock name
  * @_clk: pointer to the main struct clk (filled in at runtime)
  * @opt_clks: other device clocks that drivers can request (0..*)
- * @vdd_name: voltage domain name
  * @voltdm: pointer to voltage domain (filled in at runtime)
  * @masters: ptr to array of OCP ifs that this hwmod can initiate on
  * @slaves: ptr to array of OCP ifs that this hwmod can respond on
@@ -528,7 +527,6 @@ struct omap_hwmod {
        struct omap_hwmod_opt_clk       *opt_clks;
        char                            *clkdm_name;
        struct clockdomain              *clkdm;
-       char                            *vdd_name;
        struct omap_hwmod_ocp_if        **masters; /* connect to *_IA */
        struct omap_hwmod_ocp_if        **slaves;  /* connect to *_TA */
        void                            *dev_attr;
diff --git a/arch/arm/plat-omap/include/plat/remoteproc.h b/arch/arm/plat-omap/include/plat/remoteproc.h
new file mode 100644 (file)
index 0000000..b10eac8
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Remote Processor - omap-specific bits
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _PLAT_REMOTEPROC_H
+#define _PLAT_REMOTEPROC_H
+
+struct rproc_ops;
+struct platform_device;
+
+/*
+ * struct omap_rproc_pdata - omap remoteproc's platform data
+ * @name: the remoteproc's name
+ * @oh_name: omap hwmod device
+ * @oh_name_opt: optional, secondary omap hwmod device
+ * @firmware: name of firmware file to load
+ * @mbox_name: name of omap mailbox device to use with this rproc
+ * @ops: start/stop rproc handlers
+ * @device_enable: omap-specific handler for enabling a device
+ * @device_shutdown: omap-specific handler for shutting down a device
+ */
+struct omap_rproc_pdata {
+       const char *name;
+       const char *oh_name;
+       const char *oh_name_opt;
+       const char *firmware;
+       const char *mbox_name;
+       const struct rproc_ops *ops;
+       int (*device_enable) (struct platform_device *pdev);
+       int (*device_shutdown) (struct platform_device *pdev);
+};
+
+#if defined(CONFIG_OMAP_REMOTEPROC) || defined(CONFIG_OMAP_REMOTEPROC_MODULE)
+
+void __init omap_rproc_reserve_cma(void);
+
+#else
+
+void __init omap_rproc_reserve_cma(void)
+{
+}
+
+#endif
+
+#endif /* _PLAT_REMOTEPROC_H */
index 198d1e6a4a6c946268a4a4feef21fc0d39312647..b073e5f2b190a6b4b04543d7a20d94dbc48a8c19 100644 (file)
@@ -110,7 +110,6 @@ struct omap_board_data;
 struct omap_uart_port_info;
 
 extern void omap_serial_init(void);
-extern int omap_uart_can_sleep(void);
 extern void omap_serial_board_init(struct omap_uart_port_info *platform_data);
 extern void omap_serial_init_port(struct omap_board_data *bdata,
                struct omap_uart_port_info *platform_data);
index 75aa1b2bef519eaa8958c37a7050df66c022848a..227ae26575549eb3e1ad488247dc9af08d4bbcef 100644 (file)
@@ -101,4 +101,5 @@ static inline void omap_push_sram_idle(void) {}
 #else
 #define OMAP4_SRAM_PA          0x40300000
 #endif
+#define AM33XX_SRAM_PA         0x40300000
 #endif
index d2fcd789bb9a5ef848a1fe9fa9df9c4156547062..1b4b2da86203e98b864c60037a6bf4b549397d39 100644 (file)
 #define EMIFS_CCS(n)           (EMIFS_CS0_CONFIG + (4 * (n)))
 #define EMIFS_ACS(n)           (EMIFS_ACS0 + (4 * (n)))
 
-/* Almost all documentation for chip and board memory maps assumes
- * BM is clear.  Most devel boards have a switch to control booting
- * from NOR flash (using external chipselect 3) rather than mask ROM,
- * which uses BM to interchange the physical CS0 and CS3 addresses.
- */
-static inline u32 omap_cs0_phys(void)
-{
-       return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM)
-                       ?  OMAP_CS3_PHYS : 0;
-}
-
-static inline u32 omap_cs3_phys(void)
-{
-       return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM)
-                       ? 0 : OMAP_CS3_PHYS;
-}
-
 #endif /* __ASSEMBLER__ */
 
 #endif /* __ASM_ARCH_TC_H */
index 6ee90495ca4cee7d431bc2a28d18cb2c38794470..cc3f11ba7a994cb0207f757d02bba617e8a8fd13 100644 (file)
@@ -160,6 +160,7 @@ static inline void __arch_decomp_setup(unsigned long arch_id)
                DEBUG_LL_OMAP3(3, igep0020);
                DEBUG_LL_OMAP3(3, igep0030);
                DEBUG_LL_OMAP3(3, nokia_rm680);
+               DEBUG_LL_OMAP3(3, nokia_rm696);
                DEBUG_LL_OMAP3(3, nokia_rx51);
                DEBUG_LL_OMAP3(3, omap3517evm);
                DEBUG_LL_OMAP3(3, omap3_beagle);
index dc864b580da0644a24b0603313467ef46077d612..d0fc9f4dc155b1bc2e32e256004c36e0ffaca9c7 100644 (file)
@@ -3,6 +3,7 @@
 #ifndef        __ASM_ARCH_OMAP_USB_H
 #define        __ASM_ARCH_OMAP_USB_H
 
+#include <linux/io.h>
 #include <linux/usb/musb.h>
 #include <plat/board.h>
 
@@ -105,6 +106,46 @@ extern int omap4430_phy_set_clk(struct device *dev, int on);
 extern int omap4430_phy_init(struct device *dev);
 extern int omap4430_phy_exit(struct device *dev);
 extern int omap4430_phy_suspend(struct device *dev, int suspend);
+
+/*
+ * NOTE: Please update omap USB drivers to use ioremap + read/write
+ */
+
+#define OMAP2_L4_IO_OFFSET     0xb2000000
+#define IOMEM(x)               ((void __force __iomem *)(x))
+#define OMAP2_L4_IO_ADDRESS(pa)        IOMEM((pa) + OMAP2_L4_IO_OFFSET)
+
+static inline u8 omap_readb(u32 pa)
+{
+       return __raw_readb(OMAP2_L4_IO_ADDRESS(pa));
+}
+
+static inline u16 omap_readw(u32 pa)
+{
+       return __raw_readw(OMAP2_L4_IO_ADDRESS(pa));
+}
+
+static inline u32 omap_readl(u32 pa)
+{
+       return __raw_readl(OMAP2_L4_IO_ADDRESS(pa));
+}
+
+static inline void omap_writeb(u8 v, u32 pa)
+{
+       __raw_writeb(v, OMAP2_L4_IO_ADDRESS(pa));
+}
+
+
+static inline void omap_writew(u16 v, u32 pa)
+{
+       __raw_writew(v, OMAP2_L4_IO_ADDRESS(pa));
+}
+
+static inline void omap_writel(u32 v, u32 pa)
+{
+       __raw_writel(v, OMAP2_L4_IO_ADDRESS(pa));
+}
+
 #endif
 
 extern void am35x_musb_reset(void);
index ad80112c22751defaaa4cb5b9aefe11eac27e6be..ad32621aa52e259fe20346d60f5d9f7d38edbad6 100644 (file)
@@ -307,7 +307,7 @@ static void omap_mbox_fini(struct omap_mbox *mbox)
        if (!--mbox->use_count) {
                free_irq(mbox->irq, mbox);
                tasklet_kill(&mbox->txq->tasklet);
-       flush_work_sync(&mbox->rxq->work);
+               flush_work_sync(&mbox->rxq->work);
                mbox_queue_free(mbox->txq);
                mbox_queue_free(mbox->rxq);
        }
index 0d4aa0d5876c0360d51b76ed7f827c2339a8fd4f..cff8712122bb95f71c355bf6829aa0030e8ed552 100644 (file)
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/io.h>
-#include <asm/system.h>
 #include <linux/spinlock.h>
+
+#include <asm/system.h>
+
+#include <plat/cpu.h>
 #include <plat/mux.h>
 
 #ifdef CONFIG_OMAP_MUX
index 3dc3801aace4424c96722aa48139fc2b51197c63..5a97b4d98d41cbe4437fd605c7094e1324ae23fa 100644 (file)
@@ -319,7 +319,7 @@ int omap_pm_get_dev_context_loss_count(struct device *dev)
        if (WARN_ON(!dev))
                return -ENODEV;
 
-       if (dev->parent == &omap_device_parent) {
+       if (dev->pm_domain == &omap_device_pm_domain) {
                count = omap_device_get_context_loss_count(pdev);
        } else {
                WARN_ONCE(off_mode_enabled, "omap_pm: using dummy context loss counter; device %s should be converted to omap_device",
index e8d98693d2dd1fd0ac11a175510738cae8419c72..d50cbc6385bd48a10fd5d6064b1733b00b563910 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * omap_device implementation
  *
 #define USE_WAKEUP_LAT                 0
 #define IGNORE_WAKEUP_LAT              1
 
-static int omap_device_register(struct platform_device *pdev);
 static int omap_early_device_register(struct platform_device *pdev);
-static struct omap_device *omap_device_alloc(struct platform_device *pdev,
-                                     struct omap_hwmod **ohs, int oh_cnt,
-                                     struct omap_device_pm_latency *pm_lats,
-                                     int pm_lats_cnt);
-static void omap_device_delete(struct omap_device *od);
-
 
 static struct omap_device_pm_latency omap_default_latency[] = {
        {
@@ -320,8 +314,6 @@ static void _add_hwmod_clocks_clkdev(struct omap_device *od,
 }
 
 
-static struct dev_pm_domain omap_device_pm_domain;
-
 /**
  * omap_device_build_from_dt - build an omap_device with multiple hwmods
  * @pdev_name: name of the platform_device driver to use
@@ -348,7 +340,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
 
        oh_cnt = of_property_count_strings(node, "ti,hwmods");
        if (!oh_cnt || IS_ERR_VALUE(oh_cnt)) {
-               dev_warn(&pdev->dev, "No 'hwmods' to build omap_device\n");
+               dev_dbg(&pdev->dev, "No 'hwmods' to build omap_device\n");
                return -ENODEV;
        }
 
@@ -509,7 +501,7 @@ static int omap_device_fill_resources(struct omap_device *od,
  *
  * Returns an struct omap_device pointer or ERR_PTR() on error;
  */
-static struct omap_device *omap_device_alloc(struct platform_device *pdev,
+struct omap_device *omap_device_alloc(struct platform_device *pdev,
                                        struct omap_hwmod **ohs, int oh_cnt,
                                        struct omap_device_pm_latency *pm_lats,
                                        int pm_lats_cnt)
@@ -591,7 +583,7 @@ oda_exit1:
        return ERR_PTR(ret);
 }
 
-static void omap_device_delete(struct omap_device *od)
+void omap_device_delete(struct omap_device *od)
 {
        if (!od)
                return;
@@ -619,7 +611,7 @@ static void omap_device_delete(struct omap_device *od)
  * information.  Returns ERR_PTR(-EINVAL) if @oh is NULL; otherwise,
  * passes along the return value of omap_device_build_ss().
  */
-struct platform_device *omap_device_build(const char *pdev_name, int pdev_id,
+struct platform_device __init *omap_device_build(const char *pdev_name, int pdev_id,
                                      struct omap_hwmod *oh, void *pdata,
                                      int pdata_len,
                                      struct omap_device_pm_latency *pm_lats,
@@ -652,7 +644,7 @@ struct platform_device *omap_device_build(const char *pdev_name, int pdev_id,
  * platform_device record.  Returns an ERR_PTR() on error, or passes
  * along the return value of omap_device_register().
  */
-struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
+struct platform_device __init *omap_device_build_ss(const char *pdev_name, int pdev_id,
                                         struct omap_hwmod **ohs, int oh_cnt,
                                         void *pdata, int pdata_len,
                                         struct omap_device_pm_latency *pm_lats,
@@ -717,7 +709,7 @@ odbs_exit:
  * platform_early_add_device() on the underlying platform_device.
  * Returns 0 by default.
  */
-static int omap_early_device_register(struct platform_device *pdev)
+static int __init omap_early_device_register(struct platform_device *pdev)
 {
        struct platform_device *devices[1];
 
@@ -762,14 +754,12 @@ static int _od_suspend_noirq(struct device *dev)
        struct omap_device *od = to_omap_device(pdev);
        int ret;
 
-       if (od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND)
-               return pm_generic_suspend_noirq(dev);
-
        ret = pm_generic_suspend_noirq(dev);
 
        if (!ret && !pm_runtime_status_suspended(dev)) {
                if (pm_generic_runtime_suspend(dev) == 0) {
-                       omap_device_idle(pdev);
+                       if (!(od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND))
+                               omap_device_idle(pdev);
                        od->flags |= OMAP_DEVICE_SUSPENDED;
                }
        }
@@ -782,13 +772,11 @@ static int _od_resume_noirq(struct device *dev)
        struct platform_device *pdev = to_platform_device(dev);
        struct omap_device *od = to_omap_device(pdev);
 
-       if (od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND)
-               return pm_generic_resume_noirq(dev);
-
        if ((od->flags & OMAP_DEVICE_SUSPENDED) &&
            !pm_runtime_status_suspended(dev)) {
                od->flags &= ~OMAP_DEVICE_SUSPENDED;
-               omap_device_enable(pdev);
+               if (!(od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND))
+                       omap_device_enable(pdev);
                pm_generic_runtime_resume(dev);
        }
 
@@ -799,7 +787,7 @@ static int _od_resume_noirq(struct device *dev)
 #define _od_resume_noirq NULL
 #endif
 
-static struct dev_pm_domain omap_device_pm_domain = {
+struct dev_pm_domain omap_device_pm_domain = {
        .ops = {
                SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume,
                                   _od_runtime_idle)
@@ -817,11 +805,10 @@ static struct dev_pm_domain omap_device_pm_domain = {
  * platform_device_register() on the underlying platform_device.
  * Returns the return value of platform_device_register().
  */
-static int omap_device_register(struct platform_device *pdev)
+int omap_device_register(struct platform_device *pdev)
 {
        pr_debug("omap_device: %s: registering\n", pdev->name);
 
-       pdev->dev.parent = &omap_device_parent;
        pdev->dev.pm_domain = &omap_device_pm_domain;
        return platform_device_add(pdev);
 }
@@ -1130,11 +1117,6 @@ int omap_device_enable_clocks(struct omap_device *od)
        return 0;
 }
 
-struct device omap_device_parent = {
-       .init_name      = "omap",
-       .parent         = &platform_bus,
-};
-
 static struct notifier_block platform_nb = {
        .notifier_call = _omap_device_notifier_call,
 };
@@ -1142,6 +1124,6 @@ static struct notifier_block platform_nb = {
 static int __init omap_device_init(void)
 {
        bus_register_notifier(&platform_bus_type, &platform_nb);
-       return device_register(&omap_device_parent);
+       return 0;
 }
 core_initcall(omap_device_init);
index 4243bdcc87bcb99fe8ba3f26341757cd47ea41d9..eec98afa0f8328b2023f855879fa8a2ff34890ac 100644 (file)
 
 #include "sram.h"
 
-/* XXX These "sideways" includes are a sign that something is wrong */
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-# include "../mach-omap2/prm2xxx_3xxx.h"
-# include "../mach-omap2/sdrc.h"
-#endif
+/* XXX These "sideways" includes will disappear when sram.c becomes a driver */
+#include "../mach-omap2/iomap.h"
+#include "../mach-omap2/prm2xxx_3xxx.h"
+#include "../mach-omap2/sdrc.h"
 
 #define OMAP1_SRAM_PA          0x20000000
 #define OMAP2_SRAM_PUB_PA      (OMAP2_SRAM_PA + 0xf800)
@@ -86,7 +85,7 @@ static int is_sram_locked(void)
                        __raw_writel(0xCFDE, OMAP24XX_VA_READPERM0);  /* all i-read */
                        __raw_writel(0xCFDE, OMAP24XX_VA_WRITEPERM0); /* all i-write */
                }
-               if (cpu_is_omap34xx()) {
+               if (cpu_is_omap34xx() && !cpu_is_am33xx()) {
                        __raw_writel(0xFFFF, OMAP34XX_VA_REQINFOPERM0); /* all q-vects */
                        __raw_writel(0xFFFF, OMAP34XX_VA_READPERM0);  /* all i-read */
                        __raw_writel(0xFFFF, OMAP34XX_VA_WRITEPERM0); /* all i-write */
@@ -124,7 +123,10 @@ static void __init omap_detect_sram(void)
                                omap_sram_size = 0x800; /* 2K */
                        }
                } else {
-                       if (cpu_is_omap34xx()) {
+                       if (cpu_is_am33xx()) {
+                               omap_sram_start = AM33XX_SRAM_PA;
+                               omap_sram_size = 0x10000; /* 64K */
+                       } else if (cpu_is_omap34xx()) {
                                omap_sram_start = OMAP3_SRAM_PA;
                                omap_sram_size = 0x10000; /* 64K */
                        } else if (cpu_is_omap44xx()) {
@@ -368,6 +370,11 @@ static inline int omap34xx_sram_init(void)
        return 0;
 }
 
+static inline int am33xx_sram_init(void)
+{
+       return 0;
+}
+
 int __init omap_sram_init(void)
 {
        omap_detect_sram();
@@ -379,6 +386,8 @@ int __init omap_sram_init(void)
                omap242x_sram_init();
        else if (cpu_is_omap2430())
                omap243x_sram_init();
+       else if (cpu_is_am33xx())
+               am33xx_sram_init();
        else if (cpu_is_omap34xx())
                omap34xx_sram_init();
 
index f3570884883e574df243384475c2fd66b68906ee..d2bbfd1cb0b593ccd3ac5e45c22e8435d8ebd37e 100644 (file)
 #include <plat/usb.h>
 #include <plat/board.h>
 
+#include <mach/hardware.h>
+
+#include "../mach-omap2/common.h"
+
 #ifdef CONFIG_ARCH_OMAP_OTG
 
 void __init
index 089899a7db724e7d5d09cc5d7bfa568e484a64a4..74daf5ed1432726ca7fc7d69c3fddd174d310ae6 100644 (file)
@@ -21,6 +21,7 @@
 #include <plat/orion_wdt.h>
 #include <plat/mv_xor.h>
 #include <plat/ehci-orion.h>
+#include <mach/bridge-regs.h>
 
 /* Fill in the resources structure and link it into the platform
    device structure. There is always a memory region, and nearly
@@ -568,13 +569,17 @@ void __init orion_spi_1_init(unsigned long mapbase,
  ****************************************************************************/
 static struct orion_wdt_platform_data orion_wdt_data;
 
+static struct resource orion_wdt_resource =
+               DEFINE_RES_MEM(TIMER_VIRT_BASE, 0x28);
+
 static struct platform_device orion_wdt_device = {
        .name           = "orion_wdt",
        .id             = -1,
        .dev            = {
                .platform_data  = &orion_wdt_data,
        },
-       .num_resources  = 0,
+       .resource       = &orion_wdt_resource,
+       .num_resources  = 1,
 };
 
 void __init orion_wdt_init(unsigned long tclk)
index 885f8abd927b1de4cf47dc485ea203625e43db7b..d6a55bd2e578c804e56fcd578fa28bafea41d2d8 100644 (file)
@@ -2,7 +2,6 @@
 #define __PLAT_AUDIO_H
 
 struct kirkwood_asoc_platform_data {
-       u32 tclk;
        int burst;
 };
 #endif
index d8973ac46bc4e909a9f04a6e43883197e8e4acec..21bf6adb9198949422b50e831e08a5dcc084952b 100644 (file)
@@ -4,7 +4,7 @@
 
 config PLAT_S3C24XX
        bool
-       depends on ARCH_S3C2410
+       depends on ARCH_S3C24XX
        default y
        select NO_IOPORT
        select ARCH_REQUIRE_GPIOLIB
@@ -44,12 +44,6 @@ config S3C2410_CLOCK
          Clock code for the S3C2410, and similar processors which
          is currently includes the S3C2410, S3C2440, S3C2442.
 
-config S3C2443_CLOCK
-       bool
-       help
-         Clock code for the S3C2443 and similar processors, which includes
-         the S3C2416 and S3C2450.
-
 config S3C24XX_DCLK
        bool
        help
@@ -76,15 +70,9 @@ config S3C24XX_GPIO_EXTRA128
          Add an extra 128 gpio numbers to the available GPIO pool. This is
          available for boards that need extra gpios for external devices.
 
-config PM_SIMTEC
-       bool
-       help
-         Common power management code for systems that are
-         compatible with the Simtec style of power management
-
-config S3C2410_DMA
+config S3C24XX_DMA
        bool "S3C2410 DMA support"
-       depends on ARCH_S3C2410
+       depends on ARCH_S3C24XX
        select S3C_DMA
        help
          S3C2410 DMA support. This is needed for drivers like sound which
@@ -93,31 +81,11 @@ config S3C2410_DMA
 
 config S3C2410_DMA_DEBUG
        bool "S3C2410 DMA support debug"
-       depends on ARCH_S3C2410 && S3C2410_DMA
+       depends on ARCH_S3C24XX && S3C2410_DMA
        help
          Enable debugging output for the DMA code. This option sends info
          to the kernel log, at priority KERN_DEBUG.
 
-# SPI default pin configuration code
-
-config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13
-       bool
-       help
-         SPI GPIO configuration code for BUS0 when connected to
-         GPE11, GPE12 and GPE13.
-
-config S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7
-       bool
-       help
-         SPI GPIO configuration code for BUS 1 when connected to
-         GPG5, GPG6 and GPG7.
-
-config S3C24XX_SPI_BUS1_GPD8_GPD9_GPD10
-       bool
-       help
-         SPI GPIO configuration code for BUS 1 when connected to
-         GPD8, GPD9 and GPD10.
-
 # common code for s3c24xx based machines, such as the SMDKs.
 
 # cpu frequency items common between s3c2410 and s3c2440/s3c2442
@@ -145,21 +113,4 @@ config S3C2412_IOTIMING
          Intel node to select io timing code that is common to the s3c2412
          and the s3c2443.
 
-config MACH_SMDK
-       bool
-       help
-         Common machine code for SMDK2410 and SMDK2440
-
-config S3C24XX_SIMTEC_AUDIO
-       bool
-       depends on (ARCH_BAST || MACH_VR1000 || MACH_OSIRIS || MACH_ANUBIS)
-       default y
-       help
-         Add audio devices for common Simtec S3C24XX boards
-
-config S3C2410_SETUP_TS
-       bool
-       help
-         Compile in platform device definition for Samsung TouchScreen.
-
 endif
index b2b01125de66ac24606cf6dbe71072a974e5e7cf..2467b800cc768416de3e0f93eba09b799421ee8d 100644 (file)
@@ -23,28 +23,11 @@ obj-$(CONFIG_CPU_FREQ_S3C24XX_DEBUGFS) += cpu-freq-debugfs.o
 
 # Architecture dependent builds
 
-obj-$(CONFIG_PM_SIMTEC)                += pm-simtec.o
 obj-$(CONFIG_PM)               += pm.o
 obj-$(CONFIG_PM)               += irq-pm.o
 obj-$(CONFIG_PM)               += sleep.o
 obj-$(CONFIG_S3C2410_CLOCK)    += s3c2410-clock.o
-obj-$(CONFIG_S3C2443_CLOCK)    += s3c2443-clock.o
-obj-$(CONFIG_S3C2410_DMA)      += dma.o
+obj-$(CONFIG_S3C24XX_DMA)      += dma.o
 obj-$(CONFIG_S3C2410_IOTIMING) += s3c2410-iotiming.o
 obj-$(CONFIG_S3C2412_IOTIMING) += s3c2412-iotiming.o
 obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += s3c2410-cpufreq-utils.o
-
-# device specific setup and/or initialisation
-obj-$(CONFIG_ARCH_S3C2410)     += setup-i2c.o
-obj-$(CONFIG_S3C2410_SETUP_TS) += setup-ts.o
-
-# SPI gpio central GPIO functions
-
-obj-$(CONFIG_S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13) += spi-bus0-gpe11_12_13.o
-obj-$(CONFIG_S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7)    += spi-bus1-gpg5_6_7.o
-obj-$(CONFIG_S3C24XX_SPI_BUS1_GPD8_GPD9_GPD10)  += spi-bus1-gpd8_9_10.o
-
-# machine common support
-
-obj-$(CONFIG_MACH_SMDK)                += common-smdk.o
-obj-$(CONFIG_S3C24XX_SIMTEC_AUDIO)     += simtec-audio.o
diff --git a/arch/arm/plat-s3c24xx/common-smdk.c b/arch/arm/plat-s3c24xx/common-smdk.c
deleted file mode 100644 (file)
index 084604b..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/common-smdk.c
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Common code for SMDK2410 and SMDK2440 boards
- *
- * http://www.fluff.org/ben/smdk2440/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <mach/regs-gpio.h>
-#include <mach/leds-gpio.h>
-
-#include <plat/nand.h>
-
-#include <plat/common-smdk.h>
-#include <plat/gpio-cfg.h>
-#include <plat/devs.h>
-#include <plat/pm.h>
-
-/* LED devices */
-
-static struct s3c24xx_led_platdata smdk_pdata_led4 = {
-       .gpio           = S3C2410_GPF(4),
-       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
-       .name           = "led4",
-       .def_trigger    = "timer",
-};
-
-static struct s3c24xx_led_platdata smdk_pdata_led5 = {
-       .gpio           = S3C2410_GPF(5),
-       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
-       .name           = "led5",
-       .def_trigger    = "nand-disk",
-};
-
-static struct s3c24xx_led_platdata smdk_pdata_led6 = {
-       .gpio           = S3C2410_GPF(6),
-       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
-       .name           = "led6",
-};
-
-static struct s3c24xx_led_platdata smdk_pdata_led7 = {
-       .gpio           = S3C2410_GPF(7),
-       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
-       .name           = "led7",
-};
-
-static struct platform_device smdk_led4 = {
-       .name           = "s3c24xx_led",
-       .id             = 0,
-       .dev            = {
-               .platform_data = &smdk_pdata_led4,
-       },
-};
-
-static struct platform_device smdk_led5 = {
-       .name           = "s3c24xx_led",
-       .id             = 1,
-       .dev            = {
-               .platform_data = &smdk_pdata_led5,
-       },
-};
-
-static struct platform_device smdk_led6 = {
-       .name           = "s3c24xx_led",
-       .id             = 2,
-       .dev            = {
-               .platform_data = &smdk_pdata_led6,
-       },
-};
-
-static struct platform_device smdk_led7 = {
-       .name           = "s3c24xx_led",
-       .id             = 3,
-       .dev            = {
-               .platform_data = &smdk_pdata_led7,
-       },
-};
-
-/* NAND parititon from 2.4.18-swl5 */
-
-static struct mtd_partition smdk_default_nand_part[] = {
-       [0] = {
-               .name   = "Boot Agent",
-               .size   = SZ_16K,
-               .offset = 0,
-       },
-       [1] = {
-               .name   = "S3C2410 flash partition 1",
-               .offset = 0,
-               .size   = SZ_2M,
-       },
-       [2] = {
-               .name   = "S3C2410 flash partition 2",
-               .offset = SZ_4M,
-               .size   = SZ_4M,
-       },
-       [3] = {
-               .name   = "S3C2410 flash partition 3",
-               .offset = SZ_8M,
-               .size   = SZ_2M,
-       },
-       [4] = {
-               .name   = "S3C2410 flash partition 4",
-               .offset = SZ_1M * 10,
-               .size   = SZ_4M,
-       },
-       [5] = {
-               .name   = "S3C2410 flash partition 5",
-               .offset = SZ_1M * 14,
-               .size   = SZ_1M * 10,
-       },
-       [6] = {
-               .name   = "S3C2410 flash partition 6",
-               .offset = SZ_1M * 24,
-               .size   = SZ_1M * 24,
-       },
-       [7] = {
-               .name   = "S3C2410 flash partition 7",
-               .offset = SZ_1M * 48,
-               .size   = MTDPART_SIZ_FULL,
-       }
-};
-
-static struct s3c2410_nand_set smdk_nand_sets[] = {
-       [0] = {
-               .name           = "NAND",
-               .nr_chips       = 1,
-               .nr_partitions  = ARRAY_SIZE(smdk_default_nand_part),
-               .partitions     = smdk_default_nand_part,
-       },
-};
-
-/* choose a set of timings which should suit most 512Mbit
- * chips and beyond.
-*/
-
-static struct s3c2410_platform_nand smdk_nand_info = {
-       .tacls          = 20,
-       .twrph0         = 60,
-       .twrph1         = 20,
-       .nr_sets        = ARRAY_SIZE(smdk_nand_sets),
-       .sets           = smdk_nand_sets,
-};
-
-/* devices we initialise */
-
-static struct platform_device __initdata *smdk_devs[] = {
-       &s3c_device_nand,
-       &smdk_led4,
-       &smdk_led5,
-       &smdk_led6,
-       &smdk_led7,
-};
-
-void __init smdk_machine_init(void)
-{
-       /* Configure the LEDs (even if we have no LED support)*/
-
-       s3c_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT);
-       s3c_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT);
-       s3c_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT);
-       s3c_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT);
-
-       s3c2410_gpio_setpin(S3C2410_GPF(4), 1);
-       s3c2410_gpio_setpin(S3C2410_GPF(5), 1);
-       s3c2410_gpio_setpin(S3C2410_GPF(6), 1);
-       s3c2410_gpio_setpin(S3C2410_GPF(7), 1);
-
-       if (machine_is_smdk2443())
-               smdk_nand_info.twrph0 = 50;
-
-       s3c_nand_set_platdata(&smdk_nand_info);
-
-       platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs));
-
-       s3c_pm_init();
-}
diff --git a/arch/arm/plat-s3c24xx/pm-simtec.c b/arch/arm/plat-s3c24xx/pm-simtec.c
deleted file mode 100644 (file)
index 699f931..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/pm-simtec.c
- *
- * Copyright 2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * http://armlinux.simtec.co.uk/
- *
- * Power Management helpers for Simtec S3C24XX implementations
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/hardware.h>
-
-#include <mach/map.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-mem.h>
-
-#include <asm/mach-types.h>
-
-#include <plat/pm.h>
-
-#define COPYRIGHT ", Copyright 2005 Simtec Electronics"
-
-/* pm_simtec_init
- *
- * enable the power management functions
-*/
-
-static __init int pm_simtec_init(void)
-{
-       unsigned long gstatus4;
-
-       /* check which machine we are running on */
-
-       if (!machine_is_bast() && !machine_is_vr1000() &&
-           !machine_is_anubis() && !machine_is_osiris() &&
-           !machine_is_aml_m5900())
-               return 0;
-
-       printk(KERN_INFO "Simtec Board Power Management" COPYRIGHT "\n");
-
-       gstatus4  = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30;
-       gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28;
-       gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK);
-
-       __raw_writel(gstatus4, S3C2410_GSTATUS4);
-
-       return s3c_pm_init();
-}
-
-arch_initcall(pm_simtec_init);
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
deleted file mode 100644 (file)
index 95e6819..0000000
+++ /dev/null
@@ -1,636 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/s3c2443-clock.c
- *
- * Copyright (c) 2007, 2010 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2443 Clock control suport - common code
- */
-
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <mach/regs-s3c2443-clock.h>
-
-#include <plat/s3c2443.h>
-#include <plat/clock.h>
-#include <plat/clock-clksrc.h>
-#include <plat/cpu.h>
-
-#include <plat/cpu-freq.h>
-
-
-static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
-{
-       u32 ctrlbit = clk->ctrlbit;
-       u32 con = __raw_readl(reg);
-
-       if (enable)
-               con |= ctrlbit;
-       else
-               con &= ~ctrlbit;
-
-       __raw_writel(con, reg);
-       return 0;
-}
-
-int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
-{
-       return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
-}
-
-int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
-{
-       return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
-}
-
-int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
-{
-       return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
-}
-
-/* mpllref is a direct descendant of clk_xtal by default, but it is not
- * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
- * such directly equating the two source clocks is impossible.
- */
-struct clk clk_mpllref = {
-       .name           = "mpllref",
-       .parent         = &clk_xtal,
-};
-
-static struct clk *clk_epllref_sources[] = {
-       [0] = &clk_mpllref,
-       [1] = &clk_mpllref,
-       [2] = &clk_xtal,
-       [3] = &clk_ext,
-};
-
-struct clksrc_clk clk_epllref = {
-       .clk    = {
-               .name           = "epllref",
-       },
-       .sources = &(struct clksrc_sources) {
-               .sources = clk_epllref_sources,
-               .nr_sources = ARRAY_SIZE(clk_epllref_sources),
-       },
-       .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
-};
-
-/* esysclk
- *
- * this is sourced from either the EPLL or the EPLLref clock
-*/
-
-static struct clk *clk_sysclk_sources[] = {
-       [0] = &clk_epllref.clk,
-       [1] = &clk_epll,
-};
-
-struct clksrc_clk clk_esysclk = {
-       .clk    = {
-               .name           = "esysclk",
-               .parent         = &clk_epll,
-       },
-       .sources = &(struct clksrc_sources) {
-               .sources = clk_sysclk_sources,
-               .nr_sources = ARRAY_SIZE(clk_sysclk_sources),
-       },
-       .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
-};
-
-static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long div = __raw_readl(S3C2443_CLKDIV0);
-
-       div  &= S3C2443_CLKDIV0_EXTDIV_MASK;
-       div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1);       /* x2 */
-
-       return parent_rate / (div + 1);
-}
-
-static struct clk clk_mdivclk = {
-       .name           = "mdivclk",
-       .parent         = &clk_mpllref,
-       .ops            = &(struct clk_ops) {
-               .get_rate       = s3c2443_getrate_mdivclk,
-       },
-};
-
-static struct clk *clk_msysclk_sources[] = {
-       [0] = &clk_mpllref,
-       [1] = &clk_mpll,
-       [2] = &clk_mdivclk,
-       [3] = &clk_mpllref,
-};
-
-struct clksrc_clk clk_msysclk = {
-       .clk    = {
-               .name           = "msysclk",
-               .parent         = &clk_xtal,
-       },
-       .sources = &(struct clksrc_sources) {
-               .sources = clk_msysclk_sources,
-               .nr_sources = ARRAY_SIZE(clk_msysclk_sources),
-       },
-       .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
-};
-
-/* prediv
- *
- * this divides the msysclk down to pass to h/p/etc.
- */
-
-static unsigned long s3c2443_prediv_getrate(struct clk *clk)
-{
-       unsigned long rate = clk_get_rate(clk->parent);
-       unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
-
-       clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
-       clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
-
-       return rate / (clkdiv0 + 1);
-}
-
-static struct clk clk_prediv = {
-       .name           = "prediv",
-       .parent         = &clk_msysclk.clk,
-       .ops            = &(struct clk_ops) {
-               .get_rate       = s3c2443_prediv_getrate,
-       },
-};
-
-/* armdiv
- *
- * this clock is sourced from msysclk and can have a number of
- * divider values applied to it to then be fed into armclk.
-*/
-
-static unsigned int *armdiv;
-static int nr_armdiv;
-static int armdivmask;
-
-static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
-                                             unsigned long rate)
-{
-       unsigned long parent = clk_get_rate(clk->parent);
-       unsigned long calc;
-       unsigned best = 256; /* bigger than any value */
-       unsigned div;
-       int ptr;
-
-       if (!nr_armdiv)
-               return -EINVAL;
-
-       for (ptr = 0; ptr < nr_armdiv; ptr++) {
-               div = armdiv[ptr];
-               if (div) {
-                       /* cpufreq provides 266mhz as 266666000 not 266666666 */
-                       calc = (parent / div / 1000) * 1000;
-                       if (calc <= rate && div < best)
-                               best = div;
-               }
-       }
-
-       return parent / best;
-}
-
-static unsigned long s3c2443_armclk_getrate(struct clk *clk)
-{
-       unsigned long rate = clk_get_rate(clk->parent);
-       unsigned long clkcon0;
-       int val;
-
-       if (!nr_armdiv || !armdivmask)
-               return -EINVAL;
-
-       clkcon0 = __raw_readl(S3C2443_CLKDIV0);
-       clkcon0 &= armdivmask;
-       val = clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT;
-
-       return rate / armdiv[val];
-}
-
-static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
-{
-       unsigned long parent = clk_get_rate(clk->parent);
-       unsigned long calc;
-       unsigned div;
-       unsigned best = 256; /* bigger than any value */
-       int ptr;
-       int val = -1;
-
-       if (!nr_armdiv || !armdivmask)
-               return -EINVAL;
-
-       for (ptr = 0; ptr < nr_armdiv; ptr++) {
-               div = armdiv[ptr];
-               if (div) {
-                       /* cpufreq provides 266mhz as 266666000 not 266666666 */
-                       calc = (parent / div / 1000) * 1000;
-                       if (calc <= rate && div < best) {
-                               best = div;
-                               val = ptr;
-                       }
-               }
-       }
-
-       if (val >= 0) {
-               unsigned long clkcon0;
-
-               clkcon0 = __raw_readl(S3C2443_CLKDIV0);
-               clkcon0 &= ~armdivmask;
-               clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT;
-               __raw_writel(clkcon0, S3C2443_CLKDIV0);
-       }
-
-       return (val == -1) ? -EINVAL : 0;
-}
-
-static struct clk clk_armdiv = {
-       .name           = "armdiv",
-       .parent         = &clk_msysclk.clk,
-       .ops            = &(struct clk_ops) {
-               .round_rate = s3c2443_armclk_roundrate,
-               .get_rate = s3c2443_armclk_getrate,
-               .set_rate = s3c2443_armclk_setrate,
-       },
-};
-
-/* armclk
- *
- * this is the clock fed into the ARM core itself, from armdiv or from hclk.
- */
-
-static struct clk *clk_arm_sources[] = {
-       [0] = &clk_armdiv,
-       [1] = &clk_h,
-};
-
-static struct clksrc_clk clk_arm = {
-       .clk    = {
-               .name           = "armclk",
-       },
-       .sources = &(struct clksrc_sources) {
-               .sources = clk_arm_sources,
-               .nr_sources = ARRAY_SIZE(clk_arm_sources),
-       },
-       .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
-};
-
-/* usbhost
- *
- * usb host bus-clock, usually 48MHz to provide USB bus clock timing
-*/
-
-static struct clksrc_clk clk_usb_bus_host = {
-       .clk    = {
-               .name           = "usb-bus-host-parent",
-               .parent         = &clk_esysclk.clk,
-               .ctrlbit        = S3C2443_SCLKCON_USBHOST,
-               .enable         = s3c2443_clkcon_enable_s,
-       },
-       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
-};
-
-/* common clksrc clocks */
-
-static struct clksrc_clk clksrc_clks[] = {
-       {
-               /* camera interface bus-clock, divided down from esysclk */
-               .clk    = {
-                       .name           = "camif-upll", /* same as 2440 name */
-                       .parent         = &clk_esysclk.clk,
-                       .ctrlbit        = S3C2443_SCLKCON_CAMCLK,
-                       .enable         = s3c2443_clkcon_enable_s,
-               },
-               .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
-       }, {
-               .clk    = {
-                       .name           = "display-if",
-                       .parent         = &clk_esysclk.clk,
-                       .ctrlbit        = S3C2443_SCLKCON_DISPCLK,
-                       .enable         = s3c2443_clkcon_enable_s,
-               },
-               .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
-       },
-};
-
-static struct clksrc_clk clk_esys_uart = {
-       /* ART baud-rate clock sourced from esysclk via a divisor */
-       .clk    = {
-               .name           = "uartclk",
-               .parent         = &clk_esysclk.clk,
-       },
-       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
-};
-
-static struct clk clk_i2s_ext = {
-       .name           = "i2s-ext",
-};
-
-/* i2s_eplldiv
- *
- * This clock is the output from the I2S divisor of ESYSCLK, and is separate
- * from the mux that comes after it (cannot merge into one single clock)
-*/
-
-static struct clksrc_clk clk_i2s_eplldiv = {
-       .clk    = {
-               .name           = "i2s-eplldiv",
-               .parent         = &clk_esysclk.clk,
-       },
-       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 12, },
-};
-
-/* i2s-ref
- *
- * i2s bus reference clock, selectable from external, esysclk or epllref
- *
- * Note, this used to be two clocks, but was compressed into one.
-*/
-
-static struct clk *clk_i2s_srclist[] = {
-       [0] = &clk_i2s_eplldiv.clk,
-       [1] = &clk_i2s_ext,
-       [2] = &clk_epllref.clk,
-       [3] = &clk_epllref.clk,
-};
-
-static struct clksrc_clk clk_i2s = {
-       .clk    = {
-               .name           = "i2s-if",
-               .ctrlbit        = S3C2443_SCLKCON_I2SCLK,
-               .enable         = s3c2443_clkcon_enable_s,
-
-       },
-       .sources = &(struct clksrc_sources) {
-               .sources = clk_i2s_srclist,
-               .nr_sources = ARRAY_SIZE(clk_i2s_srclist),
-       },
-       .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
-};
-
-static struct clk init_clocks_off[] = {
-       {
-               .name           = "iis",
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_IIS,
-       }, {
-               .name           = "hsspi",
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_HSSPI,
-       }, {
-               .name           = "adc",
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_ADC,
-       }, {
-               .name           = "i2c",
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_IIC,
-       }
-};
-
-static struct clk init_clocks[] = {
-       {
-               .name           = "dma",
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_DMA0,
-       }, {
-               .name           = "dma",
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_DMA1,
-       }, {
-               .name           = "dma",
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_DMA2,
-       }, {
-               .name           = "dma",
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_DMA3,
-       }, {
-               .name           = "dma",
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_DMA4,
-       }, {
-               .name           = "dma",
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_DMA5,
-       }, {
-               .name           = "gpio",
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_GPIO,
-       }, {
-               .name           = "usb-host",
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_USBH,
-       }, {
-               .name           = "usb-device",
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_USBD,
-       }, {
-               .name           = "lcd",
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_LCDC,
-
-       }, {
-               .name           = "timers",
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_PWMT,
-       }, {
-               .name           = "cfc",
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_CFC,
-       }, {
-               .name           = "ssmc",
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_SSMC,
-       }, {
-               .name           = "uart",
-               .devname        = "s3c2440-uart.0",
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_UART0,
-       }, {
-               .name           = "uart",
-               .devname        = "s3c2440-uart.1",
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_UART1,
-       }, {
-               .name           = "uart",
-               .devname        = "s3c2440-uart.2",
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_UART2,
-       }, {
-               .name           = "uart",
-               .devname        = "s3c2440-uart.3",
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_UART3,
-       }, {
-               .name           = "rtc",
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_RTC,
-       }, {
-               .name           = "watchdog",
-               .parent         = &clk_p,
-               .ctrlbit        = S3C2443_PCLKCON_WDT,
-       }, {
-               .name           = "ac97",
-               .parent         = &clk_p,
-               .ctrlbit        = S3C2443_PCLKCON_AC97,
-       }, {
-               .name           = "nand",
-               .parent         = &clk_h,
-       }, {
-               .name           = "usb-bus-host",
-               .parent         = &clk_usb_bus_host.clk,
-       }
-};
-
-static struct clk hsmmc1_clk = {
-       .name           = "hsmmc",
-       .devname        = "s3c-sdhci.1",
-       .parent         = &clk_h,
-       .enable         = s3c2443_clkcon_enable_h,
-       .ctrlbit        = S3C2443_HCLKCON_HSMMC,
-};
-
-static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
-{
-       clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
-
-       return clkcon0 + 1;
-}
-
-/* EPLLCON compatible enough to get on/off information */
-
-void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll)
-{
-       unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
-       unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
-       unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
-       struct clk *xtal_clk;
-       unsigned long xtal;
-       unsigned long pll;
-       unsigned long fclk;
-       unsigned long hclk;
-       unsigned long pclk;
-       int ptr;
-
-       xtal_clk = clk_get(NULL, "xtal");
-       xtal = clk_get_rate(xtal_clk);
-       clk_put(xtal_clk);
-
-       pll = get_mpll(mpllcon, xtal);
-       clk_msysclk.clk.rate = pll;
-
-       fclk = clk_get_rate(&clk_armdiv);
-       hclk = s3c2443_prediv_getrate(&clk_prediv);
-       hclk /= s3c2443_get_hdiv(clkdiv0);
-       pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
-
-       s3c24xx_setup_clocks(fclk, hclk, pclk);
-
-       printk("CPU: MPLL %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
-              (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on",
-              print_mhz(pll), print_mhz(fclk),
-              print_mhz(hclk), print_mhz(pclk));
-
-       for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++)
-               s3c_set_clksrc(&clksrc_clks[ptr], true);
-
-       /* ensure usb bus clock is within correct rate of 48MHz */
-
-       if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
-               printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
-               clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
-       }
-
-       printk("CPU: EPLL %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
-              (epllcon & S3C2443_PLLCON_OFF) ? "off":"on",
-              print_mhz(clk_get_rate(&clk_epll)),
-              print_mhz(clk_get_rate(&clk_usb_bus)));
-}
-
-static struct clk *clks[] __initdata = {
-       &clk_prediv,
-       &clk_mpllref,
-       &clk_mdivclk,
-       &clk_ext,
-       &clk_epll,
-       &clk_usb_bus,
-       &clk_armdiv,
-       &hsmmc1_clk,
-};
-
-static struct clksrc_clk *clksrcs[] __initdata = {
-       &clk_i2s_eplldiv,
-       &clk_i2s,
-       &clk_usb_bus_host,
-       &clk_epllref,
-       &clk_esysclk,
-       &clk_msysclk,
-       &clk_arm,
-};
-
-static struct clk_lookup s3c2443_clk_lookup[] = {
-       CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
-       CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
-       CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk),
-       CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &hsmmc1_clk),
-};
-
-void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
-                                      unsigned int *divs, int nr_divs,
-                                      int divmask)
-{
-       int ptr;
-
-       armdiv = divs;
-       nr_armdiv = nr_divs;
-       armdivmask = divmask;
-
-       /* s3c2443 parents h and p clocks from prediv */
-       clk_h.parent = &clk_prediv;
-       clk_p.parent = &clk_prediv;
-
-       clk_usb_bus.parent = &clk_usb_bus_host.clk;
-       clk_epll.parent = &clk_epllref.clk;
-
-       s3c24xx_register_baseclocks(xtal);
-       s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
-
-       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
-               s3c_register_clksrc(clksrcs[ptr], 1);
-
-       s3c_register_clksrc(clksrc_clks, ARRAY_SIZE(clksrc_clks));
-       s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
-
-       /* See s3c2443/etc notes on disabling clocks at init time */
-       s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-       s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-       clkdev_add_table(s3c2443_clk_lookup, ARRAY_SIZE(s3c2443_clk_lookup));
-
-       s3c2443_common_setup_clocks(get_mpll);
-}
diff --git a/arch/arm/plat-s3c24xx/setup-i2c.c b/arch/arm/plat-s3c24xx/setup-i2c.c
deleted file mode 100644 (file)
index 9e90a7c..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/setup-i2c.c
- *
- * Copyright 2008 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C24XX Base setup for i2c device
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/gpio.h>
-
-struct platform_device;
-
-#include <plat/gpio-cfg.h>
-#include <plat/iic.h>
-#include <mach/hardware.h>
-#include <mach/regs-gpio.h>
-
-void s3c_i2c0_cfg_gpio(struct platform_device *dev)
-{
-       s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA);
-       s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL);
-}
diff --git a/arch/arm/plat-s3c24xx/setup-ts.c b/arch/arm/plat-s3c24xx/setup-ts.c
deleted file mode 100644 (file)
index ed26386..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/setup-ts.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *                     http://www.samsung.com/
- *
- * Based on S3C24XX setup for i2c device
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/gpio.h>
-
-struct platform_device; /* don't need the contents */
-
-#include <mach/hardware.h>
-#include <mach/regs-gpio.h>
-
-/**
- * s3c24xx_ts_cfg_gpio - configure gpio for s3c2410 systems
- *
- * Configure the GPIO for the S3C2410 system, where we have external FETs
- * connected to the device (later systems such as the S3C2440 integrate
- * these into the device).
- */
-void s3c24xx_ts_cfg_gpio(struct platform_device *dev)
-{
-       s3c2410_gpio_cfgpin(S3C2410_GPG(12), S3C2410_GPG12_XMON);
-       s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPG13_nXPON);
-       s3c2410_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPG14_YMON);
-       s3c2410_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPG15_nYPON);
-}
diff --git a/arch/arm/plat-s3c24xx/simtec-audio.c b/arch/arm/plat-s3c24xx/simtec-audio.c
deleted file mode 100644 (file)
index 6bc832e..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/simtec-audio.c
- *
- * Copyright (c) 2009 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Audio setup for various Simtec S3C24XX implementations
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/io.h>
-
-#include <mach/bast-map.h>
-#include <mach/bast-irq.h>
-#include <mach/bast-cpld.h>
-
-#include <mach/hardware.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/audio-simtec.h>
-#include <plat/devs.h>
-
-/* platform ops for audio */
-
-static void simtec_audio_startup_lrroute(void)
-{
-       unsigned int tmp;
-       unsigned long flags;
-
-       local_irq_save(flags);
-
-       tmp = __raw_readb(BAST_VA_CTRL1);
-       tmp &= ~BAST_CPLD_CTRL1_LRMASK;
-       tmp |= BAST_CPLD_CTRL1_LRCDAC;
-       __raw_writeb(tmp, BAST_VA_CTRL1);
-
-       local_irq_restore(flags);
-}
-
-static struct s3c24xx_audio_simtec_pdata simtec_audio_platdata;
-static char our_name[32];
-
-static struct platform_device simtec_audio_dev = {
-       .name   = our_name,
-       .id     = -1,
-       .dev    = {
-               .parent         = &s3c_device_iis.dev,
-               .platform_data  = &simtec_audio_platdata,
-       },
-};
-
-int __init simtec_audio_add(const char *name, bool has_lr_routing,
-                           struct s3c24xx_audio_simtec_pdata *spd)
-{
-       if (!name)
-               name = "tlv320aic23";
-
-       snprintf(our_name, sizeof(our_name)-1, "s3c24xx-simtec-%s", name);
-
-       /* copy platform data so the source can be __initdata */
-       if (spd)
-               simtec_audio_platdata = *spd;
-
-       if (has_lr_routing)
-               simtec_audio_platdata.startup = simtec_audio_startup_lrroute;
-
-       platform_device_register(&s3c_device_iis);
-       platform_device_register(&simtec_audio_dev);
-       return 0;
-}
diff --git a/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c b/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
deleted file mode 100644 (file)
index 704175b..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
- *
- * Copyright (c) 2008 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C24XX SPI - gpio configuration for bus 0 on gpe11,12,13
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
-*/
-
-#include <linux/kernel.h>
-#include <linux/gpio.h>
-
-#include <mach/spi.h>
-#include <mach/regs-gpio.h>
-
-void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi,
-                                         int enable)
-{
-       if (enable) {
-               s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0);
-               s3c_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0);
-               s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0);
-               s3c2410_gpio_pullup(S3C2410_GPE(11), 0);
-               s3c2410_gpio_pullup(S3C2410_GPE(13), 0);
-       } else {
-               s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT);
-               s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT);
-               s3c_gpio_setpull(S3C2410_GPE(11), S3C_GPIO_PULL_NONE);
-               s3c_gpio_setpull(S3C2410_GPE(12), S3C_GPIO_PULL_NONE);
-               s3c_gpio_setpull(S3C2410_GPE(13), S3C_GPIO_PULL_NONE);
-       }
-}
diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
deleted file mode 100644 (file)
index 72457af..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/spi-bus0-gpd8_9_10.c
- *
- * Copyright (c) 2008 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C24XX SPI - gpio configuration for bus 1 on gpd8,9,10
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
-*/
-
-#include <linux/kernel.h>
-#include <linux/gpio.h>
-
-#include <mach/spi.h>
-#include <mach/regs-gpio.h>
-
-void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi,
-                                       int enable)
-{
-
-       printk(KERN_INFO "%s(%d)\n", __func__, enable);
-       if (enable) {
-               s3c_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1);
-               s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1);
-               s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1);
-               s3c2410_gpio_pullup(S3C2410_GPD(10), 0);
-               s3c2410_gpio_pullup(S3C2410_GPD(9), 0);
-       } else {
-               s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT);
-               s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT);
-               s3c_gpio_setpull(S3C2410_GPD(10), S3C_GPIO_PULL_NONE);
-               s3c_gpio_setpull(S3C2410_GPD(9), S3C_GPIO_PULL_NONE);
-               s3c_gpio_setpull(S3C2410_GPD(8), S3C_GPIO_PULL_NONE);
-       }
-}
diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c b/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c
deleted file mode 100644 (file)
index c3972b6..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/spi-bus0-gpg5_6_7.c
- *
- * Copyright (c) 2008 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C24XX SPI - gpio configuration for bus 1 on gpg5,6,7
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
-*/
-
-#include <linux/kernel.h>
-#include <linux/gpio.h>
-
-#include <mach/spi.h>
-#include <mach/regs-gpio.h>
-
-void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi,
-                                      int enable)
-{
-       if (enable) {
-               s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1);
-               s3c_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1);
-               s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1);
-               s3c2410_gpio_pullup(S3C2410_GPG(5), 0);
-               s3c2410_gpio_pullup(S3C2410_GPG(6), 0);
-       } else {
-               s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT);
-               s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT);
-               s3c_gpio_setpull(S3C2410_GPG(5), S3C_GPIO_PULL_NONE);
-               s3c_gpio_setpull(S3C2410_GPG(6), S3C_GPIO_PULL_NONE);
-               s3c_gpio_setpull(S3C2410_GPG(7), S3C_GPIO_PULL_NONE);
-       }
-}
index 8167ce66188c65c19f6d9efda34b718f7acf7c0b..96bea32023046393e200d3a87987cd1557ce0f2a 100644 (file)
@@ -9,8 +9,8 @@ config PLAT_S5P
        bool
        depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
        default y
-       select ARM_VIC if !ARCH_EXYNOS4
-       select ARM_GIC if ARCH_EXYNOS4
+       select ARM_VIC if !ARCH_EXYNOS
+       select ARM_GIC if ARCH_EXYNOS
        select GIC_NON_BANKED if ARCH_EXYNOS4
        select NO_IOPORT
        select ARCH_REQUIRE_GPIOLIB
@@ -40,6 +40,10 @@ config S5P_HRT
        help
          Use the High Resolution timer support
 
+config S5P_DEV_UART
+       def_bool y
+       depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210)
+
 config S5P_PM
        bool
        help
@@ -80,6 +84,16 @@ config S5P_DEV_FIMC3
        help
          Compile in platform device definitions for FIMC controller 3
 
+config S5P_DEV_JPEG
+       bool
+       help
+         Compile in platform device definitions for JPEG codec
+
+config S5P_DEV_G2D
+       bool
+       help
+         Compile in platform device definitions for G2D device
+
 config S5P_DEV_FIMD0
        bool
        help
index 30d8c3016e6b910d3fc5c92c967a4ee2b973e6a7..4bd8241366594c1dd4e47fad5b0c4ac8ad5cdbbf 100644 (file)
@@ -12,7 +12,6 @@ obj-                          :=
 
 # Core files
 
-obj-y                          += dev-uart.o
 obj-y                          += clock.o
 obj-y                          += irq.o
 obj-$(CONFIG_S5P_EXT_INT)      += irq-eint.o
@@ -23,5 +22,7 @@ obj-$(CONFIG_S5P_SLEEP)               += sleep.o
 obj-$(CONFIG_S5P_HRT)          += s5p-time.o
 
 # devices
+
+obj-$(CONFIG_S5P_DEV_UART)     += dev-uart.o
 obj-$(CONFIG_S5P_DEV_MFC)      += dev-mfc.o
 obj-$(CONFIG_S5P_SETUP_MIPIPHY)        += setup-mipiphy.o
index 963edea7f7e77c246a334d49d29b02443d67598b..f68a9bb1194807ef193d09e62cdf6d0a9c0ff63b 100644 (file)
@@ -61,6 +61,20 @@ struct clk clk_fout_apll = {
        .id             = -1,
 };
 
+/* BPLL clock output */
+
+struct clk clk_fout_bpll = {
+       .name           = "fout_bpll",
+       .id             = -1,
+};
+
+/* CPLL clock output */
+
+struct clk clk_fout_cpll = {
+       .name           = "fout_cpll",
+       .id             = -1,
+};
+
 /* MPLL clock output
  * No need .ctrlbit, this is always on
 */
@@ -101,6 +115,28 @@ struct clksrc_sources clk_src_apll = {
        .nr_sources     = ARRAY_SIZE(clk_src_apll_list),
 };
 
+/* Possible clock sources for BPLL Mux */
+static struct clk *clk_src_bpll_list[] = {
+       [0] = &clk_fin_bpll,
+       [1] = &clk_fout_bpll,
+};
+
+struct clksrc_sources clk_src_bpll = {
+       .sources        = clk_src_bpll_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_bpll_list),
+};
+
+/* Possible clock sources for CPLL Mux */
+static struct clk *clk_src_cpll_list[] = {
+       [0] = &clk_fin_cpll,
+       [1] = &clk_fout_cpll,
+};
+
+struct clksrc_sources clk_src_cpll = {
+       .sources        = clk_src_cpll_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_cpll_list),
+};
+
 /* Possible clock sources for MPLL Mux */
 static struct clk *clk_src_mpll_list[] = {
        [0] = &clk_fin_mpll,
index c496b359c371d78e37f1223bc16ba28aeb92bcf0..139c050918c54378bf90511971819060da46aeb0 100644 (file)
@@ -200,7 +200,7 @@ static struct irq_chip s5p_irq_vic_eint = {
 #endif
 };
 
-int __init s5p_init_irq_eint(void)
+static int __init s5p_init_irq_eint(void)
 {
        int irq;
 
index 1fdfaa4599ced6465f647bc77578a92c9694b9bc..82c7311017a2b0e0ac30d8bf27f47bc001cc400e 100644 (file)
@@ -41,7 +41,7 @@ struct s5p_gpioint_bank {
        void                    (*handler)(unsigned int, struct irq_desc *);
 };
 
-LIST_HEAD(banks);
+static LIST_HEAD(banks);
 
 static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type)
 {
index 327acb3a44644e2c2b62de2aca37c3220b4a986b..d1bfecae6c9ff4b869ababa4dfa70dcc416c20a8 100644 (file)
@@ -39,19 +39,32 @@ unsigned long s3c_irqwake_eintallow = 0xffffffffL;
 int s3c_irq_wake(struct irq_data *data, unsigned int state)
 {
        unsigned long irqbit;
+       unsigned int irq_rtc_tic, irq_rtc_alarm;
+
+#ifdef CONFIG_ARCH_EXYNOS
+       if (soc_is_exynos5250()) {
+               irq_rtc_tic = EXYNOS5_IRQ_RTC_TIC;
+               irq_rtc_alarm = EXYNOS5_IRQ_RTC_ALARM;
+       } else {
+               irq_rtc_tic = EXYNOS4_IRQ_RTC_TIC;
+               irq_rtc_alarm = EXYNOS4_IRQ_RTC_ALARM;
+       }
+#else
+       irq_rtc_tic = IRQ_RTC_TIC;
+       irq_rtc_alarm = IRQ_RTC_ALARM;
+#endif
+
+       if (data->irq == irq_rtc_tic || data->irq == irq_rtc_alarm) {
+               irqbit = 1 << (data->irq + 1 - irq_rtc_alarm);
 
-       switch (data->irq) {
-       case IRQ_RTC_TIC:
-       case IRQ_RTC_ALARM:
-               irqbit = 1 << (data->irq + 1 - IRQ_RTC_ALARM);
                if (!state)
                        s3c_irqwake_intmask |= irqbit;
                else
                        s3c_irqwake_intmask &= ~irqbit;
-               break;
-       default:
+       } else {
                return -ENOENT;
        }
+
        return 0;
 }
 
index 0fd591bfc9fd23423b41e92ee6d2fbc2b7213650..006bd01eda0231e1d41d3832b6287f54a699bc98 100644 (file)
 */
 
 #include <linux/linkage.h>
-#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/hardware/cache-l2x0.h>
 
-       .text
+/*
+ *      The following code is located into the .data section. This is to
+ *      allow l2x0_regs_phys to be accessed with a relative load while we
+ *      can't rely on any MMU translation. We could have put l2x0_regs_phys
+ *      in the .text section as well, but some setups might insist on it to
+ *      be truly read-only. (Reference from: arch/arm/kernel/sleep.S)
+ */
+       .data
+       .align
 
        /*
         * sleep magic, to allow the bootloader to check for an valid
         * s3c_cpu_resume
         *
         * resume code entry for bootloader to call
-        *
-        * we must put this code here in the data segment as we have no
-        * other way of restoring the stack pointer after sleep, and we
-        * must not write to the code segment (code is read-only)
         */
 
 ENTRY(s3c_cpu_resume)
+#ifdef CONFIG_CACHE_L2X0
+       adr     r0, l2x0_regs_phys
+       ldr     r0, [r0]
+       ldr     r1, [r0, #L2X0_R_PHY_BASE]
+       ldr     r2, [r1, #L2X0_CTRL]
+       tst     r2, #0x1
+       bne     resume_l2on
+       ldr     r2, [r0, #L2X0_R_AUX_CTRL]
+       str     r2, [r1, #L2X0_AUX_CTRL]
+       ldr     r2, [r0, #L2X0_R_TAG_LATENCY]
+       str     r2, [r1, #L2X0_TAG_LATENCY_CTRL]
+       ldr     r2, [r0, #L2X0_R_DATA_LATENCY]
+       str     r2, [r1, #L2X0_DATA_LATENCY_CTRL]
+       ldr     r2, [r0, #L2X0_R_PREFETCH_CTRL]
+       str     r2, [r1, #L2X0_PREFETCH_CTRL]
+       ldr     r2, [r0, #L2X0_R_PWR_CTRL]
+       str     r2, [r1, #L2X0_POWER_CTRL]
+       mov     r2, #1
+       str     r2, [r1, #L2X0_CTRL]
+resume_l2on:
+#endif
        b       cpu_resume
+ENDPROC(s3c_cpu_resume)
+#ifdef CONFIG_CACHE_L2X0
+       .globl l2x0_regs_phys
+l2x0_regs_phys:
+       .long   0
+#endif
index 6a2abe67c8b20d9274d4df502e6ab3db8083b5e5..71553f410016057315a51b27c28bca46d8bfd93e 100644 (file)
@@ -205,7 +205,7 @@ config S3C_DEV_USB_HSOTG
 
 config S3C_DEV_WDT
        bool
-       default y if ARCH_S3C2410
+       default y if ARCH_S3C24XX
        help
          Complie in platform device definition for Watchdog Timer
 
@@ -264,7 +264,7 @@ config SAMSUNG_DEV_KEYPAD
 
 config SAMSUNG_DEV_PWM
        bool
-       default y if ARCH_S3C2410
+       default y if ARCH_S3C24XX
        help
          Compile in platform device definition for PWM Timer
 
index 10f71179071f9b2db939764804401568309d801d..65c5eca475e76ef839a16aaef568173a2dc0ee1c 100644 (file)
@@ -84,31 +84,35 @@ static int clk_null_enable(struct clk *clk, int enable)
 
 int clk_enable(struct clk *clk)
 {
+       unsigned long flags;
+
        if (IS_ERR(clk) || clk == NULL)
                return -EINVAL;
 
        clk_enable(clk->parent);
 
-       spin_lock(&clocks_lock);
+       spin_lock_irqsave(&clocks_lock, flags);
 
        if ((clk->usage++) == 0)
                (clk->enable)(clk, 1);
 
-       spin_unlock(&clocks_lock);
+       spin_unlock_irqrestore(&clocks_lock, flags);
        return 0;
 }
 
 void clk_disable(struct clk *clk)
 {
+       unsigned long flags;
+
        if (IS_ERR(clk) || clk == NULL)
                return;
 
-       spin_lock(&clocks_lock);
+       spin_lock_irqsave(&clocks_lock, flags);
 
        if ((--clk->usage) == 0)
                (clk->enable)(clk, 0);
 
-       spin_unlock(&clocks_lock);
+       spin_unlock_irqrestore(&clocks_lock, flags);
        clk_disable(clk->parent);
 }
 
index a976c023b286b4a1b991cfa63c2dc93e9912151d..5f197dcaf10c017a439185f0f29860e9877a2cdd 100644 (file)
@@ -77,7 +77,7 @@ static struct platform_device samsung_dfl_bl_device __initdata = {
  * @gpio_info: structure containing GPIO info for PWM timer
  * @bl_data:   structure containing Backlight control data
  */
-void samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
+void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
        struct platform_pwm_backlight_data *bl_data)
 {
        int ret = 0;
@@ -115,6 +115,8 @@ void samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
                samsung_bl_data->init = bl_data->init;
        if (bl_data->notify)
                samsung_bl_data->notify = bl_data->notify;
+       if (bl_data->notify_after)
+               samsung_bl_data->notify_after = bl_data->notify_after;
        if (bl_data->exit)
                samsung_bl_data->exit = bl_data->exit;
        if (bl_data->check_fb)
index d21d744e4d99d9d9623bb9d26cfb628e87c82a63..8b928f9bc1c311e72936ad392f6ed13397bc3317 100644 (file)
@@ -57,6 +57,7 @@
 #include <plat/sdhci.h>
 #include <plat/ts.h>
 #include <plat/udc.h>
+#include <plat/udc-hs.h>
 #include <plat/usb-control.h>
 #include <plat/usb-phy.h>
 #include <plat/regs-iic.h>
@@ -267,6 +268,52 @@ struct platform_device s5p_device_fimc3 = {
 };
 #endif /* CONFIG_S5P_DEV_FIMC3 */
 
+/* G2D */
+
+#ifdef CONFIG_S5P_DEV_G2D
+static struct resource s5p_g2d_resource[] = {
+       [0] = {
+               .start  = S5P_PA_G2D,
+               .end    = S5P_PA_G2D + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_2D,
+               .end    = IRQ_2D,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device s5p_device_g2d = {
+       .name           = "s5p-g2d",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(s5p_g2d_resource),
+       .resource       = s5p_g2d_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+#endif /* CONFIG_S5P_DEV_G2D */
+
+#ifdef CONFIG_S5P_DEV_JPEG
+static struct resource s5p_jpeg_resource[] = {
+       [0] = DEFINE_RES_MEM(S5P_PA_JPEG, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_JPEG),
+};
+
+struct platform_device s5p_device_jpeg = {
+       .name           = "s5p-jpeg",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(s5p_jpeg_resource),
+       .resource       = s5p_jpeg_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+#endif /*  CONFIG_S5P_DEV_JPEG */
+
 /* FIMD0 */
 
 #ifdef CONFIG_S5P_DEV_FIMD0
@@ -744,17 +791,6 @@ struct platform_device s3c_device_iis = {
 };
 #endif /* CONFIG_PLAT_S3C24XX */
 
-#ifdef CONFIG_CPU_S3C2440
-struct platform_device s3c2412_device_iis = {
-       .name           = "s3c2412-iis",
-       .id             = -1,
-       .dev            = {
-               .dma_mask               = &samsung_device_dma_mask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       }
-};
-#endif /* CONFIG_CPU_S3C2440 */
-
 /* IDE CFCON */
 
 #ifdef CONFIG_SAMSUNG_DEV_IDE
@@ -769,7 +805,7 @@ struct platform_device s3c_device_cfcon = {
        .resource       = s3c_cfcon_resource,
 };
 
-void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata)
+void __init s3c_ide_set_platdata(struct s3c_ide_platdata *pdata)
 {
        s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata),
                         &s3c_device_cfcon);
@@ -887,7 +923,7 @@ struct platform_device s5p_device_mfc_r = {
 
 #ifdef CONFIG_S5P_DEV_CSIS0
 static struct resource s5p_mipi_csis0_resource[] = {
-       [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS0, SZ_4K),
+       [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS0, SZ_16K),
        [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS0),
 };
 
@@ -901,7 +937,7 @@ struct platform_device s5p_device_mipi_csis0 = {
 
 #ifdef CONFIG_S5P_DEV_CSIS1
 static struct resource s5p_mipi_csis1_resource[] = {
-       [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS1, SZ_4K),
+       [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS1, SZ_16K),
        [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS1),
 };
 
@@ -1049,7 +1085,7 @@ struct platform_device s3c64xx_device_onenand1 = {
        .resource       = s3c64xx_onenand1_resources,
 };
 
-void s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata)
+void __init s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata)
 {
        s3c_set_platdata(pdata, sizeof(struct onenand_platform_data),
                         &s3c64xx_device_onenand1);
@@ -1078,7 +1114,7 @@ static struct resource s5p_pmu_resource[] = {
        DEFINE_RES_IRQ(IRQ_PMU)
 };
 
-struct platform_device s5p_device_pmu = {
+static struct platform_device s5p_device_pmu = {
        .name           = "arm-pmu",
        .id             = ARM_PMU_DEVICE_CPU,
        .num_resources  = ARRAY_SIZE(s5p_pmu_resource),
@@ -1423,6 +1459,19 @@ struct platform_device s3c_device_usb_hsotg = {
                .coherent_dma_mask      = DMA_BIT_MASK(32),
        },
 };
+
+void __init s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd)
+{
+       struct s3c_hsotg_plat *npd;
+
+       npd = s3c_set_platdata(pd, sizeof(struct s3c_hsotg_plat),
+                       &s3c_device_usb_hsotg);
+
+       if (!npd->phy_init)
+               npd->phy_init = s5p_usb_phy_init;
+       if (!npd->phy_exit)
+               npd->phy_exit = s5p_usb_phy_exit;
+}
 #endif /* CONFIG_S3C_DEV_USB_HSOTG */
 
 /* USB High Spped 2.0 Device (Gadget) */
index 0747c77a2fd53d0d2a66a1f1f2377b3d7e7722f6..301d9c319d0bb69b590eb63cc5e4b2319a466cb1 100644 (file)
@@ -116,7 +116,7 @@ static inline int samsung_dmadev_flush(unsigned ch)
        return dmaengine_terminate_all((struct dma_chan *)ch);
 }
 
-struct samsung_dma_ops dmadev_ops = {
+static struct samsung_dma_ops dmadev_ops = {
        .request        = samsung_dmadev_request,
        .release        = samsung_dmadev_release,
        .prepare        = samsung_dmadev_prepare,
index 5345364e7420c6e533594a35e4a7c4b1cf9b374d..376af5286a3ef8563fec56c5ac3241ba6200d201 100644 (file)
@@ -32,6 +32,3 @@ struct s3c24xx_audio_simtec_pdata {
 
        void    (*startup)(void);
 };
-
-extern int simtec_audio_add(const char *codec_name, bool has_lr_routing,
-                           struct s3c24xx_audio_simtec_pdata *pdata);
index 73c66d4d10fa4d30919a24af5ed2ee9ea1f885fc..a62753dc15baf144ecfc2ea7efe53bfc6f13a9fe 100644 (file)
@@ -79,6 +79,10 @@ extern struct clk clk_epll;
 extern struct clk clk_xtal;
 extern struct clk clk_ext;
 
+/* S3C2443/S3C2416 specific clocks */
+extern struct clksrc_clk clk_epllref;
+extern struct clksrc_clk clk_esysclk;
+
 /* S3C64XX specific clocks */
 extern struct clk clk_h2;
 extern struct clk clk_27m;
@@ -114,7 +118,23 @@ extern void s3c24xx_setup_clocks(unsigned long fclk,
 extern void s3c2410_setup_clocks(void);
 extern void s3c2412_setup_clocks(void);
 extern void s3c244x_setup_clocks(void);
-extern void s3c2443_setup_clocks(void);
+
+/* S3C2410 specific clock functions */
+
+extern int s3c2410_baseclk_add(void);
+
+/* S3C2443/S3C2416 specific clock functions */
+
+typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base);
+
+extern void s3c2443_common_setup_clocks(pll_fn get_mpll);
+extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
+                                      unsigned int *divs, int nr_divs,
+                                      int divmask);
+
+extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable);
+extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable);
+extern int s3c2443_clkcon_enable_s(struct clk *clk, int enable);
 
 /* S3C64XX specific functions and clocks */
 
index 73cb3cfd06853bd3ead46c8661acfdc0ad926f1a..787ceaca0be8aeb74122df8270ee995398da6f24 100644 (file)
@@ -42,6 +42,9 @@ extern unsigned long samsung_cpu_id;
 #define EXYNOS4412_CPU_ID      0xE4412200
 #define EXYNOS4_CPU_MASK       0xFFFE0000
 
+#define EXYNOS5250_SOC_ID      0x43520000
+#define EXYNOS5_SOC_MASK       0xFFFFF000
+
 #define IS_SAMSUNG_CPU(name, id, mask)         \
 static inline int is_samsung_##name(void)      \
 {                                              \
@@ -58,6 +61,7 @@ IS_SAMSUNG_CPU(s5pv210, S5PV210_CPU_ID, S5PV210_CPU_MASK)
 IS_SAMSUNG_CPU(exynos4210, EXYNOS4210_CPU_ID, EXYNOS4_CPU_MASK)
 IS_SAMSUNG_CPU(exynos4212, EXYNOS4212_CPU_ID, EXYNOS4_CPU_MASK)
 IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS4_CPU_MASK)
+IS_SAMSUNG_CPU(exynos5250, EXYNOS5250_SOC_ID, EXYNOS5_SOC_MASK)
 
 #if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \
     defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2440) || \
@@ -120,6 +124,12 @@ IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS4_CPU_MASK)
 #define EXYNOS4210_REV_1_0     (0x10)
 #define EXYNOS4210_REV_1_1     (0x11)
 
+#if defined(CONFIG_SOC_EXYNOS5250)
+# define soc_is_exynos5250()   is_samsung_exynos5250()
+#else
+# define soc_is_exynos5250()   0
+#endif
+
 #define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
 
 #ifndef MHZ
index 4214ea0ff8fe36ffb6d64d8372d2d8248b889b76..2155d4af62a30ce2d83c016e097690ba1b0ae316 100644 (file)
@@ -26,6 +26,8 @@ struct s3c24xx_uart_resources {
 extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
 extern struct s3c24xx_uart_resources s3c64xx_uart_resources[];
 extern struct s3c24xx_uart_resources s5p_uart_resources[];
+extern struct s3c24xx_uart_resources exynos4_uart_resources[];
+extern struct s3c24xx_uart_resources exynos5_uart_resources[];
 
 extern struct platform_device *s3c24xx_uart_devs[];
 extern struct platform_device *s3c24xx_uart_src[];
@@ -79,6 +81,8 @@ extern struct platform_device s5p_device_fimc1;
 extern struct platform_device s5p_device_fimc2;
 extern struct platform_device s5p_device_fimc3;
 extern struct platform_device s5p_device_fimc_md;
+extern struct platform_device s5p_device_jpeg;
+extern struct platform_device s5p_device_g2d;
 extern struct platform_device s5p_device_fimd0;
 extern struct platform_device s5p_device_hdmi;
 extern struct platform_device s5p_device_i2c_hdmiphy;
index c5eaad529de57d4dbdf94a2fdb96bef820ae70fd..0670f37aaaedcfe7990d359df010db7ced9c935a 100644 (file)
@@ -82,6 +82,22 @@ enum dma_ch {
        DMACH_SLIMBUS4_TX,
        DMACH_SLIMBUS5_RX,
        DMACH_SLIMBUS5_TX,
+       DMACH_MIPI_HSI0,
+       DMACH_MIPI_HSI1,
+       DMACH_MIPI_HSI2,
+       DMACH_MIPI_HSI3,
+       DMACH_MIPI_HSI4,
+       DMACH_MIPI_HSI5,
+       DMACH_MIPI_HSI6,
+       DMACH_MIPI_HSI7,
+       DMACH_MTOM_0,
+       DMACH_MTOM_1,
+       DMACH_MTOM_2,
+       DMACH_MTOM_3,
+       DMACH_MTOM_4,
+       DMACH_MTOM_5,
+       DMACH_MTOM_6,
+       DMACH_MTOM_7,
        /* END Marker, also used to denote a reserved channel */
        DMACH_MAX,
 };
index 178bccbe4804a79de6421215d5b16b3b7c58ebb3..a7d622ef16af40b76fca167a1be1edb3d5139009 100644 (file)
 #define S3C2412_DMAREQSEL_UART2_1      S3C2412_DMAREQSEL_SRC(24)
 #endif /* CONFIG_CPU_S3C2412 */
 
-#ifdef CONFIG_CPU_S3C2443
+#if defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2443)
 
 #define S3C2443_DMAREQSEL_SRC(x)       ((x) << 1)
 
index 30b7cc14cef5b6acd81edc534930ba4f11726fb7..0f8263e93eea94678b28f8e8d60cbbc1f6a48763 100644 (file)
 #define S3C2410_INTP_ALM       (1 << 1)
 #define S3C2410_INTP_TIC       (1 << 0)
 
-#define S3C2410_RTCCON       S3C2410_RTCREG(0x40)
-#define S3C2410_RTCCON_RTCEN  (1<<0)
-#define S3C2410_RTCCON_CLKSEL (1<<1)
-#define S3C2410_RTCCON_CNTSEL (1<<2)
-#define S3C2410_RTCCON_CLKRST (1<<3)
-#define S3C64XX_RTCCON_TICEN  (1<<8)
+#define S3C2410_RTCCON         S3C2410_RTCREG(0x40)
+#define S3C2410_RTCCON_RTCEN   (1 << 0)
+#define S3C2410_RTCCON_CNTSEL  (1 << 2)
+#define S3C2410_RTCCON_CLKRST  (1 << 3)
+#define S3C2443_RTCCON_TICSEL  (1 << 4)
+#define S3C64XX_RTCCON_TICEN   (1 << 8)
 
-#define S3C64XX_RTCCON_TICMSK (0xF<<7)
-#define S3C64XX_RTCCON_TICSHT (7)
+#define S3C2410_TICNT          S3C2410_RTCREG(0x44)
+#define S3C2410_TICNT_ENABLE   (1 << 7)
 
-#define S3C2410_TICNT        S3C2410_RTCREG(0x44)
-#define S3C2410_TICNT_ENABLE  (1<<7)
+/* S3C2443: tick count is 15 bit wide
+ * TICNT[6:0] contains upper 7 bits
+ * TICNT1[7:0] contains lower 8 bits
+ */
+#define S3C2443_TICNT_PART(x)  ((x & 0x7f00) >> 8)
+#define S3C2443_TICNT1         S3C2410_RTCREG(0x4C)
+#define S3C2443_TICNT1_PART(x) (x & 0xff)
 
-#define S3C2410_RTCALM       S3C2410_RTCREG(0x50)
-#define S3C2410_RTCALM_ALMEN  (1<<6)
-#define S3C2410_RTCALM_YEAREN (1<<5)
-#define S3C2410_RTCALM_MONEN  (1<<4)
-#define S3C2410_RTCALM_DAYEN  (1<<3)
-#define S3C2410_RTCALM_HOUREN (1<<2)
-#define S3C2410_RTCALM_MINEN  (1<<1)
-#define S3C2410_RTCALM_SECEN  (1<<0)
+/* S3C2416: tick count is 32 bit wide
+ * TICNT[6:0] contains bits [14:8]
+ * TICNT1[7:0] contains lower 8 bits
+ * TICNT2[16:0] contains upper 17 bits
+ */
+#define S3C2416_TICNT2         S3C2410_RTCREG(0x48)
+#define S3C2416_TICNT2_PART(x) ((x & 0xffff8000) >> 15)
 
-#define S3C2410_RTCALM_ALL \
-  S3C2410_RTCALM_ALMEN | S3C2410_RTCALM_YEAREN | S3C2410_RTCALM_MONEN |\
-  S3C2410_RTCALM_DAYEN | S3C2410_RTCALM_HOUREN | S3C2410_RTCALM_MINEN |\
-  S3C2410_RTCALM_SECEN
+#define S3C2410_RTCALM         S3C2410_RTCREG(0x50)
+#define S3C2410_RTCALM_ALMEN   (1 << 6)
+#define S3C2410_RTCALM_YEAREN  (1 << 5)
+#define S3C2410_RTCALM_MONEN   (1 << 4)
+#define S3C2410_RTCALM_DAYEN   (1 << 3)
+#define S3C2410_RTCALM_HOUREN  (1 << 2)
+#define S3C2410_RTCALM_MINEN   (1 << 1)
+#define S3C2410_RTCALM_SECEN   (1 << 0)
 
+#define S3C2410_ALMSEC         S3C2410_RTCREG(0x54)
+#define S3C2410_ALMMIN         S3C2410_RTCREG(0x58)
+#define S3C2410_ALMHOUR                S3C2410_RTCREG(0x5c)
 
-#define S3C2410_ALMSEC       S3C2410_RTCREG(0x54)
-#define S3C2410_ALMMIN       S3C2410_RTCREG(0x58)
-#define S3C2410_ALMHOUR              S3C2410_RTCREG(0x5c)
-
-#define S3C2410_ALMDATE              S3C2410_RTCREG(0x60)
-#define S3C2410_ALMMON       S3C2410_RTCREG(0x64)
-#define S3C2410_ALMYEAR              S3C2410_RTCREG(0x68)
-
-#define S3C2410_RTCRST       S3C2410_RTCREG(0x6c)
-
-#define S3C2410_RTCSEC       S3C2410_RTCREG(0x70)
-#define S3C2410_RTCMIN       S3C2410_RTCREG(0x74)
-#define S3C2410_RTCHOUR              S3C2410_RTCREG(0x78)
-#define S3C2410_RTCDATE              S3C2410_RTCREG(0x7c)
-#define S3C2410_RTCDAY       S3C2410_RTCREG(0x80)
-#define S3C2410_RTCMON       S3C2410_RTCREG(0x84)
-#define S3C2410_RTCYEAR              S3C2410_RTCREG(0x88)
+#define S3C2410_ALMDATE                S3C2410_RTCREG(0x60)
+#define S3C2410_ALMMON         S3C2410_RTCREG(0x64)
+#define S3C2410_ALMYEAR                S3C2410_RTCREG(0x68)
 
+#define S3C2410_RTCSEC         S3C2410_RTCREG(0x70)
+#define S3C2410_RTCMIN         S3C2410_RTCREG(0x74)
+#define S3C2410_RTCHOUR                S3C2410_RTCREG(0x78)
+#define S3C2410_RTCDATE                S3C2410_RTCREG(0x7c)
+#define S3C2410_RTCMON         S3C2410_RTCREG(0x84)
+#define S3C2410_RTCYEAR                S3C2410_RTCREG(0x88)
 
 #endif /* __ASM_ARCH_REGS_RTC_H */
index a111ad871833dae9e586fdb6705b9341ad644a35..fcf27966206795c78ec8a3732b2b8cd799a0f398 100644 (file)
@@ -25,8 +25,9 @@
 #define S3C_HSOTG_PHYREG(x)    ((x) + S3C_VA_USB_HSPHY)
 
 #define S3C_PHYPWR                             S3C_HSOTG_PHYREG(0x00)
-#define SRC_PHYPWR_OTG_DISABLE                 (1 << 4)
-#define SRC_PHYPWR_ANALOG_POWERDOWN            (1 << 3)
+#define S3C_PHYPWR_NORMAL_MASK                 (0x19 << 0)
+#define S3C_PHYPWR_OTG_DISABLE                 (1 << 4)
+#define S3C_PHYPWR_ANALOG_POWERDOWN            (1 << 3)
 #define SRC_PHYPWR_FORCE_SUSPEND               (1 << 1)
 
 #define S3C_PHYCLK                             S3C_HSOTG_PHYREG(0x04)
@@ -42,7 +43,7 @@
 
 #define S3C_RSTCON                             S3C_HSOTG_PHYREG(0x08)
 #define S3C_RSTCON_PHYCLK                      (1 << 2)
-#define S3C_RSTCON_HCLK                                (1 << 2)
+#define S3C_RSTCON_HCLK                                (1 << 1)
 #define S3C_RSTCON_PHY                         (1 << 0)
 
 #define S3C_PHYTUNE                            S3C_HSOTG_PHYREG(0x20)
diff --git a/arch/arm/plat-samsung/include/plat/rtc-core.h b/arch/arm/plat-samsung/include/plat/rtc-core.h
new file mode 100644 (file)
index 0000000..21d8594
--- /dev/null
@@ -0,0 +1,27 @@
+/* linux/arch/arm/plat-samsung/include/plat/rtc-core.h
+ *
+ * Copyright (c) 2011 Heiko Stuebner <heiko@sntech.de>
+ *
+ * Samsung RTC Controller core functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_RTC_CORE_H
+#define __ASM_PLAT_RTC_CORE_H __FILE__
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+ */
+
+/* re-define device name depending on support. */
+static inline void s3c_rtc_setname(char *name)
+{
+#if defined(CONFIG_SAMSUNG_DEV_RTC) || defined(CONFIG_PLAT_S3C24XX)
+       s3c_device_rtc.name = name;
+#endif
+}
+
+#endif /* __ASM_PLAT_RTC_CORE_H */
index 3986497dd3f7a2b21a1fe2c392f498366d0ce96e..55b0e5f51e97c5b7d65065b3c68772ab4018feef 100644 (file)
@@ -29,5 +29,3 @@ extern void s3c2410_init_clocks(int xtal);
 #define s3c2410_init NULL
 #define s3c2410a_init NULL
 #endif
-
-extern int s3c2410_baseclk_add(void);
index dce05b43d51c4e89c542aa2475167e14d915a814..a5b794ff838b5b230929a12f0589e26f186d668a 100644 (file)
@@ -32,23 +32,3 @@ extern void s3c2443_restart(char mode, const char *cmd);
 #define s3c2443_init NULL
 #define s3c2443_restart NULL
 #endif
-
-/* common code used by s3c2443 and others.
- * note, not to be used outside of arch/arm/mach-s3c* */
-
-struct clk;    /* some files don't need clk.h otherwise */
-
-typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base);
-
-extern void s3c2443_common_setup_clocks(pll_fn get_mpll);
-extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
-                                      unsigned int *divs, int nr_divs,
-                                      int divmask);
-
-extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable);
-extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable);
-extern int s3c2443_clkcon_enable_s(struct clk *clk, int enable);
-
-extern struct clksrc_clk clk_epllref;
-extern struct clksrc_clk clk_esysclk;
-extern struct clksrc_clk clk_msysclk;
index 984bf9e7bc89e49f3b7e14ffa7b0edc06c8375ca..1de4b32f98e9a81ad55b2f921f87c174d0707365 100644 (file)
@@ -18,6 +18,8 @@
 #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
 
 #define clk_fin_apll clk_ext_xtal_mux
+#define clk_fin_bpll clk_ext_xtal_mux
+#define clk_fin_cpll clk_ext_xtal_mux
 #define clk_fin_mpll clk_ext_xtal_mux
 #define clk_fin_epll clk_ext_xtal_mux
 #define clk_fin_dpll clk_ext_xtal_mux
@@ -29,6 +31,8 @@ extern struct clk clk_xusbxti;
 extern struct clk clk_48m;
 extern struct clk s5p_clk_27m;
 extern struct clk clk_fout_apll;
+extern struct clk clk_fout_bpll;
+extern struct clk clk_fout_cpll;
 extern struct clk clk_fout_mpll;
 extern struct clk clk_fout_epll;
 extern struct clk clk_fout_dpll;
@@ -37,6 +41,8 @@ extern struct clk clk_arm;
 extern struct clk clk_vpll;
 
 extern struct clksrc_sources clk_src_apll;
+extern struct clksrc_sources clk_src_bpll;
+extern struct clksrc_sources clk_src_cpll;
 extern struct clksrc_sources clk_src_mpll;
 extern struct clksrc_sources clk_src_epll;
 extern struct clksrc_sources clk_src_dpll;
index f82f888b91a95bb0a238975b4c575408728eb1e9..317e246ffc5604e1c0712054b90c5da23654a6da 100644 (file)
@@ -40,6 +40,7 @@ enum clk_types {
  * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI
  * @max_width: The maximum number of data bits supported.
  * @host_caps: Standard MMC host capabilities bit field.
+ * @host_caps2: The second standard MMC host capabilities bit field.
  * @cd_type: Type of Card Detection method (see cd_types enum above)
  * @clk_type: Type of clock divider method (see clk_types enum above)
  * @ext_cd_init: Initialize external card detect subsystem. Called on
@@ -63,6 +64,7 @@ enum clk_types {
 struct s3c_sdhci_platdata {
        unsigned int    max_width;
        unsigned int    host_caps;
+       unsigned int    host_caps2;
        unsigned int    pm_caps;
        enum cd_types   cd_type;
        enum clk_types  clk_type;
index a22a4f2eea9440c45ebc362c243297d44df677e7..c9e3667cb2b15ef142c3766de06cf519131dedf1 100644 (file)
@@ -26,4 +26,9 @@ enum s3c_hsotg_dmamode {
 struct s3c_hsotg_plat {
        enum s3c_hsotg_dmamode  dma;
        unsigned int            is_osc : 1;
+
+       int (*phy_init)(struct platform_device *pdev, int type);
+       int (*phy_exit)(struct platform_device *pdev, int type);
 };
+
+extern void s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd);
index ee48e12a1e7216ba356e5e160b650f6332904f3d..7e068d182c3ddbb8b0bd50f5b84e490742c296df 100644 (file)
@@ -37,7 +37,9 @@ static void arch_detect_cpu(void);
 /* how many bytes we allow into the FIFO at a time in FIFO mode */
 #define FIFO_MAX        (14)
 
+#ifdef S3C_PA_UART
 #define uart_base S3C_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT)
+#endif
 
 static __inline__ void
 uart_wr(unsigned int reg, unsigned int val)
index 51583cd301645483f110622ef2fc8dff362bf90d..f980cf3d2baa6166fa82eb420c2b1f6d7a025716 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/io.h>
 
 #include <mach/map.h>
+#include <plat/cpu.h>
 #include <plat/irq-vic-timer.h>
 #include <plat/regs-timer.h>
 
@@ -57,6 +58,21 @@ void __init s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq)
        struct irq_chip_type *ct;
        unsigned int i;
 
+#ifdef CONFIG_ARCH_EXYNOS
+       if (soc_is_exynos5250()) {
+               pirq[0] = EXYNOS5_IRQ_TIMER0_VIC;
+               pirq[1] = EXYNOS5_IRQ_TIMER1_VIC;
+               pirq[2] = EXYNOS5_IRQ_TIMER2_VIC;
+               pirq[3] = EXYNOS5_IRQ_TIMER3_VIC;
+               pirq[4] = EXYNOS5_IRQ_TIMER4_VIC;
+       } else {
+               pirq[0] = EXYNOS4_IRQ_TIMER0_VIC;
+               pirq[1] = EXYNOS4_IRQ_TIMER1_VIC;
+               pirq[2] = EXYNOS4_IRQ_TIMER2_VIC;
+               pirq[3] = EXYNOS4_IRQ_TIMER3_VIC;
+               pirq[4] = EXYNOS4_IRQ_TIMER4_VIC;
+       }
+#endif
        s3c_tgc = irq_alloc_generic_chip("s3c-timer", 1, timer_irq,
                                         S3C64XX_TINT_CSTAT, handle_level_irq);
 
index 0f707184eae0b0d07cb7cecc2e3d5464182ee4ce..fa78aa710ed1dc0592dc47effd416bc95fd6a1d8 100644 (file)
@@ -53,6 +53,8 @@ void s3c_sdhci_set_platdata(struct s3c_sdhci_platdata *pd,
                set->cfg_gpio = pd->cfg_gpio;
        if (pd->host_caps)
                set->host_caps |= pd->host_caps;
+       if (pd->host_caps2)
+               set->host_caps2 |= pd->host_caps2;
        if (pd->pm_caps)
                set->pm_caps |= pd->pm_caps;
        if (pd->clk_type)
index 69714db47c33395e286027f285aacc10bffbbf42..a5cb1945bdcc7ec637f288bd65096e5a77ae12f7 100644 (file)
@@ -1,5 +1,4 @@
 obj-y  := clock.o
-obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
 obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o
 obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o
 obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o
diff --git a/arch/arm/plat-versatile/localtimer.c b/arch/arm/plat-versatile/localtimer.c
deleted file mode 100644 (file)
index 0fb3961..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *  linux/arch/arm/plat-versatile/localtimer.c
- *
- *  Copyright (C) 2002 ARM Ltd.
- *  All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/clockchips.h>
-
-#include <asm/smp_twd.h>
-#include <asm/localtimer.h>
-#include <mach/irqs.h>
-
-/*
- * Setup the local clock events for a CPU.
- */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-       evt->irq = IRQ_LOCALTIMER;
-       twd_timer_setup(evt);
-       return 0;
-}
index 7c756fb189f713f3fd9d0b06de43530cb60833c1..afeae8978a8d193f31c276c7963b006029be3810 100644 (file)
@@ -97,6 +97,7 @@ static struct atmel_nand_data atngw100mkii_nand_data __initdata = {
        .rdy_pin        = GPIO_PIN_PB(28),
        .enable_pin     = GPIO_PIN_PE(23),
        .bus_width_16   = true,
+       .ecc_mode       = NAND_ECC_SOFT,
        .parts          = nand_partitions,
        .num_parts      = ARRAY_SIZE(nand_partitions),
 };
index c56ddac85d615ba7acdeac3cc5fc67fa925898b3..dc5263321480edf35264d7fb0e0ac65da679823f 100644 (file)
@@ -95,6 +95,7 @@ static struct atmel_nand_data atstk1006_nand_data __initdata = {
        .ale            = 22,
        .rdy_pin        = GPIO_PIN_PB(30),
        .enable_pin     = GPIO_PIN_PB(29),
+       .ecc_mode       = NAND_ECC_SOFT,
        .parts          = nand_partitions,
        .num_parts      = ARRAY_SIZE(num_partitions),
 };
index 402a7bb726696b4091e15a4e367004e634295859..889c544688ca020c4d99f1b3e5d989c8f002308d 100644 (file)
@@ -1055,8 +1055,6 @@ struct platform_device *__init at32_add_device_usart(unsigned int id)
        return at32_usarts[id];
 }
 
-struct platform_device *atmel_default_console_device;
-
 void __init at32_setup_serial_console(unsigned int usart_id)
 {
        atmel_default_console_device = at32_usarts[usart_id];
index 67b111ce332ddf02bc32afb9eacd66869a2e7a92..71733866cb4f21c308d5e926b59d261576666741 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/types.h>
 #include <linux/serial.h>
 #include <linux/platform_data/macb.h>
+#include <linux/platform_data/atmel_nand.h>
 
 #define GPIO_PIN_NONE  (-1)
 
@@ -116,18 +117,6 @@ struct platform_device *
 at32_add_device_cf(unsigned int id, unsigned int extint,
                struct cf_platform_data *data);
 
-/* NAND / SmartMedia */
-struct atmel_nand_data {
-       int     enable_pin;     /* chip enable */
-       int     det_pin;        /* card detect */
-       int     rdy_pin;        /* ready/busy */
-       u8      rdy_pin_active_low;     /* rdy_pin value is inverted */
-       u8      ale;            /* address line number connected to ALE */
-       u8      cle;            /* address line number connected to CLE */
-       u8      bus_width_16;   /* buswidth is 16 bit */
-       struct mtd_partition *parts;
-       unsigned int    num_parts;
-};
 struct platform_device *
 at32_add_device_nand(unsigned int id, struct atmel_nand_data *data);
 
index 8181293115e427b1087c95a3b56f041437fa1ced..16a24b14146c7ee7e0ffb41a43e6369c64ea2700 100644 (file)
@@ -30,9 +30,6 @@
 #define cpu_is_at91sam9261()   (0)
 #define cpu_is_at91sam9263()   (0)
 #define cpu_is_at91sam9rl()    (0)
-#define cpu_is_at91cap9()      (0)
-#define cpu_is_at91cap9_revB() (0)
-#define cpu_is_at91cap9_revC() (0)
 #define cpu_is_at91sam9g10()   (0)
 #define cpu_is_at91sam9g20()   (0)
 #define cpu_is_at91sam9g45()   (0)
index 11060fa87da35c304df036bfe968fe66556851cd..ac22dc7f4cab0ffa882182103fe6c0ccf1ad6963 100644 (file)
@@ -1,6 +1,7 @@
 config MICROBLAZE
        def_bool y
        select HAVE_MEMBLOCK
+       select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_FUNCTION_TRACER
        select HAVE_FUNCTION_TRACE_MCOUNT_TEST
        select HAVE_FUNCTION_GRAPH_TRACER
@@ -28,6 +29,12 @@ config SWAP
 config RWSEM_GENERIC_SPINLOCK
        def_bool y
 
+config ZONE_DMA
+       def_bool y
+
+config ARCH_POPULATES_NODE_MAP
+       def_bool y
+
 config RWSEM_XCHGADD_ALGORITHM
        bool
 
@@ -153,20 +160,18 @@ config XILINX_UNCACHED_SHADOW
          The feature requires the design to define the RAM memory controller
          window to be twice as large as the actual physical memory.
 
-config HIGHMEM_START_BOOL
-       bool "Set high memory pool address"
-       depends on ADVANCED_OPTIONS && HIGHMEM
+config HIGHMEM
+       bool "High memory support"
+       depends on MMU
        help
-         This option allows you to set the base address of the kernel virtual
-         area used to map high memory pages.  This can be useful in
-         optimizing the layout of kernel virtual memory.
+         The address space of Microblaze processors is only 4 Gigabytes large
+         and it has to accommodate user address space, kernel address
+         space as well as some memory mapped IO. That means that, if you
+         have a large amount of physical memory and/or IO, not all of the
+         memory can be "permanently mapped" by the kernel. The physical
+         memory that is not permanently mapped is called "high memory".
 
-         Say N here unless you know what you are doing.
-
-config HIGHMEM_START
-       hex "Virtual start address of high memory pool" if HIGHMEM_START_BOOL
-       depends on MMU
-       default "0xfe000000"
+         If unsure, say n.
 
 config LOWMEM_SIZE_BOOL
        bool "Set maximum low memory"
@@ -255,6 +260,10 @@ config MICROBLAZE_32K_PAGES
 
 endchoice
 
+config KERNEL_PAD
+       hex "Kernel PAD for unpacking" if ADVANCED_OPTIONS
+       default "0x80000" if MMU
+
 endmenu
 
 source "mm/Kconfig"
index 0c796cf8158629abf23adb530c17ba2a8ceb9be5..34940c828def82fc33d71e16827338698f8cd3e6 100644 (file)
@@ -8,7 +8,7 @@ obj-y += linked_dtb.o
 
 targets := linux.bin linux.bin.gz simpleImage.%
 
-OBJCOPYFLAGS := -O binary
+OBJCOPYFLAGS := -R .note -R .comment -R .note.gnu.build-id -O binary
 
 # Ensure system.dtb exists
 $(obj)/linked_dtb.o: $(obj)/system.dtb
diff --git a/arch/microblaze/include/asm/fixmap.h b/arch/microblaze/include/asm/fixmap.h
new file mode 100644 (file)
index 0000000..f2b312e
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * fixmap.h: compile-time virtual memory allocation
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998 Ingo Molnar
+ *
+ * Copyright 2008 Freescale Semiconductor Inc.
+ *   Port to powerpc added by Kumar Gala
+ *
+ * Copyright 2011 Michal Simek <monstr@monstr.eu>
+ * Copyright 2011 PetaLogix Qld Pty Ltd
+ *   Port to Microblaze
+ */
+
+#ifndef _ASM_FIXMAP_H
+#define _ASM_FIXMAP_H
+
+#ifndef __ASSEMBLY__
+#include <linux/kernel.h>
+#include <asm/page.h>
+#ifdef CONFIG_HIGHMEM
+#include <linux/threads.h>
+#include <asm/kmap_types.h>
+#endif
+
+#define FIXADDR_TOP    ((unsigned long)(-PAGE_SIZE))
+
+/*
+ * Here we define all the compile-time 'special' virtual
+ * addresses. The point is to have a constant address at
+ * compile time, but to set the physical address only
+ * in the boot process. We allocate these special addresses
+ * from the end of virtual memory (0xfffff000) backwards.
+ * Also this lets us do fail-safe vmalloc(), we
+ * can guarantee that these special addresses and
+ * vmalloc()-ed addresses never overlap.
+ *
+ * these 'compile-time allocated' memory buffers are
+ * fixed-size 4k pages. (or larger if used with an increment
+ * highger than 1) use fixmap_set(idx,phys) to associate
+ * physical memory with fixmap indices.
+ *
+ * TLB entries of such buffers will not be flushed across
+ * task switches.
+ */
+enum fixed_addresses {
+       FIX_HOLE,
+#ifdef CONFIG_HIGHMEM
+       FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
+       FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * num_possible_cpus()) - 1,
+#endif
+       __end_of_fixed_addresses
+};
+
+extern void __set_fixmap(enum fixed_addresses idx,
+                                       phys_addr_t phys, pgprot_t flags);
+
+#define set_fixmap(idx, phys) \
+               __set_fixmap(idx, phys, PAGE_KERNEL)
+/*
+ * Some hardware wants to get fixmapped without caching.
+ */
+#define set_fixmap_nocache(idx, phys) \
+               __set_fixmap(idx, phys, PAGE_KERNEL_CI)
+
+#define clear_fixmap(idx) \
+               __set_fixmap(idx, 0, __pgprot(0))
+
+#define __FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
+#define FIXADDR_START          (FIXADDR_TOP - __FIXADDR_SIZE)
+
+#define __fix_to_virt(x)       (FIXADDR_TOP - ((x) << PAGE_SHIFT))
+#define __virt_to_fix(x)       ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
+
+extern void __this_fixmap_does_not_exist(void);
+
+/*
+ * 'index to address' translation. If anyone tries to use the idx
+ * directly without tranlation, we catch the bug with a NULL-deference
+ * kernel oops. Illegal ranges of incoming indices are caught too.
+ */
+static __always_inline unsigned long fix_to_virt(const unsigned int idx)
+{
+       /*
+        * this branch gets completely eliminated after inlining,
+        * except when someone tries to use fixaddr indices in an
+        * illegal way. (such as mixing up address types or using
+        * out-of-range indices).
+        *
+        * If it doesn't get removed, the linker will complain
+        * loudly with a reasonably clear error message..
+        */
+       if (idx >= __end_of_fixed_addresses)
+               __this_fixmap_does_not_exist();
+
+       return __fix_to_virt(idx);
+}
+
+static inline unsigned long virt_to_fix(const unsigned long vaddr)
+{
+       BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
+       return __virt_to_fix(vaddr);
+}
+
+#endif /* !__ASSEMBLY__ */
+#endif
diff --git a/arch/microblaze/include/asm/highmem.h b/arch/microblaze/include/asm/highmem.h
new file mode 100644 (file)
index 0000000..2446a73
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * highmem.h: virtual kernel memory mappings for high memory
+ *
+ * Used in CONFIG_HIGHMEM systems for memory pages which
+ * are not addressable by direct kernel virtual addresses.
+ *
+ * Copyright (C) 1999 Gerhard Wichert, Siemens AG
+ *                   Gerhard.Wichert@pdb.siemens.de
+ *
+ *
+ * Redesigned the x86 32-bit VM architecture to deal with
+ * up to 16 Terabyte physical memory. With current x86 CPUs
+ * we now support up to 64 Gigabytes physical RAM.
+ *
+ * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
+ */
+#ifndef _ASM_HIGHMEM_H
+#define _ASM_HIGHMEM_H
+
+#ifdef __KERNEL__
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/uaccess.h>
+#include <asm/fixmap.h>
+
+extern pte_t *kmap_pte;
+extern pgprot_t kmap_prot;
+extern pte_t *pkmap_page_table;
+
+/*
+ * Right now we initialize only a single pte table. It can be extended
+ * easily, subsequent pte tables have to be allocated in one physical
+ * chunk of RAM.
+ */
+/*
+ * We use one full pte table with 4K pages. And with 16K/64K/256K pages pte
+ * table covers enough memory (32MB/512MB/2GB resp.), so that both FIXMAP
+ * and PKMAP can be placed in a single pte table. We use 512 pages for PKMAP
+ * in case of 16K/64K/256K page sizes.
+ */
+
+#define PKMAP_ORDER    PTE_SHIFT
+#define LAST_PKMAP     (1 << PKMAP_ORDER)
+
+#define PKMAP_BASE     ((FIXADDR_START - PAGE_SIZE * (LAST_PKMAP + 1)) \
+                                                               & PMD_MASK)
+
+#define LAST_PKMAP_MASK        (LAST_PKMAP - 1)
+#define PKMAP_NR(virt)  ((virt - PKMAP_BASE) >> PAGE_SHIFT)
+#define PKMAP_ADDR(nr)  (PKMAP_BASE + ((nr) << PAGE_SHIFT))
+
+extern void *kmap_high(struct page *page);
+extern void kunmap_high(struct page *page);
+extern void *kmap_atomic_prot(struct page *page, pgprot_t prot);
+extern void __kunmap_atomic(void *kvaddr);
+
+static inline void *kmap(struct page *page)
+{
+       might_sleep();
+       if (!PageHighMem(page))
+               return page_address(page);
+       return kmap_high(page);
+}
+
+static inline void kunmap(struct page *page)
+{
+       BUG_ON(in_interrupt());
+       if (!PageHighMem(page))
+               return;
+       kunmap_high(page);
+}
+
+static inline void *__kmap_atomic(struct page *page)
+{
+       return kmap_atomic_prot(page, kmap_prot);
+}
+
+static inline struct page *kmap_atomic_to_page(void *ptr)
+{
+       unsigned long idx, vaddr = (unsigned long) ptr;
+       pte_t *pte;
+
+       if (vaddr < FIXADDR_START)
+               return virt_to_page(ptr);
+
+       idx = virt_to_fix(vaddr);
+       pte = kmap_pte - (idx - FIX_KMAP_BEGIN);
+       return pte_page(*pte);
+}
+
+#define flush_cache_kmaps()    { flush_icache(); flush_dcache(); }
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_HIGHMEM_H */
index 8d6a654ceffb1b408532a27170d40909526aa157..1f9edddf7f4b206917a6083fa92427fb51e1f729 100644 (file)
@@ -56,6 +56,12 @@ typedef struct _SEGREG {
 
 extern void _tlbie(unsigned long va);  /* invalidate a TLB entry */
 extern void _tlbia(void);              /* invalidate all TLB entries */
+
+/*
+ * tlb_skip size stores actual number skipped TLBs from TLB0 - every directy TLB
+ * mapping has to increase tlb_skip size.
+ */
+extern u32 tlb_skip;
 #   endif /* __ASSEMBLY__ */
 
 /*
@@ -69,6 +75,12 @@ extern void _tlbia(void);            /* invalidate all TLB entries */
 
 #  define MICROBLAZE_TLB_SIZE 64
 
+/* For cases when you want to skip some TLB entries */
+#  define MICROBLAZE_TLB_SKIP 0
+
+/* Use the last TLB for temporary access to LMB */
+#  define MICROBLAZE_LMB_TLB_ID 63
+
 /*
  * TLB entries are defined by a "high" tag portion and a "low" data
  * portion. The data portion is 32-bits.
index a25e6b5e2ad454ec08020b3307ed02fbd89991b6..352cc2352bd5109982a879e3571d9b541d6f46a6 100644 (file)
@@ -135,8 +135,8 @@ extern unsigned long min_low_pfn;
 extern unsigned long max_pfn;
 
 extern unsigned long memory_start;
-extern unsigned long memory_end;
 extern unsigned long memory_size;
+extern unsigned long lowmem_size;
 
 extern int page_is_ram(unsigned long pfn);
 
index 44dc67aa02773d577ab606d04109763956512432..3ef7b9cafecaacea1722bf00dc680290bc97d427 100644 (file)
@@ -94,8 +94,7 @@ static inline pte_t pte_mkspecial(pte_t pte)  { return pte; }
 /* Start and end of the vmalloc area. */
 /* Make sure to map the vmalloc area above the pinned kernel memory area
    of 32Mb.  */
-#define VMALLOC_START  (CONFIG_KERNEL_START + \
-                               max(32 * 1024 * 1024UL, memory_size))
+#define VMALLOC_START  (CONFIG_KERNEL_START + CONFIG_LOWMEM_SIZE)
 #define VMALLOC_END    ioremap_bot
 
 #endif /* __ASSEMBLY__ */
index 6c72ed7eba9854c5b003555214d0c1376a544684..9f195c094731b88412fb6981c54d7e1ba724d1f6 100644 (file)
@@ -39,7 +39,8 @@ extern void of_platform_reset_gpio_probe(void);
 void time_init(void);
 void init_IRQ(void);
 void machine_early_init(const char *cmdline, unsigned int ram,
-                       unsigned int fdt, unsigned int msr);
+               unsigned int fdt, unsigned int msr, unsigned int tlb0,
+               unsigned int tlb1);
 
 void machine_restart(char *cmd);
 void machine_shutdown(void);
index 5a433cbaafb3296f1c9df2239e9b4ed513b95418..01228d2b135133f32478c1fd3a2232fc84e06524 100644 (file)
@@ -83,6 +83,7 @@ void default_idle(void);
 void free_init_pages(char *what, unsigned long begin, unsigned long end);
 void free_initmem(void);
 extern char *klimit;
+extern unsigned long kernel_tlb;
 extern void ret_from_fork(void);
 
 extern void *alloc_maybe_bootmem(size_t size, gfp_t mask);
index 072b0077abf95a4ae9494c47900913cfd79ccd71..ef25f7538d4a04090180c1062b5d1c965d06156e 100644 (file)
@@ -80,7 +80,7 @@ extern unsigned long search_exception_table(unsigned long);
 static inline int ___range_ok(unsigned long addr, unsigned long size)
 {
        return ((addr < memory_start) ||
-               ((addr + size) > memory_end));
+               ((addr + size - 1) > (memory_start + memory_size - 1)));
 }
 
 #define __range_ok(addr, size) \
index 54194b28574af687f32734a0c0a53452bcc5caba..eab6abf5652e4d2e8bf97c3ff7181f1282f8063e 100644 (file)
@@ -35,6 +35,8 @@ const struct cpu_ver_key cpu_ver_lookup[] = {
        {"8.00.b", 0x13},
        {"8.10.a", 0x14},
        {"8.20.a", 0x15},
+       {"8.20.b", 0x16},
+       {"8.30.a", 0x17},
        {NULL, 0},
 };
 
index 8356e47631c4313199bb4487068ccd8ccf6635ac..ec485876d0d0ec3ca14b005325320fd5c154eb59 100644 (file)
@@ -171,10 +171,24 @@ void __init remap_early_printk(void)
 {
        if (!early_console_initialized || !early_console)
                return;
-       printk(KERN_INFO "early_printk_console remaping from 0x%x to ",
+       printk(KERN_INFO "early_printk_console remapping from 0x%x to ",
                                                                base_addr);
        base_addr = (u32) ioremap(base_addr, PAGE_SIZE);
        printk(KERN_CONT "0x%x\n", base_addr);
+
+       /*
+        * Early console is on the top of skipped TLB entries
+        * decrease tlb_skip size ensure that hardcoded TLB entry will be
+        * used by generic algorithm
+        * FIXME check if early console mapping is on the top by rereading
+        * TLB entry and compare baseaddr
+        *  mts  rtlbx, (tlb_skip - 1)
+        *  nop
+        *  mfs  rX, rtlblo
+        *  nop
+        *  cmp rX, orig_base_addr
+        */
+       tlb_skip -= 1;
 }
 
 void __init disable_early_printk(void)
index 77320b8fc16a8c2229192343b3b527613b3a3650..98b17f9f904b5bdc2569ecf8b6040f64d210178e 100644 (file)
@@ -63,9 +63,7 @@ ENTRY(_start)
 real_start:
 #endif
 
-       mfs     r1, rmsr
-       andi    r1, r1, ~2
-       mts     rmsr, r1
+       mts     rmsr, r0
 /*
  * According to Xilinx, msrclr instruction behaves like 'mfs rX,rpc'
  * if the msrclr instruction is not enabled. We use this to detect
@@ -73,6 +71,7 @@ real_start:
  * r8 == 0 - msr instructions are implemented
  * r8 != 0 - msr instructions are not implemented
  */
+       mfs     r1, rmsr
        msrclr  r8, 0 /* clear nothing - just read msr for test */
        cmpu    r8, r8, r1 /* r1 must contain msr reg content */
 
@@ -96,7 +95,7 @@ big_endian:
 _prepare_copy_fdt:
        or      r11, r0, r0 /* incremment */
        ori     r4, r0, TOPHYS(_fdt_start)
-       ori     r3, r0, (0x4000 - 4)
+       ori     r3, r0, (0x8000 - 4)
 _copy_fdt:
        lw      r12, r7, r11 /* r12 = r7 + r11 */
        sw      r12, r4, r11 /* addr[r4 + r11] = r12 */
@@ -150,6 +149,7 @@ _copy_bram:
 _invalidate:
        mts     rtlbx, r3
        mts     rtlbhi, r0                      /* flush: ensure V is clear   */
+       mts     rtlblo, r0
        bgtid   r3, _invalidate         /* loop for all entries       */
        addik   r3, r3, -1
        /* sync */
@@ -169,6 +169,53 @@ _invalidate:
        addik   r3,r0, CONFIG_KERNEL_START /* Load the kernel virtual address */
        tophys(r4,r3)                   /* Load the kernel physical address */
 
+       /* start to do TLB calculation */
+       addik   r12, r0, _end
+       rsub    r12, r3, r12
+       addik   r12, r12, CONFIG_KERNEL_PAD /* that's the pad */
+
+       or r9, r0, r0 /* TLB0 = 0 */
+       or r10, r0, r0 /* TLB1 = 0 */
+
+       addik   r11, r12, -0x1000000
+       bgei    r11, GT16 /* size is greater than 16MB */
+       addik   r11, r12, -0x0800000
+       bgei    r11, GT8 /* size is greater than 8MB */
+       addik   r11, r12, -0x0400000
+       bgei    r11, GT4 /* size is greater than 4MB */
+       /* size is less than 4MB */
+       addik   r11, r12, -0x0200000
+       bgei    r11, GT2 /* size is greater than 2MB */
+       addik   r9, r0, 0x0100000 /* TLB0 must be 1MB */
+       addik   r11, r12, -0x0100000
+       bgei    r11, GT1 /* size is greater than 1MB */
+       /* TLB1 is 0 which is setup above */
+       bri tlb_end
+GT4: /* r11 contains the rest - will be either 1 or 4 */
+       ori r9, r0, 0x400000 /* TLB0 is 4MB */
+       bri TLB1
+GT16: /* TLB0 is 16MB */
+       addik   r9, r0, 0x1000000 /* means TLB0 is 16MB */
+TLB1:
+       /* must be used r2 because of substract if failed */
+       addik   r2, r11, -0x0400000
+       bgei    r2, GT20 /* size is greater than 16MB */
+       /* size is >16MB and <20MB */
+       addik   r11, r11, -0x0100000
+       bgei    r11, GT17 /* size is greater than 17MB */
+       /* kernel is >16MB and < 17MB */
+GT1:
+       addik   r10, r0, 0x0100000 /* means TLB1 is 1MB */
+       bri tlb_end
+GT2: /* TLB0 is 0 and TLB1 will be 4MB */
+GT17: /* TLB1 is 4MB - kernel size <20MB */
+       addik   r10, r0, 0x0400000 /* means TLB1 is 4MB */
+       bri tlb_end
+GT8: /* TLB0 is still zero that's why I can use only TLB1 */
+GT20: /* TLB1 is 16MB - kernel size >20MB */
+       addik   r10, r0, 0x1000000 /* means TLB1 is 16MB */
+tlb_end:
+
        /*
         * Configure and load two entries into TLB slots 0 and 1.
         * In case we are pinning TLBs, these are reserved in by the
@@ -178,28 +225,81 @@ _invalidate:
        andi    r4,r4,0xfffffc00        /* Mask off the real page number */
        ori     r4,r4,(TLB_WR | TLB_EX) /* Set the write and execute bits */
 
+       /*
+        * TLB0 is always used - check if is not zero (r9 stores TLB0 value)
+        * if is use TLB1 value and clear it (r10 stores TLB1 value)
+        */
+       bnei    r9, tlb0_not_zero
+       add     r9, r10, r0
+       add     r10, r0, r0
+tlb0_not_zero:
+
+       /* look at the code below */
+       ori     r30, r0, 0x200
+       andi    r29, r9, 0x100000
+       bneid   r29, 1f
+       addik   r30, r30, 0x80
+       andi    r29, r9, 0x400000
+       bneid   r29, 1f
+       addik   r30, r30, 0x80
+       andi    r29, r9, 0x1000000
+       bneid   r29, 1f
+       addik   r30, r30, 0x80
+1:
        andi    r3,r3,0xfffffc00        /* Mask off the effective page number */
-       ori     r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M))
+       ori     r3,r3,(TLB_VALID)
+       or      r3, r3, r30
 
-       mts     rtlbx,r0                /* TLB slow 0 */
+       /* Load tlb_skip size value which is index to first unused TLB entry */
+       lwi     r11, r0, TOPHYS(tlb_skip)
+       mts     rtlbx,r11               /* TLB slow 0 */
 
        mts     rtlblo,r4               /* Load the data portion of the entry */
        mts     rtlbhi,r3               /* Load the tag portion of the entry */
 
-       addik   r4, r4, 0x01000000      /* Map next 16 M entries */
-       addik   r3, r3, 0x01000000
+       /* Increase tlb_skip size */
+       addik   r11, r11, 1
+       swi     r11, r0, TOPHYS(tlb_skip)
+
+       /* TLB1 can be zeroes that's why we not setup it */
+       beqi    r10, jump_over2
+
+       /* look at the code below */
+       ori     r30, r0, 0x200
+       andi    r29, r10, 0x100000
+       bneid   r29, 1f
+       addik   r30, r30, 0x80
+       andi    r29, r10, 0x400000
+       bneid   r29, 1f
+       addik   r30, r30, 0x80
+       andi    r29, r10, 0x1000000
+       bneid   r29, 1f
+       addik   r30, r30, 0x80
+1:
+       addk    r4, r4, r9      /* previous addr + TLB0 size */
+       addk    r3, r3, r9
 
-       ori     r6,r0,1                 /* TLB slot 1 */
-       mts     rtlbx,r6
+       andi    r3,r3,0xfffffc00        /* Mask off the effective page number */
+       ori     r3,r3,(TLB_VALID)
+       or      r3, r3, r30
+
+       lwi     r11, r0, TOPHYS(tlb_skip)
+       mts     rtlbx, r11              /* r11 is used from TLB0 */
 
        mts     rtlblo,r4               /* Load the data portion of the entry */
        mts     rtlbhi,r3               /* Load the tag portion of the entry */
 
+       /* Increase tlb_skip size */
+       addik   r11, r11, 1
+       swi     r11, r0, TOPHYS(tlb_skip)
+
+jump_over2:
        /*
         * Load a TLB entry for LMB, since we need access to
         * the exception vectors, using a 4k real==virtual mapping.
         */
-       ori     r6,r0,3                 /* TLB slot 3 */
+       /* Use temporary TLB_ID for LMB - clear this temporary mapping later */
+       ori     r6, r0, MICROBLAZE_LMB_TLB_ID
        mts     rtlbx,r6
 
        ori     r4,r0,(TLB_WR | TLB_EX)
@@ -238,8 +338,8 @@ start_here:
         * Please see $(ARCH)/mach-$(SUBARCH)/setup.c for
         * the function.
         */
-       addik   r9, r0, machine_early_init
-       brald   r15, r9
+       addik   r11, r0, machine_early_init
+       brald   r15, r11
        nop
 
 #ifndef CONFIG_MMU
@@ -268,8 +368,7 @@ start_here:
 
        /* Load up the kernel context */
 kernel_load_context:
-       # Keep entry 0 and 1 valid. Entry 3 mapped to LMB can go away.
-       ori     r5,r0,3
+       ori     r5, r0, MICROBLAZE_LMB_TLB_ID
        mts     rtlbx,r5
        nop
        mts     rtlbhi,r0
index e62be83796044876d6708a8f960ce554c0dfbecc..aa510f450ac61dad55929fcc8a0056a1a09e8ee8 100644 (file)
@@ -820,19 +820,26 @@ ex_handler_done:
  *     Upon exit, we reload everything and RFI.
  * A common place to load the TLB.
  */
+.section .data
+.align 4
+.global tlb_skip
+       tlb_skip:
+               .long   MICROBLAZE_TLB_SKIP
        tlb_index:
-               .long   1 /* MS: storing last used tlb index */
+               /* MS: storing last used tlb index */
+               .long   MICROBLAZE_TLB_SIZE/2
+.previous
        finish_tlb_load:
                /* MS: load the last used TLB index. */
                lwi     r5, r0, TOPHYS(tlb_index)
                addik   r5, r5, 1 /* MS: inc tlb_index -> use next one */
 
 /* MS: FIXME this is potential fault, because this is mask not count */
-               andi    r5, r5, (MICROBLAZE_TLB_SIZE-1)
+               andi    r5, r5, MICROBLAZE_TLB_SIZE - 1
                ori     r6, r0, 1
                cmp     r31, r5, r6
                blti    r31, ex12
-               addik   r5, r6, 1
+               lwi     r5, r0, TOPHYS(tlb_skip)
        ex12:
                /* MS: save back current TLB index */
                swi     r5, r0, TOPHYS(tlb_index)
index ad120672cee5779eaf91e1f6fb48ff89ca44e3a4..6c54d4dcdec311e0f6f5fce32a6635cf0095883f 100644 (file)
@@ -151,8 +151,8 @@ void __init init_IRQ(void)
 #ifdef CONFIG_SELFMOD_INTC
        selfmod_function((int *) arr_func, intc_baseaddr);
 #endif
-       printk(KERN_INFO "XPS intc #0 at 0x%08x, num_irq=%d, edge=0x%x\n",
-               intc_baseaddr, nr_irq, intr_mask);
+       printk(KERN_INFO "%s #0 at 0x%08x, num_irq=%d, edge=0x%x\n",
+               intc->name, intc_baseaddr, nr_irq, intr_mask);
 
        /*
         * Disable all external interrupts until they are
index 206da3da361fa305843b1641e8627d0ffa3d3242..1dafddeb8a0b51c0da0d709b1eb13c67420bd80d 100644 (file)
 .type  _tlbia, @function
 .align 4;
 _tlbia:
-       addik   r12, r0, MICROBLAZE_TLB_SIZE - 1 /* flush all entries (63 - 3) */
+       lwi     r12, r0, tlb_skip;
        /* isync */
 _tlbia_1:
        mts     rtlbx, r12
        nop
        mts     rtlbhi, r0 /* flush: ensure V is clear */
        nop
-       addik   r11, r12, -2
+       rsubi   r11, r12, MICROBLAZE_TLB_SIZE - 1
        bneid   r11, _tlbia_1 /* loop for all entries */
-       addik   r12, r12, -1
+       addik   r12, r12, 1
        /* sync */
        rtsd    r15, 8
        nop
@@ -75,7 +75,7 @@ early_console_reg_tlb_alloc:
         * Load a TLB entry for the UART, so that microblaze_progress() can use
         * the UARTs nice and early.  We use a 4k real==virtual mapping.
         */
-       ori     r4, r0, MICROBLAZE_TLB_SIZE - 1
+       lwi     r4, r0, tlb_skip
        mts     rtlbx, r4 /* TLB slot 63 */
 
        or      r4,r5,r0
@@ -89,6 +89,11 @@ early_console_reg_tlb_alloc:
        nop
        mts     rtlbhi,r5 /* Load the tag portion of the entry */
        nop
+
+       lwi     r5, r0, tlb_skip
+       addik   r5, r5, 1
+       swi     r5, r0, tlb_skip
+
        rtsd    r15, 8
        nop
 
index 70e6d0b41ab4ff31688379fe795a1905f5c5599c..9f79fb3bbfa08430d7d07fad8e85cd1e47d88ad8 100644 (file)
@@ -95,8 +95,11 @@ inline unsigned get_romfs_len(unsigned *addr)
 }
 #endif /* CONFIG_MTD_UCLINUX_EBSS */
 
+unsigned long kernel_tlb;
+
 void __init machine_early_init(const char *cmdline, unsigned int ram,
-               unsigned int fdt, unsigned int msr)
+               unsigned int fdt, unsigned int msr, unsigned int tlb0,
+               unsigned int tlb1)
 {
        unsigned long *src, *dst;
        unsigned int offset = 0;
@@ -143,6 +146,12 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
        setup_early_printk(NULL);
 #endif
 
+       /* setup kernel_tlb after BSS cleaning
+        * Maybe worth to move to asm code */
+       kernel_tlb = tlb0 + tlb1;
+       /* printk("TLB1 0x%08x, TLB0 0x%08x, tlb 0x%x\n", tlb0,
+                                                       tlb1, kernel_tlb); */
+
        printk("Ramdisk addr 0x%08x, ", ram);
        if (fdt)
                printk("FDT at 0x%08x\n", fdt);
@@ -197,6 +206,19 @@ static int microblaze_debugfs_init(void)
        return of_debugfs_root == NULL;
 }
 arch_initcall(microblaze_debugfs_init);
+
+static int __init debugfs_tlb(void)
+{
+       struct dentry *d;
+
+       if (!of_debugfs_root)
+               return -ENODEV;
+
+       d = debugfs_create_u32("tlb_skip", S_IRUGO, of_debugfs_root, &tlb_skip);
+       if (!d)
+               return -ENOMEM;
+}
+device_initcall(debugfs_tlb);
 #endif
 
 static int dflt_bus_notify(struct notifier_block *nb,
index 3cb0bf640135c5ced740bc2af6e0b6e819963792..cadfd5608afb8026cc3a6f50c44f0d2dbb590cb3 100644 (file)
@@ -79,7 +79,7 @@ static inline void microblaze_timer0_start_periodic(unsigned long load_val)
         * !PWMA - disable pwm
         * TINT - clear interrupt status
         * ENT- enable timer itself
-        * EINT - enable interrupt
+        * ENIT - enable interrupt
         * !LOAD - clear the bit to let go
         * ARHT - auto reload
         * !CAPT - no external trigger
@@ -274,8 +274,8 @@ void __init time_init(void)
 #ifdef CONFIG_SELFMOD_TIMER
        selfmod_function((int *) arr_func, timer_baseaddr);
 #endif
-       printk(KERN_INFO "XPS timer #0 at 0x%08x, irq=%d\n",
-               timer_baseaddr, irq);
+       printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n",
+               timer->name, timer_baseaddr, irq);
 
        /* If there is clock-frequency property than use it */
        prop = of_get_property(timer, "clock-frequency", NULL);
index ac0e1a5d478248493ba652d8bc53ae56cf9046fd..109e9d86ade4e46051f25c1d375eac1cd9f83224 100644 (file)
@@ -44,7 +44,7 @@ SECTIONS {
        __fdt_blob : AT(ADDR(__fdt_blob) - LOAD_OFFSET) {
                _fdt_start = . ;                /* place for fdt blob */
                *(__fdt_blob) ;                 /* Any link-placed DTB */
-               . = _fdt_start + 0x4000;        /* Pad up to 16kbyte */
+               . = _fdt_start + 0x8000;        /* Pad up to 32kbyte */
                _fdt_end = . ;
        }
 
index 09c49ed872358c1f53f92f8293bde1822829031b..7313bd8acbb7d18c9043818672b873bfc3a4af77 100644 (file)
@@ -5,3 +5,4 @@
 obj-y := consistent.o init.o
 
 obj-$(CONFIG_MMU) += pgtable.o mmu_context.o fault.o
+obj-$(CONFIG_HIGHMEM) += highmem.o
diff --git a/arch/microblaze/mm/highmem.c b/arch/microblaze/mm/highmem.c
new file mode 100644 (file)
index 0000000..7d78838
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * highmem.c: virtual kernel memory mappings for high memory
+ *
+ * PowerPC version, stolen from the i386 version.
+ *
+ * Used in CONFIG_HIGHMEM systems for memory pages which
+ * are not addressable by direct kernel virtual addresses.
+ *
+ * Copyright (C) 1999 Gerhard Wichert, Siemens AG
+ *                   Gerhard.Wichert@pdb.siemens.de
+ *
+ *
+ * Redesigned the x86 32-bit VM architecture to deal with
+ * up to 16 Terrabyte physical memory. With current x86 CPUs
+ * we now support up to 64 Gigabytes physical RAM.
+ *
+ * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
+ *
+ * Reworked for PowerPC by various contributors. Moved from
+ * highmem.h by Benjamin Herrenschmidt (c) 2009 IBM Corp.
+ */
+
+#include <linux/highmem.h>
+#include <linux/module.h>
+
+/*
+ * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap
+ * gives a more generic (and caching) interface. But kmap_atomic can
+ * be used in IRQ contexts, so in some (very limited) cases we need
+ * it.
+ */
+#include <asm/tlbflush.h>
+
+void *kmap_atomic_prot(struct page *page, pgprot_t prot)
+{
+
+       unsigned long vaddr;
+       int idx, type;
+
+       /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
+       pagefault_disable();
+       if (!PageHighMem(page))
+               return page_address(page);
+
+
+       type = kmap_atomic_idx_push();
+       idx = type + KM_TYPE_NR*smp_processor_id();
+       vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+#ifdef CONFIG_DEBUG_HIGHMEM
+       BUG_ON(!pte_none(*(kmap_pte-idx)));
+#endif
+       set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot));
+       local_flush_tlb_page(NULL, vaddr);
+
+       return (void *) vaddr;
+}
+EXPORT_SYMBOL(kmap_atomic_prot);
+
+void __kunmap_atomic(void *kvaddr)
+{
+       unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
+       int type;
+
+       if (vaddr < __fix_to_virt(FIX_KMAP_END)) {
+               pagefault_enable();
+               return;
+       }
+
+       type = kmap_atomic_idx();
+#ifdef CONFIG_DEBUG_HIGHMEM
+       {
+               unsigned int idx;
+
+               idx = type + KM_TYPE_NR * smp_processor_id();
+               BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
+
+               /*
+                * force other mappings to Oops if they'll try to access
+                * this pte without first remap it
+                */
+               pte_clear(&init_mm, vaddr, kmap_pte-idx);
+               local_flush_tlb_page(NULL, vaddr);
+       }
+#endif
+       kmap_atomic_idx_pop();
+       pagefault_enable();
+}
+EXPORT_SYMBOL(__kunmap_atomic);
index 565d193c7ebfd8b307ac3efc8913bda4968dcbcd..ce80823051ba95ad1e1fc148c461fd5e51cf473f 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/pgalloc.h>
 #include <asm/sections.h>
 #include <asm/tlb.h>
+#include <asm/fixmap.h>
 
 /* Use for MMU and noMMU because of PCI generic code */
 int mem_init_done;
@@ -44,9 +45,56 @@ char *klimit = _end;
  */
 unsigned long memory_start;
 EXPORT_SYMBOL(memory_start);
-unsigned long memory_end; /* due to mm/nommu.c */
 unsigned long memory_size;
 EXPORT_SYMBOL(memory_size);
+unsigned long lowmem_size;
+
+#ifdef CONFIG_HIGHMEM
+pte_t *kmap_pte;
+EXPORT_SYMBOL(kmap_pte);
+pgprot_t kmap_prot;
+EXPORT_SYMBOL(kmap_prot);
+
+static inline pte_t *virt_to_kpte(unsigned long vaddr)
+{
+       return pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr),
+                       vaddr), vaddr);
+}
+
+static void __init highmem_init(void)
+{
+       pr_debug("%x\n", (u32)PKMAP_BASE);
+       map_page(PKMAP_BASE, 0, 0);     /* XXX gross */
+       pkmap_page_table = virt_to_kpte(PKMAP_BASE);
+
+       kmap_pte = virt_to_kpte(__fix_to_virt(FIX_KMAP_BEGIN));
+       kmap_prot = PAGE_KERNEL;
+}
+
+static unsigned long highmem_setup(void)
+{
+       unsigned long pfn;
+       unsigned long reservedpages = 0;
+
+       for (pfn = max_low_pfn; pfn < max_pfn; ++pfn) {
+               struct page *page = pfn_to_page(pfn);
+
+               /* FIXME not sure about */
+               if (memblock_is_reserved(pfn << PAGE_SHIFT))
+                       continue;
+               ClearPageReserved(page);
+               init_page_count(page);
+               __free_page(page);
+               totalhigh_pages++;
+               reservedpages++;
+       }
+       totalram_pages += totalhigh_pages;
+       printk(KERN_INFO "High memory: %luk\n",
+                                       totalhigh_pages << (PAGE_SHIFT-10));
+
+       return reservedpages;
+}
+#endif /* CONFIG_HIGHMEM */
 
 /*
  * paging_init() sets up the page tables - in fact we've already done this.
@@ -54,17 +102,28 @@ EXPORT_SYMBOL(memory_size);
 static void __init paging_init(void)
 {
        unsigned long zones_size[MAX_NR_ZONES];
+#ifdef CONFIG_MMU
+       int idx;
+
+       /* Setup fixmaps */
+       for (idx = 0; idx < __end_of_fixed_addresses; idx++)
+               clear_fixmap(idx);
+#endif
 
        /* Clean every zones */
        memset(zones_size, 0, sizeof(zones_size));
 
-       /*
-        * old: we can DMA to/from any address.put all page into ZONE_DMA
-        * We use only ZONE_NORMAL
-        */
-       zones_size[ZONE_NORMAL] = max_mapnr;
+#ifdef CONFIG_HIGHMEM
+       highmem_init();
 
-       free_area_init(zones_size);
+       zones_size[ZONE_DMA] = max_low_pfn;
+       zones_size[ZONE_HIGHMEM] = max_pfn;
+#else
+       zones_size[ZONE_DMA] = max_pfn;
+#endif
+
+       /* We don't have holes in memory map */
+       free_area_init_nodes(zones_size);
 }
 
 void __init setup_memory(void)
@@ -78,32 +137,31 @@ void __init setup_memory(void)
        /* Find main memory where is the kernel */
        for_each_memblock(memory, reg) {
                memory_start = (u32)reg->base;
-               memory_end = (u32) reg->base + reg->size;
+               lowmem_size = reg->size;
                if ((memory_start <= (u32)_text) &&
-                                       ((u32)_text <= memory_end)) {
-                       memory_size = memory_end - memory_start;
+                       ((u32)_text <= (memory_start + lowmem_size - 1))) {
+                       memory_size = lowmem_size;
                        PAGE_OFFSET = memory_start;
-                       printk(KERN_INFO "%s: Main mem: 0x%x-0x%x, "
+                       printk(KERN_INFO "%s: Main mem: 0x%x, "
                                "size 0x%08x\n", __func__, (u32) memory_start,
-                                       (u32) memory_end, (u32) memory_size);
+                                       (u32) memory_size);
                        break;
                }
        }
 
-       if (!memory_start || !memory_end) {
-               panic("%s: Missing memory setting 0x%08x-0x%08x\n",
-                       __func__, (u32) memory_start, (u32) memory_end);
+       if (!memory_start || !memory_size) {
+               panic("%s: Missing memory setting 0x%08x, size=0x%08x\n",
+                       __func__, (u32) memory_start, (u32) memory_size);
        }
 
        /* reservation of region where is the kernel */
        kernel_align_start = PAGE_DOWN((u32)_text);
        /* ALIGN can be remove because _end in vmlinux.lds.S is align */
        kernel_align_size = PAGE_UP((u32)klimit) - kernel_align_start;
-       memblock_reserve(kernel_align_start, kernel_align_size);
-       printk(KERN_INFO "%s: kernel addr=0x%08x-0x%08x size=0x%08x\n",
+       printk(KERN_INFO "%s: kernel addr:0x%08x-0x%08x size=0x%08x\n",
                __func__, kernel_align_start, kernel_align_start
                        + kernel_align_size, kernel_align_size);
-
+       memblock_reserve(kernel_align_start, kernel_align_size);
 #endif
        /*
         * Kernel:
@@ -120,11 +178,13 @@ void __init setup_memory(void)
        min_low_pfn = memory_start >> PAGE_SHIFT; /* minimum for allocation */
        /* RAM is assumed contiguous */
        num_physpages = max_mapnr = memory_size >> PAGE_SHIFT;
-       max_pfn = max_low_pfn = memory_end >> PAGE_SHIFT;
+       max_low_pfn = ((u64)memory_start + (u64)lowmem_size) >> PAGE_SHIFT;
+       max_pfn = ((u64)memory_start + (u64)memory_size) >> PAGE_SHIFT;
 
        printk(KERN_INFO "%s: max_mapnr: %#lx\n", __func__, max_mapnr);
        printk(KERN_INFO "%s: min_low_pfn: %#lx\n", __func__, min_low_pfn);
        printk(KERN_INFO "%s: max_low_pfn: %#lx\n", __func__, max_low_pfn);
+       printk(KERN_INFO "%s: max_pfn: %#lx\n", __func__, max_pfn);
 
        /*
         * Find an area to use for the bootmem bitmap.
@@ -137,15 +197,39 @@ void __init setup_memory(void)
                PFN_UP(TOPHYS((u32)klimit)), min_low_pfn, max_low_pfn);
        memblock_reserve(PFN_UP(TOPHYS((u32)klimit)) << PAGE_SHIFT, map_size);
 
+       /* Add active regions with valid PFNs */
+       for_each_memblock(memory, reg) {
+               unsigned long start_pfn, end_pfn;
+
+               start_pfn = memblock_region_memory_base_pfn(reg);
+               end_pfn = memblock_region_memory_end_pfn(reg);
+               memblock_set_node(start_pfn << PAGE_SHIFT,
+                                       (end_pfn - start_pfn) << PAGE_SHIFT, 0);
+       }
+
        /* free bootmem is whole main memory */
-       free_bootmem(memory_start, memory_size);
+       free_bootmem_with_active_regions(0, max_low_pfn);
 
        /* reserve allocate blocks */
        for_each_memblock(reserved, reg) {
-               pr_debug("reserved - 0x%08x-0x%08x\n",
-                        (u32) reg->base, (u32) reg->size);
-               reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
+               unsigned long top = reg->base + reg->size - 1;
+
+               pr_debug("reserved - 0x%08x-0x%08x, %lx, %lx\n",
+                        (u32) reg->base, (u32) reg->size, top,
+                                               memory_start + lowmem_size - 1);
+
+               if (top <= (memory_start + lowmem_size - 1)) {
+                       reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
+               } else if (reg->base < (memory_start + lowmem_size - 1)) {
+                       unsigned long trunc_size = memory_start + lowmem_size -
+                                                               reg->base;
+                       reserve_bootmem(reg->base, trunc_size, BOOTMEM_DEFAULT);
+               }
        }
+
+       /* XXX need to clip this if using highmem? */
+       sparse_memory_present_with_active_regions(0);
+
 #ifdef CONFIG_MMU
        init_bootmem_done = 1;
 #endif
@@ -190,13 +274,58 @@ void free_initmem(void)
 
 void __init mem_init(void)
 {
-       high_memory = (void *)__va(memory_end);
+       pg_data_t *pgdat;
+       unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize;
+
+       high_memory = (void *)__va(memory_start + lowmem_size - 1);
+
        /* this will put all memory onto the freelists */
        totalram_pages += free_all_bootmem();
 
-       printk(KERN_INFO "Memory: %luk/%luk available\n",
-              nr_free_pages() << (PAGE_SHIFT-10),
-              num_physpages << (PAGE_SHIFT-10));
+       for_each_online_pgdat(pgdat) {
+               unsigned long i;
+               struct page *page;
+
+               for (i = 0; i < pgdat->node_spanned_pages; i++) {
+                       if (!pfn_valid(pgdat->node_start_pfn + i))
+                               continue;
+                       page = pgdat_page_nr(pgdat, i);
+                       if (PageReserved(page))
+                               reservedpages++;
+               }
+       }
+
+#ifdef CONFIG_HIGHMEM
+       reservedpages -= highmem_setup();
+#endif
+
+       codesize = (unsigned long)&_sdata - (unsigned long)&_stext;
+       datasize = (unsigned long)&_edata - (unsigned long)&_sdata;
+       initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin;
+       bsssize = (unsigned long)&__bss_stop - (unsigned long)&__bss_start;
+
+       pr_info("Memory: %luk/%luk available (%luk kernel code, "
+               "%luk reserved, %luk data, %luk bss, %luk init)\n",
+               nr_free_pages() << (PAGE_SHIFT-10),
+               num_physpages << (PAGE_SHIFT-10),
+               codesize >> 10,
+               reservedpages << (PAGE_SHIFT-10),
+               datasize >> 10,
+               bsssize >> 10,
+               initsize >> 10);
+
+#ifdef CONFIG_MMU
+       pr_info("Kernel virtual memory layout:\n");
+       pr_info("  * 0x%08lx..0x%08lx  : fixmap\n", FIXADDR_START, FIXADDR_TOP);
+#ifdef CONFIG_HIGHMEM
+       pr_info("  * 0x%08lx..0x%08lx  : highmem PTEs\n",
+               PKMAP_BASE, PKMAP_ADDR(LAST_PKMAP));
+#endif /* CONFIG_HIGHMEM */
+       pr_info("  * 0x%08lx..0x%08lx  : early ioremap\n",
+               ioremap_bot, ioremap_base);
+       pr_info("  * 0x%08lx..0x%08lx  : vmalloc & ioremap\n",
+               (unsigned long)VMALLOC_START, VMALLOC_END);
+#endif
        mem_init_done = 1;
 }
 
@@ -226,7 +355,6 @@ static void mm_cmdline_setup(void)
                maxmem = memparse(p, &p);
                if (maxmem && memory_size > maxmem) {
                        memory_size = maxmem;
-                       memory_end = memory_start + memory_size;
                        memblock.memory.regions[0].size = memory_size;
                }
        }
@@ -270,15 +398,26 @@ asmlinkage void __init mmu_init(void)
                machine_restart(NULL);
        }
 
-       if ((u32) memblock.memory.regions[0].size < 0x1000000) {
-               printk(KERN_EMERG "Memory must be greater than 16MB\n");
+       if ((u32) memblock.memory.regions[0].size < 0x400000) {
+               printk(KERN_EMERG "Memory must be greater than 4MB\n");
+               machine_restart(NULL);
+       }
+
+       if ((u32) memblock.memory.regions[0].size < kernel_tlb) {
+               printk(KERN_EMERG "Kernel size is greater than memory node\n");
                machine_restart(NULL);
        }
+
        /* Find main memory where the kernel is */
        memory_start = (u32) memblock.memory.regions[0].base;
-       memory_end = (u32) memblock.memory.regions[0].base +
-                               (u32) memblock.memory.regions[0].size;
-       memory_size = memory_end - memory_start;
+       lowmem_size = memory_size = (u32) memblock.memory.regions[0].size;
+
+       if (lowmem_size > CONFIG_LOWMEM_SIZE) {
+               lowmem_size = CONFIG_LOWMEM_SIZE;
+#ifndef CONFIG_HIGHMEM
+               memory_size = lowmem_size;
+#endif
+       }
 
        mm_cmdline_setup(); /* FIXME parse args from command line - not used */
 
@@ -305,15 +444,20 @@ asmlinkage void __init mmu_init(void)
        /* Map in all of RAM starting at CONFIG_KERNEL_START */
        mapin_ram();
 
-#ifdef CONFIG_HIGHMEM_START_BOOL
-       ioremap_base = CONFIG_HIGHMEM_START;
+       /* Extend vmalloc and ioremap area as big as possible */
+#ifdef CONFIG_HIGHMEM
+       ioremap_base = ioremap_bot = PKMAP_BASE;
 #else
-       ioremap_base = 0xfe000000UL;    /* for now, could be 0xfffff000 */
-#endif /* CONFIG_HIGHMEM_START_BOOL */
-       ioremap_bot = ioremap_base;
+       ioremap_base = ioremap_bot = FIXADDR_START;
+#endif
 
        /* Initialize the context management stuff */
        mmu_context_init();
+
+       /* Shortly after that, the entire linear mapping will be available */
+       /* This will also cause that unflatten device tree will be allocated
+        * inside 768MB limit */
+       memblock_set_current_limit(memory_start + lowmem_size - 1);
 }
 
 /* This is only called until mem_init is done. */
@@ -324,11 +468,11 @@ void __init *early_get_page(void)
                p = alloc_bootmem_pages(PAGE_SIZE);
        } else {
                /*
-                * Mem start + 32MB -> here is limit
+                * Mem start + kernel_tlb -> here is limit
                 * because of mem mapping from head.S
                 */
                p = __va(memblock_alloc_base(PAGE_SIZE, PAGE_SIZE,
-                                       memory_start + 0x2000000));
+                                       memory_start + kernel_tlb));
        }
        return p;
 }
index 59bf2335a4ce06a9691c02b6f683036579a1381e..d1c06d07fed867b031aa9c0043661ebf15f0b899 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/io.h>
 #include <asm/mmu.h>
 #include <asm/sections.h>
+#include <asm/fixmap.h>
 
 #define flush_HPTE(X, va, pg)  _tlbie(va)
 
@@ -44,11 +45,6 @@ unsigned long ioremap_base;
 unsigned long ioremap_bot;
 EXPORT_SYMBOL(ioremap_bot);
 
-/* The maximum lowmem defaults to 768Mb, but this can be configured to
- * another value.
- */
-#define MAX_LOW_MEM    CONFIG_LOWMEM_SIZE
-
 #ifndef CONFIG_SMP
 struct pgtable_cache_struct quicklists;
 #endif
@@ -80,7 +76,7 @@ static void __iomem *__ioremap(phys_addr_t addr, unsigned long size,
                !(p >= virt_to_phys((unsigned long)&__bss_stop) &&
                p < virt_to_phys((unsigned long)__bss_stop))) {
                printk(KERN_WARNING "__ioremap(): phys addr "PTE_FMT
-                       " is RAM lr %p\n", (unsigned long)p,
+                       " is RAM lr %pf\n", (unsigned long)p,
                        __builtin_return_address(0));
                return NULL;
        }
@@ -171,7 +167,7 @@ void __init mapin_ram(void)
 
        v = CONFIG_KERNEL_START;
        p = memory_start;
-       for (s = 0; s < memory_size; s += PAGE_SIZE) {
+       for (s = 0; s < lowmem_size; s += PAGE_SIZE) {
                f = _PAGE_PRESENT | _PAGE_ACCESSED |
                                _PAGE_SHARED | _PAGE_HWEXEC;
                if ((char *) v < _stext || (char *) v >= _etext)
@@ -254,3 +250,13 @@ __init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
        }
        return pte;
 }
+
+void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags)
+{
+       unsigned long address = __fix_to_virt(idx);
+
+       if (idx >= __end_of_fixed_addresses)
+               BUG();
+
+       map_page(address, phys, pgprot_val(flags));
+}
index 6d99a5fcc09030114dd8d475e6fe54184fc59814..465d5be1f0f4fd76ddef6fcac7fe301dd0d4c060 100644 (file)
@@ -64,6 +64,7 @@ config ARCH_SUPPORTS_DEBUG_PAGEALLOC
 config S390
        def_bool y
        select USE_GENERIC_SMP_HELPERS if SMP
+       select GENERIC_CPU_DEVICES if !SMP
        select HAVE_SYSCALL_WRAPPERS
        select HAVE_FUNCTION_TRACER
        select HAVE_FUNCTION_TRACE_MCOUNT_TEST
diff --git a/arch/s390/include/asm/cpu_mf.h b/arch/s390/include/asm/cpu_mf.h
new file mode 100644 (file)
index 0000000..e49db5d
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * CPU-measurement facilities
+ *
+ *  Copyright IBM Corp. 2012
+ *  Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
+ *            Jan Glauber <jang@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (version 2 only)
+ * as published by the Free Software Foundation.
+ */
+#ifndef _ASM_S390_CPU_MF_H
+#define _ASM_S390_CPU_MF_H
+
+#define CPU_MF_INT_SF_IAE      (1 << 31)       /* invalid entry address */
+#define CPU_MF_INT_SF_ISE      (1 << 30)       /* incorrect SDBT entry */
+#define CPU_MF_INT_SF_PRA      (1 << 29)       /* program request alert */
+#define CPU_MF_INT_SF_SACA     (1 << 23)       /* sampler auth. change alert */
+#define CPU_MF_INT_SF_LSDA     (1 << 22)       /* loss of sample data alert */
+#define CPU_MF_INT_CF_CACA     (1 <<  7)       /* counter auth. change alert */
+#define CPU_MF_INT_CF_LCDA     (1 <<  6)       /* loss of counter data alert */
+
+#define CPU_MF_INT_CF_MASK     (CPU_MF_INT_CF_CACA|CPU_MF_INT_CF_LCDA)
+#define CPU_MF_INT_SF_MASK     (CPU_MF_INT_SF_IAE|CPU_MF_INT_SF_ISE|   \
+                                CPU_MF_INT_SF_PRA|CPU_MF_INT_SF_SACA|  \
+                                CPU_MF_INT_SF_LSDA)
+
+/* CPU measurement facility support */
+static inline int cpum_cf_avail(void)
+{
+       return MACHINE_HAS_SPP && test_facility(67);
+}
+
+static inline int cpum_sf_avail(void)
+{
+       return MACHINE_HAS_SPP && test_facility(68);
+}
+
+
+struct cpumf_ctr_info {
+       u16   cfvn;
+       u16   auth_ctl;
+       u16   enable_ctl;
+       u16   act_ctl;
+       u16   max_cpu;
+       u16   csvn;
+       u16   max_cg;
+       u16   reserved1;
+       u32   reserved2[12];
+} __packed;
+
+/* Query counter information */
+static inline int qctri(struct cpumf_ctr_info *info)
+{
+       int rc = -EINVAL;
+
+       asm volatile (
+               "0:     .insn   s,0xb28e0000,%1\n"
+               "1:     lhi     %0,0\n"
+               "2:\n"
+               EX_TABLE(1b, 2b)
+               : "+d" (rc), "=Q" (*info));
+       return rc;
+}
+
+/* Load CPU-counter-set controls */
+static inline int lcctl(u64 ctl)
+{
+       int cc;
+
+       asm volatile (
+               "       .insn   s,0xb2840000,%1\n"
+               "       ipm     %0\n"
+               "       srl     %0,28\n"
+               : "=d" (cc) : "m" (ctl) : "cc");
+       return cc;
+}
+
+/* Extract CPU counter */
+static inline int ecctr(u64 ctr, u64 *val)
+{
+       register u64 content asm("4") = 0;
+       int cc;
+
+       asm volatile (
+               "       .insn   rre,0xb2e40000,%0,%2\n"
+               "       ipm     %1\n"
+               "       srl     %1,28\n"
+               : "=d" (content), "=d" (cc) : "d" (ctr) : "cc");
+       if (!cc)
+               *val = content;
+       return cc;
+}
+
+#endif /* _ASM_S390_CPU_MF_H */
index acee1806f61e2b29d9eb138b28c29310cf1d2b93..5289cacd4861773928e5257b670a98525637460c 100644 (file)
@@ -45,5 +45,7 @@ int register_external_interrupt(u16 code, ext_int_handler_t handler);
 int unregister_external_interrupt(u16 code, ext_int_handler_t handler);
 void service_subclass_irq_register(void);
 void service_subclass_irq_unregister(void);
+void measurement_alert_subclass_register(void);
+void measurement_alert_subclass_unregister(void);
 
 #endif /* _ASM_IRQ_H */
index 4eb444edbe496b3e3b96789650528b9998dfd27d..7941968e12b48ced12b4122918f111485de1dc4e 100644 (file)
@@ -1,8 +1,16 @@
 /*
  * Performance event support - s390 specific definitions.
  *
- * Copyright 2009 Martin Schwidefsky, IBM Corporation.
+ * Copyright IBM Corp. 2009, 2012
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ *           Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
  */
 
-/* Empty, just to avoid compiling error */
+#include <asm/cpu_mf.h>
 
+/* CPU-measurement counter facility */
+#define PERF_CPUM_CF_MAX_CTR           160
+
+/* Per-CPU flags for PMU states */
+#define PMU_F_RESERVED                 0x1000
+#define PMU_F_ENABLED                  0x2000
index 16b0b433f1f48510a7978814beed7f265cf628ad..884b18afc8645d6d8c8b573fed87a13518b23b85 100644 (file)
@@ -48,6 +48,7 @@ obj-$(CONFIG_DYNAMIC_FTRACE)  += ftrace.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
 obj-$(CONFIG_FTRACE_SYSCALLS)  += ftrace.o
 obj-$(CONFIG_CRASH_DUMP)       += crash_dump.o
+obj-$(CONFIG_PERF_EVENTS)      += perf_event.o perf_cpum_cf.o
 
 # Kexec part
 S390_KEXEC_OBJS := machine_kexec.o crash.o
index 2429ecd68872cba797172855c898df868bfc4c8d..1c2cdd59ccd0504469a1d31a45ba2aaf6442368b 100644 (file)
@@ -255,3 +255,26 @@ void service_subclass_irq_unregister(void)
        spin_unlock(&sc_irq_lock);
 }
 EXPORT_SYMBOL(service_subclass_irq_unregister);
+
+static DEFINE_SPINLOCK(ma_subclass_lock);
+static int ma_subclass_refcount;
+
+void measurement_alert_subclass_register(void)
+{
+       spin_lock(&ma_subclass_lock);
+       if (!ma_subclass_refcount)
+               ctl_set_bit(0, 5);
+       ma_subclass_refcount++;
+       spin_unlock(&ma_subclass_lock);
+}
+EXPORT_SYMBOL(measurement_alert_subclass_register);
+
+void measurement_alert_subclass_unregister(void)
+{
+       spin_lock(&ma_subclass_lock);
+       ma_subclass_refcount--;
+       if (!ma_subclass_refcount)
+               ctl_clear_bit(0, 5);
+       spin_unlock(&ma_subclass_lock);
+}
+EXPORT_SYMBOL(measurement_alert_subclass_unregister);
diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c
new file mode 100644 (file)
index 0000000..8481ecf
--- /dev/null
@@ -0,0 +1,690 @@
+/*
+ * Performance event support for s390x - CPU-measurement Counter Facility
+ *
+ *  Copyright IBM Corp. 2012
+ *  Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (version 2 only)
+ * as published by the Free Software Foundation.
+ */
+#define KMSG_COMPONENT "cpum_cf"
+#define pr_fmt(fmt)    KMSG_COMPONENT ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/kernel_stat.h>
+#include <linux/perf_event.h>
+#include <linux/percpu.h>
+#include <linux/notifier.h>
+#include <linux/init.h>
+#include <linux/export.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/cpu_mf.h>
+
+/* CPU-measurement counter facility supports these CPU counter sets:
+ * For CPU counter sets:
+ *    Basic counter set:            0-31
+ *    Problem-state counter set:    32-63
+ *    Crypto-activity counter set:  64-127
+ *    Extented counter set:       128-159
+ */
+enum cpumf_ctr_set {
+       /* CPU counter sets */
+       CPUMF_CTR_SET_BASIC   = 0,
+       CPUMF_CTR_SET_USER    = 1,
+       CPUMF_CTR_SET_CRYPTO  = 2,
+       CPUMF_CTR_SET_EXT     = 3,
+
+       /* Maximum number of counter sets */
+       CPUMF_CTR_SET_MAX,
+};
+
+#define CPUMF_LCCTL_ENABLE_SHIFT    16
+#define CPUMF_LCCTL_ACTCTL_SHIFT     0
+static const u64 cpumf_state_ctl[CPUMF_CTR_SET_MAX] = {
+       [CPUMF_CTR_SET_BASIC]   = 0x02,
+       [CPUMF_CTR_SET_USER]    = 0x04,
+       [CPUMF_CTR_SET_CRYPTO]  = 0x08,
+       [CPUMF_CTR_SET_EXT]     = 0x01,
+};
+
+static void ctr_set_enable(u64 *state, int ctr_set)
+{
+       *state |= cpumf_state_ctl[ctr_set] << CPUMF_LCCTL_ENABLE_SHIFT;
+}
+static void ctr_set_disable(u64 *state, int ctr_set)
+{
+       *state &= ~(cpumf_state_ctl[ctr_set] << CPUMF_LCCTL_ENABLE_SHIFT);
+}
+static void ctr_set_start(u64 *state, int ctr_set)
+{
+       *state |= cpumf_state_ctl[ctr_set] << CPUMF_LCCTL_ACTCTL_SHIFT;
+}
+static void ctr_set_stop(u64 *state, int ctr_set)
+{
+       *state &= ~(cpumf_state_ctl[ctr_set] << CPUMF_LCCTL_ACTCTL_SHIFT);
+}
+
+/* Local CPUMF event structure */
+struct cpu_hw_events {
+       struct cpumf_ctr_info   info;
+       atomic_t                ctr_set[CPUMF_CTR_SET_MAX];
+       u64                     state, tx_state;
+       unsigned int            flags;
+};
+static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
+       .ctr_set = {
+               [CPUMF_CTR_SET_BASIC]  = ATOMIC_INIT(0),
+               [CPUMF_CTR_SET_USER]   = ATOMIC_INIT(0),
+               [CPUMF_CTR_SET_CRYPTO] = ATOMIC_INIT(0),
+               [CPUMF_CTR_SET_EXT]    = ATOMIC_INIT(0),
+       },
+       .state = 0,
+       .flags = 0,
+};
+
+static int get_counter_set(u64 event)
+{
+       int set = -1;
+
+       if (event < 32)
+               set = CPUMF_CTR_SET_BASIC;
+       else if (event < 64)
+               set = CPUMF_CTR_SET_USER;
+       else if (event < 128)
+               set = CPUMF_CTR_SET_CRYPTO;
+       else if (event < 160)
+               set = CPUMF_CTR_SET_EXT;
+
+       return set;
+}
+
+static int validate_event(const struct hw_perf_event *hwc)
+{
+       switch (hwc->config_base) {
+       case CPUMF_CTR_SET_BASIC:
+       case CPUMF_CTR_SET_USER:
+       case CPUMF_CTR_SET_CRYPTO:
+       case CPUMF_CTR_SET_EXT:
+               /* check for reserved counters */
+               if ((hwc->config >=  6 && hwc->config <=  31) ||
+                   (hwc->config >= 38 && hwc->config <=  63) ||
+                   (hwc->config >= 80 && hwc->config <= 127))
+                       return -EOPNOTSUPP;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int validate_ctr_version(const struct hw_perf_event *hwc)
+{
+       struct cpu_hw_events *cpuhw;
+       int err = 0;
+
+       cpuhw = &get_cpu_var(cpu_hw_events);
+
+       /* check required version for counter sets */
+       switch (hwc->config_base) {
+       case CPUMF_CTR_SET_BASIC:
+       case CPUMF_CTR_SET_USER:
+               if (cpuhw->info.cfvn < 1)
+                       err = -EOPNOTSUPP;
+               break;
+       case CPUMF_CTR_SET_CRYPTO:
+       case CPUMF_CTR_SET_EXT:
+               if (cpuhw->info.csvn < 1)
+                       err = -EOPNOTSUPP;
+               break;
+       }
+
+       put_cpu_var(cpu_hw_events);
+       return err;
+}
+
+static int validate_ctr_auth(const struct hw_perf_event *hwc)
+{
+       struct cpu_hw_events *cpuhw;
+       u64 ctrs_state;
+       int err = 0;
+
+       cpuhw = &get_cpu_var(cpu_hw_events);
+
+       /* check authorization for cpu counter sets */
+       ctrs_state = cpumf_state_ctl[hwc->config_base];
+       if (!(ctrs_state & cpuhw->info.auth_ctl))
+               err = -EPERM;
+
+       put_cpu_var(cpu_hw_events);
+       return err;
+}
+
+/*
+ * Change the CPUMF state to active.
+ * Enable and activate the CPU-counter sets according
+ * to the per-cpu control state.
+ */
+static void cpumf_pmu_enable(struct pmu *pmu)
+{
+       struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+       int err;
+
+       if (cpuhw->flags & PMU_F_ENABLED)
+               return;
+
+       err = lcctl(cpuhw->state);
+       if (err) {
+               pr_err("Enabling the performance measuring unit "
+                      "failed with rc=%lx\n", err);
+               return;
+       }
+
+       cpuhw->flags |= PMU_F_ENABLED;
+}
+
+/*
+ * Change the CPUMF state to inactive.
+ * Disable and enable (inactive) the CPU-counter sets according
+ * to the per-cpu control state.
+ */
+static void cpumf_pmu_disable(struct pmu *pmu)
+{
+       struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+       int err;
+       u64 inactive;
+
+       if (!(cpuhw->flags & PMU_F_ENABLED))
+               return;
+
+       inactive = cpuhw->state & ~((1 << CPUMF_LCCTL_ENABLE_SHIFT) - 1);
+       err = lcctl(inactive);
+       if (err) {
+               pr_err("Disabling the performance measuring unit "
+                      "failed with rc=%lx\n", err);
+               return;
+       }
+
+       cpuhw->flags &= ~PMU_F_ENABLED;
+}
+
+
+/* Number of perf events counting hardware events */
+static atomic_t num_events = ATOMIC_INIT(0);
+/* Used to avoid races in calling reserve/release_cpumf_hardware */
+static DEFINE_MUTEX(pmc_reserve_mutex);
+
+/* CPU-measurement alerts for the counter facility */
+static void cpumf_measurement_alert(struct ext_code ext_code,
+                                   unsigned int alert, unsigned long unused)
+{
+       struct cpu_hw_events *cpuhw;
+
+       if (!(alert & CPU_MF_INT_CF_MASK))
+               return;
+
+       kstat_cpu(smp_processor_id()).irqs[EXTINT_CPM]++;
+       cpuhw = &__get_cpu_var(cpu_hw_events);
+
+       /* Measurement alerts are shared and might happen when the PMU
+        * is not reserved.  Ignore these alerts in this case. */
+       if (!(cpuhw->flags & PMU_F_RESERVED))
+               return;
+
+       /* counter authorization change alert */
+       if (alert & CPU_MF_INT_CF_CACA)
+               qctri(&cpuhw->info);
+
+       /* loss of counter data alert */
+       if (alert & CPU_MF_INT_CF_LCDA)
+               pr_err("CPU[%i] Counter data was lost\n", smp_processor_id());
+}
+
+#define PMC_INIT      0
+#define PMC_RELEASE   1
+static void setup_pmc_cpu(void *flags)
+{
+       struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+
+       switch (*((int *) flags)) {
+       case PMC_INIT:
+               memset(&cpuhw->info, 0, sizeof(cpuhw->info));
+               qctri(&cpuhw->info);
+               cpuhw->flags |= PMU_F_RESERVED;
+               break;
+
+       case PMC_RELEASE:
+               cpuhw->flags &= ~PMU_F_RESERVED;
+               break;
+       }
+
+       /* Disable CPU counter sets */
+       lcctl(0);
+}
+
+/* Initialize the CPU-measurement facility */
+static int reserve_pmc_hardware(void)
+{
+       int flags = PMC_INIT;
+
+       on_each_cpu(setup_pmc_cpu, &flags, 1);
+       measurement_alert_subclass_register();
+
+       return 0;
+}
+
+/* Release the CPU-measurement facility */
+static void release_pmc_hardware(void)
+{
+       int flags = PMC_RELEASE;
+
+       on_each_cpu(setup_pmc_cpu, &flags, 1);
+       measurement_alert_subclass_unregister();
+}
+
+/* Release the PMU if event is the last perf event */
+static void hw_perf_event_destroy(struct perf_event *event)
+{
+       if (!atomic_add_unless(&num_events, -1, 1)) {
+               mutex_lock(&pmc_reserve_mutex);
+               if (atomic_dec_return(&num_events) == 0)
+                       release_pmc_hardware();
+               mutex_unlock(&pmc_reserve_mutex);
+       }
+}
+
+/* CPUMF <-> perf event mappings for kernel+userspace (basic set) */
+static const int cpumf_generic_events_basic[] = {
+       [PERF_COUNT_HW_CPU_CYCLES]          = 0,
+       [PERF_COUNT_HW_INSTRUCTIONS]        = 1,
+       [PERF_COUNT_HW_CACHE_REFERENCES]    = -1,
+       [PERF_COUNT_HW_CACHE_MISSES]        = -1,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = -1,
+       [PERF_COUNT_HW_BRANCH_MISSES]       = -1,
+       [PERF_COUNT_HW_BUS_CYCLES]          = -1,
+};
+/* CPUMF <-> perf event mappings for userspace (problem-state set) */
+static const int cpumf_generic_events_user[] = {
+       [PERF_COUNT_HW_CPU_CYCLES]          = 32,
+       [PERF_COUNT_HW_INSTRUCTIONS]        = 33,
+       [PERF_COUNT_HW_CACHE_REFERENCES]    = -1,
+       [PERF_COUNT_HW_CACHE_MISSES]        = -1,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = -1,
+       [PERF_COUNT_HW_BRANCH_MISSES]       = -1,
+       [PERF_COUNT_HW_BUS_CYCLES]          = -1,
+};
+
+static int __hw_perf_event_init(struct perf_event *event)
+{
+       struct perf_event_attr *attr = &event->attr;
+       struct hw_perf_event *hwc = &event->hw;
+       int err;
+       u64 ev;
+
+       switch (attr->type) {
+       case PERF_TYPE_RAW:
+               /* Raw events are used to access counters directly,
+                * hence do not permit excludes */
+               if (attr->exclude_kernel || attr->exclude_user ||
+                   attr->exclude_hv)
+                       return -EOPNOTSUPP;
+               ev = attr->config;
+               break;
+
+       case PERF_TYPE_HARDWARE:
+               ev = attr->config;
+               /* Count user space (problem-state) only */
+               if (!attr->exclude_user && attr->exclude_kernel) {
+                       if (ev >= ARRAY_SIZE(cpumf_generic_events_user))
+                               return -EOPNOTSUPP;
+                       ev = cpumf_generic_events_user[ev];
+
+               /* No support for kernel space counters only */
+               } else if (!attr->exclude_kernel && attr->exclude_user) {
+                       return -EOPNOTSUPP;
+
+               /* Count user and kernel space */
+               } else {
+                       if (ev >= ARRAY_SIZE(cpumf_generic_events_basic))
+                               return -EOPNOTSUPP;
+                       ev = cpumf_generic_events_basic[ev];
+               }
+               break;
+
+       default:
+               return -ENOENT;
+       }
+
+       if (ev == -1)
+               return -ENOENT;
+
+       if (ev >= PERF_CPUM_CF_MAX_CTR)
+               return -EINVAL;
+
+       /* The CPU measurement counter facility does not have any interrupts
+        * to do sampling.  Sampling must be provided by external means,
+        * for example, by timers.
+        */
+       if (hwc->sample_period)
+               return -EINVAL;
+
+       /* Use the hardware perf event structure to store the counter number
+        * in 'config' member and the counter set to which the counter belongs
+        * in the 'config_base'.  The counter set (config_base) is then used
+        * to enable/disable the counters.
+        */
+       hwc->config = ev;
+       hwc->config_base = get_counter_set(ev);
+
+       /* Validate the counter that is assigned to this event.
+        * Because the counter facility can use numerous counters at the
+        * same time without constraints, it is not necessary to explicity
+        * validate event groups (event->group_leader != event).
+        */
+       err = validate_event(hwc);
+       if (err)
+               return err;
+
+       /* Initialize for using the CPU-measurement counter facility */
+       if (!atomic_inc_not_zero(&num_events)) {
+               mutex_lock(&pmc_reserve_mutex);
+               if (atomic_read(&num_events) == 0 && reserve_pmc_hardware())
+                       err = -EBUSY;
+               else
+                       atomic_inc(&num_events);
+               mutex_unlock(&pmc_reserve_mutex);
+       }
+       event->destroy = hw_perf_event_destroy;
+
+       /* Finally, validate version and authorization of the counter set */
+       err = validate_ctr_auth(hwc);
+       if (!err)
+               err = validate_ctr_version(hwc);
+
+       return err;
+}
+
+static int cpumf_pmu_event_init(struct perf_event *event)
+{
+       int err;
+
+       switch (event->attr.type) {
+       case PERF_TYPE_HARDWARE:
+       case PERF_TYPE_HW_CACHE:
+       case PERF_TYPE_RAW:
+               err = __hw_perf_event_init(event);
+               break;
+       default:
+               return -ENOENT;
+       }
+
+       if (unlikely(err) && event->destroy)
+               event->destroy(event);
+
+       return err;
+}
+
+static int hw_perf_event_reset(struct perf_event *event)
+{
+       u64 prev, new;
+       int err;
+
+       do {
+               prev = local64_read(&event->hw.prev_count);
+               err = ecctr(event->hw.config, &new);
+               if (err) {
+                       if (err != 3)
+                               break;
+                       /* The counter is not (yet) available. This
+                        * might happen if the counter set to which
+                        * this counter belongs is in the disabled
+                        * state.
+                        */
+                       new = 0;
+               }
+       } while (local64_cmpxchg(&event->hw.prev_count, prev, new) != prev);
+
+       return err;
+}
+
+static int hw_perf_event_update(struct perf_event *event)
+{
+       u64 prev, new, delta;
+       int err;
+
+       do {
+               prev = local64_read(&event->hw.prev_count);
+               err = ecctr(event->hw.config, &new);
+               if (err)
+                       goto out;
+       } while (local64_cmpxchg(&event->hw.prev_count, prev, new) != prev);
+
+       delta = (prev <= new) ? new - prev
+                             : (-1ULL - prev) + new + 1;        /* overflow */
+       local64_add(delta, &event->count);
+out:
+       return err;
+}
+
+static void cpumf_pmu_read(struct perf_event *event)
+{
+       if (event->hw.state & PERF_HES_STOPPED)
+               return;
+
+       hw_perf_event_update(event);
+}
+
+static void cpumf_pmu_start(struct perf_event *event, int flags)
+{
+       struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+       struct hw_perf_event *hwc = &event->hw;
+
+       if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
+               return;
+
+       if (WARN_ON_ONCE(hwc->config == -1))
+               return;
+
+       if (flags & PERF_EF_RELOAD)
+               WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
+
+       hwc->state = 0;
+
+       /* (Re-)enable and activate the counter set */
+       ctr_set_enable(&cpuhw->state, hwc->config_base);
+       ctr_set_start(&cpuhw->state, hwc->config_base);
+
+       /* The counter set to which this counter belongs can be already active.
+        * Because all counters in a set are active, the event->hw.prev_count
+        * needs to be synchronized.  At this point, the counter set can be in
+        * the inactive or disabled state.
+        */
+       hw_perf_event_reset(event);
+
+       /* increment refcount for this counter set */
+       atomic_inc(&cpuhw->ctr_set[hwc->config_base]);
+}
+
+static void cpumf_pmu_stop(struct perf_event *event, int flags)
+{
+       struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+       struct hw_perf_event *hwc = &event->hw;
+
+       if (!(hwc->state & PERF_HES_STOPPED)) {
+               /* Decrement reference count for this counter set and if this
+                * is the last used counter in the set, clear activation
+                * control and set the counter set state to inactive.
+                */
+               if (!atomic_dec_return(&cpuhw->ctr_set[hwc->config_base]))
+                       ctr_set_stop(&cpuhw->state, hwc->config_base);
+               event->hw.state |= PERF_HES_STOPPED;
+       }
+
+       if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
+               hw_perf_event_update(event);
+               event->hw.state |= PERF_HES_UPTODATE;
+       }
+}
+
+static int cpumf_pmu_add(struct perf_event *event, int flags)
+{
+       struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+
+       /* Check authorization for the counter set to which this
+        * counter belongs.
+        * For group events transaction, the authorization check is
+        * done in cpumf_pmu_commit_txn().
+        */
+       if (!(cpuhw->flags & PERF_EVENT_TXN))
+               if (validate_ctr_auth(&event->hw))
+                       return -EPERM;
+
+       ctr_set_enable(&cpuhw->state, event->hw.config_base);
+       event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+
+       if (flags & PERF_EF_START)
+               cpumf_pmu_start(event, PERF_EF_RELOAD);
+
+       perf_event_update_userpage(event);
+
+       return 0;
+}
+
+static void cpumf_pmu_del(struct perf_event *event, int flags)
+{
+       struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+
+       cpumf_pmu_stop(event, PERF_EF_UPDATE);
+
+       /* Check if any counter in the counter set is still used.  If not used,
+        * change the counter set to the disabled state.  This also clears the
+        * content of all counters in the set.
+        *
+        * When a new perf event has been added but not yet started, this can
+        * clear enable control and resets all counters in a set.  Therefore,
+        * cpumf_pmu_start() always has to reenable a counter set.
+        */
+       if (!atomic_read(&cpuhw->ctr_set[event->hw.config_base]))
+               ctr_set_disable(&cpuhw->state, event->hw.config_base);
+
+       perf_event_update_userpage(event);
+}
+
+/*
+ * Start group events scheduling transaction.
+ * Set flags to perform a single test at commit time.
+ */
+static void cpumf_pmu_start_txn(struct pmu *pmu)
+{
+       struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+
+       perf_pmu_disable(pmu);
+       cpuhw->flags |= PERF_EVENT_TXN;
+       cpuhw->tx_state = cpuhw->state;
+}
+
+/*
+ * Stop and cancel a group events scheduling tranctions.
+ * Assumes cpumf_pmu_del() is called for each successful added
+ * cpumf_pmu_add() during the transaction.
+ */
+static void cpumf_pmu_cancel_txn(struct pmu *pmu)
+{
+       struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+
+       WARN_ON(cpuhw->tx_state != cpuhw->state);
+
+       cpuhw->flags &= ~PERF_EVENT_TXN;
+       perf_pmu_enable(pmu);
+}
+
+/*
+ * Commit the group events scheduling transaction.  On success, the
+ * transaction is closed.   On error, the transaction is kept open
+ * until cpumf_pmu_cancel_txn() is called.
+ */
+static int cpumf_pmu_commit_txn(struct pmu *pmu)
+{
+       struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+       u64 state;
+
+       /* check if the updated state can be scheduled */
+       state = cpuhw->state & ~((1 << CPUMF_LCCTL_ENABLE_SHIFT) - 1);
+       state >>= CPUMF_LCCTL_ENABLE_SHIFT;
+       if ((state & cpuhw->info.auth_ctl) != state)
+               return -EPERM;
+
+       cpuhw->flags &= ~PERF_EVENT_TXN;
+       perf_pmu_enable(pmu);
+       return 0;
+}
+
+/* Performance monitoring unit for s390x */
+static struct pmu cpumf_pmu = {
+       .pmu_enable   = cpumf_pmu_enable,
+       .pmu_disable  = cpumf_pmu_disable,
+       .event_init   = cpumf_pmu_event_init,
+       .add          = cpumf_pmu_add,
+       .del          = cpumf_pmu_del,
+       .start        = cpumf_pmu_start,
+       .stop         = cpumf_pmu_stop,
+       .read         = cpumf_pmu_read,
+       .start_txn    = cpumf_pmu_start_txn,
+       .commit_txn   = cpumf_pmu_commit_txn,
+       .cancel_txn   = cpumf_pmu_cancel_txn,
+};
+
+static int __cpuinit cpumf_pmu_notifier(struct notifier_block *self,
+                                       unsigned long action, void *hcpu)
+{
+       unsigned int cpu = (long) hcpu;
+       int flags;
+
+       switch (action & ~CPU_TASKS_FROZEN) {
+       case CPU_ONLINE:
+               flags = PMC_INIT;
+               smp_call_function_single(cpu, setup_pmc_cpu, &flags, 1);
+               break;
+       case CPU_DOWN_PREPARE:
+               flags = PMC_RELEASE;
+               smp_call_function_single(cpu, setup_pmc_cpu, &flags, 1);
+               break;
+       default:
+               break;
+       }
+
+       return NOTIFY_OK;
+}
+
+static int __init cpumf_pmu_init(void)
+{
+       int rc;
+
+       if (!cpum_cf_avail())
+               return -ENODEV;
+
+       /* clear bit 15 of cr0 to unauthorize problem-state to
+        * extract measurement counters */
+       ctl_clear_bit(0, 48);
+
+       /* register handler for measurement-alert interruptions */
+       rc = register_external_interrupt(0x1407, cpumf_measurement_alert);
+       if (rc) {
+               pr_err("Registering for CPU-measurement alerts "
+                      "failed with rc=%i\n", rc);
+               goto out;
+       }
+
+       rc = perf_pmu_register(&cpumf_pmu, "cpum_cf", PERF_TYPE_RAW);
+       if (rc) {
+               pr_err("Registering the cpum_cf PMU failed with rc=%i\n", rc);
+               unregister_external_interrupt(0x1407, cpumf_measurement_alert);
+               goto out;
+       }
+       perf_cpu_notifier(cpumf_pmu_notifier);
+out:
+       return rc;
+}
+early_initcall(cpumf_pmu_init);
diff --git a/arch/s390/kernel/perf_event.c b/arch/s390/kernel/perf_event.c
new file mode 100644 (file)
index 0000000..609f985
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Performance event support for s390x
+ *
+ *  Copyright IBM Corp. 2012
+ *  Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (version 2 only)
+ * as published by the Free Software Foundation.
+ */
+#define KMSG_COMPONENT "perf"
+#define pr_fmt(fmt)    KMSG_COMPONENT ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/perf_event.h>
+#include <linux/percpu.h>
+#include <linux/export.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/cpu_mf.h>
+#include <asm/lowcore.h>
+#include <asm/processor.h>
+
+const char *perf_pmu_name(void)
+{
+       if (cpum_cf_avail() || cpum_sf_avail())
+               return "CPU-measurement facilities (CPUMF)";
+       return "pmu";
+}
+EXPORT_SYMBOL(perf_pmu_name);
+
+int perf_num_counters(void)
+{
+       int num = 0;
+
+       if (cpum_cf_avail())
+               num += PERF_CPUM_CF_MAX_CTR;
+
+       return num;
+}
+EXPORT_SYMBOL(perf_num_counters);
+
+void perf_event_print_debug(void)
+{
+       struct cpumf_ctr_info cf_info;
+       unsigned long flags;
+       int cpu;
+
+       if (!cpum_cf_avail())
+               return;
+
+       local_irq_save(flags);
+
+       cpu = smp_processor_id();
+       memset(&cf_info, 0, sizeof(cf_info));
+       if (!qctri(&cf_info)) {
+               pr_info("CPU[%i] CPUM_CF: ver=%u.%u A=%04x E=%04x C=%04x\n",
+                       cpu, cf_info.cfvn, cf_info.csvn,
+                       cf_info.auth_ctl, cf_info.enable_ctl, cf_info.act_ctl);
+               print_hex_dump_bytes("CPUMF Query: ", DUMP_PREFIX_OFFSET,
+                                    &cf_info, sizeof(cf_info));
+       }
+
+       local_irq_restore(flags);
+}
+
+/* See also arch/s390/kernel/traps.c */
+static unsigned long __store_trace(struct perf_callchain_entry *entry,
+                                  unsigned long sp,
+                                  unsigned long low, unsigned long high)
+{
+       struct stack_frame *sf;
+       struct pt_regs *regs;
+
+       while (1) {
+               sp = sp & PSW_ADDR_INSN;
+               if (sp < low || sp > high - sizeof(*sf))
+                       return sp;
+               sf = (struct stack_frame *) sp;
+               perf_callchain_store(entry, sf->gprs[8] & PSW_ADDR_INSN);
+               /* Follow the backchain. */
+               while (1) {
+                       low = sp;
+                       sp = sf->back_chain & PSW_ADDR_INSN;
+                       if (!sp)
+                               break;
+                       if (sp <= low || sp > high - sizeof(*sf))
+                               return sp;
+                       sf = (struct stack_frame *) sp;
+                       perf_callchain_store(entry,
+                                            sf->gprs[8] & PSW_ADDR_INSN);
+               }
+               /* Zero backchain detected, check for interrupt frame. */
+               sp = (unsigned long) (sf + 1);
+               if (sp <= low || sp > high - sizeof(*regs))
+                       return sp;
+               regs = (struct pt_regs *) sp;
+               perf_callchain_store(entry, sf->gprs[8] & PSW_ADDR_INSN);
+               low = sp;
+               sp = regs->gprs[15];
+       }
+}
+
+void perf_callchain_kernel(struct perf_callchain_entry *entry,
+                          struct pt_regs *regs)
+{
+       unsigned long head;
+       struct stack_frame *head_sf;
+
+       if (user_mode(regs))
+               return;
+
+       head = regs->gprs[15];
+       head_sf = (struct stack_frame *) head;
+
+       if (!head_sf || !head_sf->back_chain)
+               return;
+
+       head = head_sf->back_chain;
+       head = __store_trace(entry, head, S390_lowcore.async_stack - ASYNC_SIZE,
+                            S390_lowcore.async_stack);
+
+       __store_trace(entry, head, S390_lowcore.thread_info,
+                     S390_lowcore.thread_info + THREAD_SIZE);
+}
index a0155c02e324900ae54745ae4024c3b384b51740..2857c48486ea9005ba5d3bb8a9924e4704c8ceb2 100644 (file)
@@ -100,7 +100,6 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
                mm->unmap_area = arch_unmap_area_topdown;
        }
 }
-EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
 
 #else
 
@@ -175,6 +174,5 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
                mm->unmap_area = arch_unmap_area_topdown;
        }
 }
-EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
 
 #endif
index 12bea05a0fc18b6e70124510bc2d772fd87cbc71..f097d516d8c5ab0555d5d393c9d34eb6b688fa1e 100644 (file)
@@ -17,8 +17,7 @@
 #include <linux/semaphore.h>
 #include <linux/oom.h>
 #include <linux/oprofile.h>
-
-#include <asm/lowcore.h>
+#include <asm/cpu_mf.h>
 #include <asm/irq.h>
 
 #include "hwsampler.h"
 #define ALERT_REQ_MASK   0x4000000000000000ul
 #define BUFFER_FULL_MASK 0x8000000000000000ul
 
-#define EI_IEA      (1 << 31)  /* invalid entry address              */
-#define EI_ISE      (1 << 30)  /* incorrect SDBT entry               */
-#define EI_PRA      (1 << 29)  /* program request alert              */
-#define EI_SACA     (1 << 23)  /* sampler authorization change alert */
-#define EI_LSDA     (1 << 22)  /* loss of sample data alert          */
-
 DECLARE_PER_CPU(struct hws_cpu_buffer, sampler_cpu_buffer);
 
 struct hws_execute_parms {
@@ -232,9 +225,20 @@ static inline unsigned long *trailer_entry_ptr(unsigned long v)
        return (unsigned long *) ret;
 }
 
-/* prototypes for external interrupt handler and worker */
 static void hws_ext_handler(struct ext_code ext_code,
-                           unsigned int param32, unsigned long param64);
+                           unsigned int param32, unsigned long param64)
+{
+       struct hws_cpu_buffer *cb = &__get_cpu_var(sampler_cpu_buffer);
+
+       if (!(param32 & CPU_MF_INT_SF_MASK))
+               return;
+
+       kstat_cpu(smp_processor_id()).irqs[EXTINT_CPM]++;
+       atomic_xchg(&cb->ext_params, atomic_read(&cb->ext_params) | param32);
+
+       if (hws_wq)
+               queue_work(hws_wq, &cb->worker);
+}
 
 static void worker(struct work_struct *work);
 
@@ -673,18 +677,6 @@ int hwsampler_activate(unsigned int cpu)
        return rc;
 }
 
-static void hws_ext_handler(struct ext_code ext_code,
-                           unsigned int param32, unsigned long param64)
-{
-       struct hws_cpu_buffer *cb;
-
-       kstat_cpu(smp_processor_id()).irqs[EXTINT_CPM]++;
-       cb = &__get_cpu_var(sampler_cpu_buffer);
-       atomic_xchg(&cb->ext_params, atomic_read(&cb->ext_params) | param32);
-       if (hws_wq)
-               queue_work(hws_wq, &cb->worker);
-}
-
 static int check_qsi_on_setup(void)
 {
        int rc;
@@ -760,23 +752,23 @@ static int worker_check_error(unsigned int cpu, int ext_params)
        if (!sdbt || !*sdbt)
                return -EINVAL;
 
-       if (ext_params & EI_PRA)
+       if (ext_params & CPU_MF_INT_SF_PRA)
                cb->req_alert++;
 
-       if (ext_params & EI_LSDA)
+       if (ext_params & CPU_MF_INT_SF_LSDA)
                cb->loss_of_sample_data++;
 
-       if (ext_params & EI_IEA) {
+       if (ext_params & CPU_MF_INT_SF_IAE) {
                cb->invalid_entry_address++;
                rc = -EINVAL;
        }
 
-       if (ext_params & EI_ISE) {
+       if (ext_params & CPU_MF_INT_SF_ISE) {
                cb->incorrect_sdbt_entry++;
                rc = -EINVAL;
        }
 
-       if (ext_params & EI_SACA) {
+       if (ext_params & CPU_MF_INT_SF_SACA) {
                cb->sample_auth_change_alert++;
                rc = -EINVAL;
        }
@@ -1009,7 +1001,7 @@ int hwsampler_deallocate(void)
        if (hws_state != HWS_STOPPED)
                goto deallocate_exit;
 
-       ctl_clear_bit(0, 5); /* set bit 58 CR0 off */
+       measurement_alert_subclass_unregister();
        deallocate_sdbt();
 
        hws_state = HWS_DEALLOCATED;
@@ -1123,7 +1115,7 @@ int hwsampler_shutdown(void)
                mutex_lock(&hws_sem);
 
                if (hws_state == HWS_STOPPED) {
-                       ctl_clear_bit(0, 5); /* set bit 58 CR0 off */
+                       measurement_alert_subclass_unregister();
                        deallocate_sdbt();
                }
                if (hws_wq) {
@@ -1198,7 +1190,7 @@ start_all_exit:
        hws_oom = 1;
        hws_flush_all = 0;
        /* now let them in, 1407 CPUMF external interrupts */
-       ctl_set_bit(0, 5); /* set CR0 bit 58 */
+       measurement_alert_subclass_register();
 
        return 0;
 }
index 74b8db1b74a9d9bd27d7dec2afea771f5beb9d4c..4a52590fe3d8248961e781c9887a9a2deedb45d5 100644 (file)
@@ -322,7 +322,7 @@ static void ivdr_clk_disable(struct clk *clk)
        __raw_writew(__raw_readw(PA_IVDRCTL) & ~(1 << IVDR_CK_ON), PA_IVDRCTL);
 }
 
-static struct clk_ops ivdr_clk_ops = {
+static struct sh_clk_ops ivdr_clk_ops = {
        .enable         = ivdr_clk_enable,
        .disable        = ivdr_clk_disable,
 };
index 486d1ac3694c2638d810c718b83d0ede65f1cd75..27a2314f50acb7ecccc4e1a928c79b91bcd7b2c3 100644 (file)
@@ -167,7 +167,7 @@ static void sdk7786_pcie_clk_disable(struct clk *clk)
        fpga_write_reg(fpga_read_reg(PCIECR) & ~PCIECR_CLKEN, PCIECR);
 }
 
-static struct clk_ops sdk7786_pcie_clk_ops = {
+static struct sh_clk_ops sdk7786_pcie_clk_ops = {
        .enable         = sdk7786_pcie_clk_enable,
        .disable        = sdk7786_pcie_clk_disable,
 };
index 803d4c7f09dc3c654a94aa6607c2501cc071a22a..0390a07e7e3bd0e6374df1fd2efa79bb79d1d24d 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/sh_clk.h>
 
 /* Should be defined by processor-specific code */
-void __deprecated arch_init_clk_ops(struct clk_ops **, int type);
+void __deprecated arch_init_clk_ops(struct sh_clk_ops **, int type);
 int __init arch_clk_init(void);
 
 /* arch/sh/kernel/cpu/clock-cpg.c */
index 5b7f12e58a8ddaf80b316458b3675323b88ea80b..e80252ae5bca7437b43957dce13d3f8dba5b5ed0 100644 (file)
@@ -28,7 +28,7 @@ static void master_clk_init(struct clk *clk)
        clk->rate *= pll2_mult * pll1rate[(__raw_readw(FREQCR) >> 8) & 7];
 }
 
-static struct clk_ops sh7619_master_clk_ops = {
+static struct sh_clk_ops sh7619_master_clk_ops = {
        .init           = master_clk_init,
 };
 
@@ -38,7 +38,7 @@ static unsigned long module_clk_recalc(struct clk *clk)
        return clk->parent->rate / pfc_divisors[idx];
 }
 
-static struct clk_ops sh7619_module_clk_ops = {
+static struct sh_clk_ops sh7619_module_clk_ops = {
        .recalc         = module_clk_recalc,
 };
 
@@ -47,22 +47,22 @@ static unsigned long bus_clk_recalc(struct clk *clk)
        return clk->parent->rate / pll1rate[(__raw_readw(FREQCR) >> 8) & 7];
 }
 
-static struct clk_ops sh7619_bus_clk_ops = {
+static struct sh_clk_ops sh7619_bus_clk_ops = {
        .recalc         = bus_clk_recalc,
 };
 
-static struct clk_ops sh7619_cpu_clk_ops = {
+static struct sh_clk_ops sh7619_cpu_clk_ops = {
        .recalc         = followparent_recalc,
 };
 
-static struct clk_ops *sh7619_clk_ops[] = {
+static struct sh_clk_ops *sh7619_clk_ops[] = {
        &sh7619_master_clk_ops,
        &sh7619_module_clk_ops,
        &sh7619_bus_clk_ops,
        &sh7619_cpu_clk_ops,
 };
 
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
 {
        if (test_mode_pin(MODE_PIN2 | MODE_PIN0) ||
            test_mode_pin(MODE_PIN2 | MODE_PIN1))
index 1174e2d96c03895aac70845f482b4cffd9623c2f..532a36c72322706eeb9f19fca91d1284c07541bc 100644 (file)
@@ -30,7 +30,7 @@ static void master_clk_init(struct clk *clk)
               pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
 }
 
-static struct clk_ops sh7201_master_clk_ops = {
+static struct sh_clk_ops sh7201_master_clk_ops = {
        .init           = master_clk_init,
 };
 
@@ -40,7 +40,7 @@ static unsigned long module_clk_recalc(struct clk *clk)
        return clk->parent->rate / pfc_divisors[idx];
 }
 
-static struct clk_ops sh7201_module_clk_ops = {
+static struct sh_clk_ops sh7201_module_clk_ops = {
        .recalc         = module_clk_recalc,
 };
 
@@ -50,7 +50,7 @@ static unsigned long bus_clk_recalc(struct clk *clk)
        return clk->parent->rate / pfc_divisors[idx];
 }
 
-static struct clk_ops sh7201_bus_clk_ops = {
+static struct sh_clk_ops sh7201_bus_clk_ops = {
        .recalc         = bus_clk_recalc,
 };
 
@@ -60,18 +60,18 @@ static unsigned long cpu_clk_recalc(struct clk *clk)
        return clk->parent->rate / ifc_divisors[idx];
 }
 
-static struct clk_ops sh7201_cpu_clk_ops = {
+static struct sh_clk_ops sh7201_cpu_clk_ops = {
        .recalc         = cpu_clk_recalc,
 };
 
-static struct clk_ops *sh7201_clk_ops[] = {
+static struct sh_clk_ops *sh7201_clk_ops[] = {
        &sh7201_master_clk_ops,
        &sh7201_module_clk_ops,
        &sh7201_bus_clk_ops,
        &sh7201_cpu_clk_ops,
 };
 
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
 {
        if (test_mode_pin(MODE_PIN1 | MODE_PIN0))
                pll2_mult = 1;
index 95a008e8b7353a0525bd0cc313080f4bd6da3930..529f719b6e33541e078e97d49b7637cef3219678 100644 (file)
@@ -32,7 +32,7 @@ static void master_clk_init(struct clk *clk)
        clk->rate *= pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0003] * pll2_mult;
 }
 
-static struct clk_ops sh7203_master_clk_ops = {
+static struct sh_clk_ops sh7203_master_clk_ops = {
        .init           = master_clk_init,
 };
 
@@ -42,7 +42,7 @@ static unsigned long module_clk_recalc(struct clk *clk)
        return clk->parent->rate / pfc_divisors[idx];
 }
 
-static struct clk_ops sh7203_module_clk_ops = {
+static struct sh_clk_ops sh7203_module_clk_ops = {
        .recalc         = module_clk_recalc,
 };
 
@@ -52,22 +52,22 @@ static unsigned long bus_clk_recalc(struct clk *clk)
        return clk->parent->rate / pfc_divisors[idx-2];
 }
 
-static struct clk_ops sh7203_bus_clk_ops = {
+static struct sh_clk_ops sh7203_bus_clk_ops = {
        .recalc         = bus_clk_recalc,
 };
 
-static struct clk_ops sh7203_cpu_clk_ops = {
+static struct sh_clk_ops sh7203_cpu_clk_ops = {
        .recalc         = followparent_recalc,
 };
 
-static struct clk_ops *sh7203_clk_ops[] = {
+static struct sh_clk_ops *sh7203_clk_ops[] = {
        &sh7203_master_clk_ops,
        &sh7203_module_clk_ops,
        &sh7203_bus_clk_ops,
        &sh7203_cpu_clk_ops,
 };
 
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
 {
        if (test_mode_pin(MODE_PIN1))
                pll2_mult = 4;
index 3c314d7cd6e6105d6f97f8d849d7cf6a47418c11..1777898346784fe76f1551d6f14e29650ac609b8 100644 (file)
@@ -29,7 +29,7 @@ static void master_clk_init(struct clk *clk)
        clk->rate *= pll2_mult * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
 }
 
-static struct clk_ops sh7206_master_clk_ops = {
+static struct sh_clk_ops sh7206_master_clk_ops = {
        .init           = master_clk_init,
 };
 
@@ -39,7 +39,7 @@ static unsigned long module_clk_recalc(struct clk *clk)
        return clk->parent->rate / pfc_divisors[idx];
 }
 
-static struct clk_ops sh7206_module_clk_ops = {
+static struct sh_clk_ops sh7206_module_clk_ops = {
        .recalc         = module_clk_recalc,
 };
 
@@ -48,7 +48,7 @@ static unsigned long bus_clk_recalc(struct clk *clk)
        return clk->parent->rate / pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
 }
 
-static struct clk_ops sh7206_bus_clk_ops = {
+static struct sh_clk_ops sh7206_bus_clk_ops = {
        .recalc         = bus_clk_recalc,
 };
 
@@ -58,18 +58,18 @@ static unsigned long cpu_clk_recalc(struct clk *clk)
        return clk->parent->rate / ifc_divisors[idx];
 }
 
-static struct clk_ops sh7206_cpu_clk_ops = {
+static struct sh_clk_ops sh7206_cpu_clk_ops = {
        .recalc         = cpu_clk_recalc,
 };
 
-static struct clk_ops *sh7206_clk_ops[] = {
+static struct sh_clk_ops *sh7206_clk_ops[] = {
        &sh7206_master_clk_ops,
        &sh7206_module_clk_ops,
        &sh7206_bus_clk_ops,
        &sh7206_cpu_clk_ops,
 };
 
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
 {
        if (test_mode_pin(MODE_PIN2 | MODE_PIN1 | MODE_PIN0))
                pll2_mult = 1;
index b78384afac090de66a7e04e1ff14b274fff5ff9f..90faa44ca94d191db1c1e2f8813956685cc6a53d 100644 (file)
@@ -34,7 +34,7 @@ static void master_clk_init(struct clk *clk)
        clk->rate *= pfc_divisors[idx];
 }
 
-static struct clk_ops sh3_master_clk_ops = {
+static struct sh_clk_ops sh3_master_clk_ops = {
        .init           = master_clk_init,
 };
 
@@ -46,7 +46,7 @@ static unsigned long module_clk_recalc(struct clk *clk)
        return clk->parent->rate / pfc_divisors[idx];
 }
 
-static struct clk_ops sh3_module_clk_ops = {
+static struct sh_clk_ops sh3_module_clk_ops = {
        .recalc         = module_clk_recalc,
 };
 
@@ -58,7 +58,7 @@ static unsigned long bus_clk_recalc(struct clk *clk)
        return clk->parent->rate / stc_multipliers[idx];
 }
 
-static struct clk_ops sh3_bus_clk_ops = {
+static struct sh_clk_ops sh3_bus_clk_ops = {
        .recalc         = bus_clk_recalc,
 };
 
@@ -70,18 +70,18 @@ static unsigned long cpu_clk_recalc(struct clk *clk)
        return clk->parent->rate / ifc_divisors[idx];
 }
 
-static struct clk_ops sh3_cpu_clk_ops = {
+static struct sh_clk_ops sh3_cpu_clk_ops = {
        .recalc         = cpu_clk_recalc,
 };
 
-static struct clk_ops *sh3_clk_ops[] = {
+static struct sh_clk_ops *sh3_clk_ops[] = {
        &sh3_master_clk_ops,
        &sh3_module_clk_ops,
        &sh3_bus_clk_ops,
        &sh3_cpu_clk_ops,
 };
 
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
 {
        if (idx < ARRAY_SIZE(sh3_clk_ops))
                *ops = sh3_clk_ops[idx];
index 0ecea1451c6f079db7c0e9856c83077589d6353a..a8da4a9986b3aee646d619d8c5dce551deee05b9 100644 (file)
@@ -35,7 +35,7 @@ static void master_clk_init(struct clk *clk)
        clk->rate *= pfc_divisors[__raw_readw(FRQCR) & 0x0003];
 }
 
-static struct clk_ops sh7705_master_clk_ops = {
+static struct sh_clk_ops sh7705_master_clk_ops = {
        .init           = master_clk_init,
 };
 
@@ -45,7 +45,7 @@ static unsigned long module_clk_recalc(struct clk *clk)
        return clk->parent->rate / pfc_divisors[idx];
 }
 
-static struct clk_ops sh7705_module_clk_ops = {
+static struct sh_clk_ops sh7705_module_clk_ops = {
        .recalc         = module_clk_recalc,
 };
 
@@ -55,7 +55,7 @@ static unsigned long bus_clk_recalc(struct clk *clk)
        return clk->parent->rate / stc_multipliers[idx];
 }
 
-static struct clk_ops sh7705_bus_clk_ops = {
+static struct sh_clk_ops sh7705_bus_clk_ops = {
        .recalc         = bus_clk_recalc,
 };
 
@@ -65,18 +65,18 @@ static unsigned long cpu_clk_recalc(struct clk *clk)
        return clk->parent->rate / ifc_divisors[idx];
 }
 
-static struct clk_ops sh7705_cpu_clk_ops = {
+static struct sh_clk_ops sh7705_cpu_clk_ops = {
        .recalc         = cpu_clk_recalc,
 };
 
-static struct clk_ops *sh7705_clk_ops[] = {
+static struct sh_clk_ops *sh7705_clk_ops[] = {
        &sh7705_master_clk_ops,
        &sh7705_module_clk_ops,
        &sh7705_bus_clk_ops,
        &sh7705_cpu_clk_ops,
 };
 
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
 {
        if (idx < ARRAY_SIZE(sh7705_clk_ops))
                *ops = sh7705_clk_ops[idx];
index 6f9ff8b57dd69a9d849c9c67631021b4472be255..a4088e5b2203209e02d5dda307a2eef0b7aa1839 100644 (file)
@@ -30,7 +30,7 @@ static void master_clk_init(struct clk *clk)
        clk->rate *= pfc_divisors[idx];
 }
 
-static struct clk_ops sh7706_master_clk_ops = {
+static struct sh_clk_ops sh7706_master_clk_ops = {
        .init           = master_clk_init,
 };
 
@@ -42,7 +42,7 @@ static unsigned long module_clk_recalc(struct clk *clk)
        return clk->parent->rate / pfc_divisors[idx];
 }
 
-static struct clk_ops sh7706_module_clk_ops = {
+static struct sh_clk_ops sh7706_module_clk_ops = {
        .recalc         = module_clk_recalc,
 };
 
@@ -54,7 +54,7 @@ static unsigned long bus_clk_recalc(struct clk *clk)
        return clk->parent->rate / stc_multipliers[idx];
 }
 
-static struct clk_ops sh7706_bus_clk_ops = {
+static struct sh_clk_ops sh7706_bus_clk_ops = {
        .recalc         = bus_clk_recalc,
 };
 
@@ -66,18 +66,18 @@ static unsigned long cpu_clk_recalc(struct clk *clk)
        return clk->parent->rate / ifc_divisors[idx];
 }
 
-static struct clk_ops sh7706_cpu_clk_ops = {
+static struct sh_clk_ops sh7706_cpu_clk_ops = {
        .recalc         = cpu_clk_recalc,
 };
 
-static struct clk_ops *sh7706_clk_ops[] = {
+static struct sh_clk_ops *sh7706_clk_ops[] = {
        &sh7706_master_clk_ops,
        &sh7706_module_clk_ops,
        &sh7706_bus_clk_ops,
        &sh7706_cpu_clk_ops,
 };
 
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
 {
        if (idx < ARRAY_SIZE(sh7706_clk_ops))
                *ops = sh7706_clk_ops[idx];
index f302ba09e681f1f2ec5bd9ee21495b1247980a1d..54a6d4bcc0db770a8640a72bbc093ca4847ec0ce 100644 (file)
@@ -30,7 +30,7 @@ static void master_clk_init(struct clk *clk)
        clk->rate *= pfc_divisors[idx];
 }
 
-static struct clk_ops sh7709_master_clk_ops = {
+static struct sh_clk_ops sh7709_master_clk_ops = {
        .init           = master_clk_init,
 };
 
@@ -42,7 +42,7 @@ static unsigned long module_clk_recalc(struct clk *clk)
        return clk->parent->rate / pfc_divisors[idx];
 }
 
-static struct clk_ops sh7709_module_clk_ops = {
+static struct sh_clk_ops sh7709_module_clk_ops = {
        .recalc         = module_clk_recalc,
 };
 
@@ -55,7 +55,7 @@ static unsigned long bus_clk_recalc(struct clk *clk)
        return clk->parent->rate * stc_multipliers[idx];
 }
 
-static struct clk_ops sh7709_bus_clk_ops = {
+static struct sh_clk_ops sh7709_bus_clk_ops = {
        .recalc         = bus_clk_recalc,
 };
 
@@ -67,18 +67,18 @@ static unsigned long cpu_clk_recalc(struct clk *clk)
        return clk->parent->rate / ifc_divisors[idx];
 }
 
-static struct clk_ops sh7709_cpu_clk_ops = {
+static struct sh_clk_ops sh7709_cpu_clk_ops = {
        .recalc         = cpu_clk_recalc,
 };
 
-static struct clk_ops *sh7709_clk_ops[] = {
+static struct sh_clk_ops *sh7709_clk_ops[] = {
        &sh7709_master_clk_ops,
        &sh7709_module_clk_ops,
        &sh7709_bus_clk_ops,
        &sh7709_cpu_clk_ops,
 };
 
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
 {
        if (idx < ARRAY_SIZE(sh7709_clk_ops))
                *ops = sh7709_clk_ops[idx];
index 29a87d8946a42e66e81e69fb80da9ce4fd8e431c..ce601b2e39769aebae2a9e6f4963368fe9aad116 100644 (file)
@@ -29,7 +29,7 @@ static void master_clk_init(struct clk *clk)
        clk->rate *= md_table[__raw_readw(FRQCR) & 0x0007];
 }
 
-static struct clk_ops sh7710_master_clk_ops = {
+static struct sh_clk_ops sh7710_master_clk_ops = {
        .init           = master_clk_init,
 };
 
@@ -39,7 +39,7 @@ static unsigned long module_clk_recalc(struct clk *clk)
        return clk->parent->rate / md_table[idx];
 }
 
-static struct clk_ops sh7710_module_clk_ops = {
+static struct sh_clk_ops sh7710_module_clk_ops = {
        .recalc         = module_clk_recalc,
 };
 
@@ -49,7 +49,7 @@ static unsigned long bus_clk_recalc(struct clk *clk)
        return clk->parent->rate / md_table[idx];
 }
 
-static struct clk_ops sh7710_bus_clk_ops = {
+static struct sh_clk_ops sh7710_bus_clk_ops = {
        .recalc         = bus_clk_recalc,
 };
 
@@ -59,18 +59,18 @@ static unsigned long cpu_clk_recalc(struct clk *clk)
        return clk->parent->rate / md_table[idx];
 }
 
-static struct clk_ops sh7710_cpu_clk_ops = {
+static struct sh_clk_ops sh7710_cpu_clk_ops = {
        .recalc         = cpu_clk_recalc,
 };
 
-static struct clk_ops *sh7710_clk_ops[] = {
+static struct sh_clk_ops *sh7710_clk_ops[] = {
        &sh7710_master_clk_ops,
        &sh7710_module_clk_ops,
        &sh7710_bus_clk_ops,
        &sh7710_cpu_clk_ops,
 };
 
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
 {
        if (idx < ARRAY_SIZE(sh7710_clk_ops))
                *ops = sh7710_clk_ops[idx];
index b0d0c5203996926c971ff14c67ffb8ad6578f671..21438a9a1ae1c5654d96500c78a3daa4cbe54f47 100644 (file)
@@ -29,7 +29,7 @@ static void master_clk_init(struct clk *clk)
        clk->rate *= multipliers[idx];
 }
 
-static struct clk_ops sh7712_master_clk_ops = {
+static struct sh_clk_ops sh7712_master_clk_ops = {
        .init           = master_clk_init,
 };
 
@@ -41,7 +41,7 @@ static unsigned long module_clk_recalc(struct clk *clk)
        return clk->parent->rate / divisors[idx];
 }
 
-static struct clk_ops sh7712_module_clk_ops = {
+static struct sh_clk_ops sh7712_module_clk_ops = {
        .recalc         = module_clk_recalc,
 };
 
@@ -53,17 +53,17 @@ static unsigned long cpu_clk_recalc(struct clk *clk)
        return clk->parent->rate / divisors[idx];
 }
 
-static struct clk_ops sh7712_cpu_clk_ops = {
+static struct sh_clk_ops sh7712_cpu_clk_ops = {
        .recalc         = cpu_clk_recalc,
 };
 
-static struct clk_ops *sh7712_clk_ops[] = {
+static struct sh_clk_ops *sh7712_clk_ops[] = {
        &sh7712_master_clk_ops,
        &sh7712_module_clk_ops,
        &sh7712_cpu_clk_ops,
 };
 
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
 {
        if (idx < ARRAY_SIZE(sh7712_clk_ops))
                *ops = sh7712_clk_ops[idx];
index f4e262adb39ed9ed8a450a9ec370bb8b533cf53a..4b5bab5f875f653966f0ba55007ff072c7a0ae24 100644 (file)
@@ -41,7 +41,7 @@ static inline int frqcr3_lookup(struct clk *clk, unsigned long rate)
        return 5;
 }
 
-static struct clk_ops sh4202_emi_clk_ops = {
+static struct sh_clk_ops sh4202_emi_clk_ops = {
        .recalc         = emi_clk_recalc,
 };
 
@@ -56,7 +56,7 @@ static unsigned long femi_clk_recalc(struct clk *clk)
        return clk->parent->rate / frqcr3_divisors[idx];
 }
 
-static struct clk_ops sh4202_femi_clk_ops = {
+static struct sh_clk_ops sh4202_femi_clk_ops = {
        .recalc         = femi_clk_recalc,
 };
 
@@ -130,7 +130,7 @@ static int shoc_clk_set_rate(struct clk *clk, unsigned long rate)
        return 0;
 }
 
-static struct clk_ops sh4202_shoc_clk_ops = {
+static struct sh_clk_ops sh4202_shoc_clk_ops = {
        .init           = shoc_clk_init,
        .recalc         = shoc_clk_recalc,
        .set_rate       = shoc_clk_set_rate,
index 5add75c1f53954ef1bdaaa7fbd64912d99193c5a..99e5ec8b483df24fc854700fc77386e0c3694912 100644 (file)
@@ -31,7 +31,7 @@ static void master_clk_init(struct clk *clk)
        clk->rate *= pfc_divisors[__raw_readw(FRQCR) & 0x0007];
 }
 
-static struct clk_ops sh4_master_clk_ops = {
+static struct sh_clk_ops sh4_master_clk_ops = {
        .init           = master_clk_init,
 };
 
@@ -41,7 +41,7 @@ static unsigned long module_clk_recalc(struct clk *clk)
        return clk->parent->rate / pfc_divisors[idx];
 }
 
-static struct clk_ops sh4_module_clk_ops = {
+static struct sh_clk_ops sh4_module_clk_ops = {
        .recalc         = module_clk_recalc,
 };
 
@@ -51,7 +51,7 @@ static unsigned long bus_clk_recalc(struct clk *clk)
        return clk->parent->rate / bfc_divisors[idx];
 }
 
-static struct clk_ops sh4_bus_clk_ops = {
+static struct sh_clk_ops sh4_bus_clk_ops = {
        .recalc         = bus_clk_recalc,
 };
 
@@ -61,18 +61,18 @@ static unsigned long cpu_clk_recalc(struct clk *clk)
        return clk->parent->rate / ifc_divisors[idx];
 }
 
-static struct clk_ops sh4_cpu_clk_ops = {
+static struct sh_clk_ops sh4_cpu_clk_ops = {
        .recalc         = cpu_clk_recalc,
 };
 
-static struct clk_ops *sh4_clk_ops[] = {
+static struct sh_clk_ops *sh4_clk_ops[] = {
        &sh4_master_clk_ops,
        &sh4_module_clk_ops,
        &sh4_bus_clk_ops,
        &sh4_cpu_clk_ops,
 };
 
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
 {
        if (idx < ARRAY_SIZE(sh4_clk_ops))
                *ops = sh4_clk_ops[idx];
index 70e45bdaadc7991805de4fdc3672d95f3fb76afc..ea01a72f1b94f16892734df4a336e4b1f756f7c1 100644 (file)
@@ -61,7 +61,7 @@ static unsigned long dll_recalc(struct clk *clk)
        return clk->parent->rate * mult;
 }
 
-static struct clk_ops dll_clk_ops = {
+static struct sh_clk_ops dll_clk_ops = {
        .recalc         = dll_recalc,
 };
 
@@ -81,7 +81,7 @@ static unsigned long pll_recalc(struct clk *clk)
        return clk->parent->rate * mult;
 }
 
-static struct clk_ops pll_clk_ops = {
+static struct sh_clk_ops pll_clk_ops = {
        .recalc         = pll_recalc,
 };
 
index 3c3165000c52b2c76ce6447fa922349a89c23fa2..7ac07b4f75de3c01982c5a4c2df50bb67cae8a86 100644 (file)
@@ -61,7 +61,7 @@ static unsigned long dll_recalc(struct clk *clk)
        return clk->parent->rate * mult;
 }
 
-static struct clk_ops dll_clk_ops = {
+static struct sh_clk_ops dll_clk_ops = {
        .recalc         = dll_recalc,
 };
 
@@ -84,7 +84,7 @@ static unsigned long pll_recalc(struct clk *clk)
        return (clk->parent->rate * mult) / div;
 }
 
-static struct clk_ops pll_clk_ops = {
+static struct sh_clk_ops pll_clk_ops = {
        .recalc         = pll_recalc,
 };
 
index 212c72ef959c5bdc50c358247194072358a60b81..8e1f97010c0d7ac9c792c23a5b09197508caeed5 100644 (file)
@@ -64,7 +64,7 @@ static unsigned long dll_recalc(struct clk *clk)
        return clk->parent->rate * mult;
 }
 
-static struct clk_ops dll_clk_ops = {
+static struct sh_clk_ops dll_clk_ops = {
        .recalc         = dll_recalc,
 };
 
@@ -87,7 +87,7 @@ static unsigned long pll_recalc(struct clk *clk)
        return (clk->parent->rate * mult) / div;
 }
 
-static struct clk_ops pll_clk_ops = {
+static struct sh_clk_ops pll_clk_ops = {
        .recalc         = pll_recalc,
 };
 
index 2f8c9179da47daaf267daac0324aad65b93a948d..35f75cf0c7e57b5dfe02f1fb7dc93e1156634016 100644 (file)
@@ -65,7 +65,7 @@ static unsigned long dll_recalc(struct clk *clk)
        return clk->parent->rate * mult;
 }
 
-static struct clk_ops dll_clk_ops = {
+static struct sh_clk_ops dll_clk_ops = {
        .recalc         = dll_recalc,
 };
 
@@ -88,7 +88,7 @@ static unsigned long pll_recalc(struct clk *clk)
        return (clk->parent->rate * mult) / div;
 }
 
-static struct clk_ops pll_clk_ops = {
+static struct sh_clk_ops pll_clk_ops = {
        .recalc         = pll_recalc,
 };
 
index 70bd96646f422641b223aeed33adc533561e4112..2a87901673febed3df329d47d8bf21acdabb4530 100644 (file)
@@ -70,7 +70,7 @@ static unsigned long fll_recalc(struct clk *clk)
        return (clk->parent->rate * mult) / div;
 }
 
-static struct clk_ops fll_clk_ops = {
+static struct sh_clk_ops fll_clk_ops = {
        .recalc         = fll_recalc,
 };
 
@@ -90,7 +90,7 @@ static unsigned long pll_recalc(struct clk *clk)
        return clk->parent->rate * mult;
 }
 
-static struct clk_ops pll_clk_ops = {
+static struct sh_clk_ops pll_clk_ops = {
        .recalc         = pll_recalc,
 };
 
@@ -105,7 +105,7 @@ static unsigned long div3_recalc(struct clk *clk)
        return clk->parent->rate / 3;
 }
 
-static struct clk_ops div3_clk_ops = {
+static struct sh_clk_ops div3_clk_ops = {
        .recalc         = div3_recalc,
 };
 
index 0bd21c82151b6db75609c3411cb900184119dd6e..5853989586ed6a2d4687937d38c80381106eea0e 100644 (file)
@@ -33,7 +33,7 @@ static unsigned long pll_recalc(struct clk *clk)
        return clk->parent->rate * multiplier;
 }
 
-static struct clk_ops pll_clk_ops = {
+static struct sh_clk_ops pll_clk_ops = {
        .recalc         = pll_recalc,
 };
 
index 2d4c7fd79c025515adcca670a0d5bbccc6ab04f1..7707e35aea46230b6f5c3a8e86528cbc36d8c4ce 100644 (file)
@@ -27,7 +27,7 @@ static void master_clk_init(struct clk *clk)
        clk->rate *= p0fc_divisors[(__raw_readl(FRQCR) >> 4) & 0x07];
 }
 
-static struct clk_ops sh7763_master_clk_ops = {
+static struct sh_clk_ops sh7763_master_clk_ops = {
        .init           = master_clk_init,
 };
 
@@ -37,7 +37,7 @@ static unsigned long module_clk_recalc(struct clk *clk)
        return clk->parent->rate / p0fc_divisors[idx];
 }
 
-static struct clk_ops sh7763_module_clk_ops = {
+static struct sh_clk_ops sh7763_module_clk_ops = {
        .recalc         = module_clk_recalc,
 };
 
@@ -47,22 +47,22 @@ static unsigned long bus_clk_recalc(struct clk *clk)
        return clk->parent->rate / bfc_divisors[idx];
 }
 
-static struct clk_ops sh7763_bus_clk_ops = {
+static struct sh_clk_ops sh7763_bus_clk_ops = {
        .recalc         = bus_clk_recalc,
 };
 
-static struct clk_ops sh7763_cpu_clk_ops = {
+static struct sh_clk_ops sh7763_cpu_clk_ops = {
        .recalc         = followparent_recalc,
 };
 
-static struct clk_ops *sh7763_clk_ops[] = {
+static struct sh_clk_ops *sh7763_clk_ops[] = {
        &sh7763_master_clk_ops,
        &sh7763_module_clk_ops,
        &sh7763_bus_clk_ops,
        &sh7763_cpu_clk_ops,
 };
 
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
 {
        if (idx < ARRAY_SIZE(sh7763_clk_ops))
                *ops = sh7763_clk_ops[idx];
@@ -74,7 +74,7 @@ static unsigned long shyway_clk_recalc(struct clk *clk)
        return clk->parent->rate / cfc_divisors[idx];
 }
 
-static struct clk_ops sh7763_shyway_clk_ops = {
+static struct sh_clk_ops sh7763_shyway_clk_ops = {
        .recalc         = shyway_clk_recalc,
 };
 
index 9e3354365d4049970b1b7afae84f86adfd2206ff..5d36f334bb0a74d51ddd00f36ed3cc82e95a2fbb 100644 (file)
@@ -24,7 +24,7 @@ static void master_clk_init(struct clk *clk)
        clk->rate *= pfc_divisors[(__raw_readl(FRQCR) >> 28) & 0x000f];
 }
 
-static struct clk_ops sh7770_master_clk_ops = {
+static struct sh_clk_ops sh7770_master_clk_ops = {
        .init           = master_clk_init,
 };
 
@@ -34,7 +34,7 @@ static unsigned long module_clk_recalc(struct clk *clk)
        return clk->parent->rate / pfc_divisors[idx];
 }
 
-static struct clk_ops sh7770_module_clk_ops = {
+static struct sh_clk_ops sh7770_module_clk_ops = {
        .recalc         = module_clk_recalc,
 };
 
@@ -44,7 +44,7 @@ static unsigned long bus_clk_recalc(struct clk *clk)
        return clk->parent->rate / bfc_divisors[idx];
 }
 
-static struct clk_ops sh7770_bus_clk_ops = {
+static struct sh_clk_ops sh7770_bus_clk_ops = {
        .recalc         = bus_clk_recalc,
 };
 
@@ -54,18 +54,18 @@ static unsigned long cpu_clk_recalc(struct clk *clk)
        return clk->parent->rate / ifc_divisors[idx];
 }
 
-static struct clk_ops sh7770_cpu_clk_ops = {
+static struct sh_clk_ops sh7770_cpu_clk_ops = {
        .recalc         = cpu_clk_recalc,
 };
 
-static struct clk_ops *sh7770_clk_ops[] = {
+static struct sh_clk_ops *sh7770_clk_ops[] = {
        &sh7770_master_clk_ops,
        &sh7770_module_clk_ops,
        &sh7770_bus_clk_ops,
        &sh7770_cpu_clk_ops,
 };
 
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
 {
        if (idx < ARRAY_SIZE(sh7770_clk_ops))
                *ops = sh7770_clk_ops[idx];
index 3b53348fe2fcdac7cd2bf2239fa3741be6d98e62..793dae42a2f8490c536ecfd214255e920fa95adc 100644 (file)
@@ -27,7 +27,7 @@ static void master_clk_init(struct clk *clk)
        clk->rate *= pfc_divisors[__raw_readl(FRQCR) & 0x0003];
 }
 
-static struct clk_ops sh7780_master_clk_ops = {
+static struct sh_clk_ops sh7780_master_clk_ops = {
        .init           = master_clk_init,
 };
 
@@ -37,7 +37,7 @@ static unsigned long module_clk_recalc(struct clk *clk)
        return clk->parent->rate / pfc_divisors[idx];
 }
 
-static struct clk_ops sh7780_module_clk_ops = {
+static struct sh_clk_ops sh7780_module_clk_ops = {
        .recalc         = module_clk_recalc,
 };
 
@@ -47,7 +47,7 @@ static unsigned long bus_clk_recalc(struct clk *clk)
        return clk->parent->rate / bfc_divisors[idx];
 }
 
-static struct clk_ops sh7780_bus_clk_ops = {
+static struct sh_clk_ops sh7780_bus_clk_ops = {
        .recalc         = bus_clk_recalc,
 };
 
@@ -57,18 +57,18 @@ static unsigned long cpu_clk_recalc(struct clk *clk)
        return clk->parent->rate / ifc_divisors[idx];
 }
 
-static struct clk_ops sh7780_cpu_clk_ops = {
+static struct sh_clk_ops sh7780_cpu_clk_ops = {
        .recalc         = cpu_clk_recalc,
 };
 
-static struct clk_ops *sh7780_clk_ops[] = {
+static struct sh_clk_ops *sh7780_clk_ops[] = {
        &sh7780_master_clk_ops,
        &sh7780_module_clk_ops,
        &sh7780_bus_clk_ops,
        &sh7780_cpu_clk_ops,
 };
 
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
 {
        if (idx < ARRAY_SIZE(sh7780_clk_ops))
                *ops = sh7780_clk_ops[idx];
@@ -80,7 +80,7 @@ static unsigned long shyway_clk_recalc(struct clk *clk)
        return clk->parent->rate / cfc_divisors[idx];
 }
 
-static struct clk_ops sh7780_shyway_clk_ops = {
+static struct sh_clk_ops sh7780_shyway_clk_ops = {
        .recalc         = shyway_clk_recalc,
 };
 
index 2b314439d359a30227357bb137771390c126990e..ab1c58f2d101172b6f769d48278795d6e26adbda 100644 (file)
@@ -36,7 +36,7 @@ static unsigned long pll_recalc(struct clk *clk)
        return clk->parent->rate * multiplier;
 }
 
-static struct clk_ops pll_clk_ops = {
+static struct sh_clk_ops pll_clk_ops = {
        .recalc         = pll_recalc,
 };
 
index f6c0c3d5599f663a860a8a6aa38a46c5e654cba9..491709483e109bc75213963b508b6608c55bc9ad 100644 (file)
@@ -38,7 +38,7 @@ static unsigned long pll_recalc(struct clk *clk)
        return clk->parent->rate * multiplier;
 }
 
-static struct clk_ops pll_clk_ops = {
+static struct sh_clk_ops pll_clk_ops = {
        .recalc         = pll_recalc,
 };
 
index bf2d00b8b908705ee49504c99691ddb2268abf5d..0f11b392bf466ef2334c221b02cd64de37134dac 100644 (file)
@@ -32,7 +32,7 @@ static unsigned long pll_recalc(struct clk *clk)
        return clk->parent->rate * 72;
 }
 
-static struct clk_ops pll_clk_ops = {
+static struct sh_clk_ops pll_clk_ops = {
        .recalc         = pll_recalc,
 };
 
index 9cfc19b8dbe465a2f8f9b7f2210bd4e238818dce..c48b93d4c0815b1129d27931f40191b9930b6e59 100644 (file)
@@ -28,7 +28,7 @@ static void master_clk_init(struct clk *clk)
        clk->rate *= ifc_table[idx];
 }
 
-static struct clk_ops sh5_master_clk_ops = {
+static struct sh_clk_ops sh5_master_clk_ops = {
        .init           = master_clk_init,
 };
 
@@ -38,7 +38,7 @@ static unsigned long module_clk_recalc(struct clk *clk)
        return clk->parent->rate / ifc_table[idx];
 }
 
-static struct clk_ops sh5_module_clk_ops = {
+static struct sh_clk_ops sh5_module_clk_ops = {
        .recalc         = module_clk_recalc,
 };
 
@@ -48,7 +48,7 @@ static unsigned long bus_clk_recalc(struct clk *clk)
        return clk->parent->rate / ifc_table[idx];
 }
 
-static struct clk_ops sh5_bus_clk_ops = {
+static struct sh_clk_ops sh5_bus_clk_ops = {
        .recalc         = bus_clk_recalc,
 };
 
@@ -58,18 +58,18 @@ static unsigned long cpu_clk_recalc(struct clk *clk)
        return clk->parent->rate / ifc_table[idx];
 }
 
-static struct clk_ops sh5_cpu_clk_ops = {
+static struct sh_clk_ops sh5_cpu_clk_ops = {
        .recalc         = cpu_clk_recalc,
 };
 
-static struct clk_ops *sh5_clk_ops[] = {
+static struct sh_clk_ops *sh5_clk_ops[] = {
        &sh5_master_clk_ops,
        &sh5_module_clk_ops,
        &sh5_bus_clk_ops,
        &sh5_cpu_clk_ops,
 };
 
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
 {
        cprc_base = (unsigned long)ioremap_nocache(CPRC_BASE, 1024);
        BUG_ON(!cprc_base);
index b37ae706af3ee4e6534dea8872aaef903ac19e0f..20a49ba93cb9d537d3f0149fc2e60cb770c2c43d 100644 (file)
@@ -9,6 +9,7 @@ config UML
        select HAVE_GENERIC_HARDIRQS
        select GENERIC_IRQ_SHOW
        select GENERIC_CPU_DEVICES
+       select GENERIC_IO
 
 config MMU
        bool
index 28688e6d96d795c3f860f5343524584b0cefb994..55c0661e2b5dbcba77a097522e43f109922bb577 100644 (file)
@@ -28,6 +28,7 @@ ifeq ($(SUBARCH),i386)
 endif
 ifeq ($(SUBARCH),x86_64)
         HEADER_ARCH := x86
+       KBUILD_CFLAGS += -mcmodel=large
 endif
 
 HOST_DIR := arch/$(HEADER_ARCH)
@@ -50,7 +51,7 @@ KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/um
 #
 # These apply to USER_CFLAGS to.
 
-KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
+KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ \
        $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap      \
        -Din6addr_loopback=kernel_in6addr_loopback \
        -Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr
@@ -99,7 +100,7 @@ KBUILD_KCONFIG := $(HOST_DIR)/um/Kconfig
 
 archheaders:
        $(Q)$(MAKE) -C '$(srctree)' KBUILD_SRC= \
-               ARCH=$(SUBARCH) O='$(objtree)' archheaders
+               ARCH=$(HEADER_ARCH) O='$(objtree)' archheaders
 
 archprepare: include/generated/user_constants.h
 
index 761f5e1a657ee2d47117b7e15020ed10379e3037..fdc97e2c3d7370d69eb6f07fc133e993c0db8069 100644 (file)
@@ -1,10 +1,8 @@
 #
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24
-# Thu Feb  7 11:48:55 2008
+# Automatically generated file; DO NOT EDIT.
+# User Mode Linux/i386 3.3.0 Kernel Configuration
 #
 CONFIG_DEFCONFIG_LIST="arch/$ARCH/defconfig"
-CONFIG_GENERIC_HARDIRQS=y
 CONFIG_UML=y
 CONFIG_MMU=y
 CONFIG_NO_IOMEM=y
@@ -20,12 +18,10 @@ CONFIG_HZ=100
 #
 # UML-specific options
 #
-# CONFIG_STATIC_LINK is not set
 
 #
 # Host processor type and features
 #
-# CONFIG_M386 is not set
 # CONFIG_M486 is not set
 # CONFIG_M586 is not set
 # CONFIG_M586TSC is not set
@@ -41,17 +37,17 @@ CONFIG_M686=y
 # CONFIG_MCRUSOE is not set
 # CONFIG_MEFFICEON is not set
 # CONFIG_MWINCHIPC6 is not set
-# CONFIG_MWINCHIP2 is not set
 # CONFIG_MWINCHIP3D is not set
+# CONFIG_MELAN is not set
 # CONFIG_MGEODEGX1 is not set
 # CONFIG_MGEODE_LX is not set
 # CONFIG_MCYRIXIII is not set
 # CONFIG_MVIAC3_2 is not set
 # CONFIG_MVIAC7 is not set
-# CONFIG_MPSC is not set
 # CONFIG_MCORE2 is not set
-# CONFIG_GENERIC_CPU is not set
+# CONFIG_MATOM is not set
 # CONFIG_X86_GENERIC is not set
+CONFIG_X86_INTERNODE_CACHE_SHIFT=5
 CONFIG_X86_CMPXCHG=y
 CONFIG_X86_L1_CACHE_SHIFT=5
 CONFIG_X86_XADD=y
@@ -60,47 +56,59 @@ CONFIG_X86_WP_WORKS_OK=y
 CONFIG_X86_INVLPG=y
 CONFIG_X86_BSWAP=y
 CONFIG_X86_POPAD_OK=y
-CONFIG_X86_GOOD_APIC=y
 CONFIG_X86_USE_PPRO_CHECKSUM=y
 CONFIG_X86_TSC=y
+CONFIG_X86_CMPXCHG64=y
 CONFIG_X86_CMOV=y
-CONFIG_X86_MINIMUM_CPU_FAMILY=4
-CONFIG_X86_DEBUGCTLMSR=y
+CONFIG_X86_MINIMUM_CPU_FAMILY=5
+CONFIG_CPU_SUP_INTEL=y
+CONFIG_CPU_SUP_CYRIX_32=y
+CONFIG_CPU_SUP_AMD=y
+CONFIG_CPU_SUP_CENTAUR=y
+CONFIG_CPU_SUP_TRANSMETA_32=y
+CONFIG_CPU_SUP_UMC_32=y
 CONFIG_UML_X86=y
-CONFIG_X86_32=y
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 # CONFIG_64BIT is not set
-CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_X86_32=y
+# CONFIG_X86_64 is not set
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_3_LEVEL_PGTABLES is not set
 CONFIG_ARCH_HAS_SC_SIGNALS=y
 CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA=y
 CONFIG_GENERIC_HWEIGHT=y
+# CONFIG_STATIC_LINK is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_COMPACTION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 CONFIG_LD_SCRIPT_DYN=y
 CONFIG_BINFMT_ELF=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+CONFIG_HAVE_AOUT=y
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_MISC=m
 CONFIG_HOSTFS=y
 # CONFIG_HPPFS is not set
 CONFIG_MCONSOLE=y
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_HIGHMEM is not set
 CONFIG_KERNEL_STACK_ORDER=0
+# CONFIG_MMAPPER is not set
+CONFIG_NO_DMA=y
 
 #
 # General setup
@@ -108,99 +116,169 @@ CONFIG_KERNEL_STACK_ORDER=0
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=128
+CONFIG_CROSS_COMPILE=""
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_DEFAULT_HOSTNAME="(none)"
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_FHANDLE is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
 # CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_SHOW=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TINY_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CPUSETS=y
+CONFIG_PROC_PID_CPUSET=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_MEM_RES_CTLR=y
+CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
+# CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED is not set
+# CONFIG_CGROUP_MEM_RES_CTLR_KMEM is not set
+CONFIG_CGROUP_SCHED=y
 CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
+# CONFIG_CFS_BANDWIDTH is not set
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_BLK_CGROUP=m
+# CONFIG_DEBUG_BLK_CGROUP is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_NET_NS=y
+# CONFIG_SCHED_AUTOGROUP is not set
+CONFIG_MM_OWNER=y
 CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 # CONFIG_EXPERT is not set
 CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
-CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
+# CONFIG_EMBEDDED is not set
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
-# CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
-# CONFIG_HAVE_OPROFILE is not set
-# CONFIG_HAVE_KPROBES is not set
-CONFIG_PROC_PAGE_MONITOR=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=m
+# CONFIG_CFQ_GROUP_IOSCHED is not set
+CONFIG_DEFAULT_DEADLINE=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_PREEMPT_RCU is not set
-CONFIG_BLK_DEV=y
-CONFIG_BLK_DEV_UBD=y
-# CONFIG_BLK_DEV_UBD_SYNC is not set
-CONFIG_BLK_DEV_COW_COMMON=y
-CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_ATA_OVER_ETH is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
 
 #
-# Character Devices
+# UML Character Devices
 #
 CONFIG_STDERR_CONSOLE=y
 CONFIG_STDIO_CONSOLE=y
@@ -214,40 +292,191 @@ CONFIG_XTERM_CHAN=y
 CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
 CONFIG_CON_CHAN="xterm"
 CONFIG_SSL_CHAN="pts"
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-# CONFIG_RAW_DRIVER is not set
-CONFIG_LEGACY_PTY_COUNT=32
-# CONFIG_WATCHDOG is not set
 CONFIG_UML_SOUND=m
 CONFIG_SOUND=m
+CONFIG_SOUND_OSS_CORE=y
 CONFIG_HOSTAUDIO=m
-# CONFIG_HW_RANDOM is not set
-CONFIG_UML_RANDOM=y
-# CONFIG_MMAPPER is not set
+
+#
+# Device Drivers
+#
 
 #
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
+CONFIG_GENERIC_CPU_DEVICES=y
+# CONFIG_DMA_SHARED_BUFFER is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+CONFIG_BLK_DEV=y
+CONFIG_BLK_DEV_UBD=y
+# CONFIG_BLK_DEV_UBD_SYNC is not set
+CONFIG_BLK_DEV_COW_COMMON=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_RBD is not set
+
+#
+# Misc devices
+#
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+
+#
+# Altera FPGA firmware download module
+#
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+CONFIG_DUMMY=m
+# CONFIG_EQUALIZER is not set
+# CONFIG_MII is not set
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+
+#
+# CAIF transport drivers
+#
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_CHELSIO=y
+CONFIG_NET_VENDOR_INTEL=y
+CONFIG_NET_VENDOR_I825XX=y
+CONFIG_NET_VENDOR_MARVELL=y
+CONFIG_NET_VENDOR_NATSEMI=y
+CONFIG_NET_VENDOR_8390=y
+# CONFIG_PHYLIB is not set
+CONFIG_PPP=m
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_FILTER is not set
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPP_ASYNC is not set
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_SLIP=m
+CONFIG_SLHC=m
+# CONFIG_SLIP_COMPRESSED is not set
+# CONFIG_SLIP_SMART is not set
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_WLAN=y
+# CONFIG_HOSTAP is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+
+#
+# Character devices
+#
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=32
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+CONFIG_DEVKMEM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_UML_RANDOM=y
+# CONFIG_R3964 is not set
+# CONFIG_NSC_GPIO is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+
+#
+# Enable Device Drivers -> PPS to see the PTP clock options.
+#
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_REGULATOR is not set
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_BALLOON is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
 
 #
-# Networking
+# Hardware Spinlock drivers
 #
+CONFIG_IOMMU_SUPPORT=y
+# CONFIG_VIRT_DRIVERS is not set
+# CONFIG_PM_DEVFREQ is not set
 CONFIG_NET=y
 
 #
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
+# CONFIG_UNIX_DIAG is not set
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
@@ -257,10 +486,9 @@ CONFIG_XFRM=y
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
 # CONFIG_IP_PNP is not set
 # CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
 # CONFIG_ARPD is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_INET_AH is not set
@@ -274,20 +502,23 @@ CONFIG_INET_XFRM_MODE_BEET=y
 # CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_UDP_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
+# CONFIG_L2TP is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -297,7 +528,14 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_NETPRIO_CGROUP is not set
+CONFIG_BQL=y
 
 #
 # Network testing
@@ -308,16 +546,19 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
 
 #
-# Wireless
+# CFG80211 needs to be enabled for MAC80211
 #
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
 
 #
 # UML Network Devices
@@ -331,75 +572,50 @@ CONFIG_UML_NET_DAEMON=y
 CONFIG_UML_NET_MCAST=y
 # CONFIG_UML_NET_PCAP is not set
 CONFIG_UML_NET_SLIRP=y
-CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
-CONFIG_DUMMY=m
-# CONFIG_BONDING is not set
-# CONFIG_MACVLAN is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-# CONFIG_VETH is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_WAN is not set
-CONFIG_PPP=m
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-# CONFIG_PPP_ASYNC is not set
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-# CONFIG_PPP_BSDCOMP is not set
-# CONFIG_PPP_MPPE is not set
-# CONFIG_PPPOE is not set
-# CONFIG_PPPOL2TP is not set
-CONFIG_SLIP=m
-# CONFIG_SLIP_COMPRESSED is not set
-CONFIG_SLHC=m
-# CONFIG_SLIP_SMART is not set
-# CONFIG_SLIP_MODE_SLIP6 is not set
-# CONFIG_NETCONSOLE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_CONNECTOR is not set
 
 #
 # File systems
 #
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-# CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=y
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_USE_FOR_EXT23=y
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD2=y
+CONFIG_FS_MBCACHE=y
 CONFIG_REISERFS_FS=y
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_REISERFS_FS_XATTR is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_INOTIFY=y
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
 CONFIG_QUOTA=y
 # CONFIG_QUOTA_NETLINK_INTERFACE is not set
 CONFIG_PRINT_QUOTA_WARNING=y
+# CONFIG_QUOTA_DEBUG is not set
 # CONFIG_QFMT_V1 is not set
 # CONFIG_QFMT_V2 is not set
 CONFIG_QUOTACTL=y
-CONFIG_DNOTIFY=y
-CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 # CONFIG_FUSE_FS is not set
 
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
 #
 # CD-ROM/DVD Filesystems
 #
@@ -421,15 +637,14 @@ CONFIG_JOLIET=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_TMPFS_XATTR is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -437,26 +652,26 @@ CONFIG_TMPFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
-# CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
 CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_CODEPAGE_437 is not set
@@ -497,119 +712,191 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
-# CONFIG_DLM is not set
 
 #
 # Security options
 #
 # CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
 # CONFIG_SECURITY is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
-# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=m
 # CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_USER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_ECB is not set
-# CONFIG_CRYPTO_CBC is not set
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_XTS is not set
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_TWOFISH_586 is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
 # CONFIG_CRYPTO_AES_586 is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_CAST5 is not set
 # CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_SEED is not set
 # CONFIG_CRYPTO_SALSA20 is not set
 # CONFIG_CRYPTO_SALSA20_586 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_TWOFISH_586 is not set
+
+#
+# Compression
+#
 # CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_TEST is not set
-# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
-CONFIG_BITREVERSE=m
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_FIRST_BIT=y
+CONFIG_GENERIC_IO=y
 # CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
-CONFIG_CRC32=m
+CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_DMA is not set
-# CONFIG_SCSI_NETLINK is not set
-# CONFIG_MD is not set
-# CONFIG_INPUT is not set
+# CONFIG_CRC8 is not set
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
+# CONFIG_CORDIC is not set
 
 #
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
 CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
-CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_DETECT_HUNG_TASK is not set
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_INFO_REDUCED is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_DEBUG_LIST is not set
+# CONFIG_TEST_LIST_SORT is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 CONFIG_FRAME_POINTER=y
-CONFIG_FORCED_INLINING=y
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
 # CONFIG_SAMPLES is not set
+# CONFIG_TEST_KSTRTOX is not set
 # CONFIG_GPROF is not set
 # CONFIG_GCOV is not set
-# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_EARLY_PRINTK=y
index 8df0fd9024dce6afe7c94d496247a15212c86602..02b5a76e98d9da2038442b03d47c700338af634c 100644 (file)
@@ -27,24 +27,24 @@ struct chan {
        void *data;
 };
 
-extern void chan_interrupt(struct list_head *chans, struct delayed_work *task,
+extern void chan_interrupt(struct line *line,
                           struct tty_struct *tty, int irq);
 extern int parse_chan_pair(char *str, struct line *line, int device,
                           const struct chan_opts *opts, char **error_out);
-extern int write_chan(struct list_head *chans, const char *buf, int len,
+extern int write_chan(struct chan *chan, const char *buf, int len,
                             int write_irq);
-extern int console_write_chan(struct list_head *chans, const char *buf, 
+extern int console_write_chan(struct chan *chan, const char *buf, 
                              int len);
 extern int console_open_chan(struct line *line, struct console *co);
-extern void deactivate_chan(struct list_head *chans, int irq);
-extern void reactivate_chan(struct list_head *chans, int irq);
-extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty);
+extern void deactivate_chan(struct chan *chan, int irq);
+extern void reactivate_chan(struct chan *chan, int irq);
+extern void chan_enable_winch(struct chan *chan, struct tty_struct *tty);
 extern int enable_chan(struct line *line);
-extern void close_chan(struct list_head *chans, int delay_free_irq);
-extern int chan_window_size(struct list_head *chans
+extern void close_chan(struct line *line);
+extern int chan_window_size(struct line *line
                             unsigned short *rows_out, 
                             unsigned short *cols_out);
-extern int chan_config_string(struct list_head *chans, char *str, int size,
+extern int chan_config_string(struct line *line, char *str, int size,
                              char **error_out);
 
 #endif
index 420e2c8007992cc98d1f5ed68ff4be26dad7fa8c..ca4c7ebfd0aa592141021d779f1d49feac0f33a2 100644 (file)
@@ -140,18 +140,18 @@ static int open_chan(struct list_head *chans)
        return err;
 }
 
-void chan_enable_winch(struct list_head *chans, struct tty_struct *tty)
+void chan_enable_winch(struct chan *chan, struct tty_struct *tty)
 {
-       struct list_head *ele;
-       struct chan *chan;
+       if (chan && chan->primary && chan->ops->winch)
+               register_winch(chan->fd, tty);
+}
 
-       list_for_each(ele, chans) {
-               chan = list_entry(ele, struct chan, list);
-               if (chan->primary && chan->output && chan->ops->winch) {
-                       register_winch(chan->fd, tty);
-                       return;
-               }
-       }
+static void line_timer_cb(struct work_struct *work)
+{
+       struct line *line = container_of(work, struct line, task.work);
+
+       if (!line->throttled)
+               chan_interrupt(line, line->tty, line->driver->read_irq);
 }
 
 int enable_chan(struct line *line)
@@ -160,6 +160,8 @@ int enable_chan(struct line *line)
        struct chan *chan;
        int err;
 
+       INIT_DELAYED_WORK(&line->task, line_timer_cb);
+
        list_for_each(ele, &line->chan_list) {
                chan = list_entry(ele, struct chan, list);
                err = open_one_chan(chan);
@@ -183,7 +185,7 @@ int enable_chan(struct line *line)
        return 0;
 
  out_close:
-       close_chan(&line->chan_list, 0);
+       close_chan(line);
        return err;
 }
 
@@ -244,7 +246,7 @@ static void close_one_chan(struct chan *chan, int delay_free_irq)
        chan->fd = -1;
 }
 
-void close_chan(struct list_head *chans, int delay_free_irq)
+void close_chan(struct line *line)
 {
        struct chan *chan;
 
@@ -253,77 +255,50 @@ void close_chan(struct list_head *chans, int delay_free_irq)
         * state.  Then, the first one opened will have the original state,
         * so it must be the last closed.
         */
-       list_for_each_entry_reverse(chan, chans, list) {
-               close_one_chan(chan, delay_free_irq);
+       list_for_each_entry_reverse(chan, &line->chan_list, list) {
+               close_one_chan(chan, 0);
        }
 }
 
-void deactivate_chan(struct list_head *chans, int irq)
+void deactivate_chan(struct chan *chan, int irq)
 {
-       struct list_head *ele;
-
-       struct chan *chan;
-       list_for_each(ele, chans) {
-               chan = list_entry(ele, struct chan, list);
-
-               if (chan->enabled && chan->input)
-                       deactivate_fd(chan->fd, irq);
-       }
+       if (chan && chan->enabled)
+               deactivate_fd(chan->fd, irq);
 }
 
-void reactivate_chan(struct list_head *chans, int irq)
+void reactivate_chan(struct chan *chan, int irq)
 {
-       struct list_head *ele;
-       struct chan *chan;
-
-       list_for_each(ele, chans) {
-               chan = list_entry(ele, struct chan, list);
-
-               if (chan->enabled && chan->input)
-                       reactivate_fd(chan->fd, irq);
-       }
+       if (chan && chan->enabled)
+               reactivate_fd(chan->fd, irq);
 }
 
-int write_chan(struct list_head *chans, const char *buf, int len,
+int write_chan(struct chan *chan, const char *buf, int len,
               int write_irq)
 {
-       struct list_head *ele;
-       struct chan *chan = NULL;
        int n, ret = 0;
 
-       if (len == 0)
+       if (len == 0 || !chan || !chan->ops->write)
                return 0;
 
-       list_for_each(ele, chans) {
-               chan = list_entry(ele, struct chan, list);
-               if (!chan->output || (chan->ops->write == NULL))
-                       continue;
-
-               n = chan->ops->write(chan->fd, buf, len, chan->data);
-               if (chan->primary) {
-                       ret = n;
-                       if ((ret == -EAGAIN) || ((ret >= 0) && (ret < len)))
-                               reactivate_fd(chan->fd, write_irq);
-               }
+       n = chan->ops->write(chan->fd, buf, len, chan->data);
+       if (chan->primary) {
+               ret = n;
+               if ((ret == -EAGAIN) || ((ret >= 0) && (ret < len)))
+                       reactivate_fd(chan->fd, write_irq);
        }
        return ret;
 }
 
-int console_write_chan(struct list_head *chans, const char *buf, int len)
+int console_write_chan(struct chan *chan, const char *buf, int len)
 {
-       struct list_head *ele;
-       struct chan *chan;
        int n, ret = 0;
 
-       list_for_each(ele, chans) {
-               chan = list_entry(ele, struct chan, list);
-               if (!chan->output || (chan->ops->console_write == NULL))
-                       continue;
+       if (!chan || !chan->ops->console_write)
+               return 0;
 
-               n = chan->ops->console_write(chan->fd, buf, len);
-               if (chan->primary)
-                       ret = n;
-       }
+       n = chan->ops->console_write(chan->fd, buf, len);
+       if (chan->primary)
+               ret = n;
        return ret;
 }
 
@@ -340,20 +315,24 @@ int console_open_chan(struct line *line, struct console *co)
        return 0;
 }
 
-int chan_window_size(struct list_head *chans, unsigned short *rows_out,
+int chan_window_size(struct line *line, unsigned short *rows_out,
                      unsigned short *cols_out)
 {
-       struct list_head *ele;
        struct chan *chan;
 
-       list_for_each(ele, chans) {
-               chan = list_entry(ele, struct chan, list);
-               if (chan->primary) {
-                       if (chan->ops->window_size == NULL)
-                               return 0;
-                       return chan->ops->window_size(chan->fd, chan->data,
-                                                     rows_out, cols_out);
-               }
+       chan = line->chan_in;
+       if (chan && chan->primary) {
+               if (chan->ops->window_size == NULL)
+                       return 0;
+               return chan->ops->window_size(chan->fd, chan->data,
+                                             rows_out, cols_out);
+       }
+       chan = line->chan_out;
+       if (chan && chan->primary) {
+               if (chan->ops->window_size == NULL)
+                       return 0;
+               return chan->ops->window_size(chan->fd, chan->data,
+                                             rows_out, cols_out);
        }
        return 0;
 }
@@ -429,21 +408,15 @@ static int chan_pair_config_string(struct chan *in, struct chan *out,
        return n;
 }
 
-int chan_config_string(struct list_head *chans, char *str, int size,
+int chan_config_string(struct line *line, char *str, int size,
                       char **error_out)
 {
-       struct list_head *ele;
-       struct chan *chan, *in = NULL, *out = NULL;
+       struct chan *in = line->chan_in, *out = line->chan_out;
 
-       list_for_each(ele, chans) {
-               chan = list_entry(ele, struct chan, list);
-               if (!chan->primary)
-                       continue;
-               if (chan->input)
-                       in = chan;
-               if (chan->output)
-                       out = chan;
-       }
+       if (in && !in->primary)
+               in = NULL;
+       if (out && !out->primary)
+               out = NULL;
 
        return chan_pair_config_string(in, out, str, size, error_out);
 }
@@ -547,10 +520,14 @@ int parse_chan_pair(char *str, struct line *line, int device,
        char *in, *out;
 
        if (!list_empty(chans)) {
+               line->chan_in = line->chan_out = NULL;
                free_chan(chans);
                INIT_LIST_HEAD(chans);
        }
 
+       if (!str)
+               return 0;
+
        out = strchr(str, ',');
        if (out != NULL) {
                in = str;
@@ -562,6 +539,7 @@ int parse_chan_pair(char *str, struct line *line, int device,
 
                new->input = 1;
                list_add(&new->list, chans);
+               line->chan_in = new;
 
                new = parse_chan(line, out, device, opts, error_out);
                if (new == NULL)
@@ -569,6 +547,7 @@ int parse_chan_pair(char *str, struct line *line, int device,
 
                list_add(&new->list, chans);
                new->output = 1;
+               line->chan_out = new;
        }
        else {
                new = parse_chan(line, str, device, opts, error_out);
@@ -578,43 +557,42 @@ int parse_chan_pair(char *str, struct line *line, int device,
                list_add(&new->list, chans);
                new->input = 1;
                new->output = 1;
+               line->chan_in = line->chan_out = new;
        }
        return 0;
 }
 
-void chan_interrupt(struct list_head *chans, struct delayed_work *task,
-                   struct tty_struct *tty, int irq)
+void chan_interrupt(struct line *line, struct tty_struct *tty, int irq)
 {
-       struct list_head *ele, *next;
-       struct chan *chan;
+       struct chan *chan = line->chan_in;
        int err;
        char c;
 
-       list_for_each_safe(ele, next, chans) {
-               chan = list_entry(ele, struct chan, list);
-               if (!chan->input || (chan->ops->read == NULL))
-                       continue;
-               do {
-                       if (tty && !tty_buffer_request_room(tty, 1)) {
-                               schedule_delayed_work(task, 1);
-                               goto out;
-                       }
-                       err = chan->ops->read(chan->fd, &c, chan->data);
-                       if (err > 0)
-                               tty_receive_char(tty, c);
-               } while (err > 0);
-
-               if (err == 0)
-                       reactivate_fd(chan->fd, irq);
-               if (err == -EIO) {
-                       if (chan->primary) {
-                               if (tty != NULL)
-                                       tty_hangup(tty);
-                               close_chan(chans, 1);
-                               return;
-                       }
-                       else close_one_chan(chan, 1);
+       if (!chan || !chan->ops->read)
+               goto out;
+
+       do {
+               if (tty && !tty_buffer_request_room(tty, 1)) {
+                       schedule_delayed_work(&line->task, 1);
+                       goto out;
                }
+               err = chan->ops->read(chan->fd, &c, chan->data);
+               if (err > 0)
+                       tty_receive_char(tty, c);
+       } while (err > 0);
+
+       if (err == 0)
+               reactivate_fd(chan->fd, irq);
+       if (err == -EIO) {
+               if (chan->primary) {
+                       if (tty != NULL)
+                               tty_hangup(tty);
+                       if (line->chan_out != chan)
+                               close_one_chan(line->chan_out, 1);
+               }
+               close_one_chan(chan, 1);
+               if (chan->primary)
+                       return;
        }
  out:
        if (tty)
index 9b9ced85b70378457479215c85558ebb25e05388..6257b7a6e1afb7f8cdabc672beac7c6f95d6f73f 100644 (file)
@@ -14,8 +14,6 @@ struct chan_opts {
        const int raw;
 };
 
-enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE };
-
 struct chan_ops {
        char *type;
        void *(*init)(char *, int, const struct chan_opts *);
index c1cf2206b84bcebb6326a48787c93f965326763b..4ab0d9c0911c7bd6fe42ac7369211ef1f4914d07 100644 (file)
@@ -21,19 +21,10 @@ static irqreturn_t line_interrupt(int irq, void *data)
        struct line *line = chan->line;
 
        if (line)
-               chan_interrupt(&line->chan_list, &line->task, line->tty, irq);
+               chan_interrupt(line, line->tty, irq);
        return IRQ_HANDLED;
 }
 
-static void line_timer_cb(struct work_struct *work)
-{
-       struct line *line = container_of(work, struct line, task.work);
-
-       if (!line->throttled)
-               chan_interrupt(&line->chan_list, &line->task, line->tty,
-                              line->driver->read_irq);
-}
-
 /*
  * Returns the free space inside the ring buffer of this line.
  *
@@ -145,7 +136,7 @@ static int flush_buffer(struct line *line)
                /* line->buffer + LINE_BUFSIZE is the end of the buffer! */
                count = line->buffer + LINE_BUFSIZE - line->head;
 
-               n = write_chan(&line->chan_list, line->head, count,
+               n = write_chan(line->chan_out, line->head, count,
                               line->driver->write_irq);
                if (n < 0)
                        return n;
@@ -162,7 +153,7 @@ static int flush_buffer(struct line *line)
        }
 
        count = line->tail - line->head;
-       n = write_chan(&line->chan_list, line->head, count,
+       n = write_chan(line->chan_out, line->head, count,
                       line->driver->write_irq);
 
        if (n < 0)
@@ -206,7 +197,7 @@ int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
        if (line->head != line->tail)
                ret = buffer_data(line, buf, len);
        else {
-               n = write_chan(&line->chan_list, buf, len,
+               n = write_chan(line->chan_out, buf, len,
                               line->driver->write_irq);
                if (n < 0) {
                        ret = n;
@@ -318,7 +309,7 @@ void line_throttle(struct tty_struct *tty)
 {
        struct line *line = tty->driver_data;
 
-       deactivate_chan(&line->chan_list, line->driver->read_irq);
+       deactivate_chan(line->chan_in, line->driver->read_irq);
        line->throttled = 1;
 }
 
@@ -327,8 +318,7 @@ void line_unthrottle(struct tty_struct *tty)
        struct line *line = tty->driver_data;
 
        line->throttled = 0;
-       chan_interrupt(&line->chan_list, &line->task, tty,
-                      line->driver->read_irq);
+       chan_interrupt(line, tty, line->driver->read_irq);
 
        /*
         * Maybe there is enough stuff pending that calling the interrupt
@@ -336,7 +326,7 @@ void line_unthrottle(struct tty_struct *tty)
         * again and we shouldn't turn the interrupt back on.
         */
        if (!line->throttled)
-               reactivate_chan(&line->chan_list, line->driver->read_irq);
+               reactivate_chan(line->chan_in, line->driver->read_irq);
 }
 
 static irqreturn_t line_write_interrupt(int irq, void *data)
@@ -347,13 +337,14 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
        int err;
 
        /*
-        * Interrupts are disabled here because we registered the interrupt with
-        * IRQF_DISABLED (see line_setup_irq).
+        * Interrupts are disabled here because genirq keep irqs disabled when
+        * calling the action handler.
         */
 
        spin_lock(&line->lock);
        err = flush_buffer(line);
        if (err == 0) {
+               spin_unlock(&line->lock);
                return IRQ_NONE;
        } else if (err < 0) {
                line->head = line->buffer;
@@ -371,7 +362,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
 int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
 {
        const struct line_driver *driver = line->driver;
-       int err = 0, flags = IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM;
+       int err = 0, flags = IRQF_SHARED | IRQF_SAMPLE_RANDOM;
 
        if (input)
                err = um_request_irq(driver->read_irq, fd, IRQ_READ,
@@ -383,7 +374,6 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
                err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
                                        line_write_interrupt, flags,
                                        driver->write_irq_name, data);
-       line->have_irq = 1;
        return err;
 }
 
@@ -409,7 +399,7 @@ int line_open(struct line *lines, struct tty_struct *tty)
        struct line *line = &lines[tty->index];
        int err = -ENODEV;
 
-       spin_lock(&line->count_lock);
+       mutex_lock(&line->count_lock);
        if (!line->valid)
                goto out_unlock;
 
@@ -421,25 +411,19 @@ int line_open(struct line *lines, struct tty_struct *tty)
        tty->driver_data = line;
        line->tty = tty;
 
-       spin_unlock(&line->count_lock);
        err = enable_chan(line);
        if (err) /* line_close() will be called by our caller */
-               return err;
-
-       INIT_DELAYED_WORK(&line->task, line_timer_cb);
+               goto out_unlock;
 
        if (!line->sigio) {
-               chan_enable_winch(&line->chan_list, tty);
+               chan_enable_winch(line->chan_out, tty);
                line->sigio = 1;
        }
 
-       chan_window_size(&line->chan_list, &tty->winsize.ws_row,
+       chan_window_size(line, &tty->winsize.ws_row,
                         &tty->winsize.ws_col);
-
-       return 0;
-
 out_unlock:
-       spin_unlock(&line->count_lock);
+       mutex_unlock(&line->count_lock);
        return err;
 }
 
@@ -459,7 +443,7 @@ void line_close(struct tty_struct *tty, struct file * filp)
        /* We ignore the error anyway! */
        flush_buffer(line);
 
-       spin_lock(&line->count_lock);
+       mutex_lock(&line->count_lock);
        BUG_ON(!line->valid);
 
        if (--line->count)
@@ -468,17 +452,13 @@ void line_close(struct tty_struct *tty, struct file * filp)
        line->tty = NULL;
        tty->driver_data = NULL;
 
-       spin_unlock(&line->count_lock);
-
        if (line->sigio) {
                unregister_winch(tty);
                line->sigio = 0;
        }
 
-       return;
-
 out_unlock:
-       spin_unlock(&line->count_lock);
+       mutex_unlock(&line->count_lock);
 }
 
 void close_lines(struct line *lines, int nlines)
@@ -486,34 +466,60 @@ void close_lines(struct line *lines, int nlines)
        int i;
 
        for(i = 0; i < nlines; i++)
-               close_chan(&lines[i].chan_list, 0);
+               close_chan(&lines[i]);
 }
 
-static int setup_one_line(struct line *lines, int n, char *init, int init_prio,
-                         char **error_out)
+int setup_one_line(struct line *lines, int n, char *init,
+                  const struct chan_opts *opts, char **error_out)
 {
        struct line *line = &lines[n];
+       struct tty_driver *driver = line->driver->driver;
        int err = -EINVAL;
 
-       spin_lock(&line->count_lock);
+       mutex_lock(&line->count_lock);
 
        if (line->count) {
                *error_out = "Device is already open";
                goto out;
        }
 
-       if (line->init_pri <= init_prio) {
-               line->init_pri = init_prio;
-               if (!strcmp(init, "none"))
+       if (!strcmp(init, "none")) {
+               if (line->valid) {
+                       line->valid = 0;
+                       kfree(line->init_str);
+                       tty_unregister_device(driver, n);
+                       parse_chan_pair(NULL, line, n, opts, error_out);
+                       err = 0;
+               }
+       } else {
+               char *new = kstrdup(init, GFP_KERNEL);
+               if (!new) {
+                       *error_out = "Failed to allocate memory";
+                       return -ENOMEM;
+               }
+               if (line->valid) {
+                       tty_unregister_device(driver, n);
+                       kfree(line->init_str);
+               }
+               line->init_str = new;
+               line->valid = 1;
+               err = parse_chan_pair(new, line, n, opts, error_out);
+               if (!err) {
+                       struct device *d = tty_register_device(driver, n, NULL);
+                       if (IS_ERR(d)) {
+                               *error_out = "Failed to register device";
+                               err = PTR_ERR(d);
+                               parse_chan_pair(NULL, line, n, opts, error_out);
+                       }
+               }
+               if (err) {
+                       line->init_str = NULL;
                        line->valid = 0;
-               else {
-                       line->init_str = init;
-                       line->valid = 1;
+                       kfree(new);
                }
        }
-       err = 0;
 out:
-       spin_unlock(&line->count_lock);
+       mutex_unlock(&line->count_lock);
        return err;
 }
 
@@ -524,54 +530,43 @@ out:
  * @error_out is an error string in the case of failure;
  */
 
-int line_setup(struct line *lines, unsigned int num, char *init,
-              char **error_out)
+int line_setup(char **conf, unsigned int num, char **def,
+              char *init, char *name)
 {
-       int i, n, err;
-       char *end;
+       char *error;
 
        if (*init == '=') {
                /*
                 * We said con=/ssl= instead of con#=, so we are configuring all
                 * consoles at once.
                 */
-               n = -1;
-       }
-       else {
-               n = simple_strtoul(init, &end, 0);
+               *def = init + 1;
+       } else {
+               char *end;
+               unsigned n = simple_strtoul(init, &end, 0);
+
                if (*end != '=') {
-                       *error_out = "Couldn't parse device number";
-                       return -EINVAL;
+                       error = "Couldn't parse device number";
+                       goto out;
                }
-               init = end;
-       }
-       init++;
-
-       if (n >= (signed int) num) {
-               *error_out = "Device number out of range";
-               return -EINVAL;
-       }
-       else if (n >= 0) {
-               err = setup_one_line(lines, n, init, INIT_ONE, error_out);
-               if (err)
-                       return err;
-       }
-       else {
-               for(i = 0; i < num; i++) {
-                       err = setup_one_line(lines, i, init, INIT_ALL,
-                                            error_out);
-                       if (err)
-                               return err;
+               if (n >= num) {
+                       error = "Device number out of range";
+                       goto out;
                }
+               conf[n] = end + 1;
        }
-       return n == -1 ? num : n;
+       return 0;
+
+out:
+       printk(KERN_ERR "Failed to set up %s with "
+              "configuration string \"%s\" : %s\n", name, init, error);
+       return -EINVAL;
 }
 
 int line_config(struct line *lines, unsigned int num, char *str,
                const struct chan_opts *opts, char **error_out)
 {
-       struct line *line;
-       char *new;
+       char *end;
        int n;
 
        if (*str == '=') {
@@ -579,17 +574,17 @@ int line_config(struct line *lines, unsigned int num, char *str,
                return -EINVAL;
        }
 
-       new = kstrdup(str, GFP_KERNEL);
-       if (new == NULL) {
-               *error_out = "Failed to allocate memory";
-               return -ENOMEM;
+       n = simple_strtoul(str, &end, 0);
+       if (*end++ != '=') {
+               *error_out = "Couldn't parse device number";
+               return -EINVAL;
+       }
+       if (n >= num) {
+               *error_out = "Device number out of range";
+               return -EINVAL;
        }
-       n = line_setup(lines, num, new, error_out);
-       if (n < 0)
-               return n;
 
-       line = &lines[n];
-       return parse_chan_pair(line->init_str, line, n, opts, error_out);
+       return setup_one_line(lines, n, end, opts, error_out);
 }
 
 int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
@@ -612,13 +607,13 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
 
        line = &lines[dev];
 
-       spin_lock(&line->count_lock);
+       mutex_lock(&line->count_lock);
        if (!line->valid)
                CONFIG_CHUNK(str, size, n, "none", 1);
        else if (line->tty == NULL)
                CONFIG_CHUNK(str, size, n, line->init_str, 1);
-       else n = chan_config_string(&line->chan_list, str, size, error_out);
-       spin_unlock(&line->count_lock);
+       else n = chan_config_string(line, str, size, error_out);
+       mutex_unlock(&line->count_lock);
 
        return n;
 }
@@ -640,25 +635,23 @@ int line_id(char **str, int *start_out, int *end_out)
 
 int line_remove(struct line *lines, unsigned int num, int n, char **error_out)
 {
-       int err;
-       char config[sizeof("conxxxx=none\0")];
-
-       sprintf(config, "%d=none", n);
-       err = line_setup(lines, num, config, error_out);
-       if (err >= 0)
-               err = 0;
-       return err;
+       if (n >= num) {
+               *error_out = "Device number out of range";
+               return -EINVAL;
+       }
+       return setup_one_line(lines, n, "none", NULL, error_out);
 }
 
-struct tty_driver *register_lines(struct line_driver *line_driver,
-                                 const struct tty_operations *ops,
-                                 struct line *lines, int nlines)
+int register_lines(struct line_driver *line_driver,
+                  const struct tty_operations *ops,
+                  struct line *lines, int nlines)
 {
-       int i;
        struct tty_driver *driver = alloc_tty_driver(nlines);
+       int err;
+       int i;
 
        if (!driver)
-               return NULL;
+               return -ENOMEM;
 
        driver->driver_name = line_driver->name;
        driver->name = line_driver->device_name;
@@ -666,54 +659,33 @@ struct tty_driver *register_lines(struct line_driver *line_driver,
        driver->minor_start = line_driver->minor_start;
        driver->type = line_driver->type;
        driver->subtype = line_driver->subtype;
-       driver->flags = TTY_DRIVER_REAL_RAW;
+       driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
        driver->init_termios = tty_std_termios;
+       
+       for (i = 0; i < nlines; i++) {
+               spin_lock_init(&lines[i].lock);
+               mutex_init(&lines[i].count_lock);
+               lines[i].driver = line_driver;
+               INIT_LIST_HEAD(&lines[i].chan_list);
+       }
        tty_set_operations(driver, ops);
 
-       if (tty_register_driver(driver)) {
+       err = tty_register_driver(driver);
+       if (err) {
                printk(KERN_ERR "register_lines : can't register %s driver\n",
                       line_driver->name);
                put_tty_driver(driver);
-               return NULL;
-       }
-
-       for(i = 0; i < nlines; i++) {
-               if (!lines[i].valid)
-                       tty_unregister_device(driver, i);
+               return err;
        }
 
+       line_driver->driver = driver;
        mconsole_register_dev(&line_driver->mc);
-       return driver;
+       return 0;
 }
 
 static DEFINE_SPINLOCK(winch_handler_lock);
 static LIST_HEAD(winch_handlers);
 
-void lines_init(struct line *lines, int nlines, struct chan_opts *opts)
-{
-       struct line *line;
-       char *error;
-       int i;
-
-       for(i = 0; i < nlines; i++) {
-               line = &lines[i];
-               INIT_LIST_HEAD(&line->chan_list);
-
-               if (line->init_str == NULL)
-                       continue;
-
-               line->init_str = kstrdup(line->init_str, GFP_KERNEL);
-               if (line->init_str == NULL)
-                       printk(KERN_ERR "lines_init - kstrdup returned NULL\n");
-
-               if (parse_chan_pair(line->init_str, line, i, opts, &error)) {
-                       printk(KERN_ERR "parse_chan_pair failed for "
-                              "device %d : %s\n", i, error);
-                       line->valid = 0;
-               }
-       }
-}
-
 struct winch {
        struct list_head list;
        int fd;
@@ -777,7 +749,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
        if (tty != NULL) {
                line = tty->driver_data;
                if (line != NULL) {
-                       chan_window_size(&line->chan_list, &tty->winsize.ws_row,
+                       chan_window_size(line, &tty->winsize.ws_row,
                                         &tty->winsize.ws_col);
                        kill_pgrp(tty->pgrp, SIGWINCH, 1);
                }
@@ -807,7 +779,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty,
                                   .stack       = stack });
 
        if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
-                          IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
+                          IRQF_SHARED | IRQF_SAMPLE_RANDOM,
                           "winch", winch) < 0) {
                printk(KERN_ERR "register_winch_irq - failed to register "
                       "IRQ\n");
index 63df3ca02ac2fbc5c367afaeeaec26010f8b55c0..0a1834719dbaff1e0d6afa6333c1df3a4f8274db 100644 (file)
@@ -15,7 +15,7 @@
 #include "chan_user.h"
 #include "mconsole_kern.h"
 
-/* There's only one modifiable field in this - .mc.list */
+/* There's only two modifiable fields in this - .mc.list and .driver */
 struct line_driver {
        const char *name;
        const char *device_name;
@@ -28,17 +28,18 @@ struct line_driver {
        const int write_irq;
        const char *write_irq_name;
        struct mc_device mc;
+       struct tty_driver *driver;
 };
 
 struct line {
        struct tty_struct *tty;
-       spinlock_t count_lock;
+       struct mutex count_lock;
        unsigned long count;
        int valid;
 
        char *init_str;
-       int init_pri;
        struct list_head chan_list;
+       struct chan *chan_in, *chan_out;
 
        /*This lock is actually, mostly, local to*/
        spinlock_t lock;
@@ -55,21 +56,12 @@ struct line {
        int sigio;
        struct delayed_work task;
        const struct line_driver *driver;
-       int have_irq;
 };
 
-#define LINE_INIT(str, d) \
-       { .count_lock = __SPIN_LOCK_UNLOCKED((str).count_lock), \
-         .init_str =   str,    \
-         .init_pri =   INIT_STATIC, \
-         .valid =      1, \
-         .lock =       __SPIN_LOCK_UNLOCKED((str).lock), \
-         .driver =     d }
-
 extern void line_close(struct tty_struct *tty, struct file * filp);
 extern int line_open(struct line *lines, struct tty_struct *tty);
-extern int line_setup(struct line *lines, unsigned int sizeof_lines,
-                     char *init, char **error_out);
+extern int line_setup(char **conf, unsigned nlines, char **def,
+                     char *init, char *name);
 extern int line_write(struct tty_struct *tty, const unsigned char *buf,
                      int len);
 extern int line_put_char(struct tty_struct *tty, unsigned char ch);
@@ -87,10 +79,11 @@ extern char *add_xterm_umid(char *base);
 extern int line_setup_irq(int fd, int input, int output, struct line *line,
                          void *data);
 extern void line_close_chan(struct line *line);
-extern struct tty_driver *register_lines(struct line_driver *line_driver,
-                                        const struct tty_operations *driver,
-                                        struct line *lines, int nlines);
-extern void lines_init(struct line *lines, int nlines, struct chan_opts *opts);
+extern int register_lines(struct line_driver *line_driver,
+                         const struct tty_operations *driver,
+                         struct line *lines, int nlines);
+extern int setup_one_line(struct line *lines, int n, char *init,
+                         const struct chan_opts *opts, char **error_out);
 extern void close_lines(struct line *lines, int nlines);
 
 extern int line_config(struct line *lines, unsigned int sizeof_lines,
index c70e047eed72e192cd9d0a8ade7cc6f8302a9d6c..e672bd6d43e3b2aa72b4c1c51029db9510233f52 100644 (file)
@@ -773,7 +773,7 @@ static int __init mconsole_init(void)
        register_reboot_notifier(&reboot_notifier);
 
        err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt,
-                            IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
+                            IRQF_SHARED | IRQF_SAMPLE_RANDOM,
                             "mconsole", (void *)sock);
        if (err) {
                printk(KERN_ERR "Failed to get IRQ for management console\n");
index d2996183e584eb0829548512977568ffccbb8936..95f4416e6d9f3574b2a2b85acf6ff6b858fa344a 100644 (file)
@@ -161,7 +161,7 @@ static int uml_net_open(struct net_device *dev)
        }
 
        err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
-                            IRQF_DISABLED | IRQF_SHARED, dev->name, dev);
+                            IRQF_SHARED, dev->name, dev);
        if (err != 0) {
                printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
                err = -ENETUNREACH;
index a11573be0961fd7b233a02ff40421aa3a53940c7..e31680e662a473eeee0d4e62543110b533b6d70d 100644 (file)
@@ -100,7 +100,7 @@ static int port_accept(struct port_list *port)
                  .port         = port });
 
        if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt,
-                         IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
+                         IRQF_SHARED | IRQF_SAMPLE_RANDOM,
                          "telnetd", conn)) {
                printk(KERN_ERR "port_accept : failed to get IRQ for "
                       "telnetd\n");
@@ -184,7 +184,7 @@ void *port_data(int port_num)
        }
 
        if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt,
-                         IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
+                         IRQF_SHARED | IRQF_SAMPLE_RANDOM,
                          "port", port)) {
                printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num);
                goto out_close;
index 981085a93f30c4a48539e81b0cabce905a39de53..b25296e6218ade5fdeee1d3dff4f369bce5accbe 100644 (file)
@@ -131,7 +131,7 @@ static int __init rng_init (void)
        random_fd = err;
 
        err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt,
-                            IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "random",
+                            IRQF_SAMPLE_RANDOM, "random",
                             NULL);
        if (err)
                goto err_out_cleanup_hw;
index 9d8c20af6f80dac061641ce61de33975c176b892..e09801a1327bb9ae10d33d8e55def730c1b4fd58 100644 (file)
 
 static const int ssl_version = 1;
 
-/* Referenced only by tty_driver below - presumably it's locked correctly
- * by the tty driver.
- */
-
-static struct tty_driver *ssl_driver;
-
 #define NR_PORTS 64
 
 static void ssl_announce(char *dev_name, int dev)
@@ -71,8 +65,9 @@ static struct line_driver driver = {
 /* The array is initialized by line_init, at initcall time.  The
  * elements are locked individually as needed.
  */
-static struct line serial_lines[NR_PORTS] =
-       { [0 ... NR_PORTS - 1] = LINE_INIT(CONFIG_SSL_CHAN, &driver) };
+static char *conf[NR_PORTS];
+static char *def_conf = CONFIG_SSL_CHAN;
+static struct line serial_lines[NR_PORTS];
 
 static int ssl_config(char *str, char **error_out)
 {
@@ -156,14 +151,14 @@ static void ssl_console_write(struct console *c, const char *string,
        unsigned long flags;
 
        spin_lock_irqsave(&line->lock, flags);
-       console_write_chan(&line->chan_list, string, len);
+       console_write_chan(line->chan_out, string, len);
        spin_unlock_irqrestore(&line->lock, flags);
 }
 
 static struct tty_driver *ssl_console_device(struct console *c, int *index)
 {
        *index = c->index;
-       return ssl_driver;
+       return driver.driver;
 }
 
 static int ssl_console_setup(struct console *co, char *options)
@@ -186,17 +181,30 @@ static struct console ssl_cons = {
 static int ssl_init(void)
 {
        char *new_title;
+       int err;
+       int i;
 
        printk(KERN_INFO "Initializing software serial port version %d\n",
               ssl_version);
-       ssl_driver = register_lines(&driver, &ssl_ops, serial_lines,
+
+       err = register_lines(&driver, &ssl_ops, serial_lines,
                                    ARRAY_SIZE(serial_lines));
+       if (err)
+               return err;
 
        new_title = add_xterm_umid(opts.xterm_title);
        if (new_title != NULL)
                opts.xterm_title = new_title;
 
-       lines_init(serial_lines, ARRAY_SIZE(serial_lines), &opts);
+       for (i = 0; i < NR_PORTS; i++) {
+               char *error;
+               char *s = conf[i];
+               if (!s)
+                       s = def_conf;
+               if (setup_one_line(serial_lines, i, s, &opts, &error))
+                       printk(KERN_ERR "setup_one_line failed for "
+                              "device %d : %s\n", i, error);
+       }
 
        ssl_init_done = 1;
        register_console(&ssl_cons);
@@ -214,14 +222,7 @@ __uml_exitcall(ssl_exit);
 
 static int ssl_chan_setup(char *str)
 {
-       char *error;
-       int ret;
-
-       ret = line_setup(serial_lines, ARRAY_SIZE(serial_lines), str, &error);
-       if(ret < 0)
-               printk(KERN_ERR "Failed to set up serial line with "
-                      "configuration string \"%s\" : %s\n", str, error);
-
+       line_setup(conf, NR_PORTS, &def_conf, str, "serial line");
        return 1;
 }
 
index 088776f01908e2eb5a27281cbac37b5927012881..7663541c372ee06e5be7097ff2eba2e275f86a23 100644 (file)
 
 #define MAX_TTYS (16)
 
-/* Referenced only by tty_driver below - presumably it's locked correctly
- * by the tty driver.
- */
-
-static struct tty_driver *console_driver;
-
 static void stdio_announce(char *dev_name, int dev)
 {
        printk(KERN_INFO "Virtual console %d assigned device '%s'\n", dev,
@@ -76,9 +70,9 @@ static struct line_driver driver = {
 /* The array is initialized by line_init, at initcall time.  The
  * elements are locked individually as needed.
  */
-static struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver),
-                                    [ 1 ... MAX_TTYS - 1 ] =
-                                    LINE_INIT(CONFIG_CON_CHAN, &driver) };
+static char *vt_conf[MAX_TTYS];
+static char *def_conf;
+static struct line vts[MAX_TTYS];
 
 static int con_config(char *str, char **error_out)
 {
@@ -130,14 +124,14 @@ static void uml_console_write(struct console *console, const char *string,
        unsigned long flags;
 
        spin_lock_irqsave(&line->lock, flags);
-       console_write_chan(&line->chan_list, string, len);
+       console_write_chan(line->chan_out, string, len);
        spin_unlock_irqrestore(&line->lock, flags);
 }
 
 static struct tty_driver *uml_console_device(struct console *c, int *index)
 {
        *index = c->index;
-       return console_driver;
+       return driver.driver;
 }
 
 static int uml_console_setup(struct console *co, char *options)
@@ -160,18 +154,31 @@ static struct console stdiocons = {
 static int stdio_init(void)
 {
        char *new_title;
+       int err;
+       int i;
 
-       console_driver = register_lines(&driver, &console_ops, vts,
+       err = register_lines(&driver, &console_ops, vts,
                                        ARRAY_SIZE(vts));
-       if (console_driver == NULL)
-               return -1;
+       if (err)
+               return err;
+
        printk(KERN_INFO "Initialized stdio console driver\n");
 
        new_title = add_xterm_umid(opts.xterm_title);
        if(new_title != NULL)
                opts.xterm_title = new_title;
 
-       lines_init(vts, ARRAY_SIZE(vts), &opts);
+       for (i = 0; i < MAX_TTYS; i++) {
+               char *error;
+               char *s = vt_conf[i];
+               if (!s)
+                       s = def_conf;
+               if (!s)
+                       s = i ? CONFIG_CON_CHAN : CONFIG_CON_ZERO_CHAN;
+               if (setup_one_line(vts, i, s, &opts, &error))
+                       printk(KERN_ERR "setup_one_line failed for "
+                              "device %d : %s\n", i, error);
+       }
 
        con_init_done = 1;
        register_console(&stdiocons);
@@ -189,14 +196,7 @@ __uml_exitcall(console_exit);
 
 static int console_chan_setup(char *str)
 {
-       char *error;
-       int ret;
-
-       ret = line_setup(vts, ARRAY_SIZE(vts), str, &error);
-       if(ret < 0)
-               printk(KERN_ERR "Failed to set up console with "
-                      "configuration string \"%s\" : %s\n", str, error);
-
+       line_setup(vt_conf, MAX_TTYS, &def_conf, str, "console");
        return 1;
 }
 __setup("con", console_chan_setup);
diff --git a/arch/um/drivers/ubd.h b/arch/um/drivers/ubd.h
new file mode 100644 (file)
index 0000000..3845051
--- /dev/null
@@ -0,0 +1,16 @@
+/* 
+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001 RidgeRun, Inc (glonnon@ridgerun.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_UBD_USER_H
+#define __UM_UBD_USER_H
+
+extern void ignore_sigwinch_sig(void);
+extern int start_io_thread(unsigned long sp, int *fds_out);
+extern int io_thread(void *arg);
+extern int kernel_fd;
+
+#endif
+
index 944453a3ec9972f136060054893f7e7aaa3ea568..20505cafa29904f176b735f98cdc94eeaac50181 100644 (file)
 
 #define UBD_SHIFT 4
 
-#include "linux/kernel.h"
-#include "linux/module.h"
-#include "linux/blkdev.h"
-#include "linux/ata.h"
-#include "linux/hdreg.h"
-#include "linux/init.h"
-#include "linux/cdrom.h"
-#include "linux/proc_fs.h"
-#include "linux/seq_file.h"
-#include "linux/ctype.h"
-#include "linux/capability.h"
-#include "linux/mm.h"
-#include "linux/slab.h"
-#include "linux/vmalloc.h"
-#include "linux/mutex.h"
-#include "linux/blkpg.h"
-#include "linux/genhd.h"
-#include "linux/spinlock.h"
-#include "linux/platform_device.h"
-#include "linux/scatterlist.h"
-#include "asm/segment.h"
-#include "asm/uaccess.h"
-#include "asm/irq.h"
-#include "asm/types.h"
-#include "asm/tlbflush.h"
-#include "mem_user.h"
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/ata.h>
+#include <linux/hdreg.h>
+#include <linux/cdrom.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/ctype.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/platform_device.h>
+#include <linux/scatterlist.h>
+#include <asm/tlbflush.h>
 #include "kern_util.h"
 #include "mconsole_kern.h"
 #include "init.h"
-#include "irq_user.h"
 #include "irq_kern.h"
-#include "ubd_user.h"
+#include "ubd.h"
 #include "os.h"
-#include "mem.h"
 #include "cow.h"
 
 enum ubd_req { UBD_READ, UBD_WRITE };
@@ -1115,7 +1101,7 @@ static int __init ubd_driver_init(void){
                return 0;
        }
        err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
-                            IRQF_DISABLED, "ubd", ubd_devs);
+                            0, "ubd", ubd_devs);
        if(err != 0)
                printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
        return 0;
index 007b94d97726e7864a6ccd543038f76d7b488a88..ffe02c431dea9b4f2def4acb8781a6308943e308 100644 (file)
 #include <sys/socket.h>
 #include <sys/mman.h>
 #include <sys/param.h>
-#include "asm/types.h"
-#include "ubd_user.h"
-#include "os.h"
-#include "cow.h"
-
 #include <endian.h>
 #include <byteswap.h>
 
+#include "ubd.h"
+#include "os.h"
+
 void ignore_sigwinch_sig(void)
 {
        signal(SIGWINCH, SIG_IGN);
diff --git a/arch/um/drivers/ubd_user.h b/arch/um/drivers/ubd_user.h
deleted file mode 100644 (file)
index 3845051..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/* 
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
- * Copyright (C) 2001 RidgeRun, Inc (glonnon@ridgerun.com)
- * Licensed under the GPL
- */
-
-#ifndef __UM_UBD_USER_H
-#define __UM_UBD_USER_H
-
-extern void ignore_sigwinch_sig(void);
-extern int start_io_thread(unsigned long sp, int *fds_out);
-extern int io_thread(void *arg);
-extern int kernel_fd;
-
-#endif
-
index b646bccef37aa8586fb95701a6c750d1246aa8c3..8bd130f0bda351e4295752f0d2d1c8e451752330 100644 (file)
@@ -50,7 +50,7 @@ int xterm_fd(int socket, int *pid_out)
        init_completion(&data->ready);
 
        err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt,
-                            IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
+                            IRQF_SHARED | IRQF_SAMPLE_RANDOM,
                             "xterm", data);
        if (err) {
                printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
index 451f4517b334eba8b277b113be98fcdb02e499e1..8419f5cf2ac7e3586c68677198b2b28321b95221 100644 (file)
@@ -1,3 +1,3 @@
 generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h
 generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h
-generic-y += ftrace.h
+generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h
diff --git a/arch/um/include/asm/asm-offsets.h b/arch/um/include/asm/asm-offsets.h
deleted file mode 100644 (file)
index d370ee3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <generated/asm-offsets.h>
diff --git a/arch/um/include/asm/auxvec.h b/arch/um/include/asm/auxvec.h
deleted file mode 100644 (file)
index 1e5e1c2..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __UM_AUXVEC_H
-#define __UM_AUXVEC_H
-
-#endif
diff --git a/arch/um/include/asm/current.h b/arch/um/include/asm/current.h
deleted file mode 100644 (file)
index c2191d9..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- * Licensed under the GPL
- */
-
-#ifndef __UM_CURRENT_H
-#define __UM_CURRENT_H
-
-#include "linux/thread_info.h"
-
-#define current (current_thread_info()->task)
-
-#endif
diff --git a/arch/um/include/asm/delay.h b/arch/um/include/asm/delay.h
deleted file mode 100644 (file)
index 8a5576d..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef __UM_DELAY_H
-#define __UM_DELAY_H
-
-/* Undefined on purpose */
-extern void __bad_udelay(void);
-extern void __bad_ndelay(void);
-
-extern void __udelay(unsigned long usecs);
-extern void __ndelay(unsigned long usecs);
-extern void __delay(unsigned long loops);
-
-#define udelay(n) ((__builtin_constant_p(n) && (n) > 20000) ? \
-       __bad_udelay() : __udelay(n))
-
-#define ndelay(n) ((__builtin_constant_p(n) && (n) > 20000) ? \
-       __bad_ndelay() : __ndelay(n))
-
-#endif
diff --git a/arch/um/include/asm/io.h b/arch/um/include/asm/io.h
deleted file mode 100644 (file)
index 44e8b8c..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef __UM_IO_H
-#define __UM_IO_H
-
-#include "asm/page.h"
-
-#define IO_SPACE_LIMIT 0xdeadbeef /* Sure hope nothing uses this */
-
-static inline int inb(unsigned long i) { return(0); }
-static inline void outb(char c, unsigned long i) { }
-
-/*
- * Change virtual addresses to physical addresses and vv.
- * These are pretty trivial
- */
-static inline unsigned long virt_to_phys(volatile void * address)
-{
-       return __pa((void *) address);
-}
-
-static inline void * phys_to_virt(unsigned long address)
-{
-       return __va(address);
-}
-
-/*
- * Convert a physical pointer to a virtual kernel pointer for /dev/mem
- * access
- */
-#define xlate_dev_mem_ptr(p)   __va(p)
-
-/*
- * Convert a virtual cached pointer to an uncached pointer
- */
-#define xlate_dev_kmem_ptr(p)  p
-
-static inline void writeb(unsigned char b, volatile void __iomem *addr)
-{
-       *(volatile unsigned char __force *) addr = b;
-}
-static inline void writew(unsigned short b, volatile void __iomem *addr)
-{
-       *(volatile unsigned short __force *) addr = b;
-}
-static inline void writel(unsigned int b, volatile void __iomem *addr)
-{
-       *(volatile unsigned int __force *) addr = b;
-}
-static inline void writeq(unsigned int b, volatile void __iomem *addr)
-{
-       *(volatile unsigned long long __force *) addr = b;
-}
-#define __raw_writeb writeb
-#define __raw_writew writew
-#define __raw_writel writel
-#define __raw_writeq writeq
-
-#endif
diff --git a/arch/um/include/asm/mutex.h b/arch/um/include/asm/mutex.h
deleted file mode 100644 (file)
index 458c1f7..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * Pull in the generic implementation for the mutex fastpath.
- *
- * TODO: implement optimized primitives instead, or leave the generic
- * implementation in place, or pick the atomic_xchg() based generic
- * implementation. (see asm-generic/mutex-xchg.h for details)
- */
-
-#include <asm-generic/mutex-dec.h>
diff --git a/arch/um/include/asm/param.h b/arch/um/include/asm/param.h
deleted file mode 100644 (file)
index e44f4e6..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef _UM_PARAM_H
-#define _UM_PARAM_H
-
-#define EXEC_PAGESIZE   4096
-
-#ifndef NOGROUP
-#define NOGROUP         (-1)
-#endif
-
-#define MAXHOSTNAMELEN  64      /* max length of hostname */
-
-#ifdef __KERNEL__
-#define HZ CONFIG_HZ
-#define USER_HZ        100        /* .. some user interfaces are in "ticks" */
-#define CLOCKS_PER_SEC (USER_HZ)  /* frequency at which times() counts */
-#else
-#define HZ 100
-#endif
-
-#endif
diff --git a/arch/um/include/asm/pci.h b/arch/um/include/asm/pci.h
deleted file mode 100644 (file)
index b44cf59..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __UM_PCI_H
-#define __UM_PCI_H
-
-#define PCI_DMA_BUS_IS_PHYS     (1)
-
-#endif
index 32c8ce4e15153ee6d42fb72fd7579df0400f9e69..bf90b2aa20025456445ef4d008821ef43f4a7262 100644 (file)
@@ -8,8 +8,7 @@
 #ifndef __UM_PGALLOC_H
 #define __UM_PGALLOC_H
 
-#include "linux/mm.h"
-#include "asm/fixmap.h"
+#include <linux/mm.h>
 
 #define pmd_populate_kernel(mm, pmd, pte) \
        set_pmd(pmd, __pmd(_PAGE_TABLE + (unsigned long) __pa(pte)))
index 41474fb5eee70d3f89474ae13c59cbaef10b0f37..6a3f9845743ea485c24254696ff4b41646e418d0 100644 (file)
@@ -69,6 +69,8 @@ extern unsigned long end_iomem;
 #define PAGE_KERNEL    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
 #define PAGE_KERNEL_EXEC       __pgprot(__PAGE_KERNEL_EXEC)
 
+#define io_remap_pfn_range     remap_pfn_range
+
 /*
  * The i386 can't do page protection for execute, and considers that the same
  * are read.
index f605d3c4844cb1e2883a31daf36bc96f2b2e536e..e786a6a3ec5e88c3ae6fc61d2036096d79304fcc 100644 (file)
@@ -9,7 +9,6 @@
 #ifndef __ASSEMBLY__
 
 #include <asm/ptrace-abi.h>
-#include <asm/user.h>
 #include "sysdep/ptrace.h"
 
 struct pt_regs {
index d7fe563aa7e78429aa6a10816974ce40c4219f93..40db8f71deaef4eb19c10a09e4f01d51078d3c8d 100644 (file)
@@ -2,8 +2,6 @@
 
 DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE);
 
-OFFSET(HOST_TASK_PID, task_struct, pid);
-
 DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE);
 DEFINE(UM_KERN_PAGE_MASK, PAGE_MASK);
 DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT);
index 0f1483852460a279bf32b80e68d6d3fbbcaa9d69..00965d06d2ca2022f6514c6506fa7e2fbf9adffa 100644 (file)
@@ -48,7 +48,7 @@ extern void do_uml_exitcalls(void);
  * GFP_ATOMIC.
  */
 extern int __cant_sleep(void);
-extern void *get_current(void);
+extern int get_current_pid(void);
 extern int copy_from_user_proc(void *to, void *from, int size);
 extern int cpu(void);
 extern char *uml_strdup(const char *string);
index bc494741b1f35f55b96421b00c581ab554c47d32..492bc4c1b62bf3516a996d81c24c05c494fcf8d5 100644 (file)
@@ -3,7 +3,7 @@
 # Licensed under the GPL
 #
 
-CPPFLAGS_vmlinux.lds := -U$(SUBARCH) -DSTART=$(LDS_START) \
+CPPFLAGS_vmlinux.lds := -DSTART=$(LDS_START) \
                         -DELF_ARCH=$(LDS_ELF_ARCH)        \
                         -DELF_FORMAT=$(LDS_ELF_FORMAT)
 extra-y := vmlinux.lds
index 69f24905abdc4350e368a84e94e9ed5dc9da3d3c..f386d04a84a526df7a51a13cbc6c1636543071fe 100644 (file)
@@ -126,9 +126,9 @@ void exit_thread(void)
 {
 }
 
-void *get_current(void)
+int get_current_pid(void)
 {
-       return current;
+       return task_pid_nr(current);
 }
 
 /*
index 2b272b63b514c1508a83c3199d7a1b926d0c8c40..2a1639255763973eaed54dfda4d20090a6e3bf5d 100644 (file)
@@ -25,7 +25,7 @@ int write_sigio_irq(int fd)
        int err;
 
        err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
-                            IRQF_DISABLED|IRQF_SAMPLE_RANDOM, "write sigio",
+                            IRQF_SAMPLE_RANDOM, "write sigio",
                             NULL);
        if (err) {
                printk(KERN_ERR "write_sigio_irq : um_request_irq failed, "
index 82a6e22f1f3567d4e4c95c668c3635ed058cda4c..d1a23fb3190daa9274e033572331c7a9799d5ce4 100644 (file)
@@ -82,7 +82,7 @@ static void __init setup_itimer(void)
 {
        int err;
 
-       err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL);
+       err = request_irq(TIMER_IRQ, um_timer, 0, "timer", NULL);
        if (err != 0)
                printk(KERN_ERR "register_timer : request_irq failed - "
                       "errno = %d\n", -err);
index dd764101e48823b23113cf5c32f09368382dca4c..08ff5094fcdd9c82897d32b1c877284803b497b2 100644 (file)
@@ -13,8 +13,6 @@ USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \
        main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \
        tty.o umid.o util.o
 
-CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH)
-
 HAVE_AIO_ABI := $(shell [ -r /usr/include/linux/aio_abi.h ] && \
        echo -DHAVE_AIO_ABI )
 CFLAGS_aio.o += $(HAVE_AIO_ABI)
index 45ffe46871e0528e388ff58aa264694647c06235..73926fa3f96b2e92efa8c3d301f89da027ee1808 100644 (file)
@@ -45,7 +45,7 @@ EXPORT_SYMBOL(readdir64);
 extern void truncate64(void) __attribute__((weak));
 EXPORT_SYMBOL(truncate64);
 
-#ifdef SUBARCH_i386
+#ifdef CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA
 EXPORT_SYMBOL(vsyscall_ehdr);
 EXPORT_SYMBOL(vsyscall_end);
 #endif
index 2eb2843b06343c909b6138511722ea2d7a74cd52..d50270d26b427ace5d5f7c8777094298859a54c3 100644 (file)
@@ -9,8 +9,6 @@ USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
 
 $(USER_OBJS:.o=.%): \
        c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) -include user.h $(CFLAGS_$(basetarget).o)
-$(USER_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \
-       -Dunix -D__unix__ -D__$(SUBARCH)__ $(CF)
 
 # These are like USER_OBJS but filter USER_CFLAGS through unprofile instead of
 # using it directly.
@@ -18,8 +16,9 @@ UNPROFILE_OBJS := $(foreach file,$(UNPROFILE_OBJS),$(obj)/$(file))
 
 $(UNPROFILE_OBJS:.o=.%): \
        c_flags = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS)) $(CFLAGS_$(basetarget).o)
-$(UNPROFILE_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \
-       -Dunix -D__unix__ -D__$(SUBARCH)__ $(CF)
+
+$(USER_OBJS) $(UNPROFILE_OBJS): \
+       CHECKFLAGS := $(patsubst $(NOSTDINC_FLAGS),,$(CHECKFLAGS))
 
 # The stubs can't try to call mcount or update basic block data
 define unprofile
index 36ddec6a41c9fd6690fec0acd45fe10c8a6dc73c..4be406abeefde51f1f3dd9419a799256ae1c1e1d 100644 (file)
@@ -8,15 +8,11 @@ ELF_ARCH              := i386
 ELF_FORMAT             := elf32-i386
 CHECKFLAGS     += -D__i386__
 
-ifeq ("$(origin SUBARCH)", "command line")
-ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)")
 KBUILD_CFLAGS          += $(call cc-option,-m32)
 KBUILD_AFLAGS          += $(call cc-option,-m32)
 LINK-y                 += $(call cc-option,-m32)
 
 export LDFLAGS
-endif
-endif
 
 # First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y.
 include $(srctree)/arch/x86/Makefile_32.cpu
index b2b54d2edf53979fb7daf770c0d4bf0215a73fe0..9926e11a772dbe9b5417fa204407c2ec9ee58878 100644 (file)
@@ -15,8 +15,8 @@ config UML_X86
        select GENERIC_FIND_FIRST_BIT
 
 config 64BIT
-       bool
-       default SUBARCH = "x86_64"
+       bool "64-bit kernel" if SUBARCH = "x86"
+       default SUBARCH != "i386"
 
 config X86_32
        def_bool !64BIT
index 2c32df6fe23167a6ca3955fdac07444f6f2fbc34..04f82e020f2bdafbec85118e99ff73aed925ba97 100644 (file)
 #define ARCH_IS_STACKGROW(address) \
        (address + 65536 + 32 * sizeof(unsigned long) >= UPT_SP(&current->thread.regs.regs))
 
+#include <asm/user.h>
+
+/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
+static inline void rep_nop(void)
+{
+       __asm__ __volatile__("rep;nop": : :"memory");
+}
+
+#define cpu_relax()    rep_nop()
+
 #include <asm/processor-generic.h>
 
 #endif
index 018f732704ddb25a5d26bf9a58688083ac636a27..6c6689e574ce9057d5143b2f3196f9f11418f517 100644 (file)
@@ -45,16 +45,6 @@ static inline void arch_copy_thread(struct arch_thread *from,
         memcpy(&to->tls_array, &from->tls_array, sizeof(from->tls_array));
 }
 
-#include <asm/user.h>
-
-/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
-static inline void rep_nop(void)
-{
-       __asm__ __volatile__("rep;nop": : :"memory");
-}
-
-#define cpu_relax()    rep_nop()
-
 /*
  * Default implementation of macro that returns current
  * instruction pointer ("program counter"). Stolen
index 61de92d916c332e41eb1f1a6775bb8e571593dfa..4b02a8455bd1eb55056149630c596f9e4ea9dfd1 100644 (file)
@@ -14,14 +14,6 @@ struct arch_thread {
         struct faultinfo faultinfo;
 };
 
-/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
-static inline void rep_nop(void)
-{
-       __asm__ __volatile__("rep;nop": : :"memory");
-}
-
-#define cpu_relax()   rep_nop()
-
 #define INIT_ARCH_THREAD { .debugregs                  = { [ 0 ... 7 ] = 0 }, \
                           .debugregs_seq       = 0, \
                           .fs                  = 0, \
@@ -37,8 +29,6 @@ static inline void arch_copy_thread(struct arch_thread *from,
        to->fs = from->fs;
 }
 
-#include <asm/user.h>
-
 #define current_text_addr() \
        ({ void *pc; __asm__("movq $1f,%0\n1:":"=g" (pc)); pc; })
 
index a1fba5fb9dbe0630ddbf42c53f6221b6bb2b6d31..17d88cf2c6c419ff1e8fafc3c779f3a1453d9b59 100644 (file)
@@ -13,8 +13,6 @@
 static int host_has_cmov = 1;
 static jmp_buf cmov_test_return;
 
-#define TASK_PID(task) *((int *) &(((char *) (task))[HOST_TASK_PID]))
-
 static void cmov_sigill_test_handler(int sig)
 {
        host_has_cmov = 0;
@@ -51,7 +49,7 @@ void arch_examine_signal(int sig, struct uml_pt_regs *regs)
         * This is testing for a cmov (0x0f 0x4x) instruction causing a
         * SIGILL in init.
         */
-       if ((sig != SIGILL) || (TASK_PID(get_current()) != 1))
+       if ((sig != SIGILL) || (get_current_pid() != 1))
                return;
 
        if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) {
index decf8e4208569cffb7ef94c56b5c3fa636b0d34e..6f0459cb745b8ccf6f338fe4750258537dcefef6 100644 (file)
@@ -130,6 +130,10 @@ source "drivers/clocksource/Kconfig"
 
 source "drivers/iommu/Kconfig"
 
+source "drivers/remoteproc/Kconfig"
+
+source "drivers/rpmsg/Kconfig"
+
 source "drivers/virt/Kconfig"
 
 source "drivers/devfreq/Kconfig"
index 932e8bf203562dcd2b3e02b95e8eee39115e20f9..262b19d6b627a7541266f0f569f97197be06e906 100644 (file)
@@ -125,6 +125,8 @@ obj-y                               += clk/
 obj-$(CONFIG_HWSPINLOCK)       += hwspinlock/
 obj-$(CONFIG_NFC)              += nfc/
 obj-$(CONFIG_IOMMU_SUPPORT)    += iommu/
+obj-$(CONFIG_REMOTEPROC)       += remoteproc/
+obj-$(CONFIG_RPMSG)            += rpmsg/
 
 # Virtualization drivers
 obj-$(CONFIG_VIRT_DRIVERS)     += virt/
index a6278e7e61a00bfde01bcb6726524ffb3a06514e..013c7a549fb6dbc3d5d1afe2e01730e951846507 100644 (file)
 
 #include "rbd_types.h"
 
-#define DRV_NAME "rbd"
-#define DRV_NAME_LONG "rbd (rados block device)"
+/*
+ * The basic unit of block I/O is a sector.  It is interpreted in a
+ * number of contexts in Linux (blk, bio, genhd), but the default is
+ * universally 512 bytes.  These symbols are just slightly more
+ * meaningful than the bare numbers they represent.
+ */
+#define        SECTOR_SHIFT    9
+#define        SECTOR_SIZE     (1ULL << SECTOR_SHIFT)
+
+#define RBD_DRV_NAME "rbd"
+#define RBD_DRV_NAME_LONG "rbd (rados block device)"
 
 #define RBD_MINORS_PER_MAJOR   256             /* max minors per blkdev */
 
-#define RBD_MAX_MD_NAME_LEN    (96 + sizeof(RBD_SUFFIX))
+#define RBD_MAX_MD_NAME_LEN    (RBD_MAX_OBJ_NAME_LEN + sizeof(RBD_SUFFIX))
 #define RBD_MAX_POOL_NAME_LEN  64
 #define RBD_MAX_SNAP_NAME_LEN  32
 #define RBD_MAX_OPT_LEN                1024
 
 #define RBD_SNAP_HEAD_NAME     "-"
 
+/*
+ * An RBD device name will be "rbd#", where the "rbd" comes from
+ * RBD_DRV_NAME above, and # is a unique integer identifier.
+ * MAX_INT_FORMAT_WIDTH is used in ensuring DEV_NAME_LEN is big
+ * enough to hold all possible device names.
+ */
 #define DEV_NAME_LEN           32
+#define MAX_INT_FORMAT_WIDTH   ((5 * sizeof (int)) / 2 + 1)
 
 #define RBD_NOTIFY_TIMEOUT_DEFAULT 10
 
@@ -66,7 +82,6 @@ struct rbd_image_header {
        __u8 obj_order;
        __u8 crypt_type;
        __u8 comp_type;
-       struct rw_semaphore snap_rwsem;
        struct ceph_snap_context *snapc;
        size_t snap_names_len;
        u64 snap_seq;
@@ -83,7 +98,7 @@ struct rbd_options {
 };
 
 /*
- * an instance of the client.  multiple devices may share a client.
+ * an instance of the client.  multiple devices may share an rbd client.
  */
 struct rbd_client {
        struct ceph_client      *client;
@@ -92,20 +107,9 @@ struct rbd_client {
        struct list_head        node;
 };
 
-struct rbd_req_coll;
-
 /*
- * a single io request
+ * a request completion status
  */
-struct rbd_request {
-       struct request          *rq;            /* blk layer request */
-       struct bio              *bio;           /* cloned bio */
-       struct page             **pages;        /* list of used pages */
-       u64                     len;
-       int                     coll_index;
-       struct rbd_req_coll     *coll;
-};
-
 struct rbd_req_status {
        int done;
        int rc;
@@ -122,6 +126,18 @@ struct rbd_req_coll {
        struct rbd_req_status   status[0];
 };
 
+/*
+ * a single io request
+ */
+struct rbd_request {
+       struct request          *rq;            /* blk layer request */
+       struct bio              *bio;           /* cloned bio */
+       struct page             **pages;        /* list of used pages */
+       u64                     len;
+       int                     coll_index;
+       struct rbd_req_coll     *coll;
+};
+
 struct rbd_snap {
        struct  device          dev;
        const char              *name;
@@ -140,7 +156,6 @@ struct rbd_device {
        struct gendisk          *disk;          /* blkdev's gendisk and rq */
        struct request_queue    *q;
 
-       struct ceph_client      *client;
        struct rbd_client       *rbd_client;
 
        char                    name[DEV_NAME_LEN]; /* blkdev name, e.g. rbd3 */
@@ -157,6 +172,8 @@ struct rbd_device {
        struct ceph_osd_event   *watch_event;
        struct ceph_osd_request *watch_request;
 
+       /* protects updating the header */
+       struct rw_semaphore     header_rwsem;
        char                    snap_name[RBD_MAX_SNAP_NAME_LEN];
        u32 cur_snap;   /* index+1 of current snapshot within snap context
                           0 - for the head */
@@ -171,15 +188,13 @@ struct rbd_device {
        struct device           dev;
 };
 
-static struct bus_type rbd_bus_type = {
-       .name           = "rbd",
-};
-
-static spinlock_t node_lock;      /* protects client get/put */
-
 static DEFINE_MUTEX(ctl_mutex);          /* Serialize open/close/setup/teardown */
+
 static LIST_HEAD(rbd_dev_list);    /* devices */
-static LIST_HEAD(rbd_client_list);      /* clients */
+static DEFINE_SPINLOCK(rbd_dev_list_lock);
+
+static LIST_HEAD(rbd_client_list);             /* clients */
+static DEFINE_SPINLOCK(rbd_client_list_lock);
 
 static int __rbd_init_snaps_header(struct rbd_device *rbd_dev);
 static void rbd_dev_release(struct device *dev);
@@ -190,12 +205,32 @@ static ssize_t rbd_snap_add(struct device *dev,
 static void __rbd_remove_snap_dev(struct rbd_device *rbd_dev,
                                  struct rbd_snap *snap);
 
+static ssize_t rbd_add(struct bus_type *bus, const char *buf,
+                      size_t count);
+static ssize_t rbd_remove(struct bus_type *bus, const char *buf,
+                         size_t count);
 
-static struct rbd_device *dev_to_rbd(struct device *dev)
+static struct bus_attribute rbd_bus_attrs[] = {
+       __ATTR(add, S_IWUSR, NULL, rbd_add),
+       __ATTR(remove, S_IWUSR, NULL, rbd_remove),
+       __ATTR_NULL
+};
+
+static struct bus_type rbd_bus_type = {
+       .name           = "rbd",
+       .bus_attrs      = rbd_bus_attrs,
+};
+
+static void rbd_root_dev_release(struct device *dev)
 {
-       return container_of(dev, struct rbd_device, dev);
 }
 
+static struct device rbd_root_dev = {
+       .init_name =    "rbd",
+       .release =      rbd_root_dev_release,
+};
+
+
 static struct device *rbd_get_dev(struct rbd_device *rbd_dev)
 {
        return get_device(&rbd_dev->dev);
@@ -210,8 +245,7 @@ static int __rbd_update_snaps(struct rbd_device *rbd_dev);
 
 static int rbd_open(struct block_device *bdev, fmode_t mode)
 {
-       struct gendisk *disk = bdev->bd_disk;
-       struct rbd_device *rbd_dev = disk->private_data;
+       struct rbd_device *rbd_dev = bdev->bd_disk->private_data;
 
        rbd_get_dev(rbd_dev);
 
@@ -256,9 +290,11 @@ static struct rbd_client *rbd_client_create(struct ceph_options *opt,
        kref_init(&rbdc->kref);
        INIT_LIST_HEAD(&rbdc->node);
 
+       mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
+
        rbdc->client = ceph_create_client(opt, rbdc, 0, 0);
        if (IS_ERR(rbdc->client))
-               goto out_rbdc;
+               goto out_mutex;
        opt = NULL; /* Now rbdc->client is responsible for opt */
 
        ret = ceph_open_session(rbdc->client);
@@ -267,16 +303,19 @@ static struct rbd_client *rbd_client_create(struct ceph_options *opt,
 
        rbdc->rbd_opts = rbd_opts;
 
-       spin_lock(&node_lock);
+       spin_lock(&rbd_client_list_lock);
        list_add_tail(&rbdc->node, &rbd_client_list);
-       spin_unlock(&node_lock);
+       spin_unlock(&rbd_client_list_lock);
+
+       mutex_unlock(&ctl_mutex);
 
        dout("rbd_client_create created %p\n", rbdc);
        return rbdc;
 
 out_err:
        ceph_destroy_client(rbdc->client);
-out_rbdc:
+out_mutex:
+       mutex_unlock(&ctl_mutex);
        kfree(rbdc);
 out_opt:
        if (opt)
@@ -324,7 +363,7 @@ static int parse_rbd_opts_token(char *c, void *private)
        substring_t argstr[MAX_OPT_ARGS];
        int token, intval, ret;
 
-       token = match_token((char *)c, rbdopt_tokens, argstr);
+       token = match_token(c, rbdopt_tokens, argstr);
        if (token < 0)
                return -EINVAL;
 
@@ -357,58 +396,54 @@ static int parse_rbd_opts_token(char *c, void *private)
  * Get a ceph client with specific addr and configuration, if one does
  * not exist create it.
  */
-static int rbd_get_client(struct rbd_device *rbd_dev, const char *mon_addr,
-                         char *options)
+static struct rbd_client *rbd_get_client(const char *mon_addr,
+                                        size_t mon_addr_len,
+                                        char *options)
 {
        struct rbd_client *rbdc;
        struct ceph_options *opt;
-       int ret;
        struct rbd_options *rbd_opts;
 
        rbd_opts = kzalloc(sizeof(*rbd_opts), GFP_KERNEL);
        if (!rbd_opts)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
 
        rbd_opts->notify_timeout = RBD_NOTIFY_TIMEOUT_DEFAULT;
 
-       ret = ceph_parse_options(&opt, options, mon_addr,
-                                mon_addr + strlen(mon_addr), parse_rbd_opts_token, rbd_opts);
-       if (ret < 0)
-               goto done_err;
+       opt = ceph_parse_options(options, mon_addr,
+                               mon_addr + mon_addr_len,
+                               parse_rbd_opts_token, rbd_opts);
+       if (IS_ERR(opt)) {
+               kfree(rbd_opts);
+               return ERR_CAST(opt);
+       }
 
-       spin_lock(&node_lock);
+       spin_lock(&rbd_client_list_lock);
        rbdc = __rbd_client_find(opt);
        if (rbdc) {
+               /* using an existing client */
+               kref_get(&rbdc->kref);
+               spin_unlock(&rbd_client_list_lock);
+
                ceph_destroy_options(opt);
                kfree(rbd_opts);
 
-               /* using an existing client */
-               kref_get(&rbdc->kref);
-               rbd_dev->rbd_client = rbdc;
-               rbd_dev->client = rbdc->client;
-               spin_unlock(&node_lock);
-               return 0;
+               return rbdc;
        }
-       spin_unlock(&node_lock);
+       spin_unlock(&rbd_client_list_lock);
 
        rbdc = rbd_client_create(opt, rbd_opts);
-       if (IS_ERR(rbdc)) {
-               ret = PTR_ERR(rbdc);
-               goto done_err;
-       }
 
-       rbd_dev->rbd_client = rbdc;
-       rbd_dev->client = rbdc->client;
-       return 0;
-done_err:
-       kfree(rbd_opts);
-       return ret;
+       if (IS_ERR(rbdc))
+               kfree(rbd_opts);
+
+       return rbdc;
 }
 
 /*
  * Destroy ceph client
  *
- * Caller must hold node_lock.
+ * Caller must hold rbd_client_list_lock.
  */
 static void rbd_client_release(struct kref *kref)
 {
@@ -428,11 +463,10 @@ static void rbd_client_release(struct kref *kref)
  */
 static void rbd_put_client(struct rbd_device *rbd_dev)
 {
-       spin_lock(&node_lock);
+       spin_lock(&rbd_client_list_lock);
        kref_put(&rbd_dev->rbd_client->kref, rbd_client_release);
-       spin_unlock(&node_lock);
+       spin_unlock(&rbd_client_list_lock);
        rbd_dev->rbd_client = NULL;
-       rbd_dev->client = NULL;
 }
 
 /*
@@ -457,21 +491,19 @@ static int rbd_header_from_disk(struct rbd_image_header *header,
                                 gfp_t gfp_flags)
 {
        int i;
-       u32 snap_count = le32_to_cpu(ondisk->snap_count);
-       int ret = -ENOMEM;
+       u32 snap_count;
 
-       if (memcmp(ondisk, RBD_HEADER_TEXT, sizeof(RBD_HEADER_TEXT))) {
+       if (memcmp(ondisk, RBD_HEADER_TEXT, sizeof(RBD_HEADER_TEXT)))
                return -ENXIO;
-       }
 
-       init_rwsem(&header->snap_rwsem);
-       header->snap_names_len = le64_to_cpu(ondisk->snap_names_len);
+       snap_count = le32_to_cpu(ondisk->snap_count);
        header->snapc = kmalloc(sizeof(struct ceph_snap_context) +
-                               snap_count *
-                                sizeof(struct rbd_image_snap_ondisk),
+                               snap_count * sizeof (*ondisk),
                                gfp_flags);
        if (!header->snapc)
                return -ENOMEM;
+
+       header->snap_names_len = le64_to_cpu(ondisk->snap_names_len);
        if (snap_count) {
                header->snap_names = kmalloc(header->snap_names_len,
                                             GFP_KERNEL);
@@ -498,8 +530,7 @@ static int rbd_header_from_disk(struct rbd_image_header *header,
        header->snapc->num_snaps = snap_count;
        header->total_snaps = snap_count;
 
-       if (snap_count &&
-           allocated_snaps == snap_count) {
+       if (snap_count && allocated_snaps == snap_count) {
                for (i = 0; i < snap_count; i++) {
                        header->snapc->snaps[i] =
                                le64_to_cpu(ondisk->snaps[i].id);
@@ -518,7 +549,7 @@ err_names:
        kfree(header->snap_names);
 err_snapc:
        kfree(header->snapc);
-       return ret;
+       return -ENOMEM;
 }
 
 static int snap_index(struct rbd_image_header *header, int snap_num)
@@ -542,35 +573,34 @@ static int snap_by_name(struct rbd_image_header *header, const char *snap_name,
        int i;
        char *p = header->snap_names;
 
-       for (i = 0; i < header->total_snaps; i++, p += strlen(p) + 1) {
-               if (strcmp(snap_name, p) == 0)
-                       break;
-       }
-       if (i == header->total_snaps)
-               return -ENOENT;
-       if (seq)
-               *seq = header->snapc->snaps[i];
+       for (i = 0; i < header->total_snaps; i++) {
+               if (!strcmp(snap_name, p)) {
 
-       if (size)
-               *size = header->snap_sizes[i];
+                       /* Found it.  Pass back its id and/or size */
 
-       return i;
+                       if (seq)
+                               *seq = header->snapc->snaps[i];
+                       if (size)
+                               *size = header->snap_sizes[i];
+                       return i;
+               }
+               p += strlen(p) + 1;     /* Skip ahead to the next name */
+       }
+       return -ENOENT;
 }
 
-static int rbd_header_set_snap(struct rbd_device *dev,
-                              const char *snap_name,
-                              u64 *size)
+static int rbd_header_set_snap(struct rbd_device *dev, u64 *size)
 {
        struct rbd_image_header *header = &dev->header;
        struct ceph_snap_context *snapc = header->snapc;
        int ret = -ENOENT;
 
-       down_write(&header->snap_rwsem);
+       BUILD_BUG_ON(sizeof (dev->snap_name) < sizeof (RBD_SNAP_HEAD_NAME));
 
-       if (!snap_name ||
-           !*snap_name ||
-           strcmp(snap_name, "-") == 0 ||
-           strcmp(snap_name, RBD_SNAP_HEAD_NAME) == 0) {
+       down_write(&dev->header_rwsem);
+
+       if (!memcmp(dev->snap_name, RBD_SNAP_HEAD_NAME,
+                   sizeof (RBD_SNAP_HEAD_NAME))) {
                if (header->total_snaps)
                        snapc->seq = header->snap_seq;
                else
@@ -580,7 +610,7 @@ static int rbd_header_set_snap(struct rbd_device *dev,
                if (size)
                        *size = header->image_size;
        } else {
-               ret = snap_by_name(header, snap_name, &snapc->seq, size);
+               ret = snap_by_name(header, dev->snap_name, &snapc->seq, size);
                if (ret < 0)
                        goto done;
 
@@ -590,7 +620,7 @@ static int rbd_header_set_snap(struct rbd_device *dev,
 
        ret = 0;
 done:
-       up_write(&header->snap_rwsem);
+       up_write(&dev->header_rwsem);
        return ret;
 }
 
@@ -717,7 +747,7 @@ static struct bio *bio_chain_clone(struct bio **old, struct bio **next,
 
                        /* split the bio. We'll release it either in the next
                           call, or it will have to be released outside */
-                       bp = bio_split(old_chain, (len - total) / 512ULL);
+                       bp = bio_split(old_chain, (len - total) / SECTOR_SIZE);
                        if (!bp)
                                goto err_out;
 
@@ -857,7 +887,7 @@ static int rbd_do_request(struct request *rq,
        struct timespec mtime = CURRENT_TIME;
        struct rbd_request *req_data;
        struct ceph_osd_request_head *reqhead;
-       struct rbd_image_header *header = &dev->header;
+       struct ceph_osd_client *osdc;
 
        req_data = kzalloc(sizeof(*req_data), GFP_NOIO);
        if (!req_data) {
@@ -874,15 +904,13 @@ static int rbd_do_request(struct request *rq,
 
        dout("rbd_do_request obj=%s ofs=%lld len=%lld\n", obj, len, ofs);
 
-       down_read(&header->snap_rwsem);
+       down_read(&dev->header_rwsem);
 
-       req = ceph_osdc_alloc_request(&dev->client->osdc, flags,
-                                     snapc,
-                                     ops,
-                                     false,
-                                     GFP_NOIO, pages, bio);
+       osdc = &dev->rbd_client->client->osdc;
+       req = ceph_osdc_alloc_request(osdc, flags, snapc, ops,
+                                       false, GFP_NOIO, pages, bio);
        if (!req) {
-               up_read(&header->snap_rwsem);
+               up_read(&dev->header_rwsem);
                ret = -ENOMEM;
                goto done_pages;
        }
@@ -909,27 +937,27 @@ static int rbd_do_request(struct request *rq,
        layout->fl_object_size = cpu_to_le32(1 << RBD_MAX_OBJ_ORDER);
        layout->fl_pg_preferred = cpu_to_le32(-1);
        layout->fl_pg_pool = cpu_to_le32(dev->poolid);
-       ceph_calc_raw_layout(&dev->client->osdc, layout, snapid,
-                            ofs, &len, &bno, req, ops);
+       ceph_calc_raw_layout(osdc, layout, snapid, ofs, &len, &bno,
+                               req, ops);
 
        ceph_osdc_build_request(req, ofs, &len,
                                ops,
                                snapc,
                                &mtime,
                                req->r_oid, req->r_oid_len);
-       up_read(&header->snap_rwsem);
+       up_read(&dev->header_rwsem);
 
        if (linger_req) {
-               ceph_osdc_set_request_linger(&dev->client->osdc, req);
+               ceph_osdc_set_request_linger(osdc, req);
                *linger_req = req;
        }
 
-       ret = ceph_osdc_start_request(&dev->client->osdc, req, false);
+       ret = ceph_osdc_start_request(osdc, req, false);
        if (ret < 0)
                goto done_err;
 
        if (!rbd_cb) {
-               ret = ceph_osdc_wait_request(&dev->client->osdc, req);
+               ret = ceph_osdc_wait_request(osdc, req);
                if (ver)
                        *ver = le64_to_cpu(req->r_reassert_version.version);
                dout("reassert_ver=%lld\n",
@@ -1213,8 +1241,8 @@ static void rbd_watch_cb(u64 ver, u64 notify_id, u8 opcode, void *data)
        rc = __rbd_update_snaps(dev);
        mutex_unlock(&ctl_mutex);
        if (rc)
-               pr_warning(DRV_NAME "%d got notification but failed to update"
-                          " snaps: %d\n", dev->major, rc);
+               pr_warning(RBD_DRV_NAME "%d got notification but failed to "
+                          " update snaps: %d\n", dev->major, rc);
 
        rbd_req_sync_notify_ack(dev, ver, notify_id, dev->obj_md_name);
 }
@@ -1227,7 +1255,7 @@ static int rbd_req_sync_watch(struct rbd_device *dev,
                              u64 ver)
 {
        struct ceph_osd_req_op *ops;
-       struct ceph_osd_client *osdc = &dev->client->osdc;
+       struct ceph_osd_client *osdc = &dev->rbd_client->client->osdc;
 
        int ret = rbd_create_rw_ops(&ops, 1, CEPH_OSD_OP_WATCH, 0);
        if (ret < 0)
@@ -1314,7 +1342,7 @@ static int rbd_req_sync_notify(struct rbd_device *dev,
                          const char *obj)
 {
        struct ceph_osd_req_op *ops;
-       struct ceph_osd_client *osdc = &dev->client->osdc;
+       struct ceph_osd_client *osdc = &dev->rbd_client->client->osdc;
        struct ceph_osd_event *event;
        struct rbd_notify_info info;
        int payload_len = sizeof(u32) + sizeof(u32);
@@ -1421,9 +1449,7 @@ static void rbd_rq_fn(struct request_queue *q)
        struct request *rq;
        struct bio_pair *bp = NULL;
 
-       rq = blk_fetch_request(q);
-
-       while (1) {
+       while ((rq = blk_fetch_request(q))) {
                struct bio *bio;
                struct bio *rq_bio, *next_bio = NULL;
                bool do_write;
@@ -1441,32 +1467,32 @@ static void rbd_rq_fn(struct request_queue *q)
                /* filter out block requests we don't understand */
                if ((rq->cmd_type != REQ_TYPE_FS)) {
                        __blk_end_request_all(rq, 0);
-                       goto next;
+                       continue;
                }
 
                /* deduce our operation (read, write) */
                do_write = (rq_data_dir(rq) == WRITE);
 
                size = blk_rq_bytes(rq);
-               ofs = blk_rq_pos(rq) * 512ULL;
+               ofs = blk_rq_pos(rq) * SECTOR_SIZE;
                rq_bio = rq->bio;
                if (do_write && rbd_dev->read_only) {
                        __blk_end_request_all(rq, -EROFS);
-                       goto next;
+                       continue;
                }
 
                spin_unlock_irq(q->queue_lock);
 
                dout("%s 0x%x bytes at 0x%llx\n",
                     do_write ? "write" : "read",
-                    size, blk_rq_pos(rq) * 512ULL);
+                    size, blk_rq_pos(rq) * SECTOR_SIZE);
 
                num_segs = rbd_get_num_segments(&rbd_dev->header, ofs, size);
                coll = rbd_alloc_coll(num_segs);
                if (!coll) {
                        spin_lock_irq(q->queue_lock);
                        __blk_end_request_all(rq, -ENOMEM);
-                       goto next;
+                       continue;
                }
 
                do {
@@ -1512,8 +1538,6 @@ next_seg:
                if (bp)
                        bio_pair_release(bp);
                spin_lock_irq(q->queue_lock);
-next:
-               rq = blk_fetch_request(q);
        }
 }
 
@@ -1526,13 +1550,17 @@ static int rbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bmd,
                          struct bio_vec *bvec)
 {
        struct rbd_device *rbd_dev = q->queuedata;
-       unsigned int chunk_sectors = 1 << (rbd_dev->header.obj_order - 9);
-       sector_t sector = bmd->bi_sector + get_start_sect(bmd->bi_bdev);
-       unsigned int bio_sectors = bmd->bi_size >> 9;
+       unsigned int chunk_sectors;
+       sector_t sector;
+       unsigned int bio_sectors;
        int max;
 
+       chunk_sectors = 1 << (rbd_dev->header.obj_order - SECTOR_SHIFT);
+       sector = bmd->bi_sector + get_start_sect(bmd->bi_bdev);
+       bio_sectors = bmd->bi_size >> SECTOR_SHIFT;
+
        max =  (chunk_sectors - ((sector & (chunk_sectors - 1))
-                                + bio_sectors)) << 9;
+                                + bio_sectors)) << SECTOR_SHIFT;
        if (max < 0)
                max = 0; /* bio_add cannot handle a negative return */
        if (max <= bvec->bv_len && bio_sectors == 0)
@@ -1565,15 +1593,16 @@ static int rbd_read_header(struct rbd_device *rbd_dev,
        ssize_t rc;
        struct rbd_image_header_ondisk *dh;
        int snap_count = 0;
-       u64 snap_names_len = 0;
        u64 ver;
+       size_t len;
 
+       /*
+        * First reads the fixed-size header to determine the number
+        * of snapshots, then re-reads it, along with all snapshot
+        * records as well as their stored names.
+        */
+       len = sizeof (*dh);
        while (1) {
-               int len = sizeof(*dh) +
-                         snap_count * sizeof(struct rbd_image_snap_ondisk) +
-                         snap_names_len;
-
-               rc = -ENOMEM;
                dh = kmalloc(len, GFP_KERNEL);
                if (!dh)
                        return -ENOMEM;
@@ -1588,21 +1617,22 @@ static int rbd_read_header(struct rbd_device *rbd_dev,
 
                rc = rbd_header_from_disk(header, dh, snap_count, GFP_KERNEL);
                if (rc < 0) {
-                       if (rc == -ENXIO) {
+                       if (rc == -ENXIO)
                                pr_warning("unrecognized header format"
                                           " for image %s", rbd_dev->obj);
-                       }
                        goto out_dh;
                }
 
-               if (snap_count != header->total_snaps) {
-                       snap_count = header->total_snaps;
-                       snap_names_len = header->snap_names_len;
-                       rbd_header_free(header);
-                       kfree(dh);
-                       continue;
-               }
-               break;
+               if (snap_count == header->total_snaps)
+                       break;
+
+               snap_count = header->total_snaps;
+               len = sizeof (*dh) +
+                       snap_count * sizeof(struct rbd_image_snap_ondisk) +
+                       header->snap_names_len;
+
+               rbd_header_free(header);
+               kfree(dh);
        }
        header->obj_version = ver;
 
@@ -1623,13 +1653,14 @@ static int rbd_header_add_snap(struct rbd_device *dev,
        int ret;
        void *data, *p, *e;
        u64 ver;
+       struct ceph_mon_client *monc;
 
        /* we should create a snapshot only if we're pointing at the head */
        if (dev->cur_snap)
                return -EINVAL;
 
-       ret = ceph_monc_create_snapid(&dev->client->monc, dev->poolid,
-                                     &new_snapid);
+       monc = &dev->rbd_client->client->monc;
+       ret = ceph_monc_create_snapid(monc, dev->poolid, &new_snapid);
        dout("created snapid=%lld\n", new_snapid);
        if (ret < 0)
                return ret;
@@ -1684,9 +1715,9 @@ static int __rbd_update_snaps(struct rbd_device *rbd_dev)
                return ret;
 
        /* resized? */
-       set_capacity(rbd_dev->disk, h.image_size / 512ULL);
+       set_capacity(rbd_dev->disk, h.image_size / SECTOR_SIZE);
 
-       down_write(&rbd_dev->header.snap_rwsem);
+       down_write(&rbd_dev->header_rwsem);
 
        snap_seq = rbd_dev->header.snapc->seq;
        if (rbd_dev->header.total_snaps &&
@@ -1711,7 +1742,7 @@ static int __rbd_update_snaps(struct rbd_device *rbd_dev)
 
        ret = __rbd_init_snaps_header(rbd_dev);
 
-       up_write(&rbd_dev->header.snap_rwsem);
+       up_write(&rbd_dev->header_rwsem);
 
        return ret;
 }
@@ -1721,6 +1752,7 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
        struct gendisk *disk;
        struct request_queue *q;
        int rc;
+       u64 segment_size;
        u64 total_size = 0;
 
        /* contact OSD, request size info about the object being mapped */
@@ -1733,7 +1765,7 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
        if (rc)
                return rc;
 
-       rc = rbd_header_set_snap(rbd_dev, rbd_dev->snap_name, &total_size);
+       rc = rbd_header_set_snap(rbd_dev, &total_size);
        if (rc)
                return rc;
 
@@ -1743,7 +1775,7 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
        if (!disk)
                goto out;
 
-       snprintf(disk->disk_name, sizeof(disk->disk_name), DRV_NAME "%d",
+       snprintf(disk->disk_name, sizeof(disk->disk_name), RBD_DRV_NAME "%d",
                 rbd_dev->id);
        disk->major = rbd_dev->major;
        disk->first_minor = 0;
@@ -1756,11 +1788,15 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
        if (!q)
                goto out_disk;
 
+       /* We use the default size, but let's be explicit about it. */
+       blk_queue_physical_block_size(q, SECTOR_SIZE);
+
        /* set io sizes to object size */
-       blk_queue_max_hw_sectors(q, rbd_obj_bytes(&rbd_dev->header) / 512ULL);
-       blk_queue_max_segment_size(q, rbd_obj_bytes(&rbd_dev->header));
-       blk_queue_io_min(q, rbd_obj_bytes(&rbd_dev->header));
-       blk_queue_io_opt(q, rbd_obj_bytes(&rbd_dev->header));
+       segment_size = rbd_obj_bytes(&rbd_dev->header);
+       blk_queue_max_hw_sectors(q, segment_size / SECTOR_SIZE);
+       blk_queue_max_segment_size(q, segment_size);
+       blk_queue_io_min(q, segment_size);
+       blk_queue_io_opt(q, segment_size);
 
        blk_queue_merge_bvec(q, rbd_merge_bvec);
        disk->queue = q;
@@ -1771,7 +1807,7 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
        rbd_dev->q = q;
 
        /* finally, announce the disk to the world */
-       set_capacity(disk, total_size / 512ULL);
+       set_capacity(disk, total_size / SECTOR_SIZE);
        add_disk(disk);
 
        pr_info("%s: added with size 0x%llx\n",
@@ -1788,10 +1824,15 @@ out:
   sysfs
 */
 
+static struct rbd_device *dev_to_rbd_dev(struct device *dev)
+{
+       return container_of(dev, struct rbd_device, dev);
+}
+
 static ssize_t rbd_size_show(struct device *dev,
                             struct device_attribute *attr, char *buf)
 {
-       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+       struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
 
        return sprintf(buf, "%llu\n", (unsigned long long)rbd_dev->header.image_size);
 }
@@ -1799,7 +1840,7 @@ static ssize_t rbd_size_show(struct device *dev,
 static ssize_t rbd_major_show(struct device *dev,
                              struct device_attribute *attr, char *buf)
 {
-       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+       struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
 
        return sprintf(buf, "%d\n", rbd_dev->major);
 }
@@ -1807,15 +1848,16 @@ static ssize_t rbd_major_show(struct device *dev,
 static ssize_t rbd_client_id_show(struct device *dev,
                                  struct device_attribute *attr, char *buf)
 {
-       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+       struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
 
-       return sprintf(buf, "client%lld\n", ceph_client_id(rbd_dev->client));
+       return sprintf(buf, "client%lld\n",
+                       ceph_client_id(rbd_dev->rbd_client->client));
 }
 
 static ssize_t rbd_pool_show(struct device *dev,
                             struct device_attribute *attr, char *buf)
 {
-       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+       struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
 
        return sprintf(buf, "%s\n", rbd_dev->pool_name);
 }
@@ -1823,7 +1865,7 @@ static ssize_t rbd_pool_show(struct device *dev,
 static ssize_t rbd_name_show(struct device *dev,
                             struct device_attribute *attr, char *buf)
 {
-       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+       struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
 
        return sprintf(buf, "%s\n", rbd_dev->obj);
 }
@@ -1832,7 +1874,7 @@ static ssize_t rbd_snap_show(struct device *dev,
                             struct device_attribute *attr,
                             char *buf)
 {
-       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+       struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
 
        return sprintf(buf, "%s\n", rbd_dev->snap_name);
 }
@@ -1842,7 +1884,7 @@ static ssize_t rbd_image_refresh(struct device *dev,
                                 const char *buf,
                                 size_t size)
 {
-       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+       struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
        int rc;
        int ret = size;
 
@@ -1907,7 +1949,7 @@ static ssize_t rbd_snap_size_show(struct device *dev,
 {
        struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
 
-       return sprintf(buf, "%lld\n", (long long)snap->size);
+       return sprintf(buf, "%zd\n", snap->size);
 }
 
 static ssize_t rbd_snap_id_show(struct device *dev,
@@ -1916,7 +1958,7 @@ static ssize_t rbd_snap_id_show(struct device *dev,
 {
        struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
 
-       return sprintf(buf, "%lld\n", (long long)snap->id);
+       return sprintf(buf, "%llu\n", (unsigned long long) snap->id);
 }
 
 static DEVICE_ATTR(snap_size, S_IRUGO, rbd_snap_size_show, NULL);
@@ -2088,19 +2130,9 @@ static int __rbd_init_snaps_header(struct rbd_device *rbd_dev)
        return 0;
 }
 
-
-static void rbd_root_dev_release(struct device *dev)
-{
-}
-
-static struct device rbd_root_dev = {
-       .init_name =    "rbd",
-       .release =      rbd_root_dev_release,
-};
-
 static int rbd_bus_add_dev(struct rbd_device *rbd_dev)
 {
-       int ret = -ENOMEM;
+       int ret;
        struct device *dev;
        struct rbd_snap *snap;
 
@@ -2114,7 +2146,7 @@ static int rbd_bus_add_dev(struct rbd_device *rbd_dev)
        dev_set_name(dev, "%d", rbd_dev->id);
        ret = device_register(dev);
        if (ret < 0)
-               goto done_free;
+               goto out;
 
        list_for_each_entry(snap, &rbd_dev->snaps, node) {
                ret = rbd_register_snap_dev(rbd_dev, snap,
@@ -2122,10 +2154,7 @@ static int rbd_bus_add_dev(struct rbd_device *rbd_dev)
                if (ret < 0)
                        break;
        }
-
-       mutex_unlock(&ctl_mutex);
-       return 0;
-done_free:
+out:
        mutex_unlock(&ctl_mutex);
        return ret;
 }
@@ -2154,104 +2183,250 @@ static int rbd_init_watch_dev(struct rbd_device *rbd_dev)
        return ret;
 }
 
+static atomic64_t rbd_id_max = ATOMIC64_INIT(0);
+
+/*
+ * Get a unique rbd identifier for the given new rbd_dev, and add
+ * the rbd_dev to the global list.  The minimum rbd id is 1.
+ */
+static void rbd_id_get(struct rbd_device *rbd_dev)
+{
+       rbd_dev->id = atomic64_inc_return(&rbd_id_max);
+
+       spin_lock(&rbd_dev_list_lock);
+       list_add_tail(&rbd_dev->node, &rbd_dev_list);
+       spin_unlock(&rbd_dev_list_lock);
+}
+
+/*
+ * Remove an rbd_dev from the global list, and record that its
+ * identifier is no longer in use.
+ */
+static void rbd_id_put(struct rbd_device *rbd_dev)
+{
+       struct list_head *tmp;
+       int rbd_id = rbd_dev->id;
+       int max_id;
+
+       BUG_ON(rbd_id < 1);
+
+       spin_lock(&rbd_dev_list_lock);
+       list_del_init(&rbd_dev->node);
+
+       /*
+        * If the id being "put" is not the current maximum, there
+        * is nothing special we need to do.
+        */
+       if (rbd_id != atomic64_read(&rbd_id_max)) {
+               spin_unlock(&rbd_dev_list_lock);
+               return;
+       }
+
+       /*
+        * We need to update the current maximum id.  Search the
+        * list to find out what it is.  We're more likely to find
+        * the maximum at the end, so search the list backward.
+        */
+       max_id = 0;
+       list_for_each_prev(tmp, &rbd_dev_list) {
+               struct rbd_device *rbd_dev;
+
+               rbd_dev = list_entry(tmp, struct rbd_device, node);
+               if (rbd_id > max_id)
+                       max_id = rbd_id;
+       }
+       spin_unlock(&rbd_dev_list_lock);
+
+       /*
+        * The max id could have been updated by rbd_id_get(), in
+        * which case it now accurately reflects the new maximum.
+        * Be careful not to overwrite the maximum value in that
+        * case.
+        */
+       atomic64_cmpxchg(&rbd_id_max, rbd_id, max_id);
+}
+
+/*
+ * Skips over white space at *buf, and updates *buf to point to the
+ * first found non-space character (if any). Returns the length of
+ * the token (string of non-white space characters) found.  Note
+ * that *buf must be terminated with '\0'.
+ */
+static inline size_t next_token(const char **buf)
+{
+        /*
+        * These are the characters that produce nonzero for
+        * isspace() in the "C" and "POSIX" locales.
+        */
+        const char *spaces = " \f\n\r\t\v";
+
+        *buf += strspn(*buf, spaces);  /* Find start of token */
+
+       return strcspn(*buf, spaces);   /* Return token length */
+}
+
+/*
+ * Finds the next token in *buf, and if the provided token buffer is
+ * big enough, copies the found token into it.  The result, if
+ * copied, is guaranteed to be terminated with '\0'.  Note that *buf
+ * must be terminated with '\0' on entry.
+ *
+ * Returns the length of the token found (not including the '\0').
+ * Return value will be 0 if no token is found, and it will be >=
+ * token_size if the token would not fit.
+ *
+ * The *buf pointer will be updated to point beyond the end of the
+ * found token.  Note that this occurs even if the token buffer is
+ * too small to hold it.
+ */
+static inline size_t copy_token(const char **buf,
+                               char *token,
+                               size_t token_size)
+{
+        size_t len;
+
+       len = next_token(buf);
+       if (len < token_size) {
+               memcpy(token, *buf, len);
+               *(token + len) = '\0';
+       }
+       *buf += len;
+
+        return len;
+}
+
+/*
+ * This fills in the pool_name, obj, obj_len, snap_name, obj_len,
+ * rbd_dev, rbd_md_name, and name fields of the given rbd_dev, based
+ * on the list of monitor addresses and other options provided via
+ * /sys/bus/rbd/add.
+ */
+static int rbd_add_parse_args(struct rbd_device *rbd_dev,
+                             const char *buf,
+                             const char **mon_addrs,
+                             size_t *mon_addrs_size,
+                             char *options,
+                             size_t options_size)
+{
+       size_t  len;
+
+       /* The first four tokens are required */
+
+       len = next_token(&buf);
+       if (!len)
+               return -EINVAL;
+       *mon_addrs_size = len + 1;
+       *mon_addrs = buf;
+
+       buf += len;
+
+       len = copy_token(&buf, options, options_size);
+       if (!len || len >= options_size)
+               return -EINVAL;
+
+       len = copy_token(&buf, rbd_dev->pool_name, sizeof (rbd_dev->pool_name));
+       if (!len || len >= sizeof (rbd_dev->pool_name))
+               return -EINVAL;
+
+       len = copy_token(&buf, rbd_dev->obj, sizeof (rbd_dev->obj));
+       if (!len || len >= sizeof (rbd_dev->obj))
+               return -EINVAL;
+
+       /* We have the object length in hand, save it. */
+
+       rbd_dev->obj_len = len;
+
+       BUILD_BUG_ON(RBD_MAX_MD_NAME_LEN
+                               < RBD_MAX_OBJ_NAME_LEN + sizeof (RBD_SUFFIX));
+       sprintf(rbd_dev->obj_md_name, "%s%s", rbd_dev->obj, RBD_SUFFIX);
+
+       /*
+        * The snapshot name is optional, but it's an error if it's
+        * too long.  If no snapshot is supplied, fill in the default.
+        */
+       len = copy_token(&buf, rbd_dev->snap_name, sizeof (rbd_dev->snap_name));
+       if (!len)
+               memcpy(rbd_dev->snap_name, RBD_SNAP_HEAD_NAME,
+                       sizeof (RBD_SNAP_HEAD_NAME));
+       else if (len >= sizeof (rbd_dev->snap_name))
+               return -EINVAL;
+
+       return 0;
+}
+
 static ssize_t rbd_add(struct bus_type *bus,
                       const char *buf,
                       size_t count)
 {
-       struct ceph_osd_client *osdc;
        struct rbd_device *rbd_dev;
-       ssize_t rc = -ENOMEM;
-       int irc, new_id = 0;
-       struct list_head *tmp;
-       char *mon_dev_name;
-       char *options;
+       const char *mon_addrs = NULL;
+       size_t mon_addrs_size = 0;
+       char *options = NULL;
+       struct ceph_osd_client *osdc;
+       int rc = -ENOMEM;
 
        if (!try_module_get(THIS_MODULE))
                return -ENODEV;
 
-       mon_dev_name = kmalloc(RBD_MAX_OPT_LEN, GFP_KERNEL);
-       if (!mon_dev_name)
-               goto err_out_mod;
-
-       options = kmalloc(RBD_MAX_OPT_LEN, GFP_KERNEL);
-       if (!options)
-               goto err_mon_dev;
-
-       /* new rbd_device object */
        rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL);
        if (!rbd_dev)
-               goto err_out_opt;
+               goto err_nomem;
+       options = kmalloc(count, GFP_KERNEL);
+       if (!options)
+               goto err_nomem;
 
        /* static rbd_device initialization */
        spin_lock_init(&rbd_dev->lock);
        INIT_LIST_HEAD(&rbd_dev->node);
        INIT_LIST_HEAD(&rbd_dev->snaps);
+       init_rwsem(&rbd_dev->header_rwsem);
 
-       init_rwsem(&rbd_dev->header.snap_rwsem);
+       init_rwsem(&rbd_dev->header_rwsem);
 
        /* generate unique id: find highest unique id, add one */
-       mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-
-       list_for_each(tmp, &rbd_dev_list) {
-               struct rbd_device *rbd_dev;
+       rbd_id_get(rbd_dev);
 
-               rbd_dev = list_entry(tmp, struct rbd_device, node);
-               if (rbd_dev->id >= new_id)
-                       new_id = rbd_dev->id + 1;
-       }
-
-       rbd_dev->id = new_id;
-
-       /* add to global list */
-       list_add_tail(&rbd_dev->node, &rbd_dev_list);
+       /* Fill in the device name, now that we have its id. */
+       BUILD_BUG_ON(DEV_NAME_LEN
+                       < sizeof (RBD_DRV_NAME) + MAX_INT_FORMAT_WIDTH);
+       sprintf(rbd_dev->name, "%s%d", RBD_DRV_NAME, rbd_dev->id);
 
        /* parse add command */
-       if (sscanf(buf, "%" __stringify(RBD_MAX_OPT_LEN) "s "
-                  "%" __stringify(RBD_MAX_OPT_LEN) "s "
-                  "%" __stringify(RBD_MAX_POOL_NAME_LEN) "s "
-                  "%" __stringify(RBD_MAX_OBJ_NAME_LEN) "s"
-                  "%" __stringify(RBD_MAX_SNAP_NAME_LEN) "s",
-                  mon_dev_name, options, rbd_dev->pool_name,
-                  rbd_dev->obj, rbd_dev->snap_name) < 4) {
-               rc = -EINVAL;
-               goto err_out_slot;
-       }
-
-       if (rbd_dev->snap_name[0] == 0)
-               rbd_dev->snap_name[0] = '-';
-
-       rbd_dev->obj_len = strlen(rbd_dev->obj);
-       snprintf(rbd_dev->obj_md_name, sizeof(rbd_dev->obj_md_name), "%s%s",
-                rbd_dev->obj, RBD_SUFFIX);
-
-       /* initialize rest of new object */
-       snprintf(rbd_dev->name, DEV_NAME_LEN, DRV_NAME "%d", rbd_dev->id);
-       rc = rbd_get_client(rbd_dev, mon_dev_name, options);
-       if (rc < 0)
-               goto err_out_slot;
+       rc = rbd_add_parse_args(rbd_dev, buf, &mon_addrs, &mon_addrs_size,
+                               options, count);
+       if (rc)
+               goto err_put_id;
 
-       mutex_unlock(&ctl_mutex);
+       rbd_dev->rbd_client = rbd_get_client(mon_addrs, mon_addrs_size - 1,
+                                               options);
+       if (IS_ERR(rbd_dev->rbd_client)) {
+               rc = PTR_ERR(rbd_dev->rbd_client);
+               goto err_put_id;
+       }
 
        /* pick the pool */
-       osdc = &rbd_dev->client->osdc;
+       osdc = &rbd_dev->rbd_client->client->osdc;
        rc = ceph_pg_poolid_by_name(osdc->osdmap, rbd_dev->pool_name);
        if (rc < 0)
                goto err_out_client;
        rbd_dev->poolid = rc;
 
        /* register our block device */
-       irc = register_blkdev(0, rbd_dev->name);
-       if (irc < 0) {
-               rc = irc;
+       rc = register_blkdev(0, rbd_dev->name);
+       if (rc < 0)
                goto err_out_client;
-       }
-       rbd_dev->major = irc;
+       rbd_dev->major = rc;
 
        rc = rbd_bus_add_dev(rbd_dev);
        if (rc)
                goto err_out_blkdev;
 
-       /* set up and announce blkdev mapping */
+       /*
+        * At this point cleanup in the event of an error is the job
+        * of the sysfs code (initiated by rbd_bus_del_dev()).
+        *
+        * Set up and announce blkdev mapping.
+        */
        rc = rbd_init_disk(rbd_dev);
        if (rc)
                goto err_out_bus;
@@ -2263,35 +2438,26 @@ static ssize_t rbd_add(struct bus_type *bus,
        return count;
 
 err_out_bus:
-       mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-       list_del_init(&rbd_dev->node);
-       mutex_unlock(&ctl_mutex);
-
        /* this will also clean up rest of rbd_dev stuff */
 
        rbd_bus_del_dev(rbd_dev);
        kfree(options);
-       kfree(mon_dev_name);
        return rc;
 
 err_out_blkdev:
        unregister_blkdev(rbd_dev->major, rbd_dev->name);
 err_out_client:
        rbd_put_client(rbd_dev);
-       mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-err_out_slot:
-       list_del_init(&rbd_dev->node);
-       mutex_unlock(&ctl_mutex);
-
-       kfree(rbd_dev);
-err_out_opt:
+err_put_id:
+       rbd_id_put(rbd_dev);
+err_nomem:
        kfree(options);
-err_mon_dev:
-       kfree(mon_dev_name);
-err_out_mod:
+       kfree(rbd_dev);
+
        dout("Error adding device %s\n", buf);
        module_put(THIS_MODULE);
-       return rc;
+
+       return (ssize_t) rc;
 }
 
 static struct rbd_device *__rbd_get_dev(unsigned long id)
@@ -2299,22 +2465,28 @@ static struct rbd_device *__rbd_get_dev(unsigned long id)
        struct list_head *tmp;
        struct rbd_device *rbd_dev;
 
+       spin_lock(&rbd_dev_list_lock);
        list_for_each(tmp, &rbd_dev_list) {
                rbd_dev = list_entry(tmp, struct rbd_device, node);
-               if (rbd_dev->id == id)
+               if (rbd_dev->id == id) {
+                       spin_unlock(&rbd_dev_list_lock);
                        return rbd_dev;
+               }
        }
+       spin_unlock(&rbd_dev_list_lock);
        return NULL;
 }
 
 static void rbd_dev_release(struct device *dev)
 {
-       struct rbd_device *rbd_dev =
-                       container_of(dev, struct rbd_device, dev);
+       struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
 
-       if (rbd_dev->watch_request)
-               ceph_osdc_unregister_linger_request(&rbd_dev->client->osdc,
+       if (rbd_dev->watch_request) {
+               struct ceph_client *client = rbd_dev->rbd_client->client;
+
+               ceph_osdc_unregister_linger_request(&client->osdc,
                                                    rbd_dev->watch_request);
+       }
        if (rbd_dev->watch_event)
                rbd_req_sync_unwatch(rbd_dev, rbd_dev->obj_md_name);
 
@@ -2323,6 +2495,9 @@ static void rbd_dev_release(struct device *dev)
        /* clean up and free blkdev */
        rbd_free_disk(rbd_dev);
        unregister_blkdev(rbd_dev->major, rbd_dev->name);
+
+       /* done with the id, and with the rbd_dev */
+       rbd_id_put(rbd_dev);
        kfree(rbd_dev);
 
        /* release module ref */
@@ -2355,8 +2530,6 @@ static ssize_t rbd_remove(struct bus_type *bus,
                goto done;
        }
 
-       list_del_init(&rbd_dev->node);
-
        __rbd_remove_all_snaps(rbd_dev);
        rbd_bus_del_dev(rbd_dev);
 
@@ -2370,7 +2543,7 @@ static ssize_t rbd_snap_add(struct device *dev,
                            const char *buf,
                            size_t count)
 {
-       struct rbd_device *rbd_dev = dev_to_rbd(dev);
+       struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
        int ret;
        char *name = kmalloc(count + 1, GFP_KERNEL);
        if (!name)
@@ -2406,12 +2579,6 @@ err_unlock:
        return ret;
 }
 
-static struct bus_attribute rbd_bus_attrs[] = {
-       __ATTR(add, S_IWUSR, NULL, rbd_add),
-       __ATTR(remove, S_IWUSR, NULL, rbd_remove),
-       __ATTR_NULL
-};
-
 /*
  * create control files in sysfs
  * /sys/bus/rbd/...
@@ -2420,21 +2587,21 @@ static int rbd_sysfs_init(void)
 {
        int ret;
 
-       rbd_bus_type.bus_attrs = rbd_bus_attrs;
-
-       ret = bus_register(&rbd_bus_type);
-        if (ret < 0)
+       ret = device_register(&rbd_root_dev);
+       if (ret < 0)
                return ret;
 
-       ret = device_register(&rbd_root_dev);
+       ret = bus_register(&rbd_bus_type);
+       if (ret < 0)
+               device_unregister(&rbd_root_dev);
 
        return ret;
 }
 
 static void rbd_sysfs_cleanup(void)
 {
-       device_unregister(&rbd_root_dev);
        bus_unregister(&rbd_bus_type);
+       device_unregister(&rbd_root_dev);
 }
 
 int __init rbd_init(void)
@@ -2444,8 +2611,7 @@ int __init rbd_init(void)
        rc = rbd_sysfs_init();
        if (rc)
                return rc;
-       spin_lock_init(&node_lock);
-       pr_info("loaded " DRV_NAME_LONG "\n");
+       pr_info("loaded " RBD_DRV_NAME_LONG "\n");
        return 0;
 }
 
index fc6c678aa2cb3971333f602eb9d71008d73041ac..950708688f1719109962e86b450186c845f89cf7 100644 (file)
 #define RBD_HEADER_SIGNATURE   "RBD"
 #define RBD_HEADER_VERSION     "001.005"
 
-struct rbd_info {
-       __le64 max_id;
-} __attribute__ ((packed));
-
 struct rbd_image_snap_ondisk {
        __le64 id;
        __le64 image_size;
index b757fac3cd1f123f335578a0b1efd67fc2250d2a..a07a5caa599cde1f0acf41c6dc4bbd32c9d92f36 100644 (file)
@@ -26,6 +26,8 @@
 
 #include <asm/io.h>
 
+#include <plat/cpu.h>
+
 #define RNG_OUT_REG            0x00            /* Output register */
 #define RNG_STAT_REG           0x04            /* Status register
                                                        [0] = STAT_BUSY */
index 9b3cd08cd0ed5a5ed110e866d9eb6ad2a0ec3cba..165e1febae53676458e3d24256f08b547d14d0d8 100644 (file)
@@ -8,3 +8,40 @@ config HAVE_CLK_PREPARE
 
 config HAVE_MACH_CLKDEV
        bool
+
+config COMMON_CLK
+       bool
+       select HAVE_CLK_PREPARE
+       ---help---
+         The common clock framework is a single definition of struct
+         clk, useful across many platforms, as well as an
+         implementation of the clock API in include/linux/clk.h.
+         Architectures utilizing the common struct clk should select
+         this option.
+
+menu "Common Clock Framework"
+       depends on COMMON_CLK
+
+config COMMON_CLK_DISABLE_UNUSED
+       bool "Disabled unused clocks at boot"
+       depends on COMMON_CLK
+       ---help---
+         Traverses the entire clock tree and disables any clocks that are
+         enabled in hardware but have not been enabled by any device drivers.
+         This saves power and keeps the software model of the clock in line
+         with reality.
+
+         If in doubt, say "N".
+
+config COMMON_CLK_DEBUG
+       bool "DebugFS representation of clock tree"
+       depends on COMMON_CLK
+       select DEBUG_FS
+       ---help---
+         Creates a directory hierchy in debugfs for visualizing the clk
+         tree structure.  Each directory contains read-only members
+         that export information specific to that clk node: clk_rate,
+         clk_flags, clk_prepare_count, clk_enable_count &
+         clk_notifier_count.
+
+endmenu
index 07613fa172c99d6b59ab0f0294ae144fed3de6a7..1f736bc11c4bb26f887c4480d9484c64274a0d90 100644 (file)
@@ -1,2 +1,4 @@
 
 obj-$(CONFIG_CLKDEV_LOOKUP)    += clkdev.o
+obj-$(CONFIG_COMMON_CLK)       += clk.o clk-fixed-rate.o clk-gate.o \
+                                  clk-mux.o clk-divider.o
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
new file mode 100644 (file)
index 0000000..d5ac6a7
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ * Copyright (C) 2011 Richard Zhao, Linaro <richard.zhao@linaro.org>
+ * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Adjustable divider clock implementation
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/string.h>
+
+/*
+ * DOC: basic adjustable divider clock that cannot gate
+ *
+ * Traits of this clock:
+ * prepare - clk_prepare only ensures that parents are prepared
+ * enable - clk_enable only ensures that parents are enabled
+ * rate - rate is adjustable.  clk->rate = parent->rate / divisor
+ * parent - fixed parent.  No clk_set_parent support
+ */
+
+#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
+
+#define div_mask(d)    ((1 << (d->width)) - 1)
+
+static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clk_divider *divider = to_clk_divider(hw);
+       unsigned int div;
+
+       div = readl(divider->reg) >> divider->shift;
+       div &= div_mask(divider);
+
+       if (!(divider->flags & CLK_DIVIDER_ONE_BASED))
+               div++;
+
+       return parent_rate / div;
+}
+EXPORT_SYMBOL_GPL(clk_divider_recalc_rate);
+
+/*
+ * The reverse of DIV_ROUND_UP: The maximum number which
+ * divided by m is r
+ */
+#define MULT_ROUND_UP(r, m) ((r) * (m) + (m) - 1)
+
+static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
+               unsigned long *best_parent_rate)
+{
+       struct clk_divider *divider = to_clk_divider(hw);
+       int i, bestdiv = 0;
+       unsigned long parent_rate, best = 0, now, maxdiv;
+
+       if (!rate)
+               rate = 1;
+
+       maxdiv = (1 << divider->width);
+
+       if (divider->flags & CLK_DIVIDER_ONE_BASED)
+               maxdiv--;
+
+       if (!best_parent_rate) {
+               parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
+               bestdiv = DIV_ROUND_UP(parent_rate, rate);
+               bestdiv = bestdiv == 0 ? 1 : bestdiv;
+               bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv;
+               return bestdiv;
+       }
+
+       /*
+        * The maximum divider we can use without overflowing
+        * unsigned long in rate * i below
+        */
+       maxdiv = min(ULONG_MAX / rate, maxdiv);
+
+       for (i = 1; i <= maxdiv; i++) {
+               parent_rate = __clk_round_rate(__clk_get_parent(hw->clk),
+                               MULT_ROUND_UP(rate, i));
+               now = parent_rate / i;
+               if (now <= rate && now > best) {
+                       bestdiv = i;
+                       best = now;
+                       *best_parent_rate = parent_rate;
+               }
+       }
+
+       if (!bestdiv) {
+               bestdiv = (1 << divider->width);
+               if (divider->flags & CLK_DIVIDER_ONE_BASED)
+                       bestdiv--;
+               *best_parent_rate = __clk_round_rate(__clk_get_parent(hw->clk), 1);
+       }
+
+       return bestdiv;
+}
+
+static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long *prate)
+{
+       int div;
+       div = clk_divider_bestdiv(hw, rate, prate);
+
+       if (prate)
+               return *prate / div;
+       else {
+               unsigned long r;
+               r = __clk_get_rate(__clk_get_parent(hw->clk));
+               return r / div;
+       }
+}
+EXPORT_SYMBOL_GPL(clk_divider_round_rate);
+
+static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate)
+{
+       struct clk_divider *divider = to_clk_divider(hw);
+       unsigned int div;
+       unsigned long flags = 0;
+       u32 val;
+
+       div = __clk_get_rate(__clk_get_parent(hw->clk)) / rate;
+
+       if (!(divider->flags & CLK_DIVIDER_ONE_BASED))
+               div--;
+
+       if (div > div_mask(divider))
+               div = div_mask(divider);
+
+       if (divider->lock)
+               spin_lock_irqsave(divider->lock, flags);
+
+       val = readl(divider->reg);
+       val &= ~(div_mask(divider) << divider->shift);
+       val |= div << divider->shift;
+       writel(val, divider->reg);
+
+       if (divider->lock)
+               spin_unlock_irqrestore(divider->lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(clk_divider_set_rate);
+
+struct clk_ops clk_divider_ops = {
+       .recalc_rate = clk_divider_recalc_rate,
+       .round_rate = clk_divider_round_rate,
+       .set_rate = clk_divider_set_rate,
+};
+EXPORT_SYMBOL_GPL(clk_divider_ops);
+
+struct clk *clk_register_divider(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width,
+               u8 clk_divider_flags, spinlock_t *lock)
+{
+       struct clk_divider *div;
+       struct clk *clk;
+
+       div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL);
+
+       if (!div) {
+               pr_err("%s: could not allocate divider clk\n", __func__);
+               return NULL;
+       }
+
+       /* struct clk_divider assignments */
+       div->reg = reg;
+       div->shift = shift;
+       div->width = width;
+       div->flags = clk_divider_flags;
+       div->lock = lock;
+
+       if (parent_name) {
+               div->parent[0] = kstrdup(parent_name, GFP_KERNEL);
+               if (!div->parent[0])
+                       goto out;
+       }
+
+       clk = clk_register(dev, name,
+                       &clk_divider_ops, &div->hw,
+                       div->parent,
+                       (parent_name ? 1 : 0),
+                       flags);
+       if (clk)
+               return clk;
+
+out:
+       kfree(div->parent[0]);
+       kfree(div);
+
+       return NULL;
+}
diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c
new file mode 100644 (file)
index 0000000..90c79fb
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
+ * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Fixed rate clock implementation
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+
+/*
+ * DOC: basic fixed-rate clock that cannot gate
+ *
+ * Traits of this clock:
+ * prepare - clk_(un)prepare only ensures parents are prepared
+ * enable - clk_enable only ensures parents are enabled
+ * rate - rate is always a fixed value.  No clk_set_rate support
+ * parent - fixed parent.  No clk_set_parent support
+ */
+
+#define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw)
+
+static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       return to_clk_fixed_rate(hw)->fixed_rate;
+}
+EXPORT_SYMBOL_GPL(clk_fixed_rate_recalc_rate);
+
+struct clk_ops clk_fixed_rate_ops = {
+       .recalc_rate = clk_fixed_rate_recalc_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_rate_ops);
+
+struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               unsigned long fixed_rate)
+{
+       struct clk_fixed_rate *fixed;
+       char **parent_names = NULL;
+       u8 len;
+
+       fixed = kzalloc(sizeof(struct clk_fixed_rate), GFP_KERNEL);
+
+       if (!fixed) {
+               pr_err("%s: could not allocate fixed clk\n", __func__);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       /* struct clk_fixed_rate assignments */
+       fixed->fixed_rate = fixed_rate;
+
+       if (parent_name) {
+               parent_names = kmalloc(sizeof(char *), GFP_KERNEL);
+
+               if (! parent_names)
+                       goto out;
+
+               len = sizeof(char) * strlen(parent_name);
+
+               parent_names[0] = kmalloc(len, GFP_KERNEL);
+
+               if (!parent_names[0])
+                       goto out;
+
+               strncpy(parent_names[0], parent_name, len);
+       }
+
+out:
+       return clk_register(dev, name,
+                       &clk_fixed_rate_ops, &fixed->hw,
+                       parent_names,
+                       (parent_name ? 1 : 0),
+                       flags);
+}
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
new file mode 100644 (file)
index 0000000..b5902e2
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
+ * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Gated clock implementation
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/string.h>
+
+/**
+ * DOC: basic gatable clock which can gate and ungate it's ouput
+ *
+ * Traits of this clock:
+ * prepare - clk_(un)prepare only ensures parent is (un)prepared
+ * enable - clk_enable and clk_disable are functional & control gating
+ * rate - inherits rate from parent.  No clk_set_rate support
+ * parent - fixed parent.  No clk_set_parent support
+ */
+
+#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
+
+static void clk_gate_set_bit(struct clk_gate *gate)
+{
+       u32 reg;
+       unsigned long flags = 0;
+
+       if (gate->lock)
+               spin_lock_irqsave(gate->lock, flags);
+
+       reg = readl(gate->reg);
+       reg |= BIT(gate->bit_idx);
+       writel(reg, gate->reg);
+
+       if (gate->lock)
+               spin_unlock_irqrestore(gate->lock, flags);
+}
+
+static void clk_gate_clear_bit(struct clk_gate *gate)
+{
+       u32 reg;
+       unsigned long flags = 0;
+
+       if (gate->lock)
+               spin_lock_irqsave(gate->lock, flags);
+
+       reg = readl(gate->reg);
+       reg &= ~BIT(gate->bit_idx);
+       writel(reg, gate->reg);
+
+       if (gate->lock)
+               spin_unlock_irqrestore(gate->lock, flags);
+}
+
+static int clk_gate_enable(struct clk_hw *hw)
+{
+       struct clk_gate *gate = to_clk_gate(hw);
+
+       if (gate->flags & CLK_GATE_SET_TO_DISABLE)
+               clk_gate_clear_bit(gate);
+       else
+               clk_gate_set_bit(gate);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(clk_gate_enable);
+
+static void clk_gate_disable(struct clk_hw *hw)
+{
+       struct clk_gate *gate = to_clk_gate(hw);
+
+       if (gate->flags & CLK_GATE_SET_TO_DISABLE)
+               clk_gate_set_bit(gate);
+       else
+               clk_gate_clear_bit(gate);
+}
+EXPORT_SYMBOL_GPL(clk_gate_disable);
+
+static int clk_gate_is_enabled(struct clk_hw *hw)
+{
+       u32 reg;
+       struct clk_gate *gate = to_clk_gate(hw);
+
+       reg = readl(gate->reg);
+
+       /* if a set bit disables this clk, flip it before masking */
+       if (gate->flags & CLK_GATE_SET_TO_DISABLE)
+               reg ^= BIT(gate->bit_idx);
+
+       reg &= BIT(gate->bit_idx);
+
+       return reg ? 1 : 0;
+}
+EXPORT_SYMBOL_GPL(clk_gate_is_enabled);
+
+struct clk_ops clk_gate_ops = {
+       .enable = clk_gate_enable,
+       .disable = clk_gate_disable,
+       .is_enabled = clk_gate_is_enabled,
+};
+EXPORT_SYMBOL_GPL(clk_gate_ops);
+
+struct clk *clk_register_gate(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               void __iomem *reg, u8 bit_idx,
+               u8 clk_gate_flags, spinlock_t *lock)
+{
+       struct clk_gate *gate;
+       struct clk *clk;
+
+       gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
+
+       if (!gate) {
+               pr_err("%s: could not allocate gated clk\n", __func__);
+               return NULL;
+       }
+
+       /* struct clk_gate assignments */
+       gate->reg = reg;
+       gate->bit_idx = bit_idx;
+       gate->flags = clk_gate_flags;
+       gate->lock = lock;
+
+       if (parent_name) {
+               gate->parent[0] = kstrdup(parent_name, GFP_KERNEL);
+               if (!gate->parent[0])
+                       goto out;
+       }
+
+       clk = clk_register(dev, name,
+                       &clk_gate_ops, &gate->hw,
+                       gate->parent,
+                       (parent_name ? 1 : 0),
+                       flags);
+       if (clk)
+               return clk;
+out:
+       kfree(gate->parent[0]);
+       kfree(gate);
+
+       return NULL;
+}
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
new file mode 100644 (file)
index 0000000..c71ad1f
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ * Copyright (C) 2011 Richard Zhao, Linaro <richard.zhao@linaro.org>
+ * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Simple multiplexer clock implementation
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+
+/*
+ * DOC: basic adjustable multiplexer clock that cannot gate
+ *
+ * Traits of this clock:
+ * prepare - clk_prepare only ensures that parents are prepared
+ * enable - clk_enable only ensures that parents are enabled
+ * rate - rate is only affected by parent switching.  No clk_set_rate support
+ * parent - parent is adjustable through clk_set_parent
+ */
+
+#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw)
+
+static u8 clk_mux_get_parent(struct clk_hw *hw)
+{
+       struct clk_mux *mux = to_clk_mux(hw);
+       u32 val;
+
+       /*
+        * FIXME need a mux-specific flag to determine if val is bitwise or numeric
+        * e.g. sys_clkin_ck's clksel field is 3 bits wide, but ranges from 0x1
+        * to 0x7 (index starts at one)
+        * OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so
+        * val = 0x4 really means "bit 2, index starts at bit 0"
+        */
+       val = readl(mux->reg) >> mux->shift;
+       val &= (1 << mux->width) - 1;
+
+       if (val && (mux->flags & CLK_MUX_INDEX_BIT))
+               val = ffs(val) - 1;
+
+       if (val && (mux->flags & CLK_MUX_INDEX_ONE))
+               val--;
+
+       if (val >= __clk_get_num_parents(hw->clk))
+               return -EINVAL;
+
+       return val;
+}
+EXPORT_SYMBOL_GPL(clk_mux_get_parent);
+
+static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct clk_mux *mux = to_clk_mux(hw);
+       u32 val;
+       unsigned long flags = 0;
+
+       if (mux->flags & CLK_MUX_INDEX_BIT)
+               index = (1 << ffs(index));
+
+       if (mux->flags & CLK_MUX_INDEX_ONE)
+               index++;
+
+       if (mux->lock)
+               spin_lock_irqsave(mux->lock, flags);
+
+       val = readl(mux->reg);
+       val &= ~(((1 << mux->width) - 1) << mux->shift);
+       val |= index << mux->shift;
+       writel(val, mux->reg);
+
+       if (mux->lock)
+               spin_unlock_irqrestore(mux->lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(clk_mux_set_parent);
+
+struct clk_ops clk_mux_ops = {
+       .get_parent = clk_mux_get_parent,
+       .set_parent = clk_mux_set_parent,
+};
+EXPORT_SYMBOL_GPL(clk_mux_ops);
+
+struct clk *clk_register_mux(struct device *dev, const char *name,
+               char **parent_names, u8 num_parents, unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width,
+               u8 clk_mux_flags, spinlock_t *lock)
+{
+       struct clk_mux *mux;
+
+       mux = kmalloc(sizeof(struct clk_mux), GFP_KERNEL);
+
+       if (!mux) {
+               pr_err("%s: could not allocate mux clk\n", __func__);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       /* struct clk_mux assignments */
+       mux->reg = reg;
+       mux->shift = shift;
+       mux->width = width;
+       mux->flags = clk_mux_flags;
+       mux->lock = lock;
+
+       return clk_register(dev, name, &clk_mux_ops, &mux->hw,
+                       parent_names, num_parents, flags);
+}
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
new file mode 100644 (file)
index 0000000..9cf6f59
--- /dev/null
@@ -0,0 +1,1461 @@
+/*
+ * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
+ * Copyright (C) 2011-2012 Linaro Ltd <mturquette@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Standard functionality for the common clock API.  See Documentation/clk.txt
+ */
+
+#include <linux/clk-private.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+
+static DEFINE_SPINLOCK(enable_lock);
+static DEFINE_MUTEX(prepare_lock);
+
+static HLIST_HEAD(clk_root_list);
+static HLIST_HEAD(clk_orphan_list);
+static LIST_HEAD(clk_notifier_list);
+
+/***        debugfs support        ***/
+
+#ifdef CONFIG_COMMON_CLK_DEBUG
+#include <linux/debugfs.h>
+
+static struct dentry *rootdir;
+static struct dentry *orphandir;
+static int inited = 0;
+
+/* caller must hold prepare_lock */
+static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry)
+{
+       struct dentry *d;
+       int ret = -ENOMEM;
+
+       if (!clk || !pdentry) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       d = debugfs_create_dir(clk->name, pdentry);
+       if (!d)
+               goto out;
+
+       clk->dentry = d;
+
+       d = debugfs_create_u32("clk_rate", S_IRUGO, clk->dentry,
+                       (u32 *)&clk->rate);
+       if (!d)
+               goto err_out;
+
+       d = debugfs_create_x32("clk_flags", S_IRUGO, clk->dentry,
+                       (u32 *)&clk->flags);
+       if (!d)
+               goto err_out;
+
+       d = debugfs_create_u32("clk_prepare_count", S_IRUGO, clk->dentry,
+                       (u32 *)&clk->prepare_count);
+       if (!d)
+               goto err_out;
+
+       d = debugfs_create_u32("clk_enable_count", S_IRUGO, clk->dentry,
+                       (u32 *)&clk->enable_count);
+       if (!d)
+               goto err_out;
+
+       d = debugfs_create_u32("clk_notifier_count", S_IRUGO, clk->dentry,
+                       (u32 *)&clk->notifier_count);
+       if (!d)
+               goto err_out;
+
+       ret = 0;
+       goto out;
+
+err_out:
+       debugfs_remove(clk->dentry);
+out:
+       return ret;
+}
+
+/* caller must hold prepare_lock */
+static int clk_debug_create_subtree(struct clk *clk, struct dentry *pdentry)
+{
+       struct clk *child;
+       struct hlist_node *tmp;
+       int ret = -EINVAL;;
+
+       if (!clk || !pdentry)
+               goto out;
+
+       ret = clk_debug_create_one(clk, pdentry);
+
+       if (ret)
+               goto out;
+
+       hlist_for_each_entry(child, tmp, &clk->children, child_node)
+               clk_debug_create_subtree(child, clk->dentry);
+
+       ret = 0;
+out:
+       return ret;
+}
+
+/**
+ * clk_debug_register - add a clk node to the debugfs clk tree
+ * @clk: the clk being added to the debugfs clk tree
+ *
+ * Dynamically adds a clk to the debugfs clk tree if debugfs has been
+ * initialized.  Otherwise it bails out early since the debugfs clk tree
+ * will be created lazily by clk_debug_init as part of a late_initcall.
+ *
+ * Caller must hold prepare_lock.  Only clk_init calls this function (so
+ * far) so this is taken care.
+ */
+static int clk_debug_register(struct clk *clk)
+{
+       struct clk *parent;
+       struct dentry *pdentry;
+       int ret = 0;
+
+       if (!inited)
+               goto out;
+
+       parent = clk->parent;
+
+       /*
+        * Check to see if a clk is a root clk.  Also check that it is
+        * safe to add this clk to debugfs
+        */
+       if (!parent)
+               if (clk->flags & CLK_IS_ROOT)
+                       pdentry = rootdir;
+               else
+                       pdentry = orphandir;
+       else
+               if (parent->dentry)
+                       pdentry = parent->dentry;
+               else
+                       goto out;
+
+       ret = clk_debug_create_subtree(clk, pdentry);
+
+out:
+       return ret;
+}
+
+/**
+ * clk_debug_init - lazily create the debugfs clk tree visualization
+ *
+ * clks are often initialized very early during boot before memory can
+ * be dynamically allocated and well before debugfs is setup.
+ * clk_debug_init walks the clk tree hierarchy while holding
+ * prepare_lock and creates the topology as part of a late_initcall,
+ * thus insuring that clks initialized very early will still be
+ * represented in the debugfs clk tree.  This function should only be
+ * called once at boot-time, and all other clks added dynamically will
+ * be done so with clk_debug_register.
+ */
+static int __init clk_debug_init(void)
+{
+       struct clk *clk;
+       struct hlist_node *tmp;
+
+       rootdir = debugfs_create_dir("clk", NULL);
+
+       if (!rootdir)
+               return -ENOMEM;
+
+       orphandir = debugfs_create_dir("orphans", rootdir);
+
+       if (!orphandir)
+               return -ENOMEM;
+
+       mutex_lock(&prepare_lock);
+
+       hlist_for_each_entry(clk, tmp, &clk_root_list, child_node)
+               clk_debug_create_subtree(clk, rootdir);
+
+       hlist_for_each_entry(clk, tmp, &clk_orphan_list, child_node)
+               clk_debug_create_subtree(clk, orphandir);
+
+       inited = 1;
+
+       mutex_unlock(&prepare_lock);
+
+       return 0;
+}
+late_initcall(clk_debug_init);
+#else
+static inline int clk_debug_register(struct clk *clk) { return 0; }
+#endif /* CONFIG_COMMON_CLK_DEBUG */
+
+#ifdef CONFIG_COMMON_CLK_DISABLE_UNUSED
+/* caller must hold prepare_lock */
+static void clk_disable_unused_subtree(struct clk *clk)
+{
+       struct clk *child;
+       struct hlist_node *tmp;
+       unsigned long flags;
+
+       if (!clk)
+               goto out;
+
+       hlist_for_each_entry(child, tmp, &clk->children, child_node)
+               clk_disable_unused_subtree(child);
+
+       spin_lock_irqsave(&enable_lock, flags);
+
+       if (clk->enable_count)
+               goto unlock_out;
+
+       if (clk->flags & CLK_IGNORE_UNUSED)
+               goto unlock_out;
+
+       if (__clk_is_enabled(clk) && clk->ops->disable)
+               clk->ops->disable(clk->hw);
+
+unlock_out:
+       spin_unlock_irqrestore(&enable_lock, flags);
+
+out:
+       return;
+}
+
+static int clk_disable_unused(void)
+{
+       struct clk *clk;
+       struct hlist_node *tmp;
+
+       mutex_lock(&prepare_lock);
+
+       hlist_for_each_entry(clk, tmp, &clk_root_list, child_node)
+               clk_disable_unused_subtree(clk);
+
+       hlist_for_each_entry(clk, tmp, &clk_orphan_list, child_node)
+               clk_disable_unused_subtree(clk);
+
+       mutex_unlock(&prepare_lock);
+
+       return 0;
+}
+late_initcall(clk_disable_unused);
+#else
+static inline int clk_disable_unused(struct clk *clk) { return 0; }
+#endif /* CONFIG_COMMON_CLK_DISABLE_UNUSED */
+
+/***    helper functions   ***/
+
+inline const char *__clk_get_name(struct clk *clk)
+{
+       return !clk ? NULL : clk->name;
+}
+
+inline struct clk_hw *__clk_get_hw(struct clk *clk)
+{
+       return !clk ? NULL : clk->hw;
+}
+
+inline u8 __clk_get_num_parents(struct clk *clk)
+{
+       return !clk ? -EINVAL : clk->num_parents;
+}
+
+inline struct clk *__clk_get_parent(struct clk *clk)
+{
+       return !clk ? NULL : clk->parent;
+}
+
+inline int __clk_get_enable_count(struct clk *clk)
+{
+       return !clk ? -EINVAL : clk->enable_count;
+}
+
+inline int __clk_get_prepare_count(struct clk *clk)
+{
+       return !clk ? -EINVAL : clk->prepare_count;
+}
+
+unsigned long __clk_get_rate(struct clk *clk)
+{
+       unsigned long ret;
+
+       if (!clk) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       ret = clk->rate;
+
+       if (clk->flags & CLK_IS_ROOT)
+               goto out;
+
+       if (!clk->parent)
+               ret = -ENODEV;
+
+out:
+       return ret;
+}
+
+inline unsigned long __clk_get_flags(struct clk *clk)
+{
+       return !clk ? -EINVAL : clk->flags;
+}
+
+int __clk_is_enabled(struct clk *clk)
+{
+       int ret;
+
+       if (!clk)
+               return -EINVAL;
+
+       /*
+        * .is_enabled is only mandatory for clocks that gate
+        * fall back to software usage counter if .is_enabled is missing
+        */
+       if (!clk->ops->is_enabled) {
+               ret = clk->enable_count ? 1 : 0;
+               goto out;
+       }
+
+       ret = clk->ops->is_enabled(clk->hw);
+out:
+       return ret;
+}
+
+static struct clk *__clk_lookup_subtree(const char *name, struct clk *clk)
+{
+       struct clk *child;
+       struct clk *ret;
+       struct hlist_node *tmp;
+
+       if (!strcmp(clk->name, name))
+               return clk;
+
+       hlist_for_each_entry(child, tmp, &clk->children, child_node) {
+               ret = __clk_lookup_subtree(name, child);
+               if (ret)
+                       return ret;
+       }
+
+       return NULL;
+}
+
+struct clk *__clk_lookup(const char *name)
+{
+       struct clk *root_clk;
+       struct clk *ret;
+       struct hlist_node *tmp;
+
+       if (!name)
+               return NULL;
+
+       /* search the 'proper' clk tree first */
+       hlist_for_each_entry(root_clk, tmp, &clk_root_list, child_node) {
+               ret = __clk_lookup_subtree(name, root_clk);
+               if (ret)
+                       return ret;
+       }
+
+       /* if not found, then search the orphan tree */
+       hlist_for_each_entry(root_clk, tmp, &clk_orphan_list, child_node) {
+               ret = __clk_lookup_subtree(name, root_clk);
+               if (ret)
+                       return ret;
+       }
+
+       return NULL;
+}
+
+/***        clk api        ***/
+
+void __clk_unprepare(struct clk *clk)
+{
+       if (!clk)
+               return;
+
+       if (WARN_ON(clk->prepare_count == 0))
+               return;
+
+       if (--clk->prepare_count > 0)
+               return;
+
+       WARN_ON(clk->enable_count > 0);
+
+       if (clk->ops->unprepare)
+               clk->ops->unprepare(clk->hw);
+
+       __clk_unprepare(clk->parent);
+}
+
+/**
+ * clk_unprepare - undo preparation of a clock source
+ * @clk: the clk being unprepare
+ *
+ * clk_unprepare may sleep, which differentiates it from clk_disable.  In a
+ * simple case, clk_unprepare can be used instead of clk_disable to gate a clk
+ * if the operation may sleep.  One example is a clk which is accessed over
+ * I2c.  In the complex case a clk gate operation may require a fast and a slow
+ * part.  It is this reason that clk_unprepare and clk_disable are not mutually
+ * exclusive.  In fact clk_disable must be called before clk_unprepare.
+ */
+void clk_unprepare(struct clk *clk)
+{
+       mutex_lock(&prepare_lock);
+       __clk_unprepare(clk);
+       mutex_unlock(&prepare_lock);
+}
+EXPORT_SYMBOL_GPL(clk_unprepare);
+
+int __clk_prepare(struct clk *clk)
+{
+       int ret = 0;
+
+       if (!clk)
+               return 0;
+
+       if (clk->prepare_count == 0) {
+               ret = __clk_prepare(clk->parent);
+               if (ret)
+                       return ret;
+
+               if (clk->ops->prepare) {
+                       ret = clk->ops->prepare(clk->hw);
+                       if (ret) {
+                               __clk_unprepare(clk->parent);
+                               return ret;
+                       }
+               }
+       }
+
+       clk->prepare_count++;
+
+       return 0;
+}
+
+/**
+ * clk_prepare - prepare a clock source
+ * @clk: the clk being prepared
+ *
+ * clk_prepare may sleep, which differentiates it from clk_enable.  In a simple
+ * case, clk_prepare can be used instead of clk_enable to ungate a clk if the
+ * operation may sleep.  One example is a clk which is accessed over I2c.  In
+ * the complex case a clk ungate operation may require a fast and a slow part.
+ * It is this reason that clk_prepare and clk_enable are not mutually
+ * exclusive.  In fact clk_prepare must be called before clk_enable.
+ * Returns 0 on success, -EERROR otherwise.
+ */
+int clk_prepare(struct clk *clk)
+{
+       int ret;
+
+       mutex_lock(&prepare_lock);
+       ret = __clk_prepare(clk);
+       mutex_unlock(&prepare_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(clk_prepare);
+
+static void __clk_disable(struct clk *clk)
+{
+       if (!clk)
+               return;
+
+       if (WARN_ON(clk->enable_count == 0))
+               return;
+
+       if (--clk->enable_count > 0)
+               return;
+
+       if (clk->ops->disable)
+               clk->ops->disable(clk->hw);
+
+       __clk_disable(clk->parent);
+}
+
+/**
+ * clk_disable - gate a clock
+ * @clk: the clk being gated
+ *
+ * clk_disable must not sleep, which differentiates it from clk_unprepare.  In
+ * a simple case, clk_disable can be used instead of clk_unprepare to gate a
+ * clk if the operation is fast and will never sleep.  One example is a
+ * SoC-internal clk which is controlled via simple register writes.  In the
+ * complex case a clk gate operation may require a fast and a slow part.  It is
+ * this reason that clk_unprepare and clk_disable are not mutually exclusive.
+ * In fact clk_disable must be called before clk_unprepare.
+ */
+void clk_disable(struct clk *clk)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&enable_lock, flags);
+       __clk_disable(clk);
+       spin_unlock_irqrestore(&enable_lock, flags);
+}
+EXPORT_SYMBOL_GPL(clk_disable);
+
+static int __clk_enable(struct clk *clk)
+{
+       int ret = 0;
+
+       if (!clk)
+               return 0;
+
+       if (WARN_ON(clk->prepare_count == 0))
+               return -ESHUTDOWN;
+
+       if (clk->enable_count == 0) {
+               ret = __clk_enable(clk->parent);
+
+               if (ret)
+                       return ret;
+
+               if (clk->ops->enable) {
+                       ret = clk->ops->enable(clk->hw);
+                       if (ret) {
+                               __clk_disable(clk->parent);
+                               return ret;
+                       }
+               }
+       }
+
+       clk->enable_count++;
+       return 0;
+}
+
+/**
+ * clk_enable - ungate a clock
+ * @clk: the clk being ungated
+ *
+ * clk_enable must not sleep, which differentiates it from clk_prepare.  In a
+ * simple case, clk_enable can be used instead of clk_prepare to ungate a clk
+ * if the operation will never sleep.  One example is a SoC-internal clk which
+ * is controlled via simple register writes.  In the complex case a clk ungate
+ * operation may require a fast and a slow part.  It is this reason that
+ * clk_enable and clk_prepare are not mutually exclusive.  In fact clk_prepare
+ * must be called before clk_enable.  Returns 0 on success, -EERROR
+ * otherwise.
+ */
+int clk_enable(struct clk *clk)
+{
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&enable_lock, flags);
+       ret = __clk_enable(clk);
+       spin_unlock_irqrestore(&enable_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(clk_enable);
+
+/**
+ * clk_get_rate - return the rate of clk
+ * @clk: the clk whose rate is being returned
+ *
+ * Simply returns the cached rate of the clk.  Does not query the hardware.  If
+ * clk is NULL then returns -EINVAL.
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+       unsigned long rate;
+
+       mutex_lock(&prepare_lock);
+       rate = __clk_get_rate(clk);
+       mutex_unlock(&prepare_lock);
+
+       return rate;
+}
+EXPORT_SYMBOL_GPL(clk_get_rate);
+
+/**
+ * __clk_round_rate - round the given rate for a clk
+ * @clk: round the rate of this clock
+ *
+ * Caller must hold prepare_lock.  Useful for clk_ops such as .set_rate
+ */
+unsigned long __clk_round_rate(struct clk *clk, unsigned long rate)
+{
+       unsigned long unused;
+
+       if (!clk)
+               return -EINVAL;
+
+       if (!clk->ops->round_rate)
+               return clk->rate;
+
+       if (clk->flags & CLK_SET_RATE_PARENT)
+               return clk->ops->round_rate(clk->hw, rate, &unused);
+       else
+               return clk->ops->round_rate(clk->hw, rate, NULL);
+}
+
+/**
+ * clk_round_rate - round the given rate for a clk
+ * @clk: the clk for which we are rounding a rate
+ * @rate: the rate which is to be rounded
+ *
+ * Takes in a rate as input and rounds it to a rate that the clk can actually
+ * use which is then returned.  If clk doesn't support round_rate operation
+ * then the parent rate is returned.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+       unsigned long ret;
+
+       mutex_lock(&prepare_lock);
+       ret = __clk_round_rate(clk, rate);
+       mutex_unlock(&prepare_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
+/**
+ * __clk_notify - call clk notifier chain
+ * @clk: struct clk * that is changing rate
+ * @msg: clk notifier type (see include/linux/clk.h)
+ * @old_rate: old clk rate
+ * @new_rate: new clk rate
+ *
+ * Triggers a notifier call chain on the clk rate-change notification
+ * for 'clk'.  Passes a pointer to the struct clk and the previous
+ * and current rates to the notifier callback.  Intended to be called by
+ * internal clock code only.  Returns NOTIFY_DONE from the last driver
+ * called if all went well, or NOTIFY_STOP or NOTIFY_BAD immediately if
+ * a driver returns that.
+ */
+static int __clk_notify(struct clk *clk, unsigned long msg,
+               unsigned long old_rate, unsigned long new_rate)
+{
+       struct clk_notifier *cn;
+       struct clk_notifier_data cnd;
+       int ret = NOTIFY_DONE;
+
+       cnd.clk = clk;
+       cnd.old_rate = old_rate;
+       cnd.new_rate = new_rate;
+
+       list_for_each_entry(cn, &clk_notifier_list, node) {
+               if (cn->clk == clk) {
+                       ret = srcu_notifier_call_chain(&cn->notifier_head, msg,
+                                       &cnd);
+                       break;
+               }
+       }
+
+       return ret;
+}
+
+/**
+ * __clk_recalc_rates
+ * @clk: first clk in the subtree
+ * @msg: notification type (see include/linux/clk.h)
+ *
+ * Walks the subtree of clks starting with clk and recalculates rates as it
+ * goes.  Note that if a clk does not implement the .recalc_rate callback then
+ * it is assumed that the clock will take on the rate of it's parent.
+ *
+ * clk_recalc_rates also propagates the POST_RATE_CHANGE notification,
+ * if necessary.
+ *
+ * Caller must hold prepare_lock.
+ */
+static void __clk_recalc_rates(struct clk *clk, unsigned long msg)
+{
+       unsigned long old_rate;
+       unsigned long parent_rate = 0;
+       struct hlist_node *tmp;
+       struct clk *child;
+
+       old_rate = clk->rate;
+
+       if (clk->parent)
+               parent_rate = clk->parent->rate;
+
+       if (clk->ops->recalc_rate)
+               clk->rate = clk->ops->recalc_rate(clk->hw, parent_rate);
+       else
+               clk->rate = parent_rate;
+
+       /*
+        * ignore NOTIFY_STOP and NOTIFY_BAD return values for POST_RATE_CHANGE
+        * & ABORT_RATE_CHANGE notifiers
+        */
+       if (clk->notifier_count && msg)
+               __clk_notify(clk, msg, old_rate, clk->rate);
+
+       hlist_for_each_entry(child, tmp, &clk->children, child_node)
+               __clk_recalc_rates(child, msg);
+}
+
+/**
+ * __clk_speculate_rates
+ * @clk: first clk in the subtree
+ * @parent_rate: the "future" rate of clk's parent
+ *
+ * Walks the subtree of clks starting with clk, speculating rates as it
+ * goes and firing off PRE_RATE_CHANGE notifications as necessary.
+ *
+ * Unlike clk_recalc_rates, clk_speculate_rates exists only for sending
+ * pre-rate change notifications and returns early if no clks in the
+ * subtree have subscribed to the notifications.  Note that if a clk does not
+ * implement the .recalc_rate callback then it is assumed that the clock will
+ * take on the rate of it's parent.
+ *
+ * Caller must hold prepare_lock.
+ */
+static int __clk_speculate_rates(struct clk *clk, unsigned long parent_rate)
+{
+       struct hlist_node *tmp;
+       struct clk *child;
+       unsigned long new_rate;
+       int ret = NOTIFY_DONE;
+
+       if (clk->ops->recalc_rate)
+               new_rate = clk->ops->recalc_rate(clk->hw, parent_rate);
+       else
+               new_rate = parent_rate;
+
+       /* abort the rate change if a driver returns NOTIFY_BAD */
+       if (clk->notifier_count)
+               ret = __clk_notify(clk, PRE_RATE_CHANGE, clk->rate, new_rate);
+
+       if (ret == NOTIFY_BAD)
+               goto out;
+
+       hlist_for_each_entry(child, tmp, &clk->children, child_node) {
+               ret = __clk_speculate_rates(child, new_rate);
+               if (ret == NOTIFY_BAD)
+                       break;
+       }
+
+out:
+       return ret;
+}
+
+static void clk_calc_subtree(struct clk *clk, unsigned long new_rate)
+{
+       struct clk *child;
+       struct hlist_node *tmp;
+
+       clk->new_rate = new_rate;
+
+       hlist_for_each_entry(child, tmp, &clk->children, child_node) {
+               if (child->ops->recalc_rate)
+                       child->new_rate = child->ops->recalc_rate(child->hw, new_rate);
+               else
+                       child->new_rate = new_rate;
+               clk_calc_subtree(child, child->new_rate);
+       }
+}
+
+/*
+ * calculate the new rates returning the topmost clock that has to be
+ * changed.
+ */
+static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate)
+{
+       struct clk *top = clk;
+       unsigned long best_parent_rate = clk->parent->rate;
+       unsigned long new_rate;
+
+       if (!clk->ops->round_rate && !(clk->flags & CLK_SET_RATE_PARENT)) {
+               clk->new_rate = clk->rate;
+               return NULL;
+       }
+
+       if (!clk->ops->round_rate && (clk->flags & CLK_SET_RATE_PARENT)) {
+               top = clk_calc_new_rates(clk->parent, rate);
+               new_rate = clk->new_rate = clk->parent->new_rate;
+
+               goto out;
+       }
+
+       if (clk->flags & CLK_SET_RATE_PARENT)
+               new_rate = clk->ops->round_rate(clk->hw, rate, &best_parent_rate);
+       else
+               new_rate = clk->ops->round_rate(clk->hw, rate, NULL);
+
+       if (best_parent_rate != clk->parent->rate) {
+               top = clk_calc_new_rates(clk->parent, best_parent_rate);
+
+               goto out;
+       }
+
+out:
+       clk_calc_subtree(clk, new_rate);
+
+       return top;
+}
+
+/*
+ * Notify about rate changes in a subtree. Always walk down the whole tree
+ * so that in case of an error we can walk down the whole tree again and
+ * abort the change.
+ */
+static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long event)
+{
+       struct hlist_node *tmp;
+       struct clk *child, *fail_clk = NULL;
+       int ret = NOTIFY_DONE;
+
+       if (clk->rate == clk->new_rate)
+               return 0;
+
+       if (clk->notifier_count) {
+               ret = __clk_notify(clk, event, clk->rate, clk->new_rate);
+               if (ret == NOTIFY_BAD)
+                       fail_clk = clk;
+       }
+
+       hlist_for_each_entry(child, tmp, &clk->children, child_node) {
+               clk = clk_propagate_rate_change(child, event);
+               if (clk)
+                       fail_clk = clk;
+       }
+
+       return fail_clk;
+}
+
+/*
+ * walk down a subtree and set the new rates notifying the rate
+ * change on the way
+ */
+static void clk_change_rate(struct clk *clk)
+{
+       struct clk *child;
+       unsigned long old_rate;
+       struct hlist_node *tmp;
+
+       old_rate = clk->rate;
+
+       if (clk->ops->set_rate)
+               clk->ops->set_rate(clk->hw, clk->new_rate);
+
+       if (clk->ops->recalc_rate)
+               clk->rate = clk->ops->recalc_rate(clk->hw,
+                               clk->parent->rate);
+       else
+               clk->rate = clk->parent->rate;
+
+       if (clk->notifier_count && old_rate != clk->rate)
+               __clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate);
+
+       hlist_for_each_entry(child, tmp, &clk->children, child_node)
+               clk_change_rate(child);
+}
+
+/**
+ * clk_set_rate - specify a new rate for clk
+ * @clk: the clk whose rate is being changed
+ * @rate: the new rate for clk
+ *
+ * In the simplest case clk_set_rate will only change the rate of clk.
+ *
+ * If clk has the CLK_SET_RATE_GATE flag set and it is enabled this call
+ * will fail; only when the clk is disabled will it be able to change
+ * its rate.
+ *
+ * Setting the CLK_SET_RATE_PARENT flag allows clk_set_rate to
+ * recursively propagate up to clk's parent; whether or not this happens
+ * depends on the outcome of clk's .round_rate implementation.  If
+ * *parent_rate is 0 after calling .round_rate then upstream parent
+ * propagation is ignored.  If *parent_rate comes back with a new rate
+ * for clk's parent then we propagate up to clk's parent and set it's
+ * rate.  Upward propagation will continue until either a clk does not
+ * support the CLK_SET_RATE_PARENT flag or .round_rate stops requesting
+ * changes to clk's parent_rate.  If there is a failure during upstream
+ * propagation then clk_set_rate will unwind and restore each clk's rate
+ * that had been successfully changed.  Afterwards a rate change abort
+ * notification will be propagated downstream, starting from the clk
+ * that failed.
+ *
+ * At the end of all of the rate setting, clk_set_rate internally calls
+ * __clk_recalc_rates and propagates the rate changes downstream,
+ * starting from the highest clk whose rate was changed.  This has the
+ * added benefit of propagating post-rate change notifiers.
+ *
+ * Note that while post-rate change and rate change abort notifications
+ * are guaranteed to be sent to a clk only once per call to
+ * clk_set_rate, pre-change notifications will be sent for every clk
+ * whose rate is changed.  Stacking pre-change notifications is noisy
+ * for the drivers subscribed to them, but this allows drivers to react
+ * to intermediate clk rate changes up until the point where the final
+ * rate is achieved at the end of upstream propagation.
+ *
+ * Returns 0 on success, -EERROR otherwise.
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       struct clk *top, *fail_clk;
+       int ret = 0;
+
+       /* prevent racing with updates to the clock topology */
+       mutex_lock(&prepare_lock);
+
+       /* bail early if nothing to do */
+       if (rate == clk->rate)
+               goto out;
+
+       /* calculate new rates and get the topmost changed clock */
+       top = clk_calc_new_rates(clk, rate);
+       if (!top) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       /* notify that we are about to change rates */
+       fail_clk = clk_propagate_rate_change(top, PRE_RATE_CHANGE);
+       if (fail_clk) {
+               pr_warn("%s: failed to set %s rate\n", __func__,
+                               fail_clk->name);
+               clk_propagate_rate_change(top, ABORT_RATE_CHANGE);
+               ret = -EBUSY;
+               goto out;
+       }
+
+       /* change the rates */
+       clk_change_rate(top);
+
+       mutex_unlock(&prepare_lock);
+
+       return 0;
+out:
+       mutex_unlock(&prepare_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+/**
+ * clk_get_parent - return the parent of a clk
+ * @clk: the clk whose parent gets returned
+ *
+ * Simply returns clk->parent.  Returns NULL if clk is NULL.
+ */
+struct clk *clk_get_parent(struct clk *clk)
+{
+       struct clk *parent;
+
+       mutex_lock(&prepare_lock);
+       parent = __clk_get_parent(clk);
+       mutex_unlock(&prepare_lock);
+
+       return parent;
+}
+EXPORT_SYMBOL_GPL(clk_get_parent);
+
+/*
+ * .get_parent is mandatory for clocks with multiple possible parents.  It is
+ * optional for single-parent clocks.  Always call .get_parent if it is
+ * available and WARN if it is missing for multi-parent clocks.
+ *
+ * For single-parent clocks without .get_parent, first check to see if the
+ * .parents array exists, and if so use it to avoid an expensive tree
+ * traversal.  If .parents does not exist then walk the tree with __clk_lookup.
+ */
+static struct clk *__clk_init_parent(struct clk *clk)
+{
+       struct clk *ret = NULL;
+       u8 index;
+
+       /* handle the trivial cases */
+
+       if (!clk->num_parents)
+               goto out;
+
+       if (clk->num_parents == 1) {
+               if (IS_ERR_OR_NULL(clk->parent))
+                       ret = clk->parent = __clk_lookup(clk->parent_names[0]);
+               ret = clk->parent;
+               goto out;
+       }
+
+       if (!clk->ops->get_parent) {
+               WARN(!clk->ops->get_parent,
+                       "%s: multi-parent clocks must implement .get_parent\n",
+                       __func__);
+               goto out;
+       };
+
+       /*
+        * Do our best to cache parent clocks in clk->parents.  This prevents
+        * unnecessary and expensive calls to __clk_lookup.  We don't set
+        * clk->parent here; that is done by the calling function
+        */
+
+       index = clk->ops->get_parent(clk->hw);
+
+       if (!clk->parents)
+               clk->parents =
+                       kmalloc((sizeof(struct clk*) * clk->num_parents),
+                                       GFP_KERNEL);
+
+       if (!clk->parents)
+               ret = __clk_lookup(clk->parent_names[index]);
+       else if (!clk->parents[index])
+               ret = clk->parents[index] =
+                       __clk_lookup(clk->parent_names[index]);
+       else
+               ret = clk->parents[index];
+
+out:
+       return ret;
+}
+
+void __clk_reparent(struct clk *clk, struct clk *new_parent)
+{
+#ifdef CONFIG_COMMON_CLK_DEBUG
+       struct dentry *d;
+       struct dentry *new_parent_d;
+#endif
+
+       if (!clk || !new_parent)
+               return;
+
+       hlist_del(&clk->child_node);
+
+       if (new_parent)
+               hlist_add_head(&clk->child_node, &new_parent->children);
+       else
+               hlist_add_head(&clk->child_node, &clk_orphan_list);
+
+#ifdef CONFIG_COMMON_CLK_DEBUG
+       if (!inited)
+               goto out;
+
+       if (new_parent)
+               new_parent_d = new_parent->dentry;
+       else
+               new_parent_d = orphandir;
+
+       d = debugfs_rename(clk->dentry->d_parent, clk->dentry,
+                       new_parent_d, clk->name);
+       if (d)
+               clk->dentry = d;
+       else
+               pr_debug("%s: failed to rename debugfs entry for %s\n",
+                               __func__, clk->name);
+out:
+#endif
+
+       clk->parent = new_parent;
+
+       __clk_recalc_rates(clk, POST_RATE_CHANGE);
+}
+
+static int __clk_set_parent(struct clk *clk, struct clk *parent)
+{
+       struct clk *old_parent;
+       unsigned long flags;
+       int ret = -EINVAL;
+       u8 i;
+
+       old_parent = clk->parent;
+
+       /* find index of new parent clock using cached parent ptrs */
+       for (i = 0; i < clk->num_parents; i++)
+               if (clk->parents[i] == parent)
+                       break;
+
+       /*
+        * find index of new parent clock using string name comparison
+        * also try to cache the parent to avoid future calls to __clk_lookup
+        */
+       if (i == clk->num_parents)
+               for (i = 0; i < clk->num_parents; i++)
+                       if (!strcmp(clk->parent_names[i], parent->name)) {
+                               clk->parents[i] = __clk_lookup(parent->name);
+                               break;
+                       }
+
+       if (i == clk->num_parents) {
+               pr_debug("%s: clock %s is not a possible parent of clock %s\n",
+                               __func__, parent->name, clk->name);
+               goto out;
+       }
+
+       /* migrate prepare and enable */
+       if (clk->prepare_count)
+               __clk_prepare(parent);
+
+       /* FIXME replace with clk_is_enabled(clk) someday */
+       spin_lock_irqsave(&enable_lock, flags);
+       if (clk->enable_count)
+               __clk_enable(parent);
+       spin_unlock_irqrestore(&enable_lock, flags);
+
+       /* change clock input source */
+       ret = clk->ops->set_parent(clk->hw, i);
+
+       /* clean up old prepare and enable */
+       spin_lock_irqsave(&enable_lock, flags);
+       if (clk->enable_count)
+               __clk_disable(old_parent);
+       spin_unlock_irqrestore(&enable_lock, flags);
+
+       if (clk->prepare_count)
+               __clk_unprepare(old_parent);
+
+out:
+       return ret;
+}
+
+/**
+ * clk_set_parent - switch the parent of a mux clk
+ * @clk: the mux clk whose input we are switching
+ * @parent: the new input to clk
+ *
+ * Re-parent clk to use parent as it's new input source.  If clk has the
+ * CLK_SET_PARENT_GATE flag set then clk must be gated for this
+ * operation to succeed.  After successfully changing clk's parent
+ * clk_set_parent will update the clk topology, sysfs topology and
+ * propagate rate recalculation via __clk_recalc_rates.  Returns 0 on
+ * success, -EERROR otherwise.
+ */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+       int ret = 0;
+
+       if (!clk || !clk->ops)
+               return -EINVAL;
+
+       if (!clk->ops->set_parent)
+               return -ENOSYS;
+
+       /* prevent racing with updates to the clock topology */
+       mutex_lock(&prepare_lock);
+
+       if (clk->parent == parent)
+               goto out;
+
+       /* propagate PRE_RATE_CHANGE notifications */
+       if (clk->notifier_count)
+               ret = __clk_speculate_rates(clk, parent->rate);
+
+       /* abort if a driver objects */
+       if (ret == NOTIFY_STOP)
+               goto out;
+
+       /* only re-parent if the clock is not in use */
+       if ((clk->flags & CLK_SET_PARENT_GATE) && clk->prepare_count)
+               ret = -EBUSY;
+       else
+               ret = __clk_set_parent(clk, parent);
+
+       /* propagate ABORT_RATE_CHANGE if .set_parent failed */
+       if (ret) {
+               __clk_recalc_rates(clk, ABORT_RATE_CHANGE);
+               goto out;
+       }
+
+       /* propagate rate recalculation downstream */
+       __clk_reparent(clk, parent);
+
+out:
+       mutex_unlock(&prepare_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_parent);
+
+/**
+ * __clk_init - initialize the data structures in a struct clk
+ * @dev:       device initializing this clk, placeholder for now
+ * @clk:       clk being initialized
+ *
+ * Initializes the lists in struct clk, queries the hardware for the
+ * parent and rate and sets them both.
+ *
+ * Any struct clk passed into __clk_init must have the following members
+ * populated:
+ *     .name
+ *     .ops
+ *     .hw
+ *     .parent_names
+ *     .num_parents
+ *     .flags
+ *
+ * Essentially, everything that would normally be passed into clk_register is
+ * assumed to be initialized already in __clk_init.  The other members may be
+ * populated, but are optional.
+ *
+ * __clk_init is only exposed via clk-private.h and is intended for use with
+ * very large numbers of clocks that need to be statically initialized.  It is
+ * a layering violation to include clk-private.h from any code which implements
+ * a clock's .ops; as such any statically initialized clock data MUST be in a
+ * separate C file from the logic that implements it's operations.
+ */
+void __clk_init(struct device *dev, struct clk *clk)
+{
+       int i;
+       struct clk *orphan;
+       struct hlist_node *tmp, *tmp2;
+
+       if (!clk)
+               return;
+
+       mutex_lock(&prepare_lock);
+
+       /* check to see if a clock with this name is already registered */
+       if (__clk_lookup(clk->name))
+               goto out;
+
+       /* throw a WARN if any entries in parent_names are NULL */
+       for (i = 0; i < clk->num_parents; i++)
+               WARN(!clk->parent_names[i],
+                               "%s: invalid NULL in %s's .parent_names\n",
+                               __func__, clk->name);
+
+       /*
+        * Allocate an array of struct clk *'s to avoid unnecessary string
+        * look-ups of clk's possible parents.  This can fail for clocks passed
+        * in to clk_init during early boot; thus any access to clk->parents[]
+        * must always check for a NULL pointer and try to populate it if
+        * necessary.
+        *
+        * If clk->parents is not NULL we skip this entire block.  This allows
+        * for clock drivers to statically initialize clk->parents.
+        */
+       if (clk->num_parents && !clk->parents) {
+               clk->parents = kmalloc((sizeof(struct clk*) * clk->num_parents),
+                               GFP_KERNEL);
+               /*
+                * __clk_lookup returns NULL for parents that have not been
+                * clk_init'd; thus any access to clk->parents[] must check
+                * for a NULL pointer.  We can always perform lazy lookups for
+                * missing parents later on.
+                */
+               if (clk->parents)
+                       for (i = 0; i < clk->num_parents; i++)
+                               clk->parents[i] =
+                                       __clk_lookup(clk->parent_names[i]);
+       }
+
+       clk->parent = __clk_init_parent(clk);
+
+       /*
+        * Populate clk->parent if parent has already been __clk_init'd.  If
+        * parent has not yet been __clk_init'd then place clk in the orphan
+        * list.  If clk has set the CLK_IS_ROOT flag then place it in the root
+        * clk list.
+        *
+        * Every time a new clk is clk_init'd then we walk the list of orphan
+        * clocks and re-parent any that are children of the clock currently
+        * being clk_init'd.
+        */
+       if (clk->parent)
+               hlist_add_head(&clk->child_node,
+                               &clk->parent->children);
+       else if (clk->flags & CLK_IS_ROOT)
+               hlist_add_head(&clk->child_node, &clk_root_list);
+       else
+               hlist_add_head(&clk->child_node, &clk_orphan_list);
+
+       /*
+        * Set clk's rate.  The preferred method is to use .recalc_rate.  For
+        * simple clocks and lazy developers the default fallback is to use the
+        * parent's rate.  If a clock doesn't have a parent (or is orphaned)
+        * then rate is set to zero.
+        */
+       if (clk->ops->recalc_rate)
+               clk->rate = clk->ops->recalc_rate(clk->hw,
+                               __clk_get_rate(clk->parent));
+       else if (clk->parent)
+               clk->rate = clk->parent->rate;
+       else
+               clk->rate = 0;
+
+       /*
+        * walk the list of orphan clocks and reparent any that are children of
+        * this clock
+        */
+       hlist_for_each_entry_safe(orphan, tmp, tmp2, &clk_orphan_list, child_node)
+               for (i = 0; i < orphan->num_parents; i++)
+                       if (!strcmp(clk->name, orphan->parent_names[i])) {
+                               __clk_reparent(orphan, clk);
+                               break;
+                       }
+
+       /*
+        * optional platform-specific magic
+        *
+        * The .init callback is not used by any of the basic clock types, but
+        * exists for weird hardware that must perform initialization magic.
+        * Please consider other ways of solving initialization problems before
+        * using this callback, as it's use is discouraged.
+        */
+       if (clk->ops->init)
+               clk->ops->init(clk->hw);
+
+       clk_debug_register(clk);
+
+out:
+       mutex_unlock(&prepare_lock);
+
+       return;
+}
+
+/**
+ * clk_register - allocate a new clock, register it and return an opaque cookie
+ * @dev: device that is registering this clock
+ * @name: clock name
+ * @ops: operations this clock supports
+ * @hw: link to hardware-specific clock data
+ * @parent_names: array of string names for all possible parents
+ * @num_parents: number of possible parents
+ * @flags: framework-level hints and quirks
+ *
+ * clk_register is the primary interface for populating the clock tree with new
+ * clock nodes.  It returns a pointer to the newly allocated struct clk which
+ * cannot be dereferenced by driver code but may be used in conjuction with the
+ * rest of the clock API.
+ */
+struct clk *clk_register(struct device *dev, const char *name,
+               const struct clk_ops *ops, struct clk_hw *hw,
+               char **parent_names, u8 num_parents, unsigned long flags)
+{
+       struct clk *clk;
+
+       clk = kzalloc(sizeof(*clk), GFP_KERNEL);
+       if (!clk)
+               return NULL;
+
+       clk->name = name;
+       clk->ops = ops;
+       clk->hw = hw;
+       clk->flags = flags;
+       clk->parent_names = parent_names;
+       clk->num_parents = num_parents;
+       hw->clk = clk;
+
+       __clk_init(dev, clk);
+
+       return clk;
+}
+EXPORT_SYMBOL_GPL(clk_register);
+
+/***        clk rate change notifiers        ***/
+
+/**
+ * clk_notifier_register - add a clk rate change notifier
+ * @clk: struct clk * to watch
+ * @nb: struct notifier_block * with callback info
+ *
+ * Request notification when clk's rate changes.  This uses an SRCU
+ * notifier because we want it to block and notifier unregistrations are
+ * uncommon.  The callbacks associated with the notifier must not
+ * re-enter into the clk framework by calling any top-level clk APIs;
+ * this will cause a nested prepare_lock mutex.
+ *
+ * Pre-change notifier callbacks will be passed the current, pre-change
+ * rate of the clk via struct clk_notifier_data.old_rate.  The new,
+ * post-change rate of the clk is passed via struct
+ * clk_notifier_data.new_rate.
+ *
+ * Post-change notifiers will pass the now-current, post-change rate of
+ * the clk in both struct clk_notifier_data.old_rate and struct
+ * clk_notifier_data.new_rate.
+ *
+ * Abort-change notifiers are effectively the opposite of pre-change
+ * notifiers: the original pre-change clk rate is passed in via struct
+ * clk_notifier_data.new_rate and the failed post-change rate is passed
+ * in via struct clk_notifier_data.old_rate.
+ *
+ * clk_notifier_register() must be called from non-atomic context.
+ * Returns -EINVAL if called with null arguments, -ENOMEM upon
+ * allocation failure; otherwise, passes along the return value of
+ * srcu_notifier_chain_register().
+ */
+int clk_notifier_register(struct clk *clk, struct notifier_block *nb)
+{
+       struct clk_notifier *cn;
+       int ret = -ENOMEM;
+
+       if (!clk || !nb)
+               return -EINVAL;
+
+       mutex_lock(&prepare_lock);
+
+       /* search the list of notifiers for this clk */
+       list_for_each_entry(cn, &clk_notifier_list, node)
+               if (cn->clk == clk)
+                       break;
+
+       /* if clk wasn't in the notifier list, allocate new clk_notifier */
+       if (cn->clk != clk) {
+               cn = kzalloc(sizeof(struct clk_notifier), GFP_KERNEL);
+               if (!cn)
+                       goto out;
+
+               cn->clk = clk;
+               srcu_init_notifier_head(&cn->notifier_head);
+
+               list_add(&cn->node, &clk_notifier_list);
+       }
+
+       ret = srcu_notifier_chain_register(&cn->notifier_head, nb);
+
+       clk->notifier_count++;
+
+out:
+       mutex_unlock(&prepare_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(clk_notifier_register);
+
+/**
+ * clk_notifier_unregister - remove a clk rate change notifier
+ * @clk: struct clk *
+ * @nb: struct notifier_block * with callback info
+ *
+ * Request no further notification for changes to 'clk' and frees memory
+ * allocated in clk_notifier_register.
+ *
+ * Returns -EINVAL if called with null arguments; otherwise, passes
+ * along the return value of srcu_notifier_chain_unregister().
+ */
+int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
+{
+       struct clk_notifier *cn = NULL;
+       int ret = -EINVAL;
+
+       if (!clk || !nb)
+               return -EINVAL;
+
+       mutex_lock(&prepare_lock);
+
+       list_for_each_entry(cn, &clk_notifier_list, node)
+               if (cn->clk == clk)
+                       break;
+
+       if (cn->clk == clk) {
+               ret = srcu_notifier_chain_unregister(&cn->notifier_head, nb);
+
+               clk->notifier_count--;
+
+               /* XXX the notifier code should handle this better */
+               if (!cn->notifier_head.head) {
+                       srcu_cleanup_notifier_head(&cn->notifier_head);
+                       kfree(cn);
+               }
+
+       } else {
+               ret = -ENOENT;
+       }
+
+       mutex_unlock(&prepare_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(clk_notifier_unregister);
index 55d0f95f82f9350571aca599b8480edefb5adfae..32cb929b8eb62ae387fc20b122c5d5a21da3f10b 100644 (file)
@@ -19,6 +19,8 @@
  *   - Two channels combine to create a free-running 32 bit counter
  *     with a base rate of 5+ MHz, packaged as a clocksource (with
  *     resolution better than 200 nsec).
+ *   - Some chips support 32 bit counter. A single channel is used for
+ *     this 32 bit free-running counter. the second channel is not used.
  *
  *   - The third channel may be used to provide a 16-bit clockevent
  *     source, used in either periodic or oneshot mode.  This runs
@@ -54,6 +56,11 @@ static cycle_t tc_get_cycles(struct clocksource *cs)
        return (upper << 16) | lower;
 }
 
+static cycle_t tc_get_cycles32(struct clocksource *cs)
+{
+       return __raw_readl(tcaddr + ATMEL_TC_REG(0, CV));
+}
+
 static struct clocksource clksrc = {
        .name           = "tcb_clksrc",
        .rating         = 200,
@@ -209,6 +216,48 @@ static void __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx)
 
 #endif
 
+static void __init tcb_setup_dual_chan(struct atmel_tc *tc, int mck_divisor_idx)
+{
+       /* channel 0:  waveform mode, input mclk/8, clock TIOA0 on overflow */
+       __raw_writel(mck_divisor_idx                    /* likely divide-by-8 */
+                       | ATMEL_TC_WAVE
+                       | ATMEL_TC_WAVESEL_UP           /* free-run */
+                       | ATMEL_TC_ACPA_SET             /* TIOA0 rises at 0 */
+                       | ATMEL_TC_ACPC_CLEAR,          /* (duty cycle 50%) */
+                       tcaddr + ATMEL_TC_REG(0, CMR));
+       __raw_writel(0x0000, tcaddr + ATMEL_TC_REG(0, RA));
+       __raw_writel(0x8000, tcaddr + ATMEL_TC_REG(0, RC));
+       __raw_writel(0xff, tcaddr + ATMEL_TC_REG(0, IDR));      /* no irqs */
+       __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(0, CCR));
+
+       /* channel 1:  waveform mode, input TIOA0 */
+       __raw_writel(ATMEL_TC_XC1                       /* input: TIOA0 */
+                       | ATMEL_TC_WAVE
+                       | ATMEL_TC_WAVESEL_UP,          /* free-run */
+                       tcaddr + ATMEL_TC_REG(1, CMR));
+       __raw_writel(0xff, tcaddr + ATMEL_TC_REG(1, IDR));      /* no irqs */
+       __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(1, CCR));
+
+       /* chain channel 0 to channel 1*/
+       __raw_writel(ATMEL_TC_TC1XC1S_TIOA0, tcaddr + ATMEL_TC_BMR);
+       /* then reset all the timers */
+       __raw_writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR);
+}
+
+static void __init tcb_setup_single_chan(struct atmel_tc *tc, int mck_divisor_idx)
+{
+       /* channel 0:  waveform mode, input mclk/8 */
+       __raw_writel(mck_divisor_idx                    /* likely divide-by-8 */
+                       | ATMEL_TC_WAVE
+                       | ATMEL_TC_WAVESEL_UP,          /* free-run */
+                       tcaddr + ATMEL_TC_REG(0, CMR));
+       __raw_writel(0xff, tcaddr + ATMEL_TC_REG(0, IDR));      /* no irqs */
+       __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(0, CCR));
+
+       /* then reset all the timers */
+       __raw_writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR);
+}
+
 static int __init tcb_clksrc_init(void)
 {
        static char bootinfo[] __initdata
@@ -260,34 +309,19 @@ static int __init tcb_clksrc_init(void)
                        divided_rate / 1000000,
                        ((divided_rate + 500000) % 1000000) / 1000);
 
-       /* tclib will give us three clocks no matter what the
-        * underlying platform supports.
-        */
-       clk_enable(tc->clk[1]);
-
-       /* channel 0:  waveform mode, input mclk/8, clock TIOA0 on overflow */
-       __raw_writel(best_divisor_idx                   /* likely divide-by-8 */
-                       | ATMEL_TC_WAVE
-                       | ATMEL_TC_WAVESEL_UP           /* free-run */
-                       | ATMEL_TC_ACPA_SET             /* TIOA0 rises at 0 */
-                       | ATMEL_TC_ACPC_CLEAR,          /* (duty cycle 50%) */
-                       tcaddr + ATMEL_TC_REG(0, CMR));
-       __raw_writel(0x0000, tcaddr + ATMEL_TC_REG(0, RA));
-       __raw_writel(0x8000, tcaddr + ATMEL_TC_REG(0, RC));
-       __raw_writel(0xff, tcaddr + ATMEL_TC_REG(0, IDR));      /* no irqs */
-       __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(0, CCR));
-
-       /* channel 1:  waveform mode, input TIOA0 */
-       __raw_writel(ATMEL_TC_XC1                       /* input: TIOA0 */
-                       | ATMEL_TC_WAVE
-                       | ATMEL_TC_WAVESEL_UP,          /* free-run */
-                       tcaddr + ATMEL_TC_REG(1, CMR));
-       __raw_writel(0xff, tcaddr + ATMEL_TC_REG(1, IDR));      /* no irqs */
-       __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(1, CCR));
-
-       /* chain channel 0 to channel 1, then reset all the timers */
-       __raw_writel(ATMEL_TC_TC1XC1S_TIOA0, tcaddr + ATMEL_TC_BMR);
-       __raw_writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR);
+       if (tc->tcb_config && tc->tcb_config->counter_width == 32) {
+               /* use apropriate function to read 32 bit counter */
+               clksrc.read = tc_get_cycles32;
+               /* setup ony channel 0 */
+               tcb_setup_single_chan(tc, best_divisor_idx);
+       } else {
+               /* tclib will give us three clocks no matter what the
+                * underlying platform supports.
+                */
+               clk_enable(tc->clk[1]);
+               /* setup both channel 0 & 1 */
+               tcb_setup_dual_chan(tc, best_divisor_idx);
+       }
 
        /* and away we go! */
        clocksource_register_hz(&clksrc, divided_rate);
index 1a361e99965ad26e6f9f93de0d94eed20bf77bad..88ddc77a9bb175a393888821b46c30c0a0f27f80 100644 (file)
@@ -311,51 +311,51 @@ static int exynos4210_set_busclk(struct busfreq_data *data, struct opp *opp)
        /* Change Divider - DMC0 */
        tmp = data->dmc_divtable[index];
 
-       __raw_writel(tmp, S5P_CLKDIV_DMC0);
+       __raw_writel(tmp, EXYNOS4_CLKDIV_DMC0);
 
        do {
-               tmp = __raw_readl(S5P_CLKDIV_STAT_DMC0);
+               tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC0);
        } while (tmp & 0x11111111);
 
        /* Change Divider - TOP */
        tmp = data->top_divtable[index];
 
-       __raw_writel(tmp, S5P_CLKDIV_TOP);
+       __raw_writel(tmp, EXYNOS4_CLKDIV_TOP);
 
        do {
-               tmp = __raw_readl(S5P_CLKDIV_STAT_TOP);
+               tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_TOP);
        } while (tmp & 0x11111);
 
        /* Change Divider - LEFTBUS */
-       tmp = __raw_readl(S5P_CLKDIV_LEFTBUS);
+       tmp = __raw_readl(EXYNOS4_CLKDIV_LEFTBUS);
 
-       tmp &= ~(S5P_CLKDIV_BUS_GDLR_MASK | S5P_CLKDIV_BUS_GPLR_MASK);
+       tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
 
        tmp |= ((exynos4210_clkdiv_lr_bus[index][0] <<
-                               S5P_CLKDIV_BUS_GDLR_SHIFT) |
+                               EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
                (exynos4210_clkdiv_lr_bus[index][1] <<
-                               S5P_CLKDIV_BUS_GPLR_SHIFT));
+                               EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
 
-       __raw_writel(tmp, S5P_CLKDIV_LEFTBUS);
+       __raw_writel(tmp, EXYNOS4_CLKDIV_LEFTBUS);
 
        do {
-               tmp = __raw_readl(S5P_CLKDIV_STAT_LEFTBUS);
+               tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_LEFTBUS);
        } while (tmp & 0x11);
 
        /* Change Divider - RIGHTBUS */
-       tmp = __raw_readl(S5P_CLKDIV_RIGHTBUS);
+       tmp = __raw_readl(EXYNOS4_CLKDIV_RIGHTBUS);
 
-       tmp &= ~(S5P_CLKDIV_BUS_GDLR_MASK | S5P_CLKDIV_BUS_GPLR_MASK);
+       tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
 
        tmp |= ((exynos4210_clkdiv_lr_bus[index][0] <<
-                               S5P_CLKDIV_BUS_GDLR_SHIFT) |
+                               EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
                (exynos4210_clkdiv_lr_bus[index][1] <<
-                               S5P_CLKDIV_BUS_GPLR_SHIFT));
+                               EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
 
-       __raw_writel(tmp, S5P_CLKDIV_RIGHTBUS);
+       __raw_writel(tmp, EXYNOS4_CLKDIV_RIGHTBUS);
 
        do {
-               tmp = __raw_readl(S5P_CLKDIV_STAT_RIGHTBUS);
+               tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_RIGHTBUS);
        } while (tmp & 0x11);
 
        return 0;
@@ -376,137 +376,137 @@ static int exynos4x12_set_busclk(struct busfreq_data *data, struct opp *opp)
        /* Change Divider - DMC0 */
        tmp = data->dmc_divtable[index];
 
-       __raw_writel(tmp, S5P_CLKDIV_DMC0);
+       __raw_writel(tmp, EXYNOS4_CLKDIV_DMC0);
 
        do {
-               tmp = __raw_readl(S5P_CLKDIV_STAT_DMC0);
+               tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC0);
        } while (tmp & 0x11111111);
 
        /* Change Divider - DMC1 */
-       tmp = __raw_readl(S5P_CLKDIV_DMC1);
+       tmp = __raw_readl(EXYNOS4_CLKDIV_DMC1);
 
-       tmp &= ~(S5P_CLKDIV_DMC1_G2D_ACP_MASK |
-               S5P_CLKDIV_DMC1_C2C_MASK |
-               S5P_CLKDIV_DMC1_C2CACLK_MASK);
+       tmp &= ~(EXYNOS4_CLKDIV_DMC1_G2D_ACP_MASK |
+               EXYNOS4_CLKDIV_DMC1_C2C_MASK |
+               EXYNOS4_CLKDIV_DMC1_C2CACLK_MASK);
 
        tmp |= ((exynos4x12_clkdiv_dmc1[index][0] <<
-                               S5P_CLKDIV_DMC1_G2D_ACP_SHIFT) |
+                               EXYNOS4_CLKDIV_DMC1_G2D_ACP_SHIFT) |
                (exynos4x12_clkdiv_dmc1[index][1] <<
-                               S5P_CLKDIV_DMC1_C2C_SHIFT) |
+                               EXYNOS4_CLKDIV_DMC1_C2C_SHIFT) |
                (exynos4x12_clkdiv_dmc1[index][2] <<
-                               S5P_CLKDIV_DMC1_C2CACLK_SHIFT));
+                               EXYNOS4_CLKDIV_DMC1_C2CACLK_SHIFT));
 
-       __raw_writel(tmp, S5P_CLKDIV_DMC1);
+       __raw_writel(tmp, EXYNOS4_CLKDIV_DMC1);
 
        do {
-               tmp = __raw_readl(S5P_CLKDIV_STAT_DMC1);
+               tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC1);
        } while (tmp & 0x111111);
 
        /* Change Divider - TOP */
-       tmp = __raw_readl(S5P_CLKDIV_TOP);
+       tmp = __raw_readl(EXYNOS4_CLKDIV_TOP);
 
-       tmp &= ~(S5P_CLKDIV_TOP_ACLK266_GPS_MASK |
-               S5P_CLKDIV_TOP_ACLK100_MASK |
-               S5P_CLKDIV_TOP_ACLK160_MASK |
-               S5P_CLKDIV_TOP_ACLK133_MASK |
-               S5P_CLKDIV_TOP_ONENAND_MASK);
+       tmp &= ~(EXYNOS4_CLKDIV_TOP_ACLK266_GPS_MASK |
+               EXYNOS4_CLKDIV_TOP_ACLK100_MASK |
+               EXYNOS4_CLKDIV_TOP_ACLK160_MASK |
+               EXYNOS4_CLKDIV_TOP_ACLK133_MASK |
+               EXYNOS4_CLKDIV_TOP_ONENAND_MASK);
 
        tmp |= ((exynos4x12_clkdiv_top[index][0] <<
-                               S5P_CLKDIV_TOP_ACLK266_GPS_SHIFT) |
+                               EXYNOS4_CLKDIV_TOP_ACLK266_GPS_SHIFT) |
                (exynos4x12_clkdiv_top[index][1] <<
-                               S5P_CLKDIV_TOP_ACLK100_SHIFT) |
+                               EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT) |
                (exynos4x12_clkdiv_top[index][2] <<
-                               S5P_CLKDIV_TOP_ACLK160_SHIFT) |
+                               EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT) |
                (exynos4x12_clkdiv_top[index][3] <<
-                               S5P_CLKDIV_TOP_ACLK133_SHIFT) |
+                               EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT) |
                (exynos4x12_clkdiv_top[index][4] <<
-                               S5P_CLKDIV_TOP_ONENAND_SHIFT));
+                               EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT));
 
-       __raw_writel(tmp, S5P_CLKDIV_TOP);
+       __raw_writel(tmp, EXYNOS4_CLKDIV_TOP);
 
        do {
-               tmp = __raw_readl(S5P_CLKDIV_STAT_TOP);
+               tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_TOP);
        } while (tmp & 0x11111);
 
        /* Change Divider - LEFTBUS */
-       tmp = __raw_readl(S5P_CLKDIV_LEFTBUS);
+       tmp = __raw_readl(EXYNOS4_CLKDIV_LEFTBUS);
 
-       tmp &= ~(S5P_CLKDIV_BUS_GDLR_MASK | S5P_CLKDIV_BUS_GPLR_MASK);
+       tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
 
        tmp |= ((exynos4x12_clkdiv_lr_bus[index][0] <<
-                               S5P_CLKDIV_BUS_GDLR_SHIFT) |
+                               EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
                (exynos4x12_clkdiv_lr_bus[index][1] <<
-                               S5P_CLKDIV_BUS_GPLR_SHIFT));
+                               EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
 
-       __raw_writel(tmp, S5P_CLKDIV_LEFTBUS);
+       __raw_writel(tmp, EXYNOS4_CLKDIV_LEFTBUS);
 
        do {
-               tmp = __raw_readl(S5P_CLKDIV_STAT_LEFTBUS);
+               tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_LEFTBUS);
        } while (tmp & 0x11);
 
        /* Change Divider - RIGHTBUS */
-       tmp = __raw_readl(S5P_CLKDIV_RIGHTBUS);
+       tmp = __raw_readl(EXYNOS4_CLKDIV_RIGHTBUS);
 
-       tmp &= ~(S5P_CLKDIV_BUS_GDLR_MASK | S5P_CLKDIV_BUS_GPLR_MASK);
+       tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
 
        tmp |= ((exynos4x12_clkdiv_lr_bus[index][0] <<
-                               S5P_CLKDIV_BUS_GDLR_SHIFT) |
+                               EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
                (exynos4x12_clkdiv_lr_bus[index][1] <<
-                               S5P_CLKDIV_BUS_GPLR_SHIFT));
+                               EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
 
-       __raw_writel(tmp, S5P_CLKDIV_RIGHTBUS);
+       __raw_writel(tmp, EXYNOS4_CLKDIV_RIGHTBUS);
 
        do {
-               tmp = __raw_readl(S5P_CLKDIV_STAT_RIGHTBUS);
+               tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_RIGHTBUS);
        } while (tmp & 0x11);
 
        /* Change Divider - MFC */
-       tmp = __raw_readl(S5P_CLKDIV_MFC);
+       tmp = __raw_readl(EXYNOS4_CLKDIV_MFC);
 
-       tmp &= ~(S5P_CLKDIV_MFC_MASK);
+       tmp &= ~(EXYNOS4_CLKDIV_MFC_MASK);
 
        tmp |= ((exynos4x12_clkdiv_sclkip[index][0] <<
-                               S5P_CLKDIV_MFC_SHIFT));
+                               EXYNOS4_CLKDIV_MFC_SHIFT));
 
-       __raw_writel(tmp, S5P_CLKDIV_MFC);
+       __raw_writel(tmp, EXYNOS4_CLKDIV_MFC);
 
        do {
-               tmp = __raw_readl(S5P_CLKDIV_STAT_MFC);
+               tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_MFC);
        } while (tmp & 0x1);
 
        /* Change Divider - JPEG */
-       tmp = __raw_readl(S5P_CLKDIV_CAM1);
+       tmp = __raw_readl(EXYNOS4_CLKDIV_CAM1);
 
-       tmp &= ~(S5P_CLKDIV_CAM1_JPEG_MASK);
+       tmp &= ~(EXYNOS4_CLKDIV_CAM1_JPEG_MASK);
 
        tmp |= ((exynos4x12_clkdiv_sclkip[index][1] <<
-                               S5P_CLKDIV_CAM1_JPEG_SHIFT));
+                               EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT));
 
-       __raw_writel(tmp, S5P_CLKDIV_CAM1);
+       __raw_writel(tmp, EXYNOS4_CLKDIV_CAM1);
 
        do {
-               tmp = __raw_readl(S5P_CLKDIV_STAT_CAM1);
+               tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_CAM1);
        } while (tmp & 0x1);
 
        /* Change Divider - FIMC0~3 */
-       tmp = __raw_readl(S5P_CLKDIV_CAM);
+       tmp = __raw_readl(EXYNOS4_CLKDIV_CAM);
 
-       tmp &= ~(S5P_CLKDIV_CAM_FIMC0_MASK | S5P_CLKDIV_CAM_FIMC1_MASK |
-               S5P_CLKDIV_CAM_FIMC2_MASK | S5P_CLKDIV_CAM_FIMC3_MASK);
+       tmp &= ~(EXYNOS4_CLKDIV_CAM_FIMC0_MASK | EXYNOS4_CLKDIV_CAM_FIMC1_MASK |
+               EXYNOS4_CLKDIV_CAM_FIMC2_MASK | EXYNOS4_CLKDIV_CAM_FIMC3_MASK);
 
        tmp |= ((exynos4x12_clkdiv_sclkip[index][2] <<
-                               S5P_CLKDIV_CAM_FIMC0_SHIFT) |
+                               EXYNOS4_CLKDIV_CAM_FIMC0_SHIFT) |
                (exynos4x12_clkdiv_sclkip[index][2] <<
-                               S5P_CLKDIV_CAM_FIMC1_SHIFT) |
+                               EXYNOS4_CLKDIV_CAM_FIMC1_SHIFT) |
                (exynos4x12_clkdiv_sclkip[index][2] <<
-                               S5P_CLKDIV_CAM_FIMC2_SHIFT) |
+                               EXYNOS4_CLKDIV_CAM_FIMC2_SHIFT) |
                (exynos4x12_clkdiv_sclkip[index][2] <<
-                               S5P_CLKDIV_CAM_FIMC3_SHIFT));
+                               EXYNOS4_CLKDIV_CAM_FIMC3_SHIFT));
 
-       __raw_writel(tmp, S5P_CLKDIV_CAM);
+       __raw_writel(tmp, EXYNOS4_CLKDIV_CAM);
 
        do {
-               tmp = __raw_readl(S5P_CLKDIV_STAT_CAM1);
+               tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_CAM1);
        } while (tmp & 0x1111);
 
        return 0;
@@ -760,55 +760,55 @@ static int exynos4210_init_tables(struct busfreq_data *data)
        int mgrp;
        int i, err = 0;
 
-       tmp = __raw_readl(S5P_CLKDIV_DMC0);
+       tmp = __raw_readl(EXYNOS4_CLKDIV_DMC0);
        for (i = LV_0; i < EX4210_LV_NUM; i++) {
-               tmp &= ~(S5P_CLKDIV_DMC0_ACP_MASK |
-                       S5P_CLKDIV_DMC0_ACPPCLK_MASK |
-                       S5P_CLKDIV_DMC0_DPHY_MASK |
-                       S5P_CLKDIV_DMC0_DMC_MASK |
-                       S5P_CLKDIV_DMC0_DMCD_MASK |
-                       S5P_CLKDIV_DMC0_DMCP_MASK |
-                       S5P_CLKDIV_DMC0_COPY2_MASK |
-                       S5P_CLKDIV_DMC0_CORETI_MASK);
+               tmp &= ~(EXYNOS4_CLKDIV_DMC0_ACP_MASK |
+                       EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK |
+                       EXYNOS4_CLKDIV_DMC0_DPHY_MASK |
+                       EXYNOS4_CLKDIV_DMC0_DMC_MASK |
+                       EXYNOS4_CLKDIV_DMC0_DMCD_MASK |
+                       EXYNOS4_CLKDIV_DMC0_DMCP_MASK |
+                       EXYNOS4_CLKDIV_DMC0_COPY2_MASK |
+                       EXYNOS4_CLKDIV_DMC0_CORETI_MASK);
 
                tmp |= ((exynos4210_clkdiv_dmc0[i][0] <<
-                                       S5P_CLKDIV_DMC0_ACP_SHIFT) |
+                                       EXYNOS4_CLKDIV_DMC0_ACP_SHIFT) |
                        (exynos4210_clkdiv_dmc0[i][1] <<
-                                       S5P_CLKDIV_DMC0_ACPPCLK_SHIFT) |
+                                       EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT) |
                        (exynos4210_clkdiv_dmc0[i][2] <<
-                                       S5P_CLKDIV_DMC0_DPHY_SHIFT) |
+                                       EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT) |
                        (exynos4210_clkdiv_dmc0[i][3] <<
-                                       S5P_CLKDIV_DMC0_DMC_SHIFT) |
+                                       EXYNOS4_CLKDIV_DMC0_DMC_SHIFT) |
                        (exynos4210_clkdiv_dmc0[i][4] <<
-                                       S5P_CLKDIV_DMC0_DMCD_SHIFT) |
+                                       EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT) |
                        (exynos4210_clkdiv_dmc0[i][5] <<
-                                       S5P_CLKDIV_DMC0_DMCP_SHIFT) |
+                                       EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT) |
                        (exynos4210_clkdiv_dmc0[i][6] <<
-                                       S5P_CLKDIV_DMC0_COPY2_SHIFT) |
+                                       EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT) |
                        (exynos4210_clkdiv_dmc0[i][7] <<
-                                       S5P_CLKDIV_DMC0_CORETI_SHIFT));
+                                       EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT));
 
                data->dmc_divtable[i] = tmp;
        }
 
-       tmp = __raw_readl(S5P_CLKDIV_TOP);
+       tmp = __raw_readl(EXYNOS4_CLKDIV_TOP);
        for (i = LV_0; i <  EX4210_LV_NUM; i++) {
-               tmp &= ~(S5P_CLKDIV_TOP_ACLK200_MASK |
-                       S5P_CLKDIV_TOP_ACLK100_MASK |
-                       S5P_CLKDIV_TOP_ACLK160_MASK |
-                       S5P_CLKDIV_TOP_ACLK133_MASK |
-                       S5P_CLKDIV_TOP_ONENAND_MASK);
+               tmp &= ~(EXYNOS4_CLKDIV_TOP_ACLK200_MASK |
+                       EXYNOS4_CLKDIV_TOP_ACLK100_MASK |
+                       EXYNOS4_CLKDIV_TOP_ACLK160_MASK |
+                       EXYNOS4_CLKDIV_TOP_ACLK133_MASK |
+                       EXYNOS4_CLKDIV_TOP_ONENAND_MASK);
 
                tmp |= ((exynos4210_clkdiv_top[i][0] <<
-                                       S5P_CLKDIV_TOP_ACLK200_SHIFT) |
+                                       EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT) |
                        (exynos4210_clkdiv_top[i][1] <<
-                                       S5P_CLKDIV_TOP_ACLK100_SHIFT) |
+                                       EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT) |
                        (exynos4210_clkdiv_top[i][2] <<
-                                       S5P_CLKDIV_TOP_ACLK160_SHIFT) |
+                                       EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT) |
                        (exynos4210_clkdiv_top[i][3] <<
-                                       S5P_CLKDIV_TOP_ACLK133_SHIFT) |
+                                       EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT) |
                        (exynos4210_clkdiv_top[i][4] <<
-                                       S5P_CLKDIV_TOP_ONENAND_SHIFT));
+                                       EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT));
 
                data->top_divtable[i] = tmp;
        }
@@ -868,32 +868,32 @@ static int exynos4x12_init_tables(struct busfreq_data *data)
        int ret;
 
        /* Enable pause function for DREX2 DVFS */
-       tmp = __raw_readl(S5P_DMC_PAUSE_CTRL);
-       tmp |= DMC_PAUSE_ENABLE;
-       __raw_writel(tmp, S5P_DMC_PAUSE_CTRL);
+       tmp = __raw_readl(EXYNOS4_DMC_PAUSE_CTRL);
+       tmp |= EXYNOS4_DMC_PAUSE_ENABLE;
+       __raw_writel(tmp, EXYNOS4_DMC_PAUSE_CTRL);
 
-       tmp = __raw_readl(S5P_CLKDIV_DMC0);
+       tmp = __raw_readl(EXYNOS4_CLKDIV_DMC0);
 
        for (i = 0; i <  EX4x12_LV_NUM; i++) {
-               tmp &= ~(S5P_CLKDIV_DMC0_ACP_MASK |
-                       S5P_CLKDIV_DMC0_ACPPCLK_MASK |
-                       S5P_CLKDIV_DMC0_DPHY_MASK |
-                       S5P_CLKDIV_DMC0_DMC_MASK |
-                       S5P_CLKDIV_DMC0_DMCD_MASK |
-                       S5P_CLKDIV_DMC0_DMCP_MASK);
+               tmp &= ~(EXYNOS4_CLKDIV_DMC0_ACP_MASK |
+                       EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK |
+                       EXYNOS4_CLKDIV_DMC0_DPHY_MASK |
+                       EXYNOS4_CLKDIV_DMC0_DMC_MASK |
+                       EXYNOS4_CLKDIV_DMC0_DMCD_MASK |
+                       EXYNOS4_CLKDIV_DMC0_DMCP_MASK);
 
                tmp |= ((exynos4x12_clkdiv_dmc0[i][0] <<
-                                       S5P_CLKDIV_DMC0_ACP_SHIFT) |
+                                       EXYNOS4_CLKDIV_DMC0_ACP_SHIFT) |
                        (exynos4x12_clkdiv_dmc0[i][1] <<
-                                       S5P_CLKDIV_DMC0_ACPPCLK_SHIFT) |
+                                       EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT) |
                        (exynos4x12_clkdiv_dmc0[i][2] <<
-                                       S5P_CLKDIV_DMC0_DPHY_SHIFT) |
+                                       EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT) |
                        (exynos4x12_clkdiv_dmc0[i][3] <<
-                                       S5P_CLKDIV_DMC0_DMC_SHIFT) |
+                                       EXYNOS4_CLKDIV_DMC0_DMC_SHIFT) |
                        (exynos4x12_clkdiv_dmc0[i][4] <<
-                                       S5P_CLKDIV_DMC0_DMCD_SHIFT) |
+                                       EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT) |
                        (exynos4x12_clkdiv_dmc0[i][5] <<
-                                       S5P_CLKDIV_DMC0_DMCP_SHIFT));
+                                       EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT));
 
                data->dmc_divtable[i] = tmp;
        }
index f1a274994bb1fbdc1c8e0e54b26aebe58b161c2b..4a6c46dea8a0c3c7741613576b5d9f180a2058c7 100644 (file)
@@ -252,6 +252,15 @@ config EP93XX_DMA
        help
          Enable support for the Cirrus Logic EP93xx M2P/M2M DMA controller.
 
+config DMA_SA11X0
+       tristate "SA-11x0 DMA support"
+       depends on ARCH_SA1100
+       select DMA_ENGINE
+       help
+         Support the DMA engine found on Intel StrongARM SA-1100 and
+         SA-1110 SoCs.  This DMA engine can only be used with on-chip
+         devices.
+
 config DMA_ENGINE
        bool
 
index 009a222e8283cba3929fd8763ae9abe9b4d6d694..86b795baba981907ed42f71ede7cd7263f0c5df8 100644 (file)
@@ -27,3 +27,4 @@ obj-$(CONFIG_PL330_DMA) += pl330.o
 obj-$(CONFIG_PCH_DMA) += pch_dma.o
 obj-$(CONFIG_AMBA_PL08X) += amba-pl08x.o
 obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
+obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c
new file mode 100644 (file)
index 0000000..16a6b48
--- /dev/null
@@ -0,0 +1,1109 @@
+/*
+ * SA11x0 DMAengine support
+ *
+ * Copyright (C) 2012 Russell King
+ *   Derived in part from arch/arm/mach-sa1100/dma.c,
+ *   Copyright (C) 2000, 2001 by Nicolas Pitre
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/sched.h>
+#include <linux/device.h>
+#include <linux/dmaengine.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sa11x0-dma.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#define NR_PHY_CHAN    6
+#define DMA_ALIGN      3
+#define DMA_MAX_SIZE   0x1fff
+#define DMA_CHUNK_SIZE 0x1000
+
+#define DMA_DDAR       0x00
+#define DMA_DCSR_S     0x04
+#define DMA_DCSR_C     0x08
+#define DMA_DCSR_R     0x0c
+#define DMA_DBSA       0x10
+#define DMA_DBTA       0x14
+#define DMA_DBSB       0x18
+#define DMA_DBTB       0x1c
+#define DMA_SIZE       0x20
+
+#define DCSR_RUN       (1 << 0)
+#define DCSR_IE                (1 << 1)
+#define DCSR_ERROR     (1 << 2)
+#define DCSR_DONEA     (1 << 3)
+#define DCSR_STRTA     (1 << 4)
+#define DCSR_DONEB     (1 << 5)
+#define DCSR_STRTB     (1 << 6)
+#define DCSR_BIU       (1 << 7)
+
+#define DDAR_RW                (1 << 0)        /* 0 = W, 1 = R */
+#define DDAR_E         (1 << 1)        /* 0 = LE, 1 = BE */
+#define DDAR_BS                (1 << 2)        /* 0 = BS4, 1 = BS8 */
+#define DDAR_DW                (1 << 3)        /* 0 = 8b, 1 = 16b */
+#define DDAR_Ser0UDCTr (0x0 << 4)
+#define DDAR_Ser0UDCRc (0x1 << 4)
+#define DDAR_Ser1SDLCTr        (0x2 << 4)
+#define DDAR_Ser1SDLCRc        (0x3 << 4)
+#define DDAR_Ser1UARTTr        (0x4 << 4)
+#define DDAR_Ser1UARTRc        (0x5 << 4)
+#define DDAR_Ser2ICPTr (0x6 << 4)
+#define DDAR_Ser2ICPRc (0x7 << 4)
+#define DDAR_Ser3UARTTr        (0x8 << 4)
+#define DDAR_Ser3UARTRc        (0x9 << 4)
+#define DDAR_Ser4MCP0Tr        (0xa << 4)
+#define DDAR_Ser4MCP0Rc        (0xb << 4)
+#define DDAR_Ser4MCP1Tr        (0xc << 4)
+#define DDAR_Ser4MCP1Rc        (0xd << 4)
+#define DDAR_Ser4SSPTr (0xe << 4)
+#define DDAR_Ser4SSPRc (0xf << 4)
+
+struct sa11x0_dma_sg {
+       u32                     addr;
+       u32                     len;
+};
+
+struct sa11x0_dma_desc {
+       struct dma_async_tx_descriptor tx;
+       u32                     ddar;
+       size_t                  size;
+
+       /* maybe protected by c->lock */
+       struct list_head        node;
+       unsigned                sglen;
+       struct sa11x0_dma_sg    sg[0];
+};
+
+struct sa11x0_dma_phy;
+
+struct sa11x0_dma_chan {
+       struct dma_chan         chan;
+       spinlock_t              lock;
+       dma_cookie_t            lc;
+
+       /* protected by c->lock */
+       struct sa11x0_dma_phy   *phy;
+       enum dma_status         status;
+       struct list_head        desc_submitted;
+       struct list_head        desc_issued;
+
+       /* protected by d->lock */
+       struct list_head        node;
+
+       u32                     ddar;
+       const char              *name;
+};
+
+struct sa11x0_dma_phy {
+       void __iomem            *base;
+       struct sa11x0_dma_dev   *dev;
+       unsigned                num;
+
+       struct sa11x0_dma_chan  *vchan;
+
+       /* Protected by c->lock */
+       unsigned                sg_load;
+       struct sa11x0_dma_desc  *txd_load;
+       unsigned                sg_done;
+       struct sa11x0_dma_desc  *txd_done;
+#ifdef CONFIG_PM_SLEEP
+       u32                     dbs[2];
+       u32                     dbt[2];
+       u32                     dcsr;
+#endif
+};
+
+struct sa11x0_dma_dev {
+       struct dma_device       slave;
+       void __iomem            *base;
+       spinlock_t              lock;
+       struct tasklet_struct   task;
+       struct list_head        chan_pending;
+       struct list_head        desc_complete;
+       struct sa11x0_dma_phy   phy[NR_PHY_CHAN];
+};
+
+static struct sa11x0_dma_chan *to_sa11x0_dma_chan(struct dma_chan *chan)
+{
+       return container_of(chan, struct sa11x0_dma_chan, chan);
+}
+
+static struct sa11x0_dma_dev *to_sa11x0_dma(struct dma_device *dmadev)
+{
+       return container_of(dmadev, struct sa11x0_dma_dev, slave);
+}
+
+static struct sa11x0_dma_desc *to_sa11x0_dma_tx(struct dma_async_tx_descriptor *tx)
+{
+       return container_of(tx, struct sa11x0_dma_desc, tx);
+}
+
+static struct sa11x0_dma_desc *sa11x0_dma_next_desc(struct sa11x0_dma_chan *c)
+{
+       if (list_empty(&c->desc_issued))
+               return NULL;
+
+       return list_first_entry(&c->desc_issued, struct sa11x0_dma_desc, node);
+}
+
+static void sa11x0_dma_start_desc(struct sa11x0_dma_phy *p, struct sa11x0_dma_desc *txd)
+{
+       list_del(&txd->node);
+       p->txd_load = txd;
+       p->sg_load = 0;
+
+       dev_vdbg(p->dev->slave.dev, "pchan %u: txd %p[%x]: starting: DDAR:%x\n",
+               p->num, txd, txd->tx.cookie, txd->ddar);
+}
+
+static void noinline sa11x0_dma_start_sg(struct sa11x0_dma_phy *p,
+       struct sa11x0_dma_chan *c)
+{
+       struct sa11x0_dma_desc *txd = p->txd_load;
+       struct sa11x0_dma_sg *sg;
+       void __iomem *base = p->base;
+       unsigned dbsx, dbtx;
+       u32 dcsr;
+
+       if (!txd)
+               return;
+
+       dcsr = readl_relaxed(base + DMA_DCSR_R);
+
+       /* Don't try to load the next transfer if both buffers are started */
+       if ((dcsr & (DCSR_STRTA | DCSR_STRTB)) == (DCSR_STRTA | DCSR_STRTB))
+               return;
+
+       if (p->sg_load == txd->sglen) {
+               struct sa11x0_dma_desc *txn = sa11x0_dma_next_desc(c);
+
+               /*
+                * We have reached the end of the current descriptor.
+                * Peek at the next descriptor, and if compatible with
+                * the current, start processing it.
+                */
+               if (txn && txn->ddar == txd->ddar) {
+                       txd = txn;
+                       sa11x0_dma_start_desc(p, txn);
+               } else {
+                       p->txd_load = NULL;
+                       return;
+               }
+       }
+
+       sg = &txd->sg[p->sg_load++];
+
+       /* Select buffer to load according to channel status */
+       if (((dcsr & (DCSR_BIU | DCSR_STRTB)) == (DCSR_BIU | DCSR_STRTB)) ||
+           ((dcsr & (DCSR_BIU | DCSR_STRTA)) == 0)) {
+               dbsx = DMA_DBSA;
+               dbtx = DMA_DBTA;
+               dcsr = DCSR_STRTA | DCSR_IE | DCSR_RUN;
+       } else {
+               dbsx = DMA_DBSB;
+               dbtx = DMA_DBTB;
+               dcsr = DCSR_STRTB | DCSR_IE | DCSR_RUN;
+       }
+
+       writel_relaxed(sg->addr, base + dbsx);
+       writel_relaxed(sg->len, base + dbtx);
+       writel(dcsr, base + DMA_DCSR_S);
+
+       dev_dbg(p->dev->slave.dev, "pchan %u: load: DCSR:%02x DBS%c:%08x DBT%c:%08x\n",
+               p->num, dcsr,
+               'A' + (dbsx == DMA_DBSB), sg->addr,
+               'A' + (dbtx == DMA_DBTB), sg->len);
+}
+
+static void noinline sa11x0_dma_complete(struct sa11x0_dma_phy *p,
+       struct sa11x0_dma_chan *c)
+{
+       struct sa11x0_dma_desc *txd = p->txd_done;
+
+       if (++p->sg_done == txd->sglen) {
+               struct sa11x0_dma_dev *d = p->dev;
+
+               dev_vdbg(d->slave.dev, "pchan %u: txd %p[%x]: completed\n",
+                       p->num, p->txd_done, p->txd_done->tx.cookie);
+
+               c->lc = txd->tx.cookie;
+
+               spin_lock(&d->lock);
+               list_add_tail(&txd->node, &d->desc_complete);
+               spin_unlock(&d->lock);
+
+               p->sg_done = 0;
+               p->txd_done = p->txd_load;
+
+               tasklet_schedule(&d->task);
+       }
+
+       sa11x0_dma_start_sg(p, c);
+}
+
+static irqreturn_t sa11x0_dma_irq(int irq, void *dev_id)
+{
+       struct sa11x0_dma_phy *p = dev_id;
+       struct sa11x0_dma_dev *d = p->dev;
+       struct sa11x0_dma_chan *c;
+       u32 dcsr;
+
+       dcsr = readl_relaxed(p->base + DMA_DCSR_R);
+       if (!(dcsr & (DCSR_ERROR | DCSR_DONEA | DCSR_DONEB)))
+               return IRQ_NONE;
+
+       /* Clear reported status bits */
+       writel_relaxed(dcsr & (DCSR_ERROR | DCSR_DONEA | DCSR_DONEB),
+               p->base + DMA_DCSR_C);
+
+       dev_dbg(d->slave.dev, "pchan %u: irq: DCSR:%02x\n", p->num, dcsr);
+
+       if (dcsr & DCSR_ERROR) {
+               dev_err(d->slave.dev, "pchan %u: error. DCSR:%02x DDAR:%08x DBSA:%08x DBTA:%08x DBSB:%08x DBTB:%08x\n",
+                       p->num, dcsr,
+                       readl_relaxed(p->base + DMA_DDAR),
+                       readl_relaxed(p->base + DMA_DBSA),
+                       readl_relaxed(p->base + DMA_DBTA),
+                       readl_relaxed(p->base + DMA_DBSB),
+                       readl_relaxed(p->base + DMA_DBTB));
+       }
+
+       c = p->vchan;
+       if (c) {
+               unsigned long flags;
+
+               spin_lock_irqsave(&c->lock, flags);
+               /*
+                * Now that we're holding the lock, check that the vchan
+                * really is associated with this pchan before touching the
+                * hardware.  This should always succeed, because we won't
+                * change p->vchan or c->phy while the channel is actively
+                * transferring.
+                */
+               if (c->phy == p) {
+                       if (dcsr & DCSR_DONEA)
+                               sa11x0_dma_complete(p, c);
+                       if (dcsr & DCSR_DONEB)
+                               sa11x0_dma_complete(p, c);
+               }
+               spin_unlock_irqrestore(&c->lock, flags);
+       }
+
+       return IRQ_HANDLED;
+}
+
+static void sa11x0_dma_start_txd(struct sa11x0_dma_chan *c)
+{
+       struct sa11x0_dma_desc *txd = sa11x0_dma_next_desc(c);
+
+       /* If the issued list is empty, we have no further txds to process */
+       if (txd) {
+               struct sa11x0_dma_phy *p = c->phy;
+
+               sa11x0_dma_start_desc(p, txd);
+               p->txd_done = txd;
+               p->sg_done = 0;
+
+               /* The channel should not have any transfers started */
+               WARN_ON(readl_relaxed(p->base + DMA_DCSR_R) &
+                                     (DCSR_STRTA | DCSR_STRTB));
+
+               /* Clear the run and start bits before changing DDAR */
+               writel_relaxed(DCSR_RUN | DCSR_STRTA | DCSR_STRTB,
+                              p->base + DMA_DCSR_C);
+               writel_relaxed(txd->ddar, p->base + DMA_DDAR);
+
+               /* Try to start both buffers */
+               sa11x0_dma_start_sg(p, c);
+               sa11x0_dma_start_sg(p, c);
+       }
+}
+
+static void sa11x0_dma_tasklet(unsigned long arg)
+{
+       struct sa11x0_dma_dev *d = (struct sa11x0_dma_dev *)arg;
+       struct sa11x0_dma_phy *p;
+       struct sa11x0_dma_chan *c;
+       struct sa11x0_dma_desc *txd, *txn;
+       LIST_HEAD(head);
+       unsigned pch, pch_alloc = 0;
+
+       dev_dbg(d->slave.dev, "tasklet enter\n");
+
+       /* Get the completed tx descriptors */
+       spin_lock_irq(&d->lock);
+       list_splice_init(&d->desc_complete, &head);
+       spin_unlock_irq(&d->lock);
+
+       list_for_each_entry(txd, &head, node) {
+               c = to_sa11x0_dma_chan(txd->tx.chan);
+
+               dev_dbg(d->slave.dev, "vchan %p: txd %p[%x] completed\n",
+                       c, txd, txd->tx.cookie);
+
+               spin_lock_irq(&c->lock);
+               p = c->phy;
+               if (p) {
+                       if (!p->txd_done)
+                               sa11x0_dma_start_txd(c);
+                       if (!p->txd_done) {
+                               /* No current txd associated with this channel */
+                               dev_dbg(d->slave.dev, "pchan %u: free\n", p->num);
+
+                               /* Mark this channel free */
+                               c->phy = NULL;
+                               p->vchan = NULL;
+                       }
+               }
+               spin_unlock_irq(&c->lock);
+       }
+
+       spin_lock_irq(&d->lock);
+       for (pch = 0; pch < NR_PHY_CHAN; pch++) {
+               p = &d->phy[pch];
+
+               if (p->vchan == NULL && !list_empty(&d->chan_pending)) {
+                       c = list_first_entry(&d->chan_pending,
+                               struct sa11x0_dma_chan, node);
+                       list_del_init(&c->node);
+
+                       pch_alloc |= 1 << pch;
+
+                       /* Mark this channel allocated */
+                       p->vchan = c;
+
+                       dev_dbg(d->slave.dev, "pchan %u: alloc vchan %p\n", pch, c);
+               }
+       }
+       spin_unlock_irq(&d->lock);
+
+       for (pch = 0; pch < NR_PHY_CHAN; pch++) {
+               if (pch_alloc & (1 << pch)) {
+                       p = &d->phy[pch];
+                       c = p->vchan;
+
+                       spin_lock_irq(&c->lock);
+                       c->phy = p;
+
+                       sa11x0_dma_start_txd(c);
+                       spin_unlock_irq(&c->lock);
+               }
+       }
+
+       /* Now free the completed tx descriptor, and call their callbacks */
+       list_for_each_entry_safe(txd, txn, &head, node) {
+               dma_async_tx_callback callback = txd->tx.callback;
+               void *callback_param = txd->tx.callback_param;
+
+               dev_dbg(d->slave.dev, "txd %p[%x]: callback and free\n",
+                       txd, txd->tx.cookie);
+
+               kfree(txd);
+
+               if (callback)
+                       callback(callback_param);
+       }
+
+       dev_dbg(d->slave.dev, "tasklet exit\n");
+}
+
+
+static void sa11x0_dma_desc_free(struct sa11x0_dma_dev *d, struct list_head *head)
+{
+       struct sa11x0_dma_desc *txd, *txn;
+
+       list_for_each_entry_safe(txd, txn, head, node) {
+               dev_dbg(d->slave.dev, "txd %p: freeing\n", txd);
+               kfree(txd);
+       }
+}
+
+static int sa11x0_dma_alloc_chan_resources(struct dma_chan *chan)
+{
+       return 0;
+}
+
+static void sa11x0_dma_free_chan_resources(struct dma_chan *chan)
+{
+       struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
+       struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device);
+       unsigned long flags;
+       LIST_HEAD(head);
+
+       spin_lock_irqsave(&c->lock, flags);
+       spin_lock(&d->lock);
+       list_del_init(&c->node);
+       spin_unlock(&d->lock);
+
+       list_splice_tail_init(&c->desc_submitted, &head);
+       list_splice_tail_init(&c->desc_issued, &head);
+       spin_unlock_irqrestore(&c->lock, flags);
+
+       sa11x0_dma_desc_free(d, &head);
+}
+
+static dma_addr_t sa11x0_dma_pos(struct sa11x0_dma_phy *p)
+{
+       unsigned reg;
+       u32 dcsr;
+
+       dcsr = readl_relaxed(p->base + DMA_DCSR_R);
+
+       if ((dcsr & (DCSR_BIU | DCSR_STRTA)) == DCSR_STRTA ||
+           (dcsr & (DCSR_BIU | DCSR_STRTB)) == DCSR_BIU)
+               reg = DMA_DBSA;
+       else
+               reg = DMA_DBSB;
+
+       return readl_relaxed(p->base + reg);
+}
+
+static enum dma_status sa11x0_dma_tx_status(struct dma_chan *chan,
+       dma_cookie_t cookie, struct dma_tx_state *state)
+{
+       struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
+       struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device);
+       struct sa11x0_dma_phy *p;
+       struct sa11x0_dma_desc *txd;
+       dma_cookie_t last_used, last_complete;
+       unsigned long flags;
+       enum dma_status ret;
+       size_t bytes = 0;
+
+       last_used = c->chan.cookie;
+       last_complete = c->lc;
+
+       ret = dma_async_is_complete(cookie, last_complete, last_used);
+       if (ret == DMA_SUCCESS) {
+               dma_set_tx_state(state, last_complete, last_used, 0);
+               return ret;
+       }
+
+       spin_lock_irqsave(&c->lock, flags);
+       p = c->phy;
+       ret = c->status;
+       if (p) {
+               dma_addr_t addr = sa11x0_dma_pos(p);
+
+               dev_vdbg(d->slave.dev, "tx_status: addr:%x\n", addr);
+
+               txd = p->txd_done;
+               if (txd) {
+                       unsigned i;
+
+                       for (i = 0; i < txd->sglen; i++) {
+                               dev_vdbg(d->slave.dev, "tx_status: [%u] %x+%x\n",
+                                       i, txd->sg[i].addr, txd->sg[i].len);
+                               if (addr >= txd->sg[i].addr &&
+                                   addr < txd->sg[i].addr + txd->sg[i].len) {
+                                       unsigned len;
+
+                                       len = txd->sg[i].len -
+                                               (addr - txd->sg[i].addr);
+                                       dev_vdbg(d->slave.dev, "tx_status: [%u] +%x\n",
+                                               i, len);
+                                       bytes += len;
+                                       i++;
+                                       break;
+                               }
+                       }
+                       for (; i < txd->sglen; i++) {
+                               dev_vdbg(d->slave.dev, "tx_status: [%u] %x+%x ++\n",
+                                       i, txd->sg[i].addr, txd->sg[i].len);
+                               bytes += txd->sg[i].len;
+                       }
+               }
+               if (txd != p->txd_load && p->txd_load)
+                       bytes += p->txd_load->size;
+       }
+       list_for_each_entry(txd, &c->desc_issued, node) {
+               bytes += txd->size;
+       }
+       spin_unlock_irqrestore(&c->lock, flags);
+
+       dma_set_tx_state(state, last_complete, last_used, bytes);
+
+       dev_vdbg(d->slave.dev, "tx_status: bytes 0x%zx\n", bytes);
+
+       return ret;
+}
+
+/*
+ * Move pending txds to the issued list, and re-init pending list.
+ * If not already pending, add this channel to the list of pending
+ * channels and trigger the tasklet to run.
+ */
+static void sa11x0_dma_issue_pending(struct dma_chan *chan)
+{
+       struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
+       struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device);
+       unsigned long flags;
+
+       spin_lock_irqsave(&c->lock, flags);
+       list_splice_tail_init(&c->desc_submitted, &c->desc_issued);
+       if (!list_empty(&c->desc_issued)) {
+               spin_lock(&d->lock);
+               if (!c->phy && list_empty(&c->node)) {
+                       list_add_tail(&c->node, &d->chan_pending);
+                       tasklet_schedule(&d->task);
+                       dev_dbg(d->slave.dev, "vchan %p: issued\n", c);
+               }
+               spin_unlock(&d->lock);
+       } else
+               dev_dbg(d->slave.dev, "vchan %p: nothing to issue\n", c);
+       spin_unlock_irqrestore(&c->lock, flags);
+}
+
+static dma_cookie_t sa11x0_dma_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+       struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(tx->chan);
+       struct sa11x0_dma_desc *txd = to_sa11x0_dma_tx(tx);
+       unsigned long flags;
+
+       spin_lock_irqsave(&c->lock, flags);
+       c->chan.cookie += 1;
+       if (c->chan.cookie < 0)
+               c->chan.cookie = 1;
+       txd->tx.cookie = c->chan.cookie;
+
+       list_add_tail(&txd->node, &c->desc_submitted);
+       spin_unlock_irqrestore(&c->lock, flags);
+
+       dev_dbg(tx->chan->device->dev, "vchan %p: txd %p[%x]: submitted\n",
+               c, txd, txd->tx.cookie);
+
+       return txd->tx.cookie;
+}
+
+static struct dma_async_tx_descriptor *sa11x0_dma_prep_slave_sg(
+       struct dma_chan *chan, struct scatterlist *sg, unsigned int sglen,
+       enum dma_transfer_direction dir, unsigned long flags)
+{
+       struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
+       struct sa11x0_dma_desc *txd;
+       struct scatterlist *sgent;
+       unsigned i, j = sglen;
+       size_t size = 0;
+
+       /* SA11x0 channels can only operate in their native direction */
+       if (dir != (c->ddar & DDAR_RW ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV)) {
+               dev_err(chan->device->dev, "vchan %p: bad DMA direction: DDAR:%08x dir:%u\n",
+                       c, c->ddar, dir);
+               return NULL;
+       }
+
+       /* Do not allow zero-sized txds */
+       if (sglen == 0)
+               return NULL;
+
+       for_each_sg(sg, sgent, sglen, i) {
+               dma_addr_t addr = sg_dma_address(sgent);
+               unsigned int len = sg_dma_len(sgent);
+
+               if (len > DMA_MAX_SIZE)
+                       j += DIV_ROUND_UP(len, DMA_MAX_SIZE & ~DMA_ALIGN) - 1;
+               if (addr & DMA_ALIGN) {
+                       dev_dbg(chan->device->dev, "vchan %p: bad buffer alignment: %08x\n",
+                               c, addr);
+                       return NULL;
+               }
+       }
+
+       txd = kzalloc(sizeof(*txd) + j * sizeof(txd->sg[0]), GFP_ATOMIC);
+       if (!txd) {
+               dev_dbg(chan->device->dev, "vchan %p: kzalloc failed\n", c);
+               return NULL;
+       }
+
+       j = 0;
+       for_each_sg(sg, sgent, sglen, i) {
+               dma_addr_t addr = sg_dma_address(sgent);
+               unsigned len = sg_dma_len(sgent);
+
+               size += len;
+
+               do {
+                       unsigned tlen = len;
+
+                       /*
+                        * Check whether the transfer will fit.  If not, try
+                        * to split the transfer up such that we end up with
+                        * equal chunks - but make sure that we preserve the
+                        * alignment.  This avoids small segments.
+                        */
+                       if (tlen > DMA_MAX_SIZE) {
+                               unsigned mult = DIV_ROUND_UP(tlen,
+                                       DMA_MAX_SIZE & ~DMA_ALIGN);
+
+                               tlen = (tlen / mult) & ~DMA_ALIGN;
+                       }
+
+                       txd->sg[j].addr = addr;
+                       txd->sg[j].len = tlen;
+
+                       addr += tlen;
+                       len -= tlen;
+                       j++;
+               } while (len);
+       }
+
+       dma_async_tx_descriptor_init(&txd->tx, &c->chan);
+       txd->tx.flags = flags;
+       txd->tx.tx_submit = sa11x0_dma_tx_submit;
+       txd->ddar = c->ddar;
+       txd->size = size;
+       txd->sglen = j;
+
+       dev_dbg(chan->device->dev, "vchan %p: txd %p: size %u nr %u\n",
+               c, txd, txd->size, txd->sglen);
+
+       return &txd->tx;
+}
+
+static int sa11x0_dma_slave_config(struct sa11x0_dma_chan *c, struct dma_slave_config *cfg)
+{
+       u32 ddar = c->ddar & ((0xf << 4) | DDAR_RW);
+       dma_addr_t addr;
+       enum dma_slave_buswidth width;
+       u32 maxburst;
+
+       if (ddar & DDAR_RW) {
+               addr = cfg->src_addr;
+               width = cfg->src_addr_width;
+               maxburst = cfg->src_maxburst;
+       } else {
+               addr = cfg->dst_addr;
+               width = cfg->dst_addr_width;
+               maxburst = cfg->dst_maxburst;
+       }
+
+       if ((width != DMA_SLAVE_BUSWIDTH_1_BYTE &&
+            width != DMA_SLAVE_BUSWIDTH_2_BYTES) ||
+           (maxburst != 4 && maxburst != 8))
+               return -EINVAL;
+
+       if (width == DMA_SLAVE_BUSWIDTH_2_BYTES)
+               ddar |= DDAR_DW;
+       if (maxburst == 8)
+               ddar |= DDAR_BS;
+
+       dev_dbg(c->chan.device->dev, "vchan %p: dma_slave_config addr %x width %u burst %u\n",
+               c, addr, width, maxburst);
+
+       c->ddar = ddar | (addr & 0xf0000000) | (addr & 0x003ffffc) << 6;
+
+       return 0;
+}
+
+static int sa11x0_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+       unsigned long arg)
+{
+       struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
+       struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device);
+       struct sa11x0_dma_phy *p;
+       LIST_HEAD(head);
+       unsigned long flags;
+       int ret;
+
+       switch (cmd) {
+       case DMA_SLAVE_CONFIG:
+               return sa11x0_dma_slave_config(c, (struct dma_slave_config *)arg);
+
+       case DMA_TERMINATE_ALL:
+               dev_dbg(d->slave.dev, "vchan %p: terminate all\n", c);
+               /* Clear the tx descriptor lists */
+               spin_lock_irqsave(&c->lock, flags);
+               list_splice_tail_init(&c->desc_submitted, &head);
+               list_splice_tail_init(&c->desc_issued, &head);
+
+               p = c->phy;
+               if (p) {
+                       struct sa11x0_dma_desc *txd, *txn;
+
+                       dev_dbg(d->slave.dev, "pchan %u: terminating\n", p->num);
+                       /* vchan is assigned to a pchan - stop the channel */
+                       writel(DCSR_RUN | DCSR_IE |
+                               DCSR_STRTA | DCSR_DONEA |
+                               DCSR_STRTB | DCSR_DONEB,
+                               p->base + DMA_DCSR_C);
+
+                       list_for_each_entry_safe(txd, txn, &d->desc_complete, node)
+                               if (txd->tx.chan == &c->chan)
+                                       list_move(&txd->node, &head);
+
+                       if (p->txd_load) {
+                               if (p->txd_load != p->txd_done)
+                                       list_add_tail(&p->txd_load->node, &head);
+                               p->txd_load = NULL;
+                       }
+                       if (p->txd_done) {
+                               list_add_tail(&p->txd_done->node, &head);
+                               p->txd_done = NULL;
+                       }
+                       c->phy = NULL;
+                       spin_lock(&d->lock);
+                       p->vchan = NULL;
+                       spin_unlock(&d->lock);
+                       tasklet_schedule(&d->task);
+               }
+               spin_unlock_irqrestore(&c->lock, flags);
+               sa11x0_dma_desc_free(d, &head);
+               ret = 0;
+               break;
+
+       case DMA_PAUSE:
+               dev_dbg(d->slave.dev, "vchan %p: pause\n", c);
+               spin_lock_irqsave(&c->lock, flags);
+               if (c->status == DMA_IN_PROGRESS) {
+                       c->status = DMA_PAUSED;
+
+                       p = c->phy;
+                       if (p) {
+                               writel(DCSR_RUN | DCSR_IE, p->base + DMA_DCSR_C);
+                       } else {
+                               spin_lock(&d->lock);
+                               list_del_init(&c->node);
+                               spin_unlock(&d->lock);
+                       }
+               }
+               spin_unlock_irqrestore(&c->lock, flags);
+               ret = 0;
+               break;
+
+       case DMA_RESUME:
+               dev_dbg(d->slave.dev, "vchan %p: resume\n", c);
+               spin_lock_irqsave(&c->lock, flags);
+               if (c->status == DMA_PAUSED) {
+                       c->status = DMA_IN_PROGRESS;
+
+                       p = c->phy;
+                       if (p) {
+                               writel(DCSR_RUN | DCSR_IE, p->base + DMA_DCSR_S);
+                       } else if (!list_empty(&c->desc_issued)) {
+                               spin_lock(&d->lock);
+                               list_add_tail(&c->node, &d->chan_pending);
+                               spin_unlock(&d->lock);
+                       }
+               }
+               spin_unlock_irqrestore(&c->lock, flags);
+               ret = 0;
+               break;
+
+       default:
+               ret = -ENXIO;
+               break;
+       }
+
+       return ret;
+}
+
+struct sa11x0_dma_channel_desc {
+       u32 ddar;
+       const char *name;
+};
+
+#define CD(d1, d2) { .ddar = DDAR_##d1 | d2, .name = #d1 }
+static const struct sa11x0_dma_channel_desc chan_desc[] = {
+       CD(Ser0UDCTr, 0),
+       CD(Ser0UDCRc, DDAR_RW),
+       CD(Ser1SDLCTr, 0),
+       CD(Ser1SDLCRc, DDAR_RW),
+       CD(Ser1UARTTr, 0),
+       CD(Ser1UARTRc, DDAR_RW),
+       CD(Ser2ICPTr, 0),
+       CD(Ser2ICPRc, DDAR_RW),
+       CD(Ser3UARTTr, 0),
+       CD(Ser3UARTRc, DDAR_RW),
+       CD(Ser4MCP0Tr, 0),
+       CD(Ser4MCP0Rc, DDAR_RW),
+       CD(Ser4MCP1Tr, 0),
+       CD(Ser4MCP1Rc, DDAR_RW),
+       CD(Ser4SSPTr, 0),
+       CD(Ser4SSPRc, DDAR_RW),
+};
+
+static int __devinit sa11x0_dma_init_dmadev(struct dma_device *dmadev,
+       struct device *dev)
+{
+       unsigned i;
+
+       dmadev->chancnt = ARRAY_SIZE(chan_desc);
+       INIT_LIST_HEAD(&dmadev->channels);
+       dmadev->dev = dev;
+       dmadev->device_alloc_chan_resources = sa11x0_dma_alloc_chan_resources;
+       dmadev->device_free_chan_resources = sa11x0_dma_free_chan_resources;
+       dmadev->device_control = sa11x0_dma_control;
+       dmadev->device_tx_status = sa11x0_dma_tx_status;
+       dmadev->device_issue_pending = sa11x0_dma_issue_pending;
+
+       for (i = 0; i < dmadev->chancnt; i++) {
+               struct sa11x0_dma_chan *c;
+
+               c = kzalloc(sizeof(*c), GFP_KERNEL);
+               if (!c) {
+                       dev_err(dev, "no memory for channel %u\n", i);
+                       return -ENOMEM;
+               }
+
+               c->chan.device = dmadev;
+               c->status = DMA_IN_PROGRESS;
+               c->ddar = chan_desc[i].ddar;
+               c->name = chan_desc[i].name;
+               spin_lock_init(&c->lock);
+               INIT_LIST_HEAD(&c->desc_submitted);
+               INIT_LIST_HEAD(&c->desc_issued);
+               INIT_LIST_HEAD(&c->node);
+               list_add_tail(&c->chan.device_node, &dmadev->channels);
+       }
+
+       return dma_async_device_register(dmadev);
+}
+
+static int sa11x0_dma_request_irq(struct platform_device *pdev, int nr,
+       void *data)
+{
+       int irq = platform_get_irq(pdev, nr);
+
+       if (irq <= 0)
+               return -ENXIO;
+
+       return request_irq(irq, sa11x0_dma_irq, 0, dev_name(&pdev->dev), data);
+}
+
+static void sa11x0_dma_free_irq(struct platform_device *pdev, int nr,
+       void *data)
+{
+       int irq = platform_get_irq(pdev, nr);
+       if (irq > 0)
+               free_irq(irq, data);
+}
+
+static void sa11x0_dma_free_channels(struct dma_device *dmadev)
+{
+       struct sa11x0_dma_chan *c, *cn;
+
+       list_for_each_entry_safe(c, cn, &dmadev->channels, chan.device_node) {
+               list_del(&c->chan.device_node);
+               kfree(c);
+       }
+}
+
+static int __devinit sa11x0_dma_probe(struct platform_device *pdev)
+{
+       struct sa11x0_dma_dev *d;
+       struct resource *res;
+       unsigned i;
+       int ret;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENXIO;
+
+       d = kzalloc(sizeof(*d), GFP_KERNEL);
+       if (!d) {
+               ret = -ENOMEM;
+               goto err_alloc;
+       }
+
+       spin_lock_init(&d->lock);
+       INIT_LIST_HEAD(&d->chan_pending);
+       INIT_LIST_HEAD(&d->desc_complete);
+
+       d->base = ioremap(res->start, resource_size(res));
+       if (!d->base) {
+               ret = -ENOMEM;
+               goto err_ioremap;
+       }
+
+       tasklet_init(&d->task, sa11x0_dma_tasklet, (unsigned long)d);
+
+       for (i = 0; i < NR_PHY_CHAN; i++) {
+               struct sa11x0_dma_phy *p = &d->phy[i];
+
+               p->dev = d;
+               p->num = i;
+               p->base = d->base + i * DMA_SIZE;
+               writel_relaxed(DCSR_RUN | DCSR_IE | DCSR_ERROR |
+                       DCSR_DONEA | DCSR_STRTA | DCSR_DONEB | DCSR_STRTB,
+                       p->base + DMA_DCSR_C);
+               writel_relaxed(0, p->base + DMA_DDAR);
+
+               ret = sa11x0_dma_request_irq(pdev, i, p);
+               if (ret) {
+                       while (i) {
+                               i--;
+                               sa11x0_dma_free_irq(pdev, i, &d->phy[i]);
+                       }
+                       goto err_irq;
+               }
+       }
+
+       dma_cap_set(DMA_SLAVE, d->slave.cap_mask);
+       d->slave.device_prep_slave_sg = sa11x0_dma_prep_slave_sg;
+       ret = sa11x0_dma_init_dmadev(&d->slave, &pdev->dev);
+       if (ret) {
+               dev_warn(d->slave.dev, "failed to register slave async device: %d\n",
+                       ret);
+               goto err_slave_reg;
+       }
+
+       platform_set_drvdata(pdev, d);
+       return 0;
+
+ err_slave_reg:
+       sa11x0_dma_free_channels(&d->slave);
+       for (i = 0; i < NR_PHY_CHAN; i++)
+               sa11x0_dma_free_irq(pdev, i, &d->phy[i]);
+ err_irq:
+       tasklet_kill(&d->task);
+       iounmap(d->base);
+ err_ioremap:
+       kfree(d);
+ err_alloc:
+       return ret;
+}
+
+static int __devexit sa11x0_dma_remove(struct platform_device *pdev)
+{
+       struct sa11x0_dma_dev *d = platform_get_drvdata(pdev);
+       unsigned pch;
+
+       dma_async_device_unregister(&d->slave);
+
+       sa11x0_dma_free_channels(&d->slave);
+       for (pch = 0; pch < NR_PHY_CHAN; pch++)
+               sa11x0_dma_free_irq(pdev, pch, &d->phy[pch]);
+       tasklet_kill(&d->task);
+       iounmap(d->base);
+       kfree(d);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int sa11x0_dma_suspend(struct device *dev)
+{
+       struct sa11x0_dma_dev *d = dev_get_drvdata(dev);
+       unsigned pch;
+
+       for (pch = 0; pch < NR_PHY_CHAN; pch++) {
+               struct sa11x0_dma_phy *p = &d->phy[pch];
+               u32 dcsr, saved_dcsr;
+
+               dcsr = saved_dcsr = readl_relaxed(p->base + DMA_DCSR_R);
+               if (dcsr & DCSR_RUN) {
+                       writel(DCSR_RUN | DCSR_IE, p->base + DMA_DCSR_C);
+                       dcsr = readl_relaxed(p->base + DMA_DCSR_R);
+               }
+
+               saved_dcsr &= DCSR_RUN | DCSR_IE;
+               if (dcsr & DCSR_BIU) {
+                       p->dbs[0] = readl_relaxed(p->base + DMA_DBSB);
+                       p->dbt[0] = readl_relaxed(p->base + DMA_DBTB);
+                       p->dbs[1] = readl_relaxed(p->base + DMA_DBSA);
+                       p->dbt[1] = readl_relaxed(p->base + DMA_DBTA);
+                       saved_dcsr |= (dcsr & DCSR_STRTA ? DCSR_STRTB : 0) |
+                                     (dcsr & DCSR_STRTB ? DCSR_STRTA : 0);
+               } else {
+                       p->dbs[0] = readl_relaxed(p->base + DMA_DBSA);
+                       p->dbt[0] = readl_relaxed(p->base + DMA_DBTA);
+                       p->dbs[1] = readl_relaxed(p->base + DMA_DBSB);
+                       p->dbt[1] = readl_relaxed(p->base + DMA_DBTB);
+                       saved_dcsr |= dcsr & (DCSR_STRTA | DCSR_STRTB);
+               }
+               p->dcsr = saved_dcsr;
+
+               writel(DCSR_STRTA | DCSR_STRTB, p->base + DMA_DCSR_C);
+       }
+
+       return 0;
+}
+
+static int sa11x0_dma_resume(struct device *dev)
+{
+       struct sa11x0_dma_dev *d = dev_get_drvdata(dev);
+       unsigned pch;
+
+       for (pch = 0; pch < NR_PHY_CHAN; pch++) {
+               struct sa11x0_dma_phy *p = &d->phy[pch];
+               struct sa11x0_dma_desc *txd = NULL;
+               u32 dcsr = readl_relaxed(p->base + DMA_DCSR_R);
+
+               WARN_ON(dcsr & (DCSR_BIU | DCSR_STRTA | DCSR_STRTB | DCSR_RUN));
+
+               if (p->txd_done)
+                       txd = p->txd_done;
+               else if (p->txd_load)
+                       txd = p->txd_load;
+
+               if (!txd)
+                       continue;
+
+               writel_relaxed(txd->ddar, p->base + DMA_DDAR);
+
+               writel_relaxed(p->dbs[0], p->base + DMA_DBSA);
+               writel_relaxed(p->dbt[0], p->base + DMA_DBTA);
+               writel_relaxed(p->dbs[1], p->base + DMA_DBSB);
+               writel_relaxed(p->dbt[1], p->base + DMA_DBTB);
+               writel_relaxed(p->dcsr, p->base + DMA_DCSR_S);
+       }
+
+       return 0;
+}
+#endif
+
+static const struct dev_pm_ops sa11x0_dma_pm_ops = {
+       .suspend_noirq = sa11x0_dma_suspend,
+       .resume_noirq = sa11x0_dma_resume,
+       .freeze_noirq = sa11x0_dma_suspend,
+       .thaw_noirq = sa11x0_dma_resume,
+       .poweroff_noirq = sa11x0_dma_suspend,
+       .restore_noirq = sa11x0_dma_resume,
+};
+
+static struct platform_driver sa11x0_dma_driver = {
+       .driver = {
+               .name   = "sa11x0-dma",
+               .owner  = THIS_MODULE,
+               .pm     = &sa11x0_dma_pm_ops,
+       },
+       .probe          = sa11x0_dma_probe,
+       .remove         = __devexit_p(sa11x0_dma_remove),
+};
+
+bool sa11x0_dma_filter_fn(struct dma_chan *chan, void *param)
+{
+       if (chan->device->dev->driver == &sa11x0_dma_driver.driver) {
+               struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
+               const char *p = param;
+
+               return !strcmp(c->name, p);
+       }
+       return false;
+}
+EXPORT_SYMBOL(sa11x0_dma_filter_fn);
+
+static int __init sa11x0_dma_init(void)
+{
+       return platform_driver_register(&sa11x0_dma_driver);
+}
+subsys_initcall(sa11x0_dma_init);
+
+static void __exit sa11x0_dma_exit(void)
+{
+       platform_driver_unregister(&sa11x0_dma_driver);
+}
+module_exit(sa11x0_dma_exit);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("SA-11x0 DMA driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:sa11x0-dma");
index 1c0fc3756cb103c89c616ed6d3258b3c21864926..4ca5642e9776108b5ba873be4faa0dd37e3c08ac 100644 (file)
@@ -378,13 +378,6 @@ static int __devinit ep93xx_gpio_probe(struct platform_device *pdev)
        }
        ep93xx_gpio->mmio_base = mmio;
 
-       /* Default all ports to GPIO */
-       ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS |
-                              EP93XX_SYSCON_DEVCFG_GONK |
-                              EP93XX_SYSCON_DEVCFG_EONIDE |
-                              EP93XX_SYSCON_DEVCFG_GONIDE |
-                              EP93XX_SYSCON_DEVCFG_HONIDE);
-
        for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
                struct bgpio_chip *bgc = &ep93xx_gpio->bgc[i];
                struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i];
index 0b0562979171065bb3c454112c985cb74a633728..f49bd6f47a504b0ec732173e202f6f3dca716afd 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>
+#include <linux/pm.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/gpio.h>
 #include <asm/mach/irq.h>
 
+#define OFF_MODE       1
+
+static LIST_HEAD(omap_gpio_list);
+
+struct gpio_regs {
+       u32 irqenable1;
+       u32 irqenable2;
+       u32 wake_en;
+       u32 ctrl;
+       u32 oe;
+       u32 leveldetect0;
+       u32 leveldetect1;
+       u32 risingdetect;
+       u32 fallingdetect;
+       u32 dataout;
+       u32 debounce;
+       u32 debounce_en;
+};
+
 struct gpio_bank {
+       struct list_head node;
        unsigned long pbase;
        void __iomem *base;
        u16 irq;
        u16 virtual_irq_start;
-       int method;
        u32 suspend_wakeup;
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
        u32 saved_wakeup;
-#endif
        u32 non_wakeup_gpios;
        u32 enabled_non_wakeup_gpios;
-
+       struct gpio_regs context;
        u32 saved_datain;
        u32 saved_fallingdetect;
        u32 saved_risingdetect;
@@ -51,44 +69,27 @@ struct gpio_bank {
        struct clk *dbck;
        u32 mod_usage;
        u32 dbck_enable_mask;
+       bool dbck_enabled;
        struct device *dev;
+       bool is_mpuio;
        bool dbck_flag;
+       bool loses_context;
        int stride;
        u32 width;
+       int context_loss_count;
+       u16 id;
+       int power_mode;
+       bool workaround_enabled;
 
        void (*set_dataout)(struct gpio_bank *bank, int gpio, int enable);
+       int (*get_context_loss_count)(struct device *dev);
 
        struct omap_gpio_reg_offs *regs;
 };
 
-#ifdef CONFIG_ARCH_OMAP3
-struct omap3_gpio_regs {
-       u32 irqenable1;
-       u32 irqenable2;
-       u32 wake_en;
-       u32 ctrl;
-       u32 oe;
-       u32 leveldetect0;
-       u32 leveldetect1;
-       u32 risingdetect;
-       u32 fallingdetect;
-       u32 dataout;
-};
-
-static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS];
-#endif
-
-/*
- * TODO: Cleanup gpio_bank usage as it is having information
- * related to all instances of the device
- */
-static struct gpio_bank *gpio_bank;
-
-/* TODO: Analyze removing gpio_bank_count usage from driver code */
-int gpio_bank_count;
-
 #define GPIO_INDEX(bank, gpio) (gpio % bank->width)
 #define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio))
+#define GPIO_MOD_CTRL_BIT      BIT(0)
 
 static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
 {
@@ -102,6 +103,7 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
        else
                l &= ~(1 << gpio);
        __raw_writel(l, reg);
+       bank->context.oe = l;
 }
 
 
@@ -132,6 +134,7 @@ static void _set_gpio_dataout_mask(struct gpio_bank *bank, int gpio, int enable)
        else
                l &= ~gpio_bit;
        __raw_writel(l, reg);
+       bank->context.dataout = l;
 }
 
 static int _get_gpio_datain(struct gpio_bank *bank, int gpio)
@@ -160,6 +163,22 @@ static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set)
        __raw_writel(l, base + reg);
 }
 
+static inline void _gpio_dbck_enable(struct gpio_bank *bank)
+{
+       if (bank->dbck_enable_mask && !bank->dbck_enabled) {
+               clk_enable(bank->dbck);
+               bank->dbck_enabled = true;
+       }
+}
+
+static inline void _gpio_dbck_disable(struct gpio_bank *bank)
+{
+       if (bank->dbck_enable_mask && bank->dbck_enabled) {
+               clk_disable(bank->dbck);
+               bank->dbck_enabled = false;
+       }
+}
+
 /**
  * _set_gpio_debounce - low level gpio debounce time
  * @bank: the gpio bank we're acting upon
@@ -188,70 +207,74 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
 
        l = GPIO_BIT(bank, gpio);
 
+       clk_enable(bank->dbck);
        reg = bank->base + bank->regs->debounce;
        __raw_writel(debounce, reg);
 
        reg = bank->base + bank->regs->debounce_en;
        val = __raw_readl(reg);
 
-       if (debounce) {
+       if (debounce)
                val |= l;
-               clk_enable(bank->dbck);
-       } else {
+       else
                val &= ~l;
-               clk_disable(bank->dbck);
-       }
        bank->dbck_enable_mask = val;
 
        __raw_writel(val, reg);
+       clk_disable(bank->dbck);
+       /*
+        * Enable debounce clock per module.
+        * This call is mandatory because in omap_gpio_request() when
+        * *_runtime_get_sync() is called,  _gpio_dbck_enable() within
+        * runtime callbck fails to turn on dbck because dbck_enable_mask
+        * used within _gpio_dbck_enable() is still not initialized at
+        * that point. Therefore we have to enable dbck here.
+        */
+       _gpio_dbck_enable(bank);
+       if (bank->dbck_enable_mask) {
+               bank->context.debounce = debounce;
+               bank->context.debounce_en = val;
+       }
 }
 
-#ifdef CONFIG_ARCH_OMAP2PLUS
-static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
+static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio,
                                                int trigger)
 {
        void __iomem *base = bank->base;
        u32 gpio_bit = 1 << gpio;
 
-       if (cpu_is_omap44xx()) {
-               _gpio_rmw(base, OMAP4_GPIO_LEVELDETECT0, gpio_bit,
-                         trigger & IRQ_TYPE_LEVEL_LOW);
-               _gpio_rmw(base, OMAP4_GPIO_LEVELDETECT1, gpio_bit,
-                         trigger & IRQ_TYPE_LEVEL_HIGH);
-               _gpio_rmw(base, OMAP4_GPIO_RISINGDETECT, gpio_bit,
-                         trigger & IRQ_TYPE_EDGE_RISING);
-               _gpio_rmw(base, OMAP4_GPIO_FALLINGDETECT, gpio_bit,
-                         trigger & IRQ_TYPE_EDGE_FALLING);
-       } else {
-               _gpio_rmw(base, OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
-                         trigger & IRQ_TYPE_LEVEL_LOW);
-               _gpio_rmw(base, OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
-                         trigger & IRQ_TYPE_LEVEL_HIGH);
-               _gpio_rmw(base, OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
-                         trigger & IRQ_TYPE_EDGE_RISING);
-               _gpio_rmw(base, OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
-                         trigger & IRQ_TYPE_EDGE_FALLING);
-       }
+       _gpio_rmw(base, bank->regs->leveldetect0, gpio_bit,
+                 trigger & IRQ_TYPE_LEVEL_LOW);
+       _gpio_rmw(base, bank->regs->leveldetect1, gpio_bit,
+                 trigger & IRQ_TYPE_LEVEL_HIGH);
+       _gpio_rmw(base, bank->regs->risingdetect, gpio_bit,
+                 trigger & IRQ_TYPE_EDGE_RISING);
+       _gpio_rmw(base, bank->regs->fallingdetect, gpio_bit,
+                 trigger & IRQ_TYPE_EDGE_FALLING);
+
+       bank->context.leveldetect0 =
+                       __raw_readl(bank->base + bank->regs->leveldetect0);
+       bank->context.leveldetect1 =
+                       __raw_readl(bank->base + bank->regs->leveldetect1);
+       bank->context.risingdetect =
+                       __raw_readl(bank->base + bank->regs->risingdetect);
+       bank->context.fallingdetect =
+                       __raw_readl(bank->base + bank->regs->fallingdetect);
+
        if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
-               if (cpu_is_omap44xx()) {
-                       _gpio_rmw(base, OMAP4_GPIO_IRQWAKEN0, gpio_bit,
-                                 trigger != 0);
-               } else {
-                       /*
-                        * GPIO wakeup request can only be generated on edge
-                        * transitions
-                        */
-                       if (trigger & IRQ_TYPE_EDGE_BOTH)
-                               __raw_writel(1 << gpio, bank->base
-                                       + OMAP24XX_GPIO_SETWKUENA);
-                       else
-                               __raw_writel(1 << gpio, bank->base
-                                       + OMAP24XX_GPIO_CLEARWKUENA);
-               }
+               _gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0);
+               bank->context.wake_en =
+                       __raw_readl(bank->base + bank->regs->wkup_en);
        }
+
        /* This part needs to be executed always for OMAP{34xx, 44xx} */
-       if (cpu_is_omap34xx() || cpu_is_omap44xx() ||
-                       (bank->non_wakeup_gpios & gpio_bit)) {
+       if (!bank->regs->irqctrl) {
+               /* On omap24xx proceed only when valid GPIO bit is set */
+               if (bank->non_wakeup_gpios) {
+                       if (!(bank->non_wakeup_gpios & gpio_bit))
+                               goto exit;
+               }
+
                /*
                 * Log the edge gpio and manually trigger the IRQ
                 * after resume if the input level changes
@@ -264,17 +287,11 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
                        bank->enabled_non_wakeup_gpios &= ~gpio_bit;
        }
 
-       if (cpu_is_omap44xx()) {
-               bank->level_mask =
-                       __raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT0) |
-                       __raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT1);
-       } else {
-               bank->level_mask =
-                       __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0) |
-                       __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
-       }
+exit:
+       bank->level_mask =
+               __raw_readl(bank->base + bank->regs->leveldetect0) |
+               __raw_readl(bank->base + bank->regs->leveldetect1);
 }
-#endif
 
 #ifdef CONFIG_ARCH_OMAP1
 /*
@@ -286,23 +303,10 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
        void __iomem *reg = bank->base;
        u32 l = 0;
 
-       switch (bank->method) {
-       case METHOD_MPUIO:
-               reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;
-               break;
-#ifdef CONFIG_ARCH_OMAP15XX
-       case METHOD_GPIO_1510:
-               reg += OMAP1510_GPIO_INT_CONTROL;
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-       case METHOD_GPIO_7XX:
-               reg += OMAP7XX_GPIO_INT_CONTROL;
-               break;
-#endif
-       default:
+       if (!bank->regs->irqctrl)
                return;
-       }
+
+       reg += bank->regs->irqctrl;
 
        l = __raw_readl(reg);
        if ((l >> gpio) & 1)
@@ -312,31 +316,21 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
 
        __raw_writel(l, reg);
 }
+#else
+static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) {}
 #endif
 
 static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
 {
        void __iomem *reg = bank->base;
+       void __iomem *base = bank->base;
        u32 l = 0;
 
-       switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-       case METHOD_MPUIO:
-               reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;
-               l = __raw_readl(reg);
-               if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
-                       bank->toggle_mask |= 1 << gpio;
-               if (trigger & IRQ_TYPE_EDGE_RISING)
-                       l |= 1 << gpio;
-               else if (trigger & IRQ_TYPE_EDGE_FALLING)
-                       l &= ~(1 << gpio);
-               else
-                       goto bad;
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-       case METHOD_GPIO_1510:
-               reg += OMAP1510_GPIO_INT_CONTROL;
+       if (bank->regs->leveldetect0 && bank->regs->wkup_en) {
+               set_gpio_trigger(bank, gpio, trigger);
+       } else if (bank->regs->irqctrl) {
+               reg += bank->regs->irqctrl;
+
                l = __raw_readl(reg);
                if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
                        bank->toggle_mask |= 1 << gpio;
@@ -345,15 +339,15 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
                else if (trigger & IRQ_TYPE_EDGE_FALLING)
                        l &= ~(1 << gpio);
                else
-                       goto bad;
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-       case METHOD_GPIO_1610:
+                       return -EINVAL;
+
+               __raw_writel(l, reg);
+       } else if (bank->regs->edgectrl1) {
                if (gpio & 0x08)
-                       reg += OMAP1610_GPIO_EDGE_CTRL2;
+                       reg += bank->regs->edgectrl2;
                else
-                       reg += OMAP1610_GPIO_EDGE_CTRL1;
+                       reg += bank->regs->edgectrl1;
+
                gpio &= 0x07;
                l = __raw_readl(reg);
                l &= ~(3 << (gpio << 1));
@@ -361,40 +355,14 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
                        l |= 2 << (gpio << 1);
                if (trigger & IRQ_TYPE_EDGE_FALLING)
                        l |= 1 << (gpio << 1);
-               if (trigger)
-                       /* Enable wake-up during idle for dynamic tick */
-                       __raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_SET_WAKEUPENA);
-               else
-                       __raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA);
-               break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-       case METHOD_GPIO_7XX:
-               reg += OMAP7XX_GPIO_INT_CONTROL;
-               l = __raw_readl(reg);
-               if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
-                       bank->toggle_mask |= 1 << gpio;
-               if (trigger & IRQ_TYPE_EDGE_RISING)
-                       l |= 1 << gpio;
-               else if (trigger & IRQ_TYPE_EDGE_FALLING)
-                       l &= ~(1 << gpio);
-               else
-                       goto bad;
-               break;
-#endif
-#ifdef CONFIG_ARCH_OMAP2PLUS
-       case METHOD_GPIO_24XX:
-       case METHOD_GPIO_44XX:
-               set_24xx_gpio_triggering(bank, gpio, trigger);
-               return 0;
-#endif
-       default:
-               goto bad;
+
+               /* Enable wake-up during idle for dynamic tick */
+               _gpio_rmw(base, bank->regs->wkup_en, 1 << gpio, trigger);
+               bank->context.wake_en =
+                       __raw_readl(bank->base + bank->regs->wkup_en);
+               __raw_writel(l, reg);
        }
-       __raw_writel(l, reg);
        return 0;
-bad:
-       return -EINVAL;
 }
 
 static int gpio_irq_type(struct irq_data *d, unsigned type)
@@ -412,12 +380,12 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
        if (type & ~IRQ_TYPE_SENSE_MASK)
                return -EINVAL;
 
-       /* OMAP1 allows only only edge triggering */
-       if (!cpu_class_is_omap2()
-                       && (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
+       bank = irq_data_get_irq_chip_data(d);
+
+       if (!bank->regs->leveldetect0 &&
+               (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
                return -EINVAL;
 
-       bank = irq_data_get_irq_chip_data(d);
        spin_lock_irqsave(&bank->lock, flags);
        retval = _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), type);
        spin_unlock_irqrestore(&bank->lock, flags);
@@ -484,6 +452,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
        }
 
        __raw_writel(l, reg);
+       bank->context.irqenable1 = l;
 }
 
 static void _disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
@@ -504,6 +473,7 @@ static void _disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
        }
 
        __raw_writel(l, reg);
+       bank->context.irqenable1 = l;
 }
 
 static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable)
@@ -567,38 +537,39 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
        struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
        unsigned long flags;
 
-       spin_lock_irqsave(&bank->lock, flags);
+       /*
+        * If this is the first gpio_request for the bank,
+        * enable the bank module.
+        */
+       if (!bank->mod_usage)
+               pm_runtime_get_sync(bank->dev);
 
+       spin_lock_irqsave(&bank->lock, flags);
        /* Set trigger to none. You need to enable the desired trigger with
         * request_irq() or set_irq_type().
         */
        _set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
 
-#ifdef CONFIG_ARCH_OMAP15XX
-       if (bank->method == METHOD_GPIO_1510) {
-               void __iomem *reg;
+       if (bank->regs->pinctrl) {
+               void __iomem *reg = bank->base + bank->regs->pinctrl;
 
                /* Claim the pin for MPU */
-               reg = bank->base + OMAP1510_GPIO_PIN_CONTROL;
                __raw_writel(__raw_readl(reg) | (1 << offset), reg);
        }
-#endif
-       if (!cpu_class_is_omap1()) {
-               if (!bank->mod_usage) {
-                       void __iomem *reg = bank->base;
-                       u32 ctrl;
-
-                       if (cpu_is_omap24xx() || cpu_is_omap34xx())
-                               reg += OMAP24XX_GPIO_CTRL;
-                       else if (cpu_is_omap44xx())
-                               reg += OMAP4_GPIO_CTRL;
-                       ctrl = __raw_readl(reg);
-                       /* Module is enabled, clocks are not gated */
-                       ctrl &= 0xFFFFFFFE;
-                       __raw_writel(ctrl, reg);
-               }
-               bank->mod_usage |= 1 << offset;
+
+       if (bank->regs->ctrl && !bank->mod_usage) {
+               void __iomem *reg = bank->base + bank->regs->ctrl;
+               u32 ctrl;
+
+               ctrl = __raw_readl(reg);
+               /* Module is enabled, clocks are not gated */
+               ctrl &= ~GPIO_MOD_CTRL_BIT;
+               __raw_writel(ctrl, reg);
+               bank->context.ctrl = ctrl;
        }
+
+       bank->mod_usage |= 1 << offset;
+
        spin_unlock_irqrestore(&bank->lock, flags);
 
        return 0;
@@ -607,48 +578,40 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
 static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
 {
        struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
+       void __iomem *base = bank->base;
        unsigned long flags;
 
        spin_lock_irqsave(&bank->lock, flags);
-#ifdef CONFIG_ARCH_OMAP16XX
-       if (bank->method == METHOD_GPIO_1610) {
-               /* Disable wake-up during idle for dynamic tick */
-               void __iomem *reg = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
-               __raw_writel(1 << offset, reg);
-       }
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-       if (bank->method == METHOD_GPIO_24XX) {
-               /* Disable wake-up during idle for dynamic tick */
-               void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
-               __raw_writel(1 << offset, reg);
-       }
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-       if (bank->method == METHOD_GPIO_44XX) {
+
+       if (bank->regs->wkup_en) {
                /* Disable wake-up during idle for dynamic tick */
-               void __iomem *reg = bank->base + OMAP4_GPIO_IRQWAKEN0;
-               __raw_writel(1 << offset, reg);
+               _gpio_rmw(base, bank->regs->wkup_en, 1 << offset, 0);
+               bank->context.wake_en =
+                       __raw_readl(bank->base + bank->regs->wkup_en);
        }
-#endif
-       if (!cpu_class_is_omap1()) {
-               bank->mod_usage &= ~(1 << offset);
-               if (!bank->mod_usage) {
-                       void __iomem *reg = bank->base;
-                       u32 ctrl;
-
-                       if (cpu_is_omap24xx() || cpu_is_omap34xx())
-                               reg += OMAP24XX_GPIO_CTRL;
-                       else if (cpu_is_omap44xx())
-                               reg += OMAP4_GPIO_CTRL;
-                       ctrl = __raw_readl(reg);
-                       /* Module is disabled, clocks are gated */
-                       ctrl |= 1;
-                       __raw_writel(ctrl, reg);
-               }
+
+       bank->mod_usage &= ~(1 << offset);
+
+       if (bank->regs->ctrl && !bank->mod_usage) {
+               void __iomem *reg = bank->base + bank->regs->ctrl;
+               u32 ctrl;
+
+               ctrl = __raw_readl(reg);
+               /* Module is disabled, clocks are gated */
+               ctrl |= GPIO_MOD_CTRL_BIT;
+               __raw_writel(ctrl, reg);
+               bank->context.ctrl = ctrl;
        }
+
        _reset_gpio(bank, bank->chip.base + offset);
        spin_unlock_irqrestore(&bank->lock, flags);
+
+       /*
+        * If this is the last gpio to be freed in the bank,
+        * disable the bank module.
+        */
+       if (!bank->mod_usage)
+               pm_runtime_put(bank->dev);
 }
 
 /*
@@ -674,6 +637,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 
        bank = irq_get_handler_data(irq);
        isr_reg = bank->base + bank->regs->irqstatus;
+       pm_runtime_get_sync(bank->dev);
 
        if (WARN_ON(!isr_reg))
                goto exit;
@@ -685,12 +649,8 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
                enabled = _get_gpio_irqbank_mask(bank);
                isr_saved = isr = __raw_readl(isr_reg) & enabled;
 
-               if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
-                       isr &= 0x0000ffff;
-
-               if (cpu_class_is_omap2()) {
+               if (bank->level_mask)
                        level_mask = bank->level_mask & enabled;
-               }
 
                /* clear edge sensitive interrupts before handler(s) are
                called so that we don't miss any interrupt occurred while
@@ -718,7 +678,6 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
                        if (!(isr & 1))
                                continue;
 
-#ifdef CONFIG_ARCH_OMAP1
                        /*
                         * Some chips can't respond to both rising and falling
                         * at the same time.  If this irq was requested with
@@ -728,7 +687,6 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
                         */
                        if (bank->toggle_mask & (1 << gpio_index))
                                _toggle_gpio_edge_triggering(bank, gpio_index);
-#endif
 
                        generic_handle_irq(gpio_irq);
                }
@@ -740,6 +698,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 exit:
        if (!unmasked)
                chained_irq_exit(chip, desc);
+       pm_runtime_put(bank->dev);
 }
 
 static void gpio_irq_shutdown(struct irq_data *d)
@@ -808,14 +767,6 @@ static struct irq_chip gpio_irq_chip = {
 
 /*---------------------------------------------------------------------*/
 
-#ifdef CONFIG_ARCH_OMAP1
-
-#define bank_is_mpuio(bank)    ((bank)->method == METHOD_MPUIO)
-
-#ifdef CONFIG_ARCH_OMAP16XX
-
-#include <linux/platform_device.h>
-
 static int omap_mpuio_suspend_noirq(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
@@ -869,32 +820,16 @@ static struct platform_device omap_mpuio_device = {
        /* could list the /proc/iomem resources */
 };
 
-static inline void mpuio_init(void)
+static inline void mpuio_init(struct gpio_bank *bank)
 {
-       struct gpio_bank *bank = &gpio_bank[0];
        platform_set_drvdata(&omap_mpuio_device, bank);
 
        if (platform_driver_register(&omap_mpuio_driver) == 0)
                (void) platform_device_register(&omap_mpuio_device);
 }
 
-#else
-static inline void mpuio_init(void) {}
-#endif /* 16xx */
-
-#else
-
-#define bank_is_mpuio(bank)    0
-static inline void mpuio_init(void) {}
-
-#endif
-
 /*---------------------------------------------------------------------*/
 
-/* REVISIT these are stupid implementations!  replace by ones that
- * don't switch on METHOD_* and which mostly avoid spinlocks
- */
-
 static int gpio_input(struct gpio_chip *chip, unsigned offset)
 {
        struct gpio_bank *bank;
@@ -1007,78 +942,32 @@ static void __init omap_gpio_show_rev(struct gpio_bank *bank)
  */
 static struct lock_class_key gpio_lock_class;
 
-static inline int init_gpio_info(struct platform_device *pdev)
+static void omap_gpio_mod_init(struct gpio_bank *bank)
 {
-       /* TODO: Analyze removing gpio_bank_count usage from driver code */
-       gpio_bank = kzalloc(gpio_bank_count * sizeof(struct gpio_bank),
-                               GFP_KERNEL);
-       if (!gpio_bank) {
-               dev_err(&pdev->dev, "Memory alloc failed for gpio_bank\n");
-               return -ENOMEM;
-       }
-       return 0;
-}
+       void __iomem *base = bank->base;
+       u32 l = 0xffffffff;
 
-/* TODO: Cleanup cpu_is_* checks */
-static void omap_gpio_mod_init(struct gpio_bank *bank, int id)
-{
-       if (cpu_class_is_omap2()) {
-               if (cpu_is_omap44xx()) {
-                       __raw_writel(0xffffffff, bank->base +
-                                       OMAP4_GPIO_IRQSTATUSCLR0);
-                       __raw_writel(0x00000000, bank->base +
-                                        OMAP4_GPIO_DEBOUNCENABLE);
-                       /* Initialize interface clk ungated, module enabled */
-                       __raw_writel(0, bank->base + OMAP4_GPIO_CTRL);
-               } else if (cpu_is_omap34xx()) {
-                       __raw_writel(0x00000000, bank->base +
-                                       OMAP24XX_GPIO_IRQENABLE1);
-                       __raw_writel(0xffffffff, bank->base +
-                                       OMAP24XX_GPIO_IRQSTATUS1);
-                       __raw_writel(0x00000000, bank->base +
-                                       OMAP24XX_GPIO_DEBOUNCE_EN);
-
-                       /* Initialize interface clk ungated, module enabled */
-                       __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL);
-               } else if (cpu_is_omap24xx()) {
-                       static const u32 non_wakeup_gpios[] = {
-                               0xe203ffc0, 0x08700040
-                       };
-                       if (id < ARRAY_SIZE(non_wakeup_gpios))
-                               bank->non_wakeup_gpios = non_wakeup_gpios[id];
-               }
-       } else if (cpu_class_is_omap1()) {
-               if (bank_is_mpuio(bank))
-                       __raw_writew(0xffff, bank->base +
-                               OMAP_MPUIO_GPIO_MASKIT / bank->stride);
-               if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) {
-                       __raw_writew(0xffff, bank->base
-                                               + OMAP1510_GPIO_INT_MASK);
-                       __raw_writew(0x0000, bank->base
-                                               + OMAP1510_GPIO_INT_STATUS);
-               }
-               if (cpu_is_omap16xx() && bank->method == METHOD_GPIO_1610) {
-                       __raw_writew(0x0000, bank->base
-                                               + OMAP1610_GPIO_IRQENABLE1);
-                       __raw_writew(0xffff, bank->base
-                                               + OMAP1610_GPIO_IRQSTATUS1);
-                       __raw_writew(0x0014, bank->base
-                                               + OMAP1610_GPIO_SYSCONFIG);
+       if (bank->width == 16)
+               l = 0xffff;
 
-                       /*
-                        * Enable system clock for GPIO module.
-                        * The CAM_CLK_CTRL *is* really the right place.
-                        */
-                       omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04,
-                                               ULPD_CAM_CLK_CTRL);
-               }
-               if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX) {
-                       __raw_writel(0xffffffff, bank->base
-                                               + OMAP7XX_GPIO_INT_MASK);
-                       __raw_writel(0x00000000, bank->base
-                                               + OMAP7XX_GPIO_INT_STATUS);
-               }
+       if (bank->is_mpuio) {
+               __raw_writel(l, bank->base + bank->regs->irqenable);
+               return;
        }
+
+       _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->irqenable_inv);
+       _gpio_rmw(base, bank->regs->irqstatus, l,
+                                       bank->regs->irqenable_inv == false);
+       _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->debounce_en != 0);
+       _gpio_rmw(base, bank->regs->irqenable, l, bank->regs->ctrl != 0);
+       if (bank->regs->debounce_en)
+               _gpio_rmw(base, bank->regs->debounce_en, 0, 1);
+
+       /* Save OE default value (0xffffffff) in the context */
+       bank->context.oe = __raw_readl(bank->base + bank->regs->direction);
+        /* Initialize interface clk ungated, module enabled */
+       if (bank->regs->ctrl)
+               _gpio_rmw(base, bank->regs->ctrl, 0, 1);
 }
 
 static __init void
@@ -1101,8 +990,8 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start,
        ct->chip.irq_mask = irq_gc_mask_set_bit;
        ct->chip.irq_unmask = irq_gc_mask_clr_bit;
        ct->chip.irq_set_type = gpio_irq_type;
-       /* REVISIT: assuming only 16xx supports MPUIO wake events */
-       if (cpu_is_omap16xx())
+
+       if (bank->regs->wkup_en)
                ct->chip.irq_set_wake = gpio_wake_enable,
 
        ct->regs.mask = OMAP_MPUIO_GPIO_INT / bank->stride;
@@ -1115,7 +1004,6 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank)
        int j;
        static int gpio;
 
-       bank->mod_usage = 0;
        /*
         * REVISIT eventually switch from OMAP-specific gpio structs
         * over to the generic ones
@@ -1128,11 +1016,10 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank)
        bank->chip.set_debounce = gpio_debounce;
        bank->chip.set = gpio_set;
        bank->chip.to_irq = gpio_2irq;
-       if (bank_is_mpuio(bank)) {
+       if (bank->is_mpuio) {
                bank->chip.label = "mpuio";
-#ifdef CONFIG_ARCH_OMAP16XX
-               bank->chip.dev = &omap_mpuio_device.dev;
-#endif
+               if (bank->regs->wkup_en)
+                       bank->chip.dev = &omap_mpuio_device.dev;
                bank->chip.base = OMAP_MPUIO(0);
        } else {
                bank->chip.label = "gpio";
@@ -1147,7 +1034,7 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank)
                     j < bank->virtual_irq_start + bank->width; j++) {
                irq_set_lockdep_class(j, &gpio_lock_class);
                irq_set_chip_data(j, bank);
-               if (bank_is_mpuio(bank)) {
+               if (bank->is_mpuio) {
                        omap_mpuio_alloc_gc(bank, j, bank->width);
                } else {
                        irq_set_chip(j, &gpio_irq_chip);
@@ -1161,42 +1048,44 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank)
 
 static int __devinit omap_gpio_probe(struct platform_device *pdev)
 {
-       static int gpio_init_done;
        struct omap_gpio_platform_data *pdata;
        struct resource *res;
-       int id;
        struct gpio_bank *bank;
+       int ret = 0;
 
-       if (!pdev->dev.platform_data)
-               return -EINVAL;
-
-       pdata = pdev->dev.platform_data;
-
-       if (!gpio_init_done) {
-               int ret;
-
-               ret = init_gpio_info(pdev);
-               if (ret)
-                       return ret;
+       if (!pdev->dev.platform_data) {
+               ret = -EINVAL;
+               goto err_exit;
        }
 
-       id = pdev->id;
-       bank = &gpio_bank[id];
+       bank = kzalloc(sizeof(struct gpio_bank), GFP_KERNEL);
+       if (!bank) {
+               dev_err(&pdev->dev, "Memory alloc failed for gpio_bank\n");
+               ret = -ENOMEM;
+               goto err_exit;
+       }
 
        res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        if (unlikely(!res)) {
-               dev_err(&pdev->dev, "GPIO Bank %i Invalid IRQ resource\n", id);
-               return -ENODEV;
+               dev_err(&pdev->dev, "GPIO Bank %i Invalid IRQ resource\n",
+                               pdev->id);
+               ret = -ENODEV;
+               goto err_free;
        }
 
        bank->irq = res->start;
+       bank->id = pdev->id;
+
+       pdata = pdev->dev.platform_data;
        bank->virtual_irq_start = pdata->virtual_irq_start;
-       bank->method = pdata->bank_type;
        bank->dev = &pdev->dev;
        bank->dbck_flag = pdata->dbck_flag;
        bank->stride = pdata->bank_stride;
        bank->width = pdata->bank_width;
-
+       bank->is_mpuio = pdata->is_mpuio;
+       bank->non_wakeup_gpios = pdata->non_wakeup_gpios;
+       bank->loses_context = pdata->loses_context;
+       bank->get_context_loss_count = pdata->get_context_loss_count;
        bank->regs = pdata->regs;
 
        if (bank->regs->set_dataout && bank->regs->clr_dataout)
@@ -1209,369 +1098,310 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
        /* Static mapping, never released */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (unlikely(!res)) {
-               dev_err(&pdev->dev, "GPIO Bank %i Invalid mem resource\n", id);
-               return -ENODEV;
+               dev_err(&pdev->dev, "GPIO Bank %i Invalid mem resource\n",
+                               pdev->id);
+               ret = -ENODEV;
+               goto err_free;
        }
 
        bank->base = ioremap(res->start, resource_size(res));
        if (!bank->base) {
-               dev_err(&pdev->dev, "Could not ioremap gpio bank%i\n", id);
-               return -ENOMEM;
+               dev_err(&pdev->dev, "Could not ioremap gpio bank%i\n",
+                               pdev->id);
+               ret = -ENOMEM;
+               goto err_free;
        }
 
+       platform_set_drvdata(pdev, bank);
+
        pm_runtime_enable(bank->dev);
+       pm_runtime_irq_safe(bank->dev);
        pm_runtime_get_sync(bank->dev);
 
-       omap_gpio_mod_init(bank, id);
+       if (bank->is_mpuio)
+               mpuio_init(bank);
+
+       omap_gpio_mod_init(bank);
        omap_gpio_chip_init(bank);
        omap_gpio_show_rev(bank);
 
-       if (!gpio_init_done)
-               gpio_init_done = 1;
+       pm_runtime_put(bank->dev);
 
-       return 0;
+       list_add_tail(&bank->node, &omap_gpio_list);
+
+       return ret;
+
+err_free:
+       kfree(bank);
+err_exit:
+       return ret;
 }
 
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
-static int omap_gpio_suspend(void)
+#ifdef CONFIG_ARCH_OMAP2PLUS
+
+#if defined(CONFIG_PM_SLEEP)
+static int omap_gpio_suspend(struct device *dev)
 {
-       int i;
+       struct platform_device *pdev = to_platform_device(dev);
+       struct gpio_bank *bank = platform_get_drvdata(pdev);
+       void __iomem *base = bank->base;
+       void __iomem *wakeup_enable;
+       unsigned long flags;
 
-       if (!cpu_class_is_omap2() && !cpu_is_omap16xx())
+       if (!bank->mod_usage || !bank->loses_context)
                return 0;
 
-       for (i = 0; i < gpio_bank_count; i++) {
-               struct gpio_bank *bank = &gpio_bank[i];
-               void __iomem *wake_status;
-               void __iomem *wake_clear;
-               void __iomem *wake_set;
-               unsigned long flags;
-
-               switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP16XX
-               case METHOD_GPIO_1610:
-                       wake_status = bank->base + OMAP1610_GPIO_WAKEUPENABLE;
-                       wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
-                       wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
-                       break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-               case METHOD_GPIO_24XX:
-                       wake_status = bank->base + OMAP24XX_GPIO_WAKE_EN;
-                       wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
-                       wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
-                       break;
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-               case METHOD_GPIO_44XX:
-                       wake_status = bank->base + OMAP4_GPIO_IRQWAKEN0;
-                       wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0;
-                       wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0;
-                       break;
-#endif
-               default:
-                       continue;
-               }
+       if (!bank->regs->wkup_en || !bank->suspend_wakeup)
+               return 0;
 
-               spin_lock_irqsave(&bank->lock, flags);
-               bank->saved_wakeup = __raw_readl(wake_status);
-               __raw_writel(0xffffffff, wake_clear);
-               __raw_writel(bank->suspend_wakeup, wake_set);
-               spin_unlock_irqrestore(&bank->lock, flags);
-       }
+       wakeup_enable = bank->base + bank->regs->wkup_en;
+
+       spin_lock_irqsave(&bank->lock, flags);
+       bank->saved_wakeup = __raw_readl(wakeup_enable);
+       _gpio_rmw(base, bank->regs->wkup_en, 0xffffffff, 0);
+       _gpio_rmw(base, bank->regs->wkup_en, bank->suspend_wakeup, 1);
+       spin_unlock_irqrestore(&bank->lock, flags);
 
        return 0;
 }
 
-static void omap_gpio_resume(void)
+static int omap_gpio_resume(struct device *dev)
 {
-       int i;
+       struct platform_device *pdev = to_platform_device(dev);
+       struct gpio_bank *bank = platform_get_drvdata(pdev);
+       void __iomem *base = bank->base;
+       unsigned long flags;
 
-       if (!cpu_class_is_omap2() && !cpu_is_omap16xx())
-               return;
+       if (!bank->mod_usage || !bank->loses_context)
+               return 0;
 
-       for (i = 0; i < gpio_bank_count; i++) {
-               struct gpio_bank *bank = &gpio_bank[i];
-               void __iomem *wake_clear;
-               void __iomem *wake_set;
-               unsigned long flags;
-
-               switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP16XX
-               case METHOD_GPIO_1610:
-                       wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
-                       wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
-                       break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-               case METHOD_GPIO_24XX:
-                       wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
-                       wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
-                       break;
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-               case METHOD_GPIO_44XX:
-                       wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0;
-                       wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0;
-                       break;
-#endif
-               default:
-                       continue;
-               }
+       if (!bank->regs->wkup_en || !bank->saved_wakeup)
+               return 0;
 
-               spin_lock_irqsave(&bank->lock, flags);
-               __raw_writel(0xffffffff, wake_clear);
-               __raw_writel(bank->saved_wakeup, wake_set);
-               spin_unlock_irqrestore(&bank->lock, flags);
-       }
-}
+       spin_lock_irqsave(&bank->lock, flags);
+       _gpio_rmw(base, bank->regs->wkup_en, 0xffffffff, 0);
+       _gpio_rmw(base, bank->regs->wkup_en, bank->saved_wakeup, 1);
+       spin_unlock_irqrestore(&bank->lock, flags);
 
-static struct syscore_ops omap_gpio_syscore_ops = {
-       .suspend        = omap_gpio_suspend,
-       .resume         = omap_gpio_resume,
-};
+       return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
 
-#endif
+#if defined(CONFIG_PM_RUNTIME)
+static void omap_gpio_restore_context(struct gpio_bank *bank);
 
-#ifdef CONFIG_ARCH_OMAP2PLUS
+static int omap_gpio_runtime_suspend(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct gpio_bank *bank = platform_get_drvdata(pdev);
+       u32 l1 = 0, l2 = 0;
+       unsigned long flags;
 
-static int workaround_enabled;
+       spin_lock_irqsave(&bank->lock, flags);
+       if (bank->power_mode != OFF_MODE) {
+               bank->power_mode = 0;
+               goto update_gpio_context_count;
+       }
+       /*
+        * If going to OFF, remove triggering for all
+        * non-wakeup GPIOs.  Otherwise spurious IRQs will be
+        * generated.  See OMAP2420 Errata item 1.101.
+        */
+       if (!(bank->enabled_non_wakeup_gpios))
+               goto update_gpio_context_count;
 
-void omap2_gpio_prepare_for_idle(int off_mode)
-{
-       int i, c = 0;
-       int min = 0;
+       bank->saved_datain = __raw_readl(bank->base +
+                                               bank->regs->datain);
+       l1 = __raw_readl(bank->base + bank->regs->fallingdetect);
+       l2 = __raw_readl(bank->base + bank->regs->risingdetect);
 
-       if (cpu_is_omap34xx())
-               min = 1;
+       bank->saved_fallingdetect = l1;
+       bank->saved_risingdetect = l2;
+       l1 &= ~bank->enabled_non_wakeup_gpios;
+       l2 &= ~bank->enabled_non_wakeup_gpios;
 
-       for (i = min; i < gpio_bank_count; i++) {
-               struct gpio_bank *bank = &gpio_bank[i];
-               u32 l1 = 0, l2 = 0;
-               int j;
+       __raw_writel(l1, bank->base + bank->regs->fallingdetect);
+       __raw_writel(l2, bank->base + bank->regs->risingdetect);
 
-               for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
-                       clk_disable(bank->dbck);
+       bank->workaround_enabled = true;
 
-               if (!off_mode)
-                       continue;
+update_gpio_context_count:
+       if (bank->get_context_loss_count)
+               bank->context_loss_count =
+                               bank->get_context_loss_count(bank->dev);
 
-               /* If going to OFF, remove triggering for all
-                * non-wakeup GPIOs.  Otherwise spurious IRQs will be
-                * generated.  See OMAP2420 Errata item 1.101. */
-               if (!(bank->enabled_non_wakeup_gpios))
-                       continue;
+       _gpio_dbck_disable(bank);
+       spin_unlock_irqrestore(&bank->lock, flags);
 
-               if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-                       bank->saved_datain = __raw_readl(bank->base +
-                                       OMAP24XX_GPIO_DATAIN);
-                       l1 = __raw_readl(bank->base +
-                                       OMAP24XX_GPIO_FALLINGDETECT);
-                       l2 = __raw_readl(bank->base +
-                                       OMAP24XX_GPIO_RISINGDETECT);
-               }
+       return 0;
+}
 
-               if (cpu_is_omap44xx()) {
-                       bank->saved_datain = __raw_readl(bank->base +
-                                               OMAP4_GPIO_DATAIN);
-                       l1 = __raw_readl(bank->base +
-                                               OMAP4_GPIO_FALLINGDETECT);
-                       l2 = __raw_readl(bank->base +
-                                               OMAP4_GPIO_RISINGDETECT);
-               }
+static int omap_gpio_runtime_resume(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct gpio_bank *bank = platform_get_drvdata(pdev);
+       int context_lost_cnt_after;
+       u32 l = 0, gen, gen0, gen1;
+       unsigned long flags;
 
-               bank->saved_fallingdetect = l1;
-               bank->saved_risingdetect = l2;
-               l1 &= ~bank->enabled_non_wakeup_gpios;
-               l2 &= ~bank->enabled_non_wakeup_gpios;
+       spin_lock_irqsave(&bank->lock, flags);
+       _gpio_dbck_enable(bank);
+       if (!bank->enabled_non_wakeup_gpios || !bank->workaround_enabled) {
+               spin_unlock_irqrestore(&bank->lock, flags);
+               return 0;
+       }
 
-               if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-                       __raw_writel(l1, bank->base +
-                                       OMAP24XX_GPIO_FALLINGDETECT);
-                       __raw_writel(l2, bank->base +
-                                       OMAP24XX_GPIO_RISINGDETECT);
+       if (bank->get_context_loss_count) {
+               context_lost_cnt_after =
+                       bank->get_context_loss_count(bank->dev);
+               if (context_lost_cnt_after != bank->context_loss_count ||
+                                               !context_lost_cnt_after) {
+                       omap_gpio_restore_context(bank);
+               } else {
+                       spin_unlock_irqrestore(&bank->lock, flags);
+                       return 0;
                }
+       }
 
-               if (cpu_is_omap44xx()) {
-                       __raw_writel(l1, bank->base + OMAP4_GPIO_FALLINGDETECT);
-                       __raw_writel(l2, bank->base + OMAP4_GPIO_RISINGDETECT);
-               }
+       __raw_writel(bank->saved_fallingdetect,
+                       bank->base + bank->regs->fallingdetect);
+       __raw_writel(bank->saved_risingdetect,
+                       bank->base + bank->regs->risingdetect);
+       l = __raw_readl(bank->base + bank->regs->datain);
 
-               c++;
-       }
-       if (!c) {
-               workaround_enabled = 0;
-               return;
-       }
-       workaround_enabled = 1;
-}
+       /*
+        * Check if any of the non-wakeup interrupt GPIOs have changed
+        * state.  If so, generate an IRQ by software.  This is
+        * horribly racy, but it's the best we can do to work around
+        * this silicon bug.
+        */
+       l ^= bank->saved_datain;
+       l &= bank->enabled_non_wakeup_gpios;
 
-void omap2_gpio_resume_after_idle(void)
-{
-       int i;
-       int min = 0;
+       /*
+        * No need to generate IRQs for the rising edge for gpio IRQs
+        * configured with falling edge only; and vice versa.
+        */
+       gen0 = l & bank->saved_fallingdetect;
+       gen0 &= bank->saved_datain;
 
-       if (cpu_is_omap34xx())
-               min = 1;
-       for (i = min; i < gpio_bank_count; i++) {
-               struct gpio_bank *bank = &gpio_bank[i];
-               u32 l = 0, gen, gen0, gen1;
-               int j;
+       gen1 = l & bank->saved_risingdetect;
+       gen1 &= ~(bank->saved_datain);
 
-               for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
-                       clk_enable(bank->dbck);
+       /* FIXME: Consider GPIO IRQs with level detections properly! */
+       gen = l & (~(bank->saved_fallingdetect) & ~(bank->saved_risingdetect));
+       /* Consider all GPIO IRQs needed to be updated */
+       gen |= gen0 | gen1;
 
-               if (!workaround_enabled)
-                       continue;
+       if (gen) {
+               u32 old0, old1;
 
-               if (!(bank->enabled_non_wakeup_gpios))
-                       continue;
+               old0 = __raw_readl(bank->base + bank->regs->leveldetect0);
+               old1 = __raw_readl(bank->base + bank->regs->leveldetect1);
 
                if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-                       __raw_writel(bank->saved_fallingdetect,
-                                bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-                       __raw_writel(bank->saved_risingdetect,
-                                bank->base + OMAP24XX_GPIO_RISINGDETECT);
-                       l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
+                       __raw_writel(old0 | gen, bank->base +
+                                               bank->regs->leveldetect0);
+                       __raw_writel(old1 | gen, bank->base +
+                                               bank->regs->leveldetect1);
                }
 
                if (cpu_is_omap44xx()) {
-                       __raw_writel(bank->saved_fallingdetect,
-                                bank->base + OMAP4_GPIO_FALLINGDETECT);
-                       __raw_writel(bank->saved_risingdetect,
-                                bank->base + OMAP4_GPIO_RISINGDETECT);
-                       l = __raw_readl(bank->base + OMAP4_GPIO_DATAIN);
-               }
-
-               /* Check if any of the non-wakeup interrupt GPIOs have changed
-                * state.  If so, generate an IRQ by software.  This is
-                * horribly racy, but it's the best we can do to work around
-                * this silicon bug. */
-               l ^= bank->saved_datain;
-               l &= bank->enabled_non_wakeup_gpios;
-
-               /*
-                * No need to generate IRQs for the rising edge for gpio IRQs
-                * configured with falling edge only; and vice versa.
-                */
-               gen0 = l & bank->saved_fallingdetect;
-               gen0 &= bank->saved_datain;
-
-               gen1 = l & bank->saved_risingdetect;
-               gen1 &= ~(bank->saved_datain);
-
-               /* FIXME: Consider GPIO IRQs with level detections properly! */
-               gen = l & (~(bank->saved_fallingdetect) &
-                               ~(bank->saved_risingdetect));
-               /* Consider all GPIO IRQs needed to be updated */
-               gen |= gen0 | gen1;
-
-               if (gen) {
-                       u32 old0, old1;
-
-                       if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-                               old0 = __raw_readl(bank->base +
-                                       OMAP24XX_GPIO_LEVELDETECT0);
-                               old1 = __raw_readl(bank->base +
-                                       OMAP24XX_GPIO_LEVELDETECT1);
-                               __raw_writel(old0 | gen, bank->base +
-                                       OMAP24XX_GPIO_LEVELDETECT0);
-                               __raw_writel(old1 | gen, bank->base +
-                                       OMAP24XX_GPIO_LEVELDETECT1);
-                               __raw_writel(old0, bank->base +
-                                       OMAP24XX_GPIO_LEVELDETECT0);
-                               __raw_writel(old1, bank->base +
-                                       OMAP24XX_GPIO_LEVELDETECT1);
-                       }
-
-                       if (cpu_is_omap44xx()) {
-                               old0 = __raw_readl(bank->base +
-                                               OMAP4_GPIO_LEVELDETECT0);
-                               old1 = __raw_readl(bank->base +
-                                               OMAP4_GPIO_LEVELDETECT1);
-                               __raw_writel(old0 | l, bank->base +
-                                               OMAP4_GPIO_LEVELDETECT0);
-                               __raw_writel(old1 | l, bank->base +
-                                               OMAP4_GPIO_LEVELDETECT1);
-                               __raw_writel(old0, bank->base +
-                                               OMAP4_GPIO_LEVELDETECT0);
-                               __raw_writel(old1, bank->base +
-                                               OMAP4_GPIO_LEVELDETECT1);
-                       }
+                       __raw_writel(old0 | l, bank->base +
+                                               bank->regs->leveldetect0);
+                       __raw_writel(old1 | l, bank->base +
+                                               bank->regs->leveldetect1);
                }
+               __raw_writel(old0, bank->base + bank->regs->leveldetect0);
+               __raw_writel(old1, bank->base + bank->regs->leveldetect1);
        }
 
+       bank->workaround_enabled = false;
+       spin_unlock_irqrestore(&bank->lock, flags);
+
+       return 0;
 }
+#endif /* CONFIG_PM_RUNTIME */
 
-#endif
+void omap2_gpio_prepare_for_idle(int pwr_mode)
+{
+       struct gpio_bank *bank;
+
+       list_for_each_entry(bank, &omap_gpio_list, node) {
+               if (!bank->mod_usage || !bank->loses_context)
+                       continue;
+
+               bank->power_mode = pwr_mode;
+
+               pm_runtime_put_sync_suspend(bank->dev);
+       }
+}
 
-#ifdef CONFIG_ARCH_OMAP3
-/* save the registers of bank 2-6 */
-void omap_gpio_save_context(void)
+void omap2_gpio_resume_after_idle(void)
 {
-       int i;
-
-       /* saving banks from 2-6 only since GPIO1 is in WKUP */
-       for (i = 1; i < gpio_bank_count; i++) {
-               struct gpio_bank *bank = &gpio_bank[i];
-               gpio_context[i].irqenable1 =
-                       __raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
-               gpio_context[i].irqenable2 =
-                       __raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE2);
-               gpio_context[i].wake_en =
-                       __raw_readl(bank->base + OMAP24XX_GPIO_WAKE_EN);
-               gpio_context[i].ctrl =
-                       __raw_readl(bank->base + OMAP24XX_GPIO_CTRL);
-               gpio_context[i].oe =
-                       __raw_readl(bank->base + OMAP24XX_GPIO_OE);
-               gpio_context[i].leveldetect0 =
-                       __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
-               gpio_context[i].leveldetect1 =
-                       __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
-               gpio_context[i].risingdetect =
-                       __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
-               gpio_context[i].fallingdetect =
-                       __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-               gpio_context[i].dataout =
-                       __raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT);
+       struct gpio_bank *bank;
+
+       list_for_each_entry(bank, &omap_gpio_list, node) {
+               if (!bank->mod_usage || !bank->loses_context)
+                       continue;
+
+               pm_runtime_get_sync(bank->dev);
        }
 }
 
-/* restore the required registers of bank 2-6 */
-void omap_gpio_restore_context(void)
+#if defined(CONFIG_PM_RUNTIME)
+static void omap_gpio_restore_context(struct gpio_bank *bank)
 {
-       int i;
-
-       for (i = 1; i < gpio_bank_count; i++) {
-               struct gpio_bank *bank = &gpio_bank[i];
-               __raw_writel(gpio_context[i].irqenable1,
-                               bank->base + OMAP24XX_GPIO_IRQENABLE1);
-               __raw_writel(gpio_context[i].irqenable2,
-                               bank->base + OMAP24XX_GPIO_IRQENABLE2);
-               __raw_writel(gpio_context[i].wake_en,
-                               bank->base + OMAP24XX_GPIO_WAKE_EN);
-               __raw_writel(gpio_context[i].ctrl,
-                               bank->base + OMAP24XX_GPIO_CTRL);
-               __raw_writel(gpio_context[i].oe,
-                               bank->base + OMAP24XX_GPIO_OE);
-               __raw_writel(gpio_context[i].leveldetect0,
-                               bank->base + OMAP24XX_GPIO_LEVELDETECT0);
-               __raw_writel(gpio_context[i].leveldetect1,
-                               bank->base + OMAP24XX_GPIO_LEVELDETECT1);
-               __raw_writel(gpio_context[i].risingdetect,
-                               bank->base + OMAP24XX_GPIO_RISINGDETECT);
-               __raw_writel(gpio_context[i].fallingdetect,
-                               bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-               __raw_writel(gpio_context[i].dataout,
-                               bank->base + OMAP24XX_GPIO_DATAOUT);
+       __raw_writel(bank->context.wake_en,
+                               bank->base + bank->regs->wkup_en);
+       __raw_writel(bank->context.ctrl, bank->base + bank->regs->ctrl);
+       __raw_writel(bank->context.leveldetect0,
+                               bank->base + bank->regs->leveldetect0);
+       __raw_writel(bank->context.leveldetect1,
+                               bank->base + bank->regs->leveldetect1);
+       __raw_writel(bank->context.risingdetect,
+                               bank->base + bank->regs->risingdetect);
+       __raw_writel(bank->context.fallingdetect,
+                               bank->base + bank->regs->fallingdetect);
+       if (bank->regs->set_dataout && bank->regs->clr_dataout)
+               __raw_writel(bank->context.dataout,
+                               bank->base + bank->regs->set_dataout);
+       else
+               __raw_writel(bank->context.dataout,
+                               bank->base + bank->regs->dataout);
+       __raw_writel(bank->context.oe, bank->base + bank->regs->direction);
+
+       if (bank->dbck_enable_mask) {
+               __raw_writel(bank->context.debounce, bank->base +
+                                       bank->regs->debounce);
+               __raw_writel(bank->context.debounce_en,
+                                       bank->base + bank->regs->debounce_en);
        }
+
+       __raw_writel(bank->context.irqenable1,
+                               bank->base + bank->regs->irqenable);
+       __raw_writel(bank->context.irqenable2,
+                               bank->base + bank->regs->irqenable2);
 }
+#endif /* CONFIG_PM_RUNTIME */
+#else
+#define omap_gpio_suspend NULL
+#define omap_gpio_resume NULL
+#define omap_gpio_runtime_suspend NULL
+#define omap_gpio_runtime_resume NULL
 #endif
 
+static const struct dev_pm_ops gpio_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(omap_gpio_suspend, omap_gpio_resume)
+       SET_RUNTIME_PM_OPS(omap_gpio_runtime_suspend, omap_gpio_runtime_resume,
+                                                                       NULL)
+};
+
 static struct platform_driver omap_gpio_driver = {
        .probe          = omap_gpio_probe,
        .driver         = {
                .name   = "omap_gpio",
+               .pm     = &gpio_pm_ops,
        },
 };
 
@@ -1585,17 +1415,3 @@ static int __init omap_gpio_drv_reg(void)
        return platform_driver_register(&omap_gpio_driver);
 }
 postcore_initcall(omap_gpio_drv_reg);
-
-static int __init omap_gpio_sysinit(void)
-{
-       mpuio_init();
-
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
-       if (cpu_is_omap16xx() || cpu_class_is_omap2())
-               register_syscore_ops(&omap_gpio_syscore_ops);
-#endif
-
-       return 0;
-}
-
-arch_initcall(omap_gpio_sysinit);
index 7eecf69362ee9d2b96d02fabc0a04ce1bdc8c3c6..8ea3b33d4b40bb4b96ad7edd83f6dac7e219aa03 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 
 #include <mach/hardware.h>
+#include <mach/irqs.h>
 
 static int sa1100_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
index 0a79a1167a251dd71cd1c02dc82aedd1b1842213..46277877b7ecc1bea7448391d20a7a4f710c4577 100644 (file)
@@ -169,7 +169,7 @@ int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip,
        return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
 }
 
-static int exynos4_gpio_setpull(struct samsung_gpio_chip *chip,
+static int exynos_gpio_setpull(struct samsung_gpio_chip *chip,
                                unsigned int off, samsung_gpio_pull_t pull)
 {
        if (pull == S3C_GPIO_PULL_UP)
@@ -178,7 +178,7 @@ static int exynos4_gpio_setpull(struct samsung_gpio_chip *chip,
        return samsung_gpio_setpull_updown(chip, off, pull);
 }
 
-static samsung_gpio_pull_t exynos4_gpio_getpull(struct samsung_gpio_chip *chip,
+static samsung_gpio_pull_t exynos_gpio_getpull(struct samsung_gpio_chip *chip,
                                                unsigned int off)
 {
        samsung_gpio_pull_t pull;
@@ -452,9 +452,9 @@ static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = {
 };
 #endif
 
-static struct samsung_gpio_cfg exynos4_gpio_cfg = {
-       .set_pull       = exynos4_gpio_setpull,
-       .get_pull       = exynos4_gpio_getpull,
+static struct samsung_gpio_cfg exynos_gpio_cfg = {
+       .set_pull       = exynos_gpio_setpull,
+       .get_pull       = exynos_gpio_getpull,
        .set_config     = samsung_gpio_setcfg_4bit,
        .get_config     = samsung_gpio_getcfg_4bit,
 };
@@ -502,13 +502,13 @@ static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
                .get_config     = samsung_gpio_getcfg_2bit,
        },
        [8] = {
-               .set_pull       = exynos4_gpio_setpull,
-               .get_pull       = exynos4_gpio_getpull,
+               .set_pull       = exynos_gpio_setpull,
+               .get_pull       = exynos_gpio_getpull,
        },
        [9] = {
                .cfg_eint       = 0x3,
-               .set_pull       = exynos4_gpio_setpull,
-               .get_pull       = exynos4_gpio_getpull,
+               .set_pull       = exynos_gpio_setpull,
+               .get_pull       = exynos_gpio_getpull,
        }
 };
 
@@ -2113,10 +2113,10 @@ static struct samsung_gpio_chip s5pv210_gpios_4bit[] = {
 };
 
 /*
- * Followings are the gpio banks in EXYNOS4210
+ * Followings are the gpio banks in EXYNOS SoCs
  *
  * The 'config' member when left to NULL, is initialized to the default
- * structure samsung_gpio_cfgs[3] in the init function below.
+ * structure exynos_gpio_cfg in the init function below.
  *
  * The 'base' member is also initialized in the init function below.
  * Note: The initialization of 'base' member of samsung_gpio_chip structure
@@ -2331,7 +2331,6 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = {
                        .label  = "GPY6",
                },
        }, {
-               .base   = (S5P_VA_GPIO2 + 0xC00),
                .config = &samsung_gpio_cfgs[9],
                .irq_base = IRQ_EINT(0),
                .chip   = {
@@ -2341,7 +2340,6 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = {
                        .to_irq = samsung_gpiolib_to_irq,
                },
        }, {
-               .base   = (S5P_VA_GPIO2 + 0xC20),
                .config = &samsung_gpio_cfgs[9],
                .irq_base = IRQ_EINT(8),
                .chip   = {
@@ -2351,7 +2349,6 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = {
                        .to_irq = samsung_gpiolib_to_irq,
                },
        }, {
-               .base   = (S5P_VA_GPIO2 + 0xC40),
                .config = &samsung_gpio_cfgs[9],
                .irq_base = IRQ_EINT(16),
                .chip   = {
@@ -2361,7 +2358,6 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = {
                        .to_irq = samsung_gpiolib_to_irq,
                },
        }, {
-               .base   = (S5P_VA_GPIO2 + 0xC60),
                .config = &samsung_gpio_cfgs[9],
                .irq_base = IRQ_EINT(24),
                .chip   = {
@@ -2386,8 +2382,280 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = {
 #endif
 };
 
-#if defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF)
-static int exynos4_gpio_xlate(struct gpio_chip *gc,
+static struct samsung_gpio_chip exynos5_gpios_1[] = {
+#ifdef CONFIG_ARCH_EXYNOS5
+       {
+               .chip   = {
+                       .base   = EXYNOS5_GPA0(0),
+                       .ngpio  = EXYNOS5_GPIO_A0_NR,
+                       .label  = "GPA0",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPA1(0),
+                       .ngpio  = EXYNOS5_GPIO_A1_NR,
+                       .label  = "GPA1",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPA2(0),
+                       .ngpio  = EXYNOS5_GPIO_A2_NR,
+                       .label  = "GPA2",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPB0(0),
+                       .ngpio  = EXYNOS5_GPIO_B0_NR,
+                       .label  = "GPB0",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPB1(0),
+                       .ngpio  = EXYNOS5_GPIO_B1_NR,
+                       .label  = "GPB1",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPB2(0),
+                       .ngpio  = EXYNOS5_GPIO_B2_NR,
+                       .label  = "GPB2",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPB3(0),
+                       .ngpio  = EXYNOS5_GPIO_B3_NR,
+                       .label  = "GPB3",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPC0(0),
+                       .ngpio  = EXYNOS5_GPIO_C0_NR,
+                       .label  = "GPC0",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPC1(0),
+                       .ngpio  = EXYNOS5_GPIO_C1_NR,
+                       .label  = "GPC1",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPC2(0),
+                       .ngpio  = EXYNOS5_GPIO_C2_NR,
+                       .label  = "GPC2",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPC3(0),
+                       .ngpio  = EXYNOS5_GPIO_C3_NR,
+                       .label  = "GPC3",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPD0(0),
+                       .ngpio  = EXYNOS5_GPIO_D0_NR,
+                       .label  = "GPD0",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPD1(0),
+                       .ngpio  = EXYNOS5_GPIO_D1_NR,
+                       .label  = "GPD1",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPY0(0),
+                       .ngpio  = EXYNOS5_GPIO_Y0_NR,
+                       .label  = "GPY0",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPY1(0),
+                       .ngpio  = EXYNOS5_GPIO_Y1_NR,
+                       .label  = "GPY1",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPY2(0),
+                       .ngpio  = EXYNOS5_GPIO_Y2_NR,
+                       .label  = "GPY2",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPY3(0),
+                       .ngpio  = EXYNOS5_GPIO_Y3_NR,
+                       .label  = "GPY3",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPY4(0),
+                       .ngpio  = EXYNOS5_GPIO_Y4_NR,
+                       .label  = "GPY4",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPY5(0),
+                       .ngpio  = EXYNOS5_GPIO_Y5_NR,
+                       .label  = "GPY5",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPY6(0),
+                       .ngpio  = EXYNOS5_GPIO_Y6_NR,
+                       .label  = "GPY6",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[9],
+               .irq_base = IRQ_EINT(0),
+               .chip   = {
+                       .base   = EXYNOS5_GPX0(0),
+                       .ngpio  = EXYNOS5_GPIO_X0_NR,
+                       .label  = "GPX0",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[9],
+               .irq_base = IRQ_EINT(8),
+               .chip   = {
+                       .base   = EXYNOS5_GPX1(0),
+                       .ngpio  = EXYNOS5_GPIO_X1_NR,
+                       .label  = "GPX1",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[9],
+               .irq_base = IRQ_EINT(16),
+               .chip   = {
+                       .base   = EXYNOS5_GPX2(0),
+                       .ngpio  = EXYNOS5_GPIO_X2_NR,
+                       .label  = "GPX2",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[9],
+               .irq_base = IRQ_EINT(24),
+               .chip   = {
+                       .base   = EXYNOS5_GPX3(0),
+                       .ngpio  = EXYNOS5_GPIO_X3_NR,
+                       .label  = "GPX3",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       },
+#endif
+};
+
+static struct samsung_gpio_chip exynos5_gpios_2[] = {
+#ifdef CONFIG_ARCH_EXYNOS5
+       {
+               .chip   = {
+                       .base   = EXYNOS5_GPE0(0),
+                       .ngpio  = EXYNOS5_GPIO_E0_NR,
+                       .label  = "GPE0",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPE1(0),
+                       .ngpio  = EXYNOS5_GPIO_E1_NR,
+                       .label  = "GPE1",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPF0(0),
+                       .ngpio  = EXYNOS5_GPIO_F0_NR,
+                       .label  = "GPF0",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPF1(0),
+                       .ngpio  = EXYNOS5_GPIO_F1_NR,
+                       .label  = "GPF1",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPG0(0),
+                       .ngpio  = EXYNOS5_GPIO_G0_NR,
+                       .label  = "GPG0",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPG1(0),
+                       .ngpio  = EXYNOS5_GPIO_G1_NR,
+                       .label  = "GPG1",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPG2(0),
+                       .ngpio  = EXYNOS5_GPIO_G2_NR,
+                       .label  = "GPG2",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPH0(0),
+                       .ngpio  = EXYNOS5_GPIO_H0_NR,
+                       .label  = "GPH0",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPH1(0),
+                       .ngpio  = EXYNOS5_GPIO_H1_NR,
+                       .label  = "GPH1",
+
+               },
+       },
+#endif
+};
+
+static struct samsung_gpio_chip exynos5_gpios_3[] = {
+#ifdef CONFIG_ARCH_EXYNOS5
+       {
+               .chip   = {
+                       .base   = EXYNOS5_GPV0(0),
+                       .ngpio  = EXYNOS5_GPIO_V0_NR,
+                       .label  = "GPV0",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPV1(0),
+                       .ngpio  = EXYNOS5_GPIO_V1_NR,
+                       .label  = "GPV1",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPV2(0),
+                       .ngpio  = EXYNOS5_GPIO_V2_NR,
+                       .label  = "GPV2",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPV3(0),
+                       .ngpio  = EXYNOS5_GPIO_V3_NR,
+                       .label  = "GPV3",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS5_GPV4(0),
+                       .ngpio  = EXYNOS5_GPIO_V4_NR,
+                       .label  = "GPV4",
+               },
+       },
+#endif
+};
+
+static struct samsung_gpio_chip exynos5_gpios_4[] = {
+#ifdef CONFIG_ARCH_EXYNOS5
+       {
+               .chip   = {
+                       .base   = EXYNOS5_GPZ(0),
+                       .ngpio  = EXYNOS5_GPIO_Z_NR,
+                       .label  = "GPZ",
+               },
+       },
+#endif
+};
+
+
+#if defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF)
+static int exynos_gpio_xlate(struct gpio_chip *gc,
                        const struct of_phandle_args *gpiospec, u32 *flags)
 {
        unsigned int pin;
@@ -2413,13 +2681,13 @@ static int exynos4_gpio_xlate(struct gpio_chip *gc,
        return gpiospec->args[0];
 }
 
-static const struct of_device_id exynos4_gpio_dt_match[] __initdata = {
+static const struct of_device_id exynos_gpio_dt_match[] __initdata = {
        { .compatible = "samsung,exynos4-gpio", },
        {}
 };
 
-static __init void exynos4_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
-                                                u64 base, u64 offset)
+static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
+                                               u64 base, u64 offset)
 {
        struct gpio_chip *gc =  &chip->chip;
        u64 address;
@@ -2429,28 +2697,29 @@ static __init void exynos4_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
 
        address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset;
        gc->of_node = of_find_matching_node_by_address(NULL,
-                       exynos4_gpio_dt_match, address);
+                       exynos_gpio_dt_match, address);
        if (!gc->of_node) {
                pr_info("gpio: device tree node not found for gpio controller"
                        " with base address %08llx\n", address);
                return;
        }
        gc->of_gpio_n_cells = 4;
-       gc->of_xlate = exynos4_gpio_xlate;
+       gc->of_xlate = exynos_gpio_xlate;
 }
-#elif defined(CONFIG_ARCH_EXYNOS4)
-static __init void exynos4_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
-                                                u64 base, u64 offset)
+#elif defined(CONFIG_ARCH_EXYNOS)
+static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
+                                               u64 base, u64 offset)
 {
        return;
 }
-#endif /* defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF) */
+#endif /* defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) */
 
 /* TODO: cleanup soc_is_* */
 static __init int samsung_gpiolib_init(void)
 {
        struct samsung_gpio_chip *chip;
        int i, nr_chips;
+       void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4;
        int group = 0;
 
        samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs));
@@ -2516,66 +2785,200 @@ static __init int samsung_gpiolib_init(void)
                s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
 #endif
        } else if (soc_is_exynos4210()) {
-               group = 0;
+#ifdef CONFIG_CPU_EXYNOS4210
+               void __iomem *gpx_base;
 
                /* gpio part1 */
+               gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K);
+               if (gpio_base1 == NULL) {
+                       pr_err("unable to ioremap for gpio_base1\n");
+                       goto err_ioremap1;
+               }
+
                chip = exynos4_gpios_1;
                nr_chips = ARRAY_SIZE(exynos4_gpios_1);
 
                for (i = 0; i < nr_chips; i++, chip++) {
                        if (!chip->config) {
-                               chip->config = &exynos4_gpio_cfg;
+                               chip->config = &exynos_gpio_cfg;
                                chip->group = group++;
                        }
-#ifdef CONFIG_CPU_EXYNOS4210
-                       exynos4_gpiolib_attach_ofnode(chip,
+                       exynos_gpiolib_attach_ofnode(chip,
                                        EXYNOS4_PA_GPIO1, i * 0x20);
-#endif
                }
-               samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, nr_chips, S5P_VA_GPIO1);
+               samsung_gpiolib_add_4bit_chips(exynos4_gpios_1,
+                                              nr_chips, gpio_base1);
 
                /* gpio part2 */
+               gpio_base2 = ioremap(EXYNOS4_PA_GPIO2, SZ_4K);
+               if (gpio_base2 == NULL) {
+                       pr_err("unable to ioremap for gpio_base2\n");
+                       goto err_ioremap2;
+               }
+
+               /* need to set base address for gpx */
+               chip = &exynos4_gpios_2[16];
+               gpx_base = gpio_base2 + 0xC00;
+               for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
+                       chip->base = gpx_base;
+
                chip = exynos4_gpios_2;
                nr_chips = ARRAY_SIZE(exynos4_gpios_2);
 
                for (i = 0; i < nr_chips; i++, chip++) {
                        if (!chip->config) {
-                               chip->config = &exynos4_gpio_cfg;
+                               chip->config = &exynos_gpio_cfg;
                                chip->group = group++;
                        }
-#ifdef CONFIG_CPU_EXYNOS4210
-                       exynos4_gpiolib_attach_ofnode(chip,
+                       exynos_gpiolib_attach_ofnode(chip,
                                        EXYNOS4_PA_GPIO2, i * 0x20);
-#endif
                }
-               samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, nr_chips, S5P_VA_GPIO2);
+               samsung_gpiolib_add_4bit_chips(exynos4_gpios_2,
+                                              nr_chips, gpio_base2);
 
                /* gpio part3 */
+               gpio_base3 = ioremap(EXYNOS4_PA_GPIO3, SZ_256);
+               if (gpio_base3 == NULL) {
+                       pr_err("unable to ioremap for gpio_base3\n");
+                       goto err_ioremap3;
+               }
+
                chip = exynos4_gpios_3;
                nr_chips = ARRAY_SIZE(exynos4_gpios_3);
 
                for (i = 0; i < nr_chips; i++, chip++) {
                        if (!chip->config) {
-                               chip->config = &exynos4_gpio_cfg;
+                               chip->config = &exynos_gpio_cfg;
                                chip->group = group++;
                        }
-#ifdef CONFIG_CPU_EXYNOS4210
-                       exynos4_gpiolib_attach_ofnode(chip,
+                       exynos_gpiolib_attach_ofnode(chip,
                                        EXYNOS4_PA_GPIO3, i * 0x20);
-#endif
                }
-               samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, nr_chips, S5P_VA_GPIO3);
+               samsung_gpiolib_add_4bit_chips(exynos4_gpios_3,
+                                              nr_chips, gpio_base3);
 
 #if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT)
                s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
                s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
 #endif
+
+#endif /* CONFIG_CPU_EXYNOS4210 */
+       } else if (soc_is_exynos5250()) {
+#ifdef CONFIG_SOC_EXYNOS5250
+               void __iomem *gpx_base;
+
+               /* gpio part1 */
+               gpio_base1 = ioremap(EXYNOS5_PA_GPIO1, SZ_4K);
+               if (gpio_base1 == NULL) {
+                       pr_err("unable to ioremap for gpio_base1\n");
+                       goto err_ioremap1;
+               }
+
+               /* need to set base address for gpx */
+               chip = &exynos5_gpios_1[20];
+               gpx_base = gpio_base1 + 0xC00;
+               for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
+                       chip->base = gpx_base;
+
+               chip = exynos5_gpios_1;
+               nr_chips = ARRAY_SIZE(exynos5_gpios_1);
+
+               for (i = 0; i < nr_chips; i++, chip++) {
+                       if (!chip->config) {
+                               chip->config = &exynos_gpio_cfg;
+                               chip->group = group++;
+                       }
+                       exynos_gpiolib_attach_ofnode(chip,
+                                       EXYNOS5_PA_GPIO1, i * 0x20);
+               }
+               samsung_gpiolib_add_4bit_chips(exynos5_gpios_1,
+                                              nr_chips, gpio_base1);
+
+               /* gpio part2 */
+               gpio_base2 = ioremap(EXYNOS5_PA_GPIO2, SZ_4K);
+               if (gpio_base2 == NULL) {
+                       pr_err("unable to ioremap for gpio_base2\n");
+                       goto err_ioremap2;
+               }
+
+               chip = exynos5_gpios_2;
+               nr_chips = ARRAY_SIZE(exynos5_gpios_2);
+
+               for (i = 0; i < nr_chips; i++, chip++) {
+                       if (!chip->config) {
+                               chip->config = &exynos_gpio_cfg;
+                               chip->group = group++;
+                       }
+                       exynos_gpiolib_attach_ofnode(chip,
+                                       EXYNOS5_PA_GPIO2, i * 0x20);
+               }
+               samsung_gpiolib_add_4bit_chips(exynos5_gpios_2,
+                                              nr_chips, gpio_base2);
+
+               /* gpio part3 */
+               gpio_base3 = ioremap(EXYNOS5_PA_GPIO3, SZ_4K);
+               if (gpio_base3 == NULL) {
+                       pr_err("unable to ioremap for gpio_base3\n");
+                       goto err_ioremap3;
+               }
+
+               /* need to set base address for gpv */
+               exynos5_gpios_3[0].base = gpio_base3;
+               exynos5_gpios_3[1].base = gpio_base3 + 0x20;
+               exynos5_gpios_3[2].base = gpio_base3 + 0x60;
+               exynos5_gpios_3[3].base = gpio_base3 + 0x80;
+               exynos5_gpios_3[4].base = gpio_base3 + 0xC0;
+
+               chip = exynos5_gpios_3;
+               nr_chips = ARRAY_SIZE(exynos5_gpios_3);
+
+               for (i = 0; i < nr_chips; i++, chip++) {
+                       if (!chip->config) {
+                               chip->config = &exynos_gpio_cfg;
+                               chip->group = group++;
+                       }
+                       exynos_gpiolib_attach_ofnode(chip,
+                                       EXYNOS5_PA_GPIO3, i * 0x20);
+               }
+               samsung_gpiolib_add_4bit_chips(exynos5_gpios_3,
+                                              nr_chips, gpio_base3);
+
+               /* gpio part4 */
+               gpio_base4 = ioremap(EXYNOS5_PA_GPIO4, SZ_4K);
+               if (gpio_base4 == NULL) {
+                       pr_err("unable to ioremap for gpio_base4\n");
+                       goto err_ioremap4;
+               }
+
+               chip = exynos5_gpios_4;
+               nr_chips = ARRAY_SIZE(exynos5_gpios_4);
+
+               for (i = 0; i < nr_chips; i++, chip++) {
+                       if (!chip->config) {
+                               chip->config = &exynos_gpio_cfg;
+                               chip->group = group++;
+                       }
+                       exynos_gpiolib_attach_ofnode(chip,
+                                       EXYNOS5_PA_GPIO4, i * 0x20);
+               }
+               samsung_gpiolib_add_4bit_chips(exynos5_gpios_4,
+                                              nr_chips, gpio_base4);
+#endif /* CONFIG_SOC_EXYNOS5250 */
        } else {
                WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n");
                return -ENODEV;
        }
 
        return 0;
+
+err_ioremap4:
+       iounmap(gpio_base3);
+err_ioremap3:
+       iounmap(gpio_base2);
+err_ioremap2:
+       iounmap(gpio_base1);
+err_ioremap1:
+       return -ENOMEM;
 }
 core_initcall(samsung_gpiolib_init);
 
index bdc2937915906fa7a7589b02e258daccb7b024f7..6f17671260e17b94d8176befe18e6706eb228832 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
+#include <linux/irqdomain.h>
 
 #include <asm/mach/irq.h>
 
@@ -74,9 +75,10 @@ struct tegra_gpio_bank {
 #endif
 };
 
-
+static struct irq_domain *irq_domain;
 static void __iomem *regs;
-static struct tegra_gpio_bank tegra_gpio_banks[7];
+static u32 tegra_gpio_bank_count;
+static struct tegra_gpio_bank *tegra_gpio_banks;
 
 static inline void tegra_gpio_writel(u32 val, u32 reg)
 {
@@ -139,7 +141,7 @@ static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
 
 static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 {
-       return TEGRA_GPIO_TO_IRQ(offset);
+       return irq_find_mapping(irq_domain, offset);
 }
 
 static struct gpio_chip tegra_gpio_chip = {
@@ -155,28 +157,28 @@ static struct gpio_chip tegra_gpio_chip = {
 
 static void tegra_gpio_irq_ack(struct irq_data *d)
 {
-       int gpio = d->irq - INT_GPIO_BASE;
+       int gpio = d->hwirq;
 
        tegra_gpio_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio));
 }
 
 static void tegra_gpio_irq_mask(struct irq_data *d)
 {
-       int gpio = d->irq - INT_GPIO_BASE;
+       int gpio = d->hwirq;
 
        tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 0);
 }
 
 static void tegra_gpio_irq_unmask(struct irq_data *d)
 {
-       int gpio = d->irq - INT_GPIO_BASE;
+       int gpio = d->hwirq;
 
        tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 1);
 }
 
 static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
 {
-       int gpio = d->irq - INT_GPIO_BASE;
+       int gpio = d->hwirq;
        struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
        int port = GPIO_PORT(gpio);
        int lvl_type;
@@ -273,7 +275,7 @@ void tegra_gpio_resume(void)
 
        local_irq_save(flags);
 
-       for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) {
+       for (b = 0; b < tegra_gpio_bank_count; b++) {
                struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
 
                for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
@@ -296,7 +298,7 @@ void tegra_gpio_suspend(void)
        int p;
 
        local_irq_save(flags);
-       for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) {
+       for (b = 0; b < tegra_gpio_bank_count; b++) {
                struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
 
                for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
@@ -337,13 +339,44 @@ static struct lock_class_key gpio_lock_class;
 
 static int __devinit tegra_gpio_probe(struct platform_device *pdev)
 {
+       int irq_base;
        struct resource *res;
        struct tegra_gpio_bank *bank;
        int gpio;
        int i;
        int j;
 
-       for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
+       for (;;) {
+               res = platform_get_resource(pdev, IORESOURCE_IRQ, tegra_gpio_bank_count);
+               if (!res)
+                       break;
+               tegra_gpio_bank_count++;
+       }
+       if (!tegra_gpio_bank_count) {
+               dev_err(&pdev->dev, "Missing IRQ resource\n");
+               return -ENODEV;
+       }
+
+       tegra_gpio_chip.ngpio = tegra_gpio_bank_count * 32;
+
+       tegra_gpio_banks = devm_kzalloc(&pdev->dev,
+                       tegra_gpio_bank_count * sizeof(*tegra_gpio_banks),
+                       GFP_KERNEL);
+       if (!tegra_gpio_banks) {
+               dev_err(&pdev->dev, "Couldn't allocate bank structure\n");
+               return -ENODEV;
+       }
+
+       irq_base = irq_alloc_descs(-1, 0, tegra_gpio_chip.ngpio, 0);
+       if (irq_base < 0) {
+               dev_err(&pdev->dev, "Couldn't allocate IRQ numbers\n");
+               return -ENODEV;
+       }
+       irq_domain = irq_domain_add_legacy(pdev->dev.of_node,
+                                          tegra_gpio_chip.ngpio, irq_base, 0,
+                                          &irq_domain_simple_ops, NULL);
+
+       for (i = 0; i < tegra_gpio_bank_count; i++) {
                res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
                if (!res) {
                        dev_err(&pdev->dev, "Missing IRQ resource\n");
@@ -380,8 +413,8 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
 
        gpiochip_add(&tegra_gpio_chip);
 
-       for (gpio = 0; gpio < TEGRA_NR_GPIOS; gpio++) {
-               int irq = TEGRA_GPIO_TO_IRQ(gpio);
+       for (gpio = 0; gpio < tegra_gpio_chip.ngpio; gpio++) {
+               int irq = irq_find_mapping(irq_domain, gpio);
                /* No validity check; all Tegra GPIOs are valid IRQs */
 
                bank = &tegra_gpio_banks[GPIO_BANK(gpio)];
@@ -393,7 +426,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
                set_irq_flags(irq, IRQF_VALID);
        }
 
-       for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
+       for (i = 0; i < tegra_gpio_bank_count; i++) {
                bank = &tegra_gpio_banks[i];
 
                irq_set_chained_handler(bank->irq, tegra_gpio_irq_handler);
index 4c2cb4a8ad985624f1e706cbc0b4ae7f29652fd6..5675d93b420567b3c3c5f2730c915434da9be21a 100644 (file)
@@ -244,7 +244,6 @@ static int mdfld_dsi_connector_set_property(struct drm_connector *connector,
                                uint64_t value)
 {
        struct drm_encoder *encoder = connector->encoder;
-       struct backlight_device *psb_bd;
 
        if (!strcmp(property->name, "scaling mode") && encoder) {
                struct psb_intel_crtc *psb_crtc =
@@ -301,11 +300,15 @@ static int mdfld_dsi_connector_set_property(struct drm_connector *connector,
                                                                        value))
                        goto set_prop_error;
                else {
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+                       struct backlight_device *psb_bd;
+
                        psb_bd = mdfld_get_backlight_device();
                        if (psb_bd) {
                                psb_bd->props.brightness = value;
                                mdfld_set_brightness(psb_bd);
                        }
+#endif
                }
        }
 set_prop_done:
index 8f510fd956b0f71fea65d9084b8bb38d54ccde99..fa860358add1560c2ada715a1d381f4860ef98b4 100644 (file)
@@ -654,10 +654,13 @@ nouveau_connector_detect_depth(struct drm_connector *connector)
        if (nv_connector->edid && connector->display_info.bpc)
                return;
 
-       /* if not, we're out of options unless we're LVDS, default to 6bpc */
-       connector->display_info.bpc = 6;
-       if (nv_encoder->dcb->type != OUTPUT_LVDS)
+       /* if not, we're out of options unless we're LVDS, default to 8bpc */
+       if (nv_encoder->dcb->type != OUTPUT_LVDS) {
+               connector->display_info.bpc = 8;
                return;
+       }
+
+       connector->display_info.bpc = 6;
 
        /* LVDS: panel straps */
        if (bios->fp_no_ddc) {
index 8f4f914d9eab6bcbbc722973a2c0951ba84ca8c0..e2be95af2e52919c6a272009e23e01ea48c4165e 100644 (file)
@@ -315,8 +315,8 @@ nouveau_i2c_init(struct drm_device *dev)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nvbios *bios = &dev_priv->vbios;
        struct nouveau_i2c_chan *port;
+       u8 version = 0x00, entries, recordlen;
        u8 *i2c, *entry, legacy[2][4] = {};
-       u8 version, entries, recordlen;
        int ret, i;
 
        INIT_LIST_HEAD(&dev_priv->i2c_ports);
@@ -346,12 +346,12 @@ nouveau_i2c_init(struct drm_device *dev)
                if (i2c[7]) legacy[1][1] = i2c[7];
        }
 
-       if (i2c && version >= 0x30) {
+       if (version >= 0x30) {
                entry     = i2c[1] + i2c;
                entries   = i2c[2];
                recordlen = i2c[3];
        } else
-       if (i2c) {
+       if (version) {
                entry     = i2c;
                entries   = 16;
                recordlen = 4;
index a3ae91fa81414779c541bda925528ead6de8b2fa..a4886b36d0faf771d6abc7d8aaa0983aca465850 100644 (file)
@@ -852,7 +852,7 @@ nouveau_card_init(struct drm_device *dev)
        if (ret)
                goto out_pm;
 
-       if (!dev_priv->noaccel) {
+       if (dev_priv->eng[NVOBJ_ENGINE_GR]) {
                ret = nouveau_card_channel_init(dev);
                if (ret)
                        goto out_fence;
index 083b3eada001fa6436cf1c63eb60132dabe8dda8..b5ff1f7b6f7ee4f3917d6d83e137ec02998a6d78 100644 (file)
@@ -588,8 +588,8 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                if (encoder->crtc == crtc) {
                        radeon_encoder = to_radeon_encoder(encoder);
                        connector = radeon_get_connector_for_encoder(encoder);
-                       if (connector && connector->display_info.bpc)
-                               bpc = connector->display_info.bpc;
+                       /* if (connector && connector->display_info.bpc)
+                               bpc = connector->display_info.bpc; */
                        encoder_mode = atombios_get_encoder_mode(encoder);
                        is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock);
                        if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
@@ -965,7 +965,9 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
                struct radeon_connector_atom_dig *dig_connector =
                        radeon_connector->con_priv;
                int dp_clock;
-               bpc = connector->display_info.bpc;
+
+               /* if (connector->display_info.bpc)
+                       bpc = connector->display_info.bpc; */
 
                switch (encoder_mode) {
                case ATOM_ENCODER_MODE_DP_MST:
index 6c62be226804ddf124e0d310d57bca6f314cb5e7..c57d85664e77991e6af217de06ea7c6493e9a6e6 100644 (file)
@@ -405,10 +405,13 @@ static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE],
 /* get bpc from the EDID */
 static int convert_bpc_to_bpp(int bpc)
 {
+#if 0
        if (bpc == 0)
                return 24;
        else
                return bpc * 3;
+#endif
+       return 24;
 }
 
 /* get the max pix clock supported by the link rate and lane num */
index 468b874336f9412b1e20b1018737f6eb7535436c..e607c4d7dd98bbccd9a709ab908b0c2c5b26a4b9 100644 (file)
@@ -541,7 +541,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
                dp_clock = dig_connector->dp_clock;
                dp_lane_count = dig_connector->dp_lane_count;
                hpd_id = radeon_connector->hpd.hpd;
-               bpc = connector->display_info.bpc;
+               /* bpc = connector->display_info.bpc; */
        }
 
        /* no dig encoder assigned */
@@ -1159,7 +1159,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
                dp_lane_count = dig_connector->dp_lane_count;
                connector_object_id =
                        (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
-               bpc = connector->display_info.bpc;
+               /* bpc = connector->display_info.bpc; */
        }
 
        memset(&args, 0, sizeof(args));
index a58b37a2e65ac5d925f28e12c2bc1e5391669b47..70089d32b80feb7a4777f80b63c7b5c9c0c5901a 100644 (file)
@@ -80,6 +80,9 @@ struct evergreen_cs_track {
        bool                    cb_dirty;
        bool                    db_dirty;
        bool                    streamout_dirty;
+       u32                     htile_offset;
+       u32                     htile_surface;
+       struct radeon_bo        *htile_bo;
 };
 
 static u32 evergreen_cs_get_aray_mode(u32 tiling_flags)
@@ -144,6 +147,9 @@ static void evergreen_cs_track_init(struct evergreen_cs_track *track)
        track->db_s_read_bo = NULL;
        track->db_s_write_bo = NULL;
        track->db_dirty = true;
+       track->htile_bo = NULL;
+       track->htile_offset = 0xFFFFFFFF;
+       track->htile_surface = 0;
 
        for (i = 0; i < 4; i++) {
                track->vgt_strmout_size[i] = 0;
@@ -444,6 +450,62 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
        return 0;
 }
 
+static int evergreen_cs_track_validate_htile(struct radeon_cs_parser *p,
+                                               unsigned nbx, unsigned nby)
+{
+       struct evergreen_cs_track *track = p->track;
+       unsigned long size;
+
+       if (track->htile_bo == NULL) {
+               dev_warn(p->dev, "%s:%d htile enabled without htile surface 0x%08x\n",
+                               __func__, __LINE__, track->db_z_info);
+               return -EINVAL;
+       }
+
+       if (G_028ABC_LINEAR(track->htile_surface)) {
+               /* pitch must be 16 htiles aligned == 16 * 8 pixel aligned */
+               nbx = round_up(nbx, 16 * 8);
+               /* height is npipes htiles aligned == npipes * 8 pixel aligned */
+               nby = round_up(nby, track->npipes * 8);
+       } else {
+               switch (track->npipes) {
+               case 8:
+                       nbx = round_up(nbx, 64 * 8);
+                       nby = round_up(nby, 64 * 8);
+                       break;
+               case 4:
+                       nbx = round_up(nbx, 64 * 8);
+                       nby = round_up(nby, 32 * 8);
+                       break;
+               case 2:
+                       nbx = round_up(nbx, 32 * 8);
+                       nby = round_up(nby, 32 * 8);
+                       break;
+               case 1:
+                       nbx = round_up(nbx, 32 * 8);
+                       nby = round_up(nby, 16 * 8);
+                       break;
+               default:
+                       dev_warn(p->dev, "%s:%d invalid num pipes %d\n",
+                                       __func__, __LINE__, track->npipes);
+                       return -EINVAL;
+               }
+       }
+       /* compute number of htile */
+       nbx = nbx / 8;
+       nby = nby / 8;
+       size = nbx * nby * 4;
+       size += track->htile_offset;
+
+       if (size > radeon_bo_size(track->htile_bo)) {
+               dev_warn(p->dev, "%s:%d htile surface too small %ld for %ld (%d %d)\n",
+                               __func__, __LINE__, radeon_bo_size(track->htile_bo),
+                               size, nbx, nby);
+               return -EINVAL;
+       }
+       return 0;
+}
+
 static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
 {
        struct evergreen_cs_track *track = p->track;
@@ -530,6 +592,14 @@ static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
                return -EINVAL;
        }
 
+       /* hyperz */
+       if (G_028040_TILE_SURFACE_ENABLE(track->db_z_info)) {
+               r = evergreen_cs_track_validate_htile(p, surf.nbx, surf.nby);
+               if (r) {
+                       return r;
+               }
+       }
+
        return 0;
 }
 
@@ -617,6 +687,14 @@ static int evergreen_cs_track_validate_depth(struct radeon_cs_parser *p)
                return -EINVAL;
        }
 
+       /* hyperz */
+       if (G_028040_TILE_SURFACE_ENABLE(track->db_z_info)) {
+               r = evergreen_cs_track_validate_htile(p, surf.nbx, surf.nby);
+               if (r) {
+                       return r;
+               }
+       }
+
        return 0;
 }
 
@@ -850,7 +928,7 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p)
                                return r;
                }
                /* Check depth buffer */
-               if (G_028800_Z_WRITE_ENABLE(track->db_depth_control)) {
+               if (G_028800_Z_ENABLE(track->db_depth_control)) {
                        r = evergreen_cs_track_validate_depth(p);
                        if (r)
                                return r;
@@ -1616,6 +1694,23 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
                track->cb_color_bo[tmp] = reloc->robj;
                track->cb_dirty = true;
                break;
+       case DB_HTILE_DATA_BASE:
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                       "0x%04X\n", reg);
+                       return -EINVAL;
+               }
+               track->htile_offset = radeon_get_ib_value(p, idx);
+               ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+               track->htile_bo = reloc->robj;
+               track->db_dirty = true;
+               break;
+       case DB_HTILE_SURFACE:
+               /* 8x8 only */
+               track->htile_surface = radeon_get_ib_value(p, idx);
+               track->db_dirty = true;
+               break;
        case CB_IMMED0_BASE:
        case CB_IMMED1_BASE:
        case CB_IMMED2_BASE:
@@ -1628,7 +1723,6 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
        case CB_IMMED9_BASE:
        case CB_IMMED10_BASE:
        case CB_IMMED11_BASE:
-       case DB_HTILE_DATA_BASE:
        case SQ_PGM_START_FS:
        case SQ_PGM_START_ES:
        case SQ_PGM_START_VS:
index eb5708c7159dace94031b0b243859b09d4ce907a..b4eefc355f16d1c0628e5007038a2af4e0a4f5f1 100644 (file)
 #define   G_028008_SLICE_MAX(x)                        (((x) >> 13) & 0x7FF)
 #define   C_028008_SLICE_MAX                           0xFF001FFF
 #define DB_HTILE_DATA_BASE                             0x28014
+#define DB_HTILE_SURFACE                               0x28abc
+#define   S_028ABC_HTILE_WIDTH(x)                      (((x) & 0x1) << 0)
+#define   G_028ABC_HTILE_WIDTH(x)                      (((x) >> 0) & 0x1)
+#define   C_028ABC_HTILE_WIDTH                         0xFFFFFFFE
+#define   S_028ABC_HTILE_HEIGHT(x)                      (((x) & 0x1) << 1)
+#define   G_028ABC_HTILE_HEIGHT(x)                      (((x) >> 1) & 0x1)
+#define   C_028ABC_HTILE_HEIGHT                         0xFFFFFFFD
+#define   G_028ABC_LINEAR(x)                           (((x) >> 2) & 0x1)
 #define DB_Z_INFO                                      0x28040
 #       define Z_ARRAY_MODE(x)                          ((x) << 4)
 #       define DB_TILE_SPLIT(x)                         (((x) & 0x7) << 8)
index 0ec3f205f9c49ad25c6bb38f0c499d5ac8091ab6..b8e12af304a9657db9b5b906c2df1e289edb46f9 100644 (file)
@@ -78,6 +78,9 @@ struct r600_cs_track {
        bool                    cb_dirty;
        bool                    db_dirty;
        bool                    streamout_dirty;
+       struct radeon_bo        *htile_bo;
+       u64                     htile_offset;
+       u32                     htile_surface;
 };
 
 #define FMT_8_BIT(fmt, vc)   [fmt] = { 1, 1, 1, vc, CHIP_R600 }
@@ -321,6 +324,9 @@ static void r600_cs_track_init(struct r600_cs_track *track)
        track->db_depth_size_idx = 0;
        track->db_depth_control = 0xFFFFFFFF;
        track->db_dirty = true;
+       track->htile_bo = NULL;
+       track->htile_offset = 0xFFFFFFFF;
+       track->htile_surface = 0;
 
        for (i = 0; i < 4; i++) {
                track->vgt_strmout_size[i] = 0;
@@ -455,12 +461,256 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
        return 0;
 }
 
+static int r600_cs_track_validate_db(struct radeon_cs_parser *p)
+{
+       struct r600_cs_track *track = p->track;
+       u32 nviews, bpe, ntiles, size, slice_tile_max, tmp;
+       u32 height_align, pitch_align, depth_align;
+       u32 pitch = 8192;
+       u32 height = 8192;
+       u64 base_offset, base_align;
+       struct array_mode_checker array_check;
+       int array_mode;
+       volatile u32 *ib = p->ib->ptr;
+
+
+       if (track->db_bo == NULL) {
+               dev_warn(p->dev, "z/stencil with no depth buffer\n");
+               return -EINVAL;
+       }
+       switch (G_028010_FORMAT(track->db_depth_info)) {
+       case V_028010_DEPTH_16:
+               bpe = 2;
+               break;
+       case V_028010_DEPTH_X8_24:
+       case V_028010_DEPTH_8_24:
+       case V_028010_DEPTH_X8_24_FLOAT:
+       case V_028010_DEPTH_8_24_FLOAT:
+       case V_028010_DEPTH_32_FLOAT:
+               bpe = 4;
+               break;
+       case V_028010_DEPTH_X24_8_32_FLOAT:
+               bpe = 8;
+               break;
+       default:
+               dev_warn(p->dev, "z/stencil with invalid format %d\n", G_028010_FORMAT(track->db_depth_info));
+               return -EINVAL;
+       }
+       if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) {
+               if (!track->db_depth_size_idx) {
+                       dev_warn(p->dev, "z/stencil buffer size not set\n");
+                       return -EINVAL;
+               }
+               tmp = radeon_bo_size(track->db_bo) - track->db_offset;
+               tmp = (tmp / bpe) >> 6;
+               if (!tmp) {
+                       dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %ld)\n",
+                                       track->db_depth_size, bpe, track->db_offset,
+                                       radeon_bo_size(track->db_bo));
+                       return -EINVAL;
+               }
+               ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF);
+       } else {
+               size = radeon_bo_size(track->db_bo);
+               /* pitch in pixels */
+               pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8;
+               slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
+               slice_tile_max *= 64;
+               height = slice_tile_max / pitch;
+               if (height > 8192)
+                       height = 8192;
+               base_offset = track->db_bo_mc + track->db_offset;
+               array_mode = G_028010_ARRAY_MODE(track->db_depth_info);
+               array_check.array_mode = array_mode;
+               array_check.group_size = track->group_size;
+               array_check.nbanks = track->nbanks;
+               array_check.npipes = track->npipes;
+               array_check.nsamples = track->nsamples;
+               array_check.blocksize = bpe;
+               if (r600_get_array_mode_alignment(&array_check,
+                                       &pitch_align, &height_align, &depth_align, &base_align)) {
+                       dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
+                                       G_028010_ARRAY_MODE(track->db_depth_info),
+                                       track->db_depth_info);
+                       return -EINVAL;
+               }
+               switch (array_mode) {
+               case V_028010_ARRAY_1D_TILED_THIN1:
+                       /* don't break userspace */
+                       height &= ~0x7;
+                       break;
+               case V_028010_ARRAY_2D_TILED_THIN1:
+                       break;
+               default:
+                       dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
+                                       G_028010_ARRAY_MODE(track->db_depth_info),
+                                       track->db_depth_info);
+                       return -EINVAL;
+               }
+
+               if (!IS_ALIGNED(pitch, pitch_align)) {
+                       dev_warn(p->dev, "%s:%d db pitch (%d, 0x%x, %d) invalid\n",
+                                       __func__, __LINE__, pitch, pitch_align, array_mode);
+                       return -EINVAL;
+               }
+               if (!IS_ALIGNED(height, height_align)) {
+                       dev_warn(p->dev, "%s:%d db height (%d, 0x%x, %d) invalid\n",
+                                       __func__, __LINE__, height, height_align, array_mode);
+                       return -EINVAL;
+               }
+               if (!IS_ALIGNED(base_offset, base_align)) {
+                       dev_warn(p->dev, "%s offset 0x%llx, 0x%llx, %d not aligned\n", __func__,
+                                       base_offset, base_align, array_mode);
+                       return -EINVAL;
+               }
+
+               ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
+               nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1;
+               tmp = ntiles * bpe * 64 * nviews;
+               if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) {
+                       dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n",
+                                       array_mode,
+                                       track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset,
+                                       radeon_bo_size(track->db_bo));
+                       return -EINVAL;
+               }
+       }
+
+       /* hyperz */
+       if (G_028010_TILE_SURFACE_ENABLE(track->db_depth_info)) {
+               unsigned long size;
+               unsigned nbx, nby;
+
+               if (track->htile_bo == NULL) {
+                       dev_warn(p->dev, "%s:%d htile enabled without htile surface 0x%08x\n",
+                                __func__, __LINE__, track->db_depth_info);
+                       return -EINVAL;
+               }
+               if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) {
+                       dev_warn(p->dev, "%s:%d htile can't be enabled with bogus db_depth_size 0x%08x\n",
+                                __func__, __LINE__, track->db_depth_size);
+                       return -EINVAL;
+               }
+
+               nbx = pitch;
+               nby = height;
+               if (G_028D24_LINEAR(track->htile_surface)) {
+                       /* nbx must be 16 htiles aligned == 16 * 8 pixel aligned */
+                       nbx = round_up(nbx, 16 * 8);
+                       /* nby is npipes htiles aligned == npipes * 8 pixel aligned */
+                       nby = round_up(nby, track->npipes * 8);
+               } else {
+                       /* htile widht & nby (8 or 4) make 2 bits number */
+                       tmp = track->htile_surface & 3;
+                       /* align is htile align * 8, htile align vary according to
+                        * number of pipe and tile width and nby
+                        */
+                       switch (track->npipes) {
+                       case 8:
+                               switch (tmp) {
+                               case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
+                                       nbx = round_up(nbx, 64 * 8);
+                                       nby = round_up(nby, 64 * 8);
+                                       break;
+                               case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
+                               case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
+                                       nbx = round_up(nbx, 64 * 8);
+                                       nby = round_up(nby, 32 * 8);
+                                       break;
+                               case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
+                                       nbx = round_up(nbx, 32 * 8);
+                                       nby = round_up(nby, 32 * 8);
+                                       break;
+                               default:
+                                       return -EINVAL;
+                               }
+                               break;
+                       case 4:
+                               switch (tmp) {
+                               case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
+                                       nbx = round_up(nbx, 64 * 8);
+                                       nby = round_up(nby, 32 * 8);
+                                       break;
+                               case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
+                               case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
+                                       nbx = round_up(nbx, 32 * 8);
+                                       nby = round_up(nby, 32 * 8);
+                                       break;
+                               case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
+                                       nbx = round_up(nbx, 32 * 8);
+                                       nby = round_up(nby, 16 * 8);
+                                       break;
+                               default:
+                                       return -EINVAL;
+                               }
+                               break;
+                       case 2:
+                               switch (tmp) {
+                               case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
+                                       nbx = round_up(nbx, 32 * 8);
+                                       nby = round_up(nby, 32 * 8);
+                                       break;
+                               case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
+                               case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
+                                       nbx = round_up(nbx, 32 * 8);
+                                       nby = round_up(nby, 16 * 8);
+                                       break;
+                               case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
+                                       nbx = round_up(nbx, 16 * 8);
+                                       nby = round_up(nby, 16 * 8);
+                                       break;
+                               default:
+                                       return -EINVAL;
+                               }
+                               break;
+                       case 1:
+                               switch (tmp) {
+                               case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
+                                       nbx = round_up(nbx, 32 * 8);
+                                       nby = round_up(nby, 16 * 8);
+                                       break;
+                               case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
+                               case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
+                                       nbx = round_up(nbx, 16 * 8);
+                                       nby = round_up(nby, 16 * 8);
+                                       break;
+                               case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
+                                       nbx = round_up(nbx, 16 * 8);
+                                       nby = round_up(nby, 8 * 8);
+                                       break;
+                               default:
+                                       return -EINVAL;
+                               }
+                               break;
+                       default:
+                               dev_warn(p->dev, "%s:%d invalid num pipes %d\n",
+                                        __func__, __LINE__, track->npipes);
+                               return -EINVAL;
+                       }
+               }
+               /* compute number of htile */
+               nbx = G_028D24_HTILE_WIDTH(track->htile_surface) ? nbx / 8 : nbx / 4;
+               nby = G_028D24_HTILE_HEIGHT(track->htile_surface) ? nby / 8 : nby / 4;
+               size = nbx * nby * 4;
+               size += track->htile_offset;
+
+               if (size > radeon_bo_size(track->htile_bo)) {
+                       dev_warn(p->dev, "%s:%d htile surface too small %ld for %ld (%d %d)\n",
+                                __func__, __LINE__, radeon_bo_size(track->htile_bo),
+                                size, nbx, nby);
+                       return -EINVAL;
+               }
+       }
+
+       track->db_dirty = false;
+       return 0;
+}
+
 static int r600_cs_track_check(struct radeon_cs_parser *p)
 {
        struct r600_cs_track *track = p->track;
        u32 tmp;
        int r, i;
-       volatile u32 *ib = p->ib->ptr;
 
        /* on legacy kernel we don't perform advanced check */
        if (p->rdev == NULL)
@@ -513,124 +763,14 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
                track->cb_dirty = false;
        }
 
-       if (track->db_dirty) {
-               /* Check depth buffer */
-               if (G_028800_STENCIL_ENABLE(track->db_depth_control) ||
-                       G_028800_Z_ENABLE(track->db_depth_control)) {
-                       u32 nviews, bpe, ntiles, size, slice_tile_max;
-                       u32 height, height_align, pitch, pitch_align, depth_align;
-                       u64 base_offset, base_align;
-                       struct array_mode_checker array_check;
-                       int array_mode;
-
-                       if (track->db_bo == NULL) {
-                               dev_warn(p->dev, "z/stencil with no depth buffer\n");
-                               return -EINVAL;
-                       }
-                       if (G_028010_TILE_SURFACE_ENABLE(track->db_depth_info)) {
-                               dev_warn(p->dev, "this kernel doesn't support z/stencil htile\n");
-                               return -EINVAL;
-                       }
-                       switch (G_028010_FORMAT(track->db_depth_info)) {
-                       case V_028010_DEPTH_16:
-                               bpe = 2;
-                               break;
-                       case V_028010_DEPTH_X8_24:
-                       case V_028010_DEPTH_8_24:
-                       case V_028010_DEPTH_X8_24_FLOAT:
-                       case V_028010_DEPTH_8_24_FLOAT:
-                       case V_028010_DEPTH_32_FLOAT:
-                               bpe = 4;
-                               break;
-                       case V_028010_DEPTH_X24_8_32_FLOAT:
-                               bpe = 8;
-                               break;
-                       default:
-                               dev_warn(p->dev, "z/stencil with invalid format %d\n", G_028010_FORMAT(track->db_depth_info));
-                               return -EINVAL;
-                       }
-                       if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) {
-                               if (!track->db_depth_size_idx) {
-                                       dev_warn(p->dev, "z/stencil buffer size not set\n");
-                                       return -EINVAL;
-                               }
-                               tmp = radeon_bo_size(track->db_bo) - track->db_offset;
-                               tmp = (tmp / bpe) >> 6;
-                               if (!tmp) {
-                                       dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %ld)\n",
-                                                       track->db_depth_size, bpe, track->db_offset,
-                                                       radeon_bo_size(track->db_bo));
-                                       return -EINVAL;
-                               }
-                               ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF);
-                       } else {
-                               size = radeon_bo_size(track->db_bo);
-                               /* pitch in pixels */
-                               pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8;
-                               slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
-                               slice_tile_max *= 64;
-                               height = slice_tile_max / pitch;
-                               if (height > 8192)
-                                       height = 8192;
-                               base_offset = track->db_bo_mc + track->db_offset;
-                               array_mode = G_028010_ARRAY_MODE(track->db_depth_info);
-                               array_check.array_mode = array_mode;
-                               array_check.group_size = track->group_size;
-                               array_check.nbanks = track->nbanks;
-                               array_check.npipes = track->npipes;
-                               array_check.nsamples = track->nsamples;
-                               array_check.blocksize = bpe;
-                               if (r600_get_array_mode_alignment(&array_check,
-                                                                 &pitch_align, &height_align, &depth_align, &base_align)) {
-                                       dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
-                                                G_028010_ARRAY_MODE(track->db_depth_info),
-                                                track->db_depth_info);
-                                       return -EINVAL;
-                               }
-                               switch (array_mode) {
-                               case V_028010_ARRAY_1D_TILED_THIN1:
-                                       /* don't break userspace */
-                                       height &= ~0x7;
-                                       break;
-                               case V_028010_ARRAY_2D_TILED_THIN1:
-                                       break;
-                               default:
-                                       dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
-                                                G_028010_ARRAY_MODE(track->db_depth_info),
-                                                track->db_depth_info);
-                                       return -EINVAL;
-                               }
-
-                               if (!IS_ALIGNED(pitch, pitch_align)) {
-                                       dev_warn(p->dev, "%s:%d db pitch (%d, 0x%x, %d) invalid\n",
-                                                __func__, __LINE__, pitch, pitch_align, array_mode);
-                                       return -EINVAL;
-                               }
-                               if (!IS_ALIGNED(height, height_align)) {
-                                       dev_warn(p->dev, "%s:%d db height (%d, 0x%x, %d) invalid\n",
-                                                __func__, __LINE__, height, height_align, array_mode);
-                                       return -EINVAL;
-                               }
-                               if (!IS_ALIGNED(base_offset, base_align)) {
-                                       dev_warn(p->dev, "%s offset[%d] 0x%llx, 0x%llx, %d not aligned\n", __func__, i,
-                                                base_offset, base_align, array_mode);
-                                       return -EINVAL;
-                               }
-
-                               ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
-                               nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1;
-                               tmp = ntiles * bpe * 64 * nviews;
-                               if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) {
-                                       dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n",
-                                                array_mode,
-                                                track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset,
-                                                radeon_bo_size(track->db_bo));
-                                       return -EINVAL;
-                               }
-                       }
-               }
-               track->db_dirty = false;
+       /* Check depth buffer */
+       if (track->db_dirty && (G_028800_STENCIL_ENABLE(track->db_depth_control) ||
+               G_028800_Z_ENABLE(track->db_depth_control))) {
+               r = r600_cs_track_validate_db(p);
+               if (r)
+                       return r;
        }
+
        return 0;
 }
 
@@ -1244,6 +1384,21 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
                track->db_dirty = true;
                break;
        case DB_HTILE_DATA_BASE:
+               r = r600_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                       "0x%04X\n", reg);
+                       return -EINVAL;
+               }
+               track->htile_offset = radeon_get_ib_value(p, idx) << 8;
+               ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+               track->htile_bo = reloc->robj;
+               track->db_dirty = true;
+               break;
+       case DB_HTILE_SURFACE:
+               track->htile_surface = radeon_get_ib_value(p, idx);
+               track->db_dirty = true;
+               break;
        case SQ_PGM_START_FS:
        case SQ_PGM_START_ES:
        case SQ_PGM_START_VS:
index 3568a2e345faf6d4c4682aadae04a6c192f8b7da..59f9c993cc31b4cdb550b85b5b99de588b5430b0 100644 (file)
 #define                PREZ_MUST_WAIT_FOR_POSTZ_DONE                   (1 << 31)
 #define        DB_DEPTH_BASE                                   0x2800C
 #define        DB_HTILE_DATA_BASE                              0x28014
+#define        DB_HTILE_SURFACE                                0x28D24
+#define   S_028D24_HTILE_WIDTH(x)                      (((x) & 0x1) << 0)
+#define   G_028D24_HTILE_WIDTH(x)                      (((x) >> 0) & 0x1)
+#define   C_028D24_HTILE_WIDTH                         0xFFFFFFFE
+#define   S_028D24_HTILE_HEIGHT(x)                      (((x) & 0x1) << 1)
+#define   G_028D24_HTILE_HEIGHT(x)                      (((x) >> 1) & 0x1)
+#define   C_028D24_HTILE_HEIGHT                         0xFFFFFFFD
+#define   G_028D24_LINEAR(x)                           (((x) >> 2) & 0x1)
 #define        DB_WATERMARKS                                   0x9838
 #define                DEPTH_FREE(x)                                   ((x) << 0)
 #define                DEPTH_FLUSH(x)                                  ((x) << 5)
index 91541e63d582706416b8bba9365c4930c6dadf29..6f70158d34e41f979ade9268cadeab8905ea4e81 100644 (file)
@@ -233,7 +233,17 @@ int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset,
                bo->pin_count++;
                if (gpu_addr)
                        *gpu_addr = radeon_bo_gpu_offset(bo);
-               WARN_ON_ONCE(max_offset != 0);
+
+               if (max_offset != 0) {
+                       u64 domain_start;
+
+                       if (domain == RADEON_GEM_DOMAIN_VRAM)
+                               domain_start = bo->rdev->mc.vram_start;
+                       else
+                               domain_start = bo->rdev->mc.gtt_start;
+                       WARN_ON_ONCE((*gpu_addr - domain_start) > max_offset);
+               }
+
                return 0;
        }
        radeon_ttm_placement_from_domain(bo, domain);
index aea63c4158527436f9292ce32006d04fa4801629..0f656b111c15f913f6c09045f045b81bf016c2b2 100644 (file)
@@ -509,7 +509,6 @@ cayman 0x9400
 0x00028AA8 IA_MULTI_VGT_PARAM
 0x00028AB4 VGT_REUSE_OFF
 0x00028AB8 VGT_VTX_CNT_EN
-0x00028ABC DB_HTILE_SURFACE
 0x00028AC0 DB_SRESULTS_COMPARE_STATE0
 0x00028AC4 DB_SRESULTS_COMPARE_STATE1
 0x00028AC8 DB_PRELOAD_CONTROL
index 77c37202376f459b03271e36a2ebfed24353a9c9..b912a37689bf818a0fccd576f6436f71e4e936ff 100644 (file)
@@ -519,7 +519,6 @@ evergreen 0x9400
 0x00028AA4 VGT_INSTANCE_STEP_RATE_1
 0x00028AB4 VGT_REUSE_OFF
 0x00028AB8 VGT_VTX_CNT_EN
-0x00028ABC DB_HTILE_SURFACE
 0x00028AC0 DB_SRESULTS_COMPARE_STATE0
 0x00028AC4 DB_SRESULTS_COMPARE_STATE1
 0x00028AC8 DB_PRELOAD_CONTROL
index 626c24ea0b563b56c863fe24d591cd9ef9d0671d..5e659b034d9a379d362327541480b2eeef70bf61 100644 (file)
@@ -713,7 +713,6 @@ r600 0x9400
 0x0000A710 TD_VS_SAMPLER17_BORDER_RED
 0x00009508 TA_CNTL_AUX
 0x0002802C DB_DEPTH_CLEAR
-0x00028D24 DB_HTILE_SURFACE
 0x00028D34 DB_PREFETCH_LIMIT
 0x00028D30 DB_PRELOAD_CONTROL
 0x00028D0C DB_RENDER_CONTROL
index a651779d9ff7a2faf7a41f8d437f7d97b1f66b30..c0330a41db039d15ddfece5a81a58abf50d6c1b9 100644 (file)
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
-
-#include <asm/gpio.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of_i2c.h>
+
+struct i2c_gpio_private_data {
+       struct i2c_adapter adap;
+       struct i2c_algo_bit_data bit_data;
+       struct i2c_gpio_platform_data pdata;
+};
 
 /* Toggle SDA by changing the direction of the pin */
 static void i2c_gpio_setsda_dir(void *data, int state)
@@ -78,24 +85,62 @@ static int i2c_gpio_getscl(void *data)
        return gpio_get_value(pdata->scl_pin);
 }
 
+static int __devinit of_i2c_gpio_probe(struct device_node *np,
+                            struct i2c_gpio_platform_data *pdata)
+{
+       u32 reg;
+
+       if (of_gpio_count(np) < 2)
+               return -ENODEV;
+
+       pdata->sda_pin = of_get_gpio(np, 0);
+       pdata->scl_pin = of_get_gpio(np, 1);
+
+       if (!gpio_is_valid(pdata->sda_pin) || !gpio_is_valid(pdata->scl_pin)) {
+               pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n",
+                      np->full_name, pdata->sda_pin, pdata->scl_pin);
+               return -ENODEV;
+       }
+
+       of_property_read_u32(np, "i2c-gpio,delay-us", &pdata->udelay);
+
+       if (!of_property_read_u32(np, "i2c-gpio,timeout-ms", &reg))
+               pdata->timeout = msecs_to_jiffies(reg);
+
+       pdata->sda_is_open_drain =
+               of_property_read_bool(np, "i2c-gpio,sda-open-drain");
+       pdata->scl_is_open_drain =
+               of_property_read_bool(np, "i2c-gpio,scl-open-drain");
+       pdata->scl_is_output_only =
+               of_property_read_bool(np, "i2c-gpio,scl-output-only");
+
+       return 0;
+}
+
 static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 {
+       struct i2c_gpio_private_data *priv;
        struct i2c_gpio_platform_data *pdata;
        struct i2c_algo_bit_data *bit_data;
        struct i2c_adapter *adap;
        int ret;
 
-       pdata = pdev->dev.platform_data;
-       if (!pdata)
-               return -ENXIO;
-
-       ret = -ENOMEM;
-       adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
-       if (!adap)
-               goto err_alloc_adap;
-       bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL);
-       if (!bit_data)
-               goto err_alloc_bit_data;
+       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+       adap = &priv->adap;
+       bit_data = &priv->bit_data;
+       pdata = &priv->pdata;
+
+       if (pdev->dev.of_node) {
+               ret = of_i2c_gpio_probe(pdev->dev.of_node, pdata);
+               if (ret)
+                       return ret;
+       } else {
+               if (!pdev->dev.platform_data)
+                       return -ENXIO;
+               memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
+       }
 
        ret = gpio_request(pdata->sda_pin, "sda");
        if (ret)
@@ -143,6 +188,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
        adap->algo_data = bit_data;
        adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
        adap->dev.parent = &pdev->dev;
+       adap->dev.of_node = pdev->dev.of_node;
 
        /*
         * If "dev->id" is negative we consider it as zero.
@@ -154,7 +200,9 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
        if (ret)
                goto err_add_bus;
 
-       platform_set_drvdata(pdev, adap);
+       of_i2c_register_devices(adap);
+
+       platform_set_drvdata(pdev, priv);
 
        dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
                 pdata->sda_pin, pdata->scl_pin,
@@ -168,34 +216,40 @@ err_add_bus:
 err_request_scl:
        gpio_free(pdata->sda_pin);
 err_request_sda:
-       kfree(bit_data);
-err_alloc_bit_data:
-       kfree(adap);
-err_alloc_adap:
        return ret;
 }
 
 static int __devexit i2c_gpio_remove(struct platform_device *pdev)
 {
+       struct i2c_gpio_private_data *priv;
        struct i2c_gpio_platform_data *pdata;
        struct i2c_adapter *adap;
 
-       adap = platform_get_drvdata(pdev);
-       pdata = pdev->dev.platform_data;
+       priv = platform_get_drvdata(pdev);
+       adap = &priv->adap;
+       pdata = &priv->pdata;
 
        i2c_del_adapter(adap);
        gpio_free(pdata->scl_pin);
        gpio_free(pdata->sda_pin);
-       kfree(adap->algo_data);
-       kfree(adap);
 
        return 0;
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id i2c_gpio_dt_ids[] = {
+       { .compatible = "i2c-gpio", },
+       { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, i2c_gpio_dt_ids);
+#endif
+
 static struct platform_driver i2c_gpio_driver = {
        .driver         = {
                .name   = "i2c-gpio",
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(i2c_gpio_dt_ids),
        },
        .probe          = i2c_gpio_probe,
        .remove         = __devexit_p(i2c_gpio_remove),
index 124d9c594f40bc0052b8d0e1cc4861d0024fdfa0..dfb84b7ee5503ae38a955ba843ff7f17226d3161 100644 (file)
@@ -191,7 +191,7 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
 
        dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
 
-       clk_enable(i2c_imx->clk);
+       clk_prepare_enable(i2c_imx->clk);
        writeb(i2c_imx->ifdr, i2c_imx->base + IMX_I2C_IFDR);
        /* Enable I2C controller */
        writeb(0, i2c_imx->base + IMX_I2C_I2SR);
@@ -240,7 +240,7 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
 
        /* Disable I2C controller */
        writeb(0, i2c_imx->base + IMX_I2C_I2CR);
-       clk_disable(i2c_imx->clk);
+       clk_disable_unprepare(i2c_imx->clk);
 }
 
 static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
index d60364650990746897669725ac5b2324c7cb1d04..f6733267fa9cba0baf67ec3bf1ef862a22ccf02f 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/i2c-pxa.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/of_i2c.h>
 #include <linux/platform_device.h>
 #include <linux/err.h>
@@ -1044,23 +1046,60 @@ static const struct i2c_algorithm i2c_pxa_pio_algorithm = {
        .functionality  = i2c_pxa_functionality,
 };
 
-static int i2c_pxa_probe(struct platform_device *dev)
+static struct of_device_id i2c_pxa_dt_ids[] = {
+       { .compatible = "mrvl,pxa-i2c", .data = (void *)REGS_PXA2XX },
+       { .compatible = "mrvl,pwri2c", .data = (void *)REGS_PXA3XX },
+       { .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA2XX },
+       {}
+};
+MODULE_DEVICE_TABLE(of, i2c_pxa_dt_ids);
+
+static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c,
+                           enum pxa_i2c_types *i2c_types)
 {
-       struct pxa_i2c *i2c;
-       struct resource *res;
-       struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
-       const struct platform_device_id *id = platform_get_device_id(dev);
-       enum pxa_i2c_types i2c_type = id->driver_data;
+       struct device_node *np = pdev->dev.of_node;
+       const struct of_device_id *of_id =
+                       of_match_device(i2c_pxa_dt_ids, &pdev->dev);
        int ret;
-       int irq;
 
-       res = platform_get_resource(dev, IORESOURCE_MEM, 0);
-       irq = platform_get_irq(dev, 0);
-       if (res == NULL || irq < 0)
-               return -ENODEV;
+       if (!of_id)
+               return 1;
+       ret = of_alias_get_id(np, "i2c");
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
+               return ret;
+       }
+       pdev->id = ret;
+       if (of_get_property(np, "mrvl,i2c-polling", NULL))
+               i2c->use_pio = 1;
+       if (of_get_property(np, "mrvl,i2c-fast-mode", NULL))
+               i2c->fast_mode = 1;
+       *i2c_types = (u32)(of_id->data);
+       return 0;
+}
 
-       if (!request_mem_region(res->start, resource_size(res), res->name))
-               return -ENOMEM;
+static int i2c_pxa_probe_pdata(struct platform_device *pdev,
+                              struct pxa_i2c *i2c,
+                              enum pxa_i2c_types *i2c_types)
+{
+       struct i2c_pxa_platform_data *plat = pdev->dev.platform_data;
+       const struct platform_device_id *id = platform_get_device_id(pdev);
+
+       *i2c_types = id->driver_data;
+       if (plat) {
+               i2c->use_pio = plat->use_pio;
+               i2c->fast_mode = plat->fast_mode;
+       }
+       return 0;
+}
+
+static int i2c_pxa_probe(struct platform_device *dev)
+{
+       struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
+       enum pxa_i2c_types i2c_type;
+       struct pxa_i2c *i2c;
+       struct resource *res = NULL;
+       int ret, irq;
 
        i2c = kzalloc(sizeof(struct pxa_i2c), GFP_KERNEL);
        if (!i2c) {
@@ -1068,6 +1107,24 @@ static int i2c_pxa_probe(struct platform_device *dev)
                goto emalloc;
        }
 
+       ret = i2c_pxa_probe_dt(dev, i2c, &i2c_type);
+       if (ret > 0)
+               ret = i2c_pxa_probe_pdata(dev, i2c, &i2c_type);
+       if (ret < 0)
+               goto eclk;
+
+       res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       irq = platform_get_irq(dev, 0);
+       if (res == NULL || irq < 0) {
+               ret = -ENODEV;
+               goto eclk;
+       }
+
+       if (!request_mem_region(res->start, resource_size(res), res->name)) {
+               ret = -ENOMEM;
+               goto eclk;
+       }
+
        i2c->adap.owner   = THIS_MODULE;
        i2c->adap.retries = 5;
 
@@ -1109,21 +1166,16 @@ static int i2c_pxa_probe(struct platform_device *dev)
 
        i2c->slave_addr = I2C_PXA_SLAVE_ADDR;
 
-#ifdef CONFIG_I2C_PXA_SLAVE
        if (plat) {
+#ifdef CONFIG_I2C_PXA_SLAVE
                i2c->slave_addr = plat->slave_addr;
                i2c->slave = plat->slave;
-       }
 #endif
-
-       clk_enable(i2c->clk);
-
-       if (plat) {
                i2c->adap.class = plat->class;
-               i2c->use_pio = plat->use_pio;
-               i2c->fast_mode = plat->fast_mode;
        }
 
+       clk_enable(i2c->clk);
+
        if (i2c->use_pio) {
                i2c->adap.algo = &i2c_pxa_pio_algorithm;
        } else {
@@ -1234,6 +1286,7 @@ static struct platform_driver i2c_pxa_driver = {
                .name   = "pxa2xx-i2c",
                .owner  = THIS_MODULE,
                .pm     = I2C_PXA_DEV_PM_OPS,
+               .of_match_table = i2c_pxa_dt_ids,
        },
        .id_table       = i2c_pxa_id_table,
 };
index eeafc30b207ba123293fcf17c9d840277408a297..9d639fa1afbd6efc7c223750ab475d4ebc79087d 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <mach/jornada720.h>
 #include <mach/hardware.h>
+#include <mach/irqs.h>
 
 MODULE_AUTHOR("Kristoffer Ericson <Kristoffer.Ericson@gmail.com>");
 MODULE_DESCRIPTION("HP Jornada 710/720/728 keyboard driver");
index d4d08bd9205b87b7ddc617c55fee84ec6259a2b8..bd5b10eeeb407d595bab57117a1e321ea2d26ee9 100644 (file)
@@ -92,8 +92,7 @@ static irqreturn_t ams_delta_serio_interrupt(int irq, void *dev_id)
 static int ams_delta_serio_open(struct serio *serio)
 {
        /* enable keyboard */
-       ams_delta_latch2_write(AMD_DELTA_LATCH2_KEYBRD_PWR,
-                       AMD_DELTA_LATCH2_KEYBRD_PWR);
+       gpio_set_value(AMS_DELTA_GPIO_PIN_KEYBRD_PWR, 1);
 
        return 0;
 }
@@ -101,9 +100,32 @@ static int ams_delta_serio_open(struct serio *serio)
 static void ams_delta_serio_close(struct serio *serio)
 {
        /* disable keyboard */
-       ams_delta_latch2_write(AMD_DELTA_LATCH2_KEYBRD_PWR, 0);
+       gpio_set_value(AMS_DELTA_GPIO_PIN_KEYBRD_PWR, 0);
 }
 
+static const struct gpio ams_delta_gpios[] __initconst_or_module = {
+       {
+               .gpio   = AMS_DELTA_GPIO_PIN_KEYBRD_DATA,
+               .flags  = GPIOF_DIR_IN,
+               .label  = "serio-data",
+       },
+       {
+               .gpio   = AMS_DELTA_GPIO_PIN_KEYBRD_CLK,
+               .flags  = GPIOF_DIR_IN,
+               .label  = "serio-clock",
+       },
+       {
+               .gpio   = AMS_DELTA_GPIO_PIN_KEYBRD_PWR,
+               .flags  = GPIOF_OUT_INIT_LOW,
+               .label  = "serio-power",
+       },
+       {
+               .gpio   = AMS_DELTA_GPIO_PIN_KEYBRD_DATAOUT,
+               .flags  = GPIOF_OUT_INIT_LOW,
+               .label  = "serio-dataout",
+       },
+};
+
 static int __init ams_delta_serio_init(void)
 {
        int err;
@@ -123,19 +145,12 @@ static int __init ams_delta_serio_init(void)
        strlcpy(ams_delta_serio->phys, "GPIO/serio0",
                        sizeof(ams_delta_serio->phys));
 
-       err = gpio_request(AMS_DELTA_GPIO_PIN_KEYBRD_DATA, "serio-data");
+       err = gpio_request_array(ams_delta_gpios,
+                               ARRAY_SIZE(ams_delta_gpios));
        if (err) {
-               pr_err("ams_delta_serio: Couldn't request gpio pin for data\n");
+               pr_err("ams_delta_serio: Couldn't request gpio pins\n");
                goto serio;
        }
-       gpio_direction_input(AMS_DELTA_GPIO_PIN_KEYBRD_DATA);
-
-       err = gpio_request(AMS_DELTA_GPIO_PIN_KEYBRD_CLK, "serio-clock");
-       if (err) {
-               pr_err("ams_delta_serio: couldn't request gpio pin for clock\n");
-               goto gpio_data;
-       }
-       gpio_direction_input(AMS_DELTA_GPIO_PIN_KEYBRD_CLK);
 
        err = request_irq(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK),
                        ams_delta_serio_interrupt, IRQ_TYPE_EDGE_RISING,
@@ -143,7 +158,7 @@ static int __init ams_delta_serio_init(void)
        if (err < 0) {
                pr_err("ams_delta_serio: couldn't request gpio interrupt %d\n",
                                gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK));
-               goto gpio_clk;
+               goto gpio;
        }
        /*
         * Since GPIO register handling for keyboard clock pin is performed
@@ -157,10 +172,9 @@ static int __init ams_delta_serio_init(void)
        dev_info(&ams_delta_serio->dev, "%s\n", ams_delta_serio->name);
 
        return 0;
-gpio_clk:
-       gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_CLK);
-gpio_data:
-       gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_DATA);
+gpio:
+       gpio_free_array(ams_delta_gpios,
+                       ARRAY_SIZE(ams_delta_gpios));
 serio:
        kfree(ams_delta_serio);
        return err;
@@ -171,7 +185,7 @@ static void __exit ams_delta_serio_exit(void)
 {
        serio_unregister_port(ams_delta_serio);
        free_irq(OMAP_GPIO_IRQ(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), 0);
-       gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_CLK);
-       gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_DATA);
+       gpio_free_array(ams_delta_gpios,
+                       ARRAY_SIZE(ams_delta_gpios));
 }
 module_exit(ams_delta_serio_exit);
index 8b44ddc8041ce4c1cf410435585caeb8f379193a..58b224498b35ad7d3fc6c2b034780f67921f7f9f 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 
-#include <asm/irq.h>
 #include <mach/hardware.h>
 #include <asm/hardware/iomd.h>
 #include <asm/system.h>
@@ -46,6 +45,11 @@ MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:kart");
 
+struct rpckbd_data {
+       int tx_irq;
+       int rx_irq;
+};
+
 static int rpckbd_write(struct serio *port, unsigned char val)
 {
        while (!(iomd_readb(IOMD_KCTRL) & (1 << 7)))
@@ -78,19 +82,21 @@ static irqreturn_t rpckbd_tx(int irq, void *dev_id)
 
 static int rpckbd_open(struct serio *port)
 {
+       struct rpckbd_data *rpckbd = port->port_data;
+
        /* Reset the keyboard state machine. */
        iomd_writeb(0, IOMD_KCTRL);
        iomd_writeb(8, IOMD_KCTRL);
        iomd_readb(IOMD_KARTRX);
 
-       if (request_irq(IRQ_KEYBOARDRX, rpckbd_rx, 0, "rpckbd", port) != 0) {
+       if (request_irq(rpckbd->rx_irq, rpckbd_rx, 0, "rpckbd", port) != 0) {
                printk(KERN_ERR "rpckbd.c: Could not allocate keyboard receive IRQ\n");
                return -EBUSY;
        }
 
-       if (request_irq(IRQ_KEYBOARDTX, rpckbd_tx, 0, "rpckbd", port) != 0) {
+       if (request_irq(rpckbd->tx_irq, rpckbd_tx, 0, "rpckbd", port) != 0) {
                printk(KERN_ERR "rpckbd.c: Could not allocate keyboard transmit IRQ\n");
-               free_irq(IRQ_KEYBOARDRX, port);
+               free_irq(rpckbd->rx_irq, port);
                return -EBUSY;
        }
 
@@ -99,8 +105,10 @@ static int rpckbd_open(struct serio *port)
 
 static void rpckbd_close(struct serio *port)
 {
-       free_irq(IRQ_KEYBOARDRX, port);
-       free_irq(IRQ_KEYBOARDTX, port);
+       struct rpckbd_data *rpckbd = port->port_data;
+
+       free_irq(rpckbd->rx_irq, port);
+       free_irq(rpckbd->tx_irq, port);
 }
 
 /*
@@ -109,17 +117,35 @@ static void rpckbd_close(struct serio *port)
  */
 static int __devinit rpckbd_probe(struct platform_device *dev)
 {
+       struct rpckbd_data *rpckbd;
        struct serio *serio;
+       int tx_irq, rx_irq;
+
+       rx_irq = platform_get_irq(dev, 0);
+       if (rx_irq <= 0)
+               return rx_irq < 0 ? rx_irq : -ENXIO;
+
+       tx_irq = platform_get_irq(dev, 1);
+       if (tx_irq <= 0)
+               return tx_irq < 0 ? tx_irq : -ENXIO;
 
        serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
-       if (!serio)
+       rpckbd = kzalloc(sizeof(*rpckbd), GFP_KERNEL);
+       if (!serio || !rpckbd) {
+               kfree(rpckbd);
+               kfree(serio);
                return -ENOMEM;
+       }
+
+       rpckbd->rx_irq = rx_irq;
+       rpckbd->tx_irq = tx_irq;
 
        serio->id.type          = SERIO_8042;
        serio->write            = rpckbd_write;
        serio->open             = rpckbd_open;
        serio->close            = rpckbd_close;
        serio->dev.parent       = &dev->dev;
+       serio->port_data        = rpckbd;
        strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name));
        strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys));
 
@@ -131,7 +157,11 @@ static int __devinit rpckbd_probe(struct platform_device *dev)
 static int __devexit rpckbd_remove(struct platform_device *dev)
 {
        struct serio *serio = platform_get_drvdata(dev);
+       struct rpckbd_data *rpckbd = serio->port_data;
+
        serio_unregister_port(serio);
+       kfree(rpckbd);
+
        return 0;
 }
 
index 44fc8b4bcd8157632b5e4bab9b8851dcac9e6523..5ebabe3fc84521e2ad18149f3f3092a8be686231 100644 (file)
 
 #include <asm/hardware/sa1111.h>
 
+#define PS2CR          0x0000
+#define PS2STAT                0x0004
+#define PS2DATA                0x0008
+#define PS2CLKDIV      0x000c
+#define PS2PRECNT      0x0010
+
+#define PS2CR_ENA      0x08
+#define PS2CR_FKD      0x02
+#define PS2CR_FKC      0x01
+
+#define PS2STAT_STP    0x0100
+#define PS2STAT_TXE    0x0080
+#define PS2STAT_TXB    0x0040
+#define PS2STAT_RXF    0x0020
+#define PS2STAT_RXB    0x0010
+#define PS2STAT_ENA    0x0008
+#define PS2STAT_RXP    0x0004
+#define PS2STAT_KBD    0x0002
+#define PS2STAT_KBC    0x0001
+
 struct ps2if {
        struct serio            *io;
        struct sa1111_dev       *dev;
@@ -45,22 +65,22 @@ static irqreturn_t ps2_rxint(int irq, void *dev_id)
        struct ps2if *ps2if = dev_id;
        unsigned int scancode, flag, status;
 
-       status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
+       status = sa1111_readl(ps2if->base + PS2STAT);
        while (status & PS2STAT_RXF) {
                if (status & PS2STAT_STP)
-                       sa1111_writel(PS2STAT_STP, ps2if->base + SA1111_PS2STAT);
+                       sa1111_writel(PS2STAT_STP, ps2if->base + PS2STAT);
 
                flag = (status & PS2STAT_STP ? SERIO_FRAME : 0) |
                       (status & PS2STAT_RXP ? 0 : SERIO_PARITY);
 
-               scancode = sa1111_readl(ps2if->base + SA1111_PS2DATA) & 0xff;
+               scancode = sa1111_readl(ps2if->base + PS2DATA) & 0xff;
 
                if (hweight8(scancode) & 1)
                        flag ^= SERIO_PARITY;
 
                serio_interrupt(ps2if->io, scancode, flag);
 
-               status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
+               status = sa1111_readl(ps2if->base + PS2STAT);
         }
 
         return IRQ_HANDLED;
@@ -75,12 +95,12 @@ static irqreturn_t ps2_txint(int irq, void *dev_id)
        unsigned int status;
 
        spin_lock(&ps2if->lock);
-       status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
+       status = sa1111_readl(ps2if->base + PS2STAT);
        if (ps2if->head == ps2if->tail) {
                disable_irq_nosync(irq);
                /* done */
        } else if (status & PS2STAT_TXE) {
-               sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + SA1111_PS2DATA);
+               sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + PS2DATA);
                ps2if->tail = (ps2if->tail + 1) & (sizeof(ps2if->buf) - 1);
        }
        spin_unlock(&ps2if->lock);
@@ -103,8 +123,8 @@ static int ps2_write(struct serio *io, unsigned char val)
        /*
         * If the TX register is empty, we can go straight out.
         */
-       if (sa1111_readl(ps2if->base + SA1111_PS2STAT) & PS2STAT_TXE) {
-               sa1111_writel(val, ps2if->base + SA1111_PS2DATA);
+       if (sa1111_readl(ps2if->base + PS2STAT) & PS2STAT_TXE) {
+               sa1111_writel(val, ps2if->base + PS2DATA);
        } else {
                if (ps2if->head == ps2if->tail)
                        enable_irq(ps2if->dev->irq[1]);
@@ -124,13 +144,16 @@ static int ps2_open(struct serio *io)
        struct ps2if *ps2if = io->port_data;
        int ret;
 
-       sa1111_enable_device(ps2if->dev);
+       ret = sa1111_enable_device(ps2if->dev);
+       if (ret)
+               return ret;
 
        ret = request_irq(ps2if->dev->irq[0], ps2_rxint, 0,
                          SA1111_DRIVER_NAME(ps2if->dev), ps2if);
        if (ret) {
                printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n",
                        ps2if->dev->irq[0], ret);
+               sa1111_disable_device(ps2if->dev);
                return ret;
        }
 
@@ -140,6 +163,7 @@ static int ps2_open(struct serio *io)
                printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n",
                        ps2if->dev->irq[1], ret);
                free_irq(ps2if->dev->irq[0], ps2if);
+               sa1111_disable_device(ps2if->dev);
                return ret;
        }
 
@@ -147,7 +171,7 @@ static int ps2_open(struct serio *io)
 
        enable_irq_wake(ps2if->dev->irq[0]);
 
-       sa1111_writel(PS2CR_ENA, ps2if->base + SA1111_PS2CR);
+       sa1111_writel(PS2CR_ENA, ps2if->base + PS2CR);
        return 0;
 }
 
@@ -155,7 +179,7 @@ static void ps2_close(struct serio *io)
 {
        struct ps2if *ps2if = io->port_data;
 
-       sa1111_writel(0, ps2if->base + SA1111_PS2CR);
+       sa1111_writel(0, ps2if->base + PS2CR);
 
        disable_irq_wake(ps2if->dev->irq[0]);
 
@@ -175,7 +199,7 @@ static void __devinit ps2_clear_input(struct ps2if *ps2if)
        int maxread = 100;
 
        while (maxread--) {
-               if ((sa1111_readl(ps2if->base + SA1111_PS2DATA) & 0xff) == 0xff)
+               if ((sa1111_readl(ps2if->base + PS2DATA) & 0xff) == 0xff)
                        break;
        }
 }
@@ -185,11 +209,11 @@ static unsigned int __devinit ps2_test_one(struct ps2if *ps2if,
 {
        unsigned int val;
 
-       sa1111_writel(PS2CR_ENA | mask, ps2if->base + SA1111_PS2CR);
+       sa1111_writel(PS2CR_ENA | mask, ps2if->base + PS2CR);
 
        udelay(2);
 
-       val = sa1111_readl(ps2if->base + SA1111_PS2STAT);
+       val = sa1111_readl(ps2if->base + PS2STAT);
        return val & (PS2STAT_KBC | PS2STAT_KBD);
 }
 
@@ -220,7 +244,7 @@ static int __devinit ps2_test(struct ps2if *ps2if)
                ret = -ENODEV;
        }
 
-       sa1111_writel(0, ps2if->base + SA1111_PS2CR);
+       sa1111_writel(0, ps2if->base + PS2CR);
 
        return ret;
 }
@@ -274,8 +298,8 @@ static int __devinit ps2_probe(struct sa1111_dev *dev)
        sa1111_enable_device(ps2if->dev);
 
        /* Incoming clock is 8MHz */
-       sa1111_writel(0, ps2if->base + SA1111_PS2CLKDIV);
-       sa1111_writel(127, ps2if->base + SA1111_PS2PRECNT);
+       sa1111_writel(0, ps2if->base + PS2CLKDIV);
+       sa1111_writel(127, ps2if->base + PS2PRECNT);
 
        /*
         * Flush any pending input.
@@ -330,6 +354,7 @@ static int __devexit ps2_remove(struct sa1111_dev *dev)
 static struct sa1111_driver ps2_driver = {
        .drv = {
                .name   = "sa1111-ps2",
+               .owner  = THIS_MODULE,
        },
        .devid          = SA1111_DEVID_PS2,
        .probe          = ps2_probe,
index 97b31a0e0525446ab1dd6fd6a6f777fff8c991af..2a2141915aa04939a4a1f9f9f96b0ef9a58072b6 100644 (file)
@@ -260,7 +260,7 @@ config TOUCHSCREEN_ILI210X
 
 config TOUCHSCREEN_S3C2410
        tristate "Samsung S3C2410/generic touchscreen input driver"
-       depends on ARCH_S3C2410 || SAMSUNG_DEV_TS
+       depends on ARCH_S3C24XX || SAMSUNG_DEV_TS
        select S3C_ADC
        help
          Say Y here if you have the s3c2410 touchscreen.
index c3848ad2325bcbe48d6a244d374ffd08cc70d8a9..d9be6eac99b13899e777016f4337918186a4b5a2 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <mach/hardware.h>
 #include <mach/jornada720.h>
+#include <mach/irqs.h>
 
 MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>");
 MODULE_DESCRIPTION("HP Jornada 710/720/728 touchscreen driver");
index 589ba02d65a243ade195f0fe8cb1d3032fbf7e6b..ff4b8cfda585b6461309824f277e52d263e0dcb6 100644 (file)
@@ -69,18 +69,11 @@ config LEDS_MIKROTIK_RB532
 config LEDS_S3C24XX
        tristate "LED Support for Samsung S3C24XX GPIO LEDs"
        depends on LEDS_CLASS
-       depends on ARCH_S3C2410
+       depends on ARCH_S3C24XX
        help
          This option enables support for LEDs connected to GPIO lines
          on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440.
 
-config LEDS_AMS_DELTA
-       tristate "LED Support for the Amstrad Delta (E3)"
-       depends on LEDS_CLASS
-       depends on MACH_AMS_DELTA
-       help
-         This option enables support for the LEDs on Amstrad Delta (E3).
-
 config LEDS_NET48XX
        tristate "LED Support for Soekris net48xx series Error LED"
        depends on LEDS_CLASS
index fa0f428b32fe488f753e490d15ca08939fcb000c..890481cb09f6b23aa762a242b4a9b4e98998fb91 100644 (file)
@@ -12,7 +12,6 @@ obj-$(CONFIG_LEDS_LOCOMO)             += leds-locomo.o
 obj-$(CONFIG_LEDS_LM3530)              += leds-lm3530.o
 obj-$(CONFIG_LEDS_MIKROTIK_RB532)      += leds-rb532.o
 obj-$(CONFIG_LEDS_S3C24XX)             += leds-s3c24xx.o
-obj-$(CONFIG_LEDS_AMS_DELTA)           += leds-ams-delta.o
 obj-$(CONFIG_LEDS_NET48XX)             += leds-net48xx.o
 obj-$(CONFIG_LEDS_WRAP)                        += leds-wrap.o
 obj-$(CONFIG_LEDS_COBALT_QUBE)         += leds-cobalt-qube.o
diff --git a/drivers/leds/leds-ams-delta.c b/drivers/leds/leds-ams-delta.c
deleted file mode 100644 (file)
index 0742835..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * LEDs driver for Amstrad Delta (E3)
- *
- * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/leds.h>
-#include <plat/board-ams-delta.h>
-
-/*
- * Our context
- */
-struct ams_delta_led {
-       struct led_classdev     cdev;
-       u8                      bitmask;
-};
-
-static void ams_delta_led_set(struct led_classdev *led_cdev,
-               enum led_brightness value)
-{
-       struct ams_delta_led *led_dev =
-               container_of(led_cdev, struct ams_delta_led, cdev);
-
-       if (value)
-               ams_delta_latch1_write(led_dev->bitmask, led_dev->bitmask);
-       else
-               ams_delta_latch1_write(led_dev->bitmask, 0);
-}
-
-static struct ams_delta_led ams_delta_leds[] = {
-       {
-               .cdev           = {
-                       .name           = "ams-delta::camera",
-                       .brightness_set = ams_delta_led_set,
-               },
-               .bitmask        = AMS_DELTA_LATCH1_LED_CAMERA,
-       },
-       {
-               .cdev           = {
-                       .name           = "ams-delta::advert",
-                       .brightness_set = ams_delta_led_set,
-               },
-               .bitmask        = AMS_DELTA_LATCH1_LED_ADVERT,
-       },
-       {
-               .cdev           = {
-                       .name           = "ams-delta::email",
-                       .brightness_set = ams_delta_led_set,
-               },
-               .bitmask        = AMS_DELTA_LATCH1_LED_EMAIL,
-       },
-       {
-               .cdev           = {
-                       .name           = "ams-delta::handsfree",
-                       .brightness_set = ams_delta_led_set,
-               },
-               .bitmask        = AMS_DELTA_LATCH1_LED_HANDSFREE,
-       },
-       {
-               .cdev           = {
-                       .name           = "ams-delta::voicemail",
-                       .brightness_set = ams_delta_led_set,
-               },
-               .bitmask        = AMS_DELTA_LATCH1_LED_VOICEMAIL,
-       },
-       {
-               .cdev           = {
-                       .name           = "ams-delta::voice",
-                       .brightness_set = ams_delta_led_set,
-               },
-               .bitmask        = AMS_DELTA_LATCH1_LED_VOICE,
-       },
-};
-
-static int ams_delta_led_probe(struct platform_device *pdev)
-{
-       int i, ret;
-
-       for (i = 0; i < ARRAY_SIZE(ams_delta_leds); i++) {
-               ams_delta_leds[i].cdev.flags |= LED_CORE_SUSPENDRESUME;
-               ret = led_classdev_register(&pdev->dev,
-                               &ams_delta_leds[i].cdev);
-               if (ret < 0)
-                       goto fail;
-       }
-
-       return 0;
-fail:
-       while (--i >= 0)
-               led_classdev_unregister(&ams_delta_leds[i].cdev);
-       return ret;     
-}
-
-static int ams_delta_led_remove(struct platform_device *pdev)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(ams_delta_leds); i++)
-               led_classdev_unregister(&ams_delta_leds[i].cdev);
-
-       return 0;
-}
-
-static struct platform_driver ams_delta_led_driver = {
-       .probe          = ams_delta_led_probe,
-       .remove         = ams_delta_led_remove,
-       .driver         = {
-               .name = "ams-delta-led",
-               .owner = THIS_MODULE,
-       },
-};
-
-module_platform_driver(ams_delta_led_driver);
-
-MODULE_AUTHOR("Jonathan McDowell <noodles@earth.li>");
-MODULE_DESCRIPTION("Amstrad Delta LED driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:ams-delta-led");
index faa4741df6d3f7fca87e79b8a5f788b5d1b87218..10f122a3a8566acc5a1046b4a9b35ef04ad45fab 100644 (file)
@@ -277,8 +277,8 @@ config DM_MIRROR
          needed for live data migration tools such as 'pvmove'.
 
 config DM_RAID
-       tristate "RAID 1/4/5/6 target (EXPERIMENTAL)"
-       depends on BLK_DEV_DM && EXPERIMENTAL
+       tristate "RAID 1/4/5/6 target"
+       depends on BLK_DEV_DM
        select MD_RAID1
        select MD_RAID456
        select BLK_DEV_MD
@@ -359,8 +359,8 @@ config DM_DELAY
        If unsure, say N.
 
 config DM_UEVENT
-       bool "DM uevents (EXPERIMENTAL)"
-       depends on BLK_DEV_DM && EXPERIMENTAL
+       bool "DM uevents"
+       depends on BLK_DEV_DM
        ---help---
        Generate udev events for DM events.
 
@@ -370,4 +370,24 @@ config DM_FLAKEY
        ---help---
          A target that intermittently fails I/O for debugging purposes.
 
+config DM_VERITY
+       tristate "Verity target support (EXPERIMENTAL)"
+       depends on BLK_DEV_DM && EXPERIMENTAL
+       select CRYPTO
+       select CRYPTO_HASH
+       select DM_BUFIO
+       ---help---
+         This device-mapper target creates a read-only device that
+         transparently validates the data on one underlying device against
+         a pre-generated tree of cryptographic checksums stored on a second
+         device.
+
+         You'll need to activate the digests you're going to use in the
+         cryptoapi configuration.
+
+         To compile this code as a module, choose M here: the module will
+         be called dm-verity.
+
+         If unsure, say N.
+
 endif # MD
index 046860c7a1666e54f5cdd33a40901fb2b84dd090..8b2e0dffe82e9c7fd4ca571381ea2fdfb0d77986 100644 (file)
@@ -42,6 +42,7 @@ obj-$(CONFIG_DM_LOG_USERSPACE)        += dm-log-userspace.o
 obj-$(CONFIG_DM_ZERO)          += dm-zero.o
 obj-$(CONFIG_DM_RAID)  += dm-raid.o
 obj-$(CONFIG_DM_THIN_PROVISIONING)     += dm-thin-pool.o
+obj-$(CONFIG_DM_VERITY)                += dm-verity.o
 
 ifeq ($(CONFIG_DM_UEVENT),y)
 dm-mod-objs                    += dm-uevent.o
index b6e58c7b6df544fa3a9f2f2cff94a7da6af72c3f..cc06a1e5242395c9d05e26b76c71849490f348af 100644 (file)
@@ -578,7 +578,7 @@ static void write_endio(struct bio *bio, int error)
        struct dm_buffer *b = container_of(bio, struct dm_buffer, bio);
 
        b->write_error = error;
-       if (error) {
+       if (unlikely(error)) {
                struct dm_bufio_client *c = b->c;
                (void)cmpxchg(&c->async_write_error, 0, error);
        }
@@ -697,13 +697,20 @@ static void __wait_for_free_buffer(struct dm_bufio_client *c)
        dm_bufio_lock(c);
 }
 
+enum new_flag {
+       NF_FRESH = 0,
+       NF_READ = 1,
+       NF_GET = 2,
+       NF_PREFETCH = 3
+};
+
 /*
  * Allocate a new buffer. If the allocation is not possible, wait until
  * some other thread frees a buffer.
  *
  * May drop the lock and regain it.
  */
-static struct dm_buffer *__alloc_buffer_wait_no_callback(struct dm_bufio_client *c)
+static struct dm_buffer *__alloc_buffer_wait_no_callback(struct dm_bufio_client *c, enum new_flag nf)
 {
        struct dm_buffer *b;
 
@@ -726,6 +733,9 @@ static struct dm_buffer *__alloc_buffer_wait_no_callback(struct dm_bufio_client
                                return b;
                }
 
+               if (nf == NF_PREFETCH)
+                       return NULL;
+
                if (!list_empty(&c->reserved_buffers)) {
                        b = list_entry(c->reserved_buffers.next,
                                       struct dm_buffer, lru_list);
@@ -743,9 +753,12 @@ static struct dm_buffer *__alloc_buffer_wait_no_callback(struct dm_bufio_client
        }
 }
 
-static struct dm_buffer *__alloc_buffer_wait(struct dm_bufio_client *c)
+static struct dm_buffer *__alloc_buffer_wait(struct dm_bufio_client *c, enum new_flag nf)
 {
-       struct dm_buffer *b = __alloc_buffer_wait_no_callback(c);
+       struct dm_buffer *b = __alloc_buffer_wait_no_callback(c, nf);
+
+       if (!b)
+               return NULL;
 
        if (c->alloc_callback)
                c->alloc_callback(b);
@@ -865,32 +878,23 @@ static struct dm_buffer *__find(struct dm_bufio_client *c, sector_t block)
  * Getting a buffer
  *--------------------------------------------------------------*/
 
-enum new_flag {
-       NF_FRESH = 0,
-       NF_READ = 1,
-       NF_GET = 2
-};
-
 static struct dm_buffer *__bufio_new(struct dm_bufio_client *c, sector_t block,
-                                    enum new_flag nf, struct dm_buffer **bp,
-                                    int *need_submit)
+                                    enum new_flag nf, int *need_submit)
 {
        struct dm_buffer *b, *new_b = NULL;
 
        *need_submit = 0;
 
        b = __find(c, block);
-       if (b) {
-               b->hold_count++;
-               __relink_lru(b, test_bit(B_DIRTY, &b->state) ||
-                            test_bit(B_WRITING, &b->state));
-               return b;
-       }
+       if (b)
+               goto found_buffer;
 
        if (nf == NF_GET)
                return NULL;
 
-       new_b = __alloc_buffer_wait(c);
+       new_b = __alloc_buffer_wait(c, nf);
+       if (!new_b)
+               return NULL;
 
        /*
         * We've had a period where the mutex was unlocked, so need to
@@ -899,10 +903,7 @@ static struct dm_buffer *__bufio_new(struct dm_bufio_client *c, sector_t block,
        b = __find(c, block);
        if (b) {
                __free_buffer_wake(new_b);
-               b->hold_count++;
-               __relink_lru(b, test_bit(B_DIRTY, &b->state) ||
-                            test_bit(B_WRITING, &b->state));
-               return b;
+               goto found_buffer;
        }
 
        __check_watermark(c);
@@ -922,6 +923,24 @@ static struct dm_buffer *__bufio_new(struct dm_bufio_client *c, sector_t block,
        *need_submit = 1;
 
        return b;
+
+found_buffer:
+       if (nf == NF_PREFETCH)
+               return NULL;
+       /*
+        * Note: it is essential that we don't wait for the buffer to be
+        * read if dm_bufio_get function is used. Both dm_bufio_get and
+        * dm_bufio_prefetch can be used in the driver request routine.
+        * If the user called both dm_bufio_prefetch and dm_bufio_get on
+        * the same buffer, it would deadlock if we waited.
+        */
+       if (nf == NF_GET && unlikely(test_bit(B_READING, &b->state)))
+               return NULL;
+
+       b->hold_count++;
+       __relink_lru(b, test_bit(B_DIRTY, &b->state) ||
+                    test_bit(B_WRITING, &b->state));
+       return b;
 }
 
 /*
@@ -956,10 +975,10 @@ static void *new_read(struct dm_bufio_client *c, sector_t block,
        struct dm_buffer *b;
 
        dm_bufio_lock(c);
-       b = __bufio_new(c, block, nf, bp, &need_submit);
+       b = __bufio_new(c, block, nf, &need_submit);
        dm_bufio_unlock(c);
 
-       if (!b || IS_ERR(b))
+       if (!b)
                return b;
 
        if (need_submit)
@@ -1005,13 +1024,47 @@ void *dm_bufio_new(struct dm_bufio_client *c, sector_t block,
 }
 EXPORT_SYMBOL_GPL(dm_bufio_new);
 
+void dm_bufio_prefetch(struct dm_bufio_client *c,
+                      sector_t block, unsigned n_blocks)
+{
+       struct blk_plug plug;
+
+       blk_start_plug(&plug);
+       dm_bufio_lock(c);
+
+       for (; n_blocks--; block++) {
+               int need_submit;
+               struct dm_buffer *b;
+               b = __bufio_new(c, block, NF_PREFETCH, &need_submit);
+               if (unlikely(b != NULL)) {
+                       dm_bufio_unlock(c);
+
+                       if (need_submit)
+                               submit_io(b, READ, b->block, read_endio);
+                       dm_bufio_release(b);
+
+                       dm_bufio_cond_resched();
+
+                       if (!n_blocks)
+                               goto flush_plug;
+                       dm_bufio_lock(c);
+               }
+
+       }
+
+       dm_bufio_unlock(c);
+
+flush_plug:
+       blk_finish_plug(&plug);
+}
+EXPORT_SYMBOL_GPL(dm_bufio_prefetch);
+
 void dm_bufio_release(struct dm_buffer *b)
 {
        struct dm_bufio_client *c = b->c;
 
        dm_bufio_lock(c);
 
-       BUG_ON(test_bit(B_READING, &b->state));
        BUG_ON(!b->hold_count);
 
        b->hold_count--;
@@ -1024,6 +1077,7 @@ void dm_bufio_release(struct dm_buffer *b)
                 * invalid buffer.
                 */
                if ((b->read_error || b->write_error) &&
+                   !test_bit(B_READING, &b->state) &&
                    !test_bit(B_WRITING, &b->state) &&
                    !test_bit(B_DIRTY, &b->state)) {
                        __unlink_buffer(b);
@@ -1041,6 +1095,8 @@ void dm_bufio_mark_buffer_dirty(struct dm_buffer *b)
 
        dm_bufio_lock(c);
 
+       BUG_ON(test_bit(B_READING, &b->state));
+
        if (!test_and_set_bit(B_DIRTY, &b->state))
                __relink_lru(b, LIST_DIRTY);
 
index 5c4c3a04e3810d76fc9b65277a99a3479cd3e23a..b142946a9e32ea23dcc241b5120ba00fe09e5287 100644 (file)
@@ -62,6 +62,14 @@ void *dm_bufio_get(struct dm_bufio_client *c, sector_t block,
 void *dm_bufio_new(struct dm_bufio_client *c, sector_t block,
                   struct dm_buffer **bp);
 
+/*
+ * Prefetch the specified blocks to the cache.
+ * The function starts to read the blocks and returns without waiting for
+ * I/O to finish.
+ */
+void dm_bufio_prefetch(struct dm_bufio_client *c,
+                      sector_t block, unsigned n_blocks);
+
 /*
  * Release a reference obtained with dm_bufio_{read,get,new}. The data
  * pointer and dm_buffer pointer is no longer valid after this call.
index db6b51639cee438e5b8ba0762c38105800d519b4..3f06df59fd824022fd80a9c77551178660909eb6 100644 (file)
@@ -176,7 +176,6 @@ struct crypt_config {
 
 #define MIN_IOS        16
 #define MIN_POOL_PAGES 32
-#define MIN_BIO_PAGES  8
 
 static struct kmem_cache *_crypt_io_pool;
 
@@ -848,12 +847,11 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size,
                }
 
                /*
-                * if additional pages cannot be allocated without waiting,
-                * return a partially allocated bio, the caller will then try
-                * to allocate additional bios while submitting this partial bio
+                * If additional pages cannot be allocated without waiting,
+                * return a partially-allocated bio.  The caller will then try
+                * to allocate more bios while submitting this partial bio.
                 */
-               if (i == (MIN_BIO_PAGES - 1))
-                       gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT;
+               gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT;
 
                len = (size > PAGE_SIZE) ? PAGE_SIZE : size;
 
@@ -1046,16 +1044,14 @@ static void kcryptd_queue_io(struct dm_crypt_io *io)
        queue_work(cc->io_queue, &io->work);
 }
 
-static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io,
-                                         int error, int async)
+static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io, int async)
 {
        struct bio *clone = io->ctx.bio_out;
        struct crypt_config *cc = io->target->private;
 
-       if (unlikely(error < 0)) {
+       if (unlikely(io->error < 0)) {
                crypt_free_buffer_pages(cc, clone);
                bio_put(clone);
-               io->error = -EIO;
                crypt_dec_pending(io);
                return;
        }
@@ -1106,12 +1102,16 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
                sector += bio_sectors(clone);
 
                crypt_inc_pending(io);
+
                r = crypt_convert(cc, &io->ctx);
+               if (r < 0)
+                       io->error = -EIO;
+
                crypt_finished = atomic_dec_and_test(&io->ctx.pending);
 
                /* Encryption was already finished, submit io now */
                if (crypt_finished) {
-                       kcryptd_crypt_write_io_submit(io, r, 0);
+                       kcryptd_crypt_write_io_submit(io, 0);
 
                        /*
                         * If there was an error, do not try next fragments.
@@ -1162,11 +1162,8 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
        crypt_dec_pending(io);
 }
 
-static void kcryptd_crypt_read_done(struct dm_crypt_io *io, int error)
+static void kcryptd_crypt_read_done(struct dm_crypt_io *io)
 {
-       if (unlikely(error < 0))
-               io->error = -EIO;
-
        crypt_dec_pending(io);
 }
 
@@ -1181,9 +1178,11 @@ static void kcryptd_crypt_read_convert(struct dm_crypt_io *io)
                           io->sector);
 
        r = crypt_convert(cc, &io->ctx);
+       if (r < 0)
+               io->error = -EIO;
 
        if (atomic_dec_and_test(&io->ctx.pending))
-               kcryptd_crypt_read_done(io, r);
+               kcryptd_crypt_read_done(io);
 
        crypt_dec_pending(io);
 }
@@ -1204,15 +1203,18 @@ static void kcryptd_async_done(struct crypto_async_request *async_req,
        if (!error && cc->iv_gen_ops && cc->iv_gen_ops->post)
                error = cc->iv_gen_ops->post(cc, iv_of_dmreq(cc, dmreq), dmreq);
 
+       if (error < 0)
+               io->error = -EIO;
+
        mempool_free(req_of_dmreq(cc, dmreq), cc->req_pool);
 
        if (!atomic_dec_and_test(&ctx->pending))
                return;
 
        if (bio_data_dir(io->base_bio) == READ)
-               kcryptd_crypt_read_done(io, error);
+               kcryptd_crypt_read_done(io);
        else
-               kcryptd_crypt_write_io_submit(io, error, 1);
+               kcryptd_crypt_write_io_submit(io, 1);
 }
 
 static void kcryptd_crypt(struct work_struct *work)
@@ -1413,6 +1415,7 @@ static int crypt_ctr_cipher(struct dm_target *ti,
        char *tmp, *cipher, *chainmode, *ivmode, *ivopts, *keycount;
        char *cipher_api = NULL;
        int cpu, ret = -EINVAL;
+       char dummy;
 
        /* Convert to crypto api definition? */
        if (strchr(cipher_in, '(')) {
@@ -1434,7 +1437,7 @@ static int crypt_ctr_cipher(struct dm_target *ti,
 
        if (!keycount)
                cc->tfms_count = 1;
-       else if (sscanf(keycount, "%u", &cc->tfms_count) != 1 ||
+       else if (sscanf(keycount, "%u%c", &cc->tfms_count, &dummy) != 1 ||
                 !is_power_of_2(cc->tfms_count)) {
                ti->error = "Bad cipher key count specification";
                return -EINVAL;
@@ -1579,6 +1582,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        int ret;
        struct dm_arg_set as;
        const char *opt_string;
+       char dummy;
 
        static struct dm_arg _args[] = {
                {0, 1, "Invalid number of feature args"},
@@ -1636,7 +1640,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        }
 
        ret = -EINVAL;
-       if (sscanf(argv[2], "%llu", &tmpll) != 1) {
+       if (sscanf(argv[2], "%llu%c", &tmpll, &dummy) != 1) {
                ti->error = "Invalid iv_offset sector";
                goto bad;
        }
@@ -1647,7 +1651,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
                goto bad;
        }
 
-       if (sscanf(argv[4], "%llu", &tmpll) != 1) {
+       if (sscanf(argv[4], "%llu%c", &tmpll, &dummy) != 1) {
                ti->error = "Invalid device sector";
                goto bad;
        }
index f18375dcedd99e0a878eff957c73e5f9d0ffd73a..2dc22dddb2ae31abe4b5bb2371dfb8eaedfeec73 100644 (file)
@@ -131,6 +131,7 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 {
        struct delay_c *dc;
        unsigned long long tmpll;
+       char dummy;
 
        if (argc != 3 && argc != 6) {
                ti->error = "requires exactly 3 or 6 arguments";
@@ -145,13 +146,13 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
        dc->reads = dc->writes = 0;
 
-       if (sscanf(argv[1], "%llu", &tmpll) != 1) {
+       if (sscanf(argv[1], "%llu%c", &tmpll, &dummy) != 1) {
                ti->error = "Invalid device sector";
                goto bad;
        }
        dc->start_read = tmpll;
 
-       if (sscanf(argv[2], "%u", &dc->read_delay) != 1) {
+       if (sscanf(argv[2], "%u%c", &dc->read_delay, &dummy) != 1) {
                ti->error = "Invalid delay";
                goto bad;
        }
@@ -166,13 +167,13 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        if (argc == 3)
                goto out;
 
-       if (sscanf(argv[4], "%llu", &tmpll) != 1) {
+       if (sscanf(argv[4], "%llu%c", &tmpll, &dummy) != 1) {
                ti->error = "Invalid write device sector";
                goto bad_dev_read;
        }
        dc->start_write = tmpll;
 
-       if (sscanf(argv[5], "%u", &dc->write_delay) != 1) {
+       if (sscanf(argv[5], "%u%c", &dc->write_delay, &dummy) != 1) {
                ti->error = "Invalid write delay";
                goto bad_dev_read;
        }
index 042e71996569b963a6d9ec1addd4ae5aab97a23c..aa70f7d43a1ab87750cee933d244eb098cb8d92b 100644 (file)
@@ -283,7 +283,7 @@ int dm_exception_store_init(void)
        return 0;
 
 persistent_fail:
-       dm_persistent_snapshot_exit();
+       dm_transient_snapshot_exit();
 transient_fail:
        return r;
 }
index b280c433e4a08196c0fe3d5166d9fb9f0879704f..ac49c01f1a44bc6264ab50fcb1f7ba34bf271346 100644 (file)
@@ -160,6 +160,7 @@ static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        unsigned long long tmpll;
        struct dm_arg_set as;
        const char *devname;
+       char dummy;
 
        as.argc = argc;
        as.argv = argv;
@@ -178,7 +179,7 @@ static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
        devname = dm_shift_arg(&as);
 
-       if (sscanf(dm_shift_arg(&as), "%llu", &tmpll) != 1) {
+       if (sscanf(dm_shift_arg(&as), "%llu%c", &tmpll, &dummy) != 1) {
                ti->error = "Invalid device sector";
                goto bad;
        }
index 1ce84ed0b765a889b74b94674da2aff4ffe0fd1c..a1a3e6df17b82624490952b0c91f94a9ea1e1f86 100644 (file)
@@ -880,6 +880,7 @@ static int dev_set_geometry(struct dm_ioctl *param, size_t param_size)
        struct hd_geometry geometry;
        unsigned long indata[4];
        char *geostr = (char *) param + param->data_start;
+       char dummy;
 
        md = find_device(param);
        if (!md)
@@ -891,8 +892,8 @@ static int dev_set_geometry(struct dm_ioctl *param, size_t param_size)
                goto out;
        }
 
-       x = sscanf(geostr, "%lu %lu %lu %lu", indata,
-                  indata + 1, indata + 2, indata + 3);
+       x = sscanf(geostr, "%lu %lu %lu %lu%c", indata,
+                  indata + 1, indata + 2, indata + 3, &dummy);
 
        if (x != 4) {
                DMWARN("Unable to interpret geometry settings.");
index 9728839f844a8b71a34c04b7317a9dc1fe1497ba..3639eeab60421fb1829c2f70ee7bd7e193267463 100644 (file)
@@ -29,6 +29,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 {
        struct linear_c *lc;
        unsigned long long tmp;
+       char dummy;
 
        if (argc != 2) {
                ti->error = "Invalid argument count";
@@ -41,7 +42,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
                return -ENOMEM;
        }
 
-       if (sscanf(argv[1], "%llu", &tmp) != 1) {
+       if (sscanf(argv[1], "%llu%c", &tmp, &dummy) != 1) {
                ti->error = "dm-linear: Invalid device sector";
                goto bad;
        }
index 3b52bb72bd1f0cb8717798c121008a76784b9aa0..65ebaebf502bdbc6e35f0cec1272589e2e5e000e 100644 (file)
@@ -369,6 +369,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
        unsigned int region_count;
        size_t bitset_size, buf_size;
        int r;
+       char dummy;
 
        if (argc < 1 || argc > 2) {
                DMWARN("wrong number of arguments to dirty region log");
@@ -387,7 +388,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
                }
        }
 
-       if (sscanf(argv[0], "%u", &region_size) != 1 ||
+       if (sscanf(argv[0], "%u%c", &region_size, &dummy) != 1 ||
            !_check_region_size(ti, region_size)) {
                DMWARN("invalid region size %s", argv[0]);
                return -EINVAL;
index 801d92d237cfc316ee81c08ab4c261f7113f2690..922a3385eead41be43bafeac56a4e417ad7b919d 100644 (file)
@@ -226,6 +226,27 @@ static void free_multipath(struct multipath *m)
        kfree(m);
 }
 
+static int set_mapinfo(struct multipath *m, union map_info *info)
+{
+       struct dm_mpath_io *mpio;
+
+       mpio = mempool_alloc(m->mpio_pool, GFP_ATOMIC);
+       if (!mpio)
+               return -ENOMEM;
+
+       memset(mpio, 0, sizeof(*mpio));
+       info->ptr = mpio;
+
+       return 0;
+}
+
+static void clear_mapinfo(struct multipath *m, union map_info *info)
+{
+       struct dm_mpath_io *mpio = info->ptr;
+
+       info->ptr = NULL;
+       mempool_free(mpio, m->mpio_pool);
+}
 
 /*-----------------------------------------------
  * Path selection
@@ -341,13 +362,14 @@ static int __must_push_back(struct multipath *m)
 }
 
 static int map_io(struct multipath *m, struct request *clone,
-                 struct dm_mpath_io *mpio, unsigned was_queued)
+                 union map_info *map_context, unsigned was_queued)
 {
        int r = DM_MAPIO_REMAPPED;
        size_t nr_bytes = blk_rq_bytes(clone);
        unsigned long flags;
        struct pgpath *pgpath;
        struct block_device *bdev;
+       struct dm_mpath_io *mpio = map_context->ptr;
 
        spin_lock_irqsave(&m->lock, flags);
 
@@ -423,7 +445,6 @@ static void dispatch_queued_ios(struct multipath *m)
 {
        int r;
        unsigned long flags;
-       struct dm_mpath_io *mpio;
        union map_info *info;
        struct request *clone, *n;
        LIST_HEAD(cl);
@@ -436,16 +457,15 @@ static void dispatch_queued_ios(struct multipath *m)
                list_del_init(&clone->queuelist);
 
                info = dm_get_rq_mapinfo(clone);
-               mpio = info->ptr;
 
-               r = map_io(m, clone, mpio, 1);
+               r = map_io(m, clone, info, 1);
                if (r < 0) {
-                       mempool_free(mpio, m->mpio_pool);
+                       clear_mapinfo(m, info);
                        dm_kill_unmapped_request(clone, r);
                } else if (r == DM_MAPIO_REMAPPED)
                        dm_dispatch_request(clone);
                else if (r == DM_MAPIO_REQUEUE) {
-                       mempool_free(mpio, m->mpio_pool);
+                       clear_mapinfo(m, info);
                        dm_requeue_unmapped_request(clone);
                }
        }
@@ -908,20 +928,16 @@ static int multipath_map(struct dm_target *ti, struct request *clone,
                         union map_info *map_context)
 {
        int r;
-       struct dm_mpath_io *mpio;
        struct multipath *m = (struct multipath *) ti->private;
 
-       mpio = mempool_alloc(m->mpio_pool, GFP_ATOMIC);
-       if (!mpio)
+       if (set_mapinfo(m, map_context) < 0)
                /* ENOMEM, requeue */
                return DM_MAPIO_REQUEUE;
-       memset(mpio, 0, sizeof(*mpio));
 
-       map_context->ptr = mpio;
        clone->cmd_flags |= REQ_FAILFAST_TRANSPORT;
-       r = map_io(m, clone, mpio, 0);
+       r = map_io(m, clone, map_context, 0);
        if (r < 0 || r == DM_MAPIO_REQUEUE)
-               mempool_free(mpio, m->mpio_pool);
+               clear_mapinfo(m, map_context);
 
        return r;
 }
@@ -1054,8 +1070,9 @@ static int switch_pg_num(struct multipath *m, const char *pgstr)
        struct priority_group *pg;
        unsigned pgnum;
        unsigned long flags;
+       char dummy;
 
-       if (!pgstr || (sscanf(pgstr, "%u", &pgnum) != 1) || !pgnum ||
+       if (!pgstr || (sscanf(pgstr, "%u%c", &pgnum, &dummy) != 1) || !pgnum ||
            (pgnum > m->nr_priority_groups)) {
                DMWARN("invalid PG number supplied to switch_pg_num");
                return -EINVAL;
@@ -1085,8 +1102,9 @@ static int bypass_pg_num(struct multipath *m, const char *pgstr, int bypassed)
 {
        struct priority_group *pg;
        unsigned pgnum;
+       char dummy;
 
-       if (!pgstr || (sscanf(pgstr, "%u", &pgnum) != 1) || !pgnum ||
+       if (!pgstr || (sscanf(pgstr, "%u%c", &pgnum, &dummy) != 1) || !pgnum ||
            (pgnum > m->nr_priority_groups)) {
                DMWARN("invalid PG number supplied to bypass_pg");
                return -EINVAL;
@@ -1261,13 +1279,15 @@ static int multipath_end_io(struct dm_target *ti, struct request *clone,
        struct path_selector *ps;
        int r;
 
+       BUG_ON(!mpio);
+
        r  = do_end_io(m, clone, error, mpio);
        if (pgpath) {
                ps = &pgpath->pg->ps;
                if (ps->type->end_io)
                        ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes);
        }
-       mempool_free(mpio, m->mpio_pool);
+       clear_mapinfo(m, map_context);
 
        return r;
 }
index 03a837aa5ce64ebd38af21d324e77b14cd5f4434..3941fae0de9fd79f875f5ea32ce14b03cb76d8aa 100644 (file)
@@ -112,6 +112,7 @@ static int ql_add_path(struct path_selector *ps, struct dm_path *path,
        struct selector *s = ps->context;
        struct path_info *pi;
        unsigned repeat_count = QL_MIN_IO;
+       char dummy;
 
        /*
         * Arguments: [<repeat_count>]
@@ -123,7 +124,7 @@ static int ql_add_path(struct path_selector *ps, struct dm_path *path,
                return -EINVAL;
        }
 
-       if ((argc == 1) && (sscanf(argv[0], "%u", &repeat_count) != 1)) {
+       if ((argc == 1) && (sscanf(argv[0], "%u%c", &repeat_count, &dummy) != 1)) {
                *error = "queue-length ps: invalid repeat count";
                return -EINVAL;
        }
index c5a875d7b8827833b70eb76a818ee9bf55073f53..b0ba52459ed7381d4a802acb94e69df02f979149 100644 (file)
@@ -604,7 +604,9 @@ static int read_disk_sb(struct md_rdev *rdev, int size)
                return 0;
 
        if (!sync_page_io(rdev, 0, size, rdev->sb_page, READ, 1)) {
-               DMERR("Failed to read device superblock");
+               DMERR("Failed to read superblock of device at position %d",
+                     rdev->raid_disk);
+               set_bit(Faulty, &rdev->flags);
                return -EINVAL;
        }
 
@@ -855,9 +857,25 @@ static int super_validate(struct mddev *mddev, struct md_rdev *rdev)
 static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
 {
        int ret;
+       unsigned redundancy = 0;
+       struct raid_dev *dev;
        struct md_rdev *rdev, *freshest;
        struct mddev *mddev = &rs->md;
 
+       switch (rs->raid_type->level) {
+       case 1:
+               redundancy = rs->md.raid_disks - 1;
+               break;
+       case 4:
+       case 5:
+       case 6:
+               redundancy = rs->raid_type->parity_devs;
+               break;
+       default:
+               ti->error = "Unknown RAID type";
+               return -EINVAL;
+       }
+
        freshest = NULL;
        rdev_for_each(rdev, mddev) {
                if (!rdev->meta_bdev)
@@ -872,6 +890,37 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
                case 0:
                        break;
                default:
+                       dev = container_of(rdev, struct raid_dev, rdev);
+                       if (redundancy--) {
+                               if (dev->meta_dev)
+                                       dm_put_device(ti, dev->meta_dev);
+
+                               dev->meta_dev = NULL;
+                               rdev->meta_bdev = NULL;
+
+                               if (rdev->sb_page)
+                                       put_page(rdev->sb_page);
+
+                               rdev->sb_page = NULL;
+
+                               rdev->sb_loaded = 0;
+
+                               /*
+                                * We might be able to salvage the data device
+                                * even though the meta device has failed.  For
+                                * now, we behave as though '- -' had been
+                                * set for this device in the table.
+                                */
+                               if (dev->data_dev)
+                                       dm_put_device(ti, dev->data_dev);
+
+                               dev->data_dev = NULL;
+                               rdev->bdev = NULL;
+
+                               list_del(&rdev->same_set);
+
+                               continue;
+                       }
                        ti->error = "Failed to load superblock";
                        return ret;
                }
@@ -1214,7 +1263,7 @@ static void raid_resume(struct dm_target *ti)
 
 static struct target_type raid_target = {
        .name = "raid",
-       .version = {1, 1, 0},
+       .version = {1, 2, 0},
        .module = THIS_MODULE,
        .ctr = raid_ctr,
        .dtr = raid_dtr,
index 9bfd057be6869dff2aba03a498b20e1c148ba4c8..d039de8322f0a314fca492df4b932289d9033e0d 100644 (file)
@@ -924,8 +924,9 @@ static int get_mirror(struct mirror_set *ms, struct dm_target *ti,
                      unsigned int mirror, char **argv)
 {
        unsigned long long offset;
+       char dummy;
 
-       if (sscanf(argv[1], "%llu", &offset) != 1) {
+       if (sscanf(argv[1], "%llu%c", &offset, &dummy) != 1) {
                ti->error = "Invalid offset";
                return -EINVAL;
        }
@@ -953,13 +954,14 @@ static struct dm_dirty_log *create_dirty_log(struct dm_target *ti,
 {
        unsigned param_count;
        struct dm_dirty_log *dl;
+       char dummy;
 
        if (argc < 2) {
                ti->error = "Insufficient mirror log arguments";
                return NULL;
        }
 
-       if (sscanf(argv[1], "%u", &param_count) != 1) {
+       if (sscanf(argv[1], "%u%c", &param_count, &dummy) != 1) {
                ti->error = "Invalid mirror log argument count";
                return NULL;
        }
@@ -986,13 +988,14 @@ static int parse_features(struct mirror_set *ms, unsigned argc, char **argv,
 {
        unsigned num_features;
        struct dm_target *ti = ms->ti;
+       char dummy;
 
        *args_used = 0;
 
        if (!argc)
                return 0;
 
-       if (sscanf(argv[0], "%u", &num_features) != 1) {
+       if (sscanf(argv[0], "%u%c", &num_features, &dummy) != 1) {
                ti->error = "Invalid number of features";
                return -EINVAL;
        }
@@ -1036,6 +1039,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        unsigned int nr_mirrors, m, args_used;
        struct mirror_set *ms;
        struct dm_dirty_log *dl;
+       char dummy;
 
        dl = create_dirty_log(ti, argc, argv, &args_used);
        if (!dl)
@@ -1044,7 +1048,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        argv += args_used;
        argc -= args_used;
 
-       if (!argc || sscanf(argv[0], "%u", &nr_mirrors) != 1 ||
+       if (!argc || sscanf(argv[0], "%u%c", &nr_mirrors, &dummy) != 1 ||
            nr_mirrors < 2 || nr_mirrors > DM_KCOPYD_MAX_REGIONS + 1) {
                ti->error = "Invalid number of mirrors";
                dm_dirty_log_destroy(dl);
index 27f1d423b76c0582f77001a1265526fc29db2a47..6ab1192cdd5fcf766f67b76ff7a6678db4fab8a7 100644 (file)
@@ -114,6 +114,7 @@ static int rr_add_path(struct path_selector *ps, struct dm_path *path,
        struct selector *s = (struct selector *) ps->context;
        struct path_info *pi;
        unsigned repeat_count = RR_MIN_IO;
+       char dummy;
 
        if (argc > 1) {
                *error = "round-robin ps: incorrect number of arguments";
@@ -121,7 +122,7 @@ static int rr_add_path(struct path_selector *ps, struct dm_path *path,
        }
 
        /* First path argument is number of I/Os before switching path */
-       if ((argc == 1) && (sscanf(argv[0], "%u", &repeat_count) != 1)) {
+       if ((argc == 1) && (sscanf(argv[0], "%u%c", &repeat_count, &dummy) != 1)) {
                *error = "round-robin ps: invalid repeat count";
                return -EINVAL;
        }
index 59883bd78214b0428a819ee19d397f460bfc6d8b..9df8f6bd64181fd9d4b1f1eb425d247b501fcb66 100644 (file)
@@ -110,6 +110,7 @@ static int st_add_path(struct path_selector *ps, struct dm_path *path,
        struct path_info *pi;
        unsigned repeat_count = ST_MIN_IO;
        unsigned relative_throughput = 1;
+       char dummy;
 
        /*
         * Arguments: [<repeat_count> [<relative_throughput>]]
@@ -128,13 +129,13 @@ static int st_add_path(struct path_selector *ps, struct dm_path *path,
                return -EINVAL;
        }
 
-       if (argc && (sscanf(argv[0], "%u", &repeat_count) != 1)) {
+       if (argc && (sscanf(argv[0], "%u%c", &repeat_count, &dummy) != 1)) {
                *error = "service-time ps: invalid repeat count";
                return -EINVAL;
        }
 
        if ((argc == 2) &&
-           (sscanf(argv[1], "%u", &relative_throughput) != 1 ||
+           (sscanf(argv[1], "%u%c", &relative_throughput, &dummy) != 1 ||
             relative_throughput > ST_MAX_RELATIVE_THROUGHPUT)) {
                *error = "service-time ps: invalid relative_throughput value";
                return -EINVAL;
index 3d80cf0c152d1b4fedd46a0b67773842218a326c..35c94ff24ad5867917ed715a8ce387fbb8d3b150 100644 (file)
@@ -75,8 +75,9 @@ static int get_stripe(struct dm_target *ti, struct stripe_c *sc,
                      unsigned int stripe, char **argv)
 {
        unsigned long long start;
+       char dummy;
 
-       if (sscanf(argv[1], "%llu", &start) != 1)
+       if (sscanf(argv[1], "%llu%c", &start, &dummy) != 1)
                return -EINVAL;
 
        if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table),
index 63cc54289afff481c1d4ce8a9cc2e6749de8b5de..2e227fbf1622c075c6fc543f5b2d30fb2bf7dbd7 100644 (file)
@@ -268,8 +268,7 @@ void dm_table_destroy(struct dm_table *t)
        vfree(t->highs);
 
        /* free the device list */
-       if (t->devices.next != &t->devices)
-               free_devices(&t->devices);
+       free_devices(&t->devices);
 
        dm_free_md_mempools(t->mempools);
 
@@ -464,10 +463,11 @@ int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode,
        struct dm_dev_internal *dd;
        unsigned int major, minor;
        struct dm_table *t = ti->table;
+       char dummy;
 
        BUG_ON(!t);
 
-       if (sscanf(path, "%u:%u", &major, &minor) == 2) {
+       if (sscanf(path, "%u:%u%c", &major, &minor, &dummy) == 2) {
                /* Extract the major/minor numbers */
                dev = MKDEV(major, minor);
                if (MAJOR(dev) != major || MINOR(dev) != minor)
@@ -842,9 +842,10 @@ static int validate_next_arg(struct dm_arg *arg, struct dm_arg_set *arg_set,
                             unsigned *value, char **error, unsigned grouped)
 {
        const char *arg_str = dm_shift_arg(arg_set);
+       char dummy;
 
        if (!arg_str ||
-           (sscanf(arg_str, "%u", value) != 1) ||
+           (sscanf(arg_str, "%u%c", value, &dummy) != 1) ||
            (*value < arg->min) ||
            (*value > arg->max) ||
            (grouped && arg_set->argc < *value)) {
index 237571af77fdfcf552b7061fa13ff291514c86b7..737d38865b693fb0288306477587f4e0d52f6cfa 100644 (file)
@@ -614,7 +614,7 @@ static int __commit_transaction(struct dm_pool_metadata *pmd)
        if (r < 0)
                goto out;
 
-       r = dm_sm_root_size(pmd->metadata_sm, &data_len);
+       r = dm_sm_root_size(pmd->data_sm, &data_len);
        if (r < 0)
                goto out;
 
@@ -713,6 +713,9 @@ struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev,
        if (r)
                goto bad;
 
+       if (bdev_size > THIN_METADATA_MAX_SECTORS)
+               bdev_size = THIN_METADATA_MAX_SECTORS;
+
        disk_super = dm_block_data(sblock);
        disk_super->magic = cpu_to_le64(THIN_SUPERBLOCK_MAGIC);
        disk_super->version = cpu_to_le32(THIN_VERSION);
index 859c16896877795732ad89df1b854bd2242d019b..ed4725e67c96fbae52f1ce48c28d79f0a02075a4 100644 (file)
 
 #define THIN_METADATA_BLOCK_SIZE 4096
 
+/*
+ * The metadata device is currently limited in size.
+ *
+ * We have one block of index, which can hold 255 index entries.  Each
+ * index entry contains allocation info about 16k metadata blocks.
+ */
+#define THIN_METADATA_MAX_SECTORS (255 * (1 << 14) * (THIN_METADATA_BLOCK_SIZE / (1 << SECTOR_SHIFT)))
+
+/*
+ * A metadata device larger than 16GB triggers a warning.
+ */
+#define THIN_METADATA_MAX_SECTORS_WARNING (16 * (1024 * 1024 * 1024 >> SECTOR_SHIFT))
+
 /*----------------------------------------------------------------*/
 
 struct dm_pool_metadata;
index c3087575fef0ffe5330c261a721abddef3f6771e..213ae32a0fc4f7eadacb923a5f1f2ac69163f5c7 100644 (file)
@@ -23,6 +23,7 @@
 #define DEFERRED_SET_SIZE 64
 #define MAPPING_POOL_SIZE 1024
 #define PRISON_CELLS 1024
+#define COMMIT_PERIOD HZ
 
 /*
  * The block size of the device holding pool data must be
 #define DATA_DEV_BLOCK_SIZE_MIN_SECTORS (64 * 1024 >> SECTOR_SHIFT)
 #define DATA_DEV_BLOCK_SIZE_MAX_SECTORS (1024 * 1024 * 1024 >> SECTOR_SHIFT)
 
-/*
- * The metadata device is currently limited in size.  The limitation is
- * checked lower down in dm-space-map-metadata, but we also check it here
- * so we can fail early.
- *
- * We have one block of index, which can hold 255 index entries.  Each
- * index entry contains allocation info about 16k metadata blocks.
- */
-#define METADATA_DEV_MAX_SECTORS (255 * (1 << 14) * (THIN_METADATA_BLOCK_SIZE / (1 << SECTOR_SHIFT)))
-
 /*
  * Device id is restricted to 24 bits.
  */
@@ -72,7 +63,7 @@
  * missed out if the io covers the block. (schedule_copy).
  *
  * iv) insert the new mapping into the origin's btree
- * (process_prepared_mappings).  This act of inserting breaks some
+ * (process_prepared_mapping).  This act of inserting breaks some
  * sharing of btree nodes between the two devices.  Breaking sharing only
  * effects the btree of that specific device.  Btrees for the other
  * devices that share the block never change.  The btree for the origin
@@ -124,7 +115,7 @@ struct cell {
        struct hlist_node list;
        struct bio_prison *prison;
        struct cell_key key;
-       unsigned count;
+       struct bio *holder;
        struct bio_list bios;
 };
 
@@ -220,54 +211,59 @@ static struct cell *__search_bucket(struct hlist_head *bucket,
  * This may block if a new cell needs allocating.  You must ensure that
  * cells will be unlocked even if the calling thread is blocked.
  *
- * Returns the number of entries in the cell prior to the new addition
- * or < 0 on failure.
+ * Returns 1 if the cell was already held, 0 if @inmate is the new holder.
  */
 static int bio_detain(struct bio_prison *prison, struct cell_key *key,
                      struct bio *inmate, struct cell **ref)
 {
-       int r;
+       int r = 1;
        unsigned long flags;
        uint32_t hash = hash_key(prison, key);
-       struct cell *uninitialized_var(cell), *cell2 = NULL;
+       struct cell *cell, *cell2;
 
        BUG_ON(hash > prison->nr_buckets);
 
        spin_lock_irqsave(&prison->lock, flags);
+
        cell = __search_bucket(prison->cells + hash, key);
+       if (cell) {
+               bio_list_add(&cell->bios, inmate);
+               goto out;
+       }
 
-       if (!cell) {
-               /*
-                * Allocate a new cell
-                */
-               spin_unlock_irqrestore(&prison->lock, flags);
-               cell2 = mempool_alloc(prison->cell_pool, GFP_NOIO);
-               spin_lock_irqsave(&prison->lock, flags);
+       /*
+        * Allocate a new cell
+        */
+       spin_unlock_irqrestore(&prison->lock, flags);
+       cell2 = mempool_alloc(prison->cell_pool, GFP_NOIO);
+       spin_lock_irqsave(&prison->lock, flags);
 
-               /*
-                * We've been unlocked, so we have to double check that
-                * nobody else has inserted this cell in the meantime.
-                */
-               cell = __search_bucket(prison->cells + hash, key);
+       /*
+        * We've been unlocked, so we have to double check that
+        * nobody else has inserted this cell in the meantime.
+        */
+       cell = __search_bucket(prison->cells + hash, key);
+       if (cell) {
+               mempool_free(cell2, prison->cell_pool);
+               bio_list_add(&cell->bios, inmate);
+               goto out;
+       }
 
-               if (!cell) {
-                       cell = cell2;
-                       cell2 = NULL;
+       /*
+        * Use new cell.
+        */
+       cell = cell2;
 
-                       cell->prison = prison;
-                       memcpy(&cell->key, key, sizeof(cell->key));
-                       cell->count = 0;
-                       bio_list_init(&cell->bios);
-                       hlist_add_head(&cell->list, prison->cells + hash);
-               }
-       }
+       cell->prison = prison;
+       memcpy(&cell->key, key, sizeof(cell->key));
+       cell->holder = inmate;
+       bio_list_init(&cell->bios);
+       hlist_add_head(&cell->list, prison->cells + hash);
 
-       r = cell->count++;
-       bio_list_add(&cell->bios, inmate);
-       spin_unlock_irqrestore(&prison->lock, flags);
+       r = 0;
 
-       if (cell2)
-               mempool_free(cell2, prison->cell_pool);
+out:
+       spin_unlock_irqrestore(&prison->lock, flags);
 
        *ref = cell;
 
@@ -283,8 +279,8 @@ static void __cell_release(struct cell *cell, struct bio_list *inmates)
 
        hlist_del(&cell->list);
 
-       if (inmates)
-               bio_list_merge(inmates, &cell->bios);
+       bio_list_add(inmates, cell->holder);
+       bio_list_merge(inmates, &cell->bios);
 
        mempool_free(cell, prison->cell_pool);
 }
@@ -305,22 +301,44 @@ static void cell_release(struct cell *cell, struct bio_list *bios)
  * bio may be in the cell.  This function releases the cell, and also does
  * a sanity check.
  */
+static void __cell_release_singleton(struct cell *cell, struct bio *bio)
+{
+       hlist_del(&cell->list);
+       BUG_ON(cell->holder != bio);
+       BUG_ON(!bio_list_empty(&cell->bios));
+}
+
 static void cell_release_singleton(struct cell *cell, struct bio *bio)
 {
-       struct bio_prison *prison = cell->prison;
-       struct bio_list bios;
-       struct bio *b;
        unsigned long flags;
-
-       bio_list_init(&bios);
+       struct bio_prison *prison = cell->prison;
 
        spin_lock_irqsave(&prison->lock, flags);
-       __cell_release(cell, &bios);
+       __cell_release_singleton(cell, bio);
        spin_unlock_irqrestore(&prison->lock, flags);
+}
+
+/*
+ * Sometimes we don't want the holder, just the additional bios.
+ */
+static void __cell_release_no_holder(struct cell *cell, struct bio_list *inmates)
+{
+       struct bio_prison *prison = cell->prison;
+
+       hlist_del(&cell->list);
+       bio_list_merge(inmates, &cell->bios);
 
-       b = bio_list_pop(&bios);
-       BUG_ON(b != bio);
-       BUG_ON(!bio_list_empty(&bios));
+       mempool_free(cell, prison->cell_pool);
+}
+
+static void cell_release_no_holder(struct cell *cell, struct bio_list *inmates)
+{
+       unsigned long flags;
+       struct bio_prison *prison = cell->prison;
+
+       spin_lock_irqsave(&prison->lock, flags);
+       __cell_release_no_holder(cell, inmates);
+       spin_unlock_irqrestore(&prison->lock, flags);
 }
 
 static void cell_error(struct cell *cell)
@@ -471,6 +489,13 @@ static void build_virtual_key(struct dm_thin_device *td, dm_block_t b,
  * devices.
  */
 struct new_mapping;
+
+struct pool_features {
+       unsigned zero_new_blocks:1;
+       unsigned discard_enabled:1;
+       unsigned discard_passdown:1;
+};
+
 struct pool {
        struct list_head list;
        struct dm_target *ti;   /* Only set if a pool target is bound */
@@ -484,7 +509,7 @@ struct pool {
        dm_block_t offset_mask;
        dm_block_t low_water_blocks;
 
-       unsigned zero_new_blocks:1;
+       struct pool_features pf;
        unsigned low_water_triggered:1; /* A dm event has been sent */
        unsigned no_free_space:1;       /* A -ENOSPC warning has been issued */
 
@@ -493,17 +518,21 @@ struct pool {
 
        struct workqueue_struct *wq;
        struct work_struct worker;
+       struct delayed_work waker;
 
        unsigned ref_count;
+       unsigned long last_commit_jiffies;
 
        spinlock_t lock;
        struct bio_list deferred_bios;
        struct bio_list deferred_flush_bios;
        struct list_head prepared_mappings;
+       struct list_head prepared_discards;
 
        struct bio_list retry_on_resume_list;
 
-       struct deferred_set ds; /* FIXME: move to thin_c */
+       struct deferred_set shared_read_ds;
+       struct deferred_set all_io_ds;
 
        struct new_mapping *next_mapping;
        mempool_t *mapping_pool;
@@ -521,7 +550,7 @@ struct pool_c {
        struct dm_target_callbacks callbacks;
 
        dm_block_t low_water_blocks;
-       unsigned zero_new_blocks:1;
+       struct pool_features pf;
 };
 
 /*
@@ -529,6 +558,7 @@ struct pool_c {
  */
 struct thin_c {
        struct dm_dev *pool_dev;
+       struct dm_dev *origin_dev;
        dm_thin_id dev_id;
 
        struct pool *pool;
@@ -597,6 +627,13 @@ static struct pool *__pool_table_lookup_metadata_dev(struct block_device *md_dev
 
 /*----------------------------------------------------------------*/
 
+struct endio_hook {
+       struct thin_c *tc;
+       struct deferred_entry *shared_read_entry;
+       struct deferred_entry *all_io_entry;
+       struct new_mapping *overwrite_mapping;
+};
+
 static void __requeue_bio_list(struct thin_c *tc, struct bio_list *master)
 {
        struct bio *bio;
@@ -607,7 +644,8 @@ static void __requeue_bio_list(struct thin_c *tc, struct bio_list *master)
        bio_list_init(master);
 
        while ((bio = bio_list_pop(&bios))) {
-               if (dm_get_mapinfo(bio)->ptr == tc)
+               struct endio_hook *h = dm_get_mapinfo(bio)->ptr;
+               if (h->tc == tc)
                        bio_endio(bio, DM_ENDIO_REQUEUE);
                else
                        bio_list_add(master, bio);
@@ -646,14 +684,16 @@ static void remap(struct thin_c *tc, struct bio *bio, dm_block_t block)
                (bio->bi_sector & pool->offset_mask);
 }
 
-static void remap_and_issue(struct thin_c *tc, struct bio *bio,
-                           dm_block_t block)
+static void remap_to_origin(struct thin_c *tc, struct bio *bio)
+{
+       bio->bi_bdev = tc->origin_dev->bdev;
+}
+
+static void issue(struct thin_c *tc, struct bio *bio)
 {
        struct pool *pool = tc->pool;
        unsigned long flags;
 
-       remap(tc, bio, block);
-
        /*
         * Batch together any FUA/FLUSH bios we find and then issue
         * a single commit for them in process_deferred_bios().
@@ -666,6 +706,19 @@ static void remap_and_issue(struct thin_c *tc, struct bio *bio,
                generic_make_request(bio);
 }
 
+static void remap_to_origin_and_issue(struct thin_c *tc, struct bio *bio)
+{
+       remap_to_origin(tc, bio);
+       issue(tc, bio);
+}
+
+static void remap_and_issue(struct thin_c *tc, struct bio *bio,
+                           dm_block_t block)
+{
+       remap(tc, bio, block);
+       issue(tc, bio);
+}
+
 /*
  * wake_worker() is used when new work is queued and when pool_resume is
  * ready to continue deferred IO processing.
@@ -680,21 +733,17 @@ static void wake_worker(struct pool *pool)
 /*
  * Bio endio functions.
  */
-struct endio_hook {
-       struct thin_c *tc;
-       bio_end_io_t *saved_bi_end_io;
-       struct deferred_entry *entry;
-};
-
 struct new_mapping {
        struct list_head list;
 
-       int prepared;
+       unsigned quiesced:1;
+       unsigned prepared:1;
+       unsigned pass_discard:1;
 
        struct thin_c *tc;
        dm_block_t virt_block;
        dm_block_t data_block;
-       struct cell *cell;
+       struct cell *cell, *cell2;
        int err;
 
        /*
@@ -711,7 +760,7 @@ static void __maybe_add_mapping(struct new_mapping *m)
 {
        struct pool *pool = m->tc->pool;
 
-       if (list_empty(&m->list) && m->prepared) {
+       if (m->quiesced && m->prepared) {
                list_add(&m->list, &pool->prepared_mappings);
                wake_worker(pool);
        }
@@ -734,7 +783,8 @@ static void copy_complete(int read_err, unsigned long write_err, void *context)
 static void overwrite_endio(struct bio *bio, int err)
 {
        unsigned long flags;
-       struct new_mapping *m = dm_get_mapinfo(bio)->ptr;
+       struct endio_hook *h = dm_get_mapinfo(bio)->ptr;
+       struct new_mapping *m = h->overwrite_mapping;
        struct pool *pool = m->tc->pool;
 
        m->err = err;
@@ -745,31 +795,6 @@ static void overwrite_endio(struct bio *bio, int err)
        spin_unlock_irqrestore(&pool->lock, flags);
 }
 
-static void shared_read_endio(struct bio *bio, int err)
-{
-       struct list_head mappings;
-       struct new_mapping *m, *tmp;
-       struct endio_hook *h = dm_get_mapinfo(bio)->ptr;
-       unsigned long flags;
-       struct pool *pool = h->tc->pool;
-
-       bio->bi_end_io = h->saved_bi_end_io;
-       bio_endio(bio, err);
-
-       INIT_LIST_HEAD(&mappings);
-       ds_dec(h->entry, &mappings);
-
-       spin_lock_irqsave(&pool->lock, flags);
-       list_for_each_entry_safe(m, tmp, &mappings, list) {
-               list_del(&m->list);
-               INIT_LIST_HEAD(&m->list);
-               __maybe_add_mapping(m);
-       }
-       spin_unlock_irqrestore(&pool->lock, flags);
-
-       mempool_free(h, pool->endio_hook_pool);
-}
-
 /*----------------------------------------------------------------*/
 
 /*
@@ -800,21 +825,16 @@ static void cell_defer(struct thin_c *tc, struct cell *cell,
  * Same as cell_defer above, except it omits one particular detainee,
  * a write bio that covers the block and has already been processed.
  */
-static void cell_defer_except(struct thin_c *tc, struct cell *cell,
-                             struct bio *exception)
+static void cell_defer_except(struct thin_c *tc, struct cell *cell)
 {
        struct bio_list bios;
-       struct bio *bio;
        struct pool *pool = tc->pool;
        unsigned long flags;
 
        bio_list_init(&bios);
-       cell_release(cell, &bios);
 
        spin_lock_irqsave(&pool->lock, flags);
-       while ((bio = bio_list_pop(&bios)))
-               if (bio != exception)
-                       bio_list_add(&pool->deferred_bios, bio);
+       cell_release_no_holder(cell, &pool->deferred_bios);
        spin_unlock_irqrestore(&pool->lock, flags);
 
        wake_worker(pool);
@@ -854,7 +874,7 @@ static void process_prepared_mapping(struct new_mapping *m)
         * the bios in the cell.
         */
        if (bio) {
-               cell_defer_except(tc, m->cell, bio);
+               cell_defer_except(tc, m->cell);
                bio_endio(bio, 0);
        } else
                cell_defer(tc, m->cell, m->data_block);
@@ -863,7 +883,30 @@ static void process_prepared_mapping(struct new_mapping *m)
        mempool_free(m, tc->pool->mapping_pool);
 }
 
-static void process_prepared_mappings(struct pool *pool)
+static void process_prepared_discard(struct new_mapping *m)
+{
+       int r;
+       struct thin_c *tc = m->tc;
+
+       r = dm_thin_remove_block(tc->td, m->virt_block);
+       if (r)
+               DMERR("dm_thin_remove_block() failed");
+
+       /*
+        * Pass the discard down to the underlying device?
+        */
+       if (m->pass_discard)
+               remap_and_issue(tc, m->bio, m->data_block);
+       else
+               bio_endio(m->bio, 0);
+
+       cell_defer_except(tc, m->cell);
+       cell_defer_except(tc, m->cell2);
+       mempool_free(m, tc->pool->mapping_pool);
+}
+
+static void process_prepared(struct pool *pool, struct list_head *head,
+                            void (*fn)(struct new_mapping *))
 {
        unsigned long flags;
        struct list_head maps;
@@ -871,21 +914,27 @@ static void process_prepared_mappings(struct pool *pool)
 
        INIT_LIST_HEAD(&maps);
        spin_lock_irqsave(&pool->lock, flags);
-       list_splice_init(&pool->prepared_mappings, &maps);
+       list_splice_init(head, &maps);
        spin_unlock_irqrestore(&pool->lock, flags);
 
        list_for_each_entry_safe(m, tmp, &maps, list)
-               process_prepared_mapping(m);
+               fn(m);
 }
 
 /*
  * Deferred bio jobs.
  */
-static int io_overwrites_block(struct pool *pool, struct bio *bio)
+static int io_overlaps_block(struct pool *pool, struct bio *bio)
 {
-       return ((bio_data_dir(bio) == WRITE) &&
-               !(bio->bi_sector & pool->offset_mask)) &&
+       return !(bio->bi_sector & pool->offset_mask) &&
                (bio->bi_size == (pool->sectors_per_block << SECTOR_SHIFT));
+
+}
+
+static int io_overwrites_block(struct pool *pool, struct bio *bio)
+{
+       return (bio_data_dir(bio) == WRITE) &&
+               io_overlaps_block(pool, bio);
 }
 
 static void save_and_set_endio(struct bio *bio, bio_end_io_t **save,
@@ -917,7 +966,8 @@ static struct new_mapping *get_next_mapping(struct pool *pool)
 }
 
 static void schedule_copy(struct thin_c *tc, dm_block_t virt_block,
-                         dm_block_t data_origin, dm_block_t data_dest,
+                         struct dm_dev *origin, dm_block_t data_origin,
+                         dm_block_t data_dest,
                          struct cell *cell, struct bio *bio)
 {
        int r;
@@ -925,6 +975,7 @@ static void schedule_copy(struct thin_c *tc, dm_block_t virt_block,
        struct new_mapping *m = get_next_mapping(pool);
 
        INIT_LIST_HEAD(&m->list);
+       m->quiesced = 0;
        m->prepared = 0;
        m->tc = tc;
        m->virt_block = virt_block;
@@ -933,7 +984,8 @@ static void schedule_copy(struct thin_c *tc, dm_block_t virt_block,
        m->err = 0;
        m->bio = NULL;
 
-       ds_add_work(&pool->ds, &m->list);
+       if (!ds_add_work(&pool->shared_read_ds, &m->list))
+               m->quiesced = 1;
 
        /*
         * IO to pool_dev remaps to the pool target's data_dev.
@@ -942,14 +994,15 @@ static void schedule_copy(struct thin_c *tc, dm_block_t virt_block,
         * bio immediately. Otherwise we use kcopyd to clone the data first.
         */
        if (io_overwrites_block(pool, bio)) {
+               struct endio_hook *h = dm_get_mapinfo(bio)->ptr;
+               h->overwrite_mapping = m;
                m->bio = bio;
                save_and_set_endio(bio, &m->saved_bi_end_io, overwrite_endio);
-               dm_get_mapinfo(bio)->ptr = m;
                remap_and_issue(tc, bio, data_dest);
        } else {
                struct dm_io_region from, to;
 
-               from.bdev = tc->pool_dev->bdev;
+               from.bdev = origin->bdev;
                from.sector = data_origin * pool->sectors_per_block;
                from.count = pool->sectors_per_block;
 
@@ -967,6 +1020,22 @@ static void schedule_copy(struct thin_c *tc, dm_block_t virt_block,
        }
 }
 
+static void schedule_internal_copy(struct thin_c *tc, dm_block_t virt_block,
+                                  dm_block_t data_origin, dm_block_t data_dest,
+                                  struct cell *cell, struct bio *bio)
+{
+       schedule_copy(tc, virt_block, tc->pool_dev,
+                     data_origin, data_dest, cell, bio);
+}
+
+static void schedule_external_copy(struct thin_c *tc, dm_block_t virt_block,
+                                  dm_block_t data_dest,
+                                  struct cell *cell, struct bio *bio)
+{
+       schedule_copy(tc, virt_block, tc->origin_dev,
+                     virt_block, data_dest, cell, bio);
+}
+
 static void schedule_zero(struct thin_c *tc, dm_block_t virt_block,
                          dm_block_t data_block, struct cell *cell,
                          struct bio *bio)
@@ -975,6 +1044,7 @@ static void schedule_zero(struct thin_c *tc, dm_block_t virt_block,
        struct new_mapping *m = get_next_mapping(pool);
 
        INIT_LIST_HEAD(&m->list);
+       m->quiesced = 1;
        m->prepared = 0;
        m->tc = tc;
        m->virt_block = virt_block;
@@ -988,13 +1058,14 @@ static void schedule_zero(struct thin_c *tc, dm_block_t virt_block,
         * zeroing pre-existing data, we can issue the bio immediately.
         * Otherwise we use kcopyd to zero the data first.
         */
-       if (!pool->zero_new_blocks)
+       if (!pool->pf.zero_new_blocks)
                process_prepared_mapping(m);
 
        else if (io_overwrites_block(pool, bio)) {
+               struct endio_hook *h = dm_get_mapinfo(bio)->ptr;
+               h->overwrite_mapping = m;
                m->bio = bio;
                save_and_set_endio(bio, &m->saved_bi_end_io, overwrite_endio);
-               dm_get_mapinfo(bio)->ptr = m;
                remap_and_issue(tc, bio, data_block);
 
        } else {
@@ -1081,7 +1152,8 @@ static int alloc_data_block(struct thin_c *tc, dm_block_t *result)
  */
 static void retry_on_resume(struct bio *bio)
 {
-       struct thin_c *tc = dm_get_mapinfo(bio)->ptr;
+       struct endio_hook *h = dm_get_mapinfo(bio)->ptr;
+       struct thin_c *tc = h->tc;
        struct pool *pool = tc->pool;
        unsigned long flags;
 
@@ -1102,6 +1174,86 @@ static void no_space(struct cell *cell)
                retry_on_resume(bio);
 }
 
+static void process_discard(struct thin_c *tc, struct bio *bio)
+{
+       int r;
+       struct pool *pool = tc->pool;
+       struct cell *cell, *cell2;
+       struct cell_key key, key2;
+       dm_block_t block = get_bio_block(tc, bio);
+       struct dm_thin_lookup_result lookup_result;
+       struct new_mapping *m;
+
+       build_virtual_key(tc->td, block, &key);
+       if (bio_detain(tc->pool->prison, &key, bio, &cell))
+               return;
+
+       r = dm_thin_find_block(tc->td, block, 1, &lookup_result);
+       switch (r) {
+       case 0:
+               /*
+                * Check nobody is fiddling with this pool block.  This can
+                * happen if someone's in the process of breaking sharing
+                * on this block.
+                */
+               build_data_key(tc->td, lookup_result.block, &key2);
+               if (bio_detain(tc->pool->prison, &key2, bio, &cell2)) {
+                       cell_release_singleton(cell, bio);
+                       break;
+               }
+
+               if (io_overlaps_block(pool, bio)) {
+                       /*
+                        * IO may still be going to the destination block.  We must
+                        * quiesce before we can do the removal.
+                        */
+                       m = get_next_mapping(pool);
+                       m->tc = tc;
+                       m->pass_discard = (!lookup_result.shared) & pool->pf.discard_passdown;
+                       m->virt_block = block;
+                       m->data_block = lookup_result.block;
+                       m->cell = cell;
+                       m->cell2 = cell2;
+                       m->err = 0;
+                       m->bio = bio;
+
+                       if (!ds_add_work(&pool->all_io_ds, &m->list)) {
+                               list_add(&m->list, &pool->prepared_discards);
+                               wake_worker(pool);
+                       }
+               } else {
+                       /*
+                        * This path is hit if people are ignoring
+                        * limits->discard_granularity.  It ignores any
+                        * part of the discard that is in a subsequent
+                        * block.
+                        */
+                       sector_t offset = bio->bi_sector - (block << pool->block_shift);
+                       unsigned remaining = (pool->sectors_per_block - offset) << 9;
+                       bio->bi_size = min(bio->bi_size, remaining);
+
+                       cell_release_singleton(cell, bio);
+                       cell_release_singleton(cell2, bio);
+                       remap_and_issue(tc, bio, lookup_result.block);
+               }
+               break;
+
+       case -ENODATA:
+               /*
+                * It isn't provisioned, just forget it.
+                */
+               cell_release_singleton(cell, bio);
+               bio_endio(bio, 0);
+               break;
+
+       default:
+               DMERR("discard: find block unexpectedly returned %d", r);
+               cell_release_singleton(cell, bio);
+               bio_io_error(bio);
+               break;
+       }
+}
+
 static void break_sharing(struct thin_c *tc, struct bio *bio, dm_block_t block,
                          struct cell_key *key,
                          struct dm_thin_lookup_result *lookup_result,
@@ -1113,8 +1265,8 @@ static void break_sharing(struct thin_c *tc, struct bio *bio, dm_block_t block,
        r = alloc_data_block(tc, &data_block);
        switch (r) {
        case 0:
-               schedule_copy(tc, block, lookup_result->block,
-                             data_block, cell, bio);
+               schedule_internal_copy(tc, block, lookup_result->block,
+                                      data_block, cell, bio);
                break;
 
        case -ENOSPC:
@@ -1147,13 +1299,9 @@ static void process_shared_bio(struct thin_c *tc, struct bio *bio,
        if (bio_data_dir(bio) == WRITE)
                break_sharing(tc, bio, block, &key, lookup_result, cell);
        else {
-               struct endio_hook *h;
-               h = mempool_alloc(pool->endio_hook_pool, GFP_NOIO);
+               struct endio_hook *h = dm_get_mapinfo(bio)->ptr;
 
-               h->tc = tc;
-               h->entry = ds_inc(&pool->ds);
-               save_and_set_endio(bio, &h->saved_bi_end_io, shared_read_endio);
-               dm_get_mapinfo(bio)->ptr = h;
+               h->shared_read_entry = ds_inc(&pool->shared_read_ds);
 
                cell_release_singleton(cell, bio);
                remap_and_issue(tc, bio, lookup_result->block);
@@ -1188,7 +1336,10 @@ static void provision_block(struct thin_c *tc, struct bio *bio, dm_block_t block
        r = alloc_data_block(tc, &data_block);
        switch (r) {
        case 0:
-               schedule_zero(tc, block, data_block, cell, bio);
+               if (tc->origin_dev)
+                       schedule_external_copy(tc, block, data_block, cell, bio);
+               else
+                       schedule_zero(tc, block, data_block, cell, bio);
                break;
 
        case -ENOSPC:
@@ -1239,16 +1390,27 @@ static void process_bio(struct thin_c *tc, struct bio *bio)
                break;
 
        case -ENODATA:
-               provision_block(tc, bio, block, cell);
+               if (bio_data_dir(bio) == READ && tc->origin_dev) {
+                       cell_release_singleton(cell, bio);
+                       remap_to_origin_and_issue(tc, bio);
+               } else
+                       provision_block(tc, bio, block, cell);
                break;
 
        default:
                DMERR("dm_thin_find_block() failed, error = %d", r);
+               cell_release_singleton(cell, bio);
                bio_io_error(bio);
                break;
        }
 }
 
+static int need_commit_due_to_time(struct pool *pool)
+{
+       return jiffies < pool->last_commit_jiffies ||
+              jiffies > pool->last_commit_jiffies + COMMIT_PERIOD;
+}
+
 static void process_deferred_bios(struct pool *pool)
 {
        unsigned long flags;
@@ -1264,7 +1426,9 @@ static void process_deferred_bios(struct pool *pool)
        spin_unlock_irqrestore(&pool->lock, flags);
 
        while ((bio = bio_list_pop(&bios))) {
-               struct thin_c *tc = dm_get_mapinfo(bio)->ptr;
+               struct endio_hook *h = dm_get_mapinfo(bio)->ptr;
+               struct thin_c *tc = h->tc;
+
                /*
                 * If we've got no free new_mapping structs, and processing
                 * this bio might require one, we pause until there are some
@@ -1277,7 +1441,11 @@ static void process_deferred_bios(struct pool *pool)
 
                        break;
                }
-               process_bio(tc, bio);
+
+               if (bio->bi_rw & REQ_DISCARD)
+                       process_discard(tc, bio);
+               else
+                       process_bio(tc, bio);
        }
 
        /*
@@ -1290,7 +1458,7 @@ static void process_deferred_bios(struct pool *pool)
        bio_list_init(&pool->deferred_flush_bios);
        spin_unlock_irqrestore(&pool->lock, flags);
 
-       if (bio_list_empty(&bios))
+       if (bio_list_empty(&bios) && !need_commit_due_to_time(pool))
                return;
 
        r = dm_pool_commit_metadata(pool->pmd);
@@ -1301,6 +1469,7 @@ static void process_deferred_bios(struct pool *pool)
                        bio_io_error(bio);
                return;
        }
+       pool->last_commit_jiffies = jiffies;
 
        while ((bio = bio_list_pop(&bios)))
                generic_make_request(bio);
@@ -1310,10 +1479,22 @@ static void do_worker(struct work_struct *ws)
 {
        struct pool *pool = container_of(ws, struct pool, worker);
 
-       process_prepared_mappings(pool);
+       process_prepared(pool, &pool->prepared_mappings, process_prepared_mapping);
+       process_prepared(pool, &pool->prepared_discards, process_prepared_discard);
        process_deferred_bios(pool);
 }
 
+/*
+ * We want to commit periodically so that not too much
+ * unwritten data builds up.
+ */
+static void do_waker(struct work_struct *ws)
+{
+       struct pool *pool = container_of(to_delayed_work(ws), struct pool, waker);
+       wake_worker(pool);
+       queue_delayed_work(pool->wq, &pool->waker, COMMIT_PERIOD);
+}
+
 /*----------------------------------------------------------------*/
 
 /*
@@ -1335,6 +1516,19 @@ static void thin_defer_bio(struct thin_c *tc, struct bio *bio)
        wake_worker(pool);
 }
 
+static struct endio_hook *thin_hook_bio(struct thin_c *tc, struct bio *bio)
+{
+       struct pool *pool = tc->pool;
+       struct endio_hook *h = mempool_alloc(pool->endio_hook_pool, GFP_NOIO);
+
+       h->tc = tc;
+       h->shared_read_entry = NULL;
+       h->all_io_entry = bio->bi_rw & REQ_DISCARD ? NULL : ds_inc(&pool->all_io_ds);
+       h->overwrite_mapping = NULL;
+
+       return h;
+}
+
 /*
  * Non-blocking function called from the thin target's map function.
  */
@@ -1347,12 +1541,8 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio,
        struct dm_thin_device *td = tc->td;
        struct dm_thin_lookup_result result;
 
-       /*
-        * Save the thin context for easy access from the deferred bio later.
-        */
-       map_context->ptr = tc;
-
-       if (bio->bi_rw & (REQ_FLUSH | REQ_FUA)) {
+       map_context->ptr = thin_hook_bio(tc, bio);
+       if (bio->bi_rw & (REQ_DISCARD | REQ_FLUSH | REQ_FUA)) {
                thin_defer_bio(tc, bio);
                return DM_MAPIO_SUBMITTED;
        }
@@ -1434,7 +1624,7 @@ static int bind_control_target(struct pool *pool, struct dm_target *ti)
 
        pool->ti = ti;
        pool->low_water_blocks = pt->low_water_blocks;
-       pool->zero_new_blocks = pt->zero_new_blocks;
+       pool->pf = pt->pf;
 
        return 0;
 }
@@ -1448,6 +1638,14 @@ static void unbind_control_target(struct pool *pool, struct dm_target *ti)
 /*----------------------------------------------------------------
  * Pool creation
  *--------------------------------------------------------------*/
+/* Initialize pool features. */
+static void pool_features_init(struct pool_features *pf)
+{
+       pf->zero_new_blocks = 1;
+       pf->discard_enabled = 1;
+       pf->discard_passdown = 1;
+}
+
 static void __pool_destroy(struct pool *pool)
 {
        __pool_table_remove(pool);
@@ -1495,7 +1693,7 @@ static struct pool *pool_create(struct mapped_device *pool_md,
        pool->block_shift = ffs(block_size) - 1;
        pool->offset_mask = block_size - 1;
        pool->low_water_blocks = 0;
-       pool->zero_new_blocks = 1;
+       pool_features_init(&pool->pf);
        pool->prison = prison_create(PRISON_CELLS);
        if (!pool->prison) {
                *error = "Error creating pool's bio prison";
@@ -1523,14 +1721,17 @@ static struct pool *pool_create(struct mapped_device *pool_md,
        }
 
        INIT_WORK(&pool->worker, do_worker);
+       INIT_DELAYED_WORK(&pool->waker, do_waker);
        spin_lock_init(&pool->lock);
        bio_list_init(&pool->deferred_bios);
        bio_list_init(&pool->deferred_flush_bios);
        INIT_LIST_HEAD(&pool->prepared_mappings);
+       INIT_LIST_HEAD(&pool->prepared_discards);
        pool->low_water_triggered = 0;
        pool->no_free_space = 0;
        bio_list_init(&pool->retry_on_resume_list);
-       ds_init(&pool->ds);
+       ds_init(&pool->shared_read_ds);
+       ds_init(&pool->all_io_ds);
 
        pool->next_mapping = NULL;
        pool->mapping_pool =
@@ -1549,6 +1750,7 @@ static struct pool *pool_create(struct mapped_device *pool_md,
                goto bad_endio_hook_pool;
        }
        pool->ref_count = 1;
+       pool->last_commit_jiffies = jiffies;
        pool->pool_md = pool_md;
        pool->md_dev = metadata_dev;
        __pool_table_insert(pool);
@@ -1588,7 +1790,8 @@ static void __pool_dec(struct pool *pool)
 
 static struct pool *__pool_find(struct mapped_device *pool_md,
                                struct block_device *metadata_dev,
-                               unsigned long block_size, char **error)
+                               unsigned long block_size, char **error,
+                               int *created)
 {
        struct pool *pool = __pool_table_lookup_metadata_dev(metadata_dev);
 
@@ -1604,8 +1807,10 @@ static struct pool *__pool_find(struct mapped_device *pool_md,
                                return ERR_PTR(-EINVAL);
                        __pool_inc(pool);
 
-               } else
+               } else {
                        pool = pool_create(pool_md, metadata_dev, block_size, error);
+                       *created = 1;
+               }
        }
 
        return pool;
@@ -1629,10 +1834,6 @@ static void pool_dtr(struct dm_target *ti)
        mutex_unlock(&dm_thin_pool_table.mutex);
 }
 
-struct pool_features {
-       unsigned zero_new_blocks:1;
-};
-
 static int parse_pool_features(struct dm_arg_set *as, struct pool_features *pf,
                               struct dm_target *ti)
 {
@@ -1641,7 +1842,7 @@ static int parse_pool_features(struct dm_arg_set *as, struct pool_features *pf,
        const char *arg_name;
 
        static struct dm_arg _args[] = {
-               {0, 1, "Invalid number of pool feature arguments"},
+               {0, 3, "Invalid number of pool feature arguments"},
        };
 
        /*
@@ -1661,6 +1862,12 @@ static int parse_pool_features(struct dm_arg_set *as, struct pool_features *pf,
                if (!strcasecmp(arg_name, "skip_block_zeroing")) {
                        pf->zero_new_blocks = 0;
                        continue;
+               } else if (!strcasecmp(arg_name, "ignore_discard")) {
+                       pf->discard_enabled = 0;
+                       continue;
+               } else if (!strcasecmp(arg_name, "no_discard_passdown")) {
+                       pf->discard_passdown = 0;
+                       continue;
                }
 
                ti->error = "Unrecognised pool feature requested";
@@ -1678,10 +1885,12 @@ static int parse_pool_features(struct dm_arg_set *as, struct pool_features *pf,
  *
  * Optional feature arguments are:
  *          skip_block_zeroing: skips the zeroing of newly-provisioned blocks.
+ *          ignore_discard: disable discard
+ *          no_discard_passdown: don't pass discards down to the data device
  */
 static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
 {
-       int r;
+       int r, pool_created = 0;
        struct pool_c *pt;
        struct pool *pool;
        struct pool_features pf;
@@ -1691,6 +1900,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
        dm_block_t low_water_blocks;
        struct dm_dev *metadata_dev;
        sector_t metadata_dev_size;
+       char b[BDEVNAME_SIZE];
 
        /*
         * FIXME Remove validation from scope of lock.
@@ -1712,11 +1922,9 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
        }
 
        metadata_dev_size = i_size_read(metadata_dev->bdev->bd_inode) >> SECTOR_SHIFT;
-       if (metadata_dev_size > METADATA_DEV_MAX_SECTORS) {
-               ti->error = "Metadata device is too large";
-               r = -EINVAL;
-               goto out_metadata;
-       }
+       if (metadata_dev_size > THIN_METADATA_MAX_SECTORS_WARNING)
+               DMWARN("Metadata device %s is larger than %u sectors: excess space will not be used.",
+                      bdevname(metadata_dev->bdev, b), THIN_METADATA_MAX_SECTORS);
 
        r = dm_get_device(ti, argv[1], FMODE_READ | FMODE_WRITE, &data_dev);
        if (r) {
@@ -1742,8 +1950,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
        /*
         * Set default pool features.
         */
-       memset(&pf, 0, sizeof(pf));
-       pf.zero_new_blocks = 1;
+       pool_features_init(&pf);
 
        dm_consume_args(&as, 4);
        r = parse_pool_features(&as, &pf, ti);
@@ -1757,20 +1964,58 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
        }
 
        pool = __pool_find(dm_table_get_md(ti->table), metadata_dev->bdev,
-                          block_size, &ti->error);
+                          block_size, &ti->error, &pool_created);
        if (IS_ERR(pool)) {
                r = PTR_ERR(pool);
                goto out_free_pt;
        }
 
+       /*
+        * 'pool_created' reflects whether this is the first table load.
+        * Top level discard support is not allowed to be changed after
+        * initial load.  This would require a pool reload to trigger thin
+        * device changes.
+        */
+       if (!pool_created && pf.discard_enabled != pool->pf.discard_enabled) {
+               ti->error = "Discard support cannot be disabled once enabled";
+               r = -EINVAL;
+               goto out_flags_changed;
+       }
+
+       /*
+        * If discard_passdown was enabled verify that the data device
+        * supports discards.  Disable discard_passdown if not; otherwise
+        * -EOPNOTSUPP will be returned.
+        */
+       if (pf.discard_passdown) {
+               struct request_queue *q = bdev_get_queue(data_dev->bdev);
+               if (!q || !blk_queue_discard(q)) {
+                       DMWARN("Discard unsupported by data device: Disabling discard passdown.");
+                       pf.discard_passdown = 0;
+               }
+       }
+
        pt->pool = pool;
        pt->ti = ti;
        pt->metadata_dev = metadata_dev;
        pt->data_dev = data_dev;
        pt->low_water_blocks = low_water_blocks;
-       pt->zero_new_blocks = pf.zero_new_blocks;
+       pt->pf = pf;
        ti->num_flush_requests = 1;
-       ti->num_discard_requests = 0;
+       /*
+        * Only need to enable discards if the pool should pass
+        * them down to the data device.  The thin device's discard
+        * processing will cause mappings to be removed from the btree.
+        */
+       if (pf.discard_enabled && pf.discard_passdown) {
+               ti->num_discard_requests = 1;
+               /*
+                * Setting 'discards_supported' circumvents the normal
+                * stacking of discard limits (this keeps the pool and
+                * thin devices' discard limits consistent).
+                */
+               ti->discards_supported = 1;
+       }
        ti->private = pt;
 
        pt->callbacks.congested_fn = pool_is_congested;
@@ -1780,6 +2025,8 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
 
        return 0;
 
+out_flags_changed:
+       __pool_dec(pool);
 out_free_pt:
        kfree(pt);
 out:
@@ -1878,7 +2125,7 @@ static void pool_resume(struct dm_target *ti)
        __requeue_bios(pool);
        spin_unlock_irqrestore(&pool->lock, flags);
 
-       wake_worker(pool);
+       do_waker(&pool->waker.work);
 }
 
 static void pool_postsuspend(struct dm_target *ti)
@@ -1887,6 +2134,7 @@ static void pool_postsuspend(struct dm_target *ti)
        struct pool_c *pt = ti->private;
        struct pool *pool = pt->pool;
 
+       cancel_delayed_work(&pool->waker);
        flush_workqueue(pool->wq);
 
        r = dm_pool_commit_metadata(pool->pmd);
@@ -2067,7 +2315,7 @@ static int pool_message(struct dm_target *ti, unsigned argc, char **argv)
 static int pool_status(struct dm_target *ti, status_type_t type,
                       char *result, unsigned maxlen)
 {
-       int r;
+       int r, count;
        unsigned sz = 0;
        uint64_t transaction_id;
        dm_block_t nr_free_blocks_data;
@@ -2130,10 +2378,19 @@ static int pool_status(struct dm_target *ti, status_type_t type,
                       (unsigned long)pool->sectors_per_block,
                       (unsigned long long)pt->low_water_blocks);
 
-               DMEMIT("%u ", !pool->zero_new_blocks);
+               count = !pool->pf.zero_new_blocks + !pool->pf.discard_enabled +
+                       !pool->pf.discard_passdown;
+               DMEMIT("%u ", count);
 
-               if (!pool->zero_new_blocks)
+               if (!pool->pf.zero_new_blocks)
                        DMEMIT("skip_block_zeroing ");
+
+               if (!pool->pf.discard_enabled)
+                       DMEMIT("ignore_discard ");
+
+               if (!pool->pf.discard_passdown)
+                       DMEMIT("no_discard_passdown ");
+
                break;
        }
 
@@ -2162,6 +2419,21 @@ static int pool_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
        return min(max_size, q->merge_bvec_fn(q, bvm, biovec));
 }
 
+static void set_discard_limits(struct pool *pool, struct queue_limits *limits)
+{
+       /*
+        * FIXME: these limits may be incompatible with the pool's data device
+        */
+       limits->max_discard_sectors = pool->sectors_per_block;
+
+       /*
+        * This is just a hint, and not enforced.  We have to cope with
+        * bios that overlap 2 blocks.
+        */
+       limits->discard_granularity = pool->sectors_per_block << SECTOR_SHIFT;
+       limits->discard_zeroes_data = pool->pf.zero_new_blocks;
+}
+
 static void pool_io_hints(struct dm_target *ti, struct queue_limits *limits)
 {
        struct pool_c *pt = ti->private;
@@ -2169,13 +2441,15 @@ static void pool_io_hints(struct dm_target *ti, struct queue_limits *limits)
 
        blk_limits_io_min(limits, 0);
        blk_limits_io_opt(limits, pool->sectors_per_block << SECTOR_SHIFT);
+       if (pool->pf.discard_enabled)
+               set_discard_limits(pool, limits);
 }
 
 static struct target_type pool_target = {
        .name = "thin-pool",
        .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE |
                    DM_TARGET_IMMUTABLE,
-       .version = {1, 0, 0},
+       .version = {1, 1, 0},
        .module = THIS_MODULE,
        .ctr = pool_ctr,
        .dtr = pool_dtr,
@@ -2202,6 +2476,8 @@ static void thin_dtr(struct dm_target *ti)
        __pool_dec(tc->pool);
        dm_pool_close_thin_device(tc->td);
        dm_put_device(ti, tc->pool_dev);
+       if (tc->origin_dev)
+               dm_put_device(ti, tc->origin_dev);
        kfree(tc);
 
        mutex_unlock(&dm_thin_pool_table.mutex);
@@ -2210,21 +2486,25 @@ static void thin_dtr(struct dm_target *ti)
 /*
  * Thin target parameters:
  *
- * <pool_dev> <dev_id>
+ * <pool_dev> <dev_id> [origin_dev]
  *
  * pool_dev: the path to the pool (eg, /dev/mapper/my_pool)
  * dev_id: the internal device identifier
+ * origin_dev: a device external to the pool that should act as the origin
+ *
+ * If the pool device has discards disabled, they get disabled for the thin
+ * device as well.
  */
 static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv)
 {
        int r;
        struct thin_c *tc;
-       struct dm_dev *pool_dev;
+       struct dm_dev *pool_dev, *origin_dev;
        struct mapped_device *pool_md;
 
        mutex_lock(&dm_thin_pool_table.mutex);
 
-       if (argc != 2) {
+       if (argc != 2 && argc != 3) {
                ti->error = "Invalid argument count";
                r = -EINVAL;
                goto out_unlock;
@@ -2237,6 +2517,15 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv)
                goto out_unlock;
        }
 
+       if (argc == 3) {
+               r = dm_get_device(ti, argv[2], FMODE_READ, &origin_dev);
+               if (r) {
+                       ti->error = "Error opening origin device";
+                       goto bad_origin_dev;
+               }
+               tc->origin_dev = origin_dev;
+       }
+
        r = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &pool_dev);
        if (r) {
                ti->error = "Error opening pool device";
@@ -2273,8 +2562,12 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv)
 
        ti->split_io = tc->pool->sectors_per_block;
        ti->num_flush_requests = 1;
-       ti->num_discard_requests = 0;
-       ti->discards_supported = 0;
+
+       /* In case the pool supports discards, pass them on. */
+       if (tc->pool->pf.discard_enabled) {
+               ti->discards_supported = 1;
+               ti->num_discard_requests = 1;
+       }
 
        dm_put(pool_md);
 
@@ -2289,6 +2582,9 @@ bad_pool_lookup:
 bad_common:
        dm_put_device(ti, tc->pool_dev);
 bad_pool_dev:
+       if (tc->origin_dev)
+               dm_put_device(ti, tc->origin_dev);
+bad_origin_dev:
        kfree(tc);
 out_unlock:
        mutex_unlock(&dm_thin_pool_table.mutex);
@@ -2299,11 +2595,46 @@ out_unlock:
 static int thin_map(struct dm_target *ti, struct bio *bio,
                    union map_info *map_context)
 {
-       bio->bi_sector -= ti->begin;
+       bio->bi_sector = dm_target_offset(ti, bio->bi_sector);
 
        return thin_bio_map(ti, bio, map_context);
 }
 
+static int thin_endio(struct dm_target *ti,
+                     struct bio *bio, int err,
+                     union map_info *map_context)
+{
+       unsigned long flags;
+       struct endio_hook *h = map_context->ptr;
+       struct list_head work;
+       struct new_mapping *m, *tmp;
+       struct pool *pool = h->tc->pool;
+
+       if (h->shared_read_entry) {
+               INIT_LIST_HEAD(&work);
+               ds_dec(h->shared_read_entry, &work);
+
+               spin_lock_irqsave(&pool->lock, flags);
+               list_for_each_entry_safe(m, tmp, &work, list) {
+                       list_del(&m->list);
+                       m->quiesced = 1;
+                       __maybe_add_mapping(m);
+               }
+               spin_unlock_irqrestore(&pool->lock, flags);
+       }
+
+       if (h->all_io_entry) {
+               INIT_LIST_HEAD(&work);
+               ds_dec(h->all_io_entry, &work);
+               list_for_each_entry_safe(m, tmp, &work, list)
+                       list_add(&m->list, &pool->prepared_discards);
+       }
+
+       mempool_free(h, pool->endio_hook_pool);
+
+       return 0;
+}
+
 static void thin_postsuspend(struct dm_target *ti)
 {
        if (dm_noflush_suspending(ti))
@@ -2347,6 +2678,8 @@ static int thin_status(struct dm_target *ti, status_type_t type,
                        DMEMIT("%s %lu",
                               format_dev_t(buf, tc->pool_dev->bdev->bd_dev),
                               (unsigned long) tc->dev_id);
+                       if (tc->origin_dev)
+                               DMEMIT(" %s", format_dev_t(buf, tc->origin_dev->bdev->bd_dev));
                        break;
                }
        }
@@ -2377,18 +2710,21 @@ static int thin_iterate_devices(struct dm_target *ti,
 static void thin_io_hints(struct dm_target *ti, struct queue_limits *limits)
 {
        struct thin_c *tc = ti->private;
+       struct pool *pool = tc->pool;
 
        blk_limits_io_min(limits, 0);
-       blk_limits_io_opt(limits, tc->pool->sectors_per_block << SECTOR_SHIFT);
+       blk_limits_io_opt(limits, pool->sectors_per_block << SECTOR_SHIFT);
+       set_discard_limits(pool, limits);
 }
 
 static struct target_type thin_target = {
        .name = "thin",
-       .version = {1, 0, 0},
+       .version = {1, 1, 0},
        .module = THIS_MODULE,
        .ctr = thin_ctr,
        .dtr = thin_dtr,
        .map = thin_map,
+       .end_io = thin_endio,
        .postsuspend = thin_postsuspend,
        .status = thin_status,
        .iterate_devices = thin_iterate_devices,
diff --git a/drivers/md/dm-verity.c b/drivers/md/dm-verity.c
new file mode 100644 (file)
index 0000000..fa365d3
--- /dev/null
@@ -0,0 +1,913 @@
+/*
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * Author: Mikulas Patocka <mpatocka@redhat.com>
+ *
+ * Based on Chromium dm-verity driver (C) 2011 The Chromium OS Authors
+ *
+ * This file is released under the GPLv2.
+ *
+ * In the file "/sys/module/dm_verity/parameters/prefetch_cluster" you can set
+ * default prefetch value. Data are read in "prefetch_cluster" chunks from the
+ * hash device. Setting this greatly improves performance when data and hash
+ * are on the same disk on different partitions on devices with poor random
+ * access behavior.
+ */
+
+#include "dm-bufio.h"
+
+#include <linux/module.h>
+#include <linux/device-mapper.h>
+#include <crypto/hash.h>
+
+#define DM_MSG_PREFIX                  "verity"
+
+#define DM_VERITY_IO_VEC_INLINE                16
+#define DM_VERITY_MEMPOOL_SIZE         4
+#define DM_VERITY_DEFAULT_PREFETCH_SIZE        262144
+
+#define DM_VERITY_MAX_LEVELS           63
+
+static unsigned dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE;
+
+module_param_named(prefetch_cluster, dm_verity_prefetch_cluster, uint, S_IRUGO | S_IWUSR);
+
+struct dm_verity {
+       struct dm_dev *data_dev;
+       struct dm_dev *hash_dev;
+       struct dm_target *ti;
+       struct dm_bufio_client *bufio;
+       char *alg_name;
+       struct crypto_shash *tfm;
+       u8 *root_digest;        /* digest of the root block */
+       u8 *salt;               /* salt: its size is salt_size */
+       unsigned salt_size;
+       sector_t data_start;    /* data offset in 512-byte sectors */
+       sector_t hash_start;    /* hash start in blocks */
+       sector_t data_blocks;   /* the number of data blocks */
+       sector_t hash_blocks;   /* the number of hash blocks */
+       unsigned char data_dev_block_bits;      /* log2(data blocksize) */
+       unsigned char hash_dev_block_bits;      /* log2(hash blocksize) */
+       unsigned char hash_per_block_bits;      /* log2(hashes in hash block) */
+       unsigned char levels;   /* the number of tree levels */
+       unsigned char version;
+       unsigned digest_size;   /* digest size for the current hash algorithm */
+       unsigned shash_descsize;/* the size of temporary space for crypto */
+       int hash_failed;        /* set to 1 if hash of any block failed */
+
+       mempool_t *io_mempool;  /* mempool of struct dm_verity_io */
+       mempool_t *vec_mempool; /* mempool of bio vector */
+
+       struct workqueue_struct *verify_wq;
+
+       /* starting blocks for each tree level. 0 is the lowest level. */
+       sector_t hash_level_block[DM_VERITY_MAX_LEVELS];
+};
+
+struct dm_verity_io {
+       struct dm_verity *v;
+       struct bio *bio;
+
+       /* original values of bio->bi_end_io and bio->bi_private */
+       bio_end_io_t *orig_bi_end_io;
+       void *orig_bi_private;
+
+       sector_t block;
+       unsigned n_blocks;
+
+       /* saved bio vector */
+       struct bio_vec *io_vec;
+       unsigned io_vec_size;
+
+       struct work_struct work;
+
+       /* A space for short vectors; longer vectors are allocated separately. */
+       struct bio_vec io_vec_inline[DM_VERITY_IO_VEC_INLINE];
+
+       /*
+        * Three variably-size fields follow this struct:
+        *
+        * u8 hash_desc[v->shash_descsize];
+        * u8 real_digest[v->digest_size];
+        * u8 want_digest[v->digest_size];
+        *
+        * To access them use: io_hash_desc(), io_real_digest() and io_want_digest().
+        */
+};
+
+static struct shash_desc *io_hash_desc(struct dm_verity *v, struct dm_verity_io *io)
+{
+       return (struct shash_desc *)(io + 1);
+}
+
+static u8 *io_real_digest(struct dm_verity *v, struct dm_verity_io *io)
+{
+       return (u8 *)(io + 1) + v->shash_descsize;
+}
+
+static u8 *io_want_digest(struct dm_verity *v, struct dm_verity_io *io)
+{
+       return (u8 *)(io + 1) + v->shash_descsize + v->digest_size;
+}
+
+/*
+ * Auxiliary structure appended to each dm-bufio buffer. If the value
+ * hash_verified is nonzero, hash of the block has been verified.
+ *
+ * The variable hash_verified is set to 0 when allocating the buffer, then
+ * it can be changed to 1 and it is never reset to 0 again.
+ *
+ * There is no lock around this value, a race condition can at worst cause
+ * that multiple processes verify the hash of the same buffer simultaneously
+ * and write 1 to hash_verified simultaneously.
+ * This condition is harmless, so we don't need locking.
+ */
+struct buffer_aux {
+       int hash_verified;
+};
+
+/*
+ * Initialize struct buffer_aux for a freshly created buffer.
+ */
+static void dm_bufio_alloc_callback(struct dm_buffer *buf)
+{
+       struct buffer_aux *aux = dm_bufio_get_aux_data(buf);
+
+       aux->hash_verified = 0;
+}
+
+/*
+ * Translate input sector number to the sector number on the target device.
+ */
+static sector_t verity_map_sector(struct dm_verity *v, sector_t bi_sector)
+{
+       return v->data_start + dm_target_offset(v->ti, bi_sector);
+}
+
+/*
+ * Return hash position of a specified block at a specified tree level
+ * (0 is the lowest level).
+ * The lowest "hash_per_block_bits"-bits of the result denote hash position
+ * inside a hash block. The remaining bits denote location of the hash block.
+ */
+static sector_t verity_position_at_level(struct dm_verity *v, sector_t block,
+                                        int level)
+{
+       return block >> (level * v->hash_per_block_bits);
+}
+
+static void verity_hash_at_level(struct dm_verity *v, sector_t block, int level,
+                                sector_t *hash_block, unsigned *offset)
+{
+       sector_t position = verity_position_at_level(v, block, level);
+       unsigned idx;
+
+       *hash_block = v->hash_level_block[level] + (position >> v->hash_per_block_bits);
+
+       if (!offset)
+               return;
+
+       idx = position & ((1 << v->hash_per_block_bits) - 1);
+       if (!v->version)
+               *offset = idx * v->digest_size;
+       else
+               *offset = idx << (v->hash_dev_block_bits - v->hash_per_block_bits);
+}
+
+/*
+ * Verify hash of a metadata block pertaining to the specified data block
+ * ("block" argument) at a specified level ("level" argument).
+ *
+ * On successful return, io_want_digest(v, io) contains the hash value for
+ * a lower tree level or for the data block (if we're at the lowest leve).
+ *
+ * If "skip_unverified" is true, unverified buffer is skipped and 1 is returned.
+ * If "skip_unverified" is false, unverified buffer is hashed and verified
+ * against current value of io_want_digest(v, io).
+ */
+static int verity_verify_level(struct dm_verity_io *io, sector_t block,
+                              int level, bool skip_unverified)
+{
+       struct dm_verity *v = io->v;
+       struct dm_buffer *buf;
+       struct buffer_aux *aux;
+       u8 *data;
+       int r;
+       sector_t hash_block;
+       unsigned offset;
+
+       verity_hash_at_level(v, block, level, &hash_block, &offset);
+
+       data = dm_bufio_read(v->bufio, hash_block, &buf);
+       if (unlikely(IS_ERR(data)))
+               return PTR_ERR(data);
+
+       aux = dm_bufio_get_aux_data(buf);
+
+       if (!aux->hash_verified) {
+               struct shash_desc *desc;
+               u8 *result;
+
+               if (skip_unverified) {
+                       r = 1;
+                       goto release_ret_r;
+               }
+
+               desc = io_hash_desc(v, io);
+               desc->tfm = v->tfm;
+               desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+               r = crypto_shash_init(desc);
+               if (r < 0) {
+                       DMERR("crypto_shash_init failed: %d", r);
+                       goto release_ret_r;
+               }
+
+               if (likely(v->version >= 1)) {
+                       r = crypto_shash_update(desc, v->salt, v->salt_size);
+                       if (r < 0) {
+                               DMERR("crypto_shash_update failed: %d", r);
+                               goto release_ret_r;
+                       }
+               }
+
+               r = crypto_shash_update(desc, data, 1 << v->hash_dev_block_bits);
+               if (r < 0) {
+                       DMERR("crypto_shash_update failed: %d", r);
+                       goto release_ret_r;
+               }
+
+               if (!v->version) {
+                       r = crypto_shash_update(desc, v->salt, v->salt_size);
+                       if (r < 0) {
+                               DMERR("crypto_shash_update failed: %d", r);
+                               goto release_ret_r;
+                       }
+               }
+
+               result = io_real_digest(v, io);
+               r = crypto_shash_final(desc, result);
+               if (r < 0) {
+                       DMERR("crypto_shash_final failed: %d", r);
+                       goto release_ret_r;
+               }
+               if (unlikely(memcmp(result, io_want_digest(v, io), v->digest_size))) {
+                       DMERR_LIMIT("metadata block %llu is corrupted",
+                               (unsigned long long)hash_block);
+                       v->hash_failed = 1;
+                       r = -EIO;
+                       goto release_ret_r;
+               } else
+                       aux->hash_verified = 1;
+       }
+
+       data += offset;
+
+       memcpy(io_want_digest(v, io), data, v->digest_size);
+
+       dm_bufio_release(buf);
+       return 0;
+
+release_ret_r:
+       dm_bufio_release(buf);
+
+       return r;
+}
+
+/*
+ * Verify one "dm_verity_io" structure.
+ */
+static int verity_verify_io(struct dm_verity_io *io)
+{
+       struct dm_verity *v = io->v;
+       unsigned b;
+       int i;
+       unsigned vector = 0, offset = 0;
+
+       for (b = 0; b < io->n_blocks; b++) {
+               struct shash_desc *desc;
+               u8 *result;
+               int r;
+               unsigned todo;
+
+               if (likely(v->levels)) {
+                       /*
+                        * First, we try to get the requested hash for
+                        * the current block. If the hash block itself is
+                        * verified, zero is returned. If it isn't, this
+                        * function returns 0 and we fall back to whole
+                        * chain verification.
+                        */
+                       int r = verity_verify_level(io, io->block + b, 0, true);
+                       if (likely(!r))
+                               goto test_block_hash;
+                       if (r < 0)
+                               return r;
+               }
+
+               memcpy(io_want_digest(v, io), v->root_digest, v->digest_size);
+
+               for (i = v->levels - 1; i >= 0; i--) {
+                       int r = verity_verify_level(io, io->block + b, i, false);
+                       if (unlikely(r))
+                               return r;
+               }
+
+test_block_hash:
+               desc = io_hash_desc(v, io);
+               desc->tfm = v->tfm;
+               desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+               r = crypto_shash_init(desc);
+               if (r < 0) {
+                       DMERR("crypto_shash_init failed: %d", r);
+                       return r;
+               }
+
+               if (likely(v->version >= 1)) {
+                       r = crypto_shash_update(desc, v->salt, v->salt_size);
+                       if (r < 0) {
+                               DMERR("crypto_shash_update failed: %d", r);
+                               return r;
+                       }
+               }
+
+               todo = 1 << v->data_dev_block_bits;
+               do {
+                       struct bio_vec *bv;
+                       u8 *page;
+                       unsigned len;
+
+                       BUG_ON(vector >= io->io_vec_size);
+                       bv = &io->io_vec[vector];
+                       page = kmap_atomic(bv->bv_page);
+                       len = bv->bv_len - offset;
+                       if (likely(len >= todo))
+                               len = todo;
+                       r = crypto_shash_update(desc,
+                                       page + bv->bv_offset + offset, len);
+                       kunmap_atomic(page);
+                       if (r < 0) {
+                               DMERR("crypto_shash_update failed: %d", r);
+                               return r;
+                       }
+                       offset += len;
+                       if (likely(offset == bv->bv_len)) {
+                               offset = 0;
+                               vector++;
+                       }
+                       todo -= len;
+               } while (todo);
+
+               if (!v->version) {
+                       r = crypto_shash_update(desc, v->salt, v->salt_size);
+                       if (r < 0) {
+                               DMERR("crypto_shash_update failed: %d", r);
+                               return r;
+                       }
+               }
+
+               result = io_real_digest(v, io);
+               r = crypto_shash_final(desc, result);
+               if (r < 0) {
+                       DMERR("crypto_shash_final failed: %d", r);
+                       return r;
+               }
+               if (unlikely(memcmp(result, io_want_digest(v, io), v->digest_size))) {
+                       DMERR_LIMIT("data block %llu is corrupted",
+                               (unsigned long long)(io->block + b));
+                       v->hash_failed = 1;
+                       return -EIO;
+               }
+       }
+       BUG_ON(vector != io->io_vec_size);
+       BUG_ON(offset);
+
+       return 0;
+}
+
+/*
+ * End one "io" structure with a given error.
+ */
+static void verity_finish_io(struct dm_verity_io *io, int error)
+{
+       struct bio *bio = io->bio;
+       struct dm_verity *v = io->v;
+
+       bio->bi_end_io = io->orig_bi_end_io;
+       bio->bi_private = io->orig_bi_private;
+
+       if (io->io_vec != io->io_vec_inline)
+               mempool_free(io->io_vec, v->vec_mempool);
+
+       mempool_free(io, v->io_mempool);
+
+       bio_endio(bio, error);
+}
+
+static void verity_work(struct work_struct *w)
+{
+       struct dm_verity_io *io = container_of(w, struct dm_verity_io, work);
+
+       verity_finish_io(io, verity_verify_io(io));
+}
+
+static void verity_end_io(struct bio *bio, int error)
+{
+       struct dm_verity_io *io = bio->bi_private;
+
+       if (error) {
+               verity_finish_io(io, error);
+               return;
+       }
+
+       INIT_WORK(&io->work, verity_work);
+       queue_work(io->v->verify_wq, &io->work);
+}
+
+/*
+ * Prefetch buffers for the specified io.
+ * The root buffer is not prefetched, it is assumed that it will be cached
+ * all the time.
+ */
+static void verity_prefetch_io(struct dm_verity *v, struct dm_verity_io *io)
+{
+       int i;
+
+       for (i = v->levels - 2; i >= 0; i--) {
+               sector_t hash_block_start;
+               sector_t hash_block_end;
+               verity_hash_at_level(v, io->block, i, &hash_block_start, NULL);
+               verity_hash_at_level(v, io->block + io->n_blocks - 1, i, &hash_block_end, NULL);
+               if (!i) {
+                       unsigned cluster = *(volatile unsigned *)&dm_verity_prefetch_cluster;
+
+                       cluster >>= v->data_dev_block_bits;
+                       if (unlikely(!cluster))
+                               goto no_prefetch_cluster;
+
+                       if (unlikely(cluster & (cluster - 1)))
+                               cluster = 1 << (fls(cluster) - 1);
+
+                       hash_block_start &= ~(sector_t)(cluster - 1);
+                       hash_block_end |= cluster - 1;
+                       if (unlikely(hash_block_end >= v->hash_blocks))
+                               hash_block_end = v->hash_blocks - 1;
+               }
+no_prefetch_cluster:
+               dm_bufio_prefetch(v->bufio, hash_block_start,
+                                 hash_block_end - hash_block_start + 1);
+       }
+}
+
+/*
+ * Bio map function. It allocates dm_verity_io structure and bio vector and
+ * fills them. Then it issues prefetches and the I/O.
+ */
+static int verity_map(struct dm_target *ti, struct bio *bio,
+                     union map_info *map_context)
+{
+       struct dm_verity *v = ti->private;
+       struct dm_verity_io *io;
+
+       bio->bi_bdev = v->data_dev->bdev;
+       bio->bi_sector = verity_map_sector(v, bio->bi_sector);
+
+       if (((unsigned)bio->bi_sector | bio_sectors(bio)) &
+           ((1 << (v->data_dev_block_bits - SECTOR_SHIFT)) - 1)) {
+               DMERR_LIMIT("unaligned io");
+               return -EIO;
+       }
+
+       if ((bio->bi_sector + bio_sectors(bio)) >>
+           (v->data_dev_block_bits - SECTOR_SHIFT) > v->data_blocks) {
+               DMERR_LIMIT("io out of range");
+               return -EIO;
+       }
+
+       if (bio_data_dir(bio) == WRITE)
+               return -EIO;
+
+       io = mempool_alloc(v->io_mempool, GFP_NOIO);
+       io->v = v;
+       io->bio = bio;
+       io->orig_bi_end_io = bio->bi_end_io;
+       io->orig_bi_private = bio->bi_private;
+       io->block = bio->bi_sector >> (v->data_dev_block_bits - SECTOR_SHIFT);
+       io->n_blocks = bio->bi_size >> v->data_dev_block_bits;
+
+       bio->bi_end_io = verity_end_io;
+       bio->bi_private = io;
+       io->io_vec_size = bio->bi_vcnt - bio->bi_idx;
+       if (io->io_vec_size < DM_VERITY_IO_VEC_INLINE)
+               io->io_vec = io->io_vec_inline;
+       else
+               io->io_vec = mempool_alloc(v->vec_mempool, GFP_NOIO);
+       memcpy(io->io_vec, bio_iovec(bio),
+              io->io_vec_size * sizeof(struct bio_vec));
+
+       verity_prefetch_io(v, io);
+
+       generic_make_request(bio);
+
+       return DM_MAPIO_SUBMITTED;
+}
+
+/*
+ * Status: V (valid) or C (corruption found)
+ */
+static int verity_status(struct dm_target *ti, status_type_t type,
+                        char *result, unsigned maxlen)
+{
+       struct dm_verity *v = ti->private;
+       unsigned sz = 0;
+       unsigned x;
+
+       switch (type) {
+       case STATUSTYPE_INFO:
+               DMEMIT("%c", v->hash_failed ? 'C' : 'V');
+               break;
+       case STATUSTYPE_TABLE:
+               DMEMIT("%u %s %s %u %u %llu %llu %s ",
+                       v->version,
+                       v->data_dev->name,
+                       v->hash_dev->name,
+                       1 << v->data_dev_block_bits,
+                       1 << v->hash_dev_block_bits,
+                       (unsigned long long)v->data_blocks,
+                       (unsigned long long)v->hash_start,
+                       v->alg_name
+                       );
+               for (x = 0; x < v->digest_size; x++)
+                       DMEMIT("%02x", v->root_digest[x]);
+               DMEMIT(" ");
+               if (!v->salt_size)
+                       DMEMIT("-");
+               else
+                       for (x = 0; x < v->salt_size; x++)
+                               DMEMIT("%02x", v->salt[x]);
+               break;
+       }
+
+       return 0;
+}
+
+static int verity_ioctl(struct dm_target *ti, unsigned cmd,
+                       unsigned long arg)
+{
+       struct dm_verity *v = ti->private;
+       int r = 0;
+
+       if (v->data_start ||
+           ti->len != i_size_read(v->data_dev->bdev->bd_inode) >> SECTOR_SHIFT)
+               r = scsi_verify_blk_ioctl(NULL, cmd);
+
+       return r ? : __blkdev_driver_ioctl(v->data_dev->bdev, v->data_dev->mode,
+                                    cmd, arg);
+}
+
+static int verity_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
+                       struct bio_vec *biovec, int max_size)
+{
+       struct dm_verity *v = ti->private;
+       struct request_queue *q = bdev_get_queue(v->data_dev->bdev);
+
+       if (!q->merge_bvec_fn)
+               return max_size;
+
+       bvm->bi_bdev = v->data_dev->bdev;
+       bvm->bi_sector = verity_map_sector(v, bvm->bi_sector);
+
+       return min(max_size, q->merge_bvec_fn(q, bvm, biovec));
+}
+
+static int verity_iterate_devices(struct dm_target *ti,
+                                 iterate_devices_callout_fn fn, void *data)
+{
+       struct dm_verity *v = ti->private;
+
+       return fn(ti, v->data_dev, v->data_start, ti->len, data);
+}
+
+static void verity_io_hints(struct dm_target *ti, struct queue_limits *limits)
+{
+       struct dm_verity *v = ti->private;
+
+       if (limits->logical_block_size < 1 << v->data_dev_block_bits)
+               limits->logical_block_size = 1 << v->data_dev_block_bits;
+
+       if (limits->physical_block_size < 1 << v->data_dev_block_bits)
+               limits->physical_block_size = 1 << v->data_dev_block_bits;
+
+       blk_limits_io_min(limits, limits->logical_block_size);
+}
+
+static void verity_dtr(struct dm_target *ti)
+{
+       struct dm_verity *v = ti->private;
+
+       if (v->verify_wq)
+               destroy_workqueue(v->verify_wq);
+
+       if (v->vec_mempool)
+               mempool_destroy(v->vec_mempool);
+
+       if (v->io_mempool)
+               mempool_destroy(v->io_mempool);
+
+       if (v->bufio)
+               dm_bufio_client_destroy(v->bufio);
+
+       kfree(v->salt);
+       kfree(v->root_digest);
+
+       if (v->tfm)
+               crypto_free_shash(v->tfm);
+
+       kfree(v->alg_name);
+
+       if (v->hash_dev)
+               dm_put_device(ti, v->hash_dev);
+
+       if (v->data_dev)
+               dm_put_device(ti, v->data_dev);
+
+       kfree(v);
+}
+
+/*
+ * Target parameters:
+ *     <version>       The current format is version 1.
+ *                     Vsn 0 is compatible with original Chromium OS releases.
+ *     <data device>
+ *     <hash device>
+ *     <data block size>
+ *     <hash block size>
+ *     <the number of data blocks>
+ *     <hash start block>
+ *     <algorithm>
+ *     <digest>
+ *     <salt>          Hex string or "-" if no salt.
+ */
+static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
+{
+       struct dm_verity *v;
+       unsigned num;
+       unsigned long long num_ll;
+       int r;
+       int i;
+       sector_t hash_position;
+       char dummy;
+
+       v = kzalloc(sizeof(struct dm_verity), GFP_KERNEL);
+       if (!v) {
+               ti->error = "Cannot allocate verity structure";
+               return -ENOMEM;
+       }
+       ti->private = v;
+       v->ti = ti;
+
+       if ((dm_table_get_mode(ti->table) & ~FMODE_READ)) {
+               ti->error = "Device must be readonly";
+               r = -EINVAL;
+               goto bad;
+       }
+
+       if (argc != 10) {
+               ti->error = "Invalid argument count: exactly 10 arguments required";
+               r = -EINVAL;
+               goto bad;
+       }
+
+       if (sscanf(argv[0], "%d%c", &num, &dummy) != 1 ||
+           num < 0 || num > 1) {
+               ti->error = "Invalid version";
+               r = -EINVAL;
+               goto bad;
+       }
+       v->version = num;
+
+       r = dm_get_device(ti, argv[1], FMODE_READ, &v->data_dev);
+       if (r) {
+               ti->error = "Data device lookup failed";
+               goto bad;
+       }
+
+       r = dm_get_device(ti, argv[2], FMODE_READ, &v->hash_dev);
+       if (r) {
+               ti->error = "Data device lookup failed";
+               goto bad;
+       }
+
+       if (sscanf(argv[3], "%u%c", &num, &dummy) != 1 ||
+           !num || (num & (num - 1)) ||
+           num < bdev_logical_block_size(v->data_dev->bdev) ||
+           num > PAGE_SIZE) {
+               ti->error = "Invalid data device block size";
+               r = -EINVAL;
+               goto bad;
+       }
+       v->data_dev_block_bits = ffs(num) - 1;
+
+       if (sscanf(argv[4], "%u%c", &num, &dummy) != 1 ||
+           !num || (num & (num - 1)) ||
+           num < bdev_logical_block_size(v->hash_dev->bdev) ||
+           num > INT_MAX) {
+               ti->error = "Invalid hash device block size";
+               r = -EINVAL;
+               goto bad;
+       }
+       v->hash_dev_block_bits = ffs(num) - 1;
+
+       if (sscanf(argv[5], "%llu%c", &num_ll, &dummy) != 1 ||
+           num_ll << (v->data_dev_block_bits - SECTOR_SHIFT) !=
+           (sector_t)num_ll << (v->data_dev_block_bits - SECTOR_SHIFT)) {
+               ti->error = "Invalid data blocks";
+               r = -EINVAL;
+               goto bad;
+       }
+       v->data_blocks = num_ll;
+
+       if (ti->len > (v->data_blocks << (v->data_dev_block_bits - SECTOR_SHIFT))) {
+               ti->error = "Data device is too small";
+               r = -EINVAL;
+               goto bad;
+       }
+
+       if (sscanf(argv[6], "%llu%c", &num_ll, &dummy) != 1 ||
+           num_ll << (v->hash_dev_block_bits - SECTOR_SHIFT) !=
+           (sector_t)num_ll << (v->hash_dev_block_bits - SECTOR_SHIFT)) {
+               ti->error = "Invalid hash start";
+               r = -EINVAL;
+               goto bad;
+       }
+       v->hash_start = num_ll;
+
+       v->alg_name = kstrdup(argv[7], GFP_KERNEL);
+       if (!v->alg_name) {
+               ti->error = "Cannot allocate algorithm name";
+               r = -ENOMEM;
+               goto bad;
+       }
+
+       v->tfm = crypto_alloc_shash(v->alg_name, 0, 0);
+       if (IS_ERR(v->tfm)) {
+               ti->error = "Cannot initialize hash function";
+               r = PTR_ERR(v->tfm);
+               v->tfm = NULL;
+               goto bad;
+       }
+       v->digest_size = crypto_shash_digestsize(v->tfm);
+       if ((1 << v->hash_dev_block_bits) < v->digest_size * 2) {
+               ti->error = "Digest size too big";
+               r = -EINVAL;
+               goto bad;
+       }
+       v->shash_descsize =
+               sizeof(struct shash_desc) + crypto_shash_descsize(v->tfm);
+
+       v->root_digest = kmalloc(v->digest_size, GFP_KERNEL);
+       if (!v->root_digest) {
+               ti->error = "Cannot allocate root digest";
+               r = -ENOMEM;
+               goto bad;
+       }
+       if (strlen(argv[8]) != v->digest_size * 2 ||
+           hex2bin(v->root_digest, argv[8], v->digest_size)) {
+               ti->error = "Invalid root digest";
+               r = -EINVAL;
+               goto bad;
+       }
+
+       if (strcmp(argv[9], "-")) {
+               v->salt_size = strlen(argv[9]) / 2;
+               v->salt = kmalloc(v->salt_size, GFP_KERNEL);
+               if (!v->salt) {
+                       ti->error = "Cannot allocate salt";
+                       r = -ENOMEM;
+                       goto bad;
+               }
+               if (strlen(argv[9]) != v->salt_size * 2 ||
+                   hex2bin(v->salt, argv[9], v->salt_size)) {
+                       ti->error = "Invalid salt";
+                       r = -EINVAL;
+                       goto bad;
+               }
+       }
+
+       v->hash_per_block_bits =
+               fls((1 << v->hash_dev_block_bits) / v->digest_size) - 1;
+
+       v->levels = 0;
+       if (v->data_blocks)
+               while (v->hash_per_block_bits * v->levels < 64 &&
+                      (unsigned long long)(v->data_blocks - 1) >>
+                      (v->hash_per_block_bits * v->levels))
+                       v->levels++;
+
+       if (v->levels > DM_VERITY_MAX_LEVELS) {
+               ti->error = "Too many tree levels";
+               r = -E2BIG;
+               goto bad;
+       }
+
+       hash_position = v->hash_start;
+       for (i = v->levels - 1; i >= 0; i--) {
+               sector_t s;
+               v->hash_level_block[i] = hash_position;
+               s = verity_position_at_level(v, v->data_blocks, i);
+               s = (s >> v->hash_per_block_bits) +
+                   !!(s & ((1 << v->hash_per_block_bits) - 1));
+               if (hash_position + s < hash_position) {
+                       ti->error = "Hash device offset overflow";
+                       r = -E2BIG;
+                       goto bad;
+               }
+               hash_position += s;
+       }
+       v->hash_blocks = hash_position;
+
+       v->bufio = dm_bufio_client_create(v->hash_dev->bdev,
+               1 << v->hash_dev_block_bits, 1, sizeof(struct buffer_aux),
+               dm_bufio_alloc_callback, NULL);
+       if (IS_ERR(v->bufio)) {
+               ti->error = "Cannot initialize dm-bufio";
+               r = PTR_ERR(v->bufio);
+               v->bufio = NULL;
+               goto bad;
+       }
+
+       if (dm_bufio_get_device_size(v->bufio) < v->hash_blocks) {
+               ti->error = "Hash device is too small";
+               r = -E2BIG;
+               goto bad;
+       }
+
+       v->io_mempool = mempool_create_kmalloc_pool(DM_VERITY_MEMPOOL_SIZE,
+         sizeof(struct dm_verity_io) + v->shash_descsize + v->digest_size * 2);
+       if (!v->io_mempool) {
+               ti->error = "Cannot allocate io mempool";
+               r = -ENOMEM;
+               goto bad;
+       }
+
+       v->vec_mempool = mempool_create_kmalloc_pool(DM_VERITY_MEMPOOL_SIZE,
+                                       BIO_MAX_PAGES * sizeof(struct bio_vec));
+       if (!v->vec_mempool) {
+               ti->error = "Cannot allocate vector mempool";
+               r = -ENOMEM;
+               goto bad;
+       }
+
+       /* WQ_UNBOUND greatly improves performance when running on ramdisk */
+       v->verify_wq = alloc_workqueue("kverityd", WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM | WQ_UNBOUND, num_online_cpus());
+       if (!v->verify_wq) {
+               ti->error = "Cannot allocate workqueue";
+               r = -ENOMEM;
+               goto bad;
+       }
+
+       return 0;
+
+bad:
+       verity_dtr(ti);
+
+       return r;
+}
+
+static struct target_type verity_target = {
+       .name           = "verity",
+       .version        = {1, 0, 0},
+       .module         = THIS_MODULE,
+       .ctr            = verity_ctr,
+       .dtr            = verity_dtr,
+       .map            = verity_map,
+       .status         = verity_status,
+       .ioctl          = verity_ioctl,
+       .merge          = verity_merge,
+       .iterate_devices = verity_iterate_devices,
+       .io_hints       = verity_io_hints,
+};
+
+static int __init dm_verity_init(void)
+{
+       int r;
+
+       r = dm_register_target(&verity_target);
+       if (r < 0)
+               DMERR("register failed %d", r);
+
+       return r;
+}
+
+static void __exit dm_verity_exit(void)
+{
+       dm_unregister_target(&verity_target);
+}
+
+module_init(dm_verity_init);
+module_exit(dm_verity_exit);
+
+MODULE_AUTHOR("Mikulas Patocka <mpatocka@redhat.com>");
+MODULE_AUTHOR("Mandeep Baines <msb@chromium.org>");
+MODULE_AUTHOR("Will Drewry <wad@chromium.org>");
+MODULE_DESCRIPTION(DM_NAME " target for transparent disk integrity checking");
+MODULE_LICENSE("GPL");
index b89c548ec3f88612eb4a6fec4d6230ad413ed9c1..e24143cc2040b7f3f8f90a63c3b1b2cfe2b21c24 100644 (file)
@@ -1016,6 +1016,7 @@ static void __map_bio(struct dm_target *ti, struct bio *clone,
                /*
                 * Store bio_set for cleanup.
                 */
+               clone->bi_end_io = NULL;
                clone->bi_private = md->bs;
                bio_put(clone);
                free_tio(md, tio);
index d279c768f8f10f8cf22baef4a6978483c82bb56b..5709bfeab1e8fb29af17ba7a66dc78a9432d86a2 100644 (file)
@@ -108,12 +108,9 @@ static inline void *value_base(struct node *n)
        return &n->keys[le32_to_cpu(n->header.max_entries)];
 }
 
-/*
- * FIXME: Now that value size is stored in node we don't need the third parm.
- */
-static inline void *value_ptr(struct node *n, uint32_t index, size_t value_size)
+static inline void *value_ptr(struct node *n, uint32_t index)
 {
-       BUG_ON(value_size != le32_to_cpu(n->header.value_size));
+       uint32_t value_size = le32_to_cpu(n->header.value_size);
        return value_base(n) + (value_size * index);
 }
 
index 023fbc2d389ee086e2edf53168e969a24dba5cad..aa71e2359a0704050b0b61054d4faa21bac10b53 100644 (file)
@@ -61,20 +61,20 @@ static void node_shift(struct node *n, int shift)
        if (shift < 0) {
                shift = -shift;
                BUG_ON(shift > nr_entries);
-               BUG_ON((void *) key_ptr(n, shift) >= value_ptr(n, shift, value_size));
+               BUG_ON((void *) key_ptr(n, shift) >= value_ptr(n, shift));
                memmove(key_ptr(n, 0),
                        key_ptr(n, shift),
                        (nr_entries - shift) * sizeof(__le64));
-               memmove(value_ptr(n, 0, value_size),
-                       value_ptr(n, shift, value_size),
+               memmove(value_ptr(n, 0),
+                       value_ptr(n, shift),
                        (nr_entries - shift) * value_size);
        } else {
                BUG_ON(nr_entries + shift > le32_to_cpu(n->header.max_entries));
                memmove(key_ptr(n, shift),
                        key_ptr(n, 0),
                        nr_entries * sizeof(__le64));
-               memmove(value_ptr(n, shift, value_size),
-                       value_ptr(n, 0, value_size),
+               memmove(value_ptr(n, shift),
+                       value_ptr(n, 0),
                        nr_entries * value_size);
        }
 }
@@ -91,16 +91,16 @@ static void node_copy(struct node *left, struct node *right, int shift)
                memcpy(key_ptr(left, nr_left),
                       key_ptr(right, 0),
                       shift * sizeof(__le64));
-               memcpy(value_ptr(left, nr_left, value_size),
-                      value_ptr(right, 0, value_size),
+               memcpy(value_ptr(left, nr_left),
+                      value_ptr(right, 0),
                       shift * value_size);
        } else {
                BUG_ON(shift > le32_to_cpu(right->header.max_entries));
                memcpy(key_ptr(right, 0),
                       key_ptr(left, nr_left - shift),
                       shift * sizeof(__le64));
-               memcpy(value_ptr(right, 0, value_size),
-                      value_ptr(left, nr_left - shift, value_size),
+               memcpy(value_ptr(right, 0),
+                      value_ptr(left, nr_left - shift),
                       shift * value_size);
        }
 }
@@ -120,26 +120,17 @@ static void delete_at(struct node *n, unsigned index)
                        key_ptr(n, index + 1),
                        nr_to_copy * sizeof(__le64));
 
-               memmove(value_ptr(n, index, value_size),
-                       value_ptr(n, index + 1, value_size),
+               memmove(value_ptr(n, index),
+                       value_ptr(n, index + 1),
                        nr_to_copy * value_size);
        }
 
        n->header.nr_entries = cpu_to_le32(nr_entries - 1);
 }
 
-static unsigned del_threshold(struct node *n)
-{
-       return le32_to_cpu(n->header.max_entries) / 3;
-}
-
 static unsigned merge_threshold(struct node *n)
 {
-       /*
-        * The extra one is because we know we're potentially going to
-        * delete an entry.
-        */
-       return 2 * (le32_to_cpu(n->header.max_entries) / 3) + 1;
+       return le32_to_cpu(n->header.max_entries) / 3;
 }
 
 struct child {
@@ -175,7 +166,7 @@ static int init_child(struct dm_btree_info *info, struct node *parent,
        if (inc)
                inc_children(info->tm, result->n, &le64_type);
 
-       *((__le64 *) value_ptr(parent, index, sizeof(__le64))) =
+       *((__le64 *) value_ptr(parent, index)) =
                cpu_to_le64(dm_block_location(result->block));
 
        return 0;
@@ -188,6 +179,15 @@ static int exit_child(struct dm_btree_info *info, struct child *c)
 
 static void shift(struct node *left, struct node *right, int count)
 {
+       uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
+       uint32_t nr_right = le32_to_cpu(right->header.nr_entries);
+       uint32_t max_entries = le32_to_cpu(left->header.max_entries);
+       uint32_t r_max_entries = le32_to_cpu(right->header.max_entries);
+
+       BUG_ON(max_entries != r_max_entries);
+       BUG_ON(nr_left - count > max_entries);
+       BUG_ON(nr_right + count > max_entries);
+
        if (!count)
                return;
 
@@ -199,13 +199,8 @@ static void shift(struct node *left, struct node *right, int count)
                node_shift(right, count);
        }
 
-       left->header.nr_entries =
-               cpu_to_le32(le32_to_cpu(left->header.nr_entries) - count);
-       BUG_ON(le32_to_cpu(left->header.nr_entries) > le32_to_cpu(left->header.max_entries));
-
-       right->header.nr_entries =
-               cpu_to_le32(le32_to_cpu(right->header.nr_entries) + count);
-       BUG_ON(le32_to_cpu(right->header.nr_entries) > le32_to_cpu(right->header.max_entries));
+       left->header.nr_entries = cpu_to_le32(nr_left - count);
+       right->header.nr_entries = cpu_to_le32(nr_right + count);
 }
 
 static void __rebalance2(struct dm_btree_info *info, struct node *parent,
@@ -215,8 +210,9 @@ static void __rebalance2(struct dm_btree_info *info, struct node *parent,
        struct node *right = r->n;
        uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
        uint32_t nr_right = le32_to_cpu(right->header.nr_entries);
+       unsigned threshold = 2 * merge_threshold(left) + 1;
 
-       if (nr_left + nr_right <= merge_threshold(left)) {
+       if (nr_left + nr_right < threshold) {
                /*
                 * Merge
                 */
@@ -234,9 +230,6 @@ static void __rebalance2(struct dm_btree_info *info, struct node *parent,
                 * Rebalance.
                 */
                unsigned target_left = (nr_left + nr_right) / 2;
-               unsigned shift_ = nr_left - target_left;
-               BUG_ON(le32_to_cpu(left->header.max_entries) <= nr_left - shift_);
-               BUG_ON(le32_to_cpu(right->header.max_entries) <= nr_right + shift_);
                shift(left, right, nr_left - target_left);
                *key_ptr(parent, r->index) = right->keys[0];
        }
@@ -272,6 +265,84 @@ static int rebalance2(struct shadow_spine *s, struct dm_btree_info *info,
        return exit_child(info, &right);
 }
 
+/*
+ * We dump as many entries from center as possible into left, then the rest
+ * in right, then rebalance2.  This wastes some cpu, but I want something
+ * simple atm.
+ */
+static void delete_center_node(struct dm_btree_info *info, struct node *parent,
+                              struct child *l, struct child *c, struct child *r,
+                              struct node *left, struct node *center, struct node *right,
+                              uint32_t nr_left, uint32_t nr_center, uint32_t nr_right)
+{
+       uint32_t max_entries = le32_to_cpu(left->header.max_entries);
+       unsigned shift = min(max_entries - nr_left, nr_center);
+
+       BUG_ON(nr_left + shift > max_entries);
+       node_copy(left, center, -shift);
+       left->header.nr_entries = cpu_to_le32(nr_left + shift);
+
+       if (shift != nr_center) {
+               shift = nr_center - shift;
+               BUG_ON((nr_right + shift) > max_entries);
+               node_shift(right, shift);
+               node_copy(center, right, shift);
+               right->header.nr_entries = cpu_to_le32(nr_right + shift);
+       }
+       *key_ptr(parent, r->index) = right->keys[0];
+
+       delete_at(parent, c->index);
+       r->index--;
+
+       dm_tm_dec(info->tm, dm_block_location(c->block));
+       __rebalance2(info, parent, l, r);
+}
+
+/*
+ * Redistributes entries among 3 sibling nodes.
+ */
+static void redistribute3(struct dm_btree_info *info, struct node *parent,
+                         struct child *l, struct child *c, struct child *r,
+                         struct node *left, struct node *center, struct node *right,
+                         uint32_t nr_left, uint32_t nr_center, uint32_t nr_right)
+{
+       int s;
+       uint32_t max_entries = le32_to_cpu(left->header.max_entries);
+       unsigned target = (nr_left + nr_center + nr_right) / 3;
+       BUG_ON(target > max_entries);
+
+       if (nr_left < nr_right) {
+               s = nr_left - target;
+
+               if (s < 0 && nr_center < -s) {
+                       /* not enough in central node */
+                       shift(left, center, nr_center);
+                       s = nr_center - target;
+                       shift(left, right, s);
+                       nr_right += s;
+               } else
+                       shift(left, center, s);
+
+               shift(center, right, target - nr_right);
+
+       } else {
+               s = target - nr_right;
+               if (s > 0 && nr_center < s) {
+                       /* not enough in central node */
+                       shift(center, right, nr_center);
+                       s = target - nr_center;
+                       shift(left, right, s);
+                       nr_left -= s;
+               } else
+                       shift(center, right, s);
+
+               shift(left, center, nr_left - target);
+       }
+
+       *key_ptr(parent, c->index) = center->keys[0];
+       *key_ptr(parent, r->index) = right->keys[0];
+}
+
 static void __rebalance3(struct dm_btree_info *info, struct node *parent,
                         struct child *l, struct child *c, struct child *r)
 {
@@ -282,62 +353,18 @@ static void __rebalance3(struct dm_btree_info *info, struct node *parent,
        uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
        uint32_t nr_center = le32_to_cpu(center->header.nr_entries);
        uint32_t nr_right = le32_to_cpu(right->header.nr_entries);
-       uint32_t max_entries = le32_to_cpu(left->header.max_entries);
 
-       unsigned target;
+       unsigned threshold = merge_threshold(left) * 4 + 1;
 
        BUG_ON(left->header.max_entries != center->header.max_entries);
        BUG_ON(center->header.max_entries != right->header.max_entries);
 
-       if (((nr_left + nr_center + nr_right) / 2) < merge_threshold(center)) {
-               /*
-                * Delete center node:
-                *
-                * We dump as many entries from center as possible into
-                * left, then the rest in right, then rebalance2.  This
-                * wastes some cpu, but I want something simple atm.
-                */
-               unsigned shift = min(max_entries - nr_left, nr_center);
-
-               BUG_ON(nr_left + shift > max_entries);
-               node_copy(left, center, -shift);
-               left->header.nr_entries = cpu_to_le32(nr_left + shift);
-
-               if (shift != nr_center) {
-                       shift = nr_center - shift;
-                       BUG_ON((nr_right + shift) >= max_entries);
-                       node_shift(right, shift);
-                       node_copy(center, right, shift);
-                       right->header.nr_entries = cpu_to_le32(nr_right + shift);
-               }
-               *key_ptr(parent, r->index) = right->keys[0];
-
-               delete_at(parent, c->index);
-               r->index--;
-
-               dm_tm_dec(info->tm, dm_block_location(c->block));
-               __rebalance2(info, parent, l, r);
-
-               return;
-       }
-
-       /*
-        * Rebalance
-        */
-       target = (nr_left + nr_center + nr_right) / 3;
-       BUG_ON(target > max_entries);
-
-       /*
-        * Adjust the left node
-        */
-       shift(left, center, nr_left - target);
-
-       /*
-        * Adjust the right node
-        */
-       shift(center, right, target - nr_right);
-       *key_ptr(parent, c->index) = center->keys[0];
-       *key_ptr(parent, r->index) = right->keys[0];
+       if ((nr_left + nr_center + nr_right) < threshold)
+               delete_center_node(info, parent, l, c, r, left, center, right,
+                                  nr_left, nr_center, nr_right);
+       else
+               redistribute3(info, parent, l, c, r, left, center, right,
+                             nr_left, nr_center, nr_right);
 }
 
 static int rebalance3(struct shadow_spine *s, struct dm_btree_info *info,
@@ -441,9 +468,6 @@ static int rebalance_children(struct shadow_spine *s,
        if (r)
                return r;
 
-       if (child_entries > del_threshold(n))
-               return 0;
-
        has_left_sibling = i > 0;
        has_right_sibling = i < (le32_to_cpu(n->header.nr_entries) - 1);
 
@@ -496,7 +520,7 @@ static int remove_raw(struct shadow_spine *s, struct dm_btree_info *info,
                 */
                if (shadow_has_parent(s)) {
                        __le64 location = cpu_to_le64(dm_block_location(shadow_current(s)));
-                       memcpy(value_ptr(dm_block_data(shadow_parent(s)), i, sizeof(__le64)),
+                       memcpy(value_ptr(dm_block_data(shadow_parent(s)), i),
                               &location, sizeof(__le64));
                }
 
@@ -553,7 +577,7 @@ int dm_btree_remove(struct dm_btree_info *info, dm_block_t root,
 
                if (info->value_type.dec)
                        info->value_type.dec(info->value_type.context,
-                                            value_ptr(n, index, info->value_type.size));
+                                            value_ptr(n, index));
 
                delete_at(n, index);
        }
index bd1e7ffbe26c750a26a4b9341d925a98acf632b3..d12b2cc51f1a37711586fe6d13f6261f0b56c1be 100644 (file)
@@ -74,8 +74,7 @@ void inc_children(struct dm_transaction_manager *tm, struct node *n,
                        dm_tm_inc(tm, value64(n, i));
        else if (vt->inc)
                for (i = 0; i < nr_entries; i++)
-                       vt->inc(vt->context,
-                               value_ptr(n, i, vt->size));
+                       vt->inc(vt->context, value_ptr(n, i));
 }
 
 static int insert_at(size_t value_size, struct node *node, unsigned index,
@@ -281,7 +280,7 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
 
                                for (i = 0; i < f->nr_children; i++)
                                        info->value_type.dec(info->value_type.context,
-                                                            value_ptr(f->n, i, info->value_type.size));
+                                                            value_ptr(f->n, i));
                        }
                        f->current_child = f->nr_children;
                }
@@ -320,7 +319,7 @@ static int btree_lookup_raw(struct ro_spine *s, dm_block_t block, uint64_t key,
        } while (!(flags & LEAF_NODE));
 
        *result_key = le64_to_cpu(ro_node(s)->keys[i]);
-       memcpy(v, value_ptr(ro_node(s), i, value_size), value_size);
+       memcpy(v, value_ptr(ro_node(s), i), value_size);
 
        return 0;
 }
@@ -432,7 +431,7 @@ static int btree_split_sibling(struct shadow_spine *s, dm_block_t root,
 
        size = le32_to_cpu(ln->header.flags) & INTERNAL_NODE ?
                sizeof(uint64_t) : s->info->value_type.size;
-       memcpy(value_ptr(rn, 0, size), value_ptr(ln, nr_left, size),
+       memcpy(value_ptr(rn, 0), value_ptr(ln, nr_left),
               size * nr_right);
 
        /*
@@ -443,7 +442,7 @@ static int btree_split_sibling(struct shadow_spine *s, dm_block_t root,
        pn = dm_block_data(parent);
        location = cpu_to_le64(dm_block_location(left));
        __dm_bless_for_disk(&location);
-       memcpy_disk(value_ptr(pn, parent_index, sizeof(__le64)),
+       memcpy_disk(value_ptr(pn, parent_index),
                    &location, sizeof(__le64));
 
        location = cpu_to_le64(dm_block_location(right));
@@ -529,8 +528,8 @@ static int btree_split_beneath(struct shadow_spine *s, uint64_t key)
 
        size = le32_to_cpu(pn->header.flags) & INTERNAL_NODE ?
                sizeof(__le64) : s->info->value_type.size;
-       memcpy(value_ptr(ln, 0, size), value_ptr(pn, 0, size), nr_left * size);
-       memcpy(value_ptr(rn, 0, size), value_ptr(pn, nr_left, size),
+       memcpy(value_ptr(ln, 0), value_ptr(pn, 0), nr_left * size);
+       memcpy(value_ptr(rn, 0), value_ptr(pn, nr_left),
               nr_right * size);
 
        /* new_parent should just point to l and r now */
@@ -545,12 +544,12 @@ static int btree_split_beneath(struct shadow_spine *s, uint64_t key)
        val = cpu_to_le64(dm_block_location(left));
        __dm_bless_for_disk(&val);
        pn->keys[0] = ln->keys[0];
-       memcpy_disk(value_ptr(pn, 0, sizeof(__le64)), &val, sizeof(__le64));
+       memcpy_disk(value_ptr(pn, 0), &val, sizeof(__le64));
 
        val = cpu_to_le64(dm_block_location(right));
        __dm_bless_for_disk(&val);
        pn->keys[1] = rn->keys[0];
-       memcpy_disk(value_ptr(pn, 1, sizeof(__le64)), &val, sizeof(__le64));
+       memcpy_disk(value_ptr(pn, 1), &val, sizeof(__le64));
 
        /*
         * rejig the spine.  This is ugly, since it knows too
@@ -595,7 +594,7 @@ static int btree_insert_raw(struct shadow_spine *s, dm_block_t root,
                        __le64 location = cpu_to_le64(dm_block_location(shadow_current(s)));
 
                        __dm_bless_for_disk(&location);
-                       memcpy_disk(value_ptr(dm_block_data(shadow_parent(s)), i, sizeof(uint64_t)),
+                       memcpy_disk(value_ptr(dm_block_data(shadow_parent(s)), i),
                                    &location, sizeof(__le64));
                }
 
@@ -710,12 +709,12 @@ static int insert(struct dm_btree_info *info, dm_block_t root,
                    (!info->value_type.equal ||
                     !info->value_type.equal(
                             info->value_type.context,
-                            value_ptr(n, index, info->value_type.size),
+                            value_ptr(n, index),
                             value))) {
                        info->value_type.dec(info->value_type.context,
-                                            value_ptr(n, index, info->value_type.size));
+                                            value_ptr(n, index));
                }
-               memcpy_disk(value_ptr(n, index, info->value_type.size),
+               memcpy_disk(value_ptr(n, index),
                            value, info->value_type.size);
        }
 
index df2494c06cdc08acc566dcaef7e12f14689224ac..ff3beed6ad2d93769e475539ecd60d29ffdfaf22 100644 (file)
@@ -405,8 +405,6 @@ int sm_ll_insert(struct ll_disk *ll, dm_block_t b,
                if (r < 0)
                        return r;
 
-#if 0
-               /* FIXME: dm_btree_remove doesn't handle this yet */
                if (old > 2) {
                        r = dm_btree_remove(&ll->ref_count_info,
                                            ll->ref_count_root,
@@ -414,7 +412,6 @@ int sm_ll_insert(struct ll_disk *ll, dm_block_t b,
                        if (r)
                                return r;
                }
-#endif
 
        } else {
                __le32 le_rc = cpu_to_le32(ref_count);
index 1489c3540f96bab496aa6b0681c0ada3637d09c3..243e0c663c37be28fc2282dc98be2e9715f7804a 100644 (file)
@@ -848,8 +848,9 @@ config MCP_SA11X0
 
 # Chip drivers
 config MCP_UCB1200
-       tristate "Support for UCB1200 / UCB1300"
-       depends on MCP
+       bool "Support for UCB1200 / UCB1300"
+       depends on MCP_SA11X0
+       select MCP
 
 config MCP_UCB1200_TS
        tristate "Touchscreen interface support"
index 86cc3f7841cdfdb2714368b1459a5fd54ac6491a..6acf2e03f2baa935039690637ff8b3c0f793ff2b 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/string.h>
 #include <linux/mfd/mcp.h>
 
-#include <mach/dma.h>
 #include <asm/system.h>
 
 
@@ -48,39 +47,11 @@ static int mcp_bus_remove(struct device *dev)
        return 0;
 }
 
-static int mcp_bus_suspend(struct device *dev, pm_message_t state)
-{
-       struct mcp *mcp = to_mcp(dev);
-       int ret = 0;
-
-       if (dev->driver) {
-               struct mcp_driver *drv = to_mcp_driver(dev->driver);
-
-               ret = drv->suspend(mcp, state);
-       }
-       return ret;
-}
-
-static int mcp_bus_resume(struct device *dev)
-{
-       struct mcp *mcp = to_mcp(dev);
-       int ret = 0;
-
-       if (dev->driver) {
-               struct mcp_driver *drv = to_mcp_driver(dev->driver);
-
-               ret = drv->resume(mcp);
-       }
-       return ret;
-}
-
 static struct bus_type mcp_bus_type = {
        .name           = "mcp",
        .match          = mcp_bus_match,
        .probe          = mcp_bus_probe,
        .remove         = mcp_bus_remove,
-       .suspend        = mcp_bus_suspend,
-       .resume         = mcp_bus_resume,
 };
 
 /**
@@ -208,6 +179,7 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size)
        mcp = kzalloc(sizeof(struct mcp) + size, GFP_KERNEL);
        if (mcp) {
                spin_lock_init(&mcp->lock);
+               device_initialize(&mcp->attached_device);
                mcp->attached_device.parent = parent;
                mcp->attached_device.bus = &mcp_bus_type;
                mcp->attached_device.dma_mask = parent->dma_mask;
@@ -217,18 +189,25 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size)
 }
 EXPORT_SYMBOL(mcp_host_alloc);
 
-int mcp_host_register(struct mcp *mcp)
+int mcp_host_add(struct mcp *mcp, void *pdata)
 {
+       mcp->attached_device.platform_data = pdata;
        dev_set_name(&mcp->attached_device, "mcp0");
-       return device_register(&mcp->attached_device);
+       return device_add(&mcp->attached_device);
+}
+EXPORT_SYMBOL(mcp_host_add);
+
+void mcp_host_del(struct mcp *mcp)
+{
+       device_del(&mcp->attached_device);
 }
-EXPORT_SYMBOL(mcp_host_register);
+EXPORT_SYMBOL(mcp_host_del);
 
-void mcp_host_unregister(struct mcp *mcp)
+void mcp_host_free(struct mcp *mcp)
 {
-       device_unregister(&mcp->attached_device);
+       put_device(&mcp->attached_device);
 }
-EXPORT_SYMBOL(mcp_host_unregister);
+EXPORT_SYMBOL(mcp_host_free);
 
 int mcp_driver_register(struct mcp_driver *mcpdrv)
 {
index 02c53a0766c4275d7496ece5b96cb20b0e1ddc49..1c0ceacaa1f6463db20cf2a275df68747c9cf80f 100644 (file)
  */
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/io.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/platform_device.h>
+#include <linux/pm.h>
 #include <linux/mfd/mcp.h>
 
-#include <mach/dma.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/system.h>
 #include <mach/mcp.h>
 
-#include <mach/assabet.h>
-
+#define DRIVER_NAME "sa11x0-mcp"
 
 struct mcp_sa11x0 {
-       u32     mccr0;
-       u32     mccr1;
+       void __iomem    *base0;
+       void __iomem    *base1;
+       u32             mccr0;
+       u32             mccr1;
 };
 
+/* Register offsets */
+#define MCCR0(m)       ((m)->base0 + 0x00)
+#define MCDR0(m)       ((m)->base0 + 0x08)
+#define MCDR1(m)       ((m)->base0 + 0x0c)
+#define MCDR2(m)       ((m)->base0 + 0x10)
+#define MCSR(m)                ((m)->base0 + 0x18)
+#define MCCR1(m)       ((m)->base1 + 0x00)
+
 #define priv(mcp)      ((struct mcp_sa11x0 *)mcp_priv(mcp))
 
 static void
 mcp_sa11x0_set_telecom_divisor(struct mcp *mcp, unsigned int divisor)
 {
-       unsigned int mccr0;
+       struct mcp_sa11x0 *m = priv(mcp);
 
        divisor /= 32;
 
-       mccr0 = Ser4MCCR0 & ~0x00007f00;
-       mccr0 |= divisor << 8;
-       Ser4MCCR0 = mccr0;
+       m->mccr0 &= ~0x00007f00;
+       m->mccr0 |= divisor << 8;
+       writel_relaxed(m->mccr0, MCCR0(m));
 }
 
 static void
 mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor)
 {
-       unsigned int mccr0;
+       struct mcp_sa11x0 *m = priv(mcp);
 
        divisor /= 32;
 
-       mccr0 = Ser4MCCR0 & ~0x0000007f;
-       mccr0 |= divisor;
-       Ser4MCCR0 = mccr0;
+       m->mccr0 &= ~0x0000007f;
+       m->mccr0 |= divisor;
+       writel_relaxed(m->mccr0, MCCR0(m));
 }
 
 /*
@@ -69,14 +79,15 @@ mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor)
 static void
 mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val)
 {
+       struct mcp_sa11x0 *m = priv(mcp);
        int ret = -ETIME;
        int i;
 
-       Ser4MCDR2 = reg << 17 | MCDR2_Wr | (val & 0xffff);
+       writel_relaxed(reg << 17 | MCDR2_Wr | (val & 0xffff), MCDR2(m));
 
        for (i = 0; i < 2; i++) {
                udelay(mcp->rw_timeout);
-               if (Ser4MCSR & MCSR_CWC) {
+               if (readl_relaxed(MCSR(m)) & MCSR_CWC) {
                        ret = 0;
                        break;
                }
@@ -95,15 +106,16 @@ mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val)
 static unsigned int
 mcp_sa11x0_read(struct mcp *mcp, unsigned int reg)
 {
+       struct mcp_sa11x0 *m = priv(mcp);
        int ret = -ETIME;
        int i;
 
-       Ser4MCDR2 = reg << 17 | MCDR2_Rd;
+       writel_relaxed(reg << 17 | MCDR2_Rd, MCDR2(m));
 
        for (i = 0; i < 2; i++) {
                udelay(mcp->rw_timeout);
-               if (Ser4MCSR & MCSR_CRC) {
-                       ret = Ser4MCDR2 & 0xffff;
+               if (readl_relaxed(MCSR(m)) & MCSR_CRC) {
+                       ret = readl_relaxed(MCDR2(m)) & 0xffff;
                        break;
                }
        }
@@ -116,13 +128,19 @@ mcp_sa11x0_read(struct mcp *mcp, unsigned int reg)
 
 static void mcp_sa11x0_enable(struct mcp *mcp)
 {
-       Ser4MCSR = -1;
-       Ser4MCCR0 |= MCCR0_MCE;
+       struct mcp_sa11x0 *m = priv(mcp);
+
+       writel(-1, MCSR(m));
+       m->mccr0 |= MCCR0_MCE;
+       writel_relaxed(m->mccr0, MCCR0(m));
 }
 
 static void mcp_sa11x0_disable(struct mcp *mcp)
 {
-       Ser4MCCR0 &= ~MCCR0_MCE;
+       struct mcp_sa11x0 *m = priv(mcp);
+
+       m->mccr0 &= ~MCCR0_MCE;
+       writel_relaxed(m->mccr0, MCCR0(m));
 }
 
 /*
@@ -137,55 +155,64 @@ static struct mcp_ops mcp_sa11x0 = {
        .disable                = mcp_sa11x0_disable,
 };
 
-static int mcp_sa11x0_probe(struct platform_device *pdev)
+static int mcp_sa11x0_probe(struct platform_device *dev)
 {
-       struct mcp_plat_data *data = pdev->dev.platform_data;
+       struct mcp_plat_data *data = dev->dev.platform_data;
+       struct resource *mem0, *mem1;
+       struct mcp_sa11x0 *m;
        struct mcp *mcp;
        int ret;
 
        if (!data)
                return -ENODEV;
 
-       if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp"))
-               return -EBUSY;
+       mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1);
+       if (!mem0 || !mem1)
+               return -ENXIO;
+
+       if (!request_mem_region(mem0->start, resource_size(mem0),
+                               DRIVER_NAME)) {
+               ret = -EBUSY;
+               goto err_mem0;
+       }
 
-       mcp = mcp_host_alloc(&pdev->dev, sizeof(struct mcp_sa11x0));
+       if (!request_mem_region(mem1->start, resource_size(mem1),
+                               DRIVER_NAME)) {
+               ret = -EBUSY;
+               goto err_mem1;
+       }
+
+       mcp = mcp_host_alloc(&dev->dev, sizeof(struct mcp_sa11x0));
        if (!mcp) {
                ret = -ENOMEM;
-               goto release;
+               goto err_alloc;
        }
 
        mcp->owner              = THIS_MODULE;
        mcp->ops                = &mcp_sa11x0;
        mcp->sclk_rate          = data->sclk_rate;
-       mcp->dma_audio_rd       = DMA_Ser4MCP0Rd;
-       mcp->dma_audio_wr       = DMA_Ser4MCP0Wr;
-       mcp->dma_telco_rd       = DMA_Ser4MCP1Rd;
-       mcp->dma_telco_wr       = DMA_Ser4MCP1Wr;
-       mcp->gpio_base          = data->gpio_base;
 
-       platform_set_drvdata(pdev, mcp);
+       m = priv(mcp);
+       m->mccr0 = data->mccr0 | 0x7f7f;
+       m->mccr1 = data->mccr1;
 
-       if (machine_is_assabet()) {
-               ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
+       m->base0 = ioremap(mem0->start, resource_size(mem0));
+       m->base1 = ioremap(mem1->start, resource_size(mem1));
+       if (!m->base0 || !m->base1) {
+               ret = -ENOMEM;
+               goto err_ioremap;
        }
 
-       /*
-        * Setup the PPC unit correctly.
-        */
-       PPDR &= ~PPC_RXD4;
-       PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
-       PSDR |= PPC_RXD4;
-       PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-       PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+       platform_set_drvdata(dev, mcp);
 
        /*
         * Initialise device.  Note that we initially
         * set the sampling rate to minimum.
         */
-       Ser4MCSR = -1;
-       Ser4MCCR1 = data->mccr1;
-       Ser4MCCR0 = data->mccr0 | 0x7f7f;
+       writel_relaxed(-1, MCSR(m));
+       writel_relaxed(m->mccr1, MCCR1(m));
+       writel_relaxed(m->mccr0, MCCR0(m));
 
        /*
         * Calculate the read/write timeout (us) from the bit clock
@@ -195,62 +222,90 @@ static int mcp_sa11x0_probe(struct platform_device *pdev)
        mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) /
                          mcp->sclk_rate;
 
-       ret = mcp_host_register(mcp);
+       ret = mcp_host_add(mcp, data->codec_pdata);
        if (ret == 0)
-               goto out;
+               return 0;
 
- release:
-       release_mem_region(0x80060000, 0x60);
-       platform_set_drvdata(pdev, NULL);
+       platform_set_drvdata(dev, NULL);
 
- out:
+ err_ioremap:
+       iounmap(m->base1);
+       iounmap(m->base0);
+       mcp_host_free(mcp);
+ err_alloc:
+       release_mem_region(mem1->start, resource_size(mem1));
+ err_mem1:
+       release_mem_region(mem0->start, resource_size(mem0));
+ err_mem0:
        return ret;
 }
 
 static int mcp_sa11x0_remove(struct platform_device *dev)
 {
        struct mcp *mcp = platform_get_drvdata(dev);
+       struct mcp_sa11x0 *m = priv(mcp);
+       struct resource *mem0, *mem1;
+
+       if (m->mccr0 & MCCR0_MCE)
+               dev_warn(&dev->dev,
+                        "device left active (missing disable call?)\n");
+
+       mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1);
 
        platform_set_drvdata(dev, NULL);
-       mcp_host_unregister(mcp);
-       release_mem_region(0x80060000, 0x60);
+       mcp_host_del(mcp);
+       iounmap(m->base1);
+       iounmap(m->base0);
+       mcp_host_free(mcp);
+       release_mem_region(mem1->start, resource_size(mem1));
+       release_mem_region(mem0->start, resource_size(mem0));
 
        return 0;
 }
 
-static int mcp_sa11x0_suspend(struct platform_device *dev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int mcp_sa11x0_suspend(struct device *dev)
 {
-       struct mcp *mcp = platform_get_drvdata(dev);
+       struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev));
+
+       if (m->mccr0 & MCCR0_MCE)
+               dev_warn(dev, "device left active (missing disable call?)\n");
 
-       priv(mcp)->mccr0 = Ser4MCCR0;
-       priv(mcp)->mccr1 = Ser4MCCR1;
-       Ser4MCCR0 &= ~MCCR0_MCE;
+       writel(m->mccr0 & ~MCCR0_MCE, MCCR0(m));
 
        return 0;
 }
 
-static int mcp_sa11x0_resume(struct platform_device *dev)
+static int mcp_sa11x0_resume(struct device *dev)
 {
-       struct mcp *mcp = platform_get_drvdata(dev);
+       struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev));
 
-       Ser4MCCR1 = priv(mcp)->mccr1;
-       Ser4MCCR0 = priv(mcp)->mccr0;
+       writel_relaxed(m->mccr1, MCCR1(m));
+       writel_relaxed(m->mccr0, MCCR0(m));
 
        return 0;
 }
-
-/*
- * The driver for the SA11x0 MCP port.
- */
-MODULE_ALIAS("platform:sa11x0-mcp");
+#endif
+
+static const struct dev_pm_ops mcp_sa11x0_pm_ops = {
+#ifdef CONFIG_PM_SLEEP
+       .suspend = mcp_sa11x0_suspend,
+       .freeze = mcp_sa11x0_suspend,
+       .poweroff = mcp_sa11x0_suspend,
+       .resume_noirq = mcp_sa11x0_resume,
+       .thaw_noirq = mcp_sa11x0_resume,
+       .restore_noirq = mcp_sa11x0_resume,
+#endif
+};
 
 static struct platform_driver mcp_sa11x0_driver = {
        .probe          = mcp_sa11x0_probe,
        .remove         = mcp_sa11x0_remove,
-       .suspend        = mcp_sa11x0_suspend,
-       .resume         = mcp_sa11x0_resume,
        .driver         = {
-               .name   = "sa11x0-mcp",
+               .name   = DRIVER_NAME,
+               .owner  = THIS_MODULE,
+               .pm     = &mcp_sa11x0_pm_ops,
        },
 };
 
@@ -259,6 +314,7 @@ static struct platform_driver mcp_sa11x0_driver = {
  */
 module_platform_driver(mcp_sa11x0_driver);
 
+MODULE_ALIAS("platform:" DRIVER_NAME);
 MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
 MODULE_DESCRIPTION("SA11x0 multimedia communications port driver");
 MODULE_LICENSE("GPL");
index cea9da60850d61f87c342f062483e2798b60e436..b63c0756a66917a60a55218dec79d9fbee283b75 100644 (file)
  */
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/device.h>
+#include <linux/err.h>
 #include <linux/fs.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
 #include <linux/proc_fs.h>
-#include <linux/device.h>
 #include <linux/mfd/ucb1x00.h>
 
-#include <mach/dma.h>
-
-
 #define UCB1X00_ATTR(name,input)\
 static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \
                           char *buf)   \
@@ -38,14 +39,45 @@ UCB1X00_ATTR(batt_temp, UCB_ADC_INP_AD2);
 
 static int ucb1x00_assabet_add(struct ucb1x00_dev *dev)
 {
-       device_create_file(&dev->ucb->dev, &dev_attr_vbatt);
-       device_create_file(&dev->ucb->dev, &dev_attr_vcharger);
-       device_create_file(&dev->ucb->dev, &dev_attr_batt_temp);
+       struct ucb1x00 *ucb = dev->ucb;
+       struct platform_device *pdev;
+       struct gpio_keys_platform_data keys;
+       static struct gpio_keys_button buttons[6];
+       unsigned i;
+
+       memset(buttons, 0, sizeof(buttons));
+       memset(&keys, 0, sizeof(keys));
+
+       for (i = 0; i < ARRAY_SIZE(buttons); i++) {
+               buttons[i].code = BTN_0 + i;
+               buttons[i].gpio = ucb->gpio.base + i;
+               buttons[i].type = EV_KEY;
+               buttons[i].can_disable = true;
+       }
+
+       keys.buttons = buttons;
+       keys.nbuttons = ARRAY_SIZE(buttons);
+       keys.poll_interval = 50;
+       keys.name = "ucb1x00";
+
+       pdev = platform_device_register_data(&ucb->dev, "gpio-keys", -1,
+               &keys, sizeof(keys));
+
+       device_create_file(&ucb->dev, &dev_attr_vbatt);
+       device_create_file(&ucb->dev, &dev_attr_vcharger);
+       device_create_file(&ucb->dev, &dev_attr_batt_temp);
+
+       dev->priv = pdev;
        return 0;
 }
 
 static void ucb1x00_assabet_remove(struct ucb1x00_dev *dev)
 {
+       struct platform_device *pdev = dev->priv;
+
+       if (!IS_ERR(pdev))
+               platform_device_unregister(pdev);
+
        device_remove_file(&dev->ucb->dev, &dev_attr_batt_temp);
        device_remove_file(&dev->ucb->dev, &dev_attr_vcharger);
        device_remove_file(&dev->ucb->dev, &dev_attr_vbatt);
index febc90cdef7ea4a97885f7cc88b36ceb543e8b7e..70f02daeb22a884da64297f26bc3f43e4e365aa8 100644 (file)
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/device.h>
 #include <linux/mutex.h>
 #include <linux/mfd/ucb1x00.h>
+#include <linux/pm.h>
 #include <linux/gpio.h>
-#include <linux/semaphore.h>
-
-#include <mach/dma.h>
-#include <mach/hardware.h>
 
 static DEFINE_MUTEX(ucb1x00_mutex);
 static LIST_HEAD(ucb1x00_drivers);
@@ -102,7 +100,7 @@ void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int set, unsigned int clear)
  *     ucb1x00_enable must have been called to enable the comms
  *     before using this function.
  *
- *     This function does not take any semaphores or spinlocks.
+ *     This function does not take any mutexes or spinlocks.
  */
 unsigned int ucb1x00_io_read(struct ucb1x00 *ucb)
 {
@@ -120,14 +118,22 @@ static void ucb1x00_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
        else
                ucb->io_out &= ~(1 << offset);
 
+       ucb1x00_enable(ucb);
        ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
+       ucb1x00_disable(ucb);
        spin_unlock_irqrestore(&ucb->io_lock, flags);
 }
 
 static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
        struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
-       return ucb1x00_reg_read(ucb, UCB_IO_DATA) & (1 << offset);
+       unsigned val;
+
+       ucb1x00_enable(ucb);
+       val = ucb1x00_reg_read(ucb, UCB_IO_DATA);
+       ucb1x00_disable(ucb);
+
+       return val & (1 << offset);
 }
 
 static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
@@ -137,7 +143,9 @@ static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 
        spin_lock_irqsave(&ucb->io_lock, flags);
        ucb->io_dir &= ~(1 << offset);
+       ucb1x00_enable(ucb);
        ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
+       ucb1x00_disable(ucb);
        spin_unlock_irqrestore(&ucb->io_lock, flags);
 
        return 0;
@@ -157,6 +165,7 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
        else
                ucb->io_out &= ~mask;
 
+       ucb1x00_enable(ucb);
        if (old != ucb->io_out)
                ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
 
@@ -164,11 +173,19 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
                ucb->io_dir |= mask;
                ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
        }
+       ucb1x00_disable(ucb);
        spin_unlock_irqrestore(&ucb->io_lock, flags);
 
        return 0;
 }
 
+static int ucb1x00_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+       struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
+
+       return ucb->irq_base > 0 ? ucb->irq_base + offset : -ENXIO;
+}
+
 /*
  * UCB1300 data sheet says we must:
  *  1. enable ADC      => 5us (including reference startup time)
@@ -186,7 +203,7 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
  *     Any code wishing to use the ADC converter must call this
  *     function prior to using it.
  *
- *     This function takes the ADC semaphore to prevent two or more
+ *     This function takes the ADC mutex to prevent two or more
  *     concurrent uses, and therefore may sleep.  As a result, it
  *     can only be called from process context, not interrupt
  *     context.
@@ -196,7 +213,7 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
  */
 void ucb1x00_adc_enable(struct ucb1x00 *ucb)
 {
-       down(&ucb->adc_sem);
+       mutex_lock(&ucb->adc_mutex);
 
        ucb->adc_cr |= UCB_ADC_ENA;
 
@@ -218,7 +235,7 @@ void ucb1x00_adc_enable(struct ucb1x00 *ucb)
  *     complete (2 frames max without sync).
  *
  *     If called for a synchronised ADC conversion, it may sleep
- *     with the ADC semaphore held.
+ *     with the ADC mutex held.
  */
 unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync)
 {
@@ -246,7 +263,7 @@ unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync)
  *     ucb1x00_adc_disable - disable the ADC converter
  *     @ucb: UCB1x00 structure describing chip
  *
- *     Disable the ADC converter and release the ADC semaphore.
+ *     Disable the ADC converter and release the ADC mutex.
  */
 void ucb1x00_adc_disable(struct ucb1x00 *ucb)
 {
@@ -254,7 +271,7 @@ void ucb1x00_adc_disable(struct ucb1x00 *ucb)
        ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr);
        ucb1x00_disable(ucb);
 
-       up(&ucb->adc_sem);
+       mutex_unlock(&ucb->adc_mutex);
 }
 
 /*
@@ -265,10 +282,9 @@ void ucb1x00_adc_disable(struct ucb1x00 *ucb)
  * SIBCLK to talk to the chip.  We leave the clock running until
  * we have finished processing all interrupts from the chip.
  */
-static irqreturn_t ucb1x00_irq(int irqnr, void *devid)
+static void ucb1x00_irq(unsigned int irq, struct irq_desc *desc)
 {
-       struct ucb1x00 *ucb = devid;
-       struct ucb1x00_irq *irq;
+       struct ucb1x00 *ucb = irq_desc_get_handler_data(desc);
        unsigned int isr, i;
 
        ucb1x00_enable(ucb);
@@ -276,157 +292,104 @@ static irqreturn_t ucb1x00_irq(int irqnr, void *devid)
        ucb1x00_reg_write(ucb, UCB_IE_CLEAR, isr);
        ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
 
-       for (i = 0, irq = ucb->irq_handler; i < 16 && isr; i++, isr >>= 1, irq++)
-               if (isr & 1 && irq->fn)
-                       irq->fn(i, irq->devid);
+       for (i = 0; i < 16 && isr; i++, isr >>= 1, irq++)
+               if (isr & 1)
+                       generic_handle_irq(ucb->irq_base + i);
        ucb1x00_disable(ucb);
-
-       return IRQ_HANDLED;
 }
 
-/**
- *     ucb1x00_hook_irq - hook a UCB1x00 interrupt
- *     @ucb:   UCB1x00 structure describing chip
- *     @idx:   interrupt index
- *     @fn:    function to call when interrupt is triggered
- *     @devid: device id to pass to interrupt handler
- *
- *     Hook the specified interrupt.  You can only register one handler
- *     for each interrupt source.  The interrupt source is not enabled
- *     by this function; use ucb1x00_enable_irq instead.
- *
- *     Interrupt handlers will be called with other interrupts enabled.
- *
- *     Returns zero on success, or one of the following errors:
- *      -EINVAL if the interrupt index is invalid
- *      -EBUSY if the interrupt has already been hooked
- */
-int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid)
+static void ucb1x00_irq_update(struct ucb1x00 *ucb, unsigned mask)
 {
-       struct ucb1x00_irq *irq;
-       int ret = -EINVAL;
-
-       if (idx < 16) {
-               irq = ucb->irq_handler + idx;
-               ret = -EBUSY;
-
-               spin_lock_irq(&ucb->lock);
-               if (irq->fn == NULL) {
-                       irq->devid = devid;
-                       irq->fn = fn;
-                       ret = 0;
-               }
-               spin_unlock_irq(&ucb->lock);
-       }
-       return ret;
+       ucb1x00_enable(ucb);
+       if (ucb->irq_ris_enbl & mask)
+               ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl &
+                                 ucb->irq_mask);
+       if (ucb->irq_fal_enbl & mask)
+               ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl &
+                                 ucb->irq_mask);
+       ucb1x00_disable(ucb);
 }
 
-/**
- *     ucb1x00_enable_irq - enable an UCB1x00 interrupt source
- *     @ucb: UCB1x00 structure describing chip
- *     @idx: interrupt index
- *     @edges: interrupt edges to enable
- *
- *     Enable the specified interrupt to trigger on %UCB_RISING,
- *     %UCB_FALLING or both edges.  The interrupt should have been
- *     hooked by ucb1x00_hook_irq.
- */
-void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges)
+static void ucb1x00_irq_noop(struct irq_data *data)
 {
-       unsigned long flags;
+}
 
-       if (idx < 16) {
-               spin_lock_irqsave(&ucb->lock, flags);
+static void ucb1x00_irq_mask(struct irq_data *data)
+{
+       struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data);
+       unsigned mask = 1 << (data->irq - ucb->irq_base);
 
-               ucb1x00_enable(ucb);
-               if (edges & UCB_RISING) {
-                       ucb->irq_ris_enbl |= 1 << idx;
-                       ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
-               }
-               if (edges & UCB_FALLING) {
-                       ucb->irq_fal_enbl |= 1 << idx;
-                       ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
-               }
-               ucb1x00_disable(ucb);
-               spin_unlock_irqrestore(&ucb->lock, flags);
-       }
+       raw_spin_lock(&ucb->irq_lock);
+       ucb->irq_mask &= ~mask;
+       ucb1x00_irq_update(ucb, mask);
+       raw_spin_unlock(&ucb->irq_lock);
 }
 
-/**
- *     ucb1x00_disable_irq - disable an UCB1x00 interrupt source
- *     @ucb: UCB1x00 structure describing chip
- *     @edges: interrupt edges to disable
- *
- *     Disable the specified interrupt triggering on the specified
- *     (%UCB_RISING, %UCB_FALLING or both) edges.
- */
-void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges)
+static void ucb1x00_irq_unmask(struct irq_data *data)
 {
-       unsigned long flags;
+       struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data);
+       unsigned mask = 1 << (data->irq - ucb->irq_base);
 
-       if (idx < 16) {
-               spin_lock_irqsave(&ucb->lock, flags);
-
-               ucb1x00_enable(ucb);
-               if (edges & UCB_RISING) {
-                       ucb->irq_ris_enbl &= ~(1 << idx);
-                       ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
-               }
-               if (edges & UCB_FALLING) {
-                       ucb->irq_fal_enbl &= ~(1 << idx);
-                       ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
-               }
-               ucb1x00_disable(ucb);
-               spin_unlock_irqrestore(&ucb->lock, flags);
-       }
+       raw_spin_lock(&ucb->irq_lock);
+       ucb->irq_mask |= mask;
+       ucb1x00_irq_update(ucb, mask);
+       raw_spin_unlock(&ucb->irq_lock);
 }
 
-/**
- *     ucb1x00_free_irq - disable and free the specified UCB1x00 interrupt
- *     @ucb: UCB1x00 structure describing chip
- *     @idx: interrupt index
- *     @devid: device id.
- *
- *     Disable the interrupt source and remove the handler.  devid must
- *     match the devid passed when hooking the interrupt.
- *
- *     Returns zero on success, or one of the following errors:
- *      -EINVAL if the interrupt index is invalid
- *      -ENOENT if devid does not match
- */
-int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid)
+static int ucb1x00_irq_set_type(struct irq_data *data, unsigned int type)
 {
-       struct ucb1x00_irq *irq;
-       int ret;
+       struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data);
+       unsigned mask = 1 << (data->irq - ucb->irq_base);
 
-       if (idx >= 16)
-               goto bad;
+       raw_spin_lock(&ucb->irq_lock);
+       if (type & IRQ_TYPE_EDGE_RISING)
+               ucb->irq_ris_enbl |= mask;
+       else
+               ucb->irq_ris_enbl &= ~mask;
 
-       irq = ucb->irq_handler + idx;
-       ret = -ENOENT;
+       if (type & IRQ_TYPE_EDGE_FALLING)
+               ucb->irq_fal_enbl |= mask;
+       else
+               ucb->irq_fal_enbl &= ~mask;
+       if (ucb->irq_mask & mask) {
+               ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl &
+                                 ucb->irq_mask);
+               ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl &
+                                 ucb->irq_mask);
+       }
+       raw_spin_unlock(&ucb->irq_lock);
 
-       spin_lock_irq(&ucb->lock);
-       if (irq->devid == devid) {
-               ucb->irq_ris_enbl &= ~(1 << idx);
-               ucb->irq_fal_enbl &= ~(1 << idx);
+       return 0;
+}
 
-               ucb1x00_enable(ucb);
-               ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
-               ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
-               ucb1x00_disable(ucb);
+static int ucb1x00_irq_set_wake(struct irq_data *data, unsigned int on)
+{
+       struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data);
+       struct ucb1x00_plat_data *pdata = ucb->mcp->attached_device.platform_data;
+       unsigned mask = 1 << (data->irq - ucb->irq_base);
 
-               irq->fn = NULL;
-               irq->devid = NULL;
-               ret = 0;
-       }
-       spin_unlock_irq(&ucb->lock);
-       return ret;
+       if (!pdata || !pdata->can_wakeup)
+               return -EINVAL;
 
-bad:
-       printk(KERN_ERR "Freeing bad UCB1x00 irq %d\n", idx);
-       return -EINVAL;
+       raw_spin_lock(&ucb->irq_lock);
+       if (on)
+               ucb->irq_wake |= mask;
+       else
+               ucb->irq_wake &= ~mask;
+       raw_spin_unlock(&ucb->irq_lock);
+
+       return 0;
 }
 
+static struct irq_chip ucb1x00_irqchip = {
+       .name = "ucb1x00",
+       .irq_ack = ucb1x00_irq_noop,
+       .irq_mask = ucb1x00_irq_mask,
+       .irq_unmask = ucb1x00_irq_unmask,
+       .irq_set_type = ucb1x00_irq_set_type,
+       .irq_set_wake = ucb1x00_irq_set_wake,
+};
+
 static int ucb1x00_add_dev(struct ucb1x00 *ucb, struct ucb1x00_driver *drv)
 {
        struct ucb1x00_dev *dev;
@@ -440,8 +403,8 @@ static int ucb1x00_add_dev(struct ucb1x00 *ucb, struct ucb1x00_driver *drv)
                ret = drv->add(dev);
 
                if (ret == 0) {
-                       list_add(&dev->dev_node, &ucb->devs);
-                       list_add(&dev->drv_node, &drv->devs);
+                       list_add_tail(&dev->dev_node, &ucb->devs);
+                       list_add_tail(&dev->drv_node, &drv->devs);
                } else {
                        kfree(dev);
                }
@@ -533,98 +496,126 @@ static struct class ucb1x00_class = {
 
 static int ucb1x00_probe(struct mcp *mcp)
 {
-       struct ucb1x00 *ucb;
+       struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data;
        struct ucb1x00_driver *drv;
-       unsigned int id;
+       struct ucb1x00 *ucb;
+       unsigned id, i, irq_base;
        int ret = -ENODEV;
-       int temp;
+
+       /* Tell the platform to deassert the UCB1x00 reset */
+       if (pdata && pdata->reset)
+               pdata->reset(UCB_RST_PROBE);
 
        mcp_enable(mcp);
        id = mcp_reg_read(mcp, UCB_ID);
+       mcp_disable(mcp);
 
        if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_TC35143) {
                printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id);
-               goto err_disable;
+               goto out;
        }
 
        ucb = kzalloc(sizeof(struct ucb1x00), GFP_KERNEL);
        ret = -ENOMEM;
        if (!ucb)
-               goto err_disable;
-
+               goto out;
 
+       device_initialize(&ucb->dev);
        ucb->dev.class = &ucb1x00_class;
        ucb->dev.parent = &mcp->attached_device;
        dev_set_name(&ucb->dev, "ucb1x00");
 
-       spin_lock_init(&ucb->lock);
+       raw_spin_lock_init(&ucb->irq_lock);
        spin_lock_init(&ucb->io_lock);
-       sema_init(&ucb->adc_sem, 1);
+       mutex_init(&ucb->adc_mutex);
 
        ucb->id  = id;
        ucb->mcp = mcp;
+
+       ret = device_add(&ucb->dev);
+       if (ret)
+               goto err_dev_add;
+
+       ucb1x00_enable(ucb);
        ucb->irq = ucb1x00_detect_irq(ucb);
+       ucb1x00_disable(ucb);
        if (ucb->irq == NO_IRQ) {
-               printk(KERN_ERR "UCB1x00: IRQ probe failed\n");
+               dev_err(&ucb->dev, "IRQ probe failed\n");
                ret = -ENODEV;
-               goto err_free;
+               goto err_no_irq;
        }
 
        ucb->gpio.base = -1;
-       if (mcp->gpio_base != 0) {
+       irq_base = pdata ? pdata->irq_base : 0;
+       ucb->irq_base = irq_alloc_descs(-1, irq_base, 16, -1);
+       if (ucb->irq_base < 0) {
+               dev_err(&ucb->dev, "unable to allocate 16 irqs: %d\n",
+                       ucb->irq_base);
+               goto err_irq_alloc;
+       }
+
+       for (i = 0; i < 16; i++) {
+               unsigned irq = ucb->irq_base + i;
+
+               irq_set_chip_and_handler(irq, &ucb1x00_irqchip, handle_edge_irq);
+               irq_set_chip_data(irq, ucb);
+               set_irq_flags(irq, IRQF_VALID | IRQ_NOREQUEST);
+       }
+
+       irq_set_irq_type(ucb->irq, IRQ_TYPE_EDGE_RISING);
+       irq_set_handler_data(ucb->irq, ucb);
+       irq_set_chained_handler(ucb->irq, ucb1x00_irq);
+
+       if (pdata && pdata->gpio_base) {
                ucb->gpio.label = dev_name(&ucb->dev);
-               ucb->gpio.base = mcp->gpio_base;
+               ucb->gpio.dev = &ucb->dev;
+               ucb->gpio.owner = THIS_MODULE;
+               ucb->gpio.base = pdata->gpio_base;
                ucb->gpio.ngpio = 10;
                ucb->gpio.set = ucb1x00_gpio_set;
                ucb->gpio.get = ucb1x00_gpio_get;
                ucb->gpio.direction_input = ucb1x00_gpio_direction_input;
                ucb->gpio.direction_output = ucb1x00_gpio_direction_output;
+               ucb->gpio.to_irq = ucb1x00_to_irq;
                ret = gpiochip_add(&ucb->gpio);
                if (ret)
-                       goto err_free;
+                       goto err_gpio_add;
        } else
                dev_info(&ucb->dev, "gpio_base not set so no gpiolib support");
 
-       ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING,
-                         "UCB1x00", ucb);
-       if (ret) {
-               printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
-                       ucb->irq, ret);
-               goto err_gpio;
-       }
-
        mcp_set_drvdata(mcp, ucb);
 
-       ret = device_register(&ucb->dev);
-       if (ret)
-               goto err_irq;
-
+       if (pdata)
+               device_set_wakeup_capable(&ucb->dev, pdata->can_wakeup);
 
        INIT_LIST_HEAD(&ucb->devs);
        mutex_lock(&ucb1x00_mutex);
-       list_add(&ucb->node, &ucb1x00_devices);
+       list_add_tail(&ucb->node, &ucb1x00_devices);
        list_for_each_entry(drv, &ucb1x00_drivers, node) {
                ucb1x00_add_dev(ucb, drv);
        }
        mutex_unlock(&ucb1x00_mutex);
 
-       goto out;
+       return ret;
 
- err_irq:
-       free_irq(ucb->irq, ucb);
- err_gpio:
-       if (ucb->gpio.base != -1)
-               temp = gpiochip_remove(&ucb->gpio);
- err_free:
-       kfree(ucb);
- err_disable:
-       mcp_disable(mcp);
+ err_gpio_add:
+       irq_set_chained_handler(ucb->irq, NULL);
+ err_irq_alloc:
+       if (ucb->irq_base > 0)
+               irq_free_descs(ucb->irq_base, 16);
+ err_no_irq:
+       device_del(&ucb->dev);
+ err_dev_add:
+       put_device(&ucb->dev);
  out:
+       if (pdata && pdata->reset)
+               pdata->reset(UCB_RST_PROBE_FAIL);
        return ret;
 }
 
 static void ucb1x00_remove(struct mcp *mcp)
 {
+       struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data;
        struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
        struct list_head *l, *n;
        int ret;
@@ -643,8 +634,12 @@ static void ucb1x00_remove(struct mcp *mcp)
                        dev_err(&ucb->dev, "Can't remove gpio chip: %d\n", ret);
        }
 
-       free_irq(ucb->irq, ucb);
+       irq_set_chained_handler(ucb->irq, NULL);
+       irq_free_descs(ucb->irq_base, 16);
        device_unregister(&ucb->dev);
+
+       if (pdata && pdata->reset)
+               pdata->reset(UCB_RST_REMOVE);
 }
 
 int ucb1x00_register_driver(struct ucb1x00_driver *drv)
@@ -653,7 +648,7 @@ int ucb1x00_register_driver(struct ucb1x00_driver *drv)
 
        INIT_LIST_HEAD(&drv->devs);
        mutex_lock(&ucb1x00_mutex);
-       list_add(&drv->node, &ucb1x00_drivers);
+       list_add_tail(&drv->node, &ucb1x00_drivers);
        list_for_each_entry(ucb, &ucb1x00_devices, node) {
                ucb1x00_add_dev(ucb, drv);
        }
@@ -674,44 +669,86 @@ void ucb1x00_unregister_driver(struct ucb1x00_driver *drv)
        mutex_unlock(&ucb1x00_mutex);
 }
 
-static int ucb1x00_suspend(struct mcp *mcp, pm_message_t state)
+static int ucb1x00_suspend(struct device *dev)
 {
-       struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
-       struct ucb1x00_dev *dev;
+       struct ucb1x00_plat_data *pdata = dev->platform_data;
+       struct ucb1x00 *ucb = dev_get_drvdata(dev);
+       struct ucb1x00_dev *udev;
 
        mutex_lock(&ucb1x00_mutex);
-       list_for_each_entry(dev, &ucb->devs, dev_node) {
-               if (dev->drv->suspend)
-                       dev->drv->suspend(dev, state);
+       list_for_each_entry(udev, &ucb->devs, dev_node) {
+               if (udev->drv->suspend)
+                       udev->drv->suspend(udev);
        }
        mutex_unlock(&ucb1x00_mutex);
+
+       if (ucb->irq_wake) {
+               unsigned long flags;
+
+               raw_spin_lock_irqsave(&ucb->irq_lock, flags);
+               ucb1x00_enable(ucb);
+               ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl &
+                                 ucb->irq_wake);
+               ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl &
+                                 ucb->irq_wake);
+               ucb1x00_disable(ucb);
+               raw_spin_unlock_irqrestore(&ucb->irq_lock, flags);
+
+               enable_irq_wake(ucb->irq);
+       } else if (pdata && pdata->reset)
+               pdata->reset(UCB_RST_SUSPEND);
+
        return 0;
 }
 
-static int ucb1x00_resume(struct mcp *mcp)
+static int ucb1x00_resume(struct device *dev)
 {
-       struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
-       struct ucb1x00_dev *dev;
+       struct ucb1x00_plat_data *pdata = dev->platform_data;
+       struct ucb1x00 *ucb = dev_get_drvdata(dev);
+       struct ucb1x00_dev *udev;
+
+       if (!ucb->irq_wake && pdata && pdata->reset)
+               pdata->reset(UCB_RST_RESUME);
 
+       ucb1x00_enable(ucb);
        ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
        ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
+
+       if (ucb->irq_wake) {
+               unsigned long flags;
+
+               raw_spin_lock_irqsave(&ucb->irq_lock, flags);
+               ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl &
+                                 ucb->irq_mask);
+               ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl &
+                                 ucb->irq_mask);
+               raw_spin_unlock_irqrestore(&ucb->irq_lock, flags);
+
+               disable_irq_wake(ucb->irq);
+       }
+       ucb1x00_disable(ucb);
+
        mutex_lock(&ucb1x00_mutex);
-       list_for_each_entry(dev, &ucb->devs, dev_node) {
-               if (dev->drv->resume)
-                       dev->drv->resume(dev);
+       list_for_each_entry(udev, &ucb->devs, dev_node) {
+               if (udev->drv->resume)
+                       udev->drv->resume(udev);
        }
        mutex_unlock(&ucb1x00_mutex);
        return 0;
 }
 
+static const struct dev_pm_ops ucb1x00_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(ucb1x00_suspend, ucb1x00_resume)
+};
+
 static struct mcp_driver ucb1x00_driver = {
        .drv            = {
                .name   = "ucb1x00",
+               .owner  = THIS_MODULE,
+               .pm     = &ucb1x00_pm_ops,
        },
        .probe          = ucb1x00_probe,
        .remove         = ucb1x00_remove,
-       .suspend        = ucb1x00_suspend,
-       .resume         = ucb1x00_resume,
 };
 
 static int __init ucb1x00_init(void)
@@ -742,14 +779,10 @@ EXPORT_SYMBOL(ucb1x00_adc_enable);
 EXPORT_SYMBOL(ucb1x00_adc_read);
 EXPORT_SYMBOL(ucb1x00_adc_disable);
 
-EXPORT_SYMBOL(ucb1x00_hook_irq);
-EXPORT_SYMBOL(ucb1x00_free_irq);
-EXPORT_SYMBOL(ucb1x00_enable_irq);
-EXPORT_SYMBOL(ucb1x00_disable_irq);
-
 EXPORT_SYMBOL(ucb1x00_register_driver);
 EXPORT_SYMBOL(ucb1x00_unregister_driver);
 
+MODULE_ALIAS("mcp:ucb1x00");
 MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
 MODULE_DESCRIPTION("UCB1x00 core driver");
 MODULE_LICENSE("GPL");
index 63a3cbdfa3f33a85a146f34fff7459cc6b46c17a..1e0e20c0e082b07836f2ede84659ef7d6c40efc1 100644 (file)
@@ -20,8 +20,9 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
-#include <linux/smp.h>
+#include <linux/interrupt.h>
 #include <linux/sched.h>
+#include <linux/spinlock.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/string.h>
@@ -32,7 +33,6 @@
 #include <linux/kthread.h>
 #include <linux/mfd/ucb1x00.h>
 
-#include <mach/dma.h>
 #include <mach/collie.h>
 #include <asm/mach-types.h>
 
@@ -42,6 +42,8 @@ struct ucb1x00_ts {
        struct input_dev        *idev;
        struct ucb1x00          *ucb;
 
+       spinlock_t              irq_lock;
+       unsigned                irq_disabled;
        wait_queue_head_t       irq_wait;
        struct task_struct      *rtask;
        u16                     x_res;
@@ -238,7 +240,12 @@ static int ucb1x00_thread(void *_ts)
                if (ucb1x00_ts_pen_down(ts)) {
                        set_current_state(TASK_INTERRUPTIBLE);
 
-                       ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, machine_is_collie() ? UCB_RISING : UCB_FALLING);
+                       spin_lock_irq(&ts->irq_lock);
+                       if (ts->irq_disabled) {
+                               ts->irq_disabled = 0;
+                               enable_irq(ts->ucb->irq_base + UCB_IRQ_TSPX);
+                       }
+                       spin_unlock_irq(&ts->irq_lock);
                        ucb1x00_disable(ts->ucb);
 
                        /*
@@ -281,23 +288,37 @@ static int ucb1x00_thread(void *_ts)
  * We only detect touch screen _touches_ with this interrupt
  * handler, and even then we just schedule our task.
  */
-static void ucb1x00_ts_irq(int idx, void *id)
+static irqreturn_t ucb1x00_ts_irq(int irq, void *id)
 {
        struct ucb1x00_ts *ts = id;
 
-       ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
+       spin_lock(&ts->irq_lock);
+       ts->irq_disabled = 1;
+       disable_irq_nosync(ts->ucb->irq_base + UCB_IRQ_TSPX);
+       spin_unlock(&ts->irq_lock);
        wake_up(&ts->irq_wait);
+
+       return IRQ_HANDLED;
 }
 
 static int ucb1x00_ts_open(struct input_dev *idev)
 {
        struct ucb1x00_ts *ts = input_get_drvdata(idev);
+       unsigned long flags = 0;
        int ret = 0;
 
        BUG_ON(ts->rtask);
 
+       if (machine_is_collie())
+               flags = IRQF_TRIGGER_RISING;
+       else
+               flags = IRQF_TRIGGER_FALLING;
+
+       ts->irq_disabled = 0;
+
        init_waitqueue_head(&ts->irq_wait);
-       ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_TSPX, ucb1x00_ts_irq, ts);
+       ret = request_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ucb1x00_ts_irq,
+                         flags, "ucb1x00-ts", ts);
        if (ret < 0)
                goto out;
 
@@ -314,7 +335,7 @@ static int ucb1x00_ts_open(struct input_dev *idev)
        if (!IS_ERR(ts->rtask)) {
                ret = 0;
        } else {
-               ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
+               free_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ts);
                ts->rtask = NULL;
                ret = -EFAULT;
        }
@@ -334,7 +355,7 @@ static void ucb1x00_ts_close(struct input_dev *idev)
                kthread_stop(ts->rtask);
 
        ucb1x00_enable(ts->ucb);
-       ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
+       free_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ts);
        ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 0);
        ucb1x00_disable(ts->ucb);
 }
@@ -359,11 +380,13 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
        ts->ucb = dev->ucb;
        ts->idev = idev;
        ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
+       spin_lock_init(&ts->irq_lock);
 
        idev->name       = "Touchscreen panel";
        idev->id.product = ts->ucb->id;
        idev->open       = ucb1x00_ts_open;
        idev->close      = ucb1x00_ts_close;
+       idev->dev.parent = &ts->ucb->dev;
 
        idev->evbit[0]   = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
        idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
index 4bcfc375973429a07dbcccf2558ef40237e20f00..c8d8e38d0d8ae6dc47cc0d85b581388896ae5361 100644 (file)
@@ -6,12 +6,10 @@
 #include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/export.h>
-
-/* Number of bytes to reserve for the iomem resource */
-#define ATMEL_TC_IOMEM_SIZE    256
-
+#include <linux/of.h>
 
 /*
  * This is a thin library to solve the problem of how to portably allocate
@@ -48,10 +46,17 @@ struct atmel_tc *atmel_tc_alloc(unsigned block, const char *name)
        struct atmel_tc         *tc;
        struct platform_device  *pdev = NULL;
        struct resource         *r;
+       size_t                  size;
 
        spin_lock(&tc_list_lock);
        list_for_each_entry(tc, &tc_list, node) {
-               if (tc->pdev->id == block) {
+               if (tc->pdev->dev.of_node) {
+                       if (of_alias_get_id(tc->pdev->dev.of_node, "tcb")
+                                       == block) {
+                               pdev = tc->pdev;
+                               break;
+                       }
+               } else if (tc->pdev->id == block) {
                        pdev = tc->pdev;
                        break;
                }
@@ -61,11 +66,15 @@ struct atmel_tc *atmel_tc_alloc(unsigned block, const char *name)
                goto fail;
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       r = request_mem_region(r->start, ATMEL_TC_IOMEM_SIZE, name);
        if (!r)
                goto fail;
 
-       tc->regs = ioremap(r->start, ATMEL_TC_IOMEM_SIZE);
+       size = resource_size(r);
+       r = request_mem_region(r->start, size, name);
+       if (!r)
+               goto fail;
+
+       tc->regs = ioremap(r->start, size);
        if (!tc->regs)
                goto fail_ioremap;
 
@@ -76,7 +85,7 @@ out:
        return tc;
 
 fail_ioremap:
-       release_mem_region(r->start, ATMEL_TC_IOMEM_SIZE);
+       release_mem_region(r->start, size);
 fail:
        tc = NULL;
        goto out;
@@ -96,7 +105,7 @@ void atmel_tc_free(struct atmel_tc *tc)
        spin_lock(&tc_list_lock);
        if (tc->regs) {
                iounmap(tc->regs);
-               release_mem_region(tc->iomem->start, ATMEL_TC_IOMEM_SIZE);
+               release_mem_region(tc->iomem->start, resource_size(tc->iomem));
                tc->regs = NULL;
                tc->iomem = NULL;
        }
@@ -104,6 +113,30 @@ void atmel_tc_free(struct atmel_tc *tc)
 }
 EXPORT_SYMBOL_GPL(atmel_tc_free);
 
+#if defined(CONFIG_OF)
+static struct atmel_tcb_config tcb_rm9200_config = {
+       .counter_width = 16,
+};
+
+static struct atmel_tcb_config tcb_sam9x5_config = {
+       .counter_width = 32,
+};
+
+static const struct of_device_id atmel_tcb_dt_ids[] = {
+       {
+               .compatible = "atmel,at91rm9200-tcb",
+               .data = &tcb_rm9200_config,
+       }, {
+               .compatible = "atmel,at91sam9x5-tcb",
+               .data = &tcb_sam9x5_config,
+       }, {
+               /* sentinel */
+       }
+};
+
+MODULE_DEVICE_TABLE(of, atmel_tcb_dt_ids);
+#endif
+
 static int __init tc_probe(struct platform_device *pdev)
 {
        struct atmel_tc *tc;
@@ -129,6 +162,14 @@ static int __init tc_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
+       /* Now take SoC information if available */
+       if (pdev->dev.of_node) {
+               const struct of_device_id *match;
+               match = of_match_node(atmel_tcb_dt_ids, pdev->dev.of_node);
+               if (match)
+                       tc->tcb_config = match->data;
+       }
+
        tc->clk[0] = clk;
        tc->clk[1] = clk_get(&pdev->dev, "t1_clk");
        if (IS_ERR(tc->clk[1]))
@@ -153,7 +194,10 @@ static int __init tc_probe(struct platform_device *pdev)
 }
 
 static struct platform_driver tc_driver = {
-       .driver.name    = "atmel_tcb",
+       .driver = {
+               .name   = "atmel_tcb",
+               .of_match_table = of_match_ptr(atmel_tcb_dt_ids),
+       },
 };
 
 static int __init tc_init(void)
index 00fcbed1afd28b416bff41ec30c34ec0f69b1d91..ecbee9bf87b2ef00cf18f54ff6968fe4f2616adf 100644 (file)
@@ -395,7 +395,7 @@ config MMC_SPI
 
 config MMC_S3C
        tristate "Samsung S3C SD/MMC Card Interface support"
-       depends on ARCH_S3C2410
+       depends on ARCH_S3C24XX
        help
          This selects a driver for the MCI interface found in
           Samsung's S3C2410, S3C2412, S3C2440, S3C2442 CPUs.
index 947faa5d2ce4ebb243f049bca62430541c286efa..efdb81d21c44cdee4cd57220f7acd270956ef80a 100644 (file)
@@ -86,7 +86,6 @@ static inline int at91mci_is_mci1rev2xx(void)
 {
        return (   cpu_is_at91sam9260()
                || cpu_is_at91sam9263()
-               || cpu_is_at91cap9()
                || cpu_is_at91sam9rl()
                || cpu_is_at91sam9g10()
                || cpu_is_at91sam9g20()
index 0be4e2013632f97ce4dddc489212c2ed6f7c4985..6193a0d7bde52b8cc29e52837179d90eed50faeb 100644 (file)
@@ -464,7 +464,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
                err = PTR_ERR(clk);
                goto err_clk_get;
        }
-       clk_enable(clk);
+       clk_prepare_enable(clk);
        pltfm_host->clk = clk;
 
        if (!is_imx25_esdhc(imx_data))
@@ -559,7 +559,7 @@ no_card_detect_irq:
                gpio_free(boarddata->wp_gpio);
 no_card_detect_pin:
 no_board_data:
-       clk_disable(pltfm_host->clk);
+       clk_disable_unprepare(pltfm_host->clk);
        clk_put(pltfm_host->clk);
 err_clk_get:
        kfree(imx_data);
@@ -586,7 +586,7 @@ static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev)
                gpio_free(boarddata->cd_gpio);
        }
 
-       clk_disable(pltfm_host->clk);
+       clk_disable_unprepare(pltfm_host->clk);
        clk_put(pltfm_host->clk);
        kfree(imx_data);
 
index 1af756ee0f9ab5e43db1a348505021a6fd5eee28..b19e7d435f8d6d1561a60156dff038c7508e0e2e 100644 (file)
@@ -518,9 +518,6 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
        if (pdata->cd_type == S3C_SDHCI_CD_PERMANENT)
                host->mmc->caps = MMC_CAP_NONREMOVABLE;
 
-       if (pdata->host_caps)
-               host->mmc->caps |= pdata->host_caps;
-
        if (pdata->pm_caps)
                host->mmc->pm_caps |= pdata->pm_caps;
 
@@ -544,6 +541,9 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
        if (pdata->host_caps)
                host->mmc->caps |= pdata->host_caps;
 
+       if (pdata->host_caps2)
+               host->mmc->caps2 |= pdata->host_caps2;
+
        ret = sdhci_add_host(host);
        if (ret) {
                dev_err(dev, "sdhci_add_host() failed\n");
index 1be621841400f9c2221f433e0f5b13e02619cc40..284cf3433720fe07233ce5c380e3668999d4b94e 100644 (file)
@@ -1,6 +1,6 @@
 menuconfig MTD
        tristate "Memory Technology Device (MTD) support"
-       depends on HAS_IOMEM
+       depends on GENERIC_IO
        help
          Memory Technology Devices are flash, RAM and similar chips, often
          used for solid state file systems on embedded devices. This option
index 37b05c3f2792a2bbc73521c52f4e69f8b45991cb..8d3dac40d7e6e17411936a34a6e50b226ad78667 100644 (file)
@@ -1,5 +1,6 @@
 menu "Self-contained MTD device drivers"
        depends on MTD!=n
+       depends on HAS_IOMEM
 
 config MTD_PMC551
        tristate "Ramix PMC551 PCI Mezzanine RAM card support"
index 6c5c431c64af3ed6fbf97d1bb763049bf119872b..8af67cfd671acac48ad7885a6e73ebe2f0ecdbff 100644 (file)
@@ -1,5 +1,6 @@
 menu "Mapping drivers for chip access"
        depends on MTD!=n
+       depends on HAS_IOMEM
 
 config MTD_COMPLEX_MAPPINGS
        bool "Support non-linear mappings of flash chips"
index 50282199770742eb6d78cb5701741623a3b4689a..cbc3b7867910ac421488c9531fbd3799875ea41b 100644 (file)
 #include <asm/sizes.h>
 #include <asm/mach/flash.h>
 
-#if 0
-/*
- * This is here for documentation purposes only - until these people
- * submit their machine types.  It will be gone January 2005.
- */
-static struct mtd_partition consus_partitions[] = {
-       {
-               .name           = "Consus boot firmware",
-               .offset         = 0,
-               .size           = 0x00040000,
-               .mask_flags     = MTD_WRITABLE, /* force read-only */
-       }, {
-               .name           = "Consus kernel",
-               .offset         = 0x00040000,
-               .size           = 0x00100000,
-               .mask_flags     = 0,
-       }, {
-               .name           = "Consus disk",
-               .offset         = 0x00140000,
-               /* The rest (up to 16M) for jffs.  We could put 0 and
-                  make it find the size automatically, but right now
-                  i have 32 megs.  jffs will use all 32 megs if given
-                  the chance, and this leads to horrible problems
-                  when you try to re-flash the image because blob
-                  won't erase the whole partition. */
-               .size           = 0x01000000 - 0x00140000,
-               .mask_flags     = 0,
-       }, {
-               /* this disk is a secondary disk, which can be used as
-                  needed, for simplicity, make it the size of the other
-                  consus partition, although realistically it could be
-                  the remainder of the disk (depending on the file
-                  system used) */
-                .name          = "Consus disk2",
-                .offset        = 0x01000000,
-                .size          = 0x01000000 - 0x00140000,
-                .mask_flags    = 0,
-       }
-};
-
-/* Frodo has 2 x 16M 28F128J3A flash chips in bank 0: */
-static struct mtd_partition frodo_partitions[] =
-{
-       {
-               .name           = "bootloader",
-               .size           = 0x00040000,
-               .offset         = 0x00000000,
-               .mask_flags     = MTD_WRITEABLE
-       }, {
-               .name           = "bootloader params",
-               .size           = 0x00040000,
-               .offset         = MTDPART_OFS_APPEND,
-               .mask_flags     = MTD_WRITEABLE
-       }, {
-               .name           = "kernel",
-               .size           = 0x00100000,
-               .offset         = MTDPART_OFS_APPEND,
-               .mask_flags     = MTD_WRITEABLE
-       }, {
-               .name           = "ramdisk",
-               .size           = 0x00400000,
-               .offset         = MTDPART_OFS_APPEND,
-               .mask_flags     = MTD_WRITEABLE
-       }, {
-               .name           = "file system",
-               .size           = MTDPART_SIZ_FULL,
-               .offset         = MTDPART_OFS_APPEND
-       }
-};
-
-static struct mtd_partition jornada56x_partitions[] = {
-       {
-               .name           = "bootldr",
-               .size           = 0x00040000,
-               .offset         = 0,
-               .mask_flags     = MTD_WRITEABLE,
-       }, {
-               .name           = "rootfs",
-               .size           = MTDPART_SIZ_FULL,
-               .offset         = MTDPART_OFS_APPEND,
-       }
-};
-
-static void jornada56x_set_vpp(int vpp)
-{
-       if (vpp)
-               GPSR = GPIO_GPIO26;
-       else
-               GPCR = GPIO_GPIO26;
-       GPDR |= GPIO_GPIO26;
-}
-
-/*
- * Machine        Phys          Size    set_vpp
- * Consus    : SA1100_CS0_PHYS SZ_32M
- * Frodo     : SA1100_CS0_PHYS SZ_32M
- * Jornada56x: SA1100_CS0_PHYS SZ_32M jornada56x_set_vpp
- */
-#endif
-
 struct sa_subdev_info {
        char name[16];
        struct map_info map;
@@ -373,21 +273,9 @@ static int __exit sa1100_mtd_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_PM
-static void sa1100_mtd_shutdown(struct platform_device *dev)
-{
-       struct sa_info *info = platform_get_drvdata(dev);
-       if (info && mtd_suspend(info->mtd) == 0)
-               mtd_resume(info->mtd);
-}
-#else
-#define sa1100_mtd_shutdown NULL
-#endif
-
 static struct platform_driver sa1100_mtd_driver = {
        .probe          = sa1100_mtd_probe,
        .remove         = __exit_p(sa1100_mtd_remove),
-       .shutdown       = sa1100_mtd_shutdown,
        .driver         = {
                .name   = "sa1100-mtd",
                .owner  = THIS_MODULE,
index 3b1d6da874e03de79e39afcee576d859fac3caa9..a3c4de551ebee12239c07738f9d9896a3b26060f 100644 (file)
@@ -187,7 +187,7 @@ config MTD_NAND_PPCHAMELEONEVB
 
 config MTD_NAND_S3C2410
        tristate "NAND Flash support for Samsung S3C SoCs"
-       depends on ARCH_S3C2410 || ARCH_S3C64XX
+       depends on ARCH_S3C24XX || ARCH_S3C64XX
        help
          This enables the NAND flash controller on the S3C24xx and S3C64xx
          SoCs
@@ -246,6 +246,7 @@ config MTD_NAND_BCM_UMI_HWCS
 config MTD_NAND_DISKONCHIP
        tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation) (EXPERIMENTAL)"
        depends on EXPERIMENTAL
+       depends on HAS_IOMEM
        select REED_SOLOMON
        select REED_SOLOMON_DEC16
        help
@@ -431,6 +432,7 @@ config MTD_NAND_GPMI_NAND
 
 config MTD_NAND_PLATFORM
        tristate "Support for generic platform NAND driver"
+       depends on HAS_IOMEM
        help
          This implements a generic NAND driver for on-SOC platform
          devices. You will need to provide platform-specific functions
index 3197e9764fcd32025c6ea715a05765ca4e45c30c..73416951f4c1f6bdd52b53c8f2ebe1967fae4d47 100644 (file)
@@ -26,7 +26,7 @@
 #include <asm/io.h>
 #include <mach/hardware.h>
 #include <asm/sizes.h>
-#include <asm/gpio.h>
+#include <linux/gpio.h>
 #include <plat/board-ams-delta.h>
 
 /*
@@ -34,8 +34,6 @@
  */
 static struct mtd_info *ams_delta_mtd = NULL;
 
-#define NAND_MASK (AMS_DELTA_LATCH2_NAND_NRE | AMS_DELTA_LATCH2_NAND_NWE | AMS_DELTA_LATCH2_NAND_CLE | AMS_DELTA_LATCH2_NAND_ALE | AMS_DELTA_LATCH2_NAND_NCE | AMS_DELTA_LATCH2_NAND_NWP)
-
 /*
  * Define partitions for flash devices
  */
@@ -68,10 +66,9 @@ static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte)
 
        writew(0, io_base + OMAP_MPUIO_IO_CNTL);
        writew(byte, this->IO_ADDR_W);
-       ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NWE, 0);
+       gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NWE, 0);
        ndelay(40);
-       ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NWE,
-                              AMS_DELTA_LATCH2_NAND_NWE);
+       gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NWE, 1);
 }
 
 static u_char ams_delta_read_byte(struct mtd_info *mtd)
@@ -80,12 +77,11 @@ static u_char ams_delta_read_byte(struct mtd_info *mtd)
        struct nand_chip *this = mtd->priv;
        void __iomem *io_base = this->priv;
 
-       ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NRE, 0);
+       gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NRE, 0);
        ndelay(40);
        writew(~0, io_base + OMAP_MPUIO_IO_CNTL);
        res = readw(this->IO_ADDR_R);
-       ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NRE,
-                              AMS_DELTA_LATCH2_NAND_NRE);
+       gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NRE, 1);
 
        return res;
 }
@@ -132,15 +128,12 @@ static void ams_delta_hwcontrol(struct mtd_info *mtd, int cmd,
 {
 
        if (ctrl & NAND_CTRL_CHANGE) {
-               unsigned long bits;
-
-               bits = (~ctrl & NAND_NCE) ? AMS_DELTA_LATCH2_NAND_NCE : 0;
-               bits |= (ctrl & NAND_CLE) ? AMS_DELTA_LATCH2_NAND_CLE : 0;
-               bits |= (ctrl & NAND_ALE) ? AMS_DELTA_LATCH2_NAND_ALE : 0;
-
-               ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_CLE |
-                               AMS_DELTA_LATCH2_NAND_ALE |
-                               AMS_DELTA_LATCH2_NAND_NCE, bits);
+               gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NCE,
+                               (ctrl & NAND_NCE) == 0);
+               gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_CLE,
+                               (ctrl & NAND_CLE) != 0);
+               gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_ALE,
+                               (ctrl & NAND_ALE) != 0);
        }
 
        if (cmd != NAND_CMD_NONE)
@@ -152,6 +145,39 @@ static int ams_delta_nand_ready(struct mtd_info *mtd)
        return gpio_get_value(AMS_DELTA_GPIO_PIN_NAND_RB);
 }
 
+static const struct gpio _mandatory_gpio[] = {
+       {
+               .gpio   = AMS_DELTA_GPIO_PIN_NAND_NCE,
+               .flags  = GPIOF_OUT_INIT_HIGH,
+               .label  = "nand_nce",
+       },
+       {
+               .gpio   = AMS_DELTA_GPIO_PIN_NAND_NRE,
+               .flags  = GPIOF_OUT_INIT_HIGH,
+               .label  = "nand_nre",
+       },
+       {
+               .gpio   = AMS_DELTA_GPIO_PIN_NAND_NWP,
+               .flags  = GPIOF_OUT_INIT_HIGH,
+               .label  = "nand_nwp",
+       },
+       {
+               .gpio   = AMS_DELTA_GPIO_PIN_NAND_NWE,
+               .flags  = GPIOF_OUT_INIT_HIGH,
+               .label  = "nand_nwe",
+       },
+       {
+               .gpio   = AMS_DELTA_GPIO_PIN_NAND_ALE,
+               .flags  = GPIOF_OUT_INIT_LOW,
+               .label  = "nand_ale",
+       },
+       {
+               .gpio   = AMS_DELTA_GPIO_PIN_NAND_CLE,
+               .flags  = GPIOF_OUT_INIT_LOW,
+               .label  = "nand_cle",
+       },
+};
+
 /*
  * Main initialization routine
  */
@@ -223,10 +249,9 @@ static int __devinit ams_delta_init(struct platform_device *pdev)
        platform_set_drvdata(pdev, io_base);
 
        /* Set chip enabled, but  */
-       ams_delta_latch2_write(NAND_MASK, AMS_DELTA_LATCH2_NAND_NRE |
-                                         AMS_DELTA_LATCH2_NAND_NWE |
-                                         AMS_DELTA_LATCH2_NAND_NCE |
-                                         AMS_DELTA_LATCH2_NAND_NWP);
+       err = gpio_request_array(_mandatory_gpio, ARRAY_SIZE(_mandatory_gpio));
+       if (err)
+               goto out_gpio;
 
        /* Scan to find existence of the device */
        if (nand_scan(ams_delta_mtd, 1)) {
@@ -241,7 +266,10 @@ static int __devinit ams_delta_init(struct platform_device *pdev)
        goto out;
 
  out_mtd:
+       gpio_free_array(_mandatory_gpio, ARRAY_SIZE(_mandatory_gpio));
+out_gpio:
        platform_set_drvdata(pdev, NULL);
+       gpio_free(AMS_DELTA_GPIO_PIN_NAND_RB);
        iounmap(io_base);
 out_release_io:
        release_mem_region(res->start, resource_size(res));
@@ -262,6 +290,8 @@ static int __devexit ams_delta_cleanup(struct platform_device *pdev)
        /* Release resources, unregister device */
        nand_release(ams_delta_mtd);
 
+       gpio_free_array(_mandatory_gpio, ARRAY_SIZE(_mandatory_gpio));
+       gpio_free(AMS_DELTA_GPIO_PIN_NAND_RB);
        iounmap(io_base);
        release_mem_region(res->start, resource_size(res));
 
index 35b4fb55dbd6569dad6d4c927c9807698804b882..ae7e37d9ac172fa411d99aacbb4c3b196cdc5991 100644 (file)
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_mtd.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/dmaengine.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
+#include <linux/platform_data/atmel.h>
 
-#include <mach/board.h>
 #include <mach/cpu.h>
 
-#ifdef CONFIG_MTD_NAND_ATMEL_ECC_HW
-#define hard_ecc       1
-#else
-#define hard_ecc       0
-#endif
-
-#ifdef CONFIG_MTD_NAND_ATMEL_ECC_NONE
-#define no_ecc         1
-#else
-#define no_ecc         0
-#endif
-
 static int use_dma = 1;
 module_param(use_dma, int, 0);
 
@@ -95,7 +87,7 @@ struct atmel_nand_host {
        struct mtd_info         mtd;
        void __iomem            *io_base;
        dma_addr_t              io_phys;
-       struct atmel_nand_data  *board;
+       struct atmel_nand_data  board;
        struct device           *dev;
        void __iomem            *ecc;
 
@@ -113,8 +105,8 @@ static int cpu_has_dma(void)
  */
 static void atmel_nand_enable(struct atmel_nand_host *host)
 {
-       if (gpio_is_valid(host->board->enable_pin))
-               gpio_set_value(host->board->enable_pin, 0);
+       if (gpio_is_valid(host->board.enable_pin))
+               gpio_set_value(host->board.enable_pin, 0);
 }
 
 /*
@@ -122,8 +114,8 @@ static void atmel_nand_enable(struct atmel_nand_host *host)
  */
 static void atmel_nand_disable(struct atmel_nand_host *host)
 {
-       if (gpio_is_valid(host->board->enable_pin))
-               gpio_set_value(host->board->enable_pin, 1);
+       if (gpio_is_valid(host->board.enable_pin))
+               gpio_set_value(host->board.enable_pin, 1);
 }
 
 /*
@@ -144,9 +136,9 @@ static void atmel_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl
                return;
 
        if (ctrl & NAND_CLE)
-               writeb(cmd, host->io_base + (1 << host->board->cle));
+               writeb(cmd, host->io_base + (1 << host->board.cle));
        else
-               writeb(cmd, host->io_base + (1 << host->board->ale));
+               writeb(cmd, host->io_base + (1 << host->board.ale));
 }
 
 /*
@@ -157,8 +149,8 @@ static int atmel_nand_device_ready(struct mtd_info *mtd)
        struct nand_chip *nand_chip = mtd->priv;
        struct atmel_nand_host *host = nand_chip->priv;
 
-       return gpio_get_value(host->board->rdy_pin) ^
-                !!host->board->rdy_pin_active_low;
+       return gpio_get_value(host->board.rdy_pin) ^
+                !!host->board.rdy_pin_active_low;
 }
 
 /*
@@ -273,7 +265,7 @@ static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len)
                if (atmel_nand_dma_op(mtd, buf, len, 1) == 0)
                        return;
 
-       if (host->board->bus_width_16)
+       if (host->board.bus_width_16)
                atmel_read_buf16(mtd, buf, len);
        else
                atmel_read_buf8(mtd, buf, len);
@@ -289,7 +281,7 @@ static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
                if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) == 0)
                        return;
 
-       if (host->board->bus_width_16)
+       if (host->board.bus_width_16)
                atmel_write_buf16(mtd, buf, len);
        else
                atmel_write_buf8(mtd, buf, len);
@@ -481,6 +473,56 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
        }
 }
 
+#if defined(CONFIG_OF)
+static int __devinit atmel_of_init_port(struct atmel_nand_host *host,
+                                        struct device_node *np)
+{
+       u32 val;
+       int ecc_mode;
+       struct atmel_nand_data *board = &host->board;
+       enum of_gpio_flags flags;
+
+       if (of_property_read_u32(np, "atmel,nand-addr-offset", &val) == 0) {
+               if (val >= 32) {
+                       dev_err(host->dev, "invalid addr-offset %u\n", val);
+                       return -EINVAL;
+               }
+               board->ale = val;
+       }
+
+       if (of_property_read_u32(np, "atmel,nand-cmd-offset", &val) == 0) {
+               if (val >= 32) {
+                       dev_err(host->dev, "invalid cmd-offset %u\n", val);
+                       return -EINVAL;
+               }
+               board->cle = val;
+       }
+
+       ecc_mode = of_get_nand_ecc_mode(np);
+
+       board->ecc_mode = ecc_mode < 0 ? NAND_ECC_SOFT : ecc_mode;
+
+       board->on_flash_bbt = of_get_nand_on_flash_bbt(np);
+
+       if (of_get_nand_bus_width(np) == 16)
+               board->bus_width_16 = 1;
+
+       board->rdy_pin = of_get_gpio_flags(np, 0, &flags);
+       board->rdy_pin_active_low = (flags == OF_GPIO_ACTIVE_LOW);
+
+       board->enable_pin = of_get_gpio(np, 1);
+       board->det_pin = of_get_gpio(np, 2);
+
+       return 0;
+}
+#else
+static int __devinit atmel_of_init_port(struct atmel_nand_host *host,
+                                        struct device_node *np)
+{
+       return -EINVAL;
+}
+#endif
+
 /*
  * Probe for the NAND device.
  */
@@ -491,6 +533,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
        struct nand_chip *nand_chip;
        struct resource *regs;
        struct resource *mem;
+       struct mtd_part_parser_data ppdata = {};
        int res;
 
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -517,8 +560,15 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
 
        mtd = &host->mtd;
        nand_chip = &host->nand_chip;
-       host->board = pdev->dev.platform_data;
        host->dev = &pdev->dev;
+       if (pdev->dev.of_node) {
+               res = atmel_of_init_port(host, pdev->dev.of_node);
+               if (res)
+                       goto err_nand_ioremap;
+       } else {
+               memcpy(&host->board, pdev->dev.platform_data,
+                      sizeof(struct atmel_nand_data));
+       }
 
        nand_chip->priv = host;         /* link the private data structures */
        mtd->priv = nand_chip;
@@ -529,26 +579,25 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
        nand_chip->IO_ADDR_W = host->io_base;
        nand_chip->cmd_ctrl = atmel_nand_cmd_ctrl;
 
-       if (gpio_is_valid(host->board->rdy_pin))
+       if (gpio_is_valid(host->board.rdy_pin))
                nand_chip->dev_ready = atmel_nand_device_ready;
 
+       nand_chip->ecc.mode = host->board.ecc_mode;
+
        regs = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-       if (!regs && hard_ecc) {
+       if (!regs && nand_chip->ecc.mode == NAND_ECC_HW) {
                printk(KERN_ERR "atmel_nand: can't get I/O resource "
                                "regs\nFalling back on software ECC\n");
+               nand_chip->ecc.mode = NAND_ECC_SOFT;
        }
 
-       nand_chip->ecc.mode = NAND_ECC_SOFT;    /* enable ECC */
-       if (no_ecc)
-               nand_chip->ecc.mode = NAND_ECC_NONE;
-       if (hard_ecc && regs) {
+       if (nand_chip->ecc.mode == NAND_ECC_HW) {
                host->ecc = ioremap(regs->start, resource_size(regs));
                if (host->ecc == NULL) {
                        printk(KERN_ERR "atmel_nand: ioremap failed\n");
                        res = -EIO;
                        goto err_ecc_ioremap;
                }
-               nand_chip->ecc.mode = NAND_ECC_HW;
                nand_chip->ecc.calculate = atmel_nand_calculate;
                nand_chip->ecc.correct = atmel_nand_correct;
                nand_chip->ecc.hwctl = atmel_nand_hwctl;
@@ -558,7 +607,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
 
        nand_chip->chip_delay = 20;             /* 20us command delay time */
 
-       if (host->board->bus_width_16)  /* 16-bit bus width */
+       if (host->board.bus_width_16)   /* 16-bit bus width */
                nand_chip->options |= NAND_BUSWIDTH_16;
 
        nand_chip->read_buf = atmel_read_buf;
@@ -567,15 +616,15 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, host);
        atmel_nand_enable(host);
 
-       if (gpio_is_valid(host->board->det_pin)) {
-               if (gpio_get_value(host->board->det_pin)) {
+       if (gpio_is_valid(host->board.det_pin)) {
+               if (gpio_get_value(host->board.det_pin)) {
                        printk(KERN_INFO "No SmartMedia card inserted.\n");
                        res = -ENXIO;
                        goto err_no_card;
                }
        }
 
-       if (on_flash_bbt) {
+       if (host->board.on_flash_bbt || on_flash_bbt) {
                printk(KERN_INFO "atmel_nand: Use On Flash BBT\n");
                nand_chip->bbt_options |= NAND_BBT_USE_FLASH;
        }
@@ -650,8 +699,9 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
        }
 
        mtd->name = "atmel_nand";
-       res = mtd_device_parse_register(mtd, NULL, 0,
-                       host->board->parts, host->board->num_parts);
+       ppdata.of_node = pdev->dev.of_node;
+       res = mtd_device_parse_register(mtd, NULL, &ppdata,
+                       host->board.parts, host->board.num_parts);
        if (!res)
                return res;
 
@@ -695,11 +745,21 @@ static int __exit atmel_nand_remove(struct platform_device *pdev)
        return 0;
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id atmel_nand_dt_ids[] = {
+       { .compatible = "atmel,at91rm9200-nand" },
+       { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, atmel_nand_dt_ids);
+#endif
+
 static struct platform_driver atmel_nand_driver = {
        .remove         = __exit_p(atmel_nand_remove),
        .driver         = {
                .name   = "atmel_nand",
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(atmel_nand_dt_ids),
        },
 };
 
index 772ad2966619ed56053a07b6e9329556edafe245..91467bb036341fe52f84a5db00c7664365d0abb9 100644 (file)
@@ -1,6 +1,7 @@
 menuconfig MTD_ONENAND
        tristate "OneNAND Device Support"
        depends on MTD
+       depends on HAS_IOMEM
        help
          This enables support for accessing all type of OneNAND flash
          devices. For further information see
index 068c3563e00fb6e9048356209a5c50146e0cf3bd..88bbd8ffa7fe739d0814c3da55e3b64429021d0d 100644 (file)
@@ -190,8 +190,10 @@ static struct devprobe2 isa_probes[] __initdata = {
        {seeq8005_probe, 0},
 #endif
 #ifdef CONFIG_CS89x0
+#ifndef CONFIG_CS89x0_PLATFORM
        {cs89x0_probe, 0},
 #endif
+#endif
 #ifdef CONFIG_AT1700
        {at1700_probe, 0},
 #endif
index 1f8648f099c7328d3c8334375d324b413ddb3543..8388e36cf08f97b17d75230b68e3683a3a2b365e 100644 (file)
@@ -5,8 +5,7 @@
 config NET_VENDOR_CIRRUS
        bool "Cirrus devices"
        default y
-       depends on ISA || EISA || MACH_IXDP2351 || ARCH_IXDP2X01 \
-               || MACH_MX31ADS || MACH_QQ2440 || (ARM && ARCH_EP93XX) || MAC
+       depends on ISA || EISA || ARM || MAC
        ---help---
          If you have a network (Ethernet) card belonging to this class, say Y
          and read the Ethernet-HOWTO, available from
@@ -21,8 +20,7 @@ if NET_VENDOR_CIRRUS
 
 config CS89x0
        tristate "CS89x0 support"
-       depends on (ISA || EISA || MACH_IXDP2351 \
-               || ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440)
+       depends on ISA || EISA || ARM
        ---help---
          Support for CS89x0 chipset based Ethernet cards. If you have a
          network (Ethernet) card of this type, say Y and read the
@@ -33,10 +31,15 @@ config CS89x0
          To compile this driver as a module, choose M here. The module
          will be called cs89x0.
 
-config CS89x0_NONISA_IRQ
-       def_bool y
-       depends on CS89x0 != n
-       depends on MACH_IXDP2351 || ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440
+config CS89x0_PLATFORM
+       bool "CS89x0 platform driver support"
+       depends on CS89x0
+       help
+         Say Y to compile the cs89x0 driver as a platform driver. This
+         makes this driver suitable for use on certain evaluation boards
+         such as the iMX21ADS.
+
+         If you are unsure, say N.
 
 config EP93XX_ETH
        tristate "EP93xx Ethernet support"
index d5ff93653e4ce0af7ca54fa84a182b32bebf0860..30fee428c4891efe65eee52337f7e54061e5eb5d 100644 (file)
 
 */
 
-/* Always include 'config.h' first in case the user wants to turn on
-   or override something. */
-#include <linux/module.h>
 
 /*
  * Set this to zero to disable DMA code
 
 */
 
+#include <linux/module.h>
+#include <linux/printk.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/platform_device.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <linux/atomic.h>
 #if ALLOW_DMA
 #include <asm/dma.h>
 #endif
@@ -174,26 +175,20 @@ static char version[] __initdata =
    them to system IRQ numbers. This mapping is card specific and is set to
    the configuration of the Cirrus Eval board for this chip. */
 #if defined(CONFIG_MACH_IXDP2351)
+#define CS89x0_NONISA_IRQ
 static unsigned int netcard_portlist[] __used __initdata = {IXDP2351_VIRT_CS8900_BASE, 0};
 static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0};
 #elif defined(CONFIG_ARCH_IXDP2X01)
+#define CS89x0_NONISA_IRQ
 static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
 static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
-#elif defined(CONFIG_MACH_QQ2440)
-#include <mach/qq2440.h>
-static unsigned int netcard_portlist[] __used __initdata = { QQ2440_CS8900_VIRT_BASE + 0x300, 0 };
-static unsigned int cs8900_irq_map[] = { QQ2440_CS8900_IRQ, 0, 0, 0 };
-#elif defined(CONFIG_MACH_MX31ADS)
-#include <mach/board-mx31ads.h>
-static unsigned int netcard_portlist[] __used __initdata = {
-       PBC_BASE_ADDRESS + PBC_CS8900A_IOBASE + 0x300, 0
-};
-static unsigned cs8900_irq_map[] = {EXPIO_INT_ENET_INT, 0, 0, 0};
 #else
+#ifndef CONFIG_CS89x0_PLATFORM
 static unsigned int netcard_portlist[] __used __initdata =
    { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
 static unsigned int cs8900_irq_map[] = {10,11,12,5};
 #endif
+#endif
 
 #if DEBUGGING
 static unsigned int net_debug = DEBUGGING;
@@ -236,11 +231,16 @@ struct net_local {
        unsigned char *end_dma_buff;    /* points to the end of the buffer */
        unsigned char *rx_dma_ptr;      /* points to the next packet  */
 #endif
+#ifdef CONFIG_CS89x0_PLATFORM
+       void __iomem *virt_addr;/* Virtual address for accessing the CS89x0. */
+       unsigned long phys_addr;/* Physical address for accessing the CS89x0. */
+       unsigned long size;     /* Length of CS89x0 memory region. */
+#endif
 };
 
 /* Index to functions, as function prototypes. */
 
-static int cs89x0_probe1(struct net_device *dev, int ioaddr, int modular);
+static int cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular);
 static int net_open(struct net_device *dev);
 static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t net_interrupt(int irq, void *dev_id);
@@ -294,6 +294,7 @@ static int __init media_fn(char *str)
 __setup("cs89x0_media=", media_fn);
 
 
+#ifndef CONFIG_CS89x0_PLATFORM
 /* Check for a network adaptor of this type, and return '0' iff one exists.
    If dev->base_addr == 0, probe all likely locations.
    If dev->base_addr == 1, always return failure.
@@ -343,6 +344,7 @@ out:
        return ERR_PTR(err);
 }
 #endif
+#endif
 
 #if defined(CONFIG_MACH_IXDP2351)
 static u16
@@ -504,7 +506,7 @@ static const struct net_device_ops net_ops = {
  */
 
 static int __init
-cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
+cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular)
 {
        struct net_local *lp = netdev_priv(dev);
        static unsigned version_printed;
@@ -529,15 +531,12 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
                lp->force = g_cs89x0_media__force;
 #endif
 
-#if defined(CONFIG_MACH_QQ2440)
-               lp->force |= FORCE_RJ45 | FORCE_FULL;
-#endif
         }
 
        /* Grab the region so we can find another board if autoIRQ fails. */
        /* WTF is going on here? */
        if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, DRV_NAME)) {
-               printk(KERN_ERR "%s: request_region(0x%x, 0x%x) failed\n",
+               printk(KERN_ERR "%s: request_region(0x%lx, 0x%x) failed\n",
                                DRV_NAME, ioaddr, NETCARD_IO_EXTENT);
                retval = -EBUSY;
                goto out1;
@@ -549,7 +548,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
           will skip the test for the ADD_PORT. */
        if (ioaddr & 1) {
                if (net_debug > 1)
-                       printk(KERN_INFO "%s: odd ioaddr 0x%x\n", dev->name, ioaddr);
+                       printk(KERN_INFO "%s: odd ioaddr 0x%lx\n", dev->name, ioaddr);
                if ((ioaddr & 2) != 2)
                        if ((readword(ioaddr & ~3, ADD_PORT) & ADD_MASK) != ADD_SIG) {
                                printk(KERN_ERR "%s: bad signature 0x%x\n",
@@ -560,13 +559,13 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
        }
 
        ioaddr &= ~3;
-       printk(KERN_DEBUG "PP_addr at %x[%x]: 0x%x\n",
+       printk(KERN_DEBUG "PP_addr at %lx[%x]: 0x%x\n",
                        ioaddr, ADD_PORT, readword(ioaddr, ADD_PORT));
        writeword(ioaddr, ADD_PORT, PP_ChipID);
 
        tmp = readword(ioaddr, DATA_PORT);
        if (tmp != CHIP_EISA_ID_SIG) {
-               printk(KERN_DEBUG "%s: incorrect signature at %x[%x]: 0x%x!="
+               printk(KERN_DEBUG "%s: incorrect signature at %lx[%x]: 0x%x!="
                        CHIP_EISA_ID_SIG_STR "\n",
                        dev->name, ioaddr, DATA_PORT, tmp);
                retval = -ENODEV;
@@ -736,8 +735,9 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
                        dev->irq = i;
        } else {
                i = lp->isa_config & INT_NO_MASK;
+#ifndef CONFIG_CS89x0_PLATFORM
                if (lp->chip_type == CS8900) {
-#ifdef CONFIG_CS89x0_NONISA_IRQ
+#ifdef CS89x0_NONISA_IRQ
                        i = cs8900_irq_map[0];
 #else
                        /* Translate the IRQ using the IRQ mapping table. */
@@ -758,6 +758,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
                        }
 #endif
                }
+#endif
                if (!dev->irq)
                        dev->irq = i;
        }
@@ -1168,6 +1169,7 @@ write_irq(struct net_device *dev, int chip_type, int irq)
        int i;
 
        if (chip_type == CS8900) {
+#ifndef CONFIG_CS89x0_PLATFORM
                /* Search the mapping table for the corresponding IRQ pin. */
                for (i = 0; i != ARRAY_SIZE(cs8900_irq_map); i++)
                        if (cs8900_irq_map[i] == irq)
@@ -1175,6 +1177,10 @@ write_irq(struct net_device *dev, int chip_type, int irq)
                /* Not found */
                if (i == ARRAY_SIZE(cs8900_irq_map))
                        i = 3;
+#else
+               /* INTRQ0 pin is used for interrupt generation. */
+               i = 0;
+#endif
                writereg(dev, PP_CS8900_ISAINT, i);
        } else {
                writereg(dev, PP_CS8920_ISAINT, irq);
@@ -1228,7 +1234,7 @@ net_open(struct net_device *dev)
        }
        else
        {
-#ifndef CONFIG_CS89x0_NONISA_IRQ
+#if !defined(CS89x0_NONISA_IRQ) && !defined(CONFIG_CS89x0_PLATFORM)
                if (((1 << dev->irq) & lp->irq_map) == 0) {
                        printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
                                dev->name, dev->irq, lp->irq_map);
@@ -1746,7 +1752,7 @@ static int set_mac_address(struct net_device *dev, void *p)
        return 0;
 }
 
-#ifdef MODULE
+#if defined(MODULE) && !defined(CONFIG_CS89x0_PLATFORM)
 
 static struct net_device *dev_cs89x0;
 
@@ -1900,7 +1906,97 @@ cleanup_module(void)
        release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT);
        free_netdev(dev_cs89x0);
 }
-#endif /* MODULE */
+#endif /* MODULE && !CONFIG_CS89x0_PLATFORM */
+
+#ifdef CONFIG_CS89x0_PLATFORM
+static int __init cs89x0_platform_probe(struct platform_device *pdev)
+{
+       struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
+       struct net_local *lp;
+       struct resource *mem_res;
+       int err;
+
+       if (!dev)
+               return -ENOMEM;
+
+       lp = netdev_priv(dev);
+
+       mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       dev->irq = platform_get_irq(pdev, 0);
+       if (mem_res == NULL || dev->irq <= 0) {
+               dev_warn(&dev->dev, "memory/interrupt resource missing.\n");
+               err = -ENXIO;
+               goto free;
+       }
+
+       lp->phys_addr = mem_res->start;
+       lp->size = resource_size(mem_res);
+       if (!request_mem_region(lp->phys_addr, lp->size, DRV_NAME)) {
+               dev_warn(&dev->dev, "request_mem_region() failed.\n");
+               err = -EBUSY;
+               goto free;
+       }
+
+       lp->virt_addr = ioremap(lp->phys_addr, lp->size);
+       if (!lp->virt_addr) {
+               dev_warn(&dev->dev, "ioremap() failed.\n");
+               err = -ENOMEM;
+               goto release;
+       }
+
+       err = cs89x0_probe1(dev, (unsigned long)lp->virt_addr, 0);
+       if (err) {
+               dev_warn(&dev->dev, "no cs8900 or cs8920 detected.\n");
+               goto unmap;
+       }
+
+       platform_set_drvdata(pdev, dev);
+       return 0;
+
+unmap:
+       iounmap(lp->virt_addr);
+release:
+       release_mem_region(lp->phys_addr, lp->size);
+free:
+       free_netdev(dev);
+       return err;
+}
+
+static int cs89x0_platform_remove(struct platform_device *pdev)
+{
+       struct net_device *dev = platform_get_drvdata(pdev);
+       struct net_local *lp = netdev_priv(dev);
+
+       unregister_netdev(dev);
+       iounmap(lp->virt_addr);
+       release_mem_region(lp->phys_addr, lp->size);
+       free_netdev(dev);
+       return 0;
+}
+
+static struct platform_driver cs89x0_driver = {
+       .driver = {
+               .name   = DRV_NAME,
+               .owner  = THIS_MODULE,
+       },
+       .remove = cs89x0_platform_remove,
+};
+
+static int __init cs89x0_init(void)
+{
+       return platform_driver_probe(&cs89x0_driver, cs89x0_platform_probe);
+}
+
+module_init(cs89x0_init);
+
+static void __exit cs89x0_cleanup(void)
+{
+       platform_driver_unregister(&cs89x0_driver);
+}
+
+module_exit(cs89x0_cleanup);
+
+#endif /* CONFIG_CS89x0_PLATFORM */
 
 /*
  * Local variables:
index d9428f0e738a2edf2267055ab1e2008d63d2ff3f..e7bed530399763c9d646f6194f913f530a2bbb52 100644 (file)
@@ -968,7 +968,6 @@ static int gfar_probe(struct platform_device *ofdev)
        struct gfar_private *priv = NULL;
        struct gfar __iomem *regs = NULL;
        int err = 0, i, grp_idx = 0;
-       int len_devname;
        u32 rstat = 0, tstat = 0, rqueue = 0, tqueue = 0;
        u32 isrg = 0;
        u32 __iomem *baddr;
@@ -1169,40 +1168,16 @@ static int gfar_probe(struct platform_device *ofdev)
                priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
 
        /* fill out IRQ number and name fields */
-       len_devname = strlen(dev->name);
        for (i = 0; i < priv->num_grps; i++) {
-               strncpy(&priv->gfargrp[i].int_name_tx[0], dev->name,
-                               len_devname);
                if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
-                       strncpy(&priv->gfargrp[i].int_name_tx[len_devname],
-                               "_g", sizeof("_g"));
-                       priv->gfargrp[i].int_name_tx[
-                               strlen(priv->gfargrp[i].int_name_tx)] = i+48;
-                       strncpy(&priv->gfargrp[i].int_name_tx[strlen(
-                               priv->gfargrp[i].int_name_tx)],
-                               "_tx", sizeof("_tx") + 1);
-
-                       strncpy(&priv->gfargrp[i].int_name_rx[0], dev->name,
-                                       len_devname);
-                       strncpy(&priv->gfargrp[i].int_name_rx[len_devname],
-                                       "_g", sizeof("_g"));
-                       priv->gfargrp[i].int_name_rx[
-                               strlen(priv->gfargrp[i].int_name_rx)] = i+48;
-                       strncpy(&priv->gfargrp[i].int_name_rx[strlen(
-                               priv->gfargrp[i].int_name_rx)],
-                               "_rx", sizeof("_rx") + 1);
-
-                       strncpy(&priv->gfargrp[i].int_name_er[0], dev->name,
-                                       len_devname);
-                       strncpy(&priv->gfargrp[i].int_name_er[len_devname],
-                               "_g", sizeof("_g"));
-                       priv->gfargrp[i].int_name_er[strlen(
-                                       priv->gfargrp[i].int_name_er)] = i+48;
-                       strncpy(&priv->gfargrp[i].int_name_er[strlen(\
-                               priv->gfargrp[i].int_name_er)],
-                               "_er", sizeof("_er") + 1);
+                       sprintf(priv->gfargrp[i].int_name_tx, "%s%s%c%s",
+                               dev->name, "_g", '0' + i, "_tx");
+                       sprintf(priv->gfargrp[i].int_name_rx, "%s%s%c%s",
+                               dev->name, "_g", '0' + i, "_rx");
+                       sprintf(priv->gfargrp[i].int_name_er, "%s%s%c%s",
+                               dev->name, "_g", '0' + i, "_er");
                } else
-                       priv->gfargrp[i].int_name_tx[len_devname] = '\0';
+                       strcpy(priv->gfargrp[i].int_name_tx, dev->name);
        }
 
        /* Initialize the filer table */
index fc2488adca366f15af3503d582c8251e39812c17..4c9f8d487dbbf4825e10fc2e3ee25199662e7517 100644 (file)
@@ -517,7 +517,7 @@ extern const char gfar_driver_version[];
 #define RXFCB_PERR_MASK                0x000c
 #define RXFCB_PERR_BADL3       0x0008
 
-#define GFAR_INT_NAME_MAX      IFNAMSIZ + 4
+#define GFAR_INT_NAME_MAX      (IFNAMSIZ + 6)  /* '_g#_xx' */
 
 struct txbd8
 {
index 2b5af22419a5e541726dc3880310817488ba6c99..385a4d5c7c25f1ff2a38e324d7b4b30d034770b1 100644 (file)
@@ -36,8 +36,8 @@
 
 #define _QLCNIC_LINUX_MAJOR 5
 #define _QLCNIC_LINUX_MINOR 0
-#define _QLCNIC_LINUX_SUBVERSION 25
-#define QLCNIC_LINUX_VERSIONID  "5.0.26"
+#define _QLCNIC_LINUX_SUBVERSION 27
+#define QLCNIC_LINUX_VERSIONID  "5.0.27"
 #define QLCNIC_DRV_IDC_VER  0x01
 #define QLCNIC_DRIVER_VERSION  ((_QLCNIC_LINUX_MAJOR << 16) |\
                 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
index 81bb1a69e69f85da223b606ba09478a860b03e90..75c32e875fef17d3705b87692f9341337578460c 100644 (file)
@@ -1458,8 +1458,10 @@ qlcnic_reset_context(struct qlcnic_adapter *adapter)
 
                if (netif_running(netdev)) {
                        err = qlcnic_attach(adapter);
-                       if (!err)
+                       if (!err) {
                                __qlcnic_up(adapter, netdev);
+                               qlcnic_restore_indev_addr(netdev, NETDEV_UP);
+                       }
                }
 
                netif_device_attach(netdev);
index 1dc4fad593e7ebd50a35f50a477e8bcd0a4f8481..fee44935501461663a1417c5a10b209f33da393e 100644 (file)
@@ -2280,7 +2280,7 @@ static int __devinit smc_drv_probe(struct platform_device *pdev)
        if (ret)
                goto out_release_io;
 #if defined(CONFIG_SA1100_ASSABET)
-       NCR_0 |= NCR_ENET_OSC_EN;
+       neponset_ncr_set(NCR_ENET_OSC_EN);
 #endif
        platform_set_drvdata(pdev, ndev);
        ret = smc_enable_device(pdev);
index e535137eb2d0fff40f1877bbcbcef94730e4dd12..468047866c8ca2b4ff102a04a610afd3dd968521 100644 (file)
@@ -356,7 +356,7 @@ config VLSI_FIR
 
 config SA1100_FIR
        tristate "SA1100 Internal IR"
-       depends on ARCH_SA1100 && IRDA
+       depends on ARCH_SA1100 && IRDA && DMA_SA11X0
 
 config VIA_FIR
        tristate "VIA VT8231/VT1211 SIR/MIR/FIR"
index da2705061a60fd2bac8c4ff60d2328995c46fb46..a0d1913a58d322afb07a23d458709a6ffe6a3eff 100644 (file)
@@ -15,7 +15,7 @@
  *  This driver takes one kernel command line parameter, sa1100ir=, with
  *  the following options:
  *     max_rate:baudrate       - set the maximum baud rate
- *     power_leve:level        - set the transmitter power level
+ *     power_level:level       - set the transmitter power level
  *     tx_lpm:0|1              - set transmit low power mode
  */
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/sa11x0-dma.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/wrapper.h>
 #include <net/irda/irda_device.h>
 
-#include <asm/irq.h>
-#include <mach/dma.h>
 #include <mach/hardware.h>
 #include <asm/mach/irda.h>
 
@@ -44,8 +44,15 @@ static int power_level = 3;
 static int tx_lpm;
 static int max_rate = 4000000;
 
+struct sa1100_buf {
+       struct device           *dev;
+       struct sk_buff          *skb;
+       struct scatterlist      sg;
+       struct dma_chan         *chan;
+       dma_cookie_t            cookie;
+};
+
 struct sa1100_irda {
-       unsigned char           hscr0;
        unsigned char           utcr4;
        unsigned char           power;
        unsigned char           open;
@@ -53,12 +60,8 @@ struct sa1100_irda {
        int                     speed;
        int                     newspeed;
 
-       struct sk_buff          *txskb;
-       struct sk_buff          *rxskb;
-       dma_addr_t              txbuf_dma;
-       dma_addr_t              rxbuf_dma;
-       dma_regs_t              *txdma;
-       dma_regs_t              *rxdma;
+       struct sa1100_buf       dma_rx;
+       struct sa1100_buf       dma_tx;
 
        struct device           *dev;
        struct irda_platform_data *pdata;
@@ -67,23 +70,103 @@ struct sa1100_irda {
 
        iobuff_t                tx_buff;
        iobuff_t                rx_buff;
+
+       int (*tx_start)(struct sk_buff *, struct net_device *, struct sa1100_irda *);
+       irqreturn_t (*irq)(struct net_device *, struct sa1100_irda *);
 };
 
+static int sa1100_irda_set_speed(struct sa1100_irda *, int);
+
 #define IS_FIR(si)             ((si)->speed >= 4000000)
 
 #define HPSIR_MAX_RXLEN                2047
 
+static struct dma_slave_config sa1100_irda_sir_tx = {
+       .direction      = DMA_TO_DEVICE,
+       .dst_addr       = __PREG(Ser2UTDR),
+       .dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
+       .dst_maxburst   = 4,
+};
+
+static struct dma_slave_config sa1100_irda_fir_rx = {
+       .direction      = DMA_FROM_DEVICE,
+       .src_addr       = __PREG(Ser2HSDR),
+       .src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
+       .src_maxburst   = 8,
+};
+
+static struct dma_slave_config sa1100_irda_fir_tx = {
+       .direction      = DMA_TO_DEVICE,
+       .dst_addr       = __PREG(Ser2HSDR),
+       .dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
+       .dst_maxburst   = 8,
+};
+
+static unsigned sa1100_irda_dma_xferred(struct sa1100_buf *buf)
+{
+       struct dma_chan *chan = buf->chan;
+       struct dma_tx_state state;
+       enum dma_status status;
+
+       status = chan->device->device_tx_status(chan, buf->cookie, &state);
+       if (status != DMA_PAUSED)
+               return 0;
+
+       return sg_dma_len(&buf->sg) - state.residue;
+}
+
+static int sa1100_irda_dma_request(struct device *dev, struct sa1100_buf *buf,
+       const char *name, struct dma_slave_config *cfg)
+{
+       dma_cap_mask_t m;
+       int ret;
+
+       dma_cap_zero(m);
+       dma_cap_set(DMA_SLAVE, m);
+
+       buf->chan = dma_request_channel(m, sa11x0_dma_filter_fn, (void *)name);
+       if (!buf->chan) {
+               dev_err(dev, "unable to request DMA channel for %s\n",
+                       name);
+               return -ENOENT;
+       }
+
+       ret = dmaengine_slave_config(buf->chan, cfg);
+       if (ret)
+               dev_warn(dev, "DMA slave_config for %s returned %d\n",
+                       name, ret);
+
+       buf->dev = buf->chan->device->dev;
+
+       return 0;
+}
+
+static void sa1100_irda_dma_start(struct sa1100_buf *buf,
+       enum dma_transfer_direction dir, dma_async_tx_callback cb, void *cb_p)
+{
+       struct dma_async_tx_descriptor *desc;
+       struct dma_chan *chan = buf->chan;
+
+       desc = chan->device->device_prep_slave_sg(chan, &buf->sg, 1, dir,
+                       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+       if (desc) {
+               desc->callback = cb;
+               desc->callback_param = cb_p;
+               buf->cookie = dmaengine_submit(desc);
+               dma_async_issue_pending(chan);
+       }
+}
+
 /*
  * Allocate and map the receive buffer, unless it is already allocated.
  */
 static int sa1100_irda_rx_alloc(struct sa1100_irda *si)
 {
-       if (si->rxskb)
+       if (si->dma_rx.skb)
                return 0;
 
-       si->rxskb = alloc_skb(HPSIR_MAX_RXLEN + 1, GFP_ATOMIC);
-
-       if (!si->rxskb) {
+       si->dma_rx.skb = alloc_skb(HPSIR_MAX_RXLEN + 1, GFP_ATOMIC);
+       if (!si->dma_rx.skb) {
                printk(KERN_ERR "sa1100_ir: out of memory for RX SKB\n");
                return -ENOMEM;
        }
@@ -92,11 +175,14 @@ static int sa1100_irda_rx_alloc(struct sa1100_irda *si)
         * Align any IP headers that may be contained
         * within the frame.
         */
-       skb_reserve(si->rxskb, 1);
+       skb_reserve(si->dma_rx.skb, 1);
+
+       sg_set_buf(&si->dma_rx.sg, si->dma_rx.skb->data, HPSIR_MAX_RXLEN);
+       if (dma_map_sg(si->dma_rx.dev, &si->dma_rx.sg, 1, DMA_FROM_DEVICE) == 0) {
+               dev_kfree_skb_any(si->dma_rx.skb);
+               return -ENOMEM;
+       }
 
-       si->rxbuf_dma = dma_map_single(si->dev, si->rxskb->data,
-                                       HPSIR_MAX_RXLEN,
-                                       DMA_FROM_DEVICE);
        return 0;
 }
 
@@ -106,7 +192,7 @@ static int sa1100_irda_rx_alloc(struct sa1100_irda *si)
  */
 static void sa1100_irda_rx_dma_start(struct sa1100_irda *si)
 {
-       if (!si->rxskb) {
+       if (!si->dma_rx.skb) {
                printk(KERN_ERR "sa1100_ir: rx buffer went missing\n");
                return;
        }
@@ -114,254 +200,87 @@ static void sa1100_irda_rx_dma_start(struct sa1100_irda *si)
        /*
         * First empty receive FIFO
         */
-       Ser2HSCR0 = si->hscr0 | HSCR0_HSSP;
+       Ser2HSCR0 = HSCR0_HSSP;
 
        /*
         * Enable the DMA, receiver and receive interrupt.
         */
-       sa1100_clear_dma(si->rxdma);
-       sa1100_start_dma(si->rxdma, si->rxbuf_dma, HPSIR_MAX_RXLEN);
-       Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_RXE;
+       dmaengine_terminate_all(si->dma_rx.chan);
+       sa1100_irda_dma_start(&si->dma_rx, DMA_DEV_TO_MEM, NULL, NULL);
+
+       Ser2HSCR0 = HSCR0_HSSP | HSCR0_RXE;
 }
 
-/*
- * Set the IrDA communications speed.
- */
-static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
+static void sa1100_irda_check_speed(struct sa1100_irda *si)
 {
-       unsigned long flags;
-       int brd, ret = -EINVAL;
-
-       switch (speed) {
-       case 9600:      case 19200:     case 38400:
-       case 57600:     case 115200:
-               brd = 3686400 / (16 * speed) - 1;
-
-               /*
-                * Stop the receive DMA.
-                */
-               if (IS_FIR(si))
-                       sa1100_stop_dma(si->rxdma);
-
-               local_irq_save(flags);
-
-               Ser2UTCR3 = 0;
-               Ser2HSCR0 = HSCR0_UART;
-
-               Ser2UTCR1 = brd >> 8;
-               Ser2UTCR2 = brd;
-
-               /*
-                * Clear status register
-                */
-               Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
-               Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE;
-
-               if (si->pdata->set_speed)
-                       si->pdata->set_speed(si->dev, speed);
-
-               si->speed = speed;
-
-               local_irq_restore(flags);
-               ret = 0;
-               break;
-
-       case 4000000:
-               local_irq_save(flags);
-
-               si->hscr0 = 0;
-
-               Ser2HSSR0 = 0xff;
-               Ser2HSCR0 = si->hscr0 | HSCR0_HSSP;
-               Ser2UTCR3 = 0;
-
-               si->speed = speed;
-
-               if (si->pdata->set_speed)
-                       si->pdata->set_speed(si->dev, speed);
-
-               sa1100_irda_rx_alloc(si);
-               sa1100_irda_rx_dma_start(si);
-
-               local_irq_restore(flags);
-
-               break;
-
-       default:
-               break;
+       if (si->newspeed) {
+               sa1100_irda_set_speed(si, si->newspeed);
+               si->newspeed = 0;
        }
-
-       return ret;
 }
 
 /*
- * Control the power state of the IrDA transmitter.
- * State:
- *  0 - off
- *  1 - short range, lowest power
- *  2 - medium range, medium power
- *  3 - maximum range, high power
- *
- * Currently, only assabet is known to support this.
+ * HP-SIR format support.
  */
-static int
-__sa1100_irda_set_power(struct sa1100_irda *si, unsigned int state)
-{
-       int ret = 0;
-       if (si->pdata->set_power)
-               ret = si->pdata->set_power(si->dev, state);
-       return ret;
-}
-
-static inline int
-sa1100_set_power(struct sa1100_irda *si, unsigned int state)
+static void sa1100_irda_sirtxdma_irq(void *id)
 {
-       int ret;
-
-       ret = __sa1100_irda_set_power(si, state);
-       if (ret == 0)
-               si->power = state;
-
-       return ret;
-}
+       struct net_device *dev = id;
+       struct sa1100_irda *si = netdev_priv(dev);
 
-static int sa1100_irda_startup(struct sa1100_irda *si)
-{
-       int ret;
+       dma_unmap_sg(si->dma_tx.dev, &si->dma_tx.sg, 1, DMA_TO_DEVICE);
+       dev_kfree_skb(si->dma_tx.skb);
+       si->dma_tx.skb = NULL;
 
-       /*
-        * Ensure that the ports for this device are setup correctly.
-        */
-       if (si->pdata->startup) {
-               ret = si->pdata->startup(si->dev);
-               if (ret)
-                       return ret;
-       }
+       dev->stats.tx_packets++;
+       dev->stats.tx_bytes += sg_dma_len(&si->dma_tx.sg);
 
-       /*
-        * Configure PPC for IRDA - we want to drive TXD2 low.
-        * We also want to drive this pin low during sleep.
-        */
-       PPSR &= ~PPC_TXD2;
-       PSDR &= ~PPC_TXD2;
-       PPDR |= PPC_TXD2;
-
-       /*
-        * Enable HP-SIR modulation, and ensure that the port is disabled.
-        */
-       Ser2UTCR3 = 0;
-       Ser2HSCR0 = HSCR0_UART;
-       Ser2UTCR4 = si->utcr4;
-       Ser2UTCR0 = UTCR0_8BitData;
-       Ser2HSCR2 = HSCR2_TrDataH | HSCR2_RcDataL;
+       /* We need to ensure that the transmitter has finished. */
+       do
+               rmb();
+       while (Ser2UTSR1 & UTSR1_TBY);
 
        /*
-        * Clear status register
+        * Ok, we've finished transmitting.  Now enable the receiver.
+        * Sometimes we get a receive IRQ immediately after a transmit...
         */
        Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
+       Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE;
 
-       ret = sa1100_irda_set_speed(si, si->speed = 9600);
-       if (ret) {
-               Ser2UTCR3 = 0;
-               Ser2HSCR0 = 0;
+       sa1100_irda_check_speed(si);
 
-               if (si->pdata->shutdown)
-                       si->pdata->shutdown(si->dev);
-       }
-
-       return ret;
-}
-
-static void sa1100_irda_shutdown(struct sa1100_irda *si)
-{
-       /*
-        * Stop all DMA activity.
-        */
-       sa1100_stop_dma(si->rxdma);
-       sa1100_stop_dma(si->txdma);
-
-       /* Disable the port. */
-       Ser2UTCR3 = 0;
-       Ser2HSCR0 = 0;
-
-       if (si->pdata->shutdown)
-               si->pdata->shutdown(si->dev);
+       /* I'm hungry! */
+       netif_wake_queue(dev);
 }
 
-#ifdef CONFIG_PM
-/*
- * Suspend the IrDA interface.
- */
-static int sa1100_irda_suspend(struct platform_device *pdev, pm_message_t state)
+static int sa1100_irda_sir_tx_start(struct sk_buff *skb, struct net_device *dev,
+       struct sa1100_irda *si)
 {
-       struct net_device *dev = platform_get_drvdata(pdev);
-       struct sa1100_irda *si;
-
-       if (!dev)
-               return 0;
-
-       si = netdev_priv(dev);
-       if (si->open) {
-               /*
-                * Stop the transmit queue
-                */
-               netif_device_detach(dev);
-               disable_irq(dev->irq);
-               sa1100_irda_shutdown(si);
-               __sa1100_irda_set_power(si, 0);
+       si->tx_buff.data = si->tx_buff.head;
+       si->tx_buff.len  = async_wrap_skb(skb, si->tx_buff.data,
+                                         si->tx_buff.truesize);
+
+       si->dma_tx.skb = skb;
+       sg_set_buf(&si->dma_tx.sg, si->tx_buff.data, si->tx_buff.len);
+       if (dma_map_sg(si->dma_tx.dev, &si->dma_tx.sg, 1, DMA_TO_DEVICE) == 0) {
+               si->dma_tx.skb = NULL;
+               netif_wake_queue(dev);
+               dev->stats.tx_dropped++;
+               return NETDEV_TX_OK;
        }
 
-       return 0;
-}
-
-/*
- * Resume the IrDA interface.
- */
-static int sa1100_irda_resume(struct platform_device *pdev)
-{
-       struct net_device *dev = platform_get_drvdata(pdev);
-       struct sa1100_irda *si;
-
-       if (!dev)
-               return 0;
-
-       si = netdev_priv(dev);
-       if (si->open) {
-               /*
-                * If we missed a speed change, initialise at the new speed
-                * directly.  It is debatable whether this is actually
-                * required, but in the interests of continuing from where
-                * we left off it is desirable.  The converse argument is
-                * that we should re-negotiate at 9600 baud again.
-                */
-               if (si->newspeed) {
-                       si->speed = si->newspeed;
-                       si->newspeed = 0;
-               }
-
-               sa1100_irda_startup(si);
-               __sa1100_irda_set_power(si, si->power);
-               enable_irq(dev->irq);
+       sa1100_irda_dma_start(&si->dma_tx, DMA_MEM_TO_DEV, sa1100_irda_sirtxdma_irq, dev);
 
-               /*
-                * This automatically wakes up the queue
-                */
-               netif_device_attach(dev);
-       }
+       /*
+        * The mean turn-around time is enforced by XBOF padding,
+        * so we don't have to do anything special here.
+        */
+       Ser2UTCR3 = UTCR3_TXE;
 
-       return 0;
+       return NETDEV_TX_OK;
 }
-#else
-#define sa1100_irda_suspend    NULL
-#define sa1100_irda_resume     NULL
-#endif
 
-/*
- * HP-SIR format interrupt service routines.
- */
-static void sa1100_irda_hpsir_irq(struct net_device *dev)
+static irqreturn_t sa1100_irda_sir_irq(struct net_device *dev, struct sa1100_irda *si)
 {
-       struct sa1100_irda *si = netdev_priv(dev);
        int status;
 
        status = Ser2UTSR0;
@@ -414,51 +333,96 @@ static void sa1100_irda_hpsir_irq(struct net_device *dev)
 
        }
 
-       if (status & UTSR0_TFS && si->tx_buff.len) {
-               /*
-                * Transmitter FIFO is not full
-                */
-               do {
-                       Ser2UTDR = *si->tx_buff.data++;
-                       si->tx_buff.len -= 1;
-               } while (Ser2UTSR1 & UTSR1_TNF && si->tx_buff.len);
+       return IRQ_HANDLED;
+}
 
-               if (si->tx_buff.len == 0) {
-                       dev->stats.tx_packets++;
-                       dev->stats.tx_bytes += si->tx_buff.data -
-                                             si->tx_buff.head;
+/*
+ * FIR format support.
+ */
+static void sa1100_irda_firtxdma_irq(void *id)
+{
+       struct net_device *dev = id;
+       struct sa1100_irda *si = netdev_priv(dev);
+       struct sk_buff *skb;
 
-                       /*
-                        * We need to ensure that the transmitter has
-                        * finished.
-                        */
-                       do
-                               rmb();
-                       while (Ser2UTSR1 & UTSR1_TBY);
+       /*
+        * Wait for the transmission to complete.  Unfortunately,
+        * the hardware doesn't give us an interrupt to indicate
+        * "end of frame".
+        */
+       do
+               rmb();
+       while (!(Ser2HSSR0 & HSSR0_TUR) || Ser2HSSR1 & HSSR1_TBY);
 
-                       /*
-                        * Ok, we've finished transmitting.  Now enable
-                        * the receiver.  Sometimes we get a receive IRQ
-                        * immediately after a transmit...
-                        */
-                       Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
-                       Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE;
+       /*
+        * Clear the transmit underrun bit.
+        */
+       Ser2HSSR0 = HSSR0_TUR;
 
-                       if (si->newspeed) {
-                               sa1100_irda_set_speed(si, si->newspeed);
-                               si->newspeed = 0;
-                       }
+       /*
+        * Do we need to change speed?  Note that we're lazy
+        * here - we don't free the old dma_rx.skb.  We don't need
+        * to allocate a buffer either.
+        */
+       sa1100_irda_check_speed(si);
 
-                       /* I'm hungry! */
-                       netif_wake_queue(dev);
-               }
+       /*
+        * Start reception.  This disables the transmitter for
+        * us.  This will be using the existing RX buffer.
+        */
+       sa1100_irda_rx_dma_start(si);
+
+       /* Account and free the packet. */
+       skb = si->dma_tx.skb;
+       if (skb) {
+               dma_unmap_sg(si->dma_tx.dev, &si->dma_tx.sg, 1,
+                            DMA_TO_DEVICE);
+               dev->stats.tx_packets ++;
+               dev->stats.tx_bytes += skb->len;
+               dev_kfree_skb_irq(skb);
+               si->dma_tx.skb = NULL;
        }
+
+       /*
+        * Make sure that the TX queue is available for sending
+        * (for retries).  TX has priority over RX at all times.
+        */
+       netif_wake_queue(dev);
+}
+
+static int sa1100_irda_fir_tx_start(struct sk_buff *skb, struct net_device *dev,
+       struct sa1100_irda *si)
+{
+       int mtt = irda_get_mtt(skb);
+
+       si->dma_tx.skb = skb;
+       sg_set_buf(&si->dma_tx.sg, skb->data, skb->len);
+       if (dma_map_sg(si->dma_tx.dev, &si->dma_tx.sg, 1, DMA_TO_DEVICE) == 0) {
+               si->dma_tx.skb = NULL;
+               netif_wake_queue(dev);
+               dev->stats.tx_dropped++;
+               dev_kfree_skb(skb);
+               return NETDEV_TX_OK;
+       }
+
+       sa1100_irda_dma_start(&si->dma_tx, DMA_MEM_TO_DEV, sa1100_irda_firtxdma_irq, dev);
+
+       /*
+        * If we have a mean turn-around time, impose the specified
+        * specified delay.  We could shorten this by timing from
+        * the point we received the packet.
+        */
+       if (mtt)
+               udelay(mtt);
+
+       Ser2HSCR0 = HSCR0_HSSP | HSCR0_TXE;
+
+       return NETDEV_TX_OK;
 }
 
 static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev)
 {
-       struct sk_buff *skb = si->rxskb;
-       dma_addr_t dma_addr;
+       struct sk_buff *skb = si->dma_rx.skb;
        unsigned int len, stat, data;
 
        if (!skb) {
@@ -469,11 +433,10 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev
        /*
         * Get the current data position.
         */
-       dma_addr = sa1100_get_dma_pos(si->rxdma);
-       len = dma_addr - si->rxbuf_dma;
+       len = sa1100_irda_dma_xferred(&si->dma_rx);
        if (len > HPSIR_MAX_RXLEN)
                len = HPSIR_MAX_RXLEN;
-       dma_unmap_single(si->dev, si->rxbuf_dma, len, DMA_FROM_DEVICE);
+       dma_unmap_sg(si->dma_rx.dev, &si->dma_rx.sg, 1, DMA_FROM_DEVICE);
 
        do {
                /*
@@ -501,7 +464,7 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev
        } while (Ser2HSSR0 & HSSR0_EIF);
 
        if (stat & HSSR1_EOF) {
-               si->rxskb = NULL;
+               si->dma_rx.skb = NULL;
 
                skb_put(skb, len);
                skb->dev = dev;
@@ -518,28 +481,23 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev
                netif_rx(skb);
        } else {
                /*
-                * Remap the buffer.
+                * Remap the buffer - it was previously mapped, and we
+                * hope that this succeeds.
                 */
-               si->rxbuf_dma = dma_map_single(si->dev, si->rxskb->data,
-                                               HPSIR_MAX_RXLEN,
-                                               DMA_FROM_DEVICE);
+               dma_map_sg(si->dma_rx.dev, &si->dma_rx.sg, 1, DMA_FROM_DEVICE);
        }
 }
 
 /*
- * FIR format interrupt service routine.  We only have to
- * handle RX events; transmit events go via the TX DMA handler.
- *
- * No matter what, we disable RX, process, and the restart RX.
+ * We only have to handle RX events here; transmit events go via the TX
+ * DMA handler. We disable RX, process, and the restart RX.
  */
-static void sa1100_irda_fir_irq(struct net_device *dev)
+static irqreturn_t sa1100_irda_fir_irq(struct net_device *dev, struct sa1100_irda *si)
 {
-       struct sa1100_irda *si = netdev_priv(dev);
-
        /*
         * Stop RX DMA
         */
-       sa1100_stop_dma(si->rxdma);
+       dmaengine_pause(si->dma_rx.chan);
 
        /*
         * Framing error - we throw away the packet completely.
@@ -555,7 +513,7 @@ static void sa1100_irda_fir_irq(struct net_device *dev)
                /*
                 * Clear out the DMA...
                 */
-               Ser2HSCR0 = si->hscr0 | HSCR0_HSSP;
+               Ser2HSCR0 = HSCR0_HSSP;
 
                /*
                 * Clear selected status bits now, so we
@@ -577,74 +535,124 @@ static void sa1100_irda_fir_irq(struct net_device *dev)
         * No matter what happens, we must restart reception.
         */
        sa1100_irda_rx_dma_start(si);
+
+       return IRQ_HANDLED;
 }
 
-static irqreturn_t sa1100_irda_irq(int irq, void *dev_id)
+/*
+ * Set the IrDA communications speed.
+ */
+static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
 {
-       struct net_device *dev = dev_id;
-       if (IS_FIR(((struct sa1100_irda *)netdev_priv(dev))))
-               sa1100_irda_fir_irq(dev);
-       else
-               sa1100_irda_hpsir_irq(dev);
-       return IRQ_HANDLED;
+       unsigned long flags;
+       int brd, ret = -EINVAL;
+
+       switch (speed) {
+       case 9600:      case 19200:     case 38400:
+       case 57600:     case 115200:
+               brd = 3686400 / (16 * speed) - 1;
+
+               /* Stop the receive DMA, and configure transmit. */
+               if (IS_FIR(si)) {
+                       dmaengine_terminate_all(si->dma_rx.chan);
+                       dmaengine_slave_config(si->dma_tx.chan,
+                                               &sa1100_irda_sir_tx);
+               }
+
+               local_irq_save(flags);
+
+               Ser2UTCR3 = 0;
+               Ser2HSCR0 = HSCR0_UART;
+
+               Ser2UTCR1 = brd >> 8;
+               Ser2UTCR2 = brd;
+
+               /*
+                * Clear status register
+                */
+               Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
+               Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE;
+
+               if (si->pdata->set_speed)
+                       si->pdata->set_speed(si->dev, speed);
+
+               si->speed = speed;
+               si->tx_start = sa1100_irda_sir_tx_start;
+               si->irq = sa1100_irda_sir_irq;
+
+               local_irq_restore(flags);
+               ret = 0;
+               break;
+
+       case 4000000:
+               if (!IS_FIR(si))
+                       dmaengine_slave_config(si->dma_tx.chan,
+                                               &sa1100_irda_fir_tx);
+
+               local_irq_save(flags);
+
+               Ser2HSSR0 = 0xff;
+               Ser2HSCR0 = HSCR0_HSSP;
+               Ser2UTCR3 = 0;
+
+               si->speed = speed;
+               si->tx_start = sa1100_irda_fir_tx_start;
+               si->irq = sa1100_irda_fir_irq;
+
+               if (si->pdata->set_speed)
+                       si->pdata->set_speed(si->dev, speed);
+
+               sa1100_irda_rx_alloc(si);
+               sa1100_irda_rx_dma_start(si);
+
+               local_irq_restore(flags);
+
+               break;
+
+       default:
+               break;
+       }
+
+       return ret;
 }
 
 /*
- * TX DMA completion handler.
+ * Control the power state of the IrDA transmitter.
+ * State:
+ *  0 - off
+ *  1 - short range, lowest power
+ *  2 - medium range, medium power
+ *  3 - maximum range, high power
+ *
+ * Currently, only assabet is known to support this.
  */
-static void sa1100_irda_txdma_irq(void *id)
+static int
+__sa1100_irda_set_power(struct sa1100_irda *si, unsigned int state)
 {
-       struct net_device *dev = id;
-       struct sa1100_irda *si = netdev_priv(dev);
-       struct sk_buff *skb = si->txskb;
-
-       si->txskb = NULL;
-
-       /*
-        * Wait for the transmission to complete.  Unfortunately,
-        * the hardware doesn't give us an interrupt to indicate
-        * "end of frame".
-        */
-       do
-               rmb();
-       while (!(Ser2HSSR0 & HSSR0_TUR) || Ser2HSSR1 & HSSR1_TBY);
+       int ret = 0;
+       if (si->pdata->set_power)
+               ret = si->pdata->set_power(si->dev, state);
+       return ret;
+}
 
-       /*
-        * Clear the transmit underrun bit.
-        */
-       Ser2HSSR0 = HSSR0_TUR;
+static inline int
+sa1100_set_power(struct sa1100_irda *si, unsigned int state)
+{
+       int ret;
 
-       /*
-        * Do we need to change speed?  Note that we're lazy
-        * here - we don't free the old rxskb.  We don't need
-        * to allocate a buffer either.
-        */
-       if (si->newspeed) {
-               sa1100_irda_set_speed(si, si->newspeed);
-               si->newspeed = 0;
-       }
+       ret = __sa1100_irda_set_power(si, state);
+       if (ret == 0)
+               si->power = state;
 
-       /*
-        * Start reception.  This disables the transmitter for
-        * us.  This will be using the existing RX buffer.
-        */
-       sa1100_irda_rx_dma_start(si);
+       return ret;
+}
 
-       /*
-        * Account and free the packet.
-        */
-       if (skb) {
-               dma_unmap_single(si->dev, si->txbuf_dma, skb->len, DMA_TO_DEVICE);
-               dev->stats.tx_packets ++;
-               dev->stats.tx_bytes += skb->len;
-               dev_kfree_skb_irq(skb);
-       }
+static irqreturn_t sa1100_irda_irq(int irq, void *dev_id)
+{
+       struct net_device *dev = dev_id;
+       struct sa1100_irda *si = netdev_priv(dev);
 
-       /*
-        * Make sure that the TX queue is available for sending
-        * (for retries).  TX has priority over RX at all times.
-        */
-       netif_wake_queue(dev);
+       return si->irq(dev, si);
 }
 
 static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -660,62 +668,19 @@ static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
        if (speed != si->speed && speed != -1)
                si->newspeed = speed;
 
-       /*
-        * If this is an empty frame, we can bypass a lot.
-        */
+       /* If this is an empty frame, we can bypass a lot. */
        if (skb->len == 0) {
-               if (si->newspeed) {
-                       si->newspeed = 0;
-                       sa1100_irda_set_speed(si, speed);
-               }
+               sa1100_irda_check_speed(si);
                dev_kfree_skb(skb);
                return NETDEV_TX_OK;
        }
 
-       if (!IS_FIR(si)) {
-               netif_stop_queue(dev);
-
-               si->tx_buff.data = si->tx_buff.head;
-               si->tx_buff.len  = async_wrap_skb(skb, si->tx_buff.data,
-                                                 si->tx_buff.truesize);
-
-               /*
-                * Set the transmit interrupt enable.  This will fire
-                * off an interrupt immediately.  Note that we disable
-                * the receiver so we won't get spurious characteres
-                * received.
-                */
-               Ser2UTCR3 = UTCR3_TIE | UTCR3_TXE;
-
-               dev_kfree_skb(skb);
-       } else {
-               int mtt = irda_get_mtt(skb);
-
-               /*
-                * We must not be transmitting...
-                */
-               BUG_ON(si->txskb);
-
-               netif_stop_queue(dev);
-
-               si->txskb = skb;
-               si->txbuf_dma = dma_map_single(si->dev, skb->data,
-                                        skb->len, DMA_TO_DEVICE);
-
-               sa1100_start_dma(si->txdma, si->txbuf_dma, skb->len);
-
-               /*
-                * If we have a mean turn-around time, impose the specified
-                * specified delay.  We could shorten this by timing from
-                * the point we received the packet.
-                */
-               if (mtt)
-                       udelay(mtt);
+       netif_stop_queue(dev);
 
-               Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_TXE;
-       }
+       /* We must not already have a skb to transmit... */
+       BUG_ON(si->dma_tx.skb);
 
-       return NETDEV_TX_OK;
+       return si->tx_start(skb, dev, si);
 }
 
 static int
@@ -762,6 +727,69 @@ sa1100_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
        return ret;
 }
 
+static int sa1100_irda_startup(struct sa1100_irda *si)
+{
+       int ret;
+
+       /*
+        * Ensure that the ports for this device are setup correctly.
+        */
+       if (si->pdata->startup) {
+               ret = si->pdata->startup(si->dev);
+               if (ret)
+                       return ret;
+       }
+
+       /*
+        * Configure PPC for IRDA - we want to drive TXD2 low.
+        * We also want to drive this pin low during sleep.
+        */
+       PPSR &= ~PPC_TXD2;
+       PSDR &= ~PPC_TXD2;
+       PPDR |= PPC_TXD2;
+
+       /*
+        * Enable HP-SIR modulation, and ensure that the port is disabled.
+        */
+       Ser2UTCR3 = 0;
+       Ser2HSCR0 = HSCR0_UART;
+       Ser2UTCR4 = si->utcr4;
+       Ser2UTCR0 = UTCR0_8BitData;
+       Ser2HSCR2 = HSCR2_TrDataH | HSCR2_RcDataL;
+
+       /*
+        * Clear status register
+        */
+       Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
+
+       ret = sa1100_irda_set_speed(si, si->speed = 9600);
+       if (ret) {
+               Ser2UTCR3 = 0;
+               Ser2HSCR0 = 0;
+
+               if (si->pdata->shutdown)
+                       si->pdata->shutdown(si->dev);
+       }
+
+       return ret;
+}
+
+static void sa1100_irda_shutdown(struct sa1100_irda *si)
+{
+       /*
+        * Stop all DMA activity.
+        */
+       dmaengine_terminate_all(si->dma_rx.chan);
+       dmaengine_terminate_all(si->dma_tx.chan);
+
+       /* Disable the port. */
+       Ser2UTCR3 = 0;
+       Ser2HSCR0 = 0;
+
+       if (si->pdata->shutdown)
+               si->pdata->shutdown(si->dev);
+}
+
 static int sa1100_irda_start(struct net_device *dev)
 {
        struct sa1100_irda *si = netdev_priv(dev);
@@ -769,25 +797,16 @@ static int sa1100_irda_start(struct net_device *dev)
 
        si->speed = 9600;
 
-       err = request_irq(dev->irq, sa1100_irda_irq, 0, dev->name, dev);
-       if (err)
-               goto err_irq;
-
-       err = sa1100_request_dma(DMA_Ser2HSSPRd, "IrDA receive",
-                                NULL, NULL, &si->rxdma);
+       err = sa1100_irda_dma_request(si->dev, &si->dma_rx, "Ser2ICPRc",
+                               &sa1100_irda_fir_rx);
        if (err)
                goto err_rx_dma;
 
-       err = sa1100_request_dma(DMA_Ser2HSSPWr, "IrDA transmit",
-                                sa1100_irda_txdma_irq, dev, &si->txdma);
+       err = sa1100_irda_dma_request(si->dev, &si->dma_tx, "Ser2ICPTr",
+                               &sa1100_irda_sir_tx);
        if (err)
                goto err_tx_dma;
 
-       /*
-        * The interrupt must remain disabled for now.
-        */
-       disable_irq(dev->irq);
-
        /*
         * Setup the serial port for the specified speed.
         */
@@ -803,44 +822,60 @@ static int sa1100_irda_start(struct net_device *dev)
        if (!si->irlap)
                goto err_irlap;
 
+       err = request_irq(dev->irq, sa1100_irda_irq, 0, dev->name, dev);
+       if (err)
+               goto err_irq;
+
        /*
         * Now enable the interrupt and start the queue
         */
        si->open = 1;
        sa1100_set_power(si, power_level); /* low power mode */
-       enable_irq(dev->irq);
+
        netif_start_queue(dev);
        return 0;
 
+err_irq:
+       irlap_close(si->irlap);
 err_irlap:
        si->open = 0;
        sa1100_irda_shutdown(si);
 err_startup:
-       sa1100_free_dma(si->txdma);
+       dma_release_channel(si->dma_tx.chan);
 err_tx_dma:
-       sa1100_free_dma(si->rxdma);
+       dma_release_channel(si->dma_rx.chan);
 err_rx_dma:
-       free_irq(dev->irq, dev);
-err_irq:
        return err;
 }
 
 static int sa1100_irda_stop(struct net_device *dev)
 {
        struct sa1100_irda *si = netdev_priv(dev);
+       struct sk_buff *skb;
 
-       disable_irq(dev->irq);
+       netif_stop_queue(dev);
+
+       si->open = 0;
        sa1100_irda_shutdown(si);
 
        /*
-        * If we have been doing DMA receive, make sure we
+        * If we have been doing any DMA activity, make sure we
         * tidy that up cleanly.
         */
-       if (si->rxskb) {
-               dma_unmap_single(si->dev, si->rxbuf_dma, HPSIR_MAX_RXLEN,
-                                DMA_FROM_DEVICE);
-               dev_kfree_skb(si->rxskb);
-               si->rxskb = NULL;
+       skb = si->dma_rx.skb;
+       if (skb) {
+               dma_unmap_sg(si->dma_rx.dev, &si->dma_rx.sg, 1,
+                            DMA_FROM_DEVICE);
+               dev_kfree_skb(skb);
+               si->dma_rx.skb = NULL;
+       }
+
+       skb = si->dma_tx.skb;
+       if (skb) {
+               dma_unmap_sg(si->dma_tx.dev, &si->dma_tx.sg, 1,
+                            DMA_TO_DEVICE);
+               dev_kfree_skb(skb);
+               si->dma_tx.skb = NULL;
        }
 
        /* Stop IrLAP */
@@ -849,14 +884,11 @@ static int sa1100_irda_stop(struct net_device *dev)
                si->irlap = NULL;
        }
 
-       netif_stop_queue(dev);
-       si->open = 0;
-
        /*
         * Free resources
         */
-       sa1100_free_dma(si->txdma);
-       sa1100_free_dma(si->rxdma);
+       dma_release_channel(si->dma_tx.chan);
+       dma_release_channel(si->dma_rx.chan);
        free_irq(dev->irq, dev);
 
        sa1100_set_power(si, 0);
@@ -888,11 +920,15 @@ static int sa1100_irda_probe(struct platform_device *pdev)
        struct net_device *dev;
        struct sa1100_irda *si;
        unsigned int baudrate_mask;
-       int err;
+       int err, irq;
 
        if (!pdev->dev.platform_data)
                return -EINVAL;
 
+       irq = platform_get_irq(pdev, 0);
+       if (irq <= 0)
+               return irq < 0 ? irq : -ENXIO;
+
        err = request_mem_region(__PREG(Ser2UTCR0), 0x24, "IrDA") ? 0 : -EBUSY;
        if (err)
                goto err_mem_1;
@@ -907,22 +943,27 @@ static int sa1100_irda_probe(struct platform_device *pdev)
        if (!dev)
                goto err_mem_4;
 
+       SET_NETDEV_DEV(dev, &pdev->dev);
+
        si = netdev_priv(dev);
        si->dev = &pdev->dev;
        si->pdata = pdev->dev.platform_data;
 
+       sg_init_table(&si->dma_rx.sg, 1);
+       sg_init_table(&si->dma_tx.sg, 1);
+
        /*
         * Initialise the HP-SIR buffers
         */
        err = sa1100_irda_init_iobuf(&si->rx_buff, 14384);
        if (err)
                goto err_mem_5;
-       err = sa1100_irda_init_iobuf(&si->tx_buff, 4000);
+       err = sa1100_irda_init_iobuf(&si->tx_buff, IRDA_SIR_MAX_FRAME);
        if (err)
                goto err_mem_5;
 
        dev->netdev_ops = &sa1100_irda_netdev_ops;
-       dev->irq        = IRQ_Ser2ICP;
+       dev->irq        = irq;
 
        irda_init_max_qos_capabilies(&si->qos);
 
@@ -996,6 +1037,74 @@ static int sa1100_irda_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM
+/*
+ * Suspend the IrDA interface.
+ */
+static int sa1100_irda_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct net_device *dev = platform_get_drvdata(pdev);
+       struct sa1100_irda *si;
+
+       if (!dev)
+               return 0;
+
+       si = netdev_priv(dev);
+       if (si->open) {
+               /*
+                * Stop the transmit queue
+                */
+               netif_device_detach(dev);
+               disable_irq(dev->irq);
+               sa1100_irda_shutdown(si);
+               __sa1100_irda_set_power(si, 0);
+       }
+
+       return 0;
+}
+
+/*
+ * Resume the IrDA interface.
+ */
+static int sa1100_irda_resume(struct platform_device *pdev)
+{
+       struct net_device *dev = platform_get_drvdata(pdev);
+       struct sa1100_irda *si;
+
+       if (!dev)
+               return 0;
+
+       si = netdev_priv(dev);
+       if (si->open) {
+               /*
+                * If we missed a speed change, initialise at the new speed
+                * directly.  It is debatable whether this is actually
+                * required, but in the interests of continuing from where
+                * we left off it is desirable.  The converse argument is
+                * that we should re-negotiate at 9600 baud again.
+                */
+               if (si->newspeed) {
+                       si->speed = si->newspeed;
+                       si->newspeed = 0;
+               }
+
+               sa1100_irda_startup(si);
+               __sa1100_irda_set_power(si, si->power);
+               enable_irq(dev->irq);
+
+               /*
+                * This automatically wakes up the queue
+                */
+               netif_device_attach(dev);
+       }
+
+       return 0;
+}
+#else
+#define sa1100_irda_suspend    NULL
+#define sa1100_irda_resume     NULL
+#endif
+
 static struct platform_driver sa1100ir_driver = {
        .probe          = sa1100_irda_probe,
        .remove         = sa1100_irda_remove,
index 790cbdea739237758c5bc68137d6c44a9c4d7e2e..3886b30ed37355394e6155f60bb7e559e598391e 100644 (file)
@@ -164,12 +164,14 @@ static void rx_complete(struct urb *req)
                                /* Can't use pskb_pull() on page in IRQ */
                                memcpy(skb_put(skb, 1), page_address(page), 1);
                                skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
-                                               page, 1, req->actual_length);
+                                               page, 1, req->actual_length,
+                                               req->actual_length);
                                page = NULL;
                        }
                } else {
                        skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
-                                       page, 0, req->actual_length);
+                                       page, 0, req->actual_length,
+                                       req->actual_length);
                        page = NULL;
                }
                if (req->actual_length < PAGE_SIZE)
index aac68f5195c0b2a9518616a07eca3e6763793ad8..552d24bf862e124cdae480ed301418469053ccdd 100644 (file)
@@ -409,6 +409,42 @@ static const struct usb_device_id products[] = {
                .bInterfaceProtocol = 0xff,
                .driver_info        = (unsigned long)&qmi_wwan_force_int4,
        },
+       {       /* ZTE (Vodafone) K3565-Z */
+               .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
+               .idVendor           = 0x19d2,
+               .idProduct          = 0x0063,
+               .bInterfaceClass    = 0xff,
+               .bInterfaceSubClass = 0xff,
+               .bInterfaceProtocol = 0xff,
+               .driver_info        = (unsigned long)&qmi_wwan_force_int4,
+       },
+       {       /* ZTE (Vodafone) K3570-Z */
+               .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
+               .idVendor           = 0x19d2,
+               .idProduct          = 0x1008,
+               .bInterfaceClass    = 0xff,
+               .bInterfaceSubClass = 0xff,
+               .bInterfaceProtocol = 0xff,
+               .driver_info        = (unsigned long)&qmi_wwan_force_int4,
+       },
+       {       /* ZTE (Vodafone) K3571-Z */
+               .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
+               .idVendor           = 0x19d2,
+               .idProduct          = 0x1010,
+               .bInterfaceClass    = 0xff,
+               .bInterfaceSubClass = 0xff,
+               .bInterfaceProtocol = 0xff,
+               .driver_info        = (unsigned long)&qmi_wwan_force_int4,
+       },
+       {       /* ZTE (Vodafone) K4505-Z */
+               .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
+               .idVendor           = 0x19d2,
+               .idProduct          = 0x0104,
+               .bInterfaceClass    = 0xff,
+               .bInterfaceSubClass = 0xff,
+               .bInterfaceProtocol = 0xff,
+               .driver_info        = (unsigned long)&qmi_wwan_force_int4,
+       },
        {QMI_GOBI_DEVICE(0x05c6, 0x9212)},      /* Acer Gobi Modem Device */
        {QMI_GOBI_DEVICE(0x03f0, 0x1f1d)},      /* HP un2400 Gobi Modem Device */
        {QMI_GOBI_DEVICE(0x03f0, 0x371d)},      /* HP un2430 Mobile Broadband Module */
index c5b1d199e0bc9b8cd154f2b217994b684cbbba06..b25c01be0d90c4ad06b833d00bf2d3a5132273e3 100644 (file)
@@ -499,7 +499,8 @@ il3945_pass_packet_to_mac80211(struct il_priv *il, struct il_rx_buf *rxb,
                                      le32_to_cpu(rx_end->status), stats);
 
        skb_add_rx_frag(skb, 0, rxb->page,
-                       (void *)rx_hdr->payload - (void *)pkt, len);
+                       (void *)rx_hdr->payload - (void *)pkt, len,
+                       len);
 
        il_update_stats(il, false, fc, len);
        memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
index 7b54dbb338be6127bec123f8414cd3231eaabb00..17f1c6853182d23ddfb092c3d0e7787a04ce0731 100644 (file)
@@ -596,7 +596,8 @@ il4965_pass_packet_to_mac80211(struct il_priv *il, struct ieee80211_hdr *hdr,
                return;
        }
 
-       skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
+       skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len,
+                       len);
 
        il_update_stats(il, false, fc, len);
        memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
index 44c6f712b77d5f9b5a39359ff7e5e17c86e7b9ab..f4b84d1596e3cd62cc44bea717bf9bc0eb59c3cc 100644 (file)
@@ -796,7 +796,7 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
 
        offset = (void *)hdr - rxb_addr(rxb);
        p = rxb_steal_page(rxb);
-       skb_add_rx_frag(skb, 0, p, offset, len);
+       skb_add_rx_frag(skb, 0, p, offset, len, len);
 
        iwl_update_stats(priv, false, fc, len);
 
index 6ea51dcbc728d43685aa20ef4553c743698e749e..8e84ce9765a9257a8429cd33838ab7e4bbd8fb15 100644 (file)
@@ -91,4 +91,8 @@ config OF_PCI_IRQ
        help
          OpenFirmware PCI IRQ routing helpers
 
+config OF_MTD
+       depends on MTD
+       def_bool y
+
 endmenu # OF
index a73f5a51ff4c0b884b25632d0bdd2252add04032..aa90e602c8a7e5dfbe66770edf8e85dadcc27173 100644 (file)
@@ -12,3 +12,4 @@ obj-$(CONFIG_OF_SELFTEST) += selftest.o
 obj-$(CONFIG_OF_MDIO)  += of_mdio.o
 obj-$(CONFIG_OF_PCI)   += of_pci.o
 obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
+obj-$(CONFIG_OF_MTD)   += of_mtd.o
diff --git a/drivers/of/of_mtd.c b/drivers/of/of_mtd.c
new file mode 100644 (file)
index 0000000..e7cad62
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * OF helpers for mtd.
+ *
+ * This file is released under the GPLv2
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/of_mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/export.h>
+
+/**
+ * It maps 'enum nand_ecc_modes_t' found in include/linux/mtd/nand.h
+ * into the device tree binding of 'nand-ecc', so that MTD
+ * device driver can get nand ecc from device tree.
+ */
+static const char *nand_ecc_modes[] = {
+       [NAND_ECC_NONE]         = "none",
+       [NAND_ECC_SOFT]         = "soft",
+       [NAND_ECC_HW]           = "hw",
+       [NAND_ECC_HW_SYNDROME]  = "hw_syndrome",
+       [NAND_ECC_HW_OOB_FIRST] = "hw_oob_first",
+       [NAND_ECC_SOFT_BCH]     = "soft_bch",
+};
+
+/**
+ * of_get_nand_ecc_mode - Get nand ecc mode for given device_node
+ * @np:        Pointer to the given device_node
+ *
+ * The function gets ecc mode string from property 'nand-ecc-mode',
+ * and return its index in nand_ecc_modes table, or errno in error case.
+ */
+const int of_get_nand_ecc_mode(struct device_node *np)
+{
+       const char *pm;
+       int err, i;
+
+       err = of_property_read_string(np, "nand-ecc-mode", &pm);
+       if (err < 0)
+               return err;
+
+       for (i = 0; i < ARRAY_SIZE(nand_ecc_modes); i++)
+               if (!strcasecmp(pm, nand_ecc_modes[i]))
+                       return i;
+
+       return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(of_get_nand_ecc_mode);
+
+/**
+ * of_get_nand_bus_width - Get nand bus witdh for given device_node
+ * @np:        Pointer to the given device_node
+ *
+ * return bus width option, or errno in error case.
+ */
+int of_get_nand_bus_width(struct device_node *np)
+{
+       u32 val;
+
+       if (of_property_read_u32(np, "nand-bus-width", &val))
+               return 8;
+
+       switch(val) {
+       case 8:
+       case 16:
+               return val;
+       default:
+               return -EIO;
+       }
+}
+EXPORT_SYMBOL_GPL(of_get_nand_bus_width);
+
+/**
+ * of_get_nand_on_flash_bbt - Get nand on flash bbt for given device_node
+ * @np:        Pointer to the given device_node
+ *
+ * return true if present false other wise
+ */
+bool of_get_nand_on_flash_bbt(struct device_node *np)
+{
+       return of_property_read_bool(np, "nand-on-flash-bbt");
+}
+EXPORT_SYMBOL_GPL(of_get_nand_on_flash_bbt);
index 4902206f53d942ec6174243991c842ea580feb34..1dd68f502634e4725fa9a2c97328d370236bcbdf 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <mach/board.h>
 #include <mach/at91rm9200_mc.h>
+#include <mach/at91_ramc.h>
 
 
 /*
@@ -156,7 +157,7 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
        /*
         * Use 16 bit accesses unless/until we need 8-bit i/o space.
         */
-       csr = at91_sys_read(AT91_SMC_CSR(cf->board->chipselect)) & ~AT91_SMC_DBW;
+       csr = at91_ramc_read(0, AT91_SMC_CSR(cf->board->chipselect)) & ~AT91_SMC_DBW;
 
        /*
         * NOTE: this CF controller ignores IOIS16, so we can't really do
@@ -175,7 +176,7 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
                csr |= AT91_SMC_DBW_16;
                pr_debug("%s: 16bit i/o bus\n", driver_name);
        }
-       at91_sys_write(AT91_SMC_CSR(cf->board->chipselect), csr);
+       at91_ramc_write(0, AT91_SMC_CSR(cf->board->chipselect), csr);
 
        io->start = cf->socket.io_offset;
        io->stop = io->start + SZ_2K - 1;
index ef5848f65241fbb27cea4223b775b2a529ea1630..70f728ce1856b0723e1ff9a51dd8ffb3847a8b19 100644 (file)
 
 #include "sa1111_generic.h"
 
+/*
+ * These are offsets from the above base.
+ */
+#define PCCR   0x0000
+#define PCSSR  0x0004
+#define PCSR   0x0008
+
+#define PCSR_S0_READY  (1<<0)
+#define PCSR_S1_READY  (1<<1)
+#define PCSR_S0_DETECT (1<<2)
+#define PCSR_S1_DETECT (1<<3)
+#define PCSR_S0_VS1    (1<<4)
+#define PCSR_S0_VS2    (1<<5)
+#define PCSR_S1_VS1    (1<<6)
+#define PCSR_S1_VS2    (1<<7)
+#define PCSR_S0_WP     (1<<8)
+#define PCSR_S1_WP     (1<<9)
+#define PCSR_S0_BVD1   (1<<10)
+#define PCSR_S0_BVD2   (1<<11)
+#define PCSR_S1_BVD1   (1<<12)
+#define PCSR_S1_BVD2   (1<<13)
+
+#define PCCR_S0_RST    (1<<0)
+#define PCCR_S1_RST    (1<<1)
+#define PCCR_S0_FLT    (1<<2)
+#define PCCR_S1_FLT    (1<<3)
+#define PCCR_S0_PWAITEN        (1<<4)
+#define PCCR_S1_PWAITEN        (1<<5)
+#define PCCR_S0_PSE    (1<<6)
+#define PCCR_S1_PSE    (1<<7)
+
+#define PCSSR_S0_SLEEP (1<<0)
+#define PCSSR_S1_SLEEP (1<<1)
+
 #define IDX_IRQ_S0_READY_NINT  (0)
 #define IDX_IRQ_S0_CD_VALID    (1)
 #define IDX_IRQ_S0_BVD1_STSCHG (2)
@@ -32,7 +66,7 @@
 void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
 {
        struct sa1111_pcmcia_socket *s = to_skt(skt);
-       unsigned long status = sa1111_readl(s->dev->mapbase + SA1111_PCSR);
+       unsigned long status = sa1111_readl(s->dev->mapbase + PCSR);
 
        switch (skt->nr) {
        case 0:
@@ -88,10 +122,10 @@ int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
                pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT;
 
        local_irq_save(flags);
-       val = sa1111_readl(s->dev->mapbase + SA1111_PCCR);
+       val = sa1111_readl(s->dev->mapbase + PCCR);
        val &= ~pccr_skt_mask;
        val |= pccr_set_mask & pccr_skt_mask;
-       sa1111_writel(val, s->dev->mapbase + SA1111_PCCR);
+       sa1111_writel(val, s->dev->mapbase + PCCR);
        local_irq_restore(flags);
 
        return 0;
@@ -141,20 +175,26 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
 static int pcmcia_probe(struct sa1111_dev *dev)
 {
        void __iomem *base;
+       int ret;
+
+       ret = sa1111_enable_device(dev);
+       if (ret)
+               return ret;
 
        dev_set_drvdata(&dev->dev, NULL);
 
-       if (!request_mem_region(dev->res.start, 512,
-                               SA1111_DRIVER_NAME(dev)))
+       if (!request_mem_region(dev->res.start, 512, SA1111_DRIVER_NAME(dev))) {
+               sa1111_disable_device(dev);
                return -EBUSY;
+       }
 
        base = dev->mapbase;
 
        /*
         * Initialise the suspend state.
         */
-       sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + SA1111_PCSSR);
-       sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + SA1111_PCCR);
+       sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + PCSSR);
+       sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + PCCR);
 
 #ifdef CONFIG_SA1100_BADGE4
        pcmcia_badge4_init(&dev->dev);
@@ -184,6 +224,7 @@ static int __devexit pcmcia_remove(struct sa1111_dev *dev)
        }
 
        release_mem_region(dev->res.start, 512);
+       sa1111_disable_device(dev);
        return 0;
 }
 
index 50f297d850e752a57c825d0fd9dbdb238a301bd3..1d78739c4c07699b44f1479165660c229eaa462b 100644 (file)
@@ -94,12 +94,7 @@ neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_sta
 
        ret = sa1111_pcmcia_configure_socket(skt, state);
        if (ret == 0) {
-               unsigned long flags;
-
-               local_irq_save(flags);
-               NCR_0 = (NCR_0 & ~ncr_mask) | ncr_set;
-
-               local_irq_restore(flags);
+               neponset_ncr_frob(ncr_mask, ncr_set);
                sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
        }
 
index a229de98ae6f286171c3ce96ddb0d8d6f299108e..36db5a441ebacda2498fc4cfcc5b0e24d9437a9f 100644 (file)
@@ -258,14 +258,6 @@ config REGULATOR_DB8500_PRCMU
          This driver supports the voltage domain regulators controlled by the
          DB8500 PRCMU
 
-config REGULATOR_BQ24022
-       tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC"
-       help
-         This driver controls a TI bq24022 Charger attached via
-         GPIOs. The provided current regulator can enable/disable
-         charging select between 100 mA and 500 mA charging current
-         limit.
-
 config REGULATOR_TPS6105X
        tristate "TI TPS6105X Power regulators"
        depends on TPS6105X
index b5042c885d8921af2d105f55dcf521bf4bd447be..94b52745e9579ec3fbb9790efef74a5d41315770 100644 (file)
@@ -16,7 +16,6 @@ obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
 obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o
 obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o
 obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o
-obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
 obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
 obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
 obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o
diff --git a/drivers/regulator/bq24022.c b/drivers/regulator/bq24022.c
deleted file mode 100644 (file)
index 9fab6d1..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Support for TI bq24022 (bqTINY-II) Dual Input (USB/AC Adpater)
- * 1-Cell Li-Ion Charger connected via GPIOs.
- *
- * Copyright (c) 2008 Philipp Zabel
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/gpio.h>
-#include <linux/regulator/bq24022.h>
-#include <linux/regulator/driver.h>
-
-
-static int bq24022_set_current_limit(struct regulator_dev *rdev,
-                                       int min_uA, int max_uA)
-{
-       struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev);
-
-       dev_dbg(rdev_get_dev(rdev), "setting current limit to %s mA\n",
-               max_uA >= 500000 ? "500" : "100");
-
-       /* REVISIT: maybe return error if min_uA != 0 ? */
-       gpio_set_value(pdata->gpio_iset2, max_uA >= 500000);
-       return 0;
-}
-
-static int bq24022_get_current_limit(struct regulator_dev *rdev)
-{
-       struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev);
-
-       return gpio_get_value(pdata->gpio_iset2) ? 500000 : 100000;
-}
-
-static int bq24022_enable(struct regulator_dev *rdev)
-{
-       struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev);
-
-       dev_dbg(rdev_get_dev(rdev), "enabling charger\n");
-
-       gpio_set_value(pdata->gpio_nce, 0);
-       return 0;
-}
-
-static int bq24022_disable(struct regulator_dev *rdev)
-{
-       struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev);
-
-       dev_dbg(rdev_get_dev(rdev), "disabling charger\n");
-
-       gpio_set_value(pdata->gpio_nce, 1);
-       return 0;
-}
-
-static int bq24022_is_enabled(struct regulator_dev *rdev)
-{
-       struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev);
-
-       return !gpio_get_value(pdata->gpio_nce);
-}
-
-static struct regulator_ops bq24022_ops = {
-       .set_current_limit = bq24022_set_current_limit,
-       .get_current_limit = bq24022_get_current_limit,
-       .enable            = bq24022_enable,
-       .disable           = bq24022_disable,
-       .is_enabled        = bq24022_is_enabled,
-};
-
-static struct regulator_desc bq24022_desc = {
-       .name  = "bq24022",
-       .ops   = &bq24022_ops,
-       .type  = REGULATOR_CURRENT,
-       .owner = THIS_MODULE,
-};
-
-static int __init bq24022_probe(struct platform_device *pdev)
-{
-       struct bq24022_mach_info *pdata = pdev->dev.platform_data;
-       struct regulator_dev *bq24022;
-       int ret;
-
-       if (!pdata || !pdata->gpio_nce || !pdata->gpio_iset2)
-               return -EINVAL;
-
-       ret = gpio_request(pdata->gpio_nce, "ncharge_en");
-       if (ret) {
-               dev_dbg(&pdev->dev, "couldn't request nCE GPIO: %d\n",
-                       pdata->gpio_nce);
-               goto err_ce;
-       }
-       ret = gpio_request(pdata->gpio_iset2, "charge_mode");
-       if (ret) {
-               dev_dbg(&pdev->dev, "couldn't request ISET2 GPIO: %d\n",
-                       pdata->gpio_iset2);
-               goto err_iset2;
-       }
-       ret = gpio_direction_output(pdata->gpio_iset2, 0);
-       ret = gpio_direction_output(pdata->gpio_nce, 1);
-
-       bq24022 = regulator_register(&bq24022_desc, &pdev->dev,
-                                    pdata->init_data, pdata, NULL);
-       if (IS_ERR(bq24022)) {
-               dev_dbg(&pdev->dev, "couldn't register regulator\n");
-               ret = PTR_ERR(bq24022);
-               goto err_reg;
-       }
-       platform_set_drvdata(pdev, bq24022);
-       dev_dbg(&pdev->dev, "registered regulator\n");
-
-       return 0;
-err_reg:
-       gpio_free(pdata->gpio_iset2);
-err_iset2:
-       gpio_free(pdata->gpio_nce);
-err_ce:
-       return ret;
-}
-
-static int __devexit bq24022_remove(struct platform_device *pdev)
-{
-       struct bq24022_mach_info *pdata = pdev->dev.platform_data;
-       struct regulator_dev *bq24022 = platform_get_drvdata(pdev);
-
-       regulator_unregister(bq24022);
-       gpio_free(pdata->gpio_iset2);
-       gpio_free(pdata->gpio_nce);
-
-       return 0;
-}
-
-static struct platform_driver bq24022_driver = {
-       .driver = {
-               .name = "bq24022",
-       },
-       .remove = __devexit_p(bq24022_remove),
-};
-
-static int __init bq24022_init(void)
-{
-       return platform_driver_probe(&bq24022_driver, bq24022_probe);
-}
-
-static void __exit bq24022_exit(void)
-{
-       platform_driver_unregister(&bq24022_driver);
-}
-
-module_init(bq24022_init);
-module_exit(bq24022_exit);
-
-MODULE_AUTHOR("Philipp Zabel");
-MODULE_DESCRIPTION("TI bq24022 Li-Ion Charger driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
new file mode 100644 (file)
index 0000000..24d880e
--- /dev/null
@@ -0,0 +1,28 @@
+menu "Remoteproc drivers (EXPERIMENTAL)"
+
+# REMOTEPROC gets selected by whoever wants it
+config REMOTEPROC
+       tristate
+       depends on EXPERIMENTAL
+
+config OMAP_REMOTEPROC
+       tristate "OMAP remoteproc support"
+       depends on ARCH_OMAP4
+       depends on OMAP_IOMMU
+       select REMOTEPROC
+       select OMAP_MBOX_FWK
+       select RPMSG
+       help
+         Say y here to support OMAP's remote processors (dual M3
+         and DSP on OMAP4) via the remote processor framework.
+
+         Currently only supported on OMAP4.
+
+         Usually you want to say y here, in order to enable multimedia
+         use-cases to run on your platform (multimedia codecs are
+         offloaded to remote DSP processors using this framework).
+
+         It's safe to say n here if you're not interested in multimedia
+         offloading or just want a bare minimum kernel.
+
+endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
new file mode 100644 (file)
index 0000000..5445d9b
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Generic framework for controlling remote processors
+#
+
+obj-$(CONFIG_REMOTEPROC)               += remoteproc.o
+remoteproc-y                           := remoteproc_core.o
+remoteproc-y                           += remoteproc_debugfs.o
+remoteproc-y                           += remoteproc_virtio.o
+obj-$(CONFIG_OMAP_REMOTEPROC)          += omap_remoteproc.o
diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c
new file mode 100644 (file)
index 0000000..69425c4
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * OMAP Remote Processor driver
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Brian Swetland <swetland@google.com>
+ * Fernando Guzman Lugo <fernando.lugo@ti.com>
+ * Mark Grosen <mgrosen@ti.com>
+ * Suman Anna <s-anna@ti.com>
+ * Hari Kanigeri <h-kanigeri2@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/remoteproc.h>
+
+#include <plat/mailbox.h>
+#include <plat/remoteproc.h>
+
+#include "omap_remoteproc.h"
+#include "remoteproc_internal.h"
+
+/**
+ * struct omap_rproc - omap remote processor state
+ * @mbox: omap mailbox handle
+ * @nb: notifier block that will be invoked on inbound mailbox messages
+ * @rproc: rproc handle
+ */
+struct omap_rproc {
+       struct omap_mbox *mbox;
+       struct notifier_block nb;
+       struct rproc *rproc;
+};
+
+/**
+ * omap_rproc_mbox_callback() - inbound mailbox message handler
+ * @this: notifier block
+ * @index: unused
+ * @data: mailbox payload
+ *
+ * This handler is invoked by omap's mailbox driver whenever a mailbox
+ * message is received. Usually, the mailbox payload simply contains
+ * the index of the virtqueue that is kicked by the remote processor,
+ * and we let remoteproc core handle it.
+ *
+ * In addition to virtqueue indices, we also have some out-of-band values
+ * that indicates different events. Those values are deliberately very
+ * big so they don't coincide with virtqueue indices.
+ */
+static int omap_rproc_mbox_callback(struct notifier_block *this,
+                                       unsigned long index, void *data)
+{
+       mbox_msg_t msg = (mbox_msg_t) data;
+       struct omap_rproc *oproc = container_of(this, struct omap_rproc, nb);
+       struct device *dev = oproc->rproc->dev;
+       const char *name = oproc->rproc->name;
+
+       dev_dbg(dev, "mbox msg: 0x%x\n", msg);
+
+       switch (msg) {
+       case RP_MBOX_CRASH:
+               /* just log this for now. later, we'll also do recovery */
+               dev_err(dev, "omap rproc %s crashed\n", name);
+               break;
+       case RP_MBOX_ECHO_REPLY:
+               dev_info(dev, "received echo reply from %s\n", name);
+               break;
+       default:
+               /* msg contains the index of the triggered vring */
+               if (rproc_vq_interrupt(oproc->rproc, msg) == IRQ_NONE)
+                       dev_dbg(dev, "no message was found in vqid %d\n", msg);
+       }
+
+       return NOTIFY_DONE;
+}
+
+/* kick a virtqueue */
+static void omap_rproc_kick(struct rproc *rproc, int vqid)
+{
+       struct omap_rproc *oproc = rproc->priv;
+       int ret;
+
+       /* send the index of the triggered virtqueue in the mailbox payload */
+       ret = omap_mbox_msg_send(oproc->mbox, vqid);
+       if (ret)
+               dev_err(rproc->dev, "omap_mbox_msg_send failed: %d\n", ret);
+}
+
+/*
+ * Power up the remote processor.
+ *
+ * This function will be invoked only after the firmware for this rproc
+ * was loaded, parsed successfully, and all of its resource requirements
+ * were met.
+ */
+static int omap_rproc_start(struct rproc *rproc)
+{
+       struct omap_rproc *oproc = rproc->priv;
+       struct platform_device *pdev = to_platform_device(rproc->dev);
+       struct omap_rproc_pdata *pdata = pdev->dev.platform_data;
+       int ret;
+
+       oproc->nb.notifier_call = omap_rproc_mbox_callback;
+
+       /* every omap rproc is assigned a mailbox instance for messaging */
+       oproc->mbox = omap_mbox_get(pdata->mbox_name, &oproc->nb);
+       if (IS_ERR(oproc->mbox)) {
+               ret = PTR_ERR(oproc->mbox);
+               dev_err(rproc->dev, "omap_mbox_get failed: %d\n", ret);
+               return ret;
+       }
+
+       /*
+        * Ping the remote processor. this is only for sanity-sake;
+        * there is no functional effect whatsoever.
+        *
+        * Note that the reply will _not_ arrive immediately: this message
+        * will wait in the mailbox fifo until the remote processor is booted.
+        */
+       ret = omap_mbox_msg_send(oproc->mbox, RP_MBOX_ECHO_REQUEST);
+       if (ret) {
+               dev_err(rproc->dev, "omap_mbox_get failed: %d\n", ret);
+               goto put_mbox;
+       }
+
+       ret = pdata->device_enable(pdev);
+       if (ret) {
+               dev_err(rproc->dev, "omap_device_enable failed: %d\n", ret);
+               goto put_mbox;
+       }
+
+       return 0;
+
+put_mbox:
+       omap_mbox_put(oproc->mbox, &oproc->nb);
+       return ret;
+}
+
+/* power off the remote processor */
+static int omap_rproc_stop(struct rproc *rproc)
+{
+       struct platform_device *pdev = to_platform_device(rproc->dev);
+       struct omap_rproc_pdata *pdata = pdev->dev.platform_data;
+       struct omap_rproc *oproc = rproc->priv;
+       int ret;
+
+       ret = pdata->device_shutdown(pdev);
+       if (ret)
+               return ret;
+
+       omap_mbox_put(oproc->mbox, &oproc->nb);
+
+       return 0;
+}
+
+static struct rproc_ops omap_rproc_ops = {
+       .start          = omap_rproc_start,
+       .stop           = omap_rproc_stop,
+       .kick           = omap_rproc_kick,
+};
+
+static int __devinit omap_rproc_probe(struct platform_device *pdev)
+{
+       struct omap_rproc_pdata *pdata = pdev->dev.platform_data;
+       struct omap_rproc *oproc;
+       struct rproc *rproc;
+       int ret;
+
+       ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+       if (ret) {
+               dev_err(pdev->dev.parent, "dma_set_coherent_mask: %d\n", ret);
+               return ret;
+       }
+
+       rproc = rproc_alloc(&pdev->dev, pdata->name, &omap_rproc_ops,
+                               pdata->firmware, sizeof(*oproc));
+       if (!rproc)
+               return -ENOMEM;
+
+       oproc = rproc->priv;
+       oproc->rproc = rproc;
+
+       platform_set_drvdata(pdev, rproc);
+
+       ret = rproc_register(rproc);
+       if (ret)
+               goto free_rproc;
+
+       return 0;
+
+free_rproc:
+       rproc_free(rproc);
+       return ret;
+}
+
+static int __devexit omap_rproc_remove(struct platform_device *pdev)
+{
+       struct rproc *rproc = platform_get_drvdata(pdev);
+
+       return rproc_unregister(rproc);
+}
+
+static struct platform_driver omap_rproc_driver = {
+       .probe = omap_rproc_probe,
+       .remove = __devexit_p(omap_rproc_remove),
+       .driver = {
+               .name = "omap-rproc",
+               .owner = THIS_MODULE,
+       },
+};
+
+module_platform_driver(omap_rproc_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("OMAP Remote Processor control driver");
diff --git a/drivers/remoteproc/omap_remoteproc.h b/drivers/remoteproc/omap_remoteproc.h
new file mode 100644 (file)
index 0000000..f6d2036
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Remote processor messaging
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name Texas Instruments nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _OMAP_RPMSG_H
+#define _OMAP_RPMSG_H
+
+/*
+ * enum - Predefined Mailbox Messages
+ *
+ * @RP_MBOX_READY: informs the M3's that we're up and running. this is
+ * part of the init sequence sent that the M3 expects to see immediately
+ * after it is booted.
+ *
+ * @RP_MBOX_PENDING_MSG: informs the receiver that there is an inbound
+ * message waiting in its own receive-side vring. please note that currently
+ * this message is optional: alternatively, one can explicitly send the index
+ * of the triggered virtqueue itself. the preferred approach will be decided
+ * as we progress and experiment with those two different approaches.
+ *
+ * @RP_MBOX_CRASH: this message is sent if BIOS crashes
+ *
+ * @RP_MBOX_ECHO_REQUEST: a mailbox-level "ping" message.
+ *
+ * @RP_MBOX_ECHO_REPLY: a mailbox-level reply to a "ping"
+ *
+ * @RP_MBOX_ABORT_REQUEST: a "please crash" request, used for testing the
+ * recovery mechanism (to some extent).
+ */
+enum omap_rp_mbox_messages {
+       RP_MBOX_READY           = 0xFFFFFF00,
+       RP_MBOX_PENDING_MSG     = 0xFFFFFF01,
+       RP_MBOX_CRASH           = 0xFFFFFF02,
+       RP_MBOX_ECHO_REQUEST    = 0xFFFFFF03,
+       RP_MBOX_ECHO_REPLY      = 0xFFFFFF04,
+       RP_MBOX_ABORT_REQUEST   = 0xFFFFFF05,
+};
+
+#endif /* _OMAP_RPMSG_H */
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
new file mode 100644 (file)
index 0000000..ee15c68
--- /dev/null
@@ -0,0 +1,1586 @@
+/*
+ * Remote Processor Framework
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Brian Swetland <swetland@google.com>
+ * Mark Grosen <mgrosen@ti.com>
+ * Fernando Guzman Lugo <fernando.lugo@ti.com>
+ * Suman Anna <s-anna@ti.com>
+ * Robert Tivy <rtivy@ti.com>
+ * Armando Uribe De Leon <x0095078@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt)    "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/dma-mapping.h>
+#include <linux/firmware.h>
+#include <linux/string.h>
+#include <linux/debugfs.h>
+#include <linux/remoteproc.h>
+#include <linux/iommu.h>
+#include <linux/klist.h>
+#include <linux/elf.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_ring.h>
+#include <asm/byteorder.h>
+
+#include "remoteproc_internal.h"
+
+static void klist_rproc_get(struct klist_node *n);
+static void klist_rproc_put(struct klist_node *n);
+
+/*
+ * klist of the available remote processors.
+ *
+ * We need this in order to support name-based lookups (needed by the
+ * rproc_get_by_name()).
+ *
+ * That said, we don't use rproc_get_by_name() at this point.
+ * The use cases that do require its existence should be
+ * scrutinized, and hopefully migrated to rproc_boot() using device-based
+ * binding.
+ *
+ * If/when this materializes, we could drop the klist (and the by_name
+ * API).
+ */
+static DEFINE_KLIST(rprocs, klist_rproc_get, klist_rproc_put);
+
+typedef int (*rproc_handle_resources_t)(struct rproc *rproc,
+                               struct resource_table *table, int len);
+typedef int (*rproc_handle_resource_t)(struct rproc *rproc, void *, int avail);
+
+/*
+ * This is the IOMMU fault handler we register with the IOMMU API
+ * (when relevant; not all remote processors access memory through
+ * an IOMMU).
+ *
+ * IOMMU core will invoke this handler whenever the remote processor
+ * will try to access an unmapped device address.
+ *
+ * Currently this is mostly a stub, but it will be later used to trigger
+ * the recovery of the remote processor.
+ */
+static int rproc_iommu_fault(struct iommu_domain *domain, struct device *dev,
+               unsigned long iova, int flags)
+{
+       dev_err(dev, "iommu fault: da 0x%lx flags 0x%x\n", iova, flags);
+
+       /*
+        * Let the iommu core know we're not really handling this fault;
+        * we just plan to use this as a recovery trigger.
+        */
+       return -ENOSYS;
+}
+
+static int rproc_enable_iommu(struct rproc *rproc)
+{
+       struct iommu_domain *domain;
+       struct device *dev = rproc->dev;
+       int ret;
+
+       /*
+        * We currently use iommu_present() to decide if an IOMMU
+        * setup is needed.
+        *
+        * This works for simple cases, but will easily fail with
+        * platforms that do have an IOMMU, but not for this specific
+        * rproc.
+        *
+        * This will be easily solved by introducing hw capabilities
+        * that will be set by the remoteproc driver.
+        */
+       if (!iommu_present(dev->bus)) {
+               dev_dbg(dev, "iommu not found\n");
+               return 0;
+       }
+
+       domain = iommu_domain_alloc(dev->bus);
+       if (!domain) {
+               dev_err(dev, "can't alloc iommu domain\n");
+               return -ENOMEM;
+       }
+
+       iommu_set_fault_handler(domain, rproc_iommu_fault);
+
+       ret = iommu_attach_device(domain, dev);
+       if (ret) {
+               dev_err(dev, "can't attach iommu device: %d\n", ret);
+               goto free_domain;
+       }
+
+       rproc->domain = domain;
+
+       return 0;
+
+free_domain:
+       iommu_domain_free(domain);
+       return ret;
+}
+
+static void rproc_disable_iommu(struct rproc *rproc)
+{
+       struct iommu_domain *domain = rproc->domain;
+       struct device *dev = rproc->dev;
+
+       if (!domain)
+               return;
+
+       iommu_detach_device(domain, dev);
+       iommu_domain_free(domain);
+
+       return;
+}
+
+/*
+ * Some remote processors will ask us to allocate them physically contiguous
+ * memory regions (which we call "carveouts"), and map them to specific
+ * device addresses (which are hardcoded in the firmware).
+ *
+ * They may then ask us to copy objects into specific device addresses (e.g.
+ * code/data sections) or expose us certain symbols in other device address
+ * (e.g. their trace buffer).
+ *
+ * This function is an internal helper with which we can go over the allocated
+ * carveouts and translate specific device address to kernel virtual addresses
+ * so we can access the referenced memory.
+ *
+ * Note: phys_to_virt(iommu_iova_to_phys(rproc->domain, da)) will work too,
+ * but only on kernel direct mapped RAM memory. Instead, we're just using
+ * here the output of the DMA API, which should be more correct.
+ */
+static void *rproc_da_to_va(struct rproc *rproc, u64 da, int len)
+{
+       struct rproc_mem_entry *carveout;
+       void *ptr = NULL;
+
+       list_for_each_entry(carveout, &rproc->carveouts, node) {
+               int offset = da - carveout->da;
+
+               /* try next carveout if da is too small */
+               if (offset < 0)
+                       continue;
+
+               /* try next carveout if da is too large */
+               if (offset + len > carveout->len)
+                       continue;
+
+               ptr = carveout->va + offset;
+
+               break;
+       }
+
+       return ptr;
+}
+
+/**
+ * rproc_load_segments() - load firmware segments to memory
+ * @rproc: remote processor which will be booted using these fw segments
+ * @elf_data: the content of the ELF firmware image
+ * @len: firmware size (in bytes)
+ *
+ * This function loads the firmware segments to memory, where the remote
+ * processor expects them.
+ *
+ * Some remote processors will expect their code and data to be placed
+ * in specific device addresses, and can't have them dynamically assigned.
+ *
+ * We currently support only those kind of remote processors, and expect
+ * the program header's paddr member to contain those addresses. We then go
+ * through the physically contiguous "carveout" memory regions which we
+ * allocated (and mapped) earlier on behalf of the remote processor,
+ * and "translate" device address to kernel addresses, so we can copy the
+ * segments where they are expected.
+ *
+ * Currently we only support remote processors that required carveout
+ * allocations and got them mapped onto their iommus. Some processors
+ * might be different: they might not have iommus, and would prefer to
+ * directly allocate memory for every segment/resource. This is not yet
+ * supported, though.
+ */
+static int
+rproc_load_segments(struct rproc *rproc, const u8 *elf_data, size_t len)
+{
+       struct device *dev = rproc->dev;
+       struct elf32_hdr *ehdr;
+       struct elf32_phdr *phdr;
+       int i, ret = 0;
+
+       ehdr = (struct elf32_hdr *)elf_data;
+       phdr = (struct elf32_phdr *)(elf_data + ehdr->e_phoff);
+
+       /* go through the available ELF segments */
+       for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
+               u32 da = phdr->p_paddr;
+               u32 memsz = phdr->p_memsz;
+               u32 filesz = phdr->p_filesz;
+               u32 offset = phdr->p_offset;
+               void *ptr;
+
+               if (phdr->p_type != PT_LOAD)
+                       continue;
+
+               dev_dbg(dev, "phdr: type %d da 0x%x memsz 0x%x filesz 0x%x\n",
+                                       phdr->p_type, da, memsz, filesz);
+
+               if (filesz > memsz) {
+                       dev_err(dev, "bad phdr filesz 0x%x memsz 0x%x\n",
+                                                       filesz, memsz);
+                       ret = -EINVAL;
+                       break;
+               }
+
+               if (offset + filesz > len) {
+                       dev_err(dev, "truncated fw: need 0x%x avail 0x%x\n",
+                                       offset + filesz, len);
+                       ret = -EINVAL;
+                       break;
+               }
+
+               /* grab the kernel address for this device address */
+               ptr = rproc_da_to_va(rproc, da, memsz);
+               if (!ptr) {
+                       dev_err(dev, "bad phdr da 0x%x mem 0x%x\n", da, memsz);
+                       ret = -EINVAL;
+                       break;
+               }
+
+               /* put the segment where the remote processor expects it */
+               if (phdr->p_filesz)
+                       memcpy(ptr, elf_data + phdr->p_offset, filesz);
+
+               /*
+                * Zero out remaining memory for this segment.
+                *
+                * This isn't strictly required since dma_alloc_coherent already
+                * did this for us. albeit harmless, we may consider removing
+                * this.
+                */
+               if (memsz > filesz)
+                       memset(ptr + filesz, 0, memsz - filesz);
+       }
+
+       return ret;
+}
+
+static int
+__rproc_handle_vring(struct rproc_vdev *rvdev, struct fw_rsc_vdev *rsc, int i)
+{
+       struct rproc *rproc = rvdev->rproc;
+       struct device *dev = rproc->dev;
+       struct fw_rsc_vdev_vring *vring = &rsc->vring[i];
+       dma_addr_t dma;
+       void *va;
+       int ret, size, notifyid;
+
+       dev_dbg(dev, "vdev rsc: vring%d: da %x, qsz %d, align %d\n",
+                               i, vring->da, vring->num, vring->align);
+
+       /* make sure reserved bytes are zeroes */
+       if (vring->reserved) {
+               dev_err(dev, "vring rsc has non zero reserved bytes\n");
+               return -EINVAL;
+       }
+
+       /* verify queue size and vring alignment are sane */
+       if (!vring->num || !vring->align) {
+               dev_err(dev, "invalid qsz (%d) or alignment (%d)\n",
+                                               vring->num, vring->align);
+               return -EINVAL;
+       }
+
+       /* actual size of vring (in bytes) */
+       size = PAGE_ALIGN(vring_size(vring->num, vring->align));
+
+       if (!idr_pre_get(&rproc->notifyids, GFP_KERNEL)) {
+               dev_err(dev, "idr_pre_get failed\n");
+               return -ENOMEM;
+       }
+
+       /*
+        * Allocate non-cacheable memory for the vring. In the future
+        * this call will also configure the IOMMU for us
+        */
+       va = dma_alloc_coherent(dev, size, &dma, GFP_KERNEL);
+       if (!va) {
+               dev_err(dev, "dma_alloc_coherent failed\n");
+               return -EINVAL;
+       }
+
+       /* assign an rproc-wide unique index for this vring */
+       /* TODO: assign a notifyid for rvdev updates as well */
+       ret = idr_get_new(&rproc->notifyids, &rvdev->vring[i], &notifyid);
+       if (ret) {
+               dev_err(dev, "idr_get_new failed: %d\n", ret);
+               dma_free_coherent(dev, size, va, dma);
+               return ret;
+       }
+
+       /* let the rproc know the da and notifyid of this vring */
+       /* TODO: expose this to remote processor */
+       vring->da = dma;
+       vring->notifyid = notifyid;
+
+       dev_dbg(dev, "vring%d: va %p dma %x size %x idr %d\n", i, va,
+                                       dma, size, notifyid);
+
+       rvdev->vring[i].len = vring->num;
+       rvdev->vring[i].align = vring->align;
+       rvdev->vring[i].va = va;
+       rvdev->vring[i].dma = dma;
+       rvdev->vring[i].notifyid = notifyid;
+       rvdev->vring[i].rvdev = rvdev;
+
+       return 0;
+}
+
+static void __rproc_free_vrings(struct rproc_vdev *rvdev, int i)
+{
+       struct rproc *rproc = rvdev->rproc;
+
+       for (i--; i > 0; i--) {
+               struct rproc_vring *rvring = &rvdev->vring[i];
+               int size = PAGE_ALIGN(vring_size(rvring->len, rvring->align));
+
+               dma_free_coherent(rproc->dev, size, rvring->va, rvring->dma);
+               idr_remove(&rproc->notifyids, rvring->notifyid);
+       }
+}
+
+/**
+ * rproc_handle_vdev() - handle a vdev fw resource
+ * @rproc: the remote processor
+ * @rsc: the vring resource descriptor
+ * @avail: size of available data (for sanity checking the image)
+ *
+ * This resource entry requests the host to statically register a virtio
+ * device (vdev), and setup everything needed to support it. It contains
+ * everything needed to make it possible: the virtio device id, virtio
+ * device features, vrings information, virtio config space, etc...
+ *
+ * Before registering the vdev, the vrings are allocated from non-cacheable
+ * physically contiguous memory. Currently we only support two vrings per
+ * remote processor (temporary limitation). We might also want to consider
+ * doing the vring allocation only later when ->find_vqs() is invoked, and
+ * then release them upon ->del_vqs().
+ *
+ * Note: @da is currently not really handled correctly: we dynamically
+ * allocate it using the DMA API, ignoring requested hard coded addresses,
+ * and we don't take care of any required IOMMU programming. This is all
+ * going to be taken care of when the generic iommu-based DMA API will be
+ * merged. Meanwhile, statically-addressed iommu-based firmware images should
+ * use RSC_DEVMEM resource entries to map their required @da to the physical
+ * address of their base CMA region (ouch, hacky!).
+ *
+ * Returns 0 on success, or an appropriate error code otherwise
+ */
+static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
+                                                               int avail)
+{
+       struct device *dev = rproc->dev;
+       struct rproc_vdev *rvdev;
+       int i, ret;
+
+       /* make sure resource isn't truncated */
+       if (sizeof(*rsc) + rsc->num_of_vrings * sizeof(struct fw_rsc_vdev_vring)
+                       + rsc->config_len > avail) {
+               dev_err(rproc->dev, "vdev rsc is truncated\n");
+               return -EINVAL;
+       }
+
+       /* make sure reserved bytes are zeroes */
+       if (rsc->reserved[0] || rsc->reserved[1]) {
+               dev_err(dev, "vdev rsc has non zero reserved bytes\n");
+               return -EINVAL;
+       }
+
+       dev_dbg(dev, "vdev rsc: id %d, dfeatures %x, cfg len %d, %d vrings\n",
+               rsc->id, rsc->dfeatures, rsc->config_len, rsc->num_of_vrings);
+
+       /* we currently support only two vrings per rvdev */
+       if (rsc->num_of_vrings > ARRAY_SIZE(rvdev->vring)) {
+               dev_err(dev, "too many vrings: %d\n", rsc->num_of_vrings);
+               return -EINVAL;
+       }
+
+       rvdev = kzalloc(sizeof(struct rproc_vdev), GFP_KERNEL);
+       if (!rvdev)
+               return -ENOMEM;
+
+       rvdev->rproc = rproc;
+
+       /* allocate the vrings */
+       for (i = 0; i < rsc->num_of_vrings; i++) {
+               ret = __rproc_handle_vring(rvdev, rsc, i);
+               if (ret)
+                       goto free_vrings;
+       }
+
+       /* remember the device features */
+       rvdev->dfeatures = rsc->dfeatures;
+
+       list_add_tail(&rvdev->node, &rproc->rvdevs);
+
+       /* it is now safe to add the virtio device */
+       ret = rproc_add_virtio_dev(rvdev, rsc->id);
+       if (ret)
+               goto free_vrings;
+
+       return 0;
+
+free_vrings:
+       __rproc_free_vrings(rvdev, i);
+       kfree(rvdev);
+       return ret;
+}
+
+/**
+ * rproc_handle_trace() - handle a shared trace buffer resource
+ * @rproc: the remote processor
+ * @rsc: the trace resource descriptor
+ * @avail: size of available data (for sanity checking the image)
+ *
+ * In case the remote processor dumps trace logs into memory,
+ * export it via debugfs.
+ *
+ * Currently, the 'da' member of @rsc should contain the device address
+ * where the remote processor is dumping the traces. Later we could also
+ * support dynamically allocating this address using the generic
+ * DMA API (but currently there isn't a use case for that).
+ *
+ * Returns 0 on success, or an appropriate error code otherwise
+ */
+static int rproc_handle_trace(struct rproc *rproc, struct fw_rsc_trace *rsc,
+                                                               int avail)
+{
+       struct rproc_mem_entry *trace;
+       struct device *dev = rproc->dev;
+       void *ptr;
+       char name[15];
+
+       if (sizeof(*rsc) > avail) {
+               dev_err(rproc->dev, "trace rsc is truncated\n");
+               return -EINVAL;
+       }
+
+       /* make sure reserved bytes are zeroes */
+       if (rsc->reserved) {
+               dev_err(dev, "trace rsc has non zero reserved bytes\n");
+               return -EINVAL;
+       }
+
+       /* what's the kernel address of this resource ? */
+       ptr = rproc_da_to_va(rproc, rsc->da, rsc->len);
+       if (!ptr) {
+               dev_err(dev, "erroneous trace resource entry\n");
+               return -EINVAL;
+       }
+
+       trace = kzalloc(sizeof(*trace), GFP_KERNEL);
+       if (!trace) {
+               dev_err(dev, "kzalloc trace failed\n");
+               return -ENOMEM;
+       }
+
+       /* set the trace buffer dma properties */
+       trace->len = rsc->len;
+       trace->va = ptr;
+
+       /* make sure snprintf always null terminates, even if truncating */
+       snprintf(name, sizeof(name), "trace%d", rproc->num_traces);
+
+       /* create the debugfs entry */
+       trace->priv = rproc_create_trace_file(name, rproc, trace);
+       if (!trace->priv) {
+               trace->va = NULL;
+               kfree(trace);
+               return -EINVAL;
+       }
+
+       list_add_tail(&trace->node, &rproc->traces);
+
+       rproc->num_traces++;
+
+       dev_dbg(dev, "%s added: va %p, da 0x%x, len 0x%x\n", name, ptr,
+                                               rsc->da, rsc->len);
+
+       return 0;
+}
+
+/**
+ * rproc_handle_devmem() - handle devmem resource entry
+ * @rproc: remote processor handle
+ * @rsc: the devmem resource entry
+ * @avail: size of available data (for sanity checking the image)
+ *
+ * Remote processors commonly need to access certain on-chip peripherals.
+ *
+ * Some of these remote processors access memory via an iommu device,
+ * and might require us to configure their iommu before they can access
+ * the on-chip peripherals they need.
+ *
+ * This resource entry is a request to map such a peripheral device.
+ *
+ * These devmem entries will contain the physical address of the device in
+ * the 'pa' member. If a specific device address is expected, then 'da' will
+ * contain it (currently this is the only use case supported). 'len' will
+ * contain the size of the physical region we need to map.
+ *
+ * Currently we just "trust" those devmem entries to contain valid physical
+ * addresses, but this is going to change: we want the implementations to
+ * tell us ranges of physical addresses the firmware is allowed to request,
+ * and not allow firmwares to request access to physical addresses that
+ * are outside those ranges.
+ */
+static int rproc_handle_devmem(struct rproc *rproc, struct fw_rsc_devmem *rsc,
+                                                               int avail)
+{
+       struct rproc_mem_entry *mapping;
+       int ret;
+
+       /* no point in handling this resource without a valid iommu domain */
+       if (!rproc->domain)
+               return -EINVAL;
+
+       if (sizeof(*rsc) > avail) {
+               dev_err(rproc->dev, "devmem rsc is truncated\n");
+               return -EINVAL;
+       }
+
+       /* make sure reserved bytes are zeroes */
+       if (rsc->reserved) {
+               dev_err(rproc->dev, "devmem rsc has non zero reserved bytes\n");
+               return -EINVAL;
+       }
+
+       mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
+       if (!mapping) {
+               dev_err(rproc->dev, "kzalloc mapping failed\n");
+               return -ENOMEM;
+       }
+
+       ret = iommu_map(rproc->domain, rsc->da, rsc->pa, rsc->len, rsc->flags);
+       if (ret) {
+               dev_err(rproc->dev, "failed to map devmem: %d\n", ret);
+               goto out;
+       }
+
+       /*
+        * We'll need this info later when we'll want to unmap everything
+        * (e.g. on shutdown).
+        *
+        * We can't trust the remote processor not to change the resource
+        * table, so we must maintain this info independently.
+        */
+       mapping->da = rsc->da;
+       mapping->len = rsc->len;
+       list_add_tail(&mapping->node, &rproc->mappings);
+
+       dev_dbg(rproc->dev, "mapped devmem pa 0x%x, da 0x%x, len 0x%x\n",
+                                       rsc->pa, rsc->da, rsc->len);
+
+       return 0;
+
+out:
+       kfree(mapping);
+       return ret;
+}
+
+/**
+ * rproc_handle_carveout() - handle phys contig memory allocation requests
+ * @rproc: rproc handle
+ * @rsc: the resource entry
+ * @avail: size of available data (for image validation)
+ *
+ * This function will handle firmware requests for allocation of physically
+ * contiguous memory regions.
+ *
+ * These request entries should come first in the firmware's resource table,
+ * as other firmware entries might request placing other data objects inside
+ * these memory regions (e.g. data/code segments, trace resource entries, ...).
+ *
+ * Allocating memory this way helps utilizing the reserved physical memory
+ * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
+ * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
+ * pressure is important; it may have a substantial impact on performance.
+ */
+static int rproc_handle_carveout(struct rproc *rproc,
+                               struct fw_rsc_carveout *rsc, int avail)
+{
+       struct rproc_mem_entry *carveout, *mapping;
+       struct device *dev = rproc->dev;
+       dma_addr_t dma;
+       void *va;
+       int ret;
+
+       if (sizeof(*rsc) > avail) {
+               dev_err(rproc->dev, "carveout rsc is truncated\n");
+               return -EINVAL;
+       }
+
+       /* make sure reserved bytes are zeroes */
+       if (rsc->reserved) {
+               dev_err(dev, "carveout rsc has non zero reserved bytes\n");
+               return -EINVAL;
+       }
+
+       dev_dbg(dev, "carveout rsc: da %x, pa %x, len %x, flags %x\n",
+                       rsc->da, rsc->pa, rsc->len, rsc->flags);
+
+       mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
+       if (!mapping) {
+               dev_err(dev, "kzalloc mapping failed\n");
+               return -ENOMEM;
+       }
+
+       carveout = kzalloc(sizeof(*carveout), GFP_KERNEL);
+       if (!carveout) {
+               dev_err(dev, "kzalloc carveout failed\n");
+               ret = -ENOMEM;
+               goto free_mapping;
+       }
+
+       va = dma_alloc_coherent(dev, rsc->len, &dma, GFP_KERNEL);
+       if (!va) {
+               dev_err(dev, "failed to dma alloc carveout: %d\n", rsc->len);
+               ret = -ENOMEM;
+               goto free_carv;
+       }
+
+       dev_dbg(dev, "carveout va %p, dma %x, len 0x%x\n", va, dma, rsc->len);
+
+       /*
+        * Ok, this is non-standard.
+        *
+        * Sometimes we can't rely on the generic iommu-based DMA API
+        * to dynamically allocate the device address and then set the IOMMU
+        * tables accordingly, because some remote processors might
+        * _require_ us to use hard coded device addresses that their
+        * firmware was compiled with.
+        *
+        * In this case, we must use the IOMMU API directly and map
+        * the memory to the device address as expected by the remote
+        * processor.
+        *
+        * Obviously such remote processor devices should not be configured
+        * to use the iommu-based DMA API: we expect 'dma' to contain the
+        * physical address in this case.
+        */
+       if (rproc->domain) {
+               ret = iommu_map(rproc->domain, rsc->da, dma, rsc->len,
+                                                               rsc->flags);
+               if (ret) {
+                       dev_err(dev, "iommu_map failed: %d\n", ret);
+                       goto dma_free;
+               }
+
+               /*
+                * We'll need this info later when we'll want to unmap
+                * everything (e.g. on shutdown).
+                *
+                * We can't trust the remote processor not to change the
+                * resource table, so we must maintain this info independently.
+                */
+               mapping->da = rsc->da;
+               mapping->len = rsc->len;
+               list_add_tail(&mapping->node, &rproc->mappings);
+
+               dev_dbg(dev, "carveout mapped 0x%x to 0x%x\n", rsc->da, dma);
+
+               /*
+                * Some remote processors might need to know the pa
+                * even though they are behind an IOMMU. E.g., OMAP4's
+                * remote M3 processor needs this so it can control
+                * on-chip hardware accelerators that are not behind
+                * the IOMMU, and therefor must know the pa.
+                *
+                * Generally we don't want to expose physical addresses
+                * if we don't have to (remote processors are generally
+                * _not_ trusted), so we might want to do this only for
+                * remote processor that _must_ have this (e.g. OMAP4's
+                * dual M3 subsystem).
+                */
+               rsc->pa = dma;
+       }
+
+       carveout->va = va;
+       carveout->len = rsc->len;
+       carveout->dma = dma;
+       carveout->da = rsc->da;
+
+       list_add_tail(&carveout->node, &rproc->carveouts);
+
+       return 0;
+
+dma_free:
+       dma_free_coherent(dev, rsc->len, va, dma);
+free_carv:
+       kfree(carveout);
+free_mapping:
+       kfree(mapping);
+       return ret;
+}
+
+/*
+ * A lookup table for resource handlers. The indices are defined in
+ * enum fw_resource_type.
+ */
+static rproc_handle_resource_t rproc_handle_rsc[] = {
+       [RSC_CARVEOUT] = (rproc_handle_resource_t)rproc_handle_carveout,
+       [RSC_DEVMEM] = (rproc_handle_resource_t)rproc_handle_devmem,
+       [RSC_TRACE] = (rproc_handle_resource_t)rproc_handle_trace,
+       [RSC_VDEV] = NULL, /* VDEVs were handled upon registrarion */
+};
+
+/* handle firmware resource entries before booting the remote processor */
+static int
+rproc_handle_boot_rsc(struct rproc *rproc, struct resource_table *table, int len)
+{
+       struct device *dev = rproc->dev;
+       rproc_handle_resource_t handler;
+       int ret = 0, i;
+
+       for (i = 0; i < table->num; i++) {
+               int offset = table->offset[i];
+               struct fw_rsc_hdr *hdr = (void *)table + offset;
+               int avail = len - offset - sizeof(*hdr);
+               void *rsc = (void *)hdr + sizeof(*hdr);
+
+               /* make sure table isn't truncated */
+               if (avail < 0) {
+                       dev_err(dev, "rsc table is truncated\n");
+                       return -EINVAL;
+               }
+
+               dev_dbg(dev, "rsc: type %d\n", hdr->type);
+
+               if (hdr->type >= RSC_LAST) {
+                       dev_warn(dev, "unsupported resource %d\n", hdr->type);
+                       continue;
+               }
+
+               handler = rproc_handle_rsc[hdr->type];
+               if (!handler)
+                       continue;
+
+               ret = handler(rproc, rsc, avail);
+               if (ret)
+                       break;
+       }
+
+       return ret;
+}
+
+/* handle firmware resource entries while registering the remote processor */
+static int
+rproc_handle_virtio_rsc(struct rproc *rproc, struct resource_table *table, int len)
+{
+       struct device *dev = rproc->dev;
+       int ret = 0, i;
+
+       for (i = 0; i < table->num; i++) {
+               int offset = table->offset[i];
+               struct fw_rsc_hdr *hdr = (void *)table + offset;
+               int avail = len - offset - sizeof(*hdr);
+               struct fw_rsc_vdev *vrsc;
+
+               /* make sure table isn't truncated */
+               if (avail < 0) {
+                       dev_err(dev, "rsc table is truncated\n");
+                       return -EINVAL;
+               }
+
+               dev_dbg(dev, "%s: rsc type %d\n", __func__, hdr->type);
+
+               if (hdr->type != RSC_VDEV)
+                       continue;
+
+               vrsc = (struct fw_rsc_vdev *)hdr->data;
+
+               ret = rproc_handle_vdev(rproc, vrsc, avail);
+               if (ret)
+                       break;
+       }
+
+       return ret;
+}
+
+/**
+ * rproc_find_rsc_table() - find the resource table
+ * @rproc: the rproc handle
+ * @elf_data: the content of the ELF firmware image
+ * @len: firmware size (in bytes)
+ * @tablesz: place holder for providing back the table size
+ *
+ * This function finds the resource table inside the remote processor's
+ * firmware. It is used both upon the registration of @rproc (in order
+ * to look for and register the supported virito devices), and when the
+ * @rproc is booted.
+ *
+ * Returns the pointer to the resource table if it is found, and write its
+ * size into @tablesz. If a valid table isn't found, NULL is returned
+ * (and @tablesz isn't set).
+ */
+static struct resource_table *
+rproc_find_rsc_table(struct rproc *rproc, const u8 *elf_data, size_t len,
+                                                       int *tablesz)
+{
+       struct elf32_hdr *ehdr;
+       struct elf32_shdr *shdr;
+       const char *name_table;
+       struct device *dev = rproc->dev;
+       struct resource_table *table = NULL;
+       int i;
+
+       ehdr = (struct elf32_hdr *)elf_data;
+       shdr = (struct elf32_shdr *)(elf_data + ehdr->e_shoff);
+       name_table = elf_data + shdr[ehdr->e_shstrndx].sh_offset;
+
+       /* look for the resource table and handle it */
+       for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
+               int size = shdr->sh_size;
+               int offset = shdr->sh_offset;
+
+               if (strcmp(name_table + shdr->sh_name, ".resource_table"))
+                       continue;
+
+               table = (struct resource_table *)(elf_data + offset);
+
+               /* make sure we have the entire table */
+               if (offset + size > len) {
+                       dev_err(dev, "resource table truncated\n");
+                       return NULL;
+               }
+
+               /* make sure table has at least the header */
+               if (sizeof(struct resource_table) > size) {
+                       dev_err(dev, "header-less resource table\n");
+                       return NULL;
+               }
+
+               /* we don't support any version beyond the first */
+               if (table->ver != 1) {
+                       dev_err(dev, "unsupported fw ver: %d\n", table->ver);
+                       return NULL;
+               }
+
+               /* make sure reserved bytes are zeroes */
+               if (table->reserved[0] || table->reserved[1]) {
+                       dev_err(dev, "non zero reserved bytes\n");
+                       return NULL;
+               }
+
+               /* make sure the offsets array isn't truncated */
+               if (table->num * sizeof(table->offset[0]) +
+                               sizeof(struct resource_table) > size) {
+                       dev_err(dev, "resource table incomplete\n");
+                       return NULL;
+               }
+
+               *tablesz = shdr->sh_size;
+               break;
+       }
+
+       return table;
+}
+
+/**
+ * rproc_resource_cleanup() - clean up and free all acquired resources
+ * @rproc: rproc handle
+ *
+ * This function will free all resources acquired for @rproc, and it
+ * is called whenever @rproc either shuts down or fails to boot.
+ */
+static void rproc_resource_cleanup(struct rproc *rproc)
+{
+       struct rproc_mem_entry *entry, *tmp;
+       struct device *dev = rproc->dev;
+
+       /* clean up debugfs trace entries */
+       list_for_each_entry_safe(entry, tmp, &rproc->traces, node) {
+               rproc_remove_trace_file(entry->priv);
+               rproc->num_traces--;
+               list_del(&entry->node);
+               kfree(entry);
+       }
+
+       /* clean up carveout allocations */
+       list_for_each_entry_safe(entry, tmp, &rproc->carveouts, node) {
+               dma_free_coherent(dev, entry->len, entry->va, entry->dma);
+               list_del(&entry->node);
+               kfree(entry);
+       }
+
+       /* clean up iommu mapping entries */
+       list_for_each_entry_safe(entry, tmp, &rproc->mappings, node) {
+               size_t unmapped;
+
+               unmapped = iommu_unmap(rproc->domain, entry->da, entry->len);
+               if (unmapped != entry->len) {
+                       /* nothing much to do besides complaining */
+                       dev_err(dev, "failed to unmap %u/%u\n", entry->len,
+                                                               unmapped);
+               }
+
+               list_del(&entry->node);
+               kfree(entry);
+       }
+}
+
+/* make sure this fw image is sane */
+static int rproc_fw_sanity_check(struct rproc *rproc, const struct firmware *fw)
+{
+       const char *name = rproc->firmware;
+       struct device *dev = rproc->dev;
+       struct elf32_hdr *ehdr;
+       char class;
+
+       if (!fw) {
+               dev_err(dev, "failed to load %s\n", name);
+               return -EINVAL;
+       }
+
+       if (fw->size < sizeof(struct elf32_hdr)) {
+               dev_err(dev, "Image is too small\n");
+               return -EINVAL;
+       }
+
+       ehdr = (struct elf32_hdr *)fw->data;
+
+       /* We only support ELF32 at this point */
+       class = ehdr->e_ident[EI_CLASS];
+       if (class != ELFCLASS32) {
+               dev_err(dev, "Unsupported class: %d\n", class);
+               return -EINVAL;
+       }
+
+       /* We assume the firmware has the same endianess as the host */
+# ifdef __LITTLE_ENDIAN
+       if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) {
+# else /* BIG ENDIAN */
+       if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) {
+# endif
+               dev_err(dev, "Unsupported firmware endianess\n");
+               return -EINVAL;
+       }
+
+       if (fw->size < ehdr->e_shoff + sizeof(struct elf32_shdr)) {
+               dev_err(dev, "Image is too small\n");
+               return -EINVAL;
+       }
+
+       if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
+               dev_err(dev, "Image is corrupted (bad magic)\n");
+               return -EINVAL;
+       }
+
+       if (ehdr->e_phnum == 0) {
+               dev_err(dev, "No loadable segments\n");
+               return -EINVAL;
+       }
+
+       if (ehdr->e_phoff > fw->size) {
+               dev_err(dev, "Firmware size is too small\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/*
+ * take a firmware and boot a remote processor with it.
+ */
+static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
+{
+       struct device *dev = rproc->dev;
+       const char *name = rproc->firmware;
+       struct elf32_hdr *ehdr;
+       struct resource_table *table;
+       int ret, tablesz;
+
+       ret = rproc_fw_sanity_check(rproc, fw);
+       if (ret)
+               return ret;
+
+       ehdr = (struct elf32_hdr *)fw->data;
+
+       dev_info(dev, "Booting fw image %s, size %d\n", name, fw->size);
+
+       /*
+        * if enabling an IOMMU isn't relevant for this rproc, this is
+        * just a nop
+        */
+       ret = rproc_enable_iommu(rproc);
+       if (ret) {
+               dev_err(dev, "can't enable iommu: %d\n", ret);
+               return ret;
+       }
+
+       /*
+        * The ELF entry point is the rproc's boot addr (though this is not
+        * a configurable property of all remote processors: some will always
+        * boot at a specific hardcoded address).
+        */
+       rproc->bootaddr = ehdr->e_entry;
+
+       /* look for the resource table */
+       table = rproc_find_rsc_table(rproc, fw->data, fw->size, &tablesz);
+       if (!table)
+               goto clean_up;
+
+       /* handle fw resources which are required to boot rproc */
+       ret = rproc_handle_boot_rsc(rproc, table, tablesz);
+       if (ret) {
+               dev_err(dev, "Failed to process resources: %d\n", ret);
+               goto clean_up;
+       }
+
+       /* load the ELF segments to memory */
+       ret = rproc_load_segments(rproc, fw->data, fw->size);
+       if (ret) {
+               dev_err(dev, "Failed to load program segments: %d\n", ret);
+               goto clean_up;
+       }
+
+       /* power up the remote processor */
+       ret = rproc->ops->start(rproc);
+       if (ret) {
+               dev_err(dev, "can't start rproc %s: %d\n", rproc->name, ret);
+               goto clean_up;
+       }
+
+       rproc->state = RPROC_RUNNING;
+
+       dev_info(dev, "remote processor %s is now up\n", rproc->name);
+
+       return 0;
+
+clean_up:
+       rproc_resource_cleanup(rproc);
+       rproc_disable_iommu(rproc);
+       return ret;
+}
+
+/*
+ * take a firmware and look for virtio devices to register.
+ *
+ * Note: this function is called asynchronously upon registration of the
+ * remote processor (so we must wait until it completes before we try
+ * to unregister the device. one other option is just to use kref here,
+ * that might be cleaner).
+ */
+static void rproc_fw_config_virtio(const struct firmware *fw, void *context)
+{
+       struct rproc *rproc = context;
+       struct resource_table *table;
+       int ret, tablesz;
+
+       if (rproc_fw_sanity_check(rproc, fw) < 0)
+               goto out;
+
+       /* look for the resource table */
+       table = rproc_find_rsc_table(rproc, fw->data, fw->size, &tablesz);
+       if (!table)
+               goto out;
+
+       /* look for virtio devices and register them */
+       ret = rproc_handle_virtio_rsc(rproc, table, tablesz);
+       if (ret)
+               goto out;
+
+out:
+       if (fw)
+               release_firmware(fw);
+       /* allow rproc_unregister() contexts, if any, to proceed */
+       complete_all(&rproc->firmware_loading_complete);
+}
+
+/**
+ * rproc_boot() - boot a remote processor
+ * @rproc: handle of a remote processor
+ *
+ * Boot a remote processor (i.e. load its firmware, power it on, ...).
+ *
+ * If the remote processor is already powered on, this function immediately
+ * returns (successfully).
+ *
+ * Returns 0 on success, and an appropriate error value otherwise.
+ */
+int rproc_boot(struct rproc *rproc)
+{
+       const struct firmware *firmware_p;
+       struct device *dev;
+       int ret;
+
+       if (!rproc) {
+               pr_err("invalid rproc handle\n");
+               return -EINVAL;
+       }
+
+       dev = rproc->dev;
+
+       ret = mutex_lock_interruptible(&rproc->lock);
+       if (ret) {
+               dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, ret);
+               return ret;
+       }
+
+       /* loading a firmware is required */
+       if (!rproc->firmware) {
+               dev_err(dev, "%s: no firmware to load\n", __func__);
+               ret = -EINVAL;
+               goto unlock_mutex;
+       }
+
+       /* prevent underlying implementation from being removed */
+       if (!try_module_get(dev->driver->owner)) {
+               dev_err(dev, "%s: can't get owner\n", __func__);
+               ret = -EINVAL;
+               goto unlock_mutex;
+       }
+
+       /* skip the boot process if rproc is already powered up */
+       if (atomic_inc_return(&rproc->power) > 1) {
+               ret = 0;
+               goto unlock_mutex;
+       }
+
+       dev_info(dev, "powering up %s\n", rproc->name);
+
+       /* load firmware */
+       ret = request_firmware(&firmware_p, rproc->firmware, dev);
+       if (ret < 0) {
+               dev_err(dev, "request_firmware failed: %d\n", ret);
+               goto downref_rproc;
+       }
+
+       ret = rproc_fw_boot(rproc, firmware_p);
+
+       release_firmware(firmware_p);
+
+downref_rproc:
+       if (ret) {
+               module_put(dev->driver->owner);
+               atomic_dec(&rproc->power);
+       }
+unlock_mutex:
+       mutex_unlock(&rproc->lock);
+       return ret;
+}
+EXPORT_SYMBOL(rproc_boot);
+
+/**
+ * rproc_shutdown() - power off the remote processor
+ * @rproc: the remote processor
+ *
+ * Power off a remote processor (previously booted with rproc_boot()).
+ *
+ * In case @rproc is still being used by an additional user(s), then
+ * this function will just decrement the power refcount and exit,
+ * without really powering off the device.
+ *
+ * Every call to rproc_boot() must (eventually) be accompanied by a call
+ * to rproc_shutdown(). Calling rproc_shutdown() redundantly is a bug.
+ *
+ * Notes:
+ * - we're not decrementing the rproc's refcount, only the power refcount.
+ *   which means that the @rproc handle stays valid even after rproc_shutdown()
+ *   returns, and users can still use it with a subsequent rproc_boot(), if
+ *   needed.
+ * - don't call rproc_shutdown() to unroll rproc_get_by_name(), exactly
+ *   because rproc_shutdown() _does not_ decrement the refcount of @rproc.
+ *   To decrement the refcount of @rproc, use rproc_put() (but _only_ if
+ *   you acquired @rproc using rproc_get_by_name()).
+ */
+void rproc_shutdown(struct rproc *rproc)
+{
+       struct device *dev = rproc->dev;
+       int ret;
+
+       ret = mutex_lock_interruptible(&rproc->lock);
+       if (ret) {
+               dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, ret);
+               return;
+       }
+
+       /* if the remote proc is still needed, bail out */
+       if (!atomic_dec_and_test(&rproc->power))
+               goto out;
+
+       /* power off the remote processor */
+       ret = rproc->ops->stop(rproc);
+       if (ret) {
+               atomic_inc(&rproc->power);
+               dev_err(dev, "can't stop rproc: %d\n", ret);
+               goto out;
+       }
+
+       /* clean up all acquired resources */
+       rproc_resource_cleanup(rproc);
+
+       rproc_disable_iommu(rproc);
+
+       rproc->state = RPROC_OFFLINE;
+
+       dev_info(dev, "stopped remote processor %s\n", rproc->name);
+
+out:
+       mutex_unlock(&rproc->lock);
+       if (!ret)
+               module_put(dev->driver->owner);
+}
+EXPORT_SYMBOL(rproc_shutdown);
+
+/**
+ * rproc_release() - completely deletes the existence of a remote processor
+ * @kref: the rproc's kref
+ *
+ * This function should _never_ be called directly.
+ *
+ * The only reasonable location to use it is as an argument when kref_put'ing
+ * @rproc's refcount.
+ *
+ * This way it will be called when no one holds a valid pointer to this @rproc
+ * anymore (and obviously after it is removed from the rprocs klist).
+ *
+ * Note: this function is not static because rproc_vdev_release() needs it when
+ * it decrements @rproc's refcount.
+ */
+void rproc_release(struct kref *kref)
+{
+       struct rproc *rproc = container_of(kref, struct rproc, refcount);
+       struct rproc_vdev *rvdev, *rvtmp;
+
+       dev_info(rproc->dev, "removing %s\n", rproc->name);
+
+       rproc_delete_debug_dir(rproc);
+
+       /* clean up remote vdev entries */
+       list_for_each_entry_safe(rvdev, rvtmp, &rproc->rvdevs, node) {
+               __rproc_free_vrings(rvdev, RVDEV_NUM_VRINGS);
+               list_del(&rvdev->node);
+       }
+
+       /*
+        * At this point no one holds a reference to rproc anymore,
+        * so we can directly unroll rproc_alloc()
+        */
+       rproc_free(rproc);
+}
+
+/* will be called when an rproc is added to the rprocs klist */
+static void klist_rproc_get(struct klist_node *n)
+{
+       struct rproc *rproc = container_of(n, struct rproc, node);
+
+       kref_get(&rproc->refcount);
+}
+
+/* will be called when an rproc is removed from the rprocs klist */
+static void klist_rproc_put(struct klist_node *n)
+{
+       struct rproc *rproc = container_of(n, struct rproc, node);
+
+       kref_put(&rproc->refcount, rproc_release);
+}
+
+static struct rproc *next_rproc(struct klist_iter *i)
+{
+       struct klist_node *n;
+
+       n = klist_next(i);
+       if (!n)
+               return NULL;
+
+       return container_of(n, struct rproc, node);
+}
+
+/**
+ * rproc_get_by_name() - find a remote processor by name and boot it
+ * @name: name of the remote processor
+ *
+ * Finds an rproc handle using the remote processor's name, and then
+ * boot it. If it's already powered on, then just immediately return
+ * (successfully).
+ *
+ * Returns the rproc handle on success, and NULL on failure.
+ *
+ * This function increments the remote processor's refcount, so always
+ * use rproc_put() to decrement it back once rproc isn't needed anymore.
+ *
+ * Note: currently this function (and its counterpart rproc_put()) are not
+ * being used. We need to scrutinize the use cases
+ * that still need them, and see if we can migrate them to use the non
+ * name-based boot/shutdown interface.
+ */
+struct rproc *rproc_get_by_name(const char *name)
+{
+       struct rproc *rproc;
+       struct klist_iter i;
+       int ret;
+
+       /* find the remote processor, and upref its refcount */
+       klist_iter_init(&rprocs, &i);
+       while ((rproc = next_rproc(&i)) != NULL)
+               if (!strcmp(rproc->name, name)) {
+                       kref_get(&rproc->refcount);
+                       break;
+               }
+       klist_iter_exit(&i);
+
+       /* can't find this rproc ? */
+       if (!rproc) {
+               pr_err("can't find remote processor %s\n", name);
+               return NULL;
+       }
+
+       ret = rproc_boot(rproc);
+       if (ret < 0) {
+               kref_put(&rproc->refcount, rproc_release);
+               return NULL;
+       }
+
+       return rproc;
+}
+EXPORT_SYMBOL(rproc_get_by_name);
+
+/**
+ * rproc_put() - decrement the refcount of a remote processor, and shut it down
+ * @rproc: the remote processor
+ *
+ * This function tries to shutdown @rproc, and it then decrements its
+ * refcount.
+ *
+ * After this function returns, @rproc may _not_ be used anymore, and its
+ * handle should be considered invalid.
+ *
+ * This function should be called _iff_ the @rproc handle was grabbed by
+ * calling rproc_get_by_name().
+ */
+void rproc_put(struct rproc *rproc)
+{
+       /* try to power off the remote processor */
+       rproc_shutdown(rproc);
+
+       /* downref rproc's refcount */
+       kref_put(&rproc->refcount, rproc_release);
+}
+EXPORT_SYMBOL(rproc_put);
+
+/**
+ * rproc_register() - register a remote processor
+ * @rproc: the remote processor handle to register
+ *
+ * Registers @rproc with the remoteproc framework, after it has been
+ * allocated with rproc_alloc().
+ *
+ * This is called by the platform-specific rproc implementation, whenever
+ * a new remote processor device is probed.
+ *
+ * Returns 0 on success and an appropriate error code otherwise.
+ *
+ * Note: this function initiates an asynchronous firmware loading
+ * context, which will look for virtio devices supported by the rproc's
+ * firmware.
+ *
+ * If found, those virtio devices will be created and added, so as a result
+ * of registering this remote processor, additional virtio drivers might be
+ * probed.
+ */
+int rproc_register(struct rproc *rproc)
+{
+       struct device *dev = rproc->dev;
+       int ret = 0;
+
+       /* expose to rproc_get_by_name users */
+       klist_add_tail(&rproc->node, &rprocs);
+
+       dev_info(rproc->dev, "%s is available\n", rproc->name);
+
+       dev_info(dev, "Note: remoteproc is still under development and considered experimental.\n");
+       dev_info(dev, "THE BINARY FORMAT IS NOT YET FINALIZED, and backward compatibility isn't yet guaranteed.\n");
+
+       /* create debugfs entries */
+       rproc_create_debug_dir(rproc);
+
+       /* rproc_unregister() calls must wait until async loader completes */
+       init_completion(&rproc->firmware_loading_complete);
+
+       /*
+        * We must retrieve early virtio configuration info from
+        * the firmware (e.g. whether to register a virtio device,
+        * what virtio features does it support, ...).
+        *
+        * We're initiating an asynchronous firmware loading, so we can
+        * be built-in kernel code, without hanging the boot process.
+        */
+       ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
+                                       rproc->firmware, dev, GFP_KERNEL,
+                                       rproc, rproc_fw_config_virtio);
+       if (ret < 0) {
+               dev_err(dev, "request_firmware_nowait failed: %d\n", ret);
+               complete_all(&rproc->firmware_loading_complete);
+               klist_remove(&rproc->node);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL(rproc_register);
+
+/**
+ * rproc_alloc() - allocate a remote processor handle
+ * @dev: the underlying device
+ * @name: name of this remote processor
+ * @ops: platform-specific handlers (mainly start/stop)
+ * @firmware: name of firmware file to load
+ * @len: length of private data needed by the rproc driver (in bytes)
+ *
+ * Allocates a new remote processor handle, but does not register
+ * it yet.
+ *
+ * This function should be used by rproc implementations during initialization
+ * of the remote processor.
+ *
+ * After creating an rproc handle using this function, and when ready,
+ * implementations should then call rproc_register() to complete
+ * the registration of the remote processor.
+ *
+ * On success the new rproc is returned, and on failure, NULL.
+ *
+ * Note: _never_ directly deallocate @rproc, even if it was not registered
+ * yet. Instead, if you just need to unroll rproc_alloc(), use rproc_free().
+ */
+struct rproc *rproc_alloc(struct device *dev, const char *name,
+                               const struct rproc_ops *ops,
+                               const char *firmware, int len)
+{
+       struct rproc *rproc;
+
+       if (!dev || !name || !ops)
+               return NULL;
+
+       rproc = kzalloc(sizeof(struct rproc) + len, GFP_KERNEL);
+       if (!rproc) {
+               dev_err(dev, "%s: kzalloc failed\n", __func__);
+               return NULL;
+       }
+
+       rproc->dev = dev;
+       rproc->name = name;
+       rproc->ops = ops;
+       rproc->firmware = firmware;
+       rproc->priv = &rproc[1];
+
+       atomic_set(&rproc->power, 0);
+
+       kref_init(&rproc->refcount);
+
+       mutex_init(&rproc->lock);
+
+       idr_init(&rproc->notifyids);
+
+       INIT_LIST_HEAD(&rproc->carveouts);
+       INIT_LIST_HEAD(&rproc->mappings);
+       INIT_LIST_HEAD(&rproc->traces);
+       INIT_LIST_HEAD(&rproc->rvdevs);
+
+       rproc->state = RPROC_OFFLINE;
+
+       return rproc;
+}
+EXPORT_SYMBOL(rproc_alloc);
+
+/**
+ * rproc_free() - free an rproc handle that was allocated by rproc_alloc
+ * @rproc: the remote processor handle
+ *
+ * This function should _only_ be used if @rproc was only allocated,
+ * but not registered yet.
+ *
+ * If @rproc was already successfully registered (by calling rproc_register()),
+ * then use rproc_unregister() instead.
+ */
+void rproc_free(struct rproc *rproc)
+{
+       idr_remove_all(&rproc->notifyids);
+       idr_destroy(&rproc->notifyids);
+
+       kfree(rproc);
+}
+EXPORT_SYMBOL(rproc_free);
+
+/**
+ * rproc_unregister() - unregister a remote processor
+ * @rproc: rproc handle to unregister
+ *
+ * Unregisters a remote processor, and decrements its refcount.
+ * If its refcount drops to zero, then @rproc will be freed. If not,
+ * it will be freed later once the last reference is dropped.
+ *
+ * This function should be called when the platform specific rproc
+ * implementation decides to remove the rproc device. it should
+ * _only_ be called if a previous invocation of rproc_register()
+ * has completed successfully.
+ *
+ * After rproc_unregister() returns, @rproc is _not_ valid anymore and
+ * it shouldn't be used. More specifically, don't call rproc_free()
+ * or try to directly free @rproc after rproc_unregister() returns;
+ * none of these are needed, and calling them is a bug.
+ *
+ * Returns 0 on success and -EINVAL if @rproc isn't valid.
+ */
+int rproc_unregister(struct rproc *rproc)
+{
+       struct rproc_vdev *rvdev;
+
+       if (!rproc)
+               return -EINVAL;
+
+       /* if rproc is just being registered, wait */
+       wait_for_completion(&rproc->firmware_loading_complete);
+
+       /* clean up remote vdev entries */
+       list_for_each_entry(rvdev, &rproc->rvdevs, node)
+               rproc_remove_virtio_dev(rvdev);
+
+       /* the rproc is downref'ed as soon as it's removed from the klist */
+       klist_del(&rproc->node);
+
+       /* the rproc will only be released after its refcount drops to zero */
+       kref_put(&rproc->refcount, rproc_release);
+
+       return 0;
+}
+EXPORT_SYMBOL(rproc_unregister);
+
+static int __init remoteproc_init(void)
+{
+       rproc_init_debugfs();
+       return 0;
+}
+module_init(remoteproc_init);
+
+static void __exit remoteproc_exit(void)
+{
+       rproc_exit_debugfs();
+}
+module_exit(remoteproc_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Generic Remote Processor Framework");
diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c
new file mode 100644 (file)
index 0000000..70277a5
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Remote Processor Framework
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Mark Grosen <mgrosen@ti.com>
+ * Brian Swetland <swetland@google.com>
+ * Fernando Guzman Lugo <fernando.lugo@ti.com>
+ * Suman Anna <s-anna@ti.com>
+ * Robert Tivy <rtivy@ti.com>
+ * Armando Uribe De Leon <x0095078@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt)    "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/debugfs.h>
+#include <linux/remoteproc.h>
+#include <linux/device.h>
+
+/* remoteproc debugfs parent dir */
+static struct dentry *rproc_dbg;
+
+/*
+ * Some remote processors may support dumping trace logs into a shared
+ * memory buffer. We expose this trace buffer using debugfs, so users
+ * can easily tell what's going on remotely.
+ *
+ * We will most probably improve the rproc tracing facilities later on,
+ * but this kind of lightweight and simple mechanism is always good to have,
+ * as it provides very early tracing with little to no dependencies at all.
+ */
+static ssize_t rproc_trace_read(struct file *filp, char __user *userbuf,
+                                               size_t count, loff_t *ppos)
+{
+       struct rproc_mem_entry *trace = filp->private_data;
+       int len = strnlen(trace->va, trace->len);
+
+       return simple_read_from_buffer(userbuf, count, ppos, trace->va, len);
+}
+
+static int rproc_open_generic(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+
+       return 0;
+}
+
+static const struct file_operations trace_rproc_ops = {
+       .read = rproc_trace_read,
+       .open = rproc_open_generic,
+       .llseek = generic_file_llseek,
+};
+
+/*
+ * A state-to-string lookup table, for exposing a human readable state
+ * via debugfs. Always keep in sync with enum rproc_state
+ */
+static const char * const rproc_state_string[] = {
+       "offline",
+       "suspended",
+       "running",
+       "crashed",
+       "invalid",
+};
+
+/* expose the state of the remote processor via debugfs */
+static ssize_t rproc_state_read(struct file *filp, char __user *userbuf,
+                                               size_t count, loff_t *ppos)
+{
+       struct rproc *rproc = filp->private_data;
+       unsigned int state;
+       char buf[30];
+       int i;
+
+       state = rproc->state > RPROC_LAST ? RPROC_LAST : rproc->state;
+
+       i = snprintf(buf, 30, "%.28s (%d)\n", rproc_state_string[state],
+                                                       rproc->state);
+
+       return simple_read_from_buffer(userbuf, count, ppos, buf, i);
+}
+
+static const struct file_operations rproc_state_ops = {
+       .read = rproc_state_read,
+       .open = rproc_open_generic,
+       .llseek = generic_file_llseek,
+};
+
+/* expose the name of the remote processor via debugfs */
+static ssize_t rproc_name_read(struct file *filp, char __user *userbuf,
+                                               size_t count, loff_t *ppos)
+{
+       struct rproc *rproc = filp->private_data;
+       /* need room for the name, a newline and a terminating null */
+       char buf[100];
+       int i;
+
+       i = snprintf(buf, sizeof(buf), "%.98s\n", rproc->name);
+
+       return simple_read_from_buffer(userbuf, count, ppos, buf, i);
+}
+
+static const struct file_operations rproc_name_ops = {
+       .read = rproc_name_read,
+       .open = rproc_open_generic,
+       .llseek = generic_file_llseek,
+};
+
+void rproc_remove_trace_file(struct dentry *tfile)
+{
+       debugfs_remove(tfile);
+}
+
+struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc,
+                                       struct rproc_mem_entry *trace)
+{
+       struct dentry *tfile;
+
+       tfile = debugfs_create_file(name, 0400, rproc->dbg_dir,
+                                               trace, &trace_rproc_ops);
+       if (!tfile) {
+               dev_err(rproc->dev, "failed to create debugfs trace entry\n");
+               return NULL;
+       }
+
+       return tfile;
+}
+
+void rproc_delete_debug_dir(struct rproc *rproc)
+{
+       if (!rproc->dbg_dir)
+               return;
+
+       debugfs_remove_recursive(rproc->dbg_dir);
+}
+
+void rproc_create_debug_dir(struct rproc *rproc)
+{
+       struct device *dev = rproc->dev;
+
+       if (!rproc_dbg)
+               return;
+
+       rproc->dbg_dir = debugfs_create_dir(dev_name(dev), rproc_dbg);
+       if (!rproc->dbg_dir)
+               return;
+
+       debugfs_create_file("name", 0400, rproc->dbg_dir,
+                                       rproc, &rproc_name_ops);
+       debugfs_create_file("state", 0400, rproc->dbg_dir,
+                                       rproc, &rproc_state_ops);
+}
+
+void __init rproc_init_debugfs(void)
+{
+       if (debugfs_initialized()) {
+               rproc_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL);
+               if (!rproc_dbg)
+                       pr_err("can't create debugfs dir\n");
+       }
+}
+
+void __exit rproc_exit_debugfs(void)
+{
+       if (rproc_dbg)
+               debugfs_remove(rproc_dbg);
+}
diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
new file mode 100644 (file)
index 0000000..9f336d6
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Remote processor framework
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef REMOTEPROC_INTERNAL_H
+#define REMOTEPROC_INTERNAL_H
+
+#include <linux/irqreturn.h>
+
+struct rproc;
+
+/* from remoteproc_core.c */
+void rproc_release(struct kref *kref);
+irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int vq_id);
+
+/* from remoteproc_virtio.c */
+int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id);
+void rproc_remove_virtio_dev(struct rproc_vdev *rvdev);
+
+/* from remoteproc_debugfs.c */
+void rproc_remove_trace_file(struct dentry *tfile);
+struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc,
+                                       struct rproc_mem_entry *trace);
+void rproc_delete_debug_dir(struct rproc *rproc);
+void rproc_create_debug_dir(struct rproc *rproc);
+void rproc_init_debugfs(void);
+void rproc_exit_debugfs(void);
+
+#endif /* REMOTEPROC_INTERNAL_H */
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
new file mode 100644 (file)
index 0000000..ecf6121
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * Remote processor messaging transport (OMAP platform-specific bits)
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/export.h>
+#include <linux/remoteproc.h>
+#include <linux/virtio.h>
+#include <linux/virtio_config.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_ring.h>
+#include <linux/err.h>
+#include <linux/kref.h>
+#include <linux/slab.h>
+
+#include "remoteproc_internal.h"
+
+/* kick the remote processor, and let it know which virtqueue to poke at */
+static void rproc_virtio_notify(struct virtqueue *vq)
+{
+       struct rproc_vring *rvring = vq->priv;
+       struct rproc *rproc = rvring->rvdev->rproc;
+       int notifyid = rvring->notifyid;
+
+       dev_dbg(rproc->dev, "kicking vq index: %d\n", notifyid);
+
+       rproc->ops->kick(rproc, notifyid);
+}
+
+/**
+ * rproc_vq_interrupt() - tell remoteproc that a virtqueue is interrupted
+ * @rproc: handle to the remote processor
+ * @notifyid: index of the signalled virtqueue (unique per this @rproc)
+ *
+ * This function should be called by the platform-specific rproc driver,
+ * when the remote processor signals that a specific virtqueue has pending
+ * messages available.
+ *
+ * Returns IRQ_NONE if no message was found in the @notifyid virtqueue,
+ * and otherwise returns IRQ_HANDLED.
+ */
+irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int notifyid)
+{
+       struct rproc_vring *rvring;
+
+       dev_dbg(rproc->dev, "vq index %d is interrupted\n", notifyid);
+
+       rvring = idr_find(&rproc->notifyids, notifyid);
+       if (!rvring || !rvring->vq)
+               return IRQ_NONE;
+
+       return vring_interrupt(0, rvring->vq);
+}
+EXPORT_SYMBOL(rproc_vq_interrupt);
+
+static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
+                                   unsigned id,
+                                   void (*callback)(struct virtqueue *vq),
+                                   const char *name)
+{
+       struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
+       struct rproc *rproc = vdev_to_rproc(vdev);
+       struct rproc_vring *rvring;
+       struct virtqueue *vq;
+       void *addr;
+       int len, size;
+
+       /* we're temporarily limited to two virtqueues per rvdev */
+       if (id >= ARRAY_SIZE(rvdev->vring))
+               return ERR_PTR(-EINVAL);
+
+       rvring = &rvdev->vring[id];
+
+       addr = rvring->va;
+       len = rvring->len;
+
+       /* zero vring */
+       size = vring_size(len, rvring->align);
+       memset(addr, 0, size);
+
+       dev_dbg(rproc->dev, "vring%d: va %p qsz %d notifyid %d\n",
+                                       id, addr, len, rvring->notifyid);
+
+       /*
+        * Create the new vq, and tell virtio we're not interested in
+        * the 'weak' smp barriers, since we're talking with a real device.
+        */
+       vq = vring_new_virtqueue(len, rvring->align, vdev, false, addr,
+                                       rproc_virtio_notify, callback, name);
+       if (!vq) {
+               dev_err(rproc->dev, "vring_new_virtqueue %s failed\n", name);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       rvring->vq = vq;
+       vq->priv = rvring;
+
+       return vq;
+}
+
+static void rproc_virtio_del_vqs(struct virtio_device *vdev)
+{
+       struct virtqueue *vq, *n;
+       struct rproc *rproc = vdev_to_rproc(vdev);
+       struct rproc_vring *rvring;
+
+       /* power down the remote processor before deleting vqs */
+       rproc_shutdown(rproc);
+
+       list_for_each_entry_safe(vq, n, &vdev->vqs, list) {
+               rvring = vq->priv;
+               rvring->vq = NULL;
+               vring_del_virtqueue(vq);
+       }
+}
+
+static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
+                      struct virtqueue *vqs[],
+                      vq_callback_t *callbacks[],
+                      const char *names[])
+{
+       struct rproc *rproc = vdev_to_rproc(vdev);
+       int i, ret;
+
+       for (i = 0; i < nvqs; ++i) {
+               vqs[i] = rp_find_vq(vdev, i, callbacks[i], names[i]);
+               if (IS_ERR(vqs[i])) {
+                       ret = PTR_ERR(vqs[i]);
+                       goto error;
+               }
+       }
+
+       /* now that the vqs are all set, boot the remote processor */
+       ret = rproc_boot(rproc);
+       if (ret) {
+               dev_err(rproc->dev, "rproc_boot() failed %d\n", ret);
+               goto error;
+       }
+
+       return 0;
+
+error:
+       rproc_virtio_del_vqs(vdev);
+       return ret;
+}
+
+/*
+ * We don't support yet real virtio status semantics.
+ *
+ * The plan is to provide this via the VDEV resource entry
+ * which is part of the firmware: this way the remote processor
+ * will be able to access the status values as set by us.
+ */
+static u8 rproc_virtio_get_status(struct virtio_device *vdev)
+{
+       return 0;
+}
+
+static void rproc_virtio_set_status(struct virtio_device *vdev, u8 status)
+{
+       dev_dbg(&vdev->dev, "status: %d\n", status);
+}
+
+static void rproc_virtio_reset(struct virtio_device *vdev)
+{
+       dev_dbg(&vdev->dev, "reset !\n");
+}
+
+/* provide the vdev features as retrieved from the firmware */
+static u32 rproc_virtio_get_features(struct virtio_device *vdev)
+{
+       struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
+
+       return rvdev->dfeatures;
+}
+
+static void rproc_virtio_finalize_features(struct virtio_device *vdev)
+{
+       struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
+
+       /* Give virtio_ring a chance to accept features */
+       vring_transport_features(vdev);
+
+       /*
+        * Remember the finalized features of our vdev, and provide it
+        * to the remote processor once it is powered on.
+        *
+        * Similarly to the status field, we don't expose yet the negotiated
+        * features to the remote processors at this point. This will be
+        * fixed as part of a small resource table overhaul and then an
+        * extension of the virtio resource entries.
+        */
+       rvdev->gfeatures = vdev->features[0];
+}
+
+static struct virtio_config_ops rproc_virtio_config_ops = {
+       .get_features   = rproc_virtio_get_features,
+       .finalize_features = rproc_virtio_finalize_features,
+       .find_vqs       = rproc_virtio_find_vqs,
+       .del_vqs        = rproc_virtio_del_vqs,
+       .reset          = rproc_virtio_reset,
+       .set_status     = rproc_virtio_set_status,
+       .get_status     = rproc_virtio_get_status,
+};
+
+/*
+ * This function is called whenever vdev is released, and is responsible
+ * to decrement the remote processor's refcount taken when vdev was
+ * added.
+ *
+ * Never call this function directly; it will be called by the driver
+ * core when needed.
+ */
+static void rproc_vdev_release(struct device *dev)
+{
+       struct virtio_device *vdev = dev_to_virtio(dev);
+       struct rproc *rproc = vdev_to_rproc(vdev);
+
+       kref_put(&rproc->refcount, rproc_release);
+}
+
+/**
+ * rproc_add_virtio_dev() - register an rproc-induced virtio device
+ * @rvdev: the remote vdev
+ *
+ * This function registers a virtio device. This vdev's partent is
+ * the rproc device.
+ *
+ * Returns 0 on success or an appropriate error value otherwise.
+ */
+int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id)
+{
+       struct rproc *rproc = rvdev->rproc;
+       struct device *dev = rproc->dev;
+       struct virtio_device *vdev = &rvdev->vdev;
+       int ret;
+
+       vdev->id.device = id,
+       vdev->config = &rproc_virtio_config_ops,
+       vdev->dev.parent = dev;
+       vdev->dev.release = rproc_vdev_release;
+
+       /*
+        * We're indirectly making a non-temporary copy of the rproc pointer
+        * here, because drivers probed with this vdev will indirectly
+        * access the wrapping rproc.
+        *
+        * Therefore we must increment the rproc refcount here, and decrement
+        * it _only_ when the vdev is released.
+        */
+       kref_get(&rproc->refcount);
+
+       ret = register_virtio_device(vdev);
+       if (ret) {
+               kref_put(&rproc->refcount, rproc_release);
+               dev_err(dev, "failed to register vdev: %d\n", ret);
+               goto out;
+       }
+
+       dev_info(dev, "registered %s (type %d)\n", dev_name(&vdev->dev), id);
+
+out:
+       return ret;
+}
+
+/**
+ * rproc_remove_virtio_dev() - remove an rproc-induced virtio device
+ * @rvdev: the remote vdev
+ *
+ * This function unregisters an existing virtio device.
+ */
+void rproc_remove_virtio_dev(struct rproc_vdev *rvdev)
+{
+       unregister_virtio_device(&rvdev->vdev);
+}
diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
new file mode 100644 (file)
index 0000000..32aead6
--- /dev/null
@@ -0,0 +1,10 @@
+menu "Rpmsg drivers (EXPERIMENTAL)"
+
+# RPMSG always gets selected by whoever wants it
+config RPMSG
+       tristate
+       select VIRTIO
+       select VIRTIO_RING
+       depends on EXPERIMENTAL
+
+endmenu
diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile
new file mode 100644 (file)
index 0000000..7617fcb
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_RPMSG)    += virtio_rpmsg_bus.o
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
new file mode 100644 (file)
index 0000000..75506ec
--- /dev/null
@@ -0,0 +1,1054 @@
+/*
+ * Virtio-based remote processor messaging bus
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/virtio.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_config.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/idr.h>
+#include <linux/jiffies.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/rpmsg.h>
+#include <linux/mutex.h>
+
+/**
+ * struct virtproc_info - virtual remote processor state
+ * @vdev:      the virtio device
+ * @rvq:       rx virtqueue
+ * @svq:       tx virtqueue
+ * @rbufs:     kernel address of rx buffers
+ * @sbufs:     kernel address of tx buffers
+ * @last_sbuf: index of last tx buffer used
+ * @bufs_dma:  dma base addr of the buffers
+ * @tx_lock:   protects svq, sbufs and sleepers, to allow concurrent senders.
+ *             sending a message might require waking up a dozing remote
+ *             processor, which involves sleeping, hence the mutex.
+ * @endpoints: idr of local endpoints, allows fast retrieval
+ * @endpoints_lock: lock of the endpoints set
+ * @sendq:     wait queue of sending contexts waiting for a tx buffers
+ * @sleepers:  number of senders that are waiting for a tx buffer
+ * @ns_ept:    the bus's name service endpoint
+ *
+ * This structure stores the rpmsg state of a given virtio remote processor
+ * device (there might be several virtio proc devices for each physical
+ * remote processor).
+ */
+struct virtproc_info {
+       struct virtio_device *vdev;
+       struct virtqueue *rvq, *svq;
+       void *rbufs, *sbufs;
+       int last_sbuf;
+       dma_addr_t bufs_dma;
+       struct mutex tx_lock;
+       struct idr endpoints;
+       struct mutex endpoints_lock;
+       wait_queue_head_t sendq;
+       atomic_t sleepers;
+       struct rpmsg_endpoint *ns_ept;
+};
+
+/**
+ * struct rpmsg_channel_info - internal channel info representation
+ * @name: name of service
+ * @src: local address
+ * @dst: destination address
+ */
+struct rpmsg_channel_info {
+       char name[RPMSG_NAME_SIZE];
+       u32 src;
+       u32 dst;
+};
+
+#define to_rpmsg_channel(d) container_of(d, struct rpmsg_channel, dev)
+#define to_rpmsg_driver(d) container_of(d, struct rpmsg_driver, drv)
+
+/*
+ * We're allocating 512 buffers of 512 bytes for communications, and then
+ * using the first 256 buffers for RX, and the last 256 buffers for TX.
+ *
+ * Each buffer will have 16 bytes for the msg header and 496 bytes for
+ * the payload.
+ *
+ * This will require a total space of 256KB for the buffers.
+ *
+ * We might also want to add support for user-provided buffers in time.
+ * This will allow bigger buffer size flexibility, and can also be used
+ * to achieve zero-copy messaging.
+ *
+ * Note that these numbers are purely a decision of this driver - we
+ * can change this without changing anything in the firmware of the remote
+ * processor.
+ */
+#define RPMSG_NUM_BUFS         (512)
+#define RPMSG_BUF_SIZE         (512)
+#define RPMSG_TOTAL_BUF_SPACE  (RPMSG_NUM_BUFS * RPMSG_BUF_SIZE)
+
+/*
+ * Local addresses are dynamically allocated on-demand.
+ * We do not dynamically assign addresses from the low 1024 range,
+ * in order to reserve that address range for predefined services.
+ */
+#define RPMSG_RESERVED_ADDRESSES       (1024)
+
+/* Address 53 is reserved for advertising remote services */
+#define RPMSG_NS_ADDR                  (53)
+
+/* sysfs show configuration fields */
+#define rpmsg_show_attr(field, path, format_string)                    \
+static ssize_t                                                         \
+field##_show(struct device *dev,                                       \
+                       struct device_attribute *attr, char *buf)       \
+{                                                                      \
+       struct rpmsg_channel *rpdev = to_rpmsg_channel(dev);            \
+                                                                       \
+       return sprintf(buf, format_string, rpdev->path);                \
+}
+
+/* for more info, see Documentation/ABI/testing/sysfs-bus-rpmsg */
+rpmsg_show_attr(name, id.name, "%s\n");
+rpmsg_show_attr(src, src, "0x%x\n");
+rpmsg_show_attr(dst, dst, "0x%x\n");
+rpmsg_show_attr(announce, announce ? "true" : "false", "%s\n");
+
+/*
+ * Unique (and free running) index for rpmsg devices.
+ *
+ * Yeah, we're not recycling those numbers (yet?). will be easy
+ * to change if/when we want to.
+ */
+static unsigned int rpmsg_dev_index;
+
+static ssize_t modalias_show(struct device *dev,
+                            struct device_attribute *attr, char *buf)
+{
+       struct rpmsg_channel *rpdev = to_rpmsg_channel(dev);
+
+       return sprintf(buf, RPMSG_DEVICE_MODALIAS_FMT "\n", rpdev->id.name);
+}
+
+static struct device_attribute rpmsg_dev_attrs[] = {
+       __ATTR_RO(name),
+       __ATTR_RO(modalias),
+       __ATTR_RO(dst),
+       __ATTR_RO(src),
+       __ATTR_RO(announce),
+       __ATTR_NULL
+};
+
+/* rpmsg devices and drivers are matched using the service name */
+static inline int rpmsg_id_match(const struct rpmsg_channel *rpdev,
+                                 const struct rpmsg_device_id *id)
+{
+       return strncmp(id->name, rpdev->id.name, RPMSG_NAME_SIZE) == 0;
+}
+
+/* match rpmsg channel and rpmsg driver */
+static int rpmsg_dev_match(struct device *dev, struct device_driver *drv)
+{
+       struct rpmsg_channel *rpdev = to_rpmsg_channel(dev);
+       struct rpmsg_driver *rpdrv = to_rpmsg_driver(drv);
+       const struct rpmsg_device_id *ids = rpdrv->id_table;
+       unsigned int i;
+
+       for (i = 0; ids[i].name[0]; i++)
+               if (rpmsg_id_match(rpdev, &ids[i]))
+                       return 1;
+
+       return 0;
+}
+
+static int rpmsg_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+       struct rpmsg_channel *rpdev = to_rpmsg_channel(dev);
+
+       return add_uevent_var(env, "MODALIAS=" RPMSG_DEVICE_MODALIAS_FMT,
+                                       rpdev->id.name);
+}
+
+/* for more info, see below documentation of rpmsg_create_ept() */
+static struct rpmsg_endpoint *__rpmsg_create_ept(struct virtproc_info *vrp,
+               struct rpmsg_channel *rpdev, rpmsg_rx_cb_t cb,
+               void *priv, u32 addr)
+{
+       int err, tmpaddr, request;
+       struct rpmsg_endpoint *ept;
+       struct device *dev = rpdev ? &rpdev->dev : &vrp->vdev->dev;
+
+       if (!idr_pre_get(&vrp->endpoints, GFP_KERNEL))
+               return NULL;
+
+       ept = kzalloc(sizeof(*ept), GFP_KERNEL);
+       if (!ept) {
+               dev_err(dev, "failed to kzalloc a new ept\n");
+               return NULL;
+       }
+
+       ept->rpdev = rpdev;
+       ept->cb = cb;
+       ept->priv = priv;
+
+       /* do we need to allocate a local address ? */
+       request = addr == RPMSG_ADDR_ANY ? RPMSG_RESERVED_ADDRESSES : addr;
+
+       mutex_lock(&vrp->endpoints_lock);
+
+       /* bind the endpoint to an rpmsg address (and allocate one if needed) */
+       err = idr_get_new_above(&vrp->endpoints, ept, request, &tmpaddr);
+       if (err) {
+               dev_err(dev, "idr_get_new_above failed: %d\n", err);
+               goto free_ept;
+       }
+
+       /* make sure the user's address request is fulfilled, if relevant */
+       if (addr != RPMSG_ADDR_ANY && tmpaddr != addr) {
+               dev_err(dev, "address 0x%x already in use\n", addr);
+               goto rem_idr;
+       }
+
+       ept->addr = tmpaddr;
+
+       mutex_unlock(&vrp->endpoints_lock);
+
+       return ept;
+
+rem_idr:
+       idr_remove(&vrp->endpoints, request);
+free_ept:
+       mutex_unlock(&vrp->endpoints_lock);
+       kfree(ept);
+       return NULL;
+}
+
+/**
+ * rpmsg_create_ept() - create a new rpmsg_endpoint
+ * @rpdev: rpmsg channel device
+ * @cb: rx callback handler
+ * @priv: private data for the driver's use
+ * @addr: local rpmsg address to bind with @cb
+ *
+ * Every rpmsg address in the system is bound to an rx callback (so when
+ * inbound messages arrive, they are dispatched by the rpmsg bus using the
+ * appropriate callback handler) by means of an rpmsg_endpoint struct.
+ *
+ * This function allows drivers to create such an endpoint, and by that,
+ * bind a callback, and possibly some private data too, to an rpmsg address
+ * (either one that is known in advance, or one that will be dynamically
+ * assigned for them).
+ *
+ * Simple rpmsg drivers need not call rpmsg_create_ept, because an endpoint
+ * is already created for them when they are probed by the rpmsg bus
+ * (using the rx callback provided when they registered to the rpmsg bus).
+ *
+ * So things should just work for simple drivers: they already have an
+ * endpoint, their rx callback is bound to their rpmsg address, and when
+ * relevant inbound messages arrive (i.e. messages which their dst address
+ * equals to the src address of their rpmsg channel), the driver's handler
+ * is invoked to process it.
+ *
+ * That said, more complicated drivers might do need to allocate
+ * additional rpmsg addresses, and bind them to different rx callbacks.
+ * To accomplish that, those drivers need to call this function.
+ *
+ * Drivers should provide their @rpdev channel (so the new endpoint would belong
+ * to the same remote processor their channel belongs to), an rx callback
+ * function, an optional private data (which is provided back when the
+ * rx callback is invoked), and an address they want to bind with the
+ * callback. If @addr is RPMSG_ADDR_ANY, then rpmsg_create_ept will
+ * dynamically assign them an available rpmsg address (drivers should have
+ * a very good reason why not to always use RPMSG_ADDR_ANY here).
+ *
+ * Returns a pointer to the endpoint on success, or NULL on error.
+ */
+struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *rpdev,
+                               rpmsg_rx_cb_t cb, void *priv, u32 addr)
+{
+       return __rpmsg_create_ept(rpdev->vrp, rpdev, cb, priv, addr);
+}
+EXPORT_SYMBOL(rpmsg_create_ept);
+
+/**
+ * __rpmsg_destroy_ept() - destroy an existing rpmsg endpoint
+ * @vrp: virtproc which owns this ept
+ * @ept: endpoing to destroy
+ *
+ * An internal function which destroy an ept without assuming it is
+ * bound to an rpmsg channel. This is needed for handling the internal
+ * name service endpoint, which isn't bound to an rpmsg channel.
+ * See also __rpmsg_create_ept().
+ */
+static void
+__rpmsg_destroy_ept(struct virtproc_info *vrp, struct rpmsg_endpoint *ept)
+{
+       mutex_lock(&vrp->endpoints_lock);
+       idr_remove(&vrp->endpoints, ept->addr);
+       mutex_unlock(&vrp->endpoints_lock);
+
+       kfree(ept);
+}
+
+/**
+ * rpmsg_destroy_ept() - destroy an existing rpmsg endpoint
+ * @ept: endpoing to destroy
+ *
+ * Should be used by drivers to destroy an rpmsg endpoint previously
+ * created with rpmsg_create_ept().
+ */
+void rpmsg_destroy_ept(struct rpmsg_endpoint *ept)
+{
+       __rpmsg_destroy_ept(ept->rpdev->vrp, ept);
+}
+EXPORT_SYMBOL(rpmsg_destroy_ept);
+
+/*
+ * when an rpmsg driver is probed with a channel, we seamlessly create
+ * it an endpoint, binding its rx callback to a unique local rpmsg
+ * address.
+ *
+ * if we need to, we also announce about this channel to the remote
+ * processor (needed in case the driver is exposing an rpmsg service).
+ */
+static int rpmsg_dev_probe(struct device *dev)
+{
+       struct rpmsg_channel *rpdev = to_rpmsg_channel(dev);
+       struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver);
+       struct virtproc_info *vrp = rpdev->vrp;
+       struct rpmsg_endpoint *ept;
+       int err;
+
+       ept = rpmsg_create_ept(rpdev, rpdrv->callback, NULL, rpdev->src);
+       if (!ept) {
+               dev_err(dev, "failed to create endpoint\n");
+               err = -ENOMEM;
+               goto out;
+       }
+
+       rpdev->ept = ept;
+       rpdev->src = ept->addr;
+
+       err = rpdrv->probe(rpdev);
+       if (err) {
+               dev_err(dev, "%s: failed: %d\n", __func__, err);
+               rpmsg_destroy_ept(ept);
+               goto out;
+       }
+
+       /* need to tell remote processor's name service about this channel ? */
+       if (rpdev->announce &&
+                       virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) {
+               struct rpmsg_ns_msg nsm;
+
+               strncpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
+               nsm.addr = rpdev->src;
+               nsm.flags = RPMSG_NS_CREATE;
+
+               err = rpmsg_sendto(rpdev, &nsm, sizeof(nsm), RPMSG_NS_ADDR);
+               if (err)
+                       dev_err(dev, "failed to announce service %d\n", err);
+       }
+
+out:
+       return err;
+}
+
+static int rpmsg_dev_remove(struct device *dev)
+{
+       struct rpmsg_channel *rpdev = to_rpmsg_channel(dev);
+       struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver);
+       struct virtproc_info *vrp = rpdev->vrp;
+       int err = 0;
+
+       /* tell remote processor's name service we're removing this channel */
+       if (rpdev->announce &&
+                       virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) {
+               struct rpmsg_ns_msg nsm;
+
+               strncpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
+               nsm.addr = rpdev->src;
+               nsm.flags = RPMSG_NS_DESTROY;
+
+               err = rpmsg_sendto(rpdev, &nsm, sizeof(nsm), RPMSG_NS_ADDR);
+               if (err)
+                       dev_err(dev, "failed to announce service %d\n", err);
+       }
+
+       rpdrv->remove(rpdev);
+
+       rpmsg_destroy_ept(rpdev->ept);
+
+       return err;
+}
+
+static struct bus_type rpmsg_bus = {
+       .name           = "rpmsg",
+       .match          = rpmsg_dev_match,
+       .dev_attrs      = rpmsg_dev_attrs,
+       .uevent         = rpmsg_uevent,
+       .probe          = rpmsg_dev_probe,
+       .remove         = rpmsg_dev_remove,
+};
+
+/**
+ * register_rpmsg_driver() - register an rpmsg driver with the rpmsg bus
+ * @rpdrv: pointer to a struct rpmsg_driver
+ *
+ * Returns 0 on success, and an appropriate error value on failure.
+ */
+int register_rpmsg_driver(struct rpmsg_driver *rpdrv)
+{
+       rpdrv->drv.bus = &rpmsg_bus;
+       return driver_register(&rpdrv->drv);
+}
+EXPORT_SYMBOL(register_rpmsg_driver);
+
+/**
+ * unregister_rpmsg_driver() - unregister an rpmsg driver from the rpmsg bus
+ * @rpdrv: pointer to a struct rpmsg_driver
+ *
+ * Returns 0 on success, and an appropriate error value on failure.
+ */
+void unregister_rpmsg_driver(struct rpmsg_driver *rpdrv)
+{
+       driver_unregister(&rpdrv->drv);
+}
+EXPORT_SYMBOL(unregister_rpmsg_driver);
+
+static void rpmsg_release_device(struct device *dev)
+{
+       struct rpmsg_channel *rpdev = to_rpmsg_channel(dev);
+
+       kfree(rpdev);
+}
+
+/*
+ * match an rpmsg channel with a channel info struct.
+ * this is used to make sure we're not creating rpmsg devices for channels
+ * that already exist.
+ */
+static int rpmsg_channel_match(struct device *dev, void *data)
+{
+       struct rpmsg_channel_info *chinfo = data;
+       struct rpmsg_channel *rpdev = to_rpmsg_channel(dev);
+
+       if (chinfo->src != RPMSG_ADDR_ANY && chinfo->src != rpdev->src)
+               return 0;
+
+       if (chinfo->dst != RPMSG_ADDR_ANY && chinfo->dst != rpdev->dst)
+               return 0;
+
+       if (strncmp(chinfo->name, rpdev->id.name, RPMSG_NAME_SIZE))
+               return 0;
+
+       /* found a match ! */
+       return 1;
+}
+
+/*
+ * create an rpmsg channel using its name and address info.
+ * this function will be used to create both static and dynamic
+ * channels.
+ */
+static struct rpmsg_channel *rpmsg_create_channel(struct virtproc_info *vrp,
+                               struct rpmsg_channel_info *chinfo)
+{
+       struct rpmsg_channel *rpdev;
+       struct device *tmp, *dev = &vrp->vdev->dev;
+       int ret;
+
+       /* make sure a similar channel doesn't already exist */
+       tmp = device_find_child(dev, chinfo, rpmsg_channel_match);
+       if (tmp) {
+               /* decrement the matched device's refcount back */
+               put_device(tmp);
+               dev_err(dev, "channel %s:%x:%x already exist\n",
+                               chinfo->name, chinfo->src, chinfo->dst);
+               return NULL;
+       }
+
+       rpdev = kzalloc(sizeof(struct rpmsg_channel), GFP_KERNEL);
+       if (!rpdev) {
+               pr_err("kzalloc failed\n");
+               return NULL;
+       }
+
+       rpdev->vrp = vrp;
+       rpdev->src = chinfo->src;
+       rpdev->dst = chinfo->dst;
+
+       /*
+        * rpmsg server channels has predefined local address (for now),
+        * and their existence needs to be announced remotely
+        */
+       rpdev->announce = rpdev->src != RPMSG_ADDR_ANY ? true : false;
+
+       strncpy(rpdev->id.name, chinfo->name, RPMSG_NAME_SIZE);
+
+       /* very simple device indexing plumbing which is enough for now */
+       dev_set_name(&rpdev->dev, "rpmsg%d", rpmsg_dev_index++);
+
+       rpdev->dev.parent = &vrp->vdev->dev;
+       rpdev->dev.bus = &rpmsg_bus;
+       rpdev->dev.release = rpmsg_release_device;
+
+       ret = device_register(&rpdev->dev);
+       if (ret) {
+               dev_err(dev, "device_register failed: %d\n", ret);
+               put_device(&rpdev->dev);
+               return NULL;
+       }
+
+       return rpdev;
+}
+
+/*
+ * find an existing channel using its name + address properties,
+ * and destroy it
+ */
+static int rpmsg_destroy_channel(struct virtproc_info *vrp,
+                                       struct rpmsg_channel_info *chinfo)
+{
+       struct virtio_device *vdev = vrp->vdev;
+       struct device *dev;
+
+       dev = device_find_child(&vdev->dev, chinfo, rpmsg_channel_match);
+       if (!dev)
+               return -EINVAL;
+
+       device_unregister(dev);
+
+       put_device(dev);
+
+       return 0;
+}
+
+/* super simple buffer "allocator" that is just enough for now */
+static void *get_a_tx_buf(struct virtproc_info *vrp)
+{
+       unsigned int len;
+       void *ret;
+
+       /* support multiple concurrent senders */
+       mutex_lock(&vrp->tx_lock);
+
+       /*
+        * either pick the next unused tx buffer
+        * (half of our buffers are used for sending messages)
+        */
+       if (vrp->last_sbuf < RPMSG_NUM_BUFS / 2)
+               ret = vrp->sbufs + RPMSG_BUF_SIZE * vrp->last_sbuf++;
+       /* or recycle a used one */
+       else
+               ret = virtqueue_get_buf(vrp->svq, &len);
+
+       mutex_unlock(&vrp->tx_lock);
+
+       return ret;
+}
+
+/**
+ * rpmsg_upref_sleepers() - enable "tx-complete" interrupts, if needed
+ * @vrp: virtual remote processor state
+ *
+ * This function is called before a sender is blocked, waiting for
+ * a tx buffer to become available.
+ *
+ * If we already have blocking senders, this function merely increases
+ * the "sleepers" reference count, and exits.
+ *
+ * Otherwise, if this is the first sender to block, we also enable
+ * virtio's tx callbacks, so we'd be immediately notified when a tx
+ * buffer is consumed (we rely on virtio's tx callback in order
+ * to wake up sleeping senders as soon as a tx buffer is used by the
+ * remote processor).
+ */
+static void rpmsg_upref_sleepers(struct virtproc_info *vrp)
+{
+       /* support multiple concurrent senders */
+       mutex_lock(&vrp->tx_lock);
+
+       /* are we the first sleeping context waiting for tx buffers ? */
+       if (atomic_inc_return(&vrp->sleepers) == 1)
+               /* enable "tx-complete" interrupts before dozing off */
+               virtqueue_enable_cb(vrp->svq);
+
+       mutex_unlock(&vrp->tx_lock);
+}
+
+/**
+ * rpmsg_downref_sleepers() - disable "tx-complete" interrupts, if needed
+ * @vrp: virtual remote processor state
+ *
+ * This function is called after a sender, that waited for a tx buffer
+ * to become available, is unblocked.
+ *
+ * If we still have blocking senders, this function merely decreases
+ * the "sleepers" reference count, and exits.
+ *
+ * Otherwise, if there are no more blocking senders, we also disable
+ * virtio's tx callbacks, to avoid the overhead incurred with handling
+ * those (now redundant) interrupts.
+ */
+static void rpmsg_downref_sleepers(struct virtproc_info *vrp)
+{
+       /* support multiple concurrent senders */
+       mutex_lock(&vrp->tx_lock);
+
+       /* are we the last sleeping context waiting for tx buffers ? */
+       if (atomic_dec_and_test(&vrp->sleepers))
+               /* disable "tx-complete" interrupts */
+               virtqueue_disable_cb(vrp->svq);
+
+       mutex_unlock(&vrp->tx_lock);
+}
+
+/**
+ * rpmsg_send_offchannel_raw() - send a message across to the remote processor
+ * @rpdev: the rpmsg channel
+ * @src: source address
+ * @dst: destination address
+ * @data: payload of message
+ * @len: length of payload
+ * @wait: indicates whether caller should block in case no TX buffers available
+ *
+ * This function is the base implementation for all of the rpmsg sending API.
+ *
+ * It will send @data of length @len to @dst, and say it's from @src. The
+ * message will be sent to the remote processor which the @rpdev channel
+ * belongs to.
+ *
+ * The message is sent using one of the TX buffers that are available for
+ * communication with this remote processor.
+ *
+ * If @wait is true, the caller will be blocked until either a TX buffer is
+ * available, or 15 seconds elapses (we don't want callers to
+ * sleep indefinitely due to misbehaving remote processors), and in that
+ * case -ERESTARTSYS is returned. The number '15' itself was picked
+ * arbitrarily; there's little point in asking drivers to provide a timeout
+ * value themselves.
+ *
+ * Otherwise, if @wait is false, and there are no TX buffers available,
+ * the function will immediately fail, and -ENOMEM will be returned.
+ *
+ * Normally drivers shouldn't use this function directly; instead, drivers
+ * should use the appropriate rpmsg_{try}send{to, _offchannel} API
+ * (see include/linux/rpmsg.h).
+ *
+ * Returns 0 on success and an appropriate error value on failure.
+ */
+int rpmsg_send_offchannel_raw(struct rpmsg_channel *rpdev, u32 src, u32 dst,
+                                       void *data, int len, bool wait)
+{
+       struct virtproc_info *vrp = rpdev->vrp;
+       struct device *dev = &rpdev->dev;
+       struct scatterlist sg;
+       struct rpmsg_hdr *msg;
+       int err;
+
+       /* bcasting isn't allowed */
+       if (src == RPMSG_ADDR_ANY || dst == RPMSG_ADDR_ANY) {
+               dev_err(dev, "invalid addr (src 0x%x, dst 0x%x)\n", src, dst);
+               return -EINVAL;
+       }
+
+       /*
+        * We currently use fixed-sized buffers, and therefore the payload
+        * length is limited.
+        *
+        * One of the possible improvements here is either to support
+        * user-provided buffers (and then we can also support zero-copy
+        * messaging), or to improve the buffer allocator, to support
+        * variable-length buffer sizes.
+        */
+       if (len > RPMSG_BUF_SIZE - sizeof(struct rpmsg_hdr)) {
+               dev_err(dev, "message is too big (%d)\n", len);
+               return -EMSGSIZE;
+       }
+
+       /* grab a buffer */
+       msg = get_a_tx_buf(vrp);
+       if (!msg && !wait)
+               return -ENOMEM;
+
+       /* no free buffer ? wait for one (but bail after 15 seconds) */
+       while (!msg) {
+               /* enable "tx-complete" interrupts, if not already enabled */
+               rpmsg_upref_sleepers(vrp);
+
+               /*
+                * sleep until a free buffer is available or 15 secs elapse.
+                * the timeout period is not configurable because there's
+                * little point in asking drivers to specify that.
+                * if later this happens to be required, it'd be easy to add.
+                */
+               err = wait_event_interruptible_timeout(vrp->sendq,
+                                       (msg = get_a_tx_buf(vrp)),
+                                       msecs_to_jiffies(15000));
+
+               /* disable "tx-complete" interrupts if we're the last sleeper */
+               rpmsg_downref_sleepers(vrp);
+
+               /* timeout ? */
+               if (!err) {
+                       dev_err(dev, "timeout waiting for a tx buffer\n");
+                       return -ERESTARTSYS;
+               }
+       }
+
+       msg->len = len;
+       msg->flags = 0;
+       msg->src = src;
+       msg->dst = dst;
+       msg->reserved = 0;
+       memcpy(msg->data, data, len);
+
+       dev_dbg(dev, "TX From 0x%x, To 0x%x, Len %d, Flags %d, Reserved %d\n",
+                                       msg->src, msg->dst, msg->len,
+                                       msg->flags, msg->reserved);
+       print_hex_dump(KERN_DEBUG, "rpmsg_virtio TX: ", DUMP_PREFIX_NONE, 16, 1,
+                                       msg, sizeof(*msg) + msg->len, true);
+
+       sg_init_one(&sg, msg, sizeof(*msg) + len);
+
+       mutex_lock(&vrp->tx_lock);
+
+       /* add message to the remote processor's virtqueue */
+       err = virtqueue_add_buf(vrp->svq, &sg, 1, 0, msg, GFP_KERNEL);
+       if (err < 0) {
+               /*
+                * need to reclaim the buffer here, otherwise it's lost
+                * (memory won't leak, but rpmsg won't use it again for TX).
+                * this will wait for a buffer management overhaul.
+                */
+               dev_err(dev, "virtqueue_add_buf failed: %d\n", err);
+               goto out;
+       }
+
+       /* tell the remote processor it has a pending message to read */
+       virtqueue_kick(vrp->svq);
+
+       err = 0;
+out:
+       mutex_unlock(&vrp->tx_lock);
+       return err;
+}
+EXPORT_SYMBOL(rpmsg_send_offchannel_raw);
+
+/* called when an rx buffer is used, and it's time to digest a message */
+static void rpmsg_recv_done(struct virtqueue *rvq)
+{
+       struct rpmsg_hdr *msg;
+       unsigned int len;
+       struct rpmsg_endpoint *ept;
+       struct scatterlist sg;
+       struct virtproc_info *vrp = rvq->vdev->priv;
+       struct device *dev = &rvq->vdev->dev;
+       int err;
+
+       msg = virtqueue_get_buf(rvq, &len);
+       if (!msg) {
+               dev_err(dev, "uhm, incoming signal, but no used buffer ?\n");
+               return;
+       }
+
+       dev_dbg(dev, "From: 0x%x, To: 0x%x, Len: %d, Flags: %d, Reserved: %d\n",
+                                       msg->src, msg->dst, msg->len,
+                                       msg->flags, msg->reserved);
+       print_hex_dump(KERN_DEBUG, "rpmsg_virtio RX: ", DUMP_PREFIX_NONE, 16, 1,
+                                       msg, sizeof(*msg) + msg->len, true);
+
+       /*
+        * We currently use fixed-sized buffers, so trivially sanitize
+        * the reported payload length.
+        */
+       if (len > RPMSG_BUF_SIZE ||
+               msg->len > (len - sizeof(struct rpmsg_hdr))) {
+               dev_warn(dev, "inbound msg too big: (%d, %d)\n", len, msg->len);
+               return;
+       }
+
+       /* use the dst addr to fetch the callback of the appropriate user */
+       mutex_lock(&vrp->endpoints_lock);
+       ept = idr_find(&vrp->endpoints, msg->dst);
+       mutex_unlock(&vrp->endpoints_lock);
+
+       if (ept && ept->cb)
+               ept->cb(ept->rpdev, msg->data, msg->len, ept->priv, msg->src);
+       else
+               dev_warn(dev, "msg received with no recepient\n");
+
+       /* publish the real size of the buffer */
+       sg_init_one(&sg, msg, RPMSG_BUF_SIZE);
+
+       /* add the buffer back to the remote processor's virtqueue */
+       err = virtqueue_add_buf(vrp->rvq, &sg, 0, 1, msg, GFP_KERNEL);
+       if (err < 0) {
+               dev_err(dev, "failed to add a virtqueue buffer: %d\n", err);
+               return;
+       }
+
+       /* tell the remote processor we added another available rx buffer */
+       virtqueue_kick(vrp->rvq);
+}
+
+/*
+ * This is invoked whenever the remote processor completed processing
+ * a TX msg we just sent it, and the buffer is put back to the used ring.
+ *
+ * Normally, though, we suppress this "tx complete" interrupt in order to
+ * avoid the incurred overhead.
+ */
+static void rpmsg_xmit_done(struct virtqueue *svq)
+{
+       struct virtproc_info *vrp = svq->vdev->priv;
+
+       dev_dbg(&svq->vdev->dev, "%s\n", __func__);
+
+       /* wake up potential senders that are waiting for a tx buffer */
+       wake_up_interruptible(&vrp->sendq);
+}
+
+/* invoked when a name service announcement arrives */
+static void rpmsg_ns_cb(struct rpmsg_channel *rpdev, void *data, int len,
+                                                       void *priv, u32 src)
+{
+       struct rpmsg_ns_msg *msg = data;
+       struct rpmsg_channel *newch;
+       struct rpmsg_channel_info chinfo;
+       struct virtproc_info *vrp = priv;
+       struct device *dev = &vrp->vdev->dev;
+       int ret;
+
+       print_hex_dump(KERN_DEBUG, "NS announcement: ",
+                       DUMP_PREFIX_NONE, 16, 1,
+                       data, len, true);
+
+       if (len != sizeof(*msg)) {
+               dev_err(dev, "malformed ns msg (%d)\n", len);
+               return;
+       }
+
+       /*
+        * the name service ept does _not_ belong to a real rpmsg channel,
+        * and is handled by the rpmsg bus itself.
+        * for sanity reasons, make sure a valid rpdev has _not_ sneaked
+        * in somehow.
+        */
+       if (rpdev) {
+               dev_err(dev, "anomaly: ns ept has an rpdev handle\n");
+               return;
+       }
+
+       /* don't trust the remote processor for null terminating the name */
+       msg->name[RPMSG_NAME_SIZE - 1] = '\0';
+
+       dev_info(dev, "%sing channel %s addr 0x%x\n",
+                       msg->flags & RPMSG_NS_DESTROY ? "destroy" : "creat",
+                       msg->name, msg->addr);
+
+       strncpy(chinfo.name, msg->name, sizeof(chinfo.name));
+       chinfo.src = RPMSG_ADDR_ANY;
+       chinfo.dst = msg->addr;
+
+       if (msg->flags & RPMSG_NS_DESTROY) {
+               ret = rpmsg_destroy_channel(vrp, &chinfo);
+               if (ret)
+                       dev_err(dev, "rpmsg_destroy_channel failed: %d\n", ret);
+       } else {
+               newch = rpmsg_create_channel(vrp, &chinfo);
+               if (!newch)
+                       dev_err(dev, "rpmsg_create_channel failed\n");
+       }
+}
+
+static int rpmsg_probe(struct virtio_device *vdev)
+{
+       vq_callback_t *vq_cbs[] = { rpmsg_recv_done, rpmsg_xmit_done };
+       const char *names[] = { "input", "output" };
+       struct virtqueue *vqs[2];
+       struct virtproc_info *vrp;
+       void *bufs_va;
+       int err = 0, i;
+
+       vrp = kzalloc(sizeof(*vrp), GFP_KERNEL);
+       if (!vrp)
+               return -ENOMEM;
+
+       vrp->vdev = vdev;
+
+       idr_init(&vrp->endpoints);
+       mutex_init(&vrp->endpoints_lock);
+       mutex_init(&vrp->tx_lock);
+       init_waitqueue_head(&vrp->sendq);
+
+       /* We expect two virtqueues, rx and tx (and in this order) */
+       err = vdev->config->find_vqs(vdev, 2, vqs, vq_cbs, names);
+       if (err)
+               goto free_vrp;
+
+       vrp->rvq = vqs[0];
+       vrp->svq = vqs[1];
+
+       /* allocate coherent memory for the buffers */
+       bufs_va = dma_alloc_coherent(vdev->dev.parent, RPMSG_TOTAL_BUF_SPACE,
+                               &vrp->bufs_dma, GFP_KERNEL);
+       if (!bufs_va)
+               goto vqs_del;
+
+       dev_dbg(&vdev->dev, "buffers: va %p, dma 0x%llx\n", bufs_va,
+                                       (unsigned long long)vrp->bufs_dma);
+
+       /* half of the buffers is dedicated for RX */
+       vrp->rbufs = bufs_va;
+
+       /* and half is dedicated for TX */
+       vrp->sbufs = bufs_va + RPMSG_TOTAL_BUF_SPACE / 2;
+
+       /* set up the receive buffers */
+       for (i = 0; i < RPMSG_NUM_BUFS / 2; i++) {
+               struct scatterlist sg;
+               void *cpu_addr = vrp->rbufs + i * RPMSG_BUF_SIZE;
+
+               sg_init_one(&sg, cpu_addr, RPMSG_BUF_SIZE);
+
+               err = virtqueue_add_buf(vrp->rvq, &sg, 0, 1, cpu_addr,
+                                                               GFP_KERNEL);
+               WARN_ON(err < 0); /* sanity check; this can't really happen */
+       }
+
+       /* suppress "tx-complete" interrupts */
+       virtqueue_disable_cb(vrp->svq);
+
+       vdev->priv = vrp;
+
+       /* if supported by the remote processor, enable the name service */
+       if (virtio_has_feature(vdev, VIRTIO_RPMSG_F_NS)) {
+               /* a dedicated endpoint handles the name service msgs */
+               vrp->ns_ept = __rpmsg_create_ept(vrp, NULL, rpmsg_ns_cb,
+                                               vrp, RPMSG_NS_ADDR);
+               if (!vrp->ns_ept) {
+                       dev_err(&vdev->dev, "failed to create the ns ept\n");
+                       err = -ENOMEM;
+                       goto free_coherent;
+               }
+       }
+
+       /* tell the remote processor it can start sending messages */
+       virtqueue_kick(vrp->rvq);
+
+       dev_info(&vdev->dev, "rpmsg host is online\n");
+
+       return 0;
+
+free_coherent:
+       dma_free_coherent(vdev->dev.parent, RPMSG_TOTAL_BUF_SPACE, bufs_va,
+                                       vrp->bufs_dma);
+vqs_del:
+       vdev->config->del_vqs(vrp->vdev);
+free_vrp:
+       kfree(vrp);
+       return err;
+}
+
+static int rpmsg_remove_device(struct device *dev, void *data)
+{
+       device_unregister(dev);
+
+       return 0;
+}
+
+static void __devexit rpmsg_remove(struct virtio_device *vdev)
+{
+       struct virtproc_info *vrp = vdev->priv;
+       int ret;
+
+       vdev->config->reset(vdev);
+
+       ret = device_for_each_child(&vdev->dev, NULL, rpmsg_remove_device);
+       if (ret)
+               dev_warn(&vdev->dev, "can't remove rpmsg device: %d\n", ret);
+
+       if (vrp->ns_ept)
+               __rpmsg_destroy_ept(vrp, vrp->ns_ept);
+
+       idr_remove_all(&vrp->endpoints);
+       idr_destroy(&vrp->endpoints);
+
+       vdev->config->del_vqs(vrp->vdev);
+
+       dma_free_coherent(vdev->dev.parent, RPMSG_TOTAL_BUF_SPACE,
+                                       vrp->rbufs, vrp->bufs_dma);
+
+       kfree(vrp);
+}
+
+static struct virtio_device_id id_table[] = {
+       { VIRTIO_ID_RPMSG, VIRTIO_DEV_ANY_ID },
+       { 0 },
+};
+
+static unsigned int features[] = {
+       VIRTIO_RPMSG_F_NS,
+};
+
+static struct virtio_driver virtio_ipc_driver = {
+       .feature_table  = features,
+       .feature_table_size = ARRAY_SIZE(features),
+       .driver.name    = KBUILD_MODNAME,
+       .driver.owner   = THIS_MODULE,
+       .id_table       = id_table,
+       .probe          = rpmsg_probe,
+       .remove         = __devexit_p(rpmsg_remove),
+};
+
+static int __init rpmsg_init(void)
+{
+       int ret;
+
+       ret = bus_register(&rpmsg_bus);
+       if (ret) {
+               pr_err("failed to register rpmsg bus: %d\n", ret);
+               return ret;
+       }
+
+       ret = register_virtio_driver(&virtio_ipc_driver);
+       if (ret) {
+               pr_err("failed to register virtio driver: %d\n", ret);
+               bus_unregister(&rpmsg_bus);
+       }
+
+       return ret;
+}
+module_init(rpmsg_init);
+
+static void __exit rpmsg_fini(void)
+{
+       unregister_virtio_driver(&virtio_ipc_driver);
+       bus_unregister(&rpmsg_bus);
+}
+module_exit(rpmsg_fini);
+
+MODULE_DEVICE_TABLE(virtio, id_table);
+MODULE_DESCRIPTION("Virtio-based remote processor messaging bus");
+MODULE_LICENSE("GPL v2");
index 4f9fb25f945b71d98108c9c9b89030d4f844ab10..8c8377d50c4c4578724c6149bbd084744e7c92fb 100644 (file)
@@ -755,7 +755,7 @@ config HAVE_S3C_RTC
 
 config RTC_DRV_S3C
        tristate "Samsung S3C series SoC RTC"
-       depends on ARCH_S3C2410 || ARCH_S3C64XX || HAVE_S3C_RTC
+       depends on ARCH_S3C64XX || HAVE_S3C_RTC
        help
          RTC (Realtime Clock) driver for the clock inbuilt into the
          Samsung S3C24XX series of SoCs. This can provide periodic
@@ -780,8 +780,8 @@ config RTC_DRV_EP93XX
          will be called rtc-ep93xx.
 
 config RTC_DRV_SA1100
-       tristate "SA11x0/PXA2xx"
-       depends on ARCH_SA1100 || ARCH_PXA
+       tristate "SA11x0/PXA2xx/PXA910"
+       depends on ARCH_SA1100 || ARCH_PXA || ARCH_MMP
        help
          If you say Y here you will get access to the real time clock
          built into your SA11x0 or PXA2xx CPU.
index 274a0aafe42bde9207547d2f67d894afdbe4d48a..831868904e02fd39b7058de5b4e7a65c9d8555b3 100644 (file)
@@ -57,6 +57,7 @@ struct sam9_rtc {
        void __iomem            *rtt;
        struct rtc_device       *rtcdev;
        u32                     imr;
+       void __iomem            *gpbr;
 };
 
 #define rtt_readl(rtc, field) \
@@ -65,9 +66,9 @@ struct sam9_rtc {
        __raw_writel((val), (rtc)->rtt + AT91_RTT_ ## field)
 
 #define gpbr_readl(rtc) \
-       at91_sys_read(AT91_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR)
+       __raw_readl((rtc)->gpbr)
 #define gpbr_writel(rtc, val) \
-       at91_sys_write(AT91_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR, (val))
+       __raw_writel((val), (rtc)->gpbr)
 
 /*
  * Read current time and date in RTC
@@ -287,16 +288,19 @@ static const struct rtc_class_ops at91_rtc_ops = {
 /*
  * Initialize and install RTC driver
  */
-static int __init at91_rtc_probe(struct platform_device *pdev)
+static int __devinit at91_rtc_probe(struct platform_device *pdev)
 {
-       struct resource *r;
+       struct resource *r, *r_gpbr;
        struct sam9_rtc *rtc;
        int             ret;
        u32             mr;
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!r)
+       r_gpbr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       if (!r || !r_gpbr) {
+               dev_err(&pdev->dev, "need 2 ressources\n");
                return -ENODEV;
+       }
 
        rtc = kzalloc(sizeof *rtc, GFP_KERNEL);
        if (!rtc)
@@ -314,6 +318,13 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
                goto fail;
        }
 
+       rtc->gpbr = ioremap(r_gpbr->start, resource_size(r_gpbr));
+       if (!rtc->gpbr) {
+               dev_err(&pdev->dev, "failed to map gpbr registers, aborting.\n");
+               ret = -ENOMEM;
+               goto fail_gpbr;
+       }
+
        mr = rtt_readl(rtc, MR);
 
        /* unless RTT is counting at 1 Hz, re-initialize it */
@@ -340,7 +351,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
        if (ret) {
                dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS);
                rtc_device_unregister(rtc->rtcdev);
-               goto fail;
+               goto fail_register;
        }
 
        /* NOTE:  sam9260 rev A silicon has a ROM bug which resets the
@@ -356,6 +367,8 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
        return 0;
 
 fail_register:
+       iounmap(rtc->gpbr);
+fail_gpbr:
        iounmap(rtc->rtt);
 fail:
        platform_set_drvdata(pdev, NULL);
@@ -366,7 +379,7 @@ fail:
 /*
  * Disable and remove the RTC driver
  */
-static int __exit at91_rtc_remove(struct platform_device *pdev)
+static int __devexit at91_rtc_remove(struct platform_device *pdev)
 {
        struct sam9_rtc *rtc = platform_get_drvdata(pdev);
        u32             mr = rtt_readl(rtc, MR);
@@ -377,6 +390,7 @@ static int __exit at91_rtc_remove(struct platform_device *pdev)
 
        rtc_device_unregister(rtc->rtcdev);
 
+       iounmap(rtc->gpbr);
        iounmap(rtc->rtt);
        platform_set_drvdata(pdev, NULL);
        kfree(rtc);
@@ -440,63 +454,20 @@ static int at91_rtc_resume(struct platform_device *pdev)
 #endif
 
 static struct platform_driver at91_rtc_driver = {
-       .driver.name    = "rtc-at91sam9",
-       .driver.owner   = THIS_MODULE,
-       .remove         = __exit_p(at91_rtc_remove),
+       .probe          = at91_rtc_probe,
+       .remove         = __devexit_p(at91_rtc_remove),
        .shutdown       = at91_rtc_shutdown,
        .suspend        = at91_rtc_suspend,
        .resume         = at91_rtc_resume,
+       .driver         = {
+               .name   = "rtc-at91sam9",
+               .owner  = THIS_MODULE,
+       },
 };
 
-/* Chips can have more than one RTT module, and they can be used for more
- * than just RTCs.  So we can't just register as "the" RTT driver.
- *
- * A normal approach in such cases is to create a library to allocate and
- * free the modules.  Here we just use bus_find_device() as like such a
- * library, binding directly ... no runtime "library" footprint is needed.
- */
-static int __init at91_rtc_match(struct device *dev, void *v)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       int ret;
-
-       /* continue searching if this isn't the RTT we need */
-       if (strcmp("at91_rtt", pdev->name) != 0
-                       || pdev->id != CONFIG_RTC_DRV_AT91SAM9_RTT)
-               goto fail;
-
-       /* else we found it ... but fail unless we can bind to the RTC driver */
-       if (dev->driver) {
-               dev_dbg(dev, "busy, can't use as RTC!\n");
-               goto fail;
-       }
-       dev->driver = &at91_rtc_driver.driver;
-       if (device_attach(dev) == 0) {
-               dev_dbg(dev, "can't attach RTC!\n");
-               goto fail;
-       }
-       ret = at91_rtc_probe(pdev);
-       if (ret == 0)
-               return true;
-
-       dev_dbg(dev, "RTC probe err %d!\n", ret);
-fail:
-       return false;
-}
-
 static int __init at91_rtc_init(void)
 {
-       int status;
-       struct device *rtc;
-
-       status = platform_driver_register(&at91_rtc_driver);
-       if (status)
-               return status;
-       rtc = bus_find_device(&platform_bus_type, NULL,
-                       NULL, at91_rtc_match);
-       if (!rtc)
-               platform_driver_unregister(&at91_rtc_driver);
-       return rtc ? 0 : -ENODEV;
+       return platform_driver_register(&at91_rtc_driver);
 }
 module_init(at91_rtc_init);
 
index 1300962486d11b8cf3596de0b84600f366140c30..b2185f4255aa4075124e4f8d8c084e10abd0cc56 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/bcd.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 #include <linux/delay.h>
 #include <linux/gfp.h>
 #include <linux/module.h>
@@ -294,11 +295,19 @@ static int __exit mv_rtc_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_OF
+static struct of_device_id rtc_mv_of_match_table[] = {
+       { .compatible = "mrvl,orion-rtc", },
+       {}
+};
+#endif
+
 static struct platform_driver mv_rtc_driver = {
        .remove         = __exit_p(mv_rtc_remove),
        .driver         = {
                .name   = "rtc-mv",
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(rtc_mv_of_match_table),
        },
 };
 
index c543f6f1eec2f8d75500d8c77317ed2fcd3136f7..9ccea134a9965a1b2878f6873ae933fb72ca0b1a 100644 (file)
@@ -35,6 +35,8 @@
 
 enum s3c_cpu_type {
        TYPE_S3C2410,
+       TYPE_S3C2416,
+       TYPE_S3C2443,
        TYPE_S3C64XX,
 };
 
@@ -132,6 +134,7 @@ static int s3c_rtc_setfreq(struct device *dev, int freq)
        struct platform_device *pdev = to_platform_device(dev);
        struct rtc_device *rtc_dev = platform_get_drvdata(pdev);
        unsigned int tmp = 0;
+       int val;
 
        if (!is_power_of_2(freq))
                return -EINVAL;
@@ -139,12 +142,22 @@ static int s3c_rtc_setfreq(struct device *dev, int freq)
        clk_enable(rtc_clk);
        spin_lock_irq(&s3c_rtc_pie_lock);
 
-       if (s3c_rtc_cpu_type == TYPE_S3C2410) {
+       if (s3c_rtc_cpu_type != TYPE_S3C64XX) {
                tmp = readb(s3c_rtc_base + S3C2410_TICNT);
                tmp &= S3C2410_TICNT_ENABLE;
        }
 
-       tmp |= (rtc_dev->max_user_freq / freq)-1;
+       val = (rtc_dev->max_user_freq / freq) - 1;
+
+       if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) {
+               tmp |= S3C2443_TICNT_PART(val);
+               writel(S3C2443_TICNT1_PART(val), s3c_rtc_base + S3C2443_TICNT1);
+
+               if (s3c_rtc_cpu_type == TYPE_S3C2416)
+                       writel(S3C2416_TICNT2_PART(val), s3c_rtc_base + S3C2416_TICNT2);
+       } else {
+               tmp |= val;
+       }
 
        writel(tmp, s3c_rtc_base + S3C2410_TICNT);
        spin_unlock_irq(&s3c_rtc_pie_lock);
@@ -371,7 +384,7 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en)
                tmp &= ~S3C2410_RTCCON_RTCEN;
                writew(tmp, base + S3C2410_RTCCON);
 
-               if (s3c_rtc_cpu_type == TYPE_S3C2410) {
+               if (s3c_rtc_cpu_type != TYPE_S3C64XX) {
                        tmp = readb(base + S3C2410_TICNT);
                        tmp &= ~S3C2410_TICNT_ENABLE;
                        writeb(tmp, base + S3C2410_TICNT);
@@ -428,12 +441,27 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev)
        return 0;
 }
 
+static const struct of_device_id s3c_rtc_dt_match[];
+
+static inline int s3c_rtc_get_driver_data(struct platform_device *pdev)
+{
+#ifdef CONFIG_OF
+       if (pdev->dev.of_node) {
+               const struct of_device_id *match;
+               match = of_match_node(s3c_rtc_dt_match, pdev->dev.of_node);
+               return match->data;
+       }
+#endif
+       return platform_get_device_id(pdev)->driver_data;
+}
+
 static int __devinit s3c_rtc_probe(struct platform_device *pdev)
 {
        struct rtc_device *rtc;
        struct rtc_time rtc_tm;
        struct resource *res;
        int ret;
+       int tmp;
 
        pr_debug("%s: probe=%p\n", __func__, pdev);
 
@@ -508,13 +536,7 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
                goto err_nortc;
        }
 
-#ifdef CONFIG_OF
-       if (pdev->dev.of_node)
-               s3c_rtc_cpu_type = of_device_is_compatible(pdev->dev.of_node,
-                       "samsung,s3c6410-rtc") ? TYPE_S3C64XX : TYPE_S3C2410;
-       else
-#endif
-               s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data;
+       s3c_rtc_cpu_type = s3c_rtc_get_driver_data(pdev);
 
        /* Check RTC Time */
 
@@ -533,11 +555,17 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
                dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n");
        }
 
-       if (s3c_rtc_cpu_type == TYPE_S3C64XX)
+       if (s3c_rtc_cpu_type != TYPE_S3C2410)
                rtc->max_user_freq = 32768;
        else
                rtc->max_user_freq = 128;
 
+       if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) {
+               tmp = readw(s3c_rtc_base + S3C2410_RTCCON);
+               tmp |= S3C2443_RTCCON_TICSEL;
+               writew(tmp, s3c_rtc_base + S3C2410_RTCCON);
+       }
+
        platform_set_drvdata(pdev, rtc);
 
        s3c_rtc_setfreq(&pdev->dev, 1);
@@ -638,8 +666,19 @@ static int s3c_rtc_resume(struct platform_device *pdev)
 
 #ifdef CONFIG_OF
 static const struct of_device_id s3c_rtc_dt_match[] = {
-       { .compatible = "samsung,s3c2410-rtc" },
-       { .compatible = "samsung,s3c6410-rtc" },
+       {
+               .compatible = "samsung,s3c2410-rtc"
+               .data = TYPE_S3C2410,
+       }, {
+               .compatible = "samsung,s3c2416-rtc"
+               .data = TYPE_S3C2416,
+       }, {
+               .compatible = "samsung,s3c2443-rtc"
+               .data = TYPE_S3C2443,
+       }, {
+               .compatible = "samsung,s3c6410-rtc"
+               .data = TYPE_S3C64XX,
+       },
        {},
 };
 MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match);
@@ -651,6 +690,12 @@ static struct platform_device_id s3c_rtc_driver_ids[] = {
        {
                .name           = "s3c2410-rtc",
                .driver_data    = TYPE_S3C2410,
+       }, {
+               .name           = "s3c2416-rtc",
+               .driver_data    = TYPE_S3C2416,
+       }, {
+               .name           = "s3c2443-rtc",
+               .driver_data    = TYPE_S3C2443,
        }, {
                .name           = "s3c64xx-rtc",
                .driver_data    = TYPE_S3C64XX,
index fb758db9d0f475f75e68fa191b6c1682bb0e00ee..4940fa8c4e1002f913e7f3171d8cdc72bd5310fb 100644 (file)
 
 #include <linux/platform_device.h>
 #include <linux/module.h>
+#include <linux/clk.h>
 #include <linux/rtc.h>
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/of.h>
 #include <linux/pm.h>
 #include <linux/bitops.h>
 
 #include <mach/hardware.h>
-#include <asm/irq.h>
+#include <mach/irqs.h>
 
-#ifdef CONFIG_ARCH_PXA
+#if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP)
 #include <mach/regs-rtc.h>
 #endif
 
 #define RTC_DEF_DIVIDER                (32768 - 1)
 #define RTC_DEF_TRIM           0
-
-static const unsigned long RTC_FREQ = 1024;
-static struct rtc_time rtc_alarm;
-static DEFINE_SPINLOCK(sa1100_rtc_lock);
-
-static inline int rtc_periodic_alarm(struct rtc_time *tm)
-{
-       return  (tm->tm_year == -1) ||
-               ((unsigned)tm->tm_mon >= 12) ||
-               ((unsigned)(tm->tm_mday - 1) >= 31) ||
-               ((unsigned)tm->tm_hour > 23) ||
-               ((unsigned)tm->tm_min > 59) ||
-               ((unsigned)tm->tm_sec > 59);
-}
-
-/*
- * Calculate the next alarm time given the requested alarm time mask
- * and the current time.
- */
-static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now,
-       struct rtc_time *alrm)
-{
-       unsigned long next_time;
-       unsigned long now_time;
-
-       next->tm_year = now->tm_year;
-       next->tm_mon = now->tm_mon;
-       next->tm_mday = now->tm_mday;
-       next->tm_hour = alrm->tm_hour;
-       next->tm_min = alrm->tm_min;
-       next->tm_sec = alrm->tm_sec;
-
-       rtc_tm_to_time(now, &now_time);
-       rtc_tm_to_time(next, &next_time);
-
-       if (next_time < now_time) {
-               /* Advance one day */
-               next_time += 60 * 60 * 24;
-               rtc_time_to_tm(next_time, next);
-       }
-}
-
-static int rtc_update_alarm(struct rtc_time *alrm)
-{
-       struct rtc_time alarm_tm, now_tm;
-       unsigned long now, time;
-       int ret;
-
-       do {
-               now = RCNR;
-               rtc_time_to_tm(now, &now_tm);
-               rtc_next_alarm_time(&alarm_tm, &now_tm, alrm);
-               ret = rtc_tm_to_time(&alarm_tm, &time);
-               if (ret != 0)
-                       break;
-
-               RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL);
-               RTAR = time;
-       } while (now != RCNR);
-
-       return ret;
-}
+#define RTC_FREQ               1024
+
+struct sa1100_rtc {
+       spinlock_t              lock;
+       int                     irq_1hz;
+       int                     irq_alarm;
+       struct rtc_device       *rtc;
+       struct clk              *clk;
+};
 
 static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)
 {
-       struct platform_device *pdev = to_platform_device(dev_id);
-       struct rtc_device *rtc = platform_get_drvdata(pdev);
+       struct sa1100_rtc *info = dev_get_drvdata(dev_id);
+       struct rtc_device *rtc = info->rtc;
        unsigned int rtsr;
        unsigned long events = 0;
 
-       spin_lock(&sa1100_rtc_lock);
+       spin_lock(&info->lock);
 
        rtsr = RTSR;
        /* clear interrupt sources */
@@ -146,29 +96,28 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)
 
        rtc_update_irq(rtc, 1, events);
 
-       if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm))
-               rtc_update_alarm(&rtc_alarm);
-
-       spin_unlock(&sa1100_rtc_lock);
+       spin_unlock(&info->lock);
 
        return IRQ_HANDLED;
 }
 
 static int sa1100_rtc_open(struct device *dev)
 {
+       struct sa1100_rtc *info = dev_get_drvdata(dev);
+       struct rtc_device *rtc = info->rtc;
        int ret;
-       struct platform_device *plat_dev = to_platform_device(dev);
-       struct rtc_device *rtc = platform_get_drvdata(plat_dev);
 
-       ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, 0, "rtc 1Hz", dev);
+       ret = clk_prepare_enable(info->clk);
+       if (ret)
+               goto fail_clk;
+       ret = request_irq(info->irq_1hz, sa1100_rtc_interrupt, 0, "rtc 1Hz", dev);
        if (ret) {
-               dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz);
+               dev_err(dev, "IRQ %d already in use.\n", info->irq_1hz);
                goto fail_ui;
        }
-       ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, 0,
-                         "rtc Alrm", dev);
+       ret = request_irq(info->irq_alarm, sa1100_rtc_interrupt, 0, "rtc Alrm", dev);
        if (ret) {
-               dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm);
+               dev_err(dev, "IRQ %d already in use.\n", info->irq_alarm);
                goto fail_ai;
        }
        rtc->max_user_freq = RTC_FREQ;
@@ -177,29 +126,36 @@ static int sa1100_rtc_open(struct device *dev)
        return 0;
 
  fail_ai:
-       free_irq(IRQ_RTC1Hz, dev);
+       free_irq(info->irq_1hz, dev);
  fail_ui:
+       clk_disable_unprepare(info->clk);
+ fail_clk:
        return ret;
 }
 
 static void sa1100_rtc_release(struct device *dev)
 {
-       spin_lock_irq(&sa1100_rtc_lock);
+       struct sa1100_rtc *info = dev_get_drvdata(dev);
+
+       spin_lock_irq(&info->lock);
        RTSR = 0;
-       spin_unlock_irq(&sa1100_rtc_lock);
+       spin_unlock_irq(&info->lock);
 
-       free_irq(IRQ_RTCAlrm, dev);
-       free_irq(IRQ_RTC1Hz, dev);
+       free_irq(info->irq_alarm, dev);
+       free_irq(info->irq_1hz, dev);
+       clk_disable_unprepare(info->clk);
 }
 
 static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
-       spin_lock_irq(&sa1100_rtc_lock);
+       struct sa1100_rtc *info = dev_get_drvdata(dev);
+
+       spin_lock_irq(&info->lock);
        if (enabled)
                RTSR |= RTSR_ALE;
        else
                RTSR &= ~RTSR_ALE;
-       spin_unlock_irq(&sa1100_rtc_lock);
+       spin_unlock_irq(&info->lock);
        return 0;
 }
 
@@ -224,7 +180,6 @@ static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
        u32     rtsr;
 
-       memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time));
        rtsr = RTSR;
        alrm->enabled = (rtsr & RTSR_ALE) ? 1 : 0;
        alrm->pending = (rtsr & RTSR_AL) ? 1 : 0;
@@ -233,17 +188,22 @@ static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 
 static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
+       struct sa1100_rtc *info = dev_get_drvdata(dev);
+       unsigned long time;
        int ret;
 
-       spin_lock_irq(&sa1100_rtc_lock);
-       ret = rtc_update_alarm(&alrm->time);
-       if (ret == 0) {
-               if (alrm->enabled)
-                       RTSR |= RTSR_ALE;
-               else
-                       RTSR &= ~RTSR_ALE;
-       }
-       spin_unlock_irq(&sa1100_rtc_lock);
+       spin_lock_irq(&info->lock);
+       ret = rtc_tm_to_time(&alrm->time, &time);
+       if (ret != 0)
+               goto out;
+       RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL);
+       RTAR = time;
+       if (alrm->enabled)
+               RTSR |= RTSR_ALE;
+       else
+               RTSR &= ~RTSR_ALE;
+out:
+       spin_unlock_irq(&info->lock);
 
        return ret;
 }
@@ -270,6 +230,27 @@ static const struct rtc_class_ops sa1100_rtc_ops = {
 static int sa1100_rtc_probe(struct platform_device *pdev)
 {
        struct rtc_device *rtc;
+       struct sa1100_rtc *info;
+       int irq_1hz, irq_alarm, ret = 0;
+
+       irq_1hz = platform_get_irq_byname(pdev, "rtc 1Hz");
+       irq_alarm = platform_get_irq_byname(pdev, "rtc alarm");
+       if (irq_1hz < 0 || irq_alarm < 0)
+               return -ENODEV;
+
+       info = kzalloc(sizeof(struct sa1100_rtc), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+       info->clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(info->clk)) {
+               dev_err(&pdev->dev, "failed to find rtc clock source\n");
+               ret = PTR_ERR(info->clk);
+               goto err_clk;
+       }
+       info->irq_1hz = irq_1hz;
+       info->irq_alarm = irq_alarm;
+       spin_lock_init(&info->lock);
+       platform_set_drvdata(pdev, info);
 
        /*
         * According to the manual we should be able to let RTTR be zero
@@ -291,10 +272,11 @@ static int sa1100_rtc_probe(struct platform_device *pdev)
        rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops,
                THIS_MODULE);
 
-       if (IS_ERR(rtc))
-               return PTR_ERR(rtc);
-
-       platform_set_drvdata(pdev, rtc);
+       if (IS_ERR(rtc)) {
+               ret = PTR_ERR(rtc);
+               goto err_dev;
+       }
+       info->rtc = rtc;
 
        /* Fix for a nasty initialization problem the in SA11xx RTSR register.
         * See also the comments in sa1100_rtc_interrupt().
@@ -321,14 +303,24 @@ static int sa1100_rtc_probe(struct platform_device *pdev)
        RTSR = RTSR_AL | RTSR_HZ;
 
        return 0;
+err_dev:
+       platform_set_drvdata(pdev, NULL);
+       clk_put(info->clk);
+err_clk:
+       kfree(info);
+       return ret;
 }
 
 static int sa1100_rtc_remove(struct platform_device *pdev)
 {
-       struct rtc_device *rtc = platform_get_drvdata(pdev);
+       struct sa1100_rtc *info = platform_get_drvdata(pdev);
 
-       if (rtc)
-               rtc_device_unregister(rtc);
+       if (info) {
+               rtc_device_unregister(info->rtc);
+               clk_put(info->clk);
+               platform_set_drvdata(pdev, NULL);
+               kfree(info);
+       }
 
        return 0;
 }
@@ -336,15 +328,17 @@ static int sa1100_rtc_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int sa1100_rtc_suspend(struct device *dev)
 {
+       struct sa1100_rtc *info = dev_get_drvdata(dev);
        if (device_may_wakeup(dev))
-               enable_irq_wake(IRQ_RTCAlrm);
+               enable_irq_wake(info->irq_alarm);
        return 0;
 }
 
 static int sa1100_rtc_resume(struct device *dev)
 {
+       struct sa1100_rtc *info = dev_get_drvdata(dev);
        if (device_may_wakeup(dev))
-               disable_irq_wake(IRQ_RTCAlrm);
+               disable_irq_wake(info->irq_alarm);
        return 0;
 }
 
@@ -354,6 +348,13 @@ static const struct dev_pm_ops sa1100_rtc_pm_ops = {
 };
 #endif
 
+static struct of_device_id sa1100_rtc_dt_ids[] = {
+       { .compatible = "mrvl,sa1100-rtc", },
+       { .compatible = "mrvl,mmp-rtc", },
+       {}
+};
+MODULE_DEVICE_TABLE(of, sa1100_rtc_dt_ids);
+
 static struct platform_driver sa1100_rtc_driver = {
        .probe          = sa1100_rtc_probe,
        .remove         = sa1100_rtc_remove,
@@ -362,6 +363,7 @@ static struct platform_driver sa1100_rtc_driver = {
 #ifdef CONFIG_PM
                .pm     = &sa1100_rtc_pm_ops,
 #endif
+               .of_match_table = sa1100_rtc_dt_ids,
        },
 };
 
index 2a0dfcb0bc42d2e54c230e4216890ff0133282cf..35c685c374e9965472e66d61e7dddab08792f12f 100644 (file)
@@ -1458,7 +1458,6 @@ int qdio_establish(struct qdio_initialize *init_data)
        }
 
        qdio_setup_ssqd_info(irq_ptr);
-       DBF_EVENT("qib ac:%4x", irq_ptr->qib.ac);
 
        qdio_detect_hsicq(irq_ptr);
 
index 452989a7ec13a1121519bd838204ab6eb1893dce..ecf12f0aca7b2052c5d8d127bba3a73769a2270e 100644 (file)
@@ -311,7 +311,8 @@ void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr)
 
        check_and_setup_qebsm(irq_ptr, qdioac, irq_ptr->ssqd_desc.sch_token);
        process_ac_flags(irq_ptr, qdioac);
-       DBF_EVENT("qdioac:%4x", qdioac);
+       DBF_EVENT("ac 1:%2x 2:%4x", qdioac, irq_ptr->ssqd_desc.qdioac2);
+       DBF_EVENT("3:%4x qib:%4x", irq_ptr->ssqd_desc.qdioac3, irq_ptr->qib.ac);
 }
 
 void qdio_release_memory(struct qdio_irq *irq_ptr)
index a750aa72b8ef27249a8925e49feee8cf5baf1811..2a28b4ad1975b8f66bb846f41f5928bfdaf880d3 100644 (file)
@@ -305,7 +305,7 @@ arxescsi_probe(struct expansion_card *ec, const struct ecard_id *id)
        info->base = base;
 
        info->info.scsi.io_base         = base + 0x2000;
-       info->info.scsi.irq             = NO_IRQ;
+       info->info.scsi.irq             = 0;
        info->info.scsi.dma             = NO_DMA;
        info->info.scsi.io_shift        = 5;
        info->info.ifcfg.clockrate      = 24; /* MHz */
index e85c40b6e19b162bdff9a20c203af426b746cf41..6206a666a8ec6d76a5ecba29f5069d77be339b61 100644 (file)
@@ -2176,7 +2176,7 @@ static void fas216_done(FAS216_Info *info, unsigned int result)
        fn = (void (*)(FAS216_Info *, struct scsi_cmnd *, unsigned int))SCpnt->host_scribble;
        fn(info, SCpnt, result);
 
-       if (info->scsi.irq != NO_IRQ) {
+       if (info->scsi.irq) {
                spin_lock_irqsave(&info->host_lock, flags);
                if (info->scsi.phase == PHASE_IDLE)
                        fas216_kick(info);
@@ -2276,7 +2276,7 @@ static int fas216_noqueue_command_lck(struct scsi_cmnd *SCpnt,
         * We should only be using this if we don't have an interrupt.
         * Provide some "incentive" to use the queueing code.
         */
-       BUG_ON(info->scsi.irq != NO_IRQ);
+       BUG_ON(info->scsi.irq);
 
        info->internal_done = 0;
        fas216_queue_command_lck(SCpnt, fas216_internal_done);
index 84b7127c01212409a97f793d6f87a8bdb0a17c80..df2e1b3ddfe230da9aef38355d7a3014cd8c7e0e 100644 (file)
 #ifndef FAS216_H
 #define FAS216_H
 
-#ifndef NO_IRQ
-#define NO_IRQ 255
-#endif
-
 #include <scsi/scsi_eh.h>
 
 #include "queue.h"
index 92d314a73f69ba0e11d260d4def4a0a5faa4887f..91b6d52f74eb76644c0f5ac2d81285a0da7719b3 100644 (file)
@@ -26,7 +26,7 @@ static void sh_clk_mstp32_disable(struct clk *clk)
                  clk->mapped_reg);
 }
 
-static struct clk_ops sh_clk_mstp32_clk_ops = {
+static struct sh_clk_ops sh_clk_mstp32_clk_ops = {
        .enable         = sh_clk_mstp32_enable,
        .disable        = sh_clk_mstp32_disable,
        .recalc         = followparent_recalc,
@@ -150,7 +150,7 @@ static void sh_clk_div6_disable(struct clk *clk)
        iowrite32(value, clk->mapped_reg);
 }
 
-static struct clk_ops sh_clk_div6_clk_ops = {
+static struct sh_clk_ops sh_clk_div6_clk_ops = {
        .recalc         = sh_clk_div6_recalc,
        .round_rate     = sh_clk_div_round_rate,
        .set_rate       = sh_clk_div6_set_rate,
@@ -158,7 +158,7 @@ static struct clk_ops sh_clk_div6_clk_ops = {
        .disable        = sh_clk_div6_disable,
 };
 
-static struct clk_ops sh_clk_div6_reparent_clk_ops = {
+static struct sh_clk_ops sh_clk_div6_reparent_clk_ops = {
        .recalc         = sh_clk_div6_recalc,
        .round_rate     = sh_clk_div_round_rate,
        .set_rate       = sh_clk_div6_set_rate,
@@ -200,7 +200,7 @@ static int __init sh_clk_init_parent(struct clk *clk)
 }
 
 static int __init sh_clk_div6_register_ops(struct clk *clks, int nr,
-                                          struct clk_ops *ops)
+                                          struct sh_clk_ops *ops)
 {
        struct clk *clkp;
        void *freq_table;
@@ -317,13 +317,13 @@ static void sh_clk_div4_disable(struct clk *clk)
        iowrite32(ioread32(clk->mapped_reg) | (1 << 8), clk->mapped_reg);
 }
 
-static struct clk_ops sh_clk_div4_clk_ops = {
+static struct sh_clk_ops sh_clk_div4_clk_ops = {
        .recalc         = sh_clk_div4_recalc,
        .set_rate       = sh_clk_div4_set_rate,
        .round_rate     = sh_clk_div_round_rate,
 };
 
-static struct clk_ops sh_clk_div4_enable_clk_ops = {
+static struct sh_clk_ops sh_clk_div4_enable_clk_ops = {
        .recalc         = sh_clk_div4_recalc,
        .set_rate       = sh_clk_div4_set_rate,
        .round_rate     = sh_clk_div_round_rate,
@@ -331,7 +331,7 @@ static struct clk_ops sh_clk_div4_enable_clk_ops = {
        .disable        = sh_clk_div4_disable,
 };
 
-static struct clk_ops sh_clk_div4_reparent_clk_ops = {
+static struct sh_clk_ops sh_clk_div4_reparent_clk_ops = {
        .recalc         = sh_clk_div4_recalc,
        .set_rate       = sh_clk_div4_set_rate,
        .round_rate     = sh_clk_div_round_rate,
@@ -341,7 +341,7 @@ static struct clk_ops sh_clk_div4_reparent_clk_ops = {
 };
 
 static int __init sh_clk_div4_register_ops(struct clk *clks, int nr,
-                       struct clk_div4_table *table, struct clk_ops *ops)
+                       struct clk_div4_table *table, struct sh_clk_ops *ops)
 {
        struct clk *clkp;
        void *freq_table;
index 0b06e360628a98f0e5e77c8ee163aa3cdf45bc38..3ed748355b98f629619bdb5ff9e0eae4dbf2bf32 100644 (file)
@@ -293,7 +293,7 @@ config SPI_RSPI
 
 config SPI_S3C24XX
        tristate "Samsung S3C24XX series SPI"
-       depends on ARCH_S3C2410 && EXPERIMENTAL
+       depends on ARCH_S3C24XX && EXPERIMENTAL
        select SPI_BITBANG
        help
          SPI driver for Samsung S3C24XX series ARM SoCs
index 13448c832c4420094afc5f57d8abd5a8b729ae7a..e496f799b7a9053326a1f68f82a67b49a36eaaea 100644 (file)
@@ -359,11 +359,6 @@ static int orion_spi_setup(struct spi_device *spi)
 
        orion_spi = spi_master_get_devdata(spi->master);
 
-       /* Fix ac timing if required.   */
-       if (orion_spi->spi_info->enable_clock_fix)
-               orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
-                                 (1 << 14));
-
        if ((spi->max_speed_hz == 0)
                        || (spi->max_speed_hz > orion_spi->max_speed))
                spi->max_speed_hz = orion_spi->max_speed;
index fc064535f4fceebbade550885518402b5584bf98..8ee7d790ce49424d4595321f6abc068bfcf7eb02 100644 (file)
 
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
+#include <linux/spi/s3c24xx.h>
 #include <linux/module.h>
 
 #include <plat/regs-spi.h>
-#include <mach/spi.h>
 
 #include <plat/fiq.h>
 #include <asm/fiq.h>
index 176f4690057136e18652eebb986f137d9faaec5d..e4c03351420f151e061f9593b880964392a23d98 100644 (file)
@@ -2,4 +2,4 @@
 # Makefile for the RMI4 touchscreen driver.
 #
 obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += synaptics_i2c_rmi4.o
-obj-$(CONFIG_MACH_U8500) += board-mop500-u8500uib-rmi4.o
+obj-$(CONFIG_MACH_MOP500) += board-mop500-u8500uib-rmi4.o
index 10605ecc99abd4a3663ef020462877356a5a9921..f9a6be7a9bed62103f24f461f593fec7a6a0a89c 100644 (file)
@@ -1526,6 +1526,8 @@ void __init atmel_register_uart_fns(struct atmel_port_fns *fns)
        atmel_pops.set_wake     = fns->set_wake;
 }
 
+struct platform_device *atmel_default_console_device;  /* the serial console device */
+
 #ifdef CONFIG_SERIAL_ATMEL_CONSOLE
 static void atmel_console_putchar(struct uart_port *port, int ch)
 {
index 0b7fed746b273fb5647f5f5b05fdd7a37f9c3d76..e7feceeebc2fc9be490e3325e92f317fde5feedb 100644 (file)
@@ -1508,7 +1508,7 @@ static int serial_imx_probe(struct platform_device *pdev)
                ret = PTR_ERR(sport->clk);
                goto unmap;
        }
-       clk_enable(sport->clk);
+       clk_prepare_enable(sport->clk);
 
        sport->port.uartclk = clk_get_rate(sport->clk);
 
@@ -1531,8 +1531,8 @@ deinit:
        if (pdata && pdata->exit)
                pdata->exit(pdev);
 clkput:
+       clk_disable_unprepare(sport->clk);
        clk_put(sport->clk);
-       clk_disable(sport->clk);
 unmap:
        iounmap(sport->port.membase);
 free:
@@ -1552,11 +1552,10 @@ static int serial_imx_remove(struct platform_device *pdev)
 
        if (sport) {
                uart_remove_one_port(&imx_reg, &sport->port);
+               clk_disable_unprepare(sport->clk);
                clk_put(sport->clk);
        }
 
-       clk_disable(sport->clk);
-
        if (pdata && pdata->exit)
                pdata->exit(pdev);
 
index e2fd3d8e0ab481e2fbc4be4958ea9bfa14f04497..5847a4b855f74804d327cca6490cade872f673d2 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/circ_buf.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
@@ -44,6 +45,8 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 
+#define PXA_NAME_LEN           8
+
 struct uart_pxa_port {
        struct uart_port        port;
        unsigned char           ier;
@@ -51,7 +54,7 @@ struct uart_pxa_port {
        unsigned char           mcr;
        unsigned int            lsr_break_flag;
        struct clk              *clk;
-       char                    *name;
+       char                    name[PXA_NAME_LEN];
 };
 
 static inline unsigned int serial_in(struct uart_pxa_port *up, int offset)
@@ -781,6 +784,31 @@ static const struct dev_pm_ops serial_pxa_pm_ops = {
 };
 #endif
 
+static struct of_device_id serial_pxa_dt_ids[] = {
+       { .compatible = "mrvl,pxa-uart", },
+       { .compatible = "mrvl,mmp-uart", },
+       {}
+};
+MODULE_DEVICE_TABLE(of, serial_pxa_dt_ids);
+
+static int serial_pxa_probe_dt(struct platform_device *pdev,
+                              struct uart_pxa_port *sport)
+{
+       struct device_node *np = pdev->dev.of_node;
+       int ret;
+
+       if (!np)
+               return 1;
+
+       ret = of_alias_get_id(np, "serial");
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
+               return ret;
+       }
+       sport->port.line = ret;
+       return 0;
+}
+
 static int serial_pxa_probe(struct platform_device *dev)
 {
        struct uart_pxa_port *sport;
@@ -808,20 +836,16 @@ static int serial_pxa_probe(struct platform_device *dev)
        sport->port.irq = irqres->start;
        sport->port.fifosize = 64;
        sport->port.ops = &serial_pxa_pops;
-       sport->port.line = dev->id;
        sport->port.dev = &dev->dev;
        sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
        sport->port.uartclk = clk_get_rate(sport->clk);
 
-       switch (dev->id) {
-       case 0: sport->name = "FFUART"; break;
-       case 1: sport->name = "BTUART"; break;
-       case 2: sport->name = "STUART"; break;
-       case 3: sport->name = "HWUART"; break;
-       default:
-               sport->name = "???";
-               break;
-       }
+       ret = serial_pxa_probe_dt(dev, sport);
+       if (ret > 0)
+               sport->port.line = dev->id;
+       else if (ret < 0)
+               goto err_clk;
+       snprintf(sport->name, PXA_NAME_LEN - 1, "UART%d", sport->port.line + 1);
 
        sport->port.membase = ioremap(mmres->start, resource_size(mmres));
        if (!sport->port.membase) {
@@ -829,7 +853,7 @@ static int serial_pxa_probe(struct platform_device *dev)
                goto err_clk;
        }
 
-       serial_pxa_ports[dev->id] = sport;
+       serial_pxa_ports[sport->port.line] = sport;
 
        uart_add_one_port(&serial_pxa_reg, &sport->port);
        platform_set_drvdata(dev, sport);
@@ -866,6 +890,7 @@ static struct platform_driver serial_pxa_driver = {
 #ifdef CONFIG_PM
                .pm     = &serial_pxa_pm_ops,
 #endif
+               .of_match_table = serial_pxa_dt_ids,
        },
 };
 
index ef7a21a6a01b1997702c49a7559b13f03007c0d7..2ca5959ec3fae04ddf8c73341d906c57d347bbaa 100644 (file)
@@ -38,6 +38,7 @@
 
 #include <asm/irq.h>
 #include <mach/hardware.h>
+#include <mach/irqs.h>
 #include <asm/mach/serial_sa1100.h>
 
 /* We've been assigned a range on the "Low-density serial ports" major */
index e4405e0885893b2ec6c886c15f21ea0e3c6176d2..cbd8f5f805962a2d1e6b87bce4f7c37137bb5e4c 100644 (file)
@@ -16,7 +16,7 @@ config USB_ARCH_HAS_OHCI
        # ARM:
        default y if SA1111
        default y if ARCH_OMAP
-       default y if ARCH_S3C2410
+       default y if ARCH_S3C24XX
        default y if PXA27x
        default y if PXA3xx
        default y if ARCH_EP93XX
@@ -44,7 +44,7 @@ config USB_ARCH_HAS_EHCI
        default y if PPC_MPC512x
        default y if ARCH_IXP4XX
        default y if ARCH_W90X900
-       default y if ARCH_AT91SAM9G45
+       default y if ARCH_AT91
        default y if ARCH_MXC
        default y if ARCH_OMAP3
        default y if ARCH_CNS3XXX
index c14a3972953af2a1e6955d3f070ca0d1a5f2b209..2633f7595116991f0fad156f646972c459e19f2e 100644 (file)
@@ -137,7 +137,7 @@ choice
 
 config USB_AT91
        tristate "Atmel AT91 USB Device Port"
-       depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9 && !ARCH_AT91SAM9G45
+       depends on ARCH_AT91
        help
           Many Atmel AT91 processors (such as the AT91RM2000) have a
           full speed USB Device Port with support for five configurable
@@ -150,7 +150,7 @@ config USB_AT91
 config USB_ATMEL_USBA
        tristate "Atmel USBA"
        select USB_GADGET_DUALSPEED
-       depends on AVR32 || ARCH_AT91CAP9 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
+       depends on AVR32 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
        help
          USBA is the integrated high-speed USB Device controller on
          the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel.
@@ -284,7 +284,7 @@ config USB_IMX
 
 config USB_S3C2410
        tristate "S3C2410 USB Device Controller"
-       depends on ARCH_S3C2410
+       depends on ARCH_S3C24XX
        help
          Samsung's S3C2410 is an ARM-4 processor with an integrated
          full speed USB 1.1 device controller.  It has 4 configurable
@@ -299,7 +299,7 @@ config USB_S3C2410_DEBUG
 
 config USB_S3C_HSUDC
        tristate "S3C2416, S3C2443 and S3C2450 USB Device Controller"
-       depends on ARCH_S3C2410
+       depends on ARCH_S3C24XX
        select USB_GADGET_DUALSPEED
        help
          Samsung's S3C2416, S3C2443 and S3C2450 is an ARM9 based SoC
index 15a8cdb2ded507a91e3e86ebc59ab076256ab75c..36fd2b4b49a2cc23e8f9d1e76fee72cc7e8c693c 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/clk.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 
 #include <asm/byteorder.h>
 #include <mach/hardware.h>
@@ -40,6 +42,7 @@
 #include <mach/board.h>
 #include <mach/cpu.h>
 #include <mach/at91sam9261_matrix.h>
+#include <mach/at91_matrix.h>
 
 #include "at91_udc.h"
 
@@ -910,9 +913,9 @@ static void pullup(struct at91_udc *udc, int is_on)
                } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
                        u32     usbpucr;
 
-                       usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR);
+                       usbpucr = at91_matrix_read(AT91_MATRIX_USBPUCR);
                        usbpucr |= AT91_MATRIX_USBPUCR_PUON;
-                       at91_sys_write(AT91_MATRIX_USBPUCR, usbpucr);
+                       at91_matrix_write(AT91_MATRIX_USBPUCR, usbpucr);
                }
        } else {
                stop_activity(udc);
@@ -928,9 +931,9 @@ static void pullup(struct at91_udc *udc, int is_on)
                } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) {
                        u32     usbpucr;
 
-                       usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR);
+                       usbpucr = at91_matrix_read(AT91_MATRIX_USBPUCR);
                        usbpucr &= ~AT91_MATRIX_USBPUCR_PUON;
-                       at91_sys_write(AT91_MATRIX_USBPUCR, usbpucr);
+                       at91_matrix_write(AT91_MATRIX_USBPUCR, usbpucr);
                }
                clk_off(udc);
        }
@@ -1706,7 +1709,27 @@ static void at91udc_shutdown(struct platform_device *dev)
        spin_unlock_irqrestore(&udc->lock, flags);
 }
 
-static int __init at91udc_probe(struct platform_device *pdev)
+static void __devinit at91udc_of_init(struct at91_udc *udc,
+                                    struct device_node *np)
+{
+       struct at91_udc_data *board = &udc->board;
+       u32 val;
+       enum of_gpio_flags flags;
+
+       if (of_property_read_u32(np, "atmel,vbus-polled", &val) == 0)
+               board->vbus_polled = 1;
+
+       board->vbus_pin = of_get_named_gpio_flags(np, "atmel,vbus-gpio", 0,
+                                                 &flags);
+       board->vbus_active_low = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
+
+       board->pullup_pin = of_get_named_gpio_flags(np, "atmel,pullup-gpio", 0,
+                                                 &flags);
+
+       board->pullup_active_low = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0;
+}
+
+static int __devinit at91udc_probe(struct platform_device *pdev)
 {
        struct device   *dev = &pdev->dev;
        struct at91_udc *udc;
@@ -1741,7 +1764,11 @@ static int __init at91udc_probe(struct platform_device *pdev)
        /* init software state */
        udc = &controller;
        udc->gadget.dev.parent = dev;
-       udc->board = *(struct at91_udc_data *) dev->platform_data;
+       if (pdev->dev.of_node)
+               at91udc_of_init(udc, pdev->dev.of_node);
+       else
+               memcpy(&udc->board, dev->platform_data,
+                      sizeof(struct at91_udc_data));
        udc->pdev = pdev;
        udc->enabled = 0;
        spin_lock_init(&udc->lock);
@@ -1970,6 +1997,15 @@ static int at91udc_resume(struct platform_device *pdev)
 #define        at91udc_resume  NULL
 #endif
 
+#if defined(CONFIG_OF)
+static const struct of_device_id at91_udc_dt_ids[] = {
+       { .compatible = "atmel,at91rm9200-udc" },
+       { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, at91_udc_dt_ids);
+#endif
+
 static struct platform_driver at91_udc_driver = {
        .remove         = __exit_p(at91udc_remove),
        .shutdown       = at91udc_shutdown,
@@ -1978,6 +2014,7 @@ static struct platform_driver at91_udc_driver = {
        .driver         = {
                .name   = (char *) driver_name,
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(at91_udc_dt_ids),
        },
 };
 
index 5e10f651ad6383d60c22d8c7ec4a5102e340cd36..9f98508966d10dd70202c7d7769451fef3e4d90d 100644 (file)
@@ -332,12 +332,12 @@ static int vbus_is_present(struct usba_udc *udc)
 
 static void toggle_bias(int is_on)
 {
-       unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR);
+       unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR);
 
        if (is_on)
-               at91_sys_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN);
+               at91_pmc_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN);
        else
-               at91_sys_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN));
+               at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN));
 }
 
 #else
index 7cdcb63b21ff6b3605591d87de5d413bc470c61e..85a5cebe96b3635fb521d648f937c7e938e7a6c2 100644 (file)
@@ -345,7 +345,7 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req)
                }
 
                skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
-                               skb->len <= 1, req->actual);
+                               skb->len <= 1, req->actual, req->actual);
                page = NULL;
 
                if (req->actual < req->length) { /* Last fragment */
index a5a3ef1f0096a17602f1e802fc72c4ef07fdf737..19f318ababa286810fe44f6a5efb0fc27c2690c1 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/clk.h>
 #include <linux/platform_device.h>
+#include <linux/of_platform.h>
 
 /* interface and function clocks */
 static struct clk *iclk, *fclk;
@@ -115,6 +116,8 @@ static const struct hc_driver ehci_atmel_hc_driver = {
        .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
 };
 
+static u64 at91_ehci_dma_mask = DMA_BIT_MASK(32);
+
 static int __devinit ehci_atmel_drv_probe(struct platform_device *pdev)
 {
        struct usb_hcd *hcd;
@@ -137,6 +140,13 @@ static int __devinit ehci_atmel_drv_probe(struct platform_device *pdev)
                goto fail_create_hcd;
        }
 
+       /* Right now device-tree probed devices don't get dma_mask set.
+        * Since shared usb code relies on it, set it here for now.
+        * Once we have dma capability bindings this can go away.
+        */
+       if (!pdev->dev.dma_mask)
+               pdev->dev.dma_mask = &at91_ehci_dma_mask;
+
        hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
        if (!hcd) {
                retval = -ENOMEM;
@@ -225,9 +235,21 @@ static int __devexit ehci_atmel_drv_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id atmel_ehci_dt_ids[] = {
+       { .compatible = "atmel,at91sam9g45-ehci" },
+       { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, atmel_ehci_dt_ids);
+#endif
+
 static struct platform_driver ehci_atmel_driver = {
        .probe          = ehci_atmel_drv_probe,
        .remove         = __devexit_p(ehci_atmel_drv_remove),
        .shutdown       = usb_hcd_platform_shutdown,
-       .driver.name    = "atmel-ehci",
+       .driver         = {
+               .name   = "atmel-ehci",
+               .of_match_table = of_match_ptr(atmel_ehci_dt_ids),
+       },
 };
index 77afabc77f9be8d71fd4502bd5f315d9c8bd2c40..db8963f5fbcec11988390b32e02a693c787e2727 100644 (file)
@@ -14,6 +14,8 @@
 
 #include <linux/clk.h>
 #include <linux/platform_device.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
 
 #include <mach/hardware.h>
 #include <asm/gpio.h>
@@ -448,10 +450,11 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
 
        /* From the GPIO notifying the over-current situation, find
         * out the corresponding port */
-       gpio = irq_to_gpio(irq);
        for (port = 0; port < ARRAY_SIZE(pdata->overcurrent_pin); port++) {
-               if (pdata->overcurrent_pin[port] == gpio)
+               if (gpio_to_irq(pdata->overcurrent_pin[port]) == irq) {
+                       gpio = pdata->overcurrent_pin[port];
                        break;
+               }
        }
 
        if (port == ARRAY_SIZE(pdata->overcurrent_pin)) {
@@ -476,13 +479,109 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
        return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id at91_ohci_dt_ids[] = {
+       { .compatible = "atmel,at91rm9200-ohci" },
+       { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, at91_ohci_dt_ids);
+
+static u64 at91_ohci_dma_mask = DMA_BIT_MASK(32);
+
+static int __devinit ohci_at91_of_init(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       int i, ret, gpio;
+       enum of_gpio_flags flags;
+       struct at91_usbh_data   *pdata;
+       u32 ports;
+
+       if (!np)
+               return 0;
+
+       /* Right now device-tree probed devices don't get dma_mask set.
+        * Since shared usb code relies on it, set it here for now.
+        * Once we have dma capability bindings this can go away.
+        */
+       if (!pdev->dev.dma_mask)
+               pdev->dev.dma_mask = &at91_ohci_dma_mask;
+
+       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return -ENOMEM;
+
+       if (!of_property_read_u32(np, "num-ports", &ports))
+               pdata->ports = ports;
+
+       for (i = 0; i < 2; i++) {
+               gpio = of_get_named_gpio_flags(np, "atmel,vbus-gpio", i, &flags);
+               pdata->vbus_pin[i] = gpio;
+               if (!gpio_is_valid(gpio))
+                       continue;
+               pdata->vbus_pin_active_low[i] = flags & OF_GPIO_ACTIVE_LOW;
+               ret = gpio_request(gpio, "ohci_vbus");
+               if (ret) {
+                       dev_warn(&pdev->dev, "can't request vbus gpio %d", gpio);
+                       continue;
+               }
+               ret = gpio_direction_output(gpio, !(flags & OF_GPIO_ACTIVE_LOW) ^ 1);
+               if (ret)
+                       dev_warn(&pdev->dev, "can't put vbus gpio %d as output %d",
+                                !(flags & OF_GPIO_ACTIVE_LOW) ^ 1, gpio);
+       }
+
+       for (i = 0; i < 2; i++) {
+               gpio = of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags);
+               pdata->overcurrent_pin[i] = gpio;
+               if (!gpio_is_valid(gpio))
+                       continue;
+               ret = gpio_request(gpio, "ohci_overcurrent");
+               if (ret) {
+                       dev_err(&pdev->dev, "can't request overcurrent gpio %d", gpio);
+                       continue;
+               }
+
+               ret = gpio_direction_input(gpio);
+               if (ret) {
+                       dev_err(&pdev->dev, "can't configure overcurrent gpio %d as input", gpio);
+                       continue;
+               }
+
+               ret = request_irq(gpio_to_irq(gpio),
+                                 ohci_hcd_at91_overcurrent_irq,
+                                 IRQF_SHARED, "ohci_overcurrent", pdev);
+               if (ret) {
+                       gpio_free(gpio);
+                       dev_warn(& pdev->dev, "cannot get GPIO IRQ for overcurrent\n");
+               }
+       }
+
+       pdev->dev.platform_data = pdata;
+
+       return 0;
+}
+#else
+static int __devinit ohci_at91_of_init(struct platform_device *pdev)
+{
+       return 0;
+}
+#endif
+
 /*-------------------------------------------------------------------------*/
 
 static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
 {
-       struct at91_usbh_data   *pdata = pdev->dev.platform_data;
+       struct at91_usbh_data   *pdata;
        int                     i;
 
+       i = ohci_at91_of_init(pdev);
+
+       if (i)
+               return i;
+
+       pdata = pdev->dev.platform_data;
+
        if (pdata) {
                for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) {
                        if (!gpio_is_valid(pdata->vbus_pin[i]))
@@ -595,5 +694,6 @@ static struct platform_driver ohci_hcd_at91_driver = {
        .driver         = {
                .name   = "at91_ohci",
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(at91_ohci_dt_ids),
        },
 };
index cd5e382db89cd87dccf6cc212c7edf1f190dee65..543e90e336b85f16d3e544fba1251820d7f43b5e 100644 (file)
@@ -1000,7 +1000,7 @@ MODULE_LICENSE ("GPL");
 #define SA1111_DRIVER          ohci_hcd_sa1111_driver
 #endif
 
-#if defined(CONFIG_ARCH_S3C2410) || defined(CONFIG_ARCH_S3C64XX)
+#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX)
 #include "ohci-s3c2410.c"
 #define PLATFORM_DRIVER                ohci_hcd_s3c2410_driver
 #endif
index 4bde4f9821baf99eeae6cf49fe1690278c4b13d1..e1004fb37bd93dbfa2094bdd8ea051cdb817fcfd 100644 (file)
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <mach/assabet.h>
-#include <mach/badge4.h>
 #include <asm/hardware/sa1111.h>
 
 #ifndef CONFIG_SA1111
 #error "This file is SA-1111 bus glue.  CONFIG_SA1111 must be defined."
 #endif
 
-extern int usb_disabled(void);
+#define USB_STATUS     0x0118
+#define USB_RESET      0x011c
+#define USB_IRQTEST    0x0120
+
+#define USB_RESET_FORCEIFRESET (1 << 0)
+#define USB_RESET_FORCEHCRESET (1 << 1)
+#define USB_RESET_CLKGENRESET  (1 << 2)
+#define USB_RESET_SIMSCALEDOWN (1 << 3)
+#define USB_RESET_USBINTTEST   (1 << 4)
+#define USB_RESET_SLEEPSTBYEN  (1 << 5)
+#define USB_RESET_PWRSENSELOW  (1 << 6)
+#define USB_RESET_PWRCTRLLOW   (1 << 7)
+
+#define USB_STATUS_IRQHCIRMTWKUP  (1 <<  7)
+#define USB_STATUS_IRQHCIBUFFACC  (1 <<  8)
+#define USB_STATUS_NIRQHCIM       (1 <<  9)
+#define USB_STATUS_NHCIMFCLR      (1 << 10)
+#define USB_STATUS_USBPWRSENSE    (1 << 11)
 
-/*-------------------------------------------------------------------------*/
+#if 0
+static void dump_hci_status(struct usb_hcd *hcd, const char *label)
+{
+       unsigned long status = sa1111_readl(hcd->regs + USB_STATUS);
+
+       dbg("%s USB_STATUS = { %s%s%s%s%s}", label,
+            ((status & USB_STATUS_IRQHCIRMTWKUP) ? "IRQHCIRMTWKUP " : ""),
+            ((status & USB_STATUS_IRQHCIBUFFACC) ? "IRQHCIBUFFACC " : ""),
+            ((status & USB_STATUS_NIRQHCIM) ? "" : "IRQHCIM "),
+            ((status & USB_STATUS_NHCIMFCLR) ? "" : "HCIMFCLR "),
+            ((status & USB_STATUS_USBPWRSENSE) ? "USBPWRSENSE " : ""));
+}
+#endif
 
-static void sa1111_start_hc(struct sa1111_dev *dev)
+static int ohci_sa1111_reset(struct usb_hcd *hcd)
 {
-       unsigned int usb_rst = 0;
+       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+
+       ohci_hcd_init(ohci);
+       return ohci_init(ohci);
+}
 
-       printk(KERN_DEBUG "%s: starting SA-1111 OHCI USB Controller\n",
-              __FILE__);
+static int __devinit ohci_sa1111_start(struct usb_hcd *hcd)
+{
+       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+       int ret;
 
-#ifdef CONFIG_SA1100_BADGE4
-       if (machine_is_badge4()) {
-               badge4_set_5V(BADGE4_5V_USB, 1);
+       ret = ohci_run(ohci);
+       if (ret < 0) {
+               ohci_err(ohci, "can't start\n");
+               ohci_stop(hcd);
        }
+       return ret;
+}
+
+static const struct hc_driver ohci_sa1111_hc_driver = {
+       .description =          hcd_name,
+       .product_desc =         "SA-1111 OHCI",
+       .hcd_priv_size =        sizeof(struct ohci_hcd),
+
+       /*
+        * generic hardware linkage
+        */
+       .irq =                  ohci_irq,
+       .flags =                HCD_USB11 | HCD_MEMORY,
+
+       /*
+        * basic lifecycle operations
+        */
+       .reset =                ohci_sa1111_reset,
+       .start =                ohci_sa1111_start,
+       .stop =                 ohci_stop,
+       .shutdown =             ohci_shutdown,
+
+       /*
+        * managing i/o requests and associated device resources
+        */
+       .urb_enqueue =          ohci_urb_enqueue,
+       .urb_dequeue =          ohci_urb_dequeue,
+       .endpoint_disable =     ohci_endpoint_disable,
+
+       /*
+        * scheduling support
+        */
+       .get_frame_number =     ohci_get_frame,
+
+       /*
+        * root hub support
+        */
+       .hub_status_data =      ohci_hub_status_data,
+       .hub_control =          ohci_hub_control,
+#ifdef CONFIG_PM
+       .bus_suspend =          ohci_bus_suspend,
+       .bus_resume =           ohci_bus_resume,
 #endif
+       .start_port_reset =     ohci_start_port_reset,
+};
+
+static int sa1111_start_hc(struct sa1111_dev *dev)
+{
+       unsigned int usb_rst = 0;
+       int ret;
+
+       dev_dbg(&dev->dev, "starting SA-1111 OHCI USB Controller\n");
 
        if (machine_is_xp860() ||
            machine_has_neponset() ||
@@ -51,220 +137,121 @@ static void sa1111_start_hc(struct sa1111_dev *dev)
         * host controller in reset.
         */
        sa1111_writel(usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET,
-                     dev->mapbase + SA1111_USB_RESET);
+                     dev->mapbase + USB_RESET);
 
        /*
         * Now, carefully enable the USB clock, and take
         * the USB host controller out of reset.
         */
-       sa1111_enable_device(dev);
-       udelay(11);
-       sa1111_writel(usb_rst, dev->mapbase + SA1111_USB_RESET);
+       ret = sa1111_enable_device(dev);
+       if (ret == 0) {
+               udelay(11);
+               sa1111_writel(usb_rst, dev->mapbase + USB_RESET);
+       }
+
+       return ret;
 }
 
 static void sa1111_stop_hc(struct sa1111_dev *dev)
 {
        unsigned int usb_rst;
-       printk(KERN_DEBUG "%s: stopping SA-1111 OHCI USB Controller\n",
-              __FILE__);
+
+       dev_dbg(&dev->dev, "stopping SA-1111 OHCI USB Controller\n");
 
        /*
         * Put the USB host controller into reset.
         */
-       usb_rst = sa1111_readl(dev->mapbase + SA1111_USB_RESET);
+       usb_rst = sa1111_readl(dev->mapbase + USB_RESET);
        sa1111_writel(usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET,
-                     dev->mapbase + SA1111_USB_RESET);
+                     dev->mapbase + USB_RESET);
 
        /*
         * Stop the USB clock.
         */
        sa1111_disable_device(dev);
-
-#ifdef CONFIG_SA1100_BADGE4
-       if (machine_is_badge4()) {
-               /* Disable power to the USB bus */
-               badge4_set_5V(BADGE4_5V_USB, 0);
-       }
-#endif
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-#if 0
-static void dump_hci_status(struct usb_hcd *hcd, const char *label)
-{
-       unsigned long status = sa1111_readl(hcd->regs + SA1111_USB_STATUS);
-
-       dbg ("%s USB_STATUS = { %s%s%s%s%s}", label,
-            ((status & USB_STATUS_IRQHCIRMTWKUP) ? "IRQHCIRMTWKUP " : ""),
-            ((status & USB_STATUS_IRQHCIBUFFACC) ? "IRQHCIBUFFACC " : ""),
-            ((status & USB_STATUS_NIRQHCIM) ? "" : "IRQHCIM "),
-            ((status & USB_STATUS_NHCIMFCLR) ? "" : "HCIMFCLR "),
-            ((status & USB_STATUS_USBPWRSENSE) ? "USBPWRSENSE " : ""));
 }
-#endif
-
-/*-------------------------------------------------------------------------*/
-
-/* configure so an HC device and id are always provided */
-/* always called with process context; sleeping is OK */
-
 
 /**
- * usb_hcd_sa1111_probe - initialize SA-1111-based HCDs
- * Context: !in_interrupt()
+ * ohci_hcd_sa1111_probe - initialize SA-1111-based HCDs
  *
  * Allocates basic resources for this USB host controller, and
- * then invokes the start() method for the HCD associated with it
- * through the hotplug entry's driver_data.
- *
- * Store this function in the HCD's struct pci_driver as probe().
+ * then invokes the start() method for the HCD associated with it.
  */
-int usb_hcd_sa1111_probe (const struct hc_driver *driver,
-                         struct sa1111_dev *dev)
+static int ohci_hcd_sa1111_probe(struct sa1111_dev *dev)
 {
        struct usb_hcd *hcd;
-       int retval;
+       int ret;
 
-       hcd = usb_create_hcd (driver, &dev->dev, "sa1111");
+       if (usb_disabled())
+               return -ENODEV;
+
+       hcd = usb_create_hcd(&ohci_sa1111_hc_driver, &dev->dev, "sa1111");
        if (!hcd)
                return -ENOMEM;
+
        hcd->rsrc_start = dev->res.start;
        hcd->rsrc_len = resource_size(&dev->res);
 
        if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
                dbg("request_mem_region failed");
-               retval = -EBUSY;
+               ret = -EBUSY;
                goto err1;
        }
+
        hcd->regs = dev->mapbase;
 
-       sa1111_start_hc(dev);
-       ohci_hcd_init(hcd_to_ohci(hcd));
+       ret = sa1111_start_hc(dev);
+       if (ret)
+               goto err2;
 
-       retval = usb_add_hcd(hcd, dev->irq[1], 0);
-       if (retval == 0)
-               return retval;
+       ret = usb_add_hcd(hcd, dev->irq[1], 0);
+       if (ret == 0)
+               return ret;
 
        sa1111_stop_hc(dev);
+ err2:
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  err1:
        usb_put_hcd(hcd);
-       return retval;
+       return ret;
 }
 
-
-/* may be called without controller electrically present */
-/* may be called with controller, bus, and devices active */
-
 /**
- * usb_hcd_sa1111_remove - shutdown processing for SA-1111-based HCDs
+ * ohci_hcd_sa1111_remove - shutdown processing for SA-1111-based HCDs
  * @dev: USB Host Controller being removed
- * Context: !in_interrupt()
- *
- * Reverses the effect of usb_hcd_sa1111_probe(), first invoking
- * the HCD's stop() method.  It is always called from a thread
- * context, normally "rmmod", "apmd", or something similar.
  *
+ * Reverses the effect of ohci_hcd_sa1111_probe(), first invoking
+ * the HCD's stop() method.
  */
-void usb_hcd_sa1111_remove (struct usb_hcd *hcd, struct sa1111_dev *dev)
+static int ohci_hcd_sa1111_remove(struct sa1111_dev *dev)
 {
+       struct usb_hcd *hcd = sa1111_get_drvdata(dev);
+
        usb_remove_hcd(hcd);
        sa1111_stop_hc(dev);
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
        usb_put_hcd(hcd);
-}
-
-/*-------------------------------------------------------------------------*/
 
-static int __devinit
-ohci_sa1111_start (struct usb_hcd *hcd)
-{
-       struct ohci_hcd *ohci = hcd_to_ohci (hcd);
-       int             ret;
-
-       if ((ret = ohci_init(ohci)) < 0)
-               return ret;
-
-       if ((ret = ohci_run (ohci)) < 0) {
-               err ("can't start %s", hcd->self.bus_name);
-               ohci_stop (hcd);
-               return ret;
-       }
        return 0;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static const struct hc_driver ohci_sa1111_hc_driver = {
-       .description =          hcd_name,
-       .product_desc =         "SA-1111 OHCI",
-       .hcd_priv_size =        sizeof(struct ohci_hcd),
-
-       /*
-        * generic hardware linkage
-        */
-       .irq =                  ohci_irq,
-       .flags =                HCD_USB11 | HCD_MEMORY,
-
-       /*
-        * basic lifecycle operations
-        */
-       .start =                ohci_sa1111_start,
-       .stop =                 ohci_stop,
-
-       /*
-        * managing i/o requests and associated device resources
-        */
-       .urb_enqueue =          ohci_urb_enqueue,
-       .urb_dequeue =          ohci_urb_dequeue,
-       .endpoint_disable =     ohci_endpoint_disable,
-
-       /*
-        * scheduling support
-        */
-       .get_frame_number =     ohci_get_frame,
-
-       /*
-        * root hub support
-        */
-       .hub_status_data =      ohci_hub_status_data,
-       .hub_control =          ohci_hub_control,
-#ifdef CONFIG_PM
-       .bus_suspend =          ohci_bus_suspend,
-       .bus_resume =           ohci_bus_resume,
-#endif
-       .start_port_reset =     ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_hcd_sa1111_drv_probe(struct sa1111_dev *dev)
-{
-       int ret;
-
-       if (usb_disabled())
-               return -ENODEV;
-
-       ret = usb_hcd_sa1111_probe(&ohci_sa1111_hc_driver, dev);
-       return ret;
-}
-
-static int ohci_hcd_sa1111_drv_remove(struct sa1111_dev *dev)
+static void ohci_hcd_sa1111_shutdown(struct sa1111_dev *dev)
 {
        struct usb_hcd *hcd = sa1111_get_drvdata(dev);
 
-       usb_hcd_sa1111_remove(hcd, dev);
-       return 0;
+       if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
+               hcd->driver->shutdown(hcd);
+               sa1111_stop_hc(dev);
+       }
 }
 
 static struct sa1111_driver ohci_hcd_sa1111_driver = {
        .drv = {
                .name   = "sa1111-ohci",
+               .owner  = THIS_MODULE,
        },
        .devid          = SA1111_DEVID_USB,
-       .probe          = ohci_hcd_sa1111_drv_probe,
-       .remove         = ohci_hcd_sa1111_drv_remove,
+       .probe          = ohci_hcd_sa1111_probe,
+       .remove         = ohci_hcd_sa1111_remove,
+       .shutdown       = ohci_hcd_sa1111_shutdown,
 };
-
index 6815701cf65607c0bccd68b210f5c358fb472134..836cfa9a515fe9f2523f3a387995ac386f915ec8 100644 (file)
@@ -903,8 +903,10 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff),
          .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
-       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff),
+         .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff),
+         .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) },
index 9dab1f51dd43b3bac6e275eac77f995fb245d48d..f0da2c32fbdefce2ff9d791f9fa23a73ac49de8d 100644 (file)
@@ -588,7 +588,7 @@ static int vhost_net_release(struct inode *inode, struct file *f)
 
        vhost_net_stop(n, &tx_sock, &rx_sock);
        vhost_net_flush(n);
-       vhost_dev_cleanup(&n->dev);
+       vhost_dev_cleanup(&n->dev, false);
        if (tx_sock)
                fput(tx_sock->file);
        if (rx_sock)
index bdb2d6436b2b4f9c4f6d89531abb3b1191a8b0d2..947f00d8e091a3f2f3c01cc7cc23f5f2658d37df 100644 (file)
@@ -222,6 +222,8 @@ static int vhost_worker(void *data)
                if (work) {
                        __set_current_state(TASK_RUNNING);
                        work->fn(work);
+                       if (need_resched())
+                               schedule();
                } else
                        schedule();
 
@@ -403,7 +405,7 @@ long vhost_dev_reset_owner(struct vhost_dev *dev)
        if (!memory)
                return -ENOMEM;
 
-       vhost_dev_cleanup(dev);
+       vhost_dev_cleanup(dev, true);
 
        memory->nregions = 0;
        RCU_INIT_POINTER(dev->memory, memory);
@@ -434,8 +436,8 @@ int vhost_zerocopy_signal_used(struct vhost_virtqueue *vq)
        return j;
 }
 
-/* Caller should have device mutex */
-void vhost_dev_cleanup(struct vhost_dev *dev)
+/* Caller should have device mutex if and only if locked is set */
+void vhost_dev_cleanup(struct vhost_dev *dev, bool locked)
 {
        int i;
 
@@ -472,7 +474,8 @@ void vhost_dev_cleanup(struct vhost_dev *dev)
        dev->log_file = NULL;
        /* No one will access memory at this point */
        kfree(rcu_dereference_protected(dev->memory,
-                                       lockdep_is_held(&dev->mutex)));
+                                       locked ==
+                                               lockdep_is_held(&dev->mutex)));
        RCU_INIT_POINTER(dev->memory, NULL);
        WARN_ON(!list_empty(&dev->work_list));
        if (dev->worker) {
index a801e2821d0387e2fc825e4a124bf2413f16d181..8dcf4cca6bf224ec5c36f105a994ba76b0b19188 100644 (file)
@@ -163,7 +163,7 @@ struct vhost_dev {
 long vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue *vqs, int nvqs);
 long vhost_dev_check_owner(struct vhost_dev *);
 long vhost_dev_reset_owner(struct vhost_dev *);
-void vhost_dev_cleanup(struct vhost_dev *);
+void vhost_dev_cleanup(struct vhost_dev *, bool locked);
 long vhost_dev_ioctl(struct vhost_dev *, unsigned int ioctl, unsigned long arg);
 int vhost_vq_access_ok(struct vhost_virtqueue *vq);
 int vhost_log_access_ok(struct vhost_dev *);
index a8a897ac5446700c2326c88204bf35fc2fc9b454..a290be51a1f4a2f412aa80976c85a396eb60db30 100644 (file)
@@ -2061,7 +2061,7 @@ config FB_S3C_DEBUG_REGWRITE
 
 config FB_S3C2410
        tristate "S3C2410 LCD framebuffer support"
-       depends on FB && ARCH_S3C2410
+       depends on FB && ARCH_S3C24XX
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
index b62b8b9063b53beeacffa86c8259d971372e3ec9..08214e1f09583b25ace65acdb3487a0b48c9b731 100644 (file)
 #include <linux/fb.h>
 #include <linux/backlight.h>
 
-#include <mach/hardware.h>
-
-#define EP93XX_RASTER_REG(x)           (EP93XX_RASTER_BASE + (x))
-#define EP93XX_RASTER_BRIGHTNESS       EP93XX_RASTER_REG(0x20)
-
 #define EP93XX_MAX_COUNT               255
 #define EP93XX_MAX_BRIGHT              255
 #define EP93XX_DEF_BRIGHT              128
@@ -35,7 +30,7 @@ static int ep93xxbl_set(struct backlight_device *bl, int brightness)
 {
        struct ep93xxbl *ep93xxbl = bl_get_data(bl);
 
-       __raw_writel((brightness << 8) | EP93XX_MAX_COUNT, ep93xxbl->mmio);
+       writel((brightness << 8) | EP93XX_MAX_COUNT, ep93xxbl->mmio);
 
        ep93xxbl->brightness = brightness;
 
@@ -70,21 +65,29 @@ static int __init ep93xxbl_probe(struct platform_device *dev)
        struct ep93xxbl *ep93xxbl;
        struct backlight_device *bl;
        struct backlight_properties props;
+       struct resource *res;
 
        ep93xxbl = devm_kzalloc(&dev->dev, sizeof(*ep93xxbl), GFP_KERNEL);
        if (!ep93xxbl)
                return -ENOMEM;
 
+       res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENXIO;
+
        /*
-        * This register is located in the range already ioremap'ed by
-        * the framebuffer driver.  A MFD driver seems a bit of overkill
-        * to handle this so use the static I/O mapping; this address
-        * is already virtual.
+        * FIXME - We don't do a request_mem_region here because we are
+        * sharing the register space with the framebuffer driver (see
+        * drivers/video/ep93xx-fb.c) and doing so will cause the second
+        * loaded driver to return -EBUSY.
         *
         * NOTE: No locking is required; the framebuffer does not touch
         * this register.
         */
-       ep93xxbl->mmio = EP93XX_RASTER_BRIGHTNESS;
+       ep93xxbl->mmio = devm_ioremap(&dev->dev, res->start,
+                                     resource_size(res));
+       if (!ep93xxbl->mmio)
+               return -ENXIO;
 
        memset(&props, 0, sizeof(struct backlight_properties));
        props.type = BACKLIGHT_RAW;
index 2e830ec52a5a91664527c32b3108a521e4c6c1c5..f8babbeee27543e9149af7319f42c60ef4808d3b 100644 (file)
@@ -519,12 +519,15 @@ static int __devinit ep93xxfb_probe(struct platform_device *pdev)
                goto failed;
        }
 
-       res = request_mem_region(res->start, resource_size(res), pdev->name);
-       if (!res) {
-               err = -EBUSY;
-               goto failed;
-       }
-
+       /*
+        * FIXME - We don't do a request_mem_region here because we are
+        * sharing the register space with the backlight driver (see
+        * drivers/video/backlight/ep93xx_bl.c) and doing so will cause
+        * the second loaded driver to return -EBUSY.
+        *
+        * NOTE: No locking is required; the backlight does not touch
+        * any of the framebuffer registers.
+        */
        fbi->res = res;
        fbi->mmio_base = ioremap(res->start, resource_size(res));
        if (!fbi->mmio_base) {
@@ -586,8 +589,6 @@ failed:
                clk_put(fbi->clk);
        if (fbi->mmio_base)
                iounmap(fbi->mmio_base);
-       if (fbi->res)
-               release_mem_region(fbi->res->start, resource_size(fbi->res));
        ep93xxfb_dealloc_videomem(info);
        if (&info->cmap)
                fb_dealloc_cmap(&info->cmap);
@@ -608,7 +609,6 @@ static int __devexit ep93xxfb_remove(struct platform_device *pdev)
        clk_disable(fbi->clk);
        clk_put(fbi->clk);
        iounmap(fbi->mmio_base);
-       release_mem_region(fbi->res->start, resource_size(fbi->res));
        ep93xxfb_dealloc_videomem(info);
        fb_dealloc_cmap(&info->cmap);
 
index 0fdd6f6873bfcc1f153cb50462e588ebc49d33c0..d3a31132722722eaf1c4d214cbd6d88315fea998 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/lcd.h>
+#include <linux/gpio.h>
 
 #include <plat/board-ams-delta.h>
 #include <mach/hardware.h>
@@ -98,29 +99,41 @@ static struct lcd_ops ams_delta_lcd_ops = {
 
 /* omapfb panel section */
 
+static const struct gpio _gpios[] = {
+       {
+               .gpio   = AMS_DELTA_GPIO_PIN_LCD_VBLEN,
+               .flags  = GPIOF_OUT_INIT_LOW,
+               .label  = "lcd_vblen",
+       },
+       {
+               .gpio   = AMS_DELTA_GPIO_PIN_LCD_NDISP,
+               .flags  = GPIOF_OUT_INIT_LOW,
+               .label  = "lcd_ndisp",
+       },
+};
+
 static int ams_delta_panel_init(struct lcd_panel *panel,
                struct omapfb_device *fbdev)
 {
-       return 0;
+       return gpio_request_array(_gpios, ARRAY_SIZE(_gpios));
 }
 
 static void ams_delta_panel_cleanup(struct lcd_panel *panel)
 {
+       gpio_free_array(_gpios, ARRAY_SIZE(_gpios));
 }
 
 static int ams_delta_panel_enable(struct lcd_panel *panel)
 {
-       ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_NDISP,
-                       AMS_DELTA_LATCH2_LCD_NDISP);
-       ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN,
-                       AMS_DELTA_LATCH2_LCD_VBLEN);
+       gpio_set_value(AMS_DELTA_GPIO_PIN_LCD_NDISP, 1);
+       gpio_set_value(AMS_DELTA_GPIO_PIN_LCD_VBLEN, 1);
        return 0;
 }
 
 static void ams_delta_panel_disable(struct lcd_panel *panel)
 {
-       ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN, 0);
-       ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_NDISP, 0);
+       gpio_set_value(AMS_DELTA_GPIO_PIN_LCD_VBLEN, 0);
+       gpio_set_value(AMS_DELTA_GPIO_PIN_LCD_NDISP, 0);
 }
 
 static unsigned long ams_delta_panel_get_caps(struct lcd_panel *panel)
index bddd64b435b989e45770b57f30cacc574fa572f3..ee30937482e1156240de18ccaff3f889a1e4637b 100644 (file)
@@ -3318,11 +3318,6 @@ static void _omap_dispc_initial_config(void)
        if (dss_has_feature(FEAT_FUNCGATED))
                REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9);
 
-       /* L3 firewall setting: enable access to OCM RAM */
-       /* XXX this should be somewhere in plat-omap */
-       if (cpu_is_omap24xx())
-               __raw_writel(0x402000b0, OMAP2_L3_IO_ADDRESS(0x680050a0));
-
        _dispc_setup_color_conv_coef();
 
        dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY);
index 4a6b5eeef6a798b2a4dbd060e603a6a8f235ecb9..bd2d5e159463c3c49a2f642a52814f8e8d83922f 100644 (file)
 #include <linux/pm_runtime.h>
 
 #include <video/omapdss.h>
+
+#include <plat/cpu.h>
 #include <plat/clock.h>
+
 #include "dss.h"
 #include "dss_features.h"
 
index 98d55d0e2da5336dbb58a189c25b6f45569f1789..b6325848ad614f6beb1d1c49cc72b09b2652e0df 100644 (file)
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/cpufreq.h>
+#include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/mutex.h>
 #include <linux/io.h>
 
+#include <video/sa1100fb.h>
+
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <mach/assabet.h>
 #include <mach/shannon.h>
 
-/*
- * debugging?
- */
-#define DEBUG 0
 /*
  * Complain if VAR is out of range.
  */
 #define DEBUG_VAR 1
 
-#undef ASSABET_PAL_VIDEO
-
 #include "sa1100fb.h"
 
-extern void (*sa1100fb_backlight_power)(int on);
-extern void (*sa1100fb_lcd_power)(int on);
-
-static struct sa1100fb_rgb rgb_4 = {
+static const struct sa1100fb_rgb rgb_4 = {
        .red    = { .offset = 0,  .length = 4, },
        .green  = { .offset = 0,  .length = 4, },
        .blue   = { .offset = 0,  .length = 4, },
        .transp = { .offset = 0,  .length = 0, },
 };
 
-static struct sa1100fb_rgb rgb_8 = {
+static const struct sa1100fb_rgb rgb_8 = {
        .red    = { .offset = 0,  .length = 8, },
        .green  = { .offset = 0,  .length = 8, },
        .blue   = { .offset = 0,  .length = 8, },
        .transp = { .offset = 0,  .length = 0, },
 };
 
-static struct sa1100fb_rgb def_rgb_16 = {
+static const struct sa1100fb_rgb def_rgb_16 = {
        .red    = { .offset = 11, .length = 5, },
        .green  = { .offset = 5,  .length = 6, },
        .blue   = { .offset = 0,  .length = 5, },
        .transp = { .offset = 0,  .length = 0, },
 };
 
-#ifdef CONFIG_SA1100_ASSABET
-#ifndef ASSABET_PAL_VIDEO
-/*
- * The assabet uses a sharp LQ039Q2DS54 LCD module.  It is actually
- * takes an RGB666 signal, but we provide it with an RGB565 signal
- * instead (def_rgb_16).
- */
-static struct sa1100fb_mach_info lq039q2ds54_info __initdata = {
-       .pixclock       = 171521,       .bpp            = 16,
-       .xres           = 320,          .yres           = 240,
-
-       .hsync_len      = 5,            .vsync_len      = 1,
-       .left_margin    = 61,           .upper_margin   = 3,
-       .right_margin   = 9,            .lower_margin   = 0,
-
-       .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-
-       .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-       .lccr3          = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
-};
-#else
-static struct sa1100fb_mach_info pal_info __initdata = {
-       .pixclock       = 67797,        .bpp            = 16,
-       .xres           = 640,          .yres           = 512,
-
-       .hsync_len      = 64,           .vsync_len      = 6,
-       .left_margin    = 125,          .upper_margin   = 70,
-       .right_margin   = 115,          .lower_margin   = 36,
-
-       .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-       .lccr3          = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
-};
-#endif
-#endif
-
-#ifdef CONFIG_SA1100_H3600
-static struct sa1100fb_mach_info h3600_info __initdata = {
-       .pixclock       = 174757,       .bpp            = 16,
-       .xres           = 320,          .yres           = 240,
-
-       .hsync_len      = 3,            .vsync_len      = 3,
-       .left_margin    = 12,           .upper_margin   = 10,
-       .right_margin   = 17,           .lower_margin   = 1,
-
-       .cmap_static    = 1,
-
-       .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-       .lccr3          = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
-};
-
-static struct sa1100fb_rgb h3600_rgb_16 = {
-       .red    = { .offset = 12, .length = 4, },
-       .green  = { .offset = 7,  .length = 4, },
-       .blue   = { .offset = 1,  .length = 4, },
-       .transp = { .offset = 0,  .length = 0, },
-};
-#endif
-
-#ifdef CONFIG_SA1100_H3100
-static struct sa1100fb_mach_info h3100_info __initdata = {
-       .pixclock       = 406977,       .bpp            = 4,
-       .xres           = 320,          .yres           = 240,
-
-       .hsync_len      = 26,           .vsync_len      = 41,
-       .left_margin    = 4,            .upper_margin   = 0,
-       .right_margin   = 4,            .lower_margin   = 0,
-
-       .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-       .cmap_greyscale = 1,
-       .cmap_inverse   = 1,
-
-       .lccr0          = LCCR0_Mono | LCCR0_4PixMono | LCCR0_Sngl | LCCR0_Pas,
-       .lccr3          = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
-};
-#endif
-
-#ifdef CONFIG_SA1100_COLLIE
-static struct sa1100fb_mach_info collie_info __initdata = {
-       .pixclock       = 171521,       .bpp            = 16,
-       .xres           = 320,          .yres           = 240,
-
-       .hsync_len      = 5,            .vsync_len      = 1,
-       .left_margin    = 11,           .upper_margin   = 2,
-       .right_margin   = 30,           .lower_margin   = 0,
-
-       .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-
-       .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-       .lccr3          = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
-};
-#endif
-
-#ifdef LART_GREY_LCD
-static struct sa1100fb_mach_info lart_grey_info __initdata = {
-       .pixclock       = 150000,       .bpp            = 4,
-       .xres           = 320,          .yres           = 240,
-
-       .hsync_len      = 1,            .vsync_len      = 1,
-       .left_margin    = 4,            .upper_margin   = 0,
-       .right_margin   = 2,            .lower_margin   = 0,
-
-       .cmap_greyscale = 1,
-       .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-
-       .lccr0          = LCCR0_Mono | LCCR0_Sngl | LCCR0_Pas | LCCR0_4PixMono,
-       .lccr3          = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
-};
-#endif
-#ifdef LART_COLOR_LCD
-static struct sa1100fb_mach_info lart_color_info __initdata = {
-       .pixclock       = 150000,       .bpp            = 16,
-       .xres           = 320,          .yres           = 240,
-
-       .hsync_len      = 2,            .vsync_len      = 3,
-       .left_margin    = 69,           .upper_margin   = 14,
-       .right_margin   = 8,            .lower_margin   = 4,
-
-       .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-       .lccr3          = LCCR3_OutEnH | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
-};
-#endif
-#ifdef LART_VIDEO_OUT
-static struct sa1100fb_mach_info lart_video_info __initdata = {
-       .pixclock       = 39721,        .bpp            = 16,
-       .xres           = 640,          .yres           = 480,
-
-       .hsync_len      = 95,           .vsync_len      = 2,
-       .left_margin    = 40,           .upper_margin   = 32,
-       .right_margin   = 24,           .lower_margin   = 11,
-
-       .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-
-       .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-       .lccr3          = LCCR3_OutEnL | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
-};
-#endif
-
-#ifdef LART_KIT01_LCD
-static struct sa1100fb_mach_info lart_kit01_info __initdata = {
-       .pixclock       = 63291,        .bpp            = 16,
-       .xres           = 640,          .yres           = 480,
-
-       .hsync_len      = 64,           .vsync_len      = 3,
-       .left_margin    = 122,          .upper_margin   = 45,
-       .right_margin   = 10,           .lower_margin   = 10,
-
-       .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-       .lccr3          = LCCR3_OutEnH | LCCR3_PixFlEdg
-};
-#endif
-
-#ifdef CONFIG_SA1100_SHANNON
-static struct sa1100fb_mach_info shannon_info __initdata = {
-       .pixclock       = 152500,       .bpp            = 8,
-       .xres           = 640,          .yres           = 480,
-
-       .hsync_len      = 4,            .vsync_len      = 3,
-       .left_margin    = 2,            .upper_margin   = 0,
-       .right_margin   = 1,            .lower_margin   = 0,
-
-       .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-
-       .lccr0          = LCCR0_Color | LCCR0_Dual | LCCR0_Pas,
-       .lccr3          = LCCR3_ACBsDiv(512),
-};
-#endif
-
 
 
-static struct sa1100fb_mach_info * __init
-sa1100fb_get_machine_info(struct sa1100fb_info *fbi)
-{
-       struct sa1100fb_mach_info *inf = NULL;
-
-       /*
-        *            R        G       B       T
-        * default  {11,5}, { 5,6}, { 0,5}, { 0,0}
-        * h3600    {12,4}, { 7,4}, { 1,4}, { 0,0}
-        * freebird { 8,4}, { 4,4}, { 0,4}, {12,4}
-        */
-#ifdef CONFIG_SA1100_ASSABET
-       if (machine_is_assabet()) {
-#ifndef ASSABET_PAL_VIDEO
-               inf = &lq039q2ds54_info;
-#else
-               inf = &pal_info;
-#endif
-       }
-#endif
-#ifdef CONFIG_SA1100_H3100
-       if (machine_is_h3100()) {
-               inf = &h3100_info;
-       }
-#endif
-#ifdef CONFIG_SA1100_H3600
-       if (machine_is_h3600()) {
-               inf = &h3600_info;
-               fbi->rgb[RGB_16] = &h3600_rgb_16;
-       }
-#endif
-#ifdef CONFIG_SA1100_COLLIE
-       if (machine_is_collie()) {
-               inf = &collie_info;
-       }
-#endif
-#ifdef CONFIG_SA1100_LART
-       if (machine_is_lart()) {
-#ifdef LART_GREY_LCD
-               inf = &lart_grey_info;
-#endif
-#ifdef LART_COLOR_LCD
-               inf = &lart_color_info;
-#endif
-#ifdef LART_VIDEO_OUT
-               inf = &lart_video_info;
-#endif
-#ifdef LART_KIT01_LCD
-               inf = &lart_kit01_info;
-#endif
-       }
-#endif
-#ifdef CONFIG_SA1100_SHANNON
-       if (machine_is_shannon()) {
-               inf = &shannon_info;
-       }
-#endif
-       return inf;
-}
-
 static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_info *);
 static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state);
 
@@ -533,7 +299,7 @@ sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
         * is what you poke into the framebuffer to produce the
         * colour you requested.
         */
-       if (fbi->cmap_inverse) {
+       if (fbi->inf->cmap_inverse) {
                red   = 0xffff - red;
                green = 0xffff - green;
                blue  = 0xffff - blue;
@@ -607,14 +373,14 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
                var->xres = MIN_XRES;
        if (var->yres < MIN_YRES)
                var->yres = MIN_YRES;
-       if (var->xres > fbi->max_xres)
-               var->xres = fbi->max_xres;
-       if (var->yres > fbi->max_yres)
-               var->yres = fbi->max_yres;
+       if (var->xres > fbi->inf->xres)
+               var->xres = fbi->inf->xres;
+       if (var->yres > fbi->inf->yres)
+               var->yres = fbi->inf->yres;
        var->xres_virtual = max(var->xres_virtual, var->xres);
        var->yres_virtual = max(var->yres_virtual, var->yres);
 
-       DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel);
+       dev_dbg(fbi->dev, "var->bits_per_pixel=%d\n", var->bits_per_pixel);
        switch (var->bits_per_pixel) {
        case 4:
                rgbidx = RGB_4;
@@ -638,16 +404,16 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
        var->blue   = fbi->rgb[rgbidx]->blue;
        var->transp = fbi->rgb[rgbidx]->transp;
 
-       DPRINTK("RGBT length = %d:%d:%d:%d\n",
+       dev_dbg(fbi->dev, "RGBT length = %d:%d:%d:%d\n",
                var->red.length, var->green.length, var->blue.length,
                var->transp.length);
 
-       DPRINTK("RGBT offset = %d:%d:%d:%d\n",
+       dev_dbg(fbi->dev, "RGBT offset = %d:%d:%d:%d\n",
                var->red.offset, var->green.offset, var->blue.offset,
                var->transp.offset);
 
 #ifdef CONFIG_CPU_FREQ
-       printk(KERN_DEBUG "dma period = %d ps, clock = %d kHz\n",
+       dev_dbg(fbi->dev, "dma period = %d ps, clock = %d kHz\n",
                sa1100fb_display_dma_period(var),
                cpufreq_get(smp_processor_id()));
 #endif
@@ -655,22 +421,10 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
        return 0;
 }
 
-static inline void sa1100fb_set_truecolor(u_int is_true_color)
+static void sa1100fb_set_visual(struct sa1100fb_info *fbi, u32 visual)
 {
-       if (machine_is_assabet()) {
-#if 1          // phase 4 or newer Assabet's
-               if (is_true_color)
-                       ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
-               else
-                       ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
-#else
-               // older Assabet's
-               if (is_true_color)
-                       ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
-               else
-                       ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
-#endif
-       }
+       if (fbi->inf->set_visual)
+               fbi->inf->set_visual(visual);
 }
 
 /*
@@ -683,11 +437,11 @@ static int sa1100fb_set_par(struct fb_info *info)
        struct fb_var_screeninfo *var = &info->var;
        unsigned long palette_mem_size;
 
-       DPRINTK("set_par\n");
+       dev_dbg(fbi->dev, "set_par\n");
 
        if (var->bits_per_pixel == 16)
                fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR;
-       else if (!fbi->cmap_static)
+       else if (!fbi->inf->cmap_static)
                fbi->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
        else {
                /*
@@ -704,7 +458,7 @@ static int sa1100fb_set_par(struct fb_info *info)
 
        palette_mem_size = fbi->palette_size * sizeof(u16);
 
-       DPRINTK("palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size);
+       dev_dbg(fbi->dev, "palette_mem_size = 0x%08lx\n", palette_mem_size);
 
        fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size);
        fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size;
@@ -712,7 +466,7 @@ static int sa1100fb_set_par(struct fb_info *info)
        /*
         * Set (any) board control register to handle new color depth
         */
-       sa1100fb_set_truecolor(fbi->fb.fix.visual == FB_VISUAL_TRUECOLOR);
+       sa1100fb_set_visual(fbi, fbi->fb.fix.visual);
        sa1100fb_activate_var(var, fbi);
 
        return 0;
@@ -728,7 +482,7 @@ sa1100fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
        /*
         * Make sure the user isn't doing something stupid.
         */
-       if (!kspc && (fbi->fb.var.bits_per_pixel == 16 || fbi->cmap_static))
+       if (!kspc && (fbi->fb.var.bits_per_pixel == 16 || fbi->inf->cmap_static))
                return -EINVAL;
 
        return gen_set_cmap(cmap, kspc, con, info);
@@ -775,7 +529,7 @@ static int sa1100fb_blank(int blank, struct fb_info *info)
        struct sa1100fb_info *fbi = (struct sa1100fb_info *)info;
        int i;
 
-       DPRINTK("sa1100fb_blank: blank=%d\n", blank);
+       dev_dbg(fbi->dev, "sa1100fb_blank: blank=%d\n", blank);
 
        switch (blank) {
        case FB_BLANK_POWERDOWN:
@@ -863,43 +617,43 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
        u_int half_screen_size, yres, pcd;
        u_long flags;
 
-       DPRINTK("Configuring SA1100 LCD\n");
+       dev_dbg(fbi->dev, "Configuring SA1100 LCD\n");
 
-       DPRINTK("var: xres=%d hslen=%d lm=%d rm=%d\n",
+       dev_dbg(fbi->dev, "var: xres=%d hslen=%d lm=%d rm=%d\n",
                var->xres, var->hsync_len,
                var->left_margin, var->right_margin);
-       DPRINTK("var: yres=%d vslen=%d um=%d bm=%d\n",
+       dev_dbg(fbi->dev, "var: yres=%d vslen=%d um=%d bm=%d\n",
                var->yres, var->vsync_len,
                var->upper_margin, var->lower_margin);
 
 #if DEBUG_VAR
        if (var->xres < 16        || var->xres > 1024)
-               printk(KERN_ERR "%s: invalid xres %d\n",
+               dev_err(fbi->dev, "%s: invalid xres %d\n",
                        fbi->fb.fix.id, var->xres);
        if (var->hsync_len < 1    || var->hsync_len > 64)
-               printk(KERN_ERR "%s: invalid hsync_len %d\n",
+               dev_err(fbi->dev, "%s: invalid hsync_len %d\n",
                        fbi->fb.fix.id, var->hsync_len);
        if (var->left_margin < 1  || var->left_margin > 255)
-               printk(KERN_ERR "%s: invalid left_margin %d\n",
+               dev_err(fbi->dev, "%s: invalid left_margin %d\n",
                        fbi->fb.fix.id, var->left_margin);
        if (var->right_margin < 1 || var->right_margin > 255)
-               printk(KERN_ERR "%s: invalid right_margin %d\n",
+               dev_err(fbi->dev, "%s: invalid right_margin %d\n",
                        fbi->fb.fix.id, var->right_margin);
        if (var->yres < 1         || var->yres > 1024)
-               printk(KERN_ERR "%s: invalid yres %d\n",
+               dev_err(fbi->dev, "%s: invalid yres %d\n",
                        fbi->fb.fix.id, var->yres);
        if (var->vsync_len < 1    || var->vsync_len > 64)
-               printk(KERN_ERR "%s: invalid vsync_len %d\n",
+               dev_err(fbi->dev, "%s: invalid vsync_len %d\n",
                        fbi->fb.fix.id, var->vsync_len);
        if (var->upper_margin < 0 || var->upper_margin > 255)
-               printk(KERN_ERR "%s: invalid upper_margin %d\n",
+               dev_err(fbi->dev, "%s: invalid upper_margin %d\n",
                        fbi->fb.fix.id, var->upper_margin);
        if (var->lower_margin < 0 || var->lower_margin > 255)
-               printk(KERN_ERR "%s: invalid lower_margin %d\n",
+               dev_err(fbi->dev, "%s: invalid lower_margin %d\n",
                        fbi->fb.fix.id, var->lower_margin);
 #endif
 
-       new_regs.lccr0 = fbi->lccr0 |
+       new_regs.lccr0 = fbi->inf->lccr0 |
                LCCR0_LEN | LCCR0_LDM | LCCR0_BAM |
                LCCR0_ERM | LCCR0_LtlEnd | LCCR0_DMADel(0);
 
@@ -914,7 +668,7 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
         * the YRES parameter.
         */
        yres = var->yres;
-       if (fbi->lccr0 & LCCR0_Dual)
+       if (fbi->inf->lccr0 & LCCR0_Dual)
                yres /= 2;
 
        new_regs.lccr2 =
@@ -924,14 +678,14 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
                LCCR2_EndFrmDel(var->lower_margin);
 
        pcd = get_pcd(var->pixclock, cpufreq_get(0));
-       new_regs.lccr3 = LCCR3_PixClkDiv(pcd) | fbi->lccr3 |
+       new_regs.lccr3 = LCCR3_PixClkDiv(pcd) | fbi->inf->lccr3 |
                (var->sync & FB_SYNC_HOR_HIGH_ACT ? LCCR3_HorSnchH : LCCR3_HorSnchL) |
                (var->sync & FB_SYNC_VERT_HIGH_ACT ? LCCR3_VrtSnchH : LCCR3_VrtSnchL);
 
-       DPRINTK("nlccr0 = 0x%08lx\n", new_regs.lccr0);
-       DPRINTK("nlccr1 = 0x%08lx\n", new_regs.lccr1);
-       DPRINTK("nlccr2 = 0x%08lx\n", new_regs.lccr2);
-       DPRINTK("nlccr3 = 0x%08lx\n", new_regs.lccr3);
+       dev_dbg(fbi->dev, "nlccr0 = 0x%08lx\n", new_regs.lccr0);
+       dev_dbg(fbi->dev, "nlccr1 = 0x%08lx\n", new_regs.lccr1);
+       dev_dbg(fbi->dev, "nlccr2 = 0x%08lx\n", new_regs.lccr2);
+       dev_dbg(fbi->dev, "nlccr3 = 0x%08lx\n", new_regs.lccr3);
 
        half_screen_size = var->bits_per_pixel;
        half_screen_size = half_screen_size * var->xres * var->yres / 16;
@@ -951,9 +705,12 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
         * Only update the registers if the controller is enabled
         * and something has changed.
         */
-       if ((LCCR0 != fbi->reg_lccr0)       || (LCCR1 != fbi->reg_lccr1) ||
-           (LCCR2 != fbi->reg_lccr2)       || (LCCR3 != fbi->reg_lccr3) ||
-           (DBAR1 != fbi->dbar1) || (DBAR2 != fbi->dbar2))
+       if (readl_relaxed(fbi->base + LCCR0) != fbi->reg_lccr0 ||
+           readl_relaxed(fbi->base + LCCR1) != fbi->reg_lccr1 ||
+           readl_relaxed(fbi->base + LCCR2) != fbi->reg_lccr2 ||
+           readl_relaxed(fbi->base + LCCR3) != fbi->reg_lccr3 ||
+           readl_relaxed(fbi->base + DBAR1) != fbi->dbar1 ||
+           readl_relaxed(fbi->base + DBAR2) != fbi->dbar2)
                sa1100fb_schedule_work(fbi, C_REENABLE);
 
        return 0;
@@ -967,18 +724,18 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
  */
 static inline void __sa1100fb_backlight_power(struct sa1100fb_info *fbi, int on)
 {
-       DPRINTK("backlight o%s\n", on ? "n" : "ff");
+       dev_dbg(fbi->dev, "backlight o%s\n", on ? "n" : "ff");
 
-       if (sa1100fb_backlight_power)
-               sa1100fb_backlight_power(on);
+       if (fbi->inf->backlight_power)
+               fbi->inf->backlight_power(on);
 }
 
 static inline void __sa1100fb_lcd_power(struct sa1100fb_info *fbi, int on)
 {
-       DPRINTK("LCD power o%s\n", on ? "n" : "ff");
+       dev_dbg(fbi->dev, "LCD power o%s\n", on ? "n" : "ff");
 
-       if (sa1100fb_lcd_power)
-               sa1100fb_lcd_power(on);
+       if (fbi->inf->lcd_power)
+               fbi->inf->lcd_power(on);
 }
 
 static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi)
@@ -1008,14 +765,25 @@ static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi)
        }
 
        if (mask) {
+               unsigned long flags;
+
+               /*
+                * SA-1100 requires the GPIO direction register set
+                * appropriately for the alternate function.  Hence
+                * we set it here via bitmask rather than excessive
+                * fiddling via the GPIO subsystem - and even then
+                * we'll still have to deal with GAFR.
+                */
+               local_irq_save(flags);
                GPDR |= mask;
                GAFR |= mask;
+               local_irq_restore(flags);
        }
 }
 
 static void sa1100fb_enable_controller(struct sa1100fb_info *fbi)
 {
-       DPRINTK("Enabling LCD controller\n");
+       dev_dbg(fbi->dev, "Enabling LCD controller\n");
 
        /*
         * Make sure the mode bits are present in the first palette entry
@@ -1024,43 +792,46 @@ static void sa1100fb_enable_controller(struct sa1100fb_info *fbi)
        fbi->palette_cpu[0] |= palette_pbs(&fbi->fb.var);
 
        /* Sequence from 11.7.10 */
-       LCCR3 = fbi->reg_lccr3;
-       LCCR2 = fbi->reg_lccr2;
-       LCCR1 = fbi->reg_lccr1;
-       LCCR0 = fbi->reg_lccr0 & ~LCCR0_LEN;
-       DBAR1 = fbi->dbar1;
-       DBAR2 = fbi->dbar2;
-       LCCR0 |= LCCR0_LEN;
-
-       if (machine_is_shannon()) {
-               GPDR |= SHANNON_GPIO_DISP_EN;
-               GPSR |= SHANNON_GPIO_DISP_EN;
-       }
-
-       DPRINTK("DBAR1 = 0x%08x\n", DBAR1);
-       DPRINTK("DBAR2 = 0x%08x\n", DBAR2);
-       DPRINTK("LCCR0 = 0x%08x\n", LCCR0);
-       DPRINTK("LCCR1 = 0x%08x\n", LCCR1);
-       DPRINTK("LCCR2 = 0x%08x\n", LCCR2);
-       DPRINTK("LCCR3 = 0x%08x\n", LCCR3);
+       writel_relaxed(fbi->reg_lccr3, fbi->base + LCCR3);
+       writel_relaxed(fbi->reg_lccr2, fbi->base + LCCR2);
+       writel_relaxed(fbi->reg_lccr1, fbi->base + LCCR1);
+       writel_relaxed(fbi->reg_lccr0 & ~LCCR0_LEN, fbi->base + LCCR0);
+       writel_relaxed(fbi->dbar1, fbi->base + DBAR1);
+       writel_relaxed(fbi->dbar2, fbi->base + DBAR2);
+       writel_relaxed(fbi->reg_lccr0 | LCCR0_LEN, fbi->base + LCCR0);
+
+       if (machine_is_shannon())
+               gpio_set_value(SHANNON_GPIO_DISP_EN, 1);
+
+       dev_dbg(fbi->dev, "DBAR1: 0x%08x\n", readl_relaxed(fbi->base + DBAR1));
+       dev_dbg(fbi->dev, "DBAR2: 0x%08x\n", readl_relaxed(fbi->base + DBAR2));
+       dev_dbg(fbi->dev, "LCCR0: 0x%08x\n", readl_relaxed(fbi->base + LCCR0));
+       dev_dbg(fbi->dev, "LCCR1: 0x%08x\n", readl_relaxed(fbi->base + LCCR1));
+       dev_dbg(fbi->dev, "LCCR2: 0x%08x\n", readl_relaxed(fbi->base + LCCR2));
+       dev_dbg(fbi->dev, "LCCR3: 0x%08x\n", readl_relaxed(fbi->base + LCCR3));
 }
 
 static void sa1100fb_disable_controller(struct sa1100fb_info *fbi)
 {
        DECLARE_WAITQUEUE(wait, current);
+       u32 lccr0;
 
-       DPRINTK("Disabling LCD controller\n");
+       dev_dbg(fbi->dev, "Disabling LCD controller\n");
 
-       if (machine_is_shannon()) {
-               GPCR |= SHANNON_GPIO_DISP_EN;
-       }       
+       if (machine_is_shannon())
+               gpio_set_value(SHANNON_GPIO_DISP_EN, 0);
 
        set_current_state(TASK_UNINTERRUPTIBLE);
        add_wait_queue(&fbi->ctrlr_wait, &wait);
 
-       LCSR = 0xffffffff;      /* Clear LCD Status Register */
-       LCCR0 &= ~LCCR0_LDM;    /* Enable LCD Disable Done Interrupt */
-       LCCR0 &= ~LCCR0_LEN;    /* Disable LCD Controller */
+       /* Clear LCD Status Register */
+       writel_relaxed(~0, fbi->base + LCSR);
+
+       lccr0 = readl_relaxed(fbi->base + LCCR0);
+       lccr0 &= ~LCCR0_LDM;    /* Enable LCD Disable Done Interrupt */
+       writel_relaxed(lccr0, fbi->base + LCCR0);
+       lccr0 &= ~LCCR0_LEN;    /* Disable LCD Controller */
+       writel_relaxed(lccr0, fbi->base + LCCR0);
 
        schedule_timeout(20 * HZ / 1000);
        remove_wait_queue(&fbi->ctrlr_wait, &wait);
@@ -1072,14 +843,15 @@ static void sa1100fb_disable_controller(struct sa1100fb_info *fbi)
 static irqreturn_t sa1100fb_handle_irq(int irq, void *dev_id)
 {
        struct sa1100fb_info *fbi = dev_id;
-       unsigned int lcsr = LCSR;
+       unsigned int lcsr = readl_relaxed(fbi->base + LCSR);
 
        if (lcsr & LCSR_LDD) {
-               LCCR0 |= LCCR0_LDM;
+               u32 lccr0 = readl_relaxed(fbi->base + LCCR0) | LCCR0_LDM;
+               writel_relaxed(lccr0, fbi->base + LCCR0);
                wake_up(&fbi->ctrlr_wait);
        }
 
-       LCSR = lcsr;
+       writel_relaxed(lcsr, fbi->base + LCSR);
        return IRQ_HANDLED;
 }
 
@@ -1268,7 +1040,7 @@ sa1100fb_freq_policy(struct notifier_block *nb, unsigned long val,
        switch (val) {
        case CPUFREQ_ADJUST:
        case CPUFREQ_INCOMPATIBLE:
-               printk(KERN_DEBUG "min dma period: %d ps, "
+               dev_dbg(fbi->dev, "min dma period: %d ps, "
                        "new clock %d kHz\n", sa1100fb_min_dma_period(fbi),
                        policy->max);
                /* todo: fill in min/max values */
@@ -1318,7 +1090,7 @@ static int sa1100fb_resume(struct platform_device *dev)
  *      cache.  Once this area is remapped, all virtual memory
  *      access to the video memory should occur at the new region.
  */
-static int __init sa1100fb_map_video_memory(struct sa1100fb_info *fbi)
+static int __devinit sa1100fb_map_video_memory(struct sa1100fb_info *fbi)
 {
        /*
         * We reserve one page for the palette, plus the size
@@ -1344,7 +1116,7 @@ static int __init sa1100fb_map_video_memory(struct sa1100fb_info *fbi)
 }
 
 /* Fake monspecs to fill in fbinfo structure */
-static struct fb_monspecs monspecs __initdata = {
+static struct fb_monspecs monspecs __devinitdata = {
        .hfmin  = 30000,
        .hfmax  = 70000,
        .vfmin  = 50,
@@ -1352,10 +1124,11 @@ static struct fb_monspecs monspecs __initdata = {
 };
 
 
-static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
+static struct sa1100fb_info * __devinit sa1100fb_init_fbinfo(struct device *dev)
 {
-       struct sa1100fb_mach_info *inf;
+       struct sa1100fb_mach_info *inf = dev->platform_data;
        struct sa1100fb_info *fbi;
+       unsigned i;
 
        fbi = kmalloc(sizeof(struct sa1100fb_info) + sizeof(u32) * 16,
                      GFP_KERNEL);
@@ -1390,8 +1163,6 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
        fbi->rgb[RGB_8]         = &rgb_8;
        fbi->rgb[RGB_16]        = &def_rgb_16;
 
-       inf = sa1100fb_get_machine_info(fbi);
-
        /*
         * People just don't seem to get this.  We don't support
         * anything but correct entries now, so panic if someone
@@ -1402,13 +1173,10 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
                panic("sa1100fb error: invalid LCCR3 fields set or zero "
                        "pixclock.");
 
-       fbi->max_xres                   = inf->xres;
        fbi->fb.var.xres                = inf->xres;
        fbi->fb.var.xres_virtual        = inf->xres;
-       fbi->max_yres                   = inf->yres;
        fbi->fb.var.yres                = inf->yres;
        fbi->fb.var.yres_virtual        = inf->yres;
-       fbi->max_bpp                    = inf->bpp;
        fbi->fb.var.bits_per_pixel      = inf->bpp;
        fbi->fb.var.pixclock            = inf->pixclock;
        fbi->fb.var.hsync_len           = inf->hsync_len;
@@ -1419,14 +1187,16 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
        fbi->fb.var.lower_margin        = inf->lower_margin;
        fbi->fb.var.sync                = inf->sync;
        fbi->fb.var.grayscale           = inf->cmap_greyscale;
-       fbi->cmap_inverse               = inf->cmap_inverse;
-       fbi->cmap_static                = inf->cmap_static;
-       fbi->lccr0                      = inf->lccr0;
-       fbi->lccr3                      = inf->lccr3;
        fbi->state                      = C_STARTUP;
        fbi->task_state                 = (u_char)-1;
-       fbi->fb.fix.smem_len            = fbi->max_xres * fbi->max_yres *
-                                         fbi->max_bpp / 8;
+       fbi->fb.fix.smem_len            = inf->xres * inf->yres *
+                                         inf->bpp / 8;
+       fbi->inf                        = inf;
+
+       /* Copy the RGB bitfield overrides */
+       for (i = 0; i < NR_RGB; i++)
+               if (inf->rgb[i])
+                       fbi->rgb[i] = inf->rgb[i];
 
        init_waitqueue_head(&fbi->ctrlr_wait);
        INIT_WORK(&fbi->task, sa1100fb_task);
@@ -1438,13 +1208,20 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
 static int __devinit sa1100fb_probe(struct platform_device *pdev)
 {
        struct sa1100fb_info *fbi;
+       struct resource *res;
        int ret, irq;
 
+       if (!pdev->dev.platform_data) {
+               dev_err(&pdev->dev, "no platform LCD data\n");
+               return -EINVAL;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        irq = platform_get_irq(pdev, 0);
-       if (irq < 0)
+       if (irq < 0 || !res)
                return -EINVAL;
 
-       if (!request_mem_region(0xb0100000, 0x10000, "LCD"))
+       if (!request_mem_region(res->start, resource_size(res), "LCD"))
                return -EBUSY;
 
        fbi = sa1100fb_init_fbinfo(&pdev->dev);
@@ -1452,6 +1229,10 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev)
        if (!fbi)
                goto failed;
 
+       fbi->base = ioremap(res->start, resource_size(res));
+       if (!fbi->base)
+               goto failed;
+
        /* Initialize video memory */
        ret = sa1100fb_map_video_memory(fbi);
        if (ret)
@@ -1459,14 +1240,16 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev)
 
        ret = request_irq(irq, sa1100fb_handle_irq, 0, "LCD", fbi);
        if (ret) {
-               printk(KERN_ERR "sa1100fb: request_irq failed: %d\n", ret);
+               dev_err(&pdev->dev, "request_irq failed: %d\n", ret);
                goto failed;
        }
 
-#ifdef ASSABET_PAL_VIDEO
-       if (machine_is_assabet())
-               ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
-#endif
+       if (machine_is_shannon()) {
+               ret = gpio_request_one(SHANNON_GPIO_DISP_EN,
+                       GPIOF_OUT_INIT_LOW, "display enable");
+               if (ret)
+                       goto err_free_irq;
+       }
 
        /*
         * This makes sure that our colour bitfield
@@ -1478,7 +1261,7 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev)
 
        ret = register_framebuffer(&fbi->fb);
        if (ret < 0)
-               goto err_free_irq;
+               goto err_reg_fb;
 
 #ifdef CONFIG_CPU_FREQ
        fbi->freq_transition.notifier_call = sa1100fb_freq_transition;
@@ -1490,12 +1273,17 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev)
        /* This driver cannot be unloaded at the moment */
        return 0;
 
+ err_reg_fb:
+       if (machine_is_shannon())
+               gpio_free(SHANNON_GPIO_DISP_EN);
  err_free_irq:
        free_irq(irq, fbi);
  failed:
+       if (fbi)
+               iounmap(fbi->base);
        platform_set_drvdata(pdev, NULL);
        kfree(fbi);
-       release_mem_region(0xb0100000, 0x10000);
+       release_mem_region(res->start, resource_size(res));
        return ret;
 }
 
@@ -1505,6 +1293,7 @@ static struct platform_driver sa1100fb_driver = {
        .resume         = sa1100fb_resume,
        .driver         = {
                .name   = "sa11x0-fb",
+               .owner  = THIS_MODULE,
        },
 };
 
index 1c3b459865d85fa6460e4db523056b56338ebefe..fc5d4292fad662fe7911032103ab5c22f335b71f 100644 (file)
  * for more details.
  */
 
-/*
- * These are the bitfields for each
- * display depth that we support.
- */
-struct sa1100fb_rgb {
-       struct fb_bitfield      red;
-       struct fb_bitfield      green;
-       struct fb_bitfield      blue;
-       struct fb_bitfield      transp;
-};
-
-/*
- * This structure describes the machine which we are running on.
- */
-struct sa1100fb_mach_info {
-       u_long          pixclock;
-
-       u_short         xres;
-       u_short         yres;
-
-       u_char          bpp;
-       u_char          hsync_len;
-       u_char          left_margin;
-       u_char          right_margin;
-
-       u_char          vsync_len;
-       u_char          upper_margin;
-       u_char          lower_margin;
-       u_char          sync;
-
-       u_int           cmap_greyscale:1,
-                       cmap_inverse:1,
-                       cmap_static:1,
-                       unused:29;
-
-       u_int           lccr0;
-       u_int           lccr3;
-};
+#define LCCR0           0x0000          /* LCD Control Reg. 0 */
+#define LCSR            0x0004          /* LCD Status Reg. */
+#define DBAR1           0x0010          /* LCD DMA Base Address Reg. channel 1 */
+#define DCAR1           0x0014          /* LCD DMA Current Address Reg. channel 1 */
+#define DBAR2           0x0018          /* LCD DMA Base Address Reg.  channel 2 */
+#define DCAR2           0x001C          /* LCD DMA Current Address Reg. channel 2 */
+#define LCCR1           0x0020          /* LCD Control Reg. 1 */
+#define LCCR2           0x0024          /* LCD Control Reg. 2 */
+#define LCCR3           0x0028          /* LCD Control Reg. 3 */
 
 /* Shadows for LCD controller registers */
 struct sa1100fb_lcd_reg {
@@ -57,19 +28,11 @@ struct sa1100fb_lcd_reg {
        unsigned long lccr3;
 };
 
-#define RGB_4  (0)
-#define RGB_8  (1)
-#define RGB_16 (2)
-#define NR_RGB 3
-
 struct sa1100fb_info {
        struct fb_info          fb;
        struct device           *dev;
-       struct sa1100fb_rgb     *rgb[NR_RGB];
-
-       u_int                   max_bpp;
-       u_int                   max_xres;
-       u_int                   max_yres;
+       const struct sa1100fb_rgb *rgb[NR_RGB];
+       void __iomem            *base;
 
        /*
         * These are the addresses we mapped
@@ -88,12 +51,6 @@ struct sa1100fb_info {
        dma_addr_t              dbar1;
        dma_addr_t              dbar2;
 
-       u_int                   lccr0;
-       u_int                   lccr3;
-       u_int                   cmap_inverse:1,
-                               cmap_static:1,
-                               unused:30;
-
        u_int                   reg_lccr0;
        u_int                   reg_lccr1;
        u_int                   reg_lccr2;
@@ -109,6 +66,8 @@ struct sa1100fb_info {
        struct notifier_block   freq_transition;
        struct notifier_block   freq_policy;
 #endif
+
+       const struct sa1100fb_mach_info *inf;
 };
 
 #define TO_INF(ptr,member)     container_of(ptr,struct sa1100fb_info,member)
@@ -129,15 +88,6 @@ struct sa1100fb_info {
 
 #define SA1100_NAME    "SA1100"
 
-/*
- *  Debug macros 
- */
-#if DEBUG
-#  define DPRINTK(fmt, args...)        printk("%s: " fmt, __func__ , ## args)
-#else
-#  define DPRINTK(fmt, args...)
-#endif
-
 /*
  * Minimum X and Y resolutions
  */
index 5d8cd69e191ac918261071721c11f855b4701955..37096246c93716ef314ad9fc4f519124cbc7456f 100644 (file)
@@ -172,7 +172,7 @@ config HAVE_S3C2410_WATCHDOG
 
 config S3C2410_WATCHDOG
        tristate "S3C2410 Watchdog"
-       depends on ARCH_S3C2410 || HAVE_S3C2410_WATCHDOG
+       depends on HAVE_S3C2410_WATCHDOG
        select WATCHDOG_CORE
        help
          Watchdog timer block in the Samsung SoCs. This will reboot
index ad12c20304414a0814348a72b5ac23e4ed50d2de..7ef99a169e3bbaf6e433abe4a7591b576a35ad75 100644 (file)
@@ -53,7 +53,7 @@ static unsigned long at91wdt_busy;
  */
 static inline void at91_wdt_stop(void)
 {
-       at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN);
+       at91_st_write(AT91_ST_WDMR, AT91_ST_EXTEN);
 }
 
 /*
@@ -61,9 +61,9 @@ static inline void at91_wdt_stop(void)
  */
 static inline void at91_wdt_start(void)
 {
-       at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN |
+       at91_st_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN |
                                (((65536 * wdt_time) >> 8) & AT91_ST_WDV));
-       at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
+       at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
 }
 
 /*
@@ -71,7 +71,7 @@ static inline void at91_wdt_start(void)
  */
 static inline void at91_wdt_reload(void)
 {
-       at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
+       at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
 }
 
 /* ......................................................................... */
index 173ddf1ba004b574c31a1a13c2c72a8ffabb9ac3..788aa158e78c054eef91dabae21de96fa3e20d32 100644 (file)
@@ -30,9 +30,9 @@
 /*
  * Watchdog timer block registers.
  */
-#define TIMER_CTRL             (TIMER_VIRT_BASE + 0x0000)
+#define TIMER_CTRL             0x0000
 #define  WDT_EN                        0x0010
-#define WDT_VAL                        (TIMER_VIRT_BASE + 0x0024)
+#define WDT_VAL                        0x0024
 
 #define WDT_MAX_CYCLE_COUNT    0xffffffff
 #define WDT_IN_USE             0
@@ -42,6 +42,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT;
 static int heartbeat = -1;             /* module parameter (seconds) */
 static unsigned int wdt_max_duration;  /* (seconds) */
 static unsigned int wdt_tclk;
+static void __iomem *wdt_reg;
 static unsigned long wdt_status;
 static DEFINE_SPINLOCK(wdt_lock);
 
@@ -50,7 +51,7 @@ static void orion_wdt_ping(void)
        spin_lock(&wdt_lock);
 
        /* Reload watchdog duration */
-       writel(wdt_tclk * heartbeat, WDT_VAL);
+       writel(wdt_tclk * heartbeat, wdt_reg + WDT_VAL);
 
        spin_unlock(&wdt_lock);
 }
@@ -62,7 +63,7 @@ static void orion_wdt_enable(void)
        spin_lock(&wdt_lock);
 
        /* Set watchdog duration */
-       writel(wdt_tclk * heartbeat, WDT_VAL);
+       writel(wdt_tclk * heartbeat, wdt_reg + WDT_VAL);
 
        /* Clear watchdog timer interrupt */
        reg = readl(BRIDGE_CAUSE);
@@ -70,9 +71,9 @@ static void orion_wdt_enable(void)
        writel(reg, BRIDGE_CAUSE);
 
        /* Enable watchdog timer */
-       reg = readl(TIMER_CTRL);
+       reg = readl(wdt_reg + TIMER_CTRL);
        reg |= WDT_EN;
-       writel(reg, TIMER_CTRL);
+       writel(reg, wdt_reg + TIMER_CTRL);
 
        /* Enable reset on watchdog */
        reg = readl(RSTOUTn_MASK);
@@ -94,9 +95,9 @@ static void orion_wdt_disable(void)
        writel(reg, RSTOUTn_MASK);
 
        /* Disable watchdog timer */
-       reg = readl(TIMER_CTRL);
+       reg = readl(wdt_reg + TIMER_CTRL);
        reg &= ~WDT_EN;
-       writel(reg, TIMER_CTRL);
+       writel(reg, wdt_reg + TIMER_CTRL);
 
        spin_unlock(&wdt_lock);
 }
@@ -104,7 +105,7 @@ static void orion_wdt_disable(void)
 static int orion_wdt_get_timeleft(int *time_left)
 {
        spin_lock(&wdt_lock);
-       *time_left = readl(WDT_VAL) / wdt_tclk;
+       *time_left = readl(wdt_reg + WDT_VAL) / wdt_tclk;
        spin_unlock(&wdt_lock);
        return 0;
 }
@@ -237,6 +238,7 @@ static struct miscdevice orion_wdt_miscdev = {
 static int __devinit orion_wdt_probe(struct platform_device *pdev)
 {
        struct orion_wdt_platform_data *pdata = pdev->dev.platform_data;
+       struct resource *res;
        int ret;
 
        if (pdata) {
@@ -246,6 +248,10 @@ static int __devinit orion_wdt_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       wdt_reg = ioremap(res->start, resource_size(res));
+
        if (orion_wdt_miscdev.parent)
                return -EBUSY;
        orion_wdt_miscdev.parent = &pdev->dev;
index 10b7d3c9dba8541cab1794224e866765b1c928a5..8c92a9ba83306576ef45f4abe217b92954d4c05e 100644 (file)
@@ -259,7 +259,7 @@ static int v9fs_statfs(struct dentry *dentry, struct kstatfs *buf)
        if (v9fs_proto_dotl(v9ses)) {
                res = p9_client_statfs(fid, &rs);
                if (res == 0) {
-                       buf->f_type = V9FS_MAGIC;
+                       buf->f_type = rs.type;
                        buf->f_bsize = rs.bsize;
                        buf->f_blocks = rs.blocks;
                        buf->f_bfree = rs.bfree;
index 2c489378b4cd6b470d06ecc9f3c60fc67ea6e1cf..9fff9f3b17e4a5206a9073cec2be714fba44bda0 100644 (file)
@@ -677,18 +677,19 @@ static int fill_inode(struct inode *inode,
        case S_IFLNK:
                inode->i_op = &ceph_symlink_iops;
                if (!ci->i_symlink) {
-                       int symlen = iinfo->symlink_len;
+                       u32 symlen = iinfo->symlink_len;
                        char *sym;
 
-                       BUG_ON(symlen != inode->i_size);
                        spin_unlock(&ci->i_ceph_lock);
 
+                       err = -EINVAL;
+                       if (WARN_ON(symlen != inode->i_size))
+                               goto out;
+
                        err = -ENOMEM;
-                       sym = kmalloc(symlen+1, GFP_NOFS);
+                       sym = kstrndup(iinfo->symlink, symlen, GFP_NOFS);
                        if (!sym)
                                goto out;
-                       memcpy(sym, iinfo->symlink, symlen);
-                       sym[symlen] = 0;
 
                        spin_lock(&ci->i_ceph_lock);
                        if (!ci->i_symlink)
index 866e8d7ca37d7343fe7c30cc5e036cb5d6b9494e..89971e137aab80454fed8a51a105d7df903b3101 100644 (file)
@@ -402,7 +402,7 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc,
 
        spin_lock_init(&s->s_gen_ttl_lock);
        s->s_cap_gen = 0;
-       s->s_cap_ttl = 0;
+       s->s_cap_ttl = jiffies - 1;
 
        spin_lock_init(&s->s_cap_lock);
        s->s_renew_requested = 0;
@@ -1083,8 +1083,7 @@ static void renewed_caps(struct ceph_mds_client *mdsc,
        int wake = 0;
 
        spin_lock(&session->s_cap_lock);
-       was_stale = is_renew && (session->s_cap_ttl == 0 ||
-                                time_after_eq(jiffies, session->s_cap_ttl));
+       was_stale = is_renew && time_after_eq(jiffies, session->s_cap_ttl);
 
        session->s_cap_ttl = session->s_renew_requested +
                mdsc->mdsmap->m_session_timeout*HZ;
@@ -2332,7 +2331,7 @@ static void handle_session(struct ceph_mds_session *session,
                        session->s_mds);
                spin_lock(&session->s_gen_ttl_lock);
                session->s_cap_gen++;
-               session->s_cap_ttl = 0;
+               session->s_cap_ttl = jiffies - 1;
                spin_unlock(&session->s_gen_ttl_lock);
                send_renew_caps(mdsc, session);
                break;
index a559c80f127a04353a488181029744a009165f09..f04c0961f9937eb6f553978f10942800818528ba 100644 (file)
@@ -331,7 +331,7 @@ static int build_snap_context(struct ceph_snap_realm *realm)
 
        /* alloc new snap context */
        err = -ENOMEM;
-       if (num > ULONG_MAX / sizeof(u64) - sizeof(*snapc))
+       if (num > (ULONG_MAX - sizeof(*snapc)) / sizeof(u64))
                goto fail;
        snapc = kzalloc(sizeof(*snapc) + num*sizeof(u64), GFP_NOFS);
        if (!snapc)
index 256f852219261e66984384fe19bb7182bf8dd50a..1e67dd7305a4e8596a3c5f609ccea2a866e4e31a 100644 (file)
@@ -130,10 +130,12 @@ enum {
        Opt_nodirstat,
        Opt_rbytes,
        Opt_norbytes,
+       Opt_asyncreaddir,
        Opt_noasyncreaddir,
        Opt_dcache,
        Opt_nodcache,
        Opt_ino32,
+       Opt_noino32,
 };
 
 static match_table_t fsopt_tokens = {
@@ -153,10 +155,12 @@ static match_table_t fsopt_tokens = {
        {Opt_nodirstat, "nodirstat"},
        {Opt_rbytes, "rbytes"},
        {Opt_norbytes, "norbytes"},
+       {Opt_asyncreaddir, "asyncreaddir"},
        {Opt_noasyncreaddir, "noasyncreaddir"},
        {Opt_dcache, "dcache"},
        {Opt_nodcache, "nodcache"},
        {Opt_ino32, "ino32"},
+       {Opt_noino32, "noino32"},
        {-1, NULL}
 };
 
@@ -232,6 +236,9 @@ static int parse_fsopt_token(char *c, void *private)
        case Opt_norbytes:
                fsopt->flags &= ~CEPH_MOUNT_OPT_RBYTES;
                break;
+       case Opt_asyncreaddir:
+               fsopt->flags &= ~CEPH_MOUNT_OPT_NOASYNCREADDIR;
+               break;
        case Opt_noasyncreaddir:
                fsopt->flags |= CEPH_MOUNT_OPT_NOASYNCREADDIR;
                break;
@@ -244,6 +251,9 @@ static int parse_fsopt_token(char *c, void *private)
        case Opt_ino32:
                fsopt->flags |= CEPH_MOUNT_OPT_INO32;
                break;
+       case Opt_noino32:
+               fsopt->flags &= ~CEPH_MOUNT_OPT_INO32;
+               break;
        default:
                BUG_ON(token);
        }
@@ -334,10 +344,12 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt,
        *path += 2;
        dout("server path '%s'\n", *path);
 
-       err = ceph_parse_options(popt, options, dev_name, dev_name_end,
+       *popt = ceph_parse_options(options, dev_name, dev_name_end,
                                 parse_fsopt_token, (void *)fsopt);
-       if (err)
+       if (IS_ERR(*popt)) {
+               err = PTR_ERR(*popt);
                goto out;
+       }
 
        /* success */
        *pfsopt = fsopt;
@@ -926,6 +938,7 @@ static int __init init_ceph(void)
        if (ret)
                goto out;
 
+       ceph_xattr_init();
        ret = register_filesystem(&ceph_fs_type);
        if (ret)
                goto out_icache;
@@ -935,6 +948,7 @@ static int __init init_ceph(void)
        return 0;
 
 out_icache:
+       ceph_xattr_exit();
        destroy_caches();
 out:
        return ret;
@@ -944,6 +958,7 @@ static void __exit exit_ceph(void)
 {
        dout("exit_ceph\n");
        unregister_filesystem(&ceph_fs_type);
+       ceph_xattr_exit();
        destroy_caches();
 }
 
index 1421f3d875a22e34e1449bde4d46327678d114fe..fc35036d258d7b830c37f5cba078f53c53e7d574 100644 (file)
@@ -367,7 +367,7 @@ static inline u32 ceph_ino_to_ino32(__u64 vino)
        u32 ino = vino & 0xffffffff;
        ino ^= vino >> 32;
        if (!ino)
-               ino = 1;
+               ino = 2;
        return ino;
 }
 
@@ -733,6 +733,8 @@ extern ssize_t ceph_listxattr(struct dentry *, char *, size_t);
 extern int ceph_removexattr(struct dentry *, const char *);
 extern void __ceph_build_xattrs_blob(struct ceph_inode_info *ci);
 extern void __ceph_destroy_xattrs(struct ceph_inode_info *ci);
+extern void __init ceph_xattr_init(void);
+extern void ceph_xattr_exit(void);
 
 /* caps.c */
 extern const char *ceph_cap_string(int c);
index a76f697303d9e5db700598fc817008494908bb99..35b86331d8a5ce84c311e9eb2730757f80149179 100644 (file)
@@ -8,9 +8,12 @@
 #include <linux/xattr.h>
 #include <linux/slab.h>
 
+#define XATTR_CEPH_PREFIX "ceph."
+#define XATTR_CEPH_PREFIX_LEN (sizeof (XATTR_CEPH_PREFIX) - 1)
+
 static bool ceph_is_valid_xattr(const char *name)
 {
-       return !strncmp(name, "ceph.", 5) ||
+       return !strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN) ||
               !strncmp(name, XATTR_SECURITY_PREFIX,
                        XATTR_SECURITY_PREFIX_LEN) ||
               !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) ||
@@ -21,79 +24,91 @@ static bool ceph_is_valid_xattr(const char *name)
  * These define virtual xattrs exposing the recursive directory
  * statistics and layout metadata.
  */
-struct ceph_vxattr_cb {
-       bool readonly;
+struct ceph_vxattr {
        char *name;
+       size_t name_size;       /* strlen(name) + 1 (for '\0') */
        size_t (*getxattr_cb)(struct ceph_inode_info *ci, char *val,
                              size_t size);
+       bool readonly;
 };
 
 /* directories */
 
-static size_t ceph_vxattrcb_entries(struct ceph_inode_info *ci, char *val,
+static size_t ceph_vxattrcb_dir_entries(struct ceph_inode_info *ci, char *val,
                                        size_t size)
 {
        return snprintf(val, size, "%lld", ci->i_files + ci->i_subdirs);
 }
 
-static size_t ceph_vxattrcb_files(struct ceph_inode_info *ci, char *val,
+static size_t ceph_vxattrcb_dir_files(struct ceph_inode_info *ci, char *val,
                                      size_t size)
 {
        return snprintf(val, size, "%lld", ci->i_files);
 }
 
-static size_t ceph_vxattrcb_subdirs(struct ceph_inode_info *ci, char *val,
+static size_t ceph_vxattrcb_dir_subdirs(struct ceph_inode_info *ci, char *val,
                                        size_t size)
 {
        return snprintf(val, size, "%lld", ci->i_subdirs);
 }
 
-static size_t ceph_vxattrcb_rentries(struct ceph_inode_info *ci, char *val,
+static size_t ceph_vxattrcb_dir_rentries(struct ceph_inode_info *ci, char *val,
                                         size_t size)
 {
        return snprintf(val, size, "%lld", ci->i_rfiles + ci->i_rsubdirs);
 }
 
-static size_t ceph_vxattrcb_rfiles(struct ceph_inode_info *ci, char *val,
+static size_t ceph_vxattrcb_dir_rfiles(struct ceph_inode_info *ci, char *val,
                                       size_t size)
 {
        return snprintf(val, size, "%lld", ci->i_rfiles);
 }
 
-static size_t ceph_vxattrcb_rsubdirs(struct ceph_inode_info *ci, char *val,
+static size_t ceph_vxattrcb_dir_rsubdirs(struct ceph_inode_info *ci, char *val,
                                         size_t size)
 {
        return snprintf(val, size, "%lld", ci->i_rsubdirs);
 }
 
-static size_t ceph_vxattrcb_rbytes(struct ceph_inode_info *ci, char *val,
+static size_t ceph_vxattrcb_dir_rbytes(struct ceph_inode_info *ci, char *val,
                                       size_t size)
 {
        return snprintf(val, size, "%lld", ci->i_rbytes);
 }
 
-static size_t ceph_vxattrcb_rctime(struct ceph_inode_info *ci, char *val,
+static size_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info *ci, char *val,
                                       size_t size)
 {
-       return snprintf(val, size, "%ld.%ld", (long)ci->i_rctime.tv_sec,
+       return snprintf(val, size, "%ld.09%ld", (long)ci->i_rctime.tv_sec,
                        (long)ci->i_rctime.tv_nsec);
 }
 
-static struct ceph_vxattr_cb ceph_dir_vxattrs[] = {
-       { true, "ceph.dir.entries", ceph_vxattrcb_entries},
-       { true, "ceph.dir.files", ceph_vxattrcb_files},
-       { true, "ceph.dir.subdirs", ceph_vxattrcb_subdirs},
-       { true, "ceph.dir.rentries", ceph_vxattrcb_rentries},
-       { true, "ceph.dir.rfiles", ceph_vxattrcb_rfiles},
-       { true, "ceph.dir.rsubdirs", ceph_vxattrcb_rsubdirs},
-       { true, "ceph.dir.rbytes", ceph_vxattrcb_rbytes},
-       { true, "ceph.dir.rctime", ceph_vxattrcb_rctime},
-       { true, NULL, NULL }
+#define CEPH_XATTR_NAME(_type, _name)  XATTR_CEPH_PREFIX #_type "." #_name
+
+#define XATTR_NAME_CEPH(_type, _name) \
+               { \
+                       .name = CEPH_XATTR_NAME(_type, _name), \
+                       .name_size = sizeof (CEPH_XATTR_NAME(_type, _name)), \
+                       .getxattr_cb = ceph_vxattrcb_ ## _type ## _ ## _name, \
+                       .readonly = true, \
+               }
+
+static struct ceph_vxattr ceph_dir_vxattrs[] = {
+       XATTR_NAME_CEPH(dir, entries),
+       XATTR_NAME_CEPH(dir, files),
+       XATTR_NAME_CEPH(dir, subdirs),
+       XATTR_NAME_CEPH(dir, rentries),
+       XATTR_NAME_CEPH(dir, rfiles),
+       XATTR_NAME_CEPH(dir, rsubdirs),
+       XATTR_NAME_CEPH(dir, rbytes),
+       XATTR_NAME_CEPH(dir, rctime),
+       { 0 }   /* Required table terminator */
 };
+static size_t ceph_dir_vxattrs_name_size;      /* total size of all names */
 
 /* files */
 
-static size_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val,
+static size_t ceph_vxattrcb_file_layout(struct ceph_inode_info *ci, char *val,
                                   size_t size)
 {
        int ret;
@@ -103,21 +118,32 @@ static size_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val,
                (unsigned long long)ceph_file_layout_su(ci->i_layout),
                (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout),
                (unsigned long long)ceph_file_layout_object_size(ci->i_layout));
-       if (ceph_file_layout_pg_preferred(ci->i_layout))
-               ret += snprintf(val + ret, size, "preferred_osd=%lld\n",
+
+       if (ceph_file_layout_pg_preferred(ci->i_layout) >= 0) {
+               val += ret;
+               size -= ret;
+               ret += snprintf(val, size, "preferred_osd=%lld\n",
                            (unsigned long long)ceph_file_layout_pg_preferred(
                                    ci->i_layout));
+       }
+
        return ret;
 }
 
-static struct ceph_vxattr_cb ceph_file_vxattrs[] = {
-       { true, "ceph.file.layout", ceph_vxattrcb_layout},
+static struct ceph_vxattr ceph_file_vxattrs[] = {
+       XATTR_NAME_CEPH(file, layout),
        /* The following extended attribute name is deprecated */
-       { true, "ceph.layout", ceph_vxattrcb_layout},
-       { true, NULL, NULL }
+       {
+               .name = XATTR_CEPH_PREFIX "layout",
+               .name_size = sizeof (XATTR_CEPH_PREFIX "layout"),
+               .getxattr_cb = ceph_vxattrcb_file_layout,
+               .readonly = true,
+       },
+       { 0 }   /* Required table terminator */
 };
+static size_t ceph_file_vxattrs_name_size;     /* total size of all names */
 
-static struct ceph_vxattr_cb *ceph_inode_vxattrs(struct inode *inode)
+static struct ceph_vxattr *ceph_inode_vxattrs(struct inode *inode)
 {
        if (S_ISDIR(inode->i_mode))
                return ceph_dir_vxattrs;
@@ -126,14 +152,59 @@ static struct ceph_vxattr_cb *ceph_inode_vxattrs(struct inode *inode)
        return NULL;
 }
 
-static struct ceph_vxattr_cb *ceph_match_vxattr(struct ceph_vxattr_cb *vxattr,
+static size_t ceph_vxattrs_name_size(struct ceph_vxattr *vxattrs)
+{
+       if (vxattrs == ceph_dir_vxattrs)
+               return ceph_dir_vxattrs_name_size;
+       if (vxattrs == ceph_file_vxattrs)
+               return ceph_file_vxattrs_name_size;
+       BUG();
+
+       return 0;
+}
+
+/*
+ * Compute the aggregate size (including terminating '\0') of all
+ * virtual extended attribute names in the given vxattr table.
+ */
+static size_t __init vxattrs_name_size(struct ceph_vxattr *vxattrs)
+{
+       struct ceph_vxattr *vxattr;
+       size_t size = 0;
+
+       for (vxattr = vxattrs; vxattr->name; vxattr++)
+               size += vxattr->name_size;
+
+       return size;
+}
+
+/* Routines called at initialization and exit time */
+
+void __init ceph_xattr_init(void)
+{
+       ceph_dir_vxattrs_name_size = vxattrs_name_size(ceph_dir_vxattrs);
+       ceph_file_vxattrs_name_size = vxattrs_name_size(ceph_file_vxattrs);
+}
+
+void ceph_xattr_exit(void)
+{
+       ceph_dir_vxattrs_name_size = 0;
+       ceph_file_vxattrs_name_size = 0;
+}
+
+static struct ceph_vxattr *ceph_match_vxattr(struct inode *inode,
                                                const char *name)
 {
-       do {
-               if (strcmp(vxattr->name, name) == 0)
-                       return vxattr;
-               vxattr++;
-       } while (vxattr->name);
+       struct ceph_vxattr *vxattr = ceph_inode_vxattrs(inode);
+
+       if (vxattr) {
+               while (vxattr->name) {
+                       if (!strcmp(vxattr->name, name))
+                               return vxattr;
+                       vxattr++;
+               }
+       }
+
        return NULL;
 }
 
@@ -502,17 +573,15 @@ ssize_t ceph_getxattr(struct dentry *dentry, const char *name, void *value,
 {
        struct inode *inode = dentry->d_inode;
        struct ceph_inode_info *ci = ceph_inode(inode);
-       struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
        int err;
        struct ceph_inode_xattr *xattr;
-       struct ceph_vxattr_cb *vxattr = NULL;
+       struct ceph_vxattr *vxattr = NULL;
 
        if (!ceph_is_valid_xattr(name))
                return -ENODATA;
 
        /* let's see if a virtual xattr was requested */
-       if (vxattrs)
-               vxattr = ceph_match_vxattr(vxattrs, name);
+       vxattr = ceph_match_vxattr(inode, name);
 
        spin_lock(&ci->i_ceph_lock);
        dout("getxattr %p ver=%lld index_ver=%lld\n", inode,
@@ -568,7 +637,7 @@ ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size)
 {
        struct inode *inode = dentry->d_inode;
        struct ceph_inode_info *ci = ceph_inode(inode);
-       struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
+       struct ceph_vxattr *vxattrs = ceph_inode_vxattrs(inode);
        u32 vir_namelen = 0;
        u32 namelen;
        int err;
@@ -596,11 +665,12 @@ ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size)
                goto out;
 
 list_xattr:
-       vir_namelen = 0;
-       /* include virtual dir xattrs */
-       if (vxattrs)
-               for (i = 0; vxattrs[i].name; i++)
-                       vir_namelen += strlen(vxattrs[i].name) + 1;
+       /*
+        * Start with virtual dir xattr names (if any) (including
+        * terminating '\0' characters for each).
+        */
+       vir_namelen = ceph_vxattrs_name_size(vxattrs);
+
        /* adding 1 byte per each variable due to the null termination */
        namelen = vir_namelen + ci->i_xattrs.names_size + ci->i_xattrs.count;
        err = -ERANGE;
@@ -698,17 +768,17 @@ int ceph_setxattr(struct dentry *dentry, const char *name,
                  const void *value, size_t size, int flags)
 {
        struct inode *inode = dentry->d_inode;
+       struct ceph_vxattr *vxattr;
        struct ceph_inode_info *ci = ceph_inode(inode);
-       struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
+       int issued;
        int err;
+       int dirty;
        int name_len = strlen(name);
        int val_len = size;
        char *newname = NULL;
        char *newval = NULL;
        struct ceph_inode_xattr *xattr = NULL;
-       int issued;
        int required_blob_size;
-       int dirty;
 
        if (ceph_snap(inode) != CEPH_NOSNAP)
                return -EROFS;
@@ -716,12 +786,9 @@ int ceph_setxattr(struct dentry *dentry, const char *name,
        if (!ceph_is_valid_xattr(name))
                return -EOPNOTSUPP;
 
-       if (vxattrs) {
-               struct ceph_vxattr_cb *vxattr =
-                       ceph_match_vxattr(vxattrs, name);
-               if (vxattr && vxattr->readonly)
-                       return -EOPNOTSUPP;
-       }
+       vxattr = ceph_match_vxattr(inode, name);
+       if (vxattr && vxattr->readonly)
+               return -EOPNOTSUPP;
 
        /* preallocate memory for xattr name, value, index node */
        err = -ENOMEM;
@@ -730,11 +797,9 @@ int ceph_setxattr(struct dentry *dentry, const char *name,
                goto out;
 
        if (val_len) {
-               newval = kmalloc(val_len + 1, GFP_NOFS);
+               newval = kmemdup(value, val_len, GFP_NOFS);
                if (!newval)
                        goto out;
-               memcpy(newval, value, val_len);
-               newval[val_len] = '\0';
        }
 
        xattr = kmalloc(sizeof(struct ceph_inode_xattr), GFP_NOFS);
@@ -744,6 +809,7 @@ int ceph_setxattr(struct dentry *dentry, const char *name,
        spin_lock(&ci->i_ceph_lock);
 retry:
        issued = __ceph_caps_issued(ci, NULL);
+       dout("setxattr %p issued %s\n", inode, ceph_cap_string(issued));
        if (!(issued & CEPH_CAP_XATTR_EXCL))
                goto do_sync;
        __build_xattrs(inode);
@@ -752,7 +818,7 @@ retry:
 
        if (!ci->i_xattrs.prealloc_blob ||
            required_blob_size > ci->i_xattrs.prealloc_blob->alloc_len) {
-               struct ceph_buffer *blob = NULL;
+               struct ceph_buffer *blob;
 
                spin_unlock(&ci->i_ceph_lock);
                dout(" preaallocating new blob size=%d\n", required_blob_size);
@@ -766,12 +832,13 @@ retry:
                goto retry;
        }
 
-       dout("setxattr %p issued %s\n", inode, ceph_cap_string(issued));
        err = __set_xattr(ci, newname, name_len, newval,
                          val_len, 1, 1, 1, &xattr);
+
        dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
        ci->i_xattrs.dirty = true;
        inode->i_ctime = CURRENT_TIME;
+
        spin_unlock(&ci->i_ceph_lock);
        if (dirty)
                __mark_inode_dirty(inode, dirty);
@@ -816,8 +883,8 @@ static int ceph_send_removexattr(struct dentry *dentry, const char *name)
 int ceph_removexattr(struct dentry *dentry, const char *name)
 {
        struct inode *inode = dentry->d_inode;
+       struct ceph_vxattr *vxattr;
        struct ceph_inode_info *ci = ceph_inode(inode);
-       struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
        int issued;
        int err;
        int required_blob_size;
@@ -829,22 +896,19 @@ int ceph_removexattr(struct dentry *dentry, const char *name)
        if (!ceph_is_valid_xattr(name))
                return -EOPNOTSUPP;
 
-       if (vxattrs) {
-               struct ceph_vxattr_cb *vxattr =
-                       ceph_match_vxattr(vxattrs, name);
-               if (vxattr && vxattr->readonly)
-                       return -EOPNOTSUPP;
-       }
+       vxattr = ceph_match_vxattr(inode, name);
+       if (vxattr && vxattr->readonly)
+               return -EOPNOTSUPP;
 
        err = -ENOMEM;
        spin_lock(&ci->i_ceph_lock);
-       __build_xattrs(inode);
 retry:
        issued = __ceph_caps_issued(ci, NULL);
        dout("removexattr %p issued %s\n", inode, ceph_cap_string(issued));
 
        if (!(issued & CEPH_CAP_XATTR_EXCL))
                goto do_sync;
+       __build_xattrs(inode);
 
        required_blob_size = __get_required_blob_size(ci, 0, 0);
 
@@ -865,10 +929,10 @@ retry:
        }
 
        err = __remove_xattr_by_name(ceph_inode(inode), name);
+
        dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
        ci->i_xattrs.dirty = true;
        inode->i_ctime = CURRENT_TIME;
-
        spin_unlock(&ci->i_ceph_lock);
        if (dirty)
                __mark_inode_dirty(inode, dirty);
index e9a07b2a09486c019f5967bbafae522ccc9073aa..b60ddc41d78385d168e67e98adc6020fedc1cfeb 100644 (file)
@@ -2404,6 +2404,7 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
                        if (d_ancestor(alias, dentry)) {
                                /* Check for loops */
                                actual = ERR_PTR(-ELOOP);
+                               spin_unlock(&inode->i_lock);
                        } else if (IS_ROOT(alias)) {
                                /* Is this an anonymous mountpoint that we
                                 * could splice into our tree? */
@@ -2413,7 +2414,7 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
                                goto found;
                        } else {
                                /* Nope, but we must(!) avoid directory
-                                * aliasing */
+                                * aliasing. This drops inode->i_lock */
                                actual = __d_unalias(inode, dentry, alias);
                        }
                        write_sequnlock(&rename_lock);
index a2038928f9a34b060abe6534958a830f85bd372f..1e036b79384c214f517c052de529932069d39dd0 100644 (file)
@@ -1743,8 +1743,11 @@ allocated:
 
        *errp = 0;
        brelse(bitmap_bh);
-       dquot_free_block(inode, *count-num);
-       *count = num;
+
+       if (num < *count) {
+               dquot_free_block(inode, *count-num);
+               *count = num;
+       }
 
        trace_ext3_allocate_blocks(inode, goal, num,
                                   (unsigned long long)ret_block);
@@ -1970,7 +1973,7 @@ static ext3_grpblk_t ext3_trim_all_free(struct super_block *sb,
        sbi = EXT3_SB(sb);
 
         /* Walk through the whole group */
-       while (start < max) {
+       while (start <= max) {
                start = bitmap_search_next_usable_block(start, bitmap_bh, max);
                if (start < 0)
                        break;
@@ -1980,7 +1983,7 @@ static ext3_grpblk_t ext3_trim_all_free(struct super_block *sb,
                 * Allocate contiguous free extents by setting bits in the
                 * block bitmap
                 */
-               while (next < max
+               while (next <= max
                        && claim_block(sb_bgl_lock(sbi, group),
                                        next, bitmap_bh)) {
                        next++;
@@ -2091,73 +2094,74 @@ err_out:
  */
 int ext3_trim_fs(struct super_block *sb, struct fstrim_range *range)
 {
-       ext3_grpblk_t last_block, first_block, free_blocks;
-       unsigned long first_group, last_group;
-       unsigned long group, ngroups;
+       ext3_grpblk_t last_block, first_block;
+       unsigned long group, first_group, last_group;
        struct ext3_group_desc *gdp;
        struct ext3_super_block *es = EXT3_SB(sb)->s_es;
-       uint64_t start, len, minlen, trimmed;
+       uint64_t start, minlen, end, trimmed = 0;
+       ext3_fsblk_t first_data_blk =
+                       le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block);
        ext3_fsblk_t max_blks = le32_to_cpu(es->s_blocks_count);
        int ret = 0;
 
-       start = (range->start >> sb->s_blocksize_bits) +
-               le32_to_cpu(es->s_first_data_block);
-       len = range->len >> sb->s_blocksize_bits;
+       start = range->start >> sb->s_blocksize_bits;
+       end = start + (range->len >> sb->s_blocksize_bits) - 1;
        minlen = range->minlen >> sb->s_blocksize_bits;
-       trimmed = 0;
 
-       if (unlikely(minlen > EXT3_BLOCKS_PER_GROUP(sb)))
+       if (unlikely(minlen > EXT3_BLOCKS_PER_GROUP(sb)) ||
+           unlikely(start >= max_blks))
                return -EINVAL;
-       if (start >= max_blks)
-               return -EINVAL;
-       if (start + len > max_blks)
-               len = max_blks - start;
+       if (end >= max_blks)
+               end = max_blks - 1;
+       if (end <= first_data_blk)
+               goto out;
+       if (start < first_data_blk)
+               start = first_data_blk;
 
-       ngroups = EXT3_SB(sb)->s_groups_count;
        smp_rmb();
 
        /* Determine first and last group to examine based on start and len */
        ext3_get_group_no_and_offset(sb, (ext3_fsblk_t) start,
                                     &first_group, &first_block);
-       ext3_get_group_no_and_offset(sb, (ext3_fsblk_t) (start + len),
+       ext3_get_group_no_and_offset(sb, (ext3_fsblk_t) end,
                                     &last_group, &last_block);
-       last_group = (last_group > ngroups - 1) ? ngroups - 1 : last_group;
-       last_block = EXT3_BLOCKS_PER_GROUP(sb);
 
-       if (first_group > last_group)
-               return -EINVAL;
+       /* end now represents the last block to discard in this group */
+       end = EXT3_BLOCKS_PER_GROUP(sb) - 1;
 
        for (group = first_group; group <= last_group; group++) {
                gdp = ext3_get_group_desc(sb, group, NULL);
                if (!gdp)
                        break;
 
-               free_blocks = le16_to_cpu(gdp->bg_free_blocks_count);
-               if (free_blocks < minlen)
-                       continue;
-
                /*
                 * For all the groups except the last one, last block will
-                * always be EXT3_BLOCKS_PER_GROUP(sb), so we only need to
-                * change it for the last group in which case first_block +
-                * len < EXT3_BLOCKS_PER_GROUP(sb).
+                * always be EXT3_BLOCKS_PER_GROUP(sb)-1, so we only need to
+                * change it for the last group, note that last_block is
+                * already computed earlier by ext3_get_group_no_and_offset()
                 */
-               if (first_block + len < EXT3_BLOCKS_PER_GROUP(sb))
-                       last_block = first_block + len;
-               len -= last_block - first_block;
+               if (group == last_group)
+                       end = last_block;
 
-               ret = ext3_trim_all_free(sb, group, first_block,
-                                       last_block, minlen);
-               if (ret < 0)
-                       break;
+               if (le16_to_cpu(gdp->bg_free_blocks_count) >= minlen) {
+                       ret = ext3_trim_all_free(sb, group, first_block,
+                                                end, minlen);
+                       if (ret < 0)
+                               break;
+                       trimmed += ret;
+               }
 
-               trimmed += ret;
+               /*
+                * For every group except the first one, we are sure
+                * that the first block to discard will be block #0.
+                */
                first_block = 0;
        }
 
-       if (ret >= 0)
+       if (ret > 0)
                ret = 0;
-       range->len = trimmed * sb->s_blocksize;
 
+out:
+       range->len = trimmed * sb->s_blocksize;
        return ret;
 }
index 2d0afeca0b479a9e5f3c80f6a98511a47643235a..6d3418662b540b886efb50e13450811cb6060ae1 100644 (file)
@@ -756,6 +756,7 @@ static int ext3_splice_branch(handle_t *handle, struct inode *inode,
        struct ext3_block_alloc_info *block_i;
        ext3_fsblk_t current_block;
        struct ext3_inode_info *ei = EXT3_I(inode);
+       struct timespec now;
 
        block_i = ei->i_block_alloc_info;
        /*
@@ -795,9 +796,11 @@ static int ext3_splice_branch(handle_t *handle, struct inode *inode,
        }
 
        /* We are done with atomic stuff, now do the rest of housekeeping */
-
-       inode->i_ctime = CURRENT_TIME_SEC;
-       ext3_mark_inode_dirty(handle, inode);
+       now = CURRENT_TIME_SEC;
+       if (!timespec_equal(&inode->i_ctime, &now) || !where->bh) {
+               inode->i_ctime = now;
+               ext3_mark_inode_dirty(handle, inode);
+       }
        /* ext3_mark_inode_dirty already updated i_sync_tid */
        atomic_set(&ei->i_datasync_tid, handle->h_transaction->t_tid);
 
index f9e2cd8cf711d2f43a74f5a5f4cc830604cd82d9..4bbd07a6fa189f6ab3f87825e3b94c061972c666 100644 (file)
@@ -336,10 +336,10 @@ err_out:
  * Return buffer_head on success or NULL in case of failure.
  */
 struct buffer_head *
-ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
+ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)
 {
        struct ext4_group_desc *desc;
-       struct buffer_head *bh = NULL;
+       struct buffer_head *bh;
        ext4_fsblk_t bitmap_blk;
 
        desc = ext4_get_group_desc(sb, block_group, NULL);
@@ -348,9 +348,9 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
        bitmap_blk = ext4_block_bitmap(sb, desc);
        bh = sb_getblk(sb, bitmap_blk);
        if (unlikely(!bh)) {
-               ext4_error(sb, "Cannot read block bitmap - "
-                           "block_group = %u, block_bitmap = %llu",
-                           block_group, bitmap_blk);
+               ext4_error(sb, "Cannot get buffer for block bitmap - "
+                          "block_group = %u, block_bitmap = %llu",
+                          block_group, bitmap_blk);
                return NULL;
        }
 
@@ -382,25 +382,50 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
                return bh;
        }
        /*
-        * submit the buffer_head for read. We can
-        * safely mark the bitmap as uptodate now.
-        * We do it here so the bitmap uptodate bit
-        * get set with buffer lock held.
+        * submit the buffer_head for reading
         */
+       set_buffer_new(bh);
        trace_ext4_read_block_bitmap_load(sb, block_group);
-       set_bitmap_uptodate(bh);
-       if (bh_submit_read(bh) < 0) {
-               put_bh(bh);
+       bh->b_end_io = ext4_end_bitmap_read;
+       get_bh(bh);
+       submit_bh(READ, bh);
+       return bh;
+}
+
+/* Returns 0 on success, 1 on error */
+int ext4_wait_block_bitmap(struct super_block *sb, ext4_group_t block_group,
+                          struct buffer_head *bh)
+{
+       struct ext4_group_desc *desc;
+
+       if (!buffer_new(bh))
+               return 0;
+       desc = ext4_get_group_desc(sb, block_group, NULL);
+       if (!desc)
+               return 1;
+       wait_on_buffer(bh);
+       if (!buffer_uptodate(bh)) {
                ext4_error(sb, "Cannot read block bitmap - "
-                           "block_group = %u, block_bitmap = %llu",
-                           block_group, bitmap_blk);
-               return NULL;
+                          "block_group = %u, block_bitmap = %llu",
+                          block_group, (unsigned long long) bh->b_blocknr);
+               return 1;
        }
+       clear_buffer_new(bh);
+       /* Panic or remount fs read-only if block bitmap is invalid */
        ext4_valid_block_bitmap(sb, desc, block_group, bh);
-       /*
-        * file system mounted not to panic on error,
-        * continue with corrupt bitmap
-        */
+       return 0;
+}
+
+struct buffer_head *
+ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
+{
+       struct buffer_head *bh;
+
+       bh = ext4_read_block_bitmap_nowait(sb, block_group);
+       if (ext4_wait_block_bitmap(sb, block_group, bh)) {
+               put_bh(bh);
+               return NULL;
+       }
        return bh;
 }
 
index 164c56092e5865a99238893c5717efc60a7aea4e..ad56866d729a506fce577e69ef8ca2b8852d494d 100644 (file)
@@ -91,17 +91,17 @@ int __ext4_check_dir_entry(const char *function, unsigned int line,
                return 0;
 
        if (filp)
-               ext4_error_file(filp, function, line, bh ? bh->b_blocknr : 0,
+               ext4_error_file(filp, function, line, bh->b_blocknr,
                                "bad entry in directory: %s - offset=%u(%u), "
                                "inode=%u, rec_len=%d, name_len=%d",
-                               error_msg, (unsigned) (offset%bh->b_size),
+                               error_msg, (unsigned) (offset % bh->b_size),
                                offset, le32_to_cpu(de->inode),
                                rlen, de->name_len);
        else
-               ext4_error_inode(dir, function, line, bh ? bh->b_blocknr : 0,
+               ext4_error_inode(dir, function, line, bh->b_blocknr,
                                "bad entry in directory: %s - offset=%u(%u), "
                                "inode=%u, rec_len=%d, name_len=%d",
-                               error_msg, (unsigned) (offset%bh->b_size),
+                               error_msg, (unsigned) (offset % bh->b_size),
                                offset, le32_to_cpu(de->inode),
                                rlen, de->name_len);
 
@@ -425,8 +425,9 @@ static int call_filldir(struct file *filp, void *dirent,
        sb = inode->i_sb;
 
        if (!fname) {
-               printk(KERN_ERR "EXT4-fs: call_filldir: called with "
-                      "null fname?!?\n");
+               ext4_msg(sb, KERN_ERR, "%s:%d: inode #%lu: comm %s: "
+                        "called with null fname?!?", __func__, __LINE__,
+                        inode->i_ino, current->comm);
                return 0;
        }
        curr_pos = hash2pos(fname->hash, fname->minor_hash);
index 513004fc3d840ee03586a4fedcdb133d8031c642..ded731ac8a321d7408e38bafa03d079717fe47a0 100644 (file)
@@ -53,7 +53,7 @@
                printk(KERN_DEBUG f, ## a);                             \
        } while (0)
 #else
-#define ext4_debug(f, a...)    do {} while (0)
+#define ext4_debug(fmt, ...)   no_printk(fmt, ##__VA_ARGS__)
 #endif
 
 #define EXT4_ERROR_INODE(inode, fmt, a...) \
@@ -184,6 +184,8 @@ struct mpage_da_data {
 #define        EXT4_IO_END_UNWRITTEN   0x0001
 #define EXT4_IO_END_ERROR      0x0002
 #define EXT4_IO_END_QUEUED     0x0004
+#define EXT4_IO_END_DIRECT     0x0008
+#define EXT4_IO_END_IN_FSYNC   0x0010
 
 struct ext4_io_page {
        struct page     *p_page;
@@ -192,18 +194,25 @@ struct ext4_io_page {
 
 #define MAX_IO_PAGES 128
 
+/*
+ * For converting uninitialized extents on a work queue.
+ *
+ * 'page' is only used from the writepage() path; 'pages' is only used for
+ * buffered writes; they are used to keep page references until conversion
+ * takes place.  For AIO/DIO, neither field is filled in.
+ */
 typedef struct ext4_io_end {
        struct list_head        list;           /* per-file finished IO list */
        struct inode            *inode;         /* file being written to */
        unsigned int            flag;           /* unwritten or not */
-       struct page             *page;          /* page struct for buffer write */
+       struct page             *page;          /* for writepage() path */
        loff_t                  offset;         /* offset in the file */
        ssize_t                 size;           /* size of the extent */
        struct work_struct      work;           /* data work queue */
        struct kiocb            *iocb;          /* iocb struct for AIO */
        int                     result;         /* error value for AIO */
-       int                     num_io_pages;
-       struct ext4_io_page     *pages[MAX_IO_PAGES];
+       int                     num_io_pages;   /* for writepages() */
+       struct ext4_io_page     *pages[MAX_IO_PAGES]; /* for writepages() */
 } ext4_io_end_t;
 
 struct ext4_io_submit {
@@ -923,6 +932,7 @@ struct ext4_inode_info {
 #define EXT4_MOUNT_ERRORS_CONT         0x00010 /* Continue on errors */
 #define EXT4_MOUNT_ERRORS_RO           0x00020 /* Remount fs ro on errors */
 #define EXT4_MOUNT_ERRORS_PANIC                0x00040 /* Panic on errors */
+#define EXT4_MOUNT_ERRORS_MASK         0x00070
 #define EXT4_MOUNT_MINIX_DF            0x00080 /* Mimics the Minix statfs */
 #define EXT4_MOUNT_NOLOAD              0x00100 /* Don't use existing journal*/
 #define EXT4_MOUNT_DATA_FLAGS          0x00C00 /* Mode for data writes: */
@@ -941,7 +951,6 @@ struct ext4_inode_info {
 #define EXT4_MOUNT_DIOREAD_NOLOCK      0x400000 /* Enable support for dio read nolocking */
 #define EXT4_MOUNT_JOURNAL_CHECKSUM    0x800000 /* Journal checksums */
 #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT        0x1000000 /* Journal Async Commit */
-#define EXT4_MOUNT_I_VERSION            0x2000000 /* i_version support */
 #define EXT4_MOUNT_MBLK_IO_SUBMIT      0x4000000 /* multi-block io submits */
 #define EXT4_MOUNT_DELALLOC            0x8000000 /* Delalloc support */
 #define EXT4_MOUNT_DATA_ERR_ABORT      0x10000000 /* Abort on file data write */
@@ -1142,6 +1151,7 @@ struct ext4_sb_info {
        unsigned int s_mount_opt;
        unsigned int s_mount_opt2;
        unsigned int s_mount_flags;
+       unsigned int s_def_mount_opt;
        ext4_fsblk_t s_sb_block;
        uid_t s_resuid;
        gid_t s_resgid;
@@ -1420,8 +1430,9 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei)
 #define EXT4_FEATURE_INCOMPAT_FLEX_BG          0x0200
 #define EXT4_FEATURE_INCOMPAT_EA_INODE         0x0400 /* EA in inode */
 #define EXT4_FEATURE_INCOMPAT_DIRDATA          0x1000 /* data in dirent */
-#define EXT4_FEATURE_INCOMPAT_INLINEDATA       0x2000 /* data in inode */
+#define EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM 0x2000 /* use crc32c for bg */
 #define EXT4_FEATURE_INCOMPAT_LARGEDIR         0x4000 /* >2GB or 3-lvl htree */
+#define EXT4_FEATURE_INCOMPAT_INLINEDATA       0x8000 /* data in inode */
 
 #define EXT2_FEATURE_COMPAT_SUPP       EXT4_FEATURE_COMPAT_EXT_ATTR
 #define EXT2_FEATURE_INCOMPAT_SUPP     (EXT4_FEATURE_INCOMPAT_FILETYPE| \
@@ -1794,8 +1805,14 @@ extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
                                                    ext4_group_t block_group,
                                                    struct buffer_head ** bh);
 extern int ext4_should_retry_alloc(struct super_block *sb, int *retries);
-struct buffer_head *ext4_read_block_bitmap(struct super_block *sb,
-                                     ext4_group_t block_group);
+
+extern struct buffer_head *ext4_read_block_bitmap_nowait(struct super_block *sb,
+                                               ext4_group_t block_group);
+extern int ext4_wait_block_bitmap(struct super_block *sb,
+                                 ext4_group_t block_group,
+                                 struct buffer_head *bh);
+extern struct buffer_head *ext4_read_block_bitmap(struct super_block *sb,
+                                                 ext4_group_t block_group);
 extern void ext4_init_block_bitmap(struct super_block *sb,
                                   struct buffer_head *bh,
                                   ext4_group_t group,
@@ -1841,6 +1858,7 @@ extern void ext4_check_inodes_bitmap(struct super_block *);
 extern void ext4_mark_bitmap_end(int start_bit, int end_bit, char *bitmap);
 extern int ext4_init_inode_table(struct super_block *sb,
                                 ext4_group_t group, int barrier);
+extern void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate);
 
 /* mballoc.c */
 extern long ext4_mb_stats;
index a52db3a69a30e88df3af4a5d56811985effe4dfd..0f58b86e3a0206e19626f361f453aa80b2838857 100644 (file)
@@ -47,9 +47,9 @@
  */
 #define EXT_DEBUG__
 #ifdef EXT_DEBUG
-#define ext_debug(a...)                printk(a)
+#define ext_debug(fmt, ...)    printk(fmt, ##__VA_ARGS__)
 #else
-#define ext_debug(a...)
+#define ext_debug(fmt, ...)    no_printk(fmt, ##__VA_ARGS__)
 #endif
 
 /*
index 5802fa1dab18f4a8aac358bd79f3ae92109daf02..83b20fcf9400b11b28185470f8feef309faa8252 100644 (file)
 #define EXT4_MAXQUOTAS_INIT_BLOCKS(sb) (MAXQUOTAS*EXT4_QUOTA_INIT_BLOCKS(sb))
 #define EXT4_MAXQUOTAS_DEL_BLOCKS(sb) (MAXQUOTAS*EXT4_QUOTA_DEL_BLOCKS(sb))
 
+/**
+ *   struct ext4_journal_cb_entry - Base structure for callback information.
+ *
+ *   This struct is a 'seed' structure for a using with your own callback
+ *   structs. If you are using callbacks you must allocate one of these
+ *   or another struct of your own definition which has this struct
+ *   as it's first element and pass it to ext4_journal_callback_add().
+ */
+struct ext4_journal_cb_entry {
+       /* list information for other callbacks attached to the same handle */
+       struct list_head jce_list;
+
+       /*  Function to call with this callback structure */
+       void (*jce_func)(struct super_block *sb,
+                        struct ext4_journal_cb_entry *jce, int error);
+
+       /* user data goes here */
+};
+
+/**
+ * ext4_journal_callback_add: add a function to call after transaction commit
+ * @handle: active journal transaction handle to register callback on
+ * @func: callback function to call after the transaction has committed:
+ *        @sb: superblock of current filesystem for transaction
+ *        @jce: returned journal callback data
+ *        @rc: journal state at commit (0 = transaction committed properly)
+ * @jce: journal callback data (internal and function private data struct)
+ *
+ * The registered function will be called in the context of the journal thread
+ * after the transaction for which the handle was created has completed.
+ *
+ * No locks are held when the callback function is called, so it is safe to
+ * call blocking functions from within the callback, but the callback should
+ * not block or run for too long, or the filesystem will be blocked waiting for
+ * the next transaction to commit. No journaling functions can be used, or
+ * there is a risk of deadlock.
+ *
+ * There is no guaranteed calling order of multiple registered callbacks on
+ * the same transaction.
+ */
+static inline void ext4_journal_callback_add(handle_t *handle,
+                       void (*func)(struct super_block *sb,
+                                    struct ext4_journal_cb_entry *jce,
+                                    int rc),
+                       struct ext4_journal_cb_entry *jce)
+{
+       struct ext4_sb_info *sbi =
+                       EXT4_SB(handle->h_transaction->t_journal->j_private);
+
+       /* Add the jce to transaction's private list */
+       jce->jce_func = func;
+       spin_lock(&sbi->s_md_lock);
+       list_add_tail(&jce->jce_list, &handle->h_transaction->t_private_list);
+       spin_unlock(&sbi->s_md_lock);
+}
+
+/**
+ * ext4_journal_callback_del: delete a registered callback
+ * @handle: active journal transaction handle on which callback was registered
+ * @jce: registered journal callback entry to unregister
+ */
+static inline void ext4_journal_callback_del(handle_t *handle,
+                                            struct ext4_journal_cb_entry *jce)
+{
+       struct ext4_sb_info *sbi =
+                       EXT4_SB(handle->h_transaction->t_journal->j_private);
+
+       spin_lock(&sbi->s_md_lock);
+       list_del_init(&jce->jce_list);
+       spin_unlock(&sbi->s_md_lock);
+}
+
 int
 ext4_mark_iloc_dirty(handle_t *handle,
                     struct inode *inode,
@@ -261,43 +333,45 @@ static inline void ext4_update_inode_fsync_trans(handle_t *handle,
 /* super.c */
 int ext4_force_commit(struct super_block *sb);
 
-static inline int ext4_should_journal_data(struct inode *inode)
+/*
+ * Ext4 inode journal modes
+ */
+#define EXT4_INODE_JOURNAL_DATA_MODE   0x01 /* journal data mode */
+#define EXT4_INODE_ORDERED_DATA_MODE   0x02 /* ordered data mode */
+#define EXT4_INODE_WRITEBACK_DATA_MODE 0x04 /* writeback data mode */
+
+static inline int ext4_inode_journal_mode(struct inode *inode)
 {
        if (EXT4_JOURNAL(inode) == NULL)
-               return 0;
-       if (!S_ISREG(inode->i_mode))
-               return 1;
-       if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
-               return 1;
-       if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA))
-               return 1;
-       return 0;
+               return EXT4_INODE_WRITEBACK_DATA_MODE;  /* writeback */
+       /* We do not support data journalling with delayed allocation */
+       if (!S_ISREG(inode->i_mode) ||
+           test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
+               return EXT4_INODE_JOURNAL_DATA_MODE;    /* journal data */
+       if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA) &&
+           !test_opt(inode->i_sb, DELALLOC))
+               return EXT4_INODE_JOURNAL_DATA_MODE;    /* journal data */
+       if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
+               return EXT4_INODE_ORDERED_DATA_MODE;    /* ordered */
+       if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
+               return EXT4_INODE_WRITEBACK_DATA_MODE;  /* writeback */
+       else
+               BUG();
+}
+
+static inline int ext4_should_journal_data(struct inode *inode)
+{
+       return ext4_inode_journal_mode(inode) & EXT4_INODE_JOURNAL_DATA_MODE;
 }
 
 static inline int ext4_should_order_data(struct inode *inode)
 {
-       if (EXT4_JOURNAL(inode) == NULL)
-               return 0;
-       if (!S_ISREG(inode->i_mode))
-               return 0;
-       if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA))
-               return 0;
-       if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
-               return 1;
-       return 0;
+       return ext4_inode_journal_mode(inode) & EXT4_INODE_ORDERED_DATA_MODE;
 }
 
 static inline int ext4_should_writeback_data(struct inode *inode)
 {
-       if (EXT4_JOURNAL(inode) == NULL)
-               return 1;
-       if (!S_ISREG(inode->i_mode))
-               return 0;
-       if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA))
-               return 0;
-       if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
-               return 1;
-       return 0;
+       return ext4_inode_journal_mode(inode) & EXT4_INODE_WRITEBACK_DATA_MODE;
 }
 
 /*
index 74f23c292e1b3000bb7bd9cf0e953df27488b698..1421938e6792a4f5426cbd8f4d218eea4f2192f9 100644 (file)
 
 #include <trace/events/ext4.h>
 
+/*
+ * used by extent splitting.
+ */
+#define EXT4_EXT_MAY_ZEROOUT   0x1  /* safe to zeroout if split fails \
+                                       due to ENOSPC */
+#define EXT4_EXT_MARK_UNINIT1  0x2  /* mark first half uninitialized */
+#define EXT4_EXT_MARK_UNINIT2  0x4  /* mark second half uninitialized */
+
 static int ext4_split_extent(handle_t *handle,
                                struct inode *inode,
                                struct ext4_ext_path *path,
@@ -51,6 +59,13 @@ static int ext4_split_extent(handle_t *handle,
                                int split_flag,
                                int flags);
 
+static int ext4_split_extent_at(handle_t *handle,
+                            struct inode *inode,
+                            struct ext4_ext_path *path,
+                            ext4_lblk_t split,
+                            int split_flag,
+                            int flags);
+
 static int ext4_ext_truncate_extend_restart(handle_t *handle,
                                            struct inode *inode,
                                            int needed)
@@ -300,6 +315,8 @@ static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext)
        ext4_fsblk_t block = ext4_ext_pblock(ext);
        int len = ext4_ext_get_actual_len(ext);
 
+       if (len == 0)
+               return 0;
        return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, len);
 }
 
@@ -2308,7 +2325,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
        struct ext4_extent *ex;
 
        /* the header must be checked already in ext4_ext_remove_space() */
-       ext_debug("truncate since %u in leaf\n", start);
+       ext_debug("truncate since %u in leaf to %u\n", start, end);
        if (!path[depth].p_hdr)
                path[depth].p_hdr = ext_block_hdr(path[depth].p_bh);
        eh = path[depth].p_hdr;
@@ -2343,14 +2360,17 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
                ext_debug("  border %u:%u\n", a, b);
 
                /* If this extent is beyond the end of the hole, skip it */
-               if (end <= ex_ee_block) {
+               if (end < ex_ee_block) {
                        ex--;
                        ex_ee_block = le32_to_cpu(ex->ee_block);
                        ex_ee_len = ext4_ext_get_actual_len(ex);
                        continue;
                } else if (b != ex_ee_block + ex_ee_len - 1) {
-                       EXT4_ERROR_INODE(inode,"  bad truncate %u:%u\n",
-                                        start, end);
+                       EXT4_ERROR_INODE(inode,
+                                        "can not handle truncate %u:%u "
+                                        "on extent %u:%u",
+                                        start, end, ex_ee_block,
+                                        ex_ee_block + ex_ee_len - 1);
                        err = -EIO;
                        goto out;
                } else if (a != ex_ee_block) {
@@ -2482,7 +2502,8 @@ ext4_ext_more_to_rm(struct ext4_ext_path *path)
        return 1;
 }
 
-static int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start)
+static int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
+                                ext4_lblk_t end)
 {
        struct super_block *sb = inode->i_sb;
        int depth = ext_depth(inode);
@@ -2491,7 +2512,7 @@ static int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start)
        handle_t *handle;
        int i, err;
 
-       ext_debug("truncate since %u\n", start);
+       ext_debug("truncate since %u to %u\n", start, end);
 
        /* probably first extent we're gonna free will be last in block */
        handle = ext4_journal_start(inode, depth + 1);
@@ -2503,6 +2524,61 @@ again:
 
        trace_ext4_ext_remove_space(inode, start, depth);
 
+       /*
+        * Check if we are removing extents inside the extent tree. If that
+        * is the case, we are going to punch a hole inside the extent tree
+        * so we have to check whether we need to split the extent covering
+        * the last block to remove so we can easily remove the part of it
+        * in ext4_ext_rm_leaf().
+        */
+       if (end < EXT_MAX_BLOCKS - 1) {
+               struct ext4_extent *ex;
+               ext4_lblk_t ee_block;
+
+               /* find extent for this block */
+               path = ext4_ext_find_extent(inode, end, NULL);
+               if (IS_ERR(path)) {
+                       ext4_journal_stop(handle);
+                       return PTR_ERR(path);
+               }
+               depth = ext_depth(inode);
+               ex = path[depth].p_ext;
+               if (!ex)
+                       goto cont;
+
+               ee_block = le32_to_cpu(ex->ee_block);
+
+               /*
+                * See if the last block is inside the extent, if so split
+                * the extent at 'end' block so we can easily remove the
+                * tail of the first part of the split extent in
+                * ext4_ext_rm_leaf().
+                */
+               if (end >= ee_block &&
+                   end < ee_block + ext4_ext_get_actual_len(ex) - 1) {
+                       int split_flag = 0;
+
+                       if (ext4_ext_is_uninitialized(ex))
+                               split_flag = EXT4_EXT_MARK_UNINIT1 |
+                                            EXT4_EXT_MARK_UNINIT2;
+
+                       /*
+                        * Split the extent in two so that 'end' is the last
+                        * block in the first new extent
+                        */
+                       err = ext4_split_extent_at(handle, inode, path,
+                                               end + 1, split_flag,
+                                               EXT4_GET_BLOCKS_PRE_IO |
+                                               EXT4_GET_BLOCKS_PUNCH_OUT_EXT);
+
+                       if (err < 0)
+                               goto out;
+               }
+               ext4_ext_drop_refs(path);
+               kfree(path);
+       }
+cont:
+
        /*
         * We start scanning from right side, freeing all the blocks
         * after i_size and walking into the tree depth-wise.
@@ -2515,6 +2591,7 @@ again:
        }
        path[0].p_depth = depth;
        path[0].p_hdr = ext_inode_hdr(inode);
+
        if (ext4_ext_check(inode, path[0].p_hdr, depth)) {
                err = -EIO;
                goto out;
@@ -2526,7 +2603,7 @@ again:
                        /* this is leaf block */
                        err = ext4_ext_rm_leaf(handle, inode, path,
                                               &partial_cluster, start,
-                                              EXT_MAX_BLOCKS - 1);
+                                              end);
                        /* root level has p_bh == NULL, brelse() eats this */
                        brelse(path[i].p_bh);
                        path[i].p_bh = NULL;
@@ -2651,17 +2728,17 @@ void ext4_ext_init(struct super_block *sb)
 
        if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
 #if defined(AGGRESSIVE_TEST) || defined(CHECK_BINSEARCH) || defined(EXTENTS_STATS)
-               printk(KERN_INFO "EXT4-fs: file extents enabled");
+               printk(KERN_INFO "EXT4-fs: file extents enabled"
 #ifdef AGGRESSIVE_TEST
-               printk(", aggressive tests");
+                      ", aggressive tests"
 #endif
 #ifdef CHECK_BINSEARCH
-               printk(", check binsearch");
+                      ", check binsearch"
 #endif
 #ifdef EXTENTS_STATS
-               printk(", stats");
+                      ", stats"
 #endif
-               printk("\n");
+                      "\n");
 #endif
 #ifdef EXTENTS_STATS
                spin_lock_init(&EXT4_SB(sb)->s_ext_stats_lock);
@@ -2708,14 +2785,6 @@ static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex)
        return ret;
 }
 
-/*
- * used by extent splitting.
- */
-#define EXT4_EXT_MAY_ZEROOUT   0x1  /* safe to zeroout if split fails \
-                                       due to ENOSPC */
-#define EXT4_EXT_MARK_UNINIT1  0x2  /* mark first half uninitialized */
-#define EXT4_EXT_MARK_UNINIT2  0x4  /* mark second half uninitialized */
-
 /*
  * ext4_split_extent_at() splits an extent at given block.
  *
@@ -3224,11 +3293,13 @@ static int check_eofblocks_fl(handle_t *handle, struct inode *inode,
        depth = ext_depth(inode);
        eh = path[depth].p_hdr;
 
-       if (unlikely(!eh->eh_entries)) {
-               EXT4_ERROR_INODE(inode, "eh->eh_entries == 0 and "
-                                "EOFBLOCKS_FL set");
-               return -EIO;
-       }
+       /*
+        * We're going to remove EOFBLOCKS_FL entirely in future so we
+        * do not care for this case anymore. Simply remove the flag
+        * if there are no extents.
+        */
+       if (unlikely(!eh->eh_entries))
+               goto out;
        last_ex = EXT_LAST_EXTENT(eh);
        /*
         * We should clear the EOFBLOCKS_FL flag if we are writing the
@@ -3252,6 +3323,7 @@ static int check_eofblocks_fl(handle_t *handle, struct inode *inode,
        for (i = depth-1; i >= 0; i--)
                if (path[i].p_idx != EXT_LAST_INDEX(path[i].p_hdr))
                        return 0;
+out:
        ext4_clear_inode_flag(inode, EXT4_INODE_EOFBLOCKS);
        return ext4_mark_inode_dirty(handle, inode);
 }
@@ -3710,8 +3782,6 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
        int free_on_err = 0, err = 0, depth, ret;
        unsigned int allocated = 0, offset = 0;
        unsigned int allocated_clusters = 0;
-       unsigned int punched_out = 0;
-       unsigned int result = 0;
        struct ext4_allocation_request ar;
        ext4_io_end_t *io = EXT4_I(inode)->cur_aio_dio;
        ext4_lblk_t cluster_offset;
@@ -3721,8 +3791,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
        trace_ext4_ext_map_blocks_enter(inode, map->m_lblk, map->m_len, flags);
 
        /* check in cache */
-       if (!(flags & EXT4_GET_BLOCKS_PUNCH_OUT_EXT) &&
-               ext4_ext_in_cache(inode, map->m_lblk, &newex)) {
+       if (ext4_ext_in_cache(inode, map->m_lblk, &newex)) {
                if (!newex.ee_start_lo && !newex.ee_start_hi) {
                        if ((sbi->s_cluster_ratio > 1) &&
                            ext4_find_delalloc_cluster(inode, map->m_lblk, 0))
@@ -3790,113 +3859,25 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
 
                /* if found extent covers block, simply return it */
                if (in_range(map->m_lblk, ee_block, ee_len)) {
-                       struct ext4_map_blocks punch_map;
-                       ext4_fsblk_t partial_cluster = 0;
-
                        newblock = map->m_lblk - ee_block + ee_start;
                        /* number of remaining blocks in the extent */
                        allocated = ee_len - (map->m_lblk - ee_block);
                        ext_debug("%u fit into %u:%d -> %llu\n", map->m_lblk,
                                  ee_block, ee_len, newblock);
 
-                       if ((flags & EXT4_GET_BLOCKS_PUNCH_OUT_EXT) == 0) {
-                               /*
-                                * Do not put uninitialized extent
-                                * in the cache
-                                */
-                               if (!ext4_ext_is_uninitialized(ex)) {
-                                       ext4_ext_put_in_cache(inode, ee_block,
-                                               ee_len, ee_start);
-                                       goto out;
-                               }
-                               ret = ext4_ext_handle_uninitialized_extents(
-                                       handle, inode, map, path, flags,
-                                       allocated, newblock);
-                               return ret;
-                       }
-
-                       /*
-                        * Punch out the map length, but only to the
-                        * end of the extent
-                        */
-                       punched_out = allocated < map->m_len ?
-                               allocated : map->m_len;
-
                        /*
-                        * Sense extents need to be converted to
-                        * uninitialized, they must fit in an
-                        * uninitialized extent
+                        * Do not put uninitialized extent
+                        * in the cache
                         */
-                       if (punched_out > EXT_UNINIT_MAX_LEN)
-                               punched_out = EXT_UNINIT_MAX_LEN;
-
-                       punch_map.m_lblk = map->m_lblk;
-                       punch_map.m_pblk = newblock;
-                       punch_map.m_len = punched_out;
-                       punch_map.m_flags = 0;
-
-                       /* Check to see if the extent needs to be split */
-                       if (punch_map.m_len != ee_len ||
-                               punch_map.m_lblk != ee_block) {
-
-                               ret = ext4_split_extent(handle, inode,
-                               path, &punch_map, 0,
-                               EXT4_GET_BLOCKS_PUNCH_OUT_EXT |
-                               EXT4_GET_BLOCKS_PRE_IO);
-
-                               if (ret < 0) {
-                                       err = ret;
-                                       goto out2;
-                               }
-                               /*
-                                * find extent for the block at
-                                * the start of the hole
-                                */
-                               ext4_ext_drop_refs(path);
-                               kfree(path);
-
-                               path = ext4_ext_find_extent(inode,
-                               map->m_lblk, NULL);
-                               if (IS_ERR(path)) {
-                                       err = PTR_ERR(path);
-                                       path = NULL;
-                                       goto out2;
-                               }
-
-                               depth = ext_depth(inode);
-                               ex = path[depth].p_ext;
-                               ee_len = ext4_ext_get_actual_len(ex);
-                               ee_block = le32_to_cpu(ex->ee_block);
-                               ee_start = ext4_ext_pblock(ex);
-
-                       }
-
-                       ext4_ext_mark_uninitialized(ex);
-
-                       ext4_ext_invalidate_cache(inode);
-
-                       err = ext4_ext_rm_leaf(handle, inode, path,
-                                              &partial_cluster, map->m_lblk,
-                                              map->m_lblk + punched_out);
-
-                       if (!err && path->p_hdr->eh_entries == 0) {
-                               /*
-                                * Punch hole freed all of this sub tree,
-                                * so we need to correct eh_depth
-                                */
-                               err = ext4_ext_get_access(handle, inode, path);
-                               if (err == 0) {
-                                       ext_inode_hdr(inode)->eh_depth = 0;
-                                       ext_inode_hdr(inode)->eh_max =
-                                       cpu_to_le16(ext4_ext_space_root(
-                                               inode, 0));
-
-                                       err = ext4_ext_dirty(
-                                               handle, inode, path);
-                               }
+                       if (!ext4_ext_is_uninitialized(ex)) {
+                               ext4_ext_put_in_cache(inode, ee_block,
+                                       ee_len, ee_start);
+                               goto out;
                        }
-
-                       goto out2;
+                       ret = ext4_ext_handle_uninitialized_extents(
+                               handle, inode, map, path, flags,
+                               allocated, newblock);
+                       return ret;
                }
        }
 
@@ -4165,13 +4146,11 @@ out2:
                ext4_ext_drop_refs(path);
                kfree(path);
        }
-       result = (flags & EXT4_GET_BLOCKS_PUNCH_OUT_EXT) ?
-                       punched_out : allocated;
 
        trace_ext4_ext_map_blocks_exit(inode, map->m_lblk,
-               newblock, map->m_len, err ? err : result);
+               newblock, map->m_len, err ? err : allocated);
 
-       return err ? err : result;
+       return err ? err : allocated;
 }
 
 void ext4_ext_truncate(struct inode *inode)
@@ -4228,7 +4207,7 @@ void ext4_ext_truncate(struct inode *inode)
 
        last_block = (inode->i_size + sb->s_blocksize - 1)
                        >> EXT4_BLOCK_SIZE_BITS(sb);
-       err = ext4_ext_remove_space(inode, last_block);
+       err = ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCKS - 1);
 
        /* In a multi-transaction truncate, we only make the final
         * transaction synchronous.
@@ -4436,10 +4415,11 @@ int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset,
                                      EXT4_GET_BLOCKS_IO_CONVERT_EXT);
                if (ret <= 0) {
                        WARN_ON(ret <= 0);
-                       printk(KERN_ERR "%s: ext4_ext_map_blocks "
-                                   "returned error inode#%lu, block=%u, "
-                                   "max_blocks=%u", __func__,
-                                   inode->i_ino, map.m_lblk, map.m_len);
+                       ext4_msg(inode->i_sb, KERN_ERR,
+                                "%s:%d: inode #%lu: block %u: len %u: "
+                                "ext4_ext_map_blocks returned %d",
+                                __func__, __LINE__, inode->i_ino, map.m_lblk,
+                                map.m_len, ret);
                }
                ext4_mark_inode_dirty(handle, inode);
                ret2 = ext4_journal_stop(handle);
@@ -4705,14 +4685,12 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
 {
        struct inode *inode = file->f_path.dentry->d_inode;
        struct super_block *sb = inode->i_sb;
-       struct ext4_ext_cache cache_ex;
-       ext4_lblk_t first_block, last_block, num_blocks, iblock, max_blocks;
+       ext4_lblk_t first_block, stop_block;
        struct address_space *mapping = inode->i_mapping;
-       struct ext4_map_blocks map;
        handle_t *handle;
        loff_t first_page, last_page, page_len;
        loff_t first_page_offset, last_page_offset;
-       int ret, credits, blocks_released, err = 0;
+       int credits, err = 0;
 
        /* No need to punch hole beyond i_size */
        if (offset >= inode->i_size)
@@ -4728,10 +4706,6 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
                   offset;
        }
 
-       first_block = (offset + sb->s_blocksize - 1) >>
-               EXT4_BLOCK_SIZE_BITS(sb);
-       last_block = (offset + length) >> EXT4_BLOCK_SIZE_BITS(sb);
-
        first_page = (offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
        last_page = (offset + length) >> PAGE_CACHE_SHIFT;
 
@@ -4810,7 +4784,6 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
                }
        }
 
-
        /*
         * If i_size is contained in the last page, we need to
         * unmap and zero the partial page after i_size
@@ -4830,73 +4803,22 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
                }
        }
 
+       first_block = (offset + sb->s_blocksize - 1) >>
+               EXT4_BLOCK_SIZE_BITS(sb);
+       stop_block = (offset + length) >> EXT4_BLOCK_SIZE_BITS(sb);
+
        /* If there are no blocks to remove, return now */
-       if (first_block >= last_block)
+       if (first_block >= stop_block)
                goto out;
 
        down_write(&EXT4_I(inode)->i_data_sem);
        ext4_ext_invalidate_cache(inode);
        ext4_discard_preallocations(inode);
 
-       /*
-        * Loop over all the blocks and identify blocks
-        * that need to be punched out
-        */
-       iblock = first_block;
-       blocks_released = 0;
-       while (iblock < last_block) {
-               max_blocks = last_block - iblock;
-               num_blocks = 1;
-               memset(&map, 0, sizeof(map));
-               map.m_lblk = iblock;
-               map.m_len = max_blocks;
-               ret = ext4_ext_map_blocks(handle, inode, &map,
-                       EXT4_GET_BLOCKS_PUNCH_OUT_EXT);
-
-               if (ret > 0) {
-                       blocks_released += ret;
-                       num_blocks = ret;
-               } else if (ret == 0) {
-                       /*
-                        * If map blocks could not find the block,
-                        * then it is in a hole.  If the hole was
-                        * not already cached, then map blocks should
-                        * put it in the cache.  So we can get the hole
-                        * out of the cache
-                        */
-                       memset(&cache_ex, 0, sizeof(cache_ex));
-                       if ((ext4_ext_check_cache(inode, iblock, &cache_ex)) &&
-                               !cache_ex.ec_start) {
-
-                               /* The hole is cached */
-                               num_blocks = cache_ex.ec_block +
-                               cache_ex.ec_len - iblock;
-
-                       } else {
-                               /* The block could not be identified */
-                               err = -EIO;
-                               break;
-                       }
-               } else {
-                       /* Map blocks error */
-                       err = ret;
-                       break;
-               }
-
-               if (num_blocks == 0) {
-                       /* This condition should never happen */
-                       ext_debug("Block lookup failed");
-                       err = -EIO;
-                       break;
-               }
-
-               iblock += num_blocks;
-       }
+       err = ext4_ext_remove_space(inode, first_block, stop_block - 1);
 
-       if (blocks_released > 0) {
-               ext4_ext_invalidate_cache(inode);
-               ext4_discard_preallocations(inode);
-       }
+       ext4_ext_invalidate_cache(inode);
+       ext4_discard_preallocations(inode);
 
        if (IS_SYNC(inode))
                ext4_handle_sync(handle);
index 00a2cb753efdeca63d6bbba4912729dc1c854182..bb6c7d8113134ee7796a141065d9ed602650f10e 100644 (file)
@@ -89,6 +89,7 @@ int ext4_flush_completed_IO(struct inode *inode)
                io = list_entry(ei->i_completed_io_list.next,
                                ext4_io_end_t, list);
                list_del_init(&io->list);
+               io->flag |= EXT4_IO_END_IN_FSYNC;
                /*
                 * Calling ext4_end_io_nolock() to convert completed
                 * IO to written.
@@ -108,6 +109,7 @@ int ext4_flush_completed_IO(struct inode *inode)
                if (ret < 0)
                        ret2 = ret;
                spin_lock_irqsave(&ei->i_completed_io_lock, flags);
+               io->flag &= ~EXT4_IO_END_IN_FSYNC;
        }
        spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
        return (ret2 < 0) ? ret2 : 0;
index 25d8c9781ad94ea758781f906a34412743b3cda0..409c2ee7750aabb73ce3a2cae44ca9695df53053 100644 (file)
@@ -92,6 +92,16 @@ static unsigned ext4_init_inode_bitmap(struct super_block *sb,
        return EXT4_INODES_PER_GROUP(sb);
 }
 
+void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate)
+{
+       if (uptodate) {
+               set_buffer_uptodate(bh);
+               set_bitmap_uptodate(bh);
+       }
+       unlock_buffer(bh);
+       put_bh(bh);
+}
+
 /*
  * Read the inode allocation bitmap for a given block_group, reading
  * into the specified slot in the superblock's bitmap cache.
@@ -147,18 +157,18 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
                return bh;
        }
        /*
-        * submit the buffer_head for read. We can
-        * safely mark the bitmap as uptodate now.
-        * We do it here so the bitmap uptodate bit
-        * get set with buffer lock held.
+        * submit the buffer_head for reading
         */
        trace_ext4_load_inode_bitmap(sb, block_group);
-       set_bitmap_uptodate(bh);
-       if (bh_submit_read(bh) < 0) {
+       bh->b_end_io = ext4_end_bitmap_read;
+       get_bh(bh);
+       submit_bh(READ, bh);
+       wait_on_buffer(bh);
+       if (!buffer_uptodate(bh)) {
                put_bh(bh);
                ext4_error(sb, "Cannot read inode bitmap - "
-                           "block_group = %u, inode_bitmap = %llu",
-                           block_group, bitmap_blk);
+                          "block_group = %u, inode_bitmap = %llu",
+                          block_group, bitmap_blk);
                return NULL;
        }
        return bh;
@@ -194,19 +204,20 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
        struct ext4_sb_info *sbi;
        int fatal = 0, err, count, cleared;
 
-       if (atomic_read(&inode->i_count) > 1) {
-               printk(KERN_ERR "ext4_free_inode: inode has count=%d\n",
-                      atomic_read(&inode->i_count));
+       if (!sb) {
+               printk(KERN_ERR "EXT4-fs: %s:%d: inode on "
+                      "nonexistent device\n", __func__, __LINE__);
                return;
        }
-       if (inode->i_nlink) {
-               printk(KERN_ERR "ext4_free_inode: inode has nlink=%d\n",
-                      inode->i_nlink);
+       if (atomic_read(&inode->i_count) > 1) {
+               ext4_msg(sb, KERN_ERR, "%s:%d: inode #%lu: count=%d",
+                        __func__, __LINE__, inode->i_ino,
+                        atomic_read(&inode->i_count));
                return;
        }
-       if (!sb) {
-               printk(KERN_ERR "ext4_free_inode: inode on "
-                      "nonexistent device\n");
+       if (inode->i_nlink) {
+               ext4_msg(sb, KERN_ERR, "%s:%d: inode #%lu: nlink=%d\n",
+                        __func__, __LINE__, inode->i_ino, inode->i_nlink);
                return;
        }
        sbi = EXT4_SB(sb);
@@ -592,94 +603,6 @@ static int find_group_other(struct super_block *sb, struct inode *parent,
        return -1;
 }
 
-/*
- * claim the inode from the inode bitmap. If the group
- * is uninit we need to take the groups's ext4_group_lock
- * and clear the uninit flag. The inode bitmap update
- * and group desc uninit flag clear should be done
- * after holding ext4_group_lock so that ext4_read_inode_bitmap
- * doesn't race with the ext4_claim_inode
- */
-static int ext4_claim_inode(struct super_block *sb,
-                       struct buffer_head *inode_bitmap_bh,
-                       unsigned long ino, ext4_group_t group, umode_t mode)
-{
-       int free = 0, retval = 0, count;
-       struct ext4_sb_info *sbi = EXT4_SB(sb);
-       struct ext4_group_info *grp = ext4_get_group_info(sb, group);
-       struct ext4_group_desc *gdp = ext4_get_group_desc(sb, group, NULL);
-
-       /*
-        * We have to be sure that new inode allocation does not race with
-        * inode table initialization, because otherwise we may end up
-        * allocating and writing new inode right before sb_issue_zeroout
-        * takes place and overwriting our new inode with zeroes. So we
-        * take alloc_sem to prevent it.
-        */
-       down_read(&grp->alloc_sem);
-       ext4_lock_group(sb, group);
-       if (ext4_test_and_set_bit(ino, inode_bitmap_bh->b_data)) {
-               /* not a free inode */
-               retval = 1;
-               goto err_ret;
-       }
-       ino++;
-       if ((group == 0 && ino < EXT4_FIRST_INO(sb)) ||
-                       ino > EXT4_INODES_PER_GROUP(sb)) {
-               ext4_unlock_group(sb, group);
-               up_read(&grp->alloc_sem);
-               ext4_error(sb, "reserved inode or inode > inodes count - "
-                          "block_group = %u, inode=%lu", group,
-                          ino + group * EXT4_INODES_PER_GROUP(sb));
-               return 1;
-       }
-       /* If we didn't allocate from within the initialized part of the inode
-        * table then we need to initialize up to this inode. */
-       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
-
-               if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
-                       gdp->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT);
-                       /* When marking the block group with
-                        * ~EXT4_BG_INODE_UNINIT we don't want to depend
-                        * on the value of bg_itable_unused even though
-                        * mke2fs could have initialized the same for us.
-                        * Instead we calculated the value below
-                        */
-
-                       free = 0;
-               } else {
-                       free = EXT4_INODES_PER_GROUP(sb) -
-                               ext4_itable_unused_count(sb, gdp);
-               }
-
-               /*
-                * Check the relative inode number against the last used
-                * relative inode number in this group. if it is greater
-                * we need to  update the bg_itable_unused count
-                *
-                */
-               if (ino > free)
-                       ext4_itable_unused_set(sb, gdp,
-                                       (EXT4_INODES_PER_GROUP(sb) - ino));
-       }
-       count = ext4_free_inodes_count(sb, gdp) - 1;
-       ext4_free_inodes_set(sb, gdp, count);
-       if (S_ISDIR(mode)) {
-               count = ext4_used_dirs_count(sb, gdp) + 1;
-               ext4_used_dirs_set(sb, gdp, count);
-               if (sbi->s_log_groups_per_flex) {
-                       ext4_group_t f = ext4_flex_group(sbi, group);
-
-                       atomic_inc(&sbi->s_flex_groups[f].used_dirs);
-               }
-       }
-       gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
-err_ret:
-       ext4_unlock_group(sb, group);
-       up_read(&grp->alloc_sem);
-       return retval;
-}
-
 /*
  * There are two policies for allocating an inode.  If the new inode is
  * a directory, then a forward search is made for a block group with both
@@ -741,6 +664,11 @@ got_group:
        if (ret2 == -1)
                goto out;
 
+       /*
+        * Normally we will only go through one pass of this loop,
+        * unless we get unlucky and it turns out the group we selected
+        * had its last inode grabbed by someone else.
+        */
        for (i = 0; i < ngroups; i++, ino = 0) {
                err = -EIO;
 
@@ -757,51 +685,24 @@ repeat_in_this_group:
                ino = ext4_find_next_zero_bit((unsigned long *)
                                              inode_bitmap_bh->b_data,
                                              EXT4_INODES_PER_GROUP(sb), ino);
-
-               if (ino < EXT4_INODES_PER_GROUP(sb)) {
-
-                       BUFFER_TRACE(inode_bitmap_bh, "get_write_access");
-                       err = ext4_journal_get_write_access(handle,
-                                                           inode_bitmap_bh);
-                       if (err)
-                               goto fail;
-
-                       BUFFER_TRACE(group_desc_bh, "get_write_access");
-                       err = ext4_journal_get_write_access(handle,
-                                                               group_desc_bh);
-                       if (err)
-                               goto fail;
-                       if (!ext4_claim_inode(sb, inode_bitmap_bh,
-                                               ino, group, mode)) {
-                               /* we won it */
-                               BUFFER_TRACE(inode_bitmap_bh,
-                                       "call ext4_handle_dirty_metadata");
-                               err = ext4_handle_dirty_metadata(handle,
-                                                                NULL,
-                                                       inode_bitmap_bh);
-                               if (err)
-                                       goto fail;
-                               /* zero bit is inode number 1*/
-                               ino++;
-                               goto got;
-                       }
-                       /* we lost it */
-                       ext4_handle_release_buffer(handle, inode_bitmap_bh);
-                       ext4_handle_release_buffer(handle, group_desc_bh);
-
-                       if (++ino < EXT4_INODES_PER_GROUP(sb))
-                               goto repeat_in_this_group;
+               if (ino >= EXT4_INODES_PER_GROUP(sb)) {
+                       if (++group == ngroups)
+                               group = 0;
+                       continue;
                }
-
-               /*
-                * This case is possible in concurrent environment.  It is very
-                * rare.  We cannot repeat the find_group_xxx() call because
-                * that will simply return the same blockgroup, because the
-                * group descriptor metadata has not yet been updated.
-                * So we just go onto the next blockgroup.
-                */
-               if (++group == ngroups)
-                       group = 0;
+               if (group == 0 && (ino+1) < EXT4_FIRST_INO(sb)) {
+                       ext4_error(sb, "reserved inode found cleared - "
+                                  "inode=%lu", ino + 1);
+                       continue;
+               }
+               ext4_lock_group(sb, group);
+               ret2 = ext4_test_and_set_bit(ino, inode_bitmap_bh->b_data);
+               ext4_unlock_group(sb, group);
+               ino++;          /* the inode bitmap is zero-based */
+               if (!ret2)
+                       goto got; /* we grabbed the inode! */
+               if (ino < EXT4_INODES_PER_GROUP(sb))
+                       goto repeat_in_this_group;
        }
        err = -ENOSPC;
        goto out;
@@ -838,6 +739,59 @@ got:
                if (err)
                        goto fail;
        }
+
+       BUFFER_TRACE(inode_bitmap_bh, "get_write_access");
+       err = ext4_journal_get_write_access(handle, inode_bitmap_bh);
+       if (err)
+               goto fail;
+
+       BUFFER_TRACE(group_desc_bh, "get_write_access");
+       err = ext4_journal_get_write_access(handle, group_desc_bh);
+       if (err)
+               goto fail;
+
+       /* Update the relevant bg descriptor fields */
+       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+               int free;
+               struct ext4_group_info *grp = ext4_get_group_info(sb, group);
+
+               down_read(&grp->alloc_sem); /* protect vs itable lazyinit */
+               ext4_lock_group(sb, group); /* while we modify the bg desc */
+               free = EXT4_INODES_PER_GROUP(sb) -
+                       ext4_itable_unused_count(sb, gdp);
+               if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
+                       gdp->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT);
+                       free = 0;
+               }
+               /*
+                * Check the relative inode number against the last used
+                * relative inode number in this group. if it is greater
+                * we need to update the bg_itable_unused count
+                */
+               if (ino > free)
+                       ext4_itable_unused_set(sb, gdp,
+                                       (EXT4_INODES_PER_GROUP(sb) - ino));
+               up_read(&grp->alloc_sem);
+       }
+       ext4_free_inodes_set(sb, gdp, ext4_free_inodes_count(sb, gdp) - 1);
+       if (S_ISDIR(mode)) {
+               ext4_used_dirs_set(sb, gdp, ext4_used_dirs_count(sb, gdp) + 1);
+               if (sbi->s_log_groups_per_flex) {
+                       ext4_group_t f = ext4_flex_group(sbi, group);
+
+                       atomic_inc(&sbi->s_flex_groups[f].used_dirs);
+               }
+       }
+       if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+               gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
+               ext4_unlock_group(sb, group);
+       }
+
+       BUFFER_TRACE(inode_bitmap_bh, "call ext4_handle_dirty_metadata");
+       err = ext4_handle_dirty_metadata(handle, NULL, inode_bitmap_bh);
+       if (err)
+               goto fail;
+
        BUFFER_TRACE(group_desc_bh, "call ext4_handle_dirty_metadata");
        err = ext4_handle_dirty_metadata(handle, NULL, group_desc_bh);
        if (err)
@@ -1101,7 +1055,7 @@ unsigned long ext4_count_dirs(struct super_block * sb)
  * where it is called from on active part of filesystem is ext4lazyinit
  * thread, so we do not need any special locks, however we have to prevent
  * inode allocation from the current group, so we take alloc_sem lock, to
- * block ext4_claim_inode until we are finished.
+ * block ext4_new_inode() until we are finished.
  */
 int ext4_init_inode_table(struct super_block *sb, ext4_group_t group,
                                 int barrier)
@@ -1149,9 +1103,9 @@ int ext4_init_inode_table(struct super_block *sb, ext4_group_t group,
                            sbi->s_inodes_per_block);
 
        if ((used_blks < 0) || (used_blks > sbi->s_itb_per_group)) {
-               ext4_error(sb, "Something is wrong with group %u\n"
-                          "Used itable blocks: %d"
-                          "itable unused count: %u\n",
+               ext4_error(sb, "Something is wrong with group %u"
+                          "used itable blocks: %d; "
+                          "itable unused count: %u",
                           group, used_blks,
                           ext4_itable_unused_count(sb, gdp));
                ret = 1;
index feaa82fe629d067e0900744fcbb50da2768b0183..c77b0bd2c7110975476b7f6312ddde7da515ca7a 100644 (file)
@@ -272,7 +272,7 @@ void ext4_da_update_reserve_space(struct inode *inode,
        trace_ext4_da_update_reserve_space(inode, used, quota_claim);
        if (unlikely(used > ei->i_reserved_data_blocks)) {
                ext4_msg(inode->i_sb, KERN_NOTICE, "%s: ino %lu, used %d "
-                        "with only %d reserved data blocks\n",
+                        "with only %d reserved data blocks",
                         __func__, inode->i_ino, used,
                         ei->i_reserved_data_blocks);
                WARN_ON(1);
@@ -1165,7 +1165,7 @@ static void ext4_da_release_space(struct inode *inode, int to_free)
                 */
                ext4_msg(inode->i_sb, KERN_NOTICE, "ext4_da_release_space: "
                         "ino %lu, to_free %d with only %d reserved "
-                        "data blocks\n", inode->i_ino, to_free,
+                        "data blocks", inode->i_ino, to_free,
                         ei->i_reserved_data_blocks);
                WARN_ON(1);
                to_free = ei->i_reserved_data_blocks;
@@ -1428,20 +1428,22 @@ static void ext4_da_block_invalidatepages(struct mpage_da_data *mpd)
 static void ext4_print_free_blocks(struct inode *inode)
 {
        struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
-       printk(KERN_CRIT "Total free blocks count %lld\n",
+       struct super_block *sb = inode->i_sb;
+
+       ext4_msg(sb, KERN_CRIT, "Total free blocks count %lld",
               EXT4_C2B(EXT4_SB(inode->i_sb),
                        ext4_count_free_clusters(inode->i_sb)));
-       printk(KERN_CRIT "Free/Dirty block details\n");
-       printk(KERN_CRIT "free_blocks=%lld\n",
+       ext4_msg(sb, KERN_CRIT, "Free/Dirty block details");
+       ext4_msg(sb, KERN_CRIT, "free_blocks=%lld",
               (long long) EXT4_C2B(EXT4_SB(inode->i_sb),
                percpu_counter_sum(&sbi->s_freeclusters_counter)));
-       printk(KERN_CRIT "dirty_blocks=%lld\n",
+       ext4_msg(sb, KERN_CRIT, "dirty_blocks=%lld",
               (long long) EXT4_C2B(EXT4_SB(inode->i_sb),
                percpu_counter_sum(&sbi->s_dirtyclusters_counter)));
-       printk(KERN_CRIT "Block reservation details\n");
-       printk(KERN_CRIT "i_reserved_data_blocks=%u\n",
-              EXT4_I(inode)->i_reserved_data_blocks);
-       printk(KERN_CRIT "i_reserved_meta_blocks=%u\n",
+       ext4_msg(sb, KERN_CRIT, "Block reservation details");
+       ext4_msg(sb, KERN_CRIT, "i_reserved_data_blocks=%u",
+                EXT4_I(inode)->i_reserved_data_blocks);
+       ext4_msg(sb, KERN_CRIT, "i_reserved_meta_blocks=%u",
               EXT4_I(inode)->i_reserved_meta_blocks);
        return;
 }
@@ -2482,13 +2484,14 @@ static int ext4_da_write_end(struct file *file,
        int write_mode = (int)(unsigned long)fsdata;
 
        if (write_mode == FALL_BACK_TO_NONDELALLOC) {
-               if (ext4_should_order_data(inode)) {
+               switch (ext4_inode_journal_mode(inode)) {
+               case EXT4_INODE_ORDERED_DATA_MODE:
                        return ext4_ordered_write_end(file, mapping, pos,
                                        len, copied, page, fsdata);
-               } else if (ext4_should_writeback_data(inode)) {
+               case EXT4_INODE_WRITEBACK_DATA_MODE:
                        return ext4_writeback_write_end(file, mapping, pos,
                                        len, copied, page, fsdata);
-               } else {
+               default:
                        BUG();
                }
        }
@@ -2763,7 +2766,7 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
                goto out;
 
        ext_debug("ext4_end_io_dio(): io_end 0x%p "
-                 "for inode %lu, iocb 0x%p, offset %llu, size %llu\n",
+                 "for inode %lu, iocb 0x%p, offset %llu, size %zd\n",
                  iocb->private, io_end->inode->i_ino, iocb, offset,
                  size);
 
@@ -2795,9 +2798,6 @@ out:
 
        /* queue the work to convert unwritten extents to written */
        queue_work(wq, &io_end->work);
-
-       /* XXX: probably should move into the real I/O completion handler */
-       inode_dio_done(inode);
 }
 
 static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate)
@@ -2811,8 +2811,9 @@ static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate)
                goto out;
 
        if (!(io_end->inode->i_sb->s_flags & MS_ACTIVE)) {
-               printk("sb umounted, discard end_io request for inode %lu\n",
-                       io_end->inode->i_ino);
+               ext4_msg(io_end->inode->i_sb, KERN_INFO,
+                        "sb umounted, discard end_io request for inode %lu",
+                        io_end->inode->i_ino);
                ext4_free_io_end(io_end);
                goto out;
        }
@@ -2921,9 +2922,12 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
                iocb->private = NULL;
                EXT4_I(inode)->cur_aio_dio = NULL;
                if (!is_sync_kiocb(iocb)) {
-                       iocb->private = ext4_init_io_end(inode, GFP_NOFS);
-                       if (!iocb->private)
+                       ext4_io_end_t *io_end =
+                               ext4_init_io_end(inode, GFP_NOFS);
+                       if (!io_end)
                                return -ENOMEM;
+                       io_end->flag |= EXT4_IO_END_DIRECT;
+                       iocb->private = io_end;
                        /*
                         * we save the io structure for current async
                         * direct IO, so that later ext4_map_blocks()
@@ -2940,7 +2944,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
                                         ext4_get_block_write,
                                         ext4_end_io_dio,
                                         NULL,
-                                        DIO_LOCKING | DIO_SKIP_HOLES);
+                                        DIO_LOCKING);
                if (iocb->private)
                        EXT4_I(inode)->cur_aio_dio = NULL;
                /*
@@ -3086,18 +3090,25 @@ static const struct address_space_operations ext4_da_aops = {
 
 void ext4_set_aops(struct inode *inode)
 {
-       if (ext4_should_order_data(inode) &&
-               test_opt(inode->i_sb, DELALLOC))
-               inode->i_mapping->a_ops = &ext4_da_aops;
-       else if (ext4_should_order_data(inode))
-               inode->i_mapping->a_ops = &ext4_ordered_aops;
-       else if (ext4_should_writeback_data(inode) &&
-                test_opt(inode->i_sb, DELALLOC))
-               inode->i_mapping->a_ops = &ext4_da_aops;
-       else if (ext4_should_writeback_data(inode))
-               inode->i_mapping->a_ops = &ext4_writeback_aops;
-       else
+       switch (ext4_inode_journal_mode(inode)) {
+       case EXT4_INODE_ORDERED_DATA_MODE:
+               if (test_opt(inode->i_sb, DELALLOC))
+                       inode->i_mapping->a_ops = &ext4_da_aops;
+               else
+                       inode->i_mapping->a_ops = &ext4_ordered_aops;
+               break;
+       case EXT4_INODE_WRITEBACK_DATA_MODE:
+               if (test_opt(inode->i_sb, DELALLOC))
+                       inode->i_mapping->a_ops = &ext4_da_aops;
+               else
+                       inode->i_mapping->a_ops = &ext4_writeback_aops;
+               break;
+       case EXT4_INODE_JOURNAL_DATA_MODE:
                inode->i_mapping->a_ops = &ext4_journalled_aops;
+               break;
+       default:
+               BUG();
+       }
 }
 
 
@@ -3329,16 +3340,16 @@ int ext4_punch_hole(struct file *file, loff_t offset, loff_t length)
 {
        struct inode *inode = file->f_path.dentry->d_inode;
        if (!S_ISREG(inode->i_mode))
-               return -ENOTSUPP;
+               return -EOPNOTSUPP;
 
        if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
                /* TODO: Add support for non extent hole punching */
-               return -ENOTSUPP;
+               return -EOPNOTSUPP;
        }
 
        if (EXT4_SB(inode->i_sb)->s_cluster_ratio > 1) {
                /* TODO: Add support for bigalloc file systems */
-               return -ENOTSUPP;
+               return -EOPNOTSUPP;
        }
 
        return ext4_ext_punch_hole(file, offset, length);
@@ -3924,10 +3935,8 @@ static int ext4_do_update_inode(handle_t *handle,
                        ext4_update_dynamic_rev(sb);
                        EXT4_SET_RO_COMPAT_FEATURE(sb,
                                        EXT4_FEATURE_RO_COMPAT_LARGE_FILE);
-                       sb->s_dirt = 1;
                        ext4_handle_sync(handle);
-                       err = ext4_handle_dirty_metadata(handle, NULL,
-                                       EXT4_SB(sb)->s_sbh);
+                       err = ext4_handle_dirty_super(handle, sb);
                }
        }
        raw_inode->i_generation = cpu_to_le32(inode->i_generation);
@@ -4152,11 +4161,9 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
        }
 
        if (attr->ia_valid & ATTR_SIZE) {
-               if (attr->ia_size != i_size_read(inode)) {
+               if (attr->ia_size != i_size_read(inode))
                        truncate_setsize(inode, attr->ia_size);
-                       ext4_truncate(inode);
-               } else if (ext4_test_inode_flag(inode, EXT4_INODE_EOFBLOCKS))
-                       ext4_truncate(inode);
+               ext4_truncate(inode);
        }
 
        if (!rc) {
@@ -4314,7 +4321,7 @@ int ext4_mark_iloc_dirty(handle_t *handle,
 {
        int err = 0;
 
-       if (test_opt(inode->i_sb, I_VERSION))
+       if (IS_I_VERSION(inode))
                inode_inc_iversion(inode);
 
        /* the do_update_inode consumes one bh->b_count */
index cb990b21c698bd9dd1ec0e4bb8488f6e82bbe2f7..99ab428bcfa089822e74b433aee7b1bf4076e34d 100644 (file)
@@ -21,6 +21,7 @@
  * mballoc.c contains the multiblocks allocation routines
  */
 
+#include "ext4_jbd2.h"
 #include "mballoc.h"
 #include <linux/debugfs.h>
 #include <linux/slab.h>
  */
 static struct kmem_cache *ext4_pspace_cachep;
 static struct kmem_cache *ext4_ac_cachep;
-static struct kmem_cache *ext4_free_ext_cachep;
+static struct kmem_cache *ext4_free_data_cachep;
 
 /* We create slab caches for groupinfo data structures based on the
  * superblock block size.  There will be one per mounted filesystem for
@@ -357,7 +358,8 @@ static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
                                        ext4_group_t group);
 static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap,
                                                ext4_group_t group);
-static void release_blocks_on_commit(journal_t *journal, transaction_t *txn);
+static void ext4_free_data_callback(struct super_block *sb,
+                               struct ext4_journal_cb_entry *jce, int rc);
 
 static inline void *mb_correct_addr_and_bit(int *bit, void *addr)
 {
@@ -425,7 +427,7 @@ static void *mb_find_buddy(struct ext4_buddy *e4b, int order, int *max)
 {
        char *bb;
 
-       BUG_ON(EXT4_MB_BITMAP(e4b) == EXT4_MB_BUDDY(e4b));
+       BUG_ON(e4b->bd_bitmap == e4b->bd_buddy);
        BUG_ON(max == NULL);
 
        if (order > e4b->bd_blkbits + 1) {
@@ -436,10 +438,10 @@ static void *mb_find_buddy(struct ext4_buddy *e4b, int order, int *max)
        /* at order 0 we see each particular block */
        if (order == 0) {
                *max = 1 << (e4b->bd_blkbits + 3);
-               return EXT4_MB_BITMAP(e4b);
+               return e4b->bd_bitmap;
        }
 
-       bb = EXT4_MB_BUDDY(e4b) + EXT4_SB(e4b->bd_sb)->s_mb_offsets[order];
+       bb = e4b->bd_buddy + EXT4_SB(e4b->bd_sb)->s_mb_offsets[order];
        *max = EXT4_SB(e4b->bd_sb)->s_mb_maxs[order];
 
        return bb;
@@ -588,7 +590,7 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file,
                        for (j = 0; j < (1 << order); j++) {
                                k = (i * (1 << order)) + j;
                                MB_CHECK_ASSERT(
-                                       !mb_test_bit(k, EXT4_MB_BITMAP(e4b)));
+                                       !mb_test_bit(k, e4b->bd_bitmap));
                        }
                        count++;
                }
@@ -782,7 +784,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
        int groups_per_page;
        int err = 0;
        int i;
-       ext4_group_t first_group;
+       ext4_group_t first_group, group;
        int first_block;
        struct super_block *sb;
        struct buffer_head *bhs;
@@ -806,24 +808,23 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
 
        /* allocate buffer_heads to read bitmaps */
        if (groups_per_page > 1) {
-               err = -ENOMEM;
                i = sizeof(struct buffer_head *) * groups_per_page;
                bh = kzalloc(i, GFP_NOFS);
-               if (bh == NULL)
+               if (bh == NULL) {
+                       err = -ENOMEM;
                        goto out;
+               }
        } else
                bh = &bhs;
 
        first_group = page->index * blocks_per_page / 2;
 
        /* read all groups the page covers into the cache */
-       for (i = 0; i < groups_per_page; i++) {
-               struct ext4_group_desc *desc;
-
-               if (first_group + i >= ngroups)
+       for (i = 0, group = first_group; i < groups_per_page; i++, group++) {
+               if (group >= ngroups)
                        break;
 
-               grinfo = ext4_get_group_info(sb, first_group + i);
+               grinfo = ext4_get_group_info(sb, group);
                /*
                 * If page is uptodate then we came here after online resize
                 * which added some new uninitialized group info structs, so
@@ -834,69 +835,21 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
                        bh[i] = NULL;
                        continue;
                }
-
-               err = -EIO;
-               desc = ext4_get_group_desc(sb, first_group + i, NULL);
-               if (desc == NULL)
-                       goto out;
-
-               err = -ENOMEM;
-               bh[i] = sb_getblk(sb, ext4_block_bitmap(sb, desc));
-               if (bh[i] == NULL)
+               if (!(bh[i] = ext4_read_block_bitmap_nowait(sb, group))) {
+                       err = -ENOMEM;
                        goto out;
-
-               if (bitmap_uptodate(bh[i]))
-                       continue;
-
-               lock_buffer(bh[i]);
-               if (bitmap_uptodate(bh[i])) {
-                       unlock_buffer(bh[i]);
-                       continue;
-               }
-               ext4_lock_group(sb, first_group + i);
-               if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
-                       ext4_init_block_bitmap(sb, bh[i],
-                                               first_group + i, desc);
-                       set_bitmap_uptodate(bh[i]);
-                       set_buffer_uptodate(bh[i]);
-                       ext4_unlock_group(sb, first_group + i);
-                       unlock_buffer(bh[i]);
-                       continue;
                }
-               ext4_unlock_group(sb, first_group + i);
-               if (buffer_uptodate(bh[i])) {
-                       /*
-                        * if not uninit if bh is uptodate,
-                        * bitmap is also uptodate
-                        */
-                       set_bitmap_uptodate(bh[i]);
-                       unlock_buffer(bh[i]);
-                       continue;
-               }
-               get_bh(bh[i]);
-               /*
-                * submit the buffer_head for read. We can
-                * safely mark the bitmap as uptodate now.
-                * We do it here so the bitmap uptodate bit
-                * get set with buffer lock held.
-                */
-               set_bitmap_uptodate(bh[i]);
-               bh[i]->b_end_io = end_buffer_read_sync;
-               submit_bh(READ, bh[i]);
-               mb_debug(1, "read bitmap for group %u\n", first_group + i);
+               mb_debug(1, "read bitmap for group %u\n", group);
        }
 
        /* wait for I/O completion */
-       for (i = 0; i < groups_per_page; i++)
-               if (bh[i])
-                       wait_on_buffer(bh[i]);
-
-       err = -EIO;
-       for (i = 0; i < groups_per_page; i++)
-               if (bh[i] && !buffer_uptodate(bh[i]))
+       for (i = 0, group = first_group; i < groups_per_page; i++, group++) {
+               if (bh[i] && ext4_wait_block_bitmap(sb, group, bh[i])) {
+                       err = -EIO;
                        goto out;
+               }
+       }
 
-       err = 0;
        first_block = page->index * blocks_per_page;
        for (i = 0; i < blocks_per_page; i++) {
                int group;
@@ -1250,10 +1203,10 @@ static int mb_find_order_for_block(struct ext4_buddy *e4b, int block)
        int order = 1;
        void *bb;
 
-       BUG_ON(EXT4_MB_BITMAP(e4b) == EXT4_MB_BUDDY(e4b));
+       BUG_ON(e4b->bd_bitmap == e4b->bd_buddy);
        BUG_ON(block >= (1 << (e4b->bd_blkbits + 3)));
 
-       bb = EXT4_MB_BUDDY(e4b);
+       bb = e4b->bd_buddy;
        while (order <= e4b->bd_blkbits + 1) {
                block = block >> 1;
                if (!mb_test_bit(block, bb)) {
@@ -1323,9 +1276,9 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b,
 
        /* let's maintain fragments counter */
        if (first != 0)
-               block = !mb_test_bit(first - 1, EXT4_MB_BITMAP(e4b));
+               block = !mb_test_bit(first - 1, e4b->bd_bitmap);
        if (first + count < EXT4_SB(sb)->s_mb_maxs[0])
-               max = !mb_test_bit(first + count, EXT4_MB_BITMAP(e4b));
+               max = !mb_test_bit(first + count, e4b->bd_bitmap);
        if (block && max)
                e4b->bd_info->bb_fragments--;
        else if (!block && !max)
@@ -1336,7 +1289,7 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b,
                block = first++;
                order = 0;
 
-               if (!mb_test_bit(block, EXT4_MB_BITMAP(e4b))) {
+               if (!mb_test_bit(block, e4b->bd_bitmap)) {
                        ext4_fsblk_t blocknr;
 
                        blocknr = ext4_group_first_block_no(sb, e4b->bd_group);
@@ -1347,7 +1300,7 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b,
                                              "freeing already freed block "
                                              "(bit %u)", block);
                }
-               mb_clear_bit(block, EXT4_MB_BITMAP(e4b));
+               mb_clear_bit(block, e4b->bd_bitmap);
                e4b->bd_info->bb_counters[order]++;
 
                /* start of the buddy */
@@ -1429,7 +1382,7 @@ static int mb_find_extent(struct ext4_buddy *e4b, int order, int block,
                        break;
 
                next = (block + 1) * (1 << order);
-               if (mb_test_bit(next, EXT4_MB_BITMAP(e4b)))
+               if (mb_test_bit(next, e4b->bd_bitmap))
                        break;
 
                order = mb_find_order_for_block(e4b, next);
@@ -1466,9 +1419,9 @@ static int mb_mark_used(struct ext4_buddy *e4b, struct ext4_free_extent *ex)
 
        /* let's maintain fragments counter */
        if (start != 0)
-               mlen = !mb_test_bit(start - 1, EXT4_MB_BITMAP(e4b));
+               mlen = !mb_test_bit(start - 1, e4b->bd_bitmap);
        if (start + len < EXT4_SB(e4b->bd_sb)->s_mb_maxs[0])
-               max = !mb_test_bit(start + len, EXT4_MB_BITMAP(e4b));
+               max = !mb_test_bit(start + len, e4b->bd_bitmap);
        if (mlen && max)
                e4b->bd_info->bb_fragments++;
        else if (!mlen && !max)
@@ -1511,7 +1464,7 @@ static int mb_mark_used(struct ext4_buddy *e4b, struct ext4_free_extent *ex)
        }
        mb_set_largest_free_order(e4b->bd_sb, e4b->bd_info);
 
-       ext4_set_bits(EXT4_MB_BITMAP(e4b), ex->fe_start, len0);
+       ext4_set_bits(e4b->bd_bitmap, ex->fe_start, len0);
        mb_check_buddy(e4b);
 
        return ret;
@@ -1810,7 +1763,7 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
                                        struct ext4_buddy *e4b)
 {
        struct super_block *sb = ac->ac_sb;
-       void *bitmap = EXT4_MB_BITMAP(e4b);
+       void *bitmap = e4b->bd_bitmap;
        struct ext4_free_extent ex;
        int i;
        int free;
@@ -1870,7 +1823,7 @@ void ext4_mb_scan_aligned(struct ext4_allocation_context *ac,
 {
        struct super_block *sb = ac->ac_sb;
        struct ext4_sb_info *sbi = EXT4_SB(sb);
-       void *bitmap = EXT4_MB_BITMAP(e4b);
+       void *bitmap = e4b->bd_bitmap;
        struct ext4_free_extent ex;
        ext4_fsblk_t first_group_block;
        ext4_fsblk_t a;
@@ -2224,7 +2177,7 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
                        EXT4_DESC_PER_BLOCK_BITS(sb);
                meta_group_info = kmalloc(metalen, GFP_KERNEL);
                if (meta_group_info == NULL) {
-                       ext4_msg(sb, KERN_ERR, "EXT4-fs: can't allocate mem "
+                       ext4_msg(sb, KERN_ERR, "can't allocate mem "
                                 "for a buddy group");
                        goto exit_meta_group_info;
                }
@@ -2238,7 +2191,7 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
 
        meta_group_info[i] = kmem_cache_alloc(cachep, GFP_KERNEL);
        if (meta_group_info[i] == NULL) {
-               ext4_msg(sb, KERN_ERR, "EXT4-fs: can't allocate buddy mem");
+               ext4_msg(sb, KERN_ERR, "can't allocate buddy mem");
                goto exit_group_info;
        }
        memset(meta_group_info[i], 0, kmem_cache_size(cachep));
@@ -2522,9 +2475,6 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
                proc_create_data("mb_groups", S_IRUGO, sbi->s_proc,
                                 &ext4_mb_seq_groups_fops, sb);
 
-       if (sbi->s_journal)
-               sbi->s_journal->j_commit_callback = release_blocks_on_commit;
-
        return 0;
 
 out_free_locality_groups:
@@ -2637,58 +2587,55 @@ static inline int ext4_issue_discard(struct super_block *sb,
  * This function is called by the jbd2 layer once the commit has finished,
  * so we know we can free the blocks that were released with that commit.
  */
-static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
+static void ext4_free_data_callback(struct super_block *sb,
+                                   struct ext4_journal_cb_entry *jce,
+                                   int rc)
 {
-       struct super_block *sb = journal->j_private;
+       struct ext4_free_data *entry = (struct ext4_free_data *)jce;
        struct ext4_buddy e4b;
        struct ext4_group_info *db;
        int err, count = 0, count2 = 0;
-       struct ext4_free_data *entry;
-       struct list_head *l, *ltmp;
 
-       list_for_each_safe(l, ltmp, &txn->t_private_list) {
-               entry = list_entry(l, struct ext4_free_data, list);
+       mb_debug(1, "gonna free %u blocks in group %u (0x%p):",
+                entry->efd_count, entry->efd_group, entry);
 
-               mb_debug(1, "gonna free %u blocks in group %u (0x%p):",
-                        entry->count, entry->group, entry);
+       if (test_opt(sb, DISCARD))
+               ext4_issue_discard(sb, entry->efd_group,
+                                  entry->efd_start_cluster, entry->efd_count);
 
-               if (test_opt(sb, DISCARD))
-                       ext4_issue_discard(sb, entry->group,
-                                          entry->start_cluster, entry->count);
+       err = ext4_mb_load_buddy(sb, entry->efd_group, &e4b);
+       /* we expect to find existing buddy because it's pinned */
+       BUG_ON(err != 0);
 
-               err = ext4_mb_load_buddy(sb, entry->group, &e4b);
-               /* we expect to find existing buddy because it's pinned */
-               BUG_ON(err != 0);
 
-               db = e4b.bd_info;
-               /* there are blocks to put in buddy to make them really free */
-               count += entry->count;
-               count2++;
-               ext4_lock_group(sb, entry->group);
-               /* Take it out of per group rb tree */
-               rb_erase(&entry->node, &(db->bb_free_root));
-               mb_free_blocks(NULL, &e4b, entry->start_cluster, entry->count);
+       db = e4b.bd_info;
+       /* there are blocks to put in buddy to make them really free */
+       count += entry->efd_count;
+       count2++;
+       ext4_lock_group(sb, entry->efd_group);
+       /* Take it out of per group rb tree */
+       rb_erase(&entry->efd_node, &(db->bb_free_root));
+       mb_free_blocks(NULL, &e4b, entry->efd_start_cluster, entry->efd_count);
 
-               /*
-                * Clear the trimmed flag for the group so that the next
-                * ext4_trim_fs can trim it.
-                * If the volume is mounted with -o discard, online discard
-                * is supported and the free blocks will be trimmed online.
-                */
-               if (!test_opt(sb, DISCARD))
-                       EXT4_MB_GRP_CLEAR_TRIMMED(db);
+       /*
+        * Clear the trimmed flag for the group so that the next
+        * ext4_trim_fs can trim it.
+        * If the volume is mounted with -o discard, online discard
+        * is supported and the free blocks will be trimmed online.
+        */
+       if (!test_opt(sb, DISCARD))
+               EXT4_MB_GRP_CLEAR_TRIMMED(db);
 
-               if (!db->bb_free_root.rb_node) {
-                       /* No more items in the per group rb tree
-                        * balance refcounts from ext4_mb_free_metadata()
-                        */
-                       page_cache_release(e4b.bd_buddy_page);
-                       page_cache_release(e4b.bd_bitmap_page);
-               }
-               ext4_unlock_group(sb, entry->group);
-               kmem_cache_free(ext4_free_ext_cachep, entry);
-               ext4_mb_unload_buddy(&e4b);
+       if (!db->bb_free_root.rb_node) {
+               /* No more items in the per group rb tree
+                * balance refcounts from ext4_mb_free_metadata()
+                */
+               page_cache_release(e4b.bd_buddy_page);
+               page_cache_release(e4b.bd_bitmap_page);
        }
+       ext4_unlock_group(sb, entry->efd_group);
+       kmem_cache_free(ext4_free_data_cachep, entry);
+       ext4_mb_unload_buddy(&e4b);
 
        mb_debug(1, "freed %u blocks in %u structures\n", count, count2);
 }
@@ -2741,9 +2688,9 @@ int __init ext4_init_mballoc(void)
                return -ENOMEM;
        }
 
-       ext4_free_ext_cachep = KMEM_CACHE(ext4_free_data,
-                                         SLAB_RECLAIM_ACCOUNT);
-       if (ext4_free_ext_cachep == NULL) {
+       ext4_free_data_cachep = KMEM_CACHE(ext4_free_data,
+                                          SLAB_RECLAIM_ACCOUNT);
+       if (ext4_free_data_cachep == NULL) {
                kmem_cache_destroy(ext4_pspace_cachep);
                kmem_cache_destroy(ext4_ac_cachep);
                return -ENOMEM;
@@ -2761,7 +2708,7 @@ void ext4_exit_mballoc(void)
        rcu_barrier();
        kmem_cache_destroy(ext4_pspace_cachep);
        kmem_cache_destroy(ext4_ac_cachep);
-       kmem_cache_destroy(ext4_free_ext_cachep);
+       kmem_cache_destroy(ext4_free_data_cachep);
        ext4_groupinfo_destroy_slabs();
        ext4_remove_debugfs_entry();
 }
@@ -2815,7 +2762,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
        len = EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
        if (!ext4_data_block_valid(sbi, block, len)) {
                ext4_error(sb, "Allocating blocks %llu-%llu which overlap "
-                          "fs metadata\n", block, block+len);
+                          "fs metadata", block, block+len);
                /* File system mounted not to panic on error
                 * Fix the bitmap and repeat the block allocation
                 * We leak some of the blocks here.
@@ -2911,7 +2858,8 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
        struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
        int bsbits, max;
        ext4_lblk_t end;
-       loff_t size, orig_size, start_off;
+       loff_t size, start_off;
+       loff_t orig_size __maybe_unused;
        ext4_lblk_t start;
        struct ext4_inode_info *ei = EXT4_I(ac->ac_inode);
        struct ext4_prealloc_space *pa;
@@ -3321,8 +3269,8 @@ static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap,
        n = rb_first(&(grp->bb_free_root));
 
        while (n) {
-               entry = rb_entry(n, struct ext4_free_data, node);
-               ext4_set_bits(bitmap, entry->start_cluster, entry->count);
+               entry = rb_entry(n, struct ext4_free_data, efd_node);
+               ext4_set_bits(bitmap, entry->efd_start_cluster, entry->efd_count);
                n = rb_next(n);
        }
        return;
@@ -3916,11 +3864,11 @@ static void ext4_mb_show_ac(struct ext4_allocation_context *ac)
            (EXT4_SB(sb)->s_mount_flags & EXT4_MF_FS_ABORTED))
                return;
 
-       ext4_msg(ac->ac_sb, KERN_ERR, "EXT4-fs: Can't allocate:"
+       ext4_msg(ac->ac_sb, KERN_ERR, "Can't allocate:"
                        " Allocation context details:");
-       ext4_msg(ac->ac_sb, KERN_ERR, "EXT4-fs: status %d flags %d",
+       ext4_msg(ac->ac_sb, KERN_ERR, "status %d flags %d",
                        ac->ac_status, ac->ac_flags);
-       ext4_msg(ac->ac_sb, KERN_ERR, "EXT4-fs: orig %lu/%lu/%lu@%lu, "
+       ext4_msg(ac->ac_sb, KERN_ERR, "orig %lu/%lu/%lu@%lu, "
                        "goal %lu/%lu/%lu@%lu, "
                        "best %lu/%lu/%lu@%lu cr %d",
                        (unsigned long)ac->ac_o_ex.fe_group,
@@ -3936,9 +3884,9 @@ static void ext4_mb_show_ac(struct ext4_allocation_context *ac)
                        (unsigned long)ac->ac_b_ex.fe_len,
                        (unsigned long)ac->ac_b_ex.fe_logical,
                        (int)ac->ac_criteria);
-       ext4_msg(ac->ac_sb, KERN_ERR, "EXT4-fs: %lu scanned, %d found",
+       ext4_msg(ac->ac_sb, KERN_ERR, "%lu scanned, %d found",
                 ac->ac_ex_scanned, ac->ac_found);
-       ext4_msg(ac->ac_sb, KERN_ERR, "EXT4-fs: groups: ");
+       ext4_msg(ac->ac_sb, KERN_ERR, "groups: ");
        ngroups = ext4_get_groups_count(sb);
        for (i = 0; i < ngroups; i++) {
                struct ext4_group_info *grp = ext4_get_group_info(sb, i);
@@ -4428,9 +4376,9 @@ out:
 static int can_merge(struct ext4_free_data *entry1,
                        struct ext4_free_data *entry2)
 {
-       if ((entry1->t_tid == entry2->t_tid) &&
-           (entry1->group == entry2->group) &&
-           ((entry1->start_cluster + entry1->count) == entry2->start_cluster))
+       if ((entry1->efd_tid == entry2->efd_tid) &&
+           (entry1->efd_group == entry2->efd_group) &&
+           ((entry1->efd_start_cluster + entry1->efd_count) == entry2->efd_start_cluster))
                return 1;
        return 0;
 }
@@ -4452,8 +4400,8 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
        BUG_ON(e4b->bd_bitmap_page == NULL);
        BUG_ON(e4b->bd_buddy_page == NULL);
 
-       new_node = &new_entry->node;
-       cluster = new_entry->start_cluster;
+       new_node = &new_entry->efd_node;
+       cluster = new_entry->efd_start_cluster;
 
        if (!*n) {
                /* first free block exent. We need to
@@ -4466,10 +4414,10 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
        }
        while (*n) {
                parent = *n;
-               entry = rb_entry(parent, struct ext4_free_data, node);
-               if (cluster < entry->start_cluster)
+               entry = rb_entry(parent, struct ext4_free_data, efd_node);
+               if (cluster < entry->efd_start_cluster)
                        n = &(*n)->rb_left;
-               else if (cluster >= (entry->start_cluster + entry->count))
+               else if (cluster >= (entry->efd_start_cluster + entry->efd_count))
                        n = &(*n)->rb_right;
                else {
                        ext4_grp_locked_error(sb, group, 0,
@@ -4486,34 +4434,29 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
        /* Now try to see the extent can be merged to left and right */
        node = rb_prev(new_node);
        if (node) {
-               entry = rb_entry(node, struct ext4_free_data, node);
+               entry = rb_entry(node, struct ext4_free_data, efd_node);
                if (can_merge(entry, new_entry)) {
-                       new_entry->start_cluster = entry->start_cluster;
-                       new_entry->count += entry->count;
+                       new_entry->efd_start_cluster = entry->efd_start_cluster;
+                       new_entry->efd_count += entry->efd_count;
                        rb_erase(node, &(db->bb_free_root));
-                       spin_lock(&sbi->s_md_lock);
-                       list_del(&entry->list);
-                       spin_unlock(&sbi->s_md_lock);
-                       kmem_cache_free(ext4_free_ext_cachep, entry);
+                       ext4_journal_callback_del(handle, &entry->efd_jce);
+                       kmem_cache_free(ext4_free_data_cachep, entry);
                }
        }
 
        node = rb_next(new_node);
        if (node) {
-               entry = rb_entry(node, struct ext4_free_data, node);
+               entry = rb_entry(node, struct ext4_free_data, efd_node);
                if (can_merge(new_entry, entry)) {
-                       new_entry->count += entry->count;
+                       new_entry->efd_count += entry->efd_count;
                        rb_erase(node, &(db->bb_free_root));
-                       spin_lock(&sbi->s_md_lock);
-                       list_del(&entry->list);
-                       spin_unlock(&sbi->s_md_lock);
-                       kmem_cache_free(ext4_free_ext_cachep, entry);
+                       ext4_journal_callback_del(handle, &entry->efd_jce);
+                       kmem_cache_free(ext4_free_data_cachep, entry);
                }
        }
        /* Add the extent to transaction's private list */
-       spin_lock(&sbi->s_md_lock);
-       list_add(&new_entry->list, &handle->h_transaction->t_private_list);
-       spin_unlock(&sbi->s_md_lock);
+       ext4_journal_callback_add(handle, ext4_free_data_callback,
+                                 &new_entry->efd_jce);
        return 0;
 }
 
@@ -4691,15 +4634,15 @@ do_more:
                 * blocks being freed are metadata. these blocks shouldn't
                 * be used until this transaction is committed
                 */
-               new_entry = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS);
+               new_entry = kmem_cache_alloc(ext4_free_data_cachep, GFP_NOFS);
                if (!new_entry) {
                        err = -ENOMEM;
                        goto error_return;
                }
-               new_entry->start_cluster = bit;
-               new_entry->group  = block_group;
-               new_entry->count = count_clusters;
-               new_entry->t_tid = handle->h_transaction->t_tid;
+               new_entry->efd_start_cluster = bit;
+               new_entry->efd_group = block_group;
+               new_entry->efd_count = count_clusters;
+               new_entry->efd_tid = handle->h_transaction->t_tid;
 
                ext4_lock_group(sb, block_group);
                mb_clear_bits(bitmap_bh->b_data, bit, count_clusters);
@@ -4971,11 +4914,11 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
        start = (e4b.bd_info->bb_first_free > start) ?
                e4b.bd_info->bb_first_free : start;
 
-       while (start < max) {
-               start = mb_find_next_zero_bit(bitmap, max, start);
-               if (start >= max)
+       while (start <= max) {
+               start = mb_find_next_zero_bit(bitmap, max + 1, start);
+               if (start > max)
                        break;
-               next = mb_find_next_bit(bitmap, max, start);
+               next = mb_find_next_bit(bitmap, max + 1, start);
 
                if ((next - start) >= minblocks) {
                        ext4_trim_extent(sb, start,
@@ -5027,37 +4970,36 @@ out:
 int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
 {
        struct ext4_group_info *grp;
-       ext4_group_t first_group, last_group;
-       ext4_group_t group, ngroups = ext4_get_groups_count(sb);
+       ext4_group_t group, first_group, last_group;
        ext4_grpblk_t cnt = 0, first_cluster, last_cluster;
-       uint64_t start, len, minlen, trimmed = 0;
+       uint64_t start, end, minlen, trimmed = 0;
        ext4_fsblk_t first_data_blk =
                        le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block);
+       ext4_fsblk_t max_blks = ext4_blocks_count(EXT4_SB(sb)->s_es);
        int ret = 0;
 
        start = range->start >> sb->s_blocksize_bits;
-       len = range->len >> sb->s_blocksize_bits;
+       end = start + (range->len >> sb->s_blocksize_bits) - 1;
        minlen = range->minlen >> sb->s_blocksize_bits;
 
-       if (unlikely(minlen > EXT4_CLUSTERS_PER_GROUP(sb)))
+       if (unlikely(minlen > EXT4_CLUSTERS_PER_GROUP(sb)) ||
+           unlikely(start >= max_blks))
                return -EINVAL;
-       if (start + len <= first_data_blk)
+       if (end >= max_blks)
+               end = max_blks - 1;
+       if (end <= first_data_blk)
                goto out;
-       if (start < first_data_blk) {
-               len -= first_data_blk - start;
+       if (start < first_data_blk)
                start = first_data_blk;
-       }
 
-       /* Determine first and last group to examine based on start and len */
+       /* Determine first and last group to examine based on start and end */
        ext4_get_group_no_and_offset(sb, (ext4_fsblk_t) start,
                                     &first_group, &first_cluster);
-       ext4_get_group_no_and_offset(sb, (ext4_fsblk_t) (start + len),
+       ext4_get_group_no_and_offset(sb, (ext4_fsblk_t) end,
                                     &last_group, &last_cluster);
-       last_group = (last_group > ngroups - 1) ? ngroups - 1 : last_group;
-       last_cluster = EXT4_CLUSTERS_PER_GROUP(sb);
 
-       if (first_group > last_group)
-               return -EINVAL;
+       /* end now represents the last cluster to discard in this group */
+       end = EXT4_CLUSTERS_PER_GROUP(sb) - 1;
 
        for (group = first_group; group <= last_group; group++) {
                grp = ext4_get_group_info(sb, group);
@@ -5069,31 +5011,35 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
                }
 
                /*
-                * For all the groups except the last one, last block will
-                * always be EXT4_BLOCKS_PER_GROUP(sb), so we only need to
-                * change it for the last group in which case start +
-                * len < EXT4_BLOCKS_PER_GROUP(sb).
+                * For all the groups except the last one, last cluster will
+                * always be EXT4_CLUSTERS_PER_GROUP(sb)-1, so we only need to
+                * change it for the last group, note that last_cluster is
+                * already computed earlier by ext4_get_group_no_and_offset()
                 */
-               if (first_cluster + len < EXT4_CLUSTERS_PER_GROUP(sb))
-                       last_cluster = first_cluster + len;
-               len -= last_cluster - first_cluster;
+               if (group == last_group)
+                       end = last_cluster;
 
                if (grp->bb_free >= minlen) {
                        cnt = ext4_trim_all_free(sb, group, first_cluster,
-                                               last_cluster, minlen);
+                                               end, minlen);
                        if (cnt < 0) {
                                ret = cnt;
                                break;
                        }
+                       trimmed += cnt;
                }
-               trimmed += cnt;
+
+               /*
+                * For every group except the first one, we are sure
+                * that the first cluster to discard will be cluster #0.
+                */
                first_cluster = 0;
        }
-       range->len = trimmed * sb->s_blocksize;
 
        if (!ret)
                atomic_set(&EXT4_SB(sb)->s_last_trim_minblks, minlen);
 
 out:
+       range->len = trimmed * sb->s_blocksize;
        return ret;
 }
index 47705f3285e3c145f171dcd2add8c6d311d8298e..c070618c21ce8e4d4f6bb00fff94136e2c2bf615 100644 (file)
@@ -96,21 +96,23 @@ extern u8 mb_enable_debug;
 
 
 struct ext4_free_data {
-       /* this links the free block information from group_info */
-       struct rb_node node;
+       /* MUST be the first member */
+       struct ext4_journal_cb_entry    efd_jce;
+
+       /* ext4_free_data private data starts from here */
 
-       /* this links the free block information from ext4_sb_info */
-       struct list_head list;
+       /* this links the free block information from group_info */
+       struct rb_node                  efd_node;
 
        /* group which free block extent belongs */
-       ext4_group_t group;
+       ext4_group_t                    efd_group;
 
        /* free block extent */
-       ext4_grpblk_t start_cluster;
-       ext4_grpblk_t count;
+       ext4_grpblk_t                   efd_start_cluster;
+       ext4_grpblk_t                   efd_count;
 
        /* transaction which freed this extent */
-       tid_t   t_tid;
+       tid_t                           efd_tid;
 };
 
 struct ext4_prealloc_space {
@@ -210,8 +212,6 @@ struct ext4_buddy {
        __u16 bd_blkbits;
        ext4_group_t bd_group;
 };
-#define EXT4_MB_BITMAP(e4b)    ((e4b)->bd_bitmap)
-#define EXT4_MB_BUDDY(e4b)     ((e4b)->bd_buddy)
 
 static inline ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb,
                                        struct ext4_free_extent *fex)
index e7d6bb0acfa6ccfd40e6a4f2e5ebd4e668374852..f39f80f8f2c541a78da45065b535100ffecadd5d 100644 (file)
@@ -471,7 +471,7 @@ int ext4_ext_migrate(struct inode *inode)
        tmp_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode,
                                   S_IFREG, NULL, goal, owner);
        if (IS_ERR(tmp_inode)) {
-               retval = PTR_ERR(inode);
+               retval = PTR_ERR(tmp_inode);
                ext4_journal_stop(handle);
                return retval;
        }
index 7ea4ba4eff2ac4b9dbcae63a54ee68bb5e1a7190..ed6548d89165e1d9c31118aca21d3e89a3772ab2 100644 (file)
@@ -257,8 +257,8 @@ int ext4_multi_mount_protect(struct super_block *sb,
         * If check_interval in MMP block is larger, use that instead of
         * update_interval from the superblock.
         */
-       if (mmp->mmp_check_interval > mmp_check_interval)
-               mmp_check_interval = mmp->mmp_check_interval;
+       if (le16_to_cpu(mmp->mmp_check_interval) > mmp_check_interval)
+               mmp_check_interval = le16_to_cpu(mmp->mmp_check_interval);
 
        seq = le32_to_cpu(mmp->mmp_seq);
        if (seq == EXT4_MMP_SEQ_CLEAN)
index 2043f482375d000c517093f844ed2ce873802a0e..349d7b3671c863ce1565a5d2a184c6bbdafbf6e3 100644 (file)
@@ -468,7 +468,7 @@ fail2:
 fail:
        if (*err == ERR_BAD_DX_DIR)
                ext4_warning(dir->i_sb,
-                            "Corrupt dir inode %ld, running e2fsck is "
+                            "Corrupt dir inode %lu, running e2fsck is "
                             "recommended.", dir->i_ino);
        return NULL;
 }
index 4758518965187749815eb7b76736313faa5e95c5..74cd1f7f1f888947ac6ef3e2f07c7ec60a66a748 100644 (file)
@@ -60,7 +60,6 @@ void ext4_ioend_wait(struct inode *inode)
 static void put_io_page(struct ext4_io_page *io_page)
 {
        if (atomic_dec_and_test(&io_page->p_count)) {
-               end_page_writeback(io_page->p_page);
                put_page(io_page->p_page);
                kmem_cache_free(io_page_cachep, io_page);
        }
@@ -110,6 +109,8 @@ int ext4_end_io_nolock(ext4_io_end_t *io)
        if (io->iocb)
                aio_complete(io->iocb, io->result, 0);
 
+       if (io->flag & EXT4_IO_END_DIRECT)
+               inode_dio_done(inode);
        /* Wake up anyone waiting on unwritten extent conversion */
        if (atomic_dec_and_test(&EXT4_I(inode)->i_aiodio_unwritten))
                wake_up_all(ext4_ioend_wq(io->inode));
@@ -127,12 +128,18 @@ static void ext4_end_io_work(struct work_struct *work)
        unsigned long           flags;
 
        spin_lock_irqsave(&ei->i_completed_io_lock, flags);
+       if (io->flag & EXT4_IO_END_IN_FSYNC)
+               goto requeue;
        if (list_empty(&io->list)) {
                spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
                goto free;
        }
 
        if (!mutex_trylock(&inode->i_mutex)) {
+               bool was_queued;
+requeue:
+               was_queued = !!(io->flag & EXT4_IO_END_QUEUED);
+               io->flag |= EXT4_IO_END_QUEUED;
                spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
                /*
                 * Requeue the work instead of waiting so that the work
@@ -145,9 +152,8 @@ static void ext4_end_io_work(struct work_struct *work)
                 * yield the cpu if it sees an end_io request that has already
                 * been requeued.
                 */
-               if (io->flag & EXT4_IO_END_QUEUED)
+               if (was_queued)
                        yield();
-               io->flag |= EXT4_IO_END_QUEUED;
                return;
        }
        list_del_init(&io->list);
@@ -227,9 +233,9 @@ static void ext4_end_bio(struct bio *bio, int error)
                        } while (bh != head);
                }
 
-               put_io_page(io_end->pages[i]);
+               if (atomic_read(&io_end->pages[i]->p_count) == 1)
+                       end_page_writeback(io_end->pages[i]->p_page);
        }
-       io_end->num_io_pages = 0;
        inode = io_end->inode;
 
        if (error) {
@@ -421,6 +427,8 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
         * PageWriteback bit from the page to prevent the system from
         * wedging later on.
         */
+       if (atomic_read(&io_page->p_count) == 1)
+               end_page_writeback(page);
        put_io_page(io_page);
        return ret;
 }
index f9d948f0eb861f08de3ef7b589b401846dc627f6..59fa0be272516adf6cbbc94384106690bf710c65 100644 (file)
@@ -1163,8 +1163,11 @@ static void ext4_update_super(struct super_block *sb,
        do_div(reserved_blocks, 100);
 
        ext4_blocks_count_set(es, ext4_blocks_count(es) + blocks_count);
+       ext4_free_blocks_count_set(es, ext4_free_blocks_count(es) + free_blocks);
        le32_add_cpu(&es->s_inodes_count, EXT4_INODES_PER_GROUP(sb) *
                     flex_gd->count);
+       le32_add_cpu(&es->s_free_inodes_count, EXT4_INODES_PER_GROUP(sb) *
+                    flex_gd->count);
 
        /*
         * We need to protect s_groups_count against other CPUs seeing
@@ -1465,6 +1468,7 @@ static int ext4_group_extend_no_check(struct super_block *sb,
        }
 
        ext4_blocks_count_set(es, o_blocks_count + add);
+       ext4_free_blocks_count_set(es, ext4_free_blocks_count(es) + add);
        ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count,
                   o_blocks_count + add);
        /* We add the blocks to the bitmap and set the group need init bit */
@@ -1512,16 +1516,17 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
        o_blocks_count = ext4_blocks_count(es);
 
        if (test_opt(sb, DEBUG))
-               printk(KERN_DEBUG "EXT4-fs: extending last group from %llu to %llu blocks\n",
-                      o_blocks_count, n_blocks_count);
+               ext4_msg(sb, KERN_DEBUG,
+                        "extending last group from %llu to %llu blocks",
+                        o_blocks_count, n_blocks_count);
 
        if (n_blocks_count == 0 || n_blocks_count == o_blocks_count)
                return 0;
 
        if (n_blocks_count > (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) {
-               printk(KERN_ERR "EXT4-fs: filesystem on %s:"
-                       " too large to resize to %llu blocks safely\n",
-                       sb->s_id, n_blocks_count);
+               ext4_msg(sb, KERN_ERR,
+                        "filesystem too large to resize to %llu blocks safely",
+                        n_blocks_count);
                if (sizeof(sector_t) < 8)
                        ext4_warning(sb, "CONFIG_LBDAF not enabled");
                return -EINVAL;
@@ -1582,7 +1587,7 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
        ext4_fsblk_t o_blocks_count;
        ext4_group_t o_group;
        ext4_group_t n_group;
-       ext4_grpblk_t offset;
+       ext4_grpblk_t offset, add;
        unsigned long n_desc_blocks;
        unsigned long o_desc_blocks;
        unsigned long desc_blocks;
@@ -1591,8 +1596,8 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
        o_blocks_count = ext4_blocks_count(es);
 
        if (test_opt(sb, DEBUG))
-               printk(KERN_DEBUG "EXT4-fs: resizing filesystem from %llu "
-                      "upto %llu blocks\n", o_blocks_count, n_blocks_count);
+               ext4_msg(sb, KERN_DEBUG, "resizing filesystem from %llu "
+                      "to %llu blocks", o_blocks_count, n_blocks_count);
 
        if (n_blocks_count < o_blocks_count) {
                /* On-line shrinking not supported */
@@ -1605,7 +1610,7 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
                return 0;
 
        ext4_get_group_no_and_offset(sb, n_blocks_count - 1, &n_group, &offset);
-       ext4_get_group_no_and_offset(sb, o_blocks_count, &o_group, &offset);
+       ext4_get_group_no_and_offset(sb, o_blocks_count - 1, &o_group, &offset);
 
        n_desc_blocks = (n_group + EXT4_DESC_PER_BLOCK(sb)) /
                        EXT4_DESC_PER_BLOCK(sb);
@@ -1634,10 +1639,12 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
        }
        brelse(bh);
 
-       if (offset != 0) {
-               /* extend the last group */
-               ext4_grpblk_t add;
-               add = EXT4_BLOCKS_PER_GROUP(sb) - offset;
+       /* extend the last group */
+       if (n_group == o_group)
+               add = n_blocks_count - o_blocks_count;
+       else
+               add = EXT4_BLOCKS_PER_GROUP(sb) - (offset + 1);
+       if (add > 0) {
                err = ext4_group_extend_no_check(sb, o_blocks_count, add);
                if (err)
                        goto out;
@@ -1674,7 +1681,7 @@ out:
 
        iput(resize_inode);
        if (test_opt(sb, DEBUG))
-               printk(KERN_DEBUG "EXT4-fs: resized filesystem from %llu "
-                      "upto %llu blocks\n", o_blocks_count, n_blocks_count);
+               ext4_msg(sb, KERN_DEBUG, "resized filesystem from %llu "
+                      "upto %llu blocks", o_blocks_count, n_blocks_count);
        return err;
 }
index 933900909ed0facb352e8d2c86c19a456a4fbb49..ceebaf853beb74c7e139e63f46bf44975696566b 100644 (file)
@@ -62,6 +62,7 @@ static struct ext4_features *ext4_feat;
 
 static int ext4_load_journal(struct super_block *, struct ext4_super_block *,
                             unsigned long journal_devnum);
+static int ext4_show_options(struct seq_file *seq, struct dentry *root);
 static int ext4_commit_super(struct super_block *sb, int sync);
 static void ext4_mark_recovery_complete(struct super_block *sb,
                                        struct ext4_super_block *es);
@@ -375,7 +376,7 @@ void ext4_journal_abort_handle(const char *caller, unsigned int line,
        if (is_handle_aborted(handle))
                return;
 
-       printk(KERN_ERR "%s:%d: aborting transaction: %s in %s\n",
+       printk(KERN_ERR "EXT4-fs: %s:%d: aborting transaction: %s in %s\n",
               caller, line, errstr, err_fn);
 
        jbd2_journal_abort_handle(handle);
@@ -431,6 +432,22 @@ static int block_device_ejected(struct super_block *sb)
        return bdi->dev == NULL;
 }
 
+static void ext4_journal_commit_callback(journal_t *journal, transaction_t *txn)
+{
+       struct super_block              *sb = journal->j_private;
+       struct ext4_sb_info             *sbi = EXT4_SB(sb);
+       int                             error = is_journal_aborted(journal);
+       struct ext4_journal_cb_entry    *jce, *tmp;
+
+       spin_lock(&sbi->s_md_lock);
+       list_for_each_entry_safe(jce, tmp, &txn->t_private_list, jce_list) {
+               list_del_init(&jce->jce_list);
+               spin_unlock(&sbi->s_md_lock);
+               jce->jce_func(sb, jce, error);
+               spin_lock(&sbi->s_md_lock);
+       }
+       spin_unlock(&sbi->s_md_lock);
+}
 
 /* Deal with the reporting of failure conditions on a filesystem such as
  * inconsistencies detected or read IO failures.
@@ -498,11 +515,16 @@ void ext4_error_inode(struct inode *inode, const char *function,
        va_start(args, fmt);
        vaf.fmt = fmt;
        vaf.va = &args;
-       printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: inode #%lu: ",
-              inode->i_sb->s_id, function, line, inode->i_ino);
        if (block)
-               printk(KERN_CONT "block %llu: ", block);
-       printk(KERN_CONT "comm %s: %pV\n", current->comm, &vaf);
+               printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: "
+                      "inode #%lu: block %llu: comm %s: %pV\n",
+                      inode->i_sb->s_id, function, line, inode->i_ino,
+                      block, current->comm, &vaf);
+       else
+               printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: "
+                      "inode #%lu: comm %s: %pV\n",
+                      inode->i_sb->s_id, function, line, inode->i_ino,
+                      current->comm, &vaf);
        va_end(args);
 
        ext4_handle_error(inode->i_sb);
@@ -524,15 +546,21 @@ void ext4_error_file(struct file *file, const char *function,
        path = d_path(&(file->f_path), pathname, sizeof(pathname));
        if (IS_ERR(path))
                path = "(unknown)";
-       printk(KERN_CRIT
-              "EXT4-fs error (device %s): %s:%d: inode #%lu: ",
-              inode->i_sb->s_id, function, line, inode->i_ino);
-       if (block)
-               printk(KERN_CONT "block %llu: ", block);
        va_start(args, fmt);
        vaf.fmt = fmt;
        vaf.va = &args;
-       printk(KERN_CONT "comm %s: path %s: %pV\n", current->comm, path, &vaf);
+       if (block)
+               printk(KERN_CRIT
+                      "EXT4-fs error (device %s): %s:%d: inode #%lu: "
+                      "block %llu: comm %s: path %s: %pV\n",
+                      inode->i_sb->s_id, function, line, inode->i_ino,
+                      block, current->comm, path, &vaf);
+       else
+               printk(KERN_CRIT
+                      "EXT4-fs error (device %s): %s:%d: inode #%lu: "
+                      "comm %s: path %s: %pV\n",
+                      inode->i_sb->s_id, function, line, inode->i_ino,
+                      current->comm, path, &vaf);
        va_end(args);
 
        ext4_handle_error(inode->i_sb);
@@ -808,9 +836,6 @@ static void ext4_put_super(struct super_block *sb)
        destroy_workqueue(sbi->dio_unwritten_wq);
 
        lock_super(sb);
-       if (sb->s_dirt)
-               ext4_commit_super(sb, 1);
-
        if (sbi->s_journal) {
                err = jbd2_journal_destroy(sbi->s_journal);
                sbi->s_journal = NULL;
@@ -827,9 +852,12 @@ static void ext4_put_super(struct super_block *sb)
        if (!(sb->s_flags & MS_RDONLY)) {
                EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
                es->s_state = cpu_to_le16(sbi->s_mount_state);
-               ext4_commit_super(sb, 1);
        }
+       if (sb->s_dirt || !(sb->s_flags & MS_RDONLY))
+               ext4_commit_super(sb, 1);
+
        if (sbi->s_proc) {
+               remove_proc_entry("options", sbi->s_proc);
                remove_proc_entry(sb->s_id, ext4_proc_root);
        }
        kobject_del(&sbi->s_kobj);
@@ -990,180 +1018,6 @@ void ext4_clear_inode(struct inode *inode)
        }
 }
 
-static inline void ext4_show_quota_options(struct seq_file *seq,
-                                          struct super_block *sb)
-{
-#if defined(CONFIG_QUOTA)
-       struct ext4_sb_info *sbi = EXT4_SB(sb);
-
-       if (sbi->s_jquota_fmt) {
-               char *fmtname = "";
-
-               switch (sbi->s_jquota_fmt) {
-               case QFMT_VFS_OLD:
-                       fmtname = "vfsold";
-                       break;
-               case QFMT_VFS_V0:
-                       fmtname = "vfsv0";
-                       break;
-               case QFMT_VFS_V1:
-                       fmtname = "vfsv1";
-                       break;
-               }
-               seq_printf(seq, ",jqfmt=%s", fmtname);
-       }
-
-       if (sbi->s_qf_names[USRQUOTA])
-               seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]);
-
-       if (sbi->s_qf_names[GRPQUOTA])
-               seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]);
-
-       if (test_opt(sb, USRQUOTA))
-               seq_puts(seq, ",usrquota");
-
-       if (test_opt(sb, GRPQUOTA))
-               seq_puts(seq, ",grpquota");
-#endif
-}
-
-/*
- * Show an option if
- *  - it's set to a non-default value OR
- *  - if the per-sb default is different from the global default
- */
-static int ext4_show_options(struct seq_file *seq, struct dentry *root)
-{
-       int def_errors;
-       unsigned long def_mount_opts;
-       struct super_block *sb = root->d_sb;
-       struct ext4_sb_info *sbi = EXT4_SB(sb);
-       struct ext4_super_block *es = sbi->s_es;
-
-       def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
-       def_errors     = le16_to_cpu(es->s_errors);
-
-       if (sbi->s_sb_block != 1)
-               seq_printf(seq, ",sb=%llu", sbi->s_sb_block);
-       if (test_opt(sb, MINIX_DF))
-               seq_puts(seq, ",minixdf");
-       if (test_opt(sb, GRPID) && !(def_mount_opts & EXT4_DEFM_BSDGROUPS))
-               seq_puts(seq, ",grpid");
-       if (!test_opt(sb, GRPID) && (def_mount_opts & EXT4_DEFM_BSDGROUPS))
-               seq_puts(seq, ",nogrpid");
-       if (sbi->s_resuid != EXT4_DEF_RESUID ||
-           le16_to_cpu(es->s_def_resuid) != EXT4_DEF_RESUID) {
-               seq_printf(seq, ",resuid=%u", sbi->s_resuid);
-       }
-       if (sbi->s_resgid != EXT4_DEF_RESGID ||
-           le16_to_cpu(es->s_def_resgid) != EXT4_DEF_RESGID) {
-               seq_printf(seq, ",resgid=%u", sbi->s_resgid);
-       }
-       if (test_opt(sb, ERRORS_RO)) {
-               if (def_errors == EXT4_ERRORS_PANIC ||
-                   def_errors == EXT4_ERRORS_CONTINUE) {
-                       seq_puts(seq, ",errors=remount-ro");
-               }
-       }
-       if (test_opt(sb, ERRORS_CONT) && def_errors != EXT4_ERRORS_CONTINUE)
-               seq_puts(seq, ",errors=continue");
-       if (test_opt(sb, ERRORS_PANIC) && def_errors != EXT4_ERRORS_PANIC)
-               seq_puts(seq, ",errors=panic");
-       if (test_opt(sb, NO_UID32) && !(def_mount_opts & EXT4_DEFM_UID16))
-               seq_puts(seq, ",nouid32");
-       if (test_opt(sb, DEBUG) && !(def_mount_opts & EXT4_DEFM_DEBUG))
-               seq_puts(seq, ",debug");
-#ifdef CONFIG_EXT4_FS_XATTR
-       if (test_opt(sb, XATTR_USER))
-               seq_puts(seq, ",user_xattr");
-       if (!test_opt(sb, XATTR_USER))
-               seq_puts(seq, ",nouser_xattr");
-#endif
-#ifdef CONFIG_EXT4_FS_POSIX_ACL
-       if (test_opt(sb, POSIX_ACL) && !(def_mount_opts & EXT4_DEFM_ACL))
-               seq_puts(seq, ",acl");
-       if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT4_DEFM_ACL))
-               seq_puts(seq, ",noacl");
-#endif
-       if (sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ) {
-               seq_printf(seq, ",commit=%u",
-                          (unsigned) (sbi->s_commit_interval / HZ));
-       }
-       if (sbi->s_min_batch_time != EXT4_DEF_MIN_BATCH_TIME) {
-               seq_printf(seq, ",min_batch_time=%u",
-                          (unsigned) sbi->s_min_batch_time);
-       }
-       if (sbi->s_max_batch_time != EXT4_DEF_MAX_BATCH_TIME) {
-               seq_printf(seq, ",max_batch_time=%u",
-                          (unsigned) sbi->s_max_batch_time);
-       }
-
-       /*
-        * We're changing the default of barrier mount option, so
-        * let's always display its mount state so it's clear what its
-        * status is.
-        */
-       seq_puts(seq, ",barrier=");
-       seq_puts(seq, test_opt(sb, BARRIER) ? "1" : "0");
-       if (test_opt(sb, JOURNAL_ASYNC_COMMIT))
-               seq_puts(seq, ",journal_async_commit");
-       else if (test_opt(sb, JOURNAL_CHECKSUM))
-               seq_puts(seq, ",journal_checksum");
-       if (test_opt(sb, I_VERSION))
-               seq_puts(seq, ",i_version");
-       if (!test_opt(sb, DELALLOC) &&
-           !(def_mount_opts & EXT4_DEFM_NODELALLOC))
-               seq_puts(seq, ",nodelalloc");
-
-       if (!test_opt(sb, MBLK_IO_SUBMIT))
-               seq_puts(seq, ",nomblk_io_submit");
-       if (sbi->s_stripe)
-               seq_printf(seq, ",stripe=%lu", sbi->s_stripe);
-       /*
-        * journal mode get enabled in different ways
-        * So just print the value even if we didn't specify it
-        */
-       if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
-               seq_puts(seq, ",data=journal");
-       else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
-               seq_puts(seq, ",data=ordered");
-       else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
-               seq_puts(seq, ",data=writeback");
-
-       if (sbi->s_inode_readahead_blks != EXT4_DEF_INODE_READAHEAD_BLKS)
-               seq_printf(seq, ",inode_readahead_blks=%u",
-                          sbi->s_inode_readahead_blks);
-
-       if (test_opt(sb, DATA_ERR_ABORT))
-               seq_puts(seq, ",data_err=abort");
-
-       if (test_opt(sb, NO_AUTO_DA_ALLOC))
-               seq_puts(seq, ",noauto_da_alloc");
-
-       if (test_opt(sb, DISCARD) && !(def_mount_opts & EXT4_DEFM_DISCARD))
-               seq_puts(seq, ",discard");
-
-       if (test_opt(sb, NOLOAD))
-               seq_puts(seq, ",norecovery");
-
-       if (test_opt(sb, DIOREAD_NOLOCK))
-               seq_puts(seq, ",dioread_nolock");
-
-       if (test_opt(sb, BLOCK_VALIDITY) &&
-           !(def_mount_opts & EXT4_DEFM_BLOCK_VALIDITY))
-               seq_puts(seq, ",block_validity");
-
-       if (!test_opt(sb, INIT_INODE_TABLE))
-               seq_puts(seq, ",noinit_itable");
-       else if (sbi->s_li_wait_mult != EXT4_DEF_LI_WAIT_MULT)
-               seq_printf(seq, ",init_itable=%u",
-                          (unsigned) sbi->s_li_wait_mult);
-
-       ext4_show_quota_options(seq, sb);
-
-       return 0;
-}
-
 static struct inode *ext4_nfs_get_inode(struct super_block *sb,
                                        u64 ino, u32 generation)
 {
@@ -1316,18 +1170,17 @@ static const struct export_operations ext4_export_ops = {
 enum {
        Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
        Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
-       Opt_nouid32, Opt_debug, Opt_oldalloc, Opt_orlov,
+       Opt_nouid32, Opt_debug, Opt_removed,
        Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
-       Opt_auto_da_alloc, Opt_noauto_da_alloc, Opt_noload, Opt_nobh, Opt_bh,
+       Opt_auto_da_alloc, Opt_noauto_da_alloc, Opt_noload,
        Opt_commit, Opt_min_batch_time, Opt_max_batch_time,
-       Opt_journal_update, Opt_journal_dev,
-       Opt_journal_checksum, Opt_journal_async_commit,
+       Opt_journal_dev, Opt_journal_checksum, Opt_journal_async_commit,
        Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
        Opt_data_err_abort, Opt_data_err_ignore,
        Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
        Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
-       Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err,
-       Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version,
+       Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err,
+       Opt_usrquota, Opt_grpquota, Opt_i_version,
        Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit,
        Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity,
        Opt_inode_readahead_blks, Opt_journal_ioprio,
@@ -1350,20 +1203,19 @@ static const match_table_t tokens = {
        {Opt_err_ro, "errors=remount-ro"},
        {Opt_nouid32, "nouid32"},
        {Opt_debug, "debug"},
-       {Opt_oldalloc, "oldalloc"},
-       {Opt_orlov, "orlov"},
+       {Opt_removed, "oldalloc"},
+       {Opt_removed, "orlov"},
        {Opt_user_xattr, "user_xattr"},
        {Opt_nouser_xattr, "nouser_xattr"},
        {Opt_acl, "acl"},
        {Opt_noacl, "noacl"},
-       {Opt_noload, "noload"},
        {Opt_noload, "norecovery"},
-       {Opt_nobh, "nobh"},
-       {Opt_bh, "bh"},
+       {Opt_noload, "noload"},
+       {Opt_removed, "nobh"},
+       {Opt_removed, "bh"},
        {Opt_commit, "commit=%u"},
        {Opt_min_batch_time, "min_batch_time=%u"},
        {Opt_max_batch_time, "max_batch_time=%u"},
-       {Opt_journal_update, "journal=update"},
        {Opt_journal_dev, "journal_dev=%u"},
        {Opt_journal_checksum, "journal_checksum"},
        {Opt_journal_async_commit, "journal_async_commit"},
@@ -1389,7 +1241,6 @@ static const match_table_t tokens = {
        {Opt_nobarrier, "nobarrier"},
        {Opt_i_version, "i_version"},
        {Opt_stripe, "stripe=%u"},
-       {Opt_resize, "resize"},
        {Opt_delalloc, "delalloc"},
        {Opt_nodelalloc, "nodelalloc"},
        {Opt_mblk_io_submit, "mblk_io_submit"},
@@ -1408,6 +1259,11 @@ static const match_table_t tokens = {
        {Opt_init_itable, "init_itable=%u"},
        {Opt_init_itable, "init_itable"},
        {Opt_noinit_itable, "noinit_itable"},
+       {Opt_removed, "check=none"},    /* mount option from ext2/3 */
+       {Opt_removed, "nocheck"},       /* mount option from ext2/3 */
+       {Opt_removed, "reservation"},   /* mount option from ext2/3 */
+       {Opt_removed, "noreservation"}, /* mount option from ext2/3 */
+       {Opt_removed, "journal=%u"},    /* mount option from ext2/3 */
        {Opt_err, NULL},
 };
 
@@ -1496,420 +1352,273 @@ static int clear_qf_name(struct super_block *sb, int qtype)
 }
 #endif
 
-static int parse_options(char *options, struct super_block *sb,
-                        unsigned long *journal_devnum,
-                        unsigned int *journal_ioprio,
-                        ext4_fsblk_t *n_blocks_count, int is_remount)
-{
-       struct ext4_sb_info *sbi = EXT4_SB(sb);
-       char *p;
-       substring_t args[MAX_OPT_ARGS];
-       int data_opt = 0;
-       int option;
+#define MOPT_SET       0x0001
+#define MOPT_CLEAR     0x0002
+#define MOPT_NOSUPPORT 0x0004
+#define MOPT_EXPLICIT  0x0008
+#define MOPT_CLEAR_ERR 0x0010
+#define MOPT_GTE0      0x0020
 #ifdef CONFIG_QUOTA
-       int qfmt;
+#define MOPT_Q         0
+#define MOPT_QFMT      0x0040
+#else
+#define MOPT_Q         MOPT_NOSUPPORT
+#define MOPT_QFMT      MOPT_NOSUPPORT
 #endif
-
-       if (!options)
-               return 1;
-
-       while ((p = strsep(&options, ",")) != NULL) {
-               int token;
-               if (!*p)
-                       continue;
-
-               /*
-                * Initialize args struct so we know whether arg was
-                * found; some options take optional arguments.
-                */
-               args[0].to = args[0].from = NULL;
-               token = match_token(p, tokens, args);
-               switch (token) {
-               case Opt_bsd_df:
-                       ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38");
-                       clear_opt(sb, MINIX_DF);
-                       break;
-               case Opt_minix_df:
-                       ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38");
-                       set_opt(sb, MINIX_DF);
-
-                       break;
-               case Opt_grpid:
-                       ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38");
-                       set_opt(sb, GRPID);
-
-                       break;
-               case Opt_nogrpid:
-                       ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38");
-                       clear_opt(sb, GRPID);
-
-                       break;
-               case Opt_resuid:
-                       if (match_int(&args[0], &option))
-                               return 0;
-                       sbi->s_resuid = option;
-                       break;
-               case Opt_resgid:
-                       if (match_int(&args[0], &option))
-                               return 0;
-                       sbi->s_resgid = option;
-                       break;
-               case Opt_sb:
-                       /* handled by get_sb_block() instead of here */
-                       /* *sb_block = match_int(&args[0]); */
-                       break;
-               case Opt_err_panic:
-                       clear_opt(sb, ERRORS_CONT);
-                       clear_opt(sb, ERRORS_RO);
-                       set_opt(sb, ERRORS_PANIC);
-                       break;
-               case Opt_err_ro:
-                       clear_opt(sb, ERRORS_CONT);
-                       clear_opt(sb, ERRORS_PANIC);
-                       set_opt(sb, ERRORS_RO);
-                       break;
-               case Opt_err_cont:
-                       clear_opt(sb, ERRORS_RO);
-                       clear_opt(sb, ERRORS_PANIC);
-                       set_opt(sb, ERRORS_CONT);
-                       break;
-               case Opt_nouid32:
-                       set_opt(sb, NO_UID32);
-                       break;
-               case Opt_debug:
-                       set_opt(sb, DEBUG);
-                       break;
-               case Opt_oldalloc:
-                       ext4_msg(sb, KERN_WARNING,
-                                "Ignoring deprecated oldalloc option");
-                       break;
-               case Opt_orlov:
-                       ext4_msg(sb, KERN_WARNING,
-                                "Ignoring deprecated orlov option");
-                       break;
+#define MOPT_DATAJ     0x0080
+
+static const struct mount_opts {
+       int     token;
+       int     mount_opt;
+       int     flags;
+} ext4_mount_opts[] = {
+       {Opt_minix_df, EXT4_MOUNT_MINIX_DF, MOPT_SET},
+       {Opt_bsd_df, EXT4_MOUNT_MINIX_DF, MOPT_CLEAR},
+       {Opt_grpid, EXT4_MOUNT_GRPID, MOPT_SET},
+       {Opt_nogrpid, EXT4_MOUNT_GRPID, MOPT_CLEAR},
+       {Opt_mblk_io_submit, EXT4_MOUNT_MBLK_IO_SUBMIT, MOPT_SET},
+       {Opt_nomblk_io_submit, EXT4_MOUNT_MBLK_IO_SUBMIT, MOPT_CLEAR},
+       {Opt_block_validity, EXT4_MOUNT_BLOCK_VALIDITY, MOPT_SET},
+       {Opt_noblock_validity, EXT4_MOUNT_BLOCK_VALIDITY, MOPT_CLEAR},
+       {Opt_dioread_nolock, EXT4_MOUNT_DIOREAD_NOLOCK, MOPT_SET},
+       {Opt_dioread_lock, EXT4_MOUNT_DIOREAD_NOLOCK, MOPT_CLEAR},
+       {Opt_discard, EXT4_MOUNT_DISCARD, MOPT_SET},
+       {Opt_nodiscard, EXT4_MOUNT_DISCARD, MOPT_CLEAR},
+       {Opt_delalloc, EXT4_MOUNT_DELALLOC, MOPT_SET | MOPT_EXPLICIT},
+       {Opt_nodelalloc, EXT4_MOUNT_DELALLOC, MOPT_CLEAR | MOPT_EXPLICIT},
+       {Opt_journal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM, MOPT_SET},
+       {Opt_journal_async_commit, (EXT4_MOUNT_JOURNAL_ASYNC_COMMIT |
+                                   EXT4_MOUNT_JOURNAL_CHECKSUM), MOPT_SET},
+       {Opt_noload, EXT4_MOUNT_NOLOAD, MOPT_SET},
+       {Opt_err_panic, EXT4_MOUNT_ERRORS_PANIC, MOPT_SET | MOPT_CLEAR_ERR},
+       {Opt_err_ro, EXT4_MOUNT_ERRORS_RO, MOPT_SET | MOPT_CLEAR_ERR},
+       {Opt_err_cont, EXT4_MOUNT_ERRORS_CONT, MOPT_SET | MOPT_CLEAR_ERR},
+       {Opt_data_err_abort, EXT4_MOUNT_DATA_ERR_ABORT, MOPT_SET},
+       {Opt_data_err_ignore, EXT4_MOUNT_DATA_ERR_ABORT, MOPT_CLEAR},
+       {Opt_barrier, EXT4_MOUNT_BARRIER, MOPT_SET},
+       {Opt_nobarrier, EXT4_MOUNT_BARRIER, MOPT_CLEAR},
+       {Opt_noauto_da_alloc, EXT4_MOUNT_NO_AUTO_DA_ALLOC, MOPT_SET},
+       {Opt_auto_da_alloc, EXT4_MOUNT_NO_AUTO_DA_ALLOC, MOPT_CLEAR},
+       {Opt_noinit_itable, EXT4_MOUNT_INIT_INODE_TABLE, MOPT_CLEAR},
+       {Opt_commit, 0, MOPT_GTE0},
+       {Opt_max_batch_time, 0, MOPT_GTE0},
+       {Opt_min_batch_time, 0, MOPT_GTE0},
+       {Opt_inode_readahead_blks, 0, MOPT_GTE0},
+       {Opt_init_itable, 0, MOPT_GTE0},
+       {Opt_stripe, 0, MOPT_GTE0},
+       {Opt_data_journal, EXT4_MOUNT_JOURNAL_DATA, MOPT_DATAJ},
+       {Opt_data_ordered, EXT4_MOUNT_ORDERED_DATA, MOPT_DATAJ},
+       {Opt_data_writeback, EXT4_MOUNT_WRITEBACK_DATA, MOPT_DATAJ},
 #ifdef CONFIG_EXT4_FS_XATTR
-               case Opt_user_xattr:
-                       set_opt(sb, XATTR_USER);
-                       break;
-               case Opt_nouser_xattr:
-                       clear_opt(sb, XATTR_USER);
-                       break;
+       {Opt_user_xattr, EXT4_MOUNT_XATTR_USER, MOPT_SET},
+       {Opt_nouser_xattr, EXT4_MOUNT_XATTR_USER, MOPT_CLEAR},
 #else
-               case Opt_user_xattr:
-               case Opt_nouser_xattr:
-                       ext4_msg(sb, KERN_ERR, "(no)user_xattr options not supported");
-                       break;
+       {Opt_user_xattr, 0, MOPT_NOSUPPORT},
+       {Opt_nouser_xattr, 0, MOPT_NOSUPPORT},
 #endif
 #ifdef CONFIG_EXT4_FS_POSIX_ACL
-               case Opt_acl:
-                       set_opt(sb, POSIX_ACL);
-                       break;
-               case Opt_noacl:
-                       clear_opt(sb, POSIX_ACL);
-                       break;
+       {Opt_acl, EXT4_MOUNT_POSIX_ACL, MOPT_SET},
+       {Opt_noacl, EXT4_MOUNT_POSIX_ACL, MOPT_CLEAR},
 #else
-               case Opt_acl:
-               case Opt_noacl:
-                       ext4_msg(sb, KERN_ERR, "(no)acl options not supported");
-                       break;
+       {Opt_acl, 0, MOPT_NOSUPPORT},
+       {Opt_noacl, 0, MOPT_NOSUPPORT},
 #endif
-               case Opt_journal_update:
-                       /* @@@ FIXME */
-                       /* Eventually we will want to be able to create
-                          a journal file here.  For now, only allow the
-                          user to specify an existing inode to be the
-                          journal file. */
-                       if (is_remount) {
-                               ext4_msg(sb, KERN_ERR,
-                                        "Cannot specify journal on remount");
-                               return 0;
-                       }
-                       set_opt(sb, UPDATE_JOURNAL);
-                       break;
-               case Opt_journal_dev:
-                       if (is_remount) {
+       {Opt_nouid32, EXT4_MOUNT_NO_UID32, MOPT_SET},
+       {Opt_debug, EXT4_MOUNT_DEBUG, MOPT_SET},
+       {Opt_quota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_USRQUOTA, MOPT_SET | MOPT_Q},
+       {Opt_usrquota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_USRQUOTA,
+                                                       MOPT_SET | MOPT_Q},
+       {Opt_grpquota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_GRPQUOTA,
+                                                       MOPT_SET | MOPT_Q},
+       {Opt_noquota, (EXT4_MOUNT_QUOTA | EXT4_MOUNT_USRQUOTA |
+                      EXT4_MOUNT_GRPQUOTA), MOPT_CLEAR | MOPT_Q},
+       {Opt_usrjquota, 0, MOPT_Q},
+       {Opt_grpjquota, 0, MOPT_Q},
+       {Opt_offusrjquota, 0, MOPT_Q},
+       {Opt_offgrpjquota, 0, MOPT_Q},
+       {Opt_jqfmt_vfsold, QFMT_VFS_OLD, MOPT_QFMT},
+       {Opt_jqfmt_vfsv0, QFMT_VFS_V0, MOPT_QFMT},
+       {Opt_jqfmt_vfsv1, QFMT_VFS_V1, MOPT_QFMT},
+       {Opt_err, 0, 0}
+};
+
+static int handle_mount_opt(struct super_block *sb, char *opt, int token,
+                           substring_t *args, unsigned long *journal_devnum,
+                           unsigned int *journal_ioprio, int is_remount)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       const struct mount_opts *m;
+       int arg = 0;
+
+       if (args->from && match_int(args, &arg))
+               return -1;
+       switch (token) {
+       case Opt_noacl:
+       case Opt_nouser_xattr:
+               ext4_msg(sb, KERN_WARNING, deprecated_msg, opt, "3.5");
+               break;
+       case Opt_sb:
+               return 1;       /* handled by get_sb_block() */
+       case Opt_removed:
+               ext4_msg(sb, KERN_WARNING,
+                        "Ignoring removed %s option", opt);
+               return 1;
+       case Opt_resuid:
+               sbi->s_resuid = arg;
+               return 1;
+       case Opt_resgid:
+               sbi->s_resgid = arg;
+               return 1;
+       case Opt_abort:
+               sbi->s_mount_flags |= EXT4_MF_FS_ABORTED;
+               return 1;
+       case Opt_i_version:
+               sb->s_flags |= MS_I_VERSION;
+               return 1;
+       case Opt_journal_dev:
+               if (is_remount) {
+                       ext4_msg(sb, KERN_ERR,
+                                "Cannot specify journal on remount");
+                       return -1;
+               }
+               *journal_devnum = arg;
+               return 1;
+       case Opt_journal_ioprio:
+               if (arg < 0 || arg > 7)
+                       return -1;
+               *journal_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, arg);
+               return 1;
+       }
+
+       for (m = ext4_mount_opts; m->token != Opt_err; m++) {
+               if (token != m->token)
+                       continue;
+               if (args->from && (m->flags & MOPT_GTE0) && (arg < 0))
+                       return -1;
+               if (m->flags & MOPT_EXPLICIT)
+                       set_opt2(sb, EXPLICIT_DELALLOC);
+               if (m->flags & MOPT_CLEAR_ERR)
+                       clear_opt(sb, ERRORS_MASK);
+               if (token == Opt_noquota && sb_any_quota_loaded(sb)) {
+                       ext4_msg(sb, KERN_ERR, "Cannot change quota "
+                                "options when quota turned on");
+                       return -1;
+               }
+
+               if (m->flags & MOPT_NOSUPPORT) {
+                       ext4_msg(sb, KERN_ERR, "%s option not supported", opt);
+               } else if (token == Opt_commit) {
+                       if (arg == 0)
+                               arg = JBD2_DEFAULT_MAX_COMMIT_AGE;
+                       sbi->s_commit_interval = HZ * arg;
+               } else if (token == Opt_max_batch_time) {
+                       if (arg == 0)
+                               arg = EXT4_DEF_MAX_BATCH_TIME;
+                       sbi->s_max_batch_time = arg;
+               } else if (token == Opt_min_batch_time) {
+                       sbi->s_min_batch_time = arg;
+               } else if (token == Opt_inode_readahead_blks) {
+                       if (arg > (1 << 30))
+                               return -1;
+                       if (arg && !is_power_of_2(arg)) {
                                ext4_msg(sb, KERN_ERR,
-                                       "Cannot specify journal on remount");
-                               return 0;
+                                        "EXT4-fs: inode_readahead_blks"
+                                        " must be a power of 2");
+                               return -1;
                        }
-                       if (match_int(&args[0], &option))
-                               return 0;
-                       *journal_devnum = option;
-                       break;
-               case Opt_journal_checksum:
-                       set_opt(sb, JOURNAL_CHECKSUM);
-                       break;
-               case Opt_journal_async_commit:
-                       set_opt(sb, JOURNAL_ASYNC_COMMIT);
-                       set_opt(sb, JOURNAL_CHECKSUM);
-                       break;
-               case Opt_noload:
-                       set_opt(sb, NOLOAD);
-                       break;
-               case Opt_commit:
-                       if (match_int(&args[0], &option))
-                               return 0;
-                       if (option < 0)
-                               return 0;
-                       if (option == 0)
-                               option = JBD2_DEFAULT_MAX_COMMIT_AGE;
-                       sbi->s_commit_interval = HZ * option;
-                       break;
-               case Opt_max_batch_time:
-                       if (match_int(&args[0], &option))
-                               return 0;
-                       if (option < 0)
-                               return 0;
-                       if (option == 0)
-                               option = EXT4_DEF_MAX_BATCH_TIME;
-                       sbi->s_max_batch_time = option;
-                       break;
-               case Opt_min_batch_time:
-                       if (match_int(&args[0], &option))
-                               return 0;
-                       if (option < 0)
-                               return 0;
-                       sbi->s_min_batch_time = option;
-                       break;
-               case Opt_data_journal:
-                       data_opt = EXT4_MOUNT_JOURNAL_DATA;
-                       goto datacheck;
-               case Opt_data_ordered:
-                       data_opt = EXT4_MOUNT_ORDERED_DATA;
-                       goto datacheck;
-               case Opt_data_writeback:
-                       data_opt = EXT4_MOUNT_WRITEBACK_DATA;
-               datacheck:
+                       sbi->s_inode_readahead_blks = arg;
+               } else if (token == Opt_init_itable) {
+                       set_opt(sb, INIT_INODE_TABLE);
+                       if (!args->from)
+                               arg = EXT4_DEF_LI_WAIT_MULT;
+                       sbi->s_li_wait_mult = arg;
+               } else if (token == Opt_stripe) {
+                       sbi->s_stripe = arg;
+               } else if (m->flags & MOPT_DATAJ) {
                        if (is_remount) {
                                if (!sbi->s_journal)
                                        ext4_msg(sb, KERN_WARNING, "Remounting file system with no journal so ignoring journalled data option");
-                               else if (test_opt(sb, DATA_FLAGS) != data_opt) {
+                               else if (test_opt(sb, DATA_FLAGS) !=
+                                        m->mount_opt) {
                                        ext4_msg(sb, KERN_ERR,
-                                               "Cannot change data mode on remount");
-                                       return 0;
+                                        "Cannot change data mode on remount");
+                                       return -1;
                                }
                        } else {
                                clear_opt(sb, DATA_FLAGS);
-                               sbi->s_mount_opt |= data_opt;
+                               sbi->s_mount_opt |= m->mount_opt;
                        }
-                       break;
-               case Opt_data_err_abort:
-                       set_opt(sb, DATA_ERR_ABORT);
-                       break;
-               case Opt_data_err_ignore:
-                       clear_opt(sb, DATA_ERR_ABORT);
-                       break;
 #ifdef CONFIG_QUOTA
-               case Opt_usrjquota:
+               } else if (token == Opt_usrjquota) {
                        if (!set_qf_name(sb, USRQUOTA, &args[0]))
-                               return 0;
-                       break;
-               case Opt_grpjquota:
+                               return -1;
+               } else if (token == Opt_grpjquota) {
                        if (!set_qf_name(sb, GRPQUOTA, &args[0]))
-                               return 0;
-                       break;
-               case Opt_offusrjquota:
+                               return -1;
+               } else if (token == Opt_offusrjquota) {
                        if (!clear_qf_name(sb, USRQUOTA))
-                               return 0;
-                       break;
-               case Opt_offgrpjquota:
+                               return -1;
+               } else if (token == Opt_offgrpjquota) {
                        if (!clear_qf_name(sb, GRPQUOTA))
-                               return 0;
-                       break;
-
-               case Opt_jqfmt_vfsold:
-                       qfmt = QFMT_VFS_OLD;
-                       goto set_qf_format;
-               case Opt_jqfmt_vfsv0:
-                       qfmt = QFMT_VFS_V0;
-                       goto set_qf_format;
-               case Opt_jqfmt_vfsv1:
-                       qfmt = QFMT_VFS_V1;
-set_qf_format:
+                               return -1;
+               } else if (m->flags & MOPT_QFMT) {
                        if (sb_any_quota_loaded(sb) &&
-                           sbi->s_jquota_fmt != qfmt) {
-                               ext4_msg(sb, KERN_ERR, "Cannot change "
-                                       "journaled quota options when "
-                                       "quota turned on");
-                               return 0;
-                       }
-                       sbi->s_jquota_fmt = qfmt;
-                       break;
-               case Opt_quota:
-               case Opt_usrquota:
-                       set_opt(sb, QUOTA);
-                       set_opt(sb, USRQUOTA);
-                       break;
-               case Opt_grpquota:
-                       set_opt(sb, QUOTA);
-                       set_opt(sb, GRPQUOTA);
-                       break;
-               case Opt_noquota:
-                       if (sb_any_quota_loaded(sb)) {
-                               ext4_msg(sb, KERN_ERR, "Cannot change quota "
-                                       "options when quota turned on");
-                               return 0;
+                           sbi->s_jquota_fmt != m->mount_opt) {
+                               ext4_msg(sb, KERN_ERR, "Cannot "
+                                        "change journaled quota options "
+                                        "when quota turned on");
+                               return -1;
                        }
-                       clear_opt(sb, QUOTA);
-                       clear_opt(sb, USRQUOTA);
-                       clear_opt(sb, GRPQUOTA);
-                       break;
-#else
-               case Opt_quota:
-               case Opt_usrquota:
-               case Opt_grpquota:
-                       ext4_msg(sb, KERN_ERR,
-                               "quota options not supported");
-                       break;
-               case Opt_usrjquota:
-               case Opt_grpjquota:
-               case Opt_offusrjquota:
-               case Opt_offgrpjquota:
-               case Opt_jqfmt_vfsold:
-               case Opt_jqfmt_vfsv0:
-               case Opt_jqfmt_vfsv1:
-                       ext4_msg(sb, KERN_ERR,
-                               "journaled quota options not supported");
-                       break;
-               case Opt_noquota:
-                       break;
+                       sbi->s_jquota_fmt = m->mount_opt;
 #endif
-               case Opt_abort:
-                       sbi->s_mount_flags |= EXT4_MF_FS_ABORTED;
-                       break;
-               case Opt_nobarrier:
-                       clear_opt(sb, BARRIER);
-                       break;
-               case Opt_barrier:
-                       if (args[0].from) {
-                               if (match_int(&args[0], &option))
-                                       return 0;
-                       } else
-                               option = 1;     /* No argument, default to 1 */
-                       if (option)
-                               set_opt(sb, BARRIER);
-                       else
-                               clear_opt(sb, BARRIER);
-                       break;
-               case Opt_ignore:
-                       break;
-               case Opt_resize:
-                       if (!is_remount) {
-                               ext4_msg(sb, KERN_ERR,
-                                       "resize option only available "
-                                       "for remount");
-                               return 0;
-                       }
-                       if (match_int(&args[0], &option) != 0)
-                               return 0;
-                       *n_blocks_count = option;
-                       break;
-               case Opt_nobh:
-                       ext4_msg(sb, KERN_WARNING,
-                                "Ignoring deprecated nobh option");
-                       break;
-               case Opt_bh:
-                       ext4_msg(sb, KERN_WARNING,
-                                "Ignoring deprecated bh option");
-                       break;
-               case Opt_i_version:
-                       set_opt(sb, I_VERSION);
-                       sb->s_flags |= MS_I_VERSION;
-                       break;
-               case Opt_nodelalloc:
-                       clear_opt(sb, DELALLOC);
-                       clear_opt2(sb, EXPLICIT_DELALLOC);
-                       break;
-               case Opt_mblk_io_submit:
-                       set_opt(sb, MBLK_IO_SUBMIT);
-                       break;
-               case Opt_nomblk_io_submit:
-                       clear_opt(sb, MBLK_IO_SUBMIT);
-                       break;
-               case Opt_stripe:
-                       if (match_int(&args[0], &option))
-                               return 0;
-                       if (option < 0)
-                               return 0;
-                       sbi->s_stripe = option;
-                       break;
-               case Opt_delalloc:
-                       set_opt(sb, DELALLOC);
-                       set_opt2(sb, EXPLICIT_DELALLOC);
-                       break;
-               case Opt_block_validity:
-                       set_opt(sb, BLOCK_VALIDITY);
-                       break;
-               case Opt_noblock_validity:
-                       clear_opt(sb, BLOCK_VALIDITY);
-                       break;
-               case Opt_inode_readahead_blks:
-                       if (match_int(&args[0], &option))
-                               return 0;
-                       if (option < 0 || option > (1 << 30))
-                               return 0;
-                       if (option && !is_power_of_2(option)) {
-                               ext4_msg(sb, KERN_ERR,
-                                        "EXT4-fs: inode_readahead_blks"
-                                        " must be a power of 2");
-                               return 0;
+               } else {
+                       if (!args->from)
+                               arg = 1;
+                       if (m->flags & MOPT_CLEAR)
+                               arg = !arg;
+                       else if (unlikely(!(m->flags & MOPT_SET))) {
+                               ext4_msg(sb, KERN_WARNING,
+                                        "buggy handling of option %s", opt);
+                               WARN_ON(1);
+                               return -1;
                        }
-                       sbi->s_inode_readahead_blks = option;
-                       break;
-               case Opt_journal_ioprio:
-                       if (match_int(&args[0], &option))
-                               return 0;
-                       if (option < 0 || option > 7)
-                               break;
-                       *journal_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE,
-                                                           option);
-                       break;
-               case Opt_noauto_da_alloc:
-                       set_opt(sb, NO_AUTO_DA_ALLOC);
-                       break;
-               case Opt_auto_da_alloc:
-                       if (args[0].from) {
-                               if (match_int(&args[0], &option))
-                                       return 0;
-                       } else
-                               option = 1;     /* No argument, default to 1 */
-                       if (option)
-                               clear_opt(sb, NO_AUTO_DA_ALLOC);
+                       if (arg != 0)
+                               sbi->s_mount_opt |= m->mount_opt;
                        else
-                               set_opt(sb,NO_AUTO_DA_ALLOC);
-                       break;
-               case Opt_discard:
-                       set_opt(sb, DISCARD);
-                       break;
-               case Opt_nodiscard:
-                       clear_opt(sb, DISCARD);
-                       break;
-               case Opt_dioread_nolock:
-                       set_opt(sb, DIOREAD_NOLOCK);
-                       break;
-               case Opt_dioread_lock:
-                       clear_opt(sb, DIOREAD_NOLOCK);
-                       break;
-               case Opt_init_itable:
-                       set_opt(sb, INIT_INODE_TABLE);
-                       if (args[0].from) {
-                               if (match_int(&args[0], &option))
-                                       return 0;
-                       } else
-                               option = EXT4_DEF_LI_WAIT_MULT;
-                       if (option < 0)
-                               return 0;
-                       sbi->s_li_wait_mult = option;
-                       break;
-               case Opt_noinit_itable:
-                       clear_opt(sb, INIT_INODE_TABLE);
-                       break;
-               default:
-                       ext4_msg(sb, KERN_ERR,
-                              "Unrecognized mount option \"%s\" "
-                              "or missing value", p);
-                       return 0;
+                               sbi->s_mount_opt &= ~m->mount_opt;
                }
+               return 1;
+       }
+       ext4_msg(sb, KERN_ERR, "Unrecognized mount option \"%s\" "
+                "or missing value", opt);
+       return -1;
+}
+
+static int parse_options(char *options, struct super_block *sb,
+                        unsigned long *journal_devnum,
+                        unsigned int *journal_ioprio,
+                        int is_remount)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       char *p;
+       substring_t args[MAX_OPT_ARGS];
+       int token;
+
+       if (!options)
+               return 1;
+
+       while ((p = strsep(&options, ",")) != NULL) {
+               if (!*p)
+                       continue;
+               /*
+                * Initialize args struct so we know whether arg was
+                * found; some options take optional arguments.
+                */
+               args[0].to = args[0].from = 0;
+               token = match_token(p, tokens, args);
+               if (handle_mount_opt(sb, p, token, args, journal_devnum,
+                                    journal_ioprio, is_remount) < 0)
+                       return 0;
        }
 #ifdef CONFIG_QUOTA
        if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
@@ -1942,6 +1651,160 @@ set_qf_format:
        return 1;
 }
 
+static inline void ext4_show_quota_options(struct seq_file *seq,
+                                          struct super_block *sb)
+{
+#if defined(CONFIG_QUOTA)
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+       if (sbi->s_jquota_fmt) {
+               char *fmtname = "";
+
+               switch (sbi->s_jquota_fmt) {
+               case QFMT_VFS_OLD:
+                       fmtname = "vfsold";
+                       break;
+               case QFMT_VFS_V0:
+                       fmtname = "vfsv0";
+                       break;
+               case QFMT_VFS_V1:
+                       fmtname = "vfsv1";
+                       break;
+               }
+               seq_printf(seq, ",jqfmt=%s", fmtname);
+       }
+
+       if (sbi->s_qf_names[USRQUOTA])
+               seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]);
+
+       if (sbi->s_qf_names[GRPQUOTA])
+               seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]);
+
+       if (test_opt(sb, USRQUOTA))
+               seq_puts(seq, ",usrquota");
+
+       if (test_opt(sb, GRPQUOTA))
+               seq_puts(seq, ",grpquota");
+#endif
+}
+
+static const char *token2str(int token)
+{
+       static const struct match_token *t;
+
+       for (t = tokens; t->token != Opt_err; t++)
+               if (t->token == token && !strchr(t->pattern, '='))
+                       break;
+       return t->pattern;
+}
+
+/*
+ * Show an option if
+ *  - it's set to a non-default value OR
+ *  - if the per-sb default is different from the global default
+ */
+static int _ext4_show_options(struct seq_file *seq, struct super_block *sb,
+                             int nodefs)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       struct ext4_super_block *es = sbi->s_es;
+       int def_errors, def_mount_opt = nodefs ? 0 : sbi->s_def_mount_opt;
+       const struct mount_opts *m;
+       char sep = nodefs ? '\n' : ',';
+
+#define SEQ_OPTS_PUTS(str) seq_printf(seq, "%c" str, sep)
+#define SEQ_OPTS_PRINT(str, arg) seq_printf(seq, "%c" str, sep, arg)
+
+       if (sbi->s_sb_block != 1)
+               SEQ_OPTS_PRINT("sb=%llu", sbi->s_sb_block);
+
+       for (m = ext4_mount_opts; m->token != Opt_err; m++) {
+               int want_set = m->flags & MOPT_SET;
+               if (((m->flags & (MOPT_SET|MOPT_CLEAR)) == 0) ||
+                   (m->flags & MOPT_CLEAR_ERR))
+                       continue;
+               if (!(m->mount_opt & (sbi->s_mount_opt ^ def_mount_opt)))
+                       continue; /* skip if same as the default */
+               if ((want_set &&
+                    (sbi->s_mount_opt & m->mount_opt) != m->mount_opt) ||
+                   (!want_set && (sbi->s_mount_opt & m->mount_opt)))
+                       continue; /* select Opt_noFoo vs Opt_Foo */
+               SEQ_OPTS_PRINT("%s", token2str(m->token));
+       }
+
+       if (nodefs || sbi->s_resuid != EXT4_DEF_RESUID ||
+           le16_to_cpu(es->s_def_resuid) != EXT4_DEF_RESUID)
+               SEQ_OPTS_PRINT("resuid=%u", sbi->s_resuid);
+       if (nodefs || sbi->s_resgid != EXT4_DEF_RESGID ||
+           le16_to_cpu(es->s_def_resgid) != EXT4_DEF_RESGID)
+               SEQ_OPTS_PRINT("resgid=%u", sbi->s_resgid);
+       def_errors = nodefs ? -1 : le16_to_cpu(es->s_errors);
+       if (test_opt(sb, ERRORS_RO) && def_errors != EXT4_ERRORS_RO)
+               SEQ_OPTS_PUTS("errors=remount-ro");
+       if (test_opt(sb, ERRORS_CONT) && def_errors != EXT4_ERRORS_CONTINUE)
+               SEQ_OPTS_PUTS("errors=continue");
+       if (test_opt(sb, ERRORS_PANIC) && def_errors != EXT4_ERRORS_PANIC)
+               SEQ_OPTS_PUTS("errors=panic");
+       if (nodefs || sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ)
+               SEQ_OPTS_PRINT("commit=%lu", sbi->s_commit_interval / HZ);
+       if (nodefs || sbi->s_min_batch_time != EXT4_DEF_MIN_BATCH_TIME)
+               SEQ_OPTS_PRINT("min_batch_time=%u", sbi->s_min_batch_time);
+       if (nodefs || sbi->s_max_batch_time != EXT4_DEF_MAX_BATCH_TIME)
+               SEQ_OPTS_PRINT("max_batch_time=%u", sbi->s_max_batch_time);
+       if (sb->s_flags & MS_I_VERSION)
+               SEQ_OPTS_PUTS("i_version");
+       if (nodefs || sbi->s_stripe)
+               SEQ_OPTS_PRINT("stripe=%lu", sbi->s_stripe);
+       if (EXT4_MOUNT_DATA_FLAGS & (sbi->s_mount_opt ^ def_mount_opt)) {
+               if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
+                       SEQ_OPTS_PUTS("data=journal");
+               else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
+                       SEQ_OPTS_PUTS("data=ordered");
+               else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
+                       SEQ_OPTS_PUTS("data=writeback");
+       }
+       if (nodefs ||
+           sbi->s_inode_readahead_blks != EXT4_DEF_INODE_READAHEAD_BLKS)
+               SEQ_OPTS_PRINT("inode_readahead_blks=%u",
+                              sbi->s_inode_readahead_blks);
+
+       if (nodefs || (test_opt(sb, INIT_INODE_TABLE) &&
+                      (sbi->s_li_wait_mult != EXT4_DEF_LI_WAIT_MULT)))
+               SEQ_OPTS_PRINT("init_itable=%u", sbi->s_li_wait_mult);
+
+       ext4_show_quota_options(seq, sb);
+       return 0;
+}
+
+static int ext4_show_options(struct seq_file *seq, struct dentry *root)
+{
+       return _ext4_show_options(seq, root->d_sb, 0);
+}
+
+static int options_seq_show(struct seq_file *seq, void *offset)
+{
+       struct super_block *sb = seq->private;
+       int rc;
+
+       seq_puts(seq, (sb->s_flags & MS_RDONLY) ? "ro" : "rw");
+       rc = _ext4_show_options(seq, sb, 1);
+       seq_puts(seq, "\n");
+       return rc;
+}
+
+static int options_open_fs(struct inode *inode, struct file *file)
+{
+       return single_open(file, options_seq_show, PDE(inode)->data);
+}
+
+static const struct file_operations ext4_seq_options_fops = {
+       .owner = THIS_MODULE,
+       .open = options_open_fs,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+};
+
 static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
                            int read_only)
 {
@@ -2945,7 +2808,7 @@ static int ext4_run_lazyinit_thread(void)
                ext4_clear_request_list();
                kfree(ext4_li_info);
                ext4_li_info = NULL;
-               printk(KERN_CRIT "EXT4: error %d creating inode table "
+               printk(KERN_CRIT "EXT4-fs: error %d creating inode table "
                                 "initialization thread\n",
                                 err);
                return err;
@@ -3183,11 +3046,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        set_opt(sb, INIT_INODE_TABLE);
        if (def_mount_opts & EXT4_DEFM_DEBUG)
                set_opt(sb, DEBUG);
-       if (def_mount_opts & EXT4_DEFM_BSDGROUPS) {
-               ext4_msg(sb, KERN_WARNING, deprecated_msg, "bsdgroups",
-                       "2.6.38");
+       if (def_mount_opts & EXT4_DEFM_BSDGROUPS)
                set_opt(sb, GRPID);
-       }
        if (def_mount_opts & EXT4_DEFM_UID16)
                set_opt(sb, NO_UID32);
        /* xattr user namespace & acls are now defaulted on */
@@ -3240,13 +3100,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        sbi->s_li_wait_mult = EXT4_DEF_LI_WAIT_MULT;
 
        if (!parse_options((char *) sbi->s_es->s_mount_opts, sb,
-                          &journal_devnum, &journal_ioprio, NULL, 0)) {
+                          &journal_devnum, &journal_ioprio, 0)) {
                ext4_msg(sb, KERN_WARNING,
                         "failed to parse options in superblock: %s",
                         sbi->s_es->s_mount_opts);
        }
+       sbi->s_def_mount_opt = sbi->s_mount_opt;
        if (!parse_options((char *) data, sb, &journal_devnum,
-                          &journal_ioprio, NULL, 0))
+                          &journal_ioprio, 0))
                goto failed_mount;
 
        if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) {
@@ -3416,7 +3277,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 #else
                es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
 #endif
-               sb->s_dirt = 1;
        }
 
        /* Handle clustersize */
@@ -3540,6 +3400,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        if (ext4_proc_root)
                sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root);
 
+       if (sbi->s_proc)
+               proc_create_data("options", S_IRUGO, sbi->s_proc,
+                                &ext4_seq_options_fops, sb);
+
        bgl_lock_init(sbi->s_blockgroup_lock);
 
        for (i = 0; i < db_count; i++) {
@@ -3694,6 +3558,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        }
        set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
 
+       sbi->s_journal->j_commit_callback = ext4_journal_commit_callback;
+
        /*
         * The journal may have updated the bg summary counts, so we
         * need to update the global counters.
@@ -3861,6 +3727,7 @@ failed_mount2:
        ext4_kvfree(sbi->s_group_desc);
 failed_mount:
        if (sbi->s_proc) {
+               remove_proc_entry("options", sbi->s_proc);
                remove_proc_entry(sb->s_id, ext4_proc_root);
        }
 #ifdef CONFIG_QUOTA
@@ -4090,15 +3957,6 @@ static int ext4_load_journal(struct super_block *sb,
        if (!(journal->j_flags & JBD2_BARRIER))
                ext4_msg(sb, KERN_INFO, "barriers disabled");
 
-       if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) {
-               err = jbd2_journal_update_format(journal);
-               if (err)  {
-                       ext4_msg(sb, KERN_ERR, "error updating journal");
-                       jbd2_journal_destroy(journal);
-                       return err;
-               }
-       }
-
        if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER))
                err = jbd2_journal_wipe(journal, !really_read_only);
        if (!err) {
@@ -4385,7 +4243,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
 {
        struct ext4_super_block *es;
        struct ext4_sb_info *sbi = EXT4_SB(sb);
-       ext4_fsblk_t n_blocks_count = 0;
        unsigned long old_sb_flags;
        struct ext4_mount_options old_opts;
        int enable_quota = 0;
@@ -4418,8 +4275,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
        /*
         * Allow the "check" option to be passed as a remount option.
         */
-       if (!parse_options(data, sb, NULL, &journal_ioprio,
-                          &n_blocks_count, 1)) {
+       if (!parse_options(data, sb, NULL, &journal_ioprio, 1)) {
                err = -EINVAL;
                goto restore_opts;
        }
@@ -4437,8 +4293,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
                set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
        }
 
-       if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
-               n_blocks_count > ext4_blocks_count(es)) {
+       if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
                if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) {
                        err = -EROFS;
                        goto restore_opts;
@@ -4513,8 +4368,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
                        if (sbi->s_journal)
                                ext4_clear_journal_err(sb, es);
                        sbi->s_mount_state = le16_to_cpu(es->s_state);
-                       if ((err = ext4_group_extend(sb, es, n_blocks_count)))
-                               goto restore_opts;
                        if (!ext4_setup_super(sb, es, 0))
                                sb->s_flags &= ~MS_RDONLY;
                        if (EXT4_HAS_INCOMPAT_FEATURE(sb,
index 93a00d89a220d4085c64e9d427c375e9ada76494..e88748e55c0f246e90ca21c2094303719f83df07 100644 (file)
@@ -82,8 +82,8 @@
                printk("\n"); \
        } while (0)
 #else
-# define ea_idebug(f...)
-# define ea_bdebug(f...)
+# define ea_idebug(inode, fmt, ...)    no_printk(fmt, ##__VA_ARGS__)
+# define ea_bdebug(bh, fmt, ...)       no_printk(fmt, ##__VA_ARGS__)
 #endif
 
 static void ext4_xattr_cache_insert(struct buffer_head *);
@@ -158,13 +158,10 @@ ext4_xattr_check_names(struct ext4_xattr_entry *entry, void *end)
 static inline int
 ext4_xattr_check_block(struct buffer_head *bh)
 {
-       int error;
-
        if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) ||
            BHDR(bh)->h_blocks != cpu_to_le32(1))
                return -EIO;
-       error = ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size);
-       return error;
+       return ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size);
 }
 
 static inline int
@@ -220,7 +217,8 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
        error = -ENODATA;
        if (!EXT4_I(inode)->i_file_acl)
                goto cleanup;
-       ea_idebug(inode, "reading block %u", EXT4_I(inode)->i_file_acl);
+       ea_idebug(inode, "reading block %llu",
+                 (unsigned long long)EXT4_I(inode)->i_file_acl);
        bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
        if (!bh)
                goto cleanup;
@@ -363,7 +361,8 @@ ext4_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size)
        error = 0;
        if (!EXT4_I(inode)->i_file_acl)
                goto cleanup;
-       ea_idebug(inode, "reading block %u", EXT4_I(inode)->i_file_acl);
+       ea_idebug(inode, "reading block %llu",
+                 (unsigned long long)EXT4_I(inode)->i_file_acl);
        bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
        error = -EIO;
        if (!bh)
@@ -487,18 +486,19 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
                ext4_free_blocks(handle, inode, bh, 0, 1,
                                 EXT4_FREE_BLOCKS_METADATA |
                                 EXT4_FREE_BLOCKS_FORGET);
+               unlock_buffer(bh);
        } else {
                le32_add_cpu(&BHDR(bh)->h_refcount, -1);
+               if (ce)
+                       mb_cache_entry_release(ce);
+               unlock_buffer(bh);
                error = ext4_handle_dirty_metadata(handle, inode, bh);
                if (IS_SYNC(inode))
                        ext4_handle_sync(handle);
                dquot_free_block(inode, 1);
                ea_bdebug(bh, "refcount now=%d; releasing",
                          le32_to_cpu(BHDR(bh)->h_refcount));
-               if (ce)
-                       mb_cache_entry_release(ce);
        }
-       unlock_buffer(bh);
 out:
        ext4_std_error(inode->i_sb, error);
        return;
@@ -834,7 +834,8 @@ inserted:
                        if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
                                BUG_ON(block > EXT4_MAX_BLOCK_FILE_PHYS);
 
-                       ea_idebug(inode, "creating block %d", block);
+                       ea_idebug(inode, "creating block %llu",
+                                 (unsigned long long)block);
 
                        new_bh = sb_getblk(sb, block);
                        if (!new_bh) {
index 236972b752f5141004608d8c0ff108467f820c14..539f36cf3e4a3b574f6bb977bcbdf387571675b3 100644 (file)
@@ -256,7 +256,8 @@ static bool inode_dirtied_after(struct inode *inode, unsigned long t)
 }
 
 /*
- * Move expired dirty inodes from @delaying_queue to @dispatch_queue.
+ * Move expired (dirtied after work->older_than_this) dirty inodes from
+ * @delaying_queue to @dispatch_queue.
  */
 static int move_expired_inodes(struct list_head *delaying_queue,
                               struct list_head *dispatch_queue,
@@ -1148,23 +1149,6 @@ out_unlock_inode:
 }
 EXPORT_SYMBOL(__mark_inode_dirty);
 
-/*
- * Write out a superblock's list of dirty inodes.  A wait will be performed
- * upon no inodes, all inodes or the final one, depending upon sync_mode.
- *
- * If older_than_this is non-NULL, then only write out inodes which
- * had their first dirtying at a time earlier than *older_than_this.
- *
- * If `bdi' is non-zero then we're being asked to writeback a specific queue.
- * This function assumes that the blockdev superblock's inodes are backed by
- * a variety of queues, so all inodes are searched.  For other superblocks,
- * assume that all inodes are backed by the same queue.
- *
- * The inodes to be written are parked on bdi->b_io.  They are moved back onto
- * bdi->b_dirty as they are selected for writing.  This way, none can be missed
- * on the writer throttling path, and we get decent balancing between many
- * throttled threads: we don't want them all piling up on inode_sync_wait.
- */
 static void wait_sb_inodes(struct super_block *sb)
 {
        struct inode *inode, *old_inode = NULL;
@@ -1364,8 +1348,6 @@ int write_inode_now(struct inode *inode, int sync)
        ret = writeback_single_inode(inode, wb, &wbc);
        spin_unlock(&inode->i_lock);
        spin_unlock(&wb->list_lock);
-       if (sync)
-               inode_sync_wait(inode);
        return ret;
 }
 EXPORT_SYMBOL(write_inode_now);
index 3cbfa93cd78243506e07f0f7480d73f2704b29bb..1fe731337f0790add39e1d4870f4d9bb8174fb8b 100644 (file)
@@ -67,7 +67,8 @@ extern int access_file(char *path, int r, int w, int x);
 extern int open_file(char *path, int r, int w, int append);
 extern void *open_dir(char *path, int *err_out);
 extern char *read_dir(void *stream, unsigned long long *pos,
-                     unsigned long long *ino_out, int *len_out);
+                     unsigned long long *ino_out, int *len_out,
+                     unsigned int *type_out);
 extern void close_file(void *stream);
 extern int replace_file(int oldfd, int fd);
 extern void close_dir(void *stream);
index 588d45885a6fb2b80d7bc6babf5290437636d6a8..07c516bfea7671853513d9a80f61f81d5f674f91 100644 (file)
@@ -283,6 +283,7 @@ int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
        char *name;
        unsigned long long next, ino;
        int error, len;
+       unsigned int type;
 
        name = dentry_name(file->f_path.dentry);
        if (name == NULL)
@@ -292,9 +293,9 @@ int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
        if (dir == NULL)
                return -error;
        next = file->f_pos;
-       while ((name = read_dir(dir, &next, &ino, &len)) != NULL) {
+       while ((name = read_dir(dir, &next, &ino, &len, &type)) != NULL) {
                error = (*filldir)(ent, name, len, file->f_pos,
-                                  ino, DT_UNKNOWN);
+                                  ino, type);
                if (error) break;
                file->f_pos = next;
        }
index dd7bc38a38251e9c123b08e87d42477f44f302b5..a74ad0d371c2298b84b3dc735990d71ed68aede3 100644 (file)
@@ -98,7 +98,8 @@ void *open_dir(char *path, int *err_out)
 }
 
 char *read_dir(void *stream, unsigned long long *pos,
-              unsigned long long *ino_out, int *len_out)
+              unsigned long long *ino_out, int *len_out,
+              unsigned int *type_out)
 {
        DIR *dir = stream;
        struct dirent *ent;
@@ -109,6 +110,7 @@ char *read_dir(void *stream, unsigned long long *pos,
                return NULL;
        *len_out = strlen(ent->d_name);
        *ino_out = ent->d_ino;
+       *type_out = ent->d_type;
        *pos = telldir(dir);
        return ent->d_name;
 }
index d49d202903fb13cb9e8b663c1c6aea181f38d37a..c78841ee81cf31a0c4c67a23bca294a32720cb5f 100644 (file)
@@ -88,14 +88,13 @@ static inline void __buffer_relink_io(struct journal_head *jh)
  * whole transaction.
  *
  * Requires j_list_lock
- * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it
  */
 static int __try_to_free_cp_buf(struct journal_head *jh)
 {
        int ret = 0;
        struct buffer_head *bh = jh2bh(jh);
 
-       if (jh->b_jlist == BJ_None && !buffer_locked(bh) &&
+       if (jh->b_transaction == NULL && !buffer_locked(bh) &&
            !buffer_dirty(bh) && !buffer_write_io_error(bh)) {
                /*
                 * Get our reference so that bh cannot be freed before
@@ -104,11 +103,8 @@ static int __try_to_free_cp_buf(struct journal_head *jh)
                get_bh(bh);
                JBUFFER_TRACE(jh, "remove from checkpoint list");
                ret = __jbd2_journal_remove_checkpoint(jh) + 1;
-               jbd_unlock_bh_state(bh);
                BUFFER_TRACE(bh, "release");
                __brelse(bh);
-       } else {
-               jbd_unlock_bh_state(bh);
        }
        return ret;
 }
@@ -179,21 +175,6 @@ void __jbd2_log_wait_for_space(journal_t *journal)
        }
 }
 
-/*
- * We were unable to perform jbd_trylock_bh_state() inside j_list_lock.
- * The caller must restart a list walk.  Wait for someone else to run
- * jbd_unlock_bh_state().
- */
-static void jbd_sync_bh(journal_t *journal, struct buffer_head *bh)
-       __releases(journal->j_list_lock)
-{
-       get_bh(bh);
-       spin_unlock(&journal->j_list_lock);
-       jbd_lock_bh_state(bh);
-       jbd_unlock_bh_state(bh);
-       put_bh(bh);
-}
-
 /*
  * Clean up transaction's list of buffers submitted for io.
  * We wait for any pending IO to complete and remove any clean
@@ -222,15 +203,9 @@ restart:
        while (!released && transaction->t_checkpoint_io_list) {
                jh = transaction->t_checkpoint_io_list;
                bh = jh2bh(jh);
-               if (!jbd_trylock_bh_state(bh)) {
-                       jbd_sync_bh(journal, bh);
-                       spin_lock(&journal->j_list_lock);
-                       goto restart;
-               }
                get_bh(bh);
                if (buffer_locked(bh)) {
                        spin_unlock(&journal->j_list_lock);
-                       jbd_unlock_bh_state(bh);
                        wait_on_buffer(bh);
                        /* the journal_head may have gone by now */
                        BUFFER_TRACE(bh, "brelse");
@@ -246,7 +221,6 @@ restart:
                 * it has been written out and so we can drop it from the list
                 */
                released = __jbd2_journal_remove_checkpoint(jh);
-               jbd_unlock_bh_state(bh);
                __brelse(bh);
        }
 
@@ -266,7 +240,6 @@ __flush_batch(journal_t *journal, int *batch_count)
 
        for (i = 0; i < *batch_count; i++) {
                struct buffer_head *bh = journal->j_chkpt_bhs[i];
-               clear_buffer_jwrite(bh);
                BUFFER_TRACE(bh, "brelse");
                __brelse(bh);
        }
@@ -281,7 +254,6 @@ __flush_batch(journal_t *journal, int *batch_count)
  * be written out.
  *
  * Called with j_list_lock held and drops it if 1 is returned
- * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it
  */
 static int __process_buffer(journal_t *journal, struct journal_head *jh,
                            int *batch_count, transaction_t *transaction)
@@ -292,7 +264,6 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh,
        if (buffer_locked(bh)) {
                get_bh(bh);
                spin_unlock(&journal->j_list_lock);
-               jbd_unlock_bh_state(bh);
                wait_on_buffer(bh);
                /* the journal_head may have gone by now */
                BUFFER_TRACE(bh, "brelse");
@@ -304,7 +275,6 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh,
 
                transaction->t_chp_stats.cs_forced_to_close++;
                spin_unlock(&journal->j_list_lock);
-               jbd_unlock_bh_state(bh);
                if (unlikely(journal->j_flags & JBD2_UNMOUNT))
                        /*
                         * The journal thread is dead; so starting and
@@ -323,11 +293,9 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh,
                if (unlikely(buffer_write_io_error(bh)))
                        ret = -EIO;
                get_bh(bh);
-               J_ASSERT_JH(jh, !buffer_jbddirty(bh));
                BUFFER_TRACE(bh, "remove from checkpoint");
                __jbd2_journal_remove_checkpoint(jh);
                spin_unlock(&journal->j_list_lock);
-               jbd_unlock_bh_state(bh);
                __brelse(bh);
        } else {
                /*
@@ -340,10 +308,8 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh,
                BUFFER_TRACE(bh, "queue");
                get_bh(bh);
                J_ASSERT_BH(bh, !buffer_jwrite(bh));
-               set_buffer_jwrite(bh);
                journal->j_chkpt_bhs[*batch_count] = bh;
                __buffer_relink_io(jh);
-               jbd_unlock_bh_state(bh);
                transaction->t_chp_stats.cs_written++;
                (*batch_count)++;
                if (*batch_count == JBD2_NR_BATCH) {
@@ -407,15 +373,7 @@ restart:
                int retry = 0, err;
 
                while (!retry && transaction->t_checkpoint_list) {
-                       struct buffer_head *bh;
-
                        jh = transaction->t_checkpoint_list;
-                       bh = jh2bh(jh);
-                       if (!jbd_trylock_bh_state(bh)) {
-                               jbd_sync_bh(journal, bh);
-                               retry = 1;
-                               break;
-                       }
                        retry = __process_buffer(journal, jh, &batch_count,
                                                 transaction);
                        if (retry < 0 && !result)
@@ -478,79 +436,28 @@ out:
 
 int jbd2_cleanup_journal_tail(journal_t *journal)
 {
-       transaction_t * transaction;
        tid_t           first_tid;
-       unsigned long   blocknr, freed;
+       unsigned long   blocknr;
 
        if (is_journal_aborted(journal))
                return 1;
 
-       /* OK, work out the oldest transaction remaining in the log, and
-        * the log block it starts at.
-        *
-        * If the log is now empty, we need to work out which is the
-        * next transaction ID we will write, and where it will
-        * start. */
-
-       write_lock(&journal->j_state_lock);
-       spin_lock(&journal->j_list_lock);
-       transaction = journal->j_checkpoint_transactions;
-       if (transaction) {
-               first_tid = transaction->t_tid;
-               blocknr = transaction->t_log_start;
-       } else if ((transaction = journal->j_committing_transaction) != NULL) {
-               first_tid = transaction->t_tid;
-               blocknr = transaction->t_log_start;
-       } else if ((transaction = journal->j_running_transaction) != NULL) {
-               first_tid = transaction->t_tid;
-               blocknr = journal->j_head;
-       } else {
-               first_tid = journal->j_transaction_sequence;
-               blocknr = journal->j_head;
-       }
-       spin_unlock(&journal->j_list_lock);
-       J_ASSERT(blocknr != 0);
-
-       /* If the oldest pinned transaction is at the tail of the log
-           already then there's not much we can do right now. */
-       if (journal->j_tail_sequence == first_tid) {
-               write_unlock(&journal->j_state_lock);
+       if (!jbd2_journal_get_log_tail(journal, &first_tid, &blocknr))
                return 1;
-       }
-
-       /* OK, update the superblock to recover the freed space.
-        * Physical blocks come first: have we wrapped beyond the end of
-        * the log?  */
-       freed = blocknr - journal->j_tail;
-       if (blocknr < journal->j_tail)
-               freed = freed + journal->j_last - journal->j_first;
-
-       trace_jbd2_cleanup_journal_tail(journal, first_tid, blocknr, freed);
-       jbd_debug(1,
-                 "Cleaning journal tail from %d to %d (offset %lu), "
-                 "freeing %lu\n",
-                 journal->j_tail_sequence, first_tid, blocknr, freed);
-
-       journal->j_free += freed;
-       journal->j_tail_sequence = first_tid;
-       journal->j_tail = blocknr;
-       write_unlock(&journal->j_state_lock);
+       J_ASSERT(blocknr != 0);
 
        /*
-        * If there is an external journal, we need to make sure that
-        * any data blocks that were recently written out --- perhaps
-        * by jbd2_log_do_checkpoint() --- are flushed out before we
-        * drop the transactions from the external journal.  It's
-        * unlikely this will be necessary, especially with a
-        * appropriately sized journal, but we need this to guarantee
-        * correctness.  Fortunately jbd2_cleanup_journal_tail()
-        * doesn't get called all that often.
+        * We need to make sure that any blocks that were recently written out
+        * --- perhaps by jbd2_log_do_checkpoint() --- are flushed out before
+        * we drop the transactions from the journal. It's unlikely this will
+        * be necessary, especially with an appropriately sized journal, but we
+        * need this to guarantee correctness.  Fortunately
+        * jbd2_cleanup_journal_tail() doesn't get called all that often.
         */
-       if ((journal->j_fs_dev != journal->j_dev) &&
-           (journal->j_flags & JBD2_BARRIER))
+       if (journal->j_flags & JBD2_BARRIER)
                blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL);
-       if (!(journal->j_flags & JBD2_ABORT))
-               jbd2_journal_update_superblock(journal, 1);
+
+       __jbd2_update_log_tail(journal, first_tid, blocknr);
        return 0;
 }
 
@@ -582,15 +489,12 @@ static int journal_clean_one_cp_list(struct journal_head *jh, int *released)
        do {
                jh = next_jh;
                next_jh = jh->b_cpnext;
-               /* Use trylock because of the ranking */
-               if (jbd_trylock_bh_state(jh2bh(jh))) {
-                       ret = __try_to_free_cp_buf(jh);
-                       if (ret) {
-                               freed++;
-                               if (ret == 2) {
-                                       *released = 1;
-                                       return freed;
-                               }
+               ret = __try_to_free_cp_buf(jh);
+               if (ret) {
+                       freed++;
+                       if (ret == 2) {
+                               *released = 1;
+                               return freed;
                        }
                }
                /*
@@ -673,9 +577,7 @@ out:
  * The function can free jh and bh.
  *
  * This function is called with j_list_lock held.
- * This function is called with jbd_lock_bh_state(jh2bh(jh))
  */
-
 int __jbd2_journal_remove_checkpoint(struct journal_head *jh)
 {
        struct transaction_chp_stats_s *stats;
@@ -722,7 +624,7 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh)
                                    transaction->t_tid, stats);
 
        __jbd2_journal_drop_transaction(journal, transaction);
-       kfree(transaction);
+       jbd2_journal_free_transaction(transaction);
 
        /* Just in case anybody was waiting for more transactions to be
            checkpointed... */
@@ -797,5 +699,7 @@ void __jbd2_journal_drop_transaction(journal_t *journal, transaction_t *transact
        J_ASSERT(journal->j_committing_transaction != transaction);
        J_ASSERT(journal->j_running_transaction != transaction);
 
+       trace_jbd2_drop_transaction(journal, transaction);
+
        jbd_debug(1, "Dropping transaction %d, all done\n", transaction->t_tid);
 }
index c067a8cae63bf322067763ff02687ae24c216008..17f557f01cf0dd570dcd112e5d686fa072cd7498 100644 (file)
@@ -331,6 +331,10 @@ void jbd2_journal_commit_transaction(journal_t *journal)
        struct buffer_head *cbh = NULL; /* For transactional checksums */
        __u32 crc32_sum = ~0;
        struct blk_plug plug;
+       /* Tail of the journal */
+       unsigned long first_block;
+       tid_t first_tid;
+       int update_tail;
 
        /*
         * First job: lock down the current transaction and wait for
@@ -340,7 +344,18 @@ void jbd2_journal_commit_transaction(journal_t *journal)
        /* Do we need to erase the effects of a prior jbd2_journal_flush? */
        if (journal->j_flags & JBD2_FLUSHED) {
                jbd_debug(3, "super block updated\n");
-               jbd2_journal_update_superblock(journal, 1);
+               mutex_lock(&journal->j_checkpoint_mutex);
+               /*
+                * We hold j_checkpoint_mutex so tail cannot change under us.
+                * We don't need any special data guarantees for writing sb
+                * since journal is empty and it is ok for write to be
+                * flushed only with transaction commit.
+                */
+               jbd2_journal_update_sb_log_tail(journal,
+                                               journal->j_tail_sequence,
+                                               journal->j_tail,
+                                               WRITE_SYNC);
+               mutex_unlock(&journal->j_checkpoint_mutex);
        } else {
                jbd_debug(3, "superblock not updated\n");
        }
@@ -677,10 +692,30 @@ start_journal_io:
                err = 0;
        }
 
+       /*
+        * Get current oldest transaction in the log before we issue flush
+        * to the filesystem device. After the flush we can be sure that
+        * blocks of all older transactions are checkpointed to persistent
+        * storage and we will be safe to update journal start in the
+        * superblock with the numbers we get here.
+        */
+       update_tail =
+               jbd2_journal_get_log_tail(journal, &first_tid, &first_block);
+
        write_lock(&journal->j_state_lock);
+       if (update_tail) {
+               long freed = first_block - journal->j_tail;
+
+               if (first_block < journal->j_tail)
+                       freed += journal->j_last - journal->j_first;
+               /* Update tail only if we free significant amount of space */
+               if (freed < journal->j_maxlen / 4)
+                       update_tail = 0;
+       }
        J_ASSERT(commit_transaction->t_state == T_COMMIT);
        commit_transaction->t_state = T_COMMIT_DFLUSH;
        write_unlock(&journal->j_state_lock);
+
        /* 
         * If the journal is not located on the file system device,
         * then we must flush the file system device before we issue
@@ -831,6 +866,14 @@ wait_for_iobuf:
        if (err)
                jbd2_journal_abort(journal, err);
 
+       /*
+        * Now disk caches for filesystem device are flushed so we are safe to
+        * erase checkpointed transactions from the log by updating journal
+        * superblock.
+        */
+       if (update_tail)
+               jbd2_update_log_tail(journal, first_tid, first_block);
+
        /* End of a transaction!  Finally, we can do checkpoint
            processing: any buffers committed as a result of this
            transaction can be removed from any checkpoint list it was on
@@ -1048,7 +1091,7 @@ restart_loop:
        jbd_debug(1, "JBD2: commit %d complete, head %d\n",
                  journal->j_commit_sequence, journal->j_tail_sequence);
        if (to_free)
-               kfree(commit_transaction);
+               jbd2_journal_free_transaction(commit_transaction);
 
        wake_up(&journal->j_wait_done_commit);
 }
index 839377e3d6244ac540e0a573bf9c4adc679225a8..98ed6dbfe381370710f89109dd0b5a2209a44494 100644 (file)
@@ -71,7 +71,6 @@ EXPORT_SYMBOL(jbd2_journal_revoke);
 
 EXPORT_SYMBOL(jbd2_journal_init_dev);
 EXPORT_SYMBOL(jbd2_journal_init_inode);
-EXPORT_SYMBOL(jbd2_journal_update_format);
 EXPORT_SYMBOL(jbd2_journal_check_used_features);
 EXPORT_SYMBOL(jbd2_journal_check_available_features);
 EXPORT_SYMBOL(jbd2_journal_set_features);
@@ -96,7 +95,6 @@ EXPORT_SYMBOL(jbd2_journal_release_jbd_inode);
 EXPORT_SYMBOL(jbd2_journal_begin_ordered_truncate);
 EXPORT_SYMBOL(jbd2_inode_cache);
 
-static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
 static void __journal_abort_soft (journal_t *journal, int errno);
 static int jbd2_journal_create_slab(size_t slab_size);
 
@@ -746,6 +744,98 @@ struct journal_head *jbd2_journal_get_descriptor_buffer(journal_t *journal)
        return jbd2_journal_add_journal_head(bh);
 }
 
+/*
+ * Return tid of the oldest transaction in the journal and block in the journal
+ * where the transaction starts.
+ *
+ * If the journal is now empty, return which will be the next transaction ID
+ * we will write and where will that transaction start.
+ *
+ * The return value is 0 if journal tail cannot be pushed any further, 1 if
+ * it can.
+ */
+int jbd2_journal_get_log_tail(journal_t *journal, tid_t *tid,
+                             unsigned long *block)
+{
+       transaction_t *transaction;
+       int ret;
+
+       read_lock(&journal->j_state_lock);
+       spin_lock(&journal->j_list_lock);
+       transaction = journal->j_checkpoint_transactions;
+       if (transaction) {
+               *tid = transaction->t_tid;
+               *block = transaction->t_log_start;
+       } else if ((transaction = journal->j_committing_transaction) != NULL) {
+               *tid = transaction->t_tid;
+               *block = transaction->t_log_start;
+       } else if ((transaction = journal->j_running_transaction) != NULL) {
+               *tid = transaction->t_tid;
+               *block = journal->j_head;
+       } else {
+               *tid = journal->j_transaction_sequence;
+               *block = journal->j_head;
+       }
+       ret = tid_gt(*tid, journal->j_tail_sequence);
+       spin_unlock(&journal->j_list_lock);
+       read_unlock(&journal->j_state_lock);
+
+       return ret;
+}
+
+/*
+ * Update information in journal structure and in on disk journal superblock
+ * about log tail. This function does not check whether information passed in
+ * really pushes log tail further. It's responsibility of the caller to make
+ * sure provided log tail information is valid (e.g. by holding
+ * j_checkpoint_mutex all the time between computing log tail and calling this
+ * function as is the case with jbd2_cleanup_journal_tail()).
+ *
+ * Requires j_checkpoint_mutex
+ */
+void __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block)
+{
+       unsigned long freed;
+
+       BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex));
+
+       /*
+        * We cannot afford for write to remain in drive's caches since as
+        * soon as we update j_tail, next transaction can start reusing journal
+        * space and if we lose sb update during power failure we'd replay
+        * old transaction with possibly newly overwritten data.
+        */
+       jbd2_journal_update_sb_log_tail(journal, tid, block, WRITE_FUA);
+       write_lock(&journal->j_state_lock);
+       freed = block - journal->j_tail;
+       if (block < journal->j_tail)
+               freed += journal->j_last - journal->j_first;
+
+       trace_jbd2_update_log_tail(journal, tid, block, freed);
+       jbd_debug(1,
+                 "Cleaning journal tail from %d to %d (offset %lu), "
+                 "freeing %lu\n",
+                 journal->j_tail_sequence, tid, block, freed);
+
+       journal->j_free += freed;
+       journal->j_tail_sequence = tid;
+       journal->j_tail = block;
+       write_unlock(&journal->j_state_lock);
+}
+
+/*
+ * This is a variaon of __jbd2_update_log_tail which checks for validity of
+ * provided log tail and locks j_checkpoint_mutex. So it is safe against races
+ * with other threads updating log tail.
+ */
+void jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block)
+{
+       mutex_lock(&journal->j_checkpoint_mutex);
+       if (tid_gt(tid, journal->j_tail_sequence))
+               __jbd2_update_log_tail(journal, tid, block);
+       mutex_unlock(&journal->j_checkpoint_mutex);
+}
+
 struct jbd2_stats_proc_session {
        journal_t *journal;
        struct transaction_stats_s *stats;
@@ -1114,40 +1204,45 @@ static int journal_reset(journal_t *journal)
 
        journal->j_max_transaction_buffers = journal->j_maxlen / 4;
 
-       /* Add the dynamic fields and write it to disk. */
-       jbd2_journal_update_superblock(journal, 1);
-       return jbd2_journal_start_thread(journal);
-}
-
-/**
- * void jbd2_journal_update_superblock() - Update journal sb on disk.
- * @journal: The journal to update.
- * @wait: Set to '0' if you don't want to wait for IO completion.
- *
- * Update a journal's dynamic superblock fields and write it to disk,
- * optionally waiting for the IO to complete.
- */
-void jbd2_journal_update_superblock(journal_t *journal, int wait)
-{
-       journal_superblock_t *sb = journal->j_superblock;
-       struct buffer_head *bh = journal->j_sb_buffer;
-
        /*
         * As a special case, if the on-disk copy is already marked as needing
-        * no recovery (s_start == 0) and there are no outstanding transactions
-        * in the filesystem, then we can safely defer the superblock update
-        * until the next commit by setting JBD2_FLUSHED.  This avoids
+        * no recovery (s_start == 0), then we can safely defer the superblock
+        * update until the next commit by setting JBD2_FLUSHED.  This avoids
         * attempting a write to a potential-readonly device.
         */
-       if (sb->s_start == 0 && journal->j_tail_sequence ==
-                               journal->j_transaction_sequence) {
+       if (sb->s_start == 0) {
                jbd_debug(1, "JBD2: Skipping superblock update on recovered sb "
                        "(start %ld, seq %d, errno %d)\n",
                        journal->j_tail, journal->j_tail_sequence,
                        journal->j_errno);
-               goto out;
+               journal->j_flags |= JBD2_FLUSHED;
+       } else {
+               /* Lock here to make assertions happy... */
+               mutex_lock(&journal->j_checkpoint_mutex);
+               /*
+                * Update log tail information. We use WRITE_FUA since new
+                * transaction will start reusing journal space and so we
+                * must make sure information about current log tail is on
+                * disk before that.
+                */
+               jbd2_journal_update_sb_log_tail(journal,
+                                               journal->j_tail_sequence,
+                                               journal->j_tail,
+                                               WRITE_FUA);
+               mutex_unlock(&journal->j_checkpoint_mutex);
        }
+       return jbd2_journal_start_thread(journal);
+}
 
+static void jbd2_write_superblock(journal_t *journal, int write_op)
+{
+       struct buffer_head *bh = journal->j_sb_buffer;
+       int ret;
+
+       trace_jbd2_write_superblock(journal, write_op);
+       if (!(journal->j_flags & JBD2_BARRIER))
+               write_op &= ~(REQ_FUA | REQ_FLUSH);
+       lock_buffer(bh);
        if (buffer_write_io_error(bh)) {
                /*
                 * Oh, dear.  A previous attempt to write the journal
@@ -1163,48 +1258,106 @@ void jbd2_journal_update_superblock(journal_t *journal, int wait)
                clear_buffer_write_io_error(bh);
                set_buffer_uptodate(bh);
        }
+       get_bh(bh);
+       bh->b_end_io = end_buffer_write_sync;
+       ret = submit_bh(write_op, bh);
+       wait_on_buffer(bh);
+       if (buffer_write_io_error(bh)) {
+               clear_buffer_write_io_error(bh);
+               set_buffer_uptodate(bh);
+               ret = -EIO;
+       }
+       if (ret) {
+               printk(KERN_ERR "JBD2: Error %d detected when updating "
+                      "journal superblock for %s.\n", ret,
+                      journal->j_devname);
+       }
+}
+
+/**
+ * jbd2_journal_update_sb_log_tail() - Update log tail in journal sb on disk.
+ * @journal: The journal to update.
+ * @tail_tid: TID of the new transaction at the tail of the log
+ * @tail_block: The first block of the transaction at the tail of the log
+ * @write_op: With which operation should we write the journal sb
+ *
+ * Update a journal's superblock information about log tail and write it to
+ * disk, waiting for the IO to complete.
+ */
+void jbd2_journal_update_sb_log_tail(journal_t *journal, tid_t tail_tid,
+                                    unsigned long tail_block, int write_op)
+{
+       journal_superblock_t *sb = journal->j_superblock;
+
+       BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex));
+       jbd_debug(1, "JBD2: updating superblock (start %lu, seq %u)\n",
+                 tail_block, tail_tid);
+
+       sb->s_sequence = cpu_to_be32(tail_tid);
+       sb->s_start    = cpu_to_be32(tail_block);
+
+       jbd2_write_superblock(journal, write_op);
+
+       /* Log is no longer empty */
+       write_lock(&journal->j_state_lock);
+       WARN_ON(!sb->s_sequence);
+       journal->j_flags &= ~JBD2_FLUSHED;
+       write_unlock(&journal->j_state_lock);
+}
+
+/**
+ * jbd2_mark_journal_empty() - Mark on disk journal as empty.
+ * @journal: The journal to update.
+ *
+ * Update a journal's dynamic superblock fields to show that journal is empty.
+ * Write updated superblock to disk waiting for IO to complete.
+ */
+static void jbd2_mark_journal_empty(journal_t *journal)
+{
+       journal_superblock_t *sb = journal->j_superblock;
 
+       BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex));
        read_lock(&journal->j_state_lock);
-       jbd_debug(1, "JBD2: updating superblock (start %ld, seq %d, errno %d)\n",
-                 journal->j_tail, journal->j_tail_sequence, journal->j_errno);
+       jbd_debug(1, "JBD2: Marking journal as empty (seq %d)\n",
+                 journal->j_tail_sequence);
 
        sb->s_sequence = cpu_to_be32(journal->j_tail_sequence);
-       sb->s_start    = cpu_to_be32(journal->j_tail);
-       sb->s_errno    = cpu_to_be32(journal->j_errno);
+       sb->s_start    = cpu_to_be32(0);
        read_unlock(&journal->j_state_lock);
 
-       BUFFER_TRACE(bh, "marking dirty");
-       mark_buffer_dirty(bh);
-       if (wait) {
-               sync_dirty_buffer(bh);
-               if (buffer_write_io_error(bh)) {
-                       printk(KERN_ERR "JBD2: I/O error detected "
-                              "when updating journal superblock for %s.\n",
-                              journal->j_devname);
-                       clear_buffer_write_io_error(bh);
-                       set_buffer_uptodate(bh);
-               }
-       } else
-               write_dirty_buffer(bh, WRITE);
-
-out:
-       /* If we have just flushed the log (by marking s_start==0), then
-        * any future commit will have to be careful to update the
-        * superblock again to re-record the true start of the log. */
+       jbd2_write_superblock(journal, WRITE_FUA);
 
+       /* Log is no longer empty */
        write_lock(&journal->j_state_lock);
-       if (sb->s_start)
-               journal->j_flags &= ~JBD2_FLUSHED;
-       else
-               journal->j_flags |= JBD2_FLUSHED;
+       journal->j_flags |= JBD2_FLUSHED;
        write_unlock(&journal->j_state_lock);
 }
 
+
+/**
+ * jbd2_journal_update_sb_errno() - Update error in the journal.
+ * @journal: The journal to update.
+ *
+ * Update a journal's errno.  Write updated superblock to disk waiting for IO
+ * to complete.
+ */
+static void jbd2_journal_update_sb_errno(journal_t *journal)
+{
+       journal_superblock_t *sb = journal->j_superblock;
+
+       read_lock(&journal->j_state_lock);
+       jbd_debug(1, "JBD2: updating superblock error (errno %d)\n",
+                 journal->j_errno);
+       sb->s_errno    = cpu_to_be32(journal->j_errno);
+       read_unlock(&journal->j_state_lock);
+
+       jbd2_write_superblock(journal, WRITE_SYNC);
+}
+
 /*
  * Read the superblock for a given journal, performing initial
  * validation of the format.
  */
-
 static int journal_get_superblock(journal_t *journal)
 {
        struct buffer_head *bh;
@@ -1398,14 +1551,11 @@ int jbd2_journal_destroy(journal_t *journal)
 
        if (journal->j_sb_buffer) {
                if (!is_journal_aborted(journal)) {
-                       /* We can now mark the journal as empty. */
-                       journal->j_tail = 0;
-                       journal->j_tail_sequence =
-                               ++journal->j_transaction_sequence;
-                       jbd2_journal_update_superblock(journal, 1);
-               } else {
+                       mutex_lock(&journal->j_checkpoint_mutex);
+                       jbd2_mark_journal_empty(journal);
+                       mutex_unlock(&journal->j_checkpoint_mutex);
+               } else
                        err = -EIO;
-               }
                brelse(journal->j_sb_buffer);
        }
 
@@ -1551,61 +1701,6 @@ void jbd2_journal_clear_features(journal_t *journal, unsigned long compat,
 }
 EXPORT_SYMBOL(jbd2_journal_clear_features);
 
-/**
- * int jbd2_journal_update_format () - Update on-disk journal structure.
- * @journal: Journal to act on.
- *
- * Given an initialised but unloaded journal struct, poke about in the
- * on-disk structure to update it to the most recent supported version.
- */
-int jbd2_journal_update_format (journal_t *journal)
-{
-       journal_superblock_t *sb;
-       int err;
-
-       err = journal_get_superblock(journal);
-       if (err)
-               return err;
-
-       sb = journal->j_superblock;
-
-       switch (be32_to_cpu(sb->s_header.h_blocktype)) {
-       case JBD2_SUPERBLOCK_V2:
-               return 0;
-       case JBD2_SUPERBLOCK_V1:
-               return journal_convert_superblock_v1(journal, sb);
-       default:
-               break;
-       }
-       return -EINVAL;
-}
-
-static int journal_convert_superblock_v1(journal_t *journal,
-                                        journal_superblock_t *sb)
-{
-       int offset, blocksize;
-       struct buffer_head *bh;
-
-       printk(KERN_WARNING
-               "JBD2: Converting superblock from version 1 to 2.\n");
-
-       /* Pre-initialise new fields to zero */
-       offset = ((char *) &(sb->s_feature_compat)) - ((char *) sb);
-       blocksize = be32_to_cpu(sb->s_blocksize);
-       memset(&sb->s_feature_compat, 0, blocksize-offset);
-
-       sb->s_nr_users = cpu_to_be32(1);
-       sb->s_header.h_blocktype = cpu_to_be32(JBD2_SUPERBLOCK_V2);
-       journal->j_format_version = 2;
-
-       bh = journal->j_sb_buffer;
-       BUFFER_TRACE(bh, "marking dirty");
-       mark_buffer_dirty(bh);
-       sync_dirty_buffer(bh);
-       return 0;
-}
-
-
 /**
  * int jbd2_journal_flush () - Flush journal
  * @journal: Journal to act on.
@@ -1619,7 +1714,6 @@ int jbd2_journal_flush(journal_t *journal)
 {
        int err = 0;
        transaction_t *transaction = NULL;
-       unsigned long old_tail;
 
        write_lock(&journal->j_state_lock);
 
@@ -1654,6 +1748,7 @@ int jbd2_journal_flush(journal_t *journal)
        if (is_journal_aborted(journal))
                return -EIO;
 
+       mutex_lock(&journal->j_checkpoint_mutex);
        jbd2_cleanup_journal_tail(journal);
 
        /* Finally, mark the journal as really needing no recovery.
@@ -1661,14 +1756,9 @@ int jbd2_journal_flush(journal_t *journal)
         * the magic code for a fully-recovered superblock.  Any future
         * commits of data to the journal will restore the current
         * s_start value. */
+       jbd2_mark_journal_empty(journal);
+       mutex_unlock(&journal->j_checkpoint_mutex);
        write_lock(&journal->j_state_lock);
-       old_tail = journal->j_tail;
-       journal->j_tail = 0;
-       write_unlock(&journal->j_state_lock);
-       jbd2_journal_update_superblock(journal, 1);
-       write_lock(&journal->j_state_lock);
-       journal->j_tail = old_tail;
-
        J_ASSERT(!journal->j_running_transaction);
        J_ASSERT(!journal->j_committing_transaction);
        J_ASSERT(!journal->j_checkpoint_transactions);
@@ -1708,8 +1798,12 @@ int jbd2_journal_wipe(journal_t *journal, int write)
                write ? "Clearing" : "Ignoring");
 
        err = jbd2_journal_skip_recovery(journal);
-       if (write)
-               jbd2_journal_update_superblock(journal, 1);
+       if (write) {
+               /* Lock to make assertions happy... */
+               mutex_lock(&journal->j_checkpoint_mutex);
+               jbd2_mark_journal_empty(journal);
+               mutex_unlock(&journal->j_checkpoint_mutex);
+       }
 
  no_recovery:
        return err;
@@ -1759,7 +1853,7 @@ static void __journal_abort_soft (journal_t *journal, int errno)
        __jbd2_journal_abort_hard(journal);
 
        if (errno)
-               jbd2_journal_update_superblock(journal, 1);
+               jbd2_journal_update_sb_errno(journal);
 }
 
 /**
@@ -2017,7 +2111,7 @@ static struct kmem_cache *jbd2_journal_head_cache;
 static atomic_t nr_journal_heads = ATOMIC_INIT(0);
 #endif
 
-static int journal_init_jbd2_journal_head_cache(void)
+static int jbd2_journal_init_journal_head_cache(void)
 {
        int retval;
 
@@ -2035,7 +2129,7 @@ static int journal_init_jbd2_journal_head_cache(void)
        return retval;
 }
 
-static void jbd2_journal_destroy_jbd2_journal_head_cache(void)
+static void jbd2_journal_destroy_journal_head_cache(void)
 {
        if (jbd2_journal_head_cache) {
                kmem_cache_destroy(jbd2_journal_head_cache);
@@ -2323,7 +2417,7 @@ static void __exit jbd2_remove_jbd_stats_proc_entry(void)
 
 struct kmem_cache *jbd2_handle_cache, *jbd2_inode_cache;
 
-static int __init journal_init_handle_cache(void)
+static int __init jbd2_journal_init_handle_cache(void)
 {
        jbd2_handle_cache = KMEM_CACHE(jbd2_journal_handle, SLAB_TEMPORARY);
        if (jbd2_handle_cache == NULL) {
@@ -2358,17 +2452,20 @@ static int __init journal_init_caches(void)
 
        ret = jbd2_journal_init_revoke_caches();
        if (ret == 0)
-               ret = journal_init_jbd2_journal_head_cache();
+               ret = jbd2_journal_init_journal_head_cache();
+       if (ret == 0)
+               ret = jbd2_journal_init_handle_cache();
        if (ret == 0)
-               ret = journal_init_handle_cache();
+               ret = jbd2_journal_init_transaction_cache();
        return ret;
 }
 
 static void jbd2_journal_destroy_caches(void)
 {
        jbd2_journal_destroy_revoke_caches();
-       jbd2_journal_destroy_jbd2_journal_head_cache();
+       jbd2_journal_destroy_journal_head_cache();
        jbd2_journal_destroy_handle_cache();
+       jbd2_journal_destroy_transaction_cache();
        jbd2_journal_destroy_slabs();
 }
 
index da6d7baf1390c401cc52b1cb005cde1ff7776483..c1a03354a22ff1b5a787251b422afcb5225ca2c9 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/jbd2.h>
 #include <linux/errno.h>
 #include <linux/crc32.h>
+#include <linux/blkdev.h>
 #endif
 
 /*
@@ -265,7 +266,9 @@ int jbd2_journal_recover(journal_t *journal)
        err2 = sync_blockdev(journal->j_fs_dev);
        if (!err)
                err = err2;
-
+       /* Make sure all replayed data is on permanent storage */
+       if (journal->j_flags & JBD2_BARRIER)
+               blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL);
        return err;
 }
 
index 30b2867d6cc950cb7eeceeb528f18d073405117b..6973705d6a3d9db1c96ed67f55c97c8a13ee2f6d 100644 (file)
@@ -208,17 +208,13 @@ int __init jbd2_journal_init_revoke_caches(void)
        J_ASSERT(!jbd2_revoke_record_cache);
        J_ASSERT(!jbd2_revoke_table_cache);
 
-       jbd2_revoke_record_cache = kmem_cache_create("jbd2_revoke_record",
-                                          sizeof(struct jbd2_revoke_record_s),
-                                          0,
-                                          SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY,
-                                          NULL);
+       jbd2_revoke_record_cache = KMEM_CACHE(jbd2_revoke_record_s,
+                                       SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY);
        if (!jbd2_revoke_record_cache)
                goto record_cache_failure;
 
-       jbd2_revoke_table_cache = kmem_cache_create("jbd2_revoke_table",
-                                          sizeof(struct jbd2_revoke_table_s),
-                                          0, SLAB_TEMPORARY, NULL);
+       jbd2_revoke_table_cache = KMEM_CACHE(jbd2_revoke_table_s,
+                                            SLAB_TEMPORARY);
        if (!jbd2_revoke_table_cache)
                goto table_cache_failure;
        return 0;
index e5aba56e1fd51cd01e001d090f572b3b5f1b41ed..ddcd3549c6c26cbc9cb9dd46831b189ed3c0441e 100644 (file)
 static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh);
 static void __jbd2_journal_unfile_buffer(struct journal_head *jh);
 
+static struct kmem_cache *transaction_cache;
+int __init jbd2_journal_init_transaction_cache(void)
+{
+       J_ASSERT(!transaction_cache);
+       transaction_cache = kmem_cache_create("jbd2_transaction_s",
+                                       sizeof(transaction_t),
+                                       0,
+                                       SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY,
+                                       NULL);
+       if (transaction_cache)
+               return 0;
+       return -ENOMEM;
+}
+
+void jbd2_journal_destroy_transaction_cache(void)
+{
+       if (transaction_cache) {
+               kmem_cache_destroy(transaction_cache);
+               transaction_cache = NULL;
+       }
+}
+
+void jbd2_journal_free_transaction(transaction_t *transaction)
+{
+       if (unlikely(ZERO_OR_NULL_PTR(transaction)))
+               return;
+       kmem_cache_free(transaction_cache, transaction);
+}
+
 /*
  * jbd2_get_transaction: obtain a new transaction_t object.
  *
@@ -133,7 +162,8 @@ static int start_this_handle(journal_t *journal, handle_t *handle,
 
 alloc_transaction:
        if (!journal->j_running_transaction) {
-               new_transaction = kzalloc(sizeof(*new_transaction), gfp_mask);
+               new_transaction = kmem_cache_alloc(transaction_cache,
+                                                  gfp_mask | __GFP_ZERO);
                if (!new_transaction) {
                        /*
                         * If __GFP_FS is not present, then we may be
@@ -162,7 +192,7 @@ repeat:
        if (is_journal_aborted(journal) ||
            (journal->j_errno != 0 && !(journal->j_flags & JBD2_ACK_ERR))) {
                read_unlock(&journal->j_state_lock);
-               kfree(new_transaction);
+               jbd2_journal_free_transaction(new_transaction);
                return -EROFS;
        }
 
@@ -284,7 +314,7 @@ repeat:
        read_unlock(&journal->j_state_lock);
 
        lock_map_acquire(&handle->h_lockdep_map);
-       kfree(new_transaction);
+       jbd2_journal_free_transaction(new_transaction);
        return 0;
 }
 
@@ -1549,9 +1579,9 @@ __blist_del_buffer(struct journal_head **list, struct journal_head *jh)
  * of these pointers, it could go bad.  Generally the caller needs to re-read
  * the pointer from the transaction_t.
  *
- * Called under j_list_lock.  The journal may not be locked.
+ * Called under j_list_lock.
  */
-void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh)
+static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh)
 {
        struct journal_head **list = NULL;
        transaction_t *transaction;
@@ -1646,10 +1676,8 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh)
        spin_lock(&journal->j_list_lock);
        if (jh->b_cp_transaction != NULL && jh->b_transaction == NULL) {
                /* written-back checkpointed metadata buffer */
-               if (jh->b_jlist == BJ_None) {
-                       JBUFFER_TRACE(jh, "remove from checkpoint list");
-                       __jbd2_journal_remove_checkpoint(jh);
-               }
+               JBUFFER_TRACE(jh, "remove from checkpoint list");
+               __jbd2_journal_remove_checkpoint(jh);
        }
        spin_unlock(&journal->j_list_lock);
 out:
@@ -1949,6 +1977,8 @@ zap_buffer_unlocked:
        clear_buffer_mapped(bh);
        clear_buffer_req(bh);
        clear_buffer_new(bh);
+       clear_buffer_delay(bh);
+       clear_buffer_unwritten(bh);
        bh->b_bdev = NULL;
        return may_free;
 }
index 8b4f12b33f57ac682c5ff1d788b7c42e192feb3f..d69a1d1d7e154553f3b7ae6c85602f3f9e2a9104 100644 (file)
@@ -1110,6 +1110,13 @@ static void dquot_decr_space(struct dquot *dquot, qsize_t number)
        clear_bit(DQ_BLKS_B, &dquot->dq_flags);
 }
 
+struct dquot_warn {
+       struct super_block *w_sb;
+       qid_t w_dq_id;
+       short w_dq_type;
+       short w_type;
+};
+
 static int warning_issued(struct dquot *dquot, const int warntype)
 {
        int flag = (warntype == QUOTA_NL_BHARDWARN ||
@@ -1125,41 +1132,42 @@ static int warning_issued(struct dquot *dquot, const int warntype)
 #ifdef CONFIG_PRINT_QUOTA_WARNING
 static int flag_print_warnings = 1;
 
-static int need_print_warning(struct dquot *dquot)
+static int need_print_warning(struct dquot_warn *warn)
 {
        if (!flag_print_warnings)
                return 0;
 
-       switch (dquot->dq_type) {
+       switch (warn->w_dq_type) {
                case USRQUOTA:
-                       return current_fsuid() == dquot->dq_id;
+                       return current_fsuid() == warn->w_dq_id;
                case GRPQUOTA:
-                       return in_group_p(dquot->dq_id);
+                       return in_group_p(warn->w_dq_id);
        }
        return 0;
 }
 
 /* Print warning to user which exceeded quota */
-static void print_warning(struct dquot *dquot, const int warntype)
+static void print_warning(struct dquot_warn *warn)
 {
        char *msg = NULL;
        struct tty_struct *tty;
+       int warntype = warn->w_type;
 
        if (warntype == QUOTA_NL_IHARDBELOW ||
            warntype == QUOTA_NL_ISOFTBELOW ||
            warntype == QUOTA_NL_BHARDBELOW ||
-           warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(dquot))
+           warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(warn))
                return;
 
        tty = get_current_tty();
        if (!tty)
                return;
-       tty_write_message(tty, dquot->dq_sb->s_id);
+       tty_write_message(tty, warn->w_sb->s_id);
        if (warntype == QUOTA_NL_ISOFTWARN || warntype == QUOTA_NL_BSOFTWARN)
                tty_write_message(tty, ": warning, ");
        else
                tty_write_message(tty, ": write failed, ");
-       tty_write_message(tty, quotatypes[dquot->dq_type]);
+       tty_write_message(tty, quotatypes[warn->w_dq_type]);
        switch (warntype) {
                case QUOTA_NL_IHARDWARN:
                        msg = " file limit reached.\r\n";
@@ -1185,26 +1193,34 @@ static void print_warning(struct dquot *dquot, const int warntype)
 }
 #endif
 
+static void prepare_warning(struct dquot_warn *warn, struct dquot *dquot,
+                           int warntype)
+{
+       if (warning_issued(dquot, warntype))
+               return;
+       warn->w_type = warntype;
+       warn->w_sb = dquot->dq_sb;
+       warn->w_dq_id = dquot->dq_id;
+       warn->w_dq_type = dquot->dq_type;
+}
+
 /*
  * Write warnings to the console and send warning messages over netlink.
  *
- * Note that this function can sleep.
+ * Note that this function can call into tty and networking code.
  */
-static void flush_warnings(struct dquot *const *dquots, char *warntype)
+static void flush_warnings(struct dquot_warn *warn)
 {
-       struct dquot *dq;
        int i;
 
        for (i = 0; i < MAXQUOTAS; i++) {
-               dq = dquots[i];
-               if (dq && warntype[i] != QUOTA_NL_NOWARN &&
-                   !warning_issued(dq, warntype[i])) {
+               if (warn[i].w_type == QUOTA_NL_NOWARN)
+                       continue;
 #ifdef CONFIG_PRINT_QUOTA_WARNING
-                       print_warning(dq, warntype[i]);
+               print_warning(&warn[i]);
 #endif
-                       quota_send_warning(dq->dq_type, dq->dq_id,
-                                          dq->dq_sb->s_dev, warntype[i]);
-               }
+               quota_send_warning(warn[i].w_dq_type, warn[i].w_dq_id,
+                                  warn[i].w_sb->s_dev, warn[i].w_type);
        }
 }
 
@@ -1218,11 +1234,11 @@ static int ignore_hardlimit(struct dquot *dquot)
 }
 
 /* needs dq_data_lock */
-static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype)
+static int check_idq(struct dquot *dquot, qsize_t inodes,
+                    struct dquot_warn *warn)
 {
        qsize_t newinodes = dquot->dq_dqb.dqb_curinodes + inodes;
 
-       *warntype = QUOTA_NL_NOWARN;
        if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) ||
            test_bit(DQ_FAKE_B, &dquot->dq_flags))
                return 0;
@@ -1230,7 +1246,7 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype)
        if (dquot->dq_dqb.dqb_ihardlimit &&
            newinodes > dquot->dq_dqb.dqb_ihardlimit &&
             !ignore_hardlimit(dquot)) {
-               *warntype = QUOTA_NL_IHARDWARN;
+               prepare_warning(warn, dquot, QUOTA_NL_IHARDWARN);
                return -EDQUOT;
        }
 
@@ -1239,14 +1255,14 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype)
            dquot->dq_dqb.dqb_itime &&
            get_seconds() >= dquot->dq_dqb.dqb_itime &&
             !ignore_hardlimit(dquot)) {
-               *warntype = QUOTA_NL_ISOFTLONGWARN;
+               prepare_warning(warn, dquot, QUOTA_NL_ISOFTLONGWARN);
                return -EDQUOT;
        }
 
        if (dquot->dq_dqb.dqb_isoftlimit &&
            newinodes > dquot->dq_dqb.dqb_isoftlimit &&
            dquot->dq_dqb.dqb_itime == 0) {
-               *warntype = QUOTA_NL_ISOFTWARN;
+               prepare_warning(warn, dquot, QUOTA_NL_ISOFTWARN);
                dquot->dq_dqb.dqb_itime = get_seconds() +
                    sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
        }
@@ -1255,12 +1271,12 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype)
 }
 
 /* needs dq_data_lock */
-static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype)
+static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc,
+                    struct dquot_warn *warn)
 {
        qsize_t tspace;
        struct super_block *sb = dquot->dq_sb;
 
-       *warntype = QUOTA_NL_NOWARN;
        if (!sb_has_quota_limits_enabled(sb, dquot->dq_type) ||
            test_bit(DQ_FAKE_B, &dquot->dq_flags))
                return 0;
@@ -1272,7 +1288,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
            tspace > dquot->dq_dqb.dqb_bhardlimit &&
             !ignore_hardlimit(dquot)) {
                if (!prealloc)
-                       *warntype = QUOTA_NL_BHARDWARN;
+                       prepare_warning(warn, dquot, QUOTA_NL_BHARDWARN);
                return -EDQUOT;
        }
 
@@ -1282,7 +1298,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
            get_seconds() >= dquot->dq_dqb.dqb_btime &&
             !ignore_hardlimit(dquot)) {
                if (!prealloc)
-                       *warntype = QUOTA_NL_BSOFTLONGWARN;
+                       prepare_warning(warn, dquot, QUOTA_NL_BSOFTLONGWARN);
                return -EDQUOT;
        }
 
@@ -1290,7 +1306,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
            tspace > dquot->dq_dqb.dqb_bsoftlimit &&
            dquot->dq_dqb.dqb_btime == 0) {
                if (!prealloc) {
-                       *warntype = QUOTA_NL_BSOFTWARN;
+                       prepare_warning(warn, dquot, QUOTA_NL_BSOFTWARN);
                        dquot->dq_dqb.dqb_btime = get_seconds() +
                            sb_dqopt(sb)->info[dquot->dq_type].dqi_bgrace;
                }
@@ -1543,10 +1559,9 @@ static void inode_decr_space(struct inode *inode, qsize_t number, int reserve)
 int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
 {
        int cnt, ret = 0;
-       char warntype[MAXQUOTAS];
-       int warn = flags & DQUOT_SPACE_WARN;
+       struct dquot_warn warn[MAXQUOTAS];
+       struct dquot **dquots = inode->i_dquot;
        int reserve = flags & DQUOT_SPACE_RESERVE;
-       int nofail = flags & DQUOT_SPACE_NOFAIL;
 
        /*
         * First test before acquiring mutex - solves deadlocks when we
@@ -1559,36 +1574,36 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
 
        down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
        for (cnt = 0; cnt < MAXQUOTAS; cnt++)
-               warntype[cnt] = QUOTA_NL_NOWARN;
+               warn[cnt].w_type = QUOTA_NL_NOWARN;
 
        spin_lock(&dq_data_lock);
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-               if (!inode->i_dquot[cnt])
+               if (!dquots[cnt])
                        continue;
-               ret = check_bdq(inode->i_dquot[cnt], number, !warn,
-                               warntype+cnt);
-               if (ret && !nofail) {
+               ret = check_bdq(dquots[cnt], number,
+                               !(flags & DQUOT_SPACE_WARN), &warn[cnt]);
+               if (ret && !(flags & DQUOT_SPACE_NOFAIL)) {
                        spin_unlock(&dq_data_lock);
                        goto out_flush_warn;
                }
        }
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-               if (!inode->i_dquot[cnt])
+               if (!dquots[cnt])
                        continue;
                if (reserve)
-                       dquot_resv_space(inode->i_dquot[cnt], number);
+                       dquot_resv_space(dquots[cnt], number);
                else
-                       dquot_incr_space(inode->i_dquot[cnt], number);
+                       dquot_incr_space(dquots[cnt], number);
        }
        inode_incr_space(inode, number, reserve);
        spin_unlock(&dq_data_lock);
 
        if (reserve)
                goto out_flush_warn;
-       mark_all_dquot_dirty(inode->i_dquot);
+       mark_all_dquot_dirty(dquots);
 out_flush_warn:
-       flush_warnings(inode->i_dquot, warntype);
        up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
+       flush_warnings(warn);
 out:
        return ret;
 }
@@ -1600,36 +1615,37 @@ EXPORT_SYMBOL(__dquot_alloc_space);
 int dquot_alloc_inode(const struct inode *inode)
 {
        int cnt, ret = 0;
-       char warntype[MAXQUOTAS];
+       struct dquot_warn warn[MAXQUOTAS];
+       struct dquot * const *dquots = inode->i_dquot;
 
        /* First test before acquiring mutex - solves deadlocks when we
          * re-enter the quota code and are already holding the mutex */
        if (!dquot_active(inode))
                return 0;
        for (cnt = 0; cnt < MAXQUOTAS; cnt++)
-               warntype[cnt] = QUOTA_NL_NOWARN;
+               warn[cnt].w_type = QUOTA_NL_NOWARN;
        down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
        spin_lock(&dq_data_lock);
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-               if (!inode->i_dquot[cnt])
+               if (!dquots[cnt])
                        continue;
-               ret = check_idq(inode->i_dquot[cnt], 1, warntype + cnt);
+               ret = check_idq(dquots[cnt], 1, &warn[cnt]);
                if (ret)
                        goto warn_put_all;
        }
 
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-               if (!inode->i_dquot[cnt])
+               if (!dquots[cnt])
                        continue;
-               dquot_incr_inodes(inode->i_dquot[cnt], 1);
+               dquot_incr_inodes(dquots[cnt], 1);
        }
 
 warn_put_all:
        spin_unlock(&dq_data_lock);
        if (ret == 0)
-               mark_all_dquot_dirty(inode->i_dquot);
-       flush_warnings(inode->i_dquot, warntype);
+               mark_all_dquot_dirty(dquots);
        up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
+       flush_warnings(warn);
        return ret;
 }
 EXPORT_SYMBOL(dquot_alloc_inode);
@@ -1669,7 +1685,8 @@ EXPORT_SYMBOL(dquot_claim_space_nodirty);
 void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
 {
        unsigned int cnt;
-       char warntype[MAXQUOTAS];
+       struct dquot_warn warn[MAXQUOTAS];
+       struct dquot **dquots = inode->i_dquot;
        int reserve = flags & DQUOT_SPACE_RESERVE;
 
        /* First test before acquiring mutex - solves deadlocks when we
@@ -1682,23 +1699,28 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
        down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
        spin_lock(&dq_data_lock);
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-               if (!inode->i_dquot[cnt])
+               int wtype;
+
+               warn[cnt].w_type = QUOTA_NL_NOWARN;
+               if (!dquots[cnt])
                        continue;
-               warntype[cnt] = info_bdq_free(inode->i_dquot[cnt], number);
+               wtype = info_bdq_free(dquots[cnt], number);
+               if (wtype != QUOTA_NL_NOWARN)
+                       prepare_warning(&warn[cnt], dquots[cnt], wtype);
                if (reserve)
-                       dquot_free_reserved_space(inode->i_dquot[cnt], number);
+                       dquot_free_reserved_space(dquots[cnt], number);
                else
-                       dquot_decr_space(inode->i_dquot[cnt], number);
+                       dquot_decr_space(dquots[cnt], number);
        }
        inode_decr_space(inode, number, reserve);
        spin_unlock(&dq_data_lock);
 
        if (reserve)
                goto out_unlock;
-       mark_all_dquot_dirty(inode->i_dquot);
+       mark_all_dquot_dirty(dquots);
 out_unlock:
-       flush_warnings(inode->i_dquot, warntype);
        up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
+       flush_warnings(warn);
 }
 EXPORT_SYMBOL(__dquot_free_space);
 
@@ -1708,7 +1730,8 @@ EXPORT_SYMBOL(__dquot_free_space);
 void dquot_free_inode(const struct inode *inode)
 {
        unsigned int cnt;
-       char warntype[MAXQUOTAS];
+       struct dquot_warn warn[MAXQUOTAS];
+       struct dquot * const *dquots = inode->i_dquot;
 
        /* First test before acquiring mutex - solves deadlocks when we
          * re-enter the quota code and are already holding the mutex */
@@ -1718,15 +1741,20 @@ void dquot_free_inode(const struct inode *inode)
        down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
        spin_lock(&dq_data_lock);
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-               if (!inode->i_dquot[cnt])
+               int wtype;
+
+               warn[cnt].w_type = QUOTA_NL_NOWARN;
+               if (!dquots[cnt])
                        continue;
-               warntype[cnt] = info_idq_free(inode->i_dquot[cnt], 1);
-               dquot_decr_inodes(inode->i_dquot[cnt], 1);
+               wtype = info_idq_free(dquots[cnt], 1);
+               if (wtype != QUOTA_NL_NOWARN)
+                       prepare_warning(&warn[cnt], dquots[cnt], wtype);
+               dquot_decr_inodes(dquots[cnt], 1);
        }
        spin_unlock(&dq_data_lock);
-       mark_all_dquot_dirty(inode->i_dquot);
-       flush_warnings(inode->i_dquot, warntype);
+       mark_all_dquot_dirty(dquots);
        up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
+       flush_warnings(warn);
 }
 EXPORT_SYMBOL(dquot_free_inode);
 
@@ -1747,16 +1775,20 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
        struct dquot *transfer_from[MAXQUOTAS] = {};
        int cnt, ret = 0;
        char is_valid[MAXQUOTAS] = {};
-       char warntype_to[MAXQUOTAS];
-       char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS];
+       struct dquot_warn warn_to[MAXQUOTAS];
+       struct dquot_warn warn_from_inodes[MAXQUOTAS];
+       struct dquot_warn warn_from_space[MAXQUOTAS];
 
        /* First test before acquiring mutex - solves deadlocks when we
          * re-enter the quota code and are already holding the mutex */
        if (IS_NOQUOTA(inode))
                return 0;
        /* Initialize the arrays */
-       for (cnt = 0; cnt < MAXQUOTAS; cnt++)
-               warntype_to[cnt] = QUOTA_NL_NOWARN;
+       for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+               warn_to[cnt].w_type = QUOTA_NL_NOWARN;
+               warn_from_inodes[cnt].w_type = QUOTA_NL_NOWARN;
+               warn_from_space[cnt].w_type = QUOTA_NL_NOWARN;
+       }
        down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
        if (IS_NOQUOTA(inode)) {        /* File without quota accounting? */
                up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
@@ -1778,10 +1810,10 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
                        continue;
                is_valid[cnt] = 1;
                transfer_from[cnt] = inode->i_dquot[cnt];
-               ret = check_idq(transfer_to[cnt], 1, warntype_to + cnt);
+               ret = check_idq(transfer_to[cnt], 1, &warn_to[cnt]);
                if (ret)
                        goto over_quota;
-               ret = check_bdq(transfer_to[cnt], space, 0, warntype_to + cnt);
+               ret = check_bdq(transfer_to[cnt], space, 0, &warn_to[cnt]);
                if (ret)
                        goto over_quota;
        }
@@ -1794,10 +1826,15 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
                        continue;
                /* Due to IO error we might not have transfer_from[] structure */
                if (transfer_from[cnt]) {
-                       warntype_from_inodes[cnt] =
-                               info_idq_free(transfer_from[cnt], 1);
-                       warntype_from_space[cnt] =
-                               info_bdq_free(transfer_from[cnt], space);
+                       int wtype;
+                       wtype = info_idq_free(transfer_from[cnt], 1);
+                       if (wtype != QUOTA_NL_NOWARN)
+                               prepare_warning(&warn_from_inodes[cnt],
+                                               transfer_from[cnt], wtype);
+                       wtype = info_bdq_free(transfer_from[cnt], space);
+                       if (wtype != QUOTA_NL_NOWARN)
+                               prepare_warning(&warn_from_space[cnt],
+                                               transfer_from[cnt], wtype);
                        dquot_decr_inodes(transfer_from[cnt], 1);
                        dquot_decr_space(transfer_from[cnt], cur_space);
                        dquot_free_reserved_space(transfer_from[cnt],
@@ -1815,9 +1852,9 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
 
        mark_all_dquot_dirty(transfer_from);
        mark_all_dquot_dirty(transfer_to);
-       flush_warnings(transfer_to, warntype_to);
-       flush_warnings(transfer_from, warntype_from_inodes);
-       flush_warnings(transfer_from, warntype_from_space);
+       flush_warnings(warn_to);
+       flush_warnings(warn_from_inodes);
+       flush_warnings(warn_from_space);
        /* Pass back references to put */
        for (cnt = 0; cnt < MAXQUOTAS; cnt++)
                if (is_valid[cnt])
@@ -1826,7 +1863,7 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
 over_quota:
        spin_unlock(&dq_data_lock);
        up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
-       flush_warnings(transfer_to, warntype_to);
+       flush_warnings(warn_to);
        return ret;
 }
 EXPORT_SYMBOL(__dquot_transfer);
index 987585bb0a1da594fef277e8b6e0374adaed6547..1ba2baaf43671889f2eb0339e92996a1bf41f7ca 100644 (file)
@@ -105,7 +105,6 @@ static void udf_add_free_space(struct super_block *sb, u16 partition, u32 cnt)
 }
 
 static void udf_bitmap_free_blocks(struct super_block *sb,
-                                  struct inode *inode,
                                   struct udf_bitmap *bitmap,
                                   struct kernel_lb_addr *bloc,
                                   uint32_t offset,
@@ -172,7 +171,6 @@ error_return:
 }
 
 static int udf_bitmap_prealloc_blocks(struct super_block *sb,
-                                     struct inode *inode,
                                      struct udf_bitmap *bitmap,
                                      uint16_t partition, uint32_t first_block,
                                      uint32_t block_count)
@@ -223,7 +221,6 @@ out:
 }
 
 static int udf_bitmap_new_block(struct super_block *sb,
-                               struct inode *inode,
                                struct udf_bitmap *bitmap, uint16_t partition,
                                uint32_t goal, int *err)
 {
@@ -349,7 +346,6 @@ error_return:
 }
 
 static void udf_table_free_blocks(struct super_block *sb,
-                                 struct inode *inode,
                                  struct inode *table,
                                  struct kernel_lb_addr *bloc,
                                  uint32_t offset,
@@ -581,7 +577,6 @@ error_return:
 }
 
 static int udf_table_prealloc_blocks(struct super_block *sb,
-                                    struct inode *inode,
                                     struct inode *table, uint16_t partition,
                                     uint32_t first_block, uint32_t block_count)
 {
@@ -643,7 +638,6 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
 }
 
 static int udf_table_new_block(struct super_block *sb,
-                              struct inode *inode,
                               struct inode *table, uint16_t partition,
                               uint32_t goal, int *err)
 {
@@ -743,18 +737,23 @@ void udf_free_blocks(struct super_block *sb, struct inode *inode,
        struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition];
 
        if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) {
-               udf_bitmap_free_blocks(sb, inode, map->s_uspace.s_bitmap,
+               udf_bitmap_free_blocks(sb, map->s_uspace.s_bitmap,
                                       bloc, offset, count);
        } else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) {
-               udf_table_free_blocks(sb, inode, map->s_uspace.s_table,
+               udf_table_free_blocks(sb, map->s_uspace.s_table,
                                      bloc, offset, count);
        } else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) {
-               udf_bitmap_free_blocks(sb, inode, map->s_fspace.s_bitmap,
+               udf_bitmap_free_blocks(sb, map->s_fspace.s_bitmap,
                                       bloc, offset, count);
        } else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) {
-               udf_table_free_blocks(sb, inode, map->s_fspace.s_table,
+               udf_table_free_blocks(sb, map->s_fspace.s_table,
                                      bloc, offset, count);
        }
+
+       if (inode) {
+               inode_sub_bytes(inode,
+                               ((sector_t)count) << sb->s_blocksize_bits);
+       }
 }
 
 inline int udf_prealloc_blocks(struct super_block *sb,
@@ -763,29 +762,34 @@ inline int udf_prealloc_blocks(struct super_block *sb,
                               uint32_t block_count)
 {
        struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition];
+       sector_t allocated;
 
        if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP)
-               return udf_bitmap_prealloc_blocks(sb, inode,
-                                                 map->s_uspace.s_bitmap,
-                                                 partition, first_block,
-                                                 block_count);
+               allocated = udf_bitmap_prealloc_blocks(sb,
+                                                      map->s_uspace.s_bitmap,
+                                                      partition, first_block,
+                                                      block_count);
        else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE)
-               return udf_table_prealloc_blocks(sb, inode,
-                                                map->s_uspace.s_table,
-                                                partition, first_block,
-                                                block_count);
+               allocated = udf_table_prealloc_blocks(sb,
+                                                     map->s_uspace.s_table,
+                                                     partition, first_block,
+                                                     block_count);
        else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP)
-               return udf_bitmap_prealloc_blocks(sb, inode,
-                                                 map->s_fspace.s_bitmap,
-                                                 partition, first_block,
-                                                 block_count);
+               allocated = udf_bitmap_prealloc_blocks(sb,
+                                                      map->s_fspace.s_bitmap,
+                                                      partition, first_block,
+                                                      block_count);
        else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE)
-               return udf_table_prealloc_blocks(sb, inode,
-                                                map->s_fspace.s_table,
-                                                partition, first_block,
-                                                block_count);
+               allocated = udf_table_prealloc_blocks(sb,
+                                                     map->s_fspace.s_table,
+                                                     partition, first_block,
+                                                     block_count);
        else
                return 0;
+
+       if (inode && allocated > 0)
+               inode_add_bytes(inode, allocated << sb->s_blocksize_bits);
+       return allocated;
 }
 
 inline int udf_new_block(struct super_block *sb,
@@ -793,25 +797,29 @@ inline int udf_new_block(struct super_block *sb,
                         uint16_t partition, uint32_t goal, int *err)
 {
        struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition];
+       int block;
 
        if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP)
-               return udf_bitmap_new_block(sb, inode,
-                                          map->s_uspace.s_bitmap,
-                                          partition, goal, err);
+               block = udf_bitmap_new_block(sb,
+                                            map->s_uspace.s_bitmap,
+                                            partition, goal, err);
        else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE)
-               return udf_table_new_block(sb, inode,
-                                          map->s_uspace.s_table,
-                                          partition, goal, err);
-       else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP)
-               return udf_bitmap_new_block(sb, inode,
-                                           map->s_fspace.s_bitmap,
+               block = udf_table_new_block(sb,
+                                           map->s_uspace.s_table,
                                            partition, goal, err);
+       else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP)
+               block = udf_bitmap_new_block(sb,
+                                            map->s_fspace.s_bitmap,
+                                            partition, goal, err);
        else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE)
-               return udf_table_new_block(sb, inode,
-                                          map->s_fspace.s_table,
-                                          partition, goal, err);
+               block = udf_table_new_block(sb,
+                                           map->s_fspace.s_table,
+                                           partition, goal, err);
        else {
                *err = -EIO;
                return 0;
        }
+       if (inode && block)
+               inode_add_bytes(inode, sb->s_blocksize);
+       return block;
 }
index 05ab48195be96f0f38587493ec57423d1febc083..7e5aae4bf46fd1c1e65da56615238ffe4944fd3b 100644 (file)
@@ -116,6 +116,7 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode, int *err)
        iinfo->i_lenEAttr = 0;
        iinfo->i_lenAlloc = 0;
        iinfo->i_use = 0;
+       iinfo->i_checkpoint = 1;
        if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB))
                iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
        else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
index 7699df7b3198e40e02d84a1c444e1bf360140f06..7d7528008359eca147778d09a303ca7c5424f5c4 100644 (file)
@@ -1358,6 +1358,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
                iinfo->i_unique = le64_to_cpu(fe->uniqueID);
                iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr);
                iinfo->i_lenAlloc = le32_to_cpu(fe->lengthAllocDescs);
+               iinfo->i_checkpoint = le32_to_cpu(fe->checkpoint);
                offset = sizeof(struct fileEntry) + iinfo->i_lenEAttr;
        } else {
                inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) <<
@@ -1379,6 +1380,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
                iinfo->i_unique = le64_to_cpu(efe->uniqueID);
                iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr);
                iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs);
+               iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint);
                offset = sizeof(struct extendedFileEntry) +
                                                        iinfo->i_lenEAttr;
        }
@@ -1495,6 +1497,7 @@ static int udf_update_inode(struct inode *inode, int do_sync)
        struct buffer_head *bh = NULL;
        struct fileEntry *fe;
        struct extendedFileEntry *efe;
+       uint64_t lb_recorded;
        uint32_t udfperms;
        uint16_t icbflags;
        uint16_t crclen;
@@ -1589,13 +1592,18 @@ static int udf_update_inode(struct inode *inode, int do_sync)
                dsea->minorDeviceIdent = cpu_to_le32(iminor(inode));
        }
 
+       if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
+               lb_recorded = 0; /* No extents => no blocks! */
+       else
+               lb_recorded =
+                       (inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >>
+                       (blocksize_bits - 9);
+
        if (iinfo->i_efe == 0) {
                memcpy(bh->b_data + sizeof(struct fileEntry),
                       iinfo->i_ext.i_data,
                       inode->i_sb->s_blocksize - sizeof(struct fileEntry));
-               fe->logicalBlocksRecorded = cpu_to_le64(
-                       (inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >>
-                       (blocksize_bits - 9));
+               fe->logicalBlocksRecorded = cpu_to_le64(lb_recorded);
 
                udf_time_to_disk_stamp(&fe->accessTime, inode->i_atime);
                udf_time_to_disk_stamp(&fe->modificationTime, inode->i_mtime);
@@ -1607,6 +1615,7 @@ static int udf_update_inode(struct inode *inode, int do_sync)
                fe->uniqueID = cpu_to_le64(iinfo->i_unique);
                fe->lengthExtendedAttr = cpu_to_le32(iinfo->i_lenEAttr);
                fe->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc);
+               fe->checkpoint = cpu_to_le32(iinfo->i_checkpoint);
                fe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_FE);
                crclen = sizeof(struct fileEntry);
        } else {
@@ -1615,9 +1624,7 @@ static int udf_update_inode(struct inode *inode, int do_sync)
                       inode->i_sb->s_blocksize -
                                        sizeof(struct extendedFileEntry));
                efe->objectSize = cpu_to_le64(inode->i_size);
-               efe->logicalBlocksRecorded = cpu_to_le64(
-                       (inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >>
-                       (blocksize_bits - 9));
+               efe->logicalBlocksRecorded = cpu_to_le64(lb_recorded);
 
                if (iinfo->i_crtime.tv_sec > inode->i_atime.tv_sec ||
                    (iinfo->i_crtime.tv_sec == inode->i_atime.tv_sec &&
@@ -1646,6 +1653,7 @@ static int udf_update_inode(struct inode *inode, int do_sync)
                efe->uniqueID = cpu_to_le64(iinfo->i_unique);
                efe->lengthExtendedAttr = cpu_to_le32(iinfo->i_lenEAttr);
                efe->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc);
+               efe->checkpoint = cpu_to_le32(iinfo->i_checkpoint);
                efe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EFE);
                crclen = sizeof(struct extendedFileEntry);
        }
index 85067b4c7e144d743e23fc0de7602470ffe367f9..ac8a348dcb693bb10a24a930346b82bc7db799f9 100644 (file)
@@ -950,11 +950,8 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index)
        else
                bitmap = vzalloc(size); /* TODO: get rid of vzalloc */
 
-       if (bitmap == NULL) {
-               udf_err(sb, "Unable to allocate space for bitmap and %d buffer_head pointers\n",
-                       nr_groups);
+       if (bitmap == NULL)
                return NULL;
-       }
 
        bitmap->s_block_bitmap = (struct buffer_head **)(bitmap + 1);
        bitmap->s_nr_groups = nr_groups;
index d1bd31ea724e8804e1467ff955bef46ad4aa0c5a..bb8309dcd5c1bd2d797b5e774e86c8e2d97e529f 100644 (file)
@@ -23,6 +23,7 @@ struct udf_inode_info {
        __u64                   i_lenExtents;
        __u32                   i_next_alloc_block;
        __u32                   i_next_alloc_goal;
+       __u32                   i_checkpoint;
        unsigned                i_alloc_type : 3;
        unsigned                i_efe : 1;      /* extendedFileEntry */
        unsigned                i_use : 1;      /* unallocSpaceEntry */
index 53ba65e30caa2b61f9f6ab080ac9c5c1907a4b8e..1d14b1dc1aee69588ce68329e5fa71189d277016 100644 (file)
 
 struct clk;
 
+/**
+ * struct atmel_tcb_config - SoC data for a Timer/Counter Block
+ * @counter_width: size in bits of a timer counter register
+ */
+struct atmel_tcb_config {
+       size_t  counter_width;
+};
+
 /**
  * struct atmel_tc - information about a Timer/Counter Block
  * @pdev: physical device
  * @iomem: resource associated with the I/O register
  * @regs: mapping through which the I/O registers can be accessed
+ * @tcb_config: configuration data from SoC
  * @irq: irq for each of the three channels
  * @clk: internal clock source for each of the three channels
  * @node: list node, for tclib internal use
@@ -54,6 +63,7 @@ struct atmel_tc {
        struct platform_device  *pdev;
        struct resource         *iomem;
        void __iomem            *regs;
+       struct atmel_tcb_config *tcb_config;
        int                     irq[3];
        struct clk              *clk[3];
        struct list_head        node;
index e8cf0ccd1a8dd180c0a21c8dca40c139bbf041b6..e71d683982a6f651a83a22fd7ef12bf7af6f655f 100644 (file)
@@ -208,7 +208,7 @@ extern struct kmem_cache *ceph_cap_cachep;
 extern struct kmem_cache *ceph_dentry_cachep;
 extern struct kmem_cache *ceph_file_cachep;
 
-extern int ceph_parse_options(struct ceph_options **popt, char *options,
+extern struct ceph_options *ceph_parse_options(char *options,
                              const char *dev_name, const char *dev_name_end,
                              int (*parse_extra_token)(char *c, void *private),
                              void *private);
index ffbeb2c217b442036a2675cc4cb4e6d5e1bf0d8b..3bff047f6b0f19d1037e4e7157fc785dd213f4cc 100644 (file)
@@ -14,8 +14,6 @@
 struct ceph_msg;
 struct ceph_connection;
 
-extern struct workqueue_struct *ceph_msgr_wq;       /* receive work queue */
-
 /*
  * Ceph defines these callbacks for handling connection events.
  */
@@ -54,7 +52,6 @@ struct ceph_connection_operations {
 struct ceph_messenger {
        struct ceph_entity_inst inst;    /* my name+address */
        struct ceph_entity_addr my_enc_addr;
-       struct page *zero_page;          /* used in certain error cases */
 
        bool nocrc;
 
@@ -101,7 +98,7 @@ struct ceph_msg {
 struct ceph_msg_pos {
        int page, page_pos;  /* which page; offset in page */
        int data_pos;        /* offset in data payload */
-       int did_page_crc;    /* true if we've calculated crc for current page */
+       bool did_page_crc;   /* true if we've calculated crc for current page */
 };
 
 /* ceph connection fault delay defaults, for exponential backoff */
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
new file mode 100644 (file)
index 0000000..5e4312b
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ *  linux/include/linux/clk-private.h
+ *
+ *  Copyright (c) 2010-2011 Jeremy Kerr <jeremy.kerr@canonical.com>
+ *  Copyright (C) 2011-2012 Linaro Ltd <mturquette@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __LINUX_CLK_PRIVATE_H
+#define __LINUX_CLK_PRIVATE_H
+
+#include <linux/clk-provider.h>
+#include <linux/list.h>
+
+/*
+ * WARNING: Do not include clk-private.h from any file that implements struct
+ * clk_ops.  Doing so is a layering violation!
+ *
+ * This header exists only to allow for statically initialized clock data.  Any
+ * static clock data must be defined in a separate file from the logic that
+ * implements the clock operations for that same data.
+ */
+
+#ifdef CONFIG_COMMON_CLK
+
+struct clk {
+       const char              *name;
+       const struct clk_ops    *ops;
+       struct clk_hw           *hw;
+       struct clk              *parent;
+       char                    **parent_names;
+       struct clk              **parents;
+       u8                      num_parents;
+       unsigned long           rate;
+       unsigned long           new_rate;
+       unsigned long           flags;
+       unsigned int            enable_count;
+       unsigned int            prepare_count;
+       struct hlist_head       children;
+       struct hlist_node       child_node;
+       unsigned int            notifier_count;
+#ifdef CONFIG_COMMON_CLK_DEBUG
+       struct dentry           *dentry;
+#endif
+};
+
+/*
+ * DOC: Basic clock implementations common to many platforms
+ *
+ * Each basic clock hardware type is comprised of a structure describing the
+ * clock hardware, implementations of the relevant callbacks in struct clk_ops,
+ * unique flags for that hardware type, a registration function and an
+ * alternative macro for static initialization
+ */
+
+extern struct clk_ops clk_fixed_rate_ops;
+
+#define DEFINE_CLK_FIXED_RATE(_name, _flags, _rate,            \
+                               _fixed_rate_flags)              \
+       static struct clk _name;                                \
+       static char *_name##_parent_names[] = {};               \
+       static struct clk_fixed_rate _name##_hw = {             \
+               .hw = {                                         \
+                       .clk = &_name,                          \
+               },                                              \
+               .fixed_rate = _rate,                            \
+               .flags = _fixed_rate_flags,                     \
+       };                                                      \
+       static struct clk _name = {                             \
+               .name = #_name,                                 \
+               .ops = &clk_fixed_rate_ops,                     \
+               .hw = &_name##_hw.hw,                           \
+               .parent_names = _name##_parent_names,           \
+               .num_parents =                                  \
+                       ARRAY_SIZE(_name##_parent_names),       \
+               .flags = _flags,                                \
+       };
+
+extern struct clk_ops clk_gate_ops;
+
+#define DEFINE_CLK_GATE(_name, _parent_name, _parent_ptr,      \
+                               _flags, _reg, _bit_idx,         \
+                               _gate_flags, _lock)             \
+       static struct clk _name;                                \
+       static char *_name##_parent_names[] = {                 \
+               _parent_name,                                   \
+       };                                                      \
+       static struct clk *_name##_parents[] = {                \
+               _parent_ptr,                                    \
+       };                                                      \
+       static struct clk_gate _name##_hw = {                   \
+               .hw = {                                         \
+                       .clk = &_name,                          \
+               },                                              \
+               .reg = _reg,                                    \
+               .bit_idx = _bit_idx,                            \
+               .flags = _gate_flags,                           \
+               .lock = _lock,                                  \
+       };                                                      \
+       static struct clk _name = {                             \
+               .name = #_name,                                 \
+               .ops = &clk_gate_ops,                           \
+               .hw = &_name##_hw.hw,                           \
+               .parent_names = _name##_parent_names,           \
+               .num_parents =                                  \
+                       ARRAY_SIZE(_name##_parent_names),       \
+               .parents = _name##_parents,                     \
+               .flags = _flags,                                \
+       };
+
+extern struct clk_ops clk_divider_ops;
+
+#define DEFINE_CLK_DIVIDER(_name, _parent_name, _parent_ptr,   \
+                               _flags, _reg, _shift, _width,   \
+                               _divider_flags, _lock)          \
+       static struct clk _name;                                \
+       static char *_name##_parent_names[] = {                 \
+               _parent_name,                                   \
+       };                                                      \
+       static struct clk *_name##_parents[] = {                \
+               _parent_ptr,                                    \
+       };                                                      \
+       static struct clk_divider _name##_hw = {                \
+               .hw = {                                         \
+                       .clk = &_name,                          \
+               },                                              \
+               .reg = _reg,                                    \
+               .shift = _shift,                                \
+               .width = _width,                                \
+               .flags = _divider_flags,                        \
+               .lock = _lock,                                  \
+       };                                                      \
+       static struct clk _name = {                             \
+               .name = #_name,                                 \
+               .ops = &clk_divider_ops,                        \
+               .hw = &_name##_hw.hw,                           \
+               .parent_names = _name##_parent_names,           \
+               .num_parents =                                  \
+                       ARRAY_SIZE(_name##_parent_names),       \
+               .parents = _name##_parents,                     \
+               .flags = _flags,                                \
+       };
+
+extern struct clk_ops clk_mux_ops;
+
+#define DEFINE_CLK_MUX(_name, _parent_names, _parents, _flags, \
+                               _reg, _shift, _width,           \
+                               _mux_flags, _lock)              \
+       static struct clk _name;                                \
+       static struct clk_mux _name##_hw = {                    \
+               .hw = {                                         \
+                       .clk = &_name,                          \
+               },                                              \
+               .reg = _reg,                                    \
+               .shift = _shift,                                \
+               .width = _width,                                \
+               .flags = _mux_flags,                            \
+               .lock = _lock,                                  \
+       };                                                      \
+       static struct clk _name = {                             \
+               .name = #_name,                                 \
+               .ops = &clk_mux_ops,                            \
+               .hw = &_name##_hw.hw,                           \
+               .parent_names = _parent_names,                  \
+               .num_parents =                                  \
+                       ARRAY_SIZE(_parent_names),              \
+               .parents = _parents,                            \
+               .flags = _flags,                                \
+       };
+
+/**
+ * __clk_init - initialize the data structures in a struct clk
+ * @dev:       device initializing this clk, placeholder for now
+ * @clk:       clk being initialized
+ *
+ * Initializes the lists in struct clk, queries the hardware for the
+ * parent and rate and sets them both.
+ *
+ * Any struct clk passed into __clk_init must have the following members
+ * populated:
+ *     .name
+ *     .ops
+ *     .hw
+ *     .parent_names
+ *     .num_parents
+ *     .flags
+ *
+ * It is not necessary to call clk_register if __clk_init is used directly with
+ * statically initialized clock data.
+ */
+void __clk_init(struct device *dev, struct clk *clk);
+
+#endif /* CONFIG_COMMON_CLK */
+#endif /* CLK_PRIVATE_H */
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
new file mode 100644 (file)
index 0000000..5508897
--- /dev/null
@@ -0,0 +1,300 @@
+/*
+ *  linux/include/linux/clk-provider.h
+ *
+ *  Copyright (c) 2010-2011 Jeremy Kerr <jeremy.kerr@canonical.com>
+ *  Copyright (C) 2011-2012 Linaro Ltd <mturquette@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __LINUX_CLK_PROVIDER_H
+#define __LINUX_CLK_PROVIDER_H
+
+#include <linux/clk.h>
+
+#ifdef CONFIG_COMMON_CLK
+
+/**
+ * struct clk_hw - handle for traversing from a struct clk to its corresponding
+ * hardware-specific structure.  struct clk_hw should be declared within struct
+ * clk_foo and then referenced by the struct clk instance that uses struct
+ * clk_foo's clk_ops
+ *
+ * clk: pointer to the struct clk instance that points back to this struct
+ * clk_hw instance
+ */
+struct clk_hw {
+       struct clk *clk;
+};
+
+/*
+ * flags used across common struct clk.  these flags should only affect the
+ * top-level framework.  custom flags for dealing with hardware specifics
+ * belong in struct clk_foo
+ */
+#define CLK_SET_RATE_GATE      BIT(0) /* must be gated across rate change */
+#define CLK_SET_PARENT_GATE    BIT(1) /* must be gated across re-parent */
+#define CLK_SET_RATE_PARENT    BIT(2) /* propagate rate change up one level */
+#define CLK_IGNORE_UNUSED      BIT(3) /* do not gate even if unused */
+#define CLK_IS_ROOT            BIT(4) /* root clk, has no parent */
+
+/**
+ * struct clk_ops -  Callback operations for hardware clocks; these are to
+ * be provided by the clock implementation, and will be called by drivers
+ * through the clk_* api.
+ *
+ * @prepare:   Prepare the clock for enabling. This must not return until
+ *             the clock is fully prepared, and it's safe to call clk_enable.
+ *             This callback is intended to allow clock implementations to
+ *             do any initialisation that may sleep. Called with
+ *             prepare_lock held.
+ *
+ * @unprepare: Release the clock from its prepared state. This will typically
+ *             undo any work done in the @prepare callback. Called with
+ *             prepare_lock held.
+ *
+ * @enable:    Enable the clock atomically. This must not return until the
+ *             clock is generating a valid clock signal, usable by consumer
+ *             devices. Called with enable_lock held. This function must not
+ *             sleep.
+ *
+ * @disable:   Disable the clock atomically. Called with enable_lock held.
+ *             This function must not sleep.
+ *
+ * @recalc_rate        Recalculate the rate of this clock, by quering hardware.  The
+ *             parent rate is an input parameter.  It is up to the caller to
+ *             insure that the prepare_mutex is held across this call.
+ *             Returns the calculated rate.  Optional, but recommended - if
+ *             this op is not set then clock rate will be initialized to 0.
+ *
+ * @round_rate:        Given a target rate as input, returns the closest rate actually
+ *             supported by the clock.
+ *
+ * @get_parent:        Queries the hardware to determine the parent of a clock.  The
+ *             return value is a u8 which specifies the index corresponding to
+ *             the parent clock.  This index can be applied to either the
+ *             .parent_names or .parents arrays.  In short, this function
+ *             translates the parent value read from hardware into an array
+ *             index.  Currently only called when the clock is initialized by
+ *             __clk_init.  This callback is mandatory for clocks with
+ *             multiple parents.  It is optional (and unnecessary) for clocks
+ *             with 0 or 1 parents.
+ *
+ * @set_parent:        Change the input source of this clock; for clocks with multiple
+ *             possible parents specify a new parent by passing in the index
+ *             as a u8 corresponding to the parent in either the .parent_names
+ *             or .parents arrays.  This function in affect translates an
+ *             array index into the value programmed into the hardware.
+ *             Returns 0 on success, -EERROR otherwise.
+ *
+ * @set_rate:  Change the rate of this clock. If this callback returns
+ *             CLK_SET_RATE_PARENT, the rate change will be propagated to the
+ *             parent clock (which may propagate again if the parent clock
+ *             also sets this flag). The requested rate of the parent is
+ *             passed back from the callback in the second 'unsigned long *'
+ *             argument.  Note that it is up to the hardware clock's set_rate
+ *             implementation to insure that clocks do not run out of spec
+ *             when propgating the call to set_rate up to the parent.  One way
+ *             to do this is to gate the clock (via clk_disable and/or
+ *             clk_unprepare) before calling clk_set_rate, then ungating it
+ *             afterward.  If your clock also has the CLK_GATE_SET_RATE flag
+ *             set then this will insure safety.  Returns 0 on success,
+ *             -EERROR otherwise.
+ *
+ * The clk_enable/clk_disable and clk_prepare/clk_unprepare pairs allow
+ * implementations to split any work between atomic (enable) and sleepable
+ * (prepare) contexts.  If enabling a clock requires code that might sleep,
+ * this must be done in clk_prepare.  Clock enable code that will never be
+ * called in a sleepable context may be implement in clk_enable.
+ *
+ * Typically, drivers will call clk_prepare when a clock may be needed later
+ * (eg. when a device is opened), and clk_enable when the clock is actually
+ * required (eg. from an interrupt). Note that clk_prepare MUST have been
+ * called before clk_enable.
+ */
+struct clk_ops {
+       int             (*prepare)(struct clk_hw *hw);
+       void            (*unprepare)(struct clk_hw *hw);
+       int             (*enable)(struct clk_hw *hw);
+       void            (*disable)(struct clk_hw *hw);
+       int             (*is_enabled)(struct clk_hw *hw);
+       unsigned long   (*recalc_rate)(struct clk_hw *hw,
+                                       unsigned long parent_rate);
+       long            (*round_rate)(struct clk_hw *hw, unsigned long,
+                                       unsigned long *);
+       int             (*set_parent)(struct clk_hw *hw, u8 index);
+       u8              (*get_parent)(struct clk_hw *hw);
+       int             (*set_rate)(struct clk_hw *hw, unsigned long);
+       void            (*init)(struct clk_hw *hw);
+};
+
+/*
+ * DOC: Basic clock implementations common to many platforms
+ *
+ * Each basic clock hardware type is comprised of a structure describing the
+ * clock hardware, implementations of the relevant callbacks in struct clk_ops,
+ * unique flags for that hardware type, a registration function and an
+ * alternative macro for static initialization
+ */
+
+/**
+ * struct clk_fixed_rate - fixed-rate clock
+ * @hw:                handle between common and hardware-specific interfaces
+ * @fixed_rate:        constant frequency of clock
+ */
+struct clk_fixed_rate {
+       struct          clk_hw hw;
+       unsigned long   fixed_rate;
+       u8              flags;
+};
+
+struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               unsigned long fixed_rate);
+
+/**
+ * struct clk_gate - gating clock
+ *
+ * @hw:                handle between common and hardware-specific interfaces
+ * @reg:       register controlling gate
+ * @bit_idx:   single bit controlling gate
+ * @flags:     hardware-specific flags
+ * @lock:      register lock
+ *
+ * Clock which can gate its output.  Implements .enable & .disable
+ *
+ * Flags:
+ * CLK_GATE_SET_DISABLE - by default this clock sets the bit at bit_idx to
+ *     enable the clock.  Setting this flag does the opposite: setting the bit
+ *     disable the clock and clearing it enables the clock
+ */
+struct clk_gate {
+       struct clk_hw hw;
+       void __iomem    *reg;
+       u8              bit_idx;
+       u8              flags;
+       spinlock_t      *lock;
+       char            *parent[1];
+};
+
+#define CLK_GATE_SET_TO_DISABLE                BIT(0)
+
+struct clk *clk_register_gate(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               void __iomem *reg, u8 bit_idx,
+               u8 clk_gate_flags, spinlock_t *lock);
+
+/**
+ * struct clk_divider - adjustable divider clock
+ *
+ * @hw:                handle between common and hardware-specific interfaces
+ * @reg:       register containing the divider
+ * @shift:     shift to the divider bit field
+ * @width:     width of the divider bit field
+ * @lock:      register lock
+ *
+ * Clock with an adjustable divider affecting its output frequency.  Implements
+ * .recalc_rate, .set_rate and .round_rate
+ *
+ * Flags:
+ * CLK_DIVIDER_ONE_BASED - by default the divisor is the value read from the
+ *     register plus one.  If CLK_DIVIDER_ONE_BASED is set then the divider is
+ *     the raw value read from the register, with the value of zero considered
+ *     invalid
+ * CLK_DIVIDER_POWER_OF_TWO - clock divisor is 2 raised to the value read from
+ *     the hardware register
+ */
+struct clk_divider {
+       struct clk_hw   hw;
+       void __iomem    *reg;
+       u8              shift;
+       u8              width;
+       u8              flags;
+       spinlock_t      *lock;
+       char            *parent[1];
+};
+
+#define CLK_DIVIDER_ONE_BASED          BIT(0)
+#define CLK_DIVIDER_POWER_OF_TWO       BIT(1)
+
+struct clk *clk_register_divider(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width,
+               u8 clk_divider_flags, spinlock_t *lock);
+
+/**
+ * struct clk_mux - multiplexer clock
+ *
+ * @hw:                handle between common and hardware-specific interfaces
+ * @reg:       register controlling multiplexer
+ * @shift:     shift to multiplexer bit field
+ * @width:     width of mutliplexer bit field
+ * @num_clks:  number of parent clocks
+ * @lock:      register lock
+ *
+ * Clock with multiple selectable parents.  Implements .get_parent, .set_parent
+ * and .recalc_rate
+ *
+ * Flags:
+ * CLK_MUX_INDEX_ONE - register index starts at 1, not 0
+ * CLK_MUX_INDEX_BITWISE - register index is a single bit (power of two)
+ */
+struct clk_mux {
+       struct clk_hw   hw;
+       void __iomem    *reg;
+       u8              shift;
+       u8              width;
+       u8              flags;
+       spinlock_t      *lock;
+};
+
+#define CLK_MUX_INDEX_ONE              BIT(0)
+#define CLK_MUX_INDEX_BIT              BIT(1)
+
+struct clk *clk_register_mux(struct device *dev, const char *name,
+               char **parent_names, u8 num_parents, unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width,
+               u8 clk_mux_flags, spinlock_t *lock);
+
+/**
+ * clk_register - allocate a new clock, register it and return an opaque cookie
+ * @dev: device that is registering this clock
+ * @name: clock name
+ * @ops: operations this clock supports
+ * @hw: link to hardware-specific clock data
+ * @parent_names: array of string names for all possible parents
+ * @num_parents: number of possible parents
+ * @flags: framework-level hints and quirks
+ *
+ * clk_register is the primary interface for populating the clock tree with new
+ * clock nodes.  It returns a pointer to the newly allocated struct clk which
+ * cannot be dereferenced by driver code but may be used in conjuction with the
+ * rest of the clock API.
+ */
+struct clk *clk_register(struct device *dev, const char *name,
+               const struct clk_ops *ops, struct clk_hw *hw,
+               char **parent_names, u8 num_parents, unsigned long flags);
+
+/* helper functions */
+const char *__clk_get_name(struct clk *clk);
+struct clk_hw *__clk_get_hw(struct clk *clk);
+u8 __clk_get_num_parents(struct clk *clk);
+struct clk *__clk_get_parent(struct clk *clk);
+inline int __clk_get_enable_count(struct clk *clk);
+inline int __clk_get_prepare_count(struct clk *clk);
+unsigned long __clk_get_rate(struct clk *clk);
+unsigned long __clk_get_flags(struct clk *clk);
+int __clk_is_enabled(struct clk *clk);
+struct clk *__clk_lookup(const char *name);
+
+/*
+ * FIXME clock api without lock protection
+ */
+int __clk_prepare(struct clk *clk);
+void __clk_unprepare(struct clk *clk);
+void __clk_reparent(struct clk *clk, struct clk *new_parent);
+unsigned long __clk_round_rate(struct clk *clk, unsigned long rate);
+
+#endif /* CONFIG_COMMON_CLK */
+#endif /* CLK_PROVIDER_H */
index b9d46fa154b40f065449b901ae5982503e1e4430..b0252726df6106991bdaa7fae7146bc6ea4b6633 100644 (file)
@@ -3,6 +3,7 @@
  *
  *  Copyright (C) 2004 ARM Limited.
  *  Written by Deep Blue Solutions Limited.
+ *  Copyright (C) 2011-2012 Linaro Ltd <mturquette@linaro.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
 #define __LINUX_CLK_H
 
 #include <linux/kernel.h>
+#include <linux/notifier.h>
 
 struct device;
 
-/*
- * The base API.
+struct clk;
+
+#ifdef CONFIG_COMMON_CLK
+
+/**
+ * DOC: clk notifier callback types
+ *
+ * PRE_RATE_CHANGE - called immediately before the clk rate is changed,
+ *     to indicate that the rate change will proceed.  Drivers must
+ *     immediately terminate any operations that will be affected by the
+ *     rate change.  Callbacks may either return NOTIFY_DONE or
+ *     NOTIFY_STOP.
+ *
+ * ABORT_RATE_CHANGE: called if the rate change failed for some reason
+ *     after PRE_RATE_CHANGE.  In this case, all registered notifiers on
+ *     the clk will be called with ABORT_RATE_CHANGE. Callbacks must
+ *     always return NOTIFY_DONE.
+ *
+ * POST_RATE_CHANGE - called after the clk rate change has successfully
+ *     completed.  Callbacks must always return NOTIFY_DONE.
+ *
  */
+#define PRE_RATE_CHANGE                        BIT(0)
+#define POST_RATE_CHANGE               BIT(1)
+#define ABORT_RATE_CHANGE              BIT(2)
 
+/**
+ * struct clk_notifier - associate a clk with a notifier
+ * @clk: struct clk * to associate the notifier with
+ * @notifier_head: a blocking_notifier_head for this clk
+ * @node: linked list pointers
+ *
+ * A list of struct clk_notifier is maintained by the notifier code.
+ * An entry is created whenever code registers the first notifier on a
+ * particular @clk.  Future notifiers on that @clk are added to the
+ * @notifier_head.
+ */
+struct clk_notifier {
+       struct clk                      *clk;
+       struct srcu_notifier_head       notifier_head;
+       struct list_head                node;
+};
 
-/*
- * struct clk - an machine class defined object / cookie.
+/**
+ * struct clk_notifier_data - rate data to pass to the notifier callback
+ * @clk: struct clk * being changed
+ * @old_rate: previous rate of this clk
+ * @new_rate: new rate of this clk
+ *
+ * For a pre-notifier, old_rate is the clk's rate before this rate
+ * change, and new_rate is what the rate will be in the future.  For a
+ * post-notifier, old_rate and new_rate are both set to the clk's
+ * current rate (this was done to optimize the implementation).
  */
-struct clk;
+struct clk_notifier_data {
+       struct clk              *clk;
+       unsigned long           old_rate;
+       unsigned long           new_rate;
+};
+
+int clk_notifier_register(struct clk *clk, struct notifier_block *nb);
+
+int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb);
+
+#endif /* !CONFIG_COMMON_CLK */
 
 /**
  * clk_get - lookup and obtain a reference to a clock producer.
index fa63f1b46103eceba8a380851c30500f30978c65..c437f914d537746d5c856d506ef5ee6b4e520f0b 100644 (file)
@@ -1872,19 +1872,6 @@ extern struct dentry *mount_pseudo(struct file_system_type *, char *,
        const struct dentry_operations *dops,
        unsigned long);
 
-static inline void sb_mark_dirty(struct super_block *sb)
-{
-       sb->s_dirt = 1;
-}
-static inline void sb_mark_clean(struct super_block *sb)
-{
-       sb->s_dirt = 0;
-}
-static inline int sb_is_dirty(struct super_block *sb)
-{
-       return sb->s_dirt;
-}
-
 /* Alas, no aliases. Too much hassle with bringing module.h everywhere */
 #define fops_get(fops) \
        (((fops) && try_module_get((fops)->owner) ? (fops) : NULL))
index 5557baefed60b5f5bb3dd0984bbbe7f2e0a4c8fc..912c30a8ddb1e47cd732fbd95f281238ca601ae0 100644 (file)
@@ -971,6 +971,10 @@ extern void __journal_clean_data_list(transaction_t *transaction);
 /* Log buffer allocation */
 extern struct journal_head * jbd2_journal_get_descriptor_buffer(journal_t *);
 int jbd2_journal_next_log_block(journal_t *, unsigned long long *);
+int jbd2_journal_get_log_tail(journal_t *journal, tid_t *tid,
+                             unsigned long *block);
+void __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block);
+void jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block);
 
 /* Commit management */
 extern void jbd2_journal_commit_transaction(journal_t *);
@@ -1020,6 +1024,11 @@ jbd2_journal_write_metadata_buffer(transaction_t   *transaction,
 /* Transaction locking */
 extern void            __wait_on_journal (journal_t *);
 
+/* Transaction cache support */
+extern void jbd2_journal_destroy_transaction_cache(void);
+extern int  jbd2_journal_init_transaction_cache(void);
+extern void jbd2_journal_free_transaction(transaction_t *);
+
 /*
  * Journal locking.
  *
@@ -1082,7 +1091,8 @@ extern int           jbd2_journal_destroy    (journal_t *);
 extern int        jbd2_journal_recover    (journal_t *journal);
 extern int        jbd2_journal_wipe       (journal_t *, int);
 extern int        jbd2_journal_skip_recovery   (journal_t *);
-extern void       jbd2_journal_update_superblock       (journal_t *, int);
+extern void       jbd2_journal_update_sb_log_tail      (journal_t *, tid_t,
+                               unsigned long, int);
 extern void       __jbd2_journal_abort_hard    (journal_t *);
 extern void       jbd2_journal_abort      (journal_t *, int);
 extern int        jbd2_journal_errno      (journal_t *);
index 423cb6d78ee0bc9958d63a592f53c7d5a17fa874..c18b46f8aeebbfb4a85f8b750dad108c0124eaf6 100644 (file)
@@ -66,6 +66,8 @@ struct journal_head {
         * transaction (if there is one).  Only applies to buffers on a
         * transaction's data or metadata journaling list.
         * [j_list_lock] [jbd_lock_bh_state()]
+        * Either of these locks is enough for reading, both are needed for
+        * changes.
         */
        transaction_t *b_transaction;
 
index f88c1cc0cb0f24bfda24e69f63cb728a923d5d45..a9e8bd157673a475ebfb5d78e81f0b8d6d621ed6 100644 (file)
@@ -10,8 +10,6 @@
 #ifndef MCP_H
 #define MCP_H
 
-#include <mach/dma.h>
-
 struct mcp_ops;
 
 struct mcp {
@@ -21,12 +19,7 @@ struct mcp {
        int             use_count;
        unsigned int    sclk_rate;
        unsigned int    rw_timeout;
-       dma_device_t    dma_audio_rd;
-       dma_device_t    dma_audio_wr;
-       dma_device_t    dma_telco_rd;
-       dma_device_t    dma_telco_wr;
        struct device   attached_device;
-       int             gpio_base;
 };
 
 struct mcp_ops {
@@ -47,15 +40,14 @@ void mcp_disable(struct mcp *);
 #define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate)
 
 struct mcp *mcp_host_alloc(struct device *, size_t);
-int mcp_host_register(struct mcp *);
-void mcp_host_unregister(struct mcp *);
+int mcp_host_add(struct mcp *, void *);
+void mcp_host_del(struct mcp *);
+void mcp_host_free(struct mcp *);
 
 struct mcp_driver {
        struct device_driver drv;
        int (*probe)(struct mcp *);
        void (*remove)(struct mcp *);
-       int (*suspend)(struct mcp *, pm_message_t);
-       int (*resume)(struct mcp *);
 };
 
 int mcp_driver_register(struct mcp_driver *);
index 4321f044d1e45e1ad5cdaf20eba1440427b1fb5e..28af417563609b50bbff851bea7e0fb4692c966d 100644 (file)
@@ -12,7 +12,7 @@
 
 #include <linux/mfd/mcp.h>
 #include <linux/gpio.h>
-#include <linux/semaphore.h>
+#include <linux/mutex.h>
 
 #define UCB_IO_DATA    0x00
 #define UCB_IO_DIR     0x01
 #define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
 #define UCB_MODE_AUD_OFF_CAN   (1 << 13)
 
+enum ucb1x00_reset {
+       UCB_RST_PROBE,
+       UCB_RST_RESUME,
+       UCB_RST_SUSPEND,
+       UCB_RST_REMOVE,
+       UCB_RST_PROBE_FAIL,
+};
 
-struct ucb1x00_irq {
-       void *devid;
-       void (*fn)(int, void *);
+struct ucb1x00_plat_data {
+       void                    (*reset)(enum ucb1x00_reset);
+       unsigned                irq_base;
+       int                     gpio_base;
+       unsigned                can_wakeup;
 };
 
 struct ucb1x00 {
-       spinlock_t              lock;
+       raw_spinlock_t          irq_lock;
        struct mcp              *mcp;
        unsigned int            irq;
-       struct semaphore        adc_sem;
+       int                     irq_base;
+       struct mutex            adc_mutex;
        spinlock_t              io_lock;
        u16                     id;
        u16                     io_dir;
@@ -122,7 +132,8 @@ struct ucb1x00 {
        u16                     adc_cr;
        u16                     irq_fal_enbl;
        u16                     irq_ris_enbl;
-       struct ucb1x00_irq      irq_handler[16];
+       u16                     irq_mask;
+       u16                     irq_wake;
        struct device           dev;
        struct list_head        node;
        struct list_head        devs;
@@ -144,7 +155,7 @@ struct ucb1x00_driver {
        struct list_head        devs;
        int     (*add)(struct ucb1x00_dev *dev);
        void    (*remove)(struct ucb1x00_dev *dev);
-       int     (*suspend)(struct ucb1x00_dev *dev, pm_message_t state);
+       int     (*suspend)(struct ucb1x00_dev *dev);
        int     (*resume)(struct ucb1x00_dev *dev);
 };
 
@@ -245,15 +256,4 @@ unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync);
 void ucb1x00_adc_enable(struct ucb1x00 *ucb);
 void ucb1x00_adc_disable(struct ucb1x00 *ucb);
 
-/*
- * Which edges of the IRQ do you want to control today?
- */
-#define UCB_RISING     (1 << 0)
-#define UCB_FALLING    (1 << 1)
-
-int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid);
-void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
-void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
-int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid);
-
 #endif
index fb69ad191ad743701b56663796394644ff102df5..501da4cb8a6de02ecd0dbe8b6759c26b298d2c12 100644 (file)
@@ -414,6 +414,15 @@ struct hv_vmbus_device_id {
                        __attribute__((aligned(sizeof(kernel_ulong_t))));
 };
 
+/* rpmsg */
+
+#define RPMSG_NAME_SIZE                        32
+#define RPMSG_DEVICE_MODALIAS_FMT      "rpmsg:%s"
+
+struct rpmsg_device_id {
+       char name[RPMSG_NAME_SIZE];
+};
+
 /* i2c */
 
 #define I2C_NAME_SIZE  20
index d46a18ffbebbb6ca2cdd78344289627e99b76a78..ba5d8494f2e1835277a794706b6a6519805a7ca3 100644 (file)
@@ -361,6 +361,22 @@ static inline int of_machine_is_compatible(const char *compat)
 #define of_match_node(_matches, _node) NULL
 #endif /* CONFIG_OF */
 
+/**
+ * of_property_read_bool - Findfrom a property
+ * @np:                device node from which the property value is to be read.
+ * @propname:  name of the property to be searched.
+ *
+ * Search for a property in a device node.
+ * Returns true if the property exist false otherwise.
+ */
+static inline bool of_property_read_bool(const struct device_node *np,
+                                        const char *propname)
+{
+       struct property *prop = of_find_property(np, propname, NULL);
+
+       return prop ? true : false;
+}
+
 static inline int of_property_read_u32(const struct device_node *np,
                                       const char *propname,
                                       u32 *out_value)
diff --git a/include/linux/of_mtd.h b/include/linux/of_mtd.h
new file mode 100644 (file)
index 0000000..bae1b60
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * OF helpers for mtd.
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __LINUX_OF_MTD_H
+#define __LINUX_OF_NET_H
+
+#ifdef CONFIG_OF_MTD
+#include <linux/of.h>
+extern const int of_get_nand_ecc_mode(struct device_node *np);
+int of_get_nand_bus_width(struct device_node *np);
+bool of_get_nand_on_flash_bbt(struct device_node *np);
+#endif
+
+#endif /* __LINUX_OF_MTD_H */
diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h
new file mode 100644 (file)
index 0000000..d056263
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * atmel platform data
+ *
+ * GPL v2 Only
+ */
+
+#ifndef __ATMEL_NAND_H__
+#define __ATMEL_NAND_H__
+
+#include <linux/mtd/nand.h>
+
+ /* NAND / SmartMedia */
+struct atmel_nand_data {
+       int             enable_pin;             /* chip enable */
+       int             det_pin;                /* card detect */
+       int             rdy_pin;                /* ready/busy */
+       u8              rdy_pin_active_low;     /* rdy_pin value is inverted */
+       u8              ale;                    /* address line number connected to ALE */
+       u8              cle;                    /* address line number connected to CLE */
+       u8              bus_width_16;           /* buswidth is 16 bit */
+       u8              ecc_mode;               /* ecc mode */
+       u8              on_flash_bbt;           /* bbt on flash */
+       struct mtd_partition *parts;
+       unsigned int    num_parts;
+};
+
+#endif /* __ATMEL_NAND_H__ */
diff --git a/include/linux/platform_data/tegra_emc.h b/include/linux/platform_data/tegra_emc.h
new file mode 100644 (file)
index 0000000..df67505
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Author:
+ *     Colin Cross <ccross@android.com>
+ *     Olof Johansson <olof@lixom.net>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __TEGRA_EMC_H_
+#define __TEGRA_EMC_H_
+
+#define TEGRA_EMC_NUM_REGS 46
+
+struct tegra_emc_table {
+       unsigned long rate;
+       u32 regs[TEGRA_EMC_NUM_REGS];
+};
+
+struct tegra_emc_pdata {
+       int num_tables;
+       struct tegra_emc_table *tables;
+};
+
+#endif
diff --git a/include/linux/regulator/bq24022.h b/include/linux/regulator/bq24022.h
deleted file mode 100644 (file)
index a6d0140..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Support for TI bq24022 (bqTINY-II) Dual Input (USB/AC Adpater)
- * 1-Cell Li-Ion Charger connected via GPIOs.
- *
- * Copyright (c) 2008 Philipp Zabel
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-struct regulator_init_data;
-
-/**
- * bq24022_mach_info - platform data for bq24022
- * @gpio_nce: GPIO line connected to the nCE pin, used to enable / disable charging
- * @gpio_iset2: GPIO line connected to the ISET2 pin, used to limit charging current to 100 mA / 500 mA
- */
-struct bq24022_mach_info {
-       int gpio_nce;
-       int gpio_iset2;
-       struct regulator_init_data *init_data;
-};
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
new file mode 100644 (file)
index 0000000..f1ffabb
--- /dev/null
@@ -0,0 +1,478 @@
+/*
+ * Remote Processor Framework
+ *
+ * Copyright(c) 2011 Texas Instruments, Inc.
+ * Copyright(c) 2011 Google, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name Texas Instruments nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef REMOTEPROC_H
+#define REMOTEPROC_H
+
+#include <linux/types.h>
+#include <linux/kref.h>
+#include <linux/klist.h>
+#include <linux/mutex.h>
+#include <linux/virtio.h>
+#include <linux/completion.h>
+#include <linux/idr.h>
+
+/**
+ * struct resource_table - firmware resource table header
+ * @ver: version number
+ * @num: number of resource entries
+ * @reserved: reserved (must be zero)
+ * @offset: array of offsets pointing at the various resource entries
+ *
+ * A resource table is essentially a list of system resources required
+ * by the remote processor. It may also include configuration entries.
+ * If needed, the remote processor firmware should contain this table
+ * as a dedicated ".resource_table" ELF section.
+ *
+ * Some resources entries are mere announcements, where the host is informed
+ * of specific remoteproc configuration. Other entries require the host to
+ * do something (e.g. allocate a system resource). Sometimes a negotiation
+ * is expected, where the firmware requests a resource, and once allocated,
+ * the host should provide back its details (e.g. address of an allocated
+ * memory region).
+ *
+ * The header of the resource table, as expressed by this structure,
+ * contains a version number (should we need to change this format in the
+ * future), the number of available resource entries, and their offsets
+ * in the table.
+ *
+ * Immediately following this header are the resource entries themselves,
+ * each of which begins with a resource entry header (as described below).
+ */
+struct resource_table {
+       u32 ver;
+       u32 num;
+       u32 reserved[2];
+       u32 offset[0];
+} __packed;
+
+/**
+ * struct fw_rsc_hdr - firmware resource entry header
+ * @type: resource type
+ * @data: resource data
+ *
+ * Every resource entry begins with a 'struct fw_rsc_hdr' header providing
+ * its @type. The content of the entry itself will immediately follow
+ * this header, and it should be parsed according to the resource type.
+ */
+struct fw_rsc_hdr {
+       u32 type;
+       u8 data[0];
+} __packed;
+
+/**
+ * enum fw_resource_type - types of resource entries
+ *
+ * @RSC_CARVEOUT:   request for allocation of a physically contiguous
+ *                 memory region.
+ * @RSC_DEVMEM:     request to iommu_map a memory-based peripheral.
+ * @RSC_TRACE:     announces the availability of a trace buffer into which
+ *                 the remote processor will be writing logs.
+ * @RSC_VDEV:       declare support for a virtio device, and serve as its
+ *                 virtio header.
+ * @RSC_LAST:       just keep this one at the end
+ *
+ * For more details regarding a specific resource type, please see its
+ * dedicated structure below.
+ *
+ * Please note that these values are used as indices to the rproc_handle_rsc
+ * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
+ * check the validity of an index before the lookup table is accessed, so
+ * please update it as needed.
+ */
+enum fw_resource_type {
+       RSC_CARVEOUT    = 0,
+       RSC_DEVMEM      = 1,
+       RSC_TRACE       = 2,
+       RSC_VDEV        = 3,
+       RSC_LAST        = 4,
+};
+
+#define FW_RSC_ADDR_ANY (0xFFFFFFFFFFFFFFFF)
+
+/**
+ * struct fw_rsc_carveout - physically contiguous memory request
+ * @da: device address
+ * @pa: physical address
+ * @len: length (in bytes)
+ * @flags: iommu protection flags
+ * @reserved: reserved (must be zero)
+ * @name: human-readable name of the requested memory region
+ *
+ * This resource entry requests the host to allocate a physically contiguous
+ * memory region.
+ *
+ * These request entries should precede other firmware resource entries,
+ * as other entries might request placing other data objects inside
+ * these memory regions (e.g. data/code segments, trace resource entries, ...).
+ *
+ * Allocating memory this way helps utilizing the reserved physical memory
+ * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
+ * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
+ * pressure is important; it may have a substantial impact on performance.
+ *
+ * If the firmware is compiled with static addresses, then @da should specify
+ * the expected device address of this memory region. If @da is set to
+ * FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then
+ * overwrite @da with the dynamically allocated address.
+ *
+ * We will always use @da to negotiate the device addresses, even if it
+ * isn't using an iommu. In that case, though, it will obviously contain
+ * physical addresses.
+ *
+ * Some remote processors needs to know the allocated physical address
+ * even if they do use an iommu. This is needed, e.g., if they control
+ * hardware accelerators which access the physical memory directly (this
+ * is the case with OMAP4 for instance). In that case, the host will
+ * overwrite @pa with the dynamically allocated physical address.
+ * Generally we don't want to expose physical addresses if we don't have to
+ * (remote processors are generally _not_ trusted), so we might want to
+ * change this to happen _only_ when explicitly required by the hardware.
+ *
+ * @flags is used to provide IOMMU protection flags, and @name should
+ * (optionally) contain a human readable name of this carveout region
+ * (mainly for debugging purposes).
+ */
+struct fw_rsc_carveout {
+       u32 da;
+       u32 pa;
+       u32 len;
+       u32 flags;
+       u32 reserved;
+       u8 name[32];
+} __packed;
+
+/**
+ * struct fw_rsc_devmem - iommu mapping request
+ * @da: device address
+ * @pa: physical address
+ * @len: length (in bytes)
+ * @flags: iommu protection flags
+ * @reserved: reserved (must be zero)
+ * @name: human-readable name of the requested region to be mapped
+ *
+ * This resource entry requests the host to iommu map a physically contiguous
+ * memory region. This is needed in case the remote processor requires
+ * access to certain memory-based peripherals; _never_ use it to access
+ * regular memory.
+ *
+ * This is obviously only needed if the remote processor is accessing memory
+ * via an iommu.
+ *
+ * @da should specify the required device address, @pa should specify
+ * the physical address we want to map, @len should specify the size of
+ * the mapping and @flags is the IOMMU protection flags. As always, @name may
+ * (optionally) contain a human readable name of this mapping (mainly for
+ * debugging purposes).
+ *
+ * Note: at this point we just "trust" those devmem entries to contain valid
+ * physical addresses, but this isn't safe and will be changed: eventually we
+ * want remoteproc implementations to provide us ranges of physical addresses
+ * the firmware is allowed to request, and not allow firmwares to request
+ * access to physical addresses that are outside those ranges.
+ */
+struct fw_rsc_devmem {
+       u32 da;
+       u32 pa;
+       u32 len;
+       u32 flags;
+       u32 reserved;
+       u8 name[32];
+} __packed;
+
+/**
+ * struct fw_rsc_trace - trace buffer declaration
+ * @da: device address
+ * @len: length (in bytes)
+ * @reserved: reserved (must be zero)
+ * @name: human-readable name of the trace buffer
+ *
+ * This resource entry provides the host information about a trace buffer
+ * into which the remote processor will write log messages.
+ *
+ * @da specifies the device address of the buffer, @len specifies
+ * its size, and @name may contain a human readable name of the trace buffer.
+ *
+ * After booting the remote processor, the trace buffers are exposed to the
+ * user via debugfs entries (called trace0, trace1, etc..).
+ */
+struct fw_rsc_trace {
+       u32 da;
+       u32 len;
+       u32 reserved;
+       u8 name[32];
+} __packed;
+
+/**
+ * struct fw_rsc_vdev_vring - vring descriptor entry
+ * @da: device address
+ * @align: the alignment between the consumer and producer parts of the vring
+ * @num: num of buffers supported by this vring (must be power of two)
+ * @notifyid is a unique rproc-wide notify index for this vring. This notify
+ * index is used when kicking a remote processor, to let it know that this
+ * vring is triggered.
+ * @reserved: reserved (must be zero)
+ *
+ * This descriptor is not a resource entry by itself; it is part of the
+ * vdev resource type (see below).
+ *
+ * Note that @da should either contain the device address where
+ * the remote processor is expecting the vring, or indicate that
+ * dynamically allocation of the vring's device address is supported.
+ */
+struct fw_rsc_vdev_vring {
+       u32 da;
+       u32 align;
+       u32 num;
+       u32 notifyid;
+       u32 reserved;
+} __packed;
+
+/**
+ * struct fw_rsc_vdev - virtio device header
+ * @id: virtio device id (as in virtio_ids.h)
+ * @notifyid is a unique rproc-wide notify index for this vdev. This notify
+ * index is used when kicking a remote processor, to let it know that the
+ * status/features of this vdev have changes.
+ * @dfeatures specifies the virtio device features supported by the firmware
+ * @gfeatures is a place holder used by the host to write back the
+ * negotiated features that are supported by both sides.
+ * @config_len is the size of the virtio config space of this vdev. The config
+ * space lies in the resource table immediate after this vdev header.
+ * @status is a place holder where the host will indicate its virtio progress.
+ * @num_of_vrings indicates how many vrings are described in this vdev header
+ * @reserved: reserved (must be zero)
+ * @vring is an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'.
+ *
+ * This resource is a virtio device header: it provides information about
+ * the vdev, and is then used by the host and its peer remote processors
+ * to negotiate and share certain virtio properties.
+ *
+ * By providing this resource entry, the firmware essentially asks remoteproc
+ * to statically allocate a vdev upon registration of the rproc (dynamic vdev
+ * allocation is not yet supported).
+ *
+ * Note: unlike virtualization systems, the term 'host' here means
+ * the Linux side which is running remoteproc to control the remote
+ * processors. We use the name 'gfeatures' to comply with virtio's terms,
+ * though there isn't really any virtualized guest OS here: it's the host
+ * which is responsible for negotiating the final features.
+ * Yeah, it's a bit confusing.
+ *
+ * Note: immediately following this structure is the virtio config space for
+ * this vdev (which is specific to the vdev; for more info, read the virtio
+ * spec). the size of the config space is specified by @config_len.
+ */
+struct fw_rsc_vdev {
+       u32 id;
+       u32 notifyid;
+       u32 dfeatures;
+       u32 gfeatures;
+       u32 config_len;
+       u8 status;
+       u8 num_of_vrings;
+       u8 reserved[2];
+       struct fw_rsc_vdev_vring vring[0];
+} __packed;
+
+/**
+ * struct rproc_mem_entry - memory entry descriptor
+ * @va:        virtual address
+ * @dma: dma address
+ * @len: length, in bytes
+ * @da: device address
+ * @priv: associated data
+ * @node: list node
+ */
+struct rproc_mem_entry {
+       void *va;
+       dma_addr_t dma;
+       int len;
+       u32 da;
+       void *priv;
+       struct list_head node;
+};
+
+struct rproc;
+
+/**
+ * struct rproc_ops - platform-specific device handlers
+ * @start:     power on the device and boot it
+ * @stop:      power off the device
+ * @kick:      kick a virtqueue (virtqueue id given as a parameter)
+ */
+struct rproc_ops {
+       int (*start)(struct rproc *rproc);
+       int (*stop)(struct rproc *rproc);
+       void (*kick)(struct rproc *rproc, int vqid);
+};
+
+/**
+ * enum rproc_state - remote processor states
+ * @RPROC_OFFLINE:     device is powered off
+ * @RPROC_SUSPENDED:   device is suspended; needs to be woken up to receive
+ *                     a message.
+ * @RPROC_RUNNING:     device is up and running
+ * @RPROC_CRASHED:     device has crashed; need to start recovery
+ * @RPROC_LAST:                just keep this one at the end
+ *
+ * Please note that the values of these states are used as indices
+ * to rproc_state_string, a state-to-name lookup table,
+ * so please keep the two synchronized. @RPROC_LAST is used to check
+ * the validity of an index before the lookup table is accessed, so
+ * please update it as needed too.
+ */
+enum rproc_state {
+       RPROC_OFFLINE   = 0,
+       RPROC_SUSPENDED = 1,
+       RPROC_RUNNING   = 2,
+       RPROC_CRASHED   = 3,
+       RPROC_LAST      = 4,
+};
+
+/**
+ * struct rproc - represents a physical remote processor device
+ * @node: klist node of this rproc object
+ * @domain: iommu domain
+ * @name: human readable name of the rproc
+ * @firmware: name of firmware file to be loaded
+ * @priv: private data which belongs to the platform-specific rproc module
+ * @ops: platform-specific start/stop rproc handlers
+ * @dev: underlying device
+ * @refcount: refcount of users that have a valid pointer to this rproc
+ * @power: refcount of users who need this rproc powered up
+ * @state: state of the device
+ * @lock: lock which protects concurrent manipulations of the rproc
+ * @dbg_dir: debugfs directory of this rproc device
+ * @traces: list of trace buffers
+ * @num_traces: number of trace buffers
+ * @carveouts: list of physically contiguous memory allocations
+ * @mappings: list of iommu mappings we initiated, needed on shutdown
+ * @firmware_loading_complete: marks e/o asynchronous firmware loading
+ * @bootaddr: address of first instruction to boot rproc with (optional)
+ * @rvdevs: list of remote virtio devices
+ * @notifyids: idr for dynamically assigning rproc-wide unique notify ids
+ */
+struct rproc {
+       struct klist_node node;
+       struct iommu_domain *domain;
+       const char *name;
+       const char *firmware;
+       void *priv;
+       const struct rproc_ops *ops;
+       struct device *dev;
+       struct kref refcount;
+       atomic_t power;
+       unsigned int state;
+       struct mutex lock;
+       struct dentry *dbg_dir;
+       struct list_head traces;
+       int num_traces;
+       struct list_head carveouts;
+       struct list_head mappings;
+       struct completion firmware_loading_complete;
+       u32 bootaddr;
+       struct list_head rvdevs;
+       struct idr notifyids;
+};
+
+/* we currently support only two vrings per rvdev */
+#define RVDEV_NUM_VRINGS 2
+
+/**
+ * struct rproc_vring - remoteproc vring state
+ * @va:        virtual address
+ * @dma: dma address
+ * @len: length, in bytes
+ * @da: device address
+ * @align: vring alignment
+ * @notifyid: rproc-specific unique vring index
+ * @rvdev: remote vdev
+ * @vq: the virtqueue of this vring
+ */
+struct rproc_vring {
+       void *va;
+       dma_addr_t dma;
+       int len;
+       u32 da;
+       u32 align;
+       int notifyid;
+       struct rproc_vdev *rvdev;
+       struct virtqueue *vq;
+};
+
+/**
+ * struct rproc_vdev - remoteproc state for a supported virtio device
+ * @node: list node
+ * @rproc: the rproc handle
+ * @vdev: the virio device
+ * @vring: the vrings for this vdev
+ * @dfeatures: virtio device features
+ * @gfeatures: virtio guest features
+ */
+struct rproc_vdev {
+       struct list_head node;
+       struct rproc *rproc;
+       struct virtio_device vdev;
+       struct rproc_vring vring[RVDEV_NUM_VRINGS];
+       unsigned long dfeatures;
+       unsigned long gfeatures;
+};
+
+struct rproc *rproc_get_by_name(const char *name);
+void rproc_put(struct rproc *rproc);
+
+struct rproc *rproc_alloc(struct device *dev, const char *name,
+                               const struct rproc_ops *ops,
+                               const char *firmware, int len);
+void rproc_free(struct rproc *rproc);
+int rproc_register(struct rproc *rproc);
+int rproc_unregister(struct rproc *rproc);
+
+int rproc_boot(struct rproc *rproc);
+void rproc_shutdown(struct rproc *rproc);
+
+static inline struct rproc_vdev *vdev_to_rvdev(struct virtio_device *vdev)
+{
+       return container_of(vdev, struct rproc_vdev, vdev);
+}
+
+static inline struct rproc *vdev_to_rproc(struct virtio_device *vdev)
+{
+       struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
+
+       return rvdev->rproc;
+}
+
+#endif /* REMOTEPROC_H */
diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h
new file mode 100644 (file)
index 0000000..a8e50e4
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+ * Remote processor messaging
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name Texas Instruments nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINUX_RPMSG_H
+#define _LINUX_RPMSG_H
+
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+
+/* The feature bitmap for virtio rpmsg */
+#define VIRTIO_RPMSG_F_NS      0 /* RP supports name service notifications */
+
+/**
+ * struct rpmsg_hdr - common header for all rpmsg messages
+ * @src: source address
+ * @dst: destination address
+ * @reserved: reserved for future use
+ * @len: length of payload (in bytes)
+ * @flags: message flags
+ * @data: @len bytes of message payload data
+ *
+ * Every message sent(/received) on the rpmsg bus begins with this header.
+ */
+struct rpmsg_hdr {
+       u32 src;
+       u32 dst;
+       u32 reserved;
+       u16 len;
+       u16 flags;
+       u8 data[0];
+} __packed;
+
+/**
+ * struct rpmsg_ns_msg - dynamic name service announcement message
+ * @name: name of remote service that is published
+ * @addr: address of remote service that is published
+ * @flags: indicates whether service is created or destroyed
+ *
+ * This message is sent across to publish a new service, or announce
+ * about its removal. When we receive these messages, an appropriate
+ * rpmsg channel (i.e device) is created/destroyed. In turn, the ->probe()
+ * or ->remove() handler of the appropriate rpmsg driver will be invoked
+ * (if/as-soon-as one is registered).
+ */
+struct rpmsg_ns_msg {
+       char name[RPMSG_NAME_SIZE];
+       u32 addr;
+       u32 flags;
+} __packed;
+
+/**
+ * enum rpmsg_ns_flags - dynamic name service announcement flags
+ *
+ * @RPMSG_NS_CREATE: a new remote service was just created
+ * @RPMSG_NS_DESTROY: a known remote service was just destroyed
+ */
+enum rpmsg_ns_flags {
+       RPMSG_NS_CREATE         = 0,
+       RPMSG_NS_DESTROY        = 1,
+};
+
+#define RPMSG_ADDR_ANY         0xFFFFFFFF
+
+struct virtproc_info;
+
+/**
+ * rpmsg_channel - devices that belong to the rpmsg bus are called channels
+ * @vrp: the remote processor this channel belongs to
+ * @dev: the device struct
+ * @id: device id (used to match between rpmsg drivers and devices)
+ * @src: local address
+ * @dst: destination address
+ * @ept: the rpmsg endpoint of this channel
+ * @announce: if set, rpmsg will announce the creation/removal of this channel
+ */
+struct rpmsg_channel {
+       struct virtproc_info *vrp;
+       struct device dev;
+       struct rpmsg_device_id id;
+       u32 src;
+       u32 dst;
+       struct rpmsg_endpoint *ept;
+       bool announce;
+};
+
+typedef void (*rpmsg_rx_cb_t)(struct rpmsg_channel *, void *, int, void *, u32);
+
+/**
+ * struct rpmsg_endpoint - binds a local rpmsg address to its user
+ * @rpdev: rpmsg channel device
+ * @cb: rx callback handler
+ * @addr: local rpmsg address
+ * @priv: private data for the driver's use
+ *
+ * In essence, an rpmsg endpoint represents a listener on the rpmsg bus, as
+ * it binds an rpmsg address with an rx callback handler.
+ *
+ * Simple rpmsg drivers shouldn't use this struct directly, because
+ * things just work: every rpmsg driver provides an rx callback upon
+ * registering to the bus, and that callback is then bound to its rpmsg
+ * address when the driver is probed. When relevant inbound messages arrive
+ * (i.e. messages which their dst address equals to the src address of
+ * the rpmsg channel), the driver's handler is invoked to process it.
+ *
+ * More complicated drivers though, that do need to allocate additional rpmsg
+ * addresses, and bind them to different rx callbacks, must explicitly
+ * create additional endpoints by themselves (see rpmsg_create_ept()).
+ */
+struct rpmsg_endpoint {
+       struct rpmsg_channel *rpdev;
+       rpmsg_rx_cb_t cb;
+       u32 addr;
+       void *priv;
+};
+
+/**
+ * struct rpmsg_driver - rpmsg driver struct
+ * @drv: underlying device driver
+ * @id_table: rpmsg ids serviced by this driver
+ * @probe: invoked when a matching rpmsg channel (i.e. device) is found
+ * @remove: invoked when the rpmsg channel is removed
+ * @callback: invoked when an inbound message is received on the channel
+ */
+struct rpmsg_driver {
+       struct device_driver drv;
+       const struct rpmsg_device_id *id_table;
+       int (*probe)(struct rpmsg_channel *dev);
+       void (*remove)(struct rpmsg_channel *dev);
+       void (*callback)(struct rpmsg_channel *, void *, int, void *, u32);
+};
+
+int register_rpmsg_device(struct rpmsg_channel *dev);
+void unregister_rpmsg_device(struct rpmsg_channel *dev);
+int register_rpmsg_driver(struct rpmsg_driver *drv);
+void unregister_rpmsg_driver(struct rpmsg_driver *drv);
+void rpmsg_destroy_ept(struct rpmsg_endpoint *);
+struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *,
+                               rpmsg_rx_cb_t cb, void *priv, u32 addr);
+int
+rpmsg_send_offchannel_raw(struct rpmsg_channel *, u32, u32, void *, int, bool);
+
+/**
+ * rpmsg_send() - send a message across to the remote processor
+ * @rpdev: the rpmsg channel
+ * @data: payload of message
+ * @len: length of payload
+ *
+ * This function sends @data of length @len on the @rpdev channel.
+ * The message will be sent to the remote processor which the @rpdev
+ * channel belongs to, using @rpdev's source and destination addresses.
+ * In case there are no TX buffers available, the function will block until
+ * one becomes available, or a timeout of 15 seconds elapses. When the latter
+ * happens, -ERESTARTSYS is returned.
+ *
+ * Can only be called from process context (for now).
+ *
+ * Returns 0 on success and an appropriate error value on failure.
+ */
+static inline int rpmsg_send(struct rpmsg_channel *rpdev, void *data, int len)
+{
+       u32 src = rpdev->src, dst = rpdev->dst;
+
+       return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true);
+}
+
+/**
+ * rpmsg_sendto() - send a message across to the remote processor, specify dst
+ * @rpdev: the rpmsg channel
+ * @data: payload of message
+ * @len: length of payload
+ * @dst: destination address
+ *
+ * This function sends @data of length @len to the remote @dst address.
+ * The message will be sent to the remote processor which the @rpdev
+ * channel belongs to, using @rpdev's source address.
+ * In case there are no TX buffers available, the function will block until
+ * one becomes available, or a timeout of 15 seconds elapses. When the latter
+ * happens, -ERESTARTSYS is returned.
+ *
+ * Can only be called from process context (for now).
+ *
+ * Returns 0 on success and an appropriate error value on failure.
+ */
+static inline
+int rpmsg_sendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst)
+{
+       u32 src = rpdev->src;
+
+       return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true);
+}
+
+/**
+ * rpmsg_send_offchannel() - send a message using explicit src/dst addresses
+ * @rpdev: the rpmsg channel
+ * @src: source address
+ * @dst: destination address
+ * @data: payload of message
+ * @len: length of payload
+ *
+ * This function sends @data of length @len to the remote @dst address,
+ * and uses @src as the source address.
+ * The message will be sent to the remote processor which the @rpdev
+ * channel belongs to.
+ * In case there are no TX buffers available, the function will block until
+ * one becomes available, or a timeout of 15 seconds elapses. When the latter
+ * happens, -ERESTARTSYS is returned.
+ *
+ * Can only be called from process context (for now).
+ *
+ * Returns 0 on success and an appropriate error value on failure.
+ */
+static inline
+int rpmsg_send_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst,
+                                                       void *data, int len)
+{
+       return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true);
+}
+
+/**
+ * rpmsg_send() - send a message across to the remote processor
+ * @rpdev: the rpmsg channel
+ * @data: payload of message
+ * @len: length of payload
+ *
+ * This function sends @data of length @len on the @rpdev channel.
+ * The message will be sent to the remote processor which the @rpdev
+ * channel belongs to, using @rpdev's source and destination addresses.
+ * In case there are no TX buffers available, the function will immediately
+ * return -ENOMEM without waiting until one becomes available.
+ *
+ * Can only be called from process context (for now).
+ *
+ * Returns 0 on success and an appropriate error value on failure.
+ */
+static inline
+int rpmsg_trysend(struct rpmsg_channel *rpdev, void *data, int len)
+{
+       u32 src = rpdev->src, dst = rpdev->dst;
+
+       return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false);
+}
+
+/**
+ * rpmsg_sendto() - send a message across to the remote processor, specify dst
+ * @rpdev: the rpmsg channel
+ * @data: payload of message
+ * @len: length of payload
+ * @dst: destination address
+ *
+ * This function sends @data of length @len to the remote @dst address.
+ * The message will be sent to the remote processor which the @rpdev
+ * channel belongs to, using @rpdev's source address.
+ * In case there are no TX buffers available, the function will immediately
+ * return -ENOMEM without waiting until one becomes available.
+ *
+ * Can only be called from process context (for now).
+ *
+ * Returns 0 on success and an appropriate error value on failure.
+ */
+static inline
+int rpmsg_trysendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst)
+{
+       u32 src = rpdev->src;
+
+       return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false);
+}
+
+/**
+ * rpmsg_send_offchannel() - send a message using explicit src/dst addresses
+ * @rpdev: the rpmsg channel
+ * @src: source address
+ * @dst: destination address
+ * @data: payload of message
+ * @len: length of payload
+ *
+ * This function sends @data of length @len to the remote @dst address,
+ * and uses @src as the source address.
+ * The message will be sent to the remote processor which the @rpdev
+ * channel belongs to.
+ * In case there are no TX buffers available, the function will immediately
+ * return -ENOMEM without waiting until one becomes available.
+ *
+ * Can only be called from process context (for now).
+ *
+ * Returns 0 on success and an appropriate error value on failure.
+ */
+static inline
+int rpmsg_trysend_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst,
+                                                       void *data, int len)
+{
+       return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false);
+}
+
+#endif /* _LINUX_RPMSG_H */
diff --git a/include/linux/sa11x0-dma.h b/include/linux/sa11x0-dma.h
new file mode 100644 (file)
index 0000000..65839a5
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * SA11x0 DMA Engine support
+ *
+ * Copyright (C) 2012 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __LINUX_SA11X0_DMA_H
+#define __LINUX_SA11X0_DMA_H
+
+struct dma_chan;
+
+#if defined(CONFIG_DMA_SA11X0) || defined(CONFIG_DMA_SA11X0_MODULE)
+bool sa11x0_dma_filter_fn(struct dma_chan *, void *);
+#else
+static inline bool sa11x0_dma_filter_fn(struct dma_chan *c, void *d)
+{
+       return false;
+}
+#endif
+
+#endif
index 54341d811685a2088897491c2255ba605b71ab43..0a9d8f2ac51908958776115b8d1ff5d2cbbc5b6d 100644 (file)
@@ -18,7 +18,8 @@ struct clk_mapping {
        struct kref             ref;
 };
 
-struct clk_ops {
+
+struct sh_clk_ops {
 #ifdef CONFIG_SH_CLK_CPG_LEGACY
        void (*init)(struct clk *clk);
 #endif
@@ -37,7 +38,7 @@ struct clk {
        unsigned short          parent_num;     /* choose between */
        unsigned char           src_shift;      /* source clock field in the */
        unsigned char           src_width;      /* configuration register */
-       struct clk_ops          *ops;
+       struct sh_clk_ops       *ops;
 
        struct list_head        children;
        struct list_head        sibling;        /* node for children */
index 3fcb204a261229167587ab1bce52224e085ca620..192250bd49f508e5d1508a8fdef2527cf5f1fdd9 100644 (file)
@@ -1245,7 +1245,7 @@ static inline void skb_fill_page_desc(struct sk_buff *skb, int i,
 }
 
 extern void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page,
-                           int off, int size);
+                           int off, int size, unsigned int truesize);
 
 #define SKB_PAGE_ASSERT(skb)   BUG_ON(skb_shinfo(skb)->nr_frags)
 #define SKB_FRAG_ASSERT(skb)   BUG_ON(skb_has_frag_list(skb))
index decf6d8c77b7fa7d3a297653708566bb0bdf9d95..b4d9fa6f797cdd4653334315664a86a27ec081f1 100644 (file)
@@ -11,7 +11,6 @@
 
 struct orion_spi_info {
        u32     tclk;           /* no <linux/clk.h> support yet */
-       u32     enable_clock_fix;
 };
 
 
diff --git a/include/linux/spi/s3c24xx.h b/include/linux/spi/s3c24xx.h
new file mode 100644 (file)
index 0000000..c23b923
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - SPI Controller platform_device info
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __LINUX_SPI_S3C24XX_H
+#define __LINUX_SPI_S3C24XX_H __FILE__
+
+struct s3c2410_spi_info {
+       int                      pin_cs;        /* simple gpio cs */
+       unsigned int             num_cs;        /* total chipselects */
+       int                      bus_num;       /* bus number to use. */
+
+       unsigned int             use_fiq:1;     /* use fiq */
+
+       void (*gpio_setup)(struct s3c2410_spi_info *spi, int enable);
+       void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol);
+};
+
+#endif /* __LINUX_SPI_S3C24XX_H */
index c5d8455c68c0ef80b31b37a16585471ca0e6b856..7529b854b7fd96ff11608f41313454e658ee25f8 100644 (file)
@@ -34,6 +34,7 @@
 #define VIRTIO_ID_CONSOLE      3 /* virtio console */
 #define VIRTIO_ID_RNG          4 /* virtio ring */
 #define VIRTIO_ID_BALLOON      5 /* virtio balloon */
+#define VIRTIO_ID_RPMSG                7 /* virtio remote processor messaging */
 #define VIRTIO_ID_SCSI         8 /* virtio scsi */
 #define VIRTIO_ID_9P           9 /* 9p virtio console */
 
index 90c67c7db7e9135b1a762ccb1700846c91aff281..3b572bb20aa2bb1105cba9f04b28594108b63bc9 100644 (file)
@@ -118,6 +118,10 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_generic;
 extern struct nf_conntrack_l4proto *
 __nf_ct_l4proto_find(u_int16_t l3proto, u_int8_t l4proto);
 
+extern struct nf_conntrack_l4proto *
+nf_ct_l4proto_find_get(u_int16_t l3proto, u_int8_t l4proto);
+extern void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p);
+
 /* Protocol registration. */
 extern int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *proto);
 extern void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *proto);
index 0e04db4a086531a14b817edd85782b912c0c20fc..34ec89f8dbf90303246af81061e8746bad99e867 100644 (file)
@@ -15,7 +15,7 @@ struct ctnl_timeout {
        atomic_t                refcnt;
        char                    name[CTNL_TIMEOUT_NAME_MAX];
        __u16                   l3num;
-       __u8                    l4num;
+       struct nf_conntrack_l4proto *l4proto;
        char                    data[0];
 };
 
index 75964412ddbb56574d11f8d3e608577bcc21687f..127993dbf322efa40bc68222551ff181132122b4 100644 (file)
@@ -81,6 +81,13 @@ DEFINE_EVENT(jbd2_commit, jbd2_commit_logging,
        TP_ARGS(journal, commit_transaction)
 );
 
+DEFINE_EVENT(jbd2_commit, jbd2_drop_transaction,
+
+       TP_PROTO(journal_t *journal, transaction_t *commit_transaction),
+
+       TP_ARGS(journal, commit_transaction)
+);
+
 TRACE_EVENT(jbd2_end_commit,
        TP_PROTO(journal_t *journal, transaction_t *commit_transaction),
 
@@ -200,7 +207,7 @@ TRACE_EVENT(jbd2_checkpoint_stats,
                  __entry->forced_to_close, __entry->written, __entry->dropped)
 );
 
-TRACE_EVENT(jbd2_cleanup_journal_tail,
+TRACE_EVENT(jbd2_update_log_tail,
 
        TP_PROTO(journal_t *journal, tid_t first_tid,
                 unsigned long block_nr, unsigned long freed),
@@ -229,6 +236,26 @@ TRACE_EVENT(jbd2_cleanup_journal_tail,
                  __entry->block_nr, __entry->freed)
 );
 
+TRACE_EVENT(jbd2_write_superblock,
+
+       TP_PROTO(journal_t *journal, int write_op),
+
+       TP_ARGS(journal, write_op),
+
+       TP_STRUCT__entry(
+               __field(        dev_t,  dev                     )
+               __field(          int,  write_op                )
+       ),
+
+       TP_fast_assign(
+               __entry->dev            = journal->j_fs_dev->bd_dev;
+               __entry->write_op       = write_op;
+       ),
+
+       TP_printk("dev %d,%d write_op %x", MAJOR(__entry->dev),
+                 MINOR(__entry->dev), __entry->write_op)
+);
+
 #endif /* _TRACE_JBD2_H */
 
 /* This part must be outside protection */
diff --git a/include/video/sa1100fb.h b/include/video/sa1100fb.h
new file mode 100644 (file)
index 0000000..4ab4096
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * StrongARM 1100 LCD Controller Frame Buffer Device
+ *
+ * Copyright (C) 1999 Eric A. Thomas
+ *  Based on acornfb.c Copyright (C) Russell King.
+ *  
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+#ifndef _VIDEO_SA1100FB_H
+#define _VIDEO_SA1100FB_H
+
+#include <linux/fb.h>
+#include <linux/types.h>
+
+#define RGB_4  0
+#define RGB_8  1
+#define RGB_16 2
+#define NR_RGB 3
+
+/* These are the bitfields for each display depth that we support. */
+struct sa1100fb_rgb {
+       struct fb_bitfield      red;
+       struct fb_bitfield      green;
+       struct fb_bitfield      blue;
+       struct fb_bitfield      transp;
+};
+
+/* This structure describes the machine which we are running on. */
+struct sa1100fb_mach_info {
+       u_long          pixclock;
+
+       u_short         xres;
+       u_short         yres;
+
+       u_char          bpp;
+       u_char          hsync_len;
+       u_char          left_margin;
+       u_char          right_margin;
+
+       u_char          vsync_len;
+       u_char          upper_margin;
+       u_char          lower_margin;
+       u_char          sync;
+
+       u_int           cmap_greyscale:1,
+                       cmap_inverse:1,
+                       cmap_static:1,
+                       unused:29;
+
+       u_int           lccr0;
+       u_int           lccr3;
+
+       /* Overrides for the default RGB maps */
+       const struct sa1100fb_rgb *rgb[NR_RGB];
+
+       void (*backlight_power)(int);
+       void (*lcd_power)(int);
+       void (*set_visual)(u32);
+};
+
+#endif
index 43359bb1ca9087510a13e04f052082c45ade967e..a0e5900a9d85eedba0da1420836797476753f8a0 100644 (file)
@@ -29,6 +29,10 @@ config GENERIC_IOMAP
        bool
        select GENERIC_PCI_IOMAP
 
+config GENERIC_IO
+       boolean
+       default n
+
 config CRC_CCITT
        tristate "CRC-CCITT functions"
        help
@@ -277,6 +281,7 @@ config BTREE
 config HAS_IOMEM
        boolean
        depends on !NO_IOMEM
+       select GENERIC_IO
        default y
 
 config HAS_IOPORT
index 3fc261705b1e068c28c72a329f31ee431ae3fdc9..26adea8ca2e7dd9ebdbc9c0938498a1a8a56324d 100644 (file)
@@ -95,6 +95,8 @@ unsigned long vm_dirty_bytes;
  */
 unsigned int dirty_writeback_interval = 5 * 100; /* centiseconds */
 
+EXPORT_SYMBOL_GPL(dirty_writeback_interval);
+
 /*
  * The longest time for which data is allowed to remain dirty
  */
index 776618cd2be5c122fecaf31934f06d74fff2b450..b23a17c431c87ae8ae3c000349ad52f048286bff 100644 (file)
@@ -740,10 +740,18 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
                        c->status = Disconnected;
                goto reterr;
        }
+again:
        /* Wait for the response */
        err = wait_event_interruptible(*req->wq,
                                       req->status >= REQ_STATUS_RCVD);
 
+       if ((err == -ERESTARTSYS) && (c->status == Connected)
+                                 && (type == P9_TFLUSH)) {
+               sigpending = 1;
+               clear_thread_flag(TIF_SIGPENDING);
+               goto again;
+       }
+
        if (req->status == REQ_STATUS_ERROR) {
                p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
                err = req->t_err;
@@ -1420,6 +1428,7 @@ int p9_client_clunk(struct p9_fid *fid)
        int err;
        struct p9_client *clnt;
        struct p9_req_t *req;
+       int retries = 0;
 
        if (!fid) {
                pr_warn("%s (%d): Trying to clunk with NULL fid\n",
@@ -1428,7 +1437,9 @@ int p9_client_clunk(struct p9_fid *fid)
                return 0;
        }
 
-       p9_debug(P9_DEBUG_9P, ">>> TCLUNK fid %d\n", fid->fid);
+again:
+       p9_debug(P9_DEBUG_9P, ">>> TCLUNK fid %d (try %d)\n", fid->fid,
+                                                               retries);
        err = 0;
        clnt = fid->clnt;
 
@@ -1444,8 +1455,14 @@ int p9_client_clunk(struct p9_fid *fid)
 error:
        /*
         * Fid is not valid even after a failed clunk
+        * If interrupted, retry once then give up and
+        * leak fid until umount.
         */
-       p9_fid_destroy(fid);
+       if (err == -ERESTARTSYS) {
+               if (retries++ == 0)
+                       goto again;
+       } else
+               p9_fid_destroy(fid);
        return err;
 }
 EXPORT_SYMBOL(p9_client_clunk);
@@ -1470,7 +1487,10 @@ int p9_client_remove(struct p9_fid *fid)
 
        p9_free_req(clnt, req);
 error:
-       p9_fid_destroy(fid);
+       if (err == -ERESTARTSYS)
+               p9_client_clunk(fid);
+       else
+               p9_fid_destroy(fid);
        return err;
 }
 EXPORT_SYMBOL(p9_client_remove);
index 761ad9d6cc3b12fc4d6d8c10022e4c877559f5c8..cc913193d992d98f80949f7f167ff7ecb48fdcc1 100644 (file)
@@ -201,7 +201,9 @@ enum {
        Opt_ip,
        Opt_last_string,
        /* string args above */
+       Opt_share,
        Opt_noshare,
+       Opt_crc,
        Opt_nocrc,
 };
 
@@ -217,7 +219,9 @@ static match_table_t opt_tokens = {
        {Opt_key, "key=%s"},
        {Opt_ip, "ip=%s"},
        /* string args above */
+       {Opt_share, "share"},
        {Opt_noshare, "noshare"},
+       {Opt_crc, "crc"},
        {Opt_nocrc, "nocrc"},
        {-1, NULL}
 };
@@ -277,10 +281,11 @@ out:
        return err;
 }
 
-int ceph_parse_options(struct ceph_options **popt, char *options,
-                      const char *dev_name, const char *dev_name_end,
-                      int (*parse_extra_token)(char *c, void *private),
-                      void *private)
+struct ceph_options *
+ceph_parse_options(char *options, const char *dev_name,
+                       const char *dev_name_end,
+                       int (*parse_extra_token)(char *c, void *private),
+                       void *private)
 {
        struct ceph_options *opt;
        const char *c;
@@ -289,7 +294,7 @@ int ceph_parse_options(struct ceph_options **popt, char *options,
 
        opt = kzalloc(sizeof(*opt), GFP_KERNEL);
        if (!opt)
-               return err;
+               return ERR_PTR(-ENOMEM);
        opt->mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*opt->mon_addr),
                                GFP_KERNEL);
        if (!opt->mon_addr)
@@ -398,10 +403,16 @@ int ceph_parse_options(struct ceph_options **popt, char *options,
                        opt->mount_timeout = intval;
                        break;
 
+               case Opt_share:
+                       opt->flags &= ~CEPH_OPT_NOSHARE;
+                       break;
                case Opt_noshare:
                        opt->flags |= CEPH_OPT_NOSHARE;
                        break;
 
+               case Opt_crc:
+                       opt->flags &= ~CEPH_OPT_NOCRC;
+                       break;
                case Opt_nocrc:
                        opt->flags |= CEPH_OPT_NOCRC;
                        break;
@@ -412,12 +423,11 @@ int ceph_parse_options(struct ceph_options **popt, char *options,
        }
 
        /* success */
-       *popt = opt;
-       return 0;
+       return opt;
 
 out:
        ceph_destroy_options(opt);
-       return err;
+       return ERR_PTR(err);
 }
 EXPORT_SYMBOL(ceph_parse_options);
 
index ad5b70801f37788edbb71b6d95cbe7d25ab94abd..f0993af2ae4deff311f2da78a14bcbe14b2fb8c2 100644 (file)
@@ -38,48 +38,54 @@ static char tag_keepalive = CEPH_MSGR_TAG_KEEPALIVE;
 static struct lock_class_key socket_class;
 #endif
 
+/*
+ * When skipping (ignoring) a block of input we read it into a "skip
+ * buffer," which is this many bytes in size.
+ */
+#define SKIP_BUF_SIZE  1024
 
 static void queue_con(struct ceph_connection *con);
 static void con_work(struct work_struct *);
 static void ceph_fault(struct ceph_connection *con);
 
 /*
- * nicely render a sockaddr as a string.
+ * Nicely render a sockaddr as a string.  An array of formatted
+ * strings is used, to approximate reentrancy.
  */
-#define MAX_ADDR_STR 20
-#define MAX_ADDR_STR_LEN 60
-static char addr_str[MAX_ADDR_STR][MAX_ADDR_STR_LEN];
-static DEFINE_SPINLOCK(addr_str_lock);
-static int last_addr_str;
+#define ADDR_STR_COUNT_LOG     5       /* log2(# address strings in array) */
+#define ADDR_STR_COUNT         (1 << ADDR_STR_COUNT_LOG)
+#define ADDR_STR_COUNT_MASK    (ADDR_STR_COUNT - 1)
+#define MAX_ADDR_STR_LEN       64      /* 54 is enough */
+
+static char addr_str[ADDR_STR_COUNT][MAX_ADDR_STR_LEN];
+static atomic_t addr_str_seq = ATOMIC_INIT(0);
+
+static struct page *zero_page;         /* used in certain error cases */
 
 const char *ceph_pr_addr(const struct sockaddr_storage *ss)
 {
        int i;
        char *s;
-       struct sockaddr_in *in4 = (void *)ss;
-       struct sockaddr_in6 *in6 = (void *)ss;
-
-       spin_lock(&addr_str_lock);
-       i = last_addr_str++;
-       if (last_addr_str == MAX_ADDR_STR)
-               last_addr_str = 0;
-       spin_unlock(&addr_str_lock);
+       struct sockaddr_in *in4 = (struct sockaddr_in *) ss;
+       struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) ss;
+
+       i = atomic_inc_return(&addr_str_seq) & ADDR_STR_COUNT_MASK;
        s = addr_str[i];
 
        switch (ss->ss_family) {
        case AF_INET:
-               snprintf(s, MAX_ADDR_STR_LEN, "%pI4:%u", &in4->sin_addr,
-                        (unsigned int)ntohs(in4->sin_port));
+               snprintf(s, MAX_ADDR_STR_LEN, "%pI4:%hu", &in4->sin_addr,
+                        ntohs(in4->sin_port));
                break;
 
        case AF_INET6:
-               snprintf(s, MAX_ADDR_STR_LEN, "[%pI6c]:%u", &in6->sin6_addr,
-                        (unsigned int)ntohs(in6->sin6_port));
+               snprintf(s, MAX_ADDR_STR_LEN, "[%pI6c]:%hu", &in6->sin6_addr,
+                        ntohs(in6->sin6_port));
                break;
 
        default:
-               snprintf(s, MAX_ADDR_STR_LEN, "(unknown sockaddr family %d)",
-                        (int)ss->ss_family);
+               snprintf(s, MAX_ADDR_STR_LEN, "(unknown sockaddr family %hu)",
+                        ss->ss_family);
        }
 
        return s;
@@ -95,22 +101,43 @@ static void encode_my_addr(struct ceph_messenger *msgr)
 /*
  * work queue for all reading and writing to/from the socket.
  */
-struct workqueue_struct *ceph_msgr_wq;
+static struct workqueue_struct *ceph_msgr_wq;
+
+void _ceph_msgr_exit(void)
+{
+       if (ceph_msgr_wq) {
+               destroy_workqueue(ceph_msgr_wq);
+               ceph_msgr_wq = NULL;
+       }
+
+       BUG_ON(zero_page == NULL);
+       kunmap(zero_page);
+       page_cache_release(zero_page);
+       zero_page = NULL;
+}
 
 int ceph_msgr_init(void)
 {
+       BUG_ON(zero_page != NULL);
+       zero_page = ZERO_PAGE(0);
+       page_cache_get(zero_page);
+
        ceph_msgr_wq = alloc_workqueue("ceph-msgr", WQ_NON_REENTRANT, 0);
-       if (!ceph_msgr_wq) {
-               pr_err("msgr_init failed to create workqueue\n");
-               return -ENOMEM;
-       }
-       return 0;
+       if (ceph_msgr_wq)
+               return 0;
+
+       pr_err("msgr_init failed to create workqueue\n");
+       _ceph_msgr_exit();
+
+       return -ENOMEM;
 }
 EXPORT_SYMBOL(ceph_msgr_init);
 
 void ceph_msgr_exit(void)
 {
-       destroy_workqueue(ceph_msgr_wq);
+       BUG_ON(ceph_msgr_wq == NULL);
+
+       _ceph_msgr_exit();
 }
 EXPORT_SYMBOL(ceph_msgr_exit);
 
@@ -128,8 +155,8 @@ EXPORT_SYMBOL(ceph_msgr_flush);
 /* data available on socket, or listen socket received a connect */
 static void ceph_data_ready(struct sock *sk, int count_unused)
 {
-       struct ceph_connection *con =
-               (struct ceph_connection *)sk->sk_user_data;
+       struct ceph_connection *con = sk->sk_user_data;
+
        if (sk->sk_state != TCP_CLOSE_WAIT) {
                dout("ceph_data_ready on %p state = %lu, queueing work\n",
                     con, con->state);
@@ -140,26 +167,30 @@ static void ceph_data_ready(struct sock *sk, int count_unused)
 /* socket has buffer space for writing */
 static void ceph_write_space(struct sock *sk)
 {
-       struct ceph_connection *con =
-               (struct ceph_connection *)sk->sk_user_data;
+       struct ceph_connection *con = sk->sk_user_data;
 
-       /* only queue to workqueue if there is data we want to write. */
+       /* only queue to workqueue if there is data we want to write,
+        * and there is sufficient space in the socket buffer to accept
+        * more data.  clear SOCK_NOSPACE so that ceph_write_space()
+        * doesn't get called again until try_write() fills the socket
+        * buffer. See net/ipv4/tcp_input.c:tcp_check_space()
+        * and net/core/stream.c:sk_stream_write_space().
+        */
        if (test_bit(WRITE_PENDING, &con->state)) {
-               dout("ceph_write_space %p queueing write work\n", con);
-               queue_con(con);
+               if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) {
+                       dout("ceph_write_space %p queueing write work\n", con);
+                       clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
+                       queue_con(con);
+               }
        } else {
                dout("ceph_write_space %p nothing to write\n", con);
        }
-
-       /* since we have our own write_space, clear the SOCK_NOSPACE flag */
-       clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
 }
 
 /* socket's state has changed */
 static void ceph_state_change(struct sock *sk)
 {
-       struct ceph_connection *con =
-               (struct ceph_connection *)sk->sk_user_data;
+       struct ceph_connection *con = sk->sk_user_data;
 
        dout("ceph_state_change %p state = %lu sk_state = %u\n",
             con, con->state, sk->sk_state);
@@ -184,6 +215,8 @@ static void ceph_state_change(struct sock *sk)
                dout("ceph_state_change TCP_ESTABLISHED\n");
                queue_con(con);
                break;
+       default:        /* Everything else is uninteresting */
+               break;
        }
 }
 
@@ -194,7 +227,7 @@ static void set_sock_callbacks(struct socket *sock,
                               struct ceph_connection *con)
 {
        struct sock *sk = sock->sk;
-       sk->sk_user_data = (void *)con;
+       sk->sk_user_data = con;
        sk->sk_data_ready = ceph_data_ready;
        sk->sk_write_space = ceph_write_space;
        sk->sk_state_change = ceph_state_change;
@@ -208,7 +241,7 @@ static void set_sock_callbacks(struct socket *sock,
 /*
  * initiate connection to a remote socket.
  */
-static struct socket *ceph_tcp_connect(struct ceph_connection *con)
+static int ceph_tcp_connect(struct ceph_connection *con)
 {
        struct sockaddr_storage *paddr = &con->peer_addr.in_addr;
        struct socket *sock;
@@ -218,8 +251,7 @@ static struct socket *ceph_tcp_connect(struct ceph_connection *con)
        ret = sock_create_kern(con->peer_addr.in_addr.ss_family, SOCK_STREAM,
                               IPPROTO_TCP, &sock);
        if (ret)
-               return ERR_PTR(ret);
-       con->sock = sock;
+               return ret;
        sock->sk->sk_allocation = GFP_NOFS;
 
 #ifdef CONFIG_LOCKDEP
@@ -236,19 +268,17 @@ static struct socket *ceph_tcp_connect(struct ceph_connection *con)
                dout("connect %s EINPROGRESS sk_state = %u\n",
                     ceph_pr_addr(&con->peer_addr.in_addr),
                     sock->sk->sk_state);
-               ret = 0;
-       }
-       if (ret < 0) {
+       } else if (ret < 0) {
                pr_err("connect %s error %d\n",
                       ceph_pr_addr(&con->peer_addr.in_addr), ret);
                sock_release(sock);
-               con->sock = NULL;
                con->error_msg = "connect error";
+
+               return ret;
        }
+       con->sock = sock;
 
-       if (ret < 0)
-               return ERR_PTR(ret);
-       return sock;
+       return 0;
 }
 
 static int ceph_tcp_recvmsg(struct socket *sock, void *buf, size_t len)
@@ -284,6 +314,19 @@ static int ceph_tcp_sendmsg(struct socket *sock, struct kvec *iov,
        return r;
 }
 
+static int ceph_tcp_sendpage(struct socket *sock, struct page *page,
+                    int offset, size_t size, int more)
+{
+       int flags = MSG_DONTWAIT | MSG_NOSIGNAL | (more ? MSG_MORE : MSG_EOR);
+       int ret;
+
+       ret = kernel_sendpage(sock, page, offset, size, flags);
+       if (ret == -EAGAIN)
+               ret = 0;
+
+       return ret;
+}
+
 
 /*
  * Shutdown/close the socket for the given connection.
@@ -391,22 +434,23 @@ bool ceph_con_opened(struct ceph_connection *con)
  */
 struct ceph_connection *ceph_con_get(struct ceph_connection *con)
 {
-       dout("con_get %p nref = %d -> %d\n", con,
-            atomic_read(&con->nref), atomic_read(&con->nref) + 1);
-       if (atomic_inc_not_zero(&con->nref))
-               return con;
-       return NULL;
+       int nref = __atomic_add_unless(&con->nref, 1, 0);
+
+       dout("con_get %p nref = %d -> %d\n", con, nref, nref + 1);
+
+       return nref ? con : NULL;
 }
 
 void ceph_con_put(struct ceph_connection *con)
 {
-       dout("con_put %p nref = %d -> %d\n", con,
-            atomic_read(&con->nref), atomic_read(&con->nref) - 1);
-       BUG_ON(atomic_read(&con->nref) == 0);
-       if (atomic_dec_and_test(&con->nref)) {
+       int nref = atomic_dec_return(&con->nref);
+
+       BUG_ON(nref < 0);
+       if (nref == 0) {
                BUG_ON(con->sock);
                kfree(con);
        }
+       dout("con_put %p nref = %d -> %d\n", con, nref + 1, nref);
 }
 
 /*
@@ -442,14 +486,35 @@ static u32 get_global_seq(struct ceph_messenger *msgr, u32 gt)
        return ret;
 }
 
+static void ceph_con_out_kvec_reset(struct ceph_connection *con)
+{
+       con->out_kvec_left = 0;
+       con->out_kvec_bytes = 0;
+       con->out_kvec_cur = &con->out_kvec[0];
+}
+
+static void ceph_con_out_kvec_add(struct ceph_connection *con,
+                               size_t size, void *data)
+{
+       int index;
+
+       index = con->out_kvec_left;
+       BUG_ON(index >= ARRAY_SIZE(con->out_kvec));
+
+       con->out_kvec[index].iov_len = size;
+       con->out_kvec[index].iov_base = data;
+       con->out_kvec_left++;
+       con->out_kvec_bytes += size;
+}
 
 /*
  * Prepare footer for currently outgoing message, and finish things
  * off.  Assumes out_kvec* are already valid.. we just add on to the end.
  */
-static void prepare_write_message_footer(struct ceph_connection *con, int v)
+static void prepare_write_message_footer(struct ceph_connection *con)
 {
        struct ceph_msg *m = con->out_msg;
+       int v = con->out_kvec_left;
 
        dout("prepare_write_message_footer %p\n", con);
        con->out_kvec_is_msg = true;
@@ -467,9 +532,9 @@ static void prepare_write_message_footer(struct ceph_connection *con, int v)
 static void prepare_write_message(struct ceph_connection *con)
 {
        struct ceph_msg *m;
-       int v = 0;
+       u32 crc;
 
-       con->out_kvec_bytes = 0;
+       ceph_con_out_kvec_reset(con);
        con->out_kvec_is_msg = true;
        con->out_msg_done = false;
 
@@ -477,16 +542,13 @@ static void prepare_write_message(struct ceph_connection *con)
         * TCP packet that's a good thing. */
        if (con->in_seq > con->in_seq_acked) {
                con->in_seq_acked = con->in_seq;
-               con->out_kvec[v].iov_base = &tag_ack;
-               con->out_kvec[v++].iov_len = 1;
+               ceph_con_out_kvec_add(con, sizeof (tag_ack), &tag_ack);
                con->out_temp_ack = cpu_to_le64(con->in_seq_acked);
-               con->out_kvec[v].iov_base = &con->out_temp_ack;
-               con->out_kvec[v++].iov_len = sizeof(con->out_temp_ack);
-               con->out_kvec_bytes = 1 + sizeof(con->out_temp_ack);
+               ceph_con_out_kvec_add(con, sizeof (con->out_temp_ack),
+                       &con->out_temp_ack);
        }
 
-       m = list_first_entry(&con->out_queue,
-                      struct ceph_msg, list_head);
+       m = list_first_entry(&con->out_queue, struct ceph_msg, list_head);
        con->out_msg = m;
 
        /* put message on sent list */
@@ -510,30 +572,26 @@ static void prepare_write_message(struct ceph_connection *con)
        BUG_ON(le32_to_cpu(m->hdr.front_len) != m->front.iov_len);
 
        /* tag + hdr + front + middle */
-       con->out_kvec[v].iov_base = &tag_msg;
-       con->out_kvec[v++].iov_len = 1;
-       con->out_kvec[v].iov_base = &m->hdr;
-       con->out_kvec[v++].iov_len = sizeof(m->hdr);
-       con->out_kvec[v++] = m->front;
+       ceph_con_out_kvec_add(con, sizeof (tag_msg), &tag_msg);
+       ceph_con_out_kvec_add(con, sizeof (m->hdr), &m->hdr);
+       ceph_con_out_kvec_add(con, m->front.iov_len, m->front.iov_base);
+
        if (m->middle)
-               con->out_kvec[v++] = m->middle->vec;
-       con->out_kvec_left = v;
-       con->out_kvec_bytes += 1 + sizeof(m->hdr) + m->front.iov_len +
-               (m->middle ? m->middle->vec.iov_len : 0);
-       con->out_kvec_cur = con->out_kvec;
+               ceph_con_out_kvec_add(con, m->middle->vec.iov_len,
+                       m->middle->vec.iov_base);
 
        /* fill in crc (except data pages), footer */
-       con->out_msg->hdr.crc =
-               cpu_to_le32(crc32c(0, (void *)&m->hdr,
-                                     sizeof(m->hdr) - sizeof(m->hdr.crc)));
+       crc = crc32c(0, &m->hdr, offsetof(struct ceph_msg_header, crc));
+       con->out_msg->hdr.crc = cpu_to_le32(crc);
        con->out_msg->footer.flags = CEPH_MSG_FOOTER_COMPLETE;
-       con->out_msg->footer.front_crc =
-               cpu_to_le32(crc32c(0, m->front.iov_base, m->front.iov_len));
-       if (m->middle)
-               con->out_msg->footer.middle_crc =
-                       cpu_to_le32(crc32c(0, m->middle->vec.iov_base,
-                                          m->middle->vec.iov_len));
-       else
+
+       crc = crc32c(0, m->front.iov_base, m->front.iov_len);
+       con->out_msg->footer.front_crc = cpu_to_le32(crc);
+       if (m->middle) {
+               crc = crc32c(0, m->middle->vec.iov_base,
+                               m->middle->vec.iov_len);
+               con->out_msg->footer.middle_crc = cpu_to_le32(crc);
+       } else
                con->out_msg->footer.middle_crc = 0;
        con->out_msg->footer.data_crc = 0;
        dout("prepare_write_message front_crc %u data_crc %u\n",
@@ -549,11 +607,11 @@ static void prepare_write_message(struct ceph_connection *con)
                else
                        con->out_msg_pos.page_pos = 0;
                con->out_msg_pos.data_pos = 0;
-               con->out_msg_pos.did_page_crc = 0;
+               con->out_msg_pos.did_page_crc = false;
                con->out_more = 1;  /* data + footer will follow */
        } else {
                /* no, queue up footer too and be done */
-               prepare_write_message_footer(con, v);
+               prepare_write_message_footer(con);
        }
 
        set_bit(WRITE_PENDING, &con->state);
@@ -568,14 +626,14 @@ static void prepare_write_ack(struct ceph_connection *con)
             con->in_seq_acked, con->in_seq);
        con->in_seq_acked = con->in_seq;
 
-       con->out_kvec[0].iov_base = &tag_ack;
-       con->out_kvec[0].iov_len = 1;
+       ceph_con_out_kvec_reset(con);
+
+       ceph_con_out_kvec_add(con, sizeof (tag_ack), &tag_ack);
+
        con->out_temp_ack = cpu_to_le64(con->in_seq_acked);
-       con->out_kvec[1].iov_base = &con->out_temp_ack;
-       con->out_kvec[1].iov_len = sizeof(con->out_temp_ack);
-       con->out_kvec_left = 2;
-       con->out_kvec_bytes = 1 + sizeof(con->out_temp_ack);
-       con->out_kvec_cur = con->out_kvec;
+       ceph_con_out_kvec_add(con, sizeof (con->out_temp_ack),
+                               &con->out_temp_ack);
+
        con->out_more = 1;  /* more will follow.. eventually.. */
        set_bit(WRITE_PENDING, &con->state);
 }
@@ -586,11 +644,8 @@ static void prepare_write_ack(struct ceph_connection *con)
 static void prepare_write_keepalive(struct ceph_connection *con)
 {
        dout("prepare_write_keepalive %p\n", con);
-       con->out_kvec[0].iov_base = &tag_keepalive;
-       con->out_kvec[0].iov_len = 1;
-       con->out_kvec_left = 1;
-       con->out_kvec_bytes = 1;
-       con->out_kvec_cur = con->out_kvec;
+       ceph_con_out_kvec_reset(con);
+       ceph_con_out_kvec_add(con, sizeof (tag_keepalive), &tag_keepalive);
        set_bit(WRITE_PENDING, &con->state);
 }
 
@@ -619,12 +674,9 @@ static int prepare_connect_authorizer(struct ceph_connection *con)
        con->out_connect.authorizer_protocol = cpu_to_le32(auth_protocol);
        con->out_connect.authorizer_len = cpu_to_le32(auth_len);
 
-       if (auth_len) {
-               con->out_kvec[con->out_kvec_left].iov_base = auth_buf;
-               con->out_kvec[con->out_kvec_left].iov_len = auth_len;
-               con->out_kvec_left++;
-               con->out_kvec_bytes += auth_len;
-       }
+       if (auth_len)
+               ceph_con_out_kvec_add(con, auth_len, auth_buf);
+
        return 0;
 }
 
@@ -634,22 +686,18 @@ static int prepare_connect_authorizer(struct ceph_connection *con)
 static void prepare_write_banner(struct ceph_messenger *msgr,
                                 struct ceph_connection *con)
 {
-       int len = strlen(CEPH_BANNER);
+       ceph_con_out_kvec_reset(con);
+       ceph_con_out_kvec_add(con, strlen(CEPH_BANNER), CEPH_BANNER);
+       ceph_con_out_kvec_add(con, sizeof (msgr->my_enc_addr),
+                                       &msgr->my_enc_addr);
 
-       con->out_kvec[0].iov_base = CEPH_BANNER;
-       con->out_kvec[0].iov_len = len;
-       con->out_kvec[1].iov_base = &msgr->my_enc_addr;
-       con->out_kvec[1].iov_len = sizeof(msgr->my_enc_addr);
-       con->out_kvec_left = 2;
-       con->out_kvec_bytes = len + sizeof(msgr->my_enc_addr);
-       con->out_kvec_cur = con->out_kvec;
        con->out_more = 0;
        set_bit(WRITE_PENDING, &con->state);
 }
 
 static int prepare_write_connect(struct ceph_messenger *msgr,
                                 struct ceph_connection *con,
-                                int after_banner)
+                                int include_banner)
 {
        unsigned global_seq = get_global_seq(con->msgr, 0);
        int proto;
@@ -678,22 +726,18 @@ static int prepare_write_connect(struct ceph_messenger *msgr,
        con->out_connect.protocol_version = cpu_to_le32(proto);
        con->out_connect.flags = 0;
 
-       if (!after_banner) {
-               con->out_kvec_left = 0;
-               con->out_kvec_bytes = 0;
-       }
-       con->out_kvec[con->out_kvec_left].iov_base = &con->out_connect;
-       con->out_kvec[con->out_kvec_left].iov_len = sizeof(con->out_connect);
-       con->out_kvec_left++;
-       con->out_kvec_bytes += sizeof(con->out_connect);
-       con->out_kvec_cur = con->out_kvec;
+       if (include_banner)
+               prepare_write_banner(msgr, con);
+       else
+               ceph_con_out_kvec_reset(con);
+       ceph_con_out_kvec_add(con, sizeof (con->out_connect), &con->out_connect);
+
        con->out_more = 0;
        set_bit(WRITE_PENDING, &con->state);
 
        return prepare_connect_authorizer(con);
 }
 
-
 /*
  * write as much of pending kvecs to the socket as we can.
  *  1 -> done
@@ -714,17 +758,18 @@ static int write_partial_kvec(struct ceph_connection *con)
                con->out_kvec_bytes -= ret;
                if (con->out_kvec_bytes == 0)
                        break;            /* done */
-               while (ret > 0) {
-                       if (ret >= con->out_kvec_cur->iov_len) {
-                               ret -= con->out_kvec_cur->iov_len;
-                               con->out_kvec_cur++;
-                               con->out_kvec_left--;
-                       } else {
-                               con->out_kvec_cur->iov_len -= ret;
-                               con->out_kvec_cur->iov_base += ret;
-                               ret = 0;
-                               break;
-                       }
+
+               /* account for full iov entries consumed */
+               while (ret >= con->out_kvec_cur->iov_len) {
+                       BUG_ON(!con->out_kvec_left);
+                       ret -= con->out_kvec_cur->iov_len;
+                       con->out_kvec_cur++;
+                       con->out_kvec_left--;
+               }
+               /* and for a partially-consumed entry */
+               if (ret) {
+                       con->out_kvec_cur->iov_len -= ret;
+                       con->out_kvec_cur->iov_base += ret;
                }
        }
        con->out_kvec_left = 0;
@@ -773,7 +818,7 @@ static int write_partial_msg_pages(struct ceph_connection *con)
        struct ceph_msg *msg = con->out_msg;
        unsigned data_len = le32_to_cpu(msg->hdr.data_len);
        size_t len;
-       int crc = con->msgr->nocrc;
+       bool do_datacrc = !con->msgr->nocrc;
        int ret;
        int total_max_write;
        int in_trail = 0;
@@ -790,9 +835,8 @@ static int write_partial_msg_pages(struct ceph_connection *con)
 
        while (data_len > con->out_msg_pos.data_pos) {
                struct page *page = NULL;
-               void *kaddr = NULL;
                int max_write = PAGE_SIZE;
-               int page_shift = 0;
+               int bio_offset = 0;
 
                total_max_write = data_len - trail_len -
                        con->out_msg_pos.data_pos;
@@ -811,58 +855,47 @@ static int write_partial_msg_pages(struct ceph_connection *con)
 
                        page = list_first_entry(&msg->trail->head,
                                                struct page, lru);
-                       if (crc)
-                               kaddr = kmap(page);
                        max_write = PAGE_SIZE;
                } else if (msg->pages) {
                        page = msg->pages[con->out_msg_pos.page];
-                       if (crc)
-                               kaddr = kmap(page);
                } else if (msg->pagelist) {
                        page = list_first_entry(&msg->pagelist->head,
                                                struct page, lru);
-                       if (crc)
-                               kaddr = kmap(page);
 #ifdef CONFIG_BLOCK
                } else if (msg->bio) {
                        struct bio_vec *bv;
 
                        bv = bio_iovec_idx(msg->bio_iter, msg->bio_seg);
                        page = bv->bv_page;
-                       page_shift = bv->bv_offset;
-                       if (crc)
-                               kaddr = kmap(page) + page_shift;
+                       bio_offset = bv->bv_offset;
                        max_write = bv->bv_len;
 #endif
                } else {
-                       page = con->msgr->zero_page;
-                       if (crc)
-                               kaddr = page_address(con->msgr->zero_page);
+                       page = zero_page;
                }
                len = min_t(int, max_write - con->out_msg_pos.page_pos,
                            total_max_write);
 
-               if (crc && !con->out_msg_pos.did_page_crc) {
-                       void *base = kaddr + con->out_msg_pos.page_pos;
+               if (do_datacrc && !con->out_msg_pos.did_page_crc) {
+                       void *base;
+                       u32 crc;
                        u32 tmpcrc = le32_to_cpu(con->out_msg->footer.data_crc);
+                       char *kaddr;
 
+                       kaddr = kmap(page);
                        BUG_ON(kaddr == NULL);
-                       con->out_msg->footer.data_crc =
-                               cpu_to_le32(crc32c(tmpcrc, base, len));
-                       con->out_msg_pos.did_page_crc = 1;
+                       base = kaddr + con->out_msg_pos.page_pos + bio_offset;
+                       crc = crc32c(tmpcrc, base, len);
+                       con->out_msg->footer.data_crc = cpu_to_le32(crc);
+                       con->out_msg_pos.did_page_crc = true;
                }
-               ret = kernel_sendpage(con->sock, page,
-                                     con->out_msg_pos.page_pos + page_shift,
-                                     len,
-                                     MSG_DONTWAIT | MSG_NOSIGNAL |
-                                     MSG_MORE);
-
-               if (crc &&
-                   (msg->pages || msg->pagelist || msg->bio || in_trail))
+               ret = ceph_tcp_sendpage(con->sock, page,
+                                     con->out_msg_pos.page_pos + bio_offset,
+                                     len, 1);
+
+               if (do_datacrc)
                        kunmap(page);
 
-               if (ret == -EAGAIN)
-                       ret = 0;
                if (ret <= 0)
                        goto out;
 
@@ -871,7 +904,7 @@ static int write_partial_msg_pages(struct ceph_connection *con)
                if (ret == len) {
                        con->out_msg_pos.page_pos = 0;
                        con->out_msg_pos.page++;
-                       con->out_msg_pos.did_page_crc = 0;
+                       con->out_msg_pos.did_page_crc = false;
                        if (in_trail)
                                list_move_tail(&page->lru,
                                               &msg->trail->head);
@@ -888,12 +921,10 @@ static int write_partial_msg_pages(struct ceph_connection *con)
        dout("write_partial_msg_pages %p msg %p done\n", con, msg);
 
        /* prepare and queue up footer, too */
-       if (!crc)
+       if (!do_datacrc)
                con->out_msg->footer.flags |= CEPH_MSG_FOOTER_NOCRC;
-       con->out_kvec_bytes = 0;
-       con->out_kvec_left = 0;
-       con->out_kvec_cur = con->out_kvec;
-       prepare_write_message_footer(con, 0);
+       ceph_con_out_kvec_reset(con);
+       prepare_write_message_footer(con);
        ret = 1;
 out:
        return ret;
@@ -907,12 +938,9 @@ static int write_partial_skip(struct ceph_connection *con)
        int ret;
 
        while (con->out_skip > 0) {
-               struct kvec iov = {
-                       .iov_base = page_address(con->msgr->zero_page),
-                       .iov_len = min(con->out_skip, (int)PAGE_CACHE_SIZE)
-               };
+               size_t size = min(con->out_skip, (int) PAGE_CACHE_SIZE);
 
-               ret = ceph_tcp_sendmsg(con->sock, &iov, 1, iov.iov_len, 1);
+               ret = ceph_tcp_sendpage(con->sock, zero_page, 0, size, 1);
                if (ret <= 0)
                        goto out;
                con->out_skip -= ret;
@@ -1085,8 +1113,8 @@ static void addr_set_port(struct sockaddr_storage *ss, int p)
 static int ceph_pton(const char *str, size_t len, struct sockaddr_storage *ss,
                char delim, const char **ipend)
 {
-       struct sockaddr_in *in4 = (void *)ss;
-       struct sockaddr_in6 *in6 = (void *)ss;
+       struct sockaddr_in *in4 = (struct sockaddr_in *) ss;
+       struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) ss;
 
        memset(ss, 0, sizeof(*ss));
 
@@ -1512,10 +1540,9 @@ static int read_partial_message_section(struct ceph_connection *con,
                if (ret <= 0)
                        return ret;
                section->iov_len += ret;
-               if (section->iov_len == sec_len)
-                       *crc = crc32c(0, section->iov_base,
-                                     section->iov_len);
        }
+       if (section->iov_len == sec_len)
+               *crc = crc32c(0, section->iov_base, section->iov_len);
 
        return 1;
 }
@@ -1527,7 +1554,7 @@ static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con,
 
 static int read_partial_message_pages(struct ceph_connection *con,
                                      struct page **pages,
-                                     unsigned data_len, int datacrc)
+                                     unsigned data_len, bool do_datacrc)
 {
        void *p;
        int ret;
@@ -1540,7 +1567,7 @@ static int read_partial_message_pages(struct ceph_connection *con,
        p = kmap(pages[con->in_msg_pos.page]);
        ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos,
                               left);
-       if (ret > 0 && datacrc)
+       if (ret > 0 && do_datacrc)
                con->in_data_crc =
                        crc32c(con->in_data_crc,
                                  p + con->in_msg_pos.page_pos, ret);
@@ -1560,7 +1587,7 @@ static int read_partial_message_pages(struct ceph_connection *con,
 #ifdef CONFIG_BLOCK
 static int read_partial_message_bio(struct ceph_connection *con,
                                    struct bio **bio_iter, int *bio_seg,
-                                   unsigned data_len, int datacrc)
+                                   unsigned data_len, bool do_datacrc)
 {
        struct bio_vec *bv = bio_iovec_idx(*bio_iter, *bio_seg);
        void *p;
@@ -1576,7 +1603,7 @@ static int read_partial_message_bio(struct ceph_connection *con,
 
        ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos,
                               left);
-       if (ret > 0 && datacrc)
+       if (ret > 0 && do_datacrc)
                con->in_data_crc =
                        crc32c(con->in_data_crc,
                                  p + con->in_msg_pos.page_pos, ret);
@@ -1603,9 +1630,10 @@ static int read_partial_message(struct ceph_connection *con)
        int ret;
        int to, left;
        unsigned front_len, middle_len, data_len;
-       int datacrc = con->msgr->nocrc;
+       bool do_datacrc = !con->msgr->nocrc;
        int skip;
        u64 seq;
+       u32 crc;
 
        dout("read_partial_message con %p msg %p\n", con, m);
 
@@ -1618,17 +1646,16 @@ static int read_partial_message(struct ceph_connection *con)
                if (ret <= 0)
                        return ret;
                con->in_base_pos += ret;
-               if (con->in_base_pos == sizeof(con->in_hdr)) {
-                       u32 crc = crc32c(0, (void *)&con->in_hdr,
-                                sizeof(con->in_hdr) - sizeof(con->in_hdr.crc));
-                       if (crc != le32_to_cpu(con->in_hdr.crc)) {
-                               pr_err("read_partial_message bad hdr "
-                                      " crc %u != expected %u\n",
-                                      crc, con->in_hdr.crc);
-                               return -EBADMSG;
-                       }
-               }
        }
+
+       crc = crc32c(0, &con->in_hdr, offsetof(struct ceph_msg_header, crc));
+       if (cpu_to_le32(crc) != con->in_hdr.crc) {
+               pr_err("read_partial_message bad hdr "
+                      " crc %u != expected %u\n",
+                      crc, con->in_hdr.crc);
+               return -EBADMSG;
+       }
+
        front_len = le32_to_cpu(con->in_hdr.front_len);
        if (front_len > CEPH_MSG_MAX_FRONT_LEN)
                return -EIO;
@@ -1714,7 +1741,7 @@ static int read_partial_message(struct ceph_connection *con)
        while (con->in_msg_pos.data_pos < data_len) {
                if (m->pages) {
                        ret = read_partial_message_pages(con, m->pages,
-                                                data_len, datacrc);
+                                                data_len, do_datacrc);
                        if (ret <= 0)
                                return ret;
 #ifdef CONFIG_BLOCK
@@ -1722,7 +1749,7 @@ static int read_partial_message(struct ceph_connection *con)
 
                        ret = read_partial_message_bio(con,
                                                 &m->bio_iter, &m->bio_seg,
-                                                data_len, datacrc);
+                                                data_len, do_datacrc);
                        if (ret <= 0)
                                return ret;
 #endif
@@ -1757,7 +1784,7 @@ static int read_partial_message(struct ceph_connection *con)
                       m, con->in_middle_crc, m->footer.middle_crc);
                return -EBADMSG;
        }
-       if (datacrc &&
+       if (do_datacrc &&
            (m->footer.flags & CEPH_MSG_FOOTER_NOCRC) == 0 &&
            con->in_data_crc != le32_to_cpu(m->footer.data_crc)) {
                pr_err("read_partial_message %p data crc %u != exp. %u\n", m,
@@ -1819,7 +1846,6 @@ more:
 
        /* open the socket first? */
        if (con->sock == NULL) {
-               prepare_write_banner(msgr, con);
                prepare_write_connect(msgr, con, 1);
                prepare_read_banner(con);
                set_bit(CONNECTING, &con->state);
@@ -1829,11 +1855,9 @@ more:
                con->in_tag = CEPH_MSGR_TAG_READY;
                dout("try_write initiating connect on %p new state %lu\n",
                     con, con->state);
-               con->sock = ceph_tcp_connect(con);
-               if (IS_ERR(con->sock)) {
-                       con->sock = NULL;
+               ret = ceph_tcp_connect(con);
+               if (ret < 0) {
                        con->error_msg = "connect error";
-                       ret = -1;
                        goto out;
                }
        }
@@ -1953,8 +1977,9 @@ more:
                 *
                 * FIXME: there must be a better way to do this!
                 */
-               static char buf[1024];
-               int skip = min(1024, -con->in_base_pos);
+               static char buf[SKIP_BUF_SIZE];
+               int skip = min((int) sizeof (buf), -con->in_base_pos);
+
                dout("skipping %d / %d bytes\n", skip, -con->in_base_pos);
                ret = ceph_tcp_recvmsg(con->sock, buf, skip);
                if (ret <= 0)
@@ -2216,15 +2241,6 @@ struct ceph_messenger *ceph_messenger_create(struct ceph_entity_addr *myaddr,
 
        spin_lock_init(&msgr->global_seq_lock);
 
-       /* the zero page is needed if a request is "canceled" while the message
-        * is being written over the socket */
-       msgr->zero_page = __page_cache_alloc(GFP_KERNEL | __GFP_ZERO);
-       if (!msgr->zero_page) {
-               kfree(msgr);
-               return ERR_PTR(-ENOMEM);
-       }
-       kmap(msgr->zero_page);
-
        if (myaddr)
                msgr->inst.addr = *myaddr;
 
@@ -2241,8 +2257,6 @@ EXPORT_SYMBOL(ceph_messenger_create);
 void ceph_messenger_destroy(struct ceph_messenger *msgr)
 {
        dout("destroy %p\n", msgr);
-       kunmap(msgr->zero_page);
-       __free_page(msgr->zero_page);
        kfree(msgr);
        dout("destroyed messenger %p\n", msgr);
 }
index fd863fe76934afb33bbee5583d68028366f23b91..29ad46ec9dcfc1d6de7c680c9555c00f5ac6546e 100644 (file)
@@ -283,7 +283,8 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
                ceph_decode_32_safe(p, end, yes, bad);
 #if BITS_PER_LONG == 32
                err = -EINVAL;
-               if (yes > ULONG_MAX / sizeof(struct crush_rule_step))
+               if (yes > (ULONG_MAX - sizeof(*r))
+                         / sizeof(struct crush_rule_step))
                        goto bad;
 #endif
                r = c->rules[i] = kmalloc(sizeof(*r) +
index 6eb656acdfe53a27680c894b5cd8a6a7222f2db1..a690cae91cdd14641b61844f6ac1f903fbf9666e 100644 (file)
@@ -321,12 +321,12 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
 EXPORT_SYMBOL(__netdev_alloc_skb);
 
 void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
-               int size)
+                    int size, unsigned int truesize)
 {
        skb_fill_page_desc(skb, i, page, off, size);
        skb->len += size;
        skb->data_len += size;
-       skb->truesize += size;
+       skb->truesize += truesize;
 }
 EXPORT_SYMBOL(skb_add_rx_frag);
 
index 24c456e8aa1d3eb615f4b4aa102bf2b166367cf8..496b62712fe8c9c42f15e59d86cfd94bc936e59b 100644 (file)
@@ -2474,8 +2474,12 @@ static int rt6_fill_node(struct net *net,
 
        rcu_read_lock();
        n = dst_get_neighbour_noref(&rt->dst);
-       if (n)
-               NLA_PUT(skb, RTA_GATEWAY, 16, &n->primary_key);
+       if (n) {
+               if (nla_put(skb, RTA_GATEWAY, 16, &n->primary_key) < 0) {
+                       rcu_read_unlock();
+                       goto nla_put_failure;
+               }
+       }
        rcu_read_unlock();
 
        if (rt->dst.dev)
index 7b48035826eeed8b1ae2ad3cefb97024dec84dab..cbdb754dbb10d9a88ab4eef9e1ddf4ff8b3362a6 100644 (file)
@@ -768,8 +768,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
               struct nf_conntrack_l3proto *l3proto,
               struct nf_conntrack_l4proto *l4proto,
               struct sk_buff *skb,
-              unsigned int dataoff, u32 hash,
-              unsigned int *timeouts)
+              unsigned int dataoff, u32 hash)
 {
        struct nf_conn *ct;
        struct nf_conn_help *help;
@@ -777,6 +776,8 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
        struct nf_conntrack_ecache *ecache;
        struct nf_conntrack_expect *exp;
        u16 zone = tmpl ? nf_ct_zone(tmpl) : NF_CT_DEFAULT_ZONE;
+       struct nf_conn_timeout *timeout_ext;
+       unsigned int *timeouts;
 
        if (!nf_ct_invert_tuple(&repl_tuple, tuple, l3proto, l4proto)) {
                pr_debug("Can't invert tuple.\n");
@@ -788,12 +789,21 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
        if (IS_ERR(ct))
                return (struct nf_conntrack_tuple_hash *)ct;
 
+       timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL;
+       if (timeout_ext)
+               timeouts = NF_CT_TIMEOUT_EXT_DATA(timeout_ext);
+       else
+               timeouts = l4proto->get_timeouts(net);
+
        if (!l4proto->new(ct, skb, dataoff, timeouts)) {
                nf_conntrack_free(ct);
                pr_debug("init conntrack: can't track with proto module\n");
                return NULL;
        }
 
+       if (timeout_ext)
+               nf_ct_timeout_ext_add(ct, timeout_ext->timeout, GFP_ATOMIC);
+
        nf_ct_acct_ext_add(ct, GFP_ATOMIC);
        nf_ct_tstamp_ext_add(ct, GFP_ATOMIC);
 
@@ -854,8 +864,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
                  struct nf_conntrack_l3proto *l3proto,
                  struct nf_conntrack_l4proto *l4proto,
                  int *set_reply,
-                 enum ip_conntrack_info *ctinfo,
-                 unsigned int *timeouts)
+                 enum ip_conntrack_info *ctinfo)
 {
        struct nf_conntrack_tuple tuple;
        struct nf_conntrack_tuple_hash *h;
@@ -875,7 +884,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
        h = __nf_conntrack_find_get(net, zone, &tuple, hash);
        if (!h) {
                h = init_conntrack(net, tmpl, &tuple, l3proto, l4proto,
-                                  skb, dataoff, hash, timeouts);
+                                  skb, dataoff, hash);
                if (!h)
                        return NULL;
                if (IS_ERR(h))
@@ -964,19 +973,8 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
                        goto out;
        }
 
-       /* Decide what timeout policy we want to apply to this flow. */
-       if (tmpl) {
-               timeout_ext = nf_ct_timeout_find(tmpl);
-               if (timeout_ext)
-                       timeouts = NF_CT_TIMEOUT_EXT_DATA(timeout_ext);
-               else
-                       timeouts = l4proto->get_timeouts(net);
-       } else
-               timeouts = l4proto->get_timeouts(net);
-
        ct = resolve_normal_ct(net, tmpl, skb, dataoff, pf, protonum,
-                              l3proto, l4proto, &set_reply, &ctinfo,
-                              timeouts);
+                              l3proto, l4proto, &set_reply, &ctinfo);
        if (!ct) {
                /* Not valid part of a connection */
                NF_CT_STAT_INC_ATOMIC(net, invalid);
@@ -993,6 +991,13 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
 
        NF_CT_ASSERT(skb->nfct);
 
+       /* Decide what timeout policy we want to apply to this flow. */
+       timeout_ext = nf_ct_timeout_find(ct);
+       if (timeout_ext)
+               timeouts = NF_CT_TIMEOUT_EXT_DATA(timeout_ext);
+       else
+               timeouts = l4proto->get_timeouts(net);
+
        ret = l4proto->packet(ct, skb, dataoff, ctinfo, pf, hooknum, timeouts);
        if (ret <= 0) {
                /* Invalid: inverse of the return code tells
index 5701c8dd783c02df1ef6d055f473845754e37d30..be3da2c8cdc5803c120b743c9abcceb4b6707fd5 100644 (file)
@@ -127,6 +127,27 @@ void nf_ct_l3proto_module_put(unsigned short l3proto)
 }
 EXPORT_SYMBOL_GPL(nf_ct_l3proto_module_put);
 
+struct nf_conntrack_l4proto *
+nf_ct_l4proto_find_get(u_int16_t l3num, u_int8_t l4num)
+{
+       struct nf_conntrack_l4proto *p;
+
+       rcu_read_lock();
+       p = __nf_ct_l4proto_find(l3num, l4num);
+       if (!try_module_get(p->me))
+               p = &nf_conntrack_l4proto_generic;
+       rcu_read_unlock();
+
+       return p;
+}
+EXPORT_SYMBOL_GPL(nf_ct_l4proto_find_get);
+
+void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p)
+{
+       module_put(p->me);
+}
+EXPORT_SYMBOL_GPL(nf_ct_l4proto_put);
+
 static int kill_l3proto(struct nf_conn *i, void *data)
 {
        return nf_ct_l3num(i) == ((struct nf_conntrack_l3proto *)data)->l3proto;
index fec29a43de4da394085175724a6b39a1ede0e0a8..2b9e79f5ef057295faed0fd7ad81de718763809f 100644 (file)
@@ -98,11 +98,13 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb,
                break;
        }
 
-       l4proto = __nf_ct_l4proto_find(l3num, l4num);
+       l4proto = nf_ct_l4proto_find_get(l3num, l4num);
 
        /* This protocol is not supportted, skip. */
-       if (l4proto->l4proto != l4num)
-               return -EOPNOTSUPP;
+       if (l4proto->l4proto != l4num) {
+               ret = -EOPNOTSUPP;
+               goto err_proto_put;
+       }
 
        if (matching) {
                if (nlh->nlmsg_flags & NLM_F_REPLACE) {
@@ -110,20 +112,25 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb,
                         * different kind, sorry.
                         */
                        if (matching->l3num != l3num ||
-                           matching->l4num != l4num)
-                               return -EINVAL;
+                           matching->l4proto->l4proto != l4num) {
+                               ret = -EINVAL;
+                               goto err_proto_put;
+                       }
 
                        ret = ctnl_timeout_parse_policy(matching, l4proto,
                                                        cda[CTA_TIMEOUT_DATA]);
                        return ret;
                }
-               return -EBUSY;
+               ret = -EBUSY;
+               goto err_proto_put;
        }
 
        timeout = kzalloc(sizeof(struct ctnl_timeout) +
                          l4proto->ctnl_timeout.obj_size, GFP_KERNEL);
-       if (timeout == NULL)
-               return -ENOMEM;
+       if (timeout == NULL) {
+               ret = -ENOMEM;
+               goto err_proto_put;
+       }
 
        ret = ctnl_timeout_parse_policy(timeout, l4proto,
                                        cda[CTA_TIMEOUT_DATA]);
@@ -132,13 +139,15 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb,
 
        strcpy(timeout->name, nla_data(cda[CTA_TIMEOUT_NAME]));
        timeout->l3num = l3num;
-       timeout->l4num = l4num;
+       timeout->l4proto = l4proto;
        atomic_set(&timeout->refcnt, 1);
        list_add_tail_rcu(&timeout->head, &cttimeout_list);
 
        return 0;
 err:
        kfree(timeout);
+err_proto_put:
+       nf_ct_l4proto_put(l4proto);
        return ret;
 }
 
@@ -149,7 +158,7 @@ ctnl_timeout_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
        unsigned int flags = pid ? NLM_F_MULTI : 0;
-       struct nf_conntrack_l4proto *l4proto;
+       struct nf_conntrack_l4proto *l4proto = timeout->l4proto;
 
        event |= NFNL_SUBSYS_CTNETLINK_TIMEOUT << 8;
        nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
@@ -163,20 +172,10 @@ ctnl_timeout_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
 
        NLA_PUT_STRING(skb, CTA_TIMEOUT_NAME, timeout->name);
        NLA_PUT_BE16(skb, CTA_TIMEOUT_L3PROTO, htons(timeout->l3num));
-       NLA_PUT_U8(skb, CTA_TIMEOUT_L4PROTO, timeout->l4num);
+       NLA_PUT_U8(skb, CTA_TIMEOUT_L4PROTO, timeout->l4proto->l4proto);
        NLA_PUT_BE32(skb, CTA_TIMEOUT_USE,
                        htonl(atomic_read(&timeout->refcnt)));
 
-       l4proto = __nf_ct_l4proto_find(timeout->l3num, timeout->l4num);
-
-       /* If the timeout object does not match the layer 4 protocol tracker,
-        * then skip dumping the data part since we don't know how to
-        * interpret it. This may happen for UPDlite, SCTP and DCCP since
-        * you can unload the module.
-        */
-       if (timeout->l4num != l4proto->l4proto)
-               goto out;
-
        if (likely(l4proto->ctnl_timeout.obj_to_nlattr)) {
                struct nlattr *nest_parms;
                int ret;
@@ -192,7 +191,7 @@ ctnl_timeout_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
 
                nla_nest_end(skb, nest_parms);
        }
-out:
+
        nlmsg_end(skb, nlh);
        return skb->len;
 
@@ -293,6 +292,7 @@ static int ctnl_timeout_try_del(struct ctnl_timeout *timeout)
        if (atomic_dec_and_test(&timeout->refcnt)) {
                /* We are protected by nfnl mutex. */
                list_del_rcu(&timeout->head);
+               nf_ct_l4proto_put(timeout->l4proto);
                kfree_rcu(timeout, rcu_head);
        } else {
                /* still in use, restore reference counter. */
@@ -417,6 +417,7 @@ static void __exit cttimeout_exit(void)
                /* We are sure that our objects have no clients at this point,
                 * it's safe to release them all without checking refcnt.
                 */
+               nf_ct_l4proto_put(cur->l4proto);
                kfree_rcu(cur, rcu_head);
        }
 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
index b873445df444e6230965bc8ec3c544b94d4236c0..0c8e43810ce363190c2c49477a3490ee6a077191 100644 (file)
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_CT.h>
 #include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_helper.h>
 #include <net/netfilter/nf_conntrack_ecache.h>
+#include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_timeout.h>
 #include <net/netfilter/nf_conntrack_zones.h>
 
@@ -217,50 +219,59 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
                struct ctnl_timeout *timeout;
                struct nf_conn_timeout *timeout_ext;
 
+               rcu_read_lock();
                timeout_find_get =
                        rcu_dereference(nf_ct_timeout_find_get_hook);
 
                if (timeout_find_get) {
                        const struct ipt_entry *e = par->entryinfo;
+                       struct nf_conntrack_l4proto *l4proto;
 
                        if (e->ip.invflags & IPT_INV_PROTO) {
                                ret = -EINVAL;
                                pr_info("You cannot use inversion on "
                                         "L4 protocol\n");
-                               goto err3;
+                               goto err4;
                        }
                        timeout = timeout_find_get(info->timeout);
                        if (timeout == NULL) {
                                ret = -ENOENT;
                                pr_info("No such timeout policy \"%s\"\n",
                                        info->timeout);
-                               goto err3;
+                               goto err4;
                        }
                        if (timeout->l3num != par->family) {
                                ret = -EINVAL;
                                pr_info("Timeout policy `%s' can only be "
                                        "used by L3 protocol number %d\n",
                                        info->timeout, timeout->l3num);
-                               goto err3;
+                               goto err4;
                        }
-                       if (timeout->l4num != e->ip.proto) {
+                       /* Make sure the timeout policy matches any existing
+                        * protocol tracker, otherwise default to generic.
+                        */
+                       l4proto = __nf_ct_l4proto_find(par->family,
+                                                      e->ip.proto);
+                       if (timeout->l4proto->l4proto != l4proto->l4proto) {
                                ret = -EINVAL;
                                pr_info("Timeout policy `%s' can only be "
                                        "used by L4 protocol number %d\n",
-                                       info->timeout, timeout->l4num);
-                               goto err3;
+                                       info->timeout,
+                                       timeout->l4proto->l4proto);
+                               goto err4;
                        }
                        timeout_ext = nf_ct_timeout_ext_add(ct, timeout,
                                                            GFP_KERNEL);
                        if (timeout_ext == NULL) {
                                ret = -ENOMEM;
-                               goto err3;
+                               goto err4;
                        }
                } else {
                        ret = -ENOENT;
                        pr_info("Timeout policy base is empty\n");
-                       goto err3;
+                       goto err4;
                }
+               rcu_read_unlock();
        }
 #endif
 
@@ -270,6 +281,8 @@ out:
        info->ct = ct;
        return 0;
 
+err4:
+       rcu_read_unlock();
 err3:
        nf_conntrack_free(ct);
 err2:
@@ -311,6 +324,7 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par)
                nf_ct_l3proto_module_put(par->family);
 
 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
+               rcu_read_lock();
                timeout_put = rcu_dereference(nf_ct_timeout_put_hook);
 
                if (timeout_put) {
@@ -318,6 +332,7 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par)
                        if (timeout_ext)
                                timeout_put(timeout_ext->timeout);
                }
+               rcu_read_unlock();
 #endif
        }
        nf_ct_put(info->ct);
index f99f8dee238b9394ab40c4e9308c30dfbcc4d229..ff5f75fddb15175c408a1e0a1cf8a656453aff80 100644 (file)
@@ -480,7 +480,7 @@ ipt_log_packet(u_int8_t pf,
        sb_close(m);
 }
 
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
 /* One level of recursion won't kill us */
 static void dump_ipv6_packet(struct sbuff *m,
                        const struct nf_loginfo *info,
@@ -824,7 +824,7 @@ log_tg(struct sk_buff *skb, const struct xt_action_param *par)
        if (par->family == NFPROTO_IPV4)
                ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in,
                               par->out, &li, loginfo->prefix);
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
        else if (par->family == NFPROTO_IPV6)
                ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in,
                                par->out, &li, loginfo->prefix);
@@ -864,7 +864,7 @@ static struct xt_target log_tg_regs[] __read_mostly = {
                .checkentry     = log_tg_check,
                .me             = THIS_MODULE,
        },
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
        {
                .name           = "LOG",
                .family         = NFPROTO_IPV6,
@@ -882,7 +882,7 @@ static struct nf_logger ipt_log_logger __read_mostly = {
        .me             = THIS_MODULE,
 };
 
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
 static struct nf_logger ip6t_log_logger __read_mostly = {
        .name           = "ip6t_LOG",
        .logfn          = &ip6t_log_packet,
@@ -899,7 +899,7 @@ static int __init log_tg_init(void)
                return ret;
 
        nf_log_register(NFPROTO_IPV4, &ipt_log_logger);
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
        nf_log_register(NFPROTO_IPV6, &ip6t_log_logger);
 #endif
        return 0;
@@ -908,7 +908,7 @@ static int __init log_tg_init(void)
 static void __exit log_tg_exit(void)
 {
        nf_log_unregister(&ipt_log_logger);
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
        nf_log_unregister(&ip6t_log_logger);
 #endif
        xt_unregister_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs));
index 41063e7592d2392b231c42cf86b4144d5f7a34b4..7b6792a18c051a94438493c55513f0c47c4d3483 100644 (file)
@@ -61,4 +61,12 @@ config SAMPLE_KDB
          Build an example of how to dynamically add the hello
          command to the kdb shell.
 
+config SAMPLE_RPMSG_CLIENT
+       tristate "Build rpmsg client sample -- loadable modules only"
+       depends on RPMSG && m
+       help
+         Build an rpmsg client sample driver, which demonstrates how
+         to communicate with an AMP-configured remote processor over
+         the rpmsg bus.
+
 endif # SAMPLES
index 6280817c2b7e84594a40650cb19753b50c255840..2f75851ec6294a2a694931336458057856a94094 100644 (file)
@@ -1,4 +1,4 @@
 # Makefile for Linux samples code
 
 obj-$(CONFIG_SAMPLES)  += kobject/ kprobes/ tracepoints/ trace_events/ \
-                          hw_breakpoint/ kfifo/ kdb/ hidraw/
+                          hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/
diff --git a/samples/rpmsg/Makefile b/samples/rpmsg/Makefile
new file mode 100644 (file)
index 0000000..2d4973c
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_SAMPLE_RPMSG_CLIENT) += rpmsg_client_sample.o
diff --git a/samples/rpmsg/rpmsg_client_sample.c b/samples/rpmsg/rpmsg_client_sample.c
new file mode 100644 (file)
index 0000000..23ea9f2
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Remote processor messaging - sample client driver
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rpmsg.h>
+
+#define MSG            "hello world!"
+#define MSG_LIMIT      100
+
+static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data, int len,
+                                               void *priv, u32 src)
+{
+       int ret;
+       static int rx_count;
+
+       dev_info(&rpdev->dev, "incoming msg %d (src: 0x%x)\n", ++rx_count, src);
+
+       print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 16, 1,
+                      data, len,  true);
+
+       /* samples should not live forever */
+       if (rx_count >= MSG_LIMIT) {
+               dev_info(&rpdev->dev, "goodbye!\n");
+               return;
+       }
+
+       /* send a new message now */
+       ret = rpmsg_send(rpdev, MSG, strlen(MSG));
+       if (ret)
+               dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
+}
+
+static int rpmsg_sample_probe(struct rpmsg_channel *rpdev)
+{
+       int ret;
+
+       dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
+                                       rpdev->src, rpdev->dst);
+
+       /* send a message to our remote processor */
+       ret = rpmsg_send(rpdev, MSG, strlen(MSG));
+       if (ret) {
+               dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static void __devexit rpmsg_sample_remove(struct rpmsg_channel *rpdev)
+{
+       dev_info(&rpdev->dev, "rpmsg sample client driver is removed\n");
+}
+
+static struct rpmsg_device_id rpmsg_driver_sample_id_table[] = {
+       { .name = "rpmsg-client-sample" },
+       { },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_sample_id_table);
+
+static struct rpmsg_driver rpmsg_sample_client = {
+       .drv.name       = KBUILD_MODNAME,
+       .drv.owner      = THIS_MODULE,
+       .id_table       = rpmsg_driver_sample_id_table,
+       .probe          = rpmsg_sample_probe,
+       .callback       = rpmsg_sample_cb,
+       .remove         = __devexit_p(rpmsg_sample_remove),
+};
+
+static int __init rpmsg_client_sample_init(void)
+{
+       return register_rpmsg_driver(&rpmsg_sample_client);
+}
+module_init(rpmsg_client_sample_init);
+
+static void __exit rpmsg_client_sample_fini(void)
+{
+       unregister_rpmsg_driver(&rpmsg_sample_client);
+}
+module_exit(rpmsg_client_sample_fini);
+
+MODULE_DESCRIPTION("Remote processor messaging sample client driver");
+MODULE_LICENSE("GPL v2");
index a839494c5ea888b110e194db9dffeab31e7f1323..601df809a26a857bbcc4c007e72afcab99138fd8 100644 (file)
@@ -80,13 +80,13 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
                return -ENOMEM;
 
        if (audmux_clk)
-               clk_enable(audmux_clk);
+               clk_prepare_enable(audmux_clk);
 
        ptcr = readl(audmux_base + IMX_AUDMUX_V2_PTCR(port));
        pdcr = readl(audmux_base + IMX_AUDMUX_V2_PDCR(port));
 
        if (audmux_clk)
-               clk_disable(audmux_clk);
+               clk_disable_unprepare(audmux_clk);
 
        ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
                       pdcr, ptcr);
@@ -237,13 +237,13 @@ int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
                return -ENOSYS;
 
        if (audmux_clk)
-               clk_enable(audmux_clk);
+               clk_prepare_enable(audmux_clk);
 
        writel(ptcr, audmux_base + IMX_AUDMUX_V2_PTCR(port));
        writel(pdcr, audmux_base + IMX_AUDMUX_V2_PDCR(port));
 
        if (audmux_clk)
-               clk_disable(audmux_clk);
+               clk_disable_unprepare(audmux_clk);
 
        return 0;
 }
index 49fe63ce51f7443d63d6f3f962cd72fb172dd221..7d4fa8ed669919d792fecf4fc79277dd0a4cb519 100644 (file)
@@ -426,29 +426,6 @@ static struct snd_soc_ops ams_delta_ops = {
 };
 
 
-/* Board specific codec bias level control */
-static int ams_delta_set_bias_level(struct snd_soc_card *card,
-                                   struct snd_soc_dapm_context *dapm,
-                                   enum snd_soc_bias_level level)
-{
-       switch (level) {
-       case SND_SOC_BIAS_ON:
-       case SND_SOC_BIAS_PREPARE:
-       case SND_SOC_BIAS_STANDBY:
-               if (card->dapm.bias_level == SND_SOC_BIAS_OFF)
-                       ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET,
-                                               AMS_DELTA_LATCH2_MODEM_NRESET);
-               break;
-       case SND_SOC_BIAS_OFF:
-               if (card->dapm.bias_level != SND_SOC_BIAS_OFF)
-                       ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET,
-                                               0);
-       }
-       card->dapm.bias_level = level;
-
-       return 0;
-}
-
 /* Digital mute implemented using modem/CPU multiplexer.
  * Shares hardware with codec config pulse generation */
 static bool ams_delta_muted = 1;
@@ -512,9 +489,6 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
                ams_delta_ops.shutdown = ams_delta_shutdown;
        }
 
-       /* Set codec bias level */
-       ams_delta_set_bias_level(card, dapm, SND_SOC_BIAS_STANDBY);
-
        /* Add hook switch - can be used to control the codec from userspace
         * even if line discipline fails */
        ret = snd_soc_jack_new(rtd->codec, "hook_switch",
@@ -598,7 +572,6 @@ static struct snd_soc_card ams_delta_audio_card = {
        .owner = THIS_MODULE,
        .dai_link = &ams_delta_dai_link,
        .num_links = 1,
-       .set_bias_level = ams_delta_set_bias_level,
 };
 
 /* Module init/exit */
@@ -635,7 +608,7 @@ err:
        platform_device_put(ams_delta_audio_platform_device);
        return ret;
 }
-module_init(ams_delta_module_init);
+late_initcall(ams_delta_module_init);
 
 static void __exit ams_delta_module_exit(void)
 {
@@ -647,11 +620,6 @@ static void __exit ams_delta_module_exit(void)
                        ARRAY_SIZE(ams_delta_hook_switch_gpios),
                        ams_delta_hook_switch_gpios);
 
-       /* Keep modem power on */
-       ams_delta_set_bias_level(&ams_delta_audio_card,
-                                &ams_delta_audio_card.rtd[0].codec->dapm,
-                                SND_SOC_BIAS_STANDBY);
-
        platform_device_unregister(cx20442_platform_device);
        platform_device_unregister(ams_delta_audio_platform_device);
 }
index f3417f2311b819bd4a3eb5590b26c338c162de05..fe3995ce9b380f00674d0841e29269fdf422d1eb 100644 (file)
@@ -1,8 +1,8 @@
 config SND_SOC_SAMSUNG
        tristate "ASoC support for Samsung"
-       depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_EXYNOS4
+       depends on ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_EXYNOS4
        select S3C64XX_DMA if ARCH_S3C64XX
-       select S3C2410_DMA if ARCH_S3C2410
+       select S3C2410_DMA if ARCH_S3C24XX
        help
          Say Y or M if you want to add support for codecs attached to
          the Samsung SoCs' Audio interfaces. You will also need to
@@ -84,7 +84,7 @@ config SND_SOC_SAMSUNG_SMDK2443_WM9710
 
 config SND_SOC_SAMSUNG_LN2440SBC_ALC650
        tristate "SoC AC97 Audio support for LN2440SBC - ALC650"
-       depends on SND_SOC_SAMSUNG && ARCH_S3C2410
+       depends on SND_SOC_SAMSUNG && ARCH_S3C24XX
        select S3C2410_DMA
        select AC97_BUS
        select SND_SOC_AC97_CODEC
@@ -95,7 +95,7 @@ config SND_SOC_SAMSUNG_LN2440SBC_ALC650
 
 config SND_SOC_SAMSUNG_S3C24XX_UDA134X
        tristate "SoC I2S Audio support UDA134X wired to a S3C24XX"
-       depends on SND_SOC_SAMSUNG && ARCH_S3C2410
+       depends on SND_SOC_SAMSUNG && ARCH_S3C24XX
        select SND_S3C24XX_I2S
        select SND_SOC_L3
        select SND_SOC_UDA134X
@@ -107,14 +107,14 @@ config SND_SOC_SAMSUNG_SIMTEC
 
 config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23
        tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards"
-       depends on SND_SOC_SAMSUNG && ARCH_S3C2410
+       depends on SND_SOC_SAMSUNG && ARCH_S3C24XX
        select SND_S3C24XX_I2S
        select SND_SOC_TLV320AIC23
        select SND_SOC_SAMSUNG_SIMTEC
 
 config SND_SOC_SAMSUNG_SIMTEC_HERMES
        tristate "SoC I2S Audio support for Simtec Hermes board"
-       depends on SND_SOC_SAMSUNG && ARCH_S3C2410
+       depends on SND_SOC_SAMSUNG && ARCH_S3C24XX
        select SND_S3C24XX_I2S
        select SND_SOC_TLV320AIC3X
        select SND_SOC_SAMSUNG_SIMTEC
diff --git a/tools/virtio/linux/hrtimer.h b/tools/virtio/linux/hrtimer.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tools/virtio/linux/module.h b/tools/virtio/linux/module.h
new file mode 100644 (file)
index 0000000..e69de29
index b4fbc91c41b47dd4ab2a06157594c32b14bdd2aa..7579f19e61e00ed240a8e9af108b9075ca7b7002 100644 (file)
@@ -181,6 +181,9 @@ struct virtqueue {
 #define smp_mb()       mb()
 # define smp_rmb()     barrier()
 # define smp_wmb()     barrier()
+/* Weak barriers should be used. If not - it's a bug */
+# define rmb() abort()
+# define wmb() abort()
 #else
 #error Please fill in barrier macros
 #endif