aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pwm
diff options
context:
space:
mode:
authorAjit Pal Singh <ajitpal.singh@st.com>2014-07-14 10:33:31 -0400
committerThierry Reding <thierry.reding@gmail.com>2014-08-08 07:12:45 -0400
commit6ad6b838e11d8d67950716e0715b1d71bdd0769e (patch)
tree3510898dbd6dc9c4ebbb4a50a4adbe05dca6670a /drivers/pwm
parent5165166e8a1551fb80afa5fdaad6f2ea34d92285 (diff)
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 <ajitpal.singh@st.com> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Diffstat (limited to 'drivers/pwm')
-rw-r--r--drivers/pwm/pwm-sti.c44
1 files changed, 30 insertions, 14 deletions
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 {
59 unsigned long *pwm_periods; 59 unsigned long *pwm_periods;
60 struct pwm_chip chip; 60 struct pwm_chip chip;
61 struct pwm_device *cur; 61 struct pwm_device *cur;
62 unsigned int en_count;
63 struct mutex sti_pwm_lock; /* To sync between enable/disable calls */
62 void __iomem *mmio; 64 void __iomem *mmio;
63}; 65};
64 66
@@ -236,32 +238,44 @@ static int sti_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
236{ 238{
237 struct sti_pwm_chip *pc = to_sti_pwmchip(chip); 239 struct sti_pwm_chip *pc = to_sti_pwmchip(chip);
238 struct device *dev = pc->dev; 240 struct device *dev = pc->dev;
239 int ret; 241 int ret = 0;
240
241 ret = clk_enable(pc->clk);
242 if (ret)
243 return ret;
244 242
245 ret = regmap_field_write(pc->pwm_en, 1); 243 /*
246 if (ret) 244 * Since we have a common enable for all PWM channels,
247 dev_err(dev, "%s,pwm_en write failed\n", __func__); 245 * do not enable if already enabled.
246 */
247 mutex_lock(&pc->sti_pwm_lock);
248 if (!pc->en_count) {
249 ret = clk_enable(pc->clk);
250 if (ret)
251 goto out;
248 252
253 ret = regmap_field_write(pc->pwm_en, 1);
254 if (ret) {
255 dev_err(dev, "failed to enable PWM device:%d\n",
256 pwm->hwpwm);
257 goto out;
258 }
259 }
260 pc->en_count++;
261out:
262 mutex_unlock(&pc->sti_pwm_lock);
249 return ret; 263 return ret;
250} 264}
251 265
252static void sti_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) 266static void sti_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
253{ 267{
254 struct sti_pwm_chip *pc = to_sti_pwmchip(chip); 268 struct sti_pwm_chip *pc = to_sti_pwmchip(chip);
255 struct device *dev = pc->dev;
256 unsigned int val;
257 269
270 mutex_lock(&pc->sti_pwm_lock);
271 if (--pc->en_count) {
272 mutex_unlock(&pc->sti_pwm_lock);
273 return;
274 }
258 regmap_field_write(pc->pwm_en, 0); 275 regmap_field_write(pc->pwm_en, 0);
259 276
260 regmap_read(pc->regmap, STI_CNT, &val);
261
262 dev_dbg(dev, "pwm counter :%u\n", val);
263
264 clk_disable(pc->clk); 277 clk_disable(pc->clk);
278 mutex_unlock(&pc->sti_pwm_lock);
265} 279}
266 280
267static const struct pwm_ops sti_pwm_ops = { 281static const struct pwm_ops sti_pwm_ops = {
@@ -352,6 +366,8 @@ static int sti_pwm_probe(struct platform_device *pdev)
352 366
353 pc->cdata = cdata; 367 pc->cdata = cdata;
354 pc->dev = dev; 368 pc->dev = dev;
369 pc->en_count = 0;
370 mutex_init(&pc->sti_pwm_lock);
355 371
356 ret = sti_pwm_probe_dt(pc); 372 ret = sti_pwm_probe_dt(pc);
357 if (ret) 373 if (ret)