summaryrefslogtreecommitdiff
path: root/arch/arm/mach-s3c64xx
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-s3c64xx')
-rw-r--r--arch/arm/mach-s3c64xx/Kconfig316
-rw-r--r--arch/arm/mach-s3c64xx/Makefile56
-rw-r--r--arch/arm/mach-s3c64xx/Makefile.boot2
-rw-r--r--arch/arm/mach-s3c64xx/common.c442
-rw-r--r--arch/arm/mach-s3c64xx/common.h59
-rw-r--r--arch/arm/mach-s3c64xx/cpuidle.c62
-rw-r--r--arch/arm/mach-s3c64xx/crag6410.h25
-rw-r--r--arch/arm/mach-s3c64xx/dev-audio.c228
-rw-r--r--arch/arm/mach-s3c64xx/dev-uart.c71
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/debug-macro.S38
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/dma.h56
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h94
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/hardware.h16
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/irqs.h185
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/map.h126
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/pm-core.h121
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-clock.h38
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-gpio.h187
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-irq.h19
-rw-r--r--arch/arm/mach-s3c64xx/irq-pm.c124
-rw-r--r--arch/arm/mach-s3c64xx/mach-anw6410.c238
-rw-r--r--arch/arm/mach-s3c64xx/mach-crag6410-module.c404
-rw-r--r--arch/arm/mach-s3c64xx/mach-crag6410.c863
-rw-r--r--arch/arm/mach-s3c64xx/mach-hmt.c282
-rw-r--r--arch/arm/mach-s3c64xx/mach-mini6410.c371
-rw-r--r--arch/arm/mach-s3c64xx/mach-ncp.c108
-rw-r--r--arch/arm/mach-s3c64xx/mach-real6410.c340
-rw-r--r--arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c76
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq.c400
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq.h20
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq5.c161
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq7.c177
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6400.c97
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6410.c710
-rw-r--r--arch/arm/mach-s3c64xx/pl080.c244
-rw-r--r--arch/arm/mach-s3c64xx/pm.c351
-rw-r--r--arch/arm/mach-s3c64xx/regs-gpio-memport.h24
-rw-r--r--arch/arm/mach-s3c64xx/regs-modem.h30
-rw-r--r--arch/arm/mach-s3c64xx/regs-srom.h58
-rw-r--r--arch/arm/mach-s3c64xx/regs-sys.h30
-rw-r--r--arch/arm/mach-s3c64xx/regs-syscon-power.h115
-rw-r--r--arch/arm/mach-s3c64xx/s3c6400.c97
-rw-r--r--arch/arm/mach-s3c64xx/s3c6410.c100
-rw-r--r--arch/arm/mach-s3c64xx/setup-fb-24bpp.c28
-rw-r--r--arch/arm/mach-s3c64xx/setup-i2c0.c29
-rw-r--r--arch/arm/mach-s3c64xx/setup-i2c1.c29
-rw-r--r--arch/arm/mach-s3c64xx/setup-ide.c44
-rw-r--r--arch/arm/mach-s3c64xx/setup-keypad.c25
-rw-r--r--arch/arm/mach-s3c64xx/setup-sdhci-gpio.c58
-rw-r--r--arch/arm/mach-s3c64xx/setup-spi.c31
-rw-r--r--arch/arm/mach-s3c64xx/setup-usb-phy.c91
-rw-r--r--arch/arm/mach-s3c64xx/sleep.S72
52 files changed, 7968 insertions, 0 deletions
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
new file mode 100644
index 000000000..eff95e950
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -0,0 +1,316 @@
+# Copyright 2008 Openmoko, Inc.
+# Simtec Electronics, Ben Dooks <ben@simtec.co.uk>
+#
+# Licensed under GPLv2
+
+if ARCH_S3C64XX
+
+# Configuration options for the S3C6410 CPU
+
+config CPU_S3C6400
+ bool
+ help
+ Enable S3C6400 CPU support
+
+config CPU_S3C6410
+ bool
+ help
+ Enable S3C6410 CPU support
+
+config S3C64XX_PL080
+ def_bool DMADEVICES
+ select ARM_AMBA
+ select AMBA_PL08X
+
+config S3C64XX_SETUP_SDHCI
+ bool
+ select S3C64XX_SETUP_SDHCI_GPIO
+ help
+ Internal configuration for default SDHCI setup for S3C6400 and
+ S3C6410 SoCs.
+
+config S3C64XX_DEV_ONENAND1
+ bool
+ help
+ Compile in platform device definition for OneNAND1 controller
+
+# platform specific device setup
+
+config S3C64XX_SETUP_I2C0
+ bool
+ default y
+ help
+ Common setup code for i2c bus 0.
+
+ Note, currently since i2c0 is always compiled, this setup helper
+ is always compiled with it.
+
+config S3C64XX_SETUP_I2C1
+ bool
+ help
+ Common setup code for i2c bus 1.
+
+config S3C64XX_SETUP_IDE
+ bool
+ help
+ Common setup code for S3C64XX IDE.
+
+config S3C64XX_SETUP_FB_24BPP
+ bool
+ help
+ Common setup code for S3C64XX with an 24bpp RGB display helper.
+
+config S3C64XX_SETUP_KEYPAD
+ bool
+ help
+ Common setup code for S3C64XX KEYPAD GPIO configurations
+
+config S3C64XX_SETUP_SDHCI_GPIO
+ bool
+ help
+ Common setup code for S3C64XX SDHCI GPIO configurations
+
+config S3C64XX_SETUP_SPI
+ bool
+ help
+ Common setup code for SPI GPIO configurations
+
+config S3C64XX_SETUP_USB_PHY
+ bool
+ help
+ Common setup code for USB PHY controller
+
+# S36400 Macchine support
+
+config MACH_SMDK6400
+ bool "SMDK6400"
+ select CPU_S3C6400
+ select S3C64XX_SETUP_SDHCI
+ select S3C_DEV_HSMMC1
+ help
+ Machine support for the Samsung SMDK6400
+
+# S3C6410 machine support
+
+config MACH_ANW6410
+ bool "A&W6410"
+ select CPU_S3C6410
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C_DEV_FB
+ help
+ Machine support for the A&W6410
+
+config MACH_MINI6410
+ bool "MINI6410"
+ select CPU_S3C6410
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C64XX_SETUP_SDHCI
+ select S3C_DEV_FB
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_TS
+ help
+ Machine support for the FriendlyARM MINI6410
+
+config MACH_REAL6410
+ bool "REAL6410"
+ select CPU_S3C6410
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C64XX_SETUP_SDHCI
+ select S3C_DEV_FB
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_TS
+ help
+ Machine support for the CoreWind REAL6410
+
+config MACH_SMDK6410
+ bool "SMDK6410"
+ select CPU_S3C6410
+ select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C64XX_SETUP_I2C1
+ select S3C64XX_SETUP_IDE
+ select S3C64XX_SETUP_KEYPAD
+ select S3C64XX_SETUP_SDHCI
+ select S3C64XX_SETUP_USB_PHY
+ select S3C_DEV_FB
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_I2C1
+ select S3C_DEV_RTC
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_USB_HSOTG
+ select S3C_DEV_WDT
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_BACKLIGHT
+ select SAMSUNG_DEV_IDE
+ select SAMSUNG_DEV_KEYPAD
+ select SAMSUNG_DEV_PWM
+ select SAMSUNG_DEV_TS
+ help
+ Machine support for the Samsung SMDK6410
+
+# At least some of the SMDK6410s were shipped with the card detect
+# for the MMC/SD slots connected to the same input. This means that
+# either the boards need to be altered to have channel0 to an alternate
+# configuration or that only one slot can be used.
+
+choice
+ prompt "SMDK6410 MMC/SD slot setup"
+ depends on MACH_SMDK6410
+
+config SMDK6410_SD_CH0
+ bool "Use channel 0 only"
+ depends on MACH_SMDK6410
+ help
+ Select CON7 (channel 0) as the MMC/SD slot, as
+ at least some SMDK6410 boards come with the
+ resistors fitted so that the card detects for
+ channels 0 and 1 are the same.
+
+config SMDK6410_SD_CH1
+ bool "Use channel 1 only"
+ depends on MACH_SMDK6410
+ help
+ Select CON6 (channel 1) as the MMC/SD slot, as
+ at least some SMDK6410 boards come with the
+ resistors fitted so that the card detects for
+ channels 0 and 1 are the same.
+
+endchoice
+
+config SMDK6410_WM1190_EV1
+ bool "Support Wolfson Microelectronics 1190-EV1 PMIC card"
+ depends on MACH_SMDK6410
+ depends on I2C=y
+ select MFD_WM8350_I2C
+ select REGULATOR
+ select REGULATOR_WM8350
+ help
+ The Wolfson Microelectronics 1190-EV1 is a WM835x based PMIC
+ and audio daughtercard for the Samsung SMDK6410 reference
+ platform. Enabling this option will build support for this
+ module into the kernel. The presence of the module will be
+ detected at runtime so the resulting kernel can be used
+ with or without the 1190-EV1 fitted.
+
+config SMDK6410_WM1192_EV1
+ bool "Support Wolfson Microelectronics 1192-EV1 PMIC card"
+ depends on MACH_SMDK6410
+ depends on I2C=y
+ select MFD_WM831X
+ select MFD_WM831X_I2C
+ select REGULATOR
+ select REGULATOR_WM831X
+ help
+ The Wolfson Microelectronics 1192-EV1 is a WM831x based PMIC
+ daughtercard for the Samsung SMDK6410 reference platform.
+ Enabling this option will build support for this module into
+ the kernel. The presence of the daughtercard will be
+ detected at runtime so the resulting kernel can be used
+ with or without the 1192-EV1 fitted.
+
+config MACH_NCP
+ bool "NCP"
+ select CPU_S3C6410
+ select S3C64XX_SETUP_I2C1
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_I2C1
+ help
+ Machine support for the Samsung NCP
+
+config MACH_HMT
+ bool "Airgoo HMT"
+ select CPU_S3C6410
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C_DEV_FB
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ select SAMSUNG_DEV_PWM
+ help
+ Machine support for the Airgoo HMT
+
+config MACH_SMARTQ
+ bool
+ select CPU_S3C6410
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C64XX_SETUP_SDHCI
+ select S3C64XX_SETUP_USB_PHY
+ select S3C_DEV_FB
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HWMON
+ select S3C_DEV_RTC
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_USB_HSOTG
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_PWM
+ select SAMSUNG_DEV_TS
+ help
+ Shared machine support for SmartQ 5/7
+
+config MACH_SMARTQ5
+ bool "SmartQ 5"
+ select MACH_SMARTQ
+ help
+ Machine support for the SmartQ 5
+
+config MACH_SMARTQ7
+ bool "SmartQ 7"
+ select MACH_SMARTQ
+ help
+ Machine support for the SmartQ 7
+
+config MACH_WLF_CRAGG_6410
+ bool "Wolfson Cragganmore 6410"
+ depends on I2C=y
+ select CPU_S3C6410
+ select LEDS_GPIO_REGISTER
+ select S3C64XX_DEV_SPI0
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C64XX_SETUP_I2C1
+ select S3C64XX_SETUP_IDE
+ select S3C64XX_SETUP_KEYPAD
+ select S3C64XX_SETUP_SDHCI
+ select S3C64XX_SETUP_SPI
+ select S3C64XX_SETUP_USB_PHY
+ select S3C_DEV_FB
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_I2C1
+ select S3C_DEV_RTC
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_USB_HSOTG
+ select S3C_DEV_WDT
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_KEYPAD
+ select SAMSUNG_DEV_PWM
+ help
+ Machine support for the Wolfson Cragganmore S3C6410 variant.
+
+config MACH_S3C64XX_DT
+ bool "Samsung S3C6400/S3C6410 machine using Device Tree"
+ select CLKSRC_OF
+ select CPU_S3C6400
+ select CPU_S3C6410
+ select PINCTRL
+ select PINCTRL_S3C64XX
+ select USE_OF
+ help
+ Machine support for Samsung S3C6400/S3C6410 machines with Device Tree
+ enabled.
+ Select this if a fdt blob is available for your S3C64XX SoC based
+ board.
+ Note: This is under development and not all peripherals can be
+ supported with this machine file.
+
+endif
diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile
new file mode 100644
index 000000000..17f4b07ec
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/Makefile
@@ -0,0 +1,56 @@
+# arch/arm/mach-s3c64xx/Makefile
+#
+# Copyright 2008 Openmoko, Inc.
+# Copyright 2008 Simtec Electronics
+#
+# Licensed under GPLv2
+
+# Core
+
+obj-y += common.o
+
+# Core support
+
+obj-$(CONFIG_CPU_S3C6400) += s3c6400.o
+obj-$(CONFIG_CPU_S3C6410) += s3c6410.o
+
+# PM
+
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_PM_SLEEP) += irq-pm.o sleep.o
+obj-$(CONFIG_CPU_IDLE) += cpuidle.o
+
+# DMA support
+
+obj-$(CONFIG_S3C64XX_PL080) += pl080.o
+
+# Device support
+
+obj-y += dev-uart.o
+obj-y += dev-audio.o
+
+# Device setup
+
+obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
+obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o
+obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o
+obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide.o
+obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o
+obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
+obj-$(CONFIG_S3C64XX_SETUP_SPI) += setup-spi.o
+obj-$(CONFIG_S3C64XX_SETUP_USB_PHY) += setup-usb-phy.o
+
+# Machine support
+
+obj-$(CONFIG_MACH_ANW6410) += mach-anw6410.o
+obj-$(CONFIG_MACH_HMT) += mach-hmt.o
+obj-$(CONFIG_MACH_MINI6410) += mach-mini6410.o
+obj-$(CONFIG_MACH_NCP) += mach-ncp.o
+obj-$(CONFIG_MACH_REAL6410) += mach-real6410.o
+obj-$(CONFIG_MACH_SMARTQ) += mach-smartq.o
+obj-$(CONFIG_MACH_SMARTQ5) += mach-smartq5.o
+obj-$(CONFIG_MACH_SMARTQ7) += mach-smartq7.o
+obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o
+obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o
+obj-$(CONFIG_MACH_WLF_CRAGG_6410) += mach-crag6410.o mach-crag6410-module.o
+obj-$(CONFIG_MACH_S3C64XX_DT) += mach-s3c64xx-dt.o
diff --git a/arch/arm/mach-s3c64xx/Makefile.boot b/arch/arm/mach-s3c64xx/Makefile.boot
new file mode 100644
index 000000000..c642333af
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/Makefile.boot
@@ -0,0 +1,2 @@
+ zreladdr-y += 0x50008000
+params_phys-y := 0x50000100
diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c
new file mode 100644
index 000000000..16547f264
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/common.c
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Common Codes for S3C64XX machines
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * NOTE: Code in this file is not used when booting with Device Tree support.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/clk-provider.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.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 <linux/dma-mapping.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/irqchip/arm-vic.h>
+#include <clocksource/samsung_pwm.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/system_misc.h>
+
+#include <mach/map.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/pm.h>
+#include <plat/gpio-cfg.h>
+#include <plat/irq-uart.h>
+#include <plat/pwm-core.h>
+#include <plat/regs-irqtype.h>
+#include <plat/watchdog-reset.h>
+
+#include "common.h"
+
+/* External clock frequency */
+static unsigned long xtal_f = 12000000, xusbxti_f = 48000000;
+
+void __init s3c64xx_set_xtal_freq(unsigned long freq)
+{
+ xtal_f = freq;
+}
+
+void __init s3c64xx_set_xusbxti_freq(unsigned long freq)
+{
+ xusbxti_f = freq;
+}
+
+/* uart registration process */
+
+static void __init s3c64xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ s3c24xx_init_uartdevs("s3c6400-uart", s3c64xx_uart_resources, cfg, no);
+}
+
+/* table of supported CPUs */
+
+static const char name_s3c6400[] = "S3C6400";
+static const char name_s3c6410[] = "S3C6410";
+
+static struct cpu_table cpu_ids[] __initdata = {
+ {
+ .idcode = S3C6400_CPU_ID,
+ .idmask = S3C64XX_CPU_MASK,
+ .map_io = s3c6400_map_io,
+ .init_uarts = s3c64xx_init_uarts,
+ .init = s3c6400_init,
+ .name = name_s3c6400,
+ }, {
+ .idcode = S3C6410_CPU_ID,
+ .idmask = S3C64XX_CPU_MASK,
+ .map_io = s3c6410_map_io,
+ .init_uarts = s3c64xx_init_uarts,
+ .init = s3c6410_init,
+ .name = name_s3c6410,
+ },
+};
+
+/* minimal IO mapping */
+
+/* see notes on uart map in arch/arm/mach-s3c64xx/include/mach/debug-macro.S */
+#define UART_OFFS (S3C_PA_UART & 0xfffff)
+
+static struct map_desc s3c_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S3C_VA_SYS,
+ .pfn = __phys_to_pfn(S3C64XX_PA_SYSCON),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_MEM,
+ .pfn = __phys_to_pfn(S3C64XX_PA_SROM),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)(S3C_VA_UART + UART_OFFS),
+ .pfn = __phys_to_pfn(S3C_PA_UART),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC0,
+ .pfn = __phys_to_pfn(S3C64XX_PA_VIC0),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC1,
+ .pfn = __phys_to_pfn(S3C64XX_PA_VIC1),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_TIMER,
+ .pfn = __phys_to_pfn(S3C_PA_TIMER),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C64XX_VA_GPIO,
+ .pfn = __phys_to_pfn(S3C64XX_PA_GPIO),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C64XX_VA_MODEM,
+ .pfn = __phys_to_pfn(S3C64XX_PA_MODEM),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_WATCHDOG,
+ .pfn = __phys_to_pfn(S3C64XX_PA_WATCHDOG),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_USB_HSPHY,
+ .pfn = __phys_to_pfn(S3C64XX_PA_USB_HSPHY),
+ .length = SZ_1K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct bus_type s3c64xx_subsys = {
+ .name = "s3c64xx-core",
+ .dev_name = "s3c64xx-core",
+};
+
+static struct device s3c64xx_dev = {
+ .bus = &s3c64xx_subsys,
+};
+
+static struct samsung_pwm_variant s3c64xx_pwm_variant = {
+ .bits = 32,
+ .div_base = 0,
+ .has_tint_cstat = true,
+ .tclk_mask = (1 << 7) | (1 << 6) | (1 << 5),
+};
+
+void __init samsung_set_timer_source(unsigned int event, unsigned int source)
+{
+ s3c64xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+ s3c64xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
+}
+
+void __init samsung_timer_init(void)
+{
+ unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
+ IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
+ IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
+ };
+
+ samsung_pwm_clocksource_init(S3C_VA_TIMER,
+ timer_irqs, &s3c64xx_pwm_variant);
+}
+
+/* read cpu identification code */
+
+void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
+{
+ /* initialise the io descriptors we need for initialisation */
+ iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
+ iotable_init(mach_desc, size);
+
+ /* detect cpu id */
+ s3c64xx_init_cpu();
+
+ s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+ samsung_pwm_set_platdata(&s3c64xx_pwm_variant);
+}
+
+static __init int s3c64xx_dev_init(void)
+{
+ /* Not applicable when using DT. */
+ if (of_have_populated_dt())
+ return 0;
+
+ subsys_system_register(&s3c64xx_subsys, NULL);
+ return device_register(&s3c64xx_dev);
+}
+core_initcall(s3c64xx_dev_init);
+
+/*
+ * setup the sources the vic should advertise resume
+ * for, even though it is not doing the wake
+ * (set_irq_wake needs to be valid)
+ */
+#define IRQ_VIC0_RESUME (1 << (IRQ_RTC_TIC - IRQ_VIC0_BASE))
+#define IRQ_VIC1_RESUME (1 << (IRQ_RTC_ALARM - IRQ_VIC1_BASE) | \
+ 1 << (IRQ_PENDN - IRQ_VIC1_BASE) | \
+ 1 << (IRQ_HSMMC0 - IRQ_VIC1_BASE) | \
+ 1 << (IRQ_HSMMC1 - IRQ_VIC1_BASE) | \
+ 1 << (IRQ_HSMMC2 - IRQ_VIC1_BASE))
+
+void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
+{
+ /*
+ * FIXME: there is no better place to put this at the moment
+ * (s3c64xx_clk_init needs ioremap and must happen before init_time
+ * samsung_wdt_reset_init needs clocks)
+ */
+ s3c64xx_clk_init(NULL, xtal_f, xusbxti_f, soc_is_s3c6400(), S3C_VA_SYS);
+ samsung_wdt_reset_init(S3C_VA_WATCHDOG);
+
+ printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
+
+ /* initialise the pair of VICs */
+ vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, IRQ_VIC0_RESUME);
+ vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, IRQ_VIC1_RESUME);
+}
+
+#define eint_offset(irq) ((irq) - IRQ_EINT(0))
+#define eint_irq_to_bit(irq) ((u32)(1 << eint_offset(irq)))
+
+static inline void s3c_irq_eint_mask(struct irq_data *data)
+{
+ u32 mask;
+
+ mask = __raw_readl(S3C64XX_EINT0MASK);
+ mask |= (u32)data->chip_data;
+ __raw_writel(mask, S3C64XX_EINT0MASK);
+}
+
+static void s3c_irq_eint_unmask(struct irq_data *data)
+{
+ u32 mask;
+
+ mask = __raw_readl(S3C64XX_EINT0MASK);
+ mask &= ~((u32)data->chip_data);
+ __raw_writel(mask, S3C64XX_EINT0MASK);
+}
+
+static inline void s3c_irq_eint_ack(struct irq_data *data)
+{
+ __raw_writel((u32)data->chip_data, S3C64XX_EINT0PEND);
+}
+
+static void s3c_irq_eint_maskack(struct irq_data *data)
+{
+ /* compiler should in-line these */
+ s3c_irq_eint_mask(data);
+ s3c_irq_eint_ack(data);
+}
+
+static int s3c_irq_eint_set_type(struct irq_data *data, unsigned int type)
+{
+ int offs = eint_offset(data->irq);
+ int pin, pin_val;
+ int shift;
+ u32 ctrl, mask;
+ u32 newvalue = 0;
+ void __iomem *reg;
+
+ if (offs > 27)
+ return -EINVAL;
+
+ if (offs <= 15)
+ reg = S3C64XX_EINT0CON0;
+ else
+ reg = S3C64XX_EINT0CON1;
+
+ switch (type) {
+ case IRQ_TYPE_NONE:
+ printk(KERN_WARNING "No edge setting!\n");
+ break;
+
+ case IRQ_TYPE_EDGE_RISING:
+ newvalue = S3C2410_EXTINT_RISEEDGE;
+ break;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ newvalue = S3C2410_EXTINT_FALLEDGE;
+ break;
+
+ case IRQ_TYPE_EDGE_BOTH:
+ newvalue = S3C2410_EXTINT_BOTHEDGE;
+ break;
+
+ case IRQ_TYPE_LEVEL_LOW:
+ newvalue = S3C2410_EXTINT_LOWLEV;
+ break;
+
+ case IRQ_TYPE_LEVEL_HIGH:
+ newvalue = S3C2410_EXTINT_HILEV;
+ break;
+
+ default:
+ printk(KERN_ERR "No such irq type %d", type);
+ return -1;
+ }
+
+ if (offs <= 15)
+ shift = (offs / 2) * 4;
+ else
+ shift = ((offs - 16) / 2) * 4;
+ mask = 0x7 << shift;
+
+ ctrl = __raw_readl(reg);
+ ctrl &= ~mask;
+ ctrl |= newvalue << shift;
+ __raw_writel(ctrl, reg);
+
+ /* set the GPIO pin appropriately */
+
+ if (offs < 16) {
+ pin = S3C64XX_GPN(offs);
+ pin_val = S3C_GPIO_SFN(2);
+ } else if (offs < 23) {
+ pin = S3C64XX_GPL(offs + 8 - 16);
+ pin_val = S3C_GPIO_SFN(3);
+ } else {
+ pin = S3C64XX_GPM(offs - 23);
+ pin_val = S3C_GPIO_SFN(3);
+ }
+
+ s3c_gpio_cfgpin(pin, pin_val);
+
+ return 0;
+}
+
+static struct irq_chip s3c_irq_eint = {
+ .name = "s3c-eint",
+ .irq_mask = s3c_irq_eint_mask,
+ .irq_unmask = s3c_irq_eint_unmask,
+ .irq_mask_ack = s3c_irq_eint_maskack,
+ .irq_ack = s3c_irq_eint_ack,
+ .irq_set_type = s3c_irq_eint_set_type,
+ .irq_set_wake = s3c_irqext_wake,
+};
+
+/* s3c_irq_demux_eint
+ *
+ * This function demuxes the IRQ from the group0 external interrupts,
+ * from IRQ_EINT(0) to IRQ_EINT(27). It is designed to be inlined into
+ * the specific handlers s3c_irq_demux_eintX_Y.
+ */
+static inline void s3c_irq_demux_eint(unsigned int start, unsigned int end)
+{
+ u32 status = __raw_readl(S3C64XX_EINT0PEND);
+ u32 mask = __raw_readl(S3C64XX_EINT0MASK);
+ unsigned int irq;
+
+ status &= ~mask;
+ status >>= start;
+ status &= (1 << (end - start + 1)) - 1;
+
+ for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
+ if (status & 1)
+ generic_handle_irq(irq);
+
+ status >>= 1;
+ }
+}
+
+static void s3c_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
+{
+ s3c_irq_demux_eint(0, 3);
+}
+
+static void s3c_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc)
+{
+ s3c_irq_demux_eint(4, 11);
+}
+
+static void s3c_irq_demux_eint12_19(unsigned int irq, struct irq_desc *desc)
+{
+ s3c_irq_demux_eint(12, 19);
+}
+
+static void s3c_irq_demux_eint20_27(unsigned int irq, struct irq_desc *desc)
+{
+ s3c_irq_demux_eint(20, 27);
+}
+
+static int __init s3c64xx_init_irq_eint(void)
+{
+ int irq;
+
+ /* On DT-enabled systems EINTs are handled by pinctrl-s3c64xx driver. */
+ if (of_have_populated_dt())
+ return -ENODEV;
+
+ for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
+ irq_set_chip_and_handler(irq, &s3c_irq_eint, handle_level_irq);
+ irq_set_chip_data(irq, (void *)eint_irq_to_bit(irq));
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ irq_set_chained_handler(IRQ_EINT0_3, s3c_irq_demux_eint0_3);
+ irq_set_chained_handler(IRQ_EINT4_11, s3c_irq_demux_eint4_11);
+ irq_set_chained_handler(IRQ_EINT12_19, s3c_irq_demux_eint12_19);
+ irq_set_chained_handler(IRQ_EINT20_27, s3c_irq_demux_eint20_27);
+
+ return 0;
+}
+arch_initcall(s3c64xx_init_irq_eint);
+
+void s3c64xx_restart(enum reboot_mode mode, const char *cmd)
+{
+ if (mode != REBOOT_SOFT)
+ samsung_wdt_reset();
+
+ /* if all else fails, or mode was for soft, jump to 0 */
+ soft_restart(0);
+}
diff --git a/arch/arm/mach-s3c64xx/common.h b/arch/arm/mach-s3c64xx/common.h
new file mode 100644
index 000000000..9eb864412
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/common.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Common Header for S3C64XX machines
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_S3C64XX_COMMON_H
+#define __ARCH_ARM_MACH_S3C64XX_COMMON_H
+
+#include <linux/reboot.h>
+
+void s3c64xx_init_irq(u32 vic0, u32 vic1);
+void s3c64xx_init_io(struct map_desc *mach_desc, int size);
+
+void s3c64xx_restart(enum reboot_mode mode, const char *cmd);
+
+void s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
+ unsigned long xusbxti_f, bool is_s3c6400, void __iomem *reg_base);
+void s3c64xx_set_xtal_freq(unsigned long freq);
+void s3c64xx_set_xusbxti_freq(unsigned long freq);
+
+#ifdef CONFIG_CPU_S3C6400
+
+extern int s3c6400_init(void);
+extern void s3c6400_init_irq(void);
+extern void s3c6400_map_io(void);
+
+#else
+#define s3c6400_map_io NULL
+#define s3c6400_init NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C6410
+
+extern int s3c6410_init(void);
+extern void s3c6410_init_irq(void);
+extern void s3c6410_map_io(void);
+
+#else
+#define s3c6410_map_io NULL
+#define s3c6410_init NULL
+#endif
+
+#ifdef CONFIG_S3C64XX_PL080
+extern struct pl08x_platform_data s3c64xx_dma0_plat_data;
+extern struct pl08x_platform_data s3c64xx_dma1_plat_data;
+#endif
+
+#endif /* __ARCH_ARM_MACH_S3C64XX_COMMON_H */
diff --git a/arch/arm/mach-s3c64xx/cpuidle.c b/arch/arm/mach-s3c64xx/cpuidle.c
new file mode 100644
index 000000000..93aa8cb70
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/cpuidle.c
@@ -0,0 +1,62 @@
+/* linux/arch/arm/mach-s3c64xx/cpuidle.c
+ *
+ * Copyright (c) 2011 Wolfson Microelectronics, plc
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/cpuidle.h>
+#include <linux/io.h>
+#include <linux/export.h>
+#include <linux/time.h>
+
+#include <asm/cpuidle.h>
+
+#include <mach/map.h>
+
+#include "regs-sys.h"
+#include "regs-syscon-power.h"
+
+static int s3c64xx_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ unsigned long tmp;
+
+ /* Setup PWRCFG to enter idle mode */
+ tmp = __raw_readl(S3C64XX_PWR_CFG);
+ tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
+ tmp |= S3C64XX_PWRCFG_CFG_WFI_IDLE;
+ __raw_writel(tmp, S3C64XX_PWR_CFG);
+
+ cpu_do_idle();
+
+ return index;
+}
+
+static struct cpuidle_driver s3c64xx_cpuidle_driver = {
+ .name = "s3c64xx_cpuidle",
+ .owner = THIS_MODULE,
+ .states = {
+ {
+ .enter = s3c64xx_enter_idle,
+ .exit_latency = 1,
+ .target_residency = 1,
+ .name = "IDLE",
+ .desc = "System active, ARM gated",
+ },
+ },
+ .state_count = 1,
+};
+
+static int __init s3c64xx_init_cpuidle(void)
+{
+ return cpuidle_register(&s3c64xx_cpuidle_driver, NULL);
+}
+device_initcall(s3c64xx_init_cpuidle);
diff --git a/arch/arm/mach-s3c64xx/crag6410.h b/arch/arm/mach-s3c64xx/crag6410.h
new file mode 100644
index 000000000..dcbe17f5e
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/crag6410.h
@@ -0,0 +1,25 @@
+/* Cragganmore 6410 shared definitions
+ *
+ * Copyright 2011 Wolfson Microelectronics plc
+ * Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef MACH_CRAG6410_H
+#define MACH_CRAG6410_H
+
+#include <mach/gpio-samsung.h>
+
+#define GLENFARCLAS_PMIC_IRQ_BASE IRQ_BOARD_START
+#define BANFF_PMIC_IRQ_BASE (IRQ_BOARD_START + 64)
+
+#define PCA935X_GPIO_BASE GPIO_BOARD_START
+#define CODEC_GPIO_BASE (GPIO_BOARD_START + 8)
+#define GLENFARCLAS_PMIC_GPIO_BASE (GPIO_BOARD_START + 32)
+#define BANFF_PMIC_GPIO_BASE (GPIO_BOARD_START + 64)
+#define MMGPIO_GPIO_BASE (GPIO_BOARD_START + 96)
+
+#endif
diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c
new file mode 100644
index 000000000..ff780a8d8
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/dev-audio.c
@@ -0,0 +1,228 @@
+/* linux/arch/arm/plat-s3c/dev-audio.c
+ *
+ * Copyright 2009 Wolfson Microelectronics
+ * Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+#include <linux/export.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <mach/dma.h>
+
+#include <plat/devs.h>
+#include <linux/platform_data/asoc-s3c.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio-samsung.h>
+
+static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev)
+{
+ unsigned int base;
+
+ switch (pdev->id) {
+ case 0:
+ base = S3C64XX_GPD(0);
+ break;
+ case 1:
+ base = S3C64XX_GPE(0);
+ break;
+ case 2:
+ s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
+ return 0;
+ default:
+ printk(KERN_DEBUG "Invalid I2S Controller number: %d\n",
+ pdev->id);
+ return -EINVAL;
+ }
+
+ s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));
+
+ return 0;
+}
+
+static struct resource s3c64xx_iis0_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C64XX_PA_IIS0, SZ_256),
+ [1] = DEFINE_RES_DMA(DMACH_I2S0_OUT),
+ [2] = DEFINE_RES_DMA(DMACH_I2S0_IN),
+};
+
+static struct s3c_audio_pdata i2sv3_pdata = {
+ .cfg_gpio = s3c64xx_i2s_cfg_gpio,
+};
+
+struct platform_device s3c64xx_device_iis0 = {
+ .name = "samsung-i2s",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c64xx_iis0_resource),
+ .resource = s3c64xx_iis0_resource,
+ .dev = {
+ .platform_data = &i2sv3_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_iis0);
+
+static struct resource s3c64xx_iis1_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C64XX_PA_IIS1, SZ_256),
+ [1] = DEFINE_RES_DMA(DMACH_I2S1_OUT),
+ [2] = DEFINE_RES_DMA(DMACH_I2S1_IN),
+};
+
+struct platform_device s3c64xx_device_iis1 = {
+ .name = "samsung-i2s",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c64xx_iis1_resource),
+ .resource = s3c64xx_iis1_resource,
+ .dev = {
+ .platform_data = &i2sv3_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_iis1);
+
+static struct resource s3c64xx_iisv4_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C64XX_PA_IISV4, SZ_256),
+ [1] = DEFINE_RES_DMA(DMACH_HSI_I2SV40_TX),
+ [2] = DEFINE_RES_DMA(DMACH_HSI_I2SV40_RX),
+};
+
+static struct s3c_audio_pdata i2sv4_pdata = {
+ .cfg_gpio = s3c64xx_i2s_cfg_gpio,
+ .type = {
+ .i2s = {
+ .quirks = QUIRK_PRI_6CHAN,
+ },
+ },
+};
+
+struct platform_device s3c64xx_device_iisv4 = {
+ .name = "samsung-i2s",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource),
+ .resource = s3c64xx_iisv4_resource,
+ .dev = {
+ .platform_data = &i2sv4_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_iisv4);
+
+
+/* PCM Controller platform_devices */
+
+static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
+{
+ unsigned int base;
+
+ switch (pdev->id) {
+ case 0:
+ base = S3C64XX_GPD(0);
+ break;
+ case 1:
+ base = S3C64XX_GPE(0);
+ break;
+ default:
+ printk(KERN_DEBUG "Invalid PCM Controller number: %d\n",
+ pdev->id);
+ return -EINVAL;
+ }
+
+ s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
+ return 0;
+}
+
+static struct resource s3c64xx_pcm0_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C64XX_PA_PCM0, SZ_256),
+ [1] = DEFINE_RES_DMA(DMACH_PCM0_TX),
+ [2] = DEFINE_RES_DMA(DMACH_PCM0_RX),
+};
+
+static struct s3c_audio_pdata s3c_pcm0_pdata = {
+ .cfg_gpio = s3c64xx_pcm_cfg_gpio,
+};
+
+struct platform_device s3c64xx_device_pcm0 = {
+ .name = "samsung-pcm",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c64xx_pcm0_resource),
+ .resource = s3c64xx_pcm0_resource,
+ .dev = {
+ .platform_data = &s3c_pcm0_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_pcm0);
+
+static struct resource s3c64xx_pcm1_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C64XX_PA_PCM1, SZ_256),
+ [1] = DEFINE_RES_DMA(DMACH_PCM1_TX),
+ [2] = DEFINE_RES_DMA(DMACH_PCM1_RX),
+};
+
+static struct s3c_audio_pdata s3c_pcm1_pdata = {
+ .cfg_gpio = s3c64xx_pcm_cfg_gpio,
+};
+
+struct platform_device s3c64xx_device_pcm1 = {
+ .name = "samsung-pcm",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c64xx_pcm1_resource),
+ .resource = s3c64xx_pcm1_resource,
+ .dev = {
+ .platform_data = &s3c_pcm1_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_pcm1);
+
+/* AC97 Controller platform devices */
+
+static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev)
+{
+ return s3c_gpio_cfgpin_range(S3C64XX_GPD(0), 5, S3C_GPIO_SFN(4));
+}
+
+static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev)
+{
+ return s3c_gpio_cfgpin_range(S3C64XX_GPE(0), 5, S3C_GPIO_SFN(4));
+}
+
+static struct resource s3c64xx_ac97_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C64XX_PA_AC97, SZ_256),
+ [1] = DEFINE_RES_DMA(DMACH_AC97_PCMOUT),
+ [2] = DEFINE_RES_DMA(DMACH_AC97_PCMIN),
+ [3] = DEFINE_RES_DMA(DMACH_AC97_MICIN),
+ [4] = DEFINE_RES_IRQ(IRQ_AC97),
+};
+
+static struct s3c_audio_pdata s3c_ac97_pdata;
+
+static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s3c64xx_device_ac97 = {
+ .name = "samsung-ac97",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c64xx_ac97_resource),
+ .resource = s3c64xx_ac97_resource,
+ .dev = {
+ .platform_data = &s3c_ac97_pdata,
+ .dma_mask = &s3c64xx_ac97_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_ac97);
+
+void __init s3c64xx_ac97_setup_gpio(int num)
+{
+ if (num == S3C64XX_AC97_GPD)
+ s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpd;
+ else
+ s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe;
+}
diff --git a/arch/arm/mach-s3c64xx/dev-uart.c b/arch/arm/mach-s3c64xx/dev-uart.c
new file mode 100644
index 000000000..46e18d77e
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/dev-uart.c
@@ -0,0 +1,71 @@
+/* linux/arch/arm/plat-s3c64xx/dev-uart.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Base S3C64XX UART resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+/* Serial port registrations */
+
+/* 64xx uarts are closer together */
+
+static struct resource s3c64xx_uart0_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_UART0, SZ_256),
+ [1] = DEFINE_RES_IRQ(IRQ_UART0),
+};
+
+static struct resource s3c64xx_uart1_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_UART1, SZ_256),
+ [1] = DEFINE_RES_IRQ(IRQ_UART1),
+};
+
+static struct resource s3c6xx_uart2_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_UART2, SZ_256),
+ [1] = DEFINE_RES_IRQ(IRQ_UART2),
+};
+
+static struct resource s3c64xx_uart3_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C_PA_UART3, SZ_256),
+ [1] = DEFINE_RES_IRQ(IRQ_UART3),
+};
+
+
+struct s3c24xx_uart_resources s3c64xx_uart_resources[] __initdata = {
+ [0] = {
+ .resources = s3c64xx_uart0_resource,
+ .nr_resources = ARRAY_SIZE(s3c64xx_uart0_resource),
+ },
+ [1] = {
+ .resources = s3c64xx_uart1_resource,
+ .nr_resources = ARRAY_SIZE(s3c64xx_uart1_resource),
+ },
+ [2] = {
+ .resources = s3c6xx_uart2_resource,
+ .nr_resources = ARRAY_SIZE(s3c6xx_uart2_resource),
+ },
+ [3] = {
+ .resources = s3c64xx_uart3_resource,
+ .nr_resources = ARRAY_SIZE(s3c64xx_uart3_resource),
+ },
+};
diff --git a/arch/arm/mach-s3c64xx/include/mach/debug-macro.S b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S
new file mode 100644
index 000000000..c9b95325b
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S
@@ -0,0 +1,38 @@
+/* arch/arm/mach-s3c6400/include/mach/debug-macro.S
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <linux/serial_s3c.h>
+#include <mach/map.h>
+
+ /* note, for the boot process to work we have to keep the UART
+ * virtual address aligned to an 1MiB boundary for the L1
+ * mapping the head code makes. We keep the UART virtual address
+ * aligned and add in the offset when we load the value here.
+ */
+
+ .macro addruart, rp, rv, tmp
+ ldr \rp, = S3C_PA_UART
+ ldr \rv, = (S3C_VA_UART + S3C_PA_UART & 0xfffff)
+#if CONFIG_DEBUG_S3C_UART != 0
+ add \rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART)
+ add \rv, \rv, #(0x400 * CONFIG_DEBUG_S3C_UART)
+#endif
+ .endm
+
+/* include the reset of the code which will do the work, we're only
+ * compiling for a single cpu processor type so the default of s3c2440
+ * will be fine with us.
+ */
+
+#include <debug/samsung.S>
diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h
new file mode 100644
index 000000000..096e14073
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/dma.h
@@ -0,0 +1,56 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/dma.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C6400 - DMA support
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H __FILE__
+
+#define S3C64XX_DMA_CHAN(name) ((unsigned long)(name))
+
+/* DMA0/SDMA0 */
+#define DMACH_UART0 S3C64XX_DMA_CHAN("uart0_tx")
+#define DMACH_UART0_SRC2 S3C64XX_DMA_CHAN("uart0_rx")
+#define DMACH_UART1 S3C64XX_DMA_CHAN("uart1_tx")
+#define DMACH_UART1_SRC2 S3C64XX_DMA_CHAN("uart1_rx")
+#define DMACH_UART2 S3C64XX_DMA_CHAN("uart2_tx")
+#define DMACH_UART2_SRC2 S3C64XX_DMA_CHAN("uart2_rx")
+#define DMACH_UART3 S3C64XX_DMA_CHAN("uart3_tx")
+#define DMACH_UART3_SRC2 S3C64XX_DMA_CHAN("uart3_rx")
+#define DMACH_PCM0_TX S3C64XX_DMA_CHAN("pcm0_tx")
+#define DMACH_PCM0_RX S3C64XX_DMA_CHAN("pcm0_rx")
+#define DMACH_I2S0_OUT S3C64XX_DMA_CHAN("i2s0_tx")
+#define DMACH_I2S0_IN S3C64XX_DMA_CHAN("i2s0_rx")
+#define DMACH_SPI0_TX S3C64XX_DMA_CHAN("spi0_tx")
+#define DMACH_SPI0_RX S3C64XX_DMA_CHAN("spi0_rx")
+#define DMACH_HSI_I2SV40_TX S3C64XX_DMA_CHAN("i2s2_tx")
+#define DMACH_HSI_I2SV40_RX S3C64XX_DMA_CHAN("i2s2_rx")
+
+/* DMA1/SDMA1 */
+#define DMACH_PCM1_TX S3C64XX_DMA_CHAN("pcm1_tx")
+#define DMACH_PCM1_RX S3C64XX_DMA_CHAN("pcm1_rx")
+#define DMACH_I2S1_OUT S3C64XX_DMA_CHAN("i2s1_tx")
+#define DMACH_I2S1_IN S3C64XX_DMA_CHAN("i2s1_rx")
+#define DMACH_SPI1_TX S3C64XX_DMA_CHAN("spi1_tx")
+#define DMACH_SPI1_RX S3C64XX_DMA_CHAN("spi1_rx")
+#define DMACH_AC97_PCMOUT S3C64XX_DMA_CHAN("ac97_out")
+#define DMACH_AC97_PCMIN S3C64XX_DMA_CHAN("ac97_in")
+#define DMACH_AC97_MICIN S3C64XX_DMA_CHAN("ac97_mic")
+#define DMACH_PWM S3C64XX_DMA_CHAN("pwm")
+#define DMACH_IRDA S3C64XX_DMA_CHAN("irda")
+#define DMACH_EXTERNAL S3C64XX_DMA_CHAN("external")
+#define DMACH_SECURITY_RX S3C64XX_DMA_CHAN("sec_rx")
+#define DMACH_SECURITY_TX S3C64XX_DMA_CHAN("sec_tx")
+
+enum dma_ch {
+ DMACH_MAX = 32
+};
+
+#include <linux/amba/pl08x.h>
+
+#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h b/arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h
new file mode 100644
index 000000000..9c81fac3b
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio-samsung.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C6400 - GPIO lib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef GPIO_SAMSUNG_S3C64XX_H
+#define GPIO_SAMSUNG_S3C64XX_H
+
+/* GPIO bank sizes */
+#define S3C64XX_GPIO_A_NR (8)
+#define S3C64XX_GPIO_B_NR (7)
+#define S3C64XX_GPIO_C_NR (8)
+#define S3C64XX_GPIO_D_NR (5)
+#define S3C64XX_GPIO_E_NR (5)
+#define S3C64XX_GPIO_F_NR (16)
+#define S3C64XX_GPIO_G_NR (7)
+#define S3C64XX_GPIO_H_NR (10)
+#define S3C64XX_GPIO_I_NR (16)
+#define S3C64XX_GPIO_J_NR (12)
+#define S3C64XX_GPIO_K_NR (16)
+#define S3C64XX_GPIO_L_NR (15)
+#define S3C64XX_GPIO_M_NR (6)
+#define S3C64XX_GPIO_N_NR (16)
+#define S3C64XX_GPIO_O_NR (16)
+#define S3C64XX_GPIO_P_NR (15)
+#define S3C64XX_GPIO_Q_NR (9)
+
+/* GPIO bank numbes */
+
+/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
+ * space for debugging purposes so that any accidental
+ * change from one gpio bank to another can be caught.
+*/
+
+#define S3C64XX_GPIO_NEXT(__gpio) \
+ ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum s3c_gpio_number {
+ S3C64XX_GPIO_A_START = 0,
+ S3C64XX_GPIO_B_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_A),
+ S3C64XX_GPIO_C_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_B),
+ S3C64XX_GPIO_D_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_C),
+ S3C64XX_GPIO_E_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_D),
+ S3C64XX_GPIO_F_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_E),
+ S3C64XX_GPIO_G_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_F),
+ S3C64XX_GPIO_H_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_G),
+ S3C64XX_GPIO_I_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_H),
+ S3C64XX_GPIO_J_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_I),
+ S3C64XX_GPIO_K_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_J),
+ S3C64XX_GPIO_L_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_K),
+ S3C64XX_GPIO_M_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_L),
+ S3C64XX_GPIO_N_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_M),
+ S3C64XX_GPIO_O_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_N),
+ S3C64XX_GPIO_P_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_O),
+ S3C64XX_GPIO_Q_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_P),
+};
+
+/* S3C64XX GPIO number definitions. */
+
+#define S3C64XX_GPA(_nr) (S3C64XX_GPIO_A_START + (_nr))
+#define S3C64XX_GPB(_nr) (S3C64XX_GPIO_B_START + (_nr))
+#define S3C64XX_GPC(_nr) (S3C64XX_GPIO_C_START + (_nr))
+#define S3C64XX_GPD(_nr) (S3C64XX_GPIO_D_START + (_nr))
+#define S3C64XX_GPE(_nr) (S3C64XX_GPIO_E_START + (_nr))
+#define S3C64XX_GPF(_nr) (S3C64XX_GPIO_F_START + (_nr))
+#define S3C64XX_GPG(_nr) (S3C64XX_GPIO_G_START + (_nr))
+#define S3C64XX_GPH(_nr) (S3C64XX_GPIO_H_START + (_nr))
+#define S3C64XX_GPI(_nr) (S3C64XX_GPIO_I_START + (_nr))
+#define S3C64XX_GPJ(_nr) (S3C64XX_GPIO_J_START + (_nr))
+#define S3C64XX_GPK(_nr) (S3C64XX_GPIO_K_START + (_nr))
+#define S3C64XX_GPL(_nr) (S3C64XX_GPIO_L_START + (_nr))
+#define S3C64XX_GPM(_nr) (S3C64XX_GPIO_M_START + (_nr))
+#define S3C64XX_GPN(_nr) (S3C64XX_GPIO_N_START + (_nr))
+#define S3C64XX_GPO(_nr) (S3C64XX_GPIO_O_START + (_nr))
+#define S3C64XX_GPP(_nr) (S3C64XX_GPIO_P_START + (_nr))
+#define S3C64XX_GPQ(_nr) (S3C64XX_GPIO_Q_START + (_nr))
+
+/* the end of the S3C64XX specific gpios */
+#define S3C64XX_GPIO_END (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
+#define S3C_GPIO_END S3C64XX_GPIO_END
+
+/* define the number of gpios we need to the one after the GPQ() range */
+#define GPIO_BOARD_START (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
+
+#endif /* GPIO_SAMSUNG_S3C64XX_H */
+
diff --git a/arch/arm/mach-s3c64xx/include/mach/hardware.h b/arch/arm/mach-s3c64xx/include/mach/hardware.h
new file mode 100644
index 000000000..862d033e5
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/hardware.h
@@ -0,0 +1,16 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/hardware.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C6400 - Hardware support
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H __FILE__
+
+/* currently nothing here, placeholder */
+
+#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/irqs.h b/arch/arm/mach-s3c64xx/include/mach/irqs.h
new file mode 100644
index 000000000..67bbd1dd0
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/irqs.h
@@ -0,0 +1,185 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/irqs.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - IRQ support
+ */
+
+#ifndef __ASM_MACH_S3C64XX_IRQS_H
+#define __ASM_MACH_S3C64XX_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....
+ *
+ * note, since we're using the VICs, our start must be a
+ * mulitple of 32 to allow the common code to work
+ */
+
+#define S3C_IRQ_OFFSET (32)
+
+#define S3C_IRQ(x) ((x) + S3C_IRQ_OFFSET)
+
+#define IRQ_VIC0_BASE S3C_IRQ(0)
+#define IRQ_VIC1_BASE S3C_IRQ(32)
+
+/* VIC based IRQs */
+
+#define S3C64XX_IRQ_VIC0(x) (IRQ_VIC0_BASE + (x))
+#define S3C64XX_IRQ_VIC1(x) (IRQ_VIC1_BASE + (x))
+
+/* VIC0 */
+
+#define IRQ_EINT0_3 S3C64XX_IRQ_VIC0(0)
+#define IRQ_EINT4_11 S3C64XX_IRQ_VIC0(1)
+#define IRQ_RTC_TIC S3C64XX_IRQ_VIC0(2)
+#define IRQ_CAMIF_C S3C64XX_IRQ_VIC0(3)
+#define IRQ_CAMIF_P S3C64XX_IRQ_VIC0(4)
+#define IRQ_CAMIF_MC S3C64XX_IRQ_VIC0(5)
+#define IRQ_S3C6410_IIC1 S3C64XX_IRQ_VIC0(5)
+#define IRQ_S3C6410_IIS S3C64XX_IRQ_VIC0(6)
+#define IRQ_S3C6400_CAMIF_MP S3C64XX_IRQ_VIC0(6)
+#define IRQ_CAMIF_WE_C S3C64XX_IRQ_VIC0(7)
+#define IRQ_S3C6410_G3D S3C64XX_IRQ_VIC0(8)
+#define IRQ_S3C6400_CAMIF_WE_P S3C64XX_IRQ_VIC0(8)
+#define IRQ_POST0 S3C64XX_IRQ_VIC0(9)
+#define IRQ_ROTATOR S3C64XX_IRQ_VIC0(10)
+#define IRQ_2D S3C64XX_IRQ_VIC0(11)
+#define IRQ_TVENC S3C64XX_IRQ_VIC0(12)
+#define IRQ_SCALER S3C64XX_IRQ_VIC0(13)
+#define IRQ_BATF S3C64XX_IRQ_VIC0(14)
+#define IRQ_JPEG S3C64XX_IRQ_VIC0(15)
+#define IRQ_MFC S3C64XX_IRQ_VIC0(16)
+#define IRQ_SDMA0 S3C64XX_IRQ_VIC0(17)
+#define IRQ_SDMA1 S3C64XX_IRQ_VIC0(18)
+#define IRQ_ARM_DMAERR S3C64XX_IRQ_VIC0(19)
+#define IRQ_ARM_DMA S3C64XX_IRQ_VIC0(20)
+#define IRQ_ARM_DMAS S3C64XX_IRQ_VIC0(21)
+#define IRQ_KEYPAD S3C64XX_IRQ_VIC0(22)
+#define IRQ_TIMER0_VIC S3C64XX_IRQ_VIC0(23)
+#define IRQ_TIMER1_VIC S3C64XX_IRQ_VIC0(24)
+#define IRQ_TIMER2_VIC S3C64XX_IRQ_VIC0(25)
+#define IRQ_WDT S3C64XX_IRQ_VIC0(26)
+#define IRQ_TIMER3_VIC S3C64XX_IRQ_VIC0(27)
+#define IRQ_TIMER4_VIC S3C64XX_IRQ_VIC0(28)
+#define IRQ_LCD_FIFO S3C64XX_IRQ_VIC0(29)
+#define IRQ_LCD_VSYNC S3C64XX_IRQ_VIC0(30)
+#define IRQ_LCD_SYSTEM S3C64XX_IRQ_VIC0(31)
+
+/* VIC1 */
+
+#define IRQ_EINT12_19 S3C64XX_IRQ_VIC1(0)
+#define IRQ_EINT20_27 S3C64XX_IRQ_VIC1(1)
+#define IRQ_PCM0 S3C64XX_IRQ_VIC1(2)
+#define IRQ_PCM1 S3C64XX_IRQ_VIC1(3)
+#define IRQ_AC97 S3C64XX_IRQ_VIC1(4)
+#define IRQ_UART0 S3C64XX_IRQ_VIC1(5)
+#define IRQ_UART1 S3C64XX_IRQ_VIC1(6)
+#define IRQ_UART2 S3C64XX_IRQ_VIC1(7)
+#define IRQ_UART3 S3C64XX_IRQ_VIC1(8)
+#define IRQ_DMA0 S3C64XX_IRQ_VIC1(9)
+#define IRQ_DMA1 S3C64XX_IRQ_VIC1(10)
+#define IRQ_ONENAND0 S3C64XX_IRQ_VIC1(11)
+#define IRQ_ONENAND1 S3C64XX_IRQ_VIC1(12)
+#define IRQ_NFC S3C64XX_IRQ_VIC1(13)
+#define IRQ_CFCON S3C64XX_IRQ_VIC1(14)
+#define IRQ_USBH S3C64XX_IRQ_VIC1(15)
+#define IRQ_SPI0 S3C64XX_IRQ_VIC1(16)
+#define IRQ_SPI1 S3C64XX_IRQ_VIC1(17)
+#define IRQ_IIC S3C64XX_IRQ_VIC1(18)
+#define IRQ_HSItx S3C64XX_IRQ_VIC1(19)
+#define IRQ_HSIrx S3C64XX_IRQ_VIC1(20)
+#define IRQ_RESERVED S3C64XX_IRQ_VIC1(21)
+#define IRQ_MSM S3C64XX_IRQ_VIC1(22)
+#define IRQ_HOSTIF S3C64XX_IRQ_VIC1(23)
+#define IRQ_HSMMC0 S3C64XX_IRQ_VIC1(24)
+#define IRQ_HSMMC1 S3C64XX_IRQ_VIC1(25)
+#define IRQ_HSMMC2 IRQ_SPI1 /* shared with SPI1 */
+#define IRQ_OTG S3C64XX_IRQ_VIC1(26)
+#define IRQ_IRDA S3C64XX_IRQ_VIC1(27)
+#define IRQ_RTC_ALARM S3C64XX_IRQ_VIC1(28)
+#define IRQ_SEC S3C64XX_IRQ_VIC1(29)
+#define IRQ_PENDN S3C64XX_IRQ_VIC1(30)
+#define IRQ_TC IRQ_PENDN
+#define IRQ_ADC S3C64XX_IRQ_VIC1(31)
+
+/* compatibility for device defines */
+
+#define IRQ_IIC1 IRQ_S3C6410_IIC1
+
+/* Since the IRQ_EINT(x) are a linear mapping on current s3c64xx series
+ * we just defined them as an IRQ_EINT(x) macro from S3C_IRQ_EINT_BASE
+ * which we place after the pair of VICs. */
+
+#define S3C_IRQ_EINT_BASE S3C_IRQ(64+5)
+
+#define S3C_EINT(x) ((x) + S3C_IRQ_EINT_BASE)
+#define IRQ_EINT(x) S3C_EINT(x)
+#define IRQ_EINT_BIT(x) ((x) - S3C_EINT(0))
+
+/* Next the external interrupt groups. These are similar to the IRQ_EINT(x)
+ * that they are sourced from the GPIO pins but with a different scheme for
+ * priority and source indication.
+ *
+ * The IRQ_EINT(x) can be thought of as 'group 0' of the available GPIO
+ * interrupts, but for historical reasons they are kept apart from these
+ * next interrupts.
+ *
+ * Use IRQ_EINT_GROUP(group, offset) to get the number for use in the
+ * machine specific support files.
+ */
+
+#define IRQ_EINT_GROUP1_NR (15)
+#define IRQ_EINT_GROUP2_NR (8)
+#define IRQ_EINT_GROUP3_NR (5)
+#define IRQ_EINT_GROUP4_NR (14)
+#define IRQ_EINT_GROUP5_NR (7)
+#define IRQ_EINT_GROUP6_NR (10)
+#define IRQ_EINT_GROUP7_NR (16)
+#define IRQ_EINT_GROUP8_NR (15)
+#define IRQ_EINT_GROUP9_NR (9)
+
+#define IRQ_EINT_GROUP_BASE S3C_EINT(28)
+#define IRQ_EINT_GROUP1_BASE (IRQ_EINT_GROUP_BASE + 0x00)
+#define IRQ_EINT_GROUP2_BASE (IRQ_EINT_GROUP1_BASE + IRQ_EINT_GROUP1_NR)
+#define IRQ_EINT_GROUP3_BASE (IRQ_EINT_GROUP2_BASE + IRQ_EINT_GROUP2_NR)
+#define IRQ_EINT_GROUP4_BASE (IRQ_EINT_GROUP3_BASE + IRQ_EINT_GROUP3_NR)
+#define IRQ_EINT_GROUP5_BASE (IRQ_EINT_GROUP4_BASE + IRQ_EINT_GROUP4_NR)
+#define IRQ_EINT_GROUP6_BASE (IRQ_EINT_GROUP5_BASE + IRQ_EINT_GROUP5_NR)
+#define IRQ_EINT_GROUP7_BASE (IRQ_EINT_GROUP6_BASE + IRQ_EINT_GROUP6_NR)
+#define IRQ_EINT_GROUP8_BASE (IRQ_EINT_GROUP7_BASE + IRQ_EINT_GROUP7_NR)
+#define IRQ_EINT_GROUP9_BASE (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR)
+
+#define IRQ_EINT_GROUP(group, no) (IRQ_EINT_GROUP##group##_BASE + (no))
+
+/* Define a group of interrupts for board-specific use (eg, for MFD
+ * interrupt controllers). */
+#define IRQ_BOARD_START (IRQ_EINT_GROUP9_BASE + IRQ_EINT_GROUP9_NR + 1)
+
+#ifdef CONFIG_MACH_WLF_CRAGG_6410
+#define IRQ_BOARD_NR 160
+#elif defined(CONFIG_SMDK6410_WM1190_EV1)
+#define IRQ_BOARD_NR 64
+#elif defined(CONFIG_SMDK6410_WM1192_EV1)
+#define IRQ_BOARD_NR 64
+#else
+#define IRQ_BOARD_NR 16
+#endif
+
+#define IRQ_BOARD_END (IRQ_BOARD_START + IRQ_BOARD_NR)
+
+/* Set the default NR_IRQS */
+
+#define NR_IRQS (IRQ_BOARD_END + 1)
+
+/* Compatibility */
+
+#define IRQ_ONENAND IRQ_ONENAND0
+#define IRQ_I2S0 IRQ_S3C6410_IIS
+
+#endif /* __ASM_MACH_S3C64XX_IRQS_H */
+
diff --git a/arch/arm/mach-s3c64xx/include/mach/map.h b/arch/arm/mach-s3c64xx/include/mach/map.h
new file mode 100644
index 000000000..f55ccb1ce
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/map.h
@@ -0,0 +1,126 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/map.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H __FILE__
+
+#include <plat/map-base.h>
+#include <plat/map-s3c.h>
+
+/*
+ * Post-mux Chip Select Regions Xm0CSn_
+ * These may be used by SROM, NAND or CF depending on settings
+ */
+
+#define S3C64XX_PA_XM0CSN0 (0x10000000)
+#define S3C64XX_PA_XM0CSN1 (0x18000000)
+#define S3C64XX_PA_XM0CSN2 (0x20000000)
+#define S3C64XX_PA_XM0CSN3 (0x28000000)
+#define S3C64XX_PA_XM0CSN4 (0x30000000)
+#define S3C64XX_PA_XM0CSN5 (0x38000000)
+
+/* HSMMC units */
+#define S3C64XX_PA_HSMMC(x) (0x7C200000 + ((x) * 0x100000))
+#define S3C64XX_PA_HSMMC0 S3C64XX_PA_HSMMC(0)
+#define S3C64XX_PA_HSMMC1 S3C64XX_PA_HSMMC(1)
+#define S3C64XX_PA_HSMMC2 S3C64XX_PA_HSMMC(2)
+
+#define S3C_PA_UART (0x7F005000)
+#define S3C_PA_UART0 (S3C_PA_UART + 0x00)
+#define S3C_PA_UART1 (S3C_PA_UART + 0x400)
+#define S3C_PA_UART2 (S3C_PA_UART + 0x800)
+#define S3C_PA_UART3 (S3C_PA_UART + 0xC00)
+#define S3C_UART_OFFSET (0x400)
+
+/* See notes on UART VA mapping in debug-macro.S */
+#define S3C_VA_UARTx(x) (S3C_VA_UART + (S3C_PA_UART & 0xfffff) + ((x) * S3C_UART_OFFSET))
+
+#define S3C_VA_UART0 S3C_VA_UARTx(0)
+#define S3C_VA_UART1 S3C_VA_UARTx(1)
+#define S3C_VA_UART2 S3C_VA_UARTx(2)
+#define S3C_VA_UART3 S3C_VA_UARTx(3)
+
+#define S3C64XX_PA_SROM (0x70000000)
+
+#define S3C64XX_PA_ONENAND0 (0x70100000)
+#define S3C64XX_PA_ONENAND0_BUF (0x20000000)
+#define S3C64XX_SZ_ONENAND0_BUF (SZ_64M)
+
+/* NAND and OneNAND1 controllers occupy the same register region
+ (depending on SoC POP version) */
+#define S3C64XX_PA_ONENAND1 (0x70200000)
+#define S3C64XX_PA_ONENAND1_BUF (0x28000000)
+#define S3C64XX_SZ_ONENAND1_BUF (SZ_64M)
+
+#define S3C64XX_PA_NAND (0x70200000)
+#define S3C64XX_PA_FB (0x77100000)
+#define S3C64XX_PA_USB_HSOTG (0x7C000000)
+#define S3C64XX_PA_WATCHDOG (0x7E004000)
+#define S3C64XX_PA_RTC (0x7E005000)
+#define S3C64XX_PA_KEYPAD (0x7E00A000)
+#define S3C64XX_PA_ADC (0x7E00B000)
+#define S3C64XX_PA_SYSCON (0x7E00F000)
+#define S3C64XX_PA_AC97 (0x7F001000)
+#define S3C64XX_PA_IIS0 (0x7F002000)
+#define S3C64XX_PA_IIS1 (0x7F003000)
+#define S3C64XX_PA_TIMER (0x7F006000)
+#define S3C64XX_PA_IIC0 (0x7F004000)
+#define S3C64XX_PA_SPI0 (0x7F00B000)
+#define S3C64XX_PA_SPI1 (0x7F00C000)
+#define S3C64XX_PA_PCM0 (0x7F009000)
+#define S3C64XX_PA_PCM1 (0x7F00A000)
+#define S3C64XX_PA_IISV4 (0x7F00D000)
+#define S3C64XX_PA_IIC1 (0x7F00F000)
+
+#define S3C64XX_PA_GPIO (0x7F008000)
+#define S3C64XX_SZ_GPIO SZ_4K
+
+#define S3C64XX_PA_SDRAM (0x50000000)
+
+#define S3C64XX_PA_CFCON (0x70300000)
+
+#define S3C64XX_PA_VIC0 (0x71200000)
+#define S3C64XX_PA_VIC1 (0x71300000)
+
+#define S3C64XX_PA_MODEM (0x74108000)
+
+#define S3C64XX_PA_USBHOST (0x74300000)
+
+#define S3C64XX_PA_USB_HSPHY (0x7C100000)
+
+/* compatibiltiy defines. */
+#define S3C_PA_TIMER S3C64XX_PA_TIMER
+#define S3C_PA_HSMMC0 S3C64XX_PA_HSMMC0
+#define S3C_PA_HSMMC1 S3C64XX_PA_HSMMC1
+#define S3C_PA_HSMMC2 S3C64XX_PA_HSMMC2
+#define S3C_PA_IIC S3C64XX_PA_IIC0
+#define S3C_PA_IIC1 S3C64XX_PA_IIC1
+#define S3C_PA_NAND S3C64XX_PA_NAND
+#define S3C_PA_ONENAND S3C64XX_PA_ONENAND0
+#define S3C_PA_ONENAND_BUF S3C64XX_PA_ONENAND0_BUF
+#define S3C_SZ_ONENAND_BUF S3C64XX_SZ_ONENAND0_BUF
+#define S3C_PA_FB S3C64XX_PA_FB
+#define S3C_PA_USBHOST S3C64XX_PA_USBHOST
+#define S3C_PA_USB_HSOTG S3C64XX_PA_USB_HSOTG
+#define S3C_PA_RTC S3C64XX_PA_RTC
+#define S3C_PA_WDT S3C64XX_PA_WATCHDOG
+#define S3C_PA_SPI0 S3C64XX_PA_SPI0
+#define S3C_PA_SPI1 S3C64XX_PA_SPI1
+
+#define SAMSUNG_PA_ADC S3C64XX_PA_ADC
+#define SAMSUNG_PA_CFCON S3C64XX_PA_CFCON
+#define SAMSUNG_PA_KEYPAD S3C64XX_PA_KEYPAD
+#define SAMSUNG_PA_TIMER S3C64XX_PA_TIMER
+
+#endif /* __ASM_ARCH_6400_MAP_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/pm-core.h b/arch/arm/mach-s3c64xx/include/mach/pm-core.h
new file mode 100644
index 000000000..a30a1e3ff
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/pm-core.h
@@ -0,0 +1,121 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/pm-core.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - PM core support for arch/arm/plat-s3c/pm.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_S3C64XX_PM_CORE_H
+#define __MACH_S3C64XX_PM_CORE_H __FILE__
+
+#include <linux/serial_s3c.h>
+
+#include <mach/regs-gpio.h>
+
+static inline void s3c_pm_debug_init_uart(void)
+{
+ u32 tmp = __raw_readl(S3C_PCLK_GATE);
+
+ /* As a note, since the S3C64XX UARTs generally have multiple
+ * clock sources, we simply enable PCLK at the moment and hope
+ * that the resume settings for the UART are suitable for the
+ * use with PCLK.
+ */
+
+ tmp |= S3C_CLKCON_PCLK_UART0;
+ tmp |= S3C_CLKCON_PCLK_UART1;
+ tmp |= S3C_CLKCON_PCLK_UART2;
+ tmp |= S3C_CLKCON_PCLK_UART3;
+
+ __raw_writel(tmp, S3C_PCLK_GATE);
+ udelay(10);
+}
+
+static inline void s3c_pm_arch_prepare_irqs(void)
+{
+ /* VIC should have already been taken care of */
+
+ /* clear any pending EINT0 interrupts */
+ __raw_writel(__raw_readl(S3C64XX_EINT0PEND), S3C64XX_EINT0PEND);
+}
+
+static inline void s3c_pm_arch_stop_clocks(void)
+{
+}
+
+static inline void s3c_pm_arch_show_resume_irqs(void)
+{
+}
+
+/* make these defines, we currently do not have any need to change
+ * the IRQ wake controls depending on the CPU we are running on */
+
+#define s3c_irqwake_eintallow ((1 << 28) - 1)
+#define s3c_irqwake_intallow (~0)
+
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+ struct pm_uart_save *save)
+{
+ u32 ucon = __raw_readl(regs + S3C2410_UCON);
+ u32 ucon_clk = ucon & S3C6400_UCON_CLKMASK;
+ u32 save_clk = save->ucon & S3C6400_UCON_CLKMASK;
+ u32 new_ucon;
+ u32 delta;
+
+ /* S3C64XX UART blocks only support level interrupts, so ensure that
+ * when we restore unused UART blocks we force the level interrupt
+ * settigs. */
+ save->ucon |= S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL;
+
+ /* We have a constraint on changing the clock type of the UART
+ * between UCLKx and PCLK, so ensure that when we restore UCON
+ * that the CLK field is correctly modified if the bootloader
+ * has changed anything.
+ */
+ if (ucon_clk != save_clk) {
+ new_ucon = save->ucon;
+ delta = ucon_clk ^ save_clk;
+
+ /* change from UCLKx => wrong PCLK,
+ * either UCLK can be tested for by a bit-test
+ * with UCLK0 */
+ if (ucon_clk & S3C6400_UCON_UCLK0 &&
+ !(save_clk & S3C6400_UCON_UCLK0) &&
+ delta & S3C6400_UCON_PCLK2) {
+ new_ucon &= ~S3C6400_UCON_UCLK0;
+ } else if (delta == S3C6400_UCON_PCLK2) {
+ /* as an precaution, don't change from
+ * PCLK2 => PCLK or vice-versa */
+ new_ucon ^= S3C6400_UCON_PCLK2;
+ }
+
+ S3C_PMDBG("ucon change %04x => %04x (save=%04x)\n",
+ ucon, new_ucon, save->ucon);
+ save->ucon = new_ucon;
+ }
+}
+
+static inline void s3c_pm_restored_gpios(void)
+{
+ /* ensure sleep mode has been cleared from the system */
+
+ __raw_writel(0, S3C64XX_SLPEN);
+}
+
+static inline void samsung_pm_saved_gpios(void)
+{
+ /* turn on the sleep mode and keep it there, as it seems that during
+ * suspend the xCON registers get re-set and thus you can end up with
+ * problems between going to sleep and resuming.
+ */
+
+ __raw_writel(S3C64XX_SLPEN_USE_xSLP, S3C64XX_SLPEN);
+}
+#endif /* __MACH_S3C64XX_PM_CORE_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
new file mode 100644
index 000000000..4f44aac77
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
@@ -0,0 +1,38 @@
+/* arch/arm/plat-s3c64xx/include/plat/regs-clock.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_REGS_CLOCK_H
+#define __PLAT_REGS_CLOCK_H __FILE__
+
+/*
+ * FIXME: Remove remaining definitions
+ */
+
+#define S3C_CLKREG(x) (S3C_VA_SYS + (x))
+
+#define S3C_PCLK_GATE S3C_CLKREG(0x34)
+#define S3C6410_CLK_SRC2 S3C_CLKREG(0x10C)
+#define S3C_MEM_SYS_CFG S3C_CLKREG(0x120)
+
+/* PCLK GATE Registers */
+#define S3C_CLKCON_PCLK_UART3 (1<<4)
+#define S3C_CLKCON_PCLK_UART2 (1<<3)
+#define S3C_CLKCON_PCLK_UART1 (1<<2)
+#define S3C_CLKCON_PCLK_UART0 (1<<1)
+
+/* MEM_SYS_CFG */
+#define MEM_SYS_CFG_INDEP_CF 0x4000
+#define MEM_SYS_CFG_EBI_FIX_PRI_CFCON 0x30
+
+#endif /* _PLAT_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h b/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h
new file mode 100644
index 000000000..81f7f6e68
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h
@@ -0,0 +1,187 @@
+/* linux/arch/arm/plat-s3c64xx/include/mach/regs-gpio.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - GPIO register definitions
+ */
+
+#ifndef __ASM_PLAT_S3C64XX_REGS_GPIO_H
+#define __ASM_PLAT_S3C64XX_REGS_GPIO_H __FILE__
+
+/* Base addresses for each of the banks */
+
+#define S3C64XX_GPIOREG(reg) (S3C64XX_VA_GPIO + (reg))
+
+#define S3C64XX_GPA_BASE S3C64XX_GPIOREG(0x0000)
+#define S3C64XX_GPB_BASE S3C64XX_GPIOREG(0x0020)
+#define S3C64XX_GPC_BASE S3C64XX_GPIOREG(0x0040)
+#define S3C64XX_GPD_BASE S3C64XX_GPIOREG(0x0060)
+#define S3C64XX_GPE_BASE S3C64XX_GPIOREG(0x0080)
+#define S3C64XX_GPF_BASE S3C64XX_GPIOREG(0x00A0)
+#define S3C64XX_GPG_BASE S3C64XX_GPIOREG(0x00C0)
+#define S3C64XX_GPH_BASE S3C64XX_GPIOREG(0x00E0)
+#define S3C64XX_GPI_BASE S3C64XX_GPIOREG(0x0100)
+#define S3C64XX_GPJ_BASE S3C64XX_GPIOREG(0x0120)
+#define S3C64XX_GPK_BASE S3C64XX_GPIOREG(0x0800)
+#define S3C64XX_GPL_BASE S3C64XX_GPIOREG(0x0810)
+#define S3C64XX_GPM_BASE S3C64XX_GPIOREG(0x0820)
+#define S3C64XX_GPN_BASE S3C64XX_GPIOREG(0x0830)
+#define S3C64XX_GPO_BASE S3C64XX_GPIOREG(0x0140)
+#define S3C64XX_GPP_BASE S3C64XX_GPIOREG(0x0160)
+#define S3C64XX_GPQ_BASE S3C64XX_GPIOREG(0x0180)
+
+/* SPCON */
+
+#define S3C64XX_SPCON S3C64XX_GPIOREG(0x1A0)
+
+#define S3C64XX_SPCON_DRVCON_CAM_MASK (0x3 << 30)
+#define S3C64XX_SPCON_DRVCON_CAM_SHIFT (30)
+#define S3C64XX_SPCON_DRVCON_CAM_2mA (0x0 << 30)
+#define S3C64XX_SPCON_DRVCON_CAM_4mA (0x1 << 30)
+#define S3C64XX_SPCON_DRVCON_CAM_7mA (0x2 << 30)
+#define S3C64XX_SPCON_DRVCON_CAM_9mA (0x3 << 30)
+
+#define S3C64XX_SPCON_DRVCON_HSSPI_MASK (0x3 << 28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_SHIFT (28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_2mA (0x0 << 28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_4mA (0x1 << 28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_7mA (0x2 << 28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_9mA (0x3 << 28)
+
+#define S3C64XX_SPCON_DRVCON_HSMMC_MASK (0x3 << 26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_SHIFT (26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_2mA (0x0 << 26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_4mA (0x1 << 26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_7mA (0x2 << 26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_9mA (0x3 << 26)
+
+#define S3C64XX_SPCON_DRVCON_LCD_MASK (0x3 << 24)
+#define S3C64XX_SPCON_DRVCON_LCD_SHIFT (24)
+#define S3C64XX_SPCON_DRVCON_LCD_2mA (0x0 << 24)
+#define S3C64XX_SPCON_DRVCON_LCD_4mA (0x1 << 24)
+#define S3C64XX_SPCON_DRVCON_LCD_7mA (0x2 << 24)
+#define S3C64XX_SPCON_DRVCON_LCD_9mA (0x3 << 24)
+
+#define S3C64XX_SPCON_DRVCON_MODEM_MASK (0x3 << 22)
+#define S3C64XX_SPCON_DRVCON_MODEM_SHIFT (22)
+#define S3C64XX_SPCON_DRVCON_MODEM_2mA (0x0 << 22)
+#define S3C64XX_SPCON_DRVCON_MODEM_4mA (0x1 << 22)
+#define S3C64XX_SPCON_DRVCON_MODEM_7mA (0x2 << 22)
+#define S3C64XX_SPCON_DRVCON_MODEM_9mA (0x3 << 22)
+
+#define S3C64XX_SPCON_nRSTOUT_OEN (1 << 21)
+
+#define S3C64XX_SPCON_DRVCON_SPICLK1_MASK (0x3 << 18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_SHIFT (18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_2mA (0x0 << 18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_4mA (0x1 << 18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_7mA (0x2 << 18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_9mA (0x3 << 18)
+
+#define S3C64XX_SPCON_MEM1_DQS_PUD_MASK (0x3 << 16)
+#define S3C64XX_SPCON_MEM1_DQS_PUD_SHIFT (16)
+#define S3C64XX_SPCON_MEM1_DQS_PUD_DISABLED (0x0 << 16)
+#define S3C64XX_SPCON_MEM1_DQS_PUD_DOWN (0x1 << 16)
+#define S3C64XX_SPCON_MEM1_DQS_PUD_UP (0x2 << 16)
+
+#define S3C64XX_SPCON_MEM1_D_PUD1_MASK (0x3 << 14)
+#define S3C64XX_SPCON_MEM1_D_PUD1_SHIFT (14)
+#define S3C64XX_SPCON_MEM1_D_PUD1_DISABLED (0x0 << 14)
+#define S3C64XX_SPCON_MEM1_D_PUD1_DOWN (0x1 << 14)
+#define S3C64XX_SPCON_MEM1_D_PUD1_UP (0x2 << 14)
+
+#define S3C64XX_SPCON_MEM1_D_PUD0_MASK (0x3 << 12)
+#define S3C64XX_SPCON_MEM1_D_PUD0_SHIFT (12)
+#define S3C64XX_SPCON_MEM1_D_PUD0_DISABLED (0x0 << 12)
+#define S3C64XX_SPCON_MEM1_D_PUD0_DOWN (0x1 << 12)
+#define S3C64XX_SPCON_MEM1_D_PUD0_UP (0x2 << 12)
+
+#define S3C64XX_SPCON_MEM0_D_PUD_MASK (0x3 << 8)
+#define S3C64XX_SPCON_MEM0_D_PUD_SHIFT (8)
+#define S3C64XX_SPCON_MEM0_D_PUD_DISABLED (0x0 << 8)
+#define S3C64XX_SPCON_MEM0_D_PUD_DOWN (0x1 << 8)
+#define S3C64XX_SPCON_MEM0_D_PUD_UP (0x2 << 8)
+
+#define S3C64XX_SPCON_USBH_DMPD (1 << 7)
+#define S3C64XX_SPCON_USBH_DPPD (1 << 6)
+#define S3C64XX_SPCON_USBH_PUSW2 (1 << 5)
+#define S3C64XX_SPCON_USBH_PUSW1 (1 << 4)
+#define S3C64XX_SPCON_USBH_SUSPND (1 << 3)
+
+#define S3C64XX_SPCON_LCD_SEL_MASK (0x3 << 0)
+#define S3C64XX_SPCON_LCD_SEL_SHIFT (0)
+#define S3C64XX_SPCON_LCD_SEL_HOST (0x0 << 0)
+#define S3C64XX_SPCON_LCD_SEL_RGB (0x1 << 0)
+#define S3C64XX_SPCON_LCD_SEL_606_656 (0x2 << 0)
+
+
+/* External interrupt registers */
+
+#define S3C64XX_EINT12CON S3C64XX_GPIOREG(0x200)
+#define S3C64XX_EINT34CON S3C64XX_GPIOREG(0x204)
+#define S3C64XX_EINT56CON S3C64XX_GPIOREG(0x208)
+#define S3C64XX_EINT78CON S3C64XX_GPIOREG(0x20C)
+#define S3C64XX_EINT9CON S3C64XX_GPIOREG(0x210)
+
+#define S3C64XX_EINT12FLTCON S3C64XX_GPIOREG(0x220)
+#define S3C64XX_EINT34FLTCON S3C64XX_GPIOREG(0x224)
+#define S3C64XX_EINT56FLTCON S3C64XX_GPIOREG(0x228)
+#define S3C64XX_EINT78FLTCON S3C64XX_GPIOREG(0x22C)
+#define S3C64XX_EINT9FLTCON S3C64XX_GPIOREG(0x230)
+
+#define S3C64XX_EINT12MASK S3C64XX_GPIOREG(0x240)
+#define S3C64XX_EINT34MASK S3C64XX_GPIOREG(0x244)
+#define S3C64XX_EINT56MASK S3C64XX_GPIOREG(0x248)
+#define S3C64XX_EINT78MASK S3C64XX_GPIOREG(0x24C)
+#define S3C64XX_EINT9MASK S3C64XX_GPIOREG(0x250)
+
+#define S3C64XX_EINT12PEND S3C64XX_GPIOREG(0x260)
+#define S3C64XX_EINT34PEND S3C64XX_GPIOREG(0x264)
+#define S3C64XX_EINT56PEND S3C64XX_GPIOREG(0x268)
+#define S3C64XX_EINT78PEND S3C64XX_GPIOREG(0x26C)
+#define S3C64XX_EINT9PEND S3C64XX_GPIOREG(0x270)
+
+#define S3C64XX_PRIORITY S3C64XX_GPIOREG(0x280)
+#define S3C64XX_PRIORITY_ARB(x) (1 << (x))
+
+#define S3C64XX_SERVICE S3C64XX_GPIOREG(0x284)
+#define S3C64XX_SERVICEPEND S3C64XX_GPIOREG(0x288)
+
+#define S3C64XX_EINT0CON0 S3C64XX_GPIOREG(0x900)
+#define S3C64XX_EINT0CON1 S3C64XX_GPIOREG(0x904)
+#define S3C64XX_EINT0FLTCON0 S3C64XX_GPIOREG(0x910)
+#define S3C64XX_EINT0FLTCON1 S3C64XX_GPIOREG(0x914)
+#define S3C64XX_EINT0FLTCON2 S3C64XX_GPIOREG(0x918)
+#define S3C64XX_EINT0FLTCON3 S3C64XX_GPIOREG(0x91C)
+
+#define S3C64XX_EINT0MASK S3C64XX_GPIOREG(0x920)
+#define S3C64XX_EINT0PEND S3C64XX_GPIOREG(0x924)
+
+/* GPIO sleep configuration */
+
+#define S3C64XX_SPCONSLP S3C64XX_GPIOREG(0x880)
+
+#define S3C64XX_SPCONSLP_TDO_PULLDOWN (1 << 14)
+#define S3C64XX_SPCONSLP_CKE1INIT (1 << 5)
+
+#define S3C64XX_SPCONSLP_RSTOUT_MASK (0x3 << 12)
+#define S3C64XX_SPCONSLP_RSTOUT_OUT0 (0x0 << 12)
+#define S3C64XX_SPCONSLP_RSTOUT_OUT1 (0x1 << 12)
+#define S3C64XX_SPCONSLP_RSTOUT_HIZ (0x2 << 12)
+
+#define S3C64XX_SPCONSLP_KPCOL_MASK (0x3 << 0)
+#define S3C64XX_SPCONSLP_KPCOL_OUT0 (0x0 << 0)
+#define S3C64XX_SPCONSLP_KPCOL_OUT1 (0x1 << 0)
+#define S3C64XX_SPCONSLP_KPCOL_INP (0x2 << 0)
+
+
+#define S3C64XX_SLPEN S3C64XX_GPIOREG(0x930)
+
+#define S3C64XX_SLPEN_USE_xSLP (1 << 0)
+#define S3C64XX_SLPEN_CFG_BYSLPEN (1 << 1)
+
+#endif /* __ASM_PLAT_S3C64XX_REGS_GPIO_H */
+
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-irq.h b/arch/arm/mach-s3c64xx/include/mach/regs-irq.h
new file mode 100644
index 000000000..6a1127891
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-irq.h
@@ -0,0 +1,19 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/regs-irq.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - IRQ register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_IRQ_H
+#define __ASM_ARCH_REGS_IRQ_H __FILE__
+
+
+#endif /* __ASM_ARCH_6400_REGS_IRQ_H */
diff --git a/arch/arm/mach-s3c64xx/irq-pm.c b/arch/arm/mach-s3c64xx/irq-pm.c
new file mode 100644
index 000000000..ae4ea7601
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/irq-pm.c
@@ -0,0 +1,124 @@
+/* arch/arm/plat-s3c64xx/irq-pm.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - Interrupt handling Power Management
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * NOTE: Code in this file is not used when booting with Device Tree support.
+ */
+
+#include <linux/kernel.h>
+#include <linux/syscore_ops.h>
+#include <linux/interrupt.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include <mach/map.h>
+
+#include <mach/regs-gpio.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+/* We handled all the IRQ types in this code, to save having to make several
+ * small files to handle each different type separately. Having the EINT_GRP
+ * code here shouldn't be as much bloat as the IRQ table space needed when
+ * they are enabled. The added benefit is we ensure that these registers are
+ * in the same state as we suspended.
+ */
+
+static struct sleep_save irq_save[] = {
+ SAVE_ITEM(S3C64XX_PRIORITY),
+ SAVE_ITEM(S3C64XX_EINT0CON0),
+ SAVE_ITEM(S3C64XX_EINT0CON1),
+ SAVE_ITEM(S3C64XX_EINT0FLTCON0),
+ SAVE_ITEM(S3C64XX_EINT0FLTCON1),
+ SAVE_ITEM(S3C64XX_EINT0FLTCON2),
+ SAVE_ITEM(S3C64XX_EINT0FLTCON3),
+ SAVE_ITEM(S3C64XX_EINT0MASK),
+};
+
+static struct irq_grp_save {
+ u32 fltcon;
+ u32 con;
+ u32 mask;
+} eint_grp_save[5];
+
+#ifndef CONFIG_SERIAL_SAMSUNG_UARTS
+#define SERIAL_SAMSUNG_UARTS 0
+#else
+#define SERIAL_SAMSUNG_UARTS CONFIG_SERIAL_SAMSUNG_UARTS
+#endif
+
+static u32 irq_uart_mask[SERIAL_SAMSUNG_UARTS];
+
+static int s3c64xx_irq_pm_suspend(void)
+{
+ struct irq_grp_save *grp = eint_grp_save;
+ int i;
+
+ S3C_PMDBG("%s: suspending IRQs\n", __func__);
+
+ s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
+
+ for (i = 0; i < SERIAL_SAMSUNG_UARTS; i++)
+ irq_uart_mask[i] = __raw_readl(S3C_VA_UARTx(i) + S3C64XX_UINTM);
+
+ for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
+ grp->con = __raw_readl(S3C64XX_EINT12CON + (i * 4));
+ grp->mask = __raw_readl(S3C64XX_EINT12MASK + (i * 4));
+ grp->fltcon = __raw_readl(S3C64XX_EINT12FLTCON + (i * 4));
+ }
+
+ return 0;
+}
+
+static void s3c64xx_irq_pm_resume(void)
+{
+ struct irq_grp_save *grp = eint_grp_save;
+ int i;
+
+ S3C_PMDBG("%s: resuming IRQs\n", __func__);
+
+ s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
+
+ for (i = 0; i < SERIAL_SAMSUNG_UARTS; i++)
+ __raw_writel(irq_uart_mask[i], S3C_VA_UARTx(i) + S3C64XX_UINTM);
+
+ for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
+ __raw_writel(grp->con, S3C64XX_EINT12CON + (i * 4));
+ __raw_writel(grp->mask, S3C64XX_EINT12MASK + (i * 4));
+ __raw_writel(grp->fltcon, S3C64XX_EINT12FLTCON + (i * 4));
+ }
+
+ S3C_PMDBG("%s: IRQ configuration restored\n", __func__);
+}
+
+static struct syscore_ops s3c64xx_irq_syscore_ops = {
+ .suspend = s3c64xx_irq_pm_suspend,
+ .resume = s3c64xx_irq_pm_resume,
+};
+
+static __init int s3c64xx_syscore_init(void)
+{
+ /* Appropriate drivers (pinctrl, uart) handle this when using DT. */
+ if (of_have_populated_dt())
+ return 0;
+
+ register_syscore_ops(&s3c64xx_irq_syscore_ops);
+
+ return 0;
+}
+
+core_initcall(s3c64xx_syscore_init);
diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c
new file mode 100644
index 000000000..6224c67f5
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-anw6410.c
@@ -0,0 +1,238 @@
+/* linux/arch/arm/mach-s3c64xx/mach-anw6410.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ * Copyright 2009 Kwangwoo Lee
+ * Kwangwoo Lee <kwangwoo.lee@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/dm9000.h>
+
+#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <plat/fb.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "regs-modem.h"
+
+/* DM9000 */
+#define ANW6410_PA_DM9000 (0x18000000)
+
+/* A hardware buffer to control external devices is mapped at 0x30000000.
+ * It can not be read. So current status must be kept in anw6410_extdev_status.
+ */
+#define ANW6410_VA_EXTDEV S3C_ADDR(0x02000000)
+#define ANW6410_PA_EXTDEV (0x30000000)
+
+#define ANW6410_EN_DM9000 (1<<11)
+#define ANW6410_EN_LCD (1<<14)
+
+static __u32 anw6410_extdev_status;
+
+static struct s3c2410_uartcfg anw6410_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+};
+
+/* framebuffer and LCD setup. */
+static void __init anw6410_lcd_mode_set(void)
+{
+ u32 tmp;
+
+ /* set the LCD type */
+ tmp = __raw_readl(S3C64XX_SPCON);
+ tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
+ tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
+ __raw_writel(tmp, S3C64XX_SPCON);
+
+ /* remove the LCD bypass */
+ tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
+ tmp &= ~MIFPCON_LCD_BYPASS;
+ __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
+}
+
+/* GPF1 = LCD panel power
+ * GPF4 = LCD backlight control
+ */
+static void anw6410_lcd_power_set(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+ anw6410_extdev_status |= (ANW6410_EN_LCD << 16);
+ __raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
+
+ gpio_direction_output(S3C64XX_GPF(1), 1);
+ gpio_direction_output(S3C64XX_GPF(4), 1);
+ } else {
+ anw6410_extdev_status &= ~(ANW6410_EN_LCD << 16);
+ __raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
+
+ gpio_direction_output(S3C64XX_GPF(1), 0);
+ gpio_direction_output(S3C64XX_GPF(4), 0);
+ }
+}
+
+static struct plat_lcd_data anw6410_lcd_power_data = {
+ .set_power = anw6410_lcd_power_set,
+};
+
+static struct platform_device anw6410_lcd_powerdev = {
+ .name = "platform-lcd",
+ .dev.parent = &s3c_device_fb.dev,
+ .dev.platform_data = &anw6410_lcd_power_data,
+};
+
+static struct s3c_fb_pd_win anw6410_fb_win0 = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 800,
+ .yres = 480,
+};
+
+static struct fb_videomode anw6410_lcd_timing = {
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+};
+
+/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
+static struct s3c_fb_platdata anw6410_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .vtiming = &anw6410_lcd_timing,
+ .win[0] = &anw6410_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+/* DM9000AEP 10/100 ethernet controller */
+static void __init anw6410_dm9000_enable(void)
+{
+ anw6410_extdev_status |= (ANW6410_EN_DM9000 << 16);
+ __raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
+}
+
+static struct resource anw6410_dm9000_resource[] = {
+ [0] = DEFINE_RES_MEM(ANW6410_PA_DM9000, 4),
+ [1] = DEFINE_RES_MEM(ANW6410_PA_DM9000 + 4, 501),
+ [2] = DEFINE_RES_NAMED(IRQ_EINT(15), 1, NULL, IORESOURCE_IRQ \
+ | IRQF_TRIGGER_HIGH),
+};
+
+static struct dm9000_plat_data anw6410_dm9000_pdata = {
+ .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+ /* dev_addr can be set to provide hwaddr. */
+};
+
+static struct platform_device anw6410_device_eth = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(anw6410_dm9000_resource),
+ .resource = anw6410_dm9000_resource,
+ .dev = {
+ .platform_data = &anw6410_dm9000_pdata,
+ },
+};
+
+static struct map_desc anw6410_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)ANW6410_VA_EXTDEV,
+ .pfn = __phys_to_pfn(ANW6410_PA_EXTDEV),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct platform_device *anw6410_devices[] __initdata = {
+ &s3c_device_fb,
+ &anw6410_lcd_powerdev,
+ &anw6410_device_eth,
+};
+
+static void __init anw6410_map_io(void)
+{
+ s3c64xx_init_io(anw6410_iodesc, ARRAY_SIZE(anw6410_iodesc));
+ s3c64xx_set_xtal_freq(12000000);
+ s3c24xx_init_uarts(anw6410_uartcfgs, ARRAY_SIZE(anw6410_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ anw6410_lcd_mode_set();
+}
+
+static void __init anw6410_machine_init(void)
+{
+ s3c_fb_set_platdata(&anw6410_lcd_pdata);
+
+ gpio_request(S3C64XX_GPF(1), "panel power");
+ gpio_request(S3C64XX_GPF(4), "LCD backlight");
+
+ anw6410_dm9000_enable();
+
+ platform_add_devices(anw6410_devices, ARRAY_SIZE(anw6410_devices));
+}
+
+MACHINE_START(ANW6410, "A&W6410")
+ /* Maintainer: Kwangwoo Lee <kwangwoo.lee@gmail.com> */
+ .atag_offset = 0x100,
+
+ .init_irq = s3c6410_init_irq,
+ .map_io = anw6410_map_io,
+ .init_machine = anw6410_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
new file mode 100644
index 000000000..9c00d83f7
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
@@ -0,0 +1,404 @@
+/* Speyside modules for Cragganmore - board data probing
+ *
+ * Copyright 2011 Wolfson Microelectronics plc
+ * Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/export.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/spi/spi.h>
+
+#include <linux/mfd/wm831x/irq.h>
+#include <linux/mfd/wm831x/gpio.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/mfd/arizona/pdata.h>
+
+#include <linux/regulator/machine.h>
+
+#include <sound/wm0010.h>
+#include <sound/wm2200.h>
+#include <sound/wm5100.h>
+#include <sound/wm8996.h>
+#include <sound/wm8962.h>
+#include <sound/wm9081.h>
+
+#include <linux/platform_data/spi-s3c64xx.h>
+
+#include "crag6410.h"
+
+static struct s3c64xx_spi_csinfo wm0010_spi_csinfo = {
+ .line = S3C64XX_GPC(3),
+};
+
+static struct wm0010_pdata wm0010_pdata = {
+ .gpio_reset = S3C64XX_GPN(6),
+ .reset_active_high = 1, /* Active high for Glenfarclas Rev 2 */
+};
+
+static struct spi_board_info wm1253_devs[] = {
+ [0] = {
+ .modalias = "wm0010",
+ .max_speed_hz = 26 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .irq = S3C_EINT(4),
+ .controller_data = &wm0010_spi_csinfo,
+ .platform_data = &wm0010_pdata,
+ },
+};
+
+static struct spi_board_info balblair_devs[] = {
+ [0] = {
+ .modalias = "wm0010",
+ .max_speed_hz = 26 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .irq = S3C_EINT(4),
+ .controller_data = &wm0010_spi_csinfo,
+ .platform_data = &wm0010_pdata,
+ },
+};
+
+static struct wm5100_pdata wm5100_pdata = {
+ .ldo_ena = S3C64XX_GPN(7),
+ .irq_flags = IRQF_TRIGGER_HIGH,
+ .gpio_base = CODEC_GPIO_BASE,
+
+ .in_mode = {
+ WM5100_IN_DIFF,
+ WM5100_IN_DIFF,
+ WM5100_IN_DIFF,
+ WM5100_IN_SE,
+ },
+
+ .hp_pol = CODEC_GPIO_BASE + 3,
+ .jack_modes = {
+ { WM5100_MICDET_MICBIAS3, 0, 0 },
+ { WM5100_MICDET_MICBIAS2, 1, 1 },
+ },
+
+ .gpio_defaults = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0x2, /* IRQ: CMOS output */
+ 0x3, /* CLKOUT: CMOS output */
+ },
+};
+
+static struct wm8996_retune_mobile_config wm8996_retune[] = {
+ {
+ .name = "Sub LPF",
+ .rate = 48000,
+ .regs = {
+ 0x6318, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
+ 0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
+ 0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
+ },
+ },
+ {
+ .name = "Sub HPF",
+ .rate = 48000,
+ .regs = {
+ 0x000A, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
+ 0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
+ 0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
+ },
+ },
+};
+
+static struct wm8996_pdata wm8996_pdata __initdata = {
+ .ldo_ena = S3C64XX_GPN(7),
+ .gpio_base = CODEC_GPIO_BASE,
+ .micdet_def = 1,
+ .inl_mode = WM8996_DIFFERRENTIAL_1,
+ .inr_mode = WM8996_DIFFERRENTIAL_1,
+
+ .irq_flags = IRQF_TRIGGER_RISING,
+
+ .gpio_default = {
+ 0x8001, /* GPIO1 == ADCLRCLK1 */
+ 0x8001, /* GPIO2 == ADCLRCLK2, input due to CPU */
+ 0x0141, /* GPIO3 == HP_SEL */
+ 0x0002, /* GPIO4 == IRQ */
+ 0x020e, /* GPIO5 == CLKOUT */
+ },
+
+ .retune_mobile_cfgs = wm8996_retune,
+ .num_retune_mobile_cfgs = ARRAY_SIZE(wm8996_retune),
+};
+
+static struct wm8962_pdata wm8962_pdata __initdata = {
+ .gpio_init = {
+ 0,
+ WM8962_GPIO_FN_OPCLK,
+ WM8962_GPIO_FN_DMICCLK,
+ 0,
+ 0x8000 | WM8962_GPIO_FN_DMICDAT,
+ WM8962_GPIO_FN_IRQ, /* Open drain mode */
+ },
+ .in4_dc_measure = true,
+};
+
+static struct wm9081_pdata wm9081_pdata __initdata = {
+ .irq_high = false,
+ .irq_cmos = false,
+};
+
+static const struct i2c_board_info wm1254_devs[] = {
+ { I2C_BOARD_INFO("wm8996", 0x1a),
+ .platform_data = &wm8996_pdata,
+ .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
+ },
+ { I2C_BOARD_INFO("wm9081", 0x6c),
+ .platform_data = &wm9081_pdata, },
+};
+
+static const struct i2c_board_info wm1255_devs[] = {
+ { I2C_BOARD_INFO("wm5100", 0x1a),
+ .platform_data = &wm5100_pdata,
+ .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
+ },
+ { I2C_BOARD_INFO("wm9081", 0x6c),
+ .platform_data = &wm9081_pdata, },
+};
+
+static const struct i2c_board_info wm1259_devs[] = {
+ { I2C_BOARD_INFO("wm8962", 0x1a),
+ .platform_data = &wm8962_pdata,
+ .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
+ },
+};
+
+static struct regulator_init_data wm8994_ldo1 = {
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data wm8994_ldo2 = {
+ .supply_regulator = "WALLVDD",
+};
+
+static struct wm8994_pdata wm8994_pdata = {
+ .gpio_base = CODEC_GPIO_BASE,
+ .micb2_delay = 150,
+ .gpio_defaults = {
+ 0x3, /* IRQ out, active high, CMOS */
+ },
+ .ldo = {
+ { .enable = S3C64XX_GPN(6), .init_data = &wm8994_ldo1, },
+ { .enable = S3C64XX_GPN(4), .init_data = &wm8994_ldo2, },
+ },
+};
+
+static const struct i2c_board_info wm1277_devs[] = {
+ { I2C_BOARD_INFO("wm8958", 0x1a), /* WM8958 is the superset */
+ .platform_data = &wm8994_pdata,
+ .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
+ },
+};
+
+static struct arizona_pdata wm5102_reva_pdata = {
+ .ldoena = S3C64XX_GPN(7),
+ .gpio_base = CODEC_GPIO_BASE,
+ .irq_flags = IRQF_TRIGGER_HIGH,
+ .micd_pol_gpio = CODEC_GPIO_BASE + 4,
+ .micd_rate = 6,
+ .gpio_defaults = {
+ [2] = 0x10000, /* AIF3TXLRCLK */
+ [3] = 0x4, /* OPCLK */
+ },
+};
+
+static struct s3c64xx_spi_csinfo codec_spi_csinfo = {
+ .line = S3C64XX_GPN(5),
+};
+
+static struct spi_board_info wm5102_reva_spi_devs[] = {
+ [0] = {
+ .modalias = "wm5102",
+ .max_speed_hz = 10 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .mode = SPI_MODE_0,
+ .irq = GLENFARCLAS_PMIC_IRQ_BASE +
+ WM831X_IRQ_GPIO_2,
+ .controller_data = &codec_spi_csinfo,
+ .platform_data = &wm5102_reva_pdata,
+ },
+};
+
+static struct arizona_pdata wm5102_pdata = {
+ .ldoena = S3C64XX_GPN(7),
+ .gpio_base = CODEC_GPIO_BASE,
+ .irq_flags = IRQF_TRIGGER_HIGH,
+ .micd_pol_gpio = CODEC_GPIO_BASE + 2,
+ .gpio_defaults = {
+ [2] = 0x10000, /* AIF3TXLRCLK */
+ [3] = 0x4, /* OPCLK */
+ },
+};
+
+static struct spi_board_info wm5102_spi_devs[] = {
+ [0] = {
+ .modalias = "wm5102",
+ .max_speed_hz = 10 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .mode = SPI_MODE_0,
+ .irq = GLENFARCLAS_PMIC_IRQ_BASE +
+ WM831X_IRQ_GPIO_2,
+ .controller_data = &codec_spi_csinfo,
+ .platform_data = &wm5102_pdata,
+ },
+};
+
+static struct spi_board_info wm5110_spi_devs[] = {
+ [0] = {
+ .modalias = "wm5110",
+ .max_speed_hz = 10 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .mode = SPI_MODE_0,
+ .irq = GLENFARCLAS_PMIC_IRQ_BASE +
+ WM831X_IRQ_GPIO_2,
+ .controller_data = &codec_spi_csinfo,
+ .platform_data = &wm5102_reva_pdata,
+ },
+};
+
+static const struct i2c_board_info wm6230_i2c_devs[] = {
+ { I2C_BOARD_INFO("wm9081", 0x6c),
+ .platform_data = &wm9081_pdata, },
+};
+
+static struct wm2200_pdata wm2200_pdata = {
+ .ldo_ena = S3C64XX_GPN(7),
+ .gpio_defaults = {
+ [2] = 0x0005, /* GPIO3 24.576MHz output clock */
+ },
+};
+
+static const struct i2c_board_info wm2200_i2c[] = {
+ { I2C_BOARD_INFO("wm2200", 0x3a),
+ .platform_data = &wm2200_pdata, },
+};
+
+static const struct {
+ u8 id;
+ u8 rev;
+ const char *name;
+ const struct i2c_board_info *i2c_devs;
+ int num_i2c_devs;
+ const struct spi_board_info *spi_devs;
+ int num_spi_devs;
+} gf_mods[] = {
+ { .id = 0x01, .rev = 0xff, .name = "1250-EV1 Springbank" },
+ { .id = 0x02, .rev = 0xff, .name = "1251-EV1 Jura" },
+ { .id = 0x03, .rev = 0xff, .name = "1252-EV1 Glenlivet" },
+ { .id = 0x06, .rev = 0xff, .name = "WM8997-6721-CS96-EV1 Lapraoig" },
+ { .id = 0x07, .rev = 0xff, .name = "WM5110-6271 Deanston",
+ .spi_devs = wm5110_spi_devs,
+ .num_spi_devs = ARRAY_SIZE(wm5110_spi_devs) },
+ { .id = 0x08, .rev = 0xff, .name = "WM8903-6102 Tamdhu" },
+ { .id = 0x09, .rev = 0xff, .name = "WM1811A-6305 Adelphi" },
+ { .id = 0x0a, .rev = 0xff, .name = "WM8996-6272 Blackadder" },
+ { .id = 0x0b, .rev = 0xff, .name = "WM8994-6235 Benromach" },
+ { .id = 0x11, .rev = 0xff, .name = "6249-EV2 Glenfarclas", },
+ { .id = 0x14, .rev = 0xff, .name = "6271-EV1 Lochnagar" },
+ { .id = 0x15, .rev = 0xff, .name = "6320-EV1 Bells",
+ .i2c_devs = wm6230_i2c_devs,
+ .num_i2c_devs = ARRAY_SIZE(wm6230_i2c_devs) },
+ { .id = 0x21, .rev = 0xff, .name = "1275-EV1 Mortlach" },
+ { .id = 0x25, .rev = 0xff, .name = "1274-EV1 Glencadam" },
+ { .id = 0x31, .rev = 0xff, .name = "1253-EV1 Tomatin",
+ .spi_devs = wm1253_devs, .num_spi_devs = ARRAY_SIZE(wm1253_devs) },
+ { .id = 0x32, .rev = 0xff, .name = "XXXX-EV1 Caol Illa" },
+ { .id = 0x33, .rev = 0xff, .name = "XXXX-EV1 Oban" },
+ { .id = 0x34, .rev = 0xff, .name = "WM0010-6320-CS42 Balblair",
+ .spi_devs = balblair_devs,
+ .num_spi_devs = ARRAY_SIZE(balblair_devs) },
+ { .id = 0x39, .rev = 0xff, .name = "1254-EV1 Dallas Dhu",
+ .i2c_devs = wm1254_devs, .num_i2c_devs = ARRAY_SIZE(wm1254_devs) },
+ { .id = 0x3a, .rev = 0xff, .name = "1259-EV1 Tobermory",
+ .i2c_devs = wm1259_devs, .num_i2c_devs = ARRAY_SIZE(wm1259_devs) },
+ { .id = 0x3b, .rev = 0xff, .name = "1255-EV1 Kilchoman",
+ .i2c_devs = wm1255_devs, .num_i2c_devs = ARRAY_SIZE(wm1255_devs) },
+ { .id = 0x3c, .rev = 0xff, .name = "1273-EV1 Longmorn" },
+ { .id = 0x3d, .rev = 0xff, .name = "1277-EV1 Littlemill",
+ .i2c_devs = wm1277_devs, .num_i2c_devs = ARRAY_SIZE(wm1277_devs) },
+ { .id = 0x3e, .rev = 0, .name = "WM5102-6271-EV1-CS127 Amrut",
+ .spi_devs = wm5102_reva_spi_devs,
+ .num_spi_devs = ARRAY_SIZE(wm5102_reva_spi_devs) },
+ { .id = 0x3e, .rev = -1, .name = "WM5102-6271-EV1-CS127 Amrut",
+ .spi_devs = wm5102_spi_devs,
+ .num_spi_devs = ARRAY_SIZE(wm5102_spi_devs) },
+ { .id = 0x3f, .rev = -1, .name = "WM2200-6271-CS90-M-REV1",
+ .i2c_devs = wm2200_i2c, .num_i2c_devs = ARRAY_SIZE(wm2200_i2c) },
+};
+
+static int wlf_gf_module_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *i2c_id)
+{
+ int ret, i, j, id, rev;
+
+ ret = i2c_smbus_read_byte_data(i2c, 0);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Failed to read ID: %d\n", ret);
+ return ret;
+ }
+
+ id = (ret & 0xfe) >> 2;
+ rev = ret & 0x3;
+ for (i = 0; i < ARRAY_SIZE(gf_mods); i++)
+ if (id == gf_mods[i].id && (gf_mods[i].rev == 0xff ||
+ rev == gf_mods[i].rev))
+ break;
+
+ if (i < ARRAY_SIZE(gf_mods)) {
+ dev_info(&i2c->dev, "%s revision %d\n",
+ gf_mods[i].name, rev + 1);
+
+ for (j = 0; j < gf_mods[i].num_i2c_devs; j++) {
+ if (!i2c_new_device(i2c->adapter,
+ &(gf_mods[i].i2c_devs[j])))
+ dev_err(&i2c->dev,
+ "Failed to register dev: %d\n", ret);
+ }
+
+ spi_register_board_info(gf_mods[i].spi_devs,
+ gf_mods[i].num_spi_devs);
+ } else {
+ dev_warn(&i2c->dev, "Unknown module ID 0x%x revision %d\n",
+ id, rev + 1);
+ }
+
+ return 0;
+}
+
+static const struct i2c_device_id wlf_gf_module_id[] = {
+ { "wlf-gf-module", 0 },
+ { }
+};
+
+static struct i2c_driver wlf_gf_module_driver = {
+ .driver = {
+ .name = "wlf-gf-module",
+ .owner = THIS_MODULE,
+ },
+ .probe = wlf_gf_module_probe,
+ .id_table = wlf_gf_module_id,
+};
+
+static int __init wlf_gf_module_register(void)
+{
+ return i2c_add_driver(&wlf_gf_module_driver);
+}
+device_initcall(wlf_gf_module_register);
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
new file mode 100644
index 000000000..65c426bc4
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -0,0 +1,863 @@
+/* linux/arch/arm/mach-s3c64xx/mach-crag6410.c
+ *
+ * Copyright 2011 Wolfson Microelectronics plc
+ * Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * Copyright 2011 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/delay.h>
+#include <linux/mmc/host.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/pwm_backlight.h>
+#include <linux/dm9000.h>
+#include <linux/gpio_keys.h>
+#include <linux/basic_mmio_gpio.h>
+#include <linux/spi/spi.h>
+
+#include <linux/platform_data/pca953x.h>
+#include <linux/platform_data/s3c-hsotg.h>
+
+#include <video/platform_lcd.h>
+
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/pdata.h>
+#include <linux/mfd/wm831x/irq.h>
+#include <linux/mfd/wm831x/gpio.h>
+
+#include <sound/wm1250-ev1.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <video/samsung_fimd.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/fb.h>
+#include <plat/sdhci.h>
+#include <plat/gpio-cfg.h>
+#include <linux/platform_data/spi-s3c64xx.h>
+
+#include <plat/keypad.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/adc.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <plat/pm.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "crag6410.h"
+#include "regs-gpio-memport.h"
+#include "regs-modem.h"
+#include "regs-sys.h"
+
+/* serial port setup */
+
+#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 crag6410_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,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+};
+
+static struct platform_pwm_backlight_data crag6410_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 1000,
+ .dft_brightness = 600,
+ .pwm_period_ns = 100000, /* about 1kHz */
+ .enable_gpio = -1,
+};
+
+static struct platform_device crag6410_backlight_device = {
+ .name = "pwm-backlight",
+ .id = -1,
+ .dev = {
+ .parent = &samsung_device_pwm.dev,
+ .platform_data = &crag6410_backlight_data,
+ },
+};
+
+static void crag6410_lcd_power_set(struct plat_lcd_data *pd, unsigned int power)
+{
+ pr_debug("%s: setting power %d\n", __func__, power);
+
+ if (power) {
+ gpio_set_value(S3C64XX_GPB(0), 1);
+ msleep(1);
+ s3c_gpio_cfgpin(S3C64XX_GPF(14), S3C_GPIO_SFN(2));
+ } else {
+ gpio_direction_output(S3C64XX_GPF(14), 0);
+ gpio_set_value(S3C64XX_GPB(0), 0);
+ }
+}
+
+static struct platform_device crag6410_lcd_powerdev = {
+ .name = "platform-lcd",
+ .id = -1,
+ .dev.parent = &s3c_device_fb.dev,
+ .dev.platform_data = &(struct plat_lcd_data) {
+ .set_power = crag6410_lcd_power_set,
+ },
+};
+
+/* 640x480 URT */
+static struct s3c_fb_pd_win crag6410_fb_win0 = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 640,
+ .yres = 480,
+ .virtual_y = 480 * 2,
+ .virtual_x = 640,
+};
+
+static struct fb_videomode crag6410_lcd_timing = {
+ .left_margin = 150,
+ .right_margin = 80,
+ .upper_margin = 40,
+ .lower_margin = 5,
+ .hsync_len = 40,
+ .vsync_len = 5,
+ .xres = 640,
+ .yres = 480,
+};
+
+/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
+static struct s3c_fb_platdata crag6410_lcd_pdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .vtiming = &crag6410_lcd_timing,
+ .win[0] = &crag6410_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+/* 2x6 keypad */
+
+static uint32_t crag6410_keymap[] = {
+ /* KEY(row, col, keycode) */
+ KEY(0, 0, KEY_VOLUMEUP),
+ KEY(0, 1, KEY_HOME),
+ KEY(0, 2, KEY_VOLUMEDOWN),
+ KEY(0, 3, KEY_HELP),
+ KEY(0, 4, KEY_MENU),
+ KEY(0, 5, KEY_MEDIA),
+ KEY(1, 0, 232),
+ KEY(1, 1, KEY_DOWN),
+ KEY(1, 2, KEY_LEFT),
+ KEY(1, 3, KEY_UP),
+ KEY(1, 4, KEY_RIGHT),
+ KEY(1, 5, KEY_CAMERA),
+};
+
+static struct matrix_keymap_data crag6410_keymap_data = {
+ .keymap = crag6410_keymap,
+ .keymap_size = ARRAY_SIZE(crag6410_keymap),
+};
+
+static struct samsung_keypad_platdata crag6410_keypad_data = {
+ .keymap_data = &crag6410_keymap_data,
+ .rows = 2,
+ .cols = 6,
+};
+
+static struct gpio_keys_button crag6410_gpio_keys[] = {
+ [0] = {
+ .code = KEY_SUSPEND,
+ .gpio = S3C64XX_GPL(10), /* EINT 18 */
+ .type = EV_KEY,
+ .wakeup = 1,
+ .active_low = 1,
+ },
+ [1] = {
+ .code = SW_FRONT_PROXIMITY,
+ .gpio = S3C64XX_GPN(11), /* EINT 11 */
+ .type = EV_SW,
+ },
+};
+
+static struct gpio_keys_platform_data crag6410_gpio_keydata = {
+ .buttons = crag6410_gpio_keys,
+ .nbuttons = ARRAY_SIZE(crag6410_gpio_keys),
+};
+
+static struct platform_device crag6410_gpio_keydev = {
+ .name = "gpio-keys",
+ .id = 0,
+ .dev.platform_data = &crag6410_gpio_keydata,
+};
+
+static struct resource crag6410_dm9k_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN5, 2),
+ [1] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN5 + (1 << 8), 2),
+ [2] = DEFINE_RES_NAMED(S3C_EINT(17), 1, NULL, IORESOURCE_IRQ \
+ | IORESOURCE_IRQ_HIGHLEVEL),
+};
+
+static struct dm9000_plat_data mini6410_dm9k_pdata = {
+ .flags = DM9000_PLATF_16BITONLY,
+};
+
+static struct platform_device crag6410_dm9k_device = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(crag6410_dm9k_resource),
+ .resource = crag6410_dm9k_resource,
+ .dev.platform_data = &mini6410_dm9k_pdata,
+};
+
+static struct resource crag6410_mmgpio_resource[] = {
+ [0] = DEFINE_RES_MEM_NAMED(S3C64XX_PA_XM0CSN4, 1, "dat"),
+};
+
+static struct platform_device crag6410_mmgpio = {
+ .name = "basic-mmio-gpio",
+ .id = -1,
+ .resource = crag6410_mmgpio_resource,
+ .num_resources = ARRAY_SIZE(crag6410_mmgpio_resource),
+ .dev.platform_data = &(struct bgpio_pdata) {
+ .base = MMGPIO_GPIO_BASE,
+ },
+};
+
+static struct platform_device speyside_device = {
+ .name = "speyside",
+ .id = -1,
+};
+
+static struct platform_device lowland_device = {
+ .name = "lowland",
+ .id = -1,
+};
+
+static struct platform_device tobermory_device = {
+ .name = "tobermory",
+ .id = -1,
+};
+
+static struct platform_device littlemill_device = {
+ .name = "littlemill",
+ .id = -1,
+};
+
+static struct platform_device bells_wm2200_device = {
+ .name = "bells",
+ .id = 0,
+};
+
+static struct platform_device bells_wm5102_device = {
+ .name = "bells",
+ .id = 1,
+};
+
+static struct platform_device bells_wm5110_device = {
+ .name = "bells",
+ .id = 2,
+};
+
+static struct regulator_consumer_supply wallvdd_consumers[] = {
+ REGULATOR_SUPPLY("SPKVDD", "1-001a"),
+ REGULATOR_SUPPLY("SPKVDD1", "1-001a"),
+ REGULATOR_SUPPLY("SPKVDD2", "1-001a"),
+ REGULATOR_SUPPLY("SPKVDDL", "1-001a"),
+ REGULATOR_SUPPLY("SPKVDDR", "1-001a"),
+
+ REGULATOR_SUPPLY("SPKVDDL", "spi0.1"),
+ REGULATOR_SUPPLY("SPKVDDR", "spi0.1"),
+
+ REGULATOR_SUPPLY("DC1VDD", "0-0034"),
+ REGULATOR_SUPPLY("DC2VDD", "0-0034"),
+ REGULATOR_SUPPLY("DC3VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO1VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO2VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO4VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO5VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO6VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO7VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO8VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO9VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO10VDD", "0-0034"),
+ REGULATOR_SUPPLY("LDO11VDD", "0-0034"),
+
+ REGULATOR_SUPPLY("DC1VDD", "1-0034"),
+ REGULATOR_SUPPLY("DC2VDD", "1-0034"),
+ REGULATOR_SUPPLY("DC3VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO1VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO2VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO4VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO5VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO6VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO7VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO8VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO9VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO10VDD", "1-0034"),
+ REGULATOR_SUPPLY("LDO11VDD", "1-0034"),
+};
+
+static struct regulator_init_data wallvdd_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wallvdd_consumers),
+ .consumer_supplies = wallvdd_consumers,
+};
+
+static struct fixed_voltage_config wallvdd_pdata = {
+ .supply_name = "WALLVDD",
+ .microvolts = 5000000,
+ .init_data = &wallvdd_data,
+ .gpio = -EINVAL,
+};
+
+static struct platform_device wallvdd_device = {
+ .name = "reg-fixed-voltage",
+ .id = -1,
+ .dev = {
+ .platform_data = &wallvdd_pdata,
+ },
+};
+
+static struct platform_device *crag6410_devices[] __initdata = {
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc2,
+ &s3c_device_i2c0,
+ &s3c_device_i2c1,
+ &s3c_device_fb,
+ &s3c_device_ohci,
+ &s3c_device_usb_hsotg,
+ &samsung_device_pwm,
+ &s3c64xx_device_iis0,
+ &s3c64xx_device_iis1,
+ &samsung_device_keypad,
+ &crag6410_gpio_keydev,
+ &crag6410_dm9k_device,
+ &s3c64xx_device_spi0,
+ &crag6410_mmgpio,
+ &crag6410_lcd_powerdev,
+ &crag6410_backlight_device,
+ &speyside_device,
+ &tobermory_device,
+ &littlemill_device,
+ &lowland_device,
+ &bells_wm2200_device,
+ &bells_wm5102_device,
+ &bells_wm5110_device,
+ &wallvdd_device,
+};
+
+static struct pca953x_platform_data crag6410_pca_data = {
+ .gpio_base = PCA935X_GPIO_BASE,
+ .irq_base = -1,
+};
+
+/* VDDARM is controlled by DVS1 connected to GPK(0) */
+static struct wm831x_buckv_pdata vddarm_pdata = {
+ .dvs_control_src = 1,
+ .dvs_gpio = S3C64XX_GPK(0),
+};
+
+static struct regulator_consumer_supply vddarm_consumers[] = {
+ REGULATOR_SUPPLY("vddarm", NULL),
+};
+
+static struct regulator_init_data vddarm = {
+ .constraints = {
+ .name = "VDDARM",
+ .min_uV = 1000000,
+ .max_uV = 1300000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vddarm_consumers),
+ .consumer_supplies = vddarm_consumers,
+ .supply_regulator = "WALLVDD",
+ .driver_data = &vddarm_pdata,
+};
+
+static struct regulator_consumer_supply vddint_consumers[] = {
+ REGULATOR_SUPPLY("vddint", NULL),
+};
+
+static struct regulator_init_data vddint = {
+ .constraints = {
+ .name = "VDDINT",
+ .min_uV = 1000000,
+ .max_uV = 1200000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vddint_consumers),
+ .consumer_supplies = vddint_consumers,
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data vddmem = {
+ .constraints = {
+ .name = "VDDMEM",
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data vddsys = {
+ .constraints = {
+ .name = "VDDSYS,VDDEXT,VDDPCM,VDDSS",
+ .always_on = 1,
+ },
+};
+
+static struct regulator_consumer_supply vddmmc_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
+ REGULATOR_SUPPLY("vmmc", "s3c-sdhci.1"),
+ REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"),
+};
+
+static struct regulator_init_data vddmmc = {
+ .constraints = {
+ .name = "VDDMMC,UH",
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vddmmc_consumers),
+ .consumer_supplies = vddmmc_consumers,
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data vddotgi = {
+ .constraints = {
+ .name = "VDDOTGi",
+ .always_on = 1,
+ },
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data vddotg = {
+ .constraints = {
+ .name = "VDDOTG",
+ .always_on = 1,
+ },
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data vddhi = {
+ .constraints = {
+ .name = "VDDHI",
+ .always_on = 1,
+ },
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data vddadc = {
+ .constraints = {
+ .name = "VDDADC,VDDDAC",
+ .always_on = 1,
+ },
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data vddmem0 = {
+ .constraints = {
+ .name = "VDDMEM0",
+ .always_on = 1,
+ },
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data vddpll = {
+ .constraints = {
+ .name = "VDDPLL",
+ .always_on = 1,
+ },
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data vddlcd = {
+ .constraints = {
+ .name = "VDDLCD",
+ .always_on = 1,
+ },
+ .supply_regulator = "WALLVDD",
+};
+
+static struct regulator_init_data vddalive = {
+ .constraints = {
+ .name = "VDDALIVE",
+ .always_on = 1,
+ },
+ .supply_regulator = "WALLVDD",
+};
+
+static struct wm831x_backup_pdata banff_backup_pdata = {
+ .charger_enable = 1,
+ .vlim = 2500, /* mV */
+ .ilim = 200, /* uA */
+};
+
+static struct wm831x_status_pdata banff_red_led = {
+ .name = "banff:red:",
+ .default_src = WM831X_STATUS_MANUAL,
+};
+
+static struct wm831x_status_pdata banff_green_led = {
+ .name = "banff:green:",
+ .default_src = WM831X_STATUS_MANUAL,
+};
+
+static struct wm831x_touch_pdata touch_pdata = {
+ .data_irq = S3C_EINT(26),
+ .pd_irq = S3C_EINT(27),
+};
+
+static struct wm831x_pdata crag_pmic_pdata = {
+ .wm831x_num = 1,
+ .irq_base = BANFF_PMIC_IRQ_BASE,
+ .gpio_base = BANFF_PMIC_GPIO_BASE,
+ .soft_shutdown = true,
+
+ .backup = &banff_backup_pdata,
+
+ .gpio_defaults = {
+ /* GPIO5: DVS1_REQ - CMOS, DBVDD, active high */
+ [4] = WM831X_GPN_DIR | WM831X_GPN_POL | WM831X_GPN_ENA | 0x8,
+ /* GPIO11: Touchscreen data - CMOS, DBVDD, active high*/
+ [10] = WM831X_GPN_POL | WM831X_GPN_ENA | 0x6,
+ /* GPIO12: Touchscreen pen down - CMOS, DBVDD, active high*/
+ [11] = WM831X_GPN_POL | WM831X_GPN_ENA | 0x7,
+ },
+
+ .dcdc = {
+ &vddarm, /* DCDC1 */
+ &vddint, /* DCDC2 */
+ &vddmem, /* DCDC3 */
+ },
+
+ .ldo = {
+ &vddsys, /* LDO1 */
+ &vddmmc, /* LDO2 */
+ NULL, /* LDO3 */
+ &vddotgi, /* LDO4 */
+ &vddotg, /* LDO5 */
+ &vddhi, /* LDO6 */
+ &vddadc, /* LDO7 */
+ &vddmem0, /* LDO8 */
+ &vddpll, /* LDO9 */
+ &vddlcd, /* LDO10 */
+ &vddalive, /* LDO11 */
+ },
+
+ .status = {
+ &banff_green_led,
+ &banff_red_led,
+ },
+
+ .touch = &touch_pdata,
+};
+
+static struct i2c_board_info i2c_devs0[] = {
+ { I2C_BOARD_INFO("24c08", 0x50), },
+ { I2C_BOARD_INFO("tca6408", 0x20),
+ .platform_data = &crag6410_pca_data,
+ },
+ { I2C_BOARD_INFO("wm8312", 0x34),
+ .platform_data = &crag_pmic_pdata,
+ .irq = S3C_EINT(23),
+ },
+};
+
+static struct s3c2410_platform_i2c i2c0_pdata = {
+ .frequency = 400000,
+};
+
+static struct regulator_consumer_supply pvdd_1v2_consumers[] = {
+ REGULATOR_SUPPLY("DCVDD", "spi0.0"),
+ REGULATOR_SUPPLY("AVDD", "spi0.0"),
+ REGULATOR_SUPPLY("AVDD", "spi0.1"),
+};
+
+static struct regulator_init_data pvdd_1v2 = {
+ .constraints = {
+ .name = "PVDD_1V2",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+
+ .consumer_supplies = pvdd_1v2_consumers,
+ .num_consumer_supplies = ARRAY_SIZE(pvdd_1v2_consumers),
+};
+
+static struct regulator_consumer_supply pvdd_1v8_consumers[] = {
+ REGULATOR_SUPPLY("LDOVDD", "1-001a"),
+ REGULATOR_SUPPLY("PLLVDD", "1-001a"),
+ REGULATOR_SUPPLY("DBVDD", "1-001a"),
+ REGULATOR_SUPPLY("DBVDD1", "1-001a"),
+ REGULATOR_SUPPLY("DBVDD2", "1-001a"),
+ REGULATOR_SUPPLY("DBVDD3", "1-001a"),
+ REGULATOR_SUPPLY("CPVDD", "1-001a"),
+ REGULATOR_SUPPLY("AVDD2", "1-001a"),
+ REGULATOR_SUPPLY("DCVDD", "1-001a"),
+ REGULATOR_SUPPLY("AVDD", "1-001a"),
+ REGULATOR_SUPPLY("DBVDD", "spi0.0"),
+
+ REGULATOR_SUPPLY("DBVDD", "1-003a"),
+ REGULATOR_SUPPLY("LDOVDD", "1-003a"),
+ REGULATOR_SUPPLY("CPVDD", "1-003a"),
+ REGULATOR_SUPPLY("AVDD", "1-003a"),
+ REGULATOR_SUPPLY("DBVDD1", "spi0.1"),
+ REGULATOR_SUPPLY("DBVDD2", "spi0.1"),
+ REGULATOR_SUPPLY("DBVDD3", "spi0.1"),
+ REGULATOR_SUPPLY("LDOVDD", "spi0.1"),
+ REGULATOR_SUPPLY("CPVDD", "spi0.1"),
+};
+
+static struct regulator_init_data pvdd_1v8 = {
+ .constraints = {
+ .name = "PVDD_1V8",
+ .always_on = 1,
+ },
+
+ .consumer_supplies = pvdd_1v8_consumers,
+ .num_consumer_supplies = ARRAY_SIZE(pvdd_1v8_consumers),
+};
+
+static struct regulator_consumer_supply pvdd_3v3_consumers[] = {
+ REGULATOR_SUPPLY("MICVDD", "1-001a"),
+ REGULATOR_SUPPLY("AVDD1", "1-001a"),
+};
+
+static struct regulator_init_data pvdd_3v3 = {
+ .constraints = {
+ .name = "PVDD_3V3",
+ .always_on = 1,
+ },
+
+ .consumer_supplies = pvdd_3v3_consumers,
+ .num_consumer_supplies = ARRAY_SIZE(pvdd_3v3_consumers),
+};
+
+static struct wm831x_pdata glenfarclas_pmic_pdata = {
+ .wm831x_num = 2,
+ .irq_base = GLENFARCLAS_PMIC_IRQ_BASE,
+ .gpio_base = GLENFARCLAS_PMIC_GPIO_BASE,
+ .soft_shutdown = true,
+
+ .gpio_defaults = {
+ /* GPIO1-3: IRQ inputs, rising edge triggered, CMOS */
+ [0] = WM831X_GPN_DIR | WM831X_GPN_POL | WM831X_GPN_ENA,
+ [1] = WM831X_GPN_DIR | WM831X_GPN_POL | WM831X_GPN_ENA,
+ [2] = WM831X_GPN_DIR | WM831X_GPN_POL | WM831X_GPN_ENA,
+ },
+
+ .dcdc = {
+ &pvdd_1v2, /* DCDC1 */
+ &pvdd_1v8, /* DCDC2 */
+ &pvdd_3v3, /* DCDC3 */
+ },
+
+ .disable_touch = true,
+};
+
+static struct wm1250_ev1_pdata wm1250_ev1_pdata = {
+ .gpios = {
+ [WM1250_EV1_GPIO_CLK_ENA] = S3C64XX_GPN(12),
+ [WM1250_EV1_GPIO_CLK_SEL0] = S3C64XX_GPL(12),
+ [WM1250_EV1_GPIO_CLK_SEL1] = S3C64XX_GPL(13),
+ [WM1250_EV1_GPIO_OSR] = S3C64XX_GPL(14),
+ [WM1250_EV1_GPIO_MASTER] = S3C64XX_GPL(8),
+ },
+};
+
+static struct i2c_board_info i2c_devs1[] = {
+ { I2C_BOARD_INFO("wm8311", 0x34),
+ .irq = S3C_EINT(0),
+ .platform_data = &glenfarclas_pmic_pdata },
+
+ { I2C_BOARD_INFO("wlf-gf-module", 0x20) },
+ { I2C_BOARD_INFO("wlf-gf-module", 0x22) },
+ { I2C_BOARD_INFO("wlf-gf-module", 0x24) },
+ { I2C_BOARD_INFO("wlf-gf-module", 0x25) },
+ { I2C_BOARD_INFO("wlf-gf-module", 0x26) },
+
+ { I2C_BOARD_INFO("wm1250-ev1", 0x27),
+ .platform_data = &wm1250_ev1_pdata },
+};
+
+static struct s3c2410_platform_i2c i2c1_pdata = {
+ .frequency = 400000,
+ .bus_num = 1,
+};
+
+static void __init crag6410_map_io(void)
+{
+ s3c64xx_init_io(NULL, 0);
+ s3c64xx_set_xtal_freq(12000000);
+ s3c24xx_init_uarts(crag6410_uartcfgs, ARRAY_SIZE(crag6410_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ /* LCD type and Bypass set by bootloader */
+}
+
+static struct s3c_sdhci_platdata crag6410_hsmmc2_pdata = {
+ .max_width = 4,
+ .cd_type = S3C_SDHCI_CD_PERMANENT,
+ .host_caps = MMC_CAP_POWER_OFF_CARD,
+};
+
+static void crag6410_cfg_sdhci0(struct platform_device *dev, int width)
+{
+ /* Set all the necessary GPG pins to special-function 2 */
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPG(0), 2 + width, S3C_GPIO_SFN(2));
+
+ /* force card-detected for prototype 0 */
+ s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_DOWN);
+}
+
+static struct s3c_sdhci_platdata crag6410_hsmmc0_pdata = {
+ .max_width = 4,
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .cfg_gpio = crag6410_cfg_sdhci0,
+ .host_caps = MMC_CAP_POWER_OFF_CARD,
+};
+
+static const struct gpio_led gpio_leds[] = {
+ {
+ .name = "d13:green:",
+ .gpio = MMGPIO_GPIO_BASE + 0,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "d14:green:",
+ .gpio = MMGPIO_GPIO_BASE + 1,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "d15:green:",
+ .gpio = MMGPIO_GPIO_BASE + 2,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "d16:green:",
+ .gpio = MMGPIO_GPIO_BASE + 3,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "d17:green:",
+ .gpio = MMGPIO_GPIO_BASE + 4,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "d18:green:",
+ .gpio = MMGPIO_GPIO_BASE + 5,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "d19:green:",
+ .gpio = MMGPIO_GPIO_BASE + 6,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "d20:green:",
+ .gpio = MMGPIO_GPIO_BASE + 7,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+};
+
+static const struct gpio_led_platform_data gpio_leds_pdata = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct s3c_hsotg_plat crag6410_hsotg_pdata;
+
+static void __init crag6410_machine_init(void)
+{
+ /* Open drain IRQs need pullups */
+ s3c_gpio_setpull(S3C64XX_GPM(0), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(S3C64XX_GPN(0), S3C_GPIO_PULL_UP);
+
+ gpio_request(S3C64XX_GPB(0), "LCD power");
+ gpio_direction_output(S3C64XX_GPB(0), 0);
+
+ gpio_request(S3C64XX_GPF(14), "LCD PWM");
+ gpio_direction_output(S3C64XX_GPF(14), 0); /* turn off */
+
+ gpio_request(S3C64XX_GPB(1), "SD power");
+ gpio_direction_output(S3C64XX_GPB(1), 0);
+
+ gpio_request(S3C64XX_GPF(10), "nRESETSEL");
+ gpio_direction_output(S3C64XX_GPF(10), 1);
+
+ s3c_sdhci0_set_platdata(&crag6410_hsmmc0_pdata);
+ s3c_sdhci2_set_platdata(&crag6410_hsmmc2_pdata);
+
+ s3c_i2c0_set_platdata(&i2c0_pdata);
+ s3c_i2c1_set_platdata(&i2c1_pdata);
+ s3c_fb_set_platdata(&crag6410_lcd_pdata);
+ s3c_hsotg_set_platdata(&crag6410_hsotg_pdata);
+
+ i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+
+ samsung_keypad_set_platdata(&crag6410_keypad_data);
+ s3c64xx_spi0_set_platdata(NULL, 0, 2);
+
+ platform_add_devices(crag6410_devices, ARRAY_SIZE(crag6410_devices));
+
+ gpio_led_register_device(-1, &gpio_leds_pdata);
+
+ regulator_has_full_constraints();
+
+ s3c64xx_pm_init();
+}
+
+MACHINE_START(WLF_CRAGG_6410, "Wolfson Cragganmore 6410")
+ /* Maintainer: Mark Brown <broonie@opensource.wolfsonmicro.com> */
+ .atag_offset = 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = crag6410_map_io,
+ .init_machine = crag6410_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c
new file mode 100644
index 000000000..e4b087c58
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-hmt.c
@@ -0,0 +1,282 @@
+/* mach-hmt.c - Platform code for Airgoo HMT
+ *
+ * Copyright 2009 Peter Korsgaard <jacmet@sunsite.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/leds.h>
+#include <linux/pwm_backlight.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.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 <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <mach/gpio-samsung.h>
+#include <plat/fb.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"
+
+#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 hmt_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 int hmt_bl_init(struct device *dev)
+{
+ int ret;
+
+ ret = gpio_request(S3C64XX_GPB(4), "lcd backlight enable");
+ if (!ret)
+ ret = gpio_direction_output(S3C64XX_GPB(4), 0);
+
+ return ret;
+}
+
+static int hmt_bl_notify(struct device *dev, int brightness)
+{
+ /*
+ * translate from CIELUV/CIELAB L*->brightness, E.G. from
+ * perceived luminance to light output. Assumes range 0..25600
+ */
+ if (brightness < 0x800) {
+ /* Y = Yn * L / 903.3 */
+ brightness = (100*256 * brightness + 231245/2) / 231245;
+ } else {
+ /* Y = Yn * ((L + 16) / 116 )^3 */
+ int t = (brightness*4 + 16*1024 + 58)/116;
+ brightness = 25 * ((t * t * t + 0x100000/2) / 0x100000);
+ }
+
+ gpio_set_value(S3C64XX_GPB(4), brightness);
+
+ return brightness;
+}
+
+static void hmt_bl_exit(struct device *dev)
+{
+ gpio_free(S3C64XX_GPB(4));
+}
+
+static struct platform_pwm_backlight_data hmt_backlight_data = {
+ .pwm_id = 1,
+ .max_brightness = 100 * 256,
+ .dft_brightness = 40 * 256,
+ .pwm_period_ns = 1000000000 / (100 * 256 * 20),
+ .enable_gpio = -1,
+ .init = hmt_bl_init,
+ .notify = hmt_bl_notify,
+ .exit = hmt_bl_exit,
+
+};
+
+static struct platform_device hmt_backlight_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &samsung_device_pwm.dev,
+ .platform_data = &hmt_backlight_data,
+ },
+};
+
+static struct s3c_fb_pd_win hmt_fb_win0 = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 800,
+ .yres = 480,
+};
+
+static struct fb_videomode hmt_lcd_timing = {
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+};
+
+/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
+static struct s3c_fb_platdata hmt_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .vtiming = &hmt_lcd_timing,
+ .win[0] = &hmt_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+static struct mtd_partition hmt_nand_part[] = {
+ [0] = {
+ .name = "uboot",
+ .size = SZ_512K,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "uboot-env1",
+ .size = SZ_256K,
+ .offset = SZ_512K,
+ },
+ [2] = {
+ .name = "uboot-env2",
+ .size = SZ_256K,
+ .offset = SZ_512K + SZ_256K,
+ },
+ [3] = {
+ .name = "kernel",
+ .size = SZ_2M,
+ .offset = SZ_1M,
+ },
+ [4] = {
+ .name = "rootfs",
+ .size = MTDPART_SIZ_FULL,
+ .offset = SZ_1M + SZ_2M,
+ },
+};
+
+static struct s3c2410_nand_set hmt_nand_sets[] = {
+ [0] = {
+ .name = "nand",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(hmt_nand_part),
+ .partitions = hmt_nand_part,
+ },
+};
+
+static struct s3c2410_platform_nand hmt_nand_info = {
+ .tacls = 25,
+ .twrph0 = 55,
+ .twrph1 = 40,
+ .nr_sets = ARRAY_SIZE(hmt_nand_sets),
+ .sets = hmt_nand_sets,
+};
+
+static struct gpio_led hmt_leds[] = {
+ { /* left function keys */
+ .name = "left:blue",
+ .gpio = S3C64XX_GPO(12),
+ .default_trigger = "default-on",
+ },
+ { /* right function keys - red */
+ .name = "right:red",
+ .gpio = S3C64XX_GPO(13),
+ },
+ { /* right function keys - green */
+ .name = "right:green",
+ .gpio = S3C64XX_GPO(14),
+ },
+ { /* right function keys - blue */
+ .name = "right:blue",
+ .gpio = S3C64XX_GPO(15),
+ .default_trigger = "default-on",
+ },
+};
+
+static struct gpio_led_platform_data hmt_led_data = {
+ .num_leds = ARRAY_SIZE(hmt_leds),
+ .leds = hmt_leds,
+};
+
+static struct platform_device hmt_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev.platform_data = &hmt_led_data,
+};
+
+static struct map_desc hmt_iodesc[] = {};
+
+static struct platform_device *hmt_devices[] __initdata = {
+ &s3c_device_i2c0,
+ &s3c_device_nand,
+ &s3c_device_fb,
+ &s3c_device_ohci,
+ &samsung_device_pwm,
+ &hmt_backlight_device,
+ &hmt_leds_device,
+};
+
+static void __init hmt_map_io(void)
+{
+ s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc));
+ s3c64xx_set_xtal_freq(12000000);
+ s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init hmt_machine_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+ s3c_fb_set_platdata(&hmt_lcd_pdata);
+ s3c_nand_set_platdata(&hmt_nand_info);
+
+ gpio_request(S3C64XX_GPC(7), "usb power");
+ gpio_direction_output(S3C64XX_GPC(7), 0);
+ gpio_request(S3C64XX_GPM(0), "usb power");
+ gpio_direction_output(S3C64XX_GPM(0), 1);
+ gpio_request(S3C64XX_GPK(7), "usb power");
+ gpio_direction_output(S3C64XX_GPK(7), 1);
+ gpio_request(S3C64XX_GPF(13), "usb power");
+ gpio_direction_output(S3C64XX_GPF(13), 1);
+
+ platform_add_devices(hmt_devices, ARRAY_SIZE(hmt_devices));
+}
+
+MACHINE_START(HMT, "Airgoo-HMT")
+ /* Maintainer: Peter Korsgaard <jacmet@sunsite.dk> */
+ .atag_offset = 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = hmt_map_io,
+ .init_machine = hmt_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c
new file mode 100644
index 000000000..ab61af50b
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-mini6410.c
@@ -0,0 +1,371 @@
+/* linux/arch/arm/mach-s3c64xx/mach-mini6410.c
+ *
+ * Copyright 2010 Darius Augulis <augulis.darius@gmail.com>
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/dm9000.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/types.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/adc.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/mmc-sdhci-s3c.h>
+#include <plat/sdhci.h>
+#include <linux/platform_data/touchscreen-s3c2410.h>
+
+#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "regs-modem.h"
+#include "regs-srom.h"
+
+#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 mini6410_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,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+};
+
+/* DM9000AEP 10/100 ethernet controller */
+
+static struct resource mini6410_dm9k_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN1, 2),
+ [1] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN1 + 4, 2),
+ [2] = DEFINE_RES_NAMED(S3C_EINT(7), 1, NULL, IORESOURCE_IRQ \
+ | IORESOURCE_IRQ_HIGHLEVEL),
+};
+
+static struct dm9000_plat_data mini6410_dm9k_pdata = {
+ .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+};
+
+static struct platform_device mini6410_device_eth = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(mini6410_dm9k_resource),
+ .resource = mini6410_dm9k_resource,
+ .dev = {
+ .platform_data = &mini6410_dm9k_pdata,
+ },
+};
+
+static struct mtd_partition mini6410_nand_part[] = {
+ [0] = {
+ .name = "uboot",
+ .size = SZ_1M,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "kernel",
+ .size = SZ_2M,
+ .offset = SZ_1M,
+ },
+ [2] = {
+ .name = "rootfs",
+ .size = MTDPART_SIZ_FULL,
+ .offset = SZ_1M + SZ_2M,
+ },
+};
+
+static struct s3c2410_nand_set mini6410_nand_sets[] = {
+ [0] = {
+ .name = "nand",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(mini6410_nand_part),
+ .partitions = mini6410_nand_part,
+ },
+};
+
+static struct s3c2410_platform_nand mini6410_nand_info = {
+ .tacls = 25,
+ .twrph0 = 55,
+ .twrph1 = 40,
+ .nr_sets = ARRAY_SIZE(mini6410_nand_sets),
+ .sets = mini6410_nand_sets,
+};
+
+static struct s3c_fb_pd_win mini6410_lcd_type0_fb_win = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 480,
+ .yres = 272,
+};
+
+static struct fb_videomode mini6410_lcd_type0_timing = {
+ /* 4.3" 480x272 */
+ .left_margin = 3,
+ .right_margin = 2,
+ .upper_margin = 1,
+ .lower_margin = 1,
+ .hsync_len = 40,
+ .vsync_len = 1,
+ .xres = 480,
+ .yres = 272,
+};
+
+static struct s3c_fb_pd_win mini6410_lcd_type1_fb_win = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 800,
+ .yres = 480,
+};
+
+static struct fb_videomode mini6410_lcd_type1_timing = {
+ /* 7.0" 800x480 */
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+};
+
+static struct s3c_fb_platdata mini6410_lcd_pdata[] __initdata = {
+ {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .vtiming = &mini6410_lcd_type0_timing,
+ .win[0] = &mini6410_lcd_type0_fb_win,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+ }, {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .vtiming = &mini6410_lcd_type1_timing,
+ .win[0] = &mini6410_lcd_type1_fb_win,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+ },
+ { },
+};
+
+static void mini6410_lcd_power_set(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power)
+ gpio_direction_output(S3C64XX_GPE(0), 1);
+ else
+ gpio_direction_output(S3C64XX_GPE(0), 0);
+}
+
+static struct plat_lcd_data mini6410_lcd_power_data = {
+ .set_power = mini6410_lcd_power_set,
+};
+
+static struct platform_device mini6410_lcd_powerdev = {
+ .name = "platform-lcd",
+ .dev.parent = &s3c_device_fb.dev,
+ .dev.platform_data = &mini6410_lcd_power_data,
+};
+
+static struct s3c_sdhci_platdata mini6410_hsmmc1_pdata = {
+ .max_width = 4,
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = S3C64XX_GPN(10),
+ .ext_cd_gpio_invert = true,
+};
+
+static struct platform_device *mini6410_devices[] __initdata = {
+ &mini6410_device_eth,
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc1,
+ &s3c_device_ohci,
+ &s3c_device_nand,
+ &s3c_device_fb,
+ &mini6410_lcd_powerdev,
+ &s3c_device_adc,
+ &s3c_device_ts,
+};
+
+static void __init mini6410_map_io(void)
+{
+ u32 tmp;
+
+ s3c64xx_init_io(NULL, 0);
+ s3c64xx_set_xtal_freq(12000000);
+ s3c24xx_init_uarts(mini6410_uartcfgs, ARRAY_SIZE(mini6410_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ /* set the LCD type */
+ tmp = __raw_readl(S3C64XX_SPCON);
+ tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
+ tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
+ __raw_writel(tmp, S3C64XX_SPCON);
+
+ /* remove the LCD bypass */
+ tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
+ tmp &= ~MIFPCON_LCD_BYPASS;
+ __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
+}
+
+/*
+ * mini6410_features string
+ *
+ * 0-9 LCD configuration
+ *
+ */
+static char mini6410_features_str[12] __initdata = "0";
+
+static int __init mini6410_features_setup(char *str)
+{
+ if (str)
+ strlcpy(mini6410_features_str, str,
+ sizeof(mini6410_features_str));
+ return 1;
+}
+
+__setup("mini6410=", mini6410_features_setup);
+
+#define FEATURE_SCREEN (1 << 0)
+
+struct mini6410_features_t {
+ int done;
+ int lcd_index;
+};
+
+static void mini6410_parse_features(
+ struct mini6410_features_t *features,
+ const char *features_str)
+{
+ const char *fp = features_str;
+
+ features->done = 0;
+ features->lcd_index = 0;
+
+ while (*fp) {
+ char f = *fp++;
+
+ switch (f) {
+ case '0'...'9': /* tft screen */
+ if (features->done & FEATURE_SCREEN) {
+ printk(KERN_INFO "MINI6410: '%c' ignored, "
+ "screen type already set\n", f);
+ } else {
+ int li = f - '0';
+ if (li >= ARRAY_SIZE(mini6410_lcd_pdata))
+ printk(KERN_INFO "MINI6410: '%c' out "
+ "of range LCD mode\n", f);
+ else {
+ features->lcd_index = li;
+ }
+ }
+ features->done |= FEATURE_SCREEN;
+ break;
+ }
+ }
+}
+
+static void __init mini6410_machine_init(void)
+{
+ u32 cs1;
+ struct mini6410_features_t features = { 0 };
+
+ printk(KERN_INFO "MINI6410: Option string mini6410=%s\n",
+ mini6410_features_str);
+
+ /* Parse the feature string */
+ mini6410_parse_features(&features, mini6410_features_str);
+
+ printk(KERN_INFO "MINI6410: selected LCD display is %dx%d\n",
+ mini6410_lcd_pdata[features.lcd_index].win[0]->xres,
+ mini6410_lcd_pdata[features.lcd_index].win[0]->yres);
+
+ s3c_nand_set_platdata(&mini6410_nand_info);
+ s3c_fb_set_platdata(&mini6410_lcd_pdata[features.lcd_index]);
+ s3c_sdhci1_set_platdata(&mini6410_hsmmc1_pdata);
+ s3c24xx_ts_set_platdata(NULL);
+
+ /* configure nCS1 width to 16 bits */
+
+ cs1 = __raw_readl(S3C64XX_SROM_BW) &
+ ~(S3C64XX_SROM_BW__CS_MASK << S3C64XX_SROM_BW__NCS1__SHIFT);
+ cs1 |= ((1 << S3C64XX_SROM_BW__DATAWIDTH__SHIFT) |
+ (1 << S3C64XX_SROM_BW__WAITENABLE__SHIFT) |
+ (1 << S3C64XX_SROM_BW__BYTEENABLE__SHIFT)) <<
+ S3C64XX_SROM_BW__NCS1__SHIFT;
+ __raw_writel(cs1, S3C64XX_SROM_BW);
+
+ /* set timing for nCS1 suitable for ethernet chip */
+
+ __raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) |
+ (6 << S3C64XX_SROM_BCX__TACP__SHIFT) |
+ (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) |
+ (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) |
+ (13 << S3C64XX_SROM_BCX__TACC__SHIFT) |
+ (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
+ (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);
+
+ gpio_request(S3C64XX_GPF(15), "LCD power");
+ gpio_request(S3C64XX_GPE(0), "LCD power");
+
+ platform_add_devices(mini6410_devices, ARRAY_SIZE(mini6410_devices));
+}
+
+MACHINE_START(MINI6410, "MINI6410")
+ /* Maintainer: Darius Augulis <augulis.darius@gmail.com> */
+ .atag_offset = 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = mini6410_map_io,
+ .init_machine = mini6410_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c64xx/mach-ncp.c
new file mode 100644
index 000000000..80cb1446f
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-ncp.c
@@ -0,0 +1,108 @@
+/*
+ * linux/arch/arm/mach-s3c64xx/mach-ncp.c
+ *
+ * Copyright (C) 2008-2009 Samsung Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <plat/fb.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+
+#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 ncp_uartcfgs[] __initdata = {
+ /* REVISIT: NCP uses only serial 1, 2 */
+ [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 *ncp_devices[] __initdata = {
+ &s3c_device_hsmmc1,
+ &s3c_device_i2c0,
+};
+
+static struct map_desc ncp_iodesc[] __initdata = {};
+
+static void __init ncp_map_io(void)
+{
+ s3c64xx_init_io(ncp_iodesc, ARRAY_SIZE(ncp_iodesc));
+ s3c64xx_set_xtal_freq(12000000);
+ s3c24xx_init_uarts(ncp_uartcfgs, ARRAY_SIZE(ncp_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static void __init ncp_machine_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+
+ platform_add_devices(ncp_devices, ARRAY_SIZE(ncp_devices));
+}
+
+MACHINE_START(NCP, "NCP")
+ /* Maintainer: Samsung Electronics */
+ .atag_offset = 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = ncp_map_io,
+ .init_machine = ncp_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c
new file mode 100644
index 000000000..85fa9598b
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-real6410.c
@@ -0,0 +1,340 @@
+/* linux/arch/arm/mach-s3c64xx/mach-real6410.c
+ *
+ * Copyright 2010 Darius Augulis <augulis.darius@gmail.com>
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/dm9000.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/types.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/adc.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <linux/platform_data/touchscreen-s3c2410.h>
+
+#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "regs-modem.h"
+#include "regs-srom.h"
+
+#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 real6410_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,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+};
+
+/* DM9000AEP 10/100 ethernet controller */
+
+static struct resource real6410_dm9k_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN1, 2),
+ [1] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN1 + 4, 2),
+ [2] = DEFINE_RES_NAMED(S3C_EINT(7), 1, NULL, IORESOURCE_IRQ \
+ | IORESOURCE_IRQ_HIGHLEVEL),
+};
+
+static struct dm9000_plat_data real6410_dm9k_pdata = {
+ .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+};
+
+static struct platform_device real6410_device_eth = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(real6410_dm9k_resource),
+ .resource = real6410_dm9k_resource,
+ .dev = {
+ .platform_data = &real6410_dm9k_pdata,
+ },
+};
+
+static struct s3c_fb_pd_win real6410_lcd_type0_fb_win = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 480,
+ .yres = 272,
+};
+
+static struct fb_videomode real6410_lcd_type0_timing = {
+ /* 4.3" 480x272 */
+ .left_margin = 3,
+ .right_margin = 2,
+ .upper_margin = 1,
+ .lower_margin = 1,
+ .hsync_len = 40,
+ .vsync_len = 1,
+};
+
+static struct s3c_fb_pd_win real6410_lcd_type1_fb_win = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 800,
+ .yres = 480,
+};
+
+static struct fb_videomode real6410_lcd_type1_timing = {
+ /* 7.0" 800x480 */
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+};
+
+static struct s3c_fb_platdata real6410_lcd_pdata[] __initdata = {
+ {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .vtiming = &real6410_lcd_type0_timing,
+ .win[0] = &real6410_lcd_type0_fb_win,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+ }, {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .vtiming = &real6410_lcd_type1_timing,
+ .win[0] = &real6410_lcd_type1_fb_win,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+ },
+ { },
+};
+
+static struct mtd_partition real6410_nand_part[] = {
+ [0] = {
+ .name = "uboot",
+ .size = SZ_1M,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "kernel",
+ .size = SZ_2M,
+ .offset = SZ_1M,
+ },
+ [2] = {
+ .name = "rootfs",
+ .size = MTDPART_SIZ_FULL,
+ .offset = SZ_1M + SZ_2M,
+ },
+};
+
+static struct s3c2410_nand_set real6410_nand_sets[] = {
+ [0] = {
+ .name = "nand",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(real6410_nand_part),
+ .partitions = real6410_nand_part,
+ },
+};
+
+static struct s3c2410_platform_nand real6410_nand_info = {
+ .tacls = 25,
+ .twrph0 = 55,
+ .twrph1 = 40,
+ .nr_sets = ARRAY_SIZE(real6410_nand_sets),
+ .sets = real6410_nand_sets,
+};
+
+static struct platform_device *real6410_devices[] __initdata = {
+ &real6410_device_eth,
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc1,
+ &s3c_device_fb,
+ &s3c_device_nand,
+ &s3c_device_adc,
+ &s3c_device_ts,
+ &s3c_device_ohci,
+};
+
+static void __init real6410_map_io(void)
+{
+ u32 tmp;
+
+ s3c64xx_init_io(NULL, 0);
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(real6410_uartcfgs, ARRAY_SIZE(real6410_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ /* set the LCD type */
+ tmp = __raw_readl(S3C64XX_SPCON);
+ tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
+ tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
+ __raw_writel(tmp, S3C64XX_SPCON);
+
+ /* remove the LCD bypass */
+ tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
+ tmp &= ~MIFPCON_LCD_BYPASS;
+ __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
+}
+
+/*
+ * real6410_features string
+ *
+ * 0-9 LCD configuration
+ *
+ */
+static char real6410_features_str[12] __initdata = "0";
+
+static int __init real6410_features_setup(char *str)
+{
+ if (str)
+ strlcpy(real6410_features_str, str,
+ sizeof(real6410_features_str));
+ return 1;
+}
+
+__setup("real6410=", real6410_features_setup);
+
+#define FEATURE_SCREEN (1 << 0)
+
+struct real6410_features_t {
+ int done;
+ int lcd_index;
+};
+
+static void real6410_parse_features(
+ struct real6410_features_t *features,
+ const char *features_str)
+{
+ const char *fp = features_str;
+
+ features->done = 0;
+ features->lcd_index = 0;
+
+ while (*fp) {
+ char f = *fp++;
+
+ switch (f) {
+ case '0'...'9': /* tft screen */
+ if (features->done & FEATURE_SCREEN) {
+ printk(KERN_INFO "REAL6410: '%c' ignored, "
+ "screen type already set\n", f);
+ } else {
+ int li = f - '0';
+ if (li >= ARRAY_SIZE(real6410_lcd_pdata))
+ printk(KERN_INFO "REAL6410: '%c' out "
+ "of range LCD mode\n", f);
+ else {
+ features->lcd_index = li;
+ }
+ }
+ features->done |= FEATURE_SCREEN;
+ break;
+ }
+ }
+}
+
+static void __init real6410_machine_init(void)
+{
+ u32 cs1;
+ struct real6410_features_t features = { 0 };
+
+ printk(KERN_INFO "REAL6410: Option string real6410=%s\n",
+ real6410_features_str);
+
+ /* Parse the feature string */
+ real6410_parse_features(&features, real6410_features_str);
+
+ printk(KERN_INFO "REAL6410: selected LCD display is %dx%d\n",
+ real6410_lcd_pdata[features.lcd_index].win[0]->xres,
+ real6410_lcd_pdata[features.lcd_index].win[0]->yres);
+
+ s3c_fb_set_platdata(&real6410_lcd_pdata[features.lcd_index]);
+ s3c_nand_set_platdata(&real6410_nand_info);
+ s3c24xx_ts_set_platdata(NULL);
+
+ /* configure nCS1 width to 16 bits */
+
+ cs1 = __raw_readl(S3C64XX_SROM_BW) &
+ ~(S3C64XX_SROM_BW__CS_MASK << S3C64XX_SROM_BW__NCS1__SHIFT);
+ cs1 |= ((1 << S3C64XX_SROM_BW__DATAWIDTH__SHIFT) |
+ (1 << S3C64XX_SROM_BW__WAITENABLE__SHIFT) |
+ (1 << S3C64XX_SROM_BW__BYTEENABLE__SHIFT)) <<
+ S3C64XX_SROM_BW__NCS1__SHIFT;
+ __raw_writel(cs1, S3C64XX_SROM_BW);
+
+ /* set timing for nCS1 suitable for ethernet chip */
+
+ __raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) |
+ (6 << S3C64XX_SROM_BCX__TACP__SHIFT) |
+ (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) |
+ (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) |
+ (13 << S3C64XX_SROM_BCX__TACC__SHIFT) |
+ (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
+ (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);
+
+ gpio_request(S3C64XX_GPF(15), "LCD power");
+
+ platform_add_devices(real6410_devices, ARRAY_SIZE(real6410_devices));
+}
+
+MACHINE_START(REAL6410, "REAL6410")
+ /* Maintainer: Darius Augulis <augulis.darius@gmail.com> */
+ .atag_offset = 0x100,
+
+ .init_irq = s3c6410_init_irq,
+ .map_io = real6410_map_io,
+ .init_machine = real6410_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c b/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c
new file mode 100644
index 000000000..2fddf3819
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c
@@ -0,0 +1,76 @@
+/*
+ * Samsung's S3C64XX flattened device tree enabled machine
+ *
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/system_misc.h>
+
+#include <plat/cpu.h>
+#include <plat/watchdog-reset.h>
+
+#include <mach/map.h>
+
+#include "common.h"
+
+/*
+ * IO mapping for shared system controller IP.
+ *
+ * FIXME: Make remaining drivers use dynamic mapping.
+ */
+static struct map_desc s3c64xx_dt_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S3C_VA_SYS,
+ .pfn = __phys_to_pfn(S3C64XX_PA_SYSCON),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init s3c64xx_dt_map_io(void)
+{
+ debug_ll_io_init();
+ iotable_init(s3c64xx_dt_iodesc, ARRAY_SIZE(s3c64xx_dt_iodesc));
+
+ s3c64xx_init_cpu();
+
+ if (!soc_is_s3c64xx())
+ panic("SoC is not S3C64xx!");
+}
+
+static void __init s3c64xx_dt_init_machine(void)
+{
+ samsung_wdt_reset_of_init();
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static void s3c64xx_dt_restart(enum reboot_mode mode, const char *cmd)
+{
+ if (mode != REBOOT_SOFT)
+ samsung_wdt_reset();
+
+ /* if all else fails, or mode was for soft, jump to 0 */
+ soft_restart(0);
+}
+
+static char const *s3c64xx_dt_compat[] __initdata = {
+ "samsung,s3c6400",
+ "samsung,s3c6410",
+ NULL
+};
+
+DT_MACHINE_START(S3C6400_DT, "Samsung S3C64xx (Flattened Device Tree)")
+ /* Maintainer: Tomasz Figa <tomasz.figa@gmail.com> */
+ .dt_compat = s3c64xx_dt_compat,
+ .map_io = s3c64xx_dt_map_io,
+ .init_machine = s3c64xx_dt_init_machine,
+ .restart = s3c64xx_dt_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c
new file mode 100644
index 000000000..b3d13537a
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smartq.c
@@ -0,0 +1,400 @@
+/*
+ * linux/arch/arm/mach-s3c64xx/mach-smartq.c
+ *
+ * Copyright (C) 2010 Maurus Cuelenaere
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pwm_backlight.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/usb/gpio_vbus.h>
+#include <linux/platform_data/s3c-hsotg.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <plat/gpio-cfg.h>
+#include <linux/platform_data/hwmon-s3c.h>
+#include <linux/platform_data/usb-ohci-s3c2410.h>
+#include <plat/sdhci.h>
+#include <linux/platform_data/touchscreen-s3c2410.h>
+
+#include <video/platform_lcd.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "regs-modem.h"
+
+#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 smartq_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 void smartq_usb_host_powercontrol(int port, int to)
+{
+ pr_debug("%s(%d, %d)\n", __func__, port, to);
+
+ if (port == 0) {
+ gpio_set_value(S3C64XX_GPL(0), to);
+ gpio_set_value(S3C64XX_GPL(1), to);
+ }
+}
+
+static irqreturn_t smartq_usb_host_ocirq(int irq, void *pw)
+{
+ struct s3c2410_hcd_info *info = pw;
+
+ if (gpio_get_value(S3C64XX_GPL(10)) == 0) {
+ pr_debug("%s: over-current irq (oc detected)\n", __func__);
+ s3c2410_usb_report_oc(info, 3);
+ } else {
+ pr_debug("%s: over-current irq (oc cleared)\n", __func__);
+ s3c2410_usb_report_oc(info, 0);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void smartq_usb_host_enableoc(struct s3c2410_hcd_info *info, int on)
+{
+ int ret;
+
+ /* This isn't present on a SmartQ 5 board */
+ if (machine_is_smartq5())
+ return;
+
+ if (on) {
+ ret = request_irq(gpio_to_irq(S3C64XX_GPL(10)),
+ smartq_usb_host_ocirq,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "USB host overcurrent", info);
+ if (ret != 0)
+ pr_err("failed to request usb oc irq: %d\n", ret);
+ } else {
+ free_irq(gpio_to_irq(S3C64XX_GPL(10)), info);
+ }
+}
+
+static struct s3c2410_hcd_info smartq_usb_host_info = {
+ .port[0] = {
+ .flags = S3C_HCDFLG_USED
+ },
+ .port[1] = {
+ .flags = 0
+ },
+
+ .power_control = smartq_usb_host_powercontrol,
+ .enable_oc = smartq_usb_host_enableoc,
+};
+
+static struct gpio_vbus_mach_info smartq_usb_otg_vbus_pdata = {
+ .gpio_vbus = S3C64XX_GPL(9),
+ .gpio_pullup = -1,
+ .gpio_vbus_inverted = true,
+};
+
+static struct platform_device smartq_usb_otg_vbus_dev = {
+ .name = "gpio-vbus",
+ .dev.platform_data = &smartq_usb_otg_vbus_pdata,
+};
+
+static int smartq_bl_init(struct device *dev)
+{
+ s3c_gpio_cfgpin(S3C64XX_GPF(15), S3C_GPIO_SFN(2));
+
+ return 0;
+}
+
+static struct platform_pwm_backlight_data smartq_backlight_data = {
+ .pwm_id = 1,
+ .max_brightness = 1000,
+ .dft_brightness = 600,
+ .pwm_period_ns = 1000000000 / (1000 * 20),
+ .enable_gpio = -1,
+ .init = smartq_bl_init,
+};
+
+static struct platform_device smartq_backlight_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &samsung_device_pwm.dev,
+ .platform_data = &smartq_backlight_data,
+ },
+};
+
+static struct s3c2410_ts_mach_info smartq_touchscreen_pdata __initdata = {
+ .delay = 65535,
+ .presc = 99,
+ .oversampling_shift = 4,
+};
+
+static struct s3c_sdhci_platdata smartq_internal_hsmmc_pdata = {
+ .max_width = 4,
+ .cd_type = S3C_SDHCI_CD_PERMANENT,
+};
+
+static struct s3c_hwmon_pdata smartq_hwmon_pdata __initdata = {
+ /* Battery voltage (?-4.2V) */
+ .in[0] = &(struct s3c_hwmon_chcfg) {
+ .name = "smartq:battery-voltage",
+ .mult = 3300,
+ .div = 2048,
+ },
+ /* Reference voltage (1.2V) */
+ .in[1] = &(struct s3c_hwmon_chcfg) {
+ .name = "smartq:reference-voltage",
+ .mult = 3300,
+ .div = 4096,
+ },
+};
+
+static struct s3c_hsotg_plat smartq_hsotg_pdata;
+
+static int __init smartq_lcd_setup_gpio(void)
+{
+ int ret;
+
+ ret = gpio_request(S3C64XX_GPM(3), "LCD power");
+ if (ret < 0)
+ return ret;
+
+ /* turn power off */
+ gpio_direction_output(S3C64XX_GPM(3), 0);
+
+ return 0;
+}
+
+/* GPM0 -> CS */
+static struct spi_gpio_platform_data smartq_lcd_control = {
+ .sck = S3C64XX_GPM(1),
+ .mosi = S3C64XX_GPM(2),
+ .miso = S3C64XX_GPM(2),
+};
+
+static struct platform_device smartq_lcd_control_device = {
+ .name = "spi-gpio",
+ .id = 1,
+ .dev.platform_data = &smartq_lcd_control,
+};
+
+static void smartq_lcd_power_set(struct plat_lcd_data *pd, unsigned int power)
+{
+ gpio_direction_output(S3C64XX_GPM(3), power);
+}
+
+static struct plat_lcd_data smartq_lcd_power_data = {
+ .set_power = smartq_lcd_power_set,
+};
+
+static struct platform_device smartq_lcd_power_device = {
+ .name = "platform-lcd",
+ .dev.parent = &s3c_device_fb.dev,
+ .dev.platform_data = &smartq_lcd_power_data,
+};
+
+static struct i2c_board_info smartq_i2c_devs[] __initdata = {
+ { I2C_BOARD_INFO("wm8987", 0x1a), },
+};
+
+static struct platform_device *smartq_devices[] __initdata = {
+ &s3c_device_hsmmc1, /* Init iNAND first, ... */
+ &s3c_device_hsmmc0, /* ... then the external SD card */
+ &s3c_device_hsmmc2,
+ &s3c_device_adc,
+ &s3c_device_fb,
+ &s3c_device_hwmon,
+ &s3c_device_i2c0,
+ &s3c_device_ohci,
+ &s3c_device_rtc,
+ &samsung_device_pwm,
+ &s3c_device_ts,
+ &s3c_device_usb_hsotg,
+ &s3c64xx_device_iis0,
+ &smartq_backlight_device,
+ &smartq_lcd_control_device,
+ &smartq_lcd_power_device,
+ &smartq_usb_otg_vbus_dev,
+};
+
+static void __init smartq_lcd_mode_set(void)
+{
+ u32 tmp;
+
+ /* set the LCD type */
+ tmp = __raw_readl(S3C64XX_SPCON);
+ tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
+ tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
+ __raw_writel(tmp, S3C64XX_SPCON);
+
+ /* remove the LCD bypass */
+ tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
+ tmp &= ~MIFPCON_LCD_BYPASS;
+ __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
+}
+
+static void smartq_power_off(void)
+{
+ gpio_direction_output(S3C64XX_GPK(15), 1);
+}
+
+static int __init smartq_power_off_init(void)
+{
+ int ret;
+
+ ret = gpio_request(S3C64XX_GPK(15), "Power control");
+ if (ret < 0) {
+ pr_err("%s: failed to get GPK15\n", __func__);
+ return ret;
+ }
+
+ /* leave power on */
+ gpio_direction_output(S3C64XX_GPK(15), 0);
+
+ pm_power_off = smartq_power_off;
+
+ return ret;
+}
+
+static int __init smartq_usb_host_init(void)
+{
+ int ret;
+
+ ret = gpio_request(S3C64XX_GPL(0), "USB power control");
+ if (ret < 0) {
+ pr_err("%s: failed to get GPL0\n", __func__);
+ return ret;
+ }
+
+ ret = gpio_request(S3C64XX_GPL(1), "USB host power control");
+ if (ret < 0) {
+ pr_err("%s: failed to get GPL1\n", __func__);
+ goto err;
+ }
+
+ if (!machine_is_smartq5()) {
+ /* This isn't present on a SmartQ 5 board */
+ ret = gpio_request(S3C64XX_GPL(10), "USB host overcurrent");
+ if (ret < 0) {
+ pr_err("%s: failed to get GPL10\n", __func__);
+ goto err2;
+ }
+ }
+
+ /* turn power off */
+ gpio_direction_output(S3C64XX_GPL(0), 0);
+ gpio_direction_output(S3C64XX_GPL(1), 0);
+ if (!machine_is_smartq5())
+ gpio_direction_input(S3C64XX_GPL(10));
+
+ s3c_device_ohci.dev.platform_data = &smartq_usb_host_info;
+
+ return 0;
+
+err2:
+ gpio_free(S3C64XX_GPL(1));
+err:
+ gpio_free(S3C64XX_GPL(0));
+ return ret;
+}
+
+static int __init smartq_wifi_init(void)
+{
+ int ret;
+
+ ret = gpio_request(S3C64XX_GPK(1), "wifi control");
+ if (ret < 0) {
+ pr_err("%s: failed to get GPK1\n", __func__);
+ return ret;
+ }
+
+ ret = gpio_request(S3C64XX_GPK(2), "wifi reset");
+ if (ret < 0) {
+ pr_err("%s: failed to get GPK2\n", __func__);
+ gpio_free(S3C64XX_GPK(1));
+ return ret;
+ }
+
+ /* turn power on */
+ gpio_direction_output(S3C64XX_GPK(1), 1);
+
+ /* reset device */
+ gpio_direction_output(S3C64XX_GPK(2), 0);
+ mdelay(100);
+ gpio_set_value(S3C64XX_GPK(2), 1);
+ gpio_direction_input(S3C64XX_GPK(2));
+
+ return 0;
+}
+
+static struct map_desc smartq_iodesc[] __initdata = {};
+void __init smartq_map_io(void)
+{
+ s3c64xx_init_io(smartq_iodesc, ARRAY_SIZE(smartq_iodesc));
+ s3c64xx_set_xtal_freq(12000000);
+ s3c64xx_set_xusbxti_freq(12000000);
+ s3c24xx_init_uarts(smartq_uartcfgs, ARRAY_SIZE(smartq_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ smartq_lcd_mode_set();
+}
+
+void __init smartq_machine_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+ s3c_hsotg_set_platdata(&smartq_hsotg_pdata);
+ s3c_hwmon_set_platdata(&smartq_hwmon_pdata);
+ s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata);
+ s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata);
+ s3c24xx_ts_set_platdata(&smartq_touchscreen_pdata);
+
+ i2c_register_board_info(0, smartq_i2c_devs,
+ ARRAY_SIZE(smartq_i2c_devs));
+
+ WARN_ON(smartq_lcd_setup_gpio());
+ WARN_ON(smartq_power_off_init());
+ WARN_ON(smartq_usb_host_init());
+ WARN_ON(smartq_wifi_init());
+
+ platform_add_devices(smartq_devices, ARRAY_SIZE(smartq_devices));
+}
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.h b/arch/arm/mach-s3c64xx/mach-smartq.h
new file mode 100644
index 000000000..8e8b693db
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smartq.h
@@ -0,0 +1,20 @@
+/*
+ * linux/arch/arm/mach-s3c64xx/mach-smartq.h
+ *
+ * Copyright (C) 2010 Maurus Cuelenaere
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __MACH_SMARTQ_H
+#define __MACH_SMARTQ_H __FILE__
+
+#include <linux/init.h>
+
+extern void __init smartq_map_io(void);
+extern void __init smartq_machine_init(void);
+
+#endif /* __MACH_SMARTQ_H */
diff --git a/arch/arm/mach-s3c64xx/mach-smartq5.c b/arch/arm/mach-s3c64xx/mach-smartq5.c
new file mode 100644
index 000000000..33224ab36
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smartq5.c
@@ -0,0 +1,161 @@
+/*
+ * linux/arch/arm/mach-s3c64xx/mach-smartq5.c
+ *
+ * Copyright (C) 2010 Maurus Cuelenaere
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <video/samsung_fimd.h>
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "mach-smartq.h"
+
+static struct gpio_led smartq5_leds[] = {
+ {
+ .name = "smartq5:green",
+ .active_low = 1,
+ .gpio = S3C64XX_GPN(8),
+ },
+ {
+ .name = "smartq5:red",
+ .active_low = 1,
+ .gpio = S3C64XX_GPN(9),
+ },
+};
+
+static struct gpio_led_platform_data smartq5_led_data = {
+ .num_leds = ARRAY_SIZE(smartq5_leds),
+ .leds = smartq5_leds,
+};
+
+static struct platform_device smartq5_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev.platform_data = &smartq5_led_data,
+};
+
+/* Labels according to the SmartQ manual */
+static struct gpio_keys_button smartq5_buttons[] = {
+ {
+ .gpio = S3C64XX_GPL(14),
+ .code = KEY_POWER,
+ .desc = "Power",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+ {
+ .gpio = S3C64XX_GPN(2),
+ .code = KEY_KPMINUS,
+ .desc = "Minus",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+ {
+ .gpio = S3C64XX_GPN(12),
+ .code = KEY_KPPLUS,
+ .desc = "Plus",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+ {
+ .gpio = S3C64XX_GPN(15),
+ .code = KEY_ENTER,
+ .desc = "Move",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+};
+
+static struct gpio_keys_platform_data smartq5_buttons_data = {
+ .buttons = smartq5_buttons,
+ .nbuttons = ARRAY_SIZE(smartq5_buttons),
+};
+
+static struct platform_device smartq5_buttons_device = {
+ .name = "gpio-keys",
+ .id = 0,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &smartq5_buttons_data,
+ }
+};
+
+static struct s3c_fb_pd_win smartq5_fb_win0 = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 800,
+ .yres = 480,
+};
+
+static struct fb_videomode smartq5_lcd_timing = {
+ .left_margin = 216,
+ .right_margin = 40,
+ .upper_margin = 35,
+ .lower_margin = 10,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ .refresh = 80,
+};
+
+static struct s3c_fb_platdata smartq5_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .vtiming = &smartq5_lcd_timing,
+ .win[0] = &smartq5_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC |
+ VIDCON1_INV_VDEN,
+};
+
+static struct platform_device *smartq5_devices[] __initdata = {
+ &smartq5_leds_device,
+ &smartq5_buttons_device,
+};
+
+static void __init smartq5_machine_init(void)
+{
+ s3c_fb_set_platdata(&smartq5_lcd_pdata);
+
+ smartq_machine_init();
+
+ platform_add_devices(smartq5_devices, ARRAY_SIZE(smartq5_devices));
+}
+
+MACHINE_START(SMARTQ5, "SmartQ 5")
+ /* Maintainer: Maurus Cuelenaere <mcuelenaere AT gmail DOT com> */
+ .atag_offset = 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = smartq_map_io,
+ .init_machine = smartq5_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-smartq7.c b/arch/arm/mach-s3c64xx/mach-smartq7.c
new file mode 100644
index 000000000..fc7fece22
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smartq7.c
@@ -0,0 +1,177 @@
+/*
+ * linux/arch/arm/mach-s3c64xx/mach-smartq7.c
+ *
+ * Copyright (C) 2010 Maurus Cuelenaere
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <video/samsung_fimd.h>
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "mach-smartq.h"
+
+static struct gpio_led smartq7_leds[] = {
+ {
+ .name = "smartq7:red",
+ .active_low = 1,
+ .gpio = S3C64XX_GPN(8),
+ },
+ {
+ .name = "smartq7:green",
+ .active_low = 1,
+ .gpio = S3C64XX_GPN(9),
+ },
+};
+
+static struct gpio_led_platform_data smartq7_led_data = {
+ .num_leds = ARRAY_SIZE(smartq7_leds),
+ .leds = smartq7_leds,
+};
+
+static struct platform_device smartq7_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev.platform_data = &smartq7_led_data,
+};
+
+/* Labels according to the SmartQ manual */
+static struct gpio_keys_button smartq7_buttons[] = {
+ {
+ .gpio = S3C64XX_GPL(14),
+ .code = KEY_POWER,
+ .desc = "Power",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+ {
+ .gpio = S3C64XX_GPN(2),
+ .code = KEY_FN,
+ .desc = "Function",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+ {
+ .gpio = S3C64XX_GPN(3),
+ .code = KEY_KPMINUS,
+ .desc = "Minus",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+ {
+ .gpio = S3C64XX_GPN(4),
+ .code = KEY_KPPLUS,
+ .desc = "Plus",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+ {
+ .gpio = S3C64XX_GPN(12),
+ .code = KEY_ENTER,
+ .desc = "Enter",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+ {
+ .gpio = S3C64XX_GPN(15),
+ .code = KEY_ESC,
+ .desc = "Cancel",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+};
+
+static struct gpio_keys_platform_data smartq7_buttons_data = {
+ .buttons = smartq7_buttons,
+ .nbuttons = ARRAY_SIZE(smartq7_buttons),
+};
+
+static struct platform_device smartq7_buttons_device = {
+ .name = "gpio-keys",
+ .id = 0,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &smartq7_buttons_data,
+ }
+};
+
+static struct s3c_fb_pd_win smartq7_fb_win0 = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 800,
+ .yres = 480,
+};
+
+static struct fb_videomode smartq7_lcd_timing = {
+ .left_margin = 3,
+ .right_margin = 5,
+ .upper_margin = 1,
+ .lower_margin = 20,
+ .hsync_len = 10,
+ .vsync_len = 3,
+ .xres = 800,
+ .yres = 480,
+ .refresh = 80,
+};
+
+static struct s3c_fb_platdata smartq7_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .vtiming = &smartq7_lcd_timing,
+ .win[0] = &smartq7_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC |
+ VIDCON1_INV_VCLK,
+};
+
+static struct platform_device *smartq7_devices[] __initdata = {
+ &smartq7_leds_device,
+ &smartq7_buttons_device,
+};
+
+static void __init smartq7_machine_init(void)
+{
+ s3c_fb_set_platdata(&smartq7_lcd_pdata);
+
+ smartq_machine_init();
+
+ platform_add_devices(smartq7_devices, ARRAY_SIZE(smartq7_devices));
+}
+
+MACHINE_START(SMARTQ7, "SmartQ 7")
+ /* Maintainer: Maurus Cuelenaere <mcuelenaere AT gmail DOT com> */
+ .atag_offset = 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = smartq_map_io,
+ .init_machine = smartq7_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6400.c b/arch/arm/mach-s3c64xx/mach-smdk6400.c
new file mode 100644
index 000000000..6f425126a
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smdk6400.c
@@ -0,0 +1,97 @@
+/* linux/arch/arm/mach-s3c64xx/mach-smdk6400.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#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/i2c.h>
+#include <linux/io.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/map.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <mach/gpio-samsung.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+
+#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 smdk6400_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+};
+
+static struct map_desc smdk6400_iodesc[] = {};
+
+static void __init smdk6400_map_io(void)
+{
+ s3c64xx_init_io(smdk6400_iodesc, ARRAY_SIZE(smdk6400_iodesc));
+ s3c64xx_set_xtal_freq(12000000);
+ s3c24xx_init_uarts(smdk6400_uartcfgs, ARRAY_SIZE(smdk6400_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+}
+
+static struct platform_device *smdk6400_devices[] __initdata = {
+ &s3c_device_hsmmc1,
+ &s3c_device_i2c0,
+};
+
+static struct i2c_board_info i2c_devs[] __initdata = {
+ { I2C_BOARD_INFO("wm8753", 0x1A), },
+ { I2C_BOARD_INFO("24c08", 0x50), },
+};
+
+static void __init smdk6400_machine_init(void)
+{
+ i2c_register_board_info(0, i2c_devs, ARRAY_SIZE(i2c_devs));
+ platform_add_devices(smdk6400_devices, ARRAY_SIZE(smdk6400_devices));
+}
+
+MACHINE_START(SMDK6400, "SMDK6400")
+ /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+ .atag_offset = 0x100,
+
+ .init_irq = s3c6400_init_irq,
+ .map_io = smdk6400_map_io,
+ .init_machine = smdk6400_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
new file mode 100644
index 000000000..b7447a922
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -0,0 +1,710 @@
+/* linux/arch/arm/mach-s3c64xx/mach-smdk6410.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#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/input.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/smsc911x.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/pwm_backlight.h>
+#include <linux/platform_data/s3c-hsotg.h>
+
+#ifdef CONFIG_SMDK6410_WM1190_EV1
+#include <linux/mfd/wm8350/core.h>
+#include <linux/mfd/wm8350/pmic.h>
+#endif
+
+#ifdef CONFIG_SMDK6410_WM1192_EV1
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/pdata.h>
+#endif
+
+#include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/gpio-samsung.h>
+#include <linux/platform_data/ata-samsung_cf.h>
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/adc.h>
+#include <linux/platform_data/touchscreen-s3c2410.h>
+#include <plat/keypad.h>
+#include <plat/backlight.h>
+#include <plat/samsung-time.h>
+
+#include "common.h"
+#include "regs-modem.h"
+#include "regs-srom.h"
+#include "regs-sys.h"
+
+#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 smdk6410_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,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+};
+
+/* framebuffer and LCD setup. */
+
+/* GPF15 = LCD backlight control
+ * GPF13 => Panel power
+ * GPN5 = LCD nRESET signal
+ * PWM_TOUT1 => backlight brightness
+ */
+
+static void smdk6410_lcd_power_set(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+ gpio_direction_output(S3C64XX_GPF(13), 1);
+
+ /* fire nRESET on power up */
+ gpio_direction_output(S3C64XX_GPN(5), 0);
+ msleep(10);
+ gpio_direction_output(S3C64XX_GPN(5), 1);
+ msleep(1);
+ } else {
+ gpio_direction_output(S3C64XX_GPF(13), 0);
+ }
+}
+
+static struct plat_lcd_data smdk6410_lcd_power_data = {
+ .set_power = smdk6410_lcd_power_set,
+};
+
+static struct platform_device smdk6410_lcd_powerdev = {
+ .name = "platform-lcd",
+ .dev.parent = &s3c_device_fb.dev,
+ .dev.platform_data = &smdk6410_lcd_power_data,
+};
+
+static struct s3c_fb_pd_win smdk6410_fb_win0 = {
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .xres = 800,
+ .yres = 480,
+ .virtual_y = 480 * 2,
+ .virtual_x = 800,
+};
+
+static struct fb_videomode smdk6410_lcd_timing = {
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+};
+
+/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
+static struct s3c_fb_platdata smdk6410_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .vtiming = &smdk6410_lcd_timing,
+ .win[0] = &smdk6410_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+/*
+ * Configuring Ethernet on SMDK6410
+ *
+ * Both CS8900A and LAN9115 chips share one chip select mediated by CFG6.
+ * The constant address below corresponds to nCS1
+ *
+ * 1) Set CFGB2 p3 ON others off, no other CFGB selects "ethernet"
+ * 2) CFG6 needs to be switched to "LAN9115" side
+ */
+
+static struct resource smdk6410_smsc911x_resources[] = {
+ [0] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN1, SZ_64K),
+ [1] = DEFINE_RES_NAMED(S3C_EINT(10), 1, NULL, IORESOURCE_IRQ \
+ | IRQ_TYPE_LEVEL_LOW),
+};
+
+static struct smsc911x_platform_config smdk6410_smsc911x_pdata = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+
+static struct platform_device smdk6410_smsc911x = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smdk6410_smsc911x_resources),
+ .resource = &smdk6410_smsc911x_resources[0],
+ .dev = {
+ .platform_data = &smdk6410_smsc911x_pdata,
+ },
+};
+
+#ifdef CONFIG_REGULATOR
+static struct regulator_consumer_supply smdk6410_b_pwr_5v_consumers[] = {
+ REGULATOR_SUPPLY("PVDD", "0-001b"),
+ REGULATOR_SUPPLY("AVDD", "0-001b"),
+};
+
+static struct regulator_init_data smdk6410_b_pwr_5v_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(smdk6410_b_pwr_5v_consumers),
+ .consumer_supplies = smdk6410_b_pwr_5v_consumers,
+};
+
+static struct fixed_voltage_config smdk6410_b_pwr_5v_pdata = {
+ .supply_name = "B_PWR_5V",
+ .microvolts = 5000000,
+ .init_data = &smdk6410_b_pwr_5v_data,
+ .gpio = -EINVAL,
+};
+
+static struct platform_device smdk6410_b_pwr_5v = {
+ .name = "reg-fixed-voltage",
+ .id = -1,
+ .dev = {
+ .platform_data = &smdk6410_b_pwr_5v_pdata,
+ },
+};
+#endif
+
+static struct s3c_ide_platdata smdk6410_ide_pdata __initdata = {
+ .setup_gpio = s3c64xx_ide_setup_gpio,
+};
+
+static uint32_t smdk6410_keymap[] __initdata = {
+ /* KEY(row, col, keycode) */
+ KEY(0, 3, KEY_1), KEY(0, 4, KEY_2), KEY(0, 5, KEY_3),
+ KEY(0, 6, KEY_4), KEY(0, 7, KEY_5),
+ KEY(1, 3, KEY_A), KEY(1, 4, KEY_B), KEY(1, 5, KEY_C),
+ KEY(1, 6, KEY_D), KEY(1, 7, KEY_E)
+};
+
+static struct matrix_keymap_data smdk6410_keymap_data __initdata = {
+ .keymap = smdk6410_keymap,
+ .keymap_size = ARRAY_SIZE(smdk6410_keymap),
+};
+
+static struct samsung_keypad_platdata smdk6410_keypad_data __initdata = {
+ .keymap_data = &smdk6410_keymap_data,
+ .rows = 2,
+ .cols = 8,
+};
+
+static struct map_desc smdk6410_iodesc[] = {};
+
+static struct platform_device *smdk6410_devices[] __initdata = {
+#ifdef CONFIG_SMDK6410_SD_CH0
+ &s3c_device_hsmmc0,
+#endif
+#ifdef CONFIG_SMDK6410_SD_CH1
+ &s3c_device_hsmmc1,
+#endif
+ &s3c_device_i2c0,
+ &s3c_device_i2c1,
+ &s3c_device_fb,
+ &s3c_device_ohci,
+ &samsung_device_pwm,
+ &s3c_device_usb_hsotg,
+ &s3c64xx_device_iisv4,
+ &samsung_device_keypad,
+
+#ifdef CONFIG_REGULATOR
+ &smdk6410_b_pwr_5v,
+#endif
+ &smdk6410_lcd_powerdev,
+
+ &smdk6410_smsc911x,
+ &s3c_device_adc,
+ &s3c_device_cfcon,
+ &s3c_device_rtc,
+ &s3c_device_ts,
+ &s3c_device_wdt,
+};
+
+#ifdef CONFIG_REGULATOR
+/* ARM core */
+static struct regulator_consumer_supply smdk6410_vddarm_consumers[] = {
+ REGULATOR_SUPPLY("vddarm", NULL),
+};
+
+/* VDDARM, BUCK1 on J5 */
+static struct regulator_init_data smdk6410_vddarm = {
+ .constraints = {
+ .name = "PVDD_ARM",
+ .min_uV = 1000000,
+ .max_uV = 1300000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(smdk6410_vddarm_consumers),
+ .consumer_supplies = smdk6410_vddarm_consumers,
+};
+
+/* VDD_INT, BUCK2 on J5 */
+static struct regulator_init_data smdk6410_vddint = {
+ .constraints = {
+ .name = "PVDD_INT",
+ .min_uV = 1000000,
+ .max_uV = 1200000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+};
+
+/* VDD_HI, LDO3 on J5 */
+static struct regulator_init_data smdk6410_vddhi = {
+ .constraints = {
+ .name = "PVDD_HI",
+ .always_on = 1,
+ },
+};
+
+/* VDD_PLL, LDO2 on J5 */
+static struct regulator_init_data smdk6410_vddpll = {
+ .constraints = {
+ .name = "PVDD_PLL",
+ .always_on = 1,
+ },
+};
+
+/* VDD_UH_MMC, LDO5 on J5 */
+static struct regulator_init_data smdk6410_vdduh_mmc = {
+ .constraints = {
+ .name = "PVDD_UH+PVDD_MMC",
+ .always_on = 1,
+ },
+};
+
+/* VCCM3BT, LDO8 on J5 */
+static struct regulator_init_data smdk6410_vccmc3bt = {
+ .constraints = {
+ .name = "PVCCM3BT",
+ .always_on = 1,
+ },
+};
+
+/* VCCM2MTV, LDO11 on J5 */
+static struct regulator_init_data smdk6410_vccm2mtv = {
+ .constraints = {
+ .name = "PVCCM2MTV",
+ .always_on = 1,
+ },
+};
+
+/* VDD_LCD, LDO12 on J5 */
+static struct regulator_init_data smdk6410_vddlcd = {
+ .constraints = {
+ .name = "PVDD_LCD",
+ .always_on = 1,
+ },
+};
+
+/* VDD_OTGI, LDO9 on J5 */
+static struct regulator_init_data smdk6410_vddotgi = {
+ .constraints = {
+ .name = "PVDD_OTGI",
+ .always_on = 1,
+ },
+};
+
+/* VDD_OTG, LDO14 on J5 */
+static struct regulator_init_data smdk6410_vddotg = {
+ .constraints = {
+ .name = "PVDD_OTG",
+ .always_on = 1,
+ },
+};
+
+/* VDD_ALIVE, LDO15 on J5 */
+static struct regulator_init_data smdk6410_vddalive = {
+ .constraints = {
+ .name = "PVDD_ALIVE",
+ .always_on = 1,
+ },
+};
+
+/* VDD_AUDIO, VLDO_AUDIO on J5 */
+static struct regulator_init_data smdk6410_vddaudio = {
+ .constraints = {
+ .name = "PVDD_AUDIO",
+ .always_on = 1,
+ },
+};
+#endif
+
+#ifdef CONFIG_SMDK6410_WM1190_EV1
+/* S3C64xx internal logic & PLL */
+static struct regulator_init_data wm8350_dcdc1_data = {
+ .constraints = {
+ .name = "PVDD_INT+PVDD_PLL",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .always_on = 1,
+ .apply_uV = 1,
+ },
+};
+
+/* Memory */
+static struct regulator_init_data wm8350_dcdc3_data = {
+ .constraints = {
+ .name = "PVDD_MEM",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .always_on = 1,
+ .state_mem = {
+ .uV = 1800000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ .initial_state = PM_SUSPEND_MEM,
+ },
+};
+
+/* USB, EXT, PCM, ADC/DAC, USB, MMC */
+static struct regulator_consumer_supply wm8350_dcdc4_consumers[] = {
+ REGULATOR_SUPPLY("DVDD", "0-001b"),
+};
+
+static struct regulator_init_data wm8350_dcdc4_data = {
+ .constraints = {
+ .name = "PVDD_HI+PVDD_EXT+PVDD_SYS+PVCCM2MTV",
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wm8350_dcdc4_consumers),
+ .consumer_supplies = wm8350_dcdc4_consumers,
+};
+
+/* OTGi/1190-EV1 HPVDD & AVDD */
+static struct regulator_init_data wm8350_ldo4_data = {
+ .constraints = {
+ .name = "PVDD_OTGI+HPVDD+AVDD",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct {
+ int regulator;
+ struct regulator_init_data *initdata;
+} wm1190_regulators[] = {
+ { WM8350_DCDC_1, &wm8350_dcdc1_data },
+ { WM8350_DCDC_3, &wm8350_dcdc3_data },
+ { WM8350_DCDC_4, &wm8350_dcdc4_data },
+ { WM8350_DCDC_6, &smdk6410_vddarm },
+ { WM8350_LDO_1, &smdk6410_vddalive },
+ { WM8350_LDO_2, &smdk6410_vddotg },
+ { WM8350_LDO_3, &smdk6410_vddlcd },
+ { WM8350_LDO_4, &wm8350_ldo4_data },
+};
+
+static int __init smdk6410_wm8350_init(struct wm8350 *wm8350)
+{
+ int i;
+
+ /* Configure the IRQ line */
+ s3c_gpio_setpull(S3C64XX_GPN(12), S3C_GPIO_PULL_UP);
+
+ /* Instantiate the regulators */
+ for (i = 0; i < ARRAY_SIZE(wm1190_regulators); i++)
+ wm8350_register_regulator(wm8350,
+ wm1190_regulators[i].regulator,
+ wm1190_regulators[i].initdata);
+
+ return 0;
+}
+
+static struct wm8350_platform_data __initdata smdk6410_wm8350_pdata = {
+ .init = smdk6410_wm8350_init,
+ .irq_high = 1,
+ .irq_base = IRQ_BOARD_START,
+};
+#endif
+
+#ifdef CONFIG_SMDK6410_WM1192_EV1
+static struct gpio_led wm1192_pmic_leds[] = {
+ {
+ .name = "PMIC:red:power",
+ .gpio = GPIO_BOARD_START + 3,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+};
+
+static struct gpio_led_platform_data wm1192_pmic_led = {
+ .num_leds = ARRAY_SIZE(wm1192_pmic_leds),
+ .leds = wm1192_pmic_leds,
+};
+
+static struct platform_device wm1192_pmic_led_dev = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &wm1192_pmic_led,
+ },
+};
+
+static int wm1192_pre_init(struct wm831x *wm831x)
+{
+ int ret;
+
+ /* Configure the IRQ line */
+ s3c_gpio_setpull(S3C64XX_GPN(12), S3C_GPIO_PULL_UP);
+
+ ret = platform_device_register(&wm1192_pmic_led_dev);
+ if (ret != 0)
+ dev_err(wm831x->dev, "Failed to add PMIC LED: %d\n", ret);
+
+ return 0;
+}
+
+static struct wm831x_backlight_pdata wm1192_backlight_pdata = {
+ .isink = 1,
+ .max_uA = 27554,
+};
+
+static struct regulator_init_data wm1192_dcdc3 = {
+ .constraints = {
+ .name = "PVDD_MEM+PVDD_GPS",
+ .always_on = 1,
+ },
+};
+
+static struct regulator_consumer_supply wm1192_ldo1_consumers[] = {
+ REGULATOR_SUPPLY("DVDD", "0-001b"), /* WM8580 */
+};
+
+static struct regulator_init_data wm1192_ldo1 = {
+ .constraints = {
+ .name = "PVDD_LCD+PVDD_EXT",
+ .always_on = 1,
+ },
+ .consumer_supplies = wm1192_ldo1_consumers,
+ .num_consumer_supplies = ARRAY_SIZE(wm1192_ldo1_consumers),
+};
+
+static struct wm831x_status_pdata wm1192_led7_pdata = {
+ .name = "LED7:green:",
+};
+
+static struct wm831x_status_pdata wm1192_led8_pdata = {
+ .name = "LED8:green:",
+};
+
+static struct wm831x_pdata smdk6410_wm1192_pdata = {
+ .pre_init = wm1192_pre_init,
+
+ .backlight = &wm1192_backlight_pdata,
+ .dcdc = {
+ &smdk6410_vddarm, /* DCDC1 */
+ &smdk6410_vddint, /* DCDC2 */
+ &wm1192_dcdc3,
+ },
+ .gpio_base = GPIO_BOARD_START,
+ .ldo = {
+ &wm1192_ldo1, /* LDO1 */
+ &smdk6410_vdduh_mmc, /* LDO2 */
+ NULL, /* LDO3 NC */
+ &smdk6410_vddotgi, /* LDO4 */
+ &smdk6410_vddotg, /* LDO5 */
+ &smdk6410_vddhi, /* LDO6 */
+ &smdk6410_vddaudio, /* LDO7 */
+ &smdk6410_vccm2mtv, /* LDO8 */
+ &smdk6410_vddpll, /* LDO9 */
+ &smdk6410_vccmc3bt, /* LDO10 */
+ &smdk6410_vddalive, /* LDO11 */
+ },
+ .status = {
+ &wm1192_led7_pdata,
+ &wm1192_led8_pdata,
+ },
+};
+#endif
+
+static struct i2c_board_info i2c_devs0[] __initdata = {
+ { I2C_BOARD_INFO("24c08", 0x50), },
+ { I2C_BOARD_INFO("wm8580", 0x1b), },
+
+#ifdef CONFIG_SMDK6410_WM1192_EV1
+ { I2C_BOARD_INFO("wm8312", 0x34),
+ .platform_data = &smdk6410_wm1192_pdata,
+ .irq = S3C_EINT(12),
+ },
+#endif
+
+#ifdef CONFIG_SMDK6410_WM1190_EV1
+ { I2C_BOARD_INFO("wm8350", 0x1a),
+ .platform_data = &smdk6410_wm8350_pdata,
+ .irq = S3C_EINT(12),
+ },
+#endif
+};
+
+static struct i2c_board_info i2c_devs1[] __initdata = {
+ { I2C_BOARD_INFO("24c128", 0x57), }, /* Samsung S524AD0XD1 */
+};
+
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdk6410_bl_gpio_info = {
+ .no = S3C64XX_GPF(15),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdk6410_bl_data = {
+ .pwm_id = 1,
+ .enable_gpio = -1,
+};
+
+static struct s3c_hsotg_plat smdk6410_hsotg_pdata;
+
+static void __init smdk6410_map_io(void)
+{
+ u32 tmp;
+
+ s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc));
+ s3c64xx_set_xtal_freq(12000000);
+ s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs));
+ samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
+
+ /* set the LCD type */
+
+ tmp = __raw_readl(S3C64XX_SPCON);
+ tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
+ tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
+ __raw_writel(tmp, S3C64XX_SPCON);
+
+ /* remove the lcd bypass */
+ tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
+ tmp &= ~MIFPCON_LCD_BYPASS;
+ __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
+}
+
+static void __init smdk6410_machine_init(void)
+{
+ u32 cs1;
+
+ s3c_i2c0_set_platdata(NULL);
+ s3c_i2c1_set_platdata(NULL);
+ s3c_fb_set_platdata(&smdk6410_lcd_pdata);
+ s3c_hsotg_set_platdata(&smdk6410_hsotg_pdata);
+
+ samsung_keypad_set_platdata(&smdk6410_keypad_data);
+
+ s3c24xx_ts_set_platdata(NULL);
+
+ /* configure nCS1 width to 16 bits */
+
+ cs1 = __raw_readl(S3C64XX_SROM_BW) &
+ ~(S3C64XX_SROM_BW__CS_MASK << S3C64XX_SROM_BW__NCS1__SHIFT);
+ cs1 |= ((1 << S3C64XX_SROM_BW__DATAWIDTH__SHIFT) |
+ (1 << S3C64XX_SROM_BW__WAITENABLE__SHIFT) |
+ (1 << S3C64XX_SROM_BW__BYTEENABLE__SHIFT)) <<
+ S3C64XX_SROM_BW__NCS1__SHIFT;
+ __raw_writel(cs1, S3C64XX_SROM_BW);
+
+ /* set timing for nCS1 suitable for ethernet chip */
+
+ __raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) |
+ (6 << S3C64XX_SROM_BCX__TACP__SHIFT) |
+ (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) |
+ (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) |
+ (0xe << S3C64XX_SROM_BCX__TACC__SHIFT) |
+ (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
+ (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);
+
+ gpio_request(S3C64XX_GPN(5), "LCD power");
+ gpio_request(S3C64XX_GPF(13), "LCD power");
+
+ i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+
+ s3c_ide_set_platdata(&smdk6410_ide_pdata);
+
+ platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
+
+ samsung_bl_set(&smdk6410_bl_gpio_info, &smdk6410_bl_data);
+}
+
+MACHINE_START(SMDK6410, "SMDK6410")
+ /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+ .atag_offset = 0x100,
+
+ .init_irq = s3c6410_init_irq,
+ .map_io = smdk6410_map_io,
+ .init_machine = smdk6410_machine_init,
+ .init_time = samsung_timer_init,
+ .restart = s3c64xx_restart,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/pl080.c b/arch/arm/mach-s3c64xx/pl080.c
new file mode 100644
index 000000000..901a984bd
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/pl080.c
@@ -0,0 +1,244 @@
+/*
+ * Samsung's S3C64XX generic DMA support using amba-pl08x driver.
+ *
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/pl080.h>
+#include <linux/amba/pl08x.h>
+#include <linux/of.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include "regs-sys.h"
+
+static int pl08x_get_xfer_signal(const struct pl08x_channel_data *cd)
+{
+ return cd->min_signal;
+}
+
+static void pl08x_put_xfer_signal(const struct pl08x_channel_data *cd, int ch)
+{
+}
+
+/*
+ * DMA0
+ */
+
+static struct pl08x_channel_data s3c64xx_dma0_info[] = {
+ {
+ .bus_id = "uart0_tx",
+ .min_signal = 0,
+ .max_signal = 0,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "uart0_rx",
+ .min_signal = 1,
+ .max_signal = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "uart1_tx",
+ .min_signal = 2,
+ .max_signal = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "uart1_rx",
+ .min_signal = 3,
+ .max_signal = 3,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "uart2_tx",
+ .min_signal = 4,
+ .max_signal = 4,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "uart2_rx",
+ .min_signal = 5,
+ .max_signal = 5,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "uart3_tx",
+ .min_signal = 6,
+ .max_signal = 6,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "uart3_rx",
+ .min_signal = 7,
+ .max_signal = 7,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "pcm0_tx",
+ .min_signal = 8,
+ .max_signal = 8,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "pcm0_rx",
+ .min_signal = 9,
+ .max_signal = 9,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "i2s0_tx",
+ .min_signal = 10,
+ .max_signal = 10,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "i2s0_rx",
+ .min_signal = 11,
+ .max_signal = 11,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "spi0_tx",
+ .min_signal = 12,
+ .max_signal = 12,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "spi0_rx",
+ .min_signal = 13,
+ .max_signal = 13,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "i2s2_tx",
+ .min_signal = 14,
+ .max_signal = 14,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "i2s2_rx",
+ .min_signal = 15,
+ .max_signal = 15,
+ .periph_buses = PL08X_AHB2,
+ }
+};
+
+struct pl08x_platform_data s3c64xx_dma0_plat_data = {
+ .memcpy_channel = {
+ .bus_id = "memcpy",
+ .cctl_memcpy =
+ (PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT |
+ PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT |
+ PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT |
+ PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT |
+ PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE |
+ PL080_CONTROL_PROT_SYS),
+ },
+ .lli_buses = PL08X_AHB1,
+ .mem_buses = PL08X_AHB1,
+ .get_xfer_signal = pl08x_get_xfer_signal,
+ .put_xfer_signal = pl08x_put_xfer_signal,
+ .slave_channels = s3c64xx_dma0_info,
+ .num_slave_channels = ARRAY_SIZE(s3c64xx_dma0_info),
+};
+
+static AMBA_AHB_DEVICE(s3c64xx_dma0, "dma-pl080s.0", 0,
+ 0x75000000, {IRQ_DMA0}, &s3c64xx_dma0_plat_data);
+
+/*
+ * DMA1
+ */
+
+static struct pl08x_channel_data s3c64xx_dma1_info[] = {
+ {
+ .bus_id = "pcm1_tx",
+ .min_signal = 0,
+ .max_signal = 0,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "pcm1_rx",
+ .min_signal = 1,
+ .max_signal = 1,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "i2s1_tx",
+ .min_signal = 2,
+ .max_signal = 2,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "i2s1_rx",
+ .min_signal = 3,
+ .max_signal = 3,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "spi1_tx",
+ .min_signal = 4,
+ .max_signal = 4,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "spi1_rx",
+ .min_signal = 5,
+ .max_signal = 5,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ac97_out",
+ .min_signal = 6,
+ .max_signal = 6,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ac97_in",
+ .min_signal = 7,
+ .max_signal = 7,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "ac97_mic",
+ .min_signal = 8,
+ .max_signal = 8,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "pwm",
+ .min_signal = 9,
+ .max_signal = 9,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "irda",
+ .min_signal = 10,
+ .max_signal = 10,
+ .periph_buses = PL08X_AHB2,
+ }, {
+ .bus_id = "external",
+ .min_signal = 11,
+ .max_signal = 11,
+ .periph_buses = PL08X_AHB2,
+ },
+};
+
+struct pl08x_platform_data s3c64xx_dma1_plat_data = {
+ .memcpy_channel = {
+ .bus_id = "memcpy",
+ .cctl_memcpy =
+ (PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT |
+ PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT |
+ PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT |
+ PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT |
+ PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE |
+ PL080_CONTROL_PROT_SYS),
+ },
+ .lli_buses = PL08X_AHB1,
+ .mem_buses = PL08X_AHB1,
+ .get_xfer_signal = pl08x_get_xfer_signal,
+ .put_xfer_signal = pl08x_put_xfer_signal,
+ .slave_channels = s3c64xx_dma1_info,
+ .num_slave_channels = ARRAY_SIZE(s3c64xx_dma1_info),
+};
+
+static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0,
+ 0x75100000, {IRQ_DMA1}, &s3c64xx_dma1_plat_data);
+
+static int __init s3c64xx_pl080_init(void)
+{
+ /* Set all DMA configuration to be DMA, not SDMA */
+ writel(0xffffff, S3C64XX_SDMA_SEL);
+
+ if (of_have_populated_dt())
+ return 0;
+
+ amba_device_register(&s3c64xx_dma0_device, &iomem_resource);
+ amba_device_register(&s3c64xx_dma1_device, &iomem_resource);
+
+ return 0;
+}
+arch_initcall(s3c64xx_pl080_init);
diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
new file mode 100644
index 000000000..75b14e756
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -0,0 +1,351 @@
+/* linux/arch/arm/plat-s3c64xx/pm.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX CPU PM support.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/pm_domain.h>
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+
+#include <plat/devs.h>
+#include <plat/pm.h>
+#include <plat/wakeup-mask.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+#include <mach/gpio-samsung.h>
+
+#include "regs-gpio-memport.h"
+#include "regs-modem.h"
+#include "regs-sys.h"
+#include "regs-syscon-power.h"
+
+struct s3c64xx_pm_domain {
+ char *const name;
+ u32 ena;
+ u32 pwr_stat;
+ struct generic_pm_domain pd;
+};
+
+static int s3c64xx_pd_off(struct generic_pm_domain *domain)
+{
+ struct s3c64xx_pm_domain *pd;
+ u32 val;
+
+ pd = container_of(domain, struct s3c64xx_pm_domain, pd);
+
+ val = __raw_readl(S3C64XX_NORMAL_CFG);
+ val &= ~(pd->ena);
+ __raw_writel(val, S3C64XX_NORMAL_CFG);
+
+ return 0;
+}
+
+static int s3c64xx_pd_on(struct generic_pm_domain *domain)
+{
+ struct s3c64xx_pm_domain *pd;
+ u32 val;
+ long retry = 1000000L;
+
+ pd = container_of(domain, struct s3c64xx_pm_domain, pd);
+
+ val = __raw_readl(S3C64XX_NORMAL_CFG);
+ val |= pd->ena;
+ __raw_writel(val, S3C64XX_NORMAL_CFG);
+
+ /* Not all domains provide power status readback */
+ if (pd->pwr_stat) {
+ do {
+ cpu_relax();
+ if (__raw_readl(S3C64XX_BLK_PWR_STAT) & pd->pwr_stat)
+ break;
+ } while (retry--);
+
+ if (!retry) {
+ pr_err("Failed to start domain %s\n", pd->name);
+ return -EBUSY;
+ }
+ }
+
+ return 0;
+}
+
+static struct s3c64xx_pm_domain s3c64xx_pm_irom = {
+ .name = "IROM",
+ .ena = S3C64XX_NORMALCFG_IROM_ON,
+ .pd = {
+ .power_off = s3c64xx_pd_off,
+ .power_on = s3c64xx_pd_on,
+ },
+};
+
+static struct s3c64xx_pm_domain s3c64xx_pm_etm = {
+ .name = "ETM",
+ .ena = S3C64XX_NORMALCFG_DOMAIN_ETM_ON,
+ .pwr_stat = S3C64XX_BLKPWRSTAT_ETM,
+ .pd = {
+ .power_off = s3c64xx_pd_off,
+ .power_on = s3c64xx_pd_on,
+ },
+};
+
+static struct s3c64xx_pm_domain s3c64xx_pm_s = {
+ .name = "S",
+ .ena = S3C64XX_NORMALCFG_DOMAIN_S_ON,
+ .pwr_stat = S3C64XX_BLKPWRSTAT_S,
+ .pd = {
+ .power_off = s3c64xx_pd_off,
+ .power_on = s3c64xx_pd_on,
+ },
+};
+
+static struct s3c64xx_pm_domain s3c64xx_pm_f = {
+ .name = "F",
+ .ena = S3C64XX_NORMALCFG_DOMAIN_F_ON,
+ .pwr_stat = S3C64XX_BLKPWRSTAT_F,
+ .pd = {
+ .power_off = s3c64xx_pd_off,
+ .power_on = s3c64xx_pd_on,
+ },
+};
+
+static struct s3c64xx_pm_domain s3c64xx_pm_p = {
+ .name = "P",
+ .ena = S3C64XX_NORMALCFG_DOMAIN_P_ON,
+ .pwr_stat = S3C64XX_BLKPWRSTAT_P,
+ .pd = {
+ .power_off = s3c64xx_pd_off,
+ .power_on = s3c64xx_pd_on,
+ },
+};
+
+static struct s3c64xx_pm_domain s3c64xx_pm_i = {
+ .name = "I",
+ .ena = S3C64XX_NORMALCFG_DOMAIN_I_ON,
+ .pwr_stat = S3C64XX_BLKPWRSTAT_I,
+ .pd = {
+ .power_off = s3c64xx_pd_off,
+ .power_on = s3c64xx_pd_on,
+ },
+};
+
+static struct s3c64xx_pm_domain s3c64xx_pm_g = {
+ .name = "G",
+ .ena = S3C64XX_NORMALCFG_DOMAIN_G_ON,
+ .pd = {
+ .power_off = s3c64xx_pd_off,
+ .power_on = s3c64xx_pd_on,
+ },
+};
+
+static struct s3c64xx_pm_domain s3c64xx_pm_v = {
+ .name = "V",
+ .ena = S3C64XX_NORMALCFG_DOMAIN_V_ON,
+ .pwr_stat = S3C64XX_BLKPWRSTAT_V,
+ .pd = {
+ .power_off = s3c64xx_pd_off,
+ .power_on = s3c64xx_pd_on,
+ },
+};
+
+static struct s3c64xx_pm_domain *s3c64xx_always_on_pm_domains[] = {
+ &s3c64xx_pm_irom,
+};
+
+static struct s3c64xx_pm_domain *s3c64xx_pm_domains[] = {
+ &s3c64xx_pm_etm,
+ &s3c64xx_pm_g,
+ &s3c64xx_pm_v,
+ &s3c64xx_pm_i,
+ &s3c64xx_pm_p,
+ &s3c64xx_pm_s,
+ &s3c64xx_pm_f,
+};
+
+#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+void s3c_pm_debug_smdkled(u32 set, u32 clear)
+{
+ unsigned long flags;
+ int i;
+
+ local_irq_save(flags);
+ for (i = 0; i < 4; i++) {
+ if (clear & (1 << i))
+ gpio_set_value(S3C64XX_GPN(12 + i), 0);
+ if (set & (1 << i))
+ gpio_set_value(S3C64XX_GPN(12 + i), 1);
+ }
+ local_irq_restore(flags);
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static struct sleep_save core_save[] = {
+ SAVE_ITEM(S3C64XX_MEM0DRVCON),
+ SAVE_ITEM(S3C64XX_MEM1DRVCON),
+};
+
+static struct sleep_save misc_save[] = {
+ SAVE_ITEM(S3C64XX_AHB_CON0),
+ SAVE_ITEM(S3C64XX_AHB_CON1),
+ SAVE_ITEM(S3C64XX_AHB_CON2),
+
+ SAVE_ITEM(S3C64XX_SPCON),
+
+ SAVE_ITEM(S3C64XX_MEM0CONSTOP),
+ SAVE_ITEM(S3C64XX_MEM1CONSTOP),
+ SAVE_ITEM(S3C64XX_MEM0CONSLP0),
+ SAVE_ITEM(S3C64XX_MEM0CONSLP1),
+ SAVE_ITEM(S3C64XX_MEM1CONSLP),
+
+ SAVE_ITEM(S3C64XX_SDMA_SEL),
+ SAVE_ITEM(S3C64XX_MODEM_MIFPCON),
+
+ SAVE_ITEM(S3C64XX_NORMAL_CFG),
+};
+
+void s3c_pm_configure_extint(void)
+{
+ __raw_writel(s3c_irqwake_eintmask, S3C64XX_EINT_MASK);
+}
+
+void s3c_pm_restore_core(void)
+{
+ __raw_writel(0, S3C64XX_EINT_MASK);
+
+ s3c_pm_debug_smdkled(1 << 2, 0);
+
+ s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
+ s3c_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
+}
+
+void s3c_pm_save_core(void)
+{
+ s3c_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
+ s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
+}
+#endif
+
+/* since both s3c6400 and s3c6410 share the same sleep pm calls, we
+ * put the per-cpu code in here until any new cpu comes along and changes
+ * this.
+ */
+
+static int s3c64xx_cpu_suspend(unsigned long arg)
+{
+ unsigned long tmp;
+
+ /* set our standby method to sleep */
+
+ tmp = __raw_readl(S3C64XX_PWR_CFG);
+ tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
+ tmp |= S3C64XX_PWRCFG_CFG_WFI_SLEEP;
+ __raw_writel(tmp, S3C64XX_PWR_CFG);
+
+ /* clear any old wakeup */
+
+ __raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT),
+ S3C64XX_WAKEUP_STAT);
+
+ /* set the LED state to 0110 over sleep */
+ s3c_pm_debug_smdkled(3 << 1, 0xf);
+
+ /* issue the standby signal into the pm unit. Note, we
+ * issue a write-buffer drain just in case */
+
+ tmp = 0;
+
+ asm("b 1f\n\t"
+ ".align 5\n\t"
+ "1:\n\t"
+ "mcr p15, 0, %0, c7, c10, 5\n\t"
+ "mcr p15, 0, %0, c7, c10, 4\n\t"
+ "mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp));
+
+ /* we should never get past here */
+
+ pr_info("Failed to suspend the system\n");
+ return 1; /* Aborting suspend */
+}
+
+/* mapping of interrupts to parts of the wakeup mask */
+static struct samsung_wakeup_mask wake_irqs[] = {
+ { .irq = IRQ_RTC_ALARM, .bit = S3C64XX_PWRCFG_RTC_ALARM_DISABLE, },
+ { .irq = IRQ_RTC_TIC, .bit = S3C64XX_PWRCFG_RTC_TICK_DISABLE, },
+ { .irq = IRQ_PENDN, .bit = S3C64XX_PWRCFG_TS_DISABLE, },
+ { .irq = IRQ_HSMMC0, .bit = S3C64XX_PWRCFG_MMC0_DISABLE, },
+ { .irq = IRQ_HSMMC1, .bit = S3C64XX_PWRCFG_MMC1_DISABLE, },
+ { .irq = IRQ_HSMMC2, .bit = S3C64XX_PWRCFG_MMC2_DISABLE, },
+ { .irq = NO_WAKEUP_IRQ, .bit = S3C64XX_PWRCFG_BATF_DISABLE},
+ { .irq = NO_WAKEUP_IRQ, .bit = S3C64XX_PWRCFG_MSM_DISABLE },
+ { .irq = NO_WAKEUP_IRQ, .bit = S3C64XX_PWRCFG_HSI_DISABLE },
+ { .irq = NO_WAKEUP_IRQ, .bit = S3C64XX_PWRCFG_MSM_DISABLE },
+};
+
+static void s3c64xx_pm_prepare(void)
+{
+ samsung_sync_wakemask(S3C64XX_PWR_CFG,
+ wake_irqs, ARRAY_SIZE(wake_irqs));
+
+ /* store address of resume. */
+ __raw_writel(virt_to_phys(s3c_cpu_resume), S3C64XX_INFORM0);
+
+ /* ensure previous wakeup state is cleared before sleeping */
+ __raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT), S3C64XX_WAKEUP_STAT);
+}
+
+int __init s3c64xx_pm_init(void)
+{
+ int i;
+
+ s3c_pm_init();
+
+ for (i = 0; i < ARRAY_SIZE(s3c64xx_always_on_pm_domains); i++)
+ pm_genpd_init(&s3c64xx_always_on_pm_domains[i]->pd,
+ &pm_domain_always_on_gov, false);
+
+ for (i = 0; i < ARRAY_SIZE(s3c64xx_pm_domains); i++)
+ pm_genpd_init(&s3c64xx_pm_domains[i]->pd, NULL, false);
+
+#ifdef CONFIG_S3C_DEV_FB
+ if (dev_get_platdata(&s3c_device_fb.dev))
+ pm_genpd_add_device(&s3c64xx_pm_f.pd, &s3c_device_fb.dev);
+#endif
+
+ return 0;
+}
+
+static __init int s3c64xx_pm_initcall(void)
+{
+ pm_cpu_prep = s3c64xx_pm_prepare;
+ pm_cpu_sleep = s3c64xx_cpu_suspend;
+
+#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+ gpio_request(S3C64XX_GPN(12), "DEBUG_LED0");
+ gpio_request(S3C64XX_GPN(13), "DEBUG_LED1");
+ gpio_request(S3C64XX_GPN(14), "DEBUG_LED2");
+ gpio_request(S3C64XX_GPN(15), "DEBUG_LED3");
+ gpio_direction_output(S3C64XX_GPN(12), 0);
+ gpio_direction_output(S3C64XX_GPN(13), 0);
+ gpio_direction_output(S3C64XX_GPN(14), 0);
+ gpio_direction_output(S3C64XX_GPN(15), 0);
+#endif
+
+ return 0;
+}
+arch_initcall(s3c64xx_pm_initcall);
diff --git a/arch/arm/mach-s3c64xx/regs-gpio-memport.h b/arch/arm/mach-s3c64xx/regs-gpio-memport.h
new file mode 100644
index 000000000..b92759301
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/regs-gpio-memport.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - GPIO memory port register definitions
+ */
+
+#ifndef __MACH_S3C64XX_REGS_GPIO_MEMPORT_H
+#define __MACH_S3C64XX_REGS_GPIO_MEMPORT_H __FILE__
+
+#define S3C64XX_MEM0CONSTOP S3C64XX_GPIOREG(0x1B0)
+#define S3C64XX_MEM1CONSTOP S3C64XX_GPIOREG(0x1B4)
+
+#define S3C64XX_MEM0CONSLP0 S3C64XX_GPIOREG(0x1C0)
+#define S3C64XX_MEM0CONSLP1 S3C64XX_GPIOREG(0x1C4)
+#define S3C64XX_MEM1CONSLP S3C64XX_GPIOREG(0x1C8)
+
+#define S3C64XX_MEM0DRVCON S3C64XX_GPIOREG(0x1D0)
+#define S3C64XX_MEM1DRVCON S3C64XX_GPIOREG(0x1D4)
+
+#endif /* __MACH_S3C64XX_REGS_GPIO_MEMPORT_H */
+
diff --git a/arch/arm/mach-s3c64xx/regs-modem.h b/arch/arm/mach-s3c64xx/regs-modem.h
new file mode 100644
index 000000000..073cdd3a0
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/regs-modem.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - modem block registers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __MACH_S3C64XX_REGS_MODEM_H
+#define __MACH_S3C64XX_REGS_MODEM_H __FILE__
+
+#define S3C64XX_MODEMREG(x) (S3C64XX_VA_MODEM + (x))
+
+#define S3C64XX_MODEM_INT2AP S3C64XX_MODEMREG(0x0)
+#define S3C64XX_MODEM_INT2MODEM S3C64XX_MODEMREG(0x4)
+#define S3C64XX_MODEM_MIFCON S3C64XX_MODEMREG(0x8)
+#define S3C64XX_MODEM_MIFPCON S3C64XX_MODEMREG(0xC)
+#define S3C64XX_MODEM_INTCLR S3C64XX_MODEMREG(0x10)
+#define S3C64XX_MODEM_DMA_TXADDR S3C64XX_MODEMREG(0x14)
+#define S3C64XX_MODEM_DMA_RXADDR S3C64XX_MODEMREG(0x18)
+
+#define MIFPCON_INT2M_LEVEL (1 << 4)
+#define MIFPCON_LCD_BYPASS (1 << 3)
+
+#endif /* __MACH_S3C64XX_REGS_MODEM_H */
diff --git a/arch/arm/mach-s3c64xx/regs-srom.h b/arch/arm/mach-s3c64xx/regs-srom.h
new file mode 100644
index 000000000..d56f3386e
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/regs-srom.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2009 Andy Green <andy@warmcat.com>
+ *
+ * S3C64XX SROM definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __MACH_S3C64XX_REGS_SROM_H
+#define __MACH_S3C64XX_REGS_SROM_H __FILE__
+
+#define S3C64XX_SROMREG(x) (S3C_VA_MEM + (x))
+
+#define S3C64XX_SROM_BW S3C64XX_SROMREG(0)
+#define S3C64XX_SROM_BC0 S3C64XX_SROMREG(4)
+#define S3C64XX_SROM_BC1 S3C64XX_SROMREG(8)
+#define S3C64XX_SROM_BC2 S3C64XX_SROMREG(0xc)
+#define S3C64XX_SROM_BC3 S3C64XX_SROMREG(0x10)
+#define S3C64XX_SROM_BC4 S3C64XX_SROMREG(0x14)
+#define S3C64XX_SROM_BC5 S3C64XX_SROMREG(0x18)
+
+/*
+ * one register BW holds 5 x 4-bit packed settings for NCS0 - NCS4
+ */
+
+#define S3C64XX_SROM_BW__DATAWIDTH__SHIFT 0
+#define S3C64XX_SROM_BW__WAITENABLE__SHIFT 2
+#define S3C64XX_SROM_BW__BYTEENABLE__SHIFT 3
+#define S3C64XX_SROM_BW__CS_MASK 0xf
+
+#define S3C64XX_SROM_BW__NCS0__SHIFT 0
+#define S3C64XX_SROM_BW__NCS1__SHIFT 4
+#define S3C64XX_SROM_BW__NCS2__SHIFT 8
+#define S3C64XX_SROM_BW__NCS3__SHIFT 0xc
+#define S3C64XX_SROM_BW__NCS4__SHIFT 0x10
+
+/*
+ * applies to same to BCS0 - BCS4
+ */
+
+#define S3C64XX_SROM_BCX__PMC__SHIFT 0
+#define S3C64XX_SROM_BCX__PMC__MASK 3
+#define S3C64XX_SROM_BCX__TACP__SHIFT 4
+#define S3C64XX_SROM_BCX__TACP__MASK 0xf
+#define S3C64XX_SROM_BCX__TCAH__SHIFT 8
+#define S3C64XX_SROM_BCX__TCAH__MASK 0xf
+#define S3C64XX_SROM_BCX__TCOH__SHIFT 12
+#define S3C64XX_SROM_BCX__TCOH__MASK 0xf
+#define S3C64XX_SROM_BCX__TACC__SHIFT 16
+#define S3C64XX_SROM_BCX__TACC__MASK 0x1f
+#define S3C64XX_SROM_BCX__TCOS__SHIFT 24
+#define S3C64XX_SROM_BCX__TCOS__MASK 0xf
+#define S3C64XX_SROM_BCX__TACS__SHIFT 28
+#define S3C64XX_SROM_BCX__TACS__MASK 0xf
+
+#endif /* __MACH_S3C64XX_REGS_SROM_H */
diff --git a/arch/arm/mach-s3c64xx/regs-sys.h b/arch/arm/mach-s3c64xx/regs-sys.h
new file mode 100644
index 000000000..8c411fbb0
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/regs-sys.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX system register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __MACH_S3C64XX_REGS_SYS_H
+#define __MACH_S3C64XX_REGS_SYS_H __FILE__
+
+#define S3C_SYSREG(x) (S3C_VA_SYS + (x))
+
+#define S3C64XX_AHB_CON0 S3C_SYSREG(0x100)
+#define S3C64XX_AHB_CON1 S3C_SYSREG(0x104)
+#define S3C64XX_AHB_CON2 S3C_SYSREG(0x108)
+
+#define S3C64XX_SDMA_SEL S3C_SYSREG(0x110)
+
+#define S3C64XX_OTHERS S3C_SYSREG(0x900)
+
+#define S3C64XX_OTHERS_USBMASK (1 << 16)
+#define S3C64XX_OTHERS_SYNCMUXSEL (1 << 6)
+
+#endif /* __MACH_S3C64XX_REGS_SYS_H */
diff --git a/arch/arm/mach-s3c64xx/regs-syscon-power.h b/arch/arm/mach-s3c64xx/regs-syscon-power.h
new file mode 100644
index 000000000..6e16b3404
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/regs-syscon-power.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - syscon power and sleep control registers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __MACH_S3C64XX_REGS_SYSCON_POWER_H
+#define __MACH_S3C64XX_REGS_SYSCON_POWER_H __FILE__
+
+#define S3C64XX_PWR_CFG S3C_SYSREG(0x804)
+
+#define S3C64XX_PWRCFG_OSC_OTG_DISABLE (1 << 17)
+#define S3C64XX_PWRCFG_MMC2_DISABLE (1 << 16)
+#define S3C64XX_PWRCFG_MMC1_DISABLE (1 << 15)
+#define S3C64XX_PWRCFG_MMC0_DISABLE (1 << 14)
+#define S3C64XX_PWRCFG_HSI_DISABLE (1 << 13)
+#define S3C64XX_PWRCFG_TS_DISABLE (1 << 12)
+#define S3C64XX_PWRCFG_RTC_TICK_DISABLE (1 << 11)
+#define S3C64XX_PWRCFG_RTC_ALARM_DISABLE (1 << 10)
+#define S3C64XX_PWRCFG_MSM_DISABLE (1 << 9)
+#define S3C64XX_PWRCFG_KEY_DISABLE (1 << 8)
+#define S3C64XX_PWRCFG_BATF_DISABLE (1 << 7)
+
+#define S3C64XX_PWRCFG_CFG_WFI_MASK (0x3 << 5)
+#define S3C64XX_PWRCFG_CFG_WFI_SHIFT (5)
+#define S3C64XX_PWRCFG_CFG_WFI_IGNORE (0x0 << 5)
+#define S3C64XX_PWRCFG_CFG_WFI_IDLE (0x1 << 5)
+#define S3C64XX_PWRCFG_CFG_WFI_STOP (0x2 << 5)
+#define S3C64XX_PWRCFG_CFG_WFI_SLEEP (0x3 << 5)
+
+#define S3C64XX_PWRCFG_CFG_BATFLT_MASK (0x3 << 3)
+#define S3C64XX_PWRCFG_CFG_BATFLT_SHIFT (3)
+#define S3C64XX_PWRCFG_CFG_BATFLT_IGNORE (0x0 << 3)
+#define S3C64XX_PWRCFG_CFG_BATFLT_IRQ (0x1 << 3)
+#define S3C64XX_PWRCFG_CFG_BATFLT_SLEEP (0x3 << 3)
+
+#define S3C64XX_PWRCFG_CFG_BAT_WAKE (1 << 2)
+#define S3C64XX_PWRCFG_OSC27_EN (1 << 0)
+
+#define S3C64XX_EINT_MASK S3C_SYSREG(0x808)
+
+#define S3C64XX_NORMAL_CFG S3C_SYSREG(0x810)
+
+#define S3C64XX_NORMALCFG_IROM_ON (1 << 30)
+#define S3C64XX_NORMALCFG_DOMAIN_ETM_ON (1 << 16)
+#define S3C64XX_NORMALCFG_DOMAIN_S_ON (1 << 15)
+#define S3C64XX_NORMALCFG_DOMAIN_F_ON (1 << 14)
+#define S3C64XX_NORMALCFG_DOMAIN_P_ON (1 << 13)
+#define S3C64XX_NORMALCFG_DOMAIN_I_ON (1 << 12)
+#define S3C64XX_NORMALCFG_DOMAIN_G_ON (1 << 10)
+#define S3C64XX_NORMALCFG_DOMAIN_V_ON (1 << 9)
+
+#define S3C64XX_STOP_CFG S3C_SYSREG(0x814)
+
+#define S3C64XX_STOPCFG_MEMORY_ARM_ON (1 << 29)
+#define S3C64XX_STOPCFG_TOP_MEMORY_ON (1 << 20)
+#define S3C64XX_STOPCFG_ARM_LOGIC_ON (1 << 17)
+#define S3C64XX_STOPCFG_TOP_LOGIC_ON (1 << 8)
+#define S3C64XX_STOPCFG_OSC_EN (1 << 0)
+
+#define S3C64XX_SLEEP_CFG S3C_SYSREG(0x818)
+
+#define S3C64XX_SLEEPCFG_OSC_EN (1 << 0)
+
+#define S3C64XX_STOP_MEM_CFG S3C_SYSREG(0x81c)
+
+#define S3C64XX_STOPMEMCFG_MODEMIF_RETAIN (1 << 6)
+#define S3C64XX_STOPMEMCFG_HOSTIF_RETAIN (1 << 5)
+#define S3C64XX_STOPMEMCFG_OTG_RETAIN (1 << 4)
+#define S3C64XX_STOPMEMCFG_HSMCC_RETAIN (1 << 3)
+#define S3C64XX_STOPMEMCFG_IROM_RETAIN (1 << 2)
+#define S3C64XX_STOPMEMCFG_IRDA_RETAIN (1 << 1)
+#define S3C64XX_STOPMEMCFG_NFCON_RETAIN (1 << 0)
+
+#define S3C64XX_OSC_STABLE S3C_SYSREG(0x824)
+#define S3C64XX_PWR_STABLE S3C_SYSREG(0x828)
+
+#define S3C64XX_WAKEUP_STAT S3C_SYSREG(0x908)
+
+#define S3C64XX_WAKEUPSTAT_MMC2 (1 << 11)
+#define S3C64XX_WAKEUPSTAT_MMC1 (1 << 10)
+#define S3C64XX_WAKEUPSTAT_MMC0 (1 << 9)
+#define S3C64XX_WAKEUPSTAT_HSI (1 << 8)
+#define S3C64XX_WAKEUPSTAT_BATFLT (1 << 6)
+#define S3C64XX_WAKEUPSTAT_MSM (1 << 5)
+#define S3C64XX_WAKEUPSTAT_KEY (1 << 4)
+#define S3C64XX_WAKEUPSTAT_TS (1 << 3)
+#define S3C64XX_WAKEUPSTAT_RTC_TICK (1 << 2)
+#define S3C64XX_WAKEUPSTAT_RTC_ALARM (1 << 1)
+#define S3C64XX_WAKEUPSTAT_EINT (1 << 0)
+
+#define S3C64XX_BLK_PWR_STAT S3C_SYSREG(0x90c)
+
+#define S3C64XX_BLKPWRSTAT_G (1 << 7)
+#define S3C64XX_BLKPWRSTAT_ETM (1 << 6)
+#define S3C64XX_BLKPWRSTAT_S (1 << 5)
+#define S3C64XX_BLKPWRSTAT_F (1 << 4)
+#define S3C64XX_BLKPWRSTAT_P (1 << 3)
+#define S3C64XX_BLKPWRSTAT_I (1 << 2)
+#define S3C64XX_BLKPWRSTAT_V (1 << 1)
+#define S3C64XX_BLKPWRSTAT_TOP (1 << 0)
+
+#define S3C64XX_INFORM0 S3C_SYSREG(0xA00)
+#define S3C64XX_INFORM1 S3C_SYSREG(0xA04)
+#define S3C64XX_INFORM2 S3C_SYSREG(0xA08)
+#define S3C64XX_INFORM3 S3C_SYSREG(0xA0C)
+
+#endif /* __MACH_S3C64XX_REGS_SYSCON_POWER_H */
diff --git a/arch/arm/mach-s3c64xx/s3c6400.c b/arch/arm/mach-s3c64xx/s3c6400.c
new file mode 100644
index 000000000..1ce48c54c
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/s3c6400.c
@@ -0,0 +1,97 @@
+/* linux/arch/arm/mach-s3c64xx/cpu.c
+ *
+ * Copyright 2009 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/*
+ * NOTE: Code in this file is not used when booting with Device Tree 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/clk.h>
+#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/sdhci.h>
+#include <plat/iic-core.h>
+#include <plat/onenand-core.h>
+
+#include "common.h"
+
+void __init s3c6400_map_io(void)
+{
+ /* setup SDHCI */
+
+ s3c6400_default_sdhci0();
+ s3c6400_default_sdhci1();
+ s3c6400_default_sdhci2();
+
+ /* the i2c devices are directly compatible with s3c2440 */
+ s3c_i2c0_setname("s3c2440-i2c");
+
+ s3c_device_nand.name = "s3c6400-nand";
+
+ s3c_onenand_setname("s3c6400-onenand");
+ s3c64xx_onenand1_setname("s3c6400-onenand");
+}
+
+void __init s3c6400_init_irq(void)
+{
+ /* VIC0 does not have IRQS 5..7,
+ * VIC1 is fully populated. */
+ s3c64xx_init_irq(~0 & ~(0xf << 5), ~0);
+}
+
+static struct bus_type s3c6400_subsys = {
+ .name = "s3c6400-core",
+ .dev_name = "s3c6400-core",
+};
+
+static struct device s3c6400_dev = {
+ .bus = &s3c6400_subsys,
+};
+
+static int __init s3c6400_core_init(void)
+{
+ /* Not applicable when using DT. */
+ if (of_have_populated_dt())
+ return 0;
+
+ return subsys_system_register(&s3c6400_subsys, NULL);
+}
+
+core_initcall(s3c6400_core_init);
+
+int __init s3c6400_init(void)
+{
+ printk("S3C6400: Initialising architecture\n");
+
+ return device_register(&s3c6400_dev);
+}
diff --git a/arch/arm/mach-s3c64xx/s3c6410.c b/arch/arm/mach-s3c64xx/s3c6410.c
new file mode 100644
index 000000000..b2a793054
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/s3c6410.c
@@ -0,0 +1,100 @@
+/* linux/arch/arm/mach-s3c64xx/s3c6410.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/*
+ * NOTE: Code in this file is not used when booting with Device Tree 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/clk.h>
+#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/serial_core.h>
+#include <linux/serial_s3c.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/sdhci.h>
+#include <plat/ata-core.h>
+#include <plat/adc-core.h>
+#include <plat/iic-core.h>
+#include <plat/onenand-core.h>
+
+#include "common.h"
+
+void __init s3c6410_map_io(void)
+{
+ /* initialise device information early */
+ s3c6410_default_sdhci0();
+ s3c6410_default_sdhci1();
+ s3c6410_default_sdhci2();
+
+ /* the i2c devices are directly compatible with s3c2440 */
+ s3c_i2c0_setname("s3c2440-i2c");
+ s3c_i2c1_setname("s3c2440-i2c");
+
+ s3c_adc_setname("s3c64xx-adc");
+ s3c_device_nand.name = "s3c6400-nand";
+ s3c_onenand_setname("s3c6410-onenand");
+ s3c64xx_onenand1_setname("s3c6410-onenand");
+ s3c_cfcon_setname("s3c64xx-pata");
+}
+
+void __init s3c6410_init_irq(void)
+{
+ /* VIC0 is missing IRQ7, VIC1 is fully populated. */
+ s3c64xx_init_irq(~0 & ~(1 << 7), ~0);
+}
+
+struct bus_type s3c6410_subsys = {
+ .name = "s3c6410-core",
+ .dev_name = "s3c6410-core",
+};
+
+static struct device s3c6410_dev = {
+ .bus = &s3c6410_subsys,
+};
+
+static int __init s3c6410_core_init(void)
+{
+ /* Not applicable when using DT. */
+ if (of_have_populated_dt())
+ return 0;
+
+ return subsys_system_register(&s3c6410_subsys, NULL);
+}
+
+core_initcall(s3c6410_core_init);
+
+int __init s3c6410_init(void)
+{
+ printk("S3C6410: Initialising architecture\n");
+
+ return device_register(&s3c6410_dev);
+}
diff --git a/arch/arm/mach-s3c64xx/setup-fb-24bpp.c b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
new file mode 100644
index 000000000..9d17bff12
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
@@ -0,0 +1,28 @@
+/* linux/arch/arm/plat-s3c64xx/setup-fb-24bpp.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Base S3C64XX setup information for 24bpp LCD framebuffer
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio-samsung.h>
+
+void s3c64xx_fb_gpio_setup_24bpp(void)
+{
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPI(0), 16, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPJ(0), 12, S3C_GPIO_SFN(2));
+}
diff --git a/arch/arm/mach-s3c64xx/setup-i2c0.c b/arch/arm/mach-s3c64xx/setup-i2c0.c
new file mode 100644
index 000000000..4b8c1cfdd
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-i2c0.c
@@ -0,0 +1,29 @@
+/* linux/arch/arm/plat-s3c64xx/setup-i2c0.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Base S3C64XX I2C bus 0 gpio configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio-samsung.h>
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S3C64XX_GPB(5), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s3c64xx/setup-i2c1.c b/arch/arm/mach-s3c64xx/setup-i2c1.c
new file mode 100644
index 000000000..cd1df71ee
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-i2c1.c
@@ -0,0 +1,29 @@
+/* linux/arch/arm/plat-s3c64xx/setup-i2c1.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Base S3C64XX I2C bus 1 gpio configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/platform_data/i2c-s3c2410.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio-samsung.h>
+
+void s3c_i2c1_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S3C64XX_GPB(2), 2,
+ S3C_GPIO_SFN(6), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s3c64xx/setup-ide.c b/arch/arm/mach-s3c64xx/setup-ide.c
new file mode 100644
index 000000000..689fb72e7
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-ide.c
@@ -0,0 +1,44 @@
+/* linux/arch/arm/mach-s3c64xx/setup-ide.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S3C64XX setup information for IDE
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio-samsung.h>
+#include <linux/platform_data/ata-samsung_cf.h>
+
+void s3c64xx_ide_setup_gpio(void)
+{
+ u32 reg;
+
+ reg = readl(S3C_MEM_SYS_CFG) & (~0x3f);
+
+ /* Independent CF interface, CF chip select configuration */
+ writel(reg | MEM_SYS_CFG_INDEP_CF |
+ MEM_SYS_CFG_EBI_FIX_PRI_CFCON, S3C_MEM_SYS_CFG);
+
+ s3c_gpio_cfgpin(S3C64XX_GPB(4), S3C_GPIO_SFN(4));
+
+ /* Set XhiDATA[15:0] pins as CF Data[15:0] */
+ s3c_gpio_cfgpin_range(S3C64XX_GPK(0), 16, S3C_GPIO_SFN(5));
+
+ /* Set XhiADDR[2:0] pins as CF ADDR[2:0] */
+ s3c_gpio_cfgpin_range(S3C64XX_GPL(0), 3, S3C_GPIO_SFN(6));
+
+ /* Set Xhi ctrl pins as CF ctrl pins(IORDY, IOWR, IORD, CE[0:1]) */
+ s3c_gpio_cfgpin(S3C64XX_GPM(5), S3C_GPIO_SFN(1));
+ s3c_gpio_cfgpin_range(S3C64XX_GPM(0), 5, S3C_GPIO_SFN(6));
+}
diff --git a/arch/arm/mach-s3c64xx/setup-keypad.c b/arch/arm/mach-s3c64xx/setup-keypad.c
new file mode 100644
index 000000000..6ad9a89df
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-keypad.c
@@ -0,0 +1,25 @@
+/* linux/arch/arm/mach-s3c64xx/setup-keypad.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * GPIO configuration for S3C64XX KeyPad device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/gpio.h>
+#include <plat/gpio-cfg.h>
+#include <plat/keypad.h>
+#include <mach/gpio-samsung.h>
+
+void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
+{
+ /* Set all the necessary GPK pins to special-function 3: KP_ROW[x] */
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPK(8), rows, S3C_GPIO_SFN(3));
+
+ /* Set all the necessary GPL pins to special-function 3: KP_COL[x] */
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPL(0), cols, S3C_GPIO_SFN(3));
+}
diff --git a/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
new file mode 100644
index 000000000..f426b7a16
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
@@ -0,0 +1,58 @@
+/* linux/arch/arm/plat-s3c64xx/setup-sdhci-gpio.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/sdhci.h>
+#include <mach/gpio-samsung.h>
+
+void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+
+ /* Set all the necessary GPG pins to special-function 2 */
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPG(0), 2 + width, S3C_GPIO_SFN(2));
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(2));
+ }
+}
+
+void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+
+ /* Set all the necessary GPH pins to special-function 2 */
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPH(0), 2 + width, S3C_GPIO_SFN(2));
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(3));
+ }
+}
+
+void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
+{
+ /* Set all the necessary GPH pins to special-function 3 */
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPH(6), width, S3C_GPIO_SFN(3));
+
+ /* Set all the necessary GPC pins to special-function 3 */
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPC(4), 2, S3C_GPIO_SFN(3));
+}
diff --git a/arch/arm/mach-s3c64xx/setup-spi.c b/arch/arm/mach-s3c64xx/setup-spi.c
new file mode 100644
index 000000000..5fd1a315c
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-spi.c
@@ -0,0 +1,31 @@
+/* linux/arch/arm/mach-s3c64xx/setup-spi.c
+ *
+ * Copyright (C) 2011 Samsung Electronics Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio-samsung.h>
+
+#ifdef CONFIG_S3C64XX_DEV_SPI0
+int s3c64xx_spi0_cfg_gpio(void)
+{
+ s3c_gpio_cfgall_range(S3C64XX_GPC(0), 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI1
+int s3c64xx_spi1_cfg_gpio(void)
+{
+ s3c_gpio_cfgall_range(S3C64XX_GPC(4), 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+ return 0;
+}
+#endif
diff --git a/arch/arm/mach-s3c64xx/setup-usb-phy.c b/arch/arm/mach-s3c64xx/setup-usb-phy.c
new file mode 100644
index 000000000..ca960bda0
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-usb-phy.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <mach/map.h>
+#include <plat/cpu.h>
+#include <plat/regs-usb-hsotg-phy.h>
+#include <plat/usb-phy.h>
+
+#include "regs-sys.h"
+
+static int s3c_usb_otgphy_init(struct platform_device *pdev)
+{
+ struct clk *xusbxti;
+ u32 phyclk;
+
+ writel(readl(S3C64XX_OTHERS) | S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS);
+
+ /* set clock frequency for PLL */
+ phyclk = readl(S3C_PHYCLK) & ~S3C_PHYCLK_CLKSEL_MASK;
+
+ xusbxti = clk_get(&pdev->dev, "xusbxti");
+ if (xusbxti && !IS_ERR(xusbxti)) {
+ switch (clk_get_rate(xusbxti)) {
+ case 12 * MHZ:
+ phyclk |= S3C_PHYCLK_CLKSEL_12M;
+ break;
+ case 24 * MHZ:
+ phyclk |= S3C_PHYCLK_CLKSEL_24M;
+ break;
+ default:
+ case 48 * MHZ:
+ /* default reference clock */
+ break;
+ }
+ clk_put(xusbxti);
+ }
+
+ /* TODO: select external clock/oscillator */
+ writel(phyclk | S3C_PHYCLK_CLK_FORCE, S3C_PHYCLK);
+
+ /* set to normal OTG PHY */
+ writel((readl(S3C_PHYPWR) & ~S3C_PHYPWR_NORMAL_MASK), S3C_PHYPWR);
+ mdelay(1);
+
+ /* reset OTG PHY and Link */
+ writel(S3C_RSTCON_PHY | S3C_RSTCON_HCLK | S3C_RSTCON_PHYCLK,
+ S3C_RSTCON);
+ udelay(20); /* at-least 10uS */
+ writel(0, S3C_RSTCON);
+
+ return 0;
+}
+
+static int s3c_usb_otgphy_exit(struct platform_device *pdev)
+{
+ writel((readl(S3C_PHYPWR) | S3C_PHYPWR_ANALOG_POWERDOWN |
+ S3C_PHYPWR_OTG_DISABLE), S3C_PHYPWR);
+
+ writel(readl(S3C64XX_OTHERS) & ~S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS);
+
+ return 0;
+}
+
+int s5p_usb_phy_init(struct platform_device *pdev, int type)
+{
+ if (type == USB_PHY_TYPE_DEVICE)
+ return s3c_usb_otgphy_init(pdev);
+
+ return -EINVAL;
+}
+
+int s5p_usb_phy_exit(struct platform_device *pdev, int type)
+{
+ if (type == USB_PHY_TYPE_DEVICE)
+ return s3c_usb_otgphy_exit(pdev);
+
+ return -EINVAL;
+}
diff --git a/arch/arm/mach-s3c64xx/sleep.S b/arch/arm/mach-s3c64xx/sleep.S
new file mode 100644
index 000000000..34313f9c8
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/sleep.S
@@ -0,0 +1,72 @@
+/* linux/arch/arm/plat-s3c64xx/sleep.S
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX CPU sleep code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/map.h>
+
+#undef S3C64XX_VA_GPIO
+#define S3C64XX_VA_GPIO (0x0)
+
+#include <mach/regs-gpio.h>
+
+#define LL_UART (S3C_PA_UART + (0x400 * CONFIG_S3C_LOWLEVEL_UART_PORT))
+
+ .text
+
+ /* Sleep magic, the word before the resume entry point so that the
+ * bootloader can check for a resumeable image. */
+
+ .word 0x2bedf00d
+
+ /* s3c_cpu_reusme
+ *
+ * This is the entry point, stored by whatever method the bootloader
+ * requires to get the kernel runnign again. This code expects to be
+ * entered with no caches live and the MMU disabled. It will then
+ * restore the MMU and other basic CP registers saved and restart
+ * the kernel C code to finish the resume code.
+ */
+
+ENTRY(s3c_cpu_resume)
+ msr cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
+ ldr r2, =LL_UART /* for debug */
+
+#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+
+#define S3C64XX_GPNCON (S3C64XX_GPN_BASE + 0x00)
+#define S3C64XX_GPNDAT (S3C64XX_GPN_BASE + 0x04)
+
+#define S3C64XX_GPN_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
+#define S3C64XX_GPN_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
+
+ /* Initialise the GPIO state if we are debugging via the SMDK LEDs,
+ * as the uboot version supplied resets these to inputs during the
+ * resume checks.
+ */
+
+ ldr r3, =S3C64XX_PA_GPIO
+ ldr r0, [ r3, #S3C64XX_GPNCON ]
+ bic r0, r0, #(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) | \
+ S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15))
+ orr r0, r0, #(S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) | \
+ S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15))
+ str r0, [ r3, #S3C64XX_GPNCON ]
+
+ ldr r0, [ r3, #S3C64XX_GPNDAT ]
+ bic r0, r0, #0xf << 12 @ GPN12..15
+ orr r0, r0, #1 << 15 @ GPN15
+ str r0, [ r3, #S3C64XX_GPNDAT ]
+#endif
+ b cpu_resume