Blame view

arch/arm/plat-samsung/pwm-clock.c 10.4 KB
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  /* linux/arch/arm/plat-s3c24xx/pwm-clock.c
   *
   * Copyright (c) 2007 Simtec Electronics
   * Copyright (c) 2007, 2008 Ben Dooks
   *	Ben Dooks <ben-linux@fluff.org>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License.
  */
  
  #include <linux/init.h>
  #include <linux/module.h>
  #include <linux/kernel.h>
  #include <linux/list.h>
  #include <linux/errno.h>
b09bcdd4c   Ben Dooks   [ARM] S3C64XX: Up...
17
  #include <linux/log2.h>
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
18
19
20
  #include <linux/clk.h>
  #include <linux/err.h>
  #include <linux/io.h>
a09e64fbc   Russell King   [ARM] Move includ...
21
  #include <mach/hardware.h>
e550ae741   Ben Dooks   [ARM] S3C: Fix PW...
22
  #include <mach/map.h>
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
23
  #include <asm/irq.h>
d5120ae72   Ben Dooks   [ARM] S3C24XX: Ad...
24
  #include <plat/clock.h>
a2b7ba9ca   Ben Dooks   [ARM] S3C24XX: Mo...
25
  #include <plat/cpu.h>
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
26

a2b7ba9ca   Ben Dooks   [ARM] S3C24XX: Mo...
27
  #include <plat/regs-timer.h>
c0468b024   Kukjin Kim   ARM: SAMSUNG: Con...
28
  #include <plat/pwm-clock.h>
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
  
  /* Each of the timers 0 through 5 go through the following
   * clock tree, with the inputs depending on the timers.
   *
   * pclk ---- [ prescaler 0 ] -+---> timer 0
   *			      +---> timer 1
   *
   * pclk ---- [ prescaler 1 ] -+---> timer 2
   *			      +---> timer 3
   *			      \---> timer 4
   *
   * Which are fed into the timers as so:
   *
   * prescaled 0 ---- [ div 2,4,8,16 ] ---\
   *				       [mux] -> timer 0
   * tclk 0 ------------------------------/
   *
   * prescaled 0 ---- [ div 2,4,8,16 ] ---\
   *				       [mux] -> timer 1
   * tclk 0 ------------------------------/
   *
   *
   * prescaled 1 ---- [ div 2,4,8,16 ] ---\
   *				       [mux] -> timer 2
   * tclk 1 ------------------------------/
   *
   * prescaled 1 ---- [ div 2,4,8,16 ] ---\
   *				       [mux] -> timer 3
   * tclk 1 ------------------------------/
   *
   * prescaled 1 ---- [ div 2,4,8, 16 ] --\
   *				       [mux] -> timer 4
   * tclk 1 ------------------------------/
   *
   * Since the mux and the divider are tied together in the
   * same register space, it is impossible to set the parent
   * and the rate at the same time. To avoid this, we add an
   * intermediate 'prescaled-and-divided' clock to select
   * as the parent for the timer input clock called tdiv.
   *
   * prescaled clk --> pwm-tdiv ---\
   *                             [ mux ] --> timer X
   * tclk -------------------------/
  */
7d2dbcf9f   Ben Dooks   [ARM] S3C: Fix sc...
73
  static struct clk clk_timer_scaler[];
82fd8e681   Ben Dooks   [ARM] S3C: Add se...
74
  static unsigned long clk_pwm_scaler_get_rate(struct clk *clk)
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
75
76
  {
  	unsigned long tcfg0 = __raw_readl(S3C2410_TCFG0);
7d2dbcf9f   Ben Dooks   [ARM] S3C: Fix sc...
77
  	if (clk == &clk_timer_scaler[1]) {
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
78
79
80
81
82
83
84
85
  		tcfg0 &= S3C2410_TCFG_PRESCALER1_MASK;
  		tcfg0 >>= S3C2410_TCFG_PRESCALER1_SHIFT;
  	} else {
  		tcfg0 &= S3C2410_TCFG_PRESCALER0_MASK;
  	}
  
  	return clk_get_rate(clk->parent) / (tcfg0 + 1);
  }
