[PATCH 3.12 030/144] usb: musb: only cancel work if it is initialized

From: Greg Kroah-Hartman
Date: Mon Jan 06 2014 - 17:38:33 EST

3.12-stable review patch. If anyone has any objections, please let me know.


From: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>

commit 66fadea5b79c07154126bb0db375be915f611246 upstream.

Since commit c5340bd14 ("usb: musb: cancel work on removal") the workqueue
is cancelled but then if we bail out before the workqueue is setup we
get this:

|INFO: trying to register non-static key.
|the code is fine but needs lockdep annotation.
|turning off the locking correctness validator.
|CPU: 0 PID: 708 Comm: modprobe Not tainted 3.12.0+ #435
|[<c00867bc>] (lock_acquire+0xf0/0x108) from [<c00529d0>] (flush_work+0x38/0x2ec)
|[<c00529d0>] (flush_work+0x38/0x2ec) from [<c0052d24>] (__cancel_work_timer+0xa0/0x134)
|[<c0052d24>] (__cancel_work_timer+0xa0/0x134) from [<bf0e4ae4>] (musb_free+0x40/0x60 [musb_hdrc])
|[<bf0e4ae4>] (musb_free+0x40/0x60 [musb_hdrc]) from [<bf0e5364>] (musb_probe+0x678/0xb78 [musb_hdrc])
|[<bf0e5364>] (musb_probe+0x678/0xb78 [musb_hdrc]) from [<c0294bf0>] (platform_drv_probe+0x1c/0x24)
|[<c0294bf0>] (platform_drv_probe+0x1c/0x24) from [<c0293970>] (driver_probe_device+0x90/0x224)
|[<c0293970>] (driver_probe_device+0x90/0x224) from [<c0291ef0>] (bus_for_each_drv+0x60/0x8c)
|[<c0291ef0>] (bus_for_each_drv+0x60/0x8c) from [<c02938bc>] (device_attach+0x80/0xa4)
|[<c02938bc>] (device_attach+0x80/0xa4) from [<c0292b24>] (bus_probe_device+0x88/0xac)
|[<c0292b24>] (bus_probe_device+0x88/0xac) from [<c0291490>] (device_add+0x388/0x6c8)
|[<c0291490>] (device_add+0x388/0x6c8) from [<c02952a0>] (platform_device_add+0x188/0x22c)
|[<c02952a0>] (platform_device_add+0x188/0x22c) from [<bf11ea30>] (dsps_probe+0x294/0x394 [musb_dsps])
|[<bf11ea30>] (dsps_probe+0x294/0x394 [musb_dsps]) from [<c0294bf0>] (platform_drv_probe+0x1c/0x24)
|platform musb-hdrc.1.auto: Driver musb-hdrc requests probe deferral
|musb-hdrc musb-hdrc.1.auto: musb_init_controller failed with status -517

This patch moves the init part to earlier part so it can be cleaned as
part of the fail3 label because now it is surrounded by the fail4 label.
Step two is to remove it from musb_free() and add it to the two cleanup
paths (error path and device removal) separately.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
Signed-off-by: Felipe Balbi <balbi@xxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

drivers/usb/musb/musb_core.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1809,7 +1809,6 @@ static void musb_free(struct musb *musb)
free_irq(musb->nIrq, musb);
- cancel_work_sync(&musb->irq_work);

@@ -1891,6 +1890,9 @@ musb_init_controller(struct device *dev,

+ /* Init IRQ workqueue before request_irq */
+ INIT_WORK(&musb->irq_work, musb_irq_work);
/* setup musb parts of the core (especially endpoints) */
status = musb_core_init(plat->config->multipoint
@@ -1900,9 +1902,6 @@ musb_init_controller(struct device *dev,

setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb);

- /* Init IRQ workqueue before request_irq */
- INIT_WORK(&musb->irq_work, musb_irq_work);
/* attach to the IRQ */
if (request_irq(nIrq, musb->isr, 0, dev_name(dev), musb)) {
dev_err(dev, "request_irq %d failed!\n", nIrq);
@@ -1976,6 +1975,7 @@ fail4:

+ cancel_work_sync(&musb->irq_work);
if (musb->dma_controller)
@@ -2037,6 +2037,7 @@ static int musb_remove(struct platform_d
if (musb->dma_controller)

+ cancel_work_sync(&musb->irq_work);
device_init_wakeup(dev, 0);
return 0;

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/