diff options
Diffstat (limited to 'drivers/pwm/core.c')
-rw-r--r-- | drivers/pwm/core.c | 82 |
1 files changed, 81 insertions, 1 deletions
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index c6e05078d3ad..f5acdaa52707 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c | |||
@@ -371,7 +371,7 @@ EXPORT_SYMBOL_GPL(pwm_free); | |||
371 | */ | 371 | */ |
372 | int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) | 372 | int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) |
373 | { | 373 | { |
374 | if (!pwm || period_ns == 0 || duty_ns > period_ns) | 374 | if (!pwm || duty_ns < 0 || period_ns <= 0 || duty_ns > period_ns) |
375 | return -EINVAL; | 375 | return -EINVAL; |
376 | 376 | ||
377 | return pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns); | 377 | return pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns); |
@@ -379,6 +379,28 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) | |||
379 | EXPORT_SYMBOL_GPL(pwm_config); | 379 | EXPORT_SYMBOL_GPL(pwm_config); |
380 | 380 | ||
381 | /** | 381 | /** |
382 | * pwm_set_polarity() - configure the polarity of a PWM signal | ||
383 | * @pwm: PWM device | ||
384 | * @polarity: new polarity of the PWM signal | ||
385 | * | ||
386 | * Note that the polarity cannot be configured while the PWM device is enabled | ||
387 | */ | ||
388 | int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity) | ||
389 | { | ||
390 | if (!pwm || !pwm->chip->ops) | ||
391 | return -EINVAL; | ||
392 | |||
393 | if (!pwm->chip->ops->set_polarity) | ||
394 | return -ENOSYS; | ||
395 | |||
396 | if (test_bit(PWMF_ENABLED, &pwm->flags)) | ||
397 | return -EBUSY; | ||
398 | |||
399 | return pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity); | ||
400 | } | ||
401 | EXPORT_SYMBOL_GPL(pwm_set_polarity); | ||
402 | |||
403 | /** | ||
382 | * pwm_enable() - start a PWM output toggling | 404 | * pwm_enable() - start a PWM output toggling |
383 | * @pwm: PWM device | 405 | * @pwm: PWM device |
384 | */ | 406 | */ |
@@ -624,6 +646,64 @@ out: | |||
624 | } | 646 | } |
625 | EXPORT_SYMBOL_GPL(pwm_put); | 647 | EXPORT_SYMBOL_GPL(pwm_put); |
626 | 648 | ||
649 | static void devm_pwm_release(struct device *dev, void *res) | ||
650 | { | ||
651 | pwm_put(*(struct pwm_device **)res); | ||
652 | } | ||
653 | |||
654 | /** | ||
655 | * devm_pwm_get() - resource managed pwm_get() | ||
656 | * @dev: device for PWM consumer | ||
657 | * @con_id: consumer name | ||
658 | * | ||
659 | * This function performs like pwm_get() but the acquired PWM device will | ||
660 | * automatically be released on driver detach. | ||
661 | */ | ||
662 | struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id) | ||
663 | { | ||
664 | struct pwm_device **ptr, *pwm; | ||
665 | |||
666 | ptr = devres_alloc(devm_pwm_release, sizeof(**ptr), GFP_KERNEL); | ||
667 | if (!ptr) | ||
668 | return ERR_PTR(-ENOMEM); | ||
669 | |||
670 | pwm = pwm_get(dev, con_id); | ||
671 | if (!IS_ERR(pwm)) { | ||
672 | *ptr = pwm; | ||
673 | devres_add(dev, ptr); | ||
674 | } else { | ||
675 | devres_free(ptr); | ||
676 | } | ||
677 | |||
678 | return pwm; | ||
679 | } | ||
680 | EXPORT_SYMBOL_GPL(devm_pwm_get); | ||
681 | |||
682 | static int devm_pwm_match(struct device *dev, void *res, void *data) | ||
683 | { | ||
684 | struct pwm_device **p = res; | ||
685 | |||
686 | if (WARN_ON(!p || !*p)) | ||
687 | return 0; | ||
688 | |||
689 | return *p == data; | ||
690 | } | ||
691 | |||
692 | /** | ||
693 | * devm_pwm_put() - resource managed pwm_put() | ||
694 | * @dev: device for PWM consumer | ||
695 | * @pwm: PWM device | ||
696 | * | ||
697 | * Release a PWM previously allocated using devm_pwm_get(). Calling this | ||
698 | * function is usually not needed because devm-allocated resources are | ||
699 | * automatically released on driver detach. | ||
700 | */ | ||
701 | void devm_pwm_put(struct device *dev, struct pwm_device *pwm) | ||
702 | { | ||
703 | WARN_ON(devres_release(dev, devm_pwm_release, devm_pwm_match, pwm)); | ||
704 | } | ||
705 | EXPORT_SYMBOL_GPL(devm_pwm_put); | ||
706 | |||
627 | #ifdef CONFIG_DEBUG_FS | 707 | #ifdef CONFIG_DEBUG_FS |
628 | static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s) | 708 | static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s) |
629 | { | 709 | { |