Commit 5f0625aa authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Felipe Balbi

usb: gadget: aspeed: Rework the reset logic

We had some dodgy code using the speed setting to decide whether a
port reset would reset the device or just enable it.

Instead, if the device is disabled and has a gadget attached, a
reset will enable it. If it's already enabled, a reset will
reset it.
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent 155940a1
...@@ -50,7 +50,7 @@ void ast_vhub_dev_irq(struct ast_vhub_dev *d) ...@@ -50,7 +50,7 @@ void ast_vhub_dev_irq(struct ast_vhub_dev *d)
static void ast_vhub_dev_enable(struct ast_vhub_dev *d) static void ast_vhub_dev_enable(struct ast_vhub_dev *d)
{ {
u32 reg, hmsk; u32 reg, hmsk, i;
if (d->enabled) if (d->enabled)
return; return;
...@@ -76,6 +76,20 @@ static void ast_vhub_dev_enable(struct ast_vhub_dev *d) ...@@ -76,6 +76,20 @@ static void ast_vhub_dev_enable(struct ast_vhub_dev *d)
/* Set EP0 DMA buffer address */ /* Set EP0 DMA buffer address */
writel(d->ep0.buf_dma, d->regs + AST_VHUB_DEV_EP0_DATA); writel(d->ep0.buf_dma, d->regs + AST_VHUB_DEV_EP0_DATA);
/* Clear stall on all EPs */
for (i = 0; i < AST_VHUB_NUM_GEN_EPs; i++) {
struct ast_vhub_ep *ep = d->epns[i];
if (ep && (ep->epn.stalled || ep->epn.wedged)) {
ep->epn.stalled = false;
ep->epn.wedged = false;
ast_vhub_update_epn_stall(ep);
}
}
/* Additional cleanups */
d->wakeup_en = false;
d->suspended = false;
d->enabled = true; d->enabled = true;
} }
...@@ -477,46 +491,28 @@ void ast_vhub_dev_resume(struct ast_vhub_dev *d) ...@@ -477,46 +491,28 @@ void ast_vhub_dev_resume(struct ast_vhub_dev *d)
void ast_vhub_dev_reset(struct ast_vhub_dev *d) void ast_vhub_dev_reset(struct ast_vhub_dev *d)
{ {
/* /* No driver, just disable the device and return */
* If speed is not set, we enable the port. If it is, if (!d->driver) {
* send reset to the gadget and reset "speed". ast_vhub_dev_disable(d);
* return;
* Speed is an indication that we have got the first
* setup packet to the device.
*/
if (d->gadget.speed == USB_SPEED_UNKNOWN && !d->enabled) {
DDBG(d, "Reset at unknown speed of disabled device, enabling...\n");
ast_vhub_dev_enable(d);
d->suspended = false;
} }
if (d->gadget.speed != USB_SPEED_UNKNOWN && d->driver) {
unsigned int i;
DDBG(d, "Reset at known speed of bound device, resetting...\n"); /* If the port isn't enabled, just enable it */
if (!d->enabled) {
DDBG(d, "Reset of disabled device, enabling...\n");
ast_vhub_dev_enable(d);
} else {
DDBG(d, "Reset of enabled device, resetting...\n");
spin_unlock(&d->vhub->lock); spin_unlock(&d->vhub->lock);
d->driver->reset(&d->gadget); usb_gadget_udc_reset(&d->gadget, d->driver);
spin_lock(&d->vhub->lock); spin_lock(&d->vhub->lock);
/* /*
* Disable/re-enable HW, this will clear the address * Disable and maybe re-enable HW, this will clear the address
* and speed setting. * and speed setting.
*/ */
ast_vhub_dev_disable(d); ast_vhub_dev_disable(d);
ast_vhub_dev_enable(d); ast_vhub_dev_enable(d);
/* Clear stall on all EPs */
for (i = 0; i < AST_VHUB_NUM_GEN_EPs; i++) {
struct ast_vhub_ep *ep = d->epns[i];
if (ep && ep->epn.stalled) {
ep->epn.stalled = false;
ast_vhub_update_epn_stall(ep);
}
}
/* Additional cleanups */
d->wakeup_en = false;
d->suspended = false;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment