All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boris Brezillon <boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
To: Thierry Reding
	<thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	linux-pwm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: Mike Turquette
	<mturquette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>,
	Stephen Boyd <sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>,
	linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Liam Girdwood <lgirdwood-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Kamil Debski <k.debski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>,
	lm-sensors-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org,
	Jean Delvare <jdelvare-IBi9RG/b67k@public.gmane.org>,
	Guenter Roeck <linux-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>,
	Dmitry Torokhov
	<dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	linux-input-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Bryan Wu <cooloney-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Richard Purdie <rpurdie-Fm38FmjxZ/leoWH0uzbU5w@public.gmane.org>,
	Jacek Anaszewski
	<j.anaszewski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>,
	linux-leds-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Maxime Ripard
	<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>,
	Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org,
	Joachim Eastwood
	<manabian-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Thomas Petazzoni
	<thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>,
	Heiko Stuebner <heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	Jingoo Han <jingoohan1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Lee Jones
	<lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>linu
Subject: [PATCH v5 18/46] pwm: add the core infrastructure to allow atomic update
Date: Wed, 30 Mar 2016 22:03:41 +0200	[thread overview]
Message-ID: <1459368249-13241-19-git-send-email-boris.brezillon@free-electrons.com> (raw)
In-Reply-To: <1459368249-13241-1-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

Add an ->apply() method to the pwm_ops struct to allow PWM drivers to
implement atomic update.
This method will be preferred over the ->enable(), ->disable() and
->config() methods if available.

Add the pwm_apply_state() function to the PWM user API.

Note that the pwm_apply_state() does not guarantee the atomicity of the
update operation, it all depends on the availability and implementation
of the ->apply() method.

pwm_enable/disable/set_polarity/config() are now implemented as wrappers
around the pwm_apply_state() function.

Signed-off-by: Boris Brezillon <boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 drivers/pwm/core.c  | 155 ++++++++++++++++++---------------------
 include/linux/pwm.h | 207 +++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 220 insertions(+), 142 deletions(-)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index a909c64..62e6b3c 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -226,6 +226,19 @@ void *pwm_get_chip_data(struct pwm_device *pwm)
 }
 EXPORT_SYMBOL_GPL(pwm_get_chip_data);
 
+static bool pwm_ops_check(const struct pwm_ops *ops)
+{
+	/* driver supports legacy, non-atomic operation */
+	if (ops->config && ops->enable && ops->disable)
+		return true;
+
+	/* driver supports atomic operation */
+	if (ops->apply)
+		return true;
+
+	return false;
+}
+
 /**
  * pwmchip_add_with_polarity() - register a new PWM chip
  * @chip: the PWM chip to add
@@ -244,8 +257,10 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
 	unsigned int i;
 	int ret;
 
-	if (!chip || !chip->dev || !chip->ops || !chip->ops->config ||
-	    !chip->ops->enable || !chip->ops->disable || !chip->npwm)
+	if (!chip || !chip->dev || !chip->ops || !chip->npwm)
+		return -EINVAL;
+
+	if (!pwm_ops_check(chip->ops))
 		return -EINVAL;
 
 	mutex_lock(&pwm_lock);
@@ -431,102 +446,72 @@ void pwm_free(struct pwm_device *pwm)
 EXPORT_SYMBOL_GPL(pwm_free);
 
 /**
- * pwm_config() - change a PWM device configuration
+ * pwm_apply_state() - atomically apply a new state to a PWM device
  * @pwm: PWM device
- * @duty_ns: "on" time (in nanoseconds)
- * @period_ns: duration (in nanoseconds) of one cycle
- *
- * Returns: 0 on success or a negative error code on failure.
+ * @state: new state to apply. This can be adjusted by the PWM driver
+ *	   if the requested config is not achievable, for example,
+ *	   ->duty_cycle and ->period might be approximated.
  */
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state)
 {
 	int err;
 
-	if (!pwm || duty_ns < 0 || period_ns <= 0 || duty_ns > period_ns)
-		return -EINVAL;
-
-	err = pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
-	if (err)
-		return err;
-
-	pwm->state.duty_cycle = duty_ns;
-	pwm->state.period = period_ns;
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(pwm_config);
-
-/**
- * pwm_set_polarity() - configure the polarity of a PWM signal
- * @pwm: PWM device
- * @polarity: new polarity of the PWM signal
- *
- * Note that the polarity cannot be configured while the PWM device is
- * enabled.
- *
- * Returns: 0 on success or a negative error code on failure.
- */
-int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
-{
-	int err;
-
-	if (!pwm || !pwm->chip->ops)
-		return -EINVAL;
-
-	if (!pwm->chip->ops->set_polarity)
-		return -ENOSYS;
-
-	if (pwm_is_enabled(pwm))
-		return -EBUSY;
-
-	err = pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
-	if (err)
-		return err;
-
-	pwm->state.polarity = polarity;
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(pwm_set_polarity);
-
-/**
- * pwm_enable() - start a PWM output toggling
- * @pwm: PWM device
- *
- * Returns: 0 on success or a negative error code on failure.
- */
-int pwm_enable(struct pwm_device *pwm)
-{
-	int err = 0;
-
 	if (!pwm)
 		return -EINVAL;
 
-	if (!pwm_is_enabled(pwm)) {
-		err = pwm->chip->ops->enable(pwm->chip, pwm);
-		if (!err)
-			pwm->state.enabled = true;
-	}
+	if (!memcmp(state, &pwm->state, sizeof(*state)))
+		return 0;
 
-	return err;
-}
-EXPORT_SYMBOL_GPL(pwm_enable);
+	if (pwm->chip->ops->apply) {
+		err = pwm->chip->ops->apply(pwm->chip, pwm, state);
+		if (err)
+			return err;
+	} else {
+		/*
+		 * FIXME: restore the initial state in case of error.
+		 */
+		if (state->polarity != pwm->state.polarity) {
+			if (!pwm->chip->ops->set_polarity)
+				return -ENOTSUPP;
+
+			/*
+			 * Changing the polarity of a running PWM is
+			 * only allowed when the PWM driver implements
+			 * ->apply().
+			 */
+			if (pwm->state.enabled)
+				return -EBUSY;
+
+			err = pwm->chip->ops->set_polarity(pwm->chip, pwm,
+							   state->polarity);
+			if (err)
+				return err;
+		}
 
-/**
- * pwm_disable() - stop a PWM output toggling
- * @pwm: PWM device
- */
-void pwm_disable(struct pwm_device *pwm)
-{
-	if (!pwm)
-		return;
+		if (state->period != pwm->state.period ||
+		    state->duty_cycle != pwm->state.duty_cycle) {
+			err = pwm->chip->ops->config(pwm->chip, pwm,
+						     state->period,
+						     state->duty_cycle);
+			if (err)
+				return err;
+		}
 
-	if (pwm_is_enabled(pwm)) {
-		pwm->chip->ops->disable(pwm->chip, pwm);
-		pwm->state.enabled = false;
+		if (state->enabled != pwm->state.enabled) {
+			if (state->enabled) {
+				err = pwm->chip->ops->enable(pwm->chip, pwm);
+				if (err)
+					return err;
+			} else {
+				pwm->chip->ops->disable(pwm->chip, pwm);
+			}
+		}
 	}
+
+	pwm->state = *state;
+	return 0;
 }
-EXPORT_SYMBOL_GPL(pwm_disable);
+EXPORT_SYMBOL_GPL(pwm_apply_state);
 
 static struct pwm_chip *of_node_to_pwmchip(struct device_node *np)
 {
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index ceedcf8..4aad4eb 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -5,59 +5,7 @@
 #include <linux/mutex.h>
 #include <linux/of.h>
 
-struct pwm_device;
 struct seq_file;
-
-#if IS_ENABLED(CONFIG_PWM)
-/*
- * pwm_request - request a PWM device
- */
-struct pwm_device *pwm_request(int pwm_id, const char *label);
-
-/*
- * pwm_free - free a PWM device
- */
-void pwm_free(struct pwm_device *pwm);
-
-/*
- * pwm_config - change a PWM device configuration
- */
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns);
-
-/*
- * pwm_enable - start a PWM output toggling
- */
-int pwm_enable(struct pwm_device *pwm);
-
-/*
- * pwm_disable - stop a PWM output toggling
- */
-void pwm_disable(struct pwm_device *pwm);
-#else
-static inline struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
-	return ERR_PTR(-ENODEV);
-}
-
-static inline void pwm_free(struct pwm_device *pwm)
-{
-}
-
-static inline int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
-	return -EINVAL;
-}
-
-static inline int pwm_enable(struct pwm_device *pwm)
-{
-	return -EINVAL;
-}
-
-static inline void pwm_disable(struct pwm_device *pwm)
-{
-}
-#endif
-
 struct pwm_chip;
 
 /**
@@ -183,11 +131,6 @@ static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm)
 	return pstate.duty_cycle;
 }
 
-/*
- * pwm_set_polarity - configure the polarity of a PWM signal
- */
-int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity);
-
 static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm)
 {
 	struct pwm_state pstate;
@@ -211,6 +154,10 @@ static inline void pwm_get_args(const struct pwm_device *pwm,
  * @set_polarity: configure the polarity of this PWM
  * @enable: enable PWM output toggling
  * @disable: disable PWM output toggling
+ * @apply: atomically apply a new PWM config. The state argument
+ *	   should be adjusted with the real hardware config (if the
+ *	   approximate the period or duty_cycle value, state should
+ *	   reflect it)
  * @get_state: get the current PWM state. This function is only
  *	       called once per PWM device when the PWM chip is
  *	       registered.
@@ -226,6 +173,8 @@ struct pwm_ops {
 			    enum pwm_polarity polarity);
 	int (*enable)(struct pwm_chip *chip, struct pwm_device *pwm);
 	void (*disable)(struct pwm_chip *chip, struct pwm_device *pwm);
+	int (*apply)(struct pwm_chip *chip, struct pwm_device *pwm,
+		     struct pwm_state *state);
 	void (*get_state)(struct pwm_chip *chip, struct pwm_device *pwm,
 			  struct pwm_state *pstate);
 #ifdef CONFIG_DEBUG_FS
@@ -263,6 +212,114 @@ struct pwm_chip {
 };
 
 #if IS_ENABLED(CONFIG_PWM)
+/* PWM user APIs */
+struct pwm_device *pwm_request(int pwm_id, const char *label);
+void pwm_free(struct pwm_device *pwm);
+int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state);
+
+/**
+ * pwm_config() - change a PWM device configuration
+ * @pwm: PWM device
+ * @duty_ns: "on" time (in nanoseconds)
+ * @period_ns: duration (in nanoseconds) of one cycle
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+static inline int pwm_config(struct pwm_device *pwm, int duty_ns,
+			     int period_ns)
+{
+	struct pwm_state pstate;
+
+	if (!pwm)
+		return -EINVAL;
+
+	pwm_get_state(pwm, &pstate);
+	if (pstate.duty_cycle == duty_ns && pstate.period == period_ns)
+		return 0;
+
+	pstate.duty_cycle = duty_ns;
+	pstate.period = period_ns;
+	return pwm_apply_state(pwm, &pstate);
+}
+
+/**
+ * pwm_set_polarity() - configure the polarity of a PWM signal
+ * @pwm: PWM device
+ * @polarity: new polarity of the PWM signal
+ *
+ * Note that the polarity cannot be configured while the PWM device is
+ * enabled.
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+static inline int pwm_set_polarity(struct pwm_device *pwm,
+				   enum pwm_polarity polarity)
+{
+	struct pwm_state pstate;
+
+	if (!pwm)
+		return -EINVAL;
+
+	pwm_get_state(pwm, &pstate);
+	if (pstate.polarity == polarity)
+		return 0;
+
+	/*
+	 * Changing the polarity of a running PWM without adjusting the
+	 * dutycycle/period value is a bit risky (can introduce glitches).
+	 * Return -EBUSY in this case.
+	 * Note that this is allowed when using pwm_apply_state() because
+	 * the user specifies all the parameters.
+	 */
+	if (pstate.enabled)
+		return -EBUSY;
+
+	pstate.polarity = polarity;
+	return pwm_apply_state(pwm, &pstate);
+}
+
+/**
+ * pwm_enable() - start a PWM output toggling
+ * @pwm: PWM device
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+static inline int pwm_enable(struct pwm_device *pwm)
+{
+	struct pwm_state pstate;
+
+	if (!pwm)
+		return -EINVAL;
+
+	pwm_get_state(pwm, &pstate);
+	if (pstate.enabled)
+		return 0;
+
+	pstate.enabled = true;
+	return pwm_apply_state(pwm, &pstate);
+}
+
+/**
+ * pwm_disable() - stop a PWM output toggling
+ * @pwm: PWM device
+ */
+static inline void pwm_disable(struct pwm_device *pwm)
+{
+	struct pwm_state pstate;
+
+	if (!pwm)
+		return;
+
+	pwm_get_state(pwm, &pstate);
+	if (!pstate.enabled)
+		return;
+
+	pstate.enabled = false;
+	pwm_apply_state(pwm, &pstate);
+}
+
+
+/* PWM provider APIs */
 int pwm_set_chip_data(struct pwm_device *pwm, void *data);
 void *pwm_get_chip_data(struct pwm_device *pwm);
 
