ALSA: Echoaudio - Add firmware cache #2
authorGiuliano Pochini <pochini@shiny.it>
Sun, 14 Feb 2010 17:15:51 +0000 (18:15 +0100)
committerTakashi Iwai <tiwai@suse.de>
Mon, 15 Feb 2010 09:38:10 +0000 (10:38 +0100)
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>
sound/pci/echoaudio/echoaudio.c
sound/pci/echoaudio/echoaudio.h

index 78fc2637bfa6f5820efa19ccaefd75425ee0b43a..79dde9592847cb361cc833b954651fc2234c0ead 100644 (file)
@@ -43,12 +43,24 @@ static int get_firmware(const struct firmware **fw_entry,
 {
        int err;
        char name[30];
-       const struct firmware *frm = &card_fw[fw_index];
 
-       DE_ACT(("firmware requested: %s\n", frm->data));
-       snprintf(name, sizeof(name), "ea/%s", frm->data);
-       if ((err = request_firmware(fw_entry, name, pci_device(chip))) < 0)
+#ifdef CONFIG_PM
+       if (chip->fw_cache[fw_index]) {
+               DE_ACT(("firmware requested: %s is cached\n", card_fw[fw_index].data));
+               *fw_entry = chip->fw_cache[fw_index];
+               return 0;
+       }
+#endif
+
+       DE_ACT(("firmware requested: %s\n", card_fw[fw_index].data));
+       snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data);
+       err = request_firmware(fw_entry, name, pci_device(chip));
+       if (err < 0)
                snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err);
+#ifdef CONFIG_PM
+       else
+               chip->fw_cache[fw_index] = *fw_entry;
+#endif
        return err;
 }
 
@@ -56,8 +68,29 @@ static int get_firmware(const struct firmware **fw_entry,
 
 static void free_firmware(const struct firmware *fw_entry)
 {
+#ifdef CONFIG_PM
+       DE_ACT(("firmware not released (kept in cache)\n"));
+#else
        release_firmware(fw_entry);
        DE_ACT(("firmware released\n"));
+#endif
+}
+
+
+
+static void free_firmware_cache(struct echoaudio *chip)
+{
+#ifdef CONFIG_PM
+       int i;
+
+       for (i = 0; i < 8 ; i++)
+               if (chip->fw_cache[i]) {
+                       release_firmware(chip->fw_cache[i]);
+                       DE_ACT(("release_firmware(%d)\n", i));
+               }
+
+       DE_ACT(("firmware_cache released\n"));
+#endif
 }
 
 
@@ -1880,6 +1913,7 @@ static int snd_echo_free(struct echoaudio *chip)
        pci_disable_device(chip->pci);
 
        /* release chip data */
+       free_firmware_cache(chip);
        kfree(chip);
        DE_INIT(("Chip freed.\n"));
        return 0;
index be76ef3b829a6f15a5429ec5a1d83aadcea36d10..a84c0d15cc502fe51b530ba39d88de3efe47651c 100644 (file)
@@ -449,6 +449,9 @@ struct echoaudio {
        volatile u32 __iomem *dsp_registers;    /* DSP's register base */
        u32 active_mask;                        /* Chs. active mask or
                                                 * punks out */
+#ifdef CONFIG_PM
+       const struct firmware *fw_cache[8];     /* Cached firmwares */
+#endif
 
 #ifdef ECHOCARD_HAS_MIDI
        u16 mtc_state;                          /* State for MIDI input parsing state machine */