Commit | Line | Data |
---|---|---|
c942fddf | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
1da177e4 | 2 | /* |
68a67f6c | 3 | * container.c - ACPI Generic Container Driver |
1da177e4 LT |
4 | * |
5 | * Copyright (C) 2004 Anil S Keshavamurthy (anil.s.keshavamurthy@intel.com) | |
6 | * Copyright (C) 2004 Keiichiro Tokunaga (tokunaga.keiich@jp.fujitsu.com) | |
7 | * Copyright (C) 2004 Motoyuki Ito (motoyuki@soft.fujitsu.com) | |
1da177e4 | 8 | * Copyright (C) 2004 FUJITSU LIMITED |
68a67f6c RW |
9 | * Copyright (C) 2004, 2013 Intel Corp. |
10 | * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com> | |
1da177e4 | 11 | */ |
1da177e4 | 12 | #include <linux/acpi.h> |
caa73ea1 | 13 | #include <linux/container.h> |
1da177e4 | 14 | |
2f9b06fc AS |
15 | #include "internal.h" |
16 | ||
1ba90e3a TR |
17 | static const struct acpi_device_id container_device_ids[] = { |
18 | {"ACPI0004", 0}, | |
19 | {"PNP0A05", 0}, | |
20 | {"PNP0A06", 0}, | |
21 | {"", 0}, | |
22 | }; | |
1ba90e3a | 23 | |
a1ec6572 RW |
24 | #ifdef CONFIG_ACPI_CONTAINER |
25 | ||
abda0af4 | 26 | static int check_offline(struct acpi_device *adev, void *not_used) |
caa73ea1 | 27 | { |
abda0af4 RW |
28 | if (acpi_scan_is_offline(adev, false)) |
29 | return 0; | |
caa73ea1 | 30 | |
abda0af4 RW |
31 | return -EBUSY; |
32 | } | |
caa73ea1 | 33 | |
abda0af4 RW |
34 | static int acpi_container_offline(struct container_dev *cdev) |
35 | { | |
36 | /* Check all of the dependent devices' physical companions. */ | |
37 | return acpi_dev_for_each_child(ACPI_COMPANION(&cdev->dev), check_offline, NULL); | |
caa73ea1 RW |
38 | } |
39 | ||
40 | static void acpi_container_release(struct device *dev) | |
41 | { | |
42 | kfree(to_container_dev(dev)); | |
43 | } | |
44 | ||
46394fd0 | 45 | static int container_device_attach(struct acpi_device *adev, |
737f1a9f RW |
46 | const struct acpi_device_id *not_used) |
47 | { | |
caa73ea1 RW |
48 | struct container_dev *cdev; |
49 | struct device *dev; | |
50 | int ret; | |
51 | ||
1e2380cd RW |
52 | if (adev->flags.is_dock_station) |
53 | return 0; | |
54 | ||
caa73ea1 RW |
55 | cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); |
56 | if (!cdev) | |
57 | return -ENOMEM; | |
58 | ||
59 | cdev->offline = acpi_container_offline; | |
60 | dev = &cdev->dev; | |
61 | dev->bus = &container_subsys; | |
62 | dev_set_name(dev, "%s", dev_name(&adev->dev)); | |
63 | ACPI_COMPANION_SET(dev, adev); | |
64 | dev->release = acpi_container_release; | |
65 | ret = device_register(dev); | |
0f6aa09e RW |
66 | if (ret) { |
67 | put_device(dev); | |
caa73ea1 | 68 | return ret; |
0f6aa09e | 69 | } |
caa73ea1 | 70 | adev->driver_data = dev; |
737f1a9f RW |
71 | return 1; |
72 | } | |
73 | ||
46394fd0 RW |
74 | static void container_device_detach(struct acpi_device *adev) |
75 | { | |
caa73ea1 RW |
76 | struct device *dev = acpi_driver_data(adev); |
77 | ||
78 | adev->driver_data = NULL; | |
79 | if (dev) | |
80 | device_unregister(dev); | |
46394fd0 RW |
81 | } |
82 | ||
8ab17fc9 RW |
83 | static void container_device_online(struct acpi_device *adev) |
84 | { | |
85 | struct device *dev = acpi_driver_data(adev); | |
86 | ||
87 | kobject_uevent(&dev->kobj, KOBJ_ONLINE); | |
88 | } | |
89 | ||
79917f34 | 90 | static struct acpi_scan_handler container_handler = { |
1ba90e3a | 91 | .ids = container_device_ids, |
737f1a9f | 92 | .attach = container_device_attach, |
46394fd0 | 93 | .detach = container_device_detach, |
68a67f6c RW |
94 | .hotplug = { |
95 | .enabled = true, | |
caa73ea1 | 96 | .demand_offline = true, |
8ab17fc9 | 97 | .notify_online = container_device_online, |
68a67f6c | 98 | }, |
1da177e4 LT |
99 | }; |
100 | ||
a1ec6572 RW |
101 | void __init acpi_container_init(void) |
102 | { | |
103 | acpi_scan_add_handler(&container_handler); | |
104 | } | |
105 | ||
106 | #else | |
107 | ||
108 | static struct acpi_scan_handler container_handler = { | |
109 | .ids = container_device_ids, | |
110 | }; | |
111 | ||
737f1a9f | 112 | void __init acpi_container_init(void) |
1da177e4 | 113 | { |
79917f34 | 114 | acpi_scan_add_handler_with_hotplug(&container_handler, "container"); |
1da177e4 | 115 | } |
a1ec6572 RW |
116 | |
117 | #endif /* CONFIG_ACPI_CONTAINER */ |