aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig7
-rw-r--r--arch/arm/Makefile4
-rw-r--r--arch/arm/mach-s3c2410/Kconfig9
-rw-r--r--arch/arm/mach-s3c2410/Makefile.boot10
-rw-r--r--arch/arm/mach-s3c2410/h1940-bluetooth.c32
-rw-r--r--arch/arm/mach-s3c2410/include/mach/dma.h2
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio-fns.h47
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio-nrs.h37
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio-track.h4
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio.h8
-rw-r--r--arch/arm/mach-s3c2410/include/mach/irqs.h28
-rw-r--r--arch/arm/mach-s3c2410/include/mach/map.h8
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-clock.h2
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-dsc.h36
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-gpio.h67
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-gpioj.h36
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-irq.h10
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h30
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h24
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h3
-rw-r--r--arch/arm/mach-s3c2410/include/mach/uncompress.h4
-rw-r--r--arch/arm/mach-s3c2410/mach-amlm5900.c5
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c11
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c29
-rw-r--r--arch/arm/mach-s3c2410/mach-n30.c83
-rw-r--r--arch/arm/mach-s3c2410/mach-qt2410.c10
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c5
-rw-r--r--arch/arm/mach-s3c2410/pm.c15
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c8
-rw-r--r--arch/arm/mach-s3c2412/Kconfig3
-rw-r--r--arch/arm/mach-s3c2412/gpio.c20
-rw-r--r--arch/arm/mach-s3c2412/mach-jive.c28
-rw-r--r--arch/arm/mach-s3c2412/mach-smdk2413.c14
-rw-r--r--arch/arm/mach-s3c2416/Kconfig39
-rw-r--r--arch/arm/mach-s3c2416/Makefile19
-rw-r--r--arch/arm/mach-s3c2416/clock.c135
-rw-r--r--arch/arm/mach-s3c2416/irq.c254
-rw-r--r--arch/arm/mach-s3c2416/mach-smdk2416.c206
-rw-r--r--arch/arm/mach-s3c2416/s3c2416.c130
-rw-r--r--arch/arm/mach-s3c2440/Kconfig14
-rw-r--r--arch/arm/mach-s3c2440/Makefile1
-rw-r--r--arch/arm/mach-s3c2440/mach-mini2440.c23
-rw-r--r--arch/arm/mach-s3c2440/mach-nexcoder.c9
-rw-r--r--arch/arm/mach-s3c2440/mach-osiris.c5
-rw-r--r--arch/arm/mach-s3c2440/mach-rx1950.c582
-rw-r--r--arch/arm/mach-s3c2440/mach-rx3715.c2
-rw-r--r--arch/arm/mach-s3c2440/mach-smdk2440.c2
-rw-r--r--arch/arm/mach-s3c2440/s3c2440.c8
-rw-r--r--arch/arm/mach-s3c2443/Kconfig1
-rw-r--r--arch/arm/mach-s3c2443/clock.c479
-rw-r--r--arch/arm/mach-s3c2443/mach-smdk2443.c2
-rw-r--r--arch/arm/mach-s3c64xx/clock.c36
-rw-r--r--arch/arm/mach-s3c64xx/dma.c2
-rw-r--r--arch/arm/mach-s3c64xx/gpiolib.c6
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/pll.h35
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-clock.h1
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6400.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6410.c2
-rw-r--r--arch/arm/mach-s5p6440/Kconfig1
-rw-r--r--arch/arm/mach-s5p6440/Makefile2
-rw-r--r--arch/arm/mach-s5p6440/clock.c350
-rw-r--r--arch/arm/mach-s5p6440/cpu.c2
-rw-r--r--arch/arm/mach-s5p6440/dma.c105
-rw-r--r--arch/arm/mach-s5p6440/gpio.c5
-rw-r--r--arch/arm/mach-s5p6440/include/mach/dma.h26
-rw-r--r--arch/arm/mach-s5p6440/include/mach/map.h2
-rw-r--r--arch/arm/mach-s5p6440/include/mach/pwm-clock.h24
-rw-r--r--arch/arm/mach-s5p6442/Kconfig1
-rw-r--r--arch/arm/mach-s5p6442/Makefile2
-rw-r--r--arch/arm/mach-s5p6442/cpu.c2
-rw-r--r--arch/arm/mach-s5p6442/dma.c105
-rw-r--r--arch/arm/mach-s5p6442/include/mach/dma.h26
-rw-r--r--arch/arm/mach-s5p6442/include/mach/map.h3
-rw-r--r--arch/arm/mach-s5p6442/include/mach/pwm-clock.h21
-rw-r--r--arch/arm/mach-s5pv210/Kconfig1
-rw-r--r--arch/arm/mach-s5pv210/Makefile2
-rw-r--r--arch/arm/mach-s5pv210/clock.c833
-rw-r--r--arch/arm/mach-s5pv210/cpu.c2
-rw-r--r--arch/arm/mach-s5pv210/dma.c168
-rw-r--r--arch/arm/mach-s5pv210/gpiolib.c261
-rw-r--r--arch/arm/mach-s5pv210/include/mach/dma.h26
-rw-r--r--arch/arm/mach-s5pv210/include/mach/gpio.h18
-rw-r--r--arch/arm/mach-s5pv210/include/mach/map.h4
-rw-r--r--arch/arm/mach-s5pv210/include/mach/pwm-clock.h21
-rw-r--r--arch/arm/mm/mmu.c5
-rw-r--r--arch/arm/plat-s3c24xx/Kconfig7
-rw-r--r--arch/arm/plat-s3c24xx/Makefile1
-rw-r--r--arch/arm/plat-s3c24xx/common-smdk.c9
-rw-r--r--arch/arm/plat-s3c24xx/cpu.c21
-rw-r--r--arch/arm/plat-s3c24xx/devs.c19
-rw-r--r--arch/arm/plat-s3c24xx/dma.c2
-rw-r--r--arch/arm/plat-s3c24xx/gpio.c150
-rw-r--r--arch/arm/plat-s3c24xx/gpiolib.c60
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/pll.h25
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2416.h31
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2443.h19
-rw-r--r--arch/arm/plat-s3c24xx/pm.c9
-rw-r--r--arch/arm/plat-s3c24xx/s3c2410-clock.c15
-rw-r--r--arch/arm/plat-s3c24xx/s3c2443-clock.c472
-rw-r--r--arch/arm/plat-s3c24xx/setup-i2c.c5
-rw-r--r--arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c16
-rw-r--r--arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c16
-rw-r--r--arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c16
-rw-r--r--arch/arm/plat-s5p/clock.c13
-rw-r--r--arch/arm/plat-s5p/include/plat/irqs.h2
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p-clock.h2
-rw-r--r--arch/arm/plat-samsung/Kconfig11
-rw-r--r--arch/arm/plat-samsung/Makefile3
-rw-r--r--arch/arm/plat-samsung/clock.c15
-rw-r--r--arch/arm/plat-samsung/dev-fb.c1
-rw-r--r--arch/arm/plat-samsung/dev-hwmon.c42
-rw-r--r--arch/arm/plat-samsung/gpio-config.c111
-rw-r--r--arch/arm/plat-samsung/gpio.c15
-rw-r--r--arch/arm/plat-samsung/include/plat/clock.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu.h4
-rw-r--r--arch/arm/plat-samsung/include/plat/dma.h4
-rw-r--r--arch/arm/plat-samsung/include/plat/fb.h7
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h58
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg.h11
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-core.h17
-rw-r--r--arch/arm/plat-samsung/include/plat/hwmon.h10
-rw-r--r--arch/arm/plat-samsung/include/plat/pll6553x.h51
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h78
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h32
-rw-r--r--arch/arm/plat-samsung/pm-gpio.c4
-rw-r--r--arch/arm/plat-samsung/s3c-pl330.c1224
-rw-r--r--drivers/serial/Kconfig7
127 files changed, 6093 insertions, 1176 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 92622eb5cc0d..3f8718fc4050 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -647,7 +647,7 @@ config ARCH_SA1100
647 Support for StrongARM 11x0 based boards. 647 Support for StrongARM 11x0 based boards.
648 648
649config ARCH_S3C2410 649config ARCH_S3C2410
650 bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443" 650 bool "Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443, S3C2450"
651 select GENERIC_GPIO 651 select GENERIC_GPIO
652 select ARCH_HAS_CPUFREQ 652 select ARCH_HAS_CPUFREQ
653 select HAVE_CLK 653 select HAVE_CLK
@@ -656,6 +656,10 @@ config ARCH_S3C2410
656 BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or 656 BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
657 the Samsung SMDK2410 development board (and derivatives). 657 the Samsung SMDK2410 development board (and derivatives).
658 658
659 Note, the S3C2416 and the S3C2450 are so close that they even share
660 the same SoC ID code. This means that there is no seperate machine
661 directory (no arch/arm/mach-s3c2450) as the S3C2416 was first.
662
659config ARCH_S3C64XX 663config ARCH_S3C64XX
660 bool "Samsung S3C64XX" 664 bool "Samsung S3C64XX"
661 select PLAT_SAMSUNG 665 select PLAT_SAMSUNG
@@ -892,6 +896,7 @@ if ARCH_S3C2410
892source "arch/arm/mach-s3c2400/Kconfig" 896source "arch/arm/mach-s3c2400/Kconfig"
893source "arch/arm/mach-s3c2410/Kconfig" 897source "arch/arm/mach-s3c2410/Kconfig"
894source "arch/arm/mach-s3c2412/Kconfig" 898source "arch/arm/mach-s3c2412/Kconfig"
899source "arch/arm/mach-s3c2416/Kconfig"
895source "arch/arm/mach-s3c2440/Kconfig" 900source "arch/arm/mach-s3c2440/Kconfig"
896source "arch/arm/mach-s3c2443/Kconfig" 901source "arch/arm/mach-s3c2443/Kconfig"
897endif 902endif
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index ed820e737a8a..9505a70bfc0a 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -110,6 +110,8 @@ CHECKFLAGS += -D__arm__
110head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o 110head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
111textofs-y := 0x00008000 111textofs-y := 0x00008000
112textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000 112textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000
113# We don't want the htc bootloader to corrupt kernel during resume
114textofs-$(CONFIG_PM_H1940) := 0x00108000
113# SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory 115# SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory
114ifeq ($(CONFIG_ARCH_SA1100),y) 116ifeq ($(CONFIG_ARCH_SA1100),y)
115textofs-$(CONFIG_SA1111) := 0x00208000 117textofs-$(CONFIG_SA1111) := 0x00208000
@@ -160,7 +162,7 @@ machine-$(CONFIG_ARCH_PNX4008) := pnx4008
160machine-$(CONFIG_ARCH_PXA) := pxa 162machine-$(CONFIG_ARCH_PXA) := pxa
161machine-$(CONFIG_ARCH_REALVIEW) := realview 163machine-$(CONFIG_ARCH_REALVIEW) := realview
162machine-$(CONFIG_ARCH_RPC) := rpc 164machine-$(CONFIG_ARCH_RPC) := rpc
163machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2443 165machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2416 s3c2440 s3c2443
164machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0 166machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0
165machine-$(CONFIG_ARCH_S3C64XX) := s3c64xx 167machine-$(CONFIG_ARCH_S3C64XX) := s3c64xx
166machine-$(CONFIG_ARCH_S5P6440) := s5p6440 168machine-$(CONFIG_ARCH_S5P6440) := s5p6440
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index 554731868b07..a4c0b3fcdbba 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -6,6 +6,7 @@ config CPU_S3C2410
6 bool 6 bool
7 depends on ARCH_S3C2410 7 depends on ARCH_S3C2410
8 select CPU_ARM920T 8 select CPU_ARM920T
9 select S3C_GPIO_PULL_UP
9 select S3C2410_CLOCK 10 select S3C2410_CLOCK
10 select S3C2410_GPIO 11 select S3C2410_GPIO
11 select CPU_LLSERIAL_S3C2410 12 select CPU_LLSERIAL_S3C2410
@@ -95,12 +96,19 @@ config PM_H1940
95config MACH_N30 96config MACH_N30
96 bool "Acer N30 family" 97 bool "Acer N30 family"
97 select CPU_S3C2410 98 select CPU_S3C2410
99 select MACH_N35
98 select S3C_DEV_USB_HOST 100 select S3C_DEV_USB_HOST
99 select S3C_DEV_NAND 101 select S3C_DEV_NAND
100 help 102 help
101 Say Y here if you want suppt for the Acer N30, Acer N35, 103 Say Y here if you want suppt for the Acer N30, Acer N35,
102 Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs. 104 Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs.
103 105
106config MACH_N35
107 bool
108 help
109 Internal node in order to enable support for Acer N35 if Acer N30 is
110 selected.
111
104config ARCH_BAST 112config ARCH_BAST
105 bool "Simtec Electronics BAST (EB2410ITX)" 113 bool "Simtec Electronics BAST (EB2410ITX)"
106 select CPU_S3C2410 114 select CPU_S3C2410
@@ -110,6 +118,7 @@ config ARCH_BAST
110 select MACH_BAST_IDE 118 select MACH_BAST_IDE
111 select S3C24XX_DCLK 119 select S3C24XX_DCLK
112 select ISA 120 select ISA
121 select S3C_DEV_HWMON
113 select S3C_DEV_USB_HOST 122 select S3C_DEV_USB_HOST
114 select S3C_DEV_NAND 123 select S3C_DEV_NAND
115 help 124 help
diff --git a/arch/arm/mach-s3c2410/Makefile.boot b/arch/arm/mach-s3c2410/Makefile.boot
index 7dab2a0325b5..58c1dd7f8e1d 100644
--- a/arch/arm/mach-s3c2410/Makefile.boot
+++ b/arch/arm/mach-s3c2410/Makefile.boot
@@ -1,3 +1,7 @@
1 zreladdr-y := 0x30008000 1ifeq ($(CONFIG_PM_H1940),y)
2params_phys-y := 0x30000100 2 zreladdr-y := 0x30108000
3 3 params_phys-y := 0x30100100
4else
5 zreladdr-y := 0x30008000
6 params_phys-y := 0x30000100
7endif
diff --git a/arch/arm/mach-s3c2410/h1940-bluetooth.c b/arch/arm/mach-s3c2410/h1940-bluetooth.c
index a3f3c7b1ca38..8cdeb14af592 100644
--- a/arch/arm/mach-s3c2410/h1940-bluetooth.c
+++ b/arch/arm/mach-s3c2410/h1940-bluetooth.c
@@ -33,14 +33,15 @@ static void h1940bt_enable(int on)
33 h1940_latch_control(0, H1940_LATCH_BLUETOOTH_POWER); 33 h1940_latch_control(0, H1940_LATCH_BLUETOOTH_POWER);
34 /* Reset the chip */ 34 /* Reset the chip */
35 mdelay(10); 35 mdelay(10);
36 s3c2410_gpio_setpin(S3C2410_GPH(1), 1); 36
37 gpio_set_value(S3C2410_GPH(1), 1);
37 mdelay(10); 38 mdelay(10);
38 s3c2410_gpio_setpin(S3C2410_GPH(1), 0); 39 gpio_set_value(S3C2410_GPH(1), 0);
39 } 40 }
40 else { 41 else {
41 s3c2410_gpio_setpin(S3C2410_GPH(1), 1); 42 gpio_set_value(S3C2410_GPH(1), 1);
42 mdelay(10); 43 mdelay(10);
43 s3c2410_gpio_setpin(S3C2410_GPH(1), 0); 44 gpio_set_value(S3C2410_GPH(1), 0);
44 mdelay(10); 45 mdelay(10);
45 h1940_latch_control(H1940_LATCH_BLUETOOTH_POWER, 0); 46 h1940_latch_control(H1940_LATCH_BLUETOOTH_POWER, 0);
46 } 47 }
@@ -61,15 +62,21 @@ static int __devinit h1940bt_probe(struct platform_device *pdev)
61 struct rfkill *rfk; 62 struct rfkill *rfk;
62 int ret = 0; 63 int ret = 0;
63 64
65 ret = gpio_request(S3C2410_GPH(1), dev_name(&pdev->dev));
66 if (ret) {
67 dev_err(&pdev->dev, "could not get GPH1\n");\
68 return ret;
69 }
70
64 /* Configures BT serial port GPIOs */ 71 /* Configures BT serial port GPIOs */
65 s3c2410_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0); 72 s3c_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0);
66 s3c2410_gpio_pullup(S3C2410_GPH(0), 1); 73 s3c_gpio_cfgpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE);
67 s3c2410_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT); 74 s3c_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT);
68 s3c2410_gpio_pullup(S3C2410_GPH(1), 1); 75 s3c_gpio_cfgpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE);
69 s3c2410_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0); 76 s3c_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0);
70 s3c2410_gpio_pullup(S3C2410_GPH(2), 1); 77 s3c_gpio_cfgpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE);
71 s3c2410_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0); 78 s3c_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0);
72 s3c2410_gpio_pullup(S3C2410_GPH(3), 1); 79 s3c_gpio_cfgpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE);
73 80
74 81
75 rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH, 82 rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH,
@@ -100,6 +107,7 @@ static int h1940bt_remove(struct platform_device *pdev)
100 struct rfkill *rfk = platform_get_drvdata(pdev); 107 struct rfkill *rfk = platform_get_drvdata(pdev);
101 108
102 platform_set_drvdata(pdev, NULL); 109 platform_set_drvdata(pdev, NULL);
110 gpio_free(S3C2410_GPH(1));
103 111
104 if (rfk) { 112 if (rfk) {
105 rfkill_unregister(rfk); 113 rfkill_unregister(rfk);
diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h
index 08ac5f96c012..cf68136cc668 100644
--- a/arch/arm/mach-s3c2410/include/mach/dma.h
+++ b/arch/arm/mach-s3c2410/include/mach/dma.h
@@ -54,7 +54,7 @@ enum dma_ch {
54#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */ 54#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
55 55
56/* we have 4 dma channels */ 56/* we have 4 dma channels */
57#ifndef CONFIG_CPU_S3C2443 57#if !defined(CONFIG_CPU_S3C2443) && !defined(CONFIG_CPU_S3C2416)
58#define S3C_DMA_CHANNELS (4) 58#define S3C_DMA_CHANNELS (4)
59#else 59#else
60#define S3C_DMA_CHANNELS (6) 60#define S3C_DMA_CHANNELS (6)
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-fns.h b/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
index 035a493952db..f453c4f2cb8e 100644
--- a/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
+++ b/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
@@ -10,14 +10,28 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11*/ 11*/
12 12
13#ifndef __MACH_GPIO_FNS_H
14#define __MACH_GPIO_FNS_H __FILE__
15
13/* These functions are in the to-be-removed category and it is strongly 16/* These functions are in the to-be-removed category and it is strongly
14 * encouraged not to use these in new code. They will be marked deprecated 17 * encouraged not to use these in new code. They will be marked deprecated
15 * very soon. 18 * very soon.
16 * 19 *
17 * Most of the functionality can be either replaced by the gpiocfg calls 20 * Most of the functionality can be either replaced by the gpiocfg calls
18 * for the s3c platform or by the generic GPIOlib API. 21 * for the s3c platform or by the generic GPIOlib API.
22 *
23 * As of 2.6.35-rc, these will be removed, with the few drivers using them
24 * either replaced or given a wrapper until the calls can be removed.
19*/ 25*/
20 26
27#include <plat/gpio-cfg.h>
28
29static inline void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int cfg)
30{
31 /* 1:1 mapping between cfgpin and setcfg calls at the moment */
32 s3c_gpio_cfgpin(pin, cfg);
33}
34
21/* external functions for GPIO support 35/* external functions for GPIO support
22 * 36 *
23 * These allow various different clients to access the same GPIO 37 * These allow various different clients to access the same GPIO
@@ -25,17 +39,6 @@
25 * GPIO register, then it is safe to ioremap/__raw_{read|write} to it. 39 * GPIO register, then it is safe to ioremap/__raw_{read|write} to it.
26*/ 40*/
27 41
28/* s3c2410_gpio_cfgpin
29 *
30 * set the configuration of the given pin to the value passed.
31 *
32 * eg:
33 * s3c2410_gpio_cfgpin(S3C2410_GPA(0), S3C2410_GPA0_ADDR0);
34 * s3c2410_gpio_cfgpin(S3C2410_GPE(8), S3C2410_GPE8_SDDAT1);
35*/
36
37extern void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function);
38
39extern unsigned int s3c2410_gpio_getcfg(unsigned int pin); 42extern unsigned int s3c2410_gpio_getcfg(unsigned int pin);
40 43
41/* s3c2410_gpio_getirq 44/* s3c2410_gpio_getirq
@@ -73,6 +76,14 @@ extern int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
73 76
74/* s3c2410_gpio_pullup 77/* s3c2410_gpio_pullup
75 * 78 *
79 * This call should be replaced with s3c_gpio_setpull().
80 *
81 * As a note, there is currently no distinction between pull-up and pull-down
82 * in the s3c24xx series devices with only an on/off configuration.
83 */
84
85/* s3c2410_gpio_pullup
86 *
76 * configure the pull-up control on the given pin 87 * configure the pull-up control on the given pin
77 * 88 *
78 * to = 1 => disable the pull-up 89 * to = 1 => disable the pull-up
@@ -86,18 +97,8 @@ extern int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
86 97
87extern void s3c2410_gpio_pullup(unsigned int pin, unsigned int to); 98extern void s3c2410_gpio_pullup(unsigned int pin, unsigned int to);
88 99
89/* s3c2410_gpio_getpull
90 *
91 * Read the state of the pull-up on a given pin
92 *
93 * return:
94 * < 0 => error code
95 * 0 => enabled
96 * 1 => disabled
97*/
98
99extern int s3c2410_gpio_getpull(unsigned int pin);
100
101extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to); 100extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to);
102 101
103extern unsigned int s3c2410_gpio_getpin(unsigned int pin); 102extern unsigned int s3c2410_gpio_getpin(unsigned int pin);
103
104#endif /* __MACH_GPIO_FNS_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
index 2edbb9c88ab3..4f7bf3272e87 100644
--- a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
+++ b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
@@ -16,15 +16,28 @@
16 16
17#define S3C2410_GPIONO(bank,offset) ((bank) + (offset)) 17#define S3C2410_GPIONO(bank,offset) ((bank) + (offset))
18 18
19#define S3C2410_GPIO_BANKA (32*0)
20#define S3C2410_GPIO_BANKB (32*1)
21#define S3C2410_GPIO_BANKC (32*2)
22#define S3C2410_GPIO_BANKD (32*3)
23#define S3C2410_GPIO_BANKE (32*4)
24#define S3C2410_GPIO_BANKF (32*5)
25#define S3C2410_GPIO_BANKG (32*6) 19#define S3C2410_GPIO_BANKG (32*6)
26#define S3C2410_GPIO_BANKH (32*7) 20#define S3C2410_GPIO_BANKH (32*7)
27 21
22/* GPIO sizes for various SoCs:
23 *
24 * 2442
25 * 2410 2412 2440 2443 2416
26 * ---- ---- ---- ---- ----
27 * A 23 22 25 16 25
28 * B 11 11 11 11 9
29 * C 16 15 16 16 16
30 * D 16 16 16 16 16
31 * E 16 16 16 16 16
32 * F 8 8 8 8 8
33 * G 16 16 16 16 8
34 * H 11 11 9 15 15
35 * J -- -- 13 16 --
36 * K -- -- -- -- 16
37 * L -- -- -- 15 7
38 * M -- -- -- 2 2
39 */
40
28/* GPIO bank sizes */ 41/* GPIO bank sizes */
29#define S3C2410_GPIO_A_NR (32) 42#define S3C2410_GPIO_A_NR (32)
30#define S3C2410_GPIO_B_NR (32) 43#define S3C2410_GPIO_B_NR (32)
@@ -34,6 +47,10 @@
34#define S3C2410_GPIO_F_NR (32) 47#define S3C2410_GPIO_F_NR (32)
35#define S3C2410_GPIO_G_NR (32) 48#define S3C2410_GPIO_G_NR (32)
36#define S3C2410_GPIO_H_NR (32) 49#define S3C2410_GPIO_H_NR (32)
50#define S3C2410_GPIO_J_NR (32) /* technically 16. */
51#define S3C2410_GPIO_K_NR (32) /* technically 16. */
52#define S3C2410_GPIO_L_NR (32) /* technically 15. */
53#define S3C2410_GPIO_M_NR (32) /* technically 2. */
37 54
38#if CONFIG_S3C_GPIO_SPACE != 0 55#if CONFIG_S3C_GPIO_SPACE != 0
39#error CONFIG_S3C_GPIO_SPACE cannot be zero at the moment 56#error CONFIG_S3C_GPIO_SPACE cannot be zero at the moment
@@ -53,6 +70,10 @@ enum s3c_gpio_number {
53 S3C2410_GPIO_F_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_E), 70 S3C2410_GPIO_F_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_E),
54 S3C2410_GPIO_G_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_F), 71 S3C2410_GPIO_G_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_F),
55 S3C2410_GPIO_H_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_G), 72 S3C2410_GPIO_H_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_G),
73 S3C2410_GPIO_J_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_H),
74 S3C2410_GPIO_K_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_J),
75 S3C2410_GPIO_L_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_K),
76 S3C2410_GPIO_M_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_L),
56}; 77};
57 78
58#endif /* __ASSEMBLY__ */ 79#endif /* __ASSEMBLY__ */
@@ -67,6 +88,10 @@ enum s3c_gpio_number {
67#define S3C2410_GPF(_nr) (S3C2410_GPIO_F_START + (_nr)) 88#define S3C2410_GPF(_nr) (S3C2410_GPIO_F_START + (_nr))
68#define S3C2410_GPG(_nr) (S3C2410_GPIO_G_START + (_nr)) 89#define S3C2410_GPG(_nr) (S3C2410_GPIO_G_START + (_nr))
69#define S3C2410_GPH(_nr) (S3C2410_GPIO_H_START + (_nr)) 90#define S3C2410_GPH(_nr) (S3C2410_GPIO_H_START + (_nr))
91#define S3C2410_GPJ(_nr) (S3C2410_GPIO_J_START + (_nr))
92#define S3C2410_GPK(_nr) (S3C2410_GPIO_K_START + (_nr))
93#define S3C2410_GPL(_nr) (S3C2410_GPIO_L_START + (_nr))
94#define S3C2410_GPM(_nr) (S3C2410_GPIO_M_START + (_nr))
70 95
71/* compatibility until drivers can be modified */ 96/* compatibility until drivers can be modified */
72 97
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-track.h b/arch/arm/mach-s3c2410/include/mach/gpio-track.h
index acb259103808..d67819dde42a 100644
--- a/arch/arm/mach-s3c2410/include/mach/gpio-track.h
+++ b/arch/arm/mach-s3c2410/include/mach/gpio-track.h
@@ -23,11 +23,11 @@ static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin)
23{ 23{
24 struct s3c_gpio_chip *chip; 24 struct s3c_gpio_chip *chip;
25 25
26 if (pin > S3C2410_GPG(10)) 26 if (pin > S3C_GPIO_END)
27 return NULL; 27 return NULL;
28 28
29 chip = &s3c24xx_gpios[pin/32]; 29 chip = &s3c24xx_gpios[pin/32];
30 return (S3C2410_GPIO_OFFSET(pin) < chip->chip.ngpio) ? chip : NULL; 30 return ((pin - chip->chip.base) < chip->chip.ngpio) ? chip : NULL;
31} 31}
32 32
33#endif /* __ASM_ARCH_GPIO_CORE_H */ 33#endif /* __ASM_ARCH_GPIO_CORE_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio.h b/arch/arm/mach-s3c2410/include/mach/gpio.h
index 15f0b3e7ce69..b649bf2ccd5c 100644
--- a/arch/arm/mach-s3c2410/include/mach/gpio.h
+++ b/arch/arm/mach-s3c2410/include/mach/gpio.h
@@ -20,10 +20,18 @@
20 * devices that need GPIO. 20 * devices that need GPIO.
21 */ 21 */
22 22
23#ifdef CONFIG_CPU_S3C244X
24#define ARCH_NR_GPIOS (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA)
25#else
23#define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA) 26#define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA)
27#endif
24 28
25#include <asm-generic/gpio.h> 29#include <asm-generic/gpio.h>
26#include <mach/gpio-nrs.h> 30#include <mach/gpio-nrs.h>
27#include <mach/gpio-fns.h> 31#include <mach/gpio-fns.h>
28 32
33#ifdef CONFIG_CPU_S3C24XX
34#define S3C_GPIO_END (S3C2410_GPIO_BANKJ + 32)
35#else
29#define S3C_GPIO_END (S3C2410_GPIO_BANKH + 32) 36#define S3C_GPIO_END (S3C2410_GPIO_BANKH + 32)
37#endif
diff --git a/arch/arm/mach-s3c2410/include/mach/irqs.h b/arch/arm/mach-s3c2410/include/mach/irqs.h
index 6c12c6312ad8..11bb0f08fe6a 100644
--- a/arch/arm/mach-s3c2410/include/mach/irqs.h
+++ b/arch/arm/mach-s3c2410/include/mach/irqs.h
@@ -115,6 +115,26 @@
115#define IRQ_S3C2412_SDI S3C2410_IRQSUB(13) 115#define IRQ_S3C2412_SDI S3C2410_IRQSUB(13)
116#define IRQ_S3C2412_CF S3C2410_IRQSUB(14) 116#define IRQ_S3C2412_CF S3C2410_IRQSUB(14)
117 117
118
119#define IRQ_S3C2416_EINT8t15 S3C2410_IRQ(5)
120#define IRQ_S3C2416_DMA S3C2410_IRQ(17)
121#define IRQ_S3C2416_UART3 S3C2410_IRQ(18)
122#define IRQ_S3C2416_SDI1 S3C2410_IRQ(20)
123#define IRQ_S3C2416_SDI0 S3C2410_IRQ(21)
124
125#define IRQ_S3C2416_LCD2 S3C2410_IRQSUB(15)
126#define IRQ_S3C2416_LCD3 S3C2410_IRQSUB(16)
127#define IRQ_S3C2416_LCD4 S3C2410_IRQSUB(17)
128#define IRQ_S3C2416_DMA0 S3C2410_IRQSUB(18)
129#define IRQ_S3C2416_DMA1 S3C2410_IRQSUB(19)
130#define IRQ_S3C2416_DMA2 S3C2410_IRQSUB(20)
131#define IRQ_S3C2416_DMA3 S3C2410_IRQSUB(21)
132#define IRQ_S3C2416_DMA4 S3C2410_IRQSUB(22)
133#define IRQ_S3C2416_DMA5 S3C2410_IRQSUB(23)
134#define IRQ_S32416_WDT S3C2410_IRQSUB(27)
135#define IRQ_S32416_AC97 S3C2410_IRQSUB(28)
136
137
118/* extra irqs for s3c2440 */ 138/* extra irqs for s3c2440 */
119 139
120#define IRQ_S3C2440_CAM_C S3C2410_IRQSUB(11) /* S3C2443 too */ 140#define IRQ_S3C2440_CAM_C S3C2410_IRQSUB(11) /* S3C2443 too */
@@ -130,7 +150,10 @@
130#define IRQ_S3C2443_HSMMC S3C2410_IRQ(20) /* IRQ_SDI */ 150#define IRQ_S3C2443_HSMMC S3C2410_IRQ(20) /* IRQ_SDI */
131#define IRQ_S3C2443_NAND S3C2410_IRQ(24) /* reserved */ 151#define IRQ_S3C2443_NAND S3C2410_IRQ(24) /* reserved */
132 152
153#define IRQ_S3C2416_HSMMC0 S3C2410_IRQ(21) /* S3C2416/S3C2450 */
154
133#define IRQ_HSMMC0 IRQ_S3C2443_HSMMC 155#define IRQ_HSMMC0 IRQ_S3C2443_HSMMC
156#define IRQ_HSMMC1 IRQ_S3C2416_HSMMC0
134 157
135#define IRQ_S3C2443_LCD1 S3C2410_IRQSUB(14) 158#define IRQ_S3C2443_LCD1 S3C2410_IRQSUB(14)
136#define IRQ_S3C2443_LCD2 S3C2410_IRQSUB(15) 159#define IRQ_S3C2443_LCD2 S3C2410_IRQSUB(15)
@@ -152,7 +175,7 @@
152#define IRQ_S3C2443_WDT S3C2410_IRQSUB(27) 175#define IRQ_S3C2443_WDT S3C2410_IRQSUB(27)
153#define IRQ_S3C2443_AC97 S3C2410_IRQSUB(28) 176#define IRQ_S3C2443_AC97 S3C2410_IRQSUB(28)
154 177
155#ifdef CONFIG_CPU_S3C2443 178#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
156#define NR_IRQS (IRQ_S3C2443_AC97+1) 179#define NR_IRQS (IRQ_S3C2443_AC97+1)
157#else 180#else
158#define NR_IRQS (IRQ_S3C2440_AC97+1) 181#define NR_IRQS (IRQ_S3C2440_AC97+1)
@@ -164,6 +187,9 @@
164#define IRQ_S3CUART_TX3 IRQ_S3C2443_TX3 187#define IRQ_S3CUART_TX3 IRQ_S3C2443_TX3
165#define IRQ_S3CUART_ERR3 IRQ_S3C2443_ERR3 188#define IRQ_S3CUART_ERR3 IRQ_S3C2443_ERR3
166 189
190#define IRQ_LCD_VSYNC IRQ_S3C2443_LCD3
191#define IRQ_LCD_SYSTEM IRQ_S3C2443_LCD2
192
167#ifdef CONFIG_CPU_S3C2440 193#ifdef CONFIG_CPU_S3C2440
168#define IRQ_S3C244x_AC97 IRQ_S3C2440_AC97 194#define IRQ_S3C244x_AC97 IRQ_S3C2440_AC97
169#else 195#else
diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h
index b049e61460b6..091c98a639d9 100644
--- a/arch/arm/mach-s3c2410/include/mach/map.h
+++ b/arch/arm/mach-s3c2410/include/mach/map.h
@@ -63,9 +63,11 @@
63#define S3C2440_PA_AC97 (0x5B000000) 63#define S3C2440_PA_AC97 (0x5B000000)
64#define S3C2440_SZ_AC97 SZ_1M 64#define S3C2440_SZ_AC97 SZ_1M
65 65
66/* S3C2443 High-speed SD/MMC */ 66/* S3C2443/S3C2416 High-speed SD/MMC */
67#define S3C2443_PA_HSMMC (0x4A800000) 67#define S3C2443_PA_HSMMC (0x4A800000)
68#define S3C2443_SZ_HSMMC (256) 68#define S3C2416_PA_HSMMC0 (0x4AC00000)
69
70#define S3C2443_PA_FB (0x4C800000)
69 71
70/* S3C2412 memory and IO controls */ 72/* S3C2412 memory and IO controls */
71#define S3C2412_PA_SSMC (0x4F000000) 73#define S3C2412_PA_SSMC (0x4F000000)
@@ -106,10 +108,12 @@
106#define S3C24XX_PA_SDI S3C2410_PA_SDI 108#define S3C24XX_PA_SDI S3C2410_PA_SDI
107#define S3C24XX_PA_NAND S3C2410_PA_NAND 109#define S3C24XX_PA_NAND S3C2410_PA_NAND
108 110
111#define S3C_PA_FB S3C2443_PA_FB
109#define S3C_PA_IIC S3C2410_PA_IIC 112#define S3C_PA_IIC S3C2410_PA_IIC
110#define S3C_PA_UART S3C24XX_PA_UART 113#define S3C_PA_UART S3C24XX_PA_UART
111#define S3C_PA_USBHOST S3C2410_PA_USBHOST 114#define S3C_PA_USBHOST S3C2410_PA_USBHOST
112#define S3C_PA_HSMMC0 S3C2443_PA_HSMMC 115#define S3C_PA_HSMMC0 S3C2443_PA_HSMMC
116#define S3C_PA_HSMMC1 S3C2416_PA_HSMMC0
113#define S3C_PA_NAND S3C24XX_PA_NAND 117#define S3C_PA_NAND S3C24XX_PA_NAND
114 118
115#endif /* __ASM_ARCH_MAP_H */ 119#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-clock.h
index 9a0d169be137..3415b60082d7 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-clock.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-clock.h
@@ -161,4 +161,6 @@
161 161
162#endif /* CONFIG_CPU_S3C2412 | CONFIG_CPU_S3C2413 */ 162#endif /* CONFIG_CPU_S3C2412 | CONFIG_CPU_S3C2413 */
163 163
164#define S3C2416_CLKDIV2 S3C2410_CLKREG(0x28)
165
164#endif /* __ASM_ARM_REGS_CLOCK */ 166#endif /* __ASM_ARM_REGS_CLOCK */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-dsc.h b/arch/arm/mach-s3c2410/include/mach/regs-dsc.h
index 3c3853cd3cf7..98fd4a05587c 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-dsc.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-dsc.h
@@ -19,6 +19,42 @@
19#define S3C2412_DSC1 S3C2410_GPIOREG(0xe0) 19#define S3C2412_DSC1 S3C2410_GPIOREG(0xe0)
20#endif 20#endif
21 21
22#if defined(CONFIG_CPU_S3C2416)
23#define S3C2416_DSC0 S3C2410_GPIOREG(0xc0)
24#define S3C2416_DSC1 S3C2410_GPIOREG(0xc4)
25#define S3C2416_DSC2 S3C2410_GPIOREG(0xc8)
26#define S3C2416_DSC3 S3C2410_GPIOREG(0x110)
27
28#define S3C2416_SELECT_DSC0 (0 << 30)
29#define S3C2416_SELECT_DSC1 (1 << 30)
30#define S3C2416_SELECT_DSC2 (2 << 30)
31#define S3C2416_SELECT_DSC3 (3 << 30)
32
33#define S3C2416_DSC_GETSHIFT(x) (x & 30)
34
35#define S3C2416_DSC0_CF (S3C2416_SELECT_DSC0 | 28)
36#define S3C2416_DSC0_CF_5mA (0 << 28)
37#define S3C2416_DSC0_CF_10mA (1 << 28)
38#define S3C2416_DSC0_CF_15mA (2 << 28)
39#define S3C2416_DSC0_CF_21mA (3 << 28)
40#define S3C2416_DSC0_CF_MASK (3 << 28)
41
42#define S3C2416_DSC0_nRBE (S3C2416_SELECT_DSC0 | 26)
43#define S3C2416_DSC0_nRBE_5mA (0 << 26)
44#define S3C2416_DSC0_nRBE_10mA (1 << 26)
45#define S3C2416_DSC0_nRBE_15mA (2 << 26)
46#define S3C2416_DSC0_nRBE_21mA (3 << 26)
47#define S3C2416_DSC0_nRBE_MASK (3 << 26)
48
49#define S3C2416_DSC0_nROE (S3C2416_SELECT_DSC0 | 24)
50#define S3C2416_DSC0_nROE_5mA (0 << 24)
51#define S3C2416_DSC0_nROE_10mA (1 << 24)
52#define S3C2416_DSC0_nROE_15mA (2 << 24)
53#define S3C2416_DSC0_nROE_21mA (3 << 24)
54#define S3C2416_DSC0_nROE_MASK (3 << 24)
55
56#endif
57
22#if defined(CONFIG_CPU_S3C244X) 58#if defined(CONFIG_CPU_S3C244X)
23 59
24#define S3C2440_DSC0 S3C2410_GPIOREG(0xc4) 60#define S3C2440_DSC0 S3C2410_GPIOREG(0xc4)
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
index fd672f330bf2..a0a89d429296 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
@@ -17,29 +17,11 @@
17#include <mach/gpio-nrs.h> 17#include <mach/gpio-nrs.h>
18 18
19#ifdef CONFIG_CPU_S3C2400 19#ifdef CONFIG_CPU_S3C2400
20#define S3C24XX_GPIO_BASE(x) S3C2400_GPIO_BASE(x) 20#define S3C24XX_MISCCR S3C2400_MISCCR
21#define S3C24XX_MISCCR S3C2400_MISCCR
22#else 21#else
23#define S3C24XX_GPIO_BASE(x) S3C2410_GPIO_BASE(x) 22#define S3C24XX_MISCCR S3C24XX_GPIOREG2(0x80)
24#define S3C24XX_MISCCR S3C24XX_GPIOREG2(0x80)
25#endif /* CONFIG_CPU_S3C2400 */ 23#endif /* CONFIG_CPU_S3C2400 */
26 24
27
28/* S3C2400 doesn't have a 1:1 mapping to S3C2410 gpio base pins */
29
30#define S3C2400_BANKNUM(pin) (((pin) & ~31) / 32)
31#define S3C2400_BASEA2B(pin) ((((pin) & ~31) >> 2))
32#define S3C2400_BASEC2H(pin) ((S3C2400_BANKNUM(pin) * 10) + \
33 (2 * (S3C2400_BANKNUM(pin)-2)))
34
35#define S3C2400_GPIO_BASE(pin) (pin < S3C2410_GPIO_BANKC ? \
36 S3C2400_BASEA2B(pin)+S3C24XX_VA_GPIO : \
37 S3C2400_BASEC2H(pin)+S3C24XX_VA_GPIO)
38
39
40#define S3C2410_GPIO_BASE(pin) ((((pin) & ~31) >> 1) + S3C24XX_VA_GPIO)
41#define S3C2410_GPIO_OFFSET(pin) ((pin) & 31)
42
43/* general configuration options */ 25/* general configuration options */
44 26
45#define S3C2410_GPIO_LEAVE (0xFFFFFFFF) 27#define S3C2410_GPIO_LEAVE (0xFFFFFFFF)
@@ -610,35 +592,73 @@
610#define S3C2410_GPHUP S3C2410_GPIOREG(0x78) 592#define S3C2410_GPHUP S3C2410_GPIOREG(0x78)
611 593
612#define S3C2410_GPH0_nCTS0 (0x02 << 0) 594#define S3C2410_GPH0_nCTS0 (0x02 << 0)
595#define S3C2416_GPH0_TXD0 (0x02 << 0)
613 596
614#define S3C2410_GPH1_nRTS0 (0x02 << 2) 597#define S3C2410_GPH1_nRTS0 (0x02 << 2)
598#define S3C2416_GPH1_RXD0 (0x02 << 2)
615 599
616#define S3C2410_GPH2_TXD0 (0x02 << 4) 600#define S3C2410_GPH2_TXD0 (0x02 << 4)
601#define S3C2416_GPH2_TXD1 (0x02 << 4)
617 602
618#define S3C2410_GPH3_RXD0 (0x02 << 6) 603#define S3C2410_GPH3_RXD0 (0x02 << 6)
604#define S3C2416_GPH3_RXD1 (0x02 << 6)
619 605
620#define S3C2410_GPH4_TXD1 (0x02 << 8) 606#define S3C2410_GPH4_TXD1 (0x02 << 8)
607#define S3C2416_GPH4_TXD2 (0x02 << 8)
621 608
622#define S3C2410_GPH5_RXD1 (0x02 << 10) 609#define S3C2410_GPH5_RXD1 (0x02 << 10)
610#define S3C2416_GPH5_RXD2 (0x02 << 10)
623 611
624#define S3C2410_GPH6_TXD2 (0x02 << 12) 612#define S3C2410_GPH6_TXD2 (0x02 << 12)
613#define S3C2416_GPH6_TXD3 (0x02 << 12)
625#define S3C2410_GPH6_nRTS1 (0x03 << 12) 614#define S3C2410_GPH6_nRTS1 (0x03 << 12)
615#define S3C2416_GPH6_nRTS2 (0x03 << 12)
626 616
627#define S3C2410_GPH7_RXD2 (0x02 << 14) 617#define S3C2410_GPH7_RXD2 (0x02 << 14)
618#define S3C2416_GPH7_RXD3 (0x02 << 14)
628#define S3C2410_GPH7_nCTS1 (0x03 << 14) 619#define S3C2410_GPH7_nCTS1 (0x03 << 14)
620#define S3C2416_GPH7_nCTS2 (0x03 << 14)
629 621
630#define S3C2410_GPH8_UCLK (0x02 << 16) 622#define S3C2410_GPH8_UCLK (0x02 << 16)
623#define S3C2416_GPH8_nCTS0 (0x02 << 16)
631 624
632#define S3C2410_GPH9_CLKOUT0 (0x02 << 18) 625#define S3C2410_GPH9_CLKOUT0 (0x02 << 18)
633#define S3C2442_GPH9_nSPICS0 (0x03 << 18) 626#define S3C2442_GPH9_nSPICS0 (0x03 << 18)
627#define S3C2416_GPH9_nRTS0 (0x02 << 18)
634 628
635#define S3C2410_GPH10_CLKOUT1 (0x02 << 20) 629#define S3C2410_GPH10_CLKOUT1 (0x02 << 20)
630#define S3C2416_GPH10_nCTS1 (0x02 << 20)
631
632#define S3C2416_GPH11_nRTS1 (0x02 << 22)
633
634#define S3C2416_GPH12_EXTUARTCLK (0x02 << 24)
635
636#define S3C2416_GPH13_CLKOUT0 (0x02 << 26)
637
638#define S3C2416_GPH14_CLKOUT1 (0x02 << 28)
636 639
637/* The S3C2412 and S3C2413 move the GPJ register set to after 640/* The S3C2412 and S3C2413 move the GPJ register set to after
638 * GPH, which means all registers after 0x80 are now offset by 0x10 641 * GPH, which means all registers after 0x80 are now offset by 0x10
639 * for the 2412/2413 from the 2410/2440/2442 642 * for the 2412/2413 from the 2410/2440/2442
640*/ 643*/
641 644
645/* S3C2443 and above */
646#define S3C2440_GPJCON S3C2410_GPIOREG(0xD0)
647#define S3C2440_GPJDAT S3C2410_GPIOREG(0xD4)
648#define S3C2440_GPJUP S3C2410_GPIOREG(0xD8)
649
650#define S3C2443_GPKCON S3C2410_GPIOREG(0xE0)
651#define S3C2443_GPKDAT S3C2410_GPIOREG(0xE4)
652#define S3C2443_GPKUP S3C2410_GPIOREG(0xE8)
653
654#define S3C2443_GPLCON S3C2410_GPIOREG(0xF0)
655#define S3C2443_GPLDAT S3C2410_GPIOREG(0xF4)
656#define S3C2443_GPLUP S3C2410_GPIOREG(0xF8)
657
658#define S3C2443_GPMCON S3C2410_GPIOREG(0x100)
659#define S3C2443_GPMDAT S3C2410_GPIOREG(0x104)
660#define S3C2443_GPMUP S3C2410_GPIOREG(0x108)
661
642/* miscellaneous control */ 662/* miscellaneous control */
643#define S3C2400_MISCCR S3C2410_GPIOREG(0x54) 663#define S3C2400_MISCCR S3C2410_GPIOREG(0x54)
644#define S3C2410_MISCCR S3C2410_GPIOREG(0x80) 664#define S3C2410_MISCCR S3C2410_GPIOREG(0x80)
@@ -686,6 +706,7 @@
686#define S3C2412_MISCCR_CLK1_CLKsrc (0<<8) 706#define S3C2412_MISCCR_CLK1_CLKsrc (0<<8)
687 707
688#define S3C2410_MISCCR_USBSUSPND0 (1<<12) 708#define S3C2410_MISCCR_USBSUSPND0 (1<<12)
709#define S3C2416_MISCCR_SEL_SUSPND (1<<12)
689#define S3C2410_MISCCR_USBSUSPND1 (1<<13) 710#define S3C2410_MISCCR_USBSUSPND1 (1<<13)
690 711
691#define S3C2410_MISCCR_nRSTCON (1<<16) 712#define S3C2410_MISCCR_nRSTCON (1<<16)
@@ -695,6 +716,9 @@
695#define S3C2410_MISCCR_nEN_SCLKE (1<<19) /* not 2412 */ 716#define S3C2410_MISCCR_nEN_SCLKE (1<<19) /* not 2412 */
696#define S3C2410_MISCCR_SDSLEEP (7<<17) 717#define S3C2410_MISCCR_SDSLEEP (7<<17)
697 718
719#define S3C2416_MISCCR_FLT_I2C (1<<24)
720#define S3C2416_MISCCR_HSSPI_EN2 (1<<31)
721
698/* external interrupt control... */ 722/* external interrupt control... */
699/* S3C2410_EXTINT0 -> irq sense control for EINT0..EINT7 723/* S3C2410_EXTINT0 -> irq sense control for EINT0..EINT7
700 * S3C2410_EXTINT1 -> irq sense control for EINT8..EINT15 724 * S3C2410_EXTINT1 -> irq sense control for EINT8..EINT15
@@ -762,8 +786,11 @@
762#define S3C2410_GSTATUS1_IDMASK (0xffff0000) 786#define S3C2410_GSTATUS1_IDMASK (0xffff0000)
763#define S3C2410_GSTATUS1_2410 (0x32410000) 787#define S3C2410_GSTATUS1_2410 (0x32410000)
764#define S3C2410_GSTATUS1_2412 (0x32412001) 788#define S3C2410_GSTATUS1_2412 (0x32412001)
789#define S3C2410_GSTATUS1_2416 (0x32416003)
765#define S3C2410_GSTATUS1_2440 (0x32440000) 790#define S3C2410_GSTATUS1_2440 (0x32440000)
766#define S3C2410_GSTATUS1_2442 (0x32440aaa) 791#define S3C2410_GSTATUS1_2442 (0x32440aaa)
792/* some 2416 CPUs report this value also */
793#define S3C2410_GSTATUS1_2450 (0x32450003)
767 794
768#define S3C2410_GSTATUS2_WTRESET (1<<2) 795#define S3C2410_GSTATUS2_WTRESET (1<<2)
769#define S3C2410_GSTATUS2_OFFRESET (1<<1) 796#define S3C2410_GSTATUS2_OFFRESET (1<<1)
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h b/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
index 1202ca5e99f6..19575e061114 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
@@ -22,85 +22,49 @@
22 * pull up works like all other ports. 22 * pull up works like all other ports.
23*/ 23*/
24 24
25#define S3C2440_GPIO_BANKJ (416)
26
27#define S3C2440_GPJCON S3C2410_GPIOREG(0xd0)
28#define S3C2440_GPJDAT S3C2410_GPIOREG(0xd4)
29#define S3C2440_GPJUP S3C2410_GPIOREG(0xd8)
30
31#define S3C2413_GPJCON S3C2410_GPIOREG(0x80) 25#define S3C2413_GPJCON S3C2410_GPIOREG(0x80)
32#define S3C2413_GPJDAT S3C2410_GPIOREG(0x84) 26#define S3C2413_GPJDAT S3C2410_GPIOREG(0x84)
33#define S3C2413_GPJUP S3C2410_GPIOREG(0x88) 27#define S3C2413_GPJUP S3C2410_GPIOREG(0x88)
34#define S3C2413_GPJSLPCON S3C2410_GPIOREG(0x8C) 28#define S3C2413_GPJSLPCON S3C2410_GPIOREG(0x8C)
35 29
36#define S3C2440_GPJ0 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 0)
37#define S3C2440_GPJ0_INP (0x00 << 0)
38#define S3C2440_GPJ0_OUTP (0x01 << 0) 30#define S3C2440_GPJ0_OUTP (0x01 << 0)
39#define S3C2440_GPJ0_CAMDATA0 (0x02 << 0) 31#define S3C2440_GPJ0_CAMDATA0 (0x02 << 0)
40 32
41#define S3C2440_GPJ1 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 1)
42#define S3C2440_GPJ1_INP (0x00 << 2)
43#define S3C2440_GPJ1_OUTP (0x01 << 2) 33#define S3C2440_GPJ1_OUTP (0x01 << 2)
44#define S3C2440_GPJ1_CAMDATA1 (0x02 << 2) 34#define S3C2440_GPJ1_CAMDATA1 (0x02 << 2)
45 35
46#define S3C2440_GPJ2 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 2)
47#define S3C2440_GPJ2_INP (0x00 << 4)
48#define S3C2440_GPJ2_OUTP (0x01 << 4) 36#define S3C2440_GPJ2_OUTP (0x01 << 4)
49#define S3C2440_GPJ2_CAMDATA2 (0x02 << 4) 37#define S3C2440_GPJ2_CAMDATA2 (0x02 << 4)
50 38
51#define S3C2440_GPJ3 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 3)
52#define S3C2440_GPJ3_INP (0x00 << 6)
53#define S3C2440_GPJ3_OUTP (0x01 << 6) 39#define S3C2440_GPJ3_OUTP (0x01 << 6)
54#define S3C2440_GPJ3_CAMDATA3 (0x02 << 6) 40#define S3C2440_GPJ3_CAMDATA3 (0x02 << 6)
55 41
56#define S3C2440_GPJ4 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 4)
57#define S3C2440_GPJ4_INP (0x00 << 8)
58#define S3C2440_GPJ4_OUTP (0x01 << 8) 42#define S3C2440_GPJ4_OUTP (0x01 << 8)
59#define S3C2440_GPJ4_CAMDATA4 (0x02 << 8) 43#define S3C2440_GPJ4_CAMDATA4 (0x02 << 8)
60 44
61#define S3C2440_GPJ5 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 5)
62#define S3C2440_GPJ5_INP (0x00 << 10)
63#define S3C2440_GPJ5_OUTP (0x01 << 10) 45#define S3C2440_GPJ5_OUTP (0x01 << 10)
64#define S3C2440_GPJ5_CAMDATA5 (0x02 << 10) 46#define S3C2440_GPJ5_CAMDATA5 (0x02 << 10)
65 47
66#define S3C2440_GPJ6 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 6)
67#define S3C2440_GPJ6_INP (0x00 << 12)
68#define S3C2440_GPJ6_OUTP (0x01 << 12) 48#define S3C2440_GPJ6_OUTP (0x01 << 12)
69#define S3C2440_GPJ6_CAMDATA6 (0x02 << 12) 49#define S3C2440_GPJ6_CAMDATA6 (0x02 << 12)
70 50
71#define S3C2440_GPJ7 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 7)
72#define S3C2440_GPJ7_INP (0x00 << 14)
73#define S3C2440_GPJ7_OUTP (0x01 << 14) 51#define S3C2440_GPJ7_OUTP (0x01 << 14)
74#define S3C2440_GPJ7_CAMDATA7 (0x02 << 14) 52#define S3C2440_GPJ7_CAMDATA7 (0x02 << 14)
75 53
76#define S3C2440_GPJ8 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 8)
77#define S3C2440_GPJ8_INP (0x00 << 16)
78#define S3C2440_GPJ8_OUTP (0x01 << 16) 54#define S3C2440_GPJ8_OUTP (0x01 << 16)
79#define S3C2440_GPJ8_CAMPCLK (0x02 << 16) 55#define S3C2440_GPJ8_CAMPCLK (0x02 << 16)
80 56
81#define S3C2440_GPJ9 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 9)
82#define S3C2440_GPJ9_INP (0x00 << 18)
83#define S3C2440_GPJ9_OUTP (0x01 << 18) 57#define S3C2440_GPJ9_OUTP (0x01 << 18)
84#define S3C2440_GPJ9_CAMVSYNC (0x02 << 18) 58#define S3C2440_GPJ9_CAMVSYNC (0x02 << 18)
85 59
86#define S3C2440_GPJ10 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 10)
87#define S3C2440_GPJ10_INP (0x00 << 20)
88#define S3C2440_GPJ10_OUTP (0x01 << 20) 60#define S3C2440_GPJ10_OUTP (0x01 << 20)
89#define S3C2440_GPJ10_CAMHREF (0x02 << 20) 61#define S3C2440_GPJ10_CAMHREF (0x02 << 20)
90 62
91#define S3C2440_GPJ11 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 11)
92#define S3C2440_GPJ11_INP (0x00 << 22)
93#define S3C2440_GPJ11_OUTP (0x01 << 22) 63#define S3C2440_GPJ11_OUTP (0x01 << 22)
94#define S3C2440_GPJ11_CAMCLKOUT (0x02 << 22) 64#define S3C2440_GPJ11_CAMCLKOUT (0x02 << 22)
95 65
96#define S3C2440_GPJ12 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 12)
97#define S3C2440_GPJ12_INP (0x00 << 24)
98#define S3C2440_GPJ12_OUTP (0x01 << 24) 66#define S3C2440_GPJ12_OUTP (0x01 << 24)
99#define S3C2440_GPJ12_CAMRESET (0x02 << 24) 67#define S3C2440_GPJ12_CAMRESET (0x02 << 24)
100 68
101#define S3C2443_GPJ13 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 13)
102#define S3C2443_GPJ14 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 14)
103#define S3C2443_GPJ15 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 15)
104
105#endif /* __ASM_ARCH_REGS_GPIOJ_H */ 69#endif /* __ASM_ARCH_REGS_GPIOJ_H */
106 70
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-irq.h b/arch/arm/mach-s3c2410/include/mach/regs-irq.h
index de86ee8812bd..0f07ba30b1fb 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-irq.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-irq.h
@@ -27,6 +27,16 @@
27#define S3C2410_SUBSRCPND S3C2410_IRQREG(0x018) 27#define S3C2410_SUBSRCPND S3C2410_IRQREG(0x018)
28#define S3C2410_INTSUBMSK S3C2410_IRQREG(0x01C) 28#define S3C2410_INTSUBMSK S3C2410_IRQREG(0x01C)
29 29
30#define S3C2416_PRIORITY_MODE1 S3C2410_IRQREG(0x030)
31#define S3C2416_PRIORITY_UPDATE1 S3C2410_IRQREG(0x034)
32#define S3C2416_SRCPND2 S3C2410_IRQREG(0x040)
33#define S3C2416_INTMOD2 S3C2410_IRQREG(0x044)
34#define S3C2416_INTMSK2 S3C2410_IRQREG(0x048)
35#define S3C2416_INTPND2 S3C2410_IRQREG(0x050)
36#define S3C2416_INTOFFSET2 S3C2410_IRQREG(0x054)
37#define S3C2416_PRIORITY_MODE2 S3C2410_IRQREG(0x070)
38#define S3C2416_PRIORITY_UPDATE2 S3C2410_IRQREG(0x074)
39
30/* mask: 0=enable, 1=disable 40/* mask: 0=enable, 1=disable
31 * 1 bit EINT, 4=EINT4, 23=EINT23 41 * 1 bit EINT, 4=EINT4, 23=EINT23
32 * EINT0,1,2,3 are not handled here. 42 * EINT0,1,2,3 are not handled here.
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
new file mode 100644
index 000000000000..2f31b74974af
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
@@ -0,0 +1,30 @@
1/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
2 *
3 * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
4 * as part of OpenInkpot project
5 * Copyright (c) 2009 Promwad Innovation Company
6 * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * S3C2416 memory register definitions
13*/
14
15#ifndef __ASM_ARM_REGS_S3C2416_MEM
16#define __ASM_ARM_REGS_S3C2416_MEM
17
18#ifndef S3C2416_MEMREG
19#define S3C2416_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
20#endif
21
22#define S3C2416_BANKCFG S3C2416_MEMREG(0x00)
23#define S3C2416_BANKCON1 S3C2416_MEMREG(0x04)
24#define S3C2416_BANKCON2 S3C2416_MEMREG(0x08)
25#define S3C2416_BANKCON3 S3C2416_MEMREG(0x0C)
26
27#define S3C2416_REFRESH S3C2416_MEMREG(0x10)
28#define S3C2416_TIMEOUT S3C2416_MEMREG(0x14)
29
30#endif /* __ASM_ARM_REGS_S3C2416_MEM */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
new file mode 100644
index 000000000000..e443167efb87
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
@@ -0,0 +1,24 @@
1/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
2 *
3 * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
4 * as part of OpenInkpot project
5 * Copyright (c) 2009 Promwad Innovation Company
6 * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * S3C2416 specific register definitions
13*/
14
15#ifndef __ASM_ARCH_REGS_S3C2416_H
16#define __ASM_ARCH_REGS_S3C2416_H "s3c2416"
17
18#define S3C2416_SWRST (S3C24XX_VA_CLKPWR + 0x44)
19#define S3C2416_SWRST_RESET (0x533C2416)
20
21/* see regs-power.h for the other registers in the power block. */
22
23#endif /* __ASM_ARCH_REGS_S3C2416_H */
24
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
index d87ebe0cb625..08ab9dfb6ae6 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
@@ -83,8 +83,7 @@
83#define S3C2443_HCLKCON_DMA4 (1<<4) 83#define S3C2443_HCLKCON_DMA4 (1<<4)
84#define S3C2443_HCLKCON_DMA5 (1<<5) 84#define S3C2443_HCLKCON_DMA5 (1<<5)
85#define S3C2443_HCLKCON_CAMIF (1<<8) 85#define S3C2443_HCLKCON_CAMIF (1<<8)
86#define S3C2443_HCLKCON_DISP (1<<9) 86#define S3C2443_HCLKCON_LCDC (1<<9)
87#define S3C2443_HCLKCON_LCDC (1<<10)
88#define S3C2443_HCLKCON_USBH (1<<11) 87#define S3C2443_HCLKCON_USBH (1<<11)
89#define S3C2443_HCLKCON_USBD (1<<12) 88#define S3C2443_HCLKCON_USBD (1<<12)
90#define S3C2443_HCLKCON_HSMMC (1<<16) 89#define S3C2443_HCLKCON_HSMMC (1<<16)
diff --git a/arch/arm/mach-s3c2410/include/mach/uncompress.h b/arch/arm/mach-s3c2410/include/mach/uncompress.h
index 72f756c5e504..8b283f847daa 100644
--- a/arch/arm/mach-s3c2410/include/mach/uncompress.h
+++ b/arch/arm/mach-s3c2410/include/mach/uncompress.h
@@ -40,7 +40,9 @@ static void arch_detect_cpu(void)
40 cpuid &= S3C2410_GSTATUS1_IDMASK; 40 cpuid &= S3C2410_GSTATUS1_IDMASK;
41 41
42 if (is_arm926() || cpuid == S3C2410_GSTATUS1_2440 || 42 if (is_arm926() || cpuid == S3C2410_GSTATUS1_2440 ||
43 cpuid == S3C2410_GSTATUS1_2442) { 43 cpuid == S3C2410_GSTATUS1_2442 ||
44 cpuid == S3C2410_GSTATUS1_2416 ||
45 cpuid == S3C2410_GSTATUS1_2450) {
44 fifo_mask = S3C2440_UFSTAT_TXMASK; 46 fifo_mask = S3C2440_UFSTAT_TXMASK;
45 fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT; 47 fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
46 } else { 48 } else {
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
index 7047317ed7f4..34fc05a4244b 100644
--- a/arch/arm/mach-s3c2410/mach-amlm5900.c
+++ b/arch/arm/mach-s3c2410/mach-amlm5900.c
@@ -56,6 +56,7 @@
56#include <plat/iic.h> 56#include <plat/iic.h>
57#include <plat/devs.h> 57#include <plat/devs.h>
58#include <plat/cpu.h> 58#include <plat/cpu.h>
59#include <plat/gpio-cfg.h>
59 60
60#ifdef CONFIG_MTD_PARTITIONS 61#ifdef CONFIG_MTD_PARTITIONS
61 62
@@ -225,8 +226,8 @@ static void amlm5900_init_pm(void)
225 } else { 226 } else {
226 enable_irq_wake(IRQ_EINT9); 227 enable_irq_wake(IRQ_EINT9);
227 /* configure the suspend/resume status pin */ 228 /* configure the suspend/resume status pin */
228 s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); 229 s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT);
229 s3c2410_gpio_pullup(S3C2410_GPF(2), 0); 230 s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_UP);
230 } 231 }
231} 232}
232static void __init amlm5900_init(void) 233static void __init amlm5900_init(void)
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 02b1b6220cba..c1f90f6fab42 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -61,6 +61,7 @@
61#include <plat/devs.h> 61#include <plat/devs.h>
62#include <plat/cpu.h> 62#include <plat/cpu.h>
63#include <plat/cpu-freq.h> 63#include <plat/cpu-freq.h>
64#include <plat/gpio-cfg.h>
64#include <plat/audio-simtec.h> 65#include <plat/audio-simtec.h>
65 66
66#include "usb-simtec.h" 67#include "usb-simtec.h"
@@ -216,15 +217,13 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
216static int bast_pm_suspend(struct sys_device *sd, pm_message_t state) 217static int bast_pm_suspend(struct sys_device *sd, pm_message_t state)
217{ 218{
218 /* ensure that an nRESET is not generated on resume. */ 219 /* ensure that an nRESET is not generated on resume. */
219 s3c2410_gpio_setpin(S3C2410_GPA(21), 1); 220 gpio_direction_output(S3C2410_GPA(21), 1);
220 s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
221
222 return 0; 221 return 0;
223} 222}
224 223
225static int bast_pm_resume(struct sys_device *sd) 224static int bast_pm_resume(struct sys_device *sd)
226{ 225{
227 s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT); 226 s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
228 return 0; 227 return 0;
229} 228}
230 229
@@ -634,7 +633,7 @@ static void __init bast_map_io(void)
634 633
635 s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks)); 634 s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks));
636 635
637 s3c_device_hwmon.dev.platform_data = &bast_hwmon_info; 636 s3c_hwmon_set_platdata(&bast_hwmon_info);
638 637
639 s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); 638 s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
640 s3c24xx_init_clocks(0); 639 s3c24xx_init_clocks(0);
@@ -658,6 +657,8 @@ static void __init bast_init(void)
658 nor_simtec_init(); 657 nor_simtec_init();
659 simtec_audio_add(NULL, true, &bast_audio); 658 simtec_audio_add(NULL, true, &bast_audio);
660 659
660 WARN_ON(gpio_request(S3C2410_GPA(21), "bast nreset"));
661
661 s3c_cpufreq_setboard(&bast_cpufreq); 662 s3c_cpufreq_setboard(&bast_cpufreq);
662} 663}
663 664
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index fbedd0760941..d2a2fad7db97 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -50,6 +50,7 @@
50#include <plat/udc.h> 50#include <plat/udc.h>
51#include <plat/iic.h> 51#include <plat/iic.h>
52 52
53#include <plat/gpio-cfg.h>
53#include <plat/clock.h> 54#include <plat/clock.h>
54#include <plat/devs.h> 55#include <plat/devs.h>
55#include <plat/cpu.h> 56#include <plat/cpu.h>
@@ -162,8 +163,8 @@ static struct s3c2410fb_display h1940_lcd __initdata = {
162 .xres = 240, 163 .xres = 240,
163 .yres = 320, 164 .yres = 320,
164 .bpp = 16, 165 .bpp = 16,
165 .left_margin = 20, 166 .left_margin = 8,
166 .right_margin = 8, 167 .right_margin = 20,
167 .hsync_len = 4, 168 .hsync_len = 4,
168 .upper_margin = 8, 169 .upper_margin = 8,
169 .lower_margin = 7, 170 .lower_margin = 7,
@@ -207,16 +208,16 @@ static int h1940_backlight_init(struct device *dev)
207{ 208{
208 gpio_request(S3C2410_GPB(0), "Backlight"); 209 gpio_request(S3C2410_GPB(0), "Backlight");
209 210
210 s3c2410_gpio_setpin(S3C2410_GPB(0), 0); 211 gpio_direction_output(S3C2410_GPB(0), 0);
211 s3c2410_gpio_pullup(S3C2410_GPB(0), 0); 212 s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
212 s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0); 213 s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
213 214
214 return 0; 215 return 0;
215} 216}
216 217
217static void h1940_backlight_exit(struct device *dev) 218static void h1940_backlight_exit(struct device *dev)
218{ 219{
219 s3c2410_gpio_cfgpin(S3C2410_GPB(0), 1/*S3C2410_GPB0_OUTP*/); 220 gpio_direction_output(S3C2410_GPB(0), 1);
220} 221}
221 222
222static struct platform_pwm_backlight_data backlight_data = { 223static struct platform_pwm_backlight_data backlight_data = {
@@ -245,18 +246,18 @@ static void h1940_lcd_power_set(struct plat_lcd_data *pd,
245 246
246 if (!power) { 247 if (!power) {
247 /* set to 3ec */ 248 /* set to 3ec */
248 s3c2410_gpio_setpin(S3C2410_GPC(0), 0); 249 gpio_direction_output(S3C2410_GPC(0), 0);
249 /* wait for 3ac */ 250 /* wait for 3ac */
250 do { 251 do {
251 value = s3c2410_gpio_getpin(S3C2410_GPC(6)); 252 value = gpio_get_value(S3C2410_GPC(6));
252 } while (value); 253 } while (value);
253 /* set to 38c */ 254 /* set to 38c */
254 s3c2410_gpio_setpin(S3C2410_GPC(5), 0); 255 gpio_direction_output(S3C2410_GPC(5), 0);
255 } else { 256 } else {
256 /* Set to 3ac */ 257 /* Set to 3ac */
257 s3c2410_gpio_setpin(S3C2410_GPC(5), 1); 258 gpio_direction_output(S3C2410_GPC(5), 1);
258 /* Set to 3ad */ 259 /* Set to 3ad */
259 s3c2410_gpio_setpin(S3C2410_GPC(0), 1); 260 gpio_direction_output(S3C2410_GPC(0), 1);
260 } 261 }
261} 262}
262 263
@@ -271,7 +272,6 @@ static struct platform_device h1940_lcd_powerdev = {
271}; 272};
272 273
273static struct platform_device *h1940_devices[] __initdata = { 274static struct platform_device *h1940_devices[] __initdata = {
274 &s3c_device_ts,
275 &s3c_device_ohci, 275 &s3c_device_ohci,
276 &s3c_device_lcd, 276 &s3c_device_lcd,
277 &s3c_device_wdt, 277 &s3c_device_wdt,
@@ -285,6 +285,8 @@ static struct platform_device *h1940_devices[] __initdata = {
285 &s3c_device_timer[0], 285 &s3c_device_timer[0],
286 &h1940_backlight, 286 &h1940_backlight,
287 &h1940_lcd_powerdev, 287 &h1940_lcd_powerdev,
288 &s3c_device_adc,
289 &s3c_device_ts,
288}; 290};
289 291
290static void __init h1940_map_io(void) 292static void __init h1940_map_io(void)
@@ -332,12 +334,13 @@ static void __init h1940_init(void)
332 gpio_request(S3C2410_GPC(5), "LCD power"); 334 gpio_request(S3C2410_GPC(5), "LCD power");
333 gpio_request(S3C2410_GPC(6), "LCD power"); 335 gpio_request(S3C2410_GPC(6), "LCD power");
334 336
337 gpio_direction_input(S3C2410_GPC(6));
335 338
336 platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices)); 339 platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
337} 340}
338 341
339MACHINE_START(H1940, "IPAQ-H1940") 342MACHINE_START(H1940, "IPAQ-H1940")
340 /* Maintainer: Ben Dooks <ben@fluff.org> */ 343 /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
341 .phys_io = S3C2410_PA_UART, 344 .phys_io = S3C2410_PA_UART,
342 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, 345 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
343 .boot_params = S3C2410_SDRAM_PA + 0x100, 346 .boot_params = S3C2410_SDRAM_PA + 0x100,
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index 684710f88142..41f299d983eb 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -26,6 +26,7 @@
26#include <linux/serial_core.h> 26#include <linux/serial_core.h>
27#include <linux/timer.h> 27#include <linux/timer.h>
28#include <linux/io.h> 28#include <linux/io.h>
29#include <linux/mmc/host.h>
29 30
30#include <mach/hardware.h> 31#include <mach/hardware.h>
31#include <asm/irq.h> 32#include <asm/irq.h>
@@ -46,6 +47,7 @@
46#include <plat/clock.h> 47#include <plat/clock.h>
47#include <plat/cpu.h> 48#include <plat/cpu.h>
48#include <plat/devs.h> 49#include <plat/devs.h>
50#include <plat/mci.h>
49#include <plat/s3c2410.h> 51#include <plat/s3c2410.h>
50#include <plat/udc.h> 52#include <plat/udc.h>
51 53
@@ -86,10 +88,10 @@ static void n30_udc_pullup(enum s3c2410_udc_cmd_e cmd)
86{ 88{
87 switch (cmd) { 89 switch (cmd) {
88 case S3C2410_UDC_P_ENABLE : 90 case S3C2410_UDC_P_ENABLE :
89 s3c2410_gpio_setpin(S3C2410_GPB(3), 1); 91 gpio_set_value(S3C2410_GPB(3), 1);
90 break; 92 break;
91 case S3C2410_UDC_P_DISABLE : 93 case S3C2410_UDC_P_DISABLE :
92 s3c2410_gpio_setpin(S3C2410_GPB(3), 0); 94 gpio_set_value(S3C2410_GPB(3), 0);
93 break; 95 break;
94 case S3C2410_UDC_P_RESET : 96 case S3C2410_UDC_P_RESET :
95 break; 97 break;
@@ -172,8 +174,10 @@ static struct gpio_keys_button n35_buttons[] = {
172 { 174 {
173 .gpio = S3C2410_GPF(0), 175 .gpio = S3C2410_GPF(0),
174 .code = KEY_POWER, 176 .code = KEY_POWER,
177 .type = EV_PWR,
175 .desc = "Power", 178 .desc = "Power",
176 .active_low = 0, 179 .active_low = 0,
180 .wakeup = 1,
177 }, 181 },
178 { 182 {
179 .gpio = S3C2410_GPG(9), 183 .gpio = S3C2410_GPG(9),
@@ -264,6 +268,14 @@ static struct s3c24xx_led_platdata n30_blue_led_pdata = {
264 .def_trigger = "", 268 .def_trigger = "",
265}; 269};
266 270
271/* This is the blue LED on the device. Originaly used to indicate GPS activity
272 * by flashing. */
273static struct s3c24xx_led_platdata n35_blue_led_pdata = {
274 .name = "blue_led",
275 .gpio = S3C2410_GPD(8),
276 .def_trigger = "",
277};
278
267/* This LED is driven by the battery microcontroller, and is blinking 279/* This LED is driven by the battery microcontroller, and is blinking
268 * red, blinking green or solid green when the battery is low, 280 * red, blinking green or solid green when the battery is low,
269 * charging or full respectively. By driving GPD9 low, it's possible 281 * charging or full respectively. By driving GPD9 low, it's possible
@@ -275,6 +287,13 @@ static struct s3c24xx_led_platdata n30_warning_led_pdata = {
275 .def_trigger = "", 287 .def_trigger = "",
276}; 288};
277 289
290static struct s3c24xx_led_platdata n35_warning_led_pdata = {
291 .name = "warning_led",
292 .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
293 .gpio = S3C2410_GPD(9),
294 .def_trigger = "",
295};
296
278static struct platform_device n30_blue_led = { 297static struct platform_device n30_blue_led = {
279 .name = "s3c24xx_led", 298 .name = "s3c24xx_led",
280 .id = 1, 299 .id = 1,
@@ -283,6 +302,14 @@ static struct platform_device n30_blue_led = {
283 }, 302 },
284}; 303};
285 304
305static struct platform_device n35_blue_led = {
306 .name = "s3c24xx_led",
307 .id = 1,
308 .dev = {
309 .platform_data = &n35_blue_led_pdata,
310 },
311};
312
286static struct platform_device n30_warning_led = { 313static struct platform_device n30_warning_led = {
287 .name = "s3c24xx_led", 314 .name = "s3c24xx_led",
288 .id = 2, 315 .id = 2,
@@ -291,6 +318,14 @@ static struct platform_device n30_warning_led = {
291 }, 318 },
292}; 319};
293 320
321static struct platform_device n35_warning_led = {
322 .name = "s3c24xx_led",
323 .id = 2,
324 .dev = {
325 .platform_data = &n35_warning_led_pdata,
326 },
327};
328
294static struct s3c2410fb_display n30_display __initdata = { 329static struct s3c2410fb_display n30_display __initdata = {
295 .type = S3C2410_LCDCON1_TFT, 330 .type = S3C2410_LCDCON1_TFT,
296 .width = 240, 331 .width = 240,
@@ -317,13 +352,36 @@ static struct s3c2410fb_mach_info n30_fb_info __initdata = {
317 .lpcsel = 0x06, 352 .lpcsel = 0x06,
318}; 353};
319 354
355static void n30_sdi_set_power(unsigned char power_mode, unsigned short vdd)
356{
357 switch (power_mode) {
358 case MMC_POWER_ON:
359 case MMC_POWER_UP:
360 gpio_set_value(S3C2410_GPG(4), 1);
361 break;
362 case MMC_POWER_OFF:
363 default:
364 gpio_set_value(S3C2410_GPG(4), 0);
365 break;
366 }
367}
368
369static struct s3c24xx_mci_pdata n30_mci_cfg __initdata = {
370 .gpio_detect = S3C2410_GPF(1),
371 .gpio_wprotect = S3C2410_GPG(10),
372 .ocr_avail = MMC_VDD_32_33,
373 .set_power = n30_sdi_set_power,
374};
375
320static struct platform_device *n30_devices[] __initdata = { 376static struct platform_device *n30_devices[] __initdata = {
321 &s3c_device_lcd, 377 &s3c_device_lcd,
322 &s3c_device_wdt, 378 &s3c_device_wdt,
323 &s3c_device_i2c0, 379 &s3c_device_i2c0,
324 &s3c_device_iis, 380 &s3c_device_iis,
325 &s3c_device_ohci, 381 &s3c_device_ohci,
382 &s3c_device_rtc,
326 &s3c_device_usbgadget, 383 &s3c_device_usbgadget,
384 &s3c_device_sdi,
327 &n30_button_device, 385 &n30_button_device,
328 &n30_blue_led, 386 &n30_blue_led,
329 &n30_warning_led, 387 &n30_warning_led,
@@ -334,8 +392,12 @@ static struct platform_device *n35_devices[] __initdata = {
334 &s3c_device_wdt, 392 &s3c_device_wdt,
335 &s3c_device_i2c0, 393 &s3c_device_i2c0,
336 &s3c_device_iis, 394 &s3c_device_iis,
395 &s3c_device_rtc,
337 &s3c_device_usbgadget, 396 &s3c_device_usbgadget,
397 &s3c_device_sdi,
338 &n35_button_device, 398 &n35_button_device,
399 &n35_blue_led,
400 &n35_warning_led,
339}; 401};
340 402
341static struct s3c2410_platform_i2c __initdata n30_i2ccfg = { 403static struct s3c2410_platform_i2c __initdata n30_i2ccfg = {
@@ -490,17 +552,15 @@ static void __init n30_map_io(void)
490 s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs)); 552 s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
491} 553}
492 554
493static void __init n30_init_irq(void)
494{
495 s3c24xx_init_irq();
496}
497
498/* GPB3 is the line that controls the pull-up for the USB D+ line */ 555/* GPB3 is the line that controls the pull-up for the USB D+ line */
499 556
500static void __init n30_init(void) 557static void __init n30_init(void)
501{ 558{
559 WARN_ON(gpio_request(S3C2410_GPG(4), "mmc power"));
560
502 s3c24xx_fb_set_platdata(&n30_fb_info); 561 s3c24xx_fb_set_platdata(&n30_fb_info);
503 s3c24xx_udc_set_platdata(&n30_udc_cfg); 562 s3c24xx_udc_set_platdata(&n30_udc_cfg);
563 s3c24xx_mci_set_platdata(&n30_mci_cfg);
504 s3c_i2c0_set_platdata(&n30_i2ccfg); 564 s3c_i2c0_set_platdata(&n30_i2ccfg);
505 565
506 /* Turn off suspend on both USB ports, and switch the 566 /* Turn off suspend on both USB ports, and switch the
@@ -532,10 +592,13 @@ static void __init n30_init(void)
532 s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST | 592 s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
533 S3C2410_MISCCR_USBSUSPND0 | 593 S3C2410_MISCCR_USBSUSPND0 |
534 S3C2410_MISCCR_USBSUSPND1, 594 S3C2410_MISCCR_USBSUSPND1,
535 S3C2410_MISCCR_USBSUSPND1); 595 S3C2410_MISCCR_USBSUSPND0);
536 596
537 platform_add_devices(n35_devices, ARRAY_SIZE(n35_devices)); 597 platform_add_devices(n35_devices, ARRAY_SIZE(n35_devices));
538 } 598 }
599
600 WARN_ON(gpio_request(S3C2410_GPB(3), "udc pup"));
601 gpio_direction_output(S3C2410_GPB(3), 0);
539} 602}
540 603
541MACHINE_START(N30, "Acer-N30") 604MACHINE_START(N30, "Acer-N30")
@@ -547,7 +610,7 @@ MACHINE_START(N30, "Acer-N30")
547 .boot_params = S3C2410_SDRAM_PA + 0x100, 610 .boot_params = S3C2410_SDRAM_PA + 0x100,
548 .timer = &s3c24xx_timer, 611 .timer = &s3c24xx_timer,
549 .init_machine = n30_init, 612 .init_machine = n30_init,
550 .init_irq = n30_init_irq, 613 .init_irq = s3c24xx_init_irq,
551 .map_io = n30_map_io, 614 .map_io = n30_map_io,
552MACHINE_END 615MACHINE_END
553 616
@@ -559,6 +622,6 @@ MACHINE_START(N35, "Acer-N35")
559 .boot_params = S3C2410_SDRAM_PA + 0x100, 622 .boot_params = S3C2410_SDRAM_PA + 0x100,
560 .timer = &s3c24xx_timer, 623 .timer = &s3c24xx_timer,
561 .init_machine = n30_init, 624 .init_machine = n30_init,
562 .init_irq = n30_init_irq, 625 .init_irq = s3c24xx_init_irq,
563 .map_io = n30_map_io, 626 .map_io = n30_map_io,
564MACHINE_END 627MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
index 92a4ec375d82..d0e87b6e2e0f 100644
--- a/arch/arm/mach-s3c2410/mach-qt2410.c
+++ b/arch/arm/mach-s3c2410/mach-qt2410.c
@@ -58,6 +58,7 @@
58#include <plat/iic.h> 58#include <plat/iic.h>
59 59
60#include <plat/common-smdk.h> 60#include <plat/common-smdk.h>
61#include <plat/gpio-cfg.h>
61#include <plat/devs.h> 62#include <plat/devs.h>
62#include <plat/cpu.h> 63#include <plat/cpu.h>
63#include <plat/pm.h> 64#include <plat/pm.h>
@@ -219,10 +220,10 @@ static void spi_gpio_cs(struct s3c2410_spigpio_info *spi, int cs)
219{ 220{
220 switch (cs) { 221 switch (cs) {
221 case BITBANG_CS_ACTIVE: 222 case BITBANG_CS_ACTIVE:
222 s3c2410_gpio_setpin(S3C2410_GPB(5), 0); 223 gpio_set_value(S3C2410_GPB(5), 0);
223 break; 224 break;
224 case BITBANG_CS_INACTIVE: 225 case BITBANG_CS_INACTIVE:
225 s3c2410_gpio_setpin(S3C2410_GPB(5), 1); 226 gpio_set_value(S3C2410_GPB(5), 1);
226 break; 227 break;
227 } 228 }
228} 229}
@@ -347,13 +348,14 @@ static void __init qt2410_machine_init(void)
347 } 348 }
348 s3c24xx_fb_set_platdata(&qt2410_fb_info); 349 s3c24xx_fb_set_platdata(&qt2410_fb_info);
349 350
350 s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT); 351 s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
351 s3c2410_gpio_setpin(S3C2410_GPB(0), 1); 352 s3c2410_gpio_setpin(S3C2410_GPB(0), 1);
352 353
353 s3c24xx_udc_set_platdata(&qt2410_udc_cfg); 354 s3c24xx_udc_set_platdata(&qt2410_udc_cfg);
354 s3c_i2c0_set_platdata(NULL); 355 s3c_i2c0_set_platdata(NULL);
355 356
356 s3c2410_gpio_cfgpin(S3C2410_GPB(5), S3C2410_GPIO_OUTPUT); 357 WARN_ON(gpio_request(S3C2410_GPB(5), "spi cs"));
358 gpio_direction_output(S3C2410_GPB(5), 1);
357 359
358 platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices)); 360 platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices));
359 s3c_pm_init(); 361 s3c_pm_init();
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 9051f0d31123..d540d79dd264 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -357,8 +357,7 @@ static struct clk *vr1000_clocks[] __initdata = {
357 357
358static void vr1000_power_off(void) 358static void vr1000_power_off(void)
359{ 359{
360 s3c2410_gpio_cfgpin(S3C2410_GPB(9), S3C2410_GPIO_OUTPUT); 360 gpio_direction_output(S3C2410_GPB(9), 1);
361 s3c2410_gpio_setpin(S3C2410_GPB(9), 1);
362} 361}
363 362
364static void __init vr1000_map_io(void) 363static void __init vr1000_map_io(void)
@@ -395,6 +394,8 @@ static void __init vr1000_init(void)
395 394
396 nor_simtec_init(); 395 nor_simtec_init();
397 simtec_audio_add(NULL, true, NULL); 396 simtec_audio_add(NULL, true, NULL);
397
398 WARN_ON(gpio_request(S3C2410_GPB(9), "power off"));
398} 399}
399 400
400MACHINE_START(VR1000, "Thorcom-VR1000") 401MACHINE_START(VR1000, "Thorcom-VR1000")
diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c
index 966119c8efee..725636fc4dc3 100644
--- a/arch/arm/mach-s3c2410/pm.c
+++ b/arch/arm/mach-s3c2410/pm.c
@@ -60,10 +60,10 @@ static void s3c2410_pm_prepare(void)
60 __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM)); 60 __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
61 } 61 }
62 62
63 /* the RX3715 uses similar code and the same H1940 and the 63 /* RX3715 and RX1950 use similar to H1940 code and the
64 * same offsets for resume and checksum pointers */ 64 * same offsets for resume and checksum pointers */
65 65
66 if (machine_is_rx3715()) { 66 if (machine_is_rx3715() || machine_is_rx1950()) {
67 void *base = phys_to_virt(H1940_SUSPEND_CHECK); 67 void *base = phys_to_virt(H1940_SUSPEND_CHECK);
68 unsigned long ptr; 68 unsigned long ptr;
69 unsigned long calc = 0; 69 unsigned long calc = 0;
@@ -79,6 +79,17 @@ static void s3c2410_pm_prepare(void)
79 if ( machine_is_aml_m5900() ) 79 if ( machine_is_aml_m5900() )
80 s3c2410_gpio_setpin(S3C2410_GPF(2), 1); 80 s3c2410_gpio_setpin(S3C2410_GPF(2), 1);
81 81
82 if (machine_is_rx1950()) {
83 /* According to S3C2442 user's manual, page 7-17,
84 * when the system is operating in NAND boot mode,
85 * the hardware pin configuration - EINT[23:21] –
86 * must be set as input for starting up after
87 * wakeup from sleep mode
88 */
89 s3c_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_INPUT);
90 s3c_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPIO_INPUT);
91 s3c_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPIO_INPUT);
92 }
82} 93}
83 94
84static int s3c2410_pm_resume(struct sys_device *dev) 95static int s3c2410_pm_resume(struct sys_device *dev)
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index 91ba42f688ac..adc90a3c5890 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -16,6 +16,7 @@
16#include <linux/list.h> 16#include <linux/list.h>
17#include <linux/timer.h> 17#include <linux/timer.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/gpio.h>
19#include <linux/clk.h> 20#include <linux/clk.h>
20#include <linux/sysdev.h> 21#include <linux/sysdev.h>
21#include <linux/serial_core.h> 22#include <linux/serial_core.h>
@@ -40,6 +41,10 @@
40#include <plat/clock.h> 41#include <plat/clock.h>
41#include <plat/pll.h> 42#include <plat/pll.h>
42 43
44#include <plat/gpio-core.h>
45#include <plat/gpio-cfg.h>
46#include <plat/gpio-cfg-helpers.h>
47
43/* Initial IO mappings */ 48/* Initial IO mappings */
44 49
45static struct map_desc s3c2410_iodesc[] __initdata = { 50static struct map_desc s3c2410_iodesc[] __initdata = {
@@ -65,6 +70,9 @@ void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no)
65 70
66void __init s3c2410_map_io(void) 71void __init s3c2410_map_io(void)
67{ 72{
73 s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
74 s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
75
68 iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc)); 76 iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
69} 77}
70 78
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
index 9a8c0657ae50..cef6a65637bd 100644
--- a/arch/arm/mach-s3c2412/Kconfig
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -16,7 +16,8 @@ config CPU_S3C2412
16config CPU_S3C2412_ONLY 16config CPU_S3C2412_ONLY
17 bool 17 bool
18 depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \ 18 depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
19 !CPU_S3C2440 && !CPU_S3C2442 && !CPU_S3C2443 && CPU_S3C2412 19 !CPU_2416 && !CPU_S3C2440 && !CPU_S3C2442 && \
20 !CPU_S3C2443 && CPU_S3C2412
20 default y if CPU_S3C2412 21 default y if CPU_S3C2412
21 22
22config S3C2412_DMA 23config S3C2412_DMA
diff --git a/arch/arm/mach-s3c2412/gpio.c b/arch/arm/mach-s3c2412/gpio.c
index f7afece7fc38..3404a876b33e 100644
--- a/arch/arm/mach-s3c2412/gpio.c
+++ b/arch/arm/mach-s3c2412/gpio.c
@@ -16,41 +16,43 @@
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/gpio.h>
19 20
20#include <asm/mach/arch.h> 21#include <asm/mach/arch.h>
21#include <asm/mach/map.h> 22#include <asm/mach/map.h>
22 23
23#include <mach/regs-gpio.h> 24#include <mach/regs-gpio.h>
24
25#include <mach/hardware.h> 25#include <mach/hardware.h>
26 26
27#include <plat/gpio-core.h>
28
27int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state) 29int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state)
28{ 30{
29 void __iomem *base = S3C24XX_GPIO_BASE(pin); 31 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
30 unsigned long offs = S3C2410_GPIO_OFFSET(pin); 32 unsigned long offs = pin - chip->chip.base;
31 unsigned long flags; 33 unsigned long flags;
32 unsigned long slpcon; 34 unsigned long slpcon;
33 35
34 offs *= 2; 36 offs *= 2;
35 37
36 if (pin < S3C2410_GPIO_BANKB) 38 if (pin < S3C2410_GPB(0))
37 return -EINVAL; 39 return -EINVAL;
38 40
39 if (pin >= S3C2410_GPIO_BANKF && 41 if (pin >= S3C2410_GPF(0) &&
40 pin <= S3C2410_GPIO_BANKG) 42 pin <= S3C2410_GPG(16))
41 return -EINVAL; 43 return -EINVAL;
42 44
43 if (pin > (S3C2410_GPIO_BANKH + 32)) 45 if (pin > S3C2410_GPH(16))
44 return -EINVAL; 46 return -EINVAL;
45 47
46 local_irq_save(flags); 48 local_irq_save(flags);
47 49
48 slpcon = __raw_readl(base + 0x0C); 50 slpcon = __raw_readl(chip->base + 0x0C);
49 51
50 slpcon &= ~(3 << offs); 52 slpcon &= ~(3 << offs);
51 slpcon |= state << offs; 53 slpcon |= state << offs;
52 54
53 __raw_writel(slpcon, base + 0x0C); 55 __raw_writel(slpcon, chip->base + 0x0C);
54 56
55 local_irq_restore(flags); 57 local_irq_restore(flags);
56 58
diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c
index 14f4798291aa..478f4b4606c2 100644
--- a/arch/arm/mach-s3c2412/mach-jive.c
+++ b/arch/arm/mach-s3c2412/mach-jive.c
@@ -48,6 +48,7 @@
48#include <linux/mtd/nand_ecc.h> 48#include <linux/mtd/nand_ecc.h>
49#include <linux/mtd/partitions.h> 49#include <linux/mtd/partitions.h>
50 50
51#include <plat/gpio-cfg.h>
51#include <plat/clock.h> 52#include <plat/clock.h>
52#include <plat/devs.h> 53#include <plat/devs.h>
53#include <plat/cpu.h> 54#include <plat/cpu.h>
@@ -357,8 +358,7 @@ static void jive_lcm_reset(unsigned int set)
357{ 358{
358 printk(KERN_DEBUG "%s(%d)\n", __func__, set); 359 printk(KERN_DEBUG "%s(%d)\n", __func__, set);
359 360
360 s3c2410_gpio_setpin(S3C2410_GPG(13), set); 361 gpio_set_value(S3C2410_GPG(13), set);
361 s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_OUTPUT);
362} 362}
363 363
364#undef LCD_UPPER_MARGIN 364#undef LCD_UPPER_MARGIN
@@ -391,7 +391,7 @@ static struct ili9320_platdata jive_lcm_config = {
391 391
392static void jive_lcd_spi_chipselect(struct s3c2410_spigpio_info *spi, int cs) 392static void jive_lcd_spi_chipselect(struct s3c2410_spigpio_info *spi, int cs)
393{ 393{
394 s3c2410_gpio_setpin(S3C2410_GPB(7), cs ? 0 : 1); 394 gpio_set_value(S3C2410_GPB(7), cs ? 0 : 1);
395} 395}
396 396
397static struct s3c2410_spigpio_info jive_lcd_spi = { 397static struct s3c2410_spigpio_info jive_lcd_spi = {
@@ -413,7 +413,7 @@ static struct platform_device jive_device_lcdspi = {
413 413
414static void jive_wm8750_chipselect(struct s3c2410_spigpio_info *spi, int cs) 414static void jive_wm8750_chipselect(struct s3c2410_spigpio_info *spi, int cs)
415{ 415{
416 s3c2410_gpio_setpin(S3C2410_GPH(10), cs ? 0 : 1); 416 gpio_set_value(S3C2410_GPH(10), cs ? 0 : 1);
417} 417}
418 418
419static struct s3c2410_spigpio_info jive_wm8750_spi = { 419static struct s3c2410_spigpio_info jive_wm8750_spi = {
@@ -531,7 +531,7 @@ static void jive_power_off(void)
531 printk(KERN_INFO "powering system down...\n"); 531 printk(KERN_INFO "powering system down...\n");
532 532
533 s3c2410_gpio_setpin(S3C2410_GPC(5), 1); 533 s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
534 s3c2410_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT); 534 s3c_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT);
535} 535}
536 536
537static void __init jive_machine_init(void) 537static void __init jive_machine_init(void)
@@ -636,22 +636,22 @@ static void __init jive_machine_init(void)
636 636
637 /* initialise the spi */ 637 /* initialise the spi */
638 638
639 s3c2410_gpio_setpin(S3C2410_GPG(13), 0); 639 gpio_request(S3C2410_GPG(13), "lcm reset");
640 s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_OUTPUT); 640 gpio_direction_output(S3C2410_GPG(13), 0);
641 641
642 s3c2410_gpio_setpin(S3C2410_GPB(7), 1); 642 gpio_request(S3C2410_GPB(7), "jive spi");
643 s3c2410_gpio_cfgpin(S3C2410_GPB(7), S3C2410_GPIO_OUTPUT); 643 gpio_direction_output(S3C2410_GPB(7), 1);
644 644
645 s3c2410_gpio_setpin(S3C2410_GPB(6), 0); 645 s3c2410_gpio_setpin(S3C2410_GPB(6), 0);
646 s3c2410_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT); 646 s3c_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT);
647 647
648 s3c2410_gpio_setpin(S3C2410_GPG(8), 1); 648 s3c2410_gpio_setpin(S3C2410_GPG(8), 1);
649 s3c2410_gpio_cfgpin(S3C2410_GPG(8), S3C2410_GPIO_OUTPUT); 649 s3c_gpio_cfgpin(S3C2410_GPG(8), S3C2410_GPIO_OUTPUT);
650 650
651 /* initialise the WM8750 spi */ 651 /* initialise the WM8750 spi */
652 652
653 s3c2410_gpio_setpin(S3C2410_GPH(10), 1); 653 gpio_request(S3C2410_GPH(10), "jive wm8750 spi");
654 s3c2410_gpio_cfgpin(S3C2410_GPH(10), S3C2410_GPIO_OUTPUT); 654 gpio_direction_output(S3C2410_GPH(10), 1);
655 655
656 /* Turn off suspend on both USB ports, and switch the 656 /* Turn off suspend on both USB ports, and switch the
657 * selectable USB port to USB device mode. */ 657 * selectable USB port to USB device mode. */
@@ -674,7 +674,7 @@ static void __init jive_machine_init(void)
674} 674}
675 675
676MACHINE_START(JIVE, "JIVE") 676MACHINE_START(JIVE, "JIVE")
677 /* Maintainer: Ben Dooks <ben@fluff.org> */ 677 /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
678 .phys_io = S3C2410_PA_UART, 678 .phys_io = S3C2410_PA_UART,
679 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, 679 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
680 .boot_params = S3C2410_SDRAM_PA + 0x100, 680 .boot_params = S3C2410_SDRAM_PA + 0x100,
diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c
index 0392065af1af..ba93a356a839 100644
--- a/arch/arm/mach-s3c2412/mach-smdk2413.c
+++ b/arch/arm/mach-s3c2412/mach-smdk2413.c
@@ -85,10 +85,10 @@ static void smdk2413_udc_pullup(enum s3c2410_udc_cmd_e cmd)
85 switch (cmd) 85 switch (cmd)
86 { 86 {
87 case S3C2410_UDC_P_ENABLE : 87 case S3C2410_UDC_P_ENABLE :
88 s3c2410_gpio_setpin(S3C2410_GPF(2), 1); 88 gpio_set_value(S3C2410_GPF(2), 1);
89 break; 89 break;
90 case S3C2410_UDC_P_DISABLE : 90 case S3C2410_UDC_P_DISABLE :
91 s3c2410_gpio_setpin(S3C2410_GPF(2), 0); 91 gpio_set_value(S3C2410_GPF(2), 0);
92 break; 92 break;
93 case S3C2410_UDC_P_RESET : 93 case S3C2410_UDC_P_RESET :
94 break; 94 break;
@@ -134,8 +134,8 @@ static void __init smdk2413_machine_init(void)
134{ /* Turn off suspend on both USB ports, and switch the 134{ /* Turn off suspend on both USB ports, and switch the
135 * selectable USB port to USB device mode. */ 135 * selectable USB port to USB device mode. */
136 136
137 s3c2410_gpio_setpin(S3C2410_GPF(2), 0); 137 WARN_ON(gpio_request(S3C2410_GPF(2), "udc pull"));
138 s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); 138 gpio_direction_output(S3C2410_GPF(2), 0);
139 139
140 s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST | 140 s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
141 S3C2410_MISCCR_USBSUSPND0 | 141 S3C2410_MISCCR_USBSUSPND0 |
@@ -150,7 +150,7 @@ static void __init smdk2413_machine_init(void)
150} 150}
151 151
152MACHINE_START(S3C2413, "S3C2413") 152MACHINE_START(S3C2413, "S3C2413")
153 /* Maintainer: Ben Dooks <ben@fluff.org> */ 153 /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
154 .phys_io = S3C2410_PA_UART, 154 .phys_io = S3C2410_PA_UART,
155 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, 155 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
156 .boot_params = S3C2410_SDRAM_PA + 0x100, 156 .boot_params = S3C2410_SDRAM_PA + 0x100,
@@ -163,7 +163,7 @@ MACHINE_START(S3C2413, "S3C2413")
163MACHINE_END 163MACHINE_END
164 164
165MACHINE_START(SMDK2412, "SMDK2412") 165MACHINE_START(SMDK2412, "SMDK2412")
166 /* Maintainer: Ben Dooks <ben@fluff.org> */ 166 /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
167 .phys_io = S3C2410_PA_UART, 167 .phys_io = S3C2410_PA_UART,
168 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, 168 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
169 .boot_params = S3C2410_SDRAM_PA + 0x100, 169 .boot_params = S3C2410_SDRAM_PA + 0x100,
@@ -176,7 +176,7 @@ MACHINE_START(SMDK2412, "SMDK2412")
176MACHINE_END 176MACHINE_END
177 177
178MACHINE_START(SMDK2413, "SMDK2413") 178MACHINE_START(SMDK2413, "SMDK2413")
179 /* Maintainer: Ben Dooks <ben@fluff.org> */ 179 /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
180 .phys_io = S3C2410_PA_UART, 180 .phys_io = S3C2410_PA_UART,
181 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, 181 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
182 .boot_params = S3C2410_SDRAM_PA + 0x100, 182 .boot_params = S3C2410_SDRAM_PA + 0x100,
diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig
new file mode 100644
index 000000000000..657e4fe17f39
--- /dev/null
+++ b/arch/arm/mach-s3c2416/Kconfig
@@ -0,0 +1,39 @@
1# arch/arm/mach-s3c2416/Kconfig
2#
3# Copyright 2009 Yauhen Kharuzhy <jekhor@gmail.com>
4#
5# Licensed under GPLv2
6
7# note, this also supports the S3C2450 which is so similar it has the same
8# ID code as the S3C2416.
9
10config CPU_S3C2416
11 bool
12 depends on ARCH_S3C2410
13 select CPU_ARM926T
14 select S3C2416_DMA if S3C2410_DMA
15 select CPU_LLSERIAL_S3C2440
16 select S3C_GPIO_PULL_UPDOWN
17 select SAMSUNG_CLKSRC
18 select S3C2443_CLOCK
19 help
20 Support for the S3C2416 SoC from the S3C24XX line
21
22config S3C2416_DMA
23 bool
24 depends on CPU_S3C2416
25 help
26 Internal config node for S3C2416 DMA support
27
28menu "S3C2416 Machines"
29
30config MACH_SMDK2416
31 bool "SMDK2416"
32 select CPU_S3C2416
33 select S3C_DEV_FB
34 select S3C_DEV_HSMMC
35 select S3C_DEV_HSMMC1
36 help
37 Say Y here if you are using an SMDK2416
38
39endmenu
diff --git a/arch/arm/mach-s3c2416/Makefile b/arch/arm/mach-s3c2416/Makefile
new file mode 100644
index 000000000000..6c12c7bf40ad
--- /dev/null
+++ b/arch/arm/mach-s3c2416/Makefile
@@ -0,0 +1,19 @@
1# arch/arm/mach-s3c2416/Makefile
2#
3# Copyright 2009 Yauhen Kharuzhy <jekhor@gmail.com>
4#
5# Licensed under GPLv2
6
7obj-y :=
8obj-m :=
9obj-n :=
10obj- :=
11
12obj-$(CONFIG_CPU_S3C2416) += s3c2416.o clock.o
13obj-$(CONFIG_CPU_S3C2416) += irq.o
14
15#obj-$(CONFIG_S3C2416_DMA) += dma.o
16
17# Machine support
18
19obj-$(CONFIG_MACH_SMDK2416) += mach-smdk2416.o
diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c
new file mode 100644
index 000000000000..7ccf5a2a2bfc
--- /dev/null
+++ b/arch/arm/mach-s3c2416/clock.c
@@ -0,0 +1,135 @@
1/* linux/arch/arm/mach-s3c2416/clock.c
2 *
3 * Copyright (c) 2010 Simtec Electronics
4 * Copyright (c) 2010 Ben Dooks <ben-linux@fluff.org>
5 *
6 * S3C2416 Clock control support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include <linux/init.h>
15#include <linux/clk.h>
16
17#include <plat/s3c2416.h>
18#include <plat/s3c2443.h>
19#include <plat/clock.h>
20#include <plat/clock-clksrc.h>
21#include <plat/cpu.h>
22
23#include <plat/cpu-freq.h>
24#include <plat/pll6553x.h>
25#include <plat/pll.h>
26
27#include <asm/mach/map.h>
28
29#include <mach/regs-clock.h>
30#include <mach/regs-s3c2443-clock.h>
31
32static unsigned int armdiv[8] = {
33 [0] = 1,
34 [1] = 2,
35 [2] = 3,
36 [3] = 4,
37 [5] = 6,
38 [7] = 8,
39};
40
41/* ID to hardware numbering, 0 is HSMMC1, 1 is HSMMC0 */
42static struct clksrc_clk hsmmc_div[] = {
43 [0] = {
44 .clk = {
45 .name = "hsmmc-div",
46 .id = 1,
47 .parent = &clk_esysclk.clk,
48 },
49 .reg_div = { .reg = S3C2416_CLKDIV2, .size = 2, .shift = 6 },
50 },
51 [1] = {
52 .clk = {
53 .name = "hsmmc-div",
54 .id = 0,
55 .parent = &clk_esysclk.clk,
56 },
57 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
58 },
59};
60
61static struct clksrc_clk hsmmc_mux[] = {
62 [0] = {
63 .clk = {
64 .id = 1,
65 .name = "hsmmc-if",
66 .ctrlbit = (1 << 6),
67 .enable = s3c2443_clkcon_enable_s,
68 },
69 .sources = &(struct clksrc_sources) {
70 .nr_sources = 2,
71 .sources = (struct clk *[]) {
72 [0] = &hsmmc_div[0].clk,
73 [1] = NULL, /* to fix */
74 },
75 },
76 .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 16 },
77 },
78 [1] = {
79 .clk = {
80 .id = 0,
81 .name = "hsmmc-if",
82 .ctrlbit = (1 << 12),
83 .enable = s3c2443_clkcon_enable_s,
84 },
85 .sources = &(struct clksrc_sources) {
86 .nr_sources = 2,
87 .sources = (struct clk *[]) {
88 [0] = &hsmmc_div[1].clk,
89 [1] = NULL, /* to fix */
90 },
91 },
92 .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 17 },
93 },
94};
95
96
97static inline unsigned int s3c2416_fclk_div(unsigned long clkcon0)
98{
99 clkcon0 &= 7 << S3C2443_CLKDIV0_ARMDIV_SHIFT;
100
101 return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
102}
103
104void __init_or_cpufreq s3c2416_setup_clocks(void)
105{
106 s3c2443_common_setup_clocks(s3c2416_get_pll, s3c2416_fclk_div);
107}
108
109
110static struct clksrc_clk *clksrcs[] __initdata = {
111 &hsmmc_div[0],
112 &hsmmc_div[1],
113 &hsmmc_mux[0],
114 &hsmmc_mux[1],
115};
116
117void __init s3c2416_init_clocks(int xtal)
118{
119 u32 epllcon = __raw_readl(S3C2443_EPLLCON);
120 u32 epllcon1 = __raw_readl(S3C2443_EPLLCON+4);
121 int ptr;
122
123 /* s3c2416 EPLL compatible with s3c64xx */
124 clk_epll.rate = s3c_get_pll6553x(xtal, epllcon, epllcon1);
125
126 clk_epll.parent = &clk_epllref.clk;
127
128 s3c2443_common_init_clocks(xtal, s3c2416_get_pll, s3c2416_fclk_div);
129
130 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
131 s3c_register_clksrc(clksrcs[ptr], 1);
132
133 s3c_pwmclk_init();
134
135}
diff --git a/arch/arm/mach-s3c2416/irq.c b/arch/arm/mach-s3c2416/irq.c
new file mode 100644
index 000000000000..89f521d59d06
--- /dev/null
+++ b/arch/arm/mach-s3c2416/irq.c
@@ -0,0 +1,254 @@
1/* linux/arch/arm/mach-s3c2416/irq.c
2 *
3 * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
4 * as part of OpenInkpot project
5 * Copyright (c) 2009 Promwad Innovation Company
6 * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22*/
23
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/interrupt.h>
27#include <linux/ioport.h>
28#include <linux/sysdev.h>
29#include <linux/io.h>
30
31#include <mach/hardware.h>
32#include <asm/irq.h>
33
34#include <asm/mach/irq.h>
35
36#include <mach/regs-irq.h>
37#include <mach/regs-gpio.h>
38
39#include <plat/cpu.h>
40#include <plat/pm.h>
41#include <plat/irq.h>
42
43#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
44
45static inline void s3c2416_irq_demux(unsigned int irq, unsigned int len)
46{
47 unsigned int subsrc, submsk;
48 unsigned int end;
49
50 /* read the current pending interrupts, and the mask
51 * for what it is available */
52
53 subsrc = __raw_readl(S3C2410_SUBSRCPND);
54 submsk = __raw_readl(S3C2410_INTSUBMSK);
55
56 subsrc &= ~submsk;
57 subsrc >>= (irq - S3C2410_IRQSUB(0));
58 subsrc &= (1 << len)-1;
59
60 end = len + irq;
61
62 for (; irq < end && subsrc; irq++) {
63 if (subsrc & 1)
64 generic_handle_irq(irq);
65
66 subsrc >>= 1;
67 }
68}
69
70/* WDT/AC97 sub interrupts */
71
72static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
73{
74 s3c2416_irq_demux(IRQ_S3C2443_WDT, 4);
75}
76
77#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
78#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
79
80static void s3c2416_irq_wdtac97_mask(unsigned int irqno)
81{
82 s3c_irqsub_mask(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
83}
84
85static void s3c2416_irq_wdtac97_unmask(unsigned int irqno)
86{
87 s3c_irqsub_unmask(irqno, INTMSK_WDTAC97);
88}
89
90static void s3c2416_irq_wdtac97_ack(unsigned int irqno)
91{
92 s3c_irqsub_maskack(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
93}
94
95static struct irq_chip s3c2416_irq_wdtac97 = {
96 .mask = s3c2416_irq_wdtac97_mask,
97 .unmask = s3c2416_irq_wdtac97_unmask,
98 .ack = s3c2416_irq_wdtac97_ack,
99};
100
101
102/* LCD sub interrupts */
103
104static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
105{
106 s3c2416_irq_demux(IRQ_S3C2443_LCD1, 4);
107}
108
109#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0))
110#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
111
112static void s3c2416_irq_lcd_mask(unsigned int irqno)
113{
114 s3c_irqsub_mask(irqno, INTMSK_LCD, SUBMSK_LCD);
115}
116
117static void s3c2416_irq_lcd_unmask(unsigned int irqno)
118{
119 s3c_irqsub_unmask(irqno, INTMSK_LCD);
120}
121
122static void s3c2416_irq_lcd_ack(unsigned int irqno)
123{
124 s3c_irqsub_maskack(irqno, INTMSK_LCD, SUBMSK_LCD);
125}
126
127static struct irq_chip s3c2416_irq_lcd = {
128 .mask = s3c2416_irq_lcd_mask,
129 .unmask = s3c2416_irq_lcd_unmask,
130 .ack = s3c2416_irq_lcd_ack,
131};
132
133
134/* DMA sub interrupts */
135
136static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
137{
138 s3c2416_irq_demux(IRQ_S3C2443_DMA0, 6);
139}
140
141#define INTMSK_DMA (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
142#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
143
144
145static void s3c2416_irq_dma_mask(unsigned int irqno)
146{
147 s3c_irqsub_mask(irqno, INTMSK_DMA, SUBMSK_DMA);
148}
149
150static void s3c2416_irq_dma_unmask(unsigned int irqno)
151{
152 s3c_irqsub_unmask(irqno, INTMSK_DMA);
153}
154
155static void s3c2416_irq_dma_ack(unsigned int irqno)
156{
157 s3c_irqsub_maskack(irqno, INTMSK_DMA, SUBMSK_DMA);
158}
159
160static struct irq_chip s3c2416_irq_dma = {
161 .mask = s3c2416_irq_dma_mask,
162 .unmask = s3c2416_irq_dma_unmask,
163 .ack = s3c2416_irq_dma_ack,
164};
165
166
167/* UART3 sub interrupts */
168
169static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
170{
171 s3c2416_irq_demux(IRQ_S3C2443_UART3, 3);
172}
173
174#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
175#define SUBMSK_UART3 (0xf << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
176
177
178static void s3c2416_irq_uart3_mask(unsigned int irqno)
179{
180 s3c_irqsub_mask(irqno, INTMSK_UART3, SUBMSK_UART3);
181}
182
183static void s3c2416_irq_uart3_unmask(unsigned int irqno)
184{
185 s3c_irqsub_unmask(irqno, INTMSK_UART3);
186}
187
188static void s3c2416_irq_uart3_ack(unsigned int irqno)
189{
190 s3c_irqsub_maskack(irqno, INTMSK_UART3, SUBMSK_UART3);
191}
192
193static struct irq_chip s3c2416_irq_uart3 = {
194 .mask = s3c2416_irq_uart3_mask,
195 .unmask = s3c2416_irq_uart3_unmask,
196 .ack = s3c2416_irq_uart3_ack,
197};
198
199
200/* IRQ initialisation code */
201
202static int __init s3c2416_add_sub(unsigned int base,
203 void (*demux)(unsigned int,
204 struct irq_desc *),
205 struct irq_chip *chip,
206 unsigned int start, unsigned int end)
207{
208 unsigned int irqno;
209
210 set_irq_chip(base, &s3c_irq_level_chip);
211 set_irq_handler(base, handle_level_irq);
212 set_irq_chained_handler(base, demux);
213
214 for (irqno = start; irqno <= end; irqno++) {
215 set_irq_chip(irqno, chip);
216 set_irq_handler(irqno, handle_level_irq);
217 set_irq_flags(irqno, IRQF_VALID);
218 }
219
220 return 0;
221}
222
223static int __init s3c2416_irq_add(struct sys_device *sysdev)
224{
225 printk(KERN_INFO "S3C2416: IRQ Support\n");
226
227 s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd,
228 IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4);
229
230 s3c2416_add_sub(IRQ_S3C2443_DMA, s3c2416_irq_demux_dma,
231 &s3c2416_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
232
233 s3c2416_add_sub(IRQ_S3C2443_UART3, s3c2416_irq_demux_uart3,
234 &s3c2416_irq_uart3,
235 IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
236
237 s3c2416_add_sub(IRQ_WDT, s3c2416_irq_demux_wdtac97,
238 &s3c2416_irq_wdtac97,
239 IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
240
241 return 0;
242}
243
244static struct sysdev_driver s3c2416_irq_driver = {
245 .add = s3c2416_irq_add,
246};
247
248static int __init s3c2416_irq_init(void)
249{
250 return sysdev_driver_register(&s3c2416_sysclass, &s3c2416_irq_driver);
251}
252
253arch_initcall(s3c2416_irq_init);
254
diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c2416/mach-smdk2416.c
new file mode 100644
index 000000000000..5fc3f67ef265
--- /dev/null
+++ b/arch/arm/mach-s3c2416/mach-smdk2416.c
@@ -0,0 +1,206 @@
1/* linux/arch/arm/mach-s3c2416/mach-hanlin_v3c.c
2 *
3 * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
4 * as part of OpenInkpot project
5 * Copyright (c) 2009 Promwad Innovation Company
6 * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12*/
13
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <linux/interrupt.h>
17#include <linux/list.h>
18#include <linux/timer.h>
19#include <linux/init.h>
20#include <linux/serial_core.h>
21#include <linux/platform_device.h>
22#include <linux/io.h>
23#include <linux/mtd/partitions.h>
24#include <linux/gpio.h>
25#include <linux/fb.h>
26
27#include <asm/mach/arch.h>
28#include <asm/mach/map.h>
29#include <asm/mach/irq.h>
30
31#include <mach/hardware.h>
32#include <asm/irq.h>
33#include <asm/mach-types.h>
34
35#include <plat/regs-serial.h>
36#include <mach/regs-gpio.h>
37#include <mach/regs-lcd.h>
38
39#include <mach/idle.h>
40#include <mach/leds-gpio.h>
41#include <plat/iic.h>
42
43#include <plat/s3c2416.h>
44#include <plat/gpio-cfg.h>
45#include <plat/clock.h>
46#include <plat/devs.h>
47#include <plat/cpu.h>
48#include <plat/nand.h>
49
50#include <plat/regs-fb-v4.h>
51#include <plat/fb.h>
52
53#include <plat/common-smdk.h>
54
55static struct map_desc smdk2416_iodesc[] __initdata = {
56 /* ISA IO Space map (memory space selected by A24) */
57
58 {
59 .virtual = (u32)S3C24XX_VA_ISA_WORD,
60 .pfn = __phys_to_pfn(S3C2410_CS2),
61 .length = 0x10000,
62 .type = MT_DEVICE,
63 }, {
64 .virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
65 .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
66 .length = SZ_4M,
67 .type = MT_DEVICE,
68 }, {
69 .virtual = (u32)S3C24XX_VA_ISA_BYTE,
70 .pfn = __phys_to_pfn(S3C2410_CS2),
71 .length = 0x10000,
72 .type = MT_DEVICE,
73 }, {
74 .virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
75 .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
76 .length = SZ_4M,
77 .type = MT_DEVICE,
78 }
79};
80
81#define UCON (S3C2410_UCON_DEFAULT | \
82 S3C2440_UCON_PCLK | \
83 S3C2443_UCON_RXERR_IRQEN)
84
85#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
86
87#define UFCON (S3C2410_UFCON_RXTRIG8 | \
88 S3C2410_UFCON_FIFOMODE | \
89 S3C2440_UFCON_TXTRIG16)
90
91static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = {
92 [0] = {
93 .hwport = 0,
94 .flags = 0,
95 .ucon = UCON,
96 .ulcon = ULCON,
97 .ufcon = UFCON,
98 },
99 [1] = {
100 .hwport = 1,
101 .flags = 0,
102 .ucon = UCON,
103 .ulcon = ULCON,
104 .ufcon = UFCON,
105 },
106 /* IR port */
107 [2] = {
108 .hwport = 2,
109 .flags = 0,
110 .ucon = UCON,
111 .ulcon = ULCON | 0x50,
112 .ufcon = UFCON,
113 }
114};
115
116struct s3c_fb_pd_win smdk2416_fb_win[] = {
117 [0] = {
118 /* think this is the same as the smdk6410 */
119 .win_mode = {
120 .pixclock = 41094,
121 .left_margin = 8,
122 .right_margin = 13,
123 .upper_margin = 7,
124 .lower_margin = 5,
125 .hsync_len = 3,
126 .vsync_len = 1,
127 .xres = 800,
128 .yres = 480,
129 },
130 .default_bpp = 16,
131 .max_bpp = 32,
132 },
133};
134
135static void s3c2416_fb_gpio_setup_24bpp(void)
136{
137 unsigned int gpio;
138
139 for (gpio = S3C2410_GPC(1); gpio <= S3C2410_GPC(4); gpio++) {
140 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
141 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
142 }
143
144 for (gpio = S3C2410_GPC(8); gpio <= S3C2410_GPC(15); gpio++) {
145 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
146 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
147 }
148
149 for (gpio = S3C2410_GPD(0); gpio <= S3C2410_GPD(15); gpio++) {
150 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
151 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
152 }
153}
154
155static struct s3c_fb_platdata smdk2416_fb_platdata = {
156 .win[0] = &smdk2416_fb_win[0],
157 .setup_gpio = s3c2416_fb_gpio_setup_24bpp,
158 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
159 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
160};
161
162static struct platform_device *smdk2416_devices[] __initdata = {
163 &s3c_device_fb,
164 &s3c_device_wdt,
165 &s3c_device_ohci,
166 &s3c_device_i2c0,
167 &s3c_device_hsmmc0,
168 &s3c_device_hsmmc1,
169};
170
171static void __init smdk2416_map_io(void)
172{
173 s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc));
174 s3c24xx_init_clocks(12000000);
175 s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs));
176}
177
178static void __init smdk2416_machine_init(void)
179{
180 s3c_i2c0_set_platdata(NULL);
181 s3c_fb_set_platdata(&smdk2416_fb_platdata);
182
183 gpio_request(S3C2410_GPB(4), "USBHost Power");
184 gpio_direction_output(S3C2410_GPB(4), 1);
185
186 gpio_request(S3C2410_GPB(3), "Display Power");
187 gpio_direction_output(S3C2410_GPB(3), 1);
188
189 gpio_request(S3C2410_GPB(1), "Display Reset");
190 gpio_direction_output(S3C2410_GPB(1), 1);
191
192 platform_add_devices(smdk2416_devices, ARRAY_SIZE(smdk2416_devices));
193 smdk_machine_init();
194}
195
196MACHINE_START(SMDK2416, "SMDK2416")
197 /* Maintainer: Yauhen Kharuzhy <jekhor@gmail.com> */
198 .phys_io = S3C2410_PA_UART,
199 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
200 .boot_params = S3C2410_SDRAM_PA + 0x100,
201
202 .init_irq = s3c24xx_init_irq,
203 .map_io = smdk2416_map_io,
204 .init_machine = smdk2416_machine_init,
205 .timer = &s3c24xx_timer,
206MACHINE_END
diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c
new file mode 100644
index 000000000000..35dabccd0ac2
--- /dev/null
+++ b/arch/arm/mach-s3c2416/s3c2416.c
@@ -0,0 +1,130 @@
1/* linux/arch/arm/mach-s3c2416/s3c2416.c
2 *
3 * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
4 * as part of OpenInkpot project
5 * Copyright (c) 2009 Promwad Innovation Company
6 * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
7 *
8 * Samsung S3C2416 Mobile CPU support
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25#include <linux/kernel.h>
26#include <linux/types.h>
27#include <linux/interrupt.h>
28#include <linux/list.h>
29#include <linux/timer.h>
30#include <linux/init.h>
31#include <linux/gpio.h>
32#include <linux/platform_device.h>
33#include <linux/serial_core.h>
34#include <linux/sysdev.h>
35#include <linux/clk.h>
36#include <linux/io.h>
37
38#include <asm/mach/arch.h>
39#include <asm/mach/map.h>
40#include <asm/mach/irq.h>
41
42#include <mach/hardware.h>
43#include <asm/proc-fns.h>
44#include <asm/irq.h>
45
46#include <mach/reset.h>
47#include <mach/idle.h>
48#include <mach/regs-s3c2443-clock.h>
49
50#include <plat/gpio-core.h>
51#include <plat/gpio-cfg.h>
52#include <plat/gpio-cfg-helpers.h>
53#include <plat/s3c2416.h>
54#include <plat/devs.h>
55#include <plat/cpu.h>
56
57#include <plat/iic-core.h>
58
59static struct map_desc s3c2416_iodesc[] __initdata = {
60 IODESC_ENT(WATCHDOG),
61 IODESC_ENT(CLKPWR),
62 IODESC_ENT(TIMER),
63};
64
65struct sysdev_class s3c2416_sysclass = {
66 .name = "s3c2416-core",
67};
68
69static struct sys_device s3c2416_sysdev = {
70 .cls = &s3c2416_sysclass,
71};
72
73static void s3c2416_hard_reset(void)
74{
75 __raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST);
76}
77
78int __init s3c2416_init(void)
79{
80 printk(KERN_INFO "S3C2416: Initializing architecture\n");
81
82 s3c24xx_reset_hook = s3c2416_hard_reset;
83 /* s3c24xx_idle = s3c2416_idle; */
84
85 /* change WDT IRQ number */
86 s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT;
87 s3c_device_wdt.resource[1].end = IRQ_S3C2443_WDT;
88
89 /* the i2c devices are directly compatible with s3c2440 */
90 s3c_i2c0_setname("s3c2440-i2c");
91 s3c_i2c1_setname("s3c2440-i2c");
92
93 s3c_device_fb.name = "s3c2443-fb";
94
95 return sysdev_register(&s3c2416_sysdev);
96}
97
98void __init s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no)
99{
100 s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
101
102 s3c_device_nand.name = "s3c2416-nand";
103}
104
105/* s3c2416_map_io
106 *
107 * register the standard cpu IO areas, and any passed in from the
108 * machine specific initialisation.
109 */
110
111void __init s3c2416_map_io(void)
112{
113 s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_updown;
114 s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_updown;
115
116 iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc));
117}
118
119/* need to register class before we actually register the device, and
120 * we also need to ensure that it has been initialised before any of the
121 * drivers even try to use it (even if not on an s3c2416 based system)
122 * as a driver which may support both 2443 and 2440 may try and use it.
123*/
124
125static int __init s3c2416_core_init(void)
126{
127 return sysdev_class_register(&s3c2416_sysclass);
128}
129
130core_initcall(s3c2416_core_init);
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index 7f465265cf04..cd8e7de388f0 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -6,6 +6,7 @@ config CPU_S3C2440
6 bool 6 bool
7 depends on ARCH_S3C2410 7 depends on ARCH_S3C2410
8 select CPU_ARM920T 8 select CPU_ARM920T
9 select S3C_GPIO_PULL_UP
9 select S3C2410_CLOCK 10 select S3C2410_CLOCK
10 select S3C2410_PM if PM 11 select S3C2410_PM if PM
11 select S3C2410_GPIO 12 select S3C2410_GPIO
@@ -187,4 +188,17 @@ config MACH_MINI2440
187 Say Y here to select support for the MINI2440. Is a 10cm x 10cm board 188 Say Y here to select support for the MINI2440. Is a 10cm x 10cm board
188 available via various sources. It can come with a 3.5" or 7" touch LCD. 189 available via various sources. It can come with a 3.5" or 7" touch LCD.
189 190
191config MACH_RX1950
192 bool "HP iPAQ rx1950"
193 select CPU_S3C2442
194 select S3C24XX_DCLK
195 select PM_H1940 if PM
196 select I2C
197 select S3C2410_PWM
198 select S3C_DEV_NAND
199 select S3C2410_IOTIMING if S3C2440_CPUFREQ
200 select S3C2440_XTAL_16934400
201 help
202 Say Y here if you're using HP iPAQ rx1950
203
190endmenu 204endmenu
diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile
index c85ba32d8956..d5440fa34b04 100644
--- a/arch/arm/mach-s3c2440/Makefile
+++ b/arch/arm/mach-s3c2440/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
34obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o 34obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o
35obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o 35obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o
36obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o 36obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o
37obj-$(CONFIG_MACH_RX1950) += mach-rx1950.o
37 38
38# extra machine support 39# extra machine support
39 40
diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c2440/mach-mini2440.c
index 571b17683d96..a76bcda210ad 100644
--- a/arch/arm/mach-s3c2440/mach-mini2440.c
+++ b/arch/arm/mach-s3c2440/mach-mini2440.c
@@ -53,6 +53,7 @@
53#include <linux/mtd/nand_ecc.h> 53#include <linux/mtd/nand_ecc.h>
54#include <linux/mtd/partitions.h> 54#include <linux/mtd/partitions.h>
55 55
56#include <plat/gpio-cfg.h>
56#include <plat/clock.h> 57#include <plat/clock.h>
57#include <plat/devs.h> 58#include <plat/devs.h>
58#include <plat/cpu.h> 59#include <plat/cpu.h>
@@ -102,10 +103,10 @@ static void mini2440_udc_pullup(enum s3c2410_udc_cmd_e cmd)
102 103
103 switch (cmd) { 104 switch (cmd) {
104 case S3C2410_UDC_P_ENABLE : 105 case S3C2410_UDC_P_ENABLE :
105 s3c2410_gpio_setpin(S3C2410_GPC(5), 1); 106 gpio_set_value(S3C2410_GPC(5), 1);
106 break; 107 break;
107 case S3C2410_UDC_P_DISABLE : 108 case S3C2410_UDC_P_DISABLE :
108 s3c2410_gpio_setpin(S3C2410_GPC(5), 0); 109 gpio_set_value(S3C2410_GPC(5), 0);
109 break; 110 break;
110 case S3C2410_UDC_P_RESET : 111 case S3C2410_UDC_P_RESET :
111 break; 112 break;
@@ -632,25 +633,25 @@ static void __init mini2440_init(void)
632 mini2440_parse_features(&features, mini2440_features_str); 633 mini2440_parse_features(&features, mini2440_features_str);
633 634
634 /* turn LCD on */ 635 /* turn LCD on */
635 s3c2410_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND); 636 s3c_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);
636 637
637 /* Turn the backlight early on */ 638 /* Turn the backlight early on */
638 s3c2410_gpio_setpin(S3C2410_GPG(4), 1); 639 WARN_ON(gpio_request(S3C2410_GPG(4), "backlight"));
639 s3c2410_gpio_cfgpin(S3C2410_GPG(4), S3C2410_GPIO_OUTPUT); 640 gpio_direction_output(S3C2410_GPG(4), 1);
640 641
641 /* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */ 642 /* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */
642 s3c2410_gpio_pullup(S3C2410_GPB(1), 0); 643 s3c_gpio_setpull(S3C2410_GPB(1), S3C_GPIO_PULL_UP);
643 s3c2410_gpio_setpin(S3C2410_GPB(1), 0); 644 s3c2410_gpio_setpin(S3C2410_GPB(1), 0);
644 s3c2410_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT); 645 s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT);
645 646
646 /* Make sure the D+ pullup pin is output */ 647 /* Make sure the D+ pullup pin is output */
647 s3c2410_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT); 648 WARN_ON(gpio_request(S3C2410_GPC(5), "udc pup"));
649 gpio_direction_output(S3C2410_GPC(5), 0);
648 650
649 /* mark the key as input, without pullups (there is one on the board) */ 651 /* mark the key as input, without pullups (there is one on the board) */
650 for (i = 0; i < ARRAY_SIZE(mini2440_buttons); i++) { 652 for (i = 0; i < ARRAY_SIZE(mini2440_buttons); i++) {
651 s3c2410_gpio_pullup(mini2440_buttons[i].gpio, 0); 653 s3c_gpio_setpull(mini2440_buttons[i].gpio, S3C_GPIO_PULL_UP);
652 s3c2410_gpio_cfgpin(mini2440_buttons[i].gpio, 654 s3c_gpio_cfgpin(mini2440_buttons[i].gpio, S3C2410_GPIO_INPUT);
653 S3C2410_GPIO_INPUT);
654 } 655 }
655 if (features.lcd_index != -1) { 656 if (features.lcd_index != -1) {
656 int li; 657 int li;
diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c
index 342041593f22..3ff62de45fde 100644
--- a/arch/arm/mach-s3c2440/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2440/mach-nexcoder.c
@@ -40,6 +40,7 @@
40#include <plat/regs-serial.h> 40#include <plat/regs-serial.h>
41#include <plat/iic.h> 41#include <plat/iic.h>
42 42
43#include <plat/gpio-cfg.h>
43#include <plat/s3c2410.h> 44#include <plat/s3c2410.h>
44#include <plat/s3c244x.h> 45#include <plat/s3c244x.h>
45#include <plat/clock.h> 46#include <plat/clock.h>
@@ -122,15 +123,15 @@ static void __init nexcoder_sensorboard_init(void)
122{ 123{
123 // Initialize SCCB bus 124 // Initialize SCCB bus
124 s3c2410_gpio_setpin(S3C2410_GPE(14), 1); // IICSCL 125 s3c2410_gpio_setpin(S3C2410_GPE(14), 1); // IICSCL
125 s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_OUTPUT); 126 s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_OUTPUT);
126 s3c2410_gpio_setpin(S3C2410_GPE(15), 1); // IICSDA 127 s3c2410_gpio_setpin(S3C2410_GPE(15), 1); // IICSDA
127 s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_OUTPUT); 128 s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_OUTPUT);
128 129
129 // Power up the sensor board 130 // Power up the sensor board
130 s3c2410_gpio_setpin(S3C2410_GPF(1), 1); 131 s3c2410_gpio_setpin(S3C2410_GPF(1), 1);
131 s3c2410_gpio_cfgpin(S3C2410_GPF(1), S3C2410_GPIO_OUTPUT); // CAM_GPIO7 => nLDO_PWRDN 132 s3c_gpio_cfgpin(S3C2410_GPF(1), S3C2410_GPIO_OUTPUT); // CAM_GPIO7 => nLDO_PWRDN
132 s3c2410_gpio_setpin(S3C2410_GPF(2), 0); 133 s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
133 s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); // CAM_GPIO6 => CAM_PWRDN 134 s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); // CAM_GPIO6 => CAM_PWRDN
134} 135}
135 136
136static void __init nexcoder_map_io(void) 137static void __init nexcoder_map_io(void)
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index f35371db33f5..319458da71a0 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -49,6 +49,7 @@
49#include <linux/mtd/nand_ecc.h> 49#include <linux/mtd/nand_ecc.h>
50#include <linux/mtd/partitions.h> 50#include <linux/mtd/partitions.h>
51 51
52#include <plat/gpio-cfg.h>
52#include <plat/clock.h> 53#include <plat/clock.h>
53#include <plat/devs.h> 54#include <plat/devs.h>
54#include <plat/cpu.h> 55#include <plat/cpu.h>
@@ -298,7 +299,7 @@ static int osiris_pm_suspend(struct sys_device *sd, pm_message_t state)
298 299
299 /* ensure that an nRESET is not generated on resume. */ 300 /* ensure that an nRESET is not generated on resume. */
300 s3c2410_gpio_setpin(S3C2410_GPA(21), 1); 301 s3c2410_gpio_setpin(S3C2410_GPA(21), 1);
301 s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT); 302 s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
302 303
303 return 0; 304 return 0;
304} 305}
@@ -310,7 +311,7 @@ static int osiris_pm_resume(struct sys_device *sd)
310 311
311 __raw_writeb(pm_osiris_ctrl0, OSIRIS_VA_CTRL0); 312 __raw_writeb(pm_osiris_ctrl0, OSIRIS_VA_CTRL0);
312 313
313 s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT); 314 s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
314 315
315 return 0; 316 return 0;
316} 317}
diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c
new file mode 100644
index 000000000000..8603b577a24b
--- /dev/null
+++ b/arch/arm/mach-s3c2440/mach-rx1950.c
@@ -0,0 +1,582 @@
1/* linux/arch/arm/mach-s3c2440/mach-rx1950.c
2 *
3 * Copyright (c) 2006-2009 Victor Chukhantsev, Denis Grigoriev,
4 * Copyright (c) 2007-2010 Vasily Khoruzhick
5 *
6 * based on smdk2440 written by Ben Dooks
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12*/
13
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <linux/interrupt.h>
17#include <linux/list.h>
18#include <linux/delay.h>
19#include <linux/timer.h>
20#include <linux/init.h>
21#include <linux/gpio.h>
22#include <linux/platform_device.h>
23#include <linux/serial_core.h>
24#include <linux/input.h>
25#include <linux/gpio_keys.h>
26#include <linux/sysdev.h>
27#include <linux/pwm_backlight.h>
28#include <linux/pwm.h>
29
30#include <linux/mtd/mtd.h>
31#include <linux/mtd/partitions.h>
32
33#include <linux/mmc/host.h>
34
35#include <asm/mach/arch.h>
36#include <asm/mach/map.h>
37#include <asm/mach-types.h>
38
39#include <mach/regs-gpio.h>
40#include <mach/regs-gpioj.h>
41#include <mach/h1940.h>
42#include <mach/fb.h>
43
44#include <plat/clock.h>
45#include <plat/regs-serial.h>
46#include <plat/regs-iic.h>
47#include <plat/mci.h>
48#include <plat/udc.h>
49#include <plat/nand.h>
50#include <plat/iic.h>
51#include <plat/devs.h>
52#include <plat/cpu.h>
53#include <plat/pm.h>
54#include <plat/irq.h>
55#include <plat/ts.h>
56
57#define LCD_PWM_PERIOD 192960
58#define LCD_PWM_DUTY 127353
59
60static struct map_desc rx1950_iodesc[] __initdata = {
61};
62
63static struct s3c24xx_uart_clksrc rx1950_serial_clocks[] = {
64 [0] = {
65 .name = "fclk",
66 .divisor = 0x0a,
67 .min_baud = 0,
68 .max_baud = 0,
69 },
70};
71
72static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
73 [0] = {
74 .hwport = 0,
75 .flags = 0,
76 .ucon = 0x3c5,
77 .ulcon = 0x03,
78 .ufcon = 0x51,
79 .clocks = rx1950_serial_clocks,
80 .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
81 },
82 [1] = {
83 .hwport = 1,
84 .flags = 0,
85 .ucon = 0x3c5,
86 .ulcon = 0x03,
87 .ufcon = 0x51,
88 .clocks = rx1950_serial_clocks,
89 .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
90 },
91 /* IR port */
92 [2] = {
93 .hwport = 2,
94 .flags = 0,
95 .ucon = 0x3c5,
96 .ulcon = 0x43,
97 .ufcon = 0xf1,
98 .clocks = rx1950_serial_clocks,
99 .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
100 },
101};
102
103static struct s3c2410fb_display rx1950_display = {
104 .type = S3C2410_LCDCON1_TFT,
105 .width = 240,
106 .height = 320,
107 .xres = 240,
108 .yres = 320,
109 .bpp = 16,
110
111 .pixclock = 260000,
112 .left_margin = 10,
113 .right_margin = 20,
114 .hsync_len = 10,
115 .upper_margin = 2,
116 .lower_margin = 2,
117 .vsync_len = 2,
118
119 .lcdcon5 = S3C2410_LCDCON5_FRM565 |
120 S3C2410_LCDCON5_INVVCLK |
121 S3C2410_LCDCON5_INVVLINE |
122 S3C2410_LCDCON5_INVVFRAME |
123 S3C2410_LCDCON5_HWSWP |
124 (0x02 << 13) |
125 (0x02 << 15),
126
127};
128
129static struct s3c2410fb_mach_info rx1950_lcd_cfg = {
130 .displays = &rx1950_display,
131 .num_displays = 1,
132 .default_display = 0,
133
134 .lpcsel = 0x02,
135 .gpccon = 0xaa9556a9,
136 .gpccon_mask = 0xffc003fc,
137 .gpcup = 0x0000ffff,
138 .gpcup_mask = 0xffffffff,
139
140 .gpdcon = 0xaa90aaa1,
141 .gpdcon_mask = 0xffc0fff0,
142 .gpdup = 0x0000fcfd,
143 .gpdup_mask = 0xffffffff,
144
145};
146
147static struct pwm_device *lcd_pwm;
148
149void rx1950_lcd_power(int enable)
150{
151 int i;
152 static int enabled;
153 if (enabled == enable)
154 return;
155 if (!enable) {
156
157 /* GPC11-GPC15->OUTPUT */
158 for (i = 11; i < 16; i++)
159 gpio_direction_output(S3C2410_GPC(i), 1);
160
161 /* Wait a bit here... */
162 mdelay(100);
163
164 /* GPD2-GPD7->OUTPUT */
165 /* GPD11-GPD15->OUTPUT */
166 /* GPD2-GPD7->1, GPD11-GPD15->1 */
167 for (i = 2; i < 8; i++)
168 gpio_direction_output(S3C2410_GPD(i), 1);
169 for (i = 11; i < 16; i++)
170 gpio_direction_output(S3C2410_GPD(i), 1);
171
172 /* Wait a bit here...*/
173 mdelay(100);
174
175 /* GPB0->OUTPUT, GPB0->0 */
176 gpio_direction_output(S3C2410_GPB(0), 0);
177
178 /* GPC1-GPC4->OUTPUT, GPC1-4->0 */
179 for (i = 1; i < 5; i++)
180 gpio_direction_output(S3C2410_GPC(i), 0);
181
182 /* GPC15-GPC11->0 */
183 for (i = 11; i < 16; i++)
184 gpio_direction_output(S3C2410_GPC(i), 0);
185
186 /* GPD15-GPD11->0, GPD2->GPD7->0 */
187 for (i = 11; i < 16; i++)
188 gpio_direction_output(S3C2410_GPD(i), 0);
189
190 for (i = 2; i < 8; i++)
191 gpio_direction_output(S3C2410_GPD(i), 0);
192
193 /* GPC6->0, GPC7->0, GPC5->0 */
194 gpio_direction_output(S3C2410_GPC(6), 0);
195 gpio_direction_output(S3C2410_GPC(7), 0);
196 gpio_direction_output(S3C2410_GPC(5), 0);
197
198 /* GPB1->OUTPUT, GPB1->0 */
199 gpio_direction_output(S3C2410_GPB(1), 0);
200 pwm_config(lcd_pwm, 0, LCD_PWM_PERIOD);
201 pwm_disable(lcd_pwm);
202
203 /* GPC0->0, GPC10->0 */
204 gpio_direction_output(S3C2410_GPC(0), 0);
205 gpio_direction_output(S3C2410_GPC(10), 0);
206 } else {
207 pwm_config(lcd_pwm, LCD_PWM_DUTY, LCD_PWM_PERIOD);
208 pwm_enable(lcd_pwm);
209
210 gpio_direction_output(S3C2410_GPC(0), 1);
211 gpio_direction_output(S3C2410_GPC(5), 1);
212
213 s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPB1_TOUT1);
214 gpio_direction_output(S3C2410_GPC(7), 1);
215
216 for (i = 1; i < 5; i++)
217 s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2));
218
219 for (i = 11; i < 16; i++)
220 s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2));
221
222 for (i = 2; i < 8; i++)
223 s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2));
224
225 for (i = 11; i < 16; i++)
226 s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2));
227
228 gpio_direction_output(S3C2410_GPC(10), 1);
229 gpio_direction_output(S3C2410_GPC(6), 1);
230 }
231 enabled = enable;
232}
233
234static void rx1950_bl_power(int enable)
235{
236 static int enabled;
237 if (enabled == enable)
238 return;
239 if (!enable) {
240 gpio_direction_output(S3C2410_GPB(0), 0);
241 } else {
242 /* LED driver need a "push" to power on */
243 gpio_direction_output(S3C2410_GPB(0), 1);
244 /* Warm up backlight for one period of PWM.
245 * Without this trick its almost impossible to
246 * enable backlight with low brightness value
247 */
248 ndelay(48000);
249 s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
250 }
251 enabled = enable;
252}
253
254static int rx1950_backlight_init(struct device *dev)
255{
256 WARN_ON(gpio_request(S3C2410_GPB(0), "Backlight"));
257 lcd_pwm = pwm_request(1, "RX1950 LCD");
258 if (IS_ERR(lcd_pwm)) {
259 dev_err(dev, "Unable to request PWM for LCD power!\n");
260 return PTR_ERR(lcd_pwm);
261 }
262
263 rx1950_lcd_power(1);
264 rx1950_bl_power(1);
265
266 return 0;
267}
268
269static void rx1950_backlight_exit(struct device *dev)
270{
271 rx1950_bl_power(0);
272 rx1950_lcd_power(0);
273
274 pwm_free(lcd_pwm);
275 gpio_free(S3C2410_GPB(0));
276}
277
278
279static int rx1950_backlight_notify(struct device *dev, int brightness)
280{
281 if (!brightness) {
282 rx1950_bl_power(0);
283 rx1950_lcd_power(0);
284 } else {
285 rx1950_lcd_power(1);
286 rx1950_bl_power(1);
287 }
288 return brightness;
289}
290
291static struct platform_pwm_backlight_data rx1950_backlight_data = {
292 .pwm_id = 0,
293 .max_brightness = 24,
294 .dft_brightness = 4,
295 .pwm_period_ns = 48000,
296 .init = rx1950_backlight_init,
297 .notify = rx1950_backlight_notify,
298 .exit = rx1950_backlight_exit,
299};
300
301static struct platform_device rx1950_backlight = {
302 .name = "pwm-backlight",
303 .dev = {
304 .parent = &s3c_device_timer[0].dev,
305 .platform_data = &rx1950_backlight_data,
306 },
307};
308
309static void rx1950_set_mmc_power(unsigned char power_mode, unsigned short vdd)
310{
311 switch (power_mode) {
312 case MMC_POWER_OFF:
313 gpio_direction_output(S3C2410_GPJ(1), 0);
314 break;
315 case MMC_POWER_UP:
316 case MMC_POWER_ON:
317 gpio_direction_output(S3C2410_GPJ(1), 1);
318 break;
319 default:
320 break;
321 }
322}
323
324static struct s3c24xx_mci_pdata rx1950_mmc_cfg __initdata = {
325 .gpio_detect = S3C2410_GPF(5),
326 .gpio_wprotect = S3C2410_GPH(8),
327 .set_power = rx1950_set_mmc_power,
328 .ocr_avail = MMC_VDD_32_33,
329};
330
331static struct mtd_partition rx1950_nand_part[] = {
332 [0] = {
333 .name = "Boot0",
334 .offset = 0,
335 .size = 0x4000,
336 .mask_flags = MTD_WRITEABLE,
337 },
338 [1] = {
339 .name = "Boot1",
340 .offset = MTDPART_OFS_APPEND,
341 .size = 0x40000,
342 .mask_flags = MTD_WRITEABLE,
343 },
344 [2] = {
345 .name = "Kernel",
346 .offset = MTDPART_OFS_APPEND,
347 .size = 0x300000,
348 .mask_flags = 0,
349 },
350 [3] = {
351 .name = "Filesystem",
352 .offset = MTDPART_OFS_APPEND,
353 .size = MTDPART_SIZ_FULL,
354 .mask_flags = 0,
355 },
356};
357
358static struct s3c2410_nand_set rx1950_nand_sets[] = {
359 [0] = {
360 .name = "Internal",
361 .nr_chips = 1,
362 .nr_partitions = ARRAY_SIZE(rx1950_nand_part),
363 .partitions = rx1950_nand_part,
364 },
365};
366
367static struct s3c2410_platform_nand rx1950_nand_info = {
368 .tacls = 25,
369 .twrph0 = 50,
370 .twrph1 = 15,
371 .nr_sets = ARRAY_SIZE(rx1950_nand_sets),
372 .sets = rx1950_nand_sets,
373};
374
375static void rx1950_udc_pullup(enum s3c2410_udc_cmd_e cmd)
376{
377 switch (cmd) {
378 case S3C2410_UDC_P_ENABLE:
379 gpio_direction_output(S3C2410_GPJ(5), 1);
380 break;
381 case S3C2410_UDC_P_DISABLE:
382 gpio_direction_output(S3C2410_GPJ(5), 0);
383 break;
384 case S3C2410_UDC_P_RESET:
385 break;
386 default:
387 break;
388 }
389}
390
391static struct s3c2410_udc_mach_info rx1950_udc_cfg __initdata = {
392 .udc_command = rx1950_udc_pullup,
393 .vbus_pin = S3C2410_GPG(5),
394 .vbus_pin_inverted = 1,
395};
396
397static struct s3c2410_ts_mach_info rx1950_ts_cfg __initdata = {
398 .delay = 10000,
399 .presc = 49,
400 .oversampling_shift = 3,
401};
402
403static struct gpio_keys_button rx1950_gpio_keys_table[] = {
404 {
405 .code = KEY_POWER,
406 .gpio = S3C2410_GPF(0),
407 .active_low = 1,
408 .desc = "Power button",
409 .wakeup = 1,
410 },
411 {
412 .code = KEY_F5,
413 .gpio = S3C2410_GPF(7),
414 .active_low = 1,
415 .desc = "Record button",
416 },
417 {
418 .code = KEY_F1,
419 .gpio = S3C2410_GPG(0),
420 .active_low = 1,
421 .desc = "Calendar button",
422 },
423 {
424 .code = KEY_F2,
425 .gpio = S3C2410_GPG(2),
426 .active_low = 1,
427 .desc = "Contacts button",
428 },
429 {
430 .code = KEY_F3,
431 .gpio = S3C2410_GPG(3),
432 .active_low = 1,
433 .desc = "Mail button",
434 },
435 {
436 .code = KEY_F4,
437 .gpio = S3C2410_GPG(7),
438 .active_low = 1,
439 .desc = "WLAN button",
440 },
441 {
442 .code = KEY_LEFT,
443 .gpio = S3C2410_GPG(10),
444 .active_low = 1,
445 .desc = "Left button",
446 },
447 {
448 .code = KEY_RIGHT,
449 .gpio = S3C2410_GPG(11),
450 .active_low = 1,
451 .desc = "Right button",
452 },
453 {
454 .code = KEY_UP,
455 .gpio = S3C2410_GPG(4),
456 .active_low = 1,
457 .desc = "Up button",
458 },
459 {
460 .code = KEY_DOWN,
461 .gpio = S3C2410_GPG(6),
462 .active_low = 1,
463 .desc = "Down button",
464 },
465 {
466 .code = KEY_ENTER,
467 .gpio = S3C2410_GPG(9),
468 .active_low = 1,
469 .desc = "Ok button"
470 },
471};
472
473static struct gpio_keys_platform_data rx1950_gpio_keys_data = {
474 .buttons = rx1950_gpio_keys_table,
475 .nbuttons = ARRAY_SIZE(rx1950_gpio_keys_table),
476};
477
478static struct platform_device rx1950_device_gpiokeys = {
479 .name = "gpio-keys",
480 .dev.platform_data = &rx1950_gpio_keys_data,
481};
482
483static struct s3c2410_platform_i2c rx1950_i2c_data = {
484 .flags = 0,
485 .slave_addr = 0x42,
486 .frequency = 400 * 1000,
487 .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON,
488};
489
490static struct platform_device *rx1950_devices[] __initdata = {
491 &s3c_device_lcd,
492 &s3c_device_wdt,
493 &s3c_device_i2c0,
494 &s3c_device_iis,
495 &s3c_device_usbgadget,
496 &s3c_device_rtc,
497 &s3c_device_nand,
498 &s3c_device_sdi,
499 &s3c_device_adc,
500 &s3c_device_ts,
501 &s3c_device_timer[0],
502 &s3c_device_timer[1],
503 &rx1950_backlight,
504 &rx1950_device_gpiokeys,
505};
506
507static struct clk *rx1950_clocks[] __initdata = {
508 &s3c24xx_clkout0,
509 &s3c24xx_clkout1,
510};
511
512static void __init rx1950_map_io(void)
513{
514 s3c24xx_clkout0.parent = &clk_h;
515 s3c24xx_clkout1.parent = &clk_f;
516
517 s3c24xx_register_clocks(rx1950_clocks, ARRAY_SIZE(rx1950_clocks));
518
519 s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc));
520 s3c24xx_init_clocks(16934000);
521 s3c24xx_init_uarts(rx1950_uartcfgs, ARRAY_SIZE(rx1950_uartcfgs));
522
523 /* setup PM */
524
525#ifdef CONFIG_PM_H1940
526 memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 8);
527#endif
528
529 s3c_pm_init();
530}
531
532static void __init rx1950_init_machine(void)
533{
534 int i;
535
536 s3c24xx_fb_set_platdata(&rx1950_lcd_cfg);
537 s3c24xx_udc_set_platdata(&rx1950_udc_cfg);
538 s3c24xx_ts_set_platdata(&rx1950_ts_cfg);
539 s3c24xx_mci_set_platdata(&rx1950_mmc_cfg);
540 s3c_i2c0_set_platdata(&rx1950_i2c_data);
541 s3c_nand_set_platdata(&rx1950_nand_info);
542
543 /* Turn off suspend on both USB ports, and switch the
544 * selectable USB port to USB device mode. */
545 s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
546 S3C2410_MISCCR_USBSUSPND0 |
547 S3C2410_MISCCR_USBSUSPND1, 0x0);
548
549 WARN_ON(gpio_request(S3C2410_GPJ(5), "UDC pullup"));
550 gpio_direction_output(S3C2410_GPJ(5), 0);
551
552 /* mmc power is disabled by default */
553 WARN_ON(gpio_request(S3C2410_GPJ(1), "MMC power"));
554 gpio_direction_output(S3C2410_GPJ(1), 0);
555
556 for (i = 0; i < 8; i++)
557 WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power"));
558
559 for (i = 10; i < 16; i++)
560 WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power"));
561
562 for (i = 2; i < 8; i++)
563 WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power"));
564
565 for (i = 11; i < 16; i++)
566 WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power"));
567
568 WARN_ON(gpio_request(S3C2410_GPB(1), "LCD power"));
569
570 platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices));
571}
572
573MACHINE_START(RX1950, "HP iPAQ RX1950")
574 /* Maintainers: Vasily Khoruzhick */
575 .phys_io = S3C2410_PA_UART,
576 .io_pg_offst = (((u32) S3C24XX_VA_UART) >> 18) & 0xfffc,
577 .boot_params = S3C2410_SDRAM_PA + 0x100,
578 .map_io = rx1950_map_io,
579 .init_irq = s3c24xx_init_irq,
580 .init_machine = rx1950_init_machine,
581 .timer = &s3c24xx_timer,
582MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index 1e836e506f8b..d2946de3f365 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -209,7 +209,7 @@ static void __init rx3715_init_machine(void)
209} 209}
210 210
211MACHINE_START(RX3715, "IPAQ-RX3715") 211MACHINE_START(RX3715, "IPAQ-RX3715")
212 /* Maintainer: Ben Dooks <ben@fluff.org> */ 212 /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
213 .phys_io = S3C2410_PA_UART, 213 .phys_io = S3C2410_PA_UART,
214 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, 214 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
215 .boot_params = S3C2410_SDRAM_PA + 0x100, 215 .boot_params = S3C2410_SDRAM_PA + 0x100,
diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c
index 3ac3d636d615..df83276d85ae 100644
--- a/arch/arm/mach-s3c2440/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2440/mach-smdk2440.c
@@ -174,7 +174,7 @@ static void __init smdk2440_machine_init(void)
174} 174}
175 175
176MACHINE_START(S3C2440, "SMDK2440") 176MACHINE_START(S3C2440, "SMDK2440")
177 /* Maintainer: Ben Dooks <ben@fluff.org> */ 177 /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
178 .phys_io = S3C2410_PA_UART, 178 .phys_io = S3C2410_PA_UART,
179 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, 179 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
180 .boot_params = S3C2410_SDRAM_PA + 0x100, 180 .boot_params = S3C2410_SDRAM_PA + 0x100,
diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c
index 2b68f7ea45ae..d50f3ae6173d 100644
--- a/arch/arm/mach-s3c2440/s3c2440.c
+++ b/arch/arm/mach-s3c2440/s3c2440.c
@@ -19,6 +19,7 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/serial_core.h> 20#include <linux/serial_core.h>
21#include <linux/sysdev.h> 21#include <linux/sysdev.h>
22#include <linux/gpio.h>
22#include <linux/clk.h> 23#include <linux/clk.h>
23#include <linux/io.h> 24#include <linux/io.h>
24 25
@@ -33,6 +34,10 @@
33#include <plat/cpu.h> 34#include <plat/cpu.h>
34#include <plat/s3c244x.h> 35#include <plat/s3c244x.h>
35 36
37#include <plat/gpio-core.h>
38#include <plat/gpio-cfg.h>
39#include <plat/gpio-cfg-helpers.h>
40
36static struct sys_device s3c2440_sysdev = { 41static struct sys_device s3c2440_sysdev = {
37 .cls = &s3c2440_sysclass, 42 .cls = &s3c2440_sysclass,
38}; 43};
@@ -41,6 +46,9 @@ int __init s3c2440_init(void)
41{ 46{
42 printk("S3C2440: Initialising architecture\n"); 47 printk("S3C2440: Initialising architecture\n");
43 48
49 s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
50 s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
51
44 /* change irq for watchdog */ 52 /* change irq for watchdog */
45 53
46 s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT; 54 s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig
index 698140af247c..4fef723126fa 100644
--- a/arch/arm/mach-s3c2443/Kconfig
+++ b/arch/arm/mach-s3c2443/Kconfig
@@ -8,6 +8,7 @@ config CPU_S3C2443
8 select S3C2443_DMA if S3C2410_DMA 8 select S3C2443_DMA if S3C2410_DMA
9 select CPU_LLSERIAL_S3C2440 9 select CPU_LLSERIAL_S3C2440
10 select SAMSUNG_CLKSRC 10 select SAMSUNG_CLKSRC
11 select S3C2443_CLOCK
11 help 12 help
12 Support for the S3C2443 SoC from the S3C24XX line 13 Support for the S3C2443 SoC from the S3C24XX line
13 14
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index 62cd4eaee01b..83b1aa63d778 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -21,6 +21,7 @@
21*/ 21*/
22 22
23#include <linux/init.h> 23#include <linux/init.h>
24
24#include <linux/module.h> 25#include <linux/module.h>
25#include <linux/kernel.h> 26#include <linux/kernel.h>
26#include <linux/list.h> 27#include <linux/list.h>
@@ -54,111 +55,13 @@
54 * set the correct muxing at initialisation 55 * set the correct muxing at initialisation
55*/ 56*/
56 57
57static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
58{
59 u32 ctrlbit = clk->ctrlbit;
60 u32 con = __raw_readl(reg);
61
62 if (enable)
63 con |= ctrlbit;
64 else
65 con &= ~ctrlbit;
66
67 __raw_writel(con, reg);
68 return 0;
69}
70
71static int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
72{
73 return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
74}
75
76static int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
77{
78 return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
79}
80
81static int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
82{
83 return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
84}
85
86/* clock selections */ 58/* clock selections */
87 59
88/* mpllref is a direct descendant of clk_xtal by default, but it is not
89 * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
90 * such directly equating the two source clocks is impossible.
91 */
92static struct clk clk_mpllref = {
93 .name = "mpllref",
94 .parent = &clk_xtal,
95 .id = -1,
96};
97
98static struct clk clk_i2s_ext = { 60static struct clk clk_i2s_ext = {
99 .name = "i2s-ext", 61 .name = "i2s-ext",
100 .id = -1, 62 .id = -1,
101}; 63};
102 64
103static struct clk *clk_epllref_sources[] = {
104 [0] = &clk_mpllref,
105 [1] = &clk_mpllref,
106 [2] = &clk_xtal,
107 [3] = &clk_ext,
108};
109
110static struct clksrc_clk clk_epllref = {
111 .clk = {
112 .name = "epllref",
113 .id = -1,
114 },
115 .sources = &(struct clksrc_sources) {
116 .sources = clk_epllref_sources,
117 .nr_sources = ARRAY_SIZE(clk_epllref_sources),
118 },
119 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
120};
121
122static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
123{
124 unsigned long parent_rate = clk_get_rate(clk->parent);
125 unsigned long div = __raw_readl(S3C2443_CLKDIV0);
126
127 div &= S3C2443_CLKDIV0_EXTDIV_MASK;
128 div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1); /* x2 */
129
130 return parent_rate / (div + 1);
131}
132
133static struct clk clk_mdivclk = {
134 .name = "mdivclk",
135 .parent = &clk_mpllref,
136 .id = -1,
137 .ops = &(struct clk_ops) {
138 .get_rate = s3c2443_getrate_mdivclk,
139 },
140};
141
142static struct clk *clk_msysclk_sources[] = {
143 [0] = &clk_mpllref,
144 [1] = &clk_mpll,
145 [2] = &clk_mdivclk,
146 [3] = &clk_mpllref,
147};
148
149static struct clksrc_clk clk_msysclk = {
150 .clk = {
151 .name = "msysclk",
152 .parent = &clk_xtal,
153 .id = -1,
154 },
155 .sources = &(struct clksrc_sources) {
156 .sources = clk_msysclk_sources,
157 .nr_sources = ARRAY_SIZE(clk_msysclk_sources),
158 },
159 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
160};
161
162/* armdiv 65/* armdiv
163 * 66 *
164 * this clock is sourced from msysclk and can have a number of 67 * this clock is sourced from msysclk and can have a number of
@@ -266,44 +169,6 @@ static struct clksrc_clk clk_arm = {
266 .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 }, 169 .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
267}; 170};
268 171
269/* esysclk
270 *
271 * this is sourced from either the EPLL or the EPLLref clock
272*/
273
274static struct clk *clk_sysclk_sources[] = {
275 [0] = &clk_epllref.clk,
276 [1] = &clk_epll,
277};
278
279static struct clksrc_clk clk_esysclk = {
280 .clk = {
281 .name = "esysclk",
282 .parent = &clk_epll,
283 .id = -1,
284 },
285 .sources = &(struct clksrc_sources) {
286 .sources = clk_sysclk_sources,
287 .nr_sources = ARRAY_SIZE(clk_sysclk_sources),
288 },
289 .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
290};
291
292/* uartclk
293 *
294 * UART baud-rate clock sourced from esysclk via a divisor
295*/
296
297static struct clksrc_clk clk_uart = {
298 .clk = {
299 .name = "uartclk",
300 .id = -1,
301 .parent = &clk_esysclk.clk,
302 },
303 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
304};
305
306
307/* hsspi 172/* hsspi
308 * 173 *
309 * high-speed spi clock, sourced from esysclk 174 * high-speed spi clock, sourced from esysclk
@@ -320,21 +185,6 @@ static struct clksrc_clk clk_hsspi = {
320 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 }, 185 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
321}; 186};
322 187
323/* usbhost
324 *
325 * usb host bus-clock, usually 48MHz to provide USB bus clock timing
326*/
327
328static struct clksrc_clk clk_usb_bus_host = {
329 .clk = {
330 .name = "usb-bus-host-parent",
331 .id = -1,
332 .parent = &clk_esysclk.clk,
333 .ctrlbit = S3C2443_SCLKCON_USBHOST,
334 .enable = s3c2443_clkcon_enable_s,
335 },
336 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
337};
338 188
339/* clk_hsmcc_div 189/* clk_hsmcc_div
340 * 190 *
@@ -433,89 +283,16 @@ static struct clksrc_clk clk_i2s = {
433 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 }, 283 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
434}; 284};
435 285
436/* cam-if
437 *
438 * camera interface bus-clock, divided down from esysclk
439*/
440
441static struct clksrc_clk clk_cam = {
442 .clk = {
443 .name = "camif-upll", /* same as 2440 name */
444 .id = -1,
445 .parent = &clk_esysclk.clk,
446 .ctrlbit = S3C2443_SCLKCON_CAMCLK,
447 .enable = s3c2443_clkcon_enable_s,
448 },
449 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
450};
451
452/* display-if
453 *
454 * display interface clock, divided from esysclk
455*/
456
457static struct clksrc_clk clk_display = {
458 .clk = {
459 .name = "display-if",
460 .id = -1,
461 .parent = &clk_esysclk.clk,
462 .ctrlbit = S3C2443_SCLKCON_DISPCLK,
463 .enable = s3c2443_clkcon_enable_s,
464 },
465 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
466};
467
468/* prediv
469 *
470 * this divides the msysclk down to pass to h/p/etc.
471 */
472
473static unsigned long s3c2443_prediv_getrate(struct clk *clk)
474{
475 unsigned long rate = clk_get_rate(clk->parent);
476 unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
477
478 clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
479 clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
480
481 return rate / (clkdiv0 + 1);
482}
483
484static struct clk clk_prediv = {
485 .name = "prediv",
486 .id = -1,
487 .parent = &clk_msysclk.clk,
488 .ops = &(struct clk_ops) {
489 .get_rate = s3c2443_prediv_getrate,
490 },
491};
492
493/* standard clock definitions */ 286/* standard clock definitions */
494 287
495static struct clk init_clocks_disable[] = { 288static struct clk init_clocks_off[] = {
496 { 289 {
497 .name = "nand",
498 .id = -1,
499 .parent = &clk_h,
500 }, {
501 .name = "sdi", 290 .name = "sdi",
502 .id = -1, 291 .id = -1,
503 .parent = &clk_p, 292 .parent = &clk_p,
504 .enable = s3c2443_clkcon_enable_p, 293 .enable = s3c2443_clkcon_enable_p,
505 .ctrlbit = S3C2443_PCLKCON_SDI, 294 .ctrlbit = S3C2443_PCLKCON_SDI,
506 }, { 295 }, {
507 .name = "adc",
508 .id = -1,
509 .parent = &clk_p,
510 .enable = s3c2443_clkcon_enable_p,
511 .ctrlbit = S3C2443_PCLKCON_ADC,
512 }, {
513 .name = "i2c",
514 .id = -1,
515 .parent = &clk_p,
516 .enable = s3c2443_clkcon_enable_p,
517 .ctrlbit = S3C2443_PCLKCON_IIC,
518 }, {
519 .name = "iis", 296 .name = "iis",
520 .id = -1, 297 .id = -1,
521 .parent = &clk_p, 298 .parent = &clk_p,
@@ -537,179 +314,12 @@ static struct clk init_clocks_disable[] = {
537}; 314};
538 315
539static struct clk init_clocks[] = { 316static struct clk init_clocks[] = {
540 {
541 .name = "dma",
542 .id = 0,
543 .parent = &clk_h,
544 .enable = s3c2443_clkcon_enable_h,
545 .ctrlbit = S3C2443_HCLKCON_DMA0,
546 }, {
547 .name = "dma",
548 .id = 1,
549 .parent = &clk_h,
550 .enable = s3c2443_clkcon_enable_h,
551 .ctrlbit = S3C2443_HCLKCON_DMA1,
552 }, {
553 .name = "dma",
554 .id = 2,
555 .parent = &clk_h,
556 .enable = s3c2443_clkcon_enable_h,
557 .ctrlbit = S3C2443_HCLKCON_DMA2,
558 }, {
559 .name = "dma",
560 .id = 3,
561 .parent = &clk_h,
562 .enable = s3c2443_clkcon_enable_h,
563 .ctrlbit = S3C2443_HCLKCON_DMA3,
564 }, {
565 .name = "dma",
566 .id = 4,
567 .parent = &clk_h,
568 .enable = s3c2443_clkcon_enable_h,
569 .ctrlbit = S3C2443_HCLKCON_DMA4,
570 }, {
571 .name = "dma",
572 .id = 5,
573 .parent = &clk_h,
574 .enable = s3c2443_clkcon_enable_h,
575 .ctrlbit = S3C2443_HCLKCON_DMA5,
576 }, {
577 .name = "lcd",
578 .id = -1,
579 .parent = &clk_h,
580 .enable = s3c2443_clkcon_enable_h,
581 .ctrlbit = S3C2443_HCLKCON_LCDC,
582 }, {
583 .name = "gpio",
584 .id = -1,
585 .parent = &clk_p,
586 .enable = s3c2443_clkcon_enable_p,
587 .ctrlbit = S3C2443_PCLKCON_GPIO,
588 }, {
589 .name = "usb-host",
590 .id = -1,
591 .parent = &clk_h,
592 .enable = s3c2443_clkcon_enable_h,
593 .ctrlbit = S3C2443_HCLKCON_USBH,
594 }, {
595 .name = "usb-device",
596 .id = -1,
597 .parent = &clk_h,
598 .enable = s3c2443_clkcon_enable_h,
599 .ctrlbit = S3C2443_HCLKCON_USBD,
600 }, {
601 .name = "hsmmc",
602 .id = -1,
603 .parent = &clk_h,
604 .enable = s3c2443_clkcon_enable_h,
605 .ctrlbit = S3C2443_HCLKCON_HSMMC,
606 }, {
607 .name = "cfc",
608 .id = -1,
609 .parent = &clk_h,
610 .enable = s3c2443_clkcon_enable_h,
611 .ctrlbit = S3C2443_HCLKCON_CFC,
612 }, {
613 .name = "ssmc",
614 .id = -1,
615 .parent = &clk_h,
616 .enable = s3c2443_clkcon_enable_h,
617 .ctrlbit = S3C2443_HCLKCON_SSMC,
618 }, {
619 .name = "timers",
620 .id = -1,
621 .parent = &clk_p,
622 .enable = s3c2443_clkcon_enable_p,
623 .ctrlbit = S3C2443_PCLKCON_PWMT,
624 }, {
625 .name = "uart",
626 .id = 0,
627 .parent = &clk_p,
628 .enable = s3c2443_clkcon_enable_p,
629 .ctrlbit = S3C2443_PCLKCON_UART0,
630 }, {
631 .name = "uart",
632 .id = 1,
633 .parent = &clk_p,
634 .enable = s3c2443_clkcon_enable_p,
635 .ctrlbit = S3C2443_PCLKCON_UART1,
636 }, {
637 .name = "uart",
638 .id = 2,
639 .parent = &clk_p,
640 .enable = s3c2443_clkcon_enable_p,
641 .ctrlbit = S3C2443_PCLKCON_UART2,
642 }, {
643 .name = "uart",
644 .id = 3,
645 .parent = &clk_p,
646 .enable = s3c2443_clkcon_enable_p,
647 .ctrlbit = S3C2443_PCLKCON_UART3,
648 }, {
649 .name = "rtc",
650 .id = -1,
651 .parent = &clk_p,
652 .enable = s3c2443_clkcon_enable_p,
653 .ctrlbit = S3C2443_PCLKCON_RTC,
654 }, {
655 .name = "watchdog",
656 .id = -1,
657 .parent = &clk_p,
658 .ctrlbit = S3C2443_PCLKCON_WDT,
659 }, {
660 .name = "usb-bus-host",
661 .id = -1,
662 .parent = &clk_usb_bus_host.clk,
663 }, {
664 .name = "ac97",
665 .id = -1,
666 .parent = &clk_p,
667 .ctrlbit = S3C2443_PCLKCON_AC97,
668 }
669};
670
671/* clocks to add where we need to check their parentage */
672
673static struct clksrc_clk __initdata *init_list[] = {
674 &clk_epllref, /* should be first */
675 &clk_esysclk,
676 &clk_msysclk,
677 &clk_arm,
678 &clk_i2s_eplldiv,
679 &clk_i2s,
680 &clk_cam,
681 &clk_uart,
682 &clk_display,
683 &clk_hsmmc_div,
684 &clk_usb_bus_host,
685}; 317};
686 318
687static void __init s3c2443_clk_initparents(void)
688{
689 int ptr;
690
691 for (ptr = 0; ptr < ARRAY_SIZE(init_list); ptr++)
692 s3c_set_clksrc(init_list[ptr], true);
693}
694
695static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
696{
697 clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
698
699 return clkcon0 + 1;
700}
701
702/* clocks to add straight away */ 319/* clocks to add straight away */
703 320
704static struct clksrc_clk *clksrcs[] __initdata = { 321static struct clksrc_clk *clksrcs[] __initdata = {
705 &clk_usb_bus_host,
706 &clk_epllref,
707 &clk_esysclk,
708 &clk_msysclk,
709 &clk_arm, 322 &clk_arm,
710 &clk_uart,
711 &clk_display,
712 &clk_cam,
713 &clk_i2s_eplldiv, 323 &clk_i2s_eplldiv,
714 &clk_i2s, 324 &clk_i2s,
715 &clk_hsspi, 325 &clk_hsspi,
@@ -717,92 +327,32 @@ static struct clksrc_clk *clksrcs[] __initdata = {
717}; 327};
718 328
719static struct clk *clks[] __initdata = { 329static struct clk *clks[] __initdata = {
720 &clk_ext,
721 &clk_epll,
722 &clk_usb_bus,
723 &clk_mpllref,
724 &clk_hsmmc, 330 &clk_hsmmc,
725 &clk_armdiv, 331 &clk_armdiv,
726 &clk_prediv,
727}; 332};
728 333
729void __init_or_cpufreq s3c2443_setup_clocks(void) 334void __init_or_cpufreq s3c2443_setup_clocks(void)
730{ 335{
731 unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON); 336 s3c2443_common_setup_clocks(s3c2443_get_mpll, s3c2443_fclk_div);
732 unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
733 struct clk *xtal_clk;
734 unsigned long xtal;
735 unsigned long pll;
736 unsigned long fclk;
737 unsigned long hclk;
738 unsigned long pclk;
739
740 xtal_clk = clk_get(NULL, "xtal");
741 xtal = clk_get_rate(xtal_clk);
742 clk_put(xtal_clk);
743
744 pll = s3c2443_get_mpll(mpllcon, xtal);
745 clk_msysclk.clk.rate = pll;
746
747 fclk = pll / s3c2443_fclk_div(clkdiv0);
748 hclk = s3c2443_prediv_getrate(&clk_prediv);
749 hclk /= s3c2443_get_hdiv(clkdiv0);
750 pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
751
752 s3c24xx_setup_clocks(fclk, hclk, pclk);
753
754 printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
755 (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on",
756 print_mhz(pll), print_mhz(fclk),
757 print_mhz(hclk), print_mhz(pclk));
758
759 s3c24xx_setup_clocks(fclk, hclk, pclk);
760} 337}
761 338
762void __init s3c2443_init_clocks(int xtal) 339void __init s3c2443_init_clocks(int xtal)
763{ 340{
764 struct clk *clkp;
765 unsigned long epllcon = __raw_readl(S3C2443_EPLLCON); 341 unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
766 int ret;
767 int ptr; 342 int ptr;
768 343
769 /* s3c2443 parents h and p clocks from prediv */ 344 clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
770 clk_h.parent = &clk_prediv; 345 clk_epll.parent = &clk_epllref.clk;
771 clk_p.parent = &clk_prediv; 346
347 s3c2443_common_init_clocks(xtal, s3c2443_get_mpll, s3c2443_fclk_div);
772 348
773 s3c24xx_register_baseclocks(xtal);
774 s3c2443_setup_clocks(); 349 s3c2443_setup_clocks();
775 s3c2443_clk_initparents();
776
777 for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
778 clkp = clks[ptr];
779 350
780 ret = s3c24xx_register_clock(clkp); 351 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
781 if (ret < 0) {
782 printk(KERN_ERR "Failed to register clock %s (%d)\n",
783 clkp->name, ret);
784 }
785 }
786 352
787 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) 353 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
788 s3c_register_clksrc(clksrcs[ptr], 1); 354 s3c_register_clksrc(clksrcs[ptr], 1);
789 355
790 clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
791 clk_epll.parent = &clk_epllref.clk;
792 clk_usb_bus.parent = &clk_usb_bus_host.clk;
793
794 /* ensure usb bus clock is within correct rate of 48MHz */
795
796 if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
797 printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
798 clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
799 }
800
801 printk("S3C2443: epll %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
802 (epllcon & S3C2443_PLLCON_OFF) ? "off":"on",
803 print_mhz(clk_get_rate(&clk_epll)),
804 print_mhz(clk_get_rate(&clk_usb_bus)));
805
806 /* register clocks from clock array */ 356 /* register clocks from clock array */
807 357
808 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 358 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
@@ -819,17 +369,8 @@ void __init s3c2443_init_clocks(int xtal)
819 369
820 /* install (and disable) the clocks we do not need immediately */ 370 /* install (and disable) the clocks we do not need immediately */
821 371
822 clkp = init_clocks_disable; 372 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
823 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { 373 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
824
825 ret = s3c24xx_register_clock(clkp);
826 if (ret < 0) {
827 printk(KERN_ERR "Failed to register clock %s (%d)\n",
828 clkp->name, ret);
829 }
830
831 (clkp->enable)(clkp, 0);
832 }
833 374
834 s3c_pwmclk_init(); 375 s3c_pwmclk_init();
835} 376}
diff --git a/arch/arm/mach-s3c2443/mach-smdk2443.c b/arch/arm/mach-s3c2443/mach-smdk2443.c
index e2e362bda9b7..4c863d3a52f4 100644
--- a/arch/arm/mach-s3c2443/mach-smdk2443.c
+++ b/arch/arm/mach-s3c2443/mach-smdk2443.c
@@ -131,7 +131,7 @@ static void __init smdk2443_machine_init(void)
131} 131}
132 132
133MACHINE_START(SMDK2443, "SMDK2443") 133MACHINE_START(SMDK2443, "SMDK2443")
134 /* Maintainer: Ben Dooks <ben@fluff.org> */ 134 /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
135 .phys_io = S3C2410_PA_UART, 135 .phys_io = S3C2410_PA_UART,
136 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, 136 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
137 .boot_params = S3C2410_SDRAM_PA + 0x100, 137 .boot_params = S3C2410_SDRAM_PA + 0x100,
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
index 2ac2e7d73e53..7a4138beb665 100644
--- a/arch/arm/mach-s3c64xx/clock.c
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -88,6 +88,12 @@ struct clk clk_48m = {
88 .enable = clk_48m_ctrl, 88 .enable = clk_48m_ctrl,
89}; 89};
90 90
91struct clk clk_xusbxti = {
92 .name = "xusbxti",
93 .id = -1,
94 .rate = 48000000,
95};
96
91static int inline s3c64xx_gate(void __iomem *reg, 97static int inline s3c64xx_gate(void __iomem *reg,
92 struct clk *clk, 98 struct clk *clk,
93 int enable) 99 int enable)
@@ -518,6 +524,11 @@ static struct clk clk_iis_cd1 = {
518 .id = -1, 524 .id = -1,
519}; 525};
520 526
527static struct clk clk_iisv4_cd = {
528 .name = "iis_cdclk_v4",
529 .id = -1,
530};
531
521static struct clk clk_pcm_cd = { 532static struct clk clk_pcm_cd = {
522 .name = "pcm_cdclk", 533 .name = "pcm_cdclk",
523 .id = -1, 534 .id = -1,
@@ -549,6 +560,19 @@ static struct clksrc_sources clkset_audio1 = {
549 .nr_sources = ARRAY_SIZE(clkset_audio1_list), 560 .nr_sources = ARRAY_SIZE(clkset_audio1_list),
550}; 561};
551 562
563static struct clk *clkset_audio2_list[] = {
564 [0] = &clk_mout_epll.clk,
565 [1] = &clk_dout_mpll,
566 [2] = &clk_fin_epll,
567 [3] = &clk_iisv4_cd,
568 [4] = &clk_pcm_cd,
569};
570
571static struct clksrc_sources clkset_audio2 = {
572 .sources = clkset_audio2_list,
573 .nr_sources = ARRAY_SIZE(clkset_audio2_list),
574};
575
552static struct clk *clkset_camif_list[] = { 576static struct clk *clkset_camif_list[] = {
553 &clk_h2, 577 &clk_h2,
554}; 578};
@@ -652,6 +676,16 @@ static struct clksrc_clk clksrcs[] = {
652 .sources = &clkset_audio1, 676 .sources = &clkset_audio1,
653 }, { 677 }, {
654 .clk = { 678 .clk = {
679 .name = "audio-bus",
680 .id = -1, /* There's only one IISv4 port */
681 .ctrlbit = S3C6410_CLKCON_SCLK_AUDIO2,
682 .enable = s3c64xx_sclk_ctrl,
683 },
684 .reg_src = { .reg = S3C6410_CLK_SRC2, .shift = 0, .size = 3 },
685 .reg_div = { .reg = S3C_CLK_DIV2, .shift = 24, .size = 4 },
686 .sources = &clkset_audio2,
687 }, {
688 .clk = {
655 .name = "irda-bus", 689 .name = "irda-bus",
656 .id = 0, 690 .id = 0,
657 .ctrlbit = S3C_CLKCON_SCLK_IRDA, 691 .ctrlbit = S3C_CLKCON_SCLK_IRDA,
@@ -749,6 +783,7 @@ static struct clk *clks1[] __initdata = {
749 &clk_ext_xtal_mux, 783 &clk_ext_xtal_mux,
750 &clk_iis_cd0, 784 &clk_iis_cd0,
751 &clk_iis_cd1, 785 &clk_iis_cd1,
786 &clk_iisv4_cd,
752 &clk_pcm_cd, 787 &clk_pcm_cd,
753 &clk_mout_epll.clk, 788 &clk_mout_epll.clk,
754 &clk_mout_mpll.clk, 789 &clk_mout_mpll.clk,
@@ -762,6 +797,7 @@ static struct clk *clks[] __initdata = {
762 &clk_27m, 797 &clk_27m,
763 &clk_48m, 798 &clk_48m,
764 &clk_h2, 799 &clk_h2,
800 &clk_xusbxti,
765}; 801};
766 802
767/** 803/**
diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c
index 33ccf7bf766a..5567e037b0d1 100644
--- a/arch/arm/mach-s3c64xx/dma.c
+++ b/arch/arm/mach-s3c64xx/dma.c
@@ -414,7 +414,7 @@ err_buff:
414EXPORT_SYMBOL(s3c2410_dma_enqueue); 414EXPORT_SYMBOL(s3c2410_dma_enqueue);
415 415
416 416
417int s3c2410_dma_devconfig(int channel, 417int s3c2410_dma_devconfig(unsigned int channel,
418 enum s3c2410_dmasrc source, 418 enum s3c2410_dmasrc source,
419 unsigned long devaddr) 419 unsigned long devaddr)
420{ 420{
diff --git a/arch/arm/mach-s3c64xx/gpiolib.c b/arch/arm/mach-s3c64xx/gpiolib.c
index 66e6794481d2..60c929a3cab6 100644
--- a/arch/arm/mach-s3c64xx/gpiolib.c
+++ b/arch/arm/mach-s3c64xx/gpiolib.c
@@ -51,6 +51,7 @@
51 51
52static struct s3c_gpio_cfg gpio_4bit_cfg_noint = { 52static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
53 .set_config = s3c_gpio_setcfg_s3c64xx_4bit, 53 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
54 .get_config = s3c_gpio_getcfg_s3c64xx_4bit,
54 .set_pull = s3c_gpio_setpull_updown, 55 .set_pull = s3c_gpio_setpull_updown,
55 .get_pull = s3c_gpio_getpull_updown, 56 .get_pull = s3c_gpio_getpull_updown,
56}; 57};
@@ -58,12 +59,14 @@ static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
58static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = { 59static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
59 .cfg_eint = 7, 60 .cfg_eint = 7,
60 .set_config = s3c_gpio_setcfg_s3c64xx_4bit, 61 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
62 .get_config = s3c_gpio_getcfg_s3c64xx_4bit,
61 .set_pull = s3c_gpio_setpull_updown, 63 .set_pull = s3c_gpio_setpull_updown,
62 .get_pull = s3c_gpio_getpull_updown, 64 .get_pull = s3c_gpio_getpull_updown,
63}; 65};
64 66
65static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = { 67static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
66 .cfg_eint = 3, 68 .cfg_eint = 3,
69 .get_config = s3c_gpio_getcfg_s3c64xx_4bit,
67 .set_config = s3c_gpio_setcfg_s3c64xx_4bit, 70 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
68 .set_pull = s3c_gpio_setpull_updown, 71 .set_pull = s3c_gpio_setpull_updown,
69 .get_pull = s3c_gpio_getpull_updown, 72 .get_pull = s3c_gpio_getpull_updown,
@@ -171,6 +174,7 @@ static struct s3c_gpio_chip gpio_4bit2[] = {
171 174
172static struct s3c_gpio_cfg gpio_2bit_cfg_noint = { 175static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
173 .set_config = s3c_gpio_setcfg_s3c24xx, 176 .set_config = s3c_gpio_setcfg_s3c24xx,
177 .get_config = s3c_gpio_getcfg_s3c24xx,
174 .set_pull = s3c_gpio_setpull_updown, 178 .set_pull = s3c_gpio_setpull_updown,
175 .get_pull = s3c_gpio_getpull_updown, 179 .get_pull = s3c_gpio_getpull_updown,
176}; 180};
@@ -178,6 +182,7 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
178static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = { 182static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
179 .cfg_eint = 2, 183 .cfg_eint = 2,
180 .set_config = s3c_gpio_setcfg_s3c24xx, 184 .set_config = s3c_gpio_setcfg_s3c24xx,
185 .get_config = s3c_gpio_getcfg_s3c24xx,
181 .set_pull = s3c_gpio_setpull_updown, 186 .set_pull = s3c_gpio_setpull_updown,
182 .get_pull = s3c_gpio_getpull_updown, 187 .get_pull = s3c_gpio_getpull_updown,
183}; 188};
@@ -185,6 +190,7 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
185static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = { 190static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
186 .cfg_eint = 3, 191 .cfg_eint = 3,
187 .set_config = s3c_gpio_setcfg_s3c24xx, 192 .set_config = s3c_gpio_setcfg_s3c24xx,
193 .get_config = s3c_gpio_getcfg_s3c24xx,
188 .set_pull = s3c_gpio_setpull_updown, 194 .set_pull = s3c_gpio_setpull_updown,
189 .get_pull = s3c_gpio_getpull_updown, 195 .get_pull = s3c_gpio_getpull_updown,
190}; 196};
diff --git a/arch/arm/mach-s3c64xx/include/mach/pll.h b/arch/arm/mach-s3c64xx/include/mach/pll.h
index 90bbd72fdc4e..5ef0bb698ee0 100644
--- a/arch/arm/mach-s3c64xx/include/mach/pll.h
+++ b/arch/arm/mach-s3c64xx/include/mach/pll.h
@@ -20,6 +20,7 @@
20#define S3C6400_PLL_SDIV_SHIFT (0) 20#define S3C6400_PLL_SDIV_SHIFT (0)
21 21
22#include <asm/div64.h> 22#include <asm/div64.h>
23#include <plat/pll6553x.h>
23 24
24static inline unsigned long s3c6400_get_pll(unsigned long baseclk, 25static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
25 u32 pllcon) 26 u32 pllcon)
@@ -37,38 +38,8 @@ static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
37 return (unsigned long)fvco; 38 return (unsigned long)fvco;
38} 39}
39 40
40#define S3C6400_EPLL_MDIV_MASK ((1 << (23-16)) - 1)
41#define S3C6400_EPLL_PDIV_MASK ((1 << (13-8)) - 1)
42#define S3C6400_EPLL_SDIV_MASK ((1 << (2-0)) - 1)
43#define S3C6400_EPLL_MDIV_SHIFT (16)
44#define S3C6400_EPLL_PDIV_SHIFT (8)
45#define S3C6400_EPLL_SDIV_SHIFT (0)
46#define S3C6400_EPLL_KDIV_MASK (0xffff)
47
48static inline unsigned long s3c6400_get_epll(unsigned long baseclk) 41static inline unsigned long s3c6400_get_epll(unsigned long baseclk)
49{ 42{
50 unsigned long result; 43 return s3c_get_pll6553x(baseclk, __raw_readl(S3C_EPLL_CON0),
51 u32 epll0 = __raw_readl(S3C_EPLL_CON0); 44 __raw_readl(S3C_EPLL_CON1));
52 u32 epll1 = __raw_readl(S3C_EPLL_CON1);
53 u32 mdiv, pdiv, sdiv, kdiv;
54 u64 tmp;
55
56 mdiv = (epll0 >> S3C6400_EPLL_MDIV_SHIFT) & S3C6400_EPLL_MDIV_MASK;
57 pdiv = (epll0 >> S3C6400_EPLL_PDIV_SHIFT) & S3C6400_EPLL_PDIV_MASK;
58 sdiv = (epll0 >> S3C6400_EPLL_SDIV_SHIFT) & S3C6400_EPLL_SDIV_MASK;
59 kdiv = epll1 & S3C6400_EPLL_KDIV_MASK;
60
61 /* We need to multiple baseclk by mdiv (the integer part) and kdiv
62 * which is in 2^16ths, so shift mdiv up (does not overflow) and
63 * add kdiv before multiplying. The use of tmp is to avoid any
64 * overflows before shifting bac down into result when multipling
65 * by the mdiv and kdiv pair.
66 */
67
68 tmp = baseclk;
69 tmp *= (mdiv << 16) + kdiv;
70 do_div(tmp, (pdiv << sdiv));
71 result = tmp >> 16;
72
73 return result;
74} 45}
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
index 3ef62741e5d1..0114eb0c1fe7 100644
--- a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
@@ -33,6 +33,7 @@
33#define S3C_PCLK_GATE S3C_CLKREG(0x34) 33#define S3C_PCLK_GATE S3C_CLKREG(0x34)
34#define S3C_SCLK_GATE S3C_CLKREG(0x38) 34#define S3C_SCLK_GATE S3C_CLKREG(0x38)
35#define S3C_MEM0_GATE S3C_CLKREG(0x3C) 35#define S3C_MEM0_GATE S3C_CLKREG(0x3C)
36#define S3C6410_CLK_SRC2 S3C_CLKREG(0x10C)
36 37
37/* CLKDIV0 */ 38/* CLKDIV0 */
38#define S3C6400_CLKDIV0_PCLK_MASK (0xf << 12) 39#define S3C6400_CLKDIV0_PCLK_MASK (0xf << 12)
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6400.c b/arch/arm/mach-s3c64xx/mach-smdk6400.c
index f7b18983950c..59916676d8d2 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6400.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6400.c
@@ -84,7 +84,7 @@ static void __init smdk6400_machine_init(void)
84} 84}
85 85
86MACHINE_START(SMDK6400, "SMDK6400") 86MACHINE_START(SMDK6400, "SMDK6400")
87 /* Maintainer: Ben Dooks <ben@fluff.org> */ 87 /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
88 .phys_io = S3C_PA_UART & 0xfff00000, 88 .phys_io = S3C_PA_UART & 0xfff00000,
89 .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc, 89 .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
90 .boot_params = S3C64XX_PA_SDRAM + 0x100, 90 .boot_params = S3C64XX_PA_SDRAM + 0x100,
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index 2d5afd221d77..9d51455feb31 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -656,7 +656,7 @@ static void __init smdk6410_machine_init(void)
656} 656}
657 657
658MACHINE_START(SMDK6410, "SMDK6410") 658MACHINE_START(SMDK6410, "SMDK6410")
659 /* Maintainer: Ben Dooks <ben@fluff.org> */ 659 /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
660 .phys_io = S3C_PA_UART & 0xfff00000, 660 .phys_io = S3C_PA_UART & 0xfff00000,
661 .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc, 661 .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
662 .boot_params = S3C64XX_PA_SDRAM + 0x100, 662 .boot_params = S3C64XX_PA_SDRAM + 0x100,
diff --git a/arch/arm/mach-s5p6440/Kconfig b/arch/arm/mach-s5p6440/Kconfig
index 4c29ff8b07de..77aeffd17330 100644
--- a/arch/arm/mach-s5p6440/Kconfig
+++ b/arch/arm/mach-s5p6440/Kconfig
@@ -9,6 +9,7 @@ if ARCH_S5P6440
9 9
10config CPU_S5P6440 10config CPU_S5P6440
11 bool 11 bool
12 select S3C_PL330_DMA
12 help 13 help
13 Enable S5P6440 CPU support 14 Enable S5P6440 CPU support
14 15
diff --git a/arch/arm/mach-s5p6440/Makefile b/arch/arm/mach-s5p6440/Makefile
index a2e99a249767..5fd17d3da0cb 100644
--- a/arch/arm/mach-s5p6440/Makefile
+++ b/arch/arm/mach-s5p6440/Makefile
@@ -12,7 +12,7 @@ obj- :=
12 12
13# Core support for S5P6440 system 13# Core support for S5P6440 system
14 14
15obj-$(CONFIG_CPU_S5P6440) += cpu.o init.o clock.o gpio.o 15obj-$(CONFIG_CPU_S5P6440) += cpu.o init.o clock.o gpio.o dma.o
16 16
17# machine support 17# machine support
18 18
diff --git a/arch/arm/mach-s5p6440/clock.c b/arch/arm/mach-s5p6440/clock.c
index b2672e16e7aa..ca6e48dce777 100644
--- a/arch/arm/mach-s5p6440/clock.c
+++ b/arch/arm/mach-s5p6440/clock.c
@@ -134,24 +134,6 @@ static struct clksrc_clk clk_mout_mpll = {
134 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 1, .size = 1 }, 134 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 1, .size = 1 },
135}; 135};
136 136
137static struct clk clk_h_low = {
138 .name = "hclk_low",
139 .id = -1,
140 .rate = 0,
141 .parent = NULL,
142 .ctrlbit = 0,
143 .ops = &clk_ops_def_setrate,
144};
145
146static struct clk clk_p_low = {
147 .name = "pclk_low",
148 .id = -1,
149 .rate = 0,
150 .parent = NULL,
151 .ctrlbit = 0,
152 .ops = &clk_ops_def_setrate,
153};
154
155enum perf_level { 137enum perf_level {
156 L0 = 532*1000, 138 L0 = 532*1000,
157 L1 = 266*1000, 139 L1 = 266*1000,
@@ -247,23 +229,70 @@ static struct clk_ops s5p6440_clkarm_ops = {
247 .round_rate = s5p6440_armclk_round_rate, 229 .round_rate = s5p6440_armclk_round_rate,
248}; 230};
249 231
250static unsigned long s5p6440_clk_doutmpll_get_rate(struct clk *clk) 232static struct clksrc_clk clk_armclk = {
251{ 233 .clk = {
252 unsigned long rate = clk_get_rate(clk->parent); 234 .name = "armclk",
235 .id = 1,
236 .parent = &clk_mout_apll.clk,
237 .ops = &s5p6440_clkarm_ops,
238 },
239 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 4 },
240};
253 241
254 if (__raw_readl(S5P_CLK_DIV0) & S5P_CLKDIV0_MPLL_MASK) 242static struct clksrc_clk clk_dout_mpll = {
255 rate /= 2; 243 .clk = {
244 .name = "dout_mpll",
245 .id = -1,
246 .parent = &clk_mout_mpll.clk,
247 },
248 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 1 },
249};
256 250
257 return rate; 251static struct clksrc_clk clk_hclk = {
258} 252 .clk = {
253 .name = "clk_hclk",
254 .id = -1,
255 .parent = &clk_armclk.clk,
256 },
257 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 4 },
258};
259 259
260static struct clk clk_dout_mpll = { 260static struct clksrc_clk clk_pclk = {
261 .name = "dout_mpll", 261 .clk = {
262 .id = -1, 262 .name = "clk_pclk",
263 .parent = &clk_mout_mpll.clk, 263 .id = -1,
264 .ops = &(struct clk_ops) { 264 .parent = &clk_hclk.clk,
265 .get_rate = s5p6440_clk_doutmpll_get_rate,
266 }, 265 },
266 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 4 },
267};
268
269static struct clk *clkset_hclklow_list[] = {
270 &clk_mout_apll.clk,
271 &clk_mout_mpll.clk,
272};
273
274static struct clksrc_sources clkset_hclklow = {
275 .sources = clkset_hclklow_list,
276 .nr_sources = ARRAY_SIZE(clkset_hclklow_list),
277};
278
279static struct clksrc_clk clk_hclk_low = {
280 .clk = {
281 .name = "hclk_low",
282 .id = -1,
283 },
284 .sources = &clkset_hclklow,
285 .reg_src = { .reg = S5P_SYS_OTHERS, .shift = 6, .size = 1 },
286 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 },
287};
288
289static struct clksrc_clk clk_pclk_low = {
290 .clk = {
291 .name = "pclk_low",
292 .id = -1,
293 .parent = &clk_hclk_low.clk,
294 },
295 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 },
267}; 296};
268 297
269int s5p6440_clk48m_ctrl(struct clk *clk, int enable) 298int s5p6440_clk48m_ctrl(struct clk *clk, int enable)
@@ -307,6 +336,11 @@ static int s5p6440_sclk_ctrl(struct clk *clk, int enable)
307 return s5p_gatectrl(S5P_CLK_GATE_SCLK0, clk, enable); 336 return s5p_gatectrl(S5P_CLK_GATE_SCLK0, clk, enable);
308} 337}
309 338
339static int s5p6440_sclk1_ctrl(struct clk *clk, int enable)
340{
341 return s5p_gatectrl(S5P_CLK_GATE_SCLK1, clk, enable);
342}
343
310static int s5p6440_mem_ctrl(struct clk *clk, int enable) 344static int s5p6440_mem_ctrl(struct clk *clk, int enable)
311{ 345{
312 return s5p_gatectrl(S5P_CLK_GATE_MEM0, clk, enable); 346 return s5p_gatectrl(S5P_CLK_GATE_MEM0, clk, enable);
@@ -321,37 +355,37 @@ static struct clk init_clocks_disable[] = {
321 { 355 {
322 .name = "nand", 356 .name = "nand",
323 .id = -1, 357 .id = -1,
324 .parent = &clk_h, 358 .parent = &clk_hclk.clk,
325 .enable = s5p6440_mem_ctrl, 359 .enable = s5p6440_mem_ctrl,
326 .ctrlbit = S5P_CLKCON_MEM0_HCLK_NFCON, 360 .ctrlbit = S5P_CLKCON_MEM0_HCLK_NFCON,
327 }, { 361 }, {
328 .name = "adc", 362 .name = "adc",
329 .id = -1, 363 .id = -1,
330 .parent = &clk_p_low, 364 .parent = &clk_pclk_low.clk,
331 .enable = s5p6440_pclk_ctrl, 365 .enable = s5p6440_pclk_ctrl,
332 .ctrlbit = S5P_CLKCON_PCLK_TSADC, 366 .ctrlbit = S5P_CLKCON_PCLK_TSADC,
333 }, { 367 }, {
334 .name = "i2c", 368 .name = "i2c",
335 .id = -1, 369 .id = -1,
336 .parent = &clk_p_low, 370 .parent = &clk_pclk_low.clk,
337 .enable = s5p6440_pclk_ctrl, 371 .enable = s5p6440_pclk_ctrl,
338 .ctrlbit = S5P_CLKCON_PCLK_IIC0, 372 .ctrlbit = S5P_CLKCON_PCLK_IIC0,
339 }, { 373 }, {
340 .name = "i2s_v40", 374 .name = "i2s_v40",
341 .id = 0, 375 .id = 0,
342 .parent = &clk_p_low, 376 .parent = &clk_pclk_low.clk,
343 .enable = s5p6440_pclk_ctrl, 377 .enable = s5p6440_pclk_ctrl,
344 .ctrlbit = S5P_CLKCON_PCLK_IIS2, 378 .ctrlbit = S5P_CLKCON_PCLK_IIS2,
345 }, { 379 }, {
346 .name = "spi", 380 .name = "spi",
347 .id = 0, 381 .id = 0,
348 .parent = &clk_p_low, 382 .parent = &clk_pclk_low.clk,
349 .enable = s5p6440_pclk_ctrl, 383 .enable = s5p6440_pclk_ctrl,
350 .ctrlbit = S5P_CLKCON_PCLK_SPI0, 384 .ctrlbit = S5P_CLKCON_PCLK_SPI0,
351 }, { 385 }, {
352 .name = "spi", 386 .name = "spi",
353 .id = 1, 387 .id = 1,
354 .parent = &clk_p_low, 388 .parent = &clk_pclk_low.clk,
355 .enable = s5p6440_pclk_ctrl, 389 .enable = s5p6440_pclk_ctrl,
356 .ctrlbit = S5P_CLKCON_PCLK_SPI1, 390 .ctrlbit = S5P_CLKCON_PCLK_SPI1,
357 }, { 391 }, {
@@ -387,58 +421,124 @@ static struct clk init_clocks_disable[] = {
387 }, { 421 }, {
388 .name = "otg", 422 .name = "otg",
389 .id = -1, 423 .id = -1,
390 .parent = &clk_h_low, 424 .parent = &clk_hclk_low.clk,
391 .enable = s5p6440_hclk0_ctrl, 425 .enable = s5p6440_hclk0_ctrl,
392 .ctrlbit = S5P_CLKCON_HCLK0_USB 426 .ctrlbit = S5P_CLKCON_HCLK0_USB
393 }, { 427 }, {
394 .name = "post", 428 .name = "post",
395 .id = -1, 429 .id = -1,
396 .parent = &clk_h_low, 430 .parent = &clk_hclk_low.clk,
397 .enable = s5p6440_hclk0_ctrl, 431 .enable = s5p6440_hclk0_ctrl,
398 .ctrlbit = S5P_CLKCON_HCLK0_POST0 432 .ctrlbit = S5P_CLKCON_HCLK0_POST0
399 }, { 433 }, {
400 .name = "lcd", 434 .name = "lcd",
401 .id = -1, 435 .id = -1,
402 .parent = &clk_h_low, 436 .parent = &clk_hclk_low.clk,
403 .enable = s5p6440_hclk1_ctrl, 437 .enable = s5p6440_hclk1_ctrl,
404 .ctrlbit = S5P_CLKCON_HCLK1_DISPCON, 438 .ctrlbit = S5P_CLKCON_HCLK1_DISPCON,
405 }, { 439 }, {
406 .name = "hsmmc", 440 .name = "hsmmc",
407 .id = 0, 441 .id = 0,
408 .parent = &clk_h_low, 442 .parent = &clk_hclk_low.clk,
409 .enable = s5p6440_hclk0_ctrl, 443 .enable = s5p6440_hclk0_ctrl,
410 .ctrlbit = S5P_CLKCON_HCLK0_HSMMC0, 444 .ctrlbit = S5P_CLKCON_HCLK0_HSMMC0,
411 }, { 445 }, {
412 .name = "hsmmc", 446 .name = "hsmmc",
413 .id = 1, 447 .id = 1,
414 .parent = &clk_h_low, 448 .parent = &clk_hclk_low.clk,
415 .enable = s5p6440_hclk0_ctrl, 449 .enable = s5p6440_hclk0_ctrl,
416 .ctrlbit = S5P_CLKCON_HCLK0_HSMMC1, 450 .ctrlbit = S5P_CLKCON_HCLK0_HSMMC1,
417 }, { 451 }, {
418 .name = "hsmmc", 452 .name = "hsmmc",
419 .id = 2, 453 .id = 2,
420 .parent = &clk_h_low, 454 .parent = &clk_hclk_low.clk,
421 .enable = s5p6440_hclk0_ctrl, 455 .enable = s5p6440_hclk0_ctrl,
422 .ctrlbit = S5P_CLKCON_HCLK0_HSMMC2, 456 .ctrlbit = S5P_CLKCON_HCLK0_HSMMC2,
423 }, { 457 }, {
424 .name = "rtc", 458 .name = "rtc",
425 .id = -1, 459 .id = -1,
426 .parent = &clk_p_low, 460 .parent = &clk_pclk_low.clk,
427 .enable = s5p6440_pclk_ctrl, 461 .enable = s5p6440_pclk_ctrl,
428 .ctrlbit = S5P_CLKCON_PCLK_RTC, 462 .ctrlbit = S5P_CLKCON_PCLK_RTC,
429 }, { 463 }, {
430 .name = "watchdog", 464 .name = "watchdog",
431 .id = -1, 465 .id = -1,
432 .parent = &clk_p_low, 466 .parent = &clk_pclk_low.clk,
433 .enable = s5p6440_pclk_ctrl, 467 .enable = s5p6440_pclk_ctrl,
434 .ctrlbit = S5P_CLKCON_PCLK_WDT, 468 .ctrlbit = S5P_CLKCON_PCLK_WDT,
435 }, { 469 }, {
436 .name = "timers", 470 .name = "timers",
437 .id = -1, 471 .id = -1,
438 .parent = &clk_p_low, 472 .parent = &clk_pclk_low.clk,
439 .enable = s5p6440_pclk_ctrl, 473 .enable = s5p6440_pclk_ctrl,
440 .ctrlbit = S5P_CLKCON_PCLK_PWM, 474 .ctrlbit = S5P_CLKCON_PCLK_PWM,
441 } 475 }, {
476 .name = "hclk_fimgvg",
477 .id = -1,
478 .parent = &clk_hclk.clk,
479 .enable = s5p6440_hclk1_ctrl,
480 .ctrlbit = (1 << 2),
481 }, {
482 .name = "tsi",
483 .id = -1,
484 .parent = &clk_hclk_low.clk,
485 .enable = s5p6440_hclk1_ctrl,
486 .ctrlbit = (1 << 0),
487 }, {
488 .name = "pclk_fimgvg",
489 .id = -1,
490 .parent = &clk_pclk.clk,
491 .enable = s5p6440_pclk_ctrl,
492 .ctrlbit = (1 << 31),
493 }, {
494 .name = "dmc0",
495 .id = -1,
496 .parent = &clk_pclk.clk,
497 .enable = s5p6440_pclk_ctrl,
498 .ctrlbit = (1 << 30),
499 }, {
500 .name = "etm",
501 .id = -1,
502 .parent = &clk_pclk.clk,
503 .enable = s5p6440_pclk_ctrl,
504 .ctrlbit = (1 << 29),
505 }, {
506 .name = "dsim",
507 .id = -1,
508 .parent = &clk_pclk_low.clk,
509 .enable = s5p6440_pclk_ctrl,
510 .ctrlbit = (1 << 28),
511 }, {
512 .name = "gps",
513 .id = -1,
514 .parent = &clk_pclk_low.clk,
515 .enable = s5p6440_pclk_ctrl,
516 .ctrlbit = (1 << 25),
517 }, {
518 .name = "pcm",
519 .id = -1,
520 .parent = &clk_pclk_low.clk,
521 .enable = s5p6440_pclk_ctrl,
522 .ctrlbit = (1 << 8),
523 }, {
524 .name = "irom",
525 .id = -1,
526 .parent = &clk_hclk.clk,
527 .enable = s5p6440_hclk0_ctrl,
528 .ctrlbit = (1 << 25),
529 }, {
530 .name = "dma",
531 .id = -1,
532 .parent = &clk_hclk_low.clk,
533 .enable = s5p6440_hclk0_ctrl,
534 .ctrlbit = (1 << 12),
535 }, {
536 .name = "2d",
537 .id = -1,
538 .parent = &clk_hclk.clk,
539 .enable = s5p6440_hclk0_ctrl,
540 .ctrlbit = (1 << 8),
541 },
442}; 542};
443 543
444/* 544/*
@@ -448,34 +548,46 @@ static struct clk init_clocks[] = {
448 { 548 {
449 .name = "gpio", 549 .name = "gpio",
450 .id = -1, 550 .id = -1,
451 .parent = &clk_p_low, 551 .parent = &clk_pclk_low.clk,
452 .enable = s5p6440_pclk_ctrl, 552 .enable = s5p6440_pclk_ctrl,
453 .ctrlbit = S5P_CLKCON_PCLK_GPIO, 553 .ctrlbit = S5P_CLKCON_PCLK_GPIO,
454 }, { 554 }, {
455 .name = "uart", 555 .name = "uart",
456 .id = 0, 556 .id = 0,
457 .parent = &clk_p_low, 557 .parent = &clk_pclk_low.clk,
458 .enable = s5p6440_pclk_ctrl, 558 .enable = s5p6440_pclk_ctrl,
459 .ctrlbit = S5P_CLKCON_PCLK_UART0, 559 .ctrlbit = S5P_CLKCON_PCLK_UART0,
460 }, { 560 }, {
461 .name = "uart", 561 .name = "uart",
462 .id = 1, 562 .id = 1,
463 .parent = &clk_p_low, 563 .parent = &clk_pclk_low.clk,
464 .enable = s5p6440_pclk_ctrl, 564 .enable = s5p6440_pclk_ctrl,
465 .ctrlbit = S5P_CLKCON_PCLK_UART1, 565 .ctrlbit = S5P_CLKCON_PCLK_UART1,
466 }, { 566 }, {
467 .name = "uart", 567 .name = "uart",
468 .id = 2, 568 .id = 2,
469 .parent = &clk_p_low, 569 .parent = &clk_pclk_low.clk,
470 .enable = s5p6440_pclk_ctrl, 570 .enable = s5p6440_pclk_ctrl,
471 .ctrlbit = S5P_CLKCON_PCLK_UART2, 571 .ctrlbit = S5P_CLKCON_PCLK_UART2,
472 }, { 572 }, {
473 .name = "uart", 573 .name = "uart",
474 .id = 3, 574 .id = 3,
475 .parent = &clk_p_low, 575 .parent = &clk_pclk_low.clk,
476 .enable = s5p6440_pclk_ctrl, 576 .enable = s5p6440_pclk_ctrl,
477 .ctrlbit = S5P_CLKCON_PCLK_UART3, 577 .ctrlbit = S5P_CLKCON_PCLK_UART3,
478 } 578 }, {
579 .name = "mem",
580 .id = -1,
581 .parent = &clk_hclk.clk,
582 .enable = s5p6440_hclk0_ctrl,
583 .ctrlbit = (1 << 21),
584 }, {
585 .name = "intc",
586 .id = -1,
587 .parent = &clk_hclk.clk,
588 .enable = s5p6440_hclk0_ctrl,
589 .ctrlbit = (1 << 1),
590 },
479}; 591};
480 592
481static struct clk clk_iis_cd_v40 = { 593static struct clk clk_iis_cd_v40 = {
@@ -488,20 +600,20 @@ static struct clk clk_pcm_cd = {
488 .id = -1, 600 .id = -1,
489}; 601};
490 602
491static struct clk *clkset_spi_mmc_list[] = { 603static struct clk *clkset_group1_list[] = {
492 &clk_mout_epll.clk, 604 &clk_mout_epll.clk,
493 &clk_dout_mpll, 605 &clk_dout_mpll.clk,
494 &clk_fin_epll, 606 &clk_fin_epll,
495}; 607};
496 608
497static struct clksrc_sources clkset_spi_mmc = { 609static struct clksrc_sources clkset_group1 = {
498 .sources = clkset_spi_mmc_list, 610 .sources = clkset_group1_list,
499 .nr_sources = ARRAY_SIZE(clkset_spi_mmc_list), 611 .nr_sources = ARRAY_SIZE(clkset_group1_list),
500}; 612};
501 613
502static struct clk *clkset_uart_list[] = { 614static struct clk *clkset_uart_list[] = {
503 &clk_mout_epll.clk, 615 &clk_mout_epll.clk,
504 &clk_dout_mpll 616 &clk_dout_mpll.clk,
505}; 617};
506 618
507static struct clksrc_sources clkset_uart = { 619static struct clksrc_sources clkset_uart = {
@@ -509,6 +621,19 @@ static struct clksrc_sources clkset_uart = {
509 .nr_sources = ARRAY_SIZE(clkset_uart_list), 621 .nr_sources = ARRAY_SIZE(clkset_uart_list),
510}; 622};
511 623
624static struct clk *clkset_audio_list[] = {
625 &clk_mout_epll.clk,
626 &clk_dout_mpll.clk,
627 &clk_fin_epll,
628 &clk_iis_cd_v40,
629 &clk_pcm_cd,
630};
631
632static struct clksrc_sources clkset_audio = {
633 .sources = clkset_audio_list,
634 .nr_sources = ARRAY_SIZE(clkset_audio_list),
635};
636
512static struct clksrc_clk clksrcs[] = { 637static struct clksrc_clk clksrcs[] = {
513 { 638 {
514 .clk = { 639 .clk = {
@@ -517,7 +642,7 @@ static struct clksrc_clk clksrcs[] = {
517 .ctrlbit = S5P_CLKCON_SCLK0_MMC0, 642 .ctrlbit = S5P_CLKCON_SCLK0_MMC0,
518 .enable = s5p6440_sclk_ctrl, 643 .enable = s5p6440_sclk_ctrl,
519 }, 644 },
520 .sources = &clkset_spi_mmc, 645 .sources = &clkset_group1,
521 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 18, .size = 2 }, 646 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 18, .size = 2 },
522 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4 }, 647 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4 },
523 }, { 648 }, {
@@ -527,7 +652,7 @@ static struct clksrc_clk clksrcs[] = {
527 .ctrlbit = S5P_CLKCON_SCLK0_MMC1, 652 .ctrlbit = S5P_CLKCON_SCLK0_MMC1,
528 .enable = s5p6440_sclk_ctrl, 653 .enable = s5p6440_sclk_ctrl,
529 }, 654 },
530 .sources = &clkset_spi_mmc, 655 .sources = &clkset_group1,
531 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 2 }, 656 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 2 },
532 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 4, .size = 4 }, 657 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 4, .size = 4 },
533 }, { 658 }, {
@@ -537,7 +662,7 @@ static struct clksrc_clk clksrcs[] = {
537 .ctrlbit = S5P_CLKCON_SCLK0_MMC2, 662 .ctrlbit = S5P_CLKCON_SCLK0_MMC2,
538 .enable = s5p6440_sclk_ctrl, 663 .enable = s5p6440_sclk_ctrl,
539 }, 664 },
540 .sources = &clkset_spi_mmc, 665 .sources = &clkset_group1,
541 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 22, .size = 2 }, 666 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 22, .size = 2 },
542 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 8, .size = 4 }, 667 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 8, .size = 4 },
543 }, { 668 }, {
@@ -557,7 +682,7 @@ static struct clksrc_clk clksrcs[] = {
557 .ctrlbit = S5P_CLKCON_SCLK0_SPI0, 682 .ctrlbit = S5P_CLKCON_SCLK0_SPI0,
558 .enable = s5p6440_sclk_ctrl, 683 .enable = s5p6440_sclk_ctrl,
559 }, 684 },
560 .sources = &clkset_spi_mmc, 685 .sources = &clkset_group1,
561 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 14, .size = 2 }, 686 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 14, .size = 2 },
562 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 }, 687 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
563 }, { 688 }, {
@@ -567,17 +692,63 @@ static struct clksrc_clk clksrcs[] = {
567 .ctrlbit = S5P_CLKCON_SCLK0_SPI1, 692 .ctrlbit = S5P_CLKCON_SCLK0_SPI1,
568 .enable = s5p6440_sclk_ctrl, 693 .enable = s5p6440_sclk_ctrl,
569 }, 694 },
570 .sources = &clkset_spi_mmc, 695 .sources = &clkset_group1,
571 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 2 }, 696 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 2 },
572 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 }, 697 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
573 } 698 }, {
699 .clk = {
700 .name = "sclk_post",
701 .id = -1,
702 .ctrlbit = (1 << 10),
703 .enable = s5p6440_sclk_ctrl,
704 },
705 .sources = &clkset_group1,
706 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 26, .size = 2 },
707 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 },
708 }, {
709 .clk = {
710 .name = "sclk_dispcon",
711 .id = -1,
712 .ctrlbit = (1 << 1),
713 .enable = s5p6440_sclk1_ctrl,
714 },
715 .sources = &clkset_group1,
716 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 2 },
717 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 0, .size = 4 },
718 }, {
719 .clk = {
720 .name = "sclk_fimgvg",
721 .id = -1,
722 .ctrlbit = (1 << 2),
723 .enable = s5p6440_sclk1_ctrl,
724 },
725 .sources = &clkset_group1,
726 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 2 },
727 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 4, .size = 4 },
728 }, {
729 .clk = {
730 .name = "sclk_audio2",
731 .id = -1,
732 .ctrlbit = (1 << 11),
733 .enable = s5p6440_sclk_ctrl,
734 },
735 .sources = &clkset_audio,
736 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 3 },
737 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 24, .size = 4 },
738 },
574}; 739};
575 740
576/* Clock initialisation code */ 741/* Clock initialisation code */
577static struct clksrc_clk *init_parents[] = { 742static struct clksrc_clk *sysclks[] = {
578 &clk_mout_apll, 743 &clk_mout_apll,
579 &clk_mout_epll, 744 &clk_mout_epll,
580 &clk_mout_mpll, 745 &clk_mout_mpll,
746 &clk_dout_mpll,
747 &clk_armclk,
748 &clk_hclk,
749 &clk_pclk,
750 &clk_hclk_low,
751 &clk_pclk_low,
581}; 752};
582 753
583void __init_or_cpufreq s5p6440_setup_clocks(void) 754void __init_or_cpufreq s5p6440_setup_clocks(void)
@@ -593,21 +764,13 @@ void __init_or_cpufreq s5p6440_setup_clocks(void)
593 unsigned long apll; 764 unsigned long apll;
594 unsigned long mpll; 765 unsigned long mpll;
595 unsigned int ptr; 766 unsigned int ptr;
596 u32 clkdiv0;
597 u32 clkdiv3;
598 767
599 /* Set S5P6440 functions for clk_fout_epll */ 768 /* Set S5P6440 functions for clk_fout_epll */
600 clk_fout_epll.enable = s5p6440_epll_enable; 769 clk_fout_epll.enable = s5p6440_epll_enable;
601 clk_fout_epll.ops = &s5p6440_epll_ops; 770 clk_fout_epll.ops = &s5p6440_epll_ops;
602 771
603 /* Set S5P6440 functions for arm clock */
604 clk_arm.parent = &clk_mout_apll.clk;
605 clk_arm.ops = &s5p6440_clkarm_ops;
606 clk_48m.enable = s5p6440_clk48m_ctrl; 772 clk_48m.enable = s5p6440_clk48m_ctrl;
607 773
608 clkdiv0 = __raw_readl(S5P_CLK_DIV0);
609 clkdiv3 = __raw_readl(S5P_CLK_DIV3);
610
611 xtal_clk = clk_get(NULL, "ext_xtal"); 774 xtal_clk = clk_get(NULL, "ext_xtal");
612 BUG_ON(IS_ERR(xtal_clk)); 775 BUG_ON(IS_ERR(xtal_clk));
613 776
@@ -619,41 +782,28 @@ void __init_or_cpufreq s5p6440_setup_clocks(void)
619 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502); 782 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
620 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4502); 783 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4502);
621 784
785 clk_fout_mpll.rate = mpll;
786 clk_fout_epll.rate = epll;
787 clk_fout_apll.rate = apll;
788
622 printk(KERN_INFO "S5P6440: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \ 789 printk(KERN_INFO "S5P6440: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \
623 " E=%ld.%ldMHz\n", 790 " E=%ld.%ldMHz\n",
624 print_mhz(apll), print_mhz(mpll), print_mhz(epll)); 791 print_mhz(apll), print_mhz(mpll), print_mhz(epll));
625 792
626 fclk = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_ARM); 793 fclk = clk_get_rate(&clk_armclk.clk);
627 hclk = fclk / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK); 794 hclk = clk_get_rate(&clk_hclk.clk);
628 pclk = hclk / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK); 795 pclk = clk_get_rate(&clk_pclk.clk);
629 796 hclk_low = clk_get_rate(&clk_hclk_low.clk);
630 if (__raw_readl(S5P_OTHERS) & S5P_OTHERS_HCLK_LOW_SEL_MPLL) { 797 pclk_low = clk_get_rate(&clk_pclk_low.clk);
631 /* Asynchronous mode */
632 hclk_low = mpll / GET_DIV(clkdiv3, S5P_CLKDIV3_HCLK_LOW);
633 } else {
634 /* Synchronous mode */
635 hclk_low = apll / GET_DIV(clkdiv3, S5P_CLKDIV3_HCLK_LOW);
636 }
637
638 pclk_low = hclk_low / GET_DIV(clkdiv3, S5P_CLKDIV3_PCLK_LOW);
639 798
640 printk(KERN_INFO "S5P6440: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \ 799 printk(KERN_INFO "S5P6440: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \
641 " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n", 800 " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n",
642 print_mhz(hclk), print_mhz(hclk_low), 801 print_mhz(hclk), print_mhz(hclk_low),
643 print_mhz(pclk), print_mhz(pclk_low)); 802 print_mhz(pclk), print_mhz(pclk_low));
644 803
645 clk_fout_mpll.rate = mpll;
646 clk_fout_epll.rate = epll;
647 clk_fout_apll.rate = apll;
648
649 clk_f.rate = fclk; 804 clk_f.rate = fclk;
650 clk_h.rate = hclk; 805 clk_h.rate = hclk;
651 clk_p.rate = pclk; 806 clk_p.rate = pclk;
652 clk_h_low.rate = hclk_low;
653 clk_p_low.rate = pclk_low;
654
655 for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
656 s3c_set_clksrc(init_parents[ptr], true);
657 807
658 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) 808 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
659 s3c_set_clksrc(&clksrcs[ptr], true); 809 s3c_set_clksrc(&clksrcs[ptr], true);
@@ -661,13 +811,8 @@ void __init_or_cpufreq s5p6440_setup_clocks(void)
661 811
662static struct clk *clks[] __initdata = { 812static struct clk *clks[] __initdata = {
663 &clk_ext, 813 &clk_ext,
664 &clk_mout_epll.clk,
665 &clk_mout_mpll.clk,
666 &clk_dout_mpll,
667 &clk_iis_cd_v40, 814 &clk_iis_cd_v40,
668 &clk_pcm_cd, 815 &clk_pcm_cd,
669 &clk_p_low,
670 &clk_h_low,
671}; 816};
672 817
673void __init s5p6440_register_clocks(void) 818void __init s5p6440_register_clocks(void)
@@ -680,6 +825,9 @@ void __init s5p6440_register_clocks(void)
680 if (ret > 0) 825 if (ret > 0)
681 printk(KERN_ERR "Failed to register %u clocks\n", ret); 826 printk(KERN_ERR "Failed to register %u clocks\n", ret);
682 827
828 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
829 s3c_register_clksrc(sysclks[ptr], 1);
830
683 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 831 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
684 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 832 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
685 833
diff --git a/arch/arm/mach-s5p6440/cpu.c b/arch/arm/mach-s5p6440/cpu.c
index 1794131aeacb..ca3b3206e6f8 100644
--- a/arch/arm/mach-s5p6440/cpu.c
+++ b/arch/arm/mach-s5p6440/cpu.c
@@ -88,7 +88,7 @@ void __init s5p6440_init_irq(void)
88 s5p_init_irq(vic, ARRAY_SIZE(vic)); 88 s5p_init_irq(vic, ARRAY_SIZE(vic));
89} 89}
90 90
91static struct sysdev_class s5p6440_sysclass = { 91struct sysdev_class s5p6440_sysclass = {
92 .name = "s5p6440-core", 92 .name = "s5p6440-core",
93}; 93};
94 94
diff --git a/arch/arm/mach-s5p6440/dma.c b/arch/arm/mach-s5p6440/dma.c
new file mode 100644
index 000000000000..07606ad57519
--- /dev/null
+++ b/arch/arm/mach-s5p6440/dma.c
@@ -0,0 +1,105 @@
1/*
2 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
3 * Jaswinder Singh <jassi.brar@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/platform_device.h>
21#include <linux/dma-mapping.h>
22
23#include <plat/devs.h>
24#include <plat/irqs.h>
25
26#include <mach/map.h>
27#include <mach/irqs.h>
28
29#include <plat/s3c-pl330-pdata.h>
30
31static u64 dma_dmamask = DMA_BIT_MASK(32);
32
33static struct resource s5p6440_pdma_resource[] = {
34 [0] = {
35 .start = S5P6440_PA_PDMA,
36 .end = S5P6440_PA_PDMA + SZ_4K,
37 .flags = IORESOURCE_MEM,
38 },
39 [1] = {
40 .start = IRQ_DMA0,
41 .end = IRQ_DMA0,
42 .flags = IORESOURCE_IRQ,
43 },
44};
45
46static struct s3c_pl330_platdata s5p6440_pdma_pdata = {
47 .peri = {
48 [0] = DMACH_UART0_RX,
49 [1] = DMACH_UART0_TX,
50 [2] = DMACH_UART1_RX,
51 [3] = DMACH_UART1_TX,
52 [4] = DMACH_UART2_RX,
53 [5] = DMACH_UART2_TX,
54 [6] = DMACH_UART3_RX,
55 [7] = DMACH_UART3_TX,
56 [8] = DMACH_MAX,
57 [9] = DMACH_MAX,
58 [10] = DMACH_PCM0_TX,
59 [11] = DMACH_PCM0_RX,
60 [12] = DMACH_I2S0_TX,
61 [13] = DMACH_I2S0_RX,
62 [14] = DMACH_SPI0_TX,
63 [15] = DMACH_SPI0_RX,
64 [16] = DMACH_MAX,
65 [17] = DMACH_MAX,
66 [18] = DMACH_MAX,
67 [19] = DMACH_MAX,
68 [20] = DMACH_SPI1_TX,
69 [21] = DMACH_SPI1_RX,
70 [22] = DMACH_MAX,
71 [23] = DMACH_MAX,
72 [24] = DMACH_MAX,
73 [25] = DMACH_MAX,
74 [26] = DMACH_MAX,
75 [27] = DMACH_MAX,
76 [28] = DMACH_MAX,
77 [29] = DMACH_PWM,
78 [30] = DMACH_MAX,
79 [31] = DMACH_MAX,
80 },
81};
82
83static struct platform_device s5p6440_device_pdma = {
84 .name = "s3c-pl330",
85 .id = 1,
86 .num_resources = ARRAY_SIZE(s5p6440_pdma_resource),
87 .resource = s5p6440_pdma_resource,
88 .dev = {
89 .dma_mask = &dma_dmamask,
90 .coherent_dma_mask = DMA_BIT_MASK(32),
91 .platform_data = &s5p6440_pdma_pdata,
92 },
93};
94
95static struct platform_device *s5p6440_dmacs[] __initdata = {
96 &s5p6440_device_pdma,
97};
98
99static int __init s5p6440_dma_init(void)
100{
101 platform_add_devices(s5p6440_dmacs, ARRAY_SIZE(s5p6440_dmacs));
102
103 return 0;
104}
105arch_initcall(s5p6440_dma_init);
diff --git a/arch/arm/mach-s5p6440/gpio.c b/arch/arm/mach-s5p6440/gpio.c
index b0ea741177ad..262dc75d5bea 100644
--- a/arch/arm/mach-s5p6440/gpio.c
+++ b/arch/arm/mach-s5p6440/gpio.c
@@ -161,12 +161,15 @@ static struct s3c_gpio_cfg s5p6440_gpio_cfgs[] = {
161 }, { 161 }, {
162 .cfg_eint = 0, 162 .cfg_eint = 0,
163 .set_config = s3c_gpio_setcfg_s3c24xx, 163 .set_config = s3c_gpio_setcfg_s3c24xx,
164 .get_config = s3c_gpio_getcfg_s3c24xx,
164 }, { 165 }, {
165 .cfg_eint = 2, 166 .cfg_eint = 2,
166 .set_config = s3c_gpio_setcfg_s3c24xx, 167 .set_config = s3c_gpio_setcfg_s3c24xx,
168 .get_config = s3c_gpio_getcfg_s3c24xx,
167 }, { 169 }, {
168 .cfg_eint = 3, 170 .cfg_eint = 3,
169 .set_config = s3c_gpio_setcfg_s3c24xx, 171 .set_config = s3c_gpio_setcfg_s3c24xx,
172 .get_config = s3c_gpio_getcfg_s3c24xx,
170 }, 173 },
171}; 174};
172 175
@@ -279,6 +282,8 @@ void __init s5p6440_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips)
279 for (; nr_chips > 0; nr_chips--, chipcfg++) { 282 for (; nr_chips > 0; nr_chips--, chipcfg++) {
280 if (!chipcfg->set_config) 283 if (!chipcfg->set_config)
281 chipcfg->set_config = s3c_gpio_setcfg_s3c64xx_4bit; 284 chipcfg->set_config = s3c_gpio_setcfg_s3c64xx_4bit;
285 if (!chipcfg->get_config)
286 chipcfg->get_config = s3c_gpio_getcfg_s3c64xx_4bit;
282 if (!chipcfg->set_pull) 287 if (!chipcfg->set_pull)
283 chipcfg->set_pull = s3c_gpio_setpull_updown; 288 chipcfg->set_pull = s3c_gpio_setpull_updown;
284 if (!chipcfg->get_pull) 289 if (!chipcfg->get_pull)
diff --git a/arch/arm/mach-s5p6440/include/mach/dma.h b/arch/arm/mach-s5p6440/include/mach/dma.h
new file mode 100644
index 000000000000..81209eb1409b
--- /dev/null
+++ b/arch/arm/mach-s5p6440/include/mach/dma.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
3 * Jaswinder Singh <jassi.brar@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#ifndef __MACH_DMA_H
21#define __MACH_DMA_H
22
23/* This platform uses the common S3C DMA API driver for PL330 */
24#include <plat/s3c-dma-pl330.h>
25
26#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-s5p6440/include/mach/map.h b/arch/arm/mach-s5p6440/include/mach/map.h
index ccbfdaea6eb6..72aedadd412c 100644
--- a/arch/arm/mach-s5p6440/include/mach/map.h
+++ b/arch/arm/mach-s5p6440/include/mach/map.h
@@ -29,6 +29,8 @@
29#define S5P6440_PA_VIC0 (0xE4000000) 29#define S5P6440_PA_VIC0 (0xE4000000)
30#define S5P_PA_VIC0 S5P6440_PA_VIC0 30#define S5P_PA_VIC0 S5P6440_PA_VIC0
31 31
32#define S5P6440_PA_PDMA 0xE9000000
33
32#define S5P6440_PA_VIC1 (0xE4100000) 34#define S5P6440_PA_VIC1 (0xE4100000)
33#define S5P_PA_VIC1 S5P6440_PA_VIC1 35#define S5P_PA_VIC1 S5P6440_PA_VIC1
34 36
diff --git a/arch/arm/mach-s5p6440/include/mach/pwm-clock.h b/arch/arm/mach-s5p6440/include/mach/pwm-clock.h
index c4bb7c555477..6a2a02fdf12a 100644
--- a/arch/arm/mach-s5p6440/include/mach/pwm-clock.h
+++ b/arch/arm/mach-s5p6440/include/mach/pwm-clock.h
@@ -1,11 +1,14 @@
1/* linux/arch/arm/mach-s5p6440/include/mach/pwm-clock.h 1/* linux/arch/arm/mach-s5p6440/include/mach/pwm-clock.h
2 * 2 *
3 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Copyright 2008 Openmoko, Inc.
3 * Copyright 2008 Simtec Electronics 7 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 8 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/ 9 * http://armlinux.simtec.co.uk/
6 * 10 *
7 * Copyright 2009 Samsung Electronics Co., Ltd. 11 * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
8 * http://www.samsung.com/
9 * 12 *
10 * S5P6440 - pwm clock and timer support 13 * S5P6440 - pwm clock and timer support
11 * 14 *
@@ -14,16 +17,19 @@
14 * published by the Free Software Foundation. 17 * published by the Free Software Foundation.
15*/ 18*/
16 19
20#ifndef __ASM_ARCH_PWMCLK_H
21#define __ASM_ARCH_PWMCLK_H __FILE__
22
17/** 23/**
18 * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk 24 * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
19 * @cfg: The timer TCFG1 register bits shifted down to 0. 25 * @tcfg: The timer TCFG1 register bits shifted down to 0.
20 * 26 *
21 * Return true if the given configuration from TCFG1 is a TCLK instead 27 * Return true if the given configuration from TCFG1 is a TCLK instead
22 * any of the TDIV clocks. 28 * any of the TDIV clocks.
23 */ 29 */
24static inline int pwm_cfg_src_is_tclk(unsigned long tcfg) 30static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
25{ 31{
26 return tcfg == S3C2410_TCFG1_MUX_TCLK; 32 return 0;
27} 33}
28 34
29/** 35/**
@@ -35,7 +41,7 @@ static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
35 */ 41 */
36static inline unsigned long tcfg_to_divisor(unsigned long tcfg1) 42static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
37{ 43{
38 return 1 << (1 + tcfg1); 44 return 1 << tcfg1;
39} 45}
40 46
41/** 47/**
@@ -45,7 +51,7 @@ static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
45 */ 51 */
46static inline unsigned int pwm_tdiv_has_div1(void) 52static inline unsigned int pwm_tdiv_has_div1(void)
47{ 53{
48 return 0; 54 return 1;
49} 55}
50 56
51/** 57/**
@@ -56,7 +62,9 @@ static inline unsigned int pwm_tdiv_has_div1(void)
56 */ 62 */
57static inline unsigned long pwm_tdiv_div_bits(unsigned int div) 63static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
58{ 64{
59 return ilog2(div) - 1; 65 return ilog2(div);
60} 66}
61 67
62#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK 68#define S3C_TCFG1_MUX_TCLK 0
69
70#endif /* __ASM_ARCH_PWMCLK_H */
diff --git a/arch/arm/mach-s5p6442/Kconfig b/arch/arm/mach-s5p6442/Kconfig
index 4f3f6de6a013..0fd41b447915 100644
--- a/arch/arm/mach-s5p6442/Kconfig
+++ b/arch/arm/mach-s5p6442/Kconfig
@@ -12,6 +12,7 @@ if ARCH_S5P6442
12config CPU_S5P6442 12config CPU_S5P6442
13 bool 13 bool
14 select PLAT_S5P 14 select PLAT_S5P
15 select S3C_PL330_DMA
15 help 16 help
16 Enable S5P6442 CPU support 17 Enable S5P6442 CPU support
17 18
diff --git a/arch/arm/mach-s5p6442/Makefile b/arch/arm/mach-s5p6442/Makefile
index a43d5da5c583..bf30550349cf 100644
--- a/arch/arm/mach-s5p6442/Makefile
+++ b/arch/arm/mach-s5p6442/Makefile
@@ -12,7 +12,7 @@ obj- :=
12 12
13# Core support for S5P6442 system 13# Core support for S5P6442 system
14 14
15obj-$(CONFIG_CPU_S5P6442) += cpu.o init.o clock.o 15obj-$(CONFIG_CPU_S5P6442) += cpu.o init.o clock.o dma.o
16 16
17# machine support 17# machine support
18 18
diff --git a/arch/arm/mach-s5p6442/cpu.c b/arch/arm/mach-s5p6442/cpu.c
index bc2524df89b3..a48fb553fd01 100644
--- a/arch/arm/mach-s5p6442/cpu.c
+++ b/arch/arm/mach-s5p6442/cpu.c
@@ -95,7 +95,7 @@ void __init s5p6442_init_irq(void)
95 s5p_init_irq(vic, ARRAY_SIZE(vic)); 95 s5p_init_irq(vic, ARRAY_SIZE(vic));
96} 96}
97 97
98static struct sysdev_class s5p6442_sysclass = { 98struct sysdev_class s5p6442_sysclass = {
99 .name = "s5p6442-core", 99 .name = "s5p6442-core",
100}; 100};
101 101
diff --git a/arch/arm/mach-s5p6442/dma.c b/arch/arm/mach-s5p6442/dma.c
new file mode 100644
index 000000000000..ad4f8704b93d
--- /dev/null
+++ b/arch/arm/mach-s5p6442/dma.c
@@ -0,0 +1,105 @@
1/*
2 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
3 * Jaswinder Singh <jassi.brar@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/platform_device.h>
21#include <linux/dma-mapping.h>
22
23#include <plat/devs.h>
24#include <plat/irqs.h>
25
26#include <mach/map.h>
27#include <mach/irqs.h>
28
29#include <plat/s3c-pl330-pdata.h>
30
31static u64 dma_dmamask = DMA_BIT_MASK(32);
32
33static struct resource s5p6442_pdma_resource[] = {
34 [0] = {
35 .start = S5P6442_PA_PDMA,
36 .end = S5P6442_PA_PDMA + SZ_4K,
37 .flags = IORESOURCE_MEM,
38 },
39 [1] = {
40 .start = IRQ_PDMA,
41 .end = IRQ_PDMA,
42 .flags = IORESOURCE_IRQ,
43 },
44};
45
46static struct s3c_pl330_platdata s5p6442_pdma_pdata = {
47 .peri = {
48 [0] = DMACH_UART0_RX,
49 [1] = DMACH_UART0_TX,
50 [2] = DMACH_UART1_RX,
51 [3] = DMACH_UART1_TX,
52 [4] = DMACH_UART2_RX,
53 [5] = DMACH_UART2_TX,
54 [6] = DMACH_MAX,
55 [7] = DMACH_MAX,
56 [8] = DMACH_MAX,
57 [9] = DMACH_I2S0_RX,
58 [10] = DMACH_I2S0_TX,
59 [11] = DMACH_I2S0S_TX,
60 [12] = DMACH_I2S1_RX,
61 [13] = DMACH_I2S1_TX,
62 [14] = DMACH_MAX,
63 [15] = DMACH_MAX,
64 [16] = DMACH_SPI0_RX,
65 [17] = DMACH_SPI0_TX,
66 [18] = DMACH_MAX,
67 [19] = DMACH_MAX,
68 [20] = DMACH_PCM0_RX,
69 [21] = DMACH_PCM0_TX,
70 [22] = DMACH_PCM1_RX,
71 [23] = DMACH_PCM1_TX,
72 [24] = DMACH_MAX,
73 [25] = DMACH_MAX,
74 [26] = DMACH_MAX,
75 [27] = DMACH_MSM_REQ0,
76 [28] = DMACH_MSM_REQ1,
77 [29] = DMACH_MSM_REQ2,
78 [30] = DMACH_MSM_REQ3,
79 [31] = DMACH_MAX,
80 },
81};
82
83static struct platform_device s5p6442_device_pdma = {
84 .name = "s3c-pl330",
85 .id = 1,
86 .num_resources = ARRAY_SIZE(s5p6442_pdma_resource),
87 .resource = s5p6442_pdma_resource,
88 .dev = {
89 .dma_mask = &dma_dmamask,
90 .coherent_dma_mask = DMA_BIT_MASK(32),
91 .platform_data = &s5p6442_pdma_pdata,
92 },
93};
94
95static struct platform_device *s5p6442_dmacs[] __initdata = {
96 &s5p6442_device_pdma,
97};
98
99static int __init s5p6442_dma_init(void)
100{
101 platform_add_devices(s5p6442_dmacs, ARRAY_SIZE(s5p6442_dmacs));
102
103 return 0;
104}
105arch_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
index 000000000000..81209eb1409b
--- /dev/null
+++ b/arch/arm/mach-s5p6442/include/mach/dma.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
3 * Jaswinder Singh <jassi.brar@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#ifndef __MACH_DMA_H
21#define __MACH_DMA_H
22
23/* This platform uses the common S3C DMA API driver for PL330 */
24#include <plat/s3c-dma-pl330.h>
25
26#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-s5p6442/include/mach/map.h b/arch/arm/mach-s5p6442/include/mach/map.h
index 767c596143c4..7568dc0d6be0 100644
--- a/arch/arm/mach-s5p6442/include/mach/map.h
+++ b/arch/arm/mach-s5p6442/include/mach/map.h
@@ -34,6 +34,9 @@
34#define S5P6442_PA_VIC2 (0xE4200000) 34#define S5P6442_PA_VIC2 (0xE4200000)
35#define S5P_PA_VIC2 S5P6442_PA_VIC2 35#define S5P_PA_VIC2 S5P6442_PA_VIC2
36 36
37#define S5P6442_PA_MDMA 0xE8000000
38#define S5P6442_PA_PDMA 0xE9000000
39
37#define S5P6442_PA_TIMER (0xEA000000) 40#define S5P6442_PA_TIMER (0xEA000000)
38#define S5P_PA_TIMER S5P6442_PA_TIMER 41#define S5P_PA_TIMER S5P6442_PA_TIMER
39 42
diff --git a/arch/arm/mach-s5p6442/include/mach/pwm-clock.h b/arch/arm/mach-s5p6442/include/mach/pwm-clock.h
index 15e8525da0f1..2724b37def31 100644
--- a/arch/arm/mach-s5p6442/include/mach/pwm-clock.h
+++ b/arch/arm/mach-s5p6442/include/mach/pwm-clock.h
@@ -1,13 +1,14 @@
1/* linux/arch/arm/mach-s5p6442/include/mach/pwm-clock.h 1/* linux/arch/arm/mach-s5p6442/include/mach/pwm-clock.h
2 * 2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Copyright 2008 Openmoko, Inc.
3 * Copyright 2008 Simtec Electronics 7 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 8 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/ 9 * http://armlinux.simtec.co.uk/
6 * 10 *
7 * Copyright 2010 Samsung Electronics Co., Ltd. 11 * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
8 * http://www.samsung.com/
9 *
10 * Based on arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
11 * 12 *
12 * S5P6442 - pwm clock and timer support 13 * S5P6442 - pwm clock and timer support
13 * 14 *
@@ -21,14 +22,14 @@
21 22
22/** 23/**
23 * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk 24 * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
24 * @cfg: The timer TCFG1 register bits shifted down to 0. 25 * @tcfg: The timer TCFG1 register bits shifted down to 0.
25 * 26 *
26 * Return true if the given configuration from TCFG1 is a TCLK instead 27 * Return true if the given configuration from TCFG1 is a TCLK instead
27 * any of the TDIV clocks. 28 * any of the TDIV clocks.
28 */ 29 */
29static inline int pwm_cfg_src_is_tclk(unsigned long tcfg) 30static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
30{ 31{
31 return tcfg == S3C2410_TCFG1_MUX_TCLK; 32 return tcfg == S3C64XX_TCFG1_MUX_TCLK;
32} 33}
33 34
34/** 35/**
@@ -40,7 +41,7 @@ static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
40 */ 41 */
41static inline unsigned long tcfg_to_divisor(unsigned long tcfg1) 42static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
42{ 43{
43 return 1 << (1 + tcfg1); 44 return 1 << tcfg1;
44} 45}
45 46
46/** 47/**
@@ -50,7 +51,7 @@ static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
50 */ 51 */
51static inline unsigned int pwm_tdiv_has_div1(void) 52static inline unsigned int pwm_tdiv_has_div1(void)
52{ 53{
53 return 0; 54 return 1;
54} 55}
55 56
56/** 57/**
@@ -61,9 +62,9 @@ static inline unsigned int pwm_tdiv_has_div1(void)
61 */ 62 */
62static inline unsigned long pwm_tdiv_div_bits(unsigned int div) 63static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
63{ 64{
64 return ilog2(div) - 1; 65 return ilog2(div);
65} 66}
66 67
67#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK 68#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
68 69
69#endif /* __ASM_ARCH_PWMCLK_H */ 70#endif /* __ASM_ARCH_PWMCLK_H */
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index af33a1a89b72..7601c28e240b 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -12,6 +12,7 @@ if ARCH_S5PV210
12config CPU_S5PV210 12config CPU_S5PV210
13 bool 13 bool
14 select PLAT_S5P 14 select PLAT_S5P
15 select S3C_PL330_DMA
15 help 16 help
16 Enable S5PV210 CPU support 17 Enable S5PV210 CPU support
17 18
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index e435afe7cffe..1d60b358589b 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -12,7 +12,7 @@ obj- :=
12 12
13# Core support for S5PV210 system 13# Core support for S5PV210 system
14 14
15obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o 15obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o gpiolib.o
16 16
17# machine support 17# machine support
18 18
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index ccccae262351..154bca4abc09 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -31,6 +31,128 @@
31#include <plat/clock-clksrc.h> 31#include <plat/clock-clksrc.h>
32#include <plat/s5pv210.h> 32#include <plat/s5pv210.h>
33 33
34static struct clksrc_clk clk_mout_apll = {
35 .clk = {
36 .name = "mout_apll",
37 .id = -1,
38 },
39 .sources = &clk_src_apll,
40 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
41};
42
43static struct clksrc_clk clk_mout_epll = {
44 .clk = {
45 .name = "mout_epll",
46 .id = -1,
47 },
48 .sources = &clk_src_epll,
49 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
50};
51
52static struct clksrc_clk clk_mout_mpll = {
53 .clk = {
54 .name = "mout_mpll",
55 .id = -1,
56 },
57 .sources = &clk_src_mpll,
58 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 },
59};
60
61static struct clk *clkset_armclk_list[] = {
62 [0] = &clk_mout_apll.clk,
63 [1] = &clk_mout_mpll.clk,
64};
65
66static struct clksrc_sources clkset_armclk = {
67 .sources = clkset_armclk_list,
68 .nr_sources = ARRAY_SIZE(clkset_armclk_list),
69};
70
71static struct clksrc_clk clk_armclk = {
72 .clk = {
73 .name = "armclk",
74 .id = -1,
75 },
76 .sources = &clkset_armclk,
77 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 1 },
78 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 3 },
79};
80
81static struct clksrc_clk clk_hclk_msys = {
82 .clk = {
83 .name = "hclk_msys",
84 .id = -1,
85 .parent = &clk_armclk.clk,
86 },
87 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 3 },
88};
89
90static struct clksrc_clk clk_pclk_msys = {
91 .clk = {
92 .name = "pclk_msys",
93 .id = -1,
94 .parent = &clk_hclk_msys.clk,
95 },
96 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 3 },
97};
98
99static struct clksrc_clk clk_sclk_a2m = {
100 .clk = {
101 .name = "sclk_a2m",
102 .id = -1,
103 .parent = &clk_mout_apll.clk,
104 },
105 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 },
106};
107
108static struct clk *clkset_hclk_sys_list[] = {
109 [0] = &clk_mout_mpll.clk,
110 [1] = &clk_sclk_a2m.clk,
111};
112
113static struct clksrc_sources clkset_hclk_sys = {
114 .sources = clkset_hclk_sys_list,
115 .nr_sources = ARRAY_SIZE(clkset_hclk_sys_list),
116};
117
118static struct clksrc_clk clk_hclk_dsys = {
119 .clk = {
120 .name = "hclk_dsys",
121 .id = -1,
122 },
123 .sources = &clkset_hclk_sys,
124 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 1 },
125 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 4 },
126};
127
128static struct clksrc_clk clk_pclk_dsys = {
129 .clk = {
130 .name = "pclk_dsys",
131 .id = -1,
132 .parent = &clk_hclk_dsys.clk,
133 },
134 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 20, .size = 3 },
135};
136
137static struct clksrc_clk clk_hclk_psys = {
138 .clk = {
139 .name = "hclk_psys",
140 .id = -1,
141 },
142 .sources = &clkset_hclk_sys,
143 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 24, .size = 1 },
144 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 24, .size = 4 },
145};
146
147static struct clksrc_clk clk_pclk_psys = {
148 .clk = {
149 .name = "pclk_psys",
150 .id = -1,
151 .parent = &clk_hclk_psys.clk,
152 },
153 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 28, .size = 3 },
154};
155
34static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable) 156static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable)
35{ 157{
36 return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable); 158 return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable);
@@ -51,176 +173,226 @@ static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable)
51 return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable); 173 return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
52} 174}
53 175
54static struct clk clk_h200 = { 176static int s5pv210_clk_ip4_ctrl(struct clk *clk, int enable)
55 .name = "hclk200", 177{
178 return s5p_gatectrl(S5P_CLKGATE_IP4, clk, enable);
179}
180
181static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable)
182{
183 return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable);
184}
185
186static struct clk clk_sclk_hdmi27m = {
187 .name = "sclk_hdmi27m",
56 .id = -1, 188 .id = -1,
189 .rate = 27000000,
57}; 190};
58 191
59static struct clk clk_h100 = { 192static struct clk clk_sclk_hdmiphy = {
60 .name = "hclk100", 193 .name = "sclk_hdmiphy",
61 .id = -1, 194 .id = -1,
62}; 195};
63 196
64static struct clk clk_h166 = { 197static struct clk clk_sclk_usbphy0 = {
65 .name = "hclk166", 198 .name = "sclk_usbphy0",
66 .id = -1, 199 .id = -1,
67}; 200};
68 201
69static struct clk clk_h133 = { 202static struct clk clk_sclk_usbphy1 = {
70 .name = "hclk133", 203 .name = "sclk_usbphy1",
71 .id = -1, 204 .id = -1,
72}; 205};
73 206
74static struct clk clk_p100 = { 207static struct clk clk_pcmcdclk0 = {
75 .name = "pclk100", 208 .name = "pcmcdclk",
76 .id = -1, 209 .id = -1,
77}; 210};
78 211
79static struct clk clk_p83 = { 212static struct clk clk_pcmcdclk1 = {
80 .name = "pclk83", 213 .name = "pcmcdclk",
81 .id = -1, 214 .id = -1,
82}; 215};
83 216
84static struct clk clk_p66 = { 217static struct clk clk_pcmcdclk2 = {
85 .name = "pclk66", 218 .name = "pcmcdclk",
86 .id = -1, 219 .id = -1,
87}; 220};
88 221
89static struct clk *sys_clks[] = { 222static struct clk *clkset_vpllsrc_list[] = {
90 &clk_h200, 223 [0] = &clk_fin_vpll,
91 &clk_h100, 224 [1] = &clk_sclk_hdmi27m,
92 &clk_h166, 225};
93 &clk_h133, 226
94 &clk_p100, 227static struct clksrc_sources clkset_vpllsrc = {
95 &clk_p83, 228 .sources = clkset_vpllsrc_list,
96 &clk_p66 229 .nr_sources = ARRAY_SIZE(clkset_vpllsrc_list),
230};
231
232static struct clksrc_clk clk_vpllsrc = {
233 .clk = {
234 .name = "vpll_src",
235 .id = -1,
236 .enable = s5pv210_clk_mask0_ctrl,
237 .ctrlbit = (1 << 7),
238 },
239 .sources = &clkset_vpllsrc,
240 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 28, .size = 1 },
241};
242
243static struct clk *clkset_sclk_vpll_list[] = {
244 [0] = &clk_vpllsrc.clk,
245 [1] = &clk_fout_vpll,
246};
247
248static struct clksrc_sources clkset_sclk_vpll = {
249 .sources = clkset_sclk_vpll_list,
250 .nr_sources = ARRAY_SIZE(clkset_sclk_vpll_list),
251};
252
253static struct clksrc_clk clk_sclk_vpll = {
254 .clk = {
255 .name = "sclk_vpll",
256 .id = -1,
257 },
258 .sources = &clkset_sclk_vpll,
259 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 },
260};
261
262static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk)
263{
264 return clk_get_rate(clk->parent) / 2;
265}
266
267static struct clk_ops clk_hclk_imem_ops = {
268 .get_rate = s5pv210_clk_imem_get_rate,
97}; 269};
98 270
99static struct clk init_clocks_disable[] = { 271static struct clk init_clocks_disable[] = {
100 { 272 {
101 .name = "rot", 273 .name = "rot",
102 .id = -1, 274 .id = -1,
103 .parent = &clk_h166, 275 .parent = &clk_hclk_dsys.clk,
104 .enable = s5pv210_clk_ip0_ctrl, 276 .enable = s5pv210_clk_ip0_ctrl,
105 .ctrlbit = (1<<29), 277 .ctrlbit = (1<<29),
106 }, { 278 }, {
107 .name = "otg", 279 .name = "otg",
108 .id = -1, 280 .id = -1,
109 .parent = &clk_h133, 281 .parent = &clk_hclk_psys.clk,
110 .enable = s5pv210_clk_ip1_ctrl, 282 .enable = s5pv210_clk_ip1_ctrl,
111 .ctrlbit = (1<<16), 283 .ctrlbit = (1<<16),
112 }, { 284 }, {
113 .name = "usb-host", 285 .name = "usb-host",
114 .id = -1, 286 .id = -1,
115 .parent = &clk_h133, 287 .parent = &clk_hclk_psys.clk,
116 .enable = s5pv210_clk_ip1_ctrl, 288 .enable = s5pv210_clk_ip1_ctrl,
117 .ctrlbit = (1<<17), 289 .ctrlbit = (1<<17),
118 }, { 290 }, {
119 .name = "lcd", 291 .name = "lcd",
120 .id = -1, 292 .id = -1,
121 .parent = &clk_h166, 293 .parent = &clk_hclk_dsys.clk,
122 .enable = s5pv210_clk_ip1_ctrl, 294 .enable = s5pv210_clk_ip1_ctrl,
123 .ctrlbit = (1<<0), 295 .ctrlbit = (1<<0),
124 }, { 296 }, {
125 .name = "cfcon", 297 .name = "cfcon",
126 .id = 0, 298 .id = 0,
127 .parent = &clk_h133, 299 .parent = &clk_hclk_psys.clk,
128 .enable = s5pv210_clk_ip1_ctrl, 300 .enable = s5pv210_clk_ip1_ctrl,
129 .ctrlbit = (1<<25), 301 .ctrlbit = (1<<25),
130 }, { 302 }, {
131 .name = "hsmmc", 303 .name = "hsmmc",
132 .id = 0, 304 .id = 0,
133 .parent = &clk_h133, 305 .parent = &clk_hclk_psys.clk,
134 .enable = s5pv210_clk_ip2_ctrl, 306 .enable = s5pv210_clk_ip2_ctrl,
135 .ctrlbit = (1<<16), 307 .ctrlbit = (1<<16),
136 }, { 308 }, {
137 .name = "hsmmc", 309 .name = "hsmmc",
138 .id = 1, 310 .id = 1,
139 .parent = &clk_h133, 311 .parent = &clk_hclk_psys.clk,
140 .enable = s5pv210_clk_ip2_ctrl, 312 .enable = s5pv210_clk_ip2_ctrl,
141 .ctrlbit = (1<<17), 313 .ctrlbit = (1<<17),
142 }, { 314 }, {
143 .name = "hsmmc", 315 .name = "hsmmc",
144 .id = 2, 316 .id = 2,
145 .parent = &clk_h133, 317 .parent = &clk_hclk_psys.clk,
146 .enable = s5pv210_clk_ip2_ctrl, 318 .enable = s5pv210_clk_ip2_ctrl,
147 .ctrlbit = (1<<18), 319 .ctrlbit = (1<<18),
148 }, { 320 }, {
149 .name = "hsmmc", 321 .name = "hsmmc",
150 .id = 3, 322 .id = 3,
151 .parent = &clk_h133, 323 .parent = &clk_hclk_psys.clk,
152 .enable = s5pv210_clk_ip2_ctrl, 324 .enable = s5pv210_clk_ip2_ctrl,
153 .ctrlbit = (1<<19), 325 .ctrlbit = (1<<19),
154 }, { 326 }, {
155 .name = "systimer", 327 .name = "systimer",
156 .id = -1, 328 .id = -1,
157 .parent = &clk_p66, 329 .parent = &clk_pclk_psys.clk,
158 .enable = s5pv210_clk_ip3_ctrl, 330 .enable = s5pv210_clk_ip3_ctrl,
159 .ctrlbit = (1<<16), 331 .ctrlbit = (1<<16),
160 }, { 332 }, {
161 .name = "watchdog", 333 .name = "watchdog",
162 .id = -1, 334 .id = -1,
163 .parent = &clk_p66, 335 .parent = &clk_pclk_psys.clk,
164 .enable = s5pv210_clk_ip3_ctrl, 336 .enable = s5pv210_clk_ip3_ctrl,
165 .ctrlbit = (1<<22), 337 .ctrlbit = (1<<22),
166 }, { 338 }, {
167 .name = "rtc", 339 .name = "rtc",
168 .id = -1, 340 .id = -1,
169 .parent = &clk_p66, 341 .parent = &clk_pclk_psys.clk,
170 .enable = s5pv210_clk_ip3_ctrl, 342 .enable = s5pv210_clk_ip3_ctrl,
171 .ctrlbit = (1<<15), 343 .ctrlbit = (1<<15),
172 }, { 344 }, {
173 .name = "i2c", 345 .name = "i2c",
174 .id = 0, 346 .id = 0,
175 .parent = &clk_p66, 347 .parent = &clk_pclk_psys.clk,
176 .enable = s5pv210_clk_ip3_ctrl, 348 .enable = s5pv210_clk_ip3_ctrl,
177 .ctrlbit = (1<<7), 349 .ctrlbit = (1<<7),
178 }, { 350 }, {
179 .name = "i2c", 351 .name = "i2c",
180 .id = 1, 352 .id = 1,
181 .parent = &clk_p66, 353 .parent = &clk_pclk_psys.clk,
182 .enable = s5pv210_clk_ip3_ctrl, 354 .enable = s5pv210_clk_ip3_ctrl,
183 .ctrlbit = (1<<8), 355 .ctrlbit = (1<<8),
184 }, { 356 }, {
185 .name = "i2c", 357 .name = "i2c",
186 .id = 2, 358 .id = 2,
187 .parent = &clk_p66, 359 .parent = &clk_pclk_psys.clk,
188 .enable = s5pv210_clk_ip3_ctrl, 360 .enable = s5pv210_clk_ip3_ctrl,
189 .ctrlbit = (1<<9), 361 .ctrlbit = (1<<9),
190 }, { 362 }, {
191 .name = "spi", 363 .name = "spi",
192 .id = 0, 364 .id = 0,
193 .parent = &clk_p66, 365 .parent = &clk_pclk_psys.clk,
194 .enable = s5pv210_clk_ip3_ctrl, 366 .enable = s5pv210_clk_ip3_ctrl,
195 .ctrlbit = (1<<12), 367 .ctrlbit = (1<<12),
196 }, { 368 }, {
197 .name = "spi", 369 .name = "spi",
198 .id = 1, 370 .id = 1,
199 .parent = &clk_p66, 371 .parent = &clk_pclk_psys.clk,
200 .enable = s5pv210_clk_ip3_ctrl, 372 .enable = s5pv210_clk_ip3_ctrl,
201 .ctrlbit = (1<<13), 373 .ctrlbit = (1<<13),
202 }, { 374 }, {
203 .name = "spi", 375 .name = "spi",
204 .id = 2, 376 .id = 2,
205 .parent = &clk_p66, 377 .parent = &clk_pclk_psys.clk,
206 .enable = s5pv210_clk_ip3_ctrl, 378 .enable = s5pv210_clk_ip3_ctrl,
207 .ctrlbit = (1<<14), 379 .ctrlbit = (1<<14),
208 }, { 380 }, {
209 .name = "timers", 381 .name = "timers",
210 .id = -1, 382 .id = -1,
211 .parent = &clk_p66, 383 .parent = &clk_pclk_psys.clk,
212 .enable = s5pv210_clk_ip3_ctrl, 384 .enable = s5pv210_clk_ip3_ctrl,
213 .ctrlbit = (1<<23), 385 .ctrlbit = (1<<23),
214 }, { 386 }, {
215 .name = "adc", 387 .name = "adc",
216 .id = -1, 388 .id = -1,
217 .parent = &clk_p66, 389 .parent = &clk_pclk_psys.clk,
218 .enable = s5pv210_clk_ip3_ctrl, 390 .enable = s5pv210_clk_ip3_ctrl,
219 .ctrlbit = (1<<24), 391 .ctrlbit = (1<<24),
220 }, { 392 }, {
221 .name = "keypad", 393 .name = "keypad",
222 .id = -1, 394 .id = -1,
223 .parent = &clk_p66, 395 .parent = &clk_pclk_psys.clk,
224 .enable = s5pv210_clk_ip3_ctrl, 396 .enable = s5pv210_clk_ip3_ctrl,
225 .ctrlbit = (1<<21), 397 .ctrlbit = (1<<21),
226 }, { 398 }, {
@@ -246,106 +418,537 @@ static struct clk init_clocks_disable[] = {
246 418
247static struct clk init_clocks[] = { 419static struct clk init_clocks[] = {
248 { 420 {
421 .name = "hclk_imem",
422 .id = -1,
423 .parent = &clk_hclk_msys.clk,
424 .ctrlbit = (1 << 5),
425 .enable = s5pv210_clk_ip0_ctrl,
426 .ops = &clk_hclk_imem_ops,
427 }, {
249 .name = "uart", 428 .name = "uart",
250 .id = 0, 429 .id = 0,
251 .parent = &clk_p66, 430 .parent = &clk_pclk_psys.clk,
252 .enable = s5pv210_clk_ip3_ctrl, 431 .enable = s5pv210_clk_ip3_ctrl,
253 .ctrlbit = (1<<7), 432 .ctrlbit = (1<<7),
254 }, { 433 }, {
255 .name = "uart", 434 .name = "uart",
256 .id = 1, 435 .id = 1,
257 .parent = &clk_p66, 436 .parent = &clk_pclk_psys.clk,
258 .enable = s5pv210_clk_ip3_ctrl, 437 .enable = s5pv210_clk_ip3_ctrl,
259 .ctrlbit = (1<<8), 438 .ctrlbit = (1<<8),
260 }, { 439 }, {
261 .name = "uart", 440 .name = "uart",
262 .id = 2, 441 .id = 2,
263 .parent = &clk_p66, 442 .parent = &clk_pclk_psys.clk,
264 .enable = s5pv210_clk_ip3_ctrl, 443 .enable = s5pv210_clk_ip3_ctrl,
265 .ctrlbit = (1<<9), 444 .ctrlbit = (1<<9),
266 }, { 445 }, {
267 .name = "uart", 446 .name = "uart",
268 .id = 3, 447 .id = 3,
269 .parent = &clk_p66, 448 .parent = &clk_pclk_psys.clk,
270 .enable = s5pv210_clk_ip3_ctrl, 449 .enable = s5pv210_clk_ip3_ctrl,
271 .ctrlbit = (1<<10), 450 .ctrlbit = (1<<10),
272 }, 451 },
273}; 452};
274 453
275static struct clksrc_clk clk_mout_apll = { 454static struct clk *clkset_uart_list[] = {
276 .clk = { 455 [6] = &clk_mout_mpll.clk,
277 .name = "mout_apll", 456 [7] = &clk_mout_epll.clk,
457};
458
459static struct clksrc_sources clkset_uart = {
460 .sources = clkset_uart_list,
461 .nr_sources = ARRAY_SIZE(clkset_uart_list),
462};
463
464static struct clk *clkset_group1_list[] = {
465 [0] = &clk_sclk_a2m.clk,
466 [1] = &clk_mout_mpll.clk,
467 [2] = &clk_mout_epll.clk,
468 [3] = &clk_sclk_vpll.clk,
469};
470
471static struct clksrc_sources clkset_group1 = {
472 .sources = clkset_group1_list,
473 .nr_sources = ARRAY_SIZE(clkset_group1_list),
474};
475
476static struct clk *clkset_sclk_onenand_list[] = {
477 [0] = &clk_hclk_psys.clk,
478 [1] = &clk_hclk_dsys.clk,
479};
480
481static struct clksrc_sources clkset_sclk_onenand = {
482 .sources = clkset_sclk_onenand_list,
483 .nr_sources = ARRAY_SIZE(clkset_sclk_onenand_list),
484};
485
486static struct clk *clkset_sclk_dac_list[] = {
487 [0] = &clk_sclk_vpll.clk,
488 [1] = &clk_sclk_hdmiphy,
489};
490
491static struct clksrc_sources clkset_sclk_dac = {
492 .sources = clkset_sclk_dac_list,
493 .nr_sources = ARRAY_SIZE(clkset_sclk_dac_list),
494};
495
496static struct clksrc_clk clk_sclk_dac = {
497 .clk = {
498 .name = "sclk_dac",
278 .id = -1, 499 .id = -1,
500 .ctrlbit = (1 << 10),
501 .enable = s5pv210_clk_ip1_ctrl,
279 }, 502 },
280 .sources = &clk_src_apll, 503 .sources = &clkset_sclk_dac,
281 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 }, 504 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 1 },
282}; 505};
283 506
284static struct clksrc_clk clk_mout_epll = { 507static struct clksrc_clk clk_sclk_pixel = {
285 .clk = { 508 .clk = {
286 .name = "mout_epll", 509 .name = "sclk_pixel",
287 .id = -1, 510 .id = -1,
511 .parent = &clk_sclk_vpll.clk,
288 }, 512 },
289 .sources = &clk_src_epll, 513 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4},
290 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
291}; 514};
292 515
293static struct clksrc_clk clk_mout_mpll = { 516static struct clk *clkset_sclk_hdmi_list[] = {
294 .clk = { 517 [0] = &clk_sclk_pixel.clk,
295 .name = "mout_mpll", 518 [1] = &clk_sclk_hdmiphy,
519};
520
521static struct clksrc_sources clkset_sclk_hdmi = {
522 .sources = clkset_sclk_hdmi_list,
523 .nr_sources = ARRAY_SIZE(clkset_sclk_hdmi_list),
524};
525
526static struct clksrc_clk clk_sclk_hdmi = {
527 .clk = {
528 .name = "sclk_hdmi",
296 .id = -1, 529 .id = -1,
530 .enable = s5pv210_clk_ip1_ctrl,
531 .ctrlbit = (1 << 11),
297 }, 532 },
298 .sources = &clk_src_mpll, 533 .sources = &clkset_sclk_hdmi,
299 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 }, 534 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
300}; 535};
301 536
302static struct clk *clkset_uart_list[] = { 537static struct clk *clkset_sclk_mixer_list[] = {
538 [0] = &clk_sclk_dac.clk,
539 [1] = &clk_sclk_hdmi.clk,
540};
541
542static struct clksrc_sources clkset_sclk_mixer = {
543 .sources = clkset_sclk_mixer_list,
544 .nr_sources = ARRAY_SIZE(clkset_sclk_mixer_list),
545};
546
547static struct clk *clkset_sclk_audio0_list[] = {
548 [0] = &clk_ext_xtal_mux,
549 [1] = &clk_pcmcdclk0,
550 [2] = &clk_sclk_hdmi27m,
551 [3] = &clk_sclk_usbphy0,
552 [4] = &clk_sclk_usbphy1,
553 [5] = &clk_sclk_hdmiphy,
303 [6] = &clk_mout_mpll.clk, 554 [6] = &clk_mout_mpll.clk,
304 [7] = &clk_mout_epll.clk, 555 [7] = &clk_mout_epll.clk,
556 [8] = &clk_sclk_vpll.clk,
305}; 557};
306 558
307static struct clksrc_sources clkset_uart = { 559static struct clksrc_sources clkset_sclk_audio0 = {
308 .sources = clkset_uart_list, 560 .sources = clkset_sclk_audio0_list,
309 .nr_sources = ARRAY_SIZE(clkset_uart_list), 561 .nr_sources = ARRAY_SIZE(clkset_sclk_audio0_list),
562};
563
564static struct clksrc_clk clk_sclk_audio0 = {
565 .clk = {
566 .name = "sclk_audio",
567 .id = 0,
568 .enable = s5pv210_clk_ip3_ctrl,
569 .ctrlbit = (1 << 4),
570 },
571 .sources = &clkset_sclk_audio0,
572 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 0, .size = 4 },
573 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 0, .size = 4 },
574};
575
576static struct clk *clkset_sclk_audio1_list[] = {
577 [0] = &clk_ext_xtal_mux,
578 [1] = &clk_pcmcdclk1,
579 [2] = &clk_sclk_hdmi27m,
580 [3] = &clk_sclk_usbphy0,
581 [4] = &clk_sclk_usbphy1,
582 [5] = &clk_sclk_hdmiphy,
583 [6] = &clk_mout_mpll.clk,
584 [7] = &clk_mout_epll.clk,
585 [8] = &clk_sclk_vpll.clk,
586};
587
588static struct clksrc_sources clkset_sclk_audio1 = {
589 .sources = clkset_sclk_audio1_list,
590 .nr_sources = ARRAY_SIZE(clkset_sclk_audio1_list),
591};
592
593static struct clksrc_clk clk_sclk_audio1 = {
594 .clk = {
595 .name = "sclk_audio",
596 .id = 1,
597 .enable = s5pv210_clk_ip3_ctrl,
598 .ctrlbit = (1 << 5),
599 },
600 .sources = &clkset_sclk_audio1,
601 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 4, .size = 4 },
602 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 4, .size = 4 },
603};
604
605static struct clk *clkset_sclk_audio2_list[] = {
606 [0] = &clk_ext_xtal_mux,
607 [1] = &clk_pcmcdclk0,
608 [2] = &clk_sclk_hdmi27m,
609 [3] = &clk_sclk_usbphy0,
610 [4] = &clk_sclk_usbphy1,
611 [5] = &clk_sclk_hdmiphy,
612 [6] = &clk_mout_mpll.clk,
613 [7] = &clk_mout_epll.clk,
614 [8] = &clk_sclk_vpll.clk,
615};
616
617static struct clksrc_sources clkset_sclk_audio2 = {
618 .sources = clkset_sclk_audio2_list,
619 .nr_sources = ARRAY_SIZE(clkset_sclk_audio2_list),
620};
621
622static struct clksrc_clk clk_sclk_audio2 = {
623 .clk = {
624 .name = "sclk_audio",
625 .id = 2,
626 .enable = s5pv210_clk_ip3_ctrl,
627 .ctrlbit = (1 << 6),
628 },
629 .sources = &clkset_sclk_audio2,
630 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 8, .size = 4 },
631 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 8, .size = 4 },
632};
633
634static struct clk *clkset_sclk_spdif_list[] = {
635 [0] = &clk_sclk_audio0.clk,
636 [1] = &clk_sclk_audio1.clk,
637 [2] = &clk_sclk_audio2.clk,
638};
639
640static struct clksrc_sources clkset_sclk_spdif = {
641 .sources = clkset_sclk_spdif_list,
642 .nr_sources = ARRAY_SIZE(clkset_sclk_spdif_list),
643};
644
645static struct clk *clkset_group2_list[] = {
646 [0] = &clk_ext_xtal_mux,
647 [1] = &clk_xusbxti,
648 [2] = &clk_sclk_hdmi27m,
649 [3] = &clk_sclk_usbphy0,
650 [4] = &clk_sclk_usbphy1,
651 [5] = &clk_sclk_hdmiphy,
652 [6] = &clk_mout_mpll.clk,
653 [7] = &clk_mout_epll.clk,
654 [8] = &clk_sclk_vpll.clk,
655};
656
657static struct clksrc_sources clkset_group2 = {
658 .sources = clkset_group2_list,
659 .nr_sources = ARRAY_SIZE(clkset_group2_list),
310}; 660};
311 661
312static struct clksrc_clk clksrcs[] = { 662static struct clksrc_clk clksrcs[] = {
313 { 663 {
314 .clk = { 664 .clk = {
315 .name = "uclk1", 665 .name = "sclk_dmc",
316 .id = -1, 666 .id = -1,
667 },
668 .sources = &clkset_group1,
669 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
670 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
671 }, {
672 .clk = {
673 .name = "sclk_onenand",
674 .id = -1,
675 },
676 .sources = &clkset_sclk_onenand,
677 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 28, .size = 1 },
678 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 },
679 }, {
680 .clk = {
681 .name = "uclk1",
682 .id = 0,
317 .ctrlbit = (1<<17), 683 .ctrlbit = (1<<17),
318 .enable = s5pv210_clk_ip3_ctrl, 684 .enable = s5pv210_clk_ip3_ctrl,
319 }, 685 },
320 .sources = &clkset_uart, 686 .sources = &clkset_uart,
321 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 }, 687 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
322 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 }, 688 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
323 } 689 }, {
690 .clk = {
691 .name = "uclk1",
692 .id = 1,
693 .enable = s5pv210_clk_ip3_ctrl,
694 .ctrlbit = (1 << 18),
695 },
696 .sources = &clkset_uart,
697 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
698 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
699 }, {
700 .clk = {
701 .name = "uclk1",
702 .id = 2,
703 .enable = s5pv210_clk_ip3_ctrl,
704 .ctrlbit = (1 << 19),
705 },
706 .sources = &clkset_uart,
707 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
708 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
709 }, {
710 .clk = {
711 .name = "uclk1",
712 .id = 3,
713 .enable = s5pv210_clk_ip3_ctrl,
714 .ctrlbit = (1 << 20),
715 },
716 .sources = &clkset_uart,
717 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
718 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
719 }, {
720 .clk = {
721 .name = "sclk_mixer",
722 .id = -1,
723 .enable = s5pv210_clk_ip1_ctrl,
724 .ctrlbit = (1 << 9),
725 },
726 .sources = &clkset_sclk_mixer,
727 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
728 }, {
729 .clk = {
730 .name = "sclk_spdif",
731 .id = -1,
732 .enable = s5pv210_clk_mask0_ctrl,
733 .ctrlbit = (1 << 27),
734 },
735 .sources = &clkset_sclk_spdif,
736 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
737 }, {
738 .clk = {
739 .name = "sclk_fimc",
740 .id = 0,
741 .enable = s5pv210_clk_ip0_ctrl,
742 .ctrlbit = (1 << 24),
743 },
744 .sources = &clkset_group2,
745 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 4 },
746 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 },
747 }, {
748 .clk = {
749 .name = "sclk_fimc",
750 .id = 1,
751 .enable = s5pv210_clk_ip0_ctrl,
752 .ctrlbit = (1 << 25),
753 },
754 .sources = &clkset_group2,
755 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 4 },
756 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 16, .size = 4 },
757 }, {
758 .clk = {
759 .name = "sclk_fimc",
760 .id = 2,
761 .enable = s5pv210_clk_ip0_ctrl,
762 .ctrlbit = (1 << 26),
763 },
764 .sources = &clkset_group2,
765 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 4 },
766 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 20, .size = 4 },
767 }, {
768 .clk = {
769 .name = "sclk_cam",
770 .id = 0,
771 },
772 .sources = &clkset_group2,
773 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 4 },
774 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 },
775 }, {
776 .clk = {
777 .name = "sclk_cam",
778 .id = 1,
779 },
780 .sources = &clkset_group2,
781 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 16, .size = 4 },
782 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 16, .size = 4 },
783 }, {
784 .clk = {
785 .name = "sclk_fimd",
786 .id = -1,
787 .enable = s5pv210_clk_ip1_ctrl,
788 .ctrlbit = (1 << 0),
789 },
790 .sources = &clkset_group2,
791 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 4 },
792 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 4 },
793 }, {
794 .clk = {
795 .name = "sclk_mmc",
796 .id = 0,
797 .enable = s5pv210_clk_ip2_ctrl,
798 .ctrlbit = (1 << 16),
799 },
800 .sources = &clkset_group2,
801 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 },
802 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 4 },
803 }, {
804 .clk = {
805 .name = "sclk_mmc",
806 .id = 1,
807 .enable = s5pv210_clk_ip2_ctrl,
808 .ctrlbit = (1 << 17),
809 },
810 .sources = &clkset_group2,
811 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 },
812 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 4, .size = 4 },
813 }, {
814 .clk = {
815 .name = "sclk_mmc",
816 .id = 2,
817 .enable = s5pv210_clk_ip2_ctrl,
818 .ctrlbit = (1 << 18),
819 },
820 .sources = &clkset_group2,
821 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 },
822 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 8, .size = 4 },
823 }, {
824 .clk = {
825 .name = "sclk_mmc",
826 .id = 3,
827 .enable = s5pv210_clk_ip2_ctrl,
828 .ctrlbit = (1 << 19),
829 },
830 .sources = &clkset_group2,
831 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 },
832 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
833 }, {
834 .clk = {
835 .name = "sclk_mfc",
836 .id = -1,
837 .enable = s5pv210_clk_ip0_ctrl,
838 .ctrlbit = (1 << 16),
839 },
840 .sources = &clkset_group1,
841 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 },
842 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
843 }, {
844 .clk = {
845 .name = "sclk_g2d",
846 .id = -1,
847 .enable = s5pv210_clk_ip0_ctrl,
848 .ctrlbit = (1 << 12),
849 },
850 .sources = &clkset_group1,
851 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
852 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 },
853 }, {
854 .clk = {
855 .name = "sclk_g3d",
856 .id = -1,
857 .enable = s5pv210_clk_ip0_ctrl,
858 .ctrlbit = (1 << 8),
859 },
860 .sources = &clkset_group1,
861 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 },
862 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
863 }, {
864 .clk = {
865 .name = "sclk_csis",
866 .id = -1,
867 .enable = s5pv210_clk_ip0_ctrl,
868 .ctrlbit = (1 << 31),
869 },
870 .sources = &clkset_group2,
871 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 24, .size = 4 },
872 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 28, .size = 4 },
873 }, {
874 .clk = {
875 .name = "sclk_spi",
876 .id = 0,
877 .enable = s5pv210_clk_ip3_ctrl,
878 .ctrlbit = (1 << 12),
879 },
880 .sources = &clkset_group2,
881 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 },
882 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 0, .size = 4 },
883 }, {
884 .clk = {
885 .name = "sclk_spi",
886 .id = 1,
887 .enable = s5pv210_clk_ip3_ctrl,
888 .ctrlbit = (1 << 13),
889 },
890 .sources = &clkset_group2,
891 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 },
892 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 4, .size = 4 },
893 }, {
894 .clk = {
895 .name = "sclk_pwi",
896 .id = -1,
897 .enable = &s5pv210_clk_ip4_ctrl,
898 .ctrlbit = (1 << 2),
899 },
900 .sources = &clkset_group2,
901 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 20, .size = 4 },
902 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 24, .size = 4 },
903 }, {
904 .clk = {
905 .name = "sclk_pwm",
906 .id = -1,
907 .enable = s5pv210_clk_ip3_ctrl,
908 .ctrlbit = (1 << 23),
909 },
910 .sources = &clkset_group2,
911 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 12, .size = 4 },
912 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 12, .size = 4 },
913 },
324}; 914};
325 915
326/* Clock initialisation code */ 916/* Clock initialisation code */
327static struct clksrc_clk *init_parents[] = { 917static struct clksrc_clk *sysclks[] = {
328 &clk_mout_apll, 918 &clk_mout_apll,
329 &clk_mout_epll, 919 &clk_mout_epll,
330 &clk_mout_mpll, 920 &clk_mout_mpll,
921 &clk_armclk,
922 &clk_hclk_msys,
923 &clk_sclk_a2m,
924 &clk_hclk_dsys,
925 &clk_hclk_psys,
926 &clk_pclk_msys,
927 &clk_pclk_dsys,
928 &clk_pclk_psys,
929 &clk_vpllsrc,
930 &clk_sclk_vpll,
931 &clk_sclk_dac,
932 &clk_sclk_pixel,
933 &clk_sclk_hdmi,
331}; 934};
332 935
333#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
334
335void __init_or_cpufreq s5pv210_setup_clocks(void) 936void __init_or_cpufreq s5pv210_setup_clocks(void)
336{ 937{
337 struct clk *xtal_clk; 938 struct clk *xtal_clk;
338 unsigned long xtal; 939 unsigned long xtal;
940 unsigned long vpllsrc;
339 unsigned long armclk; 941 unsigned long armclk;
340 unsigned long hclk200; 942 unsigned long hclk_msys;
341 unsigned long hclk166; 943 unsigned long hclk_dsys;
342 unsigned long hclk133; 944 unsigned long hclk_psys;
343 unsigned long pclk100; 945 unsigned long pclk_msys;
344 unsigned long pclk83; 946 unsigned long pclk_dsys;
345 unsigned long pclk66; 947 unsigned long pclk_psys;
346 unsigned long apll; 948 unsigned long apll;
347 unsigned long mpll; 949 unsigned long mpll;
348 unsigned long epll; 950 unsigned long epll;
951 unsigned long vpll;
349 unsigned int ptr; 952 unsigned int ptr;
350 u32 clkdiv0, clkdiv1; 953 u32 clkdiv0, clkdiv1;
351 954
@@ -368,59 +971,46 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
368 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508); 971 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
369 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502); 972 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
370 epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500); 973 epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500);
371 974 vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
372 printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld", 975 vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502);
373 apll, mpll, epll);
374
375 armclk = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_APLL);
376 if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX200_MASK)
377 hclk200 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK200);
378 else
379 hclk200 = armclk / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK200);
380
381 if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX166_MASK) {
382 hclk166 = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_A2M);
383 hclk166 = hclk166 / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK166);
384 } else
385 hclk166 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK166);
386
387 if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX133_MASK) {
388 hclk133 = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_A2M);
389 hclk133 = hclk133 / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK133);
390 } else
391 hclk133 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK133);
392
393 pclk100 = hclk200 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK100);
394 pclk83 = hclk166 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK83);
395 pclk66 = hclk133 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK66);
396
397 printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld, \
398 HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n",
399 armclk, hclk200, hclk166, hclk133, pclk100, pclk83, pclk66);
400 976
401 clk_fout_apll.rate = apll; 977 clk_fout_apll.rate = apll;
402 clk_fout_mpll.rate = mpll; 978 clk_fout_mpll.rate = mpll;
403 clk_fout_epll.rate = epll; 979 clk_fout_epll.rate = epll;
980 clk_fout_vpll.rate = vpll;
404 981
405 clk_f.rate = armclk; 982 printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
406 clk_h.rate = hclk133; 983 apll, mpll, epll, vpll);
407 clk_p.rate = pclk66; 984
408 clk_p66.rate = pclk66; 985 armclk = clk_get_rate(&clk_armclk.clk);
409 clk_p83.rate = pclk83; 986 hclk_msys = clk_get_rate(&clk_hclk_msys.clk);
410 clk_h133.rate = hclk133; 987 hclk_dsys = clk_get_rate(&clk_hclk_dsys.clk);
411 clk_h166.rate = hclk166; 988 hclk_psys = clk_get_rate(&clk_hclk_psys.clk);
412 clk_h200.rate = hclk200; 989 pclk_msys = clk_get_rate(&clk_pclk_msys.clk);
990 pclk_dsys = clk_get_rate(&clk_pclk_dsys.clk);
991 pclk_psys = clk_get_rate(&clk_pclk_psys.clk);
992
993 printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld\n"
994 "HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n",
995 armclk, hclk_msys, hclk_dsys, hclk_psys,
996 pclk_msys, pclk_dsys, pclk_psys);
413 997
414 for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++) 998 clk_f.rate = armclk;
415 s3c_set_clksrc(init_parents[ptr], true); 999 clk_h.rate = hclk_psys;
1000 clk_p.rate = pclk_psys;
416 1001
417 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) 1002 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
418 s3c_set_clksrc(&clksrcs[ptr], true); 1003 s3c_set_clksrc(&clksrcs[ptr], true);
419} 1004}
420 1005
421static struct clk *clks[] __initdata = { 1006static struct clk *clks[] __initdata = {
422 &clk_mout_epll.clk, 1007 &clk_sclk_hdmi27m,
423 &clk_mout_mpll.clk, 1008 &clk_sclk_hdmiphy,
1009 &clk_sclk_usbphy0,
1010 &clk_sclk_usbphy1,
1011 &clk_pcmcdclk0,
1012 &clk_pcmcdclk1,
1013 &clk_pcmcdclk2,
424}; 1014};
425 1015
426void __init s5pv210_register_clocks(void) 1016void __init s5pv210_register_clocks(void)
@@ -433,13 +1023,12 @@ void __init s5pv210_register_clocks(void)
433 if (ret > 0) 1023 if (ret > 0)
434 printk(KERN_ERR "Failed to register %u clocks\n", ret); 1024 printk(KERN_ERR "Failed to register %u clocks\n", ret);
435 1025
1026 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
1027 s3c_register_clksrc(sysclks[ptr], 1);
1028
436 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 1029 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
437 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 1030 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
438 1031
439 ret = s3c24xx_register_clocks(sys_clks, ARRAY_SIZE(sys_clks));
440 if (ret > 0)
441 printk(KERN_ERR "Failed to register system clocks\n");
442
443 clkp = init_clocks_disable; 1032 clkp = init_clocks_disable;
444 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { 1033 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
445 ret = s3c24xx_register_clock(clkp); 1034 ret = s3c24xx_register_clock(clkp);
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
index 0e0f8fde2aa6..2b776eb5d150 100644
--- a/arch/arm/mach-s5pv210/cpu.c
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -100,7 +100,7 @@ void __init s5pv210_init_irq(void)
100 s5p_init_irq(vic, ARRAY_SIZE(vic)); 100 s5p_init_irq(vic, ARRAY_SIZE(vic));
101} 101}
102 102
103static struct sysdev_class s5pv210_sysclass = { 103struct sysdev_class s5pv210_sysclass = {
104 .name = "s5pv210-core", 104 .name = "s5pv210-core",
105}; 105};
106 106
diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c
new file mode 100644
index 000000000000..778ad5fe231a
--- /dev/null
+++ b/arch/arm/mach-s5pv210/dma.c
@@ -0,0 +1,168 @@
1/*
2 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
3 * Jaswinder Singh <jassi.brar@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/platform_device.h>
21#include <linux/dma-mapping.h>
22
23#include <plat/devs.h>
24#include <plat/irqs.h>
25
26#include <mach/map.h>
27#include <mach/irqs.h>
28
29#include <plat/s3c-pl330-pdata.h>
30
31static u64 dma_dmamask = DMA_BIT_MASK(32);
32
33static struct resource s5pv210_pdma0_resource[] = {
34 [0] = {
35 .start = S5PV210_PA_PDMA0,
36 .end = S5PV210_PA_PDMA0 + SZ_4K,
37 .flags = IORESOURCE_MEM,
38 },
39 [1] = {
40 .start = IRQ_PDMA0,
41 .end = IRQ_PDMA0,
42 .flags = IORESOURCE_IRQ,
43 },
44};
45
46static struct s3c_pl330_platdata s5pv210_pdma0_pdata = {
47 .peri = {
48 [0] = DMACH_UART0_RX,
49 [1] = DMACH_UART0_TX,
50 [2] = DMACH_UART1_RX,
51 [3] = DMACH_UART1_TX,
52 [4] = DMACH_UART2_RX,
53 [5] = DMACH_UART2_TX,
54 [6] = DMACH_UART3_RX,
55 [7] = DMACH_UART3_TX,
56 [8] = DMACH_MAX,
57 [9] = DMACH_I2S0_RX,
58 [10] = DMACH_I2S0_TX,
59 [11] = DMACH_I2S0S_TX,
60 [12] = DMACH_I2S1_RX,
61 [13] = DMACH_I2S1_TX,
62 [14] = DMACH_MAX,
63 [15] = DMACH_MAX,
64 [16] = DMACH_SPI0_RX,
65 [17] = DMACH_SPI0_TX,
66 [18] = DMACH_SPI1_RX,
67 [19] = DMACH_SPI1_TX,
68 [20] = DMACH_MAX,
69 [21] = DMACH_MAX,
70 [22] = DMACH_AC97_MICIN,
71 [23] = DMACH_AC97_PCMIN,
72 [24] = DMACH_AC97_PCMOUT,
73 [25] = DMACH_MAX,
74 [26] = DMACH_PWM,
75 [27] = DMACH_SPDIF,
76 [28] = DMACH_MAX,
77 [29] = DMACH_MAX,
78 [30] = DMACH_MAX,
79 [31] = DMACH_MAX,
80 },
81};
82
83static struct platform_device s5pv210_device_pdma0 = {
84 .name = "s3c-pl330",
85 .id = 1,
86 .num_resources = ARRAY_SIZE(s5pv210_pdma0_resource),
87 .resource = s5pv210_pdma0_resource,
88 .dev = {
89 .dma_mask = &dma_dmamask,
90 .coherent_dma_mask = DMA_BIT_MASK(32),
91 .platform_data = &s5pv210_pdma0_pdata,
92 },
93};
94
95static struct resource s5pv210_pdma1_resource[] = {
96 [0] = {
97 .start = S5PV210_PA_PDMA1,
98 .end = S5PV210_PA_PDMA1 + SZ_4K,
99 .flags = IORESOURCE_MEM,
100 },
101 [1] = {
102 .start = IRQ_PDMA1,
103 .end = IRQ_PDMA1,
104 .flags = IORESOURCE_IRQ,
105 },
106};
107
108static struct s3c_pl330_platdata s5pv210_pdma1_pdata = {
109 .peri = {
110 [0] = DMACH_UART0_RX,
111 [1] = DMACH_UART0_TX,
112 [2] = DMACH_UART1_RX,
113 [3] = DMACH_UART1_TX,
114 [4] = DMACH_UART2_RX,
115 [5] = DMACH_UART2_TX,
116 [6] = DMACH_UART3_RX,
117 [7] = DMACH_UART3_TX,
118 [8] = DMACH_MAX,
119 [9] = DMACH_I2S0_RX,
120 [10] = DMACH_I2S0_TX,
121 [11] = DMACH_I2S0S_TX,
122 [12] = DMACH_I2S1_RX,
123 [13] = DMACH_I2S1_TX,
124 [14] = DMACH_I2S2_RX,
125 [15] = DMACH_I2S2_TX,
126 [16] = DMACH_SPI0_RX,
127 [17] = DMACH_SPI0_TX,
128 [18] = DMACH_SPI1_RX,
129 [19] = DMACH_SPI1_TX,
130 [20] = DMACH_MAX,
131 [21] = DMACH_MAX,
132 [22] = DMACH_PCM0_RX,
133 [23] = DMACH_PCM0_TX,
134 [24] = DMACH_PCM1_RX,
135 [25] = DMACH_PCM1_TX,
136 [26] = DMACH_MSM_REQ0,
137 [27] = DMACH_MSM_REQ1,
138 [28] = DMACH_MSM_REQ2,
139 [29] = DMACH_MSM_REQ3,
140 [30] = DMACH_PCM2_RX,
141 [31] = DMACH_PCM2_TX,
142 },
143};
144
145static struct platform_device s5pv210_device_pdma1 = {
146 .name = "s3c-pl330",
147 .id = 2,
148 .num_resources = ARRAY_SIZE(s5pv210_pdma1_resource),
149 .resource = s5pv210_pdma1_resource,
150 .dev = {
151 .dma_mask = &dma_dmamask,
152 .coherent_dma_mask = DMA_BIT_MASK(32),
153 .platform_data = &s5pv210_pdma1_pdata,
154 },
155};
156
157static struct platform_device *s5pv210_dmacs[] __initdata = {
158 &s5pv210_device_pdma0,
159 &s5pv210_device_pdma1,
160};
161
162static int __init s5pv210_dma_init(void)
163{
164 platform_add_devices(s5pv210_dmacs, ARRAY_SIZE(s5pv210_dmacs));
165
166 return 0;
167}
168arch_initcall(s5pv210_dma_init);
diff --git a/arch/arm/mach-s5pv210/gpiolib.c b/arch/arm/mach-s5pv210/gpiolib.c
new file mode 100644
index 000000000000..9ea8972e023d
--- /dev/null
+++ b/arch/arm/mach-s5pv210/gpiolib.c
@@ -0,0 +1,261 @@
1/* linux/arch/arm/mach-s5pv210/gpiolib.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV210 - GPIOlib support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/kernel.h>
14#include <linux/irq.h>
15#include <linux/io.h>
16#include <linux/gpio.h>
17#include <plat/gpio-core.h>
18#include <plat/gpio-cfg.h>
19#include <plat/gpio-cfg-helpers.h>
20#include <mach/map.h>
21
22static struct s3c_gpio_cfg gpio_cfg = {
23 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
24 .set_pull = s3c_gpio_setpull_updown,
25 .get_pull = s3c_gpio_getpull_updown,
26};
27
28static struct s3c_gpio_cfg gpio_cfg_noint = {
29 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
30 .set_pull = s3c_gpio_setpull_updown,
31 .get_pull = s3c_gpio_getpull_updown,
32};
33
34/* GPIO bank's base address given the index of the bank in the
35 * list of all gpio banks.
36 */
37#define S5PV210_BANK_BASE(bank_nr) (S5P_VA_GPIO + ((bank_nr) * 0x20))
38
39/*
40 * Following are the gpio banks in v210.
41 *
42 * The 'config' member when left to NULL, is initialized to the default
43 * structure gpio_cfg in the init function below.
44 *
45 * The 'base' member is also initialized in the init function below.
46 * Note: The initialization of 'base' member of s3c_gpio_chip structure
47 * uses the above macro and depends on the banks being listed in order here.
48 */
49static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
50 {
51 .chip = {
52 .base = S5PV210_GPA0(0),
53 .ngpio = S5PV210_GPIO_A0_NR,
54 .label = "GPA0",
55 },
56 }, {
57 .chip = {
58 .base = S5PV210_GPA1(0),
59 .ngpio = S5PV210_GPIO_A1_NR,
60 .label = "GPA1",
61 },
62 }, {
63 .chip = {
64 .base = S5PV210_GPB(0),
65 .ngpio = S5PV210_GPIO_B_NR,
66 .label = "GPB",
67 },
68 }, {
69 .chip = {
70 .base = S5PV210_GPC0(0),
71 .ngpio = S5PV210_GPIO_C0_NR,
72 .label = "GPC0",
73 },
74 }, {
75 .chip = {
76 .base = S5PV210_GPC1(0),
77 .ngpio = S5PV210_GPIO_C1_NR,
78 .label = "GPC1",
79 },
80 }, {
81 .chip = {
82 .base = S5PV210_GPD0(0),
83 .ngpio = S5PV210_GPIO_D0_NR,
84 .label = "GPD0",
85 },
86 }, {
87 .chip = {
88 .base = S5PV210_GPD1(0),
89 .ngpio = S5PV210_GPIO_D1_NR,
90 .label = "GPD1",
91 },
92 }, {
93 .chip = {
94 .base = S5PV210_GPE0(0),
95 .ngpio = S5PV210_GPIO_E0_NR,
96 .label = "GPE0",
97 },
98 }, {
99 .chip = {
100 .base = S5PV210_GPE1(0),
101 .ngpio = S5PV210_GPIO_E1_NR,
102 .label = "GPE1",
103 },
104 }, {
105 .chip = {
106 .base = S5PV210_GPF0(0),
107 .ngpio = S5PV210_GPIO_F0_NR,
108 .label = "GPF0",
109 },
110 }, {
111 .chip = {
112 .base = S5PV210_GPF1(0),
113 .ngpio = S5PV210_GPIO_F1_NR,
114 .label = "GPF1",
115 },
116 }, {
117 .chip = {
118 .base = S5PV210_GPF2(0),
119 .ngpio = S5PV210_GPIO_F2_NR,
120 .label = "GPF2",
121 },
122 }, {
123 .chip = {
124 .base = S5PV210_GPF3(0),
125 .ngpio = S5PV210_GPIO_F3_NR,
126 .label = "GPF3",
127 },
128 }, {
129 .chip = {
130 .base = S5PV210_GPG0(0),
131 .ngpio = S5PV210_GPIO_G0_NR,
132 .label = "GPG0",
133 },
134 }, {
135 .chip = {
136 .base = S5PV210_GPG1(0),
137 .ngpio = S5PV210_GPIO_G1_NR,
138 .label = "GPG1",
139 },
140 }, {
141 .chip = {
142 .base = S5PV210_GPG2(0),
143 .ngpio = S5PV210_GPIO_G2_NR,
144 .label = "GPG2",
145 },
146 }, {
147 .chip = {
148 .base = S5PV210_GPG3(0),
149 .ngpio = S5PV210_GPIO_G3_NR,
150 .label = "GPG3",
151 },
152 }, {
153 .chip = {
154 .base = S5PV210_GPI(0),
155 .ngpio = S5PV210_GPIO_I_NR,
156 .label = "GPI",
157 },
158 }, {
159 .chip = {
160 .base = S5PV210_GPJ0(0),
161 .ngpio = S5PV210_GPIO_J0_NR,
162 .label = "GPJ0",
163 },
164 }, {
165 .chip = {
166 .base = S5PV210_GPJ1(0),
167 .ngpio = S5PV210_GPIO_J1_NR,
168 .label = "GPJ1",
169 },
170 }, {
171 .chip = {
172 .base = S5PV210_GPJ2(0),
173 .ngpio = S5PV210_GPIO_J2_NR,
174 .label = "GPJ2",
175 },
176 }, {
177 .chip = {
178 .base = S5PV210_GPJ3(0),
179 .ngpio = S5PV210_GPIO_J3_NR,
180 .label = "GPJ3",
181 },
182 }, {
183 .chip = {
184 .base = S5PV210_GPJ4(0),
185 .ngpio = S5PV210_GPIO_J4_NR,
186 .label = "GPJ4",
187 },
188 }, {
189 .config = &gpio_cfg_noint,
190 .chip = {
191 .base = S5PV210_MP01(0),
192 .ngpio = S5PV210_GPIO_MP01_NR,
193 .label = "MP01",
194 },
195 }, {
196 .config = &gpio_cfg_noint,
197 .chip = {
198 .base = S5PV210_MP02(0),
199 .ngpio = S5PV210_GPIO_MP02_NR,
200 .label = "MP02",
201 },
202 }, {
203 .config = &gpio_cfg_noint,
204 .chip = {
205 .base = S5PV210_MP03(0),
206 .ngpio = S5PV210_GPIO_MP03_NR,
207 .label = "MP03",
208 },
209 }, {
210 .base = (S5P_VA_GPIO + 0xC00),
211 .config = &gpio_cfg_noint,
212 .chip = {
213 .base = S5PV210_GPH0(0),
214 .ngpio = S5PV210_GPIO_H0_NR,
215 .label = "GPH0",
216 },
217 }, {
218 .base = (S5P_VA_GPIO + 0xC20),
219 .config = &gpio_cfg_noint,
220 .chip = {
221 .base = S5PV210_GPH1(0),
222 .ngpio = S5PV210_GPIO_H1_NR,
223 .label = "GPH1",
224 },
225 }, {
226 .base = (S5P_VA_GPIO + 0xC40),
227 .config = &gpio_cfg_noint,
228 .chip = {
229 .base = S5PV210_GPH2(0),
230 .ngpio = S5PV210_GPIO_H2_NR,
231 .label = "GPH2",
232 },
233 }, {
234 .base = (S5P_VA_GPIO + 0xC60),
235 .config = &gpio_cfg_noint,
236 .chip = {
237 .base = S5PV210_GPH3(0),
238 .ngpio = S5PV210_GPIO_H3_NR,
239 .label = "GPH3",
240 },
241 },
242};
243
244static __init int s5pv210_gpiolib_init(void)
245{
246 struct s3c_gpio_chip *chip = s5pv210_gpio_4bit;
247 int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);
248 int i = 0;
249
250 for (i = 0; i < nr_chips; i++, chip++) {
251 if (chip->config == NULL)
252 chip->config = &gpio_cfg;
253 if (chip->base == NULL)
254 chip->base = S5PV210_BANK_BASE(i);
255 }
256
257 samsung_gpiolib_add_4bit_chips(s5pv210_gpio_4bit, nr_chips);
258
259 return 0;
260}
261core_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
index 000000000000..81209eb1409b
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/dma.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
3 * Jaswinder Singh <jassi.brar@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#ifndef __MACH_DMA_H
21#define __MACH_DMA_H
22
23/* This platform uses the common S3C DMA API driver for PL330 */
24#include <plat/s3c-dma-pl330.h>
25
26#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/gpio.h b/arch/arm/mach-s5pv210/include/mach/gpio.h
index 533b020e21e9..d6461ba2b71d 100644
--- a/arch/arm/mach-s5pv210/include/mach/gpio.h
+++ b/arch/arm/mach-s5pv210/include/mach/gpio.h
@@ -18,6 +18,8 @@
18#define gpio_cansleep __gpio_cansleep 18#define gpio_cansleep __gpio_cansleep
19#define gpio_to_irq __gpio_to_irq 19#define gpio_to_irq __gpio_to_irq
20 20
21/* Practically, GPIO banks upto MP03 are the configurable gpio banks */
22
21/* GPIO bank sizes */ 23/* GPIO bank sizes */
22#define S5PV210_GPIO_A0_NR (8) 24#define S5PV210_GPIO_A0_NR (8)
23#define S5PV210_GPIO_A1_NR (4) 25#define S5PV210_GPIO_A1_NR (4)
@@ -47,6 +49,10 @@
47#define S5PV210_GPIO_J3_NR (8) 49#define S5PV210_GPIO_J3_NR (8)
48#define S5PV210_GPIO_J4_NR (5) 50#define S5PV210_GPIO_J4_NR (5)
49 51
52#define S5PV210_GPIO_MP01_NR (8)
53#define S5PV210_GPIO_MP02_NR (4)
54#define S5PV210_GPIO_MP03_NR (8)
55
50/* GPIO bank numbers */ 56/* GPIO bank numbers */
51 57
52/* CONFIG_S3C_GPIO_SPACE allows the user to select extra 58/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
@@ -85,6 +91,9 @@ enum s5p_gpio_number {
85 S5PV210_GPIO_J2_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J1), 91 S5PV210_GPIO_J2_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J1),
86 S5PV210_GPIO_J3_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J2), 92 S5PV210_GPIO_J3_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J2),
87 S5PV210_GPIO_J4_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J3), 93 S5PV210_GPIO_J4_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J3),
94 S5PV210_GPIO_MP01_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J4),
95 S5PV210_GPIO_MP02_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP01),
96 S5PV210_GPIO_MP03_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP02),
88}; 97};
89 98
90/* S5PV210 GPIO number definitions */ 99/* S5PV210 GPIO number definitions */
@@ -115,13 +124,16 @@ enum s5p_gpio_number {
115#define S5PV210_GPJ2(_nr) (S5PV210_GPIO_J2_START + (_nr)) 124#define S5PV210_GPJ2(_nr) (S5PV210_GPIO_J2_START + (_nr))
116#define S5PV210_GPJ3(_nr) (S5PV210_GPIO_J3_START + (_nr)) 125#define S5PV210_GPJ3(_nr) (S5PV210_GPIO_J3_START + (_nr))
117#define S5PV210_GPJ4(_nr) (S5PV210_GPIO_J4_START + (_nr)) 126#define S5PV210_GPJ4(_nr) (S5PV210_GPIO_J4_START + (_nr))
127#define S5PV210_MP01(_nr) (S5PV210_GPIO_MP01_START + (_nr))
128#define S5PV210_MP02(_nr) (S5PV210_GPIO_MP02_START + (_nr))
129#define S5PV210_MP03(_nr) (S5PV210_GPIO_MP03_START + (_nr))
118 130
119/* the end of the S5PV210 specific gpios */ 131/* the end of the S5PV210 specific gpios */
120#define S5PV210_GPIO_END (S5PV210_GPJ4(S5PV210_GPIO_J4_NR) + 1) 132#define S5PV210_GPIO_END (S5PV210_MP03(S5PV210_GPIO_MP03_NR) + 1)
121#define S3C_GPIO_END S5PV210_GPIO_END 133#define S3C_GPIO_END S5PV210_GPIO_END
122 134
123/* define the number of gpios we need to the one after the GPJ4() range */ 135/* define the number of gpios we need to the one after the MP03() range */
124#define ARCH_NR_GPIOS (S5PV210_GPJ4(S5PV210_GPIO_J4_NR) + \ 136#define ARCH_NR_GPIOS (S5PV210_MP03(S5PV210_GPIO_MP03_NR) + \
125 CONFIG_SAMSUNG_GPIO_EXTRA + 1) 137 CONFIG_SAMSUNG_GPIO_EXTRA + 1)
126 138
127#include <asm-generic/gpio.h> 139#include <asm-generic/gpio.h>
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h
index bcd2e82c2e2b..5adcb9f26e44 100644
--- a/arch/arm/mach-s5pv210/include/mach/map.h
+++ b/arch/arm/mach-s5pv210/include/mach/map.h
@@ -43,6 +43,10 @@
43 43
44#define S5PV210_PA_SROMC (0xE8000000) 44#define S5PV210_PA_SROMC (0xE8000000)
45 45
46#define S5PV210_PA_MDMA 0xFA200000
47#define S5PV210_PA_PDMA0 0xE0900000
48#define S5PV210_PA_PDMA1 0xE0A00000
49
46#define S5PV210_PA_VIC0 (0xF2000000) 50#define S5PV210_PA_VIC0 (0xF2000000)
47#define S5P_PA_VIC0 S5PV210_PA_VIC0 51#define S5P_PA_VIC0 S5PV210_PA_VIC0
48 52
diff --git a/arch/arm/mach-s5pv210/include/mach/pwm-clock.h b/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
index 69027fea987a..f8a9f1b330e0 100644
--- a/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
+++ b/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
@@ -1,13 +1,14 @@
1/* linux/arch/arm/mach-s5pv210/include/mach/pwm-clock.h 1/* linux/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
2 * 2 *
3 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Copyright 2008 Openmoko, Inc.
3 * Copyright 2008 Simtec Electronics 7 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 8 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/ 9 * http://armlinux.simtec.co.uk/
6 * 10 *
7 * Copyright (c) 2009 Samsung Electronics Co., Ltd. 11 * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
8 * http://www.samsung.com/
9 *
10 * Based on arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
11 * 12 *
12 * S5PV210 - pwm clock and timer support 13 * S5PV210 - pwm clock and timer support
13 * 14 *
@@ -21,14 +22,14 @@
21 22
22/** 23/**
23 * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk 24 * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
24 * @cfg: The timer TCFG1 register bits shifted down to 0. 25 * @tcfg: The timer TCFG1 register bits shifted down to 0.
25 * 26 *
26 * Return true if the given configuration from TCFG1 is a TCLK instead 27 * Return true if the given configuration from TCFG1 is a TCLK instead
27 * any of the TDIV clocks. 28 * any of the TDIV clocks.
28 */ 29 */
29static inline int pwm_cfg_src_is_tclk(unsigned long tcfg) 30static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
30{ 31{
31 return tcfg == S3C2410_TCFG1_MUX_TCLK; 32 return tcfg == S3C64XX_TCFG1_MUX_TCLK;
32} 33}
33 34
34/** 35/**
@@ -40,7 +41,7 @@ static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
40 */ 41 */
41static inline unsigned long tcfg_to_divisor(unsigned long tcfg1) 42static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
42{ 43{
43 return 1 << (1 + tcfg1); 44 return 1 << tcfg1;
44} 45}
45 46
46/** 47/**
@@ -50,7 +51,7 @@ static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
50 */ 51 */
51static inline unsigned int pwm_tdiv_has_div1(void) 52static inline unsigned int pwm_tdiv_has_div1(void)
52{ 53{
53 return 0; 54 return 1;
54} 55}
55 56
56/** 57/**
@@ -61,9 +62,9 @@ static inline unsigned int pwm_tdiv_has_div1(void)
61 */ 62 */
62static inline unsigned long pwm_tdiv_div_bits(unsigned int div) 63static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
63{ 64{
64 return ilog2(div) - 1; 65 return ilog2(div);
65} 66}
66 67
67#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK 68#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
68 69
69#endif /* __ASM_ARCH_PWMCLK_H */ 70#endif /* __ASM_ARCH_PWMCLK_H */
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 241c24a1c18f..45a1bc275f0a 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -869,9 +869,10 @@ void __init reserve_node_zero(pg_data_t *pgdat)
869 if (machine_is_p720t()) 869 if (machine_is_p720t())
870 res_size = 0x00014000; 870 res_size = 0x00014000;
871 871
872 /* H1940 and RX3715 need to reserve this for suspend */ 872 /* H1940, RX3715 and RX1950 need to reserve this for suspend */
873 873
874 if (machine_is_h1940() || machine_is_rx3715()) { 874 if (machine_is_h1940() || machine_is_rx3715()
875 || machine_is_rx1950()) {
875 reserve_bootmem_node(pgdat, 0x30003000, 0x1000, 876 reserve_bootmem_node(pgdat, 0x30003000, 0x1000,
876 BOOTMEM_DEFAULT); 877 BOOTMEM_DEFAULT);
877 reserve_bootmem_node(pgdat, 0x30081000, 0x1000, 878 reserve_bootmem_node(pgdat, 0x30081000, 0x1000,
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index 6e93ef8f3d43..3ce8f010b3c6 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -9,6 +9,7 @@ config PLAT_S3C24XX
9 select NO_IOPORT 9 select NO_IOPORT
10 select ARCH_REQUIRE_GPIOLIB 10 select ARCH_REQUIRE_GPIOLIB
11 select S3C_DEVICE_NAND 11 select S3C_DEVICE_NAND
12 select S3C_GPIO_CFG_S3C24XX
12 help 13 help
13 Base platform code for any Samsung S3C24XX device 14 Base platform code for any Samsung S3C24XX device
14 15
@@ -44,6 +45,12 @@ config S3C2410_CLOCK
44 Clock code for the S3C2410, and similar processors which 45 Clock code for the S3C2410, and similar processors which
45 is currently includes the S3C2410, S3C2440, S3C2442. 46 is currently includes the S3C2410, S3C2440, S3C2442.
46 47
48config S3C2443_CLOCK
49 bool
50 help
51 Clock code for the S3C2443 and similar processors, which includes
52 the S3C2416 and S3C2450.
53
47config S3C24XX_DCLK 54config S3C24XX_DCLK
48 bool 55 bool
49 help 56 help
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
index c2237c41141f..44aea8868f89 100644
--- a/arch/arm/plat-s3c24xx/Makefile
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_PM) += pm.o
30obj-$(CONFIG_PM) += irq-pm.o 30obj-$(CONFIG_PM) += irq-pm.o
31obj-$(CONFIG_PM) += sleep.o 31obj-$(CONFIG_PM) += sleep.o
32obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o 32obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o
33obj-$(CONFIG_S3C2443_CLOCK) += s3c2443-clock.o
33obj-$(CONFIG_S3C2410_DMA) += dma.o 34obj-$(CONFIG_S3C2410_DMA) += dma.o
34obj-$(CONFIG_S3C2410_IOTIMING) += s3c2410-iotiming.o 35obj-$(CONFIG_S3C2410_IOTIMING) += s3c2410-iotiming.o
35obj-$(CONFIG_S3C2412_IOTIMING) += s3c2412-iotiming.o 36obj-$(CONFIG_S3C2412_IOTIMING) += s3c2412-iotiming.o
diff --git a/arch/arm/plat-s3c24xx/common-smdk.c b/arch/arm/plat-s3c24xx/common-smdk.c
index 9e0e20ad2e46..7b44d0c592b5 100644
--- a/arch/arm/plat-s3c24xx/common-smdk.c
+++ b/arch/arm/plat-s3c24xx/common-smdk.c
@@ -42,6 +42,7 @@
42#include <plat/nand.h> 42#include <plat/nand.h>
43 43
44#include <plat/common-smdk.h> 44#include <plat/common-smdk.h>
45#include <plat/gpio-cfg.h>
45#include <plat/devs.h> 46#include <plat/devs.h>
46#include <plat/pm.h> 47#include <plat/pm.h>
47 48
@@ -185,10 +186,10 @@ void __init smdk_machine_init(void)
185{ 186{
186 /* Configure the LEDs (even if we have no LED support)*/ 187 /* Configure the LEDs (even if we have no LED support)*/
187 188
188 s3c2410_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT); 189 s3c_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT);
189 s3c2410_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT); 190 s3c_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT);
190 s3c2410_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT); 191 s3c_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT);
191 s3c2410_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT); 192 s3c_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT);
192 193
193 s3c2410_gpio_setpin(S3C2410_GPF(4), 1); 194 s3c2410_gpio_setpin(S3C2410_GPF(4), 1);
194 s3c2410_gpio_setpin(S3C2410_GPF(5), 1); 195 s3c2410_gpio_setpin(S3C2410_GPF(5), 1);
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index 9ca64df35bf6..76d0858c3cbb 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -49,6 +49,7 @@
49#include <plat/s3c2400.h> 49#include <plat/s3c2400.h>
50#include <plat/s3c2410.h> 50#include <plat/s3c2410.h>
51#include <plat/s3c2412.h> 51#include <plat/s3c2412.h>
52#include <plat/s3c2416.h>
52#include <plat/s3c244x.h> 53#include <plat/s3c244x.h>
53#include <plat/s3c2443.h> 54#include <plat/s3c2443.h>
54 55
@@ -57,6 +58,7 @@
57static const char name_s3c2400[] = "S3C2400"; 58static const char name_s3c2400[] = "S3C2400";
58static const char name_s3c2410[] = "S3C2410"; 59static const char name_s3c2410[] = "S3C2410";
59static const char name_s3c2412[] = "S3C2412"; 60static const char name_s3c2412[] = "S3C2412";
61static const char name_s3c2416[] = "S3C2416/S3C2450";
60static const char name_s3c2440[] = "S3C2440"; 62static const char name_s3c2440[] = "S3C2440";
61static const char name_s3c2442[] = "S3C2442"; 63static const char name_s3c2442[] = "S3C2442";
62static const char name_s3c2442b[] = "S3C2442B"; 64static const char name_s3c2442b[] = "S3C2442B";
@@ -137,6 +139,15 @@ static struct cpu_table cpu_ids[] __initdata = {
137 .init = s3c2412_init, 139 .init = s3c2412_init,
138 .name = name_s3c2412, 140 .name = name_s3c2412,
139 }, 141 },
142 { /* a strange version of the s3c2416 */
143 .idcode = 0x32450003,
144 .idmask = 0xffffffff,
145 .map_io = s3c2416_map_io,
146 .init_clocks = s3c2416_init_clocks,
147 .init_uarts = s3c2416_init_uarts,
148 .init = s3c2416_init,
149 .name = name_s3c2416,
150 },
140 { 151 {
141 .idcode = 0x32443001, 152 .idcode = 0x32443001,
142 .idmask = 0xffffffff, 153 .idmask = 0xffffffff,
@@ -170,6 +181,16 @@ static struct map_desc s3c_iodesc[] __initdata = {
170 181
171static unsigned long s3c24xx_read_idcode_v5(void) 182static unsigned long s3c24xx_read_idcode_v5(void)
172{ 183{
184#if defined(CONFIG_CPU_S3C2416)
185 /* s3c2416 is v5, with S3C24XX_GSTATUS1 instead of S3C2412_GSTATUS1 */
186
187 u32 gs = __raw_readl(S3C24XX_GSTATUS1);
188
189 /* test for s3c2416 or similar device */
190 if ((gs >> 16) == 0x3245)
191 return gs;
192#endif
193
173#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) 194#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
174 return __raw_readl(S3C2412_GSTATUS1); 195 return __raw_readl(S3C2412_GSTATUS1);
175#else 196#else
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
index 9265f09bfa58..cd5b41d0b5a4 100644
--- a/arch/arm/plat-s3c24xx/devs.c
+++ b/arch/arm/plat-s3c24xx/devs.c
@@ -21,6 +21,7 @@
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/string.h>
24 25
25#include <asm/mach/arch.h> 26#include <asm/mach/arch.h>
26#include <asm/mach/map.h> 27#include <asm/mach/map.h>
@@ -149,10 +150,14 @@ void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
149{ 150{
150 struct s3c2410fb_mach_info *npd; 151 struct s3c2410fb_mach_info *npd;
151 152
152 npd = kmalloc(sizeof(*npd), GFP_KERNEL); 153 npd = kmemdup(pd, sizeof(*npd), GFP_KERNEL);
153 if (npd) { 154 if (npd) {
154 memcpy(npd, pd, sizeof(*npd));
155 s3c_device_lcd.dev.platform_data = npd; 155 s3c_device_lcd.dev.platform_data = npd;
156 npd->displays = kmemdup(pd->displays,
157 sizeof(struct s3c2410fb_display) * npd->num_displays,
158 GFP_KERNEL);
159 if (!npd->displays)
160 printk(KERN_ERR "no memory for LCD display data\n");
156 } else { 161 } else {
157 printk(KERN_ERR "no memory for LCD platform data\n"); 162 printk(KERN_ERR "no memory for LCD platform data\n");
158 } 163 }
@@ -338,14 +343,6 @@ struct platform_device s3c_device_adc = {
338 .resource = s3c_adc_resource, 343 .resource = s3c_adc_resource,
339}; 344};
340 345
341/* HWMON */
342
343struct platform_device s3c_device_hwmon = {
344 .name = "s3c-hwmon",
345 .id = -1,
346 .dev.parent = &s3c_device_adc.dev,
347};
348
349/* SDI */ 346/* SDI */
350 347
351static struct resource s3c_sdi_resource[] = { 348static struct resource s3c_sdi_resource[] = {
@@ -371,7 +368,7 @@ struct platform_device s3c_device_sdi = {
371 368
372EXPORT_SYMBOL(s3c_device_sdi); 369EXPORT_SYMBOL(s3c_device_sdi);
373 370
374void s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata) 371void __init s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata)
375{ 372{
376 struct s3c24xx_mci_pdata *npd; 373 struct s3c24xx_mci_pdata *npd;
377 374
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index 93827b3d4e84..6ad274e7593d 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -1104,7 +1104,7 @@ EXPORT_SYMBOL(s3c2410_dma_config);
1104 * devaddr: physical address of the source 1104 * devaddr: physical address of the source
1105*/ 1105*/
1106 1106
1107int s3c2410_dma_devconfig(int channel, 1107int s3c2410_dma_devconfig(unsigned int channel,
1108 enum s3c2410_dmasrc source, 1108 enum s3c2410_dmasrc source,
1109 unsigned long devaddr) 1109 unsigned long devaddr)
1110{ 1110{
diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c
index 5467470badfd..2f3d7c089dfa 100644
--- a/arch/arm/plat-s3c24xx/gpio.c
+++ b/arch/arm/plat-s3c24xx/gpio.c
@@ -1,6 +1,6 @@
1/* linux/arch/arm/plat-s3c24xx/gpio.c 1/* linux/arch/arm/plat-s3c24xx/gpio.c
2 * 2 *
3 * Copyright (c) 2004-2005 Simtec Electronics 3 * Copyright (c) 2004-2010 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
5 * 5 *
6 * S3C24XX GPIO support 6 * S3C24XX GPIO support
@@ -20,12 +20,12 @@
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/ 21*/
22 22
23
24#include <linux/kernel.h> 23#include <linux/kernel.h>
25#include <linux/init.h> 24#include <linux/init.h>
26#include <linux/module.h> 25#include <linux/module.h>
27#include <linux/interrupt.h> 26#include <linux/interrupt.h>
28#include <linux/ioport.h> 27#include <linux/ioport.h>
28#include <linux/gpio.h>
29#include <linux/io.h> 29#include <linux/io.h>
30 30
31#include <mach/hardware.h> 31#include <mach/hardware.h>
@@ -34,133 +34,46 @@
34 34
35#include <mach/regs-gpio.h> 35#include <mach/regs-gpio.h>
36 36
37void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function) 37#include <plat/gpio-core.h>
38{
39 void __iomem *base = S3C24XX_GPIO_BASE(pin);
40 unsigned long mask;
41 unsigned long con;
42 unsigned long flags;
43 38
44 if (pin < S3C2410_GPIO_BANKB) { 39/* gpiolib wrappers until these are totally eliminated */
45 mask = 1 << S3C2410_GPIO_OFFSET(pin);
46 } else {
47 mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
48 }
49
50 switch (function) {
51 case S3C2410_GPIO_LEAVE:
52 mask = 0;
53 function = 0;
54 break;
55
56 case S3C2410_GPIO_INPUT:
57 case S3C2410_GPIO_OUTPUT:
58 case S3C2410_GPIO_SFN2:
59 case S3C2410_GPIO_SFN3:
60 if (pin < S3C2410_GPIO_BANKB) {
61 function -= 1;
62 function &= 1;
63 function <<= S3C2410_GPIO_OFFSET(pin);
64 } else {
65 function &= 3;
66 function <<= S3C2410_GPIO_OFFSET(pin)*2;
67 }
68 }
69
70 /* modify the specified register wwith IRQs off */
71
72 local_irq_save(flags);
73
74 con = __raw_readl(base + 0x00);
75 con &= ~mask;
76 con |= function;
77
78 __raw_writel(con, base + 0x00);
79
80 local_irq_restore(flags);
81}
82
83EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
84
85unsigned int s3c2410_gpio_getcfg(unsigned int pin)
86{
87 void __iomem *base = S3C24XX_GPIO_BASE(pin);
88 unsigned long val = __raw_readl(base);
89
90 if (pin < S3C2410_GPIO_BANKB) {
91 val >>= S3C2410_GPIO_OFFSET(pin);
92 val &= 1;
93 val += 1;
94 } else {
95 val >>= S3C2410_GPIO_OFFSET(pin)*2;
96 val &= 3;
97 }
98
99 return val | S3C2410_GPIO_INPUT;
100}
101
102EXPORT_SYMBOL(s3c2410_gpio_getcfg);
103 40
104void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) 41void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
105{ 42{
106 void __iomem *base = S3C24XX_GPIO_BASE(pin); 43 int ret;
107 unsigned long offs = S3C2410_GPIO_OFFSET(pin);
108 unsigned long flags;
109 unsigned long up;
110 44
111 if (pin < S3C2410_GPIO_BANKB) 45 WARN_ON(to); /* should be none of these left */
112 return;
113 46
114 local_irq_save(flags); 47 if (!to) {
115 48 /* if pull is enabled, try first with up, and if that
116 up = __raw_readl(base + 0x08); 49 * fails, try using down */
117 up &= ~(1L << offs);
118 up |= to << offs;
119 __raw_writel(up, base + 0x08);
120 50
121 local_irq_restore(flags); 51 ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP);
52 if (ret)
53 s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN);
54 } else {
55 s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE);
56 }
122} 57}
123
124EXPORT_SYMBOL(s3c2410_gpio_pullup); 58EXPORT_SYMBOL(s3c2410_gpio_pullup);
125 59
126int s3c2410_gpio_getpull(unsigned int pin)
127{
128 void __iomem *base = S3C24XX_GPIO_BASE(pin);
129 unsigned long offs = S3C2410_GPIO_OFFSET(pin);
130
131 if (pin < S3C2410_GPIO_BANKB)
132 return -EINVAL;
133
134 return (__raw_readl(base + 0x08) & (1L << offs)) ? 1 : 0;
135}
136
137EXPORT_SYMBOL(s3c2410_gpio_getpull);
138
139void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) 60void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
140{ 61{
141 void __iomem *base = S3C24XX_GPIO_BASE(pin); 62 /* do this via gpiolib until all users removed */
142 unsigned long offs = S3C2410_GPIO_OFFSET(pin);
143 unsigned long flags;
144 unsigned long dat;
145 63
146 local_irq_save(flags); 64 gpio_request(pin, "temporary");
147 65 gpio_set_value(pin, to);
148 dat = __raw_readl(base + 0x04); 66 gpio_free(pin);
149 dat &= ~(1 << offs);
150 dat |= to << offs;
151 __raw_writel(dat, base + 0x04);
152
153 local_irq_restore(flags);
154} 67}
155 68
156EXPORT_SYMBOL(s3c2410_gpio_setpin); 69EXPORT_SYMBOL(s3c2410_gpio_setpin);
157 70
158unsigned int s3c2410_gpio_getpin(unsigned int pin) 71unsigned int s3c2410_gpio_getpin(unsigned int pin)
159{ 72{
160 void __iomem *base = S3C24XX_GPIO_BASE(pin); 73 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
161 unsigned long offs = S3C2410_GPIO_OFFSET(pin); 74 unsigned long offs = pin - chip->chip.base;
162 75
163 return __raw_readl(base + 0x04) & (1<< offs); 76 return __raw_readl(chip->base + 0x04) & (1<< offs);
164} 77}
165 78
166EXPORT_SYMBOL(s3c2410_gpio_getpin); 79EXPORT_SYMBOL(s3c2410_gpio_getpin);
@@ -181,22 +94,3 @@ unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
181} 94}
182 95
183EXPORT_SYMBOL(s3c2410_modify_misccr); 96EXPORT_SYMBOL(s3c2410_modify_misccr);
184
185int s3c2410_gpio_getirq(unsigned int pin)
186{
187 if (pin < S3C2410_GPF(0) || pin > S3C2410_GPG(15))
188 return -EINVAL; /* not valid interrupts */
189
190 if (pin < S3C2410_GPG(0) && pin > S3C2410_GPF(7))
191 return -EINVAL; /* not valid pin */
192
193 if (pin < S3C2410_GPF(4))
194 return (pin - S3C2410_GPF(0)) + IRQ_EINT0;
195
196 if (pin < S3C2410_GPG(0))
197 return (pin - S3C2410_GPF(4)) + IRQ_EINT4;
198
199 return (pin - S3C2410_GPG(0)) + IRQ_EINT8;
200}
201
202EXPORT_SYMBOL(s3c2410_gpio_getirq);
diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c
index 4f0f11a6a677..4c0896f2572d 100644
--- a/arch/arm/plat-s3c24xx/gpiolib.c
+++ b/arch/arm/plat-s3c24xx/gpiolib.c
@@ -1,6 +1,6 @@
1/* linux/arch/arm/plat-s3c24xx/gpiolib.c 1/* linux/arch/arm/plat-s3c24xx/gpiolib.c
2 * 2 *
3 * Copyright (c) 2008 Simtec Electronics 3 * Copyright (c) 2008-2010 Simtec Electronics
4 * http://armlinux.simtec.co.uk/ 4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk> 5 * Ben Dooks <ben@simtec.co.uk>
6 * 6 *
@@ -21,6 +21,8 @@
21#include <linux/gpio.h> 21#include <linux/gpio.h>
22 22
23#include <plat/gpio-core.h> 23#include <plat/gpio-core.h>
24#include <plat/gpio-cfg.h>
25#include <plat/gpio-cfg-helpers.h>
24#include <mach/hardware.h> 26#include <mach/hardware.h>
25#include <asm/irq.h> 27#include <asm/irq.h>
26#include <plat/pm.h> 28#include <plat/pm.h>
@@ -77,10 +79,21 @@ static int s3c24xx_gpiolib_bankg_toirq(struct gpio_chip *chip, unsigned offset)
77 return IRQ_EINT8 + offset; 79 return IRQ_EINT8 + offset;
78} 80}
79 81
82static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
83 .set_config = s3c_gpio_setcfg_s3c24xx_a,
84 .get_config = s3c_gpio_getcfg_s3c24xx_a,
85};
86
87struct s3c_gpio_cfg s3c24xx_gpiocfg_default = {
88 .set_config = s3c_gpio_setcfg_s3c24xx,
89 .get_config = s3c_gpio_getcfg_s3c24xx,
90};
91
80struct s3c_gpio_chip s3c24xx_gpios[] = { 92struct s3c_gpio_chip s3c24xx_gpios[] = {
81 [0] = { 93 [0] = {
82 .base = S3C2410_GPACON, 94 .base = S3C2410_GPACON,
83 .pm = __gpio_pm(&s3c_gpio_pm_1bit), 95 .pm = __gpio_pm(&s3c_gpio_pm_1bit),
96 .config = &s3c24xx_gpiocfg_banka,
84 .chip = { 97 .chip = {
85 .base = S3C2410_GPA(0), 98 .base = S3C2410_GPA(0),
86 .owner = THIS_MODULE, 99 .owner = THIS_MODULE,
@@ -161,15 +174,58 @@ struct s3c_gpio_chip s3c24xx_gpios[] = {
161 .ngpio = 11, 174 .ngpio = 11,
162 }, 175 },
163 }, 176 },
177 /* GPIOS for the S3C2443 and later devices. */
178 {
179 .base = S3C2440_GPJCON,
180 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
181 .chip = {
182 .base = S3C2410_GPJ(0),
183 .owner = THIS_MODULE,
184 .label = "GPIOJ",
185 .ngpio = 16,
186 },
187 }, {
188 .base = S3C2443_GPKCON,
189 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
190 .chip = {
191 .base = S3C2410_GPK(0),
192 .owner = THIS_MODULE,
193 .label = "GPIOK",
194 .ngpio = 16,
195 },
196 }, {
197 .base = S3C2443_GPLCON,
198 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
199 .chip = {
200 .base = S3C2410_GPL(0),
201 .owner = THIS_MODULE,
202 .label = "GPIOL",
203 .ngpio = 15,
204 },
205 }, {
206 .base = S3C2443_GPMCON,
207 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
208 .chip = {
209 .base = S3C2410_GPM(0),
210 .owner = THIS_MODULE,
211 .label = "GPIOM",
212 .ngpio = 2,
213 },
214 },
164}; 215};
165 216
217
166static __init int s3c24xx_gpiolib_init(void) 218static __init int s3c24xx_gpiolib_init(void)
167{ 219{
168 struct s3c_gpio_chip *chip = s3c24xx_gpios; 220 struct s3c_gpio_chip *chip = s3c24xx_gpios;
169 int gpn; 221 int gpn;
170 222
171 for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++) 223 for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++) {
224 if (!chip->config)
225 chip->config = &s3c24xx_gpiocfg_default;
226
172 s3c_gpiolib_add(chip); 227 s3c_gpiolib_add(chip);
228 }
173 229
174 return 0; 230 return 0;
175} 231}
diff --git a/arch/arm/plat-s3c24xx/include/plat/pll.h b/arch/arm/plat-s3c24xx/include/plat/pll.h
index 7ea8bffa7a9c..005729a1077a 100644
--- a/arch/arm/plat-s3c24xx/include/plat/pll.h
+++ b/arch/arm/plat-s3c24xx/include/plat/pll.h
@@ -35,3 +35,28 @@ s3c24xx_get_pll(unsigned int pllval, unsigned int baseclk)
35 35
36 return (unsigned int)fvco; 36 return (unsigned int)fvco;
37} 37}
38
39#define S3C2416_PLL_M_SHIFT (14)
40#define S3C2416_PLL_P_SHIFT (5)
41#define S3C2416_PLL_S_MASK (7)
42#define S3C2416_PLL_M_MASK ((1 << 10) - 1)
43#define S3C2416_PLL_P_MASK (63)
44
45static inline unsigned int
46s3c2416_get_pll(unsigned int pllval, unsigned int baseclk)
47{
48 unsigned int m, p, s;
49 uint64_t fvco;
50
51 m = pllval >> S3C2416_PLL_M_SHIFT;
52 p = pllval >> S3C2416_PLL_P_SHIFT;
53
54 s = pllval & S3C2416_PLL_S_MASK;
55 m &= S3C2416_PLL_M_MASK;
56 p &= S3C2416_PLL_P_MASK;
57
58 fvco = (uint64_t)baseclk * m;
59 do_div(fvco, (p << s));
60
61 return (unsigned int)fvco;
62}
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2416.h b/arch/arm/plat-s3c24xx/include/plat/s3c2416.h
new file mode 100644
index 000000000000..dc3c0907d221
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2416.h
@@ -0,0 +1,31 @@
1/* linux/include/asm-arm/plat-s3c24xx/s3c2443.h
2 *
3 * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>
4 *
5 * Header file for s3c2416 cpu support
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10*/
11
12#ifdef CONFIG_CPU_S3C2416
13
14struct s3c2410_uartcfg;
15
16extern int s3c2416_init(void);
17
18extern void s3c2416_map_io(void);
19
20extern void s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no);
21
22extern void s3c2416_init_clocks(int xtal);
23
24extern int s3c2416_baseclk_add(void);
25
26#else
27#define s3c2416_init_clocks NULL
28#define s3c2416_init_uarts NULL
29#define s3c2416_map_io NULL
30#define s3c2416_init NULL
31#endif
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2443.h b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
index 815b107ed890..a19715feb798 100644
--- a/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
@@ -30,3 +30,22 @@ extern int s3c2443_baseclk_add(void);
30#define s3c2443_map_io NULL 30#define s3c2443_map_io NULL
31#define s3c2443_init NULL 31#define s3c2443_init NULL
32#endif 32#endif
33
34/* common code used by s3c2443 and others.
35 * note, not to be used outside of arch/arm/mach-s3c* */
36
37struct clk; /* some files don't need clk.h otherwise */
38
39typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base);
40typedef unsigned int (*fdiv_fn)(unsigned long clkcon0);
41
42extern void s3c2443_common_setup_clocks(pll_fn get_mpll, fdiv_fn fdiv);
43extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, fdiv_fn fdiv);
44
45extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable);
46extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable);
47extern int s3c2443_clkcon_enable_s(struct clk *clk, int enable);
48
49extern struct clksrc_clk clk_epllref;
50extern struct clksrc_clk clk_esysclk;
51extern struct clksrc_clk clk_msysclk;
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c
index 3620dd299095..60627e63a254 100644
--- a/arch/arm/plat-s3c24xx/pm.c
+++ b/arch/arm/plat-s3c24xx/pm.c
@@ -43,6 +43,7 @@
43 43
44#include <asm/mach/time.h> 44#include <asm/mach/time.h>
45 45
46#include <plat/gpio-cfg.h>
46#include <plat/pm.h> 47#include <plat/pm.h>
47 48
48#define PFX "s3c24xx-pm: " 49#define PFX "s3c24xx-pm: "
@@ -90,22 +91,22 @@ static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
90{ 91{
91 unsigned long irqstate; 92 unsigned long irqstate;
92 unsigned long pinstate; 93 unsigned long pinstate;
93 int irq = s3c2410_gpio_getirq(pin); 94 int irq = gpio_to_irq(pin);
94 95
95 if (irqoffs < 4) 96 if (irqoffs < 4)
96 irqstate = s3c_irqwake_intmask & (1L<<irqoffs); 97 irqstate = s3c_irqwake_intmask & (1L<<irqoffs);
97 else 98 else
98 irqstate = s3c_irqwake_eintmask & (1L<<irqoffs); 99 irqstate = s3c_irqwake_eintmask & (1L<<irqoffs);
99 100
100 pinstate = s3c2410_gpio_getcfg(pin); 101 pinstate = s3c_gpio_getcfg(pin);
101 102
102 if (!irqstate) { 103 if (!irqstate) {
103 if (pinstate == S3C2410_GPIO_IRQ) 104 if (pinstate == S3C2410_GPIO_IRQ)
104 S3C_PMDBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin); 105 S3C_PMDBG("Leaving IRQ %d (pin %d) as is\n", irq, pin);
105 } else { 106 } else {
106 if (pinstate == S3C2410_GPIO_IRQ) { 107 if (pinstate == S3C2410_GPIO_IRQ) {
107 S3C_PMDBG("Disabling IRQ %d (pin %d)\n", irq, pin); 108 S3C_PMDBG("Disabling IRQ %d (pin %d)\n", irq, pin);
108 s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT); 109 s3c_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
109 } 110 }
110 } 111 }
111} 112}
diff --git a/arch/arm/plat-s3c24xx/s3c2410-clock.c b/arch/arm/plat-s3c24xx/s3c2410-clock.c
index b61bdb793734..9ecc5d913679 100644
--- a/arch/arm/plat-s3c24xx/s3c2410-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c2410-clock.c
@@ -87,7 +87,7 @@ static int s3c2410_upll_enable(struct clk *clk, int enable)
87 87
88/* standard clock definitions */ 88/* standard clock definitions */
89 89
90static struct clk init_clocks_disable[] = { 90static struct clk init_clocks_off[] = {
91 { 91 {
92 .name = "nand", 92 .name = "nand",
93 .id = -1, 93 .id = -1,
@@ -249,17 +249,8 @@ int __init s3c2410_baseclk_add(void)
249 249
250 /* install (and disable) the clocks we do not need immediately */ 250 /* install (and disable) the clocks we do not need immediately */
251 251
252 clkp = init_clocks_disable; 252 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
253 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { 253 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
254
255 ret = s3c24xx_register_clock(clkp);
256 if (ret < 0) {
257 printk(KERN_ERR "Failed to register clock %s (%d)\n",
258 clkp->name, ret);
259 }
260
261 s3c2410_clkcon_enable(clkp, 0);
262 }
263 254
264 /* show the clock-slow value */ 255 /* show the clock-slow value */
265 256
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
new file mode 100644
index 000000000000..461f070eb62d
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c
@@ -0,0 +1,472 @@
1/* linux/arch/arm/plat-s3c24xx/s3c2443-clock.c
2 *
3 * Copyright (c) 2007, 2010 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2443 Clock control suport - common code
7 */
8
9#include <linux/init.h>
10#include <linux/clk.h>
11#include <linux/io.h>
12
13#include <mach/regs-s3c2443-clock.h>
14
15#include <plat/s3c2443.h>
16#include <plat/clock.h>
17#include <plat/clock-clksrc.h>
18#include <plat/cpu.h>
19
20#include <plat/cpu-freq.h>
21
22
23static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
24{
25 u32 ctrlbit = clk->ctrlbit;
26 u32 con = __raw_readl(reg);
27
28 if (enable)
29 con |= ctrlbit;
30 else
31 con &= ~ctrlbit;
32
33 __raw_writel(con, reg);
34 return 0;
35}
36
37int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
38{
39 return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
40}
41
42int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
43{
44 return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
45}
46
47int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
48{
49 return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
50}
51
52/* mpllref is a direct descendant of clk_xtal by default, but it is not
53 * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
54 * such directly equating the two source clocks is impossible.
55 */
56struct clk clk_mpllref = {
57 .name = "mpllref",
58 .parent = &clk_xtal,
59 .id = -1,
60};
61
62static struct clk *clk_epllref_sources[] = {
63 [0] = &clk_mpllref,
64 [1] = &clk_mpllref,
65 [2] = &clk_xtal,
66 [3] = &clk_ext,
67};
68
69struct clksrc_clk clk_epllref = {
70 .clk = {
71 .name = "epllref",
72 .id = -1,
73 },
74 .sources = &(struct clksrc_sources) {
75 .sources = clk_epllref_sources,
76 .nr_sources = ARRAY_SIZE(clk_epllref_sources),
77 },
78 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
79};
80
81/* esysclk
82 *
83 * this is sourced from either the EPLL or the EPLLref clock
84*/
85
86static struct clk *clk_sysclk_sources[] = {
87 [0] = &clk_epllref.clk,
88 [1] = &clk_epll,
89};
90
91struct clksrc_clk clk_esysclk = {
92 .clk = {
93 .name = "esysclk",
94 .parent = &clk_epll,
95 .id = -1,
96 },
97 .sources = &(struct clksrc_sources) {
98 .sources = clk_sysclk_sources,
99 .nr_sources = ARRAY_SIZE(clk_sysclk_sources),
100 },
101 .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
102};
103
104static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
105{
106 unsigned long parent_rate = clk_get_rate(clk->parent);
107 unsigned long div = __raw_readl(S3C2443_CLKDIV0);
108
109 div &= S3C2443_CLKDIV0_EXTDIV_MASK;
110 div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1); /* x2 */
111
112 return parent_rate / (div + 1);
113}
114
115static struct clk clk_mdivclk = {
116 .name = "mdivclk",
117 .parent = &clk_mpllref,
118 .id = -1,
119 .ops = &(struct clk_ops) {
120 .get_rate = s3c2443_getrate_mdivclk,
121 },
122};
123
124static struct clk *clk_msysclk_sources[] = {
125 [0] = &clk_mpllref,
126 [1] = &clk_mpll,
127 [2] = &clk_mdivclk,
128 [3] = &clk_mpllref,
129};
130
131struct clksrc_clk clk_msysclk = {
132 .clk = {
133 .name = "msysclk",
134 .parent = &clk_xtal,
135 .id = -1,
136 },
137 .sources = &(struct clksrc_sources) {
138 .sources = clk_msysclk_sources,
139 .nr_sources = ARRAY_SIZE(clk_msysclk_sources),
140 },
141 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
142};
143
144/* prediv
145 *
146 * this divides the msysclk down to pass to h/p/etc.
147 */
148
149static unsigned long s3c2443_prediv_getrate(struct clk *clk)
150{
151 unsigned long rate = clk_get_rate(clk->parent);
152 unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
153
154 clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
155 clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
156
157 return rate / (clkdiv0 + 1);
158}
159
160static struct clk clk_prediv = {
161 .name = "prediv",
162 .id = -1,
163 .parent = &clk_msysclk.clk,
164 .ops = &(struct clk_ops) {
165 .get_rate = s3c2443_prediv_getrate,
166 },
167};
168
169/* usbhost
170 *
171 * usb host bus-clock, usually 48MHz to provide USB bus clock timing
172*/
173
174static struct clksrc_clk clk_usb_bus_host = {
175 .clk = {
176 .name = "usb-bus-host-parent",
177 .id = -1,
178 .parent = &clk_esysclk.clk,
179 .ctrlbit = S3C2443_SCLKCON_USBHOST,
180 .enable = s3c2443_clkcon_enable_s,
181 },
182 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
183};
184
185/* common clksrc clocks */
186
187static struct clksrc_clk clksrc_clks[] = {
188 {
189 /* ART baud-rate clock sourced from esysclk via a divisor */
190 .clk = {
191 .name = "uartclk",
192 .id = -1,
193 .parent = &clk_esysclk.clk,
194 },
195 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
196 }, {
197 /* camera interface bus-clock, divided down from esysclk */
198 .clk = {
199 .name = "camif-upll", /* same as 2440 name */
200 .id = -1,
201 .parent = &clk_esysclk.clk,
202 .ctrlbit = S3C2443_SCLKCON_CAMCLK,
203 .enable = s3c2443_clkcon_enable_s,
204 },
205 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
206 }, {
207 .clk = {
208 .name = "display-if",
209 .id = -1,
210 .parent = &clk_esysclk.clk,
211 .ctrlbit = S3C2443_SCLKCON_DISPCLK,
212 .enable = s3c2443_clkcon_enable_s,
213 },
214 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
215 },
216};
217
218
219static struct clk init_clocks_off[] = {
220 {
221 .name = "adc",
222 .id = -1,
223 .parent = &clk_p,
224 .enable = s3c2443_clkcon_enable_p,
225 .ctrlbit = S3C2443_PCLKCON_ADC,
226 }, {
227 .name = "i2c",
228 .id = -1,
229 .parent = &clk_p,
230 .enable = s3c2443_clkcon_enable_p,
231 .ctrlbit = S3C2443_PCLKCON_IIC,
232 }
233};
234
235static struct clk init_clocks[] = {
236 {
237 .name = "dma",
238 .id = 0,
239 .parent = &clk_h,
240 .enable = s3c2443_clkcon_enable_h,
241 .ctrlbit = S3C2443_HCLKCON_DMA0,
242 }, {
243 .name = "dma",
244 .id = 1,
245 .parent = &clk_h,
246 .enable = s3c2443_clkcon_enable_h,
247 .ctrlbit = S3C2443_HCLKCON_DMA1,
248 }, {
249 .name = "dma",
250 .id = 2,
251 .parent = &clk_h,
252 .enable = s3c2443_clkcon_enable_h,
253 .ctrlbit = S3C2443_HCLKCON_DMA2,
254 }, {
255 .name = "dma",
256 .id = 3,
257 .parent = &clk_h,
258 .enable = s3c2443_clkcon_enable_h,
259 .ctrlbit = S3C2443_HCLKCON_DMA3,
260 }, {
261 .name = "dma",
262 .id = 4,
263 .parent = &clk_h,
264 .enable = s3c2443_clkcon_enable_h,
265 .ctrlbit = S3C2443_HCLKCON_DMA4,
266 }, {
267 .name = "dma",
268 .id = 5,
269 .parent = &clk_h,
270 .enable = s3c2443_clkcon_enable_h,
271 .ctrlbit = S3C2443_HCLKCON_DMA5,
272 }, {
273 .name = "hsmmc",
274 .id = 0,
275 .parent = &clk_h,
276 .enable = s3c2443_clkcon_enable_h,
277 .ctrlbit = S3C2443_HCLKCON_HSMMC,
278 }, {
279 .name = "gpio",
280 .id = -1,
281 .parent = &clk_p,
282 .enable = s3c2443_clkcon_enable_p,
283 .ctrlbit = S3C2443_PCLKCON_GPIO,
284 }, {
285 .name = "usb-host",
286 .id = -1,
287 .parent = &clk_h,
288 .enable = s3c2443_clkcon_enable_h,
289 .ctrlbit = S3C2443_HCLKCON_USBH,
290 }, {
291 .name = "usb-device",
292 .id = -1,
293 .parent = &clk_h,
294 .enable = s3c2443_clkcon_enable_h,
295 .ctrlbit = S3C2443_HCLKCON_USBD,
296 }, {
297 .name = "lcd",
298 .id = -1,
299 .parent = &clk_h,
300 .enable = s3c2443_clkcon_enable_h,
301 .ctrlbit = S3C2443_HCLKCON_LCDC,
302
303 }, {
304 .name = "timers",
305 .id = -1,
306 .parent = &clk_p,
307 .enable = s3c2443_clkcon_enable_p,
308 .ctrlbit = S3C2443_PCLKCON_PWMT,
309 }, {
310 .name = "cfc",
311 .id = -1,
312 .parent = &clk_h,
313 .enable = s3c2443_clkcon_enable_h,
314 .ctrlbit = S3C2443_HCLKCON_CFC,
315 }, {
316 .name = "ssmc",
317 .id = -1,
318 .parent = &clk_h,
319 .enable = s3c2443_clkcon_enable_h,
320 .ctrlbit = S3C2443_HCLKCON_SSMC,
321 }, {
322 .name = "uart",
323 .id = 0,
324 .parent = &clk_p,
325 .enable = s3c2443_clkcon_enable_p,
326 .ctrlbit = S3C2443_PCLKCON_UART0,
327 }, {
328 .name = "uart",
329 .id = 1,
330 .parent = &clk_p,
331 .enable = s3c2443_clkcon_enable_p,
332 .ctrlbit = S3C2443_PCLKCON_UART1,
333 }, {
334 .name = "uart",
335 .id = 2,
336 .parent = &clk_p,
337 .enable = s3c2443_clkcon_enable_p,
338 .ctrlbit = S3C2443_PCLKCON_UART2,
339 }, {
340 .name = "uart",
341 .id = 3,
342 .parent = &clk_p,
343 .enable = s3c2443_clkcon_enable_p,
344 .ctrlbit = S3C2443_PCLKCON_UART3,
345 }, {
346 .name = "rtc",
347 .id = -1,
348 .parent = &clk_p,
349 .enable = s3c2443_clkcon_enable_p,
350 .ctrlbit = S3C2443_PCLKCON_RTC,
351 }, {
352 .name = "watchdog",
353 .id = -1,
354 .parent = &clk_p,
355 .ctrlbit = S3C2443_PCLKCON_WDT,
356 }, {
357 .name = "ac97",
358 .id = -1,
359 .parent = &clk_p,
360 .ctrlbit = S3C2443_PCLKCON_AC97,
361 }, {
362 .name = "nand",
363 .id = -1,
364 .parent = &clk_h,
365 }, {
366 .name = "usb-bus-host",
367 .id = -1,
368 .parent = &clk_usb_bus_host.clk,
369 }
370};
371
372static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
373{
374 clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
375
376 return clkcon0 + 1;
377}
378
379/* EPLLCON compatible enough to get on/off information */
380
381void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll,
382 fdiv_fn get_fdiv)
383{
384 unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
385 unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
386 unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
387 struct clk *xtal_clk;
388 unsigned long xtal;
389 unsigned long pll;
390 unsigned long fclk;
391 unsigned long hclk;
392 unsigned long pclk;
393 int ptr;
394
395 xtal_clk = clk_get(NULL, "xtal");
396 xtal = clk_get_rate(xtal_clk);
397 clk_put(xtal_clk);
398
399 pll = get_mpll(mpllcon, xtal);
400 clk_msysclk.clk.rate = pll;
401
402 fclk = pll / get_fdiv(clkdiv0);
403 hclk = s3c2443_prediv_getrate(&clk_prediv);
404 hclk /= s3c2443_get_hdiv(clkdiv0);
405 pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
406
407 s3c24xx_setup_clocks(fclk, hclk, pclk);
408
409 printk("CPU: MPLL %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
410 (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on",
411 print_mhz(pll), print_mhz(fclk),
412 print_mhz(hclk), print_mhz(pclk));
413
414 for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++)
415 s3c_set_clksrc(&clksrc_clks[ptr], true);
416
417 /* ensure usb bus clock is within correct rate of 48MHz */
418
419 if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
420 printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
421 clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
422 }
423
424 printk("CPU: EPLL %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
425 (epllcon & S3C2443_PLLCON_OFF) ? "off":"on",
426 print_mhz(clk_get_rate(&clk_epll)),
427 print_mhz(clk_get_rate(&clk_usb_bus)));
428}
429
430static struct clk *clks[] __initdata = {
431 &clk_prediv,
432 &clk_mpllref,
433 &clk_mdivclk,
434 &clk_ext,
435 &clk_epll,
436 &clk_usb_bus,
437};
438
439static struct clksrc_clk *clksrcs[] __initdata = {
440 &clk_usb_bus_host,
441 &clk_epllref,
442 &clk_esysclk,
443 &clk_msysclk,
444};
445
446void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
447 fdiv_fn get_fdiv)
448{
449 int ptr;
450
451 /* s3c2443 parents h and p clocks from prediv */
452 clk_h.parent = &clk_prediv;
453 clk_p.parent = &clk_prediv;
454
455 clk_usb_bus.parent = &clk_usb_bus_host.clk;
456 clk_epll.parent = &clk_epllref.clk;
457
458 s3c24xx_register_baseclocks(xtal);
459 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
460
461 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
462 s3c_register_clksrc(clksrcs[ptr], 1);
463
464 s3c_register_clksrc(clksrc_clks, ARRAY_SIZE(clksrc_clks));
465 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
466
467 /* See s3c2443/etc notes on disabling clocks at init time */
468 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
469 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
470
471 s3c2443_common_setup_clocks(get_mpll, get_fdiv);
472}
diff --git a/arch/arm/plat-s3c24xx/setup-i2c.c b/arch/arm/plat-s3c24xx/setup-i2c.c
index 71a6accf114e..9e90a7cbd1d6 100644
--- a/arch/arm/plat-s3c24xx/setup-i2c.c
+++ b/arch/arm/plat-s3c24xx/setup-i2c.c
@@ -15,12 +15,13 @@
15 15
16struct platform_device; 16struct platform_device;
17 17
18#include <plat/gpio-cfg.h>
18#include <plat/iic.h> 19#include <plat/iic.h>
19#include <mach/hardware.h> 20#include <mach/hardware.h>
20#include <mach/regs-gpio.h> 21#include <mach/regs-gpio.h>
21 22
22void s3c_i2c0_cfg_gpio(struct platform_device *dev) 23void s3c_i2c0_cfg_gpio(struct platform_device *dev)
23{ 24{
24 s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA); 25 s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA);
25 s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL); 26 s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL);
26} 27}
diff --git a/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c b/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
index da7a61728c18..9793544a6ace 100644
--- a/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
+++ b/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
@@ -21,16 +21,16 @@ void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi,
21 int enable) 21 int enable)
22{ 22{
23 if (enable) { 23 if (enable) {
24 s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0); 24 s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0);
25 s3c2410_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0); 25 s3c_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0);
26 s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0); 26 s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0);
27 s3c2410_gpio_pullup(S3C2410_GPE(11), 0); 27 s3c2410_gpio_pullup(S3C2410_GPE(11), 0);
28 s3c2410_gpio_pullup(S3C2410_GPE(13), 0); 28 s3c2410_gpio_pullup(S3C2410_GPE(13), 0);
29 } else { 29 } else {
30 s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT); 30 s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT);
31 s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT); 31 s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT);
32 s3c2410_gpio_pullup(S3C2410_GPE(11), 1); 32 s3c_gpio_cfgpull(S3C2410_GPE(11), S3C_GPIO_PULL_NONE);
33 s3c2410_gpio_pullup(S3C2410_GPE(12), 1); 33 s3c_gpio_cfgpull(S3C2410_GPE(12), S3C_GPIO_PULL_NONE);
34 s3c2410_gpio_pullup(S3C2410_GPE(13), 1); 34 s3c_gpio_cfgpull(S3C2410_GPE(13), S3C_GPIO_PULL_NONE);
35 } 35 }
36} 36}
diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
index 89fcf5308cf6..db9e9e477ec1 100644
--- a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
+++ b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
@@ -23,16 +23,16 @@ void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi,
23 23
24 printk(KERN_INFO "%s(%d)\n", __func__, enable); 24 printk(KERN_INFO "%s(%d)\n", __func__, enable);
25 if (enable) { 25 if (enable) {
26 s3c2410_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1); 26 s3c_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1);
27 s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1); 27 s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1);
28 s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1); 28 s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1);
29 s3c2410_gpio_pullup(S3C2410_GPD(10), 0); 29 s3c2410_gpio_pullup(S3C2410_GPD(10), 0);
30 s3c2410_gpio_pullup(S3C2410_GPD(9), 0); 30 s3c2410_gpio_pullup(S3C2410_GPD(9), 0);
31 } else { 31 } else {
32 s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT); 32 s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT);
33 s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT); 33 s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT);
34 s3c2410_gpio_pullup(S3C2410_GPD(10), 1); 34 s3c_gpio_cfgpull(S3C2410_GPD(10), S3C_GPIO_PULL_NONE);
35 s3c2410_gpio_pullup(S3C2410_GPD(9), 1); 35 s3c_gpio_cfgpull(S3C2410_GPD(9), S3C_GPIO_PULL_NONE);
36 s3c2410_gpio_pullup(S3C2410_GPD(8), 1); 36 s3c_gpio_cfgpull(S3C2410_GPD(8), S3C_GPIO_PULL_NONE);
37 } 37 }
38} 38}
diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c b/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c
index 86b9edc67413..8ea663a438bb 100644
--- a/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c
+++ b/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c
@@ -21,16 +21,16 @@ void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi,
21 int enable) 21 int enable)
22{ 22{
23 if (enable) { 23 if (enable) {
24 s3c2410_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1); 24 s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1);
25 s3c2410_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1); 25 s3c_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1);
26 s3c2410_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1); 26 s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1);
27 s3c2410_gpio_pullup(S3C2410_GPG(5), 0); 27 s3c2410_gpio_pullup(S3C2410_GPG(5), 0);
28 s3c2410_gpio_pullup(S3C2410_GPG(6), 0); 28 s3c2410_gpio_pullup(S3C2410_GPG(6), 0);
29 } else { 29 } else {
30 s3c2410_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT); 30 s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT);
31 s3c2410_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT); 31 s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT);
32 s3c2410_gpio_pullup(S3C2410_GPG(5), 1); 32 s3c_gpio_cfgpull(S3C2410_GPG(5), S3C_GPIO_PULL_NONE);
33 s3c2410_gpio_pullup(S3C2410_GPG(6), 1); 33 s3c_gpio_cfgpull(S3C2410_GPG(6), S3C_GPIO_PULL_NONE);
34 s3c2410_gpio_pullup(S3C2410_GPG(7), 1); 34 s3c_gpio_cfgpull(S3C2410_GPG(7), S3C_GPIO_PULL_NONE);
35 } 35 }
36} 36}
diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c
index aa96e335073b..a8bfabf4b6bc 100644
--- a/arch/arm/plat-s5p/clock.c
+++ b/arch/arm/plat-s5p/clock.c
@@ -33,6 +33,11 @@ struct clk clk_ext_xtal_mux = {
33 .id = -1, 33 .id = -1,
34}; 34};
35 35
36struct clk clk_xusbxti = {
37 .name = "xusbxti",
38 .id = -1,
39};
40
36static struct clk s5p_clk_27m = { 41static struct clk s5p_clk_27m = {
37 .name = "clk_27m", 42 .name = "clk_27m",
38 .id = -1, 43 .id = -1,
@@ -69,6 +74,13 @@ struct clk clk_fout_epll = {
69 .ctrlbit = (1 << 31), 74 .ctrlbit = (1 << 31),
70}; 75};
71 76
77/* VPLL clock output */
78struct clk clk_fout_vpll = {
79 .name = "fout_vpll",
80 .id = -1,
81 .ctrlbit = (1 << 31),
82};
83
72/* ARM clock */ 84/* ARM clock */
73struct clk clk_arm = { 85struct clk clk_arm = {
74 .name = "armclk", 86 .name = "armclk",
@@ -133,6 +145,7 @@ static struct clk *s5p_clks[] __initdata = {
133 &clk_fout_apll, 145 &clk_fout_apll,
134 &clk_fout_mpll, 146 &clk_fout_mpll,
135 &clk_fout_epll, 147 &clk_fout_epll,
148 &clk_fout_vpll,
136 &clk_arm, 149 &clk_arm,
137 &clk_vpll, 150 &clk_vpll,
138}; 151};
diff --git a/arch/arm/plat-s5p/include/plat/irqs.h b/arch/arm/plat-s5p/include/plat/irqs.h
index 42e757f2e40c..9ff3d718be39 100644
--- a/arch/arm/plat-s5p/include/plat/irqs.h
+++ b/arch/arm/plat-s5p/include/plat/irqs.h
@@ -79,7 +79,7 @@
79#define S5P_IRQ_VIC2(x) (S5P_VIC2_BASE + (x)) 79#define S5P_IRQ_VIC2(x) (S5P_VIC2_BASE + (x))
80#define S5P_IRQ_VIC3(x) (S5P_VIC3_BASE + (x)) 80#define S5P_IRQ_VIC3(x) (S5P_VIC3_BASE + (x))
81 81
82#define S5P_TIMER_IRQ(x) S5P_IRQ(11 + (x)) 82#define S5P_TIMER_IRQ(x) (11 + (x))
83 83
84#define IRQ_TIMER0 S5P_TIMER_IRQ(0) 84#define IRQ_TIMER0 S5P_TIMER_IRQ(0)
85#define IRQ_TIMER1 S5P_TIMER_IRQ(1) 85#define IRQ_TIMER1 S5P_TIMER_IRQ(1)
diff --git a/arch/arm/plat-s5p/include/plat/s5p-clock.h b/arch/arm/plat-s5p/include/plat/s5p-clock.h
index 56fb8b414d41..aa0447a18903 100644
--- a/arch/arm/plat-s5p/include/plat/s5p-clock.h
+++ b/arch/arm/plat-s5p/include/plat/s5p-clock.h
@@ -23,10 +23,12 @@
23#define clk_fin_vpll clk_ext_xtal_mux 23#define clk_fin_vpll clk_ext_xtal_mux
24 24
25extern struct clk clk_ext_xtal_mux; 25extern struct clk clk_ext_xtal_mux;
26extern struct clk clk_xusbxti;
26extern struct clk clk_48m; 27extern struct clk clk_48m;
27extern struct clk clk_fout_apll; 28extern struct clk clk_fout_apll;
28extern struct clk clk_fout_mpll; 29extern struct clk clk_fout_mpll;
29extern struct clk clk_fout_epll; 30extern struct clk clk_fout_epll;
31extern struct clk clk_fout_vpll;
30extern struct clk clk_arm; 32extern struct clk clk_arm;
31extern struct clk clk_vpll; 33extern struct clk clk_vpll;
32 34
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index d552c65fa1b0..5349d2181bd2 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -160,6 +160,11 @@ config S3C_DEV_HSMMC2
160 help 160 help
161 Compile in platform device definitions for HSMMC channel 2 161 Compile in platform device definitions for HSMMC channel 2
162 162
163config S3C_DEV_HWMON
164 bool
165 help
166 Compile in platform device definitions for HWMON
167
163config S3C_DEV_I2C1 168config S3C_DEV_I2C1
164 bool 169 bool
165 help 170 help
@@ -198,6 +203,12 @@ config S3C_DMA
198 help 203 help
199 Internal configuration for S3C DMA core 204 Internal configuration for S3C DMA core
200 205
206config S3C_PL330_DMA
207 bool
208 select PL330
209 help
210 S3C DMA API Driver for PL330 DMAC.
211
201comment "Power management" 212comment "Power management"
202 213
203config SAMSUNG_PM_DEBUG 214config SAMSUNG_PM_DEBUG
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 22c89d08f6e5..ca6036745edc 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_S3C_ADC) += adc.o
33obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o 33obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o
34obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o 34obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o
35obj-$(CONFIG_S3C_DEV_HSMMC2) += dev-hsmmc2.o 35obj-$(CONFIG_S3C_DEV_HSMMC2) += dev-hsmmc2.o
36obj-$(CONFIG_S3C_DEV_HWMON) += dev-hwmon.o
36obj-y += dev-i2c0.o 37obj-y += dev-i2c0.o
37obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o 38obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
38obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o 39obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o
@@ -45,6 +46,8 @@ obj-$(CONFIG_S3C_DEV_NAND) += dev-nand.o
45 46
46obj-$(CONFIG_S3C_DMA) += dma.o 47obj-$(CONFIG_S3C_DMA) += dma.o
47 48
49obj-$(CONFIG_S3C_PL330_DMA) += s3c-pl330.o
50
48# PM support 51# PM support
49 52
50obj-$(CONFIG_PM) += pm.o 53obj-$(CONFIG_PM) += pm.o
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
index 1b25c9d8c403..8bf79f3efdfb 100644
--- a/arch/arm/plat-samsung/clock.c
+++ b/arch/arm/plat-samsung/clock.c
@@ -376,6 +376,21 @@ void __init s3c_register_clocks(struct clk *clkp, int nr_clks)
376 } 376 }
377} 377}
378 378
379/**
380 * s3c_disable_clocks() - disable an array of clocks
381 * @clkp: Pointer to the first clock in the array.
382 * @nr_clks: Number of clocks to register.
383 *
384 * for internal use only at initialisation time. disable the clocks in the
385 * @clkp array.
386 */
387
388void __init s3c_disable_clocks(struct clk *clkp, int nr_clks)
389{
390 for (; nr_clks > 0; nr_clks--, clkp++)
391 (clkp->enable)(clkp, 0);
392}
393
379/* initalise all the clocks */ 394/* initalise all the clocks */
380 395
381int __init s3c24xx_register_baseclocks(unsigned long xtal) 396int __init s3c24xx_register_baseclocks(unsigned long xtal)
diff --git a/arch/arm/plat-samsung/dev-fb.c b/arch/arm/plat-samsung/dev-fb.c
index 002a15f313f3..bf60204c6297 100644
--- a/arch/arm/plat-samsung/dev-fb.c
+++ b/arch/arm/plat-samsung/dev-fb.c
@@ -19,7 +19,6 @@
19 19
20#include <mach/irqs.h> 20#include <mach/irqs.h>
21#include <mach/map.h> 21#include <mach/map.h>
22#include <mach/regs-fb.h>
23 22
24#include <plat/fb.h> 23#include <plat/fb.h>
25#include <plat/devs.h> 24#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
index 000000000000..b3ffb9587250
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-hwmon.c
@@ -0,0 +1,42 @@
1/* linux/arch/arm/plat-samsung/dev-hwmon.c
2 *
3 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * Adapted for HWMON by Maurus Cuelenaere
8 *
9 * Samsung series device definition for HWMON
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14*/
15
16#include <linux/kernel.h>
17#include <linux/platform_device.h>
18
19#include <plat/devs.h>
20#include <plat/hwmon.h>
21
22struct platform_device s3c_device_hwmon = {
23 .name = "s3c-hwmon",
24 .id = -1,
25 .dev.parent = &s3c_device_adc.dev,
26};
27
28void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd)
29{
30 struct s3c_hwmon_pdata *npd;
31
32 if (!pd) {
33 printk(KERN_ERR "%s: no platform data\n", __func__);
34 return;
35 }
36
37 npd = kmemdup(pd, sizeof(struct s3c_hwmon_pdata), GFP_KERNEL);
38 if (!npd)
39 printk(KERN_ERR "%s: no memory for platform data\n", __func__);
40
41 s3c_device_hwmon.dev.platform_data = npd;
42}
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
index 44a84e896546..a76eef533392 100644
--- a/arch/arm/plat-samsung/gpio-config.c
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -1,7 +1,7 @@
1/* linux/arch/arm/plat-s3c/gpio-config.c 1/* linux/arch/arm/plat-s3c/gpio-config.c
2 * 2 *
3 * Copyright 2008 Openmoko, Inc. 3 * Copyright 2008 Openmoko, Inc.
4 * Copyright 2008 Simtec Electronics 4 * Copyright 2008-2010 Simtec Electronics
5 * Ben Dooks <ben@simtec.co.uk> 5 * Ben Dooks <ben@simtec.co.uk>
6 * http://armlinux.simtec.co.uk/ 6 * http://armlinux.simtec.co.uk/
7 * 7 *
@@ -33,14 +33,34 @@ int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
33 33
34 offset = pin - chip->chip.base; 34 offset = pin - chip->chip.base;
35 35
36 local_irq_save(flags); 36 s3c_gpio_lock(chip, flags);
37 ret = s3c_gpio_do_setcfg(chip, offset, config); 37 ret = s3c_gpio_do_setcfg(chip, offset, config);
38 local_irq_restore(flags); 38 s3c_gpio_unlock(chip, flags);
39 39
40 return ret; 40 return ret;
41} 41}
42EXPORT_SYMBOL(s3c_gpio_cfgpin); 42EXPORT_SYMBOL(s3c_gpio_cfgpin);
43 43
44unsigned s3c_gpio_getcfg(unsigned int pin)
45{
46 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
47 unsigned long flags;
48 unsigned ret = 0;
49 int offset;
50
51 if (chip) {
52 offset = pin - chip->chip.base;
53
54 s3c_gpio_lock(chip, flags);
55 ret = s3c_gpio_do_getcfg(chip, offset);
56 s3c_gpio_unlock(chip, flags);
57 }
58
59 return ret;
60}
61EXPORT_SYMBOL(s3c_gpio_getcfg);
62
63
44int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull) 64int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
45{ 65{
46 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); 66 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
@@ -52,17 +72,17 @@ int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
52 72
53 offset = pin - chip->chip.base; 73 offset = pin - chip->chip.base;
54 74
55 local_irq_save(flags); 75 s3c_gpio_lock(chip, flags);
56 ret = s3c_gpio_do_setpull(chip, offset, pull); 76 ret = s3c_gpio_do_setpull(chip, offset, pull);
57 local_irq_restore(flags); 77 s3c_gpio_unlock(chip, flags);
58 78
59 return ret; 79 return ret;
60} 80}
61EXPORT_SYMBOL(s3c_gpio_setpull); 81EXPORT_SYMBOL(s3c_gpio_setpull);
62 82
63#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX 83#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
64int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip, 84int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
65 unsigned int off, unsigned int cfg) 85 unsigned int off, unsigned int cfg)
66{ 86{
67 void __iomem *reg = chip->base; 87 void __iomem *reg = chip->base;
68 unsigned int shift = off; 88 unsigned int shift = off;
@@ -87,6 +107,19 @@ int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip,
87 return 0; 107 return 0;
88} 108}
89 109
110unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
111 unsigned int off)
112{
113 u32 con;
114
115 con = __raw_readl(chip->base);
116 con >>= off;
117 con &= 1;
118 con++;
119
120 return S3C_GPIO_SFN(con);
121}
122
90int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip, 123int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
91 unsigned int off, unsigned int cfg) 124 unsigned int off, unsigned int cfg)
92{ 125{
@@ -109,6 +142,19 @@ int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
109 142
110 return 0; 143 return 0;
111} 144}
145
146unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
147 unsigned int off)
148{
149 u32 con;
150
151 con = __raw_readl(chip->base);
152 con >>= off * 2;
153 con &= 3;
154
155 /* this conversion works for IN and OUT as well as special mode */
156 return S3C_GPIO_SPECIAL(con);
157}
112#endif 158#endif
113 159
114#ifdef CONFIG_S3C_GPIO_CFG_S3C64XX 160#ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
@@ -134,6 +180,25 @@ int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
134 180
135 return 0; 181 return 0;
136} 182}
183
184unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
185 unsigned int off)
186{
187 void __iomem *reg = chip->base;
188 unsigned int shift = (off & 7) * 4;
189 u32 con;
190
191 if (off < 8 && chip->chip.ngpio > 8)
192 reg -= 4;
193
194 con = __raw_readl(reg);
195 con >>= shift;
196 con &= 0xf;
197
198 /* this conversion works for IN and OUT as well as special mode */
199 return S3C_GPIO_SPECIAL(con);
200}
201
137#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */ 202#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */
138 203
139#ifdef CONFIG_S3C_GPIO_PULL_UPDOWN 204#ifdef CONFIG_S3C_GPIO_PULL_UPDOWN
@@ -164,3 +229,35 @@ s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
164 return (__force s3c_gpio_pull_t)pup; 229 return (__force s3c_gpio_pull_t)pup;
165} 230}
166#endif 231#endif
232
233#ifdef CONFIG_S3C_GPIO_PULL_UP
234int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
235 unsigned int off, s3c_gpio_pull_t pull)
236{
237 void __iomem *reg = chip->base + 0x08;
238 u32 pup = __raw_readl(reg);
239
240 pup = __raw_readl(reg);
241
242 if (pup == S3C_GPIO_PULL_UP)
243 pup &= ~(1 << off);
244 else if (pup == S3C_GPIO_PULL_NONE)
245 pup |= (1 << off);
246 else
247 return -EINVAL;
248
249 __raw_writel(pup, reg);
250 return 0;
251}
252
253s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
254 unsigned int off)
255{
256 void __iomem *reg = chip->base + 0x08;
257 u32 pup = __raw_readl(reg);
258
259 pup &= (1 << off);
260 return pup ? S3C_GPIO_PULL_NONE : S3C_GPIO_PULL_UP;
261}
262#endif /* CONFIG_S3C_GPIO_PULL_UP */
263
diff --git a/arch/arm/plat-samsung/gpio.c b/arch/arm/plat-samsung/gpio.c
index 28d2ab8a08db..b83a83351cea 100644
--- a/arch/arm/plat-samsung/gpio.c
+++ b/arch/arm/plat-samsung/gpio.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/gpio.h> 17#include <linux/gpio.h>
18#include <linux/spinlock.h>
18 19
19#include <plat/gpio-core.h> 20#include <plat/gpio-core.h>
20 21
@@ -52,14 +53,14 @@ static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset)
52 unsigned long flags; 53 unsigned long flags;
53 unsigned long con; 54 unsigned long con;
54 55
55 local_irq_save(flags); 56 s3c_gpio_lock(ourchip, flags);
56 57
57 con = __raw_readl(base + 0x00); 58 con = __raw_readl(base + 0x00);
58 con &= ~(3 << (offset * 2)); 59 con &= ~(3 << (offset * 2));
59 60
60 __raw_writel(con, base + 0x00); 61 __raw_writel(con, base + 0x00);
61 62
62 local_irq_restore(flags); 63 s3c_gpio_unlock(ourchip, flags);
63 return 0; 64 return 0;
64} 65}
65 66
@@ -72,7 +73,7 @@ static int s3c_gpiolib_output(struct gpio_chip *chip,
72 unsigned long dat; 73 unsigned long dat;
73 unsigned long con; 74 unsigned long con;
74 75
75 local_irq_save(flags); 76 s3c_gpio_lock(ourchip, flags);
76 77
77 dat = __raw_readl(base + 0x04); 78 dat = __raw_readl(base + 0x04);
78 dat &= ~(1 << offset); 79 dat &= ~(1 << offset);
@@ -87,7 +88,7 @@ static int s3c_gpiolib_output(struct gpio_chip *chip,
87 __raw_writel(con, base + 0x00); 88 __raw_writel(con, base + 0x00);
88 __raw_writel(dat, base + 0x04); 89 __raw_writel(dat, base + 0x04);
89 90
90 local_irq_restore(flags); 91 s3c_gpio_unlock(ourchip, flags);
91 return 0; 92 return 0;
92} 93}
93 94
@@ -99,7 +100,7 @@ static void s3c_gpiolib_set(struct gpio_chip *chip,
99 unsigned long flags; 100 unsigned long flags;
100 unsigned long dat; 101 unsigned long dat;
101 102
102 local_irq_save(flags); 103 s3c_gpio_lock(ourchip, flags);
103 104
104 dat = __raw_readl(base + 0x04); 105 dat = __raw_readl(base + 0x04);
105 dat &= ~(1 << offset); 106 dat &= ~(1 << offset);
@@ -107,7 +108,7 @@ static void s3c_gpiolib_set(struct gpio_chip *chip,
107 dat |= 1 << offset; 108 dat |= 1 << offset;
108 __raw_writel(dat, base + 0x04); 109 __raw_writel(dat, base + 0x04);
109 110
110 local_irq_restore(flags); 111 s3c_gpio_unlock(ourchip, flags);
111} 112}
112 113
113static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset) 114static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset)
@@ -131,6 +132,8 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
131 BUG_ON(!gc->label); 132 BUG_ON(!gc->label);
132 BUG_ON(!gc->ngpio); 133 BUG_ON(!gc->ngpio);
133 134
135 spin_lock_init(&chip->lock);
136
134 if (!gc->direction_input) 137 if (!gc->direction_input)
135 gc->direction_input = s3c_gpiolib_input; 138 gc->direction_input = s3c_gpiolib_input;
136 if (!gc->direction_output) 139 if (!gc->direction_output)
diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h
index 60b62692ac7a..0fbcd0effd8e 100644
--- a/arch/arm/plat-samsung/include/plat/clock.h
+++ b/arch/arm/plat-samsung/include/plat/clock.h
@@ -74,6 +74,7 @@ extern struct clk clk_ext;
74extern struct clk clk_h2; 74extern struct clk clk_h2;
75extern struct clk clk_27m; 75extern struct clk clk_27m;
76extern struct clk clk_48m; 76extern struct clk clk_48m;
77extern struct clk clk_xusbxti;
77 78
78extern int clk_default_setrate(struct clk *clk, unsigned long rate); 79extern int clk_default_setrate(struct clk *clk, unsigned long rate);
79extern struct clk_ops clk_ops_def_setrate; 80extern struct clk_ops clk_ops_def_setrate;
@@ -91,6 +92,7 @@ extern int s3c24xx_register_clock(struct clk *clk);
91extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks); 92extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks);
92 93
93extern void s3c_register_clocks(struct clk *clk, int nr_clks); 94extern void s3c_register_clocks(struct clk *clk, int nr_clks);
95extern void s3c_disable_clocks(struct clk *clkp, int nr_clks);
94 96
95extern int s3c24xx_register_baseclocks(unsigned long xtal); 97extern int s3c24xx_register_baseclocks(unsigned long xtal);
96 98
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index d316b4a579f4..6412933d6fbb 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -73,11 +73,15 @@ extern struct sys_timer s3c24xx_timer;
73extern struct sysdev_class s3c2410_sysclass; 73extern struct sysdev_class s3c2410_sysclass;
74extern struct sysdev_class s3c2410a_sysclass; 74extern struct sysdev_class s3c2410a_sysclass;
75extern struct sysdev_class s3c2412_sysclass; 75extern struct sysdev_class s3c2412_sysclass;
76extern struct sysdev_class s3c2416_sysclass;
76extern struct sysdev_class s3c2440_sysclass; 77extern struct sysdev_class s3c2440_sysclass;
77extern struct sysdev_class s3c2442_sysclass; 78extern struct sysdev_class s3c2442_sysclass;
78extern struct sysdev_class s3c2443_sysclass; 79extern struct sysdev_class s3c2443_sysclass;
79extern struct sysdev_class s3c6410_sysclass; 80extern struct sysdev_class s3c6410_sysclass;
80extern struct sysdev_class s3c64xx_sysclass; 81extern struct sysdev_class s3c64xx_sysclass;
82extern struct sysdev_class s5p6440_sysclass;
83extern struct sysdev_class s5p6442_sysclass;
84extern struct sysdev_class s5pv210_sysclass;
81 85
82extern void (*s5pc1xx_idle)(void); 86extern void (*s5pc1xx_idle)(void);
83 87
diff --git a/arch/arm/plat-samsung/include/plat/dma.h b/arch/arm/plat-samsung/include/plat/dma.h
index 7584d751ed51..2e8f8c6560d7 100644
--- a/arch/arm/plat-samsung/include/plat/dma.h
+++ b/arch/arm/plat-samsung/include/plat/dma.h
@@ -110,8 +110,8 @@ extern int s3c2410_dma_config(unsigned int channel, int xferunit);
110 * configure the device we're talking to 110 * configure the device we're talking to
111*/ 111*/
112 112
113extern int s3c2410_dma_devconfig(int channel, enum s3c2410_dmasrc source, 113extern int s3c2410_dma_devconfig(unsigned int channel,
114 unsigned long devaddr); 114 enum s3c2410_dmasrc source, unsigned long devaddr);
115 115
116/* s3c2410_dma_getposition 116/* s3c2410_dma_getposition
117 * 117 *
diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h
index ffc01a76b7ce..1f85649d8c18 100644
--- a/arch/arm/plat-samsung/include/plat/fb.h
+++ b/arch/arm/plat-samsung/include/plat/fb.h
@@ -15,6 +15,13 @@
15#ifndef __PLAT_S3C_FB_H 15#ifndef __PLAT_S3C_FB_H
16#define __PLAT_S3C_FB_H __FILE__ 16#define __PLAT_S3C_FB_H __FILE__
17 17
18/* S3C_FB_MAX_WIN
19 * Set to the maximum number of windows that any of the supported hardware
20 * can use. Since the platform data uses this for an array size, having it
21 * set to the maximum of any version of the hardware can do is safe.
22 */
23#define S3C_FB_MAX_WIN (5)
24
18/** 25/**
19 * struct s3c_fb_pd_win - per window setup data 26 * struct s3c_fb_pd_win - per window setup data
20 * @win_mode: The display parameters to initialise (not for window 0) 27 * @win_mode: The display parameters to initialise (not for window 0)
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
index dda19da037ad..3e21c75feefa 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
@@ -30,6 +30,12 @@ static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip,
30 return (chip->config->set_config)(chip, off, config); 30 return (chip->config->set_config)(chip, off, config);
31} 31}
32 32
33static inline unsigned s3c_gpio_do_getcfg(struct s3c_gpio_chip *chip,
34 unsigned int off)
35{
36 return (chip->config->get_config)(chip, off);
37}
38
33static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip, 39static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
34 unsigned int off, s3c_gpio_pull_t pull) 40 unsigned int off, s3c_gpio_pull_t pull)
35{ 41{
@@ -53,6 +59,18 @@ extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
53 unsigned int off, unsigned int cfg); 59 unsigned int off, unsigned int cfg);
54 60
55/** 61/**
62 * s3c_gpio_getcfg_s3c24xx - S3C24XX style GPIO configuration read.
63 * @chip: The gpio chip that is being configured.
64 * @off: The offset for the GPIO being configured.
65 *
66 * The reverse of s3c_gpio_setcfg_s3c24xx(). Will return a value whicg
67 * could be directly passed back to s3c_gpio_setcfg_s3c24xx(), from the
68 * S3C_GPIO_SPECIAL() macro.
69 */
70unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
71 unsigned int off);
72
73/**
56 * s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A) 74 * s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A)
57 * @chip: The gpio chip that is being configured. 75 * @chip: The gpio chip that is being configured.
58 * @off: The offset for the GPIO being configured. 76 * @off: The offset for the GPIO being configured.
@@ -65,6 +83,21 @@ extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
65extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip, 83extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
66 unsigned int off, unsigned int cfg); 84 unsigned int off, unsigned int cfg);
67 85
86
87/**
88 * s3c_gpio_getcfg_s3c24xx_a - S3C24XX style GPIO configuration read (Bank A)
89 * @chip: The gpio chip that is being configured.
90 * @off: The offset for the GPIO being configured.
91 *
92 * The reverse of s3c_gpio_setcfg_s3c24xx_a() turning an GPIO into a usable
93 * GPIO configuration value.
94 *
95 * @sa s3c_gpio_getcfg_s3c24xx
96 * @sa s3c_gpio_getcfg_s3c64xx_4bit
97 */
98extern unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
99 unsigned int off);
100
68/** 101/**
69 * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config. 102 * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config.
70 * @chip: The gpio chip that is being configured. 103 * @chip: The gpio chip that is being configured.
@@ -85,6 +118,20 @@ extern int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
85 unsigned int off, unsigned int cfg); 118 unsigned int off, unsigned int cfg);
86 119
87 120
121/**
122 * s3c_gpio_getcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config read.
123 * @chip: The gpio chip that is being configured.
124 * @off: The offset for the GPIO being configured.
125 *
126 * The reverse of s3c_gpio_setcfg_s3c64xx_4bit(), turning a gpio configuration
127 * register setting into a value the software can use, such as could be passed
128 * to s3c_gpio_setcfg_s3c64xx_4bit().
129 *
130 * @sa s3c_gpio_getcfg_s3c24xx
131 */
132extern unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
133 unsigned int off);
134
88/* Pull-{up,down} resistor controls. 135/* Pull-{up,down} resistor controls.
89 * 136 *
90 * S3C2410,S3C2440,S3C24A0 = Pull-UP, 137 * S3C2410,S3C2440,S3C24A0 = Pull-UP,
@@ -146,6 +193,17 @@ extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
146 unsigned int off); 193 unsigned int off);
147 194
148/** 195/**
196 * s3c_gpio_getpull_1up() - Get configuration for choice of up or none
197 * @chip: The gpio chip that the GPIO pin belongs to
198 * @off: The offset to the pin to get the configuration of.
199 *
200 * This helper function reads the state of the pull-up resistor for the
201 * given GPIO in the same case as s3c_gpio_setpull_1up.
202*/
203extern s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
204 unsigned int off);
205
206/**
149 * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443. 207 * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443.
150 * @chip: The gpio chip that is being configured. 208 * @chip: The gpio chip that is being configured.
151 * @off: The offset for the GPIO being configured. 209 * @off: The offset for the GPIO being configured.
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
index 29cd6a86cade..8d01e853df39 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
@@ -77,6 +77,17 @@ struct s3c_gpio_cfg {
77 */ 77 */
78extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to); 78extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
79 79
80/**
81 * s3c_gpio_getcfg - Read the current function for a GPIO pin
82 * @pin: The pin to read the configuration value for.
83 *
84 * Read the configuration state of the given @pin, returning a value that
85 * could be passed back to s3c_gpio_cfgpin().
86 *
87 * @sa s3c_gpio_cfgpin
88 */
89extern unsigned s3c_gpio_getcfg(unsigned int pin);
90
80/* Define values for the pull-{up,down} available for each gpio pin. 91/* Define values for the pull-{up,down} available for each gpio pin.
81 * 92 *
82 * These values control the state of the weak pull-{up,down} resistors 93 * These values control the state of the weak pull-{up,down} resistors
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index 49ff406a7066..f3a68d1a07b9 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -44,16 +44,26 @@ struct s3c_gpio_cfg;
44 * @chip: The chip structure to be exported via gpiolib. 44 * @chip: The chip structure to be exported via gpiolib.
45 * @base: The base pointer to the gpio configuration registers. 45 * @base: The base pointer to the gpio configuration registers.
46 * @config: special function and pull-resistor control information. 46 * @config: special function and pull-resistor control information.
47 * @lock: Lock for exclusive access to this gpio bank.
47 * @pm_save: Save information for suspend/resume support. 48 * @pm_save: Save information for suspend/resume support.
48 * 49 *
49 * This wrapper provides the necessary information for the Samsung 50 * This wrapper provides the necessary information for the Samsung
50 * specific gpios being registered with gpiolib. 51 * specific gpios being registered with gpiolib.
52 *
53 * The lock protects each gpio bank from multiple access of the shared
54 * configuration registers, or from reading of data whilst another thread
55 * is writing to the register set.
56 *
57 * Each chip has its own lock to avoid any contention between different
58 * CPU cores trying to get one lock for different GPIO banks, where each
59 * bank of GPIO has its own register space and configuration registers.
51 */ 60 */
52struct s3c_gpio_chip { 61struct s3c_gpio_chip {
53 struct gpio_chip chip; 62 struct gpio_chip chip;
54 struct s3c_gpio_cfg *config; 63 struct s3c_gpio_cfg *config;
55 struct s3c_gpio_pm *pm; 64 struct s3c_gpio_pm *pm;
56 void __iomem *base; 65 void __iomem *base;
66 spinlock_t lock;
57#ifdef CONFIG_PM 67#ifdef CONFIG_PM
58 u32 pm_save[4]; 68 u32 pm_save[4];
59#endif 69#endif
@@ -108,6 +118,9 @@ extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
108extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip); 118extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip);
109extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip); 119extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip);
110 120
121/* exported for core SoC support to change */
122extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default;
123
111#ifdef CONFIG_S3C_GPIO_TRACK 124#ifdef CONFIG_S3C_GPIO_TRACK
112extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END]; 125extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
113 126
@@ -135,3 +148,7 @@ extern struct s3c_gpio_pm s3c_gpio_pm_4bit;
135#define __gpio_pm(x) NULL 148#define __gpio_pm(x) NULL
136 149
137#endif /* CONFIG_PM */ 150#endif /* CONFIG_PM */
151
152/* locking wrappers to deal with multiple access to the same gpio bank */
153#define s3c_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl)
154#define s3c_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl)
diff --git a/arch/arm/plat-samsung/include/plat/hwmon.h b/arch/arm/plat-samsung/include/plat/hwmon.h
index 1ba88ea0aa31..c167e4429bc7 100644
--- a/arch/arm/plat-samsung/include/plat/hwmon.h
+++ b/arch/arm/plat-samsung/include/plat/hwmon.h
@@ -37,5 +37,15 @@ struct s3c_hwmon_pdata {
37 struct s3c_hwmon_chcfg *in[8]; 37 struct s3c_hwmon_chcfg *in[8];
38}; 38};
39 39
40/**
41 * s3c_hwmon_set_platdata - Set platform data for S3C HWMON device
42 * @pd: Platform data to register to device.
43 *
44 * Register the given platform data for use with the S3C HWMON device.
45 * The call will copy the platform data, so the board definitions can
46 * make the structure itself __initdata.
47 */
48extern void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd);
49
40#endif /* __ASM_ARCH_ADC_HWMON_H */ 50#endif /* __ASM_ARCH_ADC_HWMON_H */
41 51
diff --git a/arch/arm/plat-samsung/include/plat/pll6553x.h b/arch/arm/plat-samsung/include/plat/pll6553x.h
new file mode 100644
index 000000000000..b8b7e1d884f8
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pll6553x.h
@@ -0,0 +1,51 @@
1/* arch/arm/plat-samsung/include/plat/pll6553x.h
2 * partially from arch/arm/mach-s3c64xx/include/mach/pll.h
3 *
4 * Copyright 2008 Openmoko, Inc.
5 * Copyright 2008 Simtec Electronics
6 * Ben Dooks <ben@simtec.co.uk>
7 * http://armlinux.simtec.co.uk/
8 *
9 * Samsung PLL6553x PLL code
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14*/
15
16/* S3C6400 and compatible (S3C2416, etc.) EPLL code */
17
18#define PLL6553X_MDIV_MASK ((1 << (23-16)) - 1)
19#define PLL6553X_PDIV_MASK ((1 << (13-8)) - 1)
20#define PLL6553X_SDIV_MASK ((1 << (2-0)) - 1)
21#define PLL6553X_MDIV_SHIFT (16)
22#define PLL6553X_PDIV_SHIFT (8)
23#define PLL6553X_SDIV_SHIFT (0)
24#define PLL6553X_KDIV_MASK (0xffff)
25
26static inline unsigned long s3c_get_pll6553x(unsigned long baseclk,
27 u32 pll0, u32 pll1)
28{
29 unsigned long result;
30 u32 mdiv, pdiv, sdiv, kdiv;
31 u64 tmp;
32
33 mdiv = (pll0 >> PLL6553X_MDIV_SHIFT) & PLL6553X_MDIV_MASK;
34 pdiv = (pll0 >> PLL6553X_PDIV_SHIFT) & PLL6553X_PDIV_MASK;
35 sdiv = (pll0 >> PLL6553X_SDIV_SHIFT) & PLL6553X_SDIV_MASK;
36 kdiv = pll1 & PLL6553X_KDIV_MASK;
37
38 /* We need to multiple baseclk by mdiv (the integer part) and kdiv
39 * which is in 2^16ths, so shift mdiv up (does not overflow) and
40 * add kdiv before multiplying. The use of tmp is to avoid any
41 * overflows before shifting bac down into result when multipling
42 * by the mdiv and kdiv pair.
43 */
44
45 tmp = baseclk;
46 tmp *= (mdiv << 16) + kdiv;
47 do_div(tmp, (pdiv << sdiv));
48 result = tmp >> 16;
49
50 return result;
51}
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
index 000000000000..5fe6721b57f7
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
@@ -0,0 +1,78 @@
1/*
2 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
3 * Jaswinder Singh <jassi.brar@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#ifndef __S3C_DMA_PL330_H_
12#define __S3C_DMA_PL330_H_
13
14#define S3C2410_DMAF_AUTOSTART (1 << 0)
15#define S3C2410_DMAF_CIRCULAR (1 << 1)
16
17/*
18 * PL330 can assign any channel to communicate with
19 * any of the peripherals attched to the DMAC.
20 * For the sake of consistency across client drivers,
21 * We keep the channel names unchanged and only add
22 * missing peripherals are added.
23 * Order is not important since S3C PL330 API driver
24 * use these just as IDs.
25 */
26enum dma_ch {
27 DMACH_UART0_RX,
28 DMACH_UART0_TX,
29 DMACH_UART1_RX,
30 DMACH_UART1_TX,
31 DMACH_UART2_RX,
32 DMACH_UART2_TX,
33 DMACH_UART3_RX,
34 DMACH_UART3_TX,
35 DMACH_IRDA,
36 DMACH_I2S0_RX,
37 DMACH_I2S0_TX,
38 DMACH_I2S0S_TX,
39 DMACH_I2S1_RX,
40 DMACH_I2S1_TX,
41 DMACH_I2S2_RX,
42 DMACH_I2S2_TX,
43 DMACH_SPI0_RX,
44 DMACH_SPI0_TX,
45 DMACH_SPI1_RX,
46 DMACH_SPI1_TX,
47 DMACH_SPI2_RX,
48 DMACH_SPI2_TX,
49 DMACH_AC97_MICIN,
50 DMACH_AC97_PCMIN,
51 DMACH_AC97_PCMOUT,
52 DMACH_EXTERNAL,
53 DMACH_PWM,
54 DMACH_SPDIF,
55 DMACH_HSI_RX,
56 DMACH_HSI_TX,
57 DMACH_PCM0_TX,
58 DMACH_PCM0_RX,
59 DMACH_PCM1_TX,
60 DMACH_PCM1_RX,
61 DMACH_PCM2_TX,
62 DMACH_PCM2_RX,
63 DMACH_MSM_REQ3,
64 DMACH_MSM_REQ2,
65 DMACH_MSM_REQ1,
66 DMACH_MSM_REQ0,
67 /* END Marker, also used to denote a reserved channel */
68 DMACH_MAX,
69};
70
71static inline bool s3c_dma_has_circular(void)
72{
73 return true;
74}
75
76#include <plat/dma.h>
77
78#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
index 000000000000..bf5e2a9d408d
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
@@ -0,0 +1,32 @@
1/* linux/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
2 *
3 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
4 * Jaswinder Singh <jassi.brar@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#ifndef __S3C_PL330_PDATA_H
13#define __S3C_PL330_PDATA_H
14
15#include <plat/s3c-dma-pl330.h>
16
17/*
18 * Every PL330 DMAC has max 32 peripheral interfaces,
19 * of which some may be not be really used in your
20 * DMAC's configuration.
21 * Populate this array of 32 peri i/fs with relevant
22 * channel IDs for used peri i/f and DMACH_MAX for
23 * those unused.
24 *
25 * The platforms just need to provide this info
26 * to the S3C DMA API driver for PL330.
27 */
28struct s3c_pl330_platdata {
29 enum dma_ch peri[32];
30};
31
32#endif /* __S3C_PL330_PDATA_H */
diff --git a/arch/arm/plat-samsung/pm-gpio.c b/arch/arm/plat-samsung/pm-gpio.c
index 69a4c7f02e25..d50ab9d2af53 100644
--- a/arch/arm/plat-samsung/pm-gpio.c
+++ b/arch/arm/plat-samsung/pm-gpio.c
@@ -329,7 +329,7 @@ void s3c_pm_save_gpios(void)
329 struct s3c_gpio_chip *ourchip; 329 struct s3c_gpio_chip *ourchip;
330 unsigned int gpio_nr; 330 unsigned int gpio_nr;
331 331
332 for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) { 332 for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
333 ourchip = s3c_gpiolib_getchip(gpio_nr); 333 ourchip = s3c_gpiolib_getchip(gpio_nr);
334 if (!ourchip) 334 if (!ourchip)
335 continue; 335 continue;
@@ -367,7 +367,7 @@ void s3c_pm_restore_gpios(void)
367 struct s3c_gpio_chip *ourchip; 367 struct s3c_gpio_chip *ourchip;
368 unsigned int gpio_nr; 368 unsigned int gpio_nr;
369 369
370 for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) { 370 for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
371 ourchip = s3c_gpiolib_getchip(gpio_nr); 371 ourchip = s3c_gpiolib_getchip(gpio_nr);
372 if (!ourchip) 372 if (!ourchip)
373 continue; 373 continue;
diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c
new file mode 100644
index 000000000000..a91305a60aed
--- /dev/null
+++ b/arch/arm/plat-samsung/s3c-pl330.c
@@ -0,0 +1,1224 @@
1/* linux/arch/arm/plat-samsung/s3c-pl330.c
2 *
3 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
4 * Jaswinder Singh <jassi.brar@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/interrupt.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include <linux/platform_device.h>
18
19#include <asm/hardware/pl330.h>
20
21#include <plat/s3c-pl330-pdata.h>
22
23/**
24 * struct s3c_pl330_dmac - Logical representation of a PL330 DMAC.
25 * @busy_chan: Number of channels currently busy.
26 * @peri: List of IDs of peripherals this DMAC can work with.
27 * @node: To attach to the global list of DMACs.
28 * @pi: PL330 configuration info for the DMAC.
29 * @kmcache: Pool to quickly allocate xfers for all channels in the dmac.
30 */
31struct s3c_pl330_dmac {
32 unsigned busy_chan;
33 enum dma_ch *peri;
34 struct list_head node;
35 struct pl330_info *pi;
36 struct kmem_cache *kmcache;
37};
38
39/**
40 * struct s3c_pl330_xfer - A request submitted by S3C DMA clients.
41 * @token: Xfer ID provided by the client.
42 * @node: To attach to the list of xfers on a channel.
43 * @px: Xfer for PL330 core.
44 * @chan: Owner channel of this xfer.
45 */
46struct s3c_pl330_xfer {
47 void *token;
48 struct list_head node;
49 struct pl330_xfer px;
50 struct s3c_pl330_chan *chan;
51};
52
53/**
54 * struct s3c_pl330_chan - Logical channel to communicate with
55 * a Physical peripheral.
56 * @pl330_chan_id: Token of a hardware channel thread of PL330 DMAC.
57 * NULL if the channel is available to be acquired.
58 * @id: ID of the peripheral that this channel can communicate with.
59 * @options: Options specified by the client.
60 * @sdaddr: Address provided via s3c2410_dma_devconfig.
61 * @node: To attach to the global list of channels.
62 * @lrq: Pointer to the last submitted pl330_req to PL330 core.
63 * @xfer_list: To manage list of xfers enqueued.
64 * @req: Two requests to communicate with the PL330 engine.
65 * @callback_fn: Callback function to the client.
66 * @rqcfg: Channel configuration for the xfers.
67 * @xfer_head: Pointer to the xfer to be next excecuted.
68 * @dmac: Pointer to the DMAC that manages this channel, NULL if the
69 * channel is available to be acquired.
70 * @client: Client of this channel. NULL if the
71 * channel is available to be acquired.
72 */
73struct s3c_pl330_chan {
74 void *pl330_chan_id;
75 enum dma_ch id;
76 unsigned int options;
77 unsigned long sdaddr;
78 struct list_head node;
79 struct pl330_req *lrq;
80 struct list_head xfer_list;
81 struct pl330_req req[2];
82 s3c2410_dma_cbfn_t callback_fn;
83 struct pl330_reqcfg rqcfg;
84 struct s3c_pl330_xfer *xfer_head;
85 struct s3c_pl330_dmac *dmac;
86 struct s3c2410_dma_client *client;
87};
88
89/* All DMACs in the platform */
90static LIST_HEAD(dmac_list);
91
92/* All channels to peripherals in the platform */
93static LIST_HEAD(chan_list);
94
95/*
96 * Since we add resources(DMACs and Channels) to the global pool,
97 * we need to guard access to the resources using a global lock
98 */
99static DEFINE_SPINLOCK(res_lock);
100
101/* Returns the channel with ID 'id' in the chan_list */
102static struct s3c_pl330_chan *id_to_chan(const enum dma_ch id)
103{
104 struct s3c_pl330_chan *ch;
105
106 list_for_each_entry(ch, &chan_list, node)
107 if (ch->id == id)
108 return ch;
109
110 return NULL;
111}
112
113/* Allocate a new channel with ID 'id' and add to chan_list */
114static void chan_add(const enum dma_ch id)
115{
116 struct s3c_pl330_chan *ch = id_to_chan(id);
117
118 /* Return if the channel already exists */
119 if (ch)
120 return;
121
122 ch = kmalloc(sizeof(*ch), GFP_KERNEL);
123 /* Return silently to work with other channels */
124 if (!ch)
125 return;
126
127 ch->id = id;
128 ch->dmac = NULL;
129
130 list_add_tail(&ch->node, &chan_list);
131}
132
133/* If the channel is not yet acquired by any client */
134static bool chan_free(struct s3c_pl330_chan *ch)
135{
136 if (!ch)
137 return false;
138
139 /* Channel points to some DMAC only when it's acquired */
140 return ch->dmac ? false : true;
141}
142
143/*
144 * Returns 0 is peripheral i/f is invalid or not present on the dmac.
145 * Index + 1, otherwise.
146 */
147static unsigned iface_of_dmac(struct s3c_pl330_dmac *dmac, enum dma_ch ch_id)
148{
149 enum dma_ch *id = dmac->peri;
150 int i;
151
152 /* Discount invalid markers */
153 if (ch_id == DMACH_MAX)
154 return 0;
155
156 for (i = 0; i < PL330_MAX_PERI; i++)
157 if (id[i] == ch_id)
158 return i + 1;
159
160 return 0;
161}
162
163/* If all channel threads of the DMAC are busy */
164static inline bool dmac_busy(struct s3c_pl330_dmac *dmac)
165{
166 struct pl330_info *pi = dmac->pi;
167
168 return (dmac->busy_chan < pi->pcfg.num_chan) ? false : true;
169}
170
171/*
172 * Returns the number of free channels that
173 * can be handled by this dmac only.
174 */
175static unsigned ch_onlyby_dmac(struct s3c_pl330_dmac *dmac)
176{
177 enum dma_ch *id = dmac->peri;
178 struct s3c_pl330_dmac *d;
179 struct s3c_pl330_chan *ch;
180 unsigned found, count = 0;
181 enum dma_ch p;
182 int i;
183
184 for (i = 0; i < PL330_MAX_PERI; i++) {
185 p = id[i];
186 ch = id_to_chan(p);
187
188 if (p == DMACH_MAX || !chan_free(ch))
189 continue;
190
191 found = 0;
192 list_for_each_entry(d, &dmac_list, node) {
193 if (d != dmac && iface_of_dmac(d, ch->id)) {
194 found = 1;
195 break;
196 }
197 }
198 if (!found)
199 count++;
200 }
201
202 return count;
203}
204
205/*
206 * Measure of suitability of 'dmac' handling 'ch'
207 *
208 * 0 indicates 'dmac' can not handle 'ch' either
209 * because it is not supported by the hardware or
210 * because all dmac channels are currently busy.
211 *
212 * >0 vlaue indicates 'dmac' has the capability.
213 * The bigger the value the more suitable the dmac.
214 */
215#define MAX_SUIT UINT_MAX
216#define MIN_SUIT 0
217
218static unsigned suitablility(struct s3c_pl330_dmac *dmac,
219 struct s3c_pl330_chan *ch)
220{
221 struct pl330_info *pi = dmac->pi;
222 enum dma_ch *id = dmac->peri;
223 struct s3c_pl330_dmac *d;
224 unsigned s;
225 int i;
226
227 s = MIN_SUIT;
228 /* If all the DMAC channel threads are busy */
229 if (dmac_busy(dmac))
230 return s;
231
232 for (i = 0; i < PL330_MAX_PERI; i++)
233 if (id[i] == ch->id)
234 break;
235
236 /* If the 'dmac' can't talk to 'ch' */
237 if (i == PL330_MAX_PERI)
238 return s;
239
240 s = MAX_SUIT;
241 list_for_each_entry(d, &dmac_list, node) {
242 /*
243 * If some other dmac can talk to this
244 * peri and has some channel free.
245 */
246 if (d != dmac && iface_of_dmac(d, ch->id) && !dmac_busy(d)) {
247 s = 0;
248 break;
249 }
250 }
251 if (s)
252 return s;
253
254 s = 100;
255
256 /* Good if free chans are more, bad otherwise */
257 s += (pi->pcfg.num_chan - dmac->busy_chan) - ch_onlyby_dmac(dmac);
258
259 return s;
260}
261
262/* More than one DMAC may have capability to transfer data with the
263 * peripheral. This function assigns most suitable DMAC to manage the
264 * channel and hence communicate with the peripheral.
265 */
266static struct s3c_pl330_dmac *map_chan_to_dmac(struct s3c_pl330_chan *ch)
267{
268 struct s3c_pl330_dmac *d, *dmac = NULL;
269 unsigned sn, sl = MIN_SUIT;
270
271 list_for_each_entry(d, &dmac_list, node) {
272 sn = suitablility(d, ch);
273
274 if (sn == MAX_SUIT)
275 return d;
276
277 if (sn > sl)
278 dmac = d;
279 }
280
281 return dmac;
282}
283
284/* Acquire the channel for peripheral 'id' */
285static struct s3c_pl330_chan *chan_acquire(const enum dma_ch id)
286{
287 struct s3c_pl330_chan *ch = id_to_chan(id);
288 struct s3c_pl330_dmac *dmac;
289
290 /* If the channel doesn't exist or is already acquired */
291 if (!ch || !chan_free(ch)) {
292 ch = NULL;
293 goto acq_exit;
294 }
295
296 dmac = map_chan_to_dmac(ch);
297 /* If couldn't map */
298 if (!dmac) {
299 ch = NULL;
300 goto acq_exit;
301 }
302
303 dmac->busy_chan++;
304 ch->dmac = dmac;
305
306acq_exit:
307 return ch;
308}
309
310/* Delete xfer from the queue */
311static inline void del_from_queue(struct s3c_pl330_xfer *xfer)
312{
313 struct s3c_pl330_xfer *t;
314 struct s3c_pl330_chan *ch;
315 int found;
316
317 if (!xfer)
318 return;
319
320 ch = xfer->chan;
321
322 /* Make sure xfer is in the queue */
323 found = 0;
324 list_for_each_entry(t, &ch->xfer_list, node)
325 if (t == xfer) {
326 found = 1;
327 break;
328 }
329
330 if (!found)
331 return;
332
333 /* If xfer is last entry in the queue */
334 if (xfer->node.next == &ch->xfer_list)
335 t = list_entry(ch->xfer_list.next,
336 struct s3c_pl330_xfer, node);
337 else
338 t = list_entry(xfer->node.next,
339 struct s3c_pl330_xfer, node);
340
341 /* If there was only one node left */
342 if (t == xfer)
343 ch->xfer_head = NULL;
344 else if (ch->xfer_head == xfer)
345 ch->xfer_head = t;
346
347 list_del(&xfer->node);
348}
349
350/* Provides pointer to the next xfer in the queue.
351 * If CIRCULAR option is set, the list is left intact,
352 * otherwise the xfer is removed from the list.
353 * Forced delete 'pluck' can be set to override the CIRCULAR option.
354 */
355static struct s3c_pl330_xfer *get_from_queue(struct s3c_pl330_chan *ch,
356 int pluck)
357{
358 struct s3c_pl330_xfer *xfer = ch->xfer_head;
359
360 if (!xfer)
361 return NULL;
362
363 /* If xfer is last entry in the queue */
364 if (xfer->node.next == &ch->xfer_list)
365 ch->xfer_head = list_entry(ch->xfer_list.next,
366 struct s3c_pl330_xfer, node);
367 else
368 ch->xfer_head = list_entry(xfer->node.next,
369 struct s3c_pl330_xfer, node);
370
371 if (pluck || !(ch->options & S3C2410_DMAF_CIRCULAR))
372 del_from_queue(xfer);
373
374 return xfer;
375}
376
377static inline void add_to_queue(struct s3c_pl330_chan *ch,
378 struct s3c_pl330_xfer *xfer, int front)
379{
380 struct pl330_xfer *xt;
381
382 /* If queue empty */
383 if (ch->xfer_head == NULL)
384 ch->xfer_head = xfer;
385
386 xt = &ch->xfer_head->px;
387 /* If the head already submitted (CIRCULAR head) */
388 if (ch->options & S3C2410_DMAF_CIRCULAR &&
389 (xt == ch->req[0].x || xt == ch->req[1].x))
390 ch->xfer_head = xfer;
391
392 /* If this is a resubmission, it should go at the head */
393 if (front) {
394 ch->xfer_head = xfer;
395 list_add(&xfer->node, &ch->xfer_list);
396 } else {
397 list_add_tail(&xfer->node, &ch->xfer_list);
398 }
399}
400
401static inline void _finish_off(struct s3c_pl330_xfer *xfer,
402 enum s3c2410_dma_buffresult res, int ffree)
403{
404 struct s3c_pl330_chan *ch;
405
406 if (!xfer)
407 return;
408
409 ch = xfer->chan;
410
411 /* Do callback */
412 if (ch->callback_fn)
413 ch->callback_fn(NULL, xfer->token, xfer->px.bytes, res);
414
415 /* Force Free or if buffer is not needed anymore */
416 if (ffree || !(ch->options & S3C2410_DMAF_CIRCULAR))
417 kmem_cache_free(ch->dmac->kmcache, xfer);
418}
419
420static inline int s3c_pl330_submit(struct s3c_pl330_chan *ch,
421 struct pl330_req *r)
422{
423 struct s3c_pl330_xfer *xfer;
424 int ret = 0;
425
426 /* If already submitted */
427 if (r->x)
428 return 0;
429
430 xfer = get_from_queue(ch, 0);
431 if (xfer) {
432 r->x = &xfer->px;
433
434 /* Use max bandwidth for M<->M xfers */
435 if (r->rqtype == MEMTOMEM) {
436 struct pl330_info *pi = xfer->chan->dmac->pi;
437 int burst = 1 << ch->rqcfg.brst_size;
438 u32 bytes = r->x->bytes;
439 int bl;
440
441 bl = pi->pcfg.data_bus_width / 8;
442 bl *= pi->pcfg.data_buf_dep;
443 bl /= burst;
444
445 /* src/dst_burst_len can't be more than 16 */
446 if (bl > 16)
447 bl = 16;
448
449 while (bl > 1) {
450 if (!(bytes % (bl * burst)))
451 break;
452 bl--;
453 }
454
455 ch->rqcfg.brst_len = bl;
456 } else {
457 ch->rqcfg.brst_len = 1;
458 }
459
460 ret = pl330_submit_req(ch->pl330_chan_id, r);
461
462 /* If submission was successful */
463 if (!ret) {
464 ch->lrq = r; /* latest submitted req */
465 return 0;
466 }
467
468 r->x = NULL;
469
470 /* If both of the PL330 ping-pong buffers filled */
471 if (ret == -EAGAIN) {
472 dev_err(ch->dmac->pi->dev, "%s:%d!\n",
473 __func__, __LINE__);
474 /* Queue back again */
475 add_to_queue(ch, xfer, 1);
476 ret = 0;
477 } else {
478 dev_err(ch->dmac->pi->dev, "%s:%d!\n",
479 __func__, __LINE__);
480 _finish_off(xfer, S3C2410_RES_ERR, 0);
481 }
482 }
483
484 return ret;
485}
486
487static void s3c_pl330_rq(struct s3c_pl330_chan *ch,
488 struct pl330_req *r, enum pl330_op_err err)
489{
490 unsigned long flags;
491 struct s3c_pl330_xfer *xfer;
492 struct pl330_xfer *xl = r->x;
493 enum s3c2410_dma_buffresult res;
494
495 spin_lock_irqsave(&res_lock, flags);
496
497 r->x = NULL;
498
499 s3c_pl330_submit(ch, r);
500
501 spin_unlock_irqrestore(&res_lock, flags);
502
503 /* Map result to S3C DMA API */
504 if (err == PL330_ERR_NONE)
505 res = S3C2410_RES_OK;
506 else if (err == PL330_ERR_ABORT)
507 res = S3C2410_RES_ABORT;
508 else
509 res = S3C2410_RES_ERR;
510
511 /* If last request had some xfer */
512 if (xl) {
513 xfer = container_of(xl, struct s3c_pl330_xfer, px);
514 _finish_off(xfer, res, 0);
515 } else {
516 dev_info(ch->dmac->pi->dev, "%s:%d No Xfer?!\n",
517 __func__, __LINE__);
518 }
519}
520
521static void s3c_pl330_rq0(void *token, enum pl330_op_err err)
522{
523 struct pl330_req *r = token;
524 struct s3c_pl330_chan *ch = container_of(r,
525 struct s3c_pl330_chan, req[0]);
526 s3c_pl330_rq(ch, r, err);
527}
528
529static void s3c_pl330_rq1(void *token, enum pl330_op_err err)
530{
531 struct pl330_req *r = token;
532 struct s3c_pl330_chan *ch = container_of(r,
533 struct s3c_pl330_chan, req[1]);
534 s3c_pl330_rq(ch, r, err);
535}
536
537/* Release an acquired channel */
538static void chan_release(struct s3c_pl330_chan *ch)
539{
540 struct s3c_pl330_dmac *dmac;
541
542 if (chan_free(ch))
543 return;
544
545 dmac = ch->dmac;
546 ch->dmac = NULL;
547 dmac->busy_chan--;
548}
549
550int s3c2410_dma_ctrl(enum dma_ch id, enum s3c2410_chan_op op)
551{
552 struct s3c_pl330_xfer *xfer;
553 enum pl330_chan_op pl330op;
554 struct s3c_pl330_chan *ch;
555 unsigned long flags;
556 int idx, ret;
557
558 spin_lock_irqsave(&res_lock, flags);
559
560 ch = id_to_chan(id);
561
562 if (!ch || chan_free(ch)) {
563 ret = -EINVAL;
564 goto ctrl_exit;
565 }
566
567 switch (op) {
568 case S3C2410_DMAOP_START:
569 /* Make sure both reqs are enqueued */
570 idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
571 s3c_pl330_submit(ch, &ch->req[idx]);
572 s3c_pl330_submit(ch, &ch->req[1 - idx]);
573 pl330op = PL330_OP_START;
574 break;
575
576 case S3C2410_DMAOP_STOP:
577 pl330op = PL330_OP_ABORT;
578 break;
579
580 case S3C2410_DMAOP_FLUSH:
581 pl330op = PL330_OP_FLUSH;
582 break;
583
584 case S3C2410_DMAOP_PAUSE:
585 case S3C2410_DMAOP_RESUME:
586 case S3C2410_DMAOP_TIMEOUT:
587 case S3C2410_DMAOP_STARTED:
588 spin_unlock_irqrestore(&res_lock, flags);
589 return 0;
590
591 default:
592 spin_unlock_irqrestore(&res_lock, flags);
593 return -EINVAL;
594 }
595
596 ret = pl330_chan_ctrl(ch->pl330_chan_id, pl330op);
597
598 if (pl330op == PL330_OP_START) {
599 spin_unlock_irqrestore(&res_lock, flags);
600 return ret;
601 }
602
603 idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
604
605 /* Abort the current xfer */
606 if (ch->req[idx].x) {
607 xfer = container_of(ch->req[idx].x,
608 struct s3c_pl330_xfer, px);
609
610 /* Drop xfer during FLUSH */
611 if (pl330op == PL330_OP_FLUSH)
612 del_from_queue(xfer);
613
614 ch->req[idx].x = NULL;
615
616 spin_unlock_irqrestore(&res_lock, flags);
617 _finish_off(xfer, S3C2410_RES_ABORT,
618 pl330op == PL330_OP_FLUSH ? 1 : 0);
619 spin_lock_irqsave(&res_lock, flags);
620 }
621
622 /* Flush the whole queue */
623 if (pl330op == PL330_OP_FLUSH) {
624
625 if (ch->req[1 - idx].x) {
626 xfer = container_of(ch->req[1 - idx].x,
627 struct s3c_pl330_xfer, px);
628
629 del_from_queue(xfer);
630
631 ch->req[1 - idx].x = NULL;
632
633 spin_unlock_irqrestore(&res_lock, flags);
634 _finish_off(xfer, S3C2410_RES_ABORT, 1);
635 spin_lock_irqsave(&res_lock, flags);
636 }
637
638 /* Finish off the remaining in the queue */
639 xfer = ch->xfer_head;
640 while (xfer) {
641
642 del_from_queue(xfer);
643
644 spin_unlock_irqrestore(&res_lock, flags);
645 _finish_off(xfer, S3C2410_RES_ABORT, 1);
646 spin_lock_irqsave(&res_lock, flags);
647
648 xfer = ch->xfer_head;
649 }
650 }
651
652ctrl_exit:
653 spin_unlock_irqrestore(&res_lock, flags);
654
655 return ret;
656}
657EXPORT_SYMBOL(s3c2410_dma_ctrl);
658
659int s3c2410_dma_enqueue(enum dma_ch id, void *token,
660 dma_addr_t addr, int size)
661{
662 struct s3c_pl330_chan *ch;
663 struct s3c_pl330_xfer *xfer;
664 unsigned long flags;
665 int idx, ret = 0;
666
667 spin_lock_irqsave(&res_lock, flags);
668
669 ch = id_to_chan(id);
670
671 /* Error if invalid or free channel */
672 if (!ch || chan_free(ch)) {
673 ret = -EINVAL;
674 goto enq_exit;
675 }
676
677 /* Error if size is unaligned */
678 if (ch->rqcfg.brst_size && size % (1 << ch->rqcfg.brst_size)) {
679 ret = -EINVAL;
680 goto enq_exit;
681 }
682
683 xfer = kmem_cache_alloc(ch->dmac->kmcache, GFP_ATOMIC);
684 if (!xfer) {
685 ret = -ENOMEM;
686 goto enq_exit;
687 }
688
689 xfer->token = token;
690 xfer->chan = ch;
691 xfer->px.bytes = size;
692 xfer->px.next = NULL; /* Single request */
693
694 /* For S3C DMA API, direction is always fixed for all xfers */
695 if (ch->req[0].rqtype == MEMTODEV) {
696 xfer->px.src_addr = addr;
697 xfer->px.dst_addr = ch->sdaddr;
698 } else {
699 xfer->px.src_addr = ch->sdaddr;
700 xfer->px.dst_addr = addr;
701 }
702
703 add_to_queue(ch, xfer, 0);
704
705 /* Try submitting on either request */
706 idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
707
708 if (!ch->req[idx].x)
709 s3c_pl330_submit(ch, &ch->req[idx]);
710 else
711 s3c_pl330_submit(ch, &ch->req[1 - idx]);
712
713 spin_unlock_irqrestore(&res_lock, flags);
714
715 if (ch->options & S3C2410_DMAF_AUTOSTART)
716 s3c2410_dma_ctrl(id, S3C2410_DMAOP_START);
717
718 return 0;
719
720enq_exit:
721 spin_unlock_irqrestore(&res_lock, flags);
722
723 return ret;
724}
725EXPORT_SYMBOL(s3c2410_dma_enqueue);
726
727int s3c2410_dma_request(enum dma_ch id,
728 struct s3c2410_dma_client *client,
729 void *dev)
730{
731 struct s3c_pl330_dmac *dmac;
732 struct s3c_pl330_chan *ch;
733 unsigned long flags;
734 int ret = 0;
735
736 spin_lock_irqsave(&res_lock, flags);
737
738 ch = chan_acquire(id);
739 if (!ch) {
740 ret = -EBUSY;
741 goto req_exit;
742 }
743
744 dmac = ch->dmac;
745
746 ch->pl330_chan_id = pl330_request_channel(dmac->pi);
747 if (!ch->pl330_chan_id) {
748 chan_release(ch);
749 ret = -EBUSY;
750 goto req_exit;
751 }
752
753 ch->client = client;
754 ch->options = 0; /* Clear any option */
755 ch->callback_fn = NULL; /* Clear any callback */
756 ch->lrq = NULL;
757
758 ch->rqcfg.brst_size = 2; /* Default word size */
759 ch->rqcfg.swap = SWAP_NO;
760 ch->rqcfg.scctl = SCCTRL0; /* Noncacheable and nonbufferable */
761 ch->rqcfg.dcctl = DCCTRL0; /* Noncacheable and nonbufferable */
762 ch->rqcfg.privileged = 0;
763 ch->rqcfg.insnaccess = 0;
764
765 /* Set invalid direction */
766 ch->req[0].rqtype = DEVTODEV;
767 ch->req[1].rqtype = ch->req[0].rqtype;
768
769 ch->req[0].cfg = &ch->rqcfg;
770 ch->req[1].cfg = ch->req[0].cfg;
771
772 ch->req[0].peri = iface_of_dmac(dmac, id) - 1; /* Original index */
773 ch->req[1].peri = ch->req[0].peri;
774
775 ch->req[0].token = &ch->req[0];
776 ch->req[0].xfer_cb = s3c_pl330_rq0;
777 ch->req[1].token = &ch->req[1];
778 ch->req[1].xfer_cb = s3c_pl330_rq1;
779
780 ch->req[0].x = NULL;
781 ch->req[1].x = NULL;
782
783 /* Reset xfer list */
784 INIT_LIST_HEAD(&ch->xfer_list);
785 ch->xfer_head = NULL;
786
787req_exit:
788 spin_unlock_irqrestore(&res_lock, flags);
789
790 return ret;
791}
792EXPORT_SYMBOL(s3c2410_dma_request);
793
794int s3c2410_dma_free(enum dma_ch id, struct s3c2410_dma_client *client)
795{
796 struct s3c_pl330_chan *ch;
797 struct s3c_pl330_xfer *xfer;
798 unsigned long flags;
799 int ret = 0;
800 unsigned idx;
801
802 spin_lock_irqsave(&res_lock, flags);
803
804 ch = id_to_chan(id);
805
806 if (!ch || chan_free(ch))
807 goto free_exit;
808
809 /* Refuse if someone else wanted to free the channel */
810 if (ch->client != client) {
811 ret = -EBUSY;
812 goto free_exit;
813 }
814
815 /* Stop any active xfer, Flushe the queue and do callbacks */
816 pl330_chan_ctrl(ch->pl330_chan_id, PL330_OP_FLUSH);
817
818 /* Abort the submitted requests */
819 idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
820
821 if (ch->req[idx].x) {
822 xfer = container_of(ch->req[idx].x,
823 struct s3c_pl330_xfer, px);
824
825 ch->req[idx].x = NULL;
826 del_from_queue(xfer);
827
828 spin_unlock_irqrestore(&res_lock, flags);
829 _finish_off(xfer, S3C2410_RES_ABORT, 1);
830 spin_lock_irqsave(&res_lock, flags);
831 }
832
833 if (ch->req[1 - idx].x) {
834 xfer = container_of(ch->req[1 - idx].x,
835 struct s3c_pl330_xfer, px);
836
837 ch->req[1 - idx].x = NULL;
838 del_from_queue(xfer);
839
840 spin_unlock_irqrestore(&res_lock, flags);
841 _finish_off(xfer, S3C2410_RES_ABORT, 1);
842 spin_lock_irqsave(&res_lock, flags);
843 }
844
845 /* Pluck and Abort the queued requests in order */
846 do {
847 xfer = get_from_queue(ch, 1);
848
849 spin_unlock_irqrestore(&res_lock, flags);
850 _finish_off(xfer, S3C2410_RES_ABORT, 1);
851 spin_lock_irqsave(&res_lock, flags);
852 } while (xfer);
853
854 ch->client = NULL;
855
856 pl330_release_channel(ch->pl330_chan_id);
857
858 ch->pl330_chan_id = NULL;
859
860 chan_release(ch);
861
862free_exit:
863 spin_unlock_irqrestore(&res_lock, flags);
864
865 return ret;
866}
867EXPORT_SYMBOL(s3c2410_dma_free);
868
869int s3c2410_dma_config(enum dma_ch id, int xferunit)
870{
871 struct s3c_pl330_chan *ch;
872 struct pl330_info *pi;
873 unsigned long flags;
874 int i, dbwidth, ret = 0;
875
876 spin_lock_irqsave(&res_lock, flags);
877
878 ch = id_to_chan(id);
879
880 if (!ch || chan_free(ch)) {
881 ret = -EINVAL;
882 goto cfg_exit;
883 }
884
885 pi = ch->dmac->pi;
886 dbwidth = pi->pcfg.data_bus_width / 8;
887
888 /* Max size of xfer can be pcfg.data_bus_width */
889 if (xferunit > dbwidth) {
890 ret = -EINVAL;
891 goto cfg_exit;
892 }
893
894 i = 0;
895 while (xferunit != (1 << i))
896 i++;
897
898 /* If valid value */
899 if (xferunit == (1 << i))
900 ch->rqcfg.brst_size = i;
901 else
902 ret = -EINVAL;
903
904cfg_exit:
905 spin_unlock_irqrestore(&res_lock, flags);
906
907 return ret;
908}
909EXPORT_SYMBOL(s3c2410_dma_config);
910
911/* Options that are supported by this driver */
912#define S3C_PL330_FLAGS (S3C2410_DMAF_CIRCULAR | S3C2410_DMAF_AUTOSTART)
913
914int s3c2410_dma_setflags(enum dma_ch id, unsigned int options)
915{
916 struct s3c_pl330_chan *ch;
917 unsigned long flags;
918 int ret = 0;
919
920 spin_lock_irqsave(&res_lock, flags);
921
922 ch = id_to_chan(id);
923
924 if (!ch || chan_free(ch) || options & ~(S3C_PL330_FLAGS))
925 ret = -EINVAL;
926 else
927 ch->options = options;
928
929 spin_unlock_irqrestore(&res_lock, flags);
930
931 return 0;
932}
933EXPORT_SYMBOL(s3c2410_dma_setflags);
934
935int s3c2410_dma_set_buffdone_fn(enum dma_ch id, s3c2410_dma_cbfn_t rtn)
936{
937 struct s3c_pl330_chan *ch;
938 unsigned long flags;
939 int ret = 0;
940
941 spin_lock_irqsave(&res_lock, flags);
942
943 ch = id_to_chan(id);
944
945 if (!ch || chan_free(ch))
946 ret = -EINVAL;
947 else
948 ch->callback_fn = rtn;
949
950 spin_unlock_irqrestore(&res_lock, flags);
951
952 return ret;
953}
954EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
955
956int s3c2410_dma_devconfig(enum dma_ch id, enum s3c2410_dmasrc source,
957 unsigned long address)
958{
959 struct s3c_pl330_chan *ch;
960 unsigned long flags;
961 int ret = 0;
962
963 spin_lock_irqsave(&res_lock, flags);
964
965 ch = id_to_chan(id);
966
967 if (!ch || chan_free(ch)) {
968 ret = -EINVAL;
969 goto devcfg_exit;
970 }
971
972 switch (source) {
973 case S3C2410_DMASRC_HW: /* P->M */
974 ch->req[0].rqtype = DEVTOMEM;
975 ch->req[1].rqtype = DEVTOMEM;
976 ch->rqcfg.src_inc = 0;
977 ch->rqcfg.dst_inc = 1;
978 break;
979 case S3C2410_DMASRC_MEM: /* M->P */
980 ch->req[0].rqtype = MEMTODEV;
981 ch->req[1].rqtype = MEMTODEV;
982 ch->rqcfg.src_inc = 1;
983 ch->rqcfg.dst_inc = 0;
984 break;
985 default:
986 ret = -EINVAL;
987 goto devcfg_exit;
988 }
989
990 ch->sdaddr = address;
991
992devcfg_exit:
993 spin_unlock_irqrestore(&res_lock, flags);
994
995 return ret;
996}
997EXPORT_SYMBOL(s3c2410_dma_devconfig);
998
999int s3c2410_dma_getposition(enum dma_ch id, dma_addr_t *src, dma_addr_t *dst)
1000{
1001 struct s3c_pl330_chan *ch = id_to_chan(id);
1002 struct pl330_chanstatus status;
1003 int ret;
1004
1005 if (!ch || chan_free(ch))
1006 return -EINVAL;
1007
1008 ret = pl330_chan_status(ch->pl330_chan_id, &status);
1009 if (ret < 0)
1010 return ret;
1011
1012 *src = status.src_addr;
1013 *dst = status.dst_addr;
1014
1015 return 0;
1016}
1017EXPORT_SYMBOL(s3c2410_dma_getposition);
1018
1019static irqreturn_t pl330_irq_handler(int irq, void *data)
1020{
1021 if (pl330_update(data))
1022 return IRQ_HANDLED;
1023 else
1024 return IRQ_NONE;
1025}
1026
1027static int pl330_probe(struct platform_device *pdev)
1028{
1029 struct s3c_pl330_dmac *s3c_pl330_dmac;
1030 struct s3c_pl330_platdata *pl330pd;
1031 struct pl330_info *pl330_info;
1032 struct resource *res;
1033 int i, ret, irq;
1034
1035 pl330pd = pdev->dev.platform_data;
1036
1037 /* Can't do without the list of _32_ peripherals */
1038 if (!pl330pd || !pl330pd->peri) {
1039 dev_err(&pdev->dev, "platform data missing!\n");
1040 return -ENODEV;
1041 }
1042
1043 pl330_info = kzalloc(sizeof(*pl330_info), GFP_KERNEL);
1044 if (!pl330_info)
1045 return -ENOMEM;
1046
1047 pl330_info->pl330_data = NULL;
1048 pl330_info->dev = &pdev->dev;
1049
1050 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1051 if (!res) {
1052 ret = -ENODEV;
1053 goto probe_err1;
1054 }
1055
1056 request_mem_region(res->start, resource_size(res), pdev->name);
1057
1058 pl330_info->base = ioremap(res->start, resource_size(res));
1059 if (!pl330_info->base) {
1060 ret = -ENXIO;
1061 goto probe_err2;
1062 }
1063
1064 irq = platform_get_irq(pdev, 0);
1065 if (irq < 0) {
1066 ret = irq;
1067 goto probe_err3;
1068 }
1069
1070 ret = request_irq(irq, pl330_irq_handler, 0,
1071 dev_name(&pdev->dev), pl330_info);
1072 if (ret)
1073 goto probe_err4;
1074
1075 ret = pl330_add(pl330_info);
1076 if (ret)
1077 goto probe_err5;
1078
1079 /* Allocate a new DMAC */
1080 s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL);
1081 if (!s3c_pl330_dmac) {
1082 ret = -ENOMEM;
1083 goto probe_err6;
1084 }
1085
1086 /* Hook the info */
1087 s3c_pl330_dmac->pi = pl330_info;
1088
1089 /* No busy channels */
1090 s3c_pl330_dmac->busy_chan = 0;
1091
1092 s3c_pl330_dmac->kmcache = kmem_cache_create(dev_name(&pdev->dev),
1093 sizeof(struct s3c_pl330_xfer), 0, 0, NULL);
1094
1095 if (!s3c_pl330_dmac->kmcache) {
1096 ret = -ENOMEM;
1097 goto probe_err7;
1098 }
1099
1100 /* Get the list of peripherals */
1101 s3c_pl330_dmac->peri = pl330pd->peri;
1102
1103 /* Attach to the list of DMACs */
1104 list_add_tail(&s3c_pl330_dmac->node, &dmac_list);
1105
1106 /* Create a channel for each peripheral in the DMAC
1107 * that is, if it doesn't already exist
1108 */
1109 for (i = 0; i < PL330_MAX_PERI; i++)
1110 if (s3c_pl330_dmac->peri[i] != DMACH_MAX)
1111 chan_add(s3c_pl330_dmac->peri[i]);
1112
1113 printk(KERN_INFO
1114 "Loaded driver for PL330 DMAC-%d %s\n", pdev->id, pdev->name);
1115 printk(KERN_INFO
1116 "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n",
1117 pl330_info->pcfg.data_buf_dep,
1118 pl330_info->pcfg.data_bus_width / 8, pl330_info->pcfg.num_chan,
1119 pl330_info->pcfg.num_peri, pl330_info->pcfg.num_events);
1120
1121 return 0;
1122
1123probe_err7:
1124 kfree(s3c_pl330_dmac);
1125probe_err6:
1126 pl330_del(pl330_info);
1127probe_err5:
1128 free_irq(irq, pl330_info);
1129probe_err4:
1130probe_err3:
1131 iounmap(pl330_info->base);
1132probe_err2:
1133 release_mem_region(res->start, resource_size(res));
1134probe_err1:
1135 kfree(pl330_info);
1136
1137 return ret;
1138}
1139
1140static int pl330_remove(struct platform_device *pdev)
1141{
1142 struct s3c_pl330_dmac *dmac, *d;
1143 struct s3c_pl330_chan *ch;
1144 unsigned long flags;
1145 int del, found;
1146
1147 if (!pdev->dev.platform_data)
1148 return -EINVAL;
1149
1150 spin_lock_irqsave(&res_lock, flags);
1151
1152 found = 0;
1153 list_for_each_entry(d, &dmac_list, node)
1154 if (d->pi->dev == &pdev->dev) {
1155 found = 1;
1156 break;
1157 }
1158
1159 if (!found) {
1160 spin_unlock_irqrestore(&res_lock, flags);
1161 return 0;
1162 }
1163
1164 dmac = d;
1165
1166 /* Remove all Channels that are managed only by this DMAC */
1167 list_for_each_entry(ch, &chan_list, node) {
1168
1169 /* Only channels that are handled by this DMAC */
1170 if (iface_of_dmac(dmac, ch->id))
1171 del = 1;
1172 else
1173 continue;
1174
1175 /* Don't remove if some other DMAC has it too */
1176 list_for_each_entry(d, &dmac_list, node)
1177 if (d != dmac && iface_of_dmac(d, ch->id)) {
1178 del = 0;
1179 break;
1180 }
1181
1182 if (del) {
1183 spin_unlock_irqrestore(&res_lock, flags);
1184 s3c2410_dma_free(ch->id, ch->client);
1185 spin_lock_irqsave(&res_lock, flags);
1186 list_del(&ch->node);
1187 kfree(ch);
1188 }
1189 }
1190
1191 /* Remove the DMAC */
1192 list_del(&dmac->node);
1193 kfree(dmac);
1194
1195 spin_unlock_irqrestore(&res_lock, flags);
1196
1197 return 0;
1198}
1199
1200static struct platform_driver pl330_driver = {
1201 .driver = {
1202 .owner = THIS_MODULE,
1203 .name = "s3c-pl330",
1204 },
1205 .probe = pl330_probe,
1206 .remove = pl330_remove,
1207};
1208
1209static int __init pl330_init(void)
1210{
1211 return platform_driver_register(&pl330_driver);
1212}
1213module_init(pl330_init);
1214
1215static void __exit pl330_exit(void)
1216{
1217 platform_driver_unregister(&pl330_driver);
1218 return;
1219}
1220module_exit(pl330_exit);
1221
1222MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");
1223MODULE_DESCRIPTION("Driver for PL330 DMA Controller");
1224MODULE_LICENSE("GPL");
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index f55c49475a8c..5f3f03df92e3 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -518,12 +518,13 @@ config SERIAL_S3C2412
518 Serial port support for the Samsung S3C2412 and S3C2413 SoC 518 Serial port support for the Samsung S3C2412 and S3C2413 SoC
519 519
520config SERIAL_S3C2440 520config SERIAL_S3C2440
521 tristate "Samsung S3C2440/S3C2442 Serial port support" 521 tristate "Samsung S3C2440/S3C2442/S3C2416 Serial port support"
522 depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442) 522 depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442 || CPU_S3C2416)
523 default y if CPU_S3C2440 523 default y if CPU_S3C2440
524 default y if CPU_S3C2442 524 default y if CPU_S3C2442
525 select SERIAL_SAMSUNG_UARTS_4 if CPU_S3C2416
525 help 526 help
526 Serial port support for the Samsung S3C2440 and S3C2442 SoC 527 Serial port support for the Samsung S3C2440, S3C2416 and S3C2442 SoC
527 528
528config SERIAL_S3C24A0 529config SERIAL_S3C24A0
529 tristate "Samsung S3C24A0 Serial port support" 530 tristate "Samsung S3C24A0 Serial port support"