platform.c 8.2 KB

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