clock.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. /*
  2. *
  3. * Copyright (C) 2010 Google, Inc.
  4. *
  5. * Author:
  6. * Colin Cross <ccross@google.com>
  7. *
  8. * This software is licensed under the terms of the GNU General Public
  9. * License version 2, as published by the Free Software Foundation, and
  10. * may be copied, distributed, and modified under those terms.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. */
  18. #include <linux/kernel.h>
  19. #include <linux/clk.h>
  20. #include <linux/list.h>
  21. #include <linux/init.h>
  22. #include <linux/module.h>
  23. #include <linux/debugfs.h>
  24. #include <linux/slab.h>
  25. #include <linux/seq_file.h>
  26. #include <asm/clkdev.h>
  27. #include "clock.h"
  28. static LIST_HEAD(clocks);
  29. static DEFINE_SPINLOCK(clock_lock);
  30. struct clk *tegra_get_clock_by_name(const char *name)
  31. {
  32. struct clk *c;
  33. struct clk *ret = NULL;
  34. unsigned long flags;
  35. spin_lock_irqsave(&clock_lock, flags);
  36. list_for_each_entry(c, &clocks, node) {
  37. if (strcmp(c->name, name) == 0) {
  38. ret = c;
  39. break;
  40. }
  41. }
  42. spin_unlock_irqrestore(&clock_lock, flags);
  43. return ret;
  44. }
  45. int clk_reparent(struct clk *c, struct clk *parent)
  46. {
  47. pr_debug("%s: %s\n", __func__, c->name);
  48. if (c->refcnt && c->parent)
  49. clk_disable_locked(c->parent);
  50. c->parent = parent;
  51. if (c->refcnt && c->parent)
  52. clk_enable_locked(c->parent);
  53. list_del(&c->sibling);
  54. list_add_tail(&c->sibling, &parent->children);
  55. return 0;
  56. }
  57. static void propagate_rate(struct clk *c)
  58. {
  59. struct clk *clkp;
  60. pr_debug("%s: %s\n", __func__, c->name);
  61. list_for_each_entry(clkp, &c->children, sibling) {
  62. pr_debug(" %s\n", clkp->name);
  63. if (clkp->ops->recalculate_rate)
  64. clkp->ops->recalculate_rate(clkp);
  65. propagate_rate(clkp);
  66. }
  67. }
  68. void clk_init(struct clk *c)
  69. {
  70. unsigned long flags;
  71. spin_lock_irqsave(&clock_lock, flags);
  72. INIT_LIST_HEAD(&c->children);
  73. INIT_LIST_HEAD(&c->sibling);
  74. if (c->ops && c->ops->init)
  75. c->ops->init(c);
  76. list_add(&c->node, &clocks);
  77. if (c->parent)
  78. list_add_tail(&c->sibling, &c->parent->children);
  79. spin_unlock_irqrestore(&clock_lock, flags);
  80. }
  81. int clk_enable_locked(struct clk *c)
  82. {
  83. int ret;
  84. pr_debug("%s: %s\n", __func__, c->name);
  85. if (c->refcnt == 0) {
  86. if (c->parent) {
  87. ret = clk_enable_locked(c->parent);
  88. if (ret)
  89. return ret;
  90. }
  91. if (c->ops && c->ops->enable) {
  92. ret = c->ops->enable(c);
  93. if (ret) {
  94. if (c->parent)
  95. clk_disable_locked(c->parent);
  96. return ret;
  97. }
  98. c->state = ON;
  99. #ifdef CONFIG_DEBUG_FS
  100. c->set = 1;
  101. #endif
  102. }
  103. }
  104. c->refcnt++;
  105. return 0;
  106. }
  107. int clk_enable(struct clk *c)
  108. {
  109. int ret;
  110. unsigned long flags;
  111. spin_lock_irqsave(&clock_lock, flags);
  112. ret = clk_enable_locked(c);
  113. spin_unlock_irqrestore(&clock_lock, flags);
  114. return ret;
  115. }
  116. EXPORT_SYMBOL(clk_enable);
  117. void clk_disable_locked(struct clk *c)
  118. {
  119. pr_debug("%s: %s\n", __func__, c->name);
  120. if (c->refcnt == 0) {
  121. WARN(1, "Attempting to disable clock %s with refcnt 0", c->name);
  122. return;
  123. }
  124. if (c->refcnt == 1) {
  125. if (c->ops && c->ops->disable)
  126. c->ops->disable(c);
  127. if (c->parent)
  128. clk_disable_locked(c->parent);
  129. c->state = OFF;
  130. }
  131. c->refcnt--;
  132. }
  133. void clk_disable(struct clk *c)
  134. {
  135. unsigned long flags;
  136. spin_lock_irqsave(&clock_lock, flags);
  137. clk_disable_locked(c);
  138. spin_unlock_irqrestore(&clock_lock, flags);
  139. }
  140. EXPORT_SYMBOL(clk_disable);
  141. int clk_set_parent_locked(struct clk *c, struct clk *parent)
  142. {
  143. int ret;
  144. pr_debug("%s: %s\n", __func__, c->name);
  145. if (!c->ops || !c->ops->set_parent)
  146. return -ENOSYS;
  147. ret = c->ops->set_parent(c, parent);
  148. if (ret)
  149. return ret;
  150. propagate_rate(c);
  151. return 0;
  152. }
  153. int clk_set_parent(struct clk *c, struct clk *parent)
  154. {
  155. int ret;
  156. unsigned long flags;
  157. spin_lock_irqsave(&clock_lock, flags);
  158. ret = clk_set_parent_locked(c, parent);
  159. spin_unlock_irqrestore(&clock_lock, flags);
  160. return ret;
  161. }
  162. EXPORT_SYMBOL(clk_set_parent);
  163. struct clk *clk_get_parent(struct clk *c)
  164. {
  165. return c->parent;
  166. }
  167. EXPORT_SYMBOL(clk_get_parent);
  168. int clk_set_rate(struct clk *c, unsigned long rate)
  169. {
  170. int ret = 0;
  171. unsigned long flags;
  172. spin_lock_irqsave(&clock_lock, flags);
  173. pr_debug("%s: %s\n", __func__, c->name);
  174. if (c->ops && c->ops->set_rate)
  175. ret = c->ops->set_rate(c, rate);
  176. else
  177. ret = -ENOSYS;
  178. propagate_rate(c);
  179. spin_unlock_irqrestore(&clock_lock, flags);
  180. return ret;
  181. }
  182. EXPORT_SYMBOL(clk_set_rate);
  183. unsigned long clk_get_rate(struct clk *c)
  184. {
  185. unsigned long flags;
  186. unsigned long ret;
  187. spin_lock_irqsave(&clock_lock, flags);
  188. pr_debug("%s: %s\n", __func__, c->name);
  189. ret = c->rate;
  190. spin_unlock_irqrestore(&clock_lock, flags);
  191. return ret;
  192. }
  193. EXPORT_SYMBOL(clk_get_rate);
  194. static int tegra_clk_init_one_from_table(struct tegra_clk_init_table *table)
  195. {
  196. struct clk *c;
  197. struct clk *p;
  198. int ret = 0;
  199. c = tegra_get_clock_by_name(table->name);
  200. if (!c) {
  201. pr_warning("Unable to initialize clock %s\n",
  202. table->name);
  203. return -ENODEV;
  204. }
  205. if (table->parent) {
  206. p = tegra_get_clock_by_name(table->parent);
  207. if (!p) {
  208. pr_warning("Unable to find parent %s of clock %s\n",
  209. table->parent, table->name);
  210. return -ENODEV;
  211. }
  212. if (c->parent != p) {
  213. ret = clk_set_parent(c, p);
  214. if (ret) {
  215. pr_warning("Unable to set parent %s of clock %s: %d\n",
  216. table->parent, table->name, ret);
  217. return -EINVAL;
  218. }
  219. }
  220. }
  221. if (table->rate && table->rate != clk_get_rate(c)) {
  222. ret = clk_set_rate(c, table->rate);
  223. if (ret) {
  224. pr_warning("Unable to set clock %s to rate %lu: %d\n",
  225. table->name, table->rate, ret);
  226. return -EINVAL;
  227. }
  228. }
  229. if (table->enabled) {
  230. ret = clk_enable(c);
  231. if (ret) {
  232. pr_warning("Unable to enable clock %s: %d\n",
  233. table->name, ret);
  234. return -EINVAL;
  235. }
  236. }
  237. return 0;
  238. }
  239. void tegra_clk_init_from_table(struct tegra_clk_init_table *table)
  240. {
  241. for (; table->name; table++)
  242. tegra_clk_init_one_from_table(table);
  243. }
  244. EXPORT_SYMBOL(tegra_clk_init_from_table);
  245. void tegra_periph_reset_deassert(struct clk *c)
  246. {
  247. tegra2_periph_reset_deassert(c);
  248. }
  249. EXPORT_SYMBOL(tegra_periph_reset_deassert);
  250. void tegra_periph_reset_assert(struct clk *c)
  251. {
  252. tegra2_periph_reset_assert(c);
  253. }
  254. EXPORT_SYMBOL(tegra_periph_reset_assert);
  255. int __init tegra_init_clock(void)
  256. {
  257. tegra2_init_clocks();
  258. return 0;
  259. }
  260. #ifdef CONFIG_DEBUG_FS
  261. static struct dentry *clk_debugfs_root;
  262. static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level)
  263. {
  264. struct clk *child;
  265. struct clk *safe;
  266. const char *state = "uninit";
  267. char div[5] = {0};
  268. if (c->state == ON)
  269. state = "on";
  270. else if (c->state == OFF)
  271. state = "off";
  272. if (c->mul != 0 && c->div != 0) {
  273. BUG_ON(c->mul > 2);
  274. if (c->mul > c->div)
  275. snprintf(div, sizeof(div), "x%d", c->mul / c->div);
  276. else
  277. snprintf(div, sizeof(div), "%d%s", c->div / c->mul,
  278. (c->div % c->mul) ? ".5" : "");
  279. }
  280. seq_printf(s, "%*s%-*s %-6s %-3d %-5s %-10lu\n",
  281. level * 3 + 1, c->set ? "" : "*",
  282. 30 - level * 3, c->name,
  283. state, c->refcnt, div, c->rate);
  284. list_for_each_entry_safe(child, safe, &c->children, sibling) {
  285. clock_tree_show_one(s, child, level + 1);
  286. }
  287. }
  288. static int clock_tree_show(struct seq_file *s, void *data)
  289. {
  290. struct clk *c;
  291. unsigned long flags;
  292. seq_printf(s, " clock state ref div rate \n");
  293. seq_printf(s, "-----------------------------------------------------------\n");
  294. spin_lock_irqsave(&clock_lock, flags);
  295. list_for_each_entry(c, &clocks, node)
  296. if (c->parent == NULL)
  297. clock_tree_show_one(s, c, 0);
  298. spin_unlock_irqrestore(&clock_lock, flags);
  299. return 0;
  300. }
  301. static int clock_tree_open(struct inode *inode, struct file *file)
  302. {
  303. return single_open(file, clock_tree_show, inode->i_private);
  304. }
  305. static const struct file_operations clock_tree_fops = {
  306. .open = clock_tree_open,
  307. .read = seq_read,
  308. .llseek = seq_lseek,
  309. .release = single_release,
  310. };
  311. static int possible_parents_show(struct seq_file *s, void *data)
  312. {
  313. struct clk *c = s->private;
  314. int i;
  315. for (i = 0; c->inputs[i].input; i++) {
  316. char *first = (i == 0) ? "" : " ";
  317. seq_printf(s, "%s%s", first, c->inputs[i].input->name);
  318. }
  319. seq_printf(s, "\n");
  320. return 0;
  321. }
  322. static int possible_parents_open(struct inode *inode, struct file *file)
  323. {
  324. return single_open(file, possible_parents_show, inode->i_private);
  325. }
  326. static const struct file_operations possible_parents_fops = {
  327. .open = possible_parents_open,
  328. .read = seq_read,
  329. .llseek = seq_lseek,
  330. .release = single_release,
  331. };
  332. static int clk_debugfs_register_one(struct clk *c)
  333. {
  334. struct dentry *d, *child, *child_tmp;
  335. d = debugfs_create_dir(c->name, clk_debugfs_root);
  336. if (!d)
  337. return -ENOMEM;
  338. c->dent = d;
  339. d = debugfs_create_u8("refcnt", S_IRUGO, c->dent, (u8 *)&c->refcnt);
  340. if (!d)
  341. goto err_out;
  342. d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
  343. if (!d)
  344. goto err_out;
  345. d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
  346. if (!d)
  347. goto err_out;
  348. if (c->inputs) {
  349. d = debugfs_create_file("possible_parents", S_IRUGO, c->dent,
  350. c, &possible_parents_fops);
  351. if (!d)
  352. goto err_out;
  353. }
  354. return 0;
  355. err_out:
  356. d = c->dent;
  357. list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
  358. debugfs_remove(child);
  359. debugfs_remove(c->dent);
  360. return -ENOMEM;
  361. }
  362. static int clk_debugfs_register(struct clk *c)
  363. {
  364. int err;
  365. struct clk *pa = c->parent;
  366. if (pa && !pa->dent) {
  367. err = clk_debugfs_register(pa);
  368. if (err)
  369. return err;
  370. }
  371. if (!c->dent) {
  372. err = clk_debugfs_register_one(c);
  373. if (err)
  374. return err;
  375. }
  376. return 0;
  377. }
  378. static int __init clk_debugfs_init(void)
  379. {
  380. struct clk *c;
  381. struct dentry *d;
  382. int err = -ENOMEM;
  383. d = debugfs_create_dir("clock", NULL);
  384. if (!d)
  385. return -ENOMEM;
  386. clk_debugfs_root = d;
  387. d = debugfs_create_file("clock_tree", S_IRUGO, clk_debugfs_root, NULL,
  388. &clock_tree_fops);
  389. if (!d)
  390. goto err_out;
  391. list_for_each_entry(c, &clocks, node) {
  392. err = clk_debugfs_register(c);
  393. if (err)
  394. goto err_out;
  395. }
  396. return 0;
  397. err_out:
  398. debugfs_remove_recursive(clk_debugfs_root);
  399. return err;
  400. }
  401. late_initcall(clk_debugfs_init);
  402. #endif