diff options
-rw-r--r-- | drivers/ide/ide-io.c | 15 | ||||
-rw-r--r-- | drivers/ide/pci/piix.c | 39 | ||||
-rw-r--r-- | include/linux/ide.h | 4 |
3 files changed, 29 insertions, 29 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index ec709269c066..d0579f1abddd 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1418,23 +1418,16 @@ irqreturn_t ide_intr (int irq, void *dev_id) del_timer(&hwgroup->timer); spin_unlock(&ide_lock); - /* Some controllers might set DMA INTR no matter DMA or PIO; - * bmdma status might need to be cleared even for - * PIO interrupts to prevent spurious/lost irq. - */ - if (hwif->ide_dma_clear_irq && !(drive->waiting_for_dma)) - /* ide_dma_end() needs bmdma status for error checking. - * So, skip clearing bmdma status here and leave it - * to ide_dma_end() if this is dma interrupt. - */ - hwif->ide_dma_clear_irq(drive); + if (hwif->port_ops && hwif->port_ops->clear_irq) + hwif->port_ops->clear_irq(drive); if (drive->dev_flags & IDE_DFLAG_UNMASK) local_irq_enable_in_hardirq(); + /* service this interrupt, may set handler for next interrupt */ startstop = handler(drive); - spin_lock_irq(&ide_lock); + spin_lock_irq(&ide_lock); /* * Note that handler() may have set things up for another * interrupt to occur soon, but it cannot happen until diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index a909684ee61b..56feb939f82a 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c @@ -215,17 +215,26 @@ static unsigned int init_chipset_ich(struct pci_dev *dev) } /** - * piix_dma_clear_irq - clear BMDMA status - * @drive: IDE drive to clear + * ich_clear_irq - clear BMDMA status + * @drive: IDE drive * - * Called from ide_intr() for PIO interrupts - * to clear BMDMA status as needed by ICHx + * ICHx contollers set DMA INTR no matter DMA or PIO. + * BMDMA status might need to be cleared even for + * PIO interrupts to prevent spurious/lost IRQ. */ -static void piix_dma_clear_irq(ide_drive_t *drive) +static void ich_clear_irq(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); u8 dma_stat; + /* + * ide_dma_end() needs BMDMA status for error checking. + * So, skip clearing BMDMA status here and leave it + * to ide_dma_end() if this is DMA interrupt. + */ + if (drive->waiting_for_dma || hwif->dma_base == 0) + return; + /* clear the INTR & ERROR bits */ dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); /* Should we force the bit as well ? */ @@ -293,21 +302,19 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif) hwif->ultra_mask = hwif->mwdma_mask = hwif->swdma_mask = 0; } -static void __devinit init_hwif_ich(ide_hwif_t *hwif) -{ - init_hwif_piix(hwif); - - /* ICHx need to clear the BMDMA status for all interrupts */ - if (hwif->dma_base) - hwif->ide_dma_clear_irq = &piix_dma_clear_irq; -} - static const struct ide_port_ops piix_port_ops = { .set_pio_mode = piix_set_pio_mode, .set_dma_mode = piix_set_dma_mode, .cable_detect = piix_cable_detect, }; +static const struct ide_port_ops ich_port_ops = { + .set_pio_mode = piix_set_pio_mode, + .set_dma_mode = piix_set_dma_mode, + .clear_irq = ich_clear_irq, + .cable_detect = piix_cable_detect, +}; + #ifndef CONFIG_IA64 #define IDE_HFLAGS_PIIX IDE_HFLAG_LEGACY_IRQS #else @@ -331,9 +338,9 @@ static const struct ide_port_ops piix_port_ops = { { \ .name = DRV_NAME, \ .init_chipset = init_chipset_ich, \ - .init_hwif = init_hwif_ich, \ + .init_hwif = init_hwif_piix, \ .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \ - .port_ops = &piix_port_ops, \ + .port_ops = &ich_port_ops, \ .host_flags = IDE_HFLAGS_PIIX, \ .pio_mask = ATA_PIO4, \ .swdma_mask = ATA_SWDMA2_ONLY, \ diff --git a/include/linux/ide.h b/include/linux/ide.h index 14d489c2e5a9..37a4344f3842 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -704,6 +704,7 @@ extern const struct ide_tp_ops default_tp_ops; * @resetproc: routine to reset controller after a disk reset * @maskproc: special host masking for drive selection * @quirkproc: check host's drive quirk list + * @clear_irq: clear IRQ * * @mdma_filter: filter MDMA modes * @udma_filter: filter UDMA modes @@ -720,6 +721,7 @@ struct ide_port_ops { void (*resetproc)(ide_drive_t *); void (*maskproc)(ide_drive_t *, int); void (*quirkproc)(ide_drive_t *); + void (*clear_irq)(ide_drive_t *); u8 (*mdma_filter)(ide_drive_t *); u8 (*udma_filter)(ide_drive_t *); @@ -782,8 +784,6 @@ typedef struct hwif_s { const struct ide_port_ops *port_ops; const struct ide_dma_ops *dma_ops; - void (*ide_dma_clear_irq)(ide_drive_t *drive); - /* dma physical region descriptor table (cpu view) */ unsigned int *dmatable_cpu; /* dma physical region descriptor table (dma view) */ |