aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorZhang Rui <rui.zhang@intel.com>2014-01-14 03:46:36 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-01-16 17:10:40 -0500
commit6eb2451f7c43c4a7f84ae7b613ea975317b951f1 (patch)
tree7ff8db97b03fa018bd4d7628186e35523a82ac04 /drivers/acpi
parent3d8e00909df96c2d3eace3996748be9c0a437e5a (diff)
ACPI: add module autoloading support for ACPI enumerated devices
An ACPI enumerated device may have its compatible id strings. To support the compatible ACPI ids (acpi_device->pnp.ids), we introduced acpi_driver_match_device() to match the driver->acpi_match_table and acpi_device->pnp.ids. For those drivers, MODULE_DEVICE_TABLE(acpi, xxx) is used to exports the driver module alias in the format of "acpi:device_compatible_ids". But in the mean time, the current code does not export the ACPI compatible strings as part of the module_alias for the ACPI enumerated devices, which will break the module autoloading. Take the following piece of code for example, static const struct acpi_device_id xxx_acpi_match[] = { { "INTABCD", 0 }, { } }; MODULE_DEVICE_TABLE(acpi, xxx_acpi_match); If this piece of code is used in a platform driver for an ACPI enumerated platform device, the platform driver module_alias is "acpi:INTABCD", but the uevent attribute of its platform device node is "platform:INTABCD:00" (PREFIX:platform_device->name). If this piece of code is used in an i2c driver for an ACPI enumerated i2c device, the i2c driver module_alias is "acpi:INTABCD", but the uevent of its i2c device node is "i2c:INTABCD:00" (PREFIX:i2c_client->name). If this piece of code is used in an spi driver for an ACPI enumerated spi device, the spi driver module_alias is "acpi:INTABCD", but the uevent of its spi device node is "spi:INTABCD" (PREFIX:spi_device->modalias). The reason why the module autoloading is not broken for now is that the uevent file of the ACPI device node is "acpi:INTABCD". Thus it is the ACPI device node creation that loads the platform/i2c/spi driver. So this is a problem that will affect us the day when the ACPI bus is removed from device model. This patch introduces two new APIs, one for exporting ACPI ids in uevent MODALIAS field, and another for exporting ACPI ids in device' modalias sysfs attribute. For any bus that supports ACPI enumerated devices, it needs to invoke these two functions for their uevent and modalias attribute. Signed-off-by: Zhang Rui <rui.zhang@intel.com> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/scan.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index c92532158195..680bb5647701 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -116,6 +116,63 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
116 return len; 116 return len;
117} 117}
118 118
119/*
120 * Creates uevent modalias field for ACPI enumerated devices.
121 * Because the other buses does not support ACPI HIDs & CIDs.
122 * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get:
123 * "acpi:IBM0001:ACPI0001"
124 */
125int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
126{
127 struct acpi_device *acpi_dev;
128 int len;
129
130 acpi_dev = ACPI_COMPANION(dev);
131 if (!acpi_dev)
132 return -ENODEV;
133
134 /* Fall back to bus specific way of modalias exporting */
135 if (list_empty(&acpi_dev->pnp.ids))
136 return -ENODEV;
137
138 if (add_uevent_var(env, "MODALIAS="))
139 return -ENOMEM;
140 len = create_modalias(acpi_dev, &env->buf[env->buflen - 1],
141 sizeof(env->buf) - env->buflen);
142 if (len <= 0)
143 return len;
144 env->buflen += len;
145 return 0;
146}
147EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias);
148
149/*
150 * Creates modalias sysfs attribute for ACPI enumerated devices.
151 * Because the other buses does not support ACPI HIDs & CIDs.
152 * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get:
153 * "acpi:IBM0001:ACPI0001"
154 */
155int acpi_device_modalias(struct device *dev, char *buf, int size)
156{
157 struct acpi_device *acpi_dev;
158 int len;
159
160 acpi_dev = ACPI_COMPANION(dev);
161 if (!acpi_dev)
162 return -ENODEV;
163
164 /* Fall back to bus specific way of modalias exporting */
165 if (list_empty(&acpi_dev->pnp.ids))
166 return -ENODEV;
167
168 len = create_modalias(acpi_dev, buf, size -1);
169 if (len <= 0)
170 return len;
171 buf[len++] = '\n';
172 return len;
173}
174EXPORT_SYMBOL_GPL(acpi_device_modalias);
175
119static ssize_t 176static ssize_t
120acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { 177acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) {
121 struct acpi_device *acpi_dev = to_acpi_device(dev); 178 struct acpi_device *acpi_dev = to_acpi_device(dev);