|
@@ -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:
|
|
|
- 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;
|
|
|
|
|
|
}
|