summaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2018-07-02 16:05:28 -0400
committerJacek Anaszewski <jacek.anaszewski@gmail.com>2018-07-05 17:21:12 -0400
commit823f786ac7615f1bf822227fc4cbeafe11fb6bf8 (patch)
tree841ecfba04fc99788f2c1aecd7ab356eb4f503c1 /drivers/leds
parent2b7b6d44e29160eb12abd950c374babf21ed83d4 (diff)
leds: transient trigger: simplifications from core changes
The trigger core learned error handling for the activate callback and can handle device attributes now. This allows simplifying the driver considerably. Note that .deactivate() is only called when .activate() succeeded, so the check for .activated can go away. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Acked-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/trigger/ledtrig-transient.c98
1 files changed, 30 insertions, 68 deletions
diff --git a/drivers/leds/trigger/ledtrig-transient.c b/drivers/leds/trigger/ledtrig-transient.c
index a55fc58179a9..a80bb82aacc2 100644
--- a/drivers/leds/trigger/ledtrig-transient.c
+++ b/drivers/leds/trigger/ledtrig-transient.c
@@ -42,8 +42,8 @@ static void transient_timer_function(struct timer_list *t)
42static ssize_t transient_activate_show(struct device *dev, 42static ssize_t transient_activate_show(struct device *dev,
43 struct device_attribute *attr, char *buf) 43 struct device_attribute *attr, char *buf)
44{ 44{
45 struct led_classdev *led_cdev = dev_get_drvdata(dev); 45 struct transient_trig_data *transient_data =
46 struct transient_trig_data *transient_data = led_cdev->trigger_data; 46 led_trigger_get_drvdata(dev);
47 47
48 return sprintf(buf, "%d\n", transient_data->activate); 48 return sprintf(buf, "%d\n", transient_data->activate);
49} 49}
@@ -51,8 +51,9 @@ static ssize_t transient_activate_show(struct device *dev,
51static ssize_t transient_activate_store(struct device *dev, 51static ssize_t transient_activate_store(struct device *dev,
52 struct device_attribute *attr, const char *buf, size_t size) 52 struct device_attribute *attr, const char *buf, size_t size)
53{ 53{
54 struct led_classdev *led_cdev = dev_get_drvdata(dev); 54 struct led_classdev *led_cdev = led_trigger_get_led(dev);
55 struct transient_trig_data *transient_data = led_cdev->trigger_data; 55 struct transient_trig_data *transient_data =
56 led_trigger_get_drvdata(dev);
56 unsigned long state; 57 unsigned long state;
57 ssize_t ret; 58 ssize_t ret;
58 59
@@ -94,8 +95,7 @@ static ssize_t transient_activate_store(struct device *dev,
94static ssize_t transient_duration_show(struct device *dev, 95static ssize_t transient_duration_show(struct device *dev,
95 struct device_attribute *attr, char *buf) 96 struct device_attribute *attr, char *buf)
96{ 97{
97 struct led_classdev *led_cdev = dev_get_drvdata(dev); 98 struct transient_trig_data *transient_data = led_trigger_get_drvdata(dev);
98 struct transient_trig_data *transient_data = led_cdev->trigger_data;
99 99
100 return sprintf(buf, "%lu\n", transient_data->duration); 100 return sprintf(buf, "%lu\n", transient_data->duration);
101} 101}
@@ -103,8 +103,8 @@ static ssize_t transient_duration_show(struct device *dev,
103static ssize_t transient_duration_store(struct device *dev, 103static ssize_t transient_duration_store(struct device *dev,
104 struct device_attribute *attr, const char *buf, size_t size) 104 struct device_attribute *attr, const char *buf, size_t size)
105{ 105{
106 struct led_classdev *led_cdev = dev_get_drvdata(dev); 106 struct transient_trig_data *transient_data =
107 struct transient_trig_data *transient_data = led_cdev->trigger_data; 107 led_trigger_get_drvdata(dev);
108 unsigned long state; 108 unsigned long state;
109 ssize_t ret; 109 ssize_t ret;
110 110
@@ -119,8 +119,8 @@ static ssize_t transient_duration_store(struct device *dev,
119static ssize_t transient_state_show(struct device *dev, 119static ssize_t transient_state_show(struct device *dev,
120 struct device_attribute *attr, char *buf) 120 struct device_attribute *attr, char *buf)
121{ 121{
122 struct led_classdev *led_cdev = dev_get_drvdata(dev); 122 struct transient_trig_data *transient_data =
123 struct transient_trig_data *transient_data = led_cdev->trigger_data; 123 led_trigger_get_drvdata(dev);
124 int state; 124 int state;
125 125
126 state = (transient_data->state == LED_FULL) ? 1 : 0; 126 state = (transient_data->state == LED_FULL) ? 1 : 0;
@@ -130,8 +130,8 @@ static ssize_t transient_state_show(struct device *dev,
130static ssize_t transient_state_store(struct device *dev, 130static ssize_t transient_state_store(struct device *dev,
131 struct device_attribute *attr, const char *buf, size_t size) 131 struct device_attribute *attr, const char *buf, size_t size)
132{ 132{
133 struct led_classdev *led_cdev = dev_get_drvdata(dev); 133 struct transient_trig_data *transient_data =
134 struct transient_trig_data *transient_data = led_cdev->trigger_data; 134 led_trigger_get_drvdata(dev);
135 unsigned long state; 135 unsigned long state;
136 ssize_t ret; 136 ssize_t ret;
137 137
@@ -152,84 +152,46 @@ static DEVICE_ATTR(duration, 0644, transient_duration_show,
152 transient_duration_store); 152 transient_duration_store);
153static DEVICE_ATTR(state, 0644, transient_state_show, transient_state_store); 153static DEVICE_ATTR(state, 0644, transient_state_show, transient_state_store);
154 154
155static struct attribute *transient_trig_attrs[] = {
156 &dev_attr_activate.attr,
157 &dev_attr_duration.attr,
158 &dev_attr_state.attr,
159 NULL
160};
161ATTRIBUTE_GROUPS(transient_trig);
162
155static int transient_trig_activate(struct led_classdev *led_cdev) 163static int transient_trig_activate(struct led_classdev *led_cdev)
156{ 164{
157 int rc;
158 struct transient_trig_data *tdata; 165 struct transient_trig_data *tdata;
159 166
160 tdata = kzalloc(sizeof(struct transient_trig_data), GFP_KERNEL); 167 tdata = kzalloc(sizeof(struct transient_trig_data), GFP_KERNEL);
161 if (!tdata) { 168 if (!tdata)
162 dev_err(led_cdev->dev, 169 return -ENOMEM;
163 "unable to allocate transient trigger\n");
164 return 0;
165 }
166 led_cdev->trigger_data = tdata;
167 tdata->led_cdev = led_cdev;
168
169 rc = device_create_file(led_cdev->dev, &dev_attr_activate);
170 if (rc)
171 goto err_out;
172 170
173 rc = device_create_file(led_cdev->dev, &dev_attr_duration); 171 led_set_trigger_data(led_cdev, tdata);
174 if (rc) 172 tdata->led_cdev = led_cdev;
175 goto err_out_duration;
176
177 rc = device_create_file(led_cdev->dev, &dev_attr_state);
178 if (rc)
179 goto err_out_state;
180 173
181 timer_setup(&tdata->timer, transient_timer_function, 0); 174 timer_setup(&tdata->timer, transient_timer_function, 0);
182 led_cdev->activated = true;
183
184 return 0;
185
186err_out_state:
187 device_remove_file(led_cdev->dev, &dev_attr_duration);
188err_out_duration:
189 device_remove_file(led_cdev->dev, &dev_attr_activate);
190err_out:
191 dev_err(led_cdev->dev, "unable to register transient trigger\n");
192 led_cdev->trigger_data = NULL;
193 kfree(tdata);
194 175
195 return 0; 176 return 0;
196} 177}
197 178
198static void transient_trig_deactivate(struct led_classdev *led_cdev) 179static void transient_trig_deactivate(struct led_classdev *led_cdev)
199{ 180{
200 struct transient_trig_data *transient_data = led_cdev->trigger_data; 181 struct transient_trig_data *transient_data = led_get_trigger_data(led_cdev);
201 182
202 if (led_cdev->activated) { 183 del_timer_sync(&transient_data->timer);
203 del_timer_sync(&transient_data->timer); 184 led_set_brightness_nosleep(led_cdev, transient_data->restore_state);
204 led_set_brightness_nosleep(led_cdev, 185 kfree(transient_data);
205 transient_data->restore_state);
206 device_remove_file(led_cdev->dev, &dev_attr_activate);
207 device_remove_file(led_cdev->dev, &dev_attr_duration);
208 device_remove_file(led_cdev->dev, &dev_attr_state);
209 led_cdev->trigger_data = NULL;
210 led_cdev->activated = false;
211 kfree(transient_data);
212 }
213} 186}
214 187
215static struct led_trigger transient_trigger = { 188static struct led_trigger transient_trigger = {
216 .name = "transient", 189 .name = "transient",
217 .activate = transient_trig_activate, 190 .activate = transient_trig_activate,
218 .deactivate = transient_trig_deactivate, 191 .deactivate = transient_trig_deactivate,
192 .groups = transient_trig_groups,
219}; 193};
220 194module_led_trigger(transient_trigger);
221static int __init transient_trig_init(void)
222{
223 return led_trigger_register(&transient_trigger);
224}
225
226static void __exit transient_trig_exit(void)
227{
228 led_trigger_unregister(&transient_trigger);
229}
230
231module_init(transient_trig_init);
232module_exit(transient_trig_exit);
233 195
234MODULE_AUTHOR("Shuah Khan <shuahkhan@gmail.com>"); 196MODULE_AUTHOR("Shuah Khan <shuahkhan@gmail.com>");
235MODULE_DESCRIPTION("Transient LED trigger"); 197MODULE_DESCRIPTION("Transient LED trigger");