summaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
authorMark Lord <liml@rtr.ca>2006-05-19 20:24:56 (GMT)
committerJeff Garzik <jeff@garzik.org>2006-05-20 04:31:45 (GMT)
commit615ab95342f6245026d8974b9724f7ea57d9a184 (patch)
treef86414f7024494c0049a0f37610fc25c4f708b1f /drivers/scsi
parent9b358e305c1d783c8a4ebf00344e95deb9e38f3d (diff)
downloadlinux-615ab95342f6245026d8974b9724f7ea57d9a184.tar.xz
[PATCH] sata_mv: deal with interrupt coalescing interrupts
In some systems, it is possible that the BIOS may have enabled interrupt coalescing for the Marvell controllers which support it. This patch adds code to detect/ack interrupts from the chip's coalescing (combing) logic. Signed-off-by: Mark Lord <liml@rtr.ca> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/sata_mv.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index 87f26cd..3ed2f33 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -50,6 +50,12 @@ enum {
MV_PCI_REG_BASE = 0,
MV_IRQ_COAL_REG_BASE = 0x18000, /* 6xxx part only */
+ MV_IRQ_COAL_CAUSE = (MV_IRQ_COAL_REG_BASE + 0x08),
+ MV_IRQ_COAL_CAUSE_LO = (MV_IRQ_COAL_REG_BASE + 0x88),
+ MV_IRQ_COAL_CAUSE_HI = (MV_IRQ_COAL_REG_BASE + 0x8c),
+ MV_IRQ_COAL_THRESHOLD = (MV_IRQ_COAL_REG_BASE + 0xcc),
+ MV_IRQ_COAL_TIME_THRESHOLD = (MV_IRQ_COAL_REG_BASE + 0xd0),
+
MV_SATAHC0_REG_BASE = 0x20000,
MV_FLASH_CTL = 0x1046c,
MV_GPIO_PORT_CTL = 0x104f0,
@@ -1448,6 +1454,7 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
struct ata_host_set *host_set = dev_instance;
unsigned int hc, handled = 0, n_hcs;
void __iomem *mmio = host_set->mmio_base;
+ struct mv_host_priv *hpriv;
u32 irq_stat;
irq_stat = readl(mmio + HC_MAIN_IRQ_CAUSE_OFS);
@@ -1469,6 +1476,17 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
handled++;
}
}
+
+ hpriv = host_set->private_data;
+ if (IS_60XX(hpriv)) {
+ /* deal with the interrupt coalescing bits */
+ if (irq_stat & (TRAN_LO_DONE | TRAN_HI_DONE | PORTS_0_7_COAL_DONE)) {
+ writelfl(0, mmio + MV_IRQ_COAL_CAUSE_LO);
+ writelfl(0, mmio + MV_IRQ_COAL_CAUSE_HI);
+ writelfl(0, mmio + MV_IRQ_COAL_CAUSE);
+ }
+ }
+
if (PCI_ERR & irq_stat) {
printk(KERN_ERR DRV_NAME ": PCI ERROR; PCI IRQ cause=0x%08x\n",
readl(mmio + PCI_IRQ_CAUSE_OFS));