Commit eb0be47d authored by Patrik Sevallius's avatar Patrik Sevallius Committed by Greg Kroah-Hartman

USB: usb peripheral controller driver oops avoidance

I'm having problem with oopses when rebooting, if I modprobe g_serial
and rmmod g_serial and do a reboot I get an oops in device_shutdown().
The reason seems to be that usb_gadget_unregister_driver() doesn't do
enough cleanup.  With this at91_udc patch I don't get the oops.
Signed-off-by: default avatarPatrik Sevallius <patrik.sevallius@enea.com>
[ Same bug was in other peripheral controller drivers; fixed ]
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 7b62cc86
...@@ -2038,6 +2038,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) ...@@ -2038,6 +2038,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
spin_unlock_irqrestore(&dev->lock, flags); spin_unlock_irqrestore(&dev->lock, flags);
driver->unbind(&dev->gadget); driver->unbind(&dev->gadget);
dev->gadget.dev.driver = NULL;
dev->driver = NULL; dev->driver = NULL;
/* set SD */ /* set SD */
......
...@@ -1616,6 +1616,8 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) ...@@ -1616,6 +1616,8 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
local_irq_enable(); local_irq_enable();
driver->unbind(&udc->gadget); driver->unbind(&udc->gadget);
udc->gadget.dev.driver = NULL;
udc->gadget.dev.driver_data = NULL;
udc->driver = NULL; udc->driver = NULL;
DBG("unbound from %s\n", driver->driver.name); DBG("unbound from %s\n", driver->driver.name);
......
...@@ -1422,6 +1422,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) ...@@ -1422,6 +1422,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
spin_unlock_irqrestore(&dev->lock, flags); spin_unlock_irqrestore(&dev->lock, flags);
driver->unbind(&dev->gadget); driver->unbind(&dev->gadget);
dev->gadget.dev.driver = NULL;
DBG(dev, "unregistered driver '%s'\n", driver->driver.name); DBG(dev, "unregistered driver '%s'\n", driver->driver.name);
return 0; return 0;
......
...@@ -474,6 +474,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) ...@@ -474,6 +474,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
spin_unlock_irqrestore(&dev->lock, flags); spin_unlock_irqrestore(&dev->lock, flags);
driver->unbind(&dev->gadget); driver->unbind(&dev->gadget);
dev->gadget.dev.driver = NULL;
device_del(&dev->gadget.dev); device_del(&dev->gadget.dev);
udc_disable(dev); udc_disable(dev);
......
...@@ -1508,6 +1508,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) ...@@ -1508,6 +1508,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
m66592_bclr(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); m66592_bclr(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0);
driver->unbind(&m66592->gadget); driver->unbind(&m66592->gadget);
m66592->gadget.dev.driver = NULL;
init_controller(m66592); init_controller(m66592);
disable_controller(m66592); disable_controller(m66592);
......
...@@ -1345,6 +1345,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) ...@@ -1345,6 +1345,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
local_irq_enable(); local_irq_enable();
driver->unbind(&dev->gadget); driver->unbind(&dev->gadget);
dev->gadget.dev.driver = NULL;
dev->driver = NULL; dev->driver = NULL;
device_del (&dev->gadget.dev); device_del (&dev->gadget.dev);
......
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