diff options
Diffstat (limited to 'drivers/base/platform.c')
| -rw-r--r-- | drivers/base/platform.c | 80 |
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); | |||
| 215 | int platform_device_add_data(struct platform_device *pdev, const void *data, | 218 | int 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 | }; |
| 977 | EXPORT_SYMBOL_GPL(platform_bus_type); | 976 | EXPORT_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 | */ | ||
| 984 | const 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 | */ | ||
| 1008 | void __init platform_bus_set_pm_ops(const struct dev_pm_ops *pm) | ||
| 1009 | { | ||
| 1010 | platform_bus_type.pm = pm; | ||
| 1011 | } | ||
| 1012 | |||
| 979 | int __init platform_bus_init(void) | 1013 | int __init platform_bus_init(void) |
| 980 | { | 1014 | { |
| 981 | int error; | 1015 | int error; |
