This file details changes in 2.6 which affect PCMCIA card driver authors:
+* New IRQ request rules (as of 2.6.35)
+   Instead of the old pcmcia_request_irq() interface, drivers may now
+   choose between:
+   - calling request_irq/free_irq directly. Use the IRQ from *p_dev->irq.
+   - use pcmcia_request_irq(p_dev, handler_t); the PCMCIA core will
+     clean up automatically on calls to pcmcia_disable_device() or
+     device ejection.
+   - drivers still not capable of IRQF_SHARED (or not telling us so) may
+     use the deprecated pcmcia_request_exclusive_irq() for the time
+     being; they might receive a shared IRQ nonetheless.
 
 * no cs_error / CS_CHECK / CONFIG_PCMCIA_DEBUG (as of 2.6.33)
    Instead of the cs_error() callback or the CS_CHECK() macro, please use
 
        pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
        pdev->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
        pdev->io.IOAddrLines = 3;
-       pdev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
        pdev->conf.Attributes = CONF_ENABLE_IRQ;
        pdev->conf.IntType = INT_MEMORY_AND_IO;
 
        }
        io_base = pdev->io.BasePort1;
        ctl_base = stk->ctl_base;
-       ret = pcmcia_request_irq(pdev, &pdev->irq);
-       if (ret)
+       if (!pdev->irq)
                goto failed;
 
        ret = pcmcia_request_configuration(pdev, &pdev->conf);
        }
 
        /* activate */
-       ret = ata_host_activate(host, pdev->irq.AssignedIRQ, ata_sff_interrupt,
+       ret = ata_host_activate(host, pdev->irq, ata_sff_interrupt,
                                IRQF_SHARED, &pcmcia_sht);
        if (ret)
                goto failed;
 
 
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
        link->io.NumPorts1 = 8;
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-
-       link->irq.Handler = bluecard_interrupt;
 
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
        if (i != 0)
                goto failed;
 
-       i = pcmcia_request_irq(link, &link->irq);
+       i = pcmcia_request_irq(link, bluecard_interrupt);
        if (i != 0)
-               link->irq.AssignedIRQ = 0;
+               goto failed;
 
        i = pcmcia_request_configuration(link, &link->conf);
        if (i != 0)
 
 
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
        link->io.NumPorts1 = 8;
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-
-       link->irq.Handler = bt3c_interrupt;
 
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
        goto failed;
 
 found_port:
-       i = pcmcia_request_irq(link, &link->irq);
+       i = pcmcia_request_irq(link, &bt3c_interrupt);
        if (i != 0)
-               link->irq.AssignedIRQ = 0;
+               goto failed;
 
        i = pcmcia_request_configuration(link, &link->conf);
        if (i != 0)
 
 
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
        link->io.NumPorts1 = 8;
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-
-       link->irq.Handler = btuart_interrupt;
 
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
        goto failed;
 
 found_port:
-       i = pcmcia_request_irq(link, &link->irq);
+       i = pcmcia_request_irq(link, btuart_interrupt);
        if (i != 0)
-               link->irq.AssignedIRQ = 0;
+               goto failed;
 
        i = pcmcia_request_configuration(link, &link->conf);
        if (i != 0)
 
 
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
        link->io.NumPorts1 = 8;
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-
-       link->irq.Handler = dtl1_interrupt;
 
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
        if (pcmcia_loop_config(link, dtl1_confcheck, NULL) < 0)
                goto failed;
 
-       i = pcmcia_request_irq(link, &link->irq);
+       i = pcmcia_request_irq(link, dtl1_interrupt);
        if (i != 0)
-               link->irq.AssignedIRQ = 0;
+               goto failed;
 
        i = pcmcia_request_configuration(link, &link->conf);
        if (i != 0)
 
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
 
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       link->irq.Handler = ipwireless_interrupt;
-
        INIT_WORK(&ipw->work_reboot, signalled_reboot_work);
 
        ipwireless_init_hardware_v1(ipw->hardware, link->io.BasePort1,
                                    ipw->is_v2_card, signalled_reboot_callback,
                                    ipw);
 
-       ret = pcmcia_request_irq(link, &link->irq);
-
+       ret = pcmcia_request_irq(link, ipwireless_interrupt);
        if (ret != 0)
                goto exit;
 
                        (unsigned int) link->io.BasePort1,
                        (unsigned int) (link->io.BasePort1 +
                                link->io.NumPorts1 - 1),
-                       (unsigned int) link->irq.AssignedIRQ);
+                       (unsigned int) link->irq);
        if (ipw->attr_memory && ipw->common_memory)
                printk(KERN_INFO IPWIRELESS_PCCARD_NAME
                        ": attr memory 0x%08lx-0x%08lx, common memory 0x%08lx-0x%08lx\n",
 
 static void release_ipwireless(struct ipw_dev *ipw)
 {
-       pcmcia_disable_device(ipw->link);
-
        if (ipw->common_memory) {
                release_mem_region(ipw->request_common_memory.Base,
                                ipw->request_common_memory.Size);
        if (ipw->attr_memory)
                pcmcia_release_window(ipw->link, ipw->handle_attr_memory);
 
-       /* Break the link with Card Services */
        pcmcia_disable_device(ipw->link);
 }
 
 
 
     /* Initialize the struct pcmcia_device structure */
 
-    /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.Handler = NULL;
-
     link->conf.Attributes = 0;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
     link->conf.ConfigIndex = 8;
     link->conf.Present = PRESENT_OPTION;
 
-    link->irq.Handler     = mgslpc_isr;
-
-    ret = pcmcia_request_irq(link, &link->irq);
+    ret = pcmcia_request_irq(link, mgslpc_isr);
     if (ret)
            goto failed;
     ret = pcmcia_request_configuration(link, &link->conf);
            goto failed;
 
     info->io_base = link->io.BasePort1;
-    info->irq_level = link->irq.AssignedIRQ;
+    info->irq_level = link->irq;
 
     /* add to linked list of devices */
     sprintf(info->node.dev_name, "mgslpc0");
     printk(KERN_INFO "%s: index 0x%02x:",
           info->node.dev_name, link->conf.ConfigIndex);
     if (link->conf.Attributes & CONF_ENABLE_IRQ)
-           printk(", irq %d", link->irq.AssignedIRQ);
+           printk(", irq %d", link->irq);
     if (link->io.NumPorts1)
            printk(", io 0x%04x-0x%04x", link->io.BasePort1,
                   link->io.BasePort1+link->io.NumPorts1-1);
 
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.IOAddrLines = 3;
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
     io_base = link->io.BasePort1;
     ctl_base = stk->ctl_base;
 
-    ret = pcmcia_request_irq(link, &link->irq);
-    if (ret)
+    if (!link->irq)
            goto failed;
     ret = pcmcia_request_configuration(link, &link->conf);
     if (ret)
     if (is_kme)
        outb(0x81, ctl_base+1);
 
-     host = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link);
+     host = idecs_register(io_base, ctl_base, link->irq, link);
      if (host == NULL && link->io.NumPorts1 == 0x20) {
            outb(0x02, ctl_base + 0x10);
            host = idecs_register(io_base + 0x10, ctl_base + 0x10,
-                                 link->irq.AssignedIRQ, link);
+                                 link->irq, link);
     }
 
     if (host == NULL)
 
     p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
     p_dev->io.NumPorts2 = 0;
 
