]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.drivers/alsa-post-ga-hda-codec-verb-retry
Imported linux-2.6.27.39 suse/xen patches.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / alsa-post-ga-hda-codec-verb-retry
diff --git a/src/patches/suse-2.6.27.31/patches.drivers/alsa-post-ga-hda-codec-verb-retry b/src/patches/suse-2.6.27.31/patches.drivers/alsa-post-ga-hda-codec-verb-retry
deleted file mode 100644 (file)
index 3318b09..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-From: Takashi Iwai <tiwai@suse.de>
-Subject: ALSA: Add codec bus reset and verb-retry at critical errors
-Patch-mainline: 
-References: bnc#502903
-
-The Volna machine causes a severe CORB/RIRB stall when PA is started
-together with fglrx.  This cannot be recovered without the controller
-reset.
-
-This patch allows the bus controller reset at critical errors so
-that the communication gets recovered again.
-
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-
----
- sound/pci/hda/hda_codec.c |   13 +++++++++++--
- sound/pci/hda/hda_codec.h |    7 ++++++-
- sound/pci/hda/hda_intel.c |   37 +++++++++++++++++++++++++++++++++----
- 3 files changed, 50 insertions(+), 7 deletions(-)
-
---- a/sound/pci/hda/hda_codec.h
-+++ b/sound/pci/hda/hda_codec.h
-@@ -541,6 +541,8 @@
-       unsigned int (*get_response)(struct hda_bus *bus);
-       /* free the private data */
-       void (*private_free)(struct hda_bus *);
-+      /* reset bus for retry verb */
-+      void (*bus_reset)(struct hda_bus *bus);
- #ifdef CONFIG_SND_HDA_POWER_SAVE
-       /* notify power-up/down from codec to controller */
-       void (*pm_notify)(struct hda_bus *bus);
-@@ -586,6 +588,9 @@
-       /* misc op flags */
-       unsigned int needs_damn_long_delay :1;
-+      unsigned int rirb_error:1;      /* error in codec communication */
-+      unsigned int response_reset:1;  /* controller was reset */
-+      unsigned int in_reset:1;        /* during reset operation */
- };
- /*
-@@ -827,7 +832,7 @@
-  * power management
-  */
- #ifdef CONFIG_PM
--int snd_hda_suspend(struct hda_bus *bus, pm_message_t state);
-+int snd_hda_suspend(struct hda_bus *bus);
- int snd_hda_resume(struct hda_bus *bus);
- #endif
---- a/sound/pci/hda/hda_codec.c
-+++ b/sound/pci/hda/hda_codec.c
-@@ -187,6 +187,7 @@
-       if (res)
-               *res = -1;
-+ again:
-       snd_hda_power_up(codec);
-       mutex_lock(&bus->cmd_mutex);
-       err = bus->ops.command(bus, cmd);
-@@ -194,6 +195,15 @@
-               *res = bus->ops.get_response(bus);
-       mutex_unlock(&bus->cmd_mutex);
-       snd_hda_power_down(codec);
-+      if (res && *res == -1 && bus->rirb_error) {
-+              if (bus->response_reset) {
-+                      snd_printd("hda_codec: resetting BUS due to "
-+                                 "fatal communication error\n");
-+                      bus->ops.bus_reset(bus);
-+              }
-+              goto again;
-+      }
-+      bus->response_reset = 0;
-       return err;
- }
-@@ -3279,11 +3289,10 @@
- /**
-  * snd_hda_suspend - suspend the codecs
-  * @bus: the HDA bus
-- * @state: suspsend state
-  *
-  * Returns 0 if successful.
-  */
--int snd_hda_suspend(struct hda_bus *bus, pm_message_t state)
-+int snd_hda_suspend(struct hda_bus *bus)
- {
-       struct hda_codec *codec;
---- a/sound/pci/hda/hda_intel.c
-+++ b/sound/pci/hda/hda_intel.c
-@@ -600,6 +600,7 @@
-               }
-               if (!chip->rirb.cmds) {
-                       smp_rmb();
-+                      bus->rirb_error = 0;
-                       return chip->rirb.res; /* the last value */
-               }
-               if (time_after(jiffies, timeout))
-@@ -640,14 +641,23 @@
-               return -1;
-       }
-+      /* a fatal communication error; need either to reset or to fallback
-+       * to the single_cmd mode
-+       */
-+      bus->rirb_error = 1;
-+      if (!bus->response_reset && !bus->in_reset) {
-+              bus->response_reset = 1;
-+              return -1; /* give a chance to retry */
-+      }
-+
-       snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, "
-                  "switching to single_cmd mode: last cmd=0x%08x\n",
-                  chip->last_cmd);
--      chip->rirb.rp = azx_readb(chip, RIRBWP);
--      chip->rirb.cmds = 0;
--      /* switch to single_cmd mode */
-       chip->single_cmd = 1;
-+      bus->response_reset = 0;
-+      /* re-initialize CORB/RIRB */
-       azx_free_cmd_io(chip);
-+      azx_init_cmd_io(chip);
-       return -1;
- }
-@@ -688,6 +698,7 @@
-       struct azx *chip = bus->private_data;
-       int timeout = 50;
-+      bus->rirb_error = 0;
-       while (timeout--) {
-               /* check ICB busy bit */
-               if (!((azx_readw(chip, IRS) & ICH6_IRS_BUSY))) {
-@@ -1227,6 +1238,23 @@
- static void azx_stop_chip(struct azx *chip);
-+static void azx_bus_reset(struct hda_bus *bus)
-+{
-+      struct azx *chip = bus->private_data;
-+      int i;
-+
-+      bus->in_reset = 1;
-+      azx_stop_chip(chip);
-+      azx_init_chip(chip);
-+      if (chip->initialized) {
-+              for (i = 0; i < AZX_MAX_PCMS; i++)
-+                      snd_pcm_suspend_all(chip->pcm[i]);
-+              snd_hda_suspend(chip->bus);
-+              snd_hda_resume(chip->bus);
-+      }
-+      bus->in_reset = 0;
-+}
-+
- /*
-  * Codec initialization
-  */
-@@ -1248,6 +1276,7 @@
-       bus_temp.pci = chip->pci;
-       bus_temp.ops.command = azx_send_cmd;
-       bus_temp.ops.get_response = azx_get_response;
-+      bus_temp.ops.bus_reset = azx_bus_reset;
- #ifdef CONFIG_SND_HDA_POWER_SAVE
-       bus_temp.ops.pm_notify = azx_power_notify;
- #endif
-@@ -2013,7 +2042,7 @@
-       for (i = 0; i < AZX_MAX_PCMS; i++)
-               snd_pcm_suspend_all(chip->pcm[i]);
-       if (chip->initialized)
--              snd_hda_suspend(chip->bus, state);
-+              snd_hda_suspend(chip->bus);
-       azx_stop_chip(chip);
-       if (chip->irq >= 0) {
-               free_irq(chip->irq, chip);