Currently pxa2xx_udc spits this warning:

WARNING: at arch/arm/mach-pxa/clock.c:86 clk_disable+0x48/0xb0()
Modules linked in:
[<c001ea0c>] (dump_stack+0x0/0x14) from [<c002fe50>] 
(warn_on_slowpath+0x4c/0x60)
[<c002fe04>] (warn_on_slowpath+0x0/0x60) from [<c00230d0>] 
(clk_disable+0x48/0xb0)
 r6:c02162fc r5:c02178f0 r4:f2600000
[<c0023088>] (clk_disable+0x0/0xb0) from [<c012d388>] (udc_disable+0x54/0x68)
 r5:c0222e08 r4:f2600000
 [<c012d334>] (udc_disable+0x0/0x68) from [<c00133a8>] 
(pxa2xx_udc_probe+0x194/0x2c0)
 r5:c0216304 r4:c0222e08
[<c0013214>] (pxa2xx_udc_probe+0x0/0x2c0) from [<c011f318>] 
(platform_drv_probe+0x20/0x24)
...

This happens because udc_probe tries to disable clock that isn't
yet enabled (udc_probe() calls udc_disable() to reinit hardware).

That warning isn't a fluffy one. That is, on ARCH_PXA, pxa2xx_udc
isn't functional without the patch below, because when clk_disable()
called on the already disabled clock, this will turn clk->enabled to
-1, and then clk_enable() will blank shot, see arch/arm/mach-pxa/clock.c:

int clk_enable(struct clk *clk)
{
...
        if (clk->enabled++ == 0)
                clk->ops->enable(clk);
...
}

Signed-off-by: Anton Vorontsov <[EMAIL PROTECTED]>
---
 drivers/usb/gadget/pxa2xx_udc.c |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 4402d6f..f2ba235 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -929,7 +929,7 @@ static int pxa2xx_udc_wakeup(struct usb_gadget *_gadget)
 
 static void stop_activity(struct pxa2xx_udc *, struct usb_gadget_driver *);
 static void udc_enable (struct pxa2xx_udc *);
-static void udc_disable(struct pxa2xx_udc *);
+static void udc_disable(struct pxa2xx_udc *, bool);
 
 /* We disable the UDC -- and its 48 MHz clock -- whenever it's not
  * in active use.
@@ -947,7 +947,7 @@ static int pullup(struct pxa2xx_udc *udc, int is_active)
                                : "(no driver)");
                        stop_activity(udc, udc->driver);
                }
-               udc_disable(udc);
+               udc_disable(udc, true);
        }
        return 0;
 }
@@ -1134,7 +1134,7 @@ static const struct file_operations debug_fops = {
 /*
  *     udc_disable - disable USB device controller
  */
-static void udc_disable(struct pxa2xx_udc *dev)
+static void udc_disable(struct pxa2xx_udc *dev, bool enabled)
 {
        /* block all irqs */
        udc_set_mask_UDCCR(UDCCR_SRM|UDCCR_REM);
@@ -1148,7 +1148,8 @@ static void udc_disable(struct pxa2xx_udc *dev)
 
 #ifdef CONFIG_ARCH_PXA
         /* Disable clock for USB device */
-       clk_disable(dev->clk);
+       if (enabled)
+               clk_disable(dev->clk);
 #endif
 
        ep0_idle (dev);
@@ -2183,7 +2184,7 @@ static int __init pxa2xx_udc_probe(struct platform_device 
*pdev)
        the_controller = dev;
        platform_set_drvdata(pdev, dev);
 
-       udc_disable(dev);
+       udc_disable(dev, false);
        udc_reinit(dev);
 
        dev->vbus = is_vbus_present();
@@ -2269,7 +2270,7 @@ static int __exit pxa2xx_udc_remove(struct 
platform_device *pdev)
        if (dev->driver)
                return -EBUSY;
 
-       udc_disable(dev);
+       udc_disable(dev, true);
        remove_debug_files(dev);
 
        if (dev->got_irq) {
-- 
1.5.4.3
-
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to