]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-linus/samsung4' of git://git.fluff.org/bjdooks/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 19 May 2010 18:49:33 +0000 (11:49 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 19 May 2010 18:49:33 +0000 (11:49 -0700)
* 'for-linus/samsung4' of git://git.fluff.org/bjdooks/linux: (98 commits)
  Input: s3c24xx_ts - depend on SAMSUNG_DEV_TS and update menu entry
  Input: s3c24xx_ts - Add FEAT for Samsung touchscreen support
  Input: s3c24xx_ts - Implement generic GPIO configuration callback
  ARM: SAMSUNG: Move s3c64xx dev-ts.c to plat-samsung and rename configuration
  ARM: SAMSUNG: Implements cfg_gpio function for Samsung touchscreen
  ARM: S3C64XX: Add touchscreen platform device definition
  ARM: SAMSUNG: Move mach/ts.h to plat/ts.h
  ARM: S5PC100: Move i2c helpers from plat-s5pc1xx to mach-s5pc100
  ARM: S5PC100: Move frame buffer helpers from plat-s5pc1xx to mach-s5pc100
  ARM: S5PC100: gpio.h cleanup
  ARM: S5PC100: Move gpio support from plat-s5pc1xx to mach-s5pc100
  ARM: S5PC100: Use common functions for gpiolib implementation
  drivers: serial: S5PC100 serial driver cleanup
  ARM: S5PC100: Pre-requisite clock patch for plat-s5pc1xx to plat-s5p move
  ARM: SAMSUNG: Copy common I2C0 device helpers to machine directories
  ARM: SAMSUNG: move driver strength gpio configuration helper to common dir
  ARM: S5PV210: Add GPIOlib support
  ARM: SAMSUNGy: fix broken timer irq base
  ARM: SMDK6440: Add audio devices on board
  ARM: S5P6440: Add audio platform devices
  ...

124 files changed:
arch/arm/Makefile
arch/arm/mach-s3c2410/Kconfig
arch/arm/mach-s3c2410/Makefile.boot
arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
arch/arm/mach-s3c2410/include/mach/gpio-track.h
arch/arm/mach-s3c2410/include/mach/gpio.h
arch/arm/mach-s3c2410/include/mach/irqs.h
arch/arm/mach-s3c2410/include/mach/map.h
arch/arm/mach-s3c2410/include/mach/regs-gpio.h
arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
arch/arm/mach-s3c2410/mach-bast.c
arch/arm/mach-s3c2410/mach-h1940.c
arch/arm/mach-s3c2410/mach-n30.c
arch/arm/mach-s3c2410/pm.c
arch/arm/mach-s3c2412/gpio.c
arch/arm/mach-s3c2412/mach-jive.c
arch/arm/mach-s3c2412/mach-smdk2413.c
arch/arm/mach-s3c2416/Kconfig
arch/arm/mach-s3c2416/mach-smdk2416.c
arch/arm/mach-s3c2416/s3c2416.c
arch/arm/mach-s3c2440/Kconfig
arch/arm/mach-s3c2440/Makefile
arch/arm/mach-s3c2440/mach-rx1950.c [new file with mode: 0644]
arch/arm/mach-s3c2440/mach-rx3715.c
arch/arm/mach-s3c2440/mach-smdk2440.c
arch/arm/mach-s3c2443/mach-smdk2443.c
arch/arm/mach-s3c64xx/Kconfig
arch/arm/mach-s3c64xx/Makefile
arch/arm/mach-s3c64xx/clock.c
arch/arm/mach-s3c64xx/dma.c
arch/arm/mach-s3c64xx/include/mach/map.h
arch/arm/mach-s3c64xx/include/mach/regs-clock.h
arch/arm/mach-s3c64xx/mach-smdk6400.c
arch/arm/mach-s3c64xx/mach-smdk6410.c
arch/arm/mach-s3c64xx/s3c6410.c
arch/arm/mach-s5p6440/Kconfig
arch/arm/mach-s5p6440/Makefile
arch/arm/mach-s5p6440/clock.c
arch/arm/mach-s5p6440/cpu.c
arch/arm/mach-s5p6440/dev-audio.c [new file with mode: 0644]
arch/arm/mach-s5p6440/dma.c [new file with mode: 0644]
arch/arm/mach-s5p6440/include/mach/dma.h [new file with mode: 0644]
arch/arm/mach-s5p6440/include/mach/map.h
arch/arm/mach-s5p6440/include/mach/pwm-clock.h
arch/arm/mach-s5p6440/mach-smdk6440.c
arch/arm/mach-s5p6440/setup-i2c0.c [moved from arch/arm/plat-s5p/setup-i2c0.c with 92% similarity]
arch/arm/mach-s5p6442/Kconfig
arch/arm/mach-s5p6442/Makefile
arch/arm/mach-s5p6442/cpu.c
arch/arm/mach-s5p6442/dev-audio.c [new file with mode: 0644]
arch/arm/mach-s5p6442/dma.c [new file with mode: 0644]
arch/arm/mach-s5p6442/include/mach/dma.h [new file with mode: 0644]
arch/arm/mach-s5p6442/include/mach/map.h
arch/arm/mach-s5p6442/include/mach/pwm-clock.h
arch/arm/mach-s5p6442/mach-smdk6442.c
arch/arm/mach-s5p6442/setup-i2c0.c [new file with mode: 0644]
arch/arm/mach-s5pc100/Kconfig
arch/arm/mach-s5pc100/Makefile
arch/arm/mach-s5pc100/clock.c [new file with mode: 0644]
arch/arm/mach-s5pc100/gpiolib.c [moved from arch/arm/plat-s5pc1xx/gpiolib.c with 78% similarity]
arch/arm/mach-s5pc100/include/mach/gpio.h
arch/arm/mach-s5pc100/include/mach/regs-clock.h [new file with mode: 0644]
arch/arm/mach-s5pc100/include/mach/regs-gpio.h [moved from arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h with 94% similarity]
arch/arm/mach-s5pc100/mach-smdkc100.c
arch/arm/mach-s5pc100/setup-fb-24bpp.c [moved from arch/arm/plat-s5pc1xx/setup-fb-24bpp.c with 89% similarity]
arch/arm/mach-s5pc100/setup-i2c0.c [moved from arch/arm/plat-s5pc1xx/setup-i2c0.c with 89% similarity]
arch/arm/mach-s5pc100/setup-i2c1.c [moved from arch/arm/plat-s5pc1xx/setup-i2c1.c with 89% similarity]
arch/arm/mach-s5pv210/Kconfig
arch/arm/mach-s5pv210/Makefile
arch/arm/mach-s5pv210/clock.c
arch/arm/mach-s5pv210/cpu.c
arch/arm/mach-s5pv210/dev-audio.c [new file with mode: 0644]
arch/arm/mach-s5pv210/dma.c [new file with mode: 0644]
arch/arm/mach-s5pv210/gpiolib.c [new file with mode: 0644]
arch/arm/mach-s5pv210/include/mach/dma.h [new file with mode: 0644]
arch/arm/mach-s5pv210/include/mach/gpio.h
arch/arm/mach-s5pv210/include/mach/map.h
arch/arm/mach-s5pv210/include/mach/pwm-clock.h
arch/arm/mach-s5pv210/mach-smdkc110.c
arch/arm/mach-s5pv210/mach-smdkv210.c
arch/arm/mach-s5pv210/setup-i2c0.c [new file with mode: 0644]
arch/arm/mm/mmu.c
arch/arm/plat-s3c24xx/Kconfig
arch/arm/plat-s3c24xx/Makefile
arch/arm/plat-s3c24xx/devs.c
arch/arm/plat-s3c24xx/dma.c
arch/arm/plat-s3c24xx/gpio.c
arch/arm/plat-s3c24xx/setup-ts.c [new file with mode: 0644]
arch/arm/plat-s5p/Kconfig
arch/arm/plat-s5p/Makefile
arch/arm/plat-s5p/clock.c
arch/arm/plat-s5p/include/plat/irqs.h
arch/arm/plat-s5p/include/plat/pll.h
arch/arm/plat-s5p/include/plat/s5p-clock.h
arch/arm/plat-s5pc1xx/Kconfig
arch/arm/plat-s5pc1xx/Makefile
arch/arm/plat-s5pc1xx/gpio-config.c [deleted file]
arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h [deleted file]
arch/arm/plat-samsung/Kconfig
arch/arm/plat-samsung/Makefile
arch/arm/plat-samsung/dev-adc.c [moved from arch/arm/mach-s3c64xx/dev-adc.c with 86% similarity]
arch/arm/plat-samsung/dev-fb.c
arch/arm/plat-samsung/dev-hwmon.c [new file with mode: 0644]
arch/arm/plat-samsung/dev-rtc.c [moved from arch/arm/mach-s3c64xx/dev-rtc.c with 58% similarity]
arch/arm/plat-samsung/dev-ts.c [new file with mode: 0644]
arch/arm/plat-samsung/gpio-config.c
arch/arm/plat-samsung/gpio.c
arch/arm/plat-samsung/include/plat/clock.h
arch/arm/plat-samsung/include/plat/cpu.h
arch/arm/plat-samsung/include/plat/devs.h
arch/arm/plat-samsung/include/plat/dma.h
arch/arm/plat-samsung/include/plat/fb.h
arch/arm/plat-samsung/include/plat/gpio-cfg.h
arch/arm/plat-samsung/include/plat/gpio-core.h
arch/arm/plat-samsung/include/plat/hwmon.h
arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/ts.h [moved from arch/arm/mach-s3c2410/include/mach/ts.h with 72% similarity]
arch/arm/plat-samsung/pm-gpio.c
arch/arm/plat-samsung/s3c-pl330.c [new file with mode: 0644]
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/s3c2410_ts.c
drivers/serial/Kconfig
drivers/serial/Makefile

index d5af3b0243008a14d902fc7bb9ba11f5c2ace271..4b857fbe4314d028c9a457ab69a2f3f1295e9fe7 100644 (file)
@@ -110,6 +110,8 @@ CHECKFLAGS  += -D__arm__
 head-y         := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
 textofs-y      := 0x00008000
 textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000
+# We don't want the htc bootloader to corrupt kernel during resume
+textofs-$(CONFIG_PM_H1940)      := 0x00108000
 # SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory
 ifeq ($(CONFIG_ARCH_SA1100),y)
 textofs-$(CONFIG_SA1111) := 0x00208000
index 9e5e96f12d86501af095bd94571c57642c1be088..7245a55795dc70b004f24eca918d7d52b4fa0e19 100644 (file)
@@ -77,6 +77,7 @@ config ARCH_H1940
        select PM_H1940 if PM
        select S3C_DEV_USB_HOST
        select S3C_DEV_NAND
+       select S3C2410_SETUP_TS
        help
          Say Y here if you are using the HP IPAQ H1940
 
@@ -96,12 +97,19 @@ config PM_H1940
 config MACH_N30
        bool "Acer N30 family"
        select CPU_S3C2410
+       select MACH_N35
        select S3C_DEV_USB_HOST
        select S3C_DEV_NAND
        help
          Say Y here if you want suppt for the Acer N30, Acer N35,
          Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs.
 
+config MACH_N35
+       bool
+       help
+         Internal node in order to enable support for Acer N35 if Acer N30 is
+         selected.
+
 config ARCH_BAST
        bool "Simtec Electronics BAST (EB2410ITX)"
        select CPU_S3C2410
@@ -111,6 +119,7 @@ config ARCH_BAST
        select MACH_BAST_IDE
        select S3C24XX_DCLK
        select ISA
+       select S3C_DEV_HWMON
        select S3C_DEV_USB_HOST
        select S3C_DEV_NAND
        help
index 7dab2a0325b5cee09bea68f59c16db5c83ca3af5..58c1dd7f8e1dbe47afc9a1bb9411780c0f72076a 100644 (file)
@@ -1,3 +1,7 @@
-   zreladdr-y  := 0x30008000
-params_phys-y  := 0x30000100
-
+ifeq ($(CONFIG_PM_H1940),y)
+       zreladdr-y              := 0x30108000
+       params_phys-y   := 0x30100100
+else
+       zreladdr-y              := 0x30008000
+       params_phys-y   := 0x30000100
+endif
index f3182ff847cbcbd53374229dbf071c84b00215e1..4f7bf3272e8730fa6d108870edce120abe49c17e 100644 (file)
 
 #define S3C2410_GPIONO(bank,offset) ((bank) + (offset))
 
-#define S3C2410_GPIO_BANKA   (32*0)
-#define S3C2410_GPIO_BANKB   (32*1)
-#define S3C2410_GPIO_BANKC   (32*2)
-#define S3C2410_GPIO_BANKD   (32*3)
-#define S3C2410_GPIO_BANKE   (32*4)
-#define S3C2410_GPIO_BANKF   (32*5)
 #define S3C2410_GPIO_BANKG   (32*6)
 #define S3C2410_GPIO_BANKH   (32*7)
 
+/* GPIO sizes for various SoCs:
+ *
+ *             2442
+ *   2410 2412 2440 2443 2416
+ *   ---- ---- ---- ---- ----
+ * A 23   22   25   16   25
+ * B 11   11   11   11   9
+ * C 16   15   16   16   16
+ * D 16   16   16   16   16
+ * E 16   16   16   16   16
+ * F 8    8    8    8    8
+ * G 16   16   16   16   8
+ * H 11   11   9    15   15
+ * J --   --   13   16   --
+ * K --   --   --   --   16
+ * L --   --   --   15   7
+ * M --   --   --   2    2
+ */
+
 /* GPIO bank sizes */
 #define S3C2410_GPIO_A_NR      (32)
 #define S3C2410_GPIO_B_NR      (32)
index acb2591038087d7b98094bdb65bf95415a8e728a..d67819dde42a11cba9ab5bb6c1abb89ae14f189d 100644 (file)
@@ -23,11 +23,11 @@ static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin)
 {
        struct s3c_gpio_chip *chip;
 
-       if (pin > S3C2410_GPG(10))
+       if (pin > S3C_GPIO_END)
                return NULL;
 
        chip = &s3c24xx_gpios[pin/32];
-       return (S3C2410_GPIO_OFFSET(pin) < chip->chip.ngpio) ? chip : NULL;
+       return ((pin - chip->chip.base) < chip->chip.ngpio) ? chip : NULL;
 }
 
 #endif /* __ASM_ARCH_GPIO_CORE_H */
index 15f0b3e7ce699a373d75ca50a4ed52cef9d1b95e..b649bf2ccd5c50582fdd02ba00044862cfe917ae 100644 (file)
  * devices that need GPIO.
  */
 
+#ifdef CONFIG_CPU_S3C244X
+#define ARCH_NR_GPIOS  (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA)
+#else
 #define ARCH_NR_GPIOS  (256 + CONFIG_S3C24XX_GPIO_EXTRA)
+#endif
 
 #include <asm-generic/gpio.h>
 #include <mach/gpio-nrs.h>
 #include <mach/gpio-fns.h>
 
+#ifdef CONFIG_CPU_S3C24XX
+#define S3C_GPIO_END   (S3C2410_GPIO_BANKJ + 32)
+#else
 #define S3C_GPIO_END   (S3C2410_GPIO_BANKH + 32)
+#endif
index 877c15e1b154c1bb48de5ec6eac8dcc75e5f1877..11bb0f08fe6a8e010d50eed0f9e64732fbc9990b 100644 (file)
 #define IRQ_S3CUART_TX3                IRQ_S3C2443_TX3
 #define IRQ_S3CUART_ERR3       IRQ_S3C2443_ERR3
 
+#define IRQ_LCD_VSYNC          IRQ_S3C2443_LCD3
+#define IRQ_LCD_SYSTEM         IRQ_S3C2443_LCD2
+
 #ifdef CONFIG_CPU_S3C2440
 #define IRQ_S3C244x_AC97 IRQ_S3C2440_AC97
 #else
index f07d68066d7ece26b07a86a16aa64d73ef30312b..091c98a639d9896f2234343c29fc713592026198 100644 (file)
@@ -67,6 +67,8 @@
 #define S3C2443_PA_HSMMC   (0x4A800000)
 #define S3C2416_PA_HSMMC0  (0x4AC00000)
 
+#define        S3C2443_PA_FB   (0x4C800000)
+
 /* S3C2412 memory and IO controls */
 #define S3C2412_PA_SSMC        (0x4F000000)
 #define S3C2412_VA_SSMC        S3C_ADDR_CPU(0x00000000)
 #define S3C24XX_PA_SDI      S3C2410_PA_SDI
 #define S3C24XX_PA_NAND            S3C2410_PA_NAND
 
+#define S3C_PA_FB          S3C2443_PA_FB
 #define S3C_PA_IIC          S3C2410_PA_IIC
 #define S3C_PA_UART        S3C24XX_PA_UART
 #define S3C_PA_USBHOST S3C2410_PA_USBHOST
index a6384239eddf93f3886f43263152a1ee059445e2..a0a89d4292961a1da85f3885e58e7e20abd706a3 100644 (file)
 #include <mach/gpio-nrs.h>
 
 #ifdef CONFIG_CPU_S3C2400
-#define S3C24XX_GPIO_BASE(x)  S3C2400_GPIO_BASE(x)
-#define S3C24XX_MISCCR        S3C2400_MISCCR
+#define S3C24XX_MISCCR         S3C2400_MISCCR
 #else
-#define S3C24XX_GPIO_BASE(x)  S3C2410_GPIO_BASE(x)
-#define S3C24XX_MISCCR       S3C24XX_GPIOREG2(0x80)
+#define S3C24XX_MISCCR         S3C24XX_GPIOREG2(0x80)
 #endif /* CONFIG_CPU_S3C2400 */
 
-
-/* S3C2400 doesn't have a 1:1 mapping to S3C2410 gpio base pins */
-
-#define S3C2400_BANKNUM(pin)     (((pin) & ~31) / 32)
-#define S3C2400_BASEA2B(pin)     ((((pin) & ~31) >> 2))
-#define S3C2400_BASEC2H(pin)     ((S3C2400_BANKNUM(pin) * 10) + \
-                                 (2 * (S3C2400_BANKNUM(pin)-2)))
-
-#define S3C2400_GPIO_BASE(pin)   (pin < S3C2410_GPIO_BANKC ? \
-                                 S3C2400_BASEA2B(pin)+S3C24XX_VA_GPIO : \
-                                 S3C2400_BASEC2H(pin)+S3C24XX_VA_GPIO)
-
-
-#define S3C2410_GPIO_BASE(pin)   ((((pin) & ~31) >> 1) + S3C24XX_VA_GPIO)
-#define S3C2410_GPIO_OFFSET(pin) ((pin) & 31)
-
 /* general configuration options */
 
 #define S3C2410_GPIO_LEAVE   (0xFFFFFFFF)
index d87ebe0cb6256deb702007570dc1009f7934af8a..08ab9dfb6ae64b48a71098a91166e957c0bde1c9 100644 (file)
@@ -83,8 +83,7 @@
 #define S3C2443_HCLKCON_DMA4           (1<<4)
 #define S3C2443_HCLKCON_DMA5           (1<<5)
 #define S3C2443_HCLKCON_CAMIF          (1<<8)
-#define S3C2443_HCLKCON_DISP           (1<<9)
-#define S3C2443_HCLKCON_LCDC           (1<<10)
+#define S3C2443_HCLKCON_LCDC           (1<<9)
 #define S3C2443_HCLKCON_USBH           (1<<11)
 #define S3C2443_HCLKCON_USBD           (1<<12)
 #define S3C2443_HCLKCON_HSMMC          (1<<16)
index b061ddcf306791c27256ba4cac397b0c8045148e..c1f90f6fab42c0d867ccfe25ffe7fbdee835fda8 100644 (file)
@@ -633,7 +633,7 @@ static void __init bast_map_io(void)
 
        s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks));
 
-       s3c_device_hwmon.dev.platform_data = &bast_hwmon_info;
+       s3c_hwmon_set_platdata(&bast_hwmon_info);
 
        s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
        s3c24xx_init_clocks(0);
index 9531b4c41deb17b7c6b975d173a78b0b21422d53..779b45b3f80fdca1f6815782eef8b8dfa81b4841 100644 (file)
@@ -46,7 +46,6 @@
 #include <mach/h1940.h>
 #include <mach/h1940-latch.h>
 #include <mach/fb.h>
-#include <mach/ts.h>
 #include <plat/udc.h>
 #include <plat/iic.h>
 
@@ -57,6 +56,7 @@
 #include <plat/pll.h>
 #include <plat/pm.h>
 #include <plat/mci.h>
+#include <plat/ts.h>
 
 static struct map_desc h1940_iodesc[] __initdata = {
        [0] = {
@@ -146,6 +146,7 @@ static struct s3c2410_ts_mach_info h1940_ts_cfg __initdata = {
                .delay = 10000,
                .presc = 49,
                .oversampling_shift = 2,
+               .cfg_gpio = s3c24xx_ts_cfg_gpio,
 };
 
 /**
@@ -163,8 +164,8 @@ static struct s3c2410fb_display h1940_lcd __initdata = {
        .xres =         240,
        .yres =         320,
        .bpp =          16,
-       .left_margin =  20,
-       .right_margin = 8,
+       .left_margin =  8,
+       .right_margin = 20,
        .hsync_len =    4,
        .upper_margin = 8,
        .lower_margin = 7,
@@ -272,7 +273,6 @@ static struct platform_device h1940_lcd_powerdev = {
 };
 
 static struct platform_device *h1940_devices[] __initdata = {
-       &s3c_device_ts,
        &s3c_device_ohci,
        &s3c_device_lcd,
        &s3c_device_wdt,
@@ -286,6 +286,8 @@ static struct platform_device *h1940_devices[] __initdata = {
        &s3c_device_timer[0],
        &h1940_backlight,
        &h1940_lcd_powerdev,
+       &s3c_device_adc,
+       &s3c_device_ts,
 };
 
 static void __init h1940_map_io(void)
@@ -339,7 +341,7 @@ static void __init h1940_init(void)
 }
 
 MACHINE_START(H1940, "IPAQ-H1940")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C2410_PA_UART,
        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
index 75a9fd37a4675d5d7bb57ccb099e84d4c33c9bc3..41f299d983eb0a06a8c9e6b64e660963b871431b 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/serial_core.h>
 #include <linux/timer.h>
 #include <linux/io.h>
+#include <linux/mmc/host.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -46,6 +47,7 @@
 #include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
+#include <plat/mci.h>
 #include <plat/s3c2410.h>
 #include <plat/udc.h>
 
@@ -172,8 +174,10 @@ static struct gpio_keys_button n35_buttons[] = {
        {
                .gpio           = S3C2410_GPF(0),
                .code           = KEY_POWER,
+               .type           = EV_PWR,
                .desc           = "Power",
                .active_low     = 0,
+               .wakeup         = 1,
        },
        {
                .gpio           = S3C2410_GPG(9),
@@ -264,6 +268,14 @@ static struct s3c24xx_led_platdata n30_blue_led_pdata = {
        .def_trigger    = "",
 };
 
+/* This is the blue LED on the device. Originaly used to indicate GPS activity
+ * by flashing. */
+static struct s3c24xx_led_platdata n35_blue_led_pdata = {
+       .name           = "blue_led",
+       .gpio           = S3C2410_GPD(8),
+       .def_trigger    = "",
+};
+
 /* This LED is driven by the battery microcontroller, and is blinking
  * red, blinking green or solid green when the battery is low,
  * charging or full respectively.  By driving GPD9 low, it's possible
@@ -275,6 +287,13 @@ static struct s3c24xx_led_platdata n30_warning_led_pdata = {
        .def_trigger    = "",
 };
 
+static struct s3c24xx_led_platdata n35_warning_led_pdata = {
+       .name           = "warning_led",
+       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+       .gpio           = S3C2410_GPD(9),
+       .def_trigger    = "",
+};
+
 static struct platform_device n30_blue_led = {
        .name           = "s3c24xx_led",
        .id             = 1,
@@ -283,6 +302,14 @@ static struct platform_device n30_blue_led = {
        },
 };
 
+static struct platform_device n35_blue_led = {
+       .name           = "s3c24xx_led",
+       .id             = 1,
+       .dev            = {
+               .platform_data  = &n35_blue_led_pdata,
+       },
+};
+
 static struct platform_device n30_warning_led = {
        .name           = "s3c24xx_led",
        .id             = 2,
@@ -291,6 +318,14 @@ static struct platform_device n30_warning_led = {
        },
 };
 
+static struct platform_device n35_warning_led = {
+       .name           = "s3c24xx_led",
+       .id             = 2,
+       .dev            = {
+               .platform_data  = &n35_warning_led_pdata,
+       },
+};
+
 static struct s3c2410fb_display n30_display __initdata = {
        .type           = S3C2410_LCDCON1_TFT,
        .width          = 240,
@@ -317,13 +352,36 @@ static struct s3c2410fb_mach_info n30_fb_info __initdata = {
        .lpcsel         = 0x06,
 };
 
+static void n30_sdi_set_power(unsigned char power_mode, unsigned short vdd)
+{
+       switch (power_mode) {
+       case MMC_POWER_ON:
+       case MMC_POWER_UP:
+               gpio_set_value(S3C2410_GPG(4), 1);
+               break;
+       case MMC_POWER_OFF:
+       default:
+               gpio_set_value(S3C2410_GPG(4), 0);
+               break;
+       }
+}
+
+static struct s3c24xx_mci_pdata n30_mci_cfg __initdata = {
+       .gpio_detect    = S3C2410_GPF(1),
+       .gpio_wprotect  = S3C2410_GPG(10),
+       .ocr_avail      = MMC_VDD_32_33,
+       .set_power      = n30_sdi_set_power,
+};
+
 static struct platform_device *n30_devices[] __initdata = {
        &s3c_device_lcd,
        &s3c_device_wdt,
        &s3c_device_i2c0,
        &s3c_device_iis,
        &s3c_device_ohci,
+       &s3c_device_rtc,
        &s3c_device_usbgadget,
+       &s3c_device_sdi,
        &n30_button_device,
        &n30_blue_led,
        &n30_warning_led,
@@ -334,8 +392,12 @@ static struct platform_device *n35_devices[] __initdata = {
        &s3c_device_wdt,
        &s3c_device_i2c0,
        &s3c_device_iis,
+       &s3c_device_rtc,
        &s3c_device_usbgadget,
+       &s3c_device_sdi,
        &n35_button_device,
+       &n35_blue_led,
+       &n35_warning_led,
 };
 
 static struct s3c2410_platform_i2c __initdata n30_i2ccfg = {
@@ -490,17 +552,15 @@ static void __init n30_map_io(void)
        s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
 }
 
-static void __init n30_init_irq(void)
-{
-       s3c24xx_init_irq();
-}
-
 /* GPB3 is the line that controls the pull-up for the USB D+ line */
 
 static void __init n30_init(void)
 {
+       WARN_ON(gpio_request(S3C2410_GPG(4), "mmc power"));
+
        s3c24xx_fb_set_platdata(&n30_fb_info);
        s3c24xx_udc_set_platdata(&n30_udc_cfg);
+       s3c24xx_mci_set_platdata(&n30_mci_cfg);
        s3c_i2c0_set_platdata(&n30_i2ccfg);
 
        /* Turn off suspend on both USB ports, and switch the
@@ -532,7 +592,7 @@ static void __init n30_init(void)
                s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
                                      S3C2410_MISCCR_USBSUSPND0 |
                                      S3C2410_MISCCR_USBSUSPND1,
-                                     S3C2410_MISCCR_USBSUSPND1);
+                                     S3C2410_MISCCR_USBSUSPND0);
 
                platform_add_devices(n35_devices, ARRAY_SIZE(n35_devices));
        }
@@ -550,7 +610,7 @@ MACHINE_START(N30, "Acer-N30")
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
        .timer          = &s3c24xx_timer,
        .init_machine   = n30_init,
-       .init_irq       = n30_init_irq,
+       .init_irq       = s3c24xx_init_irq,
        .map_io         = n30_map_io,
 MACHINE_END
 
@@ -562,6 +622,6 @@ MACHINE_START(N35, "Acer-N35")
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
        .timer          = &s3c24xx_timer,
        .init_machine   = n30_init,
-       .init_irq       = n30_init_irq,
+       .init_irq       = s3c24xx_init_irq,
        .map_io         = n30_map_io,
 MACHINE_END
index 966119c8efee1316dcc383ca0461eebada857991..725636fc4dc3a892a9a89d72d03c8804eb9ba283 100644 (file)
@@ -60,10 +60,10 @@ static void s3c2410_pm_prepare(void)
                __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
        }
 
-       /* the RX3715 uses similar code and the same H1940 and the
+       /* RX3715 and RX1950 use similar to H1940 code and the
         * same offsets for resume and checksum pointers */
 
-       if (machine_is_rx3715()) {
+       if (machine_is_rx3715() || machine_is_rx1950()) {
                void *base = phys_to_virt(H1940_SUSPEND_CHECK);
                unsigned long ptr;
                unsigned long calc = 0;
@@ -79,6 +79,17 @@ static void s3c2410_pm_prepare(void)
        if ( machine_is_aml_m5900() )
                s3c2410_gpio_setpin(S3C2410_GPF(2), 1);
 
+       if (machine_is_rx1950()) {
+               /* According to S3C2442 user's manual, page 7-17,
+                * when the system is operating in NAND boot mode,
+                * the hardware pin configuration - EINT[23:21] â€“
+                * must be set as input for starting up after
+                * wakeup from sleep mode
+                */
+               s3c_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_INPUT);
+               s3c_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPIO_INPUT);
+               s3c_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPIO_INPUT);
+       }
 }
 
 static int s3c2410_pm_resume(struct sys_device *dev)
index f7afece7fc38b1f304566ee0e0083b7055a999dd..3404a876b33ea86087eee067d05e1f1d6209adce 100644 (file)
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
+#include <linux/gpio.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
 #include <mach/regs-gpio.h>
-
 #include <mach/hardware.h>
 
+#include <plat/gpio-core.h>
+
 int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state)
 {
-       void __iomem *base = S3C24XX_GPIO_BASE(pin);
-       unsigned long offs = S3C2410_GPIO_OFFSET(pin);
+       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+       unsigned long offs = pin - chip->chip.base;
        unsigned long flags;
        unsigned long slpcon;
 
        offs *= 2;
 
-       if (pin < S3C2410_GPIO_BANKB)
+       if (pin < S3C2410_GPB(0))
                return -EINVAL;
 
-       if (pin >= S3C2410_GPIO_BANKF &&
-           pin <= S3C2410_GPIO_BANKG)
+       if (pin >= S3C2410_GPF(0) &&
+           pin <= S3C2410_GPG(16))
                return -EINVAL;
 
-       if (pin > (S3C2410_GPIO_BANKH + 32))
+       if (pin > S3C2410_GPH(16))
                return -EINVAL;
 
        local_irq_save(flags);
 
-       slpcon = __raw_readl(base + 0x0C);
+       slpcon = __raw_readl(chip->base + 0x0C);
 
        slpcon &= ~(3 << offs);
        slpcon |= state << offs;
 
-       __raw_writel(slpcon, base + 0x0C);
+       __raw_writel(slpcon, chip->base + 0x0C);
 
        local_irq_restore(flags);
 
index 43160183571a59bb8d8d5b1ecb2771f81ce39637..478f4b4606c2bd024c4209a4f59cc8c301542b46 100644 (file)
@@ -674,7 +674,7 @@ static void __init jive_machine_init(void)
 }
 
 MACHINE_START(JIVE, "JIVE")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C2410_PA_UART,
        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
index faddb36ed23b5b33fdd82a92004ab0b32739de0c..ba93a356a83998a2b6e0ab2dfc83be7945321345 100644 (file)
@@ -150,7 +150,7 @@ static void __init smdk2413_machine_init(void)
 }
 
 MACHINE_START(S3C2413, "S3C2413")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C2410_PA_UART,
        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
@@ -163,7 +163,7 @@ MACHINE_START(S3C2413, "S3C2413")
 MACHINE_END
 
 MACHINE_START(SMDK2412, "SMDK2412")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C2410_PA_UART,
        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
@@ -176,7 +176,7 @@ MACHINE_START(SMDK2412, "SMDK2412")
 MACHINE_END
 
 MACHINE_START(SMDK2413, "SMDK2413")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C2410_PA_UART,
        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
index 29103a6047dee8d830a352c015fea2378fa2a57f..657e4fe17f399cb038b8528966822b6f029fbb6e 100644 (file)
@@ -30,6 +30,7 @@ menu "S3C2416 Machines"
 config MACH_SMDK2416
        bool "SMDK2416"
        select CPU_S3C2416
+       select S3C_DEV_FB
        select S3C_DEV_HSMMC
        select S3C_DEV_HSMMC1
        help
index 99d24c44f30f1f65693c56572865570473edf1ae..5fc3f67ef265006d271d9a185d5fd6a9b5c09fbd 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/io.h>
 #include <linux/mtd/partitions.h>
 #include <linux/gpio.h>
+#include <linux/fb.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <mach/regs-lcd.h>
 
 #include <mach/idle.h>
-#include <mach/fb.h>
 #include <mach/leds-gpio.h>
 #include <plat/iic.h>
 
 #include <plat/s3c2416.h>
+#include <plat/gpio-cfg.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/nand.h>
 
+#include <plat/regs-fb-v4.h>
+#include <plat/fb.h>
+
 #include <plat/common-smdk.h>
 
 static struct map_desc smdk2416_iodesc[] __initdata = {
@@ -109,7 +113,54 @@ static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = {
        }
 };
 
+struct s3c_fb_pd_win smdk2416_fb_win[] = {
+       [0] = {
+               /* think this is the same as the smdk6410 */
+               .win_mode       = {
+                       .pixclock       = 41094,
+                       .left_margin    = 8,
+                       .right_margin   = 13,
+                       .upper_margin   = 7,
+                       .lower_margin   = 5,
+                       .hsync_len      = 3,
+                       .vsync_len      = 1,
+                       .xres           = 800,
+                       .yres           = 480,
+               },
+               .default_bpp    = 16,
+               .max_bpp        = 32,
+       },
+};
+
+static void s3c2416_fb_gpio_setup_24bpp(void)
+{
+       unsigned int gpio;
+
+       for (gpio = S3C2410_GPC(1); gpio <= S3C2410_GPC(4); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+       }
+
+       for (gpio = S3C2410_GPC(8); gpio <= S3C2410_GPC(15); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+       }
+
+       for (gpio = S3C2410_GPD(0); gpio <= S3C2410_GPD(15); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+       }
+}
+
+static struct s3c_fb_platdata smdk2416_fb_platdata = {
+       .win[0]         = &smdk2416_fb_win[0],
+       .setup_gpio     = s3c2416_fb_gpio_setup_24bpp,
+       .vidcon0        = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+       .vidcon1        = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
 static struct platform_device *smdk2416_devices[] __initdata = {
+       &s3c_device_fb,
        &s3c_device_wdt,
        &s3c_device_ohci,
        &s3c_device_i2c0,
@@ -119,20 +170,25 @@ static struct platform_device *smdk2416_devices[] __initdata = {
 
 static void __init smdk2416_map_io(void)
 {
-
        s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc));
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs));
-
 }
 
 static void __init smdk2416_machine_init(void)
 {
        s3c_i2c0_set_platdata(NULL);
+       s3c_fb_set_platdata(&smdk2416_fb_platdata);
 
        gpio_request(S3C2410_GPB(4), "USBHost Power");
        gpio_direction_output(S3C2410_GPB(4), 1);
 
+       gpio_request(S3C2410_GPB(3), "Display Power");
+       gpio_direction_output(S3C2410_GPB(3), 1);
+
+       gpio_request(S3C2410_GPB(1), "Display Reset");
+       gpio_direction_output(S3C2410_GPB(1), 1);
+
        platform_add_devices(smdk2416_devices, ARRAY_SIZE(smdk2416_devices));
        smdk_machine_init();
 }