@@ -288,6 +345,42 @@ void devm_pwm_put(struct device *dev, struct pwm_device *pwm);
 
 bool pwm_can_sleep(struct pwm_device *pwm);
 #else
+static inline struct pwm_device *pwm_request(int pwm_id, const char *label)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline void pwm_free(struct pwm_device *pwm)
+{
+}
+
+static inline int pwm_apply_state(struct pwm_device *pwm,
+				  const struct pwm_state *state)
+{
+	return -ENOTSUPP;
+}
+
+static inline int pwm_config(struct pwm_device *pwm, int duty_ns,
+			     int period_ns)
+{
+	return -EINVAL;
+}
+
+static inline int pwm_set_polarity(struct pwm_device *pwm,
+				   enum pwm_polarity polarity)
+{
+	return -ENOTSUPP;
+}
+
+static inline int pwm_enable(struct pwm_device *pwm)
+{
+	return -EINVAL;
+}
+
+static inline void pwm_disable(struct pwm_device *pwm)
+{
+}
+
 static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data)
 {
 	return -EINVAL;
-- 
2.5.0

WARNING: multiple messages have this Message-ID (diff)
From: Boris Brezillon <boris.brezillon@free-electrons.com>
To: Thierry Reding <thierry.reding@gmail.com>, linux-pwm@vger.kernel.org
Cc: Mike Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@codeaurora.org>,
	linux-clk@vger.kernel.org, Mark Brown <broonie@kernel.org>,
	Liam Girdwood <lgirdwood@gmail.com>,
	Kamil Debski <k.debski@samsung.com>,
	lm-sensors@lm-sensors.org, Jean Delvare <jdelvare@suse.com>,
	Guenter Roeck <linux@roeck-us.net>,
	Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	linux-input@vger.kernel.org, Bryan Wu <cooloney@gmail.com>,
	Richard Purdie <rpurdie@rpsys.net>,
	Jacek Anaszewski <j.anaszewski@samsung.com>,
	linux-leds@vger.kernel.org,
	Maxime Ripard <maxime.ripard@free-electrons.com>,
	Chen-Yu Tsai <wens@csie.org>,
	linux-sunxi@googlegroups.com,
	Joachim Eastwood <manabian@gmail.com>,
	Thomas Petazzoni <thomas.petazzoni@free-electrons.com>,
	Heiko Stuebner <heiko@sntech.de>,
	linux-rockchip@lists.infradead.org,
	Jingoo Han <jingoohan1@gmail.com>,
	Lee Jones <lee.jones@linaro.org>,
	linux-fbdev@vger.kernel.org,
	Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>,
	Tomi Valkeinen <tomi.valkeinen@ti.com>,
	Robert Jarzmik <robert.jarzmik@free.fr>,
	Alexandre Belloni <alexandre.belloni@free-electrons.com>,
	Kukjin Kim <kgene@kernel.org>,
	Krzysztof Kozlowski <k.kozlowski@samsung.com>,
	linux-samsung-soc@vger.kernel.org,
	intel-gfx@lists.freedesktop.org,
	Daniel Vetter <daniel.vetter@intel.com>,
	Jani Nikula <jani.nikula@linux.intel.com>,
	Jonathan Corbet <corbet@lwn.net>,
	linux-doc@vger.kernel.org, David Airlie <airlied@linux.ie>,
	Daniel Vetter <daniel@ffwll.ch>,
	dri-devel@lists.freedesktop.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	Hartley Sweeten <hsweeten@visionengravers.com>,
	Ryan Mallon <rmallon@gmail.com>,
	Alexander Shiyan <shc_work@mail.ru>, Milo Kim <milo.kim@ti.com>,
	Boris Brezillon <boris.brezillon@free-electrons.com>
Subject: [PATCH v5 18/46] pwm: add the core infrastructure to allow atomic update
Date: Wed, 30 Mar 2016 22:03:41 +0200	[thread overview]
Message-ID: <1459368249-13241-19-git-send-email-boris.brezillon@free-electrons.com> (raw)
In-Reply-To: <1459368249-13241-1-git-send-email-boris.brezillon@free-electrons.com>

Add an ->apply() method to the pwm_ops struct to allow PWM drivers to
implement atomic update.
This method will be preferred over the ->enable(), ->disable() and
->config() methods if available.

Add the pwm_apply_state() function to the PWM user API.

Note that the pwm_apply_state() does not guarantee the atomicity of the
update operation, it all depends on the availability and implementation
of the ->apply() method.

pwm_enable/disable/set_polarity/config() are now implemented as wrappers
around the pwm_apply_state() function.

Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
 drivers/pwm/core.c  | 155 ++++++++++++++++++---------------------
 include/linux/pwm.h | 207 +++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 220 insertions(+), 142 deletions(-)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index a909c64..62e6b3c 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -226,6 +226,19 @@ void *pwm_get_chip_data(struct pwm_device *pwm)
 }
 EXPORT_SYMBOL_GPL(pwm_get_chip_data);
 
