aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-samsung
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /arch/arm/plat-samsung
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'arch/arm/plat-samsung')
-rw-r--r--arch/arm/plat-samsung/dev-adc.c46
-rw-r--r--arch/arm/plat-samsung/dev-asocdma.c35
-rw-r--r--arch/arm/plat-samsung/dev-fb.c63
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc.c79
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc1.c79
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc2.c80
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc3.c83
-rw-r--r--arch/arm/plat-samsung/dev-hwmon.c32
-rw-r--r--arch/arm/plat-samsung/dev-i2c0.c70
-rw-r--r--arch/arm/plat-samsung/dev-i2c1.c61
-rw-r--r--arch/arm/plat-samsung/dev-i2c2.c62
-rw-r--r--arch/arm/plat-samsung/dev-i2c3.c60
-rw-r--r--arch/arm/plat-samsung/dev-i2c4.c60
-rw-r--r--arch/arm/plat-samsung/dev-i2c5.c60
-rw-r--r--arch/arm/plat-samsung/dev-i2c6.c60
-rw-r--r--arch/arm/plat-samsung/dev-i2c7.c60
-rw-r--r--arch/arm/plat-samsung/dev-ide.c44
-rw-r--r--arch/arm/plat-samsung/dev-keypad.c50
-rw-r--r--arch/arm/plat-samsung/dev-nand.c125
-rw-r--r--arch/arm/plat-samsung/dev-onenand.c43
-rw-r--r--arch/arm/plat-samsung/dev-pwm.c53
-rw-r--r--arch/arm/plat-samsung/dev-rtc.c43
-rw-r--r--arch/arm/plat-samsung/dev-ts.c50
-rw-r--r--arch/arm/plat-samsung/dev-usb-hsotg.c48
-rw-r--r--arch/arm/plat-samsung/dev-usb.c65
-rw-r--r--arch/arm/plat-samsung/dev-wdt.c40
-rw-r--r--arch/arm/plat-samsung/gpio-config.c431
-rw-r--r--arch/arm/plat-samsung/gpio.c167
-rw-r--r--arch/arm/plat-samsung/include/plat/ata.h36
-rw-r--r--arch/arm/plat-samsung/include/plat/audio.h59
-rw-r--r--arch/arm/plat-samsung/include/plat/hwmon.h51
-rw-r--r--arch/arm/plat-samsung/include/plat/iic.h76
-rw-r--r--arch/arm/plat-samsung/include/plat/nand.h67
-rw-r--r--arch/arm/plat-samsung/include/plat/pd.h30
-rw-r--r--arch/arm/plat-samsung/include/plat/pll6553x.h51
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-fb-v4.h159
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-fb.h386
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h379
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h98
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h32
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c64xx-spi.h75
-rw-r--r--arch/arm/plat-samsung/include/plat/ts.h25
-rw-r--r--arch/arm/plat-samsung/include/plat/udc-hs.h29
-rw-r--r--arch/arm/plat-samsung/include/plat/usb-control.h43
-rw-r--r--arch/arm/plat-samsung/irq-uart.c96
-rw-r--r--arch/arm/plat-samsung/pd.c95
-rw-r--r--arch/arm/plat-samsung/pwm.c413
-rw-r--r--arch/arm/plat-samsung/s3c-pl330.c1244
48 files changed, 5593 insertions, 0 deletions
diff --git a/arch/arm/plat-samsung/dev-adc.c b/arch/arm/plat-samsung/dev-adc.c
new file mode 100644
index 00000000000..9d903d4095e
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-adc.c
@@ -0,0 +1,46 @@
1/* linux/arch/arm/plat-samsung/dev-adc.c
2 *
3 * Copyright 2010 Maurus Cuelenaere
4 *
5 * S3C64xx series device definition for ADC device
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10*/
11
12#include <linux/kernel.h>
13#include <linux/string.h>
14#include <linux/platform_device.h>
15
16#include <mach/irqs.h>
17#include <mach/map.h>
18
19#include <plat/adc.h>
20#include <plat/devs.h>
21#include <plat/cpu.h>
22
23static struct resource s3c_adc_resource[] = {
24 [0] = {
25 .start = SAMSUNG_PA_ADC,
26 .end = SAMSUNG_PA_ADC + SZ_256 - 1,
27 .flags = IORESOURCE_MEM,
28 },
29 [1] = {
30 .start = IRQ_TC,
31 .end = IRQ_TC,
32 .flags = IORESOURCE_IRQ,
33 },
34 [2] = {
35 .start = IRQ_ADC,
36 .end = IRQ_ADC,
37 .flags = IORESOURCE_IRQ,
38 },
39};
40
41struct platform_device s3c_device_adc = {
42 .name = "samsung-adc",
43 .id = -1,
44 .num_resources = ARRAY_SIZE(s3c_adc_resource),
45 .resource = s3c_adc_resource,
46};
diff --git a/arch/arm/plat-samsung/dev-asocdma.c b/arch/arm/plat-samsung/dev-asocdma.c
new file mode 100644
index 00000000000..97e35d3c064
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-asocdma.c
@@ -0,0 +1,35 @@
1/* linux/arch/arm/plat-samsung/dev-asocdma.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 <plat/devs.h>
14
15static u64 audio_dmamask = DMA_BIT_MASK(32);
16
17struct platform_device samsung_asoc_dma = {
18 .name = "samsung-audio",
19 .id = -1,
20 .dev = {
21 .dma_mask = &audio_dmamask,
22 .coherent_dma_mask = DMA_BIT_MASK(32),
23 }
24};
25EXPORT_SYMBOL(samsung_asoc_dma);
26
27struct platform_device samsung_asoc_idma = {
28 .name = "samsung-idma",
29 .id = -1,
30 .dev = {
31 .dma_mask = &audio_dmamask,
32 .coherent_dma_mask = DMA_BIT_MASK(32),
33 }
34};
35EXPORT_SYMBOL(samsung_asoc_idma);
diff --git a/arch/arm/plat-samsung/dev-fb.c b/arch/arm/plat-samsung/dev-fb.c
new file mode 100644
index 00000000000..49a1362fd25
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-fb.c
@@ -0,0 +1,63 @@
1/* linux/arch/arm/plat-s3c/dev-fb.c
2 *
3 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C series device definition for framebuffer device
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17#include <linux/fb.h>
18#include <linux/gfp.h>
19
20#include <mach/irqs.h>
21#include <mach/map.h>
22
23#include <plat/fb.h>
24#include <plat/devs.h>
25#include <plat/cpu.h>
26
27static struct resource s3c_fb_resource[] = {
28 [0] = {
29 .start = S3C_PA_FB,
30 .end = S3C_PA_FB + SZ_16K - 1,
31 .flags = IORESOURCE_MEM,
32 },
33 [1] = {
34 .start = IRQ_LCD_VSYNC,
35 .end = IRQ_LCD_VSYNC,
36 .flags = IORESOURCE_IRQ,
37 },
38 [2] = {
39 .start = IRQ_LCD_FIFO,
40 .end = IRQ_LCD_FIFO,
41 .flags = IORESOURCE_IRQ,
42 },
43 [3] = {
44 .start = IRQ_LCD_SYSTEM,
45 .end = IRQ_LCD_SYSTEM,
46 .flags = IORESOURCE_IRQ,
47 },
48};
49
50struct platform_device s3c_device_fb = {
51 .name = "s3c-fb",
52 .id = -1,
53 .num_resources = ARRAY_SIZE(s3c_fb_resource),
54 .resource = s3c_fb_resource,
55 .dev.dma_mask = &s3c_device_fb.dev.coherent_dma_mask,
56 .dev.coherent_dma_mask = 0xffffffffUL,
57};
58
59void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
60{
61 s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
62 &s3c_device_fb);
63}
diff --git a/arch/arm/plat-samsung/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c
new file mode 100644
index 00000000000..db7a65c7f12
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-hsmmc.c
@@ -0,0 +1,79 @@
1/* linux/arch/arm/plat-s3c/dev-hsmmc.c
2 *
3 * Copyright (c) 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C series device definition for hsmmc devices
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/kernel.h>
15#include <linux/platform_device.h>
16#include <linux/mmc/host.h>
17
18#include <mach/map.h>
19#include <plat/sdhci.h>
20#include <plat/devs.h>
21#include <plat/cpu.h>
22
23#define S3C_SZ_HSMMC (0x1000)
24
25static struct resource s3c_hsmmc_resource[] = {
26 [0] = {
27 .start = S3C_PA_HSMMC0,
28 .end = S3C_PA_HSMMC0 + S3C_SZ_HSMMC - 1,
29 .flags = IORESOURCE_MEM,
30 },
31 [1] = {
32 .start = IRQ_HSMMC0,
33 .end = IRQ_HSMMC0,
34 .flags = IORESOURCE_IRQ,
35 }
36};
37
38static u64 s3c_device_hsmmc_dmamask = 0xffffffffUL;
39
40struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
41 .max_width = 4,
42 .host_caps = (MMC_CAP_4_BIT_DATA |
43 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
44 .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
45};
46
47struct platform_device s3c_device_hsmmc0 = {
48 .name = "s3c-sdhci",
49 .id = 0,
50 .num_resources = ARRAY_SIZE(s3c_hsmmc_resource),
51 .resource = s3c_hsmmc_resource,
52 .dev = {
53 .dma_mask = &s3c_device_hsmmc_dmamask,
54 .coherent_dma_mask = 0xffffffffUL,
55 .platform_data = &s3c_hsmmc0_def_platdata,
56 },
57};
58
59void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
60{
61 struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata;
62
63 set->cd_type = pd->cd_type;
64 set->ext_cd_init = pd->ext_cd_init;
65 set->ext_cd_cleanup = pd->ext_cd_cleanup;
66 set->ext_cd_gpio = pd->ext_cd_gpio;
67 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
68
69 if (pd->max_width)
70 set->max_width = pd->max_width;
71 if (pd->cfg_gpio)
72 set->cfg_gpio = pd->cfg_gpio;
73 if (pd->cfg_card)
74 set->cfg_card = pd->cfg_card;
75 if (pd->host_caps)
76 set->host_caps |= pd->host_caps;
77 if (pd->clk_type)
78 set->clk_type = pd->clk_type;
79}
diff --git a/arch/arm/plat-samsung/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c
new file mode 100644
index 00000000000..2497321f08d
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-hsmmc1.c
@@ -0,0 +1,79 @@
1/* linux/arch/arm/plat-s3c/dev-hsmmc1.c
2 *
3 * Copyright (c) 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C series device definition for hsmmc device 1
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/kernel.h>
15#include <linux/platform_device.h>
16#include <linux/mmc/host.h>
17
18#include <mach/map.h>
19#include <plat/sdhci.h>
20#include <plat/devs.h>
21#include <plat/cpu.h>
22
23#define S3C_SZ_HSMMC (0x1000)
24
25static struct resource s3c_hsmmc1_resource[] = {
26 [0] = {
27 .start = S3C_PA_HSMMC1,
28 .end = S3C_PA_HSMMC1 + S3C_SZ_HSMMC - 1,
29 .flags = IORESOURCE_MEM,
30 },
31 [1] = {
32 .start = IRQ_HSMMC1,
33 .end = IRQ_HSMMC1,
34 .flags = IORESOURCE_IRQ,
35 }
36};
37
38static u64 s3c_device_hsmmc1_dmamask = 0xffffffffUL;
39
40struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = {
41 .max_width = 4,
42 .host_caps = (MMC_CAP_4_BIT_DATA |
43 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
44 .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
45};
46
47struct platform_device s3c_device_hsmmc1 = {
48 .name = "s3c-sdhci",
49 .id = 1,
50 .num_resources = ARRAY_SIZE(s3c_hsmmc1_resource),
51 .resource = s3c_hsmmc1_resource,
52 .dev = {
53 .dma_mask = &s3c_device_hsmmc1_dmamask,
54 .coherent_dma_mask = 0xffffffffUL,
55 .platform_data = &s3c_hsmmc1_def_platdata,
56 },
57};
58
59void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
60{
61 struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata;
62
63 set->cd_type = pd->cd_type;
64 set->ext_cd_init = pd->ext_cd_init;
65 set->ext_cd_cleanup = pd->ext_cd_cleanup;
66 set->ext_cd_gpio = pd->ext_cd_gpio;
67 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
68
69 if (pd->max_width)
70 set->max_width = pd->max_width;
71 if (pd->cfg_gpio)
72 set->cfg_gpio = pd->cfg_gpio;
73 if (pd->cfg_card)
74 set->cfg_card = pd->cfg_card;
75 if (pd->host_caps)
76 set->host_caps |= pd->host_caps;
77 if (pd->clk_type)
78 set->clk_type = pd->clk_type;
79}
diff --git a/arch/arm/plat-samsung/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c
new file mode 100644
index 00000000000..f60aedba417
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-hsmmc2.c
@@ -0,0 +1,80 @@
1/* linux/arch/arm/plat-s3c/dev-hsmmc2.c
2 *
3 * Copyright (c) 2009 Samsung Electronics
4 * Copyright (c) 2009 Maurus Cuelenaere
5 *
6 * Based on arch/arm/plat-s3c/dev-hsmmc1.c
7 * original file Copyright (c) 2008 Simtec Electronics
8 *
9 * S3C series device definition for hsmmc device 2
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14*/
15
16#include <linux/kernel.h>
17#include <linux/platform_device.h>
18#include <linux/mmc/host.h>
19
20#include <mach/map.h>
21#include <plat/sdhci.h>
22#include <plat/devs.h>
23
24#define S3C_SZ_HSMMC (0x1000)
25
26static struct resource s3c_hsmmc2_resource[] = {
27 [0] = {
28 .start = S3C_PA_HSMMC2,
29 .end = S3C_PA_HSMMC2 + S3C_SZ_HSMMC - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_HSMMC2,
34 .end = IRQ_HSMMC2,
35 .flags = IORESOURCE_IRQ,
36 }
37};
38
39static u64 s3c_device_hsmmc2_dmamask = 0xffffffffUL;
40
41struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
42 .max_width = 4,
43 .host_caps = (MMC_CAP_4_BIT_DATA |
44 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
45 .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
46};
47
48struct platform_device s3c_device_hsmmc2 = {
49 .name = "s3c-sdhci",
50 .id = 2,
51 .num_resources = ARRAY_SIZE(s3c_hsmmc2_resource),
52 .resource = s3c_hsmmc2_resource,
53 .dev = {
54 .dma_mask = &s3c_device_hsmmc2_dmamask,
55 .coherent_dma_mask = 0xffffffffUL,
56 .platform_data = &s3c_hsmmc2_def_platdata,
57 },
58};
59
60void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
61{
62 struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata;
63
64 set->cd_type = pd->cd_type;
65 set->ext_cd_init = pd->ext_cd_init;
66 set->ext_cd_cleanup = pd->ext_cd_cleanup;
67 set->ext_cd_gpio = pd->ext_cd_gpio;
68 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
69
70 if (pd->max_width)
71 set->max_width = pd->max_width;
72 if (pd->cfg_gpio)
73 set->cfg_gpio = pd->cfg_gpio;
74 if (pd->cfg_card)
75 set->cfg_card = pd->cfg_card;
76 if (pd->host_caps)
77 set->host_caps |= pd->host_caps;
78 if (pd->clk_type)
79 set->clk_type = pd->clk_type;
80}
diff --git a/arch/arm/plat-samsung/dev-hsmmc3.c b/arch/arm/plat-samsung/dev-hsmmc3.c
new file mode 100644
index 00000000000..ede776f20e6
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-hsmmc3.c
@@ -0,0 +1,83 @@
1/* linux/arch/arm/plat-samsung/dev-hsmmc3.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Copyright (c) 2008 Simtec Electronics
7 * Ben Dooks <ben@simtec.co.uk>
8 * http://armlinux.simtec.co.uk/
9 *
10 * Based on arch/arm/plat-samsung/dev-hsmmc1.c
11 *
12 * Samsung device definition for hsmmc device 3
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17*/
18
19#include <linux/kernel.h>
20#include <linux/platform_device.h>
21#include <linux/mmc/host.h>
22
23#include <mach/map.h>
24#include <plat/sdhci.h>
25#include <plat/devs.h>
26
27#define S3C_SZ_HSMMC (0x1000)
28
29static struct resource s3c_hsmmc3_resource[] = {
30 [0] = {
31 .start = S3C_PA_HSMMC3,
32 .end = S3C_PA_HSMMC3 + S3C_SZ_HSMMC - 1,
33 .flags = IORESOURCE_MEM,
34 },
35 [1] = {
36 .start = IRQ_HSMMC3,
37 .end = IRQ_HSMMC3,
38 .flags = IORESOURCE_IRQ,
39 }
40};
41
42static u64 s3c_device_hsmmc3_dmamask = 0xffffffffUL;
43
44struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
45 .max_width = 4,
46 .host_caps = (MMC_CAP_4_BIT_DATA |
47 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
48 .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
49};
50
51struct platform_device s3c_device_hsmmc3 = {
52 .name = "s3c-sdhci",
53 .id = 3,
54 .num_resources = ARRAY_SIZE(s3c_hsmmc3_resource),
55 .resource = s3c_hsmmc3_resource,
56 .dev = {
57 .dma_mask = &s3c_device_hsmmc3_dmamask,
58 .coherent_dma_mask = 0xffffffffUL,
59 .platform_data = &s3c_hsmmc3_def_platdata,
60 },
61};
62
63void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
64{
65 struct s3c_sdhci_platdata *set = &s3c_hsmmc3_def_platdata;
66
67 set->cd_type = pd->cd_type;
68 set->ext_cd_init = pd->ext_cd_init;
69 set->ext_cd_cleanup = pd->ext_cd_cleanup;
70 set->ext_cd_gpio = pd->ext_cd_gpio;
71 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
72
73 if (pd->max_width)
74 set->max_width = pd->max_width;
75 if (pd->cfg_gpio)
76 set->cfg_gpio = pd->cfg_gpio;
77 if (pd->cfg_card)
78 set->cfg_card = pd->cfg_card;
79 if (pd->host_caps)
80 set->host_caps |= pd->host_caps;
81 if (pd->clk_type)
82 set->clk_type = pd->clk_type;
83}
diff --git a/arch/arm/plat-samsung/dev-hwmon.c b/arch/arm/plat-samsung/dev-hwmon.c
new file mode 100644
index 00000000000..c91a79ce8f3
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-hwmon.c
@@ -0,0 +1,32 @@
1/* linux/arch/arm/plat-samsung/dev-hwmon.c
2 *
3 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * Adapted for HWMON by Maurus Cuelenaere
8 *
9 * Samsung series device definition for HWMON
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14*/
15
16#include <linux/kernel.h>
17#include <linux/platform_device.h>
18
19#include <plat/devs.h>
20#include <plat/hwmon.h>
21
22struct platform_device s3c_device_hwmon = {
23 .name = "s3c-hwmon",
24 .id = -1,
25 .dev.parent = &s3c_device_adc.dev,
26};
27
28void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd)
29{
30 s3c_set_platdata(pd, sizeof(struct s3c_hwmon_pdata),
31 &s3c_device_hwmon);
32}
diff --git a/arch/arm/plat-samsung/dev-i2c0.c b/arch/arm/plat-samsung/dev-i2c0.c
new file mode 100644
index 00000000000..f8251f5098b
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c0.c
@@ -0,0 +1,70 @@
1/* linux/arch/arm/plat-s3c/dev-i2c0.c
2 *
3 * Copyright 2008-2009 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C series device definition for i2c device 0
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/gfp.h>
15#include <linux/kernel.h>
16#include <linux/string.h>
17#include <linux/platform_device.h>
18
19#include <mach/irqs.h>
20#include <mach/map.h>
21
22#include <plat/regs-iic.h>
23#include <plat/iic.h>
24#include <plat/devs.h>
25#include <plat/cpu.h>
26
27static struct resource s3c_i2c_resource[] = {
28 [0] = {
29 .start = S3C_PA_IIC,
30 .end = S3C_PA_IIC + SZ_4K - 1,
31 .flags = IORESOURCE_MEM,
32 },
33 [1] = {
34 .start = IRQ_IIC,
35 .end = IRQ_IIC,
36 .flags = IORESOURCE_IRQ,
37 },
38};
39
40struct platform_device s3c_device_i2c0 = {
41 .name = "s3c2410-i2c",
42#ifdef CONFIG_S3C_DEV_I2C1
43 .id = 0,
44#else
45 .id = -1,
46#endif
47 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
48 .resource = s3c_i2c_resource,
49};
50
51struct s3c2410_platform_i2c default_i2c_data __initdata = {
52 .flags = 0,
53 .slave_addr = 0x10,
54 .frequency = 100*1000,
55 .sda_delay = 100,
56};
57
58void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
59{
60 struct s3c2410_platform_i2c *npd;
61
62 if (!pd)
63 pd = &default_i2c_data;
64
65 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
66 &s3c_device_i2c0);
67
68 if (!npd->cfg_gpio)
69 npd->cfg_gpio = s3c_i2c0_cfg_gpio;
70}
diff --git a/arch/arm/plat-samsung/dev-i2c1.c b/arch/arm/plat-samsung/dev-i2c1.c
new file mode 100644
index 00000000000..3b7c7bec1cf
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c1.c
@@ -0,0 +1,61 @@
1/* linux/arch/arm/plat-s3c/dev-i2c1.c
2 *
3 * Copyright 2008-2009 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C series device definition for i2c device 1
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/gfp.h>
15#include <linux/kernel.h>
16#include <linux/string.h>
17#include <linux/platform_device.h>
18
19#include <mach/irqs.h>
20#include <mach/map.h>
21
22#include <plat/regs-iic.h>
23#include <plat/iic.h>
24#include <plat/devs.h>
25#include <plat/cpu.h>
26
27static struct resource s3c_i2c_resource[] = {
28 [0] = {
29 .start = S3C_PA_IIC1,
30 .end = S3C_PA_IIC1 + SZ_4K - 1,
31 .flags = IORESOURCE_MEM,
32 },
33 [1] = {
34 .start = IRQ_IIC1,
35 .end = IRQ_IIC1,
36 .flags = IORESOURCE_IRQ,
37 },
38};
39
40struct platform_device s3c_device_i2c1 = {
41 .name = "s3c2410-i2c",
42 .id = 1,
43 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
44 .resource = s3c_i2c_resource,
45};
46
47void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
48{
49 struct s3c2410_platform_i2c *npd;
50
51 if (!pd) {
52 pd = &default_i2c_data;
53 pd->bus_num = 1;
54 }
55
56 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
57 &s3c_device_i2c1);
58
59 if (!npd->cfg_gpio)
60 npd->cfg_gpio = s3c_i2c1_cfg_gpio;
61}
diff --git a/arch/arm/plat-samsung/dev-i2c2.c b/arch/arm/plat-samsung/dev-i2c2.c
new file mode 100644
index 00000000000..07e9fd0b1b8
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c2.c
@@ -0,0 +1,62 @@
1/* linux/arch/arm/plat-s3c/dev-i2c2.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S3C series device definition for i2c device 2
7 *
8 * Based on plat-samsung/dev-i2c0.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/gfp.h>
16#include <linux/kernel.h>
17#include <linux/string.h>
18#include <linux/platform_device.h>
19
20#include <mach/irqs.h>
21#include <mach/map.h>
22
23#include <plat/regs-iic.h>
24#include <plat/iic.h>
25#include <plat/devs.h>
26#include <plat/cpu.h>
27
28static struct resource s3c_i2c_resource[] = {
29 [0] = {
30 .start = S3C_PA_IIC2,
31 .end = S3C_PA_IIC2 + SZ_4K - 1,
32 .flags = IORESOURCE_MEM,
33 },
34 [1] = {
35 .start = IRQ_IIC2,
36 .end = IRQ_IIC2,
37 .flags = IORESOURCE_IRQ,
38 },
39};
40
41struct platform_device s3c_device_i2c2 = {
42 .name = "s3c2410-i2c",
43 .id = 2,
44 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
45 .resource = s3c_i2c_resource,
46};
47
48void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd)
49{
50 struct s3c2410_platform_i2c *npd;
51
52 if (!pd) {
53 pd = &default_i2c_data;
54 pd->bus_num = 2;
55 }
56
57 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
58 &s3c_device_i2c2);
59
60 if (!npd->cfg_gpio)
61 npd->cfg_gpio = s3c_i2c2_cfg_gpio;
62}
diff --git a/arch/arm/plat-samsung/dev-i2c3.c b/arch/arm/plat-samsung/dev-i2c3.c
new file mode 100644
index 00000000000..d48efa93c6e
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c3.c
@@ -0,0 +1,60 @@
1/* linux/arch/arm/plat-samsung/dev-i2c3.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P series device definition for i2c device 3
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/gfp.h>
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17
18#include <mach/irqs.h>
19#include <mach/map.h>
20
21#include <plat/regs-iic.h>
22#include <plat/iic.h>
23#include <plat/devs.h>
24#include <plat/cpu.h>
25
26static struct resource s3c_i2c_resource[] = {
27 [0] = {
28 .start = S3C_PA_IIC3,
29 .end = S3C_PA_IIC3 + SZ_4K - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_IIC3,
34 .end = IRQ_IIC3,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39struct platform_device s3c_device_i2c3 = {
40 .name = "s3c2440-i2c",
41 .id = 3,
42 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
43 .resource = s3c_i2c_resource,
44};
45
46void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd)
47{
48 struct s3c2410_platform_i2c *npd;
49
50 if (!pd) {
51 pd = &default_i2c_data;
52 pd->bus_num = 3;
53 }
54
55 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
56 &s3c_device_i2c3);
57
58 if (!npd->cfg_gpio)
59 npd->cfg_gpio = s3c_i2c3_cfg_gpio;
60}
diff --git a/arch/arm/plat-samsung/dev-i2c4.c b/arch/arm/plat-samsung/dev-i2c4.c
new file mode 100644
index 00000000000..07e26444efe
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c4.c
@@ -0,0 +1,60 @@
1/* linux/arch/arm/plat-samsung/dev-i2c4.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P series device definition for i2c device 3
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/gfp.h>
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17
18#include <mach/irqs.h>
19#include <mach/map.h>
20
21#include <plat/regs-iic.h>
22#include <plat/iic.h>
23#include <plat/devs.h>
24#include <plat/cpu.h>
25
26static struct resource s3c_i2c_resource[] = {
27 [0] = {
28 .start = S3C_PA_IIC4,
29 .end = S3C_PA_IIC4 + SZ_4K - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_IIC4,
34 .end = IRQ_IIC4,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39struct platform_device s3c_device_i2c4 = {
40 .name = "s3c2440-i2c",
41 .id = 4,
42 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
43 .resource = s3c_i2c_resource,
44};
45
46void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd)
47{
48 struct s3c2410_platform_i2c *npd;
49
50 if (!pd) {
51 pd = &default_i2c_data;
52 pd->bus_num = 4;
53 }
54
55 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
56 &s3c_device_i2c4);
57
58 if (!npd->cfg_gpio)
59 npd->cfg_gpio = s3c_i2c4_cfg_gpio;
60}
diff --git a/arch/arm/plat-samsung/dev-i2c5.c b/arch/arm/plat-samsung/dev-i2c5.c
new file mode 100644
index 00000000000..f4965578456
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c5.c
@@ -0,0 +1,60 @@
1/* linux/arch/arm/plat-samsung/dev-i2c3.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P series device definition for i2c device 3
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/gfp.h>
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17
18#include <mach/irqs.h>
19#include <mach/map.h>
20
21#include <plat/regs-iic.h>
22#include <plat/iic.h>
23#include <plat/devs.h>
24#include <plat/cpu.h>
25
26static struct resource s3c_i2c_resource[] = {
27 [0] = {
28 .start = S3C_PA_IIC5,
29 .end = S3C_PA_IIC5 + SZ_4K - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_IIC5,
34 .end = IRQ_IIC5,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39struct platform_device s3c_device_i2c5 = {
40 .name = "s3c2440-i2c",
41 .id = 5,
42 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
43 .resource = s3c_i2c_resource,
44};
45
46void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd)
47{
48 struct s3c2410_platform_i2c *npd;
49
50 if (!pd) {
51 pd = &default_i2c_data;
52 pd->bus_num = 5;
53 }
54
55 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
56 &s3c_device_i2c5);
57
58 if (!npd->cfg_gpio)
59 npd->cfg_gpio = s3c_i2c5_cfg_gpio;
60}
diff --git a/arch/arm/plat-samsung/dev-i2c6.c b/arch/arm/plat-samsung/dev-i2c6.c
new file mode 100644
index 00000000000..141d799944e
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c6.c
@@ -0,0 +1,60 @@
1/* linux/arch/arm/plat-samsung/dev-i2c6.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P series device definition for i2c device 6
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/gfp.h>
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17
18#include <mach/irqs.h>
19#include <mach/map.h>
20
21#include <plat/regs-iic.h>
22#include <plat/iic.h>
23#include <plat/devs.h>
24#include <plat/cpu.h>
25
26static struct resource s3c_i2c_resource[] = {
27 [0] = {
28 .start = S3C_PA_IIC6,
29 .end = S3C_PA_IIC6 + SZ_4K - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_IIC6,
34 .end = IRQ_IIC6,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39struct platform_device s3c_device_i2c6 = {
40 .name = "s3c2440-i2c",
41 .id = 6,
42 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
43 .resource = s3c_i2c_resource,
44};
45
46void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd)
47{
48 struct s3c2410_platform_i2c *npd;
49
50 if (!pd) {
51 pd = &default_i2c_data;
52 pd->bus_num = 6;
53 }
54
55 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
56 &s3c_device_i2c6);
57
58 if (!npd->cfg_gpio)
59 npd->cfg_gpio = s3c_i2c6_cfg_gpio;
60}
diff --git a/arch/arm/plat-samsung/dev-i2c7.c b/arch/arm/plat-samsung/dev-i2c7.c
new file mode 100644
index 00000000000..9dddcd1665b
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c7.c
@@ -0,0 +1,60 @@
1/* linux/arch/arm/plat-samsung/dev-i2c7.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P series device definition for i2c device 7
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/gfp.h>
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17
18#include <mach/irqs.h>
19#include <mach/map.h>
20
21#include <plat/regs-iic.h>
22#include <plat/iic.h>
23#include <plat/devs.h>
24#include <plat/cpu.h>
25
26static struct resource s3c_i2c_resource[] = {
27 [0] = {
28 .start = S3C_PA_IIC7,
29 .end = S3C_PA_IIC7 + SZ_4K - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_IIC7,
34 .end = IRQ_IIC7,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39struct platform_device s3c_device_i2c7 = {
40 .name = "s3c2440-i2c",
41 .id = 7,
42 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
43 .resource = s3c_i2c_resource,
44};
45
46void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd)
47{
48 struct s3c2410_platform_i2c *npd;
49
50 if (!pd) {
51 pd = &default_i2c_data;
52 pd->bus_num = 7;
53 }
54
55 npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
56 &s3c_device_i2c7);
57
58 if (!npd->cfg_gpio)
59 npd->cfg_gpio = s3c_i2c7_cfg_gpio;
60}
diff --git a/arch/arm/plat-samsung/dev-ide.c b/arch/arm/plat-samsung/dev-ide.c
new file mode 100644
index 00000000000..b497982795a
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-ide.c
@@ -0,0 +1,44 @@
1/* linux/arch/arm/plat-samsung/dev-ide.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung CF-ATA device definition.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/interrupt.h>
15#include <linux/platform_device.h>
16
17#include <mach/map.h>
18#include <plat/ata.h>
19#include <plat/devs.h>
20
21static struct resource s3c_cfcon_resource[] = {
22 [0] = {
23 .start = SAMSUNG_PA_CFCON,
24 .end = SAMSUNG_PA_CFCON + SZ_16K - 1,
25 .flags = IORESOURCE_MEM,
26 },
27 [1] = {
28 .start = IRQ_CFCON,
29 .end = IRQ_CFCON,
30 .flags = IORESOURCE_IRQ,
31 },
32};
33
34struct platform_device s3c_device_cfcon = {
35 .id = 0,
36 .num_resources = ARRAY_SIZE(s3c_cfcon_resource),
37 .resource = s3c_cfcon_resource,
38};
39
40void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata)
41{
42 s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata),
43 &s3c_device_cfcon);
44}
diff --git a/arch/arm/plat-samsung/dev-keypad.c b/arch/arm/plat-samsung/dev-keypad.c
new file mode 100644
index 00000000000..677c2d731b6
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-keypad.c
@@ -0,0 +1,50 @@
1/*
2 * linux/arch/arm/plat-samsung/dev-keypad.c
3 *
4 * Copyright (C) 2010 Samsung Electronics Co.Ltd
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#include <linux/platform_device.h>
15#include <mach/irqs.h>
16#include <mach/map.h>
17#include <plat/cpu.h>
18#include <plat/devs.h>
19#include <plat/keypad.h>
20
21static struct resource samsung_keypad_resources[] = {
22 [0] = {
23 .start = SAMSUNG_PA_KEYPAD,
24 .end = SAMSUNG_PA_KEYPAD + 0x20 - 1,
25 .flags = IORESOURCE_MEM,
26 },
27 [1] = {
28 .start = IRQ_KEYPAD,
29 .end = IRQ_KEYPAD,
30 .flags = IORESOURCE_IRQ,
31 },
32};
33
34struct platform_device samsung_device_keypad = {
35 .name = "samsung-keypad",
36 .id = -1,
37 .num_resources = ARRAY_SIZE(samsung_keypad_resources),
38 .resource = samsung_keypad_resources,
39};
40
41void __init samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd)
42{
43 struct samsung_keypad_platdata *npd;
44
45 npd = s3c_set_platdata(pd, sizeof(struct samsung_keypad_platdata),
46 &samsung_device_keypad);
47
48 if (!npd->cfg_gpio)
49 npd->cfg_gpio = samsung_keypad_cfg_gpio;
50}
diff --git a/arch/arm/plat-samsung/dev-nand.c b/arch/arm/plat-samsung/dev-nand.c
new file mode 100644
index 00000000000..b8e30ec6ac2
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-nand.c
@@ -0,0 +1,125 @@
1/*
2 * S3C series device definition for nand device
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7*/
8
9#include <linux/gfp.h>
10#include <linux/kernel.h>
11#include <linux/platform_device.h>
12
13#include <linux/mtd/mtd.h>
14#include <linux/mtd/partitions.h>
15
16#include <mach/map.h>
17#include <plat/devs.h>
18#include <plat/nand.h>
19
20static struct resource s3c_nand_resource[] = {
21 [0] = {
22 .start = S3C_PA_NAND,
23 .end = S3C_PA_NAND + SZ_1M,
24 .flags = IORESOURCE_MEM,
25 }
26};
27
28struct platform_device s3c_device_nand = {
29 .name = "s3c2410-nand",
30 .id = -1,
31 .num_resources = ARRAY_SIZE(s3c_nand_resource),
32 .resource = s3c_nand_resource,
33};
34
35EXPORT_SYMBOL(s3c_device_nand);
36
37/**
38 * s3c_nand_copy_set() - copy nand set data
39 * @set: The new structure, directly copied from the old.
40 *
41 * Copy all the fields from the NAND set field from what is probably __initdata
42 * to new kernel memory. The code returns 0 if the copy happened correctly or
43 * an error code for the calling function to display.
44 *
45 * Note, we currently do not try and look to see if we've already copied the
46 * data in a previous set.
47 */
48static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set)
49{
50 void *ptr;
51 int size;
52
53 size = sizeof(struct mtd_partition) * set->nr_partitions;
54 if (size) {
55 ptr = kmemdup(set->partitions, size, GFP_KERNEL);
56 set->partitions = ptr;
57
58 if (!ptr)
59 return -ENOMEM;
60 }
61
62 if (set->nr_map && set->nr_chips) {
63 size = sizeof(int) * set->nr_chips;
64 ptr = kmemdup(set->nr_map, size, GFP_KERNEL);
65 set->nr_map = ptr;
66
67 if (!ptr)
68 return -ENOMEM;
69 }
70
71 if (set->ecc_layout) {
72 ptr = kmemdup(set->ecc_layout,
73 sizeof(struct nand_ecclayout), GFP_KERNEL);
74 set->ecc_layout = ptr;
75
76 if (!ptr)
77 return -ENOMEM;
78 }
79
80 return 0;
81}
82
83void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
84{
85 struct s3c2410_platform_nand *npd;
86 int size;
87 int ret;
88
89 /* note, if we get a failure in allocation, we simply drop out of the
90 * function. If there is so little memory available at initialisation
91 * time then there is little chance the system is going to run.
92 */
93
94 npd = s3c_set_platdata(nand, sizeof(struct s3c2410_platform_nand),
95 &s3c_device_nand);
96 if (!npd)
97 return;
98
99 /* now see if we need to copy any of the nand set data */
100
101 size = sizeof(struct s3c2410_nand_set) * npd->nr_sets;
102 if (size) {
103 struct s3c2410_nand_set *from = npd->sets;
104 struct s3c2410_nand_set *to;
105 int i;
106
107 to = kmemdup(from, size, GFP_KERNEL);
108 npd->sets = to; /* set, even if we failed */
109
110 if (!to) {
111 printk(KERN_ERR "%s: no memory for sets\n", __func__);
112 return;
113 }
114
115 for (i = 0; i < npd->nr_sets; i++) {
116 ret = s3c_nand_copy_set(to);
117 if (ret) {
118 printk(KERN_ERR "%s: failed to copy set %d\n",
119 __func__, i);
120 return;
121 }
122 to++;
123 }
124 }
125}
diff --git a/arch/arm/plat-samsung/dev-onenand.c b/arch/arm/plat-samsung/dev-onenand.c
new file mode 100644
index 00000000000..f54ae71f0cd
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-onenand.c
@@ -0,0 +1,43 @@
1/*
2 * linux/arch/arm/plat-samsung/dev-onenand.c
3 *
4 * Copyright (c) 2008-2010 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com>
6 *
7 * S3C64XX/S5PC100 series device definition for OneNAND devices
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/platform_device.h>
16
17#include <mach/irqs.h>
18#include <mach/map.h>
19
20static struct resource s3c_onenand_resources[] = {
21 [0] = {
22 .start = S3C_PA_ONENAND,
23 .end = S3C_PA_ONENAND + 0x400 - 1,
24 .flags = IORESOURCE_MEM,
25 },
26 [1] = {
27 .start = S3C_PA_ONENAND_BUF,
28 .end = S3C_PA_ONENAND_BUF + S3C_SZ_ONENAND_BUF - 1,
29 .flags = IORESOURCE_MEM,
30 },
31 [2] = {
32 .start = IRQ_ONENAND,
33 .end = IRQ_ONENAND,
34 .flags = IORESOURCE_IRQ,
35 },
36};
37
38struct platform_device s3c_device_onenand = {
39 .name = "samsung-onenand",
40 .id = 0,
41 .num_resources = ARRAY_SIZE(s3c_onenand_resources),
42 .resource = s3c_onenand_resources,
43};
diff --git a/arch/arm/plat-samsung/dev-pwm.c b/arch/arm/plat-samsung/dev-pwm.c
new file mode 100644
index 00000000000..dab47b0e190
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-pwm.c
@@ -0,0 +1,53 @@
1/* linux/arch/arm/plat-samsung/dev-pwm.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Copyright (c) 2007 Ben Dooks
7 * Copyright (c) 2008 Simtec Electronics
8 * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
9 *
10 * S3C series device definition for the PWM timer
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/kernel.h>
18#include <linux/platform_device.h>
19
20#include <mach/irqs.h>
21
22#include <plat/devs.h>
23
24#define TIMER_RESOURCE_SIZE (1)
25
26#define TIMER_RESOURCE(_tmr, _irq) \
27 (struct resource [TIMER_RESOURCE_SIZE]) { \
28 [0] = { \
29 .start = _irq, \
30 .end = _irq, \
31 .flags = IORESOURCE_IRQ \
32 } \
33 }
34
35#define DEFINE_S3C_TIMER(_tmr_no, _irq) \
36 .name = "s3c24xx-pwm", \
37 .id = _tmr_no, \
38 .num_resources = TIMER_RESOURCE_SIZE, \
39 .resource = TIMER_RESOURCE(_tmr_no, _irq), \
40
41/*
42 * since we already have an static mapping for the timer,
43 * we do not bother setting any IO resource for the base.
44 */
45
46struct platform_device s3c_device_timer[] = {
47 [0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) },
48 [1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },
49 [2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) },
50 [3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
51 [4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
52};
53EXPORT_SYMBOL(s3c_device_timer);
diff --git a/arch/arm/plat-samsung/dev-rtc.c b/arch/arm/plat-samsung/dev-rtc.c
new file mode 100644
index 00000000000..bf4e2267333
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-rtc.c
@@ -0,0 +1,43 @@
1/* linux/arch/arm/plat-samsung/dev-rtc.c
2 *
3 * Copyright 2009 by Maurus Cuelenaere <mcuelenaere@gmail.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 version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#include <linux/kernel.h>
11#include <linux/string.h>
12#include <linux/platform_device.h>
13
14#include <mach/irqs.h>
15#include <mach/map.h>
16
17#include <plat/devs.h>
18
19static struct resource s3c_rtc_resource[] = {
20 [0] = {
21 .start = S3C_PA_RTC,
22 .end = S3C_PA_RTC + 0xff,
23 .flags = IORESOURCE_MEM,
24 },
25 [1] = {
26 .start = IRQ_RTC_ALARM,
27 .end = IRQ_RTC_ALARM,
28 .flags = IORESOURCE_IRQ,
29 },
30 [2] = {
31 .start = IRQ_RTC_TIC,
32 .end = IRQ_RTC_TIC,
33 .flags = IORESOURCE_IRQ
34 }
35};
36
37struct platform_device s3c_device_rtc = {
38 .name = "s3c64xx-rtc",
39 .id = -1,
40 .num_resources = ARRAY_SIZE(s3c_rtc_resource),
41 .resource = s3c_rtc_resource,
42};
43EXPORT_SYMBOL(s3c_device_rtc);
diff --git a/arch/arm/plat-samsung/dev-ts.c b/arch/arm/plat-samsung/dev-ts.c
new file mode 100644
index 00000000000..82543f0248a
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-ts.c
@@ -0,0 +1,50 @@
1/* linux/arch/arm/mach-s3c64xx/dev-ts.c
2 *
3 * Copyright (c) 2008 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
6 *
7 * Adapted by Maurus Cuelenaere for s3c64xx
8 *
9 * S3C64XX series device definition for touchscreen device
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14*/
15
16#include <linux/kernel.h>
17#include <linux/string.h>
18#include <linux/platform_device.h>
19
20#include <mach/irqs.h>
21#include <mach/map.h>
22
23#include <plat/devs.h>
24#include <plat/ts.h>
25
26static struct resource s3c_ts_resource[] = {
27 [0] = {
28 .start = SAMSUNG_PA_ADC,
29 .end = SAMSUNG_PA_ADC + SZ_256 - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_TC,
34 .end = IRQ_TC,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39struct platform_device s3c_device_ts = {
40 .name = "s3c64xx-ts",
41 .id = -1,
42 .num_resources = ARRAY_SIZE(s3c_ts_resource),
43 .resource = s3c_ts_resource,
44};
45
46void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd)
47{
48 s3c_set_platdata(pd, sizeof(struct s3c2410_ts_mach_info),
49 &s3c_device_ts);
50}
diff --git a/arch/arm/plat-samsung/dev-usb-hsotg.c b/arch/arm/plat-samsung/dev-usb-hsotg.c
new file mode 100644
index 00000000000..33a844ab691
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-usb-hsotg.c
@@ -0,0 +1,48 @@
1/* linux/arch/arm/plat-s3c/dev-usb-hsotg.c
2 *
3 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C series device definition for USB high-speed UDC/OtG block
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17#include <linux/dma-mapping.h>
18
19#include <mach/irqs.h>
20#include <mach/map.h>
21
22#include <plat/devs.h>
23
24static struct resource s3c_usb_hsotg_resources[] = {
25 [0] = {
26 .start = S3C_PA_USB_HSOTG,
27 .end = S3C_PA_USB_HSOTG + 0x10000 - 1,
28 .flags = IORESOURCE_MEM,
29 },
30 [1] = {
31 .start = IRQ_OTG,
32 .end = IRQ_OTG,
33 .flags = IORESOURCE_IRQ,
34 },
35};
36
37static u64 s3c_hsotg_dmamask = DMA_BIT_MASK(32);
38
39struct platform_device s3c_device_usb_hsotg = {
40 .name = "s3c-hsotg",
41 .id = -1,
42 .num_resources = ARRAY_SIZE(s3c_usb_hsotg_resources),
43 .resource = s3c_usb_hsotg_resources,
44 .dev = {
45 .dma_mask = &s3c_hsotg_dmamask,
46 .coherent_dma_mask = DMA_BIT_MASK(32),
47 },
48};
diff --git a/arch/arm/plat-samsung/dev-usb.c b/arch/arm/plat-samsung/dev-usb.c
new file mode 100644
index 00000000000..33fbaa96770
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-usb.c
@@ -0,0 +1,65 @@
1/* linux/arch/arm/plat-s3c/dev-usb.c
2 *
3 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C series device definition for USB host
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/gfp.h>
15#include <linux/kernel.h>
16#include <linux/string.h>
17#include <linux/platform_device.h>
18
19#include <mach/irqs.h>
20#include <mach/map.h>
21
22#include <plat/devs.h>
23#include <plat/usb-control.h>
24
25static struct resource s3c_usb_resource[] = {
26 [0] = {
27 .start = S3C_PA_USBHOST,
28 .end = S3C_PA_USBHOST + 0x100 - 1,
29 .flags = IORESOURCE_MEM,
30 },
31 [1] = {
32 .start = IRQ_USBH,
33 .end = IRQ_USBH,
34 .flags = IORESOURCE_IRQ,
35 }
36};
37
38static u64 s3c_device_usb_dmamask = 0xffffffffUL;
39
40struct platform_device s3c_device_ohci = {
41 .name = "s3c2410-ohci",
42 .id = -1,
43 .num_resources = ARRAY_SIZE(s3c_usb_resource),
44 .resource = s3c_usb_resource,
45 .dev = {
46 .dma_mask = &s3c_device_usb_dmamask,
47 .coherent_dma_mask = 0xffffffffUL
48 }
49};
50
51EXPORT_SYMBOL(s3c_device_ohci);
52
53/**
54 * s3c_ohci_set_platdata - initialise OHCI device platform data
55 * @info: The platform data.
56 *
57 * This call copies the @info passed in and sets the device .platform_data
58 * field to that copy. The @info is copied so that the original can be marked
59 * __initdata.
60 */
61void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info)
62{
63 s3c_set_platdata(info, sizeof(struct s3c2410_hcd_info),
64 &s3c_device_ohci);
65}
diff --git a/arch/arm/plat-samsung/dev-wdt.c b/arch/arm/plat-samsung/dev-wdt.c
new file mode 100644
index 00000000000..019b5b8cf14
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-wdt.c
@@ -0,0 +1,40 @@
1/* linux/arch/arm/plat-samsung/dev-wdt.c
2 *
3 * Copyright (c) 2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C series device definition for the watchdog timer
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/platform_device.h>
15
16#include <mach/irqs.h>
17#include <mach/map.h>
18
19#include <plat/devs.h>
20
21static struct resource s3c_wdt_resource[] = {
22 [0] = {
23 .start = S3C_PA_WDT,
24 .end = S3C_PA_WDT + SZ_1K,
25 .flags = IORESOURCE_MEM,
26 },
27 [1] = {
28 .start = IRQ_WDT,
29 .end = IRQ_WDT,
30 .flags = IORESOURCE_IRQ,
31 }
32};
33
34struct platform_device s3c_device_wdt = {
35 .name = "s3c2410-wdt",
36 .id = -1,
37 .num_resources = ARRAY_SIZE(s3c_wdt_resource),
38 .resource = s3c_wdt_resource,
39};
40EXPORT_SYMBOL(s3c_device_wdt);
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
new file mode 100644
index 00000000000..1c0b0401594
--- /dev/null
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -0,0 +1,431 @@
1/* linux/arch/arm/plat-s3c/gpio-config.c
2 *
3 * Copyright 2008 Openmoko, Inc.
4 * Copyright 2008-2010 Simtec Electronics
5 * Ben Dooks <ben@simtec.co.uk>
6 * http://armlinux.simtec.co.uk/
7 *
8 * S3C series GPIO configuration core
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/gpio.h>
18#include <linux/io.h>
19
20#include <plat/gpio-core.h>
21#include <plat/gpio-cfg.h>
22#include <plat/gpio-cfg-helpers.h>
23
24int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
25{
26 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
27 unsigned long flags;
28 int offset;
29 int ret;
30
31 if (!chip)
32 return -EINVAL;
33
34 offset = pin - chip->chip.base;
35
36 s3c_gpio_lock(chip, flags);
37 ret = s3c_gpio_do_setcfg(chip, offset, config);
38 s3c_gpio_unlock(chip, flags);
39
40 return ret;
41}
42EXPORT_SYMBOL(s3c_gpio_cfgpin);
43
44int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
45 unsigned int cfg)
46{
47 int ret;
48
49 for (; nr > 0; nr--, start++) {
50 ret = s3c_gpio_cfgpin(start, cfg);
51 if (ret != 0)
52 return ret;
53 }
54
55 return 0;
56}
57EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
58
59int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
60 unsigned int cfg, s3c_gpio_pull_t pull)
61{
62 int ret;
63
64 for (; nr > 0; nr--, start++) {
65 s3c_gpio_setpull(start, pull);
66 ret = s3c_gpio_cfgpin(start, cfg);
67 if (ret != 0)
68 return ret;
69 }
70
71 return 0;
72}
73EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
74
75unsigned s3c_gpio_getcfg(unsigned int pin)
76{
77 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
78 unsigned long flags;
79 unsigned ret = 0;
80 int offset;
81
82 if (chip) {
83 offset = pin - chip->chip.base;
84
85 s3c_gpio_lock(chip, flags);
86 ret = s3c_gpio_do_getcfg(chip, offset);
87 s3c_gpio_unlock(chip, flags);
88 }
89
90 return ret;
91}
92EXPORT_SYMBOL(s3c_gpio_getcfg);
93
94
95int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
96{
97 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
98 unsigned long flags;
99 int offset, ret;
100
101 if (!chip)
102 return -EINVAL;
103
104 offset = pin - chip->chip.base;
105
106 s3c_gpio_lock(chip, flags);
107 ret = s3c_gpio_do_setpull(chip, offset, pull);
108 s3c_gpio_unlock(chip, flags);
109
110 return ret;
111}
112EXPORT_SYMBOL(s3c_gpio_setpull);
113
114s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
115{
116 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
117 unsigned long flags;
118 int offset;
119 u32 pup = 0;
120
121 if (chip) {
122 offset = pin - chip->chip.base;
123
124 s3c_gpio_lock(chip, flags);
125 pup = s3c_gpio_do_getpull(chip, offset);
126 s3c_gpio_unlock(chip, flags);
127 }
128
129 return (__force s3c_gpio_pull_t)pup;
130}
131EXPORT_SYMBOL(s3c_gpio_getpull);
132
133#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
134int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
135 unsigned int off, unsigned int cfg)
136{
137 void __iomem *reg = chip->base;
138 unsigned int shift = off;
139 u32 con;
140
141 if (s3c_gpio_is_cfg_special(cfg)) {
142 cfg &= 0xf;
143
144 /* Map output to 0, and SFN2 to 1 */
145 cfg -= 1;
146 if (cfg > 1)
147 return -EINVAL;
148
149 cfg <<= shift;
150 }
151
152 con = __raw_readl(reg);
153 con &= ~(0x1 << shift);
154 con |= cfg;
155 __raw_writel(con, reg);
156
157 return 0;
158}
159
160unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
161 unsigned int off)
162{
163 u32 con;
164
165 con = __raw_readl(chip->base);
166 con >>= off;
167 con &= 1;
168 con++;
169
170 return S3C_GPIO_SFN(con);
171}
172
173int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
174 unsigned int off, unsigned int cfg)
175{
176 void __iomem *reg = chip->base;
177 unsigned int shift = off * 2;
178 u32 con;
179
180 if (s3c_gpio_is_cfg_special(cfg)) {
181 cfg &= 0xf;
182 if (cfg > 3)
183 return -EINVAL;
184
185 cfg <<= shift;
186 }
187
188 con = __raw_readl(reg);
189 con &= ~(0x3 << shift);
190 con |= cfg;
191 __raw_writel(con, reg);
192
193 return 0;
194}
195
196unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
197 unsigned int off)
198{
199 u32 con;
200
201 con = __raw_readl(chip->base);
202 con >>= off * 2;
203 con &= 3;
204
205 /* this conversion works for IN and OUT as well as special mode */
206 return S3C_GPIO_SPECIAL(con);
207}
208#endif
209
210#ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
211int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
212 unsigned int off, unsigned int cfg)
213{
214 void __iomem *reg = chip->base;
215 unsigned int shift = (off & 7) * 4;
216 u32 con;
217
218 if (off < 8 && chip->chip.ngpio > 8)
219 reg -= 4;
220
221 if (s3c_gpio_is_cfg_special(cfg)) {
222 cfg &= 0xf;
223 cfg <<= shift;
224 }
225
226 con = __raw_readl(reg);
227 con &= ~(0xf << shift);
228 con |= cfg;
229 __raw_writel(con, reg);
230
231 return 0;
232}
233
234unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
235 unsigned int off)
236{
237 void __iomem *reg = chip->base;
238 unsigned int shift = (off & 7) * 4;
239 u32 con;
240
241 if (off < 8 && chip->chip.ngpio > 8)
242 reg -= 4;
243
244 con = __raw_readl(reg);
245 con >>= shift;
246 con &= 0xf;
247
248 /* this conversion works for IN and OUT as well as special mode */
249 return S3C_GPIO_SPECIAL(con);
250}
251
252#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */
253
254#ifdef CONFIG_S3C_GPIO_PULL_UPDOWN
255int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
256 unsigned int off, s3c_gpio_pull_t pull)
257{
258 void __iomem *reg = chip->base + 0x08;
259 int shift = off * 2;
260 u32 pup;
261
262 pup = __raw_readl(reg);
263 pup &= ~(3 << shift);
264 pup |= pull << shift;
265 __raw_writel(pup, reg);
266
267 return 0;
268}
269
270s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
271 unsigned int off)
272{
273 void __iomem *reg = chip->base + 0x08;
274 int shift = off * 2;
275 u32 pup = __raw_readl(reg);
276
277 pup >>= shift;
278 pup &= 0x3;
279 return (__force s3c_gpio_pull_t)pup;
280}
281
282#ifdef CONFIG_S3C_GPIO_PULL_S3C2443
283int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip,
284 unsigned int off, s3c_gpio_pull_t pull)
285{
286 switch (pull) {
287 case S3C_GPIO_PULL_NONE:
288 pull = 0x01;
289 break;
290 case S3C_GPIO_PULL_UP:
291 pull = 0x00;
292 break;
293 case S3C_GPIO_PULL_DOWN:
294 pull = 0x02;
295 break;
296 }
297 return s3c_gpio_setpull_updown(chip, off, pull);
298}
299
300s3c_gpio_pull_t s3c_gpio_getpull_s3c2443(struct s3c_gpio_chip *chip,
301 unsigned int off)
302{
303 s3c_gpio_pull_t pull;
304
305 pull = s3c_gpio_getpull_updown(chip, off);
306
307 switch (pull) {
308 case 0x00:
309 pull = S3C_GPIO_PULL_UP;
310 break;
311 case 0x01:
312 case 0x03:
313 pull = S3C_GPIO_PULL_NONE;
314 break;
315 case 0x02:
316 pull = S3C_GPIO_PULL_DOWN;
317 break;
318 }
319
320 return pull;
321}
322#endif
323#endif
324
325#if defined(CONFIG_S3C_GPIO_PULL_UP) || defined(CONFIG_S3C_GPIO_PULL_DOWN)
326static int s3c_gpio_setpull_1(struct s3c_gpio_chip *chip,
327 unsigned int off, s3c_gpio_pull_t pull,
328 s3c_gpio_pull_t updown)
329{
330 void __iomem *reg = chip->base + 0x08;
331 u32 pup = __raw_readl(reg);
332
333 if (pull == updown)
334 pup &= ~(1 << off);
335 else if (pull == S3C_GPIO_PULL_NONE)
336 pup |= (1 << off);
337 else
338 return -EINVAL;
339
340 __raw_writel(pup, reg);
341 return 0;
342}
343
344static s3c_gpio_pull_t s3c_gpio_getpull_1(struct s3c_gpio_chip *chip,
345 unsigned int off, s3c_gpio_pull_t updown)
346{
347 void __iomem *reg = chip->base + 0x08;
348 u32 pup = __raw_readl(reg);
349
350 pup &= (1 << off);
351 return pup ? S3C_GPIO_PULL_NONE : updown;
352}
353#endif /* CONFIG_S3C_GPIO_PULL_UP || CONFIG_S3C_GPIO_PULL_DOWN */
354
355#ifdef CONFIG_S3C_GPIO_PULL_UP
356s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
357 unsigned int off)
358{
359 return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP);
360}
361
362int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
363 unsigned int off, s3c_gpio_pull_t pull)
364{
365 return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP);
366}
367#endif /* CONFIG_S3C_GPIO_PULL_UP */
368
369#ifdef CONFIG_S3C_GPIO_PULL_DOWN
370s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip,
371 unsigned int off)
372{
373 return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN);
374}
375
376int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip,
377 unsigned int off, s3c_gpio_pull_t pull)
378{
379 return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
380}
381#endif /* CONFIG_S3C_GPIO_PULL_DOWN */
382
383#ifdef CONFIG_S5P_GPIO_DRVSTR
384s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
385{
386 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
387 unsigned int off;
388 void __iomem *reg;
389 int shift;
390 u32 drvstr;
391
392 if (!chip)
393 return -EINVAL;
394
395 off = pin - chip->chip.base;
396 shift = off * 2;
397 reg = chip->base + 0x0C;
398
399 drvstr = __raw_readl(reg);
400 drvstr = drvstr >> shift;
401 drvstr &= 0x3;
402
403 return (__force s5p_gpio_drvstr_t)drvstr;
404}
405EXPORT_SYMBOL(s5p_gpio_get_drvstr);
406
407int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr)
408{
409 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
410 unsigned int off;
411 void __iomem *reg;
412 int shift;
413 u32 tmp;
414
415 if (!chip)
416 return -EINVAL;
417
418 off = pin - chip->chip.base;
419 shift = off * 2;
420 reg = chip->base + 0x0C;
421
422 tmp = __raw_readl(reg);
423 tmp &= ~(0x3 << shift);
424 tmp |= drvstr << shift;
425
426 __raw_writel(tmp, reg);
427
428 return 0;
429}
430EXPORT_SYMBOL(s5p_gpio_set_drvstr);
431#endif /* CONFIG_S5P_GPIO_DRVSTR */
diff --git a/arch/arm/plat-samsung/gpio.c b/arch/arm/plat-samsung/gpio.c
new file mode 100644
index 00000000000..7743c4b8b2f
--- /dev/null
+++ b/arch/arm/plat-samsung/gpio.c
@@ -0,0 +1,167 @@
1/* linux/arch/arm/plat-s3c/gpio.c
2 *
3 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C series GPIO core
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/io.h>
17#include <linux/gpio.h>
18#include <linux/spinlock.h>
19
20#include <plat/gpio-core.h>
21
22#ifdef CONFIG_S3C_GPIO_TRACK
23struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
24
25static __init void s3c_gpiolib_track(struct s3c_gpio_chip *chip)
26{
27 unsigned int gpn;
28 int i;
29
30 gpn = chip->chip.base;
31 for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
32 BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
33 s3c_gpios[gpn] = chip;
34 }
35}
36#endif /* CONFIG_S3C_GPIO_TRACK */
37
38/* Default routines for controlling GPIO, based on the original S3C24XX
39 * GPIO functions which deal with the case where each gpio bank of the
40 * chip is as following:
41 *
42 * base + 0x00: Control register, 2 bits per gpio
43 * gpio n: 2 bits starting at (2*n)
44 * 00 = input, 01 = output, others mean special-function
45 * base + 0x04: Data register, 1 bit per gpio
46 * bit n: data bit n
47*/
48
49static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset)
50{
51 struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
52 void __iomem *base = ourchip->base;
53 unsigned long flags;
54 unsigned long con;
55
56 s3c_gpio_lock(ourchip, flags);
57
58 con = __raw_readl(base + 0x00);
59 con &= ~(3 << (offset * 2));
60
61 __raw_writel(con, base + 0x00);
62
63 s3c_gpio_unlock(ourchip, flags);
64 return 0;
65}
66
67static int s3c_gpiolib_output(struct gpio_chip *chip,
68 unsigned offset, int value)
69{
70 struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
71 void __iomem *base = ourchip->base;
72 unsigned long flags;
73 unsigned long dat;
74 unsigned long con;
75
76 s3c_gpio_lock(ourchip, flags);
77
78 dat = __raw_readl(base + 0x04);
79 dat &= ~(1 << offset);
80 if (value)
81 dat |= 1 << offset;
82 __raw_writel(dat, base + 0x04);
83
84 con = __raw_readl(base + 0x00);
85 con &= ~(3 << (offset * 2));
86 con |= 1 << (offset * 2);
87
88 __raw_writel(con, base + 0x00);
89 __raw_writel(dat, base + 0x04);
90
91 s3c_gpio_unlock(ourchip, flags);
92 return 0;
93}
94
95static void s3c_gpiolib_set(struct gpio_chip *chip,
96 unsigned offset, int value)
97{
98 struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
99 void __iomem *base = ourchip->base;
100 unsigned long flags;
101 unsigned long dat;
102
103 s3c_gpio_lock(ourchip, flags);
104
105 dat = __raw_readl(base + 0x04);
106 dat &= ~(1 << offset);
107 if (value)
108 dat |= 1 << offset;
109 __raw_writel(dat, base + 0x04);
110
111 s3c_gpio_unlock(ourchip, flags);
112}
113
114static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset)
115{
116 struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
117 unsigned long val;
118
119 val = __raw_readl(ourchip->base + 0x04);
120 val >>= offset;
121 val &= 1;
122
123 return val;
124}
125
126__init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
127{
128 struct gpio_chip *gc = &chip->chip;
129 int ret;
130
131 BUG_ON(!chip->base);
132 BUG_ON(!gc->label);
133 BUG_ON(!gc->ngpio);
134
135 spin_lock_init(&chip->lock);
136
137 if (!gc->direction_input)
138 gc->direction_input = s3c_gpiolib_input;
139 if (!gc->direction_output)
140 gc->direction_output = s3c_gpiolib_output;
141 if (!gc->set)
142 gc->set = s3c_gpiolib_set;
143 if (!gc->get)
144 gc->get = s3c_gpiolib_get;
145
146#ifdef CONFIG_PM
147 if (chip->pm != NULL) {
148 if (!chip->pm->save || !chip->pm->resume)
149 printk(KERN_ERR "gpio: %s has missing PM functions\n",
150 gc->label);
151 } else
152 printk(KERN_ERR "gpio: %s has no PM function\n", gc->label);
153#endif
154
155 /* gpiochip_add() prints own failure message on error. */
156 ret = gpiochip_add(gc);
157 if (ret >= 0)
158 s3c_gpiolib_track(chip);
159}
160
161int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
162{
163 struct s3c_gpio_chip *s3c_chip = container_of(chip,
164 struct s3c_gpio_chip, chip);
165
166 return s3c_chip->irq_base + offset;
167}
diff --git a/arch/arm/plat-samsung/include/plat/ata.h b/arch/arm/plat-samsung/include/plat/ata.h
new file mode 100644
index 00000000000..2a3855a8372
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/ata.h
@@ -0,0 +1,36 @@
1/* linux/arch/arm/plat-samsung/include/plat/ata.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung CF-ATA platform_device info
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#ifndef __ASM_PLAT_ATA_H
14#define __ASM_PLAT_ATA_H __FILE__
15
16/**
17 * struct s3c_ide_platdata - S3C IDE driver platform data.
18 * @setup_gpio: Setup the external GPIO pins to the right state for data
19 * transfer in true-ide mode.
20 */
21struct s3c_ide_platdata {
22 void (*setup_gpio)(void);
23};
24
25/*
26 * s3c_ide_set_platdata() - Setup the platform specifc data for IDE driver.
27 * @pdata: Platform data for IDE driver.
28 */
29extern void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata);
30
31/* architecture-specific IDE configuration */
32extern void s3c64xx_ide_setup_gpio(void);
33extern void s5pc100_ide_setup_gpio(void);
34extern void s5pv210_ide_setup_gpio(void);
35
36#endif /*__ASM_PLAT_ATA_H */
diff --git a/arch/arm/plat-samsung/include/plat/audio.h b/arch/arm/plat-samsung/include/plat/audio.h
new file mode 100644
index 00000000000..aa9875f77c4
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/audio.h
@@ -0,0 +1,59 @@
1/* arch/arm/plat-samsung/include/plat/audio.h
2 *
3 * Copyright (c) 2009 Samsung Electronics Co. Ltd
4 * Author: 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/* The machine init code calls s3c*_ac97_setup_gpio with
12 * one of these defines in order to select appropriate bank
13 * of GPIO for AC97 pins
14 */
15#define S3C64XX_AC97_GPD 0
16#define S3C64XX_AC97_GPE 1
17extern void s3c64xx_ac97_setup_gpio(int);
18
19/*
20 * The machine init code calls s5p*_spdif_setup_gpio with
21 * one of these defines in order to select appropriate bank
22 * of GPIO for S/PDIF pins
23 */
24#define S5PC100_SPDIF_GPD 0
25#define S5PC100_SPDIF_GPG3 1
26extern void s5pc100_spdif_setup_gpio(int);
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 dma_addr_t idma_addr;
48};
49
50/**
51 * struct s3c_audio_pdata - common platform data for audio device drivers
52 * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode
53 */
54struct s3c_audio_pdata {
55 int (*cfg_gpio)(struct platform_device *);
56 union {
57 struct samsung_i2s i2s;
58 } type;
59};
diff --git a/arch/arm/plat-samsung/include/plat/hwmon.h b/arch/arm/plat-samsung/include/plat/hwmon.h
new file mode 100644
index 00000000000..c167e4429bc
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/hwmon.h
@@ -0,0 +1,51 @@
1/* linux/arch/arm/plat-s3c/include/plat/hwmon.h
2 *
3 * Copyright 2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C - HWMon interface for ADC
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#ifndef __ASM_ARCH_ADC_HWMON_H
15#define __ASM_ARCH_ADC_HWMON_H __FILE__
16
17/**
18 * s3c_hwmon_chcfg - channel configuration
19 * @name: The name to give this channel.
20 * @mult: Multiply the ADC value read by this.
21 * @div: Divide the value from the ADC by this.
22 *
23 * The value read from the ADC is converted to a value that
24 * hwmon expects (mV) by result = (value_read * @mult) / @div.
25 */
26struct s3c_hwmon_chcfg {
27 const char *name;
28 unsigned int mult;
29 unsigned int div;
30};
31
32/**
33 * s3c_hwmon_pdata - HWMON platform data
34 * @in: One configuration for each possible channel used.
35 */
36struct s3c_hwmon_pdata {
37 struct s3c_hwmon_chcfg *in[8];
38};
39
40/**
41 * s3c_hwmon_set_platdata - Set platform data for S3C HWMON device
42 * @pd: Platform data to register to device.
43 *
44 * Register the given platform data for use with the S3C HWMON device.
45 * The call will copy the platform data, so the board definitions can
46 * make the structure itself __initdata.
47 */
48extern void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd);
49
50#endif /* __ASM_ARCH_ADC_HWMON_H */
51
diff --git a/arch/arm/plat-samsung/include/plat/iic.h b/arch/arm/plat-samsung/include/plat/iic.h
new file mode 100644
index 00000000000..56b0059439e
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/iic.h
@@ -0,0 +1,76 @@
1/* arch/arm/plat-s3c/include/plat/iic.h
2 *
3 * Copyright 2004-2009 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C - I2C Controller platform_device info
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#ifndef __ASM_ARCH_IIC_H
14#define __ASM_ARCH_IIC_H __FILE__
15
16#define S3C_IICFLG_FILTER (1<<0) /* enable s3c2440 filter */
17
18/**
19 * struct s3c2410_platform_i2c - Platform data for s3c I2C.
20 * @bus_num: The bus number to use (if possible).
21 * @flags: Any flags for the I2C bus (E.g. S3C_IICFLK_FILTER).
22 * @slave_addr: The I2C address for the slave device (if enabled).
23 * @frequency: The desired frequency in Hz of the bus. This is
24 * guaranteed to not be exceeded. If the caller does
25 * not care, use zero and the driver will select a
26 * useful default.
27 * @sda_delay: The delay (in ns) applied to SDA edges.
28 * @cfg_gpio: A callback to configure the pins for I2C operation.
29 */
30struct s3c2410_platform_i2c {
31 int bus_num;
32 unsigned int flags;
33 unsigned int slave_addr;
34 unsigned long frequency;
35 unsigned int sda_delay;
36
37 void (*cfg_gpio)(struct platform_device *dev);
38};
39
40/**
41 * s3c_i2c0_set_platdata - set platform data for i2c0 device
42 * @i2c: The platform data to set, or NULL for default data.
43 *
44 * Register the given platform data for use with the i2c0 device. This
45 * call copies the platform data, so the caller can use __initdata for
46 * their copy.
47 *
48 * This call will set cfg_gpio if is null to the default platform
49 * implementation.
50 *
51 * Any user of s3c_device_i2c0 should call this, even if it is with
52 * NULL to ensure that the device is given the default platform data
53 * as the driver will no longer carry defaults.
54 */
55extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c);
56extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c);
57extern void s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *i2c);
58extern void s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *i2c);
59extern void s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *i2c);
60extern void s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *i2c);
61extern void s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *i2c);
62extern void s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *i2c);
63
64/* defined by architecture to configure gpio */
65extern void s3c_i2c0_cfg_gpio(struct platform_device *dev);
66extern void s3c_i2c1_cfg_gpio(struct platform_device *dev);
67extern void s3c_i2c2_cfg_gpio(struct platform_device *dev);
68extern void s3c_i2c3_cfg_gpio(struct platform_device *dev);
69extern void s3c_i2c4_cfg_gpio(struct platform_device *dev);
70extern void s3c_i2c5_cfg_gpio(struct platform_device *dev);
71extern void s3c_i2c6_cfg_gpio(struct platform_device *dev);
72extern void s3c_i2c7_cfg_gpio(struct platform_device *dev);
73
74extern struct s3c2410_platform_i2c default_i2c_data;
75
76#endif /* __ASM_ARCH_IIC_H */
diff --git a/arch/arm/plat-samsung/include/plat/nand.h b/arch/arm/plat-samsung/include/plat/nand.h
new file mode 100644
index 00000000000..b64115fa93a
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/nand.h
@@ -0,0 +1,67 @@
1/* arch/arm/mach-s3c2410/include/mach/nand.h
2 *
3 * Copyright (c) 2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2410 - NAND device controller platform_device info
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13/**
14 * struct s3c2410_nand_set - define a set of one or more nand chips
15 * @disable_ecc: Entirely disable ECC - Dangerous
16 * @flash_bbt: Openmoko u-boot can create a Bad Block Table
17 * Setting this flag will allow the kernel to
18 * look for it at boot time and also skip the NAND
19 * scan.
20 * @options: Default value to set into 'struct nand_chip' options.
21 * @nr_chips: Number of chips in this set
22 * @nr_partitions: Number of partitions pointed to by @partitions
23 * @name: Name of set (optional)
24 * @nr_map: Map for low-layer logical to physical chip numbers (option)
25 * @partitions: The mtd partition list
26 *
27 * define a set of one or more nand chips registered with an unique mtd. Also
28 * allows to pass flag to the underlying NAND layer. 'disable_ecc' will trigger
29 * a warning at boot time.
30 */
31struct s3c2410_nand_set {
32 unsigned int disable_ecc:1;
33 unsigned int flash_bbt:1;
34
35 unsigned int options;
36 int nr_chips;
37 int nr_partitions;
38 char *name;
39 int *nr_map;
40 struct mtd_partition *partitions;
41 struct nand_ecclayout *ecc_layout;
42};
43
44struct s3c2410_platform_nand {
45 /* timing information for controller, all times in nanoseconds */
46
47 int tacls; /* time for active CLE/ALE to nWE/nOE */
48 int twrph0; /* active time for nWE/nOE */
49 int twrph1; /* time for release CLE/ALE from nWE/nOE inactive */
50
51 unsigned int ignore_unset_ecc:1;
52
53 int nr_sets;
54 struct s3c2410_nand_set *sets;
55
56 void (*select_chip)(struct s3c2410_nand_set *,
57 int chip);
58};
59
60/**
61 * s3c_nand_set_platdata() - register NAND platform data.
62 * @nand: The NAND platform data to register with s3c_device_nand.
63 *
64 * This function copies the given NAND platform data, @nand and registers
65 * it with the s3c_device_nand. This allows @nand to be __initdata.
66*/
67extern void s3c_nand_set_platdata(struct s3c2410_platform_nand *nand);
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 00000000000..abb4bc32716
--- /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-2011 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 exynos4_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/pll6553x.h b/arch/arm/plat-samsung/include/plat/pll6553x.h
new file mode 100644
index 00000000000..b8b7e1d884f
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pll6553x.h
@@ -0,0 +1,51 @@
1/* arch/arm/plat-samsung/include/plat/pll6553x.h
2 * partially from arch/arm/mach-s3c64xx/include/mach/pll.h
3 *
4 * Copyright 2008 Openmoko, Inc.
5 * Copyright 2008 Simtec Electronics
6 * Ben Dooks <ben@simtec.co.uk>
7 * http://armlinux.simtec.co.uk/
8 *
9 * Samsung PLL6553x PLL code
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14*/
15
16/* S3C6400 and compatible (S3C2416, etc.) EPLL code */
17
18#define PLL6553X_MDIV_MASK ((1 << (23-16)) - 1)
19#define PLL6553X_PDIV_MASK ((1 << (13-8)) - 1)
20#define PLL6553X_SDIV_MASK ((1 << (2-0)) - 1)
21#define PLL6553X_MDIV_SHIFT (16)
22#define PLL6553X_PDIV_SHIFT (8)
23#define PLL6553X_SDIV_SHIFT (0)
24#define PLL6553X_KDIV_MASK (0xffff)
25
26static inline unsigned long s3c_get_pll6553x(unsigned long baseclk,
27 u32 pll0, u32 pll1)
28{
29 unsigned long result;
30 u32 mdiv, pdiv, sdiv, kdiv;
31 u64 tmp;
32
33 mdiv = (pll0 >> PLL6553X_MDIV_SHIFT) & PLL6553X_MDIV_MASK;
34 pdiv = (pll0 >> PLL6553X_PDIV_SHIFT) & PLL6553X_PDIV_MASK;
35 sdiv = (pll0 >> PLL6553X_SDIV_SHIFT) & PLL6553X_SDIV_MASK;
36 kdiv = pll1 & PLL6553X_KDIV_MASK;
37
38 /* We need to multiple baseclk by mdiv (the integer part) and kdiv
39 * which is in 2^16ths, so shift mdiv up (does not overflow) and
40 * add kdiv before multiplying. The use of tmp is to avoid any
41 * overflows before shifting bac down into result when multipling
42 * by the mdiv and kdiv pair.
43 */
44
45 tmp = baseclk;
46 tmp *= (mdiv << 16) + kdiv;
47 do_div(tmp, (pdiv << sdiv));
48 result = tmp >> 16;
49
50 return result;
51}
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb-v4.h b/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
new file mode 100644
index 00000000000..4c3647f8005
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
@@ -0,0 +1,159 @@
1/* arch/arm/plat-samsung/include/plat/regs-fb-v4.h
2 *
3 * Copyright 2008 Openmoko, Inc.
4 * Copyright 2008 Simtec Electronics
5 * http://armlinux.simtec.co.uk/
6 * Ben Dooks <ben@simtec.co.uk>
7 *
8 * S3C64XX - new-style framebuffer register definitions
9 *
10 * This is the register set for the new style framebuffer interface
11 * found from the S3C2443 onwards and specifically the S3C64XX series
12 * S3C6400 and S3C6410.
13 *
14 * The file contains the cpu specific items which change between whichever
15 * architecture is selected. See <plat/regs-fb.h> for the core definitions
16 * that are the same.
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License version 2 as
20 * published by the Free Software Foundation.
21*/
22
23/* include the core definitions here, in case we really do need to
24 * override them at a later date.
25*/
26
27#include <plat/regs-fb.h>
28
29#define S3C_FB_MAX_WIN (5) /* number of hardware windows available. */
30#define VIDCON1_FSTATUS_EVEN (1 << 15)
31
32/* Video timing controls */
33#define VIDTCON0 (0x10)
34#define VIDTCON1 (0x14)
35#define VIDTCON2 (0x18)
36
37/* Window position controls */
38
39#define WINCON(_win) (0x20 + ((_win) * 4))
40
41/* OSD1 and OSD4 do not have register D */
42
43#define VIDOSD_BASE (0x40)
44
45#define VIDINTCON0 (0x130)
46
47/* WINCONx */
48
49#define WINCONx_CSCWIDTH_MASK (0x3 << 26)
50#define WINCONx_CSCWIDTH_SHIFT (26)
51#define WINCONx_CSCWIDTH_WIDE (0x0 << 26)
52#define WINCONx_CSCWIDTH_NARROW (0x3 << 26)
53
54#define WINCONx_ENLOCAL (1 << 22)
55#define WINCONx_BUFSTATUS (1 << 21)
56#define WINCONx_BUFSEL (1 << 20)
57#define WINCONx_BUFAUTOEN (1 << 19)
58#define WINCONx_YCbCr (1 << 13)
59
60#define WINCON1_LOCALSEL_CAMIF (1 << 23)
61
62#define WINCON2_LOCALSEL_CAMIF (1 << 23)
63#define WINCON2_BLD_PIX (1 << 6)
64
65#define WINCON2_ALPHA_SEL (1 << 1)
66#define WINCON2_BPPMODE_MASK (0xf << 2)
67#define WINCON2_BPPMODE_SHIFT (2)
68#define WINCON2_BPPMODE_1BPP (0x0 << 2)
69#define WINCON2_BPPMODE_2BPP (0x1 << 2)
70#define WINCON2_BPPMODE_4BPP (0x2 << 2)
71#define WINCON2_BPPMODE_8BPP_1232 (0x4 << 2)
72#define WINCON2_BPPMODE_16BPP_565 (0x5 << 2)
73#define WINCON2_BPPMODE_16BPP_A1555 (0x6 << 2)
74#define WINCON2_BPPMODE_16BPP_I1555 (0x7 << 2)
75#define WINCON2_BPPMODE_18BPP_666 (0x8 << 2)
76#define WINCON2_BPPMODE_18BPP_A1665 (0x9 << 2)
77#define WINCON2_BPPMODE_19BPP_A1666 (0xa << 2)
78#define WINCON2_BPPMODE_24BPP_888 (0xb << 2)
79#define WINCON2_BPPMODE_24BPP_A1887 (0xc << 2)
80#define WINCON2_BPPMODE_25BPP_A1888 (0xd << 2)
81#define WINCON2_BPPMODE_28BPP_A4888 (0xd << 2)
82
83#define WINCON3_BLD_PIX (1 << 6)
84
85#define WINCON3_ALPHA_SEL (1 << 1)
86#define WINCON3_BPPMODE_MASK (0xf << 2)
87#define WINCON3_BPPMODE_SHIFT (2)
88#define WINCON3_BPPMODE_1BPP (0x0 << 2)
89#define WINCON3_BPPMODE_2BPP (0x1 << 2)
90#define WINCON3_BPPMODE_4BPP (0x2 << 2)
91#define WINCON3_BPPMODE_16BPP_565 (0x5 << 2)
92#define WINCON3_BPPMODE_16BPP_A1555 (0x6 << 2)
93#define WINCON3_BPPMODE_16BPP_I1555 (0x7 << 2)
94#define WINCON3_BPPMODE_18BPP_666 (0x8 << 2)
95#define WINCON3_BPPMODE_18BPP_A1665 (0x9 << 2)
96#define WINCON3_BPPMODE_19BPP_A1666 (0xa << 2)
97#define WINCON3_BPPMODE_24BPP_888 (0xb << 2)
98#define WINCON3_BPPMODE_24BPP_A1887 (0xc << 2)
99#define WINCON3_BPPMODE_25BPP_A1888 (0xd << 2)
100#define WINCON3_BPPMODE_28BPP_A4888 (0xd << 2)
101
102#define VIDINTCON0_FIFIOSEL_WINDOW2 (0x10 << 5)
103#define VIDINTCON0_FIFIOSEL_WINDOW3 (0x20 << 5)
104#define VIDINTCON0_FIFIOSEL_WINDOW4 (0x40 << 5)
105
106#define DITHMODE (0x170)
107#define WINxMAP(_win) (0x180 + ((_win) * 4))
108
109
110#define DITHMODE_R_POS_MASK (0x3 << 5)
111#define DITHMODE_R_POS_SHIFT (5)
112#define DITHMODE_R_POS_8BIT (0x0 << 5)
113#define DITHMODE_R_POS_6BIT (0x1 << 5)
114#define DITHMODE_R_POS_5BIT (0x2 << 5)
115
116#define DITHMODE_G_POS_MASK (0x3 << 3)
117#define DITHMODE_G_POS_SHIFT (3)
118#define DITHMODE_G_POS_8BIT (0x0 << 3)
119#define DITHMODE_G_POS_6BIT (0x1 << 3)
120#define DITHMODE_G_POS_5BIT (0x2 << 3)
121
122#define DITHMODE_B_POS_MASK (0x3 << 1)
123#define DITHMODE_B_POS_SHIFT (1)
124#define DITHMODE_B_POS_8BIT (0x0 << 1)
125#define DITHMODE_B_POS_6BIT (0x1 << 1)
126#define DITHMODE_B_POS_5BIT (0x2 << 1)
127
128#define DITHMODE_DITH_EN (1 << 0)
129
130#define WPALCON (0x1A0)
131
132/* Palette control */
133/* Note for S5PC100: you can still use those macros on WPALCON (aka WPALCON_L),
134 * but make sure that WPALCON_H W2PAL-W4PAL entries are zeroed out */
135#define WPALCON_W4PAL_16BPP_A555 (1 << 8)
136#define WPALCON_W3PAL_16BPP_A555 (1 << 7)
137#define WPALCON_W2PAL_16BPP_A555 (1 << 6)
138
139
140/* Notes on per-window bpp settings
141 *
142 * Value Win0 Win1 Win2 Win3 Win 4
143 * 0000 1(P) 1(P) 1(P) 1(P) 1(P)
144 * 0001 2(P) 2(P) 2(P) 2(P) 2(P)
145 * 0010 4(P) 4(P) 4(P) 4(P) -none-
146 * 0011 8(P) 8(P) -none- -none- -none-
147 * 0100 -none- 8(A232) 8(A232) -none- -none-
148 * 0101 16(565) 16(565) 16(565) 16(565) 16(565)
149 * 0110 -none- 16(A555) 16(A555) 16(A555) 16(A555)
150 * 0111 16(I555) 16(I565) 16(I555) 16(I555) 16(I555)
151 * 1000 18(666) 18(666) 18(666) 18(666) 18(666)
152 * 1001 -none- 18(A665) 18(A665) 18(A665) 16(A665)
153 * 1010 -none- 19(A666) 19(A666) 19(A666) 19(A666)
154 * 1011 24(888) 24(888) 24(888) 24(888) 24(888)
155 * 1100 -none- 24(A887) 24(A887) 24(A887) 24(A887)
156 * 1101 -none- 25(A888) 25(A888) 25(A888) 25(A888)
157 * 1110 -none- -none- -none- -none- -none-
158 * 1111 -none- -none- -none- -none- -none-
159*/
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb.h b/arch/arm/plat-samsung/include/plat/regs-fb.h
new file mode 100644
index 00000000000..8f39aa5b26e
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-fb.h
@@ -0,0 +1,386 @@
1/* arch/arm/plat-samsung/include/plat/regs-fb.h
2 *
3 * Copyright 2008 Openmoko, Inc.
4 * Copyright 2008 Simtec Electronics
5 * http://armlinux.simtec.co.uk/
6 * Ben Dooks <ben@simtec.co.uk>
7 *
8 * S3C Platform - new-style framebuffer register definitions
9 *
10 * This is the register set for the new style framebuffer interface
11 * found from the S3C2443 onwards into the S3C2416, S3C2450 and the
12 * S3C64XX series such as the S3C6400 and S3C6410.
13 *
14 * The file does not contain the cpu specific items which are based on
15 * whichever architecture is selected, it only contains the core of the
16 * register set. See <mach/regs-fb.h> to get the specifics.
17 *
18 * Note, we changed to using regs-fb.h as it avoids any clashes with
19 * the original regs-lcd.h so out of the way of regs-lcd.h as well as
20 * indicating the newer block is much more than just an LCD interface.
21 *
22 * This program is free software; you can redistribute it and/or modify
23 * it under the terms of the GNU General Public License version 2 as
24 * published by the Free Software Foundation.
25*/
26
27/* Please do not include this file directly, use <mach/regs-fb.h> to
28 * ensure all the localised SoC support is included as necessary.
29*/
30
31/* VIDCON0 */
32
33#define VIDCON0 (0x00)
34#define VIDCON0_INTERLACE (1 << 29)
35#define VIDCON0_VIDOUT_MASK (0x3 << 26)
36#define VIDCON0_VIDOUT_SHIFT (26)
37#define VIDCON0_VIDOUT_RGB (0x0 << 26)
38#define VIDCON0_VIDOUT_TV (0x1 << 26)
39#define VIDCON0_VIDOUT_I80_LDI0 (0x2 << 26)
40#define VIDCON0_VIDOUT_I80_LDI1 (0x3 << 26)
41
42#define VIDCON0_L1_DATA_MASK (0x7 << 23)
43#define VIDCON0_L1_DATA_SHIFT (23)
44#define VIDCON0_L1_DATA_16BPP (0x0 << 23)
45#define VIDCON0_L1_DATA_18BPP16 (0x1 << 23)
46#define VIDCON0_L1_DATA_18BPP9 (0x2 << 23)
47#define VIDCON0_L1_DATA_24BPP (0x3 << 23)
48#define VIDCON0_L1_DATA_18BPP (0x4 << 23)
49#define VIDCON0_L1_DATA_16BPP8 (0x5 << 23)
50
51#define VIDCON0_L0_DATA_MASK (0x7 << 20)
52#define VIDCON0_L0_DATA_SHIFT (20)
53#define VIDCON0_L0_DATA_16BPP (0x0 << 20)
54#define VIDCON0_L0_DATA_18BPP16 (0x1 << 20)
55#define VIDCON0_L0_DATA_18BPP9 (0x2 << 20)
56#define VIDCON0_L0_DATA_24BPP (0x3 << 20)
57#define VIDCON0_L0_DATA_18BPP (0x4 << 20)
58#define VIDCON0_L0_DATA_16BPP8 (0x5 << 20)
59
60#define VIDCON0_PNRMODE_MASK (0x3 << 17)
61#define VIDCON0_PNRMODE_SHIFT (17)
62#define VIDCON0_PNRMODE_RGB (0x0 << 17)
63#define VIDCON0_PNRMODE_BGR (0x1 << 17)
64#define VIDCON0_PNRMODE_SERIAL_RGB (0x2 << 17)
65#define VIDCON0_PNRMODE_SERIAL_BGR (0x3 << 17)
66
67#define VIDCON0_CLKVALUP (1 << 16)
68#define VIDCON0_CLKVAL_F_MASK (0xff << 6)
69#define VIDCON0_CLKVAL_F_SHIFT (6)
70#define VIDCON0_CLKVAL_F_LIMIT (0xff)
71#define VIDCON0_CLKVAL_F(_x) ((_x) << 6)
72#define VIDCON0_VLCKFREE (1 << 5)
73#define VIDCON0_CLKDIR (1 << 4)
74
75#define VIDCON0_CLKSEL_MASK (0x3 << 2)
76#define VIDCON0_CLKSEL_SHIFT (2)
77#define VIDCON0_CLKSEL_HCLK (0x0 << 2)
78#define VIDCON0_CLKSEL_LCD (0x1 << 2)
79#define VIDCON0_CLKSEL_27M (0x3 << 2)
80
81#define VIDCON0_ENVID (1 << 1)
82#define VIDCON0_ENVID_F (1 << 0)
83
84#define VIDCON1 (0x04)
85#define VIDCON1_LINECNT_MASK (0x7ff << 16)
86#define VIDCON1_LINECNT_SHIFT (16)
87#define VIDCON1_LINECNT_GET(_v) (((_v) >> 16) & 0x7ff)
88#define VIDCON1_VSTATUS_MASK (0x3 << 13)
89#define VIDCON1_VSTATUS_SHIFT (13)
90#define VIDCON1_VSTATUS_VSYNC (0x0 << 13)
91#define VIDCON1_VSTATUS_BACKPORCH (0x1 << 13)
92#define VIDCON1_VSTATUS_ACTIVE (0x2 << 13)
93#define VIDCON1_VSTATUS_FRONTPORCH (0x0 << 13)
94
95#define VIDCON1_INV_VCLK (1 << 7)
96#define VIDCON1_INV_HSYNC (1 << 6)
97#define VIDCON1_INV_VSYNC (1 << 5)
98#define VIDCON1_INV_VDEN (1 << 4)
99
100/* VIDCON2 */
101
102#define VIDCON2 (0x08)
103#define VIDCON2_EN601 (1 << 23)
104#define VIDCON2_TVFMTSEL_SW (1 << 14)
105
106#define VIDCON2_TVFMTSEL1_MASK (0x3 << 12)
107#define VIDCON2_TVFMTSEL1_SHIFT (12)
108#define VIDCON2_TVFMTSEL1_RGB (0x0 << 12)
109#define VIDCON2_TVFMTSEL1_YUV422 (0x1 << 12)
110#define VIDCON2_TVFMTSEL1_YUV444 (0x2 << 12)
111
112#define VIDCON2_ORGYCbCr (1 << 8)
113#define VIDCON2_YUVORDCrCb (1 << 7)
114
115/* PRTCON (S3C6410, S5PC100)
116 * Might not be present in the S3C6410 documentation,
117 * but tests prove it's there almost for sure; shouldn't hurt in any case.
118 */
119#define PRTCON (0x0c)
120#define PRTCON_PROTECT (1 << 11)
121
122/* VIDTCON0 */
123
124#define VIDTCON0_VBPDE_MASK (0xff << 24)
125#define VIDTCON0_VBPDE_SHIFT (24)
126#define VIDTCON0_VBPDE_LIMIT (0xff)
127#define VIDTCON0_VBPDE(_x) ((_x) << 24)
128
129#define VIDTCON0_VBPD_MASK (0xff << 16)
130#define VIDTCON0_VBPD_SHIFT (16)
131#define VIDTCON0_VBPD_LIMIT (0xff)
132#define VIDTCON0_VBPD(_x) ((_x) << 16)
133
134#define VIDTCON0_VFPD_MASK (0xff << 8)
135#define VIDTCON0_VFPD_SHIFT (8)
136#define VIDTCON0_VFPD_LIMIT (0xff)
137#define VIDTCON0_VFPD(_x) ((_x) << 8)
138
139#define VIDTCON0_VSPW_MASK (0xff << 0)
140#define VIDTCON0_VSPW_SHIFT (0)
141#define VIDTCON0_VSPW_LIMIT (0xff)
142#define VIDTCON0_VSPW(_x) ((_x) << 0)
143
144/* VIDTCON1 */
145
146#define VIDTCON1_VFPDE_MASK (0xff << 24)
147#define VIDTCON1_VFPDE_SHIFT (24)
148#define VIDTCON1_VFPDE_LIMIT (0xff)
149#define VIDTCON1_VFPDE(_x) ((_x) << 24)
150
151#define VIDTCON1_HBPD_MASK (0xff << 16)
152#define VIDTCON1_HBPD_SHIFT (16)
153#define VIDTCON1_HBPD_LIMIT (0xff)
154#define VIDTCON1_HBPD(_x) ((_x) << 16)
155
156#define VIDTCON1_HFPD_MASK (0xff << 8)
157#define VIDTCON1_HFPD_SHIFT (8)
158#define VIDTCON1_HFPD_LIMIT (0xff)
159#define VIDTCON1_HFPD(_x) ((_x) << 8)
160
161#define VIDTCON1_HSPW_MASK (0xff << 0)
162#define VIDTCON1_HSPW_SHIFT (0)
163#define VIDTCON1_HSPW_LIMIT (0xff)
164#define VIDTCON1_HSPW(_x) ((_x) << 0)
165
166#define VIDTCON2 (0x18)
167#define VIDTCON2_LINEVAL_MASK (0x7ff << 11)
168#define VIDTCON2_LINEVAL_SHIFT (11)
169#define VIDTCON2_LINEVAL_LIMIT (0x7ff)
170#define VIDTCON2_LINEVAL(_x) ((_x) << 11)
171
172#define VIDTCON2_HOZVAL_MASK (0x7ff << 0)
173#define VIDTCON2_HOZVAL_SHIFT (0)
174#define VIDTCON2_HOZVAL_LIMIT (0x7ff)
175#define VIDTCON2_HOZVAL(_x) ((_x) << 0)
176
177/* WINCONx */
178
179
180#define WINCONx_BITSWP (1 << 18)
181#define WINCONx_BYTSWP (1 << 17)
182#define WINCONx_HAWSWP (1 << 16)
183#define WINCONx_WSWP (1 << 15)
184#define WINCONx_BURSTLEN_MASK (0x3 << 9)
185#define WINCONx_BURSTLEN_SHIFT (9)
186#define WINCONx_BURSTLEN_16WORD (0x0 << 9)
187#define WINCONx_BURSTLEN_8WORD (0x1 << 9)
188#define WINCONx_BURSTLEN_4WORD (0x2 << 9)
189
190#define WINCONx_ENWIN (1 << 0)
191#define WINCON0_BPPMODE_MASK (0xf << 2)
192#define WINCON0_BPPMODE_SHIFT (2)
193#define WINCON0_BPPMODE_1BPP (0x0 << 2)
194#define WINCON0_BPPMODE_2BPP (0x1 << 2)
195#define WINCON0_BPPMODE_4BPP (0x2 << 2)
196#define WINCON0_BPPMODE_8BPP_PALETTE (0x3 << 2)
197#define WINCON0_BPPMODE_16BPP_565 (0x5 << 2)
198#define WINCON0_BPPMODE_16BPP_1555 (0x7 << 2)
199#define WINCON0_BPPMODE_18BPP_666 (0x8 << 2)
200#define WINCON0_BPPMODE_24BPP_888 (0xb << 2)
201
202#define WINCON1_BLD_PIX (1 << 6)
203
204#define WINCON1_ALPHA_SEL (1 << 1)
205#define WINCON1_BPPMODE_MASK (0xf << 2)
206#define WINCON1_BPPMODE_SHIFT (2)
207#define WINCON1_BPPMODE_1BPP (0x0 << 2)
208#define WINCON1_BPPMODE_2BPP (0x1 << 2)
209#define WINCON1_BPPMODE_4BPP (0x2 << 2)
210#define WINCON1_BPPMODE_8BPP_PALETTE (0x3 << 2)
211#define WINCON1_BPPMODE_8BPP_1232 (0x4 << 2)
212#define WINCON1_BPPMODE_16BPP_565 (0x5 << 2)
213#define WINCON1_BPPMODE_16BPP_A1555 (0x6 << 2)
214#define WINCON1_BPPMODE_16BPP_I1555 (0x7 << 2)
215#define WINCON1_BPPMODE_18BPP_666 (0x8 << 2)
216#define WINCON1_BPPMODE_18BPP_A1665 (0x9 << 2)
217#define WINCON1_BPPMODE_19BPP_A1666 (0xa << 2)
218#define WINCON1_BPPMODE_24BPP_888 (0xb << 2)
219#define WINCON1_BPPMODE_24BPP_A1887 (0xc << 2)
220#define WINCON1_BPPMODE_25BPP_A1888 (0xd << 2)
221#define WINCON1_BPPMODE_28BPP_A4888 (0xd << 2)
222
223/* S5PV210 */
224#define SHADOWCON (0x34)
225#define SHADOWCON_WINx_PROTECT(_win) (1 << (10 + (_win)))
226/* DMA channels (all windows) */
227#define SHADOWCON_CHx_ENABLE(_win) (1 << (_win))
228/* Local input channels (windows 0-2) */
229#define SHADOWCON_CHx_LOCAL_ENABLE(_win) (1 << (5 + (_win)))
230
231#define VIDOSDxA_TOPLEFT_X_MASK (0x7ff << 11)
232#define VIDOSDxA_TOPLEFT_X_SHIFT (11)
233#define VIDOSDxA_TOPLEFT_X_LIMIT (0x7ff)
234#define VIDOSDxA_TOPLEFT_X(_x) ((_x) << 11)
235
236#define VIDOSDxA_TOPLEFT_Y_MASK (0x7ff << 0)
237#define VIDOSDxA_TOPLEFT_Y_SHIFT (0)
238#define VIDOSDxA_TOPLEFT_Y_LIMIT (0x7ff)
239#define VIDOSDxA_TOPLEFT_Y(_x) ((_x) << 0)
240
241#define VIDOSDxB_BOTRIGHT_X_MASK (0x7ff << 11)
242#define VIDOSDxB_BOTRIGHT_X_SHIFT (11)
243#define VIDOSDxB_BOTRIGHT_X_LIMIT (0x7ff)
244#define VIDOSDxB_BOTRIGHT_X(_x) ((_x) << 11)
245
246#define VIDOSDxB_BOTRIGHT_Y_MASK (0x7ff << 0)
247#define VIDOSDxB_BOTRIGHT_Y_SHIFT (0)
248#define VIDOSDxB_BOTRIGHT_Y_LIMIT (0x7ff)
249#define VIDOSDxB_BOTRIGHT_Y(_x) ((_x) << 0)
250
251/* For VIDOSD[1..4]C */
252#define VIDISD14C_ALPHA0_R(_x) ((_x) << 20)
253#define VIDISD14C_ALPHA0_G_MASK (0xf << 16)
254#define VIDISD14C_ALPHA0_G_SHIFT (16)
255#define VIDISD14C_ALPHA0_G_LIMIT (0xf)
256#define VIDISD14C_ALPHA0_G(_x) ((_x) << 16)
257#define VIDISD14C_ALPHA0_B_MASK (0xf << 12)
258#define VIDISD14C_ALPHA0_B_SHIFT (12)
259#define VIDISD14C_ALPHA0_B_LIMIT (0xf)
260#define VIDISD14C_ALPHA0_B(_x) ((_x) << 12)
261#define VIDISD14C_ALPHA1_R_MASK (0xf << 8)
262#define VIDISD14C_ALPHA1_R_SHIFT (8)
263#define VIDISD14C_ALPHA1_R_LIMIT (0xf)
264#define VIDISD14C_ALPHA1_R(_x) ((_x) << 8)
265#define VIDISD14C_ALPHA1_G_MASK (0xf << 4)
266#define VIDISD14C_ALPHA1_G_SHIFT (4)
267#define VIDISD14C_ALPHA1_G_LIMIT (0xf)
268#define VIDISD14C_ALPHA1_G(_x) ((_x) << 4)
269#define VIDISD14C_ALPHA1_B_MASK (0xf << 0)
270#define VIDISD14C_ALPHA1_B_SHIFT (0)
271#define VIDISD14C_ALPHA1_B_LIMIT (0xf)
272#define VIDISD14C_ALPHA1_B(_x) ((_x) << 0)
273
274/* Video buffer addresses */
275#define VIDW_BUF_START(_buff) (0xA0 + ((_buff) * 8))
276#define VIDW_BUF_START1(_buff) (0xA4 + ((_buff) * 8))
277#define VIDW_BUF_END(_buff) (0xD0 + ((_buff) * 8))
278#define VIDW_BUF_END1(_buff) (0xD4 + ((_buff) * 8))
279#define VIDW_BUF_SIZE(_buff) (0x100 + ((_buff) * 4))
280
281#define VIDW_BUF_SIZE_OFFSET_MASK (0x1fff << 13)
282#define VIDW_BUF_SIZE_OFFSET_SHIFT (13)
283#define VIDW_BUF_SIZE_OFFSET_LIMIT (0x1fff)
284#define VIDW_BUF_SIZE_OFFSET(_x) ((_x) << 13)
285
286#define VIDW_BUF_SIZE_PAGEWIDTH_MASK (0x1fff << 0)
287#define VIDW_BUF_SIZE_PAGEWIDTH_SHIFT (0)
288#define VIDW_BUF_SIZE_PAGEWIDTH_LIMIT (0x1fff)
289#define VIDW_BUF_SIZE_PAGEWIDTH(_x) ((_x) << 0)
290
291/* Interrupt controls and status */
292
293#define VIDINTCON0_FIFOINTERVAL_MASK (0x3f << 20)
294#define VIDINTCON0_FIFOINTERVAL_SHIFT (20)
295#define VIDINTCON0_FIFOINTERVAL_LIMIT (0x3f)
296#define VIDINTCON0_FIFOINTERVAL(_x) ((_x) << 20)
297
298#define VIDINTCON0_INT_SYSMAINCON (1 << 19)
299#define VIDINTCON0_INT_SYSSUBCON (1 << 18)
300#define VIDINTCON0_INT_I80IFDONE (1 << 17)
301
302#define VIDINTCON0_FRAMESEL0_MASK (0x3 << 15)
303#define VIDINTCON0_FRAMESEL0_SHIFT (15)
304#define VIDINTCON0_FRAMESEL0_BACKPORCH (0x0 << 15)
305#define VIDINTCON0_FRAMESEL0_VSYNC (0x1 << 15)
306#define VIDINTCON0_FRAMESEL0_ACTIVE (0x2 << 15)
307#define VIDINTCON0_FRAMESEL0_FRONTPORCH (0x3 << 15)
308
309#define VIDINTCON0_FRAMESEL1 (1 << 13)
310#define VIDINTCON0_FRAMESEL1_MASK (0x3 << 13)
311#define VIDINTCON0_FRAMESEL1_NONE (0x0 << 13)
312#define VIDINTCON0_FRAMESEL1_BACKPORCH (0x1 << 13)
313#define VIDINTCON0_FRAMESEL1_VSYNC (0x2 << 13)
314#define VIDINTCON0_FRAMESEL1_FRONTPORCH (0x3 << 13)
315
316#define VIDINTCON0_INT_FRAME (1 << 12)
317#define VIDINTCON0_FIFIOSEL_MASK (0x7f << 5)
318#define VIDINTCON0_FIFIOSEL_SHIFT (5)
319#define VIDINTCON0_FIFIOSEL_WINDOW0 (0x1 << 5)
320#define VIDINTCON0_FIFIOSEL_WINDOW1 (0x2 << 5)
321
322#define VIDINTCON0_FIFOLEVEL_MASK (0x7 << 2)
323#define VIDINTCON0_FIFOLEVEL_SHIFT (2)
324#define VIDINTCON0_FIFOLEVEL_TO25PC (0x0 << 2)
325#define VIDINTCON0_FIFOLEVEL_TO50PC (0x1 << 2)
326#define VIDINTCON0_FIFOLEVEL_TO75PC (0x2 << 2)
327#define VIDINTCON0_FIFOLEVEL_EMPTY (0x3 << 2)
328#define VIDINTCON0_FIFOLEVEL_FULL (0x4 << 2)
329
330#define VIDINTCON0_INT_FIFO_MASK (0x3 << 0)
331#define VIDINTCON0_INT_FIFO_SHIFT (0)
332#define VIDINTCON0_INT_ENABLE (1 << 0)
333
334#define VIDINTCON1 (0x134)
335#define VIDINTCON1_INT_I180 (1 << 2)
336#define VIDINTCON1_INT_FRAME (1 << 1)
337#define VIDINTCON1_INT_FIFO (1 << 0)
338
339/* Window colour-key control registers */
340#define WKEYCON (0x140) /* 6410,V210 */
341
342#define WKEYCON0 (0x00)
343#define WKEYCON1 (0x04)
344
345#define WxKEYCON0_KEYBL_EN (1 << 26)
346#define WxKEYCON0_KEYEN_F (1 << 25)
347#define WxKEYCON0_DIRCON (1 << 24)
348#define WxKEYCON0_COMPKEY_MASK (0xffffff << 0)
349#define WxKEYCON0_COMPKEY_SHIFT (0)
350#define WxKEYCON0_COMPKEY_LIMIT (0xffffff)
351#define WxKEYCON0_COMPKEY(_x) ((_x) << 0)
352#define WxKEYCON1_COLVAL_MASK (0xffffff << 0)
353#define WxKEYCON1_COLVAL_SHIFT (0)
354#define WxKEYCON1_COLVAL_LIMIT (0xffffff)
355#define WxKEYCON1_COLVAL(_x) ((_x) << 0)
356
357
358/* Window blanking (MAP) */
359
360#define WINxMAP_MAP (1 << 24)
361#define WINxMAP_MAP_COLOUR_MASK (0xffffff << 0)
362#define WINxMAP_MAP_COLOUR_SHIFT (0)
363#define WINxMAP_MAP_COLOUR_LIMIT (0xffffff)
364#define WINxMAP_MAP_COLOUR(_x) ((_x) << 0)
365
366#define WPALCON_PAL_UPDATE (1 << 9)
367#define WPALCON_W1PAL_MASK (0x7 << 3)
368#define WPALCON_W1PAL_SHIFT (3)
369#define WPALCON_W1PAL_25BPP_A888 (0x0 << 3)
370#define WPALCON_W1PAL_24BPP (0x1 << 3)
371#define WPALCON_W1PAL_19BPP_A666 (0x2 << 3)
372#define WPALCON_W1PAL_18BPP_A665 (0x3 << 3)
373#define WPALCON_W1PAL_18BPP (0x4 << 3)
374#define WPALCON_W1PAL_16BPP_A555 (0x5 << 3)
375#define WPALCON_W1PAL_16BPP_565 (0x6 << 3)
376
377#define WPALCON_W0PAL_MASK (0x7 << 0)
378#define WPALCON_W0PAL_SHIFT (0)
379#define WPALCON_W0PAL_25BPP_A888 (0x0 << 0)
380#define WPALCON_W0PAL_24BPP (0x1 << 0)
381#define WPALCON_W0PAL_19BPP_A666 (0x2 << 0)
382#define WPALCON_W0PAL_18BPP_A665 (0x3 << 0)
383#define WPALCON_W0PAL_18BPP (0x4 << 0)
384#define WPALCON_W0PAL_16BPP_A555 (0x5 << 0)
385#define WPALCON_W0PAL_16BPP_565 (0x6 << 0)
386
diff --git a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h
new file mode 100644
index 00000000000..dc90f5ede88
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h
@@ -0,0 +1,379 @@
1/* arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h
2 *
3 * Copyright 2008 Openmoko, Inc.
4 * Copyright 2008 Simtec Electronics
5 * http://armlinux.simtec.co.uk/
6 * Ben Dooks <ben@simtec.co.uk>
7 *
8 * S3C - USB2.0 Highspeed/OtG device block registers
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#ifndef __PLAT_S3C64XX_REGS_USB_HSOTG_H
16#define __PLAT_S3C64XX_REGS_USB_HSOTG_H __FILE__
17
18#define S3C_HSOTG_REG(x) (x)
19
20#define S3C_GOTGCTL S3C_HSOTG_REG(0x000)
21#define S3C_GOTGCTL_BSESVLD (1 << 19)
22#define S3C_GOTGCTL_ASESVLD (1 << 18)
23#define S3C_GOTGCTL_DBNC_SHORT (1 << 17)
24#define S3C_GOTGCTL_CONID_B (1 << 16)
25#define S3C_GOTGCTL_DEVHNPEN (1 << 11)
26#define S3C_GOTGCTL_HSSETHNPEN (1 << 10)
27#define S3C_GOTGCTL_HNPREQ (1 << 9)
28#define S3C_GOTGCTL_HSTNEGSCS (1 << 8)
29#define S3C_GOTGCTL_SESREQ (1 << 1)
30#define S3C_GOTGCTL_SESREQSCS (1 << 0)
31
32#define S3C_GOTGINT S3C_HSOTG_REG(0x004)
33#define S3C_GOTGINT_DbnceDone (1 << 19)
34#define S3C_GOTGINT_ADevTOUTChg (1 << 18)
35#define S3C_GOTGINT_HstNegDet (1 << 17)
36#define S3C_GOTGINT_HstnegSucStsChng (1 << 9)
37#define S3C_GOTGINT_SesReqSucStsChng (1 << 8)
38#define S3C_GOTGINT_SesEndDet (1 << 2)
39
40#define S3C_GAHBCFG S3C_HSOTG_REG(0x008)
41#define S3C_GAHBCFG_PTxFEmpLvl (1 << 8)
42#define S3C_GAHBCFG_NPTxFEmpLvl (1 << 7)
43#define S3C_GAHBCFG_DMAEn (1 << 5)
44#define S3C_GAHBCFG_HBstLen_MASK (0xf << 1)
45#define S3C_GAHBCFG_HBstLen_SHIFT (1)
46#define S3C_GAHBCFG_HBstLen_Single (0x0 << 1)
47#define S3C_GAHBCFG_HBstLen_Incr (0x1 << 1)
48#define S3C_GAHBCFG_HBstLen_Incr4 (0x3 << 1)
49#define S3C_GAHBCFG_HBstLen_Incr8 (0x5 << 1)
50#define S3C_GAHBCFG_HBstLen_Incr16 (0x7 << 1)
51#define S3C_GAHBCFG_GlblIntrEn (1 << 0)
52
53#define S3C_GUSBCFG S3C_HSOTG_REG(0x00C)
54#define S3C_GUSBCFG_PHYLPClkSel (1 << 15)
55#define S3C_GUSBCFG_HNPCap (1 << 9)
56#define S3C_GUSBCFG_SRPCap (1 << 8)
57#define S3C_GUSBCFG_PHYIf16 (1 << 3)
58#define S3C_GUSBCFG_TOutCal_MASK (0x7 << 0)
59#define S3C_GUSBCFG_TOutCal_SHIFT (0)
60#define S3C_GUSBCFG_TOutCal_LIMIT (0x7)
61#define S3C_GUSBCFG_TOutCal(_x) ((_x) << 0)
62
63#define S3C_GRSTCTL S3C_HSOTG_REG(0x010)
64
65#define S3C_GRSTCTL_AHBIdle (1 << 31)
66#define S3C_GRSTCTL_DMAReq (1 << 30)
67#define S3C_GRSTCTL_TxFNum_MASK (0x1f << 6)
68#define S3C_GRSTCTL_TxFNum_SHIFT (6)
69#define S3C_GRSTCTL_TxFNum_LIMIT (0x1f)
70#define S3C_GRSTCTL_TxFNum(_x) ((_x) << 6)
71#define S3C_GRSTCTL_TxFFlsh (1 << 5)
72#define S3C_GRSTCTL_RxFFlsh (1 << 4)
73#define S3C_GRSTCTL_INTknQFlsh (1 << 3)
74#define S3C_GRSTCTL_FrmCntrRst (1 << 2)
75#define S3C_GRSTCTL_HSftRst (1 << 1)
76#define S3C_GRSTCTL_CSftRst (1 << 0)
77
78#define S3C_GINTSTS S3C_HSOTG_REG(0x014)
79#define S3C_GINTMSK S3C_HSOTG_REG(0x018)
80
81#define S3C_GINTSTS_WkUpInt (1 << 31)
82#define S3C_GINTSTS_SessReqInt (1 << 30)
83#define S3C_GINTSTS_DisconnInt (1 << 29)
84#define S3C_GINTSTS_ConIDStsChng (1 << 28)
85#define S3C_GINTSTS_PTxFEmp (1 << 26)
86#define S3C_GINTSTS_HChInt (1 << 25)
87#define S3C_GINTSTS_PrtInt (1 << 24)
88#define S3C_GINTSTS_FetSusp (1 << 22)
89#define S3C_GINTSTS_incompIP (1 << 21)
90#define S3C_GINTSTS_IncomplSOIN (1 << 20)
91#define S3C_GINTSTS_OEPInt (1 << 19)
92#define S3C_GINTSTS_IEPInt (1 << 18)
93#define S3C_GINTSTS_EPMis (1 << 17)
94#define S3C_GINTSTS_EOPF (1 << 15)
95#define S3C_GINTSTS_ISOutDrop (1 << 14)
96#define S3C_GINTSTS_EnumDone (1 << 13)
97#define S3C_GINTSTS_USBRst (1 << 12)
98#define S3C_GINTSTS_USBSusp (1 << 11)
99#define S3C_GINTSTS_ErlySusp (1 << 10)
100#define S3C_GINTSTS_GOUTNakEff (1 << 7)
101#define S3C_GINTSTS_GINNakEff (1 << 6)
102#define S3C_GINTSTS_NPTxFEmp (1 << 5)
103#define S3C_GINTSTS_RxFLvl (1 << 4)
104#define S3C_GINTSTS_SOF (1 << 3)
105#define S3C_GINTSTS_OTGInt (1 << 2)
106#define S3C_GINTSTS_ModeMis (1 << 1)
107#define S3C_GINTSTS_CurMod_Host (1 << 0)
108
109#define S3C_GRXSTSR S3C_HSOTG_REG(0x01C)
110#define S3C_GRXSTSP S3C_HSOTG_REG(0x020)
111
112#define S3C_GRXSTS_FN_MASK (0x7f << 25)
113#define S3C_GRXSTS_FN_SHIFT (25)
114
115#define S3C_GRXSTS_PktSts_MASK (0xf << 17)
116#define S3C_GRXSTS_PktSts_SHIFT (17)
117#define S3C_GRXSTS_PktSts_GlobalOutNAK (0x1 << 17)
118#define S3C_GRXSTS_PktSts_OutRX (0x2 << 17)
119#define S3C_GRXSTS_PktSts_OutDone (0x3 << 17)
120#define S3C_GRXSTS_PktSts_SetupDone (0x4 << 17)
121#define S3C_GRXSTS_PktSts_SetupRX (0x6 << 17)
122
123#define S3C_GRXSTS_DPID_MASK (0x3 << 15)
124#define S3C_GRXSTS_DPID_SHIFT (15)
125#define S3C_GRXSTS_ByteCnt_MASK (0x7ff << 4)
126#define S3C_GRXSTS_ByteCnt_SHIFT (4)
127#define S3C_GRXSTS_EPNum_MASK (0xf << 0)
128#define S3C_GRXSTS_EPNum_SHIFT (0)
129
130#define S3C_GRXFSIZ S3C_HSOTG_REG(0x024)
131
132#define S3C_GNPTXFSIZ S3C_HSOTG_REG(0x028)
133
134#define S3C_GNPTXFSIZ_NPTxFDep_MASK (0xffff << 16)
135#define S3C_GNPTXFSIZ_NPTxFDep_SHIFT (16)
136#define S3C_GNPTXFSIZ_NPTxFDep_LIMIT (0xffff)
137#define S3C_GNPTXFSIZ_NPTxFDep(_x) ((_x) << 16)
138#define S3C_GNPTXFSIZ_NPTxFStAddr_MASK (0xffff << 0)
139#define S3C_GNPTXFSIZ_NPTxFStAddr_SHIFT (0)
140#define S3C_GNPTXFSIZ_NPTxFStAddr_LIMIT (0xffff)
141#define S3C_GNPTXFSIZ_NPTxFStAddr(_x) ((_x) << 0)
142
143#define S3C_GNPTXSTS S3C_HSOTG_REG(0x02C)
144
145#define S3C_GNPTXSTS_NPtxQTop_MASK (0x7f << 24)
146#define S3C_GNPTXSTS_NPtxQTop_SHIFT (24)
147
148#define S3C_GNPTXSTS_NPTxQSpcAvail_MASK (0xff << 16)
149#define S3C_GNPTXSTS_NPTxQSpcAvail_SHIFT (16)
150#define S3C_GNPTXSTS_NPTxQSpcAvail_GET(_v) (((_v) >> 16) & 0xff)
151
152#define S3C_GNPTXSTS_NPTxFSpcAvail_MASK (0xffff << 0)
153#define S3C_GNPTXSTS_NPTxFSpcAvail_SHIFT (0)
154#define S3C_GNPTXSTS_NPTxFSpcAvail_GET(_v) (((_v) >> 0) & 0xffff)
155
156
157#define S3C_HPTXFSIZ S3C_HSOTG_REG(0x100)
158
159#define S3C_DPTXFSIZn(_a) S3C_HSOTG_REG(0x104 + (((_a) - 1) * 4))
160
161#define S3C_DPTXFSIZn_DPTxFSize_MASK (0xffff << 16)
162#define S3C_DPTXFSIZn_DPTxFSize_SHIFT (16)
163#define S3C_DPTXFSIZn_DPTxFSize_GET(_v) (((_v) >> 16) & 0xffff)
164#define S3C_DPTXFSIZn_DPTxFSize_LIMIT (0xffff)
165#define S3C_DPTXFSIZn_DPTxFSize(_x) ((_x) << 16)
166
167#define S3C_DPTXFSIZn_DPTxFStAddr_MASK (0xffff << 0)
168#define S3C_DPTXFSIZn_DPTxFStAddr_SHIFT (0)
169
170/* Device mode registers */
171#define S3C_DCFG S3C_HSOTG_REG(0x800)
172
173#define S3C_DCFG_EPMisCnt_MASK (0x1f << 18)
174#define S3C_DCFG_EPMisCnt_SHIFT (18)
175#define S3C_DCFG_EPMisCnt_LIMIT (0x1f)
176#define S3C_DCFG_EPMisCnt(_x) ((_x) << 18)
177
178#define S3C_DCFG_PerFrInt_MASK (0x3 << 11)
179#define S3C_DCFG_PerFrInt_SHIFT (11)
180#define S3C_DCFG_PerFrInt_LIMIT (0x3)
181#define S3C_DCFG_PerFrInt(_x) ((_x) << 11)
182
183#define S3C_DCFG_DevAddr_MASK (0x7f << 4)
184#define S3C_DCFG_DevAddr_SHIFT (4)
185#define S3C_DCFG_DevAddr_LIMIT (0x7f)
186#define S3C_DCFG_DevAddr(_x) ((_x) << 4)
187
188#define S3C_DCFG_NZStsOUTHShk (1 << 2)
189
190#define S3C_DCFG_DevSpd_MASK (0x3 << 0)
191#define S3C_DCFG_DevSpd_SHIFT (0)
192#define S3C_DCFG_DevSpd_HS (0x0 << 0)
193#define S3C_DCFG_DevSpd_FS (0x1 << 0)
194#define S3C_DCFG_DevSpd_LS (0x2 << 0)
195#define S3C_DCFG_DevSpd_FS48 (0x3 << 0)
196
197#define S3C_DCTL S3C_HSOTG_REG(0x804)
198
199#define S3C_DCTL_PWROnPrgDone (1 << 11)
200#define S3C_DCTL_CGOUTNak (1 << 10)
201#define S3C_DCTL_SGOUTNak (1 << 9)
202#define S3C_DCTL_CGNPInNAK (1 << 8)
203#define S3C_DCTL_SGNPInNAK (1 << 7)
204#define S3C_DCTL_TstCtl_MASK (0x7 << 4)
205#define S3C_DCTL_TstCtl_SHIFT (4)
206#define S3C_DCTL_GOUTNakSts (1 << 3)
207#define S3C_DCTL_GNPINNakSts (1 << 2)
208#define S3C_DCTL_SftDiscon (1 << 1)
209#define S3C_DCTL_RmtWkUpSig (1 << 0)
210
211#define S3C_DSTS S3C_HSOTG_REG(0x808)
212
213#define S3C_DSTS_SOFFN_MASK (0x3fff << 8)
214#define S3C_DSTS_SOFFN_SHIFT (8)
215#define S3C_DSTS_SOFFN_LIMIT (0x3fff)
216#define S3C_DSTS_SOFFN(_x) ((_x) << 8)
217#define S3C_DSTS_ErraticErr (1 << 3)
218#define S3C_DSTS_EnumSpd_MASK (0x3 << 1)
219#define S3C_DSTS_EnumSpd_SHIFT (1)
220#define S3C_DSTS_EnumSpd_HS (0x0 << 1)
221#define S3C_DSTS_EnumSpd_FS (0x1 << 1)
222#define S3C_DSTS_EnumSpd_LS (0x2 << 1)
223#define S3C_DSTS_EnumSpd_FS48 (0x3 << 1)
224
225#define S3C_DSTS_SuspSts (1 << 0)
226
227#define S3C_DIEPMSK S3C_HSOTG_REG(0x810)
228
229#define S3C_DIEPMSK_TxFIFOEmpty (1 << 7)
230#define S3C_DIEPMSK_INEPNakEffMsk (1 << 6)
231#define S3C_DIEPMSK_INTknEPMisMsk (1 << 5)
232#define S3C_DIEPMSK_INTknTXFEmpMsk (1 << 4)
233#define S3C_DIEPMSK_TimeOUTMsk (1 << 3)
234#define S3C_DIEPMSK_AHBErrMsk (1 << 2)
235#define S3C_DIEPMSK_EPDisbldMsk (1 << 1)
236#define S3C_DIEPMSK_XferComplMsk (1 << 0)
237
238#define S3C_DOEPMSK S3C_HSOTG_REG(0x814)
239
240#define S3C_DOEPMSK_Back2BackSetup (1 << 6)
241#define S3C_DOEPMSK_OUTTknEPdisMsk (1 << 4)
242#define S3C_DOEPMSK_SetupMsk (1 << 3)
243#define S3C_DOEPMSK_AHBErrMsk (1 << 2)
244#define S3C_DOEPMSK_EPDisbldMsk (1 << 1)
245#define S3C_DOEPMSK_XferComplMsk (1 << 0)
246
247#define S3C_DAINT S3C_HSOTG_REG(0x818)
248#define S3C_DAINTMSK S3C_HSOTG_REG(0x81C)
249
250#define S3C_DAINT_OutEP_SHIFT (16)
251#define S3C_DAINT_OutEP(x) (1 << ((x) + 16))
252#define S3C_DAINT_InEP(x) (1 << (x))
253
254#define S3C_DTKNQR1 S3C_HSOTG_REG(0x820)
255#define S3C_DTKNQR2 S3C_HSOTG_REG(0x824)
256#define S3C_DTKNQR3 S3C_HSOTG_REG(0x830)
257#define S3C_DTKNQR4 S3C_HSOTG_REG(0x834)
258
259#define S3C_DVBUSDIS S3C_HSOTG_REG(0x828)
260#define S3C_DVBUSPULSE S3C_HSOTG_REG(0x82C)
261
262#define S3C_DIEPCTL0 S3C_HSOTG_REG(0x900)
263#define S3C_DOEPCTL0 S3C_HSOTG_REG(0xB00)
264#define S3C_DIEPCTL(_a) S3C_HSOTG_REG(0x900 + ((_a) * 0x20))
265#define S3C_DOEPCTL(_a) S3C_HSOTG_REG(0xB00 + ((_a) * 0x20))
266
267/* EP0 specialness:
268 * bits[29..28] - reserved (no SetD0PID, SetD1PID)
269 * bits[25..22] - should always be zero, this isn't a periodic endpoint
270 * bits[10..0] - MPS setting differenct for EP0
271*/
272#define S3C_D0EPCTL_MPS_MASK (0x3 << 0)
273#define S3C_D0EPCTL_MPS_SHIFT (0)
274#define S3C_D0EPCTL_MPS_64 (0x0 << 0)
275#define S3C_D0EPCTL_MPS_32 (0x1 << 0)
276#define S3C_D0EPCTL_MPS_16 (0x2 << 0)
277#define S3C_D0EPCTL_MPS_8 (0x3 << 0)
278
279#define S3C_DxEPCTL_EPEna (1 << 31)
280#define S3C_DxEPCTL_EPDis (1 << 30)
281#define S3C_DxEPCTL_SetD1PID (1 << 29)
282#define S3C_DxEPCTL_SetOddFr (1 << 29)
283#define S3C_DxEPCTL_SetD0PID (1 << 28)
284#define S3C_DxEPCTL_SetEvenFr (1 << 28)
285#define S3C_DxEPCTL_SNAK (1 << 27)
286#define S3C_DxEPCTL_CNAK (1 << 26)
287#define S3C_DxEPCTL_TxFNum_MASK (0xf << 22)
288#define S3C_DxEPCTL_TxFNum_SHIFT (22)
289#define S3C_DxEPCTL_TxFNum_LIMIT (0xf)
290#define S3C_DxEPCTL_TxFNum(_x) ((_x) << 22)
291
292#define S3C_DxEPCTL_Stall (1 << 21)
293#define S3C_DxEPCTL_Snp (1 << 20)
294#define S3C_DxEPCTL_EPType_MASK (0x3 << 18)
295#define S3C_DxEPCTL_EPType_SHIFT (18)
296#define S3C_DxEPCTL_EPType_Control (0x0 << 18)
297#define S3C_DxEPCTL_EPType_Iso (0x1 << 18)
298#define S3C_DxEPCTL_EPType_Bulk (0x2 << 18)
299#define S3C_DxEPCTL_EPType_Intterupt (0x3 << 18)
300
301#define S3C_DxEPCTL_NAKsts (1 << 17)
302#define S3C_DxEPCTL_DPID (1 << 16)
303#define S3C_DxEPCTL_EOFrNum (1 << 16)
304#define S3C_DxEPCTL_USBActEp (1 << 15)
305#define S3C_DxEPCTL_NextEp_MASK (0xf << 11)
306#define S3C_DxEPCTL_NextEp_SHIFT (11)
307#define S3C_DxEPCTL_NextEp_LIMIT (0xf)
308#define S3C_DxEPCTL_NextEp(_x) ((_x) << 11)
309
310#define S3C_DxEPCTL_MPS_MASK (0x7ff << 0)
311#define S3C_DxEPCTL_MPS_SHIFT (0)
312#define S3C_DxEPCTL_MPS_LIMIT (0x7ff)
313#define S3C_DxEPCTL_MPS(_x) ((_x) << 0)
314
315#define S3C_DIEPINT(_a) S3C_HSOTG_REG(0x908 + ((_a) * 0x20))
316#define S3C_DOEPINT(_a) S3C_HSOTG_REG(0xB08 + ((_a) * 0x20))
317
318#define S3C_DxEPINT_INEPNakEff (1 << 6)
319#define S3C_DxEPINT_Back2BackSetup (1 << 6)
320#define S3C_DxEPINT_INTknEPMis (1 << 5)
321#define S3C_DxEPINT_INTknTXFEmp (1 << 4)
322#define S3C_DxEPINT_OUTTknEPdis (1 << 4)
323#define S3C_DxEPINT_Timeout (1 << 3)
324#define S3C_DxEPINT_Setup (1 << 3)
325#define S3C_DxEPINT_AHBErr (1 << 2)
326#define S3C_DxEPINT_EPDisbld (1 << 1)
327#define S3C_DxEPINT_XferCompl (1 << 0)
328
329#define S3C_DIEPTSIZ0 S3C_HSOTG_REG(0x910)
330
331#define S3C_DIEPTSIZ0_PktCnt_MASK (0x3 << 19)
332#define S3C_DIEPTSIZ0_PktCnt_SHIFT (19)
333#define S3C_DIEPTSIZ0_PktCnt_LIMIT (0x3)
334#define S3C_DIEPTSIZ0_PktCnt(_x) ((_x) << 19)
335
336#define S3C_DIEPTSIZ0_XferSize_MASK (0x7f << 0)
337#define S3C_DIEPTSIZ0_XferSize_SHIFT (0)
338#define S3C_DIEPTSIZ0_XferSize_LIMIT (0x7f)
339#define S3C_DIEPTSIZ0_XferSize(_x) ((_x) << 0)
340
341
342#define DOEPTSIZ0 S3C_HSOTG_REG(0xB10)
343#define S3C_DOEPTSIZ0_SUPCnt_MASK (0x3 << 29)
344#define S3C_DOEPTSIZ0_SUPCnt_SHIFT (29)
345#define S3C_DOEPTSIZ0_SUPCnt_LIMIT (0x3)
346#define S3C_DOEPTSIZ0_SUPCnt(_x) ((_x) << 29)
347
348#define S3C_DOEPTSIZ0_PktCnt (1 << 19)
349#define S3C_DOEPTSIZ0_XferSize_MASK (0x7f << 0)
350#define S3C_DOEPTSIZ0_XferSize_SHIFT (0)
351
352#define S3C_DIEPTSIZ(_a) S3C_HSOTG_REG(0x910 + ((_a) * 0x20))
353#define S3C_DOEPTSIZ(_a) S3C_HSOTG_REG(0xB10 + ((_a) * 0x20))
354
355#define S3C_DxEPTSIZ_MC_MASK (0x3 << 29)
356#define S3C_DxEPTSIZ_MC_SHIFT (29)
357#define S3C_DxEPTSIZ_MC_LIMIT (0x3)
358#define S3C_DxEPTSIZ_MC(_x) ((_x) << 29)
359
360#define S3C_DxEPTSIZ_PktCnt_MASK (0x3ff << 19)
361#define S3C_DxEPTSIZ_PktCnt_SHIFT (19)
362#define S3C_DxEPTSIZ_PktCnt_GET(_v) (((_v) >> 19) & 0x3ff)
363#define S3C_DxEPTSIZ_PktCnt_LIMIT (0x3ff)
364#define S3C_DxEPTSIZ_PktCnt(_x) ((_x) << 19)
365
366#define S3C_DxEPTSIZ_XferSize_MASK (0x7ffff << 0)
367#define S3C_DxEPTSIZ_XferSize_SHIFT (0)
368#define S3C_DxEPTSIZ_XferSize_GET(_v) (((_v) >> 0) & 0x7ffff)
369#define S3C_DxEPTSIZ_XferSize_LIMIT (0x7ffff)
370#define S3C_DxEPTSIZ_XferSize(_x) ((_x) << 0)
371
372
373#define S3C_DIEPDMA(_a) S3C_HSOTG_REG(0x914 + ((_a) * 0x20))
374#define S3C_DOEPDMA(_a) S3C_HSOTG_REG(0xB14 + ((_a) * 0x20))
375#define S3C_DTXFSTS(_a) S3C_HSOTG_REG(0x918 + ((_a) * 0x20))
376
377#define S3C_EPFIFO(_a) S3C_HSOTG_REG(0x1000 + ((_a) * 0x1000))
378
379#endif /* __PLAT_S3C64XX_REGS_USB_HSOTG_H */
diff --git a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
new file mode 100644
index 00000000000..81074421312
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
@@ -0,0 +1,98 @@
1/*
2 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
3 * Jaswinder Singh <jassi.brar@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#ifndef __S3C_DMA_PL330_H_
12#define __S3C_DMA_PL330_H_
13
14#define S3C2410_DMAF_AUTOSTART (1 << 0)
15#define S3C2410_DMAF_CIRCULAR (1 << 1)
16
17/*
18 * PL330 can assign any channel to communicate with
19 * any of the peripherals attched to the DMAC.
20 * For the sake of consistency across client drivers,
21 * We keep the channel names unchanged and only add
22 * missing peripherals are added.
23 * Order is not important since S3C PL330 API driver
24 * use these just as IDs.
25 */
26enum dma_ch {
27 DMACH_UART0_RX,
28 DMACH_UART0_TX,
29 DMACH_UART1_RX,
30 DMACH_UART1_TX,
31 DMACH_UART2_RX,
32 DMACH_UART2_TX,
33 DMACH_UART3_RX,
34 DMACH_UART3_TX,
35 DMACH_UART4_RX,
36 DMACH_UART4_TX,
37 DMACH_UART5_RX,
38 DMACH_UART5_TX,
39 DMACH_USI_RX,
40 DMACH_USI_TX,
41 DMACH_IRDA,
42 DMACH_I2S0_RX,
43 DMACH_I2S0_TX,
44 DMACH_I2S0S_TX,
45 DMACH_I2S1_RX,
46 DMACH_I2S1_TX,
47 DMACH_I2S2_RX,
48 DMACH_I2S2_TX,
49 DMACH_SPI0_RX,
50 DMACH_SPI0_TX,
51 DMACH_SPI1_RX,
52 DMACH_SPI1_TX,
53 DMACH_SPI2_RX,
54 DMACH_SPI2_TX,
55 DMACH_AC97_MICIN,
56 DMACH_AC97_PCMIN,
57 DMACH_AC97_PCMOUT,
58 DMACH_EXTERNAL,
59 DMACH_PWM,
60 DMACH_SPDIF,
61 DMACH_HSI_RX,
62 DMACH_HSI_TX,
63 DMACH_PCM0_TX,
64 DMACH_PCM0_RX,
65 DMACH_PCM1_TX,
66 DMACH_PCM1_RX,
67 DMACH_PCM2_TX,
68 DMACH_PCM2_RX,
69 DMACH_MSM_REQ3,
70 DMACH_MSM_REQ2,
71 DMACH_MSM_REQ1,
72 DMACH_MSM_REQ0,
73 DMACH_SLIMBUS0_RX,
74 DMACH_SLIMBUS0_TX,
75 DMACH_SLIMBUS0AUX_RX,
76 DMACH_SLIMBUS0AUX_TX,
77 DMACH_SLIMBUS1_RX,
78 DMACH_SLIMBUS1_TX,
79 DMACH_SLIMBUS2_RX,
80 DMACH_SLIMBUS2_TX,
81 DMACH_SLIMBUS3_RX,
82 DMACH_SLIMBUS3_TX,
83 DMACH_SLIMBUS4_RX,
84 DMACH_SLIMBUS4_TX,
85 DMACH_SLIMBUS5_RX,
86 DMACH_SLIMBUS5_TX,
87 /* END Marker, also used to denote a reserved channel */
88 DMACH_MAX,
89};
90
91static inline bool s3c_dma_has_circular(void)
92{
93 return true;
94}
95
96#include <plat/dma.h>
97
98#endif /* __S3C_DMA_PL330_H_ */
diff --git a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
new file mode 100644
index 00000000000..bf5e2a9d408
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
@@ -0,0 +1,32 @@
1/* linux/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
2 *
3 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
4 * Jaswinder Singh <jassi.brar@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#ifndef __S3C_PL330_PDATA_H
13#define __S3C_PL330_PDATA_H
14
15#include <plat/s3c-dma-pl330.h>
16
17/*
18 * Every PL330 DMAC has max 32 peripheral interfaces,
19 * of which some may be not be really used in your
20 * DMAC's configuration.
21 * Populate this array of 32 peri i/fs with relevant
22 * channel IDs for used peri i/f and DMACH_MAX for
23 * those unused.
24 *
25 * The platforms just need to provide this info
26 * to the S3C DMA API driver for PL330.
27 */
28struct s3c_pl330_platdata {
29 enum dma_ch peri[32];
30};
31
32#endif /* __S3C_PL330_PDATA_H */
diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
new file mode 100644
index 00000000000..4c16fa3621b
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
@@ -0,0 +1,75 @@
1/* linux/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
2 *
3 * Copyright (C) 2009 Samsung Electronics 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#ifndef __S3C64XX_PLAT_SPI_H
12#define __S3C64XX_PLAT_SPI_H
13
14/**
15 * struct s3c64xx_spi_csinfo - ChipSelect description
16 * @fb_delay: Slave specific feedback delay.
17 * Refer to FB_CLK_SEL register definition in SPI chapter.
18 * @line: Custom 'identity' of the CS line.
19 * @set_level: CS line control.
20 *
21 * This is per SPI-Slave Chipselect information.
22 * Allocate and initialize one in machine init code and make the
23 * spi_board_info.controller_data point to it.
24 */
25struct s3c64xx_spi_csinfo {
26 u8 fb_delay;
27 unsigned line;
28 void (*set_level)(unsigned line_id, int lvl);
29};
30
31/**
32 * struct s3c64xx_spi_info - SPI Controller defining structure
33 * @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field.
34 * @src_clk_name: Platform name of the corresponding clock.
35 * @clk_from_cmu: If the SPI clock/prescalar control block is present
36 * by the platform's clock-management-unit and not in SPI controller.
37 * @num_cs: Number of CS this controller emulates.
38 * @cfg_gpio: Configure pins for this SPI controller.
39 * @fifo_lvl_mask: All tx fifo_lvl fields start at offset-6
40 * @rx_lvl_offset: Depends on tx fifo_lvl field and bus number
41 * @high_speed: If the controller supports HIGH_SPEED_EN bit
42 * @tx_st_done: Depends on tx fifo_lvl field
43 */
44struct s3c64xx_spi_info {
45 int src_clk_nr;
46 char *src_clk_name;
47 bool clk_from_cmu;
48
49 int num_cs;
50
51 int (*cfg_gpio)(struct platform_device *pdev);
52
53 /* Following two fields are for future compatibility */
54 int fifo_lvl_mask;
55 int rx_lvl_offset;
56 int high_speed;
57 int tx_st_done;
58};
59
60/**
61 * s3c64xx_spi_set_info - SPI Controller configure callback by the board
62 * initialization code.
63 * @cntrlr: SPI controller number the configuration is for.
64 * @src_clk_nr: Clock the SPI controller is to use to generate SPI clocks.
65 * @num_cs: Number of elements in the 'cs' array.
66 *
67 * Call this from machine init code for each SPI Controller that
68 * has some chips attached to it.
69 */
70extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
71extern void s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
72extern void s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
73extern void s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
74
75#endif /* __S3C64XX_PLAT_SPI_H */
diff --git a/arch/arm/plat-samsung/include/plat/ts.h b/arch/arm/plat-samsung/include/plat/ts.h
new file mode 100644
index 00000000000..26fdb22e0fc
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/ts.h
@@ -0,0 +1,25 @@
1/* arch/arm/plat-samsung/include/plat/ts.h
2 *
3 * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org>
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 version 2 as
7 * published by the Free Software Foundation.
8*/
9
10#ifndef __ASM_ARM_TS_H
11#define __ASM_ARM_TS_H
12
13struct s3c2410_ts_mach_info {
14 int delay;
15 int presc;
16 int oversampling_shift;
17 void (*cfg_gpio)(struct platform_device *dev);
18};
19
20extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *);
21
22/* defined by architecture to configure gpio */
23extern void s3c24xx_ts_cfg_gpio(struct platform_device *dev);
24
25#endif /* __ASM_ARM_TS_H */
diff --git a/arch/arm/plat-samsung/include/plat/udc-hs.h b/arch/arm/plat-samsung/include/plat/udc-hs.h
new file mode 100644
index 00000000000..a22a4f2eea9
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/udc-hs.h
@@ -0,0 +1,29 @@
1/* arch/arm/plat-s3c/include/plat/udc-hs.h
2 *
3 * Copyright 2008 Openmoko, Inc.
4 * Copyright 2008 Simtec Electronics
5 * Ben Dooks <ben@simtec.co.uk>
6 * http://armlinux.simtec.co.uk/
7 *
8 * S3C USB2.0 High-speed / OtG platform information
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15enum s3c_hsotg_dmamode {
16 S3C_HSOTG_DMA_NONE, /* do not use DMA at-all */
17 S3C_HSOTG_DMA_ONLY, /* always use DMA */
18 S3C_HSOTG_DMA_DRV, /* DMA is chosen by driver */
19};
20
21/**
22 * struct s3c_hsotg_plat - platform data for high-speed otg/udc
23 * @dma: Whether to use DMA or not.
24 * @is_osc: The clock source is an oscillator, not a crystal
25 */
26struct s3c_hsotg_plat {
27 enum s3c_hsotg_dmamode dma;
28 unsigned int is_osc : 1;
29};
diff --git a/arch/arm/plat-samsung/include/plat/usb-control.h b/arch/arm/plat-samsung/include/plat/usb-control.h
new file mode 100644
index 00000000000..7fa1fbefc3f
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/usb-control.h
@@ -0,0 +1,43 @@
1/* arch/arm/plat-samsung/include/plat/usb-control.h
2 *
3 * Copyright (c) 2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C - USB host port information
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#ifndef __ASM_ARCH_USBCONTROL_H
14#define __ASM_ARCH_USBCONTROL_H
15
16#define S3C_HCDFLG_USED (1)
17
18struct s3c2410_hcd_port {
19 unsigned char flags;
20 unsigned char power;
21 unsigned char oc_status;
22 unsigned char oc_changed;
23};
24
25struct s3c2410_hcd_info {
26 struct usb_hcd *hcd;
27 struct s3c2410_hcd_port port[2];
28
29 void (*power_control)(int port, int to);
30 void (*enable_oc)(struct s3c2410_hcd_info *, int on);
31 void (*report_oc)(struct s3c2410_hcd_info *, int ports);
32};
33
34static void inline s3c2410_usb_report_oc(struct s3c2410_hcd_info *info, int ports)
35{
36 if (info->report_oc != NULL) {
37 (info->report_oc)(info, ports);
38 }
39}
40
41extern void s3c_ohci_set_platdata(struct s3c2410_hcd_info *info);
42
43#endif /*__ASM_ARCH_USBCONTROL_H */
diff --git a/arch/arm/plat-samsung/irq-uart.c b/arch/arm/plat-samsung/irq-uart.c
new file mode 100644
index 00000000000..3014c7226bd
--- /dev/null
+++ b/arch/arm/plat-samsung/irq-uart.c
@@ -0,0 +1,96 @@
1/* arch/arm/plat-samsung/irq-uart.c
2 * originally part of arch/arm/plat-s3c64xx/irq.c
3 *
4 * Copyright 2008 Openmoko, Inc.
5 * Copyright 2008 Simtec Electronics
6 * Ben Dooks <ben@simtec.co.uk>
7 * http://armlinux.simtec.co.uk/
8 *
9 * Samsung- UART Interrupt handling
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/kernel.h>
17#include <linux/interrupt.h>
18#include <linux/serial_core.h>
19#include <linux/irq.h>
20#include <linux/io.h>
21
22#include <asm/mach/irq.h>
23
24#include <mach/map.h>
25#include <plat/irq-uart.h>
26#include <plat/regs-serial.h>
27#include <plat/cpu.h>
28
29/* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
30 * are consecutive when looking up the interrupt in the demux routines.
31 */
32static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
33{
34 struct s3c_uart_irq *uirq = desc->irq_data.handler_data;
35 struct irq_chip *chip = irq_get_chip(irq);
36 u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP);
37 int base = uirq->base_irq;
38
39 chained_irq_enter(chip, desc);
40
41 if (pend & (1 << 0))
42 generic_handle_irq(base);
43 if (pend & (1 << 1))
44 generic_handle_irq(base + 1);
45 if (pend & (1 << 2))
46 generic_handle_irq(base + 2);
47 if (pend & (1 << 3))
48 generic_handle_irq(base + 3);
49
50 chained_irq_exit(chip, desc);
51}
52
53static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
54{
55 void __iomem *reg_base = uirq->regs;
56 struct irq_chip_generic *gc;
57 struct irq_chip_type *ct;
58
59 /* mask all interrupts at the start. */
60 __raw_writel(0xf, reg_base + S3C64XX_UINTM);
61
62 gc = irq_alloc_generic_chip("s3c-uart", 1, uirq->base_irq, reg_base,
63 handle_level_irq);
64
65 if (!gc) {
66 pr_err("%s: irq_alloc_generic_chip for IRQ %u failed\n",
67 __func__, uirq->base_irq);
68 return;
69 }
70
71 ct = gc->chip_types;
72 ct->chip.irq_ack = irq_gc_ack_set_bit;
73 ct->chip.irq_mask = irq_gc_mask_set_bit;
74 ct->chip.irq_unmask = irq_gc_mask_clr_bit;
75 ct->regs.ack = S3C64XX_UINTP;
76 ct->regs.mask = S3C64XX_UINTM;
77 irq_setup_generic_chip(gc, IRQ_MSK(4), IRQ_GC_INIT_MASK_CACHE,
78 IRQ_NOREQUEST | IRQ_NOPROBE, 0);
79
80 irq_set_handler_data(uirq->parent_irq, uirq);
81 irq_set_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
82}
83
84/**
85 * s3c_init_uart_irqs() - initialise UART IRQs and the necessary demuxing
86 * @irq: The interrupt data for registering
87 * @nr_irqs: The number of interrupt descriptions in @irq.
88 *
89 * Register the UART interrupts specified by @irq including the demuxing
90 * routines. This supports the S3C6400 and newer style of devices.
91 */
92void __init s3c_init_uart_irqs(struct s3c_uart_irq *irq, unsigned int nr_irqs)
93{
94 for (; nr_irqs > 0; nr_irqs--, irq++)
95 s3c_init_uart_irq(irq);
96}
diff --git a/arch/arm/plat-samsung/pd.c b/arch/arm/plat-samsung/pd.c
new file mode 100644
index 00000000000..efe1d564473
--- /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/pwm.c b/arch/arm/plat-samsung/pwm.c
new file mode 100644
index 00000000000..f37457c5206
--- /dev/null
+++ b/arch/arm/plat-samsung/pwm.c
@@ -0,0 +1,413 @@
1/* arch/arm/plat-s3c/pwm.c
2 *
3 * Copyright (c) 2007 Ben Dooks
4 * Copyright (c) 2008 Simtec Electronics
5 * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
6 *
7 * S3C series PWM device core
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License.
12*/
13
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/platform_device.h>
17#include <linux/slab.h>
18#include <linux/err.h>
19#include <linux/clk.h>
20#include <linux/io.h>
21#include <linux/pwm.h>
22
23#include <mach/map.h>
24
25#include <plat/regs-timer.h>
26
27struct pwm_device {
28 struct list_head list;
29 struct platform_device *pdev;
30
31 struct clk *clk_div;
32 struct clk *clk;
33 const char *label;
34
35 unsigned int period_ns;
36 unsigned int duty_ns;
37
38 unsigned char tcon_base;
39 unsigned char running;
40 unsigned char use_count;
41 unsigned char pwm_id;
42};
43
44#define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg)
45
46static struct clk *clk_scaler[2];
47
48static inline int pwm_is_tdiv(struct pwm_device *pwm)
49{
50 return clk_get_parent(pwm->clk) == pwm->clk_div;
51}
52
53static DEFINE_MUTEX(pwm_lock);
54static LIST_HEAD(pwm_list);
55
56struct pwm_device *pwm_request(int pwm_id, const char *label)
57{
58 struct pwm_device *pwm;
59 int found = 0;
60
61 mutex_lock(&pwm_lock);
62
63 list_for_each_entry(pwm, &pwm_list, list) {
64 if (pwm->pwm_id == pwm_id) {
65 found = 1;
66 break;
67 }
68 }
69
70 if (found) {
71 if (pwm->use_count == 0) {
72 pwm->use_count = 1;
73 pwm->label = label;
74 } else
75 pwm = ERR_PTR(-EBUSY);
76 } else
77 pwm = ERR_PTR(-ENOENT);
78
79 mutex_unlock(&pwm_lock);
80 return pwm;
81}
82
83EXPORT_SYMBOL(pwm_request);
84
85
86void pwm_free(struct pwm_device *pwm)
87{
88 mutex_lock(&pwm_lock);
89
90 if (pwm->use_count) {
91 pwm->use_count--;
92 pwm->label = NULL;
93 } else
94 printk(KERN_ERR "PWM%d device already freed\n", pwm->pwm_id);
95
96 mutex_unlock(&pwm_lock);
97}
98
99EXPORT_SYMBOL(pwm_free);
100
101#define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0))
102#define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2))
103#define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3))
104#define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1))
105
106int pwm_enable(struct pwm_device *pwm)
107{
108 unsigned long flags;
109 unsigned long tcon;
110
111 local_irq_save(flags);
112
113 tcon = __raw_readl(S3C2410_TCON);
114 tcon |= pwm_tcon_start(pwm);
115 __raw_writel(tcon, S3C2410_TCON);
116
117 local_irq_restore(flags);
118
119 pwm->running = 1;
120 return 0;
121}
122
123EXPORT_SYMBOL(pwm_enable);
124
125void pwm_disable(struct pwm_device *pwm)
126{
127 unsigned long flags;
128 unsigned long tcon;
129
130 local_irq_save(flags);
131
132 tcon = __raw_readl(S3C2410_TCON);
133 tcon &= ~pwm_tcon_start(pwm);
134 __raw_writel(tcon, S3C2410_TCON);
135
136 local_irq_restore(flags);
137
138 pwm->running = 0;
139}
140
141EXPORT_SYMBOL(pwm_disable);
142
143static unsigned long pwm_calc_tin(struct pwm_device *pwm, unsigned long freq)
144{
145 unsigned long tin_parent_rate;
146 unsigned int div;
147
148 tin_parent_rate = clk_get_rate(clk_get_parent(pwm->clk_div));
149 pwm_dbg(pwm, "tin parent at %lu\n", tin_parent_rate);
150
151 for (div = 2; div <= 16; div *= 2) {
152 if ((tin_parent_rate / (div << 16)) < freq)
153 return tin_parent_rate / div;
154 }
155
156 return tin_parent_rate / 16;
157}
158
159#define NS_IN_HZ (1000000000UL)
160
161int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
162{
163 unsigned long tin_rate;
164 unsigned long tin_ns;
165 unsigned long period;
166 unsigned long flags;
167 unsigned long tcon;
168 unsigned long tcnt;
169 long tcmp;
170
171 /* We currently avoid using 64bit arithmetic by using the
172 * fact that anything faster than 1Hz is easily representable
173 * by 32bits. */
174
175 if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
176 return -ERANGE;
177
178 if (duty_ns > period_ns)
179 return -EINVAL;
180
181 if (period_ns == pwm->period_ns &&
182 duty_ns == pwm->duty_ns)
183 return 0;
184
185 /* The TCMP and TCNT can be read without a lock, they're not
186 * shared between the timers. */
187
188 tcmp = __raw_readl(S3C2410_TCMPB(pwm->pwm_id));
189 tcnt = __raw_readl(S3C2410_TCNTB(pwm->pwm_id));
190
191 period = NS_IN_HZ / period_ns;
192
193 pwm_dbg(pwm, "duty_ns=%d, period_ns=%d (%lu)\n",
194 duty_ns, period_ns, period);
195
196 /* Check to see if we are changing the clock rate of the PWM */
197
198 if (pwm->period_ns != period_ns) {
199 if (pwm_is_tdiv(pwm)) {
200 tin_rate = pwm_calc_tin(pwm, period);
201 clk_set_rate(pwm->clk_div, tin_rate);
202 } else
203 tin_rate = clk_get_rate(pwm->clk);
204
205 pwm->period_ns = period_ns;
206
207 pwm_dbg(pwm, "tin_rate=%lu\n", tin_rate);
208
209 tin_ns = NS_IN_HZ / tin_rate;
210 tcnt = period_ns / tin_ns;
211 } else
212 tin_ns = NS_IN_HZ / clk_get_rate(pwm->clk);
213
214 /* Note, counters count down */
215
216 tcmp = duty_ns / tin_ns;
217 tcmp = tcnt - tcmp;
218 /* the pwm hw only checks the compare register after a decrement,
219 so the pin never toggles if tcmp = tcnt */
220 if (tcmp == tcnt)
221 tcmp--;
222
223 pwm_dbg(pwm, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt);
224
225 if (tcmp < 0)
226 tcmp = 0;
227
228 /* Update the PWM register block. */
229
230 local_irq_save(flags);
231
232 __raw_writel(tcmp, S3C2410_TCMPB(pwm->pwm_id));
233 __raw_writel(tcnt, S3C2410_TCNTB(pwm->pwm_id));
234
235 tcon = __raw_readl(S3C2410_TCON);
236 tcon |= pwm_tcon_manulupdate(pwm);
237 tcon |= pwm_tcon_autoreload(pwm);
238 __raw_writel(tcon, S3C2410_TCON);
239
240 tcon &= ~pwm_tcon_manulupdate(pwm);
241 __raw_writel(tcon, S3C2410_TCON);
242
243 local_irq_restore(flags);
244
245 return 0;
246}
247
248EXPORT_SYMBOL(pwm_config);
249
250static int pwm_register(struct pwm_device *pwm)
251{
252 pwm->duty_ns = -1;
253 pwm->period_ns = -1;
254
255 mutex_lock(&pwm_lock);
256 list_add_tail(&pwm->list, &pwm_list);
257 mutex_unlock(&pwm_lock);
258
259 return 0;
260}
261
262static int s3c_pwm_probe(struct platform_device *pdev)
263{
264 struct device *dev = &pdev->dev;
265 struct pwm_device *pwm;
266 unsigned long flags;
267 unsigned long tcon;
268 unsigned int id = pdev->id;
269 int ret;
270
271 if (id == 4) {
272 dev_err(dev, "TIMER4 is currently not supported\n");
273 return -ENXIO;
274 }
275
276 pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
277 if (pwm == NULL) {
278 dev_err(dev, "failed to allocate pwm_device\n");
279 return -ENOMEM;
280 }
281
282 pwm->pdev = pdev;
283 pwm->pwm_id = id;
284
285 /* calculate base of control bits in TCON */
286 pwm->tcon_base = id == 0 ? 0 : (id * 4) + 4;
287
288 pwm->clk = clk_get(dev, "pwm-tin");
289 if (IS_ERR(pwm->clk)) {
290 dev_err(dev, "failed to get pwm tin clk\n");
291 ret = PTR_ERR(pwm->clk);
292 goto err_alloc;
293 }
294
295 pwm->clk_div = clk_get(dev, "pwm-tdiv");
296 if (IS_ERR(pwm->clk_div)) {
297 dev_err(dev, "failed to get pwm tdiv clk\n");
298 ret = PTR_ERR(pwm->clk_div);
299 goto err_clk_tin;
300 }
301
302 local_irq_save(flags);
303
304 tcon = __raw_readl(S3C2410_TCON);
305 tcon |= pwm_tcon_invert(pwm);
306 __raw_writel(tcon, S3C2410_TCON);
307
308 local_irq_restore(flags);
309
310
311 ret = pwm_register(pwm);
312 if (ret) {
313 dev_err(dev, "failed to register pwm\n");
314 goto err_clk_tdiv;
315 }
316
317 pwm_dbg(pwm, "config bits %02x\n",
318 (__raw_readl(S3C2410_TCON) >> pwm->tcon_base) & 0x0f);
319
320 dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n",
321 clk_get_rate(pwm->clk),
322 clk_get_rate(pwm->clk_div),
323 pwm_is_tdiv(pwm) ? "div" : "ext", pwm->tcon_base);
324
325 platform_set_drvdata(pdev, pwm);
326 return 0;
327
328 err_clk_tdiv:
329 clk_put(pwm->clk_div);
330
331 err_clk_tin:
332 clk_put(pwm->clk);
333
334 err_alloc:
335 kfree(pwm);
336 return ret;
337}
338
339static int __devexit s3c_pwm_remove(struct platform_device *pdev)
340{
341 struct pwm_device *pwm = platform_get_drvdata(pdev);
342
343 clk_put(pwm->clk_div);
344 clk_put(pwm->clk);
345 kfree(pwm);
346
347 return 0;
348}
349
350#ifdef CONFIG_PM
351static int s3c_pwm_suspend(struct platform_device *pdev, pm_message_t state)
352{
353 struct pwm_device *pwm = platform_get_drvdata(pdev);
354
355 /* No one preserve these values during suspend so reset them
356 * Otherwise driver leaves PWM unconfigured if same values
357 * passed to pwm_config
358 */
359 pwm->period_ns = 0;
360 pwm->duty_ns = 0;
361
362 return 0;
363}
364
365static int s3c_pwm_resume(struct platform_device *pdev)
366{
367 struct pwm_device *pwm = platform_get_drvdata(pdev);
368 unsigned long tcon;
369
370 /* Restore invertion */
371 tcon = __raw_readl(S3C2410_TCON);
372 tcon |= pwm_tcon_invert(pwm);
373 __raw_writel(tcon, S3C2410_TCON);
374
375 return 0;
376}
377
378#else
379#define s3c_pwm_suspend NULL
380#define s3c_pwm_resume NULL
381#endif
382
383static struct platform_driver s3c_pwm_driver = {
384 .driver = {
385 .name = "s3c24xx-pwm",
386 .owner = THIS_MODULE,
387 },
388 .probe = s3c_pwm_probe,
389 .remove = __devexit_p(s3c_pwm_remove),
390 .suspend = s3c_pwm_suspend,
391 .resume = s3c_pwm_resume,
392};
393
394static int __init pwm_init(void)
395{
396 int ret;
397
398 clk_scaler[0] = clk_get(NULL, "pwm-scaler0");
399 clk_scaler[1] = clk_get(NULL, "pwm-scaler1");
400
401 if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) {
402 printk(KERN_ERR "%s: failed to get scaler clocks\n", __func__);
403 return -EINVAL;
404 }
405
406 ret = platform_driver_register(&s3c_pwm_driver);
407 if (ret)
408 printk(KERN_ERR "%s: failed to add pwm driver\n", __func__);
409
410 return ret;
411}
412
413arch_initcall(pwm_init);
diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c
new file mode 100644
index 00000000000..f85638c6f5a
--- /dev/null
+++ b/arch/arm/plat-samsung/s3c-pl330.c
@@ -0,0 +1,1244 @@
1/* linux/arch/arm/plat-samsung/s3c-pl330.c
2 *
3 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
4 * Jaswinder Singh <jassi.brar@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/interrupt.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include <linux/platform_device.h>
18#include <linux/clk.h>
19#include <linux/err.h>
20
21#include <asm/hardware/pl330.h>
22
23#include <plat/s3c-pl330-pdata.h>
24
25/**
26 * struct s3c_pl330_dmac - Logical representation of a PL330 DMAC.
27 * @busy_chan: Number of channels currently busy.
28 * @peri: List of IDs of peripherals this DMAC can work with.
29 * @node: To attach to the global list of DMACs.
30 * @pi: PL330 configuration info for the DMAC.
31 * @kmcache: Pool to quickly allocate xfers for all channels in the dmac.
32 * @clk: Pointer of DMAC operation clock.
33 */
34struct s3c_pl330_dmac {
35 unsigned busy_chan;
36 enum dma_ch *peri;
37 struct list_head node;
38 struct pl330_info *pi;
39 struct kmem_cache *kmcache;
40 struct clk *clk;
41};
42
43/**
44 * struct s3c_pl330_xfer - A request submitted by S3C DMA clients.
45 * @token: Xfer ID provided by the client.
46 * @node: To attach to the list of xfers on a channel.
47 * @px: Xfer for PL330 core.
48 * @chan: Owner channel of this xfer.
49 */
50struct s3c_pl330_xfer {
51 void *token;
52 struct list_head node;
53 struct pl330_xfer px;
54 struct s3c_pl330_chan *chan;
55};
56
57/**
58 * struct s3c_pl330_chan - Logical channel to communicate with
59 * a Physical peripheral.
60 * @pl330_chan_id: Token of a hardware channel thread of PL330 DMAC.
61 * NULL if the channel is available to be acquired.
62 * @id: ID of the peripheral that this channel can communicate with.
63 * @options: Options specified by the client.
64 * @sdaddr: Address provided via s3c2410_dma_devconfig.
65 * @node: To attach to the global list of channels.
66 * @lrq: Pointer to the last submitted pl330_req to PL330 core.
67 * @xfer_list: To manage list of xfers enqueued.
68 * @req: Two requests to communicate with the PL330 engine.
69 * @callback_fn: Callback function to the client.
70 * @rqcfg: Channel configuration for the xfers.
71 * @xfer_head: Pointer to the xfer to be next executed.
72 * @dmac: Pointer to the DMAC that manages this channel, NULL if the
73 * channel is available to be acquired.
74 * @client: Client of this channel. NULL if the
75 * channel is available to be acquired.
76 */
77struct s3c_pl330_chan {
78 void *pl330_chan_id;
79 enum dma_ch id;
80 unsigned int options;
81 unsigned long sdaddr;
82 struct list_head node;
83 struct pl330_req *lrq;
84 struct list_head xfer_list;
85 struct pl330_req req[2];
86 s3c2410_dma_cbfn_t callback_fn;
87 struct pl330_reqcfg rqcfg;
88 struct s3c_pl330_xfer *xfer_head;
89 struct s3c_pl330_dmac *dmac;
90 struct s3c2410_dma_client *client;
91};
92
93/* All DMACs in the platform */
94static LIST_HEAD(dmac_list);
95
96/* All channels to peripherals in the platform */
97static LIST_HEAD(chan_list);
98
99/*
100 * Since we add resources(DMACs and Channels) to the global pool,
101 * we need to guard access to the resources using a global lock
102 */
103static DEFINE_SPINLOCK(res_lock);
104
105/* Returns the channel with ID 'id' in the chan_list */
106static struct s3c_pl330_chan *id_to_chan(const enum dma_ch id)
107{
108 struct s3c_pl330_chan *ch;
109
110 list_for_each_entry(ch, &chan_list, node)
111 if (ch->id == id)
112 return ch;
113
114 return NULL;
115}
116
117/* Allocate a new channel with ID 'id' and add to chan_list */
118static void chan_add(const enum dma_ch id)
119{
120 struct s3c_pl330_chan *ch = id_to_chan(id);
121
122 /* Return if the channel already exists */
123 if (ch)
124 return;
125
126 ch = kmalloc(sizeof(*ch), GFP_KERNEL);
127 /* Return silently to work with other channels */
128 if (!ch)
129 return;
130
131 ch->id = id;
132 ch->dmac = NULL;
133
134 list_add_tail(&ch->node, &chan_list);
135}
136
137/* If the channel is not yet acquired by any client */
138static bool chan_free(struct s3c_pl330_chan *ch)
139{
140 if (!ch)
141 return false;
142
143 /* Channel points to some DMAC only when it's acquired */
144 return ch->dmac ? false : true;
145}
146
147/*
148 * Returns 0 is peripheral i/f is invalid or not present on the dmac.
149 * Index + 1, otherwise.
150 */
151static unsigned iface_of_dmac(struct s3c_pl330_dmac *dmac, enum dma_ch ch_id)
152{
153 enum dma_ch *id = dmac->peri;
154 int i;
155
156 /* Discount invalid markers */
157 if (ch_id == DMACH_MAX)
158 return 0;
159
160 for (i = 0; i < PL330_MAX_PERI; i++)
161 if (id[i] == ch_id)
162 return i + 1;
163
164 return 0;
165}
166
167/* If all channel threads of the DMAC are busy */
168static inline bool dmac_busy(struct s3c_pl330_dmac *dmac)
169{
170 struct pl330_info *pi = dmac->pi;
171
172 return (dmac->busy_chan < pi->pcfg.num_chan) ? false : true;
173}
174
175/*
176 * Returns the number of free channels that
177 * can be handled by this dmac only.
178 */
179static unsigned ch_onlyby_dmac(struct s3c_pl330_dmac *dmac)
180{
181 enum dma_ch *id = dmac->peri;
182 struct s3c_pl330_dmac *d;
183 struct s3c_pl330_chan *ch;
184 unsigned found, count = 0;
185 enum dma_ch p;
186 int i;
187
188 for (i = 0; i < PL330_MAX_PERI; i++) {
189 p = id[i];
190 ch = id_to_chan(p);
191
192 if (p == DMACH_MAX || !chan_free(ch))
193 continue;
194
195 found = 0;
196 list_for_each_entry(d, &dmac_list, node) {
197 if (d != dmac && iface_of_dmac(d, ch->id)) {
198 found = 1;
199 break;
200 }
201 }
202 if (!found)
203 count++;
204 }
205
206 return count;
207}
208
209/*
210 * Measure of suitability of 'dmac' handling 'ch'
211 *
212 * 0 indicates 'dmac' can not handle 'ch' either
213 * because it is not supported by the hardware or
214 * because all dmac channels are currently busy.
215 *
216 * >0 vlaue indicates 'dmac' has the capability.
217 * The bigger the value the more suitable the dmac.
218 */
219#define MAX_SUIT UINT_MAX
220#define MIN_SUIT 0
221
222static unsigned suitablility(struct s3c_pl330_dmac *dmac,
223 struct s3c_pl330_chan *ch)
224{
225 struct pl330_info *pi = dmac->pi;
226 enum dma_ch *id = dmac->peri;
227 struct s3c_pl330_dmac *d;
228 unsigned s;
229 int i;
230
231 s = MIN_SUIT;
232 /* If all the DMAC channel threads are busy */
233 if (dmac_busy(dmac))
234 return s;
235
236 for (i = 0; i < PL330_MAX_PERI; i++)
237 if (id[i] == ch->id)
238 break;
239
240 /* If the 'dmac' can't talk to 'ch' */
241 if (i == PL330_MAX_PERI)
242 return s;
243
244 s = MAX_SUIT;
245 list_for_each_entry(d, &dmac_list, node) {
246 /*
247 * If some other dmac can talk to this
248 * peri and has some channel free.
249 */
250 if (d != dmac && iface_of_dmac(d, ch->id) && !dmac_busy(d)) {
251 s = 0;
252 break;
253 }
254 }
255 if (s)
256 return s;
257
258 s = 100;
259
260 /* Good if free chans are more, bad otherwise */
261 s += (pi->pcfg.num_chan - dmac->busy_chan) - ch_onlyby_dmac(dmac);
262
263 return s;
264}
265
266/* More than one DMAC may have capability to transfer data with the
267 * peripheral. This function assigns most suitable DMAC to manage the
268 * channel and hence communicate with the peripheral.
269 */
270static struct s3c_pl330_dmac *map_chan_to_dmac(struct s3c_pl330_chan *ch)
271{
272 struct s3c_pl330_dmac *d, *dmac = NULL;
273 unsigned sn, sl = MIN_SUIT;
274
275 list_for_each_entry(d, &dmac_list, node) {
276 sn = suitablility(d, ch);
277
278 if (sn == MAX_SUIT)
279 return d;
280
281 if (sn > sl)
282 dmac = d;
283 }
284
285 return dmac;
286}
287
288/* Acquire the channel for peripheral 'id' */
289static struct s3c_pl330_chan *chan_acquire(const enum dma_ch id)
290{
291 struct s3c_pl330_chan *ch = id_to_chan(id);
292 struct s3c_pl330_dmac *dmac;
293
294 /* If the channel doesn't exist or is already acquired */
295 if (!ch || !chan_free(ch)) {
296 ch = NULL;
297 goto acq_exit;
298 }
299
300 dmac = map_chan_to_dmac(ch);
301 /* If couldn't map */
302 if (!dmac) {
303 ch = NULL;
304 goto acq_exit;
305 }
306
307 dmac->busy_chan++;
308 ch->dmac = dmac;
309
310acq_exit:
311 return ch;
312}
313
314/* Delete xfer from the queue */
315static inline void del_from_queue(struct s3c_pl330_xfer *xfer)
316{
317 struct s3c_pl330_xfer *t;
318 struct s3c_pl330_chan *ch;
319 int found;
320
321 if (!xfer)
322 return;
323
324 ch = xfer->chan;
325
326 /* Make sure xfer is in the queue */
327 found = 0;
328 list_for_each_entry(t, &ch->xfer_list, node)
329 if (t == xfer) {
330 found = 1;
331 break;
332 }
333
334 if (!found)
335 return;
336
337 /* If xfer is last entry in the queue */
338 if (xfer->node.next == &ch->xfer_list)
339 t = list_entry(ch->xfer_list.next,
340 struct s3c_pl330_xfer, node);
341 else
342 t = list_entry(xfer->node.next,
343 struct s3c_pl330_xfer, node);
344
345 /* If there was only one node left */
346 if (t == xfer)
347 ch->xfer_head = NULL;
348 else if (ch->xfer_head == xfer)
349 ch->xfer_head = t;
350
351 list_del(&xfer->node);
352}
353
354/* Provides pointer to the next xfer in the queue.
355 * If CIRCULAR option is set, the list is left intact,
356 * otherwise the xfer is removed from the list.
357 * Forced delete 'pluck' can be set to override the CIRCULAR option.
358 */
359static struct s3c_pl330_xfer *get_from_queue(struct s3c_pl330_chan *ch,
360 int pluck)
361{
362 struct s3c_pl330_xfer *xfer = ch->xfer_head;
363
364 if (!xfer)
365 return NULL;
366
367 /* If xfer is last entry in the queue */
368 if (xfer->node.next == &ch->xfer_list)
369 ch->xfer_head = list_entry(ch->xfer_list.next,
370 struct s3c_pl330_xfer, node);
371 else
372 ch->xfer_head = list_entry(xfer->node.next,
373 struct s3c_pl330_xfer, node);
374
375 if (pluck || !(ch->options & S3C2410_DMAF_CIRCULAR))
376 del_from_queue(xfer);
377
378 return xfer;
379}
380
381static inline void add_to_queue(struct s3c_pl330_chan *ch,
382 struct s3c_pl330_xfer *xfer, int front)
383{
384 struct pl330_xfer *xt;
385
386 /* If queue empty */
387 if (ch->xfer_head == NULL)
388 ch->xfer_head = xfer;
389
390 xt = &ch->xfer_head->px;
391 /* If the head already submitted (CIRCULAR head) */
392 if (ch->options & S3C2410_DMAF_CIRCULAR &&
393 (xt == ch->req[0].x || xt == ch->req[1].x))
394 ch->xfer_head = xfer;
395
396 /* If this is a resubmission, it should go at the head */
397 if (front) {
398 ch->xfer_head = xfer;
399 list_add(&xfer->node, &ch->xfer_list);
400 } else {
401 list_add_tail(&xfer->node, &ch->xfer_list);
402 }
403}
404
405static inline void _finish_off(struct s3c_pl330_xfer *xfer,
406 enum s3c2410_dma_buffresult res, int ffree)
407{
408 struct s3c_pl330_chan *ch;
409
410 if (!xfer)
411 return;
412
413 ch = xfer->chan;
414
415 /* Do callback */
416 if (ch->callback_fn)
417 ch->callback_fn(NULL, xfer->token, xfer->px.bytes, res);
418
419 /* Force Free or if buffer is not needed anymore */
420 if (ffree || !(ch->options & S3C2410_DMAF_CIRCULAR))
421 kmem_cache_free(ch->dmac->kmcache, xfer);
422}
423
424static inline int s3c_pl330_submit(struct s3c_pl330_chan *ch,
425 struct pl330_req *r)
426{
427 struct s3c_pl330_xfer *xfer;
428 int ret = 0;
429
430 /* If already submitted */
431 if (r->x)
432 return 0;
433
434 xfer = get_from_queue(ch, 0);
435 if (xfer) {
436 r->x = &xfer->px;
437
438 /* Use max bandwidth for M<->M xfers */
439 if (r->rqtype == MEMTOMEM) {
440 struct pl330_info *pi = xfer->chan->dmac->pi;
441 int burst = 1 << ch->rqcfg.brst_size;
442 u32 bytes = r->x->bytes;
443 int bl;
444
445 bl = pi->pcfg.data_bus_width / 8;
446 bl *= pi->pcfg.data_buf_dep;
447 bl /= burst;
448
449 /* src/dst_burst_len can't be more than 16 */
450 if (bl > 16)
451 bl = 16;
452
453 while (bl > 1) {
454 if (!(bytes % (bl * burst)))
455 break;
456 bl--;
457 }
458
459 ch->rqcfg.brst_len = bl;
460 } else {
461 ch->rqcfg.brst_len = 1;
462 }
463
464 ret = pl330_submit_req(ch->pl330_chan_id, r);
465
466 /* If submission was successful */
467 if (!ret) {
468 ch->lrq = r; /* latest submitted req */
469 return 0;
470 }
471
472 r->x = NULL;
473
474 /* If both of the PL330 ping-pong buffers filled */
475 if (ret == -EAGAIN) {
476 dev_err(ch->dmac->pi->dev, "%s:%d!\n",
477 __func__, __LINE__);
478 /* Queue back again */
479 add_to_queue(ch, xfer, 1);
480 ret = 0;
481 } else {
482 dev_err(ch->dmac->pi->dev, "%s:%d!\n",
483 __func__, __LINE__);
484 _finish_off(xfer, S3C2410_RES_ERR, 0);
485 }
486 }
487
488 return ret;
489}
490
491static void s3c_pl330_rq(struct s3c_pl330_chan *ch,
492 struct pl330_req *r, enum pl330_op_err err)
493{
494 unsigned long flags;
495 struct s3c_pl330_xfer *xfer;
496 struct pl330_xfer *xl = r->x;
497 enum s3c2410_dma_buffresult res;
498
499 spin_lock_irqsave(&res_lock, flags);
500
501 r->x = NULL;
502
503 s3c_pl330_submit(ch, r);
504
505 spin_unlock_irqrestore(&res_lock, flags);
506
507 /* Map result to S3C DMA API */
508 if (err == PL330_ERR_NONE)
509 res = S3C2410_RES_OK;
510 else if (err == PL330_ERR_ABORT)
511 res = S3C2410_RES_ABORT;
512 else
513 res = S3C2410_RES_ERR;
514
515 /* If last request had some xfer */
516 if (xl) {
517 xfer = container_of(xl, struct s3c_pl330_xfer, px);
518 _finish_off(xfer, res, 0);
519 } else {
520 dev_info(ch->dmac->pi->dev, "%s:%d No Xfer?!\n",
521 __func__, __LINE__);
522 }
523}
524
525static void s3c_pl330_rq0(void *token, enum pl330_op_err err)
526{
527 struct pl330_req *r = token;
528 struct s3c_pl330_chan *ch = container_of(r,
529 struct s3c_pl330_chan, req[0]);
530 s3c_pl330_rq(ch, r, err);
531}
532
533static void s3c_pl330_rq1(void *token, enum pl330_op_err err)
534{
535 struct pl330_req *r = token;
536 struct s3c_pl330_chan *ch = container_of(r,
537 struct s3c_pl330_chan, req[1]);
538 s3c_pl330_rq(ch, r, err);
539}
540
541/* Release an acquired channel */
542static void chan_release(struct s3c_pl330_chan *ch)
543{
544 struct s3c_pl330_dmac *dmac;
545
546 if (chan_free(ch))
547 return;
548
549 dmac = ch->dmac;
550 ch->dmac = NULL;
551 dmac->busy_chan--;
552}
553
554int s3c2410_dma_ctrl(enum dma_ch id, enum s3c2410_chan_op op)
555{
556 struct s3c_pl330_xfer *xfer;
557 enum pl330_chan_op pl330op;
558 struct s3c_pl330_chan *ch;
559 unsigned long flags;
560 int idx, ret;
561
562 spin_lock_irqsave(&res_lock, flags);
563
564 ch = id_to_chan(id);
565
566 if (!ch || chan_free(ch)) {
567 ret = -EINVAL;
568 goto ctrl_exit;
569 }
570
571 switch (op) {
572 case S3C2410_DMAOP_START:
573 /* Make sure both reqs are enqueued */
574 idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
575 s3c_pl330_submit(ch, &ch->req[idx]);
576 s3c_pl330_submit(ch, &ch->req[1 - idx]);
577 pl330op = PL330_OP_START;
578 break;
579
580 case S3C2410_DMAOP_STOP:
581 pl330op = PL330_OP_ABORT;
582 break;
583
584 case S3C2410_DMAOP_FLUSH:
585 pl330op = PL330_OP_FLUSH;
586 break;
587
588 case S3C2410_DMAOP_PAUSE:
589 case S3C2410_DMAOP_RESUME:
590 case S3C2410_DMAOP_TIMEOUT:
591 case S3C2410_DMAOP_STARTED:
592 spin_unlock_irqrestore(&res_lock, flags);
593 return 0;
594
595 default:
596 spin_unlock_irqrestore(&res_lock, flags);
597 return -EINVAL;
598 }
599
600 ret = pl330_chan_ctrl(ch->pl330_chan_id, pl330op);
601
602 if (pl330op == PL330_OP_START) {
603 spin_unlock_irqrestore(&res_lock, flags);
604 return ret;
605 }
606
607 idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
608
609 /* Abort the current xfer */
610 if (ch->req[idx].x) {
611 xfer = container_of(ch->req[idx].x,
612 struct s3c_pl330_xfer, px);
613
614 /* Drop xfer during FLUSH */
615 if (pl330op == PL330_OP_FLUSH)
616 del_from_queue(xfer);
617
618 ch->req[idx].x = NULL;
619
620 spin_unlock_irqrestore(&res_lock, flags);
621 _finish_off(xfer, S3C2410_RES_ABORT,
622 pl330op == PL330_OP_FLUSH ? 1 : 0);
623 spin_lock_irqsave(&res_lock, flags);
624 }
625
626 /* Flush the whole queue */
627 if (pl330op == PL330_OP_FLUSH) {
628
629 if (ch->req[1 - idx].x) {
630 xfer = container_of(ch->req[1 - idx].x,
631 struct s3c_pl330_xfer, px);
632
633 del_from_queue(xfer);
634
635 ch->req[1 - idx].x = NULL;
636
637 spin_unlock_irqrestore(&res_lock, flags);
638 _finish_off(xfer, S3C2410_RES_ABORT, 1);
639 spin_lock_irqsave(&res_lock, flags);
640 }
641
642 /* Finish off the remaining in the queue */
643 xfer = ch->xfer_head;
644 while (xfer) {
645
646 del_from_queue(xfer);
647
648 spin_unlock_irqrestore(&res_lock, flags);
649 _finish_off(xfer, S3C2410_RES_ABORT, 1);
650 spin_lock_irqsave(&res_lock, flags);
651
652 xfer = ch->xfer_head;
653 }
654 }
655
656ctrl_exit:
657 spin_unlock_irqrestore(&res_lock, flags);
658
659 return ret;
660}
661EXPORT_SYMBOL(s3c2410_dma_ctrl);
662
663int s3c2410_dma_enqueue(enum dma_ch id, void *token,
664 dma_addr_t addr, int size)
665{
666 struct s3c_pl330_chan *ch;
667 struct s3c_pl330_xfer *xfer;
668 unsigned long flags;
669 int idx, ret = 0;
670
671 spin_lock_irqsave(&res_lock, flags);
672
673 ch = id_to_chan(id);
674
675 /* Error if invalid or free channel */
676 if (!ch || chan_free(ch)) {
677 ret = -EINVAL;
678 goto enq_exit;
679 }
680
681 /* Error if size is unaligned */
682 if (ch->rqcfg.brst_size && size % (1 << ch->rqcfg.brst_size)) {
683 ret = -EINVAL;
684 goto enq_exit;
685 }
686
687 xfer = kmem_cache_alloc(ch->dmac->kmcache, GFP_ATOMIC);
688 if (!xfer) {
689 ret = -ENOMEM;
690 goto enq_exit;
691 }
692
693 xfer->token = token;
694 xfer->chan = ch;
695 xfer->px.bytes = size;
696 xfer->px.next = NULL; /* Single request */
697
698 /* For S3C DMA API, direction is always fixed for all xfers */
699 if (ch->req[0].rqtype == MEMTODEV) {
700 xfer->px.src_addr = addr;
701 xfer->px.dst_addr = ch->sdaddr;
702 } else {
703 xfer->px.src_addr = ch->sdaddr;
704 xfer->px.dst_addr = addr;
705 }
706
707 add_to_queue(ch, xfer, 0);
708
709 /* Try submitting on either request */
710 idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
711
712 if (!ch->req[idx].x)
713 s3c_pl330_submit(ch, &ch->req[idx]);
714 else
715 s3c_pl330_submit(ch, &ch->req[1 - idx]);
716
717 spin_unlock_irqrestore(&res_lock, flags);
718
719 if (ch->options & S3C2410_DMAF_AUTOSTART)
720 s3c2410_dma_ctrl(id, S3C2410_DMAOP_START);
721
722 return 0;
723
724enq_exit:
725 spin_unlock_irqrestore(&res_lock, flags);
726
727 return ret;
728}
729EXPORT_SYMBOL(s3c2410_dma_enqueue);
730
731int s3c2410_dma_request(enum dma_ch id,
732 struct s3c2410_dma_client *client,
733 void *dev)
734{
735 struct s3c_pl330_dmac *dmac;
736 struct s3c_pl330_chan *ch;
737 unsigned long flags;
738 int ret = 0;
739
740 spin_lock_irqsave(&res_lock, flags);
741
742 ch = chan_acquire(id);
743 if (!ch) {
744 ret = -EBUSY;
745 goto req_exit;
746 }
747
748 dmac = ch->dmac;
749
750 ch->pl330_chan_id = pl330_request_channel(dmac->pi);
751 if (!ch->pl330_chan_id) {
752 chan_release(ch);
753 ret = -EBUSY;
754 goto req_exit;
755 }
756
757 ch->client = client;
758 ch->options = 0; /* Clear any option */
759 ch->callback_fn = NULL; /* Clear any callback */
760 ch->lrq = NULL;
761
762 ch->rqcfg.brst_size = 2; /* Default word size */
763 ch->rqcfg.swap = SWAP_NO;
764 ch->rqcfg.scctl = SCCTRL0; /* Noncacheable and nonbufferable */
765 ch->rqcfg.dcctl = DCCTRL0; /* Noncacheable and nonbufferable */
766 ch->rqcfg.privileged = 0;
767 ch->rqcfg.insnaccess = 0;
768
769 /* Set invalid direction */
770 ch->req[0].rqtype = DEVTODEV;
771 ch->req[1].rqtype = ch->req[0].rqtype;
772
773 ch->req[0].cfg = &ch->rqcfg;
774 ch->req[1].cfg = ch->req[0].cfg;
775
776 ch->req[0].peri = iface_of_dmac(dmac, id) - 1; /* Original index */
777 ch->req[1].peri = ch->req[0].peri;
778
779 ch->req[0].token = &ch->req[0];
780 ch->req[0].xfer_cb = s3c_pl330_rq0;
781 ch->req[1].token = &ch->req[1];
782 ch->req[1].xfer_cb = s3c_pl330_rq1;
783
784 ch->req[0].x = NULL;
785 ch->req[1].x = NULL;
786
787 /* Reset xfer list */
788 INIT_LIST_HEAD(&ch->xfer_list);
789 ch->xfer_head = NULL;
790
791req_exit:
792 spin_unlock_irqrestore(&res_lock, flags);
793
794 return ret;
795}
796EXPORT_SYMBOL(s3c2410_dma_request);
797
798int s3c2410_dma_free(enum dma_ch id, struct s3c2410_dma_client *client)
799{
800 struct s3c_pl330_chan *ch;
801 struct s3c_pl330_xfer *xfer;
802 unsigned long flags;
803 int ret = 0;
804 unsigned idx;
805
806 spin_lock_irqsave(&res_lock, flags);
807
808 ch = id_to_chan(id);
809
810 if (!ch || chan_free(ch))
811 goto free_exit;
812
813 /* Refuse if someone else wanted to free the channel */
814 if (ch->client != client) {
815 ret = -EBUSY;
816 goto free_exit;
817 }
818
819 /* Stop any active xfer, Flushe the queue and do callbacks */
820 pl330_chan_ctrl(ch->pl330_chan_id, PL330_OP_FLUSH);
821
822 /* Abort the submitted requests */
823 idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
824
825 if (ch->req[idx].x) {
826 xfer = container_of(ch->req[idx].x,
827 struct s3c_pl330_xfer, px);
828
829 ch->req[idx].x = NULL;
830 del_from_queue(xfer);
831
832 spin_unlock_irqrestore(&res_lock, flags);
833 _finish_off(xfer, S3C2410_RES_ABORT, 1);
834 spin_lock_irqsave(&res_lock, flags);
835 }
836
837 if (ch->req[1 - idx].x) {
838 xfer = container_of(ch->req[1 - idx].x,
839 struct s3c_pl330_xfer, px);
840
841 ch->req[1 - idx].x = NULL;
842 del_from_queue(xfer);
843
844 spin_unlock_irqrestore(&res_lock, flags);
845 _finish_off(xfer, S3C2410_RES_ABORT, 1);
846 spin_lock_irqsave(&res_lock, flags);
847 }
848
849 /* Pluck and Abort the queued requests in order */
850 do {
851 xfer = get_from_queue(ch, 1);
852
853 spin_unlock_irqrestore(&res_lock, flags);
854 _finish_off(xfer, S3C2410_RES_ABORT, 1);
855 spin_lock_irqsave(&res_lock, flags);
856 } while (xfer);
857
858 ch->client = NULL;
859
860 pl330_release_channel(ch->pl330_chan_id);
861
862 ch->pl330_chan_id = NULL;
863
864 chan_release(ch);
865
866free_exit:
867 spin_unlock_irqrestore(&res_lock, flags);
868
869 return ret;
870}
871EXPORT_SYMBOL(s3c2410_dma_free);
872
873int s3c2410_dma_config(enum dma_ch id, int xferunit)
874{
875 struct s3c_pl330_chan *ch;
876 struct pl330_info *pi;
877 unsigned long flags;
878 int i, dbwidth, ret = 0;
879
880 spin_lock_irqsave(&res_lock, flags);
881
882 ch = id_to_chan(id);
883
884 if (!ch || chan_free(ch)) {
885 ret = -EINVAL;
886 goto cfg_exit;
887 }
888
889 pi = ch->dmac->pi;
890 dbwidth = pi->pcfg.data_bus_width / 8;
891
892 /* Max size of xfer can be pcfg.data_bus_width */
893 if (xferunit > dbwidth) {
894 ret = -EINVAL;
895 goto cfg_exit;
896 }
897
898 i = 0;
899 while (xferunit != (1 << i))
900 i++;
901
902 /* If valid value */
903 if (xferunit == (1 << i))
904 ch->rqcfg.brst_size = i;
905 else
906 ret = -EINVAL;
907
908cfg_exit:
909 spin_unlock_irqrestore(&res_lock, flags);
910
911 return ret;
912}
913EXPORT_SYMBOL(s3c2410_dma_config);
914
915/* Options that are supported by this driver */
916#define S3C_PL330_FLAGS (S3C2410_DMAF_CIRCULAR | S3C2410_DMAF_AUTOSTART)
917
918int s3c2410_dma_setflags(enum dma_ch id, unsigned int options)
919{
920 struct s3c_pl330_chan *ch;
921 unsigned long flags;
922 int ret = 0;
923
924 spin_lock_irqsave(&res_lock, flags);
925
926 ch = id_to_chan(id);
927
928 if (!ch || chan_free(ch) || options & ~(S3C_PL330_FLAGS))
929 ret = -EINVAL;
930 else
931 ch->options = options;
932
933 spin_unlock_irqrestore(&res_lock, flags);
934
935 return 0;
936}
937EXPORT_SYMBOL(s3c2410_dma_setflags);
938
939int s3c2410_dma_set_buffdone_fn(enum dma_ch id, s3c2410_dma_cbfn_t rtn)
940{
941 struct s3c_pl330_chan *ch;
942 unsigned long flags;
943 int ret = 0;
944
945 spin_lock_irqsave(&res_lock, flags);
946
947 ch = id_to_chan(id);
948
949 if (!ch || chan_free(ch))
950 ret = -EINVAL;
951 else
952 ch->callback_fn = rtn;
953
954 spin_unlock_irqrestore(&res_lock, flags);
955
956 return ret;
957}
958EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
959
960int s3c2410_dma_devconfig(enum dma_ch id, enum s3c2410_dmasrc source,
961 unsigned long address)
962{
963 struct s3c_pl330_chan *ch;
964 unsigned long flags;
965 int ret = 0;
966
967 spin_lock_irqsave(&res_lock, flags);
968
969 ch = id_to_chan(id);
970
971 if (!ch || chan_free(ch)) {
972 ret = -EINVAL;
973 goto devcfg_exit;
974 }
975
976 switch (source) {
977 case S3C2410_DMASRC_HW: /* P->M */
978 ch->req[0].rqtype = DEVTOMEM;
979 ch->req[1].rqtype = DEVTOMEM;
980 ch->rqcfg.src_inc = 0;
981 ch->rqcfg.dst_inc = 1;
982 break;
983 case S3C2410_DMASRC_MEM: /* M->P */
984 ch->req[0].rqtype = MEMTODEV;
985 ch->req[1].rqtype = MEMTODEV;
986 ch->rqcfg.src_inc = 1;
987 ch->rqcfg.dst_inc = 0;
988 break;
989 default:
990 ret = -EINVAL;
991 goto devcfg_exit;
992 }
993
994 ch->sdaddr = address;
995
996devcfg_exit:
997 spin_unlock_irqrestore(&res_lock, flags);
998
999 return ret;
1000}
1001EXPORT_SYMBOL(s3c2410_dma_devconfig);
1002
1003int s3c2410_dma_getposition(enum dma_ch id, dma_addr_t *src, dma_addr_t *dst)
1004{
1005 struct s3c_pl330_chan *ch = id_to_chan(id);
1006 struct pl330_chanstatus status;
1007 int ret;
1008
1009 if (!ch || chan_free(ch))
1010 return -EINVAL;
1011
1012 ret = pl330_chan_status(ch->pl330_chan_id, &status);
1013 if (ret < 0)
1014 return ret;
1015
1016 *src = status.src_addr;
1017 *dst = status.dst_addr;
1018
1019 return 0;
1020}
1021EXPORT_SYMBOL(s3c2410_dma_getposition);
1022
1023static irqreturn_t pl330_irq_handler(int irq, void *data)
1024{
1025 if (pl330_update(data))
1026 return IRQ_HANDLED;
1027 else
1028 return IRQ_NONE;
1029}
1030
1031static int pl330_probe(struct platform_device *pdev)
1032{
1033 struct s3c_pl330_dmac *s3c_pl330_dmac;
1034 struct s3c_pl330_platdata *pl330pd;
1035 struct pl330_info *pl330_info;
1036 struct resource *res;
1037 int i, ret, irq;
1038
1039 pl330pd = pdev->dev.platform_data;
1040
1041 /* Can't do without the list of _32_ peripherals */
1042 if (!pl330pd || !pl330pd->peri) {
1043 dev_err(&pdev->dev, "platform data missing!\n");
1044 return -ENODEV;
1045 }
1046
1047 pl330_info = kzalloc(sizeof(*pl330_info), GFP_KERNEL);
1048 if (!pl330_info)
1049 return -ENOMEM;
1050
1051 pl330_info->pl330_data = NULL;
1052 pl330_info->dev = &pdev->dev;
1053
1054 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1055 if (!res) {
1056 ret = -ENODEV;
1057 goto probe_err1;
1058 }
1059
1060 request_mem_region(res->start, resource_size(res), pdev->name);
1061
1062 pl330_info->base = ioremap(res->start, resource_size(res));
1063 if (!pl330_info->base) {
1064 ret = -ENXIO;
1065 goto probe_err2;
1066 }
1067
1068 irq = platform_get_irq(pdev, 0);
1069 if (irq < 0) {
1070 ret = irq;
1071 goto probe_err3;
1072 }
1073
1074 ret = request_irq(irq, pl330_irq_handler, 0,
1075 dev_name(&pdev->dev), pl330_info);
1076 if (ret)
1077 goto probe_err4;
1078
1079 /* Allocate a new DMAC */
1080 s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL);
1081 if (!s3c_pl330_dmac) {
1082 ret = -ENOMEM;
1083 goto probe_err5;
1084 }
1085
1086 /* Get operation clock and enable it */
1087 s3c_pl330_dmac->clk = clk_get(&pdev->dev, "pdma");
1088 if (IS_ERR(s3c_pl330_dmac->clk)) {
1089 dev_err(&pdev->dev, "Cannot get operation clock.\n");
1090 ret = -EINVAL;
1091 goto probe_err6;
1092 }
1093 clk_enable(s3c_pl330_dmac->clk);
1094
1095 ret = pl330_add(pl330_info);
1096 if (ret)
1097 goto probe_err7;
1098
1099 /* Hook the info */
1100 s3c_pl330_dmac->pi = pl330_info;
1101
1102 /* No busy channels */
1103 s3c_pl330_dmac->busy_chan = 0;
1104
1105 s3c_pl330_dmac->kmcache = kmem_cache_create(dev_name(&pdev->dev),
1106 sizeof(struct s3c_pl330_xfer), 0, 0, NULL);
1107
1108 if (!s3c_pl330_dmac->kmcache) {
1109 ret = -ENOMEM;
1110 goto probe_err8;
1111 }
1112
1113 /* Get the list of peripherals */
1114 s3c_pl330_dmac->peri = pl330pd->peri;
1115
1116 /* Attach to the list of DMACs */
1117 list_add_tail(&s3c_pl330_dmac->node, &dmac_list);
1118
1119 /* Create a channel for each peripheral in the DMAC
1120 * that is, if it doesn't already exist
1121 */
1122 for (i = 0; i < PL330_MAX_PERI; i++)
1123 if (s3c_pl330_dmac->peri[i] != DMACH_MAX)
1124 chan_add(s3c_pl330_dmac->peri[i]);
1125
1126 printk(KERN_INFO
1127 "Loaded driver for PL330 DMAC-%d %s\n", pdev->id, pdev->name);
1128 printk(KERN_INFO
1129 "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n",
1130 pl330_info->pcfg.data_buf_dep,
1131 pl330_info->pcfg.data_bus_width / 8, pl330_info->pcfg.num_chan,
1132 pl330_info->pcfg.num_peri, pl330_info->pcfg.num_events);
1133
1134 return 0;
1135
1136probe_err8:
1137 pl330_del(pl330_info);
1138probe_err7:
1139 clk_disable(s3c_pl330_dmac->clk);
1140 clk_put(s3c_pl330_dmac->clk);
1141probe_err6:
1142 kfree(s3c_pl330_dmac);
1143probe_err5:
1144 free_irq(irq, pl330_info);
1145probe_err4:
1146probe_err3:
1147 iounmap(pl330_info->base);
1148probe_err2:
1149 release_mem_region(res->start, resource_size(res));
1150probe_err1:
1151 kfree(pl330_info);
1152
1153 return ret;
1154}
1155
1156static int pl330_remove(struct platform_device *pdev)
1157{
1158 struct s3c_pl330_dmac *dmac, *d;
1159 struct s3c_pl330_chan *ch;
1160 unsigned long flags;
1161 int del, found;
1162
1163 if (!pdev->dev.platform_data)
1164 return -EINVAL;
1165
1166 spin_lock_irqsave(&res_lock, flags);
1167
1168 found = 0;
1169 list_for_each_entry(d, &dmac_list, node)
1170 if (d->pi->dev == &pdev->dev) {
1171 found = 1;
1172 break;
1173 }
1174
1175 if (!found) {
1176 spin_unlock_irqrestore(&res_lock, flags);
1177 return 0;
1178 }
1179
1180 dmac = d;
1181
1182 /* Remove all Channels that are managed only by this DMAC */
1183 list_for_each_entry(ch, &chan_list, node) {
1184
1185 /* Only channels that are handled by this DMAC */
1186 if (iface_of_dmac(dmac, ch->id))
1187 del = 1;
1188 else
1189 continue;
1190
1191 /* Don't remove if some other DMAC has it too */
1192 list_for_each_entry(d, &dmac_list, node)
1193 if (d != dmac && iface_of_dmac(d, ch->id)) {
1194 del = 0;
1195 break;
1196 }
1197
1198 if (del) {
1199 spin_unlock_irqrestore(&res_lock, flags);
1200 s3c2410_dma_free(ch->id, ch->client);
1201 spin_lock_irqsave(&res_lock, flags);
1202 list_del(&ch->node);
1203 kfree(ch);
1204 }
1205 }
1206
1207 /* Disable operation clock */
1208 clk_disable(dmac->clk);
1209 clk_put(dmac->clk);
1210
1211 /* Remove the DMAC */
1212 list_del(&dmac->node);
1213 kfree(dmac);
1214
1215 spin_unlock_irqrestore(&res_lock, flags);
1216
1217 return 0;
1218}
1219
1220static struct platform_driver pl330_driver = {
1221 .driver = {
1222 .owner = THIS_MODULE,
1223 .name = "s3c-pl330",
1224 },
1225 .probe = pl330_probe,
1226 .remove = pl330_remove,
1227};
1228
1229static int __init pl330_init(void)
1230{
1231 return platform_driver_register(&pl330_driver);
1232}
1233module_init(pl330_init);
1234
1235static void __exit pl330_exit(void)
1236{
1237 platform_driver_unregister(&pl330_driver);
1238 return;
1239}
1240module_exit(pl330_exit);
1241
1242MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");
1243MODULE_DESCRIPTION("Driver for PL330 DMA Controller");
1244MODULE_LICENSE("GPL");