aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pwm/core.c
diff options
context:
space:
mode:
authorJonathan Richardson <jonathar@broadcom.com>2015-10-16 20:40:58 -0400
committerThierry Reding <thierry.reding@gmail.com>2015-11-10 07:06:16 -0500
commitd1cd21427747f15920cd726f5f67a07880e7dee4 (patch)
tree429e8844a75def440f47479f751e60f9ff685f0c /drivers/pwm/core.c
parentf080be27d7d9333e4815655a2cedab91c3aa7acc (diff)
pwm: Set enable state properly on failed call to enable
The pwm_enable() function didn't clear the enabled bit if a call to the driver's ->enable() callback returned an error. The result was that the state of the PWM core was wrong. Clearing the bit when enable returns an error ensures the state is properly set. Tested-by: Jonathan Richardson <jonathar@broadcom.com> Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Jonathan Richardson <jonathar@broadcom.com> [thierry.reding@gmail.com: add missing kerneldoc for the lock] Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Diffstat (limited to 'drivers/pwm/core.c')
-rw-r--r--drivers/pwm/core.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 3f9df3ea3350..b8f6c309c160 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -269,6 +269,7 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
269 pwm->pwm = chip->base + i; 269 pwm->pwm = chip->base + i;
270 pwm->hwpwm = i; 270 pwm->hwpwm = i;
271 pwm->polarity = polarity; 271 pwm->polarity = polarity;
272 mutex_init(&pwm->lock);
272 273
273 radix_tree_insert(&pwm_tree, pwm->pwm, pwm); 274 radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
274 } 275 }
@@ -473,16 +474,22 @@ int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
473 if (!pwm->chip->ops->set_polarity) 474 if (!pwm->chip->ops->set_polarity)
474 return -ENOSYS; 475 return -ENOSYS;
475 476
476 if (pwm_is_enabled(pwm)) 477 mutex_lock(&pwm->lock);
477 return -EBUSY; 478
479 if (pwm_is_enabled(pwm)) {
480 err = -EBUSY;
481 goto unlock;
482 }
478 483
479 err = pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity); 484 err = pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
480 if (err) 485 if (err)
481 return err; 486 goto unlock;
482 487
483 pwm->polarity = polarity; 488 pwm->polarity = polarity;
484 489
485 return 0; 490unlock:
491 mutex_unlock(&pwm->lock);
492 return err;
486} 493}
487EXPORT_SYMBOL_GPL(pwm_set_polarity); 494EXPORT_SYMBOL_GPL(pwm_set_polarity);
488 495
@@ -494,10 +501,22 @@ EXPORT_SYMBOL_GPL(pwm_set_polarity);
494 */ 501 */
495int pwm_enable(struct pwm_device *pwm) 502int pwm_enable(struct pwm_device *pwm)
496{ 503{
497 if (pwm && !test_and_set_bit(PWMF_ENABLED, &pwm->flags)) 504 int err = 0;
498 return pwm->chip->ops->enable(pwm->chip, pwm); 505
506 if (!pwm)
507 return -EINVAL;
508
509 mutex_lock(&pwm->lock);
510
511 if (!test_and_set_bit(PWMF_ENABLED, &pwm->flags)) {
512 err = pwm->chip->ops->enable(pwm->chip, pwm);
513 if (err)
514 clear_bit(PWMF_ENABLED, &pwm->flags);
515 }
516
517 mutex_unlock(&pwm->lock);
499 518
500 return pwm ? 0 : -EINVAL; 519 return err;
501} 520}
502EXPORT_SYMBOL_GPL(pwm_enable); 521EXPORT_SYMBOL_GPL(pwm_enable);
503 522