Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b209c4df authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: emu10k1: cache emu1010 firmware



Instead of calling request_firmware() at each time, keep the obtained
firmware internally and reuse it.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 90caaef6
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include <sound/timer.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/firmware.h>

#include <asm/io.h>
#include <uapi/sound/emu10k1.h>
@@ -1785,6 +1786,8 @@ struct snd_emu10k1 {
	unsigned int efx_voices_mask[2];
	unsigned int next_free_voice;

	const struct firmware *firmware;

#ifdef CONFIG_PM_SLEEP
	unsigned int *saved_ptr;
	unsigned int *saved_gpr;
+36 −52
Original line number Diff line number Diff line
@@ -657,22 +657,17 @@ static int snd_emu10k1_cardbus_init(struct snd_emu10k1 *emu)
	return 0;
}

static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu, const char *filename)
static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu)
{
	int err;
	int n, i;
	int reg;
	int value;
	unsigned int write_post;
	unsigned long flags;
	const struct firmware *fw_entry;
	const struct firmware *fw_entry = emu->firmware;

	err = request_firmware(&fw_entry, filename, &emu->pci->dev);
	if (err != 0) {
		snd_printk(KERN_ERR "firmware: %s not found. Err = %d\n", filename, err);
		return err;
	}
	snd_printk(KERN_INFO "firmware size = 0x%zx\n", fw_entry->size);
	if (!fw_entry)
		return -EIO;

	/* The FPGA is a Xilinx Spartan IIE XC2S50E */
	/* GPIO7 -> FPGA PGMN
@@ -705,7 +700,6 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu, const char *filena
	write_post = inl(emu->port + A_IOCFG);
	spin_unlock_irqrestore(&emu->emu_lock, flags);

	release_firmware(fw_entry);
	return 0;
}

@@ -727,22 +721,9 @@ static int emu1010_firmware_thread(void *data)
			/* Return to Audio Dock programming mode */
			snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n");
			snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK);
			if (emu->card_capabilities->emu_model ==
			    EMU_MODEL_EMU1010) {
				err = snd_emu1010_load_firmware(emu, DOCK_FILENAME);
			err = snd_emu1010_load_firmware(emu);
			if (err != 0)
				continue;
			} else if (emu->card_capabilities->emu_model ==
				   EMU_MODEL_EMU1010B) {
				err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME);
				if (err != 0)
					continue;
			} else if (emu->card_capabilities->emu_model ==
				   EMU_MODEL_EMU1616) {
				err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME);
				if (err != 0)
					continue;
			}

			snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0);
			snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg);
@@ -807,7 +788,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
	unsigned int i;
	u32 tmp, tmp2, reg;
	int err;
	const char *filename = NULL;

	snd_printk(KERN_INFO "emu1010: Special config.\n");
	/* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
@@ -849,6 +829,9 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
		return -ENODEV;
	}
	snd_printk(KERN_INFO "emu1010: EMU_HANA_ID = 0x%x\n", reg);

	if (!emu->firmware) {
		const char *filename;
		switch (emu->card_capabilities->emu_model) {
		case EMU_MODEL_EMU1010:
			filename = HANA_FILENAME;
@@ -863,18 +846,17 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
			filename = EMU0404_FILENAME;
			break;
		default:
		filename = NULL;
			return -ENODEV;
		break;
		}
	snd_printk(KERN_INFO "emu1010: filename %s testing\n", filename);
	err = snd_emu1010_load_firmware(emu, filename);

		err = request_firmware(&emu->firmware, filename, &emu->pci->dev);
		if (err != 0) {
		snd_printk(
			KERN_INFO "emu1010: Loading Firmware file %s failed\n",
			filename);
			snd_printk(KERN_ERR "emu1010: firmware: %s not found. Err = %d\n", filename, err);
			return err;
		}
		snd_printk(KERN_INFO "emu1010: firmware file = %s, size = 0x%zx\n",
			   filename, emu->firmware->size);
	}

	/* ID, should read & 0x7f = 0x55 when FPGA programmed. */
	snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
@@ -1259,6 +1241,8 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu)
	}
	if (emu->emu1010.firmware_thread)
		kthread_stop(emu->emu1010.firmware_thread);
	if (emu->firmware)
		release_firmware(emu->firmware);
	if (emu->irq >= 0)
		free_irq(emu->irq, emu);
	/* remove reserved page */