]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
/home/lenb/src/to-linus branch 'acpi-2.6.12'
authorLen Brown <len.brown@intel.com>
Sat, 30 Jul 2005 03:31:17 +0000 (23:31 -0400)
committerLen Brown <len.brown@intel.com>
Sat, 30 Jul 2005 03:31:17 +0000 (23:31 -0400)
1  2 
arch/i386/pci/common.c
arch/i386/pci/irq.c
arch/i386/pci/pci.h
drivers/acpi/pci_irq.c
drivers/acpi/processor_idle.c
drivers/net/sk98lin/skge.c
drivers/pcmcia/yenta_socket.c
include/acpi/acpi_drivers.h
include/linux/acpi.h
sound/pci/intel8x0.c

diff --combined arch/i386/pci/common.c
index 70bcd53451f68873a9bfaa14a07ecf6142ea94f9,751e49bda18058859941e76d97aea1f626e938f5..ade5bc57c34ceffc54c0e1f3a79f52879bc062e9
@@@ -25,8 -25,7 +25,8 @@@ unsigned int pci_probe = PCI_PROBE_BIO
  
  int pci_routeirq;
  int pcibios_last_bus = -1;
 -struct pci_bus *pci_root_bus = NULL;
 +unsigned long pirq_table_addr;
 +struct pci_bus *pci_root_bus;
  struct pci_raw_ops *raw_pci_ops;
  
  static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
@@@ -134,7 -133,7 +134,7 @@@ struct pci_bus * __devinit pcibios_scan
  
        printk("PCI: Probing PCI hardware (bus %02x)\n", busnum);
  
 -      return pci_scan_bus(busnum, &pci_root_ops, NULL);
 +      return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL);
  }
  
  extern u8 pci_cache_line_size;
@@@ -165,7 -164,6 +165,7 @@@ static int __init pcibios_init(void
        if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
                pcibios_sort();
  #endif
 +      pci_assign_unassigned_resources();
        return 0;
  }
  
@@@ -190,9 -188,6 +190,9 @@@ char * __devinit  pcibios_setup(char *s
        } else if (!strcmp(str, "biosirq")) {
                pci_probe |= PCI_BIOS_IRQ_SCAN;
                return NULL;
 +      } else if (!strncmp(str, "pirqaddr=", 9)) {
 +              pirq_table_addr = simple_strtoul(str+9, NULL, 0);
 +              return NULL;
        }
  #endif
  #ifdef CONFIG_PCI_DIRECT
@@@ -254,3 -249,9 +254,9 @@@ int pcibios_enable_device(struct pci_de
  
        return pcibios_enable_irq(dev);
  }
+ void pcibios_disable_device (struct pci_dev *dev)
+ {
+       if (pcibios_disable_irq)
+               pcibios_disable_irq(dev);
+ }
diff --combined arch/i386/pci/irq.c
index 766b104ac1a1a55917c435698f25ec5992ff5b88,66e4149ef1897b78a5a54c56fffbd74a07025d64..187350ccf8645bfd7a1391a8c71353f4800ba2f4
@@@ -56,36 -56,8 +56,37 @@@ struct irq_router_handler 
  };
  
  int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
+ void (*pcibios_disable_irq)(struct pci_dev *dev) = NULL;
  
 +/*
 + *  Check passed address for the PCI IRQ Routing Table signature
 + *  and perform checksum verification.
 + */
 +
 +static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr)
 +{
 +      struct irq_routing_table *rt;
 +      int i;
 +      u8 sum;
 +
 +      rt = (struct irq_routing_table *) addr;
 +      if (rt->signature != PIRQ_SIGNATURE ||
 +          rt->version != PIRQ_VERSION ||
 +          rt->size % 16 ||
 +          rt->size < sizeof(struct irq_routing_table))
 +              return NULL;
 +      sum = 0;
 +      for (i=0; i < rt->size; i++)
 +              sum += addr[i];
 +      if (!sum) {
 +              DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
 +              return rt;
 +      }
 +      return NULL;
 +}
 +
 +
 +
  /*
   *  Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
   */
@@@ -94,17 -66,23 +95,17 @@@ static struct irq_routing_table * __ini
  {
        u8 *addr;
        struct irq_routing_table *rt;
 -      int i;
 -      u8 sum;
  
 +      if (pirq_table_addr) {
 +              rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr));
 +              if (rt)
 +                      return rt;
 +              printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n");
 +      }
        for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
 -              rt = (struct irq_routing_table *) addr;
 -              if (rt->signature != PIRQ_SIGNATURE ||
 -                  rt->version != PIRQ_VERSION ||
 -                  rt->size % 16 ||
 -                  rt->size < sizeof(struct irq_routing_table))
 -                      continue;
 -              sum = 0;
 -              for(i=0; i<rt->size; i++)
 -                      sum += addr[i];
 -              if (!sum) {
 -                      DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
 +              rt = pirq_check_routing_table(addr);
 +              if (rt)
                        return rt;
 -              }
        }
        return NULL;
  }
@@@ -249,24 -227,6 +250,24 @@@ static int pirq_via_set(struct pci_dev 
        return 1;
  }
  
 +/*
 + * The VIA pirq rules are nibble-based, like ALI,
 + * but without the ugly irq number munging.
 + * However, for 82C586, nibble map is different .
 + */
 +static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
 +{
 +      static unsigned int pirqmap[4] = { 3, 2, 5, 1 };
 +      return read_config_nybble(router, 0x55, pirqmap[pirq-1]);
 +}
 +
 +static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
 +{
 +      static unsigned int pirqmap[4] = { 3, 2, 5, 1 };
 +      write_config_nybble(router, 0x55, pirqmap[pirq-1], irq);
 +      return 1;
 +}
 +
  /*
   * ITE 8330G pirq rules are nibble-based
   * FIXME: pirqmap may be { 1, 0, 3, 2 },
@@@ -553,10 -513,6 +554,10 @@@ static __init int via_router_probe(stru
        switch(device)
        {
                case PCI_DEVICE_ID_VIA_82C586_0:
 +                      r->name = "VIA";
 +                      r->get = pirq_via586_get;
 +                      r->set = pirq_via586_set;
 +                      return 1;
                case PCI_DEVICE_ID_VIA_82C596:
                case PCI_DEVICE_ID_VIA_82C686:
                case PCI_DEVICE_ID_VIA_8231:
diff --combined arch/i386/pci/pci.h
index a80f0f55ff51b0dcea1c1d33670c5baae924a541,dc442dfcab9e9170ed653d62b4ad26b0809cce9b..127d53ad16bef02f65cd8011cbd1c5ec6fd70e7a
@@@ -27,7 -27,6 +27,7 @@@
  #define PCI_ASSIGN_ALL_BUSSES 0x4000
  
  extern unsigned int pci_probe;
 +extern unsigned long pirq_table_addr;
  
  /* pci-i386.c */
  
