diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-11-22 11:17:17 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-11-22 11:48:09 -0500 |
commit | b209c4dfcd960ab176d4746ab7dc442a3edb4575 (patch) | |
tree | 9c8f679c40a0543380baab32177bc441dba327b3 | |
parent | 90caaef6a1ce2ec6675b1dc5afd57767954ab7e8 (diff) |
ALSA: emu10k1: cache emu1010 firmware
Instead of calling request_firmware() at each time, keep the obtained
firmware internally and reuse it.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | include/sound/emu10k1.h | 3 | ||||
-rw-r--r-- | sound/pci/emu10k1/emu10k1_main.c | 88 |
2 files changed, 39 insertions, 52 deletions
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 3707288ae9bf..9dc94b559c7d 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <sound/timer.h> | 32 | #include <sound/timer.h> |
33 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
35 | #include <linux/firmware.h> | ||
35 | 36 | ||
36 | #include <asm/io.h> | 37 | #include <asm/io.h> |
37 | #include <uapi/sound/emu10k1.h> | 38 | #include <uapi/sound/emu10k1.h> |
@@ -1785,6 +1786,8 @@ struct snd_emu10k1 { | |||
1785 | unsigned int efx_voices_mask[2]; | 1786 | unsigned int efx_voices_mask[2]; |
1786 | unsigned int next_free_voice; | 1787 | unsigned int next_free_voice; |
1787 | 1788 | ||
1789 | const struct firmware *firmware; | ||
1790 | |||
1788 | #ifdef CONFIG_PM_SLEEP | 1791 | #ifdef CONFIG_PM_SLEEP |
1789 | unsigned int *saved_ptr; | 1792 | unsigned int *saved_ptr; |
1790 | unsigned int *saved_gpr; | 1793 | unsigned int *saved_gpr; |
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index c21adb6ef1d5..1dfb94d16b8b 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c | |||
@@ -657,22 +657,17 @@ static int snd_emu10k1_cardbus_init(struct snd_emu10k1 *emu) | |||
657 | return 0; | 657 | return 0; |
658 | } | 658 | } |
659 | 659 | ||
660 | static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu, const char *filename) | 660 | static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu) |
661 | { | 661 | { |
662 | int err; | ||
663 | int n, i; | 662 | int n, i; |
664 | int reg; | 663 | int reg; |
665 | int value; | 664 | int value; |
666 | unsigned int write_post; | 665 | unsigned int write_post; |
667 | unsigned long flags; | 666 | unsigned long flags; |
668 | const struct firmware *fw_entry; | 667 | const struct firmware *fw_entry = emu->firmware; |
669 | 668 | ||
670 | err = request_firmware(&fw_entry, filename, &emu->pci->dev); | 669 | if (!fw_entry) |
671 | if (err != 0) { | 670 | return -EIO; |
672 | snd_printk(KERN_ERR "firmware: %s not found. Err = %d\n", filename, err); | ||
673 | return err; | ||
674 | } | ||
675 | snd_printk(KERN_INFO "firmware size = 0x%zx\n", fw_entry->size); | ||
676 | 671 | ||
677 | /* The FPGA is a Xilinx Spartan IIE XC2S50E */ | 672 | /* The FPGA is a Xilinx Spartan IIE XC2S50E */ |
678 | /* GPIO7 -> FPGA PGMN | 673 | /* GPIO7 -> FPGA PGMN |
@@ -705,7 +700,6 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu, const char *filena | |||
705 | write_post = inl(emu->port + A_IOCFG); | 700 | write_post = inl(emu->port + A_IOCFG); |
706 | spin_unlock_irqrestore(&emu->emu_lock, flags); | 701 | spin_unlock_irqrestore(&emu->emu_lock, flags); |
707 | 702 | ||
708 | release_firmware(fw_entry); | ||
709 | return 0; | 703 | return 0; |
710 | } | 704 | } |
711 | 705 | ||
@@ -727,22 +721,9 @@ static int emu1010_firmware_thread(void *data) | |||
727 | /* Return to Audio Dock programming mode */ | 721 | /* Return to Audio Dock programming mode */ |
728 | snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); | 722 | snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); |
729 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK); | 723 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK); |
730 | if (emu->card_capabilities->emu_model == | 724 | err = snd_emu1010_load_firmware(emu); |
731 | EMU_MODEL_EMU1010) { | 725 | if (err != 0) |
732 | err = snd_emu1010_load_firmware(emu, DOCK_FILENAME); | 726 | continue; |
733 | if (err != 0) | ||
734 | continue; | ||
735 | } else if (emu->card_capabilities->emu_model == | ||
736 | EMU_MODEL_EMU1010B) { | ||
737 | err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME); | ||
738 | if (err != 0) | ||
739 | continue; | ||
740 | } else if (emu->card_capabilities->emu_model == | ||
741 | EMU_MODEL_EMU1616) { | ||
742 | err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME); | ||
743 | if (err != 0) | ||
744 | continue; | ||
745 | } | ||
746 | 727 | ||
747 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0); | 728 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0); |
748 | snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, ®); | 729 | snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, ®); |
@@ -807,7 +788,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) | |||
807 | unsigned int i; | 788 | unsigned int i; |
808 | u32 tmp, tmp2, reg; | 789 | u32 tmp, tmp2, reg; |
809 | int err; | 790 | int err; |
810 | const char *filename = NULL; | ||
811 | 791 | ||
812 | snd_printk(KERN_INFO "emu1010: Special config.\n"); | 792 | snd_printk(KERN_INFO "emu1010: Special config.\n"); |
813 | /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, | 793 | /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, |
@@ -849,31 +829,33 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) | |||
849 | return -ENODEV; | 829 | return -ENODEV; |
850 | } | 830 | } |
851 | snd_printk(KERN_INFO "emu1010: EMU_HANA_ID = 0x%x\n", reg); | 831 | snd_printk(KERN_INFO "emu1010: EMU_HANA_ID = 0x%x\n", reg); |
852 | switch (emu->card_capabilities->emu_model) { | 832 | |
853 | case EMU_MODEL_EMU1010: | 833 | if (!emu->firmware) { |
854 | filename = HANA_FILENAME; | 834 | const char *filename; |
855 | break; | 835 | switch (emu->card_capabilities->emu_model) { |
856 | case EMU_MODEL_EMU1010B: | 836 | case EMU_MODEL_EMU1010: |
857 | filename = EMU1010B_FILENAME; | 837 | filename = HANA_FILENAME; |
858 | break; | 838 | break; |
859 | case EMU_MODEL_EMU1616: | 839 | case EMU_MODEL_EMU1010B: |
860 | filename = EMU1010_NOTEBOOK_FILENAME; | 840 | filename = EMU1010B_FILENAME; |
861 | break; | 841 | break; |
862 | case EMU_MODEL_EMU0404: | 842 | case EMU_MODEL_EMU1616: |
863 | filename = EMU0404_FILENAME; | 843 | filename = EMU1010_NOTEBOOK_FILENAME; |
864 | break; | 844 | break; |
865 | default: | 845 | case EMU_MODEL_EMU0404: |
866 | filename = NULL; | 846 | filename = EMU0404_FILENAME; |
867 | return -ENODEV; | 847 | break; |
868 | break; | 848 | default: |
869 | } | 849 | return -ENODEV; |
870 | snd_printk(KERN_INFO "emu1010: filename %s testing\n", filename); | 850 | } |
871 | err = snd_emu1010_load_firmware(emu, filename); | 851 | |
872 | if (err != 0) { | 852 | err = request_firmware(&emu->firmware, filename, &emu->pci->dev); |
873 | snd_printk( | 853 | if (err != 0) { |
874 | KERN_INFO "emu1010: Loading Firmware file %s failed\n", | 854 | snd_printk(KERN_ERR "emu1010: firmware: %s not found. Err = %d\n", filename, err); |
875 | filename); | 855 | return err; |
876 | return err; | 856 | } |
857 | snd_printk(KERN_INFO "emu1010: firmware file = %s, size = 0x%zx\n", | ||
858 | filename, emu->firmware->size); | ||
877 | } | 859 | } |
878 | 860 | ||
879 | /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ | 861 | /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ |
@@ -1259,6 +1241,8 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu) | |||
1259 | } | 1241 | } |
1260 | if (emu->emu1010.firmware_thread) | 1242 | if (emu->emu1010.firmware_thread) |
1261 | kthread_stop(emu->emu1010.firmware_thread); | 1243 | kthread_stop(emu->emu1010.firmware_thread); |
1244 | if (emu->firmware) | ||
1245 | release_firmware(emu->firmware); | ||
1262 | if (emu->irq >= 0) | 1246 | if (emu->irq >= 0) |
1263 | free_irq(emu->irq, emu); | 1247 | free_irq(emu->irq, emu); |
1264 | /* remove reserved page */ | 1248 | /* remove reserved page */ |