+static bool pwm_ops_check(const struct pwm_ops *ops)
+{
+	/* driver supports legacy, non-atomic operation */
+	if (ops->config && ops->enable && ops->disable)
+		return true;
+
+	/* driver supports atomic operation */
+	if (ops->apply)
+		return true;
+
+	return false;
+}
+
 /**
  * pwmchip_add_with_polarity() - register a new PWM chip
  * @chip: the PWM chip to add
@@ -244,8 +257,10 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
 	unsigned int i;
 	int ret;
 
-	if (!chip || !chip->dev || !chip->ops || !chip->ops->config ||
-	    !chip->ops->enable || !chip->ops->disable || !chip->npwm)
+	if (!chip || !chip->dev || !chip->ops || !chip->npwm)
+		return -EINVAL;
+
+	if (!pwm_ops_check(chip->ops))
 		return -EINVAL;
 
 	mutex_lock(&pwm_lock);
@@ -431,102 +446,72 @@ void pwm_free(struct pwm_device *pwm)
 EXPORT_SYMBOL_GPL(pwm_free);
 
 /**
- * pwm_config() - change a PWM device configuration
+ * pwm_apply_state() - atomically apply a new state to a PWM device
  * @pwm: PWM device
- * @duty_ns: "on" time (in nanoseconds)
- * @period_ns: duration (in nanoseconds) of one cycle
- *
- * Returns: 0 on success or a negative error code on failure.
+ * @state: new state to apply. This can be adjusted by the PWM driver
+ *	   if the requested config is not achievable, for example,
+ *	   ->duty_cycle and ->period might be approximated.
  */
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state)
 {
 	int err;
 
-	if (!pwm || duty_ns < 0 || period_ns <= 0 || duty_ns > period_ns)
-		return -EINVAL;
-
-	err = pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
-	if (err)
-		return err;
-
-	pwm->state.duty_cycle = duty_ns;
-	pwm->state.period = period_ns;
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(pwm_config);
-
-/**
- * pwm_set_polarity() - configure the polarity of a PWM signal
- * @pwm: PWM device
- * @polarity: new polarity of the PWM signal
- *
- * Note that the polarity cannot be configured while the PWM device is
- * enabled.
- *
- * Returns: 0 on success or a negative error code on failure.
- */
-int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
-{
-	int err;
-
-	if (!pwm || !pwm->chip->ops)
-		return -EINVAL;
-
-	if (!pwm->chip->ops->set_polarity)
-		return -ENOSYS;
-
-	if (pwm_is_enabled(pwm))
-		return -EBUSY;
-
-	err = pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
-	if (err)
-		return err;
-
-	pwm->state.polarity = polarity;
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(pwm_set_polarity);
-
-/**
- * pwm_enable() - start a PWM output toggling
- * @pwm: PWM device
- *
- * Returns: 0 on success or a negative error code on failure.
- */
-int pwm_enable(struct pwm_device *pwm)
-{
-	int err = 0;
-
 	if (!pwm)
 		return -EINVAL;
 
-	if (!pwm_is_enabled(pwm)) {
-		err = pwm->chip->ops->enable(pwm->chip, pwm);
-		if (!err)
-			pwm->state.enabled = true;
-	}
+	if (!memcmp(state, &pwm->state, sizeof(*state)))
+		return 0;
 
-	return err;
-}
-EXPORT_SYMBOL_GPL(pwm_enable);
+	if (pwm->chip->ops->apply) {
+		err = pwm->chip->ops->apply(pwm->chip, pwm, state);
+		if (err)
+			return err;
+	} else {
+		/*
+		 * FIXME: restore the initial state in case of error.
+		 */
+		if (state->polarity != pwm->state.polarity) {
+			if (!pwm->chip->ops->set_polarity)
+				return -ENOTSUPP;
+
+			/*
+			 * Changing the polarity of a running PWM is
+			 * only allowed when the PWM driver implements
+			 * ->apply().
+			 */
+			if (pwm->state.enabled)
+				return -EBUSY;
+
+			err = pwm->chip->ops->set_polarity(pwm->chip, pwm,
+							   state->polarity);
+			if (err)
+				return err;
+		}
 
-/**
- * pwm_disable() - stop a PWM output toggling
- * @pwm: PWM device
- */
-void pwm_disable(struct pwm_device *pwm)
-{
-	if (!pwm)
-		return;
+		if (state->period != pwm->state.period ||
+		    state->duty_cycle != pwm->state.duty_cycle) {
+			err = pwm->chip->ops->config(pwm->chip, pwm,
+						     state->period,
+						     state->duty_cycle);
+			if (err)
+				return err;
+		}
 
-	if (pwm_is_enabled(pwm)) {
-		pwm->chip->ops->disable(pwm->chip, pwm);
-		pwm->state.enabled = false;
+		if (state->enabled != pwm->state.enabled) {
+			if (state->enabled) {
+				err = pwm->chip->ops->enable(pwm->chip, pwm);
+				if (err)
+					return err;
+			} else {
+				pwm->chip->ops->disable(pwm->chip, pwm);
+			}
+		}
 	}
+
+	pwm->state = *state;
+	return 0;
 }
-EXPORT_SYMBOL_GPL(pwm_disable);
+EXPORT_SYMBOL_GPL(pwm_apply_state);
 
 static struct pwm_chip *of_node_to_pwmchip(struct device_node *np)
 {
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index ceedcf8..4aad4eb 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -5,59 +5,7 @@
 #include <linux/mutex.h>
 #include <linux/of.h>
 
-struct pwm_device;
 struct seq_file;
-
-#if IS_ENABLED(CONFIG_PWM)
-/*
- * pwm_request - request a PWM device
- */
-struct pwm_device *pwm_request(int pwm_id, const char *label);
-
-/*
- * pwm_free - free a PWM device
- */
-void pwm_free(struct pwm_device *pwm);
-
-/*
- * pwm_config - change a PWM device configuration
- */
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns);
-
-/*
- * pwm_enable - start a PWM output toggling
- */
-int pwm_enable(struct pwm_device *pwm);
-
-/*
- * pwm_disable - stop a PWM output toggling
- */
-void pwm_disable(struct pwm_device *pwm);
-#else
-static inline struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
-	return ERR_PTR(-ENODEV);
-}
-
-static inline void pwm_free(struct pwm_device *pwm)
-{
-}
-
-static inline int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
-	return -EINVAL;
-}
-
-static inline int pwm_enable(struct pwm_device *pwm)
-{
-	return -EINVAL;
-}
-
-static inline void pwm_disable(struct pwm_device *pwm)
-{
-}
-#endif
-
 struct pwm_chip;
 
 /**
@@ -183,11 +131,6 @@ static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm)
 	return pstate.duty_cycle;
 }
 
-/*
- * pwm_set_polarity - configure the polarity of a PWM signal
- */
-int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity);
-
 static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm)
 {
 	struct pwm_state pstate;
@@ -211,6 +154,10 @@ static inline void pwm_get_args(const struct pwm_device *pwm,
  * @set_polarity: configure the polarity of this PWM
  * @enable: enable PWM output toggling
  * @disable: disable PWM output toggling
+ * @apply: atomically apply a new PWM config. The state argument
+ *	   should be adjusted with the real hardware config (if the
+ *	   approximate the period or duty_cycle value, state should
+ *	   reflect it)
  * @get_state: get the current PWM state. This function is only
  *	       called once per PWM device when the PWM chip is
  *	       registered.
@@ -226,6 +173,8 @@ struct pwm_ops {
 			    enum pwm_polarity polarity);
 	int (*enable)(struct pwm_chip *chip, struct pwm_device *pwm);
 	void (*disable)(struct pwm_chip *chip, struct pwm_device *pwm);
+	int (*apply)(struct pwm_chip *chip, struct pwm_device *pwm,
+		     struct pwm_state *state);
 	void (*get_state)(struct pwm_chip *chip, struct pwm_device *pwm,
 			  struct pwm_state *pstate);
 #ifdef CONFIG_DEBUG_FS
@@ -263,6 +212,114 @@ struct pwm_chip {
 };
 
 #if IS_ENABLED(CONFIG_PWM)
+/* PWM user APIs */
+struct pwm_device *pwm_request(int pwm_id, const char *label);
+void pwm_free(struct pwm_device *pwm);
+int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state);
+
+/**
+ * pwm_config() - change a PWM device configuration
+ * @pwm: PWM device
+ * @duty_ns: "on" time (in nanoseconds)
+ * @period_ns: duration (in nanoseconds) of one cycle
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+static inline int pwm_config(struct pwm_device *pwm, int duty_ns,
+			     int period_ns)
+{
+	struct pwm_state pstate;
+
+	if (!pwm)
+		return -EINVAL;
+
+	pwm_get_state(pwm, &pstate);
+	if (pstate.duty_cycle == duty_ns && pstate.period == period_ns)
+		return 0;
+
+	pstate.duty_cycle = duty_ns;
+	pstate.period = period_ns;
+	return pwm_apply_state(pwm, &pstate);
+}
+
+/**
+ * pwm_set_polarity() - configure the polarity of a PWM signal
+ * @pwm: PWM device
+ * @polarity: new polarity of the PWM signal
+ *
+ * Note that the polarity cannot be configured while the PWM device is
+ * enabled.
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+static inline int pwm_set_polarity(struct pwm_device *pwm,
+				   enum pwm_polarity polarity)
+{
+	struct pwm_state pstate;
+
+	if (!pwm)
+		return -EINVAL;
+
+	pwm_get_state(pwm, &pstate);
+	if (pstate.polarity == polarity)
+		return 0;
+
+	/*
+	 * Changing the polarity of a running PWM without adjusting the
+	 * dutycycle/period value is a bit risky (can introduce glitches).
+	 * Return -EBUSY in this case.
+	 * Note that this is allowed when using pwm_apply_state() because
+	 * the user specifies all the parameters.
+	 */
+	if (pstate.enabled)
+		return -EBUSY;
+
+	pstate.polarity = polarity;
+	return pwm_apply_state(pwm, &pstate);
+}
+
+/**
+ * pwm_enable() - start a PWM output toggling
+ * @pwm: PWM device
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+static inline int pwm_enable(struct pwm_device *pwm)
+{
+	struct pwm_state pstate;
+
+	if (!pwm)
+		return -EINVAL;
+
+	pwm_get_state(pwm, &pstate);
+	if (pstate.enabled)
+		return 0;
+
+	pstate.enabled = true;
+	return pwm_apply_state(pwm, &pstate);
+}
+
+/**
+ * pwm_disable() - stop a PWM output toggling
+ * @pwm: PWM device
+ */
+static inline void pwm_disable(struct pwm_device *pwm)
+{
+	struct pwm_state pstate;
+
+	if (!pwm)
+		return;
+
+	pwm_get_state(pwm, &pstate);
+	if (!pstate.enabled)
+		return;
+
+	pstate.enabled = false;
+	pwm_apply_state(pwm, &pstate);
+}
+
+
+/* PWM provider APIs */
 int pwm_set_chip_data(struct pwm_device *pwm, void *data);
 void *pwm_get_chip_data(struct pwm_device *pwm);
 
@@ -288,6 +345,42 @@ void devm_pwm_put(struct device *dev, struct pwm_device *pwm);
 
 bool pwm_can_sleep(struct pwm_device *pwm);
 #else
