Instead of adding and deleting the gadget device in the start and stop invocations. Use device_register in the probe method to initialize and add the gadget device and unregister it in the remove function. This also requires a release function for the gadget device. Signed-off-by: Heiko Stuebner <heiko@xxxxxxxxx> --- drivers/usb/gadget/s3c-hsudc.c | 27 ++++++++++++++++++--------- 1 files changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 06ca8c4..fa2ae7a 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -1156,11 +1156,6 @@ static int s3c_hsudc_start(struct usb_gadget_driver *driver, hsudc->driver = driver; hsudc->gadget.dev.driver = &driver->driver; hsudc->gadget.speed = USB_SPEED_UNKNOWN; - ret = device_add(&hsudc->gadget.dev); - if (ret) { - dev_err(hsudc->dev, "failed to probe gadget device"); - return ret; - } ret = bind(&hsudc->gadget); if (ret) { @@ -1180,8 +1175,6 @@ static int s3c_hsudc_start(struct usb_gadget_driver *driver, hsudc->gadget.name); driver->unbind(&hsudc->gadget); - device_del(&hsudc->gadget.dev); - hsudc->driver = NULL; hsudc->gadget.dev.driver = NULL; return ret; @@ -1222,7 +1215,6 @@ static int s3c_hsudc_stop(struct usb_gadget_driver *driver) (void) otg_set_peripheral(hsudc->transceiver, NULL); driver->unbind(&hsudc->gadget); - device_del(&hsudc->gadget.dev); disable_irq(hsudc->irq); dev_info(hsudc->dev, "unregistered gadget driver '%s'\n", @@ -1260,6 +1252,13 @@ static struct usb_gadget_ops s3c_hsudc_gadget_ops = { .vbus_draw = s3c_hsudc_vbus_draw, }; +/* The gadget structure is stored inside the hsudc structure and will be + * released along with it. */ +static void s3c_hsudc_gadget_release(struct device *dev) +{ + return; +} + static int __devinit s3c_hsudc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -1307,7 +1306,6 @@ static int __devinit s3c_hsudc_probe(struct platform_device *pdev) spin_lock_init(&hsudc->lock); - device_initialize(&hsudc->gadget.dev); dev_set_name(&hsudc->gadget.dev, "gadget"); hsudc->gadget.max_speed = USB_SPEED_HIGH; @@ -1315,6 +1313,7 @@ static int __devinit s3c_hsudc_probe(struct platform_device *pdev) hsudc->gadget.name = dev_name(dev); hsudc->gadget.dev.parent = dev; hsudc->gadget.dev.dma_mask = dev->dma_mask; + hsudc->gadget.dev.release = s3c_hsudc_gadget_release; hsudc->gadget.ep0 = &hsudc->ep[0].ep; hsudc->gadget.is_otg = 0; @@ -1348,12 +1347,20 @@ static int __devinit s3c_hsudc_probe(struct platform_device *pdev) disable_irq(hsudc->irq); local_irq_enable(); + ret = device_register(&hsudc->gadget.dev); + if (ret) { + put_device(&hsudc->gadget.dev); + goto err_add_device; + } + ret = usb_add_gadget_udc(&pdev->dev, &hsudc->gadget); if (ret) goto err_add_udc; return 0; err_add_udc: + device_unregister(&hsudc->gadget.dev); +err_add_device: clk_disable(hsudc->uclk); clk_put(hsudc->uclk); err_clk: @@ -1379,6 +1386,8 @@ static int __devexit s3c_hsudc_remove(struct platform_device *pdev) usb_del_gadget_udc(&hsudc->gadget); + device_unregister(&hsudc->gadget.dev); + clk_disable(hsudc->uclk); clk_put(hsudc->uclk); -- 1.7.2.3 -- To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html