Patch "usb: gadget: udc: renesas_usb3: lock for PN_ registers access" has been added to the 4.9-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
usb: gadget: udc: renesas_usb3: lock for PN_ registers access
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
usb-gadget-udc-renesas_usb3-lock-for-pn_-registers-access.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
940f538a100c84c6e72813e4ac88bd1753a86945Mon Sep 17 00:00:00 2001
From: Yoshihiro Shimoda <[email protected]>
Date: Wed, 26 Apr 2017 20:50:09 +0900
Subject: usb: gadget: udc: renesas_usb3: lock for PN_ registers access
From: Yoshihiro Shimoda <[email protected]>
commit 940f538a100c84c6e72813e4ac88bd1753a86945 upstream.
This controller disallows to change the PIPE until reading/writing a packet finishes. However. the previous code is not enough to hold the lock in some functions. So, this patch fixes it.
--- drivers/usb/gadget/udc/renesas_usb3.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-)
drivers/usb/gadget/udc/renesas_usb3.c +25 -3
@@ -1401,7 +1401,13 @@ static void usb3_request_done_pipen(stru struct renesas_usb3_request *usb3_req, int status) { -usb3_pn_stop (usb3 ); +unsigned long flags; + +spin_lock_irqsave (&usb3->lock, flags); +if (usb3_pn_change (usb3, usb3_ep->num)) +usb3_pn_stop (usb3); +spin_unlock_irqrestore (&usb3->lock, flags); +usb3_disable_pipe_irq (usb3, usb3_ep->num);usb3_request_done (usb3_ep, usb3_req, status);
@@ -1430,30 +1436,46 @@ static void usb3_irq_epc_pipen_bfrdy(str {struct renesas_usb3_ep *usb3_ep =usb3_get_ep (usb3, num);struct renesas_usb3_request *usb3_req =usb3_get_request (usb3_ep); +bool done = false;if (!usb3_req)return ; +spin_lock (&usb3->lock); +if (usb3_pn_change (usb3, num)) + goto out; +if (usb3_ep->dir_in) {/* Do not stop the IN pipe here to detect LSTTR interrupt */ if (!usb3_write_pipe (usb3_ep, usb3_req,USB3_PN_WRITE ))usb3_clear_bit (usb3,PN_INT_BFRDY ,USB3_PN_INT_ENA ); }else {if (!usb3_read_pipe (usb3_ep, usb3_req,USB3_PN_READ )) -usb3_request_done_pipen (usb3, usb3_ep, usb3_req,0 ); + done = true; } + +out: +/* need to unlock because usb3_request_done_pipen() locks it */ +spin_unlock (&usb3->lock); + +if (done) +usb3_request_done_pipen (usb3, usb3_ep, usb3_req,0 ); }static void usb3_irq_epc_pipen (struct renesas_usb3 *usb3,int num) {u32 pn_int_sta; -if (usb3_pn_change (usb3, num) <0 ) +spin_lock (&usb3->lock); +if (usb3_pn_change (usb3, num) <0 ) { +spin_unlock (&usb3->lock);return ; + } pn_int_sta =usb3_read (usb3,USB3_PN_INT_STA ); pn_int_sta &=usb3_read (usb3,USB3_PN_INT_ENA );usb3_write (usb3, pn_int_sta,USB3_PN_INT_STA ); +spin_unlock (&usb3->lock);if (pn_int_sta &PN_INT_LSTTR )usb3_irq_epc_pipen_lsttr (usb3, num);if (pn_int_sta &PN_INT_BFRDY )
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/usb-gadget-udc-renesas_usb3-fix-deadlock-by-spinlock.patch queue-4.9/usb-gadget-udc-renesas_usb3-fix-pm_runtime-functions-calling.patch queue-4.9/usb-gadget-udc-renesas_usb3-lock-for-pn_-registers-access.patch