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: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
This commit is contained in:
parent
155940a16d
commit
5f0625aaba
@ -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)
|
|||||||
/* 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)
|
|||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user