index 3bff05745d0b91463090a1dbf1524802ff38c7f5..35dabccd0ac232afbf101306ea3768cdb428b86c 100644 (file)
@@ -90,6 +90,8 @@ int __init s3c2416_init(void)
        s3c_i2c0_setname("s3c2440-i2c");
        s3c_i2c1_setname("s3c2440-i2c");
 
+       s3c_device_fb.name = "s3c2443-fb";
+
        return sysdev_register(&s3c2416_sysdev);
 }
 
index 9d102b9120913d9a6c3210b1c0542c18b6a3282b..cd8e7de388f0c32b5828d268894b512aa53f45f6 100644 (file)
@@ -188,4 +188,17 @@ config MACH_MINI2440
          Say Y here to select support for the MINI2440. Is a 10cm x 10cm board
          available via various sources. It can come with a 3.5" or 7" touch LCD.
 
+config MACH_RX1950
+       bool "HP iPAQ rx1950"
+       select CPU_S3C2442
+       select S3C24XX_DCLK
+       select PM_H1940 if PM
+       select I2C
+       select S3C2410_PWM
+       select S3C_DEV_NAND
+       select S3C2410_IOTIMING if S3C2440_CPUFREQ
+       select S3C2440_XTAL_16934400
+       help
+          Say Y here if you're using HP iPAQ rx1950
+
 endmenu
index c85ba32d8956da05f1af89d0869038323c038829..d5440fa34b045cb8a9e2b0d5ec75cb913ea21a0f 100644 (file)
@@ -34,6 +34,7 @@ obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
 obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o
 obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o
 obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o
+obj-$(CONFIG_MACH_RX1950) += mach-rx1950.o
 
 # extra machine support
 
diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c
new file mode 100644 (file)
index 0000000..8603b57
--- /dev/null
@@ -0,0 +1,582 @@
+/* linux/arch/arm/mach-s3c2440/mach-rx1950.c
+ *
+ * Copyright (c) 2006-2009 Victor Chukhantsev, Denis Grigoriev,
+ * Copyright (c) 2007-2010 Vasily Khoruzhick
+ *
+ * based on smdk2440 written by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/sysdev.h>
+#include <linux/pwm_backlight.h>
+#include <linux/pwm.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <linux/mmc/host.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-gpioj.h>
+#include <mach/h1940.h>
+#include <mach/fb.h>
+
+#include <plat/clock.h>
+#include <plat/regs-serial.h>
+#include <plat/regs-iic.h>
+#include <plat/mci.h>
+#include <plat/udc.h>
+#include <plat/nand.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+#include <plat/ts.h>
+
+#define LCD_PWM_PERIOD 192960
+#define LCD_PWM_DUTY 127353
+
+static struct map_desc rx1950_iodesc[] __initdata = {
+};
+
+static struct s3c24xx_uart_clksrc rx1950_serial_clocks[] = {
+       [0] = {
+              .name = "fclk",
+              .divisor = 0x0a,
+              .min_baud = 0,
+              .max_baud = 0,
+       },
+};
+
+static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
+       [0] = {
+              .hwport = 0,
+              .flags = 0,
+              .ucon = 0x3c5,
+              .ulcon = 0x03,
+              .ufcon = 0x51,
+              .clocks = rx1950_serial_clocks,
+              .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
+       },
+       [1] = {
+              .hwport = 1,
+              .flags = 0,
+              .ucon = 0x3c5,
+              .ulcon = 0x03,
+              .ufcon = 0x51,
+              .clocks = rx1950_serial_clocks,
+              .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
+       },
+       /* IR port */
+       [2] = {
+              .hwport = 2,
+              .flags = 0,
+              .ucon = 0x3c5,
+              .ulcon = 0x43,
+              .ufcon = 0xf1,
+              .clocks = rx1950_serial_clocks,
+              .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
+       },
+};
+
+static struct s3c2410fb_display rx1950_display = {
+       .type = S3C2410_LCDCON1_TFT,
+       .width = 240,
+       .height = 320,
+       .xres = 240,
+       .yres = 320,
+       .bpp = 16,
+
+       .pixclock = 260000,
+       .left_margin = 10,
+       .right_margin = 20,
+       .hsync_len = 10,
+       .upper_margin = 2,
+       .lower_margin = 2,
+       .vsync_len = 2,
+
+       .lcdcon5 = S3C2410_LCDCON5_FRM565 |
+                          S3C2410_LCDCON5_INVVCLK |
+                          S3C2410_LCDCON5_INVVLINE |
+                          S3C2410_LCDCON5_INVVFRAME |
+                          S3C2410_LCDCON5_HWSWP |
+                          (0x02 << 13) |
+                          (0x02 << 15),
+
+};
+
+static struct s3c2410fb_mach_info rx1950_lcd_cfg = {
+       .displays = &rx1950_display,
+       .num_displays = 1,
+       .default_display = 0,
+
+       .lpcsel = 0x02,
+       .gpccon = 0xaa9556a9,
+       .gpccon_mask = 0xffc003fc,
+       .gpcup = 0x0000ffff,
+       .gpcup_mask = 0xffffffff,
+
+       .gpdcon = 0xaa90aaa1,
+       .gpdcon_mask = 0xffc0fff0,
+       .gpdup = 0x0000fcfd,
+       .gpdup_mask = 0xffffffff,
+
+};
+
+static struct pwm_device *lcd_pwm;
+
+void rx1950_lcd_power(int enable)
+{
+       int i;
+       static int enabled;
+       if (enabled == enable)
+               return;
+       if (!enable) {
+
+               /* GPC11-GPC15->OUTPUT */
+               for (i = 11; i < 16; i++)
+                       gpio_direction_output(S3C2410_GPC(i), 1);
+
+               /* Wait a bit here... */
+               mdelay(100);
+
+               /* GPD2-GPD7->OUTPUT */
+               /* GPD11-GPD15->OUTPUT */
+               /* GPD2-GPD7->1, GPD11-GPD15->1 */
+               for (i = 2; i < 8; i++)
+                       gpio_direction_output(S3C2410_GPD(i), 1);
+               for (i = 11; i < 16; i++)
+                       gpio_direction_output(S3C2410_GPD(i), 1);
+
+               /* Wait a bit here...*/
+               mdelay(100);
+
+               /* GPB0->OUTPUT, GPB0->0 */
+               gpio_direction_output(S3C2410_GPB(0), 0);
+
+               /* GPC1-GPC4->OUTPUT, GPC1-4->0 */
+               for (i = 1; i < 5; i++)
+                       gpio_direction_output(S3C2410_GPC(i), 0);
+
+               /* GPC15-GPC11->0 */
+               for (i = 11; i < 16; i++)
+                       gpio_direction_output(S3C2410_GPC(i), 0);
+
+               /* GPD15-GPD11->0, GPD2->GPD7->0 */
+               for (i = 11; i < 16; i++)
+                       gpio_direction_output(S3C2410_GPD(i), 0);
+
+               for (i = 2; i < 8; i++)
+                       gpio_direction_output(S3C2410_GPD(i), 0);
+
+               /* GPC6->0, GPC7->0, GPC5->0 */
+               gpio_direction_output(S3C2410_GPC(6), 0);
+               gpio_direction_output(S3C2410_GPC(7), 0);
+               gpio_direction_output(S3C2410_GPC(5), 0);
+
+               /* GPB1->OUTPUT, GPB1->0 */
+               gpio_direction_output(S3C2410_GPB(1), 0);
+               pwm_config(lcd_pwm, 0, LCD_PWM_PERIOD);
+               pwm_disable(lcd_pwm);
+
+               /* GPC0->0, GPC10->0 */
+               gpio_direction_output(S3C2410_GPC(0), 0);
+               gpio_direction_output(S3C2410_GPC(10), 0);
+       } else {
+               pwm_config(lcd_pwm, LCD_PWM_DUTY, LCD_PWM_PERIOD);
+               pwm_enable(lcd_pwm);
+
+               gpio_direction_output(S3C2410_GPC(0), 1);
+               gpio_direction_output(S3C2410_GPC(5), 1);
+
+               s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPB1_TOUT1);
+               gpio_direction_output(S3C2410_GPC(7), 1);
+
+               for (i = 1; i < 5; i++)
+                       s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2));
+
+               for (i = 11; i < 16; i++)
+                       s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2));
+
+               for (i = 2; i < 8; i++)
+                       s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2));
+
+               for (i = 11; i < 16; i++)
+                       s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2));
+
+               gpio_direction_output(S3C2410_GPC(10), 1);
+               gpio_direction_output(S3C2410_GPC(6), 1);
+       }
+       enabled = enable;
+}
+
+static void rx1950_bl_power(int enable)
+{
+       static int enabled;
+       if (enabled == enable)
+               return;
+       if (!enable) {
+                       gpio_direction_output(S3C2410_GPB(0), 0);
+       } else {
+                       /* LED driver need a "push" to power on */
+                       gpio_direction_output(S3C2410_GPB(0), 1);
+                       /* Warm up backlight for one period of PWM.
+                        * Without this trick its almost impossible to
+                        * enable backlight with low brightness value
+                        */
+                       ndelay(48000);
+                       s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+       }
+       enabled = enable;
+}
+
+static int rx1950_backlight_init(struct device *dev)
+{
+       WARN_ON(gpio_request(S3C2410_GPB(0), "Backlight"));
+       lcd_pwm = pwm_request(1, "RX1950 LCD");
+       if (IS_ERR(lcd_pwm)) {
+               dev_err(dev, "Unable to request PWM for LCD power!\n");
+               return PTR_ERR(lcd_pwm);
+       }
+
+       rx1950_lcd_power(1);
+       rx1950_bl_power(1);
+
+       return 0;
+}
+
+static void rx1950_backlight_exit(struct device *dev)
+{
+       rx1950_bl_power(0);
+       rx1950_lcd_power(0);
+
+       pwm_free(lcd_pwm);
+       gpio_free(S3C2410_GPB(0));
+}
+
+
+static int rx1950_backlight_notify(struct device *dev, int brightness)
+{
+       if (!brightness) {
+               rx1950_bl_power(0);
+               rx1950_lcd_power(0);
+       } else {
+               rx1950_lcd_power(1);
+               rx1950_bl_power(1);
+       }
+       return brightness;
+}
+
+static struct platform_pwm_backlight_data rx1950_backlight_data = {
+       .pwm_id = 0,
+       .max_brightness = 24,
+       .dft_brightness = 4,
+       .pwm_period_ns = 48000,
+       .init = rx1950_backlight_init,
+       .notify = rx1950_backlight_notify,
+       .exit = rx1950_backlight_exit,
+};
+
+static struct platform_device rx1950_backlight = {
+       .name = "pwm-backlight",
+       .dev = {
+               .parent = &s3c_device_timer[0].dev,
+               .platform_data = &rx1950_backlight_data,
+       },
+};
+
+static void rx1950_set_mmc_power(unsigned char power_mode, unsigned short vdd)
+{
+       switch (power_mode) {
+       case MMC_POWER_OFF:
+               gpio_direction_output(S3C2410_GPJ(1), 0);
+               break;
+       case MMC_POWER_UP:
+       case MMC_POWER_ON:
+               gpio_direction_output(S3C2410_GPJ(1), 1);
+               break;
+       default:
+               break;
+       }
+}
+
+static struct s3c24xx_mci_pdata rx1950_mmc_cfg __initdata = {
+       .gpio_detect = S3C2410_GPF(5),
+       .gpio_wprotect = S3C2410_GPH(8),
+       .set_power = rx1950_set_mmc_power,
+       .ocr_avail = MMC_VDD_32_33,
+};
+
+static struct mtd_partition rx1950_nand_part[] = {
+       [0] = {
+                       .name = "Boot0",
+                       .offset = 0,
+                       .size = 0x4000,
+                       .mask_flags = MTD_WRITEABLE,
+       },
+       [1] = {
+                       .name = "Boot1",
+                       .offset = MTDPART_OFS_APPEND,
+                       .size = 0x40000,
+                       .mask_flags = MTD_WRITEABLE,
+       },
+       [2] = {
+                       .name = "Kernel",
+                       .offset = MTDPART_OFS_APPEND,
+                       .size = 0x300000,
+                       .mask_flags = 0,
+       },
+       [3] = {
+                       .name = "Filesystem",
+                       .offset = MTDPART_OFS_APPEND,
+                       .size = MTDPART_SIZ_FULL,
+                       .mask_flags = 0,
+       },
+};
+
+static struct s3c2410_nand_set rx1950_nand_sets[] = {
+       [0] = {
+                       .name = "Internal",
+                       .nr_chips = 1,
+                       .nr_partitions = ARRAY_SIZE(rx1950_nand_part),
+                       .partitions = rx1950_nand_part,
+       },
+};
+
+static struct s3c2410_platform_nand rx1950_nand_info = {
+       .tacls = 25,
+       .twrph0 = 50,
+       .twrph1 = 15,
+       .nr_sets = ARRAY_SIZE(rx1950_nand_sets),
+       .sets = rx1950_nand_sets,
+};
+
+static void rx1950_udc_pullup(enum s3c2410_udc_cmd_e cmd)
+{
+       switch (cmd) {
+       case S3C2410_UDC_P_ENABLE:
+               gpio_direction_output(S3C2410_GPJ(5), 1);
+               break;
+       case S3C2410_UDC_P_DISABLE:
+               gpio_direction_output(S3C2410_GPJ(5), 0);
+               break;
+       case S3C2410_UDC_P_RESET:
+               break;
+       default:
+               break;
+       }
+}
+
+static struct s3c2410_udc_mach_info rx1950_udc_cfg __initdata = {
+       .udc_command = rx1950_udc_pullup,
+       .vbus_pin = S3C2410_GPG(5),
+       .vbus_pin_inverted = 1,
+};
+
+static struct s3c2410_ts_mach_info rx1950_ts_cfg __initdata = {
+       .delay = 10000,
+       .presc = 49,
+       .oversampling_shift = 3,
+};
+
+static struct gpio_keys_button rx1950_gpio_keys_table[] = {
+       {
+               .code           = KEY_POWER,
+               .gpio           = S3C2410_GPF(0),
+               .active_low     = 1,
+               .desc           = "Power button",
+               .wakeup         = 1,
+       },
+       {
+               .code           = KEY_F5,
+               .gpio           = S3C2410_GPF(7),
+               .active_low     = 1,
+               .desc           = "Record button",
+       },
+       {
+               .code           = KEY_F1,
+               .gpio           = S3C2410_GPG(0),
+               .active_low     = 1,
+               .desc           = "Calendar button",
+       },
+       {
+               .code           = KEY_F2,
+               .gpio           = S3C2410_GPG(2),
+               .active_low     = 1,
+               .desc           = "Contacts button",
+       },
+       {
+               .code           = KEY_F3,
+               .gpio           = S3C2410_GPG(3),
+               .active_low     = 1,
+               .desc           = "Mail button",
+       },
+       {
+               .code           = KEY_F4,
+               .gpio           = S3C2410_GPG(7),
+               .active_low     = 1,
+               .desc           = "WLAN button",
+       },
+       {
+               .code           = KEY_LEFT,
+               .gpio           = S3C2410_GPG(10),
+               .active_low     = 1,
+               .desc           = "Left button",
+       },
+       {
+               .code           = KEY_RIGHT,
+               .gpio           = S3C2410_GPG(11),
+               .active_low     = 1,
+               .desc           = "Right button",
+       },
+       {
+               .code           = KEY_UP,
+               .gpio           = S3C2410_GPG(4),
+               .active_low     = 1,
+               .desc           = "Up button",
+       },
+       {
+               .code           = KEY_DOWN,
+               .gpio           = S3C2410_GPG(6),
+               .active_low     = 1,
+               .desc           = "Down button",
+       },
+       {
+               .code           = KEY_ENTER,
+               .gpio           = S3C2410_GPG(9),
+               .active_low     = 1,
+               .desc           = "Ok button"
+       },
+};
+
+static struct gpio_keys_platform_data rx1950_gpio_keys_data = {
+       .buttons = rx1950_gpio_keys_table,
+       .nbuttons = ARRAY_SIZE(rx1950_gpio_keys_table),
+};
+
+static struct platform_device rx1950_device_gpiokeys = {
+       .name = "gpio-keys",
+       .dev.platform_data = &rx1950_gpio_keys_data,
+};
+
+static struct s3c2410_platform_i2c rx1950_i2c_data = {
+       .flags = 0,
+       .slave_addr = 0x42,
+       .frequency = 400 * 1000,
+       .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON,
+};
+
+static struct platform_device *rx1950_devices[] __initdata = {
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_iis,
+       &s3c_device_usbgadget,
+       &s3c_device_rtc,
+       &s3c_device_nand,
+       &s3c_device_sdi,
+       &s3c_device_adc,
+       &s3c_device_ts,
+       &s3c_device_timer[0],
+       &s3c_device_timer[1],
+       &rx1950_backlight,
+       &rx1950_device_gpiokeys,
+};
+
+static struct clk *rx1950_clocks[] __initdata = {
+       &s3c24xx_clkout0,
+       &s3c24xx_clkout1,
+};
+
+static void __init rx1950_map_io(void)
+{
+       s3c24xx_clkout0.parent  = &clk_h;
+       s3c24xx_clkout1.parent  = &clk_f;
+
+       s3c24xx_register_clocks(rx1950_clocks, ARRAY_SIZE(rx1950_clocks));
+
+       s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc));
+       s3c24xx_init_clocks(16934000);
+       s3c24xx_init_uarts(rx1950_uartcfgs, ARRAY_SIZE(rx1950_uartcfgs));
+
+       /* setup PM */
+
+#ifdef CONFIG_PM_H1940
+       memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 8);
+#endif
+
+       s3c_pm_init();
+}
+
+static void __init rx1950_init_machine(void)
+{
+       int i;
+
+       s3c24xx_fb_set_platdata(&rx1950_lcd_cfg);
+       s3c24xx_udc_set_platdata(&rx1950_udc_cfg);
+       s3c24xx_ts_set_platdata(&rx1950_ts_cfg);
+       s3c24xx_mci_set_platdata(&rx1950_mmc_cfg);
+       s3c_i2c0_set_platdata(&rx1950_i2c_data);
+       s3c_nand_set_platdata(&rx1950_nand_info);
+
+       /* Turn off suspend on both USB ports, and switch the
+        * selectable USB port to USB device mode. */
+       s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+                                               S3C2410_MISCCR_USBSUSPND0 |
+                                               S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+       WARN_ON(gpio_request(S3C2410_GPJ(5), "UDC pullup"));
+       gpio_direction_output(S3C2410_GPJ(5), 0);
+
+       /* mmc power is disabled by default */
+       WARN_ON(gpio_request(S3C2410_GPJ(1), "MMC power"));
+       gpio_direction_output(S3C2410_GPJ(1), 0);
+
+       for (i = 0; i < 8; i++)
+               WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power"));
+
+       for (i = 10; i < 16; i++)
+               WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power"));
+
+       for (i = 2; i < 8; i++)
+               WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power"));
+
+       for (i = 11; i < 16; i++)
+               WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power"));
+
+       WARN_ON(gpio_request(S3C2410_GPB(1), "LCD power"));
+
+       platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices));
+}
+
+MACHINE_START(RX1950, "HP iPAQ RX1950")
+    /* Maintainers: Vasily Khoruzhick */
+    .phys_io = S3C2410_PA_UART,
+       .io_pg_offst = (((u32) S3C24XX_VA_UART) >> 18) & 0xfffc,
+       .boot_params = S3C2410_SDRAM_PA + 0x100,
+       .map_io = rx1950_map_io,
+       .init_irq = s3c24xx_init_irq,
+       .init_machine = rx1950_init_machine,
+       .timer = &s3c24xx_timer,
+MACHINE_END
index 1e836e506f8b7f50ac7d493100fb72e4ea8729e1..d2946de3f3659d3e2588cc980a727973b9716062 100644 (file)
@@ -209,7 +209,7 @@ static void __init rx3715_init_machine(void)
 }
 
 MACHINE_START(RX3715, "IPAQ-RX3715")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C2410_PA_UART,
        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
index 3ac3d636d615ee9d6c35e621c2e9c61b5624dc89..df83276d85aeba60bd582c7e5106c1380a36d890 100644 (file)
@@ -174,7 +174,7 @@ static void __init smdk2440_machine_init(void)
 }
 
 MACHINE_START(S3C2440, "SMDK2440")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C2410_PA_UART,
        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
index e2e362bda9b7e21123750435f3220c098d50fdcd..4c863d3a52f4689bd50212ea6550f33ffcda8dec 100644 (file)
@@ -131,7 +131,7 @@ static void __init smdk2443_machine_init(void)
 }
 
 MACHINE_START(SMDK2443, "SMDK2443")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C2410_PA_UART,
        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
index 959df3840de5a1be9ddd6c533c919281769b50cc..69e9fbfea9175a7e09b5e86c500a9e47ebd82d8c 100644 (file)
@@ -85,6 +85,7 @@ config MACH_ANW6410
 config MACH_SMDK6410
        bool "SMDK6410"
        select CPU_S3C6410
+       select SAMSUNG_DEV_ADC
        select S3C_DEV_HSMMC
        select S3C_DEV_HSMMC1
        select S3C_DEV_I2C1
index 3758e15086bedf11abbee9ef854f10b4ae4721bd..a10f1fc6b023441b5b7dd3960d7c45906117b773 100644 (file)
@@ -56,7 +56,6 @@ obj-$(CONFIG_MACH_HMT)                += mach-hmt.o
 # device support
 
 obj-y                          += dev-uart.o
-obj-y                          += dev-rtc.o
 obj-y                          += dev-audio.o
-obj-$(CONFIG_S3C_ADC)          += dev-adc.o
 obj-$(CONFIG_S3C64XX_DEV_SPI)  += dev-spi.o
+obj-$(CONFIG_S3C64XX_DEV_TS)   += dev-ts.o
index 2ac2e7d73e53107bc62faa0490b0400aa764fe88..7a4138beb665a1391dd5fe6137da1f584fc31107 100644 (file)
@@ -88,6 +88,12 @@ struct clk clk_48m = {
        .enable         = clk_48m_ctrl,
 };
 
+struct clk clk_xusbxti = {
+       .name           = "xusbxti",
+       .id             = -1,
+       .rate           = 48000000,
+};
+
 static int inline s3c64xx_gate(void __iomem *reg,
                                struct clk *clk,
                                int enable)
@@ -518,6 +524,11 @@ static struct clk clk_iis_cd1 = {
        .id             = -1,
 };
 
+static struct clk clk_iisv4_cd = {
+       .name           = "iis_cdclk_v4",
+       .id             = -1,
+};
+
 static struct clk clk_pcm_cd = {
        .name           = "pcm_cdclk",
        .id             = -1,
@@ -549,6 +560,19 @@ static struct clksrc_sources clkset_audio1 = {
        .nr_sources     = ARRAY_SIZE(clkset_audio1_list),
 };
 
+static struct clk *clkset_audio2_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_dout_mpll,
+       [2] = &clk_fin_epll,
+       [3] = &clk_iisv4_cd,
+       [4] = &clk_pcm_cd,
+};
+
+static struct clksrc_sources clkset_audio2 = {
+       .sources        = clkset_audio2_list,
+       .nr_sources     = ARRAY_SIZE(clkset_audio2_list),
+};
+
 static struct clk *clkset_camif_list[] = {
        &clk_h2,
 };
@@ -650,6 +674,16 @@ static struct clksrc_clk clksrcs[] = {
                .reg_src        = { .reg = S3C_CLK_SRC, .shift = 10, .size = 3  },
                .reg_div        = { .reg = S3C_CLK_DIV2, .shift = 12, .size = 4  },
                .sources        = &clkset_audio1,
+       }, {
+               .clk    = {
+                       .name           = "audio-bus",
+                       .id             = -1,  /* There's only one IISv4 port */
+                       .ctrlbit        = S3C6410_CLKCON_SCLK_AUDIO2,
+                       .enable         = s3c64xx_sclk_ctrl,
+               },
+               .reg_src        = { .reg = S3C6410_CLK_SRC2, .shift = 0, .size = 3  },
+               .reg_div        = { .reg = S3C_CLK_DIV2, .shift = 24, .size = 4  },
+               .sources        = &clkset_audio2,
        }, {
                .clk    = {
                        .name           = "irda-bus",
@@ -749,6 +783,7 @@ static struct clk *clks1[] __initdata = {
        &clk_ext_xtal_mux,
        &clk_iis_cd0,
        &clk_iis_cd1,
+       &clk_iisv4_cd,
        &clk_pcm_cd,
        &clk_mout_epll.clk,
        &clk_mout_mpll.clk,
@@ -762,6 +797,7 @@ static struct clk *clks[] __initdata = {
        &clk_27m,
        &clk_48m,
        &clk_h2,
+       &clk_xusbxti,
 };
 
 /**
index 33ccf7bf766a961d35eb71cbae7107547bcf913e..5567e037b0d15a9d890c31c7a05a57deb9baf7c7 100644 (file)
@@ -414,7 +414,7 @@ err_buff:
 EXPORT_SYMBOL(s3c2410_dma_enqueue);
 
 
-int s3c2410_dma_devconfig(int channel,
+int s3c2410_dma_devconfig(unsigned int channel,
                          enum s3c2410_dmasrc source,
                          unsigned long devaddr)
 {
index 801c1c0f3a951d812af9166fc34e4aecb9d1e476..9fdd50c8c767473fed80df430b89de0a38bf7ec3 100644 (file)
 #define S3C_PA_USBHOST         S3C64XX_PA_USBHOST
 #define S3C_PA_USB_HSOTG       S3C64XX_PA_USB_HSOTG
 #define S3C_VA_USB_HSPHY       S3C64XX_VA_USB_HSPHY
+#define S3C_PA_RTC             S3C64XX_PA_RTC
+
+#define SAMSUNG_PA_ADC         S3C64XX_PA_ADC
 
 #endif /* __ASM_ARCH_6400_MAP_H */
index 3ef62741e5d10629470549ca025c8e4feed38858..0114eb0c1fe7ca35e70b01d82945e684a03f3317 100644 (file)
@@ -33,6 +33,7 @@
 #define S3C_PCLK_GATE          S3C_CLKREG(0x34)
 #define S3C_SCLK_GATE          S3C_CLKREG(0x38)
 #define S3C_MEM0_GATE          S3C_CLKREG(0x3C)
+#define S3C6410_CLK_SRC2       S3C_CLKREG(0x10C)
 
 /* CLKDIV0 */
 #define S3C6400_CLKDIV0_PCLK_MASK      (0xf << 12)
index f7b18983950c58f33ccb5972ce6b370891316c95..59916676d8d26c2b9def21828a9386daf45e877e 100644 (file)
@@ -84,7 +84,7 @@ static void __init smdk6400_machine_init(void)
 }
 
 MACHINE_START(SMDK6400, "SMDK6400")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C_PA_UART & 0xfff00000,
        .io_pg_offst    = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C64XX_PA_SDRAM + 0x100,
index 2d5afd221d77c2530957b3368ab75abd91636fde..9d51455feb31ac2d3383aff8af77cebd20b2743f 100644 (file)
@@ -656,7 +656,7 @@ static void __init smdk6410_machine_init(void)
 }
 
 MACHINE_START(SMDK6410, "SMDK6410")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C_PA_UART & 0xfff00000,
        .io_pg_offst    = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C64XX_PA_SDRAM + 0x100,
index 59635d19466a5c31e1ae8715c4d9ae9c823fda44..3ab695c691eefe05018d91f934779e1fc01cd3f6 100644 (file)
@@ -38,6 +38,7 @@
 #include <plat/clock.h>
 #include <plat/sdhci.h>
 #include <plat/iic-core.h>
+#include <plat/adc.h>
 #include <mach/s3c6400.h>
 #include <mach/s3c6410.h>
 
@@ -52,6 +53,7 @@ void __init s3c6410_map_io(void)
        s3c_i2c0_setname("s3c2440-i2c");
        s3c_i2c1_setname("s3c2440-i2c");
 
+       s3c_device_adc.name     = "s3c64xx-adc";
        s3c_device_nand.name = "s3c6400-nand";
 }
 
index 4c29ff8b07de0fcd04782ca8f16613a2278fd433..77aeffd17330614e439524fd73d59fbfd7820996 100644 (file)
@@ -9,6 +9,7 @@ if ARCH_S5P6440
 
 config CPU_S5P6440
        bool
+       select S3C_PL330_DMA
        help
          Enable S5P6440 CPU support
 
index 1ad894b1d3ab85f22f6bfc8c166347da039fe988..44facf43d59f998e40beb1143b68f084188c65c1 100644 (file)
@@ -12,8 +12,12 @@ obj-                         :=
 
 # Core support for S5P6440 system
 
-obj-$(CONFIG_CPU_S5P6440)      += cpu.o init.o clock.o gpio.o
+obj-$(CONFIG_CPU_S5P6440)      += cpu.o init.o clock.o gpio.o dma.o
+obj-$(CONFIG_CPU_S5P6440)      += setup-i2c0.o
 
 # machine support
 
 obj-$(CONFIG_MACH_SMDK6440)    += mach-smdk6440.o
+
+# device support
+obj-y                          += dev-audio.o
index b2672e16e7aa69000c9d22e12c65307559ea318f..ca6e48dce77793b0a846a26ca5dd9a5429524c74 100644 (file)
@@ -134,24 +134,6 @@ static struct clksrc_clk clk_mout_mpll = {
        .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 1, .size = 1 },
 };
 
-static struct clk clk_h_low = {
-       .name           = "hclk_low",
-       .id             = -1,
-       .rate           = 0,
-       .parent         = NULL,
-       .ctrlbit        = 0,
-       .ops            = &clk_ops_def_setrate,
-};
-
-static struct clk clk_p_low = {
-       .name           = "pclk_low",
-       .id             = -1,
-       .rate           = 0,
-       .parent         = NULL,
-       .ctrlbit        = 0,
-       .ops            = &clk_ops_def_setrate,
-};
-
 enum perf_level {
        L0 = 532*1000,
        L1 = 266*1000,
@@ -247,23 +229,70 @@ static struct clk_ops s5p6440_clkarm_ops = {
        .round_rate     = s5p6440_armclk_round_rate,
 };
 
-static unsigned long s5p6440_clk_doutmpll_get_rate(struct clk *clk)
-{
-       unsigned long rate = clk_get_rate(clk->parent);
+static struct clksrc_clk clk_armclk = {
+       .clk    = {
+               .name   = "armclk",
+               .id     = 1,
+               .parent = &clk_mout_apll.clk,
+               .ops    = &s5p6440_clkarm_ops,
+       },
+       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 4 },
+};
 
-       if (__raw_readl(S5P_CLK_DIV0) & S5P_CLKDIV0_MPLL_MASK)
-               rate /= 2;
+static struct clksrc_clk clk_dout_mpll = {
+       .clk    = {
+               .name   = "dout_mpll",
+               .id     = -1,
+               .parent = &clk_mout_mpll.clk,
+       },
+       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 1 },
+};
 
-       return rate;
-}
+static struct clksrc_clk clk_hclk = {
+       .clk    = {
+               .name   = "clk_hclk",
+               .id     = -1,
+               .parent = &clk_armclk.clk,
+       },
+       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 4 },
+};
 
