devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Lee Jones <lee@kernel.org>
To: "Marek Behún" <kabel@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
Subject: Re: [PATCH leds v5 07/12] leds: turris-omnia: Notify sysfs on MCU global LEDs brightness change
Date: Wed, 6 Nov 2024 10:37:06 +0000	[thread overview]
Message-ID: <20241106103706.GP1807686@google.com> (raw)
In-Reply-To: <20241104141924.18816-8-kabel@kernel.org>

On Mon, 04 Nov 2024, Marek Behún wrote:

> 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             |  2 +-
>  drivers/leds/leds-turris-omnia.c | 48 ++++++++++++++++++++++++++++++++
>  2 files changed, 49 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
> index fcbe93b61e49..148384aacdcc 100644
> --- a/drivers/leds/Kconfig
> +++ b/drivers/leds/Kconfig
> @@ -217,7 +217,7 @@ config LEDS_TURRIS_OMNIA
>  	depends on I2C
>  	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 7d2ed0c6500a..168ce362fd14 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
>   * @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,30 @@ 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)) {
> +		/*
> +		 * It would be nicer to get this dirent in the driver probe method, before the IRQ
> +		 * is requested. But the really_probe() function in drivers/base/dd.c registers
> +		 * driver's .dev_groups only after probe is finished, so during driver probe the
> +		 * "brightness" sysfs node is not yet present.

Right, but this is known and therefore never called from probe making
this comment superfluous.  Either do something about it or remove the
comment and carry-on working with what you have. :)

> +		 *
> +		 * 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 int omnia_mcu_get_features(const struct i2c_client *mcu_client)
>  {
>  	u16 reply;
> @@ -459,6 +486,14 @@ static int omnia_leds_probe(struct i2c_client *client)
>  			 "Consider upgrading MCU firmware with the omnia-mcutool utility.\n");
>  	}
>  
> +	if (client->irq && (ret & OMNIA_FEAT_BRIGHTNESS_INT)) {
> +		ret = devm_request_threaded_irq(dev, client->irq, NULL,
> +						omnia_brightness_changed_threaded_fn, IRQF_ONESHOT,
> +						"leds-turris-omnia", 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);
> @@ -481,6 +516,19 @@ static int omnia_leds_probe(struct i2c_client *client)
>  
>  static void omnia_leds_remove(struct i2c_client *client)
>  {
> +	struct omnia_leds *leds = i2c_get_clientdata(client);
> +
> +	/*
> +	 * We need to free the brightness IRQ here, before putting away the brightness sysfs node.
> +	 * Otherwise devres would free the interrupt only after the sysfs node is removed, and if
> +	 * an interrupt occurred between those two events, it would use a removed sysfs node.
> +	 */
> +	devm_free_irq(&client->dev, client->irq, leds);
> +
> +	/* Now put away the sysfs node we got the first time the interrupt handler was called */
> +	if (leds->brightness_knode)
> +		sysfs_put(leds->brightness_knode);
> +
>  	/* put all LEDs into default (HW triggered) mode */
>  	omnia_cmd_write_u8(client, OMNIA_CMD_LED_MODE, OMNIA_CMD_LED_MODE_LED(OMNIA_BOARD_LEDS));
>  
> -- 
> 2.45.2
> 

-- 
Lee Jones [李琼斯]

  parent reply	other threads:[~2024-11-06 10:37 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-04 14:19 [PATCH leds v5 00/12] Turris Omnia LED driver changes Marek Behún
2024-11-04 14:19 ` [PATCH leds v5 01/12] turris-omnia-mcu-interface.h: Move command execution function to global header Marek Behún
2024-11-06 10:28   ` Lee Jones
2024-11-06 10:53     ` Gregory CLEMENT
2024-11-06 11:01       ` Lee Jones
2024-11-06 11:02         ` Lee Jones
2024-11-04 14:19 ` [PATCH leds v5 02/12] leds: turris-omnia: Use command execution functions from the MCU driver Marek Behún
2024-11-04 14:51   ` Andy Shevchenko
2024-11-05  9:07     ` Marek Behún
2024-11-05 14:49       ` Andy Shevchenko
2024-11-04 14:19 ` [PATCH leds v5 03/12] turris-omnia-mcu-interface.h: Add LED commands related definitions to global header Marek Behún
2024-11-04 14:19 ` [PATCH leds v5 04/12] leds: turris-omnia: Use global header for MCU command definitions Marek Behún
2024-11-04 14:19 ` [PATCH leds v5 05/12] dt-bindings: leds: cznic,turris-omnia-leds: Allow interrupts property Marek Behún
2024-11-04 14:19 ` [PATCH leds v5 06/12] leds: turris-omnia: Document driver private structures Marek Behún
2024-11-04 14:19 ` [PATCH leds v5 07/12] leds: turris-omnia: Notify sysfs on MCU global LEDs brightness change Marek Behún
2024-11-05  3:25   ` kernel test robot
2024-11-06 10:29     ` Lee Jones
2024-11-08 12:40       ` Marek Behún
2024-11-06 10:37   ` Lee Jones [this message]
2024-11-04 14:19 ` [PATCH leds v5 08/12] platform: cznic: turris-omnia-mcu: Inform about missing LED panel brightness change interrupt feature Marek Behún
2024-11-04 14:19 ` [PATCH leds v5 09/12] leds: turris-omnia: Inform about missing LED gamma correction feature in the MCU driver Marek Behún
2024-11-04 14:19 ` [PATCH leds v5 10/12] leds: turris-omnia: Use dev_err_probe() where appropriate Marek Behún
2024-11-04 14:19 ` [PATCH leds v5 11/12] leds: turris-omnia: Use uppercase first letter in all comments Marek Behún
2024-11-04 14:19 ` [PATCH leds v5 12/12] ARM: dts: turris-omnia: Add global LED brightness change interrupt Marek Behún
2024-11-04 16:02   ` Gregory CLEMENT
2024-12-04  6:48     ` Klaus Kudielka
2024-12-05 12:38       ` Marek Behún
2024-12-05 12:42         ` Marek Behún
2024-12-06  9:04           ` Klaus Kudielka
2024-12-06 13:15             ` Marek Behún
2024-12-15 11:39           ` Klaus Kudielka
2024-12-15 21:26             ` Marek Behún
2024-12-16 17:46               ` Klaus Kudielka

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=20241106103706.GP1807686@google.com \
    --to=lee@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=kabel@kernel.org \
    --cc=krzk+dt@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 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).