diff options
Diffstat (limited to 'drivers/usb/gadget/udc/aspeed_udc.c')
-rw-r--r-- | drivers/usb/gadget/udc/aspeed_udc.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/usb/gadget/udc/aspeed_udc.c b/drivers/usb/gadget/udc/aspeed_udc.c index 2ef89a442f50..3916c8e2ba01 100644 --- a/drivers/usb/gadget/udc/aspeed_udc.c +++ b/drivers/usb/gadget/udc/aspeed_udc.c @@ -1432,15 +1432,24 @@ static void ast_udc_init_hw(struct ast_udc_dev *udc) ast_udc_write(udc, 0, AST_UDC_EP0_CTRL); } -static int ast_udc_remove(struct platform_device *pdev) +static void ast_udc_remove(struct platform_device *pdev) { struct ast_udc_dev *udc = platform_get_drvdata(pdev); unsigned long flags; u32 ctrl; usb_del_gadget_udc(&udc->gadget); - if (udc->driver) - return -EBUSY; + if (udc->driver) { + /* + * This is broken as only some cleanup is skipped, *udev is + * freed and the register mapping goes away. Any further usage + * probably crashes. Also the device is unbound, so the skipped + * cleanup is never catched up later. + */ + dev_alert(&pdev->dev, + "Driver is busy and still going away. Fasten your seat belts!\n"); + return; + } spin_lock_irqsave(&udc->lock, flags); @@ -1459,8 +1468,6 @@ static int ast_udc_remove(struct platform_device *pdev) udc->ep0_buf_dma); udc->ep0_buf = NULL; - - return 0; } static int ast_udc_probe(struct platform_device *pdev) @@ -1581,7 +1588,7 @@ MODULE_DEVICE_TABLE(of, ast_udc_of_dt_ids); static struct platform_driver ast_udc_driver = { .probe = ast_udc_probe, - .remove = ast_udc_remove, + .remove_new = ast_udc_remove, .driver = { .name = KBUILD_MODNAME, .of_match_table = ast_udc_of_dt_ids, |