aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Mochel <mochel@linux.intel.com>2006-12-07 07:56:27 -0500
committerLen Brown <len.brown@intel.com>2006-12-15 23:38:34 -0500
commit5d9464a46918ced087c351a10f38cee95725f85b (patch)
treeacb45582f9c43a867a60cc5fa8ae2c6197dc1d2d
parentd43ec68e9837dfa6618ab473622683fdbf6e68a9 (diff)
ACPI: add ACPI bus_type for driver model
Add ACPI bus_type for Linux driver model. 1. .shutdown method is added into acpi_driver.ops needed by bus_type operations. 2. remove useless parameter 'int state' in .resume method. 3. change parameter 'int state' to 'pm_message_t state' in .suspend method. Note: The new .uevent method mark ACPI drivers by PNPID instead of by name. Udev script needs to look for "HWID=" or "COMPTID=" to load ACPI drivers as a result. Signed-off-by: Li Shaohua <shaohua.li@intel.com> Signed-off-by: Zhang Rui <rui.zhang@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r--drivers/acpi/battery.c4
-rw-r--r--drivers/acpi/fan.c8
-rw-r--r--drivers/acpi/scan.c158
-rw-r--r--drivers/acpi/thermal.c4
-rw-r--r--include/acpi/acpi_bus.h9
5 files changed, 105 insertions, 78 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 026e40755cdd..07c3c276ad34 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,
@@ -756,7 +756,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
756} 756}
757 757
758/* this is needed to learn about changes made in suspended state */ 758/* this is needed to learn about changes made in suspended state */
759static int acpi_battery_resume(struct acpi_device *device, int state) 759static int acpi_battery_resume(struct acpi_device *device)
760{ 760{
761 struct acpi_battery *battery; 761 struct acpi_battery *battery;
762 762
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index 045c89477e59..b24942041b3f 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,
@@ -238,7 +238,7 @@ static int acpi_fan_remove(struct acpi_device *device, int type)
238 return 0; 238 return 0;
239} 239}
240 240
241static int acpi_fan_suspend(struct acpi_device *device, int state) 241static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state)
242{ 242{
243 if (!device) 243 if (!device)
244 return -EINVAL; 244 return -EINVAL;
@@ -248,7 +248,7 @@ static int acpi_fan_suspend(struct acpi_device *device, int state)
248 return AE_OK; 248 return AE_OK;
249} 249}
250 250
251static int acpi_fan_resume(struct acpi_device *device, int state) 251static int acpi_fan_resume(struct acpi_device *device)
252{ 252{
253 int result = 0; 253 int result = 0;
254 int power_state = 0; 254 int power_state = 0;
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 5b42948ea97f..464746257d8e 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -222,100 +222,124 @@ acpi_eject_store(struct acpi_device *device, const char *buf, size_t count)
222/* -------------------------------------------------------------------------- 222/* --------------------------------------------------------------------------
223 ACPI Bus operations 223 ACPI Bus operations
224 -------------------------------------------------------------------------- */ 224 -------------------------------------------------------------------------- */
225static int root_suspend(struct acpi_device * acpi_dev, pm_message_t state) 225static int acpi_device_suspend(struct device *dev, pm_message_t state)
226{ 226{
227 struct acpi_device * dev, * next; 227 struct acpi_device *acpi_dev = to_acpi_device(dev);
228 int result; 228 struct acpi_driver *acpi_drv = acpi_dev->driver;
229 229
230 spin_lock(&acpi_device_lock); 230 if (acpi_drv && acpi_drv->ops.suspend)
231 list_for_each_entry_safe_reverse(dev, next, &acpi_device_list, g_list) { 231 return acpi_drv->ops.suspend(acpi_dev, state);
232 if (dev->driver && dev->driver->ops.suspend) {
233 spin_unlock(&acpi_device_lock);
234 result = dev->driver->ops.suspend(dev, 0);
235 if (result) {
236 printk(KERN_ERR PREFIX "[%s - %s] Suspend failed: %d\n",
237 acpi_device_name(dev),
238 acpi_device_bid(dev), result);
239 }
240 spin_lock(&acpi_device_lock);
241 }
242 }
243 spin_unlock(&acpi_device_lock);
244 return 0; 232 return 0;
245} 233}
246 234
247static int acpi_device_suspend(struct device * dev, pm_message_t state) 235static int acpi_device_resume(struct device *dev)
248{ 236{
249 struct acpi_device * acpi_dev = to_acpi_device(dev); 237 struct acpi_device *acpi_dev = to_acpi_device(dev);
238 struct acpi_driver *acpi_drv = acpi_dev->driver;
250 239
251 /* 240 if (acpi_drv && acpi_drv->ops.resume)
252 * For now, we should only register 1 generic device - 241 return acpi_drv->ops.resume(acpi_dev);
253 * the ACPI root device - and from there, we walk the
254 * tree of ACPI devices to suspend each one using the
255 * ACPI driver methods.
256 */
257 if (acpi_dev->handle == ACPI_ROOT_OBJECT)
258 root_suspend(acpi_dev, state);
259 return 0; 242 return 0;
260} 243}
261 244
262static int root_resume(struct acpi_device * acpi_dev) 245static int acpi_bus_match(struct device *dev, struct device_driver *drv)
263{ 246{
264 struct acpi_device * dev, * next; 247 struct acpi_device *acpi_dev = to_acpi_device(dev);
265 int result; 248 struct acpi_driver *acpi_drv = to_acpi_driver(drv);
266 249
267 spin_lock(&acpi_device_lock); 250 if (acpi_drv->ops.match)
268 list_for_each_entry_safe(dev, next, &acpi_device_list, g_list) { 251 return !acpi_drv->ops.match(acpi_dev, acpi_drv);
269 if (dev->driver && dev->driver->ops.resume) { 252 return !acpi_match_ids(acpi_dev, acpi_drv->ids);
270 spin_unlock(&acpi_device_lock); 253}
271 result = dev->driver->ops.resume(dev, 0); 254
272 if (result) { 255static int acpi_device_uevent(struct device *dev, char **envp, int num_envp,
273 printk(KERN_ERR PREFIX "[%s - %s] resume failed: %d\n", 256 char *buffer, int buffer_size)
274 acpi_device_name(dev), 257{
275 acpi_device_bid(dev), result); 258 struct acpi_device *acpi_dev = to_acpi_device(dev);
276 } 259 int i = 0, length = 0, ret = 0;
277 spin_lock(&acpi_device_lock); 260
261 if (acpi_dev->flags.hardware_id)
262 ret = add_uevent_var(envp, num_envp, &i,
263 buffer, buffer_size, &length,
264 "HWID=%s", acpi_dev->pnp.hardware_id);
265 if (ret)
266 return -ENOMEM;
267 if (acpi_dev->flags.compatible_ids) {
268 int j;
269 struct acpi_compatible_id_list *cid_list;
270
271 cid_list = acpi_dev->pnp.cid_list;
272
273 for (j = 0; j < cid_list->count; j++) {
274 ret = add_uevent_var(envp, num_envp, &i, buffer,
275 buffer_size, &length, "COMPTID=%s",
276 cid_list->id[j].value);
277 if (ret)
278 return -ENOMEM;
278 } 279 }
279 } 280 }
280 spin_unlock(&acpi_device_lock); 281
282 envp[i] = NULL;
281 return 0; 283 return 0;
282} 284}
283 285
284static int acpi_device_resume(struct device * dev) 286static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *);
287static int acpi_start_single_object(struct acpi_device *);
288static int acpi_device_probe(struct device * dev)
285{ 289{
286 struct acpi_device * acpi_dev = to_acpi_device(dev); 290 struct acpi_device *acpi_dev = to_acpi_device(dev);
291 struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver);
292 int ret;
293
294 ret = acpi_bus_driver_init(acpi_dev, acpi_drv);
295 if (!ret) {
296 acpi_start_single_object(acpi_dev);
297 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
298 "Found driver [%s] for device [%s]\n",
299 acpi_drv->name, acpi_dev->pnp.bus_id));
300 get_device(dev);
301 }
302 return ret;
303}
287 304
288 /* 305static int acpi_device_remove(struct device * dev)
289 * For now, we should only register 1 generic device - 306{
290 * the ACPI root device - and from there, we walk the 307 struct acpi_device *acpi_dev = to_acpi_device(dev);
291 * tree of ACPI devices to resume each one using the 308 struct acpi_driver *acpi_drv = acpi_dev->driver;
292 * ACPI driver methods. 309
293 */ 310 if (acpi_drv) {
294 if (acpi_dev->handle == ACPI_ROOT_OBJECT) 311 if (acpi_drv->ops.stop)
295 root_resume(acpi_dev); 312 acpi_drv->ops.stop(acpi_dev, ACPI_BUS_REMOVAL_NORMAL);
313 if (acpi_drv->ops.remove)
314 acpi_drv->ops.remove(acpi_dev, ACPI_BUS_REMOVAL_NORMAL);
315 }
316 acpi_dev->driver = NULL;
317 acpi_driver_data(dev) = NULL;
318
319 put_device(dev);
296 return 0; 320 return 0;
297} 321}
298 322
299/** 323static void acpi_device_shutdown(struct device *dev)
300 * acpi_bus_match - match device IDs to driver's supported IDs
301 * @device: the device that we are trying to match to a driver
302 * @driver: driver whose device id table is being checked
303 *
304 * Checks the device's hardware (_HID) or compatible (_CID) ids to see if it
305 * matches the specified driver's criteria.
306 */
307static int
308acpi_bus_match(struct acpi_device *device, struct acpi_driver *driver)
309{ 324{
310 if (driver && driver->ops.match) 325 struct acpi_device *acpi_dev = to_acpi_device(dev);
311 return driver->ops.match(device, driver); 326 struct acpi_driver *acpi_drv = acpi_dev->driver;
312 return acpi_match_ids(device, driver->ids); 327
328 if (acpi_drv && acpi_drv->ops.shutdown)
329 acpi_drv->ops.shutdown(acpi_dev);
330
331 return ;
313} 332}
314 333
315static struct bus_type acpi_bus_type = { 334static struct bus_type acpi_bus_type = {
316 .name = "acpi", 335 .name = "acpi",
317 .suspend = acpi_device_suspend, 336 .suspend = acpi_device_suspend,
318 .resume = acpi_device_resume, 337 .resume = acpi_device_resume,
338 .shutdown = acpi_device_shutdown,
339 .match = acpi_bus_match,
340 .probe = acpi_device_probe,
341 .remove = acpi_device_remove,
342 .uevent = acpi_device_uevent,
319}; 343};
320 344
321static void acpi_device_register(struct acpi_device *device, 345static void acpi_device_register(struct acpi_device *device,
@@ -449,7 +473,7 @@ static void acpi_driver_attach(struct acpi_driver *drv)
449 continue; 473 continue;
450 spin_unlock(&acpi_device_lock); 474 spin_unlock(&acpi_device_lock);
451 475
452 if (!acpi_bus_match(dev, drv)) { 476 if (!acpi_bus_match(&(dev->dev), &(drv->drv))) {
453 if (!acpi_bus_driver_init(dev, drv)) { 477 if (!acpi_bus_driver_init(dev, drv)) {
454 acpi_start_single_object(dev); 478 acpi_start_single_object(dev);
455 atomic_inc(&drv->references); 479 atomic_inc(&drv->references);
@@ -551,7 +575,7 @@ static int acpi_bus_find_driver(struct acpi_device *device)
551 575
552 atomic_inc(&driver->references); 576 atomic_inc(&driver->references);
553 spin_unlock(&acpi_device_lock); 577 spin_unlock(&acpi_device_lock);
554 if (!acpi_bus_match(device, driver)) { 578 if (!acpi_bus_match(&(device->dev), &(driver->drv))) {
555 result = acpi_bus_driver_init(device, driver); 579 result = acpi_bus_driver_init(device, driver);
556 if (!result) 580 if (!result)
557 goto Done; 581 goto Done;
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 5753d06b7860..3650654f878e 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);
@@ -1356,7 +1356,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
1356 return 0; 1356 return 0;
1357} 1357}
1358 1358
1359static int acpi_thermal_resume(struct acpi_device *device, int state) 1359static int acpi_thermal_resume(struct acpi_device *device)
1360{ 1360{
1361 struct acpi_thermal *tz = NULL; 1361 struct acpi_thermal *tz = NULL;
1362 int i; 1362 int i;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index a09538eb61e7..d7dd52615456 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -92,13 +92,14 @@ typedef int (*acpi_op_remove) (struct acpi_device * device, int type);
92typedef int (*acpi_op_lock) (struct acpi_device * device, int type); 92typedef int (*acpi_op_lock) (struct acpi_device * device, int type);
93typedef int (*acpi_op_start) (struct acpi_device * device); 93typedef int (*acpi_op_start) (struct acpi_device * device);
94typedef int (*acpi_op_stop) (struct acpi_device * device, int type); 94typedef int (*acpi_op_stop) (struct acpi_device * device, int type);
95typedef int (*acpi_op_suspend) (struct acpi_device * device, int state); 95typedef int (*acpi_op_suspend) (struct acpi_device * device, pm_message_t state);
96typedef int (*acpi_op_resume) (struct acpi_device * device, int state); 96typedef int (*acpi_op_resume) (struct acpi_device * device);
97typedef int (*acpi_op_scan) (struct acpi_device * device); 97typedef int (*acpi_op_scan) (struct acpi_device * device);
98typedef int (*acpi_op_bind) (struct acpi_device * device); 98typedef int (*acpi_op_bind) (struct acpi_device * device);
99typedef int (*acpi_op_unbind) (struct acpi_device * device); 99typedef int (*acpi_op_unbind) (struct acpi_device * device);
100typedef int (*acpi_op_match) (struct acpi_device * device, 100typedef int (*acpi_op_match) (struct acpi_device * device,
101 struct acpi_driver * driver); 101 struct acpi_driver * driver);
102typedef int (*acpi_op_shutdown) (struct acpi_device * device);
102 103
103struct acpi_bus_ops { 104struct acpi_bus_ops {
104 u32 acpi_op_add:1; 105 u32 acpi_op_add:1;
@@ -112,7 +113,8 @@ struct acpi_bus_ops {
112 u32 acpi_op_bind:1; 113 u32 acpi_op_bind:1;
113 u32 acpi_op_unbind:1; 114 u32 acpi_op_unbind:1;
114 u32 acpi_op_match:1; 115 u32 acpi_op_match:1;
115 u32 reserved:21; 116 u32 acpi_op_shutdown:1;
117 u32 reserved:20;
116}; 118};
117 119
118struct acpi_device_ops { 120struct acpi_device_ops {
@@ -127,6 +129,7 @@ struct acpi_device_ops {
127 acpi_op_bind bind; 129 acpi_op_bind bind;
128 acpi_op_unbind unbind; 130 acpi_op_unbind unbind;
129 acpi_op_match match; 131 acpi_op_match match;
132 acpi_op_shutdown shutdown;
130}; 133};
131 134
132struct acpi_driver { 135struct acpi_driver {