From 60fac85fffc74cdd2fbdae821f269594ca25b6b1 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 12 Nov 2007 08:47:57 +0100 Subject: [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: Clemens Ladisch Signed-off-by: Jaroslav Kysela --- sound/drivers/mpu401/mpu401_uart.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'sound/drivers') diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c index 3306ecd49243..b57f2d5a1c9d 100644 --- a/sound/drivers/mpu401/mpu401_uart.c +++ b/sound/drivers/mpu401/mpu401_uart.c @@ -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 -- cgit v1.2.3