diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2014-04-11 10:23:40 -0400 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2014-07-04 09:50:28 -0400 |
commit | 3e29b5543f9250bb358169cff0594f58284ece74 (patch) | |
tree | 6d4bdce74dab16a6b81e25d2fecda77eeedb75fd /drivers/clocksource/sh_tmu.c | |
parent | 1768aa2f4c1248051013282c6cf63b368016cb53 (diff) |
clocksource: sh_tmu: Add DT support
Document DT bindings and parse them in the TMU driver.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Simon Horman <horms+renesas@verge.net.au>
Diffstat (limited to 'drivers/clocksource/sh_tmu.c')
-rw-r--r-- | drivers/clocksource/sh_tmu.c | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 560a31acbc9c..0f665b8f2461 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/ioport.h> | 24 | #include <linux/ioport.h> |
25 | #include <linux/irq.h> | 25 | #include <linux/irq.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/of.h> | ||
27 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
28 | #include <linux/pm_domain.h> | 29 | #include <linux/pm_domain.h> |
29 | #include <linux/pm_runtime.h> | 30 | #include <linux/pm_runtime.h> |
@@ -509,23 +510,48 @@ static int sh_tmu_map_memory(struct sh_tmu_device *tmu) | |||
509 | return 0; | 510 | return 0; |
510 | } | 511 | } |
511 | 512 | ||
513 | static int sh_tmu_parse_dt(struct sh_tmu_device *tmu) | ||
514 | { | ||
515 | struct device_node *np = tmu->pdev->dev.of_node; | ||
516 | |||
517 | tmu->model = SH_TMU; | ||
518 | tmu->num_channels = 3; | ||
519 | |||
520 | of_property_read_u32(np, "#renesas,channels", &tmu->num_channels); | ||
521 | |||
522 | if (tmu->num_channels != 2 && tmu->num_channels != 3) { | ||
523 | dev_err(&tmu->pdev->dev, "invalid number of channels %u\n", | ||
524 | tmu->num_channels); | ||
525 | return -EINVAL; | ||
526 | } | ||
527 | |||
528 | return 0; | ||
529 | } | ||
530 | |||
512 | static int sh_tmu_setup(struct sh_tmu_device *tmu, struct platform_device *pdev) | 531 | static int sh_tmu_setup(struct sh_tmu_device *tmu, struct platform_device *pdev) |
513 | { | 532 | { |
514 | struct sh_timer_config *cfg = pdev->dev.platform_data; | ||
515 | const struct platform_device_id *id = pdev->id_entry; | ||
516 | unsigned int i; | 533 | unsigned int i; |
517 | int ret; | 534 | int ret; |
518 | 535 | ||
519 | if (!cfg) { | ||
520 | dev_err(&tmu->pdev->dev, "missing platform data\n"); | ||
521 | return -ENXIO; | ||
522 | } | ||
523 | |||
524 | tmu->pdev = pdev; | 536 | tmu->pdev = pdev; |
525 | tmu->model = id->driver_data; | ||
526 | 537 | ||
527 | raw_spin_lock_init(&tmu->lock); | 538 | raw_spin_lock_init(&tmu->lock); |
528 | 539 | ||
540 | if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { | ||
541 | ret = sh_tmu_parse_dt(tmu); | ||
542 | if (ret < 0) | ||
543 | return ret; | ||
544 | } else if (pdev->dev.platform_data) { | ||
545 | const struct platform_device_id *id = pdev->id_entry; | ||
546 | struct sh_timer_config *cfg = pdev->dev.platform_data; | ||
547 | |||
548 | tmu->model = id->driver_data; | ||
549 | tmu->num_channels = hweight8(cfg->channels_mask); | ||
550 | } else { | ||
551 | dev_err(&tmu->pdev->dev, "missing platform data\n"); | ||
552 | return -ENXIO; | ||
553 | } | ||
554 | |||
529 | /* Get hold of clock. */ | 555 | /* Get hold of clock. */ |
530 | tmu->clk = clk_get(&tmu->pdev->dev, "fck"); | 556 | tmu->clk = clk_get(&tmu->pdev->dev, "fck"); |
531 | if (IS_ERR(tmu->clk)) { | 557 | if (IS_ERR(tmu->clk)) { |
@@ -545,8 +571,6 @@ static int sh_tmu_setup(struct sh_tmu_device *tmu, struct platform_device *pdev) | |||
545 | } | 571 | } |
546 | 572 | ||
547 | /* Allocate and setup the channels. */ | 573 | /* Allocate and setup the channels. */ |
548 | tmu->num_channels = hweight8(cfg->channels_mask); | ||
549 | |||
550 | tmu->channels = kzalloc(sizeof(*tmu->channels) * tmu->num_channels, | 574 | tmu->channels = kzalloc(sizeof(*tmu->channels) * tmu->num_channels, |
551 | GFP_KERNEL); | 575 | GFP_KERNEL); |
552 | if (tmu->channels == NULL) { | 576 | if (tmu->channels == NULL) { |
@@ -628,11 +652,18 @@ static const struct platform_device_id sh_tmu_id_table[] = { | |||
628 | }; | 652 | }; |
629 | MODULE_DEVICE_TABLE(platform, sh_tmu_id_table); | 653 | MODULE_DEVICE_TABLE(platform, sh_tmu_id_table); |
630 | 654 | ||
655 | static const struct of_device_id sh_tmu_of_table[] __maybe_unused = { | ||
656 | { .compatible = "renesas,tmu" }, | ||
657 | { } | ||
658 | }; | ||
659 | MODULE_DEVICE_TABLE(of, sh_tmu_of_table); | ||
660 | |||
631 | static struct platform_driver sh_tmu_device_driver = { | 661 | static struct platform_driver sh_tmu_device_driver = { |
632 | .probe = sh_tmu_probe, | 662 | .probe = sh_tmu_probe, |
633 | .remove = sh_tmu_remove, | 663 | .remove = sh_tmu_remove, |
634 | .driver = { | 664 | .driver = { |
635 | .name = "sh_tmu", | 665 | .name = "sh_tmu", |
666 | .of_match_table = of_match_ptr(sh_tmu_of_table), | ||
636 | }, | 667 | }, |
637 | .id_table = sh_tmu_id_table, | 668 | .id_table = sh_tmu_id_table, |
638 | }; | 669 | }; |