Commit afb76df1 authored by Vladimir Zapolskiy's avatar Vladimir Zapolskiy Committed by Felipe Balbi

usb: musb: fix oops on omap2430 module unload

This change prevents runtime suspend and resume actual execution, if
omap2430 controller driver is loaded after musb-hdrc, and therefore the
controller isn't initialized properly.

The problem is reproducible with 3.1.y and 3.2 kernels.

Kernel configuration of musb:

  % cat .config | egrep 'MUSB|GADGET'
  CONFIG_USB_MUSB_HDRC=y
  # CONFIG_USB_MUSB_TUSB6010 is not set
  CONFIG_USB_MUSB_OMAP2PLUS=m
  # CONFIG_USB_MUSB_AM35X is not set
  CONFIG_MUSB_PIO_ONLY=y
  CONFIG_USB_GADGET=y
  # CONFIG_USB_GADGET_DEBUG is not set
  # CONFIG_USB_GADGET_DEBUG_FILES is not set
  # CONFIG_USB_GADGET_DEBUG_FS is not set
  CONFIG_USB_GADGET_VBUS_DRAW=2
  CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
  CONFIG_USB_GADGET_MUSB_HDRC=m
  CONFIG_USB_GADGET_DUALSPEED=y
  CONFIG_USB_GADGETFS=m
  # CONFIG_USB_MIDI_GADGET is not set

Fixes the following oops on module unloading:

  Unable to handle kernel NULL pointer dereference at virtual address 00000220
  ----8<----
  [<bf162088>] (omap2430_runtime_resume+0x24/0x54 [omap2430]) from [<c0302e34>] (pm_generic_runtime_resume+0x3c/0x50)
  [<c0302e34>] (pm_generic_runtime_resume+0x3c/0x50) from [<c0031a24>] (_od_runtime_resume+0x28/0x2c)
  [<c0031a24>] (_od_runtime_resume+0x28/0x2c) from [<c0306cb0>] (__rpm_callback+0x60/0xa0)
  [<c0306cb0>] (__rpm_callback+0x60/0xa0) from [<c0307f2c>] (rpm_resume+0x3fc/0x6e4)
  [<c0307f2c>] (rpm_resume+0x3fc/0x6e4) from [<c030851c>] (__pm_runtime_resume+0x5c/0x90)
  [<c030851c>] (__pm_runtime_resume+0x5c/0x90) from [<c02fd0dc>] (__device_release_driver+0x2c/0xd0)
  [<c02fd0dc>] (__device_release_driver+0x2c/0xd0) from [<c02fda18>] (driver_detach+0xe8/0xf4)
  [<c02fda18>] (driver_detach+0xe8/0xf4) from [<c02fcf88>] (bus_remove_driver+0xa0/0x104)
  [<c02fcf88>] (bus_remove_driver+0xa0/0x104) from [<c02fde54>] (driver_unregister+0x60/0x80)
  [<c02fde54>] (driver_unregister+0x60/0x80) from [<c02ff2d4>] (platform_driver_unregister+0x1c/0x20)
  [<c02ff2d4>] (platform_driver_unregister+0x1c/0x20) from [<bf162928>] (omap2430_exit+0x14/0x1c [omap2430])
  [<bf162928>] (omap2430_exit+0x14/0x1c [omap2430]) from [<c007d8bc>] (sys_delete_module+0x1f4/0x264)
  [<c007d8bc>] (sys_delete_module+0x1f4/0x264) from [<c000f000>] (ret_fast_syscall+0x0/0x30)
Signed-off-by: default avatarVladimir Zapolskiy <vladimir.zapolskiy@nokia.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: stable@vger.kernel.org # 3.1
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent ecb07797
......@@ -491,11 +491,13 @@ static int omap2430_runtime_suspend(struct device *dev)
struct omap2430_glue *glue = dev_get_drvdata(dev);
struct musb *musb = glue_to_musb(glue);
musb->context.otg_interfsel = musb_readl(musb->mregs,
OTG_INTERFSEL);
if (musb) {
musb->context.otg_interfsel = musb_readl(musb->mregs,
OTG_INTERFSEL);
omap2430_low_level_exit(musb);
usb_phy_set_suspend(musb->xceiv, 1);
omap2430_low_level_exit(musb);
usb_phy_set_suspend(musb->xceiv, 1);
}
return 0;
}
......@@ -505,11 +507,13 @@ static int omap2430_runtime_resume(struct device *dev)
struct omap2430_glue *glue = dev_get_drvdata(dev);
struct musb *musb = glue_to_musb(glue);
omap2430_low_level_init(musb);
musb_writel(musb->mregs, OTG_INTERFSEL,
musb->context.otg_interfsel);
if (musb) {
omap2430_low_level_init(musb);
musb_writel(musb->mregs, OTG_INTERFSEL,
musb->context.otg_interfsel);
usb_phy_set_suspend(musb->xceiv, 0);
usb_phy_set_suspend(musb->xceiv, 0);
}
return 0;
}
......
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