From ea0ed157863b7b650e3eff485a49cbc0925f5265 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 28 Feb 2014 13:29:06 +0100 Subject: PWM: Implement devicetree support This implements of_pwm_request() for PWM client drivers. Signed-off-by: Sascha Hauer --- drivers/pwm/core.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 7 deletions(-) (limited to 'drivers/pwm') diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 7f307244f9..cc33dec363 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -143,6 +143,24 @@ int pwmchip_remove(struct pwm_chip *chip) } EXPORT_SYMBOL_GPL(pwmchip_remove); +static int __pwm_request(struct pwm_device *pwm) +{ + int ret; + + if (test_bit(FLAG_REQUESTED, &pwm->flags)) + return -EBUSY; + + if (pwm->chip->ops->request) { + ret = pwm->chip->ops->request(pwm->chip); + if (ret) + return ret; + } + + set_bit(FLAG_REQUESTED, &pwm->flags); + + return 0; +} + /* * pwm_request - request a PWM device */ @@ -155,20 +173,59 @@ struct pwm_device *pwm_request(const char *devname) if (!pwm) return NULL; - if (test_bit(FLAG_REQUESTED, &pwm->flags)) + ret = __pwm_request(pwm); + if (ret) return NULL; - if (pwm->chip->ops->request) { - ret = pwm->chip->ops->request(pwm->chip); - if (ret) - return NULL; + return pwm; +} +EXPORT_SYMBOL_GPL(pwm_request); + +static struct pwm_device *of_node_to_pwm_device(struct device_node *np) +{ + struct pwm_device *pwm; + + list_for_each_entry(pwm, &pwm_list, node) { + if (pwm->hwdev && pwm->hwdev->device_node == np) + return pwm; } - set_bit(FLAG_REQUESTED, &pwm->flags); + return ERR_PTR(-ENODEV); +} + +struct pwm_device *of_pwm_request(struct device_node *np, const char *con_id) +{ + struct of_phandle_args args; + int index = 0; + struct pwm_device *pwm; + int ret; + + if (con_id) + return ERR_PTR(-EINVAL); + + ret = of_parse_phandle_with_args(np, "pwms", "#pwm-cells", index, + &args); + if (ret) { + pr_debug("%s(): can't parse \"pwms\" property\n", __func__); + return ERR_PTR(ret); + } + + pwm = of_node_to_pwm_device(args.np); + if (IS_ERR(pwm)) { + pr_debug("%s(): PWM chip not found\n", __func__); + return pwm; + } + + if (args.args_count > 1) + pwm_set_period(pwm, args.args[1]); + + ret = __pwm_request(pwm); + if (ret) + return ERR_PTR(-ret); return pwm; } -EXPORT_SYMBOL_GPL(pwm_request); +EXPORT_SYMBOL_GPL(of_pwm_request); /* * pwm_free - free a PWM device -- cgit v1.2.3