ALSA: hda - Delay switching to polling mode if an interrupt was missing

My sound codec seems sometimes (very rarely) to omit interrupts (ALC268)
However, interrupt mode still works.
Thus if we get timeout, poll the codec once.

If we get 3 such polls in a row, then switch to polling mode.

This patch is maybe an bandaid, but this might be a workaround for hardware bug.

Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by Maxim Levitsky and committed by Takashi Iwai 1eb6dc7d 8ce28d6a

+17 -2
+17 -2
sound/pci/hda/hda_intel.c
··· 426 426 427 427 /* flags */ 428 428 int position_fix; 429 + int poll_count; 429 430 unsigned int running :1; 430 431 unsigned int initialized :1; 431 432 unsigned int single_cmd :1; ··· 507 506 #define get_azx_dev(substream) (substream->runtime->private_data) 508 507 509 508 static int azx_acquire_irq(struct azx *chip, int do_disconnect); 510 - 509 + static int azx_send_cmd(struct hda_bus *bus, unsigned int val); 511 510 /* 512 511 * Interface for HD codec 513 512 */ ··· 665 664 { 666 665 struct azx *chip = bus->private_data; 667 666 unsigned long timeout; 667 + int do_poll = 0; 668 668 669 669 again: 670 670 timeout = jiffies + msecs_to_jiffies(1000); 671 671 for (;;) { 672 - if (chip->polling_mode) { 672 + if (chip->polling_mode || do_poll) { 673 673 spin_lock_irq(&chip->reg_lock); 674 674 azx_update_rirb(chip); 675 675 spin_unlock_irq(&chip->reg_lock); ··· 678 676 if (!chip->rirb.cmds[addr]) { 679 677 smp_rmb(); 680 678 bus->rirb_error = 0; 679 + 680 + if (!do_poll) 681 + chip->poll_count = 0; 681 682 return chip->rirb.res[addr]; /* the last value */ 682 683 } 683 684 if (time_after(jiffies, timeout)) ··· 692 687 cond_resched(); 693 688 } 694 689 } 690 + 691 + if (!chip->polling_mode && chip->poll_count < 2) { 692 + snd_printdd(SFX "azx_get_response timeout, " 693 + "polling the codec once: last cmd=0x%08x\n", 694 + chip->last_cmd[addr]); 695 + do_poll = 1; 696 + chip->poll_count++; 697 + goto again; 698 + } 699 + 695 700 696 701 if (!chip->polling_mode) { 697 702 snd_printk(KERN_WARNING SFX "azx_get_response timeout, "