aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/clocksource/sh_mtu2.c130
1 files changed, 31 insertions, 99 deletions
diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c
index 188d4e092efc..0342e4a01c9e 100644
--- a/drivers/clocksource/sh_mtu2.c
+++ b/drivers/clocksource/sh_mtu2.c
@@ -37,7 +37,6 @@ struct sh_mtu2_channel {
37 unsigned int index; 37 unsigned int index;
38 38
39 void __iomem *base; 39 void __iomem *base;
40 int irq;
41 40
42 struct clock_event_device ced; 41 struct clock_event_device ced;
43}; 42};
@@ -51,7 +50,6 @@ struct sh_mtu2_device {
51 struct sh_mtu2_channel *channels; 50 struct sh_mtu2_channel *channels;
52 unsigned int num_channels; 51 unsigned int num_channels;
53 52
54 bool legacy;
55 bool has_clockevent; 53 bool has_clockevent;
56}; 54};
57 55
@@ -162,12 +160,8 @@ static inline unsigned long sh_mtu2_read(struct sh_mtu2_channel *ch, int reg_nr)
162{ 160{
163 unsigned long offs; 161 unsigned long offs;
164 162
165 if (reg_nr == TSTR) { 163 if (reg_nr == TSTR)
166 if (ch->mtu->legacy) 164 return ioread8(ch->mtu->mapbase + 0x280);
167 return ioread8(ch->mtu->mapbase);
168 else
169 return ioread8(ch->mtu->mapbase + 0x280);
170 }
171 165
172 offs = mtu2_reg_offs[reg_nr]; 166 offs = mtu2_reg_offs[reg_nr];
173 167
@@ -182,12 +176,8 @@ static inline void sh_mtu2_write(struct sh_mtu2_channel *ch, int reg_nr,
182{ 176{
183 unsigned long offs; 177 unsigned long offs;
184 178
185 if (reg_nr == TSTR) { 179 if (reg_nr == TSTR)
186 if (ch->mtu->legacy) 180 return iowrite8(value, ch->mtu->mapbase + 0x280);
187 return iowrite8(value, ch->mtu->mapbase);
188 else
189 return iowrite8(value, ch->mtu->mapbase + 0x280);
190 }
191 181
192 offs = mtu2_reg_offs[reg_nr]; 182 offs = mtu2_reg_offs[reg_nr];
193 183
@@ -331,7 +321,6 @@ static void sh_mtu2_register_clockevent(struct sh_mtu2_channel *ch,
331 const char *name) 321 const char *name)
332{ 322{
333 struct clock_event_device *ced = &ch->ced; 323 struct clock_event_device *ced = &ch->ced;
334 int ret;
335 324
336 ced->name = name; 325 ced->name = name;
337 ced->features = CLOCK_EVT_FEAT_PERIODIC; 326 ced->features = CLOCK_EVT_FEAT_PERIODIC;
@@ -344,24 +333,12 @@ static void sh_mtu2_register_clockevent(struct sh_mtu2_channel *ch,
344 dev_info(&ch->mtu->pdev->dev, "ch%u: used for clock events\n", 333 dev_info(&ch->mtu->pdev->dev, "ch%u: used for clock events\n",
345 ch->index); 334 ch->index);
346 clockevents_register_device(ced); 335 clockevents_register_device(ced);
347
348 ret = request_irq(ch->irq, sh_mtu2_interrupt,
349 IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
350 dev_name(&ch->mtu->pdev->dev), ch);
351 if (ret) {
352 dev_err(&ch->mtu->pdev->dev, "ch%u: failed to request irq %d\n",
353 ch->index, ch->irq);
354 return;
355 }
356} 336}
357 337
358static int sh_mtu2_register(struct sh_mtu2_channel *ch, const char *name, 338static int sh_mtu2_register(struct sh_mtu2_channel *ch, const char *name)
359 bool clockevent)
360{ 339{
361 if (clockevent) { 340 ch->mtu->has_clockevent = true;
362 ch->mtu->has_clockevent = true; 341 sh_mtu2_register_clockevent(ch, name);
363 sh_mtu2_register_clockevent(ch, name);
364 }
365 342
366 return 0; 343 return 0;
367} 344}
@@ -372,40 +349,32 @@ static int sh_mtu2_setup_channel(struct sh_mtu2_channel *ch, unsigned int index,
372 static const unsigned int channel_offsets[] = { 349 static const unsigned int channel_offsets[] = {
373 0x300, 0x380, 0x000, 350 0x300, 0x380, 0x000,
374 }; 351 };
375 bool clockevent; 352 char name[6];
353 int irq;
354 int ret;
376 355
377 ch->mtu = mtu; 356 ch->mtu = mtu;
378 357
379 if (mtu->legacy) { 358 sprintf(name, "tgi%ua", index);
380 struct sh_timer_config *cfg = mtu->pdev->dev.platform_data; 359 irq = platform_get_irq_byname(mtu->pdev, name);
381 360 if (irq < 0) {
382 clockevent = cfg->clockevent_rating != 0;
383
384 ch->irq = platform_get_irq(mtu->pdev, 0);
385 ch->base = mtu->mapbase - cfg->channel_offset;
386 ch->index = cfg->timer_bit;
387 } else {
388 char name[6];
389
390 clockevent = true;
391
392 sprintf(name, "tgi%ua", index);
393 ch->irq = platform_get_irq_byname(mtu->pdev, name);
394 ch->base = mtu->mapbase + channel_offsets[index];
395 ch->index = index;
396 }
397
398 if (ch->irq < 0) {
399 /* Skip channels with no declared interrupt. */ 361 /* Skip channels with no declared interrupt. */
400 if (!mtu->legacy) 362 return 0;
401 return 0; 363 }
402 364
403 dev_err(&mtu->pdev->dev, "ch%u: failed to get irq\n", 365 ret = request_irq(irq, sh_mtu2_interrupt,
404 ch->index); 366 IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
405 return ch->irq; 367 dev_name(&ch->mtu->pdev->dev), ch);
368 if (ret) {
369 dev_err(&ch->mtu->pdev->dev, "ch%u: failed to request irq %d\n",
370 index, irq);
371 return ret;
406 } 372 }
407 373
408 return sh_mtu2_register(ch, dev_name(&mtu->pdev->dev), clockevent); 374 ch->base = mtu->mapbase + channel_offsets[index];
375 ch->index = index;
376
377 return sh_mtu2_register(ch, dev_name(&mtu->pdev->dev));
409} 378}
410 379
411static int sh_mtu2_map_memory(struct sh_mtu2_device *mtu) 380static int sh_mtu2_map_memory(struct sh_mtu2_device *mtu)
@@ -422,46 +391,19 @@ static int sh_mtu2_map_memory(struct sh_mtu2_device *mtu)
422 if (mtu->mapbase == NULL) 391 if (mtu->mapbase == NULL)
423 return -ENXIO; 392 return -ENXIO;
424 393
425 /*
426 * In legacy platform device configuration (with one device per channel)
427 * the resource points to the channel base address.
428 */
429 if (mtu->legacy) {
430 struct sh_timer_config *cfg = mtu->pdev->dev.platform_data;
431 mtu->mapbase += cfg->channel_offset;
432 }
433
434 return 0; 394 return 0;
435} 395}
436 396
437static void sh_mtu2_unmap_memory(struct sh_mtu2_device *mtu)
438{
439 if (mtu->legacy) {
440 struct sh_timer_config *cfg = mtu->pdev->dev.platform_data;
441 mtu->mapbase -= cfg->channel_offset;
442 }
443
444 iounmap(mtu->mapbase);
445}
446
447static int sh_mtu2_setup(struct sh_mtu2_device *mtu, 397static int sh_mtu2_setup(struct sh_mtu2_device *mtu,
448 struct platform_device *pdev) 398 struct platform_device *pdev)
449{ 399{
450 struct sh_timer_config *cfg = pdev->dev.platform_data;
451 const struct platform_device_id *id = pdev->id_entry;
452 unsigned int i; 400 unsigned int i;
453 int ret; 401 int ret;
454 402
455 mtu->pdev = pdev; 403 mtu->pdev = pdev;
456 mtu->legacy = id->driver_data;
457
458 if (mtu->legacy && !cfg) {
459 dev_err(&mtu->pdev->dev, "missing platform data\n");
460 return -ENXIO;
461 }
462 404
463 /* Get hold of clock. */ 405 /* Get hold of clock. */
464 mtu->clk = clk_get(&mtu->pdev->dev, mtu->legacy ? "mtu2_fck" : "fck"); 406 mtu->clk = clk_get(&mtu->pdev->dev, "fck");
465 if (IS_ERR(mtu->clk)) { 407 if (IS_ERR(mtu->clk)) {
466 dev_err(&mtu->pdev->dev, "cannot get clock\n"); 408 dev_err(&mtu->pdev->dev, "cannot get clock\n");
467 return PTR_ERR(mtu->clk); 409 return PTR_ERR(mtu->clk);
@@ -479,10 +421,7 @@ static int sh_mtu2_setup(struct sh_mtu2_device *mtu,
479 } 421 }
480 422
481 /* Allocate and setup the channels. */ 423 /* Allocate and setup the channels. */
482 if (mtu->legacy) 424 mtu->num_channels = 3;
483 mtu->num_channels = 1;
484 else
485 mtu->num_channels = 3;
486 425
487 mtu->channels = kzalloc(sizeof(*mtu->channels) * mtu->num_channels, 426 mtu->channels = kzalloc(sizeof(*mtu->channels) * mtu->num_channels,
488 GFP_KERNEL); 427 GFP_KERNEL);
@@ -491,16 +430,10 @@ static int sh_mtu2_setup(struct sh_mtu2_device *mtu,
491 goto err_unmap; 430 goto err_unmap;
492 } 431 }
493 432
494 if (mtu->legacy) { 433 for (i = 0; i < mtu->num_channels; ++i) {
495 ret = sh_mtu2_setup_channel(&mtu->channels[0], 0, mtu); 434 ret = sh_mtu2_setup_channel(&mtu->channels[i], i, mtu);
496 if (ret < 0) 435 if (ret < 0)
497 goto err_unmap; 436 goto err_unmap;
498 } else {
499 for (i = 0; i < mtu->num_channels; ++i) {
500 ret = sh_mtu2_setup_channel(&mtu->channels[i], i, mtu);
501 if (ret < 0)
502 goto err_unmap;
503 }
504 } 437 }
505 438
506 platform_set_drvdata(pdev, mtu); 439 platform_set_drvdata(pdev, mtu);
@@ -509,7 +442,7 @@ static int sh_mtu2_setup(struct sh_mtu2_device *mtu,
509 442
510err_unmap: 443err_unmap:
511 kfree(mtu->channels); 444 kfree(mtu->channels);
512 sh_mtu2_unmap_memory(mtu); 445 iounmap(mtu->mapbase);
513err_clk_unprepare: 446err_clk_unprepare:
514 clk_unprepare(mtu->clk); 447 clk_unprepare(mtu->clk);
515err_clk_put: 448err_clk_put:
@@ -560,7 +493,6 @@ static int sh_mtu2_remove(struct platform_device *pdev)
560} 493}
561 494
562static const struct platform_device_id sh_mtu2_id_table[] = { 495static const struct platform_device_id sh_mtu2_id_table[] = {
563 { "sh_mtu2", 1 },
564 { "sh-mtu2", 0 }, 496 { "sh-mtu2", 0 },
565 { }, 497 { },
566}; 498};