summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-05-17 08:49:25 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-05-17 08:49:25 +0100
commita3685f00652af83f12b63e3b4ef48f29581ba48b (patch)
tree18ec9eed3deabf3c6b9bec206765a4dd0d8cf9ec
parentb12f3cbd7a9a869eae1eb108da02526b132ba80b (diff)
parent63b1f51b2405573d47bf5b9ab6e7cd5c697d3dcc (diff)
Merge branch 'for-rmk/2635' of git://git.fluff.org/bjdooks/linux into devel-stable
-rw-r--r--arch/arm/Kconfig7
-rw-r--r--arch/arm/Makefile2
-rw-r--r--arch/arm/mach-s3c2410/Kconfig1
-rw-r--r--arch/arm/mach-s3c2410/h1940-bluetooth.c32
-rw-r--r--arch/arm/mach-s3c2410/include/mach/dma.h2
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio-fns.h47
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio-nrs.h12
-rw-r--r--arch/arm/mach-s3c2410/include/mach/irqs.h25
-rw-r--r--arch/arm/mach-s3c2410/include/mach/map.h5
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-clock.h2
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-dsc.h36
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-gpio.h45
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-gpioj.h36
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-irq.h10
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h30
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h24
-rw-r--r--arch/arm/mach-s3c2410/include/mach/uncompress.h4
-rw-r--r--arch/arm/mach-s3c2410/mach-amlm5900.c5
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c9
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c20
-rw-r--r--arch/arm/mach-s3c2410/mach-n30.c7
-rw-r--r--arch/arm/mach-s3c2410/mach-qt2410.c10
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c5
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c8
-rw-r--r--arch/arm/mach-s3c2412/Kconfig3
-rw-r--r--arch/arm/mach-s3c2412/mach-jive.c26
-rw-r--r--arch/arm/mach-s3c2412/mach-smdk2413.c8
-rw-r--r--arch/arm/mach-s3c2416/Kconfig38
-rw-r--r--arch/arm/mach-s3c2416/Makefile19
-rw-r--r--arch/arm/mach-s3c2416/clock.c135
-rw-r--r--arch/arm/mach-s3c2416/irq.c254
-rw-r--r--arch/arm/mach-s3c2416/mach-smdk2416.c150
-rw-r--r--arch/arm/mach-s3c2416/s3c2416.c128
-rw-r--r--arch/arm/mach-s3c2440/Kconfig1
-rw-r--r--arch/arm/mach-s3c2440/mach-mini2440.c23
-rw-r--r--arch/arm/mach-s3c2440/mach-nexcoder.c9
-rw-r--r--arch/arm/mach-s3c2440/mach-osiris.c5
-rw-r--r--arch/arm/mach-s3c2440/s3c2440.c8
-rw-r--r--arch/arm/mach-s3c2443/Kconfig1
-rw-r--r--arch/arm/mach-s3c2443/clock.c479
-rw-r--r--arch/arm/mach-s3c64xx/gpiolib.c6
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/pll.h35
-rw-r--r--arch/arm/mach-s5p6440/gpio.c5
-rw-r--r--arch/arm/plat-s3c24xx/Kconfig7
-rw-r--r--arch/arm/plat-s3c24xx/Makefile1
-rw-r--r--arch/arm/plat-s3c24xx/common-smdk.c9
-rw-r--r--arch/arm/plat-s3c24xx/cpu.c21
-rw-r--r--arch/arm/plat-s3c24xx/gpio.c144
-rw-r--r--arch/arm/plat-s3c24xx/gpiolib.c60
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/pll.h25
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2416.h31
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2443.h19
-rw-r--r--arch/arm/plat-s3c24xx/pm.c9
-rw-r--r--arch/arm/plat-s3c24xx/s3c2410-clock.c15
-rw-r--r--arch/arm/plat-s3c24xx/s3c2443-clock.c472
-rw-r--r--arch/arm/plat-s3c24xx/setup-i2c.c5
-rw-r--r--arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c16
-rw-r--r--arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c16
-rw-r--r--arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c16
-rw-r--r--arch/arm/plat-samsung/clock.c15
-rw-r--r--arch/arm/plat-samsung/gpio-config.c103
-rw-r--r--arch/arm/plat-samsung/include/plat/clock.h1
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu.h1
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h58
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg.h11
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-core.h3
-rw-r--r--arch/arm/plat-samsung/include/plat/pll6553x.h51
-rw-r--r--drivers/serial/Kconfig7
68 files changed, 2016 insertions, 817 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3806d636a401..ae0ecdaf353c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -657,7 +657,7 @@ config ARCH_SA1100
Support for StrongARM 11x0 based boards.
config ARCH_S3C2410
- bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
+ bool "Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443, S3C2450"
select GENERIC_GPIO
select ARCH_HAS_CPUFREQ
select HAVE_CLK
@@ -666,6 +666,10 @@ config ARCH_S3C2410
BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
the Samsung SMDK2410 development board (and derivatives).
+ Note, the S3C2416 and the S3C2450 are so close that they even share
+ the same SoC ID code. This means that there is no seperate machine
+ directory (no arch/arm/mach-s3c2450) as the S3C2416 was first.
+
config ARCH_S3C64XX
bool "Samsung S3C64XX"
select PLAT_SAMSUNG
@@ -904,6 +908,7 @@ if ARCH_S3C2410
source "arch/arm/mach-s3c2400/Kconfig"
source "arch/arm/mach-s3c2410/Kconfig"
source "arch/arm/mach-s3c2412/Kconfig"
+source "arch/arm/mach-s3c2416/Kconfig"
source "arch/arm/mach-s3c2440/Kconfig"
source "arch/arm/mach-s3c2443/Kconfig"
endif
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 3e312ec8e624..7cdaf5afcee6 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -161,7 +161,7 @@ machine-$(CONFIG_ARCH_PNX4008) := pnx4008
machine-$(CONFIG_ARCH_PXA) := pxa
machine-$(CONFIG_ARCH_REALVIEW) := realview
machine-$(CONFIG_ARCH_RPC) := rpc
-machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2443
+machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2416 s3c2440 s3c2443
machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0
machine-$(CONFIG_ARCH_S3C64XX) := s3c64xx
machine-$(CONFIG_ARCH_S5P6440) := s5p6440
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index 554731868b07..9e5e96f12d86 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -6,6 +6,7 @@ config CPU_S3C2410
bool
depends on ARCH_S3C2410
select CPU_ARM920T
+ select S3C_GPIO_PULL_UP
select S3C2410_CLOCK
select S3C2410_GPIO
select CPU_LLSERIAL_S3C2410
diff --git a/arch/arm/mach-s3c2410/h1940-bluetooth.c b/arch/arm/mach-s3c2410/h1940-bluetooth.c
index a3f3c7b1ca38..8cdeb14af592 100644
--- a/arch/arm/mach-s3c2410/h1940-bluetooth.c
+++ b/arch/arm/mach-s3c2410/h1940-bluetooth.c
@@ -33,14 +33,15 @@ static void h1940bt_enable(int on)
h1940_latch_control(0, H1940_LATCH_BLUETOOTH_POWER);
/* Reset the chip */
mdelay(10);
- s3c2410_gpio_setpin(S3C2410_GPH(1), 1);
+
+ gpio_set_value(S3C2410_GPH(1), 1);
mdelay(10);
- s3c2410_gpio_setpin(S3C2410_GPH(1), 0);
+ gpio_set_value(S3C2410_GPH(1), 0);
}
else {
- s3c2410_gpio_setpin(S3C2410_GPH(1), 1);
+ gpio_set_value(S3C2410_GPH(1), 1);
mdelay(10);
- s3c2410_gpio_setpin(S3C2410_GPH(1), 0);
+ gpio_set_value(S3C2410_GPH(1), 0);
mdelay(10);
h1940_latch_control(H1940_LATCH_BLUETOOTH_POWER, 0);
}
@@ -61,15 +62,21 @@ static int __devinit h1940bt_probe(struct platform_device *pdev)
struct rfkill *rfk;
int ret = 0;
+ ret = gpio_request(S3C2410_GPH(1), dev_name(&pdev->dev));
+ if (ret) {
+ dev_err(&pdev->dev, "could not get GPH1\n");\
+ return ret;
+ }
+
/* Configures BT serial port GPIOs */
- s3c2410_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0);
- s3c2410_gpio_pullup(S3C2410_GPH(0), 1);
- s3c2410_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT);
- s3c2410_gpio_pullup(S3C2410_GPH(1), 1);
- s3c2410_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0);
- s3c2410_gpio_pullup(S3C2410_GPH(2), 1);
- s3c2410_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0);
- s3c2410_gpio_pullup(S3C2410_GPH(3), 1);
+ s3c_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0);
+ s3c_gpio_cfgpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT);
+ s3c_gpio_cfgpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0);
+ s3c_gpio_cfgpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0);
+ s3c_gpio_cfgpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE);
rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH,
@@ -100,6 +107,7 @@ static int h1940bt_remove(struct platform_device *pdev)
struct rfkill *rfk = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
+ gpio_free(S3C2410_GPH(1));
if (rfk) {
rfkill_unregister(rfk);
diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h
index 08ac5f96c012..cf68136cc668 100644
--- a/arch/arm/mach-s3c2410/include/mach/dma.h
+++ b/arch/arm/mach-s3c2410/include/mach/dma.h
@@ -54,7 +54,7 @@ enum dma_ch {
#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
/* we have 4 dma channels */
-#ifndef CONFIG_CPU_S3C2443
+#if !defined(CONFIG_CPU_S3C2443) && !defined(CONFIG_CPU_S3C2416)
#define S3C_DMA_CHANNELS (4)
#else
#define S3C_DMA_CHANNELS (6)
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-fns.h b/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
index 035a493952db..f453c4f2cb8e 100644
--- a/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
+++ b/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
@@ -10,14 +10,28 @@
* published by the Free Software Foundation.
*/
+#ifndef __MACH_GPIO_FNS_H
+#define __MACH_GPIO_FNS_H __FILE__
+
/* These functions are in the to-be-removed category and it is strongly
* encouraged not to use these in new code. They will be marked deprecated
* very soon.
*
* Most of the functionality can be either replaced by the gpiocfg calls
* for the s3c platform or by the generic GPIOlib API.
+ *
+ * As of 2.6.35-rc, these will be removed, with the few drivers using them
+ * either replaced or given a wrapper until the calls can be removed.
*/
+#include <plat/gpio-cfg.h>
+
+static inline void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int cfg)
+{
+ /* 1:1 mapping between cfgpin and setcfg calls at the moment */
+ s3c_gpio_cfgpin(pin, cfg);
+}
+
/* external functions for GPIO support
*
* These allow various different clients to access the same GPIO
@@ -25,17 +39,6 @@
* GPIO register, then it is safe to ioremap/__raw_{read|write} to it.
*/
-/* s3c2410_gpio_cfgpin
- *
- * set the configuration of the given pin to the value passed.
- *
- * eg:
- * s3c2410_gpio_cfgpin(S3C2410_GPA(0), S3C2410_GPA0_ADDR0);
- * s3c2410_gpio_cfgpin(S3C2410_GPE(8), S3C2410_GPE8_SDDAT1);
-*/
-
-extern void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function);
-
extern unsigned int s3c2410_gpio_getcfg(unsigned int pin);
/* s3c2410_gpio_getirq
@@ -73,6 +76,14 @@ extern int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
/* s3c2410_gpio_pullup
*
+ * This call should be replaced with s3c_gpio_setpull().
+ *
+ * As a note, there is currently no distinction between pull-up and pull-down
+ * in the s3c24xx series devices with only an on/off configuration.
+ */
+
+/* s3c2410_gpio_pullup
+ *
* configure the pull-up control on the given pin
*
* to = 1 => disable the pull-up
@@ -86,18 +97,8 @@ extern int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
extern void s3c2410_gpio_pullup(unsigned int pin, unsigned int to);
-/* s3c2410_gpio_getpull
- *
- * Read the state of the pull-up on a given pin
- *
- * return:
- * < 0 => error code
- * 0 => enabled
- * 1 => disabled
-*/
-
-extern int s3c2410_gpio_getpull(unsigned int pin);
-
extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to);
extern unsigned int s3c2410_gpio_getpin(unsigned int pin);
+
+#endif /* __MACH_GPIO_FNS_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
index 2edbb9c88ab3..f3182ff847cb 100644
--- a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
+++ b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
@@ -34,6 +34,10 @@
#define S3C2410_GPIO_F_NR (32)
#define S3C2410_GPIO_G_NR (32)
#define S3C2410_GPIO_H_NR (32)
+#define S3C2410_GPIO_J_NR (32) /* technically 16. */
+#define S3C2410_GPIO_K_NR (32) /* technically 16. */
+#define S3C2410_GPIO_L_NR (32) /* technically 15. */
+#define S3C2410_GPIO_M_NR (32) /* technically 2. */
#if CONFIG_S3C_GPIO_SPACE != 0
#error CONFIG_S3C_GPIO_SPACE cannot be zero at the moment
@@ -53,6 +57,10 @@ enum s3c_gpio_number {
S3C2410_GPIO_F_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_E),
S3C2410_GPIO_G_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_F),
S3C2410_GPIO_H_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_G),
+ S3C2410_GPIO_J_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_H),
+ S3C2410_GPIO_K_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_J),
+ S3C2410_GPIO_L_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_K),
+ S3C2410_GPIO_M_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_L),
};
#endif /* __ASSEMBLY__ */
@@ -67,6 +75,10 @@ enum s3c_gpio_number {
#define S3C2410_GPF(_nr) (S3C2410_GPIO_F_START + (_nr))
#define S3C2410_GPG(_nr) (S3C2410_GPIO_G_START + (_nr))
#define S3C2410_GPH(_nr) (S3C2410_GPIO_H_START + (_nr))
+#define S3C2410_GPJ(_nr) (S3C2410_GPIO_J_START + (_nr))
+#define S3C2410_GPK(_nr) (S3C2410_GPIO_K_START + (_nr))
+#define S3C2410_GPL(_nr) (S3C2410_GPIO_L_START + (_nr))
+#define S3C2410_GPM(_nr) (S3C2410_GPIO_M_START + (_nr))
/* compatibility until drivers can be modified */
diff --git a/arch/arm/mach-s3c2410/include/mach/irqs.h b/arch/arm/mach-s3c2410/include/mach/irqs.h
index 6c12c6312ad8..877c15e1b154 100644
--- a/arch/arm/mach-s3c2410/include/mach/irqs.h
+++ b/arch/arm/mach-s3c2410/include/mach/irqs.h
@@ -115,6 +115,26 @@
#define IRQ_S3C2412_SDI S3C2410_IRQSUB(13)
#define IRQ_S3C2412_CF S3C2410_IRQSUB(14)
+
+#define IRQ_S3C2416_EINT8t15 S3C2410_IRQ(5)
+#define IRQ_S3C2416_DMA S3C2410_IRQ(17)
+#define IRQ_S3C2416_UART3 S3C2410_IRQ(18)
+#define IRQ_S3C2416_SDI1 S3C2410_IRQ(20)
+#define IRQ_S3C2416_SDI0 S3C2410_IRQ(21)
+
+#define IRQ_S3C2416_LCD2 S3C2410_IRQSUB(15)
+#define IRQ_S3C2416_LCD3 S3C2410_IRQSUB(16)
+#define IRQ_S3C2416_LCD4 S3C2410_IRQSUB(17)
+#define IRQ_S3C2416_DMA0 S3C2410_IRQSUB(18)
+#define IRQ_S3C2416_DMA1 S3C2410_IRQSUB(19)
+#define IRQ_S3C2416_DMA2 S3C2410_IRQSUB(20)
+#define IRQ_S3C2416_DMA3 S3C2410_IRQSUB(21)
+#define IRQ_S3C2416_DMA4 S3C2410_IRQSUB(22)
+#define IRQ_S3C2416_DMA5 S3C2410_IRQSUB(23)
+#define IRQ_S32416_WDT S3C2410_IRQSUB(27)
+#define IRQ_S32416_AC97 S3C2410_IRQSUB(28)
+
+
/* extra irqs for s3c2440 */
#define IRQ_S3C2440_CAM_C S3C2410_IRQSUB(11) /* S3C2443 too */
@@ -130,7 +150,10 @@
#define IRQ_S3C2443_HSMMC S3C2410_IRQ(20) /* IRQ_SDI */
#define IRQ_S3C2443_NAND S3C2410_IRQ(24) /* reserved */
+#define IRQ_S3C2416_HSMMC0 S3C2410_IRQ(21) /* S3C2416/S3C2450 */
+
#define IRQ_HSMMC0 IRQ_S3C2443_HSMMC
+#define IRQ_HSMMC1 IRQ_S3C2416_HSMMC0
#define IRQ_S3C2443_LCD1 S3C2410_IRQSUB(14)
#define IRQ_S3C2443_LCD2 S3C2410_IRQSUB(15)
@@ -152,7 +175,7 @@
#define IRQ_S3C2443_WDT S3C2410_IRQSUB(27)
#define IRQ_S3C2443_AC97 S3C2410_IRQSUB(28)
-#ifdef CONFIG_CPU_S3C2443
+#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
#define NR_IRQS (IRQ_S3C2443_AC97+1)
#else
#define NR_IRQS (IRQ_S3C2440_AC97+1)
diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h
index b049e61460b6..f07d68066d7e 100644
--- a/arch/arm/mach-s3c2410/include/mach/map.h
+++ b/arch/arm/mach-s3c2410/include/mach/map.h
@@ -63,9 +63,9 @@
#define S3C2440_PA_AC97 (0x5B000000)
#define S3C2440_SZ_AC97 SZ_1M
-/* S3C2443 High-speed SD/MMC */
+/* S3C2443/S3C2416 High-speed SD/MMC */
#define S3C2443_PA_HSMMC (0x4A800000)
-#define S3C2443_SZ_HSMMC (256)
+#define S3C2416_PA_HSMMC0 (0x4AC00000)
/* S3C2412 memory and IO controls */
#define S3C2412_PA_SSMC (0x4F000000)
@@ -110,6 +110,7 @@
#define S3C_PA_UART S3C24XX_PA_UART
#define S3C_PA_USBHOST S3C2410_PA_USBHOST
#define S3C_PA_HSMMC0 S3C2443_PA_HSMMC
+#define S3C_PA_HSMMC1 S3C2416_PA_HSMMC0
#define S3C_PA_NAND S3C24XX_PA_NAND
#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-clock.h
index 9a0d169be137..3415b60082d7 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-clock.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-clock.h
@@ -161,4 +161,6 @@
#endif /* CONFIG_CPU_S3C2412 | CONFIG_CPU_S3C2413 */
+#define S3C2416_CLKDIV2 S3C2410_CLKREG(0x28)
+
#endif /* __ASM_ARM_REGS_CLOCK */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-dsc.h b/arch/arm/mach-s3c2410/include/mach/regs-dsc.h
index 3c3853cd3cf7..98fd4a05587c 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-dsc.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-dsc.h
@@ -19,6 +19,42 @@
#define S3C2412_DSC1 S3C2410_GPIOREG(0xe0)
#endif
+#if defined(CONFIG_CPU_S3C2416)
+#define S3C2416_DSC0 S3C2410_GPIOREG(0xc0)
+#define S3C2416_DSC1 S3C2410_GPIOREG(0xc4)
+#define S3C2416_DSC2 S3C2410_GPIOREG(0xc8)
+#define S3C2416_DSC3 S3C2410_GPIOREG(0x110)
+
+#define S3C2416_SELECT_DSC0 (0 << 30)
+#define S3C2416_SELECT_DSC1 (1 << 30)
+#define S3C2416_SELECT_DSC2 (2 << 30)
+#define S3C2416_SELECT_DSC3 (3 << 30)
+
+#define S3C2416_DSC_GETSHIFT(x) (x & 30)
+
+#define S3C2416_DSC0_CF (S3C2416_SELECT_DSC0 | 28)
+#define S3C2416_DSC0_CF_5mA (0 << 28)
+#define S3C2416_DSC0_CF_10mA (1 << 28)
+#define S3C2416_DSC0_CF_15mA (2 << 28)
+#define S3C2416_DSC0_CF_21mA (3 << 28)
+#define S3C2416_DSC0_CF_MASK (3 << 28)
+
+#define S3C2416_DSC0_nRBE (S3C2416_SELECT_DSC0 | 26)
+#define S3C2416_DSC0_nRBE_5mA (0 << 26)
+#define S3C2416_DSC0_nRBE_10mA (1 << 26)
+#define S3C2416_DSC0_nRBE_15mA (2 << 26)
+#define S3C2416_DSC0_nRBE_21mA (3 << 26)
+#define S3C2416_DSC0_nRBE_MASK (3 << 26)
+
+#define S3C2416_DSC0_nROE (S3C2416_SELECT_DSC0 | 24)
+#define S3C2416_DSC0_nROE_5mA (0 << 24)
+#define S3C2416_DSC0_nROE_10mA (1 << 24)
+#define S3C2416_DSC0_nROE_15mA (2 << 24)
+#define S3C2416_DSC0_nROE_21mA (3 << 24)
+#define S3C2416_DSC0_nROE_MASK (3 << 24)
+
+#endif
+
#if defined(CONFIG_CPU_S3C244X)
#define S3C2440_DSC0 S3C2410_GPIOREG(0xc4)
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
index fd672f330bf2..a6384239eddf 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
@@ -610,35 +610,73 @@
#define S3C2410_GPHUP S3C2410_GPIOREG(0x78)
#define S3C2410_GPH0_nCTS0 (0x02 << 0)
+#define S3C2416_GPH0_TXD0 (0x02 << 0)
#define S3C2410_GPH1_nRTS0 (0x02 << 2)
+#define S3C2416_GPH1_RXD0 (0x02 << 2)
#define S3C2410_GPH2_TXD0 (0x02 << 4)
+#define S3C2416_GPH2_TXD1 (0x02 << 4)
#define S3C2410_GPH3_RXD0 (0x02 << 6)
+#define S3C2416_GPH3_RXD1 (0x02 << 6)
#define S3C2410_GPH4_TXD1 (0x02 << 8)
+#define S3C2416_GPH4_TXD2 (0x02 << 8)
#define S3C2410_GPH5_RXD1 (0x02 << 10)
+#define S3C2416_GPH5_RXD2 (0x02 << 10)
#define S3C2410_GPH6_TXD2 (0x02 << 12)
+#define S3C2416_GPH6_TXD3 (0x02 << 12)
#define S3C2410_GPH6_nRTS1 (0x03 << 12)
+#define S3C2416_GPH6_nRTS2 (0x03 << 12)
#define S3C2410_GPH7_RXD2 (0x02 << 14)
+#define S3C2416_GPH7_RXD3 (0x02 << 14)
#define S3C2410_GPH7_nCTS1 (0x03 << 14)
+#define S3C2416_GPH7_nCTS2 (0x03 << 14)
#define S3C2410_GPH8_UCLK (0x02 << 16)
+#define S3C2416_GPH8_nCTS0 (0x02 << 16)
#define S3C2410_GPH9_CLKOUT0 (0x02 << 18)
#define S3C2442_GPH9_nSPICS0 (0x03 << 18)
+#define S3C2416_GPH9_nRTS0 (0x02 << 18)
#define S3C2410_GPH10_CLKOUT1 (0x02 << 20)
+#define S3C2416_GPH10_nCTS1 (0x02 << 20)
+
+#define S3C2416_GPH11_nRTS1 (0x02 << 22)
+
+#define S3C2416_GPH12_EXTUARTCLK (0x02 << 24)
+
+#define S3C2416_GPH13_CLKOUT0 (0x02 << 26)
+
+#define S3C2416_GPH14_CLKOUT1 (0x02 << 28)
/* The S3C2412 and S3C2413 move the GPJ register set to after
* GPH, which means all registers after 0x80 are now offset by 0x10
* for the 2412/2413 from the 2410/2440/2442
*/
+/* S3C2443 and above */
+#define S3C2440_GPJCON S3C2410_GPIOREG(0xD0)
+#define S3C2440_GPJDAT S3C2410_GPIOREG(0xD4)
+#define S3C2440_GPJUP S3C2410_GPIOREG(0xD8)
+
+#define S3C2443_GPKCON S3C2410_GPIOREG(0xE0)
+#define S3C2443_GPKDAT S3C2410_GPIOREG(0xE4)
+#define S3C2443_GPKUP S3C2410_GPIOREG(0xE8)
+
+#define S3C2443_GPLCON S3C2410_GPIOREG(0xF0)
+#define S3C2443_GPLDAT S3C2410_GPIOREG(0xF4)
+#define S3C2443_GPLUP S3C2410_GPIOREG(0xF8)
+
+#define S3C2443_GPMCON S3C2410_GPIOREG(0x100)
+#define S3C2443_GPMDAT S3C2410_GPIOREG(0x104)
+#define S3C2443_GPMUP S3C2410_GPIOREG(0x108)
+
/* miscellaneous control */
#define S3C2400_MISCCR S3C2410_GPIOREG(0x54)
#define S3C2410_MISCCR S3C2410_GPIOREG(0x80)
@@ -686,6 +724,7 @@
#define S3C2412_MISCCR_CLK1_CLKsrc (0<<8)
#define S3C2410_MISCCR_USBSUSPND0 (1<<12)
+#define S3C2416_MISCCR_SEL_SUSPND (1<<12)
#define S3C2410_MISCCR_USBSUSPND1 (1<<13)
#define S3C2410_MISCCR_nRSTCON (1<<16)
@@ -695,6 +734,9 @@
#define S3C2410_MISCCR_nEN_SCLKE (1<<19) /* not 2412 */
#define S3C2410_MISCCR_SDSLEEP (7<<17)
+#define S3C2416_MISCCR_FLT_I2C (1<<24)
+#define S3C2416_MISCCR_HSSPI_EN2 (1<<31)
+
/* external interrupt control... */
/* S3C2410_EXTINT0 -> irq sense control for EINT0..EINT7
* S3C2410_EXTINT1 -> irq sense control for EINT8..EINT15
@@ -762,8 +804,11 @@
#define S3C2410_GSTATUS1_IDMASK (0xffff0000)
#define S3C2410_GSTATUS1_2410 (0x32410000)
#define S3C2410_GSTATUS1_2412 (0x32412001)
+#define S3C2410_GSTATUS1_2416 (0x32416003)
#define S3C2410_GSTATUS1_2440 (0x32440000)
#define S3C2410_GSTATUS1_2442 (0x32440aaa)
+/* some 2416 CPUs report this value also */
+#define S3C2410_GSTATUS1_2450 (0x32450003)
#define S3C2410_GSTATUS2_WTRESET (1<<2)
#define S3C2410_GSTATUS2_OFFRESET (1<<1)
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h b/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
index 1202ca5e99f6..19575e061114 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
@@ -22,85 +22,49 @@
* pull up works like all other ports.
*/
-#define S3C2440_GPIO_BANKJ (416)
-
-#define S3C2440_GPJCON S3C2410_GPIOREG(0xd0)
-#define S3C2440_GPJDAT S3C2410_GPIOREG(0xd4)
-#define S3C2440_GPJUP S3C2410_GPIOREG(0xd8)
-
#define S3C2413_GPJCON S3C2410_GPIOREG(0x80)
#define S3C2413_GPJDAT S3C2410_GPIOREG(0x84)
#define S3C2413_GPJUP S3C2410_GPIOREG(0x88)
#define S3C2413_GPJSLPCON S3C2410_GPIOREG(0x8C)
-#define S3C2440_GPJ0 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 0)
-#define S3C2440_GPJ0_INP (0x00 << 0)
#define S3C2440_GPJ0_OUTP (0x01 << 0)
#define S3C2440_GPJ0_CAMDATA0 (0x02 << 0)
-#define S3C2440_GPJ1 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 1)
-#define S3C2440_GPJ1_INP (0x00 << 2)
#define S3C2440_GPJ1_OUTP (0x01 << 2)
#define S3C2440_GPJ1_CAMDATA1 (0x02 << 2)
-#define S3C2440_GPJ2 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 2)
-#define S3C2440_GPJ2_INP (0x00 << 4)
#define S3C2440_GPJ2_OUTP (0x01 << 4)
#define S3C2440_GPJ2_CAMDATA2 (0x02 << 4)
-#define S3C2440_GPJ3 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 3)
-#define S3C2440_GPJ3_INP (0x00 << 6)
#define S3C2440_GPJ3_OUTP (0x01 << 6)
#define S3C2440_GPJ3_CAMDATA3 (0x02 << 6)
-#define S3C2440_GPJ4 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 4)
-#define S3C2440_GPJ4_INP (0x00 << 8)
#define S3C2440_GPJ4_OUTP (0x01 << 8)
#define S3C2440_GPJ4_CAMDATA4 (0x02 << 8)
-#define S3C2440_GPJ5 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 5)
-#define S3C2440_GPJ5_INP (0x00 << 10)
#define S3C2440_GPJ5_OUTP (0x01 << 10)
#define S3C2440_GPJ5_CAMDATA5 (0x02 << 10)
-#define S3C2440_GPJ6 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 6)
-#define S3C2440_GPJ6_INP (0x00 << 12)
#define S3C2440_GPJ6_OUTP (0x01 << 12)
#define S3C2440_GPJ6_CAMDATA6 (0x02 << 12)
-#define S3C2440_GPJ7 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 7)
-#define S3C2440_GPJ7_INP (0x00 << 14)
#define S3C2440_GPJ7_OUTP (0x01 << 14)
#define S3C2440_GPJ7_CAMDATA7 (0x02 << 14)
-#define S3C2440_GPJ8 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 8)
-#define S3C2440_GPJ8_INP (0x00 << 16)
#define S3C2440_GPJ8_OUTP (0x01 << 16)
#define S3C2440_GPJ8_CAMPCLK (0x02 << 16)
-#define S3C2440_GPJ9 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 9)
-#define S3C2440_GPJ9_INP (0x00 << 18)
#define S3C2440_GPJ9_OUTP (0x01 << 18)
#define S3C2440_GPJ9_CAMVSYNC (0x02 << 18)
-#define S3C2440_GPJ10 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 10)
-#define S3C2440_GPJ10_INP (0x00 << 20)
#define S3C2440_GPJ10_OUTP (0x01 << 20)
#define S3C2440_GPJ10_CAMHREF (0x02 << 20)
-#define S3C2440_GPJ11 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 11)
-#define S3C2440_GPJ11_INP (0x00 << 22)
#define S3C2440_GPJ11_OUTP (0x01 << 22)
#define S3C2440_GPJ11_CAMCLKOUT (0x02 << 22)
-#define S3C2440_GPJ12 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 12)
-#define S3C2440_GPJ12_INP (0x00 << 24)
#define S3C2440_GPJ12_OUTP (0x01 << 24)
#define S3C2440_GPJ12_CAMRESET (0x02 << 24)
-#define S3C2443_GPJ13 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 13)
-#define S3C2443_GPJ14 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 14)
-#define S3C2443_GPJ15 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 15)
-
#endif /* __ASM_ARCH_REGS_GPIOJ_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-irq.h b/arch/arm/mach-s3c2410/include/mach/regs-irq.h
index de86ee8812bd..0f07ba30b1fb 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-irq.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-irq.h
@@ -27,6 +27,16 @@
#define S3C2410_SUBSRCPND S3C2410_IRQREG(0x018)
#define S3C2410_INTSUBMSK S3C2410_IRQREG(0x01C)
+#define S3C2416_PRIORITY_MODE1 S3C2410_IRQREG(0x030)
+#define S3C2416_PRIORITY_UPDATE1 S3C2410_IRQREG(0x034)
+#define S3C2416_SRCPND2 S3C2410_IRQREG(0x040)
+#define S3C2416_INTMOD2 S3C2410_IRQREG(0x044)
+#define S3C2416_INTMSK2 S3C2410_IRQREG(0x048)
+#define S3C2416_INTPND2 S3C2410_IRQREG(0x050)
+#define S3C2416_INTOFFSET2 S3C2410_IRQREG(0x054)
+#define S3C2416_PRIORITY_MODE2 S3C2410_IRQREG(0x070)
+#define S3C2416_PRIORITY_UPDATE2 S3C2410_IRQREG(0x074)
+
/* mask: 0=enable, 1=disable
* 1 bit EINT, 4=EINT4, 23=EINT23
* EINT0,1,2,3 are not handled here.
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
new file mode 100644
index 000000000000..2f31b74974af
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
@@ -0,0 +1,30 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ * as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2416 memory register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_S3C2416_MEM
+#define __ASM_ARM_REGS_S3C2416_MEM
+
+#ifndef S3C2416_MEMREG
+#define S3C2416_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
+#endif
+
+#define S3C2416_BANKCFG S3C2416_MEMREG(0x00)
+#define S3C2416_BANKCON1 S3C2416_MEMREG(0x04)
+#define S3C2416_BANKCON2 S3C2416_MEMREG(0x08)
+#define S3C2416_BANKCON3 S3C2416_MEMREG(0x0C)
+
+#define S3C2416_REFRESH S3C2416_MEMREG(0x10)
+#define S3C2416_TIMEOUT S3C2416_MEMREG(0x14)
+
+#endif /* __ASM_ARM_REGS_S3C2416_MEM */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
new file mode 100644
index 000000000000..e443167efb87
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ * as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2416 specific register definitions
+*/
+
+#ifndef __ASM_ARCH_REGS_S3C2416_H
+#define __ASM_ARCH_REGS_S3C2416_H "s3c2416"
+
+#define S3C2416_SWRST (S3C24XX_VA_CLKPWR + 0x44)
+#define S3C2416_SWRST_RESET (0x533C2416)
+
+/* see regs-power.h for the other registers in the power block. */
+
+#endif /* __ASM_ARCH_REGS_S3C2416_H */
+
diff --git a/arch/arm/mach-s3c2410/include/mach/uncompress.h b/arch/arm/mach-s3c2410/include/mach/uncompress.h
index 72f756c5e504..8b283f847daa 100644
--- a/arch/arm/mach-s3c2410/include/mach/uncompress.h
+++ b/arch/arm/mach-s3c2410/include/mach/uncompress.h
@@ -40,7 +40,9 @@ static void arch_detect_cpu(void)
cpuid &= S3C2410_GSTATUS1_IDMASK;
if (is_arm926() || cpuid == S3C2410_GSTATUS1_2440 ||
- cpuid == S3C2410_GSTATUS1_2442) {
+ cpuid == S3C2410_GSTATUS1_2442 ||
+ cpuid == S3C2410_GSTATUS1_2416 ||
+ cpuid == S3C2410_GSTATUS1_2450) {
fifo_mask = S3C2440_UFSTAT_TXMASK;
fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
} else {
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
index 7047317ed7f4..34fc05a4244b 100644
--- a/arch/arm/mach-s3c2410/mach-amlm5900.c
+++ b/arch/arm/mach-s3c2410/mach-amlm5900.c
@@ -56,6 +56,7 @@
#include <plat/iic.h>
#include <plat/devs.h>
#include <plat/cpu.h>
+#include <plat/gpio-cfg.h>
#ifdef CONFIG_MTD_PARTITIONS
@@ -225,8 +226,8 @@ static void amlm5900_init_pm(void)
} else {
enable_irq_wake(IRQ_EINT9);
/* configure the suspend/resume status pin */
- s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT);
- s3c2410_gpio_pullup(S3C2410_GPF(2), 0);
+ s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT);
+ s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_UP);
}
}
static void __init amlm5900_init(void)
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 02b1b6220cba..b061ddcf3067 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -61,6 +61,7 @@
#include <plat/devs.h>
#include <plat/cpu.h>
#include <plat/cpu-freq.h>
+#include <plat/gpio-cfg.h>
#include <plat/audio-simtec.h>
#include "usb-simtec.h"
@@ -216,15 +217,13 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
static int bast_pm_suspend(struct sys_device *sd, pm_message_t state)
{
/* ensure that an nRESET is not generated on resume. */
- s3c2410_gpio_setpin(S3C2410_GPA(21), 1);
- s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
-
+ gpio_direction_output(S3C2410_GPA(21), 1);
return 0;
}
static int bast_pm_resume(struct sys_device *sd)
{
- s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
+ s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
return 0;
}
@@ -658,6 +657,8 @@ static void __init bast_init(void)
nor_simtec_init();
simtec_audio_add(NULL, true, &bast_audio);
+ WARN_ON(gpio_request(S3C2410_GPA(21), "bast nreset"));
+
s3c_cpufreq_setboard(&bast_cpufreq);
}
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index fbedd0760941..9531b4c41deb 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -50,6 +50,7 @@
#include <plat/udc.h>
#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
@@ -207,16 +208,16 @@ static int h1940_backlight_init(struct device *dev)
{
gpio_request(S3C2410_GPB(0), "Backlight");
- s3c2410_gpio_setpin(S3C2410_GPB(0), 0);
- s3c2410_gpio_pullup(S3C2410_GPB(0), 0);
- s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+ gpio_direction_output(S3C2410_GPB(0), 0);
+ s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
return 0;
}
static void h1940_backlight_exit(struct device *dev)
{
- s3c2410_gpio_cfgpin(S3C2410_GPB(0), 1/*S3C2410_GPB0_OUTP*/);
+ gpio_direction_output(S3C2410_GPB(0), 1);
}
static struct platform_pwm_backlight_data backlight_data = {
@@ -245,18 +246,18 @@ static void h1940_lcd_power_set(struct plat_lcd_data *pd,
if (!power) {
/* set to 3ec */
- s3c2410_gpio_setpin(S3C2410_GPC(0), 0);
+ gpio_direction_output(S3C2410_GPC(0), 0);
/* wait for 3ac */
do {
- value = s3c2410_gpio_getpin(S3C2410_GPC(6));
+ value = gpio_get_value(S3C2410_GPC(6));
} while (value);
/* set to 38c */
- s3c2410_gpio_setpin(S3C2410_GPC(5), 0);
+ gpio_direction_output(S3C2410_GPC(5), 0);
} else {
/* Set to 3ac */
- s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
+ gpio_direction_output(S3C2410_GPC(5), 1);
/* Set to 3ad */
- s3c2410_gpio_setpin(S3C2410_GPC(0), 1);
+ gpio_direction_output(S3C2410_GPC(0), 1);
}
}
@@ -332,6 +333,7 @@ static void __init h1940_init(void)
gpio_request(S3C2410_GPC(5), "LCD power");
gpio_request(S3C2410_GPC(6), "LCD power");
+ gpio_direction_input(S3C2410_GPC(6));
platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
}
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index 684710f88142..75a9fd37a467 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -86,10 +86,10 @@ static void n30_udc_pullup(enum s3c2410_udc_cmd_e cmd)
{
switch (cmd) {
case S3C2410_UDC_P_ENABLE :
- s3c2410_gpio_setpin(S3C2410_GPB(3), 1);
+ gpio_set_value(S3C2410_GPB(3), 1);
break;
case S3C2410_UDC_P_DISABLE :
- s3c2410_gpio_setpin(S3C2410_GPB(3), 0);
+ gpio_set_value(S3C2410_GPB(3), 0);
break;
case S3C2410_UDC_P_RESET :
break;
@@ -536,6 +536,9 @@ static void __init n30_init(void)
platform_add_devices(n35_devices, ARRAY_SIZE(n35_devices));
}
+
+ WARN_ON(gpio_request(S3C2410_GPB(3), "udc pup"));
+ gpio_direction_output(S3C2410_GPB(3), 0);
}
MACHINE_START(N30, "Acer-N30")
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
index 92a4ec375d82..d0e87b6e2e0f 100644
--- a/arch/arm/mach-s3c2410/mach-qt2410.c
+++ b/arch/arm/mach-s3c2410/mach-qt2410.c
@@ -58,6 +58,7 @@
#include <plat/iic.h>
#include <plat/common-smdk.h>
+#include <plat/gpio-cfg.h>
#include <plat/devs.h>
#include <plat/cpu.h>
#include <plat/pm.h>
@@ -219,10 +220,10 @@ static void spi_gpio_cs(struct s3c2410_spigpio_info *spi, int cs)
{
switch (cs) {
case BITBANG_CS_ACTIVE:
- s3c2410_gpio_setpin(S3C2410_GPB(5), 0);
+ gpio_set_value(S3C2410_GPB(5), 0);
break;
case BITBANG_CS_INACTIVE:
- s3c2410_gpio_setpin(S3C2410_GPB(5), 1);
+ gpio_set_value(S3C2410_GPB(5), 1);
break;
}
}
@@ -347,13 +348,14 @@ static void __init qt2410_machine_init(void)
}
s3c24xx_fb_set_platdata(&qt2410_fb_info);
- s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
+ s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_setpin(S3C2410_GPB(0), 1);
s3c24xx_udc_set_platdata(&qt2410_udc_cfg);
s3c_i2c0_set_platdata(NULL);
- s3c2410_gpio_cfgpin(S3C2410_GPB(5), S3C2410_GPIO_OUTPUT);
+ WARN_ON(gpio_request(S3C2410_GPB(5), "spi cs"));
+ gpio_direction_output(S3C2410_GPB(5), 1);
platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices));
s3c_pm_init();
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 9051f0d31123..d540d79dd264 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -357,8 +357,7 @@ static struct clk *vr1000_clocks[] __initdata = {
static void vr1000_power_off(void)
{
- s3c2410_gpio_cfgpin(S3C2410_GPB(9), S3C2410_GPIO_OUTPUT);
- s3c2410_gpio_setpin(S3C2410_GPB(9), 1);
+ gpio_direction_output(S3C2410_GPB(9), 1);
}
static void __init vr1000_map_io(void)
@@ -395,6 +394,8 @@ static void __init vr1000_init(void)
nor_simtec_init();
simtec_audio_add(NULL, true, NULL);
+
+ WARN_ON(gpio_request(S3C2410_GPB(9), "power off"));
}
MACHINE_START(VR1000, "Thorcom-VR1000")
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index 91ba42f688ac..adc90a3c5890 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -16,6 +16,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
+#include <linux/gpio.h>
#include <linux/clk.h>
#include <linux/sysdev.h>
#include <linux/serial_core.h>
@@ -40,6 +41,10 @@
#include <plat/clock.h>
#include <plat/pll.h>
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
/* Initial IO mappings */
static struct map_desc s3c2410_iodesc[] __initdata = {
@@ -65,6 +70,9 @@ void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no)
void __init s3c2410_map_io(void)
{
+ s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
+ s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
+
iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
}
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
index 9a8c0657ae50..cef6a65637bd 100644
--- a/arch/arm/mach-s3c2412/Kconfig
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -16,7 +16,8 @@ config CPU_S3C2412
config CPU_S3C2412_ONLY
bool
depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
- !CPU_S3C2440 && !CPU_S3C2442 && !CPU_S3C2443 && CPU_S3C2412
+ !CPU_2416 && !CPU_S3C2440 && !CPU_S3C2442 && \
+ !CPU_S3C2443 && CPU_S3C2412
default y if CPU_S3C2412
config S3C2412_DMA
diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c
index 14f4798291aa..43160183571a 100644
--- a/arch/arm/mach-s3c2412/mach-jive.c
+++ b/arch/arm/mach-s3c2412/mach-jive.c
@@ -48,6 +48,7 @@
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
+#include <plat/gpio-cfg.h>
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
@@ -357,8 +358,7 @@ static void jive_lcm_reset(unsigned int set)
{
printk(KERN_DEBUG "%s(%d)\n", __func__, set);
- s3c2410_gpio_setpin(S3C2410_GPG(13), set);
- s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_OUTPUT);
+ gpio_set_value(S3C2410_GPG(13), set);
}
#undef LCD_UPPER_MARGIN
@@ -391,7 +391,7 @@ static struct ili9320_platdata jive_lcm_config = {
static void jive_lcd_spi_chipselect(struct s3c2410_spigpio_info *spi, int cs)
{
- s3c2410_gpio_setpin(S3C2410_GPB(7), cs ? 0 : 1);
+ gpio_set_value(S3C2410_GPB(7), cs ? 0 : 1);
}
static struct s3c2410_spigpio_info jive_lcd_spi = {
@@ -413,7 +413,7 @@ static struct platform_device jive_device_lcdspi = {
static void jive_wm8750_chipselect(struct s3c2410_spigpio_info *spi, int cs)
{
- s3c2410_gpio_setpin(S3C2410_GPH(10), cs ? 0 : 1);
+ gpio_set_value(S3C2410_GPH(10), cs ? 0 : 1);
}
static struct s3c2410_spigpio_info jive_wm8750_spi = {
@@ -531,7 +531,7 @@ static void jive_power_off(void)
printk(KERN_INFO "powering system down...\n");
s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
- s3c2410_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT);
+ s3c_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT);
}
static void __init jive_machine_init(void)
@@ -636,22 +636,22 @@ static void __init jive_machine_init(void)
/* initialise the spi */
- s3c2410_gpio_setpin(S3C2410_GPG(13), 0);
- s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_OUTPUT);
+ gpio_request(S3C2410_GPG(13), "lcm reset");
+ gpio_direction_output(S3C2410_GPG(13), 0);
- s3c2410_gpio_setpin(S3C2410_GPB(7), 1);
- s3c2410_gpio_cfgpin(S3C2410_GPB(7), S3C2410_GPIO_OUTPUT);
+ gpio_request(S3C2410_GPB(7), "jive spi");
+ gpio_direction_output(S3C2410_GPB(7), 1);
s3c2410_gpio_setpin(S3C2410_GPB(6), 0);
- s3c2410_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT);
+ s3c_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_setpin(S3C2410_GPG(8), 1);
- s3c2410_gpio_cfgpin(S3C2410_GPG(8), S3C2410_GPIO_OUTPUT);
+ s3c_gpio_cfgpin(S3C2410_GPG(8), S3C2410_GPIO_OUTPUT);
/* initialise the WM8750 spi */
- s3c2410_gpio_setpin(S3C2410_GPH(10), 1);
- s3c2410_gpio_cfgpin(S3C2410_GPH(10), S3C2410_GPIO_OUTPUT);
+ gpio_request(S3C2410_GPH(10), "jive wm8750 spi");
+ gpio_direction_output(S3C2410_GPH(10), 1);
/* Turn off suspend on both USB ports, and switch the
* selectable USB port to USB device mode. */
diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c
index 0392065af1af..faddb36ed23b 100644
--- a/arch/arm/mach-s3c2412/mach-smdk2413.c
+++ b/arch/arm/mach-s3c2412/mach-smdk2413.c
@@ -85,10 +85,10 @@ static void smdk2413_udc_pullup(enum s3c2410_udc_cmd_e cmd)
switch (cmd)
{
case S3C2410_UDC_P_ENABLE :
- s3c2410_gpio_setpin(S3C2410_GPF(2), 1);
+ gpio_set_value(S3C2410_GPF(2), 1);
break;
case S3C2410_UDC_P_DISABLE :
- s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
+ gpio_set_value(S3C2410_GPF(2), 0);
break;
case S3C2410_UDC_P_RESET :
break;
@@ -134,8 +134,8 @@ static void __init smdk2413_machine_init(void)
{ /* Turn off suspend on both USB ports, and switch the
* selectable USB port to USB device mode. */
- s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
- s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT);
+ WARN_ON(gpio_request(S3C2410_GPF(2), "udc pull"));
+ gpio_direction_output(S3C2410_GPF(2), 0);
s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
S3C2410_MISCCR_USBSUSPND0 |
diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig
new file mode 100644
index 000000000000..29103a6047de
--- /dev/null
+++ b/arch/arm/mach-s3c2416/Kconfig
@@ -0,0 +1,38 @@
+# arch/arm/mach-s3c2416/Kconfig
+#
+# Copyright 2009 Yauhen Kharuzhy <jekhor@gmail.com>
+#
+# Licensed under GPLv2
+
+# note, this also supports the S3C2450 which is so similar it has the same
+# ID code as the S3C2416.
+
+config CPU_S3C2416
+ bool
+ depends on ARCH_S3C2410
+ select CPU_ARM926T
+ select S3C2416_DMA if S3C2410_DMA
+ select CPU_LLSERIAL_S3C2440
+ select S3C_GPIO_PULL_UPDOWN
+ select SAMSUNG_CLKSRC
+ select S3C2443_CLOCK
+ help
+ Support for the S3C2416 SoC from the S3C24XX line
+
+config S3C2416_DMA
+ bool
+ depends on CPU_S3C2416
+ help
+ Internal config node for S3C2416 DMA support
+
+menu "S3C2416 Machines"
+
+config MACH_SMDK2416
+ bool "SMDK2416"
+ select CPU_S3C2416
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ help
+ Say Y here if you are using an SMDK2416
+
+endmenu
diff --git a/arch/arm/mach-s3c2416/Makefile b/arch/arm/mach-s3c2416/Makefile
new file mode 100644
index 000000000000..6c12c7bf40ad
--- /dev/null
+++ b/arch/arm/mach-s3c2416/Makefile
@@ -0,0 +1,19 @@
+# arch/arm/mach-s3c2416/Makefile
+#
+# Copyright 2009 Yauhen Kharuzhy <jekhor@gmail.com>
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_CPU_S3C2416) += s3c2416.o clock.o
+obj-$(CONFIG_CPU_S3C2416) += irq.o
+
+#obj-$(CONFIG_S3C2416_DMA) += dma.o
+
+# Machine support
+
+obj-$(CONFIG_MACH_SMDK2416) += mach-smdk2416.o
diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c
new file mode 100644
index 000000000000..7ccf5a2a2bfc
--- /dev/null
+++ b/arch/arm/mach-s3c2416/clock.c
@@ -0,0 +1,135 @@
+/* linux/arch/arm/mach-s3c2416/clock.c
+ *
+ * Copyright (c) 2010 Simtec Electronics
+ * Copyright (c) 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * S3C2416 Clock control support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+
+#include <plat/s3c2416.h>
+#include <plat/s3c2443.h>
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/cpu.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/pll6553x.h>
+#include <plat/pll.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-s3c2443-clock.h>
+
+static unsigned int armdiv[8] = {
+ [0] = 1,
+ [1] = 2,
+ [2] = 3,
+ [3] = 4,
+ [5] = 6,
+ [7] = 8,
+};
+
+/* ID to hardware numbering, 0 is HSMMC1, 1 is HSMMC0 */
+static struct clksrc_clk hsmmc_div[] = {
+ [0] = {
+ .clk = {
+ .name = "hsmmc-div",
+ .id = 1,
+ .parent = &clk_esysclk.clk,
+ },
+ .reg_div = { .reg = S3C2416_CLKDIV2, .size = 2, .shift = 6 },
+ },
+ [1] = {
+ .clk = {
+ .name = "hsmmc-div",
+ .id = 0,
+ .parent = &clk_esysclk.clk,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
+ },
+};
+
+static struct clksrc_clk hsmmc_mux[] = {
+ [0] = {
+ .clk = {
+ .id = 1,
+ .name = "hsmmc-if",
+ .ctrlbit = (1 << 6),
+ .enable = s3c2443_clkcon_enable_s,
+ },
+ .sources = &(struct clksrc_sources) {
+ .nr_sources = 2,
+ .sources = (struct clk *[]) {
+ [0] = &hsmmc_div[0].clk,
+ [1] = NULL, /* to fix */
+ },
+ },
+ .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 16 },
+ },
+ [1] = {
+ .clk = {
+ .id = 0,
+ .name = "hsmmc-if",
+ .ctrlbit = (1 << 12),
+ .enable = s3c2443_clkcon_enable_s,
+ },
+ .sources = &(struct clksrc_sources) {
+ .nr_sources = 2,
+ .sources = (struct clk *[]) {
+ [0] = &hsmmc_div[1].clk,
+ [1] = NULL, /* to fix */
+ },
+ },
+ .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 17 },
+ },
+};
+
+
+static inline unsigned int s3c2416_fclk_div(unsigned long clkcon0)
+{
+ clkcon0 &= 7 << S3C2443_CLKDIV0_ARMDIV_SHIFT;
+
+ return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
+}
+
+void __init_or_cpufreq s3c2416_setup_clocks(void)
+{
+ s3c2443_common_setup_clocks(s3c2416_get_pll, s3c2416_fclk_div);
+}
+
+
+static struct clksrc_clk *clksrcs[] __initdata = {
+ &hsmmc_div[0],
+ &hsmmc_div[1],
+ &hsmmc_mux[0],
+ &hsmmc_mux[1],
+};
+
+void __init s3c2416_init_clocks(int xtal)
+{
+ u32 epllcon = __raw_readl(S3C2443_EPLLCON);
+ u32 epllcon1 = __raw_readl(S3C2443_EPLLCON+4);
+ int ptr;
+
+ /* s3c2416 EPLL compatible with s3c64xx */
+ clk_epll.rate = s3c_get_pll6553x(xtal, epllcon, epllcon1);
+
+ clk_epll.parent = &clk_epllref.clk;
+
+ s3c2443_common_init_clocks(xtal, s3c2416_get_pll, s3c2416_fclk_div);
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+ s3c_register_clksrc(clksrcs[ptr], 1);
+
+ s3c_pwmclk_init();
+
+}
diff --git a/arch/arm/mach-s3c2416/irq.c b/arch/arm/mach-s3c2416/irq.c
new file mode 100644
index 000000000000..89f521d59d06
--- /dev/null
+++ b/arch/arm/mach-s3c2416/irq.c
@@ -0,0 +1,254 @@
+/* linux/arch/arm/mach-s3c2416/irq.c
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ * as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+
+#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+
+static inline void s3c2416_irq_demux(unsigned int irq, unsigned int len)
+{
+ unsigned int subsrc, submsk;
+ unsigned int end;
+
+ /* read the current pending interrupts, and the mask
+ * for what it is available */
+
+ subsrc = __raw_readl(S3C2410_SUBSRCPND);
+ submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+ subsrc &= ~submsk;
+ subsrc >>= (irq - S3C2410_IRQSUB(0));
+ subsrc &= (1 << len)-1;
+
+ end = len + irq;
+
+ for (; irq < end && subsrc; irq++) {
+ if (subsrc & 1)
+ generic_handle_irq(irq);
+
+ subsrc >>= 1;
+ }
+}
+
+/* WDT/AC97 sub interrupts */
+
+static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
+{
+ s3c2416_irq_demux(IRQ_S3C2443_WDT, 4);
+}
+
+#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
+#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
+
+static void s3c2416_irq_wdtac97_mask(unsigned int irqno)
+{
+ s3c_irqsub_mask(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static void s3c2416_irq_wdtac97_unmask(unsigned int irqno)
+{
+ s3c_irqsub_unmask(irqno, INTMSK_WDTAC97);
+}
+
+static void s3c2416_irq_wdtac97_ack(unsigned int irqno)
+{
+ s3c_irqsub_maskack(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static struct irq_chip s3c2416_irq_wdtac97 = {
+ .mask = s3c2416_irq_wdtac97_mask,
+ .unmask = s3c2416_irq_wdtac97_unmask,
+ .ack = s3c2416_irq_wdtac97_ack,
+};
+
+
+/* LCD sub interrupts */
+
+static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
+{
+ s3c2416_irq_demux(IRQ_S3C2443_LCD1, 4);
+}
+
+#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0))
+#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
+
+static void s3c2416_irq_lcd_mask(unsigned int irqno)
+{
+ s3c_irqsub_mask(irqno, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static void s3c2416_irq_lcd_unmask(unsigned int irqno)
+{
+ s3c_irqsub_unmask(irqno, INTMSK_LCD);
+}
+
+static void s3c2416_irq_lcd_ack(unsigned int irqno)
+{
+ s3c_irqsub_maskack(irqno, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static struct irq_chip s3c2416_irq_lcd = {
+ .mask = s3c2416_irq_lcd_mask,
+ .unmask = s3c2416_irq_lcd_unmask,
+ .ack = s3c2416_irq_lcd_ack,
+};
+
+
+/* DMA sub interrupts */
+
+static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
+{
+ s3c2416_irq_demux(IRQ_S3C2443_DMA0, 6);
+}
+
+#define INTMSK_DMA (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
+#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
+
+
+static void s3c2416_irq_dma_mask(unsigned int irqno)
+{
+ s3c_irqsub_mask(irqno, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static void s3c2416_irq_dma_unmask(unsigned int irqno)
+{
+ s3c_irqsub_unmask(irqno, INTMSK_DMA);
+}
+
+static void s3c2416_irq_dma_ack(unsigned int irqno)
+{
+ s3c_irqsub_maskack(irqno, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static struct irq_chip s3c2416_irq_dma = {
+ .mask = s3c2416_irq_dma_mask,
+ .unmask = s3c2416_irq_dma_unmask,
+ .ack = s3c2416_irq_dma_ack,
+};
+
+
+/* UART3 sub interrupts */
+
+static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
+{
+ s3c2416_irq_demux(IRQ_S3C2443_UART3, 3);
+}
+
+#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
+#define SUBMSK_UART3 (0xf << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
+
+
+static void s3c2416_irq_uart3_mask(unsigned int irqno)
+{
+ s3c_irqsub_mask(irqno, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static void s3c2416_irq_uart3_unmask(unsigned int irqno)
+{
+ s3c_irqsub_unmask(irqno, INTMSK_UART3);
+}
+
+static void s3c2416_irq_uart3_ack(unsigned int irqno)
+{
+ s3c_irqsub_maskack(irqno, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static struct irq_chip s3c2416_irq_uart3 = {
+ .mask = s3c2416_irq_uart3_mask,
+ .unmask = s3c2416_irq_uart3_unmask,
+ .ack = s3c2416_irq_uart3_ack,
+};
+
+
+/* IRQ initialisation code */
+
+static int __init s3c2416_add_sub(unsigned int base,
+ void (*demux)(unsigned int,
+ struct irq_desc *),
+ struct irq_chip *chip,
+ unsigned int start, unsigned int end)
+{
+ unsigned int irqno;
+
+ set_irq_chip(base, &s3c_irq_level_chip);
+ set_irq_handler(base, handle_level_irq);
+ set_irq_chained_handler(base, demux);
+
+ for (irqno = start; irqno <= end; irqno++) {
+ set_irq_chip(irqno, chip);
+ set_irq_handler(irqno, handle_level_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+
+ return 0;
+}
+
+static int __init s3c2416_irq_add(struct sys_device *sysdev)
+{
+ printk(KERN_INFO "S3C2416: IRQ Support\n");
+
+ s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd,
+ IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4);
+
+ s3c2416_add_sub(IRQ_S3C2443_DMA, s3c2416_irq_demux_dma,
+ &s3c2416_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
+
+ s3c2416_add_sub(IRQ_S3C2443_UART3, s3c2416_irq_demux_uart3,
+ &s3c2416_irq_uart3,
+ IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
+
+ s3c2416_add_sub(IRQ_WDT, s3c2416_irq_demux_wdtac97,
+ &s3c2416_irq_wdtac97,
+ IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
+
+ return 0;
+}
+
+static struct sysdev_driver s3c2416_irq_driver = {
+ .add = s3c2416_irq_add,
+};
+
+static int __init s3c2416_irq_init(void)
+{
+ return sysdev_driver_register(&s3c2416_sysclass, &s3c2416_irq_driver);
+}
+
+arch_initcall(s3c2416_irq_init);
+
diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c2416/mach-smdk2416.c
new file mode 100644
index 000000000000..99d24c44f30f
--- /dev/null
+++ b/arch/arm/mach-s3c2416/mach-smdk2416.c
@@ -0,0 +1,150 @@
+/* linux/arch/arm/mach-s3c2416/mach-hanlin_v3c.c
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ * as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mtd/partitions.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/idle.h>
+#include <mach/fb.h>
+#include <mach/leds-gpio.h>
+#include <plat/iic.h>
+
+#include <plat/s3c2416.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/nand.h>
+
+#include <plat/common-smdk.h>
+
+static struct map_desc smdk2416_iodesc[] __initdata = {
+ /* ISA IO Space map (memory space selected by A24) */
+
+ {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD,
+ .pfn = __phys_to_pfn(S3C2410_CS2),
+ .length = 0x10000,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
+ .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+ .length = SZ_4M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE,
+ .pfn = __phys_to_pfn(S3C2410_CS2),
+ .length = 0x10000,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
+ .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+ .length = SZ_4M,
+ .type = MT_DEVICE,
+ }
+};
+
+#define UCON (S3C2410_UCON_DEFAULT | \
+ S3C2440_UCON_PCLK | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
+
+#define UFCON (S3C2410_UFCON_RXTRIG8 | \
+ S3C2410_UFCON_FIFOMODE | \
+ S3C2440_UFCON_TXTRIG16)
+
+static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ /* IR port */
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON | 0x50,
+ .ufcon = UFCON,
+ }
+};
+
+static struct platform_device *smdk2416_devices[] __initdata = {
+ &s3c_device_wdt,
+ &s3c_device_ohci,
+ &s3c_device_i2c0,
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc1,
+};
+
+static void __init smdk2416_map_io(void)
+{
+
+ s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs));
+
+}
+
+static void __init smdk2416_machine_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+
+ gpio_request(S3C2410_GPB(4), "USBHost Power");
+ gpio_direction_output(S3C2410_GPB(4), 1);
+
+ platform_add_devices(smdk2416_devices, ARRAY_SIZE(smdk2416_devices));
+ smdk_machine_init();
+}
+
+MACHINE_START(SMDK2416, "SMDK2416")
+ /* Maintainer: Yauhen Kharuzhy <jekhor@gmail.com> */
+ .phys_io = S3C2410_PA_UART,
+ .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+
+ .init_irq = s3c24xx_init_irq,
+ .map_io = smdk2416_map_io,
+ .init_machine = smdk2416_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c
new file mode 100644
index 000000000000..3bff05745d0b
--- /dev/null
+++ b/arch/arm/mach-s3c2416/s3c2416.c
@@ -0,0 +1,128 @@
+/* linux/arch/arm/mach-s3c2416/s3c2416.c
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ * as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+ *
+ * Samsung S3C2416 Mobile CPU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/proc-fns.h>
+#include <asm/irq.h>
+
+#include <mach/reset.h>
+#include <mach/idle.h>
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <plat/s3c2416.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include <plat/iic-core.h>
+
+static struct map_desc s3c2416_iodesc[] __initdata = {
+ IODESC_ENT(WATCHDOG),
+ IODESC_ENT(CLKPWR),
+ IODESC_ENT(TIMER),
+};
+
+struct sysdev_class s3c2416_sysclass = {
+ .name = "s3c2416-core",
+};
+
+static struct sys_device s3c2416_sysdev = {
+ .cls = &s3c2416_sysclass,
+};
+
+static void s3c2416_hard_reset(void)
+{
+ __raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST);
+}
+
+int __init s3c2416_init(void)
+{
+ printk(KERN_INFO "S3C2416: Initializing architecture\n");
+
+ s3c24xx_reset_hook = s3c2416_hard_reset;
+ /* s3c24xx_idle = s3c2416_idle; */
+
+ /* change WDT IRQ number */
+ s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT;
+ s3c_device_wdt.resource[1].end = IRQ_S3C2443_WDT;
+
+ /* the i2c devices are directly compatible with s3c2440 */
+ s3c_i2c0_setname("s3c2440-i2c");
+ s3c_i2c1_setname("s3c2440-i2c");
+
+ return sysdev_register(&s3c2416_sysdev);
+}
+
+void __init s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
+
+ s3c_device_nand.name = "s3c2416-nand";
+}
+
+/* s3c2416_map_io
+ *
+ * register the standard cpu IO areas, and any passed in from the
+ * machine specific initialisation.
+ */
+
+void __init s3c2416_map_io(void)
+{
+ s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_updown;
+ s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_updown;
+
+ iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc));
+}
+
+/* need to register class before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2416 based system)
+ * as a driver which may support both 2443 and 2440 may try and use it.
+*/
+
+static int __init s3c2416_core_init(void)
+{
+ return sysdev_class_register(&s3c2416_sysclass);
+}
+
+core_initcall(s3c2416_core_init);
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index 7f465265cf04..9d102b912091 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -6,6 +6,7 @@ config CPU_S3C2440
bool
depends on ARCH_S3C2410
select CPU_ARM920T
+ select S3C_GPIO_PULL_UP
select S3C2410_CLOCK
select S3C2410_PM if PM
select S3C2410_GPIO
diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c2440/mach-mini2440.c
index 571b17683d96..a76bcda210ad 100644
--- a/arch/arm/mach-s3c2440/mach-mini2440.c
+++ b/arch/arm/mach-s3c2440/mach-mini2440.c
@@ -53,6 +53,7 @@
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
+#include <plat/gpio-cfg.h>
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
@@ -102,10 +103,10 @@ static void mini2440_udc_pullup(enum s3c2410_udc_cmd_e cmd)
switch (cmd) {
case S3C2410_UDC_P_ENABLE :
- s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
+ gpio_set_value(S3C2410_GPC(5), 1);
break;
case S3C2410_UDC_P_DISABLE :
- s3c2410_gpio_setpin(S3C2410_GPC(5), 0);
+ gpio_set_value(S3C2410_GPC(5), 0);
break;
case S3C2410_UDC_P_RESET :
break;
@@ -632,25 +633,25 @@ static void __init mini2440_init(void)
mini2440_parse_features(&features, mini2440_features_str);
/* turn LCD on */
- s3c2410_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);
+ s3c_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);
/* Turn the backlight early on */
- s3c2410_gpio_setpin(S3C2410_GPG(4), 1);
- s3c2410_gpio_cfgpin(S3C2410_GPG(4), S3C2410_GPIO_OUTPUT);
+ WARN_ON(gpio_request(S3C2410_GPG(4), "backlight"));
+ gpio_direction_output(S3C2410_GPG(4), 1);
/* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */
- s3c2410_gpio_pullup(S3C2410_GPB(1), 0);
+ s3c_gpio_setpull(S3C2410_GPB(1), S3C_GPIO_PULL_UP);
s3c2410_gpio_setpin(S3C2410_GPB(1), 0);
- s3c2410_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT);
+ s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT);
/* Make sure the D+ pullup pin is output */
- s3c2410_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT);
+ WARN_ON(gpio_request(S3C2410_GPC(5), "udc pup"));
+ gpio_direction_output(S3C2410_GPC(5), 0);
/* mark the key as input, without pullups (there is one on the board) */
for (i = 0; i < ARRAY_SIZE(mini2440_buttons); i++) {
- s3c2410_gpio_pullup(mini2440_buttons[i].gpio, 0);
- s3c2410_gpio_cfgpin(mini2440_buttons[i].gpio,
- S3C2410_GPIO_INPUT);
+ s3c_gpio_setpull(mini2440_buttons[i].gpio, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(mini2440_buttons[i].gpio, S3C2410_GPIO_INPUT);
}
if (features.lcd_index != -1) {
int li;
diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c
index 342041593f22..3ff62de45fde 100644
--- a/arch/arm/mach-s3c2440/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2440/mach-nexcoder.c
@@ -40,6 +40,7 @@
#include <plat/regs-serial.h>
#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
#include <plat/s3c2410.h>
#include <plat/s3c244x.h>
#include <plat/clock.h>
@@ -122,15 +123,15 @@ static void __init nexcoder_sensorboard_init(void)
{
// Initialize SCCB bus
s3c2410_gpio_setpin(S3C2410_GPE(14), 1); // IICSCL
- s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_OUTPUT);
+ s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_setpin(S3C2410_GPE(15), 1); // IICSDA
- s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_OUTPUT);
+ s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_OUTPUT);
// Power up the sensor board
s3c2410_gpio_setpin(S3C2410_GPF(1), 1);
- s3c2410_gpio_cfgpin(S3C2410_GPF(1), S3C2410_GPIO_OUTPUT); // CAM_GPIO7 => nLDO_PWRDN
+ s3c_gpio_cfgpin(S3C2410_GPF(1), S3C2410_GPIO_OUTPUT); // CAM_GPIO7 => nLDO_PWRDN
s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
- s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); // CAM_GPIO6 => CAM_PWRDN
+ s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); // CAM_GPIO6 => CAM_PWRDN
}
static void __init nexcoder_map_io(void)
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index f35371db33f5..319458da71a0 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -49,6 +49,7 @@
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
+#include <plat/gpio-cfg.h>
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
@@ -298,7 +299,7 @@ static int osiris_pm_suspend(struct sys_device *sd, pm_message_t state)
/* ensure that an nRESET is not generated on resume. */
s3c2410_gpio_setpin(S3C2410_GPA(21), 1);
- s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
+ s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
return 0;
}
@@ -310,7 +311,7 @@ static int osiris_pm_resume(struct sys_device *sd)
__raw_writeb(pm_osiris_ctrl0, OSIRIS_VA_CTRL0);
- s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
+ s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
return 0;
}
diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c
index 2b68f7ea45ae..d50f3ae6173d 100644
--- a/arch/arm/mach-s3c2440/s3c2440.c
+++ b/arch/arm/mach-s3c2440/s3c2440.c
@@ -19,6 +19,7 @@
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/sysdev.h>
+#include <linux/gpio.h>
#include <linux/clk.h>
#include <linux/io.h>
@@ -33,6 +34,10 @@
#include <plat/cpu.h>
#include <plat/s3c244x.h>
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
static struct sys_device s3c2440_sysdev = {
.cls = &s3c2440_sysclass,
};
@@ -41,6 +46,9 @@ int __init s3c2440_init(void)
{
printk("S3C2440: Initialising architecture\n");
+ s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
+ s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
+
/* change irq for watchdog */
s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig
index 698140af247c..4fef723126fa 100644
--- a/arch/arm/mach-s3c2443/Kconfig
+++ b/arch/arm/mach-s3c2443/Kconfig
@@ -8,6 +8,7 @@ config CPU_S3C2443
select S3C2443_DMA if S3C2410_DMA
select CPU_LLSERIAL_S3C2440
select SAMSUNG_CLKSRC
+ select S3C2443_CLOCK
help
Support for the S3C2443 SoC from the S3C24XX line
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index 62cd4eaee01b..83b1aa63d778 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -21,6 +21,7 @@
*/
#include <linux/init.h>
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
@@ -54,111 +55,13 @@
* set the correct muxing at initialisation
*/
-static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
-{
- u32 ctrlbit = clk->ctrlbit;
- u32 con = __raw_readl(reg);
-
- if (enable)
- con |= ctrlbit;
- else
- con &= ~ctrlbit;
-
- __raw_writel(con, reg);
- return 0;
-}
-
-static int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
-{
- return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
-}
-
-static int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
-{
- return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
-}
-
-static int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
-{
- return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
-}
-
/* clock selections */
-/* mpllref is a direct descendant of clk_xtal by default, but it is not
- * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
- * such directly equating the two source clocks is impossible.
- */
-static struct clk clk_mpllref = {
- .name = "mpllref",
- .parent = &clk_xtal,
- .id = -1,
-};
-
static struct clk clk_i2s_ext = {
.name = "i2s-ext",
.id = -1,
};
-static struct clk *clk_epllref_sources[] = {
- [0] = &clk_mpllref,
- [1] = &clk_mpllref,
- [2] = &clk_xtal,
- [3] = &clk_ext,
-};
-
-static struct clksrc_clk clk_epllref = {
- .clk = {
- .name = "epllref",
- .id = -1,
- },
- .sources = &(struct clksrc_sources) {
- .sources = clk_epllref_sources,
- .nr_sources = ARRAY_SIZE(clk_epllref_sources),
- },
- .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
-};
-
-static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- unsigned long div = __raw_readl(S3C2443_CLKDIV0);
-
- div &= S3C2443_CLKDIV0_EXTDIV_MASK;
- div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1); /* x2 */
-
- return parent_rate / (div + 1);
-}
-
-static struct clk clk_mdivclk = {
- .name = "mdivclk",
- .parent = &clk_mpllref,
- .id = -1,
- .ops = &(struct clk_ops) {
- .get_rate = s3c2443_getrate_mdivclk,
- },
-};
-
-static struct clk *clk_msysclk_sources[] = {
- [0] = &clk_mpllref,
- [1] = &clk_mpll,
- [2] = &clk_mdivclk,
- [3] = &clk_mpllref,
-};
-
-static struct clksrc_clk clk_msysclk = {
- .clk = {
- .name = "msysclk",
- .parent = &clk_xtal,
- .id = -1,
- },
- .sources = &(struct clksrc_sources) {
- .sources = clk_msysclk_sources,
- .nr_sources = ARRAY_SIZE(clk_msysclk_sources),
- },
- .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
-};
-
/* armdiv
*
* this clock is sourced from msysclk and can have a number of
@@ -266,44 +169,6 @@ static struct clksrc_clk clk_arm = {
.reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
};
-/* esysclk
- *
- * this is sourced from either the EPLL or the EPLLref clock
-*/
-
-static struct clk *clk_sysclk_sources[] = {
- [0] = &clk_epllref.clk,
- [1] = &clk_epll,
-};
-
-static struct clksrc_clk clk_esysclk = {
- .clk = {
- .name = "esysclk",
- .parent = &clk_epll,
- .id = -1,
- },
- .sources = &(struct clksrc_sources) {
- .sources = clk_sysclk_sources,
- .nr_sources = ARRAY_SIZE(clk_sysclk_sources),
- },
- .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
-};
-
-/* uartclk
- *
- * UART baud-rate clock sourced from esysclk via a divisor
-*/
-
-static struct clksrc_clk clk_uart = {
- .clk = {
- .name = "uartclk",
- .id = -1,
- .parent = &clk_esysclk.clk,
- },
- .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
-};
-
-
/* hsspi
*
* high-speed spi clock, sourced from esysclk
@@ -320,21 +185,6 @@ static struct clksrc_clk clk_hsspi = {
.reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
};
-/* usbhost
- *
- * usb host bus-clock, usually 48MHz to provide USB bus clock timing
-*/
-
-static struct clksrc_clk clk_usb_bus_host = {
- .clk = {
- .name = "usb-bus-host-parent",
- .id = -1,
- .parent = &clk_esysclk.clk,
- .ctrlbit = S3C2443_SCLKCON_USBHOST,
- .enable = s3c2443_clkcon_enable_s,
- },
- .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
-};
/* clk_hsmcc_div
*
@@ -433,89 +283,16 @@ static struct clksrc_clk clk_i2s = {
.reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
};
-/* cam-if
- *
- * camera interface bus-clock, divided down from esysclk
-*/
-
-static struct clksrc_clk clk_cam = {
- .clk = {
- .name = "camif-upll", /* same as 2440 name */
- .id = -1,
- .parent = &clk_esysclk.clk,
- .ctrlbit = S3C2443_SCLKCON_CAMCLK,
- .enable = s3c2443_clkcon_enable_s,
- },
- .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
-};
-
-/* display-if
- *
- * display interface clock, divided from esysclk
-*/
-
-static struct clksrc_clk clk_display = {
- .clk = {
- .name = "display-if",
- .id = -1,
- .parent = &clk_esysclk.clk,
- .ctrlbit = S3C2443_SCLKCON_DISPCLK,
- .enable = s3c2443_clkcon_enable_s,
- },
- .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
-};
-
-/* prediv
- *
- * this divides the msysclk down to pass to h/p/etc.
- */
-
-static unsigned long s3c2443_prediv_getrate(struct clk *clk)
-{
- unsigned long rate = clk_get_rate(clk->parent);
- unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
-
- clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
- clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
-
- return rate / (clkdiv0 + 1);
-}
-
-static struct clk clk_prediv = {
- .name = "prediv",
- .id = -1,
- .parent = &clk_msysclk.clk,
- .ops = &(struct clk_ops) {
- .get_rate = s3c2443_prediv_getrate,
- },
-};
-
/* standard clock definitions */
-static struct clk init_clocks_disable[] = {
+static struct clk init_clocks_off[] = {
{
- .name = "nand",
- .id = -1,
- .parent = &clk_h,
- }, {
.name = "sdi",
.id = -1,
.parent = &clk_p,
.enable = s3c2443_clkcon_enable_p,
.ctrlbit = S3C2443_PCLKCON_SDI,
}, {
- .name = "adc",
- .id = -1,
- .parent = &clk_p,
- .enable = s3c2443_clkcon_enable_p,
- .ctrlbit = S3C2443_PCLKCON_ADC,
- }, {
- .name = "i2c",
- .id = -1,
- .parent = &clk_p,
- .enable = s3c2443_clkcon_enable_p,
- .ctrlbit = S3C2443_PCLKCON_IIC,
- }, {
.name = "iis",
.id = -1,
.parent = &clk_p,
@@ -537,179 +314,12 @@ static struct clk init_clocks_disable[] = {
};
static struct clk init_clocks[] = {
- {
- .name = "dma",
- .id = 0,
- .parent = &clk_h,
- .enable = s3c2443_clkcon_enable_h,
- .ctrlbit = S3C2443_HCLKCON_DMA0,
- }, {
- .name = "dma",
- .id = 1,
- .parent = &clk_h,
- .enable = s3c2443_clkcon_enable_h,
- .ctrlbit = S3C2443_HCLKCON_DMA1,
- }, {
- .name = "dma",
- .id = 2,
- .parent = &clk_h,
- .enable = s3c2443_clkcon_enable_h,
- .ctrlbit = S3C2443_HCLKCON_DMA2,
- }, {
- .name = "dma",
- .id = 3,
- .parent = &clk_h,
- .enable = s3c2443_clkcon_enable_h,
- .ctrlbit = S3C2443_HCLKCON_DMA3,
- }, {
- .name = "dma",
- .id = 4,
- .parent = &clk_h,
- .enable = s3c2443_clkcon_enable_h,
- .ctrlbit = S3C2443_HCLKCON_DMA4,
- }, {
- .name = "dma",
- .id = 5,
- .parent = &clk_h,
- .enable = s3c2443_clkcon_enable_h,
- .ctrlbit = S3C2443_HCLKCON_DMA5,
- }, {
- .name = "lcd",
- .id = -1,
- .parent = &clk_h,
- .enable = s3c2443_clkcon_enable_h,
- .ctrlbit = S3C2443_HCLKCON_LCDC,
- }, {
- .name = "gpio",
- .id = -1,
- .parent = &clk_p,
- .enable = s3c2443_clkcon_enable_p,
- .ctrlbit = S3C2443_PCLKCON_GPIO,
- }, {
- .name = "usb-host",
- .id = -1,
- .parent = &clk_h,
- .enable = s3c2443_clkcon_enable_h,
- .ctrlbit = S3C2443_HCLKCON_USBH,
- }, {
- .name = "usb-device",
- .id = -1,
- .parent = &clk_h,
- .enable = s3c2443_clkcon_enable_h,
- .ctrlbit = S3C2443_HCLKCON_USBD,
- }, {
- .name = "hsmmc",
- .id = -1,
- .parent = &clk_h,
- .enable = s3c2443_clkcon_enable_h,
- .ctrlbit = S3C2443_HCLKCON_HSMMC,
- }, {
- .name = "cfc",
- .id = -1,
- .parent = &clk_h,
- .enable = s3c2443_clkcon_enable_h,
- .ctrlbit = S3C2443_HCLKCON_CFC,
- }, {
- .name = "ssmc",
- .id = -1,
- .parent = &clk_h,
- .enable = s3c2443_clkcon_enable_h,
- .ctrlbit = S3C2443_HCLKCON_SSMC,
- }, {
- .name = "timers",
- .id = -1,
- .parent = &clk_p,
- .enable = s3c2443_clkcon_enable_p,
- .ctrlbit = S3C2443_PCLKCON_PWMT,
- }, {
- .name = "uart",
- .id = 0,
- .parent = &clk_p,
- .enable = s3c2443_clkcon_enable_p,
- .ctrlbit = S3C2443_PCLKCON_UART0,
- }, {
- .name = "uart",
- .id = 1,
- .parent = &clk_p,
- .enable = s3c2443_clkcon_enable_p,
- .ctrlbit = S3C2443_PCLKCON_UART1,
- }, {
- .name = "uart",
- .id = 2,
- .parent = &clk_p,
- .enable = s3c2443_clkcon_enable_p,
- .ctrlbit = S3C2443_PCLKCON_UART2,
- }, {
- .name = "uart",
- .id = 3,
- .parent = &clk_p,
- .enable = s3c2443_clkcon_enable_p,
- .ctrlbit = S3C2443_PCLKCON_UART3,
- }, {
- .name = "rtc",
- .id = -1,
- .parent = &clk_p,
- .enable = s3c2443_clkcon_enable_p,
- .ctrlbit = S3C2443_PCLKCON_RTC,
- }, {
- .name = "watchdog",
- .id = -1,
- .parent = &clk_p,
- .ctrlbit = S3C2443_PCLKCON_WDT,
- }, {
- .name = "usb-bus-host",
- .id = -1,
- .parent = &clk_usb_bus_host.clk,
- }, {
- .name = "ac97",
- .id = -1,
- .parent = &clk_p,
- .ctrlbit = S3C2443_PCLKCON_AC97,
- }
-};
-
-/* clocks to add where we need to check their parentage */
-
-static struct clksrc_clk __initdata *init_list[] = {
- &clk_epllref, /* should be first */
- &clk_esysclk,
- &clk_msysclk,
- &clk_arm,
- &clk_i2s_eplldiv,
- &clk_i2s,
- &clk_cam,
- &clk_uart,
- &clk_display,
- &clk_hsmmc_div,
- &clk_usb_bus_host,
};
-static void __init s3c2443_clk_initparents(void)
-{
- int ptr;
-
- for (ptr = 0; ptr < ARRAY_SIZE(init_list); ptr++)
- s3c_set_clksrc(init_list[ptr], true);
-}
-
-static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
-{
- clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
-
- return clkcon0 + 1;
-}
-
/* clocks to add straight away */
static struct clksrc_clk *clksrcs[] __initdata = {
- &clk_usb_bus_host,
- &clk_epllref,
- &clk_esysclk,
- &clk_msysclk,
&clk_arm,
- &clk_uart,
- &clk_display,
- &clk_cam,
&clk_i2s_eplldiv,
&clk_i2s,
&clk_hsspi,
@@ -717,92 +327,32 @@ static struct clksrc_clk *clksrcs[] __initdata = {
};
static struct clk *clks[] __initdata = {
- &clk_ext,
- &clk_epll,
- &clk_usb_bus,
- &clk_mpllref,
&clk_hsmmc,
&clk_armdiv,
- &clk_prediv,
};
void __init_or_cpufreq s3c2443_setup_clocks(void)
{
- unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
- unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
- struct clk *xtal_clk;
- unsigned long xtal;
- unsigned long pll;
- unsigned long fclk;
- unsigned long hclk;
- unsigned long pclk;
-
- xtal_clk = clk_get(NULL, "xtal");
- xtal = clk_get_rate(xtal_clk);
- clk_put(xtal_clk);
-
- pll = s3c2443_get_mpll(mpllcon, xtal);
- clk_msysclk.clk.rate = pll;
-
- fclk = pll / s3c2443_fclk_div(clkdiv0);
- hclk = s3c2443_prediv_getrate(&clk_prediv);
- hclk /= s3c2443_get_hdiv(clkdiv0);
- pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
-
- s3c24xx_setup_clocks(fclk, hclk, pclk);
-
- printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
- (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on",
- print_mhz(pll), print_mhz(fclk),
- print_mhz(hclk), print_mhz(pclk));
-
- s3c24xx_setup_clocks(fclk, hclk, pclk);
+ s3c2443_common_setup_clocks(s3c2443_get_mpll, s3c2443_fclk_div);
}
void __init s3c2443_init_clocks(int xtal)
{
- struct clk *clkp;
unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
- int ret;
int ptr;
- /* s3c2443 parents h and p clocks from prediv */
- clk_h.parent = &clk_prediv;
- clk_p.parent = &clk_prediv;
+ clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
+ clk_epll.parent = &clk_epllref.clk;
+
+ s3c2443_common_init_clocks(xtal, s3c2443_get_mpll, s3c2443_fclk_div);
- s3c24xx_register_baseclocks(xtal);
s3c2443_setup_clocks();
- s3c2443_clk_initparents();
-
- for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
- clkp = clks[ptr];
- ret = s3c24xx_register_clock(clkp);
- if (ret < 0) {
- printk(KERN_ERR "Failed to register clock %s (%d)\n",
- clkp->name, ret);
- }
- }
+ s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
s3c_register_clksrc(clksrcs[ptr], 1);
- clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
- clk_epll.parent = &clk_epllref.clk;
- clk_usb_bus.parent = &clk_usb_bus_host.clk;
-
- /* ensure usb bus clock is within correct rate of 48MHz */
-
- if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
- printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
- clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
- }
-
- printk("S3C2443: epll %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
- (epllcon & S3C2443_PLLCON_OFF) ? "off":"on",
- print_mhz(clk_get_rate(&clk_epll)),
- print_mhz(clk_get_rate(&clk_usb_bus)));
-
/* register clocks from clock array */
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
@@ -819,17 +369,8 @@ void __init s3c2443_init_clocks(int xtal)
/* install (and disable) the clocks we do not need immediately */
- clkp = init_clocks_disable;
- for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
-
- ret = s3c24xx_register_clock(clkp);
- if (ret < 0) {
- printk(KERN_ERR "Failed to register clock %s (%d)\n",
- clkp->name, ret);
- }
-
- (clkp->enable)(clkp, 0);
- }
+ s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+ s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_pwmclk_init();
}
diff --git a/arch/arm/mach-s3c64xx/gpiolib.c b/arch/arm/mach-s3c64xx/gpiolib.c
index 66e6794481d2..60c929a3cab6 100644
--- a/arch/arm/mach-s3c64xx/gpiolib.c
+++ b/arch/arm/mach-s3c64xx/gpiolib.c
@@ -51,6 +51,7 @@
static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
.set_config = s3c_gpio_setcfg_s3c64xx_4bit,
+ .get_config = s3c_gpio_getcfg_s3c64xx_4bit,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
};
@@ -58,12 +59,14 @@ static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
.cfg_eint = 7,
.set_config = s3c_gpio_setcfg_s3c64xx_4bit,
+ .get_config = s3c_gpio_getcfg_s3c64xx_4bit,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
};
static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
.cfg_eint = 3,
+ .get_config = s3c_gpio_getcfg_s3c64xx_4bit,
.set_config = s3c_gpio_setcfg_s3c64xx_4bit,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
@@ -171,6 +174,7 @@ static struct s3c_gpio_chip gpio_4bit2[] = {
static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
.set_config = s3c_gpio_setcfg_s3c24xx,
+ .get_config = s3c_gpio_getcfg_s3c24xx,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
};
@@ -178,6 +182,7 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
.cfg_eint = 2,
.set_config = s3c_gpio_setcfg_s3c24xx,
+ .get_config = s3c_gpio_getcfg_s3c24xx,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
};
@@ -185,6 +190,7 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
.cfg_eint = 3,
.set_config = s3c_gpio_setcfg_s3c24xx,
+ .get_config = s3c_gpio_getcfg_s3c24xx,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
};
diff --git a/arch/arm/mach-s3c64xx/include/mach/pll.h b/arch/arm/mach-s3c64xx/include/mach/pll.h
index 90bbd72fdc4e..5ef0bb698ee0 100644
--- a/arch/arm/mach-s3c64xx/include/mach/pll.h
+++ b/arch/arm/mach-s3c64xx/include/mach/pll.h
@@ -20,6 +20,7 @@
#define S3C6400_PLL_SDIV_SHIFT (0)
#include <asm/div64.h>
+#include <plat/pll6553x.h>
static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
u32 pllcon)
@@ -37,38 +38,8 @@ static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
return (unsigned long)fvco;
}
-#define S3C6400_EPLL_MDIV_MASK ((1 << (23-16)) - 1)
-#define S3C6400_EPLL_PDIV_MASK ((1 << (13-8)) - 1)
-#define S3C6400_EPLL_SDIV_MASK ((1 << (2-0)) - 1)
-#define S3C6400_EPLL_MDIV_SHIFT (16)
-#define S3C6400_EPLL_PDIV_SHIFT (8)
-#define S3C6400_EPLL_SDIV_SHIFT (0)
-#define S3C6400_EPLL_KDIV_MASK (0xffff)
-
static inline unsigned long s3c6400_get_epll(unsigned long baseclk)
{
- unsigned long result;
- u32 epll0 = __raw_readl(S3C_EPLL_CON0);
- u32 epll1 = __raw_readl(S3C_EPLL_CON1);
- u32 mdiv, pdiv, sdiv, kdiv;
- u64 tmp;
-
- mdiv = (epll0 >> S3C6400_EPLL_MDIV_SHIFT) & S3C6400_EPLL_MDIV_MASK;
- pdiv = (epll0 >> S3C6400_EPLL_PDIV_SHIFT) & S3C6400_EPLL_PDIV_MASK;
- sdiv = (epll0 >> S3C6400_EPLL_SDIV_SHIFT) & S3C6400_EPLL_SDIV_MASK;
- kdiv = epll1 & S3C6400_EPLL_KDIV_MASK;
-
- /* We need to multiple baseclk by mdiv (the integer part) and kdiv
- * which is in 2^16ths, so shift mdiv up (does not overflow) and
- * add kdiv before multiplying. The use of tmp is to avoid any
- * overflows before shifting bac down into result when multipling
- * by the mdiv and kdiv pair.
- */
-
- tmp = baseclk;
- tmp *= (mdiv << 16) + kdiv;
- do_div(tmp, (pdiv << sdiv));
- result = tmp >> 16;
-
- return result;
+ return s3c_get_pll6553x(baseclk, __raw_readl(S3C_EPLL_CON0),
+ __raw_readl(S3C_EPLL_CON1));
}
diff --git a/arch/arm/mach-s5p6440/gpio.c b/arch/arm/mach-s5p6440/gpio.c
index b0ea741177ad..262dc75d5bea 100644
--- a/arch/arm/mach-s5p6440/gpio.c
+++ b/arch/arm/mach-s5p6440/gpio.c
@@ -161,12 +161,15 @@ static struct s3c_gpio_cfg s5p6440_gpio_cfgs[] = {
}, {
.cfg_eint = 0,
.set_config = s3c_gpio_setcfg_s3c24xx,
+ .get_config = s3c_gpio_getcfg_s3c24xx,
}, {
.cfg_eint = 2,
.set_config = s3c_gpio_setcfg_s3c24xx,
+ .get_config = s3c_gpio_getcfg_s3c24xx,
}, {
.cfg_eint = 3,
.set_config = s3c_gpio_setcfg_s3c24xx,
+ .get_config = s3c_gpio_getcfg_s3c24xx,
},
};
@@ -279,6 +282,8 @@ void __init s5p6440_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips)
for (; nr_chips > 0; nr_chips--, chipcfg++) {
if (!chipcfg->set_config)
chipcfg->set_config = s3c_gpio_setcfg_s3c64xx_4bit;
+ if (!chipcfg->get_config)
+ chipcfg->get_config = s3c_gpio_getcfg_s3c64xx_4bit;
if (!chipcfg->set_pull)
chipcfg->set_pull = s3c_gpio_setpull_updown;
if (!chipcfg->get_pull)
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index 6e93ef8f3d43..3ce8f010b3c6 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -9,6 +9,7 @@ config PLAT_S3C24XX
select NO_IOPORT
select ARCH_REQUIRE_GPIOLIB
select S3C_DEVICE_NAND
+ select S3C_GPIO_CFG_S3C24XX
help
Base platform code for any Samsung S3C24XX device
@@ -44,6 +45,12 @@ config S3C2410_CLOCK
Clock code for the S3C2410, and similar processors which
is currently includes the S3C2410, S3C2440, S3C2442.
+config S3C2443_CLOCK
+ bool
+ help
+ Clock code for the S3C2443 and similar processors, which includes
+ the S3C2416 and S3C2450.
+
config S3C24XX_DCLK
bool
help
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
index c2237c41141f..44aea8868f89 100644
--- a/arch/arm/plat-s3c24xx/Makefile
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_PM) += irq-pm.o
obj-$(CONFIG_PM) += sleep.o
obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o
+obj-$(CONFIG_S3C2443_CLOCK) += s3c2443-clock.o
obj-$(CONFIG_S3C2410_DMA) += dma.o
obj-$(CONFIG_S3C2410_IOTIMING) += s3c2410-iotiming.o
obj-$(CONFIG_S3C2412_IOTIMING) += s3c2412-iotiming.o
diff --git a/arch/arm/plat-s3c24xx/common-smdk.c b/arch/arm/plat-s3c24xx/common-smdk.c
index 9e0e20ad2e46..7b44d0c592b5 100644
--- a/arch/arm/plat-s3c24xx/common-smdk.c
+++ b/arch/arm/plat-s3c24xx/common-smdk.c
@@ -42,6 +42,7 @@
#include <plat/nand.h>
#include <plat/common-smdk.h>
+#include <plat/gpio-cfg.h>
#include <plat/devs.h>
#include <plat/pm.h>
@@ -185,10 +186,10 @@ void __init smdk_machine_init(void)
{
/* Configure the LEDs (even if we have no LED support)*/
- s3c2410_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT);
- s3c2410_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT);
- s3c2410_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT);
- s3c2410_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT);
+ s3c_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT);
+ s3c_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT);
+ s3c_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT);
+ s3c_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_setpin(S3C2410_GPF(4), 1);
s3c2410_gpio_setpin(S3C2410_GPF(5), 1);
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index 9ca64df35bf6..76d0858c3cbb 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -49,6 +49,7 @@
#include <plat/s3c2400.h>
#include <plat/s3c2410.h>
#include <plat/s3c2412.h>
+#include <plat/s3c2416.h>
#include <plat/s3c244x.h>
#include <plat/s3c2443.h>
@@ -57,6 +58,7 @@
static const char name_s3c2400[] = "S3C2400";
static const char name_s3c2410[] = "S3C2410";
static const char name_s3c2412[] = "S3C2412";
+static const char name_s3c2416[] = "S3C2416/S3C2450";
static const char name_s3c2440[] = "S3C2440";
static const char name_s3c2442[] = "S3C2442";
static const char name_s3c2442b[] = "S3C2442B";
@@ -137,6 +139,15 @@ static struct cpu_table cpu_ids[] __initdata = {
.init = s3c2412_init,
.name = name_s3c2412,
},
+ { /* a strange version of the s3c2416 */
+ .idcode = 0x32450003,
+ .idmask = 0xffffffff,
+ .map_io = s3c2416_map_io,
+ .init_clocks = s3c2416_init_clocks,
+ .init_uarts = s3c2416_init_uarts,
+ .init = s3c2416_init,
+ .name = name_s3c2416,
+ },
{
.idcode = 0x32443001,
.idmask = 0xffffffff,
@@ -170,6 +181,16 @@ static struct map_desc s3c_iodesc[] __initdata = {
static unsigned long s3c24xx_read_idcode_v5(void)
{
+#if defined(CONFIG_CPU_S3C2416)
+ /* s3c2416 is v5, with S3C24XX_GSTATUS1 instead of S3C2412_GSTATUS1 */
+
+ u32 gs = __raw_readl(S3C24XX_GSTATUS1);
+
+ /* test for s3c2416 or similar device */
+ if ((gs >> 16) == 0x3245)
+ return gs;
+#endif
+
#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
return __raw_readl(S3C2412_GSTATUS1);
#else
diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c
index 5467470badfd..45126d3aafc6 100644
--- a/arch/arm/plat-s3c24xx/gpio.c
+++ b/arch/arm/plat-s3c24xx/gpio.c
@@ -1,6 +1,6 @@
/* linux/arch/arm/plat-s3c24xx/gpio.c
*
- * Copyright (c) 2004-2005 Simtec Electronics
+ * Copyright (c) 2004-2010 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C24XX GPIO support
@@ -20,12 +20,12 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
+#include <linux/gpio.h>
#include <linux/io.h>
#include <mach/hardware.h>
@@ -34,123 +34,34 @@
#include <mach/regs-gpio.h>
-void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
-{
- void __iomem *base = S3C24XX_GPIO_BASE(pin);
- unsigned long mask;
- unsigned long con;
- unsigned long flags;
-
- if (pin < S3C2410_GPIO_BANKB) {
- mask = 1 << S3C2410_GPIO_OFFSET(pin);
- } else {
- mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
- }
-
- switch (function) {
- case S3C2410_GPIO_LEAVE:
- mask = 0;
- function = 0;
- break;
-
- case S3C2410_GPIO_INPUT:
- case S3C2410_GPIO_OUTPUT:
- case S3C2410_GPIO_SFN2:
- case S3C2410_GPIO_SFN3:
- if (pin < S3C2410_GPIO_BANKB) {
- function -= 1;
- function &= 1;
- function <<= S3C2410_GPIO_OFFSET(pin);
- } else {
- function &= 3;
- function <<= S3C2410_GPIO_OFFSET(pin)*2;
- }
- }
-
- /* modify the specified register wwith IRQs off */
-
- local_irq_save(flags);
-
- con = __raw_readl(base + 0x00);
- con &= ~mask;
- con |= function;
-
- __raw_writel(con, base + 0x00);
-
- local_irq_restore(flags);
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
-
-unsigned int s3c2410_gpio_getcfg(unsigned int pin)
-{
- void __iomem *base = S3C24XX_GPIO_BASE(pin);
- unsigned long val = __raw_readl(base);
-
- if (pin < S3C2410_GPIO_BANKB) {
- val >>= S3C2410_GPIO_OFFSET(pin);
- val &= 1;
- val += 1;
- } else {
- val >>= S3C2410_GPIO_OFFSET(pin)*2;
- val &= 3;
- }
-
- return val | S3C2410_GPIO_INPUT;
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_getcfg);
+/* gpiolib wrappers until these are totally eliminated */
void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
{
- void __iomem *base = S3C24XX_GPIO_BASE(pin);
- unsigned long offs = S3C2410_GPIO_OFFSET(pin);
- unsigned long flags;
- unsigned long up;
+ int ret;
- if (pin < S3C2410_GPIO_BANKB)
- return;
+ WARN_ON(to); /* should be none of these left */
- local_irq_save(flags);
-
- up = __raw_readl(base + 0x08);
- up &= ~(1L << offs);
- up |= to << offs;
- __raw_writel(up, base + 0x08);
+ if (!to) {
+ /* if pull is enabled, try first with up, and if that
+ * fails, try using down */
- local_irq_restore(flags);
+ ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP);
+ if (ret)
+ s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN);
+ } else {
+ s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE);
+ }
}
-
EXPORT_SYMBOL(s3c2410_gpio_pullup);
-int s3c2410_gpio_getpull(unsigned int pin)
-{
- void __iomem *base = S3C24XX_GPIO_BASE(pin);
- unsigned long offs = S3C2410_GPIO_OFFSET(pin);
-
- if (pin < S3C2410_GPIO_BANKB)
- return -EINVAL;
-
- return (__raw_readl(base + 0x08) & (1L << offs)) ? 1 : 0;
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_getpull);
-
void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
{
- void __iomem *base = S3C24XX_GPIO_BASE(pin);
- unsigned long offs = S3C2410_GPIO_OFFSET(pin);
- unsigned long flags;
- unsigned long dat;
-
- local_irq_save(flags);
+ /* do this via gpiolib until all users removed */
- dat = __raw_readl(base + 0x04);
- dat &= ~(1 << offs);
- dat |= to << offs;
- __raw_writel(dat, base + 0x04);
-
- local_irq_restore(flags);
+ gpio_request(pin, "temporary");
+ gpio_set_value(pin, to);
+ gpio_free(pin);
}
EXPORT_SYMBOL(s3c2410_gpio_setpin);
@@ -181,22 +92,3 @@ unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
}
EXPORT_SYMBOL(s3c2410_modify_misccr);
-
-int s3c2410_gpio_getirq(unsigned int pin)
-{
- if (pin < S3C2410_GPF(0) || pin > S3C2410_GPG(15))
- return -EINVAL; /* not valid interrupts */
-
- if (pin < S3C2410_GPG(0) && pin > S3C2410_GPF(7))
- return -EINVAL; /* not valid pin */
-
- if (pin < S3C2410_GPF(4))
- return (pin - S3C2410_GPF(0)) + IRQ_EINT0;
-
- if (pin < S3C2410_GPG(0))
- return (pin - S3C2410_GPF(4)) + IRQ_EINT4;
-
- return (pin - S3C2410_GPG(0)) + IRQ_EINT8;
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_getirq);
diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c
index 4f0f11a6a677..4c0896f2572d 100644
--- a/arch/arm/plat-s3c24xx/gpiolib.c
+++ b/arch/arm/plat-s3c24xx/gpiolib.c
@@ -1,6 +1,6 @@
/* linux/arch/arm/plat-s3c24xx/gpiolib.c
*
- * Copyright (c) 2008 Simtec Electronics
+ * Copyright (c) 2008-2010 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
@@ -21,6 +21,8 @@
#include <linux/gpio.h>
#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <plat/pm.h>
@@ -77,10 +79,21 @@ static int s3c24xx_gpiolib_bankg_toirq(struct gpio_chip *chip, unsigned offset)
return IRQ_EINT8 + offset;
}
+static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
+ .set_config = s3c_gpio_setcfg_s3c24xx_a,
+ .get_config = s3c_gpio_getcfg_s3c24xx_a,
+};
+
+struct s3c_gpio_cfg s3c24xx_gpiocfg_default = {
+ .set_config = s3c_gpio_setcfg_s3c24xx,
+ .get_config = s3c_gpio_getcfg_s3c24xx,
+};
+
struct s3c_gpio_chip s3c24xx_gpios[] = {
[0] = {
.base = S3C2410_GPACON,
.pm = __gpio_pm(&s3c_gpio_pm_1bit),
+ .config = &s3c24xx_gpiocfg_banka,
.chip = {
.base = S3C2410_GPA(0),
.owner = THIS_MODULE,
@@ -161,15 +174,58 @@ struct s3c_gpio_chip s3c24xx_gpios[] = {
.ngpio = 11,
},
},
+ /* GPIOS for the S3C2443 and later devices. */
+ {
+ .base = S3C2440_GPJCON,
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
+ .chip = {
+ .base = S3C2410_GPJ(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOJ",
+ .ngpio = 16,
+ },
+ }, {
+ .base = S3C2443_GPKCON,
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
+ .chip = {
+ .base = S3C2410_GPK(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOK",
+ .ngpio = 16,
+ },
+ }, {
+ .base = S3C2443_GPLCON,
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
+ .chip = {
+ .base = S3C2410_GPL(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOL",
+ .ngpio = 15,
+ },
+ }, {
+ .base = S3C2443_GPMCON,
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
+ .chip = {
+ .base = S3C2410_GPM(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOM",
+ .ngpio = 2,
+ },
+ },
};
+
static __init int s3c24xx_gpiolib_init(void)
{
struct s3c_gpio_chip *chip = s3c24xx_gpios;
int gpn;
- for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++)
+ for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++) {
+ if (!chip->config)
+ chip->config = &s3c24xx_gpiocfg_default;
+
s3c_gpiolib_add(chip);
+ }
return 0;
}
diff --git a/arch/arm/plat-s3c24xx/include/plat/pll.h b/arch/arm/plat-s3c24xx/include/plat/pll.h
index 7ea8bffa7a9c..005729a1077a 100644
--- a/arch/arm/plat-s3c24xx/include/plat/pll.h
+++ b/arch/arm/plat-s3c24xx/include/plat/pll.h
@@ -35,3 +35,28 @@ s3c24xx_get_pll(unsigned int pllval, unsigned int baseclk)
return (unsigned int)fvco;
}
+
+#define S3C2416_PLL_M_SHIFT (14)
+#define S3C2416_PLL_P_SHIFT (5)
+#define S3C2416_PLL_S_MASK (7)
+#define S3C2416_PLL_M_MASK ((1 << 10) - 1)
+#define S3C2416_PLL_P_MASK (63)
+
+static inline unsigned int
+s3c2416_get_pll(unsigned int pllval, unsigned int baseclk)
+{
+ unsigned int m, p, s;
+ uint64_t fvco;
+
+ m = pllval >> S3C2416_PLL_M_SHIFT;
+ p = pllval >> S3C2416_PLL_P_SHIFT;
+
+ s = pllval & S3C2416_PLL_S_MASK;
+ m &= S3C2416_PLL_M_MASK;
+ p &= S3C2416_PLL_P_MASK;
+
+ fvco = (uint64_t)baseclk * m;
+ do_div(fvco, (p << s));
+
+ return (unsigned int)fvco;
+}
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2416.h b/arch/arm/plat-s3c24xx/include/plat/s3c2416.h
new file mode 100644
index 000000000000..dc3c0907d221
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2416.h
@@ -0,0 +1,31 @@
+/* linux/include/asm-arm/plat-s3c24xx/s3c2443.h
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>
+ *
+ * Header file for s3c2416 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifdef CONFIG_CPU_S3C2416
+
+struct s3c2410_uartcfg;
+
+extern int s3c2416_init(void);
+
+extern void s3c2416_map_io(void);
+
+extern void s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2416_init_clocks(int xtal);
+
+extern int s3c2416_baseclk_add(void);
+
+#else
+#define s3c2416_init_clocks NULL
+#define s3c2416_init_uarts NULL
+#define s3c2416_map_io NULL
+#define s3c2416_init NULL
+#endif
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2443.h b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
index 815b107ed890..a19715feb798 100644
--- a/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
@@ -30,3 +30,22 @@ extern int s3c2443_baseclk_add(void);
#define s3c2443_map_io NULL
#define s3c2443_init NULL
#endif
+
+/* common code used by s3c2443 and others.
+ * note, not to be used outside of arch/arm/mach-s3c* */
+
+struct clk; /* some files don't need clk.h otherwise */
+
+typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base);
+typedef unsigned int (*fdiv_fn)(unsigned long clkcon0);
+
+extern void s3c2443_common_setup_clocks(pll_fn get_mpll, fdiv_fn fdiv);
+extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, fdiv_fn fdiv);
+
+extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable);
+extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable);
+extern int s3c2443_clkcon_enable_s(struct clk *clk, int enable);
+
+extern struct clksrc_clk clk_epllref;
+extern struct clksrc_clk clk_esysclk;
+extern struct clksrc_clk clk_msysclk;
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c
index 3620dd299095..60627e63a254 100644
--- a/arch/arm/plat-s3c24xx/pm.c
+++ b/arch/arm/plat-s3c24xx/pm.c
@@ -43,6 +43,7 @@
#include <asm/mach/time.h>
+#include <plat/gpio-cfg.h>
#include <plat/pm.h>
#define PFX "s3c24xx-pm: "
@@ -90,22 +91,22 @@ static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
{
unsigned long irqstate;
unsigned long pinstate;
- int irq = s3c2410_gpio_getirq(pin);
+ int irq = gpio_to_irq(pin);
if (irqoffs < 4)
irqstate = s3c_irqwake_intmask & (1L<<irqoffs);
else
irqstate = s3c_irqwake_eintmask & (1L<<irqoffs);
- pinstate = s3c2410_gpio_getcfg(pin);
+ pinstate = s3c_gpio_getcfg(pin);
if (!irqstate) {
if (pinstate == S3C2410_GPIO_IRQ)
- S3C_PMDBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin);
+ S3C_PMDBG("Leaving IRQ %d (pin %d) as is\n", irq, pin);
} else {
if (pinstate == S3C2410_GPIO_IRQ) {
S3C_PMDBG("Disabling IRQ %d (pin %d)\n", irq, pin);
- s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
+ s3c_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
}
}
}
diff --git a/arch/arm/plat-s3c24xx/s3c2410-clock.c b/arch/arm/plat-s3c24xx/s3c2410-clock.c
index b61bdb793734..9ecc5d913679 100644
--- a/arch/arm/plat-s3c24xx/s3c2410-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c2410-clock.c
@@ -87,7 +87,7 @@ static int s3c2410_upll_enable(struct clk *clk, int enable)
/* standard clock definitions */
-static struct clk init_clocks_disable[] = {
+static struct clk init_clocks_off[] = {
{
.name = "nand",
.id = -1,
@@ -249,17 +249,8 @@ int __init s3c2410_baseclk_add(void)
/* install (and disable) the clocks we do not need immediately */
- clkp = init_clocks_disable;
- for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
-
- ret = s3c24xx_register_clock(clkp);
- if (ret < 0) {
- printk(KERN_ERR "Failed to register clock %s (%d)\n",
- clkp->name, ret);
- }
-
- s3c2410_clkcon_enable(clkp, 0);
- }
+ s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+ s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
/* show the clock-slow value */
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
new file mode 100644
index 000000000000..461f070eb62d
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c
@@ -0,0 +1,472 @@
+/* linux/arch/arm/plat-s3c24xx/s3c2443-clock.c
+ *
+ * Copyright (c) 2007, 2010 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2443 Clock control suport - common code
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/s3c2443.h>
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/cpu.h>
+
+#include <plat/cpu-freq.h>
+
+
+static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
+{
+ u32 ctrlbit = clk->ctrlbit;
+ u32 con = __raw_readl(reg);
+
+ if (enable)
+ con |= ctrlbit;
+ else
+ con &= ~ctrlbit;
+
+ __raw_writel(con, reg);
+ return 0;
+}
+
+int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
+{
+ return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
+}
+
+int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
+{
+ return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
+}
+
+int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
+{
+ return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
+}
+
+/* mpllref is a direct descendant of clk_xtal by default, but it is not
+ * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
+ * such directly equating the two source clocks is impossible.
+ */
+struct clk clk_mpllref = {
+ .name = "mpllref",
+ .parent = &clk_xtal,
+ .id = -1,
+};
+
+static struct clk *clk_epllref_sources[] = {
+ [0] = &clk_mpllref,
+ [1] = &clk_mpllref,
+ [2] = &clk_xtal,
+ [3] = &clk_ext,
+};
+
+struct clksrc_clk clk_epllref = {
+ .clk = {
+ .name = "epllref",
+ .id = -1,
+ },
+ .sources = &(struct clksrc_sources) {
+ .sources = clk_epllref_sources,
+ .nr_sources = ARRAY_SIZE(clk_epllref_sources),
+ },
+ .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
+};
+
+/* esysclk
+ *
+ * this is sourced from either the EPLL or the EPLLref clock
+*/
+
+static struct clk *clk_sysclk_sources[] = {
+ [0] = &clk_epllref.clk,
+ [1] = &clk_epll,
+};
+
+struct clksrc_clk clk_esysclk = {
+ .clk = {
+ .name = "esysclk",
+ .parent = &clk_epll,
+ .id = -1,
+ },
+ .sources = &(struct clksrc_sources) {
+ .sources = clk_sysclk_sources,
+ .nr_sources = ARRAY_SIZE(clk_sysclk_sources),
+ },
+ .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
+};
+
+static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long div = __raw_readl(S3C2443_CLKDIV0);
+
+ div &= S3C2443_CLKDIV0_EXTDIV_MASK;
+ div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1); /* x2 */
+
+ return parent_rate / (div + 1);
+}
+
+static struct clk clk_mdivclk = {
+ .name = "mdivclk",
+ .parent = &clk_mpllref,
+ .id = -1,
+ .ops = &(struct clk_ops) {
+ .get_rate = s3c2443_getrate_mdivclk,
+ },
+};
+
+static struct clk *clk_msysclk_sources[] = {
+ [0] = &clk_mpllref,
+ [1] = &clk_mpll,
+ [2] = &clk_mdivclk,
+ [3] = &clk_mpllref,
+};
+
+struct clksrc_clk clk_msysclk = {
+ .clk = {
+ .name = "msysclk",
+ .parent = &clk_xtal,
+ .id = -1,
+ },
+ .sources = &(struct clksrc_sources) {
+ .sources = clk_msysclk_sources,
+ .nr_sources = ARRAY_SIZE(clk_msysclk_sources),
+ },
+ .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
+};
+
+/* prediv
+ *
+ * this divides the msysclk down to pass to h/p/etc.
+ */
+
+static unsigned long s3c2443_prediv_getrate(struct clk *clk)
+{
+ unsigned long rate = clk_get_rate(clk->parent);
+ unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+
+ clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
+ clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
+
+ return rate / (clkdiv0 + 1);
+}
+
+static struct clk clk_prediv = {
+ .name = "prediv",
+ .id = -1,
+ .parent = &clk_msysclk.clk,
+ .ops = &(struct clk_ops) {
+ .get_rate = s3c2443_prediv_getrate,
+ },
+};
+
+/* usbhost
+ *
+ * usb host bus-clock, usually 48MHz to provide USB bus clock timing
+*/
+
+static struct clksrc_clk clk_usb_bus_host = {
+ .clk = {
+ .name = "usb-bus-host-parent",
+ .id = -1,
+ .parent = &clk_esysclk.clk,
+ .ctrlbit = S3C2443_SCLKCON_USBHOST,
+ .enable = s3c2443_clkcon_enable_s,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
+};
+
+/* common clksrc clocks */
+
+static struct clksrc_clk clksrc_clks[] = {
+ {
+ /* ART baud-rate clock sourced from esysclk via a divisor */
+ .clk = {
+ .name = "uartclk",
+ .id = -1,
+ .parent = &clk_esysclk.clk,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
+ }, {
+ /* camera interface bus-clock, divided down from esysclk */
+ .clk = {
+ .name = "camif-upll", /* same as 2440 name */
+ .id = -1,
+ .parent = &clk_esysclk.clk,
+ .ctrlbit = S3C2443_SCLKCON_CAMCLK,
+ .enable = s3c2443_clkcon_enable_s,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
+ }, {
+ .clk = {
+ .name = "display-if",
+ .id = -1,
+ .parent = &clk_esysclk.clk,
+ .ctrlbit = S3C2443_SCLKCON_DISPCLK,
+ .enable = s3c2443_clkcon_enable_s,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
+ },
+};
+
+
+static struct clk init_clocks_off[] = {
+ {
+ .name = "adc",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_ADC,
+ }, {
+ .name = "i2c",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_IIC,
+ }
+};
+
+static struct clk init_clocks[] = {
+ {
+ .name = "dma",
+ .id = 0,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_DMA0,
+ }, {
+ .name = "dma",
+ .id = 1,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_DMA1,
+ }, {
+ .name = "dma",
+ .id = 2,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_DMA2,
+ }, {
+ .name = "dma",
+ .id = 3,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_DMA3,
+ }, {
+ .name = "dma",
+ .id = 4,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_DMA4,
+ }, {
+ .name = "dma",
+ .id = 5,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_DMA5,
+ }, {
+ .name = "hsmmc",
+ .id = 0,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_HSMMC,
+ }, {
+ .name = "gpio",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_GPIO,
+ }, {
+ .name = "usb-host",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_USBH,
+ }, {
+ .name = "usb-device",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_USBD,
+ }, {
+ .name = "lcd",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_LCDC,
+
+ }, {
+ .name = "timers",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_PWMT,
+ }, {
+ .name = "cfc",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_CFC,
+ }, {
+ .name = "ssmc",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_SSMC,
+ }, {
+ .name = "uart",
+ .id = 0,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_UART0,
+ }, {
+ .name = "uart",
+ .id = 1,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_UART1,
+ }, {
+ .name = "uart",
+ .id = 2,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_UART2,
+ }, {
+ .name = "uart",
+ .id = 3,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_UART3,
+ }, {
+ .name = "rtc",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_RTC,
+ }, {
+ .name = "watchdog",
+ .id = -1,
+ .parent = &clk_p,
+ .ctrlbit = S3C2443_PCLKCON_WDT,
+ }, {
+ .name = "ac97",
+ .id = -1,
+ .parent = &clk_p,
+ .ctrlbit = S3C2443_PCLKCON_AC97,
+ }, {
+ .name = "nand",
+ .id = -1,
+ .parent = &clk_h,
+ }, {
+ .name = "usb-bus-host",
+ .id = -1,
+ .parent = &clk_usb_bus_host.clk,
+ }
+};
+
+static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
+{
+ clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
+
+ return clkcon0 + 1;
+}
+
+/* EPLLCON compatible enough to get on/off information */
+
+void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll,
+ fdiv_fn get_fdiv)
+{
+ unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
+ unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
+ unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+ struct clk *xtal_clk;
+ unsigned long xtal;
+ unsigned long pll;
+ unsigned long fclk;
+ unsigned long hclk;
+ unsigned long pclk;
+ int ptr;
+
+ xtal_clk = clk_get(NULL, "xtal");
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ pll = get_mpll(mpllcon, xtal);
+ clk_msysclk.clk.rate = pll;
+
+ fclk = pll / get_fdiv(clkdiv0);
+ hclk = s3c2443_prediv_getrate(&clk_prediv);
+ hclk /= s3c2443_get_hdiv(clkdiv0);
+ pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
+
+ s3c24xx_setup_clocks(fclk, hclk, pclk);
+
+ printk("CPU: MPLL %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
+ (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on",
+ print_mhz(pll), print_mhz(fclk),
+ print_mhz(hclk), print_mhz(pclk));
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++)
+ s3c_set_clksrc(&clksrc_clks[ptr], true);
+
+ /* ensure usb bus clock is within correct rate of 48MHz */
+
+ if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
+ printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
+ clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
+ }
+
+ printk("CPU: EPLL %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
+ (epllcon & S3C2443_PLLCON_OFF) ? "off":"on",
+ print_mhz(clk_get_rate(&clk_epll)),
+ print_mhz(clk_get_rate(&clk_usb_bus)));
+}
+
+static struct clk *clks[] __initdata = {
+ &clk_prediv,
+ &clk_mpllref,
+ &clk_mdivclk,
+ &clk_ext,
+ &clk_epll,
+ &clk_usb_bus,
+};
+
+static struct clksrc_clk *clksrcs[] __initdata = {
+ &clk_usb_bus_host,
+ &clk_epllref,
+ &clk_esysclk,
+ &clk_msysclk,
+};
+
+void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
+ fdiv_fn get_fdiv)
+{
+ int ptr;
+
+ /* s3c2443 parents h and p clocks from prediv */
+ clk_h.parent = &clk_prediv;
+ clk_p.parent = &clk_prediv;
+
+ clk_usb_bus.parent = &clk_usb_bus_host.clk;
+ clk_epll.parent = &clk_epllref.clk;
+
+ s3c24xx_register_baseclocks(xtal);
+ s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+ s3c_register_clksrc(clksrcs[ptr], 1);
+
+ s3c_register_clksrc(clksrc_clks, ARRAY_SIZE(clksrc_clks));
+ s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+ /* See s3c2443/etc notes on disabling clocks at init time */
+ s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+ s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+
+ s3c2443_common_setup_clocks(get_mpll, get_fdiv);
+}
diff --git a/arch/arm/plat-s3c24xx/setup-i2c.c b/arch/arm/plat-s3c24xx/setup-i2c.c
index 71a6accf114e..9e90a7cbd1d6 100644
--- a/arch/arm/plat-s3c24xx/setup-i2c.c
+++ b/arch/arm/plat-s3c24xx/setup-i2c.c
@@ -15,12 +15,13 @@
struct platform_device;
+#include <plat/gpio-cfg.h>
#include <plat/iic.h>
#include <mach/hardware.h>
#include <mach/regs-gpio.h>
void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{
- s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA);
- s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL);
+ s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA);
+ s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL);
}
diff --git a/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c b/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
index da7a61728c18..9793544a6ace 100644
--- a/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
+++ b/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
@@ -21,16 +21,16 @@ void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi,
int enable)
{
if (enable) {
- s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0);
- s3c2410_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0);
- s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0);
+ s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0);
+ s3c_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0);
+ s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0);
s3c2410_gpio_pullup(S3C2410_GPE(11), 0);
s3c2410_gpio_pullup(S3C2410_GPE(13), 0);
} else {
- s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT);
- s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT);
- s3c2410_gpio_pullup(S3C2410_GPE(11), 1);
- s3c2410_gpio_pullup(S3C2410_GPE(12), 1);
- s3c2410_gpio_pullup(S3C2410_GPE(13), 1);
+ s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT);
+ s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT);
+ s3c_gpio_cfgpull(S3C2410_GPE(11), S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpull(S3C2410_GPE(12), S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpull(S3C2410_GPE(13), S3C_GPIO_PULL_NONE);
}
}
diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
index 89fcf5308cf6..db9e9e477ec1 100644
--- a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
+++ b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
@@ -23,16 +23,16 @@ void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi,
printk(KERN_INFO "%s(%d)\n", __func__, enable);
if (enable) {
- s3c2410_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1);
- s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1);
- s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1);
+ s3c_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1);
+ s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1);
+ s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1);
s3c2410_gpio_pullup(S3C2410_GPD(10), 0);
s3c2410_gpio_pullup(S3C2410_GPD(9), 0);
} else {
- s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT);
- s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT);
- s3c2410_gpio_pullup(S3C2410_GPD(10), 1);
- s3c2410_gpio_pullup(S3C2410_GPD(9), 1);
- s3c2410_gpio_pullup(S3C2410_GPD(8), 1);
+ s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT);
+ s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT);
+ s3c_gpio_cfgpull(S3C2410_GPD(10), S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpull(S3C2410_GPD(9), S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpull(S3C2410_GPD(8), S3C_GPIO_PULL_NONE);
}
}
diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c b/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c
index 86b9edc67413..8ea663a438bb 100644
--- a/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c
+++ b/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c
@@ -21,16 +21,16 @@ void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi,
int enable)
{
if (enable) {
- s3c2410_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1);
- s3c2410_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1);
- s3c2410_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1);
+ s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1);
+ s3c_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1);
+ s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1);
s3c2410_gpio_pullup(S3C2410_GPG(5), 0);
s3c2410_gpio_pullup(S3C2410_GPG(6), 0);
} else {
- s3c2410_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT);
- s3c2410_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT);
- s3c2410_gpio_pullup(S3C2410_GPG(5), 1);
- s3c2410_gpio_pullup(S3C2410_GPG(6), 1);
- s3c2410_gpio_pullup(S3C2410_GPG(7), 1);
+ s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT);
+ s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT);
+ s3c_gpio_cfgpull(S3C2410_GPG(5), S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpull(S3C2410_GPG(6), S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpull(S3C2410_GPG(7), S3C_GPIO_PULL_NONE);
}
}
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
index 1b25c9d8c403..8bf79f3efdfb 100644
--- a/arch/arm/plat-samsung/clock.c
+++ b/arch/arm/plat-samsung/clock.c
@@ -376,6 +376,21 @@ void __init s3c_register_clocks(struct clk *clkp, int nr_clks)
}
}
+/**
+ * s3c_disable_clocks() - disable an array of clocks
+ * @clkp: Pointer to the first clock in the array.
+ * @nr_clks: Number of clocks to register.
+ *
+ * for internal use only at initialisation time. disable the clocks in the
+ * @clkp array.
+ */
+
+void __init s3c_disable_clocks(struct clk *clkp, int nr_clks)
+{
+ for (; nr_clks > 0; nr_clks--, clkp++)
+ (clkp->enable)(clkp, 0);
+}
+
/* initalise all the clocks */
int __init s3c24xx_register_baseclocks(unsigned long xtal)
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
index 44a84e896546..3282db360fa8 100644
--- a/arch/arm/plat-samsung/gpio-config.c
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -1,7 +1,7 @@
/* linux/arch/arm/plat-s3c/gpio-config.c
*
* Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
+ * Copyright 2008-2010 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
@@ -41,6 +41,26 @@ int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
}
EXPORT_SYMBOL(s3c_gpio_cfgpin);
+unsigned s3c_gpio_getcfg(unsigned int pin)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned long flags;
+ unsigned ret = 0;
+ int offset;
+
+ if (chip) {
+ offset = pin - chip->chip.base;
+
+ local_irq_save(flags);
+ ret = s3c_gpio_do_getcfg(chip, offset);
+ local_irq_restore(flags);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_getcfg);
+
+
int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
{
struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
@@ -61,8 +81,8 @@ int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
EXPORT_SYMBOL(s3c_gpio_setpull);
#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
-int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip,
- unsigned int off, unsigned int cfg)
+int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
+ unsigned int off, unsigned int cfg)
{
void __iomem *reg = chip->base;
unsigned int shift = off;
@@ -87,6 +107,19 @@ int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip,
return 0;
}
+unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ u32 con;
+
+ con = __raw_readl(chip->base);
+ con >>= off;
+ con &= 1;
+ con++;
+
+ return S3C_GPIO_SFN(con);
+}
+
int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
unsigned int off, unsigned int cfg)
{
@@ -109,6 +142,19 @@ int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
return 0;
}
+
+unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ u32 con;
+
+ con = __raw_readl(chip->base);
+ con >>= off * 2;
+ con &= 3;
+
+ /* this conversion works for IN and OUT as well as special mode */
+ return S3C_GPIO_SPECIAL(con);
+}
#endif
#ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
@@ -134,6 +180,25 @@ int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
return 0;
}
+
+unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ void __iomem *reg = chip->base;
+ unsigned int shift = (off & 7) * 4;
+ u32 con;
+
+ if (off < 8 && chip->chip.ngpio > 8)
+ reg -= 4;
+
+ con = __raw_readl(reg);
+ con >>= shift;
+ con &= 0xf;
+
+ /* this conversion works for IN and OUT as well as special mode */
+ return S3C_GPIO_SPECIAL(con);
+}
+
#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */
#ifdef CONFIG_S3C_GPIO_PULL_UPDOWN
@@ -164,3 +229,35 @@ s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
return (__force s3c_gpio_pull_t)pup;
}
#endif
+
+#ifdef CONFIG_S3C_GPIO_PULL_UP
+int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull)
+{
+ void __iomem *reg = chip->base + 0x08;
+ u32 pup = __raw_readl(reg);
+
+ pup = __raw_readl(reg);
+
+ if (pup == S3C_GPIO_PULL_UP)
+ pup &= ~(1 << off);
+ else if (pup == S3C_GPIO_PULL_NONE)
+ pup |= (1 << off);
+ else
+ return -EINVAL;
+
+ __raw_writel(pup, reg);
+ return 0;
+}
+
+s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ void __iomem *reg = chip->base + 0x08;
+ u32 pup = __raw_readl(reg);
+
+ pup &= (1 << off);
+ return pup ? S3C_GPIO_PULL_NONE : S3C_GPIO_PULL_UP;
+}
+#endif /* CONFIG_S3C_GPIO_PULL_UP */
+
diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h
index 60b62692ac7a..12caf48a6bdc 100644
--- a/arch/arm/plat-samsung/include/plat/clock.h
+++ b/arch/arm/plat-samsung/include/plat/clock.h
@@ -91,6 +91,7 @@ extern int s3c24xx_register_clock(struct clk *clk);
extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks);
extern void s3c_register_clocks(struct clk *clk, int nr_clks);
+extern void s3c_disable_clocks(struct clk *clkp, int nr_clks);
extern int s3c24xx_register_baseclocks(unsigned long xtal);
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index d316b4a579f4..5dbeb7991e60 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -73,6 +73,7 @@ extern struct sys_timer s3c24xx_timer;
extern struct sysdev_class s3c2410_sysclass;
extern struct sysdev_class s3c2410a_sysclass;
extern struct sysdev_class s3c2412_sysclass;
+extern struct sysdev_class s3c2416_sysclass;
extern struct sysdev_class s3c2440_sysclass;
extern struct sysdev_class s3c2442_sysclass;
extern struct sysdev_class s3c2443_sysclass;
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
index dda19da037ad..3e21c75feefa 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
@@ -30,6 +30,12 @@ static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip,
return (chip->config->set_config)(chip, off, config);
}
+static inline unsigned s3c_gpio_do_getcfg(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ return (chip->config->get_config)(chip, off);
+}
+
static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
unsigned int off, s3c_gpio_pull_t pull)
{
@@ -53,6 +59,18 @@ extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
unsigned int off, unsigned int cfg);
/**
+ * s3c_gpio_getcfg_s3c24xx - S3C24XX style GPIO configuration read.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of s3c_gpio_setcfg_s3c24xx(). Will return a value whicg
+ * could be directly passed back to s3c_gpio_setcfg_s3c24xx(), from the
+ * S3C_GPIO_SPECIAL() macro.
+ */
+unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
+ unsigned int off);
+
+/**
* s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A)
* @chip: The gpio chip that is being configured.
* @off: The offset for the GPIO being configured.
@@ -65,6 +83,21 @@ extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
unsigned int off, unsigned int cfg);
+
+/**
+ * s3c_gpio_getcfg_s3c24xx_a - S3C24XX style GPIO configuration read (Bank A)
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of s3c_gpio_setcfg_s3c24xx_a() turning an GPIO into a usable
+ * GPIO configuration value.
+ *
+ * @sa s3c_gpio_getcfg_s3c24xx
+ * @sa s3c_gpio_getcfg_s3c64xx_4bit
+ */
+extern unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
+ unsigned int off);
+
/**
* s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config.
* @chip: The gpio chip that is being configured.
@@ -85,6 +118,20 @@ extern int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
unsigned int off, unsigned int cfg);
+/**
+ * s3c_gpio_getcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config read.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of s3c_gpio_setcfg_s3c64xx_4bit(), turning a gpio configuration
+ * register setting into a value the software can use, such as could be passed
+ * to s3c_gpio_setcfg_s3c64xx_4bit().
+ *
+ * @sa s3c_gpio_getcfg_s3c24xx
+ */
+extern unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
+ unsigned int off);
+
/* Pull-{up,down} resistor controls.
*
* S3C2410,S3C2440,S3C24A0 = Pull-UP,
@@ -146,6 +193,17 @@ extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
unsigned int off);
/**
+ * s3c_gpio_getpull_1up() - Get configuration for choice of up or none
+ * @chip: The gpio chip that the GPIO pin belongs to
+ * @off: The offset to the pin to get the configuration of.
+ *
+ * This helper function reads the state of the pull-up resistor for the
+ * given GPIO in the same case as s3c_gpio_setpull_1up.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
+ unsigned int off);
+
+/**
* s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443.
* @chip: The gpio chip that is being configured.
* @off: The offset for the GPIO being configured.
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
index 29cd6a86cade..8d01e853df39 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
@@ -77,6 +77,17 @@ struct s3c_gpio_cfg {
*/
extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
+/**
+ * s3c_gpio_getcfg - Read the current function for a GPIO pin
+ * @pin: The pin to read the configuration value for.
+ *
+ * Read the configuration state of the given @pin, returning a value that
+ * could be passed back to s3c_gpio_cfgpin().
+ *
+ * @sa s3c_gpio_cfgpin
+ */
+extern unsigned s3c_gpio_getcfg(unsigned int pin);
+
/* Define values for the pull-{up,down} available for each gpio pin.
*
* These values control the state of the weak pull-{up,down} resistors
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index 49ff406a7066..f0584f26d493 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -108,6 +108,9 @@ extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip);
extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip);
+/* exported for core SoC support to change */
+extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default;
+
#ifdef CONFIG_S3C_GPIO_TRACK
extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
diff --git a/arch/arm/plat-samsung/include/plat/pll6553x.h b/arch/arm/plat-samsung/include/plat/pll6553x.h
new file mode 100644
index 000000000000..b8b7e1d884f8
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pll6553x.h
@@ -0,0 +1,51 @@
+/* arch/arm/plat-samsung/include/plat/pll6553x.h
+ * partially from arch/arm/mach-s3c64xx/include/mach/pll.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Samsung PLL6553x PLL 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.
+*/
+
+/* S3C6400 and compatible (S3C2416, etc.) EPLL code */
+
+#define PLL6553X_MDIV_MASK ((1 << (23-16)) - 1)
+#define PLL6553X_PDIV_MASK ((1 << (13-8)) - 1)
+#define PLL6553X_SDIV_MASK ((1 << (2-0)) - 1)
+#define PLL6553X_MDIV_SHIFT (16)
+#define PLL6553X_PDIV_SHIFT (8)
+#define PLL6553X_SDIV_SHIFT (0)
+#define PLL6553X_KDIV_MASK (0xffff)
+
+static inline unsigned long s3c_get_pll6553x(unsigned long baseclk,
+ u32 pll0, u32 pll1)
+{
+ unsigned long result;
+ u32 mdiv, pdiv, sdiv, kdiv;
+ u64 tmp;
+
+ mdiv = (pll0 >> PLL6553X_MDIV_SHIFT) & PLL6553X_MDIV_MASK;
+ pdiv = (pll0 >> PLL6553X_PDIV_SHIFT) & PLL6553X_PDIV_MASK;
+ sdiv = (pll0 >> PLL6553X_SDIV_SHIFT) & PLL6553X_SDIV_MASK;
+ kdiv = pll1 & PLL6553X_KDIV_MASK;
+
+ /* We need to multiple baseclk by mdiv (the integer part) and kdiv
+ * which is in 2^16ths, so shift mdiv up (does not overflow) and
+ * add kdiv before multiplying. The use of tmp is to avoid any
+ * overflows before shifting bac down into result when multipling
+ * by the mdiv and kdiv pair.
+ */
+
+ tmp = baseclk;
+ tmp *= (mdiv << 16) + kdiv;
+ do_div(tmp, (pdiv << sdiv));
+ result = tmp >> 16;
+
+ return result;
+}
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index f55c49475a8c..5f3f03df92e3 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -518,12 +518,13 @@ config SERIAL_S3C2412
Serial port support for the Samsung S3C2412 and S3C2413 SoC
config SERIAL_S3C2440
- tristate "Samsung S3C2440/S3C2442 Serial port support"
- depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442)
+ tristate "Samsung S3C2440/S3C2442/S3C2416 Serial port support"
+ depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442 || CPU_S3C2416)
default y if CPU_S3C2440
default y if CPU_S3C2442
+ select SERIAL_SAMSUNG_UARTS_4 if CPU_S3C2416
help
- Serial port support for the Samsung S3C2440 and S3C2442 SoC
+ Serial port support for the Samsung S3C2440, S3C2416 and S3C2442 SoC
config SERIAL_S3C24A0
tristate "Samsung S3C24A0 Serial port support"