]> Pileus Git - ~andy/linux/commitdiff
usb: gadget: lpc32xx_udc: move clock init to clock framework
authorAlexandre Pereira da Silva <aletes.xgr@gmail.com>
Wed, 20 Jun 2012 12:03:15 +0000 (09:03 -0300)
committerFelipe Balbi <balbi@ti.com>
Fri, 22 Jun 2012 10:10:03 +0000 (13:10 +0300)
Moves clock initialization to the clock framework.

Signed-off-by: Alexandre Pereira da Silva <aletes.xgr@gmail.com>
Acked-by: Roland Stigge <stigge@antcom.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/gadget/lpc32xx_udc.c

index 262acfd53e32b04f9d98f2c36d6adc84b64ef06a..d227d93ce899d72471f0d093fe6515697f0ecc70 100644 (file)
@@ -164,6 +164,7 @@ struct lpc32xx_udc {
        int                     udp_irq[4];
        struct clk              *usb_pll_clk;
        struct clk              *usb_slv_clk;
+       struct clk              *usb_otg_clk;
 
        /* DMA support */
        u32                     *udca_v_base;
@@ -226,33 +227,15 @@ static inline struct lpc32xx_udc *to_udc(struct usb_gadget *g)
 #define UDCA_BUFF_SIZE (128)
 
 /* TODO: When the clock framework is introduced in LPC32xx, IO_ADDRESS will
- * be replaced with an inremap()ed pointer, see USB_OTG_CLK_CTRL()
+ * be replaced with an inremap()ed pointer
  * */
 #define USB_CTRL               IO_ADDRESS(LPC32XX_CLK_PM_BASE + 0x64)
-#define USB_CLOCK_MASK         (AHB_M_CLOCK_ON | OTG_CLOCK_ON | \
-                                DEV_CLOCK_ON | I2C_CLOCK_ON)
 
 /* USB_CTRL bit defines */
 #define USB_SLAVE_HCLK_EN      (1 << 24)
 #define USB_HOST_NEED_CLK_EN   (1 << 21)
 #define USB_DEV_NEED_CLK_EN    (1 << 22)
 
-#define USB_OTG_CLK_CTRL(udc)  ((udc)->udp_baseaddr + 0xFF4)
-#define USB_OTG_CLK_STAT(udc)  ((udc)->udp_baseaddr + 0xFF8)
-
-/* USB_OTG_CLK_CTRL bit defines */
-#define AHB_M_CLOCK_ON         (1 << 4)
-#define OTG_CLOCK_ON           (1 << 3)
-#define I2C_CLOCK_ON           (1 << 2)
-#define DEV_CLOCK_ON           (1 << 1)
-#define HOST_CLOCK_ON          (1 << 0)
-
-#define USB_OTG_STAT_CONTROL(udc) (udc->udp_baseaddr + 0x110)
-
-/* USB_OTG_STAT_CONTROL bit defines */
-#define TRANSPARENT_I2C_EN     (1 << 7)
-#define HOST_EN                        (1 << 0)
-
 /**********************************************************************
  * USB device controller register offsets
  **********************************************************************/
@@ -676,7 +659,7 @@ static void isp1301_udc_configure(struct lpc32xx_udc *udc)
                ISP1301_I2C_INTERRUPT_RISING, INT_VBUS_VLD);
 
        /* Enable usb_need_clk clock after transceiver is initialized */
-       writel((readl(USB_CTRL) | (1 << 22)), USB_CTRL);
+       writel((readl(USB_CTRL) | USB_DEV_NEED_CLK_EN), USB_CTRL);
 
        dev_info(udc->dev, "ISP1301 Vendor ID  : 0x%04x\n",
                 i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x00));
@@ -1009,11 +992,8 @@ static void udc_dd_free(struct lpc32xx_udc *udc, struct lpc32xx_usbd_dd_gad *dd)
 /* Enables or disables most of the USB system clocks when low power mode is
  * needed. Clocks are typically started on a connection event, and disabled
  * when a cable is disconnected */