-    /* Interrupt setup */
-    p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-
     /* General socket configuration */
     p_dev->conf.Attributes = CONF_ENABLE_IRQ;
     p_dev->conf.IntType = INT_MEMORY_AND_IO;
 static int avmcs_config(struct pcmcia_device *link)
 {
     local_info_t *dev;
-    int i;
+    int i = -1;
     char devname[128];
     int cardtype;
     int (*addcard)(unsigned int port, unsigned irq);
            return -ENODEV;
 
     do {
-       /*
-        * allocate an interrupt line
-        */
-       i = pcmcia_request_irq(link, &link->irq);
-       if (i != 0) {
+       if (!link->irq) {
            /* undo */
            pcmcia_disable_device(link);
            break;
        default:
         case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break;
     }
-    if ((i = (*addcard)(link->io.BasePort1, link->irq.AssignedIRQ)) < 0) {
+    if ((i = (*addcard)(link->io.BasePort1, link->irq)) < 0) {
         printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n",
-               dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ);
+               dev->node.dev_name, link->io.BasePort1, link->irq);
        avmcs_release(link);
        return -ENODEV;
     }
 
 static void avmcs_release(struct pcmcia_device *link)
 {
-       b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ);
+       b1pcmcia_delcard(link->io.BasePort1, link->irq);
        pcmcia_disable_device(link);
 } /* avmcs_release */
 
 
     p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
     p_dev->io.IOAddrLines = 5;
 
-    /* Interrupt setup */
-    p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-
     /* General socket configuration */
     p_dev->conf.Attributes = CONF_ENABLE_IRQ;
     p_dev->conf.IntType = INT_MEMORY_AND_IO;
 static int __devinit avma1cs_config(struct pcmcia_device *link)
 {
     local_info_t *dev;
-    int i;
+    int i = -1;
     char devname[128];
     IsdnCard_t icard;
     int busy = 0;
        /*
         * allocate an interrupt line
         */
-       i = pcmcia_request_irq(link, &link->irq);
-       if (i != 0) {
+       if (!link->irq) {
            /* undo */
            pcmcia_disable_device(link);
            break;
     }
 
     printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n",
-                               link->io.BasePort1, link->irq.AssignedIRQ);
+                               link->io.BasePort1, link->irq);
 
-    icard.para[0] = link->irq.AssignedIRQ;
+    icard.para[0] = link->irq;
     icard.para[1] = link->io.BasePort1;
     icard.protocol = isdnprot;
     icard.typ = ISDN_CTYPE_A1_PCMCIA;
 
 
     local->cardnr = -1;
 
-    /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.Handler = NULL;
-
     /*
       General socket configuration defaults can go here.  In this
       client, we assume very little, and rely on the CIS for almost
     if (i != 0)
        goto failed;
 
-    i = pcmcia_request_irq(link, &link->irq);
-    if (i != 0) {
-        link->irq.AssignedIRQ = 0;
+    if (!link->irq)
        goto failed;
-    }
 
     i = pcmcia_request_configuration(link, &link->conf);
     if (i != 0)
     printk(KERN_INFO "%s: index 0x%02x: ",
            dev->node.dev_name, link->conf.ConfigIndex);
     if (link->conf.Attributes & CONF_ENABLE_IRQ)
-        printk(", irq %d", link->irq.AssignedIRQ);
+       printk(", irq %d", link->irq);
     if (link->io.NumPorts1)
         printk(", io 0x%04x-0x%04x", link->io.BasePort1,
                link->io.BasePort1+link->io.NumPorts1-1);
                link->io.BasePort2+link->io.NumPorts2-1);
     printk("\n");
 
-    icard.para[0] = link->irq.AssignedIRQ;
+    icard.para[0] = link->irq;
     icard.para[1] = link->io.BasePort1;
     icard.protocol = protocol;
     icard.typ = ISDN_CTYPE_ELSA_PCMCIA;
 
     local->p_dev = link;
     link->priv = local;
 
-    /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.Handler = NULL;
-
     /*
       General socket configuration defaults can go here.  In this
       client, we assume very little, and rely on the CIS for almost
        else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
                p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
 
-       /* Do we need to allocate an interrupt? */
-       if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
-               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+       p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
        p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
     if (ret)
            goto failed;
 
-    /*
-       Allocate an interrupt line.  Note that this does not assign a
-       handler to the interrupt, unless the 'Handler' member of the
-       irq structure is initialized.
-    */
-    if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-           ret = pcmcia_request_irq(link, &link->irq);
-           if (ret)
-                   goto failed;
-    }
-       
     /*
        This actually configures the PCMCIA socket -- setting up
        the I/O windows and the interrupt mapping, and putting the
     if (link->conf.Vpp)
        printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
     if (link->conf.Attributes & CONF_ENABLE_IRQ)
-       printk(", irq %d", link->irq.AssignedIRQ);
+       printk(", irq %d", link->irq);
     if (link->io.NumPorts1)
        printk(", io 0x%04x-0x%04x", link->io.BasePort1,
               link->io.BasePort1+link->io.NumPorts1-1);
               req->Base+req->Size-1);
     printk("\n");
 
-    icard.para[0] = link->irq.AssignedIRQ;
+    icard.para[0] = link->irq;
     icard.para[1] = link->io.BasePort1;
     icard.protocol = protocol;
     icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;
 
     local->p_dev = link;
     link->priv = local;
 
-    /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.Handler = NULL;
-
     /*
       General socket configuration defaults can go here.  In this
       client, we assume very little, and rely on the CIS for almost
     if (i != 0)
        goto cs_failed;
 
-    i = pcmcia_request_irq(link, &link->irq);
-    if (i != 0) {
-        link->irq.AssignedIRQ = 0;
+    if (!link->irq)
         goto cs_failed;
-    }
 
     i = pcmcia_request_configuration(link, &link->conf);
     if (i != 0)
     printk(KERN_INFO "%s: index 0x%02x:",
            dev->node.dev_name, link->conf.ConfigIndex);
     if (link->conf.Attributes & CONF_ENABLE_IRQ)
-        printk(", irq %d", link->irq.AssignedIRQ);
+           printk(", irq %d", link->irq);
     if (link->io.NumPorts1)
         printk(", io 0x%04x-0x%04x", link->io.BasePort1,
                link->io.BasePort1+link->io.NumPorts1-1);
                link->io.BasePort2+link->io.NumPorts2-1);
     printk("\n");
 
-    icard.para[0] = link->irq.AssignedIRQ;
+    icard.para[0] = link->irq;
     icard.para[1] = link->io.BasePort1;
     icard.protocol = protocol;
     icard.typ = ISDN_CTYPE_TELESPCMCIA;
 
        spin_lock_init(&lp->window_lock);
        link->io.NumPorts1 = 32;
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       link->irq.Handler = &el3_interrupt;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
        link->conf.ConfigIndex = 1;
        if (i != 0)
                goto failed;
 
-       ret = pcmcia_request_irq(link, &link->irq);
+       ret = pcmcia_request_irq(link, el3_interrupt);
        if (ret)
                goto failed;
 
        if (ret)
                goto failed;
 
-       dev->irq = link->irq.AssignedIRQ;
+       dev->irq = link->irq;
        dev->base_addr = link->io.BasePort1;
 
        ioaddr = dev->base_addr;
 
     spin_lock_init(&lp->lock);
     link->io.NumPorts1 = 16;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.Handler = &el3_interrupt;
+
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.ConfigIndex = 1;
     if (i != 0)
        goto failed;
 
-    ret = pcmcia_request_irq(link, &link->irq);
+    ret = pcmcia_request_irq(link, el3_interrupt);
     if (ret)
            goto failed;
 
     if (ret)
            goto failed;
        
-    dev->irq = link->irq.AssignedIRQ;
+    dev->irq = link->irq;
     dev->base_addr = link->io.BasePort1;
     ioaddr = dev->base_addr;
     EL3WINDOW(0);
 
     info = PRIV(dev);
     info->p_dev = link;
     link->priv = dev;
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
     int j, ret;
     if (link->io.NumPorts1 == 32) {
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-       if (link->io.NumPorts2 > 0) {
-           /* for master/slave multifunction cards */
+       /* for master/slave multifunction cards */
+       if (link->io.NumPorts2 > 0)
            link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
