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
next prev parent 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®