diff options
| -rw-r--r-- | drivers/base/platform.c | 48 | ||||
| -rw-r--r-- | include/linux/platform_device.h | 6 |
2 files changed, 54 insertions, 0 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 940ce41f1887..d1df4a087924 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
| @@ -388,6 +388,11 @@ static int platform_drv_probe(struct device *_dev) | |||
| 388 | return drv->probe(dev); | 388 | return drv->probe(dev); |
| 389 | } | 389 | } |
| 390 | 390 | ||
| 391 | static int platform_drv_probe_fail(struct device *_dev) | ||
| 392 | { | ||
| 393 | return -ENXIO; | ||
| 394 | } | ||
| 395 | |||
| 391 | static int platform_drv_remove(struct device *_dev) | 396 | static int platform_drv_remove(struct device *_dev) |
| 392 | { | 397 | { |
| 393 | struct platform_driver *drv = to_platform_driver(_dev->driver); | 398 | struct platform_driver *drv = to_platform_driver(_dev->driver); |
| @@ -451,6 +456,49 @@ void platform_driver_unregister(struct platform_driver *drv) | |||
| 451 | } | 456 | } |
| 452 | EXPORT_SYMBOL_GPL(platform_driver_unregister); | 457 | EXPORT_SYMBOL_GPL(platform_driver_unregister); |
| 453 | 458 | ||
| 459 | /** | ||
| 460 | * platform_driver_probe - register driver for non-hotpluggable device | ||
| 461 | * @drv: platform driver structure | ||
| 462 | * @probe: the driver probe routine, probably from an __init section | ||
| 463 | * | ||
| 464 | * Use this instead of platform_driver_register() when you know the device | ||
| 465 | * is not hotpluggable and has already been registered, and you want to | ||
| 466 | * remove its run-once probe() infrastructure from memory after the driver | ||
| 467 | * has bound to the device. | ||
| 468 | * | ||
| 469 | * One typical use for this would be with drivers for controllers integrated | ||
| 470 | * into system-on-chip processors, where the controller devices have been | ||
| 471 | * configured as part of board setup. | ||
| 472 | * | ||
| 473 | * Returns zero if the driver registered and bound to a device, else returns | ||
| 474 | * a negative error code and with the driver not registered. | ||
| 475 | */ | ||
| 476 | int platform_driver_probe(struct platform_driver *drv, | ||
| 477 | int (*probe)(struct platform_device *)) | ||
| 478 | { | ||
| 479 | int retval, code; | ||
| 480 | |||
| 481 | /* temporary section violation during probe() */ | ||
| 482 | drv->probe = probe; | ||
| 483 | retval = code = platform_driver_register(drv); | ||
| 484 | |||
| 485 | /* Fixup that section violation, being paranoid about code scanning | ||
| 486 | * the list of drivers in order to probe new devices. Check to see | ||
| 487 | * if the probe was successful, and make sure any forced probes of | ||
| 488 | * new devices fail. | ||
| 489 | */ | ||
| 490 | spin_lock(&platform_bus_type.klist_drivers.k_lock); | ||
| 491 | drv->probe = NULL; | ||
| 492 | if (code == 0 && list_empty(&drv->driver.klist_devices.k_list)) | ||
| 493 | retval = -ENODEV; | ||
| 494 | drv->driver.probe = platform_drv_probe_fail; | ||
| 495 | spin_unlock(&platform_bus_type.klist_drivers.k_lock); | ||
| 496 | |||
| 497 | if (code != retval) | ||
| 498 | platform_driver_unregister(drv); | ||
| 499 | return retval; | ||
| 500 | } | ||
| 501 | EXPORT_SYMBOL_GPL(platform_driver_probe); | ||
| 454 | 502 | ||
| 455 | /* modalias support enables more hands-off userspace setup: | 503 | /* modalias support enables more hands-off userspace setup: |
| 456 | * (a) environment variable lets new-style hotplug events work once system is | 504 | * (a) environment variable lets new-style hotplug events work once system is |
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 29cd6dee13db..20f47b81d3fa 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h | |||
| @@ -58,6 +58,12 @@ struct platform_driver { | |||
| 58 | extern int platform_driver_register(struct platform_driver *); | 58 | extern int platform_driver_register(struct platform_driver *); |
| 59 | extern void platform_driver_unregister(struct platform_driver *); | 59 | extern void platform_driver_unregister(struct platform_driver *); |
| 60 | 60 | ||
| 61 | /* non-hotpluggable platform devices may use this so that probe() and | ||
| 62 | * its support may live in __init sections, conserving runtime memory. | ||
| 63 | */ | ||
| 64 | extern int platform_driver_probe(struct platform_driver *driver, | ||
| 65 | int (*probe)(struct platform_device *)); | ||
| 66 | |||
| 61 | #define platform_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev) | 67 | #define platform_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev) |
| 62 | #define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data)) | 68 | #define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data)) |
| 63 | 69 | ||
