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

Commit 60fac85f authored by Clemens Ladisch's avatar Clemens Ladisch Committed by Jaroslav Kysela
Browse files

[ALSA] mpu401: fix recursive locking in timer



When the output and input ports are used at the same time, the timer can
be interrupted by the hardware interrupt, so we have to disable
interrupts when we take a lock in the timer.

Signed-off-by: default avatarClemens Ladisch <clemens@ladisch.de>
Signed-off-by: default avatarJaroslav Kysela <perex@perex.cz>
parent 56c36ca3
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -97,23 +97,27 @@ static void snd_mpu401_uart_clear_rx(struct snd_mpu401 *mpu)

static void uart_interrupt_tx(struct snd_mpu401 *mpu)
{
	unsigned long flags;

	if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) &&
	    test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) {
		spin_lock(&mpu->output_lock);
		spin_lock_irqsave(&mpu->output_lock, flags);
		snd_mpu401_uart_output_write(mpu);
		spin_unlock(&mpu->output_lock);
		spin_unlock_irqrestore(&mpu->output_lock, flags);
	}
}

static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
{
	unsigned long flags;

	if (mpu->info_flags & MPU401_INFO_INPUT) {
		spin_lock(&mpu->input_lock);
		spin_lock_irqsave(&mpu->input_lock, flags);
		if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode))
			snd_mpu401_uart_input_read(mpu);
		else
			snd_mpu401_uart_clear_rx(mpu);
		spin_unlock(&mpu->input_lock);
		spin_unlock_irqrestore(&mpu->input_lock, flags);
	}
	if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
		/* ok. for better Tx performance try do some output