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 940ce41f18..d1df4a0879 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 29cd6dee13..20f47b81d3 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 | ||