Merge branch 'linus' into x86/pci-ioapic-boot-irq-quirks
authorIngo Molnar <mingo@elte.hu>
Fri, 18 Jul 2008 17:31:12 +0000 (19:31 +0200)
committerIngo Molnar <mingo@elte.hu>
Fri, 18 Jul 2008 17:31:12 +0000 (19:31 +0200)
Conflicts:

drivers/pci/quirks.c

Signed-off-by: Ingo Molnar <mingo@elte.hu>
1  2 
Documentation/kernel-parameters.txt
arch/x86/pci/common.c
drivers/acpi/pci_irq.c
drivers/pci/quirks.c
include/linux/pci.h
include/linux/pci_ids.h

@@@ -147,10 -147,14 +147,14 @@@ and is between 256 and 4096 characters
                        default: 0
  
        acpi_sleep=     [HW,ACPI] Sleep options
-                       Format: { s3_bios, s3_mode, s3_beep }
+                       Format: { s3_bios, s3_mode, s3_beep, old_ordering }
                        See Documentation/power/video.txt for s3_bios and s3_mode.
                        s3_beep is for debugging; it makes the PC's speaker beep
                        as soon as the kernel's real-mode entry point is called.
+                       old_ordering causes the ACPI 1.0 ordering of the _PTS
+                       control method, wrt putting devices into low power
+                       states, to be enforced (the ACPI 2.0 ordering of _PTS is
+                       used by default).
  
        acpi_sci=       [HW,ACPI] ACPI System Control Interrupt trigger mode
                        Format: { level | edge | high | low }
  
        debug_objects   [KNL] Enable object debugging
  
+       debugpat        [X86] Enable PAT debugging
        decnet.addr=    [HW,NET]
                        Format: <area>[,<node>]
                        See also Documentation/networking/decnet.txt.
        hd=             [EIDE] (E)IDE hard drive subsystem geometry
                        Format: <cyl>,<head>,<sect>
  
-       hd?=            [HW] (E)IDE subsystem
-       hd?lun=         See Documentation/ide/ide.txt.
        highmem=nn[KMG] [KNL,BOOT] forces the highmem zone to have an exact
                        size of <nn>. This works even on boxes that have no
                        highmem otherwise. This also works to reduce highmem
                        See Documentation/ide/ide.txt.
  
        idle=           [X86]
-                       Format: idle=poll or idle=mwait
+                       Format: idle=poll or idle=mwait, idle=halt, idle=nomwait
                        Poll forces a polling idle loop that can slightly improves the performance
                        of waking up a idle CPU, but will use a lot of power and make the system
                        run hot. Not recommended.
                        to not use it because it doesn't save as much power as a normal idle
                        loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same
                        as idle=poll.
+                       idle=halt. Halt is forced to be used for CPU idle.
+                       In such case C2/C3 won't be used again.
+                       idle=nomwait. Disable mwait for CPU C-states
  
        ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem
                        Claim all unknown PCI IDE storage controllers.
        mtdparts=       [MTD]
                        See drivers/mtd/cmdlinepart.c.
  
+       mtdset=         [ARM]
+                       ARM/S3C2412 JIVE boot control
+                       See arch/arm/mach-s3c2412/mach-jive.c
        mtouchusb.raw_coordinates=
                        [HW] Make the MicroTouch USB driver use raw coordinates
                        ('y', default) or cooked coordinates ('n')
                nomsi           [MSI] If the PCI_MSI kernel config parameter is
                                enabled, this kernel boot option can be used to
                                disable the use of MSI interrupts system-wide.
 +              noioapicquirk   [APIC] Disable all boot interrupt quirks.
 +                              Safety option to keep boot IRQs enabled. This
 +                              should never be necessary.
 +              ioapicreroute   [APIC] Enable rerouting of boot IRQs to the
 +                              primary IO-APIC for bridges that cannot disable
 +                              boot IRQs. This fixes a source of spurious IRQs
 +                              when the system masks IRQs.
                biosirq         [X86-32] Use PCI BIOS calls to get the interrupt
                                routing table. These calls are known to be buggy
                                on several machines and they hang the machine
                                Use with caution as certain devices share
                                address decoders between ROMs and other
                                resources.
+               norom           [X86-32,X86_64] Do not assign address space to
+                               expansion ROMs that do not already have
+                               BIOS assigned address ranges.
                irqmask=0xMMMM  [X86-32] Set a bit mask of IRQs allowed to be
                                assigned automatically to PCI devices. You can
                                make the kernel exclude IRQs of your ISA cards
                        Format: { parport<nr> | timid | 0 }
                        See also Documentation/parport.txt.
  
+       pmtmr=          [X86] Manual setup of pmtmr I/O Port. 
+                       Override pmtimer IOPort with a hex value.
+                       e.g. pmtmr=0x508
        pnpacpi=        [ACPI]
                        { off }
  
diff --combined arch/x86/pci/common.c
  unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
                                PCI_PROBE_MMCONF;
  
+ unsigned int pci_early_dump_regs;
  static int pci_bf_sort;
  int pci_routeirq;
 +int noioapicquirk;
 +int noioapicreroute = 1;
  int pcibios_last_bus = -1;
  unsigned long pirq_table_addr;
  struct pci_bus *pci_root_bus;
