瀏覽代碼

[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 <clemens@ladisch.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Clemens Ladisch 18 年之前
父節點
當前提交
60fac85fff
共有 1 個文件被更改,包括 8 次插入4 次删除
  1. 8 4
      sound/drivers/mpu401/mpu401_uart.c

+ 8 - 4
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