diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-04 19:38:36 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-04 19:38:36 -0500 |
commit | 4da5cc2cec8caec1d357053e85a7a32f243f93a1 (patch) | |
tree | 3f8b603af4af88f86be7ec1d4e3639a7fc9dd1a6 /drivers | |
parent | 25c862cc9ea9b312c25a9f577f91b973131f1261 (diff) | |
parent | c6f43290ae687c11cdcd150d8bfeb57ec29cfa5b (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/perex/alsa
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pnp/card.c | 25 | ||||
-rw-r--r-- | drivers/pnp/driver.c | 47 | ||||
-rw-r--r-- | drivers/pnp/manager.c | 78 |
3 files changed, 131 insertions, 19 deletions
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c index bd7c966ea2d7..0ecbe4edbec1 100644 --- a/drivers/pnp/card.c +++ b/drivers/pnp/card.c | |||
@@ -69,6 +69,7 @@ static int card_probe(struct pnp_card * card, struct pnp_card_driver * drv) | |||
69 | return 0; | 69 | return 0; |
70 | clink->card = card; | 70 | clink->card = card; |
71 | clink->driver = drv; | 71 | clink->driver = drv; |
72 | clink->pm_state = PMSG_ON; | ||
72 | if (drv->probe) { | 73 | if (drv->probe) { |
73 | if (drv->probe(clink, id)>=0) | 74 | if (drv->probe(clink, id)>=0) |
74 | return 1; | 75 | return 1; |
@@ -333,6 +334,28 @@ void pnp_release_card_device(struct pnp_dev * dev) | |||
333 | up_write(&dev->dev.bus->subsys.rwsem); | 334 | up_write(&dev->dev.bus->subsys.rwsem); |
334 | } | 335 | } |
335 | 336 | ||
337 | /* | ||
338 | * suspend/resume callbacks | ||
339 | */ | ||
340 | static int card_suspend(struct pnp_dev *dev, pm_message_t state) | ||
341 | { | ||
342 | struct pnp_card_link *link = dev->card_link; | ||
343 | if (link->pm_state.event == state.event) | ||
344 | return 0; | ||
345 | link->pm_state = state; | ||
346 | return link->driver->suspend(link, state); | ||
347 | } | ||
348 | |||
349 | static int card_resume(struct pnp_dev *dev) | ||
350 | { | ||
351 | struct pnp_card_link *link = dev->card_link; | ||
352 | if (link->pm_state.event == PM_EVENT_ON) | ||
353 | return 0; | ||
354 | link->pm_state = PMSG_ON; | ||
355 | link->driver->resume(link); | ||
356 | return 0; | ||
357 | } | ||
358 | |||
336 | /** | 359 | /** |
337 | * pnp_register_card_driver - registers a PnP card driver with the PnP Layer | 360 | * pnp_register_card_driver - registers a PnP card driver with the PnP Layer |
338 | * @drv: pointer to the driver to register | 361 | * @drv: pointer to the driver to register |
@@ -348,6 +371,8 @@ int pnp_register_card_driver(struct pnp_card_driver * drv) | |||
348 | drv->link.flags = drv->flags; | 371 | drv->link.flags = drv->flags; |
349 | drv->link.probe = NULL; | 372 | drv->link.probe = NULL; |
350 | drv->link.remove = &card_remove_first; | 373 | drv->link.remove = &card_remove_first; |
374 | drv->link.suspend = drv->suspend ? card_suspend : NULL; | ||
375 | drv->link.resume = drv->resume ? card_resume : NULL; | ||
351 | 376 | ||
352 | spin_lock(&pnp_lock); | 377 | spin_lock(&pnp_lock); |
353 | list_add_tail(&drv->global_list, &pnp_card_drivers); | 378 | list_add_tail(&drv->global_list, &pnp_card_drivers); |
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index d3ccce706ab4..15fb758a9e52 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c | |||
@@ -146,10 +146,57 @@ static int pnp_bus_match(struct device *dev, struct device_driver *drv) | |||
146 | return 1; | 146 | return 1; |
147 | } | 147 | } |
148 | 148 | ||
149 | static int pnp_bus_suspend(struct device *dev, pm_message_t state) | ||
150 | { | ||
151 | struct pnp_dev * pnp_dev = to_pnp_dev(dev); | ||
152 | struct pnp_driver * pnp_drv = pnp_dev->driver; | ||
153 | int error; | ||
154 | |||
155 | if (!pnp_drv) | ||
156 | return 0; | ||
157 | |||
158 | if (pnp_drv->suspend) { | ||
159 | error = pnp_drv->suspend(pnp_dev, state); | ||
160 | if (error) | ||
161 | return error; | ||
162 | } | ||
163 | |||
164 | if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE) && | ||
165 | pnp_can_disable(pnp_dev)) { | ||
166 | error = pnp_stop_dev(pnp_dev); | ||
167 | if (error) | ||
168 | return error; | ||
169 | } | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | static int pnp_bus_resume(struct device *dev) | ||
175 | { | ||
176 | struct pnp_dev * pnp_dev = to_pnp_dev(dev); | ||
177 | struct pnp_driver * pnp_drv = pnp_dev->driver; | ||
178 | int error; | ||
179 | |||
180 | if (!pnp_drv) | ||
181 | return 0; | ||
182 | |||
183 | if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE)) { | ||
184 | error = pnp_start_dev(pnp_dev); | ||
185 | if (error) | ||
186 | return error; | ||
187 | } | ||
188 | |||
189 | if (pnp_drv->resume) | ||
190 | return pnp_drv->resume(pnp_dev); | ||
191 | |||
192 | return 0; | ||
193 | } | ||
149 | 194 | ||
150 | struct bus_type pnp_bus_type = { | 195 | struct bus_type pnp_bus_type = { |
151 | .name = "pnp", | 196 | .name = "pnp", |
152 | .match = pnp_bus_match, | 197 | .match = pnp_bus_match, |
198 | .suspend = pnp_bus_suspend, | ||
199 | .resume = pnp_bus_resume, | ||
153 | }; | 200 | }; |
154 | 201 | ||
155 | 202 | ||
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 261668618b2d..c4256aa32bcb 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c | |||
@@ -470,6 +470,53 @@ int pnp_auto_config_dev(struct pnp_dev *dev) | |||
470 | } | 470 | } |
471 | 471 | ||
472 | /** | 472 | /** |
473 | * pnp_start_dev - low-level start of the PnP device | ||
474 | * @dev: pointer to the desired device | ||
475 | * | ||
476 | * assumes that resources have alread been allocated | ||
477 | */ | ||
478 | |||
479 | int pnp_start_dev(struct pnp_dev *dev) | ||
480 | { | ||
481 | if (!pnp_can_write(dev)) { | ||
482 | pnp_info("Device %s does not supported activation.", dev->dev.bus_id); | ||
483 | return -EINVAL; | ||
484 | } | ||
485 | |||
486 | if (dev->protocol->set(dev, &dev->res)<0) { | ||
487 | pnp_err("Failed to activate device %s.", dev->dev.bus_id); | ||
488 | return -EIO; | ||
489 | } | ||
490 | |||
491 | pnp_info("Device %s activated.", dev->dev.bus_id); | ||
492 | |||
493 | return 0; | ||
494 | } | ||
495 | |||
496 | /** | ||
497 | * pnp_stop_dev - low-level disable of the PnP device | ||
498 | * @dev: pointer to the desired device | ||
499 | * | ||
500 | * does not free resources | ||
501 | */ | ||
502 | |||
503 | int pnp_stop_dev(struct pnp_dev *dev) | ||
504 | { | ||
505 | if (!pnp_can_disable(dev)) { | ||
506 | pnp_info("Device %s does not supported disabling.", dev->dev.bus_id); | ||
507 | return -EINVAL; | ||
508 | } | ||
509 | if (dev->protocol->disable(dev)<0) { | ||
510 | pnp_err("Failed to disable device %s.", dev->dev.bus_id); | ||
511 | return -EIO; | ||
512 | } | ||
513 | |||
514 | pnp_info("Device %s disabled.", dev->dev.bus_id); | ||
515 | |||
516 | return 0; | ||
517 | } | ||
518 | |||
519 | /** | ||
473 | * pnp_activate_dev - activates a PnP device for use | 520 | * pnp_activate_dev - activates a PnP device for use |
474 | * @dev: pointer to the desired device | 521 | * @dev: pointer to the desired device |
475 | * | 522 | * |
@@ -477,6 +524,8 @@ int pnp_auto_config_dev(struct pnp_dev *dev) | |||
477 | */ | 524 | */ |
478 | int pnp_activate_dev(struct pnp_dev *dev) | 525 | int pnp_activate_dev(struct pnp_dev *dev) |
479 | { | 526 | { |
527 | int error; | ||
528 | |||
480 | if (!dev) | 529 | if (!dev) |
481 | return -EINVAL; | 530 | return -EINVAL; |
482 | if (dev->active) { | 531 | if (dev->active) { |
@@ -487,18 +536,11 @@ int pnp_activate_dev(struct pnp_dev *dev) | |||
487 | if (pnp_auto_config_dev(dev)) | 536 | if (pnp_auto_config_dev(dev)) |
488 | return -EBUSY; | 537 | return -EBUSY; |
489 | 538 | ||
490 | if (!pnp_can_write(dev)) { | 539 | error = pnp_start_dev(dev); |
491 | pnp_info("Device %s does not supported activation.", dev->dev.bus_id); | 540 | if (error) |
492 | return -EINVAL; | 541 | return error; |
493 | } | ||
494 | |||
495 | if (dev->protocol->set(dev, &dev->res)<0) { | ||
496 | pnp_err("Failed to activate device %s.", dev->dev.bus_id); | ||
497 | return -EIO; | ||
498 | } | ||
499 | 542 | ||
500 | dev->active = 1; | 543 | dev->active = 1; |
501 | pnp_info("Device %s activated.", dev->dev.bus_id); | ||
502 | 544 | ||
503 | return 1; | 545 | return 1; |
504 | } | 546 | } |
@@ -511,23 +553,19 @@ int pnp_activate_dev(struct pnp_dev *dev) | |||
511 | */ | 553 | */ |
512 | int pnp_disable_dev(struct pnp_dev *dev) | 554 | int pnp_disable_dev(struct pnp_dev *dev) |
513 | { | 555 | { |
556 | int error; | ||
557 | |||
514 | if (!dev) | 558 | if (!dev) |
515 | return -EINVAL; | 559 | return -EINVAL; |
516 | if (!dev->active) { | 560 | if (!dev->active) { |
517 | return 0; /* the device is already disabled */ | 561 | return 0; /* the device is already disabled */ |
518 | } | 562 | } |
519 | 563 | ||
520 | if (!pnp_can_disable(dev)) { | 564 | error = pnp_stop_dev(dev); |
521 | pnp_info("Device %s does not supported disabling.", dev->dev.bus_id); | 565 | if (error) |
522 | return -EINVAL; | 566 | return error; |
523 | } | ||
524 | if (dev->protocol->disable(dev)<0) { | ||
525 | pnp_err("Failed to disable device %s.", dev->dev.bus_id); | ||
526 | return -EIO; | ||
527 | } | ||
528 | 567 | ||
529 | dev->active = 0; | 568 | dev->active = 0; |
530 | pnp_info("Device %s disabled.", dev->dev.bus_id); | ||
531 | 569 | ||
532 | /* release the resources so that other devices can use them */ | 570 | /* release the resources so that other devices can use them */ |
533 | down(&pnp_res_mutex); | 571 | down(&pnp_res_mutex); |
@@ -558,6 +596,8 @@ EXPORT_SYMBOL(pnp_manual_config_dev); | |||
558 | #if 0 | 596 | #if 0 |
559 | EXPORT_SYMBOL(pnp_auto_config_dev); | 597 | EXPORT_SYMBOL(pnp_auto_config_dev); |
560 | #endif | 598 | #endif |
599 | EXPORT_SYMBOL(pnp_start_dev); | ||
600 | EXPORT_SYMBOL(pnp_stop_dev); | ||
561 | EXPORT_SYMBOL(pnp_activate_dev); | 601 | EXPORT_SYMBOL(pnp_activate_dev); |
562 | EXPORT_SYMBOL(pnp_disable_dev); | 602 | EXPORT_SYMBOL(pnp_disable_dev); |
563 | EXPORT_SYMBOL(pnp_resource_change); | 603 | EXPORT_SYMBOL(pnp_resource_change); |