clk-system.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. */
  10. #include <linux/clk-provider.h>
  11. #include <linux/clkdev.h>
  12. #include <linux/clk/at91_pmc.h>
  13. #include <linux/of.h>
  14. #include <linux/of_address.h>
  15. #include <linux/io.h>
  16. #include <linux/irq.h>
  17. #include <linux/of_irq.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/wait.h>
  20. #include <linux/sched.h>
  21. #include "pmc.h"
  22. #define SYSTEM_MAX_ID 31
  23. #define SYSTEM_MAX_NAME_SZ 32
  24. #define to_clk_system(hw) container_of(hw, struct clk_system, hw)
  25. struct clk_system {
  26. struct clk_hw hw;
  27. struct at91_pmc *pmc;
  28. unsigned int irq;
  29. wait_queue_head_t wait;
  30. u8 id;
  31. };
  32. static inline int is_pck(int id)
  33. {
  34. return (id >= 8) && (id <= 15);
  35. }
  36. static irqreturn_t clk_system_irq_handler(int irq, void *dev_id)
  37. {
  38. struct clk_system *sys = (struct clk_system *)dev_id;
  39. wake_up(&sys->wait);
  40. disable_irq_nosync(sys->irq);
  41. return IRQ_HANDLED;
  42. }
  43. static int clk_system_prepare(struct clk_hw *hw)
  44. {
  45. struct clk_system *sys = to_clk_system(hw);
  46. struct at91_pmc *pmc = sys->pmc;
  47. u32 mask = 1 << sys->id;
  48. pmc_write(pmc, AT91_PMC_SCER, mask);
  49. if (!is_pck(sys->id))
  50. return 0;
  51. while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) {
  52. if (sys->irq) {
  53. enable_irq(sys->irq);
  54. wait_event(sys->wait,
  55. pmc_read(pmc, AT91_PMC_SR) & mask);
  56. } else
  57. cpu_relax();
  58. }
  59. return 0;
  60. }
  61. static void clk_system_unprepare(struct clk_hw *hw)
  62. {
  63. struct clk_system *sys = to_clk_system(hw);
  64. struct at91_pmc *pmc = sys->pmc;
  65. pmc_write(pmc, AT91_PMC_SCDR, 1 << sys->id);
  66. }
  67. static int clk_system_is_prepared(struct clk_hw *hw)
  68. {
  69. struct clk_system *sys = to_clk_system(hw);
  70. struct at91_pmc *pmc = sys->pmc;
  71. if (!(pmc_read(pmc, AT91_PMC_SCSR) & (1 << sys->id)))
  72. return 0;
  73. if (!is_pck(sys->id))
  74. return 1;
  75. return !!(pmc_read(pmc, AT91_PMC_SR) & (1 << sys->id));
  76. }
  77. static const struct clk_ops system_ops = {
  78. .prepare = clk_system_prepare,
  79. .unprepare = clk_system_unprepare,
  80. .is_prepared = clk_system_is_prepared,
  81. };
  82. static struct clk * __init
  83. at91_clk_register_system(struct at91_pmc *pmc, const char *name,
  84. const char *parent_name, u8 id, int irq)
  85. {
  86. struct clk_system *sys;
  87. struct clk *clk = NULL;
  88. struct clk_init_data init;
  89. int ret;
  90. if (!parent_name || id > SYSTEM_MAX_ID)
  91. return ERR_PTR(-EINVAL);
  92. sys = kzalloc(sizeof(*sys), GFP_KERNEL);
  93. if (!sys)
  94. return ERR_PTR(-ENOMEM);
  95. init.name = name;
  96. init.ops = &system_ops;
  97. init.parent_names = &parent_name;
  98. init.num_parents = 1;
  99. init.flags = CLK_SET_RATE_PARENT;
  100. sys->id = id;
  101. sys->hw.init = &init;
  102. sys->pmc = pmc;
  103. sys->irq = irq;
  104. if (irq) {
  105. init_waitqueue_head(&sys->wait);
  106. irq_set_status_flags(sys->irq, IRQ_NOAUTOEN);
  107. ret = request_irq(sys->irq, clk_system_irq_handler,
  108. IRQF_TRIGGER_HIGH, name, sys);
  109. if (ret) {
  110. kfree(sys);
  111. return ERR_PTR(ret);
  112. }
  113. }
  114. clk = clk_register(NULL, &sys->hw);
  115. if (IS_ERR(clk)) {
  116. if (irq)
  117. free_irq(sys->irq, sys);
  118. kfree(sys);
  119. }
  120. return clk;
  121. }
  122. static void __init
  123. of_at91_clk_sys_setup(struct device_node *np, struct at91_pmc *pmc)
  124. {
  125. int num;
  126. int irq = 0;
  127. u32 id;
  128. struct clk *clk;
  129. const char *name;
  130. struct device_node *sysclknp;
  131. const char *parent_name;
  132. num = of_get_child_count(np);
  133. if (num > (SYSTEM_MAX_ID + 1))
  134. return;
  135. for_each_child_of_node(np, sysclknp) {
  136. if (of_property_read_u32(sysclknp, "reg", &id))
  137. continue;
  138. if (of_property_read_string(np, "clock-output-names", &name))
  139. name = sysclknp->name;
  140. if (is_pck(id))
  141. irq = irq_of_parse_and_map(sysclknp, 0);
  142. parent_name = of_clk_get_parent_name(sysclknp, 0);
  143. clk = at91_clk_register_system(pmc, name, parent_name, id, irq);
  144. if (IS_ERR(clk))
  145. continue;
  146. of_clk_add_provider(sysclknp, of_clk_src_simple_get, clk);
  147. }
  148. }
  149. void __init of_at91rm9200_clk_sys_setup(struct device_node *np,
  150. struct at91_pmc *pmc)
  151. {
  152. of_at91_clk_sys_setup(np, pmc);
  153. }