@@@ -73,3 -72,4 +73,4 @@@ extern int pcibios_scanned
  extern spinlock_t pci_config_lock;
  
  extern int (*pcibios_enable_irq)(struct pci_dev *dev);
+ extern void (*pcibios_disable_irq)(struct pci_dev *dev);
diff --combined drivers/acpi/pci_irq.c
index d1f42b9728214cb31a7a2584b802325029d3fed5,c536ccfc54136529919b7159b416c7c7ec271417..bb973d2109a11e7404f1d3fa788f1d0655038d5e
@@@ -269,7 -269,51 +269,51 @@@ acpi_pci_irq_del_prt (int segment, int 
  /* --------------------------------------------------------------------------
                            PCI Interrupt Routing Support
     -------------------------------------------------------------------------- */
+ typedef int (*irq_lookup_func)(struct acpi_prt_entry *, int *, int *, char **);
  
+ static int
+ acpi_pci_allocate_irq(struct acpi_prt_entry *entry,
+       int     *edge_level,
+       int     *active_high_low,
+       char    **link)
+ {
+       int     irq;
+       ACPI_FUNCTION_TRACE("acpi_pci_allocate_irq");
+       if (entry->link.handle) {
+               irq = acpi_pci_link_allocate_irq(entry->link.handle,
+                       entry->link.index, edge_level, active_high_low, link);
+               if (irq < 0) {
+                       ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n"));
+                       return_VALUE(-1);
+               }
+       } else {
+               irq = entry->link.index;
+               *edge_level = ACPI_LEVEL_SENSITIVE;
+               *active_high_low = ACPI_ACTIVE_LOW;
+       }
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq));
+       return_VALUE(irq);
+ }
+ static int
+ acpi_pci_free_irq(struct acpi_prt_entry *entry,
+       int     *edge_level,
+       int     *active_high_low,
+       char    **link)
+ {
+       int     irq;
+       ACPI_FUNCTION_TRACE("acpi_pci_free_irq");
+       if (entry->link.handle) {
+               irq = acpi_pci_link_free_irq(entry->link.handle);
+       } else {
+               irq = entry->link.index;
+       }
+       return_VALUE(irq);
+ }
  /*
   * acpi_pci_irq_lookup
   * success: return IRQ >= 0
@@@ -282,12 -326,13 +326,13 @@@ acpi_pci_irq_lookup 
        int                     pin,
        int                     *edge_level,
        int                     *active_high_low,
-       char                    **link)
+       char                    **link,
+       irq_lookup_func         func)
  {
        struct acpi_prt_entry   *entry = NULL;
        int segment = pci_domain_nr(bus);
        int bus_nr = bus->number;
-       int irq;
+       int ret;
  
        ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup");
  
                return_VALUE(-1);
        }
        
-       if (entry->link.handle) {
-               irq = acpi_pci_link_get_irq(entry->link.handle,
-                       entry->link.index, edge_level, active_high_low, link);
-               if (irq < 0) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n"));
-                       return_VALUE(-1);
-               }
-       } else {
-               irq = entry->link.index;
-               *edge_level = ACPI_LEVEL_SENSITIVE;
-               *active_high_low = ACPI_ACTIVE_LOW;
-       }
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq));
-       return_VALUE(irq);
+       ret = func(entry, edge_level, active_high_low, link);
+       return_VALUE(ret);
  }
  
  /*
@@@ -330,7 -361,8 +361,8 @@@ acpi_pci_irq_derive 
        int                     pin,
        int                     *edge_level,
        int                     *active_high_low,
-       char                    **link)
+       char                    **link,
+       irq_lookup_func         func)
  {
        struct pci_dev          *bridge = dev;
        int                     irq = -1;
                }
  
                irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn),
-                       pin, edge_level, active_high_low, link);
+                       pin, edge_level, active_high_low, link, func);
        }
  
        if (irq < 0) {
@@@ -415,7 -447,7 +447,7 @@@ acpi_pci_irq_enable 
         * values override any BIOS-assigned IRQs set during boot.
         */
        irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
-               &edge_level, &active_high_low, &link);
+               &edge_level, &active_high_low, &link, acpi_pci_allocate_irq);
  
        /*
         * If no PRT entry was found, we'll try to derive an IRQ from the
         */
        if (irq < 0)
                irq = acpi_pci_irq_derive(dev, pin, &edge_level,
-                       &active_high_low, &link);
+                       &active_high_low, &link, acpi_pci_allocate_irq);
   
        /*
         * No IRQ known to the ACPI subsystem - maybe the BIOS / 
                printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI",
                        pci_name(dev), ('A' + pin));
                /* Interrupt Line values above 0xF are forbidden */
 -              if (dev->irq >= 0 && (dev->irq <= 0xF)) {
 +              if (dev->irq > 0 && (dev->irq <= 0xF)) {
                        printk(" - using IRQ %d\n", dev->irq);
 +                      acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW);
                        return_VALUE(0);
                }
                else {
  EXPORT_SYMBOL(acpi_pci_irq_enable);
  
  
- #ifdef CONFIG_ACPI_DEALLOCATE_IRQ
+ /* FIXME: implement x86/x86_64 version */
+ void __attribute__((weak)) acpi_unregister_gsi(u32 i) {}
  void
  acpi_pci_irq_disable (
        struct pci_dev          *dev)
         * First we check the PCI IRQ routing table (PRT) for an IRQ.
         */
        gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
-                                 &edge_level, &active_high_low, NULL);
+                       &edge_level, &active_high_low, NULL, acpi_pci_free_irq);
        /*
         * If no PRT entry was found, we'll try to derive an IRQ from the
         * device's parent bridge.
         */
        if (gsi < 0)
                gsi = acpi_pci_irq_derive(dev, pin,
-                                         &edge_level, &active_high_low, NULL);
+                       &edge_level, &active_high_low, NULL, acpi_pci_free_irq);
        if (gsi < 0)
                return_VOID;
  
  
        return_VOID;
  }
