ALSA: emu10k1: remove superfluous IRQ enable state saving

The mixer, PCM prepare, MIDI, synth driver, and procfs callbacks are all
always invoked with IRQs enabled, so there is no point in saving the
state.

snd_emu1010_load_firmware_entry() is called from emu1010_firmware_work()
and snd_emu10k1_emu1010_init(); the latter from snd_emu10k1_create() and
snd_emu10k1_resume(), all of which have IRQs enabled.

The voice and memory functions are called from mixed contexts, so they
keep the state saving.

The low-level functions all keep the state saving, because it's not
feasible to keep track of what is called where.

Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Link: https://lore.kernel.org/r/20230712145750.125086-2-oswald.buddenhagen@gmx.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Oswald Buddenhagen 2023-07-12 16:57:49 +02:00 committed by Takashi Iwai
parent deb1200f6e
commit 67192cc0f0
6 changed files with 47 additions and 69 deletions

View file

@ -667,7 +667,6 @@ static int snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu,
u16 reg;
u8 value;
__always_unused u16 write_post;
unsigned long flags;
if (!fw_entry)
return -EIO;
@ -679,7 +678,7 @@ static int snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu,
* GPIO5 -> FPGA DIN
* FPGA CONFIG OFF -> FPGA PGMN
*/
spin_lock_irqsave(&emu->emu_lock, flags);
spin_lock_irq(&emu->emu_lock);
outw(0x00, emu->port + A_GPIO); /* Set PGMN low for 100uS. */
write_post = inw(emu->port + A_GPIO);
udelay(100);
@ -702,7 +701,7 @@ static int snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu,
/* After programming, set GPIO bit 4 high again. */
outw(0x10, emu->port + A_GPIO);
write_post = inw(emu->port + A_GPIO);
spin_unlock_irqrestore(&emu->emu_lock, flags);
spin_unlock_irq(&emu->emu_lock);
return 0;
}

View file

@ -22,7 +22,6 @@ static int snd_emu10k1_synth_probe(struct device *_dev)
struct snd_emux *emux;
struct snd_emu10k1 *hw;
struct snd_emu10k1_synth_arg *arg;
unsigned long flags;
arg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
if (arg == NULL)
@ -56,10 +55,10 @@ static int snd_emu10k1_synth_probe(struct device *_dev)
return -ENOMEM;
}
spin_lock_irqsave(&hw->voice_lock, flags);
spin_lock_irq(&hw->voice_lock);
hw->synth = emux;
hw->get_synth_voice = snd_emu10k1_synth_get_voice;
spin_unlock_irqrestore(&hw->voice_lock, flags);
spin_unlock_irq(&hw->voice_lock);
dev->driver_data = emux;
@ -71,7 +70,6 @@ static int snd_emu10k1_synth_remove(struct device *_dev)
struct snd_seq_device *dev = to_seq_dev(_dev);
struct snd_emux *emux;
struct snd_emu10k1 *hw;
unsigned long flags;
if (dev->driver_data == NULL)
return 0; /* not registered actually */
@ -79,10 +77,10 @@ static int snd_emu10k1_synth_remove(struct device *_dev)
emux = dev->driver_data;
hw = emux->hw;
spin_lock_irqsave(&hw->voice_lock, flags);
spin_lock_irq(&hw->voice_lock);
hw->synth = NULL;
hw->get_synth_voice = NULL;
spin_unlock_irqrestore(&hw->voice_lock, flags);
spin_unlock_irq(&hw->voice_lock);
snd_emux_free(emux);
return 0;

View file