@@@ -33,7 -32,7 +34,7 @@@ struct pci_raw_ops *raw_pci_ext_ops
  int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
                                                int reg, int len, u32 *val)
  {
-       if (reg < 256 && raw_pci_ops)
+       if (domain == 0 && reg < 256 && raw_pci_ops)
                return raw_pci_ops->read(domain, bus, devfn, reg, len, val);
        if (raw_pci_ext_ops)
                return raw_pci_ext_ops->read(domain, bus, devfn, reg, len, val);
@@@ -43,7 -42,7 +44,7 @@@
  int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn,
                                                int reg, int len, u32 val)
  {
-       if (reg < 256 && raw_pci_ops)
+       if (domain == 0 && reg < 256 && raw_pci_ops)
                return raw_pci_ops->write(domain, bus, devfn, reg, len, val);
        if (raw_pci_ext_ops)
                return raw_pci_ext_ops->write(domain, bus, devfn, reg, len, val);
@@@ -123,6 -122,21 +124,21 @@@ void __init dmi_check_skip_isa_align(vo
        dmi_check_system(can_skip_pciprobe_dmi_table);
  }
  
+ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
+ {
+       struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE];
+       if (pci_probe & PCI_NOASSIGN_ROMS) {
+               if (rom_r->parent)
+                       return;
+               if (rom_r->start) {
+                       /* we deal with BIOS assigned ROM later */
+                       return;
+               }
+               rom_r->start = rom_r->end = rom_r->flags = 0;
+       }
+ }
  /*
   *  Called after each bus is probed, but before its children
   *  are examined.
  
  void __devinit  pcibios_fixup_bus(struct pci_bus *b)
  {
+       struct pci_dev *dev;
        pci_read_bridge_bases(b);
+       list_for_each_entry(dev, &b->devices, bus_list)
+               pcibios_fixup_device_resources(dev);
  }
  
  /*
@@@ -386,7 -404,7 +406,7 @@@ struct pci_bus * __devinit pcibios_scan
  
  extern u8 pci_cache_line_size;
  
static int __init pcibios_init(void)
+ int __init pcibios_init(void)
  {
        struct cpuinfo_x86 *c = &boot_cpu_data;
  
        return 0;
  }
  
- subsys_initcall(pcibios_init);
  char * __devinit  pcibios_setup(char *str)
  {
        if (!strcmp(str, "off")) {
        else if (!strcmp(str, "rom")) {
                pci_probe |= PCI_ASSIGN_ROMS;
                return NULL;
+       } else if (!strcmp(str, "norom")) {
+               pci_probe |= PCI_NOASSIGN_ROMS;
+               return NULL;
        } else if (!strcmp(str, "assign-busses")) {
                pci_probe |= PCI_ASSIGN_ALL_BUSSES;
                return NULL;
        } else if (!strcmp(str, "use_crs")) {
                pci_probe |= PCI_USE__CRS;
                return NULL;
+       } else if (!strcmp(str, "earlydump")) {
+               pci_early_dump_regs = 1;
+               return NULL;
        } else if (!strcmp(str, "routeirq")) {
                pci_routeirq = 1;
                return NULL;
        } else if (!strcmp(str, "skip_isa_align")) {
                pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
                return NULL;
 +      } else if (!strcmp(str, "noioapicquirk")) {
 +              noioapicquirk = 1;
 +              return NULL;
 +      } else if (!strcmp(str, "ioapicreroute")) {
 +              if (noioapicreroute != -1)
 +                      noioapicreroute = 0;
 +              return NULL;
        }
        return str;
  }
diff --combined drivers/acpi/pci_irq.c
@@@ -162,7 -162,7 +162,7 @@@ do_prt_fixups(struct acpi_prt_entry *en
                    !strcmp(prt->source, quirk->source) &&
                    strlen(prt->source) >= strlen(quirk->actual_source)) {
                        printk(KERN_WARNING PREFIX "firmware reports "
-                               "%04x:%02x:%02x[%c] connected to %s; "
+                               "%04x:%02x:%02x PCI INT %c connected to %s; "
                                "changing to %s\n",
                                entry->id.segment, entry->id.bus,
                                entry->id.device, 'A' + entry->pin,
@@@ -384,27 -384,6 +384,27 @@@ acpi_pci_free_irq(struct acpi_prt_entr
        return irq;
  }
  
 +#ifdef CONFIG_X86_IO_APIC
 +extern int noioapicquirk;
 +
 +static int bridge_has_boot_interrupt_variant(struct pci_bus *bus)
 +{
 +      struct pci_bus *bus_it;
 +
 +      for (bus_it = bus ; bus_it ; bus_it = bus_it->parent) {
 +              if (!bus_it->self)
 +                      return 0;
 +
 +              printk(KERN_INFO "vendor=%04x device=%04x\n", bus_it->self->vendor,
 +                              bus_it->self->device);
 +
 +              if (bus_it->self->irq_reroute_variant)
 +                      return bus_it->self->irq_reroute_variant;
 +      }
 +      return 0;
 +}
 +#endif /* CONFIG_X86_IO_APIC */
 +
  /*
   * acpi_pci_irq_lookup
   * success: return IRQ >= 0
@@@ -434,41 -413,6 +434,41 @@@ acpi_pci_irq_lookup(struct pci_bus *bus
        }
  
        ret = func(entry, triggering, polarity, link);
 +
 +#ifdef CONFIG_X86_IO_APIC
 +      /*
 +       * Some chipsets (e.g. intel 6700PXH) generate a legacy INTx when the
 +       * IRQ entry in the chipset's IO-APIC is masked (as, e.g. the RT kernel
 +       * does during interrupt handling). When this INTx generation cannot be
 +       * disabled, we reroute these interrupts to their legacy equivalent to
 +       * get rid of spurious interrupts.
 +       */
 +        if (!noioapicquirk) {
 +              switch (bridge_has_boot_interrupt_variant(bus)) {
 +              case 0:
 +                      /* no rerouting necessary */
 +                      break;
 +
 +              case INTEL_IRQ_REROUTE_VARIANT:
 +                      /*
 +                       * Remap according to INTx routing table in 6700PXH
 +                       * specs, intel order number 302628-002, section
 +                       * 2.15.2. Other chipsets (80332, ...) have the same
 +                       * mapping and are handled here as well.
 +                       */
 +                      printk(KERN_INFO "pci irq %d -> rerouted to legacy "
 +                                       "irq %d\n", ret, (ret % 4) + 16);
 +                      ret = (ret % 4) + 16;
 +                      break;
 +
 +              default:
 +                      printk(KERN_INFO "not rerouting irq %d to legacy irq: "
 +                                       "unknown mapping\n", ret);
 +                      break;
 +              }
 +      }
 +#endif /* CONFIG_X86_IO_APIC */
 +
        return ret;
  }
  
