Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7af9a170 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull LED fixes from Jacek Anaszewski:

 - Fix brightness setting upon hardware blinking enabled

 - Handle suspend/resume in heartbeat trigger

* tag 'for-4.7-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds:
  leds: handle suspend/resume in heartbeat trigger
  leds: core: Fix brightness setting upon hardware blinking enabled
parents bb967271 5ab92a7c
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -74,8 +74,8 @@ blink_set() function (see <linux/leds.h>). To set an LED to blinking,
however, it is better to use the API function led_blink_set(), as it
will check and implement software fallback if necessary.

To turn off blinking again, use the API function led_brightness_set()
as that will not just set the LED brightness but also stop any software
To turn off blinking, use the API function led_brightness_set()
with brightness value LED_OFF, which should stop any software
timers that may have been required for blinking.

The blink_set() function should choose a user friendly blinking value
+6 −3
Original line number Diff line number Diff line
@@ -53,11 +53,12 @@ static void led_timer_function(unsigned long data)

	if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) {
		led_set_brightness_nosleep(led_cdev, LED_OFF);
		led_cdev->flags &= ~LED_BLINK_SW;
		return;
	}

	if (led_cdev->flags & LED_BLINK_ONESHOT_STOP) {
		led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
		led_cdev->flags &=  ~(LED_BLINK_ONESHOT_STOP | LED_BLINK_SW);
		return;
	}

@@ -151,6 +152,7 @@ static void led_set_software_blink(struct led_classdev *led_cdev,
		return;
	}

	led_cdev->flags |= LED_BLINK_SW;
	mod_timer(&led_cdev->blink_timer, jiffies + 1);
}

@@ -219,6 +221,7 @@ void led_stop_software_blink(struct led_classdev *led_cdev)
	del_timer_sync(&led_cdev->blink_timer);
	led_cdev->blink_delay_on = 0;
	led_cdev->blink_delay_off = 0;
	led_cdev->flags &= ~LED_BLINK_SW;
}
EXPORT_SYMBOL_GPL(led_stop_software_blink);

@@ -226,10 +229,10 @@ void led_set_brightness(struct led_classdev *led_cdev,
			enum led_brightness brightness)
{
	/*
	 * In case blinking is on delay brightness setting
	 * If software blink is active, delay brightness setting
	 * until the next timer tick.
	 */
	if (led_cdev->blink_delay_on || led_cdev->blink_delay_off) {
	if (led_cdev->flags & LED_BLINK_SW) {
		/*
		 * If we need to disable soft blinking delegate this to the
		 * work queue task to avoid problems in case we are called
+31 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <linux/sched.h>
#include <linux/leds.h>
#include <linux/reboot.h>
#include <linux/suspend.h>
#include "../leds.h"

static int panic_heartbeats;
@@ -154,6 +155,30 @@ static struct led_trigger heartbeat_led_trigger = {
	.deactivate = heartbeat_trig_deactivate,
};

static int heartbeat_pm_notifier(struct notifier_block *nb,
				 unsigned long pm_event, void *unused)
{
	int rc;

	switch (pm_event) {
	case PM_SUSPEND_PREPARE:
	case PM_HIBERNATION_PREPARE:
	case PM_RESTORE_PREPARE:
		led_trigger_unregister(&heartbeat_led_trigger);
		break;
	case PM_POST_SUSPEND:
	case PM_POST_HIBERNATION:
	case PM_POST_RESTORE:
		rc = led_trigger_register(&heartbeat_led_trigger);
		if (rc)
			pr_err("could not re-register heartbeat trigger\n");
		break;
	default:
		break;
	}
	return NOTIFY_DONE;
}

static int heartbeat_reboot_notifier(struct notifier_block *nb,
				     unsigned long code, void *unused)
{
@@ -168,6 +193,10 @@ static int heartbeat_panic_notifier(struct notifier_block *nb,
	return NOTIFY_DONE;
}

static struct notifier_block heartbeat_pm_nb = {
	.notifier_call = heartbeat_pm_notifier,
};

static struct notifier_block heartbeat_reboot_nb = {
	.notifier_call = heartbeat_reboot_notifier,
};
@@ -184,12 +213,14 @@ static int __init heartbeat_trig_init(void)
		atomic_notifier_chain_register(&panic_notifier_list,
					       &heartbeat_panic_nb);
		register_reboot_notifier(&heartbeat_reboot_nb);
		register_pm_notifier(&heartbeat_pm_nb);
	}
	return rc;
}

static void __exit heartbeat_trig_exit(void)
{
	unregister_pm_notifier(&heartbeat_pm_nb);
	unregister_reboot_notifier(&heartbeat_reboot_nb);
	atomic_notifier_chain_unregister(&panic_notifier_list,
					 &heartbeat_panic_nb);
+12 −11
Original line number Diff line number Diff line
@@ -42,15 +42,16 @@ struct led_classdev {
#define LED_UNREGISTERING	(1 << 1)
	/* Upper 16 bits reflect control information */
#define LED_CORE_SUSPENDRESUME	(1 << 16)
#define LED_BLINK_ONESHOT	(1 << 17)
#define LED_BLINK_ONESHOT_STOP	(1 << 18)
#define LED_BLINK_INVERT	(1 << 19)
#define LED_BLINK_BRIGHTNESS_CHANGE (1 << 20)
#define LED_BLINK_DISABLE	(1 << 21)
#define LED_SYSFS_DISABLE	(1 << 22)
#define LED_DEV_CAP_FLASH	(1 << 23)
#define LED_HW_PLUGGABLE	(1 << 24)
#define LED_PANIC_INDICATOR	(1 << 25)
#define LED_BLINK_SW		(1 << 17)
#define LED_BLINK_ONESHOT	(1 << 18)
#define LED_BLINK_ONESHOT_STOP	(1 << 19)
#define LED_BLINK_INVERT	(1 << 20)
#define LED_BLINK_BRIGHTNESS_CHANGE (1 << 21)
#define LED_BLINK_DISABLE	(1 << 22)
#define LED_SYSFS_DISABLE	(1 << 23)
#define LED_DEV_CAP_FLASH	(1 << 24)
#define LED_HW_PLUGGABLE	(1 << 25)
#define LED_PANIC_INDICATOR	(1 << 26)

	/* Set LED brightness level
	 * Must not sleep. Use brightness_set_blocking for drivers
@@ -72,8 +73,8 @@ struct led_classdev {
	 * and if both are zero then a sensible default should be chosen.
	 * The call should adjust the timings in that case and if it can't
	 * match the values specified exactly.
	 * Deactivate blinking again when the brightness is set to a fixed
	 * value via the brightness_set() callback.
	 * Deactivate blinking again when the brightness is set to LED_OFF
	 * via the brightness_set() callback.
	 */
	int		(*blink_set)(struct led_classdev *led_cdev,
				     unsigned long *delay_on,