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
This commit is contained in:
commit
b1792e3670
@ -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_30:
|
||||
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_ICH8_0:
|
||||
case PCI_DEVICE_ID_INTEL_ICH8_1:
|
||||
|
@ -5,11 +5,15 @@
|
||||
obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o
|
||||
obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.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_IBM) += acpiphp_ibm.o
|
||||
obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.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_RPA) += rpaphp.o
|
||||
obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o
|
||||
|
@ -195,13 +195,13 @@ static void remove_slot_worker(struct work_struct *work)
|
||||
* Tries hard not to re-enable already existing devices;
|
||||
* 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_dev *dev;
|
||||
int func;
|
||||
int retval;
|
||||
u8 hdr_type;
|
||||
int count = 0;
|
||||
|
||||
if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
|
||||
temp->hdr_type = hdr_type & 0x7f;
|
||||
@ -213,17 +213,12 @@ static void pci_rescan_slot(struct pci_dev *temp)
|
||||
dbg("New device on %s function %x:%x\n",
|
||||
bus->name, temp->devfn >> 3,
|
||||
temp->devfn & 7);
|
||||
retval = pci_bus_add_device(dev);
|
||||
if (retval)
|
||||
dev_err(&dev->dev, "error adding "
|
||||
"device, continuing.\n");
|
||||
else
|
||||
add_slot(dev);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
/* multifunction device? */
|
||||
if (!(hdr_type & 0x80))
|
||||
return;
|
||||
return count;
|
||||
|
||||
/* continue scanning for other functions */
|
||||
for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) {
|
||||
@ -239,16 +234,13 @@ static void pci_rescan_slot(struct pci_dev *temp)
|
||||
dbg("New device on %s function %x:%x\n",
|
||||
bus->name, temp->devfn >> 3,
|
||||
temp->devfn & 7);
|
||||
retval = pci_bus_add_device(dev);
|
||||
if (retval)
|
||||
dev_err(&dev->dev, "error adding "
|
||||
"device, continuing.\n");
|
||||
else
|
||||
add_slot(dev);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
@ -262,6 +254,8 @@ static void pci_rescan_bus(const struct pci_bus *bus)
|
||||
{
|
||||
unsigned int devfn;
|
||||
struct pci_dev *dev;
|
||||
int retval;
|
||||
int found = 0;
|
||||
dev = alloc_pci_dev();
|
||||
if (!dev)
|
||||
return;
|
||||
@ -270,7 +264,23 @@ static void pci_rescan_bus(const struct pci_bus *bus)
|
||||
dev->sysdata = bus->sysdata;
|
||||
for (devfn = 0; devfn < 0x100; devfn += 8) {
|
||||
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);
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
struct msi_desc *entry;
|
||||
@ -407,8 +417,7 @@ static int msi_capability_init(struct pci_dev *dev)
|
||||
|
||||
/* All MSIs are unmasked by default, Mask them all */
|
||||
pci_read_config_dword(dev, base, &maskbits);
|
||||
temp = (1 << multi_msi_capable(control));
|
||||
temp = ((temp - 1) & ~temp);
|
||||
temp = msi_mask((control & PCI_MSI_FLAGS_QMASK) >> 1);
|
||||
maskbits |= temp;
|
||||
pci_write_config_dword(dev, base, maskbits);
|
||||
entry->msi_attrib.maskbits_mask = temp;
|
||||
|
@ -370,6 +370,7 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state)
|
||||
}
|
||||
|
||||
pci_save_state(pci_dev);
|
||||
pci_dev->state_saved = true;
|
||||
/*
|
||||
* This is for compatibility with existing code with legacy PM support.
|
||||
*/
|
||||
@ -419,6 +420,7 @@ static int pci_legacy_resume(struct device *dev)
|
||||
static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
|
||||
{
|
||||
pci_restore_standard_config(pci_dev);
|
||||
pci_dev->state_saved = false;
|
||||
pci_fixup_device(pci_fixup_resume_early, pci_dev);
|
||||
}
|
||||
|
||||
@ -555,6 +557,13 @@ static int pci_pm_resume(struct device *dev)
|
||||
struct device_driver *drv = dev->driver;
|
||||
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))
|
||||
return pci_legacy_resume(dev);
|
||||
|
||||
@ -660,7 +669,10 @@ static int pci_pm_poweroff(struct device *dev)
|
||||
if (pci_has_legacy_pm_support(pci_dev))
|
||||
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);
|
||||
suspend_report_result(drv->pm->poweroff, error);
|
||||
}
|
||||
@ -710,6 +722,13 @@ static int pci_pm_restore(struct device *dev)
|
||||
struct device_driver *drv = dev->driver;
|
||||
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))
|
||||
return pci_legacy_resume(dev);
|
||||
|
||||
|
@ -1393,35 +1393,35 @@ int pci_restore_standard_config(struct pci_dev *dev)
|
||||
pci_power_t prev_state;
|
||||
int error;
|
||||
|
||||
pci_restore_state(dev);
|
||||
pci_update_current_state(dev, PCI_D0);
|
||||
|
||||
prev_state = dev->current_state;
|
||||
if (prev_state == PCI_D0)
|
||||
return 0;
|
||||
goto Restore;
|
||||
|
||||
error = pci_raw_set_power_state(dev, PCI_D0, false);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (pci_is_bridge(dev)) {
|
||||
if (prev_state > PCI_D1)
|
||||
mdelay(PCI_PM_BUS_WAIT);
|
||||
} else {
|
||||
switch(prev_state) {
|
||||
case PCI_D3cold:
|
||||
case PCI_D3hot:
|
||||
mdelay(pci_pm_d3_delay);
|
||||
break;
|
||||
case PCI_D2:
|
||||
udelay(PCI_PM_D2_DELAY);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* This assumes that we won't get a bus in B2 or B3 from the BIOS, but
|
||||
* we've made this assumption forever and it appears to be universally
|
||||
* satisfied.
|
||||
*/
|
||||
switch(prev_state) {
|
||||
case PCI_D3cold:
|
||||
case PCI_D3hot:
|
||||
mdelay(pci_pm_d3_delay);
|
||||
break;
|
||||
case PCI_D2:
|
||||
udelay(PCI_PM_D2_DELAY);
|
||||
break;
|
||||
}
|
||||
|
||||
dev->current_state = PCI_D0;
|
||||
|
||||
return 0;
|
||||
Restore:
|
||||
return pci_restore_state(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2425,6 +2425,7 @@
|
||||
#define PCI_DEVICE_ID_INTEL_ICH7_0 0x27b8
|
||||
#define PCI_DEVICE_ID_INTEL_ICH7_1 0x27b9
|
||||
#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_17 0x27da
|
||||
#define PCI_DEVICE_ID_INTEL_ICH7_19 0x27dd
|
||||
|
Loading…
Reference in New Issue
Block a user