Part five of simplifying/fixing handling of the main_irq_mask register to resolve unexpected interrupt issues observed in 2.6.26-rc*. Keep a cached copy of the main_irq_mask so that we don't have to stall the CPU to read it on every pass through mv_interrupt. This significantly speeds up interrupt handling, both for sata_mv, and for any other driver/device sharing the same PCI IRQ line. Signed-off-by: Mark Lord <mlord@xxxxxxxxx> --- old/drivers/ata/sata_mv.c 2008-05-16 16:06:23.000000000 -0400 +++ linux/drivers/ata/sata_mv.c 2008-05-16 16:02:55.000000000 -0400 @@ -458,6 +458,7 @@ struct mv_host_priv { u32 hp_flags; + u32 main_irq_mask; struct mv_port_signal signal[8]; const struct mv_hw_ops *ops; int n_ports; @@ -843,10 +844,12 @@ struct mv_host_priv *hpriv = host->private_data; u32 old_mask, new_mask; - old_mask = readl(hpriv->main_irq_mask_addr); + old_mask = hpriv->main_irq_mask; new_mask = (old_mask & ~disable_bits) | enable_bits; - if (new_mask != old_mask) + if (new_mask != old_mask) { + hpriv->main_irq_mask = new_mask; writelfl(new_mask, hpriv->main_irq_mask_addr); + } } static void mv_enable_port_irqs(struct ata_port *ap, @@ -2200,12 +2203,11 @@ struct ata_host *host = dev_instance; struct mv_host_priv *hpriv = host->private_data; unsigned int handled = 0; - u32 main_irq_cause, main_irq_mask, pending_irqs; + u32 main_irq_cause, pending_irqs; spin_lock(&host->lock); main_irq_cause = readl(hpriv->main_irq_cause_addr); - main_irq_mask = readl(hpriv->main_irq_mask_addr); - pending_irqs = main_irq_cause & main_irq_mask; + pending_irqs = main_irq_cause & hpriv->main_irq_mask; /* * Deal with cases where we either have nothing pending, or have read * a bogus register value which can indicate HW removal or PCI fault. -- To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html