musb_core: fix musb_init_controller() error cleanup path
This function forgets to call usb_remove_hcd() or musb_gadget_cleanup() iff sysfs_create_group() fails. [ felipe.balbi@nokia.com : review the entire error path not only when we fail hcd or gadget ] Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
c6a39eec9d
commit
34e2beb2c8
|
@ -1878,8 +1878,10 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
|
|||
*/
|
||||
if (!plat) {
|
||||
dev_dbg(dev, "no platform_data?\n");
|
||||
return -ENODEV;
|
||||
status = -ENODEV;
|
||||
goto fail0;
|
||||
}
|
||||
|
||||
switch (plat->mode) {
|
||||
case MUSB_HOST:
|
||||
#ifdef CONFIG_USB_MUSB_HDRC_HCD
|
||||
|
@ -1901,13 +1903,16 @@ bad_config:
|
|||
#endif
|
||||
default:
|
||||
dev_err(dev, "incompatible Kconfig role setting\n");
|
||||
return -EINVAL;
|
||||
status = -EINVAL;
|
||||
goto fail0;
|
||||
}
|
||||
|
||||
/* allocate */
|
||||
musb = allocate_instance(dev, plat->config, ctrl);
|
||||
if (!musb)
|
||||
return -ENOMEM;
|
||||
if (!musb) {
|
||||
status = -ENOMEM;
|
||||
goto fail0;
|
||||
}
|
||||
|
||||
spin_lock_init(&musb->lock);
|
||||
musb->board_mode = plat->mode;
|
||||
|
@ -1925,7 +1930,7 @@ bad_config:
|
|||
if (IS_ERR(musb->clock)) {
|
||||
status = PTR_ERR(musb->clock);
|
||||
musb->clock = NULL;
|
||||
goto fail;
|
||||
goto fail1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1944,12 +1949,12 @@ bad_config:
|
|||
*/
|
||||
musb->isr = generic_interrupt;
|
||||
status = musb_platform_init(musb);
|
||||
|
||||
if (status < 0)
|
||||
goto fail;
|
||||
goto fail2;
|
||||
|
||||
if (!musb->isr) {
|
||||
status = -ENODEV;
|
||||
goto fail2;
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_MUSB_PIO_ONLY
|
||||
|
@ -1975,7 +1980,7 @@ bad_config:
|
|||
? MUSB_CONTROLLER_MHDRC
|
||||
: MUSB_CONTROLLER_HDRC, musb);
|
||||
if (status < 0)
|
||||
goto fail2;
|
||||
goto fail3;
|
||||
|
||||
#ifdef CONFIG_USB_MUSB_OTG
|
||||
setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb);
|
||||
|
@ -1988,7 +1993,7 @@ bad_config:
|
|||
if (request_irq(nIrq, musb->isr, 0, dev_name(dev), musb)) {
|
||||
dev_err(dev, "request_irq %d failed!\n", nIrq);
|
||||
status = -ENODEV;
|
||||
goto fail2;
|
||||
goto fail3;
|
||||
}
|
||||
musb->nIrq = nIrq;
|
||||
/* FIXME this handles wakeup irqs wrong */
|
||||
|
@ -2050,12 +2055,12 @@ bad_config:
|
|||
|
||||
}
|
||||
if (status < 0)
|
||||
goto fail2;
|
||||
goto fail3;
|
||||
|
||||
#ifdef CONFIG_SYSFS
|
||||
status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group);
|
||||
if (status)
|
||||
goto fail2;
|
||||
goto fail4;
|
||||
#endif
|
||||
|
||||
dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",
|
||||
|
@ -2072,17 +2077,29 @@ bad_config:
|
|||
|
||||
return 0;
|
||||
|
||||
fail2:
|
||||
fail4:
|
||||
if (!is_otg_enabled(musb) && is_host_enabled(musb))
|
||||
usb_remove_hcd(musb_to_hcd(musb));
|
||||
else
|
||||
musb_gadget_cleanup(musb);
|
||||
|
||||
fail3:
|
||||
if (musb->irq_wake)
|
||||
device_init_wakeup(dev, 0);
|
||||
musb_platform_exit(musb);
|
||||
fail:
|
||||
|
||||
fail2:
|
||||
if (musb->clock)
|
||||
clk_put(musb->clock);
|
||||
|
||||
fail1:
|
||||
dev_err(musb->controller,
|
||||
"musb_init_controller failed with status %d\n", status);
|
||||
|
||||
if (musb->clock)
|
||||
clk_put(musb->clock);
|
||||
device_init_wakeup(dev, 0);
|
||||
musb_free(musb);
|
||||
|
||||
fail0:
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue