[ALSA] intel8x0 - Fix irq handler registration
authorTakashi Iwai <tiwai@suse.de>
Thu, 27 Oct 2005 18:55:38 +0000 (20:55 +0200)
committerJaroslav Kysela <perex@suse.cz>
Fri, 4 Nov 2005 12:20:31 +0000 (13:20 +0100)
Modules: Intel8x0 driver

- Request irq handler after proper initialization
- Don't override always buggy_irq option for Nvidia

Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/intel8x0.c

index 8eb9665..0801083 100644 (file)
@@ -69,7 +69,7 @@ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
 static int ac97_clock = 0;
 static char *ac97_quirk;
 static int buggy_semaphore;
-static int buggy_irq;
+static int buggy_irq = -1; /* auto-check */
 static int xbox;
 
 module_param(index, int, 0444);
@@ -2636,12 +2636,6 @@ static int __devinit snd_intel8x0_create(snd_card_t * card,
            pci->device == PCI_DEVICE_ID_INTEL_440MX)
                chip->fix_nocache = 1; /* enable workaround */
 
-       /* some Nforce[2] and ICH boards have problems with IRQ handling.
-        * Needs to return IRQ_HANDLED for unknown irqs.
-        */
-       if (device_type == DEVICE_NFORCE)
-               chip->buggy_irq = 1;
-
        if ((err = pci_request_regions(pci, card->shortname)) < 0) {
                kfree(chip);
                pci_disable_device(pci);
@@ -2682,15 +2676,6 @@ static int __devinit snd_intel8x0_create(snd_card_t * card,
        }
 
  port_inited:
-       if (request_irq(pci->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
-               snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
-               snd_intel8x0_free(chip);
-               return -EBUSY;
-       }
-       chip->irq = pci->irq;
-       pci_set_master(pci);
-       synchronize_irq(chip->irq);
-
        chip->bdbars_count = bdbars[device_type];
 
        /* initialize offsets */
@@ -2741,13 +2726,27 @@ static int __devinit snd_intel8x0_create(snd_card_t * card,
        int_sta_masks = 0;
        for (i = 0; i < chip->bdbars_count; i++) {
                ichdev = &chip->ichd[i];
-               ichdev->bdbar = ((u32 *)chip->bdbars.area) + (i * ICH_MAX_FRAGS * 2);
-               ichdev->bdbar_addr = chip->bdbars.addr + (i * sizeof(u32) * ICH_MAX_FRAGS * 2);
+               ichdev->bdbar = ((u32 *)chip->bdbars.area) +
+                       (i * ICH_MAX_FRAGS * 2);
+               ichdev->bdbar_addr = chip->bdbars.addr +
+                       (i * sizeof(u32) * ICH_MAX_FRAGS * 2);
                int_sta_masks |= ichdev->int_sta_mask;
        }
-       chip->int_sta_reg = device_type == DEVICE_ALI ? ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA;
+       chip->int_sta_reg = device_type == DEVICE_ALI ?
+               ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA;
        chip->int_sta_mask = int_sta_masks;
 
+       /* request irq after initializaing int_sta_mask, etc */
+       if (request_irq(pci->irq, snd_intel8x0_interrupt,
+                       SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
+               snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
+               snd_intel8x0_free(chip);
+               return -EBUSY;
+       }
+       chip->irq = pci->irq;
+       pci_set_master(pci);
+       synchronize_irq(chip->irq);
+
        if ((err = snd_intel8x0_chip_init(chip, 1)) < 0) {
                snd_intel8x0_free(chip);
                return err;
@@ -2827,6 +2826,16 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
                }
        }
 
+       if (buggy_irq < 0) {
+               /* some Nforce[2] and ICH boards have problems with IRQ handling.
+                * Needs to return IRQ_HANDLED for unknown irqs.
+                */
+               if (pci_id->driver_data == DEVICE_NFORCE)
+                       buggy_irq = 1;
+               else
+                       buggy_irq = 0;
+       }
+
        if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data,
                                       &chip)) < 0) {
                snd_card_free(card);