summaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorBrian King <brking@linux.vnet.ibm.com>2012-03-14 21:20:08 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-03-28 15:01:06 +0100
commit7dd21308b17e2b657d167adc7e20b41b7c6bbe5c (patch)
tree3789453ea1f3fa6c572e46aec7784a18a82aebad /drivers/scsi
parent0ee1d714c285aabaadf7495bf5820114ad0959b1 (diff)
downloadlinux-7dd21308b17e2b657d167adc7e20b41b7c6bbe5c.tar.gz
linux-7dd21308b17e2b657d167adc7e20b41b7c6bbe5c.tar.bz2
linux-7dd21308b17e2b657d167adc7e20b41b7c6bbe5c.zip
[SCSI] ipr: Remove unnecessary interrupt clearing on new adapters
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>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/ipr.c21
-rw-r--r--drivers/scsi/ipr.h2
2 files changed, 17 insertions, 6 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index dcad2389be3d..0fedca6e273b 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -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;
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index f94eaee2ff16..40cbee72b83c 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -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;