-static struct clk clk_dout_mpll = {
-       .name           = "dout_mpll",
-       .id             = -1,
-       .parent         = &clk_mout_mpll.clk,
-       .ops            = &(struct clk_ops) {
-               .get_rate       = s5p6440_clk_doutmpll_get_rate,
+static struct clksrc_clk clk_pclk = {
+       .clk    = {
+               .name   = "clk_pclk",
+               .id     = -1,
+               .parent = &clk_hclk.clk,
        },
+       .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 4 },
+};
+
+static struct clk *clkset_hclklow_list[] = {
+       &clk_mout_apll.clk,
+       &clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources clkset_hclklow = {
+       .sources        = clkset_hclklow_list,
+       .nr_sources     = ARRAY_SIZE(clkset_hclklow_list),
+};
+
+static struct clksrc_clk clk_hclk_low = {
+       .clk = {
+               .name   = "hclk_low",
+               .id     = -1,
+       },
+       .sources        = &clkset_hclklow,
+       .reg_src        = { .reg = S5P_SYS_OTHERS, .shift = 6, .size = 1 },
+       .reg_div        = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk_low = {
+       .clk    = {
+               .name   = "pclk_low",
+               .id     = -1,
+               .parent = &clk_hclk_low.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 },
 };
 
 int s5p6440_clk48m_ctrl(struct clk *clk, int enable)
@@ -307,6 +336,11 @@ static int s5p6440_sclk_ctrl(struct clk *clk, int enable)
        return s5p_gatectrl(S5P_CLK_GATE_SCLK0, clk, enable);
 }
 
+static int s5p6440_sclk1_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLK_GATE_SCLK1, clk, enable);
+}
+
 static int s5p6440_mem_ctrl(struct clk *clk, int enable)
 {
        return s5p_gatectrl(S5P_CLK_GATE_MEM0, clk, enable);
@@ -321,37 +355,37 @@ static struct clk init_clocks_disable[] = {
        {
                .name           = "nand",
                .id             = -1,
-               .parent         = &clk_h,
+               .parent         = &clk_hclk.clk,
                .enable         = s5p6440_mem_ctrl,
                .ctrlbit        = S5P_CLKCON_MEM0_HCLK_NFCON,
        }, {
                .name           = "adc",
                .id             = -1,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_TSADC,
        }, {
                .name           = "i2c",
                .id             = -1,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_IIC0,
        }, {
                .name           = "i2s_v40",
                .id             = 0,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_IIS2,
        }, {
                .name           = "spi",
                .id             = 0,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_SPI0,
        }, {
                .name           = "spi",
                .id             = 1,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_SPI1,
        }, {
@@ -387,58 +421,124 @@ static struct clk init_clocks_disable[] = {
        }, {
                .name           = "otg",
                .id             = -1,
-               .parent         = &clk_h_low,
+               .parent         = &clk_hclk_low.clk,
                .enable         = s5p6440_hclk0_ctrl,
                .ctrlbit        = S5P_CLKCON_HCLK0_USB
        }, {
                .name           = "post",
                .id             = -1,
-               .parent         = &clk_h_low,
+               .parent         = &clk_hclk_low.clk,
                .enable         = s5p6440_hclk0_ctrl,
                .ctrlbit        = S5P_CLKCON_HCLK0_POST0
        }, {
                .name           = "lcd",
                .id             = -1,
-               .parent         = &clk_h_low,
+               .parent         = &clk_hclk_low.clk,
                .enable         = s5p6440_hclk1_ctrl,
                .ctrlbit        = S5P_CLKCON_HCLK1_DISPCON,
        }, {
                .name           = "hsmmc",
                .id             = 0,
-               .parent         = &clk_h_low,
+               .parent         = &clk_hclk_low.clk,
                .enable         = s5p6440_hclk0_ctrl,
                .ctrlbit        = S5P_CLKCON_HCLK0_HSMMC0,
        }, {
                .name           = "hsmmc",
                .id             = 1,
-               .parent         = &clk_h_low,
+               .parent         = &clk_hclk_low.clk,
                .enable         = s5p6440_hclk0_ctrl,
                .ctrlbit        = S5P_CLKCON_HCLK0_HSMMC1,
        }, {
                .name           = "hsmmc",
                .id             = 2,
-               .parent         = &clk_h_low,
+               .parent         = &clk_hclk_low.clk,
                .enable         = s5p6440_hclk0_ctrl,
                .ctrlbit        = S5P_CLKCON_HCLK0_HSMMC2,
        }, {
                .name           = "rtc",
                .id             = -1,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_RTC,
        }, {
                .name           = "watchdog",
                .id             = -1,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_WDT,
        }, {
                .name           = "timers",
                .id             = -1,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_PWM,
-       }
+       }, {
+               .name           = "hclk_fimgvg",
+               .id             = -1,
+               .parent         = &clk_hclk.clk,
+               .enable         = s5p6440_hclk1_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "tsi",
+               .id             = -1,
+               .parent         = &clk_hclk_low.clk,
+               .enable         = s5p6440_hclk1_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "pclk_fimgvg",
+               .id             = -1,
+               .parent         = &clk_pclk.clk,
+               .enable         = s5p6440_pclk_ctrl,
+               .ctrlbit        = (1 << 31),
+       }, {
+               .name           = "dmc0",
+               .id             = -1,
+               .parent         = &clk_pclk.clk,
+               .enable         = s5p6440_pclk_ctrl,
+               .ctrlbit        = (1 << 30),
+       }, {
+               .name           = "etm",
+               .id             = -1,
+               .parent         = &clk_pclk.clk,
+               .enable         = s5p6440_pclk_ctrl,
+               .ctrlbit        = (1 << 29),
+       }, {
+               .name           = "dsim",
+               .id             = -1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p6440_pclk_ctrl,
+               .ctrlbit        = (1 << 28),
+       }, {
+               .name           = "gps",
+               .id             = -1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p6440_pclk_ctrl,
+               .ctrlbit        = (1 << 25),
+       }, {
+               .name           = "pcm",
+               .id             = -1,
+               .parent         = &clk_pclk_low.clk,
+               .enable         = s5p6440_pclk_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "irom",
+               .id             = -1,
+               .parent         = &clk_hclk.clk,
+               .enable         = s5p6440_hclk0_ctrl,
+               .ctrlbit        = (1 << 25),
+       }, {
+               .name           = "dma",
+               .id             = -1,
+               .parent         = &clk_hclk_low.clk,
+               .enable         = s5p6440_hclk0_ctrl,
+               .ctrlbit        = (1 << 12),
+       }, {
+               .name           = "2d",
+               .id             = -1,
+               .parent         = &clk_hclk.clk,
+               .enable         = s5p6440_hclk0_ctrl,
+               .ctrlbit        = (1 << 8),
+       },
 };
 
 /*
@@ -448,34 +548,46 @@ static struct clk init_clocks[] = {
        {
                .name           = "gpio",
                .id             = -1,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_GPIO,
        }, {
                .name           = "uart",
                .id             = 0,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_UART0,
        }, {
                .name           = "uart",
                .id             = 1,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_UART1,
        }, {
                .name           = "uart",
                .id             = 2,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_UART2,
        }, {
                .name           = "uart",
                .id             = 3,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_UART3,
-       }
+       }, {
+               .name           = "mem",
+               .id             = -1,
+               .parent         = &clk_hclk.clk,
+               .enable         = s5p6440_hclk0_ctrl,
+               .ctrlbit        = (1 << 21),
+       }, {
+               .name           = "intc",
+               .id             = -1,
+               .parent         = &clk_hclk.clk,
+               .enable         = s5p6440_hclk0_ctrl,
+               .ctrlbit        = (1 << 1),
+       },
 };
 
 static struct clk clk_iis_cd_v40 = {
@@ -488,20 +600,20 @@ static struct clk clk_pcm_cd = {
        .id             = -1,
 };
 
-static struct clk *clkset_spi_mmc_list[] = {
+static struct clk *clkset_group1_list[] = {
        &clk_mout_epll.clk,
-       &clk_dout_mpll,
+       &clk_dout_mpll.clk,
        &clk_fin_epll,
 };
 
-static struct clksrc_sources clkset_spi_mmc = {
-       .sources        = clkset_spi_mmc_list,
-       .nr_sources     = ARRAY_SIZE(clkset_spi_mmc_list),
+static struct clksrc_sources clkset_group1 = {
+       .sources        = clkset_group1_list,
+       .nr_sources     = ARRAY_SIZE(clkset_group1_list),
 };
 
 static struct clk *clkset_uart_list[] = {
        &clk_mout_epll.clk,
-       &clk_dout_mpll
+       &clk_dout_mpll.clk,
 };
 
 static struct clksrc_sources clkset_uart = {
@@ -509,6 +621,19 @@ static struct clksrc_sources clkset_uart = {
        .nr_sources     = ARRAY_SIZE(clkset_uart_list),
 };
 
+static struct clk *clkset_audio_list[] = {
+       &clk_mout_epll.clk,
+       &clk_dout_mpll.clk,
+       &clk_fin_epll,
+       &clk_iis_cd_v40,
+       &clk_pcm_cd,
+};
+
+static struct clksrc_sources clkset_audio = {
+       .sources        = clkset_audio_list,
+       .nr_sources     = ARRAY_SIZE(clkset_audio_list),
+};
+
 static struct clksrc_clk clksrcs[] = {
        {
                .clk    = {
@@ -517,7 +642,7 @@ static struct clksrc_clk clksrcs[] = {
                        .ctrlbit        = S5P_CLKCON_SCLK0_MMC0,
                        .enable         = s5p6440_sclk_ctrl,
                },
-               .sources = &clkset_spi_mmc,
+               .sources = &clkset_group1,
                .reg_src = { .reg = S5P_CLK_SRC0, .shift = 18, .size = 2 },
                .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4 },
        }, {
@@ -527,7 +652,7 @@ static struct clksrc_clk clksrcs[] = {
                        .ctrlbit        = S5P_CLKCON_SCLK0_MMC1,
                        .enable         = s5p6440_sclk_ctrl,
                },
-               .sources = &clkset_spi_mmc,
+               .sources = &clkset_group1,
                .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 2 },
                .reg_div = { .reg = S5P_CLK_DIV1, .shift = 4, .size = 4 },
        }, {
@@ -537,7 +662,7 @@ static struct clksrc_clk clksrcs[] = {
                        .ctrlbit        = S5P_CLKCON_SCLK0_MMC2,
                        .enable         = s5p6440_sclk_ctrl,
                },
-               .sources = &clkset_spi_mmc,
+               .sources = &clkset_group1,
                .reg_src = { .reg = S5P_CLK_SRC0, .shift = 22, .size = 2 },
                .reg_div = { .reg = S5P_CLK_DIV1, .shift = 8, .size = 4 },
        }, {
@@ -557,7 +682,7 @@ static struct clksrc_clk clksrcs[] = {
                        .ctrlbit        = S5P_CLKCON_SCLK0_SPI0,
                        .enable         = s5p6440_sclk_ctrl,
                },
-               .sources = &clkset_spi_mmc,
+               .sources = &clkset_group1,
                .reg_src = { .reg = S5P_CLK_SRC0, .shift = 14, .size = 2 },
                .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
        }, {
@@ -567,17 +692,63 @@ static struct clksrc_clk clksrcs[] = {
                        .ctrlbit        = S5P_CLKCON_SCLK0_SPI1,
                        .enable         = s5p6440_sclk_ctrl,
                },
-               .sources = &clkset_spi_mmc,
+               .sources = &clkset_group1,
                .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 2 },
                .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
-       }
+       }, {
+               .clk    = {
+                       .name           = "sclk_post",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 10),
+                       .enable         = s5p6440_sclk_ctrl,
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P_CLK_SRC0, .shift = 26, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_dispcon",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 1),
+                       .enable         = s5p6440_sclk1_ctrl,
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 0, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimgvg",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 2),
+                       .enable         = s5p6440_sclk1_ctrl,
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 4, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_audio2",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 11),
+                       .enable         = s5p6440_sclk_ctrl,
+               },
+               .sources = &clkset_audio,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 3 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 24, .size = 4 },
+       },
 };
 
 /* Clock initialisation code */
-static struct clksrc_clk *init_parents[] = {
+static struct clksrc_clk *sysclks[] = {
        &clk_mout_apll,
        &clk_mout_epll,
        &clk_mout_mpll,
+       &clk_dout_mpll,
+       &clk_armclk,
+       &clk_hclk,
+       &clk_pclk,
+       &clk_hclk_low,
+       &clk_pclk_low,
 };
 
 void __init_or_cpufreq s5p6440_setup_clocks(void)
@@ -593,21 +764,13 @@ void __init_or_cpufreq s5p6440_setup_clocks(void)
        unsigned long apll;
        unsigned long mpll;
        unsigned int ptr;
-       u32 clkdiv0;
-       u32 clkdiv3;
 
        /* Set S5P6440 functions for clk_fout_epll */
        clk_fout_epll.enable = s5p6440_epll_enable;
        clk_fout_epll.ops = &s5p6440_epll_ops;
 
-       /* Set S5P6440 functions for arm clock */
-       clk_arm.parent = &clk_mout_apll.clk;
-       clk_arm.ops = &s5p6440_clkarm_ops;
        clk_48m.enable = s5p6440_clk48m_ctrl;
 
-       clkdiv0 = __raw_readl(S5P_CLK_DIV0);
-       clkdiv3 = __raw_readl(S5P_CLK_DIV3);
-
        xtal_clk = clk_get(NULL, "ext_xtal");
        BUG_ON(IS_ERR(xtal_clk));
 
@@ -619,41 +782,28 @@ void __init_or_cpufreq s5p6440_setup_clocks(void)
        mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
        apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4502);
 
+       clk_fout_mpll.rate = mpll;
+       clk_fout_epll.rate = epll;
+       clk_fout_apll.rate = apll;
+
        printk(KERN_INFO "S5P6440: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \
                        " E=%ld.%ldMHz\n",
                        print_mhz(apll), print_mhz(mpll), print_mhz(epll));
 
-       fclk = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_ARM);
-       hclk = fclk / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK);
-       pclk = hclk / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK);
-
-       if (__raw_readl(S5P_OTHERS) & S5P_OTHERS_HCLK_LOW_SEL_MPLL) {
-               /* Asynchronous mode */
-               hclk_low = mpll / GET_DIV(clkdiv3, S5P_CLKDIV3_HCLK_LOW);
-       } else {
-               /* Synchronous mode */
-               hclk_low = apll / GET_DIV(clkdiv3, S5P_CLKDIV3_HCLK_LOW);
-       }
-
-       pclk_low = hclk_low / GET_DIV(clkdiv3, S5P_CLKDIV3_PCLK_LOW);
+       fclk = clk_get_rate(&clk_armclk.clk);
+       hclk = clk_get_rate(&clk_hclk.clk);
+       pclk = clk_get_rate(&clk_pclk.clk);
+       hclk_low = clk_get_rate(&clk_hclk_low.clk);
+       pclk_low = clk_get_rate(&clk_pclk_low.clk);
 
        printk(KERN_INFO "S5P6440: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \
                        " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n",
                        print_mhz(hclk), print_mhz(hclk_low),
                        print_mhz(pclk), print_mhz(pclk_low));
 
-       clk_fout_mpll.rate = mpll;
-       clk_fout_epll.rate = epll;
-       clk_fout_apll.rate = apll;
-
        clk_f.rate = fclk;
        clk_h.rate = hclk;
        clk_p.rate = pclk;
-       clk_h_low.rate = hclk_low;
-       clk_p_low.rate = pclk_low;
-
-       for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
-               s3c_set_clksrc(init_parents[ptr], true);
 
        for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
                s3c_set_clksrc(&clksrcs[ptr], true);
@@ -661,13 +811,8 @@ void __init_or_cpufreq s5p6440_setup_clocks(void)
 
 static struct clk *clks[] __initdata = {
        &clk_ext,
-       &clk_mout_epll.clk,
-       &clk_mout_mpll.clk,
-       &clk_dout_mpll,
        &clk_iis_cd_v40,
        &clk_pcm_cd,
-       &clk_p_low,
-       &clk_h_low,
 };
 
 void __init s5p6440_register_clocks(void)
@@ -680,6 +825,9 @@ void __init s5p6440_register_clocks(void)
        if (ret > 0)
                printk(KERN_ERR "Failed to register %u clocks\n", ret);
 
+       for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
+               s3c_register_clksrc(sysclks[ptr], 1);
+
        s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
        s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
 
index 1794131aeacb59ab668c6a8562fc52bedd87a795..ca3b3206e6f86d999d789fc05947a44bd38be314 100644 (file)
@@ -88,7 +88,7 @@ void __init s5p6440_init_irq(void)
        s5p_init_irq(vic, ARRAY_SIZE(vic));
 }
 
