usb: phy: ab8500-usb: add transceiver clock control
authorMian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
Wed, 15 May 2013 12:03:26 +0000 (14:03 +0200)
committerFelipe Balbi <balbi@ti.com>
Tue, 28 May 2013 17:00:46 +0000 (20:00 +0300)
Add common clock support code for the ab8500-usb phy driver.

Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Maxime Coquelin <maxime.coquelin@st.com>
Signed-off-by: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
Signed-off-by: Fabio Baltieri <fabio.baltieri@linaro.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/phy/phy-ab8500-usb.c

index f760e935e059dc6158bba3aa11459bc91858bcb1..bdf7f570b5e4c7af62ca8f88a63422af4718fd49 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/notifier.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/err.h>
 #include <linux/mfd/abx500.h>
 #include <linux/mfd/abx500/ab8500.h>
 #include <linux/usb/musb-ux500.h>
@@ -126,6 +128,7 @@ struct ab8500_usb {
        unsigned vbus_draw;
        struct work_struct phy_dis_work;
        enum ab8500_usb_mode mode;
+       struct clk *sysclk;
        struct regulator *v_ape;
        struct regulator *v_musb;
        struct regulator *v_ulpi;
@@ -252,6 +255,9 @@ static void ab8500_usb_phy_enable(struct ab8500_usb *ab, bool sel_host)
        if (IS_ERR(ab->pinctrl))
                dev_err(ab->dev, "could not get/set default pinstate\n");
 
+       if (clk_prepare_enable(ab->sysclk))
+               dev_err(ab->dev, "can't prepare/enable clock\n");
+
        ab8500_usb_regulator_enable(ab);
 
        abx500_mask_and_set_register_interruptible(ab->dev,
@@ -274,6 +280,8 @@ static void ab8500_usb_phy_disable(struct ab8500_usb *ab, bool sel_host)
        /* Needed to disable the phy.*/
        ab8500_usb_wd_workaround(ab);
 
+       clk_disable_unprepare(ab->sysclk);
+
        ab8500_usb_regulator_disable(ab);
 
        if (!IS_ERR(ab->pinctrl)) {
@@ -784,6 +792,12 @@ static int ab8500_usb_probe(struct platform_device *pdev)
        if (err)
                return err;
 
+       ab->sysclk = devm_clk_get(ab->dev, "sysclk");
+       if (IS_ERR(ab->sysclk)) {
+               dev_err(ab->dev, "Could not get sysclk.\n");
+               return PTR_ERR(ab->sysclk);
+       }
+
        err = ab8500_usb_irq_setup(pdev, ab);
        if (err < 0)
                return err;