diff options
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index ac05bef7c2e..8d8e0b5aa24 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -426,6 +426,7 @@ struct azx { | |||
426 | 426 | ||
427 | /* flags */ | 427 | /* flags */ |
428 | int position_fix; | 428 | int position_fix; |
429 | int poll_count; | ||
429 | unsigned int running :1; | 430 | unsigned int running :1; |
430 | unsigned int initialized :1; | 431 | unsigned int initialized :1; |
431 | unsigned int single_cmd :1; | 432 | unsigned int single_cmd :1; |
@@ -506,7 +507,7 @@ static char *driver_short_names[] __devinitdata = { | |||
506 | #define get_azx_dev(substream) (substream->runtime->private_data) | 507 | #define get_azx_dev(substream) (substream->runtime->private_data) |
507 | 508 | ||
508 | static int azx_acquire_irq(struct azx *chip, int do_disconnect); | 509 | static int azx_acquire_irq(struct azx *chip, int do_disconnect); |
509 | 510 | static int azx_send_cmd(struct hda_bus *bus, unsigned int val); | |
510 | /* | 511 | /* |
511 | * Interface for HD codec | 512 | * Interface for HD codec |
512 | */ | 513 | */ |
@@ -664,11 +665,12 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus, | |||
664 | { | 665 | { |
665 | struct azx *chip = bus->private_data; | 666 | struct azx *chip = bus->private_data; |
666 | unsigned long timeout; | 667 | unsigned long timeout; |
668 | int do_poll = 0; | ||
667 | 669 | ||
668 | again: | 670 | again: |
669 | timeout = jiffies + msecs_to_jiffies(1000); | 671 | timeout = jiffies + msecs_to_jiffies(1000); |
670 | for (;;) { | 672 | for (;;) { |
671 | if (chip->polling_mode) { | 673 | if (chip->polling_mode || do_poll) { |
672 | spin_lock_irq(&chip->reg_lock); | 674 | spin_lock_irq(&chip->reg_lock); |
673 | azx_update_rirb(chip); | 675 | azx_update_rirb(chip); |
674 | spin_unlock_irq(&chip->reg_lock); | 676 | spin_unlock_irq(&chip->reg_lock); |
@@ -676,6 +678,9 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus, | |||
676 | if (!chip->rirb.cmds[addr]) { | 678 | if (!chip->rirb.cmds[addr]) { |
677 | smp_rmb(); | 679 | smp_rmb(); |
678 | bus->rirb_error = 0; | 680 | bus->rirb_error = 0; |
681 | |||
682 | if (!do_poll) | ||
683 | chip->poll_count = 0; | ||
679 | return chip->rirb.res[addr]; /* the last value */ | 684 | return chip->rirb.res[addr]; /* the last value */ |
680 | } | 685 | } |
681 | if (time_after(jiffies, timeout)) | 686 | if (time_after(jiffies, timeout)) |
@@ -688,6 +693,16 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus, | |||
688 | } | 693 | } |
689 | } | 694 | } |
690 | 695 | ||
696 | if (!chip->polling_mode && chip->poll_count < 2) { | ||
697 | snd_printdd(SFX "azx_get_response timeout, " | ||
698 | "polling the codec once: last cmd=0x%08x\n", | ||
699 | chip->last_cmd[addr]); | ||
700 | do_poll = 1; | ||
701 | chip->poll_count++; | ||
702 | goto again; | ||
703 | } | ||
704 | |||
705 | |||
691 | if (!chip->polling_mode) { | 706 | if (!chip->polling_mode) { |
692 | snd_printk(KERN_WARNING SFX "azx_get_response timeout, " | 707 | snd_printk(KERN_WARNING SFX "azx_get_response timeout, " |
693 | "switching to polling mode: last cmd=0x%08x\n", | 708 | "switching to polling mode: last cmd=0x%08x\n", |
@@ -1878,6 +1893,9 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) | |||
1878 | 1893 | ||
1879 | if (!bdl_pos_adj[chip->dev_index]) | 1894 | if (!bdl_pos_adj[chip->dev_index]) |
1880 | return 1; /* no delayed ack */ | 1895 | return 1; /* no delayed ack */ |
1896 | if (WARN_ONCE(!azx_dev->period_bytes, | ||
1897 | "hda-intel: zero azx_dev->period_bytes")) | ||
1898 | return 0; /* this shouldn't happen! */ | ||
1881 | if (pos % azx_dev->period_bytes > azx_dev->period_bytes / 2) | 1899 | if (pos % azx_dev->period_bytes > azx_dev->period_bytes / 2) |
1882 | return 0; /* NG - it's below the period boundary */ | 1900 | return 0; /* NG - it's below the period boundary */ |
1883 | return 1; /* OK, it's fine */ | 1901 | return 1; /* OK, it's fine */ |
@@ -2043,7 +2061,7 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect) | |||
2043 | { | 2061 | { |
2044 | if (request_irq(chip->pci->irq, azx_interrupt, | 2062 | if (request_irq(chip->pci->irq, azx_interrupt, |
2045 | chip->msi ? 0 : IRQF_SHARED, | 2063 | chip->msi ? 0 : IRQF_SHARED, |
2046 | "HDA Intel", chip)) { | 2064 | "hda_intel", chip)) { |
2047 | printk(KERN_ERR "hda-intel: unable to grab IRQ %d, " | 2065 | printk(KERN_ERR "hda-intel: unable to grab IRQ %d, " |
2048 | "disabling device\n", chip->pci->irq); | 2066 | "disabling device\n", chip->pci->irq); |
2049 | if (do_disconnect) | 2067 | if (do_disconnect) |
@@ -2332,6 +2350,7 @@ static void __devinit check_probe_mask(struct azx *chip, int dev) | |||
2332 | */ | 2350 | */ |
2333 | static struct snd_pci_quirk msi_black_list[] __devinitdata = { | 2351 | static struct snd_pci_quirk msi_black_list[] __devinitdata = { |
2334 | SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */ | 2352 | SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */ |
2353 | SND_PCI_QUIRK(0x1043, 0x829c, "ASUS", 0), /* nvidia */ | ||
2335 | {} | 2354 | {} |
2336 | }; | 2355 | }; |
2337 | 2356 | ||