-           link->irq.Attributes =
-               IRQ_TYPE_DYNAMIC_SHARING;
-       }
     } else {
        /* This should be two 16-port windows */
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
     if (ret != 0)
        goto failed;
 
-    ret = pcmcia_request_irq(link, &link->irq);
-    if (ret)
+    if (!link->irq)
            goto failed;
     
     if (link->io.NumPorts2 == 8) {
     if (ret)
            goto failed;
 
-    dev->irq = link->irq.AssignedIRQ;
+    dev->irq = link->irq;
     dev->base_addr = link->io.BasePort1;
 
     if (!get_prom(link)) {
 
     p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
     p_dev->io.NumPorts1 = 16;
     p_dev->io.IOAddrLines = 16;
-    p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
     p_dev->conf.Attributes = CONF_ENABLE_IRQ;
     p_dev->conf.IntType = INT_MEMORY_AND_IO;
 
     dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr);
 
     dev_dbg(&link->dev, "request IRQ %d\n",
-           link->irq.AssignedIRQ);
-    i = pcmcia_request_irq(link, &link->irq);
-    if (i != 0)
+           link->irq);
+    if (!link->irq)
     {
        dev_dbg(&link->dev, "requestIRQ failed totally!\n");
        goto failed;
     }
 
-    dev->irq = link->irq.AssignedIRQ;
+    dev->irq = link->irq;
 
     ret = pcmcia_request_configuration(link, &link->conf);
     if (ret)
 
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 5;
 
-    /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.Handler = fjn_interrupt;
-
     /* General socket configuration */
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     }
 
     if (link->io.NumPorts2 != 0) {
-       link->irq.Attributes =
-               IRQ_TYPE_DYNAMIC_SHARING;
        ret = mfc_try_io_port(link);
        if (ret != 0) goto failed;
     } else if (cardtype == UNGERMANN) {
            if (ret)
                    goto failed;
     }
-    ret = pcmcia_request_irq(link, &link->irq);
+    ret = pcmcia_request_irq(link, fjn_interrupt);
     if (ret)
            goto failed;
     ret = pcmcia_request_configuration(link, &link->conf);
     if (ret)
            goto failed;
 
-    dev->irq = link->irq.AssignedIRQ;
+    dev->irq = link->irq;
     dev->base_addr = link->io.BasePort1;
 
     if (link->io.BasePort2 != 0) {
 
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts1 = 4;
     link->io.IOAddrLines = 16;
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.Handler = ibmtr_interrupt;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.Present = PRESENT_OPTION;
     }
     dev->base_addr = link->io.BasePort1;
 
-    ret = pcmcia_request_irq(link, &link->irq);
+    ret = pcmcia_request_exclusive_irq(link, ibmtr_interrupt);
     if (ret)
            goto failed;
-    dev->irq = link->irq.AssignedIRQ;
-    ti->irq = link->irq.AssignedIRQ;
+    dev->irq = link->irq;
+    ti->irq = link->irq;
     ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
 
     /* Allocate the MMIO memory window */
 
     link->io.NumPorts1 = 32;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 5;
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.Handler = mace_interrupt;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.ConfigIndex = 1;
   ret = pcmcia_request_io(link, &link->io);
   if (ret)
          goto failed;
-  ret = pcmcia_request_irq(link, &link->irq);
+  ret = pcmcia_request_exclusive_irq(link, mace_interrupt);
   if (ret)
          goto failed;
   ret = pcmcia_request_configuration(link, &link->conf);
   if (ret)
          goto failed;
 
-  dev->irq = link->irq.AssignedIRQ;
+  dev->irq = link->irq;
   dev->base_addr = link->io.BasePort1;
 
   ioaddr = dev->base_addr;
 
     info->p_dev = link;
     link->priv = dev;
 
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
        if (link->io.NumPorts2 > 0) {
            /* for master/slave multifunction cards */
            link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
-           link->irq.Attributes =
-               IRQ_TYPE_DYNAMIC_SHARING;
        }
     } else {
        /* This should be two 16-port windows */
     if (ret)
        goto failed;
 
-    ret = pcmcia_request_irq(link, &link->irq);
-    if (ret)
+    if (!link->irq)
            goto failed;
 
     if (link->io.NumPorts2 == 8) {
     ret = pcmcia_request_configuration(link, &link->conf);
     if (ret)
            goto failed;
-    dev->irq = link->irq.AssignedIRQ;
+    dev->irq = link->irq;
     dev->base_addr = link->io.BasePort1;
     if (info->flags & HAS_MISC_REG) {
        if ((if_port == 1) || (if_port == 2))
 
     link->io.NumPorts1 = 16;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 4;
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.Handler = &smc_interrupt;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
 
     link->conf.Attributes |= CONF_ENABLE_SPKR;
     link->conf.Status = CCSR_AUDIO_ENA;
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->io.IOAddrLines = 16;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts2 = 8;
 
     link->conf.Attributes |= CONF_ENABLE_SPKR;
     link->conf.Status = CCSR_AUDIO_ENA;
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->io.NumPorts1 = 64;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts2 = 8;
     if (i)
            goto config_failed;
 
-    i = pcmcia_request_irq(link, &link->irq);
+    i = pcmcia_request_irq(link, smc_interrupt);
     if (i)
            goto config_failed;
     i = pcmcia_request_configuration(link, &link->conf);
     if (smc->manfid == MANFID_MOTOROLA)
        mot_config(link);
 
-    dev->irq = link->irq.AssignedIRQ;
+    dev->irq = link->irq;
 
     if ((if_port >= 0) && (if_port <= 2))
        dev->if_port = if_port;
 
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.ConfigIndex = 1;
-    link->irq.Handler = xirc2ps_interrupt;
 
     /* Fill in card specific entries */
     dev->netdev_ops = &netdev_ops;
            link->conf.Attributes |= CONF_ENABLE_SPKR;
            link->conf.Status |= CCSR_AUDIO_ENA;
        }
-       link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING;
        link->io.NumPorts2 = 8;
        link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
        if (local->dingo) {
        }
        printk(KNOT_XIRC "no ports available\n");
     } else {
-       link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING;
        link->io.NumPorts1 = 16;
        for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
            link->io.BasePort1 = ioaddr;
      * Now allocate an interrupt line. Note that this does not
      * actually assign a handler to the interrupt.
      */
-    if ((err=pcmcia_request_irq(link, &link->irq)))
+    if ((err=pcmcia_request_irq(link, xirc2ps_interrupt)))
        goto config_error;
 
     /****************
        printk(KNOT_XIRC "invalid if_port requested\n");
 
     /* we can now register the device with the net subsystem */
-    dev->irq = link->irq.AssignedIRQ;
+    dev->irq = link->irq;
     dev->base_addr = link->io.BasePort1;
 
     if (local->dingo)
 
 
        dev_dbg(&p_dev->dev, "airo_attach()\n");
 
-       /* Interrupt setup */
-       p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       p_dev->irq.Handler = NULL;
-
        /*
          General socket configuration defaults can go here.  In this
          client, we assume very little, and rely on the CIS for almost
        else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
                p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
 
-       /* Do we need to allocate an interrupt? */
-       if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
-               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+       p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
        p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
        if (ret)
                goto failed;
 
-       /*
-         Allocate an interrupt line.  Note that this does not assign a
-         handler to the interrupt, unless the 'Handler' member of the
-         irq structure is initialized.
-       */
-       if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               ret = pcmcia_request_irq(link, &link->irq);
-               if (ret)
-                       goto failed;
-       }
+       if (!link->irq)
+               goto failed;
 
        /*
          This actually configures the PCMCIA socket -- setting up
        if (ret)
                goto failed;
        ((local_info_t *)link->priv)->eth_dev =
-               init_airo_card(link->irq.AssignedIRQ,
+               init_airo_card(link->irq,
                               link->io.BasePort1, 1, &link->dev);
        if (!((local_info_t *)link->priv)->eth_dev)
                goto failed;
               dev->node.dev_name, link->conf.ConfigIndex);
        if (link->conf.Vpp)
                printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
-       if (link->conf.Attributes & CONF_ENABLE_IRQ)
-               printk(", irq %d", link->irq.AssignedIRQ);
+       printk(", irq %d", link->irq);
        if (link->io.NumPorts1)
                printk(", io 0x%04x-0x%04x", link->io.BasePort1,
                       link->io.BasePort1+link->io.NumPorts1-1);
 
 
        dev_dbg(&p_dev->dev, "atmel_attach()\n");
 
-       /* Interrupt setup */
-       p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       p_dev->irq.Handler = NULL;
-
        /*
          General socket configuration defaults can go here.  In this
          client, we assume very little, and rely on the CIS for almost
        else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
                p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
 
-       /* Do we need to allocate an interrupt? */
-       if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
-               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+       p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
        p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
        if (pcmcia_loop_config(link, atmel_config_check, NULL))
                goto failed;
 
-       /*
-         Allocate an interrupt line.  Note that this does not assign a
-         handler to the interrupt, unless the 'Handler' member of the
-         irq structure is initialized.
-       */
-       if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               ret = pcmcia_request_irq(link, &link->irq);
-               if (ret)
-                       goto failed;
+       if (!link->irq) {
+               dev_err(&link->dev, "atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config.");
+               goto failed;
        }
 
        /*
        if (ret)
                goto failed;
 
-       if (link->irq.AssignedIRQ == 0) {
-               printk(KERN_ALERT
-                      "atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config.");
-               goto failed;
-       }
-
        ((local_info_t*)link->priv)->eth_dev =
-               init_atmel_card(link->irq.AssignedIRQ,
+               init_atmel_card(link->irq,
                                link->io.BasePort1,
                                did ? did->driver_info : ATMEL_FW_TYPE_NONE,
                                &link->dev,
 
        if (res != 0)
                goto err_disable;
 
-       dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       dev->irq.Handler = NULL; /* The handler is registered later. */
-       res = pcmcia_request_irq(dev, &dev->irq);
-       if (res != 0)
+       if (!dev->irq)
                goto err_disable;
 
        res = pcmcia_request_configuration(dev, &dev->conf);
 
                p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
 
        /* Do we need to allocate an interrupt? */
-       if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
-               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
-       else if (!(p_dev->conf.Attributes & CONF_ENABLE_IRQ)) {
-               /* At least Compaq WL200 does not have IRQInfo1 set,
-                * but it does not work without interrupts.. */
-               printk(KERN_WARNING "Config has no IRQ info, but trying to "
-                      "enable IRQ anyway..\n");
-               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
-       }
+       p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
        PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
        strcpy(hw_priv->node.dev_name, dev->name);
        link->dev_node = &hw_priv->node;
 
-       /*
-        * Allocate an interrupt line.  Note that this does not assign a
-        * handler to the interrupt, unless the 'Handler' member of the
-        * irq structure is initialized.
-        */
-       if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-               link->irq.Handler = prism2_interrupt;
-               ret = pcmcia_request_irq(link, &link->irq);
-               if (ret)
-                       goto failed;
-       }
+       ret = pcmcia_request_irq(link, prism2_interrupt);
+       if (ret)
+               goto failed;
 
        /*
         * This actually configures the PCMCIA socket -- setting up
        if (ret)
                goto failed;
 
-       dev->irq = link->irq.AssignedIRQ;
+       dev->irq = link->irq;
        dev->base_addr = link->io.BasePort1;
 
        /* Finally, report what we've done */
                printk(", Vpp %d.%d", link->conf.Vpp / 10,
                       link->conf.Vpp % 10);
        if (link->conf.Attributes & CONF_ENABLE_IRQ)
