Commit 00d3dcdd96646be6059cc21f2efa94c4edc1eda5

Authored by Russell King
Committed by Russell King
1 parent 330d57fb98

[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>

Showing 2 changed files with 88 additions and 0 deletions Side-by-side Diff

drivers/base/platform.c
... ... @@ -20,6 +20,8 @@
20 20  
21 21 #include "base.h"
22 22  
  23 +#define to_platform_driver(drv) (container_of((drv), struct platform_driver, driver))
  24 +
23 25 struct device platform_bus = {
24 26 .bus_id = "platform",
25 27 };
... ... @@ -353,6 +355,77 @@
353 355 platform_device_put(pdev);
354 356 return ERR_PTR(retval);
355 357 }
  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);
356 429  
357 430  
358 431 /**
include/linux/platform_device.h
... ... @@ -43,5 +43,20 @@
43 43 extern int platform_device_add(struct platform_device *pdev);
44 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 61 #endif /* _PLATFORM_DEVICE_H_ */