diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-08-09 06:33:28 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-08-09 10:28:19 -0400 |
commit | 4918cdab497d693f4de288a576fb22e8ff9df21e (patch) | |
tree | b723f0e106c79f9591aec9442e790d0cb0d39ac7 /sound/pci/hda | |
parent | 94c142a160d63edac0e1fca7848960dcf75dd2a9 (diff) |
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')
-rw-r--r-- | sound/pci/hda/hda_codec.h | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_hwdep.c | 39 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 29 |
3 files changed, 38 insertions, 32 deletions
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index c422d330ca5..39e43753ddb 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -1072,7 +1072,7 @@ static inline void snd_hda_power_down(struct hda_codec *codec) {} | |||
1072 | /* | 1072 | /* |
1073 | * patch firmware | 1073 | * patch firmware |
1074 | */ | 1074 | */ |
1075 | int snd_hda_load_patch(struct hda_bus *bus, const char *patch); | 1075 | int snd_hda_load_patch(struct hda_bus *bus, size_t size, const void *buf); |
1076 | #endif | 1076 | #endif |
1077 | 1077 | ||
1078 | /* | 1078 | /* |
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index 6b2efb8cb1f..b9a644ca03b 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
26 | #include <linux/ctype.h> | 26 | #include <linux/ctype.h> |
27 | #include <linux/string.h> | 27 | #include <linux/string.h> |
28 | #include <linux/firmware.h> | ||
29 | #include <linux/export.h> | 28 | #include <linux/export.h> |
30 | #include <sound/core.h> | 29 | #include <sound/core.h> |
31 | #include "hda_codec.h" | 30 | #include "hda_codec.h" |
@@ -747,18 +746,21 @@ static int parse_line_mode(char *buf, struct hda_bus *bus) | |||
747 | * | 746 | * |
748 | * the spaces at the beginning and the end of the line are stripped | 747 | * the spaces at the beginning and the end of the line are stripped |
749 | */ | 748 | */ |
750 | static int get_line_from_fw(char *buf, int size, struct firmware *fw) | 749 | static int get_line_from_fw(char *buf, int size, size_t *fw_size_p, |
750 | const void **fw_data_p) | ||
751 | { | 751 | { |
752 | int len; | 752 | int len; |
753 | const char *p = fw->data; | 753 | size_t fw_size = *fw_size_p; |
754 | while (isspace(*p) && fw->size) { | 754 | const char *p = *fw_data_p; |
755 | |||
756 | while (isspace(*p) && fw_size) { | ||
755 | p++; | 757 | p++; |
756 | fw->size--; | 758 | fw_size--; |
757 | } | 759 | } |
758 | if (!fw->size) | 760 | if (!fw_size) |
759 | return 0; | 761 | return 0; |
760 | 762 | ||
761 | for (len = 0; len < fw->size; len++) { | 763 | for (len = 0; len < fw_size; len++) { |
762 | if (!*p) | 764 | if (!*p) |
763 | break; | 765 | break; |
764 | if (*p == '\n') { | 766 | if (*p == '\n') { |
@@ -770,8 +772,8 @@ static int get_line_from_fw(char *buf, int size, struct firmware *fw) | |||
770 | *buf++ = *p++; | 772 | *buf++ = *p++; |
771 | } | 773 | } |
772 | *buf = 0; | 774 | *buf = 0; |
773 | fw->size -= len; | 775 | *fw_size_p = fw_size - len; |
774 | fw->data = p; | 776 | *fw_data_p = p; |
775 | remove_trail_spaces(buf); | 777 | remove_trail_spaces(buf); |
776 | return 1; | 778 | return 1; |
777 | } | 779 | } |
@@ -779,29 +781,15 @@ static int get_line_from_fw(char *buf, int size, struct firmware *fw) | |||
779 | /* | 781 | /* |
780 | * load a "patch" firmware file and parse it | 782 | * load a "patch" firmware file and parse it |
781 | */ | 783 | */ |
782 | int snd_hda_load_patch(struct hda_bus *bus, const char *patch) | 784 | int snd_hda_load_patch(struct hda_bus *bus, size_t fw_size, const void *fw_buf) |
783 | { | 785 | { |
784 | int err; | ||
785 | const struct firmware *fw; | ||
786 | struct firmware tmp; | ||
787 | char buf[128]; | 786 | char buf[128]; |
788 | struct hda_codec *codec; | 787 | struct hda_codec *codec; |
789 | int line_mode; | 788 | int line_mode; |
790 | struct device *dev = bus->card->dev; | ||
791 | |||
792 | if (snd_BUG_ON(!dev)) | ||
793 | return -ENODEV; | ||
794 | err = request_firmware(&fw, patch, dev); | ||
795 | if (err < 0) { | ||
796 | printk(KERN_ERR "hda-codec: Cannot load the patch '%s'\n", | ||
797 | patch); | ||
798 | return err; | ||
799 | } | ||
800 | 789 | ||
801 | tmp = *fw; | ||
802 | line_mode = LINE_MODE_NONE; | 790 | line_mode = LINE_MODE_NONE; |
803 | codec = NULL; | 791 | codec = NULL; |
804 | while (get_line_from_fw(buf, sizeof(buf) - 1, &tmp)) { | 792 | while (get_line_from_fw(buf, sizeof(buf) - 1, &fw_size, &fw_buf)) { |
805 | if (!*buf || *buf == '#' || *buf == '\n') | 793 | if (!*buf || *buf == '#' || *buf == '\n') |
806 | continue; | 794 | continue; |
807 | if (*buf == '[') | 795 | if (*buf == '[') |
@@ -810,7 +798,6 @@ int snd_hda_load_patch(struct hda_bus *bus, const char *patch) | |||
810 | (codec || !patch_items[line_mode].need_codec)) | 798 | (codec || !patch_items[line_mode].need_codec)) |
811 | patch_items[line_mode].parser(buf, bus, &codec); | 799 | patch_items[line_mode].parser(buf, bus, &codec); |
812 | } | 800 | } |
813 | release_firmware(fw); | ||
814 | return 0; | 801 | return 0; |
815 | } | 802 | } |
816 | EXPORT_SYMBOL_HDA(snd_hda_load_patch); | 803 | EXPORT_SYMBOL_HDA(snd_hda_load_patch); |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index c8aced182fd..b25d5392c3b 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -55,6 +55,7 @@ | |||
55 | #include <sound/initval.h> | 55 | #include <sound/initval.h> |
56 | #include <linux/vgaarb.h> | 56 | #include <linux/vgaarb.h> |
57 | #include <linux/vga_switcheroo.h> | 57 | #include <linux/vga_switcheroo.h> |
58 | #include <linux/firmware.h> | ||
58 | #include "hda_codec.h" | 59 | #include "hda_codec.h" |
59 | 60 | ||
60 | 61 | ||
@@ -470,6 +471,10 @@ struct azx { | |||
470 | struct snd_dma_buffer rb; | 471 | struct snd_dma_buffer rb; |
471 | struct snd_dma_buffer posbuf; | 472 | struct snd_dma_buffer posbuf; |
472 | 473 | ||
474 | #ifdef CONFIG_SND_HDA_PATCH_LOADER | ||
475 | const struct firmware *fw; | ||
476 | #endif | ||
477 | |||
473 | /* flags */ | 478 | /* flags */ |
474 | int position_fix[2]; /* for both playback/capture streams */ | 479 | int position_fix[2]; /* for both playback/capture streams */ |
475 | int poll_count; | 480 | int poll_count; |
@@ -2639,6 +2644,10 @@ static int azx_free(struct azx *chip) | |||
2639 | pci_release_regions(chip->pci); | 2644 | pci_release_regions(chip->pci); |
2640 | pci_disable_device(chip->pci); | 2645 | pci_disable_device(chip->pci); |
2641 | kfree(chip->azx_dev); | 2646 | kfree(chip->azx_dev); |
2647 | #ifdef CONFIG_SND_HDA_PATCH_LOADER | ||
2648 | if (chip->fw) | ||
2649 | release_firmware(chip->fw); | ||
2650 | #endif | ||
2642 | kfree(chip); | 2651 | kfree(chip); |
2643 | 2652 | ||
2644 | return 0; | 2653 | return 0; |
@@ -3167,7 +3176,6 @@ static int __devinit azx_probe(struct pci_dev *pci, | |||
3167 | return err; | 3176 | return err; |
3168 | } | 3177 | } |
3169 | 3178 | ||
3170 | /* set this here since it's referred in snd_hda_load_patch() */ | ||
3171 | snd_card_set_dev(card, &pci->dev); | 3179 | snd_card_set_dev(card, &pci->dev); |
3172 | 3180 | ||
3173 | err = azx_create(card, pci, dev, pci_id->driver_data, &chip); | 3181 | err = azx_create(card, pci, dev, pci_id->driver_data, &chip); |
@@ -3175,6 +3183,16 @@ static int __devinit azx_probe(struct pci_dev *pci, | |||
3175 | goto out_free; | 3183 | goto out_free; |
3176 | card->private_data = chip; | 3184 | card->private_data = chip; |
3177 | 3185 | ||
3186 | #ifdef CONFIG_SND_HDA_PATCH_LOADER | ||
3187 | if (patch[dev] && *patch[dev]) { | ||
3188 | snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n", | ||
3189 | patch[dev]); | ||
3190 | err = request_firmware(&chip->fw, patch[dev], &pci->dev); | ||
3191 | if (err < 0) | ||
3192 | goto out_free; | ||
3193 | } | ||
3194 | #endif /* CONFIG_SND_HDA_PATCH_LOADER */ | ||
3195 | |||
3178 | if (!chip->disabled) { | 3196 | if (!chip->disabled) { |
3179 | err = azx_probe_continue(chip); | 3197 | err = azx_probe_continue(chip); |
3180 | if (err < 0) | 3198 | if (err < 0) |
@@ -3205,12 +3223,13 @@ static int DELAYED_INIT_MARK azx_probe_continue(struct azx *chip) | |||
3205 | if (err < 0) | 3223 | if (err < 0) |
3206 | goto out_free; | 3224 | goto out_free; |
3207 | #ifdef CONFIG_SND_HDA_PATCH_LOADER | 3225 | #ifdef CONFIG_SND_HDA_PATCH_LOADER |
3208 | if (patch[dev] && *patch[dev]) { | 3226 | if (chip->fw) { |
3209 | snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n", | 3227 | err = snd_hda_load_patch(chip->bus, chip->fw->size, |
3210 | patch[dev]); | 3228 | chip->fw->data); |
3211 | err = snd_hda_load_patch(chip->bus, patch[dev]); | ||
3212 | if (err < 0) | 3229 | if (err < 0) |
3213 | goto out_free; | 3230 | goto out_free; |
3231 | release_firmware(chip->fw); /* no longer needed */ | ||
3232 | chip->fw = NULL; | ||
3214 | } | 3233 | } |
3215 | #endif | 3234 | #endif |
3216 | if ((probe_only[dev] & 1) == 0) { | 3235 | if ((probe_only[dev] & 1) == 0) { |