aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-driver.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2008-07-21 00:55:14 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2008-07-21 00:55:14 -0400
commit908cf4b925e419bc74f3297b2f0e51d6f8a81da2 (patch)
tree6c2da79366d4695a9c2560ab18259eca8a2a25b4 /drivers/pci/pci-driver.c
parent92c49890922d54cba4b1eadeb0b185773c2c9570 (diff)
parent14b395e35d1afdd8019d11b92e28041fad591b71 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into next
Diffstat (limited to 'drivers/pci/pci-driver.c')
-rw-r--r--drivers/pci/pci-driver.c390
1 files changed, 347 insertions, 43 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 72cf61ed8f96..a13f53486114 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -181,7 +181,7 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
181 any need to change it. */ 181 any need to change it. */
182 struct mempolicy *oldpol; 182 struct mempolicy *oldpol;
183 cpumask_t oldmask = current->cpus_allowed; 183 cpumask_t oldmask = current->cpus_allowed;
184 int node = pcibus_to_node(dev->bus); 184 int node = dev_to_node(&dev->dev);
185 185
186 if (node >= 0) { 186 if (node >= 0) {
187 node_to_cpumask_ptr(nodecpumask, node); 187 node_to_cpumask_ptr(nodecpumask, node);
@@ -274,7 +274,57 @@ static int pci_device_remove(struct device * dev)
274 return 0; 274 return 0;
275} 275}
276 276
277static int pci_device_suspend(struct device * dev, pm_message_t state) 277static void pci_device_shutdown(struct device *dev)
278{
279 struct pci_dev *pci_dev = to_pci_dev(dev);
280 struct pci_driver *drv = pci_dev->driver;
281
282 if (drv && drv->shutdown)
283 drv->shutdown(pci_dev);
284 pci_msi_shutdown(pci_dev);
285 pci_msix_shutdown(pci_dev);
286}
287
288#ifdef CONFIG_PM_SLEEP
289
290/*
291 * Default "suspend" method for devices that have no driver provided suspend,
292 * or not even a driver at all.
293 */
294static void pci_default_pm_suspend(struct pci_dev *pci_dev)
295{
296 pci_save_state(pci_dev);
297 /*
298 * mark its power state as "unknown", since we don't know if
299 * e.g. the BIOS will change its device state when we suspend.
300 */
301 if (pci_dev->current_state == PCI_D0)
302 pci_dev->current_state = PCI_UNKNOWN;
303}
304
305/*
306 * Default "resume" method for devices that have no driver provided resume,
307 * or not even a driver at all.
308 */
309static int pci_default_pm_resume(struct pci_dev *pci_dev)
310{
311 int retval = 0;
312
313 /* restore the PCI config space */
314 pci_restore_state(pci_dev);
315 /* if the device was enabled before suspend, reenable */
316 retval = pci_reenable_device(pci_dev);
317 /*
318 * if the device was busmaster before the suspend, make it busmaster
319 * again
320 */
321 if (pci_dev->is_busmaster)
322 pci_set_master(pci_dev);
323
324 return retval;
325}
326
327static int pci_legacy_suspend(struct device *dev, pm_message_t state)
278{ 328{
279 struct pci_dev * pci_dev = to_pci_dev(dev); 329 struct pci_dev * pci_dev = to_pci_dev(dev);
280 struct pci_driver * drv = pci_dev->driver; 330 struct pci_driver * drv = pci_dev->driver;
@@ -284,18 +334,12 @@ static int pci_device_suspend(struct device * dev, pm_message_t state)
284 i = drv->suspend(pci_dev, state); 334 i = drv->suspend(pci_dev, state);
285 suspend_report_result(drv->suspend, i); 335 suspend_report_result(drv->suspend, i);
286 } else { 336 } else {
287 pci_save_state(pci_dev); 337 pci_default_pm_suspend(pci_dev);
288 /*
289 * mark its power state as "unknown", since we don't know if
290 * e.g. the BIOS will change its device state when we suspend.
291 */
292 if (pci_dev->current_state == PCI_D0)
293 pci_dev->current_state = PCI_UNKNOWN;
294 } 338 }
295 return i; 339 return i;
296} 340}
297 341
298static int pci_device_suspend_late(struct device * dev, pm_message_t state) 342static int pci_legacy_suspend_late(struct device *dev, pm_message_t state)
299{ 343{
300 struct pci_dev * pci_dev = to_pci_dev(dev); 344 struct pci_dev * pci_dev = to_pci_dev(dev);
301 struct pci_driver * drv = pci_dev->driver; 345 struct pci_driver * drv = pci_dev->driver;
@@ -308,26 +352,7 @@ static int pci_device_suspend_late(struct device * dev, pm_message_t state)
308 return i; 352 return i;
309} 353}
310 354
311/* 355static int pci_legacy_resume(struct device *dev)
312 * Default resume method for devices that have no driver provided resume,
313 * or not even a driver at all.
314 */
315static int pci_default_resume(struct pci_dev *pci_dev)
316{
317 int retval = 0;
318
319 /* restore the PCI config space */
320 pci_restore_state(pci_dev);
321 /* if the device was enabled before suspend, reenable */
322 retval = pci_reenable_device(pci_dev);
323 /* if the device was busmaster before the suspend, make it busmaster again */
324 if (pci_dev->is_busmaster)
325 pci_set_master(pci_dev);
326
327 return retval;
328}
329
330static int pci_device_resume(struct device * dev)
331{ 356{
332 int error; 357 int error;
333 struct pci_dev * pci_dev = to_pci_dev(dev); 358 struct pci_dev * pci_dev = to_pci_dev(dev);
@@ -336,34 +361,313 @@ static int pci_device_resume(struct device * dev)
336 if (drv && drv->resume) 361 if (drv && drv->resume)
337 error = drv->resume(pci_dev); 362 error = drv->resume(pci_dev);
338 else 363 else
339 error = pci_default_resume(pci_dev); 364 error = pci_default_pm_resume(pci_dev);
340 return error; 365 return error;
341} 366}
342 367
343static int pci_device_resume_early(struct device * dev) 368static int pci_legacy_resume_early(struct device *dev)
344{ 369{
345 int error = 0; 370 int error = 0;
346 struct pci_dev * pci_dev = to_pci_dev(dev); 371 struct pci_dev * pci_dev = to_pci_dev(dev);
347 struct pci_driver * drv = pci_dev->driver; 372 struct pci_driver * drv = pci_dev->driver;
348 373
349 pci_fixup_device(pci_fixup_resume, pci_dev);
350
351 if (drv && drv->resume_early) 374 if (drv && drv->resume_early)
352 error = drv->resume_early(pci_dev); 375 error = drv->resume_early(pci_dev);
353 return error; 376 return error;
354} 377}
355 378
356static void pci_device_shutdown(struct device *dev) 379static int pci_pm_prepare(struct device *dev)
380{
381 struct device_driver *drv = dev->driver;
382 int error = 0;
383
384 if (drv && drv->pm && drv->pm->prepare)
385 error = drv->pm->prepare(dev);
386
387 return error;
388}
389
390static void pci_pm_complete(struct device *dev)
391{
392 struct device_driver *drv = dev->driver;
393
394 if (drv && drv->pm && drv->pm->complete)
395 drv->pm->complete(dev);
396}
397
398#ifdef CONFIG_SUSPEND
399
400static int pci_pm_suspend(struct device *dev)
401{
402 struct pci_dev *pci_dev = to_pci_dev(dev);
403 struct device_driver *drv = dev->driver;
404 int error = 0;
405
406 if (drv && drv->pm) {
407 if (drv->pm->suspend) {
408 error = drv->pm->suspend(dev);
409 suspend_report_result(drv->pm->suspend, error);
410 } else {
411 pci_default_pm_suspend(pci_dev);
412 }
413 } else {
414 error = pci_legacy_suspend(dev, PMSG_SUSPEND);
415 }
416 pci_fixup_device(pci_fixup_suspend, pci_dev);
417
418 return error;
419}
420
421static int pci_pm_suspend_noirq(struct device *dev)
357{ 422{
358 struct pci_dev *pci_dev = to_pci_dev(dev); 423 struct pci_dev *pci_dev = to_pci_dev(dev);
359 struct pci_driver *drv = pci_dev->driver; 424 struct pci_driver *drv = pci_dev->driver;
425 int error = 0;
360 426
361 if (drv && drv->shutdown) 427 if (drv && drv->pm) {
362 drv->shutdown(pci_dev); 428 if (drv->pm->suspend_noirq) {
363 pci_msi_shutdown(pci_dev); 429 error = drv->pm->suspend_noirq(dev);
364 pci_msix_shutdown(pci_dev); 430 suspend_report_result(drv->pm->suspend_noirq, error);
431 }
432 } else {
433 error = pci_legacy_suspend_late(dev, PMSG_SUSPEND);
434 }
435
436 return error;
365} 437}
366 438
439static int pci_pm_resume(struct device *dev)
440{
441 struct pci_dev *pci_dev = to_pci_dev(dev);
442 struct device_driver *drv = dev->driver;
443 int error;
444
445 pci_fixup_device(pci_fixup_resume, pci_dev);
446
447 if (drv && drv->pm) {
448 error = drv->pm->resume ? drv->pm->resume(dev) :
449 pci_default_pm_resume(pci_dev);
450 } else {
451 error = pci_legacy_resume(dev);
452 }
453
454 return error;
455}
456
457static int pci_pm_resume_noirq(struct device *dev)
458{
459 struct pci_dev *pci_dev = to_pci_dev(dev);
460 struct pci_driver *drv = pci_dev->driver;
461 int error = 0;
462
463 pci_fixup_device(pci_fixup_resume_early, pci_dev);
464
465 if (drv && drv->pm) {
466 if (drv->pm->resume_noirq)
467 error = drv->pm->resume_noirq(dev);
468 } else {
469 error = pci_legacy_resume_early(dev);
470 }
471
472 return error;
473}
474
475#else /* !CONFIG_SUSPEND */
476
477#define pci_pm_suspend NULL
478#define pci_pm_suspend_noirq NULL
479#define pci_pm_resume NULL
480#define pci_pm_resume_noirq NULL
481
482#endif /* !CONFIG_SUSPEND */
483
484#ifdef CONFIG_HIBERNATION
485
486static int pci_pm_freeze(struct device *dev)
487{
488 struct pci_dev *pci_dev = to_pci_dev(dev);
489 struct device_driver *drv = dev->driver;
490 int error = 0;
491
492 if (drv && drv->pm) {
493 if (drv->pm->freeze) {
494 error = drv->pm->freeze(dev);
495 suspend_report_result(drv->pm->freeze, error);
496 } else {
497 pci_default_pm_suspend(pci_dev);
498 }
499 } else {
500 error = pci_legacy_suspend(dev, PMSG_FREEZE);
501 pci_fixup_device(pci_fixup_suspend, pci_dev);
502 }
503
504 return error;
505}
506
507static int pci_pm_freeze_noirq(struct device *dev)
508{
509 struct pci_dev *pci_dev = to_pci_dev(dev);
510 struct pci_driver *drv = pci_dev->driver;
511 int error = 0;
512
513 if (drv && drv->pm) {
514 if (drv->pm->freeze_noirq) {
515 error = drv->pm->freeze_noirq(dev);
516 suspend_report_result(drv->pm->freeze_noirq, error);
517 }
518 } else {
519 error = pci_legacy_suspend_late(dev, PMSG_FREEZE);
520 }
521
522 return error;
523}
524
525static int pci_pm_thaw(struct device *dev)
526{
527 struct device_driver *drv = dev->driver;
528 int error = 0;
529
530 if (drv && drv->pm) {
531 if (drv->pm->thaw)
532 error = drv->pm->thaw(dev);
533 } else {
534 pci_fixup_device(pci_fixup_resume, to_pci_dev(dev));
535 error = pci_legacy_resume(dev);
536 }
537
538 return error;
539}
540
541static int pci_pm_thaw_noirq(struct device *dev)
542{
543 struct pci_dev *pci_dev = to_pci_dev(dev);
544 struct pci_driver *drv = pci_dev->driver;
545 int error = 0;
546
547 if (drv && drv->pm) {
548 if (drv->pm->thaw_noirq)
549 error = drv->pm->thaw_noirq(dev);
550 } else {
551 pci_fixup_device(pci_fixup_resume_early, pci_dev);
552 error = pci_legacy_resume_early(dev);
553 }
554
555 return error;
556}
557
558static int pci_pm_poweroff(struct device *dev)
559{
560 struct device_driver *drv = dev->driver;
561 int error = 0;
562
563 pci_fixup_device(pci_fixup_suspend, to_pci_dev(dev));
564
565 if (drv && drv->pm) {
566 if (drv->pm->poweroff) {
567 error = drv->pm->poweroff(dev);
568 suspend_report_result(drv->pm->poweroff, error);
569 }
570 } else {
571 error = pci_legacy_suspend(dev, PMSG_HIBERNATE);
572 }
573
574 return error;
575}
576
577static int pci_pm_poweroff_noirq(struct device *dev)
578{
579 struct pci_dev *pci_dev = to_pci_dev(dev);
580 struct pci_driver *drv = pci_dev->driver;
581 int error = 0;
582
583 if (drv && drv->pm) {
584 if (drv->pm->poweroff_noirq) {
585 error = drv->pm->poweroff_noirq(dev);
586 suspend_report_result(drv->pm->poweroff_noirq, error);
587 }
588 } else {
589 error = pci_legacy_suspend_late(dev, PMSG_HIBERNATE);
590 }
591
592 return error;
593}
594
595static int pci_pm_restore(struct device *dev)
596{
597 struct pci_dev *pci_dev = to_pci_dev(dev);
598 struct device_driver *drv = dev->driver;
599 int error;
600
601 if (drv && drv->pm) {
602 error = drv->pm->restore ? drv->pm->restore(dev) :
603 pci_default_pm_resume(pci_dev);
604 } else {
605 error = pci_legacy_resume(dev);
606 }
607 pci_fixup_device(pci_fixup_resume, pci_dev);
608
609 return error;
610}
611
612static int pci_pm_restore_noirq(struct device *dev)
613{
614 struct pci_dev *pci_dev = to_pci_dev(dev);
615 struct pci_driver *drv = pci_dev->driver;
616 int error = 0;
617
618 pci_fixup_device(pci_fixup_resume, pci_dev);
619
620 if (drv && drv->pm) {
621 if (drv->pm->restore_noirq)
622 error = drv->pm->restore_noirq(dev);
623 } else {
624 error = pci_legacy_resume_early(dev);
625 }
626 pci_fixup_device(pci_fixup_resume_early, pci_dev);
627
628 return error;
629}
630
631#else /* !CONFIG_HIBERNATION */
632
633#define pci_pm_freeze NULL
634#define pci_pm_freeze_noirq NULL
635#define pci_pm_thaw NULL
636#define pci_pm_thaw_noirq NULL
637#define pci_pm_poweroff NULL
638#define pci_pm_poweroff_noirq NULL
639#define pci_pm_restore NULL
640#define pci_pm_restore_noirq NULL
641
642#endif /* !CONFIG_HIBERNATION */
643
644struct pm_ext_ops pci_pm_ops = {
645 .base = {
646 .prepare = pci_pm_prepare,
647 .complete = pci_pm_complete,
648 .suspend = pci_pm_suspend,
649 .resume = pci_pm_resume,
650 .freeze = pci_pm_freeze,
651 .thaw = pci_pm_thaw,
652 .poweroff = pci_pm_poweroff,
653 .restore = pci_pm_restore,
654 },
655 .suspend_noirq = pci_pm_suspend_noirq,
656 .resume_noirq = pci_pm_resume_noirq,
657 .freeze_noirq = pci_pm_freeze_noirq,
658 .thaw_noirq = pci_pm_thaw_noirq,
659 .poweroff_noirq = pci_pm_poweroff_noirq,
660 .restore_noirq = pci_pm_restore_noirq,
661};
662
663#define PCI_PM_OPS_PTR &pci_pm_ops
664
665#else /* !CONFIG_PM_SLEEP */
666
667#define PCI_PM_OPS_PTR NULL
668
669#endif /* !CONFIG_PM_SLEEP */
670
367/** 671/**
368 * __pci_register_driver - register a new pci driver 672 * __pci_register_driver - register a new pci driver
369 * @drv: the driver structure to register 673 * @drv: the driver structure to register
@@ -386,6 +690,9 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner,
386 drv->driver.owner = owner; 690 drv->driver.owner = owner;
387 drv->driver.mod_name = mod_name; 691 drv->driver.mod_name = mod_name;
388 692
693 if (drv->pm)
694 drv->driver.pm = &drv->pm->base;
695
389 spin_lock_init(&drv->dynids.lock); 696 spin_lock_init(&drv->dynids.lock);
390 INIT_LIST_HEAD(&drv->dynids.list); 697 INIT_LIST_HEAD(&drv->dynids.list);
391 698
@@ -511,12 +818,9 @@ struct bus_type pci_bus_type = {
511 .uevent = pci_uevent, 818 .uevent = pci_uevent,
512 .probe = pci_device_probe, 819 .probe = pci_device_probe,
513 .remove = pci_device_remove, 820 .remove = pci_device_remove,
514 .suspend = pci_device_suspend,
515 .suspend_late = pci_device_suspend_late,
516 .resume_early = pci_device_resume_early,
517 .resume = pci_device_resume,
518 .shutdown = pci_device_shutdown, 821 .shutdown = pci_device_shutdown,
519 .dev_attrs = pci_dev_attrs, 822 .dev_attrs = pci_dev_attrs,
823 .pm = PCI_PM_OPS_PTR,
520}; 824};
521 825
522static int __init pci_driver_init(void) 826static int __init pci_driver_init(void)