-static struct sysdev_class s5p6440_sysclass = {
+struct sysdev_class s5p6440_sysclass = {
        .name   = "s5p6440-core",
 };
 
diff --git a/arch/arm/mach-s5p6440/dev-audio.c b/arch/arm/mach-s5p6440/dev-audio.c
new file mode 100644 (file)
index 0000000..0c53679
--- /dev/null
@@ -0,0 +1,127 @@
+/* linux/arch/arm/mach-s5p6440/dev-audio.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. Ltd
+ *     Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/audio.h>
+
+#include <mach/gpio.h>
+#include <mach/map.h>
+#include <mach/dma.h>
+#include <mach/irqs.h>
+
+static int s5p6440_cfg_i2s(struct platform_device *pdev)
+{
+       /* configure GPIO for i2s port */
+       switch (pdev->id) {
+       case -1:
+               s3c_gpio_cfgpin(S5P6440_GPR(4), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6440_GPR(5), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(5));
+               break;
+
+       default:
+               printk(KERN_ERR "Invalid Device %d\n", pdev->id);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct s3c_audio_pdata s3c_i2s_pdata = {
+       .cfg_gpio = s5p6440_cfg_i2s,
+};
+
+static struct resource s5p6440_iis0_resource[] = {
+       [0] = {
+               .start = S5P6440_PA_I2S,
+               .end   = S5P6440_PA_I2S + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_I2S0_TX,
+               .end   = DMACH_I2S0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_I2S0_RX,
+               .end   = DMACH_I2S0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5p6440_device_iis = {
+       .name             = "s3c64xx-iis-v4",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(s5p6440_iis0_resource),
+       .resource         = s5p6440_iis0_resource,
+       .dev = {
+               .platform_data = &s3c_i2s_pdata,
+       },
+};
+
+/* PCM Controller platform_devices */
+
+static int s5p6440_pcm_cfg_gpio(struct platform_device *pdev)
+{
+       switch (pdev->id) {
+       case 0:
+               s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(2));
+               break;
+
+       default:
+               printk(KERN_DEBUG "Invalid PCM Controller number!");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct s3c_audio_pdata s3c_pcm_pdata = {
+       .cfg_gpio = s5p6440_pcm_cfg_gpio,
+};
+
+static struct resource s5p6440_pcm0_resource[] = {
+       [0] = {
+               .start = S5P6440_PA_PCM,
+               .end   = S5P6440_PA_PCM + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_PCM0_TX,
+               .end   = DMACH_PCM0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_PCM0_RX,
+               .end   = DMACH_PCM0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5p6440_device_pcm = {
+       .name             = "samsung-pcm",
+       .id               = 0,
+       .num_resources    = ARRAY_SIZE(s5p6440_pcm0_resource),
+       .resource         = s5p6440_pcm0_resource,
+       .dev = {
+               .platform_data = &s3c_pcm_pdata,
+       },
+};
diff --git a/arch/arm/mach-s5p6440/dma.c b/arch/arm/mach-s5p6440/dma.c
new file mode 100644 (file)
index 0000000..07606ad
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ *     Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <plat/devs.h>
+#include <plat/irqs.h>
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+
+#include <plat/s3c-pl330-pdata.h>
+
+static u64 dma_dmamask = DMA_BIT_MASK(32);
+
+static struct resource s5p6440_pdma_resource[] = {
+       [0] = {
+               .start  = S5P6440_PA_PDMA,
+               .end    = S5P6440_PA_PDMA + SZ_4K,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_DMA0,
+               .end    = IRQ_DMA0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct s3c_pl330_platdata s5p6440_pdma_pdata = {
+       .peri = {
+               [0] = DMACH_UART0_RX,
+               [1] = DMACH_UART0_TX,
+               [2] = DMACH_UART1_RX,
+               [3] = DMACH_UART1_TX,
+               [4] = DMACH_UART2_RX,
+               [5] = DMACH_UART2_TX,
+               [6] = DMACH_UART3_RX,
+               [7] = DMACH_UART3_TX,
+               [8] = DMACH_MAX,
+               [9] = DMACH_MAX,
+               [10] = DMACH_PCM0_TX,
+               [11] = DMACH_PCM0_RX,
+               [12] = DMACH_I2S0_TX,
+               [13] = DMACH_I2S0_RX,
+               [14] = DMACH_SPI0_TX,
+               [15] = DMACH_SPI0_RX,
+               [16] = DMACH_MAX,
+               [17] = DMACH_MAX,
+               [18] = DMACH_MAX,
+               [19] = DMACH_MAX,
+               [20] = DMACH_SPI1_TX,
+               [21] = DMACH_SPI1_RX,
+               [22] = DMACH_MAX,
+               [23] = DMACH_MAX,
+               [24] = DMACH_MAX,
+               [25] = DMACH_MAX,
+               [26] = DMACH_MAX,
+               [27] = DMACH_MAX,
+               [28] = DMACH_MAX,
+               [29] = DMACH_PWM,
+               [30] = DMACH_MAX,
+               [31] = DMACH_MAX,
+       },
+};
+
+static struct platform_device s5p6440_device_pdma = {
+       .name           = "s3c-pl330",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(s5p6440_pdma_resource),
+       .resource       = s5p6440_pdma_resource,
+       .dev            = {
+               .dma_mask = &dma_dmamask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+               .platform_data = &s5p6440_pdma_pdata,
+       },
+};
+
+static struct platform_device *s5p6440_dmacs[] __initdata = {
+       &s5p6440_device_pdma,
+};
+
+static int __init s5p6440_dma_init(void)
+{
+       platform_add_devices(s5p6440_dmacs, ARRAY_SIZE(s5p6440_dmacs));
+
+       return 0;
+}
+arch_initcall(s5p6440_dma_init);
diff --git a/arch/arm/mach-s5p6440/include/mach/dma.h b/arch/arm/mach-s5p6440/include/mach/dma.h
new file mode 100644 (file)
index 0000000..81209eb
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ *     Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MACH_DMA_H
+#define __MACH_DMA_H
+
+/* This platform uses the common S3C DMA API driver for PL330 */
+#include <plat/s3c-dma-pl330.h>
+
+#endif /* __MACH_DMA_H */
index 8924e5a4d6a6386f436cbcedc6fd00d72fa6fdd1..72aedadd412cd405747725993054c554dff03fe8 100644 (file)
@@ -29,6 +29,8 @@
 #define S5P6440_PA_VIC0                (0xE4000000)
 #define S5P_PA_VIC0            S5P6440_PA_VIC0
 
+#define S5P6440_PA_PDMA                0xE9000000
+
 #define S5P6440_PA_VIC1                (0xE4100000)
 #define S5P_PA_VIC1            S5P6440_PA_VIC1
 
 #define S5P6440_PA_SDRAM       (0x20000000)
 #define S5P_PA_SDRAM           S5P6440_PA_SDRAM
 
+/* I2S */
+#define S5P6440_PA_I2S         0xF2000000
+
+/* PCM */
+#define S5P6440_PA_PCM         0xF2100000
+
 /* compatibiltiy defines. */
 #define S3C_PA_UART            S5P6440_PA_UART
 #define S3C_PA_IIC             S5P6440_PA_IIC0
index c4bb7c5554777fe4b15f2dd9e712563943759938..6a2a02fdf12a23df33ce6783c7a7181923348ddb 100644 (file)
@@ -1,11 +1,14 @@
 /* linux/arch/arm/mach-s5p6440/include/mach/pwm-clock.h
  *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * Copyright 2008 Openmoko, Inc.
  * Copyright 2008 Simtec Electronics
  *      Ben Dooks <ben@simtec.co.uk>
  *      http://armlinux.simtec.co.uk/
  *
- * Copyright 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
+ * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
  *
  * S5P6440 - pwm clock and timer support
  *
  * published by the Free Software Foundation.
 */
 
+#ifndef __ASM_ARCH_PWMCLK_H
+#define __ASM_ARCH_PWMCLK_H __FILE__
+
 /**
  * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
- * @cfg: The timer TCFG1 register bits shifted down to 0.
+ * @tcfg: The timer TCFG1 register bits shifted down to 0.
  *
  * Return true if the given configuration from TCFG1 is a TCLK instead
  * any of the TDIV clocks.
  */
 static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
 {
-       return tcfg == S3C2410_TCFG1_MUX_TCLK;
+       return 0;
 }
 
 /**
@@ -35,7 +41,7 @@ static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
  */
 static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
 {
-       return 1 << (1 + tcfg1);
+       return 1 << tcfg1;
 }
 
 /**
@@ -45,7 +51,7 @@ static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
  */
 static inline unsigned int pwm_tdiv_has_div1(void)
 {
-       return 0;
+       return 1;
 }
 
 /**
@@ -56,7 +62,9 @@ static inline unsigned int pwm_tdiv_has_div1(void)
  */
 static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
 {
-       return ilog2(div) - 1;
+       return ilog2(div);
 }
 
-#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK
+#define S3C_TCFG1_MUX_TCLK 0
+
+#endif /* __ASM_ARCH_PWMCLK_H */
index 3ae88f2c7c77aede120669fffa0b39c033fa6095..d7fede971ca6cc5c65abd2951020571803284730 100644 (file)
@@ -84,6 +84,7 @@ static struct s3c2410_uartcfg smdk6440_uartcfgs[] __initdata = {
 };
 
 static struct platform_device *smdk6440_devices[] __initdata = {
+       &s5p6440_device_iis,
 };
 
 static void __init smdk6440_map_io(void)
similarity index 92%
rename from arch/arm/plat-s5p/setup-i2c0.c
rename to arch/arm/mach-s5p6440/setup-i2c0.c
index 67a66e02a97a6511cbb99330979dba2537e91ae9..69e8a664aedb3197080ff1fcdbd40b8de323e8a4 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/arch/arm/plat-s5p/setup-i2c0.c
+/* linux/arch/arm/mach-s5p6440/setup-i2c0.c
  *
  * Copyright (c) 2009 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com/
index 4f3f6de6a013f66c72b3d977d0cf998b4ba6e1ec..0fd41b447915312ee02dc2365dfbdc1ac6720dd4 100644 (file)
@@ -12,6 +12,7 @@ if ARCH_S5P6442
 config CPU_S5P6442
        bool
        select PLAT_S5P
+       select S3C_PL330_DMA
        help
          Enable S5P6442 CPU support
 
index dde39a6ce6bcced474768e81182e353018733905..e30a7f76aee6a5c77a9f74e815681b9592f18dce 100644 (file)
@@ -12,8 +12,12 @@ obj-                         :=
 
 # Core support for S5P6442 system
 
-obj-$(CONFIG_CPU_S5P6442)      += cpu.o init.o clock.o
+obj-$(CONFIG_CPU_S5P6442)      += cpu.o init.o clock.o dma.o
+obj-$(CONFIG_CPU_S5P6442)      += setup-i2c0.o
 
 # machine support
 
 obj-$(CONFIG_MACH_SMDK6442)    += mach-smdk6442.o
+
+# device support
+obj-y                          += dev-audio.o
index bc2524df89b36da7aa0f1fe6b4478f16c645e7be..a48fb553fd01cf5d42e1ab590146d7cad1e7680f 100644 (file)
@@ -95,7 +95,7 @@ void __init s5p6442_init_irq(void)
        s5p_init_irq(vic, ARRAY_SIZE(vic));
 }
 
-static struct sysdev_class s5p6442_sysclass = {
+struct sysdev_class s5p6442_sysclass = {
        .name   = "s5p6442-core",
 };
 
diff --git a/arch/arm/mach-s5p6442/dev-audio.c b/arch/arm/mach-s5p6442/dev-audio.c
new file mode 100644 (file)
index 0000000..cb801e1
--- /dev/null
@@ -0,0 +1,197 @@
+/* linux/arch/arm/mach-s5p6442/dev-audio.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. Ltd
+ *     Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/audio.h>
+
+#include <mach/gpio.h>
+#include <mach/map.h>
+#include <mach/dma.h>
+#include <mach/irqs.h>
+
+static int s5p6442_cfg_i2s(struct platform_device *pdev)
+{
+       /* configure GPIO for i2s port */
+       switch (pdev->id) {
+       case 1:
+               s3c_gpio_cfgpin(S5P6442_GPC1(0), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6442_GPC1(1), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6442_GPC1(2), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6442_GPC1(3), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6442_GPC1(4), S3C_GPIO_SFN(2));
+               break;
+
+       case -1:
+               s3c_gpio_cfgpin(S5P6442_GPC0(0), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6442_GPC0(1), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6442_GPC0(2), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6442_GPC0(3), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6442_GPC0(4), S3C_GPIO_SFN(2));
+               break;
+
+       default:
+               printk(KERN_ERR "Invalid Device %d\n", pdev->id);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct s3c_audio_pdata s3c_i2s_pdata = {
+       .cfg_gpio = s5p6442_cfg_i2s,
+};
+
+static struct resource s5p6442_iis0_resource[] = {
+       [0] = {
+               .start = S5P6442_PA_I2S0,
+               .end   = S5P6442_PA_I2S0 + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_I2S0_TX,
+               .end   = DMACH_I2S0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_I2S0_RX,
+               .end   = DMACH_I2S0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5p6442_device_iis0 = {
+       .name             = "s3c64xx-iis-v4",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(s5p6442_iis0_resource),
+       .resource         = s5p6442_iis0_resource,
+       .dev = {
+               .platform_data = &s3c_i2s_pdata,
+       },
+};
+
+static struct resource s5p6442_iis1_resource[] = {
+       [0] = {
+               .start = S5P6442_PA_I2S1,
+               .end   = S5P6442_PA_I2S1 + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_I2S1_TX,
+               .end   = DMACH_I2S1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_I2S1_RX,
+               .end   = DMACH_I2S1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5p6442_device_iis1 = {
+       .name             = "s3c64xx-iis",
+       .id               = 1,
+       .num_resources    = ARRAY_SIZE(s5p6442_iis1_resource),
+       .resource         = s5p6442_iis1_resource,
+       .dev = {
+               .platform_data = &s3c_i2s_pdata,
+       },
+};
+
+/* PCM Controller platform_devices */
+
+static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev)
+{
+       switch (pdev->id) {
+       case 0:
+               s3c_gpio_cfgpin(S5P6442_GPC0(0), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5P6442_GPC0(1), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5P6442_GPC0(2), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5P6442_GPC0(3), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5P6442_GPC0(4), S3C_GPIO_SFN(3));
+               break;
+
+       case 1:
+               s3c_gpio_cfgpin(S5P6442_GPC1(0), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5P6442_GPC1(1), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5P6442_GPC1(2), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5P6442_GPC1(3), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5P6442_GPC1(4), S3C_GPIO_SFN(3));
+               break;
+
+       default:
+               printk(KERN_DEBUG "Invalid PCM Controller number!");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct s3c_audio_pdata s3c_pcm_pdata = {
+       .cfg_gpio = s5p6442_pcm_cfg_gpio,
+};
+
+static struct resource s5p6442_pcm0_resource[] = {
+       [0] = {
+               .start = S5P6442_PA_PCM0,
+               .end   = S5P6442_PA_PCM0 + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_PCM0_TX,
+               .end   = DMACH_PCM0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_PCM0_RX,
+               .end   = DMACH_PCM0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5p6442_device_pcm0 = {
+       .name             = "samsung-pcm",
+       .id               = 0,
+       .num_resources    = ARRAY_SIZE(s5p6442_pcm0_resource),
+       .resource         = s5p6442_pcm0_resource,
+       .dev = {
+               .platform_data = &s3c_pcm_pdata,
+       },
+};
+
+static struct resource s5p6442_pcm1_resource[] = {
+       [0] = {
+               .start = S5P6442_PA_PCM1,
+               .end   = S5P6442_PA_PCM1 + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_PCM1_TX,
+               .end   = DMACH_PCM1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_PCM1_RX,
+               .end   = DMACH_PCM1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5p6442_device_pcm1 = {
+       .name             = "samsung-pcm",
+       .id               = 1,
+       .num_resources    = ARRAY_SIZE(s5p6442_pcm1_resource),
+       .resource         = s5p6442_pcm1_resource,
+       .dev = {
+               .platform_data = &s3c_pcm_pdata,
+       },
+};
diff --git a/arch/arm/mach-s5p6442/dma.c b/arch/arm/mach-s5p6442/dma.c
new file mode 100644 (file)
index 0000000..ad4f870
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ *     Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <plat/devs.h>
+#include <plat/irqs.h>
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+
+#include <plat/s3c-pl330-pdata.h>
+
+static u64 dma_dmamask = DMA_BIT_MASK(32);
+
+static struct resource s5p6442_pdma_resource[] = {
+       [0] = {
+               .start  = S5P6442_PA_PDMA,
+               .end    = S5P6442_PA_PDMA + SZ_4K,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_PDMA,
+               .end    = IRQ_PDMA,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct s3c_pl330_platdata s5p6442_pdma_pdata = {
+       .peri = {
+               [0] = DMACH_UART0_RX,
+               [1] = DMACH_UART0_TX,
+               [2] = DMACH_UART1_RX,
+               [3] = DMACH_UART1_TX,
+               [4] = DMACH_UART2_RX,
+               [5] = DMACH_UART2_TX,
+               [6] = DMACH_MAX,
+               [7] = DMACH_MAX,
+               [8] = DMACH_MAX,
+               [9] = DMACH_I2S0_RX,
+               [10] = DMACH_I2S0_TX,
+               [11] = DMACH_I2S0S_TX,
+               [12] = DMACH_I2S1_RX,
+               [13] = DMACH_I2S1_TX,
+               [14] = DMACH_MAX,
+               [15] = DMACH_MAX,
+               [16] = DMACH_SPI0_RX,
+               [17] = DMACH_SPI0_TX,
+               [18] = DMACH_MAX,
+               [19] = DMACH_MAX,
+               [20] = DMACH_PCM0_RX,
+               [21] = DMACH_PCM0_TX,
+               [22] = DMACH_PCM1_RX,
+               [23] = DMACH_PCM1_TX,
+               [24] = DMACH_MAX,
+               [25] = DMACH_MAX,
+               [26] = DMACH_MAX,
+               [27] = DMACH_MSM_REQ0,
+               [28] = DMACH_MSM_REQ1,
+               [29] = DMACH_MSM_REQ2,
+               [30] = DMACH_MSM_REQ3,
+               [31] = DMACH_MAX,
+       },
+};
+
+static struct platform_device s5p6442_device_pdma = {
+       .name           = "s3c-pl330",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(s5p6442_pdma_resource),
+       .resource       = s5p6442_pdma_resource,
+       .dev            = {
+               .dma_mask = &dma_dmamask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+               .platform_data = &s5p6442_pdma_pdata,
+       },
+};
+
+static struct platform_device *s5p6442_dmacs[] __initdata = {
+       &s5p6442_device_pdma,
+};
+
+static int __init s5p6442_dma_init(void)
+{
+       platform_add_devices(s5p6442_dmacs, ARRAY_SIZE(s5p6442_dmacs));
+
+       return 0;
+}
+arch_initcall(s5p6442_dma_init);
diff --git a/arch/arm/mach-s5p6442/include/mach/dma.h b/arch/arm/mach-s5p6442/include/mach/dma.h
new file mode 100644 (file)
index 0000000..81209eb
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ *     Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MACH_DMA_H
+#define __MACH_DMA_H
+
+/* This platform uses the common S3C DMA API driver for PL330 */
+#include <plat/s3c-dma-pl330.h>
+
+#endif /* __MACH_DMA_H */
index 685277d792fb5770d9fefac7121f9c1a938b0325..7568dc0d6be07722aee678620352708e970a42bd 100644 (file)
@@ -34,6 +34,9 @@
 #define S5P6442_PA_VIC2                (0xE4200000)
 #define S5P_PA_VIC2            S5P6442_PA_VIC2
 
+#define S5P6442_PA_MDMA                0xE8000000
+#define S5P6442_PA_PDMA                0xE9000000
+
 #define S5P6442_PA_TIMER       (0xEA000000)
 #define S5P_PA_TIMER           S5P6442_PA_TIMER
 
 #define S5P6442_PA_SDRAM       (0x20000000)
 #define S5P_PA_SDRAM           S5P6442_PA_SDRAM
 
+/* I2S */
+#define S5P6442_PA_I2S0                0xC0B00000
+#define S5P6442_PA_I2S1                0xF2200000
+
+/* PCM */
+#define S5P6442_PA_PCM0                0xF2400000
+#define S5P6442_PA_PCM1                0xF2500000
+
 /* compatibiltiy defines. */
 #define S3C_PA_UART            S5P6442_PA_UART
 #define S3C_PA_IIC             S5P6442_PA_IIC0
index 15e8525da0f13a94502609962bbbc72841d10edb..2724b37def3149c79c9acb581995024167f45fe0 100644 (file)
@@ -1,13 +1,14 @@
 /* linux/arch/arm/mach-s5p6442/include/mach/pwm-clock.h
  *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * Copyright 2008 Openmoko, Inc.
  * Copyright 2008 Simtec Electronics
  *      Ben Dooks <ben@simtec.co.uk>
  *      http://armlinux.simtec.co.uk/
  *
- * Copyright 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * Based on arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
+ * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
  *
  * S5P6442 - pwm clock and timer support
  *
 
 /**
  * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
- * @cfg: The timer TCFG1 register bits shifted down to 0.
+ * @tcfg: The timer TCFG1 register bits shifted down to 0.
  *
  * Return true if the given configuration from TCFG1 is a TCLK instead
  * any of the TDIV clocks.
  */
 static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
 {
-       return tcfg == S3C2410_TCFG1_MUX_TCLK;
+       return tcfg == S3C64XX_TCFG1_MUX_TCLK;
 }
 
 /**
@@ -40,7 +41,7 @@ static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
  */
 static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
 {
-       return 1 << (1 + tcfg1);
+       return 1 << tcfg1;
 }
 
 /**
@@ -50,7 +51,7 @@ static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
  */
 static inline unsigned int pwm_tdiv_has_div1(void)
 {
-       return 0;
+       return 1;
 }
 
 /**
@@ -61,9 +62,9 @@ static inline unsigned int pwm_tdiv_has_div1(void)
  */
 static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
 {
-       return ilog2(div) - 1;
+       return ilog2(div);
 }
 
-#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK
+#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
 
 #endif /* __ASM_ARCH_PWMCLK_H */
index 0d63371ce07cfcd52a84345f29ea2fc5db901daf..ebcf997772593c9403912f8880021c5639cf6fa1 100644 (file)
@@ -65,6 +65,7 @@ static struct s3c2410_uartcfg smdk6442_uartcfgs[] __initdata = {
 };
 
 static struct platform_device *smdk6442_devices[] __initdata = {
+       &s5p6442_device_iis0,
 };
 
 static void __init smdk6442_map_io(void)
diff --git a/arch/arm/mach-s5p6442/setup-i2c0.c b/arch/arm/mach-s5p6442/setup-i2c0.c
new file mode 100644 (file)
index 0000000..662695d
--- /dev/null
@@ -0,0 +1,25 @@
+/* linux/arch/arm/mach-s5p6442/setup-i2c0.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * I2C0 GPIO configuration.
+ *
+ * Based on plat-s3c64xx/setup-i2c0.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/iic.h>
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+{
+       /* Will be populated later */
+}
index 27ec167d2808eec0e7bfb5f9d8cf73ebe05cf97b..8593337784e16756d2c0545996b28c01b8d2b559 100644 (file)
@@ -12,12 +12,22 @@ config CPU_S5PC100
        help
          Enable S5PC100 CPU support
 
+config S5PC100_SETUP_FB_24BPP
+       bool
+       help
+         Common setup code for S5PC1XX with an 24bpp RGB display helper.
+
 config S5PC100_SETUP_SDHCI
         bool
         select S5PC1XX_SETUP_SDHCI_GPIO
         help
           Internal helper functions for S5PC100 based SDHCI systems
 
+config S5PC100_SETUP_I2C1
+       bool
+       help
+         Common setup code for i2c bus 1.
+
 config MACH_SMDKC100
        bool "SMDKC100"
        select CPU_S5PC100
@@ -26,9 +36,8 @@ config MACH_SMDKC100
        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_FB_24BPP
+       select S5PC100_SETUP_I2C1
        select S5PC100_SETUP_SDHCI
        help
          Machine support for the Samsung SMDKC100
index 809ff10f768ff3848edf03c0910d2afe7463a649..373bc546eae8bb87c36b8ad4f854b39966f164f2 100644 (file)
@@ -11,10 +11,13 @@ obj-                                :=
 
 # Core support for S5PC100 system
 
-obj-$(CONFIG_CPU_S5PC100)      += cpu.o
+obj-$(CONFIG_CPU_S5PC100)      += cpu.o gpiolib.o
+obj-$(CONFIG_CPU_S5PC100)      += setup-i2c0.o
 
 # Helper and device support
 
+obj-$(CONFIG_S5PC100_SETUP_FB_24BPP)   += setup-fb-24bpp.o
+obj-$(CONFIG_S5PC100_SETUP_I2C1)       += setup-i2c1.o
 obj-$(CONFIG_S5PC100_SETUP_SDHCI)       += setup-sdhci.o
 
 # machine support
diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c
new file mode 100644 (file)
index 0000000..e3fed4c
--- /dev/null
@@ -0,0 +1,1358 @@
+/* linux/arch/arm/mach-s5pc100/clock.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * S5PC100 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+
+#include <plat/cpu-freq.h>
+#include <mach/regs-clock.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5pc100.h>
+
+static struct clk s5p_clk_otgphy = {
+       .name           = "otg_phy",
+       .id             = -1,
+};
+
+static struct clk *clk_src_mout_href_list[] = {
+       [0] = &s5p_clk_27m,
+       [1] = &clk_fin_hpll,
+};
+
+static struct clksrc_sources clk_src_mout_href = {
+       .sources        = clk_src_mout_href_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_mout_href_list),
+};
+
+static struct clksrc_clk clk_mout_href = {
+       .clk = {
+               .name           = "mout_href",
+               .id             = -1,
+       },
+       .sources        = &clk_src_mout_href,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 1 },
+};
+
+static struct clk *clk_src_mout_48m_list[] = {
+       [0] = &clk_xusbxti,
+       [1] = &s5p_clk_otgphy,
+};
+
+static struct clksrc_sources clk_src_mout_48m = {
+       .sources        = clk_src_mout_48m_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_mout_48m_list),
+};
+
+static struct clksrc_clk clk_mout_48m = {
+       .clk = {
+               .name           = "mout_48m",
+               .id             = -1,
+       },
+       .sources        = &clk_src_mout_48m,
+       .reg_src        = { .reg = S5P_CLK_SRC1, .shift = 24, .size = 1 },
+};
+
+static struct clksrc_clk clk_mout_mpll = {
+       .clk = {
+               .name           = "mout_mpll",
+               .id             = -1,
+       },
+       .sources        = &clk_src_mpll,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 },
+};
+
+
+static struct clksrc_clk clk_mout_apll = {
+       .clk    = {
+               .name           = "mout_apll",
+               .id             = -1,
+       },
+       .sources        = &clk_src_apll,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
+};
+
+static struct clksrc_clk clk_mout_epll = {
+       .clk    = {
+               .name           = "mout_epll",
+               .id             = -1,
+       },
+       .sources        = &clk_src_epll,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
+};
+
+static struct clk *clk_src_mout_hpll_list[] = {
+       [0] = &s5p_clk_27m,
+};
+
+static struct clksrc_sources clk_src_mout_hpll = {
+       .sources        = clk_src_mout_hpll_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_mout_hpll_list),
+};
+
+static struct clksrc_clk clk_mout_hpll = {
+       .clk    = {
+               .name           = "mout_hpll",
+               .id             = -1,
+       },
+       .sources        = &clk_src_mout_hpll,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 },
+};
+
+static struct clksrc_clk clk_div_apll = {
+       .clk    = {
+               .name   = "div_apll",
+               .id     = -1,
+               .parent = &clk_mout_apll.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 1 },
+};
+
+static struct clksrc_clk clk_div_arm = {
+       .clk    = {
+               .name   = "div_arm",
+               .id     = -1,
+               .parent = &clk_div_apll.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 },
+};
+
+static struct clksrc_clk clk_div_d0_bus = {
+       .clk    = {
+               .name   = "div_d0_bus",
+               .id     = -1,
+               .parent = &clk_div_arm.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 3 },
+};
+
+static struct clksrc_clk clk_div_pclkd0 = {
+       .clk    = {
+               .name   = "div_pclkd0",
+               .id     = -1,
+               .parent = &clk_div_d0_bus.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 3 },
+};
+
+static struct clksrc_clk clk_div_secss = {
+       .clk    = {
+               .name   = "div_secss",
+               .id     = -1,
+               .parent = &clk_div_d0_bus.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 3 },
+};
+
+static struct clksrc_clk clk_div_apll2 = {
+       .clk    = {
+               .name   = "div_apll2",
+               .id     = -1,
+               .parent = &clk_mout_apll.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 3 },
+};
+
+static struct clk *clk_src_mout_am_list[] = {
+       [0] = &clk_mout_mpll.clk,
+       [1] = &clk_div_apll2.clk,
+};
+
+struct clksrc_sources clk_src_mout_am = {
+       .sources        = clk_src_mout_am_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_mout_am_list),
+};
+
+static struct clksrc_clk clk_mout_am = {
+       .clk    = {
+               .name   = "mout_am",
+               .id     = -1,
+       },
+       .sources = &clk_src_mout_am,
+       .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 1 },
+};
+
+static struct clksrc_clk clk_div_d1_bus = {
+       .clk    = {
+               .name   = "div_d1_bus",
+               .id     = -1,
+               .parent = &clk_mout_am.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 3 },
+};
+
+static struct clksrc_clk clk_div_mpll2 = {
+       .clk    = {
+               .name   = "div_mpll2",
+               .id     = -1,
+               .parent = &clk_mout_am.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV1, .shift = 8, .size = 1 },
+};
+
+static struct clksrc_clk clk_div_mpll = {
+       .clk    = {
+               .name   = "div_mpll",
+               .id     = -1,
+               .parent = &clk_mout_am.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV1, .shift = 4, .size = 2 },
+};
+
+static struct clk *clk_src_mout_onenand_list[] = {
+       [0] = &clk_div_d0_bus.clk,
+       [1] = &clk_div_d1_bus.clk,
+};
+
+struct clksrc_sources clk_src_mout_onenand = {
+       .sources        = clk_src_mout_onenand_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_mout_onenand_list),
+};
+
+static struct clksrc_clk clk_mout_onenand = {
+       .clk    = {
+               .name   = "mout_onenand",
+               .id     = -1,
+       },
+       .sources = &clk_src_mout_onenand,
+       .reg_src = { .reg = S5P_CLK_SRC0, .shift = 24, .size = 1 },
+};
+
+static struct clksrc_clk clk_div_onenand = {
+       .clk    = {
+               .name   = "div_onenand",
+               .id     = -1,
+               .parent = &clk_mout_onenand.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 2 },
+};
+
+static struct clksrc_clk clk_div_pclkd1 = {
+       .clk    = {
+               .name   = "div_pclkd1",
+               .id     = -1,
+               .parent = &clk_div_d1_bus.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV1, .shift = 16, .size = 3 },
+};
+
+static struct clksrc_clk clk_div_cam = {
+       .clk    = {
+               .name   = "div_cam",
+               .id     = -1,
+               .parent = &clk_div_mpll2.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV1, .shift = 24, .size = 5 },
+};
+
+static struct clksrc_clk clk_div_hdmi = {
+       .clk    = {
+               .name   = "div_hdmi",
+               .id     = -1,
+               .parent = &clk_mout_hpll.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV3, .shift = 28, .size = 4 },
+};
+
+static int s5pc100_epll_enable(struct clk *clk, int enable)
+{
+       unsigned int ctrlbit = clk->ctrlbit;
+       unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit;
+
+       if (enable)
+               __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON);
+       else
+               __raw_writel(epll_con, S5P_EPLL_CON);
+
+       return 0;
+}
+
+static unsigned long s5pc100_epll_get_rate(struct clk *clk)
+{
+       return clk->rate;
+}
+
+static u32 epll_div[][4] = {
+       { 32750000,     131, 3, 4 },
+       { 32768000,     131, 3, 4 },
+       { 36000000,     72,  3, 3 },
+       { 45000000,     90,  3, 3 },
+       { 45158000,     90,  3, 3 },
+       { 45158400,     90,  3, 3 },
+       { 48000000,     96,  3, 3 },
+       { 49125000,     131, 4, 3 },
+       { 49152000,     131, 4, 3 },
+       { 60000000,     120, 3, 3 },
+       { 67737600,     226, 5, 3 },
+       { 67738000,     226, 5, 3 },
+       { 73800000,     246, 5, 3 },
+       { 73728000,     246, 5, 3 },
+       { 72000000,     144, 3, 3 },
+       { 84000000,     168, 3, 3 },
+       { 96000000,     96,  3, 2 },
+       { 144000000,    144, 3, 2 },
+       { 192000000,    96,  3, 1 }
+};
+
+static int s5pc100_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+       unsigned int epll_con;
+       unsigned int i;
+
+       if (clk->rate == rate)  /* Return if nothing changed */
+               return 0;
+
+       epll_con = __raw_readl(S5P_EPLL_CON);
+
+       epll_con &= ~(PLL65XX_MDIV_MASK | PLL65XX_PDIV_MASK | PLL65XX_SDIV_MASK);
+
+       for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+               if (epll_div[i][0] == rate) {
+                       epll_con |= (epll_div[i][1] << PLL65XX_MDIV_SHIFT) |
+                                   (epll_div[i][2] << PLL65XX_PDIV_SHIFT) |
+                                   (epll_div[i][3] << PLL65XX_SDIV_SHIFT);
+                       break;
+               }
+       }
+
+       if (i == ARRAY_SIZE(epll_div)) {
+               printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
+               return -EINVAL;
+       }
+
+       __raw_writel(epll_con, S5P_EPLL_CON);
+
+       clk->rate = rate;
+
+       return 0;
+}
+
+static struct clk_ops s5pc100_epll_ops = {
+       .get_rate = s5pc100_epll_get_rate,
+       .set_rate = s5pc100_epll_set_rate,
+};
+
+static int s5pc100_d0_0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_D00, clk, enable);
+}
+
+static int s5pc100_d0_1_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_D01, clk, enable);
+}
+
+static int s5pc100_d0_2_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_D02, clk, enable);
+}
+
+static int s5pc100_d1_0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_D10, clk, enable);
+}
+
+static int s5pc100_d1_1_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_D11, clk, enable);
+}
+
+static int s5pc100_d1_2_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_D12, clk, enable);
+}
+
+static int s5pc100_d1_3_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_D13, clk, enable);
+}
+
+static int s5pc100_d1_4_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_D14, clk, enable);
+}
+
+static int s5pc100_d1_5_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_D15, clk, enable);
+}
+
+static int s5pc100_sclk0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_SCLK0, clk, enable);
+}
+
+static int s5pc100_sclk1_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_SCLK1, clk, enable);
+}
+
+/*
+ * The following clocks will be disabled during clock initialization. It is
+ * recommended to keep the following clocks disabled until the driver requests
+ * for enabling the clock.
+ */
+static struct clk init_clocks_disable[] = {
+       {
+               .name           = "cssys",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_0_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "secss",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_0_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "g2d",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_0_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "mdma",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_0_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "cfcon",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_0_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "nfcon",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_1_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "onenandc",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_1_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "sdm",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_2_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "seckey",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_2_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "hsmmc",
+               .id             = 2,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_0_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "hsmmc",
+               .id             = 1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_0_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "hsmmc",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_0_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "modemif",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_0_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "otg",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_0_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "usbhost",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_0_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "pdma",
+               .id             = 1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_0_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "pdma",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_0_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "lcd",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_1_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "rotator",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_1_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "fimc",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_1_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "fimc",
+               .id             = 1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_1_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "fimc",
+               .id             = 2,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_1_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "jpeg",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_1_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "mipi-dsim",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_1_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "mipi-csis",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_1_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "g3d",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_0_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "tv",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_2_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "vp",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_2_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "mixer",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_2_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "hdmi",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_2_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "mfc",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_2_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "apc",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_3_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "iec",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_3_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "systimer",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_3_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "watchdog",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_3_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "rtc",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_3_ctrl,
+               .ctrlbit        = (1 << 9),
+       }, {
+               .name           = "i2c",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "i2c",
+               .id             = 1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "spi",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "spi",
+               .id             = 1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "spi",
+               .id             = 2,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "irda",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 9),
+       }, {
+               .name           = "ccan",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 10),
+       }, {
+               .name           = "ccan",
+               .id             = 1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 11),
+       }, {
+               .name           = "hsitx",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 12),
+       }, {
+               .name           = "hsirx",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 13),
+       }, {
+               .name           = "iis",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_5_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "iis",
+               .id             = 1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_5_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "iis",
+               .id             = 2,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_5_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "ac97",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_5_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "pcm",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_5_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "pcm",
+               .id             = 1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_5_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "spdif",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_5_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "adc",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_5_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "keyif",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_5_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "spi_48m",
+               .id             = 0,
+               .parent         = &clk_mout_48m.clk,
+               .enable         = s5pc100_sclk0_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "spi_48m",
+               .id             = 1,
+               .parent         = &clk_mout_48m.clk,
+               .enable         = s5pc100_sclk0_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "spi_48m",
+               .id             = 2,
+               .parent         = &clk_mout_48m.clk,
+               .enable         = s5pc100_sclk0_ctrl,
+               .ctrlbit        = (1 << 9),
+       }, {
+               .name           = "mmc_48m",
+               .id             = 0,
+               .parent         = &clk_mout_48m.clk,
+               .enable         = s5pc100_sclk0_ctrl,
+               .ctrlbit        = (1 << 15),
+       }, {
+               .name           = "mmc_48m",
+               .id             = 1,
+               .parent         = &clk_mout_48m.clk,
+               .enable         = s5pc100_sclk0_ctrl,
+               .ctrlbit        = (1 << 16),
+       }, {
+               .name           = "mmc_48m",
+               .id             = 2,
+               .parent         = &clk_mout_48m.clk,
+               .enable         = s5pc100_sclk0_ctrl,
+               .ctrlbit        = (1 << 17),
+       },
+};
+
+static struct clk clk_vclk54m = {
+       .name           = "vclk_54m",
+       .id             = -1,
+       .rate           = 54000000,
+};
+
+static struct clk clk_i2scdclk0 = {
+       .name           = "i2s_cdclk0",
+       .id             = -1,
+};
+
+static struct clk clk_i2scdclk1 = {
+       .name           = "i2s_cdclk1",
+       .id             = -1,
+};
+
+static struct clk clk_i2scdclk2 = {
+       .name           = "i2s_cdclk2",
+       .id             = -1,
+};
+
+static struct clk clk_pcmcdclk0 = {
+       .name           = "pcm_cdclk0",
+       .id             = -1,
+};
+
+static struct clk clk_pcmcdclk1 = {
+       .name           = "pcm_cdclk1",
+       .id             = -1,
+};
+
+static struct clk *clk_src_group1_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_div_mpll2.clk,
+       [2] = &clk_fin_epll,
+       [3] = &clk_mout_hpll.clk,
+};
+
+struct clksrc_sources clk_src_group1 = {
+       .sources        = clk_src_group1_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_group1_list),
+};
+
+static struct clk *clk_src_group2_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_div_mpll.clk,
+};
+
+struct clksrc_sources clk_src_group2 = {
+       .sources        = clk_src_group2_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_group2_list),
+};
+
+static struct clk *clk_src_group3_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_div_mpll.clk,
+       [2] = &clk_fin_epll,
+       [3] = &clk_i2scdclk0,
+       [4] = &clk_pcmcdclk0,
+       [5] = &clk_mout_hpll.clk,
+};
+
+struct clksrc_sources clk_src_group3 = {
+       .sources        = clk_src_group3_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_group3_list),
+};
+
+static struct clk *clk_src_group4_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_div_mpll.clk,
+       [2] = &clk_fin_epll,
+       [3] = &clk_i2scdclk1,
+       [4] = &clk_pcmcdclk1,
+       [5] = &clk_mout_hpll.clk,
+};
+
+struct clksrc_sources clk_src_group4 = {
+       .sources        = clk_src_group4_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_group4_list),
+};
+
+static struct clk *clk_src_group5_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_div_mpll.clk,
+       [2] = &clk_fin_epll,
+       [3] = &clk_i2scdclk2,
+       [4] = &clk_mout_hpll.clk,
+};
+
+struct clksrc_sources clk_src_group5 = {
+       .sources        = clk_src_group5_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_group5_list),
+};
+
+static struct clk *clk_src_group6_list[] = {
+       [0] = &s5p_clk_27m,
+       [1] = &clk_vclk54m,
+       [2] = &clk_div_hdmi.clk,
+};
+
+struct clksrc_sources clk_src_group6 = {
+       .sources        = clk_src_group6_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_group6_list),
+};
+
+static struct clk *clk_src_group7_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_div_mpll.clk,
+       [2] = &clk_mout_hpll.clk,
+       [3] = &clk_vclk54m,
+};
+
+struct clksrc_sources clk_src_group7 = {
+       .sources        = clk_src_group7_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_group7_list),
+};
+
+static struct clk *clk_src_mmc0_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_div_mpll.clk,
+       [2] = &clk_fin_epll,
+};
+
+struct clksrc_sources clk_src_mmc0 = {
+       .sources        = clk_src_mmc0_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_mmc0_list),
+};
+
+static struct clk *clk_src_mmc12_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_div_mpll.clk,
+       [2] = &clk_fin_epll,
+       [3] = &clk_mout_hpll.clk,
+};
+
+struct clksrc_sources clk_src_mmc12 = {
+       .sources        = clk_src_mmc12_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_mmc12_list),
+};
+
+static struct clk *clk_src_irda_usb_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_div_mpll.clk,
+       [2] = &clk_fin_epll,
+       [3] = &clk_mout_hpll.clk,
+};
+
+struct clksrc_sources clk_src_irda_usb = {
+       .sources        = clk_src_irda_usb_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_irda_usb_list),
+};
+
+static struct clk *clk_src_pwi_list[] = {
+       [0] = &clk_fin_epll,
+       [1] = &clk_mout_epll.clk,
+       [2] = &clk_div_mpll.clk,
+};
+
+struct clksrc_sources clk_src_pwi = {
+       .sources        = clk_src_pwi_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_pwi_list),
+};
+
+static struct clksrc_clk clksrcs[] = {
+       {
+               .clk    = {
+                       .name           = "sclk_spi",
+                       .id             = 0,
+                       .ctrlbit        = (1 << 4),
+                       .enable         = s5pc100_sclk0_ctrl,
+
+               },
+               .sources = &clk_src_group1,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_spi",
+                       .id             = 1,
+                       .ctrlbit        = (1 << 5),
+                       .enable         = s5pc100_sclk0_ctrl,
+
+               },
+               .sources = &clk_src_group1,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_spi",
+                       .id             = 2,
+                       .ctrlbit        = (1 << 6),
+                       .enable         = s5pc100_sclk0_ctrl,
+
+               },
+               .sources = &clk_src_group1,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 12, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "uclk1",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 3),
+                       .enable         = s5pc100_sclk0_ctrl,
+
+               },
+               .sources = &clk_src_group2,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_mixer",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 6),
+                       .enable         = s5pc100_sclk0_ctrl,
+
+               },
+               .sources = &clk_src_group6,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 28, .size = 2 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_audio",
+                       .id             = 0,
+                       .ctrlbit        = (1 << 8),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_group3,
+               .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 3 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_audio",
+                       .id             = 1,
+                       .ctrlbit        = (1 << 9),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_group4,
+               .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 3 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_audio",
+                       .id             = 2,
+                       .ctrlbit        = (1 << 10),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_group5,
+               .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 3 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_lcd",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 0),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_group7,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 12, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimc",
+                       .id             = 0,
+                       .ctrlbit        = (1 << 1),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_group7,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 16, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 16, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimc",
+                       .id             = 1,
+                       .ctrlbit        = (1 << 2),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_group7,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 20, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 20, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimc",
+                       .id             = 2,
+                       .ctrlbit        = (1 << 3),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_group7,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 24, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 24, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "mmc_bus",
+                       .id             = 0,
+                       .ctrlbit        = (1 << 12),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_mmc0,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 0, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "mmc_bus",
+                       .id             = 1,
+                       .ctrlbit        = (1 << 13),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_mmc12,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 4, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "mmc_bus",
+                       .id             = 2,
+                       .ctrlbit        = (1 << 14),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_mmc12,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_irda",
+                       .id             = 2,
+                       .ctrlbit        = (1 << 10),
+                       .enable         = s5pc100_sclk0_ctrl,
+
+               },
+               .sources = &clk_src_irda_usb,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_irda",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 10),
+                       .enable         = s5pc100_sclk0_ctrl,
+
+               },
+               .sources = &clk_src_mmc12,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 16, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 16, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_pwi",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 1),
+                       .enable         = s5pc100_sclk0_ctrl,
+
+               },
+               .sources = &clk_src_pwi,
+               .reg_src = { .reg = S5P_CLK_SRC3, .shift = 0, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 3 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_uhost",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 11),
+                       .enable         = s5pc100_sclk0_ctrl,
+
+               },
+               .sources = &clk_src_irda_usb,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 20, .size = 4 },
+       },
+};
+
+/* Clock initialisation code */
+static struct clksrc_clk *sysclks[] = {
+       &clk_mout_apll,
+       &clk_mout_epll,
+       &clk_mout_mpll,
+       &clk_mout_hpll,
+       &clk_mout_href,
+       &clk_mout_48m,
+       &clk_div_apll,
+       &clk_div_arm,
+       &clk_div_d0_bus,
+       &clk_div_pclkd0,
+       &clk_div_secss,
+       &clk_div_apll2,
+       &clk_mout_am,
+       &clk_div_d1_bus,
+       &clk_div_mpll2,
+       &clk_div_mpll,
+       &clk_mout_onenand,
+       &clk_div_onenand,
+       &clk_div_pclkd1,
+       &clk_div_cam,
+       &clk_div_hdmi,
+};
+
+void __init_or_cpufreq s5pc100_setup_clocks(void)
+{
+       unsigned long xtal;
+       unsigned long arm;
+       unsigned long hclkd0;
+       unsigned long hclkd1;
+       unsigned long pclkd0;
+       unsigned long pclkd1;
+       unsigned long apll;
+       unsigned long mpll;
+       unsigned long epll;
+       unsigned long hpll;
+       unsigned int ptr;
+
+       /* Set S5PC100 functions for clk_fout_epll */
+       clk_fout_epll.enable = s5pc100_epll_enable;
+       clk_fout_epll.ops = &s5pc100_epll_ops;
+
+       printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+
+       xtal = clk_get_rate(&clk_xtal);
+
+       printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+
+       apll = s5p_get_pll65xx(xtal, __raw_readl(S5P_APLL_CON));
+       mpll = s5p_get_pll65xx(xtal, __raw_readl(S5P_MPLL_CON));
+       epll = s5p_get_pll65xx(xtal, __raw_readl(S5P_EPLL_CON));
+       hpll = s5p_get_pll65xx(xtal, __raw_readl(S5P_HPLL_CON));
+
+       printk(KERN_INFO "S5PC100: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz, E=%ld.%ldMHz, H=%ld.%ldMHz\n",
+                       print_mhz(apll), print_mhz(mpll), print_mhz(epll), print_mhz(hpll));
+
+       clk_fout_apll.rate = apll;
+       clk_fout_mpll.rate = mpll;
+       clk_fout_epll.rate = epll;
+       clk_mout_hpll.clk.rate = hpll;
+
+       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+               s3c_set_clksrc(&clksrcs[ptr], true);
+
+       arm = clk_get_rate(&clk_div_arm.clk);
+       hclkd0 = clk_get_rate(&clk_div_d0_bus.clk);
+       pclkd0 = clk_get_rate(&clk_div_pclkd0.clk);
+       hclkd1 = clk_get_rate(&clk_div_d1_bus.clk);
+       pclkd1 = clk_get_rate(&clk_div_pclkd1.clk);
+
+       printk(KERN_INFO "S5PC100: HCLKD0=%ld.%ldMHz, HCLKD1=%ld.%ldMHz, PCLKD0=%ld.%ldMHz, PCLKD1=%ld.%ldMHz\n",
+                       print_mhz(hclkd0), print_mhz(hclkd1), print_mhz(pclkd0), print_mhz(pclkd1));
+
+       clk_f.rate = arm;
+       clk_h.rate = hclkd1;
+       clk_p.rate = pclkd1;
+}
+
+/*
+ * The following clocks will be enabled during clock initialization.
+ */
+static struct clk init_clocks[] = {
+       {
+               .name           = "tzic",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_0_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "intc",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_0_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "ebi",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_1_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "intmem",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_1_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "sromc",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_1_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "dmc",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_1_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "chipid",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_1_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "gpio",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_3_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "uart",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "uart",
+               .id             = 1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "uart",
+               .id             = 2,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "uart",
+               .id             = 3,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "timers",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_3_ctrl,
+               .ctrlbit        = (1 << 6),
+       },
+};
+
+static struct clk *clks[] __initdata = {
+       &clk_ext,
+       &clk_i2scdclk0,
+       &clk_i2scdclk1,
+       &clk_i2scdclk2,
+       &clk_pcmcdclk0,
+       &clk_pcmcdclk1,
+};
+
+void __init s5pc100_register_clocks(void)
+{
+       struct clk *clkp;
+       int ret;
+       int ptr;
+
+       s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+       for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
+               s3c_register_clksrc(sysclks[ptr], 1);
+
+       s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+       s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+       clkp = init_clocks_disable;
+       for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+
+               ret = s3c24xx_register_clock(clkp);
+               if (ret < 0) {
+                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
+                              clkp->name, ret);
+               }
+               (clkp->enable)(clkp, 0);
+       }
+
+       s3c_pwmclk_init();
+}
similarity index 78%
rename from arch/arm/plat-s5pc1xx/gpiolib.c
rename to arch/arm/mach-s5pc100/gpiolib.c
index 1ffc57ac293d059ebb7bb9d9717a84f99cc42f27..c8e8336a3a127fd4e14ae356e69b2e09d23ea18b 100644 (file)
 #include <linux/gpio.h>
 
 #include <mach/map.h>
+#include <mach/regs-gpio.h>
 
 #include <plat/gpio-core.h>
 #include <plat/gpio-cfg.h>
 #include <plat/gpio-cfg-helpers.h>
-#include <plat/regs-gpio.h>
 
 /* S5PC100 GPIO bank summary:
  *
  * 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;
-}
-
+#if 0
 static int s5pc1xx_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
 {
        return S3C_IRQ_GPIO(chip->base + offset);
@@ -152,7 +85,7 @@ static int s5pc1xx_gpiolib_to_eint(struct gpio_chip *chip, unsigned int offset)
                return IRQ_EINT(24 + offset);
        return -EINVAL;
 }
-
+#endif
 static struct s3c_gpio_cfg gpio_cfg = {
        .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
        .set_pull       = s3c_gpio_setpull_updown,
@@ -452,12 +385,9 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
 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)
+static __init void s5pc100_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);
-
+#if 0
        /* Interrupt */
        if (chip->config == &gpio_cfg) {
                int i, irq;
@@ -473,31 +403,26 @@ static __init void s5pc1xx_gpiolib_link(struct s3c_gpio_chip *chip)
                }
        } 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);
-       }
+#endif
 }
 
 static __init int s5pc1xx_gpiolib_init(void)
 {
-       struct s3c_gpio_chip *chips;
+       struct s3c_gpio_chip *chip;
        int nr_chips;
 
-               chips = s5pc100_gpio_chips;
-               nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
+       chip = s5pc100_gpio_chips;
+       nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
+
+       for (; nr_chips > 0; nr_chips--, chip++)
+               s5pc100_gpiolib_link(chip);
 
-       s5pc1xx_gpiolib_add(chips, nr_chips, s5pc1xx_gpiolib_link);
+       samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips,
+                                      ARRAY_SIZE(s5pc100_gpio_chips));
+#if 0
        /* Interrupt */
        set_irq_chained_handler(IRQ_GPIOINT, s5pc1xx_irq_gpioint_handler);
-
+#endif
        return 0;
 }
 core_initcall(s5pc1xx_gpiolib_init);
index 2c4cbe8ee6b711da8786896d20bb489f4c4bc6a6..29a8a12d9b4f9046a4cce984917329b74683bf2b 100644 (file)
@@ -12,6 +12,9 @@
  * published by the Free Software Foundation.
 */
 
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H __FILE__
+
 #define gpio_get_value __gpio_get_value
 #define gpio_set_value __gpio_set_value
 #define gpio_cansleep  __gpio_cansleep
 #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 */
 
  * change from one gpio bank to another can be caught.
 */
 
-#define S5PC1XX_GPIO_NEXT(__gpio) \
+#define S5PC100_GPIO_NEXT(__gpio) \
        ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
 
-enum s3c_gpio_number {
+enum s5p_gpio_number {
        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),
+       S5PC100_GPIO_A1_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_A0),
+       S5PC100_GPIO_B_START    = S5PC100_GPIO_NEXT(S5PC100_GPIO_A1),
+       S5PC100_GPIO_C_START    = S5PC100_GPIO_NEXT(S5PC100_GPIO_B),
+       S5PC100_GPIO_D_START    = S5PC100_GPIO_NEXT(S5PC100_GPIO_C),
+       S5PC100_GPIO_E0_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_D),
+       S5PC100_GPIO_E1_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_E0),
+       S5PC100_GPIO_F0_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_E1),
+       S5PC100_GPIO_F1_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_F0),
+       S5PC100_GPIO_F2_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_F1),
+       S5PC100_GPIO_F3_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_F2),
+       S5PC100_GPIO_G0_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_F3),
+       S5PC100_GPIO_G1_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_G0),
+       S5PC100_GPIO_G2_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_G1),
+       S5PC100_GPIO_G3_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_G2),
+       S5PC100_GPIO_H0_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_G3),
+       S5PC100_GPIO_H1_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_H0),
+       S5PC100_GPIO_H2_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_H1),
+       S5PC100_GPIO_H3_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_H2),
+       S5PC100_GPIO_I_START    = S5PC100_GPIO_NEXT(S5PC100_GPIO_H3),
+       S5PC100_GPIO_J0_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_I),
+       S5PC100_GPIO_J1_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_J0),
+       S5PC100_GPIO_J2_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_J1),
+       S5PC100_GPIO_J3_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_J2),
+       S5PC100_GPIO_J4_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_J3),
+       S5PC100_GPIO_K0_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_J4),
+       S5PC100_GPIO_K1_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_K0),
+       S5PC100_GPIO_K2_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_K1),
+       S5PC100_GPIO_K3_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_K2),
+       S5PC100_GPIO_L0_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_K3),
+       S5PC100_GPIO_L1_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_L0),
+       S5PC100_GPIO_L2_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_L1),
+       S5PC100_GPIO_L3_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_L2),
+       S5PC100_GPIO_L4_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_L3),
+       S5PC100_GPIO_END        = S5PC100_GPIO_NEXT(S5PC100_GPIO_L4),
 };
 
 /* S5PC100 GPIO number definitions. */