+static inline struct pwm_device *pwm_request(int pwm_id, const char *label)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline void pwm_free(struct pwm_device *pwm)
+{
+}
+
+static inline int pwm_apply_state(struct pwm_device *pwm,
+				  const struct pwm_state *state)
+{
+	return -ENOTSUPP;
+}
+
+static inline int pwm_config(struct pwm_device *pwm, int duty_ns,
+			     int period_ns)
+{
+	return -EINVAL;
+}
+
+static inline int pwm_set_polarity(struct pwm_device *pwm,
+				   enum pwm_polarity polarity)
+{
+	return -ENOTSUPP;
+}
+
+static inline int pwm_enable(struct pwm_device *pwm)
+{
+	return -EINVAL;
+}
+
+static inline void pwm_disable(struct pwm_device *pwm)
+{
+}
+
 static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data)
 {
 	return -EINVAL;
-- 
2.5.0

WARNING: multiple messages have this Message-ID (diff)
From: Boris Brezillon <boris.brezillon@free-electrons.com>
To: Thierry Reding
	<thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	linux-pwm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: Mike Turquette
	<mturquette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>,
	Stephen Boyd <sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>,
	linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Liam Girdwood <lgirdwood-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Kamil Debski <k.debski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>,
	lm-sensors-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org,
	Jean Delvare <jdelvare-IBi9RG/b67k@public.gmane.org>,
	Guenter Roeck <linux-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>,
	Dmitry Torokhov
	<dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	linux-input-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Bryan Wu <cooloney-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Richard Purdie <rpurdie-Fm38FmjxZ/leoWH0uzbU5w@public.gmane.org>,
	Jacek Anaszewski
	<j.anaszewski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>,
	linux-leds-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Maxime Ripard
	<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>,
	Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org,
	Joachim Eastwood
	<manabian-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Thomas Petazzoni
	<thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>,
	Heiko Stuebner <heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	Jingoo Han <jingoohan1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Lee Jones <lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Subject: [PATCH v5 18/46] pwm: add the core infrastructure to allow atomic update
Date: Wed, 30 Mar 2016 20:03:41 +0000	[thread overview]
Message-ID: <1459368249-13241-19-git-send-email-boris.brezillon@free-electrons.com> (raw)
In-Reply-To: <1459368249-13241-1-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

Add an ->apply() method to the pwm_ops struct to allow PWM drivers to
implement atomic update.
This method will be preferred over the ->enable(), ->disable() and
->config() methods if available.

Add the pwm_apply_state() function to the PWM user API.

Note that the pwm_apply_state() does not guarantee the atomicity of the
update operation, it all depends on the availability and implementation
of the ->apply() method.

pwm_enable/disable/set_polarity/config() are now implemented as wrappers
around the pwm_apply_state() function.

Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
 drivers/pwm/core.c  | 155 ++++++++++++++++++---------------------
 include/linux/pwm.h | 207 +++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 220 insertions(+), 142 deletions(-)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index a909c64..62e6b3c 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -226,6 +226,19 @@ void *pwm_get_chip_data(struct pwm_device *pwm)
 }
 EXPORT_SYMBOL_GPL(pwm_get_chip_data);
 
+static bool pwm_ops_check(const struct pwm_ops *ops)
+{
+	/* driver supports legacy, non-atomic operation */
+	if (ops->config && ops->enable && ops->disable)
+		return true;
+
+	/* driver supports atomic operation */
+	if (ops->apply)
+		return true;
+
+	return false;
+}
+
 /**
  * pwmchip_add_with_polarity() - register a new PWM chip
  * @chip: the PWM chip to add
@@ -244,8 +257,10 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
 	unsigned int i;
 	int ret;
 
-	if (!chip || !chip->dev || !chip->ops || !chip->ops->config ||
-	    !chip->ops->enable || !chip->ops->disable || !chip->npwm)
+	if (!chip || !chip->dev || !chip->ops || !chip->npwm)
+		return -EINVAL;
+
+	if (!pwm_ops_check(chip->ops))
 		return -EINVAL;
 
 	mutex_lock(&pwm_lock);
@@ -431,102 +446,72 @@ void pwm_free(struct pwm_device *pwm)
 EXPORT_SYMBOL_GPL(pwm_free);
 
 /**
- * pwm_config() - change a PWM device configuration
+ * pwm_apply_state() - atomically apply a new state to a PWM device
  * @pwm: PWM device
- * @duty_ns: "on" time (in nanoseconds)
- * @period_ns: duration (in nanoseconds) of one cycle
- *
- * Returns: 0 on success or a negative error code on failure.
+ * @state: new state to apply. This can be adjusted by the PWM driver
+ *	   if the requested config is not achievable, for example,
+ *	   ->duty_cycle and ->period might be approximated.
  */
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state)
 {
 	int err;
 
-	if (!pwm || duty_ns < 0 || period_ns <= 0 || duty_ns > period_ns)
-		return -EINVAL;
-
-	err = pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
-	if (err)
-		return err;
-
-	pwm->state.duty_cycle = duty_ns;
-	pwm->state.period = period_ns;
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(pwm_config);
-
-/**
- * pwm_set_polarity() - configure the polarity of a PWM signal
- * @pwm: PWM device
- * @polarity: new polarity of the PWM signal
- *
- * Note that the polarity cannot be configured while the PWM device is
- * enabled.
- *
- * Returns: 0 on success or a negative error code on failure.
- */
-int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
-{
-	int err;
-
-	if (!pwm || !pwm->chip->ops)
-		return -EINVAL;
-
-	if (!pwm->chip->ops->set_polarity)
-		return -ENOSYS;
-
-	if (pwm_is_enabled(pwm))
-		return -EBUSY;
-
-	err = pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
-	if (err)
-		return err;
-
-	pwm->state.polarity = polarity;
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(pwm_set_polarity);
-
-/**
- * pwm_enable() - start a PWM output toggling
- * @pwm: PWM device
- *
- * Returns: 0 on success or a negative error code on failure.
- */
-int pwm_enable(struct pwm_device *pwm)
-{
-	int err = 0;
-
 	if (!pwm)
 		return -EINVAL;
 
-	if (!pwm_is_enabled(pwm)) {
-		err = pwm->chip->ops->enable(pwm->chip, pwm);
-		if (!err)
-			pwm->state.enabled = true;
-	}
+	if (!memcmp(state, &pwm->state, sizeof(*state)))
+		return 0;
 
-	return err;
-}
-EXPORT_SYMBOL_GPL(pwm_enable);
+	if (pwm->chip->ops->apply) {
+		err = pwm->chip->ops->apply(pwm->chip, pwm, state);
+		if (err)
+			return err;
+	} else {
+		/*
+		 * FIXME: restore the initial state in case of error.
+		 */
+		if (state->polarity != pwm->state.polarity) {
+			if (!pwm->chip->ops->set_polarity)
+				return -ENOTSUPP;
+
+			/*
+			 * Changing the polarity of a running PWM is
+			 * only allowed when the PWM driver implements
+			 * ->apply().
+			 */
+			if (pwm->state.enabled)
+				return -EBUSY;
+
+			err = pwm->chip->ops->set_polarity(pwm->chip, pwm,
+							   state->polarity);
+			if (err)
+				return err;
+		}
 
-/**
- * pwm_disable() - stop a PWM output toggling
- * @pwm: PWM device
- */
-void pwm_disable(struct pwm_device *pwm)
-{
-	if (!pwm)
-		return;
+		if (state->period != pwm->state.period ||
+		    state->duty_cycle != pwm->state.duty_cycle) {
+			err = pwm->chip->ops->config(pwm->chip, pwm,
+						     state->period,
+						     state->duty_cycle);
+			if (err)
+				return err;
+		}
 
-	if (pwm_is_enabled(pwm)) {
-		pwm->chip->ops->disable(pwm->chip, pwm);
-		pwm->state.enabled = false;
+		if (state->enabled != pwm->state.enabled) {
+			if (state->enabled) {
+				err = pwm->chip->ops->enable(pwm->chip, pwm);
+				if (err)
+					return err;
+			} else {
+				pwm->chip->ops->disable(pwm->chip, pwm);
+			}
+		}
 	}
+
+	pwm->state = *state;
+	return 0;
 }
-EXPORT_SYMBOL_GPL(pwm_disable);
+EXPORT_SYMBOL_GPL(pwm_apply_state);
 
 static struct pwm_chip *of_node_to_pwmchip(struct device_node *np)
 {
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index ceedcf8..4aad4eb 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -5,59 +5,7 @@
 #include <linux/mutex.h>
 #include <linux/of.h>
 
-struct pwm_device;
 struct seq_file;
-
-#if IS_ENABLED(CONFIG_PWM)
-/*
- * pwm_request - request a PWM device
- */
-struct pwm_device *pwm_request(int pwm_id, const char *label);
-
-/*
- * pwm_free - free a PWM device
- */
-void pwm_free(struct pwm_device *pwm);
-
-/*
- * pwm_config - change a PWM device configuration
- */
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns);
-
-/*
- * pwm_enable - start a PWM output toggling
- */
-int pwm_enable(struct pwm_device *pwm);
-
-/*
- * pwm_disable - stop a PWM output toggling
- */
-void pwm_disable(struct pwm_device *pwm);
-#else
-static inline struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
-	return ERR_PTR(-ENODEV);
-}
-
-static inline void pwm_free(struct pwm_device *pwm)
-{
-}
-
-static inline int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
-	return -EINVAL;
-}
-
-static inline int pwm_enable(struct pwm_device *pwm)
-{
-	return -EINVAL;
-}
-
-static inline void pwm_disable(struct pwm_device *pwm)
-{
-}
-#endif
-
 struct pwm_chip;
 
 /**
@@ -183,11 +131,6 @@ static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm)
 	return pstate.duty_cycle;
 }
 
-/*
- * pwm_set_polarity - configure the polarity of a PWM signal
- */
-int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity);
-
 static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm)
 {
 	struct pwm_state pstate;
@@ -211,6 +154,10 @@ static inline void pwm_get_args(const struct pwm_device *pwm,
  * @set_polarity: configure the polarity of this PWM
  * @enable: enable PWM output toggling
  * @disable: disable PWM output toggling
+ * @apply: atomically apply a new PWM config. The state argument
+ *	   should be adjusted with the real hardware config (if the
+ *	   approximate the period or duty_cycle value, state should
+ *	   reflect it)
  * @get_state: get the current PWM state. This function is only
  *	       called once per PWM device when the PWM chip is
  *	       registered.
@@ -226,6 +173,8 @@ struct pwm_ops {
 			    enum pwm_polarity polarity);
 	int (*enable)(struct pwm_chip *chip, struct pwm_device *pwm);
 	void (*disable)(struct pwm_chip *chip, struct pwm_device *pwm);
+	int (*apply)(struct pwm_chip *chip, struct pwm_device *pwm,
+		     struct pwm_state *state);
 	void (*get_state)(struct pwm_chip *chip, struct pwm_device *pwm,
 			  struct pwm_state *pstate);
 #ifdef CONFIG_DEBUG_FS
@@ -263,6 +212,114 @@ struct pwm_chip {
 };
 
 #if IS_ENABLED(CONFIG_PWM)
+/* PWM user APIs */
+struct pwm_device *pwm_request(int pwm_id, const char *label);
+void pwm_free(struct pwm_device *pwm);
+int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state);
+
+/**
+ * pwm_config() - change a PWM device configuration
+ * @pwm: PWM device
+ * @duty_ns: "on" time (in nanoseconds)
+ * @period_ns: duration (in nanoseconds) of one cycle
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+static inline int pwm_config(struct pwm_device *pwm, int duty_ns,
+			     int period_ns)
+{
+	struct pwm_state pstate;
+
+	if (!pwm)
+		return -EINVAL;
+
+	pwm_get_state(pwm, &pstate);
+	if (pstate.duty_cycle = duty_ns && pstate.period = period_ns)
+		return 0;
+
+	pstate.duty_cycle = duty_ns;
+	pstate.period = period_ns;
+	return pwm_apply_state(pwm, &pstate);
+}
+
+/**
+ * pwm_set_polarity() - configure the polarity of a PWM signal
+ * @pwm: PWM device
+ * @polarity: new polarity of the PWM signal
+ *
+ * Note that the polarity cannot be configured while the PWM device is
+ * enabled.
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+static inline int pwm_set_polarity(struct pwm_device *pwm,
+				   enum pwm_polarity polarity)
+{
+	struct pwm_state pstate;
+
+	if (!pwm)
+		return -EINVAL;
+
+	pwm_get_state(pwm, &pstate);
+	if (pstate.polarity = polarity)
+		return 0;
+
+	/*
+	 * Changing the polarity of a running PWM without adjusting the
+	 * dutycycle/period value is a bit risky (can introduce glitches).
+	 * Return -EBUSY in this case.
+	 * Note that this is allowed when using pwm_apply_state() because
+	 * the user specifies all the parameters.
+	 */
+	if (pstate.enabled)
+		return -EBUSY;
+
+	pstate.polarity = polarity;
+	return pwm_apply_state(pwm, &pstate);
+}
+
+/**
+ * pwm_enable() - start a PWM output toggling
+ * @pwm: PWM device
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+static inline int pwm_enable(struct pwm_device *pwm)
+{
+	struct pwm_state pstate;
+
+	if (!pwm)
+		return -EINVAL;
+
+	pwm_get_state(pwm, &pstate);
+	if (pstate.enabled)
+		return 0;
+
+	pstate.enabled = true;
+	return pwm_apply_state(pwm, &pstate);
+}
+
+/**
+ * pwm_disable() - stop a PWM output toggling
+ * @pwm: PWM device
+ */
+static inline void pwm_disable(struct pwm_device *pwm)
+{
+	struct pwm_state pstate;
+
+	if (!pwm)
+		return;
+
+	pwm_get_state(pwm, &pstate);
+	if (!pstate.enabled)
+		return;
+
+	pstate.enabled = false;
+	pwm_apply_state(pwm, &pstate);
+}
+
+
+/* PWM provider APIs */
 int pwm_set_chip_data(struct pwm_device *pwm, void *data);
 void *pwm_get_chip_data(struct pwm_device *pwm);
 
