Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6:
PCI PM: make the PM core more careful with drivers using the new PM framework
PCI PM: Read power state from device after trying to change it on resume
PCI PM: Do not disable and enable bridges during suspend-resume
PCI: PCIe portdrv: Simplify suspend and resume
PCI PM: Fix saving of device state in pci_legacy_suspend
PCI PM: Check if the state has been saved before trying to restore it
PCI PM: Fix handling of devices without drivers
PCI: return error on failure to read PCI ROMs
PCI: properly clean up ASPM link state on device remove

+133 -88
+12 -1
Documentation/filesystems/sysfs-pci.txt
··· 9 9 | |-- class 10 10 | |-- config 11 11 | |-- device 12 + | |-- enable 12 13 | |-- irq 13 14 | |-- local_cpus 14 15 | |-- resource ··· 33 32 class PCI class (ascii, ro) 34 33 config PCI config space (binary, rw) 35 34 device PCI device (ascii, ro) 35 + enable Whether the device is enabled (ascii, rw) 36 36 irq IRQ number (ascii, ro) 37 37 local_cpus nearby CPU mask (cpumask, ro) 38 38 resource PCI resource host addresses (ascii, ro) ··· 59 57 don't support mmapping of certain resources, so be sure to check the return 60 58 value from any attempted mmap. 61 59 60 + The 'enable' file provides a counter that indicates how many times the device 61 + has been enabled. If the 'enable' file currently returns '4', and a '1' is 62 + echoed into it, it will then return '5'. Echoing a '0' into it will decrease 63 + the count. Even when it returns to 0, though, some of the initialisation 64 + may not be reversed. 65 + 62 66 The 'rom' file is special in that it provides read-only access to the device's 63 67 ROM file, if available. It's disabled by default, however, so applications 64 68 should write the string "1" to the file to enable it before attempting a read 65 - call, and disable it following the access by writing "0" to the file. 69 + call, and disable it following the access by writing "0" to the file. Note 70 + that the device must be enabled for a rom read to return data succesfully. 71 + In the event a driver is not bound to the device, it can be enabled using the 72 + 'enable' file, documented above. 66 73 67 74 Accessing legacy resources through sysfs 68 75 ----------------------------------------
+1 -1
arch/ia64/sn/kernel/io_acpi_init.c
··· 443 443 size = pci_resource_len(dev, PCI_ROM_RESOURCE); 444 444 addr = ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE], 445 445 size); 446 - image_size = pci_get_rom_size(addr, size); 446 + image_size = pci_get_rom_size(dev, addr, size); 447 447 dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr; 448 448 dev->resource[PCI_ROM_RESOURCE].end = 449 449 (unsigned long) addr + image_size - 1;
+1 -1
arch/ia64/sn/kernel/io_init.c
··· 269 269 270 270 rom = ioremap(pci_resource_start(dev, PCI_ROM_RESOURCE), 271 271 size + 1); 272 - image_size = pci_get_rom_size(rom, size + 1); 272 + image_size = pci_get_rom_size(dev, rom, size + 1); 273 273 dev->resource[PCI_ROM_RESOURCE].end = 274 274 dev->resource[PCI_ROM_RESOURCE].start + 275 275 image_size - 1;
+106 -60
drivers/pci/pci-driver.c
··· 355 355 int i = 0; 356 356 357 357 if (drv && drv->suspend) { 358 + pci_power_t prev = pci_dev->current_state; 359 + 358 360 pci_dev->state_saved = false; 359 361 360 362 i = drv->suspend(pci_dev, state); ··· 367 365 if (pci_dev->state_saved) 368 366 goto Fixup; 369 367 370 - if (WARN_ON_ONCE(pci_dev->current_state != PCI_D0)) 368 + if (pci_dev->current_state != PCI_D0 369 + && pci_dev->current_state != PCI_UNKNOWN) { 370 + WARN_ONCE(pci_dev->current_state != prev, 371 + "PCI PM: Device state not saved by %pF\n", 372 + drv->suspend); 371 373 goto Fixup; 374 + } 372 375 } 373 376 374 377 pci_save_state(pci_dev); 375 - pci_dev->state_saved = true; 376 378 /* 377 379 * This is for compatibility with existing code with legacy PM support. 378 380 */ ··· 430 424 pci_fixup_device(pci_fixup_resume_early, pci_dev); 431 425 } 432 426 433 - static int pci_pm_default_resume(struct pci_dev *pci_dev) 427 + static void pci_pm_default_resume(struct pci_dev *pci_dev) 434 428 { 435 429 pci_fixup_device(pci_fixup_resume, pci_dev); 436 430 437 431 if (!pci_is_bridge(pci_dev)) 438 432 pci_enable_wake(pci_dev, PCI_D0, false); 439 - 440 - return pci_pm_reenable_device(pci_dev); 441 - } 442 - 443 - static void pci_pm_default_suspend_generic(struct pci_dev *pci_dev) 444 - { 445 - /* If device is enabled at this point, disable it */ 446 - pci_disable_enabled_device(pci_dev); 447 - /* 448 - * Save state with interrupts enabled, because in principle the bus the 449 - * device is on may be put into a low power state after this code runs. 450 - */ 451 - pci_save_state(pci_dev); 452 433 } 453 434 454 435 static void pci_pm_default_suspend(struct pci_dev *pci_dev) 455 436 { 456 - pci_pm_default_suspend_generic(pci_dev); 457 - 437 + /* Disable non-bridge devices without PM support */ 458 438 if (!pci_is_bridge(pci_dev)) 459 - pci_prepare_to_sleep(pci_dev); 460 - 461 - pci_fixup_device(pci_fixup_suspend, pci_dev); 439 + pci_disable_enabled_device(pci_dev); 440 + pci_save_state(pci_dev); 462 441 } 463 442 464 443 static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev) ··· 488 497 static int pci_pm_suspend(struct device *dev) 489 498 { 490 499 struct pci_dev *pci_dev = to_pci_dev(dev); 491 - struct device_driver *drv = dev->driver; 492 - int error = 0; 500 + struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 493 501 494 502 if (pci_has_legacy_pm_support(pci_dev)) 495 503 return pci_legacy_suspend(dev, PMSG_SUSPEND); 496 504 497 - if (drv && drv->pm && drv->pm->suspend) { 498 - error = drv->pm->suspend(dev); 499 - suspend_report_result(drv->pm->suspend, error); 505 + if (!pm) { 506 + pci_pm_default_suspend(pci_dev); 507 + goto Fixup; 500 508 } 501 509 502 - if (!error) 503 - pci_pm_default_suspend(pci_dev); 510 + pci_dev->state_saved = false; 504 511 505 - return error; 512 + if (pm->suspend) { 513 + pci_power_t prev = pci_dev->current_state; 514 + int error; 515 + 516 + error = pm->suspend(dev); 517 + suspend_report_result(pm->suspend, error); 518 + if (error) 519 + return error; 520 + 521 + if (pci_dev->state_saved) 522 + goto Fixup; 523 + 524 + if (pci_dev->current_state != PCI_D0 525 + && pci_dev->current_state != PCI_UNKNOWN) { 526 + WARN_ONCE(pci_dev->current_state != prev, 527 + "PCI PM: State of device not saved by %pF\n", 528 + pm->suspend); 529 + goto Fixup; 530 + } 531 + } 532 + 533 + if (!pci_dev->state_saved) { 534 + pci_save_state(pci_dev); 535 + if (!pci_is_bridge(pci_dev)) 536 + pci_prepare_to_sleep(pci_dev); 537 + } 538 + 539 + Fixup: 540 + pci_fixup_device(pci_fixup_suspend, pci_dev); 541 + 542 + return 0; 506 543 } 507 544 508 545 static int pci_pm_suspend_noirq(struct device *dev) ··· 573 554 static int pci_pm_resume(struct device *dev) 574 555 { 575 556 struct pci_dev *pci_dev = to_pci_dev(dev); 576 - struct device_driver *drv = dev->driver; 557 + struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 577 558 int error = 0; 578 559 579 560 /* ··· 586 567 if (pci_has_legacy_pm_support(pci_dev)) 587 568 return pci_legacy_resume(dev); 588 569 589 - error = pci_pm_default_resume(pci_dev); 570 + pci_pm_default_resume(pci_dev); 590 571 591 - if (!error && drv && drv->pm && drv->pm->resume) 592 - error = drv->pm->resume(dev); 572 + if (pm) { 573 + if (pm->resume) 574 + error = pm->resume(dev); 575 + } else { 576 + pci_pm_reenable_device(pci_dev); 577 + } 593 578 594 - return error; 579 + return 0; 595 580 } 596 581 597 582 #else /* !CONFIG_SUSPEND */ ··· 612 589 static int pci_pm_freeze(struct device *dev) 613 590 { 614 591 struct pci_dev *pci_dev = to_pci_dev(dev); 615 - struct device_driver *drv = dev->driver; 616 - int error = 0; 592 + struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 617 593 618 594 if (pci_has_legacy_pm_support(pci_dev)) 619 595 return pci_legacy_suspend(dev, PMSG_FREEZE); 620 596 621 - if (drv && drv->pm && drv->pm->freeze) { 622 - error = drv->pm->freeze(dev); 623 - suspend_report_result(drv->pm->freeze, error); 597 + if (!pm) { 598 + pci_pm_default_suspend(pci_dev); 599 + return 0; 624 600 } 625 601 626 - if (!error) 627 - pci_pm_default_suspend_generic(pci_dev); 602 + pci_dev->state_saved = false; 628 603 629 - return error; 604 + if (pm->freeze) { 605 + int error; 606 + 607 + error = pm->freeze(dev); 608 + suspend_report_result(pm->freeze, error); 609 + if (error) 610 + return error; 611 + } 612 + 613 + if (!pci_dev->state_saved) 614 + pci_save_state(pci_dev); 615 + 616 + return 0; 630 617 } 631 618 632 619 static int pci_pm_freeze_noirq(struct device *dev) ··· 679 646 static int pci_pm_thaw(struct device *dev) 680 647 { 681 648 struct pci_dev *pci_dev = to_pci_dev(dev); 682 - struct device_driver *drv = dev->driver; 649 + struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 683 650 int error = 0; 684 651 685 652 if (pci_has_legacy_pm_support(pci_dev)) 686 653 return pci_legacy_resume(dev); 687 654 688 - pci_pm_reenable_device(pci_dev); 689 - 690 - if (drv && drv->pm && drv->pm->thaw) 691 - error = drv->pm->thaw(dev); 655 + if (pm) { 656 + if (pm->thaw) 657 + error = pm->thaw(dev); 658 + } else { 659 + pci_pm_reenable_device(pci_dev); 660 + } 692 661 693 662 return error; 694 663 } ··· 698 663 static int pci_pm_poweroff(struct device *dev) 699 664 { 700 665 struct pci_dev *pci_dev = to_pci_dev(dev); 701 - struct device_driver *drv = dev->driver; 666 + struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 702 667 int error = 0; 703 668 704 669 if (pci_has_legacy_pm_support(pci_dev)) 705 670 return pci_legacy_suspend(dev, PMSG_HIBERNATE); 706 671 707 - if (!drv || !drv->pm) 708 - return 0; 709 - 710 - if (drv->pm->poweroff) { 711 - error = drv->pm->poweroff(dev); 712 - suspend_report_result(drv->pm->poweroff, error); 672 + if (!pm) { 673 + pci_pm_default_suspend(pci_dev); 674 + goto Fixup; 713 675 } 714 676 715 - if (!error) 716 - pci_pm_default_suspend(pci_dev); 677 + pci_dev->state_saved = false; 678 + 679 + if (pm->poweroff) { 680 + error = pm->poweroff(dev); 681 + suspend_report_result(pm->poweroff, error); 682 + } 683 + 684 + if (!pci_dev->state_saved && !pci_is_bridge(pci_dev)) 685 + pci_prepare_to_sleep(pci_dev); 686 + 687 + Fixup: 688 + pci_fixup_device(pci_fixup_suspend, pci_dev); 717 689 718 690 return error; 719 691 } ··· 761 719 static int pci_pm_restore(struct device *dev) 762 720 { 763 721 struct pci_dev *pci_dev = to_pci_dev(dev); 764 - struct device_driver *drv = dev->driver; 722 + struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 765 723 int error = 0; 766 724 767 725 /* ··· 774 732 if (pci_has_legacy_pm_support(pci_dev)) 775 733 return pci_legacy_resume(dev); 776 734 777 - error = pci_pm_default_resume(pci_dev); 735 + pci_pm_default_resume(pci_dev); 778 736 779 - if (!error && drv && drv->pm && drv->pm->restore) 780 - error = drv->pm->restore(dev); 737 + if (pm) { 738 + if (pm->restore) 739 + error = pm->restore(dev); 740 + } else { 741 + pci_pm_reenable_device(pci_dev); 742 + } 781 743 782 744 return error; 783 745 }
+2 -2
drivers/pci/pci-sysfs.c
··· 768 768 return -EINVAL; 769 769 770 770 rom = pci_map_rom(pdev, &size); /* size starts out as PCI window size */ 771 - if (!rom) 772 - return 0; 771 + if (!rom || !size) 772 + return -EIO; 773 773 774 774 if (off >= size) 775 775 count = 0;
+2 -2
drivers/pci/pci.c
··· 1418 1418 break; 1419 1419 } 1420 1420 1421 - dev->current_state = PCI_D0; 1421 + pci_update_current_state(dev, PCI_D0); 1422 1422 1423 1423 Restore: 1424 - return pci_restore_state(dev); 1424 + return dev->state_saved ? pci_restore_state(dev) : 0; 1425 1425 } 1426 1426 1427 1427 /**
+2 -2
drivers/pci/pcie/aspm.c
··· 718 718 719 719 /* 720 720 * All PCIe functions are in one slot, remove one function will remove 721 - * the the whole slot, so just wait 721 + * the whole slot, so just wait until we are the last function left. 722 722 */ 723 - if (!list_empty(&parent->subordinate->devices)) 723 + if (!list_is_last(&pdev->bus_list, &parent->subordinate->devices)) 724 724 goto out; 725 725 726 726 /* All functions are removed, so just disable ASPM for the link */
+1 -15
drivers/pci/pcie/portdrv_pci.c
··· 55 55 56 56 } 57 57 58 - static int pcie_portdrv_suspend_late(struct pci_dev *dev, pm_message_t state) 59 - { 60 - return pci_save_state(dev); 61 - } 62 - 63 - static int pcie_portdrv_resume_early(struct pci_dev *dev) 64 - { 65 - return pci_restore_state(dev); 66 - } 67 - 68 58 static int pcie_portdrv_resume(struct pci_dev *dev) 69 59 { 70 - pcie_portdrv_restore_config(dev); 60 + pci_set_master(dev); 71 61 return pcie_port_device_resume(dev); 72 62 } 73 63 #else 74 64 #define pcie_portdrv_suspend NULL 75 - #define pcie_portdrv_suspend_late NULL 76 - #define pcie_portdrv_resume_early NULL 77 65 #define pcie_portdrv_resume NULL 78 66 #endif 79 67 ··· 280 292 .remove = pcie_portdrv_remove, 281 293 282 294 .suspend = pcie_portdrv_suspend, 283 - .suspend_late = pcie_portdrv_suspend_late, 284 - .resume_early = pcie_portdrv_resume_early, 285 295 .resume = pcie_portdrv_resume, 286 296 287 297 .err_handler = &pcie_portdrv_err_handler,
+5 -3
drivers/pci/rom.c
··· 63 63 * The PCI window size could be much larger than the 64 64 * actual image size. 65 65 */ 66 - size_t pci_get_rom_size(void __iomem *rom, size_t size) 66 + size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) 67 67 { 68 68 void __iomem *image; 69 69 int last_image; ··· 72 72 do { 73 73 void __iomem *pds; 74 74 /* Standard PCI ROMs start out with these bytes 55 AA */ 75 - if (readb(image) != 0x55) 75 + if (readb(image) != 0x55) { 76 + dev_err(&pdev->dev, "Invalid ROM contents\n"); 76 77 break; 78 + } 77 79 if (readb(image + 1) != 0xAA) 78 80 break; 79 81 /* get the PCI data structure and check its signature */ ··· 161 159 * size is much larger than the actual size of the ROM. 162 160 * True size is important if the ROM is going to be copied. 163 161 */ 164 - *size = pci_get_rom_size(rom, *size); 162 + *size = pci_get_rom_size(pdev, rom, *size); 165 163 return rom; 166 164 } 167 165
+1 -1
include/linux/pci.h
··· 684 684 void pci_disable_rom(struct pci_dev *pdev); 685 685 void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); 686 686 void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom); 687 - size_t pci_get_rom_size(void __iomem *rom, size_t size); 687 + size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size); 688 688 689 689 /* Power management related routines */ 690 690 int pci_save_state(struct pci_dev *dev);