container.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * container.c - ACPI Generic Container Driver
  3. *
  4. * Copyright (C) 2004 Anil S Keshavamurthy (anil.s.keshavamurthy@intel.com)
  5. * Copyright (C) 2004 Keiichiro Tokunaga (tokunaga.keiich@jp.fujitsu.com)
  6. * Copyright (C) 2004 Motoyuki Ito (motoyuki@soft.fujitsu.com)
  7. * Copyright (C) 2004 FUJITSU LIMITED
  8. * Copyright (C) 2004, 2013 Intel Corp.
  9. * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  10. *
  11. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  12. *
  13. * This program is free software; you can redistribute it and/or modify
  14. * it under the terms of the GNU General Public License as published by
  15. * the Free Software Foundation; either version 2 of the License, or (at
  16. * your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful, but
  19. * WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  21. * General Public License for more details.
  22. *
  23. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  24. */
  25. #include <linux/acpi.h>
  26. #include <linux/container.h>
  27. #include "internal.h"
  28. #define _COMPONENT ACPI_CONTAINER_COMPONENT
  29. ACPI_MODULE_NAME("container");
  30. static const struct acpi_device_id container_device_ids[] = {
  31. {"ACPI0004", 0},
  32. {"PNP0A05", 0},
  33. {"PNP0A06", 0},
  34. {"", 0},
  35. };
  36. #ifdef CONFIG_ACPI_CONTAINER
  37. static int acpi_container_offline(struct container_dev *cdev)
  38. {
  39. struct acpi_device *adev = ACPI_COMPANION(&cdev->dev);
  40. struct acpi_device *child;
  41. /* Check all of the dependent devices' physical companions. */
  42. list_for_each_entry(child, &adev->children, node)
  43. if (!acpi_scan_is_offline(child, false))
  44. return -EBUSY;
  45. return 0;
  46. }
  47. static void acpi_container_release(struct device *dev)
  48. {
  49. kfree(to_container_dev(dev));
  50. }
  51. static int container_device_attach(struct acpi_device *adev,
  52. const struct acpi_device_id *not_used)
  53. {
  54. struct container_dev *cdev;
  55. struct device *dev;
  56. int ret;
  57. if (adev->flags.is_dock_station)
  58. return 0;
  59. cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
  60. if (!cdev)
  61. return -ENOMEM;
  62. cdev->offline = acpi_container_offline;
  63. dev = &cdev->dev;
  64. dev->bus = &container_subsys;
  65. dev_set_name(dev, "%s", dev_name(&adev->dev));
  66. ACPI_COMPANION_SET(dev, adev);
  67. dev->release = acpi_container_release;
  68. ret = device_register(dev);
  69. if (ret) {
  70. put_device(dev);
  71. return ret;
  72. }
  73. adev->driver_data = dev;
  74. return 1;
  75. }
  76. static void container_device_detach(struct acpi_device *adev)
  77. {
  78. struct device *dev = acpi_driver_data(adev);
  79. adev->driver_data = NULL;
  80. if (dev)
  81. device_unregister(dev);
  82. }
  83. static void container_device_online(struct acpi_device *adev)
  84. {
  85. struct device *dev = acpi_driver_data(adev);
  86. kobject_uevent(&dev->kobj, KOBJ_ONLINE);
  87. }
  88. static struct acpi_scan_handler container_handler = {
  89. .ids = container_device_ids,
  90. .attach = container_device_attach,
  91. .detach = container_device_detach,
  92. .hotplug = {
  93. .enabled = true,
  94. .demand_offline = true,
  95. .notify_online = container_device_online,
  96. },
  97. };
  98. void __init acpi_container_init(void)
  99. {
  100. acpi_scan_add_handler(&container_handler);
  101. }
  102. #else
  103. static struct acpi_scan_handler container_handler = {
  104. .ids = container_device_ids,
  105. };
  106. void __init acpi_container_init(void)
  107. {
  108. acpi_scan_add_handler_with_hotplug(&container_handler, "container");
  109. }
  110. #endif /* CONFIG_ACPI_CONTAINER */