Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Copyright (c) 2011 Samsung Electronics Co., Ltd.
0004 //      http://www.samsung.com
0005 //
0006 // Base Samsung platform device definitions
0007 
0008 #include <linux/gpio.h>
0009 #include <linux/kernel.h>
0010 #include <linux/types.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/list.h>
0013 #include <linux/timer.h>
0014 #include <linux/init.h>
0015 #include <linux/serial_core.h>
0016 #include <linux/serial_s3c.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/io.h>
0019 #include <linux/slab.h>
0020 #include <linux/string.h>
0021 #include <linux/dma-mapping.h>
0022 #include <linux/fb.h>
0023 #include <linux/gfp.h>
0024 #include <linux/mtd/mtd.h>
0025 #include <linux/mtd/onenand.h>
0026 #include <linux/mtd/partitions.h>
0027 #include <linux/mmc/host.h>
0028 #include <linux/ioport.h>
0029 #include <linux/sizes.h>
0030 #include <linux/platform_data/s3c-hsudc.h>
0031 #include <linux/platform_data/s3c-hsotg.h>
0032 #include <linux/platform_data/dma-s3c24xx.h>
0033 
0034 #include <linux/platform_data/media/s5p_hdmi.h>
0035 
0036 #include <asm/irq.h>
0037 #include <asm/mach/arch.h>
0038 #include <asm/mach/map.h>
0039 #include <asm/mach/irq.h>
0040 
0041 #include "irqs.h"
0042 #include "map.h"
0043 #include "gpio-samsung.h"
0044 #include "gpio-cfg.h"
0045 
0046 #ifdef CONFIG_PLAT_S3C24XX
0047 #include "regs-s3c2443-clock.h"
0048 #endif /* CONFIG_PLAT_S3C24XX */
0049 
0050 #include "cpu.h"
0051 #include "devs.h"
0052 #include <linux/soc/samsung/s3c-adc.h>
0053 #include <linux/platform_data/ata-samsung_cf.h>
0054 #include "fb.h"
0055 #include <linux/platform_data/fb-s3c2410.h>
0056 #include <linux/platform_data/hwmon-s3c.h>
0057 #include <linux/platform_data/i2c-s3c2410.h>
0058 #include "keypad.h"
0059 #include <linux/platform_data/mmc-s3cmci.h>
0060 #include <linux/platform_data/mtd-nand-s3c2410.h>
0061 #include "pwm-core.h"
0062 #include "sdhci.h"
0063 #include <linux/platform_data/touchscreen-s3c2410.h>
0064 #include <linux/platform_data/usb-s3c2410_udc.h>
0065 #include <linux/platform_data/usb-ohci-s3c2410.h>
0066 #include "usb-phy.h"
0067 #include <linux/platform_data/asoc-s3c.h>
0068 #include <linux/platform_data/spi-s3c64xx.h>
0069 
0070 #define samsung_device_dma_mask (*((u64[]) { DMA_BIT_MASK(32) }))
0071 
0072 /* AC97 */
0073 #ifdef CONFIG_CPU_S3C2440
0074 static struct resource s3c_ac97_resource[] = {
0075     [0] = DEFINE_RES_MEM(S3C2440_PA_AC97, S3C2440_SZ_AC97),
0076     [1] = DEFINE_RES_IRQ(IRQ_S3C244X_AC97),
0077 };
0078 
0079 struct platform_device s3c_device_ac97 = {
0080     .name       = "samsung-ac97",
0081     .id     = -1,
0082     .num_resources  = ARRAY_SIZE(s3c_ac97_resource),
0083     .resource   = s3c_ac97_resource,
0084     .dev        = {
0085         .dma_mask       = &samsung_device_dma_mask,
0086         .coherent_dma_mask  = DMA_BIT_MASK(32),
0087     }
0088 };
0089 #endif /* CONFIG_CPU_S3C2440 */
0090 
0091 /* ADC */
0092 
0093 #ifdef CONFIG_PLAT_S3C24XX
0094 static struct resource s3c_adc_resource[] = {
0095     [0] = DEFINE_RES_MEM(S3C24XX_PA_ADC, S3C24XX_SZ_ADC),
0096     [1] = DEFINE_RES_IRQ(IRQ_TC),
0097     [2] = DEFINE_RES_IRQ(IRQ_ADC),
0098 };
0099 
0100 struct platform_device s3c_device_adc = {
0101     .name       = "s3c24xx-adc",
0102     .id     = -1,
0103     .num_resources  = ARRAY_SIZE(s3c_adc_resource),
0104     .resource   = s3c_adc_resource,
0105 };
0106 #endif /* CONFIG_PLAT_S3C24XX */
0107 
0108 #if defined(CONFIG_SAMSUNG_DEV_ADC)
0109 static struct resource s3c_adc_resource[] = {
0110     [0] = DEFINE_RES_MEM(SAMSUNG_PA_ADC, SZ_256),
0111     [1] = DEFINE_RES_IRQ(IRQ_ADC),
0112     [2] = DEFINE_RES_IRQ(IRQ_TC),
0113 };
0114 
0115 struct platform_device s3c_device_adc = {
0116     .name       = "exynos-adc",
0117     .id     = -1,
0118     .num_resources  = ARRAY_SIZE(s3c_adc_resource),
0119     .resource   = s3c_adc_resource,
0120 };
0121 #endif /* CONFIG_SAMSUNG_DEV_ADC */
0122 
0123 /* Camif Controller */
0124 
0125 #ifdef CONFIG_CPU_S3C2440
0126 static struct resource s3c_camif_resource[] = {
0127     [0] = DEFINE_RES_MEM(S3C2440_PA_CAMIF, S3C2440_SZ_CAMIF),
0128     [1] = DEFINE_RES_IRQ(IRQ_S3C2440_CAM_C),
0129     [2] = DEFINE_RES_IRQ(IRQ_S3C2440_CAM_P),
0130 };
0131 
0132 struct platform_device s3c_device_camif = {
0133     .name       = "s3c2440-camif",
0134     .id     = -1,
0135     .num_resources  = ARRAY_SIZE(s3c_camif_resource),
0136     .resource   = s3c_camif_resource,
0137     .dev        = {
0138         .dma_mask       = &samsung_device_dma_mask,
0139         .coherent_dma_mask  = DMA_BIT_MASK(32),
0140     }
0141 };
0142 #endif /* CONFIG_CPU_S3C2440 */
0143 
0144 /* FB */
0145 
0146 #ifdef CONFIG_S3C_DEV_FB
0147 static struct resource s3c_fb_resource[] = {
0148     [0] = DEFINE_RES_MEM(S3C_PA_FB, SZ_16K),
0149     [1] = DEFINE_RES_IRQ(IRQ_LCD_VSYNC),
0150     [2] = DEFINE_RES_IRQ(IRQ_LCD_FIFO),
0151     [3] = DEFINE_RES_IRQ(IRQ_LCD_SYSTEM),
0152 };
0153 
0154 struct platform_device s3c_device_fb = {
0155     .name       = "s3c-fb",
0156     .id     = -1,
0157     .num_resources  = ARRAY_SIZE(s3c_fb_resource),
0158     .resource   = s3c_fb_resource,
0159     .dev        = {
0160         .dma_mask       = &samsung_device_dma_mask,
0161         .coherent_dma_mask  = DMA_BIT_MASK(32),
0162     },
0163 };
0164 
0165 void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
0166 {
0167     s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
0168              &s3c_device_fb);
0169 }
0170 #endif /* CONFIG_S3C_DEV_FB */
0171 
0172 /* HWMON */
0173 
0174 #ifdef CONFIG_S3C_DEV_HWMON
0175 struct platform_device s3c_device_hwmon = {
0176     .name       = "s3c-hwmon",
0177     .id     = -1,
0178     .dev.parent = &s3c_device_adc.dev,
0179 };
0180 
0181 void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd)
0182 {
0183     s3c_set_platdata(pd, sizeof(struct s3c_hwmon_pdata),
0184              &s3c_device_hwmon);
0185 }
0186 #endif /* CONFIG_S3C_DEV_HWMON */
0187 
0188 /* HSMMC */
0189 
0190 #ifdef CONFIG_S3C_DEV_HSMMC
0191 static struct resource s3c_hsmmc_resource[] = {
0192     [0] = DEFINE_RES_MEM(S3C_PA_HSMMC0, SZ_4K),
0193     [1] = DEFINE_RES_IRQ(IRQ_HSMMC0),
0194 };
0195 
0196 struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
0197     .max_width  = 4,
0198     .host_caps  = (MMC_CAP_4_BIT_DATA |
0199                MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
0200 };
0201 
0202 struct platform_device s3c_device_hsmmc0 = {
0203     .name       = "s3c-sdhci",
0204     .id     = 0,
0205     .num_resources  = ARRAY_SIZE(s3c_hsmmc_resource),
0206     .resource   = s3c_hsmmc_resource,
0207     .dev        = {
0208         .dma_mask       = &samsung_device_dma_mask,
0209         .coherent_dma_mask  = DMA_BIT_MASK(32),
0210         .platform_data      = &s3c_hsmmc0_def_platdata,
0211     },
0212 };
0213 
0214 void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
0215 {
0216     s3c_sdhci_set_platdata(pd, &s3c_hsmmc0_def_platdata);
0217 }
0218 #endif /* CONFIG_S3C_DEV_HSMMC */
0219 
0220 #ifdef CONFIG_S3C_DEV_HSMMC1
0221 static struct resource s3c_hsmmc1_resource[] = {
0222     [0] = DEFINE_RES_MEM(S3C_PA_HSMMC1, SZ_4K),
0223     [1] = DEFINE_RES_IRQ(IRQ_HSMMC1),
0224 };
0225 
0226 struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = {
0227     .max_width  = 4,
0228     .host_caps  = (MMC_CAP_4_BIT_DATA |
0229                MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
0230 };
0231 
0232 struct platform_device s3c_device_hsmmc1 = {
0233     .name       = "s3c-sdhci",
0234     .id     = 1,
0235     .num_resources  = ARRAY_SIZE(s3c_hsmmc1_resource),
0236     .resource   = s3c_hsmmc1_resource,
0237     .dev        = {
0238         .dma_mask       = &samsung_device_dma_mask,
0239         .coherent_dma_mask  = DMA_BIT_MASK(32),
0240         .platform_data      = &s3c_hsmmc1_def_platdata,
0241     },
0242 };
0243 
0244 void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
0245 {
0246     s3c_sdhci_set_platdata(pd, &s3c_hsmmc1_def_platdata);
0247 }
0248 #endif /* CONFIG_S3C_DEV_HSMMC1 */
0249 
0250 /* HSMMC2 */
0251 
0252 #ifdef CONFIG_S3C_DEV_HSMMC2
0253 static struct resource s3c_hsmmc2_resource[] = {
0254     [0] = DEFINE_RES_MEM(S3C_PA_HSMMC2, SZ_4K),
0255     [1] = DEFINE_RES_IRQ(IRQ_HSMMC2),
0256 };
0257 
0258 struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
0259     .max_width  = 4,
0260     .host_caps  = (MMC_CAP_4_BIT_DATA |
0261                MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
0262 };
0263 
0264 struct platform_device s3c_device_hsmmc2 = {
0265     .name       = "s3c-sdhci",
0266     .id     = 2,
0267     .num_resources  = ARRAY_SIZE(s3c_hsmmc2_resource),
0268     .resource   = s3c_hsmmc2_resource,
0269     .dev        = {
0270         .dma_mask       = &samsung_device_dma_mask,
0271         .coherent_dma_mask  = DMA_BIT_MASK(32),
0272         .platform_data      = &s3c_hsmmc2_def_platdata,
0273     },
0274 };
0275 
0276 void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
0277 {
0278     s3c_sdhci_set_platdata(pd, &s3c_hsmmc2_def_platdata);
0279 }
0280 #endif /* CONFIG_S3C_DEV_HSMMC2 */
0281 
0282 #ifdef CONFIG_S3C_DEV_HSMMC3
0283 static struct resource s3c_hsmmc3_resource[] = {
0284     [0] = DEFINE_RES_MEM(S3C_PA_HSMMC3, SZ_4K),
0285     [1] = DEFINE_RES_IRQ(IRQ_HSMMC3),
0286 };
0287 
0288 struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
0289     .max_width  = 4,
0290     .host_caps  = (MMC_CAP_4_BIT_DATA |
0291                MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
0292 };
0293 
0294 struct platform_device s3c_device_hsmmc3 = {
0295     .name       = "s3c-sdhci",
0296     .id     = 3,
0297     .num_resources  = ARRAY_SIZE(s3c_hsmmc3_resource),
0298     .resource   = s3c_hsmmc3_resource,
0299     .dev        = {
0300         .dma_mask       = &samsung_device_dma_mask,
0301         .coherent_dma_mask  = DMA_BIT_MASK(32),
0302         .platform_data      = &s3c_hsmmc3_def_platdata,
0303     },
0304 };
0305 
0306 void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
0307 {
0308     s3c_sdhci_set_platdata(pd, &s3c_hsmmc3_def_platdata);
0309 }
0310 #endif /* CONFIG_S3C_DEV_HSMMC3 */
0311 
0312 /* I2C */
0313 
0314 static struct resource s3c_i2c0_resource[] = {
0315     [0] = DEFINE_RES_MEM(S3C_PA_IIC, SZ_4K),
0316     [1] = DEFINE_RES_IRQ(IRQ_IIC),
0317 };
0318 
0319 struct platform_device s3c_device_i2c0 = {
0320     .name       = "s3c2410-i2c",
0321     .id     = 0,
0322     .num_resources  = ARRAY_SIZE(s3c_i2c0_resource),
0323     .resource   = s3c_i2c0_resource,
0324 };
0325 
0326 struct s3c2410_platform_i2c default_i2c_data __initdata = {
0327     .flags      = 0,
0328     .slave_addr = 0x10,
0329     .frequency  = 100*1000,
0330     .sda_delay  = 100,
0331 };
0332 
0333 void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
0334 {
0335     struct s3c2410_platform_i2c *npd;
0336 
0337     if (!pd) {
0338         pd = &default_i2c_data;
0339         pd->bus_num = 0;
0340     }
0341 
0342     npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c0);
0343 
0344     if (!npd->cfg_gpio)
0345         npd->cfg_gpio = s3c_i2c0_cfg_gpio;
0346 }
0347 
0348 #ifdef CONFIG_S3C_DEV_I2C1
0349 static struct resource s3c_i2c1_resource[] = {
0350     [0] = DEFINE_RES_MEM(S3C_PA_IIC1, SZ_4K),
0351     [1] = DEFINE_RES_IRQ(IRQ_IIC1),
0352 };
0353 
0354 struct platform_device s3c_device_i2c1 = {
0355     .name       = "s3c2410-i2c",
0356     .id     = 1,
0357     .num_resources  = ARRAY_SIZE(s3c_i2c1_resource),
0358     .resource   = s3c_i2c1_resource,
0359 };
0360 
0361 void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
0362 {
0363     struct s3c2410_platform_i2c *npd;
0364 
0365     if (!pd) {
0366         pd = &default_i2c_data;
0367         pd->bus_num = 1;
0368     }
0369 
0370     npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c1);
0371 
0372     if (!npd->cfg_gpio)
0373         npd->cfg_gpio = s3c_i2c1_cfg_gpio;
0374 }
0375 #endif /* CONFIG_S3C_DEV_I2C1 */
0376 
0377 #ifdef CONFIG_S3C_DEV_I2C2
0378 static struct resource s3c_i2c2_resource[] = {
0379     [0] = DEFINE_RES_MEM(S3C_PA_IIC2, SZ_4K),
0380     [1] = DEFINE_RES_IRQ(IRQ_IIC2),
0381 };
0382 
0383 struct platform_device s3c_device_i2c2 = {
0384     .name       = "s3c2410-i2c",
0385     .id     = 2,
0386     .num_resources  = ARRAY_SIZE(s3c_i2c2_resource),
0387     .resource   = s3c_i2c2_resource,
0388 };
0389 
0390 void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd)
0391 {
0392     struct s3c2410_platform_i2c *npd;
0393 
0394     if (!pd) {
0395         pd = &default_i2c_data;
0396         pd->bus_num = 2;
0397     }
0398 
0399     npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c2);
0400 
0401     if (!npd->cfg_gpio)
0402         npd->cfg_gpio = s3c_i2c2_cfg_gpio;
0403 }
0404 #endif /* CONFIG_S3C_DEV_I2C2 */
0405 
0406 #ifdef CONFIG_S3C_DEV_I2C3
0407 static struct resource s3c_i2c3_resource[] = {
0408     [0] = DEFINE_RES_MEM(S3C_PA_IIC3, SZ_4K),
0409     [1] = DEFINE_RES_IRQ(IRQ_IIC3),
0410 };
0411 
0412 struct platform_device s3c_device_i2c3 = {
0413     .name       = "s3c2440-i2c",
0414     .id     = 3,
0415     .num_resources  = ARRAY_SIZE(s3c_i2c3_resource),
0416     .resource   = s3c_i2c3_resource,
0417 };
0418 
0419 void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd)
0420 {
0421     struct s3c2410_platform_i2c *npd;
0422 
0423     if (!pd) {
0424         pd = &default_i2c_data;
0425         pd->bus_num = 3;
0426     }
0427 
0428     npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c3);
0429 
0430     if (!npd->cfg_gpio)
0431         npd->cfg_gpio = s3c_i2c3_cfg_gpio;
0432 }
0433 #endif /*CONFIG_S3C_DEV_I2C3 */
0434 
0435 #ifdef CONFIG_S3C_DEV_I2C4
0436 static struct resource s3c_i2c4_resource[] = {
0437     [0] = DEFINE_RES_MEM(S3C_PA_IIC4, SZ_4K),
0438     [1] = DEFINE_RES_IRQ(IRQ_IIC4),
0439 };
0440 
0441 struct platform_device s3c_device_i2c4 = {
0442     .name       = "s3c2440-i2c",
0443     .id     = 4,
0444     .num_resources  = ARRAY_SIZE(s3c_i2c4_resource),
0445     .resource   = s3c_i2c4_resource,
0446 };
0447 
0448 void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd)
0449 {
0450     struct s3c2410_platform_i2c *npd;
0451 
0452     if (!pd) {
0453         pd = &default_i2c_data;
0454         pd->bus_num = 4;
0455     }
0456 
0457     npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c4);
0458 
0459     if (!npd->cfg_gpio)
0460         npd->cfg_gpio = s3c_i2c4_cfg_gpio;
0461 }
0462 #endif /*CONFIG_S3C_DEV_I2C4 */
0463 
0464 #ifdef CONFIG_S3C_DEV_I2C5
0465 static struct resource s3c_i2c5_resource[] = {
0466     [0] = DEFINE_RES_MEM(S3C_PA_IIC5, SZ_4K),
0467     [1] = DEFINE_RES_IRQ(IRQ_IIC5),
0468 };
0469 
0470 struct platform_device s3c_device_i2c5 = {
0471     .name       = "s3c2440-i2c",
0472     .id     = 5,
0473     .num_resources  = ARRAY_SIZE(s3c_i2c5_resource),
0474     .resource   = s3c_i2c5_resource,
0475 };
0476 
0477 void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd)
0478 {
0479     struct s3c2410_platform_i2c *npd;
0480 
0481     if (!pd) {
0482         pd = &default_i2c_data;
0483         pd->bus_num = 5;
0484     }
0485 
0486     npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c5);
0487 
0488     if (!npd->cfg_gpio)
0489         npd->cfg_gpio = s3c_i2c5_cfg_gpio;
0490 }
0491 #endif /*CONFIG_S3C_DEV_I2C5 */
0492 
0493 #ifdef CONFIG_S3C_DEV_I2C6
0494 static struct resource s3c_i2c6_resource[] = {
0495     [0] = DEFINE_RES_MEM(S3C_PA_IIC6, SZ_4K),
0496     [1] = DEFINE_RES_IRQ(IRQ_IIC6),
0497 };
0498 
0499 struct platform_device s3c_device_i2c6 = {
0500     .name       = "s3c2440-i2c",
0501     .id     = 6,
0502     .num_resources  = ARRAY_SIZE(s3c_i2c6_resource),
0503     .resource   = s3c_i2c6_resource,
0504 };
0505 
0506 void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd)
0507 {
0508     struct s3c2410_platform_i2c *npd;
0509 
0510     if (!pd) {
0511         pd = &default_i2c_data;
0512         pd->bus_num = 6;
0513     }
0514 
0515     npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c6);
0516 
0517     if (!npd->cfg_gpio)
0518         npd->cfg_gpio = s3c_i2c6_cfg_gpio;
0519 }
0520 #endif /* CONFIG_S3C_DEV_I2C6 */
0521 
0522 #ifdef CONFIG_S3C_DEV_I2C7
0523 static struct resource s3c_i2c7_resource[] = {
0524     [0] = DEFINE_RES_MEM(S3C_PA_IIC7, SZ_4K),
0525     [1] = DEFINE_RES_IRQ(IRQ_IIC7),
0526 };
0527 
0528 struct platform_device s3c_device_i2c7 = {
0529     .name       = "s3c2440-i2c",
0530     .id     = 7,
0531     .num_resources  = ARRAY_SIZE(s3c_i2c7_resource),
0532     .resource   = s3c_i2c7_resource,
0533 };
0534 
0535 void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd)
0536 {
0537     struct s3c2410_platform_i2c *npd;
0538 
0539     if (!pd) {
0540         pd = &default_i2c_data;
0541         pd->bus_num = 7;
0542     }
0543 
0544     npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c7);
0545 
0546     if (!npd->cfg_gpio)
0547         npd->cfg_gpio = s3c_i2c7_cfg_gpio;
0548 }
0549 #endif /* CONFIG_S3C_DEV_I2C7 */
0550 
0551 /* I2S */
0552 
0553 #ifdef CONFIG_PLAT_S3C24XX
0554 static struct resource s3c_iis_resource[] = {
0555     [0] = DEFINE_RES_MEM(S3C24XX_PA_IIS, S3C24XX_SZ_IIS),
0556 };
0557 
0558 struct platform_device s3c_device_iis = {
0559     .name       = "s3c24xx-iis",
0560     .id     = -1,
0561     .num_resources  = ARRAY_SIZE(s3c_iis_resource),
0562     .resource   = s3c_iis_resource,
0563     .dev        = {
0564         .dma_mask       = &samsung_device_dma_mask,
0565         .coherent_dma_mask  = DMA_BIT_MASK(32),
0566     }
0567 };
0568 #endif /* CONFIG_PLAT_S3C24XX */
0569 
0570 /* IDE CFCON */
0571 
0572 #ifdef CONFIG_SAMSUNG_DEV_IDE
0573 static struct resource s3c_cfcon_resource[] = {
0574     [0] = DEFINE_RES_MEM(SAMSUNG_PA_CFCON, SZ_16K),
0575     [1] = DEFINE_RES_IRQ(IRQ_CFCON),
0576 };
0577 
0578 struct platform_device s3c_device_cfcon = {
0579     .id     = 0,
0580     .num_resources  = ARRAY_SIZE(s3c_cfcon_resource),
0581     .resource   = s3c_cfcon_resource,
0582 };
0583 
0584 void __init s3c_ide_set_platdata(struct s3c_ide_platdata *pdata)
0585 {
0586     s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata),
0587              &s3c_device_cfcon);
0588 }
0589 #endif /* CONFIG_SAMSUNG_DEV_IDE */
0590 
0591 /* KEYPAD */
0592 
0593 #ifdef CONFIG_SAMSUNG_DEV_KEYPAD
0594 static struct resource samsung_keypad_resources[] = {
0595     [0] = DEFINE_RES_MEM(SAMSUNG_PA_KEYPAD, SZ_32),
0596     [1] = DEFINE_RES_IRQ(IRQ_KEYPAD),
0597 };
0598 
0599 struct platform_device samsung_device_keypad = {
0600     .name       = "samsung-keypad",
0601     .id     = -1,
0602     .num_resources  = ARRAY_SIZE(samsung_keypad_resources),
0603     .resource   = samsung_keypad_resources,
0604 };
0605 
0606 void __init samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd)
0607 {
0608     struct samsung_keypad_platdata *npd;
0609 
0610     npd = s3c_set_platdata(pd, sizeof(*npd), &samsung_device_keypad);
0611 
0612     if (!npd->cfg_gpio)
0613         npd->cfg_gpio = samsung_keypad_cfg_gpio;
0614 }
0615 #endif /* CONFIG_SAMSUNG_DEV_KEYPAD */
0616 
0617 /* LCD Controller */
0618 
0619 #ifdef CONFIG_PLAT_S3C24XX
0620 static struct resource s3c_lcd_resource[] = {
0621     [0] = DEFINE_RES_MEM(S3C24XX_PA_LCD, S3C24XX_SZ_LCD),
0622     [1] = DEFINE_RES_IRQ(IRQ_LCD),
0623 };
0624 
0625 struct platform_device s3c_device_lcd = {
0626     .name       = "s3c2410-lcd",
0627     .id     = -1,
0628     .num_resources  = ARRAY_SIZE(s3c_lcd_resource),
0629     .resource   = s3c_lcd_resource,
0630     .dev        = {
0631         .dma_mask       = &samsung_device_dma_mask,
0632         .coherent_dma_mask  = DMA_BIT_MASK(32),
0633     }
0634 };
0635 
0636 void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
0637 {
0638     struct s3c2410fb_mach_info *npd;
0639 
0640     npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_lcd);
0641     if (npd) {
0642         npd->displays = kmemdup(pd->displays,
0643             sizeof(struct s3c2410fb_display) * npd->num_displays,
0644             GFP_KERNEL);
0645         if (!npd->displays)
0646             printk(KERN_ERR "no memory for LCD display data\n");
0647     } else {
0648         printk(KERN_ERR "no memory for LCD platform data\n");
0649     }
0650 }
0651 #endif /* CONFIG_PLAT_S3C24XX */
0652 
0653 /* NAND */
0654 
0655 #ifdef CONFIG_S3C_DEV_NAND
0656 static struct resource s3c_nand_resource[] = {
0657     [0] = DEFINE_RES_MEM(S3C_PA_NAND, SZ_1M),
0658 };
0659 
0660 struct platform_device s3c_device_nand = {
0661     .name       = "s3c2410-nand",
0662     .id     = -1,
0663     .num_resources  = ARRAY_SIZE(s3c_nand_resource),
0664     .resource   = s3c_nand_resource,
0665 };
0666 
0667 /*
0668  * s3c_nand_copy_set() - copy nand set data
0669  * @set: The new structure, directly copied from the old.
0670  *
0671  * Copy all the fields from the NAND set field from what is probably __initdata
0672  * to new kernel memory. The code returns 0 if the copy happened correctly or
0673  * an error code for the calling function to display.
0674  *
0675  * Note, we currently do not try and look to see if we've already copied the
0676  * data in a previous set.
0677  */
0678 static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set)
0679 {
0680     void *ptr;
0681     int size;
0682 
0683     size = sizeof(struct mtd_partition) * set->nr_partitions;
0684     if (size) {
0685         ptr = kmemdup(set->partitions, size, GFP_KERNEL);
0686         set->partitions = ptr;
0687 
0688         if (!ptr)
0689             return -ENOMEM;
0690     }
0691 
0692     if (set->nr_map && set->nr_chips) {
0693         size = sizeof(int) * set->nr_chips;
0694         ptr = kmemdup(set->nr_map, size, GFP_KERNEL);
0695         set->nr_map = ptr;
0696 
0697         if (!ptr)
0698             return -ENOMEM;
0699     }
0700 
0701     return 0;
0702 }
0703 
0704 void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
0705 {
0706     struct s3c2410_platform_nand *npd;
0707     int size;
0708     int ret;
0709 
0710     /* note, if we get a failure in allocation, we simply drop out of the
0711      * function. If there is so little memory available at initialisation
0712      * time then there is little chance the system is going to run.
0713      */
0714 
0715     npd = s3c_set_platdata(nand, sizeof(*npd), &s3c_device_nand);
0716     if (!npd)
0717         return;
0718 
0719     /* now see if we need to copy any of the nand set data */
0720 
0721     size = sizeof(struct s3c2410_nand_set) * npd->nr_sets;
0722     if (size) {
0723         struct s3c2410_nand_set *from = npd->sets;
0724         struct s3c2410_nand_set *to;
0725         int i;
0726 
0727         to = kmemdup(from, size, GFP_KERNEL);
0728         npd->sets = to; /* set, even if we failed */
0729 
0730         if (!to) {
0731             printk(KERN_ERR "%s: no memory for sets\n", __func__);
0732             return;
0733         }
0734 
0735         for (i = 0; i < npd->nr_sets; i++) {
0736             ret = s3c_nand_copy_set(to);
0737             if (ret) {
0738                 printk(KERN_ERR "%s: failed to copy set %d\n",
0739                 __func__, i);
0740                 return;
0741             }
0742             to++;
0743         }
0744     }
0745 }
0746 #endif /* CONFIG_S3C_DEV_NAND */
0747 
0748 /* ONENAND */
0749 
0750 #ifdef CONFIG_S3C_DEV_ONENAND
0751 static struct resource s3c_onenand_resources[] = {
0752     [0] = DEFINE_RES_MEM(S3C_PA_ONENAND, SZ_1K),
0753     [1] = DEFINE_RES_MEM(S3C_PA_ONENAND_BUF, S3C_SZ_ONENAND_BUF),
0754     [2] = DEFINE_RES_IRQ(IRQ_ONENAND),
0755 };
0756 
0757 struct platform_device s3c_device_onenand = {
0758     .name       = "samsung-onenand",
0759     .id     = 0,
0760     .num_resources  = ARRAY_SIZE(s3c_onenand_resources),
0761     .resource   = s3c_onenand_resources,
0762 };
0763 #endif /* CONFIG_S3C_DEV_ONENAND */
0764 
0765 #ifdef CONFIG_S3C64XX_DEV_ONENAND1
0766 static struct resource s3c64xx_onenand1_resources[] = {
0767     [0] = DEFINE_RES_MEM(S3C64XX_PA_ONENAND1, SZ_1K),
0768     [1] = DEFINE_RES_MEM(S3C64XX_PA_ONENAND1_BUF, S3C64XX_SZ_ONENAND1_BUF),
0769     [2] = DEFINE_RES_IRQ(IRQ_ONENAND1),
0770 };
0771 
0772 struct platform_device s3c64xx_device_onenand1 = {
0773     .name       = "samsung-onenand",
0774     .id     = 1,
0775     .num_resources  = ARRAY_SIZE(s3c64xx_onenand1_resources),
0776     .resource   = s3c64xx_onenand1_resources,
0777 };
0778 
0779 void __init s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata)
0780 {
0781     s3c_set_platdata(pdata, sizeof(struct onenand_platform_data),
0782              &s3c64xx_device_onenand1);
0783 }
0784 #endif /* CONFIG_S3C64XX_DEV_ONENAND1 */
0785 
0786 /* PWM Timer */
0787 
0788 #ifdef CONFIG_SAMSUNG_DEV_PWM
0789 static struct resource samsung_pwm_resource[] = {
0790     DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K),
0791 };
0792 
0793 struct platform_device samsung_device_pwm = {
0794     .name       = "samsung-pwm",
0795     .id     = -1,
0796     .num_resources  = ARRAY_SIZE(samsung_pwm_resource),
0797     .resource   = samsung_pwm_resource,
0798 };
0799 
0800 void __init samsung_pwm_set_platdata(struct samsung_pwm_variant *pd)
0801 {
0802     samsung_device_pwm.dev.platform_data = pd;
0803 }
0804 #endif /* CONFIG_SAMSUNG_DEV_PWM */
0805 
0806 /* RTC */
0807 
0808 #ifdef CONFIG_PLAT_S3C24XX
0809 static struct resource s3c_rtc_resource[] = {
0810     [0] = DEFINE_RES_MEM(S3C24XX_PA_RTC, SZ_256),
0811     [1] = DEFINE_RES_IRQ(IRQ_RTC),
0812     [2] = DEFINE_RES_IRQ(IRQ_TICK),
0813 };
0814 
0815 struct platform_device s3c_device_rtc = {
0816     .name       = "s3c2410-rtc",
0817     .id     = -1,
0818     .num_resources  = ARRAY_SIZE(s3c_rtc_resource),
0819     .resource   = s3c_rtc_resource,
0820 };
0821 #endif /* CONFIG_PLAT_S3C24XX */
0822 
0823 #ifdef CONFIG_S3C_DEV_RTC
0824 static struct resource s3c_rtc_resource[] = {
0825     [0] = DEFINE_RES_MEM(S3C_PA_RTC, SZ_256),
0826     [1] = DEFINE_RES_IRQ(IRQ_RTC_ALARM),
0827     [2] = DEFINE_RES_IRQ(IRQ_RTC_TIC),
0828 };
0829 
0830 struct platform_device s3c_device_rtc = {
0831     .name       = "s3c64xx-rtc",
0832     .id     = -1,
0833     .num_resources  = ARRAY_SIZE(s3c_rtc_resource),
0834     .resource   = s3c_rtc_resource,
0835 };
0836 #endif /* CONFIG_S3C_DEV_RTC */
0837 
0838 /* SDI */
0839 
0840 #ifdef CONFIG_PLAT_S3C24XX
0841 void s3c24xx_mci_def_set_power(unsigned char power_mode, unsigned short vdd)
0842 {
0843     switch (power_mode) {
0844     case MMC_POWER_ON:
0845     case MMC_POWER_UP:
0846         /* Configure GPE5...GPE10 pins in SD mode */
0847         s3c_gpio_cfgall_range(S3C2410_GPE(5), 6, S3C_GPIO_SFN(2),
0848                       S3C_GPIO_PULL_NONE);
0849         break;
0850 
0851     case MMC_POWER_OFF:
0852     default:
0853         gpio_direction_output(S3C2410_GPE(5), 0);
0854         break;
0855     }
0856 }
0857 
0858 static struct resource s3c_sdi_resource[] = {
0859     [0] = DEFINE_RES_MEM(S3C24XX_PA_SDI, S3C24XX_SZ_SDI),
0860     [1] = DEFINE_RES_IRQ(IRQ_SDI),
0861 };
0862 
0863 static struct s3c24xx_mci_pdata s3cmci_def_pdata = {
0864     /* This is currently here to avoid a number of if (host->pdata)
0865      * checks. Any zero fields to ensure reasonable defaults are picked. */
0866     .no_wprotect = 1,
0867     .no_detect = 1,
0868     .set_power = s3c24xx_mci_def_set_power,
0869 };
0870 
0871 struct platform_device s3c_device_sdi = {
0872     .name       = "s3c2410-sdi",
0873     .id     = -1,
0874     .num_resources  = ARRAY_SIZE(s3c_sdi_resource),
0875     .resource   = s3c_sdi_resource,
0876     .dev.platform_data = &s3cmci_def_pdata,
0877 };
0878 
0879 void __init s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata)
0880 {
0881     s3c_set_platdata(pdata, sizeof(struct s3c24xx_mci_pdata),
0882              &s3c_device_sdi);
0883 }
0884 #endif /* CONFIG_PLAT_S3C24XX */
0885 
0886 /* SPI */
0887 
0888 #ifdef CONFIG_PLAT_S3C24XX
0889 static struct resource s3c_spi0_resource[] = {
0890     [0] = DEFINE_RES_MEM(S3C24XX_PA_SPI, SZ_32),
0891     [1] = DEFINE_RES_IRQ(IRQ_SPI0),
0892 };
0893 
0894 struct platform_device s3c_device_spi0 = {
0895     .name       = "s3c2410-spi",
0896     .id     = 0,
0897     .num_resources  = ARRAY_SIZE(s3c_spi0_resource),
0898     .resource   = s3c_spi0_resource,
0899     .dev        = {
0900         .dma_mask       = &samsung_device_dma_mask,
0901         .coherent_dma_mask  = DMA_BIT_MASK(32),
0902     }
0903 };
0904 
0905 static struct resource s3c_spi1_resource[] = {
0906     [0] = DEFINE_RES_MEM(S3C24XX_PA_SPI1, SZ_32),
0907     [1] = DEFINE_RES_IRQ(IRQ_SPI1),
0908 };
0909 
0910 struct platform_device s3c_device_spi1 = {
0911     .name       = "s3c2410-spi",
0912     .id     = 1,
0913     .num_resources  = ARRAY_SIZE(s3c_spi1_resource),
0914     .resource   = s3c_spi1_resource,
0915     .dev        = {
0916         .dma_mask       = &samsung_device_dma_mask,
0917         .coherent_dma_mask  = DMA_BIT_MASK(32),
0918     }
0919 };
0920 #endif /* CONFIG_PLAT_S3C24XX */
0921 
0922 /* Touchscreen */
0923 
0924 #ifdef CONFIG_PLAT_S3C24XX
0925 static struct resource s3c_ts_resource[] = {
0926     [0] = DEFINE_RES_MEM(S3C24XX_PA_ADC, S3C24XX_SZ_ADC),
0927     [1] = DEFINE_RES_IRQ(IRQ_TC),
0928 };
0929 
0930 struct platform_device s3c_device_ts = {
0931     .name       = "s3c2410-ts",
0932     .id     = -1,
0933     .dev.parent = &s3c_device_adc.dev,
0934     .num_resources  = ARRAY_SIZE(s3c_ts_resource),
0935     .resource   = s3c_ts_resource,
0936 };
0937 
0938 void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_info)
0939 {
0940     s3c_set_platdata(hard_s3c2410ts_info,
0941              sizeof(struct s3c2410_ts_mach_info), &s3c_device_ts);
0942 }
0943 #endif /* CONFIG_PLAT_S3C24XX */
0944 
0945 #ifdef CONFIG_SAMSUNG_DEV_TS
0946 static struct s3c2410_ts_mach_info default_ts_data __initdata = {
0947     .delay          = 10000,
0948     .presc          = 49,
0949     .oversampling_shift = 2,
0950 };
0951 
0952 void __init s3c64xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd)
0953 {
0954     if (!pd)
0955         pd = &default_ts_data;
0956 
0957     s3c_set_platdata(pd, sizeof(struct s3c2410_ts_mach_info),
0958              &s3c_device_adc);
0959 }
0960 #endif /* CONFIG_SAMSUNG_DEV_TS */
0961 
0962 /* USB */
0963 
0964 #ifdef CONFIG_S3C_DEV_USB_HOST
0965 static struct resource s3c_usb_resource[] = {
0966     [0] = DEFINE_RES_MEM(S3C_PA_USBHOST, SZ_256),
0967     [1] = DEFINE_RES_IRQ(IRQ_USBH),
0968 };
0969 
0970 struct platform_device s3c_device_ohci = {
0971     .name       = "s3c2410-ohci",
0972     .id     = -1,
0973     .num_resources  = ARRAY_SIZE(s3c_usb_resource),
0974     .resource   = s3c_usb_resource,
0975     .dev        = {
0976         .dma_mask       = &samsung_device_dma_mask,
0977         .coherent_dma_mask  = DMA_BIT_MASK(32),
0978     }
0979 };
0980 
0981 /*
0982  * s3c_ohci_set_platdata - initialise OHCI device platform data
0983  * @info: The platform data.
0984  *
0985  * This call copies the @info passed in and sets the device .platform_data
0986  * field to that copy. The @info is copied so that the original can be marked
0987  * __initdata.
0988  */
0989 
0990 void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info)
0991 {
0992     s3c_set_platdata(info, sizeof(struct s3c2410_hcd_info),
0993              &s3c_device_ohci);
0994 }
0995 #endif /* CONFIG_S3C_DEV_USB_HOST */
0996 
0997 /* USB Device (Gadget) */
0998 
0999 #ifdef CONFIG_PLAT_S3C24XX
1000 static struct resource s3c_usbgadget_resource[] = {
1001     [0] = DEFINE_RES_MEM(S3C24XX_PA_USBDEV, S3C24XX_SZ_USBDEV),
1002     [1] = DEFINE_RES_IRQ(IRQ_USBD),
1003 };
1004 
1005 struct platform_device s3c_device_usbgadget = {
1006     .name       = "s3c2410-usbgadget",
1007     .id     = -1,
1008     .num_resources  = ARRAY_SIZE(s3c_usbgadget_resource),
1009     .resource   = s3c_usbgadget_resource,
1010 };
1011 
1012 void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd)
1013 {
1014     s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usbgadget);
1015 }
1016 #endif /* CONFIG_PLAT_S3C24XX */
1017 
1018 /* USB HSOTG */
1019 
1020 #ifdef CONFIG_S3C_DEV_USB_HSOTG
1021 static struct resource s3c_usb_hsotg_resources[] = {
1022     [0] = DEFINE_RES_MEM(S3C_PA_USB_HSOTG, SZ_128K),
1023     [1] = DEFINE_RES_IRQ(IRQ_OTG),
1024 };
1025 
1026 struct platform_device s3c_device_usb_hsotg = {
1027     .name       = "s3c-hsotg",
1028     .id     = -1,
1029     .num_resources  = ARRAY_SIZE(s3c_usb_hsotg_resources),
1030     .resource   = s3c_usb_hsotg_resources,
1031     .dev        = {
1032         .dma_mask       = &samsung_device_dma_mask,
1033         .coherent_dma_mask  = DMA_BIT_MASK(32),
1034     },
1035 };
1036 
1037 void __init dwc2_hsotg_set_platdata(struct dwc2_hsotg_plat *pd)
1038 {
1039     struct dwc2_hsotg_plat *npd;
1040 
1041     npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_usb_hsotg);
1042 
1043     if (!npd->phy_init)
1044         npd->phy_init = s3c_usb_phy_init;
1045     if (!npd->phy_exit)
1046         npd->phy_exit = s3c_usb_phy_exit;
1047 }
1048 #endif /* CONFIG_S3C_DEV_USB_HSOTG */
1049 
1050 /* USB High Spped 2.0 Device (Gadget) */
1051 
1052 #ifdef CONFIG_PLAT_S3C24XX
1053 static struct resource s3c_hsudc_resource[] = {
1054     [0] = DEFINE_RES_MEM(S3C2416_PA_HSUDC, S3C2416_SZ_HSUDC),
1055     [1] = DEFINE_RES_IRQ(IRQ_USBD),
1056 };
1057 
1058 struct platform_device s3c_device_usb_hsudc = {
1059     .name       = "s3c-hsudc",
1060     .id     = -1,
1061     .num_resources  = ARRAY_SIZE(s3c_hsudc_resource),
1062     .resource   = s3c_hsudc_resource,
1063     .dev        = {
1064         .dma_mask       = &samsung_device_dma_mask,
1065         .coherent_dma_mask  = DMA_BIT_MASK(32),
1066     },
1067 };
1068 
1069 void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd)
1070 {
1071     s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usb_hsudc);
1072     pd->phy_init = s3c_hsudc_init_phy;
1073     pd->phy_uninit = s3c_hsudc_uninit_phy;
1074 }
1075 #endif /* CONFIG_PLAT_S3C24XX */
1076 
1077 /* WDT */
1078 
1079 #ifdef CONFIG_S3C_DEV_WDT
1080 static struct resource s3c_wdt_resource[] = {
1081     [0] = DEFINE_RES_MEM(S3C_PA_WDT, SZ_1K),
1082     [1] = DEFINE_RES_IRQ(IRQ_WDT),
1083 };
1084 
1085 struct platform_device s3c_device_wdt = {
1086     .name       = "s3c2410-wdt",
1087     .id     = -1,
1088     .num_resources  = ARRAY_SIZE(s3c_wdt_resource),
1089     .resource   = s3c_wdt_resource,
1090 };
1091 #endif /* CONFIG_S3C_DEV_WDT */
1092 
1093 #ifdef CONFIG_S3C64XX_DEV_SPI0
1094 static struct resource s3c64xx_spi0_resource[] = {
1095     [0] = DEFINE_RES_MEM(S3C_PA_SPI0, SZ_256),
1096     [1] = DEFINE_RES_IRQ(IRQ_SPI0),
1097 };
1098 
1099 struct platform_device s3c64xx_device_spi0 = {
1100     .name       = "s3c6410-spi",
1101     .id     = 0,
1102     .num_resources  = ARRAY_SIZE(s3c64xx_spi0_resource),
1103     .resource   = s3c64xx_spi0_resource,
1104     .dev = {
1105         .dma_mask       = &samsung_device_dma_mask,
1106         .coherent_dma_mask  = DMA_BIT_MASK(32),
1107     },
1108 };
1109 
1110 void __init s3c64xx_spi0_set_platdata(int src_clk_nr, int num_cs)
1111 {
1112     struct s3c64xx_spi_info pd;
1113 
1114     /* Reject invalid configuration */
1115     if (!num_cs || src_clk_nr < 0) {
1116         pr_err("%s: Invalid SPI configuration\n", __func__);
1117         return;
1118     }
1119 
1120     pd.num_cs = num_cs;
1121     pd.src_clk_nr = src_clk_nr;
1122     pd.cfg_gpio = s3c64xx_spi0_cfg_gpio;
1123 
1124     s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0);
1125 }
1126 #endif /* CONFIG_S3C64XX_DEV_SPI0 */