summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-s3c24xx
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-s3c24xx')
-rw-r--r--arch/arm/mach-s3c24xx/Kconfig596
-rw-r--r--arch/arm/mach-s3c24xx/Makefile100
-rw-r--r--arch/arm/mach-s3c24xx/Makefile.boot9
-rw-r--r--arch/arm/mach-s3c24xx/anubis.h50
-rw-r--r--arch/arm/mach-s3c24xx/bast-ide.c81
-rw-r--r--arch/arm/mach-s3c24xx/bast-irq.c139
-rw-r--r--arch/arm/mach-s3c24xx/bast.h194
-rw-r--r--arch/arm/mach-s3c24xx/common-smdk.c206
-rw-r--r--arch/arm/mach-s3c24xx/common-smdk.h11
-rw-r--r--arch/arm/mach-s3c24xx/common.c671
-rw-r--r--arch/arm/mach-s3c24xx/common.h126
-rw-r--r--arch/arm/mach-s3c24xx/cpufreq-utils.c62
-rw-r--r--arch/arm/mach-s3c24xx/fb-core.h24
-rw-r--r--arch/arm/mach-s3c24xx/gta02.h20
-rw-r--r--arch/arm/mach-s3c24xx/h1940-bluetooth.c141
-rw-r--r--arch/arm/mach-s3c24xx/h1940.h52
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/dma.h51
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/fb.h2
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/gpio-samsung.h101
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/hardware.h21
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/io.h212
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/irqs.h213
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/map.h157
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/pm-core.h98
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/regs-clock.h144
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/regs-gpio.h606
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/regs-irq.h49
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/regs-lcd.h157
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/regs-s3c2443-clock.h188
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/rtc-core.h23
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/s3c2412.h23
-rw-r--r--arch/arm/mach-s3c24xx/iotiming-s3c2410.c472
-rw-r--r--arch/arm/mach-s3c24xx/iotiming-s3c2412.c278
-rw-r--r--arch/arm/mach-s3c24xx/irq-pm.c115
-rw-r--r--arch/arm/mach-s3c24xx/mach-amlm5900.c231
-rw-r--r--arch/arm/mach-s3c24xx/mach-anubis.c429
-rw-r--r--arch/arm/mach-s3c24xx/mach-at2440evb.c217
-rw-r--r--arch/arm/mach-s3c24xx/mach-bast.c590
-rw-r--r--arch/arm/mach-s3c24xx/mach-gta02.c588
-rw-r--r--arch/arm/mach-s3c24xx/mach-h1940.c750
-rw-r--r--arch/arm/mach-s3c24xx/mach-jive.c678
-rw-r--r--arch/arm/mach-s3c24xx/mach-mini2440.c714
-rw-r--r--arch/arm/mach-s3c24xx/mach-n30.c609
-rw-r--r--arch/arm/mach-s3c24xx/mach-nexcoder.c158
-rw-r--r--arch/arm/mach-s3c24xx/mach-osiris-dvs.c178
-rw-r--r--arch/arm/mach-s3c24xx/mach-osiris.c412
-rw-r--r--arch/arm/mach-s3c24xx/mach-otom.c120
-rw-r--r--arch/arm/mach-s3c24xx/mach-qt2410.c351
-rw-r--r--arch/arm/mach-s3c24xx/mach-rx1950.c822
-rw-r--r--arch/arm/mach-s3c24xx/mach-rx3715.c213
-rw-r--r--arch/arm/mach-s3c24xx/mach-s3c2416-dt.c48
-rw-r--r--arch/arm/mach-s3c24xx/mach-smdk2410.c108
-rw-r--r--arch/arm/mach-s3c24xx/mach-smdk2413.c158
-rw-r--r--arch/arm/mach-s3c24xx/mach-smdk2416.c259
-rw-r--r--arch/arm/mach-s3c24xx/mach-smdk2440.c183
-rw-r--r--arch/arm/mach-s3c24xx/mach-smdk2443.c139
-rw-r--r--arch/arm/mach-s3c24xx/mach-tct_hammer.c143
-rw-r--r--arch/arm/mach-s3c24xx/mach-vr1000.c338
-rw-r--r--arch/arm/mach-s3c24xx/mach-vstms.c164
-rw-r--r--arch/arm/mach-s3c24xx/nand-core.h24
-rw-r--r--arch/arm/mach-s3c24xx/osiris.h50
-rw-r--r--arch/arm/mach-s3c24xx/otom.h25
-rw-r--r--arch/arm/mach-s3c24xx/pll-s3c2410.c83
-rw-r--r--arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c95
-rw-r--r--arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c122
-rw-r--r--arch/arm/mach-s3c24xx/pm-h1940.S20
-rw-r--r--arch/arm/mach-s3c24xx/pm-s3c2410.c171
-rw-r--r--arch/arm/mach-s3c24xx/pm-s3c2412.c126
-rw-r--r--arch/arm/mach-s3c24xx/pm-s3c2416.c81
-rw-r--r--arch/arm/mach-s3c24xx/pm.c121
-rw-r--r--arch/arm/mach-s3c24xx/regs-dsc.h22
-rw-r--r--arch/arm/mach-s3c24xx/regs-mem.h51
-rw-r--r--arch/arm/mach-s3c24xx/s3c2410.c131
-rw-r--r--arch/arm/mach-s3c24xx/s3c2412-power.h34
-rw-r--r--arch/arm/mach-s3c24xx/s3c2412.c177
-rw-r--r--arch/arm/mach-s3c24xx/s3c2416.c132
-rw-r--r--arch/arm/mach-s3c24xx/s3c2440.c72
-rw-r--r--arch/arm/mach-s3c24xx/s3c2442.c63
-rw-r--r--arch/arm/mach-s3c24xx/s3c2443.c110
-rw-r--r--arch/arm/mach-s3c24xx/s3c244x.c130
-rw-r--r--arch/arm/mach-s3c24xx/setup-camif.c67
-rw-r--r--arch/arm/mach-s3c24xx/setup-i2c.c23
-rw-r--r--arch/arm/mach-s3c24xx/setup-sdhci-gpio.c30
-rw-r--r--arch/arm/mach-s3c24xx/setup-spi.c27
-rw-r--r--arch/arm/mach-s3c24xx/setup-ts.c27
-rw-r--r--arch/arm/mach-s3c24xx/simtec-audio.c71
-rw-r--r--arch/arm/mach-s3c24xx/simtec-nor.c74
-rw-r--r--arch/arm/mach-s3c24xx/simtec-pm.c62
-rw-r--r--arch/arm/mach-s3c24xx/simtec-usb.c125
-rw-r--r--arch/arm/mach-s3c24xx/simtec.h17
-rw-r--r--arch/arm/mach-s3c24xx/sleep-s3c2410.S55
-rw-r--r--arch/arm/mach-s3c24xx/sleep-s3c2412.S54
-rw-r--r--arch/arm/mach-s3c24xx/sleep.S70
-rw-r--r--arch/arm/mach-s3c24xx/spi-core.h27
-rw-r--r--arch/arm/mach-s3c24xx/vr1000.h113
95 files changed, 16674 insertions, 0 deletions
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
new file mode 100644
index 000000000..686f0bbde
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -0,0 +1,596 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (c) 2012 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Copyright 2007 Simtec Electronics
+
+if ARCH_S3C24XX
+
+config PLAT_S3C24XX
+ def_bool y
+ select GPIOLIB
+ select NO_IOPORT_MAP
+ select S3C_DEV_NAND
+ select IRQ_DOMAIN
+ select COMMON_CLK
+ help
+ Base platform code for any Samsung S3C24XX device
+
+
+
+menu "SAMSUNG S3C24XX SoCs Support"
+
+comment "S3C24XX SoCs"
+
+config CPU_S3C2410
+ bool "SAMSUNG S3C2410"
+ default y
+ select CPU_ARM920T
+ select S3C2410_COMMON_CLK
+ select ARM_S3C2410_CPUFREQ if ARM_S3C24XX_CPUFREQ
+ select S3C2410_PM if PM
+ help
+ Support for S3C2410 and S3C2410A family from the S3C24XX line
+ of Samsung Mobile CPUs.
+
+config CPU_S3C2412
+ bool "SAMSUNG S3C2412"
+ select CPU_ARM926T
+ select S3C2412_COMMON_CLK
+ select S3C2412_PM if PM_SLEEP
+ help
+ Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
+
+config CPU_S3C2416
+ bool "SAMSUNG S3C2416/S3C2450"
+ select CPU_ARM926T
+ select S3C2416_PM if PM_SLEEP
+ select S3C2443_COMMON_CLK
+ help
+ Support for the S3C2416 SoC from the S3C24XX line
+
+config CPU_S3C2440
+ bool "SAMSUNG S3C2440"
+ select CPU_ARM920T
+ select S3C2410_COMMON_CLK
+ select S3C2410_PM if PM_SLEEP
+ help
+ Support for S3C2440 Samsung Mobile CPU based systems.
+
+config CPU_S3C2442
+ bool "SAMSUNG S3C2442"
+ select CPU_ARM920T
+ select S3C2410_COMMON_CLK
+ select S3C2410_PM if PM_SLEEP
+ 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"
+ select CPU_ARM920T
+ select S3C2443_COMMON_CLK
+ 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.
+
+config S3C2410_PM
+ bool
+ help
+ Power Management code common to S3C2410 and better
+
+config S3C24XX_PLL
+ bool "Support CPUfreq changing of PLL frequency (EXPERIMENTAL)"
+ depends on ARM_S3C24XX_CPUFREQ
+ help
+ Compile in support for changing the PLL frequency from the
+ S3C24XX series CPUfreq driver. The PLL takes time to settle
+ after a frequency change, so by default it is not enabled.
+
+ This also means that the PLL tables for the selected CPU(s) will
+ be built which may increase the size of the kernel image.
+
+config S3C_SETUP_CAMIF
+ bool
+ help
+ Compile in common setup code for S3C CAMIF devices
+
+# cpu frequency items common between s3c2410 and s3c2440/s3c2442
+
+config S3C2410_IOTIMING
+ bool
+ depends on ARM_S3C24XX_CPUFREQ
+ help
+ Internal node to select io timing code that is common to the s3c2410
+ and s3c2440/s3c2442 cpu frequency support.
+
+config S3C2410_CPUFREQ_UTILS
+ bool
+ depends on ARM_S3C24XX_CPUFREQ
+ help
+ Internal node to select timing code that is common to the s3c2410
+ and s3c2440/s3c244 cpu frequency support.
+
+# cpu frequency support common to s3c2412, s3c2413 and s3c2442
+
+config S3C2412_IOTIMING
+ bool
+ depends on ARM_S3C24XX_CPUFREQ && (CPU_S3C2412 || CPU_S3C2443)
+ help
+ Intel node to select io timing code that is common to the s3c2412
+ and the s3c2443.
+
+# cpu-specific sections
+
+if CPU_S3C2410
+
+config S3C2410_PLL
+ bool
+ depends on ARM_S3C2410_CPUFREQ && S3C24XX_PLL
+ default y
+ help
+ Select the PLL table for the S3C2410
+
+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 ISA
+ select MACH_BAST_IDE
+ select S3C2410_COMMON_DCLK
+ select S3C2410_IOTIMING if ARM_S3C2410_CPUFREQ
+ select S3C24XX_SIMTEC_NOR
+ select S3C24XX_SIMTEC_PM if PM
+ select S3C24XX_SIMTEC_USB
+ select S3C_DEV_HWMON
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ 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 S3C24XX_SETUP_TS
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ 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
+ depends on RFKILL
+ help
+ This is a simple driver that is able to control
+ the state of built in bluetooth chip on h1940.
+
+config MACH_N30
+ bool "Acer N30 family"
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ 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_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the Nex Vision OTOM board
+
+config MACH_QT2410
+ bool "QT2410"
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the Armzone QT2410
+
+config ARCH_SMDK2410
+ bool "SMDK2410/A9M2410"
+ select S3C24XX_SMDK
+ select S3C_DEV_USB_HOST
+ 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 MACH_BAST_IDE
+ select S3C2410_COMMON_DCLK
+ select S3C24XX_SIMTEC_NOR
+ select S3C24XX_SIMTEC_PM if PM
+ select S3C24XX_SIMTEC_USB
+ select S3C_DEV_USB_HOST
+ 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 !CPU_S3C2410 && !CPU_S3C2416 && !CPU_S3C2440 && \
+ !CPU_S3C2442 && !CPU_S3C2443
+ default y
+
+config S3C2412_PM
+ bool
+ select S3C2412_PM_SLEEP
+ select SAMSUNG_WAKEMASK
+ 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_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the Logitech Jive.
+
+config MACH_JIVE_SHOW_BOOTLOADER
+ bool "Allow access to bootloader partitions in MTD"
+ depends on MACH_JIVE
+
+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_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using an SMDK2413
+
+config MACH_VSTMS
+ bool "VMSTMS"
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ 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
+ select SAMSUNG_WAKEMASK
+ 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 S3C2416_SETUP_SDHCI
+ select S3C24XX_SMDK
+ select S3C_DEV_FB
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using an SMDK2416
+
+config MACH_S3C2416_DT
+ bool "Samsung S3C2416 machine using devicetree"
+ select TIMER_OF
+ select USE_OF
+ select PINCTRL
+ select PINCTRL_S3C24XX
+ help
+ Machine support for Samsung S3C2416 machines with device tree enabled.
+ Select this if a fdt blob is available for the S3C2416 SoC based board.
+ Note: This is under development and not all peripherals can be supported
+ with this machine file.
+
+endif # CPU_S3C2416
+
+if CPU_S3C2440 || CPU_S3C2442
+
+config S3C2440_XTAL_12000000
+ bool
+ help
+ Indicate that the build needs to support 12MHz system
+ crystal.
+
+config S3C2440_XTAL_16934400
+ bool
+ help
+ Indicate that the build needs to support 16.9344MHz system
+ crystal.
+
+config S3C2440_PLL_12000000
+ bool
+ depends on ARM_S3C2440_CPUFREQ && S3C2440_XTAL_12000000
+ default y if S3C24XX_PLL
+ help
+ PLL tables for S3C2440 or S3C2442 CPUs with 12MHz crystals.
+
+config S3C2440_PLL_16934400
+ bool
+ depends on ARM_S3C2440_CPUFREQ && S3C2440_XTAL_16934400
+ default y if S3C24XX_PLL
+ help
+ PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals.
+endif
+
+if CPU_S3C2440
+
+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 HAVE_PATA_PLATFORM
+ select S3C2410_COMMON_DCLK
+ select S3C2440_XTAL_12000000
+ select S3C24XX_SIMTEC_PM if PM
+ 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_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the AT2440EVB development board
+
+config MACH_MINI2440
+ bool "MINI2440 development board"
+ select LEDS_CLASS
+ select LEDS_TRIGGERS
+ select LEDS_TRIGGER_BACKLIGHT
+ select NEW_LEDS
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ select S3C_SETUP_CAMIF
+ 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_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
+
+config MACH_OSIRIS
+ bool "Simtec IM2440D20 (OSIRIS) module"
+ select S3C2410_COMMON_DCLK
+ select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
+ select S3C2440_XTAL_12000000
+ select S3C24XX_SIMTEC_PM if PM
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ 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
+ depends on 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 PM_H1940 if PM
+ select S3C2440_XTAL_16934400
+ 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_NAND
+ select S3C_DEV_USB_HOST
+ 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 I2C
+ select MFD_PCF50633
+ select PCF50633_GPIO
+ select POWER_SUPPLY
+ select S3C24XX_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 I2C
+ select PM_H1940 if PM
+ select S3C2410_COMMON_DCLK
+ select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
+ select S3C2440_XTAL_16934400
+ select S3C24XX_PWM
+ select S3C_DEV_NAND
+ help
+ Say Y here if you're using HP iPAQ rx1950
+
+endif # CPU_S3C2442
+
+if CPU_S3C2443 || CPU_S3C2416
+
+config S3C2443_SETUP_SPI
+ bool
+ help
+ Common setup code for SPI GPIO configurations
+
+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
+
+config PM_H1940
+ bool
+ help
+ Internal node for H1940 and related PM
+
+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
index 000000000..6692f2de7
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -0,0 +1,100 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (c) 2012 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Copyright 2007 Simtec Electronics
+
+# core
+
+obj-y += common.o
+
+obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
+obj-$(CONFIG_S3C2410_PLL) += pll-s3c2410.o
+obj-$(CONFIG_S3C2410_PM) += pm-s3c2410.o sleep-s3c2410.o
+
+obj-$(CONFIG_CPU_S3C2412) += s3c2412.o
+obj-$(CONFIG_S3C2412_PM) += pm-s3c2412.o
+obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep-s3c2412.o
+
+obj-$(CONFIG_CPU_S3C2416) += s3c2416.o
+obj-$(CONFIG_S3C2416_PM) += pm-s3c2416.o
+
+obj-$(CONFIG_CPU_S3C2440) += s3c2440.o
+obj-$(CONFIG_CPU_S3C2442) += s3c2442.o
+obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
+obj-$(CONFIG_S3C2440_PLL_12000000) += pll-s3c2440-12000000.o
+obj-$(CONFIG_S3C2440_PLL_16934400) += pll-s3c2440-16934400.o
+
+obj-$(CONFIG_CPU_S3C2443) += s3c2443.o
+
+# PM
+
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_PM_SLEEP) += irq-pm.o sleep.o
+
+# common code
+
+obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += cpufreq-utils.o
+
+obj-$(CONFIG_S3C2410_IOTIMING) += iotiming-s3c2410.o
+obj-$(CONFIG_S3C2412_IOTIMING) += iotiming-s3c2412.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_S3C2416_DT) += mach-s3c2416-dt.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_S3C2443_SETUP_SPI) += setup-spi.o
+obj-$(CONFIG_ARCH_S3C24XX) += setup-i2c.o
+obj-$(CONFIG_S3C24XX_SETUP_TS) += setup-ts.o
+obj-$(CONFIG_S3C_SETUP_CAMIF) += setup-camif.o
diff --git a/arch/arm/mach-s3c24xx/Makefile.boot b/arch/arm/mach-s3c24xx/Makefile.boot
new file mode 100644
index 000000000..7f19e2260
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/Makefile.boot
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.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-s3c24xx/anubis.h b/arch/arm/mach-s3c24xx/anubis.h
new file mode 100644
index 000000000..13847292e
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/anubis.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2005 Simtec Electronics
+ * http://www.simtec.co.uk/products/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * ANUBIS - CPLD control constants
+ * ANUBIS - IRQ Number definitions
+ * ANUBIS - Memory map definitions
+ */
+
+#ifndef __MACH_S3C24XX_ANUBIS_H
+#define __MACH_S3C24XX_ANUBIS_H __FILE__
+
+/* CTRL2 - NAND WP control, IDE Reset assert/check */
+
+#define ANUBIS_CTRL1_NANDSEL (0x3)
+
+/* IDREG - revision */
+
+#define ANUBIS_IDREG_REVMASK (0x7)
+
+/* irq */
+
+#define ANUBIS_IRQ_IDE0 IRQ_EINT2
+#define ANUBIS_IRQ_IDE1 IRQ_EINT3
+#define ANUBIS_IRQ_ASIX IRQ_EINT1
+
+/* map */
+
+/* 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)
+#define ANUBIS_PA_CTRL1 ANUBIS_PA_CPLD
+
+#define ANUBIS_VA_IDREG ANUBIS_IOADDR(0x00300000)
+#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 /* __MACH_S3C24XX_ANUBIS_H */
diff --git a/arch/arm/mach-s3c24xx/bast-ide.c b/arch/arm/mach-s3c24xx/bast-ide.c
new file mode 100644
index 000000000..067944398
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/bast-ide.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright 2007 Simtec Electronics
+// http://www.simtec.co.uk/products/EB2410ITX/
+// http://armlinux.simtec.co.uk/
+// Ben Dooks <ben@simtec.co.uk>
+
+#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 "bast.h"
+
+/* IDE ports */
+
+static struct pata_platform_info bast_ide_platdata = {
+ .ioport_shift = 5,
+};
+
+static struct resource bast_ide0_resource[] = {
+ [0] = DEFINE_RES_MEM(BAST_IDE_CS + BAST_PA_IDEPRI, 8 * 0x20),
+ [1] = DEFINE_RES_MEM(BAST_IDE_CS + BAST_PA_IDEPRIAUX + (6 * 0x20), 0x20),
+ [2] = DEFINE_RES_IRQ(BAST_IRQ_IDE0),
+};
+
+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] = DEFINE_RES_MEM(BAST_IDE_CS + BAST_PA_IDESEC, 8 * 0x20),
+ [1] = DEFINE_RES_MEM(BAST_IDE_CS + BAST_PA_IDESECAUX + (6 * 0x20), 0x20),
+ [2] = DEFINE_RES_IRQ(BAST_IRQ_IDE1),
+};
+
+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
index 000000000..03728058d
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/bast-irq.c
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright 2003-2005 Simtec Electronics
+// Ben Dooks <ben@simtec.co.uk>
+//
+// http://www.simtec.co.uk/products/EB2410ITX/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-irq.h>
+
+#include "bast.h"
+
+#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 const 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 const 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 + BAST_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(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 + BAST_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(BAST_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);
+ irq_clear_status_flags(irqno, IRQ_NOREQUEST);
+ }
+ }
+
+ return 0;
+}
+
+arch_initcall(bast_irq_init);
diff --git a/arch/arm/mach-s3c24xx/bast.h b/arch/arm/mach-s3c24xx/bast.h
new file mode 100644
index 000000000..a7726f93f
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/bast.h
@@ -0,0 +1,194 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2003-2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * BAST - CPLD control constants
+ * BAST - IRQ Number definitions
+ * BAST - Memory map definitions
+ */
+
+#ifndef __MACH_S3C24XX_BAST_H
+#define __MACH_S3C24XX_BAST_H __FILE__
+
+/* 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)
+#define BAST_CPLD_DMA0_SECIDE (1)
+#define BAST_CPLD_DMA0_ISA15 (2)
+#define BAST_CPLD_DMA0_ISA36 (3)
+
+#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)
+
+/* irq numbers to onboard peripherals */
+
+#define BAST_IRQ_USBOC IRQ_EINT18
+#define BAST_IRQ_IDE0 IRQ_EINT16
+#define BAST_IRQ_IDE1 IRQ_EINT17
+#define BAST_IRQ_PCSERIAL1 IRQ_EINT15
+#define BAST_IRQ_PCSERIAL2 IRQ_EINT14
+#define BAST_IRQ_PCPARALLEL IRQ_EINT13
+#define BAST_IRQ_ASIX IRQ_EINT11
+#define BAST_IRQ_DM9000 IRQ_EINT10
+#define BAST_IRQ_ISA IRQ_EINT9
+#define BAST_IRQ_SMALERT IRQ_EINT8
+
+/* map */
+
+/*
+ * 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.
+ */
+
+#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)
+#define BAST_PA_CTRL1 (S3C2410_CS5 | 0x7800000)
+
+#define BAST_VA_CTRL2 BAST_IOADDR(0x00100000)
+#define BAST_PA_CTRL2 (S3C2410_CS1 | 0x6000000)
+
+#define BAST_VA_CTRL3 BAST_IOADDR(0x00200000)
+#define BAST_PA_CTRL3 (S3C2410_CS1 | 0x6800000)
+
+#define BAST_VA_CTRL4 BAST_IOADDR(0x00300000)
+#define BAST_PA_CTRL4 (S3C2410_CS1 | 0x7000000)
+
+/* next, we have the PC104 ISA interrupt registers */
+
+#define BAST_PA_PC104_IRQREQ (S3C2410_CS5 | 0x6000000)
+#define BAST_VA_PC104_IRQREQ BAST_IOADDR(0x00400000)
+
+#define BAST_PA_PC104_IRQRAW (S3C2410_CS5 | 0x6800000)
+#define BAST_VA_PC104_IRQRAW BAST_IOADDR(0x00500000)
+
+#define BAST_PA_PC104_IRQMASK (S3C2410_CS5 | 0x7000000)
+#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
+ * whether 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_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_DM9000_CS BAST_VAM_CS4
+
+#define BAST_IDE_CS S3C2410_CS5
+
+#endif /* __MACH_S3C24XX_BAST_H */
diff --git a/arch/arm/mach-s3c24xx/common-smdk.c b/arch/arm/mach-s3c24xx/common-smdk.c
new file mode 100644
index 000000000..58e30cad3
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/common-smdk.c
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2006 Simtec Electronics
+// Ben Dooks <ben@simtec.co.uk>
+//
+// Common code for SMDK2410 and SMDK2440 boards
+//
+// http://www.fluff.org/ben/smdk2440/
+
+#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/rawnand.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/gpio-samsung.h>
+#include <linux/platform_data/leds-s3c24xx.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <plat/pm.h>
+
+#include "common-smdk.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,
+ .ecc_mode = NAND_ECC_SOFT,
+};
+
+/* devices we initialise */
+
+static struct platform_device __initdata *smdk_devs[] = {
+ &s3c_device_nand,
+ &smdk_led4,
+ &smdk_led5,
+ &smdk_led6,
+ &smdk_led7,
+};
+
+static const struct gpio smdk_led_gpios[] = {
+ { S3C2410_GPF(4), GPIOF_OUT_INIT_HIGH, NULL },
+ { S3C2410_GPF(5), GPIOF_OUT_INIT_HIGH, NULL },
+ { S3C2410_GPF(6), GPIOF_OUT_INIT_HIGH, NULL },
+ { S3C2410_GPF(7), GPIOF_OUT_INIT_HIGH, NULL },
+};
+
+void __init smdk_machine_init(void)
+{
+ /* Configure the LEDs (even if we have no LED support)*/
+
+ int ret = gpio_request_array(smdk_led_gpios,
+ ARRAY_SIZE(smdk_led_gpios));
+ if (!WARN_ON(ret < 0))
+ gpio_free_array(smdk_led_gpios, ARRAY_SIZE(smdk_led_gpios));
+
+ 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/common-smdk.h b/arch/arm/mach-s3c24xx/common-smdk.h
new file mode 100644
index 000000000..c0352b06e
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/common-smdk.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Common code for SMDK2410 and SMDK2440 boards
+ *
+ * http://www.fluff.org/ben/smdk2440/
+ */
+
+extern void smdk_machine_init(void);
diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
new file mode 100644
index 000000000..3dc029c2d
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -0,0 +1,671 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright (c) 2004-2005 Simtec Electronics
+// http://www.simtec.co.uk/products/SWLINUX/
+// Ben Dooks <ben@simtec.co.uk>
+//
+// Common code for S3C24XX machines
+
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <clocksource/samsung_pwm.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/platform_data/dma-s3c24xx.h>
+#include <linux/dmaengine.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-clock.h>
+#include <asm/irq.h>
+#include <asm/cacheflush.h>
+#include <asm/system_info.h>
+#include <asm/system_misc.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/dma.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/cpu-freq.h>
+#include <plat/pwm-core.h>
+
+#include "common.h"
+
+/* table of supported CPUs */
+
+static const char name_s3c2410[] = "S3C2410";
+static const char name_s3c2412[] = "S3C2412";
+static const char name_s3c2416[] = "S3C2416/S3C2450";
+static const char name_s3c2440[] = "S3C2440";
+static const char name_s3c2442[] = "S3C2442";
+static const char name_s3c2442b[] = "S3C2442B";
+static const char name_s3c2443[] = "S3C2443";
+static const char name_s3c2410a[] = "S3C2410A";
+static const char name_s3c2440a[] = "S3C2440A";
+
+static struct cpu_table cpu_ids[] __initdata = {
+ {
+ .idcode = 0x32410000,
+ .idmask = 0xffffffff,
+ .map_io = s3c2410_map_io,
+ .init_uarts = s3c2410_init_uarts,
+ .init = s3c2410_init,
+ .name = name_s3c2410
+ },
+ {
+ .idcode = 0x32410002,
+ .idmask = 0xffffffff,
+ .map_io = s3c2410_map_io,
+ .init_uarts = s3c2410_init_uarts,
+ .init = s3c2410a_init,
+ .name = name_s3c2410a
+ },
+ {
+ .idcode = 0x32440000,
+ .idmask = 0xffffffff,
+ .map_io = s3c2440_map_io,
+ .init_uarts = s3c244x_init_uarts,
+ .init = s3c2440_init,
+ .name = name_s3c2440
+ },
+ {
+ .idcode = 0x32440001,
+ .idmask = 0xffffffff,
+ .map_io = s3c2440_map_io,
+ .init_uarts = s3c244x_init_uarts,
+ .init = s3c2440_init,
+ .name = name_s3c2440a
+ },
+ {
+ .idcode = 0x32440aaa,
+ .idmask = 0xffffffff,
+ .map_io = s3c2442_map_io,
+ .init_uarts = s3c244x_init_uarts,
+ .init = s3c2442_init,
+ .name = name_s3c2442
+ },
+ {
+ .idcode = 0x32440aab,
+ .idmask = 0xffffffff,
+ .map_io = s3c2442_map_io,
+ .init_uarts = s3c244x_init_uarts,
+ .init = s3c2442_init,
+ .name = name_s3c2442b
+ },
+ {
+ .idcode = 0x32412001,
+ .idmask = 0xffffffff,
+ .map_io = s3c2412_map_io,
+ .init_uarts = s3c2412_init_uarts,
+ .init = s3c2412_init,
+ .name = name_s3c2412,
+ },
+ { /* a newer version of the s3c2412 */
+ .idcode = 0x32412003,
+ .idmask = 0xffffffff,
+ .map_io = s3c2412_map_io,
+ .init_uarts = s3c2412_init_uarts,
+ .init = s3c2412_init,
+ .name = name_s3c2412,
+ },
+ { /* a strange version of the s3c2416 */
+ .idcode = 0x32450003,
+ .idmask = 0xffffffff,
+ .map_io = s3c2416_map_io,
+ .init_uarts = s3c2416_init_uarts,
+ .init = s3c2416_init,
+ .name = name_s3c2416,
+ },
+ {
+ .idcode = 0x32443001,
+ .idmask = 0xffffffff,
+ .map_io = s3c2443_map_io,
+ .init_uarts = s3c2443_init_uarts,
+ .init = s3c2443_init,
+ .name = name_s3c2443,
+ },
+};
+
+/* minimal IO mapping */
+
+static struct map_desc s3c_iodesc[] __initdata = {
+ IODESC_ENT(GPIO),
+ IODESC_ENT(IRQ),
+ IODESC_ENT(MEMCTRL),
+ IODESC_ENT(UART)
+};
+
+/* read cpu identificaiton code */
+
+static unsigned long s3c24xx_read_idcode_v5(void)
+{
+#if defined(CONFIG_CPU_S3C2416)
+ /* s3c2416 is v5, with S3C24XX_GSTATUS1 instead of S3C2412_GSTATUS1 */
+
+ u32 gs = __raw_readl(S3C24XX_GSTATUS1);
+
+ /* test for s3c2416 or similar device */
+ if ((gs >> 16) == 0x3245)
+ return gs;
+#endif
+
+#if defined(CONFIG_CPU_S3C2412)
+ return __raw_readl(S3C2412_GSTATUS1);
+#else
+ return 1UL; /* don't look like an 2400 */
+#endif
+}
+
+static unsigned long s3c24xx_read_idcode_v4(void)
+{
+ return __raw_readl(S3C2410_GSTATUS1);
+}
+
+static void s3c24xx_default_idle(void)
+{
+ unsigned long tmp = 0;
+ int i;
+
+ /* idle the system by using the idle mode which will wait for an
+ * interrupt to happen before restarting the system.
+ */
+
+ /* Warning: going into idle state upsets jtag scanning */
+
+ __raw_writel(__raw_readl(S3C2410_CLKCON) | S3C2410_CLKCON_IDLE,
+ S3C2410_CLKCON);
+
+ /* the samsung port seems to do a loop and then unset idle.. */
+ for (i = 0; i < 50; i++)
+ tmp += __raw_readl(S3C2410_CLKCON); /* ensure loop not optimised out */
+
+ /* this bit is not cleared on re-start... */
+
+ __raw_writel(__raw_readl(S3C2410_CLKCON) & ~S3C2410_CLKCON_IDLE,
+ S3C2410_CLKCON);
+}
+
+static struct samsung_pwm_variant s3c24xx_pwm_variant = {
+ .bits = 16,
+ .div_base = 1,
+ .has_tint_cstat = false,
+ .tclk_mask = (1 << 4),
+};
+
+void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
+{
+ arm_pm_idle = s3c24xx_default_idle;
+
+ /* initialise the io descriptors we need for initialisation */
+ iotable_init(mach_desc, size);
+ iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
+
+ if (cpu_architecture() >= CPU_ARCH_ARMv5) {
+ samsung_cpu_id = s3c24xx_read_idcode_v5();
+ } else {
+ samsung_cpu_id = s3c24xx_read_idcode_v4();
+ }
+
+ s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+ samsung_pwm_set_platdata(&s3c24xx_pwm_variant);
+}
+
+void __init samsung_set_timer_source(unsigned int event, unsigned int source)
+{
+ s3c24xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+ s3c24xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
+}
+
+void __init samsung_timer_init(void)
+{
+ unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
+ IRQ_TIMER0, IRQ_TIMER1, IRQ_TIMER2, IRQ_TIMER3, IRQ_TIMER4,
+ };
+
+ samsung_pwm_clocksource_init(S3C_VA_TIMER,
+ timer_irqs, &s3c24xx_pwm_variant);
+}
+
+/* Serial port registrations */
+
+#define S3C2410_PA_UART0 (S3C24XX_PA_UART)
+#define S3C2410_PA_UART1 (S3C24XX_PA_UART + 0x4000 )
+#define S3C2410_PA_UART2 (S3C24XX_PA_UART + 0x8000 )
+#define S3C2443_PA_UART3 (S3C24XX_PA_UART + 0xC000 )
+
+static struct resource s3c2410_uart0_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2410_PA_UART0, SZ_16K),
+ [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX0, \
+ IRQ_S3CUART_ERR0 - IRQ_S3CUART_RX0 + 1, \
+ NULL, IORESOURCE_IRQ)
+};
+
+static struct resource s3c2410_uart1_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2410_PA_UART1, SZ_16K),
+ [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX1, \
+ IRQ_S3CUART_ERR1 - IRQ_S3CUART_RX1 + 1, \
+ NULL, IORESOURCE_IRQ)
+};
+
+static struct resource s3c2410_uart2_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2410_PA_UART2, SZ_16K),
+ [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX2, \
+ IRQ_S3CUART_ERR2 - IRQ_S3CUART_RX2 + 1, \
+ NULL, IORESOURCE_IRQ)
+};
+
+static struct resource s3c2410_uart3_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2443_PA_UART3, SZ_16K),
+ [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX3, \
+ IRQ_S3CUART_ERR3 - IRQ_S3CUART_RX3 + 1, \
+ NULL, IORESOURCE_IRQ)
+};
+
+struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
+ [0] = {
+ .resources = s3c2410_uart0_resource,
+ .nr_resources = ARRAY_SIZE(s3c2410_uart0_resource),
+ },
+ [1] = {
+ .resources = s3c2410_uart1_resource,
+ .nr_resources = ARRAY_SIZE(s3c2410_uart1_resource),
+ },
+ [2] = {
+ .resources = s3c2410_uart2_resource,
+ .nr_resources = ARRAY_SIZE(s3c2410_uart2_resource),
+ },
+ [3] = {
+ .resources = s3c2410_uart3_resource,
+ .nr_resources = ARRAY_SIZE(s3c2410_uart3_resource),
+ },
+};
+
+#define s3c24xx_device_dma_mask (*((u64[]) { DMA_BIT_MASK(32) }))
+
+#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \
+ defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
+static struct resource s3c2410_dma_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C24XX_PA_DMA, S3C24XX_SZ_DMA),
+ [1] = DEFINE_RES_IRQ(IRQ_DMA0),
+ [2] = DEFINE_RES_IRQ(IRQ_DMA1),
+ [3] = DEFINE_RES_IRQ(IRQ_DMA2),
+ [4] = DEFINE_RES_IRQ(IRQ_DMA3),
+};
+#endif
+
+#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2442)
+static struct s3c24xx_dma_channel s3c2410_dma_channels[DMACH_MAX] = {
+ [DMACH_XD0] = { S3C24XX_DMA_AHB, true, S3C24XX_DMA_CHANREQ(0, 0), },
+ [DMACH_XD1] = { S3C24XX_DMA_AHB, true, S3C24XX_DMA_CHANREQ(0, 1), },
+ [DMACH_SDI] = { S3C24XX_DMA_APB, false, S3C24XX_DMA_CHANREQ(2, 0) |
+ S3C24XX_DMA_CHANREQ(2, 2) |
+ S3C24XX_DMA_CHANREQ(1, 3),
+ },
+ [DMACH_SPI0] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(3, 1), },
+ [DMACH_SPI1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(2, 3), },
+ [DMACH_UART0] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(1, 0), },
+ [DMACH_UART1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(1, 1), },
+ [DMACH_UART2] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(0, 3), },
+ [DMACH_TIMER] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(3, 0) |
+ S3C24XX_DMA_CHANREQ(3, 2) |
+ S3C24XX_DMA_CHANREQ(3, 3),
+ },
+ [DMACH_I2S_IN] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(2, 1) |
+ S3C24XX_DMA_CHANREQ(1, 2),
+ },
+ [DMACH_I2S_OUT] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(0, 2), },
+ [DMACH_USB_EP1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 0), },
+ [DMACH_USB_EP2] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 1), },
+ [DMACH_USB_EP3] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 2), },
+ [DMACH_USB_EP4] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 3), },
+};
+
+static const struct dma_slave_map s3c2410_dma_slave_map[] = {
+ { "s3c2410-sdi", "rx-tx", (void *)DMACH_SDI },
+ { "s3c2410-spi.0", "rx", (void *)DMACH_SPI0_RX },
+ { "s3c2410-spi.0", "tx", (void *)DMACH_SPI0_TX },
+ { "s3c2410-spi.1", "rx", (void *)DMACH_SPI1_RX },
+ { "s3c2410-spi.1", "tx", (void *)DMACH_SPI1_TX },
+ /*
+ * The DMA request source[1] (DMACH_UARTx_SRC2) are
+ * not used in the UART driver.
+ */
+ { "s3c2410-uart.0", "rx", (void *)DMACH_UART0 },
+ { "s3c2410-uart.0", "tx", (void *)DMACH_UART0 },
+ { "s3c2410-uart.1", "rx", (void *)DMACH_UART1 },
+ { "s3c2410-uart.1", "tx", (void *)DMACH_UART1 },
+ { "s3c2410-uart.2", "rx", (void *)DMACH_UART2 },
+ { "s3c2410-uart.2", "tx", (void *)DMACH_UART2 },
+ { "s3c24xx-iis", "rx", (void *)DMACH_I2S_IN },
+ { "s3c24xx-iis", "tx", (void *)DMACH_I2S_OUT },
+ { "s3c-hsudc", "rx0", (void *)DMACH_USB_EP1 },
+ { "s3c-hsudc", "tx0", (void *)DMACH_USB_EP1 },
+ { "s3c-hsudc", "rx1", (void *)DMACH_USB_EP2 },
+ { "s3c-hsudc", "tx1", (void *)DMACH_USB_EP2 },
+ { "s3c-hsudc", "rx2", (void *)DMACH_USB_EP3 },
+ { "s3c-hsudc", "tx2", (void *)DMACH_USB_EP3 },
+ { "s3c-hsudc", "rx3", (void *)DMACH_USB_EP4 },
+ { "s3c-hsudc", "tx3", (void *)DMACH_USB_EP4 }
+};
+
+static struct s3c24xx_dma_platdata s3c2410_dma_platdata = {
+ .num_phy_channels = 4,
+ .channels = s3c2410_dma_channels,
+ .num_channels = DMACH_MAX,
+ .slave_map = s3c2410_dma_slave_map,
+ .slavecnt = ARRAY_SIZE(s3c2410_dma_slave_map),
+};
+
+struct platform_device s3c2410_device_dma = {
+ .name = "s3c2410-dma",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c2410_dma_resource),
+ .resource = s3c2410_dma_resource,
+ .dev = {
+ .dma_mask = &s3c24xx_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s3c2410_dma_platdata,
+ },
+};
+#endif
+
+#ifdef CONFIG_CPU_S3C2412
+static struct s3c24xx_dma_channel s3c2412_dma_channels[DMACH_MAX] = {
+ [DMACH_XD0] = { S3C24XX_DMA_AHB, true, 17 },
+ [DMACH_XD1] = { S3C24XX_DMA_AHB, true, 18 },
+ [DMACH_SDI] = { S3C24XX_DMA_APB, false, 10 },
+ [DMACH_SPI0_RX] = { S3C24XX_DMA_APB, true, 1 },
+ [DMACH_SPI0_TX] = { S3C24XX_DMA_APB, true, 0 },
+ [DMACH_SPI1_RX] = { S3C24XX_DMA_APB, true, 3 },
+ [DMACH_SPI1_TX] = { S3C24XX_DMA_APB, true, 2 },
+ [DMACH_UART0] = { S3C24XX_DMA_APB, true, 19 },
+ [DMACH_UART1] = { S3C24XX_DMA_APB, true, 21 },
+ [DMACH_UART2] = { S3C24XX_DMA_APB, true, 23 },
+ [DMACH_UART0_SRC2] = { S3C24XX_DMA_APB, true, 20 },
+ [DMACH_UART1_SRC2] = { S3C24XX_DMA_APB, true, 22 },
+ [DMACH_UART2_SRC2] = { S3C24XX_DMA_APB, true, 24 },
+ [DMACH_TIMER] = { S3C24XX_DMA_APB, true, 9 },
+ [DMACH_I2S_IN] = { S3C24XX_DMA_APB, true, 5 },
+ [DMACH_I2S_OUT] = { S3C24XX_DMA_APB, true, 4 },
+ [DMACH_USB_EP1] = { S3C24XX_DMA_APB, true, 13 },
+ [DMACH_USB_EP2] = { S3C24XX_DMA_APB, true, 14 },
+ [DMACH_USB_EP3] = { S3C24XX_DMA_APB, true, 15 },
+ [DMACH_USB_EP4] = { S3C24XX_DMA_APB, true, 16 },
+};
+
+static const struct dma_slave_map s3c2412_dma_slave_map[] = {
+ { "s3c2412-sdi", "rx-tx", (void *)DMACH_SDI },
+ { "s3c2412-spi.0", "rx", (void *)DMACH_SPI0_RX },
+ { "s3c2412-spi.0", "tx", (void *)DMACH_SPI0_TX },
+ { "s3c2412-spi.1", "rx", (void *)DMACH_SPI1_RX },
+ { "s3c2412-spi.1", "tx", (void *)DMACH_SPI1_TX },
+ { "s3c2440-uart.0", "rx", (void *)DMACH_UART0 },
+ { "s3c2440-uart.0", "tx", (void *)DMACH_UART0 },
+ { "s3c2440-uart.1", "rx", (void *)DMACH_UART1 },
+ { "s3c2440-uart.1", "tx", (void *)DMACH_UART1 },
+ { "s3c2440-uart.2", "rx", (void *)DMACH_UART2 },
+ { "s3c2440-uart.2", "tx", (void *)DMACH_UART2 },
+ { "s3c2412-iis", "rx", (void *)DMACH_I2S_IN },
+ { "s3c2412-iis", "tx", (void *)DMACH_I2S_OUT },
+ { "s3c-hsudc", "rx0", (void *)DMACH_USB_EP1 },
+ { "s3c-hsudc", "tx0", (void *)DMACH_USB_EP1 },
+ { "s3c-hsudc", "rx1", (void *)DMACH_USB_EP2 },
+ { "s3c-hsudc", "tx1", (void *)DMACH_USB_EP2 },
+ { "s3c-hsudc", "rx2", (void *)DMACH_USB_EP3 },
+ { "s3c-hsudc", "tx2", (void *)DMACH_USB_EP3 },
+ { "s3c-hsudc", "rx3", (void *)DMACH_USB_EP4 },
+ { "s3c-hsudc", "tx3", (void *)DMACH_USB_EP4 }
+};
+
+static struct s3c24xx_dma_platdata s3c2412_dma_platdata = {
+ .num_phy_channels = 4,
+ .channels = s3c2412_dma_channels,
+ .num_channels = DMACH_MAX,
+ .slave_map = s3c2412_dma_slave_map,
+ .slavecnt = ARRAY_SIZE(s3c2412_dma_slave_map),
+};
+
+struct platform_device s3c2412_device_dma = {
+ .name = "s3c2412-dma",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c2410_dma_resource),
+ .resource = s3c2410_dma_resource,
+ .dev = {
+ .dma_mask = &s3c24xx_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s3c2412_dma_platdata,
+ },
+};
+#endif
+
+#if defined(CONFIG_CPU_S3C2440)
+static struct s3c24xx_dma_channel s3c2440_dma_channels[DMACH_MAX] = {
+ [DMACH_XD0] = { S3C24XX_DMA_AHB, true, S3C24XX_DMA_CHANREQ(0, 0), },
+ [DMACH_XD1] = { S3C24XX_DMA_AHB, true, S3C24XX_DMA_CHANREQ(0, 1), },
+ [DMACH_SDI] = { S3C24XX_DMA_APB, false, S3C24XX_DMA_CHANREQ(2, 0) |
+ S3C24XX_DMA_CHANREQ(6, 1) |
+ S3C24XX_DMA_CHANREQ(2, 2) |
+ S3C24XX_DMA_CHANREQ(1, 3),
+ },
+ [DMACH_SPI0] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(3, 1), },
+ [DMACH_SPI1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(2, 3), },
+ [DMACH_UART0] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(1, 0), },
+ [DMACH_UART1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(1, 1), },
+ [DMACH_UART2] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(0, 3), },
+ [DMACH_TIMER] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(3, 0) |
+ S3C24XX_DMA_CHANREQ(3, 2) |
+ S3C24XX_DMA_CHANREQ(3, 3),
+ },
+ [DMACH_I2S_IN] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(2, 1) |
+ S3C24XX_DMA_CHANREQ(1, 2),
+ },
+ [DMACH_I2S_OUT] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(5, 0) |
+ S3C24XX_DMA_CHANREQ(0, 2),
+ },
+ [DMACH_PCM_IN] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(6, 0) |
+ S3C24XX_DMA_CHANREQ(5, 2),
+ },
+ [DMACH_PCM_OUT] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(5, 1) |
+ S3C24XX_DMA_CHANREQ(6, 3),
+ },
+ [DMACH_MIC_IN] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(6, 2) |
+ S3C24XX_DMA_CHANREQ(5, 3),
+ },
+ [DMACH_USB_EP1] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 0), },
+ [DMACH_USB_EP2] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 1), },
+ [DMACH_USB_EP3] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 2), },
+ [DMACH_USB_EP4] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 3), },
+};
+
+static const struct dma_slave_map s3c2440_dma_slave_map[] = {
+ /* TODO: DMACH_XD0 */
+ /* TODO: DMACH_XD1 */
+ { "s3c2440-sdi", "rx-tx", (void *)DMACH_SDI },
+ { "s3c2410-spi.0", "rx", (void *)DMACH_SPI0 },
+ { "s3c2410-spi.0", "tx", (void *)DMACH_SPI0 },
+ { "s3c2410-spi.1", "rx", (void *)DMACH_SPI1 },
+ { "s3c2410-spi.1", "tx", (void *)DMACH_SPI1 },
+ { "s3c2440-uart.0", "rx", (void *)DMACH_UART0 },
+ { "s3c2440-uart.0", "tx", (void *)DMACH_UART0 },
+ { "s3c2440-uart.1", "rx", (void *)DMACH_UART1 },
+ { "s3c2440-uart.1", "tx", (void *)DMACH_UART1 },
+ { "s3c2440-uart.2", "rx", (void *)DMACH_UART2 },
+ { "s3c2440-uart.2", "tx", (void *)DMACH_UART2 },
+ { "s3c2440-uart.3", "rx", (void *)DMACH_UART3 },
+ { "s3c2440-uart.3", "tx", (void *)DMACH_UART3 },
+ /* TODO: DMACH_TIMER */
+ { "s3c24xx-iis", "rx", (void *)DMACH_I2S_IN },
+ { "s3c24xx-iis", "tx", (void *)DMACH_I2S_OUT },
+ { "samsung-ac97", "rx", (void *)DMACH_PCM_IN },
+ { "samsung-ac97", "tx", (void *)DMACH_PCM_OUT },
+ { "samsung-ac97", "rx", (void *)DMACH_MIC_IN },
+ { "s3c-hsudc", "rx0", (void *)DMACH_USB_EP1 },
+ { "s3c-hsudc", "rx1", (void *)DMACH_USB_EP2 },
+ { "s3c-hsudc", "rx2", (void *)DMACH_USB_EP3 },
+ { "s3c-hsudc", "rx3", (void *)DMACH_USB_EP4 },
+ { "s3c-hsudc", "tx0", (void *)DMACH_USB_EP1 },
+ { "s3c-hsudc", "tx1", (void *)DMACH_USB_EP2 },
+ { "s3c-hsudc", "tx2", (void *)DMACH_USB_EP3 },
+ { "s3c-hsudc", "tx3", (void *)DMACH_USB_EP4 }
+};
+
+static struct s3c24xx_dma_platdata s3c2440_dma_platdata = {
+ .num_phy_channels = 4,
+ .channels = s3c2440_dma_channels,
+ .num_channels = DMACH_MAX,
+ .slave_map = s3c2440_dma_slave_map,
+ .slavecnt = ARRAY_SIZE(s3c2440_dma_slave_map),
+};
+
+struct platform_device s3c2440_device_dma = {
+ .name = "s3c2410-dma",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c2410_dma_resource),
+ .resource = s3c2410_dma_resource,
+ .dev = {
+ .dma_mask = &s3c24xx_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s3c2440_dma_platdata,
+ },
+};
+#endif
+
+#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
+static struct resource s3c2443_dma_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C24XX_PA_DMA, S3C24XX_SZ_DMA),
+ [1] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA0),
+ [2] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA1),
+ [3] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA2),
+ [4] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA3),
+ [5] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA4),
+ [6] = DEFINE_RES_IRQ(IRQ_S3C2443_DMA5),
+};
+
+static struct s3c24xx_dma_channel s3c2443_dma_channels[DMACH_MAX] = {
+ [DMACH_XD0] = { S3C24XX_DMA_AHB, true, 17 },
+ [DMACH_XD1] = { S3C24XX_DMA_AHB, true, 18 },
+ [DMACH_SDI] = { S3C24XX_DMA_APB, false, 10 },
+ [DMACH_SPI0_RX] = { S3C24XX_DMA_APB, true, 1 },
+ [DMACH_SPI0_TX] = { S3C24XX_DMA_APB, true, 0 },
+ [DMACH_SPI1_RX] = { S3C24XX_DMA_APB, true, 3 },
+ [DMACH_SPI1_TX] = { S3C24XX_DMA_APB, true, 2 },
+ [DMACH_UART0] = { S3C24XX_DMA_APB, true, 19 },
+ [DMACH_UART1] = { S3C24XX_DMA_APB, true, 21 },
+ [DMACH_UART2] = { S3C24XX_DMA_APB, true, 23 },
+ [DMACH_UART3] = { S3C24XX_DMA_APB, true, 25 },
+ [DMACH_UART0_SRC2] = { S3C24XX_DMA_APB, true, 20 },
+ [DMACH_UART1_SRC2] = { S3C24XX_DMA_APB, true, 22 },
+ [DMACH_UART2_SRC2] = { S3C24XX_DMA_APB, true, 24 },
+ [DMACH_UART3_SRC2] = { S3C24XX_DMA_APB, true, 26 },
+ [DMACH_TIMER] = { S3C24XX_DMA_APB, true, 9 },
+ [DMACH_I2S_IN] = { S3C24XX_DMA_APB, true, 5 },
+ [DMACH_I2S_OUT] = { S3C24XX_DMA_APB, true, 4 },
+ [DMACH_PCM_IN] = { S3C24XX_DMA_APB, true, 28 },
+ [DMACH_PCM_OUT] = { S3C24XX_DMA_APB, true, 27 },
+ [DMACH_MIC_IN] = { S3C24XX_DMA_APB, true, 29 },
+};
+
+static const struct dma_slave_map s3c2443_dma_slave_map[] = {
+ { "s3c2440-sdi", "rx-tx", (void *)DMACH_SDI },
+ { "s3c2443-spi.0", "rx", (void *)DMACH_SPI0_RX },
+ { "s3c2443-spi.0", "tx", (void *)DMACH_SPI0_TX },
+ { "s3c2443-spi.1", "rx", (void *)DMACH_SPI1_RX },
+ { "s3c2443-spi.1", "tx", (void *)DMACH_SPI1_TX },
+ { "s3c2440-uart.0", "rx", (void *)DMACH_UART0 },
+ { "s3c2440-uart.0", "tx", (void *)DMACH_UART0 },
+ { "s3c2440-uart.1", "rx", (void *)DMACH_UART1 },
+ { "s3c2440-uart.1", "tx", (void *)DMACH_UART1 },
+ { "s3c2440-uart.2", "rx", (void *)DMACH_UART2 },
+ { "s3c2440-uart.2", "tx", (void *)DMACH_UART2 },
+ { "s3c2440-uart.3", "rx", (void *)DMACH_UART3 },
+ { "s3c2440-uart.3", "tx", (void *)DMACH_UART3 },
+ { "s3c24xx-iis", "rx", (void *)DMACH_I2S_IN },
+ { "s3c24xx-iis", "tx", (void *)DMACH_I2S_OUT },
+};
+
+static struct s3c24xx_dma_platdata s3c2443_dma_platdata = {
+ .num_phy_channels = 6,
+ .channels = s3c2443_dma_channels,
+ .num_channels = DMACH_MAX,
+ .slave_map = s3c2443_dma_slave_map,
+ .slavecnt = ARRAY_SIZE(s3c2443_dma_slave_map),
+};
+
+struct platform_device s3c2443_device_dma = {
+ .name = "s3c2443-dma",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c2443_dma_resource),
+ .resource = s3c2443_dma_resource,
+ .dev = {
+ .dma_mask = &s3c24xx_device_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s3c2443_dma_platdata,
+ },
+};
+#endif
+
+#if defined(CONFIG_COMMON_CLK) && defined(CONFIG_CPU_S3C2410)
+void __init s3c2410_init_clocks(int xtal)
+{
+ s3c2410_common_clk_init(NULL, xtal, 0, S3C24XX_VA_CLKPWR);
+}
+#endif
+
+#ifdef CONFIG_CPU_S3C2412
+void __init s3c2412_init_clocks(int xtal)
+{
+ s3c2412_common_clk_init(NULL, xtal, 0, S3C24XX_VA_CLKPWR);
+}
+#endif
+
+#ifdef CONFIG_CPU_S3C2416
+void __init s3c2416_init_clocks(int xtal)
+{
+ s3c2443_common_clk_init(NULL, xtal, 0, S3C24XX_VA_CLKPWR);
+}
+#endif
+
+#if defined(CONFIG_COMMON_CLK) && defined(CONFIG_CPU_S3C2440)
+void __init s3c2440_init_clocks(int xtal)
+{
+ s3c2410_common_clk_init(NULL, xtal, 1, S3C24XX_VA_CLKPWR);
+}
+#endif
+
+#if defined(CONFIG_COMMON_CLK) && defined(CONFIG_CPU_S3C2442)
+void __init s3c2442_init_clocks(int xtal)
+{
+ s3c2410_common_clk_init(NULL, xtal, 2, S3C24XX_VA_CLKPWR);
+}
+#endif
+
+#ifdef CONFIG_CPU_S3C2443
+void __init s3c2443_init_clocks(int xtal)
+{
+ s3c2443_common_clk_init(NULL, xtal, 1, S3C24XX_VA_CLKPWR);
+}
+#endif
+
+#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2440) || \
+ defined(CONFIG_CPU_S3C2442)
+static struct resource s3c2410_dclk_resource[] = {
+ [0] = DEFINE_RES_MEM(0x56000084, 0x4),
+};
+
+struct platform_device s3c2410_device_dclk = {
+ .name = "s3c2410-dclk",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c2410_dclk_resource),
+ .resource = s3c2410_dclk_resource,
+};
+#endif
diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h
new file mode 100644
index 000000000..d087b20e8
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/common.h
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Common Header for S3C24XX SoCs
+ */
+
+#ifndef __ARCH_ARM_MACH_S3C24XX_COMMON_H
+#define __ARCH_ARM_MACH_S3C24XX_COMMON_H __FILE__
+
+#include <linux/reboot.h>
+
+struct s3c2410_uartcfg;
+
+#ifdef CONFIG_CPU_S3C2410
+extern int s3c2410_init(void);
+extern int s3c2410a_init(void);
+extern void s3c2410_map_io(void);
+extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s3c2410_init_clocks(int xtal);
+extern void s3c2410_init_irq(void);
+#else
+#define s3c2410_init_clocks NULL
+#define s3c2410_init_uarts NULL
+#define s3c2410_map_io NULL
+#define s3c2410_init NULL
+#define s3c2410a_init NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2412
+extern int s3c2412_init(void);
+extern void s3c2412_map_io(void);
+extern void s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s3c2412_init_clocks(int xtal);
+extern int s3c2412_baseclk_add(void);
+extern void s3c2412_init_irq(void);
+#else
+#define s3c2412_init_clocks NULL
+#define s3c2412_init_uarts NULL
+#define s3c2412_map_io NULL
+#define s3c2412_init NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2416
+extern int s3c2416_init(void);
+extern void s3c2416_map_io(void);
+extern void s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s3c2416_init_clocks(int xtal);
+extern int s3c2416_baseclk_add(void);
+extern void s3c2416_init_irq(void);
+
+extern struct syscore_ops s3c2416_irq_syscore_ops;
+#else
+#define s3c2416_init_clocks NULL
+#define s3c2416_init_uarts NULL
+#define s3c2416_map_io NULL
+#define s3c2416_init NULL
+#endif
+
+#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
+extern void s3c244x_map_io(void);
+extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+#else
+#define s3c244x_init_uarts NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2440
+extern int s3c2440_init(void);
+extern void s3c2440_map_io(void);
+extern void s3c2440_init_clocks(int xtal);
+extern void s3c2440_init_irq(void);
+#else
+#define s3c2440_init NULL
+#define s3c2440_map_io NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2442
+extern int s3c2442_init(void);
+extern void s3c2442_map_io(void);
+extern void s3c2442_init_clocks(int xtal);
+extern void s3c2442_init_irq(void);
+#else
+#define s3c2442_init NULL
+#define s3c2442_map_io NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2443
+extern int s3c2443_init(void);
+extern void s3c2443_map_io(void);
+extern void s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s3c2443_init_clocks(int xtal);
+extern int s3c2443_baseclk_add(void);
+extern void s3c2443_init_irq(void);
+#else
+#define s3c2443_init_clocks NULL
+#define s3c2443_init_uarts NULL
+#define s3c2443_map_io NULL
+#define s3c2443_init NULL
+#endif
+
+extern struct syscore_ops s3c24xx_irq_syscore_ops;
+
+extern struct platform_device s3c2410_device_dma;
+extern struct platform_device s3c2412_device_dma;
+extern struct platform_device s3c2440_device_dma;
+extern struct platform_device s3c2443_device_dma;
+
+extern struct platform_device s3c2410_device_dclk;
+
+#ifdef CONFIG_S3C2410_COMMON_CLK
+void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
+ int current_soc,
+ void __iomem *reg_base);
+#endif
+#ifdef CONFIG_S3C2412_COMMON_CLK
+void __init s3c2412_common_clk_init(struct device_node *np, unsigned long xti_f,
+ unsigned long ext_f, void __iomem *reg_base);
+#endif
+#ifdef CONFIG_S3C2443_COMMON_CLK
+void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
+ int current_soc,
+ void __iomem *reg_base);
+#endif
+
+#endif /* __ARCH_ARM_MACH_S3C24XX_COMMON_H */
diff --git a/arch/arm/mach-s3c24xx/cpufreq-utils.c b/arch/arm/mach-s3c24xx/cpufreq-utils.c
new file mode 100644
index 000000000..1a7f38d08
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/cpufreq-utils.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2009 Simtec Electronics
+// http://armlinux.simtec.co.uk/
+// Ben Dooks <ben@simtec.co.uk>
+//
+// S3C24XX CPU Frequency scaling - utils for S3C2410/S3C2440/S3C2442
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/cpufreq.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu-freq-core.h>
+
+#include "regs-mem.h"
+
+/**
+ * s3c2410_cpufreq_setrefresh - set SDRAM refresh value
+ * @cfg: The frequency configuration
+ *
+ * Set the SDRAM refresh value appropriately for the configured
+ * frequency.
+ */
+void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
+{
+ struct s3c_cpufreq_board *board = cfg->board;
+ unsigned long refresh;
+ unsigned long refval;
+
+ /* Reduce both the refresh time (in ns) and the frequency (in MHz)
+ * down to ensure that we do not overflow 32 bit numbers.
+ *
+ * This should work for HCLK up to 133MHz and refresh period up
+ * to 30usec.
+ */
+
+ refresh = (cfg->freq.hclk / 100) * (board->refresh / 10);
+ refresh = DIV_ROUND_UP(refresh, (1000 * 1000)); /* apply scale */
+ refresh = (1 << 11) + 1 - refresh;
+
+ s3c_freq_dbg("%s: refresh value %lu\n", __func__, refresh);
+
+ refval = __raw_readl(S3C2410_REFRESH);
+ refval &= ~((1 << 12) - 1);
+ refval |= refresh;
+ __raw_writel(refval, S3C2410_REFRESH);
+}
+
+/**
+ * s3c2410_set_fvco - set the PLL value
+ * @cfg: The frequency configuration
+ */
+void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg)
+{
+ if (!IS_ERR(cfg->mpll))
+ clk_set_rate(cfg->mpll, cfg->pll.frequency);
+}
diff --git a/arch/arm/mach-s3c24xx/fb-core.h b/arch/arm/mach-s3c24xx/fb-core.h
new file mode 100644
index 000000000..1821e8202
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/fb-core.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2010 Samsung Electronics Co., Ltd.
+ * Pawel Osciak <p.osciak@samsung.com>
+ *
+ * Samsung framebuffer driver core functions
+ */
+#ifndef __ASM_PLAT_FB_CORE_H
+#define __ASM_PLAT_FB_CORE_H __FILE__
+
+/*
+ * These functions are only for use with the core support code, such as
+ * the CPU-specific initialization code.
+ */
+
+/* Re-define device name depending on support. */
+static inline void s3c_fb_setname(char *name)
+{
+#ifdef CONFIG_S3C_DEV_FB
+ s3c_device_fb.name = name;
+#endif
+}
+
+#endif /* __ASM_PLAT_FB_CORE_H */
diff --git a/arch/arm/mach-s3c24xx/gta02.h b/arch/arm/mach-s3c24xx/gta02.h
new file mode 100644
index 000000000..d5610ba82
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/gta02.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * GTA02 header
+ */
+
+#ifndef __MACH_S3C24XX_GTA02_H
+#define __MACH_S3C24XX_GTA02_H __FILE__
+
+#include <mach/regs-gpio.h>
+
+#define GTA02_GPIO_AUX_LED S3C2410_GPB(2)
+#define GTA02_GPIO_USB_PULLUP S3C2410_GPB(9)
+#define GTA02_GPIO_AUX_KEY S3C2410_GPF(6)
+#define GTA02_GPIO_HOLD_KEY S3C2410_GPF(7)
+#define GTA02_GPIO_AMP_SHUT S3C2410_GPJ(1) /* v2 + v3 + v4 only */
+#define GTA02_GPIO_HP_IN S3C2410_GPJ(2) /* v2 + v3 + v4 only */
+
+#define GTA02_IRQ_PCF50633 IRQ_EINT9
+
+#endif /* __MACH_S3C24XX_GTA02_H */
diff --git a/arch/arm/mach-s3c24xx/h1940-bluetooth.c b/arch/arm/mach-s3c24xx/h1940-bluetooth.c
new file mode 100644
index 000000000..186b53216
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/h1940-bluetooth.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-1.0+
+//
+// Copyright (c) Arnaud Patard <arnaud.patard@rtp-net.org>
+//
+// 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 <plat/gpio-cfg.h>
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include "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(NULL, 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(NULL, 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 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,
+};
+
+module_platform_driver(h1940bt_driver);
+
+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/h1940.h b/arch/arm/mach-s3c24xx/h1940.h
new file mode 100644
index 000000000..5dfe9d10c
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/h1940.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2006 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Copyright (c) 2005 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * iPAQ H1940 series definitions
+ */
+
+#ifndef __MACH_S3C24XX_H1940_H
+#define __MACH_S3C24XX_H1940_H __FILE__
+
+#define H1940_SUSPEND_CHECKSUM (0x30003ff8)
+#define H1940_SUSPEND_RESUMEAT (0x30081000)
+#define H1940_SUSPEND_CHECK (0x30080000)
+
+struct gpio_desc;
+
+extern void h1940_pm_return(void);
+extern int h1940_led_blink_set(struct gpio_desc *desc, int state,
+ unsigned long *delay_on,
+ unsigned long *delay_off);
+
+#include <linux/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 /* __MACH_S3C24XX_H1940_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/dma.h b/arch/arm/mach-s3c24xx/include/mach/dma.h
new file mode 100644
index 000000000..25fc9c258
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/dma.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2003-2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C24XX DMA support
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H __FILE__
+
+#include <linux/device.h>
+
+/* 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 = 0,
+ 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_SPI0_TX, /* s3c2443/2416/2450 hsspi0 */
+ DMACH_SPI0_RX, /* s3c2443/2416/2450 hsspi0 */
+ DMACH_SPI1_TX, /* s3c2443/2450 hsspi1 */
+ DMACH_SPI1_RX, /* s3c2443/2450 hsspi1 */
+ DMACH_MAX, /* the end entry */
+};
+
+#endif /* __ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/fb.h b/arch/arm/mach-s3c24xx/include/mach/fb.h
new file mode 100644
index 000000000..4e539cb8b
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/fb.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <plat/fb-s3c2410.h>
diff --git a/arch/arm/mach-s3c24xx/include/mach/gpio-samsung.h b/arch/arm/mach-s3c24xx/include/mach/gpio-samsung.h
new file mode 100644
index 000000000..2ad22b2d4
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/gpio-samsung.h
@@ -0,0 +1,101 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - GPIO lib support
+ */
+
+/* some boards require extra gpio capacity to support external
+ * devices that need GPIO.
+ */
+
+#ifndef GPIO_SAMSUNG_S3C24XX_H
+#define GPIO_SAMSUNG_S3C24XX_H
+
+/*
+ * GPIO sizes for various SoCs:
+ *
+ * 2410 2412 2440 2443 2416
+ * 2442
+ * ---- ---- ---- ---- ----
+ * A 23 22 25 16 27
+ * B 11 11 11 11 11
+ * C 16 16 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 11 15 15
+ * J -- -- 13 16 --
+ * K -- -- -- -- 16
+ * L -- -- -- 15 14
+ * 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))
+
+#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
+
+#endif /* GPIO_SAMSUNG_S3C24XX_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
index 000000000..1b2975708
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/hardware.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2003 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - hardware
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#ifndef __ASSEMBLY__
+
+extern unsigned int s3c2410_modify_misccr(unsigned int clr, unsigned int chg);
+
+#endif /* __ASSEMBLY__ */
+
+#include <asm/sizes.h>
+#include <mach/map.h>
+
+#endif /* __ASM_ARCH_HARDWARE_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
index 000000000..f960e6d10
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/io.h
@@ -0,0 +1,212 @@
+/* SPDX-License-Identifier: GPL-2.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 *)0 + (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)
+
+#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
index 000000000..aaf3bae08
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/irqs.h
@@ -0,0 +1,213 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2003-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ */
+
+
+#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_EINT0_2412 S3C2410_IRQ(32)
+#define IRQ_EINT1_2412 S3C2410_IRQ(33)
+#define IRQ_EINT2_2412 S3C2410_IRQ(34)
+#define IRQ_EINT3_2412 S3C2410_IRQ(35)
+#define IRQ_EINT4 S3C2410_IRQ(36) /* 52 */
+#define IRQ_EINT5 S3C2410_IRQ(37)
+#define IRQ_EINT6 S3C2410_IRQ(38)
+#define IRQ_EINT7 S3C2410_IRQ(39)
+#define IRQ_EINT8 S3C2410_IRQ(40)
+#define IRQ_EINT9 S3C2410_IRQ(41)
+#define IRQ_EINT10 S3C2410_IRQ(42)
+#define IRQ_EINT11 S3C2410_IRQ(43)
+#define IRQ_EINT12 S3C2410_IRQ(44)
+#define IRQ_EINT13 S3C2410_IRQ(45)
+#define IRQ_EINT14 S3C2410_IRQ(46)
+#define IRQ_EINT15 S3C2410_IRQ(47)
+#define IRQ_EINT16 S3C2410_IRQ(48)
+#define IRQ_EINT17 S3C2410_IRQ(49)
+#define IRQ_EINT18 S3C2410_IRQ(50)
+#define IRQ_EINT19 S3C2410_IRQ(51)
+#define IRQ_EINT20 S3C2410_IRQ(52) /* 68 */
+#define IRQ_EINT21 S3C2410_IRQ(53)
+#define IRQ_EINT22 S3C2410_IRQ(54)
+#define IRQ_EINT23 S3C2410_IRQ(55)
+
+#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(56)
+#define IRQ_LCD_FRAME S3C2410_IRQ(57)
+
+/* 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)+58)
+
+#define IRQ_S3CUART_RX0 S3C2410_IRQSUB(0) /* 74 */
+#define IRQ_S3CUART_TX0 S3C2410_IRQSUB(1)
+#define IRQ_S3CUART_ERR0 S3C2410_IRQSUB(2)
+
+#define IRQ_S3CUART_RX1 S3C2410_IRQSUB(3) /* 77 */
+#define IRQ_S3CUART_TX1 S3C2410_IRQSUB(4)
+#define IRQ_S3CUART_ERR1 S3C2410_IRQSUB(5)
+
+#define IRQ_S3CUART_RX2 S3C2410_IRQSUB(6) /* 80 */
+#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)
+
+/* second interrupt-register of s3c2416/s3c2450 */
+
+#define S3C2416_IRQ(x) S3C2410_IRQ((x) + 58 + 29)
+#define IRQ_S3C2416_2D S3C2416_IRQ(0)
+#define IRQ_S3C2416_IIC1 S3C2416_IRQ(1)
+#define IRQ_S3C2416_RESERVED2 S3C2416_IRQ(2)
+#define IRQ_S3C2416_RESERVED3 S3C2416_IRQ(3)
+#define IRQ_S3C2416_PCM0 S3C2416_IRQ(4)
+#define IRQ_S3C2416_PCM1 S3C2416_IRQ(5)
+#define IRQ_S3C2416_I2S0 S3C2416_IRQ(6)
+#define IRQ_S3C2416_I2S1 S3C2416_IRQ(7)
+
+/* 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_S3C2416)
+#define NR_IRQS (IRQ_S3C2416_I2S1 + 1)
+#else
+#define NR_IRQS (IRQ_S3C2443_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/map.h b/arch/arm/mach-s3c24xx/include/mach/map.h
new file mode 100644
index 000000000..bca93112f
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/map.h
@@ -0,0 +1,157 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2003 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - Memory map definitions
+ */
+
+#ifndef __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H
+
+#include <plat/map-base.h>
+#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
+
+/* 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)
+#define S3C2443_PA_SPI0 (0x52000000)
+#define S3C2443_PA_SPI1 S3C2410_PA_SPI
+
+/* 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_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
+
+#define S3C_PA_SPI0 S3C2443_PA_SPI0
+#define S3C_PA_SPI1 S3C2443_PA_SPI1
+
+#define SAMSUNG_PA_TIMER S3C2410_PA_TIMER
+
+#endif /* __ASM_ARCH_MAP_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
index 000000000..5e4ce89d0
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/pm-core.h
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * 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
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include "regs-clock.h"
+#include "regs-irq.h"
+
+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 */
+}
+
+/* s3c2410_pm_show_resume_irqs
+ *
+ * print any IRQs asserted at resume time (ie, we woke from)
+*/
+static inline void s3c_pm_show_resume_irqs(int start, unsigned long which,
+ unsigned long mask)
+{
+ int i;
+
+ which &= ~mask;
+
+ for (i = 0; i <= 31; i++) {
+ if (which & (1L<<i)) {
+ S3C_PMDBG("IRQ %d asserted at resume\n", start+i);
+ }
+ }
+}
+
+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) { }
+
+/* state for IRQs over sleep */
+
+/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
+ *
+ * set bit to 1 in allow bitfield to enable the wakeup settings on it
+*/
+#ifdef CONFIG_PM_SLEEP
+#define s3c_irqwake_intallow (1L << 30 | 0xfL)
+#define s3c_irqwake_eintallow (0x0000fff0L)
+#else
+#define s3c_irqwake_eintallow 0
+#define s3c_irqwake_intallow 0
+#endif
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
index 000000000..7ca3dd4f1
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/regs-clock.h
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2003-2006 Simtec Electronics <linux@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * 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)
+
+#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)
+
+#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 */
+
+#define S3C2416_CLKDIV2 S3C2410_CLKREG(0x28)
+
+#endif /* __ASM_ARM_REGS_CLOCK */
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
index 000000000..594e967c0
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h
@@ -0,0 +1,606 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2003-2004 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * S3C2410 GPIO register definitions
+ */
+
+
+#ifndef __ASM_ARCH_REGS_GPIO_H
+#define __ASM_ARCH_REGS_GPIO_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 G
+ * 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
+ *
+ * GPHCON has 2 bits for each of the input pins on port H
+ * 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
+*/
+
+/*
+ * Port J consists of 13 GPIO/Camera pins. GPJCON has 2 bits
+ * for each of the pins on port J.
+ * 00 - input, 01 output, 10 - 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)
+
+/* 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)
+
+/* 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 control 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-irq.h b/arch/arm/mach-s3c24xx/include/mach/regs-irq.h
new file mode 100644
index 000000000..8d8e669e3
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/regs-irq.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ */
+
+
+#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
index 000000000..4c3434f26
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/regs-lcd.h
@@ -0,0 +1,157 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ */
+
+#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-s3c2443-clock.h b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2443-clock.h
new file mode 100644
index 000000000..6bf924612
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2443-clock.h
@@ -0,0 +1,188 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2007 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * 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_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/rtc-core.h b/arch/arm/mach-s3c24xx/include/mach/rtc-core.h
new file mode 100644
index 000000000..88510333b
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/rtc-core.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2011 Heiko Stuebner <heiko@sntech.de>
+ *
+ * Samsung RTC Controller core functions
+ */
+
+#ifndef __RTC_CORE_H
+#define __RTC_CORE_H __FILE__
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+ */
+
+extern struct platform_device s3c_device_rtc;
+
+/* re-define device name depending on support. */
+static inline void s3c_rtc_setname(char *name)
+{
+ s3c_device_rtc.name = name;
+}
+
+#endif /* __RTC_CORE_H */
diff --git a/arch/arm/mach-s3c24xx/include/mach/s3c2412.h b/arch/arm/mach-s3c24xx/include/mach/s3c2412.h
new file mode 100644
index 000000000..4ff83f956
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/include/mach/s3c2412.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ */
+
+#ifndef __ARCH_ARM_MACH_S3C24XX_S3C2412_H
+#define __ARCH_ARM_MACH_S3C24XX_S3C2412_H __FILE__
+
+#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_REFRESH S3C2412_MEMREG(0x10)
+
+#define S3C2412_EBI_BANKCFG S3C2412_EBIREG(0x4)
+
+#define S3C2412_SSMC_BANK(x) S3C2412_SSMC(x, 0x0)
+
+#endif /* __ARCH_ARM_MACH_S3C24XX_S3C2412_H */
diff --git a/arch/arm/mach-s3c24xx/iotiming-s3c2410.c b/arch/arm/mach-s3c24xx/iotiming-s3c2410.c
new file mode 100644
index 000000000..9f90aaf70
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/iotiming-s3c2410.c
@@ -0,0 +1,472 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2006-2009 Simtec Electronics
+// http://armlinux.simtec.co.uk/
+// Ben Dooks <ben@simtec.co.uk>
+//
+// S3C24XX CPU Frequency scaling - IO timing for S3C2410/S3C2440/S3C2442
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/cpufreq.h>
+#include <linux/seq_file.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu-freq-core.h>
+
+#include "regs-mem.h"
+
+#define print_ns(x) ((x) / 10), ((x) % 10)
+
+/**
+ * s3c2410_print_timing - print bank timing data for debug purposes
+ * @pfx: The prefix to put on the output
+ * @timings: The timing inforamtion to print.
+*/
+static void s3c2410_print_timing(const char *pfx,
+ struct s3c_iotimings *timings)
+{
+ struct s3c2410_iobank_timing *bt;
+ int bank;
+
+ for (bank = 0; bank < MAX_BANKS; bank++) {
+ bt = timings->bank[bank].io_2410;
+ if (!bt)
+ continue;
+
+ printk(KERN_DEBUG "%s %d: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, "
+ "Tcoh=%d.%d, Tcah=%d.%d\n", pfx, bank,
+ print_ns(bt->tacs),
+ print_ns(bt->tcos),
+ print_ns(bt->tacc),
+ print_ns(bt->tcoh),
+ print_ns(bt->tcah));
+ }
+}
+
+/**
+ * bank_reg - convert bank number to pointer to the control register.
+ * @bank: The IO bank number.
+ */
+static inline void __iomem *bank_reg(unsigned int bank)
+{
+ return S3C2410_BANKCON0 + (bank << 2);
+}
+
+/**
+ * bank_is_io - test whether bank is used for IO
+ * @bankcon: The bank control register.
+ *
+ * This is a simplistic test to see if any BANKCON[x] is not an IO
+ * bank. It currently does not take into account whether BWSCON has
+ * an illegal width-setting in it, or if the pin connected to nCS[x]
+ * is actually being handled as a chip-select.
+ */
+static inline int bank_is_io(unsigned long bankcon)
+{
+ return !(bankcon & S3C2410_BANKCON_SDRAM);
+}
+
+/**
+ * to_div - convert cycle time to divisor
+ * @cyc: The cycle time, in 10ths of nanoseconds.
+ * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
+ *
+ * Convert the given cycle time into the divisor to use to obtain it from
+ * HCLK.
+*/
+static inline unsigned int to_div(unsigned int cyc, unsigned int hclk_tns)
+{
+ if (cyc == 0)
+ return 0;
+
+ return DIV_ROUND_UP(cyc, hclk_tns);
+}
+
+/**
+ * calc_0124 - calculate divisor control for divisors that do /0, /1. /2 and /4
+ * @cyc: The cycle time, in 10ths of nanoseconds.
+ * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
+ * @v: Pointer to register to alter.
+ * @shift: The shift to get to the control bits.
+ *
+ * Calculate the divisor, and turn it into the correct control bits to
+ * set in the result, @v.
+ */
+static unsigned int calc_0124(unsigned int cyc, unsigned long hclk_tns,
+ unsigned long *v, int shift)
+{
+ unsigned int div = to_div(cyc, hclk_tns);
+ unsigned long val;
+
+ s3c_freq_iodbg("%s: cyc=%d, hclk=%lu, shift=%d => div %d\n",
+ __func__, cyc, hclk_tns, shift, div);
+
+ switch (div) {
+ case 0:
+ val = 0;
+ break;
+ case 1:
+ val = 1;
+ break;
+ case 2:
+ val = 2;
+ break;
+ case 3:
+ case 4:
+ val = 3;
+ break;
+ default:
+ return -1;
+ }
+
+ *v |= val << shift;
+ return 0;
+}
+
+int calc_tacp(unsigned int cyc, unsigned long hclk, unsigned long *v)
+{
+ /* Currently no support for Tacp calculations. */
+ return 0;
+}
+
+/**
+ * calc_tacc - calculate divisor control for tacc.
+ * @cyc: The cycle time, in 10ths of nanoseconds.
+ * @nwait_en: IS nWAIT enabled for this bank.
+ * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
+ * @v: Pointer to register to alter.
+ *
+ * Calculate the divisor control for tACC, taking into account whether
+ * the bank has nWAIT enabled. The result is used to modify the value
+ * pointed to by @v.
+*/
+static int calc_tacc(unsigned int cyc, int nwait_en,
+ unsigned long hclk_tns, unsigned long *v)
+{
+ unsigned int div = to_div(cyc, hclk_tns);
+ unsigned long val;
+
+ s3c_freq_iodbg("%s: cyc=%u, nwait=%d, hclk=%lu => div=%u\n",
+ __func__, cyc, nwait_en, hclk_tns, div);
+
+ /* if nWait enabled on an bank, Tacc must be at-least 4 cycles. */
+ if (nwait_en && div < 4)
+ div = 4;
+
+ switch (div) {
+ case 0:
+ val = 0;
+ break;
+
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ val = div - 1;
+ break;
+
+ case 5:
+ case 6:
+ val = 4;
+ break;
+
+ case 7:
+ case 8:
+ val = 5;
+ break;
+
+ case 9:
+ case 10:
+ val = 6;
+ break;
+
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ val = 7;
+ break;
+
+ default:
+ return -1;
+ }
+
+ *v |= val << 8;
+ return 0;
+}
+
+/**
+ * s3c2410_calc_bank - calculate bank timing information
+ * @cfg: The configuration we need to calculate for.
+ * @bt: The bank timing information.
+ *
+ * Given the cycle timine for a bank @bt, calculate the new BANKCON
+ * setting for the @cfg timing. This updates the timing information
+ * ready for the cpu frequency change.
+ */
+static int s3c2410_calc_bank(struct s3c_cpufreq_config *cfg,
+ struct s3c2410_iobank_timing *bt)
+{
+ unsigned long hclk = cfg->freq.hclk_tns;
+ unsigned long res;
+ int ret;
+
+ res = bt->bankcon;
+ res &= (S3C2410_BANKCON_SDRAM | S3C2410_BANKCON_PMC16);
+
+ /* tacp: 2,3,4,5 */
+ /* tcah: 0,1,2,4 */
+ /* tcoh: 0,1,2,4 */
+ /* tacc: 1,2,3,4,6,7,10,14 (>4 for nwait) */
+ /* tcos: 0,1,2,4 */
+ /* tacs: 0,1,2,4 */
+
+ ret = calc_0124(bt->tacs, hclk, &res, S3C2410_BANKCON_Tacs_SHIFT);
+ ret |= calc_0124(bt->tcos, hclk, &res, S3C2410_BANKCON_Tcos_SHIFT);
+ ret |= calc_0124(bt->tcah, hclk, &res, S3C2410_BANKCON_Tcah_SHIFT);
+ ret |= calc_0124(bt->tcoh, hclk, &res, S3C2410_BANKCON_Tcoh_SHIFT);
+
+ if (ret)
+ return -EINVAL;
+
+ ret |= calc_tacp(bt->tacp, hclk, &res);
+ ret |= calc_tacc(bt->tacc, bt->nwait_en, hclk, &res);
+
+ if (ret)
+ return -EINVAL;
+
+ bt->bankcon = res;
+ return 0;
+}
+
+static const unsigned int tacc_tab[] = {
+ [0] = 1,
+ [1] = 2,
+ [2] = 3,
+ [3] = 4,
+ [4] = 6,
+ [5] = 9,
+ [6] = 10,
+ [7] = 14,
+};
+
+/**
+ * get_tacc - turn tACC value into cycle time
+ * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
+ * @val: The bank timing register value, shifed down.
+ */
+static unsigned int get_tacc(unsigned long hclk_tns,
+ unsigned long val)
+{
+ val &= 7;
+ return hclk_tns * tacc_tab[val];
+}
+
+/**
+ * get_0124 - turn 0/1/2/4 divider into cycle time
+ * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
+ * @val: The bank timing register value, shifed down.
+ */
+static unsigned int get_0124(unsigned long hclk_tns,
+ unsigned long val)
+{
+ val &= 3;
+ return hclk_tns * ((val == 3) ? 4 : val);
+}
+
+/**
+ * s3c2410_iotiming_getbank - turn BANKCON into cycle time information
+ * @cfg: The frequency configuration
+ * @bt: The bank timing to fill in (uses cached BANKCON)
+ *
+ * Given the BANKCON setting in @bt and the current frequency settings
+ * in @cfg, update the cycle timing information.
+ */
+void s3c2410_iotiming_getbank(struct s3c_cpufreq_config *cfg,
+ struct s3c2410_iobank_timing *bt)
+{
+ unsigned long bankcon = bt->bankcon;
+ unsigned long hclk = cfg->freq.hclk_tns;
+
+ bt->tcah = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcah_SHIFT);
+ bt->tcoh = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcoh_SHIFT);
+ bt->tcos = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcos_SHIFT);
+ bt->tacs = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tacs_SHIFT);
+ bt->tacc = get_tacc(hclk, bankcon >> S3C2410_BANKCON_Tacc_SHIFT);
+}
+
+/**
+ * s3c2410_iotiming_debugfs - debugfs show io bank timing information
+ * @seq: The seq_file to write output to using seq_printf().
+ * @cfg: The current configuration.
+ * @iob: The IO bank information to decode.
+ */
+void s3c2410_iotiming_debugfs(struct seq_file *seq,
+ struct s3c_cpufreq_config *cfg,
+ union s3c_iobank *iob)
+{
+ struct s3c2410_iobank_timing *bt = iob->io_2410;
+ unsigned long bankcon = bt->bankcon;
+ unsigned long hclk = cfg->freq.hclk_tns;
+ unsigned int tacs;
+ unsigned int tcos;
+ unsigned int tacc;
+ unsigned int tcoh;
+ unsigned int tcah;
+
+ seq_printf(seq, "BANKCON=0x%08lx\n", bankcon);
+
+ tcah = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcah_SHIFT);
+ tcoh = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcoh_SHIFT);
+ tcos = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcos_SHIFT);
+ tacs = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tacs_SHIFT);
+ tacc = get_tacc(hclk, bankcon >> S3C2410_BANKCON_Tacc_SHIFT);
+
+ seq_printf(seq,
+ "\tRead: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, Tcoh=%d.%d, Tcah=%d.%d\n",
+ print_ns(bt->tacs),
+ print_ns(bt->tcos),
+ print_ns(bt->tacc),
+ print_ns(bt->tcoh),
+ print_ns(bt->tcah));
+
+ seq_printf(seq,
+ "\t Set: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, Tcoh=%d.%d, Tcah=%d.%d\n",
+ print_ns(tacs),
+ print_ns(tcos),
+ print_ns(tacc),
+ print_ns(tcoh),
+ print_ns(tcah));
+}
+
+/**
+ * s3c2410_iotiming_calc - Calculate bank timing for frequency change.
+ * @cfg: The frequency configuration
+ * @iot: The IO timing information to fill out.
+ *
+ * Calculate the new values for the banks in @iot based on the new
+ * frequency information in @cfg. This is then used by s3c2410_iotiming_set()
+ * to update the timing when necessary.
+ */
+int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *iot)
+{
+ struct s3c2410_iobank_timing *bt;
+ unsigned long bankcon;
+ int bank;
+ int ret;
+
+ for (bank = 0; bank < MAX_BANKS; bank++) {
+ bankcon = __raw_readl(bank_reg(bank));
+ bt = iot->bank[bank].io_2410;
+
+ if (!bt)
+ continue;
+
+ bt->bankcon = bankcon;
+
+ ret = s3c2410_calc_bank(cfg, bt);
+ if (ret) {
+ printk(KERN_ERR "%s: cannot calculate bank %d io\n",
+ __func__, bank);
+ goto err;
+ }
+
+ s3c_freq_iodbg("%s: bank %d: con=%08lx\n",
+ __func__, bank, bt->bankcon);
+ }
+
+ return 0;
+ err:
+ return ret;
+}
+
+/**
+ * s3c2410_iotiming_set - set the IO timings from the given setup.
+ * @cfg: The frequency configuration
+ * @iot: The IO timing information to use.
+ *
+ * Set all the currently used IO bank timing information generated
+ * by s3c2410_iotiming_calc() once the core has validated that all
+ * the new values are within permitted bounds.
+ */
+void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *iot)
+{
+ struct s3c2410_iobank_timing *bt;
+ int bank;
+
+ /* set the io timings from the specifier */
+
+ for (bank = 0; bank < MAX_BANKS; bank++) {
+ bt = iot->bank[bank].io_2410;
+ if (!bt)
+ continue;
+
+ __raw_writel(bt->bankcon, bank_reg(bank));
+ }
+}
+
+/**
+ * s3c2410_iotiming_get - Get the timing information from current registers.
+ * @cfg: The frequency configuration
+ * @timings: The IO timing information to fill out.
+ *
+ * Calculate the @timings timing information from the current frequency
+ * information in @cfg, and the new frequency configuration
+ * through all the IO banks, reading the state and then updating @iot
+ * as necessary.
+ *
+ * This is used at the moment on initialisation to get the current
+ * configuration so that boards do not have to carry their own setup
+ * if the timings are correct on initialisation.
+ */
+
+int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *timings)
+{
+ struct s3c2410_iobank_timing *bt;
+ unsigned long bankcon;
+ unsigned long bwscon;
+ int bank;
+
+ bwscon = __raw_readl(S3C2410_BWSCON);
+
+ /* look through all banks to see what is currently set. */
+
+ for (bank = 0; bank < MAX_BANKS; bank++) {
+ bankcon = __raw_readl(bank_reg(bank));
+
+ if (!bank_is_io(bankcon))
+ continue;
+
+ s3c_freq_iodbg("%s: bank %d: con %08lx\n",
+ __func__, bank, bankcon);
+
+ bt = kzalloc(sizeof(*bt), GFP_KERNEL);
+ if (!bt)
+ return -ENOMEM;
+
+ /* find out in nWait is enabled for bank. */
+
+ if (bank != 0) {
+ unsigned long tmp = S3C2410_BWSCON_GET(bwscon, bank);
+ if (tmp & S3C2410_BWSCON_WS)
+ bt->nwait_en = 1;
+ }
+
+ timings->bank[bank].io_2410 = bt;
+ bt->bankcon = bankcon;
+
+ s3c2410_iotiming_getbank(cfg, bt);
+ }
+
+ s3c2410_print_timing("get", timings);
+ return 0;
+}
diff --git a/arch/arm/mach-s3c24xx/iotiming-s3c2412.c b/arch/arm/mach-s3c24xx/iotiming-s3c2412.c
new file mode 100644
index 000000000..59356d10f
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/iotiming-s3c2412.c
@@ -0,0 +1,278 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2006-2008 Simtec Electronics
+// http://armlinux.simtec.co.uk/
+// Ben Dooks <ben@simtec.co.uk>
+//
+// S3C2412/S3C2443 (PL093 based) IO timing support
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/seq_file.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include <linux/amba/pl093.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+
+#include <mach/s3c2412.h>
+
+#define print_ns(x) ((x) / 10), ((x) % 10)
+
+/**
+ * s3c2412_print_timing - print timing information via printk.
+ * @pfx: The prefix to print each line with.
+ * @iot: The IO timing information
+ */
+static void s3c2412_print_timing(const char *pfx, struct s3c_iotimings *iot)
+{
+ struct s3c2412_iobank_timing *bt;
+ unsigned int bank;
+
+ for (bank = 0; bank < MAX_BANKS; bank++) {
+ bt = iot->bank[bank].io_2412;
+ if (!bt)
+ continue;
+
+ printk(KERN_DEBUG "%s: %d: idcy=%d.%d wstrd=%d.%d wstwr=%d,%d"
+ "wstoen=%d.%d wstwen=%d.%d wstbrd=%d.%d\n", pfx, bank,
+ print_ns(bt->idcy),
+ print_ns(bt->wstrd),
+ print_ns(bt->wstwr),
+ print_ns(bt->wstoen),
+ print_ns(bt->wstwen),
+ print_ns(bt->wstbrd));
+ }
+}
+
+/**
+ * to_div - turn a cycle length into a divisor setting.
+ * @cyc_tns: The cycle time in 10ths of nanoseconds.
+ * @clk_tns: The clock period in 10ths of nanoseconds.
+ */
+static inline unsigned int to_div(unsigned int cyc_tns, unsigned int clk_tns)
+{
+ return cyc_tns ? DIV_ROUND_UP(cyc_tns, clk_tns) : 0;
+}
+
+/**
+ * calc_timing - calculate timing divisor value and check in range.
+ * @hwtm: The hardware timing in 10ths of nanoseconds.
+ * @clk_tns: The clock period in 10ths of nanoseconds.
+ * @err: Pointer to err variable to update in event of failure.
+ */
+static unsigned int calc_timing(unsigned int hwtm, unsigned int clk_tns,
+ unsigned int *err)
+{
+ unsigned int ret = to_div(hwtm, clk_tns);
+
+ if (ret > 0xf)
+ *err = -EINVAL;
+
+ return ret;
+}
+
+/**
+ * s3c2412_calc_bank - calculate the bank divisor settings.
+ * @cfg: The current frequency configuration.
+ * @bt: The bank timing.
+ */
+static int s3c2412_calc_bank(struct s3c_cpufreq_config *cfg,
+ struct s3c2412_iobank_timing *bt)
+{
+ unsigned int hclk = cfg->freq.hclk_tns;
+ int err = 0;
+
+ bt->smbidcyr = calc_timing(bt->idcy, hclk, &err);
+ bt->smbwstrd = calc_timing(bt->wstrd, hclk, &err);
+ bt->smbwstwr = calc_timing(bt->wstwr, hclk, &err);
+ bt->smbwstoen = calc_timing(bt->wstoen, hclk, &err);
+ bt->smbwstwen = calc_timing(bt->wstwen, hclk, &err);
+ bt->smbwstbrd = calc_timing(bt->wstbrd, hclk, &err);
+
+ return err;
+}
+
+/**
+ * s3c2412_iotiming_debugfs - debugfs show io bank timing information
+ * @seq: The seq_file to write output to using seq_printf().
+ * @cfg: The current configuration.
+ * @iob: The IO bank information to decode.
+*/
+void s3c2412_iotiming_debugfs(struct seq_file *seq,
+ struct s3c_cpufreq_config *cfg,
+ union s3c_iobank *iob)
+{
+ struct s3c2412_iobank_timing *bt = iob->io_2412;
+
+ seq_printf(seq,
+ "\tRead: idcy=%d.%d wstrd=%d.%d wstwr=%d,%d"
+ "wstoen=%d.%d wstwen=%d.%d wstbrd=%d.%d\n",
+ print_ns(bt->idcy),
+ print_ns(bt->wstrd),
+ print_ns(bt->wstwr),
+ print_ns(bt->wstoen),
+ print_ns(bt->wstwen),
+ print_ns(bt->wstbrd));
+}
+
+/**
+ * s3c2412_iotiming_calc - calculate all the bank divisor settings.
+ * @cfg: The current frequency configuration.
+ * @iot: The bank timing information.
+ *
+ * Calculate the timing information for all the banks that are
+ * configured as IO, using s3c2412_calc_bank().
+ */
+int s3c2412_iotiming_calc(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *iot)
+{
+ struct s3c2412_iobank_timing *bt;
+ int bank;
+ int ret;
+
+ for (bank = 0; bank < MAX_BANKS; bank++) {
+ bt = iot->bank[bank].io_2412;
+ if (!bt)
+ continue;
+
+ ret = s3c2412_calc_bank(cfg, bt);
+ if (ret) {
+ printk(KERN_ERR "%s: cannot calculate bank %d io\n",
+ __func__, bank);
+ goto err;
+ }
+ }
+
+ return 0;
+ err:
+ return ret;
+}
+
+/**
+ * s3c2412_iotiming_set - set the timing information
+ * @cfg: The current frequency configuration.
+ * @iot: The bank timing information.
+ *
+ * Set the IO bank information from the details calculated earlier from
+ * calling s3c2412_iotiming_calc().
+ */
+void s3c2412_iotiming_set(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *iot)
+{
+ struct s3c2412_iobank_timing *bt;
+ void __iomem *regs;
+ int bank;
+
+ /* set the io timings from the specifier */
+
+ for (bank = 0; bank < MAX_BANKS; bank++) {
+ bt = iot->bank[bank].io_2412;
+ if (!bt)
+ continue;
+
+ regs = S3C2412_SSMC_BANK(bank);
+
+ __raw_writel(bt->smbidcyr, regs + SMBIDCYR);
+ __raw_writel(bt->smbwstrd, regs + SMBWSTRDR);
+ __raw_writel(bt->smbwstwr, regs + SMBWSTWRR);
+ __raw_writel(bt->smbwstoen, regs + SMBWSTOENR);
+ __raw_writel(bt->smbwstwen, regs + SMBWSTWENR);
+ __raw_writel(bt->smbwstbrd, regs + SMBWSTBRDR);
+ }
+}
+
+static inline unsigned int s3c2412_decode_timing(unsigned int clock, u32 reg)
+{
+ return (reg & 0xf) * clock;
+}
+
+static void s3c2412_iotiming_getbank(struct s3c_cpufreq_config *cfg,
+ struct s3c2412_iobank_timing *bt,
+ unsigned int bank)
+{
+ unsigned long clk = cfg->freq.hclk_tns; /* ssmc clock??? */
+ void __iomem *regs = S3C2412_SSMC_BANK(bank);
+
+ bt->idcy = s3c2412_decode_timing(clk, __raw_readl(regs + SMBIDCYR));
+ bt->wstrd = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTRDR));
+ bt->wstoen = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTOENR));
+ bt->wstwen = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTWENR));
+ bt->wstbrd = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTBRDR));
+}
+
+/**
+ * bank_is_io - return true if bank is (possibly) IO.
+ * @bank: The bank number.
+ * @bankcfg: The value of S3C2412_EBI_BANKCFG.
+ */
+static inline bool bank_is_io(unsigned int bank, u32 bankcfg)
+{
+ if (bank < 2)
+ return true;
+
+ return !(bankcfg & (1 << bank));
+}
+
+int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *timings)
+{
+ struct s3c2412_iobank_timing *bt;
+ u32 bankcfg = __raw_readl(S3C2412_EBI_BANKCFG);
+ unsigned int bank;
+
+ /* look through all banks to see what is currently set. */
+
+ for (bank = 0; bank < MAX_BANKS; bank++) {
+ if (!bank_is_io(bank, bankcfg))
+ continue;
+
+ bt = kzalloc(sizeof(*bt), GFP_KERNEL);
+ if (!bt)
+ return -ENOMEM;
+
+ timings->bank[bank].io_2412 = bt;
+ s3c2412_iotiming_getbank(cfg, bt, bank);
+ }
+
+ s3c2412_print_timing("get", timings);
+ return 0;
+}
+
+/* this is in here as it is so small, it doesn't currently warrant a file
+ * to itself. We expect that any s3c24xx needing this is going to also
+ * need the iotiming support.
+ */
+void s3c2412_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
+{
+ struct s3c_cpufreq_board *board = cfg->board;
+ u32 refresh;
+
+ WARN_ON(board == NULL);
+
+ /* Reduce both the refresh time (in ns) and the frequency (in MHz)
+ * down to ensure that we do not overflow 32 bit numbers.
+ *
+ * This should work for HCLK up to 133MHz and refresh period up
+ * to 30usec.
+ */
+
+ refresh = (cfg->freq.hclk / 100) * (board->refresh / 10);
+ refresh = DIV_ROUND_UP(refresh, (1000 * 1000)); /* apply scale */
+ refresh &= ((1 << 16) - 1);
+
+ s3c_freq_dbg("%s: refresh value %u\n", __func__, (unsigned int)refresh);
+
+ __raw_writel(refresh, S3C2412_REFRESH);
+}
diff --git a/arch/arm/mach-s3c24xx/irq-pm.c b/arch/arm/mach-s3c24xx/irq-pm.c
new file mode 100644
index 000000000..e0131b16a
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/irq-pm.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2003-2004 Simtec Electronics
+// Ben Dooks <ben@simtec.co.uk>
+// http://armlinux.simtec.co.uk/
+//
+// S3C24XX - IRQ PM code
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/syscore_ops.h>
+#include <linux/io.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/map-base.h>
+#include <plat/map-s3c.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+#include <mach/pm-core.h>
+
+#include <asm/irq.h>
+
+int s3c_irq_wake(struct irq_data *data, unsigned int state)
+{
+ unsigned long irqbit = 1 << data->hwirq;
+
+ if (!(s3c_irqwake_intallow & irqbit))
+ return -ENOENT;
+
+ pr_info("wake %s for hwirq %lu\n",
+ state ? "enabled" : "disabled", data->hwirq);
+
+ if (!state)
+ s3c_irqwake_intmask |= irqbit;
+ else
+ s3c_irqwake_intmask &= ~irqbit;
+
+ return 0;
+}
+
+static struct sleep_save irq_save[] = {
+ SAVE_ITEM(S3C2410_INTMSK),
+ SAVE_ITEM(S3C2410_INTSUBMSK),
+};
+
+/* the extint values move between the s3c2410/s3c2440 and the s3c2412
+ * so we use an array to hold them, and to calculate the address of
+ * the register at run-time
+*/
+
+static unsigned long save_extint[3];
+static unsigned long save_eintflt[4];
+static unsigned long save_eintmask;
+
+static int s3c24xx_irq_suspend(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(save_extint); i++)
+ save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
+
+ for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
+ save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
+
+ s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
+ save_eintmask = __raw_readl(S3C24XX_EINTMASK);
+
+ return 0;
+}
+
+static void s3c24xx_irq_resume(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(save_extint); i++)
+ __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
+
+ for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
+ __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
+
+ s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
+ __raw_writel(save_eintmask, S3C24XX_EINTMASK);
+}
+
+struct syscore_ops s3c24xx_irq_syscore_ops = {
+ .suspend = s3c24xx_irq_suspend,
+ .resume = s3c24xx_irq_resume,
+};
+
+#ifdef CONFIG_CPU_S3C2416
+static struct sleep_save s3c2416_irq_save[] = {
+ SAVE_ITEM(S3C2416_INTMSK2),
+};
+
+static int s3c2416_irq_suspend(void)
+{
+ s3c_pm_do_save(s3c2416_irq_save, ARRAY_SIZE(s3c2416_irq_save));
+
+ return 0;
+}
+
+static void s3c2416_irq_resume(void)
+{
+ s3c_pm_do_restore(s3c2416_irq_save, ARRAY_SIZE(s3c2416_irq_save));
+}
+
+struct syscore_ops s3c2416_irq_syscore_ops = {
+ .suspend = s3c2416_irq_suspend,
+ .resume = s3c2416_irq_resume,
+};
+#endif
diff --git a/arch/arm/mach-s3c24xx/mach-amlm5900.c b/arch/arm/mach-s3c24xx/mach-amlm5900.c
new file mode 100644
index 000000000..9a9daf526
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-amlm5900.c
@@ -0,0 +1,231 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright (c) 2006 American Microsystems Limited
+// David Anders <danders@amltd.com>
+//
+// @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/serial_s3c.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 <mach/regs-lcd.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <linux/platform_data/i2c-s3c2410.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 <plat/samsung-time.h>
+
+#include "common.h"
+
+static struct resource amlm5900_nor_resource =
+ DEFINE_RES_MEM(0x00000000, SZ_16M);
+
+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_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init amlm5900_init_time(void)
+{
+ s3c2410_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+#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 = s3c2410_init_irq,
+ .init_machine = amlm5900_init,
+ .init_time = amlm5900_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-anubis.c b/arch/arm/mach-s3c24xx/mach-anubis.c
new file mode 100644
index 000000000..072966dca
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-anubis.c
@@ -0,0 +1,429 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright 2003-2009 Simtec Electronics
+// http://armlinux.simtec.co.uk/
+// 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/serial_core.h>
+#include <linux/serial_s3c.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/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/gpio-samsung.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/rawnand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <net/ax88796.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <linux/platform_data/asoc-s3c24xx_simtec.h>
+#include <plat/samsung-time.h>
+
+#include "anubis.h"
+#include "common.h"
+#include "simtec.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,
+ .ecc_mode = NAND_ECC_SOFT,
+};
+
+/* IDE channels */
+
+static struct pata_platform_info anubis_ide_platdata = {
+ .ioport_shift = 5,
+};
+
+static struct resource anubis_ide0_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2410_CS3, 8 * 32),
+ [2] = DEFINE_RES_MEM(S3C2410_CS3 + (1 << 26) + (6 * 32), 32),
+ [3] = DEFINE_RES_IRQ(ANUBIS_IRQ_IDE0),
+};
+
+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[] = {
+ [0] = DEFINE_RES_MEM(S3C2410_CS4, 8 * 32),
+ [1] = DEFINE_RES_MEM(S3C2410_CS4 + (1 << 26) + (6 * 32), 32),
+ [2] = DEFINE_RES_IRQ(ANUBIS_IRQ_IDE0),
+};
+
+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] = DEFINE_RES_MEM(S3C2410_CS5, 0x20 * 0x20),
+ [1] = DEFINE_RES_IRQ(ANUBIS_IRQ_ASIX),
+};
+
+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] = DEFINE_RES_MEM(S3C2410_CS2, SZ_8M),
+ [1] = DEFINE_RES_MEM(S3C2410_CS2 + SZ_64M - SZ_2M, SZ_2M),
+ [2] = DEFINE_RES_IRQ(IRQ_EINT0),
+};
+
+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 = {
+ &s3c2410_device_dclk,
+ &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,
+};
+
+/* 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)
+{
+ s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
+ s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ /* 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 */
+ gpio_request_one(S3C2410_GPA(0), GPIOF_OUT_INIT_HIGH, NULL);
+ gpio_free(S3C2410_GPA(0));
+ }
+}
+
+static void __init anubis_init_time(void)
+{
+ s3c2440_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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 = s3c2440_init_irq,
+ .init_time = anubis_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-at2440evb.c b/arch/arm/mach-s3c24xx/mach-at2440evb.c
new file mode 100644
index 000000000..68a4fa942
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-at2440evb.c
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// 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/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/gpio.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/serial_s3c.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 <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/gpio-samsung.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/rawnand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <linux/platform_data/mmc-s3cmci.h>
+#include <plat/samsung-time.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,
+ .ecc_mode = NAND_ECC_SOFT,
+};
+
+/* DM9000AEP 10/100 ethernet controller */
+
+static struct resource at2440evb_dm9k_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2410_CS3, 4),
+ [1] = DEFINE_RES_MEM(S3C2410_CS3 + 4, 4),
+ [2] = DEFINE_RES_NAMED(IRQ_EINT7, 1, NULL, 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_uarts(at2440evb_uartcfgs, ARRAY_SIZE(at2440evb_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init at2440evb_init_time(void)
+{
+ s3c2440_init_clocks(16934400);
+ samsung_timer_init();
+}
+
+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 = s3c2440_init_irq,
+ .init_time = at2440evb_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-bast.c b/arch/arm/mach-s3c24xx/mach-bast.c
new file mode 100644
index 000000000..a7c3955ae
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-bast.c
@@ -0,0 +1,590 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright 2003-2008 Simtec Electronics
+// Ben Dooks <ben@simtec.co.uk>
+//
+// http://www.simtec.co.uk/products/EB2410ITX/
+
+#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/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/dm9000.h>
+#include <linux/ata_platform.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/serial_8250.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/rawnand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <linux/platform_data/asoc-s3c24xx_simtec.h>
+#include <linux/platform_data/hwmon-s3c.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+
+#include <net/ax88796.h>
+
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/fb.h>
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/samsung-time.h>
+
+#include "bast.h"
+#include "common.h"
+#include "simtec.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,
+ .ecc_mode = NAND_ECC_SOFT,
+};
+
+/* DM9000 */
+
+static struct resource bast_dm9k_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2410_CS5 + BAST_PA_DM9000, 4),
+ [1] = DEFINE_RES_MEM(S3C2410_CS5 + BAST_PA_DM9000 + 0x40, 0x40),
+ [2] = DEFINE_RES_NAMED(BAST_IRQ_DM9000 , 1, NULL, 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 = BAST_IRQ_PCSERIAL1,
+ .flags = SERIAL_FLAGS,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = SERIAL_CLK,
+ },
+ [1] = {
+ .mapbase = SERIAL_BASE + 0x3f8,
+ .irq = BAST_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] = DEFINE_RES_MEM(S3C2410_CS5 + BAST_PA_ASIXNET, 0x18 * 0x20),
+ [1] = DEFINE_RES_MEM(S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20), 1),
+ [2] = DEFINE_RES_IRQ(BAST_IRQ_ASIX),
+};
+
+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] = DEFINE_RES_MEM(S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20), \
+ 0x30 * 0x20),
+};
+
+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 = {
+ &s3c2410_device_dclk,
+ &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 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)
+{
+ s3c_hwmon_set_platdata(&bast_hwmon_info);
+
+ s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
+ s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init bast_init_time(void)
+{
+ s3c2410_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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 = s3c2410_init_irq,
+ .init_machine = bast_init,
+ .init_time = bast_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-gta02.c b/arch/arm/mach-s3c24xx/mach-gta02.c
new file mode 100644
index 000000000..9d5595c4a
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-gta02.c
@@ -0,0 +1,588 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// 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.
+
+#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/gpio_keys.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+
+#include <linux/mmc/host.h>
+
+#include <linux/mfd/pcf50633/adc.h>
+#include <linux/mfd/pcf50633/backlight.h>
+#include <linux/mfd/pcf50633/core.h>
+#include <linux/mfd/pcf50633/gpio.h>
+#include <linux/mfd/pcf50633/mbc.h>
+#include <linux/mfd/pcf50633/pmic.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/rawnand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+#include <linux/regulator/machine.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/s3c24xx.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/touchscreen-s3c2410.h>
+#include <linux/platform_data/usb-ohci-s3c2410.h>
+#include <linux/platform_data/usb-s3c2410_udc.h>
+
+#include <mach/fb.h>
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-irq.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/pm.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "gta02.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
+
+#ifdef CONFIG_PCF50633_ADC
+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);
+}
+#endif
+
+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(gta02_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 =
+ DEFINE_RES_MEM(GTA02_FLASH_BASE, GTA02_FLASH_SIZE);
+
+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,
+ .ecc_mode = NAND_ECC_SOFT,
+};
+
+
+/* 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_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+
+/* 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,
+ &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();
+}
+
+static void __init gta02_init_time(void)
+{
+ s3c2442_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+MACHINE_START(NEO1973_GTA02, "GTA02")
+ /* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */
+ .atag_offset = 0x100,
+ .map_io = gta02_map_io,
+ .init_irq = s3c2442_init_irq,
+ .init_machine = gta02_machine_init,
+ .init_time = gta02_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c
new file mode 100644
index 000000000..e064c73a5
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-h1940.c
@@ -0,0 +1,750 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2003-2005 Simtec Electronics
+// Ben Dooks <ben@simtec.co.uk>
+//
+// http://www.handhelds.org/projects/h1940.html
+
+#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/serial_s3c.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.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/irq.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <linux/platform_data/mmc-s3cmci.h>
+#include <linux/platform_data/touchscreen-s3c2410.h>
+#include <linux/platform_data/usb-s3c2410_udc.h>
+
+#include <sound/uda1380.h>
+
+#include <mach/fb.h>
+#include <mach/hardware.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/pm.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "h1940.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))
+
+#define S3C24XX_PLL_MDIV_SHIFT (12)
+#define S3C24XX_PLL_PDIV_SHIFT (4)
+#define S3C24XX_PLL_SDIV_SHIFT (0)
+
+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] = DEFINE_RES_NAMED(IRQ_EINT2, 1, "ac", IORESOURCE_IRQ \
+ | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE),
+};
+
+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(struct gpio_desc *desc, int state,
+ unsigned long *delay_on, unsigned long *delay_off)
+{
+ int blink_gpio, check_gpio1, check_gpio2;
+ int gpio = desc ? desc_to_gpio(desc) : -EINVAL;
+
+ 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_gpio2 = 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 struct pwm_lookup h1940_pwm_lookup[] = {
+ PWM_LOOKUP("samsung-pwm", 0, "pwm-backlight", NULL, 36296,
+ PWM_POLARITY_NORMAL),
+};
+
+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 = {
+ .max_brightness = 100,
+ .dft_brightness = 50,
+ .enable_gpio = -1,
+ .init = h1940_backlight_init,
+ .notify = h1940_backlight_notify,
+ .exit = h1940_backlight_exit,
+};
+
+static struct platform_device h1940_backlight = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &samsung_device_pwm.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,
+ &s3c_device_usbgadget,
+ &h1940_device_leds,
+ &h1940_device_bluetooth,
+ &s3c_device_sdi,
+ &s3c_device_rtc,
+ &samsung_device_pwm,
+ &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_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ /* 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_data(&h1940_latch_gpiochip, NULL));
+}
+
+static void __init h1940_init_time(void)
+{
+ s3c2410_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+/* 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(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);
+
+ pwm_add_table(h1940_pwm_lookup, ARRAY_SIZE(h1940_pwm_lookup));
+ 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 = s3c2410_init_irq,
+ .init_machine = h1940_init,
+ .init_time = h1940_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-jive.c b/arch/arm/mach-s3c24xx/mach-jive.c
new file mode 100644
index 000000000..eedc9f8ed
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-jive.c
@@ -0,0 +1,678 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright 2007 Simtec Electronics
+// Ben Dooks <ben@simtec.co.uk>
+//
+// http://armlinux.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/gpio/machine.h>
+#include <linux/syscore_ops.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.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 <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/fb.h>
+#include <mach/gpio-samsung.h>
+
+#include <asm/mach-types.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/rawnand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <linux/platform_data/usb-s3c2410_udc.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "s3c2412-power.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),
+ .ecc_mode = NAND_ECC_SOFT,
+};
+
+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 1;
+
+ if (kstrtoul(options, 10, &set)) {
+ printk(KERN_ERR "failed to parse mtdset=%s\n", options);
+ return 1;
+ }
+
+ 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 1;
+}
+
+/* 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 = {
+ .num_chipselect = 1,
+};
+
+static struct platform_device jive_device_lcdspi = {
+ .name = "spi_gpio",
+ .id = 1,
+ .dev.platform_data = &jive_lcd_spi,
+};
+
+static struct gpiod_lookup_table jive_lcdspi_gpiod_table = {
+ .dev_id = "spi_gpio",
+ .table = {
+ GPIO_LOOKUP("GPIOG", 8,
+ "sck", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("GPIOB", 8,
+ "mosi", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("GPIOB", 7,
+ "cs", GPIO_ACTIVE_HIGH),
+ { },
+ },
+};
+
+/* WM8750 audio code SPI definition */
+
+static struct spi_gpio_platform_data jive_wm8750_spi = {
+ .num_chipselect = 1,
+};
+
+static struct platform_device jive_device_wm8750 = {
+ .name = "spi_gpio",
+ .id = 2,
+ .dev.platform_data = &jive_wm8750_spi,
+};
+
+static struct gpiod_lookup_table jive_wm8750_gpiod_table = {
+ .dev_id = "spi_gpio",
+ .table = {
+ GPIO_LOOKUP("GPIOB", 4,
+ "sck", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("GPIOB", 9,
+ "mosi", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("GPIOH", 10,
+ "cs", GPIO_ACTIVE_HIGH),
+ { },
+ },
+};
+
+/* 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,
+ }, {
+ .modalias = "WM8750",
+ .bus_num = 2,
+ .chip_select = 0,
+ .mode = SPI_MODE_0, /* CPOL=0, CPHA=0 */
+ .max_speed_hz = 100000,
+ },
+};
+
+/* 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,
+ &s3c2412_device_dma,
+};
+
+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(__pa_symbol(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_uarts(jive_uartcfgs, ARRAY_SIZE(jive_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init jive_init_time(void)
+{
+ s3c2412_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+static void jive_power_off(void)
+{
+ printk(KERN_INFO "powering system down...\n");
+
+ gpio_request_one(S3C2410_GPC(5), GPIOF_OUT_INIT_HIGH, NULL);
+ gpio_free(S3C2410_GPC(5));
+}
+
+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);
+
+ gpio_request(S3C2410_GPG(13), "lcm reset");
+ gpio_direction_output(S3C2410_GPG(13), 0);
+
+ gpio_request_one(S3C2410_GPB(6), GPIOF_OUT_INIT_LOW, NULL);
+ gpio_free(S3C2410_GPB(6));
+
+ /* 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;
+
+ gpiod_add_lookup_table(&jive_lcdspi_gpiod_table);
+ gpiod_add_lookup_table(&jive_wm8750_gpiod_table);
+ 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 = s3c2412_init_irq,
+ .map_io = jive_map_io,
+ .init_machine = jive_machine_init,
+ .init_time = jive_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c
new file mode 100644
index 000000000..f9fc1f8d2
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-mini2440.c
@@ -0,0 +1,714 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// 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/
+
+#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/serial_s3c.h>
+#include <linux/dm9000.h>
+#include <linux/property.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 <mach/regs-gpio.h>
+#include <linux/platform_data/leds-s3c24xx.h>
+#include <mach/regs-lcd.h>
+#include <mach/irqs.h>
+#include <mach/gpio-samsung.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <linux/platform_data/mmc-s3cmci.h>
+#include <linux/platform_data/usb-s3c2410_udc.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/rawnand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/samsung-time.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,
+ .ecc_mode = NAND_ECC_HW,
+};
+
+/* DM9000AEP 10/100 ethernet controller */
+
+static struct resource mini2440_dm9k_resource[] = {
+ [0] = DEFINE_RES_MEM(MACH_MINI2440_DM9K_BASE, 4),
+ [1] = DEFINE_RES_MEM(MACH_MINI2440_DM9K_BASE + 4, 4),
+ [2] = DEFINE_RES_NAMED(IRQ_EINT7, 1, NULL, 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 const struct property_entry mini2440_at24_properties[] = {
+ PROPERTY_ENTRY_U32("pagesize", 16),
+ { }
+};
+
+static struct i2c_board_info mini2440_i2c_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("24c08", 0x50),
+ .properties = mini2440_at24_properties,
+ },
+};
+
+static struct uda134x_platform_data s3c24xx_uda134x = {
+ .l3 = {
+ .gpio_clk = S3C2410_GPB(4),
+ .gpio_data = S3C2410_GPB(3),
+ .gpio_mode = S3C2410_GPB(2),
+ .use_gpios = 1,
+ .data_hold = 1,
+ .data_setup = 1,
+ .clock_high = 1,
+ .mode_hold = 1,
+ .mode = 1,
+ .mode_setup = 1,
+ },
+ .model = UDA134X_UDA1341,
+};
+
+static struct platform_device uda1340_codec = {
+ .name = "uda134x-codec",
+ .id = -1,
+ .dev = {
+ .platform_data = &s3c24xx_uda134x,
+ },
+};
+
+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,
+ &s3c2440_device_dma,
+ &s3c_device_iis,
+ &uda1340_codec,
+ &mini2440_audio,
+};
+
+static void __init mini2440_map_io(void)
+{
+ s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc));
+ s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init mini2440_init_time(void)
+{
+ s3c2440_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+/*
+ * 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_one(S3C2410_GPG(4), GPIOF_OUT_INIT_HIGH, NULL));
+ gpio_free(S3C2410_GPG(4));
+
+ /* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */
+ gpio_request_one(S3C2410_GPB(1), GPIOF_IN, NULL);
+ s3c_gpio_setpull(S3C2410_GPB(1), S3C_GPIO_PULL_UP);
+ gpio_free(S3C2410_GPB(1));
+
+ /* 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 = s3c2440_init_irq,
+ .init_time = mini2440_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-n30.c b/arch/arm/mach-s3c24xx/mach-n30.c
new file mode 100644
index 000000000..eec51fadb
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-n30.c
@@ -0,0 +1,609 @@
+// SPDX-License-Identifier: GPL-2.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 .
+
+#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/serial_s3c.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 <linux/platform_data/leds-s3c24xx.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/gpio-samsung.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <linux/platform_data/mmc-s3cmci.h>
+#include <linux/platform_data/usb-s3c2410_udc.h>
+#include <plat/samsung-time.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 bluetooth. 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_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init n30_init_time(void)
+{
+ s3c2410_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+/* 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,
+ .init_time = n30_init_time,
+ .init_machine = n30_init,
+ .init_irq = s3c2410_init_irq,
+ .map_io = n30_map_io,
+MACHINE_END
+
+MACHINE_START(N35, "Acer-N35")
+ /* Maintainer: Christer Weinigel <christer@weinigel.se>
+ */
+ .atag_offset = 0x100,
+ .init_time = n30_init_time,
+ .init_machine = n30_init,
+ .init_irq = s3c2410_init_irq,
+ .map_io = n30_map_io,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-nexcoder.c b/arch/arm/mach-s3c24xx/mach-nexcoder.c
new file mode 100644
index 000000000..c2f34758c
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-nexcoder.c
@@ -0,0 +1,158 @@
+// SPDX-License-Identifier: GPL-2.0
+// linux/arch/arm/mach-s3c2440/mach-nexcoder.c
+//
+// Copyright (c) 2004 Nex Vision
+// Guillaume GOURAT <guillaume.gourat@nexvision.tv>
+//
+// 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/serial_s3c.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 <mach/gpio-samsung.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/samsung-time.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] = DEFINE_RES_MEM(S3C2410_CS0, SZ_8M),
+};
+
+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 */
+ gpio_request_one(S3C2410_GPE(14), GPIOF_OUT_INIT_HIGH, NULL);
+ gpio_free(S3C2410_GPE(14)); /* IICSCL */
+ gpio_request_one(S3C2410_GPE(15), GPIOF_OUT_INIT_HIGH, NULL);
+ gpio_free(S3C2410_GPE(15)); /* IICSDA */
+
+ /* Power up the sensor board */
+ gpio_request_one(S3C2410_GPF(1), GPIOF_OUT_INIT_HIGH, NULL);
+ gpio_free(S3C2410_GPF(1)); /* CAM_GPIO7 => nLDO_PWRDN */
+ gpio_request_one(S3C2410_GPF(2), GPIOF_OUT_INIT_LOW, NULL);
+ gpio_free(S3C2410_GPF(2)); /* CAM_GPIO6 => CAM_PWRDN */
+}
+
+static void __init nexcoder_map_io(void)
+{
+ s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
+ s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ nexcoder_sensorboard_init();
+}
+
+static void __init nexcoder_init_time(void)
+{
+ s3c2440_init_clocks(12000000);
+ samsung_timer_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 = s3c2440_init_irq,
+ .init_time = nexcoder_init_time,
+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
index 000000000..5d819b6ea
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-osiris-dvs.c
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2009 Simtec Electronics
+// http://armlinux.simtec.co.uk/
+// Ben Dooks <ben@simtec.co.uk>
+//
+// Simtec Osiris Dynamic Voltage Scaling support.
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/cpufreq.h>
+#include <linux/gpio.h>
+
+#include <linux/mfd/tps65010.h>
+
+#include <plat/cpu-freq.h>
+#include <mach/gpio-samsung.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 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 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 actually 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 = osiris_dvs_remove,
+ .driver = {
+ .name = "osiris-dvs",
+ .pm = &osiris_dvs_pm,
+ },
+};
+
+module_platform_driver(osiris_dvs_driver);
+
+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
index 000000000..ee3630cb2
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-osiris.c
@@ -0,0 +1,412 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2005-2008 Simtec Electronics
+// http://armlinux.simtec.co.uk/
+// 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/syscore_ops.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/tps65010.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/rawnand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/samsung-time.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/gpio-samsung.h>
+
+#include "common.h"
+#include "osiris.h"
+#include "regs-mem.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,
+ .ecc_mode = NAND_ECC_SOFT,
+};
+
+/* PCMCIA control and configuration */
+
+static struct resource osiris_pcmcia_resource[] = {
+ [0] = DEFINE_RES_MEM(0x0f000000, SZ_1M),
+ [1] = DEFINE_RES_MEM(0x0c000000, SZ_1M),
+};
+
+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. */
+ gpio_request_one(S3C2410_GPA(21), GPIOF_OUT_INIT_HIGH, NULL);
+ gpio_free(S3C2410_GPA(21));
+
+ 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 = {
+ &s3c2410_device_dclk,
+ &s3c_device_i2c0,
+ &s3c_device_wdt,
+ &s3c_device_nand,
+ &osiris_pcmcia,
+};
+
+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;
+
+ s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc));
+ s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ /* 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 */
+ gpio_request_one(S3C2410_GPA(0), GPIOF_OUT_INIT_HIGH, NULL);
+ gpio_free(S3C2410_GPA(0));
+ }
+
+ /* 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_time(void)
+{
+ s3c2440_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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 = s3c2440_init_irq,
+ .init_machine = osiris_init,
+ .init_time = osiris_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-otom.c b/arch/arm/mach-s3c24xx/mach-otom.c
new file mode 100644
index 000000000..4e24d89e8
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-otom.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2004 Nex Vision
+// Guillaume GOURAT <guillaume.gourat@nexvision.fr>
+
+#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/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "otom.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] = DEFINE_RES_MEM(S3C2410_CS0, SZ_4M),
+};
+
+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_uarts(otom11_uartcfgs, ARRAY_SIZE(otom11_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init otom11_init_time(void)
+{
+ s3c2410_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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 = s3c2410_init_irq,
+ .init_time = otom11_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-qt2410.c b/arch/arm/mach-s3c24xx/mach-qt2410.c
new file mode 100644
index 000000000..5d48e5b6e
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-qt2410.c
@@ -0,0 +1,351 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright (C) 2006 by OpenMoko, Inc.
+// Author: Harald Welte <laforge@openmoko.org>
+// All rights reserved.
+
+#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/gpio/machine.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/rawnand.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 <linux/platform_data/leds-s3c24xx.h>
+#include <mach/regs-lcd.h>
+#include <mach/fb.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/usb-s3c2410_udc.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "common-smdk.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] = DEFINE_RES_MEM(0x19000000, 17),
+ [1] = DEFINE_RES_IRQ(IRQ_EINT9),
+};
+
+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 = {
+ .num_chipselect = 1,
+};
+
+static struct platform_device qt2410_spi = {
+ .name = "spi_gpio",
+ .id = 1,
+ .dev.platform_data = &spi_gpio_cfg,
+};
+
+static struct gpiod_lookup_table qt2410_spi_gpiod_table = {
+ .dev_id = "spi_gpio",
+ .table = {
+ GPIO_LOOKUP("GPIOG", 7,
+ "sck", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("GPIOG", 6,
+ "mosi", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("GPIOG", 5,
+ "miso", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("GPIOB", 5,
+ "cs", GPIO_ACTIVE_HIGH),
+ { },
+ },
+};
+
+/* 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,
+ .ecc_mode = NAND_ECC_SOFT,
+};
+
+/* 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_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init qt2410_init_time(void)
+{
+ s3c2410_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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);
+
+ /* set initial state of the LED GPIO */
+ WARN_ON(gpio_request_one(S3C2410_GPB(0), GPIOF_OUT_INIT_HIGH, NULL));
+ gpio_free(S3C2410_GPB(0));
+
+ s3c24xx_udc_set_platdata(&qt2410_udc_cfg);
+ s3c_i2c0_set_platdata(NULL);
+
+ gpiod_add_lookup_table(&qt2410_spi_gpiod_table);
+ 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 = s3c2410_init_irq,
+ .init_machine = qt2410_machine_init,
+ .init_time = qt2410_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c
new file mode 100644
index 000000000..7f5a18fa3
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-rx1950.c
@@ -0,0 +1,822 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2006-2009 Victor Chukhantsev, Denis Grigoriev,
+// Copyright (c) 2007-2010 Vasily Khoruzhick
+//
+// based on smdk2440 written by Ben Dooks
+
+#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/serial_s3c.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-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <linux/platform_data/mmc-s3cmci.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/touchscreen-s3c2410.h>
+#include <linux/platform_data/usb-s3c2410_udc.h>
+
+#include <sound/uda1380.h>
+
+#include <mach/fb.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/pm.h>
+#include <plat/samsung-time.h>
+#include <plat/gpio-cfg.h>
+
+#include "common.h"
+#include "h1940.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] = DEFINE_RES_NAMED(IRQ_EINT2, 1, "ac", IORESOURCE_IRQ \
+ | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE),
+};
+
+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(struct gpio_desc *desc, int state,
+ unsigned long *delay_on, unsigned long *delay_off)
+{
+ int gpio = desc_to_gpio(desc);
+ 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_lookup rx1950_pwm_lookup[] = {
+ PWM_LOOKUP("samsung-pwm", 0, "pwm-backlight.0", NULL, 48000,
+ PWM_POLARITY_NORMAL),
+};
+
+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);
+ }
+
+ /*
+ * FIXME: pwm_apply_args() should be removed when switching to
+ * the atomic PWM API.
+ */
+ pwm_apply_args(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 = {
+ .max_brightness = 24,
+ .dft_brightness = 4,
+ .enable_gpio = -1,
+ .init = rx1950_backlight_init,
+ .notify = rx1950_backlight_notify,
+ .exit = rx1950_backlight_exit,
+};
+
+static struct platform_device rx1950_backlight = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &samsung_device_pwm.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,
+ .ecc_mode = NAND_ECC_SOFT,
+};
+
+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 = {
+ &s3c2410_device_dclk,
+ &s3c_device_lcd,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_iis,
+ &s3c_device_usbgadget,
+ &s3c_device_rtc,
+ &s3c_device_nand,
+ &s3c_device_sdi,
+ &s3c_device_adc,
+ &s3c_device_ts,
+ &samsung_device_pwm,
+ &rx1950_backlight,
+ &rx1950_device_gpiokeys,
+ &power_supply,
+ &rx1950_battery,
+ &rx1950_leds,
+};
+
+static void __init rx1950_map_io(void)
+{
+ s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc));
+ s3c24xx_init_uarts(rx1950_uartcfgs, ARRAY_SIZE(rx1950_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ /* 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_time(void)
+{
+ s3c2442_init_clocks(16934000);
+ samsung_timer_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);
+
+ pwm_add_table(rx1950_pwm_lookup, ARRAY_SIZE(rx1950_pwm_lookup));
+ 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 = s3c2442_init_irq,
+ .init_machine = rx1950_init_machine,
+ .init_time = rx1950_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-rx3715.c b/arch/arm/mach-s3c24xx/mach-rx3715.c
new file mode 100644
index 000000000..529c6faf8
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-rx3715.c
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2003-2004 Simtec Electronics
+// Ben Dooks <ben@simtec.co.uk>
+//
+// http://www.handhelds.org/projects/rx3715.html
+
+#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_s3c.h>
+#include <linux/serial.h>
+#include <linux/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/rawnand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/fb.h>
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/pm.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "h1940.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,
+ .ecc_mode = NAND_ECC_SOFT,
+};
+
+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_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init rx3715_init_time(void)
+{
+ s3c2440_init_clocks(16934000);
+ samsung_timer_init();
+}
+
+/* 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_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 = s3c2440_init_irq,
+ .init_machine = rx3715_init_machine,
+ .init_time = rx3715_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c b/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c
new file mode 100644
index 000000000..aa7102713
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Samsung's S3C2416 flattened device tree enabled machine
+//
+// Copyright (c) 2012 Heiko Stuebner <heiko@sntech.de>
+//
+// based on mach-exynos/mach-exynos4-dt.c
+//
+// Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+// http://www.samsung.com
+// Copyright (c) 2010-2011 Linaro Ltd.
+// www.linaro.org
+
+#include <linux/clocksource.h>
+#include <linux/irqchip.h>
+#include <linux/serial_s3c.h>
+
+#include <asm/mach/arch.h>
+#include <mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include "common.h"
+
+static void __init s3c2416_dt_map_io(void)
+{
+ s3c24xx_init_io(NULL, 0);
+}
+
+static void __init s3c2416_dt_machine_init(void)
+{
+ s3c_pm_init();
+}
+
+static const char *const s3c2416_dt_compat[] __initconst = {
+ "samsung,s3c2416",
+ "samsung,s3c2450",
+ NULL
+};
+
+DT_MACHINE_START(S3C2416_DT, "Samsung S3C2416 (Flattened Device Tree)")
+ /* Maintainer: Heiko Stuebner <heiko@sntech.de> */
+ .dt_compat = s3c2416_dt_compat,
+ .map_io = s3c2416_dt_map_io,
+ .init_irq = irqchip_init,
+ .init_machine = s3c2416_dt_machine_init,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2410.c b/arch/arm/mach-s3c24xx/mach-smdk2410.c
new file mode 100644
index 000000000..18dfef52c
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-smdk2410.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright (C) 2004 by FS Forth-Systeme GmbH
+// All rights reserved.
+//
+// @Author: Jonas Dietsche
+//
+// @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/serial_s3c.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 <linux/platform_data/i2c-s3c2410.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "common-smdk.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_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init smdk2410_init_time(void)
+{
+ s3c2410_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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 = s3c2410_init_irq,
+ .init_machine = smdk2410_init,
+ .init_time = smdk2410_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2413.c b/arch/arm/mach-s3c24xx/mach-smdk2413.c
new file mode 100644
index 000000000..ca80167f2
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-smdk2413.c
@@ -0,0 +1,158 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// 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.
+
+#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/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/memblock.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 <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <linux/platform_data/usb-s3c2410_udc.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <mach/gpio-samsung.h>
+#include <mach/fb.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "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,
+ &s3c2412_device_dma,
+};
+
+static void __init smdk2413_fixup(struct tag *tags, char **cmdline)
+{
+ if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
+ memblock_add(0x30000000, SZ_64M);
+ }
+}
+
+static void __init smdk2413_map_io(void)
+{
+ s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc));
+ s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init smdk2413_init_time(void)
+{
+ s3c2412_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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 = s3c2412_init_irq,
+ .map_io = smdk2413_map_io,
+ .init_machine = smdk2413_machine_init,
+ .init_time = samsung_timer_init,
+MACHINE_END
+
+MACHINE_START(SMDK2412, "SMDK2412")
+ /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+ .atag_offset = 0x100,
+
+ .fixup = smdk2413_fixup,
+ .init_irq = s3c2412_init_irq,
+ .map_io = smdk2413_map_io,
+ .init_machine = smdk2413_machine_init,
+ .init_time = samsung_timer_init,
+MACHINE_END
+
+MACHINE_START(SMDK2413, "SMDK2413")
+ /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+ .atag_offset = 0x100,
+
+ .fixup = smdk2413_fixup,
+ .init_irq = s3c2412_init_irq,
+ .map_io = smdk2413_map_io,
+ .init_machine = smdk2413_machine_init,
+ .init_time = smdk2413_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2416.c b/arch/arm/mach-s3c24xx/mach-smdk2416.c
new file mode 100644
index 000000000..61c3e4589
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-smdk2416.c
@@ -0,0 +1,259 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// 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>
+
+#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/serial_s3c.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 <video/samsung_fimd.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/regs-s3c2443-clock.h>
+#include <mach/gpio-samsung.h>
+
+#include <linux/platform_data/leds-s3c24xx.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <plat/sdhci.h>
+#include <linux/platform_data/usb-s3c2410_udc.h>
+#include <linux/platform_data/s3c-hsudc.h>
+#include <plat/samsung-time.h>
+
+#include <plat/fb.h>
+
+#include "common.h"
+#include "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] = {
+ .default_bpp = 16,
+ .max_bpp = 32,
+ .xres = 800,
+ .yres = 480,
+ },
+};
+
+static struct fb_videomode smdk2416_lcd_timing = {
+ .pixclock = 41094,
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+};
+
+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],
+ .vtiming = &smdk2416_lcd_timing,
+ .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,
+ &s3c2443_device_dma,
+};
+
+static void __init smdk2416_init_time(void)
+{
+ s3c2416_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+static void __init smdk2416_map_io(void)
+{
+ s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc));
+ s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+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 = s3c2416_init_irq,
+ .map_io = smdk2416_map_io,
+ .init_machine = smdk2416_machine_init,
+ .init_time = smdk2416_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2440.c b/arch/arm/mach-s3c24xx/mach-smdk2440.c
new file mode 100644
index 000000000..7bafcd8ea
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-smdk2440.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.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.
+
+#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/serial_s3c.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 <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/fb.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "common-smdk.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_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init smdk2440_init_time(void)
+{
+ s3c2440_init_clocks(16934400);
+ samsung_timer_init();
+}
+
+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 = s3c2440_init_irq,
+ .map_io = smdk2440_map_io,
+ .init_machine = smdk2440_machine_init,
+ .init_time = smdk2440_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2443.c b/arch/arm/mach-s3c24xx/mach-smdk2443.c
new file mode 100644
index 000000000..2358ed5ed
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-smdk2443.c
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// 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
+
+#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/serial_s3c.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 <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/fb.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "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,
+ &s3c2443_device_dma,
+};
+
+static void __init smdk2443_map_io(void)
+{
+ s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc));
+ s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init smdk2443_init_time(void)
+{
+ s3c2443_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+static void __init smdk2443_machine_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+ 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 = s3c2443_init_irq,
+ .map_io = smdk2443_map_io,
+ .init_machine = smdk2443_machine_init,
+ .init_time = smdk2443_init_time,
+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
index 000000000..8d8ddd6ea
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-tct_hammer.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright (c) 2007 TinCanTools
+// David Anders <danders@amltd.com>
+//
+// @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/serial_s3c.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 <linux/platform_data/i2c-s3c2410.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 <plat/samsung-time.h>
+
+#include "common.h"
+
+static struct resource tct_hammer_nor_resource =
+ DEFINE_RES_MEM(0x00000000, SZ_16M);
+
+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_uarts(tct_hammer_uartcfgs, ARRAY_SIZE(tct_hammer_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init tct_hammer_init_time(void)
+{
+ s3c2410_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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 = s3c2410_init_irq,
+ .init_machine = tct_hammer_init,
+ .init_time = tct_hammer_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-vr1000.c b/arch/arm/mach-s3c24xx/mach-vr1000.c
new file mode 100644
index 000000000..853e74f9b
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-vr1000.c
@@ -0,0 +1,338 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// 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/
+
+#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/serial_s3c.h>
+#include <linux/io.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 <linux/platform_data/leds-s3c24xx.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <linux/platform_data/asoc-s3c24xx_simtec.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/samsung-time.h>
+
+#include "bast.h"
+#include "common.h"
+#include "simtec.h"
+#include "vr1000.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 = VR1000_IRQ_SERIAL + 0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = VR1000_BAUDBASE,
+ },
+ [1] = {
+ .mapbase = VR1000_SERIAL_MAPBASE(1),
+ .irq = VR1000_IRQ_SERIAL + 1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = VR1000_BAUDBASE,
+ },
+ [2] = {
+ .mapbase = VR1000_SERIAL_MAPBASE(2),
+ .irq = VR1000_IRQ_SERIAL + 2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = VR1000_BAUDBASE,
+ },
+ [3] = {
+ .mapbase = VR1000_SERIAL_MAPBASE(3),
+ .irq = VR1000_IRQ_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] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000, 4),
+ [1] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000 + 0x40, 0x40),
+ [2] = DEFINE_RES_NAMED(VR1000_IRQ_DM9000A, 1, NULL, IORESOURCE_IRQ \
+ | IORESOURCE_IRQ_HIGHLEVEL),
+};
+
+static struct resource vr1000_dm9k1_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000 + 0x80, 4),
+ [1] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000 + 0xC0, 0x40),
+ [2] = DEFINE_RES_NAMED(VR1000_IRQ_DM9000N, 1, NULL, 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 = {
+ &s3c2410_device_dclk,
+ &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 void vr1000_power_off(void)
+{
+ gpio_direction_output(S3C2410_GPB(9), 1);
+}
+
+static void __init vr1000_map_io(void)
+{
+ pm_power_off = vr1000_power_off;
+
+ s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
+ s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init vr1000_init_time(void)
+{
+ s3c2410_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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 = s3c2410_init_irq,
+ .init_time = vr1000_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-vstms.c b/arch/arm/mach-s3c24xx/mach-vstms.c
new file mode 100644
index 000000000..d76b28b65
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/mach-vstms.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// (C) 2006 Thomas Gleixner <tglx@linutronix.de>
+//
+// Derived from mach-smdk2413.c - (C) 2006 Simtec Electronics
+
+#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/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/rawnand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <linux/memblock.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 <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/fb.h>
+
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/samsung-time.h>
+
+#include "common.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,
+ .ecc_mode = NAND_ECC_SOFT,
+};
+
+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,
+ &s3c2412_device_dma,
+};
+
+static void __init vstms_fixup(struct tag *tags, char **cmdline)
+{
+ if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
+ memblock_add(0x30000000, SZ_64M);
+ }
+}
+
+static void __init vstms_map_io(void)
+{
+ s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc));
+ s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init vstms_init_time(void)
+{
+ s3c2412_init_clocks(12000000);
+ samsung_timer_init();
+}
+
+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 = s3c2412_init_irq,
+ .init_machine = vstms_init,
+ .map_io = vstms_map_io,
+ .init_time = vstms_init_time,
+MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/nand-core.h b/arch/arm/mach-s3c24xx/nand-core.h
new file mode 100644
index 000000000..8de633d41
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/nand-core.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S3C - Nand Controller core functions
+ */
+
+#ifndef __ASM_ARCH_NAND_CORE_H
+#define __ASM_ARCH_NAND_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_nand_setname(char *name)
+{
+#ifdef CONFIG_S3C_DEV_NAND
+ s3c_device_nand.name = name;
+#endif
+}
+
+#endif /* __ASM_ARCH_NAND_CORE_H */
diff --git a/arch/arm/mach-s3c24xx/osiris.h b/arch/arm/mach-s3c24xx/osiris.h
new file mode 100644
index 000000000..b6c9c5ed2
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/osiris.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2005 Simtec Electronics
+ * http://www.simtec.co.uk/products/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * OSIRIS - CPLD control constants
+ * OSIRIS - Memory map definitions
+ */
+
+#ifndef __MACH_S3C24XX_OSIRIS_H
+#define __MACH_S3C24XX_OSIRIS_H __FILE__
+
+/* 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)
+
+/* 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 /* __MACH_S3C24XX_OSIRIS_H */
diff --git a/arch/arm/mach-s3c24xx/otom.h b/arch/arm/mach-s3c24xx/otom.h
new file mode 100644
index 000000000..c800f67d0
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/otom.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * (c) 2005 Guillaume GOURAT / NexVision
+ * guillaume.gourat@nexvision.fr
+ *
+ * NexVision OTOM board memory map definitions
+ */
+
+/*
+ * 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 __MACH_S3C24XX_OTOM_H
+#define __MACH_S3C24XX_OTOM_H __FILE__
+
+#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)
+
+#endif /* __MACH_S3C24XX_OTOM_H */
diff --git a/arch/arm/mach-s3c24xx/pll-s3c2410.c b/arch/arm/mach-s3c24xx/pll-s3c2410.c
new file mode 100644
index 000000000..0561f79dd
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/pll-s3c2410.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright (c) 2006-2007 Simtec Electronics
+// http://armlinux.simtec.co.uk/
+// Ben Dooks <ben@simtec.co.uk>
+// Vincent Sanders <vince@arm.linux.org.uk>
+//
+// S3C2410 CPU PLL tables
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+
+/* This array should be sorted in ascending order of the frequencies */
+static struct cpufreq_frequency_table pll_vals_12MHz[] = {
+ { .frequency = 34000000, .driver_data = PLLVAL(82, 2, 3), },
+ { .frequency = 45000000, .driver_data = PLLVAL(82, 1, 3), },
+ { .frequency = 48000000, .driver_data = PLLVAL(120, 2, 3), },
+ { .frequency = 51000000, .driver_data = PLLVAL(161, 3, 3), },
+ { .frequency = 56000000, .driver_data = PLLVAL(142, 2, 3), },
+ { .frequency = 68000000, .driver_data = PLLVAL(82, 2, 2), },
+ { .frequency = 79000000, .driver_data = PLLVAL(71, 1, 2), },
+ { .frequency = 85000000, .driver_data = PLLVAL(105, 2, 2), },
+ { .frequency = 90000000, .driver_data = PLLVAL(112, 2, 2), },
+ { .frequency = 101000000, .driver_data = PLLVAL(127, 2, 2), },
+ { .frequency = 113000000, .driver_data = PLLVAL(105, 1, 2), },
+ { .frequency = 118000000, .driver_data = PLLVAL(150, 2, 2), },
+ { .frequency = 124000000, .driver_data = PLLVAL(116, 1, 2), },
+ { .frequency = 135000000, .driver_data = PLLVAL(82, 2, 1), },
+ { .frequency = 147000000, .driver_data = PLLVAL(90, 2, 1), },
+ { .frequency = 152000000, .driver_data = PLLVAL(68, 1, 1), },
+ { .frequency = 158000000, .driver_data = PLLVAL(71, 1, 1), },
+ { .frequency = 170000000, .driver_data = PLLVAL(77, 1, 1), },
+ { .frequency = 180000000, .driver_data = PLLVAL(82, 1, 1), },
+ { .frequency = 186000000, .driver_data = PLLVAL(85, 1, 1), },
+ { .frequency = 192000000, .driver_data = PLLVAL(88, 1, 1), },
+ { .frequency = 203000000, .driver_data = PLLVAL(161, 3, 1), },
+
+ /* 2410A extras */
+
+ { .frequency = 210000000, .driver_data = PLLVAL(132, 2, 1), },
+ { .frequency = 226000000, .driver_data = PLLVAL(105, 1, 1), },
+ { .frequency = 266000000, .driver_data = PLLVAL(125, 1, 1), },
+ { .frequency = 268000000, .driver_data = PLLVAL(126, 1, 1), },
+ { .frequency = 270000000, .driver_data = PLLVAL(127, 1, 1), },
+};
+
+static int s3c2410_plls_add(struct device *dev, struct subsys_interface *sif)
+{
+ return s3c_plltab_register(pll_vals_12MHz, ARRAY_SIZE(pll_vals_12MHz));
+}
+
+static struct subsys_interface s3c2410_plls_interface = {
+ .name = "s3c2410_plls",
+ .subsys = &s3c2410_subsys,
+ .add_dev = s3c2410_plls_add,
+};
+
+static int __init s3c2410_pll_init(void)
+{
+ return subsys_interface_register(&s3c2410_plls_interface);
+
+}
+arch_initcall(s3c2410_pll_init);
+
+static struct subsys_interface s3c2410a_plls_interface = {
+ .name = "s3c2410a_plls",
+ .subsys = &s3c2410a_subsys,
+ .add_dev = s3c2410_plls_add,
+};
+
+static int __init s3c2410a_pll_init(void)
+{
+ return subsys_interface_register(&s3c2410a_plls_interface);
+}
+arch_initcall(s3c2410a_pll_init);
diff --git a/arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c b/arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c
new file mode 100644
index 000000000..2ec3a2f9a
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2006-2007 Simtec Electronics
+// http://armlinux.simtec.co.uk/
+// Ben Dooks <ben@simtec.co.uk>
+// Vincent Sanders <vince@arm.linux.org.uk>
+//
+// S3C2440/S3C2442 CPU PLL tables (12MHz Crystal)
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+
+/* This array should be sorted in ascending order of the frequencies */
+static struct cpufreq_frequency_table s3c2440_plls_12[] = {
+ { .frequency = 75000000, .driver_data = PLLVAL(0x75, 3, 3), }, /* FVco 600.000000 */
+ { .frequency = 80000000, .driver_data = PLLVAL(0x98, 4, 3), }, /* FVco 640.000000 */
+ { .frequency = 90000000, .driver_data = PLLVAL(0x70, 2, 3), }, /* FVco 720.000000 */
+ { .frequency = 100000000, .driver_data = PLLVAL(0x5c, 1, 3), }, /* FVco 800.000000 */
+ { .frequency = 110000000, .driver_data = PLLVAL(0x66, 1, 3), }, /* FVco 880.000000 */
+ { .frequency = 120000000, .driver_data = PLLVAL(0x70, 1, 3), }, /* FVco 960.000000 */
+ { .frequency = 150000000, .driver_data = PLLVAL(0x75, 3, 2), }, /* FVco 600.000000 */
+ { .frequency = 160000000, .driver_data = PLLVAL(0x98, 4, 2), }, /* FVco 640.000000 */
+ { .frequency = 170000000, .driver_data = PLLVAL(0x4d, 1, 2), }, /* FVco 680.000000 */
+ { .frequency = 180000000, .driver_data = PLLVAL(0x70, 2, 2), }, /* FVco 720.000000 */
+ { .frequency = 190000000, .driver_data = PLLVAL(0x57, 1, 2), }, /* FVco 760.000000 */
+ { .frequency = 200000000, .driver_data = PLLVAL(0x5c, 1, 2), }, /* FVco 800.000000 */
+ { .frequency = 210000000, .driver_data = PLLVAL(0x84, 2, 2), }, /* FVco 840.000000 */
+ { .frequency = 220000000, .driver_data = PLLVAL(0x66, 1, 2), }, /* FVco 880.000000 */
+ { .frequency = 230000000, .driver_data = PLLVAL(0x6b, 1, 2), }, /* FVco 920.000000 */
+ { .frequency = 240000000, .driver_data = PLLVAL(0x70, 1, 2), }, /* FVco 960.000000 */
+ { .frequency = 300000000, .driver_data = PLLVAL(0x75, 3, 1), }, /* FVco 600.000000 */
+ { .frequency = 310000000, .driver_data = PLLVAL(0x93, 4, 1), }, /* FVco 620.000000 */
+ { .frequency = 320000000, .driver_data = PLLVAL(0x98, 4, 1), }, /* FVco 640.000000 */
+ { .frequency = 330000000, .driver_data = PLLVAL(0x66, 2, 1), }, /* FVco 660.000000 */
+ { .frequency = 340000000, .driver_data = PLLVAL(0x4d, 1, 1), }, /* FVco 680.000000 */
+ { .frequency = 350000000, .driver_data = PLLVAL(0xa7, 4, 1), }, /* FVco 700.000000 */
+ { .frequency = 360000000, .driver_data = PLLVAL(0x70, 2, 1), }, /* FVco 720.000000 */
+ { .frequency = 370000000, .driver_data = PLLVAL(0xb1, 4, 1), }, /* FVco 740.000000 */
+ { .frequency = 380000000, .driver_data = PLLVAL(0x57, 1, 1), }, /* FVco 760.000000 */
+ { .frequency = 390000000, .driver_data = PLLVAL(0x7a, 2, 1), }, /* FVco 780.000000 */
+ { .frequency = 400000000, .driver_data = PLLVAL(0x5c, 1, 1), }, /* FVco 800.000000 */
+};
+
+static int s3c2440_plls12_add(struct device *dev, struct subsys_interface *sif)
+{
+ struct clk *xtal_clk;
+ unsigned long xtal;
+
+ xtal_clk = clk_get(NULL, "xtal");
+ if (IS_ERR(xtal_clk))
+ return PTR_ERR(xtal_clk);
+
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ if (xtal == 12000000) {
+ printk(KERN_INFO "Using PLL table for 12MHz crystal\n");
+ return s3c_plltab_register(s3c2440_plls_12,
+ ARRAY_SIZE(s3c2440_plls_12));
+ }
+
+ return 0;
+}
+
+static struct subsys_interface s3c2440_plls12_interface = {
+ .name = "s3c2440_plls12",
+ .subsys = &s3c2440_subsys,
+ .add_dev = s3c2440_plls12_add,
+};
+
+static int __init s3c2440_pll_12mhz(void)
+{
+ return subsys_interface_register(&s3c2440_plls12_interface);
+
+}
+arch_initcall(s3c2440_pll_12mhz);
+
+static struct subsys_interface s3c2442_plls12_interface = {
+ .name = "s3c2442_plls12",
+ .subsys = &s3c2442_subsys,
+ .add_dev = s3c2440_plls12_add,
+};
+
+static int __init s3c2442_pll_12mhz(void)
+{
+ return subsys_interface_register(&s3c2442_plls12_interface);
+
+}
+arch_initcall(s3c2442_pll_12mhz);
diff --git a/arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c b/arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c
new file mode 100644
index 000000000..4b3d9e36c
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2006-2008 Simtec Electronics
+// http://armlinux.simtec.co.uk/
+// Ben Dooks <ben@simtec.co.uk>
+// Vincent Sanders <vince@arm.linux.org.uk>
+//
+// S3C2440/S3C2442 CPU PLL tables (16.93444MHz Crystal)
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+
+/* This array should be sorted in ascending order of the frequencies */
+static struct cpufreq_frequency_table s3c2440_plls_169344[] = {
+ { .frequency = 78019200, .driver_data = PLLVAL(121, 5, 3), }, /* FVco 624.153600 */
+ { .frequency = 84067200, .driver_data = PLLVAL(131, 5, 3), }, /* FVco 672.537600 */
+ { .frequency = 90115200, .driver_data = PLLVAL(141, 5, 3), }, /* FVco 720.921600 */
+ { .frequency = 96163200, .driver_data = PLLVAL(151, 5, 3), }, /* FVco 769.305600 */
+ { .frequency = 102135600, .driver_data = PLLVAL(185, 6, 3), }, /* FVco 817.084800 */
+ { .frequency = 108259200, .driver_data = PLLVAL(171, 5, 3), }, /* FVco 866.073600 */
+ { .frequency = 114307200, .driver_data = PLLVAL(127, 3, 3), }, /* FVco 914.457600 */
+ { .frequency = 120234240, .driver_data = PLLVAL(134, 3, 3), }, /* FVco 961.873920 */
+ { .frequency = 126161280, .driver_data = PLLVAL(141, 3, 3), }, /* FVco 1009.290240 */
+ { .frequency = 132088320, .driver_data = PLLVAL(148, 3, 3), }, /* FVco 1056.706560 */
+ { .frequency = 138015360, .driver_data = PLLVAL(155, 3, 3), }, /* FVco 1104.122880 */
+ { .frequency = 144789120, .driver_data = PLLVAL(163, 3, 3), }, /* FVco 1158.312960 */
+ { .frequency = 150100363, .driver_data = PLLVAL(187, 9, 2), }, /* FVco 600.401454 */
+ { .frequency = 156038400, .driver_data = PLLVAL(121, 5, 2), }, /* FVco 624.153600 */
+ { .frequency = 162086400, .driver_data = PLLVAL(126, 5, 2), }, /* FVco 648.345600 */
+ { .frequency = 168134400, .driver_data = PLLVAL(131, 5, 2), }, /* FVco 672.537600 */
+ { .frequency = 174048000, .driver_data = PLLVAL(177, 7, 2), }, /* FVco 696.192000 */
+ { .frequency = 180230400, .driver_data = PLLVAL(141, 5, 2), }, /* FVco 720.921600 */
+ { .frequency = 186278400, .driver_data = PLLVAL(124, 4, 2), }, /* FVco 745.113600 */
+ { .frequency = 192326400, .driver_data = PLLVAL(151, 5, 2), }, /* FVco 769.305600 */
+ { .frequency = 198132480, .driver_data = PLLVAL(109, 3, 2), }, /* FVco 792.529920 */
+ { .frequency = 204271200, .driver_data = PLLVAL(185, 6, 2), }, /* FVco 817.084800 */
+ { .frequency = 210268800, .driver_data = PLLVAL(141, 4, 2), }, /* FVco 841.075200 */
+ { .frequency = 216518400, .driver_data = PLLVAL(171, 5, 2), }, /* FVco 866.073600 */
+ { .frequency = 222264000, .driver_data = PLLVAL(97, 2, 2), }, /* FVco 889.056000 */
+ { .frequency = 228614400, .driver_data = PLLVAL(127, 3, 2), }, /* FVco 914.457600 */
+ { .frequency = 234259200, .driver_data = PLLVAL(158, 4, 2), }, /* FVco 937.036800 */
+ { .frequency = 240468480, .driver_data = PLLVAL(134, 3, 2), }, /* FVco 961.873920 */
+ { .frequency = 246960000, .driver_data = PLLVAL(167, 4, 2), }, /* FVco 987.840000 */
+ { .frequency = 252322560, .driver_data = PLLVAL(141, 3, 2), }, /* FVco 1009.290240 */
+ { .frequency = 258249600, .driver_data = PLLVAL(114, 2, 2), }, /* FVco 1032.998400 */
+ { .frequency = 264176640, .driver_data = PLLVAL(148, 3, 2), }, /* FVco 1056.706560 */
+ { .frequency = 270950400, .driver_data = PLLVAL(120, 2, 2), }, /* FVco 1083.801600 */
+ { .frequency = 276030720, .driver_data = PLLVAL(155, 3, 2), }, /* FVco 1104.122880 */
+ { .frequency = 282240000, .driver_data = PLLVAL(92, 1, 2), }, /* FVco 1128.960000 */
+ { .frequency = 289578240, .driver_data = PLLVAL(163, 3, 2), }, /* FVco 1158.312960 */
+ { .frequency = 294235200, .driver_data = PLLVAL(131, 2, 2), }, /* FVco 1176.940800 */
+ { .frequency = 300200727, .driver_data = PLLVAL(187, 9, 1), }, /* FVco 600.401454 */
+ { .frequency = 306358690, .driver_data = PLLVAL(191, 9, 1), }, /* FVco 612.717380 */
+ { .frequency = 312076800, .driver_data = PLLVAL(121, 5, 1), }, /* FVco 624.153600 */
+ { .frequency = 318366720, .driver_data = PLLVAL(86, 3, 1), }, /* FVco 636.733440 */
+ { .frequency = 324172800, .driver_data = PLLVAL(126, 5, 1), }, /* FVco 648.345600 */
+ { .frequency = 330220800, .driver_data = PLLVAL(109, 4, 1), }, /* FVco 660.441600 */
+ { .frequency = 336268800, .driver_data = PLLVAL(131, 5, 1), }, /* FVco 672.537600 */
+ { .frequency = 342074880, .driver_data = PLLVAL(93, 3, 1), }, /* FVco 684.149760 */
+ { .frequency = 348096000, .driver_data = PLLVAL(177, 7, 1), }, /* FVco 696.192000 */
+ { .frequency = 355622400, .driver_data = PLLVAL(118, 4, 1), }, /* FVco 711.244800 */
+ { .frequency = 360460800, .driver_data = PLLVAL(141, 5, 1), }, /* FVco 720.921600 */
+ { .frequency = 366206400, .driver_data = PLLVAL(165, 6, 1), }, /* FVco 732.412800 */
+ { .frequency = 372556800, .driver_data = PLLVAL(124, 4, 1), }, /* FVco 745.113600 */
+ { .frequency = 378201600, .driver_data = PLLVAL(126, 4, 1), }, /* FVco 756.403200 */
+ { .frequency = 384652800, .driver_data = PLLVAL(151, 5, 1), }, /* FVco 769.305600 */
+ { .frequency = 391608000, .driver_data = PLLVAL(177, 6, 1), }, /* FVco 783.216000 */
+ { .frequency = 396264960, .driver_data = PLLVAL(109, 3, 1), }, /* FVco 792.529920 */
+ { .frequency = 402192000, .driver_data = PLLVAL(87, 2, 1), }, /* FVco 804.384000 */
+};
+
+static int s3c2440_plls169344_add(struct device *dev,
+ struct subsys_interface *sif)
+{
+ struct clk *xtal_clk;
+ unsigned long xtal;
+
+ xtal_clk = clk_get(NULL, "xtal");
+ if (IS_ERR(xtal_clk))
+ return PTR_ERR(xtal_clk);
+
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ if (xtal == 169344000) {
+ printk(KERN_INFO "Using PLL table for 16.9344MHz crystal\n");
+ return s3c_plltab_register(s3c2440_plls_169344,
+ ARRAY_SIZE(s3c2440_plls_169344));
+ }
+
+ return 0;
+}
+
+static struct subsys_interface s3c2440_plls169344_interface = {
+ .name = "s3c2440_plls169344",
+ .subsys = &s3c2440_subsys,
+ .add_dev = s3c2440_plls169344_add,
+};
+
+static int __init s3c2440_pll_16934400(void)
+{
+ return subsys_interface_register(&s3c2440_plls169344_interface);
+}
+arch_initcall(s3c2440_pll_16934400);
+
+static struct subsys_interface s3c2442_plls169344_interface = {
+ .name = "s3c2442_plls169344",
+ .subsys = &s3c2442_subsys,
+ .add_dev = s3c2440_plls169344_add,
+};
+
+static int __init s3c2442_pll_16934400(void)
+{
+ return subsys_interface_register(&s3c2442_plls169344_interface);
+}
+arch_initcall(s3c2442_pll_16934400);
diff --git a/arch/arm/mach-s3c24xx/pm-h1940.S b/arch/arm/mach-s3c24xx/pm-h1940.S
new file mode 100644
index 000000000..a7bbe336a
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/pm-h1940.S
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2006 Ben Dooks <ben-linux@fluff.org>
+ *
+ * H1940 Suspend to RAM
+ */
+
+#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
index 000000000..2d8ea7013
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/pm-s3c2410.c
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright (c) 2006 Simtec Electronics
+// Ben Dooks <ben@simtec.co.uk>
+//
+// S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support
+
+#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 <asm/mach-types.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include "h1940.h"
+
+static void s3c2410_pm_prepare(void)
+{
+ /* ensure at least GSTATUS3 has the resume address */
+
+ __raw_writel(__pa_symbol(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()) {
+ gpio_request_one(S3C2410_GPF(2), GPIOF_OUT_INIT_HIGH, NULL);
+ gpio_free(S3C2410_GPF(2));
+ }
+
+ 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()) {
+ gpio_request_one(S3C2410_GPF(2), GPIOF_OUT_INIT_LOW, NULL);
+ gpio_free(S3C2410_GPF(2));
+ }
+}
+
+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
index 000000000..2dfdaab0a
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/pm-s3c2412.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2006 Simtec Electronics
+// Ben Dooks <ben@simtec.co.uk>
+//
+// http://armlinux.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/syscore_ops.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <asm/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/wakeup-mask.h>
+
+#include "regs-dsc.h"
+#include "s3c2412-power.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();
+
+ pr_info("Failed to suspend the system\n");
+ return 1; /* Aborting suspend */
+}
+
+/* mapping of interrupts to parts of the wakeup mask */
+static const struct samsung_wakeup_mask wake_irqs[] = {
+ { .irq = IRQ_RTC, .bit = S3C2412_PWRCFG_RTC_MASKIRQ, },
+};
+
+static void s3c2412_pm_prepare(void)
+{
+ samsung_sync_wakemask(S3C2412_PWRCFG,
+ wake_irqs, ARRAY_SIZE(wake_irqs));
+}
+
+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
index 000000000..9a2f05e27
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/pm-s3c2416.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2010 Samsung Electronics Co., Ltd.
+// http://www.samsung.com
+//
+// S3C2416 - PM support (Based on Ben Dooks' S3C2412 PM support)
+
+#include <linux/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include "s3c2412-power.h"
+
+#ifdef CONFIG_PM_SLEEP
+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();
+
+ pr_info("Failed to suspend the system\n");
+ return 1; /* Aborting suspend */
+}
+
+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(__pa_symbol(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);
+#endif
+
+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/pm.c b/arch/arm/mach-s3c24xx/pm.c
new file mode 100644
index 000000000..adcb90645
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/pm.c
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright (c) 2004-2006 Simtec Electronics
+// Ben Dooks <ben@simtec.co.uk>
+//
+// S3C24XX Power Manager (Suspend-To-RAM) support
+//
+// See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information
+//
+// Parts based on arch/arm/mach-pxa/pm.c
+//
+// Thanks to Dimitry Andric for debugging
+
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/io.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-irq.h>
+#include <mach/gpio-samsung.h>
+
+#include <asm/mach/time.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/pm.h>
+
+#include "regs-mem.h"
+
+#define PFX "s3c24xx-pm: "
+
+#ifdef CONFIG_PM_SLEEP
+static struct sleep_save core_save[] = {
+ /* we restore the timings here, with the proviso that the board
+ * brings the system up in an slower, or equal frequency setting
+ * to the original system.
+ *
+ * if we cannot guarantee this, then things are going to go very
+ * wrong here, as we modify the refresh and both pll settings.
+ */
+
+ SAVE_ITEM(S3C2410_BWSCON),
+ SAVE_ITEM(S3C2410_BANKCON0),
+ SAVE_ITEM(S3C2410_BANKCON1),
+ SAVE_ITEM(S3C2410_BANKCON2),
+ SAVE_ITEM(S3C2410_BANKCON3),
+ SAVE_ITEM(S3C2410_BANKCON4),
+ SAVE_ITEM(S3C2410_BANKCON5),
+};
+#endif
+
+/* s3c_pm_check_resume_pin
+ *
+ * check to see if the pin is configured correctly for sleep mode, and
+ * make any necessary adjustments if it is not
+*/
+
+static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
+{
+ unsigned long irqstate;
+ unsigned long pinstate;
+ int irq = gpio_to_irq(pin);
+
+ if (irqoffs < 4)
+ irqstate = s3c_irqwake_intmask & (1L<<irqoffs);
+ else
+ irqstate = s3c_irqwake_eintmask & (1L<<irqoffs);
+
+ pinstate = s3c_gpio_getcfg(pin);
+
+ if (!irqstate) {
+ if (pinstate == S3C2410_GPIO_IRQ)
+ S3C_PMDBG("Leaving IRQ %d (pin %d) as is\n", irq, pin);
+ } else {
+ if (pinstate == S3C2410_GPIO_IRQ) {
+ S3C_PMDBG("Disabling IRQ %d (pin %d)\n", irq, pin);
+ s3c_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
+ }
+ }
+}
+
+/* s3c_pm_configure_extint
+ *
+ * configure all external interrupt pins
+*/
+
+void s3c_pm_configure_extint(void)
+{
+ int pin;
+
+ /* for each of the external interrupts (EINT0..EINT15) we
+ * need to check whether it is an external interrupt source,
+ * and then configure it as an input if it is not
+ */
+
+ for (pin = S3C2410_GPF(0); pin <= S3C2410_GPF(7); pin++) {
+ s3c_pm_check_resume_pin(pin, pin - S3C2410_GPF(0));
+ }
+
+ for (pin = S3C2410_GPG(0); pin <= S3C2410_GPG(7); pin++) {
+ s3c_pm_check_resume_pin(pin, (pin - S3C2410_GPG(0))+8);
+ }
+}
+
+#ifdef CONFIG_PM_SLEEP
+void s3c_pm_restore_core(void)
+{
+ s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
+}
+
+void s3c_pm_save_core(void)
+{
+ s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
+}
+#endif
diff --git a/arch/arm/mach-s3c24xx/regs-dsc.h b/arch/arm/mach-s3c24xx/regs-dsc.h
new file mode 100644
index 000000000..b50063627
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/regs-dsc.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * S3C2440/S3C2412 Signal Drive Strength Control
+ */
+
+
+#ifndef __ASM_ARCH_REGS_DSC_H
+#define __ASM_ARCH_REGS_DSC_H __FILE__
+
+/* S3C2412 */
+#define S3C2412_DSC0 S3C2410_GPIOREG(0xdc)
+#define S3C2412_DSC1 S3C2410_GPIOREG(0xe0)
+
+/* S3C2440 */
+#define S3C2440_DSC0 S3C2410_GPIOREG(0xc4)
+#define S3C2440_DSC1 S3C2410_GPIOREG(0xc8)
+
+#endif /* __ASM_ARCH_REGS_DSC_H */
+
diff --git a/arch/arm/mach-s3c24xx/regs-mem.h b/arch/arm/mach-s3c24xx/regs-mem.h
new file mode 100644
index 000000000..2f3bc48b5
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/regs-mem.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * S3C2410 Memory Control register definitions
+ */
+
+#ifndef __ARCH_ARM_MACH_S3C24XX_REGS_MEM_H
+#define __ARCH_ARM_MACH_S3C24XX_REGS_MEM_H __FILE__
+
+#define S3C2410_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
+
+#define S3C2410_BWSCON S3C2410_MEMREG(0x00)
+#define S3C2410_BANKCON0 S3C2410_MEMREG(0x04)
+#define S3C2410_BANKCON1 S3C2410_MEMREG(0x08)
+#define S3C2410_BANKCON2 S3C2410_MEMREG(0x0C)
+#define S3C2410_BANKCON3 S3C2410_MEMREG(0x10)
+#define S3C2410_BANKCON4 S3C2410_MEMREG(0x14)
+#define S3C2410_BANKCON5 S3C2410_MEMREG(0x18)
+#define S3C2410_BANKCON6 S3C2410_MEMREG(0x1C)
+#define S3C2410_BANKCON7 S3C2410_MEMREG(0x20)
+#define S3C2410_REFRESH S3C2410_MEMREG(0x24)
+#define S3C2410_BANKSIZE S3C2410_MEMREG(0x28)
+
+#define S3C2410_BWSCON_ST1 (1 << 7)
+#define S3C2410_BWSCON_ST2 (1 << 11)
+#define S3C2410_BWSCON_ST3 (1 << 15)
+#define S3C2410_BWSCON_ST4 (1 << 19)
+#define S3C2410_BWSCON_ST5 (1 << 23)
+
+#define S3C2410_BWSCON_GET(_bwscon, _bank) (((_bwscon) >> ((_bank) * 4)) & 0xf)
+
+#define S3C2410_BWSCON_WS (1 << 2)
+
+#define S3C2410_BANKCON_PMC16 (0x3)
+
+#define S3C2410_BANKCON_Tacp_SHIFT (2)
+#define S3C2410_BANKCON_Tcah_SHIFT (4)
+#define S3C2410_BANKCON_Tcoh_SHIFT (6)
+#define S3C2410_BANKCON_Tacc_SHIFT (8)
+#define S3C2410_BANKCON_Tcos_SHIFT (11)
+#define S3C2410_BANKCON_Tacs_SHIFT (13)
+
+#define S3C2410_BANKCON_SDRAM (0x3 << 15)
+
+#define S3C2410_REFRESH_SELF (1 << 22)
+
+#define S3C2410_BANKSIZE_MASK (0x7 << 0)
+
+#endif /* __ARCH_ARM_MACH_S3C24XX_REGS_MEM_H */
diff --git a/arch/arm/mach-s3c24xx/s3c2410.c b/arch/arm/mach-s3c24xx/s3c2410.c
new file mode 100644
index 000000000..21fd5404b
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/s3c2410.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2003-2005 Simtec Electronics
+// Ben Dooks <ben@simtec.co.uk>
+//
+// http://www.simtec.co.uk/products/EB2410ITX/
+
+#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/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.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 <mach/gpio-samsung.h>
+#include <asm/irq.h>
+#include <asm/system_misc.h>
+
+#include <plat/cpu-freq.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/pm.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+#include "common.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));
+}
+
+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_SLEEP
+ register_syscore_ops(&s3c2410_pm_syscore_ops);
+ register_syscore_ops(&s3c24xx_irq_syscore_ops);
+#endif
+
+ return device_register(&s3c2410_dev);
+}
+
+int __init s3c2410a_init(void)
+{
+ s3c2410_dev.bus = &s3c2410a_subsys;
+ return s3c2410_init();
+}
diff --git a/arch/arm/mach-s3c24xx/s3c2412-power.h b/arch/arm/mach-s3c24xx/s3c2412-power.h
new file mode 100644
index 000000000..0031cfaa1
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/s3c2412-power.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2003-2006 Simtec Electronics <linux@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ */
+
+#ifndef __ARCH_ARM_MACH_S3C24XX_S3C2412_POWER_H
+#define __ARCH_ARM_MACH_S3C24XX_S3C2412_POWER_H __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 /* __ARCH_ARM_MACH_S3C24XX_S3C2412_POWER_H */
diff --git a/arch/arm/mach-s3c24xx/s3c2412.c b/arch/arm/mach-s3c24xx/s3c2412.c
new file mode 100644
index 000000000..8fe4d4670
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/s3c2412.c
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2006 Simtec Electronics
+// Ben Dooks <ben@simtec.co.uk>
+//
+// http://armlinux.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/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/reboot.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/proc-fns.h>
+#include <asm/irq.h>
+#include <asm/system_misc.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq.h>
+#include <plat/devs.h>
+#include <plat/pm.h>
+#include <plat/regs-spi.h>
+
+#include "common.h"
+#include "nand-core.h"
+#include "regs-dsc.h"
+#include "s3c2412-power.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();
+}
+
+/* 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));
+}
+
+/* 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_SLEEP
+ register_syscore_ops(&s3c2412_pm_syscore_ops);
+ register_syscore_ops(&s3c24xx_irq_syscore_ops);
+#endif
+
+ 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
index 000000000..1cdb7bd3e
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/s3c2416.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// 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
+
+#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 <linux/reboot.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/gpio-samsung.h>
+#include <asm/proc-fns.h>
+#include <asm/irq.h>
+#include <asm/system_misc.h>
+
+#include <mach/regs-s3c2443-clock.h>
+#include <mach/rtc-core.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/sdhci.h>
+#include <plat/pm.h>
+
+#include <plat/iic-core.h>
+#include <plat/adc-core.h>
+
+#include "common.h"
+#include "fb-core.h"
+#include "nand-core.h"
+#include "spi-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,
+};
+
+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_SLEEP
+ register_syscore_ops(&s3c2416_pm_syscore_ops);
+ register_syscore_ops(&s3c24xx_irq_syscore_ops);
+ register_syscore_ops(&s3c2416_irq_syscore_ops);
+#endif
+
+ 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();
+ s3c64xx_spi_setname("s3c2443-spi");
+
+ 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
index 000000000..451d9851b
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/s3c2440.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2004-2006 Simtec Electronics
+// Ben Dooks <ben@simtec.co.uk>
+//
+// Samsung S3C2440 Mobile CPU support
+
+#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 <mach/gpio-samsung.h>
+#include <asm/irq.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+#include "common.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_SLEEP
+ register_syscore_ops(&s3c2410_pm_syscore_ops);
+ register_syscore_ops(&s3c24xx_irq_syscore_ops);
+ register_syscore_ops(&s3c244x_pm_syscore_ops);
+#endif
+
+ /* 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
index 000000000..432d68325
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/s3c2442.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright (c) 2004-2005 Simtec Electronics
+// http://armlinux.simtec.co.uk/
+// Ben Dooks <ben@simtec.co.uk>
+//
+// S3C2442 core and lock support
+
+#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 <mach/gpio-samsung.h>
+#include <linux/atomic.h>
+#include <asm/irq.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+#include "common.h"
+
+static struct device s3c2442_dev = {
+ .bus = &s3c2442_subsys,
+};
+
+int __init s3c2442_init(void)
+{
+ printk("S3C2442: Initialising architecture\n");
+
+#ifdef CONFIG_PM_SLEEP
+ register_syscore_ops(&s3c2410_pm_syscore_ops);
+ register_syscore_ops(&s3c24xx_irq_syscore_ops);
+ register_syscore_ops(&s3c244x_pm_syscore_ops);
+#endif
+
+ 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
index 000000000..313e369c3
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/s3c2443.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2007 Simtec Electronics
+// Ben Dooks <ben@simtec.co.uk>
+//
+// Samsung S3C2443 Mobile CPU support
+
+#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 <linux/reboot.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/gpio-samsung.h>
+#include <asm/irq.h>
+#include <asm/system_misc.h>
+
+#include <mach/regs-s3c2443-clock.h>
+#include <mach/rtc-core.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/adc-core.h>
+
+#include "fb-core.h"
+#include "nand-core.h"
+#include "spi-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,
+};
+
+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;
+
+ /* initialize device information early */
+ s3c64xx_spi_setname("s3c2443-spi");
+
+ 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
index 000000000..a75f588b9
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/s3c244x.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2004-2006 Simtec Electronics
+// Ben Dooks <ben@simtec.co.uk>
+//
+// Samsung S3C2440 and S3C2442 Mobile CPU support (not S3C2443)
+
+#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/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/system_misc.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 <mach/regs-gpio.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include "common.h"
+#include "nand-core.h"
+#include "regs-dsc.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";
+ s3c2410_device_dclk.name = "s3c2440-dclk";
+}
+
+/* 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_SLEEP
+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));
+}
+
+struct syscore_ops s3c244x_pm_syscore_ops = {
+ .suspend = s3c244x_suspend,
+ .resume = s3c244x_resume,
+};
+#endif
diff --git a/arch/arm/mach-s3c24xx/setup-camif.c b/arch/arm/mach-s3c24xx/setup-camif.c
new file mode 100644
index 000000000..2b262fae3
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/setup-camif.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2012 Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
+//
+// Helper functions for S3C24XX/S3C64XX SoC series CAMIF driver
+
+#include <linux/gpio.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio-samsung.h>
+
+/* Number of camera port pins, without FIELD */
+#define S3C_CAMIF_NUM_GPIOS 13
+
+/* Default camera port configuration helpers. */
+
+static void camif_get_gpios(int *gpio_start, int *gpio_reset)
+{
+#ifdef CONFIG_ARCH_S3C24XX
+ *gpio_start = S3C2410_GPJ(0);
+ *gpio_reset = S3C2410_GPJ(12);
+#else
+ /* s3c64xx */
+ *gpio_start = S3C64XX_GPF(0);
+ *gpio_reset = S3C64XX_GPF(3);
+#endif
+}
+
+int s3c_camif_gpio_get(void)
+{
+ int gpio_start, gpio_reset;
+ int ret, i;
+
+ camif_get_gpios(&gpio_start, &gpio_reset);
+
+ for (i = 0; i < S3C_CAMIF_NUM_GPIOS; i++) {
+ int gpio = gpio_start + i;
+
+ if (gpio == gpio_reset)
+ continue;
+
+ ret = gpio_request(gpio, "camif");
+ if (!ret)
+ ret = s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ if (ret) {
+ pr_err("failed to configure GPIO %d\n", gpio);
+ for (--i; i >= 0; i--)
+ gpio_free(gpio--);
+ return ret;
+ }
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+
+ return 0;
+}
+
+void s3c_camif_gpio_put(void)
+{
+ int i, gpio_start, gpio_reset;
+
+ camif_get_gpios(&gpio_start, &gpio_reset);
+
+ for (i = 0; i < S3C_CAMIF_NUM_GPIOS; i++) {
+ int gpio = gpio_start + i;
+ if (gpio != gpio_reset)
+ gpio_free(gpio);
+ }
+}
diff --git a/arch/arm/mach-s3c24xx/setup-i2c.c b/arch/arm/mach-s3c24xx/setup-i2c.c
new file mode 100644
index 000000000..1a01d44b5
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/setup-i2c.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright 2008 Simtec Electronics
+// Ben Dooks <ben@simtec.co.uk>
+//
+// S3C24XX Base setup for i2c device
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+
+struct platform_device;
+
+#include <plat/gpio-cfg.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.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
index 000000000..218346a36
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/setup-sdhci-gpio.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// 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
+
+#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 <mach/gpio-samsung.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-spi.c b/arch/arm/mach-s3c24xx/setup-spi.c
new file mode 100644
index 000000000..6c2b96a82
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/setup-spi.c
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// HS-SPI device setup for S3C2443/S3C2416
+//
+// Copyright (C) 2011 Samsung Electronics Ltd.
+// http://www.samsung.com/
+
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+
+#include <plat/gpio-cfg.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+
+#ifdef CONFIG_S3C64XX_DEV_SPI0
+int s3c64xx_spi0_cfg_gpio(void)
+{
+ /* enable hsspi bit in misccr */
+ s3c2410_modify_misccr(S3C2416_MISCCR_HSSPI_EN2, 1);
+
+ s3c_gpio_cfgall_range(S3C2410_GPE(11), 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+
+ return 0;
+}
+#endif
diff --git a/arch/arm/mach-s3c24xx/setup-ts.c b/arch/arm/mach-s3c24xx/setup-ts.c
new file mode 100644
index 000000000..53a14d4f4
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/setup-ts.c
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2010 Samsung Electronics Co., Ltd.
+// http://www.samsung.com/
+//
+// Based on S3C24XX setup for i2c device
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/gpio-cfg.h>
+#include <mach/hardware.h>
+#include <mach/gpio-samsung.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)
+{
+ s3c_gpio_cfgpin_range(S3C2410_GPG(12), 4, S3C_GPIO_SFN(3));
+}
diff --git a/arch/arm/mach-s3c24xx/simtec-audio.c b/arch/arm/mach-s3c24xx/simtec-audio.c
new file mode 100644
index 000000000..12e17f82d
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/simtec-audio.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2009 Simtec Electronics
+// http://armlinux.simtec.co.uk/
+// Ben Dooks <ben@simtec.co.uk>
+//
+// Audio setup for various Simtec S3C24XX implementations
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+
+#include <linux/platform_data/asoc-s3c24xx_simtec.h>
+#include <plat/devs.h>
+
+#include "bast.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
index 000000000..26b18497e
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/simtec-nor.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2008 Simtec Electronics
+// http://armlinux.simtec.co.uk/
+// Ben Dooks <ben@simtec.co.uk>
+//
+// Simtec NOR mapping
+
+#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 "bast.h"
+#include "simtec.h"
+
+static void simtec_nor_vpp(struct platform_device *pdev, int vpp)
+{
+ unsigned int val;
+
+ 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);
+}
+
+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] = DEFINE_RES_MEM(S3C2410_CS1 + 0x4000000, SZ_8M),
+};
+
+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
index 000000000..c19074d81
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/simtec-pm.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright 2004 Simtec Electronics
+// Ben Dooks <ben@simtec.co.uk>
+//
+// http://armlinux.simtec.co.uk/
+//
+// Power Management helpers for Simtec S3C24XX implementations
+
+#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 <asm/mach-types.h>
+
+#include <plat/pm.h>
+
+#include "regs-mem.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
index 000000000..dc1016ffe
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/simtec-usb.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// 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
+
+#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/hardware.h>
+#include <mach/gpio-samsung.h>
+#include <asm/irq.h>
+
+#include <linux/platform_data/usb-ohci-s3c2410.h>
+#include <plat/devs.h>
+
+#include "bast.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(BAST_IRQ_USBOC, usb_simtec_ocirq,
+ 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(BAST_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 __init 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
index 000000000..d96bd6087
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/simtec.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Simtec common functions
+ */
+
+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
index 000000000..659f9eff9
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/sleep-s3c2410.S
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * 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
+ */
+
+#include <linux/linkage.h>
+#include <linux/serial_s3c.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+
+#include "regs-mem.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
+ ret lr
diff --git a/arch/arm/mach-s3c24xx/sleep-s3c2412.S b/arch/arm/mach-s3c24xx/sleep-s3c2412.S
new file mode 100644
index 000000000..c373f1ca8
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/sleep-s3c2412.S
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2007 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2412 Power Manager low-level sleep support
+ */
+
+#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
+
+ ret lr
diff --git a/arch/arm/mach-s3c24xx/sleep.S b/arch/arm/mach-s3c24xx/sleep.S
new file mode 100644
index 000000000..f0f11ad60
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/sleep.S
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * 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
+ */
+
+#include <linux/linkage.h>
+#include <linux/serial_s3c.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+
+/*
+ * S3C24XX_DEBUG_RESUME is dangerous if your bootloader does not
+ * reset the UART configuration, only enable if you really need this!
+ */
+//#define S3C24XX_DEBUG_RESUME
+
+ .text
+
+ /* sleep magic, to allow the bootloader to check for an valid
+ * image to resume to. Must be the first word before the
+ * s3c_cpu_resume entry.
+ */
+
+ .word 0x2bedf00d
+
+ /* s3c_cpu_resume
+ *
+ * resume code entry for bootloader to call
+ */
+
+ENTRY(s3c_cpu_resume)
+ mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
+ msr cpsr_c, r0
+
+ @@ load UART to allow us to print the two characters for
+ @@ resume debug
+
+ mov r2, #S3C24XX_PA_UART & 0xff000000
+ orr r2, r2, #S3C24XX_PA_UART & 0xff000
+
+#if 0
+ /* SMDK2440 LED set */
+ mov r14, #S3C24XX_PA_GPIO
+ ldr r12, [ r14, #0x54 ]
+ bic r12, r12, #3<<4
+ orr r12, r12, #1<<7
+ str r12, [ r14, #0x54 ]
+#endif
+
+#ifdef S3C24XX_DEBUG_RESUME
+ mov r3, #'L'
+ strb r3, [ r2, #S3C2410_UTXH ]
+1001:
+ ldrb r14, [ r3, #S3C2410_UTRSTAT ]
+ tst r14, #S3C2410_UTRSTAT_TXE
+ beq 1001b
+#endif /* S3C24XX_DEBUG_RESUME */
+
+ b cpu_resume
diff --git a/arch/arm/mach-s3c24xx/spi-core.h b/arch/arm/mach-s3c24xx/spi-core.h
new file mode 100644
index 000000000..bb555ccbe
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/spi-core.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2012 Heiko Stuebner <heiko@sntech.de>
+ */
+
+#ifndef __PLAT_S3C_SPI_CORE_H
+#define __PLAT_S3C_SPI_CORE_H
+
+/* 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 s3c64xx_spi_setname(char *name)
+{
+#ifdef CONFIG_S3C64XX_DEV_SPI0
+ s3c64xx_device_spi0.name = name;
+#endif
+#ifdef CONFIG_S3C64XX_DEV_SPI1
+ s3c64xx_device_spi1.name = name;
+#endif
+#ifdef CONFIG_S3C64XX_DEV_SPI2
+ s3c64xx_device_spi2.name = name;
+#endif
+}
+
+#endif /* __PLAT_S3C_SPI_CORE_H */
diff --git a/arch/arm/mach-s3c24xx/vr1000.h b/arch/arm/mach-s3c24xx/vr1000.h
new file mode 100644
index 000000000..3cfa296be
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/vr1000.h
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2003 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * VR1000 - CPLD control constants
+ * Machine VR1000 - IRQ Number definitions
+ * Machine VR1000 - Memory map definitions
+ */
+
+#ifndef __MACH_S3C24XX_VR1000_H
+#define __MACH_S3C24XX_VR1000_H __FILE__
+
+#define VR1000_CPLD_CTRL2_RAMWEN (0x04) /* SRAM Write Enable */
+
+/* irq numbers to onboard peripherals */
+
+#define VR1000_IRQ_USBOC IRQ_EINT19
+#define VR1000_IRQ_IDE0 IRQ_EINT16
+#define VR1000_IRQ_IDE1 IRQ_EINT17
+#define VR1000_IRQ_SERIAL IRQ_EINT12
+#define VR1000_IRQ_DM9000A IRQ_EINT10
+#define VR1000_IRQ_DM9000N IRQ_EINT9
+#define VR1000_IRQ_SMALERT IRQ_EINT8
+
+/* map */
+
+#define VR1000_IOADDR(x) (S3C2410_ADDR((x) + 0x01300000))
+
+/* 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
+ * whether 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 /* __MACH_S3C24XX_VR1000_H */