summaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/musb_gadget.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-03-01 17:44:20 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-03-01 17:44:20 +0100
commit15e68a803573974409972e761d8f08f03fce5bdb (patch)
tree5a7ff8f06da629bd59101718f27b157912c141be /drivers/usb/musb/musb_gadget.c
parentRevert "powerpc/usb: fix usb CTRL_PHY_CLK_VALID breaks on some platform" (diff)
parentusb: musb: Reselect index reg in interrupt context (diff)
downloadlinux-15e68a803573974409972e761d8f08f03fce5bdb.tar.xz
linux-15e68a803573974409972e761d8f08f03fce5bdb.zip
Merge tag 'musb-for-v3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
USB: MUSB changes for 3.4 Here are a set of changes to the MUSB driver. In summary we have a patch making modules behave better, there's a fix on debugfs' error path, a small change removing an unnecessary pm_runtime call on musb_shutdown() and a fix to relesect the endpoint in Interrupt context. This last patch is needed because we must drop musb's lock when calling request->complete() and that could cause problems if another thread queues a request and ends up changing MUSB_INDEX register.
Diffstat (limited to 'drivers/usb/musb/musb_gadget.c')
-rw-r--r--drivers/usb/musb/musb_gadget.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index ac3d2eec20fe..957d9ca3d06d 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -574,6 +574,15 @@ void musb_g_tx(struct musb *musb, u8 epnum)
if (request->actual == request->length) {
musb_g_giveback(musb_ep, request, 0);
+ /*
+ * In the giveback function the MUSB lock is
+ * released and acquired after sometime. During
+ * this time period the INDEX register could get
+ * changed by the gadget_queue function especially
+ * on SMP systems. Reselect the INDEX to be sure
+ * we are reading/modifying the right registers
+ */
+ musb_ep_select(mbase, epnum);
req = musb_ep->desc ? next_request(musb_ep) : NULL;
if (!req) {
dev_dbg(musb->controller, "%s idle now\n",
@@ -983,6 +992,15 @@ void musb_g_rx(struct musb *musb, u8 epnum)
}
#endif
musb_g_giveback(musb_ep, request, 0);
+ /*
+ * In the giveback function the MUSB lock is
+ * released and acquired after sometime. During
+ * this time period the INDEX register could get
+ * changed by the gadget_queue function especially
+ * on SMP systems. Reselect the INDEX to be sure
+ * we are reading/modifying the right registers
+ */
+ musb_ep_select(mbase, epnum);
req = next_request(musb_ep);
if (!req)
@@ -1762,7 +1780,7 @@ static void musb_gadget_release(struct device *dev)
}
-static void __init
+static void __devinit
init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in)
{
struct musb_hw_ep *hw_ep = musb->endpoints + epnum;
@@ -1799,7 +1817,7 @@ init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in)
* Initialize the endpoints exposed to peripheral drivers, with backlinks
* to the rest of the driver state.
*/
-static inline void __init musb_g_init_endpoints(struct musb *musb)
+static inline void __devinit musb_g_init_endpoints(struct musb *musb)
{
u8 epnum;
struct musb_hw_ep *hw_ep;
@@ -1832,7 +1850,7 @@ static inline void __init musb_g_init_endpoints(struct musb *musb)
/* called once during driver setup to initialize and link into
* the driver model; memory is zeroed.
*/
-int __init musb_gadget_setup(struct musb *musb)
+int __devinit musb_gadget_setup(struct musb *musb)
{
int status;