-               printk(", irq %d", link->irq.AssignedIRQ);
+               printk(", irq %d", link->irq);
        if (link->io.NumPorts1)
                printk(", io 0x%04x-0x%04x", link->io.BasePort1,
                       link->io.BasePort1+link->io.NumPorts1-1);
 
 
        lbs_deb_enter(LBS_DEB_CS);
 
-       free_irq(p_dev->irq.AssignedIRQ, card);
+       free_irq(p_dev->irq, card);
        pcmcia_disable_device(p_dev);
        if (card->iobase)
                ioport_unmap(card->iobase);
        p_dev->io.NumPorts1 = cfg->io.win[0].len;
 
        /* Do we need to allocate an interrupt? */
-       if (cfg->irq.IRQInfo1)
-               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+       p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
        if (cfg->io.nwin != 1) {
        card->p_dev = p_dev;
        p_dev->priv = card;
 
-       p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       p_dev->irq.Handler = NULL;
-
        p_dev->conf.Attributes = 0;
        p_dev->conf.IntType = INT_MEMORY_AND_IO;
 
         * a handler to the interrupt, unless the 'Handler' member of
         * the irq structure is initialized.
         */
-       if (p_dev->conf.Attributes & CONF_ENABLE_IRQ) {
-               ret = pcmcia_request_irq(p_dev, &p_dev->irq);
-               if (ret) {
-                       lbs_pr_err("error in pcmcia_request_irq\n");
-                       goto out1;
-               }
-       }
+       if (!p_dev->irq)
+               goto out1;
 
        /* Initialize io access */
        card->iobase = ioport_map(p_dev->io.BasePort1, p_dev->io.NumPorts1);
 
        /* Finally, report what we've done */
        lbs_deb_cs("irq %d, io 0x%04x-0x%04x\n",
-              p_dev->irq.AssignedIRQ, p_dev->io.BasePort1,
+              p_dev->irq, p_dev->io.BasePort1,
               p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1);
 
        /*
        priv->fw_ready = 1;
 
        /* Now actually get the IRQ */
-       ret = request_irq(p_dev->irq.AssignedIRQ, if_cs_interrupt,
+       ret = request_irq(p_dev->irq, if_cs_interrupt,
                IRQF_SHARED, DRV_NAME, card);
        if (ret) {
                lbs_pr_err("error in request_irq\n");
 
        card->p_dev = link;
        link->priv = priv;
 
-       /* Interrupt setup */
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       link->irq.Handler = orinoco_interrupt;
-
        /* General socket configuration defaults can go here.  In this
         * client, we assume very little, and rely on the CIS for
         * almost everything.  In most clients, many details (i.e.,
                goto failed;
        }
 
-       /*
-        * Allocate an interrupt line.  Note that this does not assign
-        * a handler to the interrupt, unless the 'Handler' member of
-        * the irq structure is initialized.
-        */
-       ret = pcmcia_request_irq(link, &link->irq);
+       ret = pcmcia_request_irq(link, orinoco_interrupt);
        if (ret)
                goto failed;
 
 
        /* Register an interface with the stack */
        if (orinoco_if_add(priv, link->io.BasePort1,
-                          link->irq.AssignedIRQ) != 0) {
+                          link->irq) != 0) {
                printk(KERN_ERR PFX "orinoco_if_add() failed\n");
                goto failed;
        }
 
        card->p_dev = link;
        link->priv = priv;
 
-       /* Interrupt setup */
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       link->irq.Handler = orinoco_interrupt;
-
        /* General socket configuration defaults can go here.  In this
         * client, we assume very little, and rely on the CIS for
         * almost everything.  In most clients, many details (i.e.,
                goto failed;
        }
 
-       /*
-        * Allocate an interrupt line.  Note that this does not assign
-        * a handler to the interrupt, unless the 'Handler' member of
-        * the irq structure is initialized.
-        */
-       ret = pcmcia_request_irq(link, &link->irq);
+       ret = pcmcia_request_irq(link, orinoco_interrupt);
        if (ret)
                goto failed;
 
 
        /* Register an interface with the stack */
        if (orinoco_if_add(priv, link->io.BasePort1,
-                          link->irq.AssignedIRQ) != 0) {
+                          link->irq) != 0) {
                printk(KERN_ERR PFX "orinoco_if_add() failed\n");
                goto failed;
        }
 
        p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
        p_dev->io.IOAddrLines = 5;
 
-       /* Interrupt setup. For PCMCIA, driver takes what's given */
-       p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       p_dev->irq.Handler = &ray_interrupt;
-
        /* General socket configuration */
        p_dev->conf.Attributes = CONF_ENABLE_IRQ;
        p_dev->conf.IntType = INT_MEMORY_AND_IO;
        /* Now allocate an interrupt line.  Note that this does not
           actually assign a handler to the interrupt.
         */
-       ret = pcmcia_request_irq(link, &link->irq);
+       ret = pcmcia_request_irq(link, ray_interrupt);
        if (ret)
                goto failed;
-       dev->irq = link->irq.AssignedIRQ;
+       dev->irq = link->irq;
 
        /* This actually configures the PCMCIA socket -- setting up
           the I/O windows and the interrupt mapping.
 
        p_dev->io.Attributes1   = IO_DATA_PATH_WIDTH_8;
        p_dev->io.IOAddrLines   = 5;
 
-       /* Interrupt setup */
-       p_dev->irq.Attributes   = IRQ_TYPE_DYNAMIC_SHARING;
-       p_dev->irq.Handler = wl3501_interrupt;
-
        /* General socket configuration */
        p_dev->conf.Attributes  = CONF_ENABLE_IRQ;
        p_dev->conf.IntType     = INT_MEMORY_AND_IO;
        /* Now allocate an interrupt line. Note that this does not actually
         * assign a handler to the interrupt. */
 
-       ret = pcmcia_request_irq(link, &link->irq);
+       ret = pcmcia_request_irq(link, wl3501_interrupt);
        if (ret)
                goto failed;
 
        if (ret)
                goto failed;
 
-       dev->irq = link->irq.AssignedIRQ;
+       dev->irq = link->irq;
        dev->base_addr = link->io.BasePort1;
        SET_NETDEV_DEV(dev, &link->dev);
        if (register_netdev(dev)) {
 
 
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
     if (ret)
            goto failed;
 
-    ret = pcmcia_request_irq(link, &link->irq);
-    if (ret)
+    if (!link->irq)
            goto failed;
     ret = pcmcia_request_configuration(link, &link->conf);
     if (ret)
            goto failed;
 
     p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
-                             link->irq.AssignedIRQ, PARPORT_DMA_NONE,
+                             link->irq, PARPORT_DMA_NONE,
                              &link->dev, IRQF_SHARED);
     if (p == NULL) {
        printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at "
               "0x%3x, irq %u failed\n", link->io.BasePort1,
-              link->irq.AssignedIRQ);
+              link->irq);
        goto failed;
     }
 
 
                        p_dev->function_config = tmp_dev->function_config;
                        p_dev->io = tmp_dev->io;
                        p_dev->irq = tmp_dev->irq;
