1 Index: linux-2.6.30-rc6/arch/arm/plat-s3c/include/plat/pwm.h
2 ===================================================================
3 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
4 +++ linux-2.6.30-rc6/arch/arm/plat-s3c/include/plat/pwm.h 2009-05-18 19:08:30.000000000 +0200
6 +#ifndef __S3C2410_PWM_H
7 +#define __S3C2410_PWM_H
9 +#include <linux/err.h>
10 +#include <linux/platform_device.h>
11 +#include <linux/clk.h>
14 +#include <mach/hardware.h>
15 +#include <asm/mach-types.h>
16 +#include <plat/regs-timer.h>
27 + enum pwm_timer timerid;
29 + unsigned long pclk_rate;
30 + unsigned long prescaler;
31 + unsigned long divider;
32 + unsigned long counter;
33 + unsigned long comparer;
36 +struct s3c24xx_pwm_platform_data{
37 + /* callback to attach platform children (to enforce suspend / resume
39 + void (*attach_child_devices)(struct device *parent_device);
42 +int s3c2410_pwm_init(struct s3c2410_pwm *s3c2410_pwm);
43 +int s3c2410_pwm_enable(struct s3c2410_pwm *s3c2410_pwm);
44 +int s3c2410_pwm_disable(struct s3c2410_pwm *s3c2410_pwm);
45 +int s3c2410_pwm_start(struct s3c2410_pwm *s3c2410_pwm);
46 +int s3c2410_pwm_stop(struct s3c2410_pwm *s3c2410_pwm);
47 +int s3c2410_pwm_duty_cycle(int reg_value, struct s3c2410_pwm *s3c2410_pwm);
48 +int s3c2410_pwm_dumpregs(void);
50 +#endif /* __S3C2410_PWM_H */
51 Index: linux-2.6.30-rc6/arch/arm/plat-s3c/Kconfig
52 ===================================================================
53 --- linux-2.6.30-rc6.orig/arch/arm/plat-s3c/Kconfig 2009-05-18 19:08:29.000000000 +0200
54 +++ linux-2.6.30-rc6/arch/arm/plat-s3c/Kconfig 2009-05-18 19:08:30.000000000 +0200
57 Internal configuration for S3C DMA core
62 + PWM timer code for the S3C2410, and similar processors
64 # device definitions to compile in
67 Index: linux-2.6.30-rc6/arch/arm/plat-s3c/Makefile
68 ===================================================================
69 --- linux-2.6.30-rc6.orig/arch/arm/plat-s3c/Makefile 2009-05-18 19:08:29.000000000 +0200
70 +++ linux-2.6.30-rc6/arch/arm/plat-s3c/Makefile 2009-05-18 19:08:30.000000000 +0200
73 obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
74 obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o
75 +obj-$(CONFIG_S3C_PWM) += pwm.o
76 obj-$(CONFIG_S3C_DMA) += dma.o
78 Index: linux-2.6.30-rc6/arch/arm/plat-s3c/pwm.c
79 ===================================================================
80 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
81 +++ linux-2.6.30-rc6/arch/arm/plat-s3c/pwm.c 2009-05-18 19:08:30.000000000 +0200
84 + * arch/arm/plat-s3c/pwm.c
86 + * Copyright (c) by Javi Roman <javiroman@kernel-labs.org>
87 + * for the Openmoko Project.
89 + * S3C2410A SoC PWM support
91 + * This program is free software; you can redistribute it and/or modify
92 + * it under the terms of the GNU General Public License as published by
93 + * the Free Software Foundation; either version 2 of the License, or
94 + * (at your option) any later version.
96 + * You should have received a copy of the GNU General Public License
97 + * along with this program; if not, write to the Free Software
98 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
102 +#include <linux/kernel.h>
103 +#include <linux/init.h>
104 +#include <linux/clk.h>
105 +#include <linux/device.h>
106 +#include <mach/hardware.h>
107 +#include <plat/regs-timer.h>
108 +#include <plat/pwm.h>
112 + static unsigned long standby_reg_tcon;
113 + static unsigned long standby_reg_tcfg0;
114 + static unsigned long standby_reg_tcfg1;
117 +int s3c2410_pwm_disable(struct s3c2410_pwm *pwm)
119 + unsigned long tcon;
122 + tcon = __raw_readl(S3C2410_TCON);
123 + tcon &= 0xffffff00;
124 + __raw_writel(tcon, S3C2410_TCON);
126 + clk_disable(pwm->pclk);
127 + clk_put(pwm->pclk);
131 +EXPORT_SYMBOL_GPL(s3c2410_pwm_disable);
133 +int s3c2410_pwm_init(struct s3c2410_pwm *pwm)
135 + pwm->pclk = clk_get(NULL, "timers");
136 + if (IS_ERR(pwm->pclk))
137 + return PTR_ERR(pwm->pclk);
139 + clk_enable(pwm->pclk);
140 + pwm->pclk_rate = clk_get_rate(pwm->pclk);
143 +EXPORT_SYMBOL_GPL(s3c2410_pwm_init);
145 +int s3c2410_pwm_enable(struct s3c2410_pwm *pwm)
147 + unsigned long tcfg0, tcfg1, tcnt, tcmp;
149 + /* control registers bits */
150 + tcfg1 = __raw_readl(S3C2410_TCFG1);
151 + tcfg0 = __raw_readl(S3C2410_TCFG0);
153 + /* divider & scaler slection */
154 + switch (pwm->timerid) {
156 + tcfg1 &= ~S3C2410_TCFG1_MUX0_MASK;
157 + tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;
160 + tcfg1 &= ~S3C2410_TCFG1_MUX1_MASK;
161 + tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;
164 + tcfg1 &= ~S3C2410_TCFG1_MUX2_MASK;
165 + tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
168 + tcfg1 &= ~S3C2410_TCFG1_MUX3_MASK;
169 + tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
172 + /* timer four is not capable of doing PWM */
175 + clk_disable(pwm->pclk);
176 + clk_put(pwm->pclk);
180 + /* divider & scaler values */
181 + tcfg1 |= pwm->divider;
182 + __raw_writel(tcfg1, S3C2410_TCFG1);
184 + switch (pwm->timerid) {
187 + tcfg0 |= pwm->prescaler;
188 + __raw_writel(tcfg0, S3C2410_TCFG0);
191 + if ((tcfg0 | pwm->prescaler) != tcfg0) {
192 + printk(KERN_WARNING "not changing prescaler of PWM %u,"
193 + " since it's shared with timer4 (clock tick)\n",
199 + /* timer count and compare buffer initial values */
200 + tcnt = pwm->counter;
201 + tcmp = pwm->comparer;
203 + __raw_writel(tcnt, S3C2410_TCNTB(pwm->timerid));
204 + __raw_writel(tcmp, S3C2410_TCMPB(pwm->timerid));
206 + /* ensure timer is stopped */
207 + s3c2410_pwm_stop(pwm);
211 +EXPORT_SYMBOL_GPL(s3c2410_pwm_enable);
213 +int s3c2410_pwm_start(struct s3c2410_pwm *pwm)
215 + unsigned long tcon;
217 + tcon = __raw_readl(S3C2410_TCON);
219 + switch (pwm->timerid) {
221 + tcon |= S3C2410_TCON_T0START;
222 + tcon &= ~S3C2410_TCON_T0MANUALUPD;
225 + tcon |= S3C2410_TCON_T1START;
226 + tcon &= ~S3C2410_TCON_T1MANUALUPD;
229 + tcon |= S3C2410_TCON_T2START;
230 + tcon &= ~S3C2410_TCON_T2MANUALUPD;
233 + tcon |= S3C2410_TCON_T3START;
234 + tcon &= ~S3C2410_TCON_T3MANUALUPD;
237 + /* timer four is not capable of doing PWM */
242 + __raw_writel(tcon, S3C2410_TCON);
246 +EXPORT_SYMBOL_GPL(s3c2410_pwm_start);
248 +int s3c2410_pwm_stop(struct s3c2410_pwm *pwm)
250 + unsigned long tcon;
252 + tcon = __raw_readl(S3C2410_TCON);
254 + switch (pwm->timerid) {
256 + tcon &= ~0x00000000;
257 + tcon |= S3C2410_TCON_T0RELOAD;
258 + tcon |= S3C2410_TCON_T0MANUALUPD;
261 + tcon &= ~0x00000080;
262 + tcon |= S3C2410_TCON_T1RELOAD;
263 + tcon |= S3C2410_TCON_T1MANUALUPD;
266 + tcon &= ~0x00000800;
267 + tcon |= S3C2410_TCON_T2RELOAD;
268 + tcon |= S3C2410_TCON_T2MANUALUPD;
271 + tcon &= ~0x00008000;
272 + tcon |= S3C2410_TCON_T3RELOAD;
273 + tcon |= S3C2410_TCON_T3MANUALUPD;
276 + /* timer four is not capable of doing PWM */
281 + __raw_writel(tcon, S3C2410_TCON);
285 +EXPORT_SYMBOL_GPL(s3c2410_pwm_stop);
287 +int s3c2410_pwm_duty_cycle(int reg_value, struct s3c2410_pwm *pwm)
289 + __raw_writel(reg_value, S3C2410_TCMPB(pwm->timerid));
293 +EXPORT_SYMBOL_GPL(s3c2410_pwm_duty_cycle);
295 +int s3c2410_pwm_dumpregs(void)
297 + printk(KERN_INFO "TCON: %08lx, TCFG0: %08lx, TCFG1: %08lx\n",
298 + (unsigned long) __raw_readl(S3C2410_TCON),
299 + (unsigned long) __raw_readl(S3C2410_TCFG0),
300 + (unsigned long) __raw_readl(S3C2410_TCFG1));
304 +EXPORT_SYMBOL_GPL(s3c2410_pwm_dumpregs);
306 +static int __init s3c24xx_pwm_probe(struct platform_device *pdev)
308 + struct s3c24xx_pwm_platform_data *pdata = pdev->dev.platform_data;
310 + dev_info(&pdev->dev, "s3c24xx_pwm is registered \n");
312 + /* if platform was interested, give him a chance to register
313 + * platform devices that switch power with us as the parent
314 + * at registration time -- ensures suspend / resume ordering
317 + if (pdata->attach_child_devices)
318 + (pdata->attach_child_devices)(&pdev->dev);
324 +static int s3c24xx_pwm_suspend(struct platform_device *pdev, pm_message_t state)
326 + /* PWM config should be kept in suspending */
327 + standby_reg_tcon = __raw_readl(S3C2410_TCON);
328 + standby_reg_tcfg0 = __raw_readl(S3C2410_TCFG0);
329 + standby_reg_tcfg1 = __raw_readl(S3C2410_TCFG1);
334 +static int s3c24xx_pwm_resume(struct platform_device *pdev)
336 + __raw_writel(standby_reg_tcon, S3C2410_TCON);
337 + __raw_writel(standby_reg_tcfg0, S3C2410_TCFG0);
338 + __raw_writel(standby_reg_tcfg1, S3C2410_TCFG1);
343 +#define s3c24xx_pwm_suspend NULL
344 +#define s3c24xx_pwm_resume NULL
347 +static struct platform_driver s3c24xx_pwm_driver = {
349 + .name = "s3c24xx_pwm",
350 + .owner = THIS_MODULE,
352 + .probe = s3c24xx_pwm_probe,
353 + .suspend = s3c24xx_pwm_suspend,
354 + .resume = s3c24xx_pwm_resume,
357 +static int __init s3c24xx_pwm_init(void)
359 + return platform_driver_register(&s3c24xx_pwm_driver);
362 +static void __exit s3c24xx_pwm_exit(void)
366 +MODULE_AUTHOR("Javi Roman <javiroman@kernel-labs.org>");
367 +MODULE_LICENSE("GPL");
369 +module_init(s3c24xx_pwm_init);
370 +module_exit(s3c24xx_pwm_exit);
371 Index: linux-2.6.30-rc6/arch/arm/plat-s3c24xx/pwm-clock.c
372 ===================================================================
373 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
374 +++ linux-2.6.30-rc6/arch/arm/plat-s3c24xx/pwm-clock.c 2009-05-18 19:08:30.000000000 +0200
376 +/* linux/arch/arm/plat-s3c24xx/pwm-clock.c
378 + * Copyright (c) 2007 Simtec Electronics
379 + * Copyright (c) 2007, 2008 Ben Dooks
380 + * Ben Dooks <ben-linux@fluff.org>
382 + * This program is free software; you can redistribute it and/or modify
383 + * it under the terms of the GNU General Public License as published by
384 + * the Free Software Foundation; either version 2 of the License.
387 +#include <linux/init.h>
388 +#include <linux/module.h>
389 +#include <linux/kernel.h>
390 +#include <linux/list.h>
391 +#include <linux/errno.h>
392 +#include <linux/clk.h>
393 +#include <linux/err.h>
394 +#include <linux/io.h>
396 +#include <mach/hardware.h>
397 +#include <asm/irq.h>
399 +#include <mach/regs-clock.h>
400 +#include <mach/regs-gpio.h>
402 +#include <asm/plat-s3c24xx/clock.h>
403 +#include <asm/plat-s3c24xx/cpu.h>
405 +#include <asm/plat-s3c/regs-timer.h>
407 +/* Each of the timers 0 through 5 go through the following
408 + * clock tree, with the inputs depending on the timers.
410 + * pclk ---- [ prescaler 0 ] -+---> timer 0
413 + * pclk ---- [ prescaler 1 ] -+---> timer 2
417 + * Which are fed into the timers as so:
419 + * prescaled 0 ---- [ div 2,4,8,16 ] ---\
421 + * tclk 0 ------------------------------/
423 + * prescaled 0 ---- [ div 2,4,8,16 ] ---\
425 + * tclk 0 ------------------------------/
428 + * prescaled 1 ---- [ div 2,4,8,16 ] ---\
430 + * tclk 1 ------------------------------/
432 + * prescaled 1 ---- [ div 2,4,8,16 ] ---\
434 + * tclk 1 ------------------------------/
436 + * prescaled 1 ---- [ div 2,4,8, 16 ] --\
438 + * tclk 1 ------------------------------/
440 + * Since the mux and the divider are tied together in the
441 + * same register space, it is impossible to set the parent
442 + * and the rate at the same time. To avoid this, we add an
443 + * intermediate 'prescaled-and-divided' clock to select
444 + * as the parent for the timer input clock called tdiv.
446 + * prescaled clk --> pwm-tdiv ---\
447 + * [ mux ] --> timer X
448 + * tclk -------------------------/
451 +static unsigned long clk_pwm_scaler_getrate(struct clk *clk)
453 + unsigned long tcfg0 = __raw_readl(S3C2410_TCFG0);
455 + if (clk->id == 1) {
456 + tcfg0 &= S3C2410_TCFG_PRESCALER1_MASK;
457 + tcfg0 >>= S3C2410_TCFG_PRESCALER1_SHIFT;
459 + tcfg0 &= S3C2410_TCFG_PRESCALER0_MASK;
462 + return clk_get_rate(clk->parent) / (tcfg0 + 1);
465 +/* TODO - add set rate calls. */
467 +static struct clk clk_timer_scaler[] = {
469 + .name = "pwm-scaler0",
471 + .get_rate = clk_pwm_scaler_getrate,
474 + .name = "pwm-scaler1",
476 + .get_rate = clk_pwm_scaler_getrate,
480 +static struct clk clk_timer_tclk[] = {
482 + .name = "pwm-tclk0",
486 + .name = "pwm-tclk1",
491 +struct pwm_tdiv_clk {
493 + unsigned int divisor;
496 +static inline struct pwm_tdiv_clk *to_tdiv(struct clk *clk)
498 + return container_of(clk, struct pwm_tdiv_clk, clk);
501 +static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
503 + return 1 << (1 + tcfg1);
506 +static unsigned long clk_pwm_tdiv_get_rate(struct clk *clk)
508 + unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
509 + unsigned int divisor;
511 + tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
512 + tcfg1 &= S3C2410_TCFG1_MUX_MASK;
514 + if (tcfg1 == S3C2410_TCFG1_MUX_TCLK)
515 + divisor = to_tdiv(clk)->divisor;
517 + divisor = tcfg_to_divisor(tcfg1);
519 + return clk_get_rate(clk->parent) / divisor;
522 +static unsigned long clk_pwm_tdiv_round_rate(struct clk *clk,
523 + unsigned long rate)
525 + unsigned long parent_rate;
526 + unsigned long divisor;
528 + parent_rate = clk_get_rate(clk->parent);
529 + divisor = parent_rate / rate;
533 + else if (divisor <= 4)
535 + else if (divisor <= 8)
540 + return parent_rate / divisor;
543 +static unsigned long clk_pwm_tdiv_bits(struct pwm_tdiv_clk *divclk)
545 + unsigned long bits;
547 + switch (divclk->divisor) {
549 + bits = S3C2410_TCFG1_MUX_DIV2;
552 + bits = S3C2410_TCFG1_MUX_DIV4;
555 + bits = S3C2410_TCFG1_MUX_DIV8;
559 + bits = S3C2410_TCFG1_MUX_DIV16;
566 +static void clk_pwm_tdiv_update(struct pwm_tdiv_clk *divclk)
568 + unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
569 + unsigned long bits = clk_pwm_tdiv_bits(divclk);
570 + unsigned long flags;
571 + unsigned long shift = S3C2410_TCFG1_SHIFT(divclk->clk.id);
573 + local_irq_save(flags);
575 + tcfg1 = __raw_readl(S3C2410_TCFG1);
576 + tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
577 + tcfg1 |= bits << shift;
578 + __raw_writel(tcfg1, S3C2410_TCFG1);
580 + local_irq_restore(flags);
583 +static int clk_pwm_tdiv_set_rate(struct clk *clk, unsigned long rate)
585 + struct pwm_tdiv_clk *divclk = to_tdiv(clk);
586 + unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
587 + unsigned long parent_rate = clk_get_rate(clk->parent);
588 + unsigned long divisor;
590 + tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
591 + tcfg1 &= S3C2410_TCFG1_MUX_MASK;
593 + rate = clk_round_rate(clk, rate);
594 + divisor = parent_rate / rate;
599 + divclk->divisor = divisor;
601 + /* Update the current MUX settings if we are currently
602 + * selected as the clock source for this clock. */
604 + if (tcfg1 != S3C2410_TCFG1_MUX_TCLK)
605 + clk_pwm_tdiv_update(divclk);
610 +static struct pwm_tdiv_clk clk_timer_tdiv[] = {
613 + .name = "pwm-tdiv",
614 + .parent = &clk_timer_scaler[0],
615 + .get_rate = clk_pwm_tdiv_get_rate,
616 + .set_rate = clk_pwm_tdiv_set_rate,
617 + .round_rate = clk_pwm_tdiv_round_rate,
622 + .name = "pwm-tdiv",
623 + .parent = &clk_timer_scaler[0],
624 + .get_rate = clk_pwm_tdiv_get_rate,
625 + .set_rate = clk_pwm_tdiv_set_rate,
626 + .round_rate = clk_pwm_tdiv_round_rate,
631 + .name = "pwm-tdiv",
632 + .parent = &clk_timer_scaler[1],
633 + .get_rate = clk_pwm_tdiv_get_rate,
634 + .set_rate = clk_pwm_tdiv_set_rate,
635 + .round_rate = clk_pwm_tdiv_round_rate,
640 + .name = "pwm-tdiv",
641 + .parent = &clk_timer_scaler[1],
642 + .get_rate = clk_pwm_tdiv_get_rate,
643 + .set_rate = clk_pwm_tdiv_set_rate,
644 + .round_rate = clk_pwm_tdiv_round_rate,
649 + .name = "pwm-tdiv",
650 + .parent = &clk_timer_scaler[1],
651 + .get_rate = clk_pwm_tdiv_get_rate,
652 + .set_rate = clk_pwm_tdiv_set_rate,
653 + .round_rate = clk_pwm_tdiv_round_rate,
658 +static int __init clk_pwm_tdiv_register(unsigned int id)
660 + struct pwm_tdiv_clk *divclk = &clk_timer_tdiv[id];
661 + unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
663 + tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
664 + tcfg1 &= S3C2410_TCFG1_MUX_MASK;
666 + divclk->clk.id = id;
667 + divclk->divisor = tcfg_to_divisor(tcfg1);
669 + return s3c24xx_register_clock(&divclk->clk);
672 +static inline struct clk *s3c24xx_pwmclk_tclk(unsigned int id)
674 + return (id >= 2) ? &clk_timer_tclk[1] : &clk_timer_tclk[0];
677 +static inline struct clk *s3c24xx_pwmclk_tdiv(unsigned int id)
679 + return &clk_timer_tdiv[id].clk;
682 +static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent)
684 + unsigned int id = clk->id;
685 + unsigned long tcfg1;
686 + unsigned long flags;
687 + unsigned long bits;
688 + unsigned long shift = S3C2410_TCFG1_SHIFT(id);
690 + if (parent == s3c24xx_pwmclk_tclk(id))
691 + bits = S3C2410_TCFG1_MUX_TCLK << shift;
692 + else if (parent == s3c24xx_pwmclk_tdiv(id))
693 + bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift;
697 + clk->parent = parent;
699 + local_irq_save(flags);
701 + tcfg1 = __raw_readl(S3C2410_TCFG1);
702 + tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
703 + __raw_writel(tcfg1 | bits, S3C2410_TCFG1);
705 + local_irq_restore(flags);
710 +static struct clk clk_tin[] = {
714 + .set_parent = clk_pwm_tin_set_parent,
719 + .set_parent = clk_pwm_tin_set_parent,
724 + .set_parent = clk_pwm_tin_set_parent,
729 + .set_parent = clk_pwm_tin_set_parent,
734 + .set_parent = clk_pwm_tin_set_parent,
738 +static __init int clk_pwm_tin_register(struct clk *pwm)
740 + unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
741 + unsigned int id = pwm->id;
743 + struct clk *parent;
746 + ret = s3c24xx_register_clock(pwm);
750 + tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
751 + tcfg1 &= S3C2410_TCFG1_MUX_MASK;
753 + if (tcfg1 == S3C2410_TCFG1_MUX_TCLK)
754 + parent = s3c24xx_pwmclk_tclk(id);
756 + parent = s3c24xx_pwmclk_tdiv(id);
758 + return clk_set_parent(pwm, parent);
761 +static __init int s3c24xx_pwmclk_init(void)
763 + struct clk *clk_timers;
767 + clk_timers = clk_get(NULL, "timers");
768 + if (IS_ERR(clk_timers)) {
769 + printk(KERN_ERR "%s: no parent clock\n", __func__);
773 + for (clk = 0; clk < ARRAY_SIZE(clk_timer_scaler); clk++) {
774 + clk_timer_scaler[clk].parent = clk_timers;
775 + ret = s3c24xx_register_clock(&clk_timer_scaler[clk]);
777 + printk(KERN_ERR "error adding pwm scaler%d clock\n", clk);
782 + for (clk = 0; clk < ARRAY_SIZE(clk_timer_tclk); clk++) {
783 + ret = s3c24xx_register_clock(&clk_timer_tclk[clk]);
785 + printk(KERN_ERR "error adding pww tclk%d\n", clk);
790 + for (clk = 0; clk < ARRAY_SIZE(clk_timer_tdiv); clk++) {
791 + ret = clk_pwm_tdiv_register(clk);
793 + printk(KERN_ERR "error adding pwm%d tdiv clock\n", clk);
798 + for (clk = 0; clk < ARRAY_SIZE(clk_tin); clk++) {
799 + ret = clk_pwm_tin_register(&clk_tin[clk]);
801 + printk(KERN_ERR "error adding pwm%d tin clock\n", clk);
812 +arch_initcall(s3c24xx_pwmclk_init);