diff options
Diffstat (limited to 'drivers/pwm')
-rw-r--r-- | drivers/pwm/core.c | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 3998ebd51db4..60b8ccc1fd7c 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c | |||
@@ -639,8 +639,35 @@ static struct pwm_chip *of_node_to_pwmchip(struct device_node *np) | |||
639 | return ERR_PTR(-EPROBE_DEFER); | 639 | return ERR_PTR(-EPROBE_DEFER); |
640 | } | 640 | } |
641 | 641 | ||
642 | static struct device_link *pwm_device_link_add(struct device *dev, | ||
643 | struct pwm_device *pwm) | ||
644 | { | ||
645 | struct device_link *dl; | ||
646 | |||
647 | if (!dev) { | ||
648 | /* | ||
649 | * No device for the PWM consumer has been provided. It may | ||
650 | * impact the PM sequence ordering: the PWM supplier may get | ||
651 | * suspended before the consumer. | ||
652 | */ | ||
653 | dev_warn(pwm->chip->dev, | ||
654 | "No consumer device specified to create a link to\n"); | ||
655 | return NULL; | ||
656 | } | ||
657 | |||
658 | dl = device_link_add(dev, pwm->chip->dev, DL_FLAG_AUTOREMOVE_CONSUMER); | ||
659 | if (!dl) { | ||
660 | dev_err(dev, "failed to create device link to %s\n", | ||
661 | dev_name(pwm->chip->dev)); | ||
662 | return ERR_PTR(-EINVAL); | ||
663 | } | ||
664 | |||
665 | return dl; | ||
666 | } | ||
667 | |||
642 | /** | 668 | /** |
643 | * of_pwm_get() - request a PWM via the PWM framework | 669 | * of_pwm_get() - request a PWM via the PWM framework |
670 | * @dev: device for PWM consumer | ||
644 | * @np: device node to get the PWM from | 671 | * @np: device node to get the PWM from |
645 | * @con_id: consumer name | 672 | * @con_id: consumer name |
646 | * | 673 | * |
@@ -658,10 +685,12 @@ static struct pwm_chip *of_node_to_pwmchip(struct device_node *np) | |||
658 | * Returns: A pointer to the requested PWM device or an ERR_PTR()-encoded | 685 | * Returns: A pointer to the requested PWM device or an ERR_PTR()-encoded |
659 | * error code on failure. | 686 | * error code on failure. |
660 | */ | 687 | */ |
661 | struct pwm_device *of_pwm_get(struct device_node *np, const char *con_id) | 688 | struct pwm_device *of_pwm_get(struct device *dev, struct device_node *np, |
689 | const char *con_id) | ||
662 | { | 690 | { |
663 | struct pwm_device *pwm = NULL; | 691 | struct pwm_device *pwm = NULL; |
664 | struct of_phandle_args args; | 692 | struct of_phandle_args args; |
693 | struct device_link *dl; | ||
665 | struct pwm_chip *pc; | 694 | struct pwm_chip *pc; |
666 | int index = 0; | 695 | int index = 0; |
667 | int err; | 696 | int err; |
@@ -692,6 +721,14 @@ struct pwm_device *of_pwm_get(struct device_node *np, const char *con_id) | |||
692 | if (IS_ERR(pwm)) | 721 | if (IS_ERR(pwm)) |
693 | goto put; | 722 | goto put; |
694 | 723 | ||
724 | dl = pwm_device_link_add(dev, pwm); | ||
725 | if (IS_ERR(dl)) { | ||
726 | /* of_xlate ended up calling pwm_request_from_chip() */ | ||
727 | pwm_free(pwm); | ||
728 | pwm = ERR_CAST(dl); | ||
729 | goto put; | ||
730 | } | ||
731 | |||
695 | /* | 732 | /* |
696 | * If a consumer name was not given, try to look it up from the | 733 | * If a consumer name was not given, try to look it up from the |
697 | * "pwm-names" property if it exists. Otherwise use the name of | 734 | * "pwm-names" property if it exists. Otherwise use the name of |
@@ -767,6 +804,7 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id) | |||
767 | const char *dev_id = dev ? dev_name(dev) : NULL; | 804 | const char *dev_id = dev ? dev_name(dev) : NULL; |
768 | struct pwm_device *pwm; | 805 | struct pwm_device *pwm; |
769 | struct pwm_chip *chip; | 806 | struct pwm_chip *chip; |
807 | struct device_link *dl; | ||
770 | unsigned int best = 0; | 808 | unsigned int best = 0; |
771 | struct pwm_lookup *p, *chosen = NULL; | 809 | struct pwm_lookup *p, *chosen = NULL; |
772 | unsigned int match; | 810 | unsigned int match; |
@@ -774,7 +812,7 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id) | |||
774 | 812 | ||
775 | /* look up via DT first */ | 813 | /* look up via DT first */ |
776 | if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node) | 814 | if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node) |
777 | return of_pwm_get(dev->of_node, con_id); | 815 | return of_pwm_get(dev, dev->of_node, con_id); |
778 | 816 | ||
779 | /* | 817 | /* |
780 | * We look up the provider in the static table typically provided by | 818 | * We look up the provider in the static table typically provided by |
@@ -851,6 +889,12 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id) | |||
851 | if (IS_ERR(pwm)) | 889 | if (IS_ERR(pwm)) |
852 | return pwm; | 890 | return pwm; |
853 | 891 | ||
892 | dl = pwm_device_link_add(dev, pwm); | ||
893 | if (IS_ERR(dl)) { | ||
894 | pwm_free(pwm); | ||
895 | return ERR_CAST(dl); | ||
896 | } | ||
897 | |||
854 | pwm->args.period = chosen->period; | 898 | pwm->args.period = chosen->period; |
855 | pwm->args.polarity = chosen->polarity; | 899 | pwm->args.polarity = chosen->polarity; |
856 | 900 | ||
@@ -943,7 +987,7 @@ struct pwm_device *devm_of_pwm_get(struct device *dev, struct device_node *np, | |||
943 | if (!ptr) | 987 | if (!ptr) |
944 | return ERR_PTR(-ENOMEM); | 988 | return ERR_PTR(-ENOMEM); |
945 | 989 | ||
946 | pwm = of_pwm_get(np, con_id); | 990 | pwm = of_pwm_get(dev, np, con_id); |
947 | if (!IS_ERR(pwm)) { | 991 | if (!IS_ERR(pwm)) { |
948 | *ptr = pwm; | 992 | *ptr = pwm; |
949 | devres_add(dev, ptr); | 993 | devres_add(dev, ptr); |