-                       p_dev->irq_v = tmp_dev->irq_v;
                        kref_get(&p_dev->function_config->ref);
                }
 
 
        dev_printk(KERN_NOTICE, &p_dev->dev,
                   "pcmcia: registering new device %s (IRQ: %d)\n",
-                  p_dev->devname, p_dev->irq_v);
+                  p_dev->devname, p_dev->irq);
 
        pcmcia_device_query(p_dev);
 
 
 } /* pcmcia_release_io */
 
 
-static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
-{
-       struct pcmcia_socket *s = p_dev->socket;
-       config_t *c;
-       int ret = -EINVAL;
-
-       mutex_lock(&s->ops_mutex);
-
-       c = p_dev->function_config;
-
-       if (!p_dev->_irq)
-               goto out;
-
-       p_dev->_irq = 0;
-
-       if (c->state & CONFIG_LOCKED)
-               goto out;
-
-       if (s->pcmcia_irq != req->AssignedIRQ) {
-               dev_dbg(&s->dev, "IRQ must match assigned one\n");
-               goto out;
-       }
-
-       if (req->Handler)
-               free_irq(req->AssignedIRQ, p_dev->priv);
-
-       ret = 0;
-
-out:
-       mutex_unlock(&s->ops_mutex);
-
-       return ret;
-} /* pcmcia_release_irq */
-
-
 int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh)
 {
        struct pcmcia_socket *s = p_dev->socket;
 EXPORT_SYMBOL(pcmcia_request_io);
 
 
-/** pcmcia_request_irq
+/**
+ * pcmcia_request_irq() - attempt to request a IRQ for a PCMCIA device
  *
- * Request_irq() reserves an irq for this client.
+ * pcmcia_request_irq() is a wrapper around request_irq which will allow
+ * the PCMCIA core to clean up the registration in pcmcia_disable_device().
+ * Drivers are free to use request_irq() directly, but then they need to
+ * call free_irq themselfves, too. Also, only IRQF_SHARED capable IRQ
+ * handlers are allowed.
  */
-
-int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
+int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev,
+                                   irq_handler_t handler)
 {
-       struct pcmcia_socket *s = p_dev->socket;
-       config_t *c;
-       int ret = -EINVAL, irq = p_dev->irq_v;
-       int type = IRQF_SHARED;
+       int ret;
 
-       mutex_lock(&s->ops_mutex);
+       if (!p_dev->irq)
+               return -EINVAL;
 
-       if (!(s->state & SOCKET_PRESENT)) {
-               dev_dbg(&s->dev, "No card present\n");
-               goto out;
-       }
-       c = p_dev->function_config;
-       if (c->state & CONFIG_LOCKED) {
-               dev_dbg(&s->dev, "Configuration is locked\n");
-               goto out;
-       }
+       ret = request_irq(p_dev->irq, handler, IRQF_SHARED,
+                       p_dev->devname, p_dev->priv);
+       if (!ret)
+               p_dev->_irq = 1;
 
-       if (!irq) {
-               dev_dbg(&s->dev, "no IRQ available\n");
-               goto out;
-       }
+       return ret;
+}
+EXPORT_SYMBOL(pcmcia_request_irq);
 
-       if (!(req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)) {
-               req->Attributes |= IRQ_TYPE_DYNAMIC_SHARING;
-               dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver "
-                       "needs updating to supported shared IRQ lines.\n");
-       }
 
-       if (req->Handler) {
-               ret = request_irq(irq, req->Handler, type,
-                                 p_dev->devname, p_dev->priv);
-               if (ret) {
-                       dev_printk(KERN_INFO, &s->dev,
-                               "request_irq() failed\n");
-                       goto out;
-               }
-       }
+/**
+ * pcmcia_request_exclusive_irq() - attempt to request an exclusive IRQ first
+ *
+ * pcmcia_request_exclusive_irq() is a wrapper around request_irq which
+ * attempts first to request an exclusive IRQ. If it fails, it also accepts
+ * a shared IRQ, but prints out a warning. PCMCIA drivers should allow for
+ * IRQ sharing and either use request_irq directly (then they need to call
+ * free_irq themselves, too), or the pcmcia_request_irq() function.
+ */
+int __must_check
+pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, irq_handler_t handler)
+{
+       int ret;
 
-       req->AssignedIRQ = irq;
+       if (!p_dev->irq)
+               return -EINVAL;
 
-       p_dev->_irq = 1;
+       ret = request_irq(p_dev->irq, handler, 0, p_dev->devname, p_dev->priv);
+       if (ret) {
+               ret = pcmcia_request_irq(p_dev, handler);
+               dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: "
+                       "request for exclusive IRQ could not be fulfilled.\n");
+               dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver "
+                       "needs updating to supported shared IRQ lines.\n");
+       }
+       if (ret)
+               dev_printk(KERN_INFO, &p_dev->dev, "request_irq() failed\n");
+       else
+               p_dev->_irq = 1;
 
-       ret = 0;
-out:
-       mutex_unlock(&s->ops_mutex);
        return ret;
