Commit 00d3dcdd96646be6059cc21f2efa94c4edc1eda5
Committed by
Russell King
1 parent
330d57fb98
Exists in
master
and in
20 other branches
[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_ */ |