Lines Matching +full:device +full:- +full:handle

1 // SPDX-License-Identifier: GPL-2.0-only
3 * drivers/acpi/device_sysfs.c - ACPI device sysfs attributes and modalias.
15 #include <linux/device.h>
21 static ssize_t acpi_object_path(acpi_handle handle, char *buf) in acpi_object_path() argument
26 result = acpi_get_name(handle, ACPI_FULL_PATHNAME, &path); in acpi_object_path()
47 return dn->handle ? acpi_object_path(dn->handle, buf) : 0; in data_node_show_path()
66 return dn_attr->show ? dn_attr->show(dn, buf) : -ENXIO; in acpi_data_node_attr_show()
77 complete(&dn->kobj_done); in acpi_data_node_release()
89 struct list_head *list = &data->subnodes; in acpi_expose_nondev_subnodes()
98 init_completion(&dn->kobj_done); in acpi_expose_nondev_subnodes()
99 ret = kobject_init_and_add(&dn->kobj, &acpi_data_node_ktype, in acpi_expose_nondev_subnodes()
100 kobj, "%s", dn->name); in acpi_expose_nondev_subnodes()
102 acpi_expose_nondev_subnodes(&dn->kobj, &dn->data); in acpi_expose_nondev_subnodes()
103 else if (dn->handle) in acpi_expose_nondev_subnodes()
104 acpi_handle_err(dn->handle, "Failed to expose (%d)\n", ret); in acpi_expose_nondev_subnodes()
110 struct list_head *list = &data->subnodes; in acpi_hide_nondev_subnodes()
117 acpi_hide_nondev_subnodes(&dn->data); in acpi_hide_nondev_subnodes()
118 kobject_put(&dn->kobj); in acpi_hide_nondev_subnodes()
123 * create_pnp_modalias - Create hid/cid(s) string for modalias and uevent
124 * @acpi_dev: ACPI device object.
129 * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get:
132 * -EINVAL: output error
133 * -ENOMEM: output is truncated
149 * device's list. in create_pnp_modalias()
152 list_for_each_entry(id, &acpi_dev->pnp.ids, list) in create_pnp_modalias()
153 if (strcmp(id->id, ACPI_DT_NAMESPACE_HID)) in create_pnp_modalias()
163 size -= len; in create_pnp_modalias()
165 list_for_each_entry(id, &acpi_dev->pnp.ids, list) { in create_pnp_modalias()
166 if (!strcmp(id->id, ACPI_DT_NAMESPACE_HID)) in create_pnp_modalias()
169 count = snprintf(&modalias[len], size, "%s:", id->id); in create_pnp_modalias()
171 return -EINVAL; in create_pnp_modalias()
174 return -ENOMEM; in create_pnp_modalias()
177 size -= count; in create_pnp_modalias()
184 * create_of_modalias - Creates DT compatible string for modalias and uevent
185 * @acpi_dev: ACPI device object.
203 status = acpi_get_name(acpi_dev->handle, ACPI_SINGLE_NAME, &buf); in create_of_modalias()
205 return -ENODEV; in create_of_modalias()
217 of_compatible = acpi_dev->data.of_compatible; in create_of_modalias()
218 if (of_compatible->type == ACPI_TYPE_PACKAGE) { in create_of_modalias()
219 nval = of_compatible->package.count; in create_of_modalias()
220 obj = of_compatible->package.elements; in create_of_modalias()
227 obj->string.pointer); in create_of_modalias()
229 return -EINVAL; in create_of_modalias()
232 return -ENOMEM; in create_of_modalias()
235 size -= count; in create_of_modalias()
247 return -ENODEV; in __acpi_device_uevent_modalias()
249 if (list_empty(&adev->pnp.ids)) in __acpi_device_uevent_modalias()
253 return -ENOMEM; in __acpi_device_uevent_modalias()
255 if (adev->data.of_compatible) in __acpi_device_uevent_modalias()
256 len = create_of_modalias(adev, &env->buf[env->buflen - 1], in __acpi_device_uevent_modalias()
257 sizeof(env->buf) - env->buflen); in __acpi_device_uevent_modalias()
259 len = create_pnp_modalias(adev, &env->buf[env->buflen - 1], in __acpi_device_uevent_modalias()
260 sizeof(env->buf) - env->buflen); in __acpi_device_uevent_modalias()
264 env->buflen += len; in __acpi_device_uevent_modalias()
270 * acpi_device_uevent_modalias - uevent modalias for ACPI-enumerated devices.
271 * @dev: Struct device to get ACPI device node.
274 * Create the uevent modalias field for ACPI-enumerated devices.
276 * Because other buses do not support ACPI HIDs & CIDs, e.g. for a device with
279 int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) in acpi_device_uevent_modalias()
290 return -ENODEV; in __acpi_device_modalias()
292 if (list_empty(&adev->pnp.ids)) in __acpi_device_modalias()
295 len = create_pnp_modalias(adev, buf, size - 1); in __acpi_device_modalias()
300 size -= len; in __acpi_device_modalias()
302 if (!adev->data.of_compatible) in __acpi_device_modalias()
305 count = create_of_modalias(adev, buf + len, size - 1); in __acpi_device_modalias()
317 * acpi_device_modalias - modalias sysfs attribute for ACPI-enumerated devices.
318 * @dev: Struct device to get ACPI device node.
322 * Create the modalias sysfs attribute for ACPI-enumerated devices.
324 * Because other buses do not support ACPI HIDs & CIDs, e.g. for a device with
327 int acpi_device_modalias(struct device *dev, char *buf, int size) in acpi_device_modalias()
334 modalias_show(struct device *dev, struct device_attribute *attr, char *buf) in modalias_show()
340 static ssize_t real_power_state_show(struct device *dev, in real_power_state_show()
356 static ssize_t power_state_show(struct device *dev, in power_state_show()
361 return sprintf(buf, "%s\n", acpi_power_state_string(adev->power.state)); in power_state_show()
367 eject_store(struct device *d, struct device_attribute *attr, in eject_store()
375 return -EINVAL; in eject_store()
377 if ((!acpi_device->handler || !acpi_device->handler->hotplug.enabled) in eject_store()
378 && !acpi_device->driver) in eject_store()
379 return -ENODEV; in eject_store()
381 status = acpi_get_type(acpi_device->handle, &not_used); in eject_store()
382 if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable) in eject_store()
383 return -ENODEV; in eject_store()
391 acpi_evaluate_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, in eject_store()
393 return status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN; in eject_store()
399 hid_show(struct device *dev, struct device_attribute *attr, char *buf) in hid_show()
407 static ssize_t uid_show(struct device *dev, in uid_show()
412 return sprintf(buf, "%s\n", acpi_dev->pnp.unique_id); in uid_show()
416 static ssize_t adr_show(struct device *dev, in adr_show()
421 if (acpi_dev->pnp.bus_address > U32_MAX) in adr_show()
422 return sprintf(buf, "0x%016llx\n", acpi_dev->pnp.bus_address); in adr_show()
424 return sprintf(buf, "0x%08llx\n", acpi_dev->pnp.bus_address); in adr_show()
428 static ssize_t path_show(struct device *dev, in path_show()
433 return acpi_object_path(acpi_dev->handle, buf); in path_show()
438 static ssize_t description_show(struct device *dev, in description_show()
445 if (acpi_dev->pnp.str_obj == NULL) in description_show()
449 * The _STR object contains a Unicode identifier for a device. in description_show()
450 * We need to convert to utf-8 so it can be displayed. in description_show()
453 (wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer, in description_show()
454 acpi_dev->pnp.str_obj->buffer.length, in description_show()
456 PAGE_SIZE - 1); in description_show()
465 sun_show(struct device *dev, struct device_attribute *attr, in sun_show()
472 status = acpi_evaluate_integer(acpi_dev->handle, "_SUN", NULL, &sun); in sun_show()
474 return -EIO; in sun_show()
481 hrv_show(struct device *dev, struct device_attribute *attr, in hrv_show()
488 status = acpi_evaluate_integer(acpi_dev->handle, "_HRV", NULL, &hrv); in hrv_show()
490 return -EIO; in hrv_show()
496 static ssize_t status_show(struct device *dev, struct device_attribute *attr, in status_show()
503 status = acpi_evaluate_integer(acpi_dev->handle, "_STA", NULL, &sta); in status_show()
505 return -EIO; in status_show()
512 * acpi_device_setup_files - Create sysfs attributes of an ACPI device.
513 * @dev: ACPI device object.
524 if (dev->handle) { in acpi_device_setup_files()
525 result = device_create_file(&dev->dev, &dev_attr_path); in acpi_device_setup_files()
530 if (!list_empty(&dev->pnp.ids)) { in acpi_device_setup_files()
531 result = device_create_file(&dev->dev, &dev_attr_hid); in acpi_device_setup_files()
535 result = device_create_file(&dev->dev, &dev_attr_modalias); in acpi_device_setup_files()
541 * If device has _STR, 'description' file is created in acpi_device_setup_files()
543 if (acpi_has_method(dev->handle, "_STR")) { in acpi_device_setup_files()
544 status = acpi_evaluate_object(dev->handle, "_STR", in acpi_device_setup_files()
548 dev->pnp.str_obj = buffer.pointer; in acpi_device_setup_files()
549 result = device_create_file(&dev->dev, &dev_attr_description); in acpi_device_setup_files()
554 if (dev->pnp.type.bus_address) in acpi_device_setup_files()
555 result = device_create_file(&dev->dev, &dev_attr_adr); in acpi_device_setup_files()
556 if (dev->pnp.unique_id) in acpi_device_setup_files()
557 result = device_create_file(&dev->dev, &dev_attr_uid); in acpi_device_setup_files()
559 if (acpi_has_method(dev->handle, "_SUN")) { in acpi_device_setup_files()
560 result = device_create_file(&dev->dev, &dev_attr_sun); in acpi_device_setup_files()
565 if (acpi_has_method(dev->handle, "_HRV")) { in acpi_device_setup_files()
566 result = device_create_file(&dev->dev, &dev_attr_hrv); in acpi_device_setup_files()
571 if (acpi_has_method(dev->handle, "_STA")) { in acpi_device_setup_files()
572 result = device_create_file(&dev->dev, &dev_attr_status); in acpi_device_setup_files()
578 * If device has _EJ0, 'eject' file is created that is used to trigger in acpi_device_setup_files()
579 * hot-removal function from userland. in acpi_device_setup_files()
581 if (acpi_has_method(dev->handle, "_EJ0")) { in acpi_device_setup_files()
582 result = device_create_file(&dev->dev, &dev_attr_eject); in acpi_device_setup_files()
587 if (dev->flags.power_manageable) { in acpi_device_setup_files()
588 result = device_create_file(&dev->dev, &dev_attr_power_state); in acpi_device_setup_files()
592 if (dev->power.flags.power_resources) in acpi_device_setup_files()
593 result = device_create_file(&dev->dev, in acpi_device_setup_files()
597 acpi_expose_nondev_subnodes(&dev->dev.kobj, &dev->data); in acpi_device_setup_files()
604 * acpi_device_remove_files - Remove sysfs attributes of an ACPI device.
605 * @dev: ACPI device object.
609 acpi_hide_nondev_subnodes(&dev->data); in acpi_device_remove_files()
611 if (dev->flags.power_manageable) { in acpi_device_remove_files()
612 device_remove_file(&dev->dev, &dev_attr_power_state); in acpi_device_remove_files()
613 if (dev->power.flags.power_resources) in acpi_device_remove_files()
614 device_remove_file(&dev->dev, in acpi_device_remove_files()
619 * If device has _STR, remove 'description' file in acpi_device_remove_files()
621 if (acpi_has_method(dev->handle, "_STR")) { in acpi_device_remove_files()
622 kfree(dev->pnp.str_obj); in acpi_device_remove_files()
623 device_remove_file(&dev->dev, &dev_attr_description); in acpi_device_remove_files()
626 * If device has _EJ0, remove 'eject' file. in acpi_device_remove_files()
628 if (acpi_has_method(dev->handle, "_EJ0")) in acpi_device_remove_files()
629 device_remove_file(&dev->dev, &dev_attr_eject); in acpi_device_remove_files()
631 if (acpi_has_method(dev->handle, "_SUN")) in acpi_device_remove_files()
632 device_remove_file(&dev->dev, &dev_attr_sun); in acpi_device_remove_files()
634 if (acpi_has_method(dev->handle, "_HRV")) in acpi_device_remove_files()
635 device_remove_file(&dev->dev, &dev_attr_hrv); in acpi_device_remove_files()
637 if (dev->pnp.unique_id) in acpi_device_remove_files()
638 device_remove_file(&dev->dev, &dev_attr_uid); in acpi_device_remove_files()
639 if (dev->pnp.type.bus_address) in acpi_device_remove_files()
640 device_remove_file(&dev->dev, &dev_attr_adr); in acpi_device_remove_files()
641 device_remove_file(&dev->dev, &dev_attr_modalias); in acpi_device_remove_files()
642 device_remove_file(&dev->dev, &dev_attr_hid); in acpi_device_remove_files()
643 if (acpi_has_method(dev->handle, "_STA")) in acpi_device_remove_files()
644 device_remove_file(&dev->dev, &dev_attr_status); in acpi_device_remove_files()
645 if (dev->handle) in acpi_device_remove_files()
646 device_remove_file(&dev->dev, &dev_attr_path); in acpi_device_remove_files()