ALSA: hda - Fix DMA mask for ATI controllers
[pandora-kernel.git] / sound / pci / hda / hda_intel.c
index a26ae8c..643f0e4 100644 (file)
@@ -58,6 +58,7 @@ static char *model[SNDRV_CARDS];
 static int position_fix[SNDRV_CARDS];
 static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
 static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
+static int probe_only[SNDRV_CARDS];
 static int single_cmd;
 static int enable_msi;
 
@@ -76,6 +77,8 @@ module_param_array(bdl_pos_adj, int, NULL, 0644);
 MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
 module_param_array(probe_mask, int, NULL, 0444);
 MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
+module_param_array(probe_only, bool, NULL, 0444);
+MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
 module_param(single_cmd, bool, 0444);
 MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
                 "(for debugging only).");
@@ -993,10 +996,11 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
                                spin_unlock(&chip->reg_lock);
                                snd_pcm_period_elapsed(azx_dev->substream);
                                spin_lock(&chip->reg_lock);
-                       } else {
+                       } else if (chip->bus && chip->bus->workq) {
                                /* bogus IRQ, process it later */
                                azx_dev->irq_pending = 1;
-                               schedule_work(&chip->irq_pending_work);
+                               queue_work(chip->bus->workq,
+                                          &chip->irq_pending_work);
                        }
                }
        }
@@ -1224,7 +1228,8 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = {
 };
 
 static int __devinit azx_codec_create(struct azx *chip, const char *model,
-                                     unsigned int codec_probe_mask)
+                                     unsigned int codec_probe_mask,
+                                     int no_init)
 {
        struct hda_bus_template bus_temp;
        int c, codecs, err;
@@ -1282,7 +1287,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
        for (c = 0; c < max_slots; c++) {
                if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
                        struct hda_codec *codec;
-                       err = snd_hda_codec_new(chip->bus, c, &codec);
+                       err = snd_hda_codec_new(chip->bus, c, !no_init, &codec);
                        if (err < 0)
                                continue;
                        codecs++;
@@ -1737,7 +1742,6 @@ static void azx_clear_irq_pending(struct azx *chip)
        for (i = 0; i < chip->num_streams; i++)
                chip->azx_dev[i].irq_pending = 0;
        spin_unlock_irq(&chip->reg_lock);
-       flush_scheduled_work();
 }
 
 static struct snd_pcm_ops azx_pcm_ops = {
@@ -2091,6 +2095,8 @@ static struct snd_pci_quirk probe_mask_list[] __devinitdata = {
        SND_PCI_QUIRK(0x1028, 0x20ac, "Dell Studio Desktop", 0x01),
        /* including bogus ALC268 in slot#2 that conflicts with ALC888 */
        SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01),
+       /* conflict of ALC268 in slot#3 (digital I/O); a temporary fix */
+       SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba laptop", 0x03),
        {}
 };
 
@@ -2204,9 +2210,17 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
        gcap = azx_readw(chip, GCAP);
        snd_printdd("chipset global capabilities = 0x%x\n", gcap);
 
+       /* ATI chips seems buggy about 64bit DMA addresses */
+       if (chip->driver_type == AZX_DRIVER_ATI)
+               gcap &= ~0x01;
+
        /* allow 64bit DMA address if supported by H/W */
        if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_64BIT_MASK))
                pci_set_consistent_dma_mask(pci, DMA_64BIT_MASK);
+       else {
+               pci_set_dma_mask(pci, DMA_32BIT_MASK);
+               pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK);
+       }
 
        /* read number of streams from GCAP register instead of using
         * hardcoded value
@@ -2340,7 +2354,8 @@ static int __devinit azx_probe(struct pci_dev *pci,
        card->private_data = chip;
 
        /* create codec instances */
-       err = azx_codec_create(chip, model[dev], probe_mask[dev]);
+       err = azx_codec_create(chip, model[dev], probe_mask[dev],
+                              probe_only[dev]);
        if (err < 0)
                goto out_free;