domain.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. /*
  2. * drivers/base/power/domain.c - Common code related to device power domains.
  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_runtime.h>
  12. #include <linux/pm_domain.h>
  13. #include <linux/slab.h>
  14. #include <linux/err.h>
  15. #ifdef CONFIG_PM_RUNTIME
  16. static void genpd_sd_counter_dec(struct generic_pm_domain *genpd)
  17. {
  18. if (!WARN_ON(genpd->sd_count == 0))
  19. genpd->sd_count--;
  20. }
  21. /**
  22. * __pm_genpd_save_device - Save the pre-suspend state of a device.
  23. * @dle: Device list entry of the device to save the state of.
  24. * @genpd: PM domain the device belongs to.
  25. */
  26. static int __pm_genpd_save_device(struct dev_list_entry *dle,
  27. struct generic_pm_domain *genpd)
  28. {
  29. struct device *dev = dle->dev;
  30. struct device_driver *drv = dev->driver;
  31. int ret = 0;
  32. if (dle->need_restore)
  33. return 0;
  34. if (drv && drv->pm && drv->pm->runtime_suspend) {
  35. if (genpd->start_device)
  36. genpd->start_device(dev);
  37. ret = drv->pm->runtime_suspend(dev);
  38. if (genpd->stop_device)
  39. genpd->stop_device(dev);
  40. }
  41. if (!ret)
  42. dle->need_restore = true;
  43. return ret;
  44. }
  45. /**
  46. * __pm_genpd_restore_device - Restore the pre-suspend state of a device.
  47. * @dle: Device list entry of the device to restore the state of.
  48. * @genpd: PM domain the device belongs to.
  49. */
  50. static void __pm_genpd_restore_device(struct dev_list_entry *dle,
  51. struct generic_pm_domain *genpd)
  52. {
  53. struct device *dev = dle->dev;
  54. struct device_driver *drv = dev->driver;
  55. if (!dle->need_restore)
  56. return;
  57. if (drv && drv->pm && drv->pm->runtime_resume) {
  58. if (genpd->start_device)
  59. genpd->start_device(dev);
  60. drv->pm->runtime_resume(dev);
  61. if (genpd->stop_device)
  62. genpd->stop_device(dev);
  63. }
  64. dle->need_restore = false;
  65. }
  66. /**
  67. * pm_genpd_poweroff - Remove power from a given PM domain.
  68. * @genpd: PM domain to power down.
  69. *
  70. * If all of the @genpd's devices have been suspended and all of its subdomains
  71. * have been powered down, run the runtime suspend callbacks provided by all of
  72. * the @genpd's devices' drivers and remove power from @genpd.
  73. */
  74. static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
  75. {
  76. struct generic_pm_domain *parent;
  77. struct dev_list_entry *dle;
  78. unsigned int not_suspended;
  79. int ret;
  80. if (genpd->power_is_off)
  81. return 0;
  82. if (genpd->sd_count > 0)
  83. return -EBUSY;
  84. not_suspended = 0;
  85. list_for_each_entry(dle, &genpd->dev_list, node)
  86. if (dle->dev->driver && !pm_runtime_suspended(dle->dev))
  87. not_suspended++;
  88. if (not_suspended > genpd->in_progress)
  89. return -EBUSY;
  90. if (genpd->gov && genpd->gov->power_down_ok) {
  91. if (!genpd->gov->power_down_ok(&genpd->domain))
  92. return -EAGAIN;
  93. }
  94. list_for_each_entry_reverse(dle, &genpd->dev_list, node) {
  95. ret = __pm_genpd_save_device(dle, genpd);
  96. if (ret)
  97. goto err_dev;
  98. }
  99. if (genpd->power_off)
  100. genpd->power_off(genpd);
  101. genpd->power_is_off = true;
  102. parent = genpd->parent;
  103. if (parent) {
  104. genpd_sd_counter_dec(parent);
  105. if (parent->sd_count == 0)
  106. queue_work(pm_wq, &parent->power_off_work);
  107. }
  108. return 0;
  109. err_dev:
  110. list_for_each_entry_continue(dle, &genpd->dev_list, node)
  111. __pm_genpd_restore_device(dle, genpd);
  112. return ret;
  113. }
  114. /**
  115. * genpd_power_off_work_fn - Power off PM domain whose subdomain count is 0.
  116. * @work: Work structure used for scheduling the execution of this function.
  117. */
  118. static void genpd_power_off_work_fn(struct work_struct *work)
  119. {
  120. struct generic_pm_domain *genpd;
  121. genpd = container_of(work, struct generic_pm_domain, power_off_work);
  122. if (genpd->parent)
  123. mutex_lock(&genpd->parent->lock);
  124. mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING);
  125. pm_genpd_poweroff(genpd);
  126. mutex_unlock(&genpd->lock);
  127. if (genpd->parent)
  128. mutex_unlock(&genpd->parent->lock);
  129. }
  130. /**
  131. * pm_genpd_runtime_suspend - Suspend a device belonging to I/O PM domain.
  132. * @dev: Device to suspend.
  133. *
  134. * Carry out a runtime suspend of a device under the assumption that its
  135. * pm_domain field points to the domain member of an object of type
  136. * struct generic_pm_domain representing a PM domain consisting of I/O devices.
  137. */
  138. static int pm_genpd_runtime_suspend(struct device *dev)
  139. {
  140. struct generic_pm_domain *genpd;
  141. dev_dbg(dev, "%s()\n", __func__);
  142. if (IS_ERR_OR_NULL(dev->pm_domain))
  143. return -EINVAL;
  144. genpd = container_of(dev->pm_domain, struct generic_pm_domain, domain);
  145. if (genpd->parent)
  146. mutex_lock(&genpd->parent->lock);
  147. mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING);
  148. if (genpd->stop_device) {
  149. int ret = genpd->stop_device(dev);
  150. if (ret)
  151. goto out;
  152. }
  153. genpd->in_progress++;
  154. pm_genpd_poweroff(genpd);
  155. genpd->in_progress--;
  156. out:
  157. mutex_unlock(&genpd->lock);
  158. if (genpd->parent)
  159. mutex_unlock(&genpd->parent->lock);
  160. return 0;
  161. }
  162. /**
  163. * pm_genpd_poweron - Restore power to a given PM domain and its parents.
  164. * @genpd: PM domain to power up.
  165. *
  166. * Restore power to @genpd and all of its parents so that it is possible to
  167. * resume a device belonging to it.
  168. */
  169. static int pm_genpd_poweron(struct generic_pm_domain *genpd)
  170. {
  171. int ret = 0;
  172. start:
  173. if (genpd->parent)
  174. mutex_lock(&genpd->parent->lock);
  175. mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING);
  176. if (!genpd->power_is_off)
  177. goto out;
  178. if (genpd->parent && genpd->parent->power_is_off) {
  179. mutex_unlock(&genpd->lock);
  180. mutex_unlock(&genpd->parent->lock);
  181. ret = pm_genpd_poweron(genpd->parent);
  182. if (ret)
  183. return ret;
  184. goto start;
  185. }
  186. if (genpd->power_on) {
  187. int ret = genpd->power_on(genpd);
  188. if (ret)
  189. goto out;
  190. }
  191. genpd->power_is_off = false;
  192. if (genpd->parent)
  193. genpd->parent->sd_count++;
  194. out:
  195. mutex_unlock(&genpd->lock);
  196. if (genpd->parent)
  197. mutex_unlock(&genpd->parent->lock);
  198. return ret;
  199. }
  200. /**
  201. * pm_genpd_runtime_resume - Resume a device belonging to I/O PM domain.
  202. * @dev: Device to resume.
  203. *
  204. * Carry out a runtime resume of a device under the assumption that its
  205. * pm_domain field points to the domain member of an object of type
  206. * struct generic_pm_domain representing a PM domain consisting of I/O devices.
  207. */
  208. static int pm_genpd_runtime_resume(struct device *dev)
  209. {
  210. struct generic_pm_domain *genpd;
  211. struct dev_list_entry *dle;
  212. int ret;
  213. dev_dbg(dev, "%s()\n", __func__);
  214. if (IS_ERR_OR_NULL(dev->pm_domain))
  215. return -EINVAL;
  216. genpd = container_of(dev->pm_domain, struct generic_pm_domain, domain);
  217. ret = pm_genpd_poweron(genpd);
  218. if (ret)
  219. return ret;
  220. mutex_lock(&genpd->lock);
  221. list_for_each_entry(dle, &genpd->dev_list, node) {
  222. if (dle->dev == dev) {
  223. __pm_genpd_restore_device(dle, genpd);
  224. break;
  225. }
  226. }
  227. if (genpd->start_device)
  228. genpd->start_device(dev);
  229. mutex_unlock(&genpd->lock);
  230. return 0;
  231. }
  232. #else
  233. static inline void genpd_power_off_work_fn(struct work_struct *work) {}
  234. #define pm_genpd_runtime_suspend NULL
  235. #define pm_genpd_runtime_resume NULL
  236. #endif /* CONFIG_PM_RUNTIME */
  237. /**
  238. * pm_genpd_add_device - Add a device to an I/O PM domain.
  239. * @genpd: PM domain to add the device to.
  240. * @dev: Device to be added.
  241. */
  242. int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev)
  243. {
  244. struct dev_list_entry *dle;
  245. int ret = 0;
  246. dev_dbg(dev, "%s()\n", __func__);
  247. if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
  248. return -EINVAL;
  249. mutex_lock(&genpd->lock);
  250. if (genpd->power_is_off) {
  251. ret = -EINVAL;
  252. goto out;
  253. }
  254. list_for_each_entry(dle, &genpd->dev_list, node)
  255. if (dle->dev == dev) {
  256. ret = -EINVAL;
  257. goto out;
  258. }
  259. dle = kzalloc(sizeof(*dle), GFP_KERNEL);
  260. if (!dle) {
  261. ret = -ENOMEM;
  262. goto out;
  263. }
  264. dle->dev = dev;
  265. dle->need_restore = false;
  266. list_add_tail(&dle->node, &genpd->dev_list);
  267. spin_lock_irq(&dev->power.lock);
  268. dev->pm_domain = &genpd->domain;
  269. spin_unlock_irq(&dev->power.lock);
  270. out:
  271. mutex_unlock(&genpd->lock);
  272. return ret;
  273. }
  274. /**
  275. * pm_genpd_remove_device - Remove a device from an I/O PM domain.
  276. * @genpd: PM domain to remove the device from.
  277. * @dev: Device to be removed.
  278. */
  279. int pm_genpd_remove_device(struct generic_pm_domain *genpd,
  280. struct device *dev)
  281. {
  282. struct dev_list_entry *dle;
  283. int ret = -EINVAL;
  284. dev_dbg(dev, "%s()\n", __func__);
  285. if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
  286. return -EINVAL;
  287. mutex_lock(&genpd->lock);
  288. list_for_each_entry(dle, &genpd->dev_list, node) {
  289. if (dle->dev != dev)
  290. continue;
  291. spin_lock_irq(&dev->power.lock);
  292. dev->pm_domain = NULL;
  293. spin_unlock_irq(&dev->power.lock);
  294. list_del(&dle->node);
  295. kfree(dle);
  296. ret = 0;
  297. break;
  298. }
  299. mutex_unlock(&genpd->lock);
  300. return ret;
  301. }
  302. /**
  303. * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain.
  304. * @genpd: Master PM domain to add the subdomain to.
  305. * @new_subdomain: Subdomain to be added.
  306. */
  307. int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
  308. struct generic_pm_domain *new_subdomain)
  309. {
  310. struct generic_pm_domain *subdomain;
  311. int ret = 0;
  312. if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(new_subdomain))
  313. return -EINVAL;
  314. mutex_lock(&genpd->lock);
  315. if (genpd->power_is_off && !new_subdomain->power_is_off) {
  316. ret = -EINVAL;
  317. goto out;
  318. }
  319. list_for_each_entry(subdomain, &genpd->sd_list, sd_node) {
  320. if (subdomain == new_subdomain) {
  321. ret = -EINVAL;
  322. goto out;
  323. }
  324. }
  325. mutex_lock_nested(&new_subdomain->lock, SINGLE_DEPTH_NESTING);
  326. list_add_tail(&new_subdomain->sd_node, &genpd->sd_list);
  327. new_subdomain->parent = genpd;
  328. if (!subdomain->power_is_off)
  329. genpd->sd_count++;
  330. mutex_unlock(&new_subdomain->lock);
  331. out:
  332. mutex_unlock(&genpd->lock);
  333. return ret;
  334. }
  335. /**
  336. * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
  337. * @genpd: Master PM domain to remove the subdomain from.
  338. * @target: Subdomain to be removed.
  339. */
  340. int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
  341. struct generic_pm_domain *target)
  342. {
  343. struct generic_pm_domain *subdomain;
  344. int ret = -EINVAL;
  345. if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(target))
  346. return -EINVAL;
  347. mutex_lock(&genpd->lock);
  348. list_for_each_entry(subdomain, &genpd->sd_list, sd_node) {
  349. if (subdomain != target)
  350. continue;
  351. mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING);
  352. list_del(&subdomain->sd_node);
  353. subdomain->parent = NULL;
  354. if (!subdomain->power_is_off)
  355. genpd_sd_counter_dec(genpd);
  356. mutex_unlock(&subdomain->lock);
  357. ret = 0;
  358. break;
  359. }
  360. mutex_unlock(&genpd->lock);
  361. return ret;
  362. }
  363. /**
  364. * pm_genpd_init - Initialize a generic I/O PM domain object.
  365. * @genpd: PM domain object to initialize.
  366. * @gov: PM domain governor to associate with the domain (may be NULL).
  367. * @is_off: Initial value of the domain's power_is_off field.
  368. */
  369. void pm_genpd_init(struct generic_pm_domain *genpd,
  370. struct dev_power_governor *gov, bool is_off)
  371. {
  372. if (IS_ERR_OR_NULL(genpd))
  373. return;
  374. INIT_LIST_HEAD(&genpd->sd_node);
  375. genpd->parent = NULL;
  376. INIT_LIST_HEAD(&genpd->dev_list);
  377. INIT_LIST_HEAD(&genpd->sd_list);
  378. mutex_init(&genpd->lock);
  379. genpd->gov = gov;
  380. INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn);
  381. genpd->in_progress = 0;
  382. genpd->sd_count = 0;
  383. genpd->power_is_off = is_off;
  384. genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend;
  385. genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume;
  386. genpd->domain.ops.runtime_idle = pm_generic_runtime_idle;
  387. }