static void uic_unmask_irq(unsigned int virq)
 {
+       struct irq_desc *desc = get_irq_desc(virq);
        struct uic *uic = get_irq_chip_data(virq);
        unsigned int src = uic_irq_to_hw(virq);
        unsigned long flags;
-       u32 er;
+       u32 er, sr;
 
+       sr = 1 << (31-src);
        spin_lock_irqsave(&uic->lock, flags);
+       /* ack level-triggered interrupts here */
+       if (desc->status & IRQ_LEVEL)
+               mtdcr(uic->dcrbase + UIC_SR, sr);
        er = mfdcr(uic->dcrbase + UIC_ER);
-       er |= 1 << (31 - src);
+       er |= sr;
        mtdcr(uic->dcrbase + UIC_ER, er);
        spin_unlock_irqrestore(&uic->lock, flags);
 }
 
 static void uic_mask_ack_irq(unsigned int virq)
 {
+       struct irq_desc *desc = get_irq_desc(virq);
        struct uic *uic = get_irq_chip_data(virq);
        unsigned int src = uic_irq_to_hw(virq);
        unsigned long flags;
        er = mfdcr(uic->dcrbase + UIC_ER);
        er &= ~sr;
        mtdcr(uic->dcrbase + UIC_ER, er);
-       mtdcr(uic->dcrbase + UIC_SR, sr);
+       /* On the UIC, acking (i.e. clearing the SR bit)
+        * a level irq will have no effect if the interrupt
+        * is still asserted by the device, even if
+        * the interrupt is already masked. Therefore
+        * we only ack the egde interrupts here, while
+        * level interrupts are ack'ed after the actual
+        * isr call in the uic_unmask_irq()
+        */
+       if (!(desc->status & IRQ_LEVEL))
+               mtdcr(uic->dcrbase + UIC_SR, sr);
        spin_unlock_irqrestore(&uic->lock, flags);
 }
 
        .set_type       = uic_set_irq_type,
 };
 
-/**
- *     handle_uic_irq - irq flow handler for UIC
- *     @irq:   the interrupt number
- *     @desc:  the interrupt description structure for this irq
- *
- * This is modified version of the generic handle_level_irq() suitable
- * for the UIC.  On the UIC, acking (i.e. clearing the SR bit) a level
- * irq will have no effect if the interrupt is still asserted by the
- * device, even if the interrupt is already masked.  Therefore, unlike
- * the standard handle_level_irq(), we must ack the interrupt *after*
- * invoking the ISR (which should have de-asserted the interrupt in
- * the external source).  For edge interrupts we ack at the beginning
- * instead of the end, to keep the window in which we can miss an
- * interrupt as small as possible.
- */
-void fastcall handle_uic_irq(unsigned int irq, struct irq_desc *desc)
-{
-       unsigned int cpu = smp_processor_id();
-       struct irqaction *action;
-       irqreturn_t action_ret;
-
-       spin_lock(&desc->lock);
-       if (desc->status & IRQ_LEVEL)
-               desc->chip->mask(irq);
-       else
-               desc->chip->mask_ack(irq);
-
-       if (unlikely(desc->status & IRQ_INPROGRESS))
-               goto out_unlock;
-       desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
-       kstat_cpu(cpu).irqs[irq]++;
-
-       /*
-        * If its disabled or no action available
-        * keep it masked and get out of here
-        */
-       action = desc->action;
-       if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
-               desc->status |= IRQ_PENDING;
-               goto out_unlock;
-       }
-
-       desc->status |= IRQ_INPROGRESS;
-       desc->status &= ~IRQ_PENDING;
-       spin_unlock(&desc->lock);
-
-       action_ret = handle_IRQ_event(irq, action);
-
-       spin_lock(&desc->lock);
-       desc->status &= ~IRQ_INPROGRESS;
-       if (desc->status & IRQ_LEVEL)
-               desc->chip->ack(irq);
-       if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
-               desc->chip->unmask(irq);
-out_unlock:
-       spin_unlock(&desc->lock);
-}
-
 static int uic_host_map(struct irq_host *h, unsigned int virq,
                        irq_hw_number_t hw)
 {
        set_irq_chip_data(virq, uic);
        /* Despite the name, handle_level_irq() works for both level
         * and edge irqs on UIC.  FIXME: check this is correct */
-       set_irq_chip_and_handler(virq, &uic_irq_chip, handle_uic_irq);
+       set_irq_chip_and_handler(virq, &uic_irq_chip, handle_level_irq);
 
        /* Set default irq type */
        set_irq_type(virq, IRQ_TYPE_NONE);