@@ -146,17 +139,13 @@ enum s3c_gpio_number {
 #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 */
+/* It used the end of the S5PC100 gpios */
 #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          (S5PC100_GPIO_END + 1)
 
 #include <asm-generic/gpio.h>
+
+#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/regs-clock.h b/arch/arm/mach-s5pc100/include/mach/regs-clock.h
new file mode 100644 (file)
index 0000000..f2283bd
--- /dev/null
@@ -0,0 +1,71 @@
+/* linux/arch/arm/mach-s5pc100/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * S5PC100 - 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_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_CLKREG(x)          (S3C_VA_SYS + (x))
+
+#define S5P_APLL_LOCK          S5P_CLKREG(0x00)
+#define S5P_MPLL_LOCK          S5P_CLKREG(0x04)
+#define S5P_EPLL_LOCK          S5P_CLKREG(0x08)
+#define S5P_HPLL_LOCK          S5P_CLKREG(0x0C)
+
+#define S5P_APLL_CON           S5P_CLKREG(0x100)
+#define S5P_MPLL_CON           S5P_CLKREG(0x104)
+#define S5P_EPLL_CON           S5P_CLKREG(0x108)
+#define S5P_HPLL_CON           S5P_CLKREG(0x10C)
+
+#define S5P_CLK_SRC0           S5P_CLKREG(0x200)
+#define S5P_CLK_SRC1           S5P_CLKREG(0x204)
+#define S5P_CLK_SRC2           S5P_CLKREG(0x208)
+#define S5P_CLK_SRC3           S5P_CLKREG(0x20C)
+
+#define S5P_CLK_DIV0           S5P_CLKREG(0x300)
+#define S5P_CLK_DIV1           S5P_CLKREG(0x304)
+#define S5P_CLK_DIV2           S5P_CLKREG(0x308)
+#define S5P_CLK_DIV3           S5P_CLKREG(0x30C)
+#define S5P_CLK_DIV4           S5P_CLKREG(0x310)
+
+#define S5P_CLK_OUT            S5P_CLKREG(0x400)
+
+#define S5P_CLKGATE_D00                S5P_CLKREG(0x500)
+#define S5P_CLKGATE_D01                S5P_CLKREG(0x504)
+#define S5P_CLKGATE_D02                S5P_CLKREG(0x508)
+
+#define S5P_CLKGATE_D10                S5P_CLKREG(0x520)
+#define S5P_CLKGATE_D11                S5P_CLKREG(0x524)
+#define S5P_CLKGATE_D12                S5P_CLKREG(0x528)
+#define S5P_CLKGATE_D13                S5P_CLKREG(0x52C)
+#define S5P_CLKGATE_D14                S5P_CLKREG(0x530)
+#define S5P_CLKGATE_D15                S5P_CLKREG(0x534)
+
+#define S5P_CLKGATE_D20                S5P_CLKREG(0x540)
+
+#define S5P_CLKGATE_SCLK0      S5P_CLKREG(0x560)
+#define S5P_CLKGATE_SCLK1      S5P_CLKREG(0x564)
+
+/* CLKDIV0 */
+#define S5P_CLKDIV0_D0_MASK            (0x7<<8)
+#define S5P_CLKDIV0_D0_SHIFT           (8)
+#define S5P_CLKDIV0_PCLKD0_MASK                (0x7<<12)
+#define S5P_CLKDIV0_PCLKD0_SHIFT       (12)
+
+/* CLKDIV1 */
+#define S5P_CLKDIV1_D1_MASK            (0x7<<12)
+#define S5P_CLKDIV1_D1_SHIFT           (12)
+#define S5P_CLKDIV1_PCLKD1_MASK                (0x7<<16)
+#define S5P_CLKDIV1_PCLKD1_SHIFT       (16)
+
+#endif /* __ASM_ARCH_REGS_CLOCK_H */
similarity index 94%
rename from arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
rename to arch/arm/mach-s5pc100/include/mach/regs-gpio.h
index 43c7bc8bf7843637e351fed104eda3e62fdc6935..68666913354ce1f59e998915aa8913cdbf912a2d 100644 (file)
@@ -3,11 +3,11 @@
  * Copyright 2009 Samsung Electronics Co.
  *      Byungho Min <bhmin@samsung.com>
  *
- * S5PC1XX - GPIO register definitions
+ * S5PC100 - GPIO register definitions
  */
 
-#ifndef __ASM_PLAT_S5PC1XX_REGS_GPIO_H
-#define __ASM_PLAT_S5PC1XX_REGS_GPIO_H __FILE__
+#ifndef __ASM_MACH_S5PC100_REGS_GPIO_H
+#define __ASM_MACH_S5PC100_REGS_GPIO_H __FILE__
 
 #include <mach/map.h>
 
@@ -66,5 +66,5 @@
 #define S5PC100_GPx_OUTPUT(__gpio)     (0x1 << ((__gpio) * 4))
 #define S5PC100_GPx_CONMASK(__gpio)    (0xf << ((__gpio) * 4))
 
-#endif /* __ASM_PLAT_S5PC1XX_REGS_GPIO_H */
+#endif /* __ASM_MACH_S5PC100_REGS_GPIO_H */
 
index ae3c52cd0ebbcc70d0c955e744ca7efe6c8dfb15..bfe67db34f047ebd6c95d73c9bef8d5c77b5fb0c 100644 (file)
@@ -35,7 +35,6 @@
 
 #include <plat/regs-serial.h>
 #include <plat/gpio-cfg.h>
-#include <plat/regs-gpio.h>
 
 #include <plat/clock.h>
 #include <plat/devs.h>
similarity index 89%
rename from arch/arm/plat-s5pc1xx/setup-fb-24bpp.c
rename to arch/arm/mach-s5pc100/setup-fb-24bpp.c
index 1a63768a9a2eb429ceeaf30112373b4f17144b0d..6eba6cb8e2f486bc2445419ce4f2f149de1bcbf6 100644 (file)
@@ -1,9 +1,9 @@
 /*
- * linux/arch/arm/plat-s5pc100/setup-fb-24bpp.c
+ * linux/arch/arm/mach-s5pc100/setup-fb-24bpp.c
  *
  * Copyright 2009 Samsung Electronics
  *
- * Base S5PC1XX setup information for 24bpp LCD framebuffer
+ * Base S5PC100 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
@@ -19,7 +19,6 @@
 #include <mach/map.h>
 #include <plat/fb.h>
 #include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-s5pc1xx.h>
 
 #define DISR_OFFSET    0x7008
 
similarity index 89%
rename from arch/arm/plat-s5pc1xx/setup-i2c0.c
rename to arch/arm/mach-s5pc100/setup-i2c0.c
index 5e4a7c3a231e464b88fe637aea897ac3fced53dd..dd3174e6ecc59c123efd7c73a10c8d38cb817f9a 100644 (file)
@@ -1,9 +1,9 @@
-/* linux/arch/arm/plat-s5pc1xx/setup-i2c0.c
+/* linux/arch/arm/mach-s5pc100/setup-i2c0.c
  *
  * Copyright 2009 Samsung Electronics Co.
  *     Byungho Min <bhmin@samsung.com>
  *
- * Base S5PC1XX I2C bus 0 gpio configuration
+ * Base S5PC100 I2C bus 0 gpio configuration
  *
  * Based on plat-s3c64xx/setup-i2c0.c
  *
similarity index 89%
rename from arch/arm/plat-s5pc1xx/setup-i2c1.c
rename to arch/arm/mach-s5pc100/setup-i2c1.c
index a0a8b4ae6ad8e64a617faff004b5d75aecaedcf3..d1fec26b69eeab1470ac9059f91db9ea407d1585 100644 (file)
@@ -1,9 +1,9 @@
-/* linux/arch/arm/plat-s3c64xx/setup-i2c1.c
+/* linux/arch/arm/mach-s5pc100/setup-i2c1.c
  *
  * Copyright 2009 Samsung Electronics Co.
  *     Byungho Min <bhmin@samsung.com>
  *
- * Base S5PC1XX I2C bus 1 gpio configuration
+ * Base S5PC100 I2C bus 1 gpio configuration
  *
  * Based on plat-s3c64xx/setup-i2c1.c
  *
index af33a1a89b72d8b83b318bb8618e027d75ca3496..7601c28e240b9e32aa2a5c2550a93a37a539f6d1 100644 (file)
@@ -12,6 +12,7 @@ if ARCH_S5PV210
 config CPU_S5PV210
        bool
        select PLAT_S5P
+       select S3C_PL330_DMA
        help
          Enable S5PV210 CPU support
 
index 8ebf51c52a01931a6e62e0adc177d4c77544eeb6..99827813d293afc96b545aac1b6cffcf5f43524b 100644 (file)
@@ -12,9 +12,14 @@ obj-                         :=
 
 # Core support for S5PV210 system
 
-obj-$(CONFIG_CPU_S5PV210)      += cpu.o init.o clock.o
+obj-$(CONFIG_CPU_S5PV210)      += cpu.o init.o clock.o dma.o gpiolib.o
+obj-$(CONFIG_CPU_S5PV210)      += setup-i2c0.o
 
 # machine support
 
 obj-$(CONFIG_MACH_SMDKV210)    += mach-smdkv210.o
 obj-$(CONFIG_MACH_SMDKC110)    += mach-smdkc110.o
+
+# device support
+
+obj-y                          += dev-audio.o
index ccccae262351681024402270a87e624846e9862d..154bca4abc09c73a2ed960a28e2f6705dbd7765b 100644 (file)
 #include <plat/clock-clksrc.h>
 #include <plat/s5pv210.h>
 
+static struct clksrc_clk clk_mout_apll = {
+       .clk    = {
+               .name           = "mout_apll",
+               .id             = -1,
+       },
+       .sources        = &clk_src_apll,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
+};
+
+static struct clksrc_clk clk_mout_epll = {
+       .clk    = {
+               .name           = "mout_epll",
+               .id             = -1,
+       },
+       .sources        = &clk_src_epll,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
+};
+
+static struct clksrc_clk clk_mout_mpll = {
+       .clk = {
+               .name           = "mout_mpll",
+               .id             = -1,
+       },
+       .sources        = &clk_src_mpll,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 },
+};
+
+static struct clk *clkset_armclk_list[] = {
+       [0] = &clk_mout_apll.clk,
+       [1] = &clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources clkset_armclk = {
+       .sources        = clkset_armclk_list,
+       .nr_sources     = ARRAY_SIZE(clkset_armclk_list),
+};
+
+static struct clksrc_clk clk_armclk = {
+       .clk    = {
+               .name           = "armclk",
+               .id             = -1,
+       },
+       .sources        = &clkset_armclk,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 1 },
+       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk clk_hclk_msys = {
+       .clk    = {
+               .name           = "hclk_msys",
+               .id             = -1,
+               .parent         = &clk_armclk.clk,
+       },
+       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 3 },
+};
+
+static struct clksrc_clk clk_pclk_msys = {
+       .clk    = {
+               .name           = "pclk_msys",
+               .id             = -1,
+               .parent         = &clk_hclk_msys.clk,
+       },
+       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 3 },
+};
+
+static struct clksrc_clk clk_sclk_a2m = {
+       .clk    = {
+               .name           = "sclk_a2m",
+               .id             = -1,
+               .parent         = &clk_mout_apll.clk,
+       },
+       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 },
+};
+
+static struct clk *clkset_hclk_sys_list[] = {
+       [0] = &clk_mout_mpll.clk,
+       [1] = &clk_sclk_a2m.clk,
+};
+
+static struct clksrc_sources clkset_hclk_sys = {
+       .sources        = clkset_hclk_sys_list,
+       .nr_sources     = ARRAY_SIZE(clkset_hclk_sys_list),
+};
+
+static struct clksrc_clk clk_hclk_dsys = {
+       .clk    = {
+               .name   = "hclk_dsys",
+               .id     = -1,
+       },
+       .sources        = &clkset_hclk_sys,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 1 },
+       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk_dsys = {
+       .clk    = {
+               .name   = "pclk_dsys",
+               .id     = -1,
+               .parent = &clk_hclk_dsys.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV0, .shift = 20, .size = 3 },
+};
+
+static struct clksrc_clk clk_hclk_psys = {
+       .clk    = {
+               .name   = "hclk_psys",
+               .id     = -1,
+       },
+       .sources        = &clkset_hclk_sys,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 24, .size = 1 },
+       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 24, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk_psys = {
+       .clk    = {
+               .name   = "pclk_psys",
+               .id     = -1,
+               .parent = &clk_hclk_psys.clk,
+       },
+       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 28, .size = 3 },
+};
+
 static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable)
 {
        return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable);
@@ -51,176 +173,226 @@ static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable)
        return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
 }
 
-static struct clk clk_h200 = {
-       .name           = "hclk200",
+static int s5pv210_clk_ip4_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_IP4, clk, enable);
+}
+
+static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable);
+}
+
+static struct clk clk_sclk_hdmi27m = {
+       .name           = "sclk_hdmi27m",
        .id             = -1,
+       .rate           = 27000000,
 };
 
-static struct clk clk_h100 = {
-       .name           = "hclk100",
+static struct clk clk_sclk_hdmiphy = {
+       .name           = "sclk_hdmiphy",
        .id             = -1,
 };
 
-static struct clk clk_h166 = {
-       .name           = "hclk166",
+static struct clk clk_sclk_usbphy0 = {
+       .name           = "sclk_usbphy0",
        .id             = -1,
 };
 
-static struct clk clk_h133 = {
-       .name           = "hclk133",
+static struct clk clk_sclk_usbphy1 = {
+       .name           = "sclk_usbphy1",
        .id             = -1,
 };
 
-static struct clk clk_p100 = {
-       .name           = "pclk100",
+static struct clk clk_pcmcdclk0 = {
+       .name           = "pcmcdclk",
        .id             = -1,
 };
 
-static struct clk clk_p83 = {
-       .name           = "pclk83",
+static struct clk clk_pcmcdclk1 = {
+       .name           = "pcmcdclk",
        .id             = -1,
 };
 
-static struct clk clk_p66 = {
-       .name           = "pclk66",
+static struct clk clk_pcmcdclk2 = {
+       .name           = "pcmcdclk",
        .id             = -1,
 };
 
-static struct clk *sys_clks[] = {
-       &clk_h200,
-       &clk_h100,
-       &clk_h166,
-       &clk_h133,
-       &clk_p100,
-       &clk_p83,
-       &clk_p66
+static struct clk *clkset_vpllsrc_list[] = {
+       [0] = &clk_fin_vpll,
+       [1] = &clk_sclk_hdmi27m,
+};
+
+static struct clksrc_sources clkset_vpllsrc = {
+       .sources        = clkset_vpllsrc_list,
+       .nr_sources     = ARRAY_SIZE(clkset_vpllsrc_list),
+};
+
+static struct clksrc_clk clk_vpllsrc = {
+       .clk    = {
+               .name           = "vpll_src",
+               .id             = -1,
+               .enable         = s5pv210_clk_mask0_ctrl,
+               .ctrlbit        = (1 << 7),
+       },
+       .sources        = &clkset_vpllsrc,
+       .reg_src        = { .reg = S5P_CLK_SRC1, .shift = 28, .size = 1 },
+};
+
+static struct clk *clkset_sclk_vpll_list[] = {
+       [0] = &clk_vpllsrc.clk,
+       [1] = &clk_fout_vpll,
+};
+
+static struct clksrc_sources clkset_sclk_vpll = {
+       .sources        = clkset_sclk_vpll_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_vpll_list),
+};
+
+static struct clksrc_clk clk_sclk_vpll = {
+       .clk    = {
+               .name           = "sclk_vpll",
+               .id             = -1,
+       },
+       .sources        = &clkset_sclk_vpll,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 },
+};
+
+static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk)
+{
+       return clk_get_rate(clk->parent) / 2;
+}
+
+static struct clk_ops clk_hclk_imem_ops = {
+       .get_rate       = s5pv210_clk_imem_get_rate,
 };
 
 static struct clk init_clocks_disable[] = {
        {
                .name           = "rot",
                .id             = -1,
-               .parent         = &clk_h166,
+               .parent         = &clk_hclk_dsys.clk,
                .enable         = s5pv210_clk_ip0_ctrl,
                .ctrlbit        = (1<<29),
        }, {
                .name           = "otg",
                .id             = -1,
-               .parent         = &clk_h133,
+               .parent         = &clk_hclk_psys.clk,
                .enable         = s5pv210_clk_ip1_ctrl,
                .ctrlbit        = (1<<16),
        }, {
                .name           = "usb-host",
                .id             = -1,
-               .parent         = &clk_h133,
+               .parent         = &clk_hclk_psys.clk,
                .enable         = s5pv210_clk_ip1_ctrl,
                .ctrlbit        = (1<<17),
        }, {
                .name           = "lcd",
                .id             = -1,
-               .parent         = &clk_h166,
+               .parent         = &clk_hclk_dsys.clk,
                .enable         = s5pv210_clk_ip1_ctrl,
                .ctrlbit        = (1<<0),
        }, {
                .name           = "cfcon",
                .id             = 0,
-               .parent         = &clk_h133,
+               .parent         = &clk_hclk_psys.clk,
                .enable         = s5pv210_clk_ip1_ctrl,
                .ctrlbit        = (1<<25),
        }, {
                .name           = "hsmmc",
                .id             = 0,
-               .parent         = &clk_h133,
+               .parent         = &clk_hclk_psys.clk,
                .enable         = s5pv210_clk_ip2_ctrl,
                .ctrlbit        = (1<<16),
        }, {
                .name           = "hsmmc",
                .id             = 1,
-               .parent         = &clk_h133,
+               .parent         = &clk_hclk_psys.clk,
                .enable         = s5pv210_clk_ip2_ctrl,
                .ctrlbit        = (1<<17),
        }, {
                .name           = "hsmmc",
                .id             = 2,
-               .parent         = &clk_h133,
+               .parent         = &clk_hclk_psys.clk,
                .enable         = s5pv210_clk_ip2_ctrl,
                .ctrlbit        = (1<<18),
        }, {
                .name           = "hsmmc",
                .id             = 3,
-               .parent         = &clk_h133,
+               .parent         = &clk_hclk_psys.clk,
                .enable         = s5pv210_clk_ip2_ctrl,
                .ctrlbit        = (1<<19),
        }, {
                .name           = "systimer",
                .id             = -1,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<16),
        }, {
                .name           = "watchdog",
                .id             = -1,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<22),
        }, {
                .name           = "rtc",
                .id             = -1,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<15),
        }, {
                .name           = "i2c",
                .id             = 0,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<7),
        }, {
                .name           = "i2c",
                .id             = 1,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<8),
        }, {
                .name           = "i2c",
                .id             = 2,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<9),
        }, {
                .name           = "spi",
                .id             = 0,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<12),
        }, {
                .name           = "spi",
                .id             = 1,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<13),
        }, {
                .name           = "spi",
                .id             = 2,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<14),
        }, {
                .name           = "timers",
                .id             = -1,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<23),
        }, {
                .name           = "adc",
                .id             = -1,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<24),
        }, {
                .name           = "keypad",
                .id             = -1,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<21),
        }, {
@@ -246,106 +418,537 @@ static struct clk init_clocks_disable[] = {
 
 static struct clk init_clocks[] = {
        {
+               .name           = "hclk_imem",
+               .id             = -1,
+               .parent         = &clk_hclk_msys.clk,
+               .ctrlbit        = (1 << 5),
+               .enable         = s5pv210_clk_ip0_ctrl,
+               .ops            = &clk_hclk_imem_ops,
+       }, {
                .name           = "uart",
                .id             = 0,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<7),
        }, {
                .name           = "uart",
                .id             = 1,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<8),
        }, {
                .name           = "uart",
                .id             = 2,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<9),
        }, {
                .name           = "uart",
                .id             = 3,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<10),
        },
 };
 
-static struct clksrc_clk clk_mout_apll = {
-       .clk    = {
-               .name           = "mout_apll",
+static struct clk *clkset_uart_list[] = {
+       [6] = &clk_mout_mpll.clk,
+       [7] = &clk_mout_epll.clk,
+};
+
+static struct clksrc_sources clkset_uart = {
+       .sources        = clkset_uart_list,
+       .nr_sources     = ARRAY_SIZE(clkset_uart_list),
+};
+
+static struct clk *clkset_group1_list[] = {
+       [0] = &clk_sclk_a2m.clk,
+       [1] = &clk_mout_mpll.clk,
+       [2] = &clk_mout_epll.clk,
+       [3] = &clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources clkset_group1 = {
+       .sources        = clkset_group1_list,
+       .nr_sources     = ARRAY_SIZE(clkset_group1_list),
+};
+
+static struct clk *clkset_sclk_onenand_list[] = {
+       [0] = &clk_hclk_psys.clk,
+       [1] = &clk_hclk_dsys.clk,
+};
+
+static struct clksrc_sources clkset_sclk_onenand = {
+       .sources        = clkset_sclk_onenand_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_onenand_list),
+};
+
+static struct clk *clkset_sclk_dac_list[] = {
+       [0] = &clk_sclk_vpll.clk,
+       [1] = &clk_sclk_hdmiphy,
+};
+
+static struct clksrc_sources clkset_sclk_dac = {
+       .sources        = clkset_sclk_dac_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_dac_list),
+};
+
+static struct clksrc_clk clk_sclk_dac = {
+       .clk            = {
+               .name           = "sclk_dac",
                .id             = -1,
+               .ctrlbit        = (1 << 10),
+               .enable         = s5pv210_clk_ip1_ctrl,
        },
-       .sources        = &clk_src_apll,
-       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
+       .sources        = &clkset_sclk_dac,
+       .reg_src        = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 1 },
 };
 
-static struct clksrc_clk clk_mout_epll = {
-       .clk    = {
-               .name           = "mout_epll",
+static struct clksrc_clk clk_sclk_pixel = {
+       .clk            = {
+               .name           = "sclk_pixel",
                .id             = -1,
+               .parent         = &clk_sclk_vpll.clk,
        },
-       .sources        = &clk_src_epll,
-       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
+       .reg_div        = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4},
 };
 
-static struct clksrc_clk clk_mout_mpll = {
-       .clk = {
-               .name           = "mout_mpll",
+static struct clk *clkset_sclk_hdmi_list[] = {
+       [0] = &clk_sclk_pixel.clk,
+       [1] = &clk_sclk_hdmiphy,
+};
+
+static struct clksrc_sources clkset_sclk_hdmi = {
+       .sources        = clkset_sclk_hdmi_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_hdmi_list),
+};
+
+static struct clksrc_clk clk_sclk_hdmi = {
+       .clk            = {
+               .name           = "sclk_hdmi",
                .id             = -1,
+               .enable         = s5pv210_clk_ip1_ctrl,
+               .ctrlbit        = (1 << 11),
        },
-       .sources        = &clk_src_mpll,
-       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 },
+       .sources        = &clkset_sclk_hdmi,
+       .reg_src        = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
 };
 
-static struct clk *clkset_uart_list[] = {
+static struct clk *clkset_sclk_mixer_list[] = {
+       [0] = &clk_sclk_dac.clk,
+       [1] = &clk_sclk_hdmi.clk,
+};
+
+static struct clksrc_sources clkset_sclk_mixer = {
+       .sources        = clkset_sclk_mixer_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_mixer_list),
+};
+
+static struct clk *clkset_sclk_audio0_list[] = {
+       [0] = &clk_ext_xtal_mux,
+       [1] = &clk_pcmcdclk0,
+       [2] = &clk_sclk_hdmi27m,
+       [3] = &clk_sclk_usbphy0,
+       [4] = &clk_sclk_usbphy1,
+       [5] = &clk_sclk_hdmiphy,
        [6] = &clk_mout_mpll.clk,
        [7] = &clk_mout_epll.clk,
+       [8] = &clk_sclk_vpll.clk,
 };
 
-static struct clksrc_sources clkset_uart = {
-       .sources        = clkset_uart_list,
-       .nr_sources     = ARRAY_SIZE(clkset_uart_list),
+static struct clksrc_sources clkset_sclk_audio0 = {
+       .sources        = clkset_sclk_audio0_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_audio0_list),
+};
+
+static struct clksrc_clk clk_sclk_audio0 = {
+       .clk            = {
+               .name           = "sclk_audio",
+               .id             = 0,
+               .enable         = s5pv210_clk_ip3_ctrl,
+               .ctrlbit        = (1 << 4),
+       },
+       .sources = &clkset_sclk_audio0,
+       .reg_src = { .reg = S5P_CLK_SRC6, .shift = 0, .size = 4 },
+       .reg_div = { .reg = S5P_CLK_DIV6, .shift = 0, .size = 4 },
+};
+
+static struct clk *clkset_sclk_audio1_list[] = {
+       [0] = &clk_ext_xtal_mux,
+       [1] = &clk_pcmcdclk1,
+       [2] = &clk_sclk_hdmi27m,
+       [3] = &clk_sclk_usbphy0,
+       [4] = &clk_sclk_usbphy1,
+       [5] = &clk_sclk_hdmiphy,
+       [6] = &clk_mout_mpll.clk,
+       [7] = &clk_mout_epll.clk,
+       [8] = &clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources clkset_sclk_audio1 = {
+       .sources        = clkset_sclk_audio1_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_audio1_list),
+};
+
+static struct clksrc_clk clk_sclk_audio1 = {
+       .clk            = {
+               .name           = "sclk_audio",
+               .id             = 1,
+               .enable         = s5pv210_clk_ip3_ctrl,
+               .ctrlbit        = (1 << 5),
+       },
+       .sources = &clkset_sclk_audio1,
+       .reg_src = { .reg = S5P_CLK_SRC6, .shift = 4, .size = 4 },
+       .reg_div = { .reg = S5P_CLK_DIV6, .shift = 4, .size = 4 },
+};
+
+static struct clk *clkset_sclk_audio2_list[] = {
+       [0] = &clk_ext_xtal_mux,
+       [1] = &clk_pcmcdclk0,
+       [2] = &clk_sclk_hdmi27m,
+       [3] = &clk_sclk_usbphy0,
+       [4] = &clk_sclk_usbphy1,
+       [5] = &clk_sclk_hdmiphy,
+       [6] = &clk_mout_mpll.clk,
+       [7] = &clk_mout_epll.clk,
+       [8] = &clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources clkset_sclk_audio2 = {
+       .sources        = clkset_sclk_audio2_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_audio2_list),
+};
+
+static struct clksrc_clk clk_sclk_audio2 = {
+       .clk            = {
+               .name           = "sclk_audio",
+               .id             = 2,
+               .enable         = s5pv210_clk_ip3_ctrl,
+               .ctrlbit        = (1 << 6),
+       },
+       .sources = &clkset_sclk_audio2,
+       .reg_src = { .reg = S5P_CLK_SRC6, .shift = 8, .size = 4 },
+       .reg_div = { .reg = S5P_CLK_DIV6, .shift = 8, .size = 4 },
+};
+
+static struct clk *clkset_sclk_spdif_list[] = {
+       [0] = &clk_sclk_audio0.clk,
+       [1] = &clk_sclk_audio1.clk,
+       [2] = &clk_sclk_audio2.clk,
+};
+
+static struct clksrc_sources clkset_sclk_spdif = {
+       .sources        = clkset_sclk_spdif_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_spdif_list),
+};
+
+static struct clk *clkset_group2_list[] = {
+       [0] = &clk_ext_xtal_mux,
+       [1] = &clk_xusbxti,
+       [2] = &clk_sclk_hdmi27m,
+       [3] = &clk_sclk_usbphy0,
+       [4] = &clk_sclk_usbphy1,
+       [5] = &clk_sclk_hdmiphy,
+       [6] = &clk_mout_mpll.clk,
+       [7] = &clk_mout_epll.clk,
+       [8] = &clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources clkset_group2 = {
+       .sources        = clkset_group2_list,
+       .nr_sources     = ARRAY_SIZE(clkset_group2_list),
 };
 
 static struct clksrc_clk clksrcs[] = {
        {
                .clk    = {
-                       .name           = "uclk1",
+                       .name           = "sclk_dmc",
                        .id             = -1,
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_onenand",
+                       .id             = -1,
+               },
+               .sources = &clkset_sclk_onenand,
+               .reg_src = { .reg = S5P_CLK_SRC0, .shift = 28, .size = 1 },
+               .reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 },
+       }, {
+               .clk    = {
+                       .name           = "uclk1",
+                       .id             = 0,
                        .ctrlbit        = (1<<17),
                        .enable         = s5pv210_clk_ip3_ctrl,
                },
                .sources = &clkset_uart,
                .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
                .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
-       }
+       }, {
+               .clk            = {
+                       .name           = "uclk1",
+                       .id             = 1,
+                       .enable         = s5pv210_clk_ip3_ctrl,
+                       .ctrlbit        = (1 << 18),
+               },
+               .sources = &clkset_uart,
+               .reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "uclk1",
+                       .id             = 2,
+                       .enable         = s5pv210_clk_ip3_ctrl,
+                       .ctrlbit        = (1 << 19),
+               },
+               .sources = &clkset_uart,
+               .reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "uclk1",
+                       .id             = 3,
+                       .enable         = s5pv210_clk_ip3_ctrl,
+                       .ctrlbit        = (1 << 20),
+               },
+               .sources = &clkset_uart,
+               .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_mixer",
+                       .id             = -1,
+                       .enable         = s5pv210_clk_ip1_ctrl,
+                       .ctrlbit        = (1 << 9),
+               },
+               .sources = &clkset_sclk_mixer,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_spdif",
+                       .id             = -1,
+                       .enable         = s5pv210_clk_mask0_ctrl,
+                       .ctrlbit        = (1 << 27),
+               },
+               .sources = &clkset_sclk_spdif,
+               .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimc",
+                       .id             = 0,
+                       .enable         = s5pv210_clk_ip0_ctrl,
+                       .ctrlbit        = (1 << 24),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimc",
+                       .id             = 1,
+                       .enable         = s5pv210_clk_ip0_ctrl,
+                       .ctrlbit        = (1 << 25),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 16, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimc",
+                       .id             = 2,
+                       .enable         = s5pv210_clk_ip0_ctrl,
+                       .ctrlbit        = (1 << 26),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 20, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_cam",
+                       .id             = 0,
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_cam",
+                       .id             = 1,
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 16, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV1, .shift = 16, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_fimd",
+                       .id             = -1,
+                       .enable         = s5pv210_clk_ip1_ctrl,
+                       .ctrlbit        = (1 << 0),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mmc",
+                       .id             = 0,
+                       .enable         = s5pv210_clk_ip2_ctrl,
+                       .ctrlbit        = (1 << 16),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mmc",
+                       .id             = 1,
+                       .enable         = s5pv210_clk_ip2_ctrl,
+                       .ctrlbit        = (1 << 17),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 4, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mmc",
+                       .id             = 2,
+                       .enable         = s5pv210_clk_ip2_ctrl,
+                       .ctrlbit        = (1 << 18),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 8, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mmc",
+                       .id             = 3,
+                       .enable         = s5pv210_clk_ip2_ctrl,
+                       .ctrlbit        = (1 << 19),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mfc",
+                       .id             = -1,
+                       .enable         = s5pv210_clk_ip0_ctrl,
+                       .ctrlbit        = (1 << 16),
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_g2d",
+                       .id             = -1,
+                       .enable         = s5pv210_clk_ip0_ctrl,
+                       .ctrlbit        = (1 << 12),
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_g3d",
+                       .id             = -1,
+                       .enable         = s5pv210_clk_ip0_ctrl,
+                       .ctrlbit        = (1 << 8),
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_csis",
+                       .id             = -1,
+                       .enable         = s5pv210_clk_ip0_ctrl,
+                       .ctrlbit        = (1 << 31),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 24, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV1, .shift = 28, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_spi",
+                       .id             = 0,
+                       .enable         = s5pv210_clk_ip3_ctrl,
+                       .ctrlbit        = (1 << 12),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV5, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_spi",
+                       .id             = 1,
+                       .enable         = s5pv210_clk_ip3_ctrl,
+                       .ctrlbit        = (1 << 13),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV5, .shift = 4, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_pwi",
+                       .id             = -1,
+                       .enable         = &s5pv210_clk_ip4_ctrl,
+                       .ctrlbit        = (1 << 2),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC6, .shift = 20, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV6, .shift = 24, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_pwm",
+                       .id             = -1,
+                       .enable         = s5pv210_clk_ip3_ctrl,
+                       .ctrlbit        = (1 << 23),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC5, .shift = 12, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV5, .shift = 12, .size = 4 },
+       },
 };
 
 /* Clock initialisation code */
-static struct clksrc_clk *init_parents[] = {
+static struct clksrc_clk *sysclks[] = {
        &clk_mout_apll,
        &clk_mout_epll,
        &clk_mout_mpll,
+       &clk_armclk,
+       &clk_hclk_msys,
+       &clk_sclk_a2m,
+       &clk_hclk_dsys,
+       &clk_hclk_psys,
+       &clk_pclk_msys,
+       &clk_pclk_dsys,
+       &clk_pclk_psys,
+       &clk_vpllsrc,
+       &clk_sclk_vpll,
+       &clk_sclk_dac,
+       &clk_sclk_pixel,
+       &clk_sclk_hdmi,
 };
 
-#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
-
 void __init_or_cpufreq s5pv210_setup_clocks(void)
 {
        struct clk *xtal_clk;
        unsigned long xtal;
+       unsigned long vpllsrc;
        unsigned long armclk;
-       unsigned long hclk200;
-       unsigned long hclk166;
-       unsigned long hclk133;
-       unsigned long pclk100;
-       unsigned long pclk83;
-       unsigned long pclk66;
+       unsigned long hclk_msys;
+       unsigned long hclk_dsys;
+       unsigned long hclk_psys;
+       unsigned long pclk_msys;
+       unsigned long pclk_dsys;
+       unsigned long pclk_psys;
        unsigned long apll;
        unsigned long mpll;
        unsigned long epll;
+       unsigned long vpll;
        unsigned int ptr;
        u32 clkdiv0, clkdiv1;
 
@@ -368,59 +971,46 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
        apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
        mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
        epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500);
-
-       printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld",
-                       apll, mpll, epll);
-
-       armclk = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_APLL);
-       if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX200_MASK)
-               hclk200 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK200);
-       else
-               hclk200 = armclk / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK200);
-
-       if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX166_MASK) {
-               hclk166 = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_A2M);
-               hclk166 = hclk166 / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK166);
-       } else
-               hclk166 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK166);
-
-       if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX133_MASK) {
-               hclk133 = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_A2M);
-               hclk133 = hclk133 / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK133);
-       } else
-               hclk133 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK133);
-
-       pclk100 = hclk200 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK100);
-       pclk83 = hclk166 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK83);
-       pclk66 = hclk133 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK66);
-
-       printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld, \
-                       HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n",
-              armclk, hclk200, hclk166, hclk133, pclk100, pclk83, pclk66);
+       vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
+       vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502);
 
        clk_fout_apll.rate = apll;
        clk_fout_mpll.rate = mpll;
        clk_fout_epll.rate = epll;
+       clk_fout_vpll.rate = vpll;
 
-       clk_f.rate = armclk;
-       clk_h.rate = hclk133;
-       clk_p.rate = pclk66;
-       clk_p66.rate = pclk66;
-       clk_p83.rate = pclk83;
-       clk_h133.rate = hclk133;
-       clk_h166.rate = hclk166;
-       clk_h200.rate = hclk200;
+       printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
+                       apll, mpll, epll, vpll);
+
+       armclk = clk_get_rate(&clk_armclk.clk);
+       hclk_msys = clk_get_rate(&clk_hclk_msys.clk);
+       hclk_dsys = clk_get_rate(&clk_hclk_dsys.clk);
+       hclk_psys = clk_get_rate(&clk_hclk_psys.clk);
+       pclk_msys = clk_get_rate(&clk_pclk_msys.clk);
+       pclk_dsys = clk_get_rate(&clk_pclk_dsys.clk);
+       pclk_psys = clk_get_rate(&clk_pclk_psys.clk);
+
+       printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld\n"
+                        "HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n",
+                       armclk, hclk_msys, hclk_dsys, hclk_psys,
+                       pclk_msys, pclk_dsys, pclk_psys);
 
-       for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
-               s3c_set_clksrc(init_parents[ptr], true);
+       clk_f.rate = armclk;
+       clk_h.rate = hclk_psys;
+       clk_p.rate = pclk_psys;
 
        for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
                s3c_set_clksrc(&clksrcs[ptr], true);
 }
 
 static struct clk *clks[] __initdata = {
-       &clk_mout_epll.clk,
-       &clk_mout_mpll.clk,
+       &clk_sclk_hdmi27m,
+       &clk_sclk_hdmiphy,
+       &clk_sclk_usbphy0,
+       &clk_sclk_usbphy1,
+       &clk_pcmcdclk0,
+       &clk_pcmcdclk1,
+       &clk_pcmcdclk2,
 };
 
 void __init s5pv210_register_clocks(void)
@@ -433,13 +1023,12 @@ void __init s5pv210_register_clocks(void)
        if (ret > 0)
                printk(KERN_ERR "Failed to register %u clocks\n", ret);
 
+       for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
+               s3c_register_clksrc(sysclks[ptr], 1);
+
        s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
        s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
 
-       ret = s3c24xx_register_clocks(sys_clks, ARRAY_SIZE(sys_clks));
-       if (ret > 0)
-               printk(KERN_ERR "Failed to register system clocks\n");
-
        clkp = init_clocks_disable;
        for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
                ret = s3c24xx_register_clock(clkp);
index 0e0f8fde2aa637ad470f76092230cf7fceb03c9b..2b776eb5d150367dea5a20ffae96c6a6c516e354 100644 (file)
@@ -100,7 +100,7 @@ void __init s5pv210_init_irq(void)
        s5p_init_irq(vic, ARRAY_SIZE(vic));
 }
 
