aboutsummaryrefslogtreecommitdiffstats
path: root/sound/drivers/mpu401/mpu401_uart.c
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2007-11-12 02:47:57 -0500
committerJaroslav Kysela <perex@perex.cz>2007-11-19 12:38:32 -0500
commit60fac85fffc74cdd2fbdae821f269594ca25b6b1 (patch)
tree9a5efc7e166f033ce5d3fe4c579f75b4cf9f09a7 /sound/drivers/mpu401/mpu401_uart.c
parent56c36ca3b2df3ad8f2a3b7d3fba3670695163aaa (diff)
[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>
Diffstat (limited to 'sound/drivers/mpu401/mpu401_uart.c')
-rw-r--r--sound/drivers/mpu401/mpu401_uart.c12
1 files changed, 8 insertions, 4 deletions
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)
97 97
98static void uart_interrupt_tx(struct snd_mpu401 *mpu) 98static void uart_interrupt_tx(struct snd_mpu401 *mpu)
99{ 99{
100 unsigned long flags;
101
100 if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) && 102 if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) &&
101 test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) { 103 test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) {
102 spin_lock(&mpu->output_lock); 104 spin_lock_irqsave(&mpu->output_lock, flags);
103 snd_mpu401_uart_output_write(mpu); 105 snd_mpu401_uart_output_write(mpu);
104 spin_unlock(&mpu->output_lock); 106 spin_unlock_irqrestore(&mpu->output_lock, flags);
105 } 107 }
106} 108}
107 109
108static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu) 110static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
109{ 111{
112 unsigned long flags;
113
110 if (mpu->info_flags & MPU401_INFO_INPUT) { 114 if (mpu->info_flags & MPU401_INFO_INPUT) {
111 spin_lock(&mpu->input_lock); 115 spin_lock_irqsave(&mpu->input_lock, flags);
112 if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) 116 if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode))
113 snd_mpu401_uart_input_read(mpu); 117 snd_mpu401_uart_input_read(mpu);
114 else 118 else
115 snd_mpu401_uart_clear_rx(mpu); 119 snd_mpu401_uart_clear_rx(mpu);
116 spin_unlock(&mpu->input_lock); 120 spin_unlock_irqrestore(&mpu->input_lock, flags);
117 } 121 }
118 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) 122 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
119 /* ok. for better Tx performance try do some output 123 /* ok. for better Tx performance try do some output