Merge branch 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / arch / arm / plat-samsung / devs.c
1 /* linux/arch/arm/plat-samsung/devs.c
2  *
3  * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4  *              http://www.samsung.com
5  *
6  * Base SAMSUNG platform device definitions
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/amba/pl330.h>
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/serial_s3c.h>
22 #include <linux/platform_device.h>
23 #include <linux/io.h>
24 #include <linux/slab.h>
25 #include <linux/string.h>
26 #include <linux/dma-mapping.h>
27 #include <linux/fb.h>
28 #include <linux/gfp.h>
29 #include <linux/mtd/mtd.h>
30 #include <linux/mtd/onenand.h>
31 #include <linux/mtd/partitions.h>
32 #include <linux/mmc/host.h>
33 #include <linux/ioport.h>
34 #include <linux/sizes.h>
35 #include <linux/platform_data/s3c-hsudc.h>
36 #include <linux/platform_data/s3c-hsotg.h>
37 #include <linux/platform_data/dma-s3c24xx.h>
38
39 #include <linux/platform_data/media/s5p_hdmi.h>
40
41 #include <asm/irq.h>
42 #include <asm/mach/arch.h>
43 #include <asm/mach/map.h>
44 #include <asm/mach/irq.h>
45
46 #include <mach/dma.h>
47 #include <mach/irqs.h>
48 #include <mach/map.h>
49
50 #include <plat/cpu.h>
51 #include <plat/devs.h>
52 #include <plat/adc.h>
53 #include <linux/platform_data/ata-samsung_cf.h>
54 #include <plat/fb.h>
55 #include <plat/fb-s3c2410.h>
56 #include <linux/platform_data/hwmon-s3c.h>
57 #include <linux/platform_data/i2c-s3c2410.h>
58 #include <plat/keypad.h>
59 #include <linux/platform_data/mmc-s3cmci.h>
60 #include <linux/platform_data/mtd-nand-s3c2410.h>
61 #include <plat/pwm-core.h>
62 #include <plat/sdhci.h>
63 #include <linux/platform_data/touchscreen-s3c2410.h>
64 #include <linux/platform_data/usb-s3c2410_udc.h>
65 #include <linux/platform_data/usb-ohci-s3c2410.h>
66 #include <plat/usb-phy.h>
67 #include <plat/regs-spi.h>
68 #include <linux/platform_data/asoc-s3c.h>
69 #include <linux/platform_data/spi-s3c64xx.h>
70
71 #define samsung_device_dma_mask (*((u64[]) { DMA_BIT_MASK(32) }))
72
73 /* AC97 */
74 #ifdef CONFIG_CPU_S3C2440
75 static struct resource s3c_ac97_resource[] = {
76         [0] = DEFINE_RES_MEM(S3C2440_PA_AC97, S3C2440_SZ_AC97),
77         [1] = DEFINE_RES_IRQ(IRQ_S3C244X_AC97),
78 };
79
80 struct platform_device s3c_device_ac97 = {
81         .name           = "samsung-ac97",
82         .id             = -1,
83         .num_resources  = ARRAY_SIZE(s3c_ac97_resource),
84         .resource       = s3c_ac97_resource,
85         .dev            = {
86                 .dma_mask               = &samsung_device_dma_mask,
87                 .coherent_dma_mask      = DMA_BIT_MASK(32),
88         }
89 };
90 #endif /* CONFIG_CPU_S3C2440 */
91
92 /* ADC */
93
94 #ifdef CONFIG_PLAT_S3C24XX
95 static struct resource s3c_adc_resource[] = {
96         [0] = DEFINE_RES_MEM(S3C24XX_PA_ADC, S3C24XX_SZ_ADC),
97         [1] = DEFINE_RES_IRQ(IRQ_TC),
98         [2] = DEFINE_RES_IRQ(IRQ_ADC),
99 };
100
101 struct platform_device s3c_device_adc = {
102         .name           = "s3c24xx-adc",
103         .id             = -1,
104         .num_resources  = ARRAY_SIZE(s3c_adc_resource),
105         .resource       = s3c_adc_resource,
106 };
107 #endif /* CONFIG_PLAT_S3C24XX */
108
109 #if defined(CONFIG_SAMSUNG_DEV_ADC)
110 static struct resource s3c_adc_resource[] = {
111         [0] = DEFINE_RES_MEM(SAMSUNG_PA_ADC, SZ_256),
112         [1] = DEFINE_RES_IRQ(IRQ_ADC),
113         [2] = DEFINE_RES_IRQ(IRQ_TC),
114 };
115
116 struct platform_device s3c_device_adc = {
117         .name           = "exynos-adc",
118         .id             = -1,
119         .num_resources  = ARRAY_SIZE(s3c_adc_resource),
120         .resource       = s3c_adc_resource,
121 };
122 #endif /* CONFIG_SAMSUNG_DEV_ADC */
123
124 /* Camif Controller */
125
126 #ifdef CONFIG_CPU_S3C2440
127 static struct resource s3c_camif_resource[] = {
128         [0] = DEFINE_RES_MEM(S3C2440_PA_CAMIF, S3C2440_SZ_CAMIF),
129         [1] = DEFINE_RES_IRQ(IRQ_S3C2440_CAM_C),
130         [2] = DEFINE_RES_IRQ(IRQ_S3C2440_CAM_P),
131 };
132
133 struct platform_device s3c_device_camif = {
134         .name           = "s3c2440-camif",
135         .id             = -1,
136         .num_resources  = ARRAY_SIZE(s3c_camif_resource),
137         .resource       = s3c_camif_resource,
138         .dev            = {
139                 .dma_mask               = &samsung_device_dma_mask,
140                 .coherent_dma_mask      = DMA_BIT_MASK(32),
141         }
142 };
143 #endif /* CONFIG_CPU_S3C2440 */
144
145 /* FB */
146
147 #ifdef CONFIG_S3C_DEV_FB
148 static struct resource s3c_fb_resource[] = {
149         [0] = DEFINE_RES_MEM(S3C_PA_FB, SZ_16K),
150         [1] = DEFINE_RES_IRQ(IRQ_LCD_VSYNC),
151         [2] = DEFINE_RES_IRQ(IRQ_LCD_FIFO),
152         [3] = DEFINE_RES_IRQ(IRQ_LCD_SYSTEM),
153 };
154
155 struct platform_device s3c_device_fb = {
156         .name           = "s3c-fb",
157         .id             = -1,
158         .num_resources  = ARRAY_SIZE(s3c_fb_resource),
159         .resource       = s3c_fb_resource,
160         .dev            = {
161                 .dma_mask               = &samsung_device_dma_mask,
162                 .coherent_dma_mask      = DMA_BIT_MASK(32),
163         },
164 };
165
166 void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
167 {
168         s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
169                          &s3c_device_fb);
170 }
171 #endif /* CONFIG_S3C_DEV_FB */
172
173 /* HWMON */
174
175 #ifdef CONFIG_S3C_DEV_HWMON
176 struct platform_device s3c_device_hwmon = {
177         .name           = "s3c-hwmon",
178         .id             = -1,
179         .dev.parent     = &s3c_device_adc.dev,
180 };
181
182 void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd)
183 {
184         s3c_set_platdata(pd, sizeof(struct s3c_hwmon_pdata),
185                          &s3c_device_hwmon);
186 }
187 #endif /* CONFIG_S3C_DEV_HWMON */
188
189 /* HSMMC */
190
191 #ifdef CONFIG_S3C_DEV_HSMMC
192 static struct resource s3c_hsmmc_resource[] = {
193         [0] = DEFINE_RES_MEM(S3C_PA_HSMMC0, SZ_4K),
194         [1] = DEFINE_RES_IRQ(IRQ_HSMMC0),
195 };
196
197 struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
198         .max_width      = 4,
199         .host_caps      = (MMC_CAP_4_BIT_DATA |
200                            MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
201 };
202
203 struct platform_device s3c_device_hsmmc0 = {
204         .name           = "s3c-sdhci",
205         .id             = 0,
206         .num_resources  = ARRAY_SIZE(s3c_hsmmc_resource),
207         .resource       = s3c_hsmmc_resource,
208         .dev            = {
209                 .dma_mask               = &samsung_device_dma_mask,
210                 .coherent_dma_mask      = DMA_BIT_MASK(32),
211                 .platform_data          = &s3c_hsmmc0_def_platdata,
212         },
213 };
214
215 void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
216 {
217         s3c_sdhci_set_platdata(pd, &s3c_hsmmc0_def_platdata);
218 }
219 #endif /* CONFIG_S3C_DEV_HSMMC */
220
221 #ifdef CONFIG_S3C_DEV_HSMMC1
222 static struct resource s3c_hsmmc1_resource[] = {
223         [0] = DEFINE_RES_MEM(S3C_PA_HSMMC1, SZ_4K),
224         [1] = DEFINE_RES_IRQ(IRQ_HSMMC1),
225 };
226
227 struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = {
228         .max_width      = 4,
229         .host_caps      = (MMC_CAP_4_BIT_DATA |
230                            MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
231 };
232
233 struct platform_device s3c_device_hsmmc1 = {
234         .name           = "s3c-sdhci",
235         .id             = 1,
236         .num_resources  = ARRAY_SIZE(s3c_hsmmc1_resource),
237         .resource       = s3c_hsmmc1_resource,
238         .dev            = {
239                 .dma_mask               = &samsung_device_dma_mask,
240                 .coherent_dma_mask      = DMA_BIT_MASK(32),
241                 .platform_data          = &s3c_hsmmc1_def_platdata,
242         },
243 };
244
245 void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
246 {
247         s3c_sdhci_set_platdata(pd, &s3c_hsmmc1_def_platdata);
248 }
249 #endif /* CONFIG_S3C_DEV_HSMMC1 */
250
251 /* HSMMC2 */
252
253 #ifdef CONFIG_S3C_DEV_HSMMC2
254 static struct resource s3c_hsmmc2_resource[] = {
255         [0] = DEFINE_RES_MEM(S3C_PA_HSMMC2, SZ_4K),
256         [1] = DEFINE_RES_IRQ(IRQ_HSMMC2),
257 };
258
259 struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
260         .max_width      = 4,
261         .host_caps      = (MMC_CAP_4_BIT_DATA |
262                            MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
263 };
264
265 struct platform_device s3c_device_hsmmc2 = {
266         .name           = "s3c-sdhci",
267         .id             = 2,
268         .num_resources  = ARRAY_SIZE(s3c_hsmmc2_resource),
269         .resource       = s3c_hsmmc2_resource,
270         .dev            = {
271                 .dma_mask               = &samsung_device_dma_mask,
272                 .coherent_dma_mask      = DMA_BIT_MASK(32),
273                 .platform_data          = &s3c_hsmmc2_def_platdata,
274         },
275 };
276
277 void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
278 {
279         s3c_sdhci_set_platdata(pd, &s3c_hsmmc2_def_platdata);
280 }
281 #endif /* CONFIG_S3C_DEV_HSMMC2 */
282
283 #ifdef CONFIG_S3C_DEV_HSMMC3
284 static struct resource s3c_hsmmc3_resource[] = {
285         [0] = DEFINE_RES_MEM(S3C_PA_HSMMC3, SZ_4K),
286         [1] = DEFINE_RES_IRQ(IRQ_HSMMC3),
287 };
288
289 struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
290         .max_width      = 4,
291         .host_caps      = (MMC_CAP_4_BIT_DATA |
292                            MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
293 };
294
295 struct platform_device s3c_device_hsmmc3 = {
296         .name           = "s3c-sdhci",
297         .id             = 3,
298         .num_resources  = ARRAY_SIZE(s3c_hsmmc3_resource),
299         .resource       = s3c_hsmmc3_resource,
300         .dev            = {
301                 .dma_mask               = &samsung_device_dma_mask,
302                 .coherent_dma_mask      = DMA_BIT_MASK(32),
303                 .platform_data          = &s3c_hsmmc3_def_platdata,
304         },
305 };
306
307 void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
308 {
309         s3c_sdhci_set_platdata(pd, &s3c_hsmmc3_def_platdata);
310 }
311 #endif /* CONFIG_S3C_DEV_HSMMC3 */
312
313 /* I2C */
314
315 static struct resource s3c_i2c0_resource[] = {
316         [0] = DEFINE_RES_MEM(S3C_PA_IIC, SZ_4K),
317         [1] = DEFINE_RES_IRQ(IRQ_IIC),
318 };
319
320 struct platform_device s3c_device_i2c0 = {
321         .name           = "s3c2410-i2c",
322         .id             = 0,
323         .num_resources  = ARRAY_SIZE(s3c_i2c0_resource),
324         .resource       = s3c_i2c0_resource,
325 };
326
327 struct s3c2410_platform_i2c default_i2c_data __initdata = {
328         .flags          = 0,
329         .slave_addr     = 0x10,
330         .frequency      = 100*1000,
331         .sda_delay      = 100,
332 };
333
334 void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
335 {
336         struct s3c2410_platform_i2c *npd;
337
338         if (!pd) {
339                 pd = &default_i2c_data;
340                 pd->bus_num = 0;
341         }
342
343         npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
344                                &s3c_device_i2c0);
345
346         if (!npd->cfg_gpio)
347                 npd->cfg_gpio = s3c_i2c0_cfg_gpio;
348 }
349
350 #ifdef CONFIG_S3C_DEV_I2C1
351 static struct resource s3c_i2c1_resource[] = {
352         [0] = DEFINE_RES_MEM(S3C_PA_IIC1, SZ_4K),
353         [1] = DEFINE_RES_IRQ(IRQ_IIC1),
354 };
355
356 struct platform_device s3c_device_i2c1 = {
357         .name           = "s3c2410-i2c",
358         .id             = 1,
359         .num_resources  = ARRAY_SIZE(s3c_i2c1_resource),
360         .resource       = s3c_i2c1_resource,
361 };
362
363 void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
364 {
365         struct s3c2410_platform_i2c *npd;
366
367         if (!pd) {
368                 pd = &default_i2c_data;
369                 pd->bus_num = 1;
370         }
371
372         npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
373                                &s3c_device_i2c1);
374
375         if (!npd->cfg_gpio)
376                 npd->cfg_gpio = s3c_i2c1_cfg_gpio;
377 }
378 #endif /* CONFIG_S3C_DEV_I2C1 */
379
380 #ifdef CONFIG_S3C_DEV_I2C2
381 static struct resource s3c_i2c2_resource[] = {
382         [0] = DEFINE_RES_MEM(S3C_PA_IIC2, SZ_4K),
383         [1] = DEFINE_RES_IRQ(IRQ_IIC2),
384 };
385
386 struct platform_device s3c_device_i2c2 = {
387         .name           = "s3c2410-i2c",
388         .id             = 2,
389         .num_resources  = ARRAY_SIZE(s3c_i2c2_resource),
390         .resource       = s3c_i2c2_resource,
391 };
392
393 void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd)
394 {
395         struct s3c2410_platform_i2c *npd;
396
397         if (!pd) {
398                 pd = &default_i2c_data;
399                 pd->bus_num = 2;
400         }
401
402         npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
403                                &s3c_device_i2c2);
404
405         if (!npd->cfg_gpio)
406                 npd->cfg_gpio = s3c_i2c2_cfg_gpio;
407 }
408 #endif /* CONFIG_S3C_DEV_I2C2 */
409
410 #ifdef CONFIG_S3C_DEV_I2C3
411 static struct resource s3c_i2c3_resource[] = {
412         [0] = DEFINE_RES_MEM(S3C_PA_IIC3, SZ_4K),
413         [1] = DEFINE_RES_IRQ(IRQ_IIC3),
414 };
415
416 struct platform_device s3c_device_i2c3 = {
417         .name           = "s3c2440-i2c",
418         .id             = 3,
419         .num_resources  = ARRAY_SIZE(s3c_i2c3_resource),
420         .resource       = s3c_i2c3_resource,
421 };
422
423 void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd)
424 {
425         struct s3c2410_platform_i2c *npd;
426
427         if (!pd) {
428                 pd = &default_i2c_data;
429                 pd->bus_num = 3;
430         }
431
432         npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
433                                &s3c_device_i2c3);
434
435         if (!npd->cfg_gpio)
436                 npd->cfg_gpio = s3c_i2c3_cfg_gpio;
437 }
438 #endif /*CONFIG_S3C_DEV_I2C3 */
439
440 #ifdef CONFIG_S3C_DEV_I2C4
441 static struct resource s3c_i2c4_resource[] = {
442         [0] = DEFINE_RES_MEM(S3C_PA_IIC4, SZ_4K),
443         [1] = DEFINE_RES_IRQ(IRQ_IIC4),
444 };
445
446 struct platform_device s3c_device_i2c4 = {
447         .name           = "s3c2440-i2c",
448         .id             = 4,
449         .num_resources  = ARRAY_SIZE(s3c_i2c4_resource),
450         .resource       = s3c_i2c4_resource,
451 };
452
453 void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd)
454 {
455         struct s3c2410_platform_i2c *npd;
456
457         if (!pd) {
458                 pd = &default_i2c_data;
459                 pd->bus_num = 4;
460         }
461
462         npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
463                                &s3c_device_i2c4);
464
465         if (!npd->cfg_gpio)
466                 npd->cfg_gpio = s3c_i2c4_cfg_gpio;
467 }
468 #endif /*CONFIG_S3C_DEV_I2C4 */
469
470 #ifdef CONFIG_S3C_DEV_I2C5
471 static struct resource s3c_i2c5_resource[] = {
472         [0] = DEFINE_RES_MEM(S3C_PA_IIC5, SZ_4K),
473         [1] = DEFINE_RES_IRQ(IRQ_IIC5),
474 };
475
476 struct platform_device s3c_device_i2c5 = {
477         .name           = "s3c2440-i2c",
478         .id             = 5,
479         .num_resources  = ARRAY_SIZE(s3c_i2c5_resource),
480         .resource       = s3c_i2c5_resource,
481 };
482
483 void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd)
484 {
485         struct s3c2410_platform_i2c *npd;
486
487         if (!pd) {
488                 pd = &default_i2c_data;
489                 pd->bus_num = 5;
490         }
491
492         npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
493                                &s3c_device_i2c5);
494
495         if (!npd->cfg_gpio)
496                 npd->cfg_gpio = s3c_i2c5_cfg_gpio;
497 }
498 #endif /*CONFIG_S3C_DEV_I2C5 */
499
500 #ifdef CONFIG_S3C_DEV_I2C6
501 static struct resource s3c_i2c6_resource[] = {
502         [0] = DEFINE_RES_MEM(S3C_PA_IIC6, SZ_4K),
503         [1] = DEFINE_RES_IRQ(IRQ_IIC6),
504 };
505
506 struct platform_device s3c_device_i2c6 = {
507         .name           = "s3c2440-i2c",
508         .id             = 6,
509         .num_resources  = ARRAY_SIZE(s3c_i2c6_resource),
510         .resource       = s3c_i2c6_resource,
511 };
512
513 void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd)
514 {
515         struct s3c2410_platform_i2c *npd;
516
517         if (!pd) {
518                 pd = &default_i2c_data;
519                 pd->bus_num = 6;
520         }
521
522         npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
523                                &s3c_device_i2c6);
524
525         if (!npd->cfg_gpio)
526                 npd->cfg_gpio = s3c_i2c6_cfg_gpio;
527 }
528 #endif /* CONFIG_S3C_DEV_I2C6 */
529
530 #ifdef CONFIG_S3C_DEV_I2C7
531 static struct resource s3c_i2c7_resource[] = {
532         [0] = DEFINE_RES_MEM(S3C_PA_IIC7, SZ_4K),
533         [1] = DEFINE_RES_IRQ(IRQ_IIC7),
534 };
535
536 struct platform_device s3c_device_i2c7 = {
537         .name           = "s3c2440-i2c",
538         .id             = 7,
539         .num_resources  = ARRAY_SIZE(s3c_i2c7_resource),
540         .resource       = s3c_i2c7_resource,
541 };
542
543 void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd)
544 {
545         struct s3c2410_platform_i2c *npd;
546
547         if (!pd) {
548                 pd = &default_i2c_data;
549                 pd->bus_num = 7;
550         }
551
552         npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
553                                &s3c_device_i2c7);
554
555         if (!npd->cfg_gpio)
556                 npd->cfg_gpio = s3c_i2c7_cfg_gpio;
557 }
558 #endif /* CONFIG_S3C_DEV_I2C7 */
559
560 /* I2S */
561
562 #ifdef CONFIG_PLAT_S3C24XX
563 static struct resource s3c_iis_resource[] = {
564         [0] = DEFINE_RES_MEM(S3C24XX_PA_IIS, S3C24XX_SZ_IIS),
565 };
566
567 struct platform_device s3c_device_iis = {
568         .name           = "s3c24xx-iis",
569         .id             = -1,
570         .num_resources  = ARRAY_SIZE(s3c_iis_resource),
571         .resource       = s3c_iis_resource,
572         .dev            = {
573                 .dma_mask               = &samsung_device_dma_mask,
574                 .coherent_dma_mask      = DMA_BIT_MASK(32),
575         }
576 };
577 #endif /* CONFIG_PLAT_S3C24XX */
578
579 /* IDE CFCON */
580
581 #ifdef CONFIG_SAMSUNG_DEV_IDE
582 static struct resource s3c_cfcon_resource[] = {
583         [0] = DEFINE_RES_MEM(SAMSUNG_PA_CFCON, SZ_16K),
584         [1] = DEFINE_RES_IRQ(IRQ_CFCON),
585 };
586
587 struct platform_device s3c_device_cfcon = {
588         .id             = 0,
589         .num_resources  = ARRAY_SIZE(s3c_cfcon_resource),
590         .resource       = s3c_cfcon_resource,
591 };
592
593 void __init s3c_ide_set_platdata(struct s3c_ide_platdata *pdata)
594 {
595         s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata),
596                          &s3c_device_cfcon);
597 }
598 #endif /* CONFIG_SAMSUNG_DEV_IDE */
599
600 /* KEYPAD */
601
602 #ifdef CONFIG_SAMSUNG_DEV_KEYPAD
603 static struct resource samsung_keypad_resources[] = {
604         [0] = DEFINE_RES_MEM(SAMSUNG_PA_KEYPAD, SZ_32),
605         [1] = DEFINE_RES_IRQ(IRQ_KEYPAD),
606 };
607
608 struct platform_device samsung_device_keypad = {
609         .name           = "samsung-keypad",
610         .id             = -1,
611         .num_resources  = ARRAY_SIZE(samsung_keypad_resources),
612         .resource       = samsung_keypad_resources,
613 };
614
615 void __init samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd)
616 {
617         struct samsung_keypad_platdata *npd;
618
619         npd = s3c_set_platdata(pd, sizeof(struct samsung_keypad_platdata),
620                         &samsung_device_keypad);
621
622         if (!npd->cfg_gpio)
623                 npd->cfg_gpio = samsung_keypad_cfg_gpio;
624 }
625 #endif /* CONFIG_SAMSUNG_DEV_KEYPAD */
626
627 /* LCD Controller */
628
629 #ifdef CONFIG_PLAT_S3C24XX
630 static struct resource s3c_lcd_resource[] = {
631         [0] = DEFINE_RES_MEM(S3C24XX_PA_LCD, S3C24XX_SZ_LCD),
632         [1] = DEFINE_RES_IRQ(IRQ_LCD),
633 };
634
635 struct platform_device s3c_device_lcd = {
636         .name           = "s3c2410-lcd",
637         .id             = -1,
638         .num_resources  = ARRAY_SIZE(s3c_lcd_resource),
639         .resource       = s3c_lcd_resource,
640         .dev            = {
641                 .dma_mask               = &samsung_device_dma_mask,
642                 .coherent_dma_mask      = DMA_BIT_MASK(32),
643         }
644 };
645
646 void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
647 {
648         struct s3c2410fb_mach_info *npd;
649
650         npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_lcd);
651         if (npd) {
652                 npd->displays = kmemdup(pd->displays,
653                         sizeof(struct s3c2410fb_display) * npd->num_displays,
654                         GFP_KERNEL);
655                 if (!npd->displays)
656                         printk(KERN_ERR "no memory for LCD display data\n");
657         } else {
658                 printk(KERN_ERR "no memory for LCD platform data\n");
659         }
660 }
661 #endif /* CONFIG_PLAT_S3C24XX */
662
663 /* NAND */
664
665 #ifdef CONFIG_S3C_DEV_NAND
666 static struct resource s3c_nand_resource[] = {
667         [0] = DEFINE_RES_MEM(S3C_PA_NAND, SZ_1M),
668 };
669
670 struct platform_device s3c_device_nand = {
671         .name           = "s3c2410-nand",
672         .id             = -1,
673         .num_resources  = ARRAY_SIZE(s3c_nand_resource),
674         .resource       = s3c_nand_resource,
675 };
676
677 /*
678  * s3c_nand_copy_set() - copy nand set data
679  * @set: The new structure, directly copied from the old.
680  *
681  * Copy all the fields from the NAND set field from what is probably __initdata
682  * to new kernel memory. The code returns 0 if the copy happened correctly or
683  * an error code for the calling function to display.
684  *
685  * Note, we currently do not try and look to see if we've already copied the
686  * data in a previous set.
687  */
688 static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set)
689 {
690         void *ptr;
691         int size;
692
693         size = sizeof(struct mtd_partition) * set->nr_partitions;
694         if (size) {
695                 ptr = kmemdup(set->partitions, size, GFP_KERNEL);
696                 set->partitions = ptr;
697
698                 if (!ptr)
699                         return -ENOMEM;
700         }
701
702         if (set->nr_map && set->nr_chips) {
703                 size = sizeof(int) * set->nr_chips;
704                 ptr = kmemdup(set->nr_map, size, GFP_KERNEL);
705                 set->nr_map = ptr;
706
707                 if (!ptr)
708                         return -ENOMEM;
709         }
710
711         return 0;
712 }
713
714 void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
715 {
716         struct s3c2410_platform_nand *npd;
717         int size;
718         int ret;
719
720         /* note, if we get a failure in allocation, we simply drop out of the
721          * function. If there is so little memory available at initialisation
722          * time then there is little chance the system is going to run.
723          */
724
725         npd = s3c_set_platdata(nand, sizeof(struct s3c2410_platform_nand),
726                                 &s3c_device_nand);
727         if (!npd)
728                 return;
729
730         /* now see if we need to copy any of the nand set data */
731
732         size = sizeof(struct s3c2410_nand_set) * npd->nr_sets;
733         if (size) {
734                 struct s3c2410_nand_set *from = npd->sets;
735                 struct s3c2410_nand_set *to;
736                 int i;
737
738                 to = kmemdup(from, size, GFP_KERNEL);
739                 npd->sets = to; /* set, even if we failed */
740
741                 if (!to) {
742                         printk(KERN_ERR "%s: no memory for sets\n", __func__);
743                         return;
744                 }
745
746                 for (i = 0; i < npd->nr_sets; i++) {
747                         ret = s3c_nand_copy_set(to);
748                         if (ret) {
749                                 printk(KERN_ERR "%s: failed to copy set %d\n",
750                                 __func__, i);
751                                 return;
752                         }
753                         to++;
754                 }
755         }
756 }
757 #endif /* CONFIG_S3C_DEV_NAND */
758
759 /* ONENAND */
760
761 #ifdef CONFIG_S3C_DEV_ONENAND
762 static struct resource s3c_onenand_resources[] = {
763         [0] = DEFINE_RES_MEM(S3C_PA_ONENAND, SZ_1K),
764         [1] = DEFINE_RES_MEM(S3C_PA_ONENAND_BUF, S3C_SZ_ONENAND_BUF),
765         [2] = DEFINE_RES_IRQ(IRQ_ONENAND),
766 };
767
768 struct platform_device s3c_device_onenand = {
769         .name           = "samsung-onenand",
770         .id             = 0,
771         .num_resources  = ARRAY_SIZE(s3c_onenand_resources),
772         .resource       = s3c_onenand_resources,
773 };
774 #endif /* CONFIG_S3C_DEV_ONENAND */
775
776 #ifdef CONFIG_S3C64XX_DEV_ONENAND1
777 static struct resource s3c64xx_onenand1_resources[] = {
778         [0] = DEFINE_RES_MEM(S3C64XX_PA_ONENAND1, SZ_1K),
779         [1] = DEFINE_RES_MEM(S3C64XX_PA_ONENAND1_BUF, S3C64XX_SZ_ONENAND1_BUF),
780         [2] = DEFINE_RES_IRQ(IRQ_ONENAND1),
781 };
782
783 struct platform_device s3c64xx_device_onenand1 = {
784         .name           = "samsung-onenand",
785         .id             = 1,
786         .num_resources  = ARRAY_SIZE(s3c64xx_onenand1_resources),
787         .resource       = s3c64xx_onenand1_resources,
788 };
789
790 void __init s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata)
791 {
792         s3c_set_platdata(pdata, sizeof(struct onenand_platform_data),
793                          &s3c64xx_device_onenand1);
794 }
795 #endif /* CONFIG_S3C64XX_DEV_ONENAND1 */
796
797 /* PWM Timer */
798
799 #ifdef CONFIG_SAMSUNG_DEV_PWM
800 static struct resource samsung_pwm_resource[] = {
801         DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K),
802 };
803
804 struct platform_device samsung_device_pwm = {
805         .name           = "samsung-pwm",
806         .id             = -1,
807         .num_resources  = ARRAY_SIZE(samsung_pwm_resource),
808         .resource       = samsung_pwm_resource,
809 };
810
811 void __init samsung_pwm_set_platdata(struct samsung_pwm_variant *pd)
812 {
813         samsung_device_pwm.dev.platform_data = pd;
814 }
815 #endif /* CONFIG_SAMSUNG_DEV_PWM */
816
817 /* RTC */
818
819 #ifdef CONFIG_PLAT_S3C24XX
820 static struct resource s3c_rtc_resource[] = {
821         [0] = DEFINE_RES_MEM(S3C24XX_PA_RTC, SZ_256),
822         [1] = DEFINE_RES_IRQ(IRQ_RTC),
823         [2] = DEFINE_RES_IRQ(IRQ_TICK),
824 };
825
826 struct platform_device s3c_device_rtc = {
827         .name           = "s3c2410-rtc",
828         .id             = -1,
829         .num_resources  = ARRAY_SIZE(s3c_rtc_resource),
830         .resource       = s3c_rtc_resource,
831 };
832 #endif /* CONFIG_PLAT_S3C24XX */
833
834 #ifdef CONFIG_S3C_DEV_RTC
835 static struct resource s3c_rtc_resource[] = {
836         [0] = DEFINE_RES_MEM(S3C_PA_RTC, SZ_256),
837         [1] = DEFINE_RES_IRQ(IRQ_RTC_ALARM),
838         [2] = DEFINE_RES_IRQ(IRQ_RTC_TIC),
839 };
840
841 struct platform_device s3c_device_rtc = {
842         .name           = "s3c64xx-rtc",
843         .id             = -1,
844         .num_resources  = ARRAY_SIZE(s3c_rtc_resource),
845         .resource       = s3c_rtc_resource,
846 };
847 #endif /* CONFIG_S3C_DEV_RTC */
848
849 /* SDI */
850
851 #ifdef CONFIG_PLAT_S3C24XX
852 static struct resource s3c_sdi_resource[] = {
853         [0] = DEFINE_RES_MEM(S3C24XX_PA_SDI, S3C24XX_SZ_SDI),
854         [1] = DEFINE_RES_IRQ(IRQ_SDI),
855 };
856
857 struct platform_device s3c_device_sdi = {
858         .name           = "s3c2410-sdi",
859         .id             = -1,
860         .num_resources  = ARRAY_SIZE(s3c_sdi_resource),
861         .resource       = s3c_sdi_resource,
862 };
863
864 void __init s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata)
865 {
866         s3c_set_platdata(pdata, sizeof(struct s3c24xx_mci_pdata),
867                          &s3c_device_sdi);
868 }
869 #endif /* CONFIG_PLAT_S3C24XX */
870
871 /* SPI */
872
873 #ifdef CONFIG_PLAT_S3C24XX
874 static struct resource s3c_spi0_resource[] = {
875         [0] = DEFINE_RES_MEM(S3C24XX_PA_SPI, SZ_32),
876         [1] = DEFINE_RES_IRQ(IRQ_SPI0),
877 };
878
879 struct platform_device s3c_device_spi0 = {
880         .name           = "s3c2410-spi",
881         .id             = 0,
882         .num_resources  = ARRAY_SIZE(s3c_spi0_resource),
883         .resource       = s3c_spi0_resource,
884         .dev            = {
885                 .dma_mask               = &samsung_device_dma_mask,
886                 .coherent_dma_mask      = DMA_BIT_MASK(32),
887         }
888 };
889
890 static struct resource s3c_spi1_resource[] = {
891         [0] = DEFINE_RES_MEM(S3C24XX_PA_SPI1, SZ_32),
892         [1] = DEFINE_RES_IRQ(IRQ_SPI1),
893 };
894
895 struct platform_device s3c_device_spi1 = {
896         .name           = "s3c2410-spi",
897         .id             = 1,
898         .num_resources  = ARRAY_SIZE(s3c_spi1_resource),
899         .resource       = s3c_spi1_resource,
900         .dev            = {
901                 .dma_mask               = &samsung_device_dma_mask,
902                 .coherent_dma_mask      = DMA_BIT_MASK(32),
903         }
904 };
905 #endif /* CONFIG_PLAT_S3C24XX */
906
907 /* Touchscreen */
908
909 #ifdef CONFIG_PLAT_S3C24XX
910 static struct resource s3c_ts_resource[] = {
911         [0] = DEFINE_RES_MEM(S3C24XX_PA_ADC, S3C24XX_SZ_ADC),
912         [1] = DEFINE_RES_IRQ(IRQ_TC),
913 };
914
915 struct platform_device s3c_device_ts = {
916         .name           = "s3c2410-ts",
917         .id             = -1,
918         .dev.parent     = &s3c_device_adc.dev,
919         .num_resources  = ARRAY_SIZE(s3c_ts_resource),
920         .resource       = s3c_ts_resource,
921 };
922
923 void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_info)
924 {
925         s3c_set_platdata(hard_s3c2410ts_info,
926                          sizeof(struct s3c2410_ts_mach_info), &s3c_device_ts);
927 }
928 #endif /* CONFIG_PLAT_S3C24XX */
929
930 #ifdef CONFIG_SAMSUNG_DEV_TS
931 static struct s3c2410_ts_mach_info default_ts_data __initdata = {
932         .delay                  = 10000,
933         .presc                  = 49,
934         .oversampling_shift     = 2,
935 };
936
937 void __init s3c64xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd)
938 {
939         if (!pd)
940                 pd = &default_ts_data;
941
942         s3c_set_platdata(pd, sizeof(struct s3c2410_ts_mach_info),
943                          &s3c_device_adc);
944 }
945 #endif /* CONFIG_SAMSUNG_DEV_TS */
946
947 /* USB */
948
949 #ifdef CONFIG_S3C_DEV_USB_HOST
950 static struct resource s3c_usb_resource[] = {
951         [0] = DEFINE_RES_MEM(S3C_PA_USBHOST, SZ_256),
952         [1] = DEFINE_RES_IRQ(IRQ_USBH),
953 };
954
955 struct platform_device s3c_device_ohci = {
956         .name           = "s3c2410-ohci",
957         .id             = -1,
958         .num_resources  = ARRAY_SIZE(s3c_usb_resource),
959         .resource       = s3c_usb_resource,
960         .dev            = {
961                 .dma_mask               = &samsung_device_dma_mask,
962                 .coherent_dma_mask      = DMA_BIT_MASK(32),
963         }
964 };
965
966 /*
967  * s3c_ohci_set_platdata - initialise OHCI device platform data
968  * @info: The platform data.
969  *
970  * This call copies the @info passed in and sets the device .platform_data
971  * field to that copy. The @info is copied so that the original can be marked
972  * __initdata.
973  */
974
975 void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info)
976 {
977         s3c_set_platdata(info, sizeof(struct s3c2410_hcd_info),
978                          &s3c_device_ohci);
979 }
980 #endif /* CONFIG_S3C_DEV_USB_HOST */
981
982 /* USB Device (Gadget) */
983
984 #ifdef CONFIG_PLAT_S3C24XX
985 static struct resource s3c_usbgadget_resource[] = {
986         [0] = DEFINE_RES_MEM(S3C24XX_PA_USBDEV, S3C24XX_SZ_USBDEV),
987         [1] = DEFINE_RES_IRQ(IRQ_USBD),
988 };
989
990 struct platform_device s3c_device_usbgadget = {
991         .name           = "s3c2410-usbgadget",
992         .id             = -1,
993         .num_resources  = ARRAY_SIZE(s3c_usbgadget_resource),
994         .resource       = s3c_usbgadget_resource,
995 };
996
997 void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd)
998 {
999         s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usbgadget);
1000 }
1001 #endif /* CONFIG_PLAT_S3C24XX */
1002
1003 /* USB HSOTG */
1004
1005 #ifdef CONFIG_S3C_DEV_USB_HSOTG
1006 static struct resource s3c_usb_hsotg_resources[] = {
1007         [0] = DEFINE_RES_MEM(S3C_PA_USB_HSOTG, SZ_128K),
1008         [1] = DEFINE_RES_IRQ(IRQ_OTG),
1009 };
1010
1011 struct platform_device s3c_device_usb_hsotg = {
1012         .name           = "s3c-hsotg",
1013         .id             = -1,
1014         .num_resources  = ARRAY_SIZE(s3c_usb_hsotg_resources),
1015         .resource       = s3c_usb_hsotg_resources,
1016         .dev            = {
1017                 .dma_mask               = &samsung_device_dma_mask,
1018                 .coherent_dma_mask      = DMA_BIT_MASK(32),
1019         },
1020 };
1021
1022 void __init dwc2_hsotg_set_platdata(struct dwc2_hsotg_plat *pd)
1023 {
1024         struct dwc2_hsotg_plat *npd;
1025
1026         npd = s3c_set_platdata(pd, sizeof(struct dwc2_hsotg_plat),
1027                         &s3c_device_usb_hsotg);
1028
1029         if (!npd->phy_init)
1030                 npd->phy_init = s5p_usb_phy_init;
1031         if (!npd->phy_exit)
1032                 npd->phy_exit = s5p_usb_phy_exit;
1033 }
1034 #endif /* CONFIG_S3C_DEV_USB_HSOTG */
1035
1036 /* USB High Spped 2.0 Device (Gadget) */
1037
1038 #ifdef CONFIG_PLAT_S3C24XX
1039 static struct resource s3c_hsudc_resource[] = {
1040         [0] = DEFINE_RES_MEM(S3C2416_PA_HSUDC, S3C2416_SZ_HSUDC),
1041         [1] = DEFINE_RES_IRQ(IRQ_USBD),
1042 };
1043
1044 struct platform_device s3c_device_usb_hsudc = {
1045         .name           = "s3c-hsudc",
1046         .id             = -1,
1047         .num_resources  = ARRAY_SIZE(s3c_hsudc_resource),
1048         .resource       = s3c_hsudc_resource,
1049         .dev            = {
1050                 .dma_mask               = &samsung_device_dma_mask,
1051                 .coherent_dma_mask      = DMA_BIT_MASK(32),
1052         },
1053 };
1054
1055 void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd)
1056 {
1057         s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usb_hsudc);
1058 }
1059 #endif /* CONFIG_PLAT_S3C24XX */
1060
1061 /* WDT */
1062
1063 #ifdef CONFIG_S3C_DEV_WDT
1064 static struct resource s3c_wdt_resource[] = {
1065         [0] = DEFINE_RES_MEM(S3C_PA_WDT, SZ_1K),
1066         [1] = DEFINE_RES_IRQ(IRQ_WDT),
1067 };
1068
1069 struct platform_device s3c_device_wdt = {
1070         .name           = "s3c2410-wdt",
1071         .id             = -1,
1072         .num_resources  = ARRAY_SIZE(s3c_wdt_resource),
1073         .resource       = s3c_wdt_resource,
1074 };
1075 #endif /* CONFIG_S3C_DEV_WDT */
1076
1077 #ifdef CONFIG_S3C64XX_DEV_SPI0
1078 static struct resource s3c64xx_spi0_resource[] = {
1079         [0] = DEFINE_RES_MEM(S3C_PA_SPI0, SZ_256),
1080         [1] = DEFINE_RES_IRQ(IRQ_SPI0),
1081 };
1082
1083 struct platform_device s3c64xx_device_spi0 = {
1084         .name           = "s3c6410-spi",
1085         .id             = 0,
1086         .num_resources  = ARRAY_SIZE(s3c64xx_spi0_resource),
1087         .resource       = s3c64xx_spi0_resource,
1088         .dev = {
1089                 .dma_mask               = &samsung_device_dma_mask,
1090                 .coherent_dma_mask      = DMA_BIT_MASK(32),
1091         },
1092 };
1093
1094 void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
1095                                                 int num_cs)
1096 {
1097         struct s3c64xx_spi_info pd;
1098
1099         /* Reject invalid configuration */
1100         if (!num_cs || src_clk_nr < 0) {
1101                 pr_err("%s: Invalid SPI configuration\n", __func__);
1102                 return;
1103         }
1104
1105         pd.num_cs = num_cs;
1106         pd.src_clk_nr = src_clk_nr;
1107         pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio;
1108
1109         s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0);
1110 }
1111 #endif /* CONFIG_S3C64XX_DEV_SPI0 */
1112
1113 #ifdef CONFIG_S3C64XX_DEV_SPI1
1114 static struct resource s3c64xx_spi1_resource[] = {
1115         [0] = DEFINE_RES_MEM(S3C_PA_SPI1, SZ_256),
1116         [1] = DEFINE_RES_IRQ(IRQ_SPI1),
1117 };
1118
1119 struct platform_device s3c64xx_device_spi1 = {
1120         .name           = "s3c6410-spi",
1121         .id             = 1,
1122         .num_resources  = ARRAY_SIZE(s3c64xx_spi1_resource),
1123         .resource       = s3c64xx_spi1_resource,
1124         .dev = {
1125                 .dma_mask               = &samsung_device_dma_mask,
1126                 .coherent_dma_mask      = DMA_BIT_MASK(32),
1127         },
1128 };
1129
1130 void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
1131                                                 int num_cs)
1132 {
1133         struct s3c64xx_spi_info pd;
1134
1135         /* Reject invalid configuration */
1136         if (!num_cs || src_clk_nr < 0) {
1137                 pr_err("%s: Invalid SPI configuration\n", __func__);
1138                 return;
1139         }
1140
1141         pd.num_cs = num_cs;
1142         pd.src_clk_nr = src_clk_nr;
1143         pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio;
1144
1145         s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1);
1146 }
1147 #endif /* CONFIG_S3C64XX_DEV_SPI1 */
1148
1149 #ifdef CONFIG_S3C64XX_DEV_SPI2
1150 static struct resource s3c64xx_spi2_resource[] = {
1151         [0] = DEFINE_RES_MEM(S3C_PA_SPI2, SZ_256),
1152         [1] = DEFINE_RES_IRQ(IRQ_SPI2),
1153 };
1154
1155 struct platform_device s3c64xx_device_spi2 = {
1156         .name           = "s3c6410-spi",
1157         .id             = 2,
1158         .num_resources  = ARRAY_SIZE(s3c64xx_spi2_resource),
1159         .resource       = s3c64xx_spi2_resource,
1160         .dev = {
1161                 .dma_mask               = &samsung_device_dma_mask,
1162                 .coherent_dma_mask      = DMA_BIT_MASK(32),
1163         },
1164 };
1165
1166 void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
1167                                                 int num_cs)
1168 {
1169         struct s3c64xx_spi_info pd;
1170
1171         /* Reject invalid configuration */
1172         if (!num_cs || src_clk_nr < 0) {
1173                 pr_err("%s: Invalid SPI configuration\n", __func__);
1174                 return;
1175         }
1176
1177         pd.num_cs = num_cs;
1178         pd.src_clk_nr = src_clk_nr;
1179         pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio;
1180
1181         s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2);
1182 }
1183 #endif /* CONFIG_S3C64XX_DEV_SPI2 */