diff options
Diffstat (limited to 'arch/arm/plat-s3c24xx')
-rw-r--r-- | arch/arm/plat-s3c24xx/Kconfig | 28 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/adc.c | 372 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/devs.c | 10 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/include/mach/pwm-clock.h | 55 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/s3c2410-clock.c | 1 |
6 files changed, 466 insertions, 1 deletions
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig index f0d54fdf88d4..2c8a2f5d75ff 100644 --- a/arch/arm/plat-s3c24xx/Kconfig +++ b/arch/arm/plat-s3c24xx/Kconfig | |||
@@ -41,6 +41,27 @@ config S3C24XX_PWM | |||
41 | Support for exporting the PWM timer blocks via the pwm device | 41 | Support for exporting the PWM timer blocks via the pwm device |
42 | system. | 42 | system. |
43 | 43 | ||
44 | |||
45 | # gpio configurations | ||
46 | |||
47 | config S3C24XX_GPIO_EXTRA | ||
48 | int | ||
49 | default 128 if S3C24XX_GPIO_EXTRA128 | ||
50 | default 64 if S3C24XX_GPIO_EXTRA64 | ||
51 | default 0 | ||
52 | |||
53 | config S3C24XX_GPIO_EXTRA64 | ||
54 | bool | ||
55 | help | ||
56 | Add an extra 64 gpio numbers to the available GPIO pool. This is | ||
57 | available for boards that need extra gpios for external devices. | ||
58 | |||
59 | config S3C24XX_GPIO_EXTRA128 | ||
60 | bool | ||
61 | help | ||
62 | Add an extra 128 gpio numbers to the available GPIO pool. This is | ||
63 | available for boards that need extra gpios for external devices. | ||
64 | |||
44 | config PM_SIMTEC | 65 | config PM_SIMTEC |
45 | bool | 66 | bool |
46 | help | 67 | help |
@@ -62,6 +83,13 @@ config S3C2410_DMA_DEBUG | |||
62 | Enable debugging output for the DMA code. This option sends info | 83 | Enable debugging output for the DMA code. This option sends info |
63 | to the kernel log, at priority KERN_DEBUG. | 84 | to the kernel log, at priority KERN_DEBUG. |
64 | 85 | ||
86 | config S3C24XX_ADC | ||
87 | bool "ADC common driver support" | ||
88 | help | ||
89 | Core support for the ADC block found in the S3C24XX SoC systems | ||
90 | for drivers such as the touchscreen and hwmon to use to share | ||
91 | this resource. | ||
92 | |||
65 | # SPI default pin configuration code | 93 | # SPI default pin configuration code |
66 | 94 | ||
67 | config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13 | 95 | config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13 |
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile index 763d3444048b..1e0767b266b8 100644 --- a/arch/arm/plat-s3c24xx/Makefile +++ b/arch/arm/plat-s3c24xx/Makefile | |||
@@ -31,6 +31,7 @@ obj-$(CONFIG_PM) += sleep.o | |||
31 | obj-$(CONFIG_HAVE_PWM) += pwm.o | 31 | obj-$(CONFIG_HAVE_PWM) += pwm.o |
32 | obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o | 32 | obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o |
33 | obj-$(CONFIG_S3C2410_DMA) += dma.o | 33 | obj-$(CONFIG_S3C2410_DMA) += dma.o |
34 | obj-$(CONFIG_S3C24XX_ADC) += adc.o | ||
34 | 35 | ||
35 | # device specific setup and/or initialisation | 36 | # device specific setup and/or initialisation |
36 | obj-$(CONFIG_ARCH_S3C2410) += setup-i2c.o | 37 | obj-$(CONFIG_ARCH_S3C2410) += setup-i2c.o |
diff --git a/arch/arm/plat-s3c24xx/adc.c b/arch/arm/plat-s3c24xx/adc.c new file mode 100644 index 000000000000..9a5c767e0a42 --- /dev/null +++ b/arch/arm/plat-s3c24xx/adc.c | |||
@@ -0,0 +1,372 @@ | |||
1 | /* arch/arm/plat-s3c24xx/adc.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 | * S3C24XX ADC 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/list.h> | ||
18 | #include <linux/err.h> | ||
19 | #include <linux/clk.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/io.h> | ||
22 | |||
23 | #include <plat/regs-adc.h> | ||
24 | #include <plat/adc.h> | ||
25 | |||
26 | /* This driver is designed to control the usage of the ADC block between | ||
27 | * the touchscreen and any other drivers that may need to use it, such as | ||
28 | * the hwmon driver. | ||
29 | * | ||
30 | * Priority will be given to the touchscreen driver, but as this itself is | ||
31 | * rate limited it should not starve other requests which are processed in | ||
32 | * order that they are received. | ||
33 | * | ||
34 | * Each user registers to get a client block which uniquely identifies it | ||
35 | * and stores information such as the necessary functions to callback when | ||
36 | * action is required. | ||
37 | */ | ||
38 | |||
39 | struct s3c_adc_client { | ||
40 | struct platform_device *pdev; | ||
41 | struct list_head pend; | ||
42 | |||
43 | unsigned int nr_samples; | ||
44 | unsigned char is_ts; | ||
45 | unsigned char channel; | ||
46 | |||
47 | void (*select_cb)(unsigned selected); | ||
48 | void (*convert_cb)(unsigned val1, unsigned val2); | ||
49 | }; | ||
50 | |||
51 | struct adc_device { | ||
52 | struct platform_device *pdev; | ||
53 | struct platform_device *owner; | ||
54 | struct clk *clk; | ||
55 | struct s3c_adc_client *cur; | ||
56 | struct s3c_adc_client *ts_pend; | ||
57 | void __iomem *regs; | ||
58 | |||
59 | unsigned int prescale; | ||
60 | |||
61 | int irq; | ||
62 | }; | ||
63 | |||
64 | static struct adc_device *adc_dev; | ||
65 | |||
66 | static LIST_HEAD(adc_pending); | ||
67 | |||
68 | #define adc_dbg(_adc, msg...) dev_dbg(&(_adc)->pdev->dev, msg) | ||
69 | |||
70 | static inline void s3c_adc_convert(struct adc_device *adc) | ||
71 | { | ||
72 | unsigned con = readl(adc->regs + S3C2410_ADCCON); | ||
73 | |||
74 | con |= S3C2410_ADCCON_ENABLE_START; | ||
75 | writel(con, adc->regs + S3C2410_ADCCON); | ||
76 | } | ||
77 | |||
78 | static inline void s3c_adc_select(struct adc_device *adc, | ||
79 | struct s3c_adc_client *client) | ||
80 | { | ||
81 | unsigned con = readl(adc->regs + S3C2410_ADCCON); | ||
82 | |||
83 | client->select_cb(1); | ||
84 | |||
85 | con &= ~S3C2410_ADCCON_MUXMASK; | ||
86 | con &= ~S3C2410_ADCCON_STDBM; | ||
87 | con &= ~S3C2410_ADCCON_STARTMASK; | ||
88 | |||
89 | if (!client->is_ts) | ||
90 | con |= S3C2410_ADCCON_SELMUX(client->channel); | ||
91 | |||
92 | writel(con, adc->regs + S3C2410_ADCCON); | ||
93 | } | ||
94 | |||
95 | static void s3c_adc_dbgshow(struct adc_device *adc) | ||
96 | { | ||
97 | adc_dbg(adc, "CON=%08x, TSC=%08x, DLY=%08x\n", | ||
98 | readl(adc->regs + S3C2410_ADCCON), | ||
99 | readl(adc->regs + S3C2410_ADCTSC), | ||
100 | readl(adc->regs + S3C2410_ADCDLY)); | ||
101 | } | ||
102 | |||
103 | void s3c_adc_try(struct adc_device *adc) | ||
104 | { | ||
105 | struct s3c_adc_client *next = adc->ts_pend; | ||
106 | |||
107 | if (!next && !list_empty(&adc_pending)) { | ||
108 | next = list_first_entry(&adc_pending, | ||
109 | struct s3c_adc_client, pend); | ||
110 | list_del(&next->pend); | ||
111 | } else | ||
112 | adc->ts_pend = NULL; | ||
113 | |||
114 | if (next) { | ||
115 | adc_dbg(adc, "new client is %p\n", next); | ||
116 | adc->cur = next; | ||
117 | s3c_adc_select(adc, next); | ||
118 | s3c_adc_convert(adc); | ||
119 | s3c_adc_dbgshow(adc); | ||
120 | } | ||
121 | } | ||
122 | |||
123 | int s3c_adc_start(struct s3c_adc_client *client, | ||
124 | unsigned int channel, unsigned int nr_samples) | ||
125 | { | ||
126 | struct adc_device *adc = adc_dev; | ||
127 | unsigned long flags; | ||
128 | |||
129 | if (!adc) { | ||
130 | printk(KERN_ERR "%s: failed to find adc\n", __func__); | ||
131 | return -EINVAL; | ||
132 | } | ||
133 | |||
134 | if (client->is_ts && adc->ts_pend) | ||
135 | return -EAGAIN; | ||
136 | |||
137 | local_irq_save(flags); | ||
138 | |||
139 | client->channel = channel; | ||
140 | client->nr_samples = nr_samples; | ||
141 | |||
142 | if (client->is_ts) | ||
143 | adc->ts_pend = client; | ||
144 | else | ||
145 | list_add_tail(&client->pend, &adc_pending); | ||
146 | |||
147 | if (!adc->cur) | ||
148 | s3c_adc_try(adc); | ||
149 | local_irq_restore(flags); | ||
150 | |||
151 | return 0; | ||
152 | } | ||
153 | EXPORT_SYMBOL_GPL(s3c_adc_start); | ||
154 | |||
155 | static void s3c_adc_default_select(unsigned select) | ||
156 | { | ||
157 | } | ||
158 | |||
159 | struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev, | ||
160 | void (*select)(unsigned int selected), | ||
161 | void (*conv)(unsigned d0, unsigned d1), | ||
162 | unsigned int is_ts) | ||
163 | { | ||
164 | struct s3c_adc_client *client; | ||
165 | |||
166 | WARN_ON(!pdev); | ||
167 | WARN_ON(!conv); | ||
168 | |||
169 | if (!select) | ||
170 | select = s3c_adc_default_select; | ||
171 | |||
172 | if (!conv || !pdev) | ||
173 | return ERR_PTR(-EINVAL); | ||
174 | |||
175 | client = kzalloc(sizeof(struct s3c_adc_client), GFP_KERNEL); | ||
176 | if (!client) { | ||
177 | dev_err(&pdev->dev, "no memory for adc client\n"); | ||
178 | return ERR_PTR(-ENOMEM); | ||
179 | } | ||
180 | |||
181 | client->pdev = pdev; | ||
182 | client->is_ts = is_ts; | ||
183 | client->select_cb = select; | ||
184 | client->convert_cb = conv; | ||
185 | |||
186 | return client; | ||
187 | } | ||
188 | EXPORT_SYMBOL_GPL(s3c_adc_register); | ||
189 | |||
190 | void s3c_adc_release(struct s3c_adc_client *client) | ||
191 | { | ||
192 | /* We should really check that nothing is in progress. */ | ||
193 | kfree(client); | ||
194 | } | ||
195 | EXPORT_SYMBOL_GPL(s3c_adc_release); | ||
196 | |||
197 | static irqreturn_t s3c_adc_irq(int irq, void *pw) | ||
198 | { | ||
199 | struct adc_device *adc = pw; | ||
200 | struct s3c_adc_client *client = adc->cur; | ||
201 | unsigned long flags; | ||
202 | unsigned data0, data1; | ||
203 | |||
204 | if (!client) { | ||
205 | dev_warn(&adc->pdev->dev, "%s: no adc pending\n", __func__); | ||
206 | return IRQ_HANDLED; | ||
207 | } | ||
208 | |||
209 | data0 = readl(adc->regs + S3C2410_ADCDAT0); | ||
210 | data1 = readl(adc->regs + S3C2410_ADCDAT1); | ||
211 | adc_dbg(adc, "read %d: 0x%04x, 0x%04x\n", client->nr_samples, data0, data1); | ||
212 | |||
213 | (client->convert_cb)(data0 & 0x3ff, data1 & 0x3ff); | ||
214 | |||
215 | if (--client->nr_samples > 0) { | ||
216 | /* fire another conversion for this */ | ||
217 | |||
218 | client->select_cb(1); | ||
219 | s3c_adc_convert(adc); | ||
220 | } else { | ||
221 | local_irq_save(flags); | ||
222 | (client->select_cb)(0); | ||
223 | adc->cur = NULL; | ||
224 | |||
225 | s3c_adc_try(adc); | ||
226 | local_irq_restore(flags); | ||
227 | } | ||
228 | |||
229 | return IRQ_HANDLED; | ||
230 | } | ||
231 | |||
232 | static int s3c_adc_probe(struct platform_device *pdev) | ||
233 | { | ||
234 | struct device *dev = &pdev->dev; | ||
235 | struct adc_device *adc; | ||
236 | struct resource *regs; | ||
237 | int ret; | ||
238 | |||
239 | adc = kzalloc(sizeof(struct adc_device), GFP_KERNEL); | ||
240 | if (adc == NULL) { | ||
241 | dev_err(dev, "failed to allocate adc_device\n"); | ||
242 | return -ENOMEM; | ||
243 | } | ||
244 | |||
245 | adc->pdev = pdev; | ||
246 | adc->prescale = S3C2410_ADCCON_PRSCVL(49); | ||
247 | |||
248 | adc->irq = platform_get_irq(pdev, 1); | ||
249 | if (adc->irq <= 0) { | ||
250 | dev_err(dev, "failed to get adc irq\n"); | ||
251 | ret = -ENOENT; | ||
252 | goto err_alloc; | ||
253 | } | ||
254 | |||
255 | ret = request_irq(adc->irq, s3c_adc_irq, 0, dev_name(dev), adc); | ||
256 | if (ret < 0) { | ||
257 | dev_err(dev, "failed to attach adc irq\n"); | ||
258 | goto err_alloc; | ||
259 | } | ||
260 | |||
261 | adc->clk = clk_get(dev, "adc"); | ||
262 | if (IS_ERR(adc->clk)) { | ||
263 | dev_err(dev, "failed to get adc clock\n"); | ||
264 | ret = PTR_ERR(adc->clk); | ||
265 | goto err_irq; | ||
266 | } | ||
267 | |||
268 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
269 | if (!regs) { | ||
270 | dev_err(dev, "failed to find registers\n"); | ||
271 | ret = -ENXIO; | ||
272 | goto err_clk; | ||
273 | } | ||
274 | |||
275 | adc->regs = ioremap(regs->start, resource_size(regs)); | ||
276 | if (!adc->regs) { | ||
277 | dev_err(dev, "failed to map registers\n"); | ||
278 | ret = -ENXIO; | ||
279 | goto err_clk; | ||
280 | } | ||
281 | |||
282 | clk_enable(adc->clk); | ||
283 | |||
284 | writel(adc->prescale | S3C2410_ADCCON_PRSCEN, | ||
285 | adc->regs + S3C2410_ADCCON); | ||
286 | |||
287 | dev_info(dev, "attached adc driver\n"); | ||
288 | |||
289 | platform_set_drvdata(pdev, adc); | ||
290 | adc_dev = adc; | ||
291 | |||
292 | return 0; | ||
293 | |||
294 | err_clk: | ||
295 | clk_put(adc->clk); | ||
296 | |||
297 | err_irq: | ||
298 | free_irq(adc->irq, adc); | ||
299 | |||
300 | err_alloc: | ||
301 | kfree(adc); | ||
302 | return ret; | ||
303 | } | ||
304 | |||
305 | static int s3c_adc_remove(struct platform_device *pdev) | ||
306 | { | ||
307 | struct adc_device *adc = platform_get_drvdata(pdev); | ||
308 | |||
309 | iounmap(adc->regs); | ||
310 | free_irq(adc->irq, adc); | ||
311 | clk_disable(adc->clk); | ||
312 | clk_put(adc->clk); | ||
313 | kfree(adc); | ||
314 | |||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | #ifdef CONFIG_PM | ||
319 | static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state) | ||
320 | { | ||
321 | struct adc_device *adc = platform_get_drvdata(pdev); | ||
322 | u32 con; | ||
323 | |||
324 | con = readl(adc->regs + S3C2410_ADCCON); | ||
325 | con |= S3C2410_ADCCON_STDBM; | ||
326 | writel(con, adc->regs + S3C2410_ADCCON); | ||
327 | |||
328 | clk_disable(adc->clk); | ||
329 | |||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | static int s3c_adc_resume(struct platform_device *pdev) | ||
334 | { | ||
335 | struct adc_device *adc = platform_get_drvdata(pdev); | ||
336 | |||
337 | clk_enable(adc->clk); | ||
338 | |||
339 | writel(adc->prescale | S3C2410_ADCCON_PRSCEN, | ||
340 | adc->regs + S3C2410_ADCCON); | ||
341 | |||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | #else | ||
346 | #define s3c_adc_suspend NULL | ||
347 | #define s3c_adc_resume NULL | ||
348 | #endif | ||
349 | |||
350 | static struct platform_driver s3c_adc_driver = { | ||
351 | .driver = { | ||
352 | .name = "s3c24xx-adc", | ||
353 | .owner = THIS_MODULE, | ||
354 | }, | ||
355 | .probe = s3c_adc_probe, | ||
356 | .remove = __devexit_p(s3c_adc_remove), | ||
357 | .suspend = s3c_adc_suspend, | ||
358 | .resume = s3c_adc_resume, | ||
359 | }; | ||
360 | |||
361 | static int __init adc_init(void) | ||
362 | { | ||
363 | int ret; | ||
364 | |||
365 | ret = platform_driver_register(&s3c_adc_driver); | ||
366 | if (ret) | ||
367 | printk(KERN_ERR "%s: failed to add adc driver\n", __func__); | ||
368 | |||
369 | return ret; | ||
370 | } | ||
371 | |||
372 | arch_initcall(adc_init); | ||
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c index 3cb07b6a0e4c..14d4f0bc1253 100644 --- a/arch/arm/plat-s3c24xx/devs.c +++ b/arch/arm/plat-s3c24xx/devs.c | |||
@@ -347,12 +347,20 @@ static struct resource s3c_adc_resource[] = { | |||
347 | }; | 347 | }; |
348 | 348 | ||
349 | struct platform_device s3c_device_adc = { | 349 | struct platform_device s3c_device_adc = { |
350 | .name = "s3c2410-adc", | 350 | .name = "s3c24xx-adc", |
351 | .id = -1, | 351 | .id = -1, |
352 | .num_resources = ARRAY_SIZE(s3c_adc_resource), | 352 | .num_resources = ARRAY_SIZE(s3c_adc_resource), |
353 | .resource = s3c_adc_resource, | 353 | .resource = s3c_adc_resource, |
354 | }; | 354 | }; |
355 | 355 | ||
356 | /* HWMON */ | ||
357 | |||
358 | struct platform_device s3c_device_hwmon = { | ||
359 | .name = "s3c24xx-hwmon", | ||
360 | .id = -1, | ||
361 | .dev.parent = &s3c_device_adc.dev, | ||
362 | }; | ||
363 | |||
356 | /* SDI */ | 364 | /* SDI */ |
357 | 365 | ||
358 | static struct resource s3c_sdi_resource[] = { | 366 | static struct resource s3c_sdi_resource[] = { |
diff --git a/arch/arm/plat-s3c24xx/include/mach/pwm-clock.h b/arch/arm/plat-s3c24xx/include/mach/pwm-clock.h new file mode 100644 index 000000000000..a087de21bc20 --- /dev/null +++ b/arch/arm/plat-s3c24xx/include/mach/pwm-clock.h | |||
@@ -0,0 +1,55 @@ | |||
1 | /* linux/arch/arm/plat-s3c24xx/include/mach/pwm-clock.h | ||
2 | * | ||
3 | * Copyright 2008 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * | ||
7 | * S3C24xx - pwm clock and timer support | ||
8 | */ | ||
9 | |||
10 | /** | ||
11 | * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk | ||
12 | * @cfg: The timer TCFG1 register bits shifted down to 0. | ||
13 | * | ||
14 | * Return true if the given configuration from TCFG1 is a TCLK instead | ||
15 | * any of the TDIV clocks. | ||
16 | */ | ||
17 | static inline int pwm_cfg_src_is_tclk(unsigned long tcfg) | ||
18 | { | ||
19 | return tcfg == S3C2410_TCFG1_MUX_TCLK; | ||
20 | } | ||
21 | |||
22 | /** | ||
23 | * tcfg_to_divisor() - convert tcfg1 setting to a divisor | ||
24 | * @tcfg1: The tcfg1 setting, shifted down. | ||
25 | * | ||
26 | * Get the divisor value for the given tcfg1 setting. We assume the | ||
27 | * caller has already checked to see if this is not a TCLK source. | ||
28 | */ | ||
29 | static inline unsigned long tcfg_to_divisor(unsigned long tcfg1) | ||
30 | { | ||
31 | return 1 << (1 + tcfg1); | ||
32 | } | ||
33 | |||
34 | /** | ||
35 | * pwm_tdiv_has_div1() - does the tdiv setting have a /1 | ||
36 | * | ||
37 | * Return true if we have a /1 in the tdiv setting. | ||
38 | */ | ||
39 | static inline unsigned int pwm_tdiv_has_div1(void) | ||
40 | { | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | /** | ||
45 | * pwm_tdiv_div_bits() - calculate TCFG1 divisor value. | ||
46 | * @div: The divisor to calculate the bit information for. | ||
47 | * | ||
48 | * Turn a divisor into the necessary bit field for TCFG1. | ||
49 | */ | ||
50 | static inline unsigned long pwm_tdiv_div_bits(unsigned int div) | ||
51 | { | ||
52 | return ilog2(div) - 1; | ||
53 | } | ||
54 | |||
55 | #define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK | ||
diff --git a/arch/arm/plat-s3c24xx/s3c2410-clock.c b/arch/arm/plat-s3c24xx/s3c2410-clock.c index 4e07943c1e29..b61bdb793734 100644 --- a/arch/arm/plat-s3c24xx/s3c2410-clock.c +++ b/arch/arm/plat-s3c24xx/s3c2410-clock.c | |||
@@ -272,5 +272,6 @@ int __init s3c2410_baseclk_add(void) | |||
272 | (clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on", | 272 | (clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on", |
273 | (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on"); | 273 | (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on"); |
274 | 274 | ||
275 | s3c_pwmclk_init(); | ||
275 | return 0; | 276 | return 0; |
276 | } | 277 | } |