- #endif /* CONFIG_ACPI_DEALLOCATE_IRQ */
index 893b074e3d1a48a4390cf84b4c1a10ef6be2460c,fd54589478514dba229968d025e311c462086ea4..af271d994f15a6db56a94f4f801bf71dc5d15c86
@@@ -81,30 -81,33 +81,33 @@@ module_param(bm_history, uint, 0644)
   *
   * To skip this limit, boot/load with a large max_cstate limit.
   */
- static int no_c2c3(struct dmi_system_id *id)
+ static int set_max_cstate(struct dmi_system_id *id)
  {
        if (max_cstate > ACPI_PROCESSOR_MAX_POWER)
                return 0;
  
-       printk(KERN_NOTICE PREFIX "%s detected - C2,C3 disabled."
+       printk(KERN_NOTICE PREFIX "%s detected - %s disabled."
                " Override with \"processor.max_cstate=%d\"\n", id->ident,
+               ((int)id->driver_data == 1)? "C2,C3":"C3",
               ACPI_PROCESSOR_MAX_POWER + 1);
  
-       max_cstate = 1;
+       max_cstate = (int)id->driver_data;
  
        return 0;
  }
  
  
  static struct dmi_system_id __initdata processor_power_dmi_table[] = {
-       { no_c2c3, "IBM ThinkPad R40e", {
+       { set_max_cstate, "IBM ThinkPad R40e", {
          DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-         DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }},
-       { no_c2c3, "Medion 41700", {
+         DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1},
+       { set_max_cstate, "Medion 41700", {
+         DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
+         DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J") }, (void*)1},
+       { set_max_cstate, "Clevo 5600D", {
          DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
-         DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J") }},
+         DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307") },
+         (void*)2},
        {},
  };
  
@@@ -176,7 -179,7 +179,7 @@@ static void acpi_processor_idle (void
        int                     sleep_ticks = 0;
        u32                     t1, t2 = 0;
  
 -      pr = processors[_smp_processor_id()];
 +      pr = processors[raw_smp_processor_id()];
        if (!pr)
                return;
  
@@@ -549,7 -552,8 +552,8 @@@ static int acpi_processor_get_power_inf
        ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1");
  
        for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
-               memset(pr->power.states, 0, sizeof(struct acpi_processor_cx));
+               memset(&(pr->power.states[i]), 0, 
+                      sizeof(struct acpi_processor_cx));
  
        /* if info is obtained from pblk/fadt, type equals state */
        pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
@@@ -580,7 -584,8 +584,8 @@@ static int acpi_processor_get_power_inf
  
        pr->power.count = 0;
        for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
-               memset(pr->power.states, 0, sizeof(struct acpi_processor_cx));
+               memset(&(pr->power.states[i]), 0, 
+                      sizeof(struct acpi_processor_cx));
  
        status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer);
        if (ACPI_FAILURE(status)) {
@@@ -763,7 -768,6 +768,6 @@@ static void acpi_processor_power_verify
        }
  
        if (pr->flags.bm_check) {
-               printk("Disabling BM access before entering C3\n");
                /* bus mastering control is necessary */
                if (!pr->flags.bm_control) {
                        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                        return_VOID;
                }
        } else {
-               printk("Invalidating cache before entering C3\n");
                /*
                 * WBINVD should be set in fadt, for C3 state to be
                 * supported on when bm_check is not required.
@@@ -842,7 -845,7 +845,7 @@@ static int acpi_processor_get_power_inf
        result = acpi_processor_get_power_info_cst(pr);
        if ((result) || (acpi_processor_power_verify(pr) < 2)) {
                result = acpi_processor_get_power_info_fadt(pr);
-               if (result)
+               if ((result) || (acpi_processor_power_verify(pr) < 2))
                        result = acpi_processor_get_power_info_default_c1(pr);
        }
  
index 82570ec44d8eefea84aa2b7721ac9f3eafa7bd3e,7bfaef9305b29fa3ecd2e6ce15a4ea5375b5ad55..074521a3634120ed1d6996d9317d6b5fef72f810
  #include      <linux/moduleparam.h>
  #include      <linux/init.h>
  #include      <linux/proc_fs.h>
 +#include      <linux/dma-mapping.h>
  
  #include      "h/skdrv1st.h"
  #include      "h/skdrv2nd.h"
@@@ -4213,7 -4212,7 +4213,7 @@@ SK_BOOL         DualNet
                        Flags);
  
                SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
 -              pAC->dev[Param.Para32[0]]->flags &= ~IFF_RUNNING;
 +              netif_carrier_off(pAC->dev[Param.Para32[0]]);
                spin_unlock_irqrestore(
                        &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
                        Flags);
                }
  
                /* Inform the world that link protocol is up. */
 -              pAC->dev[Param.Para32[0]]->flags |= IFF_RUNNING;
 +              netif_carrier_on(pAC->dev[Param.Para32[0]]);
  
                break;
        case SK_DRV_NET_DOWN:    /* SK_U32 Reason */
                } else {
                        DoPrintInterfaceChange = SK_TRUE;
                }
 -              pAC->dev[Param.Para32[1]]->flags &= ~IFF_RUNNING;
 +              netif_carrier_off(pAC->dev[Param.Para32[1]]);
                break;
        case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
                SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
@@@ -4913,8 -4912,8 +4913,8 @@@ static int __devinit skge_probe_one(str
                goto out;
   
        /* Configure DMA attributes. */
 -      if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL) &&
 -          pci_set_dma_mask(pdev, (u64) 0xffffffff))
 +      if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
 +          pci_set_dma_mask(pdev, DMA_32BIT_MASK))
                goto out_disable_device;
  
  
  #ifdef CONFIG_NET_POLL_CONTROLLER
        dev->poll_controller =  &SkGePollController;
  #endif
 -      dev->flags &=           ~IFF_RUNNING;
        SET_NETDEV_DEV(dev, &pdev->dev);
        SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
  
                dev->set_mac_address    = &SkGeSetMacAddr;
                dev->do_ioctl           = &SkGeIoctl;
                dev->change_mtu         = &SkGeChangeMtu;
 -              dev->flags             &= ~IFF_RUNNING;
                SET_NETDEV_DEV(dev, &pdev->dev);
                SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
  
@@@ -5133,6 -5134,67 +5133,67 @@@ static void __devexit skge_remove_one(s
        kfree(pAC);
  }
  
+ #ifdef CONFIG_PM
+ static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
+ {
+       struct net_device *dev = pci_get_drvdata(pdev);
+       DEV_NET *pNet = netdev_priv(dev);
+       SK_AC *pAC = pNet->pAC;
+       struct net_device *otherdev = pAC->dev[1];
+       if (pNet->Up) {
+               pAC->WasIfUp[0] = SK_TRUE;
+               DoPrintInterfaceChange = SK_FALSE;
+               SkDrvDeInitAdapter(pAC, 0);  /* performs SkGeClose */
+       }
+       if (otherdev != dev) {
+               pNet = netdev_priv(otherdev);
+               if (pNet->Up) {
+                       pAC->WasIfUp[1] = SK_TRUE;
+                       DoPrintInterfaceChange = SK_FALSE;
+                       SkDrvDeInitAdapter(pAC, 1);  /* performs SkGeClose */
+               }
+       }
+       pci_save_state(pdev);
+       pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
+       if (pAC->AllocFlag & SK_ALLOC_IRQ) {
+               free_irq(dev->irq, dev);
+       }
+       pci_disable_device(pdev);
+       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+       return 0;
+ }
+ static int skge_resume(struct pci_dev *pdev)
+ {
+       struct net_device *dev = pci_get_drvdata(pdev);
+       DEV_NET *pNet = netdev_priv(dev);
+       SK_AC *pAC = pNet->pAC;
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+       pci_enable_device(pdev);
+       pci_set_master(pdev);
+       if (pAC->GIni.GIMacsFound == 2)
+               request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
+       else
+               request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, pAC->Name, dev);
+         if (pAC->WasIfUp[0] == SK_TRUE) {
+               DoPrintInterfaceChange = SK_FALSE;
+               SkDrvInitAdapter(pAC, 0);    /* first device  */
+         }
+       if (pAC->dev[1] != dev && pAC->WasIfUp[1] == SK_TRUE) {
+               DoPrintInterfaceChange = SK_FALSE;
+               SkDrvInitAdapter(pAC, 1);    /* first device  */
+       }
+       return 0;
+ }
+ #endif
  static struct pci_device_id skge_pci_tbl[] = {
        { PCI_VENDOR_ID_3COM, 0x1700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
        { PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
@@@ -5158,6 -5220,8 +5219,8 @@@ static struct pci_driver skge_driver = 
        .id_table       = skge_pci_tbl,
        .probe          = skge_probe_one,
        .remove         = __devexit_p(skge_remove_one),
+       .suspend        = skge_suspend,
+       .resume         = skge_resume,
  };
  
  static int __init skge_init(void)
index 6837491f021c0b813aee8681cc73eb33dd0a21cd,a8a9d954bcf430225ba3a8dbf9d2541b29b71c39..744e469a9eda6cca3e0e45457706442e99f3f687
@@@ -18,6 -18,7 +18,6 @@@
  #include <linux/delay.h>
  #include <linux/module.h>
  
 -#include <pcmcia/version.h>
  #include <pcmcia/cs_types.h>
  #include <pcmcia/ss.h>
  #include <pcmcia/cs.h>
@@@ -31,14 -32,6 +31,14 @@@ static int disable_clkrun
  module_param(disable_clkrun, bool, 0444);
  MODULE_PARM_DESC(disable_clkrun, "If PC card doesn't function properly, please try this option");
  
 +static int isa_probe = 1;
 +module_param(isa_probe, bool, 0444);
 +MODULE_PARM_DESC(isa_probe, "If set ISA interrupts are probed (default). Set to N to disable probing");
 +
 +static int pwr_irqs_off;
 +module_param(pwr_irqs_off, bool, 0644);
 +MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only when seeing IRQ storms!");
 +
  #if 0
  #define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
  #else
@@@ -157,16 -150,15 +157,16 @@@ static int yenta_get_status(struct pcmc
  
        val  = (state & CB_3VCARD) ? SS_3VCARD : 0;
        val |= (state & CB_XVCARD) ? SS_XVCARD : 0;
 -      val |= (state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD | CB_3VCARD
 -                       | CB_XVCARD | CB_YVCARD)) ? 0 : SS_PENDING;
 +      val |= (state & (CB_5VCARD | CB_3VCARD | CB_XVCARD | CB_YVCARD)) ? 0 : SS_PENDING;
 +      val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? SS_PENDING : 0;
 +
  
        if (state & CB_CBCARD) {
                val |= SS_CARDBUS;      
                val |= (state & CB_CARDSTS) ? SS_STSCHG : 0;
                val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT;
                val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0;
 -      } else {
 +      } else if (state & CB_16BITCARD) {
                u8 status = exca_readb(socket, I365_STATUS);
                val |= ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0;
                if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) {
@@@ -413,13 -405,11 +413,13 @@@ static int yenta_set_mem_map(struct pcm
  }
  
  
 -static unsigned int yenta_events(struct yenta_socket *socket)
 +
 +static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  {
 +      unsigned int events;
 +      struct yenta_socket *socket = (struct yenta_socket *) dev_id;
        u8 csc;
        u32 cb_event;
 -      unsigned int events;
  
        /* Clear interrupt status for the event */
        cb_event = cb_readl(socket, CB_SOCKET_EVENT);
                events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
                events |= (csc & I365_CSC_READY) ? SS_READY : 0;
        }
 -      return events;
 -}
 -
  
 -static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 -{
 -      unsigned int events;
 -      struct yenta_socket *socket = (struct yenta_socket *) dev_id;
 -
 -      events = yenta_events(socket);
 -      if (events) {
 +      if (events)
                pcmcia_parse_events(&socket->socket, events);
 +
 +      if (cb_event || csc)
                return IRQ_HANDLED;
 -      }
 +
        return IRQ_NONE;
  }
  
@@@ -473,22 -470,11 +473,22 @@@ static void yenta_clear_maps(struct yen
        }
  }
  
 +/* redoes voltage interrogation if required */
 +static void yenta_interrogate(struct yenta_socket *socket)
 +{
 +      u32 state;
 +
 +      state = cb_readl(socket, CB_SOCKET_STATE);
 +      if (!(state & (CB_5VCARD | CB_3VCARD | CB_XVCARD | CB_YVCARD)) ||
 +          (state & (CB_CDETECT1 | CB_CDETECT2 | CB_NOTACARD | CB_BADVCCREQ)) ||
 +          ((state & (CB_16BITCARD | CB_CBCARD)) == (CB_16BITCARD | CB_CBCARD)))
 +              cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
 +}
 +
  /* Called at resume and initialization events */
  static int yenta_sock_init(struct pcmcia_socket *sock)
  {
        struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
 -      u32 state;
        u16 bridge;
  
        bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~CB_BRIDGE_INTR;
        exca_writeb(socket, I365_GENCTL, 0x00);
  
        /* Redo card voltage interrogation */
 -      state = cb_readl(socket, CB_SOCKET_STATE);
 -      if (!(state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD |
 -                     CB_3VCARD | CB_XVCARD | CB_YVCARD)))
 -              cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
 +      yenta_interrogate(socket);
  
        yenta_clear_maps(socket);
  
@@@ -527,29 -516,60 +527,29 @@@ static int yenta_sock_suspend(struct pc
   * Use an adaptive allocation for the memory resource,
   * sometimes the memory behind pci bridges is limited:
   * 1/8 of the size of the io window of the parent.
 - * max 4 MB, min 16 kB.
 + * max 4 MB, min 16 kB. We try very hard to not get below
 + * the "ACC" values, though.
   */
  #define BRIDGE_MEM_MAX 4*1024*1024
 +#define BRIDGE_MEM_ACC 128*1024
  #define BRIDGE_MEM_MIN 16*1024
  
 -#define BRIDGE_IO_MAX 256
 +#define BRIDGE_IO_MAX 512
 +#define BRIDGE_IO_ACC 256
  #define BRIDGE_IO_MIN 32
  
  #ifndef PCIBIOS_MIN_CARDBUS_IO
  #define PCIBIOS_MIN_CARDBUS_IO PCIBIOS_MIN_IO
  #endif
  
 -static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type)
 +static int yenta_search_one_res(struct resource *root, struct resource *res,
 +                              u32 min)
  {
 -      struct pci_bus *bus;
 -      struct resource *root, *res;
 -      u32 start, end;
 -      u32 align, size, min;
 -      unsigned offset;
 -      unsigned mask;
 -
 -      /* The granularity of the memory limit is 4kB, on IO it's 4 bytes */
 -      mask = ~0xfff;
 -      if (type & IORESOURCE_IO)
 -              mask = ~3;
 +      u32 align, size, start, end;
  
 -      offset = 0x1c + 8*nr;
 -      bus = socket->dev->subordinate;
 -      res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;
 -      res->name = bus->name;
 -      res->flags = type;
 -      res->start = 0;
 -      res->end = 0;
 -      root = pci_find_parent_resource(socket->dev, res);
 -
 -      if (!root)
 -              return;
 -
 -      start = config_readl(socket, offset) & mask;
 -      end = config_readl(socket, offset+4) | ~mask;
 -      if (start && end > start && !override_bios) {
 -              res->start = start;
 -              res->end = end;
 -              if (request_resource(root, res) == 0)
 -                      return;
 -              printk(KERN_INFO "yenta %s: Preassigned resource %d busy, reconfiguring...\n",
 -                              pci_name(socket->dev), nr);
 -              res->start = res->end = 0;
 -      }
 -
 -      if (type & IORESOURCE_IO) {
 +      if (res->flags & IORESOURCE_IO) {
                align = 1024;
                size = BRIDGE_IO_MAX;
 -              min = BRIDGE_IO_MIN;
                start = PCIBIOS_MIN_CARDBUS_IO;
                end = ~0U;
        } else {
                                i++;
                        size = 1 << i;
                }
 -              if (size < BRIDGE_MEM_MIN)
 -                      size = BRIDGE_MEM_MIN;
 -              min = BRIDGE_MEM_MIN;
 +              if (size < min)
 +                      size = min;
                align = size;
                start = PCIBIOS_MIN_MEM;
                end = ~0U;
        }
 -      
 +
        do {
 -              if (allocate_resource(root, res, size, start, end, align, NULL, NULL)==0) {
 -                      config_writel(socket, offset, res->start);
 -                      config_writel(socket, offset+4, res->end);
 -                      return;
 +              if (allocate_resource(root, res, size, start, end, align,
 +                                    NULL, NULL)==0) {
 +                      return 1;
                }
                size = size/2;
                align = size;
        } while (size >= min);
 +
 +      return 0;
 +}
 +
 +
 +static int yenta_search_res(struct yenta_socket *socket, struct resource *res,
 +                          u32 min)
 +{
 +      int i;
 +      for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) {
 +              struct resource * root = socket->dev->bus->resource[i];
 +              if (!root)
 +                      continue;
 +
 +              if ((res->flags ^ root->flags) &
 +                  (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH))
 +                      continue; /* Wrong type */
 +
 +              if (yenta_search_one_res(root, res, min))
 +                      return 1;
 +      }
 +      return 0;
 +}
 +
 +static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type, int addr_start, int addr_end)
 +{
 +      struct pci_bus *bus;
 +      struct resource *root, *res;
 +      u32 start, end;
 +      unsigned mask;
 +
 +      res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;
 +      /* Already allocated? */
 +      if (res->parent)
 +              return;
 +
 +      /* The granularity of the memory limit is 4kB, on IO it's 4 bytes */
 +      mask = ~0xfff;
 +      if (type & IORESOURCE_IO)
 +              mask = ~3;
 +
 +      bus = socket->dev->subordinate;
 +      res->name = bus->name;
 +      res->flags = type;
 +
 +      start = config_readl(socket, addr_start) & mask;
 +      end = config_readl(socket, addr_end) | ~mask;
 +      if (start && end > start && !override_bios) {
 +              res->start = start;
 +              res->end = end;
 +              root = pci_find_parent_resource(socket->dev, res);
 +              if (root && (request_resource(root, res) == 0))
 +                      return;
 +              printk(KERN_INFO "yenta %s: Preassigned resource %d busy or not available, reconfiguring...\n",
 +                              pci_name(socket->dev), nr);
 +      }
 +
 +      if (type & IORESOURCE_IO) {
 +              if ((yenta_search_res(socket, res, BRIDGE_IO_MAX)) ||
 +                  (yenta_search_res(socket, res, BRIDGE_IO_ACC)) ||
 +                  (yenta_search_res(socket, res, BRIDGE_IO_MIN))) {
 +                      config_writel(socket, addr_start, res->start);
 +                      config_writel(socket, addr_end, res->end);
 +              }
 +      } else {
 +              if (type & IORESOURCE_PREFETCH) {
 +                      if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) ||
 +                          (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) ||
 +                          (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) {
 +                              config_writel(socket, addr_start, res->start);
 +                              config_writel(socket, addr_end, res->end);
 +                      }
 +                      /* Approximating prefetchable by non-prefetchable */
 +                      res->flags = IORESOURCE_MEM;
 +              }
 +              if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) ||
 +                  (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) ||
 +                  (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) {
 +                      config_writel(socket, addr_start, res->start);
 +                      config_writel(socket, addr_end, res->end);
 +              }
 +      }
 +
        printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n",
 -                      pci_name(socket->dev), type);
 -      res->start = res->end = 0;
 +             pci_name(socket->dev), type);
 +      res->start = res->end = res->flags = 0;
  }
  
  /*
   */
  static void yenta_allocate_resources(struct yenta_socket *socket)
  {
 -      yenta_allocate_res(socket, 0, IORESOURCE_MEM|IORESOURCE_PREFETCH);
 -      yenta_allocate_res(socket, 1, IORESOURCE_MEM);
 -      yenta_allocate_res(socket, 2, IORESOURCE_IO);
 -      yenta_allocate_res(socket, 3, IORESOURCE_IO);   /* PCI isn't clever enough to use this one yet */
 +      yenta_allocate_res(socket, 0, IORESOURCE_IO,
 +                         PCI_CB_IO_BASE_0, PCI_CB_IO_LIMIT_0);
 +      yenta_allocate_res(socket, 1, IORESOURCE_IO,
 +                         PCI_CB_IO_BASE_1, PCI_CB_IO_LIMIT_1);
 +      yenta_allocate_res(socket, 2, IORESOURCE_MEM|IORESOURCE_PREFETCH,
 +                         PCI_CB_MEMORY_BASE_0, PCI_CB_MEMORY_LIMIT_0);
 +      yenta_allocate_res(socket, 3, IORESOURCE_MEM,
 +                         PCI_CB_MEMORY_BASE_1, PCI_CB_MEMORY_LIMIT_1);
  }
  
  
