diff options
author | Linux Build Service Account <lnxbuild@quicinc.com> | 2017-05-26 06:31:07 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-05-26 06:31:06 -0700 |
commit | 4267fd253df0e8845b57bddc3c7d083f3b9eb7ae (patch) | |
tree | 0d635c34dc5f01ea550b5a49c08df88d9e210ec5 /drivers/usb | |
parent | b52ce7f7b9c5ebe517f5cf67d7c21c2a5a3be6f5 (diff) | |
parent | a510e932e4f77fa5f5d01c4223c3d2fb2f3a88c7 (diff) |
Merge "usb: gadget: Fix synchronization issue between f_audio_source"
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/function/f_audio_source.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/usb/gadget/function/f_audio_source.c b/drivers/usb/gadget/function/f_audio_source.c index 51ab794ef6f9..ab7441fcf66f 100644 --- a/drivers/usb/gadget/function/f_audio_source.c +++ b/drivers/usb/gadget/function/f_audio_source.c @@ -369,15 +369,22 @@ static void audio_send(struct audio_dev *audio) s64 msecs; s64 frames; ktime_t now; + unsigned long flags; + spin_lock_irqsave(&audio->lock, flags); /* audio->substream will be null if we have been closed */ - if (!audio->substream) + if (!audio->substream) { + spin_unlock_irqrestore(&audio->lock, flags); return; + } /* audio->buffer_pos will be null if we have been stopped */ - if (!audio->buffer_pos) + if (!audio->buffer_pos) { + spin_unlock_irqrestore(&audio->lock, flags); return; + } runtime = audio->substream->runtime; + spin_unlock_irqrestore(&audio->lock, flags); /* compute number of frames to send */ now = ktime_get(); @@ -400,8 +407,21 @@ static void audio_send(struct audio_dev *audio) while (frames > 0) { req = audio_req_get(audio); - if (!req) + spin_lock_irqsave(&audio->lock, flags); + /* audio->substream will be null if we have been closed */ + if (!audio->substream) { + spin_unlock_irqrestore(&audio->lock, flags); + return; + } + /* audio->buffer_pos will be null if we have been stopped */ + if (!audio->buffer_pos) { + spin_unlock_irqrestore(&audio->lock, flags); + return; + } + if (!req) { + spin_unlock_irqrestore(&audio->lock, flags); break; + } length = frames_to_bytes(runtime, frames); if (length > IN_EP_MAX_PACKET_SIZE) @@ -427,6 +447,7 @@ static void audio_send(struct audio_dev *audio) } req->length = length; + spin_unlock_irqrestore(&audio->lock, flags); ret = usb_ep_queue(audio->in_ep, req, GFP_ATOMIC); if (ret < 0) { pr_err("usb_ep_queue failed ret: %d\n", ret); |