diff options
-rw-r--r-- | Documentation/ABI/testing/sysfs-devices-firmware_node | 17 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 54 | ||||
-rw-r--r-- | include/acpi/acpi_bus.h | 1 |
3 files changed, 70 insertions, 2 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-firmware_node b/Documentation/ABI/testing/sysfs-devices-firmware_node new file mode 100644 index 000000000000..46badc9ea284 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-devices-firmware_node | |||
@@ -0,0 +1,17 @@ | |||
1 | What: /sys/devices/.../firmware_node/ | ||
2 | Date: September 2012 | ||
3 | Contact: <> | ||
4 | Description: | ||
5 | The /sys/devices/.../firmware_node directory contains attributes | ||
6 | allowing the user space to check and modify some firmware | ||
7 | related properties of given device. | ||
8 | |||
9 | What: /sys/devices/.../firmware_node/description | ||
10 | Date: September 2012 | ||
11 | Contact: Lance Ortiz <lance.ortiz@hp.com> | ||
12 | Description: | ||
13 | The /sys/devices/.../firmware/description attribute contains a string | ||
14 | that describes the device as provided by the _STR method in the ACPI | ||
15 | namespace. This attribute is read-only. If the device does not have | ||
16 | an _STR method associated with it in the ACPI namespace, this | ||
17 | attribute is not present. | ||
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index d1ecca2b641a..04302835723d 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/signal.h> | 10 | #include <linux/signal.h> |
11 | #include <linux/kthread.h> | 11 | #include <linux/kthread.h> |
12 | #include <linux/dmi.h> | 12 | #include <linux/dmi.h> |
13 | #include <linux/nls.h> | ||
13 | 14 | ||
14 | #include <acpi/acpi_drivers.h> | 15 | #include <acpi/acpi_drivers.h> |
15 | 16 | ||
@@ -232,8 +233,35 @@ end: | |||
232 | } | 233 | } |
233 | static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); | 234 | static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); |
234 | 235 | ||
236 | /* sysfs file that shows description text from the ACPI _STR method */ | ||
237 | static ssize_t description_show(struct device *dev, | ||
238 | struct device_attribute *attr, | ||
239 | char *buf) { | ||
240 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
241 | int result; | ||
242 | |||
243 | if (acpi_dev->pnp.str_obj == NULL) | ||
244 | return 0; | ||
245 | |||
246 | /* | ||
247 | * The _STR object contains a Unicode identifier for a device. | ||
248 | * We need to convert to utf-8 so it can be displayed. | ||
249 | */ | ||
250 | result = utf16s_to_utf8s( | ||
251 | (wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer, | ||
252 | acpi_dev->pnp.str_obj->buffer.length, | ||
253 | UTF16_LITTLE_ENDIAN, buf, | ||
254 | PAGE_SIZE); | ||
255 | |||
256 | buf[result++] = '\n'; | ||
257 | |||
258 | return result; | ||
259 | } | ||
260 | static DEVICE_ATTR(description, 0444, description_show, NULL); | ||
261 | |||
235 | static int acpi_device_setup_files(struct acpi_device *dev) | 262 | static int acpi_device_setup_files(struct acpi_device *dev) |
236 | { | 263 | { |
264 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
237 | acpi_status status; | 265 | acpi_status status; |
238 | acpi_handle temp; | 266 | acpi_handle temp; |
239 | int result = 0; | 267 | int result = 0; |
@@ -257,6 +285,21 @@ static int acpi_device_setup_files(struct acpi_device *dev) | |||
257 | goto end; | 285 | goto end; |
258 | } | 286 | } |
259 | 287 | ||
288 | /* | ||
289 | * If device has _STR, 'description' file is created | ||
290 | */ | ||
291 | status = acpi_get_handle(dev->handle, "_STR", &temp); | ||
292 | if (ACPI_SUCCESS(status)) { | ||
293 | status = acpi_evaluate_object(dev->handle, "_STR", | ||
294 | NULL, &buffer); | ||
295 | if (ACPI_FAILURE(status)) | ||
296 | buffer.pointer = NULL; | ||
297 | dev->pnp.str_obj = buffer.pointer; | ||
298 | result = device_create_file(&dev->dev, &dev_attr_description); | ||
299 | if (result) | ||
300 | goto end; | ||
301 | } | ||
302 | |||
260 | /* | 303 | /* |
261 | * If device has _EJ0, 'eject' file is created that is used to trigger | 304 | * If device has _EJ0, 'eject' file is created that is used to trigger |
262 | * hot-removal function from userland. | 305 | * hot-removal function from userland. |
@@ -274,8 +317,15 @@ static void acpi_device_remove_files(struct acpi_device *dev) | |||
274 | acpi_handle temp; | 317 | acpi_handle temp; |
275 | 318 | ||
276 | /* | 319 | /* |
277 | * If device has _EJ0, 'eject' file is created that is used to trigger | 320 | * If device has _STR, remove 'description' file |
278 | * hot-removal function from userland. | 321 | */ |
322 | status = acpi_get_handle(dev->handle, "_STR", &temp); | ||
323 | if (ACPI_SUCCESS(status)) { | ||
324 | kfree(dev->pnp.str_obj); | ||
325 | device_remove_file(&dev->dev, &dev_attr_description); | ||
326 | } | ||
327 | /* | ||
328 | * If device has _EJ0, remove 'eject' file. | ||
279 | */ | 329 | */ |
280 | status = acpi_get_handle(dev->handle, "_EJ0", &temp); | 330 | status = acpi_get_handle(dev->handle, "_EJ0", &temp); |
281 | if (ACPI_SUCCESS(status)) | 331 | if (ACPI_SUCCESS(status)) |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index bde976ee068d..3eb9de318824 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -208,6 +208,7 @@ struct acpi_device_pnp { | |||
208 | struct list_head ids; /* _HID and _CIDs */ | 208 | struct list_head ids; /* _HID and _CIDs */ |
209 | acpi_device_name device_name; /* Driver-determined */ | 209 | acpi_device_name device_name; /* Driver-determined */ |
210 | acpi_device_class device_class; /* " */ | 210 | acpi_device_class device_class; /* " */ |
211 | union acpi_object *str_obj; /* unicode string for _STR method */ | ||
211 | }; | 212 | }; |
212 | 213 | ||
213 | #define acpi_device_bid(d) ((d)->pnp.bus_id) | 214 | #define acpi_device_bid(d) ((d)->pnp.bus_id) |