@@@ -485,7 -429,7 +485,7 @@@ acpi_pci_irq_derive(struct pci_dev *dev
  {
        struct pci_dev *bridge = dev;
        int irq = -1;
-       u8 bridge_pin = 0;
+       u8 bridge_pin = 0, orig_pin = pin;
  
  
        if (!dev)
        }
  
        if (irq < 0) {
-               printk(KERN_WARNING PREFIX "Unable to derive IRQ for device %s\n",
-                             pci_name(dev));
+               dev_warn(&dev->dev, "can't derive routing for PCI INT %c\n",
+                        'A' + orig_pin);
                return -1;
        }
  
@@@ -543,6 -487,7 +543,7 @@@ int acpi_pci_irq_enable(struct pci_dev 
        int triggering = ACPI_LEVEL_SENSITIVE;
        int polarity = ACPI_ACTIVE_LOW;
        char *link = NULL;
+       char link_desc[16];
        int rc;
  
  
        pin--;
  
        if (!dev->bus) {
-               printk(KERN_ERR PREFIX "Invalid (NULL) 'bus' field\n");
+               dev_err(&dev->dev, "invalid (NULL) 'bus' field\n");
                return -ENODEV;
        }
  
         * driver reported one, then use it. Exit in any case.
         */
        if (irq < 0) {
-               printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI",
-                      pci_name(dev), ('A' + pin));
+               dev_warn(&dev->dev, "PCI INT %c: no GSI", 'A' + pin);
                /* Interrupt Line values above 0xF are forbidden */
                if (dev->irq > 0 && (dev->irq <= 0xF)) {
                        printk(" - using IRQ %d\n", dev->irq);
  
        rc = acpi_register_gsi(irq, triggering, polarity);
        if (rc < 0) {
-               printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: failed "
-                      "to register GSI\n", pci_name(dev), ('A' + pin));
+               dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n",
+                        'A' + pin);
                return rc;
        }
        dev->irq = rc;
  
-       printk(KERN_INFO PREFIX "PCI Interrupt %s[%c] -> ",
-              pci_name(dev), 'A' + pin);
        if (link)
-               printk("Link [%s] -> ", link);
+               snprintf(link_desc, sizeof(link_desc), " -> Link[%s]", link);
+       else
+               link_desc[0] = '\0';
  
-       printk("GSI %u (%s, %s) -> IRQ %d\n", irq,
-              (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
-              (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq);
+       dev_info(&dev->dev, "PCI INT %c%s -> GSI %u (%s, %s) -> IRQ %d\n",
+                'A' + pin, link_desc, irq,
+                (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
+                (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq);
  
        return 0;
  }
@@@ -672,10 -616,6 +672,6 @@@ void acpi_pci_irq_disable(struct pci_de
         * (e.g. PCI_UNDEFINED_IRQ).
         */
  
-       printk(KERN_INFO PREFIX "PCI interrupt for device %s disabled\n",
-              pci_name(dev));
+       dev_info(&dev->dev, "PCI INT %c disabled\n", 'A' + pin);
        acpi_unregister_gsi(gsi);
-       return;
  }
diff --combined drivers/pci/quirks.c
@@@ -556,7 -556,7 +556,7 @@@ static void quirk_via_ioapic(struct pci
        pci_write_config_byte (dev, 0x58, tmp);
  }
  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_82C686,       quirk_via_ioapic);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,   PCI_DEVICE_ID_VIA_82C686,       quirk_via_ioapic);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_82C686,       quirk_via_ioapic);
  
  /*
   * VIA 8237: Some BIOSs don't set the 'Bypass APIC De-Assert Message' Bit.
@@@ -576,7 -576,7 +576,7 @@@ static void quirk_via_vt8237_bypass_api
        }
  }
  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_8237,         quirk_via_vt8237_bypass_apic_deassert);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,   PCI_DEVICE_ID_VIA_8237,         quirk_via_vt8237_bypass_apic_deassert);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_8237,         quirk_via_vt8237_bypass_apic_deassert);
  
  /*
   * The AMD io apic can hang the box when an apic irq is masked.
@@@ -602,6 -602,27 +602,6 @@@ static void __init quirk_ioapic_rmw(str
                sis_apic_bug = 1;
  }
  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI,     PCI_ANY_ID,                     quirk_ioapic_rmw);
 -
 -#define AMD8131_revA0        0x01
 -#define AMD8131_revB0        0x11
 -#define AMD8131_MISC         0x40
 -#define AMD8131_NIOAMODE_BIT 0
 -static void quirk_amd_8131_ioapic(struct pci_dev *dev)
 -{ 
 -        unsigned char tmp;
 -        
 -        if (nr_ioapics == 0) 
 -                return;
 -
 -        if (dev->revision == AMD8131_revA0 || dev->revision == AMD8131_revB0) {
 -                dev_info(&dev->dev, "Fixing up AMD8131 IOAPIC mode\n");
 -                pci_read_config_byte( dev, AMD8131_MISC, &tmp);
 -                tmp &= ~(1 << AMD8131_NIOAMODE_BIT);
 -                pci_write_config_byte( dev, AMD8131_MISC, tmp);
 -        }
 -} 
 -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
 -DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
  #endif /* CONFIG_X86_IO_APIC */
  
  /*
@@@ -753,7 -774,7 +753,7 @@@ static void quirk_cardbus_legacy(struc
        pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0);
  }
  DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
- DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
  
  /*
   * Following the PCI ordering rules is optional on the AMD762. I'm not
@@@ -776,7 -797,7 +776,7 @@@ static void quirk_amd_ordering(struct p
        }
  }
  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,    PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD,   PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD,     PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering);
  
  /*
   *    DreamWorks provided workaround for Dunord I-3000 problem
@@@ -844,7 -865,7 +844,7 @@@ static void quirk_disable_pxb(struct pc
        }
  }
  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82454NX,    quirk_disable_pxb);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX,    quirk_disable_pxb);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82454NX,    quirk_disable_pxb);
  
  static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev)
  {
        }
  }
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
  
  /*
   *    Serverworks CSB5 IDE does not fully support native mode
@@@ -1033,6 -1054,20 +1033,20 @@@ static void __init asus_hides_smbus_hos
                                 * its on-board VGA controller */
                                asus_hides_smbus = 1;
                        }
