ARM: 5965/1: Fix soft lockup in at91 udc driver
[safe/jmp/linux-2.6] / drivers / usb / gadget / at91_udc.c
index 043e04d..df1bae9 100644 (file)
@@ -1370,6 +1370,12 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
 {
        struct at91_udc         *udc = _udc;
        u32                     rescans = 5;
+       int                     disable_clock = 0;
+
+       if (!udc->clocked) {
+               clk_on(udc);
+               disable_clock = 1;
+       }
 
        while (rescans--) {
                u32 status;
@@ -1458,6 +1464,9 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
                }
        }
 
+       if (disable_clock)
+               clk_off(udc);
+
        return IRQ_HANDLED;
 }
 
@@ -1656,9 +1665,7 @@ static int __init at91udc_probe(struct platform_device *pdev)
        if (!res)
                return -ENXIO;
 
-       if (!request_mem_region(res->start,
-                       res->end - res->start + 1,
-                       driver_name)) {
+       if (!request_mem_region(res->start, resource_size(res), driver_name)) {
                DBG("someone's using UDC memory\n");
                return -EBUSY;
        }
@@ -1699,7 +1706,7 @@ static int __init at91udc_probe(struct platform_device *pdev)
                udc->ep[3].maxpacket = 64;
        }
 
-       udc->udp_baseaddr = ioremap(res->start, res->end - res->start + 1);
+       udc->udp_baseaddr = ioremap(res->start, resource_size(res));
        if (!udc->udp_baseaddr) {
                retval = -ENOMEM;
                goto fail0a;
@@ -1781,7 +1788,7 @@ fail0a:
        if (cpu_is_at91rm9200())
                gpio_free(udc->board.pullup_pin);
 fail0:
-       release_mem_region(res->start, res->end - res->start + 1);
+       release_mem_region(res->start, resource_size(res));
        DBG("%s probe failed, %d\n", driver_name, retval);
        return retval;
 }
@@ -1813,7 +1820,7 @@ static int __exit at91udc_remove(struct platform_device *pdev)
                gpio_free(udc->board.pullup_pin);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       release_mem_region(res->start, res->end - res->start + 1);
+       release_mem_region(res->start, resource_size(res));
 
        clk_put(udc->iclk);
        clk_put(udc->fclk);