-static struct sysdev_class s5pv210_sysclass = {
+struct sysdev_class s5pv210_sysclass = {
        .name   = "s5pv210-core",
 };
 
diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c
new file mode 100644 (file)
index 0000000..6e21533
--- /dev/null
@@ -0,0 +1,327 @@
+/* linux/arch/arm/mach-s5pv210/dev-audio.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. Ltd
+ *     Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/audio.h>
+
+#include <mach/gpio.h>
+#include <mach/map.h>
+#include <mach/dma.h>
+#include <mach/irqs.h>
+
+static int s5pv210_cfg_i2s(struct platform_device *pdev)
+{
+       /* configure GPIO for i2s port */
+       switch (pdev->id) {
+       case 1:
+               s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(2));
+               break;
+
+       case 2:
+               s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(4));
+               s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(4));
+               s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(4));
+               s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(4));
+               s3c_gpio_cfgpin(S5PV210_GPC1(4), S3C_GPIO_SFN(4));
+               break;
+
+       case -1:
+               s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPI(5), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPI(6), S3C_GPIO_SFN(2));
+               break;
+
+       default:
+               printk(KERN_ERR "Invalid Device %d\n", pdev->id);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct s3c_audio_pdata s3c_i2s_pdata = {
+       .cfg_gpio = s5pv210_cfg_i2s,
+};
+
+static struct resource s5pv210_iis0_resource[] = {
+       [0] = {
+               .start = S5PV210_PA_IIS0,
+               .end   = S5PV210_PA_IIS0 + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_I2S0_TX,
+               .end   = DMACH_I2S0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_I2S0_RX,
+               .end   = DMACH_I2S0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5pv210_device_iis0 = {
+       .name             = "s3c64xx-iis-v4",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(s5pv210_iis0_resource),
+       .resource         = s5pv210_iis0_resource,
+       .dev = {
+               .platform_data = &s3c_i2s_pdata,
+       },
+};
+
+static struct resource s5pv210_iis1_resource[] = {
+       [0] = {
+               .start = S5PV210_PA_IIS1,
+               .end   = S5PV210_PA_IIS1 + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_I2S1_TX,
+               .end   = DMACH_I2S1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_I2S1_RX,
+               .end   = DMACH_I2S1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5pv210_device_iis1 = {
+       .name             = "s3c64xx-iis",
+       .id               = 1,
+       .num_resources    = ARRAY_SIZE(s5pv210_iis1_resource),
+       .resource         = s5pv210_iis1_resource,
+       .dev = {
+               .platform_data = &s3c_i2s_pdata,
+       },
+};
+
+static struct resource s5pv210_iis2_resource[] = {
+       [0] = {
+               .start = S5PV210_PA_IIS2,
+               .end   = S5PV210_PA_IIS2 + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_I2S2_TX,
+               .end   = DMACH_I2S2_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_I2S2_RX,
+               .end   = DMACH_I2S2_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5pv210_device_iis2 = {
+       .name             = "s3c64xx-iis",
+       .id               = 2,
+       .num_resources    = ARRAY_SIZE(s5pv210_iis2_resource),
+       .resource         = s5pv210_iis2_resource,
+       .dev = {
+               .platform_data = &s3c_i2s_pdata,
+       },
+};
+
+/* PCM Controller platform_devices */
+
+static int s5pv210_pcm_cfg_gpio(struct platform_device *pdev)
+{
+       switch (pdev->id) {
+       case 0:
+               s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(3));
+               break;
+       case 1:
+               s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(3));
+               break;
+       case 2:
+               s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPC1(4), S3C_GPIO_SFN(2));
+               break;
+       default:
+               printk(KERN_DEBUG "Invalid PCM Controller number!");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct s3c_audio_pdata s3c_pcm_pdata = {
+       .cfg_gpio = s5pv210_pcm_cfg_gpio,
+};
+
+static struct resource s5pv210_pcm0_resource[] = {
+       [0] = {
+               .start = S5PV210_PA_PCM0,
+               .end   = S5PV210_PA_PCM0 + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_PCM0_TX,
+               .end   = DMACH_PCM0_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_PCM0_RX,
+               .end   = DMACH_PCM0_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5pv210_device_pcm0 = {
+       .name             = "samsung-pcm",
+       .id               = 0,
+       .num_resources    = ARRAY_SIZE(s5pv210_pcm0_resource),
+       .resource         = s5pv210_pcm0_resource,
+       .dev = {
+               .platform_data = &s3c_pcm_pdata,
+       },
+};
+
+static struct resource s5pv210_pcm1_resource[] = {
+       [0] = {
+               .start = S5PV210_PA_PCM1,
+               .end   = S5PV210_PA_PCM1 + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_PCM1_TX,
+               .end   = DMACH_PCM1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_PCM1_RX,
+               .end   = DMACH_PCM1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5pv210_device_pcm1 = {
+       .name             = "samsung-pcm",
+       .id               = 1,
+       .num_resources    = ARRAY_SIZE(s5pv210_pcm1_resource),
+       .resource         = s5pv210_pcm1_resource,
+       .dev = {
+               .platform_data = &s3c_pcm_pdata,
+       },
+};
+
+static struct resource s5pv210_pcm2_resource[] = {
+       [0] = {
+               .start = S5PV210_PA_PCM2,
+               .end   = S5PV210_PA_PCM2 + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_PCM2_TX,
+               .end   = DMACH_PCM2_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_PCM2_RX,
+               .end   = DMACH_PCM2_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5pv210_device_pcm2 = {
+       .name             = "samsung-pcm",
+       .id               = 2,
+       .num_resources    = ARRAY_SIZE(s5pv210_pcm2_resource),
+       .resource         = s5pv210_pcm2_resource,
+       .dev = {
+               .platform_data = &s3c_pcm_pdata,
+       },
+};
+
+/* AC97 Controller platform devices */
+
+static int s5pv210_ac97_cfg_gpio(struct platform_device *pdev)
+{
+       s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(4));
+       s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(4));
+       s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(4));
+       s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(4));
+       s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(4));
+
+       return 0;
+}
+
+static struct resource s5pv210_ac97_resource[] = {
+       [0] = {
+               .start = S5PV210_PA_AC97,
+               .end   = S5PV210_PA_AC97 + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_AC97_PCMOUT,
+               .end   = DMACH_AC97_PCMOUT,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_AC97_PCMIN,
+               .end   = DMACH_AC97_PCMIN,
+               .flags = IORESOURCE_DMA,
+       },
+       [3] = {
+               .start = DMACH_AC97_MICIN,
+               .end   = DMACH_AC97_MICIN,
+               .flags = IORESOURCE_DMA,
+       },
+       [4] = {
+               .start = IRQ_AC97,
+               .end   = IRQ_AC97,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct s3c_audio_pdata s3c_ac97_pdata = {
+       .cfg_gpio = s5pv210_ac97_cfg_gpio,
+};
+
+static u64 s5pv210_ac97_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5pv210_device_ac97 = {
+       .name             = "s3c-ac97",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(s5pv210_ac97_resource),
+       .resource         = s5pv210_ac97_resource,
+       .dev = {
+               .platform_data = &s3c_ac97_pdata,
+               .dma_mask = &s5pv210_ac97_dmamask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+       },
+};
diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c
new file mode 100644 (file)
index 0000000..778ad5f
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ *     Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <plat/devs.h>
+#include <plat/irqs.h>
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+
+#include <plat/s3c-pl330-pdata.h>
+
+static u64 dma_dmamask = DMA_BIT_MASK(32);
+
+static struct resource s5pv210_pdma0_resource[] = {
+       [0] = {
+               .start  = S5PV210_PA_PDMA0,
+               .end    = S5PV210_PA_PDMA0 + SZ_4K,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_PDMA0,
+               .end    = IRQ_PDMA0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct s3c_pl330_platdata s5pv210_pdma0_pdata = {
+       .peri = {
+               [0] = DMACH_UART0_RX,
+               [1] = DMACH_UART0_TX,
+               [2] = DMACH_UART1_RX,
+               [3] = DMACH_UART1_TX,
+               [4] = DMACH_UART2_RX,
+               [5] = DMACH_UART2_TX,
+               [6] = DMACH_UART3_RX,
+               [7] = DMACH_UART3_TX,
+               [8] = DMACH_MAX,
+               [9] = DMACH_I2S0_RX,
+               [10] = DMACH_I2S0_TX,
+               [11] = DMACH_I2S0S_TX,
+               [12] = DMACH_I2S1_RX,
+               [13] = DMACH_I2S1_TX,
+               [14] = DMACH_MAX,
+               [15] = DMACH_MAX,
+               [16] = DMACH_SPI0_RX,
+               [17] = DMACH_SPI0_TX,
+               [18] = DMACH_SPI1_RX,
+               [19] = DMACH_SPI1_TX,
+               [20] = DMACH_MAX,
+               [21] = DMACH_MAX,
+               [22] = DMACH_AC97_MICIN,
+               [23] = DMACH_AC97_PCMIN,
+               [24] = DMACH_AC97_PCMOUT,
+               [25] = DMACH_MAX,
+               [26] = DMACH_PWM,
+               [27] = DMACH_SPDIF,
+               [28] = DMACH_MAX,
+               [29] = DMACH_MAX,
+               [30] = DMACH_MAX,
+               [31] = DMACH_MAX,
+       },
+};
+
+static struct platform_device s5pv210_device_pdma0 = {
+       .name           = "s3c-pl330",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(s5pv210_pdma0_resource),
+       .resource       = s5pv210_pdma0_resource,
+       .dev            = {
+               .dma_mask = &dma_dmamask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+               .platform_data = &s5pv210_pdma0_pdata,
+       },
+};
+
+static struct resource s5pv210_pdma1_resource[] = {
+       [0] = {
+               .start  = S5PV210_PA_PDMA1,
+               .end    = S5PV210_PA_PDMA1 + SZ_4K,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_PDMA1,
+               .end    = IRQ_PDMA1,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct s3c_pl330_platdata s5pv210_pdma1_pdata = {
+       .peri = {
+               [0] = DMACH_UART0_RX,
+               [1] = DMACH_UART0_TX,
+               [2] = DMACH_UART1_RX,
+               [3] = DMACH_UART1_TX,
+               [4] = DMACH_UART2_RX,
+               [5] = DMACH_UART2_TX,
+               [6] = DMACH_UART3_RX,
+               [7] = DMACH_UART3_TX,
+               [8] = DMACH_MAX,
+               [9] = DMACH_I2S0_RX,
+               [10] = DMACH_I2S0_TX,
+               [11] = DMACH_I2S0S_TX,
+               [12] = DMACH_I2S1_RX,
+               [13] = DMACH_I2S1_TX,
+               [14] = DMACH_I2S2_RX,
+               [15] = DMACH_I2S2_TX,
+               [16] = DMACH_SPI0_RX,
+               [17] = DMACH_SPI0_TX,
+               [18] = DMACH_SPI1_RX,
+               [19] = DMACH_SPI1_TX,
+               [20] = DMACH_MAX,
+               [21] = DMACH_MAX,
+               [22] = DMACH_PCM0_RX,
+               [23] = DMACH_PCM0_TX,
+               [24] = DMACH_PCM1_RX,
+               [25] = DMACH_PCM1_TX,
+               [26] = DMACH_MSM_REQ0,
+               [27] = DMACH_MSM_REQ1,
+               [28] = DMACH_MSM_REQ2,
+               [29] = DMACH_MSM_REQ3,
+               [30] = DMACH_PCM2_RX,
+               [31] = DMACH_PCM2_TX,
+       },
+};
+
+static struct platform_device s5pv210_device_pdma1 = {
+       .name           = "s3c-pl330",
+       .id             = 2,
+       .num_resources  = ARRAY_SIZE(s5pv210_pdma1_resource),
+       .resource       = s5pv210_pdma1_resource,
+       .dev            = {
+               .dma_mask = &dma_dmamask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+               .platform_data = &s5pv210_pdma1_pdata,
+       },
+};
+
+static struct platform_device *s5pv210_dmacs[] __initdata = {
+       &s5pv210_device_pdma0,
+       &s5pv210_device_pdma1,
+};
+
+static int __init s5pv210_dma_init(void)
+{
+       platform_add_devices(s5pv210_dmacs, ARRAY_SIZE(s5pv210_dmacs));
+
+       return 0;
+}
+arch_initcall(s5pv210_dma_init);
diff --git a/arch/arm/mach-s5pv210/gpiolib.c b/arch/arm/mach-s5pv210/gpiolib.c
new file mode 100644 (file)
index 0000000..9ea8972
--- /dev/null
@@ -0,0 +1,261 @@
+/* linux/arch/arm/mach-s5pv210/gpiolib.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * S5PV210 - 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 <linux/gpio.h>
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <mach/map.h>
+
+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_noint = {
+       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
+       .set_pull       = s3c_gpio_setpull_updown,
+       .get_pull       = s3c_gpio_getpull_updown,
+};
+
+/* GPIO bank's base address given the index of the bank in the
+ * list of all gpio banks.
+ */
+#define S5PV210_BANK_BASE(bank_nr)     (S5P_VA_GPIO + ((bank_nr) * 0x20))
+
+/*
+ * Following are the gpio banks in v210.
+ *
+ * The 'config' member when left to NULL, is initialized to the default
+ * structure gpio_cfg in the init function below.
+ *
+ * The 'base' member is also initialized in the init function below.
+ * Note: The initialization of 'base' member of s3c_gpio_chip structure
+ * uses the above macro and depends on the banks being listed in order here.
+ */
+static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
+       {
+               .chip   = {
+                       .base   = S5PV210_GPA0(0),
+                       .ngpio  = S5PV210_GPIO_A0_NR,
+                       .label  = "GPA0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPA1(0),
+                       .ngpio  = S5PV210_GPIO_A1_NR,
+                       .label  = "GPA1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPB(0),
+                       .ngpio  = S5PV210_GPIO_B_NR,
+                       .label  = "GPB",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPC0(0),
+                       .ngpio  = S5PV210_GPIO_C0_NR,
+                       .label  = "GPC0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPC1(0),
+                       .ngpio  = S5PV210_GPIO_C1_NR,
+                       .label  = "GPC1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPD0(0),
+                       .ngpio  = S5PV210_GPIO_D0_NR,
+                       .label  = "GPD0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPD1(0),
+                       .ngpio  = S5PV210_GPIO_D1_NR,
+                       .label  = "GPD1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPE0(0),
+                       .ngpio  = S5PV210_GPIO_E0_NR,
+                       .label  = "GPE0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPE1(0),
+                       .ngpio  = S5PV210_GPIO_E1_NR,
+                       .label  = "GPE1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPF0(0),
+                       .ngpio  = S5PV210_GPIO_F0_NR,
+                       .label  = "GPF0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPF1(0),
+                       .ngpio  = S5PV210_GPIO_F1_NR,
+                       .label  = "GPF1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPF2(0),
+                       .ngpio  = S5PV210_GPIO_F2_NR,
+                       .label  = "GPF2",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPF3(0),
+                       .ngpio  = S5PV210_GPIO_F3_NR,
+                       .label  = "GPF3",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPG0(0),
+                       .ngpio  = S5PV210_GPIO_G0_NR,
+                       .label  = "GPG0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPG1(0),
+                       .ngpio  = S5PV210_GPIO_G1_NR,
+                       .label  = "GPG1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPG2(0),
+                       .ngpio  = S5PV210_GPIO_G2_NR,
+                       .label  = "GPG2",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPG3(0),
+                       .ngpio  = S5PV210_GPIO_G3_NR,
+                       .label  = "GPG3",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPI(0),
+                       .ngpio  = S5PV210_GPIO_I_NR,
+                       .label  = "GPI",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPJ0(0),
+                       .ngpio  = S5PV210_GPIO_J0_NR,
+                       .label  = "GPJ0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPJ1(0),
+                       .ngpio  = S5PV210_GPIO_J1_NR,
+                       .label  = "GPJ1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPJ2(0),
+                       .ngpio  = S5PV210_GPIO_J2_NR,
+                       .label  = "GPJ2",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPJ3(0),
+                       .ngpio  = S5PV210_GPIO_J3_NR,
+                       .label  = "GPJ3",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPJ4(0),
+                       .ngpio  = S5PV210_GPIO_J4_NR,
+                       .label  = "GPJ4",
+               },
+       }, {
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PV210_MP01(0),
+                       .ngpio  = S5PV210_GPIO_MP01_NR,
+                       .label  = "MP01",
+               },
+       }, {
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PV210_MP02(0),
+                       .ngpio  = S5PV210_GPIO_MP02_NR,
+                       .label  = "MP02",
+               },
+       }, {
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PV210_MP03(0),
+                       .ngpio  = S5PV210_GPIO_MP03_NR,
+                       .label  = "MP03",
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC00),
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PV210_GPH0(0),
+                       .ngpio  = S5PV210_GPIO_H0_NR,
+                       .label  = "GPH0",
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC20),
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PV210_GPH1(0),
+                       .ngpio  = S5PV210_GPIO_H1_NR,
+                       .label  = "GPH1",
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC40),
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PV210_GPH2(0),
+                       .ngpio  = S5PV210_GPIO_H2_NR,
+                       .label  = "GPH2",
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC60),
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PV210_GPH3(0),
+                       .ngpio  = S5PV210_GPIO_H3_NR,
+                       .label  = "GPH3",
+               },
+       },
+};
+
+static __init int s5pv210_gpiolib_init(void)
+{
+       struct s3c_gpio_chip *chip = s5pv210_gpio_4bit;
+       int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);
+       int i = 0;
+
+       for (i = 0; i < nr_chips; i++, chip++) {
+               if (chip->config == NULL)
+                       chip->config = &gpio_cfg;
+               if (chip->base == NULL)
+                       chip->base = S5PV210_BANK_BASE(i);
+       }
+
+       samsung_gpiolib_add_4bit_chips(s5pv210_gpio_4bit, nr_chips);
+
+       return 0;
+}
+core_initcall(s5pv210_gpiolib_init);
diff --git a/arch/arm/mach-s5pv210/include/mach/dma.h b/arch/arm/mach-s5pv210/include/mach/dma.h
new file mode 100644 (file)
index 0000000..81209eb
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ *     Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MACH_DMA_H
+#define __MACH_DMA_H
+
+/* This platform uses the common S3C DMA API driver for PL330 */
+#include <plat/s3c-dma-pl330.h>
+
+#endif /* __MACH_DMA_H */
index 533b020e21e9511ce558ee50a450e2407f4a0caa..d6461ba2b71d474d51a6319d56d6df31b407acb6 100644 (file)
@@ -18,6 +18,8 @@
 #define gpio_cansleep  __gpio_cansleep
 #define gpio_to_irq    __gpio_to_irq
 
+/* Practically, GPIO banks upto MP03 are the configurable gpio banks */
+
 /* GPIO bank sizes */
 #define S5PV210_GPIO_A0_NR     (8)
 #define S5PV210_GPIO_A1_NR     (4)
 #define S5PV210_GPIO_J3_NR     (8)
 #define S5PV210_GPIO_J4_NR     (5)
 
+#define S5PV210_GPIO_MP01_NR   (8)
+#define S5PV210_GPIO_MP02_NR   (4)
+#define S5PV210_GPIO_MP03_NR   (8)
+
 /* GPIO bank numbers */
 
 /* CONFIG_S3C_GPIO_SPACE allows the user to select extra
@@ -85,6 +91,9 @@ enum s5p_gpio_number {
        S5PV210_GPIO_J2_START   = S5PV210_GPIO_NEXT(S5PV210_GPIO_J1),
        S5PV210_GPIO_J3_START   = S5PV210_GPIO_NEXT(S5PV210_GPIO_J2),
        S5PV210_GPIO_J4_START   = S5PV210_GPIO_NEXT(S5PV210_GPIO_J3),
+       S5PV210_GPIO_MP01_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J4),
+       S5PV210_GPIO_MP02_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP01),
+       S5PV210_GPIO_MP03_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP02),
 };
 
 /* S5PV210 GPIO number definitions */
@@ -115,13 +124,16 @@ enum s5p_gpio_number {
 #define S5PV210_GPJ2(_nr)      (S5PV210_GPIO_J2_START + (_nr))
 #define S5PV210_GPJ3(_nr)      (S5PV210_GPIO_J3_START + (_nr))
 #define S5PV210_GPJ4(_nr)      (S5PV210_GPIO_J4_START + (_nr))
+#define S5PV210_MP01(_nr)      (S5PV210_GPIO_MP01_START + (_nr))
+#define S5PV210_MP02(_nr)      (S5PV210_GPIO_MP02_START + (_nr))
+#define S5PV210_MP03(_nr)      (S5PV210_GPIO_MP03_START + (_nr))
 
 /* the end of the S5PV210 specific gpios */
-#define S5PV210_GPIO_END       (S5PV210_GPJ4(S5PV210_GPIO_J4_NR) + 1)
+#define S5PV210_GPIO_END       (S5PV210_MP03(S5PV210_GPIO_MP03_NR) + 1)
 #define S3C_GPIO_END           S5PV210_GPIO_END
 
-/* define the number of gpios we need to the one after the GPJ4() range */
-#define ARCH_NR_GPIOS          (S5PV210_GPJ4(S5PV210_GPIO_J4_NR) +     \
+/* define the number of gpios we need to the one after the MP03() range */
+#define ARCH_NR_GPIOS          (S5PV210_MP03(S5PV210_GPIO_MP03_NR) +   \
                                 CONFIG_SAMSUNG_GPIO_EXTRA + 1)
 
 #include <asm-generic/gpio.h>
index c22694c8231f0148b41195f238babbde3d5d2bfd..5adcb9f26e449ef76504b10244cbd3570fb710dc 100644 (file)
 
 #define S5PV210_PA_SROMC       (0xE8000000)
 
+#define S5PV210_PA_MDMA                0xFA200000
+#define S5PV210_PA_PDMA0       0xE0900000
+#define S5PV210_PA_PDMA1       0xE0A00000
+
 #define S5PV210_PA_VIC0                (0xF2000000)
 #define S5P_PA_VIC0            S5PV210_PA_VIC0
 
 #define S5PV210_PA_SDRAM       (0x20000000)
 #define S5P_PA_SDRAM           S5PV210_PA_SDRAM
 
+/* I2S */
+#define S5PV210_PA_IIS0                0xEEE30000
+#define S5PV210_PA_IIS1                0xE2100000
+#define S5PV210_PA_IIS2                0xE2A00000
+
+/* PCM */
+#define S5PV210_PA_PCM0                0xE2300000
+#define S5PV210_PA_PCM1                0xE1200000
+#define S5PV210_PA_PCM2                0xE2B00000
+
+/* AC97 */
+#define S5PV210_PA_AC97                0xE2200000
+
 /* compatibiltiy defines. */
 #define S3C_PA_UART            S5PV210_PA_UART
 #define S3C_PA_IIC             S5PV210_PA_IIC0
index 69027fea987a9cf13f3263cbb65811a8184c6c8d..f8a9f1b330e0d2bcca520e26b3aef4a7b8b075cb 100644 (file)
@@ -1,13 +1,14 @@
 /* linux/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
  *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * Copyright 2008 Openmoko, Inc.
  * Copyright 2008 Simtec Electronics
  *      Ben Dooks <ben@simtec.co.uk>
  *      http://armlinux.simtec.co.uk/
  *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * Based on arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
+ * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
  *
  * S5PV210 - pwm clock and timer support
  *
 
 /**
  * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
- * @cfg: The timer TCFG1 register bits shifted down to 0.
+ * @tcfg: The timer TCFG1 register bits shifted down to 0.
  *
  * Return true if the given configuration from TCFG1 is a TCLK instead
  * any of the TDIV clocks.
  */
 static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
 {
-       return tcfg == S3C2410_TCFG1_MUX_TCLK;
+       return tcfg == S3C64XX_TCFG1_MUX_TCLK;
 }
 
 /**
@@ -40,7 +41,7 @@ static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
  */
 static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
 {
-       return 1 << (1 + tcfg1);
+       return 1 << tcfg1;
 }
 
 /**
@@ -50,7 +51,7 @@ static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
  */
 static inline unsigned int pwm_tdiv_has_div1(void)
 {
-       return 0;
+       return 1;
 }
 
 /**
@@ -61,9 +62,9 @@ static inline unsigned int pwm_tdiv_has_div1(void)
  */
 static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
 {
-       return ilog2(div) - 1;
+       return ilog2(div);
 }
 
-#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK
+#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
 
 #endif /* __ASM_ARCH_PWMCLK_H */
index ab4869df30c04ca221a92284e471859b46b8fb99..6f9fd3274e2e3196d18a213a40c43f89a768a989 100644 (file)
@@ -72,6 +72,8 @@ static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
 };
 
 static struct platform_device *smdkc110_devices[] __initdata = {
+       &s5pv210_device_iis0,
+       &s5pv210_device_ac97,
 };
 
 static void __init smdkc110_map_io(void)
index a27883253204c6bfbca050216c81fa1027baa3aa..3c29e18528a5f3df6067e33b39b8506829f5fa56 100644 (file)
@@ -72,6 +72,8 @@ static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
 };
 
 static struct platform_device *smdkv210_devices[] __initdata = {
+       &s5pv210_device_iis0,
+       &s5pv210_device_ac97,
 };
 
 static void __init smdkv210_map_io(void)
diff --git a/arch/arm/mach-s5pv210/setup-i2c0.c b/arch/arm/mach-s5pv210/setup-i2c0.c
new file mode 100644 (file)
index 0000000..9ec6845
--- /dev/null
@@ -0,0 +1,25 @@
+/* linux/arch/arm/mach-s5pv210/setup-i2c0.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * I2C0 GPIO configuration.
+ *
+ * Based on plat-s3c64xx/setup-i2c0.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/iic.h>
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+{
+       /* Will be populated later */
+}
index e7113d0b816863e498c57fa5536e38c3189f1967..28589417118643aec349aff677e3c1e0be53efa3 100644 (file)
@@ -870,9 +870,10 @@ void __init reserve_node_zero(pg_data_t *pgdat)
        if (machine_is_p720t())
                res_size = 0x00014000;
 
-       /* H1940 and RX3715 need to reserve this for suspend */
+       /* H1940, RX3715 and RX1950 need to reserve this for suspend */
 
