hc
2024-05-10 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb
kernel/drivers/leds/trigger/ledtrig-timer.c
....@@ -1,13 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * LED Kernel Timer Trigger
34 *
45 * Copyright 2005-2006 Openedhand Ltd.
56 *
67 * Author: Richard Purdie <rpurdie@openedhand.com>
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License version 2 as
10
- * published by the Free Software Foundation.
118 */
129
1310 #include <linux/module.h>
....@@ -15,6 +12,7 @@
1512 #include <linux/init.h>
1613 #include <linux/device.h>
1714 #include <linux/ctype.h>
15
+#include <linux/slab.h>
1816 #include <linux/leds.h>
1917
2018 static ssize_t led_delay_on_show(struct device *dev,
....@@ -30,7 +28,7 @@
3028 {
3129 struct led_classdev *led_cdev = led_trigger_get_led(dev);
3230 unsigned long state;
33
- ssize_t ret = -EINVAL;
31
+ ssize_t ret;
3432
3533 ret = kstrtoul(buf, 10, &state);
3634 if (ret)
....@@ -55,7 +53,7 @@
5553 {
5654 struct led_classdev *led_cdev = led_trigger_get_led(dev);
5755 unsigned long state;
58
- ssize_t ret = -EINVAL;
56
+ ssize_t ret;
5957
6058 ret = kstrtoul(buf, 10, &state);
6159 if (ret)
....@@ -77,8 +75,46 @@
7775 };
7876 ATTRIBUTE_GROUPS(timer_trig);
7977
78
+static void pattern_init(struct led_classdev *led_cdev)
79
+{
80
+ u32 *pattern;
81
+ unsigned int size = 0;
82
+
83
+ pattern = led_get_default_pattern(led_cdev, &size);
84
+ if (!pattern)
85
+ return;
86
+
87
+ if (size != 2) {
88
+ dev_warn(led_cdev->dev,
89
+ "Expected 2 but got %u values for delays pattern\n",
90
+ size);
91
+ goto out;
92
+ }
93
+
94
+ led_cdev->blink_delay_on = pattern[0];
95
+ led_cdev->blink_delay_off = pattern[1];
96
+ /* led_blink_set() called by caller */
97
+
98
+out:
99
+ kfree(pattern);
100
+}
101
+
80102 static int timer_trig_activate(struct led_classdev *led_cdev)
81103 {
104
+ if (led_cdev->flags & LED_INIT_DEFAULT_TRIGGER) {
105
+ pattern_init(led_cdev);
106
+ /*
107
+ * Mark as initialized even on pattern_init() error because
108
+ * any consecutive call to it would produce the same error.
109
+ */
110
+ led_cdev->flags &= ~LED_INIT_DEFAULT_TRIGGER;
111
+ }
112
+
113
+ /*
114
+ * If "set brightness to 0" is pending in workqueue, we don't
115
+ * want that to be reordered after blink_set()
116
+ */
117
+ flush_work(&led_cdev->set_brightness_work);
82118 led_blink_set(led_cdev, &led_cdev->blink_delay_on,
83119 &led_cdev->blink_delay_off);
84120