[PATCH 34/36] Driver core: platform_driver_probe(), can save codespace
- From: Greg KH <greg@xxxxxxxxx>
- Date: Fri, 1 Dec 2006 15:22:04 -0800
From: David Brownell <david-b@xxxxxxxxxxx>
This defines a new platform_driver_probe() method allowing the driver's
probe() method, and its support code+data, to safely live in __init
sections for typical system configurations.
Many system-on-chip processors could benefit from this API, to the tune
of recovering hundreds to thousands of bytes per driver. That's memory
which is currently wasted holding code which can never be called after
system startup, yet can not be removed. It can't be removed because of
the linkage requirement that pointers to init section code (like, ideally,
probe support) must not live in other sections (like driver method tables)
after those pointers would be invalid.
Signed-off-by: David Brownell <dbrownell@xxxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>
---
drivers/base/platform.c | 48 +++++++++++++++++++++++++++++++++++++++
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 940ce41..d1df4a0 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -388,6 +388,11 @@ static int platform_drv_probe(struct dev
return drv->probe(dev);
}
+static int platform_drv_probe_fail(struct device *_dev)
+{
+ return -ENXIO;
+}
+
static int platform_drv_remove(struct device *_dev)
{
struct platform_driver *drv = to_platform_driver(_dev->driver);
@@ -451,6 +456,49 @@ void platform_driver_unregister(struct p
}
EXPORT_SYMBOL_GPL(platform_driver_unregister);
+/**
+ * platform_driver_probe - register driver for non-hotpluggable device
+ * @drv: platform driver structure
+ * @probe: the driver probe routine, probably from an __init section
+ *
+ * Use this instead of platform_driver_register() when you know the device
+ * is not hotpluggable and has already been registered, and you want to
+ * remove its run-once probe() infrastructure from memory after the driver
+ * has bound to the device.
+ *
+ * One typical use for this would be with drivers for controllers integrated
+ * into system-on-chip processors, where the controller devices have been
+ * configured as part of board setup.
+ *
+ * Returns zero if the driver registered and bound to a device, else returns
+ * a negative error code and with the driver not registered.
+ */
+int platform_driver_probe(struct platform_driver *drv,
+ int (*probe)(struct platform_device *))
+{
+ int retval, code;
+
+ /* temporary section violation during probe() */
+ drv->probe = probe;
+ retval = code = platform_driver_register(drv);
+
+ /* Fixup that section violation, being paranoid about code scanning
+ * the list of drivers in order to probe new devices. Check to see
+ * if the probe was successful, and make sure any forced probes of
+ * new devices fail.
+ */
+ spin_lock(&platform_bus_type.klist_drivers.k_lock);
+ drv->probe = NULL;
+ if (code == 0 && list_empty(&drv->driver.klist_devices.k_list))
+ retval = -ENODEV;
+ drv->driver.probe = platform_drv_probe_fail;
+ spin_unlock(&platform_bus_type.klist_drivers.k_lock);
+
+ if (code != retval)
+ platform_driver_unregister(drv);
+ return retval;
+}
+EXPORT_SYMBOL_GPL(platform_driver_probe);
/* modalias support enables more hands-off userspace setup:
* (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 29cd6de..20f47b8 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -58,6 +58,12 @@ struct platform_driver {
extern int platform_driver_register(struct platform_driver *);
extern void platform_driver_unregister(struct platform_driver *);
+/* non-hotpluggable platform devices may use this so that probe() and
+ * its support may live in __init sections, conserving runtime memory.
+ */
+extern int platform_driver_probe(struct platform_driver *driver,
+ int (*probe)(struct platform_device *));
+
#define platform_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev)
#define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data))
--
1.4.4.1
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
- Follow-Ups:
- References:
- [GIT PATCH] Driver core patches for 2.6.19
- From: Greg KH
- [PATCH 1/36] Driver core: add notification of bus events
- From: Greg KH
- [PATCH 2/36] Driver core: fix "driver" symlink timing
- From: Greg KH
- [PATCH 3/36] Driver Core: Move virtual_device_parent() to core.c
- From: Greg KH
- [PATCH 4/36] CONFIG_SYSFS_DEPRECATED
- From: Greg KH
- [PATCH 5/36] Driver core: make old versions of udev work properly
- From: Greg KH
- [PATCH 6/36] CONFIG_SYSFS_DEPRECATED - bus symlinks
- From: Greg KH
- [PATCH 7/36] CONFIG_SYSFS_DEPRECATED - device symlinks
- From: Greg KH
- [PATCH 8/36] CONFIG_SYSFS_DEPRECATED - PHYSDEV* uevent variables
- From: Greg KH
- [PATCH 9/36] CONFIG_SYSFS_DEPRECATED - class symlinks
- From: Greg KH
- [PATCH 10/36] Driver core: convert vt code to use struct device
- From: Greg KH
- [PATCH 11/36] Driver core: convert vc code to use struct device
- From: Greg KH
- [PATCH 12/36] Driver core: change misc class_devices to be real devices
- From: Greg KH
- [PATCH 13/36] Driver core: convert tty core to use struct device
- From: Greg KH
- [PATCH 14/36] Driver core: convert raw device code to use struct device
- From: Greg KH
- [PATCH 15/36] I2C: convert i2c-dev to use struct device instead of struct class_device
- From: Greg KH
- [PATCH 16/36] Driver core: convert msr code to use struct device
- From: Greg KH
- [PATCH 17/36] Driver core: convert cpuid code to use struct device
- From: Greg KH
- [PATCH 18/36] Driver core: convert PPP code to use struct device
- From: Greg KH
- [PATCH 19/36] Driver core: convert ppdev code to use struct device
- From: Greg KH
- [PATCH 20/36] Driver core: convert mmc code to use struct device
- From: Greg KH
- [PATCH 22/36] Driver core: convert fb code to use struct device
- From: Greg KH
- [PATCH 23/36] Driver core: change mem class_devices to be real devices
- From: Greg KH
- [PATCH 24/36] Driver core: convert sound core to use struct device
- From: Greg KH
- [PATCH 25/36] Driver core: add dev_archdata to struct device
- From: Greg KH
- [PATCH 26/36] ACPI: Change ACPI to use dev_archdata instead of firmware_data
- From: Greg KH
- [PATCH 27/36] Driver core: Call platform_notify_remove later
- From: Greg KH
- [PATCH 28/36] cpu topology: consider sysfs_create_group return value
- From: Greg KH
- [PATCH 29/36] sysfs: sysfs_write_file() writes zero terminated data
- From: Greg KH
- [PATCH 30/36] driver core: Introduce device_find_child().
- From: Greg KH
- [PATCH 31/36] Driver core: make drivers/base/core.c:setup_parent() static
- From: Greg KH
- [PATCH 32/36] driver core: Introduce device_move(): move a device to a new parent.
- From: Greg KH
- [PATCH 33/36] driver core: Use klist_remove() in device_move()
- From: Greg KH
- [GIT PATCH] Driver core patches for 2.6.19
- Prev by Date: [PATCH 32/36] driver core: Introduce device_move(): move a device to a new parent.
- Next by Date: [PATCH 18/36] Driver core: convert PPP code to use struct device
- Previous by thread: [PATCH 33/36] driver core: Use klist_remove() in device_move()
- Next by thread: [PATCH 35/36] Documentation/driver-model/platform.txt update/rewrite
- Index(es):
Relevant Pages
|