]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ide/pci/piix.c
ide: ->ide_dma_clear_irq() -> ->clear_irq()
[linux-2.6-omap-h63xx.git] / drivers / ide / pci / piix.c
index a909684ee61b99403d88b9dd106d35545393aebb..56feb939f82a7b4fb043da9b34b4916b598ba091 100644 (file)
@@ -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, \