diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2007-11-12 02:47:57 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2007-11-19 12:38:32 -0500 |
commit | 60fac85fffc74cdd2fbdae821f269594ca25b6b1 (patch) | |
tree | 9a5efc7e166f033ce5d3fe4c579f75b4cf9f09a7 /sound/drivers | |
parent | 56c36ca3b2df3ad8f2a3b7d3fba3670695163aaa (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')
-rw-r--r-- | sound/drivers/mpu401/mpu401_uart.c | 12 |
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 | ||
98 | static void uart_interrupt_tx(struct snd_mpu401 *mpu) | 98 | static 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 | ||
108 | static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu) | 110 | static 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 |