Commit b1792e36 authored by Linus Torvalds's avatar Linus Torvalds

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 hotplug: Change link order of pciehp & acpiphp
  PCI hotplug: fakephp: Allocate PCI resources before adding the device
  PCI MSI: Fix undefined shift by 32
  PCI PM: Do not wait for buses in B2 or B3 during resume
  PCI PM: Power up devices before restoring their state
  PCI PM: Fix hibernation breakage on EeePC 701
  PCI: irq and pci_ids patch for Intel Tigerpoint DeviceIDs
  PCI PM: Fix suspend error paths and testing facility breakage
parents 859281ff 71a082ef
...@@ -572,6 +572,7 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route ...@@ -572,6 +572,7 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
case PCI_DEVICE_ID_INTEL_ICH7_1: case PCI_DEVICE_ID_INTEL_ICH7_1:
case PCI_DEVICE_ID_INTEL_ICH7_30: case PCI_DEVICE_ID_INTEL_ICH7_30:
case PCI_DEVICE_ID_INTEL_ICH7_31: case PCI_DEVICE_ID_INTEL_ICH7_31:
case PCI_DEVICE_ID_INTEL_TGP_LPC:
case PCI_DEVICE_ID_INTEL_ESB2_0: case PCI_DEVICE_ID_INTEL_ESB2_0:
case PCI_DEVICE_ID_INTEL_ICH8_0: case PCI_DEVICE_ID_INTEL_ICH8_0:
case PCI_DEVICE_ID_INTEL_ICH8_1: case PCI_DEVICE_ID_INTEL_ICH8_1:
......
...@@ -5,11 +5,15 @@ ...@@ -5,11 +5,15 @@
obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o
obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o
obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o
# pciehp should be linked before acpiphp in order to allow the native driver
# to attempt to bind first. We can then fall back to generic support.
obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o
obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o
obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o
obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o
obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o
obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o
obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o
obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o
obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o
......
...@@ -195,13 +195,13 @@ static void remove_slot_worker(struct work_struct *work) ...@@ -195,13 +195,13 @@ static void remove_slot_worker(struct work_struct *work)
* Tries hard not to re-enable already existing devices; * Tries hard not to re-enable already existing devices;
* also handles scanning of subfunctions. * also handles scanning of subfunctions.
*/ */
static void pci_rescan_slot(struct pci_dev *temp) static int pci_rescan_slot(struct pci_dev *temp)
{ {
struct pci_bus *bus = temp->bus; struct pci_bus *bus = temp->bus;
struct pci_dev *dev; struct pci_dev *dev;
int func; int func;
int retval;
u8 hdr_type; u8 hdr_type;
int count = 0;
if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) { if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
temp->hdr_type = hdr_type & 0x7f; temp->hdr_type = hdr_type & 0x7f;
...@@ -213,17 +213,12 @@ static void pci_rescan_slot(struct pci_dev *temp) ...@@ -213,17 +213,12 @@ static void pci_rescan_slot(struct pci_dev *temp)
dbg("New device on %s function %x:%x\n", dbg("New device on %s function %x:%x\n",
bus->name, temp->devfn >> 3, bus->name, temp->devfn >> 3,
temp->devfn & 7); temp->devfn & 7);
retval = pci_bus_add_device(dev); count++;
if (retval)
dev_err(&dev->dev, "error adding "
"device, continuing.\n");
else
add_slot(dev);
} }
} }
/* multifunction device? */ /* multifunction device? */
if (!(hdr_type & 0x80)) if (!(hdr_type & 0x80))
return; return count;
/* continue scanning for other functions */ /* continue scanning for other functions */
for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) { for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) {
...@@ -239,16 +234,13 @@ static void pci_rescan_slot(struct pci_dev *temp) ...@@ -239,16 +234,13 @@ static void pci_rescan_slot(struct pci_dev *temp)
dbg("New device on %s function %x:%x\n", dbg("New device on %s function %x:%x\n",
bus->name, temp->devfn >> 3, bus->name, temp->devfn >> 3,
temp->devfn & 7); temp->devfn & 7);
retval = pci_bus_add_device(dev); count++;
if (retval)
dev_err(&dev->dev, "error adding "
"device, continuing.\n");
else
add_slot(dev);
} }
} }
} }
} }
return count;
} }
...@@ -262,6 +254,8 @@ static void pci_rescan_bus(const struct pci_bus *bus) ...@@ -262,6 +254,8 @@ static void pci_rescan_bus(const struct pci_bus *bus)
{ {
unsigned int devfn; unsigned int devfn;
struct pci_dev *dev; struct pci_dev *dev;
int retval;
int found = 0;
dev = alloc_pci_dev(); dev = alloc_pci_dev();
if (!dev) if (!dev)
return; return;
...@@ -270,7 +264,23 @@ static void pci_rescan_bus(const struct pci_bus *bus) ...@@ -270,7 +264,23 @@ static void pci_rescan_bus(const struct pci_bus *bus)
dev->sysdata = bus->sysdata; dev->sysdata = bus->sysdata;
for (devfn = 0; devfn < 0x100; devfn += 8) { for (devfn = 0; devfn < 0x100; devfn += 8) {
dev->devfn = devfn; dev->devfn = devfn;
pci_rescan_slot(dev); found += pci_rescan_slot(dev);
}
if (found) {
pci_bus_assign_resources(bus);
list_for_each_entry(dev, &bus->devices, bus_list) {
/* Skip already-added devices */
if (dev->is_added)
continue;
retval = pci_bus_add_device(dev);
if (retval)
dev_err(&dev->dev,
"Error adding device, continuing\n");
else
add_slot(dev);
}
pci_bus_add_devices(bus);
} }
kfree(dev); kfree(dev);
} }
......
...@@ -103,6 +103,16 @@ static void msix_set_enable(struct pci_dev *dev, int enable) ...@@ -103,6 +103,16 @@ static void msix_set_enable(struct pci_dev *dev, int enable)
} }
} }
/*
* Essentially, this is ((1 << (1 << x)) - 1), but without the
* undefinedness of a << 32.
*/
static inline __attribute_const__ u32 msi_mask(unsigned x)
{
static const u32 mask[] = { 1, 2, 4, 0xf, 0xff, 0xffff, 0xffffffff };
return mask[x];
}
static void msix_flush_writes(struct irq_desc *desc) static void msix_flush_writes(struct irq_desc *desc)
{ {
struct msi_desc *entry; struct msi_desc *entry;
...@@ -407,8 +417,7 @@ static int msi_capability_init(struct pci_dev *dev) ...@@ -407,8 +417,7 @@ static int msi_capability_init(struct pci_dev *dev)
/* All MSIs are unmasked by default, Mask them all */ /* All MSIs are unmasked by default, Mask them all */
pci_read_config_dword(dev, base, &maskbits); pci_read_config_dword(dev, base, &maskbits);
temp = (1 << multi_msi_capable(control)); temp = msi_mask((control & PCI_MSI_FLAGS_QMASK) >> 1);
temp = ((temp - 1) & ~temp);
maskbits |= temp; maskbits |= temp;
pci_write_config_dword(dev, base, maskbits); pci_write_config_dword(dev, base, maskbits);
entry->msi_attrib.maskbits_mask = temp; entry->msi_attrib.maskbits_mask = temp;
......
...@@ -370,6 +370,7 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state) ...@@ -370,6 +370,7 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state)
} }
pci_save_state(pci_dev); pci_save_state(pci_dev);
pci_dev->state_saved = true;
/* /*
* This is for compatibility with existing code with legacy PM support. * This is for compatibility with existing code with legacy PM support.
*/ */
...@@ -419,6 +420,7 @@ static int pci_legacy_resume(struct device *dev) ...@@ -419,6 +420,7 @@ static int pci_legacy_resume(struct device *dev)
static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev) static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
{ {
pci_restore_standard_config(pci_dev); pci_restore_standard_config(pci_dev);
pci_dev->state_saved = false;
pci_fixup_device(pci_fixup_resume_early, pci_dev); pci_fixup_device(pci_fixup_resume_early, pci_dev);
} }
...@@ -555,6 +557,13 @@ static int pci_pm_resume(struct device *dev) ...@@ -555,6 +557,13 @@ static int pci_pm_resume(struct device *dev)
struct device_driver *drv = dev->driver; struct device_driver *drv = dev->driver;
int error = 0; int error = 0;
/*
* This is necessary for the suspend error path in which resume is
* called without restoring the standard config registers of the device.
*/
if (pci_dev->state_saved)
pci_restore_standard_config(pci_dev);
if (pci_has_legacy_pm_support(pci_dev)) if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume(dev); return pci_legacy_resume(dev);
...@@ -660,7 +669,10 @@ static int pci_pm_poweroff(struct device *dev) ...@@ -660,7 +669,10 @@ static int pci_pm_poweroff(struct device *dev)
if (pci_has_legacy_pm_support(pci_dev)) if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend(dev, PMSG_HIBERNATE); return pci_legacy_suspend(dev, PMSG_HIBERNATE);
if (drv && drv->pm && drv->pm->poweroff) { if (!drv || !drv->pm)
return 0;
if (drv->pm->poweroff) {
error = drv->pm->poweroff(dev); error = drv->pm->poweroff(dev);
suspend_report_result(drv->pm->poweroff, error); suspend_report_result(drv->pm->poweroff, error);
} }
...@@ -710,6 +722,13 @@ static int pci_pm_restore(struct device *dev) ...@@ -710,6 +722,13 @@ static int pci_pm_restore(struct device *dev)
struct device_driver *drv = dev->driver; struct device_driver *drv = dev->driver;
int error = 0; int error = 0;
/*
* This is necessary for the hibernation error path in which restore is
* called without restoring the standard config registers of the device.
*/
if (pci_dev->state_saved)
pci_restore_standard_config(pci_dev);
if (pci_has_legacy_pm_support(pci_dev)) if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume(dev); return pci_legacy_resume(dev);
......
...@@ -1393,35 +1393,35 @@ int pci_restore_standard_config(struct pci_dev *dev) ...@@ -1393,35 +1393,35 @@ int pci_restore_standard_config(struct pci_dev *dev)
pci_power_t prev_state; pci_power_t prev_state;
int error; int error;
pci_restore_state(dev);
pci_update_current_state(dev, PCI_D0); pci_update_current_state(dev, PCI_D0);
prev_state = dev->current_state; prev_state = dev->current_state;
if (prev_state == PCI_D0) if (prev_state == PCI_D0)
return 0; goto Restore;
error = pci_raw_set_power_state(dev, PCI_D0, false); error = pci_raw_set_power_state(dev, PCI_D0, false);
if (error) if (error)
return error; return error;
if (pci_is_bridge(dev)) { /*
if (prev_state > PCI_D1) * This assumes that we won't get a bus in B2 or B3 from the BIOS, but
mdelay(PCI_PM_BUS_WAIT); * we've made this assumption forever and it appears to be universally
} else { * satisfied.
switch(prev_state) { */
case PCI_D3cold: switch(prev_state) {
case PCI_D3hot: case PCI_D3cold:
mdelay(pci_pm_d3_delay); case PCI_D3hot:
break; mdelay(pci_pm_d3_delay);
case PCI_D2: break;
udelay(PCI_PM_D2_DELAY); case PCI_D2:
break; udelay(PCI_PM_D2_DELAY);
} break;
} }
dev->current_state = PCI_D0; dev->current_state = PCI_D0;
return 0; Restore:
return pci_restore_state(dev);
} }
/** /**
......
...@@ -2425,6 +2425,7 @@ ...@@ -2425,6 +2425,7 @@
#define PCI_DEVICE_ID_INTEL_ICH7_0 0x27b8 #define PCI_DEVICE_ID_INTEL_ICH7_0 0x27b8
#define PCI_DEVICE_ID_INTEL_ICH7_1 0x27b9 #define PCI_DEVICE_ID_INTEL_ICH7_1 0x27b9
#define PCI_DEVICE_ID_INTEL_ICH7_30 0x27b0 #define PCI_DEVICE_ID_INTEL_ICH7_30 0x27b0
#define PCI_DEVICE_ID_INTEL_TGP_LPC 0x27bc
#define PCI_DEVICE_ID_INTEL_ICH7_31 0x27bd #define PCI_DEVICE_ID_INTEL_ICH7_31 0x27bd
#define PCI_DEVICE_ID_INTEL_ICH7_17 0x27da #define PCI_DEVICE_ID_INTEL_ICH7_17 0x27da
#define PCI_DEVICE_ID_INTEL_ICH7_19 0x27dd #define PCI_DEVICE_ID_INTEL_ICH7_19 0x27dd
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment