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

[PATCH] pci: only call pci_restore_bars at boot

Certain (SGI?) ia64 boxes object to having their PCI BARs
restored unless absolutely necessary. This patch restricts calling
pci_restore_bars from pci_set_power_state unless the current state
is PCI_UNKNOWN, the actual (i.e. physical) state of the device is
PCI_D3hot, and the device indicates that it will lose its configuration
when transitioning to PCI_D0.

Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

John W. Linville and committed by
Linus Torvalds
32a36585 186051d7

+12 -4
+12 -4
drivers/pci/pci.c
··· 309 309 310 310 pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr); 311 311 312 - /* If we're in D3, force entire word to 0. 312 + /* If we're (effectively) in D3, force entire word to 0. 313 313 * This doesn't affect PME_Status, disables PME_En, and 314 314 * sets PowerState to 0. 315 315 */ 316 - if (dev->current_state >= PCI_D3hot) { 317 - if (!(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) 316 + switch (dev->current_state) { 317 + case PCI_UNKNOWN: /* Boot-up */ 318 + if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot 319 + && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) 318 320 need_restore = 1; 321 + /* Fall-through: force to D0 */ 322 + case PCI_D3hot: 323 + case PCI_D3cold: 324 + case PCI_POWER_ERROR: 319 325 pmcsr = 0; 320 - } else { 326 + break; 327 + default: 321 328 pmcsr &= ~PCI_PM_CTRL_STATE_MASK; 322 329 pmcsr |= state; 330 + break; 323 331 } 324 332 325 333 /* enter specified state */