summaryrefslogtreecommitdiff
path: root/drivers/pwm/pwm-imx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pwm/pwm-imx.c')
-rw-r--r--drivers/pwm/pwm-imx.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
index d600fd5cd4ba..2c2818c4b96e 100644
--- a/drivers/pwm/pwm-imx.c
+++ b/drivers/pwm/pwm-imx.c
@@ -50,6 +50,7 @@
struct imx_chip {
struct clk *clk_per;
struct clk *clk_ipg;
+ struct clk *clk_32k;
void __iomem *mmio_base;
@@ -206,14 +207,29 @@ static int imx_pwm_config(struct pwm_chip *chip,
struct imx_chip *imx = to_imx_chip(chip);
int ret;
+ if (imx->clk_32k) {
+ ret = clk_prepare_enable(imx->clk_32k);
+ if (ret)
+ goto err1;
+ }
+
+ ret = clk_prepare_enable(imx->clk_per);
+ if (ret)
+ goto err2;
+
ret = clk_prepare_enable(imx->clk_ipg);
if (ret)
- return ret;
+ goto err3;
ret = imx->config(chip, pwm, duty_ns, period_ns);
clk_disable_unprepare(imx->clk_ipg);
-
+err3:
+ clk_disable_unprepare(imx->clk_per);
+err2:
+ if (imx->clk_32k)
+ clk_disable_unprepare(imx->clk_32k);
+err1:
return ret;
}
@@ -222,13 +238,30 @@ static int imx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
struct imx_chip *imx = to_imx_chip(chip);
int ret;
+ if (imx->clk_32k) {
+ ret = clk_prepare_enable(imx->clk_32k);
+ if (ret)
+ goto err1;
+ }
+
ret = clk_prepare_enable(imx->clk_per);
if (ret)
- return ret;
+ goto err2;
+
+ ret = clk_prepare_enable(imx->clk_ipg);
+ if (ret)
+ goto err3;
imx->set_enable(chip, true);
return 0;
+err3:
+ clk_disable_unprepare(imx->clk_per);
+err2:
+ if (imx->clk_32k)
+ clk_disable_unprepare(imx->clk_32k);
+err1:
+ return ret;
}
static void imx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
@@ -237,7 +270,10 @@ static void imx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
imx->set_enable(chip, false);
+ clk_disable_unprepare(imx->clk_ipg);
clk_disable_unprepare(imx->clk_per);
+ if (imx->clk_32k)
+ clk_disable_unprepare(imx->clk_32k);
}
static struct pwm_ops imx_pwm_ops = {
@@ -300,6 +336,10 @@ static int imx_pwm_probe(struct platform_device *pdev)
return PTR_ERR(imx->clk_ipg);
}
+ imx->clk_32k = devm_clk_get(&pdev->dev, "32k");
+ if (IS_ERR(imx->clk_32k))
+ imx->clk_32k = NULL;
+
imx->chip.ops = &imx_pwm_ops;
imx->chip.dev = &pdev->dev;
imx->chip.base = -1;