aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-02-08 17:52:39 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-02-13 07:43:01 -0500
commit737f1a9f808280c481681b1f46254fd67023ec2f (patch)
treea805f30902127567f74772276a06a2242346f31f
parent38475b3be1517a16d263b0b04dae862bf7027d48 (diff)
ACPI / scan: Make container driver use struct acpi_scan_handler
Make the ACPI container driver use struct acpi_scan_handler for representing the object used to initialize ACPI containers and remove the ACPI driver structure used previously and the data structures created by it, since in fact they were not used for any purpose. This simplifies the code and reduces the kernel's memory footprint by avoiding the registration of a struct device_driver object with the driver core and creation of its sysfs directory which is unnecessary. In addition to that, make the namespace walk callback used for installing the notify handlers for ACPI containers more straightforward. This change includes fixes from Toshi Kani. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Yinghai Lu <yinghai@kernel.org> Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> Tested-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> Reviewed-by: Toshi Kani <toshi.kani@hp.com> Tested-by: Toshi Kani <toshi.kani@hp.com>
-rw-r--r--drivers/acpi/Kconfig2
-rw-r--r--drivers/acpi/container.c167
-rw-r--r--drivers/acpi/internal.h5
-rw-r--r--drivers/acpi/scan.c1
4 files changed, 43 insertions, 132 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 38c5078da11d..78105b3a5262 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -337,7 +337,7 @@ config X86_PM_TIMER
337 systems require this timer. 337 systems require this timer.
338 338
339config ACPI_CONTAINER 339config ACPI_CONTAINER
340 tristate "Container and Module Devices (EXPERIMENTAL)" 340 bool "Container and Module Devices (EXPERIMENTAL)"
341 depends on EXPERIMENTAL 341 depends on EXPERIMENTAL
342 default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO) 342 default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO)
343 help 343 help
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index cc0bf4613e0d..9053e86e9904 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -38,42 +38,31 @@
38 38
39#define PREFIX "ACPI: " 39#define PREFIX "ACPI: "
40 40
41#define ACPI_CONTAINER_DEVICE_NAME "ACPI container device"
42#define ACPI_CONTAINER_CLASS "container"
43
44#define INSTALL_NOTIFY_HANDLER 1
45#define UNINSTALL_NOTIFY_HANDLER 2
46
47#define _COMPONENT ACPI_CONTAINER_COMPONENT 41#define _COMPONENT ACPI_CONTAINER_COMPONENT
48ACPI_MODULE_NAME("container"); 42ACPI_MODULE_NAME("container");
49 43
50MODULE_AUTHOR("Anil S Keshavamurthy");
51MODULE_DESCRIPTION("ACPI container driver");
52MODULE_LICENSE("GPL");
53
54static int acpi_container_add(struct acpi_device *device);
55static int acpi_container_remove(struct acpi_device *device);
56
57static const struct acpi_device_id container_device_ids[] = { 44static const struct acpi_device_id container_device_ids[] = {
58 {"ACPI0004", 0}, 45 {"ACPI0004", 0},
59 {"PNP0A05", 0}, 46 {"PNP0A05", 0},
60 {"PNP0A06", 0}, 47 {"PNP0A06", 0},
61 {"", 0}, 48 {"", 0},
62}; 49};
63MODULE_DEVICE_TABLE(acpi, container_device_ids);
64 50
65static struct acpi_driver acpi_container_driver = { 51static int container_device_attach(struct acpi_device *device,
66 .name = "container", 52 const struct acpi_device_id *not_used)
67 .class = ACPI_CONTAINER_CLASS, 53{
54 /*
55 * FIXME: This is necessary, so that acpi_eject_store() doesn't return
56 * -ENODEV for containers.
57 */
58 return 1;
59}
60
61static struct acpi_scan_handler container_device_handler = {
68 .ids = container_device_ids, 62 .ids = container_device_ids,
69 .ops = { 63 .attach = container_device_attach,
70 .add = acpi_container_add,
71 .remove = acpi_container_remove,
72 },
73}; 64};
74 65
75/*******************************************************************/
76
77static int is_device_present(acpi_handle handle) 66static int is_device_present(acpi_handle handle)
78{ 67{
79 acpi_handle temp; 68 acpi_handle temp;
@@ -92,49 +81,6 @@ static int is_device_present(acpi_handle handle)
92 return ((sta & ACPI_STA_DEVICE_PRESENT) == ACPI_STA_DEVICE_PRESENT); 81 return ((sta & ACPI_STA_DEVICE_PRESENT) == ACPI_STA_DEVICE_PRESENT);
93} 82}
94 83
95static bool is_container_device(const char *hid)
96{
97 const struct acpi_device_id *container_id;
98
99 for (container_id = container_device_ids;
100 container_id->id[0]; container_id++) {
101 if (!strcmp((char *)container_id->id, hid))
102 return true;
103 }
104
105 return false;
106}
107
108/*******************************************************************/
109static int acpi_container_add(struct acpi_device *device)
110{
111 struct acpi_container *container;
112
113 container = kzalloc(sizeof(struct acpi_container), GFP_KERNEL);
114 if (!container)
115 return -ENOMEM;
116
117 container->handle = device->handle;
118 strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME);
119 strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS);
120 device->driver_data = container;
121
122 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device <%s> bid <%s>\n",
123 acpi_device_name(device), acpi_device_bid(device)));
124
125 return 0;
126}
127
128static int acpi_container_remove(struct acpi_device *device)
129{
130 acpi_status status = AE_OK;
131 struct acpi_container *pc = NULL;
132
133 pc = acpi_driver_data(device);
134 kfree(pc);
135 return status;
136}
137
138static void container_notify_cb(acpi_handle handle, u32 type, void *context) 84static void container_notify_cb(acpi_handle handle, u32 type, void *context)
139{ 85{
140 struct acpi_device *device = NULL; 86 struct acpi_device *device = NULL;
@@ -199,84 +145,43 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
199 return; 145 return;
200} 146}
201 147
202static acpi_status 148static bool is_container(acpi_handle handle)
203container_walk_namespace_cb(acpi_handle handle,
204 u32 lvl, void *context, void **rv)
205{ 149{
206 char *hid = NULL;
207 struct acpi_device_info *info; 150 struct acpi_device_info *info;
208 acpi_status status; 151 bool ret = false;
209 int *action = context;
210
211 status = acpi_get_object_info(handle, &info);
212 if (ACPI_FAILURE(status)) {
213 return AE_OK;
214 }
215 152
216 if (info->valid & ACPI_VALID_HID) 153 if (ACPI_FAILURE(acpi_get_object_info(handle, &info)))
217 hid = info->hardware_id.string; 154 return false;
218 155
219 if (hid == NULL) { 156 if (info->valid & ACPI_VALID_HID) {
220 goto end; 157 const struct acpi_device_id *id;
221 }
222
223 if (!is_container_device(hid))
224 goto end;
225 158
226 switch (*action) { 159 for (id = container_device_ids; id->id[0]; id++) {
227 case INSTALL_NOTIFY_HANDLER: 160 ret = !strcmp((char *)id->id, info->hardware_id.string);
228 acpi_install_notify_handler(handle, 161 if (ret)
229 ACPI_SYSTEM_NOTIFY, 162 break;
230 container_notify_cb, NULL); 163 }
231 break;
232 case UNINSTALL_NOTIFY_HANDLER:
233 acpi_remove_notify_handler(handle,
234 ACPI_SYSTEM_NOTIFY,
235 container_notify_cb);
236 break;
237 default:
238 break;
239 } 164 }
240
241 end:
242 kfree(info); 165 kfree(info);
243 166 return ret;
244 return AE_OK;
245} 167}
246 168
247static int __init acpi_container_init(void) 169static acpi_status acpi_container_register_notify_handler(acpi_handle handle,
170 u32 lvl, void *ctxt,
171 void **retv)
248{ 172{
249 int result = 0; 173 if (is_container(handle))
250 int action = INSTALL_NOTIFY_HANDLER; 174 acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
251 175 container_notify_cb, NULL);
252 result = acpi_bus_register_driver(&acpi_container_driver);
253 if (result < 0) {
254 return (result);
255 }
256
257 /* register notify handler to every container device */
258 acpi_walk_namespace(ACPI_TYPE_DEVICE,
259 ACPI_ROOT_OBJECT,
260 ACPI_UINT32_MAX,
261 container_walk_namespace_cb, NULL, &action, NULL);
262 176
263 return (0); 177 return AE_OK;
264} 178}
265 179
266static void __exit acpi_container_exit(void) 180void __init acpi_container_init(void)
267{ 181{
268 int action = UNINSTALL_NOTIFY_HANDLER; 182 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
269 183 acpi_container_register_notify_handler, NULL,
270 184 NULL, NULL);
271 acpi_walk_namespace(ACPI_TYPE_DEVICE,
272 ACPI_ROOT_OBJECT,
273 ACPI_UINT32_MAX,
274 container_walk_namespace_cb, NULL, &action, NULL);
275 185
276 acpi_bus_unregister_driver(&acpi_container_driver); 186 acpi_scan_add_handler(&container_device_handler);
277
278 return;
279} 187}
280
281module_init(acpi_container_init);
282module_exit(acpi_container_exit);
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 0d1397dc7003..79092328cf06 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -30,6 +30,11 @@ void acpi_pci_link_init(void);
30void acpi_platform_init(void); 30void acpi_platform_init(void);
31int acpi_sysfs_init(void); 31int acpi_sysfs_init(void);
32void acpi_csrt_init(void); 32void acpi_csrt_init(void);
33#ifdef CONFIG_ACPI_CONTAINER
34void acpi_container_init(void);
35#else
36static inline void acpi_container_init(void) {}
37#endif
33 38
34#ifdef CONFIG_DEBUG_FS 39#ifdef CONFIG_DEBUG_FS
35extern struct dentry *acpi_debugfs_dir; 40extern struct dentry *acpi_debugfs_dir;
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 5bc2641fba8a..a48b6e92f9f8 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1758,6 +1758,7 @@ int __init acpi_scan_init(void)
1758 acpi_pci_link_init(); 1758 acpi_pci_link_init();
1759 acpi_platform_init(); 1759 acpi_platform_init();
1760 acpi_csrt_init(); 1760 acpi_csrt_init();
1761 acpi_container_init();
1761 1762
1762 /* 1763 /*
1763 * Enumerate devices in the ACPI namespace. 1764 * Enumerate devices in the ACPI namespace.