Commit 7628083227b6bc4a7e33d7c381d7a4e558424b6b added clock preparation in
interrupt context. This is not allowed as it might sleep. Move clock
preparation and setting clock rate into process context (at91udc_probe).

Signed-off-by: Ronald Wahl <ronald.w...@raritan.com>
---
 drivers/usb/gadget/udc/at91_udc.c | 44 ++++++++++++++++++++++++++++-----------
 1 file changed, 32 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/gadget/udc/at91_udc.c 
b/drivers/usb/gadget/udc/at91_udc.c
index cfd18bc..0d685d0 100644
--- a/drivers/usb/gadget/udc/at91_udc.c
+++ b/drivers/usb/gadget/udc/at91_udc.c
@@ -870,12 +870,10 @@ static void clk_on(struct at91_udc *udc)
                return;
        udc->clocked = 1;
 
-       if (IS_ENABLED(CONFIG_COMMON_CLK)) {
-               clk_set_rate(udc->uclk, 48000000);
-               clk_prepare_enable(udc->uclk);
-       }
-       clk_prepare_enable(udc->iclk);
-       clk_prepare_enable(udc->fclk);
+       if (IS_ENABLED(CONFIG_COMMON_CLK))
+               clk_enable(udc->uclk);
+       clk_enable(udc->iclk);
+       clk_enable(udc->fclk);
 }
 
 static void clk_off(struct at91_udc *udc)
@@ -884,10 +882,10 @@ static void clk_off(struct at91_udc *udc)
                return;
        udc->clocked = 0;
        udc->gadget.speed = USB_SPEED_UNKNOWN;
-       clk_disable_unprepare(udc->fclk);
-       clk_disable_unprepare(udc->iclk);
+       clk_disable(udc->fclk);
+       clk_disable(udc->iclk);
        if (IS_ENABLED(CONFIG_COMMON_CLK))
-               clk_disable_unprepare(udc->uclk);
+               clk_disable(udc->uclk);
 }
 
 /*
@@ -1780,14 +1778,24 @@ static int at91udc_probe(struct platform_device *pdev)
        }
 
        /* don't do anything until we have both gadget driver and VBUS */
+       if (IS_ENABLED(CONFIG_COMMON_CLK)) {
+               clk_set_rate(udc->uclk, 48000000);
+               retval = clk_prepare(udc->uclk);
+               if (retval)
+                       goto fail1;
+       }
+       retval = clk_prepare(udc->fclk);
+       if (retval)
+               goto fail1a;
+
        retval = clk_prepare_enable(udc->iclk);
        if (retval)
-               goto fail1;
+               goto fail1b;
        at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
        at91_udp_write(udc, AT91_UDP_IDR, 0xffffffff);
        /* Clear all pending interrupts - UDP may be used by bootloader. */
        at91_udp_write(udc, AT91_UDP_ICR, 0xffffffff);
-       clk_disable_unprepare(udc->iclk);
+       clk_disable(udc->iclk);
 
        /* request UDC and maybe VBUS irqs */
        udc->udp_irq = platform_get_irq(pdev, 0);
@@ -1795,7 +1803,7 @@ static int at91udc_probe(struct platform_device *pdev)
                        0, driver_name, udc);
        if (retval < 0) {
                DBG("request irq %d failed\n", udc->udp_irq);
-               goto fail1;
+               goto fail1c;
        }
        if (gpio_is_valid(udc->board.vbus_pin)) {
                retval = gpio_request(udc->board.vbus_pin, "udc_vbus");
@@ -1848,6 +1856,13 @@ fail3:
                gpio_free(udc->board.vbus_pin);
 fail2:
        free_irq(udc->udp_irq, udc);
+fail1c:
+       clk_unprepare(udc->iclk);
+fail1b:
+       clk_unprepare(udc->fclk);
+fail1a:
+       if (IS_ENABLED(CONFIG_COMMON_CLK))
+               clk_unprepare(udc->uclk);
 fail1:
        if (IS_ENABLED(CONFIG_COMMON_CLK) && !IS_ERR(udc->uclk))
                clk_put(udc->uclk);
@@ -1896,6 +1911,11 @@ static int __exit at91udc_remove(struct platform_device 
*pdev)
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        release_mem_region(res->start, resource_size(res));
 
+       if (IS_ENABLED(CONFIG_COMMON_CLK))
+               clk_unprepare(udc->uclk);
+       clk_unprepare(udc->fclk);
+       clk_unprepare(udc->iclk);
+
        clk_put(udc->iclk);
        clk_put(udc->fclk);
        if (IS_ENABLED(CONFIG_COMMON_CLK))
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to