diff options
author | Giuliano Pochini <pochini@shiny.it> | 2010-02-14 12:15:51 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-02-15 04:38:10 -0500 |
commit | 4f8ada444cc7a7ea70cdc81f098b34c5f1f2df41 (patch) | |
tree | ded4e81a8e822ee43bdcaab71084c7b0bd58701f /sound/pci/echoaudio/echoaudio.c | |
parent | 19b50063780953563e3c3a2867c39aad7b9e64cf (diff) |
ALSA: Echoaudio - Add firmware cache #2
This patch implements a simple cache for the firmware files when CONFIG_PM is defined.
This patch changes get_firmware(), free_firmware() and adds
free_firmware_cache(). The first two functions implement a very
simple cache and the latter is used to actually release all the stored
firmwares when the module is unloaded.
When CONFIG_PM is not enabled those functions act as before, that is
free_firmware() releases the firmware immediately and
free_firmware_cache() does nothing.
Signed-off-by: Giuliano Pochini <pochini@shiny.it>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/echoaudio/echoaudio.c')
-rw-r--r-- | sound/pci/echoaudio/echoaudio.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index 78fc2637bfa6..79dde9592847 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c | |||
@@ -43,12 +43,24 @@ static int get_firmware(const struct firmware **fw_entry, | |||
43 | { | 43 | { |
44 | int err; | 44 | int err; |
45 | char name[30]; | 45 | char name[30]; |
46 | const struct firmware *frm = &card_fw[fw_index]; | ||
47 | 46 | ||
48 | DE_ACT(("firmware requested: %s\n", frm->data)); | 47 | #ifdef CONFIG_PM |
49 | snprintf(name, sizeof(name), "ea/%s", frm->data); | 48 | if (chip->fw_cache[fw_index]) { |
50 | if ((err = request_firmware(fw_entry, name, pci_device(chip))) < 0) | 49 | DE_ACT(("firmware requested: %s is cached\n", card_fw[fw_index].data)); |
50 | *fw_entry = chip->fw_cache[fw_index]; | ||
51 | return 0; | ||
52 | } | ||
53 | #endif | ||
54 | |||
55 | DE_ACT(("firmware requested: %s\n", card_fw[fw_index].data)); | ||
56 | snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data); | ||
57 | err = request_firmware(fw_entry, name, pci_device(chip)); | ||
58 | if (err < 0) | ||
51 | snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err); | 59 | snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err); |
60 | #ifdef CONFIG_PM | ||
61 | else | ||
62 | chip->fw_cache[fw_index] = *fw_entry; | ||
63 | #endif | ||
52 | return err; | 64 | return err; |
53 | } | 65 | } |
54 | 66 | ||
@@ -56,8 +68,29 @@ static int get_firmware(const struct firmware **fw_entry, | |||
56 | 68 | ||
57 | static void free_firmware(const struct firmware *fw_entry) | 69 | static void free_firmware(const struct firmware *fw_entry) |
58 | { | 70 | { |
71 | #ifdef CONFIG_PM | ||
72 | DE_ACT(("firmware not released (kept in cache)\n")); | ||
73 | #else | ||
59 | release_firmware(fw_entry); | 74 | release_firmware(fw_entry); |
60 | DE_ACT(("firmware released\n")); | 75 | DE_ACT(("firmware released\n")); |
76 | #endif | ||
77 | } | ||
78 | |||
79 | |||
80 | |||
81 | static void free_firmware_cache(struct echoaudio *chip) | ||
82 | { | ||
83 | #ifdef CONFIG_PM | ||
84 | int i; | ||
85 | |||
86 | for (i = 0; i < 8 ; i++) | ||
87 | if (chip->fw_cache[i]) { | ||
88 | release_firmware(chip->fw_cache[i]); | ||
89 | DE_ACT(("release_firmware(%d)\n", i)); | ||
90 | } | ||
91 | |||
92 | DE_ACT(("firmware_cache released\n")); | ||
93 | #endif | ||
61 | } | 94 | } |
62 | 95 | ||
63 | 96 | ||
@@ -1880,6 +1913,7 @@ static int snd_echo_free(struct echoaudio *chip) | |||
1880 | pci_disable_device(chip->pci); | 1913 | pci_disable_device(chip->pci); |
1881 | 1914 | ||
1882 | /* release chip data */ | 1915 | /* release chip data */ |
1916 | free_firmware_cache(chip); | ||
1883 | kfree(chip); | 1917 | kfree(chip); |
1884 | DE_INIT(("Chip freed.\n")); | 1918 | DE_INIT(("Chip freed.\n")); |
1885 | return 0; | 1919 | return 0; |