diff options
Diffstat (limited to 'drivers/pwm/pwm-imx27.c')
-rw-r--r-- | drivers/pwm/pwm-imx27.c | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c index 35a7ac42269c..a6e40d4c485f 100644 --- a/drivers/pwm/pwm-imx27.c +++ b/drivers/pwm/pwm-imx27.c @@ -18,7 +18,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/pwm.h> #include <linux/slab.h> @@ -96,9 +95,8 @@ struct pwm_imx27_chip { #define to_pwm_imx27_chip(chip) container_of(chip, struct pwm_imx27_chip, chip) -static int pwm_imx27_clk_prepare_enable(struct pwm_chip *chip) +static int pwm_imx27_clk_prepare_enable(struct pwm_imx27_chip *imx) { - struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip); int ret; ret = clk_prepare_enable(imx->clk_ipg); @@ -114,10 +112,8 @@ static int pwm_imx27_clk_prepare_enable(struct pwm_chip *chip) return 0; } -static void pwm_imx27_clk_disable_unprepare(struct pwm_chip *chip) +static void pwm_imx27_clk_disable_unprepare(struct pwm_imx27_chip *imx) { - struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip); - clk_disable_unprepare(imx->clk_per); clk_disable_unprepare(imx->clk_ipg); } @@ -130,7 +126,7 @@ static void pwm_imx27_get_state(struct pwm_chip *chip, u64 tmp; int ret; - ret = pwm_imx27_clk_prepare_enable(chip); + ret = pwm_imx27_clk_prepare_enable(imx); if (ret < 0) return; @@ -174,8 +170,7 @@ static void pwm_imx27_get_state(struct pwm_chip *chip, tmp = NSEC_PER_SEC * (u64)(val); state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk); - if (!state->enabled) - pwm_imx27_clk_disable_unprepare(chip); + pwm_imx27_clk_disable_unprepare(imx); } static void pwm_imx27_sw_reset(struct pwm_chip *chip) @@ -259,7 +254,7 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, if (cstate.enabled) { pwm_imx27_wait_fifo_slot(chip, pwm); } else { - ret = pwm_imx27_clk_prepare_enable(chip); + ret = pwm_imx27_clk_prepare_enable(imx); if (ret) return ret; @@ -289,8 +284,8 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, writel(cr, imx->mmio_base + MX3_PWMCR); - if (!state->enabled && cstate.enabled) - pwm_imx27_clk_disable_unprepare(chip); + if (!state->enabled) + pwm_imx27_clk_disable_unprepare(imx); return 0; } @@ -310,6 +305,8 @@ MODULE_DEVICE_TABLE(of, pwm_imx27_dt_ids); static int pwm_imx27_probe(struct platform_device *pdev) { struct pwm_imx27_chip *imx; + int ret; + u32 pwmcr; imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL); if (imx == NULL) @@ -352,6 +349,15 @@ static int pwm_imx27_probe(struct platform_device *pdev) if (IS_ERR(imx->mmio_base)) return PTR_ERR(imx->mmio_base); + ret = pwm_imx27_clk_prepare_enable(imx); + if (ret) + return ret; + + /* keep clks on if pwm is running */ + pwmcr = readl(imx->mmio_base + MX3_PWMCR); + if (!(pwmcr & MX3_PWMCR_EN)) + pwm_imx27_clk_disable_unprepare(imx); + return pwmchip_add(&imx->chip); } @@ -361,8 +367,6 @@ static int pwm_imx27_remove(struct platform_device *pdev) imx = platform_get_drvdata(pdev); - pwm_imx27_clk_disable_unprepare(&imx->chip); - return pwmchip_remove(&imx->chip); } |