+               else if (dev->device == PCI_DEVICE_ID_INTEL_82845G_IG)
+                       switch(dev->subsystem_device) {
+                       case 0x00b8: /* Compaq Evo D510 CMT */
+                       case 0x00b9: /* Compaq Evo D510 SFF */
+                               asus_hides_smbus = 1;
+                       }
+               else if (dev->device == PCI_DEVICE_ID_INTEL_82815_CGC)
+                       switch (dev->subsystem_device) {
+                       case 0x001A: /* Compaq Deskpro EN SSF P667 815E */
+                               /* Motherboard doesn't have host bridge
+                                * subvendor/subdevice IDs, therefore checking
+                                * its on-board VGA controller */
+                               asus_hides_smbus = 1;
+                       }
        }
  }
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845_HB,   asus_hides_smbus_hostbridge);
@@@ -1047,6 -1082,8 +1061,8 @@@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge);
  
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3,  asus_hides_smbus_hostbridge);
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG,  asus_hides_smbus_hostbridge);
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,  asus_hides_smbus_hostbridge);
  
  static void asus_hides_smbus_lpc(struct pci_dev *dev)
  {
@@@ -1072,31 -1109,61 +1088,61 @@@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc);
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc);
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,  asus_hides_smbus_lpc);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0,  asus_hides_smbus_lpc);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,  asus_hides_smbus_lpc);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,  asus_hides_smbus_lpc);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,  asus_hides_smbus_lpc);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,  asus_hides_smbus_lpc);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801AA_0,  asus_hides_smbus_lpc);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801DB_0,  asus_hides_smbus_lpc);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801BA_0,  asus_hides_smbus_lpc);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801CA_0,  asus_hides_smbus_lpc);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82801EB_0,  asus_hides_smbus_lpc);
  
- static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
+ /* It appears we just have one such device. If not, we have a warning */
+ static void __iomem *asus_rcba_base;
+ static void asus_hides_smbus_lpc_ich6_suspend(struct pci_dev *dev)
  {
-       u32 val, rcba;
-       void __iomem *base;
+       u32 rcba;
  
        if (likely(!asus_hides_smbus))
                return;
+       WARN_ON(asus_rcba_base);
        pci_read_config_dword(dev, 0xF0, &rcba);
-       base = ioremap_nocache(rcba & 0xFFFFC000, 0x4000); /* use bits 31:14, 16 kB aligned */
-       if (base == NULL) return;
-       val=readl(base + 0x3418); /* read the Function Disable register, dword mode only */
-       writel(val & 0xFFFFFFF7, base + 0x3418); /* enable the SMBus device */
-       iounmap(base);
+       /* use bits 31:14, 16 kB aligned */
+       asus_rcba_base = ioremap_nocache(rcba & 0xFFFFC000, 0x4000);
+       if (asus_rcba_base == NULL)
+               return;
+ }
+ static void asus_hides_smbus_lpc_ich6_resume_early(struct pci_dev *dev)
+ {
+       u32 val;
+       if (likely(!asus_hides_smbus || !asus_rcba_base))
+               return;
+       /* read the Function Disable register, dword mode only */
+       val = readl(asus_rcba_base + 0x3418);
+       writel(val & 0xFFFFFFF7, asus_rcba_base + 0x3418); /* enable the SMBus device */
+ }
+ static void asus_hides_smbus_lpc_ich6_resume(struct pci_dev *dev)
+ {
+       if (likely(!asus_hides_smbus || !asus_rcba_base))
+               return;
+       iounmap(asus_rcba_base);
+       asus_rcba_base = NULL;
        dev_info(&dev->dev, "Enabled ICH6/i801 SMBus device\n");
  }