@@ -288,6 +345,42 @@ void devm_pwm_put(struct device *dev, struct pwm_device *pwm);
 
 bool pwm_can_sleep(struct pwm_device *pwm);
 #else
+static inline struct pwm_device *pwm_request(int pwm_id, const char *label)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline void pwm_free(struct pwm_device *pwm)
+{
+}
+
+static inline int pwm_apply_state(struct pwm_device *pwm,
+				  const struct pwm_state *state)
+{
+	return -ENOTSUPP;
+}
+
+static inline int pwm_config(struct pwm_device *pwm, int duty_ns,
+			     int period_ns)
+{
+	return -EINVAL;
+}
+
+static inline int pwm_set_polarity(struct pwm_device *pwm,
+				   enum pwm_polarity polarity)
+{
+	return -ENOTSUPP;
+}
+
+static inline int pwm_enable(struct pwm_device *pwm)
+{
+	return -EINVAL;
+}
+
+static inline void pwm_disable(struct pwm_device *pwm)
+{
+}
+
 static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data)
 {
 	return -EINVAL;
-- 
2.5.0


WARNING: multiple messages have this Message-ID (diff)
From: boris.brezillon@free-electrons.com (Boris Brezillon)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v5 18/46] pwm: add the core infrastructure to allow atomic update
Date: Wed, 30 Mar 2016 22:03:41 +0200	[thread overview]
Message-ID: <1459368249-13241-19-git-send-email-boris.brezillon@free-electrons.com> (raw)
In-Reply-To: <1459368249-13241-1-git-send-email-boris.brezillon@free-electrons.com>

Add an ->apply() method to the pwm_ops struct to allow PWM drivers to
implement atomic update.
This method will be preferred over the ->enable(), ->disable() and
->config() methods if available.

Add the pwm_apply_state() function to the PWM user API.

Note that the pwm_apply_state() does not guarantee the atomicity of the
update operation, it all depends on the availability and implementation
of the ->apply() method.

pwm_enable/disable/set_polarity/config() are now implemented as wrappers
around the pwm_apply_state() function.

Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
 drivers/pwm/core.c  | 155 ++++++++++++++++++---------------------
 include/linux/pwm.h | 207 +++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 220 insertions(+), 142 deletions(-)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index a909c64..62e6b3c 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -226,6 +226,19 @@ void *pwm_get_chip_data(struct pwm_device *pwm)
 }
 EXPORT_SYMBOL_GPL(pwm_get_chip_data);
 
