diff options
author | Mark Lord <liml@rtr.ca> | 2008-05-17 13:37:07 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-05-19 17:30:05 -0400 |
commit | a44253d24a97ec3efe601267274a5fb64d8696c1 (patch) | |
tree | 313d0c34eaff675a2924576e355a114d941fdeff /drivers/ata/sata_mv.c | |
parent | 88e675e193159b9891c1c576de4348eaf490f5d0 (diff) |
sata_mv: disregard masked irqs
Part four of simplifying/fixing handling of the main_irq_mask register
to resolve unexpected interrupt issues observed in 2.6.26-rc*.
Ignore masked IRQs in mv_interrupt().
This prevents "unexpected device interrupt while idle" messages.
Signed-off-by: Mark Lord <mlord@pobox.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r-- | drivers/ata/sata_mv.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 47dae7a2fbf4..eb7f3dafb502 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -2200,20 +2200,21 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) | |||
2200 | struct ata_host *host = dev_instance; | 2200 | struct ata_host *host = dev_instance; |
2201 | struct mv_host_priv *hpriv = host->private_data; | 2201 | struct mv_host_priv *hpriv = host->private_data; |
2202 | unsigned int handled = 0; | 2202 | unsigned int handled = 0; |
2203 | u32 main_irq_cause, main_irq_mask; | 2203 | u32 main_irq_cause, main_irq_mask, pending_irqs; |
2204 | 2204 | ||
2205 | spin_lock(&host->lock); | 2205 | spin_lock(&host->lock); |
2206 | main_irq_cause = readl(hpriv->main_irq_cause_addr); | 2206 | main_irq_cause = readl(hpriv->main_irq_cause_addr); |
2207 | main_irq_mask = readl(hpriv->main_irq_mask_addr); | 2207 | main_irq_mask = readl(hpriv->main_irq_mask_addr); |
2208 | pending_irqs = main_irq_cause & main_irq_mask; | ||
2208 | /* | 2209 | /* |
2209 | * Deal with cases where we either have nothing pending, or have read | 2210 | * Deal with cases where we either have nothing pending, or have read |
2210 | * a bogus register value which can indicate HW removal or PCI fault. | 2211 | * a bogus register value which can indicate HW removal or PCI fault. |
2211 | */ | 2212 | */ |
2212 | if ((main_irq_cause & main_irq_mask) && (main_irq_cause != 0xffffffffU)) { | 2213 | if (pending_irqs && main_irq_cause != 0xffffffffU) { |
2213 | if (unlikely((main_irq_cause & PCI_ERR) && HAS_PCI(host))) | 2214 | if (unlikely((pending_irqs & PCI_ERR) && HAS_PCI(host))) |
2214 | handled = mv_pci_error(host, hpriv->base); | 2215 | handled = mv_pci_error(host, hpriv->base); |
2215 | else | 2216 | else |
2216 | handled = mv_host_intr(host, main_irq_cause); | 2217 | handled = mv_host_intr(host, pending_irqs); |
2217 | } | 2218 | } |
2218 | spin_unlock(&host->lock); | 2219 | spin_unlock(&host->lock); |
2219 | return IRQ_RETVAL(handled); | 2220 | return IRQ_RETVAL(handled); |