-} /* pcmcia_request_irq */
-EXPORT_SYMBOL(pcmcia_request_irq);
+} /* pcmcia_request_exclusive_irq */
+EXPORT_SYMBOL(pcmcia_request_exclusive_irq);
 
 
 #ifdef CONFIG_PCMCIA_PROBE
                                  p_dev);
                if (!ret) {
                        free_irq(irq, p_dev);
-                       p_dev->irq_v = s->pcmcia_irq = irq;
+                       p_dev->irq = s->pcmcia_irq = irq;
                        pcmcia_used_irq[irq]++;
                        break;
                }
 {
        struct pcmcia_socket *s = p_dev->socket;
 
-       if (p_dev->irq_v)
+       if (p_dev->irq)
                return 0;
 
        /* already assigned? */
        if (s->pcmcia_irq) {
-               p_dev->irq_v = s->pcmcia_irq;
+               p_dev->irq = s->pcmcia_irq;
                return 0;
        }
 
 
        /* but use the PCI irq otherwise */
        if (s->pci_irq) {
-               p_dev->irq_v = s->pcmcia_irq = s->pci_irq;
+               p_dev->irq = s->pcmcia_irq = s->pci_irq;
                return 0;
        }
 
 {
        pcmcia_release_configuration(p_dev);
        pcmcia_release_io(p_dev, &p_dev->io);
-       pcmcia_release_irq(p_dev, &p_dev->irq);
+       if (p_dev->_irq)
+               free_irq(p_dev->irq, p_dev->priv);
        if (p_dev->win)
                pcmcia_release_window(p_dev, p_dev->win);
 }
 
     link->io.NumPorts1 = 0x20;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 10;
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.Present = PRESENT_OPTION;
     if (ret)
            goto failed;
 
-    ret = pcmcia_request_irq(link, &link->irq);
-    if (ret)
+    if (!link->irq)
            goto failed;
 
     ret = pcmcia_request_configuration(link, &link->conf);
     memset(&s, 0, sizeof(s));
     s.conf        = "PCMCIA setup";
     s.io_port     = link->io.BasePort1;
-    s.irq         = link->irq.AssignedIRQ;
+    s.irq         = link->irq;
     s.scsiid      = host_id;
     s.reconnect   = reconnect;
     s.parity      = parity;
 
        link->io.NumPorts1 = 0x10;
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
        link->io.IOAddrLines = 10;
-       link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
        link->conf.Present = PRESENT_OPTION;
     if (ret)
            goto failed;
 
-    ret = pcmcia_request_irq(link, &link->irq);
-    if (ret)
+    if (!link->irq)
            goto failed;
     ret = pcmcia_request_configuration(link, &link->conf);
     if (ret)
     release_region(link->io.BasePort1, link->io.NumPorts1);
 
     /* Set configuration options for the fdomain driver */
-    sprintf(str, "%d,%d", link->io.BasePort1, link->irq.AssignedIRQ);
+    sprintf(str, "%d,%d", link->io.BasePort1, link->irq);
     fdomain_setup(str);
 
     host = __fdomain_16x0_detect(&fdomain_driver_template);
 
        link->io.Attributes1     = IO_DATA_PATH_WIDTH_AUTO;
        link->io.IOAddrLines     = 10;  /* not used */
 
-       /* Interrupt setup */
-       link->irq.Attributes     = IRQ_TYPE_EXCLUSIVE;
-
-       /* Interrupt handler */
-       link->irq.Handler        = &nspintr;
-       link->irq.Attributes     |= IRQF_SHARED;
-
        /* General socket configuration */
        link->conf.Attributes    = CONF_ENABLE_IRQ;
        link->conf.IntType       = INT_MEMORY_AND_IO;
                }
 
                /* Do we need to allocate an interrupt? */
-               if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
-                       p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
                /* IO window settings */
                p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
        if (ret)
                goto cs_failed;
 
-       if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               if (pcmcia_request_irq(link, &link->irq))
-                       goto cs_failed;
-       }
+       if (pcmcia_request_irq(link, nspintr))
+               goto cs_failed;
 
        ret = pcmcia_request_configuration(link, &link->conf);
        if (ret)
        /* Set port and IRQ */
        data->BaseAddress = link->io.BasePort1;
        data->NumAddress  = link->io.NumPorts1;
-       data->IrqNumber   = link->irq.AssignedIRQ;
+       data->IrqNumber   = link->irq;
 
        nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
                data->BaseAddress, data->NumAddress, data->IrqNumber);
                printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
        }
        if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               printk(", irq %d", link->irq.AssignedIRQ);
+               printk(", irq %d", link->irq);
        }
        if (link->io.NumPorts1) {
                printk(", io 0x%04x-0x%04x", link->io.BasePort1,
 
        link->io.NumPorts1 = 16;
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
        link->io.IOAddrLines = 10;
-       link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
        link->conf.Present = PRESENT_OPTION;
        if (ret)
                goto failed;
 
-       ret = pcmcia_request_irq(link, &link->irq);
-       if (ret)
+       if (!link->irq)
                goto failed;
 
        ret = pcmcia_request_configuration(link, &link->conf);
        /* The KXL-810AN has a bigger IO port window */
        if (link->io.NumPorts1 == 32)
                host = qlogic_detect(&qlogicfas_driver_template, link,
-                       link->io.BasePort1 + 16, link->irq.AssignedIRQ);
+                       link->io.BasePort1 + 16, link->irq);
        else
                host = qlogic_detect(&qlogicfas_driver_template, link,
-                       link->io.BasePort1, link->irq.AssignedIRQ);
+                       link->io.BasePort1, link->irq);
        
        if (!host) {
                printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name);
 
        scsi_remove_host(info->host);
 
-       free_irq(link->irq.AssignedIRQ, info->host);
+       free_irq(link->irq, info->host);
        pcmcia_disable_device(link);
 
        scsi_host_put(info->host);
 
        if (ret)
                goto failed;
 
-       ret = pcmcia_request_irq(link, &link->irq);
-       if (ret)
+       if (!link->irq)
                goto failed;
 
        ret = pcmcia_request_configuration(link, &link->conf);
        *       0x320, 0x330, 0x340, 0x350
        */
        port_base = link->io.BasePort1;
-       irq_level = link->irq.AssignedIRQ;
+       irq_level = link->irq;
 
        DEB(printk("SYM53C500: port_base=0x%x, irq=%d, fast_pio=%d\n",
            port_base, irq_level, USE_FAST_PIO);)
        link->io.NumPorts1 = 16;
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
        link->io.IOAddrLines = 10;
-       link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
 
 
 
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
        link->io.NumPorts1 = 8;
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        if (do_sound) {
                link->conf.Attributes |= CONF_ENABLE_SPKR;
                }
                if (info->slave) {
                        return setup_serial(link, info, port,
-                                           link->irq.AssignedIRQ);
+                                           link->irq);
                }
        }
 
        return -1;
 
 found_port:
-       i = pcmcia_request_irq(link, &link->irq);
-       if (i != 0)
-               link->irq.AssignedIRQ = 0;
-
        if (info->multi && (info->manfid == MANFID_3COM))
                link->conf.ConfigIndex &= ~(0x08);
 
        i = pcmcia_request_configuration(link, &link->conf);
        if (i != 0)
                return -1;
-       return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
+       return setup_serial(link, info, link->io.BasePort1, link->irq);
 }
 
 static int multi_config_check(struct pcmcia_device *p_dev,
                }
        }
 
-       i = pcmcia_request_irq(link, &link->irq);
-       if (i != 0) {
-               /* FIXME: comment does not fit, error handling does not fit */
-               printk(KERN_NOTICE
-                      "serial_cs: no usable port range found, giving up\n");
-               link->irq.AssignedIRQ = 0;
-       }
+       if (!link->irq)
+               dev_warn(&link->dev,
+                       "serial_cs: no usable IRQ found, continuing...\n");
 
        /*
         * Apply any configuration quirks.
                if (link->conf.ConfigIndex == 1 ||
                    link->conf.ConfigIndex == 3) {
                        err = setup_serial(link, info, base2,
-                                       link->irq.AssignedIRQ);
+                                       link->irq);
                        base2 = link->io.BasePort1;
                } else {
                        err = setup_serial(link, info, link->io.BasePort1,
-                                       link->irq.AssignedIRQ);
+                                       link->irq);
                }
                info->c950ctrl = base2;
 
                return 0;
        }
 
-       setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
+       setup_serial(link, info, link->io.BasePort1, link->irq);
        for (i = 0; i < info->multi - 1; i++)
                setup_serial(link, info, base2 + (8 * i),
-                               link->irq.AssignedIRQ);
+                               link->irq);
        return 0;
 }
 
 
                        break;
                case SSB_BUSTYPE_PCMCIA:
 #ifdef CONFIG_SSB_PCMCIAHOST
-                       sdev->irq = bus->host_pcmcia->irq.AssignedIRQ;
+                       sdev->irq = bus->host_pcmcia->irq;
                        dev->parent = &bus->host_pcmcia->dev;
 #endif
                        break;
 
        }
        printk("\n");
 
-       ret = request_irq(link->irq.AssignedIRQ, das16cs_interrupt,
+       ret = request_irq(link->irq, das16cs_interrupt,
                          IRQF_SHARED, "cb_das16_cs", dev);
        if (ret < 0) {
                return ret;
        }
-       dev->irq = link->irq.AssignedIRQ;
+       dev->irq = link->irq;
        printk("irq=%u ", dev->irq);
 
        dev->board_ptr = das16cs_probe(dev, link);
        link->priv = local;
 
        /* Initialize the pcmcia_device structure */
