mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Rong Zhang <i@rong.moe>
To: Armin Wolf <W_Armin@gmx.de>, lee@kernel.org, pavel@kernel.org
Cc: linux-leds@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 04/10] leds: class: Create "brightness_hw_changed" attribute atomically
Date: Mon, 19 Oct 2026 19:51:33 +0800	[thread overview]
Message-ID: <fbb6a7b4b674d11dab0acc2b855f59a68fae6346.camel@rong.moe> (raw)
In-Reply-To: <20261018135339.1109271-5-W_Armin@gmx.de>

Hi Armin,

Nice refactor!

On Sun, 2026-10-18 at 15:46 +0200, Armin Wolf wrote:
> Using device_create_file() might cause userspace applications
> listening for uevents to inspect a new LED device before the kernel
> has registered all sysfs attributes for it. This might cause those
> applications to incorrectly assume that the new LED device does not
> support the "brightness_hw_changed" attribute.
> 
> Fix this by letting the device core create the sysfs attribute before
> the uevent is being send to userspace.
> 
> Signed-off-by: Armin Wolf <W_Armin@gmx.de>
> ---
>  drivers/leds/led-class.c | 85 +++++++++++++++-------------------------
>  include/linux/leds.h     |  2 -
>  2 files changed, 31 insertions(+), 56 deletions(-)
> 
> diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
> index 3775ad13762f..d460f041ed86 100644
> --- a/drivers/leds/led-class.c
> +++ b/drivers/leds/led-class.c
> @@ -17,6 +17,7 @@
>  #include <linux/property.h>
>  #include <linux/slab.h>
>  #include <linux/spinlock.h>
> +#include <linux/sysfs.h>
>  #include <linux/timer.h>
>  #include <uapi/linux/uleds.h>
>  #include <linux/of.h>
> @@ -101,14 +102,6 @@ static const struct attribute_group led_group = {
>  	.attrs_const = led_class_attrs,
>  };
>  
> -static const struct attribute_group *const led_groups[] = {

This is a back-and-forth change. How about moving led_groups to the right
place in PATCH 1 beforehand?

Other than that, FWIW:

   Reviewed-by: Rong Zhang <i@rong.moe>

Thanks,
Rong

> -	&led_group,
> -#ifdef CONFIG_LEDS_TRIGGERS
> -	&led_trigger_group,
> -#endif
> -	NULL,
> -};
> -
>  #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED
>  static ssize_t brightness_hw_changed_show(struct device *dev, const struct device_attribute *attr,
>  					  char *buf)
> @@ -123,51 +116,48 @@ static ssize_t brightness_hw_changed_show(struct device *dev, const struct devic
>  
>  static const DEVICE_ATTR_RO(brightness_hw_changed);
>  
> -static int led_add_brightness_hw_changed(struct led_classdev *led_cdev)
> -{
> -	struct device *dev = led_cdev->dev;
> -	int ret;
> +static const struct attribute *const led_brightness_hw_changed_attrs[] = {
> +	&dev_attr_brightness_hw_changed.attr,
> +	NULL,
> +};
>  
> -	ret = device_create_file(dev, &dev_attr_brightness_hw_changed);
> -	if (ret) {
> -		dev_err(dev, "Error creating brightness_hw_changed\n");
> -		return ret;
> -	}
> +static umode_t led_brightness_hw_changed_is_visible(struct kobject *kobj,
> +						    const struct attribute *attr, int n)
> +{
> +	struct device *dev = kobj_to_dev(kobj);
> +	struct led_classdev *led_cdev = dev_get_drvdata(dev);
>  
> -	led_cdev->brightness_hw_changed_kn =
> -		sysfs_get_dirent(dev->kobj.sd, "brightness_hw_changed");
> -	if (!led_cdev->brightness_hw_changed_kn) {
> -		dev_err(dev, "Error getting brightness_hw_changed kn\n");
> -		device_remove_file(dev, &dev_attr_brightness_hw_changed);
> -		return -ENXIO;
> -	}
> +	if (attr == &dev_attr_brightness_hw_changed.attr &&
> +	    led_cdev->flags & LED_BRIGHT_HW_CHANGED)
> +		return attr->mode;
>  
>  	return 0;
>  }
>  
> -static void led_remove_brightness_hw_changed(struct led_classdev *led_cdev)
> -{
> -	sysfs_put(led_cdev->brightness_hw_changed_kn);
> -	device_remove_file(led_cdev->dev, &dev_attr_brightness_hw_changed);
> -}
> +static const struct attribute_group led_brightness_hw_changed_group = {
> +	.is_visible_const = led_brightness_hw_changed_is_visible,
> +	.attrs_const = led_brightness_hw_changed_attrs,
> +};
> +#endif	/* CONFIG_LEDS_BRIGHTNESS_HW_CHANGED */
>  
> +static const struct attribute_group *const led_groups[] = {
> +	&led_group,
> +#ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED
> +	&led_brightness_hw_changed_group,
> +#endif
> +#ifdef CONFIG_LEDS_TRIGGERS
> +	&led_trigger_group,
> +#endif
> +	NULL,
> +};
> +
> +#ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED
>  void led_classdev_notify_brightness_hw_changed(struct led_classdev *led_cdev, unsigned int brightness)
>  {
> -	if (WARN_ON(!led_cdev->brightness_hw_changed_kn))
> -		return;
> -
>  	led_cdev->brightness_hw_changed = brightness;
> -	sysfs_notify_dirent(led_cdev->brightness_hw_changed_kn);
> +	sysfs_notify(&led_cdev->dev->kobj, NULL, "brightness_hw_changed");
>  }
>  EXPORT_SYMBOL_GPL(led_classdev_notify_brightness_hw_changed);
> -#else
> -static int led_add_brightness_hw_changed(struct led_classdev *led_cdev)
> -{
> -	return 0;
> -}
> -static void led_remove_brightness_hw_changed(struct led_classdev *led_cdev)
> -{
> -}
>  #endif
>  
>  /**
> @@ -544,16 +534,6 @@ int led_classdev_register_ext(struct device *parent,
>  	if (init_data && init_data->fwnode)
>  		device_set_node(led_cdev->dev, init_data->fwnode);
>  
> -	if (led_cdev->flags & LED_BRIGHT_HW_CHANGED) {
> -		ret = led_add_brightness_hw_changed(led_cdev);
> -		if (ret) {
> -			device_unregister(led_cdev->dev);
> -			led_cdev->dev = NULL;
> -			mutex_unlock(&led_cdev->led_access);
> -			return ret;
> -		}
> -	}
> -
>  	led_cdev->work_flags = 0;
>  #ifdef CONFIG_LEDS_TRIGGERS
>  	init_rwsem(&led_cdev->trigger_lock);
> @@ -626,9 +606,6 @@ void led_classdev_unregister(struct led_classdev *led_cdev)
>  
>  	flush_work(&led_cdev->set_brightness_work);
>  
> -	if (led_cdev->flags & LED_BRIGHT_HW_CHANGED)
> -		led_remove_brightness_hw_changed(led_cdev);
> -
>  	device_unregister(led_cdev->dev);
>  
>  	down_write(&leds_list_lock);
> diff --git a/include/linux/leds.h b/include/linux/leds.h
> index beaf23993063..6f975078cc14 100644
> --- a/include/linux/leds.h
> +++ b/include/linux/leds.h
> @@ -21,7 +21,6 @@ struct attribute_group;
>  struct device_node;
>  struct fwnode_handle;
>  struct gpio_desc;
> -struct kernfs_node;
>  struct led_pattern;
>  struct platform_device;
>  
> @@ -237,7 +236,6 @@ struct led_classdev {
>  
>  #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED
>  	int			 brightness_hw_changed;
> -	struct kernfs_node	*brightness_hw_changed_kn;
>  #endif
>  
>  #ifdef CONFIG_LEDS_TRIGGERS_HW_CHANGED

  reply	other threads:[~2026-10-19 11:56 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-18 13:46 [PATCH 00/10] leds: class: Support custom sysfs groups on multicolor and flash LEDs Armin Wolf
2026-10-18 13:46 ` [PATCH 01/10] leds: class: Constify sysfs attributes Armin Wolf
2026-10-18 13:46 ` [PATCH 02/10] leds: multicolor: " Armin Wolf
2026-10-18 13:46 ` [PATCH 03/10] leds: flash: " Armin Wolf
2026-10-18 13:46 ` [PATCH 04/10] leds: class: Create "brightness_hw_changed" attribute atomically Armin Wolf
2026-10-19 11:51   ` Rong Zhang [this message]
2026-10-20 20:55     ` Armin Wolf
2026-10-18 13:46 ` [PATCH 05/10] leds: class: Fix race condition when creating the device Armin Wolf
2026-10-18 13:46 ` [PATCH 06/10] leds: class: Take the LED access lock when reading brightness_hw_changed Armin Wolf
2026-10-18 13:46 ` [PATCH 07/10] leds: class: Use correct type for brightness_hw_changed field Armin Wolf
2026-10-18 13:46 ` [PATCH 08/10] leds: class: Split led_classdev_register_ext() Armin Wolf
2026-10-18 13:46 ` [PATCH 09/10] leds: Support custom sysfs groups on multicolor and flash LEDs Armin Wolf
2026-10-19 11:53   ` Rong Zhang
2026-10-20 20:57     ` Armin Wolf
2026-10-18 13:46 ` [PATCH 10/10] leds: multicolor: Adjust maximum subled intensity during initialization Armin Wolf
2026-10-19 11:54   ` Rong Zhang
2026-10-20 20:59     ` Armin Wolf

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=fbb6a7b4b674d11dab0acc2b855f59a68fae6346.camel@rong.moe \
    --to=i@rong.moe \
    --cc=W_Armin@gmx.de \
    --cc=lee@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-leds@vger.kernel.org \
    --cc=pavel@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

all inboxes | Powered by JetHome®