/*
* Give firmware a chance to be called, such as ACPI _PRx, _PSx
- * Firmware method after natice method ?
+ * Firmware method after native method ?
*/
if (platform_pci_set_power_state)
platform_pci_set_power_state(dev, state);
pci_restore_state(struct pci_dev *dev)
{
int i;
+ int val;
- for (i = 0; i < 16; i++)
- pci_write_config_dword(dev,i * 4, dev->saved_config_space[i]);
+ /*
+ * The Base Address register should be programmed before the command
+ * register(s)
+ */
+ for (i = 15; i >= 0; i--) {
+ pci_read_config_dword(dev, i * 4, &val);
+ if (val != dev->saved_config_space[i]) {
+ printk(KERN_DEBUG "PM: Writing back config space on "
+ "device %s at offset %x (was %x, writing %x)\n",
+ pci_name(dev), i,
+ val, (int)dev->saved_config_space[i]);
+ pci_write_config_dword(dev,i * 4,
+ dev->saved_config_space[i]);
+ }
+ }
pci_restore_msi_state(dev);
pci_restore_msix_state(dev);
return 0;
int
pci_enable_device(struct pci_dev *dev)
{
- int err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1);
+ int err;
+
+ if (dev->is_enabled)
+ return 0;
+
+ err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1);
if (err)
return err;
pci_fixup_device(pci_fixup_enable, dev);
pci_disable_device(struct pci_dev *dev)
{
u16 pci_command;
-
+
+ if (dev->msi_enabled)
+ disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI),
+ PCI_CAP_ID_MSI);
+ if (dev->msix_enabled)
+ disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI),
+ PCI_CAP_ID_MSIX);
+
pci_read_config_word(dev, PCI_COMMAND, &pci_command);
if (pci_command & PCI_COMMAND_MASTER) {
pci_command &= ~PCI_COMMAND_MASTER;
return 0;
err_out:
- printk (KERN_WARNING "PCI: Unable to reserve %s region #%d:%lx@%lx for device %s\n",
+ printk (KERN_WARNING "PCI: Unable to reserve %s region #%d:%llx@%llx "
+ "for device %s\n",
pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem",
bar + 1, /* PCI BAR # */
- pci_resource_len(pdev, bar), pci_resource_start(pdev, bar),
+ (unsigned long long)pci_resource_len(pdev, bar),
+ (unsigned long long)pci_resource_start(pdev, bar),
pci_name(pdev));
return -EBUSY;
}