-       /* Interrupt setup */
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       link->irq.Handler = NULL;
-
        link->conf.Attributes = 0;
        link->conf.IntType = INT_MEMORY_AND_IO;
 
                return -EINVAL;
 
        /* Do we need to allocate an interrupt? */
-       if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
-               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+       p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
        p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
                goto failed;
        }
 
-       /*
-          Allocate an interrupt line.  Note that this does not assign a
-          handler to the interrupt, unless the 'Handler' member of the
-          irq structure is initialized.
-        */
-       if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               ret = pcmcia_request_irq(link, &link->irq);
-               if (ret)
-                       goto failed;
-       }
+       if (!link->irq)
+               goto failed;
+
        /*
           This actually configures the PCMCIA socket -- setting up
           the I/O windows and the interrupt mapping, and putting the
        printk(KERN_INFO "%s: index 0x%02x",
               dev->node.dev_name, link->conf.ConfigIndex);
        if (link->conf.Attributes & CONF_ENABLE_IRQ)
-               printk(", irq %u", link->irq.AssignedIRQ);
+               printk(", irq %u", link->irq);
        if (link->io.NumPorts1)
                printk(", io 0x%04x-0x%04x", link->io.BasePort1,
                       link->io.BasePort1 + link->io.NumPorts1 - 1);
 
        local->link = link;
        link->priv = local;
 
-       /* Interrupt setup */
-       link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-       link->irq.Handler = NULL;
-
        /*
           General socket configuration defaults can go here.  In this
           client, we assume very little, and rely on the CIS for almost
                return -ENODEV;
 
        /* Do we need to allocate an interrupt? */
-       if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
-               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+       p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
        p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
                goto failed;
        }
 
-       if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               ret = pcmcia_request_irq(link, &link->irq);
-               if (ret)
-                       goto failed;
-       }
+       if (!link->irq)
+               goto failed;
 
        /*
           This actually configures the PCMCIA socket -- setting up
        printk(KERN_INFO "%s: index 0x%02x",
               dev->node.dev_name, link->conf.ConfigIndex);
        if (link->conf.Attributes & CONF_ENABLE_IRQ)
-               printk(", irq %u", link->irq.AssignedIRQ);
+               printk(", irq %u", link->irq);
        if (link->io.NumPorts1)
                printk(", io 0x%04x-0x%04x", link->io.BasePort1,
                       link->io.BasePort1 + link->io.NumPorts1 - 1);
 
                        return -EIO;
                iobase = link->io.BasePort1;
 #ifdef incomplete
-               irq = link->irq.AssignedIRQ;
+               irq = link->irq;
 #endif
                break;
        default:
        local->link = link;
        link->priv = local;
 
-       /* Interrupt setup */
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       link->irq.Handler = NULL;
-
        /*
           General socket configuration defaults can go here.  In this
           client, we assume very little, and rely on the CIS for almost
        }
 
        /* Do we need to allocate an interrupt? */
-       if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
-               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+       p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
        p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
                goto failed;
        }
 
-       /*
-          Allocate an interrupt line.  Note that this does not assign a
-          handler to the interrupt, unless the 'Handler' member of the
-          irq structure is initialized.
-        */
-       if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               ret = pcmcia_request_irq(link, &link->irq);
-               if (ret)
-                       goto failed;
-       }
+       if (!link->irq)
+               goto failed;
 
        /*
           This actually configures the PCMCIA socket -- setting up
        printk(KERN_INFO "%s: index 0x%02x",
               dev->node.dev_name, link->conf.ConfigIndex);
        if (link->conf.Attributes & CONF_ENABLE_IRQ)
-               printk(", irq %d", link->irq.AssignedIRQ);
+               printk(", irq %d", link->irq);
        if (link->io.NumPorts1)
                printk(", io 0x%04x-0x%04x", link->io.BasePort1,
                       link->io.BasePort1 + link->io.NumPorts1 - 1);
 
                        return -EIO;
                iobase = link->io.BasePort1;
 #ifdef incomplete
-               irq = link->irq.AssignedIRQ;
+               irq = link->irq;
 #endif
                break;
        default:
        local->link = link;
        link->priv = local;
 
-       /* Interrupt setup */
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       link->irq.Handler = NULL;
-
        /*
           General socket configuration defaults can go here.  In this
           client, we assume very little, and rely on the CIS for almost
        }
 
        /* Do we need to allocate an interrupt? */
-       if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
-               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+       p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
        p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
                goto failed;
        }
 
-       /*
-          Allocate an interrupt line.  Note that this does not assign a
-          handler to the interrupt, unless the 'Handler' member of the
-          irq structure is initialized.
-        */
-       if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               ret = pcmcia_request_irq(link, &link->irq);
-               if (ret)
-                       goto failed;
-       }
+       if (!link->irq)
+               goto failed;
 
        /*
           This actually configures the PCMCIA socket -- setting up
        printk(KERN_INFO "%s: index 0x%02x",
               dev->node.dev_name, link->conf.ConfigIndex);
        if (link->conf.Attributes & CONF_ENABLE_IRQ)
-               printk(", irq %d", link->irq.AssignedIRQ);
+               printk(", irq %d", link->irq);
        if (link->io.NumPorts1)
                printk(", io 0x%04x-0x%04x", link->io.BasePort1,
                       link->io.BasePort1 + link->io.NumPorts1 - 1);
 
                if (!link)
                        return -EIO;
                iobase = link->io.BasePort1;
-               irq = link->irq.AssignedIRQ;
+               irq = link->irq;
                break;
        default:
                printk("bug! couldn't determine board type\n");
        local->link = link;
        link->priv = local;
 
-       /* Interrupt setup */
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       link->irq.Handler = NULL;
-
        /*
           General socket configuration defaults can go here.  In this
           client, we assume very little, and rely on the CIS for almost
        }
 
        /* Do we need to allocate an interrupt? */
-       if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
-               p_dev->conf.Attributes |=
-                       (CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ);
+       p_dev->conf.Attributes |= CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ;
 
        /* IO window settings */
        p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
                goto failed;
        }
 
-       /*
-          Allocate an interrupt line.  Note that this does not assign a
-          handler to the interrupt, unless the 'Handler' member of the
-          irq structure is initialized.
-        */
-       if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               ret = pcmcia_request_irq(link, &link->irq);
-               if (ret)
-                       goto failed;
-       }
+       if (!link->irq)
+               goto failed;
 
        /*
           This actually configures the PCMCIA socket -- setting up
        printk(KERN_INFO "%s: index 0x%02x",
               dev->node.dev_name, link->conf.ConfigIndex);
        if (link->conf.Attributes & CONF_ENABLE_IRQ)
-               printk(", irq %d", link->irq.AssignedIRQ);
+               printk(", irq %d", link->irq);
        if (link->io.NumPorts1)
                printk(", io 0x%04x-0x%04x", link->io.BasePort1,
                       link->io.BasePort1 + link->io.NumPorts1 - 1);
 
 {
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
        link->io.NumPorts1 = 16;
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
 
                return;
        }
 
-       ret = pcmcia_request_irq(link, &link->irq);
-       if (ret) {
-               printk("pcmcia_request_irq() returned error: %i\n", ret);
-       }
+       if (!link->irq)
+               dev_info(&link->dev, "no IRQ available\n");
 
        ret = pcmcia_request_configuration(link, &link->conf);
 
        dev->driver = &driver_ni_mio_cs;
        dev->iobase = link->io.BasePort1;
 
-       irq = link->irq.AssignedIRQ;
+       irq = link->irq;
 
        printk("comedi%d: %s: DAQCard: io 0x%04lx, irq %u, ",
               dev->minor, dev->driver->driver_name, dev->iobase, irq);
 
        local->link = link;
        link->priv = local;
 
-       /* Interrupt setup */
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       link->irq.Handler = daqp_interrupt;
-
        /*
           General socket configuration defaults can go here.  In this
           client, we assume very little, and rely on the CIS for almost
                return -ENODEV;
 
        /* Do we need to allocate an interrupt? */
