diff options
| author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2005-11-09 12:23:39 -0500 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-11-09 12:23:39 -0500 |
| commit | 00d3dcdd96646be6059cc21f2efa94c4edc1eda5 (patch) | |
| tree | 0e45a3e4cb62bbd45e6a9a117a78bd911f346dbe | |
| parent | 330d57fb98a916fa8e1363846540dd420e99499a (diff) | |
[DRIVER MODEL] Add platform_driver
Introduce struct platform_driver. This allows the platform device
driver methods to be passed a platform_device structure instead of
instead of a plain device structure, and therefore requiring casting
in every platform driver.
We introduce this in such a way that any existing platform drivers
registered directly via driver_register continue to work as before,
thereby allowing a gradual conversion to the new platform_driver
methods.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
| -rw-r--r-- | drivers/base/platform.c | 73 | ||||
| -rw-r--r-- | include/linux/platform_device.h | 15 |
2 files changed, 88 insertions, 0 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 6d4736e89f1a..8827dafba945 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
| @@ -20,6 +20,8 @@ | |||
| 20 | 20 | ||
| 21 | #include "base.h" | 21 | #include "base.h" |
| 22 | 22 | ||
| 23 | #define to_platform_driver(drv) (container_of((drv), struct platform_driver, driver)) | ||
| 24 | |||
| 23 | struct device platform_bus = { | 25 | struct device platform_bus = { |
| 24 | .bus_id = "platform", | 26 | .bus_id = "platform", |
| 25 | }; | 27 | }; |
| @@ -354,6 +356,77 @@ error: | |||
| 354 | return ERR_PTR(retval); | 356 | return ERR_PTR(retval); |
| 355 | } | 357 | } |
| 356 | 358 | ||
| 359 | static int platform_drv_probe(struct device *_dev) | ||
| 360 | { | ||
| 361 | struct platform_driver *drv = to_platform_driver(_dev->driver); | ||
| 362 | struct platform_device *dev = to_platform_device(_dev); | ||
| 363 | |||
| 364 | return drv->probe(dev); | ||
| 365 | } | ||
| 366 | |||
| 367 | static int platform_drv_remove(struct device *_dev) | ||
| 368 | { | ||
| 369 | struct platform_driver *drv = to_platform_driver(_dev->driver); | ||
| 370 | struct platform_device *dev = to_platform_device(_dev); | ||
| 371 | |||
| 372 | return drv->remove(dev); | ||
| 373 | } | ||
| 374 | |||
| 375 | static void platform_drv_shutdown(struct device *_dev) | ||
| 376 | { | ||
| 377 | struct platform_driver *drv = to_platform_driver(_dev->driver); | ||
| 378 | struct platform_device *dev = to_platform_device(_dev); | ||
| 379 | |||
| 380 | drv->shutdown(dev); | ||
| 381 | } | ||
| 382 | |||
| 383 | static int platform_drv_suspend(struct device *_dev, pm_message_t state) | ||
| 384 | { | ||
| 385 | struct platform_driver *drv = to_platform_driver(_dev->driver); | ||
| 386 | struct platform_device *dev = to_platform_device(_dev); | ||
| 387 | |||
| 388 | return drv->suspend(dev, state); | ||
| 389 | } | ||
| 390 | |||
| 391 | static int platform_drv_resume(struct device *_dev) | ||
| 392 | { | ||
| 393 | struct platform_driver *drv = to_platform_driver(_dev->driver); | ||
| 394 | struct platform_device *dev = to_platform_device(_dev); | ||
| 395 | |||
| 396 | return drv->resume(dev); | ||
| 397 | } | ||
| 398 | |||
| 399 | /** | ||
| 400 | * platform_driver_register | ||
| 401 | * @drv: platform driver structure | ||
| 402 | */ | ||
| 403 | int platform_driver_register(struct platform_driver *drv) | ||
| 404 | { | ||
| 405 | drv->driver.bus = &platform_bus_type; | ||
| 406 | if (drv->probe) | ||
| 407 | drv->driver.probe = platform_drv_probe; | ||
| 408 | if (drv->remove) | ||
| 409 | drv->driver.remove = platform_drv_remove; | ||
| 410 | if (drv->shutdown) | ||
| 411 | drv->driver.shutdown = platform_drv_shutdown; | ||
| 412 | if (drv->suspend) | ||
| 413 | drv->driver.suspend = platform_drv_suspend; | ||
| 414 | if (drv->resume) | ||
| 415 | drv->driver.resume = platform_drv_resume; | ||
| 416 | return driver_register(&drv->driver); | ||
| 417 | } | ||
| 418 | EXPORT_SYMBOL_GPL(platform_driver_register); | ||
| 419 | |||
| 420 | /** | ||
| 421 | * platform_driver_unregister | ||
| 422 | * @drv: platform driver structure | ||
| 423 | */ | ||
| 424 | void platform_driver_unregister(struct platform_driver *drv) | ||
| 425 | { | ||
| 426 | driver_unregister(&drv->driver); | ||
| 427 | } | ||
| 428 | EXPORT_SYMBOL_GPL(platform_driver_unregister); | ||
| 429 | |||
| 357 | 430 | ||
| 358 | /** | 431 | /** |
| 359 | * platform_match - bind platform device to platform driver. | 432 | * platform_match - bind platform device to platform driver. |
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 1a165b7ae01b..17e336f40b47 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h | |||
| @@ -43,4 +43,19 @@ extern int platform_device_add_data(struct platform_device *pdev, void *data, si | |||
| 43 | extern int platform_device_add(struct platform_device *pdev); | 43 | extern int platform_device_add(struct platform_device *pdev); |
| 44 | extern void platform_device_put(struct platform_device *pdev); | 44 | extern void platform_device_put(struct platform_device *pdev); |
| 45 | 45 | ||
| 46 | struct platform_driver { | ||
| 47 | int (*probe)(struct platform_device *); | ||
| 48 | int (*remove)(struct platform_device *); | ||
| 49 | void (*shutdown)(struct platform_device *); | ||
| 50 | int (*suspend)(struct platform_device *, pm_message_t state); | ||
| 51 | int (*resume)(struct platform_device *); | ||
| 52 | struct device_driver driver; | ||
| 53 | }; | ||
| 54 | |||
| 55 | extern int platform_driver_register(struct platform_driver *); | ||
| 56 | extern void platform_driver_unregister(struct platform_driver *); | ||
| 57 | |||
| 58 | #define platform_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev) | ||
| 59 | #define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data)) | ||
| 60 | |||
| 46 | #endif /* _PLATFORM_DEVICE_H_ */ | 61 | #endif /* _PLATFORM_DEVICE_H_ */ |
