root/drivers/acpi/device_sysfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. acpi_object_path
  2. data_node_show_path
  3. acpi_data_node_attr_show
  4. acpi_data_node_release
  5. acpi_expose_nondev_subnodes
  6. acpi_hide_nondev_subnodes
  7. create_pnp_modalias
  8. create_of_modalias
  9. __acpi_device_uevent_modalias
  10. acpi_device_uevent_modalias
  11. __acpi_device_modalias
  12. acpi_device_modalias
  13. acpi_device_modalias_show
  14. real_power_state_show
  15. power_state_show
  16. acpi_eject_store
  17. acpi_device_hid_show
  18. acpi_device_uid_show
  19. acpi_device_adr_show
  20. acpi_device_path_show
  21. description_show
  22. acpi_device_sun_show
  23. acpi_device_hrv_show
  24. status_show
  25. acpi_device_setup_files
  26. acpi_device_remove_files

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * drivers/acpi/device_sysfs.c - ACPI device sysfs attributes and modalias.
   4  *
   5  * Copyright (C) 2015, Intel Corp.
   6  * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
   7  * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
   8  *
   9  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  10  *
  11  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  12  */
  13 
  14 #include <linux/acpi.h>
  15 #include <linux/device.h>
  16 #include <linux/export.h>
  17 #include <linux/nls.h>
  18 
  19 #include "internal.h"
  20 
  21 static ssize_t acpi_object_path(acpi_handle handle, char *buf)
  22 {
  23         struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
  24         int result;
  25 
  26         result = acpi_get_name(handle, ACPI_FULL_PATHNAME, &path);
  27         if (result)
  28                 return result;
  29 
  30         result = sprintf(buf, "%s\n", (char *)path.pointer);
  31         kfree(path.pointer);
  32         return result;
  33 }
  34 
  35 struct acpi_data_node_attr {
  36         struct attribute attr;
  37         ssize_t (*show)(struct acpi_data_node *, char *);
  38         ssize_t (*store)(struct acpi_data_node *, const char *, size_t count);
  39 };
  40 
  41 #define DATA_NODE_ATTR(_name)                   \
  42         static struct acpi_data_node_attr data_node_##_name =   \
  43                 __ATTR(_name, 0444, data_node_show_##_name, NULL)
  44 
  45 static ssize_t data_node_show_path(struct acpi_data_node *dn, char *buf)
  46 {
  47         return dn->handle ? acpi_object_path(dn->handle, buf) : 0;
  48 }
  49 
  50 DATA_NODE_ATTR(path);
  51 
  52 static struct attribute *acpi_data_node_default_attrs[] = {
  53         &data_node_path.attr,
  54         NULL
  55 };
  56 
  57 #define to_data_node(k) container_of(k, struct acpi_data_node, kobj)
  58 #define to_attr(a) container_of(a, struct acpi_data_node_attr, attr)
  59 
  60 static ssize_t acpi_data_node_attr_show(struct kobject *kobj,
  61                                         struct attribute *attr, char *buf)
  62 {
  63         struct acpi_data_node *dn = to_data_node(kobj);
  64         struct acpi_data_node_attr *dn_attr = to_attr(attr);
  65 
  66         return dn_attr->show ? dn_attr->show(dn, buf) : -ENXIO;
  67 }
  68 
  69 static const struct sysfs_ops acpi_data_node_sysfs_ops = {
  70         .show   = acpi_data_node_attr_show,
  71 };
  72 
  73 static void acpi_data_node_release(struct kobject *kobj)
  74 {
  75         struct acpi_data_node *dn = to_data_node(kobj);
  76         complete(&dn->kobj_done);
  77 }
  78 
  79 static struct kobj_type acpi_data_node_ktype = {
  80         .sysfs_ops = &acpi_data_node_sysfs_ops,
  81         .default_attrs = acpi_data_node_default_attrs,
  82         .release = acpi_data_node_release,
  83 };
  84 
  85 static void acpi_expose_nondev_subnodes(struct kobject *kobj,
  86                                         struct acpi_device_data *data)
  87 {
  88         struct list_head *list = &data->subnodes;
  89         struct acpi_data_node *dn;
  90 
  91         if (list_empty(list))
  92                 return;
  93 
  94         list_for_each_entry(dn, list, sibling) {
  95                 int ret;
  96 
  97                 init_completion(&dn->kobj_done);
  98                 ret = kobject_init_and_add(&dn->kobj, &acpi_data_node_ktype,
  99                                            kobj, "%s", dn->name);
 100                 if (!ret)
 101                         acpi_expose_nondev_subnodes(&dn->kobj, &dn->data);
 102                 else if (dn->handle)
 103                         acpi_handle_err(dn->handle, "Failed to expose (%d)\n", ret);
 104         }
 105 }
 106 
 107 static void acpi_hide_nondev_subnodes(struct acpi_device_data *data)
 108 {
 109         struct list_head *list = &data->subnodes;
 110         struct acpi_data_node *dn;
 111 
 112         if (list_empty(list))
 113                 return;
 114 
 115         list_for_each_entry_reverse(dn, list, sibling) {
 116                 acpi_hide_nondev_subnodes(&dn->data);
 117                 kobject_put(&dn->kobj);
 118         }
 119 }
 120 
 121 /**
 122  * create_pnp_modalias - Create hid/cid(s) string for modalias and uevent
 123  * @acpi_dev: ACPI device object.
 124  * @modalias: Buffer to print into.
 125  * @size: Size of the buffer.
 126  *
 127  * Creates hid/cid(s) string needed for modalias and uevent
 128  * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get:
 129  * char *modalias: "acpi:IBM0001:ACPI0001"
 130  * Return: 0: no _HID and no _CID
 131  *         -EINVAL: output error
 132  *         -ENOMEM: output is truncated
 133 */
 134 static int create_pnp_modalias(struct acpi_device *acpi_dev, char *modalias,
 135                                int size)
 136 {
 137         int len;
 138         int count;
 139         struct acpi_hardware_id *id;
 140 
 141         /* Avoid unnecessarily loading modules for non present devices. */
 142         if (!acpi_device_is_present(acpi_dev))
 143                 return 0;
 144 
 145         /*
 146          * Since we skip ACPI_DT_NAMESPACE_HID from the modalias below, 0 should
 147          * be returned if ACPI_DT_NAMESPACE_HID is the only ACPI/PNP ID in the
 148          * device's list.
 149          */
 150         count = 0;
 151         list_for_each_entry(id, &acpi_dev->pnp.ids, list)
 152                 if (strcmp(id->id, ACPI_DT_NAMESPACE_HID))
 153                         count++;
 154 
 155         if (!count)
 156                 return 0;
 157 
 158         len = snprintf(modalias, size, "acpi:");
 159         if (len <= 0)
 160                 return len;
 161 
 162         size -= len;
 163 
 164         list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
 165                 if (!strcmp(id->id, ACPI_DT_NAMESPACE_HID))
 166                         continue;
 167 
 168                 count = snprintf(&modalias[len], size, "%s:", id->id);
 169                 if (count < 0)
 170                         return -EINVAL;
 171 
 172                 if (count >= size)
 173                         return -ENOMEM;
 174 
 175                 len += count;
 176                 size -= count;
 177         }
 178         modalias[len] = '\0';
 179         return len;
 180 }
 181 
 182 /**
 183  * create_of_modalias - Creates DT compatible string for modalias and uevent
 184  * @acpi_dev: ACPI device object.
 185  * @modalias: Buffer to print into.
 186  * @size: Size of the buffer.
 187  *
 188  * Expose DT compatible modalias as of:NnameTCcompatible.  This function should
 189  * only be called for devices having ACPI_DT_NAMESPACE_HID in their list of
 190  * ACPI/PNP IDs.
 191  */
 192 static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias,
 193                               int size)
 194 {
 195         struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
 196         const union acpi_object *of_compatible, *obj;
 197         acpi_status status;
 198         int len, count;
 199         int i, nval;
 200         char *c;
 201 
 202         status = acpi_get_name(acpi_dev->handle, ACPI_SINGLE_NAME, &buf);
 203         if (ACPI_FAILURE(status))
 204                 return -ENODEV;
 205 
 206         /* DT strings are all in lower case */
 207         for (c = buf.pointer; *c != '\0'; c++)
 208                 *c = tolower(*c);
 209 
 210         len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer);
 211         ACPI_FREE(buf.pointer);
 212 
 213         if (len <= 0)
 214                 return len;
 215 
 216         of_compatible = acpi_dev->data.of_compatible;
 217         if (of_compatible->type == ACPI_TYPE_PACKAGE) {
 218                 nval = of_compatible->package.count;
 219                 obj = of_compatible->package.elements;
 220         } else { /* Must be ACPI_TYPE_STRING. */
 221                 nval = 1;
 222                 obj = of_compatible;
 223         }
 224         for (i = 0; i < nval; i++, obj++) {
 225                 count = snprintf(&modalias[len], size, "C%s",
 226                                  obj->string.pointer);
 227                 if (count < 0)
 228                         return -EINVAL;
 229 
 230                 if (count >= size)
 231                         return -ENOMEM;
 232 
 233                 len += count;
 234                 size -= count;
 235         }
 236         modalias[len] = '\0';
 237         return len;
 238 }
 239 
 240 int __acpi_device_uevent_modalias(struct acpi_device *adev,
 241                                   struct kobj_uevent_env *env)
 242 {
 243         int len;
 244 
 245         if (!adev)
 246                 return -ENODEV;
 247 
 248         if (list_empty(&adev->pnp.ids))
 249                 return 0;
 250 
 251         if (add_uevent_var(env, "MODALIAS="))
 252                 return -ENOMEM;
 253 
 254         len = create_pnp_modalias(adev, &env->buf[env->buflen - 1],
 255                                   sizeof(env->buf) - env->buflen);
 256         if (len < 0)
 257                 return len;
 258 
 259         env->buflen += len;
 260         if (!adev->data.of_compatible)
 261                 return 0;
 262 
 263         if (len > 0 && add_uevent_var(env, "MODALIAS="))
 264                 return -ENOMEM;
 265 
 266         len = create_of_modalias(adev, &env->buf[env->buflen - 1],
 267                                  sizeof(env->buf) - env->buflen);
 268         if (len < 0)
 269                 return len;
 270 
 271         env->buflen += len;
 272 
 273         return 0;
 274 }
 275 
 276 /**
 277  * acpi_device_uevent_modalias - uevent modalias for ACPI-enumerated devices.
 278  *
 279  * Create the uevent modalias field for ACPI-enumerated devices.
 280  *
 281  * Because other buses do not support ACPI HIDs & CIDs, e.g. for a device with
 282  * hid:IBM0001 and cid:ACPI0001 you get: "acpi:IBM0001:ACPI0001".
 283  */
 284 int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
 285 {
 286         return __acpi_device_uevent_modalias(acpi_companion_match(dev), env);
 287 }
 288 EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias);
 289 
 290 static int __acpi_device_modalias(struct acpi_device *adev, char *buf, int size)
 291 {
 292         int len, count;
 293 
 294         if (!adev)
 295                 return -ENODEV;
 296 
 297         if (list_empty(&adev->pnp.ids))
 298                 return 0;
 299 
 300         len = create_pnp_modalias(adev, buf, size - 1);
 301         if (len < 0) {
 302                 return len;
 303         } else if (len > 0) {
 304                 buf[len++] = '\n';
 305                 size -= len;
 306         }
 307         if (!adev->data.of_compatible)
 308                 return len;
 309 
 310         count = create_of_modalias(adev, buf + len, size - 1);
 311         if (count < 0) {
 312                 return count;
 313         } else if (count > 0) {
 314                 len += count;
 315                 buf[len++] = '\n';
 316         }
 317 
 318         return len;
 319 }
 320 
 321 /**
 322  * acpi_device_modalias - modalias sysfs attribute for ACPI-enumerated devices.
 323  *
 324  * Create the modalias sysfs attribute for ACPI-enumerated devices.
 325  *
 326  * Because other buses do not support ACPI HIDs & CIDs, e.g. for a device with
 327  * hid:IBM0001 and cid:ACPI0001 you get: "acpi:IBM0001:ACPI0001".
 328  */
 329 int acpi_device_modalias(struct device *dev, char *buf, int size)
 330 {
 331         return __acpi_device_modalias(acpi_companion_match(dev), buf, size);
 332 }
 333 EXPORT_SYMBOL_GPL(acpi_device_modalias);
 334 
 335 static ssize_t
 336 acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
 337 {
 338         return __acpi_device_modalias(to_acpi_device(dev), buf, 1024);
 339 }
 340 static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
 341 
 342 static ssize_t real_power_state_show(struct device *dev,
 343                                      struct device_attribute *attr, char *buf)
 344 {
 345         struct acpi_device *adev = to_acpi_device(dev);
 346         int state;
 347         int ret;
 348 
 349         ret = acpi_device_get_power(adev, &state);
 350         if (ret)
 351                 return ret;
 352 
 353         return sprintf(buf, "%s\n", acpi_power_state_string(state));
 354 }
 355 
 356 static DEVICE_ATTR_RO(real_power_state);
 357 
 358 static ssize_t power_state_show(struct device *dev,
 359                                 struct device_attribute *attr, char *buf)
 360 {
 361         struct acpi_device *adev = to_acpi_device(dev);
 362 
 363         return sprintf(buf, "%s\n", acpi_power_state_string(adev->power.state));
 364 }
 365 
 366 static DEVICE_ATTR_RO(power_state);
 367 
 368 static ssize_t
 369 acpi_eject_store(struct device *d, struct device_attribute *attr,
 370                 const char *buf, size_t count)
 371 {
 372         struct acpi_device *acpi_device = to_acpi_device(d);
 373         acpi_object_type not_used;
 374         acpi_status status;
 375 
 376         if (!count || buf[0] != '1')
 377                 return -EINVAL;
 378 
 379         if ((!acpi_device->handler || !acpi_device->handler->hotplug.enabled)
 380             && !acpi_device->driver)
 381                 return -ENODEV;
 382 
 383         status = acpi_get_type(acpi_device->handle, &not_used);
 384         if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable)
 385                 return -ENODEV;
 386 
 387         get_device(&acpi_device->dev);
 388         status = acpi_hotplug_schedule(acpi_device, ACPI_OST_EC_OSPM_EJECT);
 389         if (ACPI_SUCCESS(status))
 390                 return count;
 391 
 392         put_device(&acpi_device->dev);
 393         acpi_evaluate_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT,
 394                           ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL);
 395         return status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN;
 396 }
 397 
 398 static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
 399 
 400 static ssize_t
 401 acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf)
 402 {
 403         struct acpi_device *acpi_dev = to_acpi_device(dev);
 404 
 405         return sprintf(buf, "%s\n", acpi_device_hid(acpi_dev));
 406 }
 407 static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL);
 408 
 409 static ssize_t acpi_device_uid_show(struct device *dev,
 410                                     struct device_attribute *attr, char *buf)
 411 {
 412         struct acpi_device *acpi_dev = to_acpi_device(dev);
 413 
 414         return sprintf(buf, "%s\n", acpi_dev->pnp.unique_id);
 415 }
 416 static DEVICE_ATTR(uid, 0444, acpi_device_uid_show, NULL);
 417 
 418 static ssize_t acpi_device_adr_show(struct device *dev,
 419                                     struct device_attribute *attr, char *buf)
 420 {
 421         struct acpi_device *acpi_dev = to_acpi_device(dev);
 422 
 423         if (acpi_dev->pnp.bus_address > U32_MAX)
 424                 return sprintf(buf, "0x%016llx\n", acpi_dev->pnp.bus_address);
 425         else
 426                 return sprintf(buf, "0x%08llx\n", acpi_dev->pnp.bus_address);
 427 }
 428 static DEVICE_ATTR(adr, 0444, acpi_device_adr_show, NULL);
 429 
 430 static ssize_t acpi_device_path_show(struct device *dev,
 431                                      struct device_attribute *attr, char *buf)
 432 {
 433         struct acpi_device *acpi_dev = to_acpi_device(dev);
 434 
 435         return acpi_object_path(acpi_dev->handle, buf);
 436 }
 437 static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL);
 438 
 439 /* sysfs file that shows description text from the ACPI _STR method */
 440 static ssize_t description_show(struct device *dev,
 441                                 struct device_attribute *attr,
 442                                 char *buf) {
 443         struct acpi_device *acpi_dev = to_acpi_device(dev);
 444         int result;
 445 
 446         if (acpi_dev->pnp.str_obj == NULL)
 447                 return 0;
 448 
 449         /*
 450          * The _STR object contains a Unicode identifier for a device.
 451          * We need to convert to utf-8 so it can be displayed.
 452          */
 453         result = utf16s_to_utf8s(
 454                 (wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer,
 455                 acpi_dev->pnp.str_obj->buffer.length,
 456                 UTF16_LITTLE_ENDIAN, buf,
 457                 PAGE_SIZE);
 458 
 459         buf[result++] = '\n';
 460 
 461         return result;
 462 }
 463 static DEVICE_ATTR_RO(description);
 464 
 465 static ssize_t
 466 acpi_device_sun_show(struct device *dev, struct device_attribute *attr,
 467                      char *buf) {
 468         struct acpi_device *acpi_dev = to_acpi_device(dev);
 469         acpi_status status;
 470         unsigned long long sun;
 471 
 472         status = acpi_evaluate_integer(acpi_dev->handle, "_SUN", NULL, &sun);
 473         if (ACPI_FAILURE(status))
 474                 return -EIO;
 475 
 476         return sprintf(buf, "%llu\n", sun);
 477 }
 478 static DEVICE_ATTR(sun, 0444, acpi_device_sun_show, NULL);
 479 
 480 static ssize_t
 481 acpi_device_hrv_show(struct device *dev, struct device_attribute *attr,
 482                      char *buf) {
 483         struct acpi_device *acpi_dev = to_acpi_device(dev);
 484         acpi_status status;
 485         unsigned long long hrv;
 486 
 487         status = acpi_evaluate_integer(acpi_dev->handle, "_HRV", NULL, &hrv);
 488         if (ACPI_FAILURE(status))
 489                 return -EIO;
 490 
 491         return sprintf(buf, "%llu\n", hrv);
 492 }
 493 static DEVICE_ATTR(hrv, 0444, acpi_device_hrv_show, NULL);
 494 
 495 static ssize_t status_show(struct device *dev, struct device_attribute *attr,
 496                                 char *buf) {
 497         struct acpi_device *acpi_dev = to_acpi_device(dev);
 498         acpi_status status;
 499         unsigned long long sta;
 500 
 501         status = acpi_evaluate_integer(acpi_dev->handle, "_STA", NULL, &sta);
 502         if (ACPI_FAILURE(status))
 503                 return -EIO;
 504 
 505         return sprintf(buf, "%llu\n", sta);
 506 }
 507 static DEVICE_ATTR_RO(status);
 508 
 509 /**
 510  * acpi_device_setup_files - Create sysfs attributes of an ACPI device.
 511  * @dev: ACPI device object.
 512  */
 513 int acpi_device_setup_files(struct acpi_device *dev)
 514 {
 515         struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
 516         acpi_status status;
 517         int result = 0;
 518 
 519         /*
 520          * Devices gotten from FADT don't have a "path" attribute
 521          */
 522         if (dev->handle) {
 523                 result = device_create_file(&dev->dev, &dev_attr_path);
 524                 if (result)
 525                         goto end;
 526         }
 527 
 528         if (!list_empty(&dev->pnp.ids)) {
 529                 result = device_create_file(&dev->dev, &dev_attr_hid);
 530                 if (result)
 531                         goto end;
 532 
 533                 result = device_create_file(&dev->dev, &dev_attr_modalias);
 534                 if (result)
 535                         goto end;
 536         }
 537 
 538         /*
 539          * If device has _STR, 'description' file is created
 540          */
 541         if (acpi_has_method(dev->handle, "_STR")) {
 542                 status = acpi_evaluate_object(dev->handle, "_STR",
 543                                         NULL, &buffer);
 544                 if (ACPI_FAILURE(status))
 545                         buffer.pointer = NULL;
 546                 dev->pnp.str_obj = buffer.pointer;
 547                 result = device_create_file(&dev->dev, &dev_attr_description);
 548                 if (result)
 549                         goto end;
 550         }
 551 
 552         if (dev->pnp.type.bus_address)
 553                 result = device_create_file(&dev->dev, &dev_attr_adr);
 554         if (dev->pnp.unique_id)
 555                 result = device_create_file(&dev->dev, &dev_attr_uid);
 556 
 557         if (acpi_has_method(dev->handle, "_SUN")) {
 558                 result = device_create_file(&dev->dev, &dev_attr_sun);
 559                 if (result)
 560                         goto end;
 561         }
 562 
 563         if (acpi_has_method(dev->handle, "_HRV")) {
 564                 result = device_create_file(&dev->dev, &dev_attr_hrv);
 565                 if (result)
 566                         goto end;
 567         }
 568 
 569         if (acpi_has_method(dev->handle, "_STA")) {
 570                 result = device_create_file(&dev->dev, &dev_attr_status);
 571                 if (result)
 572                         goto end;
 573         }
 574 
 575         /*
 576          * If device has _EJ0, 'eject' file is created that is used to trigger
 577          * hot-removal function from userland.
 578          */
 579         if (acpi_has_method(dev->handle, "_EJ0")) {
 580                 result = device_create_file(&dev->dev, &dev_attr_eject);
 581                 if (result)
 582                         return result;
 583         }
 584 
 585         if (dev->flags.power_manageable) {
 586                 result = device_create_file(&dev->dev, &dev_attr_power_state);
 587                 if (result)
 588                         return result;
 589 
 590                 if (dev->power.flags.power_resources)
 591                         result = device_create_file(&dev->dev,
 592                                                     &dev_attr_real_power_state);
 593         }
 594 
 595         acpi_expose_nondev_subnodes(&dev->dev.kobj, &dev->data);
 596 
 597 end:
 598         return result;
 599 }
 600 
 601 /**
 602  * acpi_device_remove_files - Remove sysfs attributes of an ACPI device.
 603  * @dev: ACPI device object.
 604  */
 605 void acpi_device_remove_files(struct acpi_device *dev)
 606 {
 607         acpi_hide_nondev_subnodes(&dev->data);
 608 
 609         if (dev->flags.power_manageable) {
 610                 device_remove_file(&dev->dev, &dev_attr_power_state);
 611                 if (dev->power.flags.power_resources)
 612                         device_remove_file(&dev->dev,
 613                                            &dev_attr_real_power_state);
 614         }
 615 
 616         /*
 617          * If device has _STR, remove 'description' file
 618          */
 619         if (acpi_has_method(dev->handle, "_STR")) {
 620                 kfree(dev->pnp.str_obj);
 621                 device_remove_file(&dev->dev, &dev_attr_description);
 622         }
 623         /*
 624          * If device has _EJ0, remove 'eject' file.
 625          */
 626         if (acpi_has_method(dev->handle, "_EJ0"))
 627                 device_remove_file(&dev->dev, &dev_attr_eject);
 628 
 629         if (acpi_has_method(dev->handle, "_SUN"))
 630                 device_remove_file(&dev->dev, &dev_attr_sun);
 631 
 632         if (acpi_has_method(dev->handle, "_HRV"))
 633                 device_remove_file(&dev->dev, &dev_attr_hrv);
 634 
 635         if (dev->pnp.unique_id)
 636                 device_remove_file(&dev->dev, &dev_attr_uid);
 637         if (dev->pnp.type.bus_address)
 638                 device_remove_file(&dev->dev, &dev_attr_adr);
 639         device_remove_file(&dev->dev, &dev_attr_modalias);
 640         device_remove_file(&dev->dev, &dev_attr_hid);
 641         if (acpi_has_method(dev->handle, "_STA"))
 642                 device_remove_file(&dev->dev, &dev_attr_status);
 643         if (dev->handle)
 644                 device_remove_file(&dev->dev, &dev_attr_path);
 645 }

/* [<][>][^][v][top][bottom][index][help] */