aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/platform.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/platform.c')
-rw-r--r--drivers/base/platform.c80
1 files changed, 57 insertions, 23 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index c6c933f58102..3966e62ad019 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -192,6 +192,9 @@ int platform_device_add_resources(struct platform_device *pdev,
192{ 192{
193 struct resource *r; 193 struct resource *r;
194 194
195 if (!res)
196 return 0;
197
195 r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL); 198 r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);
196 if (r) { 199 if (r) {
197 pdev->resource = r; 200 pdev->resource = r;
@@ -215,8 +218,12 @@ EXPORT_SYMBOL_GPL(platform_device_add_resources);
215int platform_device_add_data(struct platform_device *pdev, const void *data, 218int platform_device_add_data(struct platform_device *pdev, const void *data,
216 size_t size) 219 size_t size)
217{ 220{
218 void *d = kmemdup(data, size, GFP_KERNEL); 221 void *d;
222
223 if (!data)
224 return 0;
219 225
226 d = kmemdup(data, size, GFP_KERNEL);
220 if (d) { 227 if (d) {
221 pdev->dev.platform_data = d; 228 pdev->dev.platform_data = d;
222 return 0; 229 return 0;
@@ -373,17 +380,13 @@ struct platform_device *__init_or_module platform_device_register_resndata(
373 380
374 pdev->dev.parent = parent; 381 pdev->dev.parent = parent;
375 382
376 if (res) { 383 ret = platform_device_add_resources(pdev, res, num);
377 ret = platform_device_add_resources(pdev, res, num); 384 if (ret)
378 if (ret) 385 goto err;
379 goto err;
380 }
381 386
382 if (data) { 387 ret = platform_device_add_data(pdev, data, size);
383 ret = platform_device_add_data(pdev, data, size); 388 if (ret)
384 if (ret) 389 goto err;
385 goto err;
386 }
387 390
388 ret = platform_device_add(pdev); 391 ret = platform_device_add(pdev);
389 if (ret) { 392 if (ret) {
@@ -488,12 +491,12 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
488 * if the probe was successful, and make sure any forced probes of 491 * if the probe was successful, and make sure any forced probes of
489 * new devices fail. 492 * new devices fail.
490 */ 493 */
491 spin_lock(&platform_bus_type.p->klist_drivers.k_lock); 494 spin_lock(&drv->driver.bus->p->klist_drivers.k_lock);
492 drv->probe = NULL; 495 drv->probe = NULL;
493 if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list)) 496 if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list))
494 retval = -ENODEV; 497 retval = -ENODEV;
495 drv->driver.probe = platform_drv_probe_fail; 498 drv->driver.probe = platform_drv_probe_fail;
496 spin_unlock(&platform_bus_type.p->klist_drivers.k_lock); 499 spin_unlock(&drv->driver.bus->p->klist_drivers.k_lock);
497 500
498 if (code != retval) 501 if (code != retval)
499 platform_driver_unregister(drv); 502 platform_driver_unregister(drv);
@@ -530,17 +533,13 @@ struct platform_device * __init_or_module platform_create_bundle(
530 goto err_out; 533 goto err_out;
531 } 534 }
532 535
533 if (res) { 536 error = platform_device_add_resources(pdev, res, n_res);
534 error = platform_device_add_resources(pdev, res, n_res); 537 if (error)
535 if (error) 538 goto err_pdev_put;
536 goto err_pdev_put;
537 }
538 539
539 if (data) { 540 error = platform_device_add_data(pdev, data, size);
540 error = platform_device_add_data(pdev, data, size); 541 if (error)
541 if (error) 542 goto err_pdev_put;
542 goto err_pdev_put;
543 }
544 543
545 error = platform_device_add(pdev); 544 error = platform_device_add(pdev);
546 if (error) 545 if (error)
@@ -976,6 +975,41 @@ struct bus_type platform_bus_type = {
976}; 975};
977EXPORT_SYMBOL_GPL(platform_bus_type); 976EXPORT_SYMBOL_GPL(platform_bus_type);
978 977
978/**
979 * platform_bus_get_pm_ops() - return pointer to busses dev_pm_ops
980 *
981 * This function can be used by platform code to get the current
982 * set of dev_pm_ops functions used by the platform_bus_type.
983 */
984const struct dev_pm_ops * __init platform_bus_get_pm_ops(void)
985{
986 return platform_bus_type.pm;
987}
988
989/**
990 * platform_bus_set_pm_ops() - update dev_pm_ops for the platform_bus_type
991 *
992 * @pm: pointer to new dev_pm_ops struct to be used for platform_bus_type
993 *
994 * Platform code can override the dev_pm_ops methods of
995 * platform_bus_type by using this function. It is expected that
996 * platform code will first do a platform_bus_get_pm_ops(), then
997 * kmemdup it, then customize selected methods and pass a pointer to
998 * the new struct dev_pm_ops to this function.
999 *
1000 * Since platform-specific code is customizing methods for *all*
1001 * devices (not just platform-specific devices) it is expected that
1002 * any custom overrides of these functions will keep existing behavior
1003 * and simply extend it. For example, any customization of the
1004 * runtime PM methods should continue to call the pm_generic_*
1005 * functions as the default ones do in addition to the
1006 * platform-specific behavior.
1007 */
1008void __init platform_bus_set_pm_ops(const struct dev_pm_ops *pm)
1009{
1010 platform_bus_type.pm = pm;
1011}
1012
979int __init platform_bus_init(void) 1013int __init platform_bus_init(void)
980{ 1014{
981 int error; 1015 int error;