*/
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
#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;
if (IS_ERR(musb->clock)) {
status = PTR_ERR(musb->clock);
musb->clock = NULL;
- goto fail;
+ goto fail1;
}
}
*/
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
? 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);
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 */
}
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",
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:
- dev_err(musb->controller,
- "musb_init_controller failed with status %d\n", status);
+fail2:
if (musb->clock)
clk_put(musb->clock);
- device_init_wakeup(dev, 0);
+
+fail1:
+ dev_err(musb->controller,
+ "musb_init_controller failed with status %d\n", status);
+
musb_free(musb);
+fail0:
+
return status;
}