+static bool pwm_ops_check(const struct pwm_ops *ops)
+{
+	/* driver supports legacy, non-atomic operation */
+	if (ops->config && ops->enable && ops->disable)
+		return true;
+
+	/* driver supports atomic operation */
+	if (ops->apply)
+		return true;
+
+	return false;
+}
+
 /**
  * pwmchip_add_with_polarity() - register a new PWM chip
  * @chip: the PWM chip to add
@@ -244,8 +257,10 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
 	unsigned int i;
 	int ret;
 
-	if (!chip || !chip->dev || !chip->ops || !chip->ops->config ||
-	    !chip->ops->enable || !chip->ops->disable || !chip->npwm)
+	if (!chip || !chip->dev || !chip->ops || !chip->npwm)
+		return -EINVAL;
+
+	if (!pwm_ops_check(chip->ops))
 		return -EINVAL;
 
 	mutex_lock(&pwm_lock);
@@ -431,102 +446,72 @@ void pwm_free(struct pwm_device *pwm)
 EXPORT_SYMBOL_GPL(pwm_free);
 
 /**
- * pwm_config() - change a PWM device configuration
+ * pwm_apply_state() - atomically apply a new state to a PWM device
  * @pwm: PWM device
- * @duty_ns: "on" time (in nanoseconds)
- * @period_ns: duration (in nanoseconds) of one cycle
- *
- * Returns: 0 on success or a negative error code on failure.
+ * @state: new state to apply. This can be adjusted by the PWM driver
+ *	   if the requested config is not achievable, for example,
+ *	   ->duty_cycle and ->period might be approximated.
  */
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state)
 {
 	int err;
 
-	if (!pwm || duty_ns < 0 || period_ns <= 0 || duty_ns > period_ns)
-		return -EINVAL;
-
-	err = pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
-	if (err)
-		return err;
-
-	pwm->state.duty_cycle = duty_ns;
-	pwm->state.period = period_ns;
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(pwm_config);
-
-/**
- * pwm_set_polarity() - configure the polarity of a PWM signal
- * @pwm: PWM device
- * @polarity: new polarity of the PWM signal
- *
- * Note that the polarity cannot be configured while the PWM device is
- * enabled.
- *
- * Returns: 0 on success or a negative error code on failure.
- */
-int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
-{
-	int err;
-
-	if (!pwm || !pwm->chip->ops)
-		return -EINVAL;
-
-	if (!pwm->chip->ops->set_polarity)
-		return -ENOSYS;
-
-	if (pwm_is_enabled(pwm))
-		return -EBUSY;
-
-	err = pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
-	if (err)
-		return err;
-
-	pwm->state.polarity = polarity;
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(pwm_set_polarity);
-
-/**
- * pwm_enable() - start a PWM output toggling
- * @pwm: PWM device
- *
- * Returns: 0 on success or a negative error code on failure.
- */
-int pwm_enable(struct pwm_device *pwm)
-{
-	int err = 0;
-
 	if (!pwm)
 		return -EINVAL;
 
-	if (!pwm_is_enabled(pwm)) {
-		err = pwm->chip->ops->enable(pwm->chip, pwm);
-		if (!err)
-			pwm->state.enabled = true;
-	}
+	if (!memcmp(state, &pwm->state, sizeof(*state)))
+		return 0;
 
-	return err;
-}
-EXPORT_SYMBOL_GPL(pwm_enable);
+	if (pwm->chip->ops->apply) {
+		err = pwm->chip->ops->apply(pwm->chip, pwm, state);
+		if (err)
+			return err;
+	} else {
+		/*
+		 * FIXME: restore the initial state in case of error.
+		 */
+		if (state->polarity != pwm->state.polarity) {
+			if (!pwm->chip->ops->set_polarity)
+				return -ENOTSUPP;
+
+			/*
+			 * Changing the polarity of a running PWM is
+			 * only allowed when the PWM driver implements
+			 * ->apply().
+			 */
+			if (pwm->state.enabled)
+				return -EBUSY;
+
+			err = pwm->chip->ops->set_polarity(pwm->chip, pwm,
+							   state->polarity);
+			if (err)
+				return err;
+		}
 
-/**
- * pwm_disable() - stop a PWM output toggling
- * @pwm: PWM device
- */
-void pwm_disable(struct pwm_device *pwm)
-{
-	if (!pwm)
-		return;
+		if (state->period != pwm->state.period ||
+		    state->duty_cycle != pwm->state.duty_cycle) {
+			err = pwm->chip->ops->config(pwm->chip, pwm,
+						     state->period,
+						     state->duty_cycle);
+			if (err)
+				return err;
+		}
 
-	if (pwm_is_enabled(pwm)) {
-		pwm->chip->ops->disable(pwm->chip, pwm);
-		pwm->state.enabled = false;
+		if (state->enabled != pwm->state.enabled) {
+			if (state->enabled) {
+				err = pwm->chip->ops->enable(pwm->chip, pwm);
+				if (err)
+					return err;
+			} else {
+				pwm->chip->ops->disable(pwm->chip, pwm);
+			}
+		}
 	}
+
+	pwm->state = *state;
+	return 0;
 }
-EXPORT_SYMBOL_GPL(pwm_disable);
+EXPORT_SYMBOL_GPL(pwm_apply_state);
 
 static struct pwm_chip *of_node_to_pwmchip(struct device_node *np)
 {
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index ceedcf8..4aad4eb 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -5,59 +5,7 @@
 #include <linux/mutex.h>
 #include <linux/of.h>
 
-struct pwm_device;
 struct seq_file;
-
-#if IS_ENABLED(CONFIG_PWM)
-/*
- * pwm_request - request a PWM device
- */
-struct pwm_device *pwm_request(int pwm_id, const char *label);
-
-/*
- * pwm_free - free a PWM device
- */
-void pwm_free(struct pwm_device *pwm);
-
-/*
- * pwm_config - change a PWM device configuration
- */
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns);
-
-/*
- * pwm_enable - start a PWM output toggling
- */
-int pwm_enable(struct pwm_device *pwm);
-
-/*
- * pwm_disable - stop a PWM output toggling
- */
-void pwm_disable(struct pwm_device *pwm);
-#else
-static inline struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
-	return ERR_PTR(-ENODEV);
-}
-
-static inline void pwm_free(struct pwm_device *pwm)
-{
-}
-
-static inline int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
-	return -EINVAL;
-}
-
-static inline int pwm_enable(struct pwm_device *pwm)
-{
-	return -EINVAL;
-}
-
-static inline void pwm_disable(struct pwm_device *pwm)
-{
-}
-#endif
-
 struct pwm_chip;
 
 /**
@@ -183,11 +131,6 @@ static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm)
 	return pstate.duty_cycle;
 }
 
-/*
- * pwm_set_polarity - configure the polarity of a PWM signal
- */
-int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity);
-
 static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm)
 {
 	struct pwm_state pstate;
@@ -211,6 +154,10 @@ static inline void pwm_get_args(const struct pwm_device *pwm,
  * @set_polarity: configure the polarity of this PWM
  * @enable: enable PWM output toggling
  * @disable: disable PWM output toggling
+ * @apply: atomically apply a new PWM config. The state argument
+ *	   should be adjusted with the real hardware config (if the
+ *	   approximate the period or duty_cycle value, state should
+ *	   reflect it)
  * @get_state: get the current PWM state. This function is only
  *	       called once per PWM device when the PWM chip is
  *	       registered.
@@ -226,6 +173,8 @@ struct pwm_ops {
 			    enum pwm_polarity polarity);
 	int (*enable)(struct pwm_chip *chip, struct pwm_device *pwm);
 	void (*disable)(struct pwm_chip *chip, struct pwm_device *pwm);
+	int (*apply)(struct pwm_chip *chip, struct pwm_device *pwm,
+		     struct pwm_state *state);
 	void (*get_state)(struct pwm_chip *chip, struct pwm_device *pwm,
 			  struct pwm_state *pstate);
 #ifdef CONFIG_DEBUG_FS
@@ -263,6 +212,114 @@ struct pwm_chip {
 };
 
 #if IS_ENABLED(CONFIG_PWM)
+/* PWM user APIs */
+struct pwm_device *pwm_request(int pwm_id, const char *label);
+void pwm_free(struct pwm_device *pwm);
+int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state);
+
+/**
+ * pwm_config() - change a PWM device configuration
+ * @pwm: PWM device
+ * @duty_ns: "on" time (in nanoseconds)
+ * @period_ns: duration (in nanoseconds) of one cycle
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+static inline int pwm_config(struct pwm_device *pwm, int duty_ns,
+			     int period_ns)
+{
+	struct pwm_state pstate;
+
+	if (!pwm)
+		return -EINVAL;
+
+	pwm_get_state(pwm, &pstate);
+	if (pstate.duty_cycle == duty_ns && pstate.period == period_ns)
+		return 0;
+
+	pstate.duty_cycle = duty_ns;
+	pstate.period = period_ns;
+	return pwm_apply_state(pwm, &pstate);
+}
+
+/**
+ * pwm_set_polarity() - configure the polarity of a PWM signal
+ * @pwm: PWM device
+ * @polarity: new polarity of the PWM signal
+ *
+ * Note that the polarity cannot be configured while the PWM device is
+ * enabled.
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+static inline int pwm_set_polarity(struct pwm_device *pwm,
+				   enum pwm_polarity polarity)
+{
+	struct pwm_state pstate;
+
+	if (!pwm)
+		return -EINVAL;
+
+	pwm_get_state(pwm, &pstate);
+	if (pstate.polarity == polarity)
+		return 0;
+
+	/*
+	 * Changing the polarity of a running PWM without adjusting the
+	 * dutycycle/period value is a bit risky (can introduce glitches).
+	 * Return -EBUSY in this case.
+	 * Note that this is allowed when using pwm_apply_state() because
+	 * the user specifies all the parameters.
+	 */
+	if (pstate.enabled)
+		return -EBUSY;
+
+	pstate.polarity = polarity;
+	return pwm_apply_state(pwm, &pstate);
+}
+
+/**
+ * pwm_enable() - start a PWM output toggling
+ * @pwm: PWM device
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+static inline int pwm_enable(struct pwm_device *pwm)
+{
+	struct pwm_state pstate;
+
+	if (!pwm)
+		return -EINVAL;
+
+	pwm_get_state(pwm, &pstate);
+	if (pstate.enabled)
+		return 0;
+
+	pstate.enabled = true;
+	return pwm_apply_state(pwm, &pstate);
+}
+
+/**
+ * pwm_disable() - stop a PWM output toggling
+ * @pwm: PWM device
+ */
+static inline void pwm_disable(struct pwm_device *pwm)
+{
+	struct pwm_state pstate;
+
+	if (!pwm)
+		return;
+
+	pwm_get_state(pwm, &pstate);
+	if (!pstate.enabled)
+		return;
+
+	pstate.enabled = false;
+	pwm_apply_state(pwm, &pstate);
+}
+
+
+/* PWM provider APIs */
 int pwm_set_chip_data(struct pwm_device *pwm, void *data);
 void *pwm_get_chip_data(struct pwm_device *pwm);
 
@@ -288,6 +345,42 @@ void devm_pwm_put(struct device *dev, struct pwm_device *pwm);
 
 bool pwm_can_sleep(struct pwm_device *pwm);
 #else