-#define OTGOFF_CLK_MASK (AHB_M_CLOCK_ON | I2C_CLOCK_ON)
 static void udc_clk_set(struct lpc32xx_udc *udc, int enable)
 {
-       int to = 1000;
-
        if (enable != 0) {
                if (udc->clocked)
                        return;
@@ -1027,14 +1007,7 @@ static void udc_clk_set(struct lpc32xx_udc *udc, int enable)
                writel(readl(USB_CTRL) | USB_DEV_NEED_CLK_EN,
                             USB_CTRL);
 
-               /* Set to enable all needed USB OTG clocks */
-               writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL(udc));
-
-               while (((readl(USB_OTG_CLK_STAT(udc)) & USB_CLOCK_MASK) !=
-                       USB_CLOCK_MASK) && (to > 0))
-                       to--;
-               if (!to)
-                       dev_dbg(udc->dev, "Cannot enable USB OTG clocking\n");
+               clk_enable(udc->usb_otg_clk);
        } else {
                if (!udc->clocked)
                        return;
@@ -1046,19 +1019,11 @@ static void udc_clk_set(struct lpc32xx_udc *udc, int enable)
                /* 48MHz PLL dpwn */
                clk_disable(udc->usb_pll_clk);
 
-               /* Enable the USB device clock */
+               /* Disable the USB device clock */
                writel(readl(USB_CTRL) & ~USB_DEV_NEED_CLK_EN,
                             USB_CTRL);
 
-               /* Set to enable all needed USB OTG clocks */
-               writel(OTGOFF_CLK_MASK, USB_OTG_CLK_CTRL(udc));
-
-               while (((readl(USB_OTG_CLK_STAT(udc)) &
-                        OTGOFF_CLK_MASK) !=
-                       OTGOFF_CLK_MASK) && (to > 0))
-                       to--;
-               if (!to)
-                       dev_dbg(udc->dev, "Cannot disable USB OTG clocking\n");
+               clk_disable(udc->usb_otg_clk);
        }
 }
 
@@ -3238,6 +3203,12 @@ static int __init lpc32xx_udc_probe(struct platform_device *pdev)
                retval = PTR_ERR(udc->usb_slv_clk);
                goto usb_clk_get_fail;
        }
+       udc->usb_otg_clk = clk_get(&pdev->dev, "ck_usb_otg");
+       if (IS_ERR(udc->usb_otg_clk)) {
+               dev_err(udc->dev, "failed to acquire USB otg clock\n");
+               retval = PTR_ERR(udc->usb_slv_clk);
+               goto usb_otg_clk_get_fail;
+       }
 
        /* Setup PLL clock to 48MHz */
        retval = clk_enable(udc->usb_pll_clk);
@@ -3261,15 +3232,12 @@ static int __init lpc32xx_udc_probe(struct platform_device *pdev)
                goto usb_clk_enable_fail;
        }
 
-       /* Set to enable all needed USB OTG clocks */
-       writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL(udc));
-
-       i = 1000;
-       while (((readl(USB_OTG_CLK_STAT(udc)) & USB_CLOCK_MASK) !=
-               USB_CLOCK_MASK) && (i > 0))
-               i--;
-       if (!i)
-               dev_dbg(udc->dev, "USB OTG clocks not correctly enabled\n");
+       /* Enable USB OTG clock */
+       retval = clk_enable(udc->usb_otg_clk);
+       if (retval < 0) {
+               dev_err(udc->dev, "failed to start USB otg clock\n");
+               goto usb_otg_clk_enable_fail;
+       }
 
        /* Setup deferred workqueue data */
        udc->poweron = udc->pullup = 0;
@@ -3389,12 +3357,16 @@ dma_alloc_fail:
        dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE,
                          udc->udca_v_base, udc->udca_p_base);
 i2c_fail:
+       clk_disable(udc->usb_otg_clk);
+usb_otg_clk_enable_fail:
        clk_disable(udc->usb_slv_clk);
 usb_clk_enable_fail:
 pll_set_fail:
        clk_disable(udc->usb_pll_clk);
 pll_enable_fail:
        clk_put(udc->usb_slv_clk);
+usb_otg_clk_get_fail:
+       clk_put(udc->usb_otg_clk);
 usb_clk_get_fail:
        clk_put(udc->usb_pll_clk);
 pll_get_fail:
@@ -3432,6 +3404,8 @@ static int __devexit lpc32xx_udc_remove(struct platform_device *pdev)
 
        device_unregister(&udc->gadget.dev);
 
+       clk_disable(udc->usb_otg_clk);
+       clk_put(udc->usb_otg_clk);
        clk_disable(udc->usb_slv_clk);
        clk_put(udc->usb_slv_clk);
        clk_disable(udc->usb_pll_clk);
@@ -3445,7 +3419,6 @@ static int __devexit lpc32xx_udc_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int lpc32xx_udc_suspend(struct platform_device *pdev, pm_message_t mesg)
 {
-       int to = 1000;
        struct lpc32xx_udc *udc = platform_get_drvdata(pdev);
 
        if (udc->clocked) {
@@ -3460,15 +3433,6 @@ static int lpc32xx_udc_suspend(struct platform_device *pdev, pm_message_t mesg)
                   on resume */
                udc->clocked = 1;
 
-               /* Kill OTG and I2C clocks */
-               writel(0, USB_OTG_CLK_CTRL(udc));
-               while (((readl(USB_OTG_CLK_STAT(udc)) & OTGOFF_CLK_MASK) !=
-                       OTGOFF_CLK_MASK) && (to > 0))
-                       to--;
-               if (!to)
-                       dev_dbg(udc->dev,
-                               "USB OTG clocks not correctly enabled\n");
-
                /* Kill global USB clock */
                clk_disable(udc->usb_slv_clk);
        }