82fd8e681   Ben Dooks   [ARM] S3C: Add se...
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  static unsigned long clk_pwm_scaler_round_rate(struct clk *clk,
  					       unsigned long rate)
  {
  	unsigned long parent_rate = clk_get_rate(clk->parent);
  	unsigned long divisor = parent_rate / rate;
  
  	if (divisor > 256)
  		divisor = 256;
  	else if (divisor < 2)
  		divisor = 2;
  
  	return parent_rate / divisor;
  }
  
  static int clk_pwm_scaler_set_rate(struct clk *clk, unsigned long rate)
  {
  	unsigned long round = clk_pwm_scaler_round_rate(clk, rate);
  	unsigned long tcfg0;
  	unsigned long divisor;
  	unsigned long flags;
  
  	divisor = clk_get_rate(clk->parent) / round;
  	divisor--;
  
  	local_irq_save(flags);
  	tcfg0 = __raw_readl(S3C2410_TCFG0);
7d2dbcf9f   Ben Dooks   [ARM] S3C: Fix sc...
112
  	if (clk == &clk_timer_scaler[1]) {
82fd8e681   Ben Dooks   [ARM] S3C: Add se...
113
114
115
116
117
118
119
120
121
122
123
124
  		tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
  		tcfg0 |= divisor << S3C2410_TCFG_PRESCALER1_SHIFT;
  	} else {
  		tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;
  		tcfg0 |= divisor;
  	}
  
  	__raw_writel(tcfg0, S3C2410_TCFG0);
  	local_irq_restore(flags);
  
  	return 0;
  }
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
125

b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
126
127
128
129
130
  static struct clk_ops clk_pwm_scaler_ops = {
  	.get_rate	= clk_pwm_scaler_get_rate,
  	.set_rate	= clk_pwm_scaler_set_rate,
  	.round_rate	= clk_pwm_scaler_round_rate,
  };
1442e662d   Ben Dooks   [ARM] S3C24XX: Fi...
131
  static struct clk clk_timer_scaler[] = {
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
132
133
134
  	[0]	= {
  		.name		= "pwm-scaler0",
  		.id		= -1,
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
135
  		.ops		= &clk_pwm_scaler_ops,
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
136
137
138
139
  	},
  	[1]	= {
  		.name		= "pwm-scaler1",
  		.id		= -1,
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
140
  		.ops		= &clk_pwm_scaler_ops,
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
141
142
  	},
  };
