forked from Minki/linux
usb: musb: fix for v3.12-rc
A single patch fixing musb start when using peripheral only configurations. It turns out that musb_start() needs to be called for peripheral too, so that function is factored out of musb_virthub.c and into musb_core.c since it's shared for both roles. Signed-of-by: Felipe Balbi <balbi@ti.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJSWCGDAAoJEIaOsuA1yqREoF0P/2koIltWmxgHftathRpbJ0M1 aqqTFtKzeDlAMIJASM5f38KsbN1QAqVG57GtDl+CYqeK0M2wzw345E5JAoY0dD1n /QWAUcy2pKLf54wRHtP3hFv1/EyxniY6cgHkD4eh/BPMa+4AsepqNR8qxbN4WRCA Xs7iLFHIxfdIGJUJfegL3isaav9KGCVg5JpqykVbxi86A70a4R/Ogm2EcIciRKDT GWEIx6DDgsfr1A5QWKXKZFwlxnZE0BOje/lHV3KjAETboA4f5fynDXDbaayvjO7n DmobSOAZsN1M/GsQB4Kh6sMvd1CAOH4T4gbO7pGiQG58NObv/nRgkaowVI0RzSwH HREE1ODfHnXk1ArPxwKwcyIdOHa8VhNWfLa2pI1RdRjMWFwbn4AojA45fxFjBr9S Ht9lqdTpe8bmcV7iUp+x81ZOe7cEtfkgNh3Z2fpTF+4dGUO47aSMBx3zcEszH+gH iHAS+Uv4gH+jqxc8g5cM+haC1w4ulX+Rj0ZN6xKQ0612lLMeKctVk8XmW/ZM7urF /6RDmlzHrv1a34aW3k+LaPwR1oWsxy2zHSw2D5I1Vd20CZghHp+JprxGpAOjw4fS D3euh+TeYULPx68skf7GRRPzD74bvf9hobvmaSXsTlVh+5wfqoIwrNNd2K5j8/5+ 2Yck609ZK232R7obgfPv =wdwW -----END PGP SIGNATURE----- Merge tag 'fixes-for-v3.12-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-linus Pull USB gadget fixes from Felipe: usb: musb: fix for v3.12-rc A single patch fixing musb start when using peripheral only configurations. It turns out that musb_start() needs to be called for peripheral too, so that function is factored out of musb_virthub.c and into musb_core.c since it's shared for both roles. Signed-of-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
commit
22c7ef0a51
@ -921,6 +921,52 @@ static void musb_generic_disable(struct musb *musb)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Program the HDRC to start (enable interrupts, dma, etc.).
|
||||||
|
*/
|
||||||
|
void musb_start(struct musb *musb)
|
||||||
|
{
|
||||||
|
void __iomem *regs = musb->mregs;
|
||||||
|
u8 devctl = musb_readb(regs, MUSB_DEVCTL);
|
||||||
|
|
||||||
|
dev_dbg(musb->controller, "<== devctl %02x\n", devctl);
|
||||||
|
|
||||||
|
/* Set INT enable registers, enable interrupts */
|
||||||
|
musb->intrtxe = musb->epmask;
|
||||||
|
musb_writew(regs, MUSB_INTRTXE, musb->intrtxe);
|
||||||
|
musb->intrrxe = musb->epmask & 0xfffe;
|
||||||
|
musb_writew(regs, MUSB_INTRRXE, musb->intrrxe);
|
||||||
|
musb_writeb(regs, MUSB_INTRUSBE, 0xf7);
|
||||||
|
|
||||||
|
musb_writeb(regs, MUSB_TESTMODE, 0);
|
||||||
|
|
||||||
|
/* put into basic highspeed mode and start session */
|
||||||
|
musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE
|
||||||
|
| MUSB_POWER_HSENAB
|
||||||
|
/* ENSUSPEND wedges tusb */
|
||||||
|
/* | MUSB_POWER_ENSUSPEND */
|
||||||
|
);
|
||||||
|
|
||||||
|
musb->is_active = 0;
|
||||||
|
devctl = musb_readb(regs, MUSB_DEVCTL);
|
||||||
|
devctl &= ~MUSB_DEVCTL_SESSION;
|
||||||
|
|
||||||
|
/* session started after:
|
||||||
|
* (a) ID-grounded irq, host mode;
|
||||||
|
* (b) vbus present/connect IRQ, peripheral mode;
|
||||||
|
* (c) peripheral initiates, using SRP
|
||||||
|
*/
|
||||||
|
if (musb->port_mode != MUSB_PORT_MODE_HOST &&
|
||||||
|
(devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) {
|
||||||
|
musb->is_active = 1;
|
||||||
|
} else {
|
||||||
|
devctl |= MUSB_DEVCTL_SESSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
musb_platform_enable(musb);
|
||||||
|
musb_writeb(regs, MUSB_DEVCTL, devctl);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make the HDRC stop (disable interrupts, etc.);
|
* Make the HDRC stop (disable interrupts, etc.);
|
||||||
* reversible by musb_start
|
* reversible by musb_start
|
||||||
|
@ -503,6 +503,7 @@ static inline void musb_configure_ep0(struct musb *musb)
|
|||||||
extern const char musb_driver_name[];
|
extern const char musb_driver_name[];
|
||||||
|
|
||||||
extern void musb_stop(struct musb *musb);
|
extern void musb_stop(struct musb *musb);
|
||||||
|
extern void musb_start(struct musb *musb);
|
||||||
|
|
||||||
extern void musb_write_fifo(struct musb_hw_ep *ep, u16 len, const u8 *src);
|
extern void musb_write_fifo(struct musb_hw_ep *ep, u16 len, const u8 *src);
|
||||||
extern void musb_read_fifo(struct musb_hw_ep *ep, u16 len, u8 *dst);
|
extern void musb_read_fifo(struct musb_hw_ep *ep, u16 len, u8 *dst);
|
||||||
|
@ -1858,6 +1858,8 @@ static int musb_gadget_start(struct usb_gadget *g,
|
|||||||
musb->xceiv->state = OTG_STATE_B_IDLE;
|
musb->xceiv->state = OTG_STATE_B_IDLE;
|
||||||
spin_unlock_irqrestore(&musb->lock, flags);
|
spin_unlock_irqrestore(&musb->lock, flags);
|
||||||
|
|
||||||
|
musb_start(musb);
|
||||||
|
|
||||||
/* REVISIT: funcall to other code, which also
|
/* REVISIT: funcall to other code, which also
|
||||||
* handles power budgeting ... this way also
|
* handles power budgeting ... this way also
|
||||||
* ensures HdrcStart is indirectly called.
|
* ensures HdrcStart is indirectly called.
|
||||||
|
@ -44,52 +44,6 @@
|
|||||||
|
|
||||||
#include "musb_core.h"
|
#include "musb_core.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* Program the HDRC to start (enable interrupts, dma, etc.).
|
|
||||||
*/
|
|
||||||
static void musb_start(struct musb *musb)
|
|
||||||
{
|
|
||||||
void __iomem *regs = musb->mregs;
|
|
||||||
u8 devctl = musb_readb(regs, MUSB_DEVCTL);
|
|
||||||
|
|
||||||
dev_dbg(musb->controller, "<== devctl %02x\n", devctl);
|
|
||||||
|
|
||||||
/* Set INT enable registers, enable interrupts */
|
|
||||||
musb->intrtxe = musb->epmask;
|
|
||||||
musb_writew(regs, MUSB_INTRTXE, musb->intrtxe);
|
|
||||||
musb->intrrxe = musb->epmask & 0xfffe;
|
|
||||||
musb_writew(regs, MUSB_INTRRXE, musb->intrrxe);
|
|
||||||
musb_writeb(regs, MUSB_INTRUSBE, 0xf7);
|
|
||||||
|
|
||||||
musb_writeb(regs, MUSB_TESTMODE, 0);
|
|
||||||
|
|
||||||
/* put into basic highspeed mode and start session */
|
|
||||||
musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE
|
|
||||||
| MUSB_POWER_HSENAB
|
|
||||||
/* ENSUSPEND wedges tusb */
|
|
||||||
/* | MUSB_POWER_ENSUSPEND */
|
|
||||||
);
|
|
||||||
|
|
||||||
musb->is_active = 0;
|
|
||||||
devctl = musb_readb(regs, MUSB_DEVCTL);
|
|
||||||
devctl &= ~MUSB_DEVCTL_SESSION;
|
|
||||||
|
|
||||||
/* session started after:
|
|
||||||
* (a) ID-grounded irq, host mode;
|
|
||||||
* (b) vbus present/connect IRQ, peripheral mode;
|
|
||||||
* (c) peripheral initiates, using SRP
|
|
||||||
*/
|
|
||||||
if (musb->port_mode != MUSB_PORT_MODE_HOST &&
|
|
||||||
(devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) {
|
|
||||||
musb->is_active = 1;
|
|
||||||
} else {
|
|
||||||
devctl |= MUSB_DEVCTL_SESSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
musb_platform_enable(musb);
|
|
||||||
musb_writeb(regs, MUSB_DEVCTL, devctl);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void musb_port_suspend(struct musb *musb, bool do_suspend)
|
static void musb_port_suspend(struct musb *musb, bool do_suspend)
|
||||||
{
|
{
|
||||||
struct usb_otg *otg = musb->xceiv->otg;
|
struct usb_otg *otg = musb->xceiv->otg;
|
||||||
|
Loading…
Reference in New Issue
Block a user