-       if (machine_is_h1940() || machine_is_rx3715()) {
+       if (machine_is_h1940() || machine_is_rx3715()
+               || machine_is_rx1950()) {
                reserve_bootmem_node(pgdat, 0x30003000, 0x1000,
                                BOOTMEM_DEFAULT);
                reserve_bootmem_node(pgdat, 0x30081000, 0x1000,
index 3ce8f010b3c6d19a9aa9857d27c6a009d8fd5050..984bf66826d2a54773a57a316839ab346c1e6b1e 100644 (file)
@@ -164,4 +164,9 @@ config S3C24XX_SIMTEC_AUDIO
        help
          Add audio devices for common Simtec S3C24XX boards
 
+config S3C2410_SETUP_TS
+       bool
+       help
+         Compile in platform device definition for Samsung TouchScreen.
+
 endif
index 44aea8868f8913ae4b4f861be72f498aeeb70e7a..c2064c30871926e35a3785017c4c10604e5ba3e5 100644 (file)
@@ -38,6 +38,7 @@ obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += s3c2410-cpufreq-utils.o
 
 # device specific setup and/or initialisation
 obj-$(CONFIG_ARCH_S3C2410)     += setup-i2c.o
+obj-$(CONFIG_S3C2410_SETUP_TS) += setup-ts.o
 
 # SPI gpio central GPIO functions
 
index 9265f09bfa58e6b005f73fa0c9cf39dc11ec310e..58583732b29a30a2eee8076e3960602b2b3263c9 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -38,8 +39,7 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/regs-spi.h>
-
-#include <mach/ts.h>
+#include <plat/ts.h>
 
 /* Serial port registrations */
 
@@ -149,10 +149,14 @@ void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
 {
        struct s3c2410fb_mach_info *npd;
 
-       npd = kmalloc(sizeof(*npd), GFP_KERNEL);
+       npd = kmemdup(pd, sizeof(*npd), GFP_KERNEL);
        if (npd) {
-               memcpy(npd, pd, sizeof(*npd));
                s3c_device_lcd.dev.platform_data = npd;
+               npd->displays = kmemdup(pd->displays,
+                       sizeof(struct s3c2410fb_display) * npd->num_displays,
+                       GFP_KERNEL);
+               if (!npd->displays)
+                       printk(KERN_ERR "no memory for LCD display data\n");
        } else {
                printk(KERN_ERR "no memory for LCD platform data\n");
        }
@@ -338,14 +342,6 @@ struct platform_device s3c_device_adc = {
        .resource         = s3c_adc_resource,
 };
 
-/* HWMON */
-
-struct platform_device s3c_device_hwmon = {
-       .name           = "s3c-hwmon",
-       .id             = -1,
-       .dev.parent     = &s3c_device_adc.dev,
-};
-
 /* SDI */
 
 static struct resource s3c_sdi_resource[] = {
@@ -371,7 +367,7 @@ struct platform_device s3c_device_sdi = {
 
 EXPORT_SYMBOL(s3c_device_sdi);
 
-void s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata)
+void __init s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata)
 {
        struct s3c24xx_mci_pdata *npd;
 
index 93827b3d4e84645bbc34212578140978f7014642..6ad274e7593d578a23161f30eba62d88b396d5f5 100644 (file)
@@ -1104,7 +1104,7 @@ EXPORT_SYMBOL(s3c2410_dma_config);
  * devaddr:   physical address of the source
 */
 
-int s3c2410_dma_devconfig(int channel,
+int s3c2410_dma_devconfig(unsigned int channel,
                          enum s3c2410_dmasrc source,
                          unsigned long devaddr)
 {
index 45126d3aafc6d83a0385a9e969c4fa4686b77839..2f3d7c089dfaeb511edd21e078714f1190b62562 100644 (file)
@@ -34,6 +34,8 @@
 
 #include <mach/regs-gpio.h>
 
+#include <plat/gpio-core.h>
+
 /* gpiolib wrappers until these are totally eliminated */
 
 void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
@@ -68,10 +70,10 @@ EXPORT_SYMBOL(s3c2410_gpio_setpin);
 
 unsigned int s3c2410_gpio_getpin(unsigned int pin)
 {
-       void __iomem *base = S3C24XX_GPIO_BASE(pin);
-       unsigned long offs = S3C2410_GPIO_OFFSET(pin);
+       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+       unsigned long offs = pin - chip->chip.base;
 
-       return __raw_readl(base + 0x04) & (1<< offs);
+       return __raw_readl(chip->base + 0x04) & (1<< offs);
 }
 
 EXPORT_SYMBOL(s3c2410_gpio_getpin);
diff --git a/arch/arm/plat-s3c24xx/setup-ts.c b/arch/arm/plat-s3c24xx/setup-ts.c
new file mode 100644 (file)
index 0000000..ed26386
--- /dev/null
@@ -0,0 +1,34 @@
+/* linux/arch/arm/plat-s3c24xx/setup-ts.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *                     http://www.samsung.com/
+ *
+ * Based on S3C24XX setup for i2c device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+
+/**
+ * s3c24xx_ts_cfg_gpio - configure gpio for s3c2410 systems
+ *
+ * Configure the GPIO for the S3C2410 system, where we have external FETs
+ * connected to the device (later systems such as the S3C2440 integrate
+ * these into the device).
+ */
+void s3c24xx_ts_cfg_gpio(struct platform_device *dev)
+{
+       s3c2410_gpio_cfgpin(S3C2410_GPG(12), S3C2410_GPG12_XMON);
+       s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPG13_nXPON);
+       s3c2410_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPG14_YMON);
+       s3c2410_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPG15_nYPON);
+}
index d400a6a20fe417c77ab2735f9db7fbf81cf282e5..92bd75607b436f5ede6f38a72989ba952a42d619 100644 (file)
@@ -13,6 +13,7 @@ config PLAT_S5P
        select NO_IOPORT
        select ARCH_REQUIRE_GPIOLIB
        select S3C_GPIO_TRACK
+       select S5P_GPIO_DRVSTR
        select SAMSUNG_GPIOLIB_4BIT
        select S3C_GPIO_CFG_S3C64XX
        select S3C_GPIO_PULL_UPDOWN
index a7c54b332d27531e1a00542ddb197c8952d901fe..0ec09a9c36bd6d8e5e4c9af2ed7185318b6c12be 100644 (file)
@@ -16,4 +16,3 @@ obj-y                         += dev-uart.o
 obj-y                          += cpu.o
 obj-y                          += clock.o
 obj-y                          += irq.o
-obj-y                          += setup-i2c0.o
index aa96e335073b6a8829748996bc64e8f685fec2c3..24a931fd8d3b5583709d6456a447c5f41ec92df1 100644 (file)
@@ -33,7 +33,12 @@ struct clk clk_ext_xtal_mux = {
        .id             = -1,
 };
 
-static struct clk s5p_clk_27m = {
+struct clk clk_xusbxti = {
+       .name           = "xusbxti",
+       .id             = -1,
+};
+
+struct clk s5p_clk_27m = {
        .name           = "clk_27m",
        .id             = -1,
        .rate           = 27000000,
@@ -69,6 +74,13 @@ struct clk clk_fout_epll = {
        .ctrlbit        = (1 << 31),
 };
 
+/* VPLL clock output */
+struct clk clk_fout_vpll = {
+       .name           = "fout_vpll",
+       .id             = -1,
+       .ctrlbit        = (1 << 31),
+};
+
 /* ARM clock */
 struct clk clk_arm = {
        .name           = "armclk",
@@ -133,6 +145,7 @@ static struct clk *s5p_clks[] __initdata = {
        &clk_fout_apll,
        &clk_fout_mpll,
        &clk_fout_epll,
+       &clk_fout_vpll,
        &clk_arm,
        &clk_vpll,
 };
index 42e757f2e40ca972402d8bb53f000edc745fa067..9ff3d718be39f1b15b30b8c60361cbd8215f7699 100644 (file)
@@ -79,7 +79,7 @@
 #define S5P_IRQ_VIC2(x)                (S5P_VIC2_BASE + (x))
 #define S5P_IRQ_VIC3(x)                (S5P_VIC3_BASE + (x))
 
-#define S5P_TIMER_IRQ(x)       S5P_IRQ(11 + (x))
+#define S5P_TIMER_IRQ(x)       (11 + (x))
 
 #define IRQ_TIMER0             S5P_TIMER_IRQ(0)
 #define IRQ_TIMER1             S5P_TIMER_IRQ(1)
index d48325bb29e22a10f995a41aee08c93da1633c4d..7db322726bc29aed7410a58b8c4917603e13a054 100644 (file)
@@ -81,3 +81,25 @@ static inline unsigned long s5p_get_pll90xx(unsigned long baseclk,
 
        return result;
 }
+
+#define PLL65XX_MDIV_MASK      (0x3FF)
+#define PLL65XX_PDIV_MASK      (0x3F)
+#define PLL65XX_SDIV_MASK      (0x7)
+#define PLL65XX_MDIV_SHIFT     (16)
+#define PLL65XX_PDIV_SHIFT     (8)
+#define PLL65XX_SDIV_SHIFT     (0)
+
+static inline unsigned long s5p_get_pll65xx(unsigned long baseclk, u32 pll_con)
+{
+       u32 mdiv, pdiv, sdiv;
+       u64 fvco = baseclk;
+
+       mdiv = (pll_con >> PLL65XX_MDIV_SHIFT) & PLL65XX_MDIV_MASK;
+       pdiv = (pll_con >> PLL65XX_PDIV_SHIFT) & PLL65XX_PDIV_MASK;
+       sdiv = (pll_con >> PLL65XX_SDIV_SHIFT) & PLL65XX_SDIV_MASK;
+
+       fvco *= mdiv;
+       do_div(fvco, (pdiv << sdiv));
+
+       return (unsigned long)fvco;
+}
index 56fb8b414d414564e1436bc1e9b34f372daf2dd3..09418b1101fe582a374b4ded78010e36de392d11 100644 (file)
 #define clk_fin_mpll clk_ext_xtal_mux
 #define clk_fin_epll clk_ext_xtal_mux
 #define clk_fin_vpll clk_ext_xtal_mux
+#define clk_fin_hpll clk_ext_xtal_mux
 
 extern struct clk clk_ext_xtal_mux;
+extern struct clk clk_xusbxti;
 extern struct clk clk_48m;
+extern struct clk s5p_clk_27m;
 extern struct clk clk_fout_apll;
 extern struct clk clk_fout_mpll;
 extern struct clk clk_fout_epll;
+extern struct clk clk_fout_vpll;
 extern struct clk clk_arm;
 extern struct clk clk_vpll;
 
index c7ccdf22eefaa2de521dc33ec4b928f5a13635c9..c7bd2bbda239c804b3fc60aa69d09b666f4d0af4 100644 (file)
@@ -16,9 +16,10 @@ config PLAT_S5PC1XX
        select SAMSUNG_IRQ_VIC_TIMER
        select S3C_GPIO_TRACK
        select S3C_GPIO_PULL_UPDOWN
+       select S5P_GPIO_DRVSTR
        select S3C_GPIO_CFG_S3C24XX
        select S3C_GPIO_CFG_S3C64XX
-       select S5P_GPIO_CFG_S5PC1XX
+       select SAMSUNG_GPIOLIB_4BIT
        help
          Base platform code for any Samsung S5PC1XX device
 
@@ -38,25 +39,6 @@ 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 S5PC1XX_SETUP_I2C0
-       bool
-       default y
-       help
-         Common setup code for i2c bus 0.
-
-         Note, currently since i2c0 is always compiled, this setup helper
-         is always compiled with it.
-
-config S5PC1XX_SETUP_I2C1
-       bool
-       help
-         Common setup code for i2c bus 1.
-
 config S5PC1XX_SETUP_SDHCI_GPIO
        bool
        help
index 278f268060897478169ed4d61d7f02eda88eaea1..9ce6409a9e02c7ee6ed95774d65201739f1f09d2 100644 (file)
@@ -13,9 +13,8 @@ obj-                          :=
 
 obj-y                          += dev-uart.o
 obj-y                          += cpu.o
-obj-y                          += irq.o irq-gpio.o irq-eint.o
+obj-y                          += irq.o
 obj-y                          += clock.o
-obj-y                          += gpiolib.o
 
 # CPU support
 
@@ -24,8 +23,4 @@ obj-$(CONFIG_CPU_S5PC100_CLOCK)       += s5pc100-clock.o
 
 # Device setup
 
-obj-$(CONFIG_S5P_GPIO_CFG_S5PC1XX) += gpio-config.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/gpio-config.c b/arch/arm/plat-s5pc1xx/gpio-config.c
deleted file mode 100644 (file)
index a4f67e8..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* linux/arch/arm/plat-s5pc1xx/gpio-config.c
- *
- * Copyright 2009 Samsung Electronics
- *
- * S5PC1XX GPIO Configuration.
- *
- * Based on plat-s3c64xx/gpio-config.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-
-#include <plat/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/include/plat/gpio-cfg-s5pc1xx.h b/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h
deleted file mode 100644 (file)
index 72ad59f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/* linux/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg.h
- *
- * Copyright 2009 Samsung Electronic
- *
- * 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 */
index d552c65fa1b05477c8e65cd4eab222a3d06e4b5b..229919e9744c8ee3f2cf0b570c48247946f0d6bb 100644 (file)
@@ -90,12 +90,6 @@ 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.
-
 config S3C_GPIO_PULL_UPDOWN
        bool
        help
@@ -111,6 +105,12 @@ config S3C_GPIO_PULL_UP
        help
          Internal configuration to enable the correct GPIO pull helper
 
+config S5P_GPIO_DRVSTR
+       bool
+       help
+         Internal configuration to get and set correct GPIO driver strength
+         helper
+
 config SAMSUNG_GPIO_EXTRA
        int "Number of additional GPIO pins"
        default 0
@@ -160,6 +160,11 @@ config S3C_DEV_HSMMC2
        help
          Compile in platform device definitions for HSMMC channel 2
 
+config S3C_DEV_HWMON
+       bool
+       help
+           Compile in platform device definitions for HWMON
+
 config S3C_DEV_I2C1
        bool
        help
@@ -185,12 +190,27 @@ config S3C_DEV_NAND
        help
          Compile in platform device definition for NAND controller
 
+config S3C_DEV_RTC
+       bool
+       help
+         Complie in platform device definition for RTC
+
+config SAMSUNG_DEV_ADC
+       bool
+       help
+         Compile in platform device definition for ADC controller
+
 config S3C64XX_DEV_SPI
        bool
        help
          Compile in platform device definitions for S3C64XX's type
          SPI controllers.
 
+config SAMSUNG_DEV_TS
+       bool
+       help
+           Common in platform device definitions for touchscreen device
+
 # DMA
 
 config S3C_DMA
@@ -198,6 +218,12 @@ config S3C_DMA
        help
          Internal configuration for S3C DMA core
 
+config S3C_PL330_DMA
+       bool
+       select PL330
+       help
+         S3C DMA API Driver for PL330 DMAC.
+
 comment "Power management"
 
 config SAMSUNG_PM_DEBUG
index 22c89d08f6e52d2edfada32bfaa50c0e8a82735b..48288499a3b9f8a3a2fceb5be1d5047f88fcd7c1 100644 (file)
@@ -33,6 +33,7 @@ obj-$(CONFIG_S3C_ADC) += adc.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-$(CONFIG_S3C_DEV_HWMON)    += dev-hwmon.o
 obj-y                          += dev-i2c0.o
 obj-$(CONFIG_S3C_DEV_I2C1)     += dev-i2c1.o
 obj-$(CONFIG_S3C_DEV_FB)       += dev-fb.o
@@ -40,11 +41,17 @@ obj-y                               += dev-uart.o
 obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
 obj-$(CONFIG_S3C_DEV_USB_HSOTG)        += dev-usb-hsotg.o
 obj-$(CONFIG_S3C_DEV_NAND)     += dev-nand.o
+obj-$(CONFIG_S3C_DEV_RTC)      += dev-rtc.o
+
+obj-$(CONFIG_SAMSUNG_DEV_ADC)  += dev-adc.o
+obj-$(CONFIG_SAMSUNG_DEV_TS)   += dev-ts.o
 
 # DMA support
 
 obj-$(CONFIG_S3C_DMA)          += dma.o
 
+obj-$(CONFIG_S3C_PL330_DMA)    += s3c-pl330.o
+
 # PM support
 
 obj-$(CONFIG_PM)               += pm.o
similarity index 86%
rename from arch/arm/mach-s3c64xx/dev-adc.c
rename to arch/arm/plat-samsung/dev-adc.c
index fafef9b6bcfa4d60907ee31d97136d6ca1a50e8f..9d903d4095ed9e90e161792b7048b46ad39c590d 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/arch/arm/plat-s3c64xx/dev-adc.c
+/* linux/arch/arm/plat-samsung/dev-adc.c
  *
  * Copyright 2010 Maurus Cuelenaere
  *
@@ -22,8 +22,8 @@
 
 static struct resource s3c_adc_resource[] = {
        [0] = {
-               .start = S3C64XX_PA_ADC,
-               .end   = S3C64XX_PA_ADC + SZ_256 - 1,
+               .start = SAMSUNG_PA_ADC,
+               .end   = SAMSUNG_PA_ADC + SZ_256 - 1,
                .flags = IORESOURCE_MEM,
        },
        [1] = {
@@ -39,7 +39,7 @@ static struct resource s3c_adc_resource[] = {
 };
 
 struct platform_device s3c_device_adc = {
-       .name           = "s3c64xx-adc",
+       .name           = "samsung-adc",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(s3c_adc_resource),
        .resource       = s3c_adc_resource,
index 002a15f313f30bb7e1e798d78b60a287578b574e..bf60204c62976f1b583d08eebe34bd13d23500d7 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <mach/irqs.h>
 #include <mach/map.h>
-#include <mach/regs-fb.h>
 
 #include <plat/fb.h>
 #include <plat/devs.h>
diff --git a/arch/arm/plat-samsung/dev-hwmon.c b/arch/arm/plat-samsung/dev-hwmon.c
new file mode 100644 (file)
index 0000000..b3ffb95
--- /dev/null
@@ -0,0 +1,42 @@
+/* linux/arch/arm/plat-samsung/dev-hwmon.c
+ *
+ * Copyright 2008 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *     http://armlinux.simtec.co.uk/
+ *
+ * Adapted for HWMON by Maurus Cuelenaere
+ *
+ * Samsung series device definition for HWMON
+ *
+ * This program is free software; you can 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 <plat/devs.h>
+#include <plat/hwmon.h>
+
+struct platform_device s3c_device_hwmon = {
+       .name           = "s3c-hwmon",
+       .id             = -1,
+       .dev.parent     = &s3c_device_adc.dev,
+};
+
+void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd)
+{
+       struct s3c_hwmon_pdata *npd;
+
+       if (!pd) {
+               printk(KERN_ERR "%s: no platform data\n", __func__);
+               return;
+       }
+
+       npd = kmemdup(pd, sizeof(struct s3c_hwmon_pdata), GFP_KERNEL);
+       if (!npd)
+               printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+
+       s3c_device_hwmon.dev.platform_data = npd;
+}
similarity index 58%
rename from arch/arm/mach-s3c64xx/dev-rtc.c
rename to arch/arm/plat-samsung/dev-rtc.c
index b9e7a05f0129ce300fc4c7196db6b0c48a0085cc..bf4e2267333c2b8f721d088217fc070f6ae6bfd4 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/arch/arm/plat-s3c64xx/dev-rtc.c
+/* linux/arch/arm/plat-samsung/dev-rtc.c
  *
  * Copyright 2009 by Maurus Cuelenaere <mcuelenaere@gmail.com>
  *
 
 static struct resource s3c_rtc_resource[] = {
        [0] = {
-               .start = S3C64XX_PA_RTC,
-               .end   = S3C64XX_PA_RTC + 0xff,
-               .flags = IORESOURCE_MEM,
+               .start  = S3C_PA_RTC,
+               .end    = S3C_PA_RTC + 0xff,
+               .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start = IRQ_RTC_ALARM,
-               .end   = IRQ_RTC_ALARM,
-               .flags = IORESOURCE_IRQ,
+               .start  = IRQ_RTC_ALARM,
+               .end    = IRQ_RTC_ALARM,
+               .flags  = IORESOURCE_IRQ,
        },
        [2] = {
-               .start = IRQ_RTC_TIC,
-               .end   = IRQ_RTC_TIC,
-               .flags = IORESOURCE_IRQ
+               .start  = IRQ_RTC_TIC,
+               .end    = IRQ_RTC_TIC,
+               .flags  = IORESOURCE_IRQ
        }
 };
 
 struct platform_device s3c_device_rtc = {
-       .name             = "s3c64xx-rtc",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_rtc_resource),
-       .resource         = s3c_rtc_resource,
+       .name           = "s3c64xx-rtc",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_rtc_resource),
+       .resource       = s3c_rtc_resource,
 };
 EXPORT_SYMBOL(s3c_device_rtc);
diff --git a/arch/arm/plat-samsung/dev-ts.c b/arch/arm/plat-samsung/dev-ts.c
new file mode 100644 (file)
index 0000000..236ef84
--- /dev/null
@@ -0,0 +1,61 @@
+/* linux/arch/arm/mach-s3c64xx/dev-ts.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ *
+ * Adapted by Maurus Cuelenaere for s3c64xx
+ *
+ * S3C64XX series device definition for touchscreen device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+#include <plat/ts.h>
+
+static struct resource s3c_ts_resource[] = {
+       [0] = {
+               .start = SAMSUNG_PA_ADC,
+               .end   = SAMSUNG_PA_ADC + SZ_256 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_TC,
+               .end   = IRQ_TC,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device s3c_device_ts = {
+       .name           = "s3c64xx-ts",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_ts_resource),
+       .resource       = s3c_ts_resource,
+};
+
+void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd)
+{
+       struct s3c2410_ts_mach_info *npd;
+
+       if (!pd) {
+               printk(KERN_ERR "%s: no platform data\n", __func__);
+               return;
+       }
+
+       npd = kmemdup(pd, sizeof(struct s3c2410_ts_mach_info), GFP_KERNEL);
+       if (!npd)
+               printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+
+       s3c_device_ts.dev.platform_data = npd;
+}
+EXPORT_SYMBOL(s3c24xx_ts_set_platdata);
index 3282db360fa8b4bb54f96b99c7c27819583fb31a..57b68a50f45e93aa14852500ace0df1fdc48da8b 100644 (file)
@@ -33,9 +33,9 @@ int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
 
        offset = pin - chip->chip.base;
 
-       local_irq_save(flags);
+       s3c_gpio_lock(chip, flags);
        ret = s3c_gpio_do_setcfg(chip, offset, config);
-       local_irq_restore(flags);
+       s3c_gpio_unlock(chip, flags);
 
        return ret;
 }
@@ -51,9 +51,9 @@ unsigned s3c_gpio_getcfg(unsigned int pin)
        if (chip) {
                offset = pin - chip->chip.base;
 
-               local_irq_save(flags);
+               s3c_gpio_lock(chip, flags);
                ret = s3c_gpio_do_getcfg(chip, offset);
-               local_irq_restore(flags);
+               s3c_gpio_unlock(chip, flags);
        }
 
        return ret;
@@ -72,9 +72,9 @@ int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
 
        offset = pin - chip->chip.base;
 
-       local_irq_save(flags);
+       s3c_gpio_lock(chip, flags);
        ret = s3c_gpio_do_setpull(chip, offset, pull);
-       local_irq_restore(flags);
+       s3c_gpio_unlock(chip, flags);
 
        return ret;
 }
@@ -261,3 +261,51 @@ s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
 }
 #endif /* CONFIG_S3C_GPIO_PULL_UP */
 
+#ifdef CONFIG_S5P_GPIO_DRVSTR
+s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
+{
+       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+       unsigned int off;
+       void __iomem *reg;
+       int shift;
+       u32 drvstr;
+
+       if (!chip)
+               return -EINVAL;
+
+       off = chip->chip.base - pin;
+       shift = off * 2;
+       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, s5p_gpio_drvstr_t drvstr)
+{
+       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+       unsigned int off;
+       void __iomem *reg;
+       int shift;
+       u32 tmp;
+
+       if (!chip)
+               return -EINVAL;
+
+       off = chip->chip.base - pin;
+       shift = off * 2;
+       reg = chip->base + 0x0C;
+
+       tmp = __raw_readl(reg);
+       tmp |= drvstr << shift;
+
+       __raw_writel(tmp, reg);
+
+       return 0;
+}
+EXPORT_SYMBOL(s5p_gpio_set_drvstr);
+#endif /* CONFIG_S5P_GPIO_DRVSTR */
index 28d2ab8a08db79861a4422ada8d1e19554ee1d6d..b83a83351cea9dc456c6a7e5d660ecd273c057bb 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/spinlock.h>
 
 #include <plat/gpio-core.h>
 
@@ -52,14 +53,14 @@ static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset)
        unsigned long flags;
        unsigned long con;
 
-       local_irq_save(flags);
+       s3c_gpio_lock(ourchip, flags);
 
        con = __raw_readl(base + 0x00);
        con &= ~(3 << (offset * 2));
 
        __raw_writel(con, base + 0x00);
 
-       local_irq_restore(flags);
+       s3c_gpio_unlock(ourchip, flags);
        return 0;
 }
 
@@ -72,7 +73,7 @@ static int s3c_gpiolib_output(struct gpio_chip *chip,
        unsigned long dat;
        unsigned long con;
 
-       local_irq_save(flags);
+       s3c_gpio_lock(ourchip, flags);
 
        dat = __raw_readl(base + 0x04);
        dat &= ~(1 << offset);
@@ -87,7 +88,7 @@ static int s3c_gpiolib_output(struct gpio_chip *chip,
        __raw_writel(con, base + 0x00);
        __raw_writel(dat, base + 0x04);
 
-       local_irq_restore(flags);
+       s3c_gpio_unlock(ourchip, flags);
        return 0;
 }
 
@@ -99,7 +100,7 @@ static void s3c_gpiolib_set(struct gpio_chip *chip,
        unsigned long flags;
        unsigned long dat;
 
-       local_irq_save(flags);
+       s3c_gpio_lock(ourchip, flags);
 
        dat = __raw_readl(base + 0x04);
        dat &= ~(1 << offset);
@@ -107,7 +108,7 @@ static void s3c_gpiolib_set(struct gpio_chip *chip,
                dat |= 1 << offset;
        __raw_writel(dat, base + 0x04);
 
-       local_irq_restore(flags);
+       s3c_gpio_unlock(ourchip, flags);
 }
 
 static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset)
@@ -131,6 +132,8 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
        BUG_ON(!gc->label);
        BUG_ON(!gc->ngpio);
 
+       spin_lock_init(&chip->lock);
+
        if (!gc->direction_input)
                gc->direction_input = s3c_gpiolib_input;
        if (!gc->direction_output)
index 12caf48a6bdc8e37b55d103179fb9278dc7c1815..0fbcd0effd8e436fb0ac0351c46a835ec1ee7506 100644 (file)
@@ -74,6 +74,7 @@ extern struct clk clk_ext;
 extern struct clk clk_h2;
 extern struct clk clk_27m;
 extern struct clk clk_48m;
+extern struct clk clk_xusbxti;
 
 extern int clk_default_setrate(struct clk *clk, unsigned long rate);
 extern struct clk_ops clk_ops_def_setrate;
index 5dbeb7991e606cb76652a989b64fec9d54ee8acc..6412933d6fbb813050b840e1d71e788758b9a9fc 100644 (file)
@@ -79,6 +79,9 @@ extern struct sysdev_class s3c2442_sysclass;
 extern struct sysdev_class s3c2443_sysclass;
 extern struct sysdev_class s3c6410_sysclass;
 extern struct sysdev_class s3c64xx_sysclass;
+extern struct sysdev_class s5p6440_sysclass;
+extern struct sysdev_class s5p6442_sysclass;
+extern struct sysdev_class s5pv210_sysclass;
 
 extern void (*s5pc1xx_idle)(void);
 
index 796d2425831375fe99b20841366eede7e25e4896..ef69e56b28854e508d007cb14b92dc5bbf05022b 100644 (file)
@@ -64,6 +64,22 @@ extern struct platform_device s3c_device_nand;
 extern struct platform_device s3c_device_usbgadget;
 extern struct platform_device s3c_device_usb_hsotg;
 
+extern struct platform_device s5pv210_device_ac97;
+extern struct platform_device s5pv210_device_pcm0;
+extern struct platform_device s5pv210_device_pcm1;
+extern struct platform_device s5pv210_device_pcm2;
+extern struct platform_device s5pv210_device_iis0;
+extern struct platform_device s5pv210_device_iis1;
+extern struct platform_device s5pv210_device_iis2;
+
+extern struct platform_device s5p6442_device_pcm0;
+extern struct platform_device s5p6442_device_pcm1;
+extern struct platform_device s5p6442_device_iis0;
+extern struct platform_device s5p6442_device_iis1;
+
+extern struct platform_device s5p6440_device_pcm;
+extern struct platform_device s5p6440_device_iis;
+
 /* s3c2440 specific devices */
 
 #ifdef CONFIG_CPU_S3C2440
index 7584d751ed513df477cdece38fa83d6a75473beb..2e8f8c6560d72128c92cdfa16b4f908565865216 100644 (file)
@@ -110,8 +110,8 @@ extern int s3c2410_dma_config(unsigned int channel, int xferunit);
  * configure the device we're talking to
 */
 
-extern int s3c2410_dma_devconfig(int channel, enum s3c2410_dmasrc source,
-                                unsigned long devaddr);
+extern int s3c2410_dma_devconfig(unsigned int channel,
+               enum s3c2410_dmasrc source, unsigned long devaddr);
 
 /* s3c2410_dma_getposition
  *
index ffc01a76b7cee362255c6dd94fb9a98bdc4c0bee..1f85649d8c18a46bb48b40d22e2e20032c728aef 100644 (file)
 #ifndef __PLAT_S3C_FB_H
 #define __PLAT_S3C_FB_H __FILE__
 
+/* S3C_FB_MAX_WIN
+ * Set to the maximum number of windows that any of the supported hardware
+ * can use. Since the platform data uses this for an array size, having it
+ * set to the maximum of any version of the hardware can do is safe.
+ */
+#define S3C_FB_MAX_WIN (5)
+
 /**
  * struct s3c_fb_pd_win - per window setup data
  * @win_mode: The display parameters to initialise (not for window 0)
index 8d01e853df3974a0ee109b80563324f747c9ebfa..34efdd2b032c718e94777a9286a8f0c4f41dd4d3 100644 (file)
@@ -25,6 +25,7 @@
 #define __PLAT_GPIO_CFG_H __FILE__
 
 typedef unsigned int __bitwise__ s3c_gpio_pull_t;
+typedef unsigned int __bitwise__ s5p_gpio_drvstr_t;
 
 /* forward declaration if gpio-core.h hasn't been included */
 struct s3c_gpio_chip;
@@ -118,4 +119,33 @@ extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull);
 */
 extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
 
+/* Define values for the drvstr available for each gpio pin.
+ *
+ * These values control the value of the output signal driver strength,
+ * configurable on most pins on the S5C series.
+ */
+#define S5P_GPIO_DRVSTR_LV1    ((__force s5p_gpio_drvstr_t)0x00)
+#define S5P_GPIO_DRVSTR_LV2    ((__force s5p_gpio_drvstr_t)0x01)
+#define S5P_GPIO_DRVSTR_LV3    ((__force s5p_gpio_drvstr_t)0x10)
+#define S5P_GPIO_DRVSTR_LV4    ((__force s5p_gpio_drvstr_t)0x11)
+
+/**
+ * s5c_gpio_get_drvstr() - get the driver streght value of a gpio pin
+ * @pin: The pin number to get the settings for
+ *
+ * Read the driver streght value for the specified pin.
+*/
+extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin);
+
+/**
+ * s3c_gpio_set_drvstr() - set the driver streght value of a gpio pin
+ * @pin: The pin number to configure the driver streght value
+ * @drvstr: The new value of the driver strength
+ *
+ * This function sets the driver strength value for the specified pin.
+ * It will return 0 if successfull, or a negative error code if the pin
+ * cannot support the requested setting.
+*/
+extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr);
+
 #endif /* __PLAT_GPIO_CFG_H */
index f0584f26d4931577c275b7edd6fea28980732319..f3a68d1a07b90f1284ae01a610be836ad7611286 100644 (file)
@@ -44,16 +44,26 @@ struct s3c_gpio_cfg;
  * @chip: The chip structure to be exported via gpiolib.
  * @base: The base pointer to the gpio configuration registers.
  * @config: special function and pull-resistor control information.
+ * @lock: Lock for exclusive access to this gpio bank.
  * @pm_save: Save information for suspend/resume support.
  *
  * This wrapper provides the necessary information for the Samsung
  * specific gpios being registered with gpiolib.
+ *
+ * The lock protects each gpio bank from multiple access of the shared
+ * configuration registers, or from reading of data whilst another thread
+ * is writing to the register set.
+ *
+ * Each chip has its own lock to avoid any  contention between different
+ * CPU cores trying to get one lock for different GPIO banks, where each
+ * bank of GPIO has its own register space and configuration registers.
  */
 struct s3c_gpio_chip {
        struct gpio_chip        chip;
        struct s3c_gpio_cfg     *config;
        struct s3c_gpio_pm      *pm;
        void __iomem            *base;
+       spinlock_t               lock;
 #ifdef CONFIG_PM
        u32                     pm_save[4];
 #endif
@@ -138,3 +148,7 @@ extern struct s3c_gpio_pm s3c_gpio_pm_4bit;
 #define __gpio_pm(x) NULL
 
 #endif /* CONFIG_PM */
+
+/* locking wrappers to deal with multiple access to the same gpio bank */
+#define s3c_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl)
+#define s3c_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl)
index 1ba88ea0aa319cde75944f40efaf4844f78868c0..c167e4429bc705a6fc58faa6709917065b518547 100644 (file)
@@ -37,5 +37,15 @@ struct s3c_hwmon_pdata {
        struct s3c_hwmon_chcfg  *in[8];
 };
 
+/**
+ * s3c_hwmon_set_platdata - Set platform data for S3C HWMON device
+ * @pd: Platform data to register to device.
+ *
+ * Register the given platform data for use with the S3C HWMON device.
+ * The call will copy the platform data, so the board definitions can
+ * make the structure itself __initdata.
+ */
+extern void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd);
+
 #endif /* __ASM_ARCH_ADC_HWMON_H */
 
diff --git a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
new file mode 100644 (file)
index 0000000..5fe6721
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ *     Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef        __S3C_DMA_PL330_H_
+#define        __S3C_DMA_PL330_H_
+
+#define S3C2410_DMAF_AUTOSTART         (1 << 0)
+#define S3C2410_DMAF_CIRCULAR          (1 << 1)
+
+/*
+ * PL330 can assign any channel to communicate with
+ * any of the peripherals attched to the DMAC.
+ * For the sake of consistency across client drivers,
+ * We keep the channel names unchanged and only add
+ * missing peripherals are added.
+ * Order is not important since S3C PL330 API driver
+ * use these just as IDs.
+ */
+enum dma_ch {
+       DMACH_UART0_RX,
+       DMACH_UART0_TX,
+       DMACH_UART1_RX,
+       DMACH_UART1_TX,
+       DMACH_UART2_RX,
+       DMACH_UART2_TX,
+       DMACH_UART3_RX,
+       DMACH_UART3_TX,
+       DMACH_IRDA,
+       DMACH_I2S0_RX,
+       DMACH_I2S0_TX,
+       DMACH_I2S0S_TX,
+       DMACH_I2S1_RX,
+       DMACH_I2S1_TX,
+       DMACH_I2S2_RX,
+       DMACH_I2S2_TX,
+       DMACH_SPI0_RX,
+       DMACH_SPI0_TX,
+       DMACH_SPI1_RX,
+       DMACH_SPI1_TX,
+       DMACH_SPI2_RX,
+       DMACH_SPI2_TX,
+       DMACH_AC97_MICIN,
+       DMACH_AC97_PCMIN,
+       DMACH_AC97_PCMOUT,
+       DMACH_EXTERNAL,
+       DMACH_PWM,
+       DMACH_SPDIF,
+       DMACH_HSI_RX,
+       DMACH_HSI_TX,
+       DMACH_PCM0_TX,
+       DMACH_PCM0_RX,
+       DMACH_PCM1_TX,
+       DMACH_PCM1_RX,
+       DMACH_PCM2_TX,
+       DMACH_PCM2_RX,
+       DMACH_MSM_REQ3,
+       DMACH_MSM_REQ2,
+       DMACH_MSM_REQ1,
+       DMACH_MSM_REQ0,
+       /* END Marker, also used to denote a reserved channel */
+       DMACH_MAX,
+};
+
+static inline bool s3c_dma_has_circular(void)
+{
+       return true;
+}
+
+#include <plat/dma.h>
+
+#endif /* __S3C_DMA_PL330_H_ */
diff --git a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
new file mode 100644 (file)
index 0000000..bf5e2a9
--- /dev/null
@@ -0,0 +1,32 @@
+/* linux/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
+ *
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ *     Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __S3C_PL330_PDATA_H
+#define __S3C_PL330_PDATA_H
+
+#include <plat/s3c-dma-pl330.h>
+
+/*
+ * Every PL330 DMAC has max 32 peripheral interfaces,
+ * of which some may be not be really used in your
+ * DMAC's configuration.
+ * Populate this array of 32 peri i/fs with relevant
+ * channel IDs for used peri i/f and DMACH_MAX for
+ * those unused.
+ *
+ * The platforms just need to provide this info
+ * to the S3C DMA API driver for PL330.
+ */
+struct s3c_pl330_platdata {
+       enum dma_ch peri[32];
+};
+
+#endif /* __S3C_PL330_PDATA_H */
similarity index 72%
rename from arch/arm/mach-s3c2410/include/mach/ts.h
rename to arch/arm/plat-samsung/include/plat/ts.h
index dc361700d6956f1bfe56f9b39c6a14e736fe8b01..26fdb22e0fc239e62d318aa3b1f0edf6e8d84c42 100644 (file)
@@ -1,4 +1,4 @@
-/* linux/include/asm/arch-s3c2410/ts.h
+/* arch/arm/plat-samsung/include/plat/ts.h
  *
  * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org>
  *
@@ -14,8 +14,12 @@ struct s3c2410_ts_mach_info {
        int             delay;
        int             presc;
        int             oversampling_shift;
+       void    (*cfg_gpio)(struct platform_device *dev);
 };
 
 extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *);
 
+/* defined by architecture to configure gpio */
+extern void s3c24xx_ts_cfg_gpio(struct platform_device *dev);
+
 #endif /* __ASM_ARM_TS_H */
index 69a4c7f02e25397b2d5b1086cb8028cc2699449e..d50ab9d2af53ff9083122f61097d69114757ae60 100644 (file)
@@ -329,7 +329,7 @@ void s3c_pm_save_gpios(void)
        struct s3c_gpio_chip *ourchip;
        unsigned int gpio_nr;
 
-       for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) {
+       for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
                ourchip = s3c_gpiolib_getchip(gpio_nr);
                if (!ourchip)
                        continue;
@@ -367,7 +367,7 @@ void s3c_pm_restore_gpios(void)
        struct s3c_gpio_chip *ourchip;
        unsigned int gpio_nr;
 
-       for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) {
+       for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
                ourchip = s3c_gpiolib_getchip(gpio_nr);
                if (!ourchip)
                        continue;
diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c
new file mode 100644 (file)
index 0000000..a91305a
--- /dev/null
@@ -0,0 +1,1224 @@
+/* linux/arch/arm/plat-samsung/s3c-pl330.c
+ *
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ *     Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware/pl330.h>
+
+#include <plat/s3c-pl330-pdata.h>
+
+/**
+ * struct s3c_pl330_dmac - Logical representation of a PL330 DMAC.
+ * @busy_chan: Number of channels currently busy.
+ * @peri: List of IDs of peripherals this DMAC can work with.
+ * @node: To attach to the global list of DMACs.
+ * @pi: PL330 configuration info for the DMAC.
+ * @kmcache: Pool to quickly allocate xfers for all channels in the dmac.
+ */
+struct s3c_pl330_dmac {
+       unsigned                busy_chan;
+       enum dma_ch             *peri;
+       struct list_head        node;
+       struct pl330_info       *pi;
+       struct kmem_cache       *kmcache;
+};
+
+/**
+ * struct s3c_pl330_xfer - A request submitted by S3C DMA clients.
+ * @token: Xfer ID provided by the client.
+ * @node: To attach to the list of xfers on a channel.
+ * @px: Xfer for PL330 core.
+ * @chan: Owner channel of this xfer.
+ */
+struct s3c_pl330_xfer {
+       void                    *token;
+       struct list_head        node;
+       struct pl330_xfer       px;
+       struct s3c_pl330_chan   *chan;
+};
+
+/**
+ * struct s3c_pl330_chan - Logical channel to communicate with
+ *     a Physical peripheral.
+ * @pl330_chan_id: Token of a hardware channel thread of PL330 DMAC.
+ *     NULL if the channel is available to be acquired.
+ * @id: ID of the peripheral that this channel can communicate with.
+ * @options: Options specified by the client.
+ * @sdaddr: Address provided via s3c2410_dma_devconfig.
+ * @node: To attach to the global list of channels.
+ * @lrq: Pointer to the last submitted pl330_req to PL330 core.
+ * @xfer_list: To manage list of xfers enqueued.
+ * @req: Two requests to communicate with the PL330 engine.
+ * @callback_fn: Callback function to the client.
+ * @rqcfg: Channel configuration for the xfers.
+ * @xfer_head: Pointer to the xfer to be next excecuted.
+ * @dmac: Pointer to the DMAC that manages this channel, NULL if the
+ *     channel is available to be acquired.
+ * @client: Client of this channel. NULL if the
+ *     channel is available to be acquired.
+ */
+struct s3c_pl330_chan {
+       void                            *pl330_chan_id;
+       enum dma_ch                     id;
+       unsigned int                    options;
+       unsigned long                   sdaddr;
+       struct list_head                node;
+       struct pl330_req                *lrq;
+       struct list_head                xfer_list;
+       struct pl330_req                req[2];
+       s3c2410_dma_cbfn_t              callback_fn;
+       struct pl330_reqcfg             rqcfg;
+       struct s3c_pl330_xfer           *xfer_head;
+       struct s3c_pl330_dmac           *dmac;
+       struct s3c2410_dma_client       *client;
+};
+
+/* All DMACs in the platform */
+static LIST_HEAD(dmac_list);
+
+/* All channels to peripherals in the platform */
+static LIST_HEAD(chan_list);
+
+/*
+ * Since we add resources(DMACs and Channels) to the global pool,
+ * we need to guard access to the resources using a global lock
+ */
+static DEFINE_SPINLOCK(res_lock);
+
+/* Returns the channel with ID 'id' in the chan_list */
+static struct s3c_pl330_chan *id_to_chan(const enum dma_ch id)
+{
+       struct s3c_pl330_chan *ch;
+
+       list_for_each_entry(ch, &chan_list, node)
+               if (ch->id == id)
+                       return ch;
+
+       return NULL;
+}
+
+/* Allocate a new channel with ID 'id' and add to chan_list */
+static void chan_add(const enum dma_ch id)
+{
+       struct s3c_pl330_chan *ch = id_to_chan(id);
+
+       /* Return if the channel already exists */
+       if (ch)
+               return;
+
+       ch = kmalloc(sizeof(*ch), GFP_KERNEL);
+       /* Return silently to work with other channels */
+       if (!ch)
+               return;
+
+       ch->id = id;
+       ch->dmac = NULL;
+
+       list_add_tail(&ch->node, &chan_list);
+}
+
+/* If the channel is not yet acquired by any client */
+static bool chan_free(struct s3c_pl330_chan *ch)
+{
+       if (!ch)
+               return false;
+
+       /* Channel points to some DMAC only when it's acquired */
+       return ch->dmac ? false : true;
+}
+
+/*
+ * Returns 0 is peripheral i/f is invalid or not present on the dmac.
+ * Index + 1, otherwise.
+ */
+static unsigned iface_of_dmac(struct s3c_pl330_dmac *dmac, enum dma_ch ch_id)
+{
+       enum dma_ch *id = dmac->peri;
+       int i;
+
+       /* Discount invalid markers */
+       if (ch_id == DMACH_MAX)
+               return 0;
+
+       for (i = 0; i < PL330_MAX_PERI; i++)
+               if (id[i] == ch_id)
+                       return i + 1;
+
+       return 0;
+}
+
+/* If all channel threads of the DMAC are busy */
+static inline bool dmac_busy(struct s3c_pl330_dmac *dmac)
+{
+       struct pl330_info *pi = dmac->pi;
+
+       return (dmac->busy_chan < pi->pcfg.num_chan) ? false : true;
+}
+
+/*
+ * Returns the number of free channels that
+ * can be handled by this dmac only.
+ */
+static unsigned ch_onlyby_dmac(struct s3c_pl330_dmac *dmac)
+{
+       enum dma_ch *id = dmac->peri;
+       struct s3c_pl330_dmac *d;
+       struct s3c_pl330_chan *ch;
+       unsigned found, count = 0;
+       enum dma_ch p;
+       int i;
+
+       for (i = 0; i < PL330_MAX_PERI; i++) {
+               p = id[i];
+               ch = id_to_chan(p);
+
+               if (p == DMACH_MAX || !chan_free(ch))
+                       continue;
+
+               found = 0;
+               list_for_each_entry(d, &dmac_list, node) {
+                       if (d != dmac && iface_of_dmac(d, ch->id)) {
+                               found = 1;
+                               break;
+                       }
+               }
+               if (!found)
+                       count++;
+       }
+
+       return count;
+}
+
+/*
+ * Measure of suitability of 'dmac' handling 'ch'
+ *
+ * 0 indicates 'dmac' can not handle 'ch' either
+ * because it is not supported by the hardware or
+ * because all dmac channels are currently busy.
+ *
+ * >0 vlaue indicates 'dmac' has the capability.
+ * The bigger the value the more suitable the dmac.
+ */
+#define MAX_SUIT       UINT_MAX
+#define MIN_SUIT       0
+
+static unsigned suitablility(struct s3c_pl330_dmac *dmac,
+               struct s3c_pl330_chan *ch)
+{
+       struct pl330_info *pi = dmac->pi;
+       enum dma_ch *id = dmac->peri;
+       struct s3c_pl330_dmac *d;
+       unsigned s;
+       int i;
+
+       s = MIN_SUIT;
+       /* If all the DMAC channel threads are busy */
+       if (dmac_busy(dmac))
+               return s;
+
+       for (i = 0; i < PL330_MAX_PERI; i++)
+               if (id[i] == ch->id)
+                       break;
+
+       /* If the 'dmac' can't talk to 'ch' */
+       if (i == PL330_MAX_PERI)
+               return s;
+
+       s = MAX_SUIT;
+       list_for_each_entry(d, &dmac_list, node) {
+               /*
+                * If some other dmac can talk to this
+                * peri and has some channel free.
+                */
+               if (d != dmac && iface_of_dmac(d, ch->id) && !dmac_busy(d)) {
+                       s = 0;
+                       break;
+               }
+       }
+       if (s)
+               return s;
+
+       s = 100;
+
+       /* Good if free chans are more, bad otherwise */
+       s += (pi->pcfg.num_chan - dmac->busy_chan) - ch_onlyby_dmac(dmac);
+
+       return s;
+}
+
+/* More than one DMAC may have capability to transfer data with the
+ * peripheral. This function assigns most suitable DMAC to manage the
+ * channel and hence communicate with the peripheral.
+ */
+static struct s3c_pl330_dmac *map_chan_to_dmac(struct s3c_pl330_chan *ch)
+{
+       struct s3c_pl330_dmac *d, *dmac = NULL;
+       unsigned sn, sl = MIN_SUIT;
+
+       list_for_each_entry(d, &dmac_list, node) {
+               sn = suitablility(d, ch);
+
+               if (sn == MAX_SUIT)
+                       return d;
+
+               if (sn > sl)
+                       dmac = d;
+       }
+
+       return dmac;
+}
+
+/* Acquire the channel for peripheral 'id' */
+static struct s3c_pl330_chan *chan_acquire(const enum dma_ch id)
+{
+       struct s3c_pl330_chan *ch = id_to_chan(id);
+       struct s3c_pl330_dmac *dmac;
+
+       /* If the channel doesn't exist or is already acquired */
+       if (!ch || !chan_free(ch)) {
+               ch = NULL;
+               goto acq_exit;
+       }
+
+       dmac = map_chan_to_dmac(ch);
+       /* If couldn't map */
+       if (!dmac) {
+               ch = NULL;
+               goto acq_exit;
+       }
+
+       dmac->busy_chan++;
+       ch->dmac = dmac;
+
+acq_exit:
+       return ch;
+}
+
+/* Delete xfer from the queue */
+static inline void del_from_queue(struct s3c_pl330_xfer *xfer)
+{
+       struct s3c_pl330_xfer *t;
+       struct s3c_pl330_chan *ch;
+       int found;
+
+       if (!xfer)
+               return;
+
+       ch = xfer->chan;
+
+       /* Make sure xfer is in the queue */
+       found = 0;
+       list_for_each_entry(t, &ch->xfer_list, node)
+               if (t == xfer) {
+                       found = 1;
+                       break;
+               }
+
+       if (!found)
+               return;
+
+       /* If xfer is last entry in the queue */
+       if (xfer->node.next == &ch->xfer_list)
+               t = list_entry(ch->xfer_list.next,
+                               struct s3c_pl330_xfer, node);
+       else
+               t = list_entry(xfer->node.next,
+                               struct s3c_pl330_xfer, node);
+
+       /* If there was only one node left */
+       if (t == xfer)
+               ch->xfer_head = NULL;
+       else if (ch->xfer_head == xfer)
+               ch->xfer_head = t;
+
+       list_del(&xfer->node);
+}
+
+/* Provides pointer to the next xfer in the queue.
+ * If CIRCULAR option is set, the list is left intact,
+ * otherwise the xfer is removed from the list.
+ * Forced delete 'pluck' can be set to override the CIRCULAR option.
+ */
+static struct s3c_pl330_xfer *get_from_queue(struct s3c_pl330_chan *ch,
+               int pluck)
+{
+       struct s3c_pl330_xfer *xfer = ch->xfer_head;
+
+       if (!xfer)
+               return NULL;
+
+       /* If xfer is last entry in the queue */
+       if (xfer->node.next == &ch->xfer_list)
+               ch->xfer_head = list_entry(ch->xfer_list.next,
+                                       struct s3c_pl330_xfer, node);
+       else
+               ch->xfer_head = list_entry(xfer->node.next,
+                                       struct s3c_pl330_xfer, node);
+
+       if (pluck || !(ch->options & S3C2410_DMAF_CIRCULAR))
+               del_from_queue(xfer);
+
+       return xfer;
+}
+
+static inline void add_to_queue(struct s3c_pl330_chan *ch,
+               struct s3c_pl330_xfer *xfer, int front)
+{
+       struct pl330_xfer *xt;
+
+       /* If queue empty */
+       if (ch->xfer_head == NULL)
+               ch->xfer_head = xfer;
+
+       xt = &ch->xfer_head->px;
+       /* If the head already submitted (CIRCULAR head) */
+       if (ch->options & S3C2410_DMAF_CIRCULAR &&
+               (xt == ch->req[0].x || xt == ch->req[1].x))
+               ch->xfer_head = xfer;
+
+       /* If this is a resubmission, it should go at the head */
+       if (front) {
+               ch->xfer_head = xfer;
+               list_add(&xfer->node, &ch->xfer_list);
+       } else {
+               list_add_tail(&xfer->node, &ch->xfer_list);
+       }
+}
+
+static inline void _finish_off(struct s3c_pl330_xfer *xfer,
+               enum s3c2410_dma_buffresult res, int ffree)
+{
+       struct s3c_pl330_chan *ch;
+
+       if (!xfer)
+               return;
+
+       ch = xfer->chan;
+
+       /* Do callback */
+       if (ch->callback_fn)
+               ch->callback_fn(NULL, xfer->token, xfer->px.bytes, res);
+
+       /* Force Free or if buffer is not needed anymore */
+       if (ffree || !(ch->options & S3C2410_DMAF_CIRCULAR))
+               kmem_cache_free(ch->dmac->kmcache, xfer);
+}
+
+static inline int s3c_pl330_submit(struct s3c_pl330_chan *ch,
+               struct pl330_req *r)
+{
+       struct s3c_pl330_xfer *xfer;
+       int ret = 0;
+
+       /* If already submitted */
+       if (r->x)
+               return 0;
+
+       xfer = get_from_queue(ch, 0);
+       if (xfer) {
+               r->x = &xfer->px;
+
+               /* Use max bandwidth for M<->M xfers */
+               if (r->rqtype == MEMTOMEM) {
+                       struct pl330_info *pi = xfer->chan->dmac->pi;
+                       int burst = 1 << ch->rqcfg.brst_size;
+                       u32 bytes = r->x->bytes;
+                       int bl;
+
+                       bl = pi->pcfg.data_bus_width / 8;
+                       bl *= pi->pcfg.data_buf_dep;
+                       bl /= burst;
+
+                       /* src/dst_burst_len can't be more than 16 */
+                       if (bl > 16)
+                               bl = 16;
+
+                       while (bl > 1) {
+                               if (!(bytes % (bl * burst)))
+                                       break;
+                               bl--;
+                       }
+
+                       ch->rqcfg.brst_len = bl;
+               } else {
+                       ch->rqcfg.brst_len = 1;
+               }
+
+               ret = pl330_submit_req(ch->pl330_chan_id, r);
+
+               /* If submission was successful */
+               if (!ret) {
+                       ch->lrq = r; /* latest submitted req */
+                       return 0;
+               }
+
+               r->x = NULL;
+
+               /* If both of the PL330 ping-pong buffers filled */
+               if (ret == -EAGAIN) {
+                       dev_err(ch->dmac->pi->dev, "%s:%d!\n",
+                               __func__, __LINE__);
+                       /* Queue back again */
+                       add_to_queue(ch, xfer, 1);
+                       ret = 0;
+               } else {
+                       dev_err(ch->dmac->pi->dev, "%s:%d!\n",
+                               __func__, __LINE__);
+                       _finish_off(xfer, S3C2410_RES_ERR, 0);
+               }
+       }
+
+       return ret;
+}
+
+static void s3c_pl330_rq(struct s3c_pl330_chan *ch,
+       struct pl330_req *r, enum pl330_op_err err)
+{
+       unsigned long flags;
+       struct s3c_pl330_xfer *xfer;
+       struct pl330_xfer *xl = r->x;
+       enum s3c2410_dma_buffresult res;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       r->x = NULL;
+
+       s3c_pl330_submit(ch, r);
+
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       /* Map result to S3C DMA API */
+       if (err == PL330_ERR_NONE)
+               res = S3C2410_RES_OK;
+       else if (err == PL330_ERR_ABORT)
+               res = S3C2410_RES_ABORT;
+       else
+               res = S3C2410_RES_ERR;
+
+       /* If last request had some xfer */
+       if (xl) {
+               xfer = container_of(xl, struct s3c_pl330_xfer, px);
+               _finish_off(xfer, res, 0);
+       } else {
+               dev_info(ch->dmac->pi->dev, "%s:%d No Xfer?!\n",
+                       __func__, __LINE__);
+       }
+}
+
+static void s3c_pl330_rq0(void *token, enum pl330_op_err err)
+{
+       struct pl330_req *r = token;
+       struct s3c_pl330_chan *ch = container_of(r,
+                                       struct s3c_pl330_chan, req[0]);
+       s3c_pl330_rq(ch, r, err);
+}
+
+static void s3c_pl330_rq1(void *token, enum pl330_op_err err)
+{
+       struct pl330_req *r = token;
+       struct s3c_pl330_chan *ch = container_of(r,
+                                       struct s3c_pl330_chan, req[1]);
+       s3c_pl330_rq(ch, r, err);
+}
+
+/* Release an acquired channel */
+static void chan_release(struct s3c_pl330_chan *ch)
+{
+       struct s3c_pl330_dmac *dmac;
+
+       if (chan_free(ch))
+               return;
+
+       dmac = ch->dmac;
+       ch->dmac = NULL;
+       dmac->busy_chan--;
+}
+
+int s3c2410_dma_ctrl(enum dma_ch id, enum s3c2410_chan_op op)
+{
+       struct s3c_pl330_xfer *xfer;
+       enum pl330_chan_op pl330op;
+       struct s3c_pl330_chan *ch;
+       unsigned long flags;
+       int idx, ret;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       ch = id_to_chan(id);
+
+       if (!ch || chan_free(ch)) {
+               ret = -EINVAL;
+               goto ctrl_exit;
+       }
+
+       switch (op) {
+       case S3C2410_DMAOP_START:
+               /* Make sure both reqs are enqueued */
+               idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
+               s3c_pl330_submit(ch, &ch->req[idx]);
+               s3c_pl330_submit(ch, &ch->req[1 - idx]);
+               pl330op = PL330_OP_START;
+               break;
+
+       case S3C2410_DMAOP_STOP:
+               pl330op = PL330_OP_ABORT;
+               break;
+
+       case S3C2410_DMAOP_FLUSH:
+               pl330op = PL330_OP_FLUSH;
+               break;
+
+       case S3C2410_DMAOP_PAUSE:
+       case S3C2410_DMAOP_RESUME:
+       case S3C2410_DMAOP_TIMEOUT:
+       case S3C2410_DMAOP_STARTED:
+               spin_unlock_irqrestore(&res_lock, flags);
+               return 0;
+
+       default:
+               spin_unlock_irqrestore(&res_lock, flags);
+               return -EINVAL;
+       }
+
+       ret = pl330_chan_ctrl(ch->pl330_chan_id, pl330op);
+
+       if (pl330op == PL330_OP_START) {
+               spin_unlock_irqrestore(&res_lock, flags);
+               return ret;
+       }
+
+       idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
+
+       /* Abort the current xfer */
+       if (ch->req[idx].x) {
+               xfer = container_of(ch->req[idx].x,
+                               struct s3c_pl330_xfer, px);
+
+               /* Drop xfer during FLUSH */
+               if (pl330op == PL330_OP_FLUSH)
+                       del_from_queue(xfer);
+
+               ch->req[idx].x = NULL;
+
+               spin_unlock_irqrestore(&res_lock, flags);
+               _finish_off(xfer, S3C2410_RES_ABORT,
+                               pl330op == PL330_OP_FLUSH ? 1 : 0);
+               spin_lock_irqsave(&res_lock, flags);
+       }
+
+       /* Flush the whole queue */
+       if (pl330op == PL330_OP_FLUSH) {
+
+               if (ch->req[1 - idx].x) {
+                       xfer = container_of(ch->req[1 - idx].x,
+                                       struct s3c_pl330_xfer, px);
+
+                       del_from_queue(xfer);
+
+                       ch->req[1 - idx].x = NULL;
+
+                       spin_unlock_irqrestore(&res_lock, flags);
+                       _finish_off(xfer, S3C2410_RES_ABORT, 1);
+                       spin_lock_irqsave(&res_lock, flags);
+               }
+
+               /* Finish off the remaining in the queue */
+               xfer = ch->xfer_head;
+               while (xfer) {
+
+                       del_from_queue(xfer);
+
+                       spin_unlock_irqrestore(&res_lock, flags);
+                       _finish_off(xfer, S3C2410_RES_ABORT, 1);
+                       spin_lock_irqsave(&res_lock, flags);
+
+                       xfer = ch->xfer_head;
+               }
+       }
+
+ctrl_exit:
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_ctrl);
+
+int s3c2410_dma_enqueue(enum dma_ch id, void *token,
+                       dma_addr_t addr, int size)
+{
+       struct s3c_pl330_chan *ch;
+       struct s3c_pl330_xfer *xfer;
+       unsigned long flags;
+       int idx, ret = 0;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       ch = id_to_chan(id);
+
+       /* Error if invalid or free channel */
+       if (!ch || chan_free(ch)) {
+               ret = -EINVAL;
+               goto enq_exit;
+       }
+
+       /* Error if size is unaligned */
+       if (ch->rqcfg.brst_size && size % (1 << ch->rqcfg.brst_size)) {
+               ret = -EINVAL;
+               goto enq_exit;
+       }
+
+       xfer = kmem_cache_alloc(ch->dmac->kmcache, GFP_ATOMIC);
+       if (!xfer) {
+               ret = -ENOMEM;
+               goto enq_exit;
+       }
+
+       xfer->token = token;
+       xfer->chan = ch;
+       xfer->px.bytes = size;
+       xfer->px.next = NULL; /* Single request */
+
+       /* For S3C DMA API, direction is always fixed for all xfers */
+       if (ch->req[0].rqtype == MEMTODEV) {
+               xfer->px.src_addr = addr;
+               xfer->px.dst_addr = ch->sdaddr;
+       } else {
+               xfer->px.src_addr = ch->sdaddr;
+               xfer->px.dst_addr = addr;
+       }
+
+       add_to_queue(ch, xfer, 0);
+
+       /* Try submitting on either request */
+       idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
+
+       if (!ch->req[idx].x)
+               s3c_pl330_submit(ch, &ch->req[idx]);
+       else
+               s3c_pl330_submit(ch, &ch->req[1 - idx]);
+
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       if (ch->options & S3C2410_DMAF_AUTOSTART)
+               s3c2410_dma_ctrl(id, S3C2410_DMAOP_START);
+
+       return 0;
+
+enq_exit:
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_enqueue);
+
+int s3c2410_dma_request(enum dma_ch id,
+                       struct s3c2410_dma_client *client,
+                       void *dev)
+{
+       struct s3c_pl330_dmac *dmac;
+       struct s3c_pl330_chan *ch;
+       unsigned long flags;
+       int ret = 0;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       ch = chan_acquire(id);
+       if (!ch) {
+               ret = -EBUSY;
+               goto req_exit;
+       }
+
+       dmac = ch->dmac;
+
+       ch->pl330_chan_id = pl330_request_channel(dmac->pi);
+       if (!ch->pl330_chan_id) {
+               chan_release(ch);
+               ret = -EBUSY;
+               goto req_exit;
+       }
+
+       ch->client = client;
+       ch->options = 0; /* Clear any option */
+       ch->callback_fn = NULL; /* Clear any callback */
+       ch->lrq = NULL;
+
+       ch->rqcfg.brst_size = 2; /* Default word size */
+       ch->rqcfg.swap = SWAP_NO;
+       ch->rqcfg.scctl = SCCTRL0; /* Noncacheable and nonbufferable */
+       ch->rqcfg.dcctl = DCCTRL0; /* Noncacheable and nonbufferable */
+       ch->rqcfg.privileged = 0;
+       ch->rqcfg.insnaccess = 0;
+
+       /* Set invalid direction */
+       ch->req[0].rqtype = DEVTODEV;
+       ch->req[1].rqtype = ch->req[0].rqtype;
+
+       ch->req[0].cfg = &ch->rqcfg;
+       ch->req[1].cfg = ch->req[0].cfg;
+
+       ch->req[0].peri = iface_of_dmac(dmac, id) - 1; /* Original index */
+       ch->req[1].peri = ch->req[0].peri;
+
+       ch->req[0].token = &ch->req[0];
+       ch->req[0].xfer_cb = s3c_pl330_rq0;
+       ch->req[1].token = &ch->req[1];
+       ch->req[1].xfer_cb = s3c_pl330_rq1;
+
+       ch->req[0].x = NULL;
+       ch->req[1].x = NULL;
+
+       /* Reset xfer list */
+       INIT_LIST_HEAD(&ch->xfer_list);
+       ch->xfer_head = NULL;
+
+req_exit:
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_request);
+
+int s3c2410_dma_free(enum dma_ch id, struct s3c2410_dma_client *client)
+{
+       struct s3c_pl330_chan *ch;
+       struct s3c_pl330_xfer *xfer;
+       unsigned long flags;
+       int ret = 0;
+       unsigned idx;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       ch = id_to_chan(id);
+
+       if (!ch || chan_free(ch))
+               goto free_exit;
+
+       /* Refuse if someone else wanted to free the channel */
+       if (ch->client != client) {
+               ret = -EBUSY;
+               goto free_exit;
+       }
+
+       /* Stop any active xfer, Flushe the queue and do callbacks */
+       pl330_chan_ctrl(ch->pl330_chan_id, PL330_OP_FLUSH);
+
+       /* Abort the submitted requests */
+       idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
+
+       if (ch->req[idx].x) {
+               xfer = container_of(ch->req[idx].x,
+                               struct s3c_pl330_xfer, px);
+
+               ch->req[idx].x = NULL;
+               del_from_queue(xfer);
+
+               spin_unlock_irqrestore(&res_lock, flags);
+               _finish_off(xfer, S3C2410_RES_ABORT, 1);
+               spin_lock_irqsave(&res_lock, flags);
+       }
+
+       if (ch->req[1 - idx].x) {
+               xfer = container_of(ch->req[1 - idx].x,
+                               struct s3c_pl330_xfer, px);
+
+               ch->req[1 - idx].x = NULL;
+               del_from_queue(xfer);
+
+               spin_unlock_irqrestore(&res_lock, flags);
+               _finish_off(xfer, S3C2410_RES_ABORT, 1);
+               spin_lock_irqsave(&res_lock, flags);
+       }
+
+       /* Pluck and Abort the queued requests in order */
+       do {
+               xfer = get_from_queue(ch, 1);
+
+               spin_unlock_irqrestore(&res_lock, flags);
+               _finish_off(xfer, S3C2410_RES_ABORT, 1);
+               spin_lock_irqsave(&res_lock, flags);
+       } while (xfer);
+
+       ch->client = NULL;
+
+       pl330_release_channel(ch->pl330_chan_id);
+
+       ch->pl330_chan_id = NULL;
+
+       chan_release(ch);
+
+free_exit:
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_free);
+
+int s3c2410_dma_config(enum dma_ch id, int xferunit)
+{
+       struct s3c_pl330_chan *ch;
+       struct pl330_info *pi;
+       unsigned long flags;
+       int i, dbwidth, ret = 0;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       ch = id_to_chan(id);
+
+       if (!ch || chan_free(ch)) {
+               ret = -EINVAL;
+               goto cfg_exit;
+       }
+
+       pi = ch->dmac->pi;
+       dbwidth = pi->pcfg.data_bus_width / 8;
+
+       /* Max size of xfer can be pcfg.data_bus_width */
+       if (xferunit > dbwidth) {
+               ret = -EINVAL;
+               goto cfg_exit;
+       }
+
+       i = 0;
+       while (xferunit != (1 << i))
+               i++;
+
+       /* If valid value */
+       if (xferunit == (1 << i))
+               ch->rqcfg.brst_size = i;
+       else
+               ret = -EINVAL;
+
+cfg_exit:
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_config);
+
+/* Options that are supported by this driver */
+#define S3C_PL330_FLAGS (S3C2410_DMAF_CIRCULAR | S3C2410_DMAF_AUTOSTART)
+
+int s3c2410_dma_setflags(enum dma_ch id, unsigned int options)
+{
+       struct s3c_pl330_chan *ch;
+       unsigned long flags;
+       int ret = 0;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       ch = id_to_chan(id);
+
+       if (!ch || chan_free(ch) || options & ~(S3C_PL330_FLAGS))
+               ret = -EINVAL;
+       else
+               ch->options = options;
+
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_setflags);
+
+int s3c2410_dma_set_buffdone_fn(enum dma_ch id, s3c2410_dma_cbfn_t rtn)
+{
+       struct s3c_pl330_chan *ch;
+       unsigned long flags;
+       int ret = 0;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       ch = id_to_chan(id);
+
+       if (!ch || chan_free(ch))
+               ret = -EINVAL;
+       else
+               ch->callback_fn = rtn;
+
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
+
+int s3c2410_dma_devconfig(enum dma_ch id, enum s3c2410_dmasrc source,
+                         unsigned long address)
+{
+       struct s3c_pl330_chan *ch;
+       unsigned long flags;
+       int ret = 0;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       ch = id_to_chan(id);
+
+       if (!ch || chan_free(ch)) {
+               ret = -EINVAL;
+               goto devcfg_exit;
+       }
+
+       switch (source) {
+       case S3C2410_DMASRC_HW: /* P->M */
+               ch->req[0].rqtype = DEVTOMEM;
+               ch->req[1].rqtype = DEVTOMEM;
+               ch->rqcfg.src_inc = 0;
+               ch->rqcfg.dst_inc = 1;
+               break;
+       case S3C2410_DMASRC_MEM: /* M->P */
+               ch->req[0].rqtype = MEMTODEV;
+               ch->req[1].rqtype = MEMTODEV;
+               ch->rqcfg.src_inc = 1;
+               ch->rqcfg.dst_inc = 0;
+               break;
+       default:
+               ret = -EINVAL;
+               goto devcfg_exit;
+       }
+
+       ch->sdaddr = address;
+
+devcfg_exit:
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_devconfig);
+
+int s3c2410_dma_getposition(enum dma_ch id, dma_addr_t *src, dma_addr_t *dst)
+{
+       struct s3c_pl330_chan *ch = id_to_chan(id);
+       struct pl330_chanstatus status;
+       int ret;
+
+       if (!ch || chan_free(ch))
+               return -EINVAL;
+
+       ret = pl330_chan_status(ch->pl330_chan_id, &status);
+       if (ret < 0)
+               return ret;
+
+       *src = status.src_addr;
+       *dst = status.dst_addr;
+
+       return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_getposition);
+
+static irqreturn_t pl330_irq_handler(int irq, void *data)
+{
+       if (pl330_update(data))
+               return IRQ_HANDLED;
+       else
+               return IRQ_NONE;
+}
+
+static int pl330_probe(struct platform_device *pdev)
+{
+       struct s3c_pl330_dmac *s3c_pl330_dmac;
+       struct s3c_pl330_platdata *pl330pd;
+       struct pl330_info *pl330_info;
+       struct resource *res;
+       int i, ret, irq;
+
+       pl330pd = pdev->dev.platform_data;
+
+       /* Can't do without the list of _32_ peripherals */
+       if (!pl330pd || !pl330pd->peri) {
+               dev_err(&pdev->dev, "platform data missing!\n");
+               return -ENODEV;
+       }
+
+       pl330_info = kzalloc(sizeof(*pl330_info), GFP_KERNEL);
+       if (!pl330_info)
+               return -ENOMEM;
+
+       pl330_info->pl330_data = NULL;
+       pl330_info->dev = &pdev->dev;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               ret = -ENODEV;
+               goto probe_err1;
+       }
+
+       request_mem_region(res->start, resource_size(res), pdev->name);
+
+       pl330_info->base = ioremap(res->start, resource_size(res));
+       if (!pl330_info->base) {
+               ret = -ENXIO;
+               goto probe_err2;
+       }
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               ret = irq;
+               goto probe_err3;
+       }
+
+       ret = request_irq(irq, pl330_irq_handler, 0,
+                       dev_name(&pdev->dev), pl330_info);
+       if (ret)
+               goto probe_err4;
+
+       ret = pl330_add(pl330_info);
+       if (ret)
+               goto probe_err5;
+
+       /* Allocate a new DMAC */
+       s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL);
+       if (!s3c_pl330_dmac) {
+               ret = -ENOMEM;
+               goto probe_err6;
+       }
+
+       /* Hook the info */
+       s3c_pl330_dmac->pi = pl330_info;
+
+       /* No busy channels */
+       s3c_pl330_dmac->busy_chan = 0;
+
+       s3c_pl330_dmac->kmcache = kmem_cache_create(dev_name(&pdev->dev),
+                               sizeof(struct s3c_pl330_xfer), 0, 0, NULL);
+
+       if (!s3c_pl330_dmac->kmcache) {
+               ret = -ENOMEM;
+               goto probe_err7;
+       }
+
+       /* Get the list of peripherals */
+       s3c_pl330_dmac->peri = pl330pd->peri;
+
+       /* Attach to the list of DMACs */
+       list_add_tail(&s3c_pl330_dmac->node, &dmac_list);
+
+       /* Create a channel for each peripheral in the DMAC
+        * that is, if it doesn't already exist
+        */
+       for (i = 0; i < PL330_MAX_PERI; i++)
+               if (s3c_pl330_dmac->peri[i] != DMACH_MAX)
+                       chan_add(s3c_pl330_dmac->peri[i]);
+
+       printk(KERN_INFO
+               "Loaded driver for PL330 DMAC-%d %s\n", pdev->id, pdev->name);
+       printk(KERN_INFO
+               "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n",
+               pl330_info->pcfg.data_buf_dep,
+               pl330_info->pcfg.data_bus_width / 8, pl330_info->pcfg.num_chan,
+               pl330_info->pcfg.num_peri, pl330_info->pcfg.num_events);
+
+       return 0;
+
+probe_err7:
+       kfree(s3c_pl330_dmac);
+probe_err6:
+       pl330_del(pl330_info);
+probe_err5:
+       free_irq(irq, pl330_info);
+probe_err4:
+probe_err3:
+       iounmap(pl330_info->base);
+probe_err2:
+       release_mem_region(res->start, resource_size(res));
+probe_err1:
+       kfree(pl330_info);
+
+       return ret;
+}
+
+static int pl330_remove(struct platform_device *pdev)
+{
+       struct s3c_pl330_dmac *dmac, *d;
+       struct s3c_pl330_chan *ch;
+       unsigned long flags;
+       int del, found;
+
+       if (!pdev->dev.platform_data)
+               return -EINVAL;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       found = 0;
+       list_for_each_entry(d, &dmac_list, node)
+               if (d->pi->dev == &pdev->dev) {
+                       found = 1;
+                       break;
+               }
+
+       if (!found) {
+               spin_unlock_irqrestore(&res_lock, flags);
+               return 0;
+       }
+
+       dmac = d;
+
+       /* Remove all Channels that are managed only by this DMAC */
+       list_for_each_entry(ch, &chan_list, node) {
+
+               /* Only channels that are handled by this DMAC */
+               if (iface_of_dmac(dmac, ch->id))
+                       del = 1;
+               else
+                       continue;
+
+               /* Don't remove if some other DMAC has it too */
+               list_for_each_entry(d, &dmac_list, node)
+                       if (d != dmac && iface_of_dmac(d, ch->id)) {
+                               del = 0;
+                               break;
+                       }
+
+               if (del) {
+                       spin_unlock_irqrestore(&res_lock, flags);
+                       s3c2410_dma_free(ch->id, ch->client);
+                       spin_lock_irqsave(&res_lock, flags);
+                       list_del(&ch->node);
+                       kfree(ch);
+               }
+       }
+
+       /* Remove the DMAC */
+       list_del(&dmac->node);
+       kfree(dmac);
+
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       return 0;
+}
+
+static struct platform_driver pl330_driver = {
+       .driver         = {
+               .owner  = THIS_MODULE,
+               .name   = "s3c-pl330",
+       },
+       .probe          = pl330_probe,
+       .remove         = pl330_remove,
+};
+
+static int __init pl330_init(void)
+{
+       return platform_driver_register(&pl330_driver);
+}
+module_init(pl330_init);
+
+static void __exit pl330_exit(void)
+{
+       platform_driver_unregister(&pl330_driver);
+       return;
+}
+module_exit(pl330_exit);
+
+MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");
+MODULE_DESCRIPTION("Driver for PL330 DMA Controller");
+MODULE_LICENSE("GPL");
index 3d1ade2e51964d89532f4094dcecea60121527e1..6c0f1712f55bbb2d2a75a6f9a8a35f1f5fe728e4 100644 (file)
@@ -142,8 +142,8 @@ config TOUCHSCREEN_FUJITSU
          module will be called fujitsu-ts.
 
 config TOUCHSCREEN_S3C2410
-       tristate "Samsung S3C2410 touchscreen input driver"
-       depends on ARCH_S3C2410
+       tristate "Samsung S3C2410/generic touchscreen input driver"
+       depends on ARCH_S3C2410 || SAMSUNG_DEV_TS
        select S3C24XX_ADC
        help
          Say Y here if you have the s3c2410 touchscreen.
index 98a7d1279486f1fb4ad7dca35314b7d021b9f6f3..e0b7c834111d37467b1b6454828f5ad071ddcae9 100644 (file)
@@ -37,9 +37,7 @@
 
 #include <plat/adc.h>
 #include <plat/regs-adc.h>
-
-#include <mach/regs-gpio.h>
-#include <mach/ts.h>
+#include <plat/ts.h>
 
 #define TSC_SLEEP  (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0))
 
@@ -57,6 +55,8 @@
                         S3C2410_ADCTSC_AUTO_PST | \
                         S3C2410_ADCTSC_XY_PST(0))
 
