diff options
author | Mark Lord <liml@rtr.ca> | 2009-01-21 10:31:29 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2009-01-26 06:41:57 -0500 |
commit | 6d3c30efc964fadf2e6270e6fceaeca3ce50027a (patch) | |
tree | 555b60363b953a35836adf61ca0b5a4ca71e64a0 /drivers/ata/sata_mv.c | |
parent | 5d0fb2e730e2085021cf5c8b6d14983e92aea75b (diff) |
sata_mv: msi masking fix (v2)
Enable reliable use of Message-Signaled Interrupts (MSI) in sata_mv
by masking further chip interrupts within the main interrupt handler.
Based upon a suggestion by Grant Grundler.
MSI is working reliably in all of my test systems here now.
Signed-off-by: Mark Lord <mlord@pobox.com>
Reviewed-by: Grant Grundler <grundler@google.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 | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 9e9fb9594781..f2d8a020ea53 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -33,8 +33,6 @@ | |||
33 | * | 33 | * |
34 | * --> ATAPI support (Marvell claims the 60xx/70xx chips can do it). | 34 | * --> ATAPI support (Marvell claims the 60xx/70xx chips can do it). |
35 | * | 35 | * |
36 | * --> Investigate problems with PCI Message Signalled Interrupts (MSI). | ||
37 | * | ||
38 | * --> Develop a low-power-consumption strategy, and implement it. | 36 | * --> Develop a low-power-consumption strategy, and implement it. |
39 | * | 37 | * |
40 | * --> [Experiment, low priority] Investigate interrupt coalescing. | 38 | * --> [Experiment, low priority] Investigate interrupt coalescing. |
@@ -70,7 +68,7 @@ | |||
70 | #include <linux/libata.h> | 68 | #include <linux/libata.h> |
71 | 69 | ||
72 | #define DRV_NAME "sata_mv" | 70 | #define DRV_NAME "sata_mv" |
73 | #define DRV_VERSION "1.24" | 71 | #define DRV_VERSION "1.25" |
74 | 72 | ||
75 | enum { | 73 | enum { |
76 | /* BAR's are enumerated in terms of pci_resource_start() terms */ | 74 | /* BAR's are enumerated in terms of pci_resource_start() terms */ |
@@ -2199,9 +2197,15 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) | |||
2199 | struct ata_host *host = dev_instance; | 2197 | struct ata_host *host = dev_instance; |
2200 | struct mv_host_priv *hpriv = host->private_data; | 2198 | struct mv_host_priv *hpriv = host->private_data; |
2201 | unsigned int handled = 0; | 2199 | unsigned int handled = 0; |
2200 | int using_msi = hpriv->hp_flags & MV_HP_FLAG_MSI; | ||
2202 | u32 main_irq_cause, pending_irqs; | 2201 | u32 main_irq_cause, pending_irqs; |
2203 | 2202 | ||
2204 | spin_lock(&host->lock); | 2203 | spin_lock(&host->lock); |
2204 | |||
2205 | /* for MSI: block new interrupts while in here */ | ||
2206 | if (using_msi) | ||
2207 | writel(0, hpriv->main_irq_mask_addr); | ||
2208 | |||
2205 | main_irq_cause = readl(hpriv->main_irq_cause_addr); | 2209 | main_irq_cause = readl(hpriv->main_irq_cause_addr); |
2206 | pending_irqs = main_irq_cause & hpriv->main_irq_mask; | 2210 | pending_irqs = main_irq_cause & hpriv->main_irq_mask; |
2207 | /* | 2211 | /* |
@@ -2215,6 +2219,11 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) | |||
2215 | handled = mv_host_intr(host, pending_irqs); | 2219 | handled = mv_host_intr(host, pending_irqs); |
2216 | } | 2220 | } |
2217 | spin_unlock(&host->lock); | 2221 | spin_unlock(&host->lock); |
2222 | |||
2223 | /* for MSI: unmask; interrupt cause bits will retrigger now */ | ||
2224 | if (using_msi) | ||
2225 | writel(hpriv->main_irq_mask, hpriv->main_irq_mask_addr); | ||
2226 | |||
2218 | return IRQ_RETVAL(handled); | 2227 | return IRQ_RETVAL(handled); |
2219 | } | 2228 | } |
2220 | 2229 | ||
@@ -3417,9 +3426,9 @@ static int mv_pci_init_one(struct pci_dev *pdev, | |||
3417 | if (rc) | 3426 | if (rc) |
3418 | return rc; | 3427 | return rc; |
3419 | 3428 | ||
3420 | /* Enable interrupts */ | 3429 | /* Enable message-switched interrupts, if requested */ |
3421 | if (msi && pci_enable_msi(pdev)) | 3430 | if (msi && pci_enable_msi(pdev) == 0) |
3422 | pci_intx(pdev, 1); | 3431 | hpriv->hp_flags |= MV_HP_FLAG_MSI; |
3423 | 3432 | ||
3424 | mv_dump_pci_cfg(pdev, 0x68); | 3433 | mv_dump_pci_cfg(pdev, 0x68); |
3425 | mv_print_info(host); | 3434 | mv_print_info(host); |