if(line->driver->read_irq == current_irq)
                free_irq_later(line->driver->read_irq, tty);
        else {
-               free_irq_by_irq_and_dev(line->driver->read_irq, tty);
                free_irq(line->driver->read_irq, tty);
        }
 
        if(line->driver->write_irq == current_irq)
                free_irq_later(line->driver->write_irq, tty);
        else {
-               free_irq_by_irq_and_dev(line->driver->write_irq, tty);
                free_irq(line->driver->write_irq, tty);
        }
 
 
        netif_stop_queue(dev);
        spin_lock(&lp->lock);
 
-       free_irq_by_irq_and_dev(dev->irq, dev);
        free_irq(dev->irq, dev);
        if(lp->close != NULL)
                (*lp->close)(lp->fd, &lp->user);
 
                 * connection.  Then we loop here throwing out failed 
                 * connections until a good one is found.
                 */
-               free_irq_by_irq_and_dev(TELNETD_IRQ, conn);
                free_irq(TELNETD_IRQ, conn);
 
                if(conn->fd >= 0) break;
 
         * isn't set) this will hang... */
        wait_for_completion(&data->ready);
 
-       free_irq_by_irq_and_dev(XTERM_IRQ, data);
        free_irq(XTERM_IRQ, data);
 
        ret = data->new_fd;
 
        spin_unlock_irqrestore(&irq_spinlock, flags);
 }
 
-/*  presently hw_interrupt_type must define (startup || enable) &&
- *  disable && end */
+/* hw_interrupt_type must define (startup || enable) &&
+ * (shutdown || disable) && end */
 static void dummy(unsigned int irq)
 {
 }
 
-static struct hw_interrupt_type SIGIO_irq_type = {
+/* This is used for everything else than the timer. */
+static struct hw_interrupt_type normal_irq_type = {
        .typename = "SIGIO",
+       .release = free_irq_by_irq_and_dev,
        .disable = dummy,
        .enable = dummy,
        .ack = dummy,
 
 static struct hw_interrupt_type SIGVTALRM_irq_type = {
        .typename = "SIGVTALRM",
+       .release = free_irq_by_irq_and_dev,
        .shutdown = dummy, /* never called */
        .disable = dummy,
        .enable = dummy,
                irq_desc[i].status = IRQ_DISABLED;
                irq_desc[i].action = NULL;
                irq_desc[i].depth = 1;
-               irq_desc[i].handler = &SIGIO_irq_type;
+               irq_desc[i].handler = &normal_irq_type;
                enable_irq(i);
        }
 }
 
                                next = irq_fd->next;
                                if(irq_fd->freed){
                                        free_irq(irq_fd->irq, irq_fd->id);
-                                       free_irq_by_irq_and_dev(irq_fd->irq,
-                                                               irq_fd->id);
                                }
                        }
                }
 
        void (*ack)(unsigned int irq);
        void (*end)(unsigned int irq);
        void (*set_affinity)(unsigned int irq, cpumask_t dest);
+       void (*release)(unsigned int irq, void *dev_id);
 };
 
 typedef struct hw_interrupt_type  hw_irq_controller;
 
 
                        /* Found it - now remove it from the list of entries */
                        *pp = action->next;
+
+                       if (desc->handler->release)
+                               desc->handler->release(irq, dev_id);
+
                        if (!desc->action) {
                                desc->status |= IRQ_DISABLED;
                                if (desc->handler->shutdown)