aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Kconfig37
-rw-r--r--drivers/acpi/Makefile5
-rw-r--r--drivers/acpi/battery.c4
-rw-r--r--drivers/acpi/bay.c490
-rw-r--r--drivers/acpi/bus.c2
-rw-r--r--drivers/acpi/button.c2
-rw-r--r--drivers/acpi/container.c6
-rw-r--r--drivers/acpi/debug.c62
-rw-r--r--drivers/acpi/dock.c16
-rw-r--r--drivers/acpi/fan.c8
-rw-r--r--drivers/acpi/glue.c123
-rw-r--r--drivers/acpi/motherboard.c191
-rw-r--r--drivers/acpi/osl.c48
-rw-r--r--drivers/acpi/pci_root.c38
-rw-r--r--drivers/acpi/processor_core.c8
-rw-r--r--drivers/acpi/scan.c1261
-rw-r--r--drivers/acpi/system.c24
-rw-r--r--drivers/acpi/thermal.c4
-rw-r--r--drivers/acpi/video.c166
19 files changed, 1419 insertions, 1076 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index f4f000abc4e9..20eacc2c9e0e 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -3,6 +3,7 @@
3# 3#
4 4
5menu "ACPI (Advanced Configuration and Power Interface) Support" 5menu "ACPI (Advanced Configuration and Power Interface) Support"
6 depends on !X86_NUMAQ
6 depends on !X86_VISWS 7 depends on !X86_VISWS
7 depends on !IA64_HP_SIM 8 depends on !IA64_HP_SIM
8 depends on IA64 || X86 9 depends on IA64 || X86
@@ -77,6 +78,20 @@ config ACPI_SLEEP_PROC_SLEEP
77 Create /proc/acpi/sleep 78 Create /proc/acpi/sleep
78 Deprecated by /sys/power/state 79 Deprecated by /sys/power/state
79 80
81config ACPI_PROCFS
82 bool "Procfs interface (deprecated)"
83 depends on ACPI
84 default y
85 ---help---
86 Procfs interface for ACPI is made optional for back-compatible.
87 As the same functions are duplicated in sysfs interface
88 and this proc interface will be removed some time later,
89 it's marked as deprecated.
90 ( /proc/acpi/debug_layer && debug_level are deprecated by
91 /sys/module/acpi/parameters/debug_layer && debug_level.
92 /proc/acpi/info is deprecated by
93 /sys/module/acpi/parameters/acpica_version )
94
80config ACPI_AC 95config ACPI_AC
81 tristate "AC Adapter" 96 tristate "AC Adapter"
82 depends on X86 97 depends on X86
@@ -107,7 +122,7 @@ config ACPI_BUTTON
107 122
108config ACPI_VIDEO 123config ACPI_VIDEO
109 tristate "Video" 124 tristate "Video"
110 depends on X86 125 depends on X86 && BACKLIGHT_CLASS_DEVICE
111 help 126 help
112 This driver implement the ACPI Extensions For Display Adapters 127 This driver implement the ACPI Extensions For Display Adapters
113 for integrated graphics devices on motherboard, as specified in 128 for integrated graphics devices on motherboard, as specified in
@@ -139,6 +154,13 @@ config ACPI_DOCK
139 help 154 help
140 This driver adds support for ACPI controlled docking stations 155 This driver adds support for ACPI controlled docking stations
141 156
157config ACPI_BAY
158 tristate "Removable Drive Bay (EXPERIMENTAL)"
159 depends on EXPERIMENTAL
160 help
161 This driver adds support for ACPI controlled removable drive
162 bays such as the IBM ultrabay or the Dell Module Bay.
163
142config ACPI_PROCESSOR 164config ACPI_PROCESSOR
143 tristate "Processor" 165 tristate "Processor"
144 default y 166 default y
@@ -186,19 +208,22 @@ config ACPI_ASUS
186 208
187 Note: display switching code is currently considered EXPERIMENTAL, 209 Note: display switching code is currently considered EXPERIMENTAL,
188 toying with these values may even lock your machine. 210 toying with these values may even lock your machine.
189 211
190 All settings are changed via /proc/acpi/asus directory entries. Owner 212 All settings are changed via /proc/acpi/asus directory entries. Owner
191 and group for these entries can be set with asus_uid and asus_gid 213 and group for these entries can be set with asus_uid and asus_gid
192 parameters. 214 parameters.
193 215
194 More information and a userspace daemon for handling the extra buttons 216 More information and a userspace daemon for handling the extra buttons
195 at <http://sourceforge.net/projects/acpi4asus/>. 217 at <http://sourceforge.net/projects/acpi4asus/>.
196 218
197 If you have an ACPI-compatible ASUS laptop, say Y or M here. This 219 If you have an ACPI-compatible ASUS laptop, say Y or M here. This
198 driver is still under development, so if your laptop is unsupported or 220 driver is still under development, so if your laptop is unsupported or
199 something works not quite as expected, please use the mailing list 221 something works not quite as expected, please use the mailing list
200 available on the above page (acpi4asus-user@lists.sourceforge.net) 222 available on the above page (acpi4asus-user@lists.sourceforge.net).
201 223
224 NOTE: This driver is deprecated and will probably be removed soon,
225 use asus-laptop instead.
226
202config ACPI_IBM 227config ACPI_IBM
203 tristate "IBM ThinkPad Laptop Extras" 228 tristate "IBM ThinkPad Laptop Extras"
204 depends on X86 229 depends on X86
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index bce7ca27b429..856c32bccacb 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -37,13 +37,15 @@ endif
37 37
38obj-y += sleep/ 38obj-y += sleep/
39obj-y += bus.o glue.o 39obj-y += bus.o glue.o
40obj-y += scan.o
40obj-$(CONFIG_ACPI_AC) += ac.o 41obj-$(CONFIG_ACPI_AC) += ac.o
41obj-$(CONFIG_ACPI_BATTERY) += battery.o 42obj-$(CONFIG_ACPI_BATTERY) += battery.o
42obj-$(CONFIG_ACPI_BUTTON) += button.o 43obj-$(CONFIG_ACPI_BUTTON) += button.o
43obj-$(CONFIG_ACPI_EC) += ec.o 44obj-$(CONFIG_ACPI_EC) += ec.o
44obj-$(CONFIG_ACPI_FAN) += fan.o 45obj-$(CONFIG_ACPI_FAN) += fan.o
45obj-$(CONFIG_ACPI_DOCK) += dock.o 46obj-$(CONFIG_ACPI_DOCK) += dock.o
46obj-$(CONFIG_ACPI_VIDEO) += video.o 47obj-$(CONFIG_ACPI_BAY) += bay.o
48obj-$(CONFIG_ACPI_VIDEO) += video.o
47obj-$(CONFIG_ACPI_HOTKEY) += hotkey.o 49obj-$(CONFIG_ACPI_HOTKEY) += hotkey.o
48obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o 50obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
49obj-$(CONFIG_ACPI_POWER) += power.o 51obj-$(CONFIG_ACPI_POWER) += power.o
@@ -56,7 +58,6 @@ obj-$(CONFIG_ACPI_NUMA) += numa.o
56obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o 58obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o
57obj-$(CONFIG_ACPI_IBM) += ibm_acpi.o 59obj-$(CONFIG_ACPI_IBM) += ibm_acpi.o
58obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o 60obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
59obj-y += scan.o motherboard.o
60obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o 61obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
61obj-y += cm_sbs.o 62obj-y += cm_sbs.o
62obj-$(CONFIG_ACPI_SBS) += i2c_ec.o sbs.o 63obj-$(CONFIG_ACPI_SBS) += i2c_ec.o sbs.o
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 5f43e0d14899..2f4521a48fe7 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -64,7 +64,7 @@ extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
64 64
65static int acpi_battery_add(struct acpi_device *device); 65static int acpi_battery_add(struct acpi_device *device);
66static int acpi_battery_remove(struct acpi_device *device, int type); 66static int acpi_battery_remove(struct acpi_device *device, int type);
67static int acpi_battery_resume(struct acpi_device *device, int status); 67static int acpi_battery_resume(struct acpi_device *device);
68 68
69static struct acpi_driver acpi_battery_driver = { 69static struct acpi_driver acpi_battery_driver = {
70 .name = ACPI_BATTERY_DRIVER_NAME, 70 .name = ACPI_BATTERY_DRIVER_NAME,
@@ -753,7 +753,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
753} 753}
754 754
755/* this is needed to learn about changes made in suspended state */ 755/* this is needed to learn about changes made in suspended state */
756static int acpi_battery_resume(struct acpi_device *device, int state) 756static int acpi_battery_resume(struct acpi_device *device)
757{ 757{
758 struct acpi_battery *battery; 758 struct acpi_battery *battery;
759 759
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c
new file mode 100644
index 000000000000..667fa1dfa1a3
--- /dev/null
+++ b/drivers/acpi/bay.c
@@ -0,0 +1,490 @@
1/*
2 * bay.c - ACPI removable drive bay driver
3 *
4 * Copyright (C) 2006 Kristen Carlson Accardi <kristen.c.accardi@intel.com>
5 *
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 */
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/types.h>
28#include <linux/notifier.h>
29#include <acpi/acpi_bus.h>
30#include <acpi/acpi_drivers.h>
31#include <linux/seq_file.h>
32#include <asm/uaccess.h>
33#include <linux/platform_device.h>
34
35#define ACPI_BAY_DRIVER_NAME "ACPI Removable Drive Bay Driver"
36
37ACPI_MODULE_NAME("bay")
38MODULE_AUTHOR("Kristen Carlson Accardi");
39MODULE_DESCRIPTION(ACPI_BAY_DRIVER_NAME);
40MODULE_LICENSE("GPL");
41#define ACPI_BAY_CLASS "bay"
42#define ACPI_BAY_COMPONENT 0x10000000
43#define _COMPONENT ACPI_BAY_COMPONENT
44#define bay_dprintk(h,s) {\
45 char prefix[80] = {'\0'};\
46 struct acpi_buffer buffer = {sizeof(prefix), prefix};\
47 acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\
48 printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); }
49static void bay_notify(acpi_handle handle, u32 event, void *data);
50static int acpi_bay_add(struct acpi_device *device);
51static int acpi_bay_remove(struct acpi_device *device, int type);
52
53static struct acpi_driver acpi_bay_driver = {
54 .name = ACPI_BAY_DRIVER_NAME,
55 .class = ACPI_BAY_CLASS,
56 .ids = ACPI_BAY_HID,
57 .ops = {
58 .add = acpi_bay_add,
59 .remove = acpi_bay_remove,
60 },
61};
62
63struct bay {
64 acpi_handle handle;
65 char *name;
66 struct list_head list;
67 struct platform_device *pdev;
68};
69
70static LIST_HEAD(drive_bays);
71
72
73/*****************************************************************************
74 * Drive Bay functions *
75 *****************************************************************************/
76/**
77 * is_ejectable - see if a device is ejectable
78 * @handle: acpi handle of the device
79 *
80 * If an acpi object has a _EJ0 method, then it is ejectable
81 */
82static int is_ejectable(acpi_handle handle)
83{
84 acpi_status status;
85 acpi_handle tmp;
86
87 status = acpi_get_handle(handle, "_EJ0", &tmp);
88 if (ACPI_FAILURE(status))
89 return 0;
90 return 1;
91}
92
93/**
94 * bay_present - see if the bay device is present
95 * @bay: the drive bay
96 *
97 * execute the _STA method.
98 */
99static int bay_present(struct bay *bay)
100{
101 unsigned long sta;
102 acpi_status status;
103
104 if (bay) {
105 status = acpi_evaluate_integer(bay->handle, "_STA", NULL, &sta);
106 if (ACPI_SUCCESS(status) && sta)
107 return 1;
108 }
109 return 0;
110}
111
112/**
113 * eject_device - respond to an eject request
114 * @handle - the device to eject
115 *
116 * Call this devices _EJ0 method.
117 */
118static void eject_device(acpi_handle handle)
119{
120 struct acpi_object_list arg_list;
121 union acpi_object arg;
122
123 bay_dprintk(handle, "Ejecting device");
124
125 arg_list.count = 1;
126 arg_list.pointer = &arg;
127 arg.type = ACPI_TYPE_INTEGER;
128 arg.integer.value = 1;
129
130 if (ACPI_FAILURE(acpi_evaluate_object(handle, "_EJ0",
131 &arg_list, NULL)))
132 pr_debug("Failed to evaluate _EJ0!\n");
133}
134
135/*
136 * show_present - read method for "present" file in sysfs
137 */
138static ssize_t show_present(struct device *dev,
139 struct device_attribute *attr, char *buf)
140{
141 struct bay *bay = dev_get_drvdata(dev);
142 return snprintf(buf, PAGE_SIZE, "%d\n", bay_present(bay));
143
144}
145DEVICE_ATTR(present, S_IRUGO, show_present, NULL);
146
147/*
148 * write_eject - write method for "eject" file in sysfs
149 */
150static ssize_t write_eject(struct device *dev, struct device_attribute *attr,
151 const char *buf, size_t count)
152{
153 struct bay *bay = dev_get_drvdata(dev);
154
155 if (!count)
156 return -EINVAL;
157
158 eject_device(bay->handle);
159 return count;
160}
161DEVICE_ATTR(eject, S_IWUSR, NULL, write_eject);
162
163/**
164 * is_ata - see if a device is an ata device
165 * @handle: acpi handle of the device
166 *
167 * If an acpi object has one of 4 ATA ACPI methods defined,
168 * then it is an ATA device
169 */
170static int is_ata(acpi_handle handle)
171{
172 acpi_handle tmp;
173
174 if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) ||
175 (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) ||
176 (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) ||
177 (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp))))
178 return 1;
179
180 return 0;
181}
182
183/**
184 * parent_is_ata(acpi_handle handle)
185 *
186 */
187static int parent_is_ata(acpi_handle handle)
188{
189 acpi_handle phandle;
190
191 if (acpi_get_parent(handle, &phandle))
192 return 0;
193
194 return is_ata(phandle);
195}
196
197/**
198 * is_ejectable_bay - see if a device is an ejectable drive bay
199 * @handle: acpi handle of the device
200 *
201 * If an acpi object is ejectable and has one of the ACPI ATA
202 * methods defined, then we can safely call it an ejectable
203 * drive bay
204 */
205static int is_ejectable_bay(acpi_handle handle)
206{
207 if ((is_ata(handle) || parent_is_ata(handle)) && is_ejectable(handle))
208 return 1;
209 return 0;
210}
211
212/**
213 * eject_removable_drive - try to eject this drive
214 * @dev : the device structure of the drive
215 *
216 * If a device is a removable drive that requires an _EJ0 method
217 * to be executed in order to safely remove from the system, do
218 * it. ATM - always returns success
219 */
220int eject_removable_drive(struct device *dev)
221{
222 acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
223
224 if (handle) {
225 bay_dprintk(handle, "Got device handle");
226 if (is_ejectable_bay(handle))
227 eject_device(handle);
228 } else {
229 printk("No acpi handle for device\n");
230 }
231
232 /* should I return an error code? */
233 return 0;
234}
235EXPORT_SYMBOL_GPL(eject_removable_drive);
236
237static int acpi_bay_add(struct acpi_device *device)
238{
239 bay_dprintk(device->handle, "adding bay device");
240 strcpy(acpi_device_name(device), "Dockable Bay");
241 strcpy(acpi_device_class(device), "bay");
242 return 0;
243}
244
245static int acpi_bay_add_fs(struct bay *bay)
246{
247 int ret;
248 struct device *dev = &bay->pdev->dev;
249
250 ret = device_create_file(dev, &dev_attr_present);
251 if (ret)
252 goto add_fs_err;
253 ret = device_create_file(dev, &dev_attr_eject);
254 if (ret) {
255 device_remove_file(dev, &dev_attr_present);
256 goto add_fs_err;
257 }
258 return 0;
259
260 add_fs_err:
261 bay_dprintk(bay->handle, "Error adding sysfs files\n");
262 return ret;
263}
264
265static void acpi_bay_remove_fs(struct bay *bay)
266{
267 struct device *dev = &bay->pdev->dev;
268
269 /* cleanup sysfs */
270 device_remove_file(dev, &dev_attr_present);
271 device_remove_file(dev, &dev_attr_eject);
272}
273
274static int bay_is_dock_device(acpi_handle handle)
275{
276 acpi_handle parent;
277
278 acpi_get_parent(handle, &parent);
279
280 /* if the device or it's parent is dependent on the
281 * dock, then we are a dock device
282 */
283 return (is_dock_device(handle) || is_dock_device(parent));
284}
285
286static int bay_add(acpi_handle handle, int id)
287{
288 acpi_status status;
289 struct bay *new_bay;
290 struct platform_device *pdev;
291 struct acpi_buffer nbuffer = {ACPI_ALLOCATE_BUFFER, NULL};
292 acpi_get_name(handle, ACPI_FULL_PATHNAME, &nbuffer);
293
294 bay_dprintk(handle, "Adding notify handler");
295
296 /*
297 * Initialize bay device structure
298 */
299 new_bay = kzalloc(GFP_ATOMIC, sizeof(*new_bay));
300 INIT_LIST_HEAD(&new_bay->list);
301 new_bay->handle = handle;
302 new_bay->name = (char *)nbuffer.pointer;
303
304 /* initialize platform device stuff */
305 pdev = platform_device_register_simple(ACPI_BAY_CLASS, id, NULL, 0);
306 if (pdev == NULL) {
307 printk(KERN_ERR PREFIX "Error registering bay device\n");
308 goto bay_add_err;
309 }
310 new_bay->pdev = pdev;
311 platform_set_drvdata(pdev, new_bay);
312
313 if (acpi_bay_add_fs(new_bay)) {
314 platform_device_unregister(new_bay->pdev);
315 goto bay_add_err;
316 }
317
318 /* register for events on this device */
319 status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
320 bay_notify, new_bay);
321 if (ACPI_FAILURE(status)) {
322 printk(KERN_ERR PREFIX "Error installing bay notify handler\n");
323 }
324
325 /* if we are on a dock station, we should register for dock
326 * notifications.
327 */
328 if (bay_is_dock_device(handle)) {
329 bay_dprintk(handle, "Is dependent on dock\n");
330 register_hotplug_dock_device(handle, bay_notify, new_bay);
331 }
332 list_add(&new_bay->list, &drive_bays);
333 printk(KERN_INFO PREFIX "Bay [%s] Added\n", new_bay->name);
334 return 0;
335
336bay_add_err:
337 kfree(new_bay->name);
338 kfree(new_bay);
339 return -ENODEV;
340}
341
342static int acpi_bay_remove(struct acpi_device *device, int type)
343{
344 /*** FIXME: do something here */
345 return 0;
346}
347
348/**
349 * bay_create_acpi_device - add new devices to acpi
350 * @handle - handle of the device to add
351 *
352 * This function will create a new acpi_device for the given
353 * handle if one does not exist already. This should cause
354 * acpi to scan for drivers for the given devices, and call
355 * matching driver's add routine.
356 *
357 * Returns a pointer to the acpi_device corresponding to the handle.
358 */
359static struct acpi_device * bay_create_acpi_device(acpi_handle handle)
360{
361 struct acpi_device *device = NULL;
362 struct acpi_device *parent_device;
363 acpi_handle parent;
364 int ret;
365
366 bay_dprintk(handle, "Trying to get device");
367 if (acpi_bus_get_device(handle, &device)) {
368 /*
369 * no device created for this object,
370 * so we should create one.
371 */
372 bay_dprintk(handle, "No device for handle");
373 acpi_get_parent(handle, &parent);
374 if (acpi_bus_get_device(parent, &parent_device))
375 parent_device = NULL;
376
377 ret = acpi_bus_add(&device, parent_device, handle,
378 ACPI_BUS_TYPE_DEVICE);
379 if (ret) {
380 pr_debug("error adding bus, %x\n",
381 -ret);
382 return NULL;
383 }
384 }
385 return device;
386}
387
388/**
389 * bay_notify - act upon an acpi bay notification
390 * @handle: the bay handle
391 * @event: the acpi event
392 * @data: our driver data struct
393 *
394 */
395static void bay_notify(acpi_handle handle, u32 event, void *data)
396{
397 struct acpi_device *dev;
398
399 bay_dprintk(handle, "Bay event");
400
401 switch(event) {
402 case ACPI_NOTIFY_BUS_CHECK:
403 printk("Bus Check\n");
404 case ACPI_NOTIFY_DEVICE_CHECK:
405 printk("Device Check\n");
406 dev = bay_create_acpi_device(handle);
407 if (dev)
408 acpi_bus_generate_event(dev, event, 0);
409 else
410 printk("No device for generating event\n");
411 /* wouldn't it be a good idea to just rescan SATA
412 * right here?
413 */
414 break;
415 case ACPI_NOTIFY_EJECT_REQUEST:
416 printk("Eject request\n");
417 dev = bay_create_acpi_device(handle);
418 if (dev)
419 acpi_bus_generate_event(dev, event, 0);
420 else
421 printk("No device for generating eventn");
422
423 /* wouldn't it be a good idea to just call the
424 * eject_device here if we were a SATA device?
425 */
426 break;
427 default:
428 printk("unknown event %d\n", event);
429 }
430}
431
432static acpi_status
433find_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
434{
435 int *count = (int *)context;
436
437 /*
438 * there could be more than one ejectable bay.
439 * so, just return AE_OK always so that every object
440 * will be checked.
441 */
442 if (is_ejectable_bay(handle)) {
443 bay_dprintk(handle, "found ejectable bay");
444 if (!bay_add(handle, *count))
445 (*count)++;
446 }
447 return AE_OK;
448}
449
450static int __init bay_init(void)
451{
452 int bays = 0;
453
454 INIT_LIST_HEAD(&drive_bays);
455
456 /* look for dockable drive bays */
457 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
458 ACPI_UINT32_MAX, find_bay, &bays, NULL);
459
460 if (bays)
461 if ((acpi_bus_register_driver(&acpi_bay_driver) < 0))
462 printk(KERN_ERR "Unable to register bay driver\n");
463
464 if (!bays)
465 return -ENODEV;
466
467 return 0;
468}
469
470static void __exit bay_exit(void)
471{
472 struct bay *bay, *tmp;
473
474 list_for_each_entry_safe(bay, tmp, &drive_bays, list) {
475 if (is_dock_device(bay->handle))
476 unregister_hotplug_dock_device(bay->handle);
477 acpi_bay_remove_fs(bay);
478 acpi_remove_notify_handler(bay->handle, ACPI_SYSTEM_NOTIFY,
479 bay_notify);
480 platform_device_unregister(bay->pdev);
481 kfree(bay->name);
482 kfree(bay);
483 }
484
485 acpi_bus_unregister_driver(&acpi_bay_driver);
486}
487
488postcore_initcall(bay_init);
489module_exit(bay_exit);
490
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 15d677e6cee9..c26468da4295 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -192,7 +192,7 @@ int acpi_bus_set_power(acpi_handle handle, int state)
192 192
193 if (!device->flags.power_manageable) { 193 if (!device->flags.power_manageable) {
194 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n", 194 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n",
195 device->kobj.name)); 195 device->dev.kobj.name));
196 return -ENODEV; 196 return -ENODEV;
197 } 197 }
198 /* 198 /*
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index ac860583c203..c726612fafb6 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -75,7 +75,7 @@ static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
75static struct acpi_driver acpi_button_driver = { 75static struct acpi_driver acpi_button_driver = {
76 .name = ACPI_BUTTON_DRIVER_NAME, 76 .name = ACPI_BUTTON_DRIVER_NAME,
77 .class = ACPI_BUTTON_CLASS, 77 .class = ACPI_BUTTON_CLASS,
78 .ids = "ACPI_FPB,ACPI_FSB,PNP0C0D,PNP0C0C,PNP0C0E", 78 .ids = "button_power,button_sleep,PNP0C0D,PNP0C0C,PNP0C0E",
79 .ops = { 79 .ops = {
80 .add = acpi_button_add, 80 .add = acpi_button_add,
81 .remove = acpi_button_remove, 81 .remove = acpi_button_remove,
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 0a1863ec91f3..69a68fd394cf 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -167,7 +167,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
167 if (ACPI_FAILURE(status) || !device) { 167 if (ACPI_FAILURE(status) || !device) {
168 result = container_device_add(&device, handle); 168 result = container_device_add(&device, handle);
169 if (!result) 169 if (!result)
170 kobject_uevent(&device->kobj, 170 kobject_uevent(&device->dev.kobj,
171 KOBJ_ONLINE); 171 KOBJ_ONLINE);
172 else 172 else
173 printk("Failed to add container\n"); 173 printk("Failed to add container\n");
@@ -175,13 +175,13 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
175 } else { 175 } else {
176 if (ACPI_SUCCESS(status)) { 176 if (ACPI_SUCCESS(status)) {
177 /* device exist and this is a remove request */ 177 /* device exist and this is a remove request */
178 kobject_uevent(&device->kobj, KOBJ_OFFLINE); 178 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
179 } 179 }
180 } 180 }
181 break; 181 break;
182 case ACPI_NOTIFY_EJECT_REQUEST: 182 case ACPI_NOTIFY_EJECT_REQUEST:
183 if (!acpi_bus_get_device(handle, &device) && device) { 183 if (!acpi_bus_get_device(handle, &device) && device) {
184 kobject_uevent(&device->kobj, KOBJ_OFFLINE); 184 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
185 } 185 }
186 break; 186 break;
187 default: 187 default:
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
index 35c6af8a83cd..d48f65a8f658 100644
--- a/drivers/acpi/debug.c
+++ b/drivers/acpi/debug.c
@@ -13,14 +13,11 @@
13 13
14#define _COMPONENT ACPI_SYSTEM_COMPONENT 14#define _COMPONENT ACPI_SYSTEM_COMPONENT
15ACPI_MODULE_NAME("debug") 15ACPI_MODULE_NAME("debug")
16#define ACPI_SYSTEM_FILE_DEBUG_LAYER "debug_layer" 16
17#define ACPI_SYSTEM_FILE_DEBUG_LEVEL "debug_level"
18#ifdef MODULE_PARAM_PREFIX 17#ifdef MODULE_PARAM_PREFIX
19#undef MODULE_PARAM_PREFIX 18#undef MODULE_PARAM_PREFIX
20#endif 19#endif
21#define MODULE_PARAM_PREFIX 20#define MODULE_PARAM_PREFIX "acpi."
22 module_param(acpi_dbg_layer, uint, 0400);
23module_param(acpi_dbg_level, uint, 0400);
24 21
25struct acpi_dlayer { 22struct acpi_dlayer {
26 const char *name; 23 const char *name;
@@ -86,6 +83,60 @@ static const struct acpi_dlevel acpi_debug_levels[] = {
86 ACPI_DEBUG_INIT(ACPI_LV_EVENTS), 83 ACPI_DEBUG_INIT(ACPI_LV_EVENTS),
87}; 84};
88 85
86/* --------------------------------------------------------------------------
87 FS Interface (/sys)
88 -------------------------------------------------------------------------- */
89static int param_get_debug_layer(char *buffer, struct kernel_param *kp) {
90 int result = 0;
91 int i;
92
93 result = sprintf(buffer, "%-25s\tHex SET\n", "Description");
94
95 for(i = 0; i <ARRAY_SIZE(acpi_debug_layers); i++) {
96 result += sprintf(buffer+result, "%-25s\t0x%08lX [%c]\n",
97 acpi_debug_layers[i].name,
98 acpi_debug_layers[i].value,
99 (acpi_dbg_layer & acpi_debug_layers[i].value) ? '*' : ' ');
100 }
101 result += sprintf(buffer+result, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS",
102 ACPI_ALL_DRIVERS,
103 (acpi_dbg_layer & ACPI_ALL_DRIVERS) ==
104 ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer &
105 ACPI_ALL_DRIVERS) == 0 ? ' ' : '-');
106 result += sprintf(buffer+result, "--\ndebug_layer = 0x%08X ( * = enabled)\n", acpi_dbg_layer);
107
108 return result;
109}
110
111static int param_get_debug_level(char *buffer, struct kernel_param *kp) {
112 int result = 0;
113 int i;
114
115 result = sprintf(buffer, "%-25s\tHex SET\n", "Description");
116
117 for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) {
118 result += sprintf(buffer+result, "%-25s\t0x%08lX [%c]\n",
119 acpi_debug_levels[i].name,
120 acpi_debug_levels[i].value,
121 (acpi_dbg_level & acpi_debug_levels[i].
122 value) ? '*' : ' ');
123 }
124 result += sprintf(buffer+result, "--\ndebug_level = 0x%08X (* = enabled)\n",
125 acpi_dbg_level);
126
127 return result;
128}
129
130module_param_call(debug_layer, param_set_uint, param_get_debug_layer, &acpi_dbg_layer, 0644);
131module_param_call(debug_level, param_set_uint, param_get_debug_level, &acpi_dbg_level, 0644);
132
133/* --------------------------------------------------------------------------
134 FS Interface (/proc)
135 -------------------------------------------------------------------------- */
136#ifdef CONFIG_ACPI_PROCFS
137#define ACPI_SYSTEM_FILE_DEBUG_LAYER "debug_layer"
138#define ACPI_SYSTEM_FILE_DEBUG_LEVEL "debug_level"
139
89static int 140static int
90acpi_system_read_debug(char *page, 141acpi_system_read_debug(char *page,
91 char **start, off_t off, int count, int *eof, void *data) 142 char **start, off_t off, int count, int *eof, void *data)
@@ -221,3 +272,4 @@ static int __init acpi_debug_init(void)
221} 272}
222 273
223subsys_initcall(acpi_debug_init); 274subsys_initcall(acpi_debug_init);
275#endif
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 90990a4b6526..688e83a16906 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -615,20 +615,28 @@ static acpi_status
615find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv) 615find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv)
616{ 616{
617 acpi_status status; 617 acpi_status status;
618 acpi_handle tmp; 618 acpi_handle tmp, parent;
619 struct dock_station *ds = context; 619 struct dock_station *ds = context;
620 struct dock_dependent_device *dd; 620 struct dock_dependent_device *dd;
621 621
622 status = acpi_bus_get_ejd(handle, &tmp); 622 status = acpi_bus_get_ejd(handle, &tmp);
623 if (ACPI_FAILURE(status)) 623 if (ACPI_FAILURE(status)) {
624 return AE_OK; 624 /* try the parent device as well */
625 status = acpi_get_parent(handle, &parent);
626 if (ACPI_FAILURE(status))
627 goto fdd_out;
628 /* see if parent is dependent on dock */
629 status = acpi_bus_get_ejd(parent, &tmp);
630 if (ACPI_FAILURE(status))
631 goto fdd_out;
632 }
625 633
626 if (tmp == ds->handle) { 634 if (tmp == ds->handle) {
627 dd = alloc_dock_dependent_device(handle); 635 dd = alloc_dock_dependent_device(handle);
628 if (dd) 636 if (dd)
629 add_dock_dependent_device(ds, dd); 637 add_dock_dependent_device(ds, dd);
630 } 638 }
631 639fdd_out:
632 return AE_OK; 640 return AE_OK;
633} 641}
634 642
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index f305a826ca2d..af22fdf73413 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -48,8 +48,8 @@ MODULE_LICENSE("GPL");
48 48
49static int acpi_fan_add(struct acpi_device *device); 49static int acpi_fan_add(struct acpi_device *device);
50static int acpi_fan_remove(struct acpi_device *device, int type); 50static int acpi_fan_remove(struct acpi_device *device, int type);
51static int acpi_fan_suspend(struct acpi_device *device, int state); 51static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state);
52static int acpi_fan_resume(struct acpi_device *device, int state); 52static int acpi_fan_resume(struct acpi_device *device);
53 53
54static struct acpi_driver acpi_fan_driver = { 54static struct acpi_driver acpi_fan_driver = {
55 .name = ACPI_FAN_DRIVER_NAME, 55 .name = ACPI_FAN_DRIVER_NAME,
@@ -237,7 +237,7 @@ static int acpi_fan_remove(struct acpi_device *device, int type)
237 return 0; 237 return 0;
238} 238}
239 239
240static int acpi_fan_suspend(struct acpi_device *device, int state) 240static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state)
241{ 241{
242 if (!device) 242 if (!device)
243 return -EINVAL; 243 return -EINVAL;
@@ -247,7 +247,7 @@ static int acpi_fan_suspend(struct acpi_device *device, int state)
247 return AE_OK; 247 return AE_OK;
248} 248}
249 249
250static int acpi_fan_resume(struct acpi_device *device, int state) 250static int acpi_fan_resume(struct acpi_device *device)
251{ 251{
252 int result = 0; 252 int result = 0;
253 int power_state = 0; 253 int power_state = 0;
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 8a0324b43e53..7b6c9ff9bebe 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -86,129 +86,6 @@ static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle)
86 return ret; 86 return ret;
87} 87}
88 88
89/* Get PCI root bridge's handle from its segment and bus number */
90struct acpi_find_pci_root {
91 unsigned int seg;
92 unsigned int bus;
93 acpi_handle handle;
94};
95
96static acpi_status
97do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
98{
99 unsigned long *busnr = data;
100 struct acpi_resource_address64 address;
101
102 if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
103 resource->type != ACPI_RESOURCE_TYPE_ADDRESS32 &&
104 resource->type != ACPI_RESOURCE_TYPE_ADDRESS64)
105 return AE_OK;
106
107 acpi_resource_to_address64(resource, &address);
108 if ((address.address_length > 0) &&
109 (address.resource_type == ACPI_BUS_NUMBER_RANGE))
110 *busnr = address.minimum;
111
112 return AE_OK;
113}
114
115static int get_root_bridge_busnr(acpi_handle handle)
116{
117 acpi_status status;
118 unsigned long bus, bbn;
119 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
120
121 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
122
123 status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL,
124 &bbn);
125 if (status == AE_NOT_FOUND) {
126 /* Assume bus = 0 */
127 printk(KERN_INFO PREFIX
128 "Assume root bridge [%s] bus is 0\n",
129 (char *)buffer.pointer);
130 status = AE_OK;
131 bbn = 0;
132 }
133 if (ACPI_FAILURE(status)) {
134 bbn = -ENODEV;
135 goto exit;
136 }
137 if (bbn > 0)
138 goto exit;
139
140 /* _BBN in some systems return 0 for all root bridges */
141 bus = -1;
142 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
143 do_root_bridge_busnr_callback, &bus);
144 /* If _CRS failed, we just use _BBN */
145 if (ACPI_FAILURE(status) || (bus == -1))
146 goto exit;
147 /* We select _CRS */
148 if (bbn != bus) {
149 printk(KERN_INFO PREFIX
150 "_BBN and _CRS returns different value for %s. Select _CRS\n",
151 (char *)buffer.pointer);
152 bbn = bus;
153 }
154 exit:
155 kfree(buffer.pointer);
156 return (int)bbn;
157}
158
159static acpi_status
160find_pci_rootbridge(acpi_handle handle, u32 lvl, void *context, void **rv)
161{
162 struct acpi_find_pci_root *find = (struct acpi_find_pci_root *)context;
163 unsigned long seg, bus;
164 acpi_status status;
165 int tmp;
166 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
167
168 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
169
170 status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &seg);
171 if (status == AE_NOT_FOUND) {
172 /* Assume seg = 0 */
173 status = AE_OK;
174 seg = 0;
175 }
176 if (ACPI_FAILURE(status)) {
177 status = AE_CTRL_DEPTH;
178 goto exit;
179 }
180
181 tmp = get_root_bridge_busnr(handle);
182 if (tmp < 0) {
183 printk(KERN_ERR PREFIX
184 "Find root bridge failed for %s\n",
185 (char *)buffer.pointer);
186 status = AE_CTRL_DEPTH;
187 goto exit;
188 }
189 bus = tmp;
190
191 if (seg == find->seg && bus == find->bus)
192 {
193 find->handle = handle;
194 status = AE_CTRL_TERMINATE;
195 }
196 else
197 status = AE_OK;
198 exit:
199 kfree(buffer.pointer);
200 return status;
201}
202
203acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
204{
205 struct acpi_find_pci_root find = { seg, bus, NULL };
206
207 acpi_get_devices(PCI_ROOT_HID_STRING, find_pci_rootbridge, &find, NULL);
208 return find.handle;
209}
210EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
211
212/* Get device's handler per its address under its parent */ 89/* Get device's handler per its address under its parent */
213struct acpi_find_child { 90struct acpi_find_child {
214 acpi_handle handle; 91 acpi_handle handle;
diff --git a/drivers/acpi/motherboard.c b/drivers/acpi/motherboard.c
deleted file mode 100644
index b61107b05262..000000000000
--- a/drivers/acpi/motherboard.c
+++ /dev/null
@@ -1,191 +0,0 @@
1/*
2 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or (at
6 * your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16 *
17 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
18 */
19
20/* Purpose: Prevent PCMCIA cards from using motherboard resources. */
21
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/types.h>
25#include <linux/pci.h>
26#include <linux/ioport.h>
27#include <asm/io.h>
28
29#include <acpi/acpi_bus.h>
30#include <acpi/acpi_drivers.h>
31
32#define _COMPONENT ACPI_SYSTEM_COMPONENT
33ACPI_MODULE_NAME("acpi_motherboard")
34
35/* Dell use PNP0C01 instead of PNP0C02 */
36#define ACPI_MB_HID1 "PNP0C01"
37#define ACPI_MB_HID2 "PNP0C02"
38/**
39 * Doesn't care about legacy IO ports, only IO ports beyond 0x1000 are reserved
40 * Doesn't care about the failure of 'request_region', since other may reserve
41 * the io ports as well
42 */
43#define IS_RESERVED_ADDR(base, len) \
44 (((len) > 0) && ((base) > 0) && ((base) + (len) < IO_SPACE_LIMIT) \
45 && ((base) + (len) > PCIBIOS_MIN_IO))
46/*
47 * Clearing the flag (IORESOURCE_BUSY) allows drivers to use
48 * the io ports if they really know they can use it, while
49 * still preventing hotplug PCI devices from using it.
50 */
51
52/*
53 * When CONFIG_PNP is enabled, pnp/system.c binds to PNP0C01
54 * and PNP0C02, redundant with acpi_reserve_io_ranges().
55 * But acpi_reserve_io_ranges() is necessary for !CONFIG_PNP.
56 */
57static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data)
58{
59 struct resource *requested_res = NULL;
60
61
62 if (res->type == ACPI_RESOURCE_TYPE_IO) {
63 struct acpi_resource_io *io_res = &res->data.io;
64
65 if (io_res->minimum != io_res->maximum)
66 return AE_OK;
67 if (IS_RESERVED_ADDR
68 (io_res->minimum, io_res->address_length)) {
69 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
70 "Motherboard resources 0x%08x - 0x%08x\n",
71 io_res->minimum,
72 io_res->minimum +
73 io_res->address_length));
74 requested_res =
75 request_region(io_res->minimum,
76 io_res->address_length, "motherboard");
77 }
78 } else if (res->type == ACPI_RESOURCE_TYPE_FIXED_IO) {
79 struct acpi_resource_fixed_io *fixed_io_res =
80 &res->data.fixed_io;
81
82 if (IS_RESERVED_ADDR
83 (fixed_io_res->address, fixed_io_res->address_length)) {
84 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
85 "Motherboard resources 0x%08x - 0x%08x\n",
86 fixed_io_res->address,
87 fixed_io_res->address +
88 fixed_io_res->address_length));
89 requested_res =
90 request_region(fixed_io_res->address,
91 fixed_io_res->address_length,
92 "motherboard");
93 }
94 } else {
95 /* Memory mapped IO? */
96 }
97
98 if (requested_res)
99 requested_res->flags &= ~IORESOURCE_BUSY;
100 return AE_OK;
101}
102
103static int acpi_motherboard_add(struct acpi_device *device)
104{
105 if (!device)
106 return -EINVAL;
107 acpi_walk_resources(device->handle, METHOD_NAME__CRS,
108 acpi_reserve_io_ranges, NULL);
109
110 return 0;
111}
112
113static struct acpi_driver acpi_motherboard_driver1 = {
114 .name = "motherboard",
115 .class = "",
116 .ids = ACPI_MB_HID1,
117 .ops = {
118 .add = acpi_motherboard_add,
119 },
120};
121
122static struct acpi_driver acpi_motherboard_driver2 = {
123 .name = "motherboard",
124 .class = "",
125 .ids = ACPI_MB_HID2,
126 .ops = {
127 .add = acpi_motherboard_add,
128 },
129};
130
131static void __init acpi_request_region (struct acpi_generic_address *addr,
132 unsigned int length, char *desc)
133{
134 if (!addr->address || !length)
135 return;
136
137 if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
138 request_region(addr->address, length, desc);
139 else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
140 request_mem_region(addr->address, length, desc);
141}
142
143static void __init acpi_reserve_resources(void)
144{
145 acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block,
146 acpi_gbl_FADT.pm1_event_length, "ACPI PM1a_EVT_BLK");
147
148 acpi_request_region(&acpi_gbl_FADT.xpm1b_event_block,
149 acpi_gbl_FADT.pm1_event_length, "ACPI PM1b_EVT_BLK");
150
151 acpi_request_region(&acpi_gbl_FADT.xpm1a_control_block,
152 acpi_gbl_FADT.pm1_control_length, "ACPI PM1a_CNT_BLK");
153
154 acpi_request_region(&acpi_gbl_FADT.xpm1b_control_block,
155 acpi_gbl_FADT.pm1_control_length, "ACPI PM1b_CNT_BLK");
156
157 if (acpi_gbl_FADT.pm_timer_length == 4)
158 acpi_request_region(&acpi_gbl_FADT.xpm_timer_block, 4, "ACPI PM_TMR");
159
160 acpi_request_region(&acpi_gbl_FADT.xpm2_control_block,
161 acpi_gbl_FADT.pm2_control_length, "ACPI PM2_CNT_BLK");
162
163 /* Length of GPE blocks must be a non-negative multiple of 2 */
164
165 if (!(acpi_gbl_FADT.gpe0_block_length & 0x1))
166 acpi_request_region(&acpi_gbl_FADT.xgpe0_block,
167 acpi_gbl_FADT.gpe0_block_length, "ACPI GPE0_BLK");
168
169 if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
170 acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
171 acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
172}
173
174static int __init acpi_motherboard_init(void)
175{
176 acpi_bus_register_driver(&acpi_motherboard_driver1);
177 acpi_bus_register_driver(&acpi_motherboard_driver2);
178 /*
179 * Guarantee motherboard IO reservation first
180 * This module must run after scan.c
181 */
182 if (!acpi_disabled)
183 acpi_reserve_resources();
184 return 0;
185}
186
187/**
188 * Reserve motherboard resources after PCI claim BARs,
189 * but before PCI assign resources for uninitialized PCI devices
190 */
191fs_initcall(acpi_motherboard_init);
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index a28f5b8972b4..0f6f3bcbc8eb 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -76,6 +76,54 @@ static acpi_osd_handler acpi_irq_handler;
76static void *acpi_irq_context; 76static void *acpi_irq_context;
77static struct workqueue_struct *kacpid_wq; 77static struct workqueue_struct *kacpid_wq;
78 78
79static void __init acpi_request_region (struct acpi_generic_address *addr,
80 unsigned int length, char *desc)
81{
82 struct resource *res;
83
84 if (!addr->address || !length)
85 return;
86
87 if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
88 res = request_region(addr->address, length, desc);
89 else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
90 res = request_mem_region(addr->address, length, desc);
91}
92
93static int __init acpi_reserve_resources(void)
94{
95 acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length,
96 "ACPI PM1a_EVT_BLK");
97
98 acpi_request_region(&acpi_gbl_FADT.xpm1b_event_block, acpi_gbl_FADT.pm1_event_length,
99 "ACPI PM1b_EVT_BLK");
100
101 acpi_request_region(&acpi_gbl_FADT.xpm1a_control_block, acpi_gbl_FADT.pm1_control_length,
102 "ACPI PM1a_CNT_BLK");
103
104 acpi_request_region(&acpi_gbl_FADT.xpm1b_control_block, acpi_gbl_FADT.pm1_control_length,
105 "ACPI PM1b_CNT_BLK");
106
107 if (acpi_gbl_FADT.pm_timer_length == 4)
108 acpi_request_region(&acpi_gbl_FADT.xpm_timer_block, 4, "ACPI PM_TMR");
109
110 acpi_request_region(&acpi_gbl_FADT.xpm2_control_block, acpi_gbl_FADT.pm2_control_length,
111 "ACPI PM2_CNT_BLK");
112
113 /* Length of GPE blocks must be a non-negative multiple of 2 */
114
115 if (!(acpi_gbl_FADT.gpe0_block_length & 0x1))
116 acpi_request_region(&acpi_gbl_FADT.xgpe0_block,
117 acpi_gbl_FADT.gpe0_block_length, "ACPI GPE0_BLK");
118
119 if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
120 acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
121 acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
122
123 return 0;
124}
125device_initcall(acpi_reserve_resources);
126
79acpi_status acpi_os_initialize(void) 127acpi_status acpi_os_initialize(void)
80{ 128{
81 return AE_OK; 129 return AE_OK;
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index a860efa2c562..4ecf701687e8 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -117,6 +117,19 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
117 117
118EXPORT_SYMBOL(acpi_pci_unregister_driver); 118EXPORT_SYMBOL(acpi_pci_unregister_driver);
119 119
120acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
121{
122 struct acpi_pci_root *tmp;
123
124 list_for_each_entry(tmp, &acpi_pci_roots, node) {
125 if ((tmp->id.segment == (u16) seg) && (tmp->id.bus == (u16) bus))
126 return tmp->device->handle;
127 }
128 return NULL;
129}
130
131EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
132
120static acpi_status 133static acpi_status
121get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) 134get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
122{ 135{
@@ -152,6 +165,21 @@ static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum)
152 return AE_OK; 165 return AE_OK;
153} 166}
154 167
168static void acpi_pci_bridge_scan(struct acpi_device *device)
169{
170 int status;
171 struct acpi_device *child = NULL;
172
173 if (device->flags.bus_address)
174 if (device->parent && device->parent->ops.bind) {
175 status = device->parent->ops.bind(device);
176 if (!status) {
177 list_for_each_entry(child, &device->children, node)
178 acpi_pci_bridge_scan(child);
179 }
180 }
181}
182
155static int acpi_pci_root_add(struct acpi_device *device) 183static int acpi_pci_root_add(struct acpi_device *device)
156{ 184{
157 int result = 0; 185 int result = 0;
@@ -160,6 +188,7 @@ static int acpi_pci_root_add(struct acpi_device *device)
160 acpi_status status = AE_OK; 188 acpi_status status = AE_OK;
161 unsigned long value = 0; 189 unsigned long value = 0;
162 acpi_handle handle = NULL; 190 acpi_handle handle = NULL;
191 struct acpi_device *child;
163 192
164 193
165 if (!device) 194 if (!device)
@@ -175,9 +204,6 @@ static int acpi_pci_root_add(struct acpi_device *device)
175 strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); 204 strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
176 acpi_driver_data(device) = root; 205 acpi_driver_data(device) = root;
177 206
178 /*
179 * TBD: Doesn't the bus driver automatically set this?
180 */
181 device->ops.bind = acpi_pci_bind; 207 device->ops.bind = acpi_pci_bind;
182 208
183 /* 209 /*
@@ -299,6 +325,12 @@ static int acpi_pci_root_add(struct acpi_device *device)
299 result = acpi_pci_irq_add_prt(device->handle, root->id.segment, 325 result = acpi_pci_irq_add_prt(device->handle, root->id.segment,
300 root->id.bus); 326 root->id.bus);
301 327
328 /*
329 * Scan and bind all _ADR-Based Devices
330 */
331 list_for_each_entry(child, &device->children, node)
332 acpi_pci_bridge_scan(child);
333
302 end: 334 end:
303 if (result) { 335 if (result) {
304 if (!list_empty(&root->node)) 336 if (!list_empty(&root->node))
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index eacf9a252019..0079bc51082c 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -814,7 +814,7 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
814 return -ENODEV; 814 return -ENODEV;
815 815
816 if ((pr->id >= 0) && (pr->id < NR_CPUS)) { 816 if ((pr->id >= 0) && (pr->id < NR_CPUS)) {
817 kobject_uevent(&(*device)->kobj, KOBJ_ONLINE); 817 kobject_uevent(&(*device)->dev.kobj, KOBJ_ONLINE);
818 } 818 }
819 return 0; 819 return 0;
820} 820}
@@ -852,13 +852,13 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
852 } 852 }
853 853
854 if (pr->id >= 0 && (pr->id < NR_CPUS)) { 854 if (pr->id >= 0 && (pr->id < NR_CPUS)) {
855 kobject_uevent(&device->kobj, KOBJ_OFFLINE); 855 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
856 break; 856 break;
857 } 857 }
858 858
859 result = acpi_processor_start(device); 859 result = acpi_processor_start(device);
860 if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) { 860 if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) {
861 kobject_uevent(&device->kobj, KOBJ_ONLINE); 861 kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
862 } else { 862 } else {
863 printk(KERN_ERR PREFIX "Device [%s] failed to start\n", 863 printk(KERN_ERR PREFIX "Device [%s] failed to start\n",
864 acpi_device_bid(device)); 864 acpi_device_bid(device));
@@ -881,7 +881,7 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
881 } 881 }
882 882
883 if ((pr->id < NR_CPUS) && (cpu_present(pr->id))) 883 if ((pr->id < NR_CPUS) && (cpu_present(pr->id)))
884 kobject_uevent(&device->kobj, KOBJ_OFFLINE); 884 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
885 break; 885 break;
886 default: 886 default:
887 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 887 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 0de458664642..64f26db10c8e 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -21,101 +21,305 @@ extern struct acpi_device *acpi_root;
21#define ACPI_BUS_DEVICE_NAME "System Bus" 21#define ACPI_BUS_DEVICE_NAME "System Bus"
22 22
23static LIST_HEAD(acpi_device_list); 23static LIST_HEAD(acpi_device_list);
24static LIST_HEAD(acpi_bus_id_list);
24DEFINE_SPINLOCK(acpi_device_lock); 25DEFINE_SPINLOCK(acpi_device_lock);
25LIST_HEAD(acpi_wakeup_device_list); 26LIST_HEAD(acpi_wakeup_device_list);
26 27
28struct acpi_device_bus_id{
29 char bus_id[15];
30 unsigned int instance_no;
31 struct list_head node;
32};
33static int acpi_eject_operation(acpi_handle handle, int lockable)
34{
35 struct acpi_object_list arg_list;
36 union acpi_object arg;
37 acpi_status status = AE_OK;
38
39 /*
40 * TBD: evaluate _PS3?
41 */
42
43 if (lockable) {
44 arg_list.count = 1;
45 arg_list.pointer = &arg;
46 arg.type = ACPI_TYPE_INTEGER;
47 arg.integer.value = 0;
48 acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
49 }
50
51 arg_list.count = 1;
52 arg_list.pointer = &arg;
53 arg.type = ACPI_TYPE_INTEGER;
54 arg.integer.value = 1;
55
56 /*
57 * TBD: _EJD support.
58 */
59
60 status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
61 if (ACPI_FAILURE(status)) {
62 return (-ENODEV);
63 }
64
65 return (0);
66}
27 67
28static void acpi_device_release(struct kobject *kobj) 68static ssize_t
69acpi_eject_store(struct device *d, struct device_attribute *attr,
70 const char *buf, size_t count)
29{ 71{
30 struct acpi_device *dev = container_of(kobj, struct acpi_device, kobj); 72 int result;
31 kfree(dev->pnp.cid_list); 73 int ret = count;
32 kfree(dev); 74 int islockable;
75 acpi_status status;
76 acpi_handle handle;
77 acpi_object_type type = 0;
78 struct acpi_device *acpi_device = to_acpi_device(d);
79
80 if ((!count) || (buf[0] != '1')) {
81 return -EINVAL;
82 }
83#ifndef FORCE_EJECT
84 if (acpi_device->driver == NULL) {
85 ret = -ENODEV;
86 goto err;
87 }
88#endif
89 status = acpi_get_type(acpi_device->handle, &type);
90 if (ACPI_FAILURE(status) || (!acpi_device->flags.ejectable)) {
91 ret = -ENODEV;
92 goto err;
93 }
94
95 islockable = acpi_device->flags.lockable;
96 handle = acpi_device->handle;
97
98 result = acpi_bus_trim(acpi_device, 1);
99
100 if (!result)
101 result = acpi_eject_operation(handle, islockable);
102
103 if (result) {
104 ret = -EBUSY;
105 }
106 err:
107 return ret;
33} 108}
34 109
35struct acpi_device_attribute { 110static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
36 struct attribute attr; 111
37 ssize_t(*show) (struct acpi_device *, char *); 112static ssize_t
38 ssize_t(*store) (struct acpi_device *, const char *, size_t); 113acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) {
39}; 114 struct acpi_device *acpi_dev = to_acpi_device(dev);
115
116 return sprintf(buf, "%s\n", acpi_dev->pnp.hardware_id);
117}
118static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL);
119
120static ssize_t
121acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) {
122 struct acpi_device *acpi_dev = to_acpi_device(dev);
123 struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
124 int result;
125
126 result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path);
127 if(result)
128 goto end;
129
130 result = sprintf(buf, "%s\n", (char*)path.pointer);
131 kfree(path.pointer);
132 end:
133 return result;
134}
135static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL);
136
137static int acpi_device_setup_files(struct acpi_device *dev)
138{
139 acpi_status status;
140 acpi_handle temp;
141 int result = 0;
142
143 /*
144 * Devices gotten from FADT don't have a "path" attribute
145 */
146 if(dev->handle) {
147 result = device_create_file(&dev->dev, &dev_attr_path);
148 if(result)
149 goto end;
150 }
40 151
41typedef void acpi_device_sysfs_files(struct kobject *, 152 if(dev->flags.hardware_id) {
42 const struct attribute *); 153 result = device_create_file(&dev->dev, &dev_attr_hid);
154 if(result)
155 goto end;
156 }
43 157
44static void setup_sys_fs_device_files(struct acpi_device *dev, 158 /*
45 acpi_device_sysfs_files * func); 159 * If device has _EJ0, 'eject' file is created that is used to trigger
160 * hot-removal function from userland.
161 */
162 status = acpi_get_handle(dev->handle, "_EJ0", &temp);
163 if (ACPI_SUCCESS(status))
164 result = device_create_file(&dev->dev, &dev_attr_eject);
165 end:
166 return result;
167}
46 168
47#define create_sysfs_device_files(dev) \ 169static void acpi_device_remove_files(struct acpi_device *dev)
48 setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_create_file) 170{
49#define remove_sysfs_device_files(dev) \ 171 acpi_status status;
50 setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_remove_file) 172 acpi_handle temp;
51 173
52#define to_acpi_device(n) container_of(n, struct acpi_device, kobj) 174 /*
53#define to_handle_attr(n) container_of(n, struct acpi_device_attribute, attr); 175 * If device has _EJ0, 'eject' file is created that is used to trigger
176 * hot-removal function from userland.
177 */
178 status = acpi_get_handle(dev->handle, "_EJ0", &temp);
179 if (ACPI_SUCCESS(status))
180 device_remove_file(&dev->dev, &dev_attr_eject);
54 181
55static ssize_t acpi_device_attr_show(struct kobject *kobj, 182 if(dev->flags.hardware_id)
56 struct attribute *attr, char *buf) 183 device_remove_file(&dev->dev, &dev_attr_hid);
184 if(dev->handle)
185 device_remove_file(&dev->dev, &dev_attr_path);
186}
187/* --------------------------------------------------------------------------
188 ACPI Bus operations
189 -------------------------------------------------------------------------- */
190static void acpi_device_release(struct device *dev)
57{ 191{
58 struct acpi_device *device = to_acpi_device(kobj); 192 struct acpi_device *acpi_dev = to_acpi_device(dev);
59 struct acpi_device_attribute *attribute = to_handle_attr(attr); 193
60 return attribute->show ? attribute->show(device, buf) : -EIO; 194 kfree(acpi_dev->pnp.cid_list);
195 kfree(acpi_dev);
61} 196}
62static ssize_t acpi_device_attr_store(struct kobject *kobj, 197
63 struct attribute *attr, const char *buf, 198static int acpi_device_suspend(struct device *dev, pm_message_t state)
64 size_t len)
65{ 199{
66 struct acpi_device *device = to_acpi_device(kobj); 200 struct acpi_device *acpi_dev = to_acpi_device(dev);
67 struct acpi_device_attribute *attribute = to_handle_attr(attr); 201 struct acpi_driver *acpi_drv = acpi_dev->driver;
68 return attribute->store ? attribute->store(device, buf, len) : -EIO; 202
203 if (acpi_drv && acpi_drv->ops.suspend)
204 return acpi_drv->ops.suspend(acpi_dev, state);
205 return 0;
69} 206}
70 207
71static struct sysfs_ops acpi_device_sysfs_ops = { 208static int acpi_device_resume(struct device *dev)
72 .show = acpi_device_attr_show, 209{
73 .store = acpi_device_attr_store, 210 struct acpi_device *acpi_dev = to_acpi_device(dev);
74}; 211 struct acpi_driver *acpi_drv = acpi_dev->driver;
75 212
76static struct kobj_type ktype_acpi_ns = { 213 if (acpi_drv && acpi_drv->ops.resume)
77 .sysfs_ops = &acpi_device_sysfs_ops, 214 return acpi_drv->ops.resume(acpi_dev);
78 .release = acpi_device_release, 215 return 0;
79}; 216}
80 217
81static int namespace_uevent(struct kset *kset, struct kobject *kobj, 218static int acpi_bus_match(struct device *dev, struct device_driver *drv)
82 char **envp, int num_envp, char *buffer,
83 int buffer_size)
84{ 219{
85 struct acpi_device *dev = to_acpi_device(kobj); 220 struct acpi_device *acpi_dev = to_acpi_device(dev);
86 int i = 0; 221 struct acpi_driver *acpi_drv = to_acpi_driver(drv);
87 int len = 0;
88 222
89 if (!dev->driver) 223 return !acpi_match_ids(acpi_dev, acpi_drv->ids);
90 return 0; 224}
91 225
92 if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, 226static int acpi_device_uevent(struct device *dev, char **envp, int num_envp,
93 "PHYSDEVDRIVER=%s", dev->driver->name)) 227 char *buffer, int buffer_size)
228{
229 struct acpi_device *acpi_dev = to_acpi_device(dev);
230 int i = 0, length = 0, ret = 0;
231
232 if (acpi_dev->flags.hardware_id)
233 ret = add_uevent_var(envp, num_envp, &i,
234 buffer, buffer_size, &length,
235 "HWID=%s", acpi_dev->pnp.hardware_id);
236 if (ret)
94 return -ENOMEM; 237 return -ENOMEM;
238 if (acpi_dev->flags.compatible_ids) {
239 int j;
240 struct acpi_compatible_id_list *cid_list;
241
242 cid_list = acpi_dev->pnp.cid_list;
243
244 for (j = 0; j < cid_list->count; j++) {
245 ret = add_uevent_var(envp, num_envp, &i, buffer,
246 buffer_size, &length, "COMPTID=%s",
247 cid_list->id[j].value);
248 if (ret)
249 return -ENOMEM;
250 }
251 }
95 252
96 envp[i] = NULL; 253 envp[i] = NULL;
254 return 0;
255}
256
257static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *);
258static int acpi_start_single_object(struct acpi_device *);
259static int acpi_device_probe(struct device * dev)
260{
261 struct acpi_device *acpi_dev = to_acpi_device(dev);
262 struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver);
263 int ret;
264
265 ret = acpi_bus_driver_init(acpi_dev, acpi_drv);
266 if (!ret) {
267 if (acpi_dev->bus_ops.acpi_op_start)
268 acpi_start_single_object(acpi_dev);
269 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
270 "Found driver [%s] for device [%s]\n",
271 acpi_drv->name, acpi_dev->pnp.bus_id));
272 get_device(dev);
273 }
274 return ret;
275}
97 276
277static int acpi_device_remove(struct device * dev)
278{
279 struct acpi_device *acpi_dev = to_acpi_device(dev);
280 struct acpi_driver *acpi_drv = acpi_dev->driver;
281
282 if (acpi_drv) {
283 if (acpi_drv->ops.stop)
284 acpi_drv->ops.stop(acpi_dev, acpi_dev->removal_type);
285 if (acpi_drv->ops.remove)
286 acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type);
287 }
288 acpi_dev->driver = NULL;
289 acpi_driver_data(dev) = NULL;
290
291 put_device(dev);
98 return 0; 292 return 0;
99} 293}
100 294
101static struct kset_uevent_ops namespace_uevent_ops = { 295static void acpi_device_shutdown(struct device *dev)
102 .uevent = &namespace_uevent, 296{
103}; 297 struct acpi_device *acpi_dev = to_acpi_device(dev);
298 struct acpi_driver *acpi_drv = acpi_dev->driver;
299
300 if (acpi_drv && acpi_drv->ops.shutdown)
301 acpi_drv->ops.shutdown(acpi_dev);
104 302
105static struct kset acpi_namespace_kset = { 303 return ;
106 .kobj = { 304}
107 .name = "namespace", 305
108 }, 306static struct bus_type acpi_bus_type = {
109 .subsys = &acpi_subsys, 307 .name = "acpi",
110 .ktype = &ktype_acpi_ns, 308 .suspend = acpi_device_suspend,
111 .uevent_ops = &namespace_uevent_ops, 309 .resume = acpi_device_resume,
310 .shutdown = acpi_device_shutdown,
311 .match = acpi_bus_match,
312 .probe = acpi_device_probe,
313 .remove = acpi_device_remove,
314 .uevent = acpi_device_uevent,
112}; 315};
113 316
114static void acpi_device_register(struct acpi_device *device, 317static int acpi_device_register(struct acpi_device *device,
115 struct acpi_device *parent) 318 struct acpi_device *parent)
116{ 319{
117 int err; 320 int result;
118 321 struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id;
322 int found = 0;
119 /* 323 /*
120 * Linkage 324 * Linkage
121 * ------- 325 * -------
@@ -126,7 +330,33 @@ static void acpi_device_register(struct acpi_device *device,
126 INIT_LIST_HEAD(&device->g_list); 330 INIT_LIST_HEAD(&device->g_list);
127 INIT_LIST_HEAD(&device->wakeup_list); 331 INIT_LIST_HEAD(&device->wakeup_list);
128 332
333 new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
334 if (!new_bus_id) {
335 printk(KERN_ERR PREFIX "Memory allocation error\n");
336 return -ENOMEM;
337 }
338
129 spin_lock(&acpi_device_lock); 339 spin_lock(&acpi_device_lock);
340 /*
341 * Find suitable bus_id and instance number in acpi_bus_id_list
342 * If failed, create one and link it into acpi_bus_id_list
343 */
344 list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) {
345 if(!strcmp(acpi_device_bus_id->bus_id, device->flags.hardware_id? device->pnp.hardware_id : "device")) {
346 acpi_device_bus_id->instance_no ++;
347 found = 1;
348 kfree(new_bus_id);
349 break;
350 }
351 }
352 if(!found) {
353 acpi_device_bus_id = new_bus_id;
354 strcpy(acpi_device_bus_id->bus_id, device->flags.hardware_id ? device->pnp.hardware_id : "device");
355 acpi_device_bus_id->instance_no = 0;
356 list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list);
357 }
358 sprintf(device->dev.bus_id, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);
359
130 if (device->parent) { 360 if (device->parent) {
131 list_add_tail(&device->node, &device->parent->children); 361 list_add_tail(&device->node, &device->parent->children);
132 list_add_tail(&device->g_list, &device->parent->g_list); 362 list_add_tail(&device->g_list, &device->parent->g_list);
@@ -136,16 +366,33 @@ static void acpi_device_register(struct acpi_device *device,
136 list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list); 366 list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
137 spin_unlock(&acpi_device_lock); 367 spin_unlock(&acpi_device_lock);
138 368
139 strlcpy(device->kobj.name, device->pnp.bus_id, KOBJ_NAME_LEN); 369 if (device->parent)
140 if (parent) 370 device->dev.parent = &parent->dev;
141 device->kobj.parent = &parent->kobj; 371 device->dev.bus = &acpi_bus_type;
142 device->kobj.ktype = &ktype_acpi_ns; 372 device_initialize(&device->dev);
143 device->kobj.kset = &acpi_namespace_kset; 373 device->dev.release = &acpi_device_release;
144 err = kobject_register(&device->kobj); 374 result = device_add(&device->dev);
145 if (err < 0) 375 if(result) {
146 printk(KERN_WARNING "%s: kobject_register error: %d\n", 376 printk("Error adding device %s", device->dev.bus_id);
147 __FUNCTION__, err); 377 goto end;
148 create_sysfs_device_files(device); 378 }
379
380 result = acpi_device_setup_files(device);
381 if(result)
382 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error creating sysfs interface for device %s\n", device->dev.bus_id));
383
384 device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
385 return 0;
386 end:
387 spin_lock(&acpi_device_lock);
388 if (device->parent) {
389 list_del(&device->node);
390 list_del(&device->g_list);
391 } else
392 list_del(&device->g_list);
393 list_del(&device->wakeup_list);
394 spin_unlock(&acpi_device_lock);
395 return result;
149} 396}
150 397
151static void acpi_device_unregister(struct acpi_device *device, int type) 398static void acpi_device_unregister(struct acpi_device *device, int type)
@@ -158,81 +405,143 @@ static void acpi_device_unregister(struct acpi_device *device, int type)
158 list_del(&device->g_list); 405 list_del(&device->g_list);
159 406
160 list_del(&device->wakeup_list); 407 list_del(&device->wakeup_list);
161
162 spin_unlock(&acpi_device_lock); 408 spin_unlock(&acpi_device_lock);
163 409
164 acpi_detach_data(device->handle, acpi_bus_data_handler); 410 acpi_detach_data(device->handle, acpi_bus_data_handler);
165 remove_sysfs_device_files(device); 411
166 kobject_unregister(&device->kobj); 412 acpi_device_remove_files(device);
413 device_unregister(&device->dev);
167} 414}
168 415
169void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context) 416/* --------------------------------------------------------------------------
417 Driver Management
418 -------------------------------------------------------------------------- */
419/**
420 * acpi_bus_driver_init - add a device to a driver
421 * @device: the device to add and initialize
422 * @driver: driver for the device
423 *
424 * Used to initialize a device via its device driver. Called whenever a
425 * driver is bound to a device. Invokes the driver's add() ops.
426 */
427static int
428acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
170{ 429{
430 int result = 0;
171 431
172 /* TBD */
173 432
174 return; 433 if (!device || !driver)
175} 434 return -EINVAL;
176 435
177static int acpi_bus_get_power_flags(struct acpi_device *device) 436 if (!driver->ops.add)
178{ 437 return -ENOSYS;
179 acpi_status status = 0;
180 acpi_handle handle = NULL;
181 u32 i = 0;
182 438
439 result = driver->ops.add(device);
440 if (result) {
441 device->driver = NULL;
442 acpi_driver_data(device) = NULL;
443 return result;
444 }
183 445
184 /* 446 device->driver = driver;
185 * Power Management Flags
186 */
187 status = acpi_get_handle(device->handle, "_PSC", &handle);
188 if (ACPI_SUCCESS(status))
189 device->power.flags.explicit_get = 1;
190 status = acpi_get_handle(device->handle, "_IRC", &handle);
191 if (ACPI_SUCCESS(status))
192 device->power.flags.inrush_current = 1;
193 447
194 /* 448 /*
195 * Enumerate supported power management states 449 * TBD - Configuration Management: Assign resources to device based
450 * upon possible configuration and currently allocated resources.
196 */ 451 */
197 for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) {
198 struct acpi_device_power_state *ps = &device->power.states[i];
199 char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' };
200 452
201 /* Evaluate "_PRx" to se if power resources are referenced */ 453 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
202 acpi_evaluate_reference(device->handle, object_name, NULL, 454 "Driver successfully bound to device\n"));
203 &ps->resources); 455 return 0;
204 if (ps->resources.count) { 456}
205 device->power.flags.power_resources = 1;
206 ps->flags.valid = 1;
207 }
208 457
209 /* Evaluate "_PSx" to see if we can do explicit sets */ 458static int acpi_start_single_object(struct acpi_device *device)
210 object_name[2] = 'S'; 459{
211 status = acpi_get_handle(device->handle, object_name, &handle); 460 int result = 0;
212 if (ACPI_SUCCESS(status)) { 461 struct acpi_driver *driver;
213 ps->flags.explicit_set = 1;
214 ps->flags.valid = 1;
215 }
216 462
217 /* State is valid if we have some power control */
218 if (ps->resources.count || ps->flags.explicit_set)
219 ps->flags.valid = 1;
220 463
221 ps->power = -1; /* Unknown - driver assigned */ 464 if (!(driver = device->driver))
222 ps->latency = -1; /* Unknown - driver assigned */ 465 return 0;
466
467 if (driver->ops.start) {
468 result = driver->ops.start(device);
469 if (result && driver->ops.remove)
470 driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
223 } 471 }
224 472
225 /* Set defaults for D0 and D3 states (always valid) */ 473 return result;
226 device->power.states[ACPI_STATE_D0].flags.valid = 1; 474}
227 device->power.states[ACPI_STATE_D0].power = 100;
228 device->power.states[ACPI_STATE_D3].flags.valid = 1;
229 device->power.states[ACPI_STATE_D3].power = 0;
230 475
231 /* TBD: System wake support and resource requirements. */ 476/**
477 * acpi_bus_register_driver - register a driver with the ACPI bus
478 * @driver: driver being registered
479 *
480 * Registers a driver with the ACPI bus. Searches the namespace for all
481 * devices that match the driver's criteria and binds. Returns zero for
482 * success or a negative error status for failure.
483 */
484int acpi_bus_register_driver(struct acpi_driver *driver)
485{
486 int ret;
232 487
233 device->power.state = ACPI_STATE_UNKNOWN; 488 if (acpi_disabled)
489 return -ENODEV;
490 driver->drv.name = driver->name;
491 driver->drv.bus = &acpi_bus_type;
492 driver->drv.owner = driver->owner;
234 493
235 return 0; 494 ret = driver_register(&driver->drv);
495 return ret;
496}
497
498EXPORT_SYMBOL(acpi_bus_register_driver);
499
500/**
501 * acpi_bus_unregister_driver - unregisters a driver with the APIC bus
502 * @driver: driver to unregister
503 *
504 * Unregisters a driver with the ACPI bus. Searches the namespace for all
505 * devices that match the driver's criteria and unbinds.
506 */
507void acpi_bus_unregister_driver(struct acpi_driver *driver)
508{
509 driver_unregister(&driver->drv);
510}
511
512EXPORT_SYMBOL(acpi_bus_unregister_driver);
513
514/* --------------------------------------------------------------------------
515 Device Enumeration
516 -------------------------------------------------------------------------- */
517acpi_status
518acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
519{
520 acpi_status status;
521 acpi_handle tmp;
522 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
523 union acpi_object *obj;
524
525 status = acpi_get_handle(handle, "_EJD", &tmp);
526 if (ACPI_FAILURE(status))
527 return status;
528
529 status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer);
530 if (ACPI_SUCCESS(status)) {
531 obj = buffer.pointer;
532 status = acpi_get_handle(NULL, obj->string.pointer, ejd);
533 kfree(buffer.pointer);
534 }
535 return status;
536}
537EXPORT_SYMBOL_GPL(acpi_bus_get_ejd);
538
539void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context)
540{
541
542 /* TBD */
543
544 return;
236} 545}
237 546
238int acpi_match_ids(struct acpi_device *device, char *ids) 547int acpi_match_ids(struct acpi_device *device, char *ids)
@@ -254,6 +563,12 @@ int acpi_match_ids(struct acpi_device *device, char *ids)
254 return -ENOENT; 563 return -ENOENT;
255} 564}
256 565
566static int acpi_bus_get_perf_flags(struct acpi_device *device)
567{
568 device->performance.state = ACPI_STATE_UNKNOWN;
569 return 0;
570}
571
257static acpi_status 572static acpi_status
258acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, 573acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device,
259 union acpi_object *package) 574 union acpi_object *package)
@@ -338,359 +653,66 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
338 return 0; 653 return 0;
339} 654}
340 655
341/* -------------------------------------------------------------------------- 656static int acpi_bus_get_power_flags(struct acpi_device *device)
342 ACPI sysfs device file support
343 -------------------------------------------------------------------------- */
344static ssize_t acpi_eject_store(struct acpi_device *device,
345 const char *buf, size_t count);
346
347#define ACPI_DEVICE_ATTR(_name,_mode,_show,_store) \
348static struct acpi_device_attribute acpi_device_attr_##_name = \
349 __ATTR(_name, _mode, _show, _store)
350
351ACPI_DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
352
353/**
354 * setup_sys_fs_device_files - sets up the device files under device namespace
355 * @dev: acpi_device object
356 * @func: function pointer to create or destroy the device file
357 */
358static void
359setup_sys_fs_device_files(struct acpi_device *dev,
360 acpi_device_sysfs_files * func)
361{
362 acpi_status status;
363 acpi_handle temp = NULL;
364
365 /*
366 * If device has _EJ0, 'eject' file is created that is used to trigger
367 * hot-removal function from userland.
368 */
369 status = acpi_get_handle(dev->handle, "_EJ0", &temp);
370 if (ACPI_SUCCESS(status))
371 (*(func)) (&dev->kobj, &acpi_device_attr_eject.attr);
372}
373
374static int acpi_eject_operation(acpi_handle handle, int lockable)
375{ 657{
376 struct acpi_object_list arg_list; 658 acpi_status status = 0;
377 union acpi_object arg; 659 acpi_handle handle = NULL;
378 acpi_status status = AE_OK; 660 u32 i = 0;
379
380 /*
381 * TBD: evaluate _PS3?
382 */
383
384 if (lockable) {
385 arg_list.count = 1;
386 arg_list.pointer = &arg;
387 arg.type = ACPI_TYPE_INTEGER;
388 arg.integer.value = 0;
389 acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
390 }
391 661
392 arg_list.count = 1;
393 arg_list.pointer = &arg;
394 arg.type = ACPI_TYPE_INTEGER;
395 arg.integer.value = 1;
396 662
397 /* 663 /*
398 * TBD: _EJD support. 664 * Power Management Flags
399 */ 665 */
400 666 status = acpi_get_handle(device->handle, "_PSC", &handle);
401 status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); 667 if (ACPI_SUCCESS(status))
402 if (ACPI_FAILURE(status)) { 668 device->power.flags.explicit_get = 1;
403 return (-ENODEV); 669 status = acpi_get_handle(device->handle, "_IRC", &handle);
404 } 670 if (ACPI_SUCCESS(status))
405 671 device->power.flags.inrush_current = 1;
406 return (0);
407}
408
409static ssize_t
410acpi_eject_store(struct acpi_device *device, const char *buf, size_t count)
411{
412 int result;
413 int ret = count;
414 int islockable;
415 acpi_status status;
416 acpi_handle handle;
417 acpi_object_type type = 0;
418
419 if ((!count) || (buf[0] != '1')) {
420 return -EINVAL;
421 }
422#ifndef FORCE_EJECT
423 if (device->driver == NULL) {
424 ret = -ENODEV;
425 goto err;
426 }
427#endif
428 status = acpi_get_type(device->handle, &type);
429 if (ACPI_FAILURE(status) || (!device->flags.ejectable)) {
430 ret = -ENODEV;
431 goto err;
432 }
433
434 islockable = device->flags.lockable;
435 handle = device->handle;
436
437 result = acpi_bus_trim(device, 1);
438
439 if (!result)
440 result = acpi_eject_operation(handle, islockable);
441
442 if (result) {
443 ret = -EBUSY;
444 }
445 err:
446 return ret;
447}
448
449/* --------------------------------------------------------------------------
450 Performance Management
451 -------------------------------------------------------------------------- */
452
453static int acpi_bus_get_perf_flags(struct acpi_device *device)
454{
455 device->performance.state = ACPI_STATE_UNKNOWN;
456 return 0;
457}
458
459/* --------------------------------------------------------------------------
460 Driver Management
461 -------------------------------------------------------------------------- */
462
463static LIST_HEAD(acpi_bus_drivers);
464
465/**
466 * acpi_bus_match - match device IDs to driver's supported IDs
467 * @device: the device that we are trying to match to a driver
468 * @driver: driver whose device id table is being checked
469 *
470 * Checks the device's hardware (_HID) or compatible (_CID) ids to see if it
471 * matches the specified driver's criteria.
472 */
473static int
474acpi_bus_match(struct acpi_device *device, struct acpi_driver *driver)
475{
476 if (driver && driver->ops.match)
477 return driver->ops.match(device, driver);
478 return acpi_match_ids(device, driver->ids);
479}
480
481/**
482 * acpi_bus_driver_init - add a device to a driver
483 * @device: the device to add and initialize
484 * @driver: driver for the device
485 *
486 * Used to initialize a device via its device driver. Called whenever a
487 * driver is bound to a device. Invokes the driver's add() and start() ops.
488 */
489static int
490acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
491{
492 int result = 0;
493
494
495 if (!device || !driver)
496 return -EINVAL;
497
498 if (!driver->ops.add)
499 return -ENOSYS;
500
501 result = driver->ops.add(device);
502 if (result) {
503 device->driver = NULL;
504 acpi_driver_data(device) = NULL;
505 return result;
506 }
507
508 device->driver = driver;
509 672
510 /* 673 /*
511 * TBD - Configuration Management: Assign resources to device based 674 * Enumerate supported power management states
512 * upon possible configuration and currently allocated resources.
513 */ 675 */
676 for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) {
677 struct acpi_device_power_state *ps = &device->power.states[i];
678 char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' };
514 679
515 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 680 /* Evaluate "_PRx" to se if power resources are referenced */
516 "Driver successfully bound to device\n")); 681 acpi_evaluate_reference(device->handle, object_name, NULL,
517 return 0; 682 &ps->resources);
518} 683 if (ps->resources.count) {
519 684 device->power.flags.power_resources = 1;
520static int acpi_start_single_object(struct acpi_device *device) 685 ps->flags.valid = 1;
521{
522 int result = 0;
523 struct acpi_driver *driver;
524
525
526 if (!(driver = device->driver))
527 return 0;
528
529 if (driver->ops.start) {
530 result = driver->ops.start(device);
531 if (result && driver->ops.remove)
532 driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
533 }
534
535 return result;
536}
537
538static void acpi_driver_attach(struct acpi_driver *drv)
539{
540 struct list_head *node, *next;
541
542
543 spin_lock(&acpi_device_lock);
544 list_for_each_safe(node, next, &acpi_device_list) {
545 struct acpi_device *dev =
546 container_of(node, struct acpi_device, g_list);
547
548 if (dev->driver || !dev->status.present)
549 continue;
550 spin_unlock(&acpi_device_lock);
551
552 if (!acpi_bus_match(dev, drv)) {
553 if (!acpi_bus_driver_init(dev, drv)) {
554 acpi_start_single_object(dev);
555 atomic_inc(&drv->references);
556 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
557 "Found driver [%s] for device [%s]\n",
558 drv->name, dev->pnp.bus_id));
559 }
560 } 686 }
561 spin_lock(&acpi_device_lock);
562 }
563 spin_unlock(&acpi_device_lock);
564}
565
566static void acpi_driver_detach(struct acpi_driver *drv)
567{
568 struct list_head *node, *next;
569 687
570 688 /* Evaluate "_PSx" to see if we can do explicit sets */
571 spin_lock(&acpi_device_lock); 689 object_name[2] = 'S';
572 list_for_each_safe(node, next, &acpi_device_list) { 690 status = acpi_get_handle(device->handle, object_name, &handle);
573 struct acpi_device *dev = 691 if (ACPI_SUCCESS(status)) {
574 container_of(node, struct acpi_device, g_list); 692 ps->flags.explicit_set = 1;
575 693 ps->flags.valid = 1;
576 if (dev->driver == drv) {
577 spin_unlock(&acpi_device_lock);
578 if (drv->ops.remove)
579 drv->ops.remove(dev, ACPI_BUS_REMOVAL_NORMAL);
580 spin_lock(&acpi_device_lock);
581 dev->driver = NULL;
582 dev->driver_data = NULL;
583 atomic_dec(&drv->references);
584 } 694 }
585 }
586 spin_unlock(&acpi_device_lock);
587}
588
589/**
590 * acpi_bus_register_driver - register a driver with the ACPI bus
591 * @driver: driver being registered
592 *
593 * Registers a driver with the ACPI bus. Searches the namespace for all
594 * devices that match the driver's criteria and binds. Returns zero for
595 * success or a negative error status for failure.
596 */
597int acpi_bus_register_driver(struct acpi_driver *driver)
598{
599
600 if (acpi_disabled)
601 return -ENODEV;
602
603 spin_lock(&acpi_device_lock);
604 list_add_tail(&driver->node, &acpi_bus_drivers);
605 spin_unlock(&acpi_device_lock);
606 acpi_driver_attach(driver);
607
608 return 0;
609}
610
611EXPORT_SYMBOL(acpi_bus_register_driver);
612
613/**
614 * acpi_bus_unregister_driver - unregisters a driver with the APIC bus
615 * @driver: driver to unregister
616 *
617 * Unregisters a driver with the ACPI bus. Searches the namespace for all
618 * devices that match the driver's criteria and unbinds.
619 */
620void acpi_bus_unregister_driver(struct acpi_driver *driver)
621{
622 acpi_driver_detach(driver);
623
624 if (!atomic_read(&driver->references)) {
625 spin_lock(&acpi_device_lock);
626 list_del_init(&driver->node);
627 spin_unlock(&acpi_device_lock);
628 }
629 return;
630}
631
632EXPORT_SYMBOL(acpi_bus_unregister_driver);
633
634/**
635 * acpi_bus_find_driver - check if there is a driver installed for the device
636 * @device: device that we are trying to find a supporting driver for
637 *
638 * Parses the list of registered drivers looking for a driver applicable for
639 * the specified device.
640 */
641static int acpi_bus_find_driver(struct acpi_device *device)
642{
643 int result = 0;
644 struct list_head *node, *next;
645 695
696 /* State is valid if we have some power control */
697 if (ps->resources.count || ps->flags.explicit_set)
698 ps->flags.valid = 1;
646 699
647 spin_lock(&acpi_device_lock); 700 ps->power = -1; /* Unknown - driver assigned */
648 list_for_each_safe(node, next, &acpi_bus_drivers) { 701 ps->latency = -1; /* Unknown - driver assigned */
649 struct acpi_driver *driver =
650 container_of(node, struct acpi_driver, node);
651
652 atomic_inc(&driver->references);
653 spin_unlock(&acpi_device_lock);
654 if (!acpi_bus_match(device, driver)) {
655 result = acpi_bus_driver_init(device, driver);
656 if (!result)
657 goto Done;
658 }
659 atomic_dec(&driver->references);
660 spin_lock(&acpi_device_lock);
661 } 702 }
662 spin_unlock(&acpi_device_lock);
663
664 Done:
665 return result;
666}
667 703
668/* -------------------------------------------------------------------------- 704 /* Set defaults for D0 and D3 states (always valid) */
669 Device Enumeration 705 device->power.states[ACPI_STATE_D0].flags.valid = 1;
670 -------------------------------------------------------------------------- */ 706 device->power.states[ACPI_STATE_D0].power = 100;
707 device->power.states[ACPI_STATE_D3].flags.valid = 1;
708 device->power.states[ACPI_STATE_D3].power = 0;
671 709
672acpi_status 710 /* TBD: System wake support and resource requirements. */
673acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
674{
675 acpi_status status;
676 acpi_handle tmp;
677 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
678 union acpi_object *obj;
679 711
680 status = acpi_get_handle(handle, "_EJD", &tmp); 712 device->power.state = ACPI_STATE_UNKNOWN;
681 if (ACPI_FAILURE(status))
682 return status;
683 713
684 status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer); 714 return 0;
685 if (ACPI_SUCCESS(status)) {
686 obj = buffer.pointer;
687 status = acpi_get_handle(NULL, obj->string.pointer, ejd);
688 kfree(buffer.pointer);
689 }
690 return status;
691} 715}
692EXPORT_SYMBOL_GPL(acpi_bus_get_ejd);
693
694 716
695static int acpi_bus_get_flags(struct acpi_device *device) 717static int acpi_bus_get_flags(struct acpi_device *device)
696{ 718{
@@ -782,6 +804,75 @@ static void acpi_device_get_busid(struct acpi_device *device,
782 } 804 }
783} 805}
784 806
807static int
808acpi_video_bus_match(struct acpi_device *device)
809{
810 acpi_handle h_dummy1;
811 acpi_handle h_dummy2;
812 acpi_handle h_dummy3;
813
814
815 if (!device)
816 return -EINVAL;
817
818 /* Since there is no HID, CID for ACPI Video drivers, we have
819 * to check well known required nodes for each feature we support.
820 */
821
822 /* Does this device able to support video switching ? */
823 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) &&
824 ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2)))
825 return 0;
826
827 /* Does this device able to retrieve a video ROM ? */
828 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1)))
829 return 0;
830
831 /* Does this device able to configure which video head to be POSTed ? */
832 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) &&
833 ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) &&
834 ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3)))
835 return 0;
836
837 return -ENODEV;
838}
839
840/*
841 * acpi_bay_match - see if a device is an ejectable driver bay
842 *
843 * If an acpi object is ejectable and has one of the ACPI ATA methods defined,
844 * then we can safely call it an ejectable drive bay
845 */
846static int acpi_bay_match(struct acpi_device *device){
847 acpi_status status;
848 acpi_handle handle;
849 acpi_handle tmp;
850 acpi_handle phandle;
851
852 handle = device->handle;
853
854 status = acpi_get_handle(handle, "_EJ0", &tmp);
855 if (ACPI_FAILURE(status))
856 return -ENODEV;
857
858 if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) ||
859 (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) ||
860 (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) ||
861 (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp))))
862 return 0;
863
864 if (acpi_get_parent(handle, &phandle))
865 return -ENODEV;
866
867 if ((ACPI_SUCCESS(acpi_get_handle(phandle, "_GTF", &tmp))) ||
868 (ACPI_SUCCESS(acpi_get_handle(phandle, "_GTM", &tmp))) ||
869 (ACPI_SUCCESS(acpi_get_handle(phandle, "_STM", &tmp))) ||
870 (ACPI_SUCCESS(acpi_get_handle(phandle, "_SDD", &tmp))))
871 return 0;
872
873 return -ENODEV;
874}
875
785static void acpi_device_set_id(struct acpi_device *device, 876static void acpi_device_set_id(struct acpi_device *device,
786 struct acpi_device *parent, acpi_handle handle, 877 struct acpi_device *parent, acpi_handle handle,
787 int type) 878 int type)
@@ -812,6 +903,16 @@ static void acpi_device_set_id(struct acpi_device *device,
812 device->pnp.bus_address = info->address; 903 device->pnp.bus_address = info->address;
813 device->flags.bus_address = 1; 904 device->flags.bus_address = 1;
814 } 905 }
906
907 if(!(info->valid & (ACPI_VALID_HID | ACPI_VALID_CID))){
908 status = acpi_video_bus_match(device);
909 if(ACPI_SUCCESS(status))
910 hid = ACPI_VIDEO_HID;
911
912 status = acpi_bay_match(device);
913 if (ACPI_SUCCESS(status))
914 hid = ACPI_BAY_HID;
915 }
815 break; 916 break;
816 case ACPI_BUS_TYPE_POWER: 917 case ACPI_BUS_TYPE_POWER:
817 hid = ACPI_POWER_HID; 918 hid = ACPI_POWER_HID;
@@ -888,86 +989,24 @@ static int acpi_device_set_context(struct acpi_device *device, int type)
888 return result; 989 return result;
889} 990}
890 991
891static void acpi_device_get_debug_info(struct acpi_device *device,
892 acpi_handle handle, int type)
893{
894#ifdef CONFIG_ACPI_DEBUG_OUTPUT
895 char *type_string = NULL;
896 char name[80] = { '?', '\0' };
897 struct acpi_buffer buffer = { sizeof(name), name };
898
899 switch (type) {
900 case ACPI_BUS_TYPE_DEVICE:
901 type_string = "Device";
902 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
903 break;
904 case ACPI_BUS_TYPE_POWER:
905 type_string = "Power Resource";
906 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
907 break;
908 case ACPI_BUS_TYPE_PROCESSOR:
909 type_string = "Processor";
910 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
911 break;
912 case ACPI_BUS_TYPE_SYSTEM:
913 type_string = "System";
914 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
915 break;
916 case ACPI_BUS_TYPE_THERMAL:
917 type_string = "Thermal Zone";
918 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
919 break;
920 case ACPI_BUS_TYPE_POWER_BUTTON:
921 type_string = "Power Button";
922 sprintf(name, "PWRB");
923 break;
924 case ACPI_BUS_TYPE_SLEEP_BUTTON:
925 type_string = "Sleep Button";
926 sprintf(name, "SLPB");
927 break;
928 }
929
930 printk(KERN_DEBUG "Found %s %s [%p]\n", type_string, name, handle);
931#endif /*CONFIG_ACPI_DEBUG_OUTPUT */
932}
933
934static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) 992static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
935{ 993{
936 int result = 0;
937 struct acpi_driver *driver;
938
939
940 if (!dev) 994 if (!dev)
941 return -EINVAL; 995 return -EINVAL;
942 996
943 driver = dev->driver; 997 dev->removal_type = ACPI_BUS_REMOVAL_EJECT;
944 998 device_release_driver(&dev->dev);
945 if ((driver) && (driver->ops.remove)) {
946
947 if (driver->ops.stop) {
948 result = driver->ops.stop(dev, ACPI_BUS_REMOVAL_EJECT);
949 if (result)
950 return result;
951 }
952
953 result = dev->driver->ops.remove(dev, ACPI_BUS_REMOVAL_EJECT);
954 if (result) {
955 return result;
956 }
957
958 atomic_dec(&dev->driver->references);
959 dev->driver = NULL;
960 acpi_driver_data(dev) = NULL;
961 }
962 999
963 if (!rmdevice) 1000 if (!rmdevice)
964 return 0; 1001 return 0;
965 1002
1003 /*
1004 * unbind _ADR-Based Devices when hot removal
1005 */
966 if (dev->flags.bus_address) { 1006 if (dev->flags.bus_address) {
967 if ((dev->parent) && (dev->parent->ops.unbind)) 1007 if ((dev->parent) && (dev->parent->ops.unbind))
968 dev->parent->ops.unbind(dev); 1008 dev->parent->ops.unbind(dev);
969 } 1009 }
970
971 acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT); 1010 acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT);
972 1011
973 return 0; 1012 return 0;
@@ -975,7 +1014,8 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
975 1014
976static int 1015static int
977acpi_add_single_object(struct acpi_device **child, 1016acpi_add_single_object(struct acpi_device **child,
978 struct acpi_device *parent, acpi_handle handle, int type) 1017 struct acpi_device *parent, acpi_handle handle, int type,
1018 struct acpi_bus_ops *ops)
979{ 1019{
980 int result = 0; 1020 int result = 0;
981 struct acpi_device *device = NULL; 1021 struct acpi_device *device = NULL;
@@ -992,6 +1032,8 @@ acpi_add_single_object(struct acpi_device **child,
992 1032
993 device->handle = handle; 1033 device->handle = handle;
994 device->parent = parent; 1034 device->parent = parent;
1035 device->bus_ops = *ops; /* workround for not call .start */
1036
995 1037
996 acpi_device_get_busid(device, handle, type); 1038 acpi_device_get_busid(device, handle, type);
997 1039
@@ -1076,33 +1118,16 @@ acpi_add_single_object(struct acpi_device **child,
1076 if ((result = acpi_device_set_context(device, type))) 1118 if ((result = acpi_device_set_context(device, type)))
1077 goto end; 1119 goto end;
1078 1120
1079 acpi_device_get_debug_info(device, handle, type); 1121 result = acpi_device_register(device, parent);
1080
1081 acpi_device_register(device, parent);
1082 1122
1083 /* 1123 /*
1084 * Bind _ADR-Based Devices 1124 * Bind _ADR-Based Devices when hot add
1085 * -----------------------
1086 * If there's a a bus address (_ADR) then we utilize the parent's
1087 * 'bind' function (if exists) to bind the ACPI- and natively-
1088 * enumerated device representations.
1089 */ 1125 */
1090 if (device->flags.bus_address) { 1126 if (device->flags.bus_address) {
1091 if (device->parent && device->parent->ops.bind) 1127 if (device->parent && device->parent->ops.bind)
1092 device->parent->ops.bind(device); 1128 device->parent->ops.bind(device);
1093 } 1129 }
1094 1130
1095 /*
1096 * Locate & Attach Driver
1097 * ----------------------
1098 * If there's a hardware id (_HID) or compatible ids (_CID) we check
1099 * to see if there's a driver installed for this kind of device. Note
1100 * that drivers can install before or after a device is enumerated.
1101 *
1102 * TBD: Assumes LDM provides driver hot-plug capability.
1103 */
1104 acpi_bus_find_driver(device);
1105
1106 end: 1131 end:
1107 if (!result) 1132 if (!result)
1108 *child = device; 1133 *child = device;
@@ -1188,14 +1213,14 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)
1188 1213
1189 if (ops->acpi_op_add) 1214 if (ops->acpi_op_add)
1190 status = acpi_add_single_object(&child, parent, 1215 status = acpi_add_single_object(&child, parent,
1191 chandle, type); 1216 chandle, type, ops);
1192 else 1217 else
1193 status = acpi_bus_get_device(chandle, &child); 1218 status = acpi_bus_get_device(chandle, &child);
1194 1219
1195 if (ACPI_FAILURE(status)) 1220 if (ACPI_FAILURE(status))
1196 continue; 1221 continue;
1197 1222
1198 if (ops->acpi_op_start) { 1223 if (ops->acpi_op_start && !(ops->acpi_op_add)) {
1199 status = acpi_start_single_object(child); 1224 status = acpi_start_single_object(child);
1200 if (ACPI_FAILURE(status)) 1225 if (ACPI_FAILURE(status))
1201 continue; 1226 continue;
@@ -1233,13 +1258,13 @@ acpi_bus_add(struct acpi_device **child,
1233 int result; 1258 int result;
1234 struct acpi_bus_ops ops; 1259 struct acpi_bus_ops ops;
1235 1260
1261 memset(&ops, 0, sizeof(ops));
1262 ops.acpi_op_add = 1;
1236 1263
1237 result = acpi_add_single_object(child, parent, handle, type); 1264 result = acpi_add_single_object(child, parent, handle, type, &ops);
1238 if (!result) { 1265 if (!result)
1239 memset(&ops, 0, sizeof(ops));
1240 ops.acpi_op_add = 1;
1241 result = acpi_bus_scan(*child, &ops); 1266 result = acpi_bus_scan(*child, &ops);
1242 } 1267
1243 return result; 1268 return result;
1244} 1269}
1245 1270
@@ -1325,127 +1350,35 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
1325{ 1350{
1326 int result = 0; 1351 int result = 0;
1327 struct acpi_device *device = NULL; 1352 struct acpi_device *device = NULL;
1328 1353 struct acpi_bus_ops ops;
1329 1354
1330 if (!root) 1355 if (!root)
1331 return -ENODEV; 1356 return -ENODEV;
1332 1357
1358 memset(&ops, 0, sizeof(ops));
1359 ops.acpi_op_add = 1;
1360 ops.acpi_op_start = 1;
1361
1333 /* 1362 /*
1334 * Enumerate all fixed-feature devices. 1363 * Enumerate all fixed-feature devices.
1335 */ 1364 */
1336 if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) { 1365 if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) {
1337 result = acpi_add_single_object(&device, acpi_root, 1366 result = acpi_add_single_object(&device, acpi_root,
1338 NULL, 1367 NULL,
1339 ACPI_BUS_TYPE_POWER_BUTTON); 1368 ACPI_BUS_TYPE_POWER_BUTTON,
1340 if (!result) 1369 &ops);
1341 result = acpi_start_single_object(device);
1342 } 1370 }
1343 1371
1344 if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) { 1372 if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
1345 result = acpi_add_single_object(&device, acpi_root, 1373 result = acpi_add_single_object(&device, acpi_root,
1346 NULL, 1374 NULL,
1347 ACPI_BUS_TYPE_SLEEP_BUTTON); 1375 ACPI_BUS_TYPE_SLEEP_BUTTON,
1348 if (!result) 1376 &ops);
1349 result = acpi_start_single_object(device);
1350 } 1377 }
1351 1378
1352 return result; 1379 return result;
1353} 1380}
1354 1381
1355
1356static inline struct acpi_device * to_acpi_dev(struct device * dev)
1357{
1358 return container_of(dev, struct acpi_device, dev);
1359}
1360
1361
1362static int root_suspend(struct acpi_device * acpi_dev, pm_message_t state)
1363{
1364 struct acpi_device * dev, * next;
1365 int result;
1366
1367 spin_lock(&acpi_device_lock);
1368 list_for_each_entry_safe_reverse(dev, next, &acpi_device_list, g_list) {
1369 if (dev->driver && dev->driver->ops.suspend) {
1370 spin_unlock(&acpi_device_lock);
1371 result = dev->driver->ops.suspend(dev, 0);
1372 if (result) {
1373 printk(KERN_ERR PREFIX "[%s - %s] Suspend failed: %d\n",
1374 acpi_device_name(dev),
1375 acpi_device_bid(dev), result);
1376 }
1377 spin_lock(&acpi_device_lock);
1378 }
1379 }
1380 spin_unlock(&acpi_device_lock);
1381 return 0;
1382}
1383
1384
1385static int acpi_device_suspend(struct device * dev, pm_message_t state)
1386{
1387 struct acpi_device * acpi_dev = to_acpi_dev(dev);
1388
1389 /*
1390 * For now, we should only register 1 generic device -
1391 * the ACPI root device - and from there, we walk the
1392 * tree of ACPI devices to suspend each one using the
1393 * ACPI driver methods.
1394 */
1395 if (acpi_dev->handle == ACPI_ROOT_OBJECT)
1396 root_suspend(acpi_dev, state);
1397 return 0;
1398}
1399
1400
1401
1402static int root_resume(struct acpi_device * acpi_dev)
1403{
1404 struct acpi_device * dev, * next;
1405 int result;
1406
1407 spin_lock(&acpi_device_lock);
1408 list_for_each_entry_safe(dev, next, &acpi_device_list, g_list) {
1409 if (dev->driver && dev->driver->ops.resume) {
1410 spin_unlock(&acpi_device_lock);
1411 result = dev->driver->ops.resume(dev, 0);
1412 if (result) {
1413 printk(KERN_ERR PREFIX "[%s - %s] resume failed: %d\n",
1414 acpi_device_name(dev),
1415 acpi_device_bid(dev), result);
1416 }
1417 spin_lock(&acpi_device_lock);
1418 }
1419 }
1420 spin_unlock(&acpi_device_lock);
1421 return 0;
1422}
1423
1424
1425static int acpi_device_resume(struct device * dev)
1426{
1427 struct acpi_device * acpi_dev = to_acpi_dev(dev);
1428
1429 /*
1430 * For now, we should only register 1 generic device -
1431 * the ACPI root device - and from there, we walk the
1432 * tree of ACPI devices to resume each one using the
1433 * ACPI driver methods.
1434 */
1435 if (acpi_dev->handle == ACPI_ROOT_OBJECT)
1436 root_resume(acpi_dev);
1437 return 0;
1438}
1439
1440
1441static struct bus_type acpi_bus_type = {
1442 .name = "acpi",
1443 .suspend = acpi_device_suspend,
1444 .resume = acpi_device_resume,
1445};
1446
1447
1448
1449static int __init acpi_scan_init(void) 1382static int __init acpi_scan_init(void)
1450{ 1383{
1451 int result; 1384 int result;
@@ -1455,9 +1388,9 @@ static int __init acpi_scan_init(void)
1455 if (acpi_disabled) 1388 if (acpi_disabled)
1456 return 0; 1389 return 0;
1457 1390
1458 result = kset_register(&acpi_namespace_kset); 1391 memset(&ops, 0, sizeof(ops));
1459 if (result < 0) 1392 ops.acpi_op_add = 1;
1460 printk(KERN_ERR PREFIX "kset_register error: %d\n", result); 1393 ops.acpi_op_start = 1;
1461 1394
1462 result = bus_register(&acpi_bus_type); 1395 result = bus_register(&acpi_bus_type);
1463 if (result) { 1396 if (result) {
@@ -1469,32 +1402,16 @@ static int __init acpi_scan_init(void)
1469 * Create the root device in the bus's device tree 1402 * Create the root device in the bus's device tree
1470 */ 1403 */
1471 result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT, 1404 result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
1472 ACPI_BUS_TYPE_SYSTEM); 1405 ACPI_BUS_TYPE_SYSTEM, &ops);
1473 if (result) 1406 if (result)
1474 goto Done; 1407 goto Done;
1475 1408
1476 result = acpi_start_single_object(acpi_root);
1477 if (result)
1478 goto Done;
1479
1480 acpi_root->dev.bus = &acpi_bus_type;
1481 snprintf(acpi_root->dev.bus_id, BUS_ID_SIZE, "%s", acpi_bus_type.name);
1482 result = device_register(&acpi_root->dev);
1483 if (result) {
1484 /* We don't want to quit even if we failed to add suspend/resume */
1485 printk(KERN_ERR PREFIX "Could not register device\n");
1486 }
1487
1488 /* 1409 /*
1489 * Enumerate devices in the ACPI namespace. 1410 * Enumerate devices in the ACPI namespace.
1490 */ 1411 */
1491 result = acpi_bus_scan_fixed(acpi_root); 1412 result = acpi_bus_scan_fixed(acpi_root);
1492 if (!result) { 1413 if (!result)
1493 memset(&ops, 0, sizeof(ops));
1494 ops.acpi_op_add = 1;
1495 ops.acpi_op_start = 1;
1496 result = acpi_bus_scan(acpi_root, &ops); 1414 result = acpi_bus_scan(acpi_root, &ops);
1497 }
1498 1415
1499 if (result) 1416 if (result)
1500 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); 1417 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 2d425d845821..7147b0bdab0a 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -32,6 +32,11 @@
32 32
33#define _COMPONENT ACPI_SYSTEM_COMPONENT 33#define _COMPONENT ACPI_SYSTEM_COMPONENT
34ACPI_MODULE_NAME("acpi_system") 34ACPI_MODULE_NAME("acpi_system")
35#ifdef MODULE_PARAM_PREFIX
36#undef MODULE_PARAM_PREFIX
37#endif
38#define MODULE_PARAM_PREFIX "acpi."
39
35#define ACPI_SYSTEM_CLASS "system" 40#define ACPI_SYSTEM_CLASS "system"
36#define ACPI_SYSTEM_DRIVER_NAME "ACPI System Driver" 41#define ACPI_SYSTEM_DRIVER_NAME "ACPI System Driver"
37#define ACPI_SYSTEM_DEVICE_NAME "System" 42#define ACPI_SYSTEM_DEVICE_NAME "System"
@@ -40,9 +45,23 @@ ACPI_MODULE_NAME("acpi_system")
40#define ACPI_SYSTEM_FILE_DSDT "dsdt" 45#define ACPI_SYSTEM_FILE_DSDT "dsdt"
41#define ACPI_SYSTEM_FILE_FADT "fadt" 46#define ACPI_SYSTEM_FILE_FADT "fadt"
42 47
48/*
49 * Make ACPICA version work as module param
50 */
51static int param_get_acpica_version(char *buffer, struct kernel_param *kp) {
52 int result;
53
54 result = sprintf(buffer, "%x", ACPI_CA_VERSION);
55
56 return result;
57}
58
59module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);
60
43/* -------------------------------------------------------------------------- 61/* --------------------------------------------------------------------------
44 FS Interface (/proc) 62 FS Interface (/proc)
45 -------------------------------------------------------------------------- */ 63 -------------------------------------------------------------------------- */
64#ifdef CONFIG_ACPI_PROCFS
46 65
47static int acpi_system_read_info(struct seq_file *seq, void *offset) 66static int acpi_system_read_info(struct seq_file *seq, void *offset)
48{ 67{
@@ -62,6 +81,7 @@ static const struct file_operations acpi_system_info_ops = {
62 .llseek = seq_lseek, 81 .llseek = seq_lseek,
63 .release = single_release, 82 .release = single_release,
64}; 83};
84#endif
65 85
66static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t, 86static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
67 loff_t *); 87 loff_t *);
@@ -125,6 +145,7 @@ static int __init acpi_system_init(void)
125 if (acpi_disabled) 145 if (acpi_disabled)
126 return 0; 146 return 0;
127 147
148#ifdef CONFIG_ACPI_PROCFS
128 /* 'info' [R] */ 149 /* 'info' [R] */
129 name = ACPI_SYSTEM_FILE_INFO; 150 name = ACPI_SYSTEM_FILE_INFO;
130 entry = create_proc_entry(name, S_IRUGO, acpi_root_dir); 151 entry = create_proc_entry(name, S_IRUGO, acpi_root_dir);
@@ -133,6 +154,7 @@ static int __init acpi_system_init(void)
133 else { 154 else {
134 entry->proc_fops = &acpi_system_info_ops; 155 entry->proc_fops = &acpi_system_info_ops;
135 } 156 }
157#endif
136 158
137 /* 'dsdt' [R] */ 159 /* 'dsdt' [R] */
138 name = ACPI_SYSTEM_FILE_DSDT; 160 name = ACPI_SYSTEM_FILE_DSDT;
@@ -156,7 +178,9 @@ static int __init acpi_system_init(void)
156 Error: 178 Error:
157 remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir); 179 remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir);
158 remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir); 180 remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir);
181#ifdef CONFIG_ACPI_PROCFS
159 remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir); 182 remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir);
183#endif
160 184
161 error = -EFAULT; 185 error = -EFAULT;
162 goto Done; 186 goto Done;
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 40ddb4dd9631..f76d3168c2b2 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -82,7 +82,7 @@ MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n");
82 82
83static int acpi_thermal_add(struct acpi_device *device); 83static int acpi_thermal_add(struct acpi_device *device);
84static int acpi_thermal_remove(struct acpi_device *device, int type); 84static int acpi_thermal_remove(struct acpi_device *device, int type);
85static int acpi_thermal_resume(struct acpi_device *device, int state); 85static int acpi_thermal_resume(struct acpi_device *device);
86static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); 86static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
87static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); 87static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
88static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); 88static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
@@ -1353,7 +1353,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
1353 return 0; 1353 return 0;
1354} 1354}
1355 1355
1356static int acpi_thermal_resume(struct acpi_device *device, int state) 1356static int acpi_thermal_resume(struct acpi_device *device)
1357{ 1357{
1358 struct acpi_thermal *tz = NULL; 1358 struct acpi_thermal *tz = NULL;
1359 int i; 1359 int i;
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 3d54680d0333..e0b97add8c63 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -32,6 +32,7 @@
32#include <linux/proc_fs.h> 32#include <linux/proc_fs.h>
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34 34
35#include <linux/backlight.h>
35#include <asm/uaccess.h> 36#include <asm/uaccess.h>
36 37
37#include <acpi/acpi_bus.h> 38#include <acpi/acpi_bus.h>
@@ -56,6 +57,12 @@
56 57
57#define ACPI_VIDEO_HEAD_INVALID (~0u - 1) 58#define ACPI_VIDEO_HEAD_INVALID (~0u - 1)
58#define ACPI_VIDEO_HEAD_END (~0u) 59#define ACPI_VIDEO_HEAD_END (~0u)
60#define MAX_NAME_LEN 20
61
62#define ACPI_VIDEO_DISPLAY_CRT 1
63#define ACPI_VIDEO_DISPLAY_TV 2
64#define ACPI_VIDEO_DISPLAY_DVI 3
65#define ACPI_VIDEO_DISPLAY_LCD 4
59 66
60#define _COMPONENT ACPI_VIDEO_COMPONENT 67#define _COMPONENT ACPI_VIDEO_COMPONENT
61ACPI_MODULE_NAME("acpi_video") 68ACPI_MODULE_NAME("acpi_video")
@@ -66,16 +73,14 @@ MODULE_LICENSE("GPL");
66 73
67static int acpi_video_bus_add(struct acpi_device *device); 74static int acpi_video_bus_add(struct acpi_device *device);
68static int acpi_video_bus_remove(struct acpi_device *device, int type); 75static int acpi_video_bus_remove(struct acpi_device *device, int type);
69static int acpi_video_bus_match(struct acpi_device *device,
70 struct acpi_driver *driver);
71 76
72static struct acpi_driver acpi_video_bus = { 77static struct acpi_driver acpi_video_bus = {
73 .name = ACPI_VIDEO_DRIVER_NAME, 78 .name = ACPI_VIDEO_DRIVER_NAME,
74 .class = ACPI_VIDEO_CLASS, 79 .class = ACPI_VIDEO_CLASS,
80 .ids = ACPI_VIDEO_HID,
75 .ops = { 81 .ops = {
76 .add = acpi_video_bus_add, 82 .add = acpi_video_bus_add,
77 .remove = acpi_video_bus_remove, 83 .remove = acpi_video_bus_remove,
78 .match = acpi_video_bus_match,
79 }, 84 },
80}; 85};
81 86
@@ -133,20 +138,21 @@ struct acpi_video_device_flags {
133 u8 crt:1; 138 u8 crt:1;
134 u8 lcd:1; 139 u8 lcd:1;
135 u8 tvout:1; 140 u8 tvout:1;
141 u8 dvi:1;
136 u8 bios:1; 142 u8 bios:1;
137 u8 unknown:1; 143 u8 unknown:1;
138 u8 reserved:3; 144 u8 reserved:2;
139}; 145};
140 146
141struct acpi_video_device_cap { 147struct acpi_video_device_cap {
142 u8 _ADR:1; /*Return the unique ID */ 148 u8 _ADR:1; /*Return the unique ID */
143 u8 _BCL:1; /*Query list of brightness control levels supported */ 149 u8 _BCL:1; /*Query list of brightness control levels supported */
144 u8 _BCM:1; /*Set the brightness level */ 150 u8 _BCM:1; /*Set the brightness level */
151 u8 _BQC:1; /* Get current brightness level */
145 u8 _DDC:1; /*Return the EDID for this device */ 152 u8 _DDC:1; /*Return the EDID for this device */
146 u8 _DCS:1; /*Return status of output device */ 153 u8 _DCS:1; /*Return status of output device */
147 u8 _DGS:1; /*Query graphics state */ 154 u8 _DGS:1; /*Query graphics state */
148 u8 _DSS:1; /*Device state set */ 155 u8 _DSS:1; /*Device state set */
149 u8 _reserved:1;
150}; 156};
151 157
152struct acpi_video_device_brightness { 158struct acpi_video_device_brightness {
@@ -163,6 +169,8 @@ struct acpi_video_device {
163 struct acpi_video_bus *video; 169 struct acpi_video_bus *video;
164 struct acpi_device *dev; 170 struct acpi_device *dev;
165 struct acpi_video_device_brightness *brightness; 171 struct acpi_video_device_brightness *brightness;
172 struct backlight_device *backlight;
173 struct backlight_properties *data;
166}; 174};
167 175
168/* bus */ 176/* bus */
@@ -257,11 +265,35 @@ static void acpi_video_device_bind(struct acpi_video_bus *video,
257 struct acpi_video_device *device); 265 struct acpi_video_device *device);
258static int acpi_video_device_enumerate(struct acpi_video_bus *video); 266static int acpi_video_device_enumerate(struct acpi_video_bus *video);
259static int acpi_video_switch_output(struct acpi_video_bus *video, int event); 267static int acpi_video_switch_output(struct acpi_video_bus *video, int event);
268static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,
269 int level);
270static int acpi_video_device_lcd_get_level_current(
271 struct acpi_video_device *device,
272 unsigned long *level);
260static int acpi_video_get_next_level(struct acpi_video_device *device, 273static int acpi_video_get_next_level(struct acpi_video_device *device,
261 u32 level_current, u32 event); 274 u32 level_current, u32 event);
262static void acpi_video_switch_brightness(struct acpi_video_device *device, 275static void acpi_video_switch_brightness(struct acpi_video_device *device,
263 int event); 276 int event);
264 277
278/*backlight device sysfs support*/
279static int acpi_video_get_brightness(struct backlight_device *bd)
280{
281 unsigned long cur_level;
282 struct acpi_video_device *vd =
283 (struct acpi_video_device *)class_get_devdata(&bd->class_dev);
284 acpi_video_device_lcd_get_level_current(vd, &cur_level);
285 return (int) cur_level;
286}
287
288static int acpi_video_set_brightness(struct backlight_device *bd)
289{
290 int request_level = bd->props->brightness;
291 struct acpi_video_device *vd =
292 (struct acpi_video_device *)class_get_devdata(&bd->class_dev);
293 acpi_video_device_lcd_set_level(vd, request_level);
294 return 0;
295}
296
265/* -------------------------------------------------------------------------- 297/* --------------------------------------------------------------------------
266 Video Management 298 Video Management
267 -------------------------------------------------------------------------- */ 299 -------------------------------------------------------------------------- */
@@ -499,6 +531,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
499 acpi_integer status; 531 acpi_integer status;
500 acpi_handle h_dummy1; 532 acpi_handle h_dummy1;
501 int i; 533 int i;
534 u32 max_level = 0;
502 union acpi_object *obj = NULL; 535 union acpi_object *obj = NULL;
503 struct acpi_video_device_brightness *br = NULL; 536 struct acpi_video_device_brightness *br = NULL;
504 537
@@ -514,6 +547,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
514 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) { 547 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) {
515 device->cap._BCM = 1; 548 device->cap._BCM = 1;
516 } 549 }
550 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
551 device->cap._BQC = 1;
517 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { 552 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
518 device->cap._DDC = 1; 553 device->cap._DDC = 1;
519 } 554 }
@@ -550,6 +585,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
550 continue; 585 continue;
551 } 586 }
552 br->levels[count] = (u32) o->integer.value; 587 br->levels[count] = (u32) o->integer.value;
588 if (br->levels[count] > max_level)
589 max_level = br->levels[count];
553 count++; 590 count++;
554 } 591 }
555 out: 592 out:
@@ -568,6 +605,37 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
568 605
569 kfree(obj); 606 kfree(obj);
570 607
608 if (device->cap._BCL && device->cap._BCM && device->cap._BQC){
609 unsigned long tmp;
610 static int count = 0;
611 char *name;
612 struct backlight_properties *acpi_video_data;
613
614 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
615 if (!name)
616 return;
617
618 acpi_video_data = kzalloc(
619 sizeof(struct backlight_properties),
620 GFP_KERNEL);
621 if (!acpi_video_data){
622 kfree(name);
623 return;
624 }
625 acpi_video_data->owner = THIS_MODULE;
626 acpi_video_data->get_brightness =
627 acpi_video_get_brightness;
628 acpi_video_data->update_status =
629 acpi_video_set_brightness;
630 sprintf(name, "acpi_video%d", count++);
631 device->data = acpi_video_data;
632 acpi_video_data->max_brightness = max_level;
633 acpi_video_device_lcd_get_level_current(device, &tmp);
634 acpi_video_data->brightness = (int)tmp;
635 device->backlight = backlight_device_register(name,
636 NULL, device, acpi_video_data);
637 kfree(name);
638 }
571 return; 639 return;
572} 640}
573 641
@@ -668,6 +736,8 @@ static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset)
668 seq_printf(seq, "LCD\n"); 736 seq_printf(seq, "LCD\n");
669 else if (dev->flags.tvout) 737 else if (dev->flags.tvout)
670 seq_printf(seq, "TVOUT\n"); 738 seq_printf(seq, "TVOUT\n");
739 else if (dev->flags.dvi)
740 seq_printf(seq, "DVI\n");
671 else 741 else
672 seq_printf(seq, "UNKNOWN\n"); 742 seq_printf(seq, "UNKNOWN\n");
673 743
@@ -1242,6 +1312,16 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device)
1242 -------------------------------------------------------------------------- */ 1312 -------------------------------------------------------------------------- */
1243 1313
1244/* device interface */ 1314/* device interface */
1315static struct acpi_video_device_attrib*
1316acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id)
1317{
1318 int count;
1319
1320 for(count = 0; count < video->attached_count; count++)
1321 if((video->attached_array[count].value.int_val & 0xffff) == device_id)
1322 return &(video->attached_array[count].value.attrib);
1323 return NULL;
1324}
1245 1325
1246static int 1326static int
1247acpi_video_bus_get_one_device(struct acpi_device *device, 1327acpi_video_bus_get_one_device(struct acpi_device *device,
@@ -1250,7 +1330,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
1250 unsigned long device_id; 1330 unsigned long device_id;
1251 int status; 1331 int status;
1252 struct acpi_video_device *data; 1332 struct acpi_video_device *data;
1253 1333 struct acpi_video_device_attrib* attribute;
1254 1334
1255 if (!device || !video) 1335 if (!device || !video)
1256 return -EINVAL; 1336 return -EINVAL;
@@ -1271,20 +1351,30 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
1271 data->video = video; 1351 data->video = video;
1272 data->dev = device; 1352 data->dev = device;
1273 1353
1274 switch (device_id & 0xffff) { 1354 attribute = acpi_video_get_device_attr(video, device_id);
1275 case 0x0100: 1355
1276 data->flags.crt = 1; 1356 if((attribute != NULL) && attribute->device_id_scheme) {
1277 break; 1357 switch (attribute->display_type) {
1278 case 0x0400: 1358 case ACPI_VIDEO_DISPLAY_CRT:
1279 data->flags.lcd = 1; 1359 data->flags.crt = 1;
1280 break; 1360 break;
1281 case 0x0200: 1361 case ACPI_VIDEO_DISPLAY_TV:
1282 data->flags.tvout = 1; 1362 data->flags.tvout = 1;
1283 break; 1363 break;
1284 default: 1364 case ACPI_VIDEO_DISPLAY_DVI:
1365 data->flags.dvi = 1;
1366 break;
1367 case ACPI_VIDEO_DISPLAY_LCD:
1368 data->flags.lcd = 1;
1369 break;
1370 default:
1371 data->flags.unknown = 1;
1372 break;
1373 }
1374 if(attribute->bios_can_detect)
1375 data->flags.bios = 1;
1376 } else
1285 data->flags.unknown = 1; 1377 data->flags.unknown = 1;
1286 break;
1287 }
1288 1378
1289 acpi_video_device_bind(video, data); 1379 acpi_video_device_bind(video, data);
1290 acpi_video_device_find_cap(data); 1380 acpi_video_device_find_cap(data);
@@ -1588,7 +1678,10 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
1588 status = acpi_remove_notify_handler(device->dev->handle, 1678 status = acpi_remove_notify_handler(device->dev->handle,
1589 ACPI_DEVICE_NOTIFY, 1679 ACPI_DEVICE_NOTIFY,
1590 acpi_video_device_notify); 1680 acpi_video_device_notify);
1591 1681 if (device->backlight){
1682 backlight_device_unregister(device->backlight);
1683 kfree(device->data);
1684 }
1592 return 0; 1685 return 0;
1593} 1686}
1594 1687
@@ -1790,39 +1883,6 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
1790 return 0; 1883 return 0;
1791} 1884}
1792 1885
1793static int
1794acpi_video_bus_match(struct acpi_device *device, struct acpi_driver *driver)
1795{
1796 acpi_handle h_dummy1;
1797 acpi_handle h_dummy2;
1798 acpi_handle h_dummy3;
1799
1800
1801 if (!device || !driver)
1802 return -EINVAL;
1803
1804 /* Since there is no HID, CID for ACPI Video drivers, we have
1805 * to check well known required nodes for each feature we support.
1806 */
1807
1808 /* Does this device able to support video switching ? */
1809 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) &&
1810 ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2)))
1811 return 0;
1812
1813 /* Does this device able to retrieve a video ROM ? */
1814 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1)))
1815 return 0;
1816
1817 /* Does this device able to configure which video head to be POSTed ? */
1818 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) &&
1819 ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) &&
1820 ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3)))
1821 return 0;
1822
1823 return -ENODEV;
1824}
1825
1826static int __init acpi_video_init(void) 1886static int __init acpi_video_init(void)
1827{ 1887{
1828 int result = 0; 1888 int result = 0;