lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Tue, 23 Sep 2014 16:17:26 -0700 From: Doug Anderson <dianders@...omium.org> To: thierry.reding@...il.com, Linus Walleij <linus.walleij@...aro.org>, Mark Brown <broonie@...nel.org>, Lee Jones <lee.jones@...aro.org> Cc: Chris Zhong <zyw@...k-chips.com>, Heiko Stuebner <heiko@...ech.de>, Sonny Rao <sonnyrao@...omium.org>, Doug Anderson <dianders@...omium.org>, linux-pwm@...r.kernel.org, linux-kernel@...r.kernel.org Subject: [RFC PATCH] pwm: Add the concept of an "active" pinctrl There are cases where you really don't want a PWM's pinctrl to take effect until you know that the PWM is driving at the proper rate. A good example of this is a PWM-controlled regulator, where the boot state of the pin (maybe a pulled down input) could cause a vastly different voltage to take effect than having the pin setup as a PWM but not having the PWM enabled yet. Let's add a feature where you can define an "active" pinctrl state. This state (if it exists) will be applied after the PWM has actually been enabled. If the PWM is ever disabled we'll go back to "default" state. Signed-off-by: Doug Anderson <dianders@...omium.org> --- I'm sure Linus W or Thierry or Mark will tell me this is an idiotic idea (or totally the wrong way to do it), but I figured I'd float it out there and maybe someone can tell me something better to do. ;) drivers/pwm/core.c | 34 +++++++++++++++++++++++++++++++--- include/linux/pwm.h | 8 ++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 966497d..12f86e0 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -245,6 +245,14 @@ int pwmchip_add(struct pwm_chip *chip) if (ret < 0) goto out; + chip->pinctrl = devm_pinctrl_get(chip->dev); + if (!IS_ERR_OR_NULL(chip->pinctrl)) { + chip->state_default = pinctrl_lookup_state(chip->pinctrl, + "default"); + chip->state_active = pinctrl_lookup_state(chip->pinctrl, + "active"); + } + chip->pwms = kzalloc(chip->npwm * sizeof(*pwm), GFP_KERNEL); if (!chip->pwms) { ret = -ENOMEM; @@ -457,8 +465,17 @@ EXPORT_SYMBOL_GPL(pwm_set_polarity); */ int pwm_enable(struct pwm_device *pwm) { - if (pwm && !test_and_set_bit(PWMF_ENABLED, &pwm->flags)) - return pwm->chip->ops->enable(pwm->chip, pwm); + int ret; + + if (pwm && !test_and_set_bit(PWMF_ENABLED, &pwm->flags)) { + ret = pwm->chip->ops->enable(pwm->chip, pwm); + + if (!ret && !IS_ERR_OR_NULL(pwm->chip->state_active)) + ret = pinctrl_select_state(pwm->chip->pinctrl, + pwm->chip->state_active); + + return ret; + } return pwm ? 0 : -EINVAL; } @@ -470,8 +487,19 @@ EXPORT_SYMBOL_GPL(pwm_enable); */ void pwm_disable(struct pwm_device *pwm) { - if (pwm && test_and_clear_bit(PWMF_ENABLED, &pwm->flags)) + int ret; + + if (pwm && test_and_clear_bit(PWMF_ENABLED, &pwm->flags)) { + if (!IS_ERR_OR_NULL(pwm->chip->state_default)) { + ret = pinctrl_select_state(pwm->chip->pinctrl, + pwm->chip->state_default); + if (ret) + dev_warn(pwm->chip->dev, + "Couldn't set def state: %d\n", ret); + } + pwm->chip->ops->disable(pwm->chip, pwm); + } } EXPORT_SYMBOL_GPL(pwm_disable); diff --git a/include/linux/pwm.h b/include/linux/pwm.h index e90628c..039c898 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -162,6 +162,10 @@ struct pwm_ops { * @pwms: array of PWM devices allocated by the framework * @can_sleep: must be true if the .config(), .enable() or .disable() * operations may sleep + * + * @pinctrl: Pointer to the a pinctrl for the dev + * @state_default: We'll apply this when a PWM is disabled + * @state_active: We'll apply this when a PWM is enabled */ struct pwm_chip { struct device *dev; @@ -176,6 +180,10 @@ struct pwm_chip { const struct of_phandle_args *args); unsigned int of_pwm_n_cells; bool can_sleep; + + struct pinctrl *pinctrl; + struct pinctrl_state *state_default; + struct pinctrl_state *state_active; }; #if IS_ENABLED(CONFIG_PWM) -- 2.1.0.rc2.206.gedb03e5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists