diff options
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 12230a2ed4f1..353412bb5ccb 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -425,6 +425,7 @@ struct azx { | |||
425 | 425 | ||
426 | /* flags */ | 426 | /* flags */ |
427 | int position_fix; | 427 | int position_fix; |
428 | int poll_count; | ||
428 | unsigned int running :1; | 429 | unsigned int running :1; |
429 | unsigned int initialized :1; | 430 | unsigned int initialized :1; |
430 | unsigned int single_cmd :1; | 431 | unsigned int single_cmd :1; |
@@ -505,7 +506,7 @@ static char *driver_short_names[] __devinitdata = { | |||
505 | #define get_azx_dev(substream) (substream->runtime->private_data) | 506 | #define get_azx_dev(substream) (substream->runtime->private_data) |
506 | 507 | ||
507 | static int azx_acquire_irq(struct azx *chip, int do_disconnect); | 508 | static int azx_acquire_irq(struct azx *chip, int do_disconnect); |
508 | 509 | static int azx_send_cmd(struct hda_bus *bus, unsigned int val); | |
509 | /* | 510 | /* |
510 | * Interface for HD codec | 511 | * Interface for HD codec |
511 | */ | 512 | */ |
@@ -663,11 +664,12 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus, | |||
663 | { | 664 | { |
664 | struct azx *chip = bus->private_data; | 665 | struct azx *chip = bus->private_data; |
665 | unsigned long timeout; | 666 | unsigned long timeout; |
667 | int do_poll = 0; | ||
666 | 668 | ||
667 | again: | 669 | again: |
668 | timeout = jiffies + msecs_to_jiffies(1000); | 670 | timeout = jiffies + msecs_to_jiffies(1000); |
669 | for (;;) { | 671 | for (;;) { |
670 | if (chip->polling_mode) { | 672 | if (chip->polling_mode || do_poll) { |
671 | spin_lock_irq(&chip->reg_lock); | 673 | spin_lock_irq(&chip->reg_lock); |
672 | azx_update_rirb(chip); | 674 | azx_update_rirb(chip); |
673 | spin_unlock_irq(&chip->reg_lock); | 675 | spin_unlock_irq(&chip->reg_lock); |
@@ -675,6 +677,9 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus, | |||
675 | if (!chip->rirb.cmds[addr]) { | 677 | if (!chip->rirb.cmds[addr]) { |
676 | smp_rmb(); | 678 | smp_rmb(); |
677 | bus->rirb_error = 0; | 679 | bus->rirb_error = 0; |
680 | |||
681 | if (!do_poll) | ||
682 | chip->poll_count = 0; | ||
678 | return chip->rirb.res[addr]; /* the last value */ | 683 | return chip->rirb.res[addr]; /* the last value */ |
679 | } | 684 | } |
680 | if (time_after(jiffies, timeout)) | 685 | if (time_after(jiffies, timeout)) |
@@ -687,6 +692,16 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus, | |||
687 | } | 692 | } |
688 | } | 693 | } |
689 | 694 | ||
695 | if (!chip->polling_mode && chip->poll_count < 2) { | ||
696 | snd_printdd(SFX "azx_get_response timeout, " | ||
697 | "polling the codec once: last cmd=0x%08x\n", | ||
698 | chip->last_cmd[addr]); | ||
699 | do_poll = 1; | ||
700 | chip->poll_count++; | ||
701 | goto again; | ||
702 | } | ||
703 | |||
704 | |||
690 | if (!chip->polling_mode) { | 705 | if (!chip->polling_mode) { |
691 | snd_printk(KERN_WARNING SFX "azx_get_response timeout, " | 706 | snd_printk(KERN_WARNING SFX "azx_get_response timeout, " |
692 | "switching to polling mode: last cmd=0x%08x\n", | 707 | "switching to polling mode: last cmd=0x%08x\n", |
@@ -2042,7 +2057,7 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect) | |||
2042 | { | 2057 | { |
2043 | if (request_irq(chip->pci->irq, azx_interrupt, | 2058 | if (request_irq(chip->pci->irq, azx_interrupt, |
2044 | chip->msi ? 0 : IRQF_SHARED, | 2059 | chip->msi ? 0 : IRQF_SHARED, |
2045 | "HDA Intel", chip)) { | 2060 | "hda_intel", chip)) { |
2046 | printk(KERN_ERR "hda-intel: unable to grab IRQ %d, " | 2061 | printk(KERN_ERR "hda-intel: unable to grab IRQ %d, " |
2047 | "disabling device\n", chip->pci->irq); | 2062 | "disabling device\n", chip->pci->irq); |
2048 | if (do_disconnect) | 2063 | if (do_disconnect) |
@@ -2331,6 +2346,7 @@ static void __devinit check_probe_mask(struct azx *chip, int dev) | |||
2331 | */ | 2346 | */ |
2332 | static struct snd_pci_quirk msi_black_list[] __devinitdata = { | 2347 | static struct snd_pci_quirk msi_black_list[] __devinitdata = { |
2333 | SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */ | 2348 | SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */ |
2349 | SND_PCI_QUIRK(0x1043, 0x829c, "ASUS", 0), /* nvidia */ | ||
2334 | {} | 2350 | {} |
2335 | }; | 2351 | }; |
2336 | 2352 | ||