+#define FEAT_PEN_IRQ   (1 << 0)        /* HAS ADCCLRINTPNDNUP */
+
 /* Per-touchscreen data. */
 
 /**
@@ -71,6 +71,7 @@
  * @irq_tc: The interrupt number for pen up/down interrupt
  * @count: The number of samples collected.
  * @shift: The log2 of the maximum count to read in one go.
+ * @features: The features supported by the TSADC MOdule.
  */
 struct s3c2410ts {
        struct s3c_adc_client *client;
@@ -83,25 +84,11 @@ struct s3c2410ts {
        int irq_tc;
        int count;
        int shift;
+       int features;
 };
 
 static struct s3c2410ts ts;
 
-/**
- * s3c2410_ts_connect - configure gpio for s3c2410 systems
- *
- * Configure the GPIO for the S3C2410 system, where we have external FETs
- * connected to the device (later systems such as the S3C2440 integrate
- * these into the device).
-*/
-static inline void s3c2410_ts_connect(void)
-{
-       s3c2410_gpio_cfgpin(S3C2410_GPG(12), S3C2410_GPG12_XMON);
-       s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPG13_nXPON);
-       s3c2410_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPG14_YMON);
-       s3c2410_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPG15_nYPON);
-}
-
 /**
  * get_down - return the down state of the pen
  * @data0: The data read from ADCDAT0 register.
@@ -188,6 +175,11 @@ static irqreturn_t stylus_irq(int irq, void *dev_id)
        else
                dev_info(ts.dev, "%s: count=%d\n", __func__, ts.count);
 
+       if (ts.features & FEAT_PEN_IRQ) {
+               /* Clear pen down/up interrupt */
+               writel(0x0, ts.io + S3C64XX_ADCCLRINTPNDNUP);
+       }
+
        return IRQ_HANDLED;
 }
 
@@ -296,9 +288,9 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev)
                goto err_clk;
        }
 
-       /* Configure the touchscreen external FETs on the S3C2410 */
-       if (!platform_get_device_id(pdev)->driver_data)
-               s3c2410_ts_connect();
+       /* inititalise the gpio */
+       if (info->cfg_gpio)
+               info->cfg_gpio(to_platform_device(ts.dev));
 
        ts.client = s3c_adc_register(pdev, s3c24xx_ts_select,
                                     s3c24xx_ts_conversion, 1);
@@ -334,6 +326,7 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev)
        ts.input->id.version = 0x0102;
 
        ts.shift = info->oversampling_shift;
+       ts.features = platform_get_device_id(pdev)->driver_data;
 
        ret = request_irq(ts.irq_tc, stylus_irq, IRQF_DISABLED,
                          "s3c2410_ts_pen", ts.input);
@@ -420,15 +413,14 @@ static struct dev_pm_ops s3c_ts_pmops = {
 #endif
 
 static struct platform_device_id s3cts_driver_ids[] = {
-       { "s3c2410-ts", 0 },
-       { "s3c2440-ts", 1 },
+       { "s3c64xx-ts", FEAT_PEN_IRQ },
        { }
 };
 MODULE_DEVICE_TABLE(platform, s3cts_driver_ids);
 
 static struct platform_driver s3c_ts_driver = {
        .driver         = {
-               .name   = "s3c24xx-ts",
+               .name   = "samsung-ts",
                .owner  = THIS_MODULE,
 #ifdef CONFIG_PM
                .pm     = &s3c_ts_pmops,
index 5f3f03df92e3613a1bb4658e57d6cb3fa9b4f30b..302836a8069304424bda675515498b38f2b32f23 100644 (file)
@@ -534,21 +534,13 @@ config SERIAL_S3C24A0
          Serial port support for the Samsung S3C24A0 SoC
 
 config SERIAL_S3C6400
-       tristate "Samsung S3C6400/S3C6410/S5P6440 Seria port support"
-       depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440)
+       tristate "Samsung S3C6400/S3C6410/S5P6440/S5PC100 Serial port support"
+       depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5PC100)
        select SERIAL_SAMSUNG_UARTS_4
        default y
        help
-         Serial port support for the Samsung S3C6400, S3C6410 and S5P6440
-         SoCs
-
-config SERIAL_S5PC100
-       tristate "Samsung S5PC100 Serial port support"
-       depends on SERIAL_SAMSUNG && CPU_S5PC100
-       select SERIAL_SAMSUNG_UARTS_4
-       default y
-       help
-         Serial port support for the Samsung S5PC100 SoCs
+         Serial port support for the Samsung S3C6400, S3C6410, S5P6440
+         and S5PC100 SoCs
 
 config SERIAL_S5PV210
        tristate "Samsung S5PV210 Serial port support"
index 6aa4723b74eecd58743e06e996fce958f551741d..328f107346c4f6c19254f855c7515a409ce7a091 100644 (file)
@@ -44,7 +44,6 @@ obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o
 obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o
 obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o
 obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o
-obj-$(CONFIG_SERIAL_S5PC100) += s3c6400.o
 obj-$(CONFIG_SERIAL_S5PV210) += s5pv210.o
 obj-$(CONFIG_SERIAL_MAX3100) += max3100.o
 obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o