diff options
| -rw-r--r-- | sound/pci/hda/hda_intel.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 565de38a3fc7..d853e2c33bb7 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", |