+static inline struct pwm_device *pwm_request(int pwm_id, const char *label)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline void pwm_free(struct pwm_device *pwm)
+{
+}
+
+static inline int pwm_apply_state(struct pwm_device *pwm,
+				  const struct pwm_state *state)
+{
+	return -ENOTSUPP;
+}
+
+static inline int pwm_config(struct pwm_device *pwm, int duty_ns,
+			     int period_ns)
+{
+	return -EINVAL;
+}
+
+static inline int pwm_set_polarity(struct pwm_device *pwm,
+				   enum pwm_polarity polarity)
+{
+	return -ENOTSUPP;
+}
+
+static inline int pwm_enable(struct pwm_device *pwm)
+{
+	return -EINVAL;
+}
+
+static inline void pwm_disable(struct pwm_device *pwm)
+{
+}
+
 static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data)
 {
 	return -EINVAL;
-- 
2.5.0

  parent reply	other threads:[~2016-03-30 20:03 UTC|newest]

Thread overview: 437+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-30 20:03 [PATCH v5 00/46] pwm: add support for atomic update Boris Brezillon
2016-03-30 20:03 ` Boris Brezillon
2016-03-30 20:03 ` Boris Brezillon
2016-03-30 20:03 ` Boris Brezillon
2016-03-30 20:03 ` [PATCH v5 02/46] backlight: pwm_bl: remove useless call to pwm_set_period() Boris Brezillon
2016-03-30 20:03   ` Boris Brezillon
2016-03-30 20:03   ` Boris Brezillon
2016-03-30 20:03   ` Boris Brezillon
2016-04-12 11:03   ` Thierry Reding
2016-04-12 11:03     ` Thierry Reding
2016-04-12 11:03     ` Thierry Reding
2016-04-12 11:03     ` Thierry Reding
     [not found]     ` <20160412110350.GH18882-EkSeR96xj6Pcmrwk2tT4+A@public.gmane.org>
2016-04-12 14:16       ` Lee Jones
2016-04-12 14:16         ` Lee Jones
2016-04-12 14:16         ` Lee Jones
2016-04-12 14:16         ` Lee Jones
2016-04-12 14:25         ` Thierry Reding
2016-04-12 14:25           ` Thierry Reding
2016-04-12 14:25           ` Thierry Reding
2016-04-12 14:25           ` Thierry Reding
2016-03-30 20:03 ` [PATCH v5 03/46] backlight: lm3630a_bl: stop messing with the pwm->period field Boris Brezillon
2016-03-30 20:03   ` Boris Brezillon
2016-03-30 20:03   ` Boris Brezillon
2016-03-30 20:03   ` Boris Brezillon
2016-04-12 11:08   ` Thierry Reding
2016-04-12 11:08     ` Thierry Reding
2016-04-12 11:08     ` Thierry Reding
2016-04-12 11:08     ` Thierry Reding
2016-04-12 14:16     ` Lee Jones
2016-04-12 14:16       ` Lee Jones
2016-04-12 14:16       ` Lee Jones
2016-04-12 14:16       ` Lee Jones
2016-04-12 14:26       ` Thierry Reding
2016-04-12 14:26         ` Thierry Reding
2016-04-12 14:26         ` Thierry Reding
2016-04-12 14:26         ` Thierry Reding
2016-04-13  8:25         ` Lee Jones
2016-04-13  8:25           ` Lee Jones
2016-04-13  8:25           ` Lee Jones
2016-04-13  8:25           ` Lee Jones
2016-04-13  8:26           ` Lee Jones
2016-04-13  8:26             ` Lee Jones
2016-04-13  8:26             ` Lee Jones
2016-04-13  8:26             ` Lee Jones
2016-03-30 20:03 ` [PATCH v5 08/46] hwmon: pwm-fan: use pwm_get_args() where appropriate Boris Brezillon
2016-03-30 20:03   ` Boris Brezillon
2016-03-30 20:03   ` Boris Brezillon
2016-03-30 20:03   ` Boris Brezillon
2016-03-30 22:52   ` Guenter Roeck
2016-03-30 22:52     ` Guenter Roeck
2016-03-30 22:52     ` Guenter Roeck
2016-03-30 22:52     ` Guenter Roeck
2016-03-31  7:07     ` Boris Brezillon
2016-03-31  7:07       ` Boris Brezillon
2016-03-31  7:07       ` Boris Brezillon
2016-03-31  7:07       ` Boris Brezillon
2016-04-04 15:20       ` Thierry Reding
2016-04-04 15:20         ` Thierry Reding
2016-04-04 15:20         ` Thierry Reding
2016-04-04 15:20         ` Thierry Reding
2016-04-01  8:29   ` Kamil Debski
2016-04-01  8:29     ` Kamil Debski
2016-04-01  8:29     ` Kamil Debski
2016-04-01  8:29     ` Kamil Debski
2016-03-30 20:03 ` [PATCH v5 12/46] fbdev: ssd1307fb: " Boris Brezillon
2016-03-30 20:03   ` Boris Brezillon
2016-03-30 20:03   ` Boris Brezillon
2016-03-30 20:03   ` Boris Brezillon
     [not found] ` <1459368249-13241-1-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2016-03-30 20:03   ` [PATCH v5 01/46] pwm: rcar: make use of pwm_is_enabled() Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-04-12 11:01     ` Thierry Reding
2016-04-12 11:01       ` Thierry Reding
2016-04-12 11:01       ` Thierry Reding
2016-04-12 11:01       ` Thierry Reding
     [not found]       ` <20160412110152.GG18882-EkSeR96xj6Pcmrwk2tT4+A@public.gmane.org>
2016-04-14 11:05         ` Boris Brezillon
2016-04-14 11:05           ` Boris Brezillon
2016-04-14 11:05           ` Boris Brezillon
2016-04-14 11:05           ` Boris Brezillon
2016-03-30 20:03   ` [PATCH v5 04/46] pwm: get rid of pwm->lock Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
     [not found]     ` <1459368249-13241-5-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2016-04-12 11:22       ` Thierry Reding
2016-04-12 11:22         ` Thierry Reding
2016-04-12 11:22         ` Thierry Reding
2016-04-12 11:22         ` Thierry Reding
     [not found]         ` <20160412112246.GJ18882-EkSeR96xj6Pcmrwk2tT4+A@public.gmane.org>
2016-04-12 11:32           ` Boris Brezillon
2016-04-12 11:32             ` Boris Brezillon
2016-04-12 11:32             ` Boris Brezillon
2016-04-12 11:32             ` Boris Brezillon
2016-04-12 11:46             ` Thierry Reding
2016-04-12 11:46               ` Thierry Reding
2016-04-12 11:46               ` Thierry Reding
2016-04-12 11:46               ` Thierry Reding
2016-03-30 20:03   ` [PATCH v5 05/46] pwm: introduce the pwm_args concept Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
     [not found]     ` <1459368249-13241-6-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2016-03-30 21:55       ` Stephen Boyd
2016-03-30 21:55         ` Stephen Boyd
2016-03-30 21:55         ` Stephen Boyd
2016-03-30 21:55         ` Stephen Boyd
     [not found]         ` <20160330215510.GS18567-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-03-31  7:09           ` Boris Brezillon
2016-03-31  7:09             ` Boris Brezillon
2016-03-31  7:09             ` Boris Brezillon
2016-03-31  7:09             ` Boris Brezillon
2016-03-31  7:57         ` Boris Brezillon
2016-03-31  7:57           ` Boris Brezillon
2016-03-31  7:57           ` Boris Brezillon
2016-03-31  7:57           ` Boris Brezillon
2016-04-12 11:39       ` Thierry Reding
2016-04-12 11:39         ` Thierry Reding
2016-04-12 11:39         ` Thierry Reding
2016-04-12 11:39         ` Thierry Reding
     [not found]         ` <20160412113912.GK18882-EkSeR96xj6Pcmrwk2tT4+A@public.gmane.org>
2016-04-12 12:04           ` Boris Brezillon
2016-04-12 12:04             ` Boris Brezillon
2016-04-12 12:04             ` Boris Brezillon
2016-04-12 12:04             ` Boris Brezillon
2016-04-12 12:20             ` Thierry Reding
2016-04-12 12:20               ` Thierry Reding
2016-04-12 12:20               ` Thierry Reding
2016-04-12 12:20               ` Thierry Reding
     [not found]               ` <20160412122029.GO18882-EkSeR96xj6Pcmrwk2tT4+A@public.gmane.org>
2016-04-12 12:55                 ` Boris Brezillon
2016-04-12 12:55                   ` Boris Brezillon
2016-04-12 12:55                   ` Boris Brezillon
2016-04-12 12:55                   ` Boris Brezillon
2016-04-12 13:06           ` Boris Brezillon
2016-04-12 13:06             ` Boris Brezillon
2016-04-12 13:06             ` Boris Brezillon
2016-04-12 13:06             ` Boris Brezillon
2016-04-12 13:15             ` Thierry Reding
2016-04-12 13:15               ` Thierry Reding
2016-04-12 13:15               ` Thierry Reding
2016-04-12 13:15               ` Thierry Reding
2016-03-30 20:03   ` [PATCH v5 06/46] pwm: use pwm_get/set_xxx() helpers where appropriate Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03   ` [PATCH v5 07/46] clk: pwm: use pwm_get_args() " Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
     [not found]     ` <1459368249-13241-8-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2016-03-30 21:58       ` Stephen Boyd
2016-03-30 21:58         ` Stephen Boyd
2016-03-30 21:58         ` Stephen Boyd
2016-03-30 21:58         ` Stephen Boyd
2016-03-30 20:03   ` [PATCH v5 09/46] misc: max77693-haptic: " Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03   ` [PATCH v5 10/46] leds: pwm: " Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-31  7:13     ` Jacek Anaszewski
2016-03-31  7:13       ` Jacek Anaszewski
2016-03-31  7:13       ` Jacek Anaszewski
2016-03-31  7:13       ` Jacek Anaszewski
2016-03-30 20:03   ` [PATCH v5 11/46] regulator: " Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03   ` [PATCH v5 13/46] backlight: pwm_bl: " Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03   ` [PATCH v5 14/46] pwm: keep PWM state in sync with hardware state Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03   ` [PATCH v5 15/46] pwm: introduce the pwm_state concept Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-04-12 11:49     ` Thierry Reding
2016-04-12 11:49       ` Thierry Reding
2016-04-12 11:49       ` Thierry Reding
2016-04-12 11:49       ` Thierry Reding
2016-04-12 12:17       ` Boris Brezillon
2016-04-12 12:17         ` Boris Brezillon
2016-04-12 12:17         ` Boris Brezillon
2016-04-12 12:17         ` Boris Brezillon
2016-04-12 12:21         ` Thierry Reding
2016-04-12 12:21           ` Thierry Reding
2016-04-12 12:21           ` Thierry Reding
2016-04-12 12:21           ` Thierry Reding
2016-04-12 12:45           ` Boris Brezillon
2016-04-12 12:45             ` Boris Brezillon
2016-04-12 12:45             ` Boris Brezillon
2016-04-12 12:45             ` Boris Brezillon
2016-04-12 13:11             ` Thierry Reding
2016-04-12 13:11               ` Thierry Reding
2016-04-12 13:11               ` Thierry Reding
2016-04-12 13:11               ` Thierry Reding
     [not found]               ` <20160412131118.GQ18882-EkSeR96xj6Pcmrwk2tT4+A@public.gmane.org>
2016-04-12 13:26                 ` Boris Brezillon
2016-04-12 13:26                   ` Boris Brezillon
2016-04-12 13:26                   ` Boris Brezillon
2016-04-12 13:26                   ` Boris Brezillon
2016-04-12 14:05                   ` Thierry Reding
2016-04-12 14:05                     ` Thierry Reding
2016-04-12 14:05                     ` Thierry Reding
2016-04-12 14:05                     ` Thierry Reding
2016-04-12 14:13                     ` Boris Brezillon
2016-04-12 14:13                       ` Boris Brezillon
2016-04-12 14:13                       ` Boris Brezillon
2016-04-12 14:13                       ` Boris Brezillon
2016-03-30 20:03   ` [PATCH v5 16/46] pwm: move the enabled/disabled info into pwm_state Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
     [not found]     ` <1459368249-13241-17-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2016-04-12 11:51       ` Thierry Reding
2016-04-12 11:51         ` Thierry Reding
2016-04-12 11:51         ` Thierry Reding
2016-04-12 11:51         ` Thierry Reding
2016-03-30 20:03   ` [PATCH v5 17/46] pwm: add the PWM initial state retrieval infra Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03   ` Boris Brezillon [this message]
2016-03-30 20:03     ` [PATCH v5 18/46] pwm: add the core infrastructure to allow atomic update Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03   ` [PATCH v5 19/46] pwm: switch to the atomic API Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03   ` [PATCH v5 20/46] pwm: add information about polarity, duty cycle and period to debugfs Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03   ` [PATCH v5 21/46] pwm: rockchip: add initial state retrieval Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03   ` [PATCH v5 22/46] pwm: rockchip: avoid glitches on already running PWMs Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
     [not found]     ` <1459368249-13241-23-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2017-08-04 12:45       ` [v5,22/46] " David.Wu
2017-08-04 14:07         ` Boris Brezillon
2017-08-04 14:07           ` Boris Brezillon
2017-08-04 14:48           ` Heiko Stuebner
2017-08-04 14:48             ` Heiko Stuebner
2017-08-04 16:22             ` Doug Anderson
2017-08-21 15:39               ` Boris Brezillon
2017-08-21 15:39                 ` Boris Brezillon
2017-08-21 16:49                 ` Doug Anderson
2017-08-21 16:49                   ` Doug Anderson
2017-08-21 19:50                   ` Boris Brezillon
2017-08-21 19:50                     ` Boris Brezillon
2017-08-07  7:43             ` Elaine Zhang
2016-03-30 20:03   ` [PATCH v5 23/46] pwm: rockchip: add support for atomic update Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03   ` [PATCH v5 24/46] pwm: sti: add support for initial state retrieval Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03   ` [PATCH v5 25/46] pwm: sti: avoid glitches on already running PWMs Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03   ` [PATCH v5 26/46] pwm: sun4i: implement hardware readout Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
     [not found]     ` <1459368249-13241-27-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2016-03-31  8:00       ` Alexandre Belloni
2016-03-31  8:00         ` Alexandre Belloni
2016-03-31  8:00         ` Alexandre Belloni
2016-03-31  8:00         ` Alexandre Belloni
2016-03-30 20:03   ` [PATCH v5 27/46] regulator: pwm: adjust PWM config at probe time Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
     [not found]     ` <1459368249-13241-28-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2016-03-30 21:22       ` Mark Brown
2016-03-30 21:22         ` Mark Brown
2016-03-30 21:22         ` Mark Brown
2016-03-30 21:22         ` Mark Brown
2016-03-30 20:03   ` [PATCH v5 28/46] regulator: pwm: swith to the atomic PWM API Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
     [not found]     ` <1459368249-13241-29-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2016-03-30 21:23       ` Mark Brown
2016-03-30 21:23         ` Mark Brown
2016-03-30 21:23         ` Mark Brown
2016-03-30 21:23         ` Mark Brown
2016-03-30 20:03   ` [PATCH v5 29/46] regulator: pwm: properly initialize the ->state field Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03   ` [PATCH v5 30/46] regulator: pwm: retrieve correct voltage Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
     [not found]     ` <1459368249-13241-31-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2016-03-30 21:24       ` Mark Brown
2016-03-30 21:24         ` Mark Brown
2016-03-30 21:24         ` Mark Brown
2016-03-30 21:24         ` Mark Brown
     [not found]         ` <20160330212410.GX2350-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2016-04-07 21:54           ` Boris Brezillon
2016-04-07 21:54             ` Boris Brezillon
2016-04-07 21:54             ` Boris Brezillon
2016-04-07 21:54             ` Boris Brezillon
2016-04-12  4:42             ` Mark Brown
2016-04-12  4:42               ` Mark Brown
2016-04-12  4:42               ` Mark Brown
2016-04-12  4:42               ` Mark Brown
     [not found]               ` <20160412044203.GW3351-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2016-04-12  8:37                 ` Boris Brezillon
2016-04-12  8:37                   ` Boris Brezillon
2016-04-12  8:37                   ` Boris Brezillon
2016-04-12  8:37                   ` Boris Brezillon
2016-04-12 10:09                   ` Mark Brown
2016-04-12 10:09                     ` Mark Brown
2016-04-12 10:09                     ` Mark Brown
2016-04-12 10:09                     ` Mark Brown
     [not found]                     ` <20160412100938.GA14664-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2016-04-12 10:31                       ` Boris Brezillon
2016-04-12 10:31                         ` Boris Brezillon
2016-04-12 10:31                         ` Boris Brezillon
2016-04-12 10:31                         ` Boris Brezillon
2016-03-30 20:03   ` [PATCH v5 31/46] pwm: update documentation Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03   ` [PATCH v5 32/46] pwm: deprecate pwm_config(), pwm_enable() and pwm_disable() Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-31 17:38     ` Dmitry Torokhov
2016-03-31 17:38       ` Dmitry Torokhov
2016-03-31 17:38       ` Dmitry Torokhov
2016-03-31 17:38       ` Dmitry Torokhov
2016-03-31 18:54       ` Boris Brezillon
2016-03-31 18:54         ` Boris Brezillon
2016-03-31 18:54         ` Boris Brezillon
2016-03-31 18:54         ` Boris Brezillon
2016-04-04 15:22         ` Thierry Reding
2016-04-04 15:22           ` Thierry Reding
2016-04-04 15:22           ` Thierry Reding
2016-04-04 15:22           ` Thierry Reding
2016-03-30 20:03   ` [PATCH v5 33/46] pwm: replace pwm_disable() by pwm_apply_state() Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03   ` [PATCH v5 34/46] clk: pwm: switch to the atomic API Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 22:01     ` Stephen Boyd
2016-03-30 22:01       ` Stephen Boyd
2016-03-30 22:01       ` Stephen Boyd
2016-03-30 22:01       ` Stephen Boyd
     [not found]       ` <20160330220149.GU18567-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-03-31  6:57         ` Boris Brezillon
2016-03-31  6:57           ` Boris Brezillon
2016-03-31  6:57           ` Boris Brezillon
2016-03-31  6:57           ` Boris Brezillon
2016-04-04 15:30           ` Thierry Reding
2016-04-04 15:30             ` Thierry Reding
2016-04-04 15:30             ` Thierry Reding
2016-04-04 15:30             ` Thierry Reding
2016-03-30 20:03   ` [PATCH v5 35/46] hwmon: pwm-fan: " Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-04-01  8:29     ` Kamil Debski
2016-04-01  8:29       ` Kamil Debski
2016-04-01  8:29       ` Kamil Debski
2016-04-01  8:29       ` Kamil Debski
2016-03-30 20:03   ` [PATCH v5 36/46] input: misc: max77693: " Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-30 20:03     ` Boris Brezillon
2016-03-31 17:48     ` Dmitry Torokhov
2016-03-31 17:48       ` Dmitry Torokhov
2016-03-31 17:48       ` Dmitry Torokhov
2016-03-31 17:48       ` Dmitry Torokhov
2016-03-31 18:57       ` Boris Brezillon
2016-03-31 18:57         ` Boris Brezillon
2016-03-31 18:57         ` Boris Brezillon
2016-03-31 18:57         ` Boris Brezillon
2016-04-04 15:34         ` Thierry Reding
2016-04-04 15:34           ` Thierry Reding
2016-04-04 15:34           ` Thierry Reding
2016-04-04 15:34           ` Thierry Reding
2016-03-30 20:04   ` [PATCH v5 37/46] input: misc: max8997: switch to the atomic PWM API Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04   ` [PATCH v5 38/46] input: misc: pwm-beeper: " Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04   ` [PATCH v5 39/46] leds: pwm: " Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04   ` [PATCH v5 40/46] backlight: lm3630a: " Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04   ` [PATCH v5 42/46] backlight: lp8788: " Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04   ` [PATCH v5 43/46] backlight: pwm_bl: " Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04   ` [PATCH v5 44/46] video: ssd1307fb: " Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04   ` [PATCH v5 45/46] drm: i915: " Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-31  6:34     ` Jani Nikula
2016-03-31  8:44       ` Shobhit Kumar
2016-03-30 20:04   ` [PATCH v5 46/46] ARM: s3c24xx: rx1950: " Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:04     ` Boris Brezillon
2016-03-30 20:18   ` [PATCH v5 00/46] pwm: add support for atomic update Boris Brezillon
2016-03-30 20:18     ` Boris Brezillon
2016-03-30 20:18     ` Boris Brezillon
2016-03-30 20:18     ` Boris Brezillon
2016-03-30 20:18     ` Boris Brezillon
2016-04-11 22:42   ` Boris Brezillon
2016-04-11 22:42     ` Boris Brezillon
2016-04-11 22:42     ` Boris Brezillon
2016-04-11 22:42     ` Boris Brezillon
2016-03-30 20:04 ` [PATCH v5 41/46] backlight: lp855x: switch to the atomic PWM API Boris Brezillon
2016-03-30 20:04   ` Boris Brezillon
2016-03-30 20:04   ` Boris Brezillon
2016-03-30 20:04   ` Boris Brezillon
2016-03-31 16:12 ` ✗ Fi.CI.BAT: failure for pwm: add support for atomic update Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1459368249-13241-19-git-send-email-boris.brezillon@free-electrons.com \
    --to=boris.brezillon-wi1+55scjutkeb57/3fjtnbpr1lh4cv8@public.gmane.org \
    --cc=broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=cooloney-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org \
    --cc=j.anaszewski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org \
    --cc=jdelvare-IBi9RG/b67k@public.gmane.org \
    --cc=jingoohan1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=k.debski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org \
    --cc=lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
    --cc=lgirdwood-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=linux-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org \
    --cc=linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-input-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-leds-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-pwm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org \
    --cc=lm-sensors-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org \
    --cc=manabian-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org \
    --cc=mturquette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org \
    --cc=rpurdie-Fm38FmjxZ/leoWH0uzbU5w@public.gmane.org \
    --cc=sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
    --cc=thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org \
    --cc=wens-jdAy2FN1RRM@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.