From: "Marek Behún" <kabel@kernel.org>
To: Lee Jones <lee@kernel.org>
Cc: "Pavel Machek" <pavel@ucw.cz>,
linux-leds@vger.kernel.org, "Arnd Bergmann" <arnd@arndb.de>,
soc@kernel.org, "Gregory CLEMENT" <gregory.clement@bootlin.com>,
arm@kernel.org, "Andy Shevchenko" <andy@kernel.org>,
"Hans de Goede" <hdegoede@redhat.com>,
"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
"Andrew Lunn" <andrew@lunn.ch>,
"Sebastian Hesselbarth" <sebastian.hesselbarth@gmail.com>,
"Rob Herring" <robh+dt@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
devicetree@vger.kernel.org, "Marek Behún" <kabel@kernel.org>
Subject: [PATCH leds v7 07/11] leds: turris-omnia: Notify sysfs on MCU global LEDs brightness change
Date: Mon, 11 Nov 2024 11:03:51 +0100 [thread overview]
Message-ID: <20241111100355.6978-8-kabel@kernel.org> (raw)
In-Reply-To: <20241111100355.6978-1-kabel@kernel.org>
Recall that on Turris Omnia, the LED controller has a global brightness
property, which allows the user to make the front LED panel dimmer.
There is also a button on the front panel, which by default is
configured so that pressing it changes the global brightness to a lower
value (unless it is at 0%, in which case pressing the button changes the
global brightness to 100%).
Newer versions of the MCU firmware support informing the SOC that the
brightness was changed by button press event via an interrupt.
Now that we have the turris-omnia-mcu driver, which adds support for MCU
interrupts, add the ability to inform the userspace (via a sysfs
notification) that the global brightness was changed.
Signed-off-by: Marek Behún <kabel@kernel.org>
---
drivers/leds/Kconfig | 1 +
drivers/leds/leds-turris-omnia.c | 62 ++++++++++++++++++++++++++++++++
2 files changed, 63 insertions(+)
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index fcbe93b61e49..9ab6b56898c6 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -218,6 +218,7 @@ config LEDS_TURRIS_OMNIA
depends on MACH_ARMADA_38X || COMPILE_TEST
depends on OF
depends on TURRIS_OMNIA_MCU
+ depends on TURRIS_OMNIA_MCU_GPIO
select LEDS_TRIGGERS
help
This option enables basic support for the LEDs found on the front
diff --git a/drivers/leds/leds-turris-omnia.c b/drivers/leds/leds-turris-omnia.c
index b60c34f57d0e..61186c3a6c2f 100644
--- a/drivers/leds/leds-turris-omnia.c
+++ b/drivers/leds/leds-turris-omnia.c
@@ -43,12 +43,15 @@ struct omnia_led {
* @client: I2C client device
* @lock: mutex to protect cached state
* @has_gamma_correction: whether the MCU firmware supports gamma correction
+ * @brightness_knode: kernel node of the "brightness" device sysfs attribute (this is the
+ * driver specific global brightness, not the LED classdev brightness)
* @leds: flexible array of per-LED data
*/
struct omnia_leds {
struct i2c_client *client;
struct mutex lock;
bool has_gamma_correction;
+ struct kernfs_node *brightness_knode;
struct omnia_led leds[];
};
@@ -373,6 +376,59 @@ static struct attribute *omnia_led_controller_attrs[] = {
};
ATTRIBUTE_GROUPS(omnia_led_controller);
+static irqreturn_t omnia_brightness_changed_threaded_fn(int irq, void *data)
+{
+ struct omnia_leds *leds = data;
+
+ if (unlikely(!leds->brightness_knode)) {
+ /*
+ * Note that sysfs_get_dirent() may sleep. This is okay, because we are in threaded
+ * context.
+ */
+ leds->brightness_knode = sysfs_get_dirent(leds->client->dev.kobj.sd, "brightness");
+ if (!leds->brightness_knode)
+ return IRQ_NONE;
+ }
+
+ sysfs_notify_dirent(leds->brightness_knode);
+
+ return IRQ_HANDLED;
+}
+
+static void omnia_brightness_knode_put(void *data)
+{
+ struct omnia_leds *leds = data;
+
+ if (leds->brightness_knode)
+ sysfs_put(leds->brightness_knode);
+}
+
+static int omnia_request_brightness_irq(struct omnia_leds *leds)
+{
+ struct device *dev = &leds->client->dev;
+ int ret;
+
+ if (!leds->client->irq) {
+ dev_info(dev,
+ "Brightness change interrupt supported by MCU firmware but not described in device-tree\n");
+
+ return 0;
+ }
+
+ /*
+ * Registering the brightness_knode destructor before requesting the IRQ ensures that on
+ * removal the brightness_knode sysfs node is put only after the IRQ is freed.
+ * This is needed because the interrupt handler uses the knode.
+ */
+ ret = devm_add_action(dev, omnia_brightness_knode_put, leds);
+ if (ret < 0)
+ return ret;
+
+ return devm_request_threaded_irq(dev, leds->client->irq, NULL,
+ omnia_brightness_changed_threaded_fn, IRQF_ONESHOT,
+ "leds-turris-omnia", leds);
+}
+
static int omnia_mcu_get_features(const struct i2c_client *mcu_client)
{
u16 reply;
@@ -459,6 +515,12 @@ static int omnia_leds_probe(struct i2c_client *client)
"Consider upgrading MCU firmware with the omnia-mcutool utility.\n");
}
+ if (ret & OMNIA_FEAT_BRIGHTNESS_INT) {
+ ret = omnia_request_brightness_irq(leds);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Cannot request brightness IRQ\n");
+ }
+
mutex_init(&leds->lock);
ret = devm_led_trigger_register(dev, &omnia_hw_trigger);
--
2.45.2
next prev parent reply other threads:[~2024-11-11 10:04 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-11 10:03 [PATCH leds v7 00/11] Turris Omnia LED driver changes Marek Behún
2024-11-11 10:03 ` [PATCH leds v7 01/11] turris-omnia-mcu-interface.h: Move command execution function to global header Marek Behún
2024-11-11 10:03 ` [PATCH leds v7 02/11] leds: turris-omnia: Use command execution functions from the MCU driver Marek Behún
2024-11-11 10:03 ` [PATCH leds v7 03/11] turris-omnia-mcu-interface.h: Add LED commands related definitions to global header Marek Behún
2024-12-12 18:33 ` Lee Jones
2024-11-11 10:03 ` [PATCH leds v7 04/11] leds: turris-omnia: Use global header for MCU command definitions Marek Behún
2024-11-11 10:03 ` [PATCH leds v7 05/11] dt-bindings: leds: cznic,turris-omnia-leds: Allow interrupts property Marek Behún
2024-11-11 10:03 ` [PATCH leds v7 06/11] leds: turris-omnia: Document driver private structures Marek Behún
2024-11-11 10:03 ` Marek Behún [this message]
2024-11-11 10:03 ` [PATCH leds v7 08/11] platform: cznic: turris-omnia-mcu: Inform about missing LED panel brightness change interrupt feature Marek Behún
2024-11-11 10:03 ` [PATCH leds v7 09/11] leds: turris-omnia: Inform about missing LED gamma correction feature in the MCU driver Marek Behún
2024-11-11 10:03 ` [PATCH leds v7 10/11] leds: turris-omnia: Use dev_err_probe() where appropriate Marek Behún
2024-11-11 10:03 ` [PATCH leds v7 11/11] leds: turris-omnia: Use uppercase first letter in all comments Marek Behún
2024-12-09 9:48 ` [PATCH leds v7 00/11] Turris Omnia LED driver changes Marek Behún
2024-12-12 18:38 ` Lee Jones
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=20241111100355.6978-8-kabel@kernel.org \
--to=kabel@kernel.org \
--cc=andrew@lunn.ch \
--cc=andy@kernel.org \
--cc=arm@kernel.org \
--cc=arnd@arndb.de \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=gregory.clement@bootlin.com \
--cc=hdegoede@redhat.com \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=krzk+dt@kernel.org \
--cc=lee@kernel.org \
--cc=linux-leds@vger.kernel.org \
--cc=pavel@ucw.cz \
--cc=robh+dt@kernel.org \
--cc=sebastian.hesselbarth@gmail.com \
--cc=soc@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 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.