[SCSI] ipr: Remove unnecessary interrupt clearing on new adapters
authorBrian King <brking@linux.vnet.ibm.com>
Thu, 15 Mar 2012 02:20:08 +0000 (21:20 -0500)
committerJames Bottomley <JBottomley@Parallels.com>
Wed, 28 Mar 2012 14:01:06 +0000 (15:01 +0100)
The latest ipr hardware no longer requires the driver to issue any MMIOs
to clear the interrupt so remove this to optimize performance.

Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/ipr.c
drivers/scsi/ipr.h

index dcad2389be3df87f0eae528ad32e83083a4eff61..0fedca6e273b48a38df7bd65088e719032ff14e5 100644 (file)
@@ -105,6 +105,7 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
        { /* Gemstone, Citrine, Obsidian, and Obsidian-E */
                .mailbox = 0x0042C,
                .cache_line_size = 0x20,
+               .clear_isr = 1,
                {
                        .set_interrupt_mask_reg = 0x0022C,
                        .clr_interrupt_mask_reg = 0x00230,
@@ -127,6 +128,7 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
        { /* Snipe and Scamp */
                .mailbox = 0x0052C,
                .cache_line_size = 0x20,
+               .clear_isr = 1,
                {
                        .set_interrupt_mask_reg = 0x00288,
                        .clr_interrupt_mask_reg = 0x0028C,
@@ -149,6 +151,7 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
        { /* CRoC */
                .mailbox = 0x00044,
                .cache_line_size = 0x20,
+               .clear_isr = 0,
                {
                        .set_interrupt_mask_reg = 0x00010,
                        .clr_interrupt_mask_reg = 0x00018,
@@ -5049,12 +5052,14 @@ static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg,
                del_timer(&ioa_cfg->reset_cmd->timer);
                ipr_reset_ioa_job(ioa_cfg->reset_cmd);
        } else if ((int_reg & IPR_PCII_HRRQ_UPDATED) == int_reg) {
-               if (ipr_debug && printk_ratelimit())
-                       dev_err(&ioa_cfg->pdev->dev,
-                               "Spurious interrupt detected. 0x%08X\n", int_reg);
-               writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32);
-               int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32);
-               return IRQ_NONE;
+               if (ioa_cfg->clear_isr) {
+                       if (ipr_debug && printk_ratelimit())
+                               dev_err(&ioa_cfg->pdev->dev,
+                                       "Spurious interrupt detected. 0x%08X\n", int_reg);
+                       writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32);
+                       int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32);
+                       return IRQ_NONE;
+               }
        } else {
                if (int_reg & IPR_PCII_IOA_UNIT_CHECKED)
                        ioa_cfg->ioa_unit_checked = 1;
@@ -5154,6 +5159,9 @@ static irqreturn_t ipr_isr(int irq, void *devp)
                        }
                }
 
+               if (ipr_cmd && !ioa_cfg->clear_isr)
+                       break;
+
                if (ipr_cmd != NULL) {
                        /* Clear the PCI interrupt */
                        num_hrrq = 0;
@@ -8769,6 +8777,7 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
        /* set SIS 32 or SIS 64 */
        ioa_cfg->sis64 = ioa_cfg->ipr_chip->sis_type == IPR_SIS64 ? 1 : 0;
        ioa_cfg->chip_cfg = ioa_cfg->ipr_chip->cfg;
+       ioa_cfg->clear_isr = ioa_cfg->chip_cfg->clear_isr;
 
        if (ipr_transop_timeout)
                ioa_cfg->transop_timeout = ipr_transop_timeout;
index f94eaee2ff16b626ae516a718fced5d76979cd95..40cbee72b83ce4286547395f62c9e6a2e622b901 100644 (file)
@@ -1306,6 +1306,7 @@ struct ipr_interrupts {
 struct ipr_chip_cfg_t {
        u32 mailbox;
        u8 cache_line_size;
+       u8 clear_isr;
        struct ipr_interrupt_offsets regs;
 };
 
@@ -1388,6 +1389,7 @@ struct ipr_ioa_cfg {
        u8 sis64:1;
        u8 dump_timeout:1;
        u8 cfg_locked:1;
+       u8 clear_isr:1;
 
        u8 revid;