@@@ -918,11 -853,11 +918,11 @@@ static int yenta_probe_cb_irq(struct ye
   */
  static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask)
  {
 -      socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
 -      socket->socket.map_size = 0x1000;
        socket->socket.pci_irq = socket->cb_irq;
 -      socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
 -      socket->socket.cb_dev = socket->dev;
 +      if (isa_probe)
 +              socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
 +      else
 +              socket->socket.irq_mask = 0;
  
        printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n",
               socket->socket.irq_mask, socket->cb_irq);
@@@ -988,9 -923,6 +988,9 @@@ static int __devinit yenta_probe (struc
        socket->socket.dev.dev = &dev->dev;
        socket->socket.driver_data = socket;
        socket->socket.owner = THIS_MODULE;
 +      socket->socket.features = SS_CAP_PAGE_REGS | SS_CAP_PCCARD;
 +      socket->socket.map_size = 0x1000;
 +      socket->socket.cb_dev = dev;
  
        /* prepare struct yenta_socket */
        socket->dev = dev;
                socket->poll_timer.data = (unsigned long)socket;
                socket->poll_timer.expires = jiffies + HZ;
                add_timer(&socket->poll_timer);
 +              printk(KERN_INFO "Yenta: no PCI IRQ, CardBus support disabled for this socket.\n"
 +                     KERN_INFO "Yenta: check your BIOS CardBus, BIOS IRQ or ACPI settings.\n");
 +      } else {
 +              socket->socket.features |= SS_CAP_CARDBUS;
        }
  
        /* Figure out what the dang thing can do for the PCMCIA layer... */
 +      yenta_interrogate(socket);
        yenta_get_socket_capabilities(socket, isa_interrupts);
        printk(KERN_INFO "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
  
@@@ -1107,6 -1034,8 +1107,8 @@@ static int yenta_dev_suspend (struct pc
                pci_read_config_dword(dev, 17*4, &socket->saved_state[1]);
                pci_disable_device(dev);
  
+               free_irq(dev->irq, socket);
                /*
                 * Some laptops (IBM T22) do not like us putting the Cardbus
                 * bridge into D3.  At a guess, some other laptop will
@@@ -1132,6 -1061,13 +1134,13 @@@ static int yenta_dev_resume (struct pci
                pci_enable_device(dev);
                pci_set_master(dev);
  
+               if (socket->cb_irq)
+                       if (request_irq(socket->cb_irq, yenta_interrupt,
+                                       SA_SHIRQ, "yenta", socket)) {
+                               printk(KERN_WARNING "Yenta: request_irq() failed on resume!\n");
+                               socket->cb_irq = 0;
+                       }
                if (socket->type && socket->type->restore_state)
                        socket->type->restore_state(socket);
        }
index caeaa71a566399171a7aacf7047110b3daa34cfc,13f092977c0cd249139faeaca1c5577bcf88b5d1..579fe191b7e7d3415fe9163568b575403e409a6a
@@@ -56,8 -56,9 +56,9 @@@
  /* ACPI PCI Interrupt Link (pci_link.c) */
  
  int acpi_irq_penalty_init (void);
- int acpi_pci_link_get_irq (acpi_handle handle, int index, int *edge_level,
+ int acpi_pci_link_allocate_irq (acpi_handle handle, int index, int *edge_level,
        int *active_high_low, char **name);
+ int acpi_pci_link_free_irq(acpi_handle handle);
  
  /* ACPI PCI Interrupt Routing (pci_irq.c) */
  
@@@ -68,7 -69,6 +69,7 @@@ void acpi_pci_irq_del_prt (int segment
  
  struct pci_bus;
  
 +acpi_status acpi_get_pci_id (acpi_handle handle, struct acpi_pci_id *id);
  int acpi_pci_bind (struct acpi_device *device);
  int acpi_pci_unbind (struct acpi_device *device);
  int acpi_pci_bind_root (struct acpi_device *device, struct acpi_pci_id *id, struct pci_bus *bus);
diff --combined include/linux/acpi.h
index f85cbe919e132de0a147961de241939003f10148,ca0cd240cee0213ab2c9e98305f13e87c1f8f112..b46a5205ee7b1ce25f327cc07759220142d7f34d
@@@ -345,19 -345,11 +345,19 @@@ struct acpi_table_ecdt 
  
  /* PCI MMCONFIG */
  
 +/* Defined in PCI Firmware Specification 3.0 */
 +struct acpi_table_mcfg_config {
 +      u32                             base_address;
 +      u32                             base_reserved;
 +      u16                             pci_segment_group_number;
 +      u8                              start_bus_number;
 +      u8                              end_bus_number;
 +      u8                              reserved[4];
 +} __attribute__ ((packed));
  struct acpi_table_mcfg {
        struct acpi_table_header        header;
        u8                              reserved[8];
 -      u32                             base_address;
 -      u32                             base_reserved;
 +      struct acpi_table_mcfg_config   config[0];
  } __attribute__ ((packed));
  
  /* Table Handlers */
@@@ -402,7 -394,6 +402,7 @@@ int acpi_table_parse (enum acpi_table_i
  int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header);
  int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries);
  int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries);
 +int acpi_parse_mcfg (unsigned long phys_addr, unsigned long size);
  void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr);
  void acpi_table_print_madt_entry (acpi_table_entry_header *madt);
  void acpi_table_print_srat_entry (acpi_table_entry_header *srat);
@@@ -419,13 -410,9 +419,13 @@@ int acpi_map_lsapic(acpi_handle handle
  int acpi_unmap_lsapic(int cpu);
  #endif /* CONFIG_ACPI_HOTPLUG_CPU */
  
 +int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base);
 +int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base);
 +
  extern int acpi_mp_config;
  
 -extern u32 pci_mmcfg_base_addr;
 +extern struct acpi_table_mcfg_config *pci_mmcfg_config;
 +extern int pci_mmcfg_config_num;
  
  extern int sbf_port ;
  
