From adb3ee421d6d39fbfadadf7093a587461ac4597e Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 12 Mar 2010 10:27:21 +0200 Subject: usb: musb: abstract out ULPI_BUSCONTROL register reads/writes The USB PHY on current Blackfin processors is a UTMI+ level 2 PHY. However, it has no ULPI support - so there are no registers at all. That means accesses to ULPI_BUSCONTROL have to be abstracted away like other MUSB registers. This fixes building for Blackfin parts again. Signed-off-by: Mike Frysinger Acked-by: Anand Gadiyar Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/usb/musb/musb_core.c') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index b4bbf8f2c238..e54e468c5672 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2007,7 +2007,6 @@ bad_config: /* host side needs more setup */ if (is_host_enabled(musb)) { struct usb_hcd *hcd = musb_to_hcd(musb); - u8 busctl; otg_set_host(musb->xceiv, &hcd->self); @@ -2018,9 +2017,9 @@ bad_config: /* program PHY to use external vBus if required */ if (plat->extvbus) { - busctl = musb_readb(musb->mregs, MUSB_ULPI_BUSCONTROL); + u8 busctl = musb_read_ulpi_buscontrol(musb->mregs); busctl |= MUSB_ULPI_USE_EXTVBUS; - musb_writeb(musb->mregs, MUSB_ULPI_BUSCONTROL, busctl); + musb_write_ulpi_buscontrol(musb->mregs, busctl); } } -- cgit v1.2.3 From aa4714560b4ea359bb7830188ebd06bce71bcdea Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 12 Mar 2010 10:27:24 +0200 Subject: usb: musb: core: declare mbase only where it's used ... and avoid a compilation if we disable host side of musb. Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/usb/musb/musb_core.c') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index e54e468c5672..0e8b8ab1d168 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -379,7 +379,6 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, u8 devctl, u8 power) { irqreturn_t handled = IRQ_NONE; - void __iomem *mbase = musb->mregs; DBG(3, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl, int_usb); @@ -394,6 +393,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, if (devctl & MUSB_DEVCTL_HM) { #ifdef CONFIG_USB_MUSB_HDRC_HCD + void __iomem *mbase = musb->mregs; + switch (musb->xceiv->state) { case OTG_STATE_A_SUSPEND: /* remote wakeup? later, GetPortStatus @@ -471,6 +472,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, #ifdef CONFIG_USB_MUSB_HDRC_HCD /* see manual for the order of the tests */ if (int_usb & MUSB_INTR_SESSREQ) { + void __iomem *mbase = musb->mregs; + DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb)); /* IRQ arrives from ID pin sense or (later, if VBUS power @@ -519,6 +522,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, case OTG_STATE_A_WAIT_BCON: case OTG_STATE_A_WAIT_VRISE: if (musb->vbuserr_retry) { + void __iomem *mbase = musb->mregs; + musb->vbuserr_retry--; ignore = 1; devctl |= MUSB_DEVCTL_SESSION; @@ -622,6 +627,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, if (int_usb & MUSB_INTR_CONNECT) { struct usb_hcd *hcd = musb_to_hcd(musb); + void __iomem *mbase = musb->mregs; handled = IRQ_HANDLED; musb->is_active = 1; -- cgit v1.2.3 From 5e0e61afa5b342c0197fce2d4fd2a2b515e96b31 Mon Sep 17 00:00:00 2001 From: Ajay Kumar Gupta Date: Thu, 25 Mar 2010 13:14:26 +0200 Subject: musb: save and restore missing bus control register Added the missing BUS_CONTROL register in musb save/restore routines. Signed-off-by: Ajay Kumar Gupta Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 2 ++ drivers/usb/musb/musb_core.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/usb/musb/musb_core.c') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 0e8b8ab1d168..3342b82d4e53 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2176,6 +2176,7 @@ void musb_save_context(struct musb *musb) if (is_host_enabled(musb)) { musb_context.frame = musb_readw(musb_base, MUSB_FRAME); musb_context.testmode = musb_readb(musb_base, MUSB_TESTMODE); + musb_context.busctl = musb_read_ulpi_buscontrol(musb->mregs); } musb_context.power = musb_readb(musb_base, MUSB_POWER); musb_context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE); @@ -2247,6 +2248,7 @@ void musb_restore_context(struct musb *musb) if (is_host_enabled(musb)) { musb_writew(musb_base, MUSB_FRAME, musb_context.frame); musb_writeb(musb_base, MUSB_TESTMODE, musb_context.testmode); + musb_write_ulpi_buscontrol(musb->mregs, musb_context.busctl); } musb_writeb(musb_base, MUSB_POWER, musb_context.power); musb_writew(musb_base, MUSB_INTRTXE, musb_context.intrtxe); diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index cd9f4a9a06c6..ac17b004909b 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -478,7 +478,7 @@ struct musb_context_registers { u16 frame; u8 index, testmode; - u8 devctl, misc; + u8 devctl, busctl, misc; struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; }; -- cgit v1.2.3 From 1fb48f4a96ef3d4eee0a13b92a3e8489171b47c9 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Thu, 25 Mar 2010 13:14:28 +0200 Subject: musb_core: don't touch 'musb->clock' in musb_free() Remove duplicate/unbalanced calls to clk_disable()/clk_put() in musb_free(): - clk_disable() is called by musb_platform_exit() just prior to this call; - clk_put() is called by the callers of musb_free() prior to calling it... Signed-off-by: Sergei Shtylyov Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/usb/musb/musb_core.c') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 3342b82d4e53..03544de751ef 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1857,11 +1857,6 @@ static void musb_free(struct musb *musb) musb_platform_exit(musb); musb_writeb(musb->mregs, MUSB_DEVCTL, 0); - if (musb->clock) { - clk_disable(musb->clock); - clk_put(musb->clock); - } - #ifdef CONFIG_USB_MUSB_HDRC_HCD usb_put_hcd(musb_to_hcd(musb)); #else -- cgit v1.2.3 From 3d0bfbf25957e04354389047f0e6ba520d58487c Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Thu, 25 Mar 2010 13:14:29 +0200 Subject: musb_core: don't prevent disabling clock on driver unload Resetting 'musb->clock' to NULL in musb_shutdown() prevents musb_platform_exit() from properly disabling the clock when unloading the driver -- don't do it. Signed-off-by: Sergei Shtylyov Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/usb/musb/musb_core.c') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 03544de751ef..8b68f21d3f82 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -965,10 +965,8 @@ static void musb_shutdown(struct platform_device *pdev) spin_lock_irqsave(&musb->lock, flags); musb_platform_disable(musb); musb_generic_disable(musb); - if (musb->clock) { + if (musb->clock) clk_put(musb->clock); - musb->clock = NULL; - } spin_unlock_irqrestore(&musb->lock, flags); /* FIXME power down */ -- cgit v1.2.3 From 461972d8a4c94bc44f11a13046041c78a7cf18dd Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Thu, 25 Mar 2010 13:14:32 +0200 Subject: musb_core: don't call musb_platform_exit() twice musb_platform_exit() is called twice from musb_init_controller() iff controller initialization fails. Move the call (and the DevCtl register writes surrounding it) from musb_free() to musb_remove(). Fix mispalced and now incorrect 'goto's in musb_init_controller(). Signed-off-by: Sergei Shtylyov Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'drivers/usb/musb/musb_core.c') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 8b68f21d3f82..508fd582973f 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1851,10 +1851,6 @@ static void musb_free(struct musb *musb) put_device(musb->xceiv->dev); #endif - musb_writeb(musb->mregs, MUSB_DEVCTL, 0); - musb_platform_exit(musb); - musb_writeb(musb->mregs, MUSB_DEVCTL, 0); - #ifdef CONFIG_USB_MUSB_HDRC_HCD usb_put_hcd(musb_to_hcd(musb)); #else @@ -2032,8 +2028,6 @@ bad_config: musb->xceiv->state = OTG_STATE_A_IDLE; status = usb_add_hcd(musb_to_hcd(musb), -1, 0); - if (status) - goto fail; DBG(1, "%s mode, status %d, devctl %02x %c\n", "HOST", status, @@ -2048,8 +2042,6 @@ bad_config: musb->xceiv->state = OTG_STATE_B_IDLE; status = musb_gadget_setup(musb); - if (status) - goto fail; DBG(1, "%s mode, status %d, dev%02x\n", is_otg_enabled(musb) ? "OTG" : "PERIPHERAL", @@ -2057,12 +2049,14 @@ bad_config: musb_readb(musb->mregs, MUSB_DEVCTL)); } + if (status < 0) + goto fail2; #ifdef CONFIG_SYSFS status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group); -#endif if (status) goto fail2; +#endif dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n", ({char *s; @@ -2125,7 +2119,6 @@ static int __init musb_probe(struct platform_device *pdev) /* clobbered by use_dma=n */ orig_dma_mask = dev->dma_mask; #endif - status = musb_init_controller(dev, irq, base); if (status < 0) iounmap(base); @@ -2148,6 +2141,10 @@ static int __exit musb_remove(struct platform_device *pdev) if (musb->board_mode == MUSB_HOST) usb_remove_hcd(musb_to_hcd(musb)); #endif + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); + musb_platform_exit(musb); + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); + musb_free(musb); iounmap(ctrl_base); device_init_wakeup(&pdev->dev, 0); -- cgit v1.2.3 From 34e2beb2c883e0ea1b6135ad6f7713f7574a01aa Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Thu, 25 Mar 2010 13:14:33 +0200 Subject: 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 Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 51 +++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 17 deletions(-) (limited to 'drivers/usb/musb/musb_core.c') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 508fd582973f..705cc4ad8737 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -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; } -- cgit v1.2.3