diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-03-22 13:23:46 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-03-22 13:23:46 -0400 |
commit | 74511020dde10252f8b8e648690d99dba721de14 (patch) | |
tree | 04fc22bc7dd5d5b8d9294b2e57985b093858bd84 /arch/arm/mach-s3c2440 | |
parent | 69266866a5790080d7fe80094b28d670ff8aa765 (diff) | |
parent | 3cc4e53f86dab635166929bfa47cc68d59b28c26 (diff) |
Merge branch 'for-2.6.34' into for-2.6.35
Diffstat (limited to 'arch/arm/mach-s3c2440')
-rw-r--r-- | arch/arm/mach-s3c2440/Kconfig | 74 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/Makefile | 11 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/clock.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/dma.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/dsc.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/include/mach/gta02.h | 84 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/mach-anubis.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/mach-at2440evb.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/mach-gta02.c | 647 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/mach-mini2440.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/mach-nexcoder.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/mach-rx3715.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/mach-smdk2440.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/s3c2440-cpufreq.c | 311 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/s3c2440-pll-12000000.c | 97 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/s3c2440-pll-16934400.c | 127 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/s3c2440.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/s3c2442.c | 165 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/s3c244x-clock.c | 138 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/s3c244x-irq.c | 142 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/s3c244x.c | 195 |
21 files changed, 2006 insertions, 24 deletions
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig index 80879358eb2f..7f465265cf04 100644 --- a/arch/arm/mach-s3c2440/Kconfig +++ b/arch/arm/mach-s3c2440/Kconfig | |||
@@ -15,14 +15,67 @@ config CPU_S3C2440 | |||
15 | help | 15 | help |
16 | Support for S3C2440 Samsung Mobile CPU based systems. | 16 | Support for S3C2440 Samsung Mobile CPU based systems. |
17 | 17 | ||
18 | config CPU_S3C2442 | ||
19 | bool | ||
20 | depends on ARCH_S3C2410 | ||
21 | select CPU_ARM920T | ||
22 | select S3C2410_CLOCK | ||
23 | select S3C2410_GPIO | ||
24 | select S3C2410_PM if PM | ||
25 | select CPU_S3C244X | ||
26 | select CPU_LLSERIAL_S3C2440 | ||
27 | help | ||
28 | Support for S3C2442 Samsung Mobile CPU based systems. | ||
29 | |||
30 | config CPU_S3C244X | ||
31 | bool | ||
32 | depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442) | ||
33 | help | ||
34 | Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems. | ||
35 | |||
36 | |||
37 | |||
38 | config S3C2440_CPUFREQ | ||
39 | bool "S3C2440/S3C2442 CPU Frequency scaling support" | ||
40 | depends on CPU_FREQ_S3C24XX && (CPU_S3C2440 || CPU_S3C2442) | ||
41 | select S3C2410_CPUFREQ_UTILS | ||
42 | default y | ||
43 | help | ||
44 | CPU Frequency scaling support for S3C2440 and S3C2442 SoC CPUs. | ||
45 | |||
46 | config S3C2440_XTAL_12000000 | ||
47 | bool | ||
48 | help | ||
49 | Indicate that the build needs to support 12MHz system | ||
50 | crystal. | ||
51 | |||
52 | config S3C2440_XTAL_16934400 | ||
53 | bool | ||
54 | help | ||
55 | Indicate that the build needs to support 16.9344MHz system | ||
56 | crystal. | ||
57 | |||
58 | config S3C2440_PLL_12000000 | ||
59 | bool | ||
60 | depends on S3C2440_CPUFREQ && S3C2440_XTAL_12000000 | ||
61 | default y if CPU_FREQ_S3C24XX_PLL | ||
62 | help | ||
63 | PLL tables for S3C2440 or S3C2442 CPUs with 12MHz crystals. | ||
64 | |||
65 | config S3C2440_PLL_16934400 | ||
66 | bool | ||
67 | depends on S3C2440_CPUFREQ && S3C2440_XTAL_16934400 | ||
68 | default y if CPU_FREQ_S3C24XX_PLL | ||
69 | help | ||
70 | PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals. | ||
71 | |||
18 | config S3C2440_DMA | 72 | config S3C2440_DMA |
19 | bool | 73 | bool |
20 | depends on ARCH_S3C2410 && CPU_S3C24405B | 74 | depends on ARCH_S3C2410 && CPU_S3C24405B |
21 | help | 75 | help |
22 | Support for S3C2440 specific DMA code5A | 76 | Support for S3C2440 specific DMA code5A |
23 | 77 | ||
24 | 78 | menu "S3C2440 and S3C2442 Machines" | |
25 | menu "S3C2440 Machines" | ||
26 | 79 | ||
27 | config MACH_ANUBIS | 80 | config MACH_ANUBIS |
28 | bool "Simtec Electronics ANUBIS" | 81 | bool "Simtec Electronics ANUBIS" |
@@ -37,6 +90,18 @@ config MACH_ANUBIS | |||
37 | Say Y here if you are using the Simtec Electronics ANUBIS | 90 | Say Y here if you are using the Simtec Electronics ANUBIS |
38 | development system | 91 | development system |
39 | 92 | ||
93 | config MACH_NEO1973_GTA02 | ||
94 | bool "Openmoko GTA02 / Freerunner phone" | ||
95 | select CPU_S3C2442 | ||
96 | select MFD_PCF50633 | ||
97 | select PCF50633_GPIO | ||
98 | select I2C | ||
99 | select POWER_SUPPLY | ||
100 | select MACH_NEO1973 | ||
101 | select S3C2410_PWM | ||
102 | help | ||
103 | Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone | ||
104 | |||
40 | config MACH_OSIRIS | 105 | config MACH_OSIRIS |
41 | bool "Simtec IM2440D20 (OSIRIS) module" | 106 | bool "Simtec IM2440D20 (OSIRIS) module" |
42 | select CPU_S3C2440 | 107 | select CPU_S3C2440 |
@@ -94,11 +159,14 @@ config MACH_NEXCODER_2440 | |||
94 | 159 | ||
95 | config SMDK2440_CPU2440 | 160 | config SMDK2440_CPU2440 |
96 | bool "SMDK2440 with S3C2440 CPU module" | 161 | bool "SMDK2440 with S3C2440 CPU module" |
97 | depends on ARCH_S3C2440 | ||
98 | default y if ARCH_S3C2440 | 162 | default y if ARCH_S3C2440 |
99 | select S3C2440_XTAL_16934400 | 163 | select S3C2440_XTAL_16934400 |
100 | select CPU_S3C2440 | 164 | select CPU_S3C2440 |
101 | 165 | ||
166 | config SMDK2440_CPU2442 | ||
167 | bool "SMDM2440 with S3C2442 CPU module" | ||
168 | select CPU_S3C2442 | ||
169 | |||
102 | config MACH_AT2440EVB | 170 | config MACH_AT2440EVB |
103 | bool "Avantech AT2440EVB development board" | 171 | bool "Avantech AT2440EVB development board" |
104 | select CPU_S3C2440 | 172 | select CPU_S3C2440 |
diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile index 5f3224531885..c85ba32d8956 100644 --- a/arch/arm/mach-s3c2440/Makefile +++ b/arch/arm/mach-s3c2440/Makefile | |||
@@ -10,10 +10,20 @@ obj-n := | |||
10 | obj- := | 10 | obj- := |
11 | 11 | ||
12 | obj-$(CONFIG_CPU_S3C2440) += s3c2440.o dsc.o | 12 | obj-$(CONFIG_CPU_S3C2440) += s3c2440.o dsc.o |
13 | obj-$(CONFIG_CPU_S3C2442) += s3c2442.o | ||
14 | |||
13 | obj-$(CONFIG_CPU_S3C2440) += irq.o | 15 | obj-$(CONFIG_CPU_S3C2440) += irq.o |
14 | obj-$(CONFIG_CPU_S3C2440) += clock.o | 16 | obj-$(CONFIG_CPU_S3C2440) += clock.o |
15 | obj-$(CONFIG_S3C2440_DMA) += dma.o | 17 | obj-$(CONFIG_S3C2440_DMA) += dma.o |
16 | 18 | ||
19 | obj-$(CONFIG_CPU_S3C244X) += s3c244x.o | ||
20 | obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o | ||
21 | obj-$(CONFIG_CPU_S3C244X) += s3c244x-clock.o | ||
22 | obj-$(CONFIG_S3C2440_CPUFREQ) += s3c2440-cpufreq.o | ||
23 | |||
24 | obj-$(CONFIG_S3C2440_PLL_12000000) += s3c2440-pll-12000000.o | ||
25 | obj-$(CONFIG_S3C2440_PLL_16934400) += s3c2440-pll-16934400.o | ||
26 | |||
17 | # Machine support | 27 | # Machine support |
18 | 28 | ||
19 | obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o | 29 | obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o |
@@ -23,6 +33,7 @@ obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o | |||
23 | obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o | 33 | obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o |
24 | obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o | 34 | obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o |
25 | obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o | 35 | obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o |
36 | obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o | ||
26 | 37 | ||
27 | # extra machine support | 38 | # extra machine support |
28 | 39 | ||
diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c index d1c29b2537cd..3dc2426e2345 100644 --- a/arch/arm/mach-s3c2440/clock.c +++ b/arch/arm/mach-s3c2440/clock.c | |||
@@ -98,8 +98,10 @@ static struct clk s3c2440_clk_cam = { | |||
98 | static struct clk s3c2440_clk_cam_upll = { | 98 | static struct clk s3c2440_clk_cam_upll = { |
99 | .name = "camif-upll", | 99 | .name = "camif-upll", |
100 | .id = -1, | 100 | .id = -1, |
101 | .set_rate = s3c2440_camif_upll_setrate, | 101 | .ops = &(struct clk_ops) { |
102 | .round_rate = s3c2440_camif_upll_round, | 102 | .set_rate = s3c2440_camif_upll_setrate, |
103 | .round_rate = s3c2440_camif_upll_round, | ||
104 | }, | ||
103 | }; | 105 | }; |
104 | 106 | ||
105 | static struct clk s3c2440_clk_ac97 = { | 107 | static struct clk s3c2440_clk_ac97 = { |
diff --git a/arch/arm/mach-s3c2440/dma.c b/arch/arm/mach-s3c2440/dma.c index e08e081430f0..3b0529f54e9c 100644 --- a/arch/arm/mach-s3c2440/dma.c +++ b/arch/arm/mach-s3c2440/dma.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <mach/map.h> | 20 | #include <mach/map.h> |
21 | #include <mach/dma.h> | 21 | #include <mach/dma.h> |
22 | 22 | ||
23 | #include <plat/dma-plat.h> | 23 | #include <plat/dma-s3c24xx.h> |
24 | #include <plat/cpu.h> | 24 | #include <plat/cpu.h> |
25 | 25 | ||
26 | #include <plat/regs-serial.h> | 26 | #include <plat/regs-serial.h> |
diff --git a/arch/arm/mach-s3c2440/dsc.c b/arch/arm/mach-s3c2440/dsc.c index 554044272771..9ea66e31f626 100644 --- a/arch/arm/mach-s3c2440/dsc.c +++ b/arch/arm/mach-s3c2440/dsc.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <mach/regs-dsc.h> | 28 | #include <mach/regs-dsc.h> |
29 | 29 | ||
30 | #include <plat/cpu.h> | 30 | #include <plat/cpu.h> |
31 | #include <plat/s3c2440.h> | 31 | #include <plat/s3c244x.h> |
32 | 32 | ||
33 | int s3c2440_set_dsc(unsigned int pin, unsigned int value) | 33 | int s3c2440_set_dsc(unsigned int pin, unsigned int value) |
34 | { | 34 | { |
diff --git a/arch/arm/mach-s3c2440/include/mach/gta02.h b/arch/arm/mach-s3c2440/include/mach/gta02.h new file mode 100644 index 000000000000..953331d8d56a --- /dev/null +++ b/arch/arm/mach-s3c2440/include/mach/gta02.h | |||
@@ -0,0 +1,84 @@ | |||
1 | #ifndef _GTA02_H | ||
2 | #define _GTA02_H | ||
3 | |||
4 | #include <mach/regs-gpio.h> | ||
5 | |||
6 | /* Different hardware revisions, passed in ATAG_REVISION by u-boot */ | ||
7 | #define GTA02v1_SYSTEM_REV 0x00000310 | ||
8 | #define GTA02v2_SYSTEM_REV 0x00000320 | ||
9 | #define GTA02v3_SYSTEM_REV 0x00000330 | ||
10 | #define GTA02v4_SYSTEM_REV 0x00000340 | ||
11 | #define GTA02v5_SYSTEM_REV 0x00000350 | ||
12 | /* since A7 is basically same as A6, we use A6 PCB ID */ | ||
13 | #define GTA02v6_SYSTEM_REV 0x00000360 | ||
14 | |||
15 | #define GTA02_GPIO_n3DL_GSM S3C2410_GPA(13) /* v1 + v2 + v3 only */ | ||
16 | |||
17 | #define GTA02_GPIO_PWR_LED1 S3C2410_GPB(0) | ||
18 | #define GTA02_GPIO_PWR_LED2 S3C2410_GPB(1) | ||
19 | #define GTA02_GPIO_AUX_LED S3C2410_GPB(2) | ||
20 | #define GTA02_GPIO_VIBRATOR_ON S3C2410_GPB(3) | ||
21 | #define GTA02_GPIO_MODEM_RST S3C2410_GPB(5) | ||
22 | #define GTA02_GPIO_BT_EN S3C2410_GPB(6) | ||
23 | #define GTA02_GPIO_MODEM_ON S3C2410_GPB(7) | ||
24 | #define GTA02_GPIO_EXTINT8 S3C2410_GPB(8) | ||
25 | #define GTA02_GPIO_USB_PULLUP S3C2410_GPB(9) | ||
26 | |||
27 | #define GTA02_GPIO_PIO5 S3C2410_GPC(5) /* v3 + v4 only */ | ||
28 | |||
29 | #define GTA02v3_GPIO_nG1_CS S3C2410_GPD(12) /* v3 + v4 only */ | ||
30 | #define GTA02v3_GPIO_nG2_CS S3C2410_GPD(13) /* v3 + v4 only */ | ||
31 | #define GTA02v5_GPIO_HDQ S3C2410_GPD(14) /* v5 + */ | ||
32 | |||
33 | #define GTA02_GPIO_nG1_INT S3C2410_GPF(0) | ||
34 | #define GTA02_GPIO_IO1 S3C2410_GPF(1) | ||
35 | #define GTA02_GPIO_PIO_2 S3C2410_GPF(2) /* v2 + v3 + v4 only */ | ||
36 | #define GTA02_GPIO_JACK_INSERT S3C2410_GPF(4) | ||
37 | #define GTA02_GPIO_WLAN_GPIO1 S3C2410_GPF(5) /* v2 + v3 + v4 only */ | ||
38 | #define GTA02_GPIO_AUX_KEY S3C2410_GPF(6) | ||
39 | #define GTA02_GPIO_HOLD_KEY S3C2410_GPF(7) | ||
40 | |||
41 | #define GTA02_GPIO_3D_IRQ S3C2410_GPG(4) | ||
42 | #define GTA02v2_GPIO_nG2_INT S3C2410_GPG(8) /* v2 + v3 + v4 only */ | ||
43 | #define GTA02v3_GPIO_nUSB_OC S3C2410_GPG(9) /* v3 + v4 only */ | ||
44 | #define GTA02v3_GPIO_nUSB_FLT S3C2410_GPG(10) /* v3 + v4 only */ | ||
45 | #define GTA02v3_GPIO_nGSM_OC S3C2410_GPG(11) /* v3 + v4 only */ | ||
46 | |||
47 | #define GTA02_GPIO_AMP_SHUT S3C2440_GPJ1 /* v2 + v3 + v4 only */ | ||
48 | #define GTA02v1_GPIO_WLAN_GPIO10 S3C2440_GPJ2 | ||
49 | #define GTA02_GPIO_HP_IN S3C2440_GPJ2 /* v2 + v3 + v4 only */ | ||
50 | #define GTA02_GPIO_INT0 S3C2440_GPJ3 /* v2 + v3 + v4 only */ | ||
51 | #define GTA02_GPIO_nGSM_EN S3C2440_GPJ4 | ||
52 | #define GTA02_GPIO_3D_RESET S3C2440_GPJ5 | ||
53 | #define GTA02_GPIO_nDL_GSM S3C2440_GPJ6 /* v4 + v5 only */ | ||
54 | #define GTA02_GPIO_WLAN_GPIO0 S3C2440_GPJ7 | ||
55 | #define GTA02v1_GPIO_BAT_ID S3C2440_GPJ8 | ||
56 | #define GTA02_GPIO_KEEPACT S3C2440_GPJ8 | ||
57 | #define GTA02v1_GPIO_HP_IN S3C2440_GPJ10 | ||
58 | #define GTA02_CHIP_PWD S3C2440_GPJ11 /* v2 + v3 + v4 only */ | ||
59 | #define GTA02_GPIO_nWLAN_RESET S3C2440_GPJ12 /* v2 + v3 + v4 only */ | ||
60 | |||
61 | #define GTA02_IRQ_GSENSOR_1 IRQ_EINT0 | ||
62 | #define GTA02_IRQ_MODEM IRQ_EINT1 | ||
63 | #define GTA02_IRQ_PIO_2 IRQ_EINT2 /* v2 + v3 + v4 only */ | ||
64 | #define GTA02_IRQ_nJACK_INSERT IRQ_EINT4 | ||
65 | #define GTA02_IRQ_WLAN_GPIO1 IRQ_EINT5 | ||
66 | #define GTA02_IRQ_AUX IRQ_EINT6 | ||
67 | #define GTA02_IRQ_nHOLD IRQ_EINT7 | ||
68 | #define GTA02_IRQ_PCF50633 IRQ_EINT9 | ||
69 | #define GTA02_IRQ_3D IRQ_EINT12 | ||
70 | #define GTA02_IRQ_GSENSOR_2 IRQ_EINT16 /* v2 + v3 + v4 only */ | ||
71 | #define GTA02v3_IRQ_nUSB_OC IRQ_EINT17 /* v3 + v4 only */ | ||
72 | #define GTA02v3_IRQ_nUSB_FLT IRQ_EINT18 /* v3 + v4 only */ | ||
73 | #define GTA02v3_IRQ_nGSM_OC IRQ_EINT19 /* v3 + v4 only */ | ||
74 | |||
75 | /* returns 00 000 on GTA02 A5 and earlier, A6 returns 01 001 */ | ||
76 | #define GTA02_PCB_ID1_0 S3C2410_GPC(13) | ||
77 | #define GTA02_PCB_ID1_1 S3C2410_GPC(15) | ||
78 | #define GTA02_PCB_ID1_2 S3C2410_GPD(0) | ||
79 | #define GTA02_PCB_ID2_0 S3C2410_GPD(3) | ||
80 | #define GTA02_PCB_ID2_1 S3C2410_GPD(4) | ||
81 | |||
82 | int gta02_get_pcb_revision(void); | ||
83 | |||
84 | #endif /* _GTA02_H */ | ||
diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c index 62a4c3eba97f..b73f78a9da5c 100644 --- a/arch/arm/mach-s3c2440/mach-anubis.c +++ b/arch/arm/mach-s3c2440/mach-anubis.c | |||
@@ -409,7 +409,7 @@ static struct platform_device anubis_device_sm501 = { | |||
409 | /* Standard Anubis devices */ | 409 | /* Standard Anubis devices */ |
410 | 410 | ||
411 | static struct platform_device *anubis_devices[] __initdata = { | 411 | static struct platform_device *anubis_devices[] __initdata = { |
412 | &s3c_device_usb, | 412 | &s3c_device_ohci, |
413 | &s3c_device_wdt, | 413 | &s3c_device_wdt, |
414 | &s3c_device_adc, | 414 | &s3c_device_adc, |
415 | &s3c_device_i2c0, | 415 | &s3c_device_i2c0, |
diff --git a/arch/arm/mach-s3c2440/mach-at2440evb.c b/arch/arm/mach-s3c2440/mach-at2440evb.c index aa69290e04c6..84725791e6bf 100644 --- a/arch/arm/mach-s3c2440/mach-at2440evb.c +++ b/arch/arm/mach-s3c2440/mach-at2440evb.c | |||
@@ -165,7 +165,7 @@ static struct platform_device at2440evb_device_eth = { | |||
165 | }, | 165 | }, |
166 | }; | 166 | }; |
167 | 167 | ||
168 | static struct s3c24xx_mci_pdata at2440evb_mci_pdata = { | 168 | static struct s3c24xx_mci_pdata at2440evb_mci_pdata __initdata = { |
169 | .gpio_detect = S3C2410_GPG(10), | 169 | .gpio_detect = S3C2410_GPG(10), |
170 | }; | 170 | }; |
171 | 171 | ||
@@ -203,7 +203,7 @@ static struct s3c2410fb_mach_info at2440evb_fb_info __initdata = { | |||
203 | }; | 203 | }; |
204 | 204 | ||
205 | static struct platform_device *at2440evb_devices[] __initdata = { | 205 | static struct platform_device *at2440evb_devices[] __initdata = { |
206 | &s3c_device_usb, | 206 | &s3c_device_ohci, |
207 | &s3c_device_wdt, | 207 | &s3c_device_wdt, |
208 | &s3c_device_adc, | 208 | &s3c_device_adc, |
209 | &s3c_device_i2c0, | 209 | &s3c_device_i2c0, |
@@ -216,8 +216,6 @@ static struct platform_device *at2440evb_devices[] __initdata = { | |||
216 | 216 | ||
217 | static void __init at2440evb_map_io(void) | 217 | static void __init at2440evb_map_io(void) |
218 | { | 218 | { |
219 | s3c_device_sdi.dev.platform_data = &at2440evb_mci_pdata; | ||
220 | |||
221 | s3c24xx_init_io(at2440evb_iodesc, ARRAY_SIZE(at2440evb_iodesc)); | 219 | s3c24xx_init_io(at2440evb_iodesc, ARRAY_SIZE(at2440evb_iodesc)); |
222 | s3c24xx_init_clocks(16934400); | 220 | s3c24xx_init_clocks(16934400); |
223 | s3c24xx_init_uarts(at2440evb_uartcfgs, ARRAY_SIZE(at2440evb_uartcfgs)); | 221 | s3c24xx_init_uarts(at2440evb_uartcfgs, ARRAY_SIZE(at2440evb_uartcfgs)); |
@@ -226,6 +224,7 @@ static void __init at2440evb_map_io(void) | |||
226 | static void __init at2440evb_init(void) | 224 | static void __init at2440evb_init(void) |
227 | { | 225 | { |
228 | s3c24xx_fb_set_platdata(&at2440evb_fb_info); | 226 | s3c24xx_fb_set_platdata(&at2440evb_fb_info); |
227 | s3c24xx_mci_set_platdata(&at2440evb_mci_pdata); | ||
229 | s3c_nand_set_platdata(&at2440evb_nand_info); | 228 | s3c_nand_set_platdata(&at2440evb_nand_info); |
230 | s3c_i2c0_set_platdata(NULL); | 229 | s3c_i2c0_set_platdata(NULL); |
231 | 230 | ||
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c new file mode 100644 index 000000000000..45799c608d8f --- /dev/null +++ b/arch/arm/mach-s3c2440/mach-gta02.c | |||
@@ -0,0 +1,647 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-s3c2442/mach-gta02.c | ||
3 | * | ||
4 | * S3C2442 Machine Support for Openmoko GTA02 / FreeRunner. | ||
5 | * | ||
6 | * Copyright (C) 2006-2009 by Openmoko, Inc. | ||
7 | * Authors: Harald Welte <laforge@openmoko.org> | ||
8 | * Andy Green <andy@openmoko.org> | ||
9 | * Werner Almesberger <werner@openmoko.org> | ||
10 | * All rights reserved. | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License as | ||
14 | * published by the Free Software Foundation; either version 2 of | ||
15 | * the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
25 | * MA 02111-1307 USA | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/types.h> | ||
31 | #include <linux/interrupt.h> | ||
32 | #include <linux/list.h> | ||
33 | #include <linux/delay.h> | ||
34 | #include <linux/timer.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/gpio.h> | ||
37 | #include <linux/workqueue.h> | ||
38 | #include <linux/platform_device.h> | ||
39 | #include <linux/serial_core.h> | ||
40 | #include <linux/spi/spi.h> | ||
41 | |||
42 | #include <linux/mmc/host.h> | ||
43 | |||
44 | #include <linux/mtd/mtd.h> | ||
45 | #include <linux/mtd/nand.h> | ||
46 | #include <linux/mtd/nand_ecc.h> | ||
47 | #include <linux/mtd/partitions.h> | ||
48 | #include <linux/mtd/physmap.h> | ||
49 | #include <linux/io.h> | ||
50 | |||
51 | #include <linux/i2c.h> | ||
52 | #include <linux/backlight.h> | ||
53 | #include <linux/regulator/machine.h> | ||
54 | |||
55 | #include <linux/mfd/pcf50633/core.h> | ||
56 | #include <linux/mfd/pcf50633/mbc.h> | ||
57 | #include <linux/mfd/pcf50633/adc.h> | ||
58 | #include <linux/mfd/pcf50633/gpio.h> | ||
59 | #include <linux/mfd/pcf50633/pmic.h> | ||
60 | |||
61 | #include <asm/mach/arch.h> | ||
62 | #include <asm/mach/map.h> | ||
63 | #include <asm/mach/irq.h> | ||
64 | |||
65 | #include <asm/irq.h> | ||
66 | #include <asm/mach-types.h> | ||
67 | |||
68 | #include <mach/regs-irq.h> | ||
69 | #include <mach/regs-gpio.h> | ||
70 | #include <mach/regs-gpioj.h> | ||
71 | #include <mach/fb.h> | ||
72 | |||
73 | #include <mach/spi.h> | ||
74 | #include <mach/spi-gpio.h> | ||
75 | #include <plat/usb-control.h> | ||
76 | #include <mach/regs-mem.h> | ||
77 | #include <mach/hardware.h> | ||
78 | |||
79 | #include <mach/gta02.h> | ||
80 | |||
81 | #include <plat/regs-serial.h> | ||
82 | #include <plat/nand.h> | ||
83 | #include <plat/devs.h> | ||
84 | #include <plat/cpu.h> | ||
85 | #include <plat/pm.h> | ||
86 | #include <plat/udc.h> | ||
87 | #include <plat/gpio-cfg.h> | ||
88 | #include <plat/iic.h> | ||
89 | |||
90 | static struct pcf50633 *gta02_pcf; | ||
91 | |||
92 | /* | ||
93 | * This gets called every 1ms when we paniced. | ||
94 | */ | ||
95 | |||
96 | static long gta02_panic_blink(long count) | ||
97 | { | ||
98 | long delay = 0; | ||
99 | static long last_blink; | ||
100 | static char led; | ||
101 | |||
102 | /* Fast blink: 200ms period. */ | ||
103 | if (count - last_blink < 100) | ||
104 | return 0; | ||
105 | |||
106 | led ^= 1; | ||
107 | gpio_direction_output(GTA02_GPIO_AUX_LED, led); | ||
108 | |||
109 | last_blink = count; | ||
110 | |||
111 | return delay; | ||
112 | } | ||
113 | |||
114 | |||
115 | static struct map_desc gta02_iodesc[] __initdata = { | ||
116 | { | ||
117 | .virtual = 0xe0000000, | ||
118 | .pfn = __phys_to_pfn(S3C2410_CS3 + 0x01000000), | ||
119 | .length = SZ_1M, | ||
120 | .type = MT_DEVICE | ||
121 | }, | ||
122 | }; | ||
123 | |||
124 | #define UCON (S3C2410_UCON_DEFAULT | S3C2443_UCON_RXERR_IRQEN) | ||
125 | #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB) | ||
126 | #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) | ||
127 | |||
128 | static struct s3c2410_uartcfg gta02_uartcfgs[] = { | ||
129 | [0] = { | ||
130 | .hwport = 0, | ||
131 | .flags = 0, | ||
132 | .ucon = UCON, | ||
133 | .ulcon = ULCON, | ||
134 | .ufcon = UFCON, | ||
135 | }, | ||
136 | [1] = { | ||
137 | .hwport = 1, | ||
138 | .flags = 0, | ||
139 | .ucon = UCON, | ||
140 | .ulcon = ULCON, | ||
141 | .ufcon = UFCON, | ||
142 | }, | ||
143 | [2] = { | ||
144 | .hwport = 2, | ||
145 | .flags = 0, | ||
146 | .ucon = UCON, | ||
147 | .ulcon = ULCON, | ||
148 | .ufcon = UFCON, | ||
149 | }, | ||
150 | }; | ||
151 | |||
152 | #ifdef CONFIG_CHARGER_PCF50633 | ||
153 | /* | ||
154 | * On GTA02 the 1A charger features a 48K resistor to 0V on the ID pin. | ||
155 | * We use this to recognize that we can pull 1A from the USB socket. | ||
156 | * | ||
157 | * These constants are the measured pcf50633 ADC levels with the 1A | ||
158 | * charger / 48K resistor, and with no pulldown resistor. | ||
159 | */ | ||
160 | |||
161 | #define ADC_NOM_CHG_DETECT_1A 6 | ||
162 | #define ADC_NOM_CHG_DETECT_USB 43 | ||
163 | |||
164 | static void | ||
165 | gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res) | ||
166 | { | ||
167 | int ma; | ||
168 | |||
169 | /* Interpret charger type */ | ||
170 | if (res < ((ADC_NOM_CHG_DETECT_USB + ADC_NOM_CHG_DETECT_1A) / 2)) { | ||
171 | |||
172 | /* | ||
173 | * Sanity - stop GPO driving out now that we have a 1A charger | ||
174 | * GPO controls USB Host power generation on GTA02 | ||
175 | */ | ||
176 | pcf50633_gpio_set(pcf, PCF50633_GPO, 0); | ||
177 | |||
178 | ma = 1000; | ||
179 | } else | ||
180 | ma = 100; | ||
181 | |||
182 | pcf50633_mbc_usb_curlim_set(pcf, ma); | ||
183 | } | ||
184 | |||
185 | static struct delayed_work gta02_charger_work; | ||
186 | static int gta02_usb_vbus_draw; | ||
187 | |||
188 | static void gta02_charger_worker(struct work_struct *work) | ||
189 | { | ||
190 | if (gta02_usb_vbus_draw) { | ||
191 | pcf50633_mbc_usb_curlim_set(gta02_pcf, gta02_usb_vbus_draw); | ||
192 | return; | ||
193 | } | ||
194 | |||
195 | #ifdef CONFIG_PCF50633_ADC | ||
196 | pcf50633_adc_async_read(gta02_pcf, | ||
197 | PCF50633_ADCC1_MUX_ADCIN1, | ||
198 | PCF50633_ADCC1_AVERAGE_16, | ||
199 | gta02_configure_pmu_for_charger, | ||
200 | NULL); | ||
201 | #else | ||
202 | /* | ||
203 | * If the PCF50633 ADC is disabled we fallback to a | ||
204 | * 100mA limit for safety. | ||
205 | */ | ||
206 | pcf50633_mbc_usb_curlim_set(pcf, 100); | ||
207 | #endif | ||
208 | } | ||
209 | |||
210 | #define GTA02_CHARGER_CONFIGURE_TIMEOUT ((3000 * HZ) / 1000) | ||
211 | |||
212 | static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq) | ||
213 | { | ||
214 | if (irq == PCF50633_IRQ_USBINS) { | ||
215 | schedule_delayed_work(>a02_charger_work, | ||
216 | GTA02_CHARGER_CONFIGURE_TIMEOUT); | ||
217 | |||
218 | return; | ||
219 | } | ||
220 | |||
221 | if (irq == PCF50633_IRQ_USBREM) { | ||
222 | cancel_delayed_work_sync(>a02_charger_work); | ||
223 | gta02_usb_vbus_draw = 0; | ||
224 | } | ||
225 | } | ||
226 | |||
227 | static void gta02_udc_vbus_draw(unsigned int ma) | ||
228 | { | ||
229 | if (!gta02_pcf) | ||
230 | return; | ||
231 | |||
232 | gta02_usb_vbus_draw = ma; | ||
233 | |||
234 | schedule_delayed_work(>a02_charger_work, | ||
235 | GTA02_CHARGER_CONFIGURE_TIMEOUT); | ||
236 | } | ||
237 | #else /* !CONFIG_CHARGER_PCF50633 */ | ||
238 | #define gta02_pmu_event_callback NULL | ||
239 | #define gta02_udc_vbus_draw NULL | ||
240 | #endif | ||
241 | |||
242 | /* | ||
243 | * This is called when pc50633 is probed, unfortunately quite late in the | ||
244 | * day since it is an I2C bus device. Here we can belatedly define some | ||
245 | * platform devices with the advantage that we can mark the pcf50633 as the | ||
246 | * parent. This makes them get suspended and resumed with their parent | ||
247 | * the pcf50633 still around. | ||
248 | */ | ||
249 | |||
250 | static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf); | ||
251 | |||
252 | |||
253 | static char *gta02_batteries[] = { | ||
254 | "battery", | ||
255 | }; | ||
256 | |||
257 | struct pcf50633_platform_data gta02_pcf_pdata = { | ||
258 | .resumers = { | ||
259 | [0] = PCF50633_INT1_USBINS | | ||
260 | PCF50633_INT1_USBREM | | ||
261 | PCF50633_INT1_ALARM, | ||
262 | [1] = PCF50633_INT2_ONKEYF, | ||
263 | [2] = PCF50633_INT3_ONKEY1S, | ||
264 | [3] = PCF50633_INT4_LOWSYS | | ||
265 | PCF50633_INT4_LOWBAT | | ||
266 | PCF50633_INT4_HIGHTMP, | ||
267 | }, | ||
268 | |||
269 | .batteries = gta02_batteries, | ||
270 | .num_batteries = ARRAY_SIZE(gta02_batteries), | ||
271 | |||
272 | .charger_reference_current_ma = 1000, | ||
273 | |||
274 | .reg_init_data = { | ||
275 | [PCF50633_REGULATOR_AUTO] = { | ||
276 | .constraints = { | ||
277 | .min_uV = 3300000, | ||
278 | .max_uV = 3300000, | ||
279 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
280 | .always_on = 1, | ||
281 | .apply_uV = 1, | ||
282 | .state_mem = { | ||
283 | .enabled = 1, | ||
284 | }, | ||
285 | }, | ||
286 | }, | ||
287 | [PCF50633_REGULATOR_DOWN1] = { | ||
288 | .constraints = { | ||
289 | .min_uV = 1300000, | ||
290 | .max_uV = 1600000, | ||
291 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
292 | .always_on = 1, | ||
293 | .apply_uV = 1, | ||
294 | }, | ||
295 | }, | ||
296 | [PCF50633_REGULATOR_DOWN2] = { | ||
297 | .constraints = { | ||
298 | .min_uV = 1800000, | ||
299 | .max_uV = 1800000, | ||
300 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
301 | .apply_uV = 1, | ||
302 | .always_on = 1, | ||
303 | .state_mem = { | ||
304 | .enabled = 1, | ||
305 | }, | ||
306 | }, | ||
307 | }, | ||
308 | [PCF50633_REGULATOR_HCLDO] = { | ||
309 | .constraints = { | ||
310 | .min_uV = 2000000, | ||
311 | .max_uV = 3300000, | ||
312 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
313 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, | ||
314 | .always_on = 1, | ||
315 | }, | ||
316 | }, | ||
317 | [PCF50633_REGULATOR_LDO1] = { | ||
318 | .constraints = { | ||
319 | .min_uV = 3300000, | ||
320 | .max_uV = 3300000, | ||
321 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
322 | .apply_uV = 1, | ||
323 | .state_mem = { | ||
324 | .enabled = 0, | ||
325 | }, | ||
326 | }, | ||
327 | }, | ||
328 | [PCF50633_REGULATOR_LDO2] = { | ||
329 | .constraints = { | ||
330 | .min_uV = 3300000, | ||
331 | .max_uV = 3300000, | ||
332 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
333 | .apply_uV = 1, | ||
334 | }, | ||
335 | }, | ||
336 | [PCF50633_REGULATOR_LDO3] = { | ||
337 | .constraints = { | ||
338 | .min_uV = 3000000, | ||
339 | .max_uV = 3000000, | ||
340 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
341 | .apply_uV = 1, | ||
342 | }, | ||
343 | }, | ||
344 | [PCF50633_REGULATOR_LDO4] = { | ||
345 | .constraints = { | ||
346 | .min_uV = 3200000, | ||
347 | .max_uV = 3200000, | ||
348 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
349 | .apply_uV = 1, | ||
350 | }, | ||
351 | }, | ||
352 | [PCF50633_REGULATOR_LDO5] = { | ||
353 | .constraints = { | ||
354 | .min_uV = 3000000, | ||
355 | .max_uV = 3000000, | ||
356 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
357 | .apply_uV = 1, | ||
358 | .state_mem = { | ||
359 | .enabled = 1, | ||
360 | }, | ||
361 | }, | ||
362 | }, | ||
363 | [PCF50633_REGULATOR_LDO6] = { | ||
364 | .constraints = { | ||
365 | .min_uV = 3000000, | ||
366 | .max_uV = 3000000, | ||
367 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
368 | }, | ||
369 | }, | ||
370 | [PCF50633_REGULATOR_MEMLDO] = { | ||
371 | .constraints = { | ||
372 | .min_uV = 1800000, | ||
373 | .max_uV = 1800000, | ||
374 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
375 | .state_mem = { | ||
376 | .enabled = 1, | ||
377 | }, | ||
378 | }, | ||
379 | }, | ||
380 | |||
381 | }, | ||
382 | .probe_done = gta02_pmu_attach_child_devices, | ||
383 | .mbc_event_callback = gta02_pmu_event_callback, | ||
384 | }; | ||
385 | |||
386 | |||
387 | /* NOR Flash. */ | ||
388 | |||
389 | #define GTA02_FLASH_BASE 0x18000000 /* GCS3 */ | ||
390 | #define GTA02_FLASH_SIZE 0x200000 /* 2MBytes */ | ||
391 | |||
392 | static struct physmap_flash_data gta02_nor_flash_data = { | ||
393 | .width = 2, | ||
394 | }; | ||
395 | |||
396 | static struct resource gta02_nor_flash_resource = { | ||
397 | .start = GTA02_FLASH_BASE, | ||
398 | .end = GTA02_FLASH_BASE + GTA02_FLASH_SIZE - 1, | ||
399 | .flags = IORESOURCE_MEM, | ||
400 | }; | ||
401 | |||
402 | static struct platform_device gta02_nor_flash = { | ||
403 | .name = "physmap-flash", | ||
404 | .id = 0, | ||
405 | .dev = { | ||
406 | .platform_data = >a02_nor_flash_data, | ||
407 | }, | ||
408 | .resource = >a02_nor_flash_resource, | ||
409 | .num_resources = 1, | ||
410 | }; | ||
411 | |||
412 | |||
413 | struct platform_device s3c24xx_pwm_device = { | ||
414 | .name = "s3c24xx_pwm", | ||
415 | .num_resources = 0, | ||
416 | }; | ||
417 | |||
418 | static struct i2c_board_info gta02_i2c_devs[] __initdata = { | ||
419 | { | ||
420 | I2C_BOARD_INFO("pcf50633", 0x73), | ||
421 | .irq = GTA02_IRQ_PCF50633, | ||
422 | .platform_data = >a02_pcf_pdata, | ||
423 | }, | ||
424 | { | ||
425 | I2C_BOARD_INFO("wm8753", 0x1a), | ||
426 | }, | ||
427 | }; | ||
428 | |||
429 | static struct s3c2410_nand_set __initdata gta02_nand_sets[] = { | ||
430 | [0] = { | ||
431 | /* | ||
432 | * This name is also hard-coded in the boot loaders, so | ||
433 | * changing it would would require all users to upgrade | ||
434 | * their boot loaders, some of which are stored in a NOR | ||
435 | * that is considered to be immutable. | ||
436 | */ | ||
437 | .name = "neo1973-nand", | ||
438 | .nr_chips = 1, | ||
439 | .flash_bbt = 1, | ||
440 | }, | ||
441 | }; | ||
442 | |||
443 | /* | ||
444 | * Choose a set of timings derived from S3C@2442B MCP54 | ||
445 | * data sheet (K5D2G13ACM-D075 MCP Memory). | ||
446 | */ | ||
447 | |||
448 | static struct s3c2410_platform_nand __initdata gta02_nand_info = { | ||
449 | .tacls = 0, | ||
450 | .twrph0 = 25, | ||
451 | .twrph1 = 15, | ||
452 | .nr_sets = ARRAY_SIZE(gta02_nand_sets), | ||
453 | .sets = gta02_nand_sets, | ||
454 | }; | ||
455 | |||
456 | |||
457 | static void gta02_udc_command(enum s3c2410_udc_cmd_e cmd) | ||
458 | { | ||
459 | switch (cmd) { | ||
460 | case S3C2410_UDC_P_ENABLE: | ||
461 | pr_debug("%s S3C2410_UDC_P_ENABLE\n", __func__); | ||
462 | gpio_direction_output(GTA02_GPIO_USB_PULLUP, 1); | ||
463 | break; | ||
464 | case S3C2410_UDC_P_DISABLE: | ||
465 | pr_debug("%s S3C2410_UDC_P_DISABLE\n", __func__); | ||
466 | gpio_direction_output(GTA02_GPIO_USB_PULLUP, 0); | ||
467 | break; | ||
468 | case S3C2410_UDC_P_RESET: | ||
469 | pr_debug("%s S3C2410_UDC_P_RESET\n", __func__); | ||
470 | /* FIXME: Do something here. */ | ||
471 | } | ||
472 | } | ||
473 | |||
474 | /* Get PMU to set USB current limit accordingly. */ | ||
475 | static struct s3c2410_udc_mach_info gta02_udc_cfg = { | ||
476 | .vbus_draw = gta02_udc_vbus_draw, | ||
477 | .udc_command = gta02_udc_command, | ||
478 | |||
479 | }; | ||
480 | |||
481 | |||
482 | |||
483 | static void gta02_bl_set_intensity(int intensity) | ||
484 | { | ||
485 | struct pcf50633 *pcf = gta02_pcf; | ||
486 | int old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT); | ||
487 | |||
488 | /* We map 8-bit intensity to 6-bit intensity in hardware. */ | ||
489 | intensity >>= 2; | ||
490 | |||
491 | /* | ||
492 | * This can happen during, eg, print of panic on blanked console, | ||
493 | * but we can't service i2c without interrupts active, so abort. | ||
494 | */ | ||
495 | if (in_atomic()) { | ||
496 | printk(KERN_ERR "gta02_bl_set_intensity called while atomic\n"); | ||
497 | return; | ||
498 | } | ||
499 | |||
500 | old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT); | ||
501 | if (intensity == old_intensity) | ||
502 | return; | ||
503 | |||
504 | /* We can't do this anywhere else. */ | ||
505 | pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 5); | ||
506 | |||
507 | if (!(pcf50633_reg_read(pcf, PCF50633_REG_LEDENA) & 3)) | ||
508 | old_intensity = 0; | ||
509 | |||
510 | /* | ||
511 | * The PCF50633 cannot handle LEDOUT = 0 (datasheet p60) | ||
512 | * if seen, you have to re-enable the LED unit. | ||
513 | */ | ||
514 | if (!intensity || !old_intensity) | ||
515 | pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0); | ||
516 | |||
517 | /* Illegal to set LEDOUT to 0. */ | ||
518 | if (!intensity) | ||
519 | pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, 2); | ||
520 | else | ||
521 | pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, | ||
522 | intensity); | ||
523 | |||
524 | if (intensity) | ||
525 | pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 2); | ||
526 | |||
527 | } | ||
528 | |||
529 | static struct generic_bl_info gta02_bl_info = { | ||
530 | .name = "gta02-bl", | ||
531 | .max_intensity = 0xff, | ||
532 | .default_intensity = 0xff, | ||
533 | .set_bl_intensity = gta02_bl_set_intensity, | ||
534 | }; | ||
535 | |||
536 | static struct platform_device gta02_bl_dev = { | ||
537 | .name = "generic-bl", | ||
538 | .id = 1, | ||
539 | .dev = { | ||
540 | .platform_data = >a02_bl_info, | ||
541 | }, | ||
542 | }; | ||
543 | |||
544 | |||
545 | |||
546 | /* USB */ | ||
547 | static struct s3c2410_hcd_info gta02_usb_info __initdata = { | ||
548 | .port[0] = { | ||
549 | .flags = S3C_HCDFLG_USED, | ||
550 | }, | ||
551 | .port[1] = { | ||
552 | .flags = 0, | ||
553 | }, | ||
554 | }; | ||
555 | |||
556 | |||
557 | static void __init gta02_map_io(void) | ||
558 | { | ||
559 | s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc)); | ||
560 | s3c24xx_init_clocks(12000000); | ||
561 | s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs)); | ||
562 | } | ||
563 | |||
564 | |||
565 | /* These are the guys that don't need to be children of PMU. */ | ||
566 | |||
567 | static struct platform_device *gta02_devices[] __initdata = { | ||
568 | &s3c_device_ohci, | ||
569 | &s3c_device_wdt, | ||
570 | &s3c_device_sdi, | ||
571 | &s3c_device_usbgadget, | ||
572 | &s3c_device_nand, | ||
573 | >a02_nor_flash, | ||
574 | &s3c24xx_pwm_device, | ||
575 | &s3c_device_iis, | ||
576 | &s3c_device_i2c0, | ||
577 | }; | ||
578 | |||
579 | /* These guys DO need to be children of PMU. */ | ||
580 | |||
581 | static struct platform_device *gta02_devices_pmu_children[] = { | ||
582 | >a02_bl_dev, | ||
583 | }; | ||
584 | |||
585 | |||
586 | /* | ||
587 | * This is called when pc50633 is probed, quite late in the day since it is an | ||
588 | * I2C bus device. Here we can define platform devices with the advantage that | ||
589 | * we can mark the pcf50633 as the parent. This makes them get suspended and | ||
590 | * resumed with their parent the pcf50633 still around. All devices whose | ||
591 | * operation depends on something from pcf50633 must have this relationship | ||
592 | * made explicit like this, or suspend and resume will become an unreliable | ||
593 | * hellworld. | ||
594 | */ | ||
595 | |||
596 | static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf) | ||
597 | { | ||
598 | int n; | ||
599 | |||
600 | /* Grab a copy of the now probed PMU pointer. */ | ||
601 | gta02_pcf = pcf; | ||
602 | |||
603 | for (n = 0; n < ARRAY_SIZE(gta02_devices_pmu_children); n++) | ||
604 | gta02_devices_pmu_children[n]->dev.parent = pcf->dev; | ||
605 | |||
606 | platform_add_devices(gta02_devices_pmu_children, | ||
607 | ARRAY_SIZE(gta02_devices_pmu_children)); | ||
608 | } | ||
609 | |||
610 | static void gta02_poweroff(void) | ||
611 | { | ||
612 | pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1); | ||
613 | } | ||
614 | |||
615 | static void __init gta02_machine_init(void) | ||
616 | { | ||
617 | /* Set the panic callback to make AUX LED blink at ~5Hz. */ | ||
618 | panic_blink = gta02_panic_blink; | ||
619 | |||
620 | s3c_pm_init(); | ||
621 | |||
622 | #ifdef CONFIG_CHARGER_PCF50633 | ||
623 | INIT_DELAYED_WORK(>a02_charger_work, gta02_charger_worker); | ||
624 | #endif | ||
625 | |||
626 | s3c24xx_udc_set_platdata(>a02_udc_cfg); | ||
627 | s3c_ohci_set_platdata(>a02_usb_info); | ||
628 | s3c_nand_set_platdata(>a02_nand_info); | ||
629 | s3c_i2c0_set_platdata(NULL); | ||
630 | |||
631 | i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs)); | ||
632 | |||
633 | platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices)); | ||
634 | pm_power_off = gta02_poweroff; | ||
635 | } | ||
636 | |||
637 | |||
638 | MACHINE_START(NEO1973_GTA02, "GTA02") | ||
639 | /* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */ | ||
640 | .phys_io = S3C2410_PA_UART, | ||
641 | .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, | ||
642 | .boot_params = S3C2410_SDRAM_PA + 0x100, | ||
643 | .map_io = gta02_map_io, | ||
644 | .init_irq = s3c24xx_init_irq, | ||
645 | .init_machine = gta02_machine_init, | ||
646 | .timer = &s3c24xx_timer, | ||
647 | MACHINE_END | ||
diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c2440/mach-mini2440.c index 2068e9096a43..571b17683d96 100644 --- a/arch/arm/mach-s3c2440/mach-mini2440.c +++ b/arch/arm/mach-s3c2440/mach-mini2440.c | |||
@@ -506,9 +506,8 @@ static struct i2c_board_info mini2440_i2c_devs[] __initdata = { | |||
506 | }; | 506 | }; |
507 | 507 | ||
508 | static struct platform_device *mini2440_devices[] __initdata = { | 508 | static struct platform_device *mini2440_devices[] __initdata = { |
509 | &s3c_device_usb, | 509 | &s3c_device_ohci, |
510 | &s3c_device_wdt, | 510 | &s3c_device_wdt, |
511 | /* &s3c_device_adc,*/ /* ADC doesn't like living with touchscreen ! */ | ||
512 | &s3c_device_i2c0, | 511 | &s3c_device_i2c0, |
513 | &s3c_device_rtc, | 512 | &s3c_device_rtc, |
514 | &s3c_device_usbgadget, | 513 | &s3c_device_usbgadget, |
@@ -522,8 +521,6 @@ static struct platform_device *mini2440_devices[] __initdata = { | |||
522 | &s3c_device_sdi, | 521 | &s3c_device_sdi, |
523 | &s3c_device_iis, | 522 | &s3c_device_iis, |
524 | &mini2440_audio, | 523 | &mini2440_audio, |
525 | /* &s3c_device_timer[0],*/ /* buzzer pwm, no API for it */ | ||
526 | /* remaining devices are optional */ | ||
527 | }; | 524 | }; |
528 | 525 | ||
529 | static void __init mini2440_map_io(void) | 526 | static void __init mini2440_map_io(void) |
@@ -531,8 +528,6 @@ static void __init mini2440_map_io(void) | |||
531 | s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc)); | 528 | s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc)); |
532 | s3c24xx_init_clocks(12000000); | 529 | s3c24xx_init_clocks(12000000); |
533 | s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs)); | 530 | s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs)); |
534 | |||
535 | s3c_device_sdi.dev.platform_data = &mini2440_mmc_cfg; | ||
536 | } | 531 | } |
537 | 532 | ||
538 | /* | 533 | /* |
@@ -678,6 +673,7 @@ static void __init mini2440_init(void) | |||
678 | } | 673 | } |
679 | 674 | ||
680 | s3c24xx_udc_set_platdata(&mini2440_udc_cfg); | 675 | s3c24xx_udc_set_platdata(&mini2440_udc_cfg); |
676 | s3c24xx_mci_set_platdata(&mini2440_mmc_cfg); | ||
681 | s3c_nand_set_platdata(&mini2440_nand_info); | 677 | s3c_nand_set_platdata(&mini2440_nand_info); |
682 | s3c_i2c0_set_platdata(NULL); | 678 | s3c_i2c0_set_platdata(NULL); |
683 | 679 | ||
diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c index d43edede590e..342041593f22 100644 --- a/arch/arm/mach-s3c2440/mach-nexcoder.c +++ b/arch/arm/mach-s3c2440/mach-nexcoder.c | |||
@@ -41,7 +41,7 @@ | |||
41 | #include <plat/iic.h> | 41 | #include <plat/iic.h> |
42 | 42 | ||
43 | #include <plat/s3c2410.h> | 43 | #include <plat/s3c2410.h> |
44 | #include <plat/s3c2440.h> | 44 | #include <plat/s3c244x.h> |
45 | #include <plat/clock.h> | 45 | #include <plat/clock.h> |
46 | #include <plat/devs.h> | 46 | #include <plat/devs.h> |
47 | #include <plat/cpu.h> | 47 | #include <plat/cpu.h> |
@@ -106,7 +106,7 @@ static struct platform_device nexcoder_device_nor = { | |||
106 | /* Standard Nexcoder devices */ | 106 | /* Standard Nexcoder devices */ |
107 | 107 | ||
108 | static struct platform_device *nexcoder_devices[] __initdata = { | 108 | static struct platform_device *nexcoder_devices[] __initdata = { |
109 | &s3c_device_usb, | 109 | &s3c_device_ohci, |
110 | &s3c_device_lcd, | 110 | &s3c_device_lcd, |
111 | &s3c_device_wdt, | 111 | &s3c_device_wdt, |
112 | &s3c_device_i2c0, | 112 | &s3c_device_i2c0, |
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c index a952a13afb1f..1e836e506f8b 100644 --- a/arch/arm/mach-s3c2440/mach-rx3715.c +++ b/arch/arm/mach-s3c2440/mach-rx3715.c | |||
@@ -176,7 +176,7 @@ static struct s3c2410_platform_nand __initdata rx3715_nand_info = { | |||
176 | }; | 176 | }; |
177 | 177 | ||
178 | static struct platform_device *rx3715_devices[] __initdata = { | 178 | static struct platform_device *rx3715_devices[] __initdata = { |
179 | &s3c_device_usb, | 179 | &s3c_device_ohci, |
180 | &s3c_device_lcd, | 180 | &s3c_device_lcd, |
181 | &s3c_device_wdt, | 181 | &s3c_device_wdt, |
182 | &s3c_device_i2c0, | 182 | &s3c_device_i2c0, |
diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c index ec13e748ccc5..3ac3d636d615 100644 --- a/arch/arm/mach-s3c2440/mach-smdk2440.c +++ b/arch/arm/mach-s3c2440/mach-smdk2440.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <plat/iic.h> | 40 | #include <plat/iic.h> |
41 | 41 | ||
42 | #include <plat/s3c2410.h> | 42 | #include <plat/s3c2410.h> |
43 | #include <plat/s3c2440.h> | 43 | #include <plat/s3c244x.h> |
44 | #include <plat/clock.h> | 44 | #include <plat/clock.h> |
45 | #include <plat/devs.h> | 45 | #include <plat/devs.h> |
46 | #include <plat/cpu.h> | 46 | #include <plat/cpu.h> |
@@ -150,7 +150,7 @@ static struct s3c2410fb_mach_info smdk2440_fb_info __initdata = { | |||
150 | }; | 150 | }; |
151 | 151 | ||
152 | static struct platform_device *smdk2440_devices[] __initdata = { | 152 | static struct platform_device *smdk2440_devices[] __initdata = { |
153 | &s3c_device_usb, | 153 | &s3c_device_ohci, |
154 | &s3c_device_lcd, | 154 | &s3c_device_lcd, |
155 | &s3c_device_wdt, | 155 | &s3c_device_wdt, |
156 | &s3c_device_i2c0, | 156 | &s3c_device_i2c0, |
diff --git a/arch/arm/mach-s3c2440/s3c2440-cpufreq.c b/arch/arm/mach-s3c2440/s3c2440-cpufreq.c new file mode 100644 index 000000000000..976002fb1b8f --- /dev/null +++ b/arch/arm/mach-s3c2440/s3c2440-cpufreq.c | |||
@@ -0,0 +1,311 @@ | |||
1 | /* linux/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c | ||
2 | * | ||
3 | * Copyright (c) 2006-2009 Simtec Electronics | ||
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * Vincent Sanders <vince@simtec.co.uk> | ||
7 | * | ||
8 | * S3C2440/S3C2442 CPU Frequency scaling | ||
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/init.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/ioport.h> | ||
19 | #include <linux/cpufreq.h> | ||
20 | #include <linux/sysdev.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/clk.h> | ||
23 | #include <linux/err.h> | ||
24 | #include <linux/io.h> | ||
25 | |||
26 | #include <mach/hardware.h> | ||
27 | |||
28 | #include <asm/mach/arch.h> | ||
29 | #include <asm/mach/map.h> | ||
30 | |||
31 | #include <mach/regs-clock.h> | ||
32 | |||
33 | #include <plat/cpu.h> | ||
34 | #include <plat/cpu-freq-core.h> | ||
35 | #include <plat/clock.h> | ||
36 | |||
37 | static struct clk *xtal; | ||
38 | static struct clk *fclk; | ||
39 | static struct clk *hclk; | ||
40 | static struct clk *armclk; | ||
41 | |||
42 | /* HDIV: 1, 2, 3, 4, 6, 8 */ | ||
43 | |||
44 | static inline int within_khz(unsigned long a, unsigned long b) | ||
45 | { | ||
46 | long diff = a - b; | ||
47 | |||
48 | return (diff >= -1000 && diff <= 1000); | ||
49 | } | ||
50 | |||
51 | /** | ||
52 | * s3c2440_cpufreq_calcdivs - calculate divider settings | ||
53 | * @cfg: The cpu frequency settings. | ||
54 | * | ||
55 | * Calcualte the divider values for the given frequency settings | ||
56 | * specified in @cfg. The values are stored in @cfg for later use | ||
57 | * by the relevant set routine if the request settings can be reached. | ||
58 | */ | ||
59 | int s3c2440_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg) | ||
60 | { | ||
61 | unsigned int hdiv, pdiv; | ||
62 | unsigned long hclk, fclk, armclk; | ||
63 | unsigned long hclk_max; | ||
64 | |||
65 | fclk = cfg->freq.fclk; | ||
66 | armclk = cfg->freq.armclk; | ||
67 | hclk_max = cfg->max.hclk; | ||
68 | |||
69 | s3c_freq_dbg("%s: fclk is %lu, armclk %lu, max hclk %lu\n", | ||
70 | __func__, fclk, armclk, hclk_max); | ||
71 | |||
72 | if (armclk > fclk) { | ||
73 | printk(KERN_WARNING "%s: armclk > fclk\n", __func__); | ||
74 | armclk = fclk; | ||
75 | } | ||
76 | |||
77 | /* if we are in DVS, we need HCLK to be <= ARMCLK */ | ||
78 | if (armclk < fclk && armclk < hclk_max) | ||
79 | hclk_max = armclk; | ||
80 | |||
81 | for (hdiv = 1; hdiv < 9; hdiv++) { | ||
82 | if (hdiv == 5 || hdiv == 7) | ||
83 | hdiv++; | ||
84 | |||
85 | hclk = (fclk / hdiv); | ||
86 | if (hclk <= hclk_max || within_khz(hclk, hclk_max)) | ||
87 | break; | ||
88 | } | ||
89 | |||
90 | s3c_freq_dbg("%s: hclk %lu, div %d\n", __func__, hclk, hdiv); | ||
91 | |||
92 | if (hdiv > 8) | ||
93 | goto invalid; | ||
94 | |||
95 | pdiv = (hclk > cfg->max.pclk) ? 2 : 1; | ||
96 | |||
97 | if ((hclk / pdiv) > cfg->max.pclk) | ||
98 | pdiv++; | ||
99 | |||
100 | s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv); | ||
101 | |||
102 | if (pdiv > 2) | ||
103 | goto invalid; | ||
104 | |||
105 | pdiv *= hdiv; | ||
106 | |||
107 | /* calculate a valid armclk */ | ||
108 | |||
109 | if (armclk < hclk) | ||
110 | armclk = hclk; | ||
111 | |||
112 | /* if we're running armclk lower than fclk, this really means | ||
113 | * that the system should go into dvs mode, which means that | ||
114 | * armclk is connected to hclk. */ | ||
115 | if (armclk < fclk) { | ||
116 | cfg->divs.dvs = 1; | ||
117 | armclk = hclk; | ||
118 | } else | ||
119 | cfg->divs.dvs = 0; | ||
120 | |||
121 | cfg->freq.armclk = armclk; | ||
122 | |||
123 | /* store the result, and then return */ | ||
124 | |||
125 | cfg->divs.h_divisor = hdiv; | ||
126 | cfg->divs.p_divisor = pdiv; | ||
127 | |||
128 | return 0; | ||
129 | |||
130 | invalid: | ||
131 | return -EINVAL; | ||
132 | } | ||
133 | |||
134 | #define CAMDIVN_HCLK_HALF (S3C2440_CAMDIVN_HCLK3_HALF | \ | ||
135 | S3C2440_CAMDIVN_HCLK4_HALF) | ||
136 | |||
137 | /** | ||
138 | * s3c2440_cpufreq_setdivs - set the cpu frequency divider settings | ||
139 | * @cfg: The cpu frequency settings. | ||
140 | * | ||
141 | * Set the divisors from the settings in @cfg, which where generated | ||
142 | * during the calculation phase by s3c2440_cpufreq_calcdivs(). | ||
143 | */ | ||
144 | static void s3c2440_cpufreq_setdivs(struct s3c_cpufreq_config *cfg) | ||
145 | { | ||
146 | unsigned long clkdiv, camdiv; | ||
147 | |||
148 | s3c_freq_dbg("%s: divsiors: h=%d, p=%d\n", __func__, | ||
149 | cfg->divs.h_divisor, cfg->divs.p_divisor); | ||
150 | |||
151 | clkdiv = __raw_readl(S3C2410_CLKDIVN); | ||
152 | camdiv = __raw_readl(S3C2440_CAMDIVN); | ||
153 | |||
154 | clkdiv &= ~(S3C2440_CLKDIVN_HDIVN_MASK | S3C2440_CLKDIVN_PDIVN); | ||
155 | camdiv &= ~CAMDIVN_HCLK_HALF; | ||
156 | |||
157 | switch (cfg->divs.h_divisor) { | ||
158 | case 1: | ||
159 | clkdiv |= S3C2440_CLKDIVN_HDIVN_1; | ||
160 | break; | ||
161 | |||
162 | case 2: | ||
163 | clkdiv |= S3C2440_CLKDIVN_HDIVN_2; | ||
164 | break; | ||
165 | |||
166 | case 6: | ||
167 | camdiv |= S3C2440_CAMDIVN_HCLK3_HALF; | ||
168 | case 3: | ||
169 | clkdiv |= S3C2440_CLKDIVN_HDIVN_3_6; | ||
170 | break; | ||
171 | |||
172 | case 8: | ||
173 | camdiv |= S3C2440_CAMDIVN_HCLK4_HALF; | ||
174 | case 4: | ||
175 | clkdiv |= S3C2440_CLKDIVN_HDIVN_4_8; | ||
176 | break; | ||
177 | |||
178 | default: | ||
179 | BUG(); /* we don't expect to get here. */ | ||
180 | } | ||
181 | |||
182 | if (cfg->divs.p_divisor != cfg->divs.h_divisor) | ||
183 | clkdiv |= S3C2440_CLKDIVN_PDIVN; | ||
184 | |||
185 | /* todo - set pclk. */ | ||
186 | |||
187 | /* Write the divisors first with hclk intentionally halved so that | ||
188 | * when we write clkdiv we will under-frequency instead of over. We | ||
189 | * then make a short delay and remove the hclk halving if necessary. | ||
190 | */ | ||
191 | |||
192 | __raw_writel(camdiv | CAMDIVN_HCLK_HALF, S3C2440_CAMDIVN); | ||
193 | __raw_writel(clkdiv, S3C2410_CLKDIVN); | ||
194 | |||
195 | ndelay(20); | ||
196 | __raw_writel(camdiv, S3C2440_CAMDIVN); | ||
197 | |||
198 | clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk); | ||
199 | } | ||
200 | |||
201 | static int run_freq_for(unsigned long max_hclk, unsigned long fclk, | ||
202 | int *divs, | ||
203 | struct cpufreq_frequency_table *table, | ||
204 | size_t table_size) | ||
205 | { | ||
206 | unsigned long freq; | ||
207 | int index = 0; | ||
208 | int div; | ||
209 | |||
210 | for (div = *divs; div > 0; div = *divs++) { | ||
211 | freq = fclk / div; | ||
212 | |||
213 | if (freq > max_hclk && div != 1) | ||
214 | continue; | ||
215 | |||
216 | freq /= 1000; /* table is in kHz */ | ||
217 | index = s3c_cpufreq_addfreq(table, index, table_size, freq); | ||
218 | if (index < 0) | ||
219 | break; | ||
220 | } | ||
221 | |||
222 | return index; | ||
223 | } | ||
224 | |||
225 | static int hclk_divs[] = { 1, 2, 3, 4, 6, 8, -1 }; | ||
226 | |||
227 | static int s3c2440_cpufreq_calctable(struct s3c_cpufreq_config *cfg, | ||
228 | struct cpufreq_frequency_table *table, | ||
229 | size_t table_size) | ||
230 | { | ||
231 | int ret; | ||
232 | |||
233 | WARN_ON(cfg->info == NULL); | ||
234 | WARN_ON(cfg->board == NULL); | ||
235 | |||
236 | ret = run_freq_for(cfg->info->max.hclk, | ||
237 | cfg->info->max.fclk, | ||
238 | hclk_divs, | ||
239 | table, table_size); | ||
240 | |||
241 | s3c_freq_dbg("%s: returning %d\n", __func__, ret); | ||
242 | |||
243 | return ret; | ||
244 | } | ||
245 | |||
246 | struct s3c_cpufreq_info s3c2440_cpufreq_info = { | ||
247 | .max = { | ||
248 | .fclk = 400000000, | ||
249 | .hclk = 133333333, | ||
250 | .pclk = 66666666, | ||
251 | }, | ||
252 | |||
253 | .locktime_m = 300, | ||
254 | .locktime_u = 300, | ||
255 | .locktime_bits = 16, | ||
256 | |||
257 | .name = "s3c244x", | ||
258 | .calc_iotiming = s3c2410_iotiming_calc, | ||
259 | .set_iotiming = s3c2410_iotiming_set, | ||
260 | .get_iotiming = s3c2410_iotiming_get, | ||
261 | .set_fvco = s3c2410_set_fvco, | ||
262 | |||
263 | .set_refresh = s3c2410_cpufreq_setrefresh, | ||
264 | .set_divs = s3c2440_cpufreq_setdivs, | ||
265 | .calc_divs = s3c2440_cpufreq_calcdivs, | ||
266 | .calc_freqtable = s3c2440_cpufreq_calctable, | ||
267 | |||
268 | .resume_clocks = s3c244x_setup_clocks, | ||
269 | |||
270 | .debug_io_show = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs), | ||
271 | }; | ||
272 | |||
273 | static int s3c2440_cpufreq_add(struct sys_device *sysdev) | ||
274 | { | ||
275 | xtal = s3c_cpufreq_clk_get(NULL, "xtal"); | ||
276 | hclk = s3c_cpufreq_clk_get(NULL, "hclk"); | ||
277 | fclk = s3c_cpufreq_clk_get(NULL, "fclk"); | ||
278 | armclk = s3c_cpufreq_clk_get(NULL, "armclk"); | ||
279 | |||
280 | if (IS_ERR(xtal) || IS_ERR(hclk) || IS_ERR(fclk) || IS_ERR(armclk)) { | ||
281 | printk(KERN_ERR "%s: failed to get clocks\n", __func__); | ||
282 | return -ENOENT; | ||
283 | } | ||
284 | |||
285 | return s3c_cpufreq_register(&s3c2440_cpufreq_info); | ||
286 | } | ||
287 | |||
288 | static struct sysdev_driver s3c2440_cpufreq_driver = { | ||
289 | .add = s3c2440_cpufreq_add, | ||
290 | }; | ||
291 | |||
292 | static int s3c2440_cpufreq_init(void) | ||
293 | { | ||
294 | return sysdev_driver_register(&s3c2440_sysclass, | ||
295 | &s3c2440_cpufreq_driver); | ||
296 | } | ||
297 | |||
298 | /* arch_initcall adds the clocks we need, so use subsys_initcall. */ | ||
299 | subsys_initcall(s3c2440_cpufreq_init); | ||
300 | |||
301 | static struct sysdev_driver s3c2442_cpufreq_driver = { | ||
302 | .add = s3c2440_cpufreq_add, | ||
303 | }; | ||
304 | |||
305 | static int s3c2442_cpufreq_init(void) | ||
306 | { | ||
307 | return sysdev_driver_register(&s3c2442_sysclass, | ||
308 | &s3c2442_cpufreq_driver); | ||
309 | } | ||
310 | |||
311 | subsys_initcall(s3c2442_cpufreq_init); | ||
diff --git a/arch/arm/mach-s3c2440/s3c2440-pll-12000000.c b/arch/arm/mach-s3c2440/s3c2440-pll-12000000.c new file mode 100644 index 000000000000..f105d5e8c477 --- /dev/null +++ b/arch/arm/mach-s3c2440/s3c2440-pll-12000000.c | |||
@@ -0,0 +1,97 @@ | |||
1 | /* arch/arm/mach-s3c2440/s3c2440-pll-12000000.c | ||
2 | * | ||
3 | * Copyright (c) 2006-2007 Simtec Electronics | ||
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * Vincent Sanders <vince@arm.linux.org.uk> | ||
7 | * | ||
8 | * S3C2440/S3C2442 CPU PLL tables (12MHz Crystal) | ||
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/types.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/sysdev.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/err.h> | ||
20 | |||
21 | #include <plat/cpu.h> | ||
22 | #include <plat/cpu-freq-core.h> | ||
23 | |||
24 | static struct cpufreq_frequency_table s3c2440_plls_12[] __initdata = { | ||
25 | { .frequency = 75000000, .index = PLLVAL(0x75, 3, 3), }, /* FVco 600.000000 */ | ||
26 | { .frequency = 80000000, .index = PLLVAL(0x98, 4, 3), }, /* FVco 640.000000 */ | ||
27 | { .frequency = 90000000, .index = PLLVAL(0x70, 2, 3), }, /* FVco 720.000000 */ | ||
28 | { .frequency = 100000000, .index = PLLVAL(0x5c, 1, 3), }, /* FVco 800.000000 */ | ||
29 | { .frequency = 110000000, .index = PLLVAL(0x66, 1, 3), }, /* FVco 880.000000 */ | ||
30 | { .frequency = 120000000, .index = PLLVAL(0x70, 1, 3), }, /* FVco 960.000000 */ | ||
31 | { .frequency = 150000000, .index = PLLVAL(0x75, 3, 2), }, /* FVco 600.000000 */ | ||
32 | { .frequency = 160000000, .index = PLLVAL(0x98, 4, 2), }, /* FVco 640.000000 */ | ||
33 | { .frequency = 170000000, .index = PLLVAL(0x4d, 1, 2), }, /* FVco 680.000000 */ | ||
34 | { .frequency = 180000000, .index = PLLVAL(0x70, 2, 2), }, /* FVco 720.000000 */ | ||
35 | { .frequency = 190000000, .index = PLLVAL(0x57, 1, 2), }, /* FVco 760.000000 */ | ||
36 | { .frequency = 200000000, .index = PLLVAL(0x5c, 1, 2), }, /* FVco 800.000000 */ | ||
37 | { .frequency = 210000000, .index = PLLVAL(0x84, 2, 2), }, /* FVco 840.000000 */ | ||
38 | { .frequency = 220000000, .index = PLLVAL(0x66, 1, 2), }, /* FVco 880.000000 */ | ||
39 | { .frequency = 230000000, .index = PLLVAL(0x6b, 1, 2), }, /* FVco 920.000000 */ | ||
40 | { .frequency = 240000000, .index = PLLVAL(0x70, 1, 2), }, /* FVco 960.000000 */ | ||
41 | { .frequency = 300000000, .index = PLLVAL(0x75, 3, 1), }, /* FVco 600.000000 */ | ||
42 | { .frequency = 310000000, .index = PLLVAL(0x93, 4, 1), }, /* FVco 620.000000 */ | ||
43 | { .frequency = 320000000, .index = PLLVAL(0x98, 4, 1), }, /* FVco 640.000000 */ | ||
44 | { .frequency = 330000000, .index = PLLVAL(0x66, 2, 1), }, /* FVco 660.000000 */ | ||
45 | { .frequency = 340000000, .index = PLLVAL(0x4d, 1, 1), }, /* FVco 680.000000 */ | ||
46 | { .frequency = 350000000, .index = PLLVAL(0xa7, 4, 1), }, /* FVco 700.000000 */ | ||
47 | { .frequency = 360000000, .index = PLLVAL(0x70, 2, 1), }, /* FVco 720.000000 */ | ||
48 | { .frequency = 370000000, .index = PLLVAL(0xb1, 4, 1), }, /* FVco 740.000000 */ | ||
49 | { .frequency = 380000000, .index = PLLVAL(0x57, 1, 1), }, /* FVco 760.000000 */ | ||
50 | { .frequency = 390000000, .index = PLLVAL(0x7a, 2, 1), }, /* FVco 780.000000 */ | ||
51 | { .frequency = 400000000, .index = PLLVAL(0x5c, 1, 1), }, /* FVco 800.000000 */ | ||
52 | }; | ||
53 | |||
54 | static int s3c2440_plls12_add(struct sys_device *dev) | ||
55 | { | ||
56 | struct clk *xtal_clk; | ||
57 | unsigned long xtal; | ||
58 | |||
59 | xtal_clk = clk_get(NULL, "xtal"); | ||
60 | if (IS_ERR(xtal_clk)) | ||
61 | return PTR_ERR(xtal_clk); | ||
62 | |||
63 | xtal = clk_get_rate(xtal_clk); | ||
64 | clk_put(xtal_clk); | ||
65 | |||
66 | if (xtal == 12000000) { | ||
67 | printk(KERN_INFO "Using PLL table for 12MHz crystal\n"); | ||
68 | return s3c_plltab_register(s3c2440_plls_12, | ||
69 | ARRAY_SIZE(s3c2440_plls_12)); | ||
70 | } | ||
71 | |||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static struct sysdev_driver s3c2440_plls12_drv = { | ||
76 | .add = s3c2440_plls12_add, | ||
77 | }; | ||
78 | |||
79 | static int __init s3c2440_pll_12mhz(void) | ||
80 | { | ||
81 | return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_plls12_drv); | ||
82 | |||
83 | } | ||
84 | |||
85 | arch_initcall(s3c2440_pll_12mhz); | ||
86 | |||
87 | static struct sysdev_driver s3c2442_plls12_drv = { | ||
88 | .add = s3c2440_plls12_add, | ||
89 | }; | ||
90 | |||
91 | static int __init s3c2442_pll_12mhz(void) | ||
92 | { | ||
93 | return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_plls12_drv); | ||
94 | |||
95 | } | ||
96 | |||
97 | arch_initcall(s3c2442_pll_12mhz); | ||
diff --git a/arch/arm/mach-s3c2440/s3c2440-pll-16934400.c b/arch/arm/mach-s3c2440/s3c2440-pll-16934400.c new file mode 100644 index 000000000000..c8a8f90ef382 --- /dev/null +++ b/arch/arm/mach-s3c2440/s3c2440-pll-16934400.c | |||
@@ -0,0 +1,127 @@ | |||
1 | /* arch/arm/mach-s3c2440/s3c2440-pll-16934400.c | ||
2 | * | ||
3 | * Copyright (c) 2006-2008 Simtec Electronics | ||
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * Vincent Sanders <vince@arm.linux.org.uk> | ||
7 | * | ||
8 | * S3C2440/S3C2442 CPU PLL tables (16.93444MHz Crystal) | ||
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/types.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/sysdev.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/err.h> | ||
20 | |||
21 | #include <plat/cpu.h> | ||
22 | #include <plat/cpu-freq-core.h> | ||
23 | |||
24 | static struct cpufreq_frequency_table s3c2440_plls_169344[] __initdata = { | ||
25 | { .frequency = 78019200, .index = PLLVAL(121, 5, 3), }, /* FVco 624.153600 */ | ||
26 | { .frequency = 84067200, .index = PLLVAL(131, 5, 3), }, /* FVco 672.537600 */ | ||
27 | { .frequency = 90115200, .index = PLLVAL(141, 5, 3), }, /* FVco 720.921600 */ | ||
28 | { .frequency = 96163200, .index = PLLVAL(151, 5, 3), }, /* FVco 769.305600 */ | ||
29 | { .frequency = 102135600, .index = PLLVAL(185, 6, 3), }, /* FVco 817.084800 */ | ||
30 | { .frequency = 108259200, .index = PLLVAL(171, 5, 3), }, /* FVco 866.073600 */ | ||
31 | { .frequency = 114307200, .index = PLLVAL(127, 3, 3), }, /* FVco 914.457600 */ | ||
32 | { .frequency = 120234240, .index = PLLVAL(134, 3, 3), }, /* FVco 961.873920 */ | ||
33 | { .frequency = 126161280, .index = PLLVAL(141, 3, 3), }, /* FVco 1009.290240 */ | ||
34 | { .frequency = 132088320, .index = PLLVAL(148, 3, 3), }, /* FVco 1056.706560 */ | ||
35 | { .frequency = 138015360, .index = PLLVAL(155, 3, 3), }, /* FVco 1104.122880 */ | ||
36 | { .frequency = 144789120, .index = PLLVAL(163, 3, 3), }, /* FVco 1158.312960 */ | ||
37 | { .frequency = 150100363, .index = PLLVAL(187, 9, 2), }, /* FVco 600.401454 */ | ||
38 | { .frequency = 156038400, .index = PLLVAL(121, 5, 2), }, /* FVco 624.153600 */ | ||
39 | { .frequency = 162086400, .index = PLLVAL(126, 5, 2), }, /* FVco 648.345600 */ | ||
40 | { .frequency = 168134400, .index = PLLVAL(131, 5, 2), }, /* FVco 672.537600 */ | ||
41 | { .frequency = 174048000, .index = PLLVAL(177, 7, 2), }, /* FVco 696.192000 */ | ||
42 | { .frequency = 180230400, .index = PLLVAL(141, 5, 2), }, /* FVco 720.921600 */ | ||
43 | { .frequency = 186278400, .index = PLLVAL(124, 4, 2), }, /* FVco 745.113600 */ | ||
44 | { .frequency = 192326400, .index = PLLVAL(151, 5, 2), }, /* FVco 769.305600 */ | ||
45 | { .frequency = 198132480, .index = PLLVAL(109, 3, 2), }, /* FVco 792.529920 */ | ||
46 | { .frequency = 204271200, .index = PLLVAL(185, 6, 2), }, /* FVco 817.084800 */ | ||
47 | { .frequency = 210268800, .index = PLLVAL(141, 4, 2), }, /* FVco 841.075200 */ | ||
48 | { .frequency = 216518400, .index = PLLVAL(171, 5, 2), }, /* FVco 866.073600 */ | ||
49 | { .frequency = 222264000, .index = PLLVAL(97, 2, 2), }, /* FVco 889.056000 */ | ||
50 | { .frequency = 228614400, .index = PLLVAL(127, 3, 2), }, /* FVco 914.457600 */ | ||
51 | { .frequency = 234259200, .index = PLLVAL(158, 4, 2), }, /* FVco 937.036800 */ | ||
52 | { .frequency = 240468480, .index = PLLVAL(134, 3, 2), }, /* FVco 961.873920 */ | ||
53 | { .frequency = 246960000, .index = PLLVAL(167, 4, 2), }, /* FVco 987.840000 */ | ||
54 | { .frequency = 252322560, .index = PLLVAL(141, 3, 2), }, /* FVco 1009.290240 */ | ||
55 | { .frequency = 258249600, .index = PLLVAL(114, 2, 2), }, /* FVco 1032.998400 */ | ||
56 | { .frequency = 264176640, .index = PLLVAL(148, 3, 2), }, /* FVco 1056.706560 */ | ||
57 | { .frequency = 270950400, .index = PLLVAL(120, 2, 2), }, /* FVco 1083.801600 */ | ||
58 | { .frequency = 276030720, .index = PLLVAL(155, 3, 2), }, /* FVco 1104.122880 */ | ||
59 | { .frequency = 282240000, .index = PLLVAL(92, 1, 2), }, /* FVco 1128.960000 */ | ||
60 | { .frequency = 289578240, .index = PLLVAL(163, 3, 2), }, /* FVco 1158.312960 */ | ||
61 | { .frequency = 294235200, .index = PLLVAL(131, 2, 2), }, /* FVco 1176.940800 */ | ||
62 | { .frequency = 300200727, .index = PLLVAL(187, 9, 1), }, /* FVco 600.401454 */ | ||
63 | { .frequency = 306358690, .index = PLLVAL(191, 9, 1), }, /* FVco 612.717380 */ | ||
64 | { .frequency = 312076800, .index = PLLVAL(121, 5, 1), }, /* FVco 624.153600 */ | ||
65 | { .frequency = 318366720, .index = PLLVAL(86, 3, 1), }, /* FVco 636.733440 */ | ||
66 | { .frequency = 324172800, .index = PLLVAL(126, 5, 1), }, /* FVco 648.345600 */ | ||
67 | { .frequency = 330220800, .index = PLLVAL(109, 4, 1), }, /* FVco 660.441600 */ | ||
68 | { .frequency = 336268800, .index = PLLVAL(131, 5, 1), }, /* FVco 672.537600 */ | ||
69 | { .frequency = 342074880, .index = PLLVAL(93, 3, 1), }, /* FVco 684.149760 */ | ||
70 | { .frequency = 348096000, .index = PLLVAL(177, 7, 1), }, /* FVco 696.192000 */ | ||
71 | { .frequency = 355622400, .index = PLLVAL(118, 4, 1), }, /* FVco 711.244800 */ | ||
72 | { .frequency = 360460800, .index = PLLVAL(141, 5, 1), }, /* FVco 720.921600 */ | ||
73 | { .frequency = 366206400, .index = PLLVAL(165, 6, 1), }, /* FVco 732.412800 */ | ||
74 | { .frequency = 372556800, .index = PLLVAL(124, 4, 1), }, /* FVco 745.113600 */ | ||
75 | { .frequency = 378201600, .index = PLLVAL(126, 4, 1), }, /* FVco 756.403200 */ | ||
76 | { .frequency = 384652800, .index = PLLVAL(151, 5, 1), }, /* FVco 769.305600 */ | ||
77 | { .frequency = 391608000, .index = PLLVAL(177, 6, 1), }, /* FVco 783.216000 */ | ||
78 | { .frequency = 396264960, .index = PLLVAL(109, 3, 1), }, /* FVco 792.529920 */ | ||
79 | { .frequency = 402192000, .index = PLLVAL(87, 2, 1), }, /* FVco 804.384000 */ | ||
80 | }; | ||
81 | |||
82 | static int s3c2440_plls169344_add(struct sys_device *dev) | ||
83 | { | ||
84 | struct clk *xtal_clk; | ||
85 | unsigned long xtal; | ||
86 | |||
87 | xtal_clk = clk_get(NULL, "xtal"); | ||
88 | if (IS_ERR(xtal_clk)) | ||
89 | return PTR_ERR(xtal_clk); | ||
90 | |||
91 | xtal = clk_get_rate(xtal_clk); | ||
92 | clk_put(xtal_clk); | ||
93 | |||
94 | if (xtal == 169344000) { | ||
95 | printk(KERN_INFO "Using PLL table for 16.9344MHz crystal\n"); | ||
96 | return s3c_plltab_register(s3c2440_plls_169344, | ||
97 | ARRAY_SIZE(s3c2440_plls_169344)); | ||
98 | } | ||
99 | |||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static struct sysdev_driver s3c2440_plls169344_drv = { | ||
104 | .add = s3c2440_plls169344_add, | ||
105 | }; | ||
106 | |||
107 | static int __init s3c2440_pll_16934400(void) | ||
108 | { | ||
109 | return sysdev_driver_register(&s3c2440_sysclass, | ||
110 | &s3c2440_plls169344_drv); | ||
111 | |||
112 | } | ||
113 | |||
114 | arch_initcall(s3c2440_pll_16934400); | ||
115 | |||
116 | static struct sysdev_driver s3c2442_plls169344_drv = { | ||
117 | .add = s3c2440_plls169344_add, | ||
118 | }; | ||
119 | |||
120 | static int __init s3c2442_pll_16934400(void) | ||
121 | { | ||
122 | return sysdev_driver_register(&s3c2442_sysclass, | ||
123 | &s3c2442_plls169344_drv); | ||
124 | |||
125 | } | ||
126 | |||
127 | arch_initcall(s3c2442_pll_16934400); | ||
diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c index ac1f7ea5f405..2b68f7ea45ae 100644 --- a/arch/arm/mach-s3c2440/s3c2440.c +++ b/arch/arm/mach-s3c2440/s3c2440.c | |||
@@ -29,9 +29,9 @@ | |||
29 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
30 | #include <asm/irq.h> | 30 | #include <asm/irq.h> |
31 | 31 | ||
32 | #include <plat/s3c2440.h> | ||
33 | #include <plat/devs.h> | 32 | #include <plat/devs.h> |
34 | #include <plat/cpu.h> | 33 | #include <plat/cpu.h> |
34 | #include <plat/s3c244x.h> | ||
35 | 35 | ||
36 | static struct sys_device s3c2440_sysdev = { | 36 | static struct sys_device s3c2440_sysdev = { |
37 | .cls = &s3c2440_sysclass, | 37 | .cls = &s3c2440_sysclass, |
diff --git a/arch/arm/mach-s3c2440/s3c2442.c b/arch/arm/mach-s3c2440/s3c2442.c new file mode 100644 index 000000000000..188ad1e57dc0 --- /dev/null +++ b/arch/arm/mach-s3c2440/s3c2442.c | |||
@@ -0,0 +1,165 @@ | |||
1 | /* linux/arch/arm/mach-s3c2442/s3c2442.c | ||
2 | * | ||
3 | * Copyright (c) 2004-2005 Simtec Electronics | ||
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * S3C2442 core and lock support | ||
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, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/init.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/list.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/err.h> | ||
30 | #include <linux/device.h> | ||
31 | #include <linux/sysdev.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/ioport.h> | ||
34 | #include <linux/mutex.h> | ||
35 | #include <linux/clk.h> | ||
36 | #include <linux/io.h> | ||
37 | |||
38 | #include <mach/hardware.h> | ||
39 | #include <asm/atomic.h> | ||
40 | #include <asm/irq.h> | ||
41 | |||
42 | #include <mach/regs-clock.h> | ||
43 | |||
44 | #include <plat/clock.h> | ||
45 | #include <plat/cpu.h> | ||
46 | |||
47 | /* S3C2442 extended clock support */ | ||
48 | |||
49 | static unsigned long s3c2442_camif_upll_round(struct clk *clk, | ||
50 | unsigned long rate) | ||
51 | { | ||
52 | unsigned long parent_rate = clk_get_rate(clk->parent); | ||
53 | int div; | ||
54 | |||
55 | if (rate > parent_rate) | ||
56 | return parent_rate; | ||
57 | |||
58 | div = parent_rate / rate; | ||
59 | |||
60 | if (div == 3) | ||
61 | return parent_rate / 3; | ||
62 | |||
63 | /* note, we remove the +/- 1 calculations for the divisor */ | ||
64 | |||
65 | div /= 2; | ||
66 | |||
67 | if (div < 1) | ||
68 | div = 1; | ||
69 | else if (div > 16) | ||
70 | div = 16; | ||
71 | |||
72 | return parent_rate / (div * 2); | ||
73 | } | ||
74 | |||
75 | static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate) | ||
76 | { | ||
77 | unsigned long parent_rate = clk_get_rate(clk->parent); | ||
78 | unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN); | ||
79 | |||
80 | rate = s3c2442_camif_upll_round(clk, rate); | ||
81 | |||
82 | camdivn &= ~S3C2442_CAMDIVN_CAMCLK_DIV3; | ||
83 | |||
84 | if (rate == parent_rate) { | ||
85 | camdivn &= ~S3C2440_CAMDIVN_CAMCLK_SEL; | ||
86 | } else if ((parent_rate / rate) == 3) { | ||
87 | camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL; | ||
88 | camdivn |= S3C2442_CAMDIVN_CAMCLK_DIV3; | ||
89 | } else { | ||
90 | camdivn &= ~S3C2440_CAMDIVN_CAMCLK_MASK; | ||
91 | camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL; | ||
92 | camdivn |= (((parent_rate / rate) / 2) - 1); | ||
93 | } | ||
94 | |||
95 | __raw_writel(camdivn, S3C2440_CAMDIVN); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | /* Extra S3C2442 clocks */ | ||
101 | |||
102 | static struct clk s3c2442_clk_cam = { | ||
103 | .name = "camif", | ||
104 | .id = -1, | ||
105 | .enable = s3c2410_clkcon_enable, | ||
106 | .ctrlbit = S3C2440_CLKCON_CAMERA, | ||
107 | }; | ||
108 | |||
109 | static struct clk s3c2442_clk_cam_upll = { | ||
110 | .name = "camif-upll", | ||
111 | .id = -1, | ||
112 | .ops = &(struct clk_ops) { | ||
113 | .set_rate = s3c2442_camif_upll_setrate, | ||
114 | .round_rate = s3c2442_camif_upll_round, | ||
115 | }, | ||
116 | }; | ||
117 | |||
118 | static int s3c2442_clk_add(struct sys_device *sysdev) | ||
119 | { | ||
120 | struct clk *clock_upll; | ||
121 | struct clk *clock_h; | ||
122 | struct clk *clock_p; | ||
123 | |||
124 | clock_p = clk_get(NULL, "pclk"); | ||
125 | clock_h = clk_get(NULL, "hclk"); | ||
126 | clock_upll = clk_get(NULL, "upll"); | ||
127 | |||
128 | if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) { | ||
129 | printk(KERN_ERR "S3C2442: Failed to get parent clocks\n"); | ||
130 | return -EINVAL; | ||
131 | } | ||
132 | |||
133 | s3c2442_clk_cam.parent = clock_h; | ||
134 | s3c2442_clk_cam_upll.parent = clock_upll; | ||
135 | |||
136 | s3c24xx_register_clock(&s3c2442_clk_cam); | ||
137 | s3c24xx_register_clock(&s3c2442_clk_cam_upll); | ||
138 | |||
139 | clk_disable(&s3c2442_clk_cam); | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | static struct sysdev_driver s3c2442_clk_driver = { | ||
145 | .add = s3c2442_clk_add, | ||
146 | }; | ||
147 | |||
148 | static __init int s3c2442_clk_init(void) | ||
149 | { | ||
150 | return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver); | ||
151 | } | ||
152 | |||
153 | arch_initcall(s3c2442_clk_init); | ||
154 | |||
155 | |||
156 | static struct sys_device s3c2442_sysdev = { | ||
157 | .cls = &s3c2442_sysclass, | ||
158 | }; | ||
159 | |||
160 | int __init s3c2442_init(void) | ||
161 | { | ||
162 | printk("S3C2442: Initialising architecture\n"); | ||
163 | |||
164 | return sysdev_register(&s3c2442_sysdev); | ||
165 | } | ||
diff --git a/arch/arm/mach-s3c2440/s3c244x-clock.c b/arch/arm/mach-s3c2440/s3c244x-clock.c new file mode 100644 index 000000000000..f8d96130d1d1 --- /dev/null +++ b/arch/arm/mach-s3c2440/s3c244x-clock.c | |||
@@ -0,0 +1,138 @@ | |||
1 | /* linux/arch/arm/plat-s3c24xx/s3c24xx-clock.c | ||
2 | * | ||
3 | * Copyright (c) 2004-2008 Simtec Electronics | ||
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * S3C2440/S3C2442 Common clock support | ||
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, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/init.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/list.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/err.h> | ||
30 | #include <linux/device.h> | ||
31 | #include <linux/sysdev.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/ioport.h> | ||
34 | #include <linux/clk.h> | ||
35 | #include <linux/io.h> | ||
36 | |||
37 | #include <mach/hardware.h> | ||
38 | #include <asm/atomic.h> | ||
39 | #include <asm/irq.h> | ||
40 | |||
41 | #include <mach/regs-clock.h> | ||
42 | |||
43 | #include <plat/clock.h> | ||
44 | #include <plat/cpu.h> | ||
45 | |||
46 | static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent) | ||
47 | { | ||
48 | unsigned long camdivn; | ||
49 | unsigned long dvs; | ||
50 | |||
51 | if (parent == &clk_f) | ||
52 | dvs = 0; | ||
53 | else if (parent == &clk_h) | ||
54 | dvs = S3C2440_CAMDIVN_DVSEN; | ||
55 | else | ||
56 | return -EINVAL; | ||
57 | |||
58 | clk->parent = parent; | ||
59 | |||
60 | camdivn = __raw_readl(S3C2440_CAMDIVN); | ||
61 | camdivn &= ~S3C2440_CAMDIVN_DVSEN; | ||
62 | camdivn |= dvs; | ||
63 | __raw_writel(camdivn, S3C2440_CAMDIVN); | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static struct clk clk_arm = { | ||
69 | .name = "armclk", | ||
70 | .id = -1, | ||
71 | .ops = &(struct clk_ops) { | ||
72 | .set_parent = s3c2440_setparent_armclk, | ||
73 | }, | ||
74 | }; | ||
75 | |||
76 | static int s3c244x_clk_add(struct sys_device *sysdev) | ||
77 | { | ||
78 | unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN); | ||
79 | unsigned long clkdivn; | ||
80 | struct clk *clock_upll; | ||
81 | int ret; | ||
82 | |||
83 | printk("S3C244X: Clock Support, DVS %s\n", | ||
84 | (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off"); | ||
85 | |||
86 | clk_arm.parent = (camdivn & S3C2440_CAMDIVN_DVSEN) ? &clk_h : &clk_f; | ||
87 | |||
88 | ret = s3c24xx_register_clock(&clk_arm); | ||
89 | if (ret < 0) { | ||
90 | printk(KERN_ERR "S3C24XX: Failed to add armclk (%d)\n", ret); | ||
91 | return ret; | ||
92 | } | ||
93 | |||
94 | clock_upll = clk_get(NULL, "upll"); | ||
95 | if (IS_ERR(clock_upll)) { | ||
96 | printk(KERN_ERR "S3C244X: Failed to get upll clock\n"); | ||
97 | return -ENOENT; | ||
98 | } | ||
99 | |||
100 | /* check rate of UPLL, and if it is near 96MHz, then change | ||
101 | * to using half the UPLL rate for the system */ | ||
102 | |||
103 | if (clk_get_rate(clock_upll) > (94 * MHZ)) { | ||
104 | clk_usb_bus.rate = clk_get_rate(clock_upll) / 2; | ||
105 | |||
106 | spin_lock(&clocks_lock); | ||
107 | |||
108 | clkdivn = __raw_readl(S3C2410_CLKDIVN); | ||
109 | clkdivn |= S3C2440_CLKDIVN_UCLK; | ||
110 | __raw_writel(clkdivn, S3C2410_CLKDIVN); | ||
111 | |||
112 | spin_unlock(&clocks_lock); | ||
113 | } | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static struct sysdev_driver s3c2440_clk_driver = { | ||
119 | .add = s3c244x_clk_add, | ||
120 | }; | ||
121 | |||
122 | static int s3c2440_clk_init(void) | ||
123 | { | ||
124 | return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver); | ||
125 | } | ||
126 | |||
127 | arch_initcall(s3c2440_clk_init); | ||
128 | |||
129 | static struct sysdev_driver s3c2442_clk_driver = { | ||
130 | .add = s3c244x_clk_add, | ||
131 | }; | ||
132 | |||
133 | static int s3c2442_clk_init(void) | ||
134 | { | ||
135 | return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver); | ||
136 | } | ||
137 | |||
138 | arch_initcall(s3c2442_clk_init); | ||
diff --git a/arch/arm/mach-s3c2440/s3c244x-irq.c b/arch/arm/mach-s3c2440/s3c244x-irq.c new file mode 100644 index 000000000000..a75c0c2431ea --- /dev/null +++ b/arch/arm/mach-s3c2440/s3c244x-irq.c | |||
@@ -0,0 +1,142 @@ | |||
1 | /* linux/arch/arm/plat-s3c24xx/s3c244x-irq.c | ||
2 | * | ||
3 | * Copyright (c) 2003-2004 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
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 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/init.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/ioport.h> | ||
26 | #include <linux/sysdev.h> | ||
27 | #include <linux/io.h> | ||
28 | |||
29 | #include <mach/hardware.h> | ||
30 | #include <asm/irq.h> | ||
31 | |||
32 | #include <asm/mach/irq.h> | ||
33 | |||
34 | #include <mach/regs-irq.h> | ||
35 | #include <mach/regs-gpio.h> | ||
36 | |||
37 | #include <plat/cpu.h> | ||
38 | #include <plat/pm.h> | ||
39 | #include <plat/irq.h> | ||
40 | |||
41 | /* camera irq */ | ||
42 | |||
43 | static void s3c_irq_demux_cam(unsigned int irq, | ||
44 | struct irq_desc *desc) | ||
45 | { | ||
46 | unsigned int subsrc, submsk; | ||
47 | |||
48 | /* read the current pending interrupts, and the mask | ||
49 | * for what it is available */ | ||
50 | |||
51 | subsrc = __raw_readl(S3C2410_SUBSRCPND); | ||
52 | submsk = __raw_readl(S3C2410_INTSUBMSK); | ||
53 | |||
54 | subsrc &= ~submsk; | ||
55 | subsrc >>= 11; | ||
56 | subsrc &= 3; | ||
57 | |||
58 | if (subsrc != 0) { | ||
59 | if (subsrc & 1) { | ||
60 | generic_handle_irq(IRQ_S3C2440_CAM_C); | ||
61 | } | ||
62 | if (subsrc & 2) { | ||
63 | generic_handle_irq(IRQ_S3C2440_CAM_P); | ||
64 | } | ||
65 | } | ||
66 | } | ||
67 | |||
68 | #define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0)) | ||
69 | |||
70 | static void | ||
71 | s3c_irq_cam_mask(unsigned int irqno) | ||
72 | { | ||
73 | s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11); | ||
74 | } | ||
75 | |||
76 | static void | ||
77 | s3c_irq_cam_unmask(unsigned int irqno) | ||
78 | { | ||
79 | s3c_irqsub_unmask(irqno, INTMSK_CAM); | ||
80 | } | ||
81 | |||
82 | static void | ||
83 | s3c_irq_cam_ack(unsigned int irqno) | ||
84 | { | ||
85 | s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11); | ||
86 | } | ||
87 | |||
88 | static struct irq_chip s3c_irq_cam = { | ||
89 | .mask = s3c_irq_cam_mask, | ||
90 | .unmask = s3c_irq_cam_unmask, | ||
91 | .ack = s3c_irq_cam_ack, | ||
92 | }; | ||
93 | |||
94 | static int s3c244x_irq_add(struct sys_device *sysdev) | ||
95 | { | ||
96 | unsigned int irqno; | ||
97 | |||
98 | set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip); | ||
99 | set_irq_handler(IRQ_NFCON, handle_level_irq); | ||
100 | set_irq_flags(IRQ_NFCON, IRQF_VALID); | ||
101 | |||
102 | /* add chained handler for camera */ | ||
103 | |||
104 | set_irq_chip(IRQ_CAM, &s3c_irq_level_chip); | ||
105 | set_irq_handler(IRQ_CAM, handle_level_irq); | ||
106 | set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam); | ||
107 | |||
108 | for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) { | ||
109 | set_irq_chip(irqno, &s3c_irq_cam); | ||
110 | set_irq_handler(irqno, handle_level_irq); | ||
111 | set_irq_flags(irqno, IRQF_VALID); | ||
112 | } | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static struct sysdev_driver s3c2440_irq_driver = { | ||
118 | .add = s3c244x_irq_add, | ||
119 | .suspend = s3c24xx_irq_suspend, | ||
120 | .resume = s3c24xx_irq_resume, | ||
121 | }; | ||
122 | |||
123 | static int s3c2440_irq_init(void) | ||
124 | { | ||
125 | return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver); | ||
126 | } | ||
127 | |||
128 | arch_initcall(s3c2440_irq_init); | ||
129 | |||
130 | static struct sysdev_driver s3c2442_irq_driver = { | ||
131 | .add = s3c244x_irq_add, | ||
132 | .suspend = s3c24xx_irq_suspend, | ||
133 | .resume = s3c24xx_irq_resume, | ||
134 | }; | ||
135 | |||
136 | |||
137 | static int s3c2442_irq_init(void) | ||
138 | { | ||
139 | return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_irq_driver); | ||
140 | } | ||
141 | |||
142 | arch_initcall(s3c2442_irq_init); | ||
diff --git a/arch/arm/mach-s3c2440/s3c244x.c b/arch/arm/mach-s3c2440/s3c244x.c new file mode 100644 index 000000000000..5e4a97e76533 --- /dev/null +++ b/arch/arm/mach-s3c2440/s3c244x.c | |||
@@ -0,0 +1,195 @@ | |||
1 | /* linux/arch/arm/plat-s3c24xx/s3c244x.c | ||
2 | * | ||
3 | * Copyright (c) 2004-2006 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * Samsung S3C2440 and S3C2442 Mobile CPU support (not S3C2443) | ||
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/types.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/list.h> | ||
17 | #include <linux/timer.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/serial_core.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/sysdev.h> | ||
22 | #include <linux/clk.h> | ||
23 | #include <linux/io.h> | ||
24 | |||
25 | #include <asm/mach/arch.h> | ||
26 | #include <asm/mach/map.h> | ||
27 | #include <asm/mach/irq.h> | ||
28 | |||
29 | #include <mach/hardware.h> | ||
30 | #include <asm/irq.h> | ||
31 | |||
32 | #include <plat/cpu-freq.h> | ||
33 | |||
34 | #include <mach/regs-clock.h> | ||
35 | #include <plat/regs-serial.h> | ||
36 | #include <mach/regs-gpio.h> | ||
37 | #include <mach/regs-gpioj.h> | ||
38 | #include <mach/regs-dsc.h> | ||
39 | |||
40 | #include <plat/s3c2410.h> | ||
41 | #include <plat/s3c244x.h> | ||
42 | #include <plat/clock.h> | ||
43 | #include <plat/devs.h> | ||
44 | #include <plat/cpu.h> | ||
45 | #include <plat/pm.h> | ||
46 | #include <plat/pll.h> | ||
47 | |||
48 | static struct map_desc s3c244x_iodesc[] __initdata = { | ||
49 | IODESC_ENT(CLKPWR), | ||
50 | IODESC_ENT(TIMER), | ||
51 | IODESC_ENT(WATCHDOG), | ||
52 | }; | ||
53 | |||
54 | /* uart initialisation */ | ||
55 | |||
56 | void __init s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no) | ||
57 | { | ||
58 | s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no); | ||
59 | } | ||
60 | |||
61 | void __init s3c244x_map_io(void) | ||
62 | { | ||
63 | /* register our io-tables */ | ||
64 | |||
65 | iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc)); | ||
66 | |||
67 | /* rename any peripherals used differing from the s3c2410 */ | ||
68 | |||
69 | s3c_device_sdi.name = "s3c2440-sdi"; | ||
70 | s3c_device_i2c0.name = "s3c2440-i2c"; | ||
71 | s3c_device_nand.name = "s3c2440-nand"; | ||
72 | s3c_device_ts.name = "s3c2440-ts"; | ||
73 | s3c_device_usbgadget.name = "s3c2440-usbgadget"; | ||
74 | } | ||
75 | |||
76 | void __init_or_cpufreq s3c244x_setup_clocks(void) | ||
77 | { | ||
78 | struct clk *xtal_clk; | ||
79 | unsigned long clkdiv; | ||
80 | unsigned long camdiv; | ||
81 | unsigned long xtal; | ||
82 | unsigned long hclk, fclk, pclk; | ||
83 | int hdiv = 1; | ||
84 | |||
85 | xtal_clk = clk_get(NULL, "xtal"); | ||
86 | xtal = clk_get_rate(xtal_clk); | ||
87 | clk_put(xtal_clk); | ||
88 | |||
89 | fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2; | ||
90 | |||
91 | clkdiv = __raw_readl(S3C2410_CLKDIVN); | ||
92 | camdiv = __raw_readl(S3C2440_CAMDIVN); | ||
93 | |||
94 | /* work out clock scalings */ | ||
95 | |||
96 | switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) { | ||
97 | case S3C2440_CLKDIVN_HDIVN_1: | ||
98 | hdiv = 1; | ||
99 | break; | ||
100 | |||
101 | case S3C2440_CLKDIVN_HDIVN_2: | ||
102 | hdiv = 2; | ||
103 | break; | ||
104 | |||
105 | case S3C2440_CLKDIVN_HDIVN_4_8: | ||
106 | hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4; | ||
107 | break; | ||
108 | |||
109 | case S3C2440_CLKDIVN_HDIVN_3_6: | ||
110 | hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3; | ||
111 | break; | ||
112 | } | ||
113 | |||
114 | hclk = fclk / hdiv; | ||
115 | pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN) ? 2 : 1); | ||
116 | |||
117 | /* print brief summary of clocks, etc */ | ||
118 | |||
119 | printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n", | ||
120 | print_mhz(fclk), print_mhz(hclk), print_mhz(pclk)); | ||
121 | |||
122 | s3c24xx_setup_clocks(fclk, hclk, pclk); | ||
123 | } | ||
124 | |||
125 | void __init s3c244x_init_clocks(int xtal) | ||
126 | { | ||
127 | /* initialise the clocks here, to allow other things like the | ||
128 | * console to use them, and to add new ones after the initialisation | ||
129 | */ | ||
130 | |||
131 | s3c24xx_register_baseclocks(xtal); | ||
132 | s3c244x_setup_clocks(); | ||
133 | s3c2410_baseclk_add(); | ||
134 | } | ||
135 | |||
136 | #ifdef CONFIG_PM | ||
137 | |||
138 | static struct sleep_save s3c244x_sleep[] = { | ||
139 | SAVE_ITEM(S3C2440_DSC0), | ||
140 | SAVE_ITEM(S3C2440_DSC1), | ||
141 | SAVE_ITEM(S3C2440_GPJDAT), | ||
142 | SAVE_ITEM(S3C2440_GPJCON), | ||
143 | SAVE_ITEM(S3C2440_GPJUP) | ||
144 | }; | ||
145 | |||
146 | static int s3c244x_suspend(struct sys_device *dev, pm_message_t state) | ||
147 | { | ||
148 | s3c_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep)); | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static int s3c244x_resume(struct sys_device *dev) | ||
153 | { | ||
154 | s3c_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep)); | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | #else | ||
159 | #define s3c244x_suspend NULL | ||
160 | #define s3c244x_resume NULL | ||
161 | #endif | ||
162 | |||
163 | /* Since the S3C2442 and S3C2440 share items, put both sysclasses here */ | ||
164 | |||
165 | struct sysdev_class s3c2440_sysclass = { | ||
166 | .name = "s3c2440-core", | ||
167 | .suspend = s3c244x_suspend, | ||
168 | .resume = s3c244x_resume | ||
169 | }; | ||
170 | |||
171 | struct sysdev_class s3c2442_sysclass = { | ||
172 | .name = "s3c2442-core", | ||
173 | .suspend = s3c244x_suspend, | ||
174 | .resume = s3c244x_resume | ||
175 | }; | ||
176 | |||
177 | /* need to register class before we actually register the device, and | ||
178 | * we also need to ensure that it has been initialised before any of the | ||
179 | * drivers even try to use it (even if not on an s3c2440 based system) | ||
180 | * as a driver which may support both 2410 and 2440 may try and use it. | ||
181 | */ | ||
182 | |||
183 | static int __init s3c2440_core_init(void) | ||
184 | { | ||
185 | return sysdev_class_register(&s3c2440_sysclass); | ||
186 | } | ||
187 | |||
188 | core_initcall(s3c2440_core_init); | ||
189 | |||
190 | static int __init s3c2442_core_init(void) | ||
191 | { | ||
192 | return sysdev_class_register(&s3c2442_sysclass); | ||
193 | } | ||
194 | |||
195 | core_initcall(s3c2442_core_init); | ||