1442e662d   Ben Dooks   [ARM] S3C24XX: Fi...
143
  static struct clk clk_timer_tclk[] = {
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
  	[0]	= {
  		.name		= "pwm-tclk0",
  		.id		= -1,
  	},
  	[1]	= {
  		.name		= "pwm-tclk1",
  		.id		= -1,
  	},
  };
  
  struct pwm_tdiv_clk {
  	struct clk	clk;
  	unsigned int	divisor;
  };
  
  static inline struct pwm_tdiv_clk *to_tdiv(struct clk *clk)
  {
  	return container_of(clk, struct pwm_tdiv_clk, clk);
  }
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
163
164
165
166
167
168
169
  static unsigned long clk_pwm_tdiv_get_rate(struct clk *clk)
  {
  	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
  	unsigned int divisor;
  
  	tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
  	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
b09bcdd4c   Ben Dooks   [ARM] S3C64XX: Up...
170
  	if (pwm_cfg_src_is_tclk(tcfg1))
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
  		divisor = to_tdiv(clk)->divisor;
  	else
  		divisor = tcfg_to_divisor(tcfg1);
  
  	return clk_get_rate(clk->parent) / divisor;
  }
  
  static unsigned long clk_pwm_tdiv_round_rate(struct clk *clk,
  					     unsigned long rate)
  {
  	unsigned long parent_rate;
  	unsigned long divisor;
  
  	parent_rate = clk_get_rate(clk->parent);
  	divisor = parent_rate / rate;
b09bcdd4c   Ben Dooks   [ARM] S3C64XX: Up...
186
187
188
  	if (divisor <= 1 && pwm_tdiv_has_div1())
  		divisor = 1;
  	else if (divisor <= 2)
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
189
190
191
192
193
194
195
196
197
198
199
200
201
  		divisor = 2;
  	else if (divisor <= 4)
  		divisor = 4;
  	else if (divisor <= 8)
  		divisor = 8;
  	else
  		divisor = 16;
  
  	return parent_rate / divisor;
  }
  
  static unsigned long clk_pwm_tdiv_bits(struct pwm_tdiv_clk *divclk)
  {
b09bcdd4c   Ben Dooks   [ARM] S3C64XX: Up...
202
  	return pwm_tdiv_div_bits(divclk->divisor);
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
  }
  
  static void clk_pwm_tdiv_update(struct pwm_tdiv_clk *divclk)
  {
  	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
  	unsigned long bits = clk_pwm_tdiv_bits(divclk);
  	unsigned long flags;
  	unsigned long shift =  S3C2410_TCFG1_SHIFT(divclk->clk.id);
  
  	local_irq_save(flags);
  
  	tcfg1 = __raw_readl(S3C2410_TCFG1);
  	tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
  	tcfg1 |= bits << shift;
  	__raw_writel(tcfg1, S3C2410_TCFG1);
  
  	local_irq_restore(flags);
  }
  
  static int clk_pwm_tdiv_set_rate(struct clk *clk, unsigned long rate)
  {
  	struct pwm_tdiv_clk *divclk = to_tdiv(clk);
  	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
  	unsigned long parent_rate = clk_get_rate(clk->parent);
  	unsigned long divisor;
  
  	tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
  	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
  
  	rate = clk_round_rate(clk, rate);
  	divisor = parent_rate / rate;
  
  	if (divisor > 16)
  		return -EINVAL;
  
  	divclk->divisor = divisor;
  
  	/* Update the current MUX settings if we are currently
  	 * selected as the clock source for this clock. */
b09bcdd4c   Ben Dooks   [ARM] S3C64XX: Up...
242
  	if (!pwm_cfg_src_is_tclk(tcfg1))
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
243
244
245
246
  		clk_pwm_tdiv_update(divclk);
  
  	return 0;
  }
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
247
248
249
250
251
  static struct clk_ops clk_tdiv_ops = {
  	.get_rate	= clk_pwm_tdiv_get_rate,
  	.set_rate	= clk_pwm_tdiv_set_rate,
  	.round_rate	= clk_pwm_tdiv_round_rate,
  };
