diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-01-16 19:59:38 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-01-16 19:59:38 -0500 |
commit | bc411b8a643825b634916f9ba167546a88a0ac28 (patch) | |
tree | 9243b5c8139391e003e31bea845a59975aeced3e /drivers | |
parent | 8341ecc9f4eb7513951bd1986d78185a11ac6d4e (diff) | |
parent | b9f73067f32531db608e469a9ad20ce631e34550 (diff) |
Merge branch 'acpi-modules'
* acpi-modules:
platform: introduce OF style 'modalias' support for platform bus
ACPI: fix module autoloading for ACPI enumerated devices
ACPI: add module autoloading support for ACPI enumerated devices
ACPI: fix create_modalias() return value handling
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/scan.c | 73 | ||||
-rw-r--r-- | drivers/base/platform.c | 16 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.c | 11 | ||||
-rw-r--r-- | drivers/of/device.c | 3 | ||||
-rw-r--r-- | drivers/spi/spi.c | 10 |
5 files changed, 106 insertions, 7 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index c0f57ff15024..e00365ccb897 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -86,6 +86,9 @@ int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler, | |||
86 | * Creates hid/cid(s) string needed for modalias and uevent | 86 | * Creates hid/cid(s) string needed for modalias and uevent |
87 | * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: | 87 | * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: |
88 | * char *modalias: "acpi:IBM0001:ACPI0001" | 88 | * char *modalias: "acpi:IBM0001:ACPI0001" |
89 | * Return: 0: no _HID and no _CID | ||
90 | * -EINVAL: output error | ||
91 | * -ENOMEM: output is truncated | ||
89 | */ | 92 | */ |
90 | static int create_modalias(struct acpi_device *acpi_dev, char *modalias, | 93 | static int create_modalias(struct acpi_device *acpi_dev, char *modalias, |
91 | int size) | 94 | int size) |
@@ -102,8 +105,10 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, | |||
102 | 105 | ||
103 | list_for_each_entry(id, &acpi_dev->pnp.ids, list) { | 106 | list_for_each_entry(id, &acpi_dev->pnp.ids, list) { |
104 | count = snprintf(&modalias[len], size, "%s:", id->id); | 107 | count = snprintf(&modalias[len], size, "%s:", id->id); |
105 | if (count < 0 || count >= size) | 108 | if (count < 0) |
106 | return -EINVAL; | 109 | return EINVAL; |
110 | if (count >= size) | ||
111 | return -ENOMEM; | ||
107 | len += count; | 112 | len += count; |
108 | size -= count; | 113 | size -= count; |
109 | } | 114 | } |
@@ -112,15 +117,71 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, | |||
112 | return len; | 117 | return len; |
113 | } | 118 | } |
114 | 119 | ||
120 | /* | ||
121 | * Creates uevent modalias field for ACPI enumerated devices. | ||
122 | * Because the other buses does not support ACPI HIDs & CIDs. | ||
123 | * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get: | ||
124 | * "acpi:IBM0001:ACPI0001" | ||
125 | */ | ||
126 | int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) | ||
127 | { | ||
128 | struct acpi_device *acpi_dev; | ||
129 | int len; | ||
130 | |||
131 | acpi_dev = ACPI_COMPANION(dev); | ||
132 | if (!acpi_dev) | ||
133 | return -ENODEV; | ||
134 | |||
135 | /* Fall back to bus specific way of modalias exporting */ | ||
136 | if (list_empty(&acpi_dev->pnp.ids)) | ||
137 | return -ENODEV; | ||
138 | |||
139 | if (add_uevent_var(env, "MODALIAS=")) | ||
140 | return -ENOMEM; | ||
141 | len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], | ||
142 | sizeof(env->buf) - env->buflen); | ||
143 | if (len <= 0) | ||
144 | return len; | ||
145 | env->buflen += len; | ||
146 | return 0; | ||
147 | } | ||
148 | EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias); | ||
149 | |||
150 | /* | ||
151 | * Creates modalias sysfs attribute for ACPI enumerated devices. | ||
152 | * Because the other buses does not support ACPI HIDs & CIDs. | ||
153 | * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get: | ||
154 | * "acpi:IBM0001:ACPI0001" | ||
155 | */ | ||
156 | int acpi_device_modalias(struct device *dev, char *buf, int size) | ||
157 | { | ||
158 | struct acpi_device *acpi_dev; | ||
159 | int len; | ||
160 | |||
161 | acpi_dev = ACPI_COMPANION(dev); | ||
162 | if (!acpi_dev) | ||
163 | return -ENODEV; | ||
164 | |||
165 | /* Fall back to bus specific way of modalias exporting */ | ||
166 | if (list_empty(&acpi_dev->pnp.ids)) | ||
167 | return -ENODEV; | ||
168 | |||
169 | len = create_modalias(acpi_dev, buf, size -1); | ||
170 | if (len <= 0) | ||
171 | return len; | ||
172 | buf[len++] = '\n'; | ||
173 | return len; | ||
174 | } | ||
175 | EXPORT_SYMBOL_GPL(acpi_device_modalias); | ||
176 | |||
115 | static ssize_t | 177 | static ssize_t |
116 | acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { | 178 | acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { |
117 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 179 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
118 | int len; | 180 | int len; |
119 | 181 | ||
120 | /* Device has no HID and no CID or string is >1024 */ | ||
121 | len = create_modalias(acpi_dev, buf, 1024); | 182 | len = create_modalias(acpi_dev, buf, 1024); |
122 | if (len <= 0) | 183 | if (len <= 0) |
123 | return 0; | 184 | return len; |
124 | buf[len++] = '\n'; | 185 | buf[len++] = '\n'; |
125 | return len; | 186 | return len; |
126 | } | 187 | } |
@@ -839,8 +900,8 @@ static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
839 | return -ENOMEM; | 900 | return -ENOMEM; |
840 | len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], | 901 | len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], |
841 | sizeof(env->buf) - env->buflen); | 902 | sizeof(env->buf) - env->buflen); |
842 | if (len >= (sizeof(env->buf) - env->buflen)) | 903 | if (len <= 0) |
843 | return -ENOMEM; | 904 | return len; |
844 | env->buflen += len; | 905 | env->buflen += len; |
845 | return 0; | 906 | return 0; |
846 | } | 907 | } |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 3a94b799f166..bc78848dd59a 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -677,7 +677,17 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a, | |||
677 | char *buf) | 677 | char *buf) |
678 | { | 678 | { |
679 | struct platform_device *pdev = to_platform_device(dev); | 679 | struct platform_device *pdev = to_platform_device(dev); |
680 | int len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name); | 680 | int len; |
681 | |||
682 | len = of_device_get_modalias(dev, buf, PAGE_SIZE -1); | ||
683 | if (len != -ENODEV) | ||
684 | return len; | ||
685 | |||
686 | len = acpi_device_modalias(dev, buf, PAGE_SIZE -1); | ||
687 | if (len != -ENODEV) | ||
688 | return len; | ||
689 | |||
690 | len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name); | ||
681 | 691 | ||
682 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; | 692 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; |
683 | } | 693 | } |
@@ -699,6 +709,10 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
699 | if (rc != -ENODEV) | 709 | if (rc != -ENODEV) |
700 | return rc; | 710 | return rc; |
701 | 711 | ||
712 | rc = acpi_device_uevent_modalias(dev, env); | ||
713 | if (rc != -ENODEV) | ||
714 | return rc; | ||
715 | |||
702 | add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, | 716 | add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, |
703 | pdev->name); | 717 | pdev->name); |
704 | return 0; | 718 | return 0; |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index d74c0b34248e..c4c5588ec0fb 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -104,6 +104,11 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv) | |||
104 | static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env) | 104 | static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env) |
105 | { | 105 | { |
106 | struct i2c_client *client = to_i2c_client(dev); | 106 | struct i2c_client *client = to_i2c_client(dev); |
107 | int rc; | ||
108 | |||
109 | rc = acpi_device_uevent_modalias(dev, env); | ||
110 | if (rc != -ENODEV) | ||
111 | return rc; | ||
107 | 112 | ||
108 | if (add_uevent_var(env, "MODALIAS=%s%s", | 113 | if (add_uevent_var(env, "MODALIAS=%s%s", |
109 | I2C_MODULE_PREFIX, client->name)) | 114 | I2C_MODULE_PREFIX, client->name)) |
@@ -409,6 +414,12 @@ static ssize_t | |||
409 | show_modalias(struct device *dev, struct device_attribute *attr, char *buf) | 414 | show_modalias(struct device *dev, struct device_attribute *attr, char *buf) |
410 | { | 415 | { |
411 | struct i2c_client *client = to_i2c_client(dev); | 416 | struct i2c_client *client = to_i2c_client(dev); |
417 | int len; | ||
418 | |||
419 | len = acpi_device_modalias(dev, buf, PAGE_SIZE -1); | ||
420 | if (len != -ENODEV) | ||
421 | return len; | ||
422 | |||
412 | return sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name); | 423 | return sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name); |
413 | } | 424 | } |
414 | 425 | ||
diff --git a/drivers/of/device.c b/drivers/of/device.c index f685e55e0717..dafb9736ab9b 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c | |||
@@ -85,6 +85,9 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) | |||
85 | int cplen, i; | 85 | int cplen, i; |
86 | ssize_t tsize, csize, repend; | 86 | ssize_t tsize, csize, repend; |
87 | 87 | ||
88 | if ((!dev) || (!dev->of_node)) | ||
89 | return -ENODEV; | ||
90 | |||
88 | /* Name & Type */ | 91 | /* Name & Type */ |
89 | csize = snprintf(str, len, "of:N%sT%s", dev->of_node->name, | 92 | csize = snprintf(str, len, "of:N%sT%s", dev->of_node->name, |
90 | dev->of_node->type); | 93 | dev->of_node->type); |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 349ebba4b199..827ff49d3d4f 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -58,6 +58,11 @@ static ssize_t | |||
58 | modalias_show(struct device *dev, struct device_attribute *a, char *buf) | 58 | modalias_show(struct device *dev, struct device_attribute *a, char *buf) |
59 | { | 59 | { |
60 | const struct spi_device *spi = to_spi_device(dev); | 60 | const struct spi_device *spi = to_spi_device(dev); |
61 | int len; | ||
62 | |||
63 | len = acpi_device_modalias(dev, buf, PAGE_SIZE - 1); | ||
64 | if (len != -ENODEV) | ||
65 | return len; | ||
61 | 66 | ||
62 | return sprintf(buf, "%s%s\n", SPI_MODULE_PREFIX, spi->modalias); | 67 | return sprintf(buf, "%s%s\n", SPI_MODULE_PREFIX, spi->modalias); |
63 | } | 68 | } |
@@ -114,6 +119,11 @@ static int spi_match_device(struct device *dev, struct device_driver *drv) | |||
114 | static int spi_uevent(struct device *dev, struct kobj_uevent_env *env) | 119 | static int spi_uevent(struct device *dev, struct kobj_uevent_env *env) |
115 | { | 120 | { |
116 | const struct spi_device *spi = to_spi_device(dev); | 121 | const struct spi_device *spi = to_spi_device(dev); |
122 | int rc; | ||
123 | |||
124 | rc = acpi_device_uevent_modalias(dev, env); | ||
125 | if (rc != -ENODEV) | ||
126 | return rc; | ||
117 | 127 | ||
118 | add_uevent_var(env, "MODALIAS=%s%s", SPI_MODULE_PREFIX, spi->modalias); | 128 | add_uevent_var(env, "MODALIAS=%s%s", SPI_MODULE_PREFIX, spi->modalias); |
119 | return 0; | 129 | return 0; |