aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2018-09-10 05:19:58 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-09-10 13:35:46 -0400
commit273925c777420585af1ca18548b73e730043576e (patch)
treedd2708688c56e437a9cc0893dc47c079c577b420
parent57361846b52bc686112da6ca5368d11210796804 (diff)
media: em28xx-audio: use irqsave() in USB's complete callback
The USB completion callback does not disable interrupts while acquiring the lock. We want to remove the local_irq_disable() invocation from __usb_hcd_giveback_urb() and therefore it is required for the callback handler to disable the interrupts while acquiring the lock. The callback may be invoked either in IRQ or BH context depending on the USB host controller. Use the _irqsave() variant of the locking primitives. Cc: Mauro Carvalho Chehab <mchehab@kernel.org> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Acked-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/media/usb/em28xx/em28xx-audio.c5
-rw-r--r--drivers/media/usb/em28xx/em28xx-core.c5
2 files changed, 6 insertions, 4 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c
index 8e799ae1df69..67481fc82445 100644
--- a/drivers/media/usb/em28xx/em28xx-audio.c
+++ b/drivers/media/usb/em28xx/em28xx-audio.c
@@ -116,6 +116,7 @@ static void em28xx_audio_isocirq(struct urb *urb)
116 stride = runtime->frame_bits >> 3; 116 stride = runtime->frame_bits >> 3;
117 117
118 for (i = 0; i < urb->number_of_packets; i++) { 118 for (i = 0; i < urb->number_of_packets; i++) {
119 unsigned long flags;
119 int length = 120 int length =
120 urb->iso_frame_desc[i].actual_length / stride; 121 urb->iso_frame_desc[i].actual_length / stride;
121 cp = (unsigned char *)urb->transfer_buffer + 122 cp = (unsigned char *)urb->transfer_buffer +
@@ -137,7 +138,7 @@ static void em28xx_audio_isocirq(struct urb *urb)
137 length * stride); 138 length * stride);
138 } 139 }
139 140
140 snd_pcm_stream_lock(substream); 141 snd_pcm_stream_lock_irqsave(substream, flags);
141 142
142 dev->adev.hwptr_done_capture += length; 143 dev->adev.hwptr_done_capture += length;
143 if (dev->adev.hwptr_done_capture >= 144 if (dev->adev.hwptr_done_capture >=
@@ -153,7 +154,7 @@ static void em28xx_audio_isocirq(struct urb *urb)
153 period_elapsed = 1; 154 period_elapsed = 1;
154 } 155 }
155 156
156 snd_pcm_stream_unlock(substream); 157 snd_pcm_stream_unlock_irqrestore(substream, flags);
157 } 158 }
158 if (period_elapsed) 159 if (period_elapsed)
159 snd_pcm_period_elapsed(substream); 160 snd_pcm_period_elapsed(substream);
diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c
index 5657f8710ca6..2b8c84a5c9a8 100644
--- a/drivers/media/usb/em28xx/em28xx-core.c
+++ b/drivers/media/usb/em28xx/em28xx-core.c
@@ -777,6 +777,7 @@ EXPORT_SYMBOL_GPL(em28xx_set_mode);
777static void em28xx_irq_callback(struct urb *urb) 777static void em28xx_irq_callback(struct urb *urb)
778{ 778{
779 struct em28xx *dev = urb->context; 779 struct em28xx *dev = urb->context;
780 unsigned long flags;
780 int i; 781 int i;
781 782
782 switch (urb->status) { 783 switch (urb->status) {
@@ -793,9 +794,9 @@ static void em28xx_irq_callback(struct urb *urb)
793 } 794 }
794 795
795 /* Copy data from URB */ 796 /* Copy data from URB */
796 spin_lock(&dev->slock); 797 spin_lock_irqsave(&dev->slock, flags);
797 dev->usb_ctl.urb_data_copy(dev, urb); 798 dev->usb_ctl.urb_data_copy(dev, urb);
798 spin_unlock(&dev->slock); 799 spin_unlock_irqrestore(&dev->slock, flags);
799 800
800 /* Reset urb buffers */ 801 /* Reset urb buffers */
801 for (i = 0; i < urb->number_of_packets; i++) { 802 for (i = 0; i < urb->number_of_packets; i++) {