linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
To: <pavel@ucw.cz>, <robh+dt@kernel.org>,
	<krzysztof.kozlowski+dt@linaro.org>
Cc: <andy.shevchenko@gmail.com>, <linux-leds@vger.kernel.org>,
	<devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	Jean-Jacques Hiblot <jjhiblot@traphandler.com>
Subject: [RESEND PATCH v6 3/3] leds: tlc5925: Add support for non blocking operations
Date: Fri, 22 Jul 2022 10:11:46 +0200	[thread overview]
Message-ID: <20220722081146.47262-4-jjhiblot@traphandler.com> (raw)
In-Reply-To: <20220722081146.47262-1-jjhiblot@traphandler.com>

Settings multiple LEDs in a row can be a slow operation because of the
time required to acquire the bus and prepare the transfer.
And, in most cases, it is not required that the operation is synchronous.
Implementing the non-blocking brightness_set() for such cases.
A work queue is used to perform the actual SPI transfer.

The blocking method is still available in case someone needs to perform
this operation synchronously (ie by calling led_set_brightness_sync()).

Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
---
 drivers/leds/leds-tlc5925.c | 38 +++++++++++++++++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/drivers/leds/leds-tlc5925.c b/drivers/leds/leds-tlc5925.c
index 797836354c74..0423e3592bd7 100644
--- a/drivers/leds/leds-tlc5925.c
+++ b/drivers/leds/leds-tlc5925.c
@@ -18,6 +18,7 @@
 #include <linux/property.h>
 #include <linux/spi/spi.h>
 #include <linux/types.h>
+#include <linux/workqueue.h>
 
 #define TLC5925_SHIFT_REGISTER_LENGTH 16
 
@@ -29,10 +30,25 @@ struct single_led_priv {
 struct tlc5925_leds_priv {
 	int max_num_leds;
 	unsigned long *state;
+	struct spi_device *spi;
+	struct work_struct xmit_work;
 	struct single_led_priv leds[];
 };
 
-static int tlc5925_brightness_set_blocking(struct led_classdev *cdev,
+static int xmit(struct tlc5925_leds_priv *priv)
+{
+	return spi_write(priv->spi, priv->state, BITS_TO_BYTES(priv->max_num_leds));
+}
+
+static void xmit_work(struct work_struct *ws)
+{
+	struct tlc5925_leds_priv *priv =
+		container_of(ws, struct tlc5925_leds_priv, xmit_work);
+
+	xmit(priv);
+};
+
+static void tlc5925_brightness_set(struct led_classdev *cdev,
 					    enum led_brightness brightness)
 {
 	struct spi_device *spi = to_spi_device(cdev->dev->parent);
@@ -43,9 +59,23 @@ static int tlc5925_brightness_set_blocking(struct led_classdev *cdev,
 
 	assign_bit(index, priv->state, !!brightness);
 
-	return spi_write(spi, priv->state, BITS_TO_BYTES(priv->max_num_leds));
+	schedule_work(&priv->xmit_work);
 }
 
+static int tlc5925_brightness_set_blocking(struct led_classdev *cdev,
+					    enum led_brightness brightness)
+{
+	struct spi_device *spi = to_spi_device(cdev->dev->parent);
+	struct tlc5925_leds_priv *priv = spi_get_drvdata(spi);
+	struct single_led_priv *led =
+		container_of(cdev, struct single_led_priv, cdev);
+	int index = led->idx;
+
+	assign_bit(index, priv->state, !!brightness);
+
+	cancel_work_sync(&priv->xmit_work);
+	return xmit(priv);
+}
 static int tlc5925_probe(struct spi_device *spi)
 {
 	struct device *dev = &spi->dev;
@@ -83,6 +113,9 @@ static int tlc5925_probe(struct spi_device *spi)
 	if (!priv->state)
 		return -ENOMEM;
 
+	priv->spi = spi;
+	INIT_WORK(&priv->xmit_work, xmit_work);
+
 	priv->max_num_leds = max_num_leds;
 
 	device_for_each_child_node(dev, child) {
@@ -104,6 +137,7 @@ static int tlc5925_probe(struct spi_device *spi)
 		cdev = &(priv->leds[count].cdev);
 		cdev->brightness = LED_OFF;
 		cdev->max_brightness = 1;
+		cdev->brightness_set = tlc5925_brightness_set;
 		cdev->brightness_set_blocking = tlc5925_brightness_set_blocking;
 
 		ret = devm_led_classdev_register_ext(dev, cdev, &init_data);
-- 
2.25.1


  parent reply	other threads:[~2022-07-22  8:12 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-22  8:11 [RESEND PATCH v6 0/3] Add support for the TLC5925 Jean-Jacques Hiblot
2022-07-22  8:11 ` [RESEND PATCH v6 1/3] dt-bindings: leds: Add bindings for the TLC5925 controller Jean-Jacques Hiblot
2022-07-22  8:11 ` [RESEND PATCH v6 2/3] leds: Add driver for the TLC5925 LED controller Jean-Jacques Hiblot
2022-07-30 21:27   ` Pavel Machek
2022-07-31 19:28   ` Andy Shevchenko
2022-08-04 20:23     ` Jean-Jacques Hiblot
2022-08-04 20:40       ` Andy Shevchenko
2022-08-04 21:04       ` Pavel Machek
2022-08-24  8:39         ` Jean-Jacques Hiblot
2022-08-24  8:55           ` Andy Shevchenko
2022-08-24  9:58             ` Jean-Jacques Hiblot
2022-08-24 10:18               ` Andy Shevchenko
2022-08-26  9:11                 ` Linus Walleij
2022-07-22  8:11 ` Jean-Jacques Hiblot [this message]
2022-07-30 21:22   ` [RESEND PATCH v6 3/3] leds: tlc5925: Add support for non blocking operations Pavel Machek

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=20220722081146.47262-4-jjhiblot@traphandler.com \
    --to=jjhiblot@traphandler.com \
    --cc=andy.shevchenko@gmail.com \
    --cc=devicetree@vger.kernel.org \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-leds@vger.kernel.org \
    --cc=pavel@ucw.cz \
    --cc=robh+dt@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).