-       if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
-               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+       p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
        p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
                goto failed;
        }
 
-       /*
-          Allocate an interrupt line.  Note that this does not assign a
-          handler to the interrupt, unless the 'Handler' member of the
-          irq structure is initialized.
-        */
-       if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               ret = pcmcia_request_irq(link, &link->irq);
-               if (ret)
-                       goto failed;
-       }
+       ret = pcmcia_request_irq(link, daqp_interrupt);
+       if (ret)
+               goto failed;
 
        /*
           This actually configures the PCMCIA socket -- setting up
        printk(KERN_INFO "%s: index 0x%02x",
               dev->node.dev_name, link->conf.ConfigIndex);
        if (link->conf.Attributes & CONF_ENABLE_IRQ)
-               printk(", irq %u", link->irq.AssignedIRQ);
+               printk(", irq %u", link->irq);
        if (link->io.NumPorts1)
                printk(", io 0x%04x-0x%04x", link->io.BasePort1,
                       link->io.BasePort1 + link->io.NumPorts1 - 1);
 
        link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; */
     link->io.IOAddrLines = 5;
     
-    /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.Handler = &netwave_interrupt;
-    
     /* General socket configuration */
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
      *  Now allocate an interrupt line.  Note that this does not
      *  actually assign a handler to the interrupt.
      */
-    ret = pcmcia_request_irq(link, &link->irq);
+    ret = pcmcia_request_irq(link, netwave_interrupt);
     if (ret)
            goto failed;
 
     ramBase = ioremap(req.Base, 0x8000);
     priv->ramBase = ramBase;
 
-    dev->irq = link->irq.AssignedIRQ;
+    dev->irq = link->irq;
     dev->base_addr = link->io.BasePort1;
     SET_NETDEV_DEV(dev, &link->dev);
 
 
       if (i != 0)
          break;
 
-      /*
-       * Now allocate an interrupt line.  Note that this does not
-       * actually assign a handler to the interrupt.
-       */
-      i = pcmcia_request_irq(link, &link->irq);
-      if (i != 0)
+      i = pcmcia_request_interrupt(link, wavelan_interrupt);
+      if (!i)
          break;
 
       /*
          break;
 
       /* Feed device with this info... */
-      dev->irq = link->irq.AssignedIRQ;
+      dev->irq = link->irq;
       dev->base_addr = link->io.BasePort1;
       netif_start_queue(dev);
 
   p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
   p_dev->io.IOAddrLines = 3;
 
-  /* Interrupt setup */
-  p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-  p_dev->irq.Handler = wavelan_interrupt;
-
   /* General socket configuration */
   p_dev->conf.Attributes = CONF_ENABLE_IRQ;
   p_dev->conf.IntType = INT_MEMORY_AND_IO;
 
   ret = wv_hw_config(dev);
   if (ret) {
-         dev->irq = 0;
          pcmcia_disable_device(p_dev);
          return ret;
   }
 
     link->io.NumPorts1      = HCF_NUM_IO_PORTS;
     link->io.Attributes1    = IO_DATA_PATH_WIDTH_16;
     link->io.IOAddrLines    = 6;
-    link->irq.Attributes    = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1      = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-    link->irq.Handler       = &wl_isr;
     link->conf.Attributes   = CONF_ENABLE_IRQ;
     link->conf.IntType      = INT_MEMORY_AND_IO;
     link->conf.ConfigIndex  = 5;
     link->conf.Present      = PRESENT_OPTION;
 
-    link->priv = link->irq.Instance = dev;
+    link->priv = dev;
     lp = wl_priv(dev);
     lp->link = link;
 
     link->conf.Attributes |= CONF_ENABLE_IRQ;
 
     CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, wl_isr));
     CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
 
 
-    dev->irq        = link->irq.AssignedIRQ;
+    dev->irq        = link->irq;
     dev->base_addr  = link->io.BasePort1;
 
     SET_NETDEV_DEV(dev, &handle_to_dev(link));
 
                        dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
 
        /* we need an interrupt */
-       if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
-               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+       p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
 
        /* IO window settings */
        p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
        /* require an IRQ and two registers */
        if (!link->io.NumPorts1 || link->io.NumPorts1 < 2)
                goto failed;
-       if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               ret = pcmcia_request_irq(link, &link->irq);
-               if (ret)
-                       goto failed;
-       } else
+
+       if (!link->irq)
                goto failed;
 
        ret = pcmcia_request_configuration(link, &link->conf);
               dev->node.dev_name, link->conf.ConfigIndex);
        if (link->conf.Vpp)
                printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
-       printk(", irq %d", link->irq.AssignedIRQ);
+       printk(", irq %d", link->irq);
        printk(", io 0x%04x-0x%04x", link->io.BasePort1,
               link->io.BasePort1+link->io.NumPorts1-1);
        printk("\n");
 
-       if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ)
+       if (sl811_hc_init(parent, link->io.BasePort1, link->irq)
                        < 0) {
 failed:
                printk(KERN_WARNING "sl811_cs_config failed\n");
        local->p_dev = link;
        link->priv = local;
 
-       /* Initialize */
-       link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-       link->irq.Handler = NULL;
-
        link->conf.Attributes = 0;
        link->conf.IntType = INT_MEMORY_AND_IO;
 
 
 #define IO_DATA_PATH_WIDTH_16  0x08
 #define IO_DATA_PATH_WIDTH_AUTO        0x10
 
-/* For RequestIRQ and ReleaseIRQ */
-typedef struct irq_req_t {
-       u_int           Attributes;
-       u_int           AssignedIRQ;
-       irq_handler_t   Handler;
-} irq_req_t;
-
 /* Attributes for RequestIRQ and ReleaseIRQ */
 #define IRQ_TYPE                       0x03
 #define IRQ_TYPE_EXCLUSIVE             0x00
 
        dev_node_t              *dev_node;
        u_int                   open;
        io_req_t                io;
-       irq_req_t               irq;
        config_req_t            conf;
        window_handle_t         win;
 
        /* device setup */
-       unsigned int            irq_v; /* do not use directly yet */
+       unsigned int            irq;
 
        /* Is the device suspended? */
        u16                     suspended:1;
 
 /* device configuration */
 int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req);
-int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req);
+
+int __must_check __deprecated
+pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev,
+                               irq_handler_t handler);
+int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev,
+                               irq_handler_t handler);
+
 int pcmcia_request_configuration(struct pcmcia_device *p_dev,
                                 config_req_t *req);
 
 
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
        link->io.NumPorts1 = 16;
 
-       link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-       /* FIXME: This driver should be updated to allow for dynamic IRQ sharing */
-       /* link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; */
-
-       link->irq.Handler = pdacf_interrupt;
        link->conf.Attributes = CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
        link->conf.ConfigIndex = 1;
        if (ret)
                goto failed;
 
-       ret = pcmcia_request_irq(link, &link->irq);
+       ret = pcmcia_request_exclusive_irq(link, pdacf_interrupt);
        if (ret)
                goto failed;
 
        if (ret)
                goto failed;
 
-       if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq.AssignedIRQ) < 0)
+       if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq) < 0)
                goto failed;
 
        link->dev_node = &pdacf->node;
 
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
        link->io.NumPorts1 = 16;
 
-       link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-
-       link->irq.Handler = &snd_vx_irq_handler;
-
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
        link->conf.ConfigIndex = 1;
        if (ret)
                goto failed;
 
-       ret = pcmcia_request_irq(link, &link->irq);
+       ret = pcmcia_request_exclusive_irq(link, snd_vx_irq_handler);
        if (ret)
                goto failed;
 
        chip->dev = &link->dev;
        snd_card_set_dev(chip->card, chip->dev);
 
-       if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0)
+       if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq) < 0)
                goto failed;
 
        link->dev_node = &vxp->node;