+ static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
+ {
+       asus_hides_smbus_lpc_ich6_suspend(dev);
+       asus_hides_smbus_lpc_ich6_resume_early(dev);
+       asus_hides_smbus_lpc_ich6_resume(dev);
+ }
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1,     asus_hides_smbus_lpc_ich6);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1,     asus_hides_smbus_lpc_ich6);
+ DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_INTEL,        PCI_DEVICE_ID_INTEL_ICH6_1,     asus_hides_smbus_lpc_ich6_suspend);
+ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1,     asus_hides_smbus_lpc_ich6_resume);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_ICH6_1,     asus_hides_smbus_lpc_ich6_resume_early);
  
  /*
   * SiS 96x south bridge: BIOS typically hides SMBus device...
@@@ -1114,10 -1181,10 +1160,10 @@@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,    PCI_DEVICE_ID_SI_962,           quirk_sis_96x_smbus);
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,    PCI_DEVICE_ID_SI_963,           quirk_sis_96x_smbus);
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,    PCI_DEVICE_ID_SI_LPC,           quirk_sis_96x_smbus);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,    PCI_DEVICE_ID_SI_961,           quirk_sis_96x_smbus);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,    PCI_DEVICE_ID_SI_962,           quirk_sis_96x_smbus);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,    PCI_DEVICE_ID_SI_963,           quirk_sis_96x_smbus);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,    PCI_DEVICE_ID_SI_LPC,           quirk_sis_96x_smbus);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI,      PCI_DEVICE_ID_SI_961,           quirk_sis_96x_smbus);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI,      PCI_DEVICE_ID_SI_962,           quirk_sis_96x_smbus);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI,      PCI_DEVICE_ID_SI_963,           quirk_sis_96x_smbus);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI,      PCI_DEVICE_ID_SI_LPC,           quirk_sis_96x_smbus);
  
  /*
   * ... This is further complicated by the fact that some SiS96x south
@@@ -1151,7 -1218,7 +1197,7 @@@ static void quirk_sis_503(struct pci_de
        quirk_sis_96x_smbus(dev);
  }
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,    PCI_DEVICE_ID_SI_503,           quirk_sis_503);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,    PCI_DEVICE_ID_SI_503,           quirk_sis_503);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_SI,      PCI_DEVICE_ID_SI_503,           quirk_sis_503);
  
  
  /*
@@@ -1184,7 -1251,7 +1230,7 @@@ static void asus_hides_ac97_lpc(struct 
        }
  }
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,   PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,   PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc);
  
  #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE)
  
@@@ -1249,12 -1316,12 +1295,12 @@@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_J
  DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata);
  DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata);
  DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB360, quirk_jmicron_ata);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, quirk_jmicron_ata);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, quirk_jmicron_ata);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, quirk_jmicron_ata);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, quirk_jmicron_ata);
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, quirk_jmicron_ata);
  
  #endif
  
@@@ -1342,155 -1409,6 +1388,155 @@@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_I
  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,  0x260a, quirk_intel_pcie_pm);
  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,  0x260b, quirk_intel_pcie_pm);
  
 +#ifdef CONFIG_X86_IO_APIC
 +/*
 + * Boot interrupts on some chipsets cannot be turned off. For these chipsets,
 + * remap the original interrupt in the linux kernel to the boot interrupt, so
 + * that a PCI device's interrupt handler is installed on the boot interrupt
 + * line instead.
 + */
 +static void quirk_reroute_to_boot_interrupts_intel(struct pci_dev *dev)
 +{
 +      if (noioapicquirk)
 +              return;
 +
 +      dev->irq_reroute_variant = INTEL_IRQ_REROUTE_VARIANT;
 +
 +      printk(KERN_INFO "PCI quirk: reroute interrupts for 0x%04x:0x%04x\n",
 +                      dev->vendor, dev->device);
 +      return;
 +}
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_80333_0,    quirk_reroute_to_boot_interrupts_intel);
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_80333_1,    quirk_reroute_to_boot_interrupts_intel);
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ESB2_0,     quirk_reroute_to_boot_interrupts_intel);
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_PXH_0,      quirk_reroute_to_boot_interrupts_intel);
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_PXH_1,      quirk_reroute_to_boot_interrupts_intel);
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_PXHV,       quirk_reroute_to_boot_interrupts_intel);
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_80332_0,    quirk_reroute_to_boot_interrupts_intel);
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_80332_1,    quirk_reroute_to_boot_interrupts_intel);
 +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80333_0,    quirk_reroute_to_boot_interrupts_intel);
 +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80333_1,    quirk_reroute_to_boot_interrupts_intel);
 +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0,     quirk_reroute_to_boot_interrupts_intel);
 +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_0,      quirk_reroute_to_boot_interrupts_intel);
 +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_1,      quirk_reroute_to_boot_interrupts_intel);
 +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHV,       quirk_reroute_to_boot_interrupts_intel);
 +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80332_0,    quirk_reroute_to_boot_interrupts_intel);
 +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80332_1,    quirk_reroute_to_boot_interrupts_intel);
 +
 +/*
 + * On some chipsets we can disable the generation of legacy INTx boot
 + * interrupts.
 + */
 +
 +/*
 + * IO-APIC1 on 6300ESB generates boot interrupts, see intel order no
 + * 300641-004US, section 5.7.3.
 + */
 +#define INTEL_6300_IOAPIC_ABAR                0x40
 +#define INTEL_6300_DISABLE_BOOT_IRQ   (1<<14)
 +
 +static void quirk_disable_intel_boot_interrupt(struct pci_dev *dev)
 +{
 +      u16 pci_config_word;
 +
 +      if (noioapicquirk)
 +              return;
 +
 +      pci_read_config_word(dev, INTEL_6300_IOAPIC_ABAR, &pci_config_word);
 +      pci_config_word |= INTEL_6300_DISABLE_BOOT_IRQ;
 +      pci_write_config_word(dev, INTEL_6300_IOAPIC_ABAR, pci_config_word);
 +
 +      printk(KERN_INFO "disabled boot interrupt on device 0x%04x:0x%04x\n",
 +              dev->vendor, dev->device);
 +}
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_ESB_10,    quirk_disable_intel_boot_interrupt);
 +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_ESB_10,   quirk_disable_intel_boot_interrupt);
 +
 +/*
 + * disable boot interrupts on HT-1000
 + */
 +#define BC_HT1000_FEATURE_REG         0x64
 +#define BC_HT1000_PIC_REGS_ENABLE     (1<<0)
 +#define BC_HT1000_MAP_IDX             0xC00
 +#define BC_HT1000_MAP_DATA            0xC01
 +
 +static void quirk_disable_broadcom_boot_interrupt(struct pci_dev *dev)
 +{
 +      u32 pci_config_dword;
 +      u8 irq;
 +
 +      if (noioapicquirk)
 +              return;
 +
 +      pci_read_config_dword(dev, BC_HT1000_FEATURE_REG, &pci_config_dword);
 +      pci_write_config_dword(dev, BC_HT1000_FEATURE_REG, pci_config_dword |
 +                      BC_HT1000_PIC_REGS_ENABLE);
 +
 +      for (irq = 0x10; irq < 0x10 + 32; irq++) {
 +              outb(irq, BC_HT1000_MAP_IDX);
 +              outb(0x00, BC_HT1000_MAP_DATA);
 +      }
 +
 +      pci_write_config_dword(dev, BC_HT1000_FEATURE_REG, pci_config_dword);
 +
 +      printk(KERN_INFO "disabled boot interrupts on PCI device"
 +                      "0x%04x:0x%04x\n", dev->vendor, dev->device);
 +}
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS,   PCI_DEVICE_ID_SERVERWORKS_HT1000SB,      quirk_disable_broadcom_boot_interrupt);
 +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SERVERWORKS,   PCI_DEVICE_ID_SERVERWORKS_HT1000SB,     quirk_disable_broadcom_boot_interrupt);
 +
 +/*
 + * disable boot interrupts on AMD and ATI chipsets
 + */
 +/*
 + * NOIOAMODE needs to be disabled to disable "boot interrupts". For AMD 8131
 + * rev. A0 and B0, NOIOAMODE needs to be disabled anyway to fix IO-APIC mode
 + * (due to an erratum).
 + */
 +#define AMD_813X_MISC                 0x40
 +#define AMD_813X_NOIOAMODE            (1<<0)
 +
 +static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev)
 +{
 +      u32 pci_config_dword;
 +
 +      if (noioapicquirk)
 +              return;
 +
 +      pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword);
 +      pci_config_dword &= ~AMD_813X_NOIOAMODE;
 +      pci_write_config_dword(dev, AMD_813X_MISC, pci_config_dword);
 +
 +      printk(KERN_INFO "disabled boot interrupts on PCI device "
 +                      "0x%04x:0x%04x\n", dev->vendor, dev->device);
 +}
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,   PCI_DEVICE_ID_AMD_8131_BRIDGE,   quirk_disable_amd_813x_boot_interrupt);
 +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD,   PCI_DEVICE_ID_AMD_8132_BRIDGE,  quirk_disable_amd_813x_boot_interrupt);
 +
 +#define AMD_8111_PCI_IRQ_ROUTING      0x56
 +
 +static void quirk_disable_amd_8111_boot_interrupt(struct pci_dev *dev)
 +{
 +      u16 pci_config_word;
 +
 +      if (noioapicquirk)
 +              return;
 +
 +      pci_read_config_word(dev, AMD_8111_PCI_IRQ_ROUTING, &pci_config_word);
 +      if (!pci_config_word) {
 +              printk(KERN_INFO "boot interrupts on PCI device 0x%04x:0x%04x "
 +                              "already disabled\n",
 +                              dev->vendor, dev->device);
 +              return;
 +      }
 +      pci_write_config_word(dev, AMD_8111_PCI_IRQ_ROUTING, 0);
 +      printk(KERN_INFO "disabled boot interrupts on PCI device "
 +                      "0x%04x:0x%04x\n", dev->vendor, dev->device);
 +}
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,   PCI_DEVICE_ID_AMD_8111_SMBUS,    quirk_disable_amd_8111_boot_interrupt);
 +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD,   PCI_DEVICE_ID_AMD_8111_SMBUS,   quirk_disable_amd_8111_boot_interrupt);
 +#endif /* CONFIG_X86_IO_APIC */
 +
  /*
   * Toshiba TC86C001 IDE controller reports the standard 8-byte BAR0 size
   * but the PIO transfers won't work if BAR0 falls at the odd 8 bytes.
@@@ -1649,6 -1567,10 +1695,10 @@@ extern struct pci_fixup __start_pci_fix
  extern struct pci_fixup __end_pci_fixups_enable[];
  extern struct pci_fixup __start_pci_fixups_resume[];
  extern struct pci_fixup __end_pci_fixups_resume[];
+ extern struct pci_fixup __start_pci_fixups_resume_early[];
+ extern struct pci_fixup __end_pci_fixups_resume_early[];
+ extern struct pci_fixup __start_pci_fixups_suspend[];
+ extern struct pci_fixup __end_pci_fixups_suspend[];
  
  
  void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
                end = __end_pci_fixups_resume;
                break;
  
+       case pci_fixup_resume_early:
+               start = __start_pci_fixups_resume_early;
+               end = __end_pci_fixups_resume_early;
+               break;
+       case pci_fixup_suspend:
+               start = __start_pci_fixups_suspend;
+               end = __end_pci_fixups_suspend;
+               break;
        default:
                /* stupid compiler warning, you would think with an enum... */
                return;