1442e662d   Ben Dooks   [ARM] S3C24XX: Fi...
252
  static struct pwm_tdiv_clk clk_timer_tdiv[] = {
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
253
254
  	[0]	= {
  		.clk	= {
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
255
  			.name	= "pwm-tdiv",
e83626f2f   Thomas Abraham   ARM: S3C24XX: Add...
256
  			.devname	= "s3c24xx-pwm.0",
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
257
258
  			.ops	= &clk_tdiv_ops,
  			.parent	= &clk_timer_scaler[0],
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
259
260
261
262
  		},
  	},
  	[1]	= {
  		.clk	= {
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
263
  			.name	= "pwm-tdiv",
e83626f2f   Thomas Abraham   ARM: S3C24XX: Add...
264
  			.devname	= "s3c24xx-pwm.1",
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
265
266
  			.ops	= &clk_tdiv_ops,
  			.parent	= &clk_timer_scaler[0],
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
267
268
269
270
  		}
  	},
  	[2]	= {
  		.clk	= {
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
271
  			.name	= "pwm-tdiv",
e83626f2f   Thomas Abraham   ARM: S3C24XX: Add...
272
  			.devname	= "s3c24xx-pwm.2",
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
273
274
  			.ops	= &clk_tdiv_ops,
  			.parent	= &clk_timer_scaler[1],
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
275
276
277
278
  		},
  	},
  	[3]	= {
  		.clk	= {
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
279
  			.name	= "pwm-tdiv",
e83626f2f   Thomas Abraham   ARM: S3C24XX: Add...
280
  			.devname	= "s3c24xx-pwm.3",
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
281
282
  			.ops	= &clk_tdiv_ops,
  			.parent	= &clk_timer_scaler[1],
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
283
284
285
286
  		},
  	},
  	[4]	= {
  		.clk	= {
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
287
  			.name	= "pwm-tdiv",
e83626f2f   Thomas Abraham   ARM: S3C24XX: Add...
288
  			.devname	= "s3c24xx-pwm.4",
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
289
290
  			.ops	= &clk_tdiv_ops,
  			.parent	= &clk_timer_scaler[1],
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
  		},
  	},
  };
  
  static int __init clk_pwm_tdiv_register(unsigned int id)
  {
  	struct pwm_tdiv_clk *divclk = &clk_timer_tdiv[id];
  	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
  
  	tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
  	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
  
  	divclk->clk.id = id;
  	divclk->divisor = tcfg_to_divisor(tcfg1);
  
  	return s3c24xx_register_clock(&divclk->clk);
  }
  
  static inline struct clk *s3c24xx_pwmclk_tclk(unsigned int id)
  {
  	return (id >= 2) ? &clk_timer_tclk[1] : &clk_timer_tclk[0];
  }
  
  static inline struct clk *s3c24xx_pwmclk_tdiv(unsigned int id)
  {
  	return &clk_timer_tdiv[id].clk;
  }
  
  static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent)
  {
  	unsigned int id = clk->id;
  	unsigned long tcfg1;
  	unsigned long flags;
  	unsigned long bits;
  	unsigned long shift = S3C2410_TCFG1_SHIFT(id);
c0468b024   Kukjin Kim   ARM: SAMSUNG: Con...
326
327
328
329
330
331
332
333
  	unsigned long mux_tclk;
  
  	if (soc_is_s3c24xx())
  		mux_tclk = S3C2410_TCFG1_MUX_TCLK;
  	else if (soc_is_s5p6440() || soc_is_s5p6450())
  		mux_tclk = 0;
  	else
  		mux_tclk = S3C64XX_TCFG1_MUX_TCLK;
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
334
  	if (parent == s3c24xx_pwmclk_tclk(id))
c0468b024   Kukjin Kim   ARM: SAMSUNG: Con...
335
  		bits = mux_tclk << shift;
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
336
  	else if (parent == s3c24xx_pwmclk_tdiv(id))
7e90d760e   Dallas Foley   [ARM] S3C24XX: pw...
337
  		bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift;
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
  	else
  		return -EINVAL;
  
  	clk->parent = parent;
  
  	local_irq_save(flags);
  
  	tcfg1 = __raw_readl(S3C2410_TCFG1);
  	tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
  	__raw_writel(tcfg1 | bits, S3C2410_TCFG1);
  
  	local_irq_restore(flags);
  
  	return 0;
  }
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
353
354
355
  static struct clk_ops clk_tin_ops = {
  	.set_parent	= clk_pwm_tin_set_parent,
  };
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
356
357
  static struct clk clk_tin[] = {
  	[0]	= {
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
358
  		.name	= "pwm-tin",
e83626f2f   Thomas Abraham   ARM: S3C24XX: Add...
359
  		.devname	= "s3c24xx-pwm.0",
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
360
361
  		.id	= 0,
  		.ops	= &clk_tin_ops,
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
362
363
  	},
  	[1]	= {
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
364
  		.name	= "pwm-tin",
e83626f2f   Thomas Abraham   ARM: S3C24XX: Add...
365
  		.devname	= "s3c24xx-pwm.1",
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
366
367
  		.id	= 1,
  		.ops	= &clk_tin_ops,
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
368
369
  	},
  	[2]	= {
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
370
  		.name	= "pwm-tin",
e83626f2f   Thomas Abraham   ARM: S3C24XX: Add...
371
  		.devname	= "s3c24xx-pwm.2",
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
372
373
  		.id	= 2,
  		.ops	= &clk_tin_ops,
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
374
375
  	},
  	[3]	= {
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
376
  		.name	= "pwm-tin",
e83626f2f   Thomas Abraham   ARM: S3C24XX: Add...
377
  		.devname	= "s3c24xx-pwm.3",
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
378
379
  		.id	= 3,
  		.ops	= &clk_tin_ops,
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
380
381
  	},
  	[4]	= {
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
382
  		.name	= "pwm-tin",
e83626f2f   Thomas Abraham   ARM: S3C24XX: Add...
383
  		.devname	= "s3c24xx-pwm.4",
b3bf41be0   Ben Dooks   ARM: SAMSUNG: Red...
384
385
  		.id	= 4,
  		.ops	= &clk_tin_ops,
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
  	},
  };
  
  static __init int clk_pwm_tin_register(struct clk *pwm)
  {
  	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
  	unsigned int id = pwm->id;
  
  	struct clk *parent;
  	int ret;
  
  	ret = s3c24xx_register_clock(pwm);
  	if (ret < 0)
  		return ret;
  
  	tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
  	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
b09bcdd4c   Ben Dooks   [ARM] S3C64XX: Up...
403
  	if (pwm_cfg_src_is_tclk(tcfg1))
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
404
405
406
407
408
409
  		parent = s3c24xx_pwmclk_tclk(id);
  	else
  		parent = s3c24xx_pwmclk_tdiv(id);
  
  	return clk_set_parent(pwm, parent);
  }