@@@ -453,9 -440,7 +453,7 @@@ int acpi_gsi_to_irq (u32 gsi, unsigned 
   * If this matches the last registration, any IRQ resources for gsi
   * are freed.
   */
- #ifdef CONFIG_ACPI_DEALLOCATE_IRQ
  void acpi_unregister_gsi (u32 gsi);
- #endif
  
  #ifdef CONFIG_ACPI_PCI
  
@@@ -480,9 -465,7 +478,7 @@@ struct pci_dev
  int acpi_pci_irq_enable (struct pci_dev *dev);
  void acpi_penalize_isa_irq(int irq, int active);
  
- #ifdef CONFIG_ACPI_DEALLOCATE_IRQ
  void acpi_pci_irq_disable (struct pci_dev *dev);
- #endif
  
  struct acpi_pci_driver {
        struct acpi_pci_driver *next;
diff --combined sound/pci/intel8x0.c
index cc16f95f9ceff2b71cda1e227956cdc851b93daf,2a7e63b5757f42b54e10d2e0c125d04d5f795b66..28ac005c21b5ca9381e62316a4a94e24ddbbb857
@@@ -1725,235 -1725,229 +1725,235 @@@ static struct ac97_pcm ac97_pcm_defs[] 
  
  static struct ac97_quirk ac97_quirks[] __devinitdata = {
        {
 -              .vendor = 0x0e11,
 -              .device = 0x008a,
 +              .subvendor = 0x0e11,
 +              .subdevice = 0x008a,
                .name = "Compaq Evo W4000",     /* AD1885 */
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x0e11,
 -              .device = 0x00b8,
 +              .subvendor = 0x0e11,
 +              .subdevice = 0x00b8,
                .name = "Compaq Evo D510C",
                .type = AC97_TUNE_HP_ONLY
        },
          {
 -              .vendor = 0x0e11,
 -              .device = 0x0860,
 +              .subvendor = 0x0e11,
 +              .subdevice = 0x0860,
                .name = "HP/Compaq nx7010",
                .type = AC97_TUNE_MUTE_LED
          },
        {
 -              .vendor = 0x1014,
 -              .device = 0x1f00,
 +              .subvendor = 0x1014,
 +              .subdevice = 0x1f00,
                .name = "MS-9128",
                .type = AC97_TUNE_ALC_JACK
        },
        {
 -              .vendor = 0x1028,
 -              .device = 0x00d8,
 +              .subvendor = 0x1028,
 +              .subdevice = 0x00d8,
                .name = "Dell Precision 530",   /* AD1885 */
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x1028,
 -              .device = 0x010d,
 +              .subvendor = 0x1028,
 +              .subdevice = 0x010d,
                .name = "Dell", /* which model?  AD1885 */
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x1028,
 -              .device = 0x0126,
 +              .subvendor = 0x1028,
 +              .subdevice = 0x0126,
                .name = "Dell Optiplex GX260",  /* AD1981A */
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x1028,
 -              .device = 0x012c,
 +              .subvendor = 0x1028,
 +              .subdevice = 0x012c,
                .name = "Dell Precision 650",   /* AD1981A */
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x1028,
 -              .device = 0x012d,
 +              .subvendor = 0x1028,
 +              .subdevice = 0x012d,
                .name = "Dell Precision 450",   /* AD1981B*/
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x1028,
 -              .device = 0x0147,
 +              .subvendor = 0x1028,
 +              .subdevice = 0x0147,
                .name = "Dell", /* which model?  AD1981B*/
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x1028,
 -              .device = 0x0163,
 +              .subvendor = 0x1028,
 +              .subdevice = 0x0163,
                .name = "Dell Unknown", /* STAC9750/51 */
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x103c,
 -              .device = 0x006d,
 +              .subvendor = 0x103c,
 +              .subdevice = 0x006d,
                .name = "HP zv5000",
                .type = AC97_TUNE_MUTE_LED      /*AD1981B*/
        },
        {       /* FIXME: which codec? */
 -              .vendor = 0x103c,
 -              .device = 0x00c3,
 +              .subvendor = 0x103c,
 +              .subdevice = 0x00c3,
                .name = "HP xw6000",
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x103c,
 -              .device = 0x088c,
 +              .subvendor = 0x103c,
 +              .subdevice = 0x088c,
                .name = "HP nc8000",
                .type = AC97_TUNE_MUTE_LED
        },
        {
 -              .vendor = 0x103c,
 -              .device = 0x0890,
 +              .subvendor = 0x103c,
 +              .subdevice = 0x0890,
                .name = "HP nc6000",
                .type = AC97_TUNE_MUTE_LED
        },
        {
 -              .vendor = 0x103c,
 -              .device = 0x129d,
 +              .subvendor = 0x103c,
 +              .subdevice = 0x129d,
                .name = "HP xw8000",
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x103c,
 -              .device = 0x12f1,
 +              .subvendor = 0x103c,
 +              .subdevice = 0x12f1,
                .name = "HP xw8200",    /* AD1981B*/
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x103c,
 -              .device = 0x12f2,
 +              .subvendor = 0x103c,
 +              .subdevice = 0x12f2,
                .name = "HP xw6200",
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x103c,
 -              .device = 0x3008,
 +              .subvendor = 0x103c,
 +              .subdevice = 0x3008,
                .name = "HP xw4200",    /* AD1981B*/
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x104d,
 -              .device = 0x8197,
 +              .subvendor = 0x104d,
 +              .subdevice = 0x8197,
                .name = "Sony S1XP",
                .type = AC97_TUNE_INV_EAPD
        },
        {
 -              .vendor = 0x1043,
 -              .device = 0x80f3,
 +              .subvendor = 0x1043,
 +              .subdevice = 0x80f3,
                .name = "ASUS ICH5/AD1985",
                .type = AC97_TUNE_AD_SHARING
        },
        {
 -              .vendor = 0x10cf,
 -              .device = 0x11c3,
 +              .subvendor = 0x10cf,
 +              .subdevice = 0x11c3,
                .name = "Fujitsu-Siemens E4010",
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x10cf,
 -              .device = 0x1253,
 +              .subvendor = 0x10cf,
 +              .subdevice = 0x1225,
 +              .name = "Fujitsu-Siemens T3010",
 +              .type = AC97_TUNE_HP_ONLY
 +      },
 +      {
 +              .subvendor = 0x10cf,
 +              .subdevice = 0x1253,
                .name = "Fujitsu S6210",        /* STAC9750/51 */
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x10f1,
 -              .device = 0x2665,
 +              .subvendor = 0x10f1,
 +              .subdevice = 0x2665,
                .name = "Fujitsu-Siemens Celsius",      /* AD1981? */
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x10f1,
 -              .device = 0x2885,
 +              .subvendor = 0x10f1,
 +              .subdevice = 0x2885,
                .name = "AMD64 Mobo",   /* ALC650 */
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x110a,
 -              .device = 0x0056,
 +              .subvendor = 0x110a,
 +              .subdevice = 0x0056,
                .name = "Fujitsu-Siemens Scenic",       /* AD1981? */
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x11d4,
 -              .device = 0x5375,
 +              .subvendor = 0x11d4,
 +              .subdevice = 0x5375,
                .name = "ADI AD1985 (discrete)",
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x1462,
 -              .device = 0x5470,
 +              .subvendor = 0x1462,
 +              .subdevice = 0x5470,
                .name = "MSI P4 ATX 645 Ultra",
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x1734,
 -              .device = 0x0088,
 +              .subvendor = 0x1734,
 +              .subdevice = 0x0088,
                .name = "Fujitsu-Siemens D1522",        /* AD1981 */
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x8086,
 -              .device = 0x2000,
 +              .subvendor = 0x8086,
 +              .subdevice = 0x2000,
                .mask = 0xfff0,
                .name = "Intel ICH5/AD1985",
                .type = AC97_TUNE_AD_SHARING
        },
        {
 -              .vendor = 0x8086,
 -              .device = 0x4000,
 +              .subvendor = 0x8086,
 +              .subdevice = 0x4000,
                .mask = 0xfff0,
                .name = "Intel ICH5/AD1985",
                .type = AC97_TUNE_AD_SHARING
        },
        {
 -              .vendor = 0x8086,
 -              .device = 0x4856,
 +              .subvendor = 0x8086,
 +              .subdevice = 0x4856,
                .name = "Intel D845WN (82801BA)",
                .type = AC97_TUNE_SWAP_HP
        },
        {
 -              .vendor = 0x8086,
 -              .device = 0x4d44,
 +              .subvendor = 0x8086,
 +              .subdevice = 0x4d44,
                .name = "Intel D850EMV2",       /* AD1885 */
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x8086,
 -              .device = 0x4d56,
 +              .subvendor = 0x8086,
 +              .subdevice = 0x4d56,
                .name = "Intel ICH/AD1885",
                .type = AC97_TUNE_HP_ONLY
        },
        {
 -              .vendor = 0x8086,
 -              .device = 0x6000,
 +              .subvendor = 0x8086,
 +              .subdevice = 0x6000,
                .mask = 0xfff0,
                .name = "Intel ICH5/AD1985",
                .type = AC97_TUNE_AD_SHARING
        },
        {
 -              .vendor = 0x8086,
 -              .device = 0xe000,
 +              .subvendor = 0x8086,
 +              .subdevice = 0xe000,
                .mask = 0xfff0,
                .name = "Intel ICH5/AD1985",
                .type = AC97_TUNE_AD_SHARING
        },
  #if 0 /* FIXME: this seems wrong on most boards */
        {
 -              .vendor = 0x8086,
 -              .device = 0xa000,
 +              .subvendor = 0x8086,
 +              .subdevice = 0xa000,
                .mask = 0xfff0,
                .name = "Intel ICH5/AD1985",
                .type = AC97_TUNE_HP_ONLY
@@@ -2373,6 -2367,8 +2373,8 @@@ static int intel8x0_suspend(snd_card_t 
        for (i = 0; i < 3; i++)
                if (chip->ac97[i])
                        snd_ac97_suspend(chip->ac97[i]);
+       if (chip->irq >= 0)
+               free_irq(chip->irq, (void *)chip);
        pci_disable_device(chip->pci);
        return 0;
  }
@@@ -2384,7 -2380,9 +2386,9 @@@ static int intel8x0_resume(snd_card_t *
  
        pci_enable_device(chip->pci);
        pci_set_master(chip->pci);
-       snd_intel8x0_chip_init(chip, 0);
+       request_irq(chip->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip);
+       synchronize_irq(chip->irq);
+       snd_intel8x0_chip_init(chip, 1);
  
        /* refill nocache */
        if (chip->fix_nocache)
@@@ -2855,7 -2853,7 +2859,7 @@@ static struct pci_driver driver = 
  
  static int __init alsa_card_intel8x0_init(void)
  {
 -      return pci_module_init(&driver);
 +      return pci_register_driver(&driver);
  }
  
  static void __exit alsa_card_intel8x0_exit(void)