From a4733b5248af10d5088ba06495e3faad9f7822b3 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 10 Jul 2018 12:18:31 -0400 Subject: [PATCH] media: go7007: 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: Hans Verkuil Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/go7007/go7007-driver.c | 9 +++++---- drivers/media/usb/go7007/snd-go7007.c | 11 ++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/media/usb/go7007/go7007-driver.c b/drivers/media/usb/go7007/go7007-driver.c index 05b1126..62aeebc 100644 --- a/drivers/media/usb/go7007/go7007-driver.c +++ b/drivers/media/usb/go7007/go7007-driver.c @@ -448,13 +448,14 @@ static struct go7007_buffer *frame_boundary(struct go7007 *go, struct go7007_buf { u32 *bytesused; struct go7007_buffer *vb_tmp = NULL; + unsigned long flags; if (vb == NULL) { - spin_lock(&go->spinlock); + spin_lock_irqsave(&go->spinlock, flags); if (!list_empty(&go->vidq_active)) vb = go->active_buf = list_first_entry(&go->vidq_active, struct go7007_buffer, list); - spin_unlock(&go->spinlock); + spin_unlock_irqrestore(&go->spinlock, flags); go->next_seq++; return vb; } @@ -468,7 +469,7 @@ static struct go7007_buffer *frame_boundary(struct go7007 *go, struct go7007_buf vb->vb.vb2_buf.timestamp = ktime_get_ns(); vb_tmp = vb; - spin_lock(&go->spinlock); + spin_lock_irqsave(&go->spinlock, flags); list_del(&vb->list); if (list_empty(&go->vidq_active)) vb = NULL; @@ -476,7 +477,7 @@ static struct go7007_buffer *frame_boundary(struct go7007 *go, struct go7007_buf vb = list_first_entry(&go->vidq_active, struct go7007_buffer, list); go->active_buf = vb; - spin_unlock(&go->spinlock); + spin_unlock_irqrestore(&go->spinlock, flags); vb2_buffer_done(&vb_tmp->vb.vb2_buf, VB2_BUF_STATE_DONE); return vb; } diff --git a/drivers/media/usb/go7007/snd-go7007.c b/drivers/media/usb/go7007/snd-go7007.c index f84a213..137fc25 100644 --- a/drivers/media/usb/go7007/snd-go7007.c +++ b/drivers/media/usb/go7007/snd-go7007.c @@ -75,13 +75,14 @@ static void parse_audio_stream_data(struct go7007 *go, u8 *buf, int length) struct go7007_snd *gosnd = go->snd_context; struct snd_pcm_runtime *runtime = gosnd->substream->runtime; int frames = bytes_to_frames(runtime, length); + unsigned long flags; - spin_lock(&gosnd->lock); + spin_lock_irqsave(&gosnd->lock, flags); gosnd->hw_ptr += frames; if (gosnd->hw_ptr >= runtime->buffer_size) gosnd->hw_ptr -= runtime->buffer_size; gosnd->avail += frames; - spin_unlock(&gosnd->lock); + spin_unlock_irqrestore(&gosnd->lock, flags); if (gosnd->w_idx + length > runtime->dma_bytes) { int cpy = runtime->dma_bytes - gosnd->w_idx; @@ -92,13 +93,13 @@ static void parse_audio_stream_data(struct go7007 *go, u8 *buf, int length) } memcpy(runtime->dma_area + gosnd->w_idx, buf, length); gosnd->w_idx += length; - spin_lock(&gosnd->lock); + spin_lock_irqsave(&gosnd->lock, flags); if (gosnd->avail < runtime->period_size) { - spin_unlock(&gosnd->lock); + spin_unlock_irqrestore(&gosnd->lock, flags); return; } gosnd->avail -= runtime->period_size; - spin_unlock(&gosnd->lock); + spin_unlock_irqrestore(&gosnd->lock, flags); if (gosnd->capturing) snd_pcm_period_elapsed(gosnd->substream); } -- 2.7.4