aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-s3c64xx/clock.c2
-rw-r--r--arch/arm/mach-s3c64xx/dev-audio.c60
-rw-r--r--arch/arm/mach-s3c64xx/irq-eint.c37
-rw-r--r--arch/arm/mach-s5p6442/dev-audio.c44
-rw-r--r--arch/arm/mach-s5p6442/mach-smdk6442.c10
-rw-r--r--arch/arm/mach-s5p6442/setup-i2c0.c5
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6440.c2
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6450.c14
-rw-r--r--arch/arm/mach-s5p64x0/dev-audio.c144
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/map.h2
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6440.c1
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6450.c1
-rw-r--r--arch/arm/mach-s5pc100/dev-audio.c54
-rw-r--r--arch/arm/mach-s5pv210/clock.c10
-rw-r--r--arch/arm/mach-s5pv210/dev-audio.c56
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkc110.c1
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkv210.c1
-rw-r--r--arch/arm/mach-s5pv310/Kconfig5
-rw-r--r--arch/arm/mach-s5pv310/Makefile3
-rw-r--r--arch/arm/mach-s5pv310/clock.c30
-rw-r--r--arch/arm/mach-s5pv310/dev-audio.c364
-rw-r--r--arch/arm/mach-s5pv310/dma.c168
-rw-r--r--arch/arm/mach-s5pv310/include/mach/dma.h26
-rw-r--r--arch/arm/mach-s5pv310/include/mach/irqs.h3
-rw-r--r--arch/arm/mach-s5pv310/include/mach/map.h21
-rw-r--r--arch/arm/mach-s5pv310/irq-eint.c2
-rw-r--r--arch/arm/mach-s5pv310/mach-smdkc210.c12
-rw-r--r--arch/arm/mach-s5pv310/mach-smdkv310.c12
-rw-r--r--arch/arm/plat-s3c24xx/irq.c2
-rw-r--r--arch/arm/plat-s5p/irq-eint.c4
-rw-r--r--arch/arm/plat-samsung/Kconfig8
-rw-r--r--arch/arm/plat-samsung/Makefile4
-rw-r--r--arch/arm/plat-samsung/include/plat/audio.h24
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h11
-rw-r--r--arch/arm/plat-samsung/include/plat/pd.h30
-rw-r--r--arch/arm/plat-samsung/include/plat/pm.h4
-rw-r--r--arch/arm/plat-samsung/irq-uart.c36
-rw-r--r--arch/arm/plat-samsung/irq-vic-timer.c22
-rw-r--r--arch/arm/plat-samsung/pd.c95
-rw-r--r--arch/arm/plat-samsung/pm.c6
40 files changed, 1183 insertions, 153 deletions
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
index 7e03f0ae2fc8..1c98d2ff2ed6 100644
--- a/arch/arm/mach-s3c64xx/clock.c
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -695,7 +695,7 @@ static struct clksrc_clk clksrcs[] = {
695 }, { 695 }, {
696 .clk = { 696 .clk = {
697 .name = "audio-bus", 697 .name = "audio-bus",
698 .id = -1, /* There's only one IISv4 port */ 698 .id = 2,
699 .ctrlbit = S3C6410_CLKCON_SCLK_AUDIO2, 699 .ctrlbit = S3C6410_CLKCON_SCLK_AUDIO2,
700 .enable = s3c64xx_sclk_ctrl, 700 .enable = s3c64xx_sclk_ctrl,
701 }, 701 },
diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c
index 76426a32c013..7618627b98f5 100644
--- a/arch/arm/mach-s3c64xx/dev-audio.c
+++ b/arch/arm/mach-s3c64xx/dev-audio.c
@@ -22,7 +22,12 @@
22#include <plat/audio.h> 22#include <plat/audio.h>
23#include <plat/gpio-cfg.h> 23#include <plat/gpio-cfg.h>
24 24
25static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev) 25static const char *rclksrc[] = {
26 [0] = "iis",
27 [1] = "audio-bus",
28};
29
30static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev)
26{ 31{
27 unsigned int base; 32 unsigned int base;
28 33
@@ -33,6 +38,12 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
33 case 1: 38 case 1:
34 base = S3C64XX_GPE(0); 39 base = S3C64XX_GPE(0);
35 break; 40 break;
41 case 2:
42 s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
43 s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
44 s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
45 s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
46 return 0;
36 default: 47 default:
37 printk(KERN_DEBUG "Invalid I2S Controller number: %d\n", 48 printk(KERN_DEBUG "Invalid I2S Controller number: %d\n",
38 pdev->id); 49 pdev->id);
@@ -44,16 +55,6 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
44 return 0; 55 return 0;
45} 56}
46 57
47static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev)
48{
49 s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
50 s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
51 s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
52 s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
53
54 return 0;
55}
56
57static struct resource s3c64xx_iis0_resource[] = { 58static struct resource s3c64xx_iis0_resource[] = {
58 [0] = { 59 [0] = {
59 .start = S3C64XX_PA_IIS0, 60 .start = S3C64XX_PA_IIS0,
@@ -72,17 +73,22 @@ static struct resource s3c64xx_iis0_resource[] = {
72 }, 73 },
73}; 74};
74 75
75static struct s3c_audio_pdata s3c_i2s0_pdata = { 76static struct s3c_audio_pdata i2sv3_pdata = {
76 .cfg_gpio = s3c64xx_i2sv3_cfg_gpio, 77 .cfg_gpio = s3c64xx_i2s_cfg_gpio,
78 .type = {
79 .i2s = {
80 .src_clk = rclksrc,
81 },
82 },
77}; 83};
78 84
79struct platform_device s3c64xx_device_iis0 = { 85struct platform_device s3c64xx_device_iis0 = {
80 .name = "s3c64xx-iis", 86 .name = "samsung-i2s",
81 .id = 0, 87 .id = 0,
82 .num_resources = ARRAY_SIZE(s3c64xx_iis0_resource), 88 .num_resources = ARRAY_SIZE(s3c64xx_iis0_resource),
83 .resource = s3c64xx_iis0_resource, 89 .resource = s3c64xx_iis0_resource,
84 .dev = { 90 .dev = {
85 .platform_data = &s3c_i2s0_pdata, 91 .platform_data = &i2sv3_pdata,
86 }, 92 },
87}; 93};
88EXPORT_SYMBOL(s3c64xx_device_iis0); 94EXPORT_SYMBOL(s3c64xx_device_iis0);
@@ -105,17 +111,13 @@ static struct resource s3c64xx_iis1_resource[] = {
105 }, 111 },
106}; 112};
107 113
108static struct s3c_audio_pdata s3c_i2s1_pdata = {
109 .cfg_gpio = s3c64xx_i2sv3_cfg_gpio,
110};
111
112struct platform_device s3c64xx_device_iis1 = { 114struct platform_device s3c64xx_device_iis1 = {
113 .name = "s3c64xx-iis", 115 .name = "samsung-i2s",
114 .id = 1, 116 .id = 1,
115 .num_resources = ARRAY_SIZE(s3c64xx_iis1_resource), 117 .num_resources = ARRAY_SIZE(s3c64xx_iis1_resource),
116 .resource = s3c64xx_iis1_resource, 118 .resource = s3c64xx_iis1_resource,
117 .dev = { 119 .dev = {
118 .platform_data = &s3c_i2s1_pdata, 120 .platform_data = &i2sv3_pdata,
119 }, 121 },
120}; 122};
121EXPORT_SYMBOL(s3c64xx_device_iis1); 123EXPORT_SYMBOL(s3c64xx_device_iis1);
@@ -138,17 +140,23 @@ static struct resource s3c64xx_iisv4_resource[] = {
138 }, 140 },
139}; 141};
140 142
141static struct s3c_audio_pdata s3c_i2sv4_pdata = { 143static struct s3c_audio_pdata i2sv4_pdata = {
142 .cfg_gpio = s3c64xx_i2sv4_cfg_gpio, 144 .cfg_gpio = s3c64xx_i2s_cfg_gpio,
145 .type = {
146 .i2s = {
147 .quirks = QUIRK_PRI_6CHAN,
148 .src_clk = rclksrc,
149 },
150 },
143}; 151};
144 152
145struct platform_device s3c64xx_device_iisv4 = { 153struct platform_device s3c64xx_device_iisv4 = {
146 .name = "s3c64xx-iis-v4", 154 .name = "samsung-i2s",
147 .id = -1, 155 .id = 2,
148 .num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource), 156 .num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource),
149 .resource = s3c64xx_iisv4_resource, 157 .resource = s3c64xx_iisv4_resource,
150 .dev = { 158 .dev = {
151 .platform_data = &s3c_i2sv4_pdata, 159 .platform_data = &i2sv4_pdata,
152 }, 160 },
153}; 161};
154EXPORT_SYMBOL(s3c64xx_device_iisv4); 162EXPORT_SYMBOL(s3c64xx_device_iisv4);
diff --git a/arch/arm/mach-s3c64xx/irq-eint.c b/arch/arm/mach-s3c64xx/irq-eint.c
index 5682d6a7f4af..2ead8189da74 100644
--- a/arch/arm/mach-s3c64xx/irq-eint.c
+++ b/arch/arm/mach-s3c64xx/irq-eint.c
@@ -30,41 +30,41 @@
30#include <plat/pm.h> 30#include <plat/pm.h>
31 31
32#define eint_offset(irq) ((irq) - IRQ_EINT(0)) 32#define eint_offset(irq) ((irq) - IRQ_EINT(0))
33#define eint_irq_to_bit(irq) (1 << eint_offset(irq)) 33#define eint_irq_to_bit(irq) ((u32)(1 << eint_offset(irq)))
34 34
35static inline void s3c_irq_eint_mask(unsigned int irq) 35static inline void s3c_irq_eint_mask(struct irq_data *data)
36{ 36{
37 u32 mask; 37 u32 mask;
38 38
39 mask = __raw_readl(S3C64XX_EINT0MASK); 39 mask = __raw_readl(S3C64XX_EINT0MASK);
40 mask |= eint_irq_to_bit(irq); 40 mask |= (u32)data->chip_data;
41 __raw_writel(mask, S3C64XX_EINT0MASK); 41 __raw_writel(mask, S3C64XX_EINT0MASK);
42} 42}
43 43
44static void s3c_irq_eint_unmask(unsigned int irq) 44static void s3c_irq_eint_unmask(struct irq_data *data)
45{ 45{
46 u32 mask; 46 u32 mask;
47 47
48 mask = __raw_readl(S3C64XX_EINT0MASK); 48 mask = __raw_readl(S3C64XX_EINT0MASK);
49 mask &= ~eint_irq_to_bit(irq); 49 mask &= ~((u32)data->chip_data);
50 __raw_writel(mask, S3C64XX_EINT0MASK); 50 __raw_writel(mask, S3C64XX_EINT0MASK);
51} 51}
52 52
53static inline void s3c_irq_eint_ack(unsigned int irq) 53static inline void s3c_irq_eint_ack(struct irq_data *data)
54{ 54{
55 __raw_writel(eint_irq_to_bit(irq), S3C64XX_EINT0PEND); 55 __raw_writel((u32)data->chip_data, S3C64XX_EINT0PEND);
56} 56}
57 57
58static void s3c_irq_eint_maskack(unsigned int irq) 58static void s3c_irq_eint_maskack(struct irq_data *data)
59{ 59{
60 /* compiler should in-line these */ 60 /* compiler should in-line these */
61 s3c_irq_eint_mask(irq); 61 s3c_irq_eint_mask(data);
62 s3c_irq_eint_ack(irq); 62 s3c_irq_eint_ack(data);
63} 63}
64 64
65static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type) 65static int s3c_irq_eint_set_type(struct irq_data *data, unsigned int type)
66{ 66{
67 int offs = eint_offset(irq); 67 int offs = eint_offset(data->irq);
68 int pin, pin_val; 68 int pin, pin_val;
69 int shift; 69 int shift;
70 u32 ctrl, mask; 70 u32 ctrl, mask;
@@ -140,12 +140,12 @@ static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
140 140
141static struct irq_chip s3c_irq_eint = { 141static struct irq_chip s3c_irq_eint = {
142 .name = "s3c-eint", 142 .name = "s3c-eint",
143 .mask = s3c_irq_eint_mask, 143 .irq_mask = s3c_irq_eint_mask,
144 .unmask = s3c_irq_eint_unmask, 144 .irq_unmask = s3c_irq_eint_unmask,
145 .mask_ack = s3c_irq_eint_maskack, 145 .irq_mask_ack = s3c_irq_eint_maskack,
146 .ack = s3c_irq_eint_ack, 146 .irq_ack = s3c_irq_eint_ack,
147 .set_type = s3c_irq_eint_set_type, 147 .irq_set_type = s3c_irq_eint_set_type,
148 .set_wake = s3c_irqext_wake, 148 .irq_set_wake = s3c_irqext_wake,
149}; 149};
150 150
151/* s3c_irq_demux_eint 151/* s3c_irq_demux_eint
@@ -198,6 +198,7 @@ static int __init s3c64xx_init_irq_eint(void)
198 198
199 for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) { 199 for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
200 set_irq_chip(irq, &s3c_irq_eint); 200 set_irq_chip(irq, &s3c_irq_eint);
201 set_irq_chip_data(irq, (void *)eint_irq_to_bit(irq));
201 set_irq_handler(irq, handle_level_irq); 202 set_irq_handler(irq, handle_level_irq);
202 set_irq_flags(irq, IRQF_VALID); 203 set_irq_flags(irq, IRQF_VALID);
203 } 204 }
diff --git a/arch/arm/mach-s5p6442/dev-audio.c b/arch/arm/mach-s5p6442/dev-audio.c
index 3462197ff352..8719dc41fe32 100644
--- a/arch/arm/mach-s5p6442/dev-audio.c
+++ b/arch/arm/mach-s5p6442/dev-audio.c
@@ -29,7 +29,7 @@ static int s5p6442_cfg_i2s(struct platform_device *pdev)
29 base = S5P6442_GPC1(0); 29 base = S5P6442_GPC1(0);
30 break; 30 break;
31 31
32 case -1: 32 case 0:
33 base = S5P6442_GPC0(0); 33 base = S5P6442_GPC0(0);
34 break; 34 break;
35 35
@@ -42,8 +42,19 @@ static int s5p6442_cfg_i2s(struct platform_device *pdev)
42 return 0; 42 return 0;
43} 43}
44 44
45static struct s3c_audio_pdata s3c_i2s_pdata = { 45static const char *rclksrc_v35[] = {
46 [0] = "busclk",
47 [1] = "i2sclk",
48};
49
50static struct s3c_audio_pdata i2sv35_pdata = {
46 .cfg_gpio = s5p6442_cfg_i2s, 51 .cfg_gpio = s5p6442_cfg_i2s,
52 .type = {
53 .i2s = {
54 .quirks = QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR,
55 .src_clk = rclksrc_v35,
56 },
57 },
47}; 58};
48 59
49static struct resource s5p6442_iis0_resource[] = { 60static struct resource s5p6442_iis0_resource[] = {
@@ -62,15 +73,34 @@ static struct resource s5p6442_iis0_resource[] = {
62 .end = DMACH_I2S0_RX, 73 .end = DMACH_I2S0_RX,
63 .flags = IORESOURCE_DMA, 74 .flags = IORESOURCE_DMA,
64 }, 75 },
76 [3] = {
77 .start = DMACH_I2S0S_TX,
78 .end = DMACH_I2S0S_TX,
79 .flags = IORESOURCE_DMA,
80 },
65}; 81};
66 82
67struct platform_device s5p6442_device_iis0 = { 83struct platform_device s5p6442_device_iis0 = {
68 .name = "s3c64xx-iis-v4", 84 .name = "samsung-i2s",
69 .id = -1, 85 .id = 0,
70 .num_resources = ARRAY_SIZE(s5p6442_iis0_resource), 86 .num_resources = ARRAY_SIZE(s5p6442_iis0_resource),
71 .resource = s5p6442_iis0_resource, 87 .resource = s5p6442_iis0_resource,
72 .dev = { 88 .dev = {
73 .platform_data = &s3c_i2s_pdata, 89 .platform_data = &i2sv35_pdata,
90 },
91};
92
93static const char *rclksrc_v3[] = {
94 [0] = "iis",
95 [1] = "sclk_audio",
96};
97
98static struct s3c_audio_pdata i2sv3_pdata = {
99 .cfg_gpio = s5p6442_cfg_i2s,
100 .type = {
101 .i2s = {
102 .src_clk = rclksrc_v3,
103 },
74 }, 104 },
75}; 105};
76 106
@@ -93,12 +123,12 @@ static struct resource s5p6442_iis1_resource[] = {
93}; 123};
94 124
95struct platform_device s5p6442_device_iis1 = { 125struct platform_device s5p6442_device_iis1 = {
96 .name = "s3c64xx-iis", 126 .name = "samsung-i2s",
97 .id = 1, 127 .id = 1,
98 .num_resources = ARRAY_SIZE(s5p6442_iis1_resource), 128 .num_resources = ARRAY_SIZE(s5p6442_iis1_resource),
99 .resource = s5p6442_iis1_resource, 129 .resource = s5p6442_iis1_resource,
100 .dev = { 130 .dev = {
101 .platform_data = &s3c_i2s_pdata, 131 .platform_data = &i2sv3_pdata,
102 }, 132 },
103}; 133};
104 134
diff --git a/arch/arm/mach-s5p6442/mach-smdk6442.c b/arch/arm/mach-s5p6442/mach-smdk6442.c
index 819fd80d00af..e69f137b0a39 100644
--- a/arch/arm/mach-s5p6442/mach-smdk6442.c
+++ b/arch/arm/mach-s5p6442/mach-smdk6442.c
@@ -12,6 +12,7 @@
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/serial_core.h> 14#include <linux/serial_core.h>
15#include <linux/i2c.h>
15 16
16#include <asm/mach/arch.h> 17#include <asm/mach/arch.h>
17#include <asm/mach/map.h> 18#include <asm/mach/map.h>
@@ -25,6 +26,7 @@
25#include <plat/s5p6442.h> 26#include <plat/s5p6442.h>
26#include <plat/devs.h> 27#include <plat/devs.h>
27#include <plat/cpu.h> 28#include <plat/cpu.h>
29#include <plat/iic.h>
28 30
29/* Following are default values for UCON, ULCON and UFCON UART registers */ 31/* Following are default values for UCON, ULCON and UFCON UART registers */
30#define SMDK6442_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 32#define SMDK6442_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -65,10 +67,15 @@ static struct s3c2410_uartcfg smdk6442_uartcfgs[] __initdata = {
65}; 67};
66 68
67static struct platform_device *smdk6442_devices[] __initdata = { 69static struct platform_device *smdk6442_devices[] __initdata = {
70 &s3c_device_i2c0,
68 &s5p6442_device_iis0, 71 &s5p6442_device_iis0,
69 &s3c_device_wdt, 72 &s3c_device_wdt,
70}; 73};
71 74
75static struct i2c_board_info smdk6442_i2c_devs0[] __initdata = {
76 { I2C_BOARD_INFO("wm8580", 0x1b), },
77};
78
72static void __init smdk6442_map_io(void) 79static void __init smdk6442_map_io(void)
73{ 80{
74 s5p_init_io(NULL, 0, S5P_VA_CHIPID); 81 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -78,6 +85,9 @@ static void __init smdk6442_map_io(void)
78 85
79static void __init smdk6442_machine_init(void) 86static void __init smdk6442_machine_init(void)
80{ 87{
88 s3c_i2c0_set_platdata(NULL);
89 i2c_register_board_info(0, smdk6442_i2c_devs0,
90 ARRAY_SIZE(smdk6442_i2c_devs0));
81 platform_add_devices(smdk6442_devices, ARRAY_SIZE(smdk6442_devices)); 91 platform_add_devices(smdk6442_devices, ARRAY_SIZE(smdk6442_devices));
82} 92}
83 93
diff --git a/arch/arm/mach-s5p6442/setup-i2c0.c b/arch/arm/mach-s5p6442/setup-i2c0.c
index 662695dd7761..aad85656b0cc 100644
--- a/arch/arm/mach-s5p6442/setup-i2c0.c
+++ b/arch/arm/mach-s5p6442/setup-i2c0.c
@@ -14,12 +14,15 @@
14 14
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/gpio.h>
17 18
18struct platform_device; /* don't need the contents */ 19struct platform_device; /* don't need the contents */
19 20
21#include <plat/gpio-cfg.h>
20#include <plat/iic.h> 22#include <plat/iic.h>
21 23
22void s3c_i2c0_cfg_gpio(struct platform_device *dev) 24void s3c_i2c0_cfg_gpio(struct platform_device *dev)
23{ 25{
24 /* Will be populated later */ 26 s3c_gpio_cfgall_range(S5P6442_GPD1(0), 2,
27 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
25} 28}
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
index e4883dc1c8d7..409c5fc3670d 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6440.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -261,7 +261,7 @@ static struct clk init_clocks_disable[] = {
261 .enable = s5p64x0_pclk_ctrl, 261 .enable = s5p64x0_pclk_ctrl,
262 .ctrlbit = (1 << 25), 262 .ctrlbit = (1 << 25),
263 }, { 263 }, {
264 .name = "i2s_v40", 264 .name = "iis",
265 .id = 0, 265 .id = 0,
266 .parent = &clk_pclk_low.clk, 266 .parent = &clk_pclk_low.clk,
267 .enable = s5p64x0_pclk_ctrl, 267 .enable = s5p64x0_pclk_ctrl,
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
index 7dbf3c968f53..d8b20ee8cc8c 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6450.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -256,11 +256,23 @@ static struct clk init_clocks_disable[] = {
256 .ctrlbit = (1 << 22), 256 .ctrlbit = (1 << 22),
257 }, { 257 }, {
258 .name = "iis", 258 .name = "iis",
259 .id = -1, 259 .id = 0,
260 .parent = &clk_pclk_low.clk, 260 .parent = &clk_pclk_low.clk,
261 .enable = s5p64x0_pclk_ctrl, 261 .enable = s5p64x0_pclk_ctrl,
262 .ctrlbit = (1 << 26), 262 .ctrlbit = (1 << 26),
263 }, { 263 }, {
264 .name = "iis",
265 .id = 1,
266 .parent = &clk_pclk_low.clk,
267 .enable = s5p64x0_pclk_ctrl,
268 .ctrlbit = (1 << 15),
269 }, {
270 .name = "iis",
271 .id = 2,
272 .parent = &clk_pclk_low.clk,
273 .enable = s5p64x0_pclk_ctrl,
274 .ctrlbit = (1 << 16),
275 }, {
264 .name = "i2c", 276 .name = "i2c",
265 .id = 1, 277 .id = 1,
266 .parent = &clk_pclk_low.clk, 278 .parent = &clk_pclk_low.clk,
diff --git a/arch/arm/mach-s5p64x0/dev-audio.c b/arch/arm/mach-s5p64x0/dev-audio.c
index 396bacc0a39a..35f1f226dabb 100644
--- a/arch/arm/mach-s5p64x0/dev-audio.c
+++ b/arch/arm/mach-s5p64x0/dev-audio.c
@@ -19,15 +19,19 @@
19#include <mach/dma.h> 19#include <mach/dma.h>
20#include <mach/irqs.h> 20#include <mach/irqs.h>
21 21
22static const char *rclksrc[] = {
23 [0] = "iis",
24 [1] = "sclk_audio2",
25};
26
22static int s5p6440_cfg_i2s(struct platform_device *pdev) 27static int s5p6440_cfg_i2s(struct platform_device *pdev)
23{ 28{
24 /* configure GPIO for i2s port */
25 switch (pdev->id) { 29 switch (pdev->id) {
26 case -1: 30 case 0:
27 s3c_gpio_cfgpin_range(S5P6440_GPR(4), 5, S3C_GPIO_SFN(5)); 31 s3c_gpio_cfgpin_range(S5P6440_GPC(4), 2, S3C_GPIO_SFN(5));
28 s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(5)); 32 s3c_gpio_cfgpin(S5P6440_GPC(7), S3C_GPIO_SFN(5));
33 s3c_gpio_cfgpin_range(S5P6440_GPH(6), 4, S3C_GPIO_SFN(5));
29 break; 34 break;
30
31 default: 35 default:
32 printk(KERN_ERR "Invalid Device %d\n", pdev->id); 36 printk(KERN_ERR "Invalid Device %d\n", pdev->id);
33 return -EINVAL; 37 return -EINVAL;
@@ -36,17 +40,58 @@ static int s5p6440_cfg_i2s(struct platform_device *pdev)
36 return 0; 40 return 0;
37} 41}
38 42
43static struct s3c_audio_pdata s5p6440_i2s_pdata = {
44 .cfg_gpio = s5p6440_cfg_i2s,
45 .type = {
46 .i2s = {
47 .quirks = QUIRK_PRI_6CHAN,
48 .src_clk = rclksrc,
49 },
50 },
51};
52
53static struct resource s5p64x0_i2s0_resource[] = {
54 [0] = {
55 .start = S5P64X0_PA_I2S,
56 .end = S5P64X0_PA_I2S + 0x100 - 1,
57 .flags = IORESOURCE_MEM,
58 },
59 [1] = {
60 .start = DMACH_I2S0_TX,
61 .end = DMACH_I2S0_TX,
62 .flags = IORESOURCE_DMA,
63 },
64 [2] = {
65 .start = DMACH_I2S0_RX,
66 .end = DMACH_I2S0_RX,
67 .flags = IORESOURCE_DMA,
68 },
69};
70
71struct platform_device s5p6440_device_iis = {
72 .name = "samsung-i2s",
73 .id = 0,
74 .num_resources = ARRAY_SIZE(s5p64x0_i2s0_resource),
75 .resource = s5p64x0_i2s0_resource,
76 .dev = {
77 .platform_data = &s5p6440_i2s_pdata,
78 },
79};
80
39static int s5p6450_cfg_i2s(struct platform_device *pdev) 81static int s5p6450_cfg_i2s(struct platform_device *pdev)
40{ 82{
41 /* configure GPIO for i2s port */
42 switch (pdev->id) { 83 switch (pdev->id) {
43 case -1: 84 case 0:
44 s3c_gpio_cfgpin(S5P6450_GPB(4), S3C_GPIO_SFN(5));
45 s3c_gpio_cfgpin_range(S5P6450_GPR(4), 5, S3C_GPIO_SFN(5)); 85 s3c_gpio_cfgpin_range(S5P6450_GPR(4), 5, S3C_GPIO_SFN(5));
46 s3c_gpio_cfgpin_range(S5P6450_GPR(13), 2, S3C_GPIO_SFN(5)); 86 s3c_gpio_cfgpin_range(S5P6450_GPR(13), 2, S3C_GPIO_SFN(5));
47
48 break; 87 break;
49 88 case 1:
89 s3c_gpio_cfgpin(S5P6440_GPB(4), S3C_GPIO_SFN(5));
90 s3c_gpio_cfgpin_range(S5P6450_GPC(0), 4, S3C_GPIO_SFN(5));
91 break;
92 case 2:
93 s3c_gpio_cfgpin_range(S5P6450_GPK(0), 5, S3C_GPIO_SFN(5));
94 break;
50 default: 95 default:
51 printk(KERN_ERR "Invalid Device %d\n", pdev->id); 96 printk(KERN_ERR "Invalid Device %d\n", pdev->id);
52 return -EINVAL; 97 return -EINVAL;
@@ -55,47 +100,86 @@ static int s5p6450_cfg_i2s(struct platform_device *pdev)
55 return 0; 100 return 0;
56} 101}
57 102
58static struct s3c_audio_pdata s5p6440_i2s_pdata = { 103static struct s3c_audio_pdata s5p6450_i2s0_pdata = {
59 .cfg_gpio = s5p6440_cfg_i2s, 104 .cfg_gpio = s5p6450_cfg_i2s,
105 .type = {
106 .i2s = {
107 .quirks = QUIRK_PRI_6CHAN,
108 .src_clk = rclksrc,
109 },
110 },
111};
112
113struct platform_device s5p6450_device_iis0 = {
114 .name = "samsung-i2s",
115 .id = 0,
116 .num_resources = ARRAY_SIZE(s5p64x0_i2s0_resource),
117 .resource = s5p64x0_i2s0_resource,
118 .dev = {
119 .platform_data = &s5p6450_i2s0_pdata,
120 },
60}; 121};
61 122
62static struct s3c_audio_pdata s5p6450_i2s_pdata = { 123static struct s3c_audio_pdata s5p6450_i2s_pdata = {
63 .cfg_gpio = s5p6450_cfg_i2s, 124 .cfg_gpio = s5p6450_cfg_i2s,
125 .type = {
126 .i2s = {
127 .src_clk = rclksrc,
128 },
129 },
64}; 130};
65 131
66static struct resource s5p64x0_iis0_resource[] = { 132static struct resource s5p6450_i2s1_resource[] = {
67 [0] = { 133 [0] = {
68 .start = S5P64X0_PA_I2S, 134 .start = S5P6450_PA_I2S1,
69 .end = S5P64X0_PA_I2S + 0x100 - 1, 135 .end = S5P6450_PA_I2S1 + 0x100 - 1,
70 .flags = IORESOURCE_MEM, 136 .flags = IORESOURCE_MEM,
71 }, 137 },
72 [1] = { 138 [1] = {
73 .start = DMACH_I2S0_TX, 139 .start = DMACH_I2S1_TX,
74 .end = DMACH_I2S0_TX, 140 .end = DMACH_I2S1_TX,
75 .flags = IORESOURCE_DMA, 141 .flags = IORESOURCE_DMA,
76 }, 142 },
77 [2] = { 143 [2] = {
78 .start = DMACH_I2S0_RX, 144 .start = DMACH_I2S1_RX,
79 .end = DMACH_I2S0_RX, 145 .end = DMACH_I2S1_RX,
80 .flags = IORESOURCE_DMA, 146 .flags = IORESOURCE_DMA,
81 }, 147 },
82}; 148};
83 149
84struct platform_device s5p6440_device_iis = { 150struct platform_device s5p6450_device_iis1 = {
85 .name = "s3c64xx-iis-v4", 151 .name = "samsung-i2s",
86 .id = -1, 152 .id = 1,
87 .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource), 153 .num_resources = ARRAY_SIZE(s5p6450_i2s1_resource),
88 .resource = s5p64x0_iis0_resource, 154 .resource = s5p6450_i2s1_resource,
89 .dev = { 155 .dev = {
90 .platform_data = &s5p6440_i2s_pdata, 156 .platform_data = &s5p6450_i2s_pdata,
91 }, 157 },
92}; 158};
93 159
94struct platform_device s5p6450_device_iis0 = { 160static struct resource s5p6450_i2s2_resource[] = {
95 .name = "s3c64xx-iis-v4", 161 [0] = {
96 .id = -1, 162 .start = S5P6450_PA_I2S2,
97 .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource), 163 .end = S5P6450_PA_I2S2 + 0x100 - 1,
98 .resource = s5p64x0_iis0_resource, 164 .flags = IORESOURCE_MEM,
165 },
166 [1] = {
167 .start = DMACH_I2S2_TX,
168 .end = DMACH_I2S2_TX,
169 .flags = IORESOURCE_DMA,
170 },
171 [2] = {
172 .start = DMACH_I2S2_RX,
173 .end = DMACH_I2S2_RX,
174 .flags = IORESOURCE_DMA,
175 },
176};
177
178struct platform_device s5p6450_device_iis2 = {
179 .name = "samsung-i2s",
180 .id = 2,
181 .num_resources = ARRAY_SIZE(s5p6450_i2s2_resource),
182 .resource = s5p6450_i2s2_resource,
99 .dev = { 183 .dev = {
100 .platform_data = &s5p6450_i2s_pdata, 184 .platform_data = &s5p6450_i2s_pdata,
101 }, 185 },
diff --git a/arch/arm/mach-s5p64x0/include/mach/map.h b/arch/arm/mach-s5p64x0/include/mach/map.h
index bdf108bbf8fa..a9365e5ba614 100644
--- a/arch/arm/mach-s5p64x0/include/mach/map.h
+++ b/arch/arm/mach-s5p64x0/include/mach/map.h
@@ -66,6 +66,8 @@
66#define S5P64X0_PA_HSMMC(x) (0xED800000 + ((x) * 0x100000)) 66#define S5P64X0_PA_HSMMC(x) (0xED800000 + ((x) * 0x100000))
67 67
68#define S5P64X0_PA_I2S (0xF2000000) 68#define S5P64X0_PA_I2S (0xF2000000)
69#define S5P6450_PA_I2S1 0xF2800000
70#define S5P6450_PA_I2S2 0xF2900000
69 71
70#define S5P64X0_PA_PCM (0xF2100000) 72#define S5P64X0_PA_PCM (0xF2100000)
71 73
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index 87c3f03c618c..e9802755daeb 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -117,6 +117,7 @@ static struct s3c2410_platform_i2c s5p6440_i2c1_data __initdata = {
117 117
118static struct i2c_board_info smdk6440_i2c_devs0[] __initdata = { 118static struct i2c_board_info smdk6440_i2c_devs0[] __initdata = {
119 { I2C_BOARD_INFO("24c08", 0x50), }, 119 { I2C_BOARD_INFO("24c08", 0x50), },
120 { I2C_BOARD_INFO("wm8580", 0x1b), },
120}; 121};
121 122
122static struct i2c_board_info smdk6440_i2c_devs1[] __initdata = { 123static struct i2c_board_info smdk6440_i2c_devs1[] __initdata = {
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
index d609f5af2b98..b78f56292780 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -135,6 +135,7 @@ static struct s3c2410_platform_i2c s5p6450_i2c1_data __initdata = {
135}; 135};
136 136
137static struct i2c_board_info smdk6450_i2c_devs0[] __initdata = { 137static struct i2c_board_info smdk6450_i2c_devs0[] __initdata = {
138 { I2C_BOARD_INFO("wm8580", 0x1b), },
138 { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung KS24C080C EEPROM */ 139 { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung KS24C080C EEPROM */
139}; 140};
140 141
diff --git a/arch/arm/mach-s5pc100/dev-audio.c b/arch/arm/mach-s5pc100/dev-audio.c
index 564e195ec493..10ab275ebd63 100644
--- a/arch/arm/mach-s5pc100/dev-audio.c
+++ b/arch/arm/mach-s5pc100/dev-audio.c
@@ -23,17 +23,14 @@ static int s5pc100_cfg_i2s(struct platform_device *pdev)
23{ 23{
24 /* configure GPIO for i2s port */ 24 /* configure GPIO for i2s port */
25 switch (pdev->id) { 25 switch (pdev->id) {
26 case 0: /* Dedicated pins */
27 break;
26 case 1: 28 case 1:
27 s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(2)); 29 s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(2));
28 break; 30 break;
29
30 case 2: 31 case 2:
31 s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(4)); 32 s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(4));
32 break; 33 break;
33
34 case -1: /* Dedicated pins */
35 break;
36
37 default: 34 default:
38 printk(KERN_ERR "Invalid Device %d\n", pdev->id); 35 printk(KERN_ERR "Invalid Device %d\n", pdev->id);
39 return -EINVAL; 36 return -EINVAL;
@@ -42,8 +39,20 @@ static int s5pc100_cfg_i2s(struct platform_device *pdev)
42 return 0; 39 return 0;
43} 40}
44 41
45static struct s3c_audio_pdata s3c_i2s_pdata = { 42static const char *rclksrc_v5[] = {
43 [0] = "iis",
44 [1] = "i2sclkd2",
45};
46
47static struct s3c_audio_pdata i2sv5_pdata = {
46 .cfg_gpio = s5pc100_cfg_i2s, 48 .cfg_gpio = s5pc100_cfg_i2s,
49 .type = {
50 .i2s = {
51 .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
52 | QUIRK_NEED_RSTCLR,
53 .src_clk = rclksrc_v5,
54 },
55 },
47}; 56};
48 57
49static struct resource s5pc100_iis0_resource[] = { 58static struct resource s5pc100_iis0_resource[] = {
@@ -62,15 +71,34 @@ static struct resource s5pc100_iis0_resource[] = {
62 .end = DMACH_I2S0_RX, 71 .end = DMACH_I2S0_RX,
63 .flags = IORESOURCE_DMA, 72 .flags = IORESOURCE_DMA,
64 }, 73 },
74 [3] = {
75 .start = DMACH_I2S0S_TX,
76 .end = DMACH_I2S0S_TX,
77 .flags = IORESOURCE_DMA,
78 },
65}; 79};
66 80
67struct platform_device s5pc100_device_iis0 = { 81struct platform_device s5pc100_device_iis0 = {
68 .name = "s3c64xx-iis-v4", 82 .name = "samsung-i2s",
69 .id = -1, 83 .id = 0,
70 .num_resources = ARRAY_SIZE(s5pc100_iis0_resource), 84 .num_resources = ARRAY_SIZE(s5pc100_iis0_resource),
71 .resource = s5pc100_iis0_resource, 85 .resource = s5pc100_iis0_resource,
72 .dev = { 86 .dev = {
73 .platform_data = &s3c_i2s_pdata, 87 .platform_data = &i2sv5_pdata,
88 },
89};
90
91static const char *rclksrc_v3[] = {
92 [0] = "iis",
93 [1] = "sclk_audio",
94};
95
96static struct s3c_audio_pdata i2sv3_pdata = {
97 .cfg_gpio = s5pc100_cfg_i2s,
98 .type = {
99 .i2s = {
100 .src_clk = rclksrc_v3,
101 },
74 }, 102 },
75}; 103};
76 104
@@ -93,12 +121,12 @@ static struct resource s5pc100_iis1_resource[] = {
93}; 121};
94 122
95struct platform_device s5pc100_device_iis1 = { 123struct platform_device s5pc100_device_iis1 = {
96 .name = "s3c64xx-iis", 124 .name = "samsung-i2s",
97 .id = 1, 125 .id = 1,
98 .num_resources = ARRAY_SIZE(s5pc100_iis1_resource), 126 .num_resources = ARRAY_SIZE(s5pc100_iis1_resource),
99 .resource = s5pc100_iis1_resource, 127 .resource = s5pc100_iis1_resource,
100 .dev = { 128 .dev = {
101 .platform_data = &s3c_i2s_pdata, 129 .platform_data = &i2sv3_pdata,
102 }, 130 },
103}; 131};
104 132
@@ -121,12 +149,12 @@ static struct resource s5pc100_iis2_resource[] = {
121}; 149};
122 150
123struct platform_device s5pc100_device_iis2 = { 151struct platform_device s5pc100_device_iis2 = {
124 .name = "s3c64xx-iis", 152 .name = "samsung-i2s",
125 .id = 2, 153 .id = 2,
126 .num_resources = ARRAY_SIZE(s5pc100_iis2_resource), 154 .num_resources = ARRAY_SIZE(s5pc100_iis2_resource),
127 .resource = s5pc100_iis2_resource, 155 .resource = s5pc100_iis2_resource,
128 .dev = { 156 .dev = {
129 .platform_data = &s3c_i2s_pdata, 157 .platform_data = &i2sv3_pdata,
130 }, 158 },
131}; 159};
132 160
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index 2f9372fb2286..dab6ef3b6ca9 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -467,20 +467,20 @@ static struct clk init_clocks_disable[] = {
467 .enable = s5pv210_clk_ip3_ctrl, 467 .enable = s5pv210_clk_ip3_ctrl,
468 .ctrlbit = (1<<21), 468 .ctrlbit = (1<<21),
469 }, { 469 }, {
470 .name = "i2s_v50", 470 .name = "iis",
471 .id = 0, 471 .id = 0,
472 .parent = &clk_p, 472 .parent = &clk_p,
473 .enable = s5pv210_clk_ip3_ctrl, 473 .enable = s5pv210_clk_ip3_ctrl,
474 .ctrlbit = (1<<4), 474 .ctrlbit = (1<<4),
475 }, { 475 }, {
476 .name = "i2s_v32", 476 .name = "iis",
477 .id = 0, 477 .id = 1,
478 .parent = &clk_p, 478 .parent = &clk_p,
479 .enable = s5pv210_clk_ip3_ctrl, 479 .enable = s5pv210_clk_ip3_ctrl,
480 .ctrlbit = (1 << 5), 480 .ctrlbit = (1 << 5),
481 }, { 481 }, {
482 .name = "i2s_v32", 482 .name = "iis",
483 .id = 1, 483 .id = 2,
484 .parent = &clk_p, 484 .parent = &clk_p,
485 .enable = s5pv210_clk_ip3_ctrl, 485 .enable = s5pv210_clk_ip3_ctrl,
486 .ctrlbit = (1 << 6), 486 .ctrlbit = (1 << 6),
diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c
index 1303fcb12b51..ddd2704b3467 100644
--- a/arch/arm/mach-s5pv210/dev-audio.c
+++ b/arch/arm/mach-s5pv210/dev-audio.c
@@ -19,22 +19,24 @@
19#include <mach/dma.h> 19#include <mach/dma.h>
20#include <mach/irqs.h> 20#include <mach/irqs.h>
21 21
22static const char *rclksrc[] = {
23 [0] = "busclk",
24 [1] = "i2sclk",
25};
26
22static int s5pv210_cfg_i2s(struct platform_device *pdev) 27static int s5pv210_cfg_i2s(struct platform_device *pdev)
23{ 28{
24 /* configure GPIO for i2s port */ 29 /* configure GPIO for i2s port */
25 switch (pdev->id) { 30 switch (pdev->id) {
31 case 0:
32 s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2));
33 break;
26 case 1: 34 case 1:
27 s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(2)); 35 s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(2));
28 break; 36 break;
29
30 case 2: 37 case 2:
31 s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(4)); 38 s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(4));
32 break; 39 break;
33
34 case -1:
35 s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2));
36 break;
37
38 default: 40 default:
39 printk(KERN_ERR "Invalid Device %d\n", pdev->id); 41 printk(KERN_ERR "Invalid Device %d\n", pdev->id);
40 return -EINVAL; 42 return -EINVAL;
@@ -43,8 +45,15 @@ static int s5pv210_cfg_i2s(struct platform_device *pdev)
43 return 0; 45 return 0;
44} 46}
45 47
46static struct s3c_audio_pdata s3c_i2s_pdata = { 48static struct s3c_audio_pdata i2sv5_pdata = {
47 .cfg_gpio = s5pv210_cfg_i2s, 49 .cfg_gpio = s5pv210_cfg_i2s,
50 .type = {
51 .i2s = {
52 .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
53 | QUIRK_NEED_RSTCLR,
54 .src_clk = rclksrc,
55 },
56 },
48}; 57};
49 58
50static struct resource s5pv210_iis0_resource[] = { 59static struct resource s5pv210_iis0_resource[] = {
@@ -63,15 +72,34 @@ static struct resource s5pv210_iis0_resource[] = {
63 .end = DMACH_I2S0_RX, 72 .end = DMACH_I2S0_RX,
64 .flags = IORESOURCE_DMA, 73 .flags = IORESOURCE_DMA,
65 }, 74 },
75 [3] = {
76 .start = DMACH_I2S0S_TX,
77 .end = DMACH_I2S0S_TX,
78 .flags = IORESOURCE_DMA,
79 },
66}; 80};
67 81
68struct platform_device s5pv210_device_iis0 = { 82struct platform_device s5pv210_device_iis0 = {
69 .name = "s3c64xx-iis-v4", 83 .name = "samsung-i2s",
70 .id = -1, 84 .id = 0,
71 .num_resources = ARRAY_SIZE(s5pv210_iis0_resource), 85 .num_resources = ARRAY_SIZE(s5pv210_iis0_resource),
72 .resource = s5pv210_iis0_resource, 86 .resource = s5pv210_iis0_resource,
73 .dev = { 87 .dev = {
74 .platform_data = &s3c_i2s_pdata, 88 .platform_data = &i2sv5_pdata,
89 },
90};
91
92static const char *rclksrc_v3[] = {
93 [0] = "iis",
94 [1] = "audio-bus",
95};
96
97static struct s3c_audio_pdata i2sv3_pdata = {
98 .cfg_gpio = s5pv210_cfg_i2s,
99 .type = {
100 .i2s = {
101 .src_clk = rclksrc_v3,
102 },
75 }, 103 },
76}; 104};
77 105
@@ -94,12 +122,12 @@ static struct resource s5pv210_iis1_resource[] = {
94}; 122};
95 123
96struct platform_device s5pv210_device_iis1 = { 124struct platform_device s5pv210_device_iis1 = {
97 .name = "s3c64xx-iis", 125 .name = "samsung-i2s",
98 .id = 1, 126 .id = 1,
99 .num_resources = ARRAY_SIZE(s5pv210_iis1_resource), 127 .num_resources = ARRAY_SIZE(s5pv210_iis1_resource),
100 .resource = s5pv210_iis1_resource, 128 .resource = s5pv210_iis1_resource,
101 .dev = { 129 .dev = {
102 .platform_data = &s3c_i2s_pdata, 130 .platform_data = &i2sv3_pdata,
103 }, 131 },
104}; 132};
105 133
@@ -122,12 +150,12 @@ static struct resource s5pv210_iis2_resource[] = {
122}; 150};
123 151
124struct platform_device s5pv210_device_iis2 = { 152struct platform_device s5pv210_device_iis2 = {
125 .name = "s3c64xx-iis", 153 .name = "samsung-i2s",
126 .id = 2, 154 .id = 2,
127 .num_resources = ARRAY_SIZE(s5pv210_iis2_resource), 155 .num_resources = ARRAY_SIZE(s5pv210_iis2_resource),
128 .resource = s5pv210_iis2_resource, 156 .resource = s5pv210_iis2_resource,
129 .dev = { 157 .dev = {
130 .platform_data = &s3c_i2s_pdata, 158 .platform_data = &i2sv3_pdata,
131 }, 159 },
132}; 160};
133 161
diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c
index 5dd1681c069e..bb20a14da100 100644
--- a/arch/arm/mach-s5pv210/mach-smdkc110.c
+++ b/arch/arm/mach-s5pv210/mach-smdkc110.c
@@ -94,6 +94,7 @@ static struct platform_device *smdkc110_devices[] __initdata = {
94 94
95static struct i2c_board_info smdkc110_i2c_devs0[] __initdata = { 95static struct i2c_board_info smdkc110_i2c_devs0[] __initdata = {
96 { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */ 96 { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */
97 { I2C_BOARD_INFO("wm8580", 0x1b), },
97}; 98};
98 99
99static struct i2c_board_info smdkc110_i2c_devs1[] __initdata = { 100static struct i2c_board_info smdkc110_i2c_devs1[] __initdata = {
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index 30eec118a3a4..3a59068e983a 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -178,6 +178,7 @@ static void __init smdkv210_dm9000_init(void)
178 178
179static struct i2c_board_info smdkv210_i2c_devs0[] __initdata = { 179static struct i2c_board_info smdkv210_i2c_devs0[] __initdata = {
180 { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */ 180 { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */
181 { I2C_BOARD_INFO("wm8580", 0x1b), },
181}; 182};
182 183
183static struct i2c_board_info smdkv210_i2c_devs1[] __initdata = { 184static struct i2c_board_info smdkv210_i2c_devs1[] __initdata = {
diff --git a/arch/arm/mach-s5pv310/Kconfig b/arch/arm/mach-s5pv310/Kconfig
index 1150b360f38c..3e1fe9d6b1fa 100644
--- a/arch/arm/mach-s5pv310/Kconfig
+++ b/arch/arm/mach-s5pv310/Kconfig
@@ -11,6 +11,7 @@ if ARCH_S5PV310
11 11
12config CPU_S5PV310 12config CPU_S5PV310
13 bool 13 bool
14 select S3C_PL330_DMA
14 help 15 help
15 Enable S5PV310 CPU support 16 Enable S5PV310 CPU support
16 17
@@ -69,10 +70,12 @@ config MACH_SMDKC210
69 select CPU_S5PV310 70 select CPU_S5PV310
70 select S3C_DEV_RTC 71 select S3C_DEV_RTC
71 select S3C_DEV_WDT 72 select S3C_DEV_WDT
73 select S3C_DEV_I2C1
72 select S3C_DEV_HSMMC 74 select S3C_DEV_HSMMC
73 select S3C_DEV_HSMMC1 75 select S3C_DEV_HSMMC1
74 select S3C_DEV_HSMMC2 76 select S3C_DEV_HSMMC2
75 select S3C_DEV_HSMMC3 77 select S3C_DEV_HSMMC3
78 select S5PV310_SETUP_I2C1
76 select S5PV310_SETUP_SDHCI 79 select S5PV310_SETUP_SDHCI
77 help 80 help
78 Machine support for Samsung SMDKC210 81 Machine support for Samsung SMDKC210
@@ -97,10 +100,12 @@ config MACH_SMDKV310
97 select CPU_S5PV310 100 select CPU_S5PV310
98 select S3C_DEV_RTC 101 select S3C_DEV_RTC
99 select S3C_DEV_WDT 102 select S3C_DEV_WDT
103 select S3C_DEV_I2C1
100 select S3C_DEV_HSMMC 104 select S3C_DEV_HSMMC
101 select S3C_DEV_HSMMC1 105 select S3C_DEV_HSMMC1
102 select S3C_DEV_HSMMC2 106 select S3C_DEV_HSMMC2
103 select S3C_DEV_HSMMC3 107 select S3C_DEV_HSMMC3
108 select S5PV310_SETUP_I2C1
104 select S5PV310_SETUP_SDHCI 109 select S5PV310_SETUP_SDHCI
105 help 110 help
106 Machine support for Samsung SMDKV310 111 Machine support for Samsung SMDKV310
diff --git a/arch/arm/mach-s5pv310/Makefile b/arch/arm/mach-s5pv310/Makefile
index 84afc64e7c01..61e3cb654269 100644
--- a/arch/arm/mach-s5pv310/Makefile
+++ b/arch/arm/mach-s5pv310/Makefile
@@ -13,7 +13,7 @@ obj- :=
13# Core support for S5PV310 system 13# Core support for S5PV310 system
14 14
15obj-$(CONFIG_CPU_S5PV310) += cpu.o init.o clock.o irq-combiner.o 15obj-$(CONFIG_CPU_S5PV310) += cpu.o init.o clock.o irq-combiner.o
16obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o gpiolib.o irq-eint.o 16obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o gpiolib.o irq-eint.o dma.o
17 17
18obj-$(CONFIG_SMP) += platsmp.o headsmp.o 18obj-$(CONFIG_SMP) += platsmp.o headsmp.o
19obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o 19obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
@@ -27,6 +27,7 @@ obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o
27 27
28# device support 28# device support
29 29
30obj-y += dev-audio.o
30obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o 31obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o
31obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o 32obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o
32obj-$(CONFIG_S5PV310_SETUP_I2C3) += setup-i2c3.o 33obj-$(CONFIG_S5PV310_SETUP_I2C3) += setup-i2c3.o
diff --git a/arch/arm/mach-s5pv310/clock.c b/arch/arm/mach-s5pv310/clock.c
index 58c9d33f36fe..6d22c43c6ee8 100644
--- a/arch/arm/mach-s5pv310/clock.c
+++ b/arch/arm/mach-s5pv310/clock.c
@@ -467,6 +467,16 @@ static struct clk init_clocks_disable[] = {
467 .enable = s5pv310_clk_ip_fsys_ctrl, 467 .enable = s5pv310_clk_ip_fsys_ctrl,
468 .ctrlbit = (1 << 10), 468 .ctrlbit = (1 << 10),
469 }, { 469 }, {
470 .name = "pdma",
471 .id = 0,
472 .enable = s5pv310_clk_ip_fsys_ctrl,
473 .ctrlbit = (1 << 0),
474 }, {
475 .name = "pdma",
476 .id = 1,
477 .enable = s5pv310_clk_ip_fsys_ctrl,
478 .ctrlbit = (1 << 1),
479 }, {
470 .name = "adc", 480 .name = "adc",
471 .id = -1, 481 .id = -1,
472 .enable = s5pv310_clk_ip_peril_ctrl, 482 .enable = s5pv310_clk_ip_peril_ctrl,
@@ -507,6 +517,26 @@ static struct clk init_clocks_disable[] = {
507 .enable = s5pv310_clk_ip_peril_ctrl, 517 .enable = s5pv310_clk_ip_peril_ctrl,
508 .ctrlbit = (1 << 18), 518 .ctrlbit = (1 << 18),
509 }, { 519 }, {
520 .name = "iis",
521 .id = 0,
522 .enable = s5pv310_clk_ip_peril_ctrl,
523 .ctrlbit = (1 << 19),
524 }, {
525 .name = "iis",
526 .id = 1,
527 .enable = s5pv310_clk_ip_peril_ctrl,
528 .ctrlbit = (1 << 20),
529 }, {
530 .name = "iis",
531 .id = 2,
532 .enable = s5pv310_clk_ip_peril_ctrl,
533 .ctrlbit = (1 << 21),
534 }, {
535 .name = "ac97",
536 .id = -1,
537 .enable = s5pv310_clk_ip_peril_ctrl,
538 .ctrlbit = (1 << 27),
539 }, {
510 .name = "fimg2d", 540 .name = "fimg2d",
511 .id = -1, 541 .id = -1,
512 .enable = s5pv310_clk_ip_image_ctrl, 542 .enable = s5pv310_clk_ip_image_ctrl,
diff --git a/arch/arm/mach-s5pv310/dev-audio.c b/arch/arm/mach-s5pv310/dev-audio.c
new file mode 100644
index 000000000000..a1964242f0fa
--- /dev/null
+++ b/arch/arm/mach-s5pv310/dev-audio.c
@@ -0,0 +1,364 @@
1/* linux/arch/arm/mach-s5pv310/dev-audio.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 version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h>
13#include <linux/gpio.h>
14
15#include <plat/gpio-cfg.h>
16#include <plat/audio.h>
17
18#include <mach/map.h>
19#include <mach/dma.h>
20#include <mach/irqs.h>
21
22static const char *rclksrc[] = {
23 [0] = "busclk",
24 [1] = "i2sclk",
25};
26
27static int s5pv310_cfg_i2s(struct platform_device *pdev)
28{
29 /* configure GPIO for i2s port */
30 switch (pdev->id) {
31 case 0:
32 s3c_gpio_cfgpin_range(S5PV310_GPZ(0), 7, S3C_GPIO_SFN(2));
33 break;
34 case 1:
35 s3c_gpio_cfgpin_range(S5PV310_GPC0(0), 5, S3C_GPIO_SFN(2));
36 break;
37 case 2:
38 s3c_gpio_cfgpin_range(S5PV310_GPC1(0), 5, S3C_GPIO_SFN(4));
39 break;
40 default:
41 printk(KERN_ERR "Invalid Device %d\n", pdev->id);
42 return -EINVAL;
43 }
44
45 return 0;
46}
47
48static struct s3c_audio_pdata i2sv5_pdata = {
49 .cfg_gpio = s5pv310_cfg_i2s,
50 .type = {
51 .i2s = {
52 .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
53 | QUIRK_NEED_RSTCLR,
54 .src_clk = rclksrc,
55 },
56 },
57};
58
59static struct resource s5pv310_i2s0_resource[] = {
60 [0] = {
61 .start = S5PV310_PA_I2S0,
62 .end = S5PV310_PA_I2S0 + 0x100 - 1,
63 .flags = IORESOURCE_MEM,
64 },
65 [1] = {
66 .start = DMACH_I2S0_TX,
67 .end = DMACH_I2S0_TX,
68 .flags = IORESOURCE_DMA,
69 },
70 [2] = {
71 .start = DMACH_I2S0_RX,
72 .end = DMACH_I2S0_RX,
73 .flags = IORESOURCE_DMA,
74 },
75 [3] = {
76 .start = DMACH_I2S0S_TX,
77 .end = DMACH_I2S0S_TX,
78 .flags = IORESOURCE_DMA,
79 },
80};
81
82struct platform_device s5pv310_device_i2s0 = {
83 .name = "samsung-i2s",
84 .id = 0,
85 .num_resources = ARRAY_SIZE(s5pv310_i2s0_resource),
86 .resource = s5pv310_i2s0_resource,
87 .dev = {
88 .platform_data = &i2sv5_pdata,
89 },
90};
91
92static const char *rclksrc_v3[] = {
93 [0] = "sclk_i2s",
94 [1] = "no_such_clock",
95};
96
97static struct s3c_audio_pdata i2sv3_pdata = {
98 .cfg_gpio = s5pv310_cfg_i2s,
99 .type = {
100 .i2s = {
101 .quirks = QUIRK_NO_MUXPSR,
102 .src_clk = rclksrc_v3,
103 },
104 },
105};
106
107static struct resource s5pv310_i2s1_resource[] = {
108 [0] = {
109 .start = S5PV310_PA_I2S1,
110 .end = S5PV310_PA_I2S1 + 0x100 - 1,
111 .flags = IORESOURCE_MEM,
112 },
113 [1] = {
114 .start = DMACH_I2S1_TX,
115 .end = DMACH_I2S1_TX,
116 .flags = IORESOURCE_DMA,
117 },
118 [2] = {
119 .start = DMACH_I2S1_RX,
120 .end = DMACH_I2S1_RX,
121 .flags = IORESOURCE_DMA,
122 },
123};
124
125struct platform_device s5pv310_device_i2s1 = {
126 .name = "samsung-i2s",
127 .id = 1,
128 .num_resources = ARRAY_SIZE(s5pv310_i2s1_resource),
129 .resource = s5pv310_i2s1_resource,
130 .dev = {
131 .platform_data = &i2sv3_pdata,
132 },
133};
134
135static struct resource s5pv310_i2s2_resource[] = {
136 [0] = {
137 .start = S5PV310_PA_I2S2,
138 .end = S5PV310_PA_I2S2 + 0x100 - 1,
139 .flags = IORESOURCE_MEM,
140 },
141 [1] = {
142 .start = DMACH_I2S2_TX,
143 .end = DMACH_I2S2_TX,
144 .flags = IORESOURCE_DMA,
145 },
146 [2] = {
147 .start = DMACH_I2S2_RX,
148 .end = DMACH_I2S2_RX,
149 .flags = IORESOURCE_DMA,
150 },
151};
152
153struct platform_device s5pv310_device_i2s2 = {
154 .name = "samsung-i2s",
155 .id = 2,
156 .num_resources = ARRAY_SIZE(s5pv310_i2s2_resource),
157 .resource = s5pv310_i2s2_resource,
158 .dev = {
159 .platform_data = &i2sv3_pdata,
160 },
161};
162
163/* PCM Controller platform_devices */
164
165static int s5pv310_pcm_cfg_gpio(struct platform_device *pdev)
166{
167 switch (pdev->id) {
168 case 0:
169 s3c_gpio_cfgpin_range(S5PV310_GPZ(0), 5, S3C_GPIO_SFN(3));
170 break;
171 case 1:
172 s3c_gpio_cfgpin_range(S5PV310_GPC0(0), 5, S3C_GPIO_SFN(3));
173 break;
174 case 2:
175 s3c_gpio_cfgpin_range(S5PV310_GPC1(0), 5, S3C_GPIO_SFN(3));
176 break;
177 default:
178 printk(KERN_DEBUG "Invalid PCM Controller number!");
179 return -EINVAL;
180 }
181
182 return 0;
183}
184
185static struct s3c_audio_pdata s3c_pcm_pdata = {
186 .cfg_gpio = s5pv310_pcm_cfg_gpio,
187};
188
189static struct resource s5pv310_pcm0_resource[] = {
190 [0] = {
191 .start = S5PV310_PA_PCM0,
192 .end = S5PV310_PA_PCM0 + 0x100 - 1,
193 .flags = IORESOURCE_MEM,
194 },
195 [1] = {
196 .start = DMACH_PCM0_TX,
197 .end = DMACH_PCM0_TX,
198 .flags = IORESOURCE_DMA,
199 },
200 [2] = {
201 .start = DMACH_PCM0_RX,
202 .end = DMACH_PCM0_RX,
203 .flags = IORESOURCE_DMA,
204 },
205};
206
207struct platform_device s5pv310_device_pcm0 = {
208 .name = "samsung-pcm",
209 .id = 0,
210 .num_resources = ARRAY_SIZE(s5pv310_pcm0_resource),
211 .resource = s5pv310_pcm0_resource,
212 .dev = {
213 .platform_data = &s3c_pcm_pdata,
214 },
215};
216
217static struct resource s5pv310_pcm1_resource[] = {
218 [0] = {
219 .start = S5PV310_PA_PCM1,
220 .end = S5PV310_PA_PCM1 + 0x100 - 1,
221 .flags = IORESOURCE_MEM,
222 },
223 [1] = {
224 .start = DMACH_PCM1_TX,
225 .end = DMACH_PCM1_TX,
226 .flags = IORESOURCE_DMA,
227 },
228 [2] = {
229 .start = DMACH_PCM1_RX,
230 .end = DMACH_PCM1_RX,
231 .flags = IORESOURCE_DMA,
232 },
233};
234
235struct platform_device s5pv310_device_pcm1 = {
236 .name = "samsung-pcm",
237 .id = 1,
238 .num_resources = ARRAY_SIZE(s5pv310_pcm1_resource),
239 .resource = s5pv310_pcm1_resource,
240 .dev = {
241 .platform_data = &s3c_pcm_pdata,
242 },
243};
244
245static struct resource s5pv310_pcm2_resource[] = {
246 [0] = {
247 .start = S5PV310_PA_PCM2,
248 .end = S5PV310_PA_PCM2 + 0x100 - 1,
249 .flags = IORESOURCE_MEM,
250 },
251 [1] = {
252 .start = DMACH_PCM2_TX,
253 .end = DMACH_PCM2_TX,
254 .flags = IORESOURCE_DMA,
255 },
256 [2] = {
257 .start = DMACH_PCM2_RX,
258 .end = DMACH_PCM2_RX,
259 .flags = IORESOURCE_DMA,
260 },
261};
262
263struct platform_device s5pv310_device_pcm2 = {
264 .name = "samsung-pcm",
265 .id = 2,
266 .num_resources = ARRAY_SIZE(s5pv310_pcm2_resource),
267 .resource = s5pv310_pcm2_resource,
268 .dev = {
269 .platform_data = &s3c_pcm_pdata,
270 },
271};
272
273/* AC97 Controller platform devices */
274
275static int s5pv310_ac97_cfg_gpio(struct platform_device *pdev)
276{
277 return s3c_gpio_cfgpin_range(S5PV310_GPC0(0), 5, S3C_GPIO_SFN(4));
278}
279
280static struct resource s5pv310_ac97_resource[] = {
281 [0] = {
282 .start = S5PV310_PA_AC97,
283 .end = S5PV310_PA_AC97 + 0x100 - 1,
284 .flags = IORESOURCE_MEM,
285 },
286 [1] = {
287 .start = DMACH_AC97_PCMOUT,
288 .end = DMACH_AC97_PCMOUT,
289 .flags = IORESOURCE_DMA,
290 },
291 [2] = {
292 .start = DMACH_AC97_PCMIN,
293 .end = DMACH_AC97_PCMIN,
294 .flags = IORESOURCE_DMA,
295 },
296 [3] = {
297 .start = DMACH_AC97_MICIN,
298 .end = DMACH_AC97_MICIN,
299 .flags = IORESOURCE_DMA,
300 },
301 [4] = {
302 .start = IRQ_AC97,
303 .end = IRQ_AC97,
304 .flags = IORESOURCE_IRQ,
305 },
306};
307
308static struct s3c_audio_pdata s3c_ac97_pdata = {
309 .cfg_gpio = s5pv310_ac97_cfg_gpio,
310};
311
312static u64 s5pv310_ac97_dmamask = DMA_BIT_MASK(32);
313
314struct platform_device s5pv310_device_ac97 = {
315 .name = "samsung-ac97",
316 .id = -1,
317 .num_resources = ARRAY_SIZE(s5pv310_ac97_resource),
318 .resource = s5pv310_ac97_resource,
319 .dev = {
320 .platform_data = &s3c_ac97_pdata,
321 .dma_mask = &s5pv310_ac97_dmamask,
322 .coherent_dma_mask = DMA_BIT_MASK(32),
323 },
324};
325
326/* S/PDIF Controller platform_device */
327
328static int s5pv310_spdif_cfg_gpio(struct platform_device *pdev)
329{
330 s3c_gpio_cfgpin_range(S5PV310_GPC1(0), 2, S3C_GPIO_SFN(3));
331
332 return 0;
333}
334
335static struct resource s5pv310_spdif_resource[] = {
336 [0] = {
337 .start = S5PV310_PA_SPDIF,
338 .end = S5PV310_PA_SPDIF + 0x100 - 1,
339 .flags = IORESOURCE_MEM,
340 },
341 [1] = {
342 .start = DMACH_SPDIF,
343 .end = DMACH_SPDIF,
344 .flags = IORESOURCE_DMA,
345 },
346};
347
348static struct s3c_audio_pdata samsung_spdif_pdata = {
349 .cfg_gpio = s5pv310_spdif_cfg_gpio,
350};
351
352static u64 s5pv310_spdif_dmamask = DMA_BIT_MASK(32);
353
354struct platform_device s5pv310_device_spdif = {
355 .name = "samsung-spdif",
356 .id = -1,
357 .num_resources = ARRAY_SIZE(s5pv310_spdif_resource),
358 .resource = s5pv310_spdif_resource,
359 .dev = {
360 .platform_data = &samsung_spdif_pdata,
361 .dma_mask = &s5pv310_spdif_dmamask,
362 .coherent_dma_mask = DMA_BIT_MASK(32),
363 },
364};
diff --git a/arch/arm/mach-s5pv310/dma.c b/arch/arm/mach-s5pv310/dma.c
new file mode 100644
index 000000000000..20066c7c9e56
--- /dev/null
+++ b/arch/arm/mach-s5pv310/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 s5pv310_pdma0_resource[] = {
34 [0] = {
35 .start = S5PV310_PA_PDMA0,
36 .end = S5PV310_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 s5pv310_pdma0_pdata = {
47 .peri = {
48 [0] = DMACH_PCM0_RX,
49 [1] = DMACH_PCM0_TX,
50 [2] = DMACH_PCM2_RX,
51 [3] = DMACH_PCM2_TX,
52 [4] = DMACH_MSM_REQ0,
53 [5] = DMACH_MSM_REQ2,
54 [6] = DMACH_SPI0_RX,
55 [7] = DMACH_SPI0_TX,
56 [8] = DMACH_SPI2_RX,
57 [9] = DMACH_SPI2_TX,
58 [10] = DMACH_I2S0S_TX,
59 [11] = DMACH_I2S0_RX,
60 [12] = DMACH_I2S0_TX,
61 [13] = DMACH_I2S2_RX,
62 [14] = DMACH_I2S2_TX,
63 [15] = DMACH_UART0_RX,
64 [16] = DMACH_UART0_TX,
65 [17] = DMACH_UART2_RX,
66 [18] = DMACH_UART2_TX,
67 [19] = DMACH_UART4_RX,
68 [20] = DMACH_UART4_TX,
69 [21] = DMACH_SLIMBUS0_RX,
70 [22] = DMACH_SLIMBUS0_TX,
71 [23] = DMACH_SLIMBUS2_RX,
72 [24] = DMACH_SLIMBUS2_TX,
73 [25] = DMACH_SLIMBUS4_RX,
74 [26] = DMACH_SLIMBUS4_TX,
75 [27] = DMACH_AC97_MICIN,
76 [28] = DMACH_AC97_PCMIN,
77 [29] = DMACH_AC97_PCMOUT,
78 [30] = DMACH_MAX,
79 [31] = DMACH_MAX,
80 },
81};
82
83static struct platform_device s5pv310_device_pdma0 = {
84 .name = "s3c-pl330",
85 .id = 0,
86 .num_resources = ARRAY_SIZE(s5pv310_pdma0_resource),
87 .resource = s5pv310_pdma0_resource,
88 .dev = {
89 .dma_mask = &dma_dmamask,
90 .coherent_dma_mask = DMA_BIT_MASK(32),
91 .platform_data = &s5pv310_pdma0_pdata,
92 },
93};
94
95static struct resource s5pv310_pdma1_resource[] = {
96 [0] = {
97 .start = S5PV310_PA_PDMA1,
98 .end = S5PV310_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 s5pv310_pdma1_pdata = {
109 .peri = {
110 [0] = DMACH_PCM0_RX,
111 [1] = DMACH_PCM0_TX,
112 [2] = DMACH_PCM1_RX,
113 [3] = DMACH_PCM1_TX,
114 [4] = DMACH_MSM_REQ1,
115 [5] = DMACH_MSM_REQ3,
116 [6] = DMACH_SPI1_RX,
117 [7] = DMACH_SPI1_TX,
118 [8] = DMACH_I2S0S_TX,
119 [9] = DMACH_I2S0_RX,
120 [10] = DMACH_I2S0_TX,
121 [11] = DMACH_I2S1_RX,
122 [12] = DMACH_I2S1_TX,
123 [13] = DMACH_UART0_RX,
124 [14] = DMACH_UART0_TX,
125 [15] = DMACH_UART1_RX,
126 [16] = DMACH_UART1_TX,
127 [17] = DMACH_UART3_RX,
128 [18] = DMACH_UART3_TX,
129 [19] = DMACH_SLIMBUS1_RX,
130 [20] = DMACH_SLIMBUS1_TX,
131 [21] = DMACH_SLIMBUS3_RX,
132 [22] = DMACH_SLIMBUS3_TX,
133 [23] = DMACH_SLIMBUS5_RX,
134 [24] = DMACH_SLIMBUS5_TX,
135 [25] = DMACH_SLIMBUS0AUX_RX,
136 [26] = DMACH_SLIMBUS0AUX_TX,
137 [27] = DMACH_SPDIF,
138 [28] = DMACH_MAX,
139 [29] = DMACH_MAX,
140 [30] = DMACH_MAX,
141 [31] = DMACH_MAX,
142 },
143};
144
145static struct platform_device s5pv310_device_pdma1 = {
146 .name = "s3c-pl330",
147 .id = 1,
148 .num_resources = ARRAY_SIZE(s5pv310_pdma1_resource),
149 .resource = s5pv310_pdma1_resource,
150 .dev = {
151 .dma_mask = &dma_dmamask,
152 .coherent_dma_mask = DMA_BIT_MASK(32),
153 .platform_data = &s5pv310_pdma1_pdata,
154 },
155};
156
157static struct platform_device *s5pv310_dmacs[] __initdata = {
158 &s5pv310_device_pdma0,
159 &s5pv310_device_pdma1,
160};
161
162static int __init s5pv310_dma_init(void)
163{
164 platform_add_devices(s5pv310_dmacs, ARRAY_SIZE(s5pv310_dmacs));
165
166 return 0;
167}
168arch_initcall(s5pv310_dma_init);
diff --git a/arch/arm/mach-s5pv310/include/mach/dma.h b/arch/arm/mach-s5pv310/include/mach/dma.h
new file mode 100644
index 000000000000..81209eb1409b
--- /dev/null
+++ b/arch/arm/mach-s5pv310/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-s5pv310/include/mach/irqs.h b/arch/arm/mach-s5pv310/include/mach/irqs.h
index 0a2544aaee0c..34f214444f27 100644
--- a/arch/arm/mach-s5pv310/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv310/include/mach/irqs.h
@@ -54,6 +54,9 @@
54#define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(64)) 54#define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(64))
55#define COMBINER_IRQ(x, y) (COMBINER_GROUP(x) + y) 55#define COMBINER_IRQ(x, y) (COMBINER_GROUP(x) + y)
56 56
57#define IRQ_PDMA0 COMBINER_IRQ(21, 0)
58#define IRQ_PDMA1 COMBINER_IRQ(21, 1)
59
57#define IRQ_TIMER0_VIC COMBINER_IRQ(22, 0) 60#define IRQ_TIMER0_VIC COMBINER_IRQ(22, 0)
58#define IRQ_TIMER1_VIC COMBINER_IRQ(22, 1) 61#define IRQ_TIMER1_VIC COMBINER_IRQ(22, 1)
59#define IRQ_TIMER2_VIC COMBINER_IRQ(22, 2) 62#define IRQ_TIMER2_VIC COMBINER_IRQ(22, 2)
diff --git a/arch/arm/mach-s5pv310/include/mach/map.h b/arch/arm/mach-s5pv310/include/mach/map.h
index 5eab2ecfed2a..0d0e7eb5b391 100644
--- a/arch/arm/mach-s5pv310/include/mach/map.h
+++ b/arch/arm/mach-s5pv310/include/mach/map.h
@@ -52,6 +52,11 @@
52#define S5PV310_PA_GIC_DIST (0x10501000) 52#define S5PV310_PA_GIC_DIST (0x10501000)
53#define S5PV310_PA_L2CC (0x10502000) 53#define S5PV310_PA_L2CC (0x10502000)
54 54
55/* DMA */
56#define S5PV310_PA_MDMA 0x10810000
57#define S5PV310_PA_PDMA0 0x12680000
58#define S5PV310_PA_PDMA1 0x12690000
59
55#define S5PV310_PA_GPIO1 (0x11400000) 60#define S5PV310_PA_GPIO1 (0x11400000)
56#define S5PV310_PA_GPIO2 (0x11000000) 61#define S5PV310_PA_GPIO2 (0x11000000)
57#define S5PV310_PA_GPIO3 (0x03860000) 62#define S5PV310_PA_GPIO3 (0x03860000)
@@ -64,6 +69,22 @@
64#define S5PV310_PA_SROMC (0x12570000) 69#define S5PV310_PA_SROMC (0x12570000)
65#define S5P_PA_SROMC S5PV310_PA_SROMC 70#define S5P_PA_SROMC S5PV310_PA_SROMC
66 71
72/* S/PDIF */
73#define S5PV310_PA_SPDIF 0xE1100000
74
75/* I2S */
76#define S5PV310_PA_I2S0 0x03830000
77#define S5PV310_PA_I2S1 0xE3100000
78#define S5PV310_PA_I2S2 0xE2A00000
79
80/* PCM */
81#define S5PV310_PA_PCM0 0x03840000
82#define S5PV310_PA_PCM1 0x13980000
83#define S5PV310_PA_PCM2 0x13990000
84
85/* AC97 */
86#define S5PV310_PA_AC97 0x139A0000
87
67#define S5PV310_PA_UART (0x13800000) 88#define S5PV310_PA_UART (0x13800000)
68 89
69#define S5P_PA_UART(x) (S5PV310_PA_UART + ((x) * S3C_UART_OFFSET)) 90#define S5P_PA_UART(x) (S5PV310_PA_UART + ((x) * S3C_UART_OFFSET))
diff --git a/arch/arm/mach-s5pv310/irq-eint.c b/arch/arm/mach-s5pv310/irq-eint.c
index 5877503e92c3..f5a415edc0b6 100644
--- a/arch/arm/mach-s5pv310/irq-eint.c
+++ b/arch/arm/mach-s5pv310/irq-eint.c
@@ -152,7 +152,7 @@ static struct irq_chip s5pv310_irq_eint = {
152 .ack = s5pv310_irq_eint_ack, 152 .ack = s5pv310_irq_eint_ack,
153 .set_type = s5pv310_irq_eint_set_type, 153 .set_type = s5pv310_irq_eint_set_type,
154#ifdef CONFIG_PM 154#ifdef CONFIG_PM
155 .set_wake = s3c_irqext_wake, 155 .irq_set_wake = s3c_irqext_wake,
156#endif 156#endif
157}; 157};
158 158
diff --git a/arch/arm/mach-s5pv310/mach-smdkc210.c b/arch/arm/mach-s5pv310/mach-smdkc210.c
index 62956d3488b1..f3bc283df119 100644
--- a/arch/arm/mach-s5pv310/mach-smdkc210.c
+++ b/arch/arm/mach-s5pv310/mach-smdkc210.c
@@ -14,6 +14,7 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/smsc911x.h> 15#include <linux/smsc911x.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/i2c.h>
17 18
18#include <asm/mach/arch.h> 19#include <asm/mach/arch.h>
19#include <asm/mach-types.h> 20#include <asm/mach-types.h>
@@ -24,6 +25,7 @@
24#include <plat/cpu.h> 25#include <plat/cpu.h>
25#include <plat/devs.h> 26#include <plat/devs.h>
26#include <plat/sdhci.h> 27#include <plat/sdhci.h>
28#include <plat/iic.h>
27 29
28#include <mach/map.h> 30#include <mach/map.h>
29 31
@@ -139,7 +141,12 @@ static struct platform_device smdkc210_smsc911x = {
139 }, 141 },
140}; 142};
141 143
144static struct i2c_board_info i2c_devs1[] __initdata = {
145 {I2C_BOARD_INFO("wm8994", 0x1a),},
146};
147
142static struct platform_device *smdkc210_devices[] __initdata = { 148static struct platform_device *smdkc210_devices[] __initdata = {
149 &s3c_device_i2c1,
143 &s3c_device_hsmmc0, 150 &s3c_device_hsmmc0,
144 &s3c_device_hsmmc1, 151 &s3c_device_hsmmc1,
145 &s3c_device_hsmmc2, 152 &s3c_device_hsmmc2,
@@ -147,6 +154,8 @@ static struct platform_device *smdkc210_devices[] __initdata = {
147 &s3c_device_rtc, 154 &s3c_device_rtc,
148 &s3c_device_wdt, 155 &s3c_device_wdt,
149 &smdkc210_smsc911x, 156 &smdkc210_smsc911x,
157 &s5pv310_device_ac97,
158 &s5pv310_device_i2s0,
150}; 159};
151 160
152static void __init smdkc210_smsc911x_init(void) 161static void __init smdkc210_smsc911x_init(void)
@@ -181,6 +190,9 @@ static void __init smdkc210_map_io(void)
181 190
182static void __init smdkc210_machine_init(void) 191static void __init smdkc210_machine_init(void)
183{ 192{
193 s3c_i2c1_set_platdata(NULL);
194 i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
195
184 smdkc210_smsc911x_init(); 196 smdkc210_smsc911x_init();
185 197
186 s3c_sdhci0_set_platdata(&smdkc210_hsmmc0_pdata); 198 s3c_sdhci0_set_platdata(&smdkc210_hsmmc0_pdata);
diff --git a/arch/arm/mach-s5pv310/mach-smdkv310.c b/arch/arm/mach-s5pv310/mach-smdkv310.c
index 342660232342..e4a826ac3c1d 100644
--- a/arch/arm/mach-s5pv310/mach-smdkv310.c
+++ b/arch/arm/mach-s5pv310/mach-smdkv310.c
@@ -14,6 +14,7 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/smsc911x.h> 15#include <linux/smsc911x.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/i2c.h>
17 18
18#include <asm/mach/arch.h> 19#include <asm/mach/arch.h>
19#include <asm/mach-types.h> 20#include <asm/mach-types.h>
@@ -24,6 +25,7 @@
24#include <plat/cpu.h> 25#include <plat/cpu.h>
25#include <plat/devs.h> 26#include <plat/devs.h>
26#include <plat/sdhci.h> 27#include <plat/sdhci.h>
28#include <plat/iic.h>
27 29
28#include <mach/map.h> 30#include <mach/map.h>
29 31
@@ -139,7 +141,12 @@ static struct platform_device smdkv310_smsc911x = {
139 }, 141 },
140}; 142};
141 143
144static struct i2c_board_info i2c_devs1[] __initdata = {
145 {I2C_BOARD_INFO("wm8994", 0x1a),},
146};
147
142static struct platform_device *smdkv310_devices[] __initdata = { 148static struct platform_device *smdkv310_devices[] __initdata = {
149 &s3c_device_i2c1,
143 &s3c_device_hsmmc0, 150 &s3c_device_hsmmc0,
144 &s3c_device_hsmmc1, 151 &s3c_device_hsmmc1,
145 &s3c_device_hsmmc2, 152 &s3c_device_hsmmc2,
@@ -147,6 +154,8 @@ static struct platform_device *smdkv310_devices[] __initdata = {
147 &s3c_device_rtc, 154 &s3c_device_rtc,
148 &s3c_device_wdt, 155 &s3c_device_wdt,
149 &smdkv310_smsc911x, 156 &smdkv310_smsc911x,
157 &s5pv310_device_ac97,
158 &s5pv310_device_i2s0,
150}; 159};
151 160
152static void __init smdkv310_smsc911x_init(void) 161static void __init smdkv310_smsc911x_init(void)
@@ -181,6 +190,9 @@ static void __init smdkv310_map_io(void)
181 190
182static void __init smdkv310_machine_init(void) 191static void __init smdkv310_machine_init(void)
183{ 192{
193 s3c_i2c1_set_platdata(NULL);
194 i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
195
184 smdkv310_smsc911x_init(); 196 smdkv310_smsc911x_init();
185 197
186 s3c_sdhci0_set_platdata(&smdkv310_hsmmc0_pdata); 198 s3c_sdhci0_set_platdata(&smdkv310_hsmmc0_pdata);
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index ad0d44ef1f93..91ce38393ba6 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -238,7 +238,7 @@ static struct irq_chip s3c_irqext_chip = {
238 .unmask = s3c_irqext_unmask, 238 .unmask = s3c_irqext_unmask,
239 .ack = s3c_irqext_ack, 239 .ack = s3c_irqext_ack,
240 .set_type = s3c_irqext_type, 240 .set_type = s3c_irqext_type,
241 .set_wake = s3c_irqext_wake 241 .irq_set_wake = s3c_irqext_wake
242}; 242};
243 243
244static struct irq_chip s3c_irq_eint0t4 = { 244static struct irq_chip s3c_irq_eint0t4 = {
diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c
index 752f1a645f9d..f2f2e1ccd0e6 100644
--- a/arch/arm/plat-s5p/irq-eint.c
+++ b/arch/arm/plat-s5p/irq-eint.c
@@ -125,7 +125,7 @@ static struct irq_chip s5p_irq_eint = {
125 .ack = s5p_irq_eint_ack, 125 .ack = s5p_irq_eint_ack,
126 .set_type = s5p_irq_eint_set_type, 126 .set_type = s5p_irq_eint_set_type,
127#ifdef CONFIG_PM 127#ifdef CONFIG_PM
128 .set_wake = s3c_irqext_wake, 128 .irq_set_wake = s3c_irqext_wake,
129#endif 129#endif
130}; 130};
131 131
@@ -194,7 +194,7 @@ static struct irq_chip s5p_irq_vic_eint = {
194 .ack = s5p_irq_vic_eint_ack, 194 .ack = s5p_irq_vic_eint_ack,
195 .set_type = s5p_irq_eint_set_type, 195 .set_type = s5p_irq_eint_set_type,
196#ifdef CONFIG_PM 196#ifdef CONFIG_PM
197 .set_wake = s3c_irqext_wake, 197 .irq_set_wake = s3c_irqext_wake,
198#endif 198#endif
199}; 199};
200 200
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index dcd6eff4ee53..2ebf4157d93a 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -333,4 +333,12 @@ config SAMSUNG_WAKEMASK
333 and above. This code allows a set of interrupt to wakeup-mask 333 and above. This code allows a set of interrupt to wakeup-mask
334 mappings. See <plat/wakeup-mask.h> 334 mappings. See <plat/wakeup-mask.h>
335 335
336comment "Power Domain"
337
338config SAMSUNG_PD
339 bool "Samsung Power Domain"
340 depends on PM_RUNTIME
341 help
342 Say Y here if you want to control Power Domain by Runtime PM.
343
336endif 344endif
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index afcce474af8e..09dbd78b56f5 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -73,6 +73,10 @@ obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o
73 73
74obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o 74obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o
75 75
76# PD support
77
78obj-$(CONFIG_SAMSUNG_PD) += pd.o
79
76# PWM support 80# PWM support
77 81
78obj-$(CONFIG_HAVE_PWM) += pwm.o 82obj-$(CONFIG_HAVE_PWM) += pwm.o
diff --git a/arch/arm/plat-samsung/include/plat/audio.h b/arch/arm/plat-samsung/include/plat/audio.h
index 7712ff6336f4..a0826ed2f9fe 100644
--- a/arch/arm/plat-samsung/include/plat/audio.h
+++ b/arch/arm/plat-samsung/include/plat/audio.h
@@ -25,10 +25,34 @@ extern void s3c64xx_ac97_setup_gpio(int);
25#define S5PC100_SPDIF_GPG3 1 25#define S5PC100_SPDIF_GPG3 1
26extern void s5pc100_spdif_setup_gpio(int); 26extern void s5pc100_spdif_setup_gpio(int);
27 27
28struct samsung_i2s {
29/* If the Primary DAI has 5.1 Channels */
30#define QUIRK_PRI_6CHAN (1 << 0)
31/* If the I2S block has a Stereo Overlay Channel */
32#define QUIRK_SEC_DAI (1 << 1)
33/*
34 * If the I2S block has no internal prescalar or MUX (I2SMOD[10] bit)
35 * The Machine driver must provide suitably set clock to the I2S block.
36 */
37#define QUIRK_NO_MUXPSR (1 << 2)
38#define QUIRK_NEED_RSTCLR (1 << 3)
39 /* Quirks of the I2S controller */
40 u32 quirks;
41
42 /*
43 * Array of clock names that can be used to generate I2S signals.
44 * Also corresponds to clocks of I2SMOD[10]
45 */
46 const char **src_clk;
47};
48
28/** 49/**
29 * struct s3c_audio_pdata - common platform data for audio device drivers 50 * struct s3c_audio_pdata - common platform data for audio device drivers
30 * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode 51 * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode
31 */ 52 */
32struct s3c_audio_pdata { 53struct s3c_audio_pdata {
33 int (*cfg_gpio)(struct platform_device *); 54 int (*cfg_gpio)(struct platform_device *);
55 union {
56 struct samsung_i2s i2s;
57 } type;
34}; 58};
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 7935a8bc080f..94794c816b0e 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -96,6 +96,15 @@ extern struct platform_device s5pv210_device_iis1;
96extern struct platform_device s5pv210_device_iis2; 96extern struct platform_device s5pv210_device_iis2;
97extern struct platform_device s5pv210_device_spdif; 97extern struct platform_device s5pv210_device_spdif;
98 98
99extern struct platform_device s5pv310_device_ac97;
100extern struct platform_device s5pv310_device_pcm0;
101extern struct platform_device s5pv310_device_pcm1;
102extern struct platform_device s5pv310_device_pcm2;
103extern struct platform_device s5pv310_device_i2s0;
104extern struct platform_device s5pv310_device_i2s1;
105extern struct platform_device s5pv310_device_i2s2;
106extern struct platform_device s5pv310_device_spdif;
107
99extern struct platform_device s5p6442_device_pcm0; 108extern struct platform_device s5p6442_device_pcm0;
100extern struct platform_device s5p6442_device_pcm1; 109extern struct platform_device s5p6442_device_pcm1;
101extern struct platform_device s5p6442_device_iis0; 110extern struct platform_device s5p6442_device_iis0;
@@ -106,6 +115,8 @@ extern struct platform_device s5p6440_device_pcm;
106extern struct platform_device s5p6440_device_iis; 115extern struct platform_device s5p6440_device_iis;
107 116
108extern struct platform_device s5p6450_device_iis0; 117extern struct platform_device s5p6450_device_iis0;
118extern struct platform_device s5p6450_device_iis1;
119extern struct platform_device s5p6450_device_iis2;
109extern struct platform_device s5p6450_device_pcm0; 120extern struct platform_device s5p6450_device_pcm0;
110 121
111extern struct platform_device s5pc100_device_ac97; 122extern struct platform_device s5pc100_device_ac97;
diff --git a/arch/arm/plat-samsung/include/plat/pd.h b/arch/arm/plat-samsung/include/plat/pd.h
new file mode 100644
index 000000000000..5f0ad85783db
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pd.h
@@ -0,0 +1,30 @@
1/* linux/arch/arm/plat-samsung/include/plat/pd.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.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 version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#ifndef __ASM_PLAT_SAMSUNG_PD_H
12#define __ASM_PLAT_SAMSUNG_PD_H __FILE__
13
14struct samsung_pd_info {
15 int (*enable)(struct device *dev);
16 int (*disable)(struct device *dev);
17 void __iomem *base;
18};
19
20enum s5pv310_pd_block {
21 PD_MFC,
22 PD_G3D,
23 PD_LCD0,
24 PD_LCD1,
25 PD_TV,
26 PD_CAM,
27 PD_GPS
28};
29
30#endif /* __ASM_PLAT_SAMSUNG_PD_H */
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h
index 245836d91931..d9025e377675 100644
--- a/arch/arm/plat-samsung/include/plat/pm.h
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -15,6 +15,8 @@
15 * management 15 * management
16*/ 16*/
17 17
18#include <linux/irq.h>
19
18#ifdef CONFIG_PM 20#ifdef CONFIG_PM
19 21
20extern __init int s3c_pm_init(void); 22extern __init int s3c_pm_init(void);
@@ -100,7 +102,7 @@ extern void s3c_pm_do_restore(struct sleep_save *ptr, int count);
100extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count); 102extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count);
101 103
102#ifdef CONFIG_PM 104#ifdef CONFIG_PM
103extern int s3c_irqext_wake(unsigned int irqno, unsigned int state); 105extern int s3c_irqext_wake(struct irq_data *data, unsigned int state);
104extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state); 106extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state);
105extern int s3c24xx_irq_resume(struct sys_device *dev); 107extern int s3c24xx_irq_resume(struct sys_device *dev);
106#else 108#else
diff --git a/arch/arm/plat-samsung/irq-uart.c b/arch/arm/plat-samsung/irq-uart.c
index 4f8c102674ae..da31d785cbd1 100644
--- a/arch/arm/plat-samsung/irq-uart.c
+++ b/arch/arm/plat-samsung/irq-uart.c
@@ -28,9 +28,9 @@
28 * are consecutive when looking up the interrupt in the demux routines. 28 * are consecutive when looking up the interrupt in the demux routines.
29 */ 29 */
30 30
31static inline void __iomem *s3c_irq_uart_base(unsigned int irq) 31static inline void __iomem *s3c_irq_uart_base(struct irq_data *data)
32{ 32{
33 struct s3c_uart_irq *uirq = get_irq_chip_data(irq); 33 struct s3c_uart_irq *uirq = data->chip_data;
34 return uirq->regs; 34 return uirq->regs;
35} 35}
36 36
@@ -39,10 +39,10 @@ static inline unsigned int s3c_irq_uart_bit(unsigned int irq)
39 return irq & 3; 39 return irq & 3;
40} 40}
41 41
42static void s3c_irq_uart_mask(unsigned int irq) 42static void s3c_irq_uart_mask(struct irq_data *data)
43{ 43{
44 void __iomem *regs = s3c_irq_uart_base(irq); 44 void __iomem *regs = s3c_irq_uart_base(data);
45 unsigned int bit = s3c_irq_uart_bit(irq); 45 unsigned int bit = s3c_irq_uart_bit(data->irq);
46 u32 reg; 46 u32 reg;
47 47
48 reg = __raw_readl(regs + S3C64XX_UINTM); 48 reg = __raw_readl(regs + S3C64XX_UINTM);
@@ -50,10 +50,10 @@ static void s3c_irq_uart_mask(unsigned int irq)
50 __raw_writel(reg, regs + S3C64XX_UINTM); 50 __raw_writel(reg, regs + S3C64XX_UINTM);
51} 51}
52 52
53static void s3c_irq_uart_maskack(unsigned int irq) 53static void s3c_irq_uart_maskack(struct irq_data *data)
54{ 54{
55 void __iomem *regs = s3c_irq_uart_base(irq); 55 void __iomem *regs = s3c_irq_uart_base(data);
56 unsigned int bit = s3c_irq_uart_bit(irq); 56 unsigned int bit = s3c_irq_uart_bit(data->irq);
57 u32 reg; 57 u32 reg;
58 58
59 reg = __raw_readl(regs + S3C64XX_UINTM); 59 reg = __raw_readl(regs + S3C64XX_UINTM);
@@ -62,10 +62,10 @@ static void s3c_irq_uart_maskack(unsigned int irq)
62 __raw_writel(1 << bit, regs + S3C64XX_UINTP); 62 __raw_writel(1 << bit, regs + S3C64XX_UINTP);
63} 63}
64 64
65static void s3c_irq_uart_unmask(unsigned int irq) 65static void s3c_irq_uart_unmask(struct irq_data *data)
66{ 66{
67 void __iomem *regs = s3c_irq_uart_base(irq); 67 void __iomem *regs = s3c_irq_uart_base(data);
68 unsigned int bit = s3c_irq_uart_bit(irq); 68 unsigned int bit = s3c_irq_uart_bit(data->irq);
69 u32 reg; 69 u32 reg;
70 70
71 reg = __raw_readl(regs + S3C64XX_UINTM); 71 reg = __raw_readl(regs + S3C64XX_UINTM);
@@ -73,10 +73,10 @@ static void s3c_irq_uart_unmask(unsigned int irq)
73 __raw_writel(reg, regs + S3C64XX_UINTM); 73 __raw_writel(reg, regs + S3C64XX_UINTM);
74} 74}
75 75
76static void s3c_irq_uart_ack(unsigned int irq) 76static void s3c_irq_uart_ack(struct irq_data *data)
77{ 77{
78 void __iomem *regs = s3c_irq_uart_base(irq); 78 void __iomem *regs = s3c_irq_uart_base(data);
79 unsigned int bit = s3c_irq_uart_bit(irq); 79 unsigned int bit = s3c_irq_uart_bit(data->irq);
80 80
81 __raw_writel(1 << bit, regs + S3C64XX_UINTP); 81 __raw_writel(1 << bit, regs + S3C64XX_UINTP);
82} 82}
@@ -99,10 +99,10 @@ static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
99 99
100static struct irq_chip s3c_irq_uart = { 100static struct irq_chip s3c_irq_uart = {
101 .name = "s3c-uart", 101 .name = "s3c-uart",
102 .mask = s3c_irq_uart_mask, 102 .irq_mask = s3c_irq_uart_mask,
103 .unmask = s3c_irq_uart_unmask, 103 .irq_unmask = s3c_irq_uart_unmask,
104 .mask_ack = s3c_irq_uart_maskack, 104 .irq_mask_ack = s3c_irq_uart_maskack,
105 .ack = s3c_irq_uart_ack, 105 .irq_ack = s3c_irq_uart_ack,
106}; 106};
107 107
108static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq) 108static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c
index 0270519fcabc..7ce77ddb729d 100644
--- a/arch/arm/plat-samsung/irq-vic-timer.c
+++ b/arch/arm/plat-samsung/irq-vic-timer.c
@@ -29,38 +29,41 @@ static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc)
29 29
30/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ 30/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
31 31
32static void s3c_irq_timer_mask(unsigned int irq) 32static void s3c_irq_timer_mask(struct irq_data *data)
33{ 33{
34 u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); 34 u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
35 u32 mask = (u32)data->chip_data;
35 36
36 reg &= 0x1f; /* mask out pending interrupts */ 37 reg &= 0x1f; /* mask out pending interrupts */
37 reg &= ~(1 << (irq - IRQ_TIMER0)); 38 reg &= ~mask;
38 __raw_writel(reg, S3C64XX_TINT_CSTAT); 39 __raw_writel(reg, S3C64XX_TINT_CSTAT);
39} 40}
40 41
41static void s3c_irq_timer_unmask(unsigned int irq) 42static void s3c_irq_timer_unmask(struct irq_data *data)
42{ 43{
43 u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); 44 u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
45 u32 mask = (u32)data->chip_data;
44 46
45 reg &= 0x1f; /* mask out pending interrupts */ 47 reg &= 0x1f; /* mask out pending interrupts */
46 reg |= 1 << (irq - IRQ_TIMER0); 48 reg |= mask;
47 __raw_writel(reg, S3C64XX_TINT_CSTAT); 49 __raw_writel(reg, S3C64XX_TINT_CSTAT);
48} 50}
49 51
50static void s3c_irq_timer_ack(unsigned int irq) 52static void s3c_irq_timer_ack(struct irq_data *data)
51{ 53{
52 u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); 54 u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
55 u32 mask = (u32)data->chip_data;
53 56
54 reg &= 0x1f; 57 reg &= 0x1f;
55 reg |= (1 << 5) << (irq - IRQ_TIMER0); 58 reg |= mask << 5;
56 __raw_writel(reg, S3C64XX_TINT_CSTAT); 59 __raw_writel(reg, S3C64XX_TINT_CSTAT);
57} 60}
58 61
59static struct irq_chip s3c_irq_timer = { 62static struct irq_chip s3c_irq_timer = {
60 .name = "s3c-timer", 63 .name = "s3c-timer",
61 .mask = s3c_irq_timer_mask, 64 .irq_mask = s3c_irq_timer_mask,
62 .unmask = s3c_irq_timer_unmask, 65 .irq_unmask = s3c_irq_timer_unmask,
63 .ack = s3c_irq_timer_ack, 66 .irq_ack = s3c_irq_timer_ack,
64}; 67};
65 68
66/** 69/**
@@ -79,6 +82,7 @@ void __init s3c_init_vic_timer_irq(unsigned int parent_irq,
79 set_irq_chained_handler(parent_irq, s3c_irq_demux_vic_timer); 82 set_irq_chained_handler(parent_irq, s3c_irq_demux_vic_timer);
80 83
81 set_irq_chip(timer_irq, &s3c_irq_timer); 84 set_irq_chip(timer_irq, &s3c_irq_timer);
85 set_irq_chip_data(timer_irq, (void *)(1 << (timer_irq - IRQ_TIMER0)));
82 set_irq_handler(timer_irq, handle_level_irq); 86 set_irq_handler(timer_irq, handle_level_irq);
83 set_irq_flags(timer_irq, IRQF_VALID); 87 set_irq_flags(timer_irq, IRQF_VALID);
84 88
diff --git a/arch/arm/plat-samsung/pd.c b/arch/arm/plat-samsung/pd.c
new file mode 100644
index 000000000000..efe1d564473e
--- /dev/null
+++ b/arch/arm/plat-samsung/pd.c
@@ -0,0 +1,95 @@
1/* linux/arch/arm/plat-samsung/pd.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung Power domain 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/init.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/err.h>
17#include <linux/pm_runtime.h>
18
19#include <plat/pd.h>
20
21static int samsung_pd_probe(struct platform_device *pdev)
22{
23 struct samsung_pd_info *pdata = pdev->dev.platform_data;
24 struct device *dev = &pdev->dev;
25
26 if (!pdata) {
27 dev_err(dev, "no device data specified\n");
28 return -ENOENT;
29 }
30
31 pm_runtime_set_active(dev);
32 pm_runtime_enable(dev);
33
34 dev_info(dev, "power domain registered\n");
35 return 0;
36}
37
38static int __devexit samsung_pd_remove(struct platform_device *pdev)
39{
40 struct device *dev = &pdev->dev;
41
42 pm_runtime_disable(dev);
43 return 0;
44}
45
46static int samsung_pd_runtime_suspend(struct device *dev)
47{
48 struct samsung_pd_info *pdata = dev->platform_data;
49 int ret = 0;
50
51 if (pdata->disable)
52 ret = pdata->disable(dev);
53
54 dev_dbg(dev, "suspended\n");
55 return ret;
56}
57
58static int samsung_pd_runtime_resume(struct device *dev)
59{
60 struct samsung_pd_info *pdata = dev->platform_data;
61 int ret = 0;
62
63 if (pdata->enable)
64 ret = pdata->enable(dev);
65
66 dev_dbg(dev, "resumed\n");
67 return ret;
68}
69
70static const struct dev_pm_ops samsung_pd_pm_ops = {
71 .runtime_suspend = samsung_pd_runtime_suspend,
72 .runtime_resume = samsung_pd_runtime_resume,
73};
74
75static struct platform_driver samsung_pd_driver = {
76 .driver = {
77 .name = "samsung-pd",
78 .owner = THIS_MODULE,
79 .pm = &samsung_pd_pm_ops,
80 },
81 .probe = samsung_pd_probe,
82 .remove = __devexit_p(samsung_pd_remove),
83};
84
85static int __init samsung_pd_init(void)
86{
87 int ret;
88
89 ret = platform_driver_register(&samsung_pd_driver);
90 if (ret)
91 printk(KERN_ERR "%s: failed to add PD driver\n", __func__);
92
93 return ret;
94}
95arch_initcall(samsung_pd_init);
diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c
index 27cfca597699..eaa57dc969ae 100644
--- a/arch/arm/plat-samsung/pm.c
+++ b/arch/arm/plat-samsung/pm.c
@@ -136,15 +136,15 @@ static void s3c_pm_restore_uarts(void) { }
136unsigned long s3c_irqwake_intmask = 0xffffffffL; 136unsigned long s3c_irqwake_intmask = 0xffffffffL;
137unsigned long s3c_irqwake_eintmask = 0xffffffffL; 137unsigned long s3c_irqwake_eintmask = 0xffffffffL;
138 138
139int s3c_irqext_wake(unsigned int irqno, unsigned int state) 139int s3c_irqext_wake(struct irq_data *data, unsigned int state)
140{ 140{
141 unsigned long bit = 1L << IRQ_EINT_BIT(irqno); 141 unsigned long bit = 1L << IRQ_EINT_BIT(data->irq);
142 142
143 if (!(s3c_irqwake_eintallow & bit)) 143 if (!(s3c_irqwake_eintallow & bit))
144 return -ENOENT; 144 return -ENOENT;
145 145
146 printk(KERN_INFO "wake %s for irq %d\n", 146 printk(KERN_INFO "wake %s for irq %d\n",
147 state ? "enabled" : "disabled", irqno); 147 state ? "enabled" : "disabled", data->irq);
148 148
149 if (!state) 149 if (!state)
150 s3c_irqwake_eintmask |= bit; 150 s3c_irqwake_eintmask |= bit;