All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Update Samsung S5PC100 SoC support
@ 2009-10-13  8:11 ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: kyungmin.park, bhmin, ben-linux, m.szyprowski

Hello,

This patch series updates Samsung S5PC100 SoC support. S5PC100 platform
core has been extended with new clocks hierarchy implementation, gpio lib,
support for external and gpio interrupts and some basics of power
management (cpu idle and system reset). Also platform helpers for
s3c framebuffer, i2c and hsmmc drivers has been added.

All these patches has been tested on SMDKC100 board.

This patch series has been prepared against latest ARM Kernel tree from
http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm.git/

(I'm really sorry for double-posting this patch series, but at the first
attepmt I used the old address of the ARM Kernel mailing list)

This patch series includes:

[PATCH 01/17] ARM: MM: use 64bytes of L1 cache on plat S5PC1xx
[PATCH 02/17] ARM: S5PC1XX: registers rename
[PATCH 03/17] ARM: S5PC1XX: clock registers rename
[PATCH 04/17] ARM: S5PC1XX: clocks reimplementation
[PATCH 05/17] ARM: S5PC1XX: add GPIO L banks to register definition
[PATCH 06/17] ARM: S5PC1XX: GPIO registers rename
[PATCH 07/17] ARM: S5PC1xx: add gpiolib and external/gpio interrupt support
[PATCH 08/17] ARM: S5PC1XX: add cpu idle and system reset support
[PATCH 09/17] ARM: S5PC1xx: add platform helpers for s3c-fb device
[PATCH 10/17] SMDKC100: enable S3C FrameBuffer
[PATCH 11/17] drivers: fb: enable S3C FrameBuffer on S5PC1XX platform
[PATCH 12/17] ARM: S5PC1xx: add platform helpers for i2c adapter devices
[PATCH 13/17] SMDKC100: add I2C0 and I2C1 buses support
[PATCH 14/17] drivers: i2c: s3c2410-i2c also on S5PC1XX platform
[PATCH 15/17] ARM: S5PC1xx: add platform helpers for SDHCI host controllers
[PATCH 16/17] SMDKC100: add SDHCI controllers 0, 1 and 2 support
[PATCH 17/17] drivers: MMC: enable SDHCI-S3C on S5PC1XX platform

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH] Update Samsung S5PC100 SoC support
@ 2009-10-13  8:11 ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

This patch series updates Samsung S5PC100 SoC support. S5PC100 platform
core has been extended with new clocks hierarchy implementation, gpio lib,
support for external and gpio interrupts and some basics of power
management (cpu idle and system reset). Also platform helpers for
s3c framebuffer, i2c and hsmmc drivers has been added.

All these patches has been tested on SMDKC100 board.

This patch series has been prepared against latest ARM Kernel tree from
http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm.git/

(I'm really sorry for double-posting this patch series, but at the first
attepmt I used the old address of the ARM Kernel mailing list)

This patch series includes:

[PATCH 01/17] ARM: MM: use 64bytes of L1 cache on plat S5PC1xx
[PATCH 02/17] ARM: S5PC1XX: registers rename
[PATCH 03/17] ARM: S5PC1XX: clock registers rename
[PATCH 04/17] ARM: S5PC1XX: clocks reimplementation
[PATCH 05/17] ARM: S5PC1XX: add GPIO L banks to register definition
[PATCH 06/17] ARM: S5PC1XX: GPIO registers rename
[PATCH 07/17] ARM: S5PC1xx: add gpiolib and external/gpio interrupt support
[PATCH 08/17] ARM: S5PC1XX: add cpu idle and system reset support
[PATCH 09/17] ARM: S5PC1xx: add platform helpers for s3c-fb device
[PATCH 10/17] SMDKC100: enable S3C FrameBuffer
[PATCH 11/17] drivers: fb: enable S3C FrameBuffer on S5PC1XX platform
[PATCH 12/17] ARM: S5PC1xx: add platform helpers for i2c adapter devices
[PATCH 13/17] SMDKC100: add I2C0 and I2C1 buses support
[PATCH 14/17] drivers: i2c: s3c2410-i2c also on S5PC1XX platform
[PATCH 15/17] ARM: S5PC1xx: add platform helpers for SDHCI host controllers
[PATCH 16/17] SMDKC100: add SDHCI controllers 0, 1 and 2 support
[PATCH 17/17] drivers: MMC: enable SDHCI-S3C on S5PC1XX platform

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 01/17] ARM: MM: use 64bytes of L1 cache on plat S5PC1xx
  2009-10-13  8:11 ` Marek Szyprowski
@ 2009-10-13  8:11   ` Marek Szyprowski
  -1 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: kyungmin.park, bhmin, ben-linux, m.szyprowski

Samsung S5PC1xx SoCs are Coretex8 based, so use 64 bytes of L1 cache
line instead of the default 32 bytes.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mm/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index e993140..9cf7706 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -777,5 +777,5 @@ config CACHE_XSC3L2
 
 config ARM_L1_CACHE_SHIFT
 	int
-	default 6 if ARCH_OMAP3
+	default 6 if ARCH_OMAP3 || ARCH_S5PC1XX
 	default 5
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 01/17] ARM: MM: use 64bytes of L1 cache on plat S5PC1xx
@ 2009-10-13  8:11   ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

Samsung S5PC1xx SoCs are Coretex8 based, so use 64 bytes of L1 cache
line instead of the default 32 bytes.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mm/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index e993140..9cf7706 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -777,5 +777,5 @@ config CACHE_XSC3L2
 
 config ARM_L1_CACHE_SHIFT
 	int
-	default 6 if ARCH_OMAP3
+	default 6 if ARCH_OMAP3 || ARCH_S5PC1XX
 	default 5
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 02/17] ARM: S5PC1XX: registers rename
  2009-10-13  8:11   ` Marek Szyprowski
@ 2009-10-13  8:11     ` Marek Szyprowski
  -1 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: kyungmin.park, bhmin, ben-linux, m.szyprowski

S5PC110 and S5PC100 register maps differs in many places, rename all
defined registers to be S5PC100 specific. System map has been also updated
to cover more integrated peripherals.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/include/mach/map.h |   87 +++++++++++++++++++++++++++--
 arch/arm/mach-s5pc100/mach-smdkc100.c    |    4 +-
 2 files changed, 83 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h
index 9e9f391..4681ebe 100644
--- a/arch/arm/mach-s5pc100/include/mach/map.h
+++ b/arch/arm/mach-s5pc100/include/mach/map.h
@@ -17,6 +17,19 @@
 
 #include <plat/map-base.h>
 
+/*
+ * map-base.h has already defined virtual memory address
+ * S3C_VA_IRQ		S3C_ADDR(0x00000000)	irq controller(s)
+ * S3C_VA_SYS		S3C_ADDR(0x00100000)	system control
+ * S3C_VA_MEM		S3C_ADDR(0x00200000)	system control (not used)
+ * S3C_VA_TIMER		S3C_ADDR(0x00300000)	timer block
+ * S3C_VA_WATCHDOG	S3C_ADDR(0x00400000)	watchdog
+ * S3C_VA_UART		S3C_ADDR(0x01000000)	UART
+ *
+ * S5PC100 specific virtual memory address can be defined here
+ * S5PC1XX_VA_GPIO	S3C_ADDR(0x00500000)	GPIO
+ *
+ */
 
 /* Chip ID */
 #define S5PC100_PA_CHIPID	(0xE0000000)
@@ -24,13 +37,20 @@
 #define S5PC1XX_VA_CHIPID	S3C_VA_SYS
 
 /* System */
-#define S5PC100_PA_SYS		(0xE0100000)
-#define S5PC100_PA_CLK		(S5PC100_PA_SYS + 0x0)
-#define S5PC100_PA_PWR		(S5PC100_PA_SYS + 0x8000)
+#define S5PC100_PA_CLK		(0xE0100000)
+#define S5PC100_PA_CLK_OTHER	(0xE0200000)
+#define S5PC100_PA_PWR		(0xE0108000)
 #define S5PC1XX_PA_CLK		S5PC100_PA_CLK
 #define S5PC1XX_PA_PWR		S5PC100_PA_PWR
+#define S5PC1XX_PA_CLK_OTHER	S5PC100_PA_CLK_OTHER
 #define S5PC1XX_VA_CLK		(S3C_VA_SYS + 0x10000)
 #define S5PC1XX_VA_PWR		(S3C_VA_SYS + 0x20000)
+#define S5PC1XX_VA_CLK_OTHER	(S3C_VA_SYS + 0x30000)
+
+/* GPIO */
+#define S5PC100_PA_GPIO		(0xE0300000)
+#define S5PC1XX_PA_GPIO		S5PC100_PA_GPIO
+#define S5PC1XX_VA_GPIO		S3C_ADDR(0x00500000)
 
 /* Interrupt */
 #define S5PC100_PA_VIC		(0xE4000000)
@@ -40,23 +60,64 @@
 #define S5PC1XX_PA_VIC(x)	(S5PC100_PA_VIC + ((x) * S5PC100_PA_VIC_OFFSET))
 #define S5PC1XX_VA_VIC(x)	(S5PC100_VA_VIC + ((x) * S5PC100_VA_VIC_OFFSET))
 
+/* DMA */
+#define S5PC100_PA_MDMA		(0xE8100000)
+#define S5PC100_PA_PDMA0	(0xE9000000)
+#define S5PC100_PA_PDMA1	(0xE9200000)
+
 /* Timer */
 #define S5PC100_PA_TIMER	(0xEA000000)
 #define S5PC1XX_PA_TIMER	S5PC100_PA_TIMER
 #define S5PC1XX_VA_TIMER	S3C_VA_TIMER
 
+/* RTC */
+#define S5PC100_PA_RTC		(0xEA300000)
+
 /* UART */
 #define S5PC100_PA_UART		(0xEC000000)
 #define S5PC1XX_PA_UART		S5PC100_PA_UART
 #define S5PC1XX_VA_UART		S3C_VA_UART
 
-/* IIC */
-#define S5PC100_PA_IIC		(0xEC100000)
+/* I2C */
+#define S5PC100_PA_I2C		(0xEC100000)
+#define S5PC100_PA_I2C1		(0xEC200000)
+
+/* USB HS OTG */
+#define S5PC100_PA_USB_HSOTG	(0xED200000)
+#define S5PC100_PA_USB_HSPHY	(0xED300000)
+
+/* SD/MMC */
+#define S5PC100_PA_HSMMC(x)	(0xED800000 + ((x) * 0x100000))
+#define S5PC100_PA_HSMMC0	S5PC100_PA_HSMMC(0)
+#define S5PC100_PA_HSMMC1	S5PC100_PA_HSMMC(1)
+#define S5PC100_PA_HSMMC2	S5PC100_PA_HSMMC(2)
+
+/* LCD */
+#define S5PC100_PA_FB		(0xEE000000)
+
+/* Multimedia */
+#define S5PC100_PA_G2D		(0xEE800000)
+#define S5PC100_PA_JPEG		(0xEE500000)
+#define S5PC100_PA_ROTATOR	(0xEE100000)
+#define S5PC100_PA_G3D		(0xEF000000)
+
+/* I2S */
+#define S5PC100_PA_I2S0		(0xF2000000)
+#define S5PC100_PA_I2S1		(0xF2100000)
+#define S5PC100_PA_I2S2		(0xF2200000)
+
+/* KEYPAD */
+#define S5PC100_PA_KEYPAD	(0xF3100000)
+
+/* ADC & TouchScreen */
+#define S5PC100_PA_TSADC	(0xF3000000)
 
 /* ETC */
 #define S5PC100_PA_SDRAM	(0x20000000)
+#define S5PC1XX_PA_SDRAM	S5PC100_PA_SDRAM
 
 /* compatibility defines. */
+#define S3C_PA_RTC		S5PC100_PA_RTC
 #define S3C_PA_UART		S5PC100_PA_UART
 #define S3C_PA_UART0		(S5PC100_PA_UART + 0x0)
 #define S3C_PA_UART1		(S5PC100_PA_UART + 0x400)
@@ -67,9 +128,23 @@
 #define S3C_VA_UART2		(S3C_VA_UART + 0x800)
 #define S3C_VA_UART3		(S3C_VA_UART + 0xC00)
 #define S3C_UART_OFFSET		0x400
+#define S3C_VA_UARTx(x)		(S3C_VA_UART + ((x) * S3C_UART_OFFSET))
+#define S3C_PA_FB		S5PC100_PA_FB
+#define S3C_PA_G2D		S5PC100_PA_G2D
+#define S3C_PA_G3D		S5PC100_PA_G3D
+#define S3C_PA_JPEG		S5PC100_PA_JPEG
+#define S3C_PA_ROTATOR		S5PC100_PA_ROTATOR
 #define S3C_VA_VIC0		(S3C_VA_IRQ + 0x0)
 #define S3C_VA_VIC1		(S3C_VA_IRQ + 0x10000)
 #define S3C_VA_VIC2		(S3C_VA_IRQ + 0x20000)
-#define S3C_PA_IIC		S5PC100_PA_IIC
+#define S3C_PA_IIC		S5PC100_PA_I2C
+#define S3C_PA_IIC1		S5PC100_PA_I2C1
+#define S3C_PA_USB_HSOTG	S5PC100_PA_USB_HSOTG
+#define S3C_PA_USB_HSPHY	S5PC100_PA_USB_HSPHY
+#define S3C_PA_HSMMC0		S5PC100_PA_HSMMC0
+#define S3C_PA_HSMMC1		S5PC100_PA_HSMMC1
+#define S3C_PA_HSMMC2		S5PC100_PA_HSMMC2
+#define S3C_PA_KEYPAD		S5PC100_PA_KEYPAD
+#define S3C_PA_TSADC		S5PC100_PA_TSADC
 
 #endif /* __ASM_ARCH_C100_MAP_H */
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index 214093c..05bb20a 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -92,9 +92,9 @@ static void __init smdkc100_machine_init(void)
 
 MACHINE_START(SMDKC100, "SMDKC100")
 	/* Maintainer: Byungho Min <bhmin@samsung.com> */
-	.phys_io	= S5PC1XX_PA_UART & 0xfff00000,
+	.phys_io	= S5PC100_PA_UART & 0xfff00000,
 	.io_pg_offst	= (((u32)S5PC1XX_VA_UART) >> 18) & 0xfffc,
-	.boot_params	= S5PC100_PA_SDRAM + 0x100,
+	.boot_params	= S5PC1XX_PA_SDRAM + 0x100,
 
 	.init_irq	= s5pc100_init_irq,
 	.map_io		= smdkc100_map_io,
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 02/17] ARM: S5PC1XX: registers rename
@ 2009-10-13  8:11     ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

S5PC110 and S5PC100 register maps differs in many places, rename all
defined registers to be S5PC100 specific. System map has been also updated
to cover more integrated peripherals.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/include/mach/map.h |   87 +++++++++++++++++++++++++++--
 arch/arm/mach-s5pc100/mach-smdkc100.c    |    4 +-
 2 files changed, 83 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h
index 9e9f391..4681ebe 100644
--- a/arch/arm/mach-s5pc100/include/mach/map.h
+++ b/arch/arm/mach-s5pc100/include/mach/map.h
@@ -17,6 +17,19 @@
 
 #include <plat/map-base.h>
 
+/*
+ * map-base.h has already defined virtual memory address
+ * S3C_VA_IRQ		S3C_ADDR(0x00000000)	irq controller(s)
+ * S3C_VA_SYS		S3C_ADDR(0x00100000)	system control
+ * S3C_VA_MEM		S3C_ADDR(0x00200000)	system control (not used)
+ * S3C_VA_TIMER		S3C_ADDR(0x00300000)	timer block
+ * S3C_VA_WATCHDOG	S3C_ADDR(0x00400000)	watchdog
+ * S3C_VA_UART		S3C_ADDR(0x01000000)	UART
+ *
+ * S5PC100 specific virtual memory address can be defined here
+ * S5PC1XX_VA_GPIO	S3C_ADDR(0x00500000)	GPIO
+ *
+ */
 
 /* Chip ID */
 #define S5PC100_PA_CHIPID	(0xE0000000)
@@ -24,13 +37,20 @@
 #define S5PC1XX_VA_CHIPID	S3C_VA_SYS
 
 /* System */
-#define S5PC100_PA_SYS		(0xE0100000)
-#define S5PC100_PA_CLK		(S5PC100_PA_SYS + 0x0)
-#define S5PC100_PA_PWR		(S5PC100_PA_SYS + 0x8000)
+#define S5PC100_PA_CLK		(0xE0100000)
+#define S5PC100_PA_CLK_OTHER	(0xE0200000)
+#define S5PC100_PA_PWR		(0xE0108000)
 #define S5PC1XX_PA_CLK		S5PC100_PA_CLK
 #define S5PC1XX_PA_PWR		S5PC100_PA_PWR
+#define S5PC1XX_PA_CLK_OTHER	S5PC100_PA_CLK_OTHER
 #define S5PC1XX_VA_CLK		(S3C_VA_SYS + 0x10000)
 #define S5PC1XX_VA_PWR		(S3C_VA_SYS + 0x20000)
+#define S5PC1XX_VA_CLK_OTHER	(S3C_VA_SYS + 0x30000)
+
+/* GPIO */
+#define S5PC100_PA_GPIO		(0xE0300000)
+#define S5PC1XX_PA_GPIO		S5PC100_PA_GPIO
+#define S5PC1XX_VA_GPIO		S3C_ADDR(0x00500000)
 
 /* Interrupt */
 #define S5PC100_PA_VIC		(0xE4000000)
@@ -40,23 +60,64 @@
 #define S5PC1XX_PA_VIC(x)	(S5PC100_PA_VIC + ((x) * S5PC100_PA_VIC_OFFSET))
 #define S5PC1XX_VA_VIC(x)	(S5PC100_VA_VIC + ((x) * S5PC100_VA_VIC_OFFSET))
 
+/* DMA */
+#define S5PC100_PA_MDMA		(0xE8100000)
+#define S5PC100_PA_PDMA0	(0xE9000000)
+#define S5PC100_PA_PDMA1	(0xE9200000)
+
 /* Timer */
 #define S5PC100_PA_TIMER	(0xEA000000)
 #define S5PC1XX_PA_TIMER	S5PC100_PA_TIMER
 #define S5PC1XX_VA_TIMER	S3C_VA_TIMER
 
+/* RTC */
+#define S5PC100_PA_RTC		(0xEA300000)
+
 /* UART */
 #define S5PC100_PA_UART		(0xEC000000)
 #define S5PC1XX_PA_UART		S5PC100_PA_UART
 #define S5PC1XX_VA_UART		S3C_VA_UART
 
-/* IIC */
-#define S5PC100_PA_IIC		(0xEC100000)
+/* I2C */
+#define S5PC100_PA_I2C		(0xEC100000)
+#define S5PC100_PA_I2C1		(0xEC200000)
+
+/* USB HS OTG */
+#define S5PC100_PA_USB_HSOTG	(0xED200000)
+#define S5PC100_PA_USB_HSPHY	(0xED300000)
+
+/* SD/MMC */
+#define S5PC100_PA_HSMMC(x)	(0xED800000 + ((x) * 0x100000))
+#define S5PC100_PA_HSMMC0	S5PC100_PA_HSMMC(0)
+#define S5PC100_PA_HSMMC1	S5PC100_PA_HSMMC(1)
+#define S5PC100_PA_HSMMC2	S5PC100_PA_HSMMC(2)
+
+/* LCD */
+#define S5PC100_PA_FB		(0xEE000000)
+
+/* Multimedia */
+#define S5PC100_PA_G2D		(0xEE800000)
+#define S5PC100_PA_JPEG		(0xEE500000)
+#define S5PC100_PA_ROTATOR	(0xEE100000)
+#define S5PC100_PA_G3D		(0xEF000000)
+
+/* I2S */
+#define S5PC100_PA_I2S0		(0xF2000000)
+#define S5PC100_PA_I2S1		(0xF2100000)
+#define S5PC100_PA_I2S2		(0xF2200000)
+
+/* KEYPAD */
+#define S5PC100_PA_KEYPAD	(0xF3100000)
+
+/* ADC & TouchScreen */
+#define S5PC100_PA_TSADC	(0xF3000000)
 
 /* ETC */
 #define S5PC100_PA_SDRAM	(0x20000000)
+#define S5PC1XX_PA_SDRAM	S5PC100_PA_SDRAM
 
 /* compatibility defines. */
+#define S3C_PA_RTC		S5PC100_PA_RTC
 #define S3C_PA_UART		S5PC100_PA_UART
 #define S3C_PA_UART0		(S5PC100_PA_UART + 0x0)
 #define S3C_PA_UART1		(S5PC100_PA_UART + 0x400)
@@ -67,9 +128,23 @@
 #define S3C_VA_UART2		(S3C_VA_UART + 0x800)
 #define S3C_VA_UART3		(S3C_VA_UART + 0xC00)
 #define S3C_UART_OFFSET		0x400
+#define S3C_VA_UARTx(x)		(S3C_VA_UART + ((x) * S3C_UART_OFFSET))
+#define S3C_PA_FB		S5PC100_PA_FB
+#define S3C_PA_G2D		S5PC100_PA_G2D
+#define S3C_PA_G3D		S5PC100_PA_G3D
+#define S3C_PA_JPEG		S5PC100_PA_JPEG
+#define S3C_PA_ROTATOR		S5PC100_PA_ROTATOR
 #define S3C_VA_VIC0		(S3C_VA_IRQ + 0x0)
 #define S3C_VA_VIC1		(S3C_VA_IRQ + 0x10000)
 #define S3C_VA_VIC2		(S3C_VA_IRQ + 0x20000)
-#define S3C_PA_IIC		S5PC100_PA_IIC
+#define S3C_PA_IIC		S5PC100_PA_I2C
+#define S3C_PA_IIC1		S5PC100_PA_I2C1
+#define S3C_PA_USB_HSOTG	S5PC100_PA_USB_HSOTG
+#define S3C_PA_USB_HSPHY	S5PC100_PA_USB_HSPHY
+#define S3C_PA_HSMMC0		S5PC100_PA_HSMMC0
+#define S3C_PA_HSMMC1		S5PC100_PA_HSMMC1
+#define S3C_PA_HSMMC2		S5PC100_PA_HSMMC2
+#define S3C_PA_KEYPAD		S5PC100_PA_KEYPAD
+#define S3C_PA_TSADC		S5PC100_PA_TSADC
 
 #endif /* __ASM_ARCH_C100_MAP_H */
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index 214093c..05bb20a 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -92,9 +92,9 @@ static void __init smdkc100_machine_init(void)
 
 MACHINE_START(SMDKC100, "SMDKC100")
 	/* Maintainer: Byungho Min <bhmin@samsung.com> */
-	.phys_io	= S5PC1XX_PA_UART & 0xfff00000,
+	.phys_io	= S5PC100_PA_UART & 0xfff00000,
 	.io_pg_offst	= (((u32)S5PC1XX_VA_UART) >> 18) & 0xfffc,
-	.boot_params	= S5PC100_PA_SDRAM + 0x100,
+	.boot_params	= S5PC1XX_PA_SDRAM + 0x100,
 
 	.init_irq	= s5pc100_init_irq,
 	.map_io		= smdkc100_map_io,
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 03/17] ARM: S5PC1XX: clock registers rename
  2009-10-13  8:11     ` Marek Szyprowski
@ 2009-10-13  8:11       ` Marek Szyprowski
  -1 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: kyungmin.park, bhmin, ben-linux, m.szyprowski

S5PC100 and S5PC110 clock registers differs in many places, rename all
previously defined registers to be S5PC100 specific. Remove all power
management registers. They will be added later to a separate file.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/plat-s5pc1xx/include/plat/regs-clock.h |  183 ++++++++---------------
 arch/arm/plat-s5pc1xx/s5pc100-clock.c           |   44 +++---
 2 files changed, 84 insertions(+), 143 deletions(-)

diff --git a/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h b/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
index 75c8390..607d609 100644
--- a/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
+++ b/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
@@ -13,68 +13,68 @@
 #ifndef __PLAT_REGS_CLOCK_H
 #define __PLAT_REGS_CLOCK_H __FILE__
 
-#define S5PC1XX_CLKREG(x)		(S5PC1XX_VA_CLK + (x))
+#define S5PC100_CLKREG(x)		(S5PC1XX_VA_CLK + (x))
 
-#define S5PC1XX_APLL_LOCK		S5PC1XX_CLKREG(0x00)
-#define S5PC1XX_MPLL_LOCK		S5PC1XX_CLKREG(0x04)
-#define S5PC1XX_EPLL_LOCK		S5PC1XX_CLKREG(0x08)
-#define S5PC100_HPLL_LOCK		S5PC1XX_CLKREG(0x0C)
+/* s5pc100 register for clock */
+#define S5PC100_APLL_LOCK		S5PC100_CLKREG(0x00)
+#define S5PC100_MPLL_LOCK		S5PC100_CLKREG(0x04)
+#define S5PC100_EPLL_LOCK		S5PC100_CLKREG(0x08)
+#define S5PC100_HPLL_LOCK		S5PC100_CLKREG(0x0C)
 
-#define S5PC1XX_APLL_CON		S5PC1XX_CLKREG(0x100)
-#define S5PC1XX_MPLL_CON		S5PC1XX_CLKREG(0x104)
-#define S5PC1XX_EPLL_CON		S5PC1XX_CLKREG(0x108)
-#define S5PC100_HPLL_CON		S5PC1XX_CLKREG(0x10C)
+#define S5PC100_APLL_CON		S5PC100_CLKREG(0x100)
+#define S5PC100_MPLL_CON		S5PC100_CLKREG(0x104)
+#define S5PC100_EPLL_CON		S5PC100_CLKREG(0x108)
+#define S5PC100_HPLL_CON		S5PC100_CLKREG(0x10C)
 
-#define S5PC1XX_CLK_SRC0		S5PC1XX_CLKREG(0x200)
-#define S5PC1XX_CLK_SRC1		S5PC1XX_CLKREG(0x204)
-#define S5PC1XX_CLK_SRC2		S5PC1XX_CLKREG(0x208)
-#define S5PC1XX_CLK_SRC3		S5PC1XX_CLKREG(0x20C)
+#define S5PC100_CLKSRC0			S5PC100_CLKREG(0x200)
+#define S5PC100_CLKSRC1			S5PC100_CLKREG(0x204)
+#define S5PC100_CLKSRC2			S5PC100_CLKREG(0x208)
+#define S5PC100_CLKSRC3			S5PC100_CLKREG(0x20C)
 
-#define S5PC1XX_CLK_DIV0		S5PC1XX_CLKREG(0x300)
-#define S5PC1XX_CLK_DIV1		S5PC1XX_CLKREG(0x304)
-#define S5PC1XX_CLK_DIV2		S5PC1XX_CLKREG(0x308)
-#define S5PC1XX_CLK_DIV3		S5PC1XX_CLKREG(0x30C)
-#define S5PC1XX_CLK_DIV4		S5PC1XX_CLKREG(0x310)
+#define S5PC100_CLKDIV0			S5PC100_CLKREG(0x300)
+#define S5PC100_CLKDIV1			S5PC100_CLKREG(0x304)
+#define S5PC100_CLKDIV2			S5PC100_CLKREG(0x308)
+#define S5PC100_CLKDIV3			S5PC100_CLKREG(0x30C)
+#define S5PC100_CLKDIV4			S5PC100_CLKREG(0x310)
 
-#define S5PC100_CLK_OUT			S5PC1XX_CLKREG(0x400)
+#define S5PC100_CLK_OUT			S5PC100_CLKREG(0x400)
 
-#define S5PC100_CLKGATE_D00		S5PC1XX_CLKREG(0x500)
-#define S5PC100_CLKGATE_D01		S5PC1XX_CLKREG(0x504)
-#define S5PC100_CLKGATE_D02		S5PC1XX_CLKREG(0x508)
+#define S5PC100_CLKGATE_D00		S5PC100_CLKREG(0x500)
+#define S5PC100_CLKGATE_D01		S5PC100_CLKREG(0x504)
+#define S5PC100_CLKGATE_D02		S5PC100_CLKREG(0x508)
 
-#define S5PC100_CLKGATE_D10		S5PC1XX_CLKREG(0x520)
-#define S5PC100_CLKGATE_D11		S5PC1XX_CLKREG(0x524)
-#define S5PC100_CLKGATE_D12		S5PC1XX_CLKREG(0x528)
-#define S5PC100_CLKGATE_D13		S5PC1XX_CLKREG(0x52C)
-#define S5PC100_CLKGATE_D14		S5PC1XX_CLKREG(0x530)
-#define S5PC100_CLKGATE_D15		S5PC1XX_CLKREG(0x534)
+#define S5PC100_CLKGATE_D10		S5PC100_CLKREG(0x520)
+#define S5PC100_CLKGATE_D11		S5PC100_CLKREG(0x524)
+#define S5PC100_CLKGATE_D12		S5PC100_CLKREG(0x528)
+#define S5PC100_CLKGATE_D13		S5PC100_CLKREG(0x52C)
+#define S5PC100_CLKGATE_D14		S5PC100_CLKREG(0x530)
+#define S5PC100_CLKGATE_D15		S5PC100_CLKREG(0x534)
 
-#define S5PC100_CLKGATE_D20		S5PC1XX_CLKREG(0x540)
+#define S5PC100_CLKGATE_D20		S5PC100_CLKREG(0x540)
 
-#define S5PC100_SCLKGATE0		S5PC1XX_CLKREG(0x560)
-#define S5PC100_SCLKGATE1		S5PC1XX_CLKREG(0x564)
+#define S5PC100_SCLKGATE0		S5PC100_CLKREG(0x560)
+#define S5PC100_SCLKGATE1		S5PC100_CLKREG(0x564)
 
-#define S5PC100_OTHERS          S5PC1XX_CLKREG(0x8200)
-
-#define S5PC1XX_EPLL_EN     (1<<31)
-#define S5PC1XX_EPLL_MASK   0xffffffff
-#define S5PC1XX_EPLLVAL(_m, _p, _s)   ((_m) << 16 | ((_p) << 8) | ((_s)))
+/* EPLL_CON */
+#define S5PC100_EPLL_EN			(1<<31)
+#define S5PC100_EPLL_MASK		0xffffffff
+#define S5PC100_EPLLVAL(_m, _p, _s)	((_m) << 16 | ((_p) << 8) | ((_s)))
 
 /* CLKSRC0 */
-#define S5PC1XX_CLKSRC0_APLL_MASK		(0x1<<0)
-#define S5PC1XX_CLKSRC0_APLL_SHIFT		(0)
-#define S5PC1XX_CLKSRC0_MPLL_MASK		(0x1<<4)
-#define S5PC1XX_CLKSRC0_MPLL_SHIFT		(4)
-#define S5PC1XX_CLKSRC0_EPLL_MASK		(0x1<<8)
-#define S5PC1XX_CLKSRC0_EPLL_SHIFT		(8)
+#define S5PC100_CLKSRC0_APLL_MASK		(0x1<<0)
+#define S5PC100_CLKSRC0_APLL_SHIFT		(0)
+#define S5PC100_CLKSRC0_MPLL_MASK		(0x1<<4)
+#define S5PC100_CLKSRC0_MPLL_SHIFT		(4)
+#define S5PC100_CLKSRC0_EPLL_MASK		(0x1<<8)
+#define S5PC100_CLKSRC0_EPLL_SHIFT		(8)
 #define S5PC100_CLKSRC0_HPLL_MASK		(0x1<<12)
 #define S5PC100_CLKSRC0_HPLL_SHIFT		(12)
 #define S5PC100_CLKSRC0_AMMUX_MASK		(0x1<<16)
 #define S5PC100_CLKSRC0_AMMUX_SHIFT		(16)
 #define S5PC100_CLKSRC0_HREF_MASK		(0x1<<20)
 #define S5PC100_CLKSRC0_HREF_SHIFT		(20)
-#define S5PC1XX_CLKSRC0_ONENAND_MASK	(0x1<<24)
-#define S5PC1XX_CLKSRC0_ONENAND_SHIFT	(24)
+#define S5PC100_CLKSRC0_ONENAND_MASK	(0x1<<24)
+#define S5PC100_CLKSRC0_ONENAND_SHIFT	(24)
 
 
 /* CLKSRC1 */
@@ -127,10 +127,9 @@
 #define S5PC100_CLKSRC3_SPDIF_MASK		(0x3<<24)
 #define S5PC100_CLKSRC3_SPDIF_SHIFT		(24)
 
-
 /* CLKDIV0 */
-#define S5PC1XX_CLKDIV0_APLL_MASK		(0x1<<0)
-#define S5PC1XX_CLKDIV0_APLL_SHIFT		(0)
+#define S5PC100_CLKDIV0_APLL_MASK		(0x1<<0)
+#define S5PC100_CLKDIV0_APLL_SHIFT		(0)
 #define S5PC100_CLKDIV0_ARM_MASK		(0x7<<4)
 #define S5PC100_CLKDIV0_ARM_SHIFT		(4)
 #define S5PC100_CLKDIV0_D0_MASK		(0x7<<8)
@@ -141,8 +140,8 @@
 #define S5PC100_CLKDIV0_SECSS_SHIFT		(16)
 
 /* CLKDIV1 */
-#define S5PC100_CLKDIV1_AM_MASK		(0x7<<0)
-#define S5PC100_CLKDIV1_AM_SHIFT		(0)
+#define S5PC100_CLKDIV1_APLL2_MASK		(0x7<<0)
+#define S5PC100_CLKDIV1_APLL2_SHIFT		(0)
 #define S5PC100_CLKDIV1_MPLL_MASK		(0x3<<4)
 #define S5PC100_CLKDIV1_MPLL_SHIFT		(4)
 #define S5PC100_CLKDIV1_MPLL2_MASK		(0x1<<8)
@@ -202,7 +201,6 @@
 #define S5PC100_CLKDIV4_AUDIO2_MASK		(0xf<<20)
 #define S5PC100_CLKDIV4_AUDIO2_SHIFT	(20)
 
-
 /* HCLKD0/PCLKD0 Clock Gate 0 Registers */
 #define S5PC100_CLKGATE_D00_INTC		(1<<0)
 #define S5PC100_CLKGATE_D00_TZIC		(1<<1)
@@ -295,8 +293,8 @@
 #define S5PC100_CLKGATE_D20_I2SD2		(1<<1)
 
 /* Special Clock Gate 0 Registers */
-#define	S5PC1XX_CLKGATE_SCLK0_HPM		(1<<0)
-#define	S5PC1XX_CLKGATE_SCLK0_PWI		(1<<1)
+#define	S5PC100_CLKGATE_SCLK0_HPM		(1<<0)
+#define	S5PC100_CLKGATE_SCLK0_PWI		(1<<1)
 #define	S5PC100_CLKGATE_SCLK0_ONENAND	(1<<2)
 #define	S5PC100_CLKGATE_SCLK0_UART		(1<<3)
 #define	S5PC100_CLKGATE_SCLK0_SPI0		(1<<4)
@@ -329,74 +327,17 @@
 #define	S5PC100_CLKGATE_SCLK1_SPDIF		(1<<11)
 #define	S5PC100_CLKGATE_SCLK1_CAM		(1<<12)
 
-/* register for power management */
-#define S5PC100_PWR_CFG 		S5PC1XX_CLKREG(0x8000)
-#define S5PC100_EINT_WAKEUP_MASK 	S5PC1XX_CLKREG(0x8004)
-#define S5PC100_NORMAL_CFG 		S5PC1XX_CLKREG(0x8010)
-#define S5PC100_STOP_CFG 		S5PC1XX_CLKREG(0x8014)
-#define S5PC100_SLEEP_CFG 		S5PC1XX_CLKREG(0x8018)
-#define S5PC100_STOP_MEM_CFG 	S5PC1XX_CLKREG(0x801C)
-#define S5PC100_OSC_FREQ 		S5PC1XX_CLKREG(0x8100)
-#define S5PC100_OSC_STABLE 		S5PC1XX_CLKREG(0x8104)
-#define S5PC100_PWR_STABLE 		S5PC1XX_CLKREG(0x8108)
-#define S5PC100_MTC_STABLE 		S5PC1XX_CLKREG(0x8110)
-#define S5PC100_CLAMP_STABLE 	S5PC1XX_CLKREG(0x8114)
-#define S5PC100_OTHERS 		S5PC1XX_CLKREG(0x8200)
-#define S5PC100_RST_STAT 		S5PC1XX_CLKREG(0x8300)
-#define S5PC100_WAKEUP_STAT 	S5PC1XX_CLKREG(0x8304)
-#define S5PC100_BLK_PWR_STAT 	S5PC1XX_CLKREG(0x8308)
-#define S5PC100_INFORM0 		S5PC1XX_CLKREG(0x8400)
-#define S5PC100_INFORM1 		S5PC1XX_CLKREG(0x8404)
-#define S5PC100_INFORM2 		S5PC1XX_CLKREG(0x8408)
-#define S5PC100_INFORM3 		S5PC1XX_CLKREG(0x840C)
-#define S5PC100_INFORM4 		S5PC1XX_CLKREG(0x8410)
-#define S5PC100_INFORM5 		S5PC1XX_CLKREG(0x8414)
-#define S5PC100_INFORM6 		S5PC1XX_CLKREG(0x8418)
-#define S5PC100_INFORM7 		S5PC1XX_CLKREG(0x841C)
-#define S5PC100_DCGIDX_MAP0 	S5PC1XX_CLKREG(0x8500)
-#define S5PC100_DCGIDX_MAP1 	S5PC1XX_CLKREG(0x8504)
-#define S5PC100_DCGIDX_MAP2 	S5PC1XX_CLKREG(0x8508)
-#define S5PC100_DCGPERF_MAP0 	S5PC1XX_CLKREG(0x850C)
-#define S5PC100_DCGPERF_MAP1 	S5PC1XX_CLKREG(0x8510)
-#define S5PC100_DVCIDX_MAP 		S5PC1XX_CLKREG(0x8514)
-#define S5PC100_FREQ_CPU 		S5PC1XX_CLKREG(0x8518)
-#define S5PC100_FREQ_DPM 		S5PC1XX_CLKREG(0x851C)
-#define S5PC100_DVSEMCLK_EN 	S5PC1XX_CLKREG(0x8520)
-#define S5PC100_APLL_CON_L8 	S5PC1XX_CLKREG(0x8600)
-#define S5PC100_APLL_CON_L7 	S5PC1XX_CLKREG(0x8604)
-#define S5PC100_APLL_CON_L6 	S5PC1XX_CLKREG(0x8608)
-#define S5PC100_APLL_CON_L5 	S5PC1XX_CLKREG(0x860C)
-#define S5PC100_APLL_CON_L4 	S5PC1XX_CLKREG(0x8610)
-#define S5PC100_APLL_CON_L3 	S5PC1XX_CLKREG(0x8614)
-#define S5PC100_APLL_CON_L2 	S5PC1XX_CLKREG(0x8618)
-#define S5PC100_APLL_CON_L1 	S5PC1XX_CLKREG(0x861C)
-#define S5PC100_IEM_CONTROL 	S5PC1XX_CLKREG(0x8620)
-#define S5PC100_CLKDIV_IEM_L8 	S5PC1XX_CLKREG(0x8700)
-#define S5PC100_CLKDIV_IEM_L7 	S5PC1XX_CLKREG(0x8704)
-#define S5PC100_CLKDIV_IEM_L6 	S5PC1XX_CLKREG(0x8708)
-#define S5PC100_CLKDIV_IEM_L5 	S5PC1XX_CLKREG(0x870C)
-#define S5PC100_CLKDIV_IEM_L4 	S5PC1XX_CLKREG(0x8710)
-#define S5PC100_CLKDIV_IEM_L3 	S5PC1XX_CLKREG(0x8714)
-#define S5PC100_CLKDIV_IEM_L2 	S5PC1XX_CLKREG(0x8718)
-#define S5PC100_CLKDIV_IEM_L1 	S5PC1XX_CLKREG(0x871C)
-#define S5PC100_IEM_HPMCLK_DIV 	S5PC1XX_CLKREG(0x8724)
-
-#define S5PC100_SWRESET		S5PC1XX_CLKREG(0x100000)
-#define S5PC100_OND_SWRESET		S5PC1XX_CLKREG(0x100008)
-#define S5PC100_GEN_CTRL		S5PC1XX_CLKREG(0x100100)
-#define S5PC100_GEN_STATUS		S5PC1XX_CLKREG(0x100104)
-#define S5PC100_MEM_SYS_CFG		S5PC1XX_CLKREG(0x100200)
-#define S5PC100_CAM_MUX_SEL		S5PC1XX_CLKREG(0x100300)
-#define S5PC100_MIXER_OUT_SEL	S5PC1XX_CLKREG(0x100304)
-#define S5PC100_LPMP_MODE_SEL	S5PC1XX_CLKREG(0x100308)
-#define S5PC100_MIPI_PHY_CON0	S5PC1XX_CLKREG(0x100400)
-#define S5PC100_MIPI_PHY_CON1	S5PC1XX_CLKREG(0x100414)
-#define S5PC100_HDMI_PHY_CON0	S5PC1XX_CLKREG(0x100420)
-
-#define S5PC100_CFG_WFI_CLEAN	(~(3<<5))
-#define S5PC100_CFG_WFI_IDLE	(1<<5)
-#define S5PC100_CFG_WFI_STOP	(2<<5)
-#define S5PC100_CFG_WFI_SLEEP	(3<<5)
+#define S5PC100_SWRESET		S5PC100_CLKREG(0x100000)
+#define S5PC100_OND_SWRESET		S5PC100_CLKREG(0x100008)
+#define S5PC100_GEN_CTRL		S5PC100_CLKREG(0x100100)
+#define S5PC100_GEN_STATUS		S5PC100_CLKREG(0x100104)
+#define S5PC100_MEM_SYS_CFG		S5PC100_CLKREG(0x100200)
+#define S5PC100_CAM_MUX_SEL		S5PC100_CLKREG(0x100300)
+#define S5PC100_MIXER_OUT_SEL	S5PC100_CLKREG(0x100304)
+#define S5PC100_LPMP_MODE_SEL	S5PC100_CLKREG(0x100308)
+#define S5PC100_MIPI_PHY_CON0	S5PC100_CLKREG(0x100400)
+#define S5PC100_MIPI_PHY_CON1	S5PC100_CLKREG(0x100414)
+#define S5PC100_HDMI_PHY_CON0	S5PC100_CLKREG(0x100420)
 
 #define S5PC100_OTHER_SYS_INT	24
 #define S5PC100_OTHER_STA_TYPE	23
@@ -411,7 +352,7 @@
 #define S5PC100_SLEEP_CFG_OSC_EN	0
 
 /* OTHERS Resgister */
-#define S5PC100_OTHERS_USB_SIG_MASK 	(1 << 16)
+#define S5PC100_OTHERS_USB_SIG_MASK	(1 << 16)
 #define S5PC100_OTHERS_MIPI_DPHY_EN		(1 << 28)
 
 /* MIPI D-PHY Control Register 0 */
diff --git a/arch/arm/plat-s5pc1xx/s5pc100-clock.c b/arch/arm/plat-s5pc1xx/s5pc100-clock.c
index 6b24035..efc868b 100644
--- a/arch/arm/plat-s5pc1xx/s5pc100-clock.c
+++ b/arch/arm/plat-s5pc1xx/s5pc100-clock.c
@@ -87,13 +87,13 @@ static int clk_48m_ctrl(struct clk *clk, int enable)
 	/* can't rely on clock lock, this register has other usages */
 	local_irq_save(flags);
 
-	val = __raw_readl(S5PC1XX_CLK_SRC1);
+	val = __raw_readl(S5PC100_CLKSRC1);
 	if (enable)
 		val |= S5PC100_CLKSRC1_CLK48M_MASK;
 	else
 		val &= ~S5PC100_CLKSRC1_CLK48M_MASK;
 
-	__raw_writel(val, S5PC1XX_CLK_SRC1);
+	__raw_writel(val, S5PC100_CLKSRC1);
 	local_irq_restore(flags);
 
 	return 0;
@@ -685,7 +685,7 @@ static struct clk init_clocks[] = {
 		.id		= -1,
 		.parent		= NULL,
 		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC1XX_CLKGATE_SCLK0_HPM,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_HPM,
 	}, {
 		.name		= "sclk_onenand",
 		.id		= -1,
@@ -801,10 +801,10 @@ static struct clksrc_clk clk_mout_apll = {
 		.name		= "mout_apll",
 		.id		= -1,
 	},
-	.shift		= S5PC1XX_CLKSRC0_APLL_SHIFT,
-	.mask		= S5PC1XX_CLKSRC0_APLL_MASK,
+	.shift		= S5PC100_CLKSRC0_APLL_SHIFT,
+	.mask		= S5PC100_CLKSRC0_APLL_MASK,
 	.sources	= &clk_src_apll,
-	.reg_source	= S5PC1XX_CLK_SRC0,
+	.reg_source	= S5PC100_CLKSRC0,
 };
 
 static struct clk clk_fout_epll = {
@@ -827,10 +827,10 @@ static struct clksrc_clk clk_mout_epll = {
 		.name		= "mout_epll",
 		.id		= -1,
 	},
-	.shift		= S5PC1XX_CLKSRC0_EPLL_SHIFT,
-	.mask		= S5PC1XX_CLKSRC0_EPLL_MASK,
+	.shift		= S5PC100_CLKSRC0_EPLL_SHIFT,
+	.mask		= S5PC100_CLKSRC0_EPLL_MASK,
 	.sources	= &clk_src_epll,
-	.reg_source	= S5PC1XX_CLK_SRC0,
+	.reg_source	= S5PC100_CLKSRC0,
 };
 
 static struct clk *clk_src_mpll_list[] = {
@@ -848,10 +848,10 @@ static struct clksrc_clk clk_mout_mpll = {
 		.name		= "mout_mpll",
 		.id		= -1,
 	},
-	.shift		= S5PC1XX_CLKSRC0_MPLL_SHIFT,
-	.mask		= S5PC1XX_CLKSRC0_MPLL_MASK,
+	.shift		= S5PC100_CLKSRC0_MPLL_SHIFT,
+	.mask		= S5PC100_CLKSRC0_MPLL_MASK,
 	.sources	= &clk_src_mpll,
-	.reg_source	= S5PC1XX_CLK_SRC0,
+	.reg_source	= S5PC100_CLKSRC0,
 };
 
 static unsigned long s5pc1xx_clk_doutmpll_get_rate(struct clk *clk)
@@ -861,7 +861,7 @@ static unsigned long s5pc1xx_clk_doutmpll_get_rate(struct clk *clk)
 
 	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
 
-	clkdiv = __raw_readl(S5PC1XX_CLK_DIV1) & S5PC100_CLKDIV1_MPLL_MASK;
+	clkdiv = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_MPLL_MASK;
 	rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL_SHIFT) + 1;
 
 	return rate;
@@ -881,7 +881,7 @@ static unsigned long s5pc1xx_clk_doutmpll2_get_rate(struct clk *clk)
 
 	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
 
-	clkdiv = __raw_readl(S5PC1XX_CLK_DIV1) & S5PC100_CLKDIV1_MPLL2_MASK;
+	clkdiv = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_MPLL2_MASK;
 	rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL2_SHIFT) + 1;
 
 	return rate;
@@ -1007,8 +1007,8 @@ static struct clksrc_clk clk_uart_uclk1 = {
 	.mask		= S5PC100_CLKSRC1_UART_MASK,
 	.sources	= &clkset_uart,
 	.divider_shift	= S5PC100_CLKDIV2_UART_SHIFT,
-	.reg_divider	= S5PC1XX_CLK_DIV2,
-	.reg_source	= S5PC1XX_CLK_SRC1,
+	.reg_divider	= S5PC100_CLKDIV2,
+	.reg_source	= S5PC100_CLKSRC1,
 };
 
 /* Clock initialisation code */
@@ -1061,8 +1061,8 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
 
 	printk(KERN_DEBUG "%s: registering clocks\n", __func__);
 
-	clkdiv0 = __raw_readl(S5PC1XX_CLK_DIV0);
-	clkdiv1 = __raw_readl(S5PC1XX_CLK_DIV1);
+	clkdiv0 = __raw_readl(S5PC100_CLKDIV0);
+	clkdiv1 = __raw_readl(S5PC100_CLKDIV1);
 
 	printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
 			__func__, clkdiv0, clkdiv1);
@@ -1075,15 +1075,15 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
 
 	printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
 
-	apll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_APLL_CON));
-	mpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_MPLL_CON));
-	epll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_EPLL_CON));
+	apll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_APLL_CON));
+	mpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_MPLL_CON));
+	epll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_EPLL_CON));
 	hpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_HPLL_CON));
 
 	printk(KERN_INFO "S5PC100: PLL settings, A=%ld, M=%ld, E=%ld, H=%ld\n",
 	       apll, mpll, epll, hpll);
 
-	armclk = apll / GET_DIV(clkdiv0, S5PC1XX_CLKDIV0_APLL);
+	armclk = apll / GET_DIV(clkdiv0, S5PC100_CLKDIV0_APLL);
 	armclk = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_ARM);
 	hclkd0 = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_D0);
 	pclkd0 = hclkd0 / GET_DIV(clkdiv0, S5PC100_CLKDIV0_PCLKD0);
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 03/17] ARM: S5PC1XX: clock registers rename
@ 2009-10-13  8:11       ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

S5PC100 and S5PC110 clock registers differs in many places, rename all
previously defined registers to be S5PC100 specific. Remove all power
management registers. They will be added later to a separate file.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/plat-s5pc1xx/include/plat/regs-clock.h |  183 ++++++++---------------
 arch/arm/plat-s5pc1xx/s5pc100-clock.c           |   44 +++---
 2 files changed, 84 insertions(+), 143 deletions(-)

diff --git a/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h b/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
index 75c8390..607d609 100644
--- a/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
+++ b/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
@@ -13,68 +13,68 @@
 #ifndef __PLAT_REGS_CLOCK_H
 #define __PLAT_REGS_CLOCK_H __FILE__
 
-#define S5PC1XX_CLKREG(x)		(S5PC1XX_VA_CLK + (x))
+#define S5PC100_CLKREG(x)		(S5PC1XX_VA_CLK + (x))
 
-#define S5PC1XX_APLL_LOCK		S5PC1XX_CLKREG(0x00)
-#define S5PC1XX_MPLL_LOCK		S5PC1XX_CLKREG(0x04)
-#define S5PC1XX_EPLL_LOCK		S5PC1XX_CLKREG(0x08)
-#define S5PC100_HPLL_LOCK		S5PC1XX_CLKREG(0x0C)
+/* s5pc100 register for clock */
+#define S5PC100_APLL_LOCK		S5PC100_CLKREG(0x00)
+#define S5PC100_MPLL_LOCK		S5PC100_CLKREG(0x04)
+#define S5PC100_EPLL_LOCK		S5PC100_CLKREG(0x08)
+#define S5PC100_HPLL_LOCK		S5PC100_CLKREG(0x0C)
 
-#define S5PC1XX_APLL_CON		S5PC1XX_CLKREG(0x100)
-#define S5PC1XX_MPLL_CON		S5PC1XX_CLKREG(0x104)
-#define S5PC1XX_EPLL_CON		S5PC1XX_CLKREG(0x108)
-#define S5PC100_HPLL_CON		S5PC1XX_CLKREG(0x10C)
+#define S5PC100_APLL_CON		S5PC100_CLKREG(0x100)
+#define S5PC100_MPLL_CON		S5PC100_CLKREG(0x104)
+#define S5PC100_EPLL_CON		S5PC100_CLKREG(0x108)
+#define S5PC100_HPLL_CON		S5PC100_CLKREG(0x10C)
 
-#define S5PC1XX_CLK_SRC0		S5PC1XX_CLKREG(0x200)
-#define S5PC1XX_CLK_SRC1		S5PC1XX_CLKREG(0x204)
-#define S5PC1XX_CLK_SRC2		S5PC1XX_CLKREG(0x208)
-#define S5PC1XX_CLK_SRC3		S5PC1XX_CLKREG(0x20C)
+#define S5PC100_CLKSRC0			S5PC100_CLKREG(0x200)
+#define S5PC100_CLKSRC1			S5PC100_CLKREG(0x204)
+#define S5PC100_CLKSRC2			S5PC100_CLKREG(0x208)
+#define S5PC100_CLKSRC3			S5PC100_CLKREG(0x20C)
 
-#define S5PC1XX_CLK_DIV0		S5PC1XX_CLKREG(0x300)
-#define S5PC1XX_CLK_DIV1		S5PC1XX_CLKREG(0x304)
-#define S5PC1XX_CLK_DIV2		S5PC1XX_CLKREG(0x308)
-#define S5PC1XX_CLK_DIV3		S5PC1XX_CLKREG(0x30C)
-#define S5PC1XX_CLK_DIV4		S5PC1XX_CLKREG(0x310)
+#define S5PC100_CLKDIV0			S5PC100_CLKREG(0x300)
+#define S5PC100_CLKDIV1			S5PC100_CLKREG(0x304)
+#define S5PC100_CLKDIV2			S5PC100_CLKREG(0x308)
+#define S5PC100_CLKDIV3			S5PC100_CLKREG(0x30C)
+#define S5PC100_CLKDIV4			S5PC100_CLKREG(0x310)
 
-#define S5PC100_CLK_OUT			S5PC1XX_CLKREG(0x400)
+#define S5PC100_CLK_OUT			S5PC100_CLKREG(0x400)
 
-#define S5PC100_CLKGATE_D00		S5PC1XX_CLKREG(0x500)
-#define S5PC100_CLKGATE_D01		S5PC1XX_CLKREG(0x504)
-#define S5PC100_CLKGATE_D02		S5PC1XX_CLKREG(0x508)
+#define S5PC100_CLKGATE_D00		S5PC100_CLKREG(0x500)
+#define S5PC100_CLKGATE_D01		S5PC100_CLKREG(0x504)
+#define S5PC100_CLKGATE_D02		S5PC100_CLKREG(0x508)
 
-#define S5PC100_CLKGATE_D10		S5PC1XX_CLKREG(0x520)
-#define S5PC100_CLKGATE_D11		S5PC1XX_CLKREG(0x524)
-#define S5PC100_CLKGATE_D12		S5PC1XX_CLKREG(0x528)
-#define S5PC100_CLKGATE_D13		S5PC1XX_CLKREG(0x52C)
-#define S5PC100_CLKGATE_D14		S5PC1XX_CLKREG(0x530)
-#define S5PC100_CLKGATE_D15		S5PC1XX_CLKREG(0x534)
+#define S5PC100_CLKGATE_D10		S5PC100_CLKREG(0x520)
+#define S5PC100_CLKGATE_D11		S5PC100_CLKREG(0x524)
+#define S5PC100_CLKGATE_D12		S5PC100_CLKREG(0x528)
+#define S5PC100_CLKGATE_D13		S5PC100_CLKREG(0x52C)
+#define S5PC100_CLKGATE_D14		S5PC100_CLKREG(0x530)
+#define S5PC100_CLKGATE_D15		S5PC100_CLKREG(0x534)
 
-#define S5PC100_CLKGATE_D20		S5PC1XX_CLKREG(0x540)
+#define S5PC100_CLKGATE_D20		S5PC100_CLKREG(0x540)
 
-#define S5PC100_SCLKGATE0		S5PC1XX_CLKREG(0x560)
-#define S5PC100_SCLKGATE1		S5PC1XX_CLKREG(0x564)
+#define S5PC100_SCLKGATE0		S5PC100_CLKREG(0x560)
+#define S5PC100_SCLKGATE1		S5PC100_CLKREG(0x564)
 
-#define S5PC100_OTHERS          S5PC1XX_CLKREG(0x8200)
-
-#define S5PC1XX_EPLL_EN     (1<<31)
-#define S5PC1XX_EPLL_MASK   0xffffffff
-#define S5PC1XX_EPLLVAL(_m, _p, _s)   ((_m) << 16 | ((_p) << 8) | ((_s)))
+/* EPLL_CON */
+#define S5PC100_EPLL_EN			(1<<31)
+#define S5PC100_EPLL_MASK		0xffffffff
+#define S5PC100_EPLLVAL(_m, _p, _s)	((_m) << 16 | ((_p) << 8) | ((_s)))
 
 /* CLKSRC0 */
-#define S5PC1XX_CLKSRC0_APLL_MASK		(0x1<<0)
-#define S5PC1XX_CLKSRC0_APLL_SHIFT		(0)
-#define S5PC1XX_CLKSRC0_MPLL_MASK		(0x1<<4)
-#define S5PC1XX_CLKSRC0_MPLL_SHIFT		(4)
-#define S5PC1XX_CLKSRC0_EPLL_MASK		(0x1<<8)
-#define S5PC1XX_CLKSRC0_EPLL_SHIFT		(8)
+#define S5PC100_CLKSRC0_APLL_MASK		(0x1<<0)
+#define S5PC100_CLKSRC0_APLL_SHIFT		(0)
+#define S5PC100_CLKSRC0_MPLL_MASK		(0x1<<4)
+#define S5PC100_CLKSRC0_MPLL_SHIFT		(4)
+#define S5PC100_CLKSRC0_EPLL_MASK		(0x1<<8)
+#define S5PC100_CLKSRC0_EPLL_SHIFT		(8)
 #define S5PC100_CLKSRC0_HPLL_MASK		(0x1<<12)
 #define S5PC100_CLKSRC0_HPLL_SHIFT		(12)
 #define S5PC100_CLKSRC0_AMMUX_MASK		(0x1<<16)
 #define S5PC100_CLKSRC0_AMMUX_SHIFT		(16)
 #define S5PC100_CLKSRC0_HREF_MASK		(0x1<<20)
 #define S5PC100_CLKSRC0_HREF_SHIFT		(20)
-#define S5PC1XX_CLKSRC0_ONENAND_MASK	(0x1<<24)
-#define S5PC1XX_CLKSRC0_ONENAND_SHIFT	(24)
+#define S5PC100_CLKSRC0_ONENAND_MASK	(0x1<<24)
+#define S5PC100_CLKSRC0_ONENAND_SHIFT	(24)
 
 
 /* CLKSRC1 */
@@ -127,10 +127,9 @@
 #define S5PC100_CLKSRC3_SPDIF_MASK		(0x3<<24)
 #define S5PC100_CLKSRC3_SPDIF_SHIFT		(24)
 
-
 /* CLKDIV0 */
-#define S5PC1XX_CLKDIV0_APLL_MASK		(0x1<<0)
-#define S5PC1XX_CLKDIV0_APLL_SHIFT		(0)
+#define S5PC100_CLKDIV0_APLL_MASK		(0x1<<0)
+#define S5PC100_CLKDIV0_APLL_SHIFT		(0)
 #define S5PC100_CLKDIV0_ARM_MASK		(0x7<<4)
 #define S5PC100_CLKDIV0_ARM_SHIFT		(4)
 #define S5PC100_CLKDIV0_D0_MASK		(0x7<<8)
@@ -141,8 +140,8 @@
 #define S5PC100_CLKDIV0_SECSS_SHIFT		(16)
 
 /* CLKDIV1 */
-#define S5PC100_CLKDIV1_AM_MASK		(0x7<<0)
-#define S5PC100_CLKDIV1_AM_SHIFT		(0)
+#define S5PC100_CLKDIV1_APLL2_MASK		(0x7<<0)
+#define S5PC100_CLKDIV1_APLL2_SHIFT		(0)
 #define S5PC100_CLKDIV1_MPLL_MASK		(0x3<<4)
 #define S5PC100_CLKDIV1_MPLL_SHIFT		(4)
 #define S5PC100_CLKDIV1_MPLL2_MASK		(0x1<<8)
@@ -202,7 +201,6 @@
 #define S5PC100_CLKDIV4_AUDIO2_MASK		(0xf<<20)
 #define S5PC100_CLKDIV4_AUDIO2_SHIFT	(20)
 
-
 /* HCLKD0/PCLKD0 Clock Gate 0 Registers */
 #define S5PC100_CLKGATE_D00_INTC		(1<<0)
 #define S5PC100_CLKGATE_D00_TZIC		(1<<1)
@@ -295,8 +293,8 @@
 #define S5PC100_CLKGATE_D20_I2SD2		(1<<1)
 
 /* Special Clock Gate 0 Registers */
-#define	S5PC1XX_CLKGATE_SCLK0_HPM		(1<<0)
-#define	S5PC1XX_CLKGATE_SCLK0_PWI		(1<<1)
+#define	S5PC100_CLKGATE_SCLK0_HPM		(1<<0)
+#define	S5PC100_CLKGATE_SCLK0_PWI		(1<<1)
 #define	S5PC100_CLKGATE_SCLK0_ONENAND	(1<<2)
 #define	S5PC100_CLKGATE_SCLK0_UART		(1<<3)
 #define	S5PC100_CLKGATE_SCLK0_SPI0		(1<<4)
@@ -329,74 +327,17 @@
 #define	S5PC100_CLKGATE_SCLK1_SPDIF		(1<<11)
 #define	S5PC100_CLKGATE_SCLK1_CAM		(1<<12)
 
-/* register for power management */
-#define S5PC100_PWR_CFG 		S5PC1XX_CLKREG(0x8000)
-#define S5PC100_EINT_WAKEUP_MASK 	S5PC1XX_CLKREG(0x8004)
-#define S5PC100_NORMAL_CFG 		S5PC1XX_CLKREG(0x8010)
-#define S5PC100_STOP_CFG 		S5PC1XX_CLKREG(0x8014)
-#define S5PC100_SLEEP_CFG 		S5PC1XX_CLKREG(0x8018)
-#define S5PC100_STOP_MEM_CFG 	S5PC1XX_CLKREG(0x801C)
-#define S5PC100_OSC_FREQ 		S5PC1XX_CLKREG(0x8100)
-#define S5PC100_OSC_STABLE 		S5PC1XX_CLKREG(0x8104)
-#define S5PC100_PWR_STABLE 		S5PC1XX_CLKREG(0x8108)
-#define S5PC100_MTC_STABLE 		S5PC1XX_CLKREG(0x8110)
-#define S5PC100_CLAMP_STABLE 	S5PC1XX_CLKREG(0x8114)
-#define S5PC100_OTHERS 		S5PC1XX_CLKREG(0x8200)
-#define S5PC100_RST_STAT 		S5PC1XX_CLKREG(0x8300)
-#define S5PC100_WAKEUP_STAT 	S5PC1XX_CLKREG(0x8304)
-#define S5PC100_BLK_PWR_STAT 	S5PC1XX_CLKREG(0x8308)
-#define S5PC100_INFORM0 		S5PC1XX_CLKREG(0x8400)
-#define S5PC100_INFORM1 		S5PC1XX_CLKREG(0x8404)
-#define S5PC100_INFORM2 		S5PC1XX_CLKREG(0x8408)
-#define S5PC100_INFORM3 		S5PC1XX_CLKREG(0x840C)
-#define S5PC100_INFORM4 		S5PC1XX_CLKREG(0x8410)
-#define S5PC100_INFORM5 		S5PC1XX_CLKREG(0x8414)
-#define S5PC100_INFORM6 		S5PC1XX_CLKREG(0x8418)
-#define S5PC100_INFORM7 		S5PC1XX_CLKREG(0x841C)
-#define S5PC100_DCGIDX_MAP0 	S5PC1XX_CLKREG(0x8500)
-#define S5PC100_DCGIDX_MAP1 	S5PC1XX_CLKREG(0x8504)
-#define S5PC100_DCGIDX_MAP2 	S5PC1XX_CLKREG(0x8508)
-#define S5PC100_DCGPERF_MAP0 	S5PC1XX_CLKREG(0x850C)
-#define S5PC100_DCGPERF_MAP1 	S5PC1XX_CLKREG(0x8510)
-#define S5PC100_DVCIDX_MAP 		S5PC1XX_CLKREG(0x8514)
-#define S5PC100_FREQ_CPU 		S5PC1XX_CLKREG(0x8518)
-#define S5PC100_FREQ_DPM 		S5PC1XX_CLKREG(0x851C)
-#define S5PC100_DVSEMCLK_EN 	S5PC1XX_CLKREG(0x8520)
-#define S5PC100_APLL_CON_L8 	S5PC1XX_CLKREG(0x8600)
-#define S5PC100_APLL_CON_L7 	S5PC1XX_CLKREG(0x8604)
-#define S5PC100_APLL_CON_L6 	S5PC1XX_CLKREG(0x8608)
-#define S5PC100_APLL_CON_L5 	S5PC1XX_CLKREG(0x860C)
-#define S5PC100_APLL_CON_L4 	S5PC1XX_CLKREG(0x8610)
-#define S5PC100_APLL_CON_L3 	S5PC1XX_CLKREG(0x8614)
-#define S5PC100_APLL_CON_L2 	S5PC1XX_CLKREG(0x8618)
-#define S5PC100_APLL_CON_L1 	S5PC1XX_CLKREG(0x861C)
-#define S5PC100_IEM_CONTROL 	S5PC1XX_CLKREG(0x8620)
-#define S5PC100_CLKDIV_IEM_L8 	S5PC1XX_CLKREG(0x8700)
-#define S5PC100_CLKDIV_IEM_L7 	S5PC1XX_CLKREG(0x8704)
-#define S5PC100_CLKDIV_IEM_L6 	S5PC1XX_CLKREG(0x8708)
-#define S5PC100_CLKDIV_IEM_L5 	S5PC1XX_CLKREG(0x870C)
-#define S5PC100_CLKDIV_IEM_L4 	S5PC1XX_CLKREG(0x8710)
-#define S5PC100_CLKDIV_IEM_L3 	S5PC1XX_CLKREG(0x8714)
-#define S5PC100_CLKDIV_IEM_L2 	S5PC1XX_CLKREG(0x8718)
-#define S5PC100_CLKDIV_IEM_L1 	S5PC1XX_CLKREG(0x871C)
-#define S5PC100_IEM_HPMCLK_DIV 	S5PC1XX_CLKREG(0x8724)
-
-#define S5PC100_SWRESET		S5PC1XX_CLKREG(0x100000)
-#define S5PC100_OND_SWRESET		S5PC1XX_CLKREG(0x100008)
-#define S5PC100_GEN_CTRL		S5PC1XX_CLKREG(0x100100)
-#define S5PC100_GEN_STATUS		S5PC1XX_CLKREG(0x100104)
-#define S5PC100_MEM_SYS_CFG		S5PC1XX_CLKREG(0x100200)
-#define S5PC100_CAM_MUX_SEL		S5PC1XX_CLKREG(0x100300)
-#define S5PC100_MIXER_OUT_SEL	S5PC1XX_CLKREG(0x100304)
-#define S5PC100_LPMP_MODE_SEL	S5PC1XX_CLKREG(0x100308)
-#define S5PC100_MIPI_PHY_CON0	S5PC1XX_CLKREG(0x100400)
-#define S5PC100_MIPI_PHY_CON1	S5PC1XX_CLKREG(0x100414)
-#define S5PC100_HDMI_PHY_CON0	S5PC1XX_CLKREG(0x100420)
-
-#define S5PC100_CFG_WFI_CLEAN	(~(3<<5))
-#define S5PC100_CFG_WFI_IDLE	(1<<5)
-#define S5PC100_CFG_WFI_STOP	(2<<5)
-#define S5PC100_CFG_WFI_SLEEP	(3<<5)
+#define S5PC100_SWRESET		S5PC100_CLKREG(0x100000)
+#define S5PC100_OND_SWRESET		S5PC100_CLKREG(0x100008)
+#define S5PC100_GEN_CTRL		S5PC100_CLKREG(0x100100)
+#define S5PC100_GEN_STATUS		S5PC100_CLKREG(0x100104)
+#define S5PC100_MEM_SYS_CFG		S5PC100_CLKREG(0x100200)
+#define S5PC100_CAM_MUX_SEL		S5PC100_CLKREG(0x100300)
+#define S5PC100_MIXER_OUT_SEL	S5PC100_CLKREG(0x100304)
+#define S5PC100_LPMP_MODE_SEL	S5PC100_CLKREG(0x100308)
+#define S5PC100_MIPI_PHY_CON0	S5PC100_CLKREG(0x100400)
+#define S5PC100_MIPI_PHY_CON1	S5PC100_CLKREG(0x100414)
+#define S5PC100_HDMI_PHY_CON0	S5PC100_CLKREG(0x100420)
 
 #define S5PC100_OTHER_SYS_INT	24
 #define S5PC100_OTHER_STA_TYPE	23
@@ -411,7 +352,7 @@
 #define S5PC100_SLEEP_CFG_OSC_EN	0
 
 /* OTHERS Resgister */
-#define S5PC100_OTHERS_USB_SIG_MASK 	(1 << 16)
+#define S5PC100_OTHERS_USB_SIG_MASK	(1 << 16)
 #define S5PC100_OTHERS_MIPI_DPHY_EN		(1 << 28)
 
 /* MIPI D-PHY Control Register 0 */
diff --git a/arch/arm/plat-s5pc1xx/s5pc100-clock.c b/arch/arm/plat-s5pc1xx/s5pc100-clock.c
index 6b24035..efc868b 100644
--- a/arch/arm/plat-s5pc1xx/s5pc100-clock.c
+++ b/arch/arm/plat-s5pc1xx/s5pc100-clock.c
@@ -87,13 +87,13 @@ static int clk_48m_ctrl(struct clk *clk, int enable)
 	/* can't rely on clock lock, this register has other usages */
 	local_irq_save(flags);
 
-	val = __raw_readl(S5PC1XX_CLK_SRC1);
+	val = __raw_readl(S5PC100_CLKSRC1);
 	if (enable)
 		val |= S5PC100_CLKSRC1_CLK48M_MASK;
 	else
 		val &= ~S5PC100_CLKSRC1_CLK48M_MASK;
 
-	__raw_writel(val, S5PC1XX_CLK_SRC1);
+	__raw_writel(val, S5PC100_CLKSRC1);
 	local_irq_restore(flags);
 
 	return 0;
@@ -685,7 +685,7 @@ static struct clk init_clocks[] = {
 		.id		= -1,
 		.parent		= NULL,
 		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC1XX_CLKGATE_SCLK0_HPM,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_HPM,
 	}, {
 		.name		= "sclk_onenand",
 		.id		= -1,
@@ -801,10 +801,10 @@ static struct clksrc_clk clk_mout_apll = {
 		.name		= "mout_apll",
 		.id		= -1,
 	},
-	.shift		= S5PC1XX_CLKSRC0_APLL_SHIFT,
-	.mask		= S5PC1XX_CLKSRC0_APLL_MASK,
+	.shift		= S5PC100_CLKSRC0_APLL_SHIFT,
+	.mask		= S5PC100_CLKSRC0_APLL_MASK,
 	.sources	= &clk_src_apll,
-	.reg_source	= S5PC1XX_CLK_SRC0,
+	.reg_source	= S5PC100_CLKSRC0,
 };
 
 static struct clk clk_fout_epll = {
@@ -827,10 +827,10 @@ static struct clksrc_clk clk_mout_epll = {
 		.name		= "mout_epll",
 		.id		= -1,
 	},
-	.shift		= S5PC1XX_CLKSRC0_EPLL_SHIFT,
-	.mask		= S5PC1XX_CLKSRC0_EPLL_MASK,
+	.shift		= S5PC100_CLKSRC0_EPLL_SHIFT,
+	.mask		= S5PC100_CLKSRC0_EPLL_MASK,
 	.sources	= &clk_src_epll,
-	.reg_source	= S5PC1XX_CLK_SRC0,
+	.reg_source	= S5PC100_CLKSRC0,
 };
 
 static struct clk *clk_src_mpll_list[] = {
@@ -848,10 +848,10 @@ static struct clksrc_clk clk_mout_mpll = {
 		.name		= "mout_mpll",
 		.id		= -1,
 	},
-	.shift		= S5PC1XX_CLKSRC0_MPLL_SHIFT,
-	.mask		= S5PC1XX_CLKSRC0_MPLL_MASK,
+	.shift		= S5PC100_CLKSRC0_MPLL_SHIFT,
+	.mask		= S5PC100_CLKSRC0_MPLL_MASK,
 	.sources	= &clk_src_mpll,
-	.reg_source	= S5PC1XX_CLK_SRC0,
+	.reg_source	= S5PC100_CLKSRC0,
 };
 
 static unsigned long s5pc1xx_clk_doutmpll_get_rate(struct clk *clk)
@@ -861,7 +861,7 @@ static unsigned long s5pc1xx_clk_doutmpll_get_rate(struct clk *clk)
 
 	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
 
-	clkdiv = __raw_readl(S5PC1XX_CLK_DIV1) & S5PC100_CLKDIV1_MPLL_MASK;
+	clkdiv = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_MPLL_MASK;
 	rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL_SHIFT) + 1;
 
 	return rate;
@@ -881,7 +881,7 @@ static unsigned long s5pc1xx_clk_doutmpll2_get_rate(struct clk *clk)
 
 	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
 
-	clkdiv = __raw_readl(S5PC1XX_CLK_DIV1) & S5PC100_CLKDIV1_MPLL2_MASK;
+	clkdiv = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_MPLL2_MASK;
 	rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL2_SHIFT) + 1;
 
 	return rate;
@@ -1007,8 +1007,8 @@ static struct clksrc_clk clk_uart_uclk1 = {
 	.mask		= S5PC100_CLKSRC1_UART_MASK,
 	.sources	= &clkset_uart,
 	.divider_shift	= S5PC100_CLKDIV2_UART_SHIFT,
-	.reg_divider	= S5PC1XX_CLK_DIV2,
-	.reg_source	= S5PC1XX_CLK_SRC1,
+	.reg_divider	= S5PC100_CLKDIV2,
+	.reg_source	= S5PC100_CLKSRC1,
 };
 
 /* Clock initialisation code */
@@ -1061,8 +1061,8 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
 
 	printk(KERN_DEBUG "%s: registering clocks\n", __func__);
 
-	clkdiv0 = __raw_readl(S5PC1XX_CLK_DIV0);
-	clkdiv1 = __raw_readl(S5PC1XX_CLK_DIV1);
+	clkdiv0 = __raw_readl(S5PC100_CLKDIV0);
+	clkdiv1 = __raw_readl(S5PC100_CLKDIV1);
 
 	printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
 			__func__, clkdiv0, clkdiv1);
@@ -1075,15 +1075,15 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
 
 	printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
 
-	apll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_APLL_CON));
-	mpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_MPLL_CON));
-	epll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_EPLL_CON));
+	apll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_APLL_CON));
+	mpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_MPLL_CON));
+	epll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_EPLL_CON));
 	hpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_HPLL_CON));
 
 	printk(KERN_INFO "S5PC100: PLL settings, A=%ld, M=%ld, E=%ld, H=%ld\n",
 	       apll, mpll, epll, hpll);
 
-	armclk = apll / GET_DIV(clkdiv0, S5PC1XX_CLKDIV0_APLL);
+	armclk = apll / GET_DIV(clkdiv0, S5PC100_CLKDIV0_APLL);
 	armclk = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_ARM);
 	hclkd0 = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_D0);
 	pclkd0 = hclkd0 / GET_DIV(clkdiv0, S5PC100_CLKDIV0_PCLKD0);
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 04/17] ARM: S5PC1XX: clocks reimplementation
  2009-10-13  8:11       ` Marek Szyprowski
@ 2009-10-13  8:11         ` Marek Szyprowski
  -1 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: kyungmin.park, bhmin, ben-linux, m.szyprowski

Clocks hierarchy has been completely reimplemented to match the S5PC100
specification.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/plat-s5pc1xx/Makefile               |    1 +
 arch/arm/plat-s5pc1xx/clock.c                |  728 ++++++++++++
 arch/arm/plat-s5pc1xx/cpu.c                  |    5 +
 arch/arm/plat-s5pc1xx/include/plat/s5pc100.h |    5 +-
 arch/arm/plat-s5pc1xx/s5pc100-clock.c        | 1531 +++++++++++++-------------
 5 files changed, 1504 insertions(+), 766 deletions(-)
 create mode 100644 arch/arm/plat-s5pc1xx/clock.c

diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile
index f1ecb2c..ebbf364 100644
--- a/arch/arm/plat-s5pc1xx/Makefile
+++ b/arch/arm/plat-s5pc1xx/Makefile
@@ -14,6 +14,7 @@ obj-				:=
 obj-y				+= dev-uart.o
 obj-y				+= cpu.o
 obj-y				+= irq.o
+obj-y				+= clock.o
 
 # CPU support
 
diff --git a/arch/arm/plat-s5pc1xx/clock.c b/arch/arm/plat-s5pc1xx/clock.c
new file mode 100644
index 0000000..26c21d8
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/clock.c
@@ -0,0 +1,728 @@
+/* linux/arch/arm/plat-s5pc1xx/clock.c
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *
+ * S5PC1XX Base clock support
+ *
+ * Based on plat-s3c64xx/clock.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/regs-clock.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+
+struct clk clk_27m = {
+	.name		= "clk_27m",
+	.id		= -1,
+	.rate		= 27000000,
+};
+
+static int clk_48m_ctrl(struct clk *clk, int enable)
+{
+	unsigned long flags;
+	u32 val;
+
+	/* can't rely on clock lock, this register has other usages */
+	local_irq_save(flags);
+
+	val = __raw_readl(S5PC100_CLKSRC1);
+	if (enable)
+		val |= S5PC100_CLKSRC1_CLK48M_MASK;
+	else
+		val &= ~S5PC100_CLKSRC1_CLK48M_MASK;
+
+	__raw_writel(val, S5PC100_CLKSRC1);
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+struct clk clk_48m = {
+	.name		= "clk_48m",
+	.id		= -1,
+	.rate		= 48000000,
+	.enable		= clk_48m_ctrl,
+};
+
+struct clk clk_54m = {
+	.name		= "clk_54m",
+	.id		= -1,
+	.rate		= 54000000,
+};
+
+static int clk_default_setrate(struct clk *clk, unsigned long rate)
+{
+	clk->rate = rate;
+	return 0;
+}
+
+static int clk_dummy_enable(struct clk *clk, int enable)
+{
+	return 0;
+}
+
+struct clk clk_hd0 = {
+	.name		= "hclkd0",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+	.set_rate	= clk_default_setrate,
+	.enable		= clk_dummy_enable,
+};
+
+struct clk clk_pd0 = {
+	.name		= "pclkd0",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+	.set_rate	= clk_default_setrate,
+	.enable		= clk_dummy_enable,
+};
+
+static int s5pc1xx_clk_gate(void __iomem *reg, struct clk *clk, int enable)
+{
+	unsigned int ctrlbit = clk->ctrlbit;
+	u32 con;
+
+	con = __raw_readl(reg);
+	if (enable)
+		con |= ctrlbit;
+	else
+		con &= ~ctrlbit;
+	__raw_writel(con, reg);
+
+	return 0;
+}
+
+static int s5pc100_clk_d00_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D00, clk, enable);
+}
+
+static int s5pc100_clk_d01_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D01, clk, enable);
+}
+
+static int s5pc100_clk_d02_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D02, clk, enable);
+}
+
+static int s5pc100_clk_d10_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D10, clk, enable);
+}
+
+static int s5pc100_clk_d11_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D11, clk, enable);
+}
+
+static int s5pc100_clk_d12_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D12, clk, enable);
+}
+
+static int s5pc100_clk_d13_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D13, clk, enable);
+}
+
+static int s5pc100_clk_d14_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D14, clk, enable);
+}
+
+static int s5pc100_clk_d15_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D15, clk, enable);
+}
+
+static int s5pc100_clk_d20_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D20, clk, enable);
+}
+
+int s5pc100_sclk0_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_SCLKGATE0, clk, enable);
+}
+
+int s5pc100_sclk1_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_SCLKGATE1, clk, enable);
+}
+
+static struct clk s5pc100_init_clocks_disable[] = {
+	{
+		.name		= "dsi",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_DSI,
+	}, {
+		.name		= "csi",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_CSI,
+	}, {
+		.name		= "ccan",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_CCAN0,
+	}, {
+		.name		= "ccan",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_CCAN1,
+	}, {
+		.name		= "keypad",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_KEYIF,
+	}, {
+		.name		= "hclkd2",
+		.id		= -1,
+		.parent		= NULL,
+		.enable		= s5pc100_clk_d20_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D20_HCLKD2,
+	}, {
+		.name		= "iis-d2",
+		.id		= -1,
+		.parent		= NULL,
+		.enable		= s5pc100_clk_d20_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D20_I2SD2,
+	},
+};
+
+static struct clk s5pc100_init_clocks[] = {
+	/* System1 (D0_0) devices */
+	{
+		.name		= "intc",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_INTC,
+	}, {
+		.name		= "tzic",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_TZIC,
+	}, {
+		.name		= "cf-ata",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_CFCON,
+	}, {
+		.name		= "mdma",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_MDMA,
+	}, {
+		.name		= "g2d",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_G2D,
+	}, {
+		.name		= "secss",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_SECSS,
+	}, {
+		.name		= "cssys",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_CSSYS,
+	},
+
+	/* Memory (D0_1) devices */
+	{
+		.name		= "dmc",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_DMC,
+	}, {
+		.name		= "sromc",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_SROMC,
+	}, {
+		.name		= "onenand",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_ONENAND,
+	}, {
+		.name		= "nand",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_NFCON,
+	}, {
+		.name		= "intmem",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_INTMEM,
+	}, {
+		.name		= "ebi",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_EBI,
+	},
+
+	/* System2 (D0_2) devices */
+	{
+		.name		= "seckey",
+		.id		= -1,
+		.parent		= &clk_pd0,
+		.enable		= s5pc100_clk_d02_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D02_SECKEY,
+	}, {
+		.name		= "sdm",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d02_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D02_SDM,
+	},
+
+	/* File (D1_0) devices */
+	{
+		.name		= "pdma",
+		.id		= 0,
+		.parent		= &clk_h,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_PDMA0,
+	}, {
+		.name		= "pdma",
+		.id		= 1,
+		.parent		= &clk_h,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_PDMA1,
+	}, {
+		.name		= "usb-host",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_USBHOST,
+	}, {
+		.name		= "otg",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_USBOTG,
+	}, {
+		.name		= "modem",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_MODEMIF,
+	}, {
+		.name		= "hsmmc",
+		.id		= 0,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC0,
+	}, {
+		.name		= "hsmmc",
+		.id		= 1,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC1,
+	}, {
+		.name		= "hsmmc",
+		.id		= 2,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC2,
+	},
+
+	/* Multimedia1 (D1_1) devices */
+	{
+		.name		= "lcd",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_LCD,
+	}, {
+		.name		= "rotator",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_ROTATOR,
+	}, {
+		.name		= "fimc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC0,
+	}, {
+		.name		= "fimc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC1,
+	}, {
+		.name		= "fimc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC2,
+	}, {
+		.name		= "jpeg",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_JPEG,
+	}, {
+		.name		= "g3d",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_G3D,
+	},
+
+	/* Multimedia2 (D1_2) devices */
+	{
+		.name		= "tv",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_TV,
+	}, {
+		.name		= "vp",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_VP,
+	}, {
+		.name		= "mixer",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_MIXER,
+	}, {
+		.name		= "hdmi",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_HDMI,
+	}, {
+		.name		= "mfc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_MFC,
+	},
+
+	/* System (D1_3) devices */
+	{
+		.name		= "chipid",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_CHIPID,
+	}, {
+		.name		= "gpio",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_GPIO,
+	}, {
+		.name		= "apc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_APC,
+	}, {
+		.name		= "iec",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_IEC,
+	}, {
+		.name		= "timers",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_PWM,
+	}, {
+		.name		= "systimer",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_SYSTIMER,
+	}, {
+		.name		= "watchdog",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_WDT,
+	}, {
+		.name		= "rtc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_RTC,
+	},
+
+	/* Connectivity (D1_4) devices */
+	{
+		.name		= "uart",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_UART0,
+	}, {
+		.name		= "uart",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_UART1,
+	}, {
+		.name		= "uart",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_UART2,
+	}, {
+		.name		= "uart",
+		.id		= 3,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_UART3,
+	}, {
+		.name		= "i2c",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_IIC,
+	}, {
+		.name		= "hdmi-i2c",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_HDMI_IIC,
+	}, {
+		.name		= "spi",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_SPI0,
+	}, {
+		.name		= "spi",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_SPI1,
+	}, {
+		.name		= "spi",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_SPI2,
+	}, {
+		.name		= "irda",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_IRDA,
+	}, {
+		.name		= "hsitx",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_HSITX,
+	}, {
+		.name		= "hsirx",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_HSIRX,
+	},
+
+	/* Audio (D1_5) devices */
+	{
+		.name		= "iis",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_IIS0,
+	}, {
+		.name		= "iis",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_IIS1,
+	}, {
+		.name		= "iis",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_IIS2,
+	}, {
+		.name		= "ac97",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_AC97,
+	}, {
+		.name		= "pcm",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_PCM0,
+	}, {
+		.name		= "pcm",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_PCM1,
+	}, {
+		.name		= "spdif",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_SPDIF,
+	}, {
+		.name		= "adc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_TSADC,
+	}, {
+		.name		= "cg",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_CG,
+	},
+
+	/* Audio (D2_0) devices: all disabled */
+
+	/* Special Clocks 0 */
+	{
+		.name		= "sclk_hpm",
+		.id		= -1,
+		.parent		= NULL,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_HPM,
+	}, {
+		.name		= "sclk_onenand",
+		.id		= -1,
+		.parent		= NULL,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_ONENAND,
+	}, {
+		.name		= "spi_48",
+		.id		= 0,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI0_48,
+	}, {
+		.name		= "spi_48",
+		.id		= 1,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI1_48,
+	}, {
+		.name		= "spi_48",
+		.id		= 2,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI2_48,
+	}, {
+		.name		= "mmc_48",
+		.id		= 0,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC0_48,
+	}, {
+		.name		= "mmc_48",
+		.id		= 1,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC1_48,
+	}, {
+		.name		= "mmc_48",
+		.id		= 2,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC2_48,
+	},
+	/* Special Clocks 1 */
+};
+
+static struct clk *clks[] __initdata = {
+	&clk_ext,
+	&clk_epll,
+	&clk_27m,
+	&clk_48m,
+	&clk_54m,
+};
+
+void __init s5pc1xx_register_clocks(void)
+{
+	struct clk *clkp;
+	int ret;
+	int ptr;
+	int size;
+
+	s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+	clkp = s5pc100_init_clocks;
+	size = ARRAY_SIZE(s5pc100_init_clocks);
+
+	for (ptr = 0; ptr < size; ptr++, clkp++) {
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
+	}
+
+	clkp = s5pc100_init_clocks_disable;
+	size = ARRAY_SIZE(s5pc100_init_clocks_disable);
+
+	for (ptr = 0; ptr < size; 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_pwmclk_init();
+}
diff --git a/arch/arm/plat-s5pc1xx/cpu.c b/arch/arm/plat-s5pc1xx/cpu.c
index 715a733..e8f3472 100644
--- a/arch/arm/plat-s5pc1xx/cpu.c
+++ b/arch/arm/plat-s5pc1xx/cpu.c
@@ -55,6 +55,11 @@ static struct cpu_table cpu_ids[] __initdata = {
 
 static struct map_desc s5pc1xx_iodesc[] __initdata = {
 	{
+		.virtual	= (unsigned long)S5PC1XX_VA_CLK_OTHER,
+		.pfn		= __phys_to_pfn(S5PC1XX_PA_CLK_OTHER),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
 		.virtual	= (unsigned long)S5PC1XX_VA_CHIPID,
 		.pfn		= __phys_to_pfn(S5PC1XX_PA_CHIPID),
 		.length		= SZ_16,
diff --git a/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h b/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h
index 45e2751..2531f34 100644
--- a/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h
+++ b/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h
@@ -35,10 +35,9 @@ extern struct clk clk_hpll;
 extern struct clk clk_hd0;
 extern struct clk clk_pd0;
 extern struct clk clk_54m;
-extern struct clk clk_dout_mpll2;
 extern void s5pc1xx_register_clocks(void);
-extern int s5pc1xx_sclk0_ctrl(struct clk *clk, int enable);
-extern int s5pc1xx_sclk1_ctrl(struct clk *clk, int enable);
+extern int s5pc100_sclk0_ctrl(struct clk *clk, int enable);
+extern int s5pc100_sclk1_ctrl(struct clk *clk, int enable);
 
 /* Some day, belows will be moved to plat-s5pc/include/plat/devs.h */
 extern struct s3c24xx_uart_resources s5pc1xx_uart_resources[];
diff --git a/arch/arm/plat-s5pc1xx/s5pc100-clock.c b/arch/arm/plat-s5pc1xx/s5pc100-clock.c
index efc868b..b436d44 100644
--- a/arch/arm/plat-s5pc1xx/s5pc100-clock.c
+++ b/arch/arm/plat-s5pc1xx/s5pc100-clock.c
@@ -49,6 +49,7 @@ static struct clk clk_ext_xtal_mux = {
 #define clk_fin_hpll clk_ext_xtal_mux
 
 #define clk_fout_mpll	clk_mpll
+#define clk_vclk_54m	clk_54m
 
 struct clk_sources {
 	unsigned int	nr_sources;
@@ -67,746 +68,327 @@ struct clksrc_clk {
 	void __iomem		*reg_source;
 };
 
-static int clk_default_setrate(struct clk *clk, unsigned long rate)
-{
-	clk->rate = rate;
-	return 1;
-}
-
-struct clk clk_27m = {
-	.name		= "clk_27m",
+/* APLL */
+static struct clk clk_fout_apll = {
+	.name		= "fout_apll",
 	.id		= -1,
 	.rate		= 27000000,
 };
 
-static int clk_48m_ctrl(struct clk *clk, int enable)
-{
-	unsigned long flags;
-	u32 val;
+static struct clk *clk_src_apll_list[] = {
+	[0] = &clk_fin_apll,
+	[1] = &clk_fout_apll,
+};
 
-	/* can't rely on clock lock, this register has other usages */
-	local_irq_save(flags);
+static struct clk_sources clk_src_apll = {
+	.sources	= clk_src_apll_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_apll_list),
+};
 
-	val = __raw_readl(S5PC100_CLKSRC1);
-	if (enable)
-		val |= S5PC100_CLKSRC1_CLK48M_MASK;
-	else
-		val &= ~S5PC100_CLKSRC1_CLK48M_MASK;
+static struct clksrc_clk clk_mout_apll = {
+	.clk	= {
+		.name		= "mout_apll",
+		.id		= -1,
+	},
+	.shift		= S5PC100_CLKSRC0_APLL_SHIFT,
+	.mask		= S5PC100_CLKSRC0_APLL_MASK,
+	.sources	= &clk_src_apll,
+	.reg_source	= S5PC100_CLKSRC0,
+};
 
-	__raw_writel(val, S5PC100_CLKSRC1);
-	local_irq_restore(flags);
+static unsigned long s5pc100_clk_dout_apll_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
 
-	return 0;
-}
+	ratio = __raw_readl(S5PC100_CLKDIV0) & S5PC100_CLKDIV0_APLL_MASK;
+	ratio >>= S5PC100_CLKDIV0_APLL_SHIFT;
 
-struct clk clk_48m = {
-	.name		= "clk_48m",
-	.id		= -1,
-	.rate		= 48000000,
-	.enable		= clk_48m_ctrl,
-};
+	return rate / (ratio + 1);
+}
 
-struct clk clk_54m = {
-	.name		= "clk_54m",
+static struct clk clk_dout_apll = {
+	.name		= "dout_apll",
 	.id		= -1,
-	.rate		= 54000000,
+	.parent		= &clk_mout_apll.clk,
+	.get_rate	= s5pc100_clk_dout_apll_get_rate,
 };
 
-struct clk clk_hpll = {
-	.name		= "hpll",
-	.id		= -1,
-};
+static unsigned long s5pc100_clk_arm_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
 
-struct clk clk_hd0 = {
-	.name		= "hclkd0",
-	.id		= -1,
-	.rate		= 0,
-	.parent		= NULL,
-	.ctrlbit	= 0,
-	.set_rate	= clk_default_setrate,
-};
+	ratio = __raw_readl(S5PC100_CLKDIV0) & S5PC100_CLKDIV0_ARM_MASK;
+	ratio >>= S5PC100_CLKDIV0_ARM_SHIFT;
 
-struct clk clk_pd0 = {
-	.name		= "pclkd0",
-	.id		= -1,
-	.rate		= 0,
-	.parent		= NULL,
-	.ctrlbit	= 0,
-	.set_rate	= clk_default_setrate,
-};
+	return rate / (ratio + 1);
+}
 
-static int s5pc1xx_clk_gate(void __iomem *reg,
-				struct clk *clk,
-				int enable)
+static unsigned long s5pc100_clk_arm_round_rate(struct clk *clk,
+						unsigned long rate)
 {
-	unsigned int ctrlbit = clk->ctrlbit;
-	u32 con;
+	unsigned long parent = clk_get_rate(clk->parent);
+	u32 div;
 
-	con = __raw_readl(reg);
+	if (parent < rate)
+		return rate;
 
-	if (enable)
-		con |= ctrlbit;
-	else
-		con &= ~ctrlbit;
+	div = (parent / rate) - 1;
+	if (div > S5PC100_CLKDIV0_ARM_MASK)
+		div = S5PC100_CLKDIV0_ARM_MASK;
 
-	__raw_writel(con, reg);
-	return 0;
+	return parent / (div + 1);
 }
 
-static int s5pc1xx_clk_d00_ctrl(struct clk *clk, int enable)
+static int s5pc100_clk_arm_set_rate(struct clk *clk, unsigned long rate)
 {
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D00, clk, enable);
-}
+	unsigned long parent = clk_get_rate(clk->parent);
+	u32 div;
+	u32 val;
 
-static int s5pc1xx_clk_d01_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D01, clk, enable);
-}
+	if (rate < parent / (S5PC100_CLKDIV0_ARM_MASK + 1))
+		return -EINVAL;
 
-static int s5pc1xx_clk_d02_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D02, clk, enable);
-}
+	rate = clk_round_rate(clk, rate);
+	div = clk_get_rate(clk->parent) / rate;
 
-static int s5pc1xx_clk_d10_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D10, clk, enable);
-}
+	val = __raw_readl(S5PC100_CLKDIV0);
+	val &= S5PC100_CLKDIV0_ARM_MASK;
+	val |= (div - 1);
+	__raw_writel(val, S5PC100_CLKDIV0);
 
-static int s5pc1xx_clk_d11_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D11, clk, enable);
+	return 0;
 }
 
-static int s5pc1xx_clk_d12_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D12, clk, enable);
-}
+static struct clk clk_arm = {
+	.name		= "armclk",
+	.id		= -1,
+	.parent		= &clk_dout_apll,
+	.get_rate	= s5pc100_clk_arm_get_rate,
+	.set_rate	= s5pc100_clk_arm_set_rate,
+	.round_rate	= s5pc100_clk_arm_round_rate,
+};
 
-static int s5pc1xx_clk_d13_ctrl(struct clk *clk, int enable)
+static unsigned long s5pc100_clk_dout_d0_bus_get_rate(struct clk *clk)
 {
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D13, clk, enable);
-}
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
 
-static int s5pc1xx_clk_d14_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D14, clk, enable);
-}
+	ratio = __raw_readl(S5PC100_CLKDIV0) & S5PC100_CLKDIV0_D0_MASK;
+	ratio >>= S5PC100_CLKDIV0_D0_SHIFT;
 
-static int s5pc1xx_clk_d15_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D15, clk, enable);
+	return rate / (ratio + 1);
 }
 
-static int s5pc1xx_clk_d20_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D20, clk, enable);
-}
+static struct clk clk_dout_d0_bus = {
+	.name		= "dout_d0_bus",
+	.id		= -1,
+	.parent		= &clk_arm,
+	.get_rate	= s5pc100_clk_dout_d0_bus_get_rate,
+};
 
-int s5pc1xx_sclk0_ctrl(struct clk *clk, int enable)
+static unsigned long s5pc100_clk_dout_pclkd0_get_rate(struct clk *clk)
 {
-	return s5pc1xx_clk_gate(S5PC100_SCLKGATE0, clk, enable);
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
+
+	ratio = __raw_readl(S5PC100_CLKDIV0) & S5PC100_CLKDIV0_PCLKD0_MASK;
+	ratio >>= S5PC100_CLKDIV0_PCLKD0_SHIFT;
+
+	return rate / (ratio + 1);
 }
 
-int s5pc1xx_sclk1_ctrl(struct clk *clk, int enable)
+static struct clk clk_dout_pclkd0 = {
+	.name		= "dout_pclkd0",
+	.id		= -1,
+	.parent		= &clk_dout_d0_bus,
+	.get_rate	= s5pc100_clk_dout_pclkd0_get_rate,
+};
+
+static unsigned long s5pc100_clk_dout_apll2_get_rate(struct clk *clk)
 {
-	return s5pc1xx_clk_gate(S5PC100_SCLKGATE1, clk, enable);
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
+
+	ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_APLL2_MASK;
+	ratio >>= S5PC100_CLKDIV1_APLL2_SHIFT;
+
+	return rate / (ratio + 1);
 }
 
-static struct clk init_clocks_disable[] = {
-	{
-		.name		= "dsi",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_DSI,
-	}, {
-		.name		= "csi",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_CSI,
-	}, {
-		.name		= "ccan0",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_CCAN0,
-	}, {
-		.name		= "ccan1",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_CCAN1,
-	}, {
-		.name		= "keypad",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_KEYIF,
-	}, {
-		.name		= "hclkd2",
-		.id		= -1,
-		.parent		= NULL,
-		.enable		= s5pc1xx_clk_d20_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D20_HCLKD2,
-	}, {
-		.name		= "iis-d2",
-		.id		= -1,
-		.parent		= NULL,
-		.enable		= s5pc1xx_clk_d20_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D20_I2SD2,
-	}, {
-		.name		= "otg",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_USBOTG,
-	},
+static struct clk clk_dout_apll2 = {
+	.name		= "dout_apll2",
+	.id		= -1,
+	.parent		= &clk_mout_apll.clk,
+	.get_rate	= s5pc100_clk_dout_apll2_get_rate,
 };
 
-static struct clk init_clocks[] = {
-	/* System1 (D0_0) devices */
-	{
-		.name		= "intc",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_INTC,
-	}, {
-		.name		= "tzic",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_TZIC,
-	}, {
-		.name		= "cf-ata",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_CFCON,
-	}, {
-		.name		= "mdma",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_MDMA,
-	}, {
-		.name		= "g2d",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_G2D,
-	}, {
-		.name		= "secss",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_SECSS,
-	}, {
-		.name		= "cssys",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_CSSYS,
-	},
+/* MPLL */
+static struct clk *clk_src_mpll_list[] = {
+	[0] = &clk_fin_mpll,
+	[1] = &clk_fout_mpll,
+};
 
-	/* Memory (D0_1) devices */
-	{
-		.name		= "dmc",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d01_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D01_DMC,
-	}, {
-		.name		= "sromc",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d01_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D01_SROMC,
-	}, {
-		.name		= "onenand",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d01_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D01_ONENAND,
-	}, {
-		.name		= "nand",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d01_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D01_NFCON,
-	}, {
-		.name		= "intmem",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d01_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D01_INTMEM,
-	}, {
-		.name		= "ebi",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d01_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D01_EBI,
-	},
+static struct clk_sources clk_src_mpll = {
+	.sources	= clk_src_mpll_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_mpll_list),
+};
 
-	/* System2 (D0_2) devices */
-	{
-		.name		= "seckey",
-		.id		= -1,
-		.parent		= &clk_pd0,
-		.enable		= s5pc1xx_clk_d02_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D02_SECKEY,
-	}, {
-		.name		= "sdm",
+static struct clksrc_clk clk_mout_mpll = {
+	.clk = {
+		.name		= "mout_mpll",
 		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d02_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D02_SDM,
 	},
+	.shift		= S5PC100_CLKSRC0_MPLL_SHIFT,
+	.mask		= S5PC100_CLKSRC0_MPLL_MASK,
+	.sources	= &clk_src_mpll,
+	.reg_source	= S5PC100_CLKSRC0,
+};
 
-	/* File (D1_0) devices */
-	{
-		.name		= "pdma0",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_PDMA0,
-	}, {
-		.name		= "pdma1",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_PDMA1,
-	}, {
-		.name		= "usb-host",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_USBHOST,
-	}, {
-		.name		= "modem",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_MODEMIF,
-	}, {
-		.name		= "hsmmc",
-		.id		= 0,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC0,
-	}, {
-		.name		= "hsmmc",
-		.id		= 1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC1,
-	}, {
-		.name		= "hsmmc",
-		.id		= 2,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC2,
-	},
+static struct clk *clkset_am_list[] = {
+	[0] = &clk_mout_mpll.clk,
+	[1] = &clk_dout_apll2,
+};
 
-	/* Multimedia1 (D1_1) devices */
-	{
-		.name		= "lcd",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_LCD,
-	}, {
-		.name		= "rotator",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_ROTATOR,
-	}, {
-		.name		= "fimc",
-		.id		= 0,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC0,
-	}, {
-		.name		= "fimc",
-		.id		= 1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC1,
-	}, {
-		.name		= "fimc",
-		.id		= 2,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC2,
-	}, {
-		.name		= "jpeg",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_JPEG,
-	}, {
-		.name		= "g3d",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_G3D,
-	},
+static struct clk_sources clk_src_am = {
+	.sources	= clkset_am_list,
+	.nr_sources	= ARRAY_SIZE(clkset_am_list),
+};
 
-	/* Multimedia2 (D1_2) devices */
-	{
-		.name		= "tv",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d12_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D12_TV,
-	}, {
-		.name		= "vp",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d12_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D12_VP,
-	}, {
-		.name		= "mixer",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d12_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D12_MIXER,
-	}, {
-		.name		= "hdmi",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d12_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D12_HDMI,
-	}, {
-		.name		= "mfc",
+static struct clksrc_clk clk_mout_am = {
+	.clk = {
+		.name		= "mout_am",
 		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d12_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D12_MFC,
 	},
+	.shift		= S5PC100_CLKSRC0_AMMUX_SHIFT,
+	.mask		= S5PC100_CLKSRC0_AMMUX_MASK,
+	.sources	= &clk_src_am,
+	.reg_source	= S5PC100_CLKSRC0,
+};
 
-	/* System (D1_3) devices */
-	{
-		.name		= "chipid",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_CHIPID,
-	}, {
-		.name		= "gpio",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_GPIO,
-	}, {
-		.name		= "apc",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_APC,
-	}, {
-		.name		= "iec",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_IEC,
-	}, {
-		.name		= "timers",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_PWM,
-	}, {
-		.name		= "systimer",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_SYSTIMER,
-	}, {
-		.name		= "watchdog",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_WDT,
-	}, {
-		.name		= "rtc",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_RTC,
-	},
+static unsigned long s5pc100_clk_dout_d1_bus_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
 
-	/* Connectivity (D1_4) devices */
-	{
-		.name		= "uart",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_UART0,
-	}, {
-		.name		= "uart",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_UART1,
-	}, {
-		.name		= "uart",
-		.id		= 2,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_UART2,
-	}, {
-		.name		= "uart",
-		.id		= 3,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_UART3,
-	}, {
-		.name		= "i2c",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_IIC,
-	}, {
-		.name		= "hdmi-i2c",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_HDMI_IIC,
-	}, {
-		.name		= "spi",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_SPI0,
-	}, {
-		.name		= "spi",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_SPI1,
-	}, {
-		.name		= "spi",
-		.id		= 2,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_SPI2,
-	}, {
-		.name		= "irda",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_IRDA,
-	}, {
-		.name		= "hsitx",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_HSITX,
-	}, {
-		.name		= "hsirx",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_HSIRX,
-	},
+	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
 
-	/* Audio (D1_5) devices */
-	{
-		.name		= "iis",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_IIS0,
-	}, {
-		.name		= "iis",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_IIS1,
-	}, {
-		.name		= "iis",
-		.id		= 2,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_IIS2,
-	}, {
-		.name		= "ac97",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_AC97,
-	}, {
-		.name		= "pcm",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_PCM0,
-	}, {
-		.name		= "pcm",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_PCM1,
-	}, {
-		.name		= "spdif",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_SPDIF,
-	}, {
-		.name		= "adc",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_TSADC,
-	}, {
-		.name		= "keyif",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_KEYIF,
-	}, {
-		.name		= "cg",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_CG,
-	},
+	ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_D1_MASK;
+	ratio >>= S5PC100_CLKDIV1_D1_SHIFT;
 
-	/* Audio (D2_0) devices: all disabled */
+	return rate / (ratio + 1);
+}
 
-	/* Special Clocks 1 */
-	{
-		.name		= "sclk_hpm",
-		.id		= -1,
-		.parent		= NULL,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_HPM,
-	}, {
-		.name		= "sclk_onenand",
-		.id		= -1,
-		.parent		= NULL,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_ONENAND,
-	}, {
-		.name		= "sclk_spi_48",
-		.id		= 0,
-		.parent		= &clk_48m,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI0_48,
-	}, {
-		.name		= "sclk_spi_48",
-		.id		= 1,
-		.parent		= &clk_48m,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI1_48,
-	}, {
-		.name		= "sclk_spi_48",
-		.id		= 2,
-		.parent		= &clk_48m,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI2_48,
-	}, {
-		.name		= "sclk_mmc_48",
-		.id		= 0,
-		.parent		= &clk_48m,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC0_48,
-	}, {
-		.name		= "sclk_mmc_48",
-		.id		= 1,
-		.parent		= &clk_48m,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC1_48,
-	}, {
-		.name		= "sclk_mmc_48",
-		.id		= 2,
-		.parent		= &clk_48m,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC2_48,
-	},
+static struct clk clk_dout_d1_bus = {
+	.name		= "dout_d1_bus",
+	.id		= -1,
+	.parent		= &clk_mout_am.clk,
+	.get_rate	= s5pc100_clk_dout_d1_bus_get_rate,
+};
 
-	/* Special Clocks 2 */
-	{
-		.name		= "sclk_tv_54",
-		.id		= -1,
-		.parent		= &clk_54m,
-		.enable		= s5pc1xx_sclk1_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK1_TV54,
-	}, {
-		.name		= "sclk_vdac_54",
-		.id		= -1,
-		.parent		= &clk_54m,
-		.enable		= s5pc1xx_sclk1_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK1_VDAC54,
-	}, {
-		.name		= "sclk_spdif",
+static struct clk *clkset_onenand_list[] = {
+	[0] = &clk_dout_d0_bus,
+	[1] = &clk_dout_d1_bus,
+};
+
+static struct clk_sources clk_src_onenand = {
+	.sources	= clkset_onenand_list,
+	.nr_sources	= ARRAY_SIZE(clkset_onenand_list),
+};
+
+static struct clksrc_clk clk_mout_onenand = {
+	.clk = {
+		.name		= "mout_onenand",
 		.id		= -1,
-		.parent		= NULL,
-		.enable		= s5pc1xx_sclk1_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK1_SPDIF,
 	},
+	.shift		= S5PC100_CLKSRC0_ONENAND_SHIFT,
+	.mask		= S5PC100_CLKSRC0_ONENAND_MASK,
+	.sources	= &clk_src_onenand,
+	.reg_source	= S5PC100_CLKSRC0,
 };
 
-void __init s5pc1xx_register_clocks(void)
+static unsigned long s5pc100_clk_dout_pclkd1_get_rate(struct clk *clk)
 {
-	struct clk *clkp;
-	int ret;
-	int ptr;
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
 
-	clkp = init_clocks;
-	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
-	}
+	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
 
-	clkp = init_clocks_disable;
-	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+	ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_PCLKD1_MASK;
+	ratio >>= S5PC100_CLKDIV1_PCLKD1_SHIFT;
 
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
+	return rate / (ratio + 1);
+}
 
-		(clkp->enable)(clkp, 0);
-	}
+static struct clk clk_dout_pclkd1 = {
+	.name		= "dout_pclkd1",
+	.id		= -1,
+	.parent		= &clk_dout_d1_bus,
+	.get_rate	= s5pc100_clk_dout_pclkd1_get_rate,
+};
 
-	s3c_pwmclk_init();
+static unsigned long s5pc100_clk_dout_mpll2_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
+
+	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
+
+	ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_MPLL2_MASK;
+	ratio >>= S5PC100_CLKDIV1_MPLL2_SHIFT;
+
+	return rate / (ratio + 1);
 }
-static struct clk clk_fout_apll = {
-	.name		= "fout_apll",
+
+static struct clk clk_dout_mpll2 = {
+	.name		= "dout_mpll2",
 	.id		= -1,
+	.parent		= &clk_mout_am.clk,
+	.get_rate	= s5pc100_clk_dout_mpll2_get_rate,
 };
 
-static struct clk *clk_src_apll_list[] = {
-	[0] = &clk_fin_apll,
-	[1] = &clk_fout_apll,
-};
+static unsigned long s5pc100_clk_dout_cam_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
 
-static struct clk_sources clk_src_apll = {
-	.sources	= clk_src_apll_list,
-	.nr_sources	= ARRAY_SIZE(clk_src_apll_list),
+	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
+
+	ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_CAM_MASK;
+	ratio >>= S5PC100_CLKDIV1_CAM_SHIFT;
+
+	return rate / (ratio + 1);
+}
+
+static struct clk clk_dout_cam = {
+	.name		= "dout_cam",
+	.id		= -1,
+	.parent		= &clk_dout_mpll2,
+	.get_rate	= s5pc100_clk_dout_cam_get_rate,
 };
 
-static struct clksrc_clk clk_mout_apll = {
-	.clk	= {
-		.name		= "mout_apll",
-		.id		= -1,
-	},
-	.shift		= S5PC100_CLKSRC0_APLL_SHIFT,
-	.mask		= S5PC100_CLKSRC0_APLL_MASK,
-	.sources	= &clk_src_apll,
-	.reg_source	= S5PC100_CLKSRC0,
+static unsigned long s5pc100_clk_dout_mpll_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
+
+	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
+
+	ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_MPLL_MASK;
+	ratio >>= S5PC100_CLKDIV1_MPLL_SHIFT;
+
+	return rate / (ratio + 1);
+}
+
+static struct clk clk_dout_mpll = {
+	.name		= "dout_mpll",
+	.id		= -1,
+	.parent		= &clk_mout_am.clk,
+	.get_rate	= s5pc100_clk_dout_mpll_get_rate,
 };
 
+/* EPLL */
 static struct clk clk_fout_epll = {
 	.name		= "fout_epll",
 	.id		= -1,
@@ -833,85 +415,51 @@ static struct clksrc_clk clk_mout_epll = {
 	.reg_source	= S5PC100_CLKSRC0,
 };
 
-static struct clk *clk_src_mpll_list[] = {
-	[0] = &clk_fin_mpll,
-	[1] = &clk_fout_mpll,
+/* HPLL */
+static struct clk clk_fout_hpll = {
+	.name		= "fout_hpll",
+	.id		= -1,
 };
 
-static struct clk_sources clk_src_mpll = {
-	.sources	= clk_src_mpll_list,
-	.nr_sources	= ARRAY_SIZE(clk_src_mpll_list),
+static struct clk *clk_src_hpll_list[] = {
+	[0] = &clk_27m,
+	[1] = &clk_fout_hpll,
 };
 
-static struct clksrc_clk clk_mout_mpll = {
-	.clk = {
-		.name		= "mout_mpll",
+static struct clk_sources clk_src_hpll = {
+	.sources	= clk_src_hpll_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_hpll_list),
+};
+
+static struct clksrc_clk clk_mout_hpll = {
+	.clk	= {
+		.name		= "mout_hpll",
 		.id		= -1,
 	},
-	.shift		= S5PC100_CLKSRC0_MPLL_SHIFT,
-	.mask		= S5PC100_CLKSRC0_MPLL_MASK,
-	.sources	= &clk_src_mpll,
+	.shift		= S5PC100_CLKSRC0_HPLL_SHIFT,
+	.mask		= S5PC100_CLKSRC0_HPLL_MASK,
+	.sources	= &clk_src_hpll,
 	.reg_source	= S5PC100_CLKSRC0,
 };
 
-static unsigned long s5pc1xx_clk_doutmpll_get_rate(struct clk *clk)
-{
-	unsigned long rate = clk_get_rate(clk->parent);
-	unsigned long clkdiv;
-
-	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
-
-	clkdiv = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_MPLL_MASK;
-	rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL_SHIFT) + 1;
-
-	return rate;
-}
-
-static struct clk clk_dout_mpll = {
-	.name		= "dout_mpll",
-	.id		= -1,
-	.parent		= &clk_mout_mpll.clk,
-	.get_rate	= s5pc1xx_clk_doutmpll_get_rate,
-};
-
-static unsigned long s5pc1xx_clk_doutmpll2_get_rate(struct clk *clk)
-{
-	unsigned long rate = clk_get_rate(clk->parent);
-	unsigned long clkdiv;
-
-	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
-
-	clkdiv = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_MPLL2_MASK;
-	rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL2_SHIFT) + 1;
-
-	return rate;
-}
-
-struct clk clk_dout_mpll2 = {
-	.name		= "dout_mpll2",
-	.id		= -1,
-	.parent		= &clk_mout_mpll.clk,
-	.get_rate	= s5pc1xx_clk_doutmpll2_get_rate,
-};
-
-static struct clk *clkset_uart_list[] = {
-	&clk_mout_epll.clk,
-	&clk_dout_mpll,
-	NULL,
-	NULL
-};
-
-static struct clk_sources clkset_uart = {
-	.sources	= clkset_uart_list,
-	.nr_sources	= ARRAY_SIZE(clkset_uart_list),
-};
+/* Peripherals */
+/*
+ * The peripheral clocks are all controlled via clocksource followed
+ * by an optional divider and gate stage. We currently roll this into
+ * one clock which hides the intermediate clock from the mux.
+ *
+ * Note, the JPEG clock can only be an even divider...
+ *
+ * The scaler and LCD clocks depend on the S5PC100 version, and also
+ * have a common parent divisor so are not included here.
+ */
 
 static inline struct clksrc_clk *to_clksrc(struct clk *clk)
 {
 	return container_of(clk, struct clksrc_clk, clk);
 }
 
-static unsigned long s5pc1xx_getrate_clksrc(struct clk *clk)
+static unsigned long s5pc100_getrate_clksrc(struct clk *clk)
 {
 	struct clksrc_clk *sclk = to_clksrc(clk);
 	unsigned long rate = clk_get_rate(clk->parent);
@@ -925,7 +473,7 @@ static unsigned long s5pc1xx_getrate_clksrc(struct clk *clk)
 	return rate;
 }
 
-static int s5pc1xx_setrate_clksrc(struct clk *clk, unsigned long rate)
+static int s5pc100_setrate_clksrc(struct clk *clk, unsigned long rate)
 {
 	struct clksrc_clk *sclk = to_clksrc(clk);
 	void __iomem *reg = sclk->reg_divider;
@@ -938,14 +486,14 @@ static int s5pc1xx_setrate_clksrc(struct clk *clk, unsigned long rate)
 		return -EINVAL;
 
 	val = __raw_readl(reg);
-	val &= ~(0xf << sclk->shift);
-	val |= (div - 1) << sclk->shift;
+	val &= ~(0xf << sclk->divider_shift);
+	val |= (div - 1) << sclk->divider_shift;
 	__raw_writel(val, reg);
 
 	return 0;
 }
 
-static int s5pc1xx_setparent_clksrc(struct clk *clk, struct clk *parent)
+static int s5pc100_setparent_clksrc(struct clk *clk, struct clk *parent)
 {
 	struct clksrc_clk *sclk = to_clksrc(clk);
 	struct clk_sources *srcs = sclk->sources;
@@ -970,7 +518,7 @@ static int s5pc1xx_setparent_clksrc(struct clk *clk, struct clk *parent)
 	return -EINVAL;
 }
 
-static unsigned long s5pc1xx_roundrate_clksrc(struct clk *clk,
+static unsigned long s5pc100_roundrate_clksrc(struct clk *clk,
 					      unsigned long rate)
 {
 	unsigned long parent_rate = clk_get_rate(clk->parent);
@@ -992,16 +540,95 @@ static unsigned long s5pc1xx_roundrate_clksrc(struct clk *clk,
 	return rate;
 }
 
+static struct clk *clkset_spi_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll2,
+	&clk_fin_epll,
+	&clk_mout_hpll.clk,
+};
+
+static struct clk_sources clkset_spi = {
+	.sources	= clkset_spi_list,
+	.nr_sources	= ARRAY_SIZE(clkset_spi_list),
+};
+
+static struct clksrc_clk clk_spi0 = {
+	.clk	= {
+		.name		= "spi_bus",
+		.id		= 0,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI0,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC1_SPI0_SHIFT,
+	.mask		= S5PC100_CLKSRC1_SPI0_MASK,
+	.sources	= &clkset_spi,
+	.divider_shift	= S5PC100_CLKDIV2_SPI0_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV2,
+	.reg_source	= S5PC100_CLKSRC1,
+};
+
+static struct clksrc_clk clk_spi1 = {
+	.clk	= {
+		.name		= "spi_bus",
+		.id		= 1,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI1,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC1_SPI1_SHIFT,
+	.mask		= S5PC100_CLKSRC1_SPI1_MASK,
+	.sources	= &clkset_spi,
+	.divider_shift	= S5PC100_CLKDIV2_SPI1_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV2,
+	.reg_source	= S5PC100_CLKSRC1,
+};
+
+static struct clksrc_clk clk_spi2 = {
+	.clk	= {
+		.name		= "spi_bus",
+		.id		= 2,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI2,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC1_SPI2_SHIFT,
+	.mask		= S5PC100_CLKSRC1_SPI2_MASK,
+	.sources	= &clkset_spi,
+	.divider_shift	= S5PC100_CLKDIV2_SPI2_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV2,
+	.reg_source	= S5PC100_CLKSRC1,
+};
+
+static struct clk *clkset_uart_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+};
+
+static struct clk_sources clkset_uart = {
+	.sources	= clkset_uart_list,
+	.nr_sources	= ARRAY_SIZE(clkset_uart_list),
+};
+
 static struct clksrc_clk clk_uart_uclk1 = {
 	.clk	= {
 		.name		= "uclk1",
 		.id		= -1,
 		.ctrlbit        = S5PC100_CLKGATE_SCLK0_UART,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.set_parent	= s5pc1xx_setparent_clksrc,
-		.get_rate	= s5pc1xx_getrate_clksrc,
-		.set_rate	= s5pc1xx_setrate_clksrc,
-		.round_rate	= s5pc1xx_roundrate_clksrc,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
 	},
 	.shift		= S5PC100_CLKSRC1_UART_SHIFT,
 	.mask		= S5PC100_CLKSRC1_UART_MASK,
@@ -1011,16 +638,368 @@ static struct clksrc_clk clk_uart_uclk1 = {
 	.reg_source	= S5PC100_CLKSRC1,
 };
 
+static struct clk clk_iis_cd0 = {
+	.name		= "iis_cdclk0",
+	.id		= -1,
+};
+
+static struct clk clk_iis_cd1 = {
+	.name		= "iis_cdclk1",
+	.id		= -1,
+};
+
+static struct clk clk_iis_cd2 = {
+	.name		= "iis_cdclk2",
+	.id		= -1,
+};
+
+static struct clk clk_pcm_cd0 = {
+	.name		= "pcm_cdclk0",
+	.id		= -1,
+};
+
+static struct clk clk_pcm_cd1 = {
+	.name		= "pcm_cdclk1",
+	.id		= -1,
+};
+
+static struct clk *clkset_audio0_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_fin_epll,
+	&clk_iis_cd0,
+	&clk_pcm_cd0,
+	&clk_mout_hpll.clk,
+};
+
+static struct clk_sources clkset_audio0 = {
+	.sources	= clkset_audio0_list,
+	.nr_sources	= ARRAY_SIZE(clkset_audio0_list),
+};
+
+static struct clksrc_clk clk_audio0 = {
+	.clk	= {
+		.name		= "audio-bus",
+		.id		= 0,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_AUDIO0,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC3_AUDIO0_SHIFT,
+	.mask		= S5PC100_CLKSRC3_AUDIO0_MASK,
+	.sources	= &clkset_audio0,
+	.divider_shift	= S5PC100_CLKDIV4_AUDIO0_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV4,
+	.reg_source	= S5PC100_CLKSRC3,
+};
+
+static struct clk *clkset_audio1_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_fin_epll,
+	&clk_iis_cd1,
+	&clk_pcm_cd1,
+	&clk_mout_hpll.clk,
+};
+
+static struct clk_sources clkset_audio1 = {
+	.sources	= clkset_audio1_list,
+	.nr_sources	= ARRAY_SIZE(clkset_audio1_list),
+};
+
+static struct clksrc_clk clk_audio1 = {
+	.clk	= {
+		.name		= "audio-bus",
+		.id		= 1,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_AUDIO1,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC3_AUDIO1_SHIFT,
+	.mask		= S5PC100_CLKSRC3_AUDIO1_MASK,
+	.sources	= &clkset_audio1,
+	.divider_shift	= S5PC100_CLKDIV4_AUDIO1_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV4,
+	.reg_source	= S5PC100_CLKSRC3,
+};
+
+static struct clk *clkset_audio2_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_fin_epll,
+	&clk_iis_cd2,
+	&clk_mout_hpll.clk,
+};
+
+static struct clk_sources clkset_audio2 = {
+	.sources	= clkset_audio2_list,
+	.nr_sources	= ARRAY_SIZE(clkset_audio2_list),
+};
+
+static struct clksrc_clk clk_audio2 = {
+	.clk	= {
+		.name		= "audio-bus",
+		.id		= 2,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_AUDIO2,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC3_AUDIO2_SHIFT,
+	.mask		= S5PC100_CLKSRC3_AUDIO2_MASK,
+	.sources	= &clkset_audio2,
+	.divider_shift	= S5PC100_CLKDIV4_AUDIO2_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV4,
+	.reg_source	= S5PC100_CLKSRC3,
+};
+
+static struct clk *clkset_spdif_list[] = {
+	&clk_audio0.clk,
+	&clk_audio1.clk,
+	&clk_audio2.clk,
+};
+
+static struct clk_sources clkset_spdif = {
+	.sources	= clkset_spdif_list,
+	.nr_sources	= ARRAY_SIZE(clkset_spdif_list),
+};
+
+static struct clksrc_clk clk_spdif = {
+	.clk	= {
+		.name		= "spdif",
+		.id		= -1,
+	},
+	.shift		= S5PC100_CLKSRC3_SPDIF_SHIFT,
+	.mask		= S5PC100_CLKSRC3_SPDIF_MASK,
+	.sources	= &clkset_spdif,
+	.reg_source	= S5PC100_CLKSRC3,
+};
+
+static struct clk *clkset_lcd_fimc_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_mout_hpll.clk,
+	&clk_vclk_54m,
+};
+
+static struct clk_sources clkset_lcd_fimc = {
+	.sources	= clkset_lcd_fimc_list,
+	.nr_sources	= ARRAY_SIZE(clkset_lcd_fimc_list),
+};
+
+static struct clksrc_clk clk_lcd = {
+	.clk	= {
+		.name		= "lcd",
+		.id		= -1,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_LCD,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_LCD_SHIFT,
+	.mask		= S5PC100_CLKSRC2_LCD_MASK,
+	.sources	= &clkset_lcd_fimc,
+	.divider_shift	= S5PC100_CLKDIV3_LCD_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+static struct clksrc_clk clk_fimc0 = {
+	.clk	= {
+		.name		= "fimc",
+		.id		= 0,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_FIMC0,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_FIMC0_SHIFT,
+	.mask		= S5PC100_CLKSRC2_FIMC0_MASK,
+	.sources	= &clkset_lcd_fimc,
+	.divider_shift	= S5PC100_CLKDIV3_FIMC0_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+static struct clksrc_clk clk_fimc1 = {
+	.clk	= {
+		.name		= "fimc",
+		.id		= 1,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_FIMC1,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_FIMC1_SHIFT,
+	.mask		= S5PC100_CLKSRC2_FIMC1_MASK,
+	.sources	= &clkset_lcd_fimc,
+	.divider_shift	= S5PC100_CLKDIV3_FIMC1_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+static struct clksrc_clk clk_fimc2 = {
+	.clk	= {
+		.name		= "fimc",
+		.id		= 2,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_FIMC2,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_FIMC2_SHIFT,
+	.mask		= S5PC100_CLKSRC2_FIMC2_MASK,
+	.sources	= &clkset_lcd_fimc,
+	.divider_shift	= S5PC100_CLKDIV3_FIMC2_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+static struct clk *clkset_mmc_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_fin_epll,
+	&clk_mout_hpll.clk ,
+};
+
+static struct clk_sources clkset_mmc = {
+	.sources	= clkset_mmc_list,
+	.nr_sources	= ARRAY_SIZE(clkset_mmc_list),
+};
+
+static struct clksrc_clk clk_mmc0 = {
+	.clk	= {
+		.name		= "mmc_bus",
+		.id		= 0,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC0,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_MMC0_SHIFT,
+	.mask		= S5PC100_CLKSRC2_MMC0_MASK,
+	.sources	= &clkset_mmc,
+	.divider_shift	= S5PC100_CLKDIV3_MMC0_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+static struct clksrc_clk clk_mmc1 = {
+	.clk	= {
+		.name		= "mmc_bus",
+		.id		= 1,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC1,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_MMC1_SHIFT,
+	.mask		= S5PC100_CLKSRC2_MMC1_MASK,
+	.sources	= &clkset_mmc,
+	.divider_shift	= S5PC100_CLKDIV3_MMC1_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+static struct clksrc_clk clk_mmc2 = {
+	.clk	= {
+		.name		= "mmc_bus",
+		.id		= 2,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC2,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_MMC2_SHIFT,
+	.mask		= S5PC100_CLKSRC2_MMC2_MASK,
+	.sources	= &clkset_mmc,
+	.divider_shift	= S5PC100_CLKDIV3_MMC2_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+
+static struct clk *clkset_usbhost_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_mout_hpll.clk,
+	&clk_48m,
+};
+
+static struct clk_sources clkset_usbhost = {
+	.sources	= clkset_usbhost_list,
+	.nr_sources	= ARRAY_SIZE(clkset_usbhost_list),
+};
+
+static struct clksrc_clk clk_usbhost = {
+	.clk	= {
+		.name		= "usbhost",
+		.id		= -1,
+		.ctrlbit        = S5PC100_CLKGATE_SCLK0_USBHOST,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC1_UHOST_SHIFT,
+	.mask		= S5PC100_CLKSRC1_UHOST_MASK,
+	.sources	= &clkset_usbhost,
+	.divider_shift	= S5PC100_CLKDIV2_UHOST_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV2,
+	.reg_source	= S5PC100_CLKSRC1,
+};
+
 /* Clock initialisation code */
 
 static struct clksrc_clk *init_parents[] = {
 	&clk_mout_apll,
-	&clk_mout_epll,
 	&clk_mout_mpll,
+	&clk_mout_am,
+	&clk_mout_onenand,
+	&clk_mout_epll,
+	&clk_mout_hpll,
+	&clk_spi0,
+	&clk_spi1,
+	&clk_spi2,
 	&clk_uart_uclk1,
+	&clk_audio0,
+	&clk_audio1,
+	&clk_audio2,
+	&clk_spdif,
+	&clk_lcd,
+	&clk_fimc0,
+	&clk_fimc1,
+	&clk_fimc2,
+	&clk_mmc0,
+	&clk_mmc1,
+	&clk_mmc2,
+	&clk_usbhost,
 };
 
-static void __init_or_cpufreq s5pc1xx_set_clksrc(struct clksrc_clk *clk)
+static void __init_or_cpufreq s5pc100_set_clksrc(struct clksrc_clk *clk)
 {
 	struct clk_sources *srcs = clk->sources;
 	u32 clksrc = __raw_readl(clk->reg_source);
@@ -1036,9 +1015,9 @@ static void __init_or_cpufreq s5pc1xx_set_clksrc(struct clksrc_clk *clk)
 
 	clk->clk.parent = srcs->sources[clksrc];
 
-	printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n",
-	       clk->clk.name, clk->clk.parent->name, clksrc,
-	       clk_get_rate(&clk->clk));
+	printk(KERN_INFO "%s: source is %s (%d), rate is %ld.%03ld MHz\n",
+		clk->clk.name, clk->clk.parent->name, clksrc,
+		print_mhz(clk_get_rate(&clk->clk)));
 }
 
 #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
@@ -1052,10 +1031,7 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
 	unsigned long hclk;
 	unsigned long pclkd0;
 	unsigned long pclk;
-	unsigned long apll;
-	unsigned long mpll;
-	unsigned long hpll;
-	unsigned long epll;
+	unsigned long apll, mpll, epll, hpll;
 	unsigned int ptr;
 	u32 clkdiv0, clkdiv1;
 
@@ -1064,8 +1040,7 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
 	clkdiv0 = __raw_readl(S5PC100_CLKDIV0);
 	clkdiv1 = __raw_readl(S5PC100_CLKDIV1);
 
-	printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
-			__func__, clkdiv0, clkdiv1);
+	printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n", __func__, clkdiv0, clkdiv1);
 
 	xtal_clk = clk_get(NULL, "xtal");
 	BUG_ON(IS_ERR(xtal_clk));
@@ -1080,8 +1055,10 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
 	epll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_EPLL_CON));
 	hpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_HPLL_CON));
 
-	printk(KERN_INFO "S5PC100: PLL settings, A=%ld, M=%ld, E=%ld, H=%ld\n",
-	       apll, mpll, epll, hpll);
+	printk(KERN_INFO "S5PC100: Apll=%ld.%03ld Mhz, Mpll=%ld.%03ld Mhz"
+		", Epll=%ld.%03ld Mhz, Hpll=%ld.%03ld Mhz\n",
+		print_mhz(apll), print_mhz(mpll),
+		print_mhz(epll), print_mhz(hpll));
 
 	armclk = apll / GET_DIV(clkdiv0, S5PC100_CLKDIV0_APLL);
 	armclk = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_ARM);
@@ -1090,33 +1067,64 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
 	hclk = mpll / GET_DIV(clkdiv1, S5PC100_CLKDIV1_D1);
 	pclk = hclk / GET_DIV(clkdiv1, S5PC100_CLKDIV1_PCLKD1);
 
-	printk(KERN_INFO "S5PC100: ARMCLK=%ld, HCLKD0=%ld, PCLKD0=%ld, HCLK=%ld, PCLK=%ld\n",
-	       armclk, hclkd0, pclkd0, hclk, pclk);
+	printk(KERN_INFO "S5PC100: ARMCLK=%ld.%03ld MHz, HCLKD0=%ld.%03ld MHz,"
+		" PCLKD0=%ld.%03ld MHz\n, HCLK=%ld.%03ld MHz,"
+		" PCLK=%ld.%03ld MHz\n",
+		print_mhz(armclk), print_mhz(hclkd0),
+		print_mhz(pclkd0), print_mhz(hclk), print_mhz(pclk));
 
 	clk_fout_apll.rate = apll;
 	clk_fout_mpll.rate = mpll;
 	clk_fout_epll.rate = epll;
-	clk_fout_apll.rate = apll;
+	clk_fout_hpll.rate = hpll;
 
 	clk_h.rate = hclk;
 	clk_p.rate = pclk;
+	clk_f.rate = armclk;
 
 	for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
-		s5pc1xx_set_clksrc(init_parents[ptr]);
+		s5pc100_set_clksrc(init_parents[ptr]);
 }
 
 static struct clk *clks[] __initdata = {
 	&clk_ext_xtal_mux,
-	&clk_mout_epll.clk,
-	&clk_fout_epll,
+	&clk_mout_apll.clk,
+	&clk_dout_apll,
+	&clk_dout_d0_bus,
+	&clk_dout_pclkd0,
+	&clk_dout_apll2,
 	&clk_mout_mpll.clk,
+	&clk_mout_am.clk,
+	&clk_dout_d1_bus,
+	&clk_mout_onenand.clk,
+	&clk_dout_pclkd1,
+	&clk_dout_mpll2,
+	&clk_dout_cam,
 	&clk_dout_mpll,
+	&clk_mout_epll.clk,
+	&clk_fout_epll,
+	&clk_iis_cd0,
+	&clk_iis_cd1,
+	&clk_iis_cd2,
+	&clk_pcm_cd0,
+	&clk_pcm_cd1,
+	&clk_spi0.clk,
+	&clk_spi1.clk,
+	&clk_spi2.clk,
 	&clk_uart_uclk1.clk,
-	&clk_ext,
-	&clk_epll,
-	&clk_27m,
-	&clk_48m,
-	&clk_54m,
+	&clk_audio0.clk,
+	&clk_audio1.clk,
+	&clk_audio2.clk,
+	&clk_spdif.clk,
+	&clk_lcd.clk,
+	&clk_fimc0.clk,
+	&clk_fimc1.clk,
+	&clk_fimc2.clk,
+	&clk_mmc0.clk,
+	&clk_mmc1.clk,
+	&clk_mmc2.clk,
+	&clk_usbhost.clk,
+	&clk_arm,
 };
 
 void __init s5pc100_register_clocks(void)
@@ -1133,7 +1141,4 @@ void __init s5pc100_register_clocks(void)
 			       clkp->name, ret);
 		}
 	}
-
-	clk_mpll.parent = &clk_mout_mpll.clk;
-	clk_epll.parent = &clk_mout_epll.clk;
 }
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 04/17] ARM: S5PC1XX: clocks reimplementation
@ 2009-10-13  8:11         ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

Clocks hierarchy has been completely reimplemented to match the S5PC100
specification.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/plat-s5pc1xx/Makefile               |    1 +
 arch/arm/plat-s5pc1xx/clock.c                |  728 ++++++++++++
 arch/arm/plat-s5pc1xx/cpu.c                  |    5 +
 arch/arm/plat-s5pc1xx/include/plat/s5pc100.h |    5 +-
 arch/arm/plat-s5pc1xx/s5pc100-clock.c        | 1531 +++++++++++++-------------
 5 files changed, 1504 insertions(+), 766 deletions(-)
 create mode 100644 arch/arm/plat-s5pc1xx/clock.c

diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile
index f1ecb2c..ebbf364 100644
--- a/arch/arm/plat-s5pc1xx/Makefile
+++ b/arch/arm/plat-s5pc1xx/Makefile
@@ -14,6 +14,7 @@ obj-				:=
 obj-y				+= dev-uart.o
 obj-y				+= cpu.o
 obj-y				+= irq.o
+obj-y				+= clock.o
 
 # CPU support
 
diff --git a/arch/arm/plat-s5pc1xx/clock.c b/arch/arm/plat-s5pc1xx/clock.c
new file mode 100644
index 0000000..26c21d8
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/clock.c
@@ -0,0 +1,728 @@
+/* linux/arch/arm/plat-s5pc1xx/clock.c
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *
+ * S5PC1XX Base clock support
+ *
+ * Based on plat-s3c64xx/clock.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/regs-clock.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+
+struct clk clk_27m = {
+	.name		= "clk_27m",
+	.id		= -1,
+	.rate		= 27000000,
+};
+
+static int clk_48m_ctrl(struct clk *clk, int enable)
+{
+	unsigned long flags;
+	u32 val;
+
+	/* can't rely on clock lock, this register has other usages */
+	local_irq_save(flags);
+
+	val = __raw_readl(S5PC100_CLKSRC1);
+	if (enable)
+		val |= S5PC100_CLKSRC1_CLK48M_MASK;
+	else
+		val &= ~S5PC100_CLKSRC1_CLK48M_MASK;
+
+	__raw_writel(val, S5PC100_CLKSRC1);
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+struct clk clk_48m = {
+	.name		= "clk_48m",
+	.id		= -1,
+	.rate		= 48000000,
+	.enable		= clk_48m_ctrl,
+};
+
+struct clk clk_54m = {
+	.name		= "clk_54m",
+	.id		= -1,
+	.rate		= 54000000,
+};
+
+static int clk_default_setrate(struct clk *clk, unsigned long rate)
+{
+	clk->rate = rate;
+	return 0;
+}
+
+static int clk_dummy_enable(struct clk *clk, int enable)
+{
+	return 0;
+}
+
+struct clk clk_hd0 = {
+	.name		= "hclkd0",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+	.set_rate	= clk_default_setrate,
+	.enable		= clk_dummy_enable,
+};
+
+struct clk clk_pd0 = {
+	.name		= "pclkd0",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+	.set_rate	= clk_default_setrate,
+	.enable		= clk_dummy_enable,
+};
+
+static int s5pc1xx_clk_gate(void __iomem *reg, struct clk *clk, int enable)
+{
+	unsigned int ctrlbit = clk->ctrlbit;
+	u32 con;
+
+	con = __raw_readl(reg);
+	if (enable)
+		con |= ctrlbit;
+	else
+		con &= ~ctrlbit;
+	__raw_writel(con, reg);
+
+	return 0;
+}
+
+static int s5pc100_clk_d00_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D00, clk, enable);
+}
+
+static int s5pc100_clk_d01_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D01, clk, enable);
+}
+
+static int s5pc100_clk_d02_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D02, clk, enable);
+}
+
+static int s5pc100_clk_d10_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D10, clk, enable);
+}
+
+static int s5pc100_clk_d11_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D11, clk, enable);
+}
+
+static int s5pc100_clk_d12_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D12, clk, enable);
+}
+
+static int s5pc100_clk_d13_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D13, clk, enable);
+}
+
+static int s5pc100_clk_d14_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D14, clk, enable);
+}
+
+static int s5pc100_clk_d15_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D15, clk, enable);
+}
+
+static int s5pc100_clk_d20_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D20, clk, enable);
+}
+
+int s5pc100_sclk0_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_SCLKGATE0, clk, enable);
+}
+
+int s5pc100_sclk1_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_SCLKGATE1, clk, enable);
+}
+
+static struct clk s5pc100_init_clocks_disable[] = {
+	{
+		.name		= "dsi",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_DSI,
+	}, {
+		.name		= "csi",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_CSI,
+	}, {
+		.name		= "ccan",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_CCAN0,
+	}, {
+		.name		= "ccan",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_CCAN1,
+	}, {
+		.name		= "keypad",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_KEYIF,
+	}, {
+		.name		= "hclkd2",
+		.id		= -1,
+		.parent		= NULL,
+		.enable		= s5pc100_clk_d20_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D20_HCLKD2,
+	}, {
+		.name		= "iis-d2",
+		.id		= -1,
+		.parent		= NULL,
+		.enable		= s5pc100_clk_d20_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D20_I2SD2,
+	},
+};
+
+static struct clk s5pc100_init_clocks[] = {
+	/* System1 (D0_0) devices */
+	{
+		.name		= "intc",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_INTC,
+	}, {
+		.name		= "tzic",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_TZIC,
+	}, {
+		.name		= "cf-ata",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_CFCON,
+	}, {
+		.name		= "mdma",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_MDMA,
+	}, {
+		.name		= "g2d",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_G2D,
+	}, {
+		.name		= "secss",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_SECSS,
+	}, {
+		.name		= "cssys",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_CSSYS,
+	},
+
+	/* Memory (D0_1) devices */
+	{
+		.name		= "dmc",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_DMC,
+	}, {
+		.name		= "sromc",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_SROMC,
+	}, {
+		.name		= "onenand",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_ONENAND,
+	}, {
+		.name		= "nand",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_NFCON,
+	}, {
+		.name		= "intmem",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_INTMEM,
+	}, {
+		.name		= "ebi",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_EBI,
+	},
+
+	/* System2 (D0_2) devices */
+	{
+		.name		= "seckey",
+		.id		= -1,
+		.parent		= &clk_pd0,
+		.enable		= s5pc100_clk_d02_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D02_SECKEY,
+	}, {
+		.name		= "sdm",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc100_clk_d02_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D02_SDM,
+	},
+
+	/* File (D1_0) devices */
+	{
+		.name		= "pdma",
+		.id		= 0,
+		.parent		= &clk_h,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_PDMA0,
+	}, {
+		.name		= "pdma",
+		.id		= 1,
+		.parent		= &clk_h,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_PDMA1,
+	}, {
+		.name		= "usb-host",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_USBHOST,
+	}, {
+		.name		= "otg",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_USBOTG,
+	}, {
+		.name		= "modem",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_MODEMIF,
+	}, {
+		.name		= "hsmmc",
+		.id		= 0,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC0,
+	}, {
+		.name		= "hsmmc",
+		.id		= 1,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC1,
+	}, {
+		.name		= "hsmmc",
+		.id		= 2,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC2,
+	},
+
+	/* Multimedia1 (D1_1) devices */
+	{
+		.name		= "lcd",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_LCD,
+	}, {
+		.name		= "rotator",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_ROTATOR,
+	}, {
+		.name		= "fimc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC0,
+	}, {
+		.name		= "fimc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC1,
+	}, {
+		.name		= "fimc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC2,
+	}, {
+		.name		= "jpeg",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_JPEG,
+	}, {
+		.name		= "g3d",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_G3D,
+	},
+
+	/* Multimedia2 (D1_2) devices */
+	{
+		.name		= "tv",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_TV,
+	}, {
+		.name		= "vp",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_VP,
+	}, {
+		.name		= "mixer",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_MIXER,
+	}, {
+		.name		= "hdmi",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_HDMI,
+	}, {
+		.name		= "mfc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_MFC,
+	},
+
+	/* System (D1_3) devices */
+	{
+		.name		= "chipid",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_CHIPID,
+	}, {
+		.name		= "gpio",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_GPIO,
+	}, {
+		.name		= "apc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_APC,
+	}, {
+		.name		= "iec",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_IEC,
+	}, {
+		.name		= "timers",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_PWM,
+	}, {
+		.name		= "systimer",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_SYSTIMER,
+	}, {
+		.name		= "watchdog",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_WDT,
+	}, {
+		.name		= "rtc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_RTC,
+	},
+
+	/* Connectivity (D1_4) devices */
+	{
+		.name		= "uart",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_UART0,
+	}, {
+		.name		= "uart",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_UART1,
+	}, {
+		.name		= "uart",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_UART2,
+	}, {
+		.name		= "uart",
+		.id		= 3,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_UART3,
+	}, {
+		.name		= "i2c",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_IIC,
+	}, {
+		.name		= "hdmi-i2c",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_HDMI_IIC,
+	}, {
+		.name		= "spi",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_SPI0,
+	}, {
+		.name		= "spi",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_SPI1,
+	}, {
+		.name		= "spi",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_SPI2,
+	}, {
+		.name		= "irda",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_IRDA,
+	}, {
+		.name		= "hsitx",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_HSITX,
+	}, {
+		.name		= "hsirx",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_HSIRX,
+	},
+
+	/* Audio (D1_5) devices */
+	{
+		.name		= "iis",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_IIS0,
+	}, {
+		.name		= "iis",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_IIS1,
+	}, {
+		.name		= "iis",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_IIS2,
+	}, {
+		.name		= "ac97",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_AC97,
+	}, {
+		.name		= "pcm",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_PCM0,
+	}, {
+		.name		= "pcm",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_PCM1,
+	}, {
+		.name		= "spdif",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_SPDIF,
+	}, {
+		.name		= "adc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_TSADC,
+	}, {
+		.name		= "cg",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc100_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_CG,
+	},
+
+	/* Audio (D2_0) devices: all disabled */
+
+	/* Special Clocks 0 */
+	{
+		.name		= "sclk_hpm",
+		.id		= -1,
+		.parent		= NULL,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_HPM,
+	}, {
+		.name		= "sclk_onenand",
+		.id		= -1,
+		.parent		= NULL,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_ONENAND,
+	}, {
+		.name		= "spi_48",
+		.id		= 0,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI0_48,
+	}, {
+		.name		= "spi_48",
+		.id		= 1,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI1_48,
+	}, {
+		.name		= "spi_48",
+		.id		= 2,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI2_48,
+	}, {
+		.name		= "mmc_48",
+		.id		= 0,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC0_48,
+	}, {
+		.name		= "mmc_48",
+		.id		= 1,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC1_48,
+	}, {
+		.name		= "mmc_48",
+		.id		= 2,
+		.parent		= &clk_48m,
+		.enable		= s5pc100_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC2_48,
+	},
+	/* Special Clocks 1 */
+};
+
+static struct clk *clks[] __initdata = {
+	&clk_ext,
+	&clk_epll,
+	&clk_27m,
+	&clk_48m,
+	&clk_54m,
+};
+
+void __init s5pc1xx_register_clocks(void)
+{
+	struct clk *clkp;
+	int ret;
+	int ptr;
+	int size;
+
+	s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+	clkp = s5pc100_init_clocks;
+	size = ARRAY_SIZE(s5pc100_init_clocks);
+
+	for (ptr = 0; ptr < size; ptr++, clkp++) {
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
+	}
+
+	clkp = s5pc100_init_clocks_disable;
+	size = ARRAY_SIZE(s5pc100_init_clocks_disable);
+
+	for (ptr = 0; ptr < size; 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_pwmclk_init();
+}
diff --git a/arch/arm/plat-s5pc1xx/cpu.c b/arch/arm/plat-s5pc1xx/cpu.c
index 715a733..e8f3472 100644
--- a/arch/arm/plat-s5pc1xx/cpu.c
+++ b/arch/arm/plat-s5pc1xx/cpu.c
@@ -55,6 +55,11 @@ static struct cpu_table cpu_ids[] __initdata = {
 
 static struct map_desc s5pc1xx_iodesc[] __initdata = {
 	{
+		.virtual	= (unsigned long)S5PC1XX_VA_CLK_OTHER,
+		.pfn		= __phys_to_pfn(S5PC1XX_PA_CLK_OTHER),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
 		.virtual	= (unsigned long)S5PC1XX_VA_CHIPID,
 		.pfn		= __phys_to_pfn(S5PC1XX_PA_CHIPID),
 		.length		= SZ_16,
diff --git a/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h b/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h
index 45e2751..2531f34 100644
--- a/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h
+++ b/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h
@@ -35,10 +35,9 @@ extern struct clk clk_hpll;
 extern struct clk clk_hd0;
 extern struct clk clk_pd0;
 extern struct clk clk_54m;
-extern struct clk clk_dout_mpll2;
 extern void s5pc1xx_register_clocks(void);
-extern int s5pc1xx_sclk0_ctrl(struct clk *clk, int enable);
-extern int s5pc1xx_sclk1_ctrl(struct clk *clk, int enable);
+extern int s5pc100_sclk0_ctrl(struct clk *clk, int enable);
+extern int s5pc100_sclk1_ctrl(struct clk *clk, int enable);
 
 /* Some day, belows will be moved to plat-s5pc/include/plat/devs.h */
 extern struct s3c24xx_uart_resources s5pc1xx_uart_resources[];
diff --git a/arch/arm/plat-s5pc1xx/s5pc100-clock.c b/arch/arm/plat-s5pc1xx/s5pc100-clock.c
index efc868b..b436d44 100644
--- a/arch/arm/plat-s5pc1xx/s5pc100-clock.c
+++ b/arch/arm/plat-s5pc1xx/s5pc100-clock.c
@@ -49,6 +49,7 @@ static struct clk clk_ext_xtal_mux = {
 #define clk_fin_hpll clk_ext_xtal_mux
 
 #define clk_fout_mpll	clk_mpll
+#define clk_vclk_54m	clk_54m
 
 struct clk_sources {
 	unsigned int	nr_sources;
@@ -67,746 +68,327 @@ struct clksrc_clk {
 	void __iomem		*reg_source;
 };
 
-static int clk_default_setrate(struct clk *clk, unsigned long rate)
-{
-	clk->rate = rate;
-	return 1;
-}
-
-struct clk clk_27m = {
-	.name		= "clk_27m",
+/* APLL */
+static struct clk clk_fout_apll = {
+	.name		= "fout_apll",
 	.id		= -1,
 	.rate		= 27000000,
 };
 
-static int clk_48m_ctrl(struct clk *clk, int enable)
-{
-	unsigned long flags;
-	u32 val;
+static struct clk *clk_src_apll_list[] = {
+	[0] = &clk_fin_apll,
+	[1] = &clk_fout_apll,
+};
 
-	/* can't rely on clock lock, this register has other usages */
-	local_irq_save(flags);
+static struct clk_sources clk_src_apll = {
+	.sources	= clk_src_apll_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_apll_list),
+};
 
-	val = __raw_readl(S5PC100_CLKSRC1);
-	if (enable)
-		val |= S5PC100_CLKSRC1_CLK48M_MASK;
-	else
-		val &= ~S5PC100_CLKSRC1_CLK48M_MASK;
+static struct clksrc_clk clk_mout_apll = {
+	.clk	= {
+		.name		= "mout_apll",
+		.id		= -1,
+	},
+	.shift		= S5PC100_CLKSRC0_APLL_SHIFT,
+	.mask		= S5PC100_CLKSRC0_APLL_MASK,
+	.sources	= &clk_src_apll,
+	.reg_source	= S5PC100_CLKSRC0,
+};
 
-	__raw_writel(val, S5PC100_CLKSRC1);
-	local_irq_restore(flags);
+static unsigned long s5pc100_clk_dout_apll_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
 
-	return 0;
-}
+	ratio = __raw_readl(S5PC100_CLKDIV0) & S5PC100_CLKDIV0_APLL_MASK;
+	ratio >>= S5PC100_CLKDIV0_APLL_SHIFT;
 
-struct clk clk_48m = {
-	.name		= "clk_48m",
-	.id		= -1,
-	.rate		= 48000000,
-	.enable		= clk_48m_ctrl,
-};
+	return rate / (ratio + 1);
+}
 
-struct clk clk_54m = {
-	.name		= "clk_54m",
+static struct clk clk_dout_apll = {
+	.name		= "dout_apll",
 	.id		= -1,
-	.rate		= 54000000,
+	.parent		= &clk_mout_apll.clk,
+	.get_rate	= s5pc100_clk_dout_apll_get_rate,
 };
 
-struct clk clk_hpll = {
-	.name		= "hpll",
-	.id		= -1,
-};
+static unsigned long s5pc100_clk_arm_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
 
-struct clk clk_hd0 = {
-	.name		= "hclkd0",
-	.id		= -1,
-	.rate		= 0,
-	.parent		= NULL,
-	.ctrlbit	= 0,
-	.set_rate	= clk_default_setrate,
-};
+	ratio = __raw_readl(S5PC100_CLKDIV0) & S5PC100_CLKDIV0_ARM_MASK;
+	ratio >>= S5PC100_CLKDIV0_ARM_SHIFT;
 
-struct clk clk_pd0 = {
-	.name		= "pclkd0",
-	.id		= -1,
-	.rate		= 0,
-	.parent		= NULL,
-	.ctrlbit	= 0,
-	.set_rate	= clk_default_setrate,
-};
+	return rate / (ratio + 1);
+}
 
-static int s5pc1xx_clk_gate(void __iomem *reg,
-				struct clk *clk,
-				int enable)
+static unsigned long s5pc100_clk_arm_round_rate(struct clk *clk,
+						unsigned long rate)
 {
-	unsigned int ctrlbit = clk->ctrlbit;
-	u32 con;
+	unsigned long parent = clk_get_rate(clk->parent);
+	u32 div;
 
-	con = __raw_readl(reg);
+	if (parent < rate)
+		return rate;
 
-	if (enable)
-		con |= ctrlbit;
-	else
-		con &= ~ctrlbit;
+	div = (parent / rate) - 1;
+	if (div > S5PC100_CLKDIV0_ARM_MASK)
+		div = S5PC100_CLKDIV0_ARM_MASK;
 
-	__raw_writel(con, reg);
-	return 0;
+	return parent / (div + 1);
 }
 
-static int s5pc1xx_clk_d00_ctrl(struct clk *clk, int enable)
+static int s5pc100_clk_arm_set_rate(struct clk *clk, unsigned long rate)
 {
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D00, clk, enable);
-}
+	unsigned long parent = clk_get_rate(clk->parent);
+	u32 div;
+	u32 val;
 
-static int s5pc1xx_clk_d01_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D01, clk, enable);
-}
+	if (rate < parent / (S5PC100_CLKDIV0_ARM_MASK + 1))
+		return -EINVAL;
 
-static int s5pc1xx_clk_d02_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D02, clk, enable);
-}
+	rate = clk_round_rate(clk, rate);
+	div = clk_get_rate(clk->parent) / rate;
 
-static int s5pc1xx_clk_d10_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D10, clk, enable);
-}
+	val = __raw_readl(S5PC100_CLKDIV0);
+	val &= S5PC100_CLKDIV0_ARM_MASK;
+	val |= (div - 1);
+	__raw_writel(val, S5PC100_CLKDIV0);
 
-static int s5pc1xx_clk_d11_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D11, clk, enable);
+	return 0;
 }
 
-static int s5pc1xx_clk_d12_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D12, clk, enable);
-}
+static struct clk clk_arm = {
+	.name		= "armclk",
+	.id		= -1,
+	.parent		= &clk_dout_apll,
+	.get_rate	= s5pc100_clk_arm_get_rate,
+	.set_rate	= s5pc100_clk_arm_set_rate,
+	.round_rate	= s5pc100_clk_arm_round_rate,
+};
 
-static int s5pc1xx_clk_d13_ctrl(struct clk *clk, int enable)
+static unsigned long s5pc100_clk_dout_d0_bus_get_rate(struct clk *clk)
 {
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D13, clk, enable);
-}
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
 
-static int s5pc1xx_clk_d14_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D14, clk, enable);
-}
+	ratio = __raw_readl(S5PC100_CLKDIV0) & S5PC100_CLKDIV0_D0_MASK;
+	ratio >>= S5PC100_CLKDIV0_D0_SHIFT;
 
-static int s5pc1xx_clk_d15_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D15, clk, enable);
+	return rate / (ratio + 1);
 }
 
-static int s5pc1xx_clk_d20_ctrl(struct clk *clk, int enable)
-{
-	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D20, clk, enable);
-}
+static struct clk clk_dout_d0_bus = {
+	.name		= "dout_d0_bus",
+	.id		= -1,
+	.parent		= &clk_arm,
+	.get_rate	= s5pc100_clk_dout_d0_bus_get_rate,
+};
 
-int s5pc1xx_sclk0_ctrl(struct clk *clk, int enable)
+static unsigned long s5pc100_clk_dout_pclkd0_get_rate(struct clk *clk)
 {
-	return s5pc1xx_clk_gate(S5PC100_SCLKGATE0, clk, enable);
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
+
+	ratio = __raw_readl(S5PC100_CLKDIV0) & S5PC100_CLKDIV0_PCLKD0_MASK;
+	ratio >>= S5PC100_CLKDIV0_PCLKD0_SHIFT;
+
+	return rate / (ratio + 1);
 }
 
-int s5pc1xx_sclk1_ctrl(struct clk *clk, int enable)
+static struct clk clk_dout_pclkd0 = {
+	.name		= "dout_pclkd0",
+	.id		= -1,
+	.parent		= &clk_dout_d0_bus,
+	.get_rate	= s5pc100_clk_dout_pclkd0_get_rate,
+};
+
+static unsigned long s5pc100_clk_dout_apll2_get_rate(struct clk *clk)
 {
-	return s5pc1xx_clk_gate(S5PC100_SCLKGATE1, clk, enable);
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
+
+	ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_APLL2_MASK;
+	ratio >>= S5PC100_CLKDIV1_APLL2_SHIFT;
+
+	return rate / (ratio + 1);
 }
 
-static struct clk init_clocks_disable[] = {
-	{
-		.name		= "dsi",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_DSI,
-	}, {
-		.name		= "csi",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_CSI,
-	}, {
-		.name		= "ccan0",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_CCAN0,
-	}, {
-		.name		= "ccan1",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_CCAN1,
-	}, {
-		.name		= "keypad",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_KEYIF,
-	}, {
-		.name		= "hclkd2",
-		.id		= -1,
-		.parent		= NULL,
-		.enable		= s5pc1xx_clk_d20_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D20_HCLKD2,
-	}, {
-		.name		= "iis-d2",
-		.id		= -1,
-		.parent		= NULL,
-		.enable		= s5pc1xx_clk_d20_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D20_I2SD2,
-	}, {
-		.name		= "otg",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_USBOTG,
-	},
+static struct clk clk_dout_apll2 = {
+	.name		= "dout_apll2",
+	.id		= -1,
+	.parent		= &clk_mout_apll.clk,
+	.get_rate	= s5pc100_clk_dout_apll2_get_rate,
 };
 
-static struct clk init_clocks[] = {
-	/* System1 (D0_0) devices */
-	{
-		.name		= "intc",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_INTC,
-	}, {
-		.name		= "tzic",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_TZIC,
-	}, {
-		.name		= "cf-ata",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_CFCON,
-	}, {
-		.name		= "mdma",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_MDMA,
-	}, {
-		.name		= "g2d",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_G2D,
-	}, {
-		.name		= "secss",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_SECSS,
-	}, {
-		.name		= "cssys",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d00_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D00_CSSYS,
-	},
+/* MPLL */
+static struct clk *clk_src_mpll_list[] = {
+	[0] = &clk_fin_mpll,
+	[1] = &clk_fout_mpll,
+};
 
-	/* Memory (D0_1) devices */
-	{
-		.name		= "dmc",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d01_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D01_DMC,
-	}, {
-		.name		= "sromc",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d01_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D01_SROMC,
-	}, {
-		.name		= "onenand",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d01_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D01_ONENAND,
-	}, {
-		.name		= "nand",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d01_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D01_NFCON,
-	}, {
-		.name		= "intmem",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d01_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D01_INTMEM,
-	}, {
-		.name		= "ebi",
-		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d01_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D01_EBI,
-	},
+static struct clk_sources clk_src_mpll = {
+	.sources	= clk_src_mpll_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_mpll_list),
+};
 
-	/* System2 (D0_2) devices */
-	{
-		.name		= "seckey",
-		.id		= -1,
-		.parent		= &clk_pd0,
-		.enable		= s5pc1xx_clk_d02_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D02_SECKEY,
-	}, {
-		.name		= "sdm",
+static struct clksrc_clk clk_mout_mpll = {
+	.clk = {
+		.name		= "mout_mpll",
 		.id		= -1,
-		.parent		= &clk_hd0,
-		.enable		= s5pc1xx_clk_d02_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D02_SDM,
 	},
+	.shift		= S5PC100_CLKSRC0_MPLL_SHIFT,
+	.mask		= S5PC100_CLKSRC0_MPLL_MASK,
+	.sources	= &clk_src_mpll,
+	.reg_source	= S5PC100_CLKSRC0,
+};
 
-	/* File (D1_0) devices */
-	{
-		.name		= "pdma0",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_PDMA0,
-	}, {
-		.name		= "pdma1",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_PDMA1,
-	}, {
-		.name		= "usb-host",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_USBHOST,
-	}, {
-		.name		= "modem",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_MODEMIF,
-	}, {
-		.name		= "hsmmc",
-		.id		= 0,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC0,
-	}, {
-		.name		= "hsmmc",
-		.id		= 1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC1,
-	}, {
-		.name		= "hsmmc",
-		.id		= 2,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d10_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC2,
-	},
+static struct clk *clkset_am_list[] = {
+	[0] = &clk_mout_mpll.clk,
+	[1] = &clk_dout_apll2,
+};
 
-	/* Multimedia1 (D1_1) devices */
-	{
-		.name		= "lcd",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_LCD,
-	}, {
-		.name		= "rotator",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_ROTATOR,
-	}, {
-		.name		= "fimc",
-		.id		= 0,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC0,
-	}, {
-		.name		= "fimc",
-		.id		= 1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC1,
-	}, {
-		.name		= "fimc",
-		.id		= 2,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC2,
-	}, {
-		.name		= "jpeg",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_JPEG,
-	}, {
-		.name		= "g3d",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d11_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D11_G3D,
-	},
+static struct clk_sources clk_src_am = {
+	.sources	= clkset_am_list,
+	.nr_sources	= ARRAY_SIZE(clkset_am_list),
+};
 
-	/* Multimedia2 (D1_2) devices */
-	{
-		.name		= "tv",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d12_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D12_TV,
-	}, {
-		.name		= "vp",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d12_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D12_VP,
-	}, {
-		.name		= "mixer",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d12_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D12_MIXER,
-	}, {
-		.name		= "hdmi",
-		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d12_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D12_HDMI,
-	}, {
-		.name		= "mfc",
+static struct clksrc_clk clk_mout_am = {
+	.clk = {
+		.name		= "mout_am",
 		.id		= -1,
-		.parent		= &clk_h,
-		.enable		= s5pc1xx_clk_d12_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D12_MFC,
 	},
+	.shift		= S5PC100_CLKSRC0_AMMUX_SHIFT,
+	.mask		= S5PC100_CLKSRC0_AMMUX_MASK,
+	.sources	= &clk_src_am,
+	.reg_source	= S5PC100_CLKSRC0,
+};
 
-	/* System (D1_3) devices */
-	{
-		.name		= "chipid",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_CHIPID,
-	}, {
-		.name		= "gpio",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_GPIO,
-	}, {
-		.name		= "apc",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_APC,
-	}, {
-		.name		= "iec",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_IEC,
-	}, {
-		.name		= "timers",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_PWM,
-	}, {
-		.name		= "systimer",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_SYSTIMER,
-	}, {
-		.name		= "watchdog",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_WDT,
-	}, {
-		.name		= "rtc",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d13_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D13_RTC,
-	},
+static unsigned long s5pc100_clk_dout_d1_bus_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
 
-	/* Connectivity (D1_4) devices */
-	{
-		.name		= "uart",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_UART0,
-	}, {
-		.name		= "uart",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_UART1,
-	}, {
-		.name		= "uart",
-		.id		= 2,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_UART2,
-	}, {
-		.name		= "uart",
-		.id		= 3,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_UART3,
-	}, {
-		.name		= "i2c",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_IIC,
-	}, {
-		.name		= "hdmi-i2c",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_HDMI_IIC,
-	}, {
-		.name		= "spi",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_SPI0,
-	}, {
-		.name		= "spi",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_SPI1,
-	}, {
-		.name		= "spi",
-		.id		= 2,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_SPI2,
-	}, {
-		.name		= "irda",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_IRDA,
-	}, {
-		.name		= "hsitx",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_HSITX,
-	}, {
-		.name		= "hsirx",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d14_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D14_HSIRX,
-	},
+	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
 
-	/* Audio (D1_5) devices */
-	{
-		.name		= "iis",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_IIS0,
-	}, {
-		.name		= "iis",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_IIS1,
-	}, {
-		.name		= "iis",
-		.id		= 2,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_IIS2,
-	}, {
-		.name		= "ac97",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_AC97,
-	}, {
-		.name		= "pcm",
-		.id		= 0,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_PCM0,
-	}, {
-		.name		= "pcm",
-		.id		= 1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_PCM1,
-	}, {
-		.name		= "spdif",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_SPDIF,
-	}, {
-		.name		= "adc",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_TSADC,
-	}, {
-		.name		= "keyif",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_KEYIF,
-	}, {
-		.name		= "cg",
-		.id		= -1,
-		.parent		= &clk_p,
-		.enable		= s5pc1xx_clk_d15_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_D15_CG,
-	},
+	ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_D1_MASK;
+	ratio >>= S5PC100_CLKDIV1_D1_SHIFT;
 
-	/* Audio (D2_0) devices: all disabled */
+	return rate / (ratio + 1);
+}
 
-	/* Special Clocks 1 */
-	{
-		.name		= "sclk_hpm",
-		.id		= -1,
-		.parent		= NULL,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_HPM,
-	}, {
-		.name		= "sclk_onenand",
-		.id		= -1,
-		.parent		= NULL,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_ONENAND,
-	}, {
-		.name		= "sclk_spi_48",
-		.id		= 0,
-		.parent		= &clk_48m,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI0_48,
-	}, {
-		.name		= "sclk_spi_48",
-		.id		= 1,
-		.parent		= &clk_48m,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI1_48,
-	}, {
-		.name		= "sclk_spi_48",
-		.id		= 2,
-		.parent		= &clk_48m,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI2_48,
-	}, {
-		.name		= "sclk_mmc_48",
-		.id		= 0,
-		.parent		= &clk_48m,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC0_48,
-	}, {
-		.name		= "sclk_mmc_48",
-		.id		= 1,
-		.parent		= &clk_48m,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC1_48,
-	}, {
-		.name		= "sclk_mmc_48",
-		.id		= 2,
-		.parent		= &clk_48m,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC2_48,
-	},
+static struct clk clk_dout_d1_bus = {
+	.name		= "dout_d1_bus",
+	.id		= -1,
+	.parent		= &clk_mout_am.clk,
+	.get_rate	= s5pc100_clk_dout_d1_bus_get_rate,
+};
 
-	/* Special Clocks 2 */
-	{
-		.name		= "sclk_tv_54",
-		.id		= -1,
-		.parent		= &clk_54m,
-		.enable		= s5pc1xx_sclk1_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK1_TV54,
-	}, {
-		.name		= "sclk_vdac_54",
-		.id		= -1,
-		.parent		= &clk_54m,
-		.enable		= s5pc1xx_sclk1_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK1_VDAC54,
-	}, {
-		.name		= "sclk_spdif",
+static struct clk *clkset_onenand_list[] = {
+	[0] = &clk_dout_d0_bus,
+	[1] = &clk_dout_d1_bus,
+};
+
+static struct clk_sources clk_src_onenand = {
+	.sources	= clkset_onenand_list,
+	.nr_sources	= ARRAY_SIZE(clkset_onenand_list),
+};
+
+static struct clksrc_clk clk_mout_onenand = {
+	.clk = {
+		.name		= "mout_onenand",
 		.id		= -1,
-		.parent		= NULL,
-		.enable		= s5pc1xx_sclk1_ctrl,
-		.ctrlbit	= S5PC100_CLKGATE_SCLK1_SPDIF,
 	},
+	.shift		= S5PC100_CLKSRC0_ONENAND_SHIFT,
+	.mask		= S5PC100_CLKSRC0_ONENAND_MASK,
+	.sources	= &clk_src_onenand,
+	.reg_source	= S5PC100_CLKSRC0,
 };
 
-void __init s5pc1xx_register_clocks(void)
+static unsigned long s5pc100_clk_dout_pclkd1_get_rate(struct clk *clk)
 {
-	struct clk *clkp;
-	int ret;
-	int ptr;
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
 
-	clkp = init_clocks;
-	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
-	}
+	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
 
-	clkp = init_clocks_disable;
-	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+	ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_PCLKD1_MASK;
+	ratio >>= S5PC100_CLKDIV1_PCLKD1_SHIFT;
 
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
+	return rate / (ratio + 1);
+}
 
-		(clkp->enable)(clkp, 0);
-	}
+static struct clk clk_dout_pclkd1 = {
+	.name		= "dout_pclkd1",
+	.id		= -1,
+	.parent		= &clk_dout_d1_bus,
+	.get_rate	= s5pc100_clk_dout_pclkd1_get_rate,
+};
 
-	s3c_pwmclk_init();
+static unsigned long s5pc100_clk_dout_mpll2_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
+
+	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
+
+	ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_MPLL2_MASK;
+	ratio >>= S5PC100_CLKDIV1_MPLL2_SHIFT;
+
+	return rate / (ratio + 1);
 }
-static struct clk clk_fout_apll = {
-	.name		= "fout_apll",
+
+static struct clk clk_dout_mpll2 = {
+	.name		= "dout_mpll2",
 	.id		= -1,
+	.parent		= &clk_mout_am.clk,
+	.get_rate	= s5pc100_clk_dout_mpll2_get_rate,
 };
 
-static struct clk *clk_src_apll_list[] = {
-	[0] = &clk_fin_apll,
-	[1] = &clk_fout_apll,
-};
+static unsigned long s5pc100_clk_dout_cam_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
 
-static struct clk_sources clk_src_apll = {
-	.sources	= clk_src_apll_list,
-	.nr_sources	= ARRAY_SIZE(clk_src_apll_list),
+	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
+
+	ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_CAM_MASK;
+	ratio >>= S5PC100_CLKDIV1_CAM_SHIFT;
+
+	return rate / (ratio + 1);
+}
+
+static struct clk clk_dout_cam = {
+	.name		= "dout_cam",
+	.id		= -1,
+	.parent		= &clk_dout_mpll2,
+	.get_rate	= s5pc100_clk_dout_cam_get_rate,
 };
 
-static struct clksrc_clk clk_mout_apll = {
-	.clk	= {
-		.name		= "mout_apll",
-		.id		= -1,
-	},
-	.shift		= S5PC100_CLKSRC0_APLL_SHIFT,
-	.mask		= S5PC100_CLKSRC0_APLL_MASK,
-	.sources	= &clk_src_apll,
-	.reg_source	= S5PC100_CLKSRC0,
+static unsigned long s5pc100_clk_dout_mpll_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned int ratio;
+
+	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
+
+	ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_MPLL_MASK;
+	ratio >>= S5PC100_CLKDIV1_MPLL_SHIFT;
+
+	return rate / (ratio + 1);
+}
+
+static struct clk clk_dout_mpll = {
+	.name		= "dout_mpll",
+	.id		= -1,
+	.parent		= &clk_mout_am.clk,
+	.get_rate	= s5pc100_clk_dout_mpll_get_rate,
 };
 
+/* EPLL */
 static struct clk clk_fout_epll = {
 	.name		= "fout_epll",
 	.id		= -1,
@@ -833,85 +415,51 @@ static struct clksrc_clk clk_mout_epll = {
 	.reg_source	= S5PC100_CLKSRC0,
 };
 
-static struct clk *clk_src_mpll_list[] = {
-	[0] = &clk_fin_mpll,
-	[1] = &clk_fout_mpll,
+/* HPLL */
+static struct clk clk_fout_hpll = {
+	.name		= "fout_hpll",
+	.id		= -1,
 };
 
-static struct clk_sources clk_src_mpll = {
-	.sources	= clk_src_mpll_list,
-	.nr_sources	= ARRAY_SIZE(clk_src_mpll_list),
+static struct clk *clk_src_hpll_list[] = {
+	[0] = &clk_27m,
+	[1] = &clk_fout_hpll,
 };
 
-static struct clksrc_clk clk_mout_mpll = {
-	.clk = {
-		.name		= "mout_mpll",
+static struct clk_sources clk_src_hpll = {
+	.sources	= clk_src_hpll_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_hpll_list),
+};
+
+static struct clksrc_clk clk_mout_hpll = {
+	.clk	= {
+		.name		= "mout_hpll",
 		.id		= -1,
 	},
-	.shift		= S5PC100_CLKSRC0_MPLL_SHIFT,
-	.mask		= S5PC100_CLKSRC0_MPLL_MASK,
-	.sources	= &clk_src_mpll,
+	.shift		= S5PC100_CLKSRC0_HPLL_SHIFT,
+	.mask		= S5PC100_CLKSRC0_HPLL_MASK,
+	.sources	= &clk_src_hpll,
 	.reg_source	= S5PC100_CLKSRC0,
 };
 
-static unsigned long s5pc1xx_clk_doutmpll_get_rate(struct clk *clk)
-{
-	unsigned long rate = clk_get_rate(clk->parent);
-	unsigned long clkdiv;
-
-	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
-
-	clkdiv = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_MPLL_MASK;
-	rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL_SHIFT) + 1;
-
-	return rate;
-}
-
-static struct clk clk_dout_mpll = {
-	.name		= "dout_mpll",
-	.id		= -1,
-	.parent		= &clk_mout_mpll.clk,
-	.get_rate	= s5pc1xx_clk_doutmpll_get_rate,
-};
-
-static unsigned long s5pc1xx_clk_doutmpll2_get_rate(struct clk *clk)
-{
-	unsigned long rate = clk_get_rate(clk->parent);
-	unsigned long clkdiv;
-
-	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
-
-	clkdiv = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_MPLL2_MASK;
-	rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL2_SHIFT) + 1;
-
-	return rate;
-}
-
-struct clk clk_dout_mpll2 = {
-	.name		= "dout_mpll2",
-	.id		= -1,
-	.parent		= &clk_mout_mpll.clk,
-	.get_rate	= s5pc1xx_clk_doutmpll2_get_rate,
-};
-
-static struct clk *clkset_uart_list[] = {
-	&clk_mout_epll.clk,
-	&clk_dout_mpll,
-	NULL,
-	NULL
-};
-
-static struct clk_sources clkset_uart = {
-	.sources	= clkset_uart_list,
-	.nr_sources	= ARRAY_SIZE(clkset_uart_list),
-};
+/* Peripherals */
+/*
+ * The peripheral clocks are all controlled via clocksource followed
+ * by an optional divider and gate stage. We currently roll this into
+ * one clock which hides the intermediate clock from the mux.
+ *
+ * Note, the JPEG clock can only be an even divider...
+ *
+ * The scaler and LCD clocks depend on the S5PC100 version, and also
+ * have a common parent divisor so are not included here.
+ */
 
 static inline struct clksrc_clk *to_clksrc(struct clk *clk)
 {
 	return container_of(clk, struct clksrc_clk, clk);
 }
 
-static unsigned long s5pc1xx_getrate_clksrc(struct clk *clk)
+static unsigned long s5pc100_getrate_clksrc(struct clk *clk)
 {
 	struct clksrc_clk *sclk = to_clksrc(clk);
 	unsigned long rate = clk_get_rate(clk->parent);
@@ -925,7 +473,7 @@ static unsigned long s5pc1xx_getrate_clksrc(struct clk *clk)
 	return rate;
 }
 
-static int s5pc1xx_setrate_clksrc(struct clk *clk, unsigned long rate)
+static int s5pc100_setrate_clksrc(struct clk *clk, unsigned long rate)
 {
 	struct clksrc_clk *sclk = to_clksrc(clk);
 	void __iomem *reg = sclk->reg_divider;
@@ -938,14 +486,14 @@ static int s5pc1xx_setrate_clksrc(struct clk *clk, unsigned long rate)
 		return -EINVAL;
 
 	val = __raw_readl(reg);
-	val &= ~(0xf << sclk->shift);
-	val |= (div - 1) << sclk->shift;
+	val &= ~(0xf << sclk->divider_shift);
+	val |= (div - 1) << sclk->divider_shift;
 	__raw_writel(val, reg);
 
 	return 0;
 }
 
-static int s5pc1xx_setparent_clksrc(struct clk *clk, struct clk *parent)
+static int s5pc100_setparent_clksrc(struct clk *clk, struct clk *parent)
 {
 	struct clksrc_clk *sclk = to_clksrc(clk);
 	struct clk_sources *srcs = sclk->sources;
@@ -970,7 +518,7 @@ static int s5pc1xx_setparent_clksrc(struct clk *clk, struct clk *parent)
 	return -EINVAL;
 }
 
-static unsigned long s5pc1xx_roundrate_clksrc(struct clk *clk,
+static unsigned long s5pc100_roundrate_clksrc(struct clk *clk,
 					      unsigned long rate)
 {
 	unsigned long parent_rate = clk_get_rate(clk->parent);
@@ -992,16 +540,95 @@ static unsigned long s5pc1xx_roundrate_clksrc(struct clk *clk,
 	return rate;
 }
 
+static struct clk *clkset_spi_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll2,
+	&clk_fin_epll,
+	&clk_mout_hpll.clk,
+};
+
+static struct clk_sources clkset_spi = {
+	.sources	= clkset_spi_list,
+	.nr_sources	= ARRAY_SIZE(clkset_spi_list),
+};
+
+static struct clksrc_clk clk_spi0 = {
+	.clk	= {
+		.name		= "spi_bus",
+		.id		= 0,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI0,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC1_SPI0_SHIFT,
+	.mask		= S5PC100_CLKSRC1_SPI0_MASK,
+	.sources	= &clkset_spi,
+	.divider_shift	= S5PC100_CLKDIV2_SPI0_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV2,
+	.reg_source	= S5PC100_CLKSRC1,
+};
+
+static struct clksrc_clk clk_spi1 = {
+	.clk	= {
+		.name		= "spi_bus",
+		.id		= 1,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI1,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC1_SPI1_SHIFT,
+	.mask		= S5PC100_CLKSRC1_SPI1_MASK,
+	.sources	= &clkset_spi,
+	.divider_shift	= S5PC100_CLKDIV2_SPI1_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV2,
+	.reg_source	= S5PC100_CLKSRC1,
+};
+
+static struct clksrc_clk clk_spi2 = {
+	.clk	= {
+		.name		= "spi_bus",
+		.id		= 2,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI2,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC1_SPI2_SHIFT,
+	.mask		= S5PC100_CLKSRC1_SPI2_MASK,
+	.sources	= &clkset_spi,
+	.divider_shift	= S5PC100_CLKDIV2_SPI2_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV2,
+	.reg_source	= S5PC100_CLKSRC1,
+};
+
+static struct clk *clkset_uart_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+};
+
+static struct clk_sources clkset_uart = {
+	.sources	= clkset_uart_list,
+	.nr_sources	= ARRAY_SIZE(clkset_uart_list),
+};
+
 static struct clksrc_clk clk_uart_uclk1 = {
 	.clk	= {
 		.name		= "uclk1",
 		.id		= -1,
 		.ctrlbit        = S5PC100_CLKGATE_SCLK0_UART,
-		.enable		= s5pc1xx_sclk0_ctrl,
-		.set_parent	= s5pc1xx_setparent_clksrc,
-		.get_rate	= s5pc1xx_getrate_clksrc,
-		.set_rate	= s5pc1xx_setrate_clksrc,
-		.round_rate	= s5pc1xx_roundrate_clksrc,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
 	},
 	.shift		= S5PC100_CLKSRC1_UART_SHIFT,
 	.mask		= S5PC100_CLKSRC1_UART_MASK,
@@ -1011,16 +638,368 @@ static struct clksrc_clk clk_uart_uclk1 = {
 	.reg_source	= S5PC100_CLKSRC1,
 };
 
+static struct clk clk_iis_cd0 = {
+	.name		= "iis_cdclk0",
+	.id		= -1,
+};
+
+static struct clk clk_iis_cd1 = {
+	.name		= "iis_cdclk1",
+	.id		= -1,
+};
+
+static struct clk clk_iis_cd2 = {
+	.name		= "iis_cdclk2",
+	.id		= -1,
+};
+
+static struct clk clk_pcm_cd0 = {
+	.name		= "pcm_cdclk0",
+	.id		= -1,
+};
+
+static struct clk clk_pcm_cd1 = {
+	.name		= "pcm_cdclk1",
+	.id		= -1,
+};
+
+static struct clk *clkset_audio0_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_fin_epll,
+	&clk_iis_cd0,
+	&clk_pcm_cd0,
+	&clk_mout_hpll.clk,
+};
+
+static struct clk_sources clkset_audio0 = {
+	.sources	= clkset_audio0_list,
+	.nr_sources	= ARRAY_SIZE(clkset_audio0_list),
+};
+
+static struct clksrc_clk clk_audio0 = {
+	.clk	= {
+		.name		= "audio-bus",
+		.id		= 0,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_AUDIO0,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC3_AUDIO0_SHIFT,
+	.mask		= S5PC100_CLKSRC3_AUDIO0_MASK,
+	.sources	= &clkset_audio0,
+	.divider_shift	= S5PC100_CLKDIV4_AUDIO0_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV4,
+	.reg_source	= S5PC100_CLKSRC3,
+};
+
+static struct clk *clkset_audio1_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_fin_epll,
+	&clk_iis_cd1,
+	&clk_pcm_cd1,
+	&clk_mout_hpll.clk,
+};
+
+static struct clk_sources clkset_audio1 = {
+	.sources	= clkset_audio1_list,
+	.nr_sources	= ARRAY_SIZE(clkset_audio1_list),
+};
+
+static struct clksrc_clk clk_audio1 = {
+	.clk	= {
+		.name		= "audio-bus",
+		.id		= 1,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_AUDIO1,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC3_AUDIO1_SHIFT,
+	.mask		= S5PC100_CLKSRC3_AUDIO1_MASK,
+	.sources	= &clkset_audio1,
+	.divider_shift	= S5PC100_CLKDIV4_AUDIO1_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV4,
+	.reg_source	= S5PC100_CLKSRC3,
+};
+
+static struct clk *clkset_audio2_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_fin_epll,
+	&clk_iis_cd2,
+	&clk_mout_hpll.clk,
+};
+
+static struct clk_sources clkset_audio2 = {
+	.sources	= clkset_audio2_list,
+	.nr_sources	= ARRAY_SIZE(clkset_audio2_list),
+};
+
+static struct clksrc_clk clk_audio2 = {
+	.clk	= {
+		.name		= "audio-bus",
+		.id		= 2,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_AUDIO2,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC3_AUDIO2_SHIFT,
+	.mask		= S5PC100_CLKSRC3_AUDIO2_MASK,
+	.sources	= &clkset_audio2,
+	.divider_shift	= S5PC100_CLKDIV4_AUDIO2_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV4,
+	.reg_source	= S5PC100_CLKSRC3,
+};
+
+static struct clk *clkset_spdif_list[] = {
+	&clk_audio0.clk,
+	&clk_audio1.clk,
+	&clk_audio2.clk,
+};
+
+static struct clk_sources clkset_spdif = {
+	.sources	= clkset_spdif_list,
+	.nr_sources	= ARRAY_SIZE(clkset_spdif_list),
+};
+
+static struct clksrc_clk clk_spdif = {
+	.clk	= {
+		.name		= "spdif",
+		.id		= -1,
+	},
+	.shift		= S5PC100_CLKSRC3_SPDIF_SHIFT,
+	.mask		= S5PC100_CLKSRC3_SPDIF_MASK,
+	.sources	= &clkset_spdif,
+	.reg_source	= S5PC100_CLKSRC3,
+};
+
+static struct clk *clkset_lcd_fimc_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_mout_hpll.clk,
+	&clk_vclk_54m,
+};
+
+static struct clk_sources clkset_lcd_fimc = {
+	.sources	= clkset_lcd_fimc_list,
+	.nr_sources	= ARRAY_SIZE(clkset_lcd_fimc_list),
+};
+
+static struct clksrc_clk clk_lcd = {
+	.clk	= {
+		.name		= "lcd",
+		.id		= -1,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_LCD,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_LCD_SHIFT,
+	.mask		= S5PC100_CLKSRC2_LCD_MASK,
+	.sources	= &clkset_lcd_fimc,
+	.divider_shift	= S5PC100_CLKDIV3_LCD_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+static struct clksrc_clk clk_fimc0 = {
+	.clk	= {
+		.name		= "fimc",
+		.id		= 0,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_FIMC0,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_FIMC0_SHIFT,
+	.mask		= S5PC100_CLKSRC2_FIMC0_MASK,
+	.sources	= &clkset_lcd_fimc,
+	.divider_shift	= S5PC100_CLKDIV3_FIMC0_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+static struct clksrc_clk clk_fimc1 = {
+	.clk	= {
+		.name		= "fimc",
+		.id		= 1,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_FIMC1,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_FIMC1_SHIFT,
+	.mask		= S5PC100_CLKSRC2_FIMC1_MASK,
+	.sources	= &clkset_lcd_fimc,
+	.divider_shift	= S5PC100_CLKDIV3_FIMC1_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+static struct clksrc_clk clk_fimc2 = {
+	.clk	= {
+		.name		= "fimc",
+		.id		= 2,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_FIMC2,
+		.enable		= s5pc100_sclk1_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_FIMC2_SHIFT,
+	.mask		= S5PC100_CLKSRC2_FIMC2_MASK,
+	.sources	= &clkset_lcd_fimc,
+	.divider_shift	= S5PC100_CLKDIV3_FIMC2_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+static struct clk *clkset_mmc_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_fin_epll,
+	&clk_mout_hpll.clk ,
+};
+
+static struct clk_sources clkset_mmc = {
+	.sources	= clkset_mmc_list,
+	.nr_sources	= ARRAY_SIZE(clkset_mmc_list),
+};
+
+static struct clksrc_clk clk_mmc0 = {
+	.clk	= {
+		.name		= "mmc_bus",
+		.id		= 0,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC0,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_MMC0_SHIFT,
+	.mask		= S5PC100_CLKSRC2_MMC0_MASK,
+	.sources	= &clkset_mmc,
+	.divider_shift	= S5PC100_CLKDIV3_MMC0_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+static struct clksrc_clk clk_mmc1 = {
+	.clk	= {
+		.name		= "mmc_bus",
+		.id		= 1,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC1,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_MMC1_SHIFT,
+	.mask		= S5PC100_CLKSRC2_MMC1_MASK,
+	.sources	= &clkset_mmc,
+	.divider_shift	= S5PC100_CLKDIV3_MMC1_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+static struct clksrc_clk clk_mmc2 = {
+	.clk	= {
+		.name		= "mmc_bus",
+		.id		= 2,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC2,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC2_MMC2_SHIFT,
+	.mask		= S5PC100_CLKSRC2_MMC2_MASK,
+	.sources	= &clkset_mmc,
+	.divider_shift	= S5PC100_CLKDIV3_MMC2_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV3,
+	.reg_source	= S5PC100_CLKSRC2,
+};
+
+
+static struct clk *clkset_usbhost_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	&clk_mout_hpll.clk,
+	&clk_48m,
+};
+
+static struct clk_sources clkset_usbhost = {
+	.sources	= clkset_usbhost_list,
+	.nr_sources	= ARRAY_SIZE(clkset_usbhost_list),
+};
+
+static struct clksrc_clk clk_usbhost = {
+	.clk	= {
+		.name		= "usbhost",
+		.id		= -1,
+		.ctrlbit        = S5PC100_CLKGATE_SCLK0_USBHOST,
+		.enable		= s5pc100_sclk0_ctrl,
+		.set_parent	= s5pc100_setparent_clksrc,
+		.get_rate	= s5pc100_getrate_clksrc,
+		.set_rate	= s5pc100_setrate_clksrc,
+		.round_rate	= s5pc100_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC1_UHOST_SHIFT,
+	.mask		= S5PC100_CLKSRC1_UHOST_MASK,
+	.sources	= &clkset_usbhost,
+	.divider_shift	= S5PC100_CLKDIV2_UHOST_SHIFT,
+	.reg_divider	= S5PC100_CLKDIV2,
+	.reg_source	= S5PC100_CLKSRC1,
+};
+
 /* Clock initialisation code */
 
 static struct clksrc_clk *init_parents[] = {
 	&clk_mout_apll,
-	&clk_mout_epll,
 	&clk_mout_mpll,
+	&clk_mout_am,
+	&clk_mout_onenand,
+	&clk_mout_epll,
+	&clk_mout_hpll,
+	&clk_spi0,
+	&clk_spi1,
+	&clk_spi2,
 	&clk_uart_uclk1,
+	&clk_audio0,
+	&clk_audio1,
+	&clk_audio2,
+	&clk_spdif,
+	&clk_lcd,
+	&clk_fimc0,
+	&clk_fimc1,
+	&clk_fimc2,
+	&clk_mmc0,
+	&clk_mmc1,
+	&clk_mmc2,
+	&clk_usbhost,
 };
 
-static void __init_or_cpufreq s5pc1xx_set_clksrc(struct clksrc_clk *clk)
+static void __init_or_cpufreq s5pc100_set_clksrc(struct clksrc_clk *clk)
 {
 	struct clk_sources *srcs = clk->sources;
 	u32 clksrc = __raw_readl(clk->reg_source);
@@ -1036,9 +1015,9 @@ static void __init_or_cpufreq s5pc1xx_set_clksrc(struct clksrc_clk *clk)
 
 	clk->clk.parent = srcs->sources[clksrc];
 
-	printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n",
-	       clk->clk.name, clk->clk.parent->name, clksrc,
-	       clk_get_rate(&clk->clk));
+	printk(KERN_INFO "%s: source is %s (%d), rate is %ld.%03ld MHz\n",
+		clk->clk.name, clk->clk.parent->name, clksrc,
+		print_mhz(clk_get_rate(&clk->clk)));
 }
 
 #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
@@ -1052,10 +1031,7 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
 	unsigned long hclk;
 	unsigned long pclkd0;
 	unsigned long pclk;
-	unsigned long apll;
-	unsigned long mpll;
-	unsigned long hpll;
-	unsigned long epll;
+	unsigned long apll, mpll, epll, hpll;
 	unsigned int ptr;
 	u32 clkdiv0, clkdiv1;
 
@@ -1064,8 +1040,7 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
 	clkdiv0 = __raw_readl(S5PC100_CLKDIV0);
 	clkdiv1 = __raw_readl(S5PC100_CLKDIV1);
 
-	printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
-			__func__, clkdiv0, clkdiv1);
+	printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n", __func__, clkdiv0, clkdiv1);
 
 	xtal_clk = clk_get(NULL, "xtal");
 	BUG_ON(IS_ERR(xtal_clk));
@@ -1080,8 +1055,10 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
 	epll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_EPLL_CON));
 	hpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_HPLL_CON));
 
-	printk(KERN_INFO "S5PC100: PLL settings, A=%ld, M=%ld, E=%ld, H=%ld\n",
-	       apll, mpll, epll, hpll);
+	printk(KERN_INFO "S5PC100: Apll=%ld.%03ld Mhz, Mpll=%ld.%03ld Mhz"
+		", Epll=%ld.%03ld Mhz, Hpll=%ld.%03ld Mhz\n",
+		print_mhz(apll), print_mhz(mpll),
+		print_mhz(epll), print_mhz(hpll));
 
 	armclk = apll / GET_DIV(clkdiv0, S5PC100_CLKDIV0_APLL);
 	armclk = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_ARM);
@@ -1090,33 +1067,64 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
 	hclk = mpll / GET_DIV(clkdiv1, S5PC100_CLKDIV1_D1);
 	pclk = hclk / GET_DIV(clkdiv1, S5PC100_CLKDIV1_PCLKD1);
 
-	printk(KERN_INFO "S5PC100: ARMCLK=%ld, HCLKD0=%ld, PCLKD0=%ld, HCLK=%ld, PCLK=%ld\n",
-	       armclk, hclkd0, pclkd0, hclk, pclk);
+	printk(KERN_INFO "S5PC100: ARMCLK=%ld.%03ld MHz, HCLKD0=%ld.%03ld MHz,"
+		" PCLKD0=%ld.%03ld MHz\n, HCLK=%ld.%03ld MHz,"
+		" PCLK=%ld.%03ld MHz\n",
+		print_mhz(armclk), print_mhz(hclkd0),
+		print_mhz(pclkd0), print_mhz(hclk), print_mhz(pclk));
 
 	clk_fout_apll.rate = apll;
 	clk_fout_mpll.rate = mpll;
 	clk_fout_epll.rate = epll;
-	clk_fout_apll.rate = apll;
+	clk_fout_hpll.rate = hpll;
 
 	clk_h.rate = hclk;
 	clk_p.rate = pclk;
+	clk_f.rate = armclk;
 
 	for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
-		s5pc1xx_set_clksrc(init_parents[ptr]);
+		s5pc100_set_clksrc(init_parents[ptr]);
 }
 
 static struct clk *clks[] __initdata = {
 	&clk_ext_xtal_mux,
-	&clk_mout_epll.clk,
-	&clk_fout_epll,
+	&clk_mout_apll.clk,
+	&clk_dout_apll,
+	&clk_dout_d0_bus,
+	&clk_dout_pclkd0,
+	&clk_dout_apll2,
 	&clk_mout_mpll.clk,
+	&clk_mout_am.clk,
+	&clk_dout_d1_bus,
+	&clk_mout_onenand.clk,
+	&clk_dout_pclkd1,
+	&clk_dout_mpll2,
+	&clk_dout_cam,
 	&clk_dout_mpll,
+	&clk_mout_epll.clk,
+	&clk_fout_epll,
+	&clk_iis_cd0,
+	&clk_iis_cd1,
+	&clk_iis_cd2,
+	&clk_pcm_cd0,
+	&clk_pcm_cd1,
+	&clk_spi0.clk,
+	&clk_spi1.clk,
+	&clk_spi2.clk,
 	&clk_uart_uclk1.clk,
-	&clk_ext,
-	&clk_epll,
-	&clk_27m,
-	&clk_48m,
-	&clk_54m,
+	&clk_audio0.clk,
+	&clk_audio1.clk,
+	&clk_audio2.clk,
+	&clk_spdif.clk,
+	&clk_lcd.clk,
+	&clk_fimc0.clk,
+	&clk_fimc1.clk,
+	&clk_fimc2.clk,
+	&clk_mmc0.clk,
+	&clk_mmc1.clk,
+	&clk_mmc2.clk,
+	&clk_usbhost.clk,
+	&clk_arm,
 };
 
 void __init s5pc100_register_clocks(void)
@@ -1133,7 +1141,4 @@ void __init s5pc100_register_clocks(void)
 			       clkp->name, ret);
 		}
 	}
-
-	clk_mpll.parent = &clk_mout_mpll.clk;
-	clk_epll.parent = &clk_mout_epll.clk;
 }
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 05/17] ARM: S5PC1XX: add GPIO L banks to register definition
  2009-10-13  8:11         ` Marek Szyprowski
@ 2009-10-13  8:11           ` Marek Szyprowski
  -1 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: m.szyprowski, kyungmin.park, ben-linux, bhmin

Add GPIO L0-L4 banks to register definition.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/include/mach/gpio.h |   30 ++++++++++++++++++++++------
 1 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-s5pc100/include/mach/gpio.h b/arch/arm/mach-s5pc100/include/mach/gpio.h
index c74fc93..5d22961 100644
--- a/arch/arm/mach-s5pc100/include/mach/gpio.h
+++ b/arch/arm/mach-s5pc100/include/mach/gpio.h
@@ -47,6 +47,11 @@
 #define S5PC1XX_GPIO_K1_NR	(6)
 #define S5PC1XX_GPIO_K2_NR	(8)
 #define S5PC1XX_GPIO_K3_NR	(8)
+#define S5PC1XX_GPIO_L0_NR	(8)
+#define S5PC1XX_GPIO_L1_NR	(8)
+#define S5PC1XX_GPIO_L2_NR	(8)
+#define S5PC1XX_GPIO_L3_NR	(8)
+#define S5PC1XX_GPIO_L4_NR	(8)
 #define S5PC1XX_GPIO_MP00_NR	(8)
 #define S5PC1XX_GPIO_MP01_NR	(8)
 #define S5PC1XX_GPIO_MP02_NR	(8)
@@ -64,9 +69,9 @@
 	((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
 
 enum s3c_gpio_number {
-	S5PC1XX_GPIO_A0_START 	= 0,
-	S5PC1XX_GPIO_A1_START 	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A0),
-	S5PC1XX_GPIO_B_START 	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A1),
+	S5PC1XX_GPIO_A0_START	= 0,
+	S5PC1XX_GPIO_A1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A0),
+	S5PC1XX_GPIO_B_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A1),
 	S5PC1XX_GPIO_C_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_B),
 	S5PC1XX_GPIO_D_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_C),
 	S5PC1XX_GPIO_E0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_D),
@@ -93,11 +98,17 @@ enum s3c_gpio_number {
 	S5PC1XX_GPIO_K1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K0),
 	S5PC1XX_GPIO_K2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K1),
 	S5PC1XX_GPIO_K3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K2),
-	S5PC1XX_GPIO_MP00_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K3),
+	S5PC1XX_GPIO_L0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K3),
+	S5PC1XX_GPIO_L1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L0),
+	S5PC1XX_GPIO_L2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L1),
+	S5PC1XX_GPIO_L3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L2),
+	S5PC1XX_GPIO_L4_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L3),
+	S5PC1XX_GPIO_MP00_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L4),
 	S5PC1XX_GPIO_MP01_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP00),
 	S5PC1XX_GPIO_MP02_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP01),
 	S5PC1XX_GPIO_MP03_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP02),
 	S5PC1XX_GPIO_MP04_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP03),
+	S5PC1XX_GPIO_END	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP04),
 };
 
 /* S5PC1XX GPIO number definitions. */
@@ -130,17 +141,22 @@ enum s3c_gpio_number {
 #define S5PC1XX_GPK1(_nr)	(S5PC1XX_GPIO_K1_START + (_nr))
 #define S5PC1XX_GPK2(_nr)	(S5PC1XX_GPIO_K2_START + (_nr))
 #define S5PC1XX_GPK3(_nr)	(S5PC1XX_GPIO_K3_START + (_nr))
+#define S5PC1XX_GPL0(_nr)	(S5PC1XX_GPIO_L0_START + (_nr))
+#define S5PC1XX_GPL1(_nr)	(S5PC1XX_GPIO_L1_START + (_nr))
+#define S5PC1XX_GPL2(_nr)	(S5PC1XX_GPIO_L2_START + (_nr))
+#define S5PC1XX_GPL3(_nr)	(S5PC1XX_GPIO_L3_START + (_nr))
+#define S5PC1XX_GPL4(_nr)	(S5PC1XX_GPIO_L4_START + (_nr))
 #define S5PC1XX_MP00(_nr)	(S5PC1XX_GPIO_MP00_START + (_nr))
 #define S5PC1XX_MP01(_nr)	(S5PC1XX_GPIO_MP01_START + (_nr))
 #define S5PC1XX_MP02(_nr)	(S5PC1XX_GPIO_MP02_START + (_nr))
 #define S5PC1XX_MP03(_nr)	(S5PC1XX_GPIO_MP03_START + (_nr))
 #define S5PC1XX_MP04(_nr)	(S5PC1XX_GPIO_MP04_START + (_nr))
+#define S5PC1XX_MP05(_nr)	(S5PC1XX_GPIO_MP05_START + (_nr))
 
-/* the end of the S5PC1XX specific gpios */
-#define S5PC1XX_GPIO_END	(S5PC1XX_MP04(S5PC1XX_GPIO_MP04_NR) + 1)
+/* It used the end of the S5PC1XX gpios */
 #define S3C_GPIO_END		S5PC1XX_GPIO_END
 
 /* define the number of gpios we need to the one after the MP04() range */
-#define ARCH_NR_GPIOS	(S5PC1XX_MP04(S5PC1XX_GPIO_MP04_NR) + 1)
+#define ARCH_NR_GPIOS		(S5PC1XX_GPIO_END + 1)
 
 #include <asm-generic/gpio.h>
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 05/17] ARM: S5PC1XX: add GPIO L banks to register definition
@ 2009-10-13  8:11           ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

Add GPIO L0-L4 banks to register definition.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/include/mach/gpio.h |   30 ++++++++++++++++++++++------
 1 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-s5pc100/include/mach/gpio.h b/arch/arm/mach-s5pc100/include/mach/gpio.h
index c74fc93..5d22961 100644
--- a/arch/arm/mach-s5pc100/include/mach/gpio.h
+++ b/arch/arm/mach-s5pc100/include/mach/gpio.h
@@ -47,6 +47,11 @@
 #define S5PC1XX_GPIO_K1_NR	(6)
 #define S5PC1XX_GPIO_K2_NR	(8)
 #define S5PC1XX_GPIO_K3_NR	(8)
+#define S5PC1XX_GPIO_L0_NR	(8)
+#define S5PC1XX_GPIO_L1_NR	(8)
+#define S5PC1XX_GPIO_L2_NR	(8)
+#define S5PC1XX_GPIO_L3_NR	(8)
+#define S5PC1XX_GPIO_L4_NR	(8)
 #define S5PC1XX_GPIO_MP00_NR	(8)
 #define S5PC1XX_GPIO_MP01_NR	(8)
 #define S5PC1XX_GPIO_MP02_NR	(8)
@@ -64,9 +69,9 @@
 	((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
 
 enum s3c_gpio_number {
-	S5PC1XX_GPIO_A0_START 	= 0,
-	S5PC1XX_GPIO_A1_START 	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A0),
-	S5PC1XX_GPIO_B_START 	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A1),
+	S5PC1XX_GPIO_A0_START	= 0,
+	S5PC1XX_GPIO_A1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A0),
+	S5PC1XX_GPIO_B_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A1),
 	S5PC1XX_GPIO_C_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_B),
 	S5PC1XX_GPIO_D_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_C),
 	S5PC1XX_GPIO_E0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_D),
@@ -93,11 +98,17 @@ enum s3c_gpio_number {
 	S5PC1XX_GPIO_K1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K0),
 	S5PC1XX_GPIO_K2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K1),
 	S5PC1XX_GPIO_K3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K2),
-	S5PC1XX_GPIO_MP00_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K3),
+	S5PC1XX_GPIO_L0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K3),
+	S5PC1XX_GPIO_L1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L0),
+	S5PC1XX_GPIO_L2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L1),
+	S5PC1XX_GPIO_L3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L2),
+	S5PC1XX_GPIO_L4_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L3),
+	S5PC1XX_GPIO_MP00_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L4),
 	S5PC1XX_GPIO_MP01_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP00),
 	S5PC1XX_GPIO_MP02_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP01),
 	S5PC1XX_GPIO_MP03_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP02),
 	S5PC1XX_GPIO_MP04_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP03),
+	S5PC1XX_GPIO_END	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP04),
 };
 
 /* S5PC1XX GPIO number definitions. */
@@ -130,17 +141,22 @@ enum s3c_gpio_number {
 #define S5PC1XX_GPK1(_nr)	(S5PC1XX_GPIO_K1_START + (_nr))
 #define S5PC1XX_GPK2(_nr)	(S5PC1XX_GPIO_K2_START + (_nr))
 #define S5PC1XX_GPK3(_nr)	(S5PC1XX_GPIO_K3_START + (_nr))
+#define S5PC1XX_GPL0(_nr)	(S5PC1XX_GPIO_L0_START + (_nr))
+#define S5PC1XX_GPL1(_nr)	(S5PC1XX_GPIO_L1_START + (_nr))
+#define S5PC1XX_GPL2(_nr)	(S5PC1XX_GPIO_L2_START + (_nr))
+#define S5PC1XX_GPL3(_nr)	(S5PC1XX_GPIO_L3_START + (_nr))
+#define S5PC1XX_GPL4(_nr)	(S5PC1XX_GPIO_L4_START + (_nr))
 #define S5PC1XX_MP00(_nr)	(S5PC1XX_GPIO_MP00_START + (_nr))
 #define S5PC1XX_MP01(_nr)	(S5PC1XX_GPIO_MP01_START + (_nr))
 #define S5PC1XX_MP02(_nr)	(S5PC1XX_GPIO_MP02_START + (_nr))
 #define S5PC1XX_MP03(_nr)	(S5PC1XX_GPIO_MP03_START + (_nr))
 #define S5PC1XX_MP04(_nr)	(S5PC1XX_GPIO_MP04_START + (_nr))
+#define S5PC1XX_MP05(_nr)	(S5PC1XX_GPIO_MP05_START + (_nr))
 
-/* the end of the S5PC1XX specific gpios */
-#define S5PC1XX_GPIO_END	(S5PC1XX_MP04(S5PC1XX_GPIO_MP04_NR) + 1)
+/* It used the end of the S5PC1XX gpios */
 #define S3C_GPIO_END		S5PC1XX_GPIO_END
 
 /* define the number of gpios we need to the one after the MP04() range */
-#define ARCH_NR_GPIOS	(S5PC1XX_MP04(S5PC1XX_GPIO_MP04_NR) + 1)
+#define ARCH_NR_GPIOS		(S5PC1XX_GPIO_END + 1)
 
 #include <asm-generic/gpio.h>
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 06/17] ARM: S5PC1XX: GPIO registers rename
  2009-10-13  8:11           ` Marek Szyprowski
@ 2009-10-13  8:11             ` Marek Szyprowski
  -1 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: m.szyprowski, kyungmin.park, ben-linux, bhmin

S5PC100 and S5PC110 GPIO registers differs in many places, rename all
previously defined registers to be S5PC100 specific.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/include/mach/gpio.h |  244 ++++++++++++++--------------
 1 files changed, 122 insertions(+), 122 deletions(-)

diff --git a/arch/arm/mach-s5pc100/include/mach/gpio.h b/arch/arm/mach-s5pc100/include/mach/gpio.h
index 5d22961..2c4cbe8 100644
--- a/arch/arm/mach-s5pc100/include/mach/gpio.h
+++ b/arch/arm/mach-s5pc100/include/mach/gpio.h
@@ -18,45 +18,45 @@
 #define gpio_to_irq	__gpio_to_irq
 
 /* GPIO bank sizes */
-#define S5PC1XX_GPIO_A0_NR	(8)
-#define S5PC1XX_GPIO_A1_NR	(5)
-#define S5PC1XX_GPIO_B_NR	(8)
-#define S5PC1XX_GPIO_C_NR	(5)
-#define S5PC1XX_GPIO_D_NR	(7)
-#define S5PC1XX_GPIO_E0_NR	(8)
-#define S5PC1XX_GPIO_E1_NR	(6)
-#define S5PC1XX_GPIO_F0_NR	(8)
-#define S5PC1XX_GPIO_F1_NR	(8)
-#define S5PC1XX_GPIO_F2_NR	(8)
-#define S5PC1XX_GPIO_F3_NR	(4)
-#define S5PC1XX_GPIO_G0_NR	(8)
-#define S5PC1XX_GPIO_G1_NR	(3)
-#define S5PC1XX_GPIO_G2_NR	(7)
-#define S5PC1XX_GPIO_G3_NR	(7)
-#define S5PC1XX_GPIO_H0_NR	(8)
-#define S5PC1XX_GPIO_H1_NR	(8)
-#define S5PC1XX_GPIO_H2_NR	(8)
-#define S5PC1XX_GPIO_H3_NR	(8)
-#define S5PC1XX_GPIO_I_NR	(8)
-#define S5PC1XX_GPIO_J0_NR	(8)
-#define S5PC1XX_GPIO_J1_NR	(5)
-#define S5PC1XX_GPIO_J2_NR	(8)
-#define S5PC1XX_GPIO_J3_NR	(8)
-#define S5PC1XX_GPIO_J4_NR	(4)
-#define S5PC1XX_GPIO_K0_NR	(8)
-#define S5PC1XX_GPIO_K1_NR	(6)
-#define S5PC1XX_GPIO_K2_NR	(8)
-#define S5PC1XX_GPIO_K3_NR	(8)
-#define S5PC1XX_GPIO_L0_NR	(8)
-#define S5PC1XX_GPIO_L1_NR	(8)
-#define S5PC1XX_GPIO_L2_NR	(8)
-#define S5PC1XX_GPIO_L3_NR	(8)
-#define S5PC1XX_GPIO_L4_NR	(8)
-#define S5PC1XX_GPIO_MP00_NR	(8)
-#define S5PC1XX_GPIO_MP01_NR	(8)
-#define S5PC1XX_GPIO_MP02_NR	(8)
-#define S5PC1XX_GPIO_MP03_NR	(8)
-#define S5PC1XX_GPIO_MP04_NR	(5)
+#define S5PC100_GPIO_A0_NR	(8)
+#define S5PC100_GPIO_A1_NR	(5)
+#define S5PC100_GPIO_B_NR	(8)
+#define S5PC100_GPIO_C_NR	(5)
+#define S5PC100_GPIO_D_NR	(7)
+#define S5PC100_GPIO_E0_NR	(8)
+#define S5PC100_GPIO_E1_NR	(6)
+#define S5PC100_GPIO_F0_NR	(8)
+#define S5PC100_GPIO_F1_NR	(8)
+#define S5PC100_GPIO_F2_NR	(8)
+#define S5PC100_GPIO_F3_NR	(4)
+#define S5PC100_GPIO_G0_NR	(8)
+#define S5PC100_GPIO_G1_NR	(3)
+#define S5PC100_GPIO_G2_NR	(7)
+#define S5PC100_GPIO_G3_NR	(7)
+#define S5PC100_GPIO_H0_NR	(8)
+#define S5PC100_GPIO_H1_NR	(8)
+#define S5PC100_GPIO_H2_NR	(8)
+#define S5PC100_GPIO_H3_NR	(8)
+#define S5PC100_GPIO_I_NR	(8)
+#define S5PC100_GPIO_J0_NR	(8)
+#define S5PC100_GPIO_J1_NR	(5)
+#define S5PC100_GPIO_J2_NR	(8)
+#define S5PC100_GPIO_J3_NR	(8)
+#define S5PC100_GPIO_J4_NR	(4)
+#define S5PC100_GPIO_K0_NR	(8)
+#define S5PC100_GPIO_K1_NR	(6)
+#define S5PC100_GPIO_K2_NR	(8)
+#define S5PC100_GPIO_K3_NR	(8)
+#define S5PC100_GPIO_L0_NR	(8)
+#define S5PC100_GPIO_L1_NR	(8)
+#define S5PC100_GPIO_L2_NR	(8)
+#define S5PC100_GPIO_L3_NR	(8)
+#define S5PC100_GPIO_L4_NR	(8)
+#define S5PC100_GPIO_MP00_NR	(8)
+#define S5PC100_GPIO_MP01_NR	(8)
+#define S5PC100_GPIO_MP02_NR	(8)
+#define S5PC100_GPIO_MP03_NR	(8)
+#define S5PC100_GPIO_MP04_NR	(5)
 
 /* GPIO bank numbes */
 
@@ -69,94 +69,94 @@
 	((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
 
 enum s3c_gpio_number {
-	S5PC1XX_GPIO_A0_START	= 0,
-	S5PC1XX_GPIO_A1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A0),
-	S5PC1XX_GPIO_B_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A1),
-	S5PC1XX_GPIO_C_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_B),
-	S5PC1XX_GPIO_D_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_C),
-	S5PC1XX_GPIO_E0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_D),
-	S5PC1XX_GPIO_E1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_E0),
-	S5PC1XX_GPIO_F0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_E1),
-	S5PC1XX_GPIO_F1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F0),
-	S5PC1XX_GPIO_F2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F1),
-	S5PC1XX_GPIO_F3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F2),
-	S5PC1XX_GPIO_G0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F3),
-	S5PC1XX_GPIO_G1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G0),
-	S5PC1XX_GPIO_G2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G1),
-	S5PC1XX_GPIO_G3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G2),
-	S5PC1XX_GPIO_H0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G3),
-	S5PC1XX_GPIO_H1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H0),
-	S5PC1XX_GPIO_H2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H1),
-	S5PC1XX_GPIO_H3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H2),
-	S5PC1XX_GPIO_I_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H3),
-	S5PC1XX_GPIO_J0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_I),
-	S5PC1XX_GPIO_J1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J0),
-	S5PC1XX_GPIO_J2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J1),
-	S5PC1XX_GPIO_J3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J2),
-	S5PC1XX_GPIO_J4_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J3),
-	S5PC1XX_GPIO_K0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J4),
-	S5PC1XX_GPIO_K1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K0),
-	S5PC1XX_GPIO_K2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K1),
-	S5PC1XX_GPIO_K3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K2),
-	S5PC1XX_GPIO_L0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K3),
-	S5PC1XX_GPIO_L1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L0),
-	S5PC1XX_GPIO_L2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L1),
-	S5PC1XX_GPIO_L3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L2),
-	S5PC1XX_GPIO_L4_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L3),
-	S5PC1XX_GPIO_MP00_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L4),
-	S5PC1XX_GPIO_MP01_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP00),
-	S5PC1XX_GPIO_MP02_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP01),
-	S5PC1XX_GPIO_MP03_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP02),
-	S5PC1XX_GPIO_MP04_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP03),
-	S5PC1XX_GPIO_END	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP04),
+	S5PC100_GPIO_A0_START	= 0,
+	S5PC100_GPIO_A1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_A0),
+	S5PC100_GPIO_B_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_A1),
+	S5PC100_GPIO_C_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_B),
+	S5PC100_GPIO_D_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_C),
+	S5PC100_GPIO_E0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_D),
+	S5PC100_GPIO_E1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_E0),
+	S5PC100_GPIO_F0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_E1),
+	S5PC100_GPIO_F1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F0),
+	S5PC100_GPIO_F2_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F1),
+	S5PC100_GPIO_F3_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F2),
+	S5PC100_GPIO_G0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F3),
+	S5PC100_GPIO_G1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G0),
+	S5PC100_GPIO_G2_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G1),
+	S5PC100_GPIO_G3_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G2),
+	S5PC100_GPIO_H0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G3),
+	S5PC100_GPIO_H1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H0),
+	S5PC100_GPIO_H2_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H1),
+	S5PC100_GPIO_H3_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H2),
+	S5PC100_GPIO_I_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H3),
+	S5PC100_GPIO_J0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_I),
+	S5PC100_GPIO_J1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J0),
+	S5PC100_GPIO_J2_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J1),
+	S5PC100_GPIO_J3_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J2),
+	S5PC100_GPIO_J4_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J3),
+	S5PC100_GPIO_K0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J4),
+	S5PC100_GPIO_K1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K0),
+	S5PC100_GPIO_K2_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K1),
+	S5PC100_GPIO_K3_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K2),
+	S5PC100_GPIO_L0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K3),
+	S5PC100_GPIO_L1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L0),
+	S5PC100_GPIO_L2_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L1),
+	S5PC100_GPIO_L3_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L2),
+	S5PC100_GPIO_L4_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L3),
+	S5PC100_GPIO_MP00_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L4),
+	S5PC100_GPIO_MP01_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP00),
+	S5PC100_GPIO_MP02_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP01),
+	S5PC100_GPIO_MP03_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP02),
+	S5PC100_GPIO_MP04_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP03),
+	S5PC100_GPIO_END	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP04),
 };
 
-/* S5PC1XX GPIO number definitions. */
-#define S5PC1XX_GPA0(_nr)	(S5PC1XX_GPIO_A0_START + (_nr))
-#define S5PC1XX_GPA1(_nr)	(S5PC1XX_GPIO_A1_START + (_nr))
-#define S5PC1XX_GPB(_nr)	(S5PC1XX_GPIO_B_START + (_nr))
-#define S5PC1XX_GPC(_nr)	(S5PC1XX_GPIO_C_START + (_nr))
-#define S5PC1XX_GPD(_nr)	(S5PC1XX_GPIO_D_START + (_nr))
-#define S5PC1XX_GPE0(_nr)	(S5PC1XX_GPIO_E0_START + (_nr))
-#define S5PC1XX_GPE1(_nr)	(S5PC1XX_GPIO_E1_START + (_nr))
-#define S5PC1XX_GPF0(_nr)	(S5PC1XX_GPIO_F0_START + (_nr))
-#define S5PC1XX_GPF1(_nr)	(S5PC1XX_GPIO_F1_START + (_nr))
-#define S5PC1XX_GPF2(_nr)	(S5PC1XX_GPIO_F2_START + (_nr))
-#define S5PC1XX_GPF3(_nr)	(S5PC1XX_GPIO_F3_START + (_nr))
-#define S5PC1XX_GPG0(_nr)	(S5PC1XX_GPIO_G0_START + (_nr))
-#define S5PC1XX_GPG1(_nr)	(S5PC1XX_GPIO_G1_START + (_nr))
-#define S5PC1XX_GPG2(_nr)	(S5PC1XX_GPIO_G2_START + (_nr))
-#define S5PC1XX_GPG3(_nr)	(S5PC1XX_GPIO_G3_START + (_nr))
-#define S5PC1XX_GPH0(_nr)	(S5PC1XX_GPIO_H0_START + (_nr))
-#define S5PC1XX_GPH1(_nr)	(S5PC1XX_GPIO_H1_START + (_nr))
-#define S5PC1XX_GPH2(_nr)	(S5PC1XX_GPIO_H2_START + (_nr))
-#define S5PC1XX_GPH3(_nr)	(S5PC1XX_GPIO_H3_START + (_nr))
-#define S5PC1XX_GPI(_nr)	(S5PC1XX_GPIO_I_START + (_nr))
-#define S5PC1XX_GPJ0(_nr)	(S5PC1XX_GPIO_J0_START + (_nr))
-#define S5PC1XX_GPJ1(_nr)	(S5PC1XX_GPIO_J1_START + (_nr))
-#define S5PC1XX_GPJ2(_nr)	(S5PC1XX_GPIO_J2_START + (_nr))
-#define S5PC1XX_GPJ3(_nr)	(S5PC1XX_GPIO_J3_START + (_nr))
-#define S5PC1XX_GPJ4(_nr)	(S5PC1XX_GPIO_J4_START + (_nr))
-#define S5PC1XX_GPK0(_nr)	(S5PC1XX_GPIO_K0_START + (_nr))
-#define S5PC1XX_GPK1(_nr)	(S5PC1XX_GPIO_K1_START + (_nr))
-#define S5PC1XX_GPK2(_nr)	(S5PC1XX_GPIO_K2_START + (_nr))
-#define S5PC1XX_GPK3(_nr)	(S5PC1XX_GPIO_K3_START + (_nr))
-#define S5PC1XX_GPL0(_nr)	(S5PC1XX_GPIO_L0_START + (_nr))
-#define S5PC1XX_GPL1(_nr)	(S5PC1XX_GPIO_L1_START + (_nr))
-#define S5PC1XX_GPL2(_nr)	(S5PC1XX_GPIO_L2_START + (_nr))
-#define S5PC1XX_GPL3(_nr)	(S5PC1XX_GPIO_L3_START + (_nr))
-#define S5PC1XX_GPL4(_nr)	(S5PC1XX_GPIO_L4_START + (_nr))
-#define S5PC1XX_MP00(_nr)	(S5PC1XX_GPIO_MP00_START + (_nr))
-#define S5PC1XX_MP01(_nr)	(S5PC1XX_GPIO_MP01_START + (_nr))
-#define S5PC1XX_MP02(_nr)	(S5PC1XX_GPIO_MP02_START + (_nr))
-#define S5PC1XX_MP03(_nr)	(S5PC1XX_GPIO_MP03_START + (_nr))
-#define S5PC1XX_MP04(_nr)	(S5PC1XX_GPIO_MP04_START + (_nr))
-#define S5PC1XX_MP05(_nr)	(S5PC1XX_GPIO_MP05_START + (_nr))
+/* S5PC100 GPIO number definitions. */
+#define S5PC100_GPA0(_nr)	(S5PC100_GPIO_A0_START + (_nr))
+#define S5PC100_GPA1(_nr)	(S5PC100_GPIO_A1_START + (_nr))
+#define S5PC100_GPB(_nr)	(S5PC100_GPIO_B_START + (_nr))
+#define S5PC100_GPC(_nr)	(S5PC100_GPIO_C_START + (_nr))
+#define S5PC100_GPD(_nr)	(S5PC100_GPIO_D_START + (_nr))
+#define S5PC100_GPE0(_nr)	(S5PC100_GPIO_E0_START + (_nr))
+#define S5PC100_GPE1(_nr)	(S5PC100_GPIO_E1_START + (_nr))
+#define S5PC100_GPF0(_nr)	(S5PC100_GPIO_F0_START + (_nr))
+#define S5PC100_GPF1(_nr)	(S5PC100_GPIO_F1_START + (_nr))
+#define S5PC100_GPF2(_nr)	(S5PC100_GPIO_F2_START + (_nr))
+#define S5PC100_GPF3(_nr)	(S5PC100_GPIO_F3_START + (_nr))
+#define S5PC100_GPG0(_nr)	(S5PC100_GPIO_G0_START + (_nr))
+#define S5PC100_GPG1(_nr)	(S5PC100_GPIO_G1_START + (_nr))
+#define S5PC100_GPG2(_nr)	(S5PC100_GPIO_G2_START + (_nr))
+#define S5PC100_GPG3(_nr)	(S5PC100_GPIO_G3_START + (_nr))
+#define S5PC100_GPH0(_nr)	(S5PC100_GPIO_H0_START + (_nr))
+#define S5PC100_GPH1(_nr)	(S5PC100_GPIO_H1_START + (_nr))
+#define S5PC100_GPH2(_nr)	(S5PC100_GPIO_H2_START + (_nr))
+#define S5PC100_GPH3(_nr)	(S5PC100_GPIO_H3_START + (_nr))
+#define S5PC100_GPI(_nr)	(S5PC100_GPIO_I_START + (_nr))
+#define S5PC100_GPJ0(_nr)	(S5PC100_GPIO_J0_START + (_nr))
+#define S5PC100_GPJ1(_nr)	(S5PC100_GPIO_J1_START + (_nr))
+#define S5PC100_GPJ2(_nr)	(S5PC100_GPIO_J2_START + (_nr))
+#define S5PC100_GPJ3(_nr)	(S5PC100_GPIO_J3_START + (_nr))
+#define S5PC100_GPJ4(_nr)	(S5PC100_GPIO_J4_START + (_nr))
+#define S5PC100_GPK0(_nr)	(S5PC100_GPIO_K0_START + (_nr))
+#define S5PC100_GPK1(_nr)	(S5PC100_GPIO_K1_START + (_nr))
+#define S5PC100_GPK2(_nr)	(S5PC100_GPIO_K2_START + (_nr))
+#define S5PC100_GPK3(_nr)	(S5PC100_GPIO_K3_START + (_nr))
+#define S5PC100_GPL0(_nr)	(S5PC100_GPIO_L0_START + (_nr))
+#define S5PC100_GPL1(_nr)	(S5PC100_GPIO_L1_START + (_nr))
+#define S5PC100_GPL2(_nr)	(S5PC100_GPIO_L2_START + (_nr))
+#define S5PC100_GPL3(_nr)	(S5PC100_GPIO_L3_START + (_nr))
+#define S5PC100_GPL4(_nr)	(S5PC100_GPIO_L4_START + (_nr))
+#define S5PC100_MP00(_nr)	(S5PC100_GPIO_MP00_START + (_nr))
+#define S5PC100_MP01(_nr)	(S5PC100_GPIO_MP01_START + (_nr))
+#define S5PC100_MP02(_nr)	(S5PC100_GPIO_MP02_START + (_nr))
+#define S5PC100_MP03(_nr)	(S5PC100_GPIO_MP03_START + (_nr))
+#define S5PC100_MP04(_nr)	(S5PC100_GPIO_MP04_START + (_nr))
+#define S5PC100_MP05(_nr)	(S5PC100_GPIO_MP05_START + (_nr))
 
 /* It used the end of the S5PC1XX gpios */
-#define S3C_GPIO_END		S5PC1XX_GPIO_END
+#define S3C_GPIO_END		S5PC100_GPIO_END
 
 /* define the number of gpios we need to the one after the MP04() range */
-#define ARCH_NR_GPIOS		(S5PC1XX_GPIO_END + 1)
+#define ARCH_NR_GPIOS		(S5PC100_GPIO_END + 1)
 
 #include <asm-generic/gpio.h>
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 06/17] ARM: S5PC1XX: GPIO registers rename
@ 2009-10-13  8:11             ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

S5PC100 and S5PC110 GPIO registers differs in many places, rename all
previously defined registers to be S5PC100 specific.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/include/mach/gpio.h |  244 ++++++++++++++--------------
 1 files changed, 122 insertions(+), 122 deletions(-)

diff --git a/arch/arm/mach-s5pc100/include/mach/gpio.h b/arch/arm/mach-s5pc100/include/mach/gpio.h
index 5d22961..2c4cbe8 100644
--- a/arch/arm/mach-s5pc100/include/mach/gpio.h
+++ b/arch/arm/mach-s5pc100/include/mach/gpio.h
@@ -18,45 +18,45 @@
 #define gpio_to_irq	__gpio_to_irq
 
 /* GPIO bank sizes */
-#define S5PC1XX_GPIO_A0_NR	(8)
-#define S5PC1XX_GPIO_A1_NR	(5)
-#define S5PC1XX_GPIO_B_NR	(8)
-#define S5PC1XX_GPIO_C_NR	(5)
-#define S5PC1XX_GPIO_D_NR	(7)
-#define S5PC1XX_GPIO_E0_NR	(8)
-#define S5PC1XX_GPIO_E1_NR	(6)
-#define S5PC1XX_GPIO_F0_NR	(8)
-#define S5PC1XX_GPIO_F1_NR	(8)
-#define S5PC1XX_GPIO_F2_NR	(8)
-#define S5PC1XX_GPIO_F3_NR	(4)
-#define S5PC1XX_GPIO_G0_NR	(8)
-#define S5PC1XX_GPIO_G1_NR	(3)
-#define S5PC1XX_GPIO_G2_NR	(7)
-#define S5PC1XX_GPIO_G3_NR	(7)
-#define S5PC1XX_GPIO_H0_NR	(8)
-#define S5PC1XX_GPIO_H1_NR	(8)
-#define S5PC1XX_GPIO_H2_NR	(8)
-#define S5PC1XX_GPIO_H3_NR	(8)
-#define S5PC1XX_GPIO_I_NR	(8)
-#define S5PC1XX_GPIO_J0_NR	(8)
-#define S5PC1XX_GPIO_J1_NR	(5)
-#define S5PC1XX_GPIO_J2_NR	(8)
-#define S5PC1XX_GPIO_J3_NR	(8)
-#define S5PC1XX_GPIO_J4_NR	(4)
-#define S5PC1XX_GPIO_K0_NR	(8)
-#define S5PC1XX_GPIO_K1_NR	(6)
-#define S5PC1XX_GPIO_K2_NR	(8)
-#define S5PC1XX_GPIO_K3_NR	(8)
-#define S5PC1XX_GPIO_L0_NR	(8)
-#define S5PC1XX_GPIO_L1_NR	(8)
-#define S5PC1XX_GPIO_L2_NR	(8)
-#define S5PC1XX_GPIO_L3_NR	(8)
-#define S5PC1XX_GPIO_L4_NR	(8)
-#define S5PC1XX_GPIO_MP00_NR	(8)
-#define S5PC1XX_GPIO_MP01_NR	(8)
-#define S5PC1XX_GPIO_MP02_NR	(8)
-#define S5PC1XX_GPIO_MP03_NR	(8)
-#define S5PC1XX_GPIO_MP04_NR	(5)
+#define S5PC100_GPIO_A0_NR	(8)
+#define S5PC100_GPIO_A1_NR	(5)
+#define S5PC100_GPIO_B_NR	(8)
+#define S5PC100_GPIO_C_NR	(5)
+#define S5PC100_GPIO_D_NR	(7)
+#define S5PC100_GPIO_E0_NR	(8)
+#define S5PC100_GPIO_E1_NR	(6)
+#define S5PC100_GPIO_F0_NR	(8)
+#define S5PC100_GPIO_F1_NR	(8)
+#define S5PC100_GPIO_F2_NR	(8)
+#define S5PC100_GPIO_F3_NR	(4)
+#define S5PC100_GPIO_G0_NR	(8)
+#define S5PC100_GPIO_G1_NR	(3)
+#define S5PC100_GPIO_G2_NR	(7)
+#define S5PC100_GPIO_G3_NR	(7)
+#define S5PC100_GPIO_H0_NR	(8)
+#define S5PC100_GPIO_H1_NR	(8)
+#define S5PC100_GPIO_H2_NR	(8)
+#define S5PC100_GPIO_H3_NR	(8)
+#define S5PC100_GPIO_I_NR	(8)
+#define S5PC100_GPIO_J0_NR	(8)
+#define S5PC100_GPIO_J1_NR	(5)
+#define S5PC100_GPIO_J2_NR	(8)
+#define S5PC100_GPIO_J3_NR	(8)
+#define S5PC100_GPIO_J4_NR	(4)
+#define S5PC100_GPIO_K0_NR	(8)
+#define S5PC100_GPIO_K1_NR	(6)
+#define S5PC100_GPIO_K2_NR	(8)
+#define S5PC100_GPIO_K3_NR	(8)
+#define S5PC100_GPIO_L0_NR	(8)
+#define S5PC100_GPIO_L1_NR	(8)
+#define S5PC100_GPIO_L2_NR	(8)
+#define S5PC100_GPIO_L3_NR	(8)
+#define S5PC100_GPIO_L4_NR	(8)
+#define S5PC100_GPIO_MP00_NR	(8)
+#define S5PC100_GPIO_MP01_NR	(8)
+#define S5PC100_GPIO_MP02_NR	(8)
+#define S5PC100_GPIO_MP03_NR	(8)
+#define S5PC100_GPIO_MP04_NR	(5)
 
 /* GPIO bank numbes */
 
@@ -69,94 +69,94 @@
 	((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
 
 enum s3c_gpio_number {
-	S5PC1XX_GPIO_A0_START	= 0,
-	S5PC1XX_GPIO_A1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A0),
-	S5PC1XX_GPIO_B_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A1),
-	S5PC1XX_GPIO_C_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_B),
-	S5PC1XX_GPIO_D_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_C),
-	S5PC1XX_GPIO_E0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_D),
-	S5PC1XX_GPIO_E1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_E0),
-	S5PC1XX_GPIO_F0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_E1),
-	S5PC1XX_GPIO_F1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F0),
-	S5PC1XX_GPIO_F2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F1),
-	S5PC1XX_GPIO_F3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F2),
-	S5PC1XX_GPIO_G0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F3),
-	S5PC1XX_GPIO_G1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G0),
-	S5PC1XX_GPIO_G2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G1),
-	S5PC1XX_GPIO_G3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G2),
-	S5PC1XX_GPIO_H0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G3),
-	S5PC1XX_GPIO_H1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H0),
-	S5PC1XX_GPIO_H2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H1),
-	S5PC1XX_GPIO_H3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H2),
-	S5PC1XX_GPIO_I_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H3),
-	S5PC1XX_GPIO_J0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_I),
-	S5PC1XX_GPIO_J1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J0),
-	S5PC1XX_GPIO_J2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J1),
-	S5PC1XX_GPIO_J3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J2),
-	S5PC1XX_GPIO_J4_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J3),
-	S5PC1XX_GPIO_K0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J4),
-	S5PC1XX_GPIO_K1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K0),
-	S5PC1XX_GPIO_K2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K1),
-	S5PC1XX_GPIO_K3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K2),
-	S5PC1XX_GPIO_L0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K3),
-	S5PC1XX_GPIO_L1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L0),
-	S5PC1XX_GPIO_L2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L1),
-	S5PC1XX_GPIO_L3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L2),
-	S5PC1XX_GPIO_L4_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L3),
-	S5PC1XX_GPIO_MP00_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_L4),
-	S5PC1XX_GPIO_MP01_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP00),
-	S5PC1XX_GPIO_MP02_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP01),
-	S5PC1XX_GPIO_MP03_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP02),
-	S5PC1XX_GPIO_MP04_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP03),
-	S5PC1XX_GPIO_END	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP04),
+	S5PC100_GPIO_A0_START	= 0,
+	S5PC100_GPIO_A1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_A0),
+	S5PC100_GPIO_B_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_A1),
+	S5PC100_GPIO_C_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_B),
+	S5PC100_GPIO_D_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_C),
+	S5PC100_GPIO_E0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_D),
+	S5PC100_GPIO_E1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_E0),
+	S5PC100_GPIO_F0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_E1),
+	S5PC100_GPIO_F1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F0),
+	S5PC100_GPIO_F2_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F1),
+	S5PC100_GPIO_F3_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F2),
+	S5PC100_GPIO_G0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F3),
+	S5PC100_GPIO_G1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G0),
+	S5PC100_GPIO_G2_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G1),
+	S5PC100_GPIO_G3_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G2),
+	S5PC100_GPIO_H0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G3),
+	S5PC100_GPIO_H1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H0),
+	S5PC100_GPIO_H2_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H1),
+	S5PC100_GPIO_H3_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H2),
+	S5PC100_GPIO_I_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H3),
+	S5PC100_GPIO_J0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_I),
+	S5PC100_GPIO_J1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J0),
+	S5PC100_GPIO_J2_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J1),
+	S5PC100_GPIO_J3_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J2),
+	S5PC100_GPIO_J4_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J3),
+	S5PC100_GPIO_K0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J4),
+	S5PC100_GPIO_K1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K0),
+	S5PC100_GPIO_K2_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K1),
+	S5PC100_GPIO_K3_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K2),
+	S5PC100_GPIO_L0_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K3),
+	S5PC100_GPIO_L1_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L0),
+	S5PC100_GPIO_L2_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L1),
+	S5PC100_GPIO_L3_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L2),
+	S5PC100_GPIO_L4_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L3),
+	S5PC100_GPIO_MP00_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L4),
+	S5PC100_GPIO_MP01_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP00),
+	S5PC100_GPIO_MP02_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP01),
+	S5PC100_GPIO_MP03_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP02),
+	S5PC100_GPIO_MP04_START	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP03),
+	S5PC100_GPIO_END	= S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP04),
 };
 
-/* S5PC1XX GPIO number definitions. */
-#define S5PC1XX_GPA0(_nr)	(S5PC1XX_GPIO_A0_START + (_nr))
-#define S5PC1XX_GPA1(_nr)	(S5PC1XX_GPIO_A1_START + (_nr))
-#define S5PC1XX_GPB(_nr)	(S5PC1XX_GPIO_B_START + (_nr))
-#define S5PC1XX_GPC(_nr)	(S5PC1XX_GPIO_C_START + (_nr))
-#define S5PC1XX_GPD(_nr)	(S5PC1XX_GPIO_D_START + (_nr))
-#define S5PC1XX_GPE0(_nr)	(S5PC1XX_GPIO_E0_START + (_nr))
-#define S5PC1XX_GPE1(_nr)	(S5PC1XX_GPIO_E1_START + (_nr))
-#define S5PC1XX_GPF0(_nr)	(S5PC1XX_GPIO_F0_START + (_nr))
-#define S5PC1XX_GPF1(_nr)	(S5PC1XX_GPIO_F1_START + (_nr))
-#define S5PC1XX_GPF2(_nr)	(S5PC1XX_GPIO_F2_START + (_nr))
-#define S5PC1XX_GPF3(_nr)	(S5PC1XX_GPIO_F3_START + (_nr))
-#define S5PC1XX_GPG0(_nr)	(S5PC1XX_GPIO_G0_START + (_nr))
-#define S5PC1XX_GPG1(_nr)	(S5PC1XX_GPIO_G1_START + (_nr))
-#define S5PC1XX_GPG2(_nr)	(S5PC1XX_GPIO_G2_START + (_nr))
-#define S5PC1XX_GPG3(_nr)	(S5PC1XX_GPIO_G3_START + (_nr))
-#define S5PC1XX_GPH0(_nr)	(S5PC1XX_GPIO_H0_START + (_nr))
-#define S5PC1XX_GPH1(_nr)	(S5PC1XX_GPIO_H1_START + (_nr))
-#define S5PC1XX_GPH2(_nr)	(S5PC1XX_GPIO_H2_START + (_nr))
-#define S5PC1XX_GPH3(_nr)	(S5PC1XX_GPIO_H3_START + (_nr))
-#define S5PC1XX_GPI(_nr)	(S5PC1XX_GPIO_I_START + (_nr))
-#define S5PC1XX_GPJ0(_nr)	(S5PC1XX_GPIO_J0_START + (_nr))
-#define S5PC1XX_GPJ1(_nr)	(S5PC1XX_GPIO_J1_START + (_nr))
-#define S5PC1XX_GPJ2(_nr)	(S5PC1XX_GPIO_J2_START + (_nr))
-#define S5PC1XX_GPJ3(_nr)	(S5PC1XX_GPIO_J3_START + (_nr))
-#define S5PC1XX_GPJ4(_nr)	(S5PC1XX_GPIO_J4_START + (_nr))
-#define S5PC1XX_GPK0(_nr)	(S5PC1XX_GPIO_K0_START + (_nr))
-#define S5PC1XX_GPK1(_nr)	(S5PC1XX_GPIO_K1_START + (_nr))
-#define S5PC1XX_GPK2(_nr)	(S5PC1XX_GPIO_K2_START + (_nr))
-#define S5PC1XX_GPK3(_nr)	(S5PC1XX_GPIO_K3_START + (_nr))
-#define S5PC1XX_GPL0(_nr)	(S5PC1XX_GPIO_L0_START + (_nr))
-#define S5PC1XX_GPL1(_nr)	(S5PC1XX_GPIO_L1_START + (_nr))
-#define S5PC1XX_GPL2(_nr)	(S5PC1XX_GPIO_L2_START + (_nr))
-#define S5PC1XX_GPL3(_nr)	(S5PC1XX_GPIO_L3_START + (_nr))
-#define S5PC1XX_GPL4(_nr)	(S5PC1XX_GPIO_L4_START + (_nr))
-#define S5PC1XX_MP00(_nr)	(S5PC1XX_GPIO_MP00_START + (_nr))
-#define S5PC1XX_MP01(_nr)	(S5PC1XX_GPIO_MP01_START + (_nr))
-#define S5PC1XX_MP02(_nr)	(S5PC1XX_GPIO_MP02_START + (_nr))
-#define S5PC1XX_MP03(_nr)	(S5PC1XX_GPIO_MP03_START + (_nr))
-#define S5PC1XX_MP04(_nr)	(S5PC1XX_GPIO_MP04_START + (_nr))
-#define S5PC1XX_MP05(_nr)	(S5PC1XX_GPIO_MP05_START + (_nr))
+/* S5PC100 GPIO number definitions. */
+#define S5PC100_GPA0(_nr)	(S5PC100_GPIO_A0_START + (_nr))
+#define S5PC100_GPA1(_nr)	(S5PC100_GPIO_A1_START + (_nr))
+#define S5PC100_GPB(_nr)	(S5PC100_GPIO_B_START + (_nr))
+#define S5PC100_GPC(_nr)	(S5PC100_GPIO_C_START + (_nr))
+#define S5PC100_GPD(_nr)	(S5PC100_GPIO_D_START + (_nr))
+#define S5PC100_GPE0(_nr)	(S5PC100_GPIO_E0_START + (_nr))
+#define S5PC100_GPE1(_nr)	(S5PC100_GPIO_E1_START + (_nr))
+#define S5PC100_GPF0(_nr)	(S5PC100_GPIO_F0_START + (_nr))
+#define S5PC100_GPF1(_nr)	(S5PC100_GPIO_F1_START + (_nr))
+#define S5PC100_GPF2(_nr)	(S5PC100_GPIO_F2_START + (_nr))
+#define S5PC100_GPF3(_nr)	(S5PC100_GPIO_F3_START + (_nr))
+#define S5PC100_GPG0(_nr)	(S5PC100_GPIO_G0_START + (_nr))
+#define S5PC100_GPG1(_nr)	(S5PC100_GPIO_G1_START + (_nr))
+#define S5PC100_GPG2(_nr)	(S5PC100_GPIO_G2_START + (_nr))
+#define S5PC100_GPG3(_nr)	(S5PC100_GPIO_G3_START + (_nr))
+#define S5PC100_GPH0(_nr)	(S5PC100_GPIO_H0_START + (_nr))
+#define S5PC100_GPH1(_nr)	(S5PC100_GPIO_H1_START + (_nr))
+#define S5PC100_GPH2(_nr)	(S5PC100_GPIO_H2_START + (_nr))
+#define S5PC100_GPH3(_nr)	(S5PC100_GPIO_H3_START + (_nr))
+#define S5PC100_GPI(_nr)	(S5PC100_GPIO_I_START + (_nr))
+#define S5PC100_GPJ0(_nr)	(S5PC100_GPIO_J0_START + (_nr))
+#define S5PC100_GPJ1(_nr)	(S5PC100_GPIO_J1_START + (_nr))
+#define S5PC100_GPJ2(_nr)	(S5PC100_GPIO_J2_START + (_nr))
+#define S5PC100_GPJ3(_nr)	(S5PC100_GPIO_J3_START + (_nr))
+#define S5PC100_GPJ4(_nr)	(S5PC100_GPIO_J4_START + (_nr))
+#define S5PC100_GPK0(_nr)	(S5PC100_GPIO_K0_START + (_nr))
+#define S5PC100_GPK1(_nr)	(S5PC100_GPIO_K1_START + (_nr))
+#define S5PC100_GPK2(_nr)	(S5PC100_GPIO_K2_START + (_nr))
+#define S5PC100_GPK3(_nr)	(S5PC100_GPIO_K3_START + (_nr))
+#define S5PC100_GPL0(_nr)	(S5PC100_GPIO_L0_START + (_nr))
+#define S5PC100_GPL1(_nr)	(S5PC100_GPIO_L1_START + (_nr))
+#define S5PC100_GPL2(_nr)	(S5PC100_GPIO_L2_START + (_nr))
+#define S5PC100_GPL3(_nr)	(S5PC100_GPIO_L3_START + (_nr))
+#define S5PC100_GPL4(_nr)	(S5PC100_GPIO_L4_START + (_nr))
+#define S5PC100_MP00(_nr)	(S5PC100_GPIO_MP00_START + (_nr))
+#define S5PC100_MP01(_nr)	(S5PC100_GPIO_MP01_START + (_nr))
+#define S5PC100_MP02(_nr)	(S5PC100_GPIO_MP02_START + (_nr))
+#define S5PC100_MP03(_nr)	(S5PC100_GPIO_MP03_START + (_nr))
+#define S5PC100_MP04(_nr)	(S5PC100_GPIO_MP04_START + (_nr))
+#define S5PC100_MP05(_nr)	(S5PC100_GPIO_MP05_START + (_nr))
 
 /* It used the end of the S5PC1XX gpios */
-#define S3C_GPIO_END		S5PC1XX_GPIO_END
+#define S3C_GPIO_END		S5PC100_GPIO_END
 
 /* define the number of gpios we need to the one after the MP04() range */
-#define ARCH_NR_GPIOS		(S5PC1XX_GPIO_END + 1)
+#define ARCH_NR_GPIOS		(S5PC100_GPIO_END + 1)
 
 #include <asm-generic/gpio.h>
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 07/17] ARM: S5PC1xx: add gpiolib and external/gpio interrupt support
  2009-10-13  8:11             ` Marek Szyprowski
@ 2009-10-13  8:11               ` Marek Szyprowski
  -1 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: kyungmin.park, bhmin, ben-linux, m.szyprowski

Add support for gpiolib calls. This is based on the gpiolib implementation
from plat-s3c64xx tree.
Add support for external interrupts for GPIO H banks.
Add support for GPIO interrupts for all banks.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/plat-s3c/Kconfig                          |    6 +
 arch/arm/plat-s3c/include/plat/gpio-cfg.h          |    1 +
 arch/arm/plat-s5pc1xx/Kconfig                      |    3 +
 arch/arm/plat-s5pc1xx/Makefile                     |    3 +-
 arch/arm/plat-s5pc1xx/cpu.c                        |    5 +
 arch/arm/plat-s5pc1xx/gpio-config.c                |   61 +++
 arch/arm/plat-s5pc1xx/gpiolib.c                    |  503 ++++++++++++++++++++
 .../plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h   |   33 ++
 arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h      |   44 ++
 arch/arm/plat-s5pc1xx/include/plat/irqs.h          |   15 +-
 arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h     |   70 +++
 arch/arm/plat-s5pc1xx/irq-eint.c                   |  281 +++++++++++
 arch/arm/plat-s5pc1xx/irq-gpio.c                   |  266 +++++++++++
 arch/arm/plat-s5pc1xx/irq.c                        |    2 +-
 14 files changed, 1288 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/plat-s5pc1xx/gpio-config.c
 create mode 100644 arch/arm/plat-s5pc1xx/gpiolib.c
 create mode 100644 arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h
 create mode 100644 arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h
 create mode 100644 arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
 create mode 100644 arch/arm/plat-s5pc1xx/irq-eint.c
 create mode 100644 arch/arm/plat-s5pc1xx/irq-gpio.c

diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig
index 8931c5f..f155a84 100644
--- a/arch/arm/plat-s3c/Kconfig
+++ b/arch/arm/plat-s3c/Kconfig
@@ -159,6 +159,12 @@ config S3C_GPIO_CFG_S3C64XX
 	  Internal configuration to enable S3C64XX style GPIO configuration
 	  functions.
 
+config S5P_GPIO_CFG_S5PC1XX
+	bool
+	help
+	  Internal configuration to enable S5PC1XX style GPIO configuration
+	  functions.
+
 # DMA
 
 config S3C_DMA
diff --git a/arch/arm/plat-s3c/include/plat/gpio-cfg.h b/arch/arm/plat-s3c/include/plat/gpio-cfg.h
index 29cd6a8..7e73429 100644
--- a/arch/arm/plat-s3c/include/plat/gpio-cfg.h
+++ b/arch/arm/plat-s3c/include/plat/gpio-cfg.h
@@ -62,6 +62,7 @@ struct s3c_gpio_cfg {
 #define S3C_GPIO_INPUT	(S3C_GPIO_SPECIAL(0))
 #define S3C_GPIO_OUTPUT	(S3C_GPIO_SPECIAL(1))
 #define S3C_GPIO_SFN(x)	(S3C_GPIO_SPECIAL(x))
+#define S3C_GPIO_IRQ	(S3C_GPIO_SPECIAL(0xf))
 
 #define s3c_gpio_is_cfg_special(_cfg) \
 	(((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK)
diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig
index a8a711c..86edd27 100644
--- a/arch/arm/plat-s5pc1xx/Kconfig
+++ b/arch/arm/plat-s5pc1xx/Kconfig
@@ -15,6 +15,9 @@ config PLAT_S5PC1XX
 	select ARCH_REQUIRE_GPIOLIB
 	select S3C_GPIO_TRACK
 	select S3C_GPIO_PULL_UPDOWN
+	select S3C_GPIO_CFG_S3C24XX
+	select S3C_GPIO_CFG_S3C64XX
+	select S5P_GPIO_CFG_S5PC1XX
 	help
 	  Base platform code for any Samsung S5PC1XX device
 
diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile
index ebbf364..f126951 100644
--- a/arch/arm/plat-s5pc1xx/Makefile
+++ b/arch/arm/plat-s5pc1xx/Makefile
@@ -13,8 +13,9 @@ obj-				:=
 
 obj-y				+= dev-uart.o
 obj-y				+= cpu.o
-obj-y				+= irq.o
+obj-y				+= irq.o irq-gpio.o irq-eint.o
 obj-y				+= clock.o
+obj-y				+= gpiolib.o
 
 # CPU support
 
diff --git a/arch/arm/plat-s5pc1xx/cpu.c b/arch/arm/plat-s5pc1xx/cpu.c
index e8f3472..02baeaa 100644
--- a/arch/arm/plat-s5pc1xx/cpu.c
+++ b/arch/arm/plat-s5pc1xx/cpu.c
@@ -60,6 +60,11 @@ static struct map_desc s5pc1xx_iodesc[] __initdata = {
 		.length		= SZ_4K,
 		.type		= MT_DEVICE,
 	}, {
+		.virtual	= (unsigned long)S5PC1XX_VA_GPIO,
+		.pfn		= __phys_to_pfn(S5PC100_PA_GPIO),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
 		.virtual	= (unsigned long)S5PC1XX_VA_CHIPID,
 		.pfn		= __phys_to_pfn(S5PC1XX_PA_CHIPID),
 		.length		= SZ_16,
diff --git a/arch/arm/plat-s5pc1xx/gpio-config.c b/arch/arm/plat-s5pc1xx/gpio-config.c
new file mode 100644
index 0000000..b911475
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/gpio-config.c
@@ -0,0 +1,61 @@
+/* linux/arch/arm/plat-s5pc1xx/gpio-config.c
+ *
+ * Copyright 2009 Samsung Electronics
+ *	InKi Dae  <inki.dae@samsung.com>
+ *
+ * S5PC110 GPIO Configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+
+#include <mach/gpio-core.h>
+#include <plat/gpio-cfg-s5pc1xx.h>
+
+s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin, unsigned int off)
+{
+	struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+	void __iomem *reg;
+	int shift = off * 2;
+	u32 drvstr;
+
+	if (!chip)
+		return -EINVAL;
+
+	reg = chip->base + 0x0C;
+
+	drvstr = __raw_readl(reg);
+	drvstr = 0xffff & (0x3 << shift);
+	drvstr = drvstr >> shift;
+
+	return (__force s5p_gpio_drvstr_t)drvstr;
+}
+EXPORT_SYMBOL(s5p_gpio_get_drvstr);
+
+int s5p_gpio_set_drvstr(unsigned int pin, unsigned int off,
+			s5p_gpio_drvstr_t drvstr)
+{
+	struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+	void __iomem *reg;
+	int shift = off * 2;
+	u32 tmp;
+
+	if (!chip)
+		return -EINVAL;
+
+	reg = chip->base + 0x0C;
+
+	tmp = __raw_readl(reg);
+	tmp |= drvstr << shift;
+
+	__raw_writel(tmp, reg);
+
+	return 0;
+}
+EXPORT_SYMBOL(s5p_gpio_set_drvstr);
diff --git a/arch/arm/plat-s5pc1xx/gpiolib.c b/arch/arm/plat-s5pc1xx/gpiolib.c
new file mode 100644
index 0000000..9da8efc
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/gpiolib.c
@@ -0,0 +1,503 @@
+/*
+ * arch/arm/plat-s5pc1xx/gpiolib.c
+ *
+ *  Copyright 2009 Samsung Electronics Co
+ *  Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * S5PC1XX - GPIOlib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <mach/gpio.h>
+#include <mach/gpio-core.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <plat/regs-gpio.h>
+
+/* S5PC100 GPIO bank summary:
+ *
+ * Bank	GPIOs	Style	INT Type
+ * A0	8	4Bit	GPIO_INT0
+ * A1	5	4Bit	GPIO_INT1
+ * B	8	4Bit	GPIO_INT2
+ * C	5	4Bit	GPIO_INT3
+ * D	7	4Bit	GPIO_INT4
+ * E0	8	4Bit	GPIO_INT5
+ * E1	6	4Bit	GPIO_INT6
+ * F0	8	4Bit	GPIO_INT7
+ * F1	8	4Bit	GPIO_INT8
+ * F2	8	4Bit	GPIO_INT9
+ * F3	4	4Bit	GPIO_INT10
+ * G0	8	4Bit	GPIO_INT11
+ * G1	3	4Bit	GPIO_INT12
+ * G2	7	4Bit	GPIO_INT13
+ * G3	7	4Bit	GPIO_INT14
+ * H0	8	4Bit	WKUP_INT
+ * H1	8	4Bit	WKUP_INT
+ * H2	8	4Bit	WKUP_INT
+ * H3	8	4Bit	WKUP_INT
+ * I	8	4Bit	GPIO_INT15
+ * J0	8	4Bit	GPIO_INT16
+ * J1	5	4Bit	GPIO_INT17
+ * J2	8	4Bit	GPIO_INT18
+ * J3	8	4Bit	GPIO_INT19
+ * J4	4	4Bit	GPIO_INT20
+ * K0	8	4Bit	None
+ * K1	6	4Bit	None
+ * K2	8	4Bit	None
+ * K3	8	4Bit	None
+ * L0	8	4Bit	None
+ * L1	8	4Bit	None
+ * L2	8	4Bit	None
+ * L3	8	4Bit	None
+ */
+
+#define OFF_GPCON	(0x00)
+#define OFF_GPDAT	(0x04)
+
+#define con_4bit_shift(__off) ((__off) * 4)
+
+#if 1
+#define gpio_dbg(x...) do { } while (0)
+#else
+#define gpio_dbg(x...) printk(KERN_DEBUG x)
+#endif
+
+/* The s5pc1xx_gpiolib routines are to control the gpio banks where
+ * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
+ * following example:
+ *
+ * base + 0x00: Control register, 4 bits per gpio
+ *	        gpio n: 4 bits starting at (4*n)
+ *		0000 = input, 0001 = output, others mean special-function
+ * base + 0x04: Data register, 1 bit per gpio
+ *		bit n: data bit n
+ *
+ * Note, since the data register is one bit per gpio and is at base + 0x4
+ * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of
+ * the output.
+ */
+
+static int s5pc1xx_gpiolib_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+	void __iomem *base = ourchip->base;
+	unsigned long con;
+
+	con = __raw_readl(base + OFF_GPCON);
+	con &= ~(0xf << con_4bit_shift(offset));
+	__raw_writel(con, base + OFF_GPCON);
+
+	gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
+
+	return 0;
+}
+
+static int s5pc1xx_gpiolib_output(struct gpio_chip *chip,
+				       unsigned offset, int value)
+{
+	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+	void __iomem *base = ourchip->base;
+	unsigned long con;
+	unsigned long dat;
+
+	con = __raw_readl(base + OFF_GPCON);
+	con &= ~(0xf << con_4bit_shift(offset));
+	con |= 0x1 << con_4bit_shift(offset);
+
+	dat = __raw_readl(base + OFF_GPDAT);
+	if (value)
+		dat |= 1 << offset;
+	else
+		dat &= ~(1 << offset);
+
+	__raw_writel(dat, base + OFF_GPDAT);
+	__raw_writel(con, base + OFF_GPCON);
+	__raw_writel(dat, base + OFF_GPDAT);
+
+	gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
+
+	return 0;
+}
+
+static int s5pc1xx_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
+{
+	return S3C_IRQ_GPIO(chip->base + offset);
+}
+
+static int s5pc1xx_gpiolib_to_eint(struct gpio_chip *chip, unsigned int offset)
+{
+	int base;
+
+	base = chip->base - S5PC100_GPH0(0);
+	if (base == 0)
+		return IRQ_EINT(offset);
+	base = chip->base - S5PC100_GPH1(0);
+	if (base == 0)
+		return IRQ_EINT(8 + offset);
+	base = chip->base - S5PC100_GPH2(0);
+	if (base == 0)
+		return IRQ_EINT(16 + offset);
+	base = chip->base - S5PC100_GPH3(0);
+	if (base == 0)
+		return IRQ_EINT(24 + offset);
+	return -EINVAL;
+}
+
+static struct s3c_gpio_cfg gpio_cfg = {
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_cfg_eint = {
+	.cfg_eint	= 0xf,
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_cfg_noint = {
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
+	{
+		.base	= S5PC100_GPA0_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPA0(0),
+			.ngpio	= S5PC100_GPIO_A0_NR,
+			.label	= "GPA0",
+		},
+	}, {
+		.base	= S5PC100_GPA1_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPA1(0),
+			.ngpio	= S5PC100_GPIO_A1_NR,
+			.label	= "GPA1",
+		},
+	}, {
+		.base	= S5PC100_GPB_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPB(0),
+			.ngpio	= S5PC100_GPIO_B_NR,
+			.label	= "GPB",
+		},
+	}, {
+		.base	= S5PC100_GPC_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPC(0),
+			.ngpio	= S5PC100_GPIO_C_NR,
+			.label	= "GPC",
+		},
+	}, {
+		.base	= S5PC100_GPD_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPD(0),
+			.ngpio	= S5PC100_GPIO_D_NR,
+			.label	= "GPD",
+		},
+	}, {
+		.base	= S5PC100_GPE0_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPE0(0),
+			.ngpio	= S5PC100_GPIO_E0_NR,
+			.label	= "GPE0",
+		},
+	}, {
+		.base	= S5PC100_GPE1_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPE1(0),
+			.ngpio	= S5PC100_GPIO_E1_NR,
+			.label	= "GPE1",
+		},
+	}, {
+		.base	= S5PC100_GPF0_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPF0(0),
+			.ngpio	= S5PC100_GPIO_F0_NR,
+			.label	= "GPF0",
+		},
+	}, {
+		.base	= S5PC100_GPF1_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPF1(0),
+			.ngpio	= S5PC100_GPIO_F1_NR,
+			.label	= "GPF1",
+		},
+	}, {
+		.base	= S5PC100_GPF2_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPF2(0),
+			.ngpio	= S5PC100_GPIO_F2_NR,
+			.label	= "GPF2",
+		},
+	}, {
+		.base	= S5PC100_GPF3_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPF3(0),
+			.ngpio	= S5PC100_GPIO_F3_NR,
+			.label	= "GPF3",
+		},
+	}, {
+		.base	= S5PC100_GPG0_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPG0(0),
+			.ngpio	= S5PC100_GPIO_G0_NR,
+			.label	= "GPG0",
+		},
+	}, {
+		.base	= S5PC100_GPG1_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPG1(0),
+			.ngpio	= S5PC100_GPIO_G1_NR,
+			.label	= "GPG1",
+		},
+	}, {
+		.base	= S5PC100_GPG2_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPG2(0),
+			.ngpio	= S5PC100_GPIO_G2_NR,
+			.label	= "GPG2",
+		},
+	}, {
+		.base	= S5PC100_GPG3_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPG3(0),
+			.ngpio	= S5PC100_GPIO_G3_NR,
+			.label	= "GPG3",
+		},
+	}, {
+		.base	= S5PC100_GPH0_BASE,
+		.config	= &gpio_cfg_eint,
+		.chip	= {
+			.base	= S5PC100_GPH0(0),
+			.ngpio	= S5PC100_GPIO_H0_NR,
+			.label	= "GPH0",
+		},
+	}, {
+		.base	= S5PC100_GPH1_BASE,
+		.config	= &gpio_cfg_eint,
+		.chip	= {
+			.base	= S5PC100_GPH1(0),
+			.ngpio	= S5PC100_GPIO_H1_NR,
+			.label	= "GPH1",
+		},
+	}, {
+		.base	= S5PC100_GPH2_BASE,
+		.config	= &gpio_cfg_eint,
+		.chip	= {
+			.base	= S5PC100_GPH2(0),
+			.ngpio	= S5PC100_GPIO_H2_NR,
+			.label	= "GPH2",
+		},
+	}, {
+		.base	= S5PC100_GPH3_BASE,
+		.config	= &gpio_cfg_eint,
+		.chip	= {
+			.base	= S5PC100_GPH3(0),
+			.ngpio	= S5PC100_GPIO_H3_NR,
+			.label	= "GPH3",
+		},
+	}, {
+		.base	= S5PC100_GPI_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPI(0),
+			.ngpio	= S5PC100_GPIO_I_NR,
+			.label	= "GPI",
+		},
+	}, {
+		.base	= S5PC100_GPJ0_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPJ0(0),
+			.ngpio	= S5PC100_GPIO_J0_NR,
+			.label	= "GPJ0",
+		},
+	}, {
+		.base	= S5PC100_GPJ1_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPJ1(0),
+			.ngpio	= S5PC100_GPIO_J1_NR,
+			.label	= "GPJ1",
+		},
+	}, {
+		.base	= S5PC100_GPJ2_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPJ2(0),
+			.ngpio	= S5PC100_GPIO_J2_NR,
+			.label	= "GPJ2",
+		},
+	}, {
+		.base	= S5PC100_GPJ3_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPJ3(0),
+			.ngpio	= S5PC100_GPIO_J3_NR,
+			.label	= "GPJ3",
+		},
+	}, {
+		.base	= S5PC100_GPJ4_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPJ4(0),
+			.ngpio	= S5PC100_GPIO_J4_NR,
+			.label	= "GPJ4",
+		},
+	}, {
+		.base	= S5PC100_GPK0_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPK0(0),
+			.ngpio	= S5PC100_GPIO_K0_NR,
+			.label	= "GPK0",
+		},
+	}, {
+		.base	= S5PC100_GPK1_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPK1(0),
+			.ngpio	= S5PC100_GPIO_K1_NR,
+			.label	= "GPK1",
+		},
+	}, {
+		.base	= S5PC100_GPK2_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPK2(0),
+			.ngpio	= S5PC100_GPIO_K2_NR,
+			.label	= "GPK2",
+		},
+	}, {
+		.base	= S5PC100_GPK3_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPK3(0),
+			.ngpio	= S5PC100_GPIO_K3_NR,
+			.label	= "GPK3",
+		},
+	}, {
+		.base	= S5PC100_GPL0_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL0(0),
+			.ngpio	= S5PC100_GPIO_L0_NR,
+			.label	= "GPL0",
+		},
+	}, {
+		.base	= S5PC100_GPL1_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL1(0),
+			.ngpio	= S5PC100_GPIO_L1_NR,
+			.label	= "GPL1",
+		},
+	}, {
+		.base	= S5PC100_GPL2_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL2(0),
+			.ngpio	= S5PC100_GPIO_L2_NR,
+			.label	= "GPL2",
+		},
+	}, {
+		.base	= S5PC100_GPL3_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL3(0),
+			.ngpio	= S5PC100_GPIO_L3_NR,
+			.label	= "GPL3",
+		},
+	}, {
+		.base	= S5PC100_GPL4_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL4(0),
+			.ngpio	= S5PC100_GPIO_L4_NR,
+			.label	= "GPL4",
+		},
+	},
+};
+
+/* FIXME move from irq-gpio.c */
+extern struct irq_chip s5pc1xx_gpioint;
+extern void s5pc1xx_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc);
+
+static __init void s5pc1xx_gpiolib_link(struct s3c_gpio_chip *chip)
+{
+	chip->chip.direction_input = s5pc1xx_gpiolib_input;
+	chip->chip.direction_output = s5pc1xx_gpiolib_output;
+	chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
+
+	/* Interrupt */
+	if (chip->config == &gpio_cfg) {
+		int i, irq;
+
+		chip->chip.to_irq = s5pc1xx_gpiolib_to_irq;
+
+		for (i = 0;  i < chip->chip.ngpio; i++) {
+			irq = S3C_IRQ_GPIO_BASE + chip->chip.base + i;
+			set_irq_chip(irq, &s5pc1xx_gpioint);
+			set_irq_data(irq, &chip->chip);
+			set_irq_handler(irq, handle_level_irq);
+			set_irq_flags(irq, IRQF_VALID);
+		}
+	} else if (chip->config == &gpio_cfg_eint)
+		chip->chip.to_irq = s5pc1xx_gpiolib_to_eint;
+}
+
+static __init void s5pc1xx_gpiolib_add(struct s3c_gpio_chip *chips,
+				       int nr_chips,
+				       void (*fn)(struct s3c_gpio_chip *))
+{
+	for (; nr_chips > 0; nr_chips--, chips++) {
+		if (fn)
+			(fn)(chips);
+		s3c_gpiolib_add(chips);
+	}
+}
+
+static __init int s5pc1xx_gpiolib_init(void)
+{
+	struct s3c_gpio_chip *chips;
+	int nr_chips;
+
+		chips = s5pc100_gpio_chips;
+		nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
+
+	s5pc1xx_gpiolib_add(chips, nr_chips, s5pc1xx_gpiolib_link);
+	/* Interrupt */
+	set_irq_chained_handler(IRQ_GPIOINT, s5pc1xx_irq_gpioint_handler);
+
+	return 0;
+}
+core_initcall(s5pc1xx_gpiolib_init);
diff --git a/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h b/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h
new file mode 100644
index 0000000..c29ee25
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h
@@ -0,0 +1,33 @@
+/* linux/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg.h
+ *
+ * Copyright 2009 Samsung Electronic
+ *	InKi Dae <inki.dae@samsung.com>
+ *
+ * S5PC1XX Platform - GPIO pin configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* This file contains the necessary definitions to get the basic gpio
+ * pin configuration done such as setting a pin to input or output or
+ * changing the pull-{up,down} configurations.
+ */
+
+#ifndef __GPIO_CFG_S5PC1XX_H
+#define __GPIO_CFG_S5PC1XX_H __FILE__
+
+typedef unsigned int __bitwise__ s5p_gpio_drvstr_t;
+
+#define S5P_GPIO_DRVSTR_LV1	0x00
+#define S5P_GPIO_DRVSTR_LV2	0x01
+#define S5P_GPIO_DRVSTR_LV3	0x10
+#define S5P_GPIO_DRVSTR_LV4	0x11
+
+extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin, unsigned int off);
+
+extern int s5p_gpio_set_drvstr(unsigned int pin, unsigned int off,
+			s5p_gpio_drvstr_t drvstr);
+
+#endif /* __GPIO_CFG_S5PC1XX_H */
diff --git a/arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h b/arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h
new file mode 100644
index 0000000..33ad267
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h
@@ -0,0 +1,44 @@
+/* linux/arch/arm/plat-s5pc1xx/include/plat/gpio-eint.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *
+ * External Interrupt (GPH0 ~ GPH3) control register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S5PC1XX_WKUP_INT_CON0_7		(S5PC1XX_EINT_BASE + 0x0)
+#define S5PC1XX_WKUP_INT_CON8_15	(S5PC1XX_EINT_BASE + 0x4)
+#define S5PC1XX_WKUP_INT_CON16_23	(S5PC1XX_EINT_BASE + 0x8)
+#define S5PC1XX_WKUP_INT_CON24_31	(S5PC1XX_EINT_BASE + 0xC)
+#define S5PC1XX_WKUP_INT_CON(x)		(S5PC1XX_WKUP_INT_CON0_7 + (x * 0x4))
+
+#define S5PC1XX_WKUP_INT_FLTCON0_3	(S5PC1XX_EINT_BASE + 0x80)
+#define S5PC1XX_WKUP_INT_FLTCON4_7	(S5PC1XX_EINT_BASE + 0x84)
+#define S5PC1XX_WKUP_INT_FLTCON8_11	(S5PC1XX_EINT_BASE + 0x88)
+#define S5PC1XX_WKUP_INT_FLTCON12_15	(S5PC1XX_EINT_BASE + 0x8C)
+#define S5PC1XX_WKUP_INT_FLTCON16_19	(S5PC1XX_EINT_BASE + 0x90)
+#define S5PC1XX_WKUP_INT_FLTCON20_23	(S5PC1XX_EINT_BASE + 0x94)
+#define S5PC1XX_WKUP_INT_FLTCON24_27	(S5PC1XX_EINT_BASE + 0x98)
+#define S5PC1XX_WKUP_INT_FLTCON28_31	(S5PC1XX_EINT_BASE + 0x9C)
+#define S5PC1XX_WKUP_INT_FLTCON(x)	(S5PC1XX_WKUP_INT_FLTCON0_3 + (x * 0x4))
+
+#define S5PC1XX_WKUP_INT_MASK0_7	(S5PC1XX_EINT_BASE + 0x100)
+#define S5PC1XX_WKUP_INT_MASK8_15	(S5PC1XX_EINT_BASE + 0x104)
+#define S5PC1XX_WKUP_INT_MASK16_23	(S5PC1XX_EINT_BASE + 0x108)
+#define S5PC1XX_WKUP_INT_MASK24_31	(S5PC1XX_EINT_BASE + 0x10C)
+#define S5PC1XX_WKUP_INT_MASK(x)	(S5PC1XX_WKUP_INT_MASK0_7 + (x * 0x4))
+
+#define S5PC1XX_WKUP_INT_PEND0_7	(S5PC1XX_EINT_BASE + 0x140)
+#define S5PC1XX_WKUP_INT_PEND8_15	(S5PC1XX_EINT_BASE + 0x144)
+#define S5PC1XX_WKUP_INT_PEND16_23	(S5PC1XX_EINT_BASE + 0x148)
+#define S5PC1XX_WKUP_INT_PEND24_31	(S5PC1XX_EINT_BASE + 0x14C)
+#define S5PC1XX_WKUP_INT_PEND(x)	(S5PC1XX_WKUP_INT_PEND0_7 + (x * 0x4))
+
+#define S5PC1XX_WKUP_INT_LOWLEV		(0x00)
+#define S5PC1XX_WKUP_INT_HILEV		(0x01)
+#define S5PC1XX_WKUP_INT_FALLEDGE	(0x02)
+#define S5PC1XX_WKUP_INT_RISEEDGE	(0x03)
+#define S5PC1XX_WKUP_INT_BOTHEDGE	(0x04)
diff --git a/arch/arm/plat-s5pc1xx/include/plat/irqs.h b/arch/arm/plat-s5pc1xx/include/plat/irqs.h
index f07d8c3..ef87363 100644
--- a/arch/arm/plat-s5pc1xx/include/plat/irqs.h
+++ b/arch/arm/plat-s5pc1xx/include/plat/irqs.h
@@ -171,12 +171,21 @@
 #define IRQ_SDMIRQ		S5PC1XX_IRQ_VIC2(30)
 #define IRQ_SDMFIQ		S5PC1XX_IRQ_VIC2(31)
 
+/* External interrupt */
 #define S3C_IRQ_EINT_BASE	(IRQ_SDMFIQ + 1)
 
-#define S3C_EINT(x)		((x) + S3C_IRQ_EINT_BASE)
-#define IRQ_EINT(x)		S3C_EINT(x)
+#define S3C_EINT(x)		(S3C_IRQ_EINT_BASE + (x - 16))
+#define IRQ_EINT(x)		(x < 16 ? IRQ_EINT0 + x : S3C_EINT(x))
+#define IRQ_EINT_BIT(x)		(x < IRQ_EINT16_31 ? x - IRQ_EINT0 : x - S3C_EINT(0))
 
-#define NR_IRQS 		(IRQ_EINT(31)+1)
+/* GPIO interrupt */
+#define S3C_IRQ_GPIO_BASE	(IRQ_EINT(31) + 1)
+#define S3C_IRQ_GPIO(x)		(S3C_IRQ_GPIO_BASE + (x))
+
+/*
+ * Until MP04 Groups -> 40 (exactly 39) Groups * 8 ~= 320 GPIOs
+ */
+#define NR_IRQS			(S3C_IRQ_GPIO(320) + 1)
 
 #endif /* __ASM_PLAT_S5PC1XX_IRQS_H */
 
diff --git a/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h b/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
new file mode 100644
index 0000000..43c7bc8
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
@@ -0,0 +1,70 @@
+/* linux/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *      Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC1XX - GPIO register definitions
+ */
+
+#ifndef __ASM_PLAT_S5PC1XX_REGS_GPIO_H
+#define __ASM_PLAT_S5PC1XX_REGS_GPIO_H __FILE__
+
+#include <mach/map.h>
+
+/* S5PC100 */
+#define S5PC100_GPIO_BASE	S5PC1XX_VA_GPIO
+#define S5PC100_GPA0_BASE	(S5PC100_GPIO_BASE + 0x0000)
+#define S5PC100_GPA1_BASE	(S5PC100_GPIO_BASE + 0x0020)
+#define S5PC100_GPB_BASE	(S5PC100_GPIO_BASE + 0x0040)
+#define S5PC100_GPC_BASE	(S5PC100_GPIO_BASE + 0x0060)
+#define S5PC100_GPD_BASE	(S5PC100_GPIO_BASE + 0x0080)
+#define S5PC100_GPE0_BASE	(S5PC100_GPIO_BASE + 0x00A0)
+#define S5PC100_GPE1_BASE	(S5PC100_GPIO_BASE + 0x00C0)
+#define S5PC100_GPF0_BASE	(S5PC100_GPIO_BASE + 0x00E0)
+#define S5PC100_GPF1_BASE	(S5PC100_GPIO_BASE + 0x0100)
+#define S5PC100_GPF2_BASE	(S5PC100_GPIO_BASE + 0x0120)
+#define S5PC100_GPF3_BASE	(S5PC100_GPIO_BASE + 0x0140)
+#define S5PC100_GPG0_BASE	(S5PC100_GPIO_BASE + 0x0160)
+#define S5PC100_GPG1_BASE	(S5PC100_GPIO_BASE + 0x0180)
+#define S5PC100_GPG2_BASE	(S5PC100_GPIO_BASE + 0x01A0)
+#define S5PC100_GPG3_BASE	(S5PC100_GPIO_BASE + 0x01C0)
+#define S5PC100_GPH0_BASE	(S5PC100_GPIO_BASE + 0x0C00)
+#define S5PC100_GPH1_BASE	(S5PC100_GPIO_BASE + 0x0C20)
+#define S5PC100_GPH2_BASE	(S5PC100_GPIO_BASE + 0x0C40)
+#define S5PC100_GPH3_BASE	(S5PC100_GPIO_BASE + 0x0C60)
+#define S5PC100_GPI_BASE	(S5PC100_GPIO_BASE + 0x01E0)
+#define S5PC100_GPJ0_BASE	(S5PC100_GPIO_BASE + 0x0200)
+#define S5PC100_GPJ1_BASE	(S5PC100_GPIO_BASE + 0x0220)
+#define S5PC100_GPJ2_BASE	(S5PC100_GPIO_BASE + 0x0240)
+#define S5PC100_GPJ3_BASE	(S5PC100_GPIO_BASE + 0x0260)
+#define S5PC100_GPJ4_BASE	(S5PC100_GPIO_BASE + 0x0280)
+#define S5PC100_GPK0_BASE	(S5PC100_GPIO_BASE + 0x02A0)
+#define S5PC100_GPK1_BASE	(S5PC100_GPIO_BASE + 0x02C0)
+#define S5PC100_GPK2_BASE	(S5PC100_GPIO_BASE + 0x02E0)
+#define S5PC100_GPK3_BASE	(S5PC100_GPIO_BASE + 0x0300)
+#define S5PC100_GPL0_BASE	(S5PC100_GPIO_BASE + 0x0320)
+#define S5PC100_GPL1_BASE	(S5PC100_GPIO_BASE + 0x0340)
+#define S5PC100_GPL2_BASE	(S5PC100_GPIO_BASE + 0x0360)
+#define S5PC100_GPL3_BASE	(S5PC100_GPIO_BASE + 0x0380)
+#define S5PC100_GPL4_BASE	(S5PC100_GPIO_BASE + 0x03A0)
+#define S5PC100_EINT_BASE	(S5PC100_GPIO_BASE + 0x0E00)
+
+#define S5PC100_UHOST		(S5PC100_GPIO_BASE + 0x0B68)
+#define S5PC100_PDNEN		(S5PC100_GPIO_BASE + 0x0F80)
+
+/* PDNEN */
+#define S5PC100_PDNEN_CFG_PDNEN	(1 << 1)
+#define S5PC100_PDNEN_CFG_AUTO	(0 << 1)
+#define S5PC100_PDNEN_POWERDOWN	(1 << 0)
+#define S5PC100_PDNEN_NORMAL	(0 << 0)
+
+/* Common part */
+/* External interrupt base is same at both s5pc100 and s5pc110 */
+#define S5PC1XX_EINT_BASE	(S5PC100_EINT_BASE)
+
+#define S5PC100_GPx_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
+#define S5PC100_GPx_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
+#define S5PC100_GPx_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
+
+#endif /* __ASM_PLAT_S5PC1XX_REGS_GPIO_H */
+
diff --git a/arch/arm/plat-s5pc1xx/irq-eint.c b/arch/arm/plat-s5pc1xx/irq-eint.c
new file mode 100644
index 0000000..34f9443
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/irq-eint.c
@@ -0,0 +1,281 @@
+/*
+ * linux/arch/arm/plat-s5pc1xx/irq-eint.c
+ *
+ *  Copyright 2009 Samsung Electronics Co.
+ *  Byungho Min <bhmin@samsung.com>
+ *  Kyungin Park <kyungmin.park@samsung.com>
+ *
+ * Based on plat-s3c64xx/irq-eint.c
+ *
+ * S5PC1XX - Interrupt handling for IRQ_EINT(x)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/pm.h>
+
+#include <asm/hardware/vic.h>
+
+#include <mach/map.h>
+#include <mach/gpio.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-ext.h>
+#include <plat/pm.h>
+#include <plat/regs-gpio.h>
+#include <plat/regs-irqtype.h>
+
+/*
+ * bank is a group of external interrupt
+ * bank0 means EINT0 ... EINT7
+ * bank1 means EINT8 ... EINT15
+ * bank2 means EINT16 ... EINT23
+ * bank3 means EINT24 ... EINT31
+ */
+
+static inline int s3c_get_eint(unsigned int irq)
+{
+	int real;
+
+	if (irq < IRQ_EINT16_31)
+		real = (irq - IRQ_EINT0);
+	else
+		real = (irq - S3C_IRQ_EINT_BASE) + IRQ_EINT16_31 - IRQ_EINT0;
+
+	return real;
+}
+
+static inline int s3c_get_bank(unsigned int irq)
+{
+	return s3c_get_eint(irq) >> 3;
+}
+
+static inline int s3c_eint_to_bit(unsigned int irq)
+{
+	int real, bit;
+
+	real = s3c_get_eint(irq);
+	bit = 1 << (real & (8 - 1));
+
+	return bit;
+}
+
+static inline void s3c_irq_eint_mask(unsigned int irq)
+{
+	u32 mask;
+	u32 bank = s3c_get_bank(irq);
+
+	mask = __raw_readl(S5PC1XX_WKUP_INT_MASK(bank));
+	mask |= s3c_eint_to_bit(irq);
+	__raw_writel(mask, S5PC1XX_WKUP_INT_MASK(bank));
+}
+
+static void s3c_irq_eint_unmask(unsigned int irq)
+{
+	u32 mask;
+	u32 bank = s3c_get_bank(irq);
+
+	mask = __raw_readl(S5PC1XX_WKUP_INT_MASK(bank));
+	mask &= ~(s3c_eint_to_bit(irq));
+	__raw_writel(mask, S5PC1XX_WKUP_INT_MASK(bank));
+}
+
+static inline void s3c_irq_eint_ack(unsigned int irq)
+{
+	u32 bank = s3c_get_bank(irq);
+
+	__raw_writel(s3c_eint_to_bit(irq), S5PC1XX_WKUP_INT_PEND(bank));
+}
+
+static void s3c_irq_eint_maskack(unsigned int irq)
+{
+	/* compiler should in-line these */
+	s3c_irq_eint_mask(irq);
+	s3c_irq_eint_ack(irq);
+}
+
+static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
+{
+	u32 bank = s3c_get_bank(irq);
+	int real = s3c_get_eint(irq);
+	int gpio, shift, sfn;
+	u32 ctrl, con = 0;
+
+	switch (type) {
+	case IRQ_TYPE_NONE:
+		printk(KERN_WARNING "No edge setting!\n");
+		break;
+
+	case IRQ_TYPE_EDGE_RISING:
+		con = S5PC1XX_WKUP_INT_RISEEDGE;
+		break;
+
+	case IRQ_TYPE_EDGE_FALLING:
+		con = S5PC1XX_WKUP_INT_FALLEDGE;
+		break;
+
+	case IRQ_TYPE_EDGE_BOTH:
+		con = S5PC1XX_WKUP_INT_BOTHEDGE;
+		break;
+
+	case IRQ_TYPE_LEVEL_LOW:
+		con = S5PC1XX_WKUP_INT_LOWLEV;
+		break;
+
+	case IRQ_TYPE_LEVEL_HIGH:
+		con = S5PC1XX_WKUP_INT_HILEV;
+		break;
+
+	default:
+		printk(KERN_ERR "No such irq type %d", type);
+		return -EINVAL;
+	}
+
+	gpio = real & (8 - 1);
+	shift = gpio << 2;
+
+	ctrl = __raw_readl(S5PC1XX_WKUP_INT_CON(bank));
+	ctrl &= ~(0x7 << shift);
+	ctrl |= con << shift;
+	__raw_writel(ctrl, S5PC1XX_WKUP_INT_CON(bank));
+
+	switch (real) {
+	case 0 ... 7:
+			gpio = S5PC100_GPH0(gpio);
+		break;
+	case 8 ... 15:
+			gpio = S5PC100_GPH1(gpio);
+		break;
+	case 16 ... 23:
+			gpio = S5PC100_GPH2(gpio);
+		break;
+	case 24 ... 31:
+			gpio = S5PC100_GPH3(gpio);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	sfn = S3C_GPIO_SFN(0x2);
+	s3c_gpio_cfgpin(gpio, sfn);
+
+	return 0;
+}
+
+static struct irq_chip s3c_irq_eint = {
+	.name		= "EINT",
+	.mask		= s3c_irq_eint_mask,
+	.unmask		= s3c_irq_eint_unmask,
+	.mask_ack	= s3c_irq_eint_maskack,
+	.ack		= s3c_irq_eint_ack,
+	.set_type	= s3c_irq_eint_set_type,
+	.set_wake	= s3c_irqext_wake,
+};
+
+/* s3c_irq_demux_eint
+ *
+ * This function demuxes the IRQ from external interrupts,
+ * from IRQ_EINT(16) to IRQ_EINT(31). It is designed to be inlined into
+ * the specific handlers s3c_irq_demux_eintX_Y.
+ */
+static inline void s3c_irq_demux_eint(unsigned int start, unsigned int end)
+{
+	u32 status = __raw_readl(S5PC1XX_WKUP_INT_PEND((start >> 3)));
+	u32 mask = __raw_readl(S5PC1XX_WKUP_INT_MASK((start >> 3)));
+	unsigned int irq;
+
+	status &= ~mask;
+	status &= (1 << (end - start + 1)) - 1;
+
+	for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
+		if (status & 1)
+			generic_handle_irq(irq);
+
+		status >>= 1;
+	}
+}
+
+static void s3c_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
+{
+	s3c_irq_demux_eint(16, 23);
+	s3c_irq_demux_eint(24, 31);
+}
+
+/*
+ * Handle EINT0 ... EINT15 at VIC directly
+ */
+static void s3c_irq_vic_eint_mask(unsigned int irq)
+{
+	void __iomem *base = get_irq_chip_data(irq);
+	unsigned int real;
+
+	s3c_irq_eint_mask(irq);
+	real = s3c_get_eint(irq);
+	writel(1 << real, base + VIC_INT_ENABLE_CLEAR);
+}
+
+static void s3c_irq_vic_eint_unmask(unsigned int irq)
+{
+	void __iomem *base = get_irq_chip_data(irq);
+	unsigned int real;
+
+	s3c_irq_eint_unmask(irq);
+	real = s3c_get_eint(irq);
+	writel(1 << real, base + VIC_INT_ENABLE);
+}
+
+static inline void s3c_irq_vic_eint_ack(unsigned int irq)
+{
+	u32 bit;
+	u32 bank = s3c_get_bank(irq);
+
+	bit = s3c_eint_to_bit(irq);
+	__raw_writel(bit, S5PC1XX_WKUP_INT_PEND(bank));
+}
+
+static void s3c_irq_vic_eint_maskack(unsigned int irq)
+{
+	/* compiler should in-line these */
+	s3c_irq_vic_eint_mask(irq);
+	s3c_irq_vic_eint_ack(irq);
+}
+
+static struct irq_chip s3c_irq_vic_eint = {
+	.name		= "EINT",
+	.mask		= s3c_irq_vic_eint_mask,
+	.unmask		= s3c_irq_vic_eint_unmask,
+	.mask_ack	= s3c_irq_vic_eint_maskack,
+	.ack		= s3c_irq_vic_eint_ack,
+	.set_type	= s3c_irq_eint_set_type,
+	.set_wake	= s3c_irqext_wake,
+};
+
+static int __init s5pc1xx_init_irq_eint(void)
+{
+	int irq;
+
+	for (irq = IRQ_EINT0; irq <= IRQ_EINT15; irq++) {
+		set_irq_chip(irq, &s3c_irq_vic_eint);
+		set_irq_handler(irq, handle_level_irq);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+	for (irq = IRQ_EINT(16); irq <= IRQ_EINT(31); irq++) {
+		set_irq_chip(irq, &s3c_irq_eint);
+		set_irq_handler(irq, handle_level_irq);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+	set_irq_chained_handler(IRQ_EINT16_31, s3c_irq_demux_eint16_31);
+
+	return 0;
+}
+
+arch_initcall(s5pc1xx_init_irq_eint);
diff --git a/arch/arm/plat-s5pc1xx/irq-gpio.c b/arch/arm/plat-s5pc1xx/irq-gpio.c
new file mode 100644
index 0000000..843a88e
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/irq-gpio.c
@@ -0,0 +1,266 @@
+/*
+ * arch/arm/plat-s5pc1xx/irq-gpio.c
+ *
+ * Copyright (C) 2009 Samsung Electronics
+ *
+ * S5PC1XX - Interrupt handling for IRQ_GPIO${group}(x)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
+
+#define S5PC1XX_GPIOREG(x)		(S5PC1XX_VA_GPIO + (x))
+
+#define CON_OFFSET			0x700
+#define MASK_OFFSET			0x900
+#define PEND_OFFSET			0xA00
+#define CON_OFFSET_2			0xE00
+#define MASK_OFFSET_2			0xF00
+#define PEND_OFFSET_2			0xF40
+
+#define GPIOINT_LEVEL_LOW		0x0
+#define GPIOINT_LEVEL_HIGH		0x1
+#define GPIOINT_EDGE_FALLING		0x2
+#define GPIOINT_EDGE_RISING		0x3
+#define GPIOINT_EDGE_BOTH		0x4
+
+static int group_to_con_offset(int group)
+{
+	return group << 2;
+}
+
+static int group_to_mask_offset(int group)
+{
+	return group << 2;
+}
+
+static int group_to_pend_offset(int group)
+{
+	return group << 2;
+}
+
+static int s5pc1xx_get_start(unsigned int group)
+{
+	switch (group) {
+	case 0: return S5PC100_GPIO_A0_START;
+	case 1: return S5PC100_GPIO_A1_START;
+	case 2: return S5PC100_GPIO_B_START;
+	case 3: return S5PC100_GPIO_C_START;
+	case 4: return S5PC100_GPIO_D_START;
+	case 5: return S5PC100_GPIO_E0_START;
+	case 6: return S5PC100_GPIO_E1_START;
+	case 7: return S5PC100_GPIO_F0_START;
+	case 8: return S5PC100_GPIO_F1_START;
+	case 9: return S5PC100_GPIO_F2_START;
+	case 10: return S5PC100_GPIO_F3_START;
+	case 11: return S5PC100_GPIO_G0_START;
+	case 12: return S5PC100_GPIO_G1_START;
+	case 13: return S5PC100_GPIO_G2_START;
+	case 14: return S5PC100_GPIO_G3_START;
+	case 15: return S5PC100_GPIO_I_START;
+	case 16: return S5PC100_GPIO_J0_START;
+	case 17: return S5PC100_GPIO_J1_START;
+	case 18: return S5PC100_GPIO_J2_START;
+	case 19: return S5PC100_GPIO_J3_START;
+	case 20: return S5PC100_GPIO_J4_START;
+	default:
+		BUG();
+	}
+
+	return -EINVAL;
+}
+
+static int s5pc1xx_get_group(unsigned int irq)
+{
+	irq -= S3C_IRQ_GPIO(0);
+
+	switch (irq) {
+	case S5PC100_GPIO_A0_START ... S5PC100_GPIO_A1_START - 1:
+		return 0;
+	case S5PC100_GPIO_A1_START ... S5PC100_GPIO_B_START - 1:
+		return 1;
+	case S5PC100_GPIO_B_START ... S5PC100_GPIO_C_START - 1:
+		return 2;
+	case S5PC100_GPIO_C_START ... S5PC100_GPIO_D_START - 1:
+		return 3;
+	case S5PC100_GPIO_D_START ... S5PC100_GPIO_E0_START - 1:
+		return 4;
+	case S5PC100_GPIO_E0_START ... S5PC100_GPIO_E1_START - 1:
+		return 5;
+	case S5PC100_GPIO_E1_START ... S5PC100_GPIO_F0_START - 1:
+		return 6;
+	case S5PC100_GPIO_F0_START ... S5PC100_GPIO_F1_START - 1:
+		return 7;
+	case S5PC100_GPIO_F1_START ... S5PC100_GPIO_F2_START - 1:
+		return 8;
+	case S5PC100_GPIO_F2_START ... S5PC100_GPIO_F3_START - 1:
+		return 9;
+	case S5PC100_GPIO_F3_START ... S5PC100_GPIO_G0_START - 1:
+		return 10;
+	case S5PC100_GPIO_G0_START ... S5PC100_GPIO_G1_START - 1:
+		return 11;
+	case S5PC100_GPIO_G1_START ... S5PC100_GPIO_G2_START - 1:
+		return 12;
+	case S5PC100_GPIO_G2_START ... S5PC100_GPIO_G3_START - 1:
+		return 13;
+	case S5PC100_GPIO_G3_START ... S5PC100_GPIO_H0_START - 1:
+		return 14;
+	case S5PC100_GPIO_I_START ... S5PC100_GPIO_J0_START - 1:
+		return 15;
+	case S5PC100_GPIO_J0_START ... S5PC100_GPIO_J1_START - 1:
+		return 16;
+	case S5PC100_GPIO_J1_START ... S5PC100_GPIO_J2_START - 1:
+		return 17;
+	case S5PC100_GPIO_J2_START ... S5PC100_GPIO_J3_START - 1:
+		return 18;
+	case S5PC100_GPIO_J3_START ... S5PC100_GPIO_J4_START - 1:
+		return 19;
+	case S5PC100_GPIO_J4_START ... S5PC100_GPIO_K0_START - 1:
+		return 20;
+	default:
+		BUG();
+	}
+
+	return -EINVAL;
+}
+
+static int s5pc1xx_get_offset(unsigned int irq)
+{
+	struct gpio_chip *chip = get_irq_data(irq);
+	return irq - S3C_IRQ_GPIO(chip->base);
+}
+
+static void s5pc1xx_gpioint_ack(unsigned int irq)
+{
+	int group, offset, pend_offset;
+	unsigned int value;
+
+	group = s5pc1xx_get_group(irq);
+	offset = s5pc1xx_get_offset(irq);
+	pend_offset = group_to_pend_offset(group);
+
+	value = __raw_readl(S5PC1XX_GPIOREG(PEND_OFFSET) + pend_offset);
+	value |= 1 << offset;
+	__raw_writel(value, S5PC1XX_GPIOREG(PEND_OFFSET) + pend_offset);
+}
+
+static void s5pc1xx_gpioint_mask(unsigned int irq)
+{
+	int group, offset, mask_offset;
+	unsigned int value;
+
+	group = s5pc1xx_get_group(irq);
+	offset = s5pc1xx_get_offset(irq);
+	mask_offset = group_to_mask_offset(group);
+
+	value = __raw_readl(S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
+	value |= 1 << offset;
+	__raw_writel(value, S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
+}
+
+static void s5pc1xx_gpioint_unmask(unsigned int irq)
+{
+	int group, offset, mask_offset;
+	unsigned int value;
+
+	group = s5pc1xx_get_group(irq);
+	offset = s5pc1xx_get_offset(irq);
+	mask_offset = group_to_mask_offset(group);
+
+	value = __raw_readl(S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
+	value &= ~(1 << offset);
+	__raw_writel(value, S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
+}
+
+static void s5pc1xx_gpioint_mask_ack(unsigned int irq)
+{
+	s5pc1xx_gpioint_mask(irq);
+	s5pc1xx_gpioint_ack(irq);
+}
+
+static int s5pc1xx_gpioint_set_type(unsigned int irq, unsigned int type)
+{
+	int group, offset, con_offset;
+	unsigned int value;
+
+	group = s5pc1xx_get_group(irq);
+	offset = s5pc1xx_get_offset(irq);
+	con_offset = group_to_con_offset(group);
+
+	switch (type) {
+	case IRQ_TYPE_NONE:
+		printk(KERN_WARNING "No irq type\n");
+		return -EINVAL;
+	case IRQ_TYPE_EDGE_RISING:
+		type = GPIOINT_EDGE_RISING;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		type = GPIOINT_EDGE_FALLING;
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		type = GPIOINT_EDGE_BOTH;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		type = GPIOINT_LEVEL_HIGH;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		type = GPIOINT_LEVEL_LOW;
+		break;
+	default:
+		BUG();
+	}
+
+
+	value = __raw_readl(S5PC1XX_GPIOREG(CON_OFFSET) + con_offset);
+	value &= ~(0xf << (offset * 0x4));
+	value |= (type << (offset * 0x4));
+	__raw_writel(value, S5PC1XX_GPIOREG(CON_OFFSET) + con_offset);
+
+	return 0;
+}
+
+struct irq_chip s5pc1xx_gpioint = {
+	.name		= "GPIO",
+	.ack		= s5pc1xx_gpioint_ack,
+	.mask		= s5pc1xx_gpioint_mask,
+	.mask_ack	= s5pc1xx_gpioint_mask_ack,
+	.unmask		= s5pc1xx_gpioint_unmask,
+	.set_type	= s5pc1xx_gpioint_set_type,
+};
+
+void s5pc1xx_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc)
+{
+	int group, offset, pend_offset, mask_offset;
+	int real_irq, group_end;
+	unsigned int pend, mask;
+
+	group_end = 21;
+
+	for (group = 0; group < group_end; group++) {
+		pend_offset = group_to_pend_offset(group);
+		pend = __raw_readl(S5PC1XX_GPIOREG(PEND_OFFSET) + pend_offset);
+		if (!pend)
+			continue;
+
+		mask_offset = group_to_mask_offset(group);
+		mask = __raw_readl(S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
+		pend &= ~mask;
+
+		for (offset = 0; offset < 8; offset++) {
+			if (pend & (1 << offset)) {
+				real_irq = s5pc1xx_get_start(group) + offset;
+				generic_handle_irq(S3C_IRQ_GPIO(real_irq));
+			}
+		}
+	}
+}
diff --git a/arch/arm/plat-s5pc1xx/irq.c b/arch/arm/plat-s5pc1xx/irq.c
index 80d6dd9..e44fd04 100644
--- a/arch/arm/plat-s5pc1xx/irq.c
+++ b/arch/arm/plat-s5pc1xx/irq.c
@@ -79,7 +79,7 @@ static void s3c_irq_timer_ack(unsigned int irq)
 {
 	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
 
-	reg &= 0x1f;
+	reg &= 0x1f;  /* mask out pending interrupts */
 	reg |= (1 << 5) << (irq - IRQ_TIMER0);
 	__raw_writel(reg, S3C64XX_TINT_CSTAT);
 }
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 07/17] ARM: S5PC1xx: add gpiolib and external/gpio interrupt support
@ 2009-10-13  8:11               ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

Add support for gpiolib calls. This is based on the gpiolib implementation
from plat-s3c64xx tree.
Add support for external interrupts for GPIO H banks.
Add support for GPIO interrupts for all banks.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/plat-s3c/Kconfig                          |    6 +
 arch/arm/plat-s3c/include/plat/gpio-cfg.h          |    1 +
 arch/arm/plat-s5pc1xx/Kconfig                      |    3 +
 arch/arm/plat-s5pc1xx/Makefile                     |    3 +-
 arch/arm/plat-s5pc1xx/cpu.c                        |    5 +
 arch/arm/plat-s5pc1xx/gpio-config.c                |   61 +++
 arch/arm/plat-s5pc1xx/gpiolib.c                    |  503 ++++++++++++++++++++
 .../plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h   |   33 ++
 arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h      |   44 ++
 arch/arm/plat-s5pc1xx/include/plat/irqs.h          |   15 +-
 arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h     |   70 +++
 arch/arm/plat-s5pc1xx/irq-eint.c                   |  281 +++++++++++
 arch/arm/plat-s5pc1xx/irq-gpio.c                   |  266 +++++++++++
 arch/arm/plat-s5pc1xx/irq.c                        |    2 +-
 14 files changed, 1288 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/plat-s5pc1xx/gpio-config.c
 create mode 100644 arch/arm/plat-s5pc1xx/gpiolib.c
 create mode 100644 arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h
 create mode 100644 arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h
 create mode 100644 arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
 create mode 100644 arch/arm/plat-s5pc1xx/irq-eint.c
 create mode 100644 arch/arm/plat-s5pc1xx/irq-gpio.c

diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig
index 8931c5f..f155a84 100644
--- a/arch/arm/plat-s3c/Kconfig
+++ b/arch/arm/plat-s3c/Kconfig
@@ -159,6 +159,12 @@ config S3C_GPIO_CFG_S3C64XX
 	  Internal configuration to enable S3C64XX style GPIO configuration
 	  functions.
 
+config S5P_GPIO_CFG_S5PC1XX
+	bool
+	help
+	  Internal configuration to enable S5PC1XX style GPIO configuration
+	  functions.
+
 # DMA
 
 config S3C_DMA
diff --git a/arch/arm/plat-s3c/include/plat/gpio-cfg.h b/arch/arm/plat-s3c/include/plat/gpio-cfg.h
index 29cd6a8..7e73429 100644
--- a/arch/arm/plat-s3c/include/plat/gpio-cfg.h
+++ b/arch/arm/plat-s3c/include/plat/gpio-cfg.h
@@ -62,6 +62,7 @@ struct s3c_gpio_cfg {
 #define S3C_GPIO_INPUT	(S3C_GPIO_SPECIAL(0))
 #define S3C_GPIO_OUTPUT	(S3C_GPIO_SPECIAL(1))
 #define S3C_GPIO_SFN(x)	(S3C_GPIO_SPECIAL(x))
+#define S3C_GPIO_IRQ	(S3C_GPIO_SPECIAL(0xf))
 
 #define s3c_gpio_is_cfg_special(_cfg) \
 	(((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK)
diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig
index a8a711c..86edd27 100644
--- a/arch/arm/plat-s5pc1xx/Kconfig
+++ b/arch/arm/plat-s5pc1xx/Kconfig
@@ -15,6 +15,9 @@ config PLAT_S5PC1XX
 	select ARCH_REQUIRE_GPIOLIB
 	select S3C_GPIO_TRACK
 	select S3C_GPIO_PULL_UPDOWN
+	select S3C_GPIO_CFG_S3C24XX
+	select S3C_GPIO_CFG_S3C64XX
+	select S5P_GPIO_CFG_S5PC1XX
 	help
 	  Base platform code for any Samsung S5PC1XX device
 
diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile
index ebbf364..f126951 100644
--- a/arch/arm/plat-s5pc1xx/Makefile
+++ b/arch/arm/plat-s5pc1xx/Makefile
@@ -13,8 +13,9 @@ obj-				:=
 
 obj-y				+= dev-uart.o
 obj-y				+= cpu.o
-obj-y				+= irq.o
+obj-y				+= irq.o irq-gpio.o irq-eint.o
 obj-y				+= clock.o
+obj-y				+= gpiolib.o
 
 # CPU support
 
diff --git a/arch/arm/plat-s5pc1xx/cpu.c b/arch/arm/plat-s5pc1xx/cpu.c
index e8f3472..02baeaa 100644
--- a/arch/arm/plat-s5pc1xx/cpu.c
+++ b/arch/arm/plat-s5pc1xx/cpu.c
@@ -60,6 +60,11 @@ static struct map_desc s5pc1xx_iodesc[] __initdata = {
 		.length		= SZ_4K,
 		.type		= MT_DEVICE,
 	}, {
+		.virtual	= (unsigned long)S5PC1XX_VA_GPIO,
+		.pfn		= __phys_to_pfn(S5PC100_PA_GPIO),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
 		.virtual	= (unsigned long)S5PC1XX_VA_CHIPID,
 		.pfn		= __phys_to_pfn(S5PC1XX_PA_CHIPID),
 		.length		= SZ_16,
diff --git a/arch/arm/plat-s5pc1xx/gpio-config.c b/arch/arm/plat-s5pc1xx/gpio-config.c
new file mode 100644
index 0000000..b911475
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/gpio-config.c
@@ -0,0 +1,61 @@
+/* linux/arch/arm/plat-s5pc1xx/gpio-config.c
+ *
+ * Copyright 2009 Samsung Electronics
+ *	InKi Dae  <inki.dae@samsung.com>
+ *
+ * S5PC110 GPIO Configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+
+#include <mach/gpio-core.h>
+#include <plat/gpio-cfg-s5pc1xx.h>
+
+s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin, unsigned int off)
+{
+	struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+	void __iomem *reg;
+	int shift = off * 2;
+	u32 drvstr;
+
+	if (!chip)
+		return -EINVAL;
+
+	reg = chip->base + 0x0C;
+
+	drvstr = __raw_readl(reg);
+	drvstr = 0xffff & (0x3 << shift);
+	drvstr = drvstr >> shift;
+
+	return (__force s5p_gpio_drvstr_t)drvstr;
+}
+EXPORT_SYMBOL(s5p_gpio_get_drvstr);
+
+int s5p_gpio_set_drvstr(unsigned int pin, unsigned int off,
+			s5p_gpio_drvstr_t drvstr)
+{
+	struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+	void __iomem *reg;
+	int shift = off * 2;
+	u32 tmp;
+
+	if (!chip)
+		return -EINVAL;
+
+	reg = chip->base + 0x0C;
+
+	tmp = __raw_readl(reg);
+	tmp |= drvstr << shift;
+
+	__raw_writel(tmp, reg);
+
+	return 0;
+}
+EXPORT_SYMBOL(s5p_gpio_set_drvstr);
diff --git a/arch/arm/plat-s5pc1xx/gpiolib.c b/arch/arm/plat-s5pc1xx/gpiolib.c
new file mode 100644
index 0000000..9da8efc
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/gpiolib.c
@@ -0,0 +1,503 @@
+/*
+ * arch/arm/plat-s5pc1xx/gpiolib.c
+ *
+ *  Copyright 2009 Samsung Electronics Co
+ *  Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * S5PC1XX - GPIOlib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <mach/gpio.h>
+#include <mach/gpio-core.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <plat/regs-gpio.h>
+
+/* S5PC100 GPIO bank summary:
+ *
+ * Bank	GPIOs	Style	INT Type
+ * A0	8	4Bit	GPIO_INT0
+ * A1	5	4Bit	GPIO_INT1
+ * B	8	4Bit	GPIO_INT2
+ * C	5	4Bit	GPIO_INT3
+ * D	7	4Bit	GPIO_INT4
+ * E0	8	4Bit	GPIO_INT5
+ * E1	6	4Bit	GPIO_INT6
+ * F0	8	4Bit	GPIO_INT7
+ * F1	8	4Bit	GPIO_INT8
+ * F2	8	4Bit	GPIO_INT9
+ * F3	4	4Bit	GPIO_INT10
+ * G0	8	4Bit	GPIO_INT11
+ * G1	3	4Bit	GPIO_INT12
+ * G2	7	4Bit	GPIO_INT13
+ * G3	7	4Bit	GPIO_INT14
+ * H0	8	4Bit	WKUP_INT
+ * H1	8	4Bit	WKUP_INT
+ * H2	8	4Bit	WKUP_INT
+ * H3	8	4Bit	WKUP_INT
+ * I	8	4Bit	GPIO_INT15
+ * J0	8	4Bit	GPIO_INT16
+ * J1	5	4Bit	GPIO_INT17
+ * J2	8	4Bit	GPIO_INT18
+ * J3	8	4Bit	GPIO_INT19
+ * J4	4	4Bit	GPIO_INT20
+ * K0	8	4Bit	None
+ * K1	6	4Bit	None
+ * K2	8	4Bit	None
+ * K3	8	4Bit	None
+ * L0	8	4Bit	None
+ * L1	8	4Bit	None
+ * L2	8	4Bit	None
+ * L3	8	4Bit	None
+ */
+
+#define OFF_GPCON	(0x00)
+#define OFF_GPDAT	(0x04)
+
+#define con_4bit_shift(__off) ((__off) * 4)
+
+#if 1
+#define gpio_dbg(x...) do { } while (0)
+#else
+#define gpio_dbg(x...) printk(KERN_DEBUG x)
+#endif
+
+/* The s5pc1xx_gpiolib routines are to control the gpio banks where
+ * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
+ * following example:
+ *
+ * base + 0x00: Control register, 4 bits per gpio
+ *	        gpio n: 4 bits starting at (4*n)
+ *		0000 = input, 0001 = output, others mean special-function
+ * base + 0x04: Data register, 1 bit per gpio
+ *		bit n: data bit n
+ *
+ * Note, since the data register is one bit per gpio and is at base + 0x4
+ * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of
+ * the output.
+ */
+
+static int s5pc1xx_gpiolib_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+	void __iomem *base = ourchip->base;
+	unsigned long con;
+
+	con = __raw_readl(base + OFF_GPCON);
+	con &= ~(0xf << con_4bit_shift(offset));
+	__raw_writel(con, base + OFF_GPCON);
+
+	gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
+
+	return 0;
+}
+
+static int s5pc1xx_gpiolib_output(struct gpio_chip *chip,
+				       unsigned offset, int value)
+{
+	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+	void __iomem *base = ourchip->base;
+	unsigned long con;
+	unsigned long dat;
+
+	con = __raw_readl(base + OFF_GPCON);
+	con &= ~(0xf << con_4bit_shift(offset));
+	con |= 0x1 << con_4bit_shift(offset);
+
+	dat = __raw_readl(base + OFF_GPDAT);
+	if (value)
+		dat |= 1 << offset;
+	else
+		dat &= ~(1 << offset);
+
+	__raw_writel(dat, base + OFF_GPDAT);
+	__raw_writel(con, base + OFF_GPCON);
+	__raw_writel(dat, base + OFF_GPDAT);
+
+	gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
+
+	return 0;
+}
+
+static int s5pc1xx_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
+{
+	return S3C_IRQ_GPIO(chip->base + offset);
+}
+
+static int s5pc1xx_gpiolib_to_eint(struct gpio_chip *chip, unsigned int offset)
+{
+	int base;
+
+	base = chip->base - S5PC100_GPH0(0);
+	if (base == 0)
+		return IRQ_EINT(offset);
+	base = chip->base - S5PC100_GPH1(0);
+	if (base == 0)
+		return IRQ_EINT(8 + offset);
+	base = chip->base - S5PC100_GPH2(0);
+	if (base == 0)
+		return IRQ_EINT(16 + offset);
+	base = chip->base - S5PC100_GPH3(0);
+	if (base == 0)
+		return IRQ_EINT(24 + offset);
+	return -EINVAL;
+}
+
+static struct s3c_gpio_cfg gpio_cfg = {
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_cfg_eint = {
+	.cfg_eint	= 0xf,
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_cfg_noint = {
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
+	{
+		.base	= S5PC100_GPA0_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPA0(0),
+			.ngpio	= S5PC100_GPIO_A0_NR,
+			.label	= "GPA0",
+		},
+	}, {
+		.base	= S5PC100_GPA1_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPA1(0),
+			.ngpio	= S5PC100_GPIO_A1_NR,
+			.label	= "GPA1",
+		},
+	}, {
+		.base	= S5PC100_GPB_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPB(0),
+			.ngpio	= S5PC100_GPIO_B_NR,
+			.label	= "GPB",
+		},
+	}, {
+		.base	= S5PC100_GPC_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPC(0),
+			.ngpio	= S5PC100_GPIO_C_NR,
+			.label	= "GPC",
+		},
+	}, {
+		.base	= S5PC100_GPD_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPD(0),
+			.ngpio	= S5PC100_GPIO_D_NR,
+			.label	= "GPD",
+		},
+	}, {
+		.base	= S5PC100_GPE0_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPE0(0),
+			.ngpio	= S5PC100_GPIO_E0_NR,
+			.label	= "GPE0",
+		},
+	}, {
+		.base	= S5PC100_GPE1_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPE1(0),
+			.ngpio	= S5PC100_GPIO_E1_NR,
+			.label	= "GPE1",
+		},
+	}, {
+		.base	= S5PC100_GPF0_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPF0(0),
+			.ngpio	= S5PC100_GPIO_F0_NR,
+			.label	= "GPF0",
+		},
+	}, {
+		.base	= S5PC100_GPF1_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPF1(0),
+			.ngpio	= S5PC100_GPIO_F1_NR,
+			.label	= "GPF1",
+		},
+	}, {
+		.base	= S5PC100_GPF2_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPF2(0),
+			.ngpio	= S5PC100_GPIO_F2_NR,
+			.label	= "GPF2",
+		},
+	}, {
+		.base	= S5PC100_GPF3_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPF3(0),
+			.ngpio	= S5PC100_GPIO_F3_NR,
+			.label	= "GPF3",
+		},
+	}, {
+		.base	= S5PC100_GPG0_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPG0(0),
+			.ngpio	= S5PC100_GPIO_G0_NR,
+			.label	= "GPG0",
+		},
+	}, {
+		.base	= S5PC100_GPG1_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPG1(0),
+			.ngpio	= S5PC100_GPIO_G1_NR,
+			.label	= "GPG1",
+		},
+	}, {
+		.base	= S5PC100_GPG2_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPG2(0),
+			.ngpio	= S5PC100_GPIO_G2_NR,
+			.label	= "GPG2",
+		},
+	}, {
+		.base	= S5PC100_GPG3_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPG3(0),
+			.ngpio	= S5PC100_GPIO_G3_NR,
+			.label	= "GPG3",
+		},
+	}, {
+		.base	= S5PC100_GPH0_BASE,
+		.config	= &gpio_cfg_eint,
+		.chip	= {
+			.base	= S5PC100_GPH0(0),
+			.ngpio	= S5PC100_GPIO_H0_NR,
+			.label	= "GPH0",
+		},
+	}, {
+		.base	= S5PC100_GPH1_BASE,
+		.config	= &gpio_cfg_eint,
+		.chip	= {
+			.base	= S5PC100_GPH1(0),
+			.ngpio	= S5PC100_GPIO_H1_NR,
+			.label	= "GPH1",
+		},
+	}, {
+		.base	= S5PC100_GPH2_BASE,
+		.config	= &gpio_cfg_eint,
+		.chip	= {
+			.base	= S5PC100_GPH2(0),
+			.ngpio	= S5PC100_GPIO_H2_NR,
+			.label	= "GPH2",
+		},
+	}, {
+		.base	= S5PC100_GPH3_BASE,
+		.config	= &gpio_cfg_eint,
+		.chip	= {
+			.base	= S5PC100_GPH3(0),
+			.ngpio	= S5PC100_GPIO_H3_NR,
+			.label	= "GPH3",
+		},
+	}, {
+		.base	= S5PC100_GPI_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPI(0),
+			.ngpio	= S5PC100_GPIO_I_NR,
+			.label	= "GPI",
+		},
+	}, {
+		.base	= S5PC100_GPJ0_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPJ0(0),
+			.ngpio	= S5PC100_GPIO_J0_NR,
+			.label	= "GPJ0",
+		},
+	}, {
+		.base	= S5PC100_GPJ1_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPJ1(0),
+			.ngpio	= S5PC100_GPIO_J1_NR,
+			.label	= "GPJ1",
+		},
+	}, {
+		.base	= S5PC100_GPJ2_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPJ2(0),
+			.ngpio	= S5PC100_GPIO_J2_NR,
+			.label	= "GPJ2",
+		},
+	}, {
+		.base	= S5PC100_GPJ3_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPJ3(0),
+			.ngpio	= S5PC100_GPIO_J3_NR,
+			.label	= "GPJ3",
+		},
+	}, {
+		.base	= S5PC100_GPJ4_BASE,
+		.config	= &gpio_cfg,
+		.chip	= {
+			.base	= S5PC100_GPJ4(0),
+			.ngpio	= S5PC100_GPIO_J4_NR,
+			.label	= "GPJ4",
+		},
+	}, {
+		.base	= S5PC100_GPK0_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPK0(0),
+			.ngpio	= S5PC100_GPIO_K0_NR,
+			.label	= "GPK0",
+		},
+	}, {
+		.base	= S5PC100_GPK1_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPK1(0),
+			.ngpio	= S5PC100_GPIO_K1_NR,
+			.label	= "GPK1",
+		},
+	}, {
+		.base	= S5PC100_GPK2_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPK2(0),
+			.ngpio	= S5PC100_GPIO_K2_NR,
+			.label	= "GPK2",
+		},
+	}, {
+		.base	= S5PC100_GPK3_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPK3(0),
+			.ngpio	= S5PC100_GPIO_K3_NR,
+			.label	= "GPK3",
+		},
+	}, {
+		.base	= S5PC100_GPL0_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL0(0),
+			.ngpio	= S5PC100_GPIO_L0_NR,
+			.label	= "GPL0",
+		},
+	}, {
+		.base	= S5PC100_GPL1_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL1(0),
+			.ngpio	= S5PC100_GPIO_L1_NR,
+			.label	= "GPL1",
+		},
+	}, {
+		.base	= S5PC100_GPL2_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL2(0),
+			.ngpio	= S5PC100_GPIO_L2_NR,
+			.label	= "GPL2",
+		},
+	}, {
+		.base	= S5PC100_GPL3_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL3(0),
+			.ngpio	= S5PC100_GPIO_L3_NR,
+			.label	= "GPL3",
+		},
+	}, {
+		.base	= S5PC100_GPL4_BASE,
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL4(0),
+			.ngpio	= S5PC100_GPIO_L4_NR,
+			.label	= "GPL4",
+		},
+	},
+};
+
+/* FIXME move from irq-gpio.c */
+extern struct irq_chip s5pc1xx_gpioint;
+extern void s5pc1xx_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc);
+
+static __init void s5pc1xx_gpiolib_link(struct s3c_gpio_chip *chip)
+{
+	chip->chip.direction_input = s5pc1xx_gpiolib_input;
+	chip->chip.direction_output = s5pc1xx_gpiolib_output;
+	chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
+
+	/* Interrupt */
+	if (chip->config == &gpio_cfg) {
+		int i, irq;
+
+		chip->chip.to_irq = s5pc1xx_gpiolib_to_irq;
+
+		for (i = 0;  i < chip->chip.ngpio; i++) {
+			irq = S3C_IRQ_GPIO_BASE + chip->chip.base + i;
+			set_irq_chip(irq, &s5pc1xx_gpioint);
+			set_irq_data(irq, &chip->chip);
+			set_irq_handler(irq, handle_level_irq);
+			set_irq_flags(irq, IRQF_VALID);
+		}
+	} else if (chip->config == &gpio_cfg_eint)
+		chip->chip.to_irq = s5pc1xx_gpiolib_to_eint;
+}
+
+static __init void s5pc1xx_gpiolib_add(struct s3c_gpio_chip *chips,
+				       int nr_chips,
+				       void (*fn)(struct s3c_gpio_chip *))
+{
+	for (; nr_chips > 0; nr_chips--, chips++) {
+		if (fn)
+			(fn)(chips);
+		s3c_gpiolib_add(chips);
+	}
+}
+
+static __init int s5pc1xx_gpiolib_init(void)
+{
+	struct s3c_gpio_chip *chips;
+	int nr_chips;
+
+		chips = s5pc100_gpio_chips;
+		nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
+
+	s5pc1xx_gpiolib_add(chips, nr_chips, s5pc1xx_gpiolib_link);
+	/* Interrupt */
+	set_irq_chained_handler(IRQ_GPIOINT, s5pc1xx_irq_gpioint_handler);
+
+	return 0;
+}
+core_initcall(s5pc1xx_gpiolib_init);
diff --git a/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h b/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h
new file mode 100644
index 0000000..c29ee25
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h
@@ -0,0 +1,33 @@
+/* linux/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg.h
+ *
+ * Copyright 2009 Samsung Electronic
+ *	InKi Dae <inki.dae@samsung.com>
+ *
+ * S5PC1XX Platform - GPIO pin configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* This file contains the necessary definitions to get the basic gpio
+ * pin configuration done such as setting a pin to input or output or
+ * changing the pull-{up,down} configurations.
+ */
+
+#ifndef __GPIO_CFG_S5PC1XX_H
+#define __GPIO_CFG_S5PC1XX_H __FILE__
+
+typedef unsigned int __bitwise__ s5p_gpio_drvstr_t;
+
+#define S5P_GPIO_DRVSTR_LV1	0x00
+#define S5P_GPIO_DRVSTR_LV2	0x01
+#define S5P_GPIO_DRVSTR_LV3	0x10
+#define S5P_GPIO_DRVSTR_LV4	0x11
+
+extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin, unsigned int off);
+
+extern int s5p_gpio_set_drvstr(unsigned int pin, unsigned int off,
+			s5p_gpio_drvstr_t drvstr);
+
+#endif /* __GPIO_CFG_S5PC1XX_H */
diff --git a/arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h b/arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h
new file mode 100644
index 0000000..33ad267
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h
@@ -0,0 +1,44 @@
+/* linux/arch/arm/plat-s5pc1xx/include/plat/gpio-eint.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *
+ * External Interrupt (GPH0 ~ GPH3) control register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S5PC1XX_WKUP_INT_CON0_7		(S5PC1XX_EINT_BASE + 0x0)
+#define S5PC1XX_WKUP_INT_CON8_15	(S5PC1XX_EINT_BASE + 0x4)
+#define S5PC1XX_WKUP_INT_CON16_23	(S5PC1XX_EINT_BASE + 0x8)
+#define S5PC1XX_WKUP_INT_CON24_31	(S5PC1XX_EINT_BASE + 0xC)
+#define S5PC1XX_WKUP_INT_CON(x)		(S5PC1XX_WKUP_INT_CON0_7 + (x * 0x4))
+
+#define S5PC1XX_WKUP_INT_FLTCON0_3	(S5PC1XX_EINT_BASE + 0x80)
+#define S5PC1XX_WKUP_INT_FLTCON4_7	(S5PC1XX_EINT_BASE + 0x84)
+#define S5PC1XX_WKUP_INT_FLTCON8_11	(S5PC1XX_EINT_BASE + 0x88)
+#define S5PC1XX_WKUP_INT_FLTCON12_15	(S5PC1XX_EINT_BASE + 0x8C)
+#define S5PC1XX_WKUP_INT_FLTCON16_19	(S5PC1XX_EINT_BASE + 0x90)
+#define S5PC1XX_WKUP_INT_FLTCON20_23	(S5PC1XX_EINT_BASE + 0x94)
+#define S5PC1XX_WKUP_INT_FLTCON24_27	(S5PC1XX_EINT_BASE + 0x98)
+#define S5PC1XX_WKUP_INT_FLTCON28_31	(S5PC1XX_EINT_BASE + 0x9C)
+#define S5PC1XX_WKUP_INT_FLTCON(x)	(S5PC1XX_WKUP_INT_FLTCON0_3 + (x * 0x4))
+
+#define S5PC1XX_WKUP_INT_MASK0_7	(S5PC1XX_EINT_BASE + 0x100)
+#define S5PC1XX_WKUP_INT_MASK8_15	(S5PC1XX_EINT_BASE + 0x104)
+#define S5PC1XX_WKUP_INT_MASK16_23	(S5PC1XX_EINT_BASE + 0x108)
+#define S5PC1XX_WKUP_INT_MASK24_31	(S5PC1XX_EINT_BASE + 0x10C)
+#define S5PC1XX_WKUP_INT_MASK(x)	(S5PC1XX_WKUP_INT_MASK0_7 + (x * 0x4))
+
+#define S5PC1XX_WKUP_INT_PEND0_7	(S5PC1XX_EINT_BASE + 0x140)
+#define S5PC1XX_WKUP_INT_PEND8_15	(S5PC1XX_EINT_BASE + 0x144)
+#define S5PC1XX_WKUP_INT_PEND16_23	(S5PC1XX_EINT_BASE + 0x148)
+#define S5PC1XX_WKUP_INT_PEND24_31	(S5PC1XX_EINT_BASE + 0x14C)
+#define S5PC1XX_WKUP_INT_PEND(x)	(S5PC1XX_WKUP_INT_PEND0_7 + (x * 0x4))
+
+#define S5PC1XX_WKUP_INT_LOWLEV		(0x00)
+#define S5PC1XX_WKUP_INT_HILEV		(0x01)
+#define S5PC1XX_WKUP_INT_FALLEDGE	(0x02)
+#define S5PC1XX_WKUP_INT_RISEEDGE	(0x03)
+#define S5PC1XX_WKUP_INT_BOTHEDGE	(0x04)
diff --git a/arch/arm/plat-s5pc1xx/include/plat/irqs.h b/arch/arm/plat-s5pc1xx/include/plat/irqs.h
index f07d8c3..ef87363 100644
--- a/arch/arm/plat-s5pc1xx/include/plat/irqs.h
+++ b/arch/arm/plat-s5pc1xx/include/plat/irqs.h
@@ -171,12 +171,21 @@
 #define IRQ_SDMIRQ		S5PC1XX_IRQ_VIC2(30)
 #define IRQ_SDMFIQ		S5PC1XX_IRQ_VIC2(31)
 
+/* External interrupt */
 #define S3C_IRQ_EINT_BASE	(IRQ_SDMFIQ + 1)
 
-#define S3C_EINT(x)		((x) + S3C_IRQ_EINT_BASE)
-#define IRQ_EINT(x)		S3C_EINT(x)
+#define S3C_EINT(x)		(S3C_IRQ_EINT_BASE + (x - 16))
+#define IRQ_EINT(x)		(x < 16 ? IRQ_EINT0 + x : S3C_EINT(x))
+#define IRQ_EINT_BIT(x)		(x < IRQ_EINT16_31 ? x - IRQ_EINT0 : x - S3C_EINT(0))
 
-#define NR_IRQS 		(IRQ_EINT(31)+1)
+/* GPIO interrupt */
+#define S3C_IRQ_GPIO_BASE	(IRQ_EINT(31) + 1)
+#define S3C_IRQ_GPIO(x)		(S3C_IRQ_GPIO_BASE + (x))
+
+/*
+ * Until MP04 Groups -> 40 (exactly 39) Groups * 8 ~= 320 GPIOs
+ */
+#define NR_IRQS			(S3C_IRQ_GPIO(320) + 1)
 
 #endif /* __ASM_PLAT_S5PC1XX_IRQS_H */
 
diff --git a/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h b/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
new file mode 100644
index 0000000..43c7bc8
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
@@ -0,0 +1,70 @@
+/* linux/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *      Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC1XX - GPIO register definitions
+ */
+
+#ifndef __ASM_PLAT_S5PC1XX_REGS_GPIO_H
+#define __ASM_PLAT_S5PC1XX_REGS_GPIO_H __FILE__
+
+#include <mach/map.h>
+
+/* S5PC100 */
+#define S5PC100_GPIO_BASE	S5PC1XX_VA_GPIO
+#define S5PC100_GPA0_BASE	(S5PC100_GPIO_BASE + 0x0000)
+#define S5PC100_GPA1_BASE	(S5PC100_GPIO_BASE + 0x0020)
+#define S5PC100_GPB_BASE	(S5PC100_GPIO_BASE + 0x0040)
+#define S5PC100_GPC_BASE	(S5PC100_GPIO_BASE + 0x0060)
+#define S5PC100_GPD_BASE	(S5PC100_GPIO_BASE + 0x0080)
+#define S5PC100_GPE0_BASE	(S5PC100_GPIO_BASE + 0x00A0)
+#define S5PC100_GPE1_BASE	(S5PC100_GPIO_BASE + 0x00C0)
+#define S5PC100_GPF0_BASE	(S5PC100_GPIO_BASE + 0x00E0)
+#define S5PC100_GPF1_BASE	(S5PC100_GPIO_BASE + 0x0100)
+#define S5PC100_GPF2_BASE	(S5PC100_GPIO_BASE + 0x0120)
+#define S5PC100_GPF3_BASE	(S5PC100_GPIO_BASE + 0x0140)
+#define S5PC100_GPG0_BASE	(S5PC100_GPIO_BASE + 0x0160)
+#define S5PC100_GPG1_BASE	(S5PC100_GPIO_BASE + 0x0180)
+#define S5PC100_GPG2_BASE	(S5PC100_GPIO_BASE + 0x01A0)
+#define S5PC100_GPG3_BASE	(S5PC100_GPIO_BASE + 0x01C0)
+#define S5PC100_GPH0_BASE	(S5PC100_GPIO_BASE + 0x0C00)
+#define S5PC100_GPH1_BASE	(S5PC100_GPIO_BASE + 0x0C20)
+#define S5PC100_GPH2_BASE	(S5PC100_GPIO_BASE + 0x0C40)
+#define S5PC100_GPH3_BASE	(S5PC100_GPIO_BASE + 0x0C60)
+#define S5PC100_GPI_BASE	(S5PC100_GPIO_BASE + 0x01E0)
+#define S5PC100_GPJ0_BASE	(S5PC100_GPIO_BASE + 0x0200)
+#define S5PC100_GPJ1_BASE	(S5PC100_GPIO_BASE + 0x0220)
+#define S5PC100_GPJ2_BASE	(S5PC100_GPIO_BASE + 0x0240)
+#define S5PC100_GPJ3_BASE	(S5PC100_GPIO_BASE + 0x0260)
+#define S5PC100_GPJ4_BASE	(S5PC100_GPIO_BASE + 0x0280)
+#define S5PC100_GPK0_BASE	(S5PC100_GPIO_BASE + 0x02A0)
+#define S5PC100_GPK1_BASE	(S5PC100_GPIO_BASE + 0x02C0)
+#define S5PC100_GPK2_BASE	(S5PC100_GPIO_BASE + 0x02E0)
+#define S5PC100_GPK3_BASE	(S5PC100_GPIO_BASE + 0x0300)
+#define S5PC100_GPL0_BASE	(S5PC100_GPIO_BASE + 0x0320)
+#define S5PC100_GPL1_BASE	(S5PC100_GPIO_BASE + 0x0340)
+#define S5PC100_GPL2_BASE	(S5PC100_GPIO_BASE + 0x0360)
+#define S5PC100_GPL3_BASE	(S5PC100_GPIO_BASE + 0x0380)
+#define S5PC100_GPL4_BASE	(S5PC100_GPIO_BASE + 0x03A0)
+#define S5PC100_EINT_BASE	(S5PC100_GPIO_BASE + 0x0E00)
+
+#define S5PC100_UHOST		(S5PC100_GPIO_BASE + 0x0B68)
+#define S5PC100_PDNEN		(S5PC100_GPIO_BASE + 0x0F80)
+
+/* PDNEN */
+#define S5PC100_PDNEN_CFG_PDNEN	(1 << 1)
+#define S5PC100_PDNEN_CFG_AUTO	(0 << 1)
+#define S5PC100_PDNEN_POWERDOWN	(1 << 0)
+#define S5PC100_PDNEN_NORMAL	(0 << 0)
+
+/* Common part */
+/* External interrupt base is same at both s5pc100 and s5pc110 */
+#define S5PC1XX_EINT_BASE	(S5PC100_EINT_BASE)
+
+#define S5PC100_GPx_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
+#define S5PC100_GPx_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
+#define S5PC100_GPx_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
+
+#endif /* __ASM_PLAT_S5PC1XX_REGS_GPIO_H */
+
diff --git a/arch/arm/plat-s5pc1xx/irq-eint.c b/arch/arm/plat-s5pc1xx/irq-eint.c
new file mode 100644
index 0000000..34f9443
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/irq-eint.c
@@ -0,0 +1,281 @@
+/*
+ * linux/arch/arm/plat-s5pc1xx/irq-eint.c
+ *
+ *  Copyright 2009 Samsung Electronics Co.
+ *  Byungho Min <bhmin@samsung.com>
+ *  Kyungin Park <kyungmin.park@samsung.com>
+ *
+ * Based on plat-s3c64xx/irq-eint.c
+ *
+ * S5PC1XX - Interrupt handling for IRQ_EINT(x)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/pm.h>
+
+#include <asm/hardware/vic.h>
+
+#include <mach/map.h>
+#include <mach/gpio.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-ext.h>
+#include <plat/pm.h>
+#include <plat/regs-gpio.h>
+#include <plat/regs-irqtype.h>
+
+/*
+ * bank is a group of external interrupt
+ * bank0 means EINT0 ... EINT7
+ * bank1 means EINT8 ... EINT15
+ * bank2 means EINT16 ... EINT23
+ * bank3 means EINT24 ... EINT31
+ */
+
+static inline int s3c_get_eint(unsigned int irq)
+{
+	int real;
+
+	if (irq < IRQ_EINT16_31)
+		real = (irq - IRQ_EINT0);
+	else
+		real = (irq - S3C_IRQ_EINT_BASE) + IRQ_EINT16_31 - IRQ_EINT0;
+
+	return real;
+}
+
+static inline int s3c_get_bank(unsigned int irq)
+{
+	return s3c_get_eint(irq) >> 3;
+}
+
+static inline int s3c_eint_to_bit(unsigned int irq)
+{
+	int real, bit;
+
+	real = s3c_get_eint(irq);
+	bit = 1 << (real & (8 - 1));
+
+	return bit;
+}
+
+static inline void s3c_irq_eint_mask(unsigned int irq)
+{
+	u32 mask;
+	u32 bank = s3c_get_bank(irq);
+
+	mask = __raw_readl(S5PC1XX_WKUP_INT_MASK(bank));
+	mask |= s3c_eint_to_bit(irq);
+	__raw_writel(mask, S5PC1XX_WKUP_INT_MASK(bank));
+}
+
+static void s3c_irq_eint_unmask(unsigned int irq)
+{
+	u32 mask;
+	u32 bank = s3c_get_bank(irq);
+
+	mask = __raw_readl(S5PC1XX_WKUP_INT_MASK(bank));
+	mask &= ~(s3c_eint_to_bit(irq));
+	__raw_writel(mask, S5PC1XX_WKUP_INT_MASK(bank));
+}
+
+static inline void s3c_irq_eint_ack(unsigned int irq)
+{
+	u32 bank = s3c_get_bank(irq);
+
+	__raw_writel(s3c_eint_to_bit(irq), S5PC1XX_WKUP_INT_PEND(bank));
+}
+
+static void s3c_irq_eint_maskack(unsigned int irq)
+{
+	/* compiler should in-line these */
+	s3c_irq_eint_mask(irq);
+	s3c_irq_eint_ack(irq);
+}
+
+static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
+{
+	u32 bank = s3c_get_bank(irq);
+	int real = s3c_get_eint(irq);
+	int gpio, shift, sfn;
+	u32 ctrl, con = 0;
+
+	switch (type) {
+	case IRQ_TYPE_NONE:
+		printk(KERN_WARNING "No edge setting!\n");
+		break;
+
+	case IRQ_TYPE_EDGE_RISING:
+		con = S5PC1XX_WKUP_INT_RISEEDGE;
+		break;
+
+	case IRQ_TYPE_EDGE_FALLING:
+		con = S5PC1XX_WKUP_INT_FALLEDGE;
+		break;
+
+	case IRQ_TYPE_EDGE_BOTH:
+		con = S5PC1XX_WKUP_INT_BOTHEDGE;
+		break;
+
+	case IRQ_TYPE_LEVEL_LOW:
+		con = S5PC1XX_WKUP_INT_LOWLEV;
+		break;
+
+	case IRQ_TYPE_LEVEL_HIGH:
+		con = S5PC1XX_WKUP_INT_HILEV;
+		break;
+
+	default:
+		printk(KERN_ERR "No such irq type %d", type);
+		return -EINVAL;
+	}
+
+	gpio = real & (8 - 1);
+	shift = gpio << 2;
+
+	ctrl = __raw_readl(S5PC1XX_WKUP_INT_CON(bank));
+	ctrl &= ~(0x7 << shift);
+	ctrl |= con << shift;
+	__raw_writel(ctrl, S5PC1XX_WKUP_INT_CON(bank));
+
+	switch (real) {
+	case 0 ... 7:
+			gpio = S5PC100_GPH0(gpio);
+		break;
+	case 8 ... 15:
+			gpio = S5PC100_GPH1(gpio);
+		break;
+	case 16 ... 23:
+			gpio = S5PC100_GPH2(gpio);
+		break;
+	case 24 ... 31:
+			gpio = S5PC100_GPH3(gpio);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	sfn = S3C_GPIO_SFN(0x2);
+	s3c_gpio_cfgpin(gpio, sfn);
+
+	return 0;
+}
+
+static struct irq_chip s3c_irq_eint = {
+	.name		= "EINT",
+	.mask		= s3c_irq_eint_mask,
+	.unmask		= s3c_irq_eint_unmask,
+	.mask_ack	= s3c_irq_eint_maskack,
+	.ack		= s3c_irq_eint_ack,
+	.set_type	= s3c_irq_eint_set_type,
+	.set_wake	= s3c_irqext_wake,
+};
+
+/* s3c_irq_demux_eint
+ *
+ * This function demuxes the IRQ from external interrupts,
+ * from IRQ_EINT(16) to IRQ_EINT(31). It is designed to be inlined into
+ * the specific handlers s3c_irq_demux_eintX_Y.
+ */
+static inline void s3c_irq_demux_eint(unsigned int start, unsigned int end)
+{
+	u32 status = __raw_readl(S5PC1XX_WKUP_INT_PEND((start >> 3)));
+	u32 mask = __raw_readl(S5PC1XX_WKUP_INT_MASK((start >> 3)));
+	unsigned int irq;
+
+	status &= ~mask;
+	status &= (1 << (end - start + 1)) - 1;
+
+	for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
+		if (status & 1)
+			generic_handle_irq(irq);
+
+		status >>= 1;
+	}
+}
+
+static void s3c_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
+{
+	s3c_irq_demux_eint(16, 23);
+	s3c_irq_demux_eint(24, 31);
+}
+
+/*
+ * Handle EINT0 ... EINT15 at VIC directly
+ */
+static void s3c_irq_vic_eint_mask(unsigned int irq)
+{
+	void __iomem *base = get_irq_chip_data(irq);
+	unsigned int real;
+
+	s3c_irq_eint_mask(irq);
+	real = s3c_get_eint(irq);
+	writel(1 << real, base + VIC_INT_ENABLE_CLEAR);
+}
+
+static void s3c_irq_vic_eint_unmask(unsigned int irq)
+{
+	void __iomem *base = get_irq_chip_data(irq);
+	unsigned int real;
+
+	s3c_irq_eint_unmask(irq);
+	real = s3c_get_eint(irq);
+	writel(1 << real, base + VIC_INT_ENABLE);
+}
+
+static inline void s3c_irq_vic_eint_ack(unsigned int irq)
+{
+	u32 bit;
+	u32 bank = s3c_get_bank(irq);
+
+	bit = s3c_eint_to_bit(irq);
+	__raw_writel(bit, S5PC1XX_WKUP_INT_PEND(bank));
+}
+
+static void s3c_irq_vic_eint_maskack(unsigned int irq)
+{
+	/* compiler should in-line these */
+	s3c_irq_vic_eint_mask(irq);
+	s3c_irq_vic_eint_ack(irq);
+}
+
+static struct irq_chip s3c_irq_vic_eint = {
+	.name		= "EINT",
+	.mask		= s3c_irq_vic_eint_mask,
+	.unmask		= s3c_irq_vic_eint_unmask,
+	.mask_ack	= s3c_irq_vic_eint_maskack,
+	.ack		= s3c_irq_vic_eint_ack,
+	.set_type	= s3c_irq_eint_set_type,
+	.set_wake	= s3c_irqext_wake,
+};
+
+static int __init s5pc1xx_init_irq_eint(void)
+{
+	int irq;
+
+	for (irq = IRQ_EINT0; irq <= IRQ_EINT15; irq++) {
+		set_irq_chip(irq, &s3c_irq_vic_eint);
+		set_irq_handler(irq, handle_level_irq);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+	for (irq = IRQ_EINT(16); irq <= IRQ_EINT(31); irq++) {
+		set_irq_chip(irq, &s3c_irq_eint);
+		set_irq_handler(irq, handle_level_irq);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+	set_irq_chained_handler(IRQ_EINT16_31, s3c_irq_demux_eint16_31);
+
+	return 0;
+}
+
+arch_initcall(s5pc1xx_init_irq_eint);
diff --git a/arch/arm/plat-s5pc1xx/irq-gpio.c b/arch/arm/plat-s5pc1xx/irq-gpio.c
new file mode 100644
index 0000000..843a88e
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/irq-gpio.c
@@ -0,0 +1,266 @@
+/*
+ * arch/arm/plat-s5pc1xx/irq-gpio.c
+ *
+ * Copyright (C) 2009 Samsung Electronics
+ *
+ * S5PC1XX - Interrupt handling for IRQ_GPIO${group}(x)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
+
+#define S5PC1XX_GPIOREG(x)		(S5PC1XX_VA_GPIO + (x))
+
+#define CON_OFFSET			0x700
+#define MASK_OFFSET			0x900
+#define PEND_OFFSET			0xA00
+#define CON_OFFSET_2			0xE00
+#define MASK_OFFSET_2			0xF00
+#define PEND_OFFSET_2			0xF40
+
+#define GPIOINT_LEVEL_LOW		0x0
+#define GPIOINT_LEVEL_HIGH		0x1
+#define GPIOINT_EDGE_FALLING		0x2
+#define GPIOINT_EDGE_RISING		0x3
+#define GPIOINT_EDGE_BOTH		0x4
+
+static int group_to_con_offset(int group)
+{
+	return group << 2;
+}
+
+static int group_to_mask_offset(int group)
+{
+	return group << 2;
+}
+
+static int group_to_pend_offset(int group)
+{
+	return group << 2;
+}
+
+static int s5pc1xx_get_start(unsigned int group)
+{
+	switch (group) {
+	case 0: return S5PC100_GPIO_A0_START;
+	case 1: return S5PC100_GPIO_A1_START;
+	case 2: return S5PC100_GPIO_B_START;
+	case 3: return S5PC100_GPIO_C_START;
+	case 4: return S5PC100_GPIO_D_START;
+	case 5: return S5PC100_GPIO_E0_START;
+	case 6: return S5PC100_GPIO_E1_START;
+	case 7: return S5PC100_GPIO_F0_START;
+	case 8: return S5PC100_GPIO_F1_START;
+	case 9: return S5PC100_GPIO_F2_START;
+	case 10: return S5PC100_GPIO_F3_START;
+	case 11: return S5PC100_GPIO_G0_START;
+	case 12: return S5PC100_GPIO_G1_START;
+	case 13: return S5PC100_GPIO_G2_START;
+	case 14: return S5PC100_GPIO_G3_START;
+	case 15: return S5PC100_GPIO_I_START;
+	case 16: return S5PC100_GPIO_J0_START;
+	case 17: return S5PC100_GPIO_J1_START;
+	case 18: return S5PC100_GPIO_J2_START;
+	case 19: return S5PC100_GPIO_J3_START;
+	case 20: return S5PC100_GPIO_J4_START;
+	default:
+		BUG();
+	}
+
+	return -EINVAL;
+}
+
+static int s5pc1xx_get_group(unsigned int irq)
+{
+	irq -= S3C_IRQ_GPIO(0);
+
+	switch (irq) {
+	case S5PC100_GPIO_A0_START ... S5PC100_GPIO_A1_START - 1:
+		return 0;
+	case S5PC100_GPIO_A1_START ... S5PC100_GPIO_B_START - 1:
+		return 1;
+	case S5PC100_GPIO_B_START ... S5PC100_GPIO_C_START - 1:
+		return 2;
+	case S5PC100_GPIO_C_START ... S5PC100_GPIO_D_START - 1:
+		return 3;
+	case S5PC100_GPIO_D_START ... S5PC100_GPIO_E0_START - 1:
+		return 4;
+	case S5PC100_GPIO_E0_START ... S5PC100_GPIO_E1_START - 1:
+		return 5;
+	case S5PC100_GPIO_E1_START ... S5PC100_GPIO_F0_START - 1:
+		return 6;
+	case S5PC100_GPIO_F0_START ... S5PC100_GPIO_F1_START - 1:
+		return 7;
+	case S5PC100_GPIO_F1_START ... S5PC100_GPIO_F2_START - 1:
+		return 8;
+	case S5PC100_GPIO_F2_START ... S5PC100_GPIO_F3_START - 1:
+		return 9;
+	case S5PC100_GPIO_F3_START ... S5PC100_GPIO_G0_START - 1:
+		return 10;
+	case S5PC100_GPIO_G0_START ... S5PC100_GPIO_G1_START - 1:
+		return 11;
+	case S5PC100_GPIO_G1_START ... S5PC100_GPIO_G2_START - 1:
+		return 12;
+	case S5PC100_GPIO_G2_START ... S5PC100_GPIO_G3_START - 1:
+		return 13;
+	case S5PC100_GPIO_G3_START ... S5PC100_GPIO_H0_START - 1:
+		return 14;
+	case S5PC100_GPIO_I_START ... S5PC100_GPIO_J0_START - 1:
+		return 15;
+	case S5PC100_GPIO_J0_START ... S5PC100_GPIO_J1_START - 1:
+		return 16;
+	case S5PC100_GPIO_J1_START ... S5PC100_GPIO_J2_START - 1:
+		return 17;
+	case S5PC100_GPIO_J2_START ... S5PC100_GPIO_J3_START - 1:
+		return 18;
+	case S5PC100_GPIO_J3_START ... S5PC100_GPIO_J4_START - 1:
+		return 19;
+	case S5PC100_GPIO_J4_START ... S5PC100_GPIO_K0_START - 1:
+		return 20;
+	default:
+		BUG();
+	}
+
+	return -EINVAL;
+}
+
+static int s5pc1xx_get_offset(unsigned int irq)
+{
+	struct gpio_chip *chip = get_irq_data(irq);
+	return irq - S3C_IRQ_GPIO(chip->base);
+}
+
+static void s5pc1xx_gpioint_ack(unsigned int irq)
+{
+	int group, offset, pend_offset;
+	unsigned int value;
+
+	group = s5pc1xx_get_group(irq);
+	offset = s5pc1xx_get_offset(irq);
+	pend_offset = group_to_pend_offset(group);
+
+	value = __raw_readl(S5PC1XX_GPIOREG(PEND_OFFSET) + pend_offset);
+	value |= 1 << offset;
+	__raw_writel(value, S5PC1XX_GPIOREG(PEND_OFFSET) + pend_offset);
+}
+
+static void s5pc1xx_gpioint_mask(unsigned int irq)
+{
+	int group, offset, mask_offset;
+	unsigned int value;
+
+	group = s5pc1xx_get_group(irq);
+	offset = s5pc1xx_get_offset(irq);
+	mask_offset = group_to_mask_offset(group);
+
+	value = __raw_readl(S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
+	value |= 1 << offset;
+	__raw_writel(value, S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
+}
+
+static void s5pc1xx_gpioint_unmask(unsigned int irq)
+{
+	int group, offset, mask_offset;
+	unsigned int value;
+
+	group = s5pc1xx_get_group(irq);
+	offset = s5pc1xx_get_offset(irq);
+	mask_offset = group_to_mask_offset(group);
+
+	value = __raw_readl(S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
+	value &= ~(1 << offset);
+	__raw_writel(value, S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
+}
+
+static void s5pc1xx_gpioint_mask_ack(unsigned int irq)
+{
+	s5pc1xx_gpioint_mask(irq);
+	s5pc1xx_gpioint_ack(irq);
+}
+
+static int s5pc1xx_gpioint_set_type(unsigned int irq, unsigned int type)
+{
+	int group, offset, con_offset;
+	unsigned int value;
+
+	group = s5pc1xx_get_group(irq);
+	offset = s5pc1xx_get_offset(irq);
+	con_offset = group_to_con_offset(group);
+
+	switch (type) {
+	case IRQ_TYPE_NONE:
+		printk(KERN_WARNING "No irq type\n");
+		return -EINVAL;
+	case IRQ_TYPE_EDGE_RISING:
+		type = GPIOINT_EDGE_RISING;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		type = GPIOINT_EDGE_FALLING;
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		type = GPIOINT_EDGE_BOTH;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		type = GPIOINT_LEVEL_HIGH;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		type = GPIOINT_LEVEL_LOW;
+		break;
+	default:
+		BUG();
+	}
+
+
+	value = __raw_readl(S5PC1XX_GPIOREG(CON_OFFSET) + con_offset);
+	value &= ~(0xf << (offset * 0x4));
+	value |= (type << (offset * 0x4));
+	__raw_writel(value, S5PC1XX_GPIOREG(CON_OFFSET) + con_offset);
+
+	return 0;
+}
+
+struct irq_chip s5pc1xx_gpioint = {
+	.name		= "GPIO",
+	.ack		= s5pc1xx_gpioint_ack,
+	.mask		= s5pc1xx_gpioint_mask,
+	.mask_ack	= s5pc1xx_gpioint_mask_ack,
+	.unmask		= s5pc1xx_gpioint_unmask,
+	.set_type	= s5pc1xx_gpioint_set_type,
+};
+
+void s5pc1xx_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc)
+{
+	int group, offset, pend_offset, mask_offset;
+	int real_irq, group_end;
+	unsigned int pend, mask;
+
+	group_end = 21;
+
+	for (group = 0; group < group_end; group++) {
+		pend_offset = group_to_pend_offset(group);
+		pend = __raw_readl(S5PC1XX_GPIOREG(PEND_OFFSET) + pend_offset);
+		if (!pend)
+			continue;
+
+		mask_offset = group_to_mask_offset(group);
+		mask = __raw_readl(S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
+		pend &= ~mask;
+
+		for (offset = 0; offset < 8; offset++) {
+			if (pend & (1 << offset)) {
+				real_irq = s5pc1xx_get_start(group) + offset;
+				generic_handle_irq(S3C_IRQ_GPIO(real_irq));
+			}
+		}
+	}
+}
diff --git a/arch/arm/plat-s5pc1xx/irq.c b/arch/arm/plat-s5pc1xx/irq.c
index 80d6dd9..e44fd04 100644
--- a/arch/arm/plat-s5pc1xx/irq.c
+++ b/arch/arm/plat-s5pc1xx/irq.c
@@ -79,7 +79,7 @@ static void s3c_irq_timer_ack(unsigned int irq)
 {
 	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
 
-	reg &= 0x1f;
+	reg &= 0x1f;  /* mask out pending interrupts */
 	reg |= (1 << 5) << (irq - IRQ_TIMER0);
 	__raw_writel(reg, S3C64XX_TINT_CSTAT);
 }
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 08/17] ARM: S5PC1XX: add cpu idle and system reset support
  2009-10-13  8:11               ` Marek Szyprowski
@ 2009-10-13  8:11                 ` Marek Szyprowski
  -1 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: kyungmin.park, bhmin, ben-linux, m.szyprowski

Add CPU idle support by a call to SoC build-in power management core.
Add system reset support by a simple write to system controll register.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/cpu.c                     |   22 ++++++
 arch/arm/mach-s5pc100/include/mach/system.h     |   15 +++-
 arch/arm/plat-s3c/include/plat/cpu.h            |    6 ++
 arch/arm/plat-s5pc1xx/include/plat/regs-power.h |   84 +++++++++++++++++++++++
 4 files changed, 124 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/plat-s5pc1xx/include/plat/regs-power.h

diff --git a/arch/arm/mach-s5pc100/cpu.c b/arch/arm/mach-s5pc100/cpu.c
index 0e71889..a23ca57 100644
--- a/arch/arm/mach-s5pc100/cpu.c
+++ b/arch/arm/mach-s5pc100/cpu.c
@@ -22,6 +22,8 @@
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 
+#include <asm/proc-fns.h>
+
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
@@ -32,6 +34,7 @@
 
 #include <plat/cpu-freq.h>
 #include <plat/regs-serial.h>
+#include <plat/regs-power.h>
 
 #include <plat/cpu.h>
 #include <plat/devs.h>
@@ -45,6 +48,23 @@
 static struct map_desc s5pc100_iodesc[] __initdata = {
 };
 
+static void s5pc100_idle(void)
+{
+	unsigned long tmp;
+
+	tmp = __raw_readl(S5PC100_PWR_CFG);
+	tmp &= ~S5PC100_PWRCFG_CFG_DEEP_IDLE;
+	tmp &= ~S5PC100_PWRCFG_CFG_WFI_MASK;
+	tmp |= S5PC100_PWRCFG_CFG_WFI_DEEP_IDLE;
+	__raw_writel(tmp, S5PC100_PWR_CFG);
+
+	tmp = __raw_readl(S5PC100_OTHERS);
+	tmp |= S5PC100_PMU_INT_DISABLE;
+	__raw_writel(tmp, S5PC100_OTHERS);
+
+	cpu_do_idle();
+}
+
 /* s5pc100_map_io
  *
  * register the standard cpu IO areas
@@ -93,5 +113,7 @@ int __init s5pc100_init(void)
 {
 	printk(KERN_DEBUG "S5PC100: Initialising architecture\n");
 
+	s5pc1xx_idle = s5pc100_idle;
+
 	return sysdev_register(&s5pc100_sysdev);
 }
diff --git a/arch/arm/mach-s5pc100/include/mach/system.h b/arch/arm/mach-s5pc100/include/mach/system.h
index e390143..07f0907 100644
--- a/arch/arm/mach-s5pc100/include/mach/system.h
+++ b/arch/arm/mach-s5pc100/include/mach/system.h
@@ -11,14 +11,23 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H __FILE__
 
+#include <linux/io.h>
+#include <mach/map.h>
+
+void (*s5pc1xx_idle)(void);
+
 static void arch_idle(void)
 {
-	/* nothing here yet */
+	if (s5pc1xx_idle)
+		s5pc1xx_idle();
 }
 
 static void arch_reset(char mode, const char *cmd)
 {
-	/* nothing here yet */
-}
+	unsigned long reset;
 
+	reset = 0xc100;
+	__raw_writel(reset, S5PC1XX_VA_CLK_OTHER);
+	return;
+}
 #endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/plat-s3c/include/plat/cpu.h b/arch/arm/plat-s3c/include/plat/cpu.h
index fbc3d49..d1131ca 100644
--- a/arch/arm/plat-s3c/include/plat/cpu.h
+++ b/arch/arm/plat-s3c/include/plat/cpu.h
@@ -12,6 +12,9 @@
 
 /* todo - fix when rmk changes iodescs to use `void __iomem *` */
 
+#ifndef __SAMSUNG_PLAT_CPU_H
+#define __SAMSUNG_PLAT_CPU_H
+
 #define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
 
 #ifndef MHZ
@@ -73,3 +76,6 @@ extern struct sysdev_class s3c2443_sysclass;
 extern struct sysdev_class s3c6410_sysclass;
 extern struct sysdev_class s3c64xx_sysclass;
 
+extern void (*s5pc1xx_idle)(void);
+
+#endif
diff --git a/arch/arm/plat-s5pc1xx/include/plat/regs-power.h b/arch/arm/plat-s5pc1xx/include/plat/regs-power.h
new file mode 100644
index 0000000..02ffa49
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/regs-power.h
@@ -0,0 +1,84 @@
+/* arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Jongse Won <jongse.won@samsung.com>
+ *
+ * S5PC1XX clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARM_REGS_PWR
+#define __ASM_ARM_REGS_PWR __FILE__
+
+#define S5PC1XX_PWRREG(x)			(S5PC1XX_VA_PWR + (x))
+
+/* s5pc100 (0xE0108000) register for power management */
+#define S5PC100_PWR_CFG				S5PC1XX_PWRREG(0x0)
+#define S5PC100_EINT_WAKEUP_MASK		S5PC1XX_PWRREG(0x4)
+#define S5PC100_NORMAL_CFG			S5PC1XX_PWRREG(0x10)
+#define S5PC100_STOP_CFG			S5PC1XX_PWRREG(0x14)
+#define S5PC100_SLEEP_CFG			S5PC1XX_PWRREG(0x18)
+#define S5PC100_STOP_MEM_CFG			S5PC1XX_PWRREG(0x1C)
+#define S5PC100_OSC_FREQ			S5PC1XX_PWRREG(0x100)
+#define S5PC100_OSC_STABLE			S5PC1XX_PWRREG(0x104)
+#define S5PC100_PWR_STABLE			S5PC1XX_PWRREG(0x108)
+#define S5PC100_MTC_STABLE			S5PC1XX_PWRREG(0x110)
+#define S5PC100_CLAMP_STABLE			S5PC1XX_PWRREG(0x114)
+#define S5PC100_OTHERS				S5PC1XX_PWRREG(0x200)
+#define S5PC100_RST_STAT			S5PC1XX_PWRREG(0x300)
+#define S5PC100_WAKEUP_STAT			S5PC1XX_PWRREG(0x304)
+#define S5PC100_BLK_PWR_STAT			S5PC1XX_PWRREG(0x308)
+#define S5PC100_INFORM0				S5PC1XX_PWRREG(0x400)
+#define S5PC100_INFORM1				S5PC1XX_PWRREG(0x404)
+#define S5PC100_INFORM2				S5PC1XX_PWRREG(0x408)
+#define S5PC100_INFORM3				S5PC1XX_PWRREG(0x40C)
+#define S5PC100_INFORM4				S5PC1XX_PWRREG(0x410)
+#define S5PC100_INFORM5				S5PC1XX_PWRREG(0x414)
+#define S5PC100_INFORM6				S5PC1XX_PWRREG(0x418)
+#define S5PC100_INFORM7				S5PC1XX_PWRREG(0x41C)
+#define S5PC100_DCGIDX_MAP0			S5PC1XX_PWRREG(0x500)
+#define S5PC100_DCGIDX_MAP1			S5PC1XX_PWRREG(0x504)
+#define S5PC100_DCGIDX_MAP2			S5PC1XX_PWRREG(0x508)
+#define S5PC100_DCGPERF_MAP0			S5PC1XX_PWRREG(0x50C)
+#define S5PC100_DCGPERF_MAP1			S5PC1XX_PWRREG(0x510)
+#define S5PC100_DVCIDX_MAP			S5PC1XX_PWRREG(0x514)
+#define S5PC100_FREQ_CPU			S5PC1XX_PWRREG(0x518)
+#define S5PC100_FREQ_DPM			S5PC1XX_PWRREG(0x51C)
+#define S5PC100_DVSEMCLK_EN			S5PC1XX_PWRREG(0x520)
+#define S5PC100_APLL_CON_L8			S5PC1XX_PWRREG(0x600)
+#define S5PC100_APLL_CON_L7			S5PC1XX_PWRREG(0x604)
+#define S5PC100_APLL_CON_L6			S5PC1XX_PWRREG(0x608)
+#define S5PC100_APLL_CON_L5			S5PC1XX_PWRREG(0x60C)
+#define S5PC100_APLL_CON_L4			S5PC1XX_PWRREG(0x610)
+#define S5PC100_APLL_CON_L3			S5PC1XX_PWRREG(0x614)
+#define S5PC100_APLL_CON_L2			S5PC1XX_PWRREG(0x618)
+#define S5PC100_APLL_CON_L1			S5PC1XX_PWRREG(0x61C)
+#define S5PC100_IEM_CONTROL			S5PC1XX_PWRREG(0x620)
+#define S5PC100_CLKDIV_IEM_L8			S5PC1XX_PWRREG(0x700)
+#define S5PC100_CLKDIV_IEM_L7			S5PC1XX_PWRREG(0x704)
+#define S5PC100_CLKDIV_IEM_L6			S5PC1XX_PWRREG(0x708)
+#define S5PC100_CLKDIV_IEM_L5			S5PC1XX_PWRREG(0x70C)
+#define S5PC100_CLKDIV_IEM_L4			S5PC1XX_PWRREG(0x710)
+#define S5PC100_CLKDIV_IEM_L3			S5PC1XX_PWRREG(0x714)
+#define S5PC100_CLKDIV_IEM_L2			S5PC1XX_PWRREG(0x718)
+#define S5PC100_CLKDIV_IEM_L1			S5PC1XX_PWRREG(0x71C)
+#define S5PC100_IEM_HPMCLK_DIV			S5PC1XX_PWRREG(0x724)
+
+/* PWR_CFG */
+#define S5PC100_PWRCFG_CFG_DEEP_IDLE		(1 << 31)
+#define S5PC100_PWRCFG_CFG_WFI_MASK		(3 << 5)
+#define S5PC100_PWRCFG_CFG_WFI_IDLE		(0 << 5)
+#define S5PC100_PWRCFG_CFG_WFI_DEEP_IDLE	(1 << 5)
+#define S5PC100_PWRCFG_CFG_WFI_STOP		(2 << 5)
+#define S5PC100_PWRCFG_CFG_WFI_SLEEP		(3 << 5)
+
+/* SLEEP_CFG */
+#define S5PC100_SLEEP_OSC_EN_SLEEP		(1 << 0)
+
+/* OTHERS */
+#define S5PC100_PMU_INT_DISABLE			(1 << 24)
+
+#endif /* __ASM_ARM_REGS_PWR */
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 08/17] ARM: S5PC1XX: add cpu idle and system reset support
@ 2009-10-13  8:11                 ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

Add CPU idle support by a call to SoC build-in power management core.
Add system reset support by a simple write to system controll register.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/cpu.c                     |   22 ++++++
 arch/arm/mach-s5pc100/include/mach/system.h     |   15 +++-
 arch/arm/plat-s3c/include/plat/cpu.h            |    6 ++
 arch/arm/plat-s5pc1xx/include/plat/regs-power.h |   84 +++++++++++++++++++++++
 4 files changed, 124 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/plat-s5pc1xx/include/plat/regs-power.h

diff --git a/arch/arm/mach-s5pc100/cpu.c b/arch/arm/mach-s5pc100/cpu.c
index 0e71889..a23ca57 100644
--- a/arch/arm/mach-s5pc100/cpu.c
+++ b/arch/arm/mach-s5pc100/cpu.c
@@ -22,6 +22,8 @@
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 
+#include <asm/proc-fns.h>
+
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
@@ -32,6 +34,7 @@
 
 #include <plat/cpu-freq.h>
 #include <plat/regs-serial.h>
+#include <plat/regs-power.h>
 
 #include <plat/cpu.h>
 #include <plat/devs.h>
@@ -45,6 +48,23 @@
 static struct map_desc s5pc100_iodesc[] __initdata = {
 };
 
+static void s5pc100_idle(void)
+{
+	unsigned long tmp;
+
+	tmp = __raw_readl(S5PC100_PWR_CFG);
+	tmp &= ~S5PC100_PWRCFG_CFG_DEEP_IDLE;
+	tmp &= ~S5PC100_PWRCFG_CFG_WFI_MASK;
+	tmp |= S5PC100_PWRCFG_CFG_WFI_DEEP_IDLE;
+	__raw_writel(tmp, S5PC100_PWR_CFG);
+
+	tmp = __raw_readl(S5PC100_OTHERS);
+	tmp |= S5PC100_PMU_INT_DISABLE;
+	__raw_writel(tmp, S5PC100_OTHERS);
+
+	cpu_do_idle();
+}
+
 /* s5pc100_map_io
  *
  * register the standard cpu IO areas
@@ -93,5 +113,7 @@ int __init s5pc100_init(void)
 {
 	printk(KERN_DEBUG "S5PC100: Initialising architecture\n");
 
+	s5pc1xx_idle = s5pc100_idle;
+
 	return sysdev_register(&s5pc100_sysdev);
 }
diff --git a/arch/arm/mach-s5pc100/include/mach/system.h b/arch/arm/mach-s5pc100/include/mach/system.h
index e390143..07f0907 100644
--- a/arch/arm/mach-s5pc100/include/mach/system.h
+++ b/arch/arm/mach-s5pc100/include/mach/system.h
@@ -11,14 +11,23 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H __FILE__
 
+#include <linux/io.h>
+#include <mach/map.h>
+
+void (*s5pc1xx_idle)(void);
+
 static void arch_idle(void)
 {
-	/* nothing here yet */
+	if (s5pc1xx_idle)
+		s5pc1xx_idle();
 }
 
 static void arch_reset(char mode, const char *cmd)
 {
-	/* nothing here yet */
-}
+	unsigned long reset;
 
+	reset = 0xc100;
+	__raw_writel(reset, S5PC1XX_VA_CLK_OTHER);
+	return;
+}
 #endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/plat-s3c/include/plat/cpu.h b/arch/arm/plat-s3c/include/plat/cpu.h
index fbc3d49..d1131ca 100644
--- a/arch/arm/plat-s3c/include/plat/cpu.h
+++ b/arch/arm/plat-s3c/include/plat/cpu.h
@@ -12,6 +12,9 @@
 
 /* todo - fix when rmk changes iodescs to use `void __iomem *` */
 
+#ifndef __SAMSUNG_PLAT_CPU_H
+#define __SAMSUNG_PLAT_CPU_H
+
 #define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
 
 #ifndef MHZ
@@ -73,3 +76,6 @@ extern struct sysdev_class s3c2443_sysclass;
 extern struct sysdev_class s3c6410_sysclass;
 extern struct sysdev_class s3c64xx_sysclass;
 
+extern void (*s5pc1xx_idle)(void);
+
+#endif
diff --git a/arch/arm/plat-s5pc1xx/include/plat/regs-power.h b/arch/arm/plat-s5pc1xx/include/plat/regs-power.h
new file mode 100644
index 0000000..02ffa49
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/regs-power.h
@@ -0,0 +1,84 @@
+/* arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Jongse Won <jongse.won@samsung.com>
+ *
+ * S5PC1XX clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARM_REGS_PWR
+#define __ASM_ARM_REGS_PWR __FILE__
+
+#define S5PC1XX_PWRREG(x)			(S5PC1XX_VA_PWR + (x))
+
+/* s5pc100 (0xE0108000) register for power management */
+#define S5PC100_PWR_CFG				S5PC1XX_PWRREG(0x0)
+#define S5PC100_EINT_WAKEUP_MASK		S5PC1XX_PWRREG(0x4)
+#define S5PC100_NORMAL_CFG			S5PC1XX_PWRREG(0x10)
+#define S5PC100_STOP_CFG			S5PC1XX_PWRREG(0x14)
+#define S5PC100_SLEEP_CFG			S5PC1XX_PWRREG(0x18)
+#define S5PC100_STOP_MEM_CFG			S5PC1XX_PWRREG(0x1C)
+#define S5PC100_OSC_FREQ			S5PC1XX_PWRREG(0x100)
+#define S5PC100_OSC_STABLE			S5PC1XX_PWRREG(0x104)
+#define S5PC100_PWR_STABLE			S5PC1XX_PWRREG(0x108)
+#define S5PC100_MTC_STABLE			S5PC1XX_PWRREG(0x110)
+#define S5PC100_CLAMP_STABLE			S5PC1XX_PWRREG(0x114)
+#define S5PC100_OTHERS				S5PC1XX_PWRREG(0x200)
+#define S5PC100_RST_STAT			S5PC1XX_PWRREG(0x300)
+#define S5PC100_WAKEUP_STAT			S5PC1XX_PWRREG(0x304)
+#define S5PC100_BLK_PWR_STAT			S5PC1XX_PWRREG(0x308)
+#define S5PC100_INFORM0				S5PC1XX_PWRREG(0x400)
+#define S5PC100_INFORM1				S5PC1XX_PWRREG(0x404)
+#define S5PC100_INFORM2				S5PC1XX_PWRREG(0x408)
+#define S5PC100_INFORM3				S5PC1XX_PWRREG(0x40C)
+#define S5PC100_INFORM4				S5PC1XX_PWRREG(0x410)
+#define S5PC100_INFORM5				S5PC1XX_PWRREG(0x414)
+#define S5PC100_INFORM6				S5PC1XX_PWRREG(0x418)
+#define S5PC100_INFORM7				S5PC1XX_PWRREG(0x41C)
+#define S5PC100_DCGIDX_MAP0			S5PC1XX_PWRREG(0x500)
+#define S5PC100_DCGIDX_MAP1			S5PC1XX_PWRREG(0x504)
+#define S5PC100_DCGIDX_MAP2			S5PC1XX_PWRREG(0x508)
+#define S5PC100_DCGPERF_MAP0			S5PC1XX_PWRREG(0x50C)
+#define S5PC100_DCGPERF_MAP1			S5PC1XX_PWRREG(0x510)
+#define S5PC100_DVCIDX_MAP			S5PC1XX_PWRREG(0x514)
+#define S5PC100_FREQ_CPU			S5PC1XX_PWRREG(0x518)
+#define S5PC100_FREQ_DPM			S5PC1XX_PWRREG(0x51C)
+#define S5PC100_DVSEMCLK_EN			S5PC1XX_PWRREG(0x520)
+#define S5PC100_APLL_CON_L8			S5PC1XX_PWRREG(0x600)
+#define S5PC100_APLL_CON_L7			S5PC1XX_PWRREG(0x604)
+#define S5PC100_APLL_CON_L6			S5PC1XX_PWRREG(0x608)
+#define S5PC100_APLL_CON_L5			S5PC1XX_PWRREG(0x60C)
+#define S5PC100_APLL_CON_L4			S5PC1XX_PWRREG(0x610)
+#define S5PC100_APLL_CON_L3			S5PC1XX_PWRREG(0x614)
+#define S5PC100_APLL_CON_L2			S5PC1XX_PWRREG(0x618)
+#define S5PC100_APLL_CON_L1			S5PC1XX_PWRREG(0x61C)
+#define S5PC100_IEM_CONTROL			S5PC1XX_PWRREG(0x620)
+#define S5PC100_CLKDIV_IEM_L8			S5PC1XX_PWRREG(0x700)
+#define S5PC100_CLKDIV_IEM_L7			S5PC1XX_PWRREG(0x704)
+#define S5PC100_CLKDIV_IEM_L6			S5PC1XX_PWRREG(0x708)
+#define S5PC100_CLKDIV_IEM_L5			S5PC1XX_PWRREG(0x70C)
+#define S5PC100_CLKDIV_IEM_L4			S5PC1XX_PWRREG(0x710)
+#define S5PC100_CLKDIV_IEM_L3			S5PC1XX_PWRREG(0x714)
+#define S5PC100_CLKDIV_IEM_L2			S5PC1XX_PWRREG(0x718)
+#define S5PC100_CLKDIV_IEM_L1			S5PC1XX_PWRREG(0x71C)
+#define S5PC100_IEM_HPMCLK_DIV			S5PC1XX_PWRREG(0x724)
+
+/* PWR_CFG */
+#define S5PC100_PWRCFG_CFG_DEEP_IDLE		(1 << 31)
+#define S5PC100_PWRCFG_CFG_WFI_MASK		(3 << 5)
+#define S5PC100_PWRCFG_CFG_WFI_IDLE		(0 << 5)
+#define S5PC100_PWRCFG_CFG_WFI_DEEP_IDLE	(1 << 5)
+#define S5PC100_PWRCFG_CFG_WFI_STOP		(2 << 5)
+#define S5PC100_PWRCFG_CFG_WFI_SLEEP		(3 << 5)
+
+/* SLEEP_CFG */
+#define S5PC100_SLEEP_OSC_EN_SLEEP		(1 << 0)
+
+/* OTHERS */
+#define S5PC100_PMU_INT_DISABLE			(1 << 24)
+
+#endif /* __ASM_ARM_REGS_PWR */
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 09/17] ARM: S5PC1xx: add platform helpers for s3c-fb device
  2009-10-13  8:11                 ` Marek Szyprowski
@ 2009-10-13  8:11                   ` Marek Szyprowski
  -1 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: kyungmin.park, bhmin, ben-linux, m.szyprowski

Samsung S5PC100 has LCD-controller compatible with the one known from
previous SoCs series. Add required platform setup and support code that
it can be used with s3c-fb driver.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/include/mach/irqs.h    |    5 +
 arch/arm/mach-s5pc100/include/mach/regs-fb.h |  259 ++++++++++++++++++++++++++
 arch/arm/plat-s3c/include/plat/fb.h          |    7 +
 arch/arm/plat-s5pc1xx/Kconfig                |    5 +
 arch/arm/plat-s5pc1xx/Makefile               |    1 +
 arch/arm/plat-s5pc1xx/setup-fb-24bpp.c       |   49 +++++
 6 files changed, 326 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-s5pc100/include/mach/regs-fb.h
 create mode 100644 arch/arm/plat-s5pc1xx/setup-fb-24bpp.c

diff --git a/arch/arm/mach-s5pc100/include/mach/irqs.h b/arch/arm/mach-s5pc100/include/mach/irqs.h
index 622720d..b53fa48 100644
--- a/arch/arm/mach-s5pc100/include/mach/irqs.h
+++ b/arch/arm/mach-s5pc100/include/mach/irqs.h
@@ -11,4 +11,9 @@
 
 #include <plat/irqs.h>
 
+/* LCD */
+#define IRQ_LCD_FIFO		IRQ_LCD0
+#define IRQ_LCD_VSYNC		IRQ_LCD1
+#define IRQ_LCD_SYSTEM		IRQ_LCD2
+
 #endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/regs-fb.h b/arch/arm/mach-s5pc100/include/mach/regs-fb.h
new file mode 100644
index 0000000..4701979
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/regs-fb.h
@@ -0,0 +1,259 @@
+/* arch/arm/mach-s3c6400/include/mach/regs-fb.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      http://armlinux.simtec.co.uk/
+ *      Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - new-style framebuffer register definitions
+ *
+ * This is the register set for the new style framebuffer interface
+ * found from the S3C2443 onwards and specifically the S3C64XX series
+ * S3C6400 and S3C6410.
+ *
+ * The file contains the cpu specific items which change between whichever
+ * architecture is selected. See <plat/regs-fb.h> for the core definitions
+ * that are the same.
+ *
+ * This program is free software; you can 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 the core definitions here, in case we really do need to
+ * override them at a later date.
+*/
+
+#include <plat/regs-fb.h>
+
+#define S3C_FB_MAX_WIN (5)  /* number of hardware windows available. */
+#define VIDCON1_FSTATUS_EVEN	(1 << 15)
+
+/* Video timing controls */
+#define VIDTCON0				(0x10)
+#define VIDTCON1				(0x14)
+#define VIDTCON2				(0x18)
+
+/* Window position controls */
+
+#define WINCON(_win)				(0x20 + ((_win) * 4))
+
+/* OSD1 and OSD4 do not have register D */
+
+#define VIDOSD_A(_win)				(0x40 + ((_win) * 16))
+#define VIDOSD_B(_win)				(0x44 + ((_win) * 16))
+#define VIDOSD_C(_win)				(0x48 + ((_win) * 16))
+#define VIDOSD_D(_win)				(0x4C + ((_win) * 16))
+
+/* Video buffer addresses */
+
+#define VIDW_BUF_START(_buff)			(0xA0 + ((_buff) * 8))
+#define VIDW_BUF_START1(_buff)			(0xA4 + ((_buff) * 8))
+#define VIDW_BUF_END(_buff)			(0xD0 + ((_buff) * 8))
+#define VIDW_BUF_END1(_buff)			(0xD4 + ((_buff) * 8))
+#define VIDW_BUF_SIZE(_buff)			(0x100 + ((_buff) * 4))
+
+#define VIDINTCON0				(0x130)
+
+#define WxKEYCONy(_win, _con)			((0x140 + ((_win) * 8)) + ((_con) * 4))
+
+/* WINCONx */
+
+#define WINCONx_CSCWIDTH_MASK			(0x3 << 26)
+#define WINCONx_CSCWIDTH_SHIFT			(26)
+#define WINCONx_CSCWIDTH_WIDE			(0x0 << 26)
+#define WINCONx_CSCWIDTH_NARROW			(0x3 << 26)
+
+#define WINCONx_ENLOCAL				(1 << 22)
+#define WINCONx_BUFSTATUS			(1 << 21)
+#define WINCONx_BUFSEL				(1 << 20)
+#define WINCONx_BUFAUTOEN			(1 << 19)
+#define WINCONx_YCbCr				(1 << 13)
+
+#define WINCON1_LOCALSEL_CAMIF			(1 << 23)
+
+#define WINCON2_LOCALSEL_CAMIF			(1 << 23)
+#define WINCON2_BLD_PIX				(1 << 6)
+
+#define WINCON2_ALPHA_SEL			(1 << 1)
+#define WINCON2_BPPMODE_MASK			(0xf << 2)
+#define WINCON2_BPPMODE_SHIFT			(2)
+#define WINCON2_BPPMODE_1BPP			(0x0 << 2)
+#define WINCON2_BPPMODE_2BPP			(0x1 << 2)
+#define WINCON2_BPPMODE_4BPP			(0x2 << 2)
+#define WINCON2_BPPMODE_8BPP_1232		(0x4 << 2)
+#define WINCON2_BPPMODE_16BPP_565		(0x5 << 2)
+#define WINCON2_BPPMODE_16BPP_A1555		(0x6 << 2)
+#define WINCON2_BPPMODE_16BPP_I1555		(0x7 << 2)
+#define WINCON2_BPPMODE_18BPP_666		(0x8 << 2)
+#define WINCON2_BPPMODE_18BPP_A1665		(0x9 << 2)
+#define WINCON2_BPPMODE_19BPP_A1666		(0xa << 2)
+#define WINCON2_BPPMODE_24BPP_888		(0xb << 2)
+#define WINCON2_BPPMODE_24BPP_A1887		(0xc << 2)
+#define WINCON2_BPPMODE_25BPP_A1888		(0xd << 2)
+#define WINCON2_BPPMODE_28BPP_A4888		(0xd << 2)
+
+#define WINCON3_BLD_PIX				(1 << 6)
+
+#define WINCON3_ALPHA_SEL			(1 << 1)
+#define WINCON3_BPPMODE_MASK			(0xf << 2)
+#define WINCON3_BPPMODE_SHIFT			(2)
+#define WINCON3_BPPMODE_1BPP			(0x0 << 2)
+#define WINCON3_BPPMODE_2BPP			(0x1 << 2)
+#define WINCON3_BPPMODE_4BPP			(0x2 << 2)
+#define WINCON3_BPPMODE_16BPP_565		(0x5 << 2)
+#define WINCON3_BPPMODE_16BPP_A1555		(0x6 << 2)
+#define WINCON3_BPPMODE_16BPP_I1555		(0x7 << 2)
+#define WINCON3_BPPMODE_18BPP_666		(0x8 << 2)
+#define WINCON3_BPPMODE_18BPP_A1665		(0x9 << 2)
+#define WINCON3_BPPMODE_19BPP_A1666		(0xa << 2)
+#define WINCON3_BPPMODE_24BPP_888		(0xb << 2)
+#define WINCON3_BPPMODE_24BPP_A1887		(0xc << 2)
+#define WINCON3_BPPMODE_25BPP_A1888		(0xd << 2)
+#define WINCON3_BPPMODE_28BPP_A4888		(0xd << 2)
+
+#define VIDINTCON0_FIFIOSEL_WINDOW2		(0x10 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW3		(0x20 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW4		(0x40 << 5)
+
+#define DITHMODE				(0x170)
+#define WINxMAP(_win)				(0x180 + ((_win) * 4))
+
+
+#define DITHMODE_R_POS_MASK			(0x3 << 5)
+#define DITHMODE_R_POS_SHIFT			(5)
+#define DITHMODE_R_POS_8BIT			(0x0 << 5)
+#define DITHMODE_R_POS_6BIT			(0x1 << 5)
+#define DITHMODE_R_POS_5BIT			(0x2 << 5)
+
+#define DITHMODE_G_POS_MASK			(0x3 << 3)
+#define DITHMODE_G_POS_SHIFT			(3)
+#define DITHMODE_G_POS_8BIT			(0x0 << 3)
+#define DITHMODE_G_POS_6BIT			(0x1 << 3)
+#define DITHMODE_G_POS_5BIT			(0x2 << 3)
+
+#define DITHMODE_B_POS_MASK			(0x3 << 1)
+#define DITHMODE_B_POS_SHIFT			(1)
+#define DITHMODE_B_POS_8BIT			(0x0 << 1)
+#define DITHMODE_B_POS_6BIT			(0x1 << 1)
+#define DITHMODE_B_POS_5BIT			(0x2 << 1)
+
+#define DITHMODE_DITH_EN			(1 << 0)
+
+#define WPALCON					(0x1A0)
+
+#define WPALCON_W4PAL_16BPP_A555		(1 << 8)
+#define WPALCON_W3PAL_16BPP_A555		(1 << 7)
+#define WPALCON_W2PAL_16BPP_A555		(1 << 6)
+
+/* Palette registers */
+
+#define WIN2_PAL(_entry)			(0x300 + ((_entry) * 2))
+#define WIN3_PAL(_entry)			(0x320 + ((_entry) * 2))
+#define WIN4_PAL(_entry)			(0x340 + ((_entry) * 2))
+#define WIN0_PAL(_entry)			(0x400 + ((_entry) * 4))
+#define WIN1_PAL(_entry)			(0x800 + ((_entry) * 4))
+
+/* system specific implementation code for palette sizes, and other
+ * information that changes depending on which architecture is being
+ * compiled.
+*/
+
+/* return true if window _win has OSD register D */
+#define s3c_fb_has_osd_d(_win) ((_win) != 4 && (_win) != 0)
+
+static inline unsigned int s3c_fb_win_pal_size(unsigned int win)
+{
+	if (win < 2)
+		return 256;
+	if (win < 4)
+		return 16;
+	if (win == 4)
+		return 4;
+
+	BUG();	/* shouldn't get here */
+}
+
+static inline int s3c_fb_validate_win_bpp(unsigned int win, unsigned int bpp)
+{
+	/* all windows can do 1/2 bpp */
+
+	if ((bpp == 25 || bpp == 19) && win == 0)
+		return 0;	/* win 0 does not have 19 or 25bpp modes */
+
+	if (bpp == 4 && win == 4)
+		return 0;
+
+	if (bpp == 8 && (win >= 3))
+		return 0;	/* win 3/4 cannot do 8bpp in any mode */
+
+	return 1;
+}
+
+static inline unsigned int s3c_fb_pal_reg(unsigned int window, int reg)
+{
+	switch (window) {
+	case 0: return WIN0_PAL(reg);
+	case 1: return WIN1_PAL(reg);
+	case 2: return WIN2_PAL(reg);
+	case 3: return WIN3_PAL(reg);
+	case 4: return WIN4_PAL(reg);
+	}
+
+	BUG();
+}
+
+static inline int s3c_fb_pal_is16(unsigned int window)
+{
+	return window > 1;
+}
+
+struct s3c_fb_palette {
+	struct fb_bitfield	r;
+	struct fb_bitfield	g;
+	struct fb_bitfield	b;
+	struct fb_bitfield	a;
+};
+
+static inline void s3c_fb_init_palette(unsigned int window,
+				       struct s3c_fb_palette *palette)
+{
+	if (window < 2) {
+		/* Windows 0/1 are 8/8/8 or A/8/8/8 */
+		palette->r.offset = 16;
+		palette->r.length = 8;
+		palette->g.offset = 8;
+		palette->g.length = 8;
+		palette->b.offset = 0;
+		palette->b.length = 8;
+	} else {
+		/* currently we assume RGB 5/6/5 */
+		palette->r.offset = 11;
+		palette->r.length = 5;
+		palette->g.offset = 5;
+		palette->g.length = 6;
+		palette->b.offset = 0;
+		palette->b.length = 5;
+	}
+}
+
+/* Notes on per-window bpp settings
+ *
+ * Value	Win0	 Win1	  Win2	   Win3	    Win 4
+ * 0000		1(P)	 1(P)	  1(P)	   1(P)	    1(P)
+ * 0001		2(P)	 2(P)     2(P)	   2(P)	    2(P)
+ * 0010		4(P)	 4(P)     4(P)	   4(P)     -none-
+ * 0011		8(P)	 8(P)     -none-   -none-   -none-
+ * 0100		-none-	 8(A232)  8(A232)  -none-   -none-
+ * 0101		16(565)	 16(565)  16(565)  16(565)   16(565)
+ * 0110		-none-	 16(A555) 16(A555) 16(A555)  16(A555)
+ * 0111		16(I555) 16(I565) 16(I555) 16(I555)  16(I555)
+ * 1000		18(666)	 18(666)  18(666)  18(666)   18(666)
+ * 1001		-none-	 18(A665) 18(A665) 18(A665)  16(A665)
+ * 1010		-none-	 19(A666) 19(A666) 19(A666)  19(A666)
+ * 1011		24(888)	 24(888)  24(888)  24(888)   24(888)
+ * 1100		-none-	 24(A887) 24(A887) 24(A887)  24(A887)
+ * 1101		-none-	 25(A888) 25(A888) 25(A888)  25(A888)
+ * 1110		-none-	 -none-	  -none-   -none-    -none-
+ * 1111		-none-	 -none-   -none-   -none-    -none-
+*/
diff --git a/arch/arm/plat-s3c/include/plat/fb.h b/arch/arm/plat-s3c/include/plat/fb.h
index 214ff56..f8db879 100644
--- a/arch/arm/plat-s3c/include/plat/fb.h
+++ b/arch/arm/plat-s3c/include/plat/fb.h
@@ -70,4 +70,11 @@ extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd);
  */
 extern void s3c64xx_fb_gpio_setup_24bpp(void);
 
+/**
+ * s5pc100_fb_gpio_setup_24bpp() - S5PC100 setup function for 24bpp LCD
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
+ */
+extern void s5pc100_fb_gpio_setup_24bpp(void);
+
 #endif /* __PLAT_S3C_FB_H */
diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig
index 86edd27..6ac48a6 100644
--- a/arch/arm/plat-s5pc1xx/Kconfig
+++ b/arch/arm/plat-s5pc1xx/Kconfig
@@ -37,6 +37,11 @@ config CPU_S5PC100_CLOCK
 
 # platform specific device setup
 
+config S5PC1XX_SETUP_FB_24BPP
+	bool
+	help
+          Common setup code for S5PC1XX with an 24bpp RGB display helper.
+
 config S5PC100_SETUP_I2C0
 	bool
 	default y
diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile
index f126951..34c8da5 100644
--- a/arch/arm/plat-s5pc1xx/Makefile
+++ b/arch/arm/plat-s5pc1xx/Makefile
@@ -24,5 +24,6 @@ obj-$(CONFIG_CPU_S5PC100_CLOCK)	+= s5pc100-clock.o
 
 # Device setup
 
+obj-$(CONFIG_S5PC1XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
 obj-$(CONFIG_S5PC100_SETUP_I2C0) += setup-i2c0.o
 obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o
diff --git a/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c b/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c
new file mode 100644
index 0000000..b63f33e
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c
@@ -0,0 +1,49 @@
+/*
+ * linux/arch/arm/plat-s5pc100/setup-fb-24bpp.c
+ *
+ * Copyright 2009 Samsung Electronics
+ *
+ * Base S5PC1XX setup information for 24bpp LCD framebuffer
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+
+#include <mach/regs-fb.h>
+#include <mach/gpio.h>
+#include <mach/map.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-s5pc1xx.h>
+
+#define DISR_OFFSET	0x7008
+
+void s5pc100_fb_gpio_setup_24bpp(void)
+{
+	unsigned int gpio = 0;
+
+	for (gpio = S5PC100_GPF0(0); gpio <= S5PC100_GPF0(7); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	for (gpio = S5PC100_GPF1(0); gpio <= S5PC100_GPF1(7); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	for (gpio = S5PC100_GPF2(0); gpio <= S5PC100_GPF2(7); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	for (gpio = S5PC100_GPF3(0); gpio <= S5PC100_GPF3(3); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+}
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 09/17] ARM: S5PC1xx: add platform helpers for s3c-fb device
@ 2009-10-13  8:11                   ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

Samsung S5PC100 has LCD-controller compatible with the one known from
previous SoCs series. Add required platform setup and support code that
it can be used with s3c-fb driver.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/include/mach/irqs.h    |    5 +
 arch/arm/mach-s5pc100/include/mach/regs-fb.h |  259 ++++++++++++++++++++++++++
 arch/arm/plat-s3c/include/plat/fb.h          |    7 +
 arch/arm/plat-s5pc1xx/Kconfig                |    5 +
 arch/arm/plat-s5pc1xx/Makefile               |    1 +
 arch/arm/plat-s5pc1xx/setup-fb-24bpp.c       |   49 +++++
 6 files changed, 326 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-s5pc100/include/mach/regs-fb.h
 create mode 100644 arch/arm/plat-s5pc1xx/setup-fb-24bpp.c

diff --git a/arch/arm/mach-s5pc100/include/mach/irqs.h b/arch/arm/mach-s5pc100/include/mach/irqs.h
index 622720d..b53fa48 100644
--- a/arch/arm/mach-s5pc100/include/mach/irqs.h
+++ b/arch/arm/mach-s5pc100/include/mach/irqs.h
@@ -11,4 +11,9 @@
 
 #include <plat/irqs.h>
 
+/* LCD */
+#define IRQ_LCD_FIFO		IRQ_LCD0
+#define IRQ_LCD_VSYNC		IRQ_LCD1
+#define IRQ_LCD_SYSTEM		IRQ_LCD2
+
 #endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/regs-fb.h b/arch/arm/mach-s5pc100/include/mach/regs-fb.h
new file mode 100644
index 0000000..4701979
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/regs-fb.h
@@ -0,0 +1,259 @@
+/* arch/arm/mach-s3c6400/include/mach/regs-fb.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      http://armlinux.simtec.co.uk/
+ *      Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - new-style framebuffer register definitions
+ *
+ * This is the register set for the new style framebuffer interface
+ * found from the S3C2443 onwards and specifically the S3C64XX series
+ * S3C6400 and S3C6410.
+ *
+ * The file contains the cpu specific items which change between whichever
+ * architecture is selected. See <plat/regs-fb.h> for the core definitions
+ * that are the same.
+ *
+ * This program is free software; you can 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 the core definitions here, in case we really do need to
+ * override them at a later date.
+*/
+
+#include <plat/regs-fb.h>
+
+#define S3C_FB_MAX_WIN (5)  /* number of hardware windows available. */
+#define VIDCON1_FSTATUS_EVEN	(1 << 15)
+
+/* Video timing controls */
+#define VIDTCON0				(0x10)
+#define VIDTCON1				(0x14)
+#define VIDTCON2				(0x18)
+
+/* Window position controls */
+
+#define WINCON(_win)				(0x20 + ((_win) * 4))
+
+/* OSD1 and OSD4 do not have register D */
+
+#define VIDOSD_A(_win)				(0x40 + ((_win) * 16))
+#define VIDOSD_B(_win)				(0x44 + ((_win) * 16))
+#define VIDOSD_C(_win)				(0x48 + ((_win) * 16))
+#define VIDOSD_D(_win)				(0x4C + ((_win) * 16))
+
+/* Video buffer addresses */
+
+#define VIDW_BUF_START(_buff)			(0xA0 + ((_buff) * 8))
+#define VIDW_BUF_START1(_buff)			(0xA4 + ((_buff) * 8))
+#define VIDW_BUF_END(_buff)			(0xD0 + ((_buff) * 8))
+#define VIDW_BUF_END1(_buff)			(0xD4 + ((_buff) * 8))
+#define VIDW_BUF_SIZE(_buff)			(0x100 + ((_buff) * 4))
+
+#define VIDINTCON0				(0x130)
+
+#define WxKEYCONy(_win, _con)			((0x140 + ((_win) * 8)) + ((_con) * 4))
+
+/* WINCONx */
+
+#define WINCONx_CSCWIDTH_MASK			(0x3 << 26)
+#define WINCONx_CSCWIDTH_SHIFT			(26)
+#define WINCONx_CSCWIDTH_WIDE			(0x0 << 26)
+#define WINCONx_CSCWIDTH_NARROW			(0x3 << 26)
+
+#define WINCONx_ENLOCAL				(1 << 22)
+#define WINCONx_BUFSTATUS			(1 << 21)
+#define WINCONx_BUFSEL				(1 << 20)
+#define WINCONx_BUFAUTOEN			(1 << 19)
+#define WINCONx_YCbCr				(1 << 13)
+
+#define WINCON1_LOCALSEL_CAMIF			(1 << 23)
+
+#define WINCON2_LOCALSEL_CAMIF			(1 << 23)
+#define WINCON2_BLD_PIX				(1 << 6)
+
+#define WINCON2_ALPHA_SEL			(1 << 1)
+#define WINCON2_BPPMODE_MASK			(0xf << 2)
+#define WINCON2_BPPMODE_SHIFT			(2)
+#define WINCON2_BPPMODE_1BPP			(0x0 << 2)
+#define WINCON2_BPPMODE_2BPP			(0x1 << 2)
+#define WINCON2_BPPMODE_4BPP			(0x2 << 2)
+#define WINCON2_BPPMODE_8BPP_1232		(0x4 << 2)
+#define WINCON2_BPPMODE_16BPP_565		(0x5 << 2)
+#define WINCON2_BPPMODE_16BPP_A1555		(0x6 << 2)
+#define WINCON2_BPPMODE_16BPP_I1555		(0x7 << 2)
+#define WINCON2_BPPMODE_18BPP_666		(0x8 << 2)
+#define WINCON2_BPPMODE_18BPP_A1665		(0x9 << 2)
+#define WINCON2_BPPMODE_19BPP_A1666		(0xa << 2)
+#define WINCON2_BPPMODE_24BPP_888		(0xb << 2)
+#define WINCON2_BPPMODE_24BPP_A1887		(0xc << 2)
+#define WINCON2_BPPMODE_25BPP_A1888		(0xd << 2)
+#define WINCON2_BPPMODE_28BPP_A4888		(0xd << 2)
+
+#define WINCON3_BLD_PIX				(1 << 6)
+
+#define WINCON3_ALPHA_SEL			(1 << 1)
+#define WINCON3_BPPMODE_MASK			(0xf << 2)
+#define WINCON3_BPPMODE_SHIFT			(2)
+#define WINCON3_BPPMODE_1BPP			(0x0 << 2)
+#define WINCON3_BPPMODE_2BPP			(0x1 << 2)
+#define WINCON3_BPPMODE_4BPP			(0x2 << 2)
+#define WINCON3_BPPMODE_16BPP_565		(0x5 << 2)
+#define WINCON3_BPPMODE_16BPP_A1555		(0x6 << 2)
+#define WINCON3_BPPMODE_16BPP_I1555		(0x7 << 2)
+#define WINCON3_BPPMODE_18BPP_666		(0x8 << 2)
+#define WINCON3_BPPMODE_18BPP_A1665		(0x9 << 2)
+#define WINCON3_BPPMODE_19BPP_A1666		(0xa << 2)
+#define WINCON3_BPPMODE_24BPP_888		(0xb << 2)
+#define WINCON3_BPPMODE_24BPP_A1887		(0xc << 2)
+#define WINCON3_BPPMODE_25BPP_A1888		(0xd << 2)
+#define WINCON3_BPPMODE_28BPP_A4888		(0xd << 2)
+
+#define VIDINTCON0_FIFIOSEL_WINDOW2		(0x10 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW3		(0x20 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW4		(0x40 << 5)
+
+#define DITHMODE				(0x170)
+#define WINxMAP(_win)				(0x180 + ((_win) * 4))
+
+
+#define DITHMODE_R_POS_MASK			(0x3 << 5)
+#define DITHMODE_R_POS_SHIFT			(5)
+#define DITHMODE_R_POS_8BIT			(0x0 << 5)
+#define DITHMODE_R_POS_6BIT			(0x1 << 5)
+#define DITHMODE_R_POS_5BIT			(0x2 << 5)
+
+#define DITHMODE_G_POS_MASK			(0x3 << 3)
+#define DITHMODE_G_POS_SHIFT			(3)
+#define DITHMODE_G_POS_8BIT			(0x0 << 3)
+#define DITHMODE_G_POS_6BIT			(0x1 << 3)
+#define DITHMODE_G_POS_5BIT			(0x2 << 3)
+
+#define DITHMODE_B_POS_MASK			(0x3 << 1)
+#define DITHMODE_B_POS_SHIFT			(1)
+#define DITHMODE_B_POS_8BIT			(0x0 << 1)
+#define DITHMODE_B_POS_6BIT			(0x1 << 1)
+#define DITHMODE_B_POS_5BIT			(0x2 << 1)
+
+#define DITHMODE_DITH_EN			(1 << 0)
+
+#define WPALCON					(0x1A0)
+
+#define WPALCON_W4PAL_16BPP_A555		(1 << 8)
+#define WPALCON_W3PAL_16BPP_A555		(1 << 7)
+#define WPALCON_W2PAL_16BPP_A555		(1 << 6)
+
+/* Palette registers */
+
+#define WIN2_PAL(_entry)			(0x300 + ((_entry) * 2))
+#define WIN3_PAL(_entry)			(0x320 + ((_entry) * 2))
+#define WIN4_PAL(_entry)			(0x340 + ((_entry) * 2))
+#define WIN0_PAL(_entry)			(0x400 + ((_entry) * 4))
+#define WIN1_PAL(_entry)			(0x800 + ((_entry) * 4))
+
+/* system specific implementation code for palette sizes, and other
+ * information that changes depending on which architecture is being
+ * compiled.
+*/
+
+/* return true if window _win has OSD register D */
+#define s3c_fb_has_osd_d(_win) ((_win) != 4 && (_win) != 0)
+
+static inline unsigned int s3c_fb_win_pal_size(unsigned int win)
+{
+	if (win < 2)
+		return 256;
+	if (win < 4)
+		return 16;
+	if (win == 4)
+		return 4;
+
+	BUG();	/* shouldn't get here */
+}
+
+static inline int s3c_fb_validate_win_bpp(unsigned int win, unsigned int bpp)
+{
+	/* all windows can do 1/2 bpp */
+
+	if ((bpp == 25 || bpp == 19) && win == 0)
+		return 0;	/* win 0 does not have 19 or 25bpp modes */
+
+	if (bpp == 4 && win == 4)
+		return 0;
+
+	if (bpp == 8 && (win >= 3))
+		return 0;	/* win 3/4 cannot do 8bpp in any mode */
+
+	return 1;
+}
+
+static inline unsigned int s3c_fb_pal_reg(unsigned int window, int reg)
+{
+	switch (window) {
+	case 0: return WIN0_PAL(reg);
+	case 1: return WIN1_PAL(reg);
+	case 2: return WIN2_PAL(reg);
+	case 3: return WIN3_PAL(reg);
+	case 4: return WIN4_PAL(reg);
+	}
+
+	BUG();
+}
+
+static inline int s3c_fb_pal_is16(unsigned int window)
+{
+	return window > 1;
+}
+
+struct s3c_fb_palette {
+	struct fb_bitfield	r;
+	struct fb_bitfield	g;
+	struct fb_bitfield	b;
+	struct fb_bitfield	a;
+};
+
+static inline void s3c_fb_init_palette(unsigned int window,
+				       struct s3c_fb_palette *palette)
+{
+	if (window < 2) {
+		/* Windows 0/1 are 8/8/8 or A/8/8/8 */
+		palette->r.offset = 16;
+		palette->r.length = 8;
+		palette->g.offset = 8;
+		palette->g.length = 8;
+		palette->b.offset = 0;
+		palette->b.length = 8;
+	} else {
+		/* currently we assume RGB 5/6/5 */
+		palette->r.offset = 11;
+		palette->r.length = 5;
+		palette->g.offset = 5;
+		palette->g.length = 6;
+		palette->b.offset = 0;
+		palette->b.length = 5;
+	}
+}
+
+/* Notes on per-window bpp settings
+ *
+ * Value	Win0	 Win1	  Win2	   Win3	    Win 4
+ * 0000		1(P)	 1(P)	  1(P)	   1(P)	    1(P)
+ * 0001		2(P)	 2(P)     2(P)	   2(P)	    2(P)
+ * 0010		4(P)	 4(P)     4(P)	   4(P)     -none-
+ * 0011		8(P)	 8(P)     -none-   -none-   -none-
+ * 0100		-none-	 8(A232)  8(A232)  -none-   -none-
+ * 0101		16(565)	 16(565)  16(565)  16(565)   16(565)
+ * 0110		-none-	 16(A555) 16(A555) 16(A555)  16(A555)
+ * 0111		16(I555) 16(I565) 16(I555) 16(I555)  16(I555)
+ * 1000		18(666)	 18(666)  18(666)  18(666)   18(666)
+ * 1001		-none-	 18(A665) 18(A665) 18(A665)  16(A665)
+ * 1010		-none-	 19(A666) 19(A666) 19(A666)  19(A666)
+ * 1011		24(888)	 24(888)  24(888)  24(888)   24(888)
+ * 1100		-none-	 24(A887) 24(A887) 24(A887)  24(A887)
+ * 1101		-none-	 25(A888) 25(A888) 25(A888)  25(A888)
+ * 1110		-none-	 -none-	  -none-   -none-    -none-
+ * 1111		-none-	 -none-   -none-   -none-    -none-
+*/
diff --git a/arch/arm/plat-s3c/include/plat/fb.h b/arch/arm/plat-s3c/include/plat/fb.h
index 214ff56..f8db879 100644
--- a/arch/arm/plat-s3c/include/plat/fb.h
+++ b/arch/arm/plat-s3c/include/plat/fb.h
@@ -70,4 +70,11 @@ extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd);
  */
 extern void s3c64xx_fb_gpio_setup_24bpp(void);
 
+/**
+ * s5pc100_fb_gpio_setup_24bpp() - S5PC100 setup function for 24bpp LCD
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
+ */
+extern void s5pc100_fb_gpio_setup_24bpp(void);
+
 #endif /* __PLAT_S3C_FB_H */
diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig
index 86edd27..6ac48a6 100644
--- a/arch/arm/plat-s5pc1xx/Kconfig
+++ b/arch/arm/plat-s5pc1xx/Kconfig
@@ -37,6 +37,11 @@ config CPU_S5PC100_CLOCK
 
 # platform specific device setup
 
+config S5PC1XX_SETUP_FB_24BPP
+	bool
+	help
+          Common setup code for S5PC1XX with an 24bpp RGB display helper.
+
 config S5PC100_SETUP_I2C0
 	bool
 	default y
diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile
index f126951..34c8da5 100644
--- a/arch/arm/plat-s5pc1xx/Makefile
+++ b/arch/arm/plat-s5pc1xx/Makefile
@@ -24,5 +24,6 @@ obj-$(CONFIG_CPU_S5PC100_CLOCK)	+= s5pc100-clock.o
 
 # Device setup
 
+obj-$(CONFIG_S5PC1XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
 obj-$(CONFIG_S5PC100_SETUP_I2C0) += setup-i2c0.o
 obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o
diff --git a/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c b/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c
new file mode 100644
index 0000000..b63f33e
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c
@@ -0,0 +1,49 @@
+/*
+ * linux/arch/arm/plat-s5pc100/setup-fb-24bpp.c
+ *
+ * Copyright 2009 Samsung Electronics
+ *
+ * Base S5PC1XX setup information for 24bpp LCD framebuffer
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+
+#include <mach/regs-fb.h>
+#include <mach/gpio.h>
+#include <mach/map.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-s5pc1xx.h>
+
+#define DISR_OFFSET	0x7008
+
+void s5pc100_fb_gpio_setup_24bpp(void)
+{
+	unsigned int gpio = 0;
+
+	for (gpio = S5PC100_GPF0(0); gpio <= S5PC100_GPF0(7); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	for (gpio = S5PC100_GPF1(0); gpio <= S5PC100_GPF1(7); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	for (gpio = S5PC100_GPF2(0); gpio <= S5PC100_GPF2(7); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	for (gpio = S5PC100_GPF3(0); gpio <= S5PC100_GPF3(3); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+}
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 10/17] SMDKC100: enable S3C FrameBuffer
  2009-10-13  8:11                   ` Marek Szyprowski
@ 2009-10-13  8:11                     ` Marek Szyprowski
  -1 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: kyungmin.park, bhmin, ben-linux, m.szyprowski

Add required machine definitions for s3c-fb device.
A 800x480 lcd device (simmilar to the one known from SMDK6410 boards) has
been defined. The lcd controller is attached to GPIO lines and can be
enabled/disabled with platform-lcd driver.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/Kconfig         |    2 +
 arch/arm/mach-s5pc100/mach-smdkc100.c |   67 +++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index b1a4ba5..5e6b9a3 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -17,6 +17,8 @@ config CPU_S5PC100
 config MACH_SMDKC100
 	bool "SMDKC100"
 	select CPU_S5PC100
+	select S3C_DEV_FB
 	select S5PC1XX_SETUP_I2C1
+	select S5PC1XX_SETUP_FB_24BPP
 	help
 	  Machine support for the Samsung SMDKC100
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index 05bb20a..098956d 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -27,16 +27,21 @@
 #include <asm/mach/map.h>
 
 #include <mach/map.h>
+#include <mach/regs-fb.h>
+#include <video/platform_lcd.h>
 
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
 #include <plat/regs-serial.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-gpio.h>
 
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/s5pc100.h>
+#include <plat/fb.h>
 
 #define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
 #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
@@ -73,9 +78,65 @@ static struct s3c2410_uartcfg smdkc100_uartcfgs[] __initdata = {
 	},
 };
 
+/* LCD power controller */
+static void smdkc100_lcd_power_set(struct plat_lcd_data *pd,
+				   unsigned int power)
+{
+	/* backlight */
+	gpio_direction_output(S5PC100_GPD(0), power);
+
+	if (power) {
+		/* module reset */
+		gpio_direction_output(S5PC100_GPH0(6), 1);
+		mdelay(100);
+		gpio_direction_output(S5PC100_GPH0(6), 0);
+		mdelay(10);
+		gpio_direction_output(S5PC100_GPH0(6), 1);
+		mdelay(10);
+	}
+}
+
+static struct plat_lcd_data smdkc100_lcd_power_data = {
+	.set_power	= smdkc100_lcd_power_set,
+};
+
+static struct platform_device smdkc100_lcd_powerdev = {
+	.name			= "platform-lcd",
+	.dev.parent		= &s3c_device_fb.dev,
+	.dev.platform_data	= &smdkc100_lcd_power_data,
+};
+
+/* Frame Buffer */
+static struct s3c_fb_pd_win smdkc100_fb_win0 = {
+	/* this is to ensure we use win0 */
+	.win_mode	= {
+		.refresh	= 70,
+		.pixclock	= (8+13+3+800)*(7+5+1+480),
+		.left_margin	= 8,
+		.right_margin	= 13,
+		.upper_margin	= 7,
+		.lower_margin	= 5,
+		.hsync_len	= 3,
+		.vsync_len	= 1,
+		.xres		= 800,
+		.yres		= 480,
+	},
+	.max_bpp	= 32,
+	.default_bpp	= 16,
+};
+
+static struct s3c_fb_platdata smdkc100_lcd_pdata __initdata = {
+	.win[0]		= &smdkc100_fb_win0,
+	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+	.setup_gpio	= s5pc100_fb_gpio_setup_24bpp,
+};
+
 static struct map_desc smdkc100_iodesc[] = {};
 
 static struct platform_device *smdkc100_devices[] __initdata = {
+	&s3c_device_fb,
+	&smdkc100_lcd_powerdev,
 };
 
 static void __init smdkc100_map_io(void)
@@ -87,6 +148,12 @@ static void __init smdkc100_map_io(void)
 
 static void __init smdkc100_machine_init(void)
 {
+	s3c_fb_set_platdata(&smdkc100_lcd_pdata);
+
+	/* LCD init */
+	gpio_request(S5PC100_GPD(0), "GPD");
+	gpio_request(S5PC100_GPH0(6), "GPH0");
+	smdkc100_lcd_power_set(&smdkc100_lcd_power_data, 0);
 	platform_add_devices(smdkc100_devices, ARRAY_SIZE(smdkc100_devices));
 }
 
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 10/17] SMDKC100: enable S3C FrameBuffer
@ 2009-10-13  8:11                     ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

Add required machine definitions for s3c-fb device.
A 800x480 lcd device (simmilar to the one known from SMDK6410 boards) has
been defined. The lcd controller is attached to GPIO lines and can be
enabled/disabled with platform-lcd driver.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/Kconfig         |    2 +
 arch/arm/mach-s5pc100/mach-smdkc100.c |   67 +++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index b1a4ba5..5e6b9a3 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -17,6 +17,8 @@ config CPU_S5PC100
 config MACH_SMDKC100
 	bool "SMDKC100"
 	select CPU_S5PC100
+	select S3C_DEV_FB
 	select S5PC1XX_SETUP_I2C1
+	select S5PC1XX_SETUP_FB_24BPP
 	help
 	  Machine support for the Samsung SMDKC100
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index 05bb20a..098956d 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -27,16 +27,21 @@
 #include <asm/mach/map.h>
 
 #include <mach/map.h>
+#include <mach/regs-fb.h>
+#include <video/platform_lcd.h>
 
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
 #include <plat/regs-serial.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-gpio.h>
 
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/s5pc100.h>
+#include <plat/fb.h>
 
 #define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
 #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
@@ -73,9 +78,65 @@ static struct s3c2410_uartcfg smdkc100_uartcfgs[] __initdata = {
 	},
 };
 
+/* LCD power controller */
+static void smdkc100_lcd_power_set(struct plat_lcd_data *pd,
+				   unsigned int power)
+{
+	/* backlight */
+	gpio_direction_output(S5PC100_GPD(0), power);
+
+	if (power) {
+		/* module reset */
+		gpio_direction_output(S5PC100_GPH0(6), 1);
+		mdelay(100);
+		gpio_direction_output(S5PC100_GPH0(6), 0);
+		mdelay(10);
+		gpio_direction_output(S5PC100_GPH0(6), 1);
+		mdelay(10);
+	}
+}
+
+static struct plat_lcd_data smdkc100_lcd_power_data = {
+	.set_power	= smdkc100_lcd_power_set,
+};
+
+static struct platform_device smdkc100_lcd_powerdev = {
+	.name			= "platform-lcd",
+	.dev.parent		= &s3c_device_fb.dev,
+	.dev.platform_data	= &smdkc100_lcd_power_data,
+};
+
+/* Frame Buffer */
+static struct s3c_fb_pd_win smdkc100_fb_win0 = {
+	/* this is to ensure we use win0 */
+	.win_mode	= {
+		.refresh	= 70,
+		.pixclock	= (8+13+3+800)*(7+5+1+480),
+		.left_margin	= 8,
+		.right_margin	= 13,
+		.upper_margin	= 7,
+		.lower_margin	= 5,
+		.hsync_len	= 3,
+		.vsync_len	= 1,
+		.xres		= 800,
+		.yres		= 480,
+	},
+	.max_bpp	= 32,
+	.default_bpp	= 16,
+};
+
+static struct s3c_fb_platdata smdkc100_lcd_pdata __initdata = {
+	.win[0]		= &smdkc100_fb_win0,
+	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+	.setup_gpio	= s5pc100_fb_gpio_setup_24bpp,
+};
+
 static struct map_desc smdkc100_iodesc[] = {};
 
 static struct platform_device *smdkc100_devices[] __initdata = {
+	&s3c_device_fb,
+	&smdkc100_lcd_powerdev,
 };
 
 static void __init smdkc100_map_io(void)
@@ -87,6 +148,12 @@ static void __init smdkc100_map_io(void)
 
 static void __init smdkc100_machine_init(void)
 {
+	s3c_fb_set_platdata(&smdkc100_lcd_pdata);
+
+	/* LCD init */
+	gpio_request(S5PC100_GPD(0), "GPD");
+	gpio_request(S5PC100_GPH0(6), "GPH0");
+	smdkc100_lcd_power_set(&smdkc100_lcd_power_data, 0);
 	platform_add_devices(smdkc100_devices, ARRAY_SIZE(smdkc100_devices));
 }
 
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 11/17] drivers: fb: enable S3C FrameBuffer on S5PC1XX platform
  2009-10-13  8:11                     ` Marek Szyprowski
@ 2009-10-13  8:11                       ` Marek Szyprowski
  -1 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: kyungmin.park, bhmin, ben-linux, m.szyprowski

Samsung S5PC100 SoC has LCD display controller compatible to the one
known from S3C6410 SoCs. Enable support for s3c-fb driver also on S5PC1xx
platform.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/video/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 9bbb285..bb2c7b6 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1882,7 +1882,7 @@ config FB_TMIO_ACCELL
 
 config FB_S3C
 	tristate "Samsung S3C framebuffer support"
-	depends on FB && ARCH_S3C64XX
+	depends on FB && (ARCH_S3C64XX || ARCH_S5PC1XX)
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 11/17] drivers: fb: enable S3C FrameBuffer on S5PC1XX platform
@ 2009-10-13  8:11                       ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

Samsung S5PC100 SoC has LCD display controller compatible to the one
known from S3C6410 SoCs. Enable support for s3c-fb driver also on S5PC1xx
platform.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/video/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 9bbb285..bb2c7b6 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1882,7 +1882,7 @@ config FB_TMIO_ACCELL
 
 config FB_S3C
 	tristate "Samsung S3C framebuffer support"
-	depends on FB && ARCH_S3C64XX
+	depends on FB && (ARCH_S3C64XX || ARCH_S5PC1XX)
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 12/17] ARM: S5PC1xx: add platform helpers for i2c adapter devices
  2009-10-13  8:11                       ` Marek Szyprowski
@ 2009-10-13  8:11                         ` Marek Szyprowski
  -1 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: kyungmin.park, bhmin, ben-linux, m.szyprowski

Samsung S5PC100 has I2C bus controller compatible with the one known from
previous SoCs series. Add required platform setup and support code that
it can be used with s3c2410-i2c driver.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/cpu.c        |    4 ++++
 arch/arm/plat-s5pc1xx/Kconfig      |    4 ++--
 arch/arm/plat-s5pc1xx/Makefile     |    4 ++--
 arch/arm/plat-s5pc1xx/setup-i2c0.c |    7 ++++++-
 arch/arm/plat-s5pc1xx/setup-i2c1.c |    7 ++++++-
 5 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-s5pc100/cpu.c b/arch/arm/mach-s5pc100/cpu.c
index a23ca57..1319e3d 100644
--- a/arch/arm/mach-s5pc100/cpu.c
+++ b/arch/arm/mach-s5pc100/cpu.c
@@ -75,6 +75,10 @@ void __init s5pc100_map_io(void)
 	iotable_init(s5pc100_iodesc, ARRAY_SIZE(s5pc100_iodesc));
 
 	/* initialise device information early */
+
+	/* the i2c devices are directly compatible with s3c2440 */
+	s3c_i2c0_setname("s3c2440-i2c");
+	s3c_i2c1_setname("s3c2440-i2c");
 }
 
 void __init s5pc100_init_clocks(int xtal)
diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig
index 6ac48a6..1fc25b9 100644
--- a/arch/arm/plat-s5pc1xx/Kconfig
+++ b/arch/arm/plat-s5pc1xx/Kconfig
@@ -42,7 +42,7 @@ config S5PC1XX_SETUP_FB_24BPP
 	help
           Common setup code for S5PC1XX with an 24bpp RGB display helper.
 
-config S5PC100_SETUP_I2C0
+config S5PC1XX_SETUP_I2C0
 	bool
 	default y
 	help
@@ -51,7 +51,7 @@ config S5PC100_SETUP_I2C0
 	  Note, currently since i2c0 is always compiled, this setup helper
 	  is always compiled with it.
 
-config S5PC100_SETUP_I2C1
+config S5PC1XX_SETUP_I2C1
 	bool
 	help
 	  Common setup code for i2c bus 1.
diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile
index 34c8da5..15c800e 100644
--- a/arch/arm/plat-s5pc1xx/Makefile
+++ b/arch/arm/plat-s5pc1xx/Makefile
@@ -25,5 +25,5 @@ obj-$(CONFIG_CPU_S5PC100_CLOCK)	+= s5pc100-clock.o
 # Device setup
 
 obj-$(CONFIG_S5PC1XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
-obj-$(CONFIG_S5PC100_SETUP_I2C0) += setup-i2c0.o
-obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o
+obj-$(CONFIG_S5PC1XX_SETUP_I2C0) += setup-i2c0.o
+obj-$(CONFIG_S5PC1XX_SETUP_I2C1) += setup-i2c1.o
diff --git a/arch/arm/plat-s5pc1xx/setup-i2c0.c b/arch/arm/plat-s5pc1xx/setup-i2c0.c
index 3d00c02..09d5a2d 100644
--- a/arch/arm/plat-s5pc1xx/setup-i2c0.c
+++ b/arch/arm/plat-s5pc1xx/setup-i2c0.c
@@ -17,9 +17,14 @@
 
 struct platform_device; /* don't need the contents */
 
+#include <mach/gpio.h>
 #include <plat/iic.h>
+#include <plat/gpio-cfg.h>
 
 void s3c_i2c0_cfg_gpio(struct platform_device *dev)
 {
-	/* Pin configuration would be needed */
+	s3c_gpio_cfgpin(S5PC100_GPD(3), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PC100_GPD(3), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PC100_GPD(4), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PC100_GPD(4), S3C_GPIO_PULL_UP);
 }
diff --git a/arch/arm/plat-s5pc1xx/setup-i2c1.c b/arch/arm/plat-s5pc1xx/setup-i2c1.c
index c8f3ca4..3c13613 100644
--- a/arch/arm/plat-s5pc1xx/setup-i2c1.c
+++ b/arch/arm/plat-s5pc1xx/setup-i2c1.c
@@ -17,9 +17,14 @@
 
 struct platform_device; /* don't need the contents */
 
+#include <mach/gpio.h>
 #include <plat/iic.h>
+#include <plat/gpio-cfg.h>
 
 void s3c_i2c1_cfg_gpio(struct platform_device *dev)
 {
-	/* Pin configuration would be needed */
+	s3c_gpio_cfgpin(S5PC100_GPD(5), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PC100_GPD(5), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PC100_GPD(6), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PC100_GPD(6), S3C_GPIO_PULL_UP);
 }
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 12/17] ARM: S5PC1xx: add platform helpers for i2c adapter devices
@ 2009-10-13  8:11                         ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

Samsung S5PC100 has I2C bus controller compatible with the one known from
previous SoCs series. Add required platform setup and support code that
it can be used with s3c2410-i2c driver.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/cpu.c        |    4 ++++
 arch/arm/plat-s5pc1xx/Kconfig      |    4 ++--
 arch/arm/plat-s5pc1xx/Makefile     |    4 ++--
 arch/arm/plat-s5pc1xx/setup-i2c0.c |    7 ++++++-
 arch/arm/plat-s5pc1xx/setup-i2c1.c |    7 ++++++-
 5 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-s5pc100/cpu.c b/arch/arm/mach-s5pc100/cpu.c
index a23ca57..1319e3d 100644
--- a/arch/arm/mach-s5pc100/cpu.c
+++ b/arch/arm/mach-s5pc100/cpu.c
@@ -75,6 +75,10 @@ void __init s5pc100_map_io(void)
 	iotable_init(s5pc100_iodesc, ARRAY_SIZE(s5pc100_iodesc));
 
 	/* initialise device information early */
+
+	/* the i2c devices are directly compatible with s3c2440 */
+	s3c_i2c0_setname("s3c2440-i2c");
+	s3c_i2c1_setname("s3c2440-i2c");
 }
 
 void __init s5pc100_init_clocks(int xtal)
diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig
index 6ac48a6..1fc25b9 100644
--- a/arch/arm/plat-s5pc1xx/Kconfig
+++ b/arch/arm/plat-s5pc1xx/Kconfig
@@ -42,7 +42,7 @@ config S5PC1XX_SETUP_FB_24BPP
 	help
           Common setup code for S5PC1XX with an 24bpp RGB display helper.
 
-config S5PC100_SETUP_I2C0
+config S5PC1XX_SETUP_I2C0
 	bool
 	default y
 	help
@@ -51,7 +51,7 @@ config S5PC100_SETUP_I2C0
 	  Note, currently since i2c0 is always compiled, this setup helper
 	  is always compiled with it.
 
-config S5PC100_SETUP_I2C1
+config S5PC1XX_SETUP_I2C1
 	bool
 	help
 	  Common setup code for i2c bus 1.
diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile
index 34c8da5..15c800e 100644
--- a/arch/arm/plat-s5pc1xx/Makefile
+++ b/arch/arm/plat-s5pc1xx/Makefile
@@ -25,5 +25,5 @@ obj-$(CONFIG_CPU_S5PC100_CLOCK)	+= s5pc100-clock.o
 # Device setup
 
 obj-$(CONFIG_S5PC1XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
-obj-$(CONFIG_S5PC100_SETUP_I2C0) += setup-i2c0.o
-obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o
+obj-$(CONFIG_S5PC1XX_SETUP_I2C0) += setup-i2c0.o
+obj-$(CONFIG_S5PC1XX_SETUP_I2C1) += setup-i2c1.o
diff --git a/arch/arm/plat-s5pc1xx/setup-i2c0.c b/arch/arm/plat-s5pc1xx/setup-i2c0.c
index 3d00c02..09d5a2d 100644
--- a/arch/arm/plat-s5pc1xx/setup-i2c0.c
+++ b/arch/arm/plat-s5pc1xx/setup-i2c0.c
@@ -17,9 +17,14 @@
 
 struct platform_device; /* don't need the contents */
 
+#include <mach/gpio.h>
 #include <plat/iic.h>
+#include <plat/gpio-cfg.h>
 
 void s3c_i2c0_cfg_gpio(struct platform_device *dev)
 {
-	/* Pin configuration would be needed */
+	s3c_gpio_cfgpin(S5PC100_GPD(3), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PC100_GPD(3), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PC100_GPD(4), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PC100_GPD(4), S3C_GPIO_PULL_UP);
 }
diff --git a/arch/arm/plat-s5pc1xx/setup-i2c1.c b/arch/arm/plat-s5pc1xx/setup-i2c1.c
index c8f3ca4..3c13613 100644
--- a/arch/arm/plat-s5pc1xx/setup-i2c1.c
+++ b/arch/arm/plat-s5pc1xx/setup-i2c1.c
@@ -17,9 +17,14 @@
 
 struct platform_device; /* don't need the contents */
 
+#include <mach/gpio.h>
 #include <plat/iic.h>
+#include <plat/gpio-cfg.h>
 
 void s3c_i2c1_cfg_gpio(struct platform_device *dev)
 {
-	/* Pin configuration would be needed */
+	s3c_gpio_cfgpin(S5PC100_GPD(5), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PC100_GPD(5), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PC100_GPD(6), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PC100_GPD(6), S3C_GPIO_PULL_UP);
 }
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 13/17] SMDKC100: add I2C0 and I2C1 buses support
  2009-10-13  8:11                         ` Marek Szyprowski
@ 2009-10-13  8:11                           ` Marek Szyprowski
  -1 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: kyungmin.park, bhmin, ben-linux, m.szyprowski

Add required machine definitions for I2C 0 and 1 bus controllers.
Currently no I2C device are defined yet.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/Kconfig         |    2 ++
 arch/arm/mach-s5pc100/mach-smdkc100.c |   17 +++++++++++++++++
 2 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index 5e6b9a3..36e7e00 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -18,6 +18,8 @@ config MACH_SMDKC100
 	bool "SMDKC100"
 	select CPU_S5PC100
 	select S3C_DEV_FB
+	select S3C_DEV_I2C1
+	select S5PC1XX_SETUP_I2C0
 	select S5PC1XX_SETUP_I2C1
 	select S5PC1XX_SETUP_FB_24BPP
 	help
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index 098956d..2c0119f 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -42,6 +42,7 @@
 #include <plat/cpu.h>
 #include <plat/s5pc100.h>
 #include <plat/fb.h>
+#include <plat/iic.h>
 
 #define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
 #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
@@ -78,6 +79,14 @@ static struct s3c2410_uartcfg smdkc100_uartcfgs[] __initdata = {
 	},
 };
 
+/* I2C0 */
+static struct i2c_board_info i2c_devs0[] __initdata = {
+};
+
+/* I2C1 */
+static struct i2c_board_info i2c_devs1[] __initdata = {
+};
+
 /* LCD power controller */
 static void smdkc100_lcd_power_set(struct plat_lcd_data *pd,
 				   unsigned int power)
@@ -135,6 +144,8 @@ static struct s3c_fb_platdata smdkc100_lcd_pdata __initdata = {
 static struct map_desc smdkc100_iodesc[] = {};
 
 static struct platform_device *smdkc100_devices[] __initdata = {
+	&s3c_device_i2c0,
+	&s3c_device_i2c1,
 	&s3c_device_fb,
 	&smdkc100_lcd_powerdev,
 };
@@ -148,6 +159,12 @@ static void __init smdkc100_map_io(void)
 
 static void __init smdkc100_machine_init(void)
 {
+	/* I2C */
+	s3c_i2c0_set_platdata(NULL);
+	s3c_i2c1_set_platdata(NULL);
+	i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
+	i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+
 	s3c_fb_set_platdata(&smdkc100_lcd_pdata);
 
 	/* LCD init */
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 13/17] SMDKC100: add I2C0 and I2C1 buses support
@ 2009-10-13  8:11                           ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

Add required machine definitions for I2C 0 and 1 bus controllers.
Currently no I2C device are defined yet.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/Kconfig         |    2 ++
 arch/arm/mach-s5pc100/mach-smdkc100.c |   17 +++++++++++++++++
 2 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index 5e6b9a3..36e7e00 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -18,6 +18,8 @@ config MACH_SMDKC100
 	bool "SMDKC100"
 	select CPU_S5PC100
 	select S3C_DEV_FB
+	select S3C_DEV_I2C1
+	select S5PC1XX_SETUP_I2C0
 	select S5PC1XX_SETUP_I2C1
 	select S5PC1XX_SETUP_FB_24BPP
 	help
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index 098956d..2c0119f 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -42,6 +42,7 @@
 #include <plat/cpu.h>
 #include <plat/s5pc100.h>
 #include <plat/fb.h>
+#include <plat/iic.h>
 
 #define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
 #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
@@ -78,6 +79,14 @@ static struct s3c2410_uartcfg smdkc100_uartcfgs[] __initdata = {
 	},
 };
 
+/* I2C0 */
+static struct i2c_board_info i2c_devs0[] __initdata = {
+};
+
+/* I2C1 */
+static struct i2c_board_info i2c_devs1[] __initdata = {
+};
+
 /* LCD power controller */
 static void smdkc100_lcd_power_set(struct plat_lcd_data *pd,
 				   unsigned int power)
@@ -135,6 +144,8 @@ static struct s3c_fb_platdata smdkc100_lcd_pdata __initdata = {
 static struct map_desc smdkc100_iodesc[] = {};
 
 static struct platform_device *smdkc100_devices[] __initdata = {
+	&s3c_device_i2c0,
+	&s3c_device_i2c1,
 	&s3c_device_fb,
 	&smdkc100_lcd_powerdev,
 };
@@ -148,6 +159,12 @@ static void __init smdkc100_map_io(void)
 
 static void __init smdkc100_machine_init(void)
 {
+	/* I2C */
+	s3c_i2c0_set_platdata(NULL);
+	s3c_i2c1_set_platdata(NULL);
+	i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
+	i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+
 	s3c_fb_set_platdata(&smdkc100_lcd_pdata);
 
 	/* LCD init */
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 14/17] drivers: i2c: s3c2410-i2c also on S5PC1XX platform
  2009-10-13  8:11                           ` Marek Szyprowski
@ 2009-10-13  8:11                             ` Marek Szyprowski
  -1 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: kyungmin.park, bhmin, ben-linux, m.szyprowski

Samsung S5PC100 SoC has I2C controllers directly compatible to the one
known from S3C24x0 SoCs. Enable support for s3c-i2c driver also on S5PC1xx
platform.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/i2c/busses/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 737335f..5b173f3 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -494,7 +494,7 @@ config I2C_PXA_SLAVE
 
 config I2C_S3C2410
 	tristate "S3C2410 I2C Driver"
-	depends on ARCH_S3C2410 || ARCH_S3C64XX
+	depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC1XX
 	help
 	  Say Y here to include support for I2C controller in the
 	  Samsung S3C2410 based System-on-Chip devices.
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 14/17] drivers: i2c: s3c2410-i2c also on S5PC1XX platform
@ 2009-10-13  8:11                             ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

Samsung S5PC100 SoC has I2C controllers directly compatible to the one
known from S3C24x0 SoCs. Enable support for s3c-i2c driver also on S5PC1xx
platform.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/i2c/busses/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 737335f..5b173f3 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -494,7 +494,7 @@ config I2C_PXA_SLAVE
 
 config I2C_S3C2410
 	tristate "S3C2410 I2C Driver"
-	depends on ARCH_S3C2410 || ARCH_S3C64XX
+	depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC1XX
 	help
 	  Say Y here to include support for I2C controller in the
 	  Samsung S3C2410 based System-on-Chip devices.
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 15/17] ARM: S5PC1xx: add platform helpers for SDHCI host controllers
  2009-10-13  8:11                             ` Marek Szyprowski
@ 2009-10-13  8:11                               ` Marek Szyprowski
  -1 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: kyungmin.park, bhmin, ben-linux, m.szyprowski

Samsung S5PC100 has 3 SDHCI controllers compatible with the one known from
previous SoCs series. Add required platform setup and support code that
the devices can be used with sdhci-s3c driver.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/Kconfig            |    6 ++
 arch/arm/mach-s5pc100/Makefile           |    4 ++
 arch/arm/mach-s5pc100/cpu.c              |    3 +
 arch/arm/mach-s5pc100/setup-sdhci.c      |   63 ++++++++++++++++++++++
 arch/arm/plat-s3c/Kconfig                |    5 ++
 arch/arm/plat-s3c/Makefile               |    1 +
 arch/arm/plat-s3c/dev-hsmmc2.c           |   65 ++++++++++++++++++++++
 arch/arm/plat-s3c/include/plat/sdhci.h   |   55 +++++++++++++++++++
 arch/arm/plat-s5pc1xx/Kconfig            |    6 ++
 arch/arm/plat-s5pc1xx/Makefile           |    1 +
 arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c |   86 ++++++++++++++++++++++++++++++
 11 files changed, 295 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-s5pc100/setup-sdhci.c
 create mode 100644 arch/arm/plat-s3c/dev-hsmmc2.c
 create mode 100644 arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c

diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index 36e7e00..21b1821 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -14,6 +14,12 @@ config CPU_S5PC100
 	help
 	  Enable S5PC100 CPU support
 
+config S5PC100_SETUP_SDHCI
+        bool
+        select S5PC1XX_SETUP_SDHCI_GPIO
+        help
+          Internal helper functions for S5PC100 based SDHCI systems
+
 config MACH_SMDKC100
 	bool "SMDKC100"
 	select CPU_S5PC100
diff --git a/arch/arm/mach-s5pc100/Makefile b/arch/arm/mach-s5pc100/Makefile
index afc89b3..809ff10 100644
--- a/arch/arm/mach-s5pc100/Makefile
+++ b/arch/arm/mach-s5pc100/Makefile
@@ -13,5 +13,9 @@ obj-				:=
 
 obj-$(CONFIG_CPU_S5PC100)	+= cpu.o
 
+# Helper and device support
+
+obj-$(CONFIG_S5PC100_SETUP_SDHCI)       += setup-sdhci.o
+
 # machine support
 obj-$(CONFIG_MACH_SMDKC100)	+= mach-smdkc100.o
diff --git a/arch/arm/mach-s5pc100/cpu.c b/arch/arm/mach-s5pc100/cpu.c
index 1319e3d..d79e757 100644
--- a/arch/arm/mach-s5pc100/cpu.c
+++ b/arch/arm/mach-s5pc100/cpu.c
@@ -75,6 +75,9 @@ void __init s5pc100_map_io(void)
 	iotable_init(s5pc100_iodesc, ARRAY_SIZE(s5pc100_iodesc));
 
 	/* initialise device information early */
+	s5pc100_default_sdhci0();
+	s5pc100_default_sdhci1();
+	s5pc100_default_sdhci2();
 
 	/* the i2c devices are directly compatible with s3c2440 */
 	s3c_i2c0_setname("s3c2440-i2c");
diff --git a/arch/arm/mach-s5pc100/setup-sdhci.c b/arch/arm/mach-s5pc100/setup-sdhci.c
new file mode 100644
index 0000000..634bac3
--- /dev/null
+++ b/arch/arm/mach-s5pc100/setup-sdhci.c
@@ -0,0 +1,63 @@
+/* linux/arch/arm/mach-s5pc100/setup-sdhci.c
+ *
+ * Copyright 2008 Samsung Electronics
+ *
+ * S5PC100 - Helper functions for settign up SDHCI device(s) (HSMMC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+
+#include <plat/regs-sdhci.h>
+#include <plat/sdhci.h>
+
+/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
+
+char *s5pc100_hsmmc_clksrcs[4] = {
+	[0] = "hsmmc",
+	[1] = "hsmmc",
+	/* [2] = "mmc_bus", not yet succesfuuly used yet */
+	/* [3] = "48m", - note not succesfully used yet */
+};
+
+
+void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev,
+				    void __iomem *r,
+				    struct mmc_ios *ios,
+				    struct mmc_card *card)
+{
+	u32 ctrl2, ctrl3;
+
+	/* don't need to alter anything acording to card-type */
+
+	writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4);
+
+	ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
+	ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
+	ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
+		  S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
+		  S3C_SDHCI_CTRL2_ENFBCLKRX |
+		  S3C_SDHCI_CTRL2_DFCNT_NONE |
+		  S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
+
+	if (ios->clock < 25 * 1000000)
+		ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
+			 S3C_SDHCI_CTRL3_FCSEL2 |
+			 S3C_SDHCI_CTRL3_FCSEL1 |
+			 S3C_SDHCI_CTRL3_FCSEL0);
+	else
+		ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
+
+	writel(ctrl2, r + S3C_SDHCI_CONTROL2);
+	writel(ctrl3, r + S3C_SDHCI_CONTROL3);
+}
diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig
index f155a84..e139a72 100644
--- a/arch/arm/plat-s3c/Kconfig
+++ b/arch/arm/plat-s3c/Kconfig
@@ -184,6 +184,11 @@ config S3C_DEV_HSMMC1
 	help
 	  Compile in platform device definitions for HSMMC channel 1
 
+config S3C_DEV_HSMMC2
+	bool
+	help
+	  Compile in platform device definitions for HSMMC channel 2
+
 config S3C_DEV_I2C1
 	bool
 	help
diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile
index 3c09109..50444da 100644
--- a/arch/arm/plat-s3c/Makefile
+++ b/arch/arm/plat-s3c/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_HAVE_PWM)		+= pwm.o
 
 obj-$(CONFIG_S3C_DEV_HSMMC)	+= dev-hsmmc.o
 obj-$(CONFIG_S3C_DEV_HSMMC1)	+= dev-hsmmc1.o
+obj-$(CONFIG_S3C_DEV_HSMMC2)	+= dev-hsmmc2.o
 obj-y				+= dev-i2c0.o
 obj-$(CONFIG_S3C_DEV_I2C1)	+= dev-i2c1.o
 obj-$(CONFIG_S3C_DEV_FB)	+= dev-fb.o
diff --git a/arch/arm/plat-s3c/dev-hsmmc2.c b/arch/arm/plat-s3c/dev-hsmmc2.c
new file mode 100644
index 0000000..082e55a
--- /dev/null
+++ b/arch/arm/plat-s3c/dev-hsmmc2.c
@@ -0,0 +1,65 @@
+/* linux/arch/arm/plat-s3c/dev-hsmmc2.c
+ *
+ * Copyright (c) 2009 Samsung Electronics
+ *
+ * S3C series device definition for hsmmc device 2
+ *
+ * This program is free software; you can 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/platform_device.h>
+#include <linux/mmc/host.h>
+
+#include <mach/map.h>
+#include <plat/sdhci.h>
+#include <plat/devs.h>
+
+#define S3C_SZ_HSMMC	(0x1000)
+
+static struct resource s3c_hsmmc2_resource[] = {
+	[0] = {
+		.start = S3C_PA_HSMMC2,
+		.end   = S3C_PA_HSMMC2 + S3C_SZ_HSMMC - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_HSMMC2,
+		.end   = IRQ_HSMMC2,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+static u64 s3c_device_hsmmc2_dmamask = 0xffffffffUL;
+
+struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
+	.max_width	= 4,
+	.host_caps	= (MMC_CAP_4_BIT_DATA |
+			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+};
+
+struct platform_device s3c_device_hsmmc2 = {
+	.name		= "s3c-sdhci",
+	.id		= 2,
+	.num_resources	= ARRAY_SIZE(s3c_hsmmc2_resource),
+	.resource	= s3c_hsmmc2_resource,
+	.dev		= {
+		.dma_mask		= &s3c_device_hsmmc2_dmamask,
+		.coherent_dma_mask	= 0xffffffffUL,
+		.platform_data		= &s3c_hsmmc2_def_platdata,
+	},
+};
+
+void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+	struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata;
+
+	set->max_width = pd->max_width;
+
+	if (pd->cfg_gpio)
+		set->cfg_gpio = pd->cfg_gpio;
+	if (pd->cfg_card)
+		set->cfg_card = pd->cfg_card;
+}
diff --git a/arch/arm/plat-s3c/include/plat/sdhci.h b/arch/arm/plat-s3c/include/plat/sdhci.h
index f615308..c71d078 100644
--- a/arch/arm/plat-s3c/include/plat/sdhci.h
+++ b/arch/arm/plat-s3c/include/plat/sdhci.h
@@ -57,6 +57,7 @@ struct s3c_sdhci_platdata {
  */
 extern void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd);
 extern void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd);
+extern void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd);
 
 /* Default platform data, exported so that per-cpu initialisation can
  * set the correct one when there are more than one cpu type selected.
@@ -64,11 +65,15 @@ extern void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd);
 
 extern struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata;
 extern struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata;
+extern struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata;
 
 /* Helper function availablity */
 
 extern void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
 extern void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
+extern void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
 
 /* S3C6400 SDHCI setup */
 
@@ -145,4 +150,54 @@ static inline void s3c6410_default_sdhci0(void) { }
 static inline void s3c6410_default_sdhci1(void) { }
 #endif /* CONFIG_S3C6410_SETUP_SDHCI */
 
+/* S5PC100 SDHCI setup */
+
+#ifdef CONFIG_S5PC100_SETUP_SDHCI
+extern char *s5pc100_hsmmc_clksrcs[4];
+
+extern void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev,
+					   void __iomem *r,
+					   struct mmc_ios *ios,
+					   struct mmc_card *card);
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static inline void s5pc100_default_sdhci0(void)
+{
+	s3c_hsmmc0_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
+	s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio;
+	s3c_hsmmc0_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
+}
+#else
+static inline void s5pc100_default_sdhci0(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC */
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+static inline void s5pc100_default_sdhci1(void)
+{
+	s3c_hsmmc1_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
+	s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio;
+	s3c_hsmmc1_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
+}
+#else
+static inline void s5pc100_default_sdhci1(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC1 */
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static inline void s5pc100_default_sdhci2(void)
+{
+	s3c_hsmmc2_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
+	s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio;
+	s3c_hsmmc2_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
+}
+#else
+static inline void s5pc100_default_sdhci2(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC1 */
+
+
+#else
+static inline void s5pc100_default_sdhci0(void) { }
+static inline void s5pc100_default_sdhci1(void) { }
+static inline void s5pc100_default_sdhci2(void) { }
+#endif /* CONFIG_S5PC100_SETUP_SDHCI */
+
 #endif /* __PLAT_S3C_SDHCI_H */
diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig
index 1fc25b9..1608e62 100644
--- a/arch/arm/plat-s5pc1xx/Kconfig
+++ b/arch/arm/plat-s5pc1xx/Kconfig
@@ -55,4 +55,10 @@ config S5PC1XX_SETUP_I2C1
 	bool
 	help
 	  Common setup code for i2c bus 1.
+
+config S5PC1XX_SETUP_SDHCI_GPIO
+	bool
+	help
+	  Common setup code for SDHCI gpio.
+
 endif
diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile
index 15c800e..66a8f3e 100644
--- a/arch/arm/plat-s5pc1xx/Makefile
+++ b/arch/arm/plat-s5pc1xx/Makefile
@@ -27,3 +27,4 @@ obj-$(CONFIG_CPU_S5PC100_CLOCK)	+= s5pc100-clock.o
 obj-$(CONFIG_S5PC1XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
 obj-$(CONFIG_S5PC1XX_SETUP_I2C0) += setup-i2c0.o
 obj-$(CONFIG_S5PC1XX_SETUP_I2C1) += setup-i2c1.o
+obj-$(CONFIG_S5PC1XX_SETUP_SDHCI_GPIO)	+= setup-sdhci-gpio.o
diff --git a/arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c b/arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c
new file mode 100644
index 0000000..3577619
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c
@@ -0,0 +1,86 @@
+/* linux/arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c
+ *
+ * Copyright 2009 Samsung Eletronics
+ *
+ * S5PC1XX - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-sdhci.h>
+
+void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
+{
+	unsigned int gpio;
+	unsigned int end;
+	unsigned int num;
+
+	num = width;
+	/* In case of 8 width, we should decrease the 2 */
+	if (width == 8)
+		num = width - 2;
+
+	end = S5PC100_GPG0(2 + num);
+
+	/* Set all the necessary GPG0/GPG1 pins to special-function 0 */
+	for (gpio = S5PC100_GPG0(0); gpio < end; gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	if (width == 8) {
+		for (gpio = S5PC100_GPG1(0); gpio <= S5PC100_GPG1(1); gpio++) {
+			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+		}
+	}
+
+	s3c_gpio_setpull(S5PC100_GPG1(2), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PC100_GPG1(2), S3C_GPIO_SFN(2));
+}
+
+void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
+{
+	unsigned int gpio;
+	unsigned int end;
+
+	end = S5PC100_GPG2(2 + width);
+
+	/* Set all the necessary GPG2 pins to special-function 2 */
+	for (gpio = S5PC100_GPG2(0); gpio < end; gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	s3c_gpio_setpull(S5PC100_GPG2(6), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PC100_GPG2(6), S3C_GPIO_SFN(2));
+}
+
+void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
+{
+	unsigned int gpio;
+	unsigned int end;
+
+	end = S5PC100_GPG3(2 + width);
+
+	/* Set all the necessary GPG3 pins to special-function 2 */
+	for (gpio = S5PC100_GPG3(0); gpio < end; gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	s3c_gpio_setpull(S5PC100_GPG3(6), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PC100_GPG3(6), S3C_GPIO_SFN(2));
+}
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 15/17] ARM: S5PC1xx: add platform helpers for SDHCI host controllers
@ 2009-10-13  8:11                               ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

Samsung S5PC100 has 3 SDHCI controllers compatible with the one known from
previous SoCs series. Add required platform setup and support code that
the devices can be used with sdhci-s3c driver.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/Kconfig            |    6 ++
 arch/arm/mach-s5pc100/Makefile           |    4 ++
 arch/arm/mach-s5pc100/cpu.c              |    3 +
 arch/arm/mach-s5pc100/setup-sdhci.c      |   63 ++++++++++++++++++++++
 arch/arm/plat-s3c/Kconfig                |    5 ++
 arch/arm/plat-s3c/Makefile               |    1 +
 arch/arm/plat-s3c/dev-hsmmc2.c           |   65 ++++++++++++++++++++++
 arch/arm/plat-s3c/include/plat/sdhci.h   |   55 +++++++++++++++++++
 arch/arm/plat-s5pc1xx/Kconfig            |    6 ++
 arch/arm/plat-s5pc1xx/Makefile           |    1 +
 arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c |   86 ++++++++++++++++++++++++++++++
 11 files changed, 295 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-s5pc100/setup-sdhci.c
 create mode 100644 arch/arm/plat-s3c/dev-hsmmc2.c
 create mode 100644 arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c

diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index 36e7e00..21b1821 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -14,6 +14,12 @@ config CPU_S5PC100
 	help
 	  Enable S5PC100 CPU support
 
+config S5PC100_SETUP_SDHCI
+        bool
+        select S5PC1XX_SETUP_SDHCI_GPIO
+        help
+          Internal helper functions for S5PC100 based SDHCI systems
+
 config MACH_SMDKC100
 	bool "SMDKC100"
 	select CPU_S5PC100
diff --git a/arch/arm/mach-s5pc100/Makefile b/arch/arm/mach-s5pc100/Makefile
index afc89b3..809ff10 100644
--- a/arch/arm/mach-s5pc100/Makefile
+++ b/arch/arm/mach-s5pc100/Makefile
@@ -13,5 +13,9 @@ obj-				:=
 
 obj-$(CONFIG_CPU_S5PC100)	+= cpu.o
 
+# Helper and device support
+
+obj-$(CONFIG_S5PC100_SETUP_SDHCI)       += setup-sdhci.o
+
 # machine support
 obj-$(CONFIG_MACH_SMDKC100)	+= mach-smdkc100.o
diff --git a/arch/arm/mach-s5pc100/cpu.c b/arch/arm/mach-s5pc100/cpu.c
index 1319e3d..d79e757 100644
--- a/arch/arm/mach-s5pc100/cpu.c
+++ b/arch/arm/mach-s5pc100/cpu.c
@@ -75,6 +75,9 @@ void __init s5pc100_map_io(void)
 	iotable_init(s5pc100_iodesc, ARRAY_SIZE(s5pc100_iodesc));
 
 	/* initialise device information early */
+	s5pc100_default_sdhci0();
+	s5pc100_default_sdhci1();
+	s5pc100_default_sdhci2();
 
 	/* the i2c devices are directly compatible with s3c2440 */
 	s3c_i2c0_setname("s3c2440-i2c");
diff --git a/arch/arm/mach-s5pc100/setup-sdhci.c b/arch/arm/mach-s5pc100/setup-sdhci.c
new file mode 100644
index 0000000..634bac3
--- /dev/null
+++ b/arch/arm/mach-s5pc100/setup-sdhci.c
@@ -0,0 +1,63 @@
+/* linux/arch/arm/mach-s5pc100/setup-sdhci.c
+ *
+ * Copyright 2008 Samsung Electronics
+ *
+ * S5PC100 - Helper functions for settign up SDHCI device(s) (HSMMC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+
+#include <plat/regs-sdhci.h>
+#include <plat/sdhci.h>
+
+/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
+
+char *s5pc100_hsmmc_clksrcs[4] = {
+	[0] = "hsmmc",
+	[1] = "hsmmc",
+	/* [2] = "mmc_bus", not yet succesfuuly used yet */
+	/* [3] = "48m", - note not succesfully used yet */
+};
+
+
+void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev,
+				    void __iomem *r,
+				    struct mmc_ios *ios,
+				    struct mmc_card *card)
+{
+	u32 ctrl2, ctrl3;
+
+	/* don't need to alter anything acording to card-type */
+
+	writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4);
+
+	ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
+	ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
+	ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
+		  S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
+		  S3C_SDHCI_CTRL2_ENFBCLKRX |
+		  S3C_SDHCI_CTRL2_DFCNT_NONE |
+		  S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
+
+	if (ios->clock < 25 * 1000000)
+		ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
+			 S3C_SDHCI_CTRL3_FCSEL2 |
+			 S3C_SDHCI_CTRL3_FCSEL1 |
+			 S3C_SDHCI_CTRL3_FCSEL0);
+	else
+		ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
+
+	writel(ctrl2, r + S3C_SDHCI_CONTROL2);
+	writel(ctrl3, r + S3C_SDHCI_CONTROL3);
+}
diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig
index f155a84..e139a72 100644
--- a/arch/arm/plat-s3c/Kconfig
+++ b/arch/arm/plat-s3c/Kconfig
@@ -184,6 +184,11 @@ config S3C_DEV_HSMMC1
 	help
 	  Compile in platform device definitions for HSMMC channel 1
 
+config S3C_DEV_HSMMC2
+	bool
+	help
+	  Compile in platform device definitions for HSMMC channel 2
+
 config S3C_DEV_I2C1
 	bool
 	help
diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile
index 3c09109..50444da 100644
--- a/arch/arm/plat-s3c/Makefile
+++ b/arch/arm/plat-s3c/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_HAVE_PWM)		+= pwm.o
 
 obj-$(CONFIG_S3C_DEV_HSMMC)	+= dev-hsmmc.o
 obj-$(CONFIG_S3C_DEV_HSMMC1)	+= dev-hsmmc1.o
+obj-$(CONFIG_S3C_DEV_HSMMC2)	+= dev-hsmmc2.o
 obj-y				+= dev-i2c0.o
 obj-$(CONFIG_S3C_DEV_I2C1)	+= dev-i2c1.o
 obj-$(CONFIG_S3C_DEV_FB)	+= dev-fb.o
diff --git a/arch/arm/plat-s3c/dev-hsmmc2.c b/arch/arm/plat-s3c/dev-hsmmc2.c
new file mode 100644
index 0000000..082e55a
--- /dev/null
+++ b/arch/arm/plat-s3c/dev-hsmmc2.c
@@ -0,0 +1,65 @@
+/* linux/arch/arm/plat-s3c/dev-hsmmc2.c
+ *
+ * Copyright (c) 2009 Samsung Electronics
+ *
+ * S3C series device definition for hsmmc device 2
+ *
+ * This program is free software; you can 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/platform_device.h>
+#include <linux/mmc/host.h>
+
+#include <mach/map.h>
+#include <plat/sdhci.h>
+#include <plat/devs.h>
+
+#define S3C_SZ_HSMMC	(0x1000)
+
+static struct resource s3c_hsmmc2_resource[] = {
+	[0] = {
+		.start = S3C_PA_HSMMC2,
+		.end   = S3C_PA_HSMMC2 + S3C_SZ_HSMMC - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_HSMMC2,
+		.end   = IRQ_HSMMC2,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+static u64 s3c_device_hsmmc2_dmamask = 0xffffffffUL;
+
+struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
+	.max_width	= 4,
+	.host_caps	= (MMC_CAP_4_BIT_DATA |
+			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+};
+
+struct platform_device s3c_device_hsmmc2 = {
+	.name		= "s3c-sdhci",
+	.id		= 2,
+	.num_resources	= ARRAY_SIZE(s3c_hsmmc2_resource),
+	.resource	= s3c_hsmmc2_resource,
+	.dev		= {
+		.dma_mask		= &s3c_device_hsmmc2_dmamask,
+		.coherent_dma_mask	= 0xffffffffUL,
+		.platform_data		= &s3c_hsmmc2_def_platdata,
+	},
+};
+
+void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+	struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata;
+
+	set->max_width = pd->max_width;
+
+	if (pd->cfg_gpio)
+		set->cfg_gpio = pd->cfg_gpio;
+	if (pd->cfg_card)
+		set->cfg_card = pd->cfg_card;
+}
diff --git a/arch/arm/plat-s3c/include/plat/sdhci.h b/arch/arm/plat-s3c/include/plat/sdhci.h
index f615308..c71d078 100644
--- a/arch/arm/plat-s3c/include/plat/sdhci.h
+++ b/arch/arm/plat-s3c/include/plat/sdhci.h
@@ -57,6 +57,7 @@ struct s3c_sdhci_platdata {
  */
 extern void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd);
 extern void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd);
+extern void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd);
 
 /* Default platform data, exported so that per-cpu initialisation can
  * set the correct one when there are more than one cpu type selected.
@@ -64,11 +65,15 @@ extern void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd);
 
 extern struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata;
 extern struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata;
+extern struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata;
 
 /* Helper function availablity */
 
 extern void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
 extern void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
+extern void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
 
 /* S3C6400 SDHCI setup */
 
@@ -145,4 +150,54 @@ static inline void s3c6410_default_sdhci0(void) { }
 static inline void s3c6410_default_sdhci1(void) { }
 #endif /* CONFIG_S3C6410_SETUP_SDHCI */
 
+/* S5PC100 SDHCI setup */
+
+#ifdef CONFIG_S5PC100_SETUP_SDHCI
+extern char *s5pc100_hsmmc_clksrcs[4];
+
+extern void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev,
+					   void __iomem *r,
+					   struct mmc_ios *ios,
+					   struct mmc_card *card);
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static inline void s5pc100_default_sdhci0(void)
+{
+	s3c_hsmmc0_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
+	s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio;
+	s3c_hsmmc0_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
+}
+#else
+static inline void s5pc100_default_sdhci0(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC */
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+static inline void s5pc100_default_sdhci1(void)
+{
+	s3c_hsmmc1_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
+	s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio;
+	s3c_hsmmc1_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
+}
+#else
+static inline void s5pc100_default_sdhci1(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC1 */
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static inline void s5pc100_default_sdhci2(void)
+{
+	s3c_hsmmc2_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
+	s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio;
+	s3c_hsmmc2_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
+}
+#else
+static inline void s5pc100_default_sdhci2(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC1 */
+
+
+#else
+static inline void s5pc100_default_sdhci0(void) { }
+static inline void s5pc100_default_sdhci1(void) { }
+static inline void s5pc100_default_sdhci2(void) { }
+#endif /* CONFIG_S5PC100_SETUP_SDHCI */
+
 #endif /* __PLAT_S3C_SDHCI_H */
diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig
index 1fc25b9..1608e62 100644
--- a/arch/arm/plat-s5pc1xx/Kconfig
+++ b/arch/arm/plat-s5pc1xx/Kconfig
@@ -55,4 +55,10 @@ config S5PC1XX_SETUP_I2C1
 	bool
 	help
 	  Common setup code for i2c bus 1.
+
+config S5PC1XX_SETUP_SDHCI_GPIO
+	bool
+	help
+	  Common setup code for SDHCI gpio.
+
 endif
diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile
index 15c800e..66a8f3e 100644
--- a/arch/arm/plat-s5pc1xx/Makefile
+++ b/arch/arm/plat-s5pc1xx/Makefile
@@ -27,3 +27,4 @@ obj-$(CONFIG_CPU_S5PC100_CLOCK)	+= s5pc100-clock.o
 obj-$(CONFIG_S5PC1XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
 obj-$(CONFIG_S5PC1XX_SETUP_I2C0) += setup-i2c0.o
 obj-$(CONFIG_S5PC1XX_SETUP_I2C1) += setup-i2c1.o
+obj-$(CONFIG_S5PC1XX_SETUP_SDHCI_GPIO)	+= setup-sdhci-gpio.o
diff --git a/arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c b/arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c
new file mode 100644
index 0000000..3577619
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c
@@ -0,0 +1,86 @@
+/* linux/arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c
+ *
+ * Copyright 2009 Samsung Eletronics
+ *
+ * S5PC1XX - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-sdhci.h>
+
+void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
+{
+	unsigned int gpio;
+	unsigned int end;
+	unsigned int num;
+
+	num = width;
+	/* In case of 8 width, we should decrease the 2 */
+	if (width == 8)
+		num = width - 2;
+
+	end = S5PC100_GPG0(2 + num);
+
+	/* Set all the necessary GPG0/GPG1 pins to special-function 0 */
+	for (gpio = S5PC100_GPG0(0); gpio < end; gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	if (width == 8) {
+		for (gpio = S5PC100_GPG1(0); gpio <= S5PC100_GPG1(1); gpio++) {
+			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+		}
+	}
+
+	s3c_gpio_setpull(S5PC100_GPG1(2), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PC100_GPG1(2), S3C_GPIO_SFN(2));
+}
+
+void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
+{
+	unsigned int gpio;
+	unsigned int end;
+
+	end = S5PC100_GPG2(2 + width);
+
+	/* Set all the necessary GPG2 pins to special-function 2 */
+	for (gpio = S5PC100_GPG2(0); gpio < end; gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	s3c_gpio_setpull(S5PC100_GPG2(6), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PC100_GPG2(6), S3C_GPIO_SFN(2));
+}
+
+void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
+{
+	unsigned int gpio;
+	unsigned int end;
+
+	end = S5PC100_GPG3(2 + width);
+
+	/* Set all the necessary GPG3 pins to special-function 2 */
+	for (gpio = S5PC100_GPG3(0); gpio < end; gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	s3c_gpio_setpull(S5PC100_GPG3(6), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PC100_GPG3(6), S3C_GPIO_SFN(2));
+}
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 16/17] SMDKC100: add SDHCI controllers 0, 1 and 2 support
  2009-10-13  8:11                               ` Marek Szyprowski
@ 2009-10-13  8:11                                 ` Marek Szyprowski
  -1 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: kyungmin.park, bhmin, ben-linux, m.szyprowski

Add required machine definitions for SDHCI controller 0, 1 and 2. SMDKC100
has 2 SDHCI/MMC ports. Port 1 is directly connected to controller 0. Port
1 can be conntected to controler 1 or 2, depending on jumper setup.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/Kconfig         |    4 ++++
 arch/arm/mach-s5pc100/mach-smdkc100.c |    3 +++
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index 21b1821..0dd2b8c 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -25,8 +25,12 @@ config MACH_SMDKC100
 	select CPU_S5PC100
 	select S3C_DEV_FB
 	select S3C_DEV_I2C1
+	select S3C_DEV_HSMMC
+	select S3C_DEV_HSMMC1
+	select S3C_DEV_HSMMC2
 	select S5PC1XX_SETUP_I2C0
 	select S5PC1XX_SETUP_I2C1
 	select S5PC1XX_SETUP_FB_24BPP
+	select S5PC100_SETUP_SDHCI
 	help
 	  Machine support for the Samsung SMDKC100
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index 2c0119f..8dee48e 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -147,6 +147,9 @@ static struct platform_device *smdkc100_devices[] __initdata = {
 	&s3c_device_i2c0,
 	&s3c_device_i2c1,
 	&s3c_device_fb,
+	&s3c_device_hsmmc0,
+	&s3c_device_hsmmc1,
+	&s3c_device_hsmmc2,
 	&smdkc100_lcd_powerdev,
 };
 
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 16/17] SMDKC100: add SDHCI controllers 0, 1 and 2 support
@ 2009-10-13  8:11                                 ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

Add required machine definitions for SDHCI controller 0, 1 and 2. SMDKC100
has 2 SDHCI/MMC ports. Port 1 is directly connected to controller 0. Port
1 can be conntected to controler 1 or 2, depending on jumper setup.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/Kconfig         |    4 ++++
 arch/arm/mach-s5pc100/mach-smdkc100.c |    3 +++
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index 21b1821..0dd2b8c 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -25,8 +25,12 @@ config MACH_SMDKC100
 	select CPU_S5PC100
 	select S3C_DEV_FB
 	select S3C_DEV_I2C1
+	select S3C_DEV_HSMMC
+	select S3C_DEV_HSMMC1
+	select S3C_DEV_HSMMC2
 	select S5PC1XX_SETUP_I2C0
 	select S5PC1XX_SETUP_I2C1
 	select S5PC1XX_SETUP_FB_24BPP
+	select S5PC100_SETUP_SDHCI
 	help
 	  Machine support for the Samsung SMDKC100
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index 2c0119f..8dee48e 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -147,6 +147,9 @@ static struct platform_device *smdkc100_devices[] __initdata = {
 	&s3c_device_i2c0,
 	&s3c_device_i2c1,
 	&s3c_device_fb,
+	&s3c_device_hsmmc0,
+	&s3c_device_hsmmc1,
+	&s3c_device_hsmmc2,
 	&smdkc100_lcd_powerdev,
 };
 
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 17/17] drivers: MMC: enable SDHCI-S3C on S5PC1XX platform
  2009-10-13  8:11                                 ` Marek Szyprowski
@ 2009-10-13  8:11                                   ` Marek Szyprowski
  -1 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: kyungmin.park, bhmin, ben-linux, m.szyprowski

Samsung S5PC100 SoC has SDHCI controller compatible to the one known from
S3C64xx SoCs. Enable support for sdhci-s3c driver also on S5PC1xx platform.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/mmc/host/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 432ae83..faddf82 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -96,7 +96,7 @@ config MMC_SDHCI_PLTFM
 
 config MMC_SDHCI_S3C
 	tristate "SDHCI support on Samsung S3C SoC"
-	depends on MMC_SDHCI && (PLAT_S3C24XX || PLAT_S3C64XX)
+	depends on MMC_SDHCI && (PLAT_S3C24XX || PLAT_S3C64XX || PLAT_S5PC1XX)
 	help
 	  This selects the Secure Digital Host Controller Interface (SDHCI)
 	  often referrered to as the HSMMC block in some of the Samsung S3C
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 17/17] drivers: MMC: enable SDHCI-S3C on S5PC1XX platform
@ 2009-10-13  8:11                                   ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

Samsung S5PC100 SoC has SDHCI controller compatible to the one known from
S3C64xx SoCs. Enable support for sdhci-s3c driver also on S5PC1xx platform.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/mmc/host/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 432ae83..faddf82 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -96,7 +96,7 @@ config MMC_SDHCI_PLTFM
 
 config MMC_SDHCI_S3C
 	tristate "SDHCI support on Samsung S3C SoC"
-	depends on MMC_SDHCI && (PLAT_S3C24XX || PLAT_S3C64XX)
+	depends on MMC_SDHCI && (PLAT_S3C24XX || PLAT_S3C64XX || PLAT_S5PC1XX)
 	help
 	  This selects the Secure Digital Host Controller Interface (SDHCI)
 	  often referrered to as the HSMMC block in some of the Samsung S3C
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* Re: [PATCH 01/17] ARM: MM: use 64bytes of L1 cache on plat S5PC1xx
  2009-10-13  8:11   ` Marek Szyprowski
@ 2009-11-06  2:32     ` Harald Welte
  -1 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  2:32 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-arm-kernel, linux-samsung-soc, kyungmin.park, ben-linux, bhmin

Hi Marek,

> Samsung S5PC1xx SoCs are Coretex8 based, so use 64 bytes of L1 cache
> line instead of the default 32 bytes.

this is an obvious fix, and I'd recommend Ben should merge it asap (if he
didn't already)
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 01/17] ARM: MM: use 64bytes of L1 cache on plat S5PC1xx
@ 2009-11-06  2:32     ` Harald Welte
  0 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  2:32 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marek,

> Samsung S5PC1xx SoCs are Coretex8 based, so use 64 bytes of L1 cache
> line instead of the default 32 bytes.

this is an obvious fix, and I'd recommend Ben should merge it asap (if he
didn't already)
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 02/17] ARM: S5PC1XX: registers rename
  2009-10-13  8:11     ` Marek Szyprowski
@ 2009-11-06  3:18       ` Harald Welte
  -1 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:18 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-arm-kernel, linux-samsung-soc, kyungmin.park, ben-linux, bhmin

Hi Marek,

On Tue, Oct 13, 2009 at 10:11:07AM +0200, Marek Szyprowski wrote:

> S5PC110 and S5PC100 register maps differs in many places, rename all
> defined registers to be S5PC100 specific. System map has been also updated
> to cover more integrated peripherals.

The general idea of this patch is fine.  However, I have some questions:

>  /* System */
> -#define S5PC100_PA_SYS		(0xE0100000)
> -#define S5PC100_PA_CLK		(S5PC100_PA_SYS + 0x0)
> -#define S5PC100_PA_PWR		(S5PC100_PA_SYS + 0x8000)
> +#define S5PC100_PA_CLK		(0xE0100000)
> +#define S5PC100_PA_CLK_OTHER	(0xE0200000)
> +#define S5PC100_PA_PWR		(0xE0108000)

this is more like a rename.  Why was this done?  It would be good to explain in
the commitlog

> +/* GPIO */
> +#define S5PC100_PA_GPIO		(0xE0300000)
> +#define S5PC1XX_PA_GPIO		S5PC100_PA_GPIO
> +#define S5PC1XX_VA_GPIO		S3C_ADDR(0x00500000)

If the address is different for c100 and c110: why do we need a S5CP1XX_*
definition?  In my personal opinion, all those compile-time defines are a
kludge and we should not introduce more of them.  They will bite us in the back
if we ever in the future want to build a kernel that can boot on both c100 and
c110.

>  /* ETC */
>  #define S5PC100_PA_SDRAM	(0x20000000)
> +#define S5PC1XX_PA_SDRAM	S5PC100_PA_SDRAM

Again here. We already have the c100 specific define.  Why add a new c1xx define?

>  	/* Maintainer: Byungho Min <bhmin@samsung.com> */
> -	.phys_io	= S5PC1XX_PA_UART & 0xfff00000,
> +	.phys_io	= S5PC100_PA_UART & 0xfff00000,

this is the change I like.

>  	.io_pg_offst	= (((u32)S5PC1XX_VA_UART) >> 18) & 0xfffc,
> -	.boot_params	= S5PC100_PA_SDRAM + 0x100,
> +	.boot_params	= S5PC1XX_PA_SDRAM + 0x100,

This is the wrong kind of change, from my point of view.  We don't know yet
if all future s5pc1xx products will also have the same address, do we?

-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 02/17] ARM: S5PC1XX: registers rename
@ 2009-11-06  3:18       ` Harald Welte
  0 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:18 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marek,

On Tue, Oct 13, 2009 at 10:11:07AM +0200, Marek Szyprowski wrote:

> S5PC110 and S5PC100 register maps differs in many places, rename all
> defined registers to be S5PC100 specific. System map has been also updated
> to cover more integrated peripherals.

The general idea of this patch is fine.  However, I have some questions:

>  /* System */
> -#define S5PC100_PA_SYS		(0xE0100000)
> -#define S5PC100_PA_CLK		(S5PC100_PA_SYS + 0x0)
> -#define S5PC100_PA_PWR		(S5PC100_PA_SYS + 0x8000)
> +#define S5PC100_PA_CLK		(0xE0100000)
> +#define S5PC100_PA_CLK_OTHER	(0xE0200000)
> +#define S5PC100_PA_PWR		(0xE0108000)

this is more like a rename.  Why was this done?  It would be good to explain in
the commitlog

> +/* GPIO */
> +#define S5PC100_PA_GPIO		(0xE0300000)
> +#define S5PC1XX_PA_GPIO		S5PC100_PA_GPIO
> +#define S5PC1XX_VA_GPIO		S3C_ADDR(0x00500000)

If the address is different for c100 and c110: why do we need a S5CP1XX_*
definition?  In my personal opinion, all those compile-time defines are a
kludge and we should not introduce more of them.  They will bite us in the back
if we ever in the future want to build a kernel that can boot on both c100 and
c110.

>  /* ETC */
>  #define S5PC100_PA_SDRAM	(0x20000000)
> +#define S5PC1XX_PA_SDRAM	S5PC100_PA_SDRAM

Again here. We already have the c100 specific define.  Why add a new c1xx define?

>  	/* Maintainer: Byungho Min <bhmin@samsung.com> */
> -	.phys_io	= S5PC1XX_PA_UART & 0xfff00000,
> +	.phys_io	= S5PC100_PA_UART & 0xfff00000,

this is the change I like.

>  	.io_pg_offst	= (((u32)S5PC1XX_VA_UART) >> 18) & 0xfffc,
> -	.boot_params	= S5PC100_PA_SDRAM + 0x100,
> +	.boot_params	= S5PC1XX_PA_SDRAM + 0x100,

This is the wrong kind of change, from my point of view.  We don't know yet
if all future s5pc1xx products will also have the same address, do we?

-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 03/17] ARM: S5PC1XX: clock registers rename
  2009-10-13  8:11       ` Marek Szyprowski
@ 2009-11-06  3:19         ` Harald Welte
  -1 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:19 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-arm-kernel, linux-samsung-soc, kyungmin.park, ben-linux, bhmin

On Tue, Oct 13, 2009 at 10:11:08AM +0200, Marek Szyprowski wrote:
> S5PC100 and S5PC110 clock registers differs in many places, rename all
> previously defined registers to be S5PC100 specific. Remove all power
> management registers. They will be added later to a separate file.

This looks good to me. Not that I have any authority, I'm just reviewing.
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 03/17] ARM: S5PC1XX: clock registers rename
@ 2009-11-06  3:19         ` Harald Welte
  0 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 13, 2009 at 10:11:08AM +0200, Marek Szyprowski wrote:
> S5PC100 and S5PC110 clock registers differs in many places, rename all
> previously defined registers to be S5PC100 specific. Remove all power
> management registers. They will be added later to a separate file.

This looks good to me. Not that I have any authority, I'm just reviewing.
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 05/17] ARM: S5PC1XX: add GPIO L banks to register definition
  2009-10-13  8:11           ` Marek Szyprowski
@ 2009-11-06  3:20             ` Harald Welte
  -1 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:20 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-arm-kernel, linux-samsung-soc, kyungmin.park, ben-linux, bhmin

On Tue, Oct 13, 2009 at 10:11:10AM +0200, Marek Szyprowski wrote:
> Add GPIO L0-L4 banks to register definition.

looks fine to me.
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 05/17] ARM: S5PC1XX: add GPIO L banks to register definition
@ 2009-11-06  3:20             ` Harald Welte
  0 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 13, 2009 at 10:11:10AM +0200, Marek Szyprowski wrote:
> Add GPIO L0-L4 banks to register definition.

looks fine to me.
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 06/17] ARM: S5PC1XX: GPIO registers rename
  2009-10-13  8:11             ` Marek Szyprowski
@ 2009-11-06  3:20               ` Harald Welte
  -1 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:20 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-arm-kernel, linux-samsung-soc, kyungmin.park, ben-linux, bhmin

On Tue, Oct 13, 2009 at 10:11:11AM +0200, Marek Szyprowski wrote:
> S5PC100 and S5PC110 GPIO registers differs in many places, rename all
> previously defined registers to be S5PC100 specific.

looks fine to me.
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 06/17] ARM: S5PC1XX: GPIO registers rename
@ 2009-11-06  3:20               ` Harald Welte
  0 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 13, 2009 at 10:11:11AM +0200, Marek Szyprowski wrote:
> S5PC100 and S5PC110 GPIO registers differs in many places, rename all
> previously defined registers to be S5PC100 specific.

looks fine to me.
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 07/17] ARM: S5PC1xx: add gpiolib and external/gpio interrupt support
  2009-10-13  8:11               ` Marek Szyprowski
@ 2009-11-06  3:23                 ` Harald Welte
  -1 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:23 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-arm-kernel, linux-samsung-soc, kyungmin.park, ben-linux, bhmin

On Tue, Oct 13, 2009 at 10:11:12AM +0200, Marek Szyprowski wrote:
> Add support for gpiolib calls. This is based on the gpiolib implementation
> from plat-s3c64xx tree.

I think this is also the right way.  We definitely want gpiolib support.

Ben, what do you think?

Regards,
	Harald
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 07/17] ARM: S5PC1xx: add gpiolib and external/gpio interrupt support
@ 2009-11-06  3:23                 ` Harald Welte
  0 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 13, 2009 at 10:11:12AM +0200, Marek Szyprowski wrote:
> Add support for gpiolib calls. This is based on the gpiolib implementation
> from plat-s3c64xx tree.

I think this is also the right way.  We definitely want gpiolib support.

Ben, what do you think?

Regards,
	Harald
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 08/17] ARM: S5PC1XX: add cpu idle and system reset support
  2009-10-13  8:11                 ` Marek Szyprowski
@ 2009-11-06  3:26                   ` Harald Welte
  -1 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:26 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-arm-kernel, linux-samsung-soc, kyungmin.park, ben-linux, bhmin

On Tue, Oct 13, 2009 at 10:11:13AM +0200, Marek Szyprowski wrote:
> Add CPU idle support by a call to SoC build-in power management core.
> Add system reset support by a simple write to system controll register.

looks great, and is definitely an improvement.

However, one small comment:

>  static void arch_reset(char mode, const char *cmd)
>  {
> -	/* nothing here yet */
> -}
> +	unsigned long reset;
>  
> +	reset = 0xc100;
> +	__raw_writel(reset, S5PC1XX_VA_CLK_OTHER);
> +	return;
> +}

why do we first define an unsigned long reset and then set it to some magic
value?  why not simply make this one line like 
	__raw_writel(0xc100, S5PC1XX_VA_CLK_OTHER);

also, it might be a good idea to use some #define values rather than the 0xc100
magic value.
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 08/17] ARM: S5PC1XX: add cpu idle and system reset support
@ 2009-11-06  3:26                   ` Harald Welte
  0 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 13, 2009 at 10:11:13AM +0200, Marek Szyprowski wrote:
> Add CPU idle support by a call to SoC build-in power management core.
> Add system reset support by a simple write to system controll register.

looks great, and is definitely an improvement.

However, one small comment:

>  static void arch_reset(char mode, const char *cmd)
>  {
> -	/* nothing here yet */
> -}
> +	unsigned long reset;
>  
> +	reset = 0xc100;
> +	__raw_writel(reset, S5PC1XX_VA_CLK_OTHER);
> +	return;
> +}

why do we first define an unsigned long reset and then set it to some magic
value?  why not simply make this one line like 
	__raw_writel(0xc100, S5PC1XX_VA_CLK_OTHER);

also, it might be a good idea to use some #define values rather than the 0xc100
magic value.
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 09/17] ARM: S5PC1xx: add platform helpers for s3c-fb device
  2009-10-13  8:11                   ` Marek Szyprowski
@ 2009-11-06  3:29                     ` Harald Welte
  -1 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:29 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-arm-kernel, linux-samsung-soc, kyungmin.park, ben-linux, bhmin

On Tue, Oct 13, 2009 at 10:11:14AM +0200, Marek Szyprowski wrote:
> Samsung S5PC100 has LCD-controller compatible with the one known from
> previous SoCs series. Add required platform setup and support code that
> it can be used with s3c-fb driver.

Once again i like teh idea and purpose of the patch.

However, I don't like that we copy an entire header file and now have two
copies of the same header file in the kernel tree.

>  arch/arm/mach-s5pc100/include/mach/regs-fb.h |  259 ++++++++++++++++++++++++++

I'm quite sure that there must be a solution where we can avoid copying the
file to two places.

-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 09/17] ARM: S5PC1xx: add platform helpers for s3c-fb device
@ 2009-11-06  3:29                     ` Harald Welte
  0 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 13, 2009 at 10:11:14AM +0200, Marek Szyprowski wrote:
> Samsung S5PC100 has LCD-controller compatible with the one known from
> previous SoCs series. Add required platform setup and support code that
> it can be used with s3c-fb driver.

Once again i like teh idea and purpose of the patch.

However, I don't like that we copy an entire header file and now have two
copies of the same header file in the kernel tree.

>  arch/arm/mach-s5pc100/include/mach/regs-fb.h |  259 ++++++++++++++++++++++++++

I'm quite sure that there must be a solution where we can avoid copying the
file to two places.

-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 10/17] SMDKC100: enable S3C FrameBuffer
  2009-10-13  8:11                     ` Marek Szyprowski
@ 2009-11-06  3:29                       ` Harald Welte
  -1 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:29 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-arm-kernel, linux-samsung-soc, kyungmin.park, ben-linux, bhmin

On Tue, Oct 13, 2009 at 10:11:15AM +0200, Marek Szyprowski wrote:
> Add required machine definitions for s3c-fb device.
> A 800x480 lcd device (simmilar to the one known from SMDK6410 boards) has
> been defined. The lcd controller is attached to GPIO lines and can be
> enabled/disabled with platform-lcd driver.

looks fine to me.
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 10/17] SMDKC100: enable S3C FrameBuffer
@ 2009-11-06  3:29                       ` Harald Welte
  0 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 13, 2009 at 10:11:15AM +0200, Marek Szyprowski wrote:
> Add required machine definitions for s3c-fb device.
> A 800x480 lcd device (simmilar to the one known from SMDK6410 boards) has
> been defined. The lcd controller is attached to GPIO lines and can be
> enabled/disabled with platform-lcd driver.

looks fine to me.
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 12/17] ARM: S5PC1xx: add platform helpers for i2c adapter devices
  2009-10-13  8:11                         ` Marek Szyprowski
@ 2009-11-06  3:30                           ` Harald Welte
  -1 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:30 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-arm-kernel, linux-samsung-soc, kyungmin.park, ben-linux, bhmin

On Tue, Oct 13, 2009 at 10:11:17AM +0200, Marek Szyprowski wrote:
> Samsung S5PC100 has I2C bus controller compatible with the one known from
> previous SoCs series. Add required platform setup and support code that
> it can be used with s3c2410-i2c driver.

this is straight forward.  I think Ben should merge it.
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 12/17] ARM: S5PC1xx: add platform helpers for i2c adapter devices
@ 2009-11-06  3:30                           ` Harald Welte
  0 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 13, 2009 at 10:11:17AM +0200, Marek Szyprowski wrote:
> Samsung S5PC100 has I2C bus controller compatible with the one known from
> previous SoCs series. Add required platform setup and support code that
> it can be used with s3c2410-i2c driver.

this is straight forward.  I think Ben should merge it.
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 13/17] SMDKC100: add I2C0 and I2C1 buses support
  2009-10-13  8:11                           ` Marek Szyprowski
@ 2009-11-06  3:30                             ` Harald Welte
  -1 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:30 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-arm-kernel, linux-samsung-soc, kyungmin.park, ben-linux, bhmin

On Tue, Oct 13, 2009 at 10:11:18AM +0200, Marek Szyprowski wrote:
> Add required machine definitions for I2C 0 and 1 bus controllers.
> Currently no I2C device are defined yet.

same as previous patch: trivial and should be merged.
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 13/17] SMDKC100: add I2C0 and I2C1 buses support
@ 2009-11-06  3:30                             ` Harald Welte
  0 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 13, 2009 at 10:11:18AM +0200, Marek Szyprowski wrote:
> Add required machine definitions for I2C 0 and 1 bus controllers.
> Currently no I2C device are defined yet.

same as previous patch: trivial and should be merged.
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 15/17] ARM: S5PC1xx: add platform helpers for SDHCI host controllers
  2009-10-13  8:11                               ` Marek Szyprowski
@ 2009-11-06  3:31                                 ` Harald Welte
  -1 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:31 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-arm-kernel, linux-samsung-soc, kyungmin.park, ben-linux, bhmin

On Tue, Oct 13, 2009 at 10:11:20AM +0200, Marek Szyprowski wrote:
> Samsung S5PC100 has 3 SDHCI controllers compatible with the one known from
> previous SoCs series. Add required platform setup and support code that
> the devices can be used with sdhci-s3c driver.

this patch, plus the following two patches also should be merged. I think they
are straight-forward .
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 15/17] ARM: S5PC1xx: add platform helpers for SDHCI host controllers
@ 2009-11-06  3:31                                 ` Harald Welte
  0 siblings, 0 replies; 76+ messages in thread
From: Harald Welte @ 2009-11-06  3:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 13, 2009 at 10:11:20AM +0200, Marek Szyprowski wrote:
> Samsung S5PC100 has 3 SDHCI controllers compatible with the one known from
> previous SoCs series. Add required platform setup and support code that
> the devices can be used with sdhci-s3c driver.

this patch, plus the following two patches also should be merged. I think they
are straight-forward .
-- 
- Harald Welte <laforge@gnumonks.org>           http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
                                                  (ETSI EN 300 175-7 Ch. A6)

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 02/17] ARM: S5PC1XX: registers rename
  2009-10-13  8:11     ` Marek Szyprowski
                       ` (2 preceding siblings ...)
  (?)
@ 2009-11-06  8:17     ` tommy.hong
  -1 siblings, 0 replies; 76+ messages in thread
From: tommy.hong @ 2009-11-06  8:17 UTC (permalink / raw)
  To: linux-arm-kernel

yeah,i agree






?2009-11-06?11:18:45?"Harald?Welte"?<laforge@gnumonks.org>????
>Hi?Marek,
>
>On?Tue,?Oct?13,?2009?at?10:11:07AM?+0200,?Marek?Szyprowski?wrote:
>
>>?S5PC110?and?S5PC100?register?maps?differs?in?many?places,?rename?all
>>?defined?registers?to?be?S5PC100?specific.?System?map?has?been?also?updated
>>?to?cover?more?integrated?peripherals.
>
>The?general?idea?of?this?patch?is?fine.??However,?I?have?some?questions:
>
>>??/*?System?*/
>>?-#define?S5PC100_PA_SYS		(0xE0100000)
>>?-#define?S5PC100_PA_CLK		(S5PC100_PA_SYS?+?0x0)
>>?-#define?S5PC100_PA_PWR		(S5PC100_PA_SYS?+?0x8000)
>>?+#define?S5PC100_PA_CLK		(0xE0100000)
>>?+#define?S5PC100_PA_CLK_OTHER	(0xE0200000)
>>?+#define?S5PC100_PA_PWR		(0xE0108000)
>
>this?is?more?like?a?rename.??Why?was?this?done???It?would?be?good?to?explain?in
>the?commitlog
>
>>?+/*?GPIO?*/
>>?+#define?S5PC100_PA_GPIO		(0xE0300000)
>>?+#define?S5PC1XX_PA_GPIO		S5PC100_PA_GPIO
>>?+#define?S5PC1XX_VA_GPIO		S3C_ADDR(0x00500000)
>
>If?the?address?is?different?for?c100?and?c110:?why?do?we?need?a?S5CP1XX_*
>definition???In?my?personal?opinion,?all?those?compile-time?defines?are?a
>kludge?and?we?should?not?introduce?more?of?them.??They?will?bite?us?in?the?back
>if?we?ever?in?the?future?want?to?build?a?kernel?that?can?boot?on?both?c100?and
>c110.
>
>>??/*?ETC?*/
>>??#define?S5PC100_PA_SDRAM	(0x20000000)
>>?+#define?S5PC1XX_PA_SDRAM	S5PC100_PA_SDRAM
>
>Again?here.?We?already?have?the?c100?specific?define.??Why?add?a?new?c1xx?define?
>
>>??	/*?Maintainer:?Byungho?Min?<bhmin@samsung.com>?*/
>>?-	.phys_io	=?S5PC1XX_PA_UART?&?0xfff00000,
>>?+	.phys_io	=?S5PC100_PA_UART?&?0xfff00000,
>
>this?is?the?change?I?like.
>
>>??	.io_pg_offst	=?(((u32)S5PC1XX_VA_UART)?>>?18)?&?0xfffc,
>>?-	.boot_params	=?S5PC100_PA_SDRAM?+?0x100,
>>?+	.boot_params	=?S5PC1XX_PA_SDRAM?+?0x100,
>
>This?is?the?wrong?kind?of?change,?from?my?point?of?view.??We?don't?know?yet
>if?all?future?s5pc1xx?products?will?also?have?the?same?address,?do?we?
>
>--?
>-?Harald?Welte?<laforge@gnumonks.org>???????????http://laforge.gnumonks.org/
>============================================================================
>"Privacy?in?residential?applications?is?a?desirable?marketing?option."
>??????????????????????????????????????????????????(ETSI?EN?300?175-7?Ch.?A6)
>
>_______________________________________________
>linux-arm-kernel?mailing?list
>linux-arm-kernel at lists.infradead.org
>http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20091106/1f8a0fb8/attachment.htm>

^ permalink raw reply	[flat|nested] 76+ messages in thread

* RE: [PATCH 02/17] ARM: S5PC1XX: registers rename
  2009-11-06  3:18       ` Harald Welte
@ 2009-11-06 15:02         ` Marek Szyprowski
  -1 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-11-06 15:02 UTC (permalink / raw)
  To: 'Harald Welte'
  Cc: linux-samsung-soc, kyungmin.park, bhmin, ben-linux,
	linux-arm-kernel, Marek Szyprowski

Hello,

On Friday, November 06, 2009 4:19 AM, Harald Welte wrote:
 
> Hi Marek,
> 
> On Tue, Oct 13, 2009 at 10:11:07AM +0200, Marek Szyprowski wrote:
> 
> > S5PC110 and S5PC100 register maps differs in many places, rename all
> > defined registers to be S5PC100 specific. System map has been also updated
> > to cover more integrated peripherals.
> 
> The general idea of this patch is fine.  However, I have some questions:
> 
> >  /* System */
> > -#define S5PC100_PA_SYS		(0xE0100000)
> > -#define S5PC100_PA_CLK		(S5PC100_PA_SYS + 0x0)
> > -#define S5PC100_PA_PWR		(S5PC100_PA_SYS + 0x8000)
> > +#define S5PC100_PA_CLK		(0xE0100000)
> > +#define S5PC100_PA_CLK_OTHER	(0xE0200000)
> > +#define S5PC100_PA_PWR		(0xE0108000)
> 
> this is more like a rename.  Why was this done?  It would be good to explain in
> the commitlog

I renamed these registers to better match the chip specification. The 'SYS'
register name was borrowed from S3C64XX series and is a bit inadequate in C100.
 
> > +/* GPIO */
> > +#define S5PC100_PA_GPIO		(0xE0300000)
> > +#define S5PC1XX_PA_GPIO		S5PC100_PA_GPIO
> > +#define S5PC1XX_VA_GPIO		S3C_ADDR(0x00500000)
> 
> If the address is different for c100 and c110: why do we need a S5CP1XX_*
> definition?  In my personal opinion, all those compile-time defines are a
> kludge and we should not introduce more of them.  They will bite us in the back
> if we ever in the future want to build a kernel that can boot on both c100 and
> c110.

These C1XX defines were the first step to prepare the code for C110 support. 

S5PC110 register map differs completely from the S5PC100 one. These two SOCs
cannot be easily handled by the same kernel binary image without some hacks and
runtime fixups if we place them in the one kernel platform. Creating yet another
kernel platform just because of these differences would unnecessarily duplicate
a lot of code and would not use the potential of the current kernel
infrastructure (separate include directories, resource&device driver model, etc).

My idea was to introduce a sub-platforms in plat-s5pc1xx. Such sub-platforms
would be exclusive - one for C100 and one for C110. Each of the sub-platforms would
have its own include files (in mach-s5pc100 and mach-s5pc110 directories
respectively) and most of the chip differences can be handled in compile time by
proper macros. Macros for the common resources would use 'C1XX' names. In this
approach common resources (GPIO, DMA, io space and so on) can be easily defined
with C1XX defines. This also perfectly matches the current convention of common
S3C_XXX defines (i.e. S3C_PA_UART, S3C_PA_FB, S3C_VA_VICn, S3C_PA_HSMMCn, and so
on), so most of the code from arch/arm/plat-s3c/ can be reused without any
modifications. I assume that the S3C prefix would be renamed to SAMSUNG sometime
later.

Sub-platform can be easily defined by a simple choice command in
arch/arm/plat-s5pc1xx/Kconfig:

+choice
+        prompt "S5PC1xx SoC Type"
+        default ARCH_S5PC100
+
+config ARCH_S5PC100
+        bool "S5PC100"
+
+config ARCH_S5PC110
+        bool "S5PC110"
+
+endchoice

Then each sub-platform can be easily defined basing on the CONFIG_ARCH_S5PC100
and CONFIG_ARCH_S5PC110 defines.

Similar approach is used in OMAP platform (there is only one platform directory,
and the chip series is defined by a Kconfig choice option).

> >  	.io_pg_offst	= (((u32)S5PC1XX_VA_UART) >> 18) & 0xfffc,
> > -	.boot_params	= S5PC100_PA_SDRAM + 0x100,
> > +	.boot_params	= S5PC1XX_PA_SDRAM + 0x100,
> 
> This is the wrong kind of change, from my point of view.  We don't know yet
> if all future s5pc1xx products will also have the same address, do we?

Right, I missed this one.

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 02/17] ARM: S5PC1XX: registers rename
@ 2009-11-06 15:02         ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-11-06 15:02 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On Friday, November 06, 2009 4:19 AM, Harald Welte wrote:
 
> Hi Marek,
> 
> On Tue, Oct 13, 2009 at 10:11:07AM +0200, Marek Szyprowski wrote:
> 
> > S5PC110 and S5PC100 register maps differs in many places, rename all
> > defined registers to be S5PC100 specific. System map has been also updated
> > to cover more integrated peripherals.
> 
> The general idea of this patch is fine.  However, I have some questions:
> 
> >  /* System */
> > -#define S5PC100_PA_SYS		(0xE0100000)
> > -#define S5PC100_PA_CLK		(S5PC100_PA_SYS + 0x0)
> > -#define S5PC100_PA_PWR		(S5PC100_PA_SYS + 0x8000)
> > +#define S5PC100_PA_CLK		(0xE0100000)
> > +#define S5PC100_PA_CLK_OTHER	(0xE0200000)
> > +#define S5PC100_PA_PWR		(0xE0108000)
> 
> this is more like a rename.  Why was this done?  It would be good to explain in
> the commitlog

I renamed these registers to better match the chip specification. The 'SYS'
register name was borrowed from S3C64XX series and is a bit inadequate in C100.
 
> > +/* GPIO */
> > +#define S5PC100_PA_GPIO		(0xE0300000)
> > +#define S5PC1XX_PA_GPIO		S5PC100_PA_GPIO
> > +#define S5PC1XX_VA_GPIO		S3C_ADDR(0x00500000)
> 
> If the address is different for c100 and c110: why do we need a S5CP1XX_*
> definition?  In my personal opinion, all those compile-time defines are a
> kludge and we should not introduce more of them.  They will bite us in the back
> if we ever in the future want to build a kernel that can boot on both c100 and
> c110.

These C1XX defines were the first step to prepare the code for C110 support. 

S5PC110 register map differs completely from the S5PC100 one. These two SOCs
cannot be easily handled by the same kernel binary image without some hacks and
runtime fixups if we place them in the one kernel platform. Creating yet another
kernel platform just because of these differences would unnecessarily duplicate
a lot of code and would not use the potential of the current kernel
infrastructure (separate include directories, resource&device driver model, etc).

My idea was to introduce a sub-platforms in plat-s5pc1xx. Such sub-platforms
would be exclusive - one for C100 and one for C110. Each of the sub-platforms would
have its own include files (in mach-s5pc100 and mach-s5pc110 directories
respectively) and most of the chip differences can be handled in compile time by
proper macros. Macros for the common resources would use 'C1XX' names. In this
approach common resources (GPIO, DMA, io space and so on) can be easily defined
with C1XX defines. This also perfectly matches the current convention of common
S3C_XXX defines (i.e. S3C_PA_UART, S3C_PA_FB, S3C_VA_VICn, S3C_PA_HSMMCn, and so
on), so most of the code from arch/arm/plat-s3c/ can be reused without any
modifications. I assume that the S3C prefix would be renamed to SAMSUNG sometime
later.

Sub-platform can be easily defined by a simple choice command in
arch/arm/plat-s5pc1xx/Kconfig:

+choice
+        prompt "S5PC1xx SoC Type"
+        default ARCH_S5PC100
+
+config ARCH_S5PC100
+        bool "S5PC100"
+
+config ARCH_S5PC110
+        bool "S5PC110"
+
+endchoice

Then each sub-platform can be easily defined basing on the CONFIG_ARCH_S5PC100
and CONFIG_ARCH_S5PC110 defines.

Similar approach is used in OMAP platform (there is only one platform directory,
and the chip series is defined by a Kconfig choice option).

> >  	.io_pg_offst	= (((u32)S5PC1XX_VA_UART) >> 18) & 0xfffc,
> > -	.boot_params	= S5PC100_PA_SDRAM + 0x100,
> > +	.boot_params	= S5PC1XX_PA_SDRAM + 0x100,
> 
> This is the wrong kind of change, from my point of view.  We don't know yet
> if all future s5pc1xx products will also have the same address, do we?

Right, I missed this one.

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 01/17] ARM: MM: use 64bytes of L1 cache on plat S5PC1xx
  2009-10-13  8:11   ` Marek Szyprowski
@ 2009-11-08 23:58     ` Ben Dooks
  -1 siblings, 0 replies; 76+ messages in thread
From: Ben Dooks @ 2009-11-08 23:58 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-arm-kernel, linux-samsung-soc, kyungmin.park, bhmin, ben-linux

On Tue, Oct 13, 2009 at 10:11:06AM +0200, Marek Szyprowski wrote:
> Samsung S5PC1xx SoCs are Coretex8 based, so use 64 bytes of L1 cache
> line instead of the default 32 bytes.
> 
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>

This worries me, either this patch was from 'Kyungmin Park' and thus
should have either been sent by, or have an 'From:' line at the top
of the description. If this has been appraised by Kyungmin then the
signoff should either be after Marek's (as this is the sender) or be
something other than a signed-off-by.

> ---
>  arch/arm/mm/Kconfig |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
> index e993140..9cf7706 100644
> --- a/arch/arm/mm/Kconfig
> +++ b/arch/arm/mm/Kconfig
> @@ -777,5 +777,5 @@ config CACHE_XSC3L2
>  
>  config ARM_L1_CACHE_SHIFT
>  	int
> -	default 6 if ARCH_OMAP3
> +	default 6 if ARCH_OMAP3 || ARCH_S5PC1XX
>  	default 5
> -- 
> 1.6.4
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
-- 
Ben

Q:      What's a light-year?
A:      One-third less calories than a regular year.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 01/17] ARM: MM: use 64bytes of L1 cache on plat S5PC1xx
@ 2009-11-08 23:58     ` Ben Dooks
  0 siblings, 0 replies; 76+ messages in thread
From: Ben Dooks @ 2009-11-08 23:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 13, 2009 at 10:11:06AM +0200, Marek Szyprowski wrote:
> Samsung S5PC1xx SoCs are Coretex8 based, so use 64 bytes of L1 cache
> line instead of the default 32 bytes.
> 
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>

This worries me, either this patch was from 'Kyungmin Park' and thus
should have either been sent by, or have an 'From:' line at the top
of the description. If this has been appraised by Kyungmin then the
signoff should either be after Marek's (as this is the sender) or be
something other than a signed-off-by.

> ---
>  arch/arm/mm/Kconfig |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
> index e993140..9cf7706 100644
> --- a/arch/arm/mm/Kconfig
> +++ b/arch/arm/mm/Kconfig
> @@ -777,5 +777,5 @@ config CACHE_XSC3L2
>  
>  config ARM_L1_CACHE_SHIFT
>  	int
> -	default 6 if ARCH_OMAP3
> +	default 6 if ARCH_OMAP3 || ARCH_S5PC1XX
>  	default 5
> -- 
> 1.6.4
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
-- 
Ben

Q:      What's a light-year?
A:      One-third less calories than a regular year.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 07/17] ARM: S5PC1xx: add gpiolib and external/gpio interrupt support
  2009-10-13  8:11               ` Marek Szyprowski
@ 2009-11-09  0:00                 ` Ben Dooks
  -1 siblings, 0 replies; 76+ messages in thread
From: Ben Dooks @ 2009-11-09  0:00 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-arm-kernel, linux-samsung-soc, kyungmin.park, bhmin, ben-linux

On Tue, Oct 13, 2009 at 10:11:12AM +0200, Marek Szyprowski wrote:
> Add support for gpiolib calls. This is based on the gpiolib implementation
> from plat-s3c64xx tree.
> Add support for external interrupts for GPIO H banks.
> Add support for GPIO interrupts for all banks.

Hmm, this one has multiple authours in the copyright, but but some
are missing from the signed-off-by.
 
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  arch/arm/plat-s3c/Kconfig                          |    6 +
>  arch/arm/plat-s3c/include/plat/gpio-cfg.h          |    1 +
>  arch/arm/plat-s5pc1xx/Kconfig                      |    3 +
>  arch/arm/plat-s5pc1xx/Makefile                     |    3 +-
>  arch/arm/plat-s5pc1xx/cpu.c                        |    5 +
>  arch/arm/plat-s5pc1xx/gpio-config.c                |   61 +++
>  arch/arm/plat-s5pc1xx/gpiolib.c                    |  503 ++++++++++++++++++++
>  .../plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h   |   33 ++
>  arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h      |   44 ++
>  arch/arm/plat-s5pc1xx/include/plat/irqs.h          |   15 +-
>  arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h     |   70 +++
>  arch/arm/plat-s5pc1xx/irq-eint.c                   |  281 +++++++++++
>  arch/arm/plat-s5pc1xx/irq-gpio.c                   |  266 +++++++++++
>  arch/arm/plat-s5pc1xx/irq.c                        |    2 +-
>  14 files changed, 1288 insertions(+), 5 deletions(-)
>  create mode 100644 arch/arm/plat-s5pc1xx/gpio-config.c
>  create mode 100644 arch/arm/plat-s5pc1xx/gpiolib.c
>  create mode 100644 arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h
>  create mode 100644 arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h
>  create mode 100644 arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
>  create mode 100644 arch/arm/plat-s5pc1xx/irq-eint.c
>  create mode 100644 arch/arm/plat-s5pc1xx/irq-gpio.c
> 
> diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig
> index 8931c5f..f155a84 100644
> --- a/arch/arm/plat-s3c/Kconfig
> +++ b/arch/arm/plat-s3c/Kconfig
> @@ -159,6 +159,12 @@ config S3C_GPIO_CFG_S3C64XX
>  	  Internal configuration to enable S3C64XX style GPIO configuration
>  	  functions.
>  
> +config S5P_GPIO_CFG_S5PC1XX
> +	bool
> +	help
> +	  Internal configuration to enable S5PC1XX style GPIO configuration
> +	  functions.
> +
>  # DMA
>  
>  config S3C_DMA
> diff --git a/arch/arm/plat-s3c/include/plat/gpio-cfg.h b/arch/arm/plat-s3c/include/plat/gpio-cfg.h
> index 29cd6a8..7e73429 100644
> --- a/arch/arm/plat-s3c/include/plat/gpio-cfg.h
> +++ b/arch/arm/plat-s3c/include/plat/gpio-cfg.h
> @@ -62,6 +62,7 @@ struct s3c_gpio_cfg {
>  #define S3C_GPIO_INPUT	(S3C_GPIO_SPECIAL(0))
>  #define S3C_GPIO_OUTPUT	(S3C_GPIO_SPECIAL(1))
>  #define S3C_GPIO_SFN(x)	(S3C_GPIO_SPECIAL(x))
> +#define S3C_GPIO_IRQ	(S3C_GPIO_SPECIAL(0xf))
>  
>  #define s3c_gpio_is_cfg_special(_cfg) \
>  	(((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK)
> diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig
> index a8a711c..86edd27 100644
> --- a/arch/arm/plat-s5pc1xx/Kconfig
> +++ b/arch/arm/plat-s5pc1xx/Kconfig
> @@ -15,6 +15,9 @@ config PLAT_S5PC1XX
>  	select ARCH_REQUIRE_GPIOLIB
>  	select S3C_GPIO_TRACK
>  	select S3C_GPIO_PULL_UPDOWN
> +	select S3C_GPIO_CFG_S3C24XX
> +	select S3C_GPIO_CFG_S3C64XX
> +	select S5P_GPIO_CFG_S5PC1XX
>  	help
>  	  Base platform code for any Samsung S5PC1XX device
>  
> diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile
> index ebbf364..f126951 100644
> --- a/arch/arm/plat-s5pc1xx/Makefile
> +++ b/arch/arm/plat-s5pc1xx/Makefile
> @@ -13,8 +13,9 @@ obj-				:=
>  
>  obj-y				+= dev-uart.o
>  obj-y				+= cpu.o
> -obj-y				+= irq.o
> +obj-y				+= irq.o irq-gpio.o irq-eint.o
>  obj-y				+= clock.o
> +obj-y				+= gpiolib.o
>  
>  # CPU support
>  
> diff --git a/arch/arm/plat-s5pc1xx/cpu.c b/arch/arm/plat-s5pc1xx/cpu.c
> index e8f3472..02baeaa 100644
> --- a/arch/arm/plat-s5pc1xx/cpu.c
> +++ b/arch/arm/plat-s5pc1xx/cpu.c
> @@ -60,6 +60,11 @@ static struct map_desc s5pc1xx_iodesc[] __initdata = {
>  		.length		= SZ_4K,
>  		.type		= MT_DEVICE,
>  	}, {
> +		.virtual	= (unsigned long)S5PC1XX_VA_GPIO,
> +		.pfn		= __phys_to_pfn(S5PC100_PA_GPIO),
> +		.length		= SZ_4K,
> +		.type		= MT_DEVICE,
> +	}, {
>  		.virtual	= (unsigned long)S5PC1XX_VA_CHIPID,
>  		.pfn		= __phys_to_pfn(S5PC1XX_PA_CHIPID),
>  		.length		= SZ_16,
> diff --git a/arch/arm/plat-s5pc1xx/gpio-config.c b/arch/arm/plat-s5pc1xx/gpio-config.c
> new file mode 100644
> index 0000000..b911475
> --- /dev/null
> +++ b/arch/arm/plat-s5pc1xx/gpio-config.c
> @@ -0,0 +1,61 @@
> +/* linux/arch/arm/plat-s5pc1xx/gpio-config.c
> + *
> + * Copyright 2009 Samsung Electronics
> + *	InKi Dae  <inki.dae@samsung.com>
> + *
> + * S5PC110 GPIO Configuration.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> +*/
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/gpio.h>
> +#include <linux/io.h>
> +
> +#include <mach/gpio-core.h>
> +#include <plat/gpio-cfg-s5pc1xx.h>
> +
> +s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin, unsigned int off)
> +{
> +	struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
> +	void __iomem *reg;
> +	int shift = off * 2;
> +	u32 drvstr;
> +
> +	if (!chip)
> +		return -EINVAL;
> +
> +	reg = chip->base + 0x0C;
> +
> +	drvstr = __raw_readl(reg);
> +	drvstr = 0xffff & (0x3 << shift);
> +	drvstr = drvstr >> shift;
> +
> +	return (__force s5p_gpio_drvstr_t)drvstr;
> +}
> +EXPORT_SYMBOL(s5p_gpio_get_drvstr);
> +
> +int s5p_gpio_set_drvstr(unsigned int pin, unsigned int off,
> +			s5p_gpio_drvstr_t drvstr)
> +{
> +	struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
> +	void __iomem *reg;
> +	int shift = off * 2;
> +	u32 tmp;
> +
> +	if (!chip)
> +		return -EINVAL;
> +
> +	reg = chip->base + 0x0C;
> +
> +	tmp = __raw_readl(reg);
> +	tmp |= drvstr << shift;
> +
> +	__raw_writel(tmp, reg);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(s5p_gpio_set_drvstr);
> diff --git a/arch/arm/plat-s5pc1xx/gpiolib.c b/arch/arm/plat-s5pc1xx/gpiolib.c
> new file mode 100644
> index 0000000..9da8efc
> --- /dev/null
> +++ b/arch/arm/plat-s5pc1xx/gpiolib.c
> @@ -0,0 +1,503 @@
> +/*
> + * arch/arm/plat-s5pc1xx/gpiolib.c
> + *
> + *  Copyright 2009 Samsung Electronics Co
> + *  Kyungmin Park <kyungmin.park@samsung.com>
> + *
> + * S5PC1XX - GPIOlib support
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/irq.h>
> +#include <linux/io.h>
> +
> +#include <mach/map.h>
> +#include <mach/gpio.h>
> +#include <mach/gpio-core.h>
> +
> +#include <plat/gpio-cfg.h>
> +#include <plat/gpio-cfg-helpers.h>
> +#include <plat/regs-gpio.h>
> +
> +/* S5PC100 GPIO bank summary:
> + *
> + * Bank	GPIOs	Style	INT Type
> + * A0	8	4Bit	GPIO_INT0
> + * A1	5	4Bit	GPIO_INT1
> + * B	8	4Bit	GPIO_INT2
> + * C	5	4Bit	GPIO_INT3
> + * D	7	4Bit	GPIO_INT4
> + * E0	8	4Bit	GPIO_INT5
> + * E1	6	4Bit	GPIO_INT6
> + * F0	8	4Bit	GPIO_INT7
> + * F1	8	4Bit	GPIO_INT8
> + * F2	8	4Bit	GPIO_INT9
> + * F3	4	4Bit	GPIO_INT10
> + * G0	8	4Bit	GPIO_INT11
> + * G1	3	4Bit	GPIO_INT12
> + * G2	7	4Bit	GPIO_INT13
> + * G3	7	4Bit	GPIO_INT14
> + * H0	8	4Bit	WKUP_INT
> + * H1	8	4Bit	WKUP_INT
> + * H2	8	4Bit	WKUP_INT
> + * H3	8	4Bit	WKUP_INT
> + * I	8	4Bit	GPIO_INT15
> + * J0	8	4Bit	GPIO_INT16
> + * J1	5	4Bit	GPIO_INT17
> + * J2	8	4Bit	GPIO_INT18
> + * J3	8	4Bit	GPIO_INT19
> + * J4	4	4Bit	GPIO_INT20
> + * K0	8	4Bit	None
> + * K1	6	4Bit	None
> + * K2	8	4Bit	None
> + * K3	8	4Bit	None
> + * L0	8	4Bit	None
> + * L1	8	4Bit	None
> + * L2	8	4Bit	None
> + * L3	8	4Bit	None
> + */
> +
> +#define OFF_GPCON	(0x00)
> +#define OFF_GPDAT	(0x04)
> +
> +#define con_4bit_shift(__off) ((__off) * 4)
> +
> +#if 1
> +#define gpio_dbg(x...) do { } while (0)
> +#else
> +#define gpio_dbg(x...) printk(KERN_DEBUG x)
> +#endif
> +
> +/* The s5pc1xx_gpiolib routines are to control the gpio banks where
> + * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
> + * following example:
> + *
> + * base + 0x00: Control register, 4 bits per gpio
> + *	        gpio n: 4 bits starting at (4*n)
> + *		0000 = input, 0001 = output, others mean special-function
> + * base + 0x04: Data register, 1 bit per gpio
> + *		bit n: data bit n
> + *
> + * Note, since the data register is one bit per gpio and is at base + 0x4
> + * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of
> + * the output.
> + */
> +
> +static int s5pc1xx_gpiolib_input(struct gpio_chip *chip, unsigned offset)
> +{
> +	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
> +	void __iomem *base = ourchip->base;
> +	unsigned long con;
> +
> +	con = __raw_readl(base + OFF_GPCON);
> +	con &= ~(0xf << con_4bit_shift(offset));
> +	__raw_writel(con, base + OFF_GPCON);
> +
> +	gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
> +
> +	return 0;
> +}
> +
> +static int s5pc1xx_gpiolib_output(struct gpio_chip *chip,
> +				       unsigned offset, int value)
> +{
> +	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
> +	void __iomem *base = ourchip->base;
> +	unsigned long con;
> +	unsigned long dat;
> +
> +	con = __raw_readl(base + OFF_GPCON);
> +	con &= ~(0xf << con_4bit_shift(offset));
> +	con |= 0x1 << con_4bit_shift(offset);
> +
> +	dat = __raw_readl(base + OFF_GPDAT);
> +	if (value)
> +		dat |= 1 << offset;
> +	else
> +		dat &= ~(1 << offset);
> +
> +	__raw_writel(dat, base + OFF_GPDAT);
> +	__raw_writel(con, base + OFF_GPCON);
> +	__raw_writel(dat, base + OFF_GPDAT);
> +
> +	gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
> +
> +	return 0;
> +}
> +
> +static int s5pc1xx_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
> +{
> +	return S3C_IRQ_GPIO(chip->base + offset);
> +}
> +
> +static int s5pc1xx_gpiolib_to_eint(struct gpio_chip *chip, unsigned int offset)
> +{
> +	int base;
> +
> +	base = chip->base - S5PC100_GPH0(0);
> +	if (base == 0)
> +		return IRQ_EINT(offset);
> +	base = chip->base - S5PC100_GPH1(0);
> +	if (base == 0)
> +		return IRQ_EINT(8 + offset);
> +	base = chip->base - S5PC100_GPH2(0);
> +	if (base == 0)
> +		return IRQ_EINT(16 + offset);
> +	base = chip->base - S5PC100_GPH3(0);
> +	if (base == 0)
> +		return IRQ_EINT(24 + offset);
> +	return -EINVAL;
> +}
> +
> +static struct s3c_gpio_cfg gpio_cfg = {
> +	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
> +	.set_pull	= s3c_gpio_setpull_updown,
> +	.get_pull	= s3c_gpio_getpull_updown,
> +};
> +
> +static struct s3c_gpio_cfg gpio_cfg_eint = {
> +	.cfg_eint	= 0xf,
> +	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
> +	.set_pull	= s3c_gpio_setpull_updown,
> +	.get_pull	= s3c_gpio_getpull_updown,
> +};
> +
> +static struct s3c_gpio_cfg gpio_cfg_noint = {
> +	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
> +	.set_pull	= s3c_gpio_setpull_updown,
> +	.get_pull	= s3c_gpio_getpull_updown,
> +};
> +
> +static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
> +	{
> +		.base	= S5PC100_GPA0_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPA0(0),
> +			.ngpio	= S5PC100_GPIO_A0_NR,
> +			.label	= "GPA0",
> +		},
> +	}, {
> +		.base	= S5PC100_GPA1_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPA1(0),
> +			.ngpio	= S5PC100_GPIO_A1_NR,
> +			.label	= "GPA1",
> +		},
> +	}, {
> +		.base	= S5PC100_GPB_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPB(0),
> +			.ngpio	= S5PC100_GPIO_B_NR,
> +			.label	= "GPB",
> +		},
> +	}, {
> +		.base	= S5PC100_GPC_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPC(0),
> +			.ngpio	= S5PC100_GPIO_C_NR,
> +			.label	= "GPC",
> +		},
> +	}, {
> +		.base	= S5PC100_GPD_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPD(0),
> +			.ngpio	= S5PC100_GPIO_D_NR,
> +			.label	= "GPD",
> +		},
> +	}, {
> +		.base	= S5PC100_GPE0_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPE0(0),
> +			.ngpio	= S5PC100_GPIO_E0_NR,
> +			.label	= "GPE0",
> +		},
> +	}, {
> +		.base	= S5PC100_GPE1_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPE1(0),
> +			.ngpio	= S5PC100_GPIO_E1_NR,
> +			.label	= "GPE1",
> +		},
> +	}, {
> +		.base	= S5PC100_GPF0_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPF0(0),
> +			.ngpio	= S5PC100_GPIO_F0_NR,
> +			.label	= "GPF0",
> +		},
> +	}, {
> +		.base	= S5PC100_GPF1_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPF1(0),
> +			.ngpio	= S5PC100_GPIO_F1_NR,
> +			.label	= "GPF1",
> +		},
> +	}, {
> +		.base	= S5PC100_GPF2_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPF2(0),
> +			.ngpio	= S5PC100_GPIO_F2_NR,
> +			.label	= "GPF2",
> +		},
> +	}, {
> +		.base	= S5PC100_GPF3_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPF3(0),
> +			.ngpio	= S5PC100_GPIO_F3_NR,
> +			.label	= "GPF3",
> +		},
> +	}, {
> +		.base	= S5PC100_GPG0_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPG0(0),
> +			.ngpio	= S5PC100_GPIO_G0_NR,
> +			.label	= "GPG0",
> +		},
> +	}, {
> +		.base	= S5PC100_GPG1_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPG1(0),
> +			.ngpio	= S5PC100_GPIO_G1_NR,
> +			.label	= "GPG1",
> +		},
> +	}, {
> +		.base	= S5PC100_GPG2_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPG2(0),
> +			.ngpio	= S5PC100_GPIO_G2_NR,
> +			.label	= "GPG2",
> +		},
> +	}, {
> +		.base	= S5PC100_GPG3_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPG3(0),
> +			.ngpio	= S5PC100_GPIO_G3_NR,
> +			.label	= "GPG3",
> +		},
> +	}, {
> +		.base	= S5PC100_GPH0_BASE,
> +		.config	= &gpio_cfg_eint,
> +		.chip	= {
> +			.base	= S5PC100_GPH0(0),
> +			.ngpio	= S5PC100_GPIO_H0_NR,
> +			.label	= "GPH0",
> +		},
> +	}, {
> +		.base	= S5PC100_GPH1_BASE,
> +		.config	= &gpio_cfg_eint,
> +		.chip	= {
> +			.base	= S5PC100_GPH1(0),
> +			.ngpio	= S5PC100_GPIO_H1_NR,
> +			.label	= "GPH1",
> +		},
> +	}, {
> +		.base	= S5PC100_GPH2_BASE,
> +		.config	= &gpio_cfg_eint,
> +		.chip	= {
> +			.base	= S5PC100_GPH2(0),
> +			.ngpio	= S5PC100_GPIO_H2_NR,
> +			.label	= "GPH2",
> +		},
> +	}, {
> +		.base	= S5PC100_GPH3_BASE,
> +		.config	= &gpio_cfg_eint,
> +		.chip	= {
> +			.base	= S5PC100_GPH3(0),
> +			.ngpio	= S5PC100_GPIO_H3_NR,
> +			.label	= "GPH3",
> +		},
> +	}, {
> +		.base	= S5PC100_GPI_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPI(0),
> +			.ngpio	= S5PC100_GPIO_I_NR,
> +			.label	= "GPI",
> +		},
> +	}, {
> +		.base	= S5PC100_GPJ0_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPJ0(0),
> +			.ngpio	= S5PC100_GPIO_J0_NR,
> +			.label	= "GPJ0",
> +		},
> +	}, {
> +		.base	= S5PC100_GPJ1_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPJ1(0),
> +			.ngpio	= S5PC100_GPIO_J1_NR,
> +			.label	= "GPJ1",
> +		},
> +	}, {
> +		.base	= S5PC100_GPJ2_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPJ2(0),
> +			.ngpio	= S5PC100_GPIO_J2_NR,
> +			.label	= "GPJ2",
> +		},
> +	}, {
> +		.base	= S5PC100_GPJ3_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPJ3(0),
> +			.ngpio	= S5PC100_GPIO_J3_NR,
> +			.label	= "GPJ3",
> +		},
> +	}, {
> +		.base	= S5PC100_GPJ4_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPJ4(0),
> +			.ngpio	= S5PC100_GPIO_J4_NR,
> +			.label	= "GPJ4",
> +		},
> +	}, {
> +		.base	= S5PC100_GPK0_BASE,
> +		.config	= &gpio_cfg_noint,
> +		.chip	= {
> +			.base	= S5PC100_GPK0(0),
> +			.ngpio	= S5PC100_GPIO_K0_NR,
> +			.label	= "GPK0",
> +		},
> +	}, {
> +		.base	= S5PC100_GPK1_BASE,
> +		.config	= &gpio_cfg_noint,
> +		.chip	= {
> +			.base	= S5PC100_GPK1(0),
> +			.ngpio	= S5PC100_GPIO_K1_NR,
> +			.label	= "GPK1",
> +		},
> +	}, {
> +		.base	= S5PC100_GPK2_BASE,
> +		.config	= &gpio_cfg_noint,
> +		.chip	= {
> +			.base	= S5PC100_GPK2(0),
> +			.ngpio	= S5PC100_GPIO_K2_NR,
> +			.label	= "GPK2",
> +		},
> +	}, {
> +		.base	= S5PC100_GPK3_BASE,
> +		.config	= &gpio_cfg_noint,
> +		.chip	= {
> +			.base	= S5PC100_GPK3(0),
> +			.ngpio	= S5PC100_GPIO_K3_NR,
> +			.label	= "GPK3",
> +		},
> +	}, {
> +		.base	= S5PC100_GPL0_BASE,
> +		.config	= &gpio_cfg_noint,
> +		.chip	= {
> +			.base	= S5PC100_GPL0(0),
> +			.ngpio	= S5PC100_GPIO_L0_NR,
> +			.label	= "GPL0",
> +		},
> +	}, {
> +		.base	= S5PC100_GPL1_BASE,
> +		.config	= &gpio_cfg_noint,
> +		.chip	= {
> +			.base	= S5PC100_GPL1(0),
> +			.ngpio	= S5PC100_GPIO_L1_NR,
> +			.label	= "GPL1",
> +		},
> +	}, {
> +		.base	= S5PC100_GPL2_BASE,
> +		.config	= &gpio_cfg_noint,
> +		.chip	= {
> +			.base	= S5PC100_GPL2(0),
> +			.ngpio	= S5PC100_GPIO_L2_NR,
> +			.label	= "GPL2",
> +		},
> +	}, {
> +		.base	= S5PC100_GPL3_BASE,
> +		.config	= &gpio_cfg_noint,
> +		.chip	= {
> +			.base	= S5PC100_GPL3(0),
> +			.ngpio	= S5PC100_GPIO_L3_NR,
> +			.label	= "GPL3",
> +		},
> +	}, {
> +		.base	= S5PC100_GPL4_BASE,
> +		.config	= &gpio_cfg_noint,
> +		.chip	= {
> +			.base	= S5PC100_GPL4(0),
> +			.ngpio	= S5PC100_GPIO_L4_NR,
> +			.label	= "GPL4",
> +		},
> +	},
> +};
> +
> +/* FIXME move from irq-gpio.c */
> +extern struct irq_chip s5pc1xx_gpioint;
> +extern void s5pc1xx_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc);
> +
> +static __init void s5pc1xx_gpiolib_link(struct s3c_gpio_chip *chip)
> +{
> +	chip->chip.direction_input = s5pc1xx_gpiolib_input;
> +	chip->chip.direction_output = s5pc1xx_gpiolib_output;
> +	chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
> +
> +	/* Interrupt */
> +	if (chip->config == &gpio_cfg) {
> +		int i, irq;
> +
> +		chip->chip.to_irq = s5pc1xx_gpiolib_to_irq;
> +
> +		for (i = 0;  i < chip->chip.ngpio; i++) {
> +			irq = S3C_IRQ_GPIO_BASE + chip->chip.base + i;
> +			set_irq_chip(irq, &s5pc1xx_gpioint);
> +			set_irq_data(irq, &chip->chip);
> +			set_irq_handler(irq, handle_level_irq);
> +			set_irq_flags(irq, IRQF_VALID);
> +		}
> +	} else if (chip->config == &gpio_cfg_eint)
> +		chip->chip.to_irq = s5pc1xx_gpiolib_to_eint;
> +}
> +
> +static __init void s5pc1xx_gpiolib_add(struct s3c_gpio_chip *chips,
> +				       int nr_chips,
> +				       void (*fn)(struct s3c_gpio_chip *))
> +{
> +	for (; nr_chips > 0; nr_chips--, chips++) {
> +		if (fn)
> +			(fn)(chips);
> +		s3c_gpiolib_add(chips);
> +	}
> +}
> +
> +static __init int s5pc1xx_gpiolib_init(void)
> +{
> +	struct s3c_gpio_chip *chips;
> +	int nr_chips;
> +
> +		chips = s5pc100_gpio_chips;
> +		nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
> +
> +	s5pc1xx_gpiolib_add(chips, nr_chips, s5pc1xx_gpiolib_link);
> +	/* Interrupt */
> +	set_irq_chained_handler(IRQ_GPIOINT, s5pc1xx_irq_gpioint_handler);
> +
> +	return 0;
> +}
> +core_initcall(s5pc1xx_gpiolib_init);
> diff --git a/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h b/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h
> new file mode 100644
> index 0000000..c29ee25
> --- /dev/null
> +++ b/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h
> @@ -0,0 +1,33 @@
> +/* linux/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg.h
> + *
> + * Copyright 2009 Samsung Electronic
> + *	InKi Dae <inki.dae@samsung.com>
> + *
> + * S5PC1XX Platform - GPIO pin configuration
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> +*/
> +
> +/* This file contains the necessary definitions to get the basic gpio
> + * pin configuration done such as setting a pin to input or output or
> + * changing the pull-{up,down} configurations.
> + */
> +
> +#ifndef __GPIO_CFG_S5PC1XX_H
> +#define __GPIO_CFG_S5PC1XX_H __FILE__
> +
> +typedef unsigned int __bitwise__ s5p_gpio_drvstr_t;
> +
> +#define S5P_GPIO_DRVSTR_LV1	0x00
> +#define S5P_GPIO_DRVSTR_LV2	0x01
> +#define S5P_GPIO_DRVSTR_LV3	0x10
> +#define S5P_GPIO_DRVSTR_LV4	0x11
> +
> +extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin, unsigned int off);
> +
> +extern int s5p_gpio_set_drvstr(unsigned int pin, unsigned int off,
> +			s5p_gpio_drvstr_t drvstr);
> +
> +#endif /* __GPIO_CFG_S5PC1XX_H */
> diff --git a/arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h b/arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h
> new file mode 100644
> index 0000000..33ad267
> --- /dev/null
> +++ b/arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h
> @@ -0,0 +1,44 @@
> +/* linux/arch/arm/plat-s5pc1xx/include/plat/gpio-eint.h
> + *
> + * Copyright 2009 Samsung Electronics Co.
> + *
> + * External Interrupt (GPH0 ~ GPH3) control register definitions
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> +*/
> +
> +#define S5PC1XX_WKUP_INT_CON0_7		(S5PC1XX_EINT_BASE + 0x0)
> +#define S5PC1XX_WKUP_INT_CON8_15	(S5PC1XX_EINT_BASE + 0x4)
> +#define S5PC1XX_WKUP_INT_CON16_23	(S5PC1XX_EINT_BASE + 0x8)
> +#define S5PC1XX_WKUP_INT_CON24_31	(S5PC1XX_EINT_BASE + 0xC)
> +#define S5PC1XX_WKUP_INT_CON(x)		(S5PC1XX_WKUP_INT_CON0_7 + (x * 0x4))
> +
> +#define S5PC1XX_WKUP_INT_FLTCON0_3	(S5PC1XX_EINT_BASE + 0x80)
> +#define S5PC1XX_WKUP_INT_FLTCON4_7	(S5PC1XX_EINT_BASE + 0x84)
> +#define S5PC1XX_WKUP_INT_FLTCON8_11	(S5PC1XX_EINT_BASE + 0x88)
> +#define S5PC1XX_WKUP_INT_FLTCON12_15	(S5PC1XX_EINT_BASE + 0x8C)
> +#define S5PC1XX_WKUP_INT_FLTCON16_19	(S5PC1XX_EINT_BASE + 0x90)
> +#define S5PC1XX_WKUP_INT_FLTCON20_23	(S5PC1XX_EINT_BASE + 0x94)
> +#define S5PC1XX_WKUP_INT_FLTCON24_27	(S5PC1XX_EINT_BASE + 0x98)
> +#define S5PC1XX_WKUP_INT_FLTCON28_31	(S5PC1XX_EINT_BASE + 0x9C)
> +#define S5PC1XX_WKUP_INT_FLTCON(x)	(S5PC1XX_WKUP_INT_FLTCON0_3 + (x * 0x4))
> +
> +#define S5PC1XX_WKUP_INT_MASK0_7	(S5PC1XX_EINT_BASE + 0x100)
> +#define S5PC1XX_WKUP_INT_MASK8_15	(S5PC1XX_EINT_BASE + 0x104)
> +#define S5PC1XX_WKUP_INT_MASK16_23	(S5PC1XX_EINT_BASE + 0x108)
> +#define S5PC1XX_WKUP_INT_MASK24_31	(S5PC1XX_EINT_BASE + 0x10C)
> +#define S5PC1XX_WKUP_INT_MASK(x)	(S5PC1XX_WKUP_INT_MASK0_7 + (x * 0x4))
> +
> +#define S5PC1XX_WKUP_INT_PEND0_7	(S5PC1XX_EINT_BASE + 0x140)
> +#define S5PC1XX_WKUP_INT_PEND8_15	(S5PC1XX_EINT_BASE + 0x144)
> +#define S5PC1XX_WKUP_INT_PEND16_23	(S5PC1XX_EINT_BASE + 0x148)
> +#define S5PC1XX_WKUP_INT_PEND24_31	(S5PC1XX_EINT_BASE + 0x14C)
> +#define S5PC1XX_WKUP_INT_PEND(x)	(S5PC1XX_WKUP_INT_PEND0_7 + (x * 0x4))
> +
> +#define S5PC1XX_WKUP_INT_LOWLEV		(0x00)
> +#define S5PC1XX_WKUP_INT_HILEV		(0x01)
> +#define S5PC1XX_WKUP_INT_FALLEDGE	(0x02)
> +#define S5PC1XX_WKUP_INT_RISEEDGE	(0x03)
> +#define S5PC1XX_WKUP_INT_BOTHEDGE	(0x04)
> diff --git a/arch/arm/plat-s5pc1xx/include/plat/irqs.h b/arch/arm/plat-s5pc1xx/include/plat/irqs.h
> index f07d8c3..ef87363 100644
> --- a/arch/arm/plat-s5pc1xx/include/plat/irqs.h
> +++ b/arch/arm/plat-s5pc1xx/include/plat/irqs.h
> @@ -171,12 +171,21 @@
>  #define IRQ_SDMIRQ		S5PC1XX_IRQ_VIC2(30)
>  #define IRQ_SDMFIQ		S5PC1XX_IRQ_VIC2(31)
>  
> +/* External interrupt */
>  #define S3C_IRQ_EINT_BASE	(IRQ_SDMFIQ + 1)
>  
> -#define S3C_EINT(x)		((x) + S3C_IRQ_EINT_BASE)
> -#define IRQ_EINT(x)		S3C_EINT(x)
> +#define S3C_EINT(x)		(S3C_IRQ_EINT_BASE + (x - 16))
> +#define IRQ_EINT(x)		(x < 16 ? IRQ_EINT0 + x : S3C_EINT(x))
> +#define IRQ_EINT_BIT(x)		(x < IRQ_EINT16_31 ? x - IRQ_EINT0 : x - S3C_EINT(0))
>  
> -#define NR_IRQS 		(IRQ_EINT(31)+1)
> +/* GPIO interrupt */
> +#define S3C_IRQ_GPIO_BASE	(IRQ_EINT(31) + 1)
> +#define S3C_IRQ_GPIO(x)		(S3C_IRQ_GPIO_BASE + (x))
> +
> +/*
> + * Until MP04 Groups -> 40 (exactly 39) Groups * 8 ~= 320 GPIOs
> + */
> +#define NR_IRQS			(S3C_IRQ_GPIO(320) + 1)
>  
>  #endif /* __ASM_PLAT_S5PC1XX_IRQS_H */
>  
> diff --git a/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h b/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
> new file mode 100644
> index 0000000..43c7bc8
> --- /dev/null
> +++ b/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
> @@ -0,0 +1,70 @@
> +/* linux/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
> + *
> + * Copyright 2009 Samsung Electronics Co.
> + *      Byungho Min <bhmin@samsung.com>
> + *
> + * S5PC1XX - GPIO register definitions
> + */
> +
> +#ifndef __ASM_PLAT_S5PC1XX_REGS_GPIO_H
> +#define __ASM_PLAT_S5PC1XX_REGS_GPIO_H __FILE__
> +
> +#include <mach/map.h>
> +
> +/* S5PC100 */
> +#define S5PC100_GPIO_BASE	S5PC1XX_VA_GPIO
> +#define S5PC100_GPA0_BASE	(S5PC100_GPIO_BASE + 0x0000)
> +#define S5PC100_GPA1_BASE	(S5PC100_GPIO_BASE + 0x0020)
> +#define S5PC100_GPB_BASE	(S5PC100_GPIO_BASE + 0x0040)
> +#define S5PC100_GPC_BASE	(S5PC100_GPIO_BASE + 0x0060)
> +#define S5PC100_GPD_BASE	(S5PC100_GPIO_BASE + 0x0080)
> +#define S5PC100_GPE0_BASE	(S5PC100_GPIO_BASE + 0x00A0)
> +#define S5PC100_GPE1_BASE	(S5PC100_GPIO_BASE + 0x00C0)
> +#define S5PC100_GPF0_BASE	(S5PC100_GPIO_BASE + 0x00E0)
> +#define S5PC100_GPF1_BASE	(S5PC100_GPIO_BASE + 0x0100)
> +#define S5PC100_GPF2_BASE	(S5PC100_GPIO_BASE + 0x0120)
> +#define S5PC100_GPF3_BASE	(S5PC100_GPIO_BASE + 0x0140)
> +#define S5PC100_GPG0_BASE	(S5PC100_GPIO_BASE + 0x0160)
> +#define S5PC100_GPG1_BASE	(S5PC100_GPIO_BASE + 0x0180)
> +#define S5PC100_GPG2_BASE	(S5PC100_GPIO_BASE + 0x01A0)
> +#define S5PC100_GPG3_BASE	(S5PC100_GPIO_BASE + 0x01C0)
> +#define S5PC100_GPH0_BASE	(S5PC100_GPIO_BASE + 0x0C00)
> +#define S5PC100_GPH1_BASE	(S5PC100_GPIO_BASE + 0x0C20)
> +#define S5PC100_GPH2_BASE	(S5PC100_GPIO_BASE + 0x0C40)
> +#define S5PC100_GPH3_BASE	(S5PC100_GPIO_BASE + 0x0C60)
> +#define S5PC100_GPI_BASE	(S5PC100_GPIO_BASE + 0x01E0)
> +#define S5PC100_GPJ0_BASE	(S5PC100_GPIO_BASE + 0x0200)
> +#define S5PC100_GPJ1_BASE	(S5PC100_GPIO_BASE + 0x0220)
> +#define S5PC100_GPJ2_BASE	(S5PC100_GPIO_BASE + 0x0240)
> +#define S5PC100_GPJ3_BASE	(S5PC100_GPIO_BASE + 0x0260)
> +#define S5PC100_GPJ4_BASE	(S5PC100_GPIO_BASE + 0x0280)
> +#define S5PC100_GPK0_BASE	(S5PC100_GPIO_BASE + 0x02A0)
> +#define S5PC100_GPK1_BASE	(S5PC100_GPIO_BASE + 0x02C0)
> +#define S5PC100_GPK2_BASE	(S5PC100_GPIO_BASE + 0x02E0)
> +#define S5PC100_GPK3_BASE	(S5PC100_GPIO_BASE + 0x0300)
> +#define S5PC100_GPL0_BASE	(S5PC100_GPIO_BASE + 0x0320)
> +#define S5PC100_GPL1_BASE	(S5PC100_GPIO_BASE + 0x0340)
> +#define S5PC100_GPL2_BASE	(S5PC100_GPIO_BASE + 0x0360)
> +#define S5PC100_GPL3_BASE	(S5PC100_GPIO_BASE + 0x0380)
> +#define S5PC100_GPL4_BASE	(S5PC100_GPIO_BASE + 0x03A0)
> +#define S5PC100_EINT_BASE	(S5PC100_GPIO_BASE + 0x0E00)
> +
> +#define S5PC100_UHOST		(S5PC100_GPIO_BASE + 0x0B68)
> +#define S5PC100_PDNEN		(S5PC100_GPIO_BASE + 0x0F80)
> +
> +/* PDNEN */
> +#define S5PC100_PDNEN_CFG_PDNEN	(1 << 1)
> +#define S5PC100_PDNEN_CFG_AUTO	(0 << 1)
> +#define S5PC100_PDNEN_POWERDOWN	(1 << 0)
> +#define S5PC100_PDNEN_NORMAL	(0 << 0)
> +
> +/* Common part */
> +/* External interrupt base is same at both s5pc100 and s5pc110 */
> +#define S5PC1XX_EINT_BASE	(S5PC100_EINT_BASE)
> +
> +#define S5PC100_GPx_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
> +#define S5PC100_GPx_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
> +#define S5PC100_GPx_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
> +
> +#endif /* __ASM_PLAT_S5PC1XX_REGS_GPIO_H */
> +
> diff --git a/arch/arm/plat-s5pc1xx/irq-eint.c b/arch/arm/plat-s5pc1xx/irq-eint.c
> new file mode 100644
> index 0000000..34f9443
> --- /dev/null
> +++ b/arch/arm/plat-s5pc1xx/irq-eint.c
> @@ -0,0 +1,281 @@
> +/*
> + * linux/arch/arm/plat-s5pc1xx/irq-eint.c
> + *
> + *  Copyright 2009 Samsung Electronics Co.
> + *  Byungho Min <bhmin@samsung.com>
> + *  Kyungin Park <kyungmin.park@samsung.com>
> + *
> + * Based on plat-s3c64xx/irq-eint.c
> + *
> + * S5PC1XX - Interrupt handling for IRQ_EINT(x)
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/io.h>
> +#include <linux/sysdev.h>
> +#include <linux/pm.h>
> +
> +#include <asm/hardware/vic.h>
> +
> +#include <mach/map.h>
> +#include <mach/gpio.h>
> +
> +#include <plat/gpio-cfg.h>
> +#include <plat/gpio-ext.h>
> +#include <plat/pm.h>
> +#include <plat/regs-gpio.h>
> +#include <plat/regs-irqtype.h>
> +
> +/*
> + * bank is a group of external interrupt
> + * bank0 means EINT0 ... EINT7
> + * bank1 means EINT8 ... EINT15
> + * bank2 means EINT16 ... EINT23
> + * bank3 means EINT24 ... EINT31
> + */
> +
> +static inline int s3c_get_eint(unsigned int irq)
> +{
> +	int real;
> +
> +	if (irq < IRQ_EINT16_31)
> +		real = (irq - IRQ_EINT0);
> +	else
> +		real = (irq - S3C_IRQ_EINT_BASE) + IRQ_EINT16_31 - IRQ_EINT0;
> +
> +	return real;
> +}
> +
> +static inline int s3c_get_bank(unsigned int irq)
> +{
> +	return s3c_get_eint(irq) >> 3;
> +}
> +
> +static inline int s3c_eint_to_bit(unsigned int irq)
> +{
> +	int real, bit;
> +
> +	real = s3c_get_eint(irq);
> +	bit = 1 << (real & (8 - 1));
> +
> +	return bit;
> +}
> +
> +static inline void s3c_irq_eint_mask(unsigned int irq)
> +{
> +	u32 mask;
> +	u32 bank = s3c_get_bank(irq);
> +
> +	mask = __raw_readl(S5PC1XX_WKUP_INT_MASK(bank));
> +	mask |= s3c_eint_to_bit(irq);
> +	__raw_writel(mask, S5PC1XX_WKUP_INT_MASK(bank));
> +}
> +
> +static void s3c_irq_eint_unmask(unsigned int irq)
> +{
> +	u32 mask;
> +	u32 bank = s3c_get_bank(irq);
> +
> +	mask = __raw_readl(S5PC1XX_WKUP_INT_MASK(bank));
> +	mask &= ~(s3c_eint_to_bit(irq));
> +	__raw_writel(mask, S5PC1XX_WKUP_INT_MASK(bank));
> +}
> +
> +static inline void s3c_irq_eint_ack(unsigned int irq)
> +{
> +	u32 bank = s3c_get_bank(irq);
> +
> +	__raw_writel(s3c_eint_to_bit(irq), S5PC1XX_WKUP_INT_PEND(bank));
> +}
> +
> +static void s3c_irq_eint_maskack(unsigned int irq)
> +{
> +	/* compiler should in-line these */
> +	s3c_irq_eint_mask(irq);
> +	s3c_irq_eint_ack(irq);
> +}
> +
> +static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
> +{
> +	u32 bank = s3c_get_bank(irq);
> +	int real = s3c_get_eint(irq);
> +	int gpio, shift, sfn;
> +	u32 ctrl, con = 0;
> +
> +	switch (type) {
> +	case IRQ_TYPE_NONE:
> +		printk(KERN_WARNING "No edge setting!\n");
> +		break;
> +
> +	case IRQ_TYPE_EDGE_RISING:
> +		con = S5PC1XX_WKUP_INT_RISEEDGE;
> +		break;
> +
> +	case IRQ_TYPE_EDGE_FALLING:
> +		con = S5PC1XX_WKUP_INT_FALLEDGE;
> +		break;
> +
> +	case IRQ_TYPE_EDGE_BOTH:
> +		con = S5PC1XX_WKUP_INT_BOTHEDGE;
> +		break;
> +
> +	case IRQ_TYPE_LEVEL_LOW:
> +		con = S5PC1XX_WKUP_INT_LOWLEV;
> +		break;
> +
> +	case IRQ_TYPE_LEVEL_HIGH:
> +		con = S5PC1XX_WKUP_INT_HILEV;
> +		break;
> +
> +	default:
> +		printk(KERN_ERR "No such irq type %d", type);
> +		return -EINVAL;
> +	}
> +
> +	gpio = real & (8 - 1);
> +	shift = gpio << 2;
> +
> +	ctrl = __raw_readl(S5PC1XX_WKUP_INT_CON(bank));
> +	ctrl &= ~(0x7 << shift);
> +	ctrl |= con << shift;
> +	__raw_writel(ctrl, S5PC1XX_WKUP_INT_CON(bank));
> +
> +	switch (real) {
> +	case 0 ... 7:
> +			gpio = S5PC100_GPH0(gpio);
> +		break;
> +	case 8 ... 15:
> +			gpio = S5PC100_GPH1(gpio);
> +		break;
> +	case 16 ... 23:
> +			gpio = S5PC100_GPH2(gpio);
> +		break;
> +	case 24 ... 31:
> +			gpio = S5PC100_GPH3(gpio);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	sfn = S3C_GPIO_SFN(0x2);
> +	s3c_gpio_cfgpin(gpio, sfn);
> +
> +	return 0;
> +}
> +
> +static struct irq_chip s3c_irq_eint = {
> +	.name		= "EINT",
> +	.mask		= s3c_irq_eint_mask,
> +	.unmask		= s3c_irq_eint_unmask,
> +	.mask_ack	= s3c_irq_eint_maskack,
> +	.ack		= s3c_irq_eint_ack,
> +	.set_type	= s3c_irq_eint_set_type,
> +	.set_wake	= s3c_irqext_wake,
> +};
> +
> +/* s3c_irq_demux_eint
> + *
> + * This function demuxes the IRQ from external interrupts,
> + * from IRQ_EINT(16) to IRQ_EINT(31). It is designed to be inlined into
> + * the specific handlers s3c_irq_demux_eintX_Y.
> + */
> +static inline void s3c_irq_demux_eint(unsigned int start, unsigned int end)
> +{
> +	u32 status = __raw_readl(S5PC1XX_WKUP_INT_PEND((start >> 3)));
> +	u32 mask = __raw_readl(S5PC1XX_WKUP_INT_MASK((start >> 3)));
> +	unsigned int irq;
> +
> +	status &= ~mask;
> +	status &= (1 << (end - start + 1)) - 1;
> +
> +	for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
> +		if (status & 1)
> +			generic_handle_irq(irq);
> +
> +		status >>= 1;
> +	}
> +}
> +
> +static void s3c_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
> +{
> +	s3c_irq_demux_eint(16, 23);
> +	s3c_irq_demux_eint(24, 31);
> +}
> +
> +/*
> + * Handle EINT0 ... EINT15 at VIC directly
> + */
> +static void s3c_irq_vic_eint_mask(unsigned int irq)
> +{
> +	void __iomem *base = get_irq_chip_data(irq);
> +	unsigned int real;
> +
> +	s3c_irq_eint_mask(irq);
> +	real = s3c_get_eint(irq);
> +	writel(1 << real, base + VIC_INT_ENABLE_CLEAR);
> +}
> +
> +static void s3c_irq_vic_eint_unmask(unsigned int irq)
> +{
> +	void __iomem *base = get_irq_chip_data(irq);
> +	unsigned int real;
> +
> +	s3c_irq_eint_unmask(irq);
> +	real = s3c_get_eint(irq);
> +	writel(1 << real, base + VIC_INT_ENABLE);
> +}
> +
> +static inline void s3c_irq_vic_eint_ack(unsigned int irq)
> +{
> +	u32 bit;
> +	u32 bank = s3c_get_bank(irq);
> +
> +	bit = s3c_eint_to_bit(irq);
> +	__raw_writel(bit, S5PC1XX_WKUP_INT_PEND(bank));
> +}
> +
> +static void s3c_irq_vic_eint_maskack(unsigned int irq)
> +{
> +	/* compiler should in-line these */
> +	s3c_irq_vic_eint_mask(irq);
> +	s3c_irq_vic_eint_ack(irq);
> +}
> +
> +static struct irq_chip s3c_irq_vic_eint = {
> +	.name		= "EINT",
> +	.mask		= s3c_irq_vic_eint_mask,
> +	.unmask		= s3c_irq_vic_eint_unmask,
> +	.mask_ack	= s3c_irq_vic_eint_maskack,
> +	.ack		= s3c_irq_vic_eint_ack,
> +	.set_type	= s3c_irq_eint_set_type,
> +	.set_wake	= s3c_irqext_wake,
> +};
> +
> +static int __init s5pc1xx_init_irq_eint(void)
> +{
> +	int irq;
> +
> +	for (irq = IRQ_EINT0; irq <= IRQ_EINT15; irq++) {
> +		set_irq_chip(irq, &s3c_irq_vic_eint);
> +		set_irq_handler(irq, handle_level_irq);
> +		set_irq_flags(irq, IRQF_VALID);
> +	}
> +
> +	for (irq = IRQ_EINT(16); irq <= IRQ_EINT(31); irq++) {
> +		set_irq_chip(irq, &s3c_irq_eint);
> +		set_irq_handler(irq, handle_level_irq);
> +		set_irq_flags(irq, IRQF_VALID);
> +	}
> +
> +	set_irq_chained_handler(IRQ_EINT16_31, s3c_irq_demux_eint16_31);
> +
> +	return 0;
> +}
> +
> +arch_initcall(s5pc1xx_init_irq_eint);
> diff --git a/arch/arm/plat-s5pc1xx/irq-gpio.c b/arch/arm/plat-s5pc1xx/irq-gpio.c
> new file mode 100644
> index 0000000..843a88e
> --- /dev/null
> +++ b/arch/arm/plat-s5pc1xx/irq-gpio.c
> @@ -0,0 +1,266 @@
> +/*
> + * arch/arm/plat-s5pc1xx/irq-gpio.c
> + *
> + * Copyright (C) 2009 Samsung Electronics
> + *
> + * S5PC1XX - Interrupt handling for IRQ_GPIO${group}(x)
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/io.h>
> +
> +#include <mach/map.h>
> +#include <mach/gpio.h>
> +#include <plat/gpio-cfg.h>
> +
> +#define S5PC1XX_GPIOREG(x)		(S5PC1XX_VA_GPIO + (x))
> +
> +#define CON_OFFSET			0x700
> +#define MASK_OFFSET			0x900
> +#define PEND_OFFSET			0xA00
> +#define CON_OFFSET_2			0xE00
> +#define MASK_OFFSET_2			0xF00
> +#define PEND_OFFSET_2			0xF40
> +
> +#define GPIOINT_LEVEL_LOW		0x0
> +#define GPIOINT_LEVEL_HIGH		0x1
> +#define GPIOINT_EDGE_FALLING		0x2
> +#define GPIOINT_EDGE_RISING		0x3
> +#define GPIOINT_EDGE_BOTH		0x4
> +
> +static int group_to_con_offset(int group)
> +{
> +	return group << 2;
> +}
> +
> +static int group_to_mask_offset(int group)
> +{
> +	return group << 2;
> +}
> +
> +static int group_to_pend_offset(int group)
> +{
> +	return group << 2;
> +}
> +
> +static int s5pc1xx_get_start(unsigned int group)
> +{
> +	switch (group) {
> +	case 0: return S5PC100_GPIO_A0_START;
> +	case 1: return S5PC100_GPIO_A1_START;
> +	case 2: return S5PC100_GPIO_B_START;
> +	case 3: return S5PC100_GPIO_C_START;
> +	case 4: return S5PC100_GPIO_D_START;
> +	case 5: return S5PC100_GPIO_E0_START;
> +	case 6: return S5PC100_GPIO_E1_START;
> +	case 7: return S5PC100_GPIO_F0_START;
> +	case 8: return S5PC100_GPIO_F1_START;
> +	case 9: return S5PC100_GPIO_F2_START;
> +	case 10: return S5PC100_GPIO_F3_START;
> +	case 11: return S5PC100_GPIO_G0_START;
> +	case 12: return S5PC100_GPIO_G1_START;
> +	case 13: return S5PC100_GPIO_G2_START;
> +	case 14: return S5PC100_GPIO_G3_START;
> +	case 15: return S5PC100_GPIO_I_START;
> +	case 16: return S5PC100_GPIO_J0_START;
> +	case 17: return S5PC100_GPIO_J1_START;
> +	case 18: return S5PC100_GPIO_J2_START;
> +	case 19: return S5PC100_GPIO_J3_START;
> +	case 20: return S5PC100_GPIO_J4_START;
> +	default:
> +		BUG();
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int s5pc1xx_get_group(unsigned int irq)
> +{
> +	irq -= S3C_IRQ_GPIO(0);
> +
> +	switch (irq) {
> +	case S5PC100_GPIO_A0_START ... S5PC100_GPIO_A1_START - 1:
> +		return 0;
> +	case S5PC100_GPIO_A1_START ... S5PC100_GPIO_B_START - 1:
> +		return 1;
> +	case S5PC100_GPIO_B_START ... S5PC100_GPIO_C_START - 1:
> +		return 2;
> +	case S5PC100_GPIO_C_START ... S5PC100_GPIO_D_START - 1:
> +		return 3;
> +	case S5PC100_GPIO_D_START ... S5PC100_GPIO_E0_START - 1:
> +		return 4;
> +	case S5PC100_GPIO_E0_START ... S5PC100_GPIO_E1_START - 1:
> +		return 5;
> +	case S5PC100_GPIO_E1_START ... S5PC100_GPIO_F0_START - 1:
> +		return 6;
> +	case S5PC100_GPIO_F0_START ... S5PC100_GPIO_F1_START - 1:
> +		return 7;
> +	case S5PC100_GPIO_F1_START ... S5PC100_GPIO_F2_START - 1:
> +		return 8;
> +	case S5PC100_GPIO_F2_START ... S5PC100_GPIO_F3_START - 1:
> +		return 9;
> +	case S5PC100_GPIO_F3_START ... S5PC100_GPIO_G0_START - 1:
> +		return 10;
> +	case S5PC100_GPIO_G0_START ... S5PC100_GPIO_G1_START - 1:
> +		return 11;
> +	case S5PC100_GPIO_G1_START ... S5PC100_GPIO_G2_START - 1:
> +		return 12;
> +	case S5PC100_GPIO_G2_START ... S5PC100_GPIO_G3_START - 1:
> +		return 13;
> +	case S5PC100_GPIO_G3_START ... S5PC100_GPIO_H0_START - 1:
> +		return 14;
> +	case S5PC100_GPIO_I_START ... S5PC100_GPIO_J0_START - 1:
> +		return 15;
> +	case S5PC100_GPIO_J0_START ... S5PC100_GPIO_J1_START - 1:
> +		return 16;
> +	case S5PC100_GPIO_J1_START ... S5PC100_GPIO_J2_START - 1:
> +		return 17;
> +	case S5PC100_GPIO_J2_START ... S5PC100_GPIO_J3_START - 1:
> +		return 18;
> +	case S5PC100_GPIO_J3_START ... S5PC100_GPIO_J4_START - 1:
> +		return 19;
> +	case S5PC100_GPIO_J4_START ... S5PC100_GPIO_K0_START - 1:
> +		return 20;
> +	default:
> +		BUG();
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int s5pc1xx_get_offset(unsigned int irq)
> +{
> +	struct gpio_chip *chip = get_irq_data(irq);
> +	return irq - S3C_IRQ_GPIO(chip->base);
> +}
> +
> +static void s5pc1xx_gpioint_ack(unsigned int irq)
> +{
> +	int group, offset, pend_offset;
> +	unsigned int value;
> +
> +	group = s5pc1xx_get_group(irq);
> +	offset = s5pc1xx_get_offset(irq);
> +	pend_offset = group_to_pend_offset(group);
> +
> +	value = __raw_readl(S5PC1XX_GPIOREG(PEND_OFFSET) + pend_offset);
> +	value |= 1 << offset;
> +	__raw_writel(value, S5PC1XX_GPIOREG(PEND_OFFSET) + pend_offset);
> +}
> +
> +static void s5pc1xx_gpioint_mask(unsigned int irq)
> +{
> +	int group, offset, mask_offset;
> +	unsigned int value;
> +
> +	group = s5pc1xx_get_group(irq);
> +	offset = s5pc1xx_get_offset(irq);
> +	mask_offset = group_to_mask_offset(group);
> +
> +	value = __raw_readl(S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
> +	value |= 1 << offset;
> +	__raw_writel(value, S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
> +}
> +
> +static void s5pc1xx_gpioint_unmask(unsigned int irq)
> +{
> +	int group, offset, mask_offset;
> +	unsigned int value;
> +
> +	group = s5pc1xx_get_group(irq);
> +	offset = s5pc1xx_get_offset(irq);
> +	mask_offset = group_to_mask_offset(group);
> +
> +	value = __raw_readl(S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
> +	value &= ~(1 << offset);
> +	__raw_writel(value, S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
> +}
> +
> +static void s5pc1xx_gpioint_mask_ack(unsigned int irq)
> +{
> +	s5pc1xx_gpioint_mask(irq);
> +	s5pc1xx_gpioint_ack(irq);
> +}
> +
> +static int s5pc1xx_gpioint_set_type(unsigned int irq, unsigned int type)
> +{
> +	int group, offset, con_offset;
> +	unsigned int value;
> +
> +	group = s5pc1xx_get_group(irq);
> +	offset = s5pc1xx_get_offset(irq);
> +	con_offset = group_to_con_offset(group);
> +
> +	switch (type) {
> +	case IRQ_TYPE_NONE:
> +		printk(KERN_WARNING "No irq type\n");
> +		return -EINVAL;
> +	case IRQ_TYPE_EDGE_RISING:
> +		type = GPIOINT_EDGE_RISING;
> +		break;
> +	case IRQ_TYPE_EDGE_FALLING:
> +		type = GPIOINT_EDGE_FALLING;
> +		break;
> +	case IRQ_TYPE_EDGE_BOTH:
> +		type = GPIOINT_EDGE_BOTH;
> +		break;
> +	case IRQ_TYPE_LEVEL_HIGH:
> +		type = GPIOINT_LEVEL_HIGH;
> +		break;
> +	case IRQ_TYPE_LEVEL_LOW:
> +		type = GPIOINT_LEVEL_LOW;
> +		break;
> +	default:
> +		BUG();
> +	}
> +
> +
> +	value = __raw_readl(S5PC1XX_GPIOREG(CON_OFFSET) + con_offset);
> +	value &= ~(0xf << (offset * 0x4));
> +	value |= (type << (offset * 0x4));
> +	__raw_writel(value, S5PC1XX_GPIOREG(CON_OFFSET) + con_offset);
> +
> +	return 0;
> +}
> +
> +struct irq_chip s5pc1xx_gpioint = {
> +	.name		= "GPIO",
> +	.ack		= s5pc1xx_gpioint_ack,
> +	.mask		= s5pc1xx_gpioint_mask,
> +	.mask_ack	= s5pc1xx_gpioint_mask_ack,
> +	.unmask		= s5pc1xx_gpioint_unmask,
> +	.set_type	= s5pc1xx_gpioint_set_type,
> +};
> +
> +void s5pc1xx_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc)
> +{
> +	int group, offset, pend_offset, mask_offset;
> +	int real_irq, group_end;
> +	unsigned int pend, mask;
> +
> +	group_end = 21;
> +
> +	for (group = 0; group < group_end; group++) {
> +		pend_offset = group_to_pend_offset(group);
> +		pend = __raw_readl(S5PC1XX_GPIOREG(PEND_OFFSET) + pend_offset);
> +		if (!pend)
> +			continue;
> +
> +		mask_offset = group_to_mask_offset(group);
> +		mask = __raw_readl(S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
> +		pend &= ~mask;
> +
> +		for (offset = 0; offset < 8; offset++) {
> +			if (pend & (1 << offset)) {
> +				real_irq = s5pc1xx_get_start(group) + offset;
> +				generic_handle_irq(S3C_IRQ_GPIO(real_irq));
> +			}
> +		}
> +	}
> +}
> diff --git a/arch/arm/plat-s5pc1xx/irq.c b/arch/arm/plat-s5pc1xx/irq.c
> index 80d6dd9..e44fd04 100644
> --- a/arch/arm/plat-s5pc1xx/irq.c
> +++ b/arch/arm/plat-s5pc1xx/irq.c
> @@ -79,7 +79,7 @@ static void s3c_irq_timer_ack(unsigned int irq)
>  {
>  	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
>  
> -	reg &= 0x1f;
> +	reg &= 0x1f;  /* mask out pending interrupts */
>  	reg |= (1 << 5) << (irq - IRQ_TIMER0);
>  	__raw_writel(reg, S3C64XX_TINT_CSTAT);
>  }
> -- 
> 1.6.4
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
-- 
Ben

Q:      What's a light-year?
A:      One-third less calories than a regular year.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 07/17] ARM: S5PC1xx: add gpiolib and external/gpio interrupt support
@ 2009-11-09  0:00                 ` Ben Dooks
  0 siblings, 0 replies; 76+ messages in thread
From: Ben Dooks @ 2009-11-09  0:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 13, 2009 at 10:11:12AM +0200, Marek Szyprowski wrote:
> Add support for gpiolib calls. This is based on the gpiolib implementation
> from plat-s3c64xx tree.
> Add support for external interrupts for GPIO H banks.
> Add support for GPIO interrupts for all banks.

Hmm, this one has multiple authours in the copyright, but but some
are missing from the signed-off-by.
 
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  arch/arm/plat-s3c/Kconfig                          |    6 +
>  arch/arm/plat-s3c/include/plat/gpio-cfg.h          |    1 +
>  arch/arm/plat-s5pc1xx/Kconfig                      |    3 +
>  arch/arm/plat-s5pc1xx/Makefile                     |    3 +-
>  arch/arm/plat-s5pc1xx/cpu.c                        |    5 +
>  arch/arm/plat-s5pc1xx/gpio-config.c                |   61 +++
>  arch/arm/plat-s5pc1xx/gpiolib.c                    |  503 ++++++++++++++++++++
>  .../plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h   |   33 ++
>  arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h      |   44 ++
>  arch/arm/plat-s5pc1xx/include/plat/irqs.h          |   15 +-
>  arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h     |   70 +++
>  arch/arm/plat-s5pc1xx/irq-eint.c                   |  281 +++++++++++
>  arch/arm/plat-s5pc1xx/irq-gpio.c                   |  266 +++++++++++
>  arch/arm/plat-s5pc1xx/irq.c                        |    2 +-
>  14 files changed, 1288 insertions(+), 5 deletions(-)
>  create mode 100644 arch/arm/plat-s5pc1xx/gpio-config.c
>  create mode 100644 arch/arm/plat-s5pc1xx/gpiolib.c
>  create mode 100644 arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h
>  create mode 100644 arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h
>  create mode 100644 arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
>  create mode 100644 arch/arm/plat-s5pc1xx/irq-eint.c
>  create mode 100644 arch/arm/plat-s5pc1xx/irq-gpio.c
> 
> diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig
> index 8931c5f..f155a84 100644
> --- a/arch/arm/plat-s3c/Kconfig
> +++ b/arch/arm/plat-s3c/Kconfig
> @@ -159,6 +159,12 @@ config S3C_GPIO_CFG_S3C64XX
>  	  Internal configuration to enable S3C64XX style GPIO configuration
>  	  functions.
>  
> +config S5P_GPIO_CFG_S5PC1XX
> +	bool
> +	help
> +	  Internal configuration to enable S5PC1XX style GPIO configuration
> +	  functions.
> +
>  # DMA
>  
>  config S3C_DMA
> diff --git a/arch/arm/plat-s3c/include/plat/gpio-cfg.h b/arch/arm/plat-s3c/include/plat/gpio-cfg.h
> index 29cd6a8..7e73429 100644
> --- a/arch/arm/plat-s3c/include/plat/gpio-cfg.h
> +++ b/arch/arm/plat-s3c/include/plat/gpio-cfg.h
> @@ -62,6 +62,7 @@ struct s3c_gpio_cfg {
>  #define S3C_GPIO_INPUT	(S3C_GPIO_SPECIAL(0))
>  #define S3C_GPIO_OUTPUT	(S3C_GPIO_SPECIAL(1))
>  #define S3C_GPIO_SFN(x)	(S3C_GPIO_SPECIAL(x))
> +#define S3C_GPIO_IRQ	(S3C_GPIO_SPECIAL(0xf))
>  
>  #define s3c_gpio_is_cfg_special(_cfg) \
>  	(((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK)
> diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig
> index a8a711c..86edd27 100644
> --- a/arch/arm/plat-s5pc1xx/Kconfig
> +++ b/arch/arm/plat-s5pc1xx/Kconfig
> @@ -15,6 +15,9 @@ config PLAT_S5PC1XX
>  	select ARCH_REQUIRE_GPIOLIB
>  	select S3C_GPIO_TRACK
>  	select S3C_GPIO_PULL_UPDOWN
> +	select S3C_GPIO_CFG_S3C24XX
> +	select S3C_GPIO_CFG_S3C64XX
> +	select S5P_GPIO_CFG_S5PC1XX
>  	help
>  	  Base platform code for any Samsung S5PC1XX device
>  
> diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile
> index ebbf364..f126951 100644
> --- a/arch/arm/plat-s5pc1xx/Makefile
> +++ b/arch/arm/plat-s5pc1xx/Makefile
> @@ -13,8 +13,9 @@ obj-				:=
>  
>  obj-y				+= dev-uart.o
>  obj-y				+= cpu.o
> -obj-y				+= irq.o
> +obj-y				+= irq.o irq-gpio.o irq-eint.o
>  obj-y				+= clock.o
> +obj-y				+= gpiolib.o
>  
>  # CPU support
>  
> diff --git a/arch/arm/plat-s5pc1xx/cpu.c b/arch/arm/plat-s5pc1xx/cpu.c
> index e8f3472..02baeaa 100644
> --- a/arch/arm/plat-s5pc1xx/cpu.c
> +++ b/arch/arm/plat-s5pc1xx/cpu.c
> @@ -60,6 +60,11 @@ static struct map_desc s5pc1xx_iodesc[] __initdata = {
>  		.length		= SZ_4K,
>  		.type		= MT_DEVICE,
>  	}, {
> +		.virtual	= (unsigned long)S5PC1XX_VA_GPIO,
> +		.pfn		= __phys_to_pfn(S5PC100_PA_GPIO),
> +		.length		= SZ_4K,
> +		.type		= MT_DEVICE,
> +	}, {
>  		.virtual	= (unsigned long)S5PC1XX_VA_CHIPID,
>  		.pfn		= __phys_to_pfn(S5PC1XX_PA_CHIPID),
>  		.length		= SZ_16,
> diff --git a/arch/arm/plat-s5pc1xx/gpio-config.c b/arch/arm/plat-s5pc1xx/gpio-config.c
> new file mode 100644
> index 0000000..b911475
> --- /dev/null
> +++ b/arch/arm/plat-s5pc1xx/gpio-config.c
> @@ -0,0 +1,61 @@
> +/* linux/arch/arm/plat-s5pc1xx/gpio-config.c
> + *
> + * Copyright 2009 Samsung Electronics
> + *	InKi Dae  <inki.dae@samsung.com>
> + *
> + * S5PC110 GPIO Configuration.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> +*/
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/gpio.h>
> +#include <linux/io.h>
> +
> +#include <mach/gpio-core.h>
> +#include <plat/gpio-cfg-s5pc1xx.h>
> +
> +s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin, unsigned int off)
> +{
> +	struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
> +	void __iomem *reg;
> +	int shift = off * 2;
> +	u32 drvstr;
> +
> +	if (!chip)
> +		return -EINVAL;
> +
> +	reg = chip->base + 0x0C;
> +
> +	drvstr = __raw_readl(reg);
> +	drvstr = 0xffff & (0x3 << shift);
> +	drvstr = drvstr >> shift;
> +
> +	return (__force s5p_gpio_drvstr_t)drvstr;
> +}
> +EXPORT_SYMBOL(s5p_gpio_get_drvstr);
> +
> +int s5p_gpio_set_drvstr(unsigned int pin, unsigned int off,
> +			s5p_gpio_drvstr_t drvstr)
> +{
> +	struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
> +	void __iomem *reg;
> +	int shift = off * 2;
> +	u32 tmp;
> +
> +	if (!chip)
> +		return -EINVAL;
> +
> +	reg = chip->base + 0x0C;
> +
> +	tmp = __raw_readl(reg);
> +	tmp |= drvstr << shift;
> +
> +	__raw_writel(tmp, reg);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(s5p_gpio_set_drvstr);
> diff --git a/arch/arm/plat-s5pc1xx/gpiolib.c b/arch/arm/plat-s5pc1xx/gpiolib.c
> new file mode 100644
> index 0000000..9da8efc
> --- /dev/null
> +++ b/arch/arm/plat-s5pc1xx/gpiolib.c
> @@ -0,0 +1,503 @@
> +/*
> + * arch/arm/plat-s5pc1xx/gpiolib.c
> + *
> + *  Copyright 2009 Samsung Electronics Co
> + *  Kyungmin Park <kyungmin.park@samsung.com>
> + *
> + * S5PC1XX - GPIOlib support
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/irq.h>
> +#include <linux/io.h>
> +
> +#include <mach/map.h>
> +#include <mach/gpio.h>
> +#include <mach/gpio-core.h>
> +
> +#include <plat/gpio-cfg.h>
> +#include <plat/gpio-cfg-helpers.h>
> +#include <plat/regs-gpio.h>
> +
> +/* S5PC100 GPIO bank summary:
> + *
> + * Bank	GPIOs	Style	INT Type
> + * A0	8	4Bit	GPIO_INT0
> + * A1	5	4Bit	GPIO_INT1
> + * B	8	4Bit	GPIO_INT2
> + * C	5	4Bit	GPIO_INT3
> + * D	7	4Bit	GPIO_INT4
> + * E0	8	4Bit	GPIO_INT5
> + * E1	6	4Bit	GPIO_INT6
> + * F0	8	4Bit	GPIO_INT7
> + * F1	8	4Bit	GPIO_INT8
> + * F2	8	4Bit	GPIO_INT9
> + * F3	4	4Bit	GPIO_INT10
> + * G0	8	4Bit	GPIO_INT11
> + * G1	3	4Bit	GPIO_INT12
> + * G2	7	4Bit	GPIO_INT13
> + * G3	7	4Bit	GPIO_INT14
> + * H0	8	4Bit	WKUP_INT
> + * H1	8	4Bit	WKUP_INT
> + * H2	8	4Bit	WKUP_INT
> + * H3	8	4Bit	WKUP_INT
> + * I	8	4Bit	GPIO_INT15
> + * J0	8	4Bit	GPIO_INT16
> + * J1	5	4Bit	GPIO_INT17
> + * J2	8	4Bit	GPIO_INT18
> + * J3	8	4Bit	GPIO_INT19
> + * J4	4	4Bit	GPIO_INT20
> + * K0	8	4Bit	None
> + * K1	6	4Bit	None
> + * K2	8	4Bit	None
> + * K3	8	4Bit	None
> + * L0	8	4Bit	None
> + * L1	8	4Bit	None
> + * L2	8	4Bit	None
> + * L3	8	4Bit	None
> + */
> +
> +#define OFF_GPCON	(0x00)
> +#define OFF_GPDAT	(0x04)
> +
> +#define con_4bit_shift(__off) ((__off) * 4)
> +
> +#if 1
> +#define gpio_dbg(x...) do { } while (0)
> +#else
> +#define gpio_dbg(x...) printk(KERN_DEBUG x)
> +#endif
> +
> +/* The s5pc1xx_gpiolib routines are to control the gpio banks where
> + * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
> + * following example:
> + *
> + * base + 0x00: Control register, 4 bits per gpio
> + *	        gpio n: 4 bits starting at (4*n)
> + *		0000 = input, 0001 = output, others mean special-function
> + * base + 0x04: Data register, 1 bit per gpio
> + *		bit n: data bit n
> + *
> + * Note, since the data register is one bit per gpio and is at base + 0x4
> + * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of
> + * the output.
> + */
> +
> +static int s5pc1xx_gpiolib_input(struct gpio_chip *chip, unsigned offset)
> +{
> +	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
> +	void __iomem *base = ourchip->base;
> +	unsigned long con;
> +
> +	con = __raw_readl(base + OFF_GPCON);
> +	con &= ~(0xf << con_4bit_shift(offset));
> +	__raw_writel(con, base + OFF_GPCON);
> +
> +	gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
> +
> +	return 0;
> +}
> +
> +static int s5pc1xx_gpiolib_output(struct gpio_chip *chip,
> +				       unsigned offset, int value)
> +{
> +	struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
> +	void __iomem *base = ourchip->base;
> +	unsigned long con;
> +	unsigned long dat;
> +
> +	con = __raw_readl(base + OFF_GPCON);
> +	con &= ~(0xf << con_4bit_shift(offset));
> +	con |= 0x1 << con_4bit_shift(offset);
> +
> +	dat = __raw_readl(base + OFF_GPDAT);
> +	if (value)
> +		dat |= 1 << offset;
> +	else
> +		dat &= ~(1 << offset);
> +
> +	__raw_writel(dat, base + OFF_GPDAT);
> +	__raw_writel(con, base + OFF_GPCON);
> +	__raw_writel(dat, base + OFF_GPDAT);
> +
> +	gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
> +
> +	return 0;
> +}
> +
> +static int s5pc1xx_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
> +{
> +	return S3C_IRQ_GPIO(chip->base + offset);
> +}
> +
> +static int s5pc1xx_gpiolib_to_eint(struct gpio_chip *chip, unsigned int offset)
> +{
> +	int base;
> +
> +	base = chip->base - S5PC100_GPH0(0);
> +	if (base == 0)
> +		return IRQ_EINT(offset);
> +	base = chip->base - S5PC100_GPH1(0);
> +	if (base == 0)
> +		return IRQ_EINT(8 + offset);
> +	base = chip->base - S5PC100_GPH2(0);
> +	if (base == 0)
> +		return IRQ_EINT(16 + offset);
> +	base = chip->base - S5PC100_GPH3(0);
> +	if (base == 0)
> +		return IRQ_EINT(24 + offset);
> +	return -EINVAL;
> +}
> +
> +static struct s3c_gpio_cfg gpio_cfg = {
> +	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
> +	.set_pull	= s3c_gpio_setpull_updown,
> +	.get_pull	= s3c_gpio_getpull_updown,
> +};
> +
> +static struct s3c_gpio_cfg gpio_cfg_eint = {
> +	.cfg_eint	= 0xf,
> +	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
> +	.set_pull	= s3c_gpio_setpull_updown,
> +	.get_pull	= s3c_gpio_getpull_updown,
> +};
> +
> +static struct s3c_gpio_cfg gpio_cfg_noint = {
> +	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
> +	.set_pull	= s3c_gpio_setpull_updown,
> +	.get_pull	= s3c_gpio_getpull_updown,
> +};
> +
> +static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
> +	{
> +		.base	= S5PC100_GPA0_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPA0(0),
> +			.ngpio	= S5PC100_GPIO_A0_NR,
> +			.label	= "GPA0",
> +		},
> +	}, {
> +		.base	= S5PC100_GPA1_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPA1(0),
> +			.ngpio	= S5PC100_GPIO_A1_NR,
> +			.label	= "GPA1",
> +		},
> +	}, {
> +		.base	= S5PC100_GPB_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPB(0),
> +			.ngpio	= S5PC100_GPIO_B_NR,
> +			.label	= "GPB",
> +		},
> +	}, {
> +		.base	= S5PC100_GPC_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPC(0),
> +			.ngpio	= S5PC100_GPIO_C_NR,
> +			.label	= "GPC",
> +		},
> +	}, {
> +		.base	= S5PC100_GPD_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPD(0),
> +			.ngpio	= S5PC100_GPIO_D_NR,
> +			.label	= "GPD",
> +		},
> +	}, {
> +		.base	= S5PC100_GPE0_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPE0(0),
> +			.ngpio	= S5PC100_GPIO_E0_NR,
> +			.label	= "GPE0",
> +		},
> +	}, {
> +		.base	= S5PC100_GPE1_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPE1(0),
> +			.ngpio	= S5PC100_GPIO_E1_NR,
> +			.label	= "GPE1",
> +		},
> +	}, {
> +		.base	= S5PC100_GPF0_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPF0(0),
> +			.ngpio	= S5PC100_GPIO_F0_NR,
> +			.label	= "GPF0",
> +		},
> +	}, {
> +		.base	= S5PC100_GPF1_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPF1(0),
> +			.ngpio	= S5PC100_GPIO_F1_NR,
> +			.label	= "GPF1",
> +		},
> +	}, {
> +		.base	= S5PC100_GPF2_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPF2(0),
> +			.ngpio	= S5PC100_GPIO_F2_NR,
> +			.label	= "GPF2",
> +		},
> +	}, {
> +		.base	= S5PC100_GPF3_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPF3(0),
> +			.ngpio	= S5PC100_GPIO_F3_NR,
> +			.label	= "GPF3",
> +		},
> +	}, {
> +		.base	= S5PC100_GPG0_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPG0(0),
> +			.ngpio	= S5PC100_GPIO_G0_NR,
> +			.label	= "GPG0",
> +		},
> +	}, {
> +		.base	= S5PC100_GPG1_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPG1(0),
> +			.ngpio	= S5PC100_GPIO_G1_NR,
> +			.label	= "GPG1",
> +		},
> +	}, {
> +		.base	= S5PC100_GPG2_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPG2(0),
> +			.ngpio	= S5PC100_GPIO_G2_NR,
> +			.label	= "GPG2",
> +		},
> +	}, {
> +		.base	= S5PC100_GPG3_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPG3(0),
> +			.ngpio	= S5PC100_GPIO_G3_NR,
> +			.label	= "GPG3",
> +		},
> +	}, {
> +		.base	= S5PC100_GPH0_BASE,
> +		.config	= &gpio_cfg_eint,
> +		.chip	= {
> +			.base	= S5PC100_GPH0(0),
> +			.ngpio	= S5PC100_GPIO_H0_NR,
> +			.label	= "GPH0",
> +		},
> +	}, {
> +		.base	= S5PC100_GPH1_BASE,
> +		.config	= &gpio_cfg_eint,
> +		.chip	= {
> +			.base	= S5PC100_GPH1(0),
> +			.ngpio	= S5PC100_GPIO_H1_NR,
> +			.label	= "GPH1",
> +		},
> +	}, {
> +		.base	= S5PC100_GPH2_BASE,
> +		.config	= &gpio_cfg_eint,
> +		.chip	= {
> +			.base	= S5PC100_GPH2(0),
> +			.ngpio	= S5PC100_GPIO_H2_NR,
> +			.label	= "GPH2",
> +		},
> +	}, {
> +		.base	= S5PC100_GPH3_BASE,
> +		.config	= &gpio_cfg_eint,
> +		.chip	= {
> +			.base	= S5PC100_GPH3(0),
> +			.ngpio	= S5PC100_GPIO_H3_NR,
> +			.label	= "GPH3",
> +		},
> +	}, {
> +		.base	= S5PC100_GPI_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPI(0),
> +			.ngpio	= S5PC100_GPIO_I_NR,
> +			.label	= "GPI",
> +		},
> +	}, {
> +		.base	= S5PC100_GPJ0_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPJ0(0),
> +			.ngpio	= S5PC100_GPIO_J0_NR,
> +			.label	= "GPJ0",
> +		},
> +	}, {
> +		.base	= S5PC100_GPJ1_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPJ1(0),
> +			.ngpio	= S5PC100_GPIO_J1_NR,
> +			.label	= "GPJ1",
> +		},
> +	}, {
> +		.base	= S5PC100_GPJ2_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPJ2(0),
> +			.ngpio	= S5PC100_GPIO_J2_NR,
> +			.label	= "GPJ2",
> +		},
> +	}, {
> +		.base	= S5PC100_GPJ3_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPJ3(0),
> +			.ngpio	= S5PC100_GPIO_J3_NR,
> +			.label	= "GPJ3",
> +		},
> +	}, {
> +		.base	= S5PC100_GPJ4_BASE,
> +		.config	= &gpio_cfg,
> +		.chip	= {
> +			.base	= S5PC100_GPJ4(0),
> +			.ngpio	= S5PC100_GPIO_J4_NR,
> +			.label	= "GPJ4",
> +		},
> +	}, {
> +		.base	= S5PC100_GPK0_BASE,
> +		.config	= &gpio_cfg_noint,
> +		.chip	= {
> +			.base	= S5PC100_GPK0(0),
> +			.ngpio	= S5PC100_GPIO_K0_NR,
> +			.label	= "GPK0",
> +		},
> +	}, {
> +		.base	= S5PC100_GPK1_BASE,
> +		.config	= &gpio_cfg_noint,
> +		.chip	= {
> +			.base	= S5PC100_GPK1(0),
> +			.ngpio	= S5PC100_GPIO_K1_NR,
> +			.label	= "GPK1",
> +		},
> +	}, {
> +		.base	= S5PC100_GPK2_BASE,
> +		.config	= &gpio_cfg_noint,
> +		.chip	= {
> +			.base	= S5PC100_GPK2(0),
> +			.ngpio	= S5PC100_GPIO_K2_NR,
> +			.label	= "GPK2",
> +		},
> +	}, {
> +		.base	= S5PC100_GPK3_BASE,
> +		.config	= &gpio_cfg_noint,
> +		.chip	= {
> +			.base	= S5PC100_GPK3(0),
> +			.ngpio	= S5PC100_GPIO_K3_NR,
> +			.label	= "GPK3",
> +		},
> +	}, {
> +		.base	= S5PC100_GPL0_BASE,
> +		.config	= &gpio_cfg_noint,
> +		.chip	= {
> +			.base	= S5PC100_GPL0(0),
> +			.ngpio	= S5PC100_GPIO_L0_NR,
> +			.label	= "GPL0",
> +		},
> +	}, {
> +		.base	= S5PC100_GPL1_BASE,
> +		.config	= &gpio_cfg_noint,
> +		.chip	= {
> +			.base	= S5PC100_GPL1(0),
> +			.ngpio	= S5PC100_GPIO_L1_NR,
> +			.label	= "GPL1",
> +		},
> +	}, {
> +		.base	= S5PC100_GPL2_BASE,
> +		.config	= &gpio_cfg_noint,
> +		.chip	= {
> +			.base	= S5PC100_GPL2(0),
> +			.ngpio	= S5PC100_GPIO_L2_NR,
> +			.label	= "GPL2",
> +		},
> +	}, {
> +		.base	= S5PC100_GPL3_BASE,
> +		.config	= &gpio_cfg_noint,
> +		.chip	= {
> +			.base	= S5PC100_GPL3(0),
> +			.ngpio	= S5PC100_GPIO_L3_NR,
> +			.label	= "GPL3",
> +		},
> +	}, {
> +		.base	= S5PC100_GPL4_BASE,
> +		.config	= &gpio_cfg_noint,
> +		.chip	= {
> +			.base	= S5PC100_GPL4(0),
> +			.ngpio	= S5PC100_GPIO_L4_NR,
> +			.label	= "GPL4",
> +		},
> +	},
> +};
> +
> +/* FIXME move from irq-gpio.c */
> +extern struct irq_chip s5pc1xx_gpioint;
> +extern void s5pc1xx_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc);
> +
> +static __init void s5pc1xx_gpiolib_link(struct s3c_gpio_chip *chip)
> +{
> +	chip->chip.direction_input = s5pc1xx_gpiolib_input;
> +	chip->chip.direction_output = s5pc1xx_gpiolib_output;
> +	chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
> +
> +	/* Interrupt */
> +	if (chip->config == &gpio_cfg) {
> +		int i, irq;
> +
> +		chip->chip.to_irq = s5pc1xx_gpiolib_to_irq;
> +
> +		for (i = 0;  i < chip->chip.ngpio; i++) {
> +			irq = S3C_IRQ_GPIO_BASE + chip->chip.base + i;
> +			set_irq_chip(irq, &s5pc1xx_gpioint);
> +			set_irq_data(irq, &chip->chip);
> +			set_irq_handler(irq, handle_level_irq);
> +			set_irq_flags(irq, IRQF_VALID);
> +		}
> +	} else if (chip->config == &gpio_cfg_eint)
> +		chip->chip.to_irq = s5pc1xx_gpiolib_to_eint;
> +}
> +
> +static __init void s5pc1xx_gpiolib_add(struct s3c_gpio_chip *chips,
> +				       int nr_chips,
> +				       void (*fn)(struct s3c_gpio_chip *))
> +{
> +	for (; nr_chips > 0; nr_chips--, chips++) {
> +		if (fn)
> +			(fn)(chips);
> +		s3c_gpiolib_add(chips);
> +	}
> +}
> +
> +static __init int s5pc1xx_gpiolib_init(void)
> +{
> +	struct s3c_gpio_chip *chips;
> +	int nr_chips;
> +
> +		chips = s5pc100_gpio_chips;
> +		nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
> +
> +	s5pc1xx_gpiolib_add(chips, nr_chips, s5pc1xx_gpiolib_link);
> +	/* Interrupt */
> +	set_irq_chained_handler(IRQ_GPIOINT, s5pc1xx_irq_gpioint_handler);
> +
> +	return 0;
> +}
> +core_initcall(s5pc1xx_gpiolib_init);
> diff --git a/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h b/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h
> new file mode 100644
> index 0000000..c29ee25
> --- /dev/null
> +++ b/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h
> @@ -0,0 +1,33 @@
> +/* linux/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg.h
> + *
> + * Copyright 2009 Samsung Electronic
> + *	InKi Dae <inki.dae@samsung.com>
> + *
> + * S5PC1XX Platform - GPIO pin configuration
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> +*/
> +
> +/* This file contains the necessary definitions to get the basic gpio
> + * pin configuration done such as setting a pin to input or output or
> + * changing the pull-{up,down} configurations.
> + */
> +
> +#ifndef __GPIO_CFG_S5PC1XX_H
> +#define __GPIO_CFG_S5PC1XX_H __FILE__
> +
> +typedef unsigned int __bitwise__ s5p_gpio_drvstr_t;
> +
> +#define S5P_GPIO_DRVSTR_LV1	0x00
> +#define S5P_GPIO_DRVSTR_LV2	0x01
> +#define S5P_GPIO_DRVSTR_LV3	0x10
> +#define S5P_GPIO_DRVSTR_LV4	0x11
> +
> +extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin, unsigned int off);
> +
> +extern int s5p_gpio_set_drvstr(unsigned int pin, unsigned int off,
> +			s5p_gpio_drvstr_t drvstr);
> +
> +#endif /* __GPIO_CFG_S5PC1XX_H */
> diff --git a/arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h b/arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h
> new file mode 100644
> index 0000000..33ad267
> --- /dev/null
> +++ b/arch/arm/plat-s5pc1xx/include/plat/gpio-ext.h
> @@ -0,0 +1,44 @@
> +/* linux/arch/arm/plat-s5pc1xx/include/plat/gpio-eint.h
> + *
> + * Copyright 2009 Samsung Electronics Co.
> + *
> + * External Interrupt (GPH0 ~ GPH3) control register definitions
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> +*/
> +
> +#define S5PC1XX_WKUP_INT_CON0_7		(S5PC1XX_EINT_BASE + 0x0)
> +#define S5PC1XX_WKUP_INT_CON8_15	(S5PC1XX_EINT_BASE + 0x4)
> +#define S5PC1XX_WKUP_INT_CON16_23	(S5PC1XX_EINT_BASE + 0x8)
> +#define S5PC1XX_WKUP_INT_CON24_31	(S5PC1XX_EINT_BASE + 0xC)
> +#define S5PC1XX_WKUP_INT_CON(x)		(S5PC1XX_WKUP_INT_CON0_7 + (x * 0x4))
> +
> +#define S5PC1XX_WKUP_INT_FLTCON0_3	(S5PC1XX_EINT_BASE + 0x80)
> +#define S5PC1XX_WKUP_INT_FLTCON4_7	(S5PC1XX_EINT_BASE + 0x84)
> +#define S5PC1XX_WKUP_INT_FLTCON8_11	(S5PC1XX_EINT_BASE + 0x88)
> +#define S5PC1XX_WKUP_INT_FLTCON12_15	(S5PC1XX_EINT_BASE + 0x8C)
> +#define S5PC1XX_WKUP_INT_FLTCON16_19	(S5PC1XX_EINT_BASE + 0x90)
> +#define S5PC1XX_WKUP_INT_FLTCON20_23	(S5PC1XX_EINT_BASE + 0x94)
> +#define S5PC1XX_WKUP_INT_FLTCON24_27	(S5PC1XX_EINT_BASE + 0x98)
> +#define S5PC1XX_WKUP_INT_FLTCON28_31	(S5PC1XX_EINT_BASE + 0x9C)
> +#define S5PC1XX_WKUP_INT_FLTCON(x)	(S5PC1XX_WKUP_INT_FLTCON0_3 + (x * 0x4))
> +
> +#define S5PC1XX_WKUP_INT_MASK0_7	(S5PC1XX_EINT_BASE + 0x100)
> +#define S5PC1XX_WKUP_INT_MASK8_15	(S5PC1XX_EINT_BASE + 0x104)
> +#define S5PC1XX_WKUP_INT_MASK16_23	(S5PC1XX_EINT_BASE + 0x108)
> +#define S5PC1XX_WKUP_INT_MASK24_31	(S5PC1XX_EINT_BASE + 0x10C)
> +#define S5PC1XX_WKUP_INT_MASK(x)	(S5PC1XX_WKUP_INT_MASK0_7 + (x * 0x4))
> +
> +#define S5PC1XX_WKUP_INT_PEND0_7	(S5PC1XX_EINT_BASE + 0x140)
> +#define S5PC1XX_WKUP_INT_PEND8_15	(S5PC1XX_EINT_BASE + 0x144)
> +#define S5PC1XX_WKUP_INT_PEND16_23	(S5PC1XX_EINT_BASE + 0x148)
> +#define S5PC1XX_WKUP_INT_PEND24_31	(S5PC1XX_EINT_BASE + 0x14C)
> +#define S5PC1XX_WKUP_INT_PEND(x)	(S5PC1XX_WKUP_INT_PEND0_7 + (x * 0x4))
> +
> +#define S5PC1XX_WKUP_INT_LOWLEV		(0x00)
> +#define S5PC1XX_WKUP_INT_HILEV		(0x01)
> +#define S5PC1XX_WKUP_INT_FALLEDGE	(0x02)
> +#define S5PC1XX_WKUP_INT_RISEEDGE	(0x03)
> +#define S5PC1XX_WKUP_INT_BOTHEDGE	(0x04)
> diff --git a/arch/arm/plat-s5pc1xx/include/plat/irqs.h b/arch/arm/plat-s5pc1xx/include/plat/irqs.h
> index f07d8c3..ef87363 100644
> --- a/arch/arm/plat-s5pc1xx/include/plat/irqs.h
> +++ b/arch/arm/plat-s5pc1xx/include/plat/irqs.h
> @@ -171,12 +171,21 @@
>  #define IRQ_SDMIRQ		S5PC1XX_IRQ_VIC2(30)
>  #define IRQ_SDMFIQ		S5PC1XX_IRQ_VIC2(31)
>  
> +/* External interrupt */
>  #define S3C_IRQ_EINT_BASE	(IRQ_SDMFIQ + 1)
>  
> -#define S3C_EINT(x)		((x) + S3C_IRQ_EINT_BASE)
> -#define IRQ_EINT(x)		S3C_EINT(x)
> +#define S3C_EINT(x)		(S3C_IRQ_EINT_BASE + (x - 16))
> +#define IRQ_EINT(x)		(x < 16 ? IRQ_EINT0 + x : S3C_EINT(x))
> +#define IRQ_EINT_BIT(x)		(x < IRQ_EINT16_31 ? x - IRQ_EINT0 : x - S3C_EINT(0))
>  
> -#define NR_IRQS 		(IRQ_EINT(31)+1)
> +/* GPIO interrupt */
> +#define S3C_IRQ_GPIO_BASE	(IRQ_EINT(31) + 1)
> +#define S3C_IRQ_GPIO(x)		(S3C_IRQ_GPIO_BASE + (x))
> +
> +/*
> + * Until MP04 Groups -> 40 (exactly 39) Groups * 8 ~= 320 GPIOs
> + */
> +#define NR_IRQS			(S3C_IRQ_GPIO(320) + 1)
>  
>  #endif /* __ASM_PLAT_S5PC1XX_IRQS_H */
>  
> diff --git a/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h b/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
> new file mode 100644
> index 0000000..43c7bc8
> --- /dev/null
> +++ b/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
> @@ -0,0 +1,70 @@
> +/* linux/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
> + *
> + * Copyright 2009 Samsung Electronics Co.
> + *      Byungho Min <bhmin@samsung.com>
> + *
> + * S5PC1XX - GPIO register definitions
> + */
> +
> +#ifndef __ASM_PLAT_S5PC1XX_REGS_GPIO_H
> +#define __ASM_PLAT_S5PC1XX_REGS_GPIO_H __FILE__
> +
> +#include <mach/map.h>
> +
> +/* S5PC100 */
> +#define S5PC100_GPIO_BASE	S5PC1XX_VA_GPIO
> +#define S5PC100_GPA0_BASE	(S5PC100_GPIO_BASE + 0x0000)
> +#define S5PC100_GPA1_BASE	(S5PC100_GPIO_BASE + 0x0020)
> +#define S5PC100_GPB_BASE	(S5PC100_GPIO_BASE + 0x0040)
> +#define S5PC100_GPC_BASE	(S5PC100_GPIO_BASE + 0x0060)
> +#define S5PC100_GPD_BASE	(S5PC100_GPIO_BASE + 0x0080)
> +#define S5PC100_GPE0_BASE	(S5PC100_GPIO_BASE + 0x00A0)
> +#define S5PC100_GPE1_BASE	(S5PC100_GPIO_BASE + 0x00C0)
> +#define S5PC100_GPF0_BASE	(S5PC100_GPIO_BASE + 0x00E0)
> +#define S5PC100_GPF1_BASE	(S5PC100_GPIO_BASE + 0x0100)
> +#define S5PC100_GPF2_BASE	(S5PC100_GPIO_BASE + 0x0120)
> +#define S5PC100_GPF3_BASE	(S5PC100_GPIO_BASE + 0x0140)
> +#define S5PC100_GPG0_BASE	(S5PC100_GPIO_BASE + 0x0160)
> +#define S5PC100_GPG1_BASE	(S5PC100_GPIO_BASE + 0x0180)
> +#define S5PC100_GPG2_BASE	(S5PC100_GPIO_BASE + 0x01A0)
> +#define S5PC100_GPG3_BASE	(S5PC100_GPIO_BASE + 0x01C0)
> +#define S5PC100_GPH0_BASE	(S5PC100_GPIO_BASE + 0x0C00)
> +#define S5PC100_GPH1_BASE	(S5PC100_GPIO_BASE + 0x0C20)
> +#define S5PC100_GPH2_BASE	(S5PC100_GPIO_BASE + 0x0C40)
> +#define S5PC100_GPH3_BASE	(S5PC100_GPIO_BASE + 0x0C60)
> +#define S5PC100_GPI_BASE	(S5PC100_GPIO_BASE + 0x01E0)
> +#define S5PC100_GPJ0_BASE	(S5PC100_GPIO_BASE + 0x0200)
> +#define S5PC100_GPJ1_BASE	(S5PC100_GPIO_BASE + 0x0220)
> +#define S5PC100_GPJ2_BASE	(S5PC100_GPIO_BASE + 0x0240)
> +#define S5PC100_GPJ3_BASE	(S5PC100_GPIO_BASE + 0x0260)
> +#define S5PC100_GPJ4_BASE	(S5PC100_GPIO_BASE + 0x0280)
> +#define S5PC100_GPK0_BASE	(S5PC100_GPIO_BASE + 0x02A0)
> +#define S5PC100_GPK1_BASE	(S5PC100_GPIO_BASE + 0x02C0)
> +#define S5PC100_GPK2_BASE	(S5PC100_GPIO_BASE + 0x02E0)
> +#define S5PC100_GPK3_BASE	(S5PC100_GPIO_BASE + 0x0300)
> +#define S5PC100_GPL0_BASE	(S5PC100_GPIO_BASE + 0x0320)
> +#define S5PC100_GPL1_BASE	(S5PC100_GPIO_BASE + 0x0340)
> +#define S5PC100_GPL2_BASE	(S5PC100_GPIO_BASE + 0x0360)
> +#define S5PC100_GPL3_BASE	(S5PC100_GPIO_BASE + 0x0380)
> +#define S5PC100_GPL4_BASE	(S5PC100_GPIO_BASE + 0x03A0)
> +#define S5PC100_EINT_BASE	(S5PC100_GPIO_BASE + 0x0E00)
> +
> +#define S5PC100_UHOST		(S5PC100_GPIO_BASE + 0x0B68)
> +#define S5PC100_PDNEN		(S5PC100_GPIO_BASE + 0x0F80)
> +
> +/* PDNEN */
> +#define S5PC100_PDNEN_CFG_PDNEN	(1 << 1)
> +#define S5PC100_PDNEN_CFG_AUTO	(0 << 1)
> +#define S5PC100_PDNEN_POWERDOWN	(1 << 0)
> +#define S5PC100_PDNEN_NORMAL	(0 << 0)
> +
> +/* Common part */
> +/* External interrupt base is same at both s5pc100 and s5pc110 */
> +#define S5PC1XX_EINT_BASE	(S5PC100_EINT_BASE)
> +
> +#define S5PC100_GPx_INPUT(__gpio)	(0x0 << ((__gpio) * 4))
> +#define S5PC100_GPx_OUTPUT(__gpio)	(0x1 << ((__gpio) * 4))
> +#define S5PC100_GPx_CONMASK(__gpio)	(0xf << ((__gpio) * 4))
> +
> +#endif /* __ASM_PLAT_S5PC1XX_REGS_GPIO_H */
> +
> diff --git a/arch/arm/plat-s5pc1xx/irq-eint.c b/arch/arm/plat-s5pc1xx/irq-eint.c
> new file mode 100644
> index 0000000..34f9443
> --- /dev/null
> +++ b/arch/arm/plat-s5pc1xx/irq-eint.c
> @@ -0,0 +1,281 @@
> +/*
> + * linux/arch/arm/plat-s5pc1xx/irq-eint.c
> + *
> + *  Copyright 2009 Samsung Electronics Co.
> + *  Byungho Min <bhmin@samsung.com>
> + *  Kyungin Park <kyungmin.park@samsung.com>
> + *
> + * Based on plat-s3c64xx/irq-eint.c
> + *
> + * S5PC1XX - Interrupt handling for IRQ_EINT(x)
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/io.h>
> +#include <linux/sysdev.h>
> +#include <linux/pm.h>
> +
> +#include <asm/hardware/vic.h>
> +
> +#include <mach/map.h>
> +#include <mach/gpio.h>
> +
> +#include <plat/gpio-cfg.h>
> +#include <plat/gpio-ext.h>
> +#include <plat/pm.h>
> +#include <plat/regs-gpio.h>
> +#include <plat/regs-irqtype.h>
> +
> +/*
> + * bank is a group of external interrupt
> + * bank0 means EINT0 ... EINT7
> + * bank1 means EINT8 ... EINT15
> + * bank2 means EINT16 ... EINT23
> + * bank3 means EINT24 ... EINT31
> + */
> +
> +static inline int s3c_get_eint(unsigned int irq)
> +{
> +	int real;
> +
> +	if (irq < IRQ_EINT16_31)
> +		real = (irq - IRQ_EINT0);
> +	else
> +		real = (irq - S3C_IRQ_EINT_BASE) + IRQ_EINT16_31 - IRQ_EINT0;
> +
> +	return real;
> +}
> +
> +static inline int s3c_get_bank(unsigned int irq)
> +{
> +	return s3c_get_eint(irq) >> 3;
> +}
> +
> +static inline int s3c_eint_to_bit(unsigned int irq)
> +{
> +	int real, bit;
> +
> +	real = s3c_get_eint(irq);
> +	bit = 1 << (real & (8 - 1));
> +
> +	return bit;
> +}
> +
> +static inline void s3c_irq_eint_mask(unsigned int irq)
> +{
> +	u32 mask;
> +	u32 bank = s3c_get_bank(irq);
> +
> +	mask = __raw_readl(S5PC1XX_WKUP_INT_MASK(bank));
> +	mask |= s3c_eint_to_bit(irq);
> +	__raw_writel(mask, S5PC1XX_WKUP_INT_MASK(bank));
> +}
> +
> +static void s3c_irq_eint_unmask(unsigned int irq)
> +{
> +	u32 mask;
> +	u32 bank = s3c_get_bank(irq);
> +
> +	mask = __raw_readl(S5PC1XX_WKUP_INT_MASK(bank));
> +	mask &= ~(s3c_eint_to_bit(irq));
> +	__raw_writel(mask, S5PC1XX_WKUP_INT_MASK(bank));
> +}
> +
> +static inline void s3c_irq_eint_ack(unsigned int irq)
> +{
> +	u32 bank = s3c_get_bank(irq);
> +
> +	__raw_writel(s3c_eint_to_bit(irq), S5PC1XX_WKUP_INT_PEND(bank));
> +}
> +
> +static void s3c_irq_eint_maskack(unsigned int irq)
> +{
> +	/* compiler should in-line these */
> +	s3c_irq_eint_mask(irq);
> +	s3c_irq_eint_ack(irq);
> +}
> +
> +static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
> +{
> +	u32 bank = s3c_get_bank(irq);
> +	int real = s3c_get_eint(irq);
> +	int gpio, shift, sfn;
> +	u32 ctrl, con = 0;
> +
> +	switch (type) {
> +	case IRQ_TYPE_NONE:
> +		printk(KERN_WARNING "No edge setting!\n");
> +		break;
> +
> +	case IRQ_TYPE_EDGE_RISING:
> +		con = S5PC1XX_WKUP_INT_RISEEDGE;
> +		break;
> +
> +	case IRQ_TYPE_EDGE_FALLING:
> +		con = S5PC1XX_WKUP_INT_FALLEDGE;
> +		break;
> +
> +	case IRQ_TYPE_EDGE_BOTH:
> +		con = S5PC1XX_WKUP_INT_BOTHEDGE;
> +		break;
> +
> +	case IRQ_TYPE_LEVEL_LOW:
> +		con = S5PC1XX_WKUP_INT_LOWLEV;
> +		break;
> +
> +	case IRQ_TYPE_LEVEL_HIGH:
> +		con = S5PC1XX_WKUP_INT_HILEV;
> +		break;
> +
> +	default:
> +		printk(KERN_ERR "No such irq type %d", type);
> +		return -EINVAL;
> +	}
> +
> +	gpio = real & (8 - 1);
> +	shift = gpio << 2;
> +
> +	ctrl = __raw_readl(S5PC1XX_WKUP_INT_CON(bank));
> +	ctrl &= ~(0x7 << shift);
> +	ctrl |= con << shift;
> +	__raw_writel(ctrl, S5PC1XX_WKUP_INT_CON(bank));
> +
> +	switch (real) {
> +	case 0 ... 7:
> +			gpio = S5PC100_GPH0(gpio);
> +		break;
> +	case 8 ... 15:
> +			gpio = S5PC100_GPH1(gpio);
> +		break;
> +	case 16 ... 23:
> +			gpio = S5PC100_GPH2(gpio);
> +		break;
> +	case 24 ... 31:
> +			gpio = S5PC100_GPH3(gpio);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	sfn = S3C_GPIO_SFN(0x2);
> +	s3c_gpio_cfgpin(gpio, sfn);
> +
> +	return 0;
> +}
> +
> +static struct irq_chip s3c_irq_eint = {
> +	.name		= "EINT",
> +	.mask		= s3c_irq_eint_mask,
> +	.unmask		= s3c_irq_eint_unmask,
> +	.mask_ack	= s3c_irq_eint_maskack,
> +	.ack		= s3c_irq_eint_ack,
> +	.set_type	= s3c_irq_eint_set_type,
> +	.set_wake	= s3c_irqext_wake,
> +};
> +
> +/* s3c_irq_demux_eint
> + *
> + * This function demuxes the IRQ from external interrupts,
> + * from IRQ_EINT(16) to IRQ_EINT(31). It is designed to be inlined into
> + * the specific handlers s3c_irq_demux_eintX_Y.
> + */
> +static inline void s3c_irq_demux_eint(unsigned int start, unsigned int end)
> +{
> +	u32 status = __raw_readl(S5PC1XX_WKUP_INT_PEND((start >> 3)));
> +	u32 mask = __raw_readl(S5PC1XX_WKUP_INT_MASK((start >> 3)));
> +	unsigned int irq;
> +
> +	status &= ~mask;
> +	status &= (1 << (end - start + 1)) - 1;
> +
> +	for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
> +		if (status & 1)
> +			generic_handle_irq(irq);
> +
> +		status >>= 1;
> +	}
> +}
> +
> +static void s3c_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
> +{
> +	s3c_irq_demux_eint(16, 23);
> +	s3c_irq_demux_eint(24, 31);
> +}
> +
> +/*
> + * Handle EINT0 ... EINT15 at VIC directly
> + */
> +static void s3c_irq_vic_eint_mask(unsigned int irq)
> +{
> +	void __iomem *base = get_irq_chip_data(irq);
> +	unsigned int real;
> +
> +	s3c_irq_eint_mask(irq);
> +	real = s3c_get_eint(irq);
> +	writel(1 << real, base + VIC_INT_ENABLE_CLEAR);
> +}
> +
> +static void s3c_irq_vic_eint_unmask(unsigned int irq)
> +{
> +	void __iomem *base = get_irq_chip_data(irq);
> +	unsigned int real;
> +
> +	s3c_irq_eint_unmask(irq);
> +	real = s3c_get_eint(irq);
> +	writel(1 << real, base + VIC_INT_ENABLE);
> +}
> +
> +static inline void s3c_irq_vic_eint_ack(unsigned int irq)
> +{
> +	u32 bit;
> +	u32 bank = s3c_get_bank(irq);
> +
> +	bit = s3c_eint_to_bit(irq);
> +	__raw_writel(bit, S5PC1XX_WKUP_INT_PEND(bank));
> +}
> +
> +static void s3c_irq_vic_eint_maskack(unsigned int irq)
> +{
> +	/* compiler should in-line these */
> +	s3c_irq_vic_eint_mask(irq);
> +	s3c_irq_vic_eint_ack(irq);
> +}
> +
> +static struct irq_chip s3c_irq_vic_eint = {
> +	.name		= "EINT",
> +	.mask		= s3c_irq_vic_eint_mask,
> +	.unmask		= s3c_irq_vic_eint_unmask,
> +	.mask_ack	= s3c_irq_vic_eint_maskack,
> +	.ack		= s3c_irq_vic_eint_ack,
> +	.set_type	= s3c_irq_eint_set_type,
> +	.set_wake	= s3c_irqext_wake,
> +};
> +
> +static int __init s5pc1xx_init_irq_eint(void)
> +{
> +	int irq;
> +
> +	for (irq = IRQ_EINT0; irq <= IRQ_EINT15; irq++) {
> +		set_irq_chip(irq, &s3c_irq_vic_eint);
> +		set_irq_handler(irq, handle_level_irq);
> +		set_irq_flags(irq, IRQF_VALID);
> +	}
> +
> +	for (irq = IRQ_EINT(16); irq <= IRQ_EINT(31); irq++) {
> +		set_irq_chip(irq, &s3c_irq_eint);
> +		set_irq_handler(irq, handle_level_irq);
> +		set_irq_flags(irq, IRQF_VALID);
> +	}
> +
> +	set_irq_chained_handler(IRQ_EINT16_31, s3c_irq_demux_eint16_31);
> +
> +	return 0;
> +}
> +
> +arch_initcall(s5pc1xx_init_irq_eint);
> diff --git a/arch/arm/plat-s5pc1xx/irq-gpio.c b/arch/arm/plat-s5pc1xx/irq-gpio.c
> new file mode 100644
> index 0000000..843a88e
> --- /dev/null
> +++ b/arch/arm/plat-s5pc1xx/irq-gpio.c
> @@ -0,0 +1,266 @@
> +/*
> + * arch/arm/plat-s5pc1xx/irq-gpio.c
> + *
> + * Copyright (C) 2009 Samsung Electronics
> + *
> + * S5PC1XX - Interrupt handling for IRQ_GPIO${group}(x)
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/io.h>
> +
> +#include <mach/map.h>
> +#include <mach/gpio.h>
> +#include <plat/gpio-cfg.h>
> +
> +#define S5PC1XX_GPIOREG(x)		(S5PC1XX_VA_GPIO + (x))
> +
> +#define CON_OFFSET			0x700
> +#define MASK_OFFSET			0x900
> +#define PEND_OFFSET			0xA00
> +#define CON_OFFSET_2			0xE00
> +#define MASK_OFFSET_2			0xF00
> +#define PEND_OFFSET_2			0xF40
> +
> +#define GPIOINT_LEVEL_LOW		0x0
> +#define GPIOINT_LEVEL_HIGH		0x1
> +#define GPIOINT_EDGE_FALLING		0x2
> +#define GPIOINT_EDGE_RISING		0x3
> +#define GPIOINT_EDGE_BOTH		0x4
> +
> +static int group_to_con_offset(int group)
> +{
> +	return group << 2;
> +}
> +
> +static int group_to_mask_offset(int group)
> +{
> +	return group << 2;
> +}
> +
> +static int group_to_pend_offset(int group)
> +{
> +	return group << 2;
> +}
> +
> +static int s5pc1xx_get_start(unsigned int group)
> +{
> +	switch (group) {
> +	case 0: return S5PC100_GPIO_A0_START;
> +	case 1: return S5PC100_GPIO_A1_START;
> +	case 2: return S5PC100_GPIO_B_START;
> +	case 3: return S5PC100_GPIO_C_START;
> +	case 4: return S5PC100_GPIO_D_START;
> +	case 5: return S5PC100_GPIO_E0_START;
> +	case 6: return S5PC100_GPIO_E1_START;
> +	case 7: return S5PC100_GPIO_F0_START;
> +	case 8: return S5PC100_GPIO_F1_START;
> +	case 9: return S5PC100_GPIO_F2_START;
> +	case 10: return S5PC100_GPIO_F3_START;
> +	case 11: return S5PC100_GPIO_G0_START;
> +	case 12: return S5PC100_GPIO_G1_START;
> +	case 13: return S5PC100_GPIO_G2_START;
> +	case 14: return S5PC100_GPIO_G3_START;
> +	case 15: return S5PC100_GPIO_I_START;
> +	case 16: return S5PC100_GPIO_J0_START;
> +	case 17: return S5PC100_GPIO_J1_START;
> +	case 18: return S5PC100_GPIO_J2_START;
> +	case 19: return S5PC100_GPIO_J3_START;
> +	case 20: return S5PC100_GPIO_J4_START;
> +	default:
> +		BUG();
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int s5pc1xx_get_group(unsigned int irq)
> +{
> +	irq -= S3C_IRQ_GPIO(0);
> +
> +	switch (irq) {
> +	case S5PC100_GPIO_A0_START ... S5PC100_GPIO_A1_START - 1:
> +		return 0;
> +	case S5PC100_GPIO_A1_START ... S5PC100_GPIO_B_START - 1:
> +		return 1;
> +	case S5PC100_GPIO_B_START ... S5PC100_GPIO_C_START - 1:
> +		return 2;
> +	case S5PC100_GPIO_C_START ... S5PC100_GPIO_D_START - 1:
> +		return 3;
> +	case S5PC100_GPIO_D_START ... S5PC100_GPIO_E0_START - 1:
> +		return 4;
> +	case S5PC100_GPIO_E0_START ... S5PC100_GPIO_E1_START - 1:
> +		return 5;
> +	case S5PC100_GPIO_E1_START ... S5PC100_GPIO_F0_START - 1:
> +		return 6;
> +	case S5PC100_GPIO_F0_START ... S5PC100_GPIO_F1_START - 1:
> +		return 7;
> +	case S5PC100_GPIO_F1_START ... S5PC100_GPIO_F2_START - 1:
> +		return 8;
> +	case S5PC100_GPIO_F2_START ... S5PC100_GPIO_F3_START - 1:
> +		return 9;
> +	case S5PC100_GPIO_F3_START ... S5PC100_GPIO_G0_START - 1:
> +		return 10;
> +	case S5PC100_GPIO_G0_START ... S5PC100_GPIO_G1_START - 1:
> +		return 11;
> +	case S5PC100_GPIO_G1_START ... S5PC100_GPIO_G2_START - 1:
> +		return 12;
> +	case S5PC100_GPIO_G2_START ... S5PC100_GPIO_G3_START - 1:
> +		return 13;
> +	case S5PC100_GPIO_G3_START ... S5PC100_GPIO_H0_START - 1:
> +		return 14;
> +	case S5PC100_GPIO_I_START ... S5PC100_GPIO_J0_START - 1:
> +		return 15;
> +	case S5PC100_GPIO_J0_START ... S5PC100_GPIO_J1_START - 1:
> +		return 16;
> +	case S5PC100_GPIO_J1_START ... S5PC100_GPIO_J2_START - 1:
> +		return 17;
> +	case S5PC100_GPIO_J2_START ... S5PC100_GPIO_J3_START - 1:
> +		return 18;
> +	case S5PC100_GPIO_J3_START ... S5PC100_GPIO_J4_START - 1:
> +		return 19;
> +	case S5PC100_GPIO_J4_START ... S5PC100_GPIO_K0_START - 1:
> +		return 20;
> +	default:
> +		BUG();
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int s5pc1xx_get_offset(unsigned int irq)
> +{
> +	struct gpio_chip *chip = get_irq_data(irq);
> +	return irq - S3C_IRQ_GPIO(chip->base);
> +}
> +
> +static void s5pc1xx_gpioint_ack(unsigned int irq)
> +{
> +	int group, offset, pend_offset;
> +	unsigned int value;
> +
> +	group = s5pc1xx_get_group(irq);
> +	offset = s5pc1xx_get_offset(irq);
> +	pend_offset = group_to_pend_offset(group);
> +
> +	value = __raw_readl(S5PC1XX_GPIOREG(PEND_OFFSET) + pend_offset);
> +	value |= 1 << offset;
> +	__raw_writel(value, S5PC1XX_GPIOREG(PEND_OFFSET) + pend_offset);
> +}
> +
> +static void s5pc1xx_gpioint_mask(unsigned int irq)
> +{
> +	int group, offset, mask_offset;
> +	unsigned int value;
> +
> +	group = s5pc1xx_get_group(irq);
> +	offset = s5pc1xx_get_offset(irq);
> +	mask_offset = group_to_mask_offset(group);
> +
> +	value = __raw_readl(S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
> +	value |= 1 << offset;
> +	__raw_writel(value, S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
> +}
> +
> +static void s5pc1xx_gpioint_unmask(unsigned int irq)
> +{
> +	int group, offset, mask_offset;
> +	unsigned int value;
> +
> +	group = s5pc1xx_get_group(irq);
> +	offset = s5pc1xx_get_offset(irq);
> +	mask_offset = group_to_mask_offset(group);
> +
> +	value = __raw_readl(S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
> +	value &= ~(1 << offset);
> +	__raw_writel(value, S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
> +}
> +
> +static void s5pc1xx_gpioint_mask_ack(unsigned int irq)
> +{
> +	s5pc1xx_gpioint_mask(irq);
> +	s5pc1xx_gpioint_ack(irq);
> +}
> +
> +static int s5pc1xx_gpioint_set_type(unsigned int irq, unsigned int type)
> +{
> +	int group, offset, con_offset;
> +	unsigned int value;
> +
> +	group = s5pc1xx_get_group(irq);
> +	offset = s5pc1xx_get_offset(irq);
> +	con_offset = group_to_con_offset(group);
> +
> +	switch (type) {
> +	case IRQ_TYPE_NONE:
> +		printk(KERN_WARNING "No irq type\n");
> +		return -EINVAL;
> +	case IRQ_TYPE_EDGE_RISING:
> +		type = GPIOINT_EDGE_RISING;
> +		break;
> +	case IRQ_TYPE_EDGE_FALLING:
> +		type = GPIOINT_EDGE_FALLING;
> +		break;
> +	case IRQ_TYPE_EDGE_BOTH:
> +		type = GPIOINT_EDGE_BOTH;
> +		break;
> +	case IRQ_TYPE_LEVEL_HIGH:
> +		type = GPIOINT_LEVEL_HIGH;
> +		break;
> +	case IRQ_TYPE_LEVEL_LOW:
> +		type = GPIOINT_LEVEL_LOW;
> +		break;
> +	default:
> +		BUG();
> +	}
> +
> +
> +	value = __raw_readl(S5PC1XX_GPIOREG(CON_OFFSET) + con_offset);
> +	value &= ~(0xf << (offset * 0x4));
> +	value |= (type << (offset * 0x4));
> +	__raw_writel(value, S5PC1XX_GPIOREG(CON_OFFSET) + con_offset);
> +
> +	return 0;
> +}
> +
> +struct irq_chip s5pc1xx_gpioint = {
> +	.name		= "GPIO",
> +	.ack		= s5pc1xx_gpioint_ack,
> +	.mask		= s5pc1xx_gpioint_mask,
> +	.mask_ack	= s5pc1xx_gpioint_mask_ack,
> +	.unmask		= s5pc1xx_gpioint_unmask,
> +	.set_type	= s5pc1xx_gpioint_set_type,
> +};
> +
> +void s5pc1xx_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc)
> +{
> +	int group, offset, pend_offset, mask_offset;
> +	int real_irq, group_end;
> +	unsigned int pend, mask;
> +
> +	group_end = 21;
> +
> +	for (group = 0; group < group_end; group++) {
> +		pend_offset = group_to_pend_offset(group);
> +		pend = __raw_readl(S5PC1XX_GPIOREG(PEND_OFFSET) + pend_offset);
> +		if (!pend)
> +			continue;
> +
> +		mask_offset = group_to_mask_offset(group);
> +		mask = __raw_readl(S5PC1XX_GPIOREG(MASK_OFFSET) + mask_offset);
> +		pend &= ~mask;
> +
> +		for (offset = 0; offset < 8; offset++) {
> +			if (pend & (1 << offset)) {
> +				real_irq = s5pc1xx_get_start(group) + offset;
> +				generic_handle_irq(S3C_IRQ_GPIO(real_irq));
> +			}
> +		}
> +	}
> +}
> diff --git a/arch/arm/plat-s5pc1xx/irq.c b/arch/arm/plat-s5pc1xx/irq.c
> index 80d6dd9..e44fd04 100644
> --- a/arch/arm/plat-s5pc1xx/irq.c
> +++ b/arch/arm/plat-s5pc1xx/irq.c
> @@ -79,7 +79,7 @@ static void s3c_irq_timer_ack(unsigned int irq)
>  {
>  	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
>  
> -	reg &= 0x1f;
> +	reg &= 0x1f;  /* mask out pending interrupts */
>  	reg |= (1 << 5) << (irq - IRQ_TIMER0);
>  	__raw_writel(reg, S3C64XX_TINT_CSTAT);
>  }
> -- 
> 1.6.4
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
-- 
Ben

Q:      What's a light-year?
A:      One-third less calories than a regular year.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 09/17] ARM: S5PC1xx: add platform helpers for s3c-fb device
  2009-10-13  8:11                   ` Marek Szyprowski
@ 2009-11-09  0:02                     ` Ben Dooks
  -1 siblings, 0 replies; 76+ messages in thread
From: Ben Dooks @ 2009-11-09  0:02 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-arm-kernel, linux-samsung-soc, kyungmin.park, bhmin, ben-linux

On Tue, Oct 13, 2009 at 10:11:14AM +0200, Marek Szyprowski wrote:
> Samsung S5PC100 has LCD-controller compatible with the one known from
> previous SoCs series. Add required platform setup and support code that
> it can be used with s3c-fb driver.
> 
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  arch/arm/mach-s5pc100/include/mach/irqs.h    |    5 +
>  arch/arm/mach-s5pc100/include/mach/regs-fb.h |  259 ++++++++++++++++++++++++++
>  arch/arm/plat-s3c/include/plat/fb.h          |    7 +
>  arch/arm/plat-s5pc1xx/Kconfig                |    5 +
>  arch/arm/plat-s5pc1xx/Makefile               |    1 +
>  arch/arm/plat-s5pc1xx/setup-fb-24bpp.c       |   49 +++++
>  6 files changed, 326 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-s5pc100/include/mach/regs-fb.h
>  create mode 100644 arch/arm/plat-s5pc1xx/setup-fb-24bpp.c
> 
> diff --git a/arch/arm/mach-s5pc100/include/mach/irqs.h b/arch/arm/mach-s5pc100/include/mach/irqs.h
> index 622720d..b53fa48 100644
> --- a/arch/arm/mach-s5pc100/include/mach/irqs.h
> +++ b/arch/arm/mach-s5pc100/include/mach/irqs.h
> @@ -11,4 +11,9 @@
>  
>  #include <plat/irqs.h>
>  
> +/* LCD */
> +#define IRQ_LCD_FIFO		IRQ_LCD0
> +#define IRQ_LCD_VSYNC		IRQ_LCD1
> +#define IRQ_LCD_SYSTEM		IRQ_LCD2
> +
>  #endif /* __ASM_ARCH_IRQ_H */
> diff --git a/arch/arm/mach-s5pc100/include/mach/regs-fb.h b/arch/arm/mach-s5pc100/include/mach/regs-fb.h
> new file mode 100644
> index 0000000..4701979
> --- /dev/null
> +++ b/arch/arm/mach-s5pc100/include/mach/regs-fb.h
> @@ -0,0 +1,259 @@
> +/* arch/arm/mach-s3c6400/include/mach/regs-fb.h
> + *
> + * Copyright 2008 Openmoko, Inc.
> + * Copyright 2008 Simtec Electronics
> + *      http://armlinux.simtec.co.uk/
> + *      Ben Dooks <ben@simtec.co.uk>

Either make the file common, or have an attribution to the original
source it was copied from. Otherwise, thanks for writing some code
and giving it to me.

PS, this seems to be a less than occasional occurance here. Whilst it
might seem flattering, the amount of crud that gets mis-attributed to
other people can often cause an ammount of annoyance. Please try to
avoid this in the future.

> + * S3C64XX - new-style framebuffer register definitions
> + *
> + * This is the register set for the new style framebuffer interface
> + * found from the S3C2443 onwards and specifically the S3C64XX series
> + * S3C6400 and S3C6410.
> + *
> + * The file contains the cpu specific items which change between whichever
> + * architecture is selected. See <plat/regs-fb.h> for the core definitions
> + * that are the same.
> + *
> + * This program is free software; you can 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 the core definitions here, in case we really do need to
> + * override them at a later date.
> +*/
> +
> +#include <plat/regs-fb.h>
> +
> +#define S3C_FB_MAX_WIN (5)  /* number of hardware windows available. */
> +#define VIDCON1_FSTATUS_EVEN	(1 << 15)
> +
> +/* Video timing controls */
> +#define VIDTCON0				(0x10)
> +#define VIDTCON1				(0x14)
> +#define VIDTCON2				(0x18)
> +
> +/* Window position controls */
> +
> +#define WINCON(_win)				(0x20 + ((_win) * 4))
> +
> +/* OSD1 and OSD4 do not have register D */
> +
> +#define VIDOSD_A(_win)				(0x40 + ((_win) * 16))
> +#define VIDOSD_B(_win)				(0x44 + ((_win) * 16))
> +#define VIDOSD_C(_win)				(0x48 + ((_win) * 16))
> +#define VIDOSD_D(_win)				(0x4C + ((_win) * 16))
> +
> +/* Video buffer addresses */
> +
> +#define VIDW_BUF_START(_buff)			(0xA0 + ((_buff) * 8))
> +#define VIDW_BUF_START1(_buff)			(0xA4 + ((_buff) * 8))
> +#define VIDW_BUF_END(_buff)			(0xD0 + ((_buff) * 8))
> +#define VIDW_BUF_END1(_buff)			(0xD4 + ((_buff) * 8))
> +#define VIDW_BUF_SIZE(_buff)			(0x100 + ((_buff) * 4))
> +
> +#define VIDINTCON0				(0x130)
> +
> +#define WxKEYCONy(_win, _con)			((0x140 + ((_win) * 8)) + ((_con) * 4))
> +
> +/* WINCONx */
> +
> +#define WINCONx_CSCWIDTH_MASK			(0x3 << 26)
> +#define WINCONx_CSCWIDTH_SHIFT			(26)
> +#define WINCONx_CSCWIDTH_WIDE			(0x0 << 26)
> +#define WINCONx_CSCWIDTH_NARROW			(0x3 << 26)
> +
> +#define WINCONx_ENLOCAL				(1 << 22)
> +#define WINCONx_BUFSTATUS			(1 << 21)
> +#define WINCONx_BUFSEL				(1 << 20)
> +#define WINCONx_BUFAUTOEN			(1 << 19)
> +#define WINCONx_YCbCr				(1 << 13)
> +
> +#define WINCON1_LOCALSEL_CAMIF			(1 << 23)
> +
> +#define WINCON2_LOCALSEL_CAMIF			(1 << 23)
> +#define WINCON2_BLD_PIX				(1 << 6)
> +
> +#define WINCON2_ALPHA_SEL			(1 << 1)
> +#define WINCON2_BPPMODE_MASK			(0xf << 2)
> +#define WINCON2_BPPMODE_SHIFT			(2)
> +#define WINCON2_BPPMODE_1BPP			(0x0 << 2)
> +#define WINCON2_BPPMODE_2BPP			(0x1 << 2)
> +#define WINCON2_BPPMODE_4BPP			(0x2 << 2)
> +#define WINCON2_BPPMODE_8BPP_1232		(0x4 << 2)
> +#define WINCON2_BPPMODE_16BPP_565		(0x5 << 2)
> +#define WINCON2_BPPMODE_16BPP_A1555		(0x6 << 2)
> +#define WINCON2_BPPMODE_16BPP_I1555		(0x7 << 2)
> +#define WINCON2_BPPMODE_18BPP_666		(0x8 << 2)
> +#define WINCON2_BPPMODE_18BPP_A1665		(0x9 << 2)
> +#define WINCON2_BPPMODE_19BPP_A1666		(0xa << 2)
> +#define WINCON2_BPPMODE_24BPP_888		(0xb << 2)
> +#define WINCON2_BPPMODE_24BPP_A1887		(0xc << 2)
> +#define WINCON2_BPPMODE_25BPP_A1888		(0xd << 2)
> +#define WINCON2_BPPMODE_28BPP_A4888		(0xd << 2)
> +
> +#define WINCON3_BLD_PIX				(1 << 6)
> +
> +#define WINCON3_ALPHA_SEL			(1 << 1)
> +#define WINCON3_BPPMODE_MASK			(0xf << 2)
> +#define WINCON3_BPPMODE_SHIFT			(2)
> +#define WINCON3_BPPMODE_1BPP			(0x0 << 2)
> +#define WINCON3_BPPMODE_2BPP			(0x1 << 2)
> +#define WINCON3_BPPMODE_4BPP			(0x2 << 2)
> +#define WINCON3_BPPMODE_16BPP_565		(0x5 << 2)
> +#define WINCON3_BPPMODE_16BPP_A1555		(0x6 << 2)
> +#define WINCON3_BPPMODE_16BPP_I1555		(0x7 << 2)
> +#define WINCON3_BPPMODE_18BPP_666		(0x8 << 2)
> +#define WINCON3_BPPMODE_18BPP_A1665		(0x9 << 2)
> +#define WINCON3_BPPMODE_19BPP_A1666		(0xa << 2)
> +#define WINCON3_BPPMODE_24BPP_888		(0xb << 2)
> +#define WINCON3_BPPMODE_24BPP_A1887		(0xc << 2)
> +#define WINCON3_BPPMODE_25BPP_A1888		(0xd << 2)
> +#define WINCON3_BPPMODE_28BPP_A4888		(0xd << 2)
> +
> +#define VIDINTCON0_FIFIOSEL_WINDOW2		(0x10 << 5)
> +#define VIDINTCON0_FIFIOSEL_WINDOW3		(0x20 << 5)
> +#define VIDINTCON0_FIFIOSEL_WINDOW4		(0x40 << 5)
> +
> +#define DITHMODE				(0x170)
> +#define WINxMAP(_win)				(0x180 + ((_win) * 4))
> +
> +
> +#define DITHMODE_R_POS_MASK			(0x3 << 5)
> +#define DITHMODE_R_POS_SHIFT			(5)
> +#define DITHMODE_R_POS_8BIT			(0x0 << 5)
> +#define DITHMODE_R_POS_6BIT			(0x1 << 5)
> +#define DITHMODE_R_POS_5BIT			(0x2 << 5)
> +
> +#define DITHMODE_G_POS_MASK			(0x3 << 3)
> +#define DITHMODE_G_POS_SHIFT			(3)
> +#define DITHMODE_G_POS_8BIT			(0x0 << 3)
> +#define DITHMODE_G_POS_6BIT			(0x1 << 3)
> +#define DITHMODE_G_POS_5BIT			(0x2 << 3)
> +
> +#define DITHMODE_B_POS_MASK			(0x3 << 1)
> +#define DITHMODE_B_POS_SHIFT			(1)
> +#define DITHMODE_B_POS_8BIT			(0x0 << 1)
> +#define DITHMODE_B_POS_6BIT			(0x1 << 1)
> +#define DITHMODE_B_POS_5BIT			(0x2 << 1)
> +
> +#define DITHMODE_DITH_EN			(1 << 0)
> +
> +#define WPALCON					(0x1A0)
> +
> +#define WPALCON_W4PAL_16BPP_A555		(1 << 8)
> +#define WPALCON_W3PAL_16BPP_A555		(1 << 7)
> +#define WPALCON_W2PAL_16BPP_A555		(1 << 6)
> +
> +/* Palette registers */
> +
> +#define WIN2_PAL(_entry)			(0x300 + ((_entry) * 2))
> +#define WIN3_PAL(_entry)			(0x320 + ((_entry) * 2))
> +#define WIN4_PAL(_entry)			(0x340 + ((_entry) * 2))
> +#define WIN0_PAL(_entry)			(0x400 + ((_entry) * 4))
> +#define WIN1_PAL(_entry)			(0x800 + ((_entry) * 4))
> +
> +/* system specific implementation code for palette sizes, and other
> + * information that changes depending on which architecture is being
> + * compiled.
> +*/
> +
> +/* return true if window _win has OSD register D */
> +#define s3c_fb_has_osd_d(_win) ((_win) != 4 && (_win) != 0)
> +
> +static inline unsigned int s3c_fb_win_pal_size(unsigned int win)
> +{
> +	if (win < 2)
> +		return 256;
> +	if (win < 4)
> +		return 16;
> +	if (win == 4)
> +		return 4;
> +
> +	BUG();	/* shouldn't get here */
> +}
> +
> +static inline int s3c_fb_validate_win_bpp(unsigned int win, unsigned int bpp)
> +{
> +	/* all windows can do 1/2 bpp */
> +
> +	if ((bpp == 25 || bpp == 19) && win == 0)
> +		return 0;	/* win 0 does not have 19 or 25bpp modes */
> +
> +	if (bpp == 4 && win == 4)
> +		return 0;
> +
> +	if (bpp == 8 && (win >= 3))
> +		return 0;	/* win 3/4 cannot do 8bpp in any mode */
> +
> +	return 1;
> +}
> +
> +static inline unsigned int s3c_fb_pal_reg(unsigned int window, int reg)
> +{
> +	switch (window) {
> +	case 0: return WIN0_PAL(reg);
> +	case 1: return WIN1_PAL(reg);
> +	case 2: return WIN2_PAL(reg);
> +	case 3: return WIN3_PAL(reg);
> +	case 4: return WIN4_PAL(reg);
> +	}
> +
> +	BUG();
> +}
> +
> +static inline int s3c_fb_pal_is16(unsigned int window)
> +{
> +	return window > 1;
> +}
> +
> +struct s3c_fb_palette {
> +	struct fb_bitfield	r;
> +	struct fb_bitfield	g;
> +	struct fb_bitfield	b;
> +	struct fb_bitfield	a;
> +};
> +
> +static inline void s3c_fb_init_palette(unsigned int window,
> +				       struct s3c_fb_palette *palette)
> +{
> +	if (window < 2) {
> +		/* Windows 0/1 are 8/8/8 or A/8/8/8 */
> +		palette->r.offset = 16;
> +		palette->r.length = 8;
> +		palette->g.offset = 8;
> +		palette->g.length = 8;
> +		palette->b.offset = 0;
> +		palette->b.length = 8;
> +	} else {
> +		/* currently we assume RGB 5/6/5 */
> +		palette->r.offset = 11;
> +		palette->r.length = 5;
> +		palette->g.offset = 5;
> +		palette->g.length = 6;
> +		palette->b.offset = 0;
> +		palette->b.length = 5;
> +	}
> +}
> +
> +/* Notes on per-window bpp settings
> + *
> + * Value	Win0	 Win1	  Win2	   Win3	    Win 4
> + * 0000		1(P)	 1(P)	  1(P)	   1(P)	    1(P)
> + * 0001		2(P)	 2(P)     2(P)	   2(P)	    2(P)
> + * 0010		4(P)	 4(P)     4(P)	   4(P)     -none-
> + * 0011		8(P)	 8(P)     -none-   -none-   -none-
> + * 0100		-none-	 8(A232)  8(A232)  -none-   -none-
> + * 0101		16(565)	 16(565)  16(565)  16(565)   16(565)
> + * 0110		-none-	 16(A555) 16(A555) 16(A555)  16(A555)
> + * 0111		16(I555) 16(I565) 16(I555) 16(I555)  16(I555)
> + * 1000		18(666)	 18(666)  18(666)  18(666)   18(666)
> + * 1001		-none-	 18(A665) 18(A665) 18(A665)  16(A665)
> + * 1010		-none-	 19(A666) 19(A666) 19(A666)  19(A666)
> + * 1011		24(888)	 24(888)  24(888)  24(888)   24(888)
> + * 1100		-none-	 24(A887) 24(A887) 24(A887)  24(A887)
> + * 1101		-none-	 25(A888) 25(A888) 25(A888)  25(A888)
> + * 1110		-none-	 -none-	  -none-   -none-    -none-
> + * 1111		-none-	 -none-   -none-   -none-    -none-
> +*/
> diff --git a/arch/arm/plat-s3c/include/plat/fb.h b/arch/arm/plat-s3c/include/plat/fb.h
> index 214ff56..f8db879 100644
> --- a/arch/arm/plat-s3c/include/plat/fb.h
> +++ b/arch/arm/plat-s3c/include/plat/fb.h
> @@ -70,4 +70,11 @@ extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd);
>   */
>  extern void s3c64xx_fb_gpio_setup_24bpp(void);
>  
> +/**
> + * s5pc100_fb_gpio_setup_24bpp() - S5PC100 setup function for 24bpp LCD
> + *
> + * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
> + */
> +extern void s5pc100_fb_gpio_setup_24bpp(void);
> +
>  #endif /* __PLAT_S3C_FB_H */
> diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig
> index 86edd27..6ac48a6 100644
> --- a/arch/arm/plat-s5pc1xx/Kconfig
> +++ b/arch/arm/plat-s5pc1xx/Kconfig
> @@ -37,6 +37,11 @@ config CPU_S5PC100_CLOCK
>  
>  # platform specific device setup
>  
> +config S5PC1XX_SETUP_FB_24BPP
> +	bool
> +	help
> +          Common setup code for S5PC1XX with an 24bpp RGB display helper.
> +
>  config S5PC100_SETUP_I2C0
>  	bool
>  	default y
> diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile
> index f126951..34c8da5 100644
> --- a/arch/arm/plat-s5pc1xx/Makefile
> +++ b/arch/arm/plat-s5pc1xx/Makefile
> @@ -24,5 +24,6 @@ obj-$(CONFIG_CPU_S5PC100_CLOCK)	+= s5pc100-clock.o
>  
>  # Device setup
>  
> +obj-$(CONFIG_S5PC1XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
>  obj-$(CONFIG_S5PC100_SETUP_I2C0) += setup-i2c0.o
>  obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o
> diff --git a/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c b/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c
> new file mode 100644
> index 0000000..b63f33e
> --- /dev/null
> +++ b/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c
> @@ -0,0 +1,49 @@
> +/*
> + * linux/arch/arm/plat-s5pc100/setup-fb-24bpp.c
> + *
> + * Copyright 2009 Samsung Electronics
> + *
> + * Base S5PC1XX setup information for 24bpp LCD framebuffer
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/types.h>
> +#include <linux/fb.h>
> +
> +#include <mach/regs-fb.h>
> +#include <mach/gpio.h>
> +#include <mach/map.h>
> +#include <plat/fb.h>
> +#include <plat/gpio-cfg.h>
> +#include <plat/gpio-cfg-s5pc1xx.h>
> +
> +#define DISR_OFFSET	0x7008
> +
> +void s5pc100_fb_gpio_setup_24bpp(void)
> +{
> +	unsigned int gpio = 0;
> +
> +	for (gpio = S5PC100_GPF0(0); gpio <= S5PC100_GPF0(7); gpio++) {
> +		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
> +		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
> +	}
> +
> +	for (gpio = S5PC100_GPF1(0); gpio <= S5PC100_GPF1(7); gpio++) {
> +		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
> +		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
> +	}
> +
> +	for (gpio = S5PC100_GPF2(0); gpio <= S5PC100_GPF2(7); gpio++) {
> +		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
> +		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
> +	}
> +
> +	for (gpio = S5PC100_GPF3(0); gpio <= S5PC100_GPF3(3); gpio++) {
> +		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
> +		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
> +	}
> +}
> -- 
> 1.6.4
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
-- 
Ben

Q:      What's a light-year?
A:      One-third less calories than a regular year.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 09/17] ARM: S5PC1xx: add platform helpers for s3c-fb device
@ 2009-11-09  0:02                     ` Ben Dooks
  0 siblings, 0 replies; 76+ messages in thread
From: Ben Dooks @ 2009-11-09  0:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 13, 2009 at 10:11:14AM +0200, Marek Szyprowski wrote:
> Samsung S5PC100 has LCD-controller compatible with the one known from
> previous SoCs series. Add required platform setup and support code that
> it can be used with s3c-fb driver.
> 
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  arch/arm/mach-s5pc100/include/mach/irqs.h    |    5 +
>  arch/arm/mach-s5pc100/include/mach/regs-fb.h |  259 ++++++++++++++++++++++++++
>  arch/arm/plat-s3c/include/plat/fb.h          |    7 +
>  arch/arm/plat-s5pc1xx/Kconfig                |    5 +
>  arch/arm/plat-s5pc1xx/Makefile               |    1 +
>  arch/arm/plat-s5pc1xx/setup-fb-24bpp.c       |   49 +++++
>  6 files changed, 326 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-s5pc100/include/mach/regs-fb.h
>  create mode 100644 arch/arm/plat-s5pc1xx/setup-fb-24bpp.c
> 
> diff --git a/arch/arm/mach-s5pc100/include/mach/irqs.h b/arch/arm/mach-s5pc100/include/mach/irqs.h
> index 622720d..b53fa48 100644
> --- a/arch/arm/mach-s5pc100/include/mach/irqs.h
> +++ b/arch/arm/mach-s5pc100/include/mach/irqs.h
> @@ -11,4 +11,9 @@
>  
>  #include <plat/irqs.h>
>  
> +/* LCD */
> +#define IRQ_LCD_FIFO		IRQ_LCD0
> +#define IRQ_LCD_VSYNC		IRQ_LCD1
> +#define IRQ_LCD_SYSTEM		IRQ_LCD2
> +
>  #endif /* __ASM_ARCH_IRQ_H */
> diff --git a/arch/arm/mach-s5pc100/include/mach/regs-fb.h b/arch/arm/mach-s5pc100/include/mach/regs-fb.h
> new file mode 100644
> index 0000000..4701979
> --- /dev/null
> +++ b/arch/arm/mach-s5pc100/include/mach/regs-fb.h
> @@ -0,0 +1,259 @@
> +/* arch/arm/mach-s3c6400/include/mach/regs-fb.h
> + *
> + * Copyright 2008 Openmoko, Inc.
> + * Copyright 2008 Simtec Electronics
> + *      http://armlinux.simtec.co.uk/
> + *      Ben Dooks <ben@simtec.co.uk>

Either make the file common, or have an attribution to the original
source it was copied from. Otherwise, thanks for writing some code
and giving it to me.

PS, this seems to be a less than occasional occurance here. Whilst it
might seem flattering, the amount of crud that gets mis-attributed to
other people can often cause an ammount of annoyance. Please try to
avoid this in the future.

> + * S3C64XX - new-style framebuffer register definitions
> + *
> + * This is the register set for the new style framebuffer interface
> + * found from the S3C2443 onwards and specifically the S3C64XX series
> + * S3C6400 and S3C6410.
> + *
> + * The file contains the cpu specific items which change between whichever
> + * architecture is selected. See <plat/regs-fb.h> for the core definitions
> + * that are the same.
> + *
> + * This program is free software; you can 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 the core definitions here, in case we really do need to
> + * override them at a later date.
> +*/
> +
> +#include <plat/regs-fb.h>
> +
> +#define S3C_FB_MAX_WIN (5)  /* number of hardware windows available. */
> +#define VIDCON1_FSTATUS_EVEN	(1 << 15)
> +
> +/* Video timing controls */
> +#define VIDTCON0				(0x10)
> +#define VIDTCON1				(0x14)
> +#define VIDTCON2				(0x18)
> +
> +/* Window position controls */
> +
> +#define WINCON(_win)				(0x20 + ((_win) * 4))
> +
> +/* OSD1 and OSD4 do not have register D */
> +
> +#define VIDOSD_A(_win)				(0x40 + ((_win) * 16))
> +#define VIDOSD_B(_win)				(0x44 + ((_win) * 16))
> +#define VIDOSD_C(_win)				(0x48 + ((_win) * 16))
> +#define VIDOSD_D(_win)				(0x4C + ((_win) * 16))
> +
> +/* Video buffer addresses */
> +
> +#define VIDW_BUF_START(_buff)			(0xA0 + ((_buff) * 8))
> +#define VIDW_BUF_START1(_buff)			(0xA4 + ((_buff) * 8))
> +#define VIDW_BUF_END(_buff)			(0xD0 + ((_buff) * 8))
> +#define VIDW_BUF_END1(_buff)			(0xD4 + ((_buff) * 8))
> +#define VIDW_BUF_SIZE(_buff)			(0x100 + ((_buff) * 4))
> +
> +#define VIDINTCON0				(0x130)
> +
> +#define WxKEYCONy(_win, _con)			((0x140 + ((_win) * 8)) + ((_con) * 4))
> +
> +/* WINCONx */
> +
> +#define WINCONx_CSCWIDTH_MASK			(0x3 << 26)
> +#define WINCONx_CSCWIDTH_SHIFT			(26)
> +#define WINCONx_CSCWIDTH_WIDE			(0x0 << 26)
> +#define WINCONx_CSCWIDTH_NARROW			(0x3 << 26)
> +
> +#define WINCONx_ENLOCAL				(1 << 22)
> +#define WINCONx_BUFSTATUS			(1 << 21)
> +#define WINCONx_BUFSEL				(1 << 20)
> +#define WINCONx_BUFAUTOEN			(1 << 19)
> +#define WINCONx_YCbCr				(1 << 13)
> +
> +#define WINCON1_LOCALSEL_CAMIF			(1 << 23)
> +
> +#define WINCON2_LOCALSEL_CAMIF			(1 << 23)
> +#define WINCON2_BLD_PIX				(1 << 6)
> +
> +#define WINCON2_ALPHA_SEL			(1 << 1)
> +#define WINCON2_BPPMODE_MASK			(0xf << 2)
> +#define WINCON2_BPPMODE_SHIFT			(2)
> +#define WINCON2_BPPMODE_1BPP			(0x0 << 2)
> +#define WINCON2_BPPMODE_2BPP			(0x1 << 2)
> +#define WINCON2_BPPMODE_4BPP			(0x2 << 2)
> +#define WINCON2_BPPMODE_8BPP_1232		(0x4 << 2)
> +#define WINCON2_BPPMODE_16BPP_565		(0x5 << 2)
> +#define WINCON2_BPPMODE_16BPP_A1555		(0x6 << 2)
> +#define WINCON2_BPPMODE_16BPP_I1555		(0x7 << 2)
> +#define WINCON2_BPPMODE_18BPP_666		(0x8 << 2)
> +#define WINCON2_BPPMODE_18BPP_A1665		(0x9 << 2)
> +#define WINCON2_BPPMODE_19BPP_A1666		(0xa << 2)
> +#define WINCON2_BPPMODE_24BPP_888		(0xb << 2)
> +#define WINCON2_BPPMODE_24BPP_A1887		(0xc << 2)
> +#define WINCON2_BPPMODE_25BPP_A1888		(0xd << 2)
> +#define WINCON2_BPPMODE_28BPP_A4888		(0xd << 2)
> +
> +#define WINCON3_BLD_PIX				(1 << 6)
> +
> +#define WINCON3_ALPHA_SEL			(1 << 1)
> +#define WINCON3_BPPMODE_MASK			(0xf << 2)
> +#define WINCON3_BPPMODE_SHIFT			(2)
> +#define WINCON3_BPPMODE_1BPP			(0x0 << 2)
> +#define WINCON3_BPPMODE_2BPP			(0x1 << 2)
> +#define WINCON3_BPPMODE_4BPP			(0x2 << 2)
> +#define WINCON3_BPPMODE_16BPP_565		(0x5 << 2)
> +#define WINCON3_BPPMODE_16BPP_A1555		(0x6 << 2)
> +#define WINCON3_BPPMODE_16BPP_I1555		(0x7 << 2)
> +#define WINCON3_BPPMODE_18BPP_666		(0x8 << 2)
> +#define WINCON3_BPPMODE_18BPP_A1665		(0x9 << 2)
> +#define WINCON3_BPPMODE_19BPP_A1666		(0xa << 2)
> +#define WINCON3_BPPMODE_24BPP_888		(0xb << 2)
> +#define WINCON3_BPPMODE_24BPP_A1887		(0xc << 2)
> +#define WINCON3_BPPMODE_25BPP_A1888		(0xd << 2)
> +#define WINCON3_BPPMODE_28BPP_A4888		(0xd << 2)
> +
> +#define VIDINTCON0_FIFIOSEL_WINDOW2		(0x10 << 5)
> +#define VIDINTCON0_FIFIOSEL_WINDOW3		(0x20 << 5)
> +#define VIDINTCON0_FIFIOSEL_WINDOW4		(0x40 << 5)
> +
> +#define DITHMODE				(0x170)
> +#define WINxMAP(_win)				(0x180 + ((_win) * 4))
> +
> +
> +#define DITHMODE_R_POS_MASK			(0x3 << 5)
> +#define DITHMODE_R_POS_SHIFT			(5)
> +#define DITHMODE_R_POS_8BIT			(0x0 << 5)
> +#define DITHMODE_R_POS_6BIT			(0x1 << 5)
> +#define DITHMODE_R_POS_5BIT			(0x2 << 5)
> +
> +#define DITHMODE_G_POS_MASK			(0x3 << 3)
> +#define DITHMODE_G_POS_SHIFT			(3)
> +#define DITHMODE_G_POS_8BIT			(0x0 << 3)
> +#define DITHMODE_G_POS_6BIT			(0x1 << 3)
> +#define DITHMODE_G_POS_5BIT			(0x2 << 3)
> +
> +#define DITHMODE_B_POS_MASK			(0x3 << 1)
> +#define DITHMODE_B_POS_SHIFT			(1)
> +#define DITHMODE_B_POS_8BIT			(0x0 << 1)
> +#define DITHMODE_B_POS_6BIT			(0x1 << 1)
> +#define DITHMODE_B_POS_5BIT			(0x2 << 1)
> +
> +#define DITHMODE_DITH_EN			(1 << 0)
> +
> +#define WPALCON					(0x1A0)
> +
> +#define WPALCON_W4PAL_16BPP_A555		(1 << 8)
> +#define WPALCON_W3PAL_16BPP_A555		(1 << 7)
> +#define WPALCON_W2PAL_16BPP_A555		(1 << 6)
> +
> +/* Palette registers */
> +
> +#define WIN2_PAL(_entry)			(0x300 + ((_entry) * 2))
> +#define WIN3_PAL(_entry)			(0x320 + ((_entry) * 2))
> +#define WIN4_PAL(_entry)			(0x340 + ((_entry) * 2))
> +#define WIN0_PAL(_entry)			(0x400 + ((_entry) * 4))
> +#define WIN1_PAL(_entry)			(0x800 + ((_entry) * 4))
> +
> +/* system specific implementation code for palette sizes, and other
> + * information that changes depending on which architecture is being
> + * compiled.
> +*/
> +
> +/* return true if window _win has OSD register D */
> +#define s3c_fb_has_osd_d(_win) ((_win) != 4 && (_win) != 0)
> +
> +static inline unsigned int s3c_fb_win_pal_size(unsigned int win)
> +{
> +	if (win < 2)
> +		return 256;
> +	if (win < 4)
> +		return 16;
> +	if (win == 4)
> +		return 4;
> +
> +	BUG();	/* shouldn't get here */
> +}
> +
> +static inline int s3c_fb_validate_win_bpp(unsigned int win, unsigned int bpp)
> +{
> +	/* all windows can do 1/2 bpp */
> +
> +	if ((bpp == 25 || bpp == 19) && win == 0)
> +		return 0;	/* win 0 does not have 19 or 25bpp modes */
> +
> +	if (bpp == 4 && win == 4)
> +		return 0;
> +
> +	if (bpp == 8 && (win >= 3))
> +		return 0;	/* win 3/4 cannot do 8bpp in any mode */
> +
> +	return 1;
> +}
> +
> +static inline unsigned int s3c_fb_pal_reg(unsigned int window, int reg)
> +{
> +	switch (window) {
> +	case 0: return WIN0_PAL(reg);
> +	case 1: return WIN1_PAL(reg);
> +	case 2: return WIN2_PAL(reg);
> +	case 3: return WIN3_PAL(reg);
> +	case 4: return WIN4_PAL(reg);
> +	}
> +
> +	BUG();
> +}
> +
> +static inline int s3c_fb_pal_is16(unsigned int window)
> +{
> +	return window > 1;
> +}
> +
> +struct s3c_fb_palette {
> +	struct fb_bitfield	r;
> +	struct fb_bitfield	g;
> +	struct fb_bitfield	b;
> +	struct fb_bitfield	a;
> +};
> +
> +static inline void s3c_fb_init_palette(unsigned int window,
> +				       struct s3c_fb_palette *palette)
> +{
> +	if (window < 2) {
> +		/* Windows 0/1 are 8/8/8 or A/8/8/8 */
> +		palette->r.offset = 16;
> +		palette->r.length = 8;
> +		palette->g.offset = 8;
> +		palette->g.length = 8;
> +		palette->b.offset = 0;
> +		palette->b.length = 8;
> +	} else {
> +		/* currently we assume RGB 5/6/5 */
> +		palette->r.offset = 11;
> +		palette->r.length = 5;
> +		palette->g.offset = 5;
> +		palette->g.length = 6;
> +		palette->b.offset = 0;
> +		palette->b.length = 5;
> +	}
> +}
> +
> +/* Notes on per-window bpp settings
> + *
> + * Value	Win0	 Win1	  Win2	   Win3	    Win 4
> + * 0000		1(P)	 1(P)	  1(P)	   1(P)	    1(P)
> + * 0001		2(P)	 2(P)     2(P)	   2(P)	    2(P)
> + * 0010		4(P)	 4(P)     4(P)	   4(P)     -none-
> + * 0011		8(P)	 8(P)     -none-   -none-   -none-
> + * 0100		-none-	 8(A232)  8(A232)  -none-   -none-
> + * 0101		16(565)	 16(565)  16(565)  16(565)   16(565)
> + * 0110		-none-	 16(A555) 16(A555) 16(A555)  16(A555)
> + * 0111		16(I555) 16(I565) 16(I555) 16(I555)  16(I555)
> + * 1000		18(666)	 18(666)  18(666)  18(666)   18(666)
> + * 1001		-none-	 18(A665) 18(A665) 18(A665)  16(A665)
> + * 1010		-none-	 19(A666) 19(A666) 19(A666)  19(A666)
> + * 1011		24(888)	 24(888)  24(888)  24(888)   24(888)
> + * 1100		-none-	 24(A887) 24(A887) 24(A887)  24(A887)
> + * 1101		-none-	 25(A888) 25(A888) 25(A888)  25(A888)
> + * 1110		-none-	 -none-	  -none-   -none-    -none-
> + * 1111		-none-	 -none-   -none-   -none-    -none-
> +*/
> diff --git a/arch/arm/plat-s3c/include/plat/fb.h b/arch/arm/plat-s3c/include/plat/fb.h
> index 214ff56..f8db879 100644
> --- a/arch/arm/plat-s3c/include/plat/fb.h
> +++ b/arch/arm/plat-s3c/include/plat/fb.h
> @@ -70,4 +70,11 @@ extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd);
>   */
>  extern void s3c64xx_fb_gpio_setup_24bpp(void);
>  
> +/**
> + * s5pc100_fb_gpio_setup_24bpp() - S5PC100 setup function for 24bpp LCD
> + *
> + * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
> + */
> +extern void s5pc100_fb_gpio_setup_24bpp(void);
> +
>  #endif /* __PLAT_S3C_FB_H */
> diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig
> index 86edd27..6ac48a6 100644
> --- a/arch/arm/plat-s5pc1xx/Kconfig
> +++ b/arch/arm/plat-s5pc1xx/Kconfig
> @@ -37,6 +37,11 @@ config CPU_S5PC100_CLOCK
>  
>  # platform specific device setup
>  
> +config S5PC1XX_SETUP_FB_24BPP
> +	bool
> +	help
> +          Common setup code for S5PC1XX with an 24bpp RGB display helper.
> +
>  config S5PC100_SETUP_I2C0
>  	bool
>  	default y
> diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile
> index f126951..34c8da5 100644
> --- a/arch/arm/plat-s5pc1xx/Makefile
> +++ b/arch/arm/plat-s5pc1xx/Makefile
> @@ -24,5 +24,6 @@ obj-$(CONFIG_CPU_S5PC100_CLOCK)	+= s5pc100-clock.o
>  
>  # Device setup
>  
> +obj-$(CONFIG_S5PC1XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
>  obj-$(CONFIG_S5PC100_SETUP_I2C0) += setup-i2c0.o
>  obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o
> diff --git a/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c b/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c
> new file mode 100644
> index 0000000..b63f33e
> --- /dev/null
> +++ b/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c
> @@ -0,0 +1,49 @@
> +/*
> + * linux/arch/arm/plat-s5pc100/setup-fb-24bpp.c
> + *
> + * Copyright 2009 Samsung Electronics
> + *
> + * Base S5PC1XX setup information for 24bpp LCD framebuffer
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/types.h>
> +#include <linux/fb.h>
> +
> +#include <mach/regs-fb.h>
> +#include <mach/gpio.h>
> +#include <mach/map.h>
> +#include <plat/fb.h>
> +#include <plat/gpio-cfg.h>
> +#include <plat/gpio-cfg-s5pc1xx.h>
> +
> +#define DISR_OFFSET	0x7008
> +
> +void s5pc100_fb_gpio_setup_24bpp(void)
> +{
> +	unsigned int gpio = 0;
> +
> +	for (gpio = S5PC100_GPF0(0); gpio <= S5PC100_GPF0(7); gpio++) {
> +		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
> +		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
> +	}
> +
> +	for (gpio = S5PC100_GPF1(0); gpio <= S5PC100_GPF1(7); gpio++) {
> +		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
> +		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
> +	}
> +
> +	for (gpio = S5PC100_GPF2(0); gpio <= S5PC100_GPF2(7); gpio++) {
> +		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
> +		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
> +	}
> +
> +	for (gpio = S5PC100_GPF3(0); gpio <= S5PC100_GPF3(3); gpio++) {
> +		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
> +		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
> +	}
> +}
> -- 
> 1.6.4
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
-- 
Ben

Q:      What's a light-year?
A:      One-third less calories than a regular year.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH] Update Samsung S5PC100 SoC support
  2009-10-13  8:11 ` Marek Szyprowski
@ 2009-11-09  0:05   ` Ben Dooks
  -1 siblings, 0 replies; 76+ messages in thread
From: Ben Dooks @ 2009-11-09  0:05 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-arm-kernel, linux-samsung-soc, kyungmin.park, bhmin, ben-linux

On Tue, Oct 13, 2009 at 10:11:05AM +0200, Marek Szyprowski wrote:
> Hello,
> 
> This patch series updates Samsung S5PC100 SoC support. S5PC100 platform
> core has been extended with new clocks hierarchy implementation, gpio lib,
> support for external and gpio interrupts and some basics of power
> management (cpu idle and system reset). Also platform helpers for
> s3c framebuffer, i2c and hsmmc drivers has been added.
> 
> All these patches has been tested on SMDKC100 board.

Apart from the problems with sign-offs/authors on these patches, they
seem to be mostly fine. My only concern is the LCD header files and
I will try and revist these before the next merge window is upon us.

-- 
Ben

Q:      What's a light-year?
A:      One-third less calories than a regular year.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH] Update Samsung S5PC100 SoC support
@ 2009-11-09  0:05   ` Ben Dooks
  0 siblings, 0 replies; 76+ messages in thread
From: Ben Dooks @ 2009-11-09  0:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 13, 2009 at 10:11:05AM +0200, Marek Szyprowski wrote:
> Hello,
> 
> This patch series updates Samsung S5PC100 SoC support. S5PC100 platform
> core has been extended with new clocks hierarchy implementation, gpio lib,
> support for external and gpio interrupts and some basics of power
> management (cpu idle and system reset). Also platform helpers for
> s3c framebuffer, i2c and hsmmc drivers has been added.
> 
> All these patches has been tested on SMDKC100 board.

Apart from the problems with sign-offs/authors on these patches, they
seem to be mostly fine. My only concern is the LCD header files and
I will try and revist these before the next merge window is upon us.

-- 
Ben

Q:      What's a light-year?
A:      One-third less calories than a regular year.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 02/17] ARM: S5PC1XX: registers rename
  2009-11-06 15:02         ` Marek Szyprowski
@ 2009-11-09  0:07           ` Ben Dooks
  -1 siblings, 0 replies; 76+ messages in thread
From: Ben Dooks @ 2009-11-09  0:07 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: 'Harald Welte',
	linux-samsung-soc, kyungmin.park, bhmin, ben-linux,
	linux-arm-kernel

On Fri, Nov 06, 2009 at 04:02:17PM +0100, Marek Szyprowski wrote:
> Hello,
> 
> On Friday, November 06, 2009 4:19 AM, Harald Welte wrote:
>  
> > Hi Marek,
> > 
> > On Tue, Oct 13, 2009 at 10:11:07AM +0200, Marek Szyprowski wrote:
> > 
> > > S5PC110 and S5PC100 register maps differs in many places, rename all
> > > defined registers to be S5PC100 specific. System map has been also updated
> > > to cover more integrated peripherals.
> > 
> > The general idea of this patch is fine.  However, I have some questions:
> > 
> > >  /* System */
> > > -#define S5PC100_PA_SYS		(0xE0100000)
> > > -#define S5PC100_PA_CLK		(S5PC100_PA_SYS + 0x0)
> > > -#define S5PC100_PA_PWR		(S5PC100_PA_SYS + 0x8000)
> > > +#define S5PC100_PA_CLK		(0xE0100000)
> > > +#define S5PC100_PA_CLK_OTHER	(0xE0200000)
> > > +#define S5PC100_PA_PWR		(0xE0108000)
> > 
> > this is more like a rename.  Why was this done?  It would be good to explain in
> > the commitlog
> 
> I renamed these registers to better match the chip specification. The 'SYS'
> register name was borrowed from S3C64XX series and is a bit inadequate in C100.
>  
> > > +/* GPIO */
> > > +#define S5PC100_PA_GPIO		(0xE0300000)
> > > +#define S5PC1XX_PA_GPIO		S5PC100_PA_GPIO
> > > +#define S5PC1XX_VA_GPIO		S3C_ADDR(0x00500000)
> > 
> > If the address is different for c100 and c110: why do we need a S5CP1XX_*
> > definition?  In my personal opinion, all those compile-time defines are a
> > kludge and we should not introduce more of them.  They will bite us in the back
> > if we ever in the future want to build a kernel that can boot on both c100 and
> > c110.
> 
> These C1XX defines were the first step to prepare the code for C110 support. 
> 
> S5PC110 register map differs completely from the S5PC100 one. These two SOCs
> cannot be easily handled by the same kernel binary image without some hacks and
> runtime fixups if we place them in the one kernel platform. Creating yet another
> kernel platform just because of these differences would unnecessarily duplicate
> a lot of code and would not use the potential of the current kernel
> infrastructure (separate include directories, resource&device driver model, etc).

can people line-wrap their emails a bit more please..
 
> My idea was to introduce a sub-platforms in plat-s5pc1xx. Such sub-platforms
> would be exclusive - one for C100 and one for C110. Each of the sub-platforms would
> have its own include files (in mach-s5pc100 and mach-s5pc110 directories
> respectively) and most of the chip differences can be handled in compile time by
> proper macros. Macros for the common resources would use 'C1XX' names. In this
> approach common resources (GPIO, DMA, io space and so on) can be easily defined
> with C1XX defines. This also perfectly matches the current convention of common
> S3C_XXX defines (i.e. S3C_PA_UART, S3C_PA_FB, S3C_VA_VICn, S3C_PA_HSMMCn, and so
> on), so most of the code from arch/arm/plat-s3c/ can be reused without any
> modifications. I assume that the S3C prefix would be renamed to SAMSUNG sometime
> later.

I will be working on this and hopefully have some stuff soon to try
and remove a lot of these problems. Harald and I spent some time on
this subject when we where last together.

-- 
Ben

Q:      What's a light-year?
A:      One-third less calories than a regular year.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 02/17] ARM: S5PC1XX: registers rename
@ 2009-11-09  0:07           ` Ben Dooks
  0 siblings, 0 replies; 76+ messages in thread
From: Ben Dooks @ 2009-11-09  0:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 06, 2009 at 04:02:17PM +0100, Marek Szyprowski wrote:
> Hello,
> 
> On Friday, November 06, 2009 4:19 AM, Harald Welte wrote:
>  
> > Hi Marek,
> > 
> > On Tue, Oct 13, 2009 at 10:11:07AM +0200, Marek Szyprowski wrote:
> > 
> > > S5PC110 and S5PC100 register maps differs in many places, rename all
> > > defined registers to be S5PC100 specific. System map has been also updated
> > > to cover more integrated peripherals.
> > 
> > The general idea of this patch is fine.  However, I have some questions:
> > 
> > >  /* System */
> > > -#define S5PC100_PA_SYS		(0xE0100000)
> > > -#define S5PC100_PA_CLK		(S5PC100_PA_SYS + 0x0)
> > > -#define S5PC100_PA_PWR		(S5PC100_PA_SYS + 0x8000)
> > > +#define S5PC100_PA_CLK		(0xE0100000)
> > > +#define S5PC100_PA_CLK_OTHER	(0xE0200000)
> > > +#define S5PC100_PA_PWR		(0xE0108000)
> > 
> > this is more like a rename.  Why was this done?  It would be good to explain in
> > the commitlog
> 
> I renamed these registers to better match the chip specification. The 'SYS'
> register name was borrowed from S3C64XX series and is a bit inadequate in C100.
>  
> > > +/* GPIO */
> > > +#define S5PC100_PA_GPIO		(0xE0300000)
> > > +#define S5PC1XX_PA_GPIO		S5PC100_PA_GPIO
> > > +#define S5PC1XX_VA_GPIO		S3C_ADDR(0x00500000)
> > 
> > If the address is different for c100 and c110: why do we need a S5CP1XX_*
> > definition?  In my personal opinion, all those compile-time defines are a
> > kludge and we should not introduce more of them.  They will bite us in the back
> > if we ever in the future want to build a kernel that can boot on both c100 and
> > c110.
> 
> These C1XX defines were the first step to prepare the code for C110 support. 
> 
> S5PC110 register map differs completely from the S5PC100 one. These two SOCs
> cannot be easily handled by the same kernel binary image without some hacks and
> runtime fixups if we place them in the one kernel platform. Creating yet another
> kernel platform just because of these differences would unnecessarily duplicate
> a lot of code and would not use the potential of the current kernel
> infrastructure (separate include directories, resource&device driver model, etc).

can people line-wrap their emails a bit more please..
 
> My idea was to introduce a sub-platforms in plat-s5pc1xx. Such sub-platforms
> would be exclusive - one for C100 and one for C110. Each of the sub-platforms would
> have its own include files (in mach-s5pc100 and mach-s5pc110 directories
> respectively) and most of the chip differences can be handled in compile time by
> proper macros. Macros for the common resources would use 'C1XX' names. In this
> approach common resources (GPIO, DMA, io space and so on) can be easily defined
> with C1XX defines. This also perfectly matches the current convention of common
> S3C_XXX defines (i.e. S3C_PA_UART, S3C_PA_FB, S3C_VA_VICn, S3C_PA_HSMMCn, and so
> on), so most of the code from arch/arm/plat-s3c/ can be reused without any
> modifications. I assume that the S3C prefix would be renamed to SAMSUNG sometime
> later.

I will be working on this and hopefully have some stuff soon to try
and remove a lot of these problems. Harald and I spent some time on
this subject when we where last together.

-- 
Ben

Q:      What's a light-year?
A:      One-third less calories than a regular year.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 01/17] ARM: MM: use 64bytes of L1 cache on plat S5PC1xx
  2009-11-08 23:58     ` Ben Dooks
@ 2009-11-09  2:41       ` Kyungmin Park
  -1 siblings, 0 replies; 76+ messages in thread
From: Kyungmin Park @ 2009-11-09  2:41 UTC (permalink / raw)
  To: Ben Dooks; +Cc: Marek Szyprowski, linux-arm-kernel, linux-samsung-soc, bhmin

Hi,

It's missing of "From".

Actually I don't care who send and from. I just want to merge the
s5pc1xx series patches to mainline ASAP .

Thank you,
Kyungmin Park

On Mon, Nov 9, 2009 at 8:58 AM, Ben Dooks <ben-linux@fluff.org> wrote:
> On Tue, Oct 13, 2009 at 10:11:06AM +0200, Marek Szyprowski wrote:
>> Samsung S5PC1xx SoCs are Coretex8 based, so use 64 bytes of L1 cache
>> line instead of the default 32 bytes.
>>
>> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>
> This worries me, either this patch was from 'Kyungmin Park' and thus
> should have either been sent by, or have an 'From:' line at the top
> of the description. If this has been appraised by Kyungmin then the
> signoff should either be after Marek's (as this is the sender) or be
> something other than a signed-off-by.
>
>> ---
>>  arch/arm/mm/Kconfig |    2 +-
>>  1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
>> index e993140..9cf7706 100644
>> --- a/arch/arm/mm/Kconfig
>> +++ b/arch/arm/mm/Kconfig
>> @@ -777,5 +777,5 @@ config CACHE_XSC3L2
>>
>>  config ARM_L1_CACHE_SHIFT
>>       int
>> -     default 6 if ARCH_OMAP3
>> +     default 6 if ARCH_OMAP3 || ARCH_S5PC1XX
>>       default 5
>> --
>> 1.6.4
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
> --
> --
> Ben
>
> Q:      What's a light-year?
> A:      One-third less calories than a regular year.
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 01/17] ARM: MM: use 64bytes of L1 cache on plat S5PC1xx
@ 2009-11-09  2:41       ` Kyungmin Park
  0 siblings, 0 replies; 76+ messages in thread
From: Kyungmin Park @ 2009-11-09  2:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

It's missing of "From".

Actually I don't care who send and from. I just want to merge the
s5pc1xx series patches to mainline ASAP .

Thank you,
Kyungmin Park

On Mon, Nov 9, 2009 at 8:58 AM, Ben Dooks <ben-linux@fluff.org> wrote:
> On Tue, Oct 13, 2009 at 10:11:06AM +0200, Marek Szyprowski wrote:
>> Samsung S5PC1xx SoCs are Coretex8 based, so use 64 bytes of L1 cache
>> line instead of the default 32 bytes.
>>
>> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>
> This worries me, either this patch was from 'Kyungmin Park' and thus
> should have either been sent by, or have an 'From:' line at the top
> of the description. If this has been appraised by Kyungmin then the
> signoff should either be after Marek's (as this is the sender) or be
> something other than a signed-off-by.
>
>> ---
>> ?arch/arm/mm/Kconfig | ? ?2 +-
>> ?1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
>> index e993140..9cf7706 100644
>> --- a/arch/arm/mm/Kconfig
>> +++ b/arch/arm/mm/Kconfig
>> @@ -777,5 +777,5 @@ config CACHE_XSC3L2
>>
>> ?config ARM_L1_CACHE_SHIFT
>> ? ? ? int
>> - ? ? default 6 if ARCH_OMAP3
>> + ? ? default 6 if ARCH_OMAP3 || ARCH_S5PC1XX
>> ? ? ? default 5
>> --
>> 1.6.4
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
> --
> --
> Ben
>
> Q: ? ? ?What's a light-year?
> A: ? ? ?One-third less calories than a regular year.
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 08/17] ARM: S5PC1XX: add cpu idle and system reset support
  2009-10-13  7:57             ` [PATCH 07/17] ARM: S5PC1xx: add gpiolib and external/gpio interrupt support Marek Szyprowski
@ 2009-10-13  7:57               ` Marek Szyprowski
  0 siblings, 0 replies; 76+ messages in thread
From: Marek Szyprowski @ 2009-10-13  7:57 UTC (permalink / raw)
  To: linux-arm-kernel, linux-samsung-soc
  Cc: m.szyprowski, kyungmin.park, ben-linux, bhmin

Add CPU idle support by a call to SoC build-in power management core.
Add system reset support by a simple write to system controll register.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 arch/arm/mach-s5pc100/cpu.c                     |   22 ++++++
 arch/arm/mach-s5pc100/include/mach/system.h     |   15 +++-
 arch/arm/plat-s3c/include/plat/cpu.h            |    6 ++
 arch/arm/plat-s5pc1xx/include/plat/regs-power.h |   84 +++++++++++++++++++++++
 4 files changed, 124 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/plat-s5pc1xx/include/plat/regs-power.h

diff --git a/arch/arm/mach-s5pc100/cpu.c b/arch/arm/mach-s5pc100/cpu.c
index 0e71889..a23ca57 100644
--- a/arch/arm/mach-s5pc100/cpu.c
+++ b/arch/arm/mach-s5pc100/cpu.c
@@ -22,6 +22,8 @@
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 
+#include <asm/proc-fns.h>
+
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
@@ -32,6 +34,7 @@
 
 #include <plat/cpu-freq.h>
 #include <plat/regs-serial.h>
+#include <plat/regs-power.h>
 
 #include <plat/cpu.h>
 #include <plat/devs.h>
@@ -45,6 +48,23 @@
 static struct map_desc s5pc100_iodesc[] __initdata = {
 };
 
+static void s5pc100_idle(void)
+{
+	unsigned long tmp;
+
+	tmp = __raw_readl(S5PC100_PWR_CFG);
+	tmp &= ~S5PC100_PWRCFG_CFG_DEEP_IDLE;
+	tmp &= ~S5PC100_PWRCFG_CFG_WFI_MASK;
+	tmp |= S5PC100_PWRCFG_CFG_WFI_DEEP_IDLE;
+	__raw_writel(tmp, S5PC100_PWR_CFG);
+
+	tmp = __raw_readl(S5PC100_OTHERS);
+	tmp |= S5PC100_PMU_INT_DISABLE;
+	__raw_writel(tmp, S5PC100_OTHERS);
+
+	cpu_do_idle();
+}
+
 /* s5pc100_map_io
  *
  * register the standard cpu IO areas
@@ -93,5 +113,7 @@ int __init s5pc100_init(void)
 {
 	printk(KERN_DEBUG "S5PC100: Initialising architecture\n");
 
+	s5pc1xx_idle = s5pc100_idle;
+
 	return sysdev_register(&s5pc100_sysdev);
 }
diff --git a/arch/arm/mach-s5pc100/include/mach/system.h b/arch/arm/mach-s5pc100/include/mach/system.h
index e390143..07f0907 100644
--- a/arch/arm/mach-s5pc100/include/mach/system.h
+++ b/arch/arm/mach-s5pc100/include/mach/system.h
@@ -11,14 +11,23 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H __FILE__
 
+#include <linux/io.h>
+#include <mach/map.h>
+
+void (*s5pc1xx_idle)(void);
+
 static void arch_idle(void)
 {
-	/* nothing here yet */
+	if (s5pc1xx_idle)
+		s5pc1xx_idle();
 }
 
 static void arch_reset(char mode, const char *cmd)
 {
-	/* nothing here yet */
-}
+	unsigned long reset;
 
+	reset = 0xc100;
+	__raw_writel(reset, S5PC1XX_VA_CLK_OTHER);
+	return;
+}
 #endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/plat-s3c/include/plat/cpu.h b/arch/arm/plat-s3c/include/plat/cpu.h
index fbc3d49..d1131ca 100644
--- a/arch/arm/plat-s3c/include/plat/cpu.h
+++ b/arch/arm/plat-s3c/include/plat/cpu.h
@@ -12,6 +12,9 @@
 
 /* todo - fix when rmk changes iodescs to use `void __iomem *` */
 
+#ifndef __SAMSUNG_PLAT_CPU_H
+#define __SAMSUNG_PLAT_CPU_H
+
 #define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
 
 #ifndef MHZ
@@ -73,3 +76,6 @@ extern struct sysdev_class s3c2443_sysclass;
 extern struct sysdev_class s3c6410_sysclass;
 extern struct sysdev_class s3c64xx_sysclass;
 
+extern void (*s5pc1xx_idle)(void);
+
+#endif
diff --git a/arch/arm/plat-s5pc1xx/include/plat/regs-power.h b/arch/arm/plat-s5pc1xx/include/plat/regs-power.h
new file mode 100644
index 0000000..02ffa49
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/regs-power.h
@@ -0,0 +1,84 @@
+/* arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Jongse Won <jongse.won@samsung.com>
+ *
+ * S5PC1XX clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARM_REGS_PWR
+#define __ASM_ARM_REGS_PWR __FILE__
+
+#define S5PC1XX_PWRREG(x)			(S5PC1XX_VA_PWR + (x))
+
+/* s5pc100 (0xE0108000) register for power management */
+#define S5PC100_PWR_CFG				S5PC1XX_PWRREG(0x0)
+#define S5PC100_EINT_WAKEUP_MASK		S5PC1XX_PWRREG(0x4)
+#define S5PC100_NORMAL_CFG			S5PC1XX_PWRREG(0x10)
+#define S5PC100_STOP_CFG			S5PC1XX_PWRREG(0x14)
+#define S5PC100_SLEEP_CFG			S5PC1XX_PWRREG(0x18)
+#define S5PC100_STOP_MEM_CFG			S5PC1XX_PWRREG(0x1C)
+#define S5PC100_OSC_FREQ			S5PC1XX_PWRREG(0x100)
+#define S5PC100_OSC_STABLE			S5PC1XX_PWRREG(0x104)
+#define S5PC100_PWR_STABLE			S5PC1XX_PWRREG(0x108)
+#define S5PC100_MTC_STABLE			S5PC1XX_PWRREG(0x110)
+#define S5PC100_CLAMP_STABLE			S5PC1XX_PWRREG(0x114)
+#define S5PC100_OTHERS				S5PC1XX_PWRREG(0x200)
+#define S5PC100_RST_STAT			S5PC1XX_PWRREG(0x300)
+#define S5PC100_WAKEUP_STAT			S5PC1XX_PWRREG(0x304)
+#define S5PC100_BLK_PWR_STAT			S5PC1XX_PWRREG(0x308)
+#define S5PC100_INFORM0				S5PC1XX_PWRREG(0x400)
+#define S5PC100_INFORM1				S5PC1XX_PWRREG(0x404)
+#define S5PC100_INFORM2				S5PC1XX_PWRREG(0x408)
+#define S5PC100_INFORM3				S5PC1XX_PWRREG(0x40C)
+#define S5PC100_INFORM4				S5PC1XX_PWRREG(0x410)
+#define S5PC100_INFORM5				S5PC1XX_PWRREG(0x414)
+#define S5PC100_INFORM6				S5PC1XX_PWRREG(0x418)
+#define S5PC100_INFORM7				S5PC1XX_PWRREG(0x41C)
+#define S5PC100_DCGIDX_MAP0			S5PC1XX_PWRREG(0x500)
+#define S5PC100_DCGIDX_MAP1			S5PC1XX_PWRREG(0x504)
+#define S5PC100_DCGIDX_MAP2			S5PC1XX_PWRREG(0x508)
+#define S5PC100_DCGPERF_MAP0			S5PC1XX_PWRREG(0x50C)
+#define S5PC100_DCGPERF_MAP1			S5PC1XX_PWRREG(0x510)
+#define S5PC100_DVCIDX_MAP			S5PC1XX_PWRREG(0x514)
+#define S5PC100_FREQ_CPU			S5PC1XX_PWRREG(0x518)
+#define S5PC100_FREQ_DPM			S5PC1XX_PWRREG(0x51C)
+#define S5PC100_DVSEMCLK_EN			S5PC1XX_PWRREG(0x520)
+#define S5PC100_APLL_CON_L8			S5PC1XX_PWRREG(0x600)
+#define S5PC100_APLL_CON_L7			S5PC1XX_PWRREG(0x604)
+#define S5PC100_APLL_CON_L6			S5PC1XX_PWRREG(0x608)
+#define S5PC100_APLL_CON_L5			S5PC1XX_PWRREG(0x60C)
+#define S5PC100_APLL_CON_L4			S5PC1XX_PWRREG(0x610)
+#define S5PC100_APLL_CON_L3			S5PC1XX_PWRREG(0x614)
+#define S5PC100_APLL_CON_L2			S5PC1XX_PWRREG(0x618)
+#define S5PC100_APLL_CON_L1			S5PC1XX_PWRREG(0x61C)
+#define S5PC100_IEM_CONTROL			S5PC1XX_PWRREG(0x620)
+#define S5PC100_CLKDIV_IEM_L8			S5PC1XX_PWRREG(0x700)
+#define S5PC100_CLKDIV_IEM_L7			S5PC1XX_PWRREG(0x704)
+#define S5PC100_CLKDIV_IEM_L6			S5PC1XX_PWRREG(0x708)
+#define S5PC100_CLKDIV_IEM_L5			S5PC1XX_PWRREG(0x70C)
+#define S5PC100_CLKDIV_IEM_L4			S5PC1XX_PWRREG(0x710)
+#define S5PC100_CLKDIV_IEM_L3			S5PC1XX_PWRREG(0x714)
+#define S5PC100_CLKDIV_IEM_L2			S5PC1XX_PWRREG(0x718)
+#define S5PC100_CLKDIV_IEM_L1			S5PC1XX_PWRREG(0x71C)
+#define S5PC100_IEM_HPMCLK_DIV			S5PC1XX_PWRREG(0x724)
+
+/* PWR_CFG */
+#define S5PC100_PWRCFG_CFG_DEEP_IDLE		(1 << 31)
+#define S5PC100_PWRCFG_CFG_WFI_MASK		(3 << 5)
+#define S5PC100_PWRCFG_CFG_WFI_IDLE		(0 << 5)
+#define S5PC100_PWRCFG_CFG_WFI_DEEP_IDLE	(1 << 5)
+#define S5PC100_PWRCFG_CFG_WFI_STOP		(2 << 5)
+#define S5PC100_PWRCFG_CFG_WFI_SLEEP		(3 << 5)
+
+/* SLEEP_CFG */
+#define S5PC100_SLEEP_OSC_EN_SLEEP		(1 << 0)
+
+/* OTHERS */
+#define S5PC100_PMU_INT_DISABLE			(1 << 24)
+
+#endif /* __ASM_ARM_REGS_PWR */
-- 
1.6.4

^ permalink raw reply related	[flat|nested] 76+ messages in thread

end of thread, other threads:[~2009-11-09  2:41 UTC | newest]

Thread overview: 76+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-13  8:11 [PATCH] Update Samsung S5PC100 SoC support Marek Szyprowski
2009-10-13  8:11 ` Marek Szyprowski
2009-10-13  8:11 ` [PATCH 01/17] ARM: MM: use 64bytes of L1 cache on plat S5PC1xx Marek Szyprowski
2009-10-13  8:11   ` Marek Szyprowski
2009-10-13  8:11   ` [PATCH 02/17] ARM: S5PC1XX: registers rename Marek Szyprowski
2009-10-13  8:11     ` Marek Szyprowski
2009-10-13  8:11     ` [PATCH 03/17] ARM: S5PC1XX: clock " Marek Szyprowski
2009-10-13  8:11       ` Marek Szyprowski
2009-10-13  8:11       ` [PATCH 04/17] ARM: S5PC1XX: clocks reimplementation Marek Szyprowski
2009-10-13  8:11         ` Marek Szyprowski
2009-10-13  8:11         ` [PATCH 05/17] ARM: S5PC1XX: add GPIO L banks to register definition Marek Szyprowski
2009-10-13  8:11           ` Marek Szyprowski
2009-10-13  8:11           ` [PATCH 06/17] ARM: S5PC1XX: GPIO registers rename Marek Szyprowski
2009-10-13  8:11             ` Marek Szyprowski
2009-10-13  8:11             ` [PATCH 07/17] ARM: S5PC1xx: add gpiolib and external/gpio interrupt support Marek Szyprowski
2009-10-13  8:11               ` Marek Szyprowski
2009-10-13  8:11               ` [PATCH 08/17] ARM: S5PC1XX: add cpu idle and system reset support Marek Szyprowski
2009-10-13  8:11                 ` Marek Szyprowski
2009-10-13  8:11                 ` [PATCH 09/17] ARM: S5PC1xx: add platform helpers for s3c-fb device Marek Szyprowski
2009-10-13  8:11                   ` Marek Szyprowski
2009-10-13  8:11                   ` [PATCH 10/17] SMDKC100: enable S3C FrameBuffer Marek Szyprowski
2009-10-13  8:11                     ` Marek Szyprowski
2009-10-13  8:11                     ` [PATCH 11/17] drivers: fb: enable S3C FrameBuffer on S5PC1XX platform Marek Szyprowski
2009-10-13  8:11                       ` Marek Szyprowski
2009-10-13  8:11                       ` [PATCH 12/17] ARM: S5PC1xx: add platform helpers for i2c adapter devices Marek Szyprowski
2009-10-13  8:11                         ` Marek Szyprowski
2009-10-13  8:11                         ` [PATCH 13/17] SMDKC100: add I2C0 and I2C1 buses support Marek Szyprowski
2009-10-13  8:11                           ` Marek Szyprowski
2009-10-13  8:11                           ` [PATCH 14/17] drivers: i2c: s3c2410-i2c also on S5PC1XX platform Marek Szyprowski
2009-10-13  8:11                             ` Marek Szyprowski
2009-10-13  8:11                             ` [PATCH 15/17] ARM: S5PC1xx: add platform helpers for SDHCI host controllers Marek Szyprowski
2009-10-13  8:11                               ` Marek Szyprowski
2009-10-13  8:11                               ` [PATCH 16/17] SMDKC100: add SDHCI controllers 0, 1 and 2 support Marek Szyprowski
2009-10-13  8:11                                 ` Marek Szyprowski
2009-10-13  8:11                                 ` [PATCH 17/17] drivers: MMC: enable SDHCI-S3C on S5PC1XX platform Marek Szyprowski
2009-10-13  8:11                                   ` Marek Szyprowski
2009-11-06  3:31                               ` [PATCH 15/17] ARM: S5PC1xx: add platform helpers for SDHCI host controllers Harald Welte
2009-11-06  3:31                                 ` Harald Welte
2009-11-06  3:30                           ` [PATCH 13/17] SMDKC100: add I2C0 and I2C1 buses support Harald Welte
2009-11-06  3:30                             ` Harald Welte
2009-11-06  3:30                         ` [PATCH 12/17] ARM: S5PC1xx: add platform helpers for i2c adapter devices Harald Welte
2009-11-06  3:30                           ` Harald Welte
2009-11-06  3:29                     ` [PATCH 10/17] SMDKC100: enable S3C FrameBuffer Harald Welte
2009-11-06  3:29                       ` Harald Welte
2009-11-06  3:29                   ` [PATCH 09/17] ARM: S5PC1xx: add platform helpers for s3c-fb device Harald Welte
2009-11-06  3:29                     ` Harald Welte
2009-11-09  0:02                   ` Ben Dooks
2009-11-09  0:02                     ` Ben Dooks
2009-11-06  3:26                 ` [PATCH 08/17] ARM: S5PC1XX: add cpu idle and system reset support Harald Welte
2009-11-06  3:26                   ` Harald Welte
2009-11-06  3:23               ` [PATCH 07/17] ARM: S5PC1xx: add gpiolib and external/gpio interrupt support Harald Welte
2009-11-06  3:23                 ` Harald Welte
2009-11-09  0:00               ` Ben Dooks
2009-11-09  0:00                 ` Ben Dooks
2009-11-06  3:20             ` [PATCH 06/17] ARM: S5PC1XX: GPIO registers rename Harald Welte
2009-11-06  3:20               ` Harald Welte
2009-11-06  3:20           ` [PATCH 05/17] ARM: S5PC1XX: add GPIO L banks to register definition Harald Welte
2009-11-06  3:20             ` Harald Welte
2009-11-06  3:19       ` [PATCH 03/17] ARM: S5PC1XX: clock registers rename Harald Welte
2009-11-06  3:19         ` Harald Welte
2009-11-06  3:18     ` [PATCH 02/17] ARM: S5PC1XX: " Harald Welte
2009-11-06  3:18       ` Harald Welte
2009-11-06 15:02       ` Marek Szyprowski
2009-11-06 15:02         ` Marek Szyprowski
2009-11-09  0:07         ` Ben Dooks
2009-11-09  0:07           ` Ben Dooks
2009-11-06  8:17     ` tommy.hong
2009-11-06  2:32   ` [PATCH 01/17] ARM: MM: use 64bytes of L1 cache on plat S5PC1xx Harald Welte
2009-11-06  2:32     ` Harald Welte
2009-11-08 23:58   ` Ben Dooks
2009-11-08 23:58     ` Ben Dooks
2009-11-09  2:41     ` Kyungmin Park
2009-11-09  2:41       ` Kyungmin Park
2009-11-09  0:05 ` [PATCH] Update Samsung S5PC100 SoC support Ben Dooks
2009-11-09  0:05   ` Ben Dooks
  -- strict thread matches above, loose matches on Subject: below --
2009-10-13  7:56 Marek Szyprowski
2009-10-13  7:56 ` [PATCH 01/17] ARM: MM: use 64bytes of L1 cache on plat S5PC1xx Marek Szyprowski
2009-10-13  7:56   ` [PATCH 02/17] ARM: S5PC1XX: registers rename Marek Szyprowski
2009-10-13  7:56     ` [PATCH 03/17] ARM: S5PC1XX: clock " Marek Szyprowski
2009-10-13  7:56       ` [PATCH 04/17] ARM: S5PC1XX: clocks reimplementation Marek Szyprowski
2009-10-13  7:57         ` [PATCH 05/17] ARM: S5PC1XX: add GPIO L banks to register definition Marek Szyprowski
2009-10-13  7:57           ` [PATCH 06/17] ARM: S5PC1XX: GPIO registers rename Marek Szyprowski
2009-10-13  7:57             ` [PATCH 07/17] ARM: S5PC1xx: add gpiolib and external/gpio interrupt support Marek Szyprowski
2009-10-13  7:57               ` [PATCH 08/17] ARM: S5PC1XX: add cpu idle and system reset support Marek Szyprowski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.