From: Hans de Goede <hdegoede@redhat.com>
To: "Darren Hart" <dvhart@infradead.org>,
"Matthew Garrett" <mjg59@srcf.ucam.org>,
"Pali Rohár" <pali.rohar@gmail.com>,
"Henrique de Moraes Holschuh" <ibm-acpi@hmh.eng.br>,
"Richard Purdie" <rpurdie@rpsys.net>,
"Jacek Anaszewski" <j.anaszewski@samsung.com>
Cc: ibm-acpi-devel@lists.sourceforge.net,
platform-driver-x86@vger.kernel.org, linux-leds@vger.kernel.org,
Hans de Goede <hdegoede@redhat.com>
Subject: [PATCH v5 1/6] leds: triggers: Add current_brightness trigger parameter
Date: Thu, 17 Nov 2016 23:24:36 +0100 [thread overview]
Message-ID: <20161117222441.31464-1-hdegoede@redhat.com> (raw)
In some cases it may be desirable for userspace to be notified when
a trigger event happens. This commit adds support for a poll-able
current_brightness trigger specific sysfs attribute which triggers
may register:
What: /sys/class/leds/<led>/current_brightness
Date: November 2016
KernelVersion: 4.10
Description:
Triggers which support it may register a current_brightness
file. This file supports poll() to detect when the trigger
modifies the brightness of the LED.
Reading this file will always return the current brightness
of the LED.
Writing this file sets the current brightness of the LED,
without influencing the trigger.
This commit adds 3 functions triggers which want to support this can use:
void led_trigger_add_current_brightness(struct led_classdev *cdev);
void led_trigger_remove_current_brightness(struct led_classdev *cdev);
void led_trigger_notify_current_brightness_change(struct led_classdev *);
The add / remove functions are to be used as, or called from the triggers
activate / deactivate callbacks and when an event happens the trigger can
call the notify function to wake-up any poll() waiters.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v5:
-This is a new patch in v5 of this patch-set (replacing earlier attempts
at similar functionality)
---
Documentation/ABI/testing/sysfs-class-led | 15 +++++-
drivers/leds/led-triggers.c | 81 +++++++++++++++++++++++++++++++
drivers/leds/leds.h | 3 ++
include/linux/leds.h | 3 ++
4 files changed, 101 insertions(+), 1 deletion(-)
diff --git a/Documentation/ABI/testing/sysfs-class-led b/Documentation/ABI/testing/sysfs-class-led
index 491cdee..b8cb74d 100644
--- a/Documentation/ABI/testing/sysfs-class-led
+++ b/Documentation/ABI/testing/sysfs-class-led
@@ -33,7 +33,8 @@ Description:
You can change triggers in a similar manner to the way an IO
scheduler is chosen. Trigger specific parameters can appear in
/sys/class/leds/<led> once a given trigger is selected. For
- their documentation see sysfs-class-led-trigger-*.
+ their documentation see sysfs-class-led-trigger-*. Also see
+ the trigger specific current_brightness file described below.
What: /sys/class/leds/<led>/inverted
Date: January 2011
@@ -44,3 +45,15 @@ Description:
gpio and backlight triggers. In case of the backlight trigger,
it is useful when driving a LED which is intended to indicate
a device in a standby like state.
+
+What: /sys/class/leds/<led>/current_brightness
+Date: November 2016
+KernelVersion: 4.10
+Description:
+ Triggers which support it may register a current_brightness
+ file. This file supports poll() to detect when the trigger
+ modifies the brightness of the LED.
+ Reading this file will always return the current brightness
+ of the LED.
+ Writing this file sets the current brightness of the LED,
+ without influencing the trigger.
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 431123b..d2ed9c2 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -102,6 +102,87 @@ ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr,
}
EXPORT_SYMBOL_GPL(led_trigger_show);
+static ssize_t current_brightness_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+
+ led_update_brightness(led_cdev);
+
+ return sprintf(buf, "%u\n", led_cdev->brightness);
+}
+
+static ssize_t current_brightness_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+ unsigned long state;
+ ssize_t ret;
+
+ mutex_lock(&led_cdev->led_access);
+
+ if (led_sysfs_is_disabled(led_cdev)) {
+ ret = -EBUSY;
+ goto unlock;
+ }
+
+ ret = kstrtoul(buf, 10, &state);
+ if (ret)
+ goto unlock;
+
+ /* _nosleep version so as to not stop sw blinking */
+ led_set_brightness_nosleep(led_cdev, state);
+
+ /* Let any listeners know the brighness changed */
+ if (led_cdev->current_brightness_kn)
+ sysfs_notify_dirent(led_cdev->current_brightness_kn);
+
+ ret = size;
+unlock:
+ mutex_unlock(&led_cdev->led_access);
+ return ret;
+}
+
+static DEVICE_ATTR_RW(current_brightness);
+
+void led_trigger_add_current_brightness(struct led_classdev *led_cdev)
+{
+ int ret;
+
+ ret = device_create_file(led_cdev->dev, &dev_attr_current_brightness);
+ if (ret) {
+ dev_err(led_cdev->dev, "Error creating current_brightness\n");
+ return;
+ }
+
+ led_cdev->current_brightness_kn =
+ sysfs_get_dirent(led_cdev->dev->kobj.sd, "current_brightness");
+ if (!led_cdev->current_brightness_kn)
+ dev_err(led_cdev->dev, "Error getting current_brightness kn\n");
+}
+EXPORT_SYMBOL_GPL(led_trigger_add_current_brightness);
+
+void led_trigger_remove_current_brightness(struct led_classdev *led_cdev)
+{
+ sysfs_put(led_cdev->current_brightness_kn);
+ led_cdev->current_brightness_kn = NULL;
+ device_remove_file(led_cdev->dev, &dev_attr_current_brightness);
+}
+EXPORT_SYMBOL_GPL(led_trigger_remove_current_brightness);
+
+void led_trigger_notify_current_brightness_change(struct led_trigger *trig)
+{
+ struct led_classdev *led_cdev;
+
+ read_lock(&trig->leddev_list_lock);
+ list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list) {
+ if (led_cdev->current_brightness_kn)
+ sysfs_notify_dirent(led_cdev->current_brightness_kn);
+ }
+ read_unlock(&trig->leddev_list_lock);
+}
+EXPORT_SYMBOL_GPL(led_trigger_notify_current_brightness_change);
+
/* Caller must ensure led_cdev->trigger_lock held */
void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
{
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h
index 7d38e6b..3d06ee6 100644
--- a/drivers/leds/leds.h
+++ b/drivers/leds/leds.h
@@ -27,6 +27,9 @@ void led_set_brightness_nopm(struct led_classdev *led_cdev,
enum led_brightness value);
void led_set_brightness_nosleep(struct led_classdev *led_cdev,
enum led_brightness value);
+void led_trigger_add_current_brightness(struct led_classdev *cdev);
+void led_trigger_remove_current_brightness(struct led_classdev *cdev);
+void led_trigger_notify_current_brightness_change(struct led_trigger *trig);
extern struct rw_semaphore leds_list_lock;
extern struct list_head leds_list;
diff --git a/include/linux/leds.h b/include/linux/leds.h
index 569cb53..d3eb992 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -13,6 +13,7 @@
#define __LINUX_LEDS_H_INCLUDED
#include <linux/device.h>
+#include <linux/kernfs.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/rwsem.h>
@@ -108,6 +109,8 @@ struct led_classdev {
void *trigger_data;
/* true if activated - deactivate routine uses it to do cleanup */
bool activated;
+ /* For triggers with current_brightness sysfs attribute */
+ struct kernfs_node *current_brightness_kn;
#endif
/* Ensures consistent access to the LED Flash Class device */
--
2.9.3
next reply other threads:[~2016-11-17 22:24 UTC|newest]
Thread overview: 77+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-17 22:24 Hans de Goede [this message]
2016-11-17 22:24 ` [PATCH v5 2/6] leds: triggers: Add a keyboard backlight trigger Hans de Goede
2016-11-18 8:55 ` Jacek Anaszewski
[not found] ` <af5a6b68-310d-85ec-16db-5c9036f38ba5-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2016-11-18 9:07 ` Hans de Goede
2016-11-18 16:03 ` Jacek Anaszewski
2016-11-18 18:47 ` Hans de Goede
2016-11-19 15:44 ` Jacek Anaszewski
2016-11-20 15:05 ` Pali Rohár
2016-11-20 16:21 ` Pavel Machek
2016-11-20 18:48 ` Hans de Goede
[not found] ` <acd1691b-56be-c902-feff-7ecf38ea102a-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-11-20 19:45 ` Pali Rohár
2016-11-21 10:24 ` Jacek Anaszewski
2016-11-21 10:42 ` Hans de Goede
2016-11-21 11:24 ` Jacek Anaszewski
2016-11-21 11:56 ` Hans de Goede
2016-11-21 13:29 ` Jacek Anaszewski
2016-11-22 14:58 ` Pali Rohár
2016-11-22 15:20 ` [ibm-acpi-devel] " Glenn Golden
2016-11-23 11:01 ` Jacek Anaszewski
2016-11-24 9:15 ` Pali Rohár
2016-11-24 9:21 ` Hans de Goede
2016-11-24 14:21 ` Jacek Anaszewski
2016-11-24 14:26 ` Pali Rohár
2016-11-24 15:32 ` Jacek Anaszewski
[not found] ` <50225a88-b928-c61b-bf6f-6c85fb6a9082-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2016-11-24 15:36 ` Pali Rohár
2016-11-24 16:21 ` Jacek Anaszewski
2016-11-24 16:51 ` Pali Rohár
2016-11-24 21:35 ` Jacek Anaszewski
[not found] ` <5238be1f-d669-07e6-c796-5bc0126cb456-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-11-24 21:45 ` Pali Rohár
2016-11-25 8:33 ` Jacek Anaszewski
2016-11-25 10:01 ` Pavel Machek
2016-11-25 10:25 ` Jacek Anaszewski
[not found] ` <e32e3d6c-5d6d-c882-21d9-8028c8311b0b-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2016-11-25 11:05 ` Pavel Machek
2016-11-25 11:19 ` Jacek Anaszewski
[not found] ` <2367b9a7-68f7-2038-0d3a-a9561055b4f6-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2016-11-25 14:49 ` Pavel Machek
2016-11-25 15:55 ` Jacek Anaszewski
2016-11-25 20:40 ` Pavel Machek
2016-11-25 22:28 ` Jacek Anaszewski
2016-12-21 18:49 ` Pavel Machek
2016-12-23 21:55 ` Jacek Anaszewski
2017-01-13 19:17 ` Darren Hart
2017-01-15 10:54 ` Hans de Goede
2017-01-15 12:25 ` Henrique de Moraes Holschuh
2017-01-15 15:05 ` Hans de Goede
2017-01-24 12:32 ` Pavel Machek
2017-01-24 22:56 ` Jacek Anaszewski
2017-01-25 13:12 ` Hans de Goede
2016-11-25 11:14 ` Hans de Goede
2016-11-25 11:26 ` Pali Rohár
2016-11-25 12:05 ` Pavel Machek
2016-11-25 15:46 ` Jacek Anaszewski
2016-12-01 14:08 ` Jacek Anaszewski
2016-11-25 9:56 ` Pavel Machek
2016-11-25 9:51 ` Pavel Machek
2016-11-21 11:41 ` Pavel Machek
2016-11-21 13:29 ` Jacek Anaszewski
2016-11-25 9:29 ` Pavel Machek
2016-11-21 8:35 ` Jacek Anaszewski
2016-11-21 9:31 ` Hans de Goede
2016-11-21 10:12 ` Pali Rohár
2016-11-21 10:16 ` Hans de Goede
2016-11-25 10:07 ` Pavel Machek
2016-11-17 22:24 ` [PATCH v5 3/6] leds: triggers: Add support for read-only triggers Hans de Goede
2016-11-18 8:52 ` Jacek Anaszewski
2016-11-18 9:04 ` Hans de Goede
2016-11-18 10:49 ` Jacek Anaszewski
2016-11-18 11:01 ` Hans de Goede
2016-11-17 22:24 ` [PATCH v5 4/6] platform: x86: thinkpad: Call led kbd_backlight trigger on kbd brightness change Hans de Goede
2016-11-17 22:24 ` [PATCH v5 5/6] platform: x86: dell-laptop: Set keyboard backlight led device default trigger Hans de Goede
2016-11-17 22:24 ` [PATCH v5 6/6] platform: x86: dell-wmi: Call led kbd_backlight trigger on kbd brightness change Hans de Goede
2016-11-20 14:59 ` [PATCH v5 1/6] leds: triggers: Add current_brightness trigger parameter Pali Rohár
2016-11-20 18:45 ` Hans de Goede
2016-11-20 19:40 ` Pali Rohár
2016-11-20 22:12 ` Pavel Machek
2016-11-20 23:07 ` Pali Rohár
2016-11-20 23:48 ` Pavel Machek
2016-11-21 10:02 ` Pali Rohár
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=20161117222441.31464-1-hdegoede@redhat.com \
--to=hdegoede@redhat.com \
--cc=dvhart@infradead.org \
--cc=ibm-acpi-devel@lists.sourceforge.net \
--cc=ibm-acpi@hmh.eng.br \
--cc=j.anaszewski@samsung.com \
--cc=linux-leds@vger.kernel.org \
--cc=mjg59@srcf.ucam.org \
--cc=pali.rohar@gmail.com \
--cc=platform-driver-x86@vger.kernel.org \
--cc=rpurdie@rpsys.net \
/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