ide: fix handling of unexpected IRQs vs request_irq()
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Tue, 23 Jun 2009 10:43:00 +0000 (03:43 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 24 Jun 2009 07:32:30 +0000 (00:32 -0700)
Add ide_host_enable_irqs() helper and use it in ide_host_register()
before registering ports.  Then remove no longer needed IRQ unmasking
from in init_irq().

This should fix the problem with "screaming" shared IRQ on the first
port (after request_irq() call while we have the unexpected IRQ pending
on the second port) which was uncovered by my rework of the serialized
interfaces support.

Reported-by: Frans Pop <elendil@planet.nl>
Tested-by: Frans Pop <elendil@planet.nl>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/ide/ide-probe.c

index 51af4eea0d367440d69a9c6db98e097f50ad2d12..1bb106f6221a5aad84aa6385158b23d53b9eaa69 100644 (file)
@@ -818,6 +818,24 @@ static int ide_port_setup_devices(ide_hwif_t *hwif)
        return j;
 }
 
+static void ide_host_enable_irqs(struct ide_host *host)
+{
+       ide_hwif_t *hwif;
+       int i;
+
+       ide_host_for_each_port(i, hwif, host) {
+               if (hwif == NULL)
+                       continue;
+
+               /* clear any pending IRQs */
+               hwif->tp_ops->read_status(hwif);
+
+               /* unmask IRQs */
+               if (hwif->io_ports.ctl_addr)
+                       hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
+       }
+}
+
 /*
  * This routine sets up the IRQ for an IDE interface.
  */
@@ -831,9 +849,6 @@ static int init_irq (ide_hwif_t *hwif)
        if (irq_handler == NULL)
                irq_handler = ide_intr;
 
-       if (io_ports->ctl_addr)
-               hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
-
        if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif))
                goto out_up;
 
@@ -1404,6 +1419,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
                        ide_port_tune_devices(hwif);
        }
 
+       ide_host_enable_irqs(host);
+
        ide_host_for_each_port(i, hwif, host) {
                if (hwif == NULL)
                        continue;