summaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_intel.c
diff options
context:
space:
mode:
authorTakashi Iwai2012-08-09 12:33:28 +0200
committerTakashi Iwai2012-08-09 16:28:19 +0200
commit4918cdab497d693f4de288a576fb22e8ff9df21e (patch)
treeb723f0e106c79f9591aec9442e790d0cb0d39ac7 /sound/pci/hda/hda_intel.c
parentALSA: hda - Fix pop noise in headphones on S3 for Asus X55A, X55V (diff)
downloadkernel-qcow2-linux-4918cdab497d693f4de288a576fb22e8ff9df21e.tar.gz
kernel-qcow2-linux-4918cdab497d693f4de288a576fb22e8ff9df21e.tar.xz
kernel-qcow2-linux-4918cdab497d693f4de288a576fb22e8ff9df21e.zip
ALSA: hda - Load firmware in hda_intel.c
This is a preliminary work for the deferred probing for request_firmware() errors at init. This patch moves the call of request_firmware() to hda_intel.c, and call it in the earlier stage of probing rather than azx_probe_continue(). Tested-by: Thierry Reding <thierry.reding@avionic-design.de> Reviewed-by: David Henningsson <david.henningsson@canonical.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r--sound/pci/hda/hda_intel.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index c8aced182fd1..b25d5392c3b2 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -55,6 +55,7 @@
#include <sound/initval.h>
#include <linux/vgaarb.h>
#include <linux/vga_switcheroo.h>
+#include <linux/firmware.h>
#include "hda_codec.h"
@@ -470,6 +471,10 @@ struct azx {
struct snd_dma_buffer rb;
struct snd_dma_buffer posbuf;
+#ifdef CONFIG_SND_HDA_PATCH_LOADER
+ const struct firmware *fw;
+#endif
+
/* flags */
int position_fix[2]; /* for both playback/capture streams */
int poll_count;
@@ -2639,6 +2644,10 @@ static int azx_free(struct azx *chip)
pci_release_regions(chip->pci);
pci_disable_device(chip->pci);
kfree(chip->azx_dev);
+#ifdef CONFIG_SND_HDA_PATCH_LOADER
+ if (chip->fw)
+ release_firmware(chip->fw);
+#endif
kfree(chip);
return 0;
@@ -3167,7 +3176,6 @@ static int __devinit azx_probe(struct pci_dev *pci,
return err;
}
- /* set this here since it's referred in snd_hda_load_patch() */
snd_card_set_dev(card, &pci->dev);
err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
@@ -3175,6 +3183,16 @@ static int __devinit azx_probe(struct pci_dev *pci,
goto out_free;
card->private_data = chip;
+#ifdef CONFIG_SND_HDA_PATCH_LOADER
+ if (patch[dev] && *patch[dev]) {
+ snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n",
+ patch[dev]);
+ err = request_firmware(&chip->fw, patch[dev], &pci->dev);
+ if (err < 0)
+ goto out_free;
+ }
+#endif /* CONFIG_SND_HDA_PATCH_LOADER */
+
if (!chip->disabled) {
err = azx_probe_continue(chip);
if (err < 0)
@@ -3205,12 +3223,13 @@ static int DELAYED_INIT_MARK azx_probe_continue(struct azx *chip)
if (err < 0)
goto out_free;
#ifdef CONFIG_SND_HDA_PATCH_LOADER
- if (patch[dev] && *patch[dev]) {
- snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n",
- patch[dev]);
- err = snd_hda_load_patch(chip->bus, patch[dev]);
+ if (chip->fw) {
+ err = snd_hda_load_patch(chip->bus, chip->fw->size,
+ chip->fw->data);
if (err < 0)
goto out_free;
+ release_firmware(chip->fw); /* no longer needed */
+ chip->fw = NULL;
}
#endif
if ((probe_only[dev] & 1) == 0) {