timer-of.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * Copyright (c) 2017, Linaro Ltd. All rights reserved.
  3. *
  4. * Author: Daniel Lezcano <daniel.lezcano@linaro.org>
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms and conditions of the GNU General Public License,
  8. * version 2, as published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope it will be useful, but WITHOUT
  11. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  13. * more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include <linux/clk.h>
  19. #include <linux/interrupt.h>
  20. #include <linux/of.h>
  21. #include <linux/of_address.h>
  22. #include <linux/of_irq.h>
  23. #include <linux/slab.h>
  24. #include "timer-of.h"
  25. static __init void timer_irq_exit(struct of_timer_irq *of_irq)
  26. {
  27. struct timer_of *to = container_of(of_irq, struct timer_of, of_irq);
  28. struct clock_event_device *clkevt = &to->clkevt;
  29. of_irq->percpu ? free_percpu_irq(of_irq->irq, clkevt) :
  30. free_irq(of_irq->irq, clkevt);
  31. }
  32. static __init int timer_irq_init(struct device_node *np,
  33. struct of_timer_irq *of_irq)
  34. {
  35. int ret;
  36. struct timer_of *to = container_of(of_irq, struct timer_of, of_irq);
  37. struct clock_event_device *clkevt = &to->clkevt;
  38. of_irq->irq = of_irq->name ? of_irq_get_byname(np, of_irq->name):
  39. irq_of_parse_and_map(np, of_irq->index);
  40. if (!of_irq->irq) {
  41. pr_err("Failed to map interrupt for %s\n", np->full_name);
  42. return -EINVAL;
  43. }
  44. ret = of_irq->percpu ?
  45. request_percpu_irq(of_irq->irq, of_irq->handler,
  46. np->full_name, clkevt) :
  47. request_irq(of_irq->irq, of_irq->handler,
  48. of_irq->flags ? of_irq->flags : IRQF_TIMER,
  49. np->full_name, clkevt);
  50. if (ret) {
  51. pr_err("Failed to request irq %d for %s\n", of_irq->irq,
  52. np->full_name);
  53. return ret;
  54. }
  55. clkevt->irq = of_irq->irq;
  56. return 0;
  57. }
  58. static __init void timer_clk_exit(struct of_timer_clk *of_clk)
  59. {
  60. of_clk->rate = 0;
  61. clk_disable_unprepare(of_clk->clk);
  62. clk_put(of_clk->clk);
  63. }
  64. static __init int timer_clk_init(struct device_node *np,
  65. struct of_timer_clk *of_clk)
  66. {
  67. int ret;
  68. of_clk->clk = of_clk->name ? of_clk_get_by_name(np, of_clk->name) :
  69. of_clk_get(np, of_clk->index);
  70. if (IS_ERR(of_clk->clk)) {
  71. pr_err("Failed to get clock for %s\n", np->full_name);
  72. return PTR_ERR(of_clk->clk);
  73. }
  74. ret = clk_prepare_enable(of_clk->clk);
  75. if (ret) {
  76. pr_err("Failed for enable clock for %s\n", np->full_name);
  77. goto out_clk_put;
  78. }
  79. of_clk->rate = clk_get_rate(of_clk->clk);
  80. if (!of_clk->rate) {
  81. ret = -EINVAL;
  82. pr_err("Failed to get clock rate for %s\n", np->full_name);
  83. goto out_clk_disable;
  84. }
  85. of_clk->period = DIV_ROUND_UP(of_clk->rate, HZ);
  86. out:
  87. return ret;
  88. out_clk_disable:
  89. clk_disable_unprepare(of_clk->clk);
  90. out_clk_put:
  91. clk_put(of_clk->clk);
  92. goto out;
  93. }
  94. static __init void timer_base_exit(struct of_timer_base *of_base)
  95. {
  96. iounmap(of_base->base);
  97. }
  98. static __init int timer_base_init(struct device_node *np,
  99. struct of_timer_base *of_base)
  100. {
  101. const char *name = of_base->name ? of_base->name : np->full_name;
  102. of_base->base = of_io_request_and_map(np, of_base->index, name);
  103. if (of_base->base) {
  104. pr_err("Failed to iomap (%s)\n", name);
  105. return -ENXIO;
  106. }
  107. return 0;
  108. }
  109. int __init timer_of_init(struct device_node *np, struct timer_of *to)
  110. {
  111. int ret;
  112. int flags = 0;
  113. if (to->flags & TIMER_OF_BASE) {
  114. ret = timer_base_init(np, &to->of_base);
  115. if (ret)
  116. goto out_fail;
  117. flags |= TIMER_OF_BASE;
  118. }
  119. if (to->flags & TIMER_OF_CLOCK) {
  120. ret = timer_clk_init(np, &to->of_clk);
  121. if (ret)
  122. goto out_fail;
  123. flags |= TIMER_OF_CLOCK;
  124. }
  125. if (to->flags & TIMER_OF_IRQ) {
  126. ret = timer_irq_init(np, &to->of_irq);
  127. if (ret)
  128. goto out_fail;
  129. flags |= TIMER_OF_IRQ;
  130. }
  131. if (!to->clkevt.name)
  132. to->clkevt.name = np->name;
  133. out:
  134. return ret;
  135. out_fail:
  136. if (flags & TIMER_OF_IRQ)
  137. timer_irq_exit(&to->of_irq);
  138. if (flags & TIMER_OF_CLOCK)
  139. timer_clk_exit(&to->of_clk);
  140. if (flags & TIMER_OF_BASE)
  141. timer_base_exit(&to->of_base);
  142. goto out;
  143. }