platform.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. /*
  2. * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
  3. * <benh@kernel.crashing.org>
  4. * and Arnd Bergmann, IBM Corp.
  5. * Merged from powerpc/kernel/of_platform.c and
  6. * sparc{,64}/kernel/of_device.c by Stephen Rothwell
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version
  11. * 2 of the License, or (at your option) any later version.
  12. *
  13. */
  14. #include <linux/errno.h>
  15. #include <linux/module.h>
  16. #include <linux/device.h>
  17. #include <linux/of_device.h>
  18. #include <linux/of_platform.h>
  19. extern struct device_attribute of_platform_device_attrs[];
  20. static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
  21. {
  22. struct of_device *of_dev = to_of_device(dev);
  23. struct of_platform_driver *of_drv = to_of_platform_driver(drv);
  24. const struct of_device_id *matches = of_drv->match_table;
  25. if (!matches)
  26. return 0;
  27. return of_match_device(matches, of_dev) != NULL;
  28. }
  29. static int of_platform_device_probe(struct device *dev)
  30. {
  31. int error = -ENODEV;
  32. struct of_platform_driver *drv;
  33. struct of_device *of_dev;
  34. const struct of_device_id *match;
  35. drv = to_of_platform_driver(dev->driver);
  36. of_dev = to_of_device(dev);
  37. if (!drv->probe)
  38. return error;
  39. of_dev_get(of_dev);
  40. match = of_match_device(drv->match_table, of_dev);
  41. if (match)
  42. error = drv->probe(of_dev, match);
  43. if (error)
  44. of_dev_put(of_dev);
  45. return error;
  46. }
  47. static int of_platform_device_remove(struct device *dev)
  48. {
  49. struct of_device *of_dev = to_of_device(dev);
  50. struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
  51. if (dev->driver && drv->remove)
  52. drv->remove(of_dev);
  53. return 0;
  54. }
  55. static void of_platform_device_shutdown(struct device *dev)
  56. {
  57. struct of_device *of_dev = to_of_device(dev);
  58. struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
  59. if (dev->driver && drv->shutdown)
  60. drv->shutdown(of_dev);
  61. }
  62. #ifdef CONFIG_PM_SLEEP
  63. static int of_platform_legacy_suspend(struct device *dev, pm_message_t mesg)
  64. {
  65. struct of_device *of_dev = to_of_device(dev);
  66. struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
  67. int ret = 0;
  68. if (dev->driver && drv->suspend)
  69. ret = drv->suspend(of_dev, mesg);
  70. return ret;
  71. }
  72. static int of_platform_legacy_resume(struct device *dev)
  73. {
  74. struct of_device *of_dev = to_of_device(dev);
  75. struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
  76. int ret = 0;
  77. if (dev->driver && drv->resume)
  78. ret = drv->resume(of_dev);
  79. return ret;
  80. }
  81. static int of_platform_pm_prepare(struct device *dev)
  82. {
  83. struct device_driver *drv = dev->driver;
  84. int ret = 0;
  85. if (drv && drv->pm && drv->pm->prepare)
  86. ret = drv->pm->prepare(dev);
  87. return ret;
  88. }
  89. static void of_platform_pm_complete(struct device *dev)
  90. {
  91. struct device_driver *drv = dev->driver;
  92. if (drv && drv->pm && drv->pm->complete)
  93. drv->pm->complete(dev);
  94. }
  95. #ifdef CONFIG_SUSPEND
  96. static int of_platform_pm_suspend(struct device *dev)
  97. {
  98. struct device_driver *drv = dev->driver;
  99. int ret = 0;
  100. if (!drv)
  101. return 0;
  102. if (drv->pm) {
  103. if (drv->pm->suspend)
  104. ret = drv->pm->suspend(dev);
  105. } else {
  106. ret = of_platform_legacy_suspend(dev, PMSG_SUSPEND);
  107. }
  108. return ret;
  109. }
  110. static int of_platform_pm_suspend_noirq(struct device *dev)
  111. {
  112. struct device_driver *drv = dev->driver;
  113. int ret = 0;
  114. if (!drv)
  115. return 0;
  116. if (drv->pm) {
  117. if (drv->pm->suspend_noirq)
  118. ret = drv->pm->suspend_noirq(dev);
  119. }
  120. return ret;
  121. }
  122. static int of_platform_pm_resume(struct device *dev)
  123. {
  124. struct device_driver *drv = dev->driver;
  125. int ret = 0;
  126. if (!drv)
  127. return 0;
  128. if (drv->pm) {
  129. if (drv->pm->resume)
  130. ret = drv->pm->resume(dev);
  131. } else {
  132. ret = of_platform_legacy_resume(dev);
  133. }
  134. return ret;
  135. }
  136. static int of_platform_pm_resume_noirq(struct device *dev)
  137. {
  138. struct device_driver *drv = dev->driver;
  139. int ret = 0;
  140. if (!drv)
  141. return 0;
  142. if (drv->pm) {
  143. if (drv->pm->resume_noirq)
  144. ret = drv->pm->resume_noirq(dev);
  145. }
  146. return ret;
  147. }
  148. #else /* !CONFIG_SUSPEND */
  149. #define of_platform_pm_suspend NULL
  150. #define of_platform_pm_resume NULL
  151. #define of_platform_pm_suspend_noirq NULL
  152. #define of_platform_pm_resume_noirq NULL
  153. #endif /* !CONFIG_SUSPEND */
  154. #ifdef CONFIG_HIBERNATION
  155. static int of_platform_pm_freeze(struct device *dev)
  156. {
  157. struct device_driver *drv = dev->driver;
  158. int ret = 0;
  159. if (!drv)
  160. return 0;
  161. if (drv->pm) {
  162. if (drv->pm->freeze)
  163. ret = drv->pm->freeze(dev);
  164. } else {
  165. ret = of_platform_legacy_suspend(dev, PMSG_FREEZE);
  166. }
  167. return ret;
  168. }
  169. static int of_platform_pm_freeze_noirq(struct device *dev)
  170. {
  171. struct device_driver *drv = dev->driver;
  172. int ret = 0;
  173. if (!drv)
  174. return 0;
  175. if (drv->pm) {
  176. if (drv->pm->freeze_noirq)
  177. ret = drv->pm->freeze_noirq(dev);
  178. }
  179. return ret;
  180. }
  181. static int of_platform_pm_thaw(struct device *dev)
  182. {
  183. struct device_driver *drv = dev->driver;
  184. int ret = 0;
  185. if (!drv)
  186. return 0;
  187. if (drv->pm) {
  188. if (drv->pm->thaw)
  189. ret = drv->pm->thaw(dev);
  190. } else {
  191. ret = of_platform_legacy_resume(dev);
  192. }
  193. return ret;
  194. }
  195. static int of_platform_pm_thaw_noirq(struct device *dev)
  196. {
  197. struct device_driver *drv = dev->driver;
  198. int ret = 0;
  199. if (!drv)
  200. return 0;
  201. if (drv->pm) {
  202. if (drv->pm->thaw_noirq)
  203. ret = drv->pm->thaw_noirq(dev);
  204. }
  205. return ret;
  206. }
  207. static int of_platform_pm_poweroff(struct device *dev)
  208. {
  209. struct device_driver *drv = dev->driver;
  210. int ret = 0;
  211. if (!drv)
  212. return 0;
  213. if (drv->pm) {
  214. if (drv->pm->poweroff)
  215. ret = drv->pm->poweroff(dev);
  216. } else {
  217. ret = of_platform_legacy_suspend(dev, PMSG_HIBERNATE);
  218. }
  219. return ret;
  220. }
  221. static int of_platform_pm_poweroff_noirq(struct device *dev)
  222. {
  223. struct device_driver *drv = dev->driver;
  224. int ret = 0;
  225. if (!drv)
  226. return 0;
  227. if (drv->pm) {
  228. if (drv->pm->poweroff_noirq)
  229. ret = drv->pm->poweroff_noirq(dev);
  230. }
  231. return ret;
  232. }
  233. static int of_platform_pm_restore(struct device *dev)
  234. {
  235. struct device_driver *drv = dev->driver;
  236. int ret = 0;
  237. if (!drv)
  238. return 0;
  239. if (drv->pm) {
  240. if (drv->pm->restore)
  241. ret = drv->pm->restore(dev);
  242. } else {
  243. ret = of_platform_legacy_resume(dev);
  244. }
  245. return ret;
  246. }
  247. static int of_platform_pm_restore_noirq(struct device *dev)
  248. {
  249. struct device_driver *drv = dev->driver;
  250. int ret = 0;
  251. if (!drv)
  252. return 0;
  253. if (drv->pm) {
  254. if (drv->pm->restore_noirq)
  255. ret = drv->pm->restore_noirq(dev);
  256. }
  257. return ret;
  258. }
  259. #else /* !CONFIG_HIBERNATION */
  260. #define of_platform_pm_freeze NULL
  261. #define of_platform_pm_thaw NULL
  262. #define of_platform_pm_poweroff NULL
  263. #define of_platform_pm_restore NULL
  264. #define of_platform_pm_freeze_noirq NULL
  265. #define of_platform_pm_thaw_noirq NULL
  266. #define of_platform_pm_poweroff_noirq NULL
  267. #define of_platform_pm_restore_noirq NULL
  268. #endif /* !CONFIG_HIBERNATION */
  269. static struct dev_pm_ops of_platform_dev_pm_ops = {
  270. .prepare = of_platform_pm_prepare,
  271. .complete = of_platform_pm_complete,
  272. .suspend = of_platform_pm_suspend,
  273. .resume = of_platform_pm_resume,
  274. .freeze = of_platform_pm_freeze,
  275. .thaw = of_platform_pm_thaw,
  276. .poweroff = of_platform_pm_poweroff,
  277. .restore = of_platform_pm_restore,
  278. .suspend_noirq = of_platform_pm_suspend_noirq,
  279. .resume_noirq = of_platform_pm_resume_noirq,
  280. .freeze_noirq = of_platform_pm_freeze_noirq,
  281. .thaw_noirq = of_platform_pm_thaw_noirq,
  282. .poweroff_noirq = of_platform_pm_poweroff_noirq,
  283. .restore_noirq = of_platform_pm_restore_noirq,
  284. };
  285. #define OF_PLATFORM_PM_OPS_PTR (&of_platform_dev_pm_ops)
  286. #else /* !CONFIG_PM_SLEEP */
  287. #define OF_PLATFORM_PM_OPS_PTR NULL
  288. #endif /* !CONFIG_PM_SLEEP */
  289. int of_bus_type_init(struct bus_type *bus, const char *name)
  290. {
  291. bus->name = name;
  292. bus->match = of_platform_bus_match;
  293. bus->probe = of_platform_device_probe;
  294. bus->remove = of_platform_device_remove;
  295. bus->shutdown = of_platform_device_shutdown;
  296. bus->dev_attrs = of_platform_device_attrs;
  297. bus->pm = OF_PLATFORM_PM_OPS_PTR;
  298. return bus_register(bus);
  299. }
  300. int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
  301. {
  302. /* initialize common driver fields */
  303. if (!drv->driver.name)
  304. drv->driver.name = drv->name;
  305. if (!drv->driver.owner)
  306. drv->driver.owner = drv->owner;
  307. drv->driver.bus = bus;
  308. /* register with core */
  309. return driver_register(&drv->driver);
  310. }
  311. EXPORT_SYMBOL(of_register_driver);
  312. void of_unregister_driver(struct of_platform_driver *drv)
  313. {
  314. driver_unregister(&drv->driver);
  315. }
  316. EXPORT_SYMBOL(of_unregister_driver);