From: Ajit Pal Singh Date: Mon, 14 Jul 2014 14:33:31 +0000 (+0100) Subject: pwm: sti: Sync between enable/disable calls X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=6ad6b838e11d8d67950716e0715b1d71bdd0769e;p=linux-beck.git pwm: sti: Sync between enable/disable calls ST PWM IP has a common enable/disable control for all the PWM channels on a PWM cell. Disables PWM output on the PWM HW only when disable is called for the last channel. Signed-off-by: Ajit Pal Singh Signed-off-by: Lee Jones Signed-off-by: Thierry Reding --- diff --git a/drivers/pwm/pwm-sti.c b/drivers/pwm/pwm-sti.c index 2d3260571b5a..f98afe4906fb 100644 --- a/drivers/pwm/pwm-sti.c +++ b/drivers/pwm/pwm-sti.c @@ -59,6 +59,8 @@ struct sti_pwm_chip { unsigned long *pwm_periods; struct pwm_chip chip; struct pwm_device *cur; + unsigned int en_count; + struct mutex sti_pwm_lock; /* To sync between enable/disable calls */ void __iomem *mmio; }; @@ -236,32 +238,44 @@ static int sti_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) { struct sti_pwm_chip *pc = to_sti_pwmchip(chip); struct device *dev = pc->dev; - int ret; - - ret = clk_enable(pc->clk); - if (ret) - return ret; + int ret = 0; - ret = regmap_field_write(pc->pwm_en, 1); - if (ret) - dev_err(dev, "%s,pwm_en write failed\n", __func__); + /* + * Since we have a common enable for all PWM channels, + * do not enable if already enabled. + */ + mutex_lock(&pc->sti_pwm_lock); + if (!pc->en_count) { + ret = clk_enable(pc->clk); + if (ret) + goto out; + ret = regmap_field_write(pc->pwm_en, 1); + if (ret) { + dev_err(dev, "failed to enable PWM device:%d\n", + pwm->hwpwm); + goto out; + } + } + pc->en_count++; +out: + mutex_unlock(&pc->sti_pwm_lock); return ret; } static void sti_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) { struct sti_pwm_chip *pc = to_sti_pwmchip(chip); - struct device *dev = pc->dev; - unsigned int val; + mutex_lock(&pc->sti_pwm_lock); + if (--pc->en_count) { + mutex_unlock(&pc->sti_pwm_lock); + return; + } regmap_field_write(pc->pwm_en, 0); - regmap_read(pc->regmap, STI_CNT, &val); - - dev_dbg(dev, "pwm counter :%u\n", val); - clk_disable(pc->clk); + mutex_unlock(&pc->sti_pwm_lock); } static const struct pwm_ops sti_pwm_ops = { @@ -352,6 +366,8 @@ static int sti_pwm_probe(struct platform_device *pdev) pc->cdata = cdata; pc->dev = dev; + pc->en_count = 0; + mutex_init(&pc->sti_pwm_lock); ret = sti_pwm_probe_dt(pc); if (ret)