summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2005-11-09 18:23:39 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-11-09 18:23:39 +0100
commit00d3dcdd96646be6059cc21f2efa94c4edc1eda5 (patch)
tree0e45a3e4cb62bbd45e6a9a117a78bd911f346dbe
parent[PATCH] Fix sysctl unregistration oops (CVE-2005-2709) (diff)
downloadlinux-00d3dcdd96646be6059cc21f2efa94c4edc1eda5.tar.xz
linux-00d3dcdd96646be6059cc21f2efa94c4edc1eda5.zip
[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.c73
-rw-r--r--include/linux/platform_device.h15
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 @@
#include "base.h"
+#define to_platform_driver(drv) (container_of((drv), struct platform_driver, driver))
+
struct device platform_bus = {
.bus_id = "platform",
};
@@ -354,6 +356,77 @@ error:
return ERR_PTR(retval);
}
+static int platform_drv_probe(struct device *_dev)
+{
+ struct platform_driver *drv = to_platform_driver(_dev->driver);
+ struct platform_device *dev = to_platform_device(_dev);
+
+ return drv->probe(dev);
+}
+
+static int platform_drv_remove(struct device *_dev)
+{
+ struct platform_driver *drv = to_platform_driver(_dev->driver);
+ struct platform_device *dev = to_platform_device(_dev);
+
+ return drv->remove(dev);
+}
+
+static void platform_drv_shutdown(struct device *_dev)
+{
+ struct platform_driver *drv = to_platform_driver(_dev->driver);
+ struct platform_device *dev = to_platform_device(_dev);
+
+ drv->shutdown(dev);
+}
+
+static int platform_drv_suspend(struct device *_dev, pm_message_t state)
+{
+ struct platform_driver *drv = to_platform_driver(_dev->driver);
+ struct platform_device *dev = to_platform_device(_dev);
+
+ return drv->suspend(dev, state);
+}
+
+static int platform_drv_resume(struct device *_dev)
+{
+ struct platform_driver *drv = to_platform_driver(_dev->driver);
+ struct platform_device *dev = to_platform_device(_dev);
+
+ return drv->resume(dev);
+}
+
+/**
+ * platform_driver_register
+ * @drv: platform driver structure
+ */
+int platform_driver_register(struct platform_driver *drv)
+{
+ drv->driver.bus = &platform_bus_type;
+ if (drv->probe)
+ drv->driver.probe = platform_drv_probe;
+ if (drv->remove)
+ drv->driver.remove = platform_drv_remove;
+ if (drv->shutdown)
+ drv->driver.shutdown = platform_drv_shutdown;
+ if (drv->suspend)
+ drv->driver.suspend = platform_drv_suspend;
+ if (drv->resume)
+ drv->driver.resume = platform_drv_resume;
+ return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(platform_driver_register);
+
+/**
+ * platform_driver_unregister
+ * @drv: platform driver structure
+ */
+void platform_driver_unregister(struct platform_driver *drv)
+{
+ driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(platform_driver_unregister);
+
/**
* 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
extern int platform_device_add(struct platform_device *pdev);
extern void platform_device_put(struct platform_device *pdev);
+struct platform_driver {
+ int (*probe)(struct platform_device *);
+ int (*remove)(struct platform_device *);
+ void (*shutdown)(struct platform_device *);
+ int (*suspend)(struct platform_device *, pm_message_t state);
+ int (*resume)(struct platform_device *);
+ struct device_driver driver;
+};
+
+extern int platform_driver_register(struct platform_driver *);
+extern void platform_driver_unregister(struct platform_driver *);
+
+#define platform_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev)
+#define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data))
+
#endif /* _PLATFORM_DEVICE_H_ */