platform.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984
  1. /*
  2. * platform.c - platform 'pseudo' bus for legacy devices
  3. *
  4. * Copyright (c) 2002-3 Patrick Mochel
  5. * Copyright (c) 2002-3 Open Source Development Labs
  6. *
  7. * This file is released under the GPLv2
  8. *
  9. * Please see Documentation/driver-model/platform.txt for more
  10. * information.
  11. */
  12. #include <linux/platform_device.h>
  13. #include <linux/module.h>
  14. #include <linux/init.h>
  15. #include <linux/dma-mapping.h>
  16. #include <linux/bootmem.h>
  17. #include <linux/err.h>
  18. #include <linux/slab.h>
  19. #include "base.h"
  20. #define to_platform_driver(drv) (container_of((drv), struct platform_driver, \
  21. driver))
  22. struct device platform_bus = {
  23. .bus_id = "platform",
  24. };
  25. EXPORT_SYMBOL_GPL(platform_bus);
  26. /**
  27. * platform_get_resource - get a resource for a device
  28. * @dev: platform device
  29. * @type: resource type
  30. * @num: resource index
  31. */
  32. struct resource *platform_get_resource(struct platform_device *dev,
  33. unsigned int type, unsigned int num)
  34. {
  35. int i;
  36. for (i = 0; i < dev->num_resources; i++) {
  37. struct resource *r = &dev->resource[i];
  38. if (type == resource_type(r) && num-- == 0)
  39. return r;
  40. }
  41. return NULL;
  42. }
  43. EXPORT_SYMBOL_GPL(platform_get_resource);
  44. /**
  45. * platform_get_irq - get an IRQ for a device
  46. * @dev: platform device
  47. * @num: IRQ number index
  48. */
  49. int platform_get_irq(struct platform_device *dev, unsigned int num)
  50. {
  51. struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num);
  52. return r ? r->start : -ENXIO;
  53. }
  54. EXPORT_SYMBOL_GPL(platform_get_irq);
  55. /**
  56. * platform_get_resource_byname - get a resource for a device by name
  57. * @dev: platform device
  58. * @type: resource type
  59. * @name: resource name
  60. */
  61. struct resource *platform_get_resource_byname(struct platform_device *dev,
  62. unsigned int type, char *name)
  63. {
  64. int i;
  65. for (i = 0; i < dev->num_resources; i++) {
  66. struct resource *r = &dev->resource[i];
  67. if (type == resource_type(r) && !strcmp(r->name, name))
  68. return r;
  69. }
  70. return NULL;
  71. }
  72. EXPORT_SYMBOL_GPL(platform_get_resource_byname);
  73. /**
  74. * platform_get_irq - get an IRQ for a device
  75. * @dev: platform device
  76. * @name: IRQ name
  77. */
  78. int platform_get_irq_byname(struct platform_device *dev, char *name)
  79. {
  80. struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ,
  81. name);
  82. return r ? r->start : -ENXIO;
  83. }
  84. EXPORT_SYMBOL_GPL(platform_get_irq_byname);
  85. /**
  86. * platform_add_devices - add a numbers of platform devices
  87. * @devs: array of platform devices to add
  88. * @num: number of platform devices in array
  89. */
  90. int platform_add_devices(struct platform_device **devs, int num)
  91. {
  92. int i, ret = 0;
  93. for (i = 0; i < num; i++) {
  94. ret = platform_device_register(devs[i]);
  95. if (ret) {
  96. while (--i >= 0)
  97. platform_device_unregister(devs[i]);
  98. break;
  99. }
  100. }
  101. return ret;
  102. }
  103. EXPORT_SYMBOL_GPL(platform_add_devices);
  104. struct platform_object {
  105. struct platform_device pdev;
  106. char name[1];
  107. };
  108. /**
  109. * platform_device_put
  110. * @pdev: platform device to free
  111. *
  112. * Free all memory associated with a platform device. This function must
  113. * _only_ be externally called in error cases. All other usage is a bug.
  114. */
  115. void platform_device_put(struct platform_device *pdev)
  116. {
  117. if (pdev)
  118. put_device(&pdev->dev);
  119. }
  120. EXPORT_SYMBOL_GPL(platform_device_put);
  121. static void platform_device_release(struct device *dev)
  122. {
  123. struct platform_object *pa = container_of(dev, struct platform_object,
  124. pdev.dev);
  125. kfree(pa->pdev.dev.platform_data);
  126. kfree(pa->pdev.resource);
  127. kfree(pa);
  128. }
  129. /**
  130. * platform_device_alloc
  131. * @name: base name of the device we're adding
  132. * @id: instance id
  133. *
  134. * Create a platform device object which can have other objects attached
  135. * to it, and which will have attached objects freed when it is released.
  136. */
  137. struct platform_device *platform_device_alloc(const char *name, int id)
  138. {
  139. struct platform_object *pa;
  140. pa = kzalloc(sizeof(struct platform_object) + strlen(name), GFP_KERNEL);
  141. if (pa) {
  142. strcpy(pa->name, name);
  143. pa->pdev.name = pa->name;
  144. pa->pdev.id = id;
  145. device_initialize(&pa->pdev.dev);
  146. pa->pdev.dev.release = platform_device_release;
  147. }
  148. return pa ? &pa->pdev : NULL;
  149. }
  150. EXPORT_SYMBOL_GPL(platform_device_alloc);
  151. /**
  152. * platform_device_add_resources
  153. * @pdev: platform device allocated by platform_device_alloc to add resources to
  154. * @res: set of resources that needs to be allocated for the device
  155. * @num: number of resources
  156. *
  157. * Add a copy of the resources to the platform device. The memory
  158. * associated with the resources will be freed when the platform device is
  159. * released.
  160. */
  161. int platform_device_add_resources(struct platform_device *pdev,
  162. struct resource *res, unsigned int num)
  163. {
  164. struct resource *r;
  165. r = kmalloc(sizeof(struct resource) * num, GFP_KERNEL);
  166. if (r) {
  167. memcpy(r, res, sizeof(struct resource) * num);
  168. pdev->resource = r;
  169. pdev->num_resources = num;
  170. }
  171. return r ? 0 : -ENOMEM;
  172. }
  173. EXPORT_SYMBOL_GPL(platform_device_add_resources);
  174. /**
  175. * platform_device_add_data
  176. * @pdev: platform device allocated by platform_device_alloc to add resources to
  177. * @data: platform specific data for this platform device
  178. * @size: size of platform specific data
  179. *
  180. * Add a copy of platform specific data to the platform device's
  181. * platform_data pointer. The memory associated with the platform data
  182. * will be freed when the platform device is released.
  183. */
  184. int platform_device_add_data(struct platform_device *pdev, const void *data,
  185. size_t size)
  186. {
  187. void *d;
  188. d = kmalloc(size, GFP_KERNEL);
  189. if (d) {
  190. memcpy(d, data, size);
  191. pdev->dev.platform_data = d;
  192. }
  193. return d ? 0 : -ENOMEM;
  194. }
  195. EXPORT_SYMBOL_GPL(platform_device_add_data);
  196. /**
  197. * platform_device_add - add a platform device to device hierarchy
  198. * @pdev: platform device we're adding
  199. *
  200. * This is part 2 of platform_device_register(), though may be called
  201. * separately _iff_ pdev was allocated by platform_device_alloc().
  202. */
  203. int platform_device_add(struct platform_device *pdev)
  204. {
  205. int i, ret = 0;
  206. if (!pdev)
  207. return -EINVAL;
  208. if (!pdev->dev.parent)
  209. pdev->dev.parent = &platform_bus;
  210. pdev->dev.bus = &platform_bus_type;
  211. if (pdev->id != -1)
  212. snprintf(pdev->dev.bus_id, BUS_ID_SIZE, "%s.%d", pdev->name,
  213. pdev->id);
  214. else
  215. strlcpy(pdev->dev.bus_id, pdev->name, BUS_ID_SIZE);
  216. for (i = 0; i < pdev->num_resources; i++) {
  217. struct resource *p, *r = &pdev->resource[i];
  218. if (r->name == NULL)
  219. r->name = pdev->dev.bus_id;
  220. p = r->parent;
  221. if (!p) {
  222. if (resource_type(r) == IORESOURCE_MEM)
  223. p = &iomem_resource;
  224. else if (resource_type(r) == IORESOURCE_IO)
  225. p = &ioport_resource;
  226. }
  227. if (p && insert_resource(p, r)) {
  228. printk(KERN_ERR
  229. "%s: failed to claim resource %d\n",
  230. pdev->dev.bus_id, i);
  231. ret = -EBUSY;
  232. goto failed;
  233. }
  234. }
  235. pr_debug("Registering platform device '%s'. Parent at %s\n",
  236. pdev->dev.bus_id, pdev->dev.parent->bus_id);
  237. ret = device_add(&pdev->dev);
  238. if (ret == 0)
  239. return ret;
  240. failed:
  241. while (--i >= 0) {
  242. struct resource *r = &pdev->resource[i];
  243. unsigned long type = resource_type(r);
  244. if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
  245. release_resource(r);
  246. }
  247. return ret;
  248. }
  249. EXPORT_SYMBOL_GPL(platform_device_add);
  250. /**
  251. * platform_device_del - remove a platform-level device
  252. * @pdev: platform device we're removing
  253. *
  254. * Note that this function will also release all memory- and port-based
  255. * resources owned by the device (@dev->resource). This function must
  256. * _only_ be externally called in error cases. All other usage is a bug.
  257. */
  258. void platform_device_del(struct platform_device *pdev)
  259. {
  260. int i;
  261. if (pdev) {
  262. device_del(&pdev->dev);
  263. for (i = 0; i < pdev->num_resources; i++) {
  264. struct resource *r = &pdev->resource[i];
  265. unsigned long type = resource_type(r);
  266. if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
  267. release_resource(r);
  268. }
  269. }
  270. }
  271. EXPORT_SYMBOL_GPL(platform_device_del);
  272. /**
  273. * platform_device_register - add a platform-level device
  274. * @pdev: platform device we're adding
  275. */
  276. int platform_device_register(struct platform_device *pdev)
  277. {
  278. device_initialize(&pdev->dev);
  279. return platform_device_add(pdev);
  280. }
  281. EXPORT_SYMBOL_GPL(platform_device_register);
  282. /**
  283. * platform_device_unregister - unregister a platform-level device
  284. * @pdev: platform device we're unregistering
  285. *
  286. * Unregistration is done in 2 steps. First we release all resources
  287. * and remove it from the subsystem, then we drop reference count by
  288. * calling platform_device_put().
  289. */
  290. void platform_device_unregister(struct platform_device *pdev)
  291. {
  292. platform_device_del(pdev);
  293. platform_device_put(pdev);
  294. }
  295. EXPORT_SYMBOL_GPL(platform_device_unregister);
  296. /**
  297. * platform_device_register_simple
  298. * @name: base name of the device we're adding
  299. * @id: instance id
  300. * @res: set of resources that needs to be allocated for the device
  301. * @num: number of resources
  302. *
  303. * This function creates a simple platform device that requires minimal
  304. * resource and memory management. Canned release function freeing memory
  305. * allocated for the device allows drivers using such devices to be
  306. * unloaded without waiting for the last reference to the device to be
  307. * dropped.
  308. *
  309. * This interface is primarily intended for use with legacy drivers which
  310. * probe hardware directly. Because such drivers create sysfs device nodes
  311. * themselves, rather than letting system infrastructure handle such device
  312. * enumeration tasks, they don't fully conform to the Linux driver model.
  313. * In particular, when such drivers are built as modules, they can't be
  314. * "hotplugged".
  315. */
  316. struct platform_device *platform_device_register_simple(const char *name,
  317. int id,
  318. struct resource *res,
  319. unsigned int num)
  320. {
  321. struct platform_device *pdev;
  322. int retval;
  323. pdev = platform_device_alloc(name, id);
  324. if (!pdev) {
  325. retval = -ENOMEM;
  326. goto error;
  327. }
  328. if (num) {
  329. retval = platform_device_add_resources(pdev, res, num);
  330. if (retval)
  331. goto error;
  332. }
  333. retval = platform_device_add(pdev);
  334. if (retval)
  335. goto error;
  336. return pdev;
  337. error:
  338. platform_device_put(pdev);
  339. return ERR_PTR(retval);
  340. }
  341. EXPORT_SYMBOL_GPL(platform_device_register_simple);
  342. /**
  343. * platform_device_register_data
  344. * @parent: parent device for the device we're adding
  345. * @name: base name of the device we're adding
  346. * @id: instance id
  347. * @data: platform specific data for this platform device
  348. * @size: size of platform specific data
  349. *
  350. * This function creates a simple platform device that requires minimal
  351. * resource and memory management. Canned release function freeing memory
  352. * allocated for the device allows drivers using such devices to be
  353. * unloaded without waiting for the last reference to the device to be
  354. * dropped.
  355. */
  356. struct platform_device *platform_device_register_data(
  357. struct device *parent,
  358. const char *name, int id,
  359. const void *data, size_t size)
  360. {
  361. struct platform_device *pdev;
  362. int retval;
  363. pdev = platform_device_alloc(name, id);
  364. if (!pdev) {
  365. retval = -ENOMEM;
  366. goto error;
  367. }
  368. pdev->dev.parent = parent;
  369. if (size) {
  370. retval = platform_device_add_data(pdev, data, size);
  371. if (retval)
  372. goto error;
  373. }
  374. retval = platform_device_add(pdev);
  375. if (retval)
  376. goto error;
  377. return pdev;
  378. error:
  379. platform_device_put(pdev);
  380. return ERR_PTR(retval);
  381. }
  382. static int platform_drv_probe(struct device *_dev)
  383. {
  384. struct platform_driver *drv = to_platform_driver(_dev->driver);
  385. struct platform_device *dev = to_platform_device(_dev);
  386. return drv->probe(dev);
  387. }
  388. static int platform_drv_probe_fail(struct device *_dev)
  389. {
  390. return -ENXIO;
  391. }
  392. static int platform_drv_remove(struct device *_dev)
  393. {
  394. struct platform_driver *drv = to_platform_driver(_dev->driver);
  395. struct platform_device *dev = to_platform_device(_dev);
  396. return drv->remove(dev);
  397. }
  398. static void platform_drv_shutdown(struct device *_dev)
  399. {
  400. struct platform_driver *drv = to_platform_driver(_dev->driver);
  401. struct platform_device *dev = to_platform_device(_dev);
  402. drv->shutdown(dev);
  403. }
  404. static int platform_drv_suspend(struct device *_dev, pm_message_t state)
  405. {
  406. struct platform_driver *drv = to_platform_driver(_dev->driver);
  407. struct platform_device *dev = to_platform_device(_dev);
  408. return drv->suspend(dev, state);
  409. }
  410. static int platform_drv_resume(struct device *_dev)
  411. {
  412. struct platform_driver *drv = to_platform_driver(_dev->driver);
  413. struct platform_device *dev = to_platform_device(_dev);
  414. return drv->resume(dev);
  415. }
  416. /**
  417. * platform_driver_register
  418. * @drv: platform driver structure
  419. */
  420. int platform_driver_register(struct platform_driver *drv)
  421. {
  422. drv->driver.bus = &platform_bus_type;
  423. if (drv->probe)
  424. drv->driver.probe = platform_drv_probe;
  425. if (drv->remove)
  426. drv->driver.remove = platform_drv_remove;
  427. if (drv->shutdown)
  428. drv->driver.shutdown = platform_drv_shutdown;
  429. if (drv->suspend)
  430. drv->driver.suspend = platform_drv_suspend;
  431. if (drv->resume)
  432. drv->driver.resume = platform_drv_resume;
  433. if (drv->pm)
  434. drv->driver.pm = &drv->pm->base;
  435. return driver_register(&drv->driver);
  436. }
  437. EXPORT_SYMBOL_GPL(platform_driver_register);
  438. /**
  439. * platform_driver_unregister
  440. * @drv: platform driver structure
  441. */
  442. void platform_driver_unregister(struct platform_driver *drv)
  443. {
  444. driver_unregister(&drv->driver);
  445. }
  446. EXPORT_SYMBOL_GPL(platform_driver_unregister);
  447. /**
  448. * platform_driver_probe - register driver for non-hotpluggable device
  449. * @drv: platform driver structure
  450. * @probe: the driver probe routine, probably from an __init section
  451. *
  452. * Use this instead of platform_driver_register() when you know the device
  453. * is not hotpluggable and has already been registered, and you want to
  454. * remove its run-once probe() infrastructure from memory after the driver
  455. * has bound to the device.
  456. *
  457. * One typical use for this would be with drivers for controllers integrated
  458. * into system-on-chip processors, where the controller devices have been
  459. * configured as part of board setup.
  460. *
  461. * Returns zero if the driver registered and bound to a device, else returns
  462. * a negative error code and with the driver not registered.
  463. */
  464. int __init_or_module platform_driver_probe(struct platform_driver *drv,
  465. int (*probe)(struct platform_device *))
  466. {
  467. int retval, code;
  468. /* temporary section violation during probe() */
  469. drv->probe = probe;
  470. retval = code = platform_driver_register(drv);
  471. /* Fixup that section violation, being paranoid about code scanning
  472. * the list of drivers in order to probe new devices. Check to see
  473. * if the probe was successful, and make sure any forced probes of
  474. * new devices fail.
  475. */
  476. spin_lock(&platform_bus_type.p->klist_drivers.k_lock);
  477. drv->probe = NULL;
  478. if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list))
  479. retval = -ENODEV;
  480. drv->driver.probe = platform_drv_probe_fail;
  481. spin_unlock(&platform_bus_type.p->klist_drivers.k_lock);
  482. if (code != retval)
  483. platform_driver_unregister(drv);
  484. return retval;
  485. }
  486. EXPORT_SYMBOL_GPL(platform_driver_probe);
  487. /* modalias support enables more hands-off userspace setup:
  488. * (a) environment variable lets new-style hotplug events work once system is
  489. * fully running: "modprobe $MODALIAS"
  490. * (b) sysfs attribute lets new-style coldplug recover from hotplug events
  491. * mishandled before system is fully running: "modprobe $(cat modalias)"
  492. */
  493. static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
  494. char *buf)
  495. {
  496. struct platform_device *pdev = to_platform_device(dev);
  497. int len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name);
  498. return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
  499. }
  500. static struct device_attribute platform_dev_attrs[] = {
  501. __ATTR_RO(modalias),
  502. __ATTR_NULL,
  503. };
  504. static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
  505. {
  506. struct platform_device *pdev = to_platform_device(dev);
  507. add_uevent_var(env, "MODALIAS=platform:%s", pdev->name);
  508. return 0;
  509. }
  510. /**
  511. * platform_match - bind platform device to platform driver.
  512. * @dev: device.
  513. * @drv: driver.
  514. *
  515. * Platform device IDs are assumed to be encoded like this:
  516. * "<name><instance>", where <name> is a short description of the type of
  517. * device, like "pci" or "floppy", and <instance> is the enumerated
  518. * instance of the device, like '0' or '42'. Driver IDs are simply
  519. * "<name>". So, extract the <name> from the platform_device structure,
  520. * and compare it against the name of the driver. Return whether they match
  521. * or not.
  522. */
  523. static int platform_match(struct device *dev, struct device_driver *drv)
  524. {
  525. struct platform_device *pdev;
  526. pdev = container_of(dev, struct platform_device, dev);
  527. return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);
  528. }
  529. #ifdef CONFIG_PM_SLEEP
  530. static int platform_legacy_suspend(struct device *dev, pm_message_t mesg)
  531. {
  532. int ret = 0;
  533. if (dev->driver && dev->driver->suspend)
  534. ret = dev->driver->suspend(dev, mesg);
  535. return ret;
  536. }
  537. static int platform_legacy_suspend_late(struct device *dev, pm_message_t mesg)
  538. {
  539. struct platform_driver *drv = to_platform_driver(dev->driver);
  540. struct platform_device *pdev;
  541. int ret = 0;
  542. pdev = container_of(dev, struct platform_device, dev);
  543. if (dev->driver && drv->suspend_late)
  544. ret = drv->suspend_late(pdev, mesg);
  545. return ret;
  546. }
  547. static int platform_legacy_resume_early(struct device *dev)
  548. {
  549. struct platform_driver *drv = to_platform_driver(dev->driver);
  550. struct platform_device *pdev;
  551. int ret = 0;
  552. pdev = container_of(dev, struct platform_device, dev);
  553. if (dev->driver && drv->resume_early)
  554. ret = drv->resume_early(pdev);
  555. return ret;
  556. }
  557. static int platform_legacy_resume(struct device *dev)
  558. {
  559. int ret = 0;
  560. if (dev->driver && dev->driver->resume)
  561. ret = dev->driver->resume(dev);
  562. return ret;
  563. }
  564. static int platform_pm_prepare(struct device *dev)
  565. {
  566. struct device_driver *drv = dev->driver;
  567. int ret = 0;
  568. if (drv && drv->pm && drv->pm->prepare)
  569. ret = drv->pm->prepare(dev);
  570. return ret;
  571. }
  572. static void platform_pm_complete(struct device *dev)
  573. {
  574. struct device_driver *drv = dev->driver;
  575. if (drv && drv->pm && drv->pm->complete)
  576. drv->pm->complete(dev);
  577. }
  578. #ifdef CONFIG_SUSPEND
  579. static int platform_pm_suspend(struct device *dev)
  580. {
  581. struct device_driver *drv = dev->driver;
  582. int ret = 0;
  583. if (drv && drv->pm) {
  584. if (drv->pm->suspend)
  585. ret = drv->pm->suspend(dev);
  586. } else {
  587. ret = platform_legacy_suspend(dev, PMSG_SUSPEND);
  588. }
  589. return ret;
  590. }
  591. static int platform_pm_suspend_noirq(struct device *dev)
  592. {
  593. struct platform_driver *pdrv;
  594. int ret = 0;
  595. if (!dev->driver)
  596. return 0;
  597. pdrv = to_platform_driver(dev->driver);
  598. if (pdrv->pm) {
  599. if (pdrv->pm->suspend_noirq)
  600. ret = pdrv->pm->suspend_noirq(dev);
  601. } else {
  602. ret = platform_legacy_suspend_late(dev, PMSG_SUSPEND);
  603. }
  604. return ret;
  605. }
  606. static int platform_pm_resume(struct device *dev)
  607. {
  608. struct device_driver *drv = dev->driver;
  609. int ret = 0;
  610. if (drv && drv->pm) {
  611. if (drv->pm->resume)
  612. ret = drv->pm->resume(dev);
  613. } else {
  614. ret = platform_legacy_resume(dev);
  615. }
  616. return ret;
  617. }
  618. static int platform_pm_resume_noirq(struct device *dev)
  619. {
  620. struct platform_driver *pdrv;
  621. int ret = 0;
  622. if (!dev->driver)
  623. return 0;
  624. pdrv = to_platform_driver(dev->driver);
  625. if (pdrv->pm) {
  626. if (pdrv->pm->resume_noirq)
  627. ret = pdrv->pm->resume_noirq(dev);
  628. } else {
  629. ret = platform_legacy_resume_early(dev);
  630. }
  631. return ret;
  632. }
  633. #else /* !CONFIG_SUSPEND */
  634. #define platform_pm_suspend NULL
  635. #define platform_pm_resume NULL
  636. #define platform_pm_suspend_noirq NULL
  637. #define platform_pm_resume_noirq NULL
  638. #endif /* !CONFIG_SUSPEND */
  639. #ifdef CONFIG_HIBERNATION
  640. static int platform_pm_freeze(struct device *dev)
  641. {
  642. struct device_driver *drv = dev->driver;
  643. int ret = 0;
  644. if (!drv)
  645. return 0;
  646. if (drv->pm) {
  647. if (drv->pm->freeze)
  648. ret = drv->pm->freeze(dev);
  649. } else {
  650. ret = platform_legacy_suspend(dev, PMSG_FREEZE);
  651. }
  652. return ret;
  653. }
  654. static int platform_pm_freeze_noirq(struct device *dev)
  655. {
  656. struct platform_driver *pdrv;
  657. int ret = 0;
  658. if (!dev->driver)
  659. return 0;
  660. pdrv = to_platform_driver(dev->driver);
  661. if (pdrv->pm) {
  662. if (pdrv->pm->freeze_noirq)
  663. ret = pdrv->pm->freeze_noirq(dev);
  664. } else {
  665. ret = platform_legacy_suspend_late(dev, PMSG_FREEZE);
  666. }
  667. return ret;
  668. }
  669. static int platform_pm_thaw(struct device *dev)
  670. {
  671. struct device_driver *drv = dev->driver;
  672. int ret = 0;
  673. if (drv && drv->pm) {
  674. if (drv->pm->thaw)
  675. ret = drv->pm->thaw(dev);
  676. } else {
  677. ret = platform_legacy_resume(dev);
  678. }
  679. return ret;
  680. }
  681. static int platform_pm_thaw_noirq(struct device *dev)
  682. {
  683. struct platform_driver *pdrv;
  684. int ret = 0;
  685. if (!dev->driver)
  686. return 0;
  687. pdrv = to_platform_driver(dev->driver);
  688. if (pdrv->pm) {
  689. if (pdrv->pm->thaw_noirq)
  690. ret = pdrv->pm->thaw_noirq(dev);
  691. } else {
  692. ret = platform_legacy_resume_early(dev);
  693. }
  694. return ret;
  695. }
  696. static int platform_pm_poweroff(struct device *dev)
  697. {
  698. struct device_driver *drv = dev->driver;
  699. int ret = 0;
  700. if (drv && drv->pm) {
  701. if (drv->pm->poweroff)
  702. ret = drv->pm->poweroff(dev);
  703. } else {
  704. ret = platform_legacy_suspend(dev, PMSG_HIBERNATE);
  705. }
  706. return ret;
  707. }
  708. static int platform_pm_poweroff_noirq(struct device *dev)
  709. {
  710. struct platform_driver *pdrv;
  711. int ret = 0;
  712. if (!dev->driver)
  713. return 0;
  714. pdrv = to_platform_driver(dev->driver);
  715. if (pdrv->pm) {
  716. if (pdrv->pm->poweroff_noirq)
  717. ret = pdrv->pm->poweroff_noirq(dev);
  718. } else {
  719. ret = platform_legacy_suspend_late(dev, PMSG_HIBERNATE);
  720. }
  721. return ret;
  722. }
  723. static int platform_pm_restore(struct device *dev)
  724. {
  725. struct device_driver *drv = dev->driver;
  726. int ret = 0;
  727. if (drv && drv->pm) {
  728. if (drv->pm->restore)
  729. ret = drv->pm->restore(dev);
  730. } else {
  731. ret = platform_legacy_resume(dev);
  732. }
  733. return ret;
  734. }
  735. static int platform_pm_restore_noirq(struct device *dev)
  736. {
  737. struct platform_driver *pdrv;
  738. int ret = 0;
  739. if (!dev->driver)
  740. return 0;
  741. pdrv = to_platform_driver(dev->driver);
  742. if (pdrv->pm) {
  743. if (pdrv->pm->restore_noirq)
  744. ret = pdrv->pm->restore_noirq(dev);
  745. } else {
  746. ret = platform_legacy_resume_early(dev);
  747. }
  748. return ret;
  749. }
  750. #else /* !CONFIG_HIBERNATION */
  751. #define platform_pm_freeze NULL
  752. #define platform_pm_thaw NULL
  753. #define platform_pm_poweroff NULL
  754. #define platform_pm_restore NULL
  755. #define platform_pm_freeze_noirq NULL
  756. #define platform_pm_thaw_noirq NULL
  757. #define platform_pm_poweroff_noirq NULL
  758. #define platform_pm_restore_noirq NULL
  759. #endif /* !CONFIG_HIBERNATION */
  760. static struct pm_ext_ops platform_pm_ops = {
  761. .base = {
  762. .prepare = platform_pm_prepare,
  763. .complete = platform_pm_complete,
  764. .suspend = platform_pm_suspend,
  765. .resume = platform_pm_resume,
  766. .freeze = platform_pm_freeze,
  767. .thaw = platform_pm_thaw,
  768. .poweroff = platform_pm_poweroff,
  769. .restore = platform_pm_restore,
  770. },
  771. .suspend_noirq = platform_pm_suspend_noirq,
  772. .resume_noirq = platform_pm_resume_noirq,
  773. .freeze_noirq = platform_pm_freeze_noirq,
  774. .thaw_noirq = platform_pm_thaw_noirq,
  775. .poweroff_noirq = platform_pm_poweroff_noirq,
  776. .restore_noirq = platform_pm_restore_noirq,
  777. };
  778. #define PLATFORM_PM_OPS_PTR &platform_pm_ops
  779. #else /* !CONFIG_PM_SLEEP */
  780. #define PLATFORM_PM_OPS_PTR NULL
  781. #endif /* !CONFIG_PM_SLEEP */
  782. struct bus_type platform_bus_type = {
  783. .name = "platform",
  784. .dev_attrs = platform_dev_attrs,
  785. .match = platform_match,
  786. .uevent = platform_uevent,
  787. .pm = PLATFORM_PM_OPS_PTR,
  788. };
  789. EXPORT_SYMBOL_GPL(platform_bus_type);
  790. int __init platform_bus_init(void)
  791. {
  792. int error;
  793. error = device_register(&platform_bus);
  794. if (error)
  795. return error;
  796. error = bus_register(&platform_bus_type);
  797. if (error)
  798. device_unregister(&platform_bus);
  799. return error;
  800. }
  801. #ifndef ARCH_HAS_DMA_GET_REQUIRED_MASK
  802. u64 dma_get_required_mask(struct device *dev)
  803. {
  804. u32 low_totalram = ((max_pfn - 1) << PAGE_SHIFT);
  805. u32 high_totalram = ((max_pfn - 1) >> (32 - PAGE_SHIFT));
  806. u64 mask;
  807. if (!high_totalram) {
  808. /* convert to mask just covering totalram */
  809. low_totalram = (1 << (fls(low_totalram) - 1));
  810. low_totalram += low_totalram - 1;
  811. mask = low_totalram;
  812. } else {
  813. high_totalram = (1 << (fls(high_totalram) - 1));
  814. high_totalram += high_totalram - 1;
  815. mask = (((u64)high_totalram) << 32) + 0xffffffff;
  816. }
  817. return mask;
  818. }
  819. EXPORT_SYMBOL_GPL(dma_get_required_mask);
  820. #endif