aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/feature-removal-schedule.txt10
-rw-r--r--drivers/acpi/Kconfig14
-rw-r--r--drivers/acpi/Makefile2
-rw-r--r--drivers/acpi/battery.c4
-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/fan.c8
-rw-r--r--drivers/acpi/motherboard.c19
-rw-r--r--drivers/acpi/pci_root.c25
-rw-r--r--drivers/acpi/processor_core.c8
-rw-r--r--drivers/acpi/scan.c1176
-rw-r--r--drivers/acpi/system.c24
-rw-r--r--drivers/acpi/thermal.c4
-rw-r--r--drivers/acpi/video.c37
-rw-r--r--include/acpi/acpi_bus.h22
-rw-r--r--include/acpi/acpi_drivers.h13
18 files changed, 717 insertions, 721 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 0ba6af02cdaf..b3d1ce7e3ba0 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -274,6 +274,7 @@ Who: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
274 274
275--------------------------- 275---------------------------
276 276
277<<<<<<< test:Documentation/feature-removal-schedule.txt
277What: ACPI hotkey driver (CONFIG_ACPI_HOTKEY) 278What: ACPI hotkey driver (CONFIG_ACPI_HOTKEY)
278When: 2.6.21 279When: 2.6.21
279Why: hotkey.c was an attempt to consolidate multiple drivers that use 280Why: hotkey.c was an attempt to consolidate multiple drivers that use
@@ -306,11 +307,18 @@ Why: The ACPI namespace is effectively the symbol list for
306 the BIOS can be extracted and disassembled with acpidump 307 the BIOS can be extracted and disassembled with acpidump
307 and iasl as documented in the pmtools package here: 308 and iasl as documented in the pmtools package here:
308 http://ftp.kernel.org/pub/linux/kernel/people/lenb/acpi/utils 309 http://ftp.kernel.org/pub/linux/kernel/people/lenb/acpi/utils
309
310Who: Len Brown <len.brown@intel.com> 310Who: Len Brown <len.brown@intel.com>
311 311
312--------------------------- 312---------------------------
313 313
314What: ACPI procfs interface
315When: July 2007
316Why: After ACPI sysfs conversion, ACPI attributes will be duplicated
317 in sysfs and the ACPI procfs interface should be removed.
318Who: Zhang Rui <rui.zhang@intel.com>
319
320---------------------------
321
314What: /proc/acpi/button 322What: /proc/acpi/button
315When: August 2007 323When: August 2007
316Why: /proc/acpi/button has been replaced by events to the input layer 324Why: /proc/acpi/button has been replaced by events to the input layer
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 1422a11b5bbd..5c087a5bddf8 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -77,6 +77,20 @@ config ACPI_SLEEP_PROC_SLEEP
77 Create /proc/acpi/sleep 77 Create /proc/acpi/sleep
78 Deprecated by /sys/power/state 78 Deprecated by /sys/power/state
79 79
80config ACPI_PROCFS
81 bool "Procfs interface (deprecated)"
82 depends on ACPI
83 default y
84 ---help---
85 Procfs interface for ACPI is made optional for back-compatible.
86 As the same functions are duplicated in sysfs interface
87 and this proc interface will be removed some time later,
88 it's marked as deprecated.
89 ( /proc/acpi/debug_layer && debug_level are deprecated by
90 /sys/module/acpi/parameters/debug_layer && debug_level.
91 /proc/acpi/info is deprecated by
92 /sys/module/acpi/parameters/acpica_version )
93
80config ACPI_AC 94config ACPI_AC
81 tristate "AC Adapter" 95 tristate "AC Adapter"
82 depends on X86 96 depends on X86
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 1a738056558f..399b0e8c41c4 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -37,6 +37,7 @@ 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 motherboard.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
@@ -57,7 +58,6 @@ obj-$(CONFIG_ACPI_NUMA) += numa.o
57obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o 58obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o
58obj-$(CONFIG_ACPI_IBM) += ibm_acpi.o 59obj-$(CONFIG_ACPI_IBM) += ibm_acpi.o
59obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o 60obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
60obj-y += scan.o motherboard.o
61obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o 61obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
62obj-y += cm_sbs.o 62obj-y += cm_sbs.o
63obj-$(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/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/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/motherboard.c b/drivers/acpi/motherboard.c
index b61107b05262..8f13b4f3e906 100644
--- a/drivers/acpi/motherboard.c
+++ b/drivers/acpi/motherboard.c
@@ -33,8 +33,7 @@
33ACPI_MODULE_NAME("acpi_motherboard") 33ACPI_MODULE_NAME("acpi_motherboard")
34 34
35/* Dell use PNP0C01 instead of PNP0C02 */ 35/* Dell use PNP0C01 instead of PNP0C02 */
36#define ACPI_MB_HID1 "PNP0C01" 36#define ACPI_MB_HID "PNP0C01,PNP0C02"
37#define ACPI_MB_HID2 "PNP0C02"
38/** 37/**
39 * Doesn't care about legacy IO ports, only IO ports beyond 0x1000 are reserved 38 * 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 39 * Doesn't care about the failure of 'request_region', since other may reserve
@@ -110,19 +109,10 @@ static int acpi_motherboard_add(struct acpi_device *device)
110 return 0; 109 return 0;
111} 110}
112 111
113static struct acpi_driver acpi_motherboard_driver1 = { 112static struct acpi_driver acpi_motherboard_driver = {
114 .name = "motherboard", 113 .name = "motherboard",
115 .class = "", 114 .class = "",
116 .ids = ACPI_MB_HID1, 115 .ids = ACPI_MB_HID,
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 = { 116 .ops = {
127 .add = acpi_motherboard_add, 117 .add = acpi_motherboard_add,
128 }, 118 },
@@ -173,8 +163,7 @@ static void __init acpi_reserve_resources(void)
173 163
174static int __init acpi_motherboard_init(void) 164static int __init acpi_motherboard_init(void)
175{ 165{
176 acpi_bus_register_driver(&acpi_motherboard_driver1); 166 acpi_bus_register_driver(&acpi_motherboard_driver);
177 acpi_bus_register_driver(&acpi_motherboard_driver2);
178 /* 167 /*
179 * Guarantee motherboard IO reservation first 168 * Guarantee motherboard IO reservation first
180 * This module must run after scan.c 169 * This module must run after scan.c
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 1f06229040ac..4ecf701687e8 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -165,6 +165,21 @@ static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum)
165 return AE_OK; 165 return AE_OK;
166} 166}
167 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
168static int acpi_pci_root_add(struct acpi_device *device) 183static int acpi_pci_root_add(struct acpi_device *device)
169{ 184{
170 int result = 0; 185 int result = 0;
@@ -173,6 +188,7 @@ static int acpi_pci_root_add(struct acpi_device *device)
173 acpi_status status = AE_OK; 188 acpi_status status = AE_OK;
174 unsigned long value = 0; 189 unsigned long value = 0;
175 acpi_handle handle = NULL; 190 acpi_handle handle = NULL;
191 struct acpi_device *child;
176 192
177 193
178 if (!device) 194 if (!device)
@@ -188,9 +204,6 @@ static int acpi_pci_root_add(struct acpi_device *device)
188 strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); 204 strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
189 acpi_driver_data(device) = root; 205 acpi_driver_data(device) = root;
190 206
191 /*
192 * TBD: Doesn't the bus driver automatically set this?
193 */
194 device->ops.bind = acpi_pci_bind; 207 device->ops.bind = acpi_pci_bind;
195 208
196 /* 209 /*
@@ -312,6 +325,12 @@ static int acpi_pci_root_add(struct acpi_device *device)
312 result = acpi_pci_irq_add_prt(device->handle, root->id.segment, 325 result = acpi_pci_irq_add_prt(device->handle, root->id.segment,
313 root->id.bus); 326 root->id.bus);
314 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
315 end: 334 end:
316 if (result) { 335 if (result) {
317 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..5049230ccf49 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;
27 55
28static void acpi_device_release(struct kobject *kobj) 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}
67
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;
37 ssize_t(*show) (struct acpi_device *, char *);
38 ssize_t(*store) (struct acpi_device *, const char *, size_t);
39};
40 111
41typedef void acpi_device_sysfs_files(struct kobject *, 112static ssize_t
42 const struct attribute *); 113acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) {
114 struct acpi_device *acpi_dev = to_acpi_device(dev);
43 115
44static void setup_sys_fs_device_files(struct acpi_device *dev, 116 return sprintf(buf, "%s\n", acpi_dev->pnp.hardware_id);
45 acpi_device_sysfs_files * func); 117}
118static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL);
46 119
47#define create_sysfs_device_files(dev) \ 120static ssize_t
48 setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_create_file) 121acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) {
49#define remove_sysfs_device_files(dev) \ 122 struct acpi_device *acpi_dev = to_acpi_device(dev);
50 setup_sys_fs_device_files(dev, (acpi_device_sysfs_files *)&sysfs_remove_file) 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;
51 129
52#define to_acpi_device(n) container_of(n, struct acpi_device, kobj) 130 result = sprintf(buf, "%s\n", (char*)path.pointer);
53#define to_handle_attr(n) container_of(n, struct acpi_device_attribute, attr); 131 kfree(path.pointer);
132 end:
133 return result;
134}
135static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL);
54 136
55static ssize_t acpi_device_attr_show(struct kobject *kobj, 137static int acpi_device_setup_files(struct acpi_device *dev)
56 struct attribute *attr, char *buf)
57{ 138{
58 struct acpi_device *device = to_acpi_device(kobj); 139 acpi_status status;
59 struct acpi_device_attribute *attribute = to_handle_attr(attr); 140 acpi_handle temp;
60 return attribute->show ? attribute->show(device, buf) : -EIO; 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 }
151
152 if(dev->flags.hardware_id) {
153 result = device_create_file(&dev->dev, &dev_attr_hid);
154 if(result)
155 goto end;
156 }
157
158 /*
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;
61} 167}
62static ssize_t acpi_device_attr_store(struct kobject *kobj, 168
63 struct attribute *attr, const char *buf, 169static void acpi_device_remove_files(struct acpi_device *dev)
64 size_t len)
65{ 170{
66 struct acpi_device *device = to_acpi_device(kobj); 171 acpi_status status;
67 struct acpi_device_attribute *attribute = to_handle_attr(attr); 172 acpi_handle temp;
68 return attribute->store ? attribute->store(device, buf, len) : -EIO; 173
174 /*
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);
181
182 if(dev->flags.hardware_id)
183 device_remove_file(&dev->dev, &dev_attr_hid);
184 if(dev->handle)
185 device_remove_file(&dev->dev, &dev_attr_path);
69} 186}
187/* --------------------------------------------------------------------------
188 ACPI Bus operations
189 -------------------------------------------------------------------------- */
190static void acpi_device_release(struct device *dev)
191{
192 struct acpi_device *acpi_dev = to_acpi_device(dev);
70 193
71static struct sysfs_ops acpi_device_sysfs_ops = { 194 kfree(acpi_dev->pnp.cid_list);
72 .show = acpi_device_attr_show, 195 kfree(acpi_dev);
73 .store = acpi_device_attr_store, 196}
74};
75 197
76static struct kobj_type ktype_acpi_ns = { 198static int acpi_device_suspend(struct device *dev, pm_message_t state)
77 .sysfs_ops = &acpi_device_sysfs_ops, 199{
78 .release = acpi_device_release, 200 struct acpi_device *acpi_dev = to_acpi_device(dev);
79}; 201 struct acpi_driver *acpi_drv = acpi_dev->driver;
202
203 if (acpi_drv && acpi_drv->ops.suspend)
204 return acpi_drv->ops.suspend(acpi_dev, state);
205 return 0;
206}
80 207
81static int namespace_uevent(struct kset *kset, struct kobject *kobj, 208static int acpi_device_resume(struct device *dev)
82 char **envp, int num_envp, char *buffer,
83 int buffer_size)
84{ 209{
85 struct acpi_device *dev = to_acpi_device(kobj); 210 struct acpi_device *acpi_dev = to_acpi_device(dev);
86 int i = 0; 211 struct acpi_driver *acpi_drv = acpi_dev->driver;
87 int len = 0;
88 212
89 if (!dev->driver) 213 if (acpi_drv && acpi_drv->ops.resume)
90 return 0; 214 return acpi_drv->ops.resume(acpi_dev);
215 return 0;
216}
217
218static int acpi_bus_match(struct device *dev, struct device_driver *drv)
219{
220 struct acpi_device *acpi_dev = to_acpi_device(dev);
221 struct acpi_driver *acpi_drv = to_acpi_driver(drv);
91 222
92 if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, 223 return !acpi_match_ids(acpi_dev, acpi_drv->ids);
93 "PHYSDEVDRIVER=%s", dev->driver->name)) 224}
225
226static int acpi_device_uevent(struct device *dev, char **envp, int num_envp,
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}
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;
97 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;
104 299
105static struct kset acpi_namespace_kset = { 300 if (acpi_drv && acpi_drv->ops.shutdown)
106 .kobj = { 301 acpi_drv->ops.shutdown(acpi_dev);
107 .name = "namespace", 302
108 }, 303 return ;
109 .subsys = &acpi_subsys, 304}
110 .ktype = &ktype_acpi_ns, 305
111 .uevent_ops = &namespace_uevent_ops, 306static struct bus_type acpi_bus_type = {
307 .name = "acpi",
308 .suspend = acpi_device_suspend,
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
570 687
571 spin_lock(&acpi_device_lock); 688 /* Evaluate "_PSx" to see if we can do explicit sets */
572 list_for_each_safe(node, next, &acpi_device_list) { 689 object_name[2] = 'S';
573 struct acpi_device *dev = 690 status = acpi_get_handle(device->handle, object_name, &handle);
574 container_of(node, struct acpi_device, g_list); 691 if (ACPI_SUCCESS(status)) {
575 692 ps->flags.explicit_set = 1;
576 if (dev->driver == drv) { 693 ps->flags.valid = 1;
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 703
664 Done: 704 /* Set defaults for D0 and D3 states (always valid) */
665 return result; 705 device->power.states[ACPI_STATE_D0].flags.valid = 1;
666} 706 device->power.states[ACPI_STATE_D0].power = 100;
667 707 device->power.states[ACPI_STATE_D3].flags.valid = 1;
668/* -------------------------------------------------------------------------- 708 device->power.states[ACPI_STATE_D3].power = 0;
669 Device Enumeration
670 -------------------------------------------------------------------------- */
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,39 @@ 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
785static void acpi_device_set_id(struct acpi_device *device, 840static void acpi_device_set_id(struct acpi_device *device,
786 struct acpi_device *parent, acpi_handle handle, 841 struct acpi_device *parent, acpi_handle handle,
787 int type) 842 int type)
@@ -812,6 +867,12 @@ static void acpi_device_set_id(struct acpi_device *device,
812 device->pnp.bus_address = info->address; 867 device->pnp.bus_address = info->address;
813 device->flags.bus_address = 1; 868 device->flags.bus_address = 1;
814 } 869 }
870
871 if(!(info->valid & (ACPI_VALID_HID | ACPI_VALID_CID))){
872 status = acpi_video_bus_match(device);
873 if(ACPI_SUCCESS(status))
874 hid = ACPI_VIDEO_HID;
875 }
815 break; 876 break;
816 case ACPI_BUS_TYPE_POWER: 877 case ACPI_BUS_TYPE_POWER:
817 hid = ACPI_POWER_HID; 878 hid = ACPI_POWER_HID;
@@ -933,41 +994,22 @@ static void acpi_device_get_debug_info(struct acpi_device *device,
933 994
934static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) 995static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
935{ 996{
936 int result = 0;
937 struct acpi_driver *driver;
938
939
940 if (!dev) 997 if (!dev)
941 return -EINVAL; 998 return -EINVAL;
942 999
943 driver = dev->driver; 1000 dev->removal_type = ACPI_BUS_REMOVAL_EJECT;
944 1001 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 1002
963 if (!rmdevice) 1003 if (!rmdevice)
964 return 0; 1004 return 0;
965 1005
1006 /*
1007 * unbind _ADR-Based Devices when hot removal
1008 */
966 if (dev->flags.bus_address) { 1009 if (dev->flags.bus_address) {
967 if ((dev->parent) && (dev->parent->ops.unbind)) 1010 if ((dev->parent) && (dev->parent->ops.unbind))
968 dev->parent->ops.unbind(dev); 1011 dev->parent->ops.unbind(dev);
969 } 1012 }
970
971 acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT); 1013 acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT);
972 1014
973 return 0; 1015 return 0;
@@ -975,7 +1017,8 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
975 1017
976static int 1018static int
977acpi_add_single_object(struct acpi_device **child, 1019acpi_add_single_object(struct acpi_device **child,
978 struct acpi_device *parent, acpi_handle handle, int type) 1020 struct acpi_device *parent, acpi_handle handle, int type,
1021 struct acpi_bus_ops *ops)
979{ 1022{
980 int result = 0; 1023 int result = 0;
981 struct acpi_device *device = NULL; 1024 struct acpi_device *device = NULL;
@@ -992,6 +1035,8 @@ acpi_add_single_object(struct acpi_device **child,
992 1035
993 device->handle = handle; 1036 device->handle = handle;
994 device->parent = parent; 1037 device->parent = parent;
1038 device->bus_ops = *ops; /* workround for not call .start */
1039
995 1040
996 acpi_device_get_busid(device, handle, type); 1041 acpi_device_get_busid(device, handle, type);
997 1042
@@ -1078,31 +1123,16 @@ acpi_add_single_object(struct acpi_device **child,
1078 1123
1079 acpi_device_get_debug_info(device, handle, type); 1124 acpi_device_get_debug_info(device, handle, type);
1080 1125
1081 acpi_device_register(device, parent); 1126 result = acpi_device_register(device, parent);
1082 1127
1083 /* 1128 /*
1084 * Bind _ADR-Based Devices 1129 * 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 */ 1130 */
1090 if (device->flags.bus_address) { 1131 if (device->flags.bus_address) {
1091 if (device->parent && device->parent->ops.bind) 1132 if (device->parent && device->parent->ops.bind)
1092 device->parent->ops.bind(device); 1133 device->parent->ops.bind(device);
1093 } 1134 }
1094 1135
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: 1136 end:
1107 if (!result) 1137 if (!result)
1108 *child = device; 1138 *child = device;
@@ -1188,14 +1218,14 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)
1188 1218
1189 if (ops->acpi_op_add) 1219 if (ops->acpi_op_add)
1190 status = acpi_add_single_object(&child, parent, 1220 status = acpi_add_single_object(&child, parent,
1191 chandle, type); 1221 chandle, type, ops);
1192 else 1222 else
1193 status = acpi_bus_get_device(chandle, &child); 1223 status = acpi_bus_get_device(chandle, &child);
1194 1224
1195 if (ACPI_FAILURE(status)) 1225 if (ACPI_FAILURE(status))
1196 continue; 1226 continue;
1197 1227
1198 if (ops->acpi_op_start) { 1228 if (ops->acpi_op_start && !(ops->acpi_op_add)) {
1199 status = acpi_start_single_object(child); 1229 status = acpi_start_single_object(child);
1200 if (ACPI_FAILURE(status)) 1230 if (ACPI_FAILURE(status))
1201 continue; 1231 continue;
@@ -1233,13 +1263,13 @@ acpi_bus_add(struct acpi_device **child,
1233 int result; 1263 int result;
1234 struct acpi_bus_ops ops; 1264 struct acpi_bus_ops ops;
1235 1265
1266 memset(&ops, 0, sizeof(ops));
1267 ops.acpi_op_add = 1;
1236 1268
1237 result = acpi_add_single_object(child, parent, handle, type); 1269 result = acpi_add_single_object(child, parent, handle, type, &ops);
1238 if (!result) { 1270 if (!result)
1239 memset(&ops, 0, sizeof(ops));
1240 ops.acpi_op_add = 1;
1241 result = acpi_bus_scan(*child, &ops); 1271 result = acpi_bus_scan(*child, &ops);
1242 } 1272
1243 return result; 1273 return result;
1244} 1274}
1245 1275
@@ -1325,127 +1355,35 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
1325{ 1355{
1326 int result = 0; 1356 int result = 0;
1327 struct acpi_device *device = NULL; 1357 struct acpi_device *device = NULL;
1328 1358 struct acpi_bus_ops ops;
1329 1359
1330 if (!root) 1360 if (!root)
1331 return -ENODEV; 1361 return -ENODEV;
1332 1362
1363 memset(&ops, 0, sizeof(ops));
1364 ops.acpi_op_add = 1;
1365 ops.acpi_op_start = 1;
1366
1333 /* 1367 /*
1334 * Enumerate all fixed-feature devices. 1368 * Enumerate all fixed-feature devices.
1335 */ 1369 */
1336 if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) { 1370 if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) {
1337 result = acpi_add_single_object(&device, acpi_root, 1371 result = acpi_add_single_object(&device, acpi_root,
1338 NULL, 1372 NULL,
1339 ACPI_BUS_TYPE_POWER_BUTTON); 1373 ACPI_BUS_TYPE_POWER_BUTTON,
1340 if (!result) 1374 &ops);
1341 result = acpi_start_single_object(device);
1342 } 1375 }
1343 1376
1344 if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) { 1377 if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
1345 result = acpi_add_single_object(&device, acpi_root, 1378 result = acpi_add_single_object(&device, acpi_root,
1346 NULL, 1379 NULL,
1347 ACPI_BUS_TYPE_SLEEP_BUTTON); 1380 ACPI_BUS_TYPE_SLEEP_BUTTON,
1348 if (!result) 1381 &ops);
1349 result = acpi_start_single_object(device);
1350 } 1382 }
1351 1383
1352 return result; 1384 return result;
1353} 1385}
1354 1386
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) 1387static int __init acpi_scan_init(void)
1450{ 1388{
1451 int result; 1389 int result;
@@ -1455,9 +1393,9 @@ static int __init acpi_scan_init(void)
1455 if (acpi_disabled) 1393 if (acpi_disabled)
1456 return 0; 1394 return 0;
1457 1395
1458 result = kset_register(&acpi_namespace_kset); 1396 memset(&ops, 0, sizeof(ops));
1459 if (result < 0) 1397 ops.acpi_op_add = 1;
1460 printk(KERN_ERR PREFIX "kset_register error: %d\n", result); 1398 ops.acpi_op_start = 1;
1461 1399
1462 result = bus_register(&acpi_bus_type); 1400 result = bus_register(&acpi_bus_type);
1463 if (result) { 1401 if (result) {
@@ -1469,32 +1407,16 @@ static int __init acpi_scan_init(void)
1469 * Create the root device in the bus's device tree 1407 * Create the root device in the bus's device tree
1470 */ 1408 */
1471 result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT, 1409 result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
1472 ACPI_BUS_TYPE_SYSTEM); 1410 ACPI_BUS_TYPE_SYSTEM, &ops);
1473 if (result)
1474 goto Done;
1475
1476 result = acpi_start_single_object(acpi_root);
1477 if (result) 1411 if (result)
1478 goto Done; 1412 goto Done;
1479 1413
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 /* 1414 /*
1489 * Enumerate devices in the ACPI namespace. 1415 * Enumerate devices in the ACPI namespace.
1490 */ 1416 */
1491 result = acpi_bus_scan_fixed(acpi_root); 1417 result = acpi_bus_scan_fixed(acpi_root);
1492 if (!result) { 1418 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); 1419 result = acpi_bus_scan(acpi_root, &ops);
1497 }
1498 1420
1499 if (result) 1421 if (result)
1500 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); 1422 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 a695aeb8b2a7..e0b97add8c63 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -73,16 +73,14 @@ MODULE_LICENSE("GPL");
73 73
74static int acpi_video_bus_add(struct acpi_device *device); 74static int acpi_video_bus_add(struct acpi_device *device);
75static int acpi_video_bus_remove(struct acpi_device *device, int type); 75static int acpi_video_bus_remove(struct acpi_device *device, int type);
76static int acpi_video_bus_match(struct acpi_device *device,
77 struct acpi_driver *driver);
78 76
79static struct acpi_driver acpi_video_bus = { 77static struct acpi_driver acpi_video_bus = {
80 .name = ACPI_VIDEO_DRIVER_NAME, 78 .name = ACPI_VIDEO_DRIVER_NAME,
81 .class = ACPI_VIDEO_CLASS, 79 .class = ACPI_VIDEO_CLASS,
80 .ids = ACPI_VIDEO_HID,
82 .ops = { 81 .ops = {
83 .add = acpi_video_bus_add, 82 .add = acpi_video_bus_add,
84 .remove = acpi_video_bus_remove, 83 .remove = acpi_video_bus_remove,
85 .match = acpi_video_bus_match,
86 }, 84 },
87}; 85};
88 86
@@ -1885,39 +1883,6 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
1885 return 0; 1883 return 0;
1886} 1884}
1887 1885
1888static int
1889acpi_video_bus_match(struct acpi_device *device, struct acpi_driver *driver)
1890{
1891 acpi_handle h_dummy1;
1892 acpi_handle h_dummy2;
1893 acpi_handle h_dummy3;
1894
1895
1896 if (!device || !driver)
1897 return -EINVAL;
1898
1899 /* Since there is no HID, CID for ACPI Video drivers, we have
1900 * to check well known required nodes for each feature we support.
1901 */
1902
1903 /* Does this device able to support video switching ? */
1904 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) &&
1905 ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2)))
1906 return 0;
1907
1908 /* Does this device able to retrieve a video ROM ? */
1909 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1)))
1910 return 0;
1911
1912 /* Does this device able to configure which video head to be POSTed ? */
1913 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) &&
1914 ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) &&
1915 ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3)))
1916 return 0;
1917
1918 return -ENODEV;
1919}
1920
1921static int __init acpi_video_init(void) 1886static int __init acpi_video_init(void)
1922{ 1887{
1923 int result = 0; 1888 int result = 0;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index aef0e55253a9..0d9f984a60a1 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -91,13 +91,12 @@ typedef int (*acpi_op_remove) (struct acpi_device * device, int type);
91typedef int (*acpi_op_lock) (struct acpi_device * device, int type); 91typedef int (*acpi_op_lock) (struct acpi_device * device, int type);
92typedef int (*acpi_op_start) (struct acpi_device * device); 92typedef int (*acpi_op_start) (struct acpi_device * device);
93typedef int (*acpi_op_stop) (struct acpi_device * device, int type); 93typedef int (*acpi_op_stop) (struct acpi_device * device, int type);
94typedef int (*acpi_op_suspend) (struct acpi_device * device, int state); 94typedef int (*acpi_op_suspend) (struct acpi_device * device, pm_message_t state);
95typedef int (*acpi_op_resume) (struct acpi_device * device, int state); 95typedef int (*acpi_op_resume) (struct acpi_device * device);
96typedef int (*acpi_op_scan) (struct acpi_device * device); 96typedef int (*acpi_op_scan) (struct acpi_device * device);
97typedef int (*acpi_op_bind) (struct acpi_device * device); 97typedef int (*acpi_op_bind) (struct acpi_device * device);
98typedef int (*acpi_op_unbind) (struct acpi_device * device); 98typedef int (*acpi_op_unbind) (struct acpi_device * device);
99typedef int (*acpi_op_match) (struct acpi_device * device, 99typedef int (*acpi_op_shutdown) (struct acpi_device * device);
100 struct acpi_driver * driver);
101 100
102struct acpi_bus_ops { 101struct acpi_bus_ops {
103 u32 acpi_op_add:1; 102 u32 acpi_op_add:1;
@@ -110,7 +109,7 @@ struct acpi_bus_ops {
110 u32 acpi_op_scan:1; 109 u32 acpi_op_scan:1;
111 u32 acpi_op_bind:1; 110 u32 acpi_op_bind:1;
112 u32 acpi_op_unbind:1; 111 u32 acpi_op_unbind:1;
113 u32 acpi_op_match:1; 112 u32 acpi_op_shutdown:1;
114 u32 reserved:21; 113 u32 reserved:21;
115}; 114};
116 115
@@ -125,16 +124,16 @@ struct acpi_device_ops {
125 acpi_op_scan scan; 124 acpi_op_scan scan;
126 acpi_op_bind bind; 125 acpi_op_bind bind;
127 acpi_op_unbind unbind; 126 acpi_op_unbind unbind;
128 acpi_op_match match; 127 acpi_op_shutdown shutdown;
129}; 128};
130 129
131struct acpi_driver { 130struct acpi_driver {
132 struct list_head node;
133 char name[80]; 131 char name[80];
134 char class[80]; 132 char class[80];
135 atomic_t references;
136 char *ids; /* Supported Hardware IDs */ 133 char *ids; /* Supported Hardware IDs */
137 struct acpi_device_ops ops; 134 struct acpi_device_ops ops;
135 struct device_driver drv;
136 struct module *owner;
138}; 137};
139 138
140/* 139/*
@@ -184,7 +183,7 @@ struct acpi_device_dir {
184 183
185typedef char acpi_bus_id[5]; 184typedef char acpi_bus_id[5];
186typedef unsigned long acpi_bus_address; 185typedef unsigned long acpi_bus_address;
187typedef char acpi_hardware_id[9]; 186typedef char acpi_hardware_id[15];
188typedef char acpi_unique_id[9]; 187typedef char acpi_unique_id[9];
189typedef char acpi_device_name[40]; 188typedef char acpi_device_name[40];
190typedef char acpi_device_class[20]; 189typedef char acpi_device_class[20];
@@ -295,11 +294,14 @@ struct acpi_device {
295 struct acpi_device_ops ops; 294 struct acpi_device_ops ops;
296 struct acpi_driver *driver; 295 struct acpi_driver *driver;
297 void *driver_data; 296 void *driver_data;
298 struct kobject kobj;
299 struct device dev; 297 struct device dev;
298 struct acpi_bus_ops bus_ops; /* workaround for different code path for hotplug */
299 enum acpi_bus_removal_type removal_type; /* indicate for different removal type */
300}; 300};
301 301
302#define acpi_driver_data(d) ((d)->driver_data) 302#define acpi_driver_data(d) ((d)->driver_data)
303#define to_acpi_device(d) container_of(d, struct acpi_device, dev)
304#define to_acpi_driver(d) container_of(d, struct acpi_driver, drv)
303 305
304/* 306/*
305 * Events 307 * Events
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index baaa734b1098..4dc8a5043ef0 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -36,13 +36,14 @@
36 36
37/* _HID definitions */ 37/* _HID definitions */
38 38
39#define ACPI_POWER_HID "ACPI_PWR" 39#define ACPI_POWER_HID "power_resource"
40#define ACPI_PROCESSOR_HID "ACPI0007" 40#define ACPI_PROCESSOR_HID "ACPI0007"
41#define ACPI_SYSTEM_HID "ACPI_SYS" 41#define ACPI_SYSTEM_HID "acpi_system"
42#define ACPI_THERMAL_HID "ACPI_THM" 42#define ACPI_THERMAL_HID "thermal"
43#define ACPI_BUTTON_HID_POWERF "ACPI_FPB" 43#define ACPI_BUTTON_HID_POWERF "button_power"
44#define ACPI_BUTTON_HID_SLEEPF "ACPI_FSB" 44#define ACPI_BUTTON_HID_SLEEPF "button_sleep"
45 45#define ACPI_VIDEO_HID "video"
46#define ACPI_BAY_HID "bay"
46/* -------------------------------------------------------------------------- 47/* --------------------------------------------------------------------------
47 PCI 48 PCI
48 -------------------------------------------------------------------------- */ 49 -------------------------------------------------------------------------- */