9d325f234   Ben Dooks   [ARM] S3C: Update...
410
411
412
413
414
415
416
417
418
419
  /**
   * s3c_pwmclk_init() - initialise pwm clocks
   *
   * Initialise and register the clocks which provide the inputs for the
   * pwm timer blocks.
   *
   * Note, this call is required by the time core, so must be called after
   * the base clocks are added and before any of the initcalls are run.
   */
  __init void s3c_pwmclk_init(void)
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
420
421
422
423
424
425
426
427
428
  {
  	struct clk *clk_timers;
  	unsigned int clk;
  	int ret;
  
  	clk_timers = clk_get(NULL, "timers");
  	if (IS_ERR(clk_timers)) {
  		printk(KERN_ERR "%s: no parent clock
  ", __func__);
9d325f234   Ben Dooks   [ARM] S3C: Update...
429
  		return;
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
430
  	}
1d9f13c49   Ben Dooks   ARM: SAMSUNG: Add...
431
  	for (clk = 0; clk < ARRAY_SIZE(clk_timer_scaler); clk++)
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
432
  		clk_timer_scaler[clk].parent = clk_timers;
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
433

1d9f13c49   Ben Dooks   ARM: SAMSUNG: Add...
434
435
  	s3c_register_clocks(clk_timer_scaler, ARRAY_SIZE(clk_timer_scaler));
  	s3c_register_clocks(clk_timer_tclk, ARRAY_SIZE(clk_timer_tclk));
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
436
437
438
  
  	for (clk = 0; clk < ARRAY_SIZE(clk_timer_tdiv); clk++) {
  		ret = clk_pwm_tdiv_register(clk);
1d9f13c49   Ben Dooks   ARM: SAMSUNG: Add...
439

b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
440
441
442
  		if (ret < 0) {
  			printk(KERN_ERR "error adding pwm%d tdiv clock
  ", clk);
9d325f234   Ben Dooks   [ARM] S3C: Update...
443
  			return;
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
444
445
446
447
448
449
450
451
  		}
  	}
  
  	for (clk = 0; clk < ARRAY_SIZE(clk_tin); clk++) {
  		ret = clk_pwm_tin_register(&clk_tin[clk]);
  		if (ret < 0) {
  			printk(KERN_ERR "error adding pwm%d tin clock
  ", clk);
9d325f234   Ben Dooks   [ARM] S3C: Update...
452
  			return;
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
453
454
  		}
  	}
b999f0db9   Ben Dooks   [ARM] S3C24XX: Su...
455
  }