@ -1193,7 +1193,6 @@ static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
unsigned int ngain, ogain;
u16 gpio;
int change = 0;
unsigned long flags;
u32 source;
/* If the capture source has changed,
* update the capture volume from the cached value
@ -1207,13 +1206,13 @@ static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
change = (emu->i2c_capture_source != source_id);
if (change) {
snd_emu10k1_i2c_write(emu, ADC_MUX, 0); /* Mute input */
spin_lock_irqsave(&emu->emu_lock, flags);
spin_lock_irq(&emu->emu_lock);
gpio = inw(emu->port + A_IOCFG);
if (source_id==0)
outw(gpio | 0x4, emu->port + A_IOCFG);
else
outw(gpio & ~0x4, emu->port + A_IOCFG);
spin_unlock_irqrestore(&emu->emu_lock, flags);
spin_unlock_irq(&emu->emu_lock);
ngain = emu->i2c_capture_volume[source_id][0]; /* Left */
ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
@ -1357,7 +1356,6 @@ static int snd_audigy_spdif_output_rate_put(struct snd_kcontrol *kcontrol,
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
int change;
unsigned int reg, val, tmp;
unsigned long flags;
switch(ucontrol->value.enumerated.item[0]) {
case 0:
@ -1375,14 +1373,14 @@ static int snd_audigy_spdif_output_rate_put(struct snd_kcontrol *kcontrol,
}
spin_lock_irqsave(&emu->reg_lock, flags);
spin_lock_irq(&emu->reg_lock);
reg = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
tmp = reg & ~A_SPDIF_RATE_MASK;
tmp |= val;
change = (tmp != reg);
if (change)
snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
spin_unlock_irqrestore(&emu->reg_lock, flags);
spin_unlock_irq(&emu->reg_lock);
return change;
}
@ -1499,7 +1497,6 @@ static int snd_emu10k1_send_routing_get(struct snd_kcontrol *kcontrol,
static int snd_emu10k1_send_routing_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
unsigned long flags;
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
struct snd_emu10k1_pcm_mixer *mix =
&emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
@ -1507,7 +1504,7 @@ static int snd_emu10k1_send_routing_put(struct snd_kcontrol *kcontrol,
int num_efx = emu->audigy ? 8 : 4;
int mask = emu->audigy ? 0x3f : 0x0f;
spin_lock_irqsave(&emu->reg_lock, flags);
spin_lock_irq(&emu->reg_lock);
for (voice = 0; voice < 3; voice++)
for (idx = 0; idx < num_efx; idx++) {
val = ucontrol->value.integer.value[(voice * num_efx) + idx] & mask;
@ -1527,7 +1524,7 @@ static int snd_emu10k1_send_routing_put(struct snd_kcontrol *kcontrol,
&mix->send_routing[0][0]);
}
}
spin_unlock_irqrestore(&emu->reg_lock, flags);
spin_unlock_irq(&emu->reg_lock);
return change;
}
@ -1569,14 +1566,13 @@ static int snd_emu10k1_send_volume_get(struct snd_kcontrol *kcontrol,
static int snd_emu10k1_send_volume_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
unsigned long flags;
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
struct snd_emu10k1_pcm_mixer *mix =
&emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
int change = 0, idx, val;
int num_efx = emu->audigy ? 8 : 4;
spin_lock_irqsave(&emu->reg_lock, flags);
spin_lock_irq(&emu->reg_lock);
for (idx = 0; idx < 3*num_efx; idx++) {
val = ucontrol->value.integer.value[idx] & 255;
if (mix->send_volume[idx/num_efx][idx%num_efx] != val) {
@ -1595,7 +1591,7 @@ static int snd_emu10k1_send_volume_put(struct snd_kcontrol *kcontrol,
&mix->send_volume[0][0]);
}
}
spin_unlock_irqrestore(&emu->reg_lock, flags);
spin_unlock_irq(&emu->reg_lock);
return change;
}
@ -1635,13 +1631,12 @@ static int snd_emu10k1_attn_get(struct snd_kcontrol *kcontrol,
static int snd_emu10k1_attn_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
unsigned long flags;
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
struct snd_emu10k1_pcm_mixer *mix =
&emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
int change = 0, idx, val;
spin_lock_irqsave(&emu->reg_lock, flags);
spin_lock_irq(&emu->reg_lock);
for (idx = 0; idx < 3; idx++) {
unsigned uval = ucontrol->value.integer.value[idx] & 0x1ffff;
val = uval * 0x8000U / 0xffffU;
@ -1658,7 +1653,7 @@ static int snd_emu10k1_attn_put(struct snd_kcontrol *kcontrol,
snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[0]);
}
}
spin_unlock_irqrestore(&emu->reg_lock, flags);
spin_unlock_irq(&emu->reg_lock);
return change;
}
@ -1704,7 +1699,6 @@ static int snd_emu10k1_efx_send_routing_get(struct snd_kcontrol *kcontrol,
static int snd_emu10k1_efx_send_routing_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
unsigned long flags;
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];
@ -1712,7 +1706,7 @@ static int snd_emu10k1_efx_send_routing_put(struct snd_kcontrol *kcontrol,
int num_efx = emu->audigy ? 8 : 4;
int mask = emu->audigy ? 0x3f : 0x0f;
spin_lock_irqsave(&emu->reg_lock, flags);
spin_lock_irq(&emu->reg_lock);
for (idx = 0; idx < num_efx; idx++) {
val = ucontrol->value.integer.value[idx] & mask;
if (mix->send_routing[0][idx] != val) {
@ -1727,7 +1721,7 @@ static int snd_emu10k1_efx_send_routing_put(struct snd_kcontrol *kcontrol,
&mix->send_routing[0][0]);
}
}
spin_unlock_irqrestore(&emu->reg_lock, flags);
spin_unlock_irq(&emu->reg_lock);
return change;
}
@ -1769,14 +1763,13 @@ static int snd_emu10k1_efx_send_volume_get(struct snd_kcontrol *kcontrol,
static int snd_emu10k1_efx_send_volume_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
unsigned long flags;
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];
int change = 0, idx, val;
int num_efx = emu->audigy ? 8 : 4;
spin_lock_irqsave(&emu->reg_lock, flags);
spin_lock_irq(&emu->reg_lock);
for (idx = 0; idx < num_efx; idx++) {
val = ucontrol->value.integer.value[idx] & 255;
if (mix->send_volume[0][idx] != val) {
@ -1790,7 +1783,7 @@ static int snd_emu10k1_efx_send_volume_put(struct snd_kcontrol *kcontrol,
&mix->send_volume[0][0]);
}
}
spin_unlock_irqrestore(&emu->reg_lock, flags);
spin_unlock_irq(&emu->reg_lock);
return change;
}
@ -1829,14 +1822,13 @@ static int snd_emu10k1_efx_attn_get(struct snd_kcontrol *kcontrol,
static int snd_emu10k1_efx_attn_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
unsigned long flags;
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];
int change = 0, val;
unsigned uval;
spin_lock_irqsave(&emu->reg_lock, flags);
spin_lock_irq(&emu->reg_lock);
uval = ucontrol->value.integer.value[0] & 0x1ffff;
val = uval * 0x8000U / 0xffffU;
if (mix->attn[0] != val) {
@ -1848,7 +1840,7 @@ static int snd_emu10k1_efx_attn_put(struct snd_kcontrol *kcontrol,
snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[ch]->number, mix->attn[0]);
}
}
spin_unlock_irqrestore(&emu->reg_lock, flags);
spin_unlock_irq(&emu->reg_lock);
return change;
}
@ -1884,7 +1876,6 @@ static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol,
static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
unsigned long flags;
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
unsigned int reg, val, sw;
int change = 0;
@ -1892,7 +1883,7 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol,
sw = ucontrol->value.integer.value[0];
if (emu->card_capabilities->invert_shared_spdif)
sw = !sw;
spin_lock_irqsave(&emu->emu_lock, flags);
spin_lock_irq(&emu->emu_lock);
if ( emu->card_capabilities->i2c_adc) {
/* Do nothing for Audigy 2 ZS Notebook */
} else if (emu->audigy) {
@ -1913,7 +1904,7 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol,
reg |= val;
outl(reg | val, emu->port + HCFG);
}
spin_unlock_irqrestore(&emu->emu_lock, flags);
spin_unlock_irq(&emu->emu_lock);
return change;
}

View file

@ -104,10 +104,9 @@ static void snd_emu10k1_midi_interrupt2(struct snd_emu10k1 *emu, unsigned int st
static int snd_emu10k1_midi_cmd(struct snd_emu10k1 * emu, struct snd_emu10k1_midi *midi, unsigned char cmd, int ack)
{
unsigned long flags;
int timeout, ok;
spin_lock_irqsave(&midi->input_lock, flags);
spin_lock_irq(&midi->input_lock);
mpu401_write_data(emu, midi, 0x00);
/* mpu401_clear_rx(emu, midi); */
@ -126,7 +125,7 @@ static int snd_emu10k1_midi_cmd(struct snd_emu10k1 * emu, struct snd_emu10k1_mid
} else {
ok = 1;
}
spin_unlock_irqrestore(&midi->input_lock, flags);
spin_unlock_irq(&midi->input_lock);
if (!ok) {
dev_err(emu->card->dev,
"midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
@ -142,22 +141,21 @@ static int snd_emu10k1_midi_input_open(struct snd_rawmidi_substream *substream)
{
struct snd_emu10k1 *emu;
struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
unsigned long flags;
emu = midi->emu;
if (snd_BUG_ON(!emu))
return -ENXIO;
spin_lock_irqsave(&midi->open_lock, flags);
spin_lock_irq(&midi->open_lock);
midi->midi_mode |= EMU10K1_MIDI_MODE_INPUT;
midi->substream_input = substream;
if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags);
spin_unlock_irq(&midi->open_lock);
if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))
goto error_out;
if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
goto error_out;
} else {
spin_unlock_irqrestore(&midi->open_lock, flags);
spin_unlock_irq(&midi->open_lock);
}
return 0;
@ -169,22 +167,21 @@ static int snd_emu10k1_midi_output_open(struct snd_rawmidi_substream *substream)
{
struct snd_emu10k1 *emu;
struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
unsigned long flags;
emu = midi->emu;
if (snd_BUG_ON(!emu))
return -ENXIO;
spin_lock_irqsave(&midi->open_lock, flags);
spin_lock_irq(&midi->open_lock);
midi->midi_mode |= EMU10K1_MIDI_MODE_OUTPUT;
midi->substream_output = substream;
if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags);
spin_unlock_irq(&midi->open_lock);
if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))
goto error_out;
if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
goto error_out;
} else {
spin_unlock_irqrestore(&midi->open_lock, flags);
spin_unlock_irq(&midi->open_lock);
}
return 0;
@ -196,21 +193,20 @@ static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream)
{
struct snd_emu10k1 *emu;
struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
unsigned long flags;
int err = 0;
emu = midi->emu;
if (snd_BUG_ON(!emu))
return -ENXIO;
spin_lock_irqsave(&midi->open_lock, flags);
spin_lock_irq(&midi->open_lock);
snd_emu10k1_intr_disable(emu, midi->rx_enable);
midi->midi_mode &= ~EMU10K1_MIDI_MODE_INPUT;
midi->substream_input = NULL;
if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags);
spin_unlock_irq(&midi->open_lock);
err = snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
} else {
spin_unlock_irqrestore(&midi->open_lock, flags);
spin_unlock_irq(&midi->open_lock);
}
return err;
}
@ -219,21 +215,20 @@ static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream
{
struct snd_emu10k1 *emu;
struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
unsigned long flags;
int err = 0;
emu = midi->emu;
if (snd_BUG_ON(!emu))
return -ENXIO;
spin_lock_irqsave(&midi->open_lock, flags);
spin_lock_irq(&midi->open_lock);
snd_emu10k1_intr_disable(emu, midi->tx_enable);
midi->midi_mode &= ~EMU10K1_MIDI_MODE_OUTPUT;
midi->substream_output = NULL;
if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
spin_unlock_irqrestore(&midi->open_lock, flags);
spin_unlock_irq(&midi->open_lock);
err = snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
} else {
spin_unlock_irqrestore(&midi->open_lock, flags);
spin_unlock_irq(&midi->open_lock);
}
return err;
}
@ -256,7 +251,6 @@ static void snd_emu10k1_midi_output_trigger(struct snd_rawmidi_substream *substr
{
struct snd_emu10k1 *emu;
struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
unsigned long flags;
emu = midi->emu;
if (snd_BUG_ON(!emu))
@ -267,13 +261,13 @@ static void snd_emu10k1_midi_output_trigger(struct snd_rawmidi_substream *substr
unsigned char byte;
/* try to send some amount of bytes here before interrupts */
spin_lock_irqsave(&midi->output_lock, flags);
spin_lock_irq(&midi->output_lock);
while (max > 0) {
if (mpu401_output_ready(emu, midi)) {
if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT) ||
snd_rawmidi_transmit(substream, &byte, 1) != 1) {
/* no more data */
spin_unlock_irqrestore(&midi->output_lock, flags);
spin_unlock_irq(&midi->output_lock);
return;
}
mpu401_write_data(emu, midi, byte);
@ -282,7 +276,7 @@ static void snd_emu10k1_midi_output_trigger(struct snd_rawmidi_substream *substr
break;
}
}
spin_unlock_irqrestore(&midi->output_lock, flags);
spin_unlock_irq(&midi->output_lock);
snd_emu10k1_intr_enable(emu, midi->tx_enable);
} else {
snd_emu10k1_intr_disable(emu, midi->tx_enable);

View file

@ -343,9 +343,7 @@ static void snd_emu10k1_pcm_init_voices(struct snd_emu10k1 *emu,
unsigned int end_addr,
struct snd_emu10k1_pcm_mixer *mix)
{
unsigned long flags;
spin_lock_irqsave(&emu->reg_lock, flags);
spin_lock_irq(&emu->reg_lock);
snd_emu10k1_pcm_init_voice(emu, evoice, w_16, stereo,
start_addr, end_addr,
&mix->send_routing[stereo][0],
@ -355,7 +353,7 @@ static void snd_emu10k1_pcm_init_voices(struct snd_emu10k1 *emu,
start_addr, end_addr,
&mix->send_routing[2][0],
&mix->send_volume[2][0]);
spin_unlock_irqrestore(&emu->reg_lock, flags);
spin_unlock_irq(&emu->reg_lock);
}
static void snd_emu10k1_pcm_init_extra_voice(struct snd_emu10k1 *emu,

View file

@ -536,15 +536,14 @@ static unsigned int snd_ptr_read(struct snd_emu10k1 * emu,
unsigned int reg,
unsigned int chn)
{
unsigned long flags;
unsigned int regptr, val;
regptr = (reg << 16) | chn;
spin_lock_irqsave(&emu->emu_lock, flags);
spin_lock_irq(&emu->emu_lock);
outl(regptr, emu->port + iobase + PTR);
val = inl(emu->port + iobase + DATA);
spin_unlock_irqrestore(&emu->emu_lock, flags);
spin_unlock_irq(&emu->emu_lock);
return val;
}
@ -555,14 +554,13 @@ static void snd_ptr_write(struct snd_emu10k1 *emu,
unsigned int data)
{
unsigned int regptr;
unsigned long flags;
regptr = (reg << 16) | chn;
spin_lock_irqsave(&emu->emu_lock, flags);
spin_lock_irq(&emu->emu_lock);
outl(regptr, emu->port + iobase + PTR);
outl(data, emu->port + iobase + DATA);
spin_unlock_irqrestore(&emu->emu_lock, flags);
spin_unlock_irq(&emu->emu_lock);
}