@@@ -1757,7 -1689,7 +1817,7 @@@ static void quirk_nvidia_ck804_pcie_aer
  }
  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA,  PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
                        quirk_nvidia_ck804_pcie_aer_ext_cap);
- DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA,  PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
+ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_NVIDIA,  PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
                        quirk_nvidia_ck804_pcie_aer_ext_cap);
  
  static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
diff --combined include/linux/pci.h
@@@ -17,8 -17,7 +17,7 @@@
  #ifndef LINUX_PCI_H
  #define LINUX_PCI_H
  
- /* Include the pci register defines */
- #include <linux/pci_regs.h>
+ #include <linux/pci_regs.h>   /* The pci register defines */
  
  /*
   * The PCI interface treats multi-function devices as independent
  #include <linux/list.h>
  #include <linux/compiler.h>
  #include <linux/errno.h>
+ #include <linux/kobject.h>
  #include <asm/atomic.h>
  #include <linux/device.h>
  
  /* Include the ID list */
  #include <linux/pci_ids.h>
  
+ /* pci_slot represents a physical slot */
+ struct pci_slot {
+       struct pci_bus *bus;            /* The bus this slot is on */
+       struct list_head list;          /* node in list of slots on this bus */
+       struct hotplug_slot *hotplug;   /* Hotplug info (migrate over time) */
+       unsigned char number;           /* PCI_SLOT(pci_dev->devfn) */
+       struct kobject kobj;
+ };
  /* File state for mmap()s on /proc/bus/pci/X/Y */
  enum pci_mmap_state {
        pci_mmap_io,
@@@ -117,11 -126,6 +126,11 @@@ enum pci_dev_flags 
        PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG = (__force pci_dev_flags_t) 1,
  };
  
 +enum pci_irq_reroute_variant {
 +      INTEL_IRQ_REROUTE_VARIANT = 1,
 +      MAX_IRQ_REROUTE_VARIANTS = 3
 +};
 +
  typedef unsigned short __bitwise pci_bus_flags_t;
  enum pci_bus_flags {
        PCI_BUS_FLAGS_NO_MSI   = (__force pci_bus_flags_t) 1,
@@@ -147,6 -151,7 +156,7 @@@ struct pci_dev 
  
        void            *sysdata;       /* hook for sys-specific extension */
        struct proc_dir_entry *procent; /* device entry in /proc/bus/pci */
+       struct pci_slot *slot;          /* Physical slot this device is in */
  
        unsigned int    devfn;          /* encoded device & function index */
        unsigned short  vendor;
        pci_power_t     current_state;  /* Current operating state. In ACPI-speak,
                                           this is D0-D3, D0 being fully functional,
                                           and D3 being off. */
+       int             pm_cap;         /* PM capability offset in the
+                                          configuration space */
+       unsigned int    pme_support:5;  /* Bitmask of states from which PME#
+                                          can be generated */
+       unsigned int    d1_support:1;   /* Low power state D1 is supported */
+       unsigned int    d2_support:1;   /* Low power state D2 is supported */
+       unsigned int    no_d1d2:1;      /* Only allow D0 and D3 */
  
  #ifdef CONFIG_PCIEASPM
        struct pcie_link_state  *link_state;    /* ASPM link state. */
        unsigned int    is_added:1;
        unsigned int    is_busmaster:1; /* device is busmaster */
        unsigned int    no_msi:1;       /* device may not use msi */
-       unsigned int    no_d1d2:1;   /* only allow d0 or d3 */
        unsigned int    block_ucfg_access:1;    /* userspace config space access is blocked */
        unsigned int    broken_parity_status:1; /* Device generates false positive parity */
 +      unsigned int    irq_reroute_variant:2;  /* device needs IRQ rerouting variant */
        unsigned int    msi_enabled:1;
        unsigned int    msix_enabled:1;
        unsigned int    is_managed:1;
@@@ -273,6 -283,7 +289,7 @@@ struct pci_bus 
        struct list_head children;      /* list of child buses */
        struct list_head devices;       /* list of devices on this bus */
        struct pci_dev  *self;          /* bridge device as seen by parent */
+       struct list_head slots;         /* list of slots on this bus */
        struct resource *resource[PCI_BUS_NUM_RESOURCES];
                                        /* address space routed to this bus */
  
@@@ -334,7 -345,7 +351,7 @@@ struct pci_bus_region 
  struct pci_dynids {
        spinlock_t lock;            /* protects list, index */
        struct list_head list;      /* for IDs added at runtime */
-       unsigned int use_driver_data:1; /* pci_driver->driver_data is used */
+       unsigned int use_driver_data:1; /* pci_device_id->driver_data is used */
  };
  
  /* ---------------------------------------------------------------- */
@@@ -396,7 -407,7 +413,7 @@@ struct pci_driver 
        int  (*resume_early) (struct pci_dev *dev);
        int  (*resume) (struct pci_dev *dev);                   /* Device woken up */
        void (*shutdown) (struct pci_dev *dev);
+       struct pm_ext_ops *pm;
        struct pci_error_handlers *err_handler;
        struct device_driver    driver;
        struct pci_dynids dynids;
@@@ -495,6 -506,10 +512,10 @@@ struct pci_bus *pci_create_bus(struct d
                               struct pci_ops *ops, void *sysdata);
  struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev,
                                int busnr);
+ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
+                                const char *name);
+ void pci_destroy_slot(struct pci_slot *slot);
+ void pci_update_slot_number(struct pci_slot *slot, int slot_nr);
  int pci_scan_slot(struct pci_bus *bus, int devfn);
  struct pci_dev *pci_scan_single_device(struct pci_bus *bus, int devfn);
  void pci_device_add(struct pci_dev *dev, struct pci_bus *bus);
@@@ -624,6 -639,8 +645,8 @@@ int pci_restore_state(struct pci_dev *d
  int pci_set_power_state(struct pci_dev *dev, pci_power_t state);
  pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
  int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable);
+ int pci_prepare_to_sleep(struct pci_dev *dev);
+ int pci_back_from_sleep(struct pci_dev *dev);
  
  /* Functions for PCI Hotplug drivers to use */
  int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap);
@@@ -845,6 -862,11 +868,11 @@@ static inline int pci_set_dma_mask(stru
        return -EIO;
  }
  
+ static inline int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
+ {
+       return -EIO;
+ }
  static inline int pci_set_dma_max_seg_size(struct pci_dev *dev,
                                        unsigned int size)
  {
@@@ -983,9 -1005,9 +1011,9 @@@ static inline void pci_set_drvdata(stru
  /* If you want to know what to call your pci_dev, ask this function.
   * Again, it's a wrapper around the generic device.
   */
- static inline char *pci_name(struct pci_dev *pdev)
+ static inline const char *pci_name(struct pci_dev *pdev)
  {
-       return pdev->dev.bus_id;
+       return dev_name(&pdev->dev);
  }
  
  
@@@ -1020,7 -1042,9 +1048,9 @@@ enum pci_fixup_pass 
        pci_fixup_header,       /* After reading configuration header */
        pci_fixup_final,        /* Final phase of device fixups */
        pci_fixup_enable,       /* pci_enable_device() time */
-       pci_fixup_resume,       /* pci_enable_device() time */
+       pci_fixup_resume,       /* pci_device_resume() */
+       pci_fixup_suspend,      /* pci_device_suspend */
+       pci_fixup_resume_early, /* pci_device_resume_early() */
  };
  
  /* Anonymous variables would be nice... */
  #define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook)                        \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume,                    \
                        resume##vendor##device##hook, vendor, device, hook)
+ #define DECLARE_PCI_FIXUP_RESUME_EARLY(vendor, device, hook)          \
+       DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early,              \
+                       resume_early##vendor##device##hook, vendor, device, hook)
+ #define DECLARE_PCI_FIXUP_SUSPEND(vendor, device, hook)                       \
+       DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend,                   \
+                       suspend##vendor##device##hook, vendor, device, hook)
  
  
  void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
@@@ -1066,7 -1096,10 +1102,10 @@@ extern int pci_pci_problems
  extern unsigned long pci_cardbus_io_size;
  extern unsigned long pci_cardbus_mem_size;
  
- extern int pcibios_add_platform_entries(struct pci_dev *dev);
+ int pcibios_add_platform_entries(struct pci_dev *dev);
+ void pcibios_disable_device(struct pci_dev *dev);
+ int pcibios_set_pcie_reset_state(struct pci_dev *dev,
+                                enum pcie_reset_state state);
  
  #ifdef CONFIG_PCI_MMCONFIG
  extern void __init pci_mmcfg_early_init(void);
diff --combined include/linux/pci_ids.h
  #define PCI_DEVICE_ID_MPC8544         0x0033
  #define PCI_DEVICE_ID_MPC8572E                0x0040
  #define PCI_DEVICE_ID_MPC8572         0x0041
+ #define PCI_DEVICE_ID_MPC8536E                0x0050
+ #define PCI_DEVICE_ID_MPC8536         0x0051
  #define PCI_DEVICE_ID_MPC8641         0x7010
  #define PCI_DEVICE_ID_MPC8641D                0x7011
  #define PCI_DEVICE_ID_MPC8610         0x7018
  #define PCI_DEVICE_ID_JMICRON_JMB366  0x2366
  #define PCI_DEVICE_ID_JMICRON_JMB368  0x2368
  #define PCI_DEVICE_ID_JMICRON_JMB38X_SD       0x2381
+ #define PCI_DEVICE_ID_JMICRON_JMB38X_MMC 0x2382
  #define PCI_DEVICE_ID_JMICRON_JMB38X_MS       0x2383
  
  #define PCI_VENDOR_ID_KORENIX         0x1982
  #define PCI_DEVICE_ID_INTEL_PXH_0     0x0329
  #define PCI_DEVICE_ID_INTEL_PXH_1     0x032A
  #define PCI_DEVICE_ID_INTEL_PXHV      0x032C
 +#define PCI_DEVICE_ID_INTEL_80332_0   0x0330
 +#define PCI_DEVICE_ID_INTEL_80332_1   0x0332
 +#define PCI_DEVICE_ID_INTEL_80333_0   0x0370
 +#define PCI_DEVICE_ID_INTEL_80333_1   0x0372
  #define PCI_DEVICE_ID_INTEL_82375     0x0482
  #define PCI_DEVICE_ID_INTEL_82424     0x0483
  #define PCI_DEVICE_ID_INTEL_82378     0x0484
  #define PCI_DEVICE_ID_INTEL_ESB_4     0x25a4
  #define PCI_DEVICE_ID_INTEL_ESB_5     0x25a6
  #define PCI_DEVICE_ID_INTEL_ESB_9     0x25ab
 +#define PCI_DEVICE_ID_INTEL_ESB_10    0x25ac
  #define PCI_DEVICE_ID_INTEL_82820_HB  0x2500
  #define PCI_DEVICE_ID_INTEL_82820_UP_HB       0x2501
  #define PCI_DEVICE_ID_INTEL_82850_HB  0x2530