0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/acpi.h>
0013 #include <linux/container.h>
0014
0015 #include "internal.h"
0016
0017 static const struct acpi_device_id container_device_ids[] = {
0018 {"ACPI0004", 0},
0019 {"PNP0A05", 0},
0020 {"PNP0A06", 0},
0021 {"", 0},
0022 };
0023
0024 #ifdef CONFIG_ACPI_CONTAINER
0025
0026 static int check_offline(struct acpi_device *adev, void *not_used)
0027 {
0028 if (acpi_scan_is_offline(adev, false))
0029 return 0;
0030
0031 return -EBUSY;
0032 }
0033
0034 static int acpi_container_offline(struct container_dev *cdev)
0035 {
0036
0037 return acpi_dev_for_each_child(ACPI_COMPANION(&cdev->dev), check_offline, NULL);
0038 }
0039
0040 static void acpi_container_release(struct device *dev)
0041 {
0042 kfree(to_container_dev(dev));
0043 }
0044
0045 static int container_device_attach(struct acpi_device *adev,
0046 const struct acpi_device_id *not_used)
0047 {
0048 struct container_dev *cdev;
0049 struct device *dev;
0050 int ret;
0051
0052 if (adev->flags.is_dock_station)
0053 return 0;
0054
0055 cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
0056 if (!cdev)
0057 return -ENOMEM;
0058
0059 cdev->offline = acpi_container_offline;
0060 dev = &cdev->dev;
0061 dev->bus = &container_subsys;
0062 dev_set_name(dev, "%s", dev_name(&adev->dev));
0063 ACPI_COMPANION_SET(dev, adev);
0064 dev->release = acpi_container_release;
0065 ret = device_register(dev);
0066 if (ret) {
0067 put_device(dev);
0068 return ret;
0069 }
0070 adev->driver_data = dev;
0071 return 1;
0072 }
0073
0074 static void container_device_detach(struct acpi_device *adev)
0075 {
0076 struct device *dev = acpi_driver_data(adev);
0077
0078 adev->driver_data = NULL;
0079 if (dev)
0080 device_unregister(dev);
0081 }
0082
0083 static void container_device_online(struct acpi_device *adev)
0084 {
0085 struct device *dev = acpi_driver_data(adev);
0086
0087 kobject_uevent(&dev->kobj, KOBJ_ONLINE);
0088 }
0089
0090 static struct acpi_scan_handler container_handler = {
0091 .ids = container_device_ids,
0092 .attach = container_device_attach,
0093 .detach = container_device_detach,
0094 .hotplug = {
0095 .enabled = true,
0096 .demand_offline = true,
0097 .notify_online = container_device_online,
0098 },
0099 };
0100
0101 void __init acpi_container_init(void)
0102 {
0103 acpi_scan_add_handler(&container_handler);
0104 }
0105
0106 #else
0107
0108 static struct acpi_scan_handler container_handler = {
0109 .ids = container_device_ids,
0110 };
0111
0112 void __init acpi_container_init(void)
0113 {
0114 acpi_scan_add_handler_with_hotplug(&container_handler, "container");
0115 }
0116
0117 #endif