/drivers/base/power/clock_ops.c

https://bitbucket.org/ndreys/linux-sunxi · C · 431 lines · 255 code · 71 blank · 105 comment · 49 complexity · 0689e5094c78b913bf0041f34a291297 MD5 · raw file

  1. /*
  2. * drivers/base/power/clock_ops.c - Generic clock manipulation PM callbacks
  3. *
  4. * Copyright (c) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
  5. *
  6. * This file is released under the GPLv2.
  7. */
  8. #include <linux/init.h>
  9. #include <linux/kernel.h>
  10. #include <linux/io.h>
  11. #include <linux/pm.h>
  12. #include <linux/pm_runtime.h>
  13. #include <linux/clk.h>
  14. #include <linux/slab.h>
  15. #include <linux/err.h>
  16. #ifdef CONFIG_PM_RUNTIME
  17. struct pm_runtime_clk_data {
  18. struct list_head clock_list;
  19. struct mutex lock;
  20. };
  21. enum pce_status {
  22. PCE_STATUS_NONE = 0,
  23. PCE_STATUS_ACQUIRED,
  24. PCE_STATUS_ENABLED,
  25. PCE_STATUS_ERROR,
  26. };
  27. struct pm_clock_entry {
  28. struct list_head node;
  29. char *con_id;
  30. struct clk *clk;
  31. enum pce_status status;
  32. };
  33. static struct pm_runtime_clk_data *__to_prd(struct device *dev)
  34. {
  35. return dev ? dev->power.subsys_data : NULL;
  36. }
  37. /**
  38. * pm_runtime_clk_add - Start using a device clock for runtime PM.
  39. * @dev: Device whose clock is going to be used for runtime PM.
  40. * @con_id: Connection ID of the clock.
  41. *
  42. * Add the clock represented by @con_id to the list of clocks used for
  43. * the runtime PM of @dev.
  44. */
  45. int pm_runtime_clk_add(struct device *dev, const char *con_id)
  46. {
  47. struct pm_runtime_clk_data *prd = __to_prd(dev);
  48. struct pm_clock_entry *ce;
  49. if (!prd)
  50. return -EINVAL;
  51. ce = kzalloc(sizeof(*ce), GFP_KERNEL);
  52. if (!ce) {
  53. dev_err(dev, "Not enough memory for clock entry.\n");
  54. return -ENOMEM;
  55. }
  56. if (con_id) {
  57. ce->con_id = kstrdup(con_id, GFP_KERNEL);
  58. if (!ce->con_id) {
  59. dev_err(dev,
  60. "Not enough memory for clock connection ID.\n");
  61. kfree(ce);
  62. return -ENOMEM;
  63. }
  64. }
  65. mutex_lock(&prd->lock);
  66. list_add_tail(&ce->node, &prd->clock_list);
  67. mutex_unlock(&prd->lock);
  68. return 0;
  69. }
  70. /**
  71. * __pm_runtime_clk_remove - Destroy runtime PM clock entry.
  72. * @ce: Runtime PM clock entry to destroy.
  73. *
  74. * This routine must be called under the mutex protecting the runtime PM list
  75. * of clocks corresponding the the @ce's device.
  76. */
  77. static void __pm_runtime_clk_remove(struct pm_clock_entry *ce)
  78. {
  79. if (!ce)
  80. return;
  81. list_del(&ce->node);
  82. if (ce->status < PCE_STATUS_ERROR) {
  83. if (ce->status == PCE_STATUS_ENABLED)
  84. clk_disable(ce->clk);
  85. if (ce->status >= PCE_STATUS_ACQUIRED)
  86. clk_put(ce->clk);
  87. }
  88. if (ce->con_id)
  89. kfree(ce->con_id);
  90. kfree(ce);
  91. }
  92. /**
  93. * pm_runtime_clk_remove - Stop using a device clock for runtime PM.
  94. * @dev: Device whose clock should not be used for runtime PM any more.
  95. * @con_id: Connection ID of the clock.
  96. *
  97. * Remove the clock represented by @con_id from the list of clocks used for
  98. * the runtime PM of @dev.
  99. */
  100. void pm_runtime_clk_remove(struct device *dev, const char *con_id)
  101. {
  102. struct pm_runtime_clk_data *prd = __to_prd(dev);
  103. struct pm_clock_entry *ce;
  104. if (!prd)
  105. return;
  106. mutex_lock(&prd->lock);
  107. list_for_each_entry(ce, &prd->clock_list, node) {
  108. if (!con_id && !ce->con_id) {
  109. __pm_runtime_clk_remove(ce);
  110. break;
  111. } else if (!con_id || !ce->con_id) {
  112. continue;
  113. } else if (!strcmp(con_id, ce->con_id)) {
  114. __pm_runtime_clk_remove(ce);
  115. break;
  116. }
  117. }
  118. mutex_unlock(&prd->lock);
  119. }
  120. /**
  121. * pm_runtime_clk_init - Initialize a device's list of runtime PM clocks.
  122. * @dev: Device to initialize the list of runtime PM clocks for.
  123. *
  124. * Allocate a struct pm_runtime_clk_data object, initialize its lock member and
  125. * make the @dev's power.subsys_data field point to it.
  126. */
  127. int pm_runtime_clk_init(struct device *dev)
  128. {
  129. struct pm_runtime_clk_data *prd;
  130. prd = kzalloc(sizeof(*prd), GFP_KERNEL);
  131. if (!prd) {
  132. dev_err(dev, "Not enough memory fo runtime PM data.\n");
  133. return -ENOMEM;
  134. }
  135. INIT_LIST_HEAD(&prd->clock_list);
  136. mutex_init(&prd->lock);
  137. dev->power.subsys_data = prd;
  138. return 0;
  139. }
  140. /**
  141. * pm_runtime_clk_destroy - Destroy a device's list of runtime PM clocks.
  142. * @dev: Device to destroy the list of runtime PM clocks for.
  143. *
  144. * Clear the @dev's power.subsys_data field, remove the list of clock entries
  145. * from the struct pm_runtime_clk_data object pointed to by it before and free
  146. * that object.
  147. */
  148. void pm_runtime_clk_destroy(struct device *dev)
  149. {
  150. struct pm_runtime_clk_data *prd = __to_prd(dev);
  151. struct pm_clock_entry *ce, *c;
  152. if (!prd)
  153. return;
  154. dev->power.subsys_data = NULL;
  155. mutex_lock(&prd->lock);
  156. list_for_each_entry_safe_reverse(ce, c, &prd->clock_list, node)
  157. __pm_runtime_clk_remove(ce);
  158. mutex_unlock(&prd->lock);
  159. kfree(prd);
  160. }
  161. /**
  162. * pm_runtime_clk_acquire - Acquire a device clock.
  163. * @dev: Device whose clock is to be acquired.
  164. * @con_id: Connection ID of the clock.
  165. */
  166. static void pm_runtime_clk_acquire(struct device *dev,
  167. struct pm_clock_entry *ce)
  168. {
  169. ce->clk = clk_get(dev, ce->con_id);
  170. if (IS_ERR(ce->clk)) {
  171. ce->status = PCE_STATUS_ERROR;
  172. } else {
  173. ce->status = PCE_STATUS_ACQUIRED;
  174. dev_dbg(dev, "Clock %s managed by runtime PM.\n", ce->con_id);
  175. }
  176. }
  177. /**
  178. * pm_runtime_clk_suspend - Disable clocks in a device's runtime PM clock list.
  179. * @dev: Device to disable the clocks for.
  180. */
  181. int pm_runtime_clk_suspend(struct device *dev)
  182. {
  183. struct pm_runtime_clk_data *prd = __to_prd(dev);
  184. struct pm_clock_entry *ce;
  185. dev_dbg(dev, "%s()\n", __func__);
  186. if (!prd)
  187. return 0;
  188. mutex_lock(&prd->lock);
  189. list_for_each_entry_reverse(ce, &prd->clock_list, node) {
  190. if (ce->status == PCE_STATUS_NONE)
  191. pm_runtime_clk_acquire(dev, ce);
  192. if (ce->status < PCE_STATUS_ERROR) {
  193. clk_disable(ce->clk);
  194. ce->status = PCE_STATUS_ACQUIRED;
  195. }
  196. }
  197. mutex_unlock(&prd->lock);
  198. return 0;
  199. }
  200. /**
  201. * pm_runtime_clk_resume - Enable clocks in a device's runtime PM clock list.
  202. * @dev: Device to enable the clocks for.
  203. */
  204. int pm_runtime_clk_resume(struct device *dev)
  205. {
  206. struct pm_runtime_clk_data *prd = __to_prd(dev);
  207. struct pm_clock_entry *ce;
  208. dev_dbg(dev, "%s()\n", __func__);
  209. if (!prd)
  210. return 0;
  211. mutex_lock(&prd->lock);
  212. list_for_each_entry(ce, &prd->clock_list, node) {
  213. if (ce->status == PCE_STATUS_NONE)
  214. pm_runtime_clk_acquire(dev, ce);
  215. if (ce->status < PCE_STATUS_ERROR) {
  216. clk_enable(ce->clk);
  217. ce->status = PCE_STATUS_ENABLED;
  218. }
  219. }
  220. mutex_unlock(&prd->lock);
  221. return 0;
  222. }
  223. /**
  224. * pm_runtime_clk_notify - Notify routine for device addition and removal.
  225. * @nb: Notifier block object this function is a member of.
  226. * @action: Operation being carried out by the caller.
  227. * @data: Device the routine is being run for.
  228. *
  229. * For this function to work, @nb must be a member of an object of type
  230. * struct pm_clk_notifier_block containing all of the requisite data.
  231. * Specifically, the pwr_domain member of that object is copied to the device's
  232. * pwr_domain field and its con_ids member is used to populate the device's list
  233. * of runtime PM clocks, depending on @action.
  234. *
  235. * If the device's pwr_domain field is already populated with a value different
  236. * from the one stored in the struct pm_clk_notifier_block object, the function
  237. * does nothing.
  238. */
  239. static int pm_runtime_clk_notify(struct notifier_block *nb,
  240. unsigned long action, void *data)
  241. {
  242. struct pm_clk_notifier_block *clknb;
  243. struct device *dev = data;
  244. char **con_id;
  245. int error;
  246. dev_dbg(dev, "%s() %ld\n", __func__, action);
  247. clknb = container_of(nb, struct pm_clk_notifier_block, nb);
  248. switch (action) {
  249. case BUS_NOTIFY_ADD_DEVICE:
  250. if (dev->pwr_domain)
  251. break;
  252. error = pm_runtime_clk_init(dev);
  253. if (error)
  254. break;
  255. dev->pwr_domain = clknb->pwr_domain;
  256. if (clknb->con_ids[0]) {
  257. for (con_id = clknb->con_ids; *con_id; con_id++)
  258. pm_runtime_clk_add(dev, *con_id);
  259. } else {
  260. pm_runtime_clk_add(dev, NULL);
  261. }
  262. break;
  263. case BUS_NOTIFY_DEL_DEVICE:
  264. if (dev->pwr_domain != clknb->pwr_domain)
  265. break;
  266. dev->pwr_domain = NULL;
  267. pm_runtime_clk_destroy(dev);
  268. break;
  269. }
  270. return 0;
  271. }
  272. #else /* !CONFIG_PM_RUNTIME */
  273. /**
  274. * enable_clock - Enable a device clock.
  275. * @dev: Device whose clock is to be enabled.
  276. * @con_id: Connection ID of the clock.
  277. */
  278. static void enable_clock(struct device *dev, const char *con_id)
  279. {
  280. struct clk *clk;
  281. clk = clk_get(dev, con_id);
  282. if (!IS_ERR(clk)) {
  283. clk_enable(clk);
  284. clk_put(clk);
  285. dev_info(dev, "Runtime PM disabled, clock forced on.\n");
  286. }
  287. }
  288. /**
  289. * disable_clock - Disable a device clock.
  290. * @dev: Device whose clock is to be disabled.
  291. * @con_id: Connection ID of the clock.
  292. */
  293. static void disable_clock(struct device *dev, const char *con_id)
  294. {
  295. struct clk *clk;
  296. clk = clk_get(dev, con_id);
  297. if (!IS_ERR(clk)) {
  298. clk_disable(clk);
  299. clk_put(clk);
  300. dev_info(dev, "Runtime PM disabled, clock forced off.\n");
  301. }
  302. }
  303. /**
  304. * pm_runtime_clk_notify - Notify routine for device addition and removal.
  305. * @nb: Notifier block object this function is a member of.
  306. * @action: Operation being carried out by the caller.
  307. * @data: Device the routine is being run for.
  308. *
  309. * For this function to work, @nb must be a member of an object of type
  310. * struct pm_clk_notifier_block containing all of the requisite data.
  311. * Specifically, the con_ids member of that object is used to enable or disable
  312. * the device's clocks, depending on @action.
  313. */
  314. static int pm_runtime_clk_notify(struct notifier_block *nb,
  315. unsigned long action, void *data)
  316. {
  317. struct pm_clk_notifier_block *clknb;
  318. struct device *dev = data;
  319. char **con_id;
  320. dev_dbg(dev, "%s() %ld\n", __func__, action);
  321. clknb = container_of(nb, struct pm_clk_notifier_block, nb);
  322. switch (action) {
  323. case BUS_NOTIFY_BIND_DRIVER:
  324. if (clknb->con_ids[0]) {
  325. for (con_id = clknb->con_ids; *con_id; con_id++)
  326. enable_clock(dev, *con_id);
  327. } else {
  328. enable_clock(dev, NULL);
  329. }
  330. break;
  331. case BUS_NOTIFY_UNBOUND_DRIVER:
  332. if (clknb->con_ids[0]) {
  333. for (con_id = clknb->con_ids; *con_id; con_id++)
  334. disable_clock(dev, *con_id);
  335. } else {
  336. disable_clock(dev, NULL);
  337. }
  338. break;
  339. }
  340. return 0;
  341. }
  342. #endif /* !CONFIG_PM_RUNTIME */
  343. /**
  344. * pm_runtime_clk_add_notifier - Add bus type notifier for runtime PM clocks.
  345. * @bus: Bus type to add the notifier to.
  346. * @clknb: Notifier to be added to the given bus type.
  347. *
  348. * The nb member of @clknb is not expected to be initialized and its
  349. * notifier_call member will be replaced with pm_runtime_clk_notify(). However,
  350. * the remaining members of @clknb should be populated prior to calling this
  351. * routine.
  352. */
  353. void pm_runtime_clk_add_notifier(struct bus_type *bus,
  354. struct pm_clk_notifier_block *clknb)
  355. {
  356. if (!bus || !clknb)
  357. return;
  358. clknb->nb.notifier_call = pm_runtime_clk_notify;
  359. bus_register_notifier(bus, &clknb->nb);
  360. }