Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

leds: triggers: let struct led_trigger::activate() return an error code

Given that activating a trigger can fail, let the callback return an
indication. This prevents to have a trigger active according to the
"trigger" sysfs attribute but not functional.

All users are changed accordingly to return 0 for now. There is no intended
change in behaviour.

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>

authored by

Uwe Kleine-König and committed by
Jacek Anaszewski
2282e125 033692eb

+101 -45
+21 -3
drivers/leds/led-triggers.c
··· 103 103 EXPORT_SYMBOL_GPL(led_trigger_show); 104 104 105 105 /* Caller must ensure led_cdev->trigger_lock held */ 106 - void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) 106 + int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) 107 107 { 108 108 unsigned long flags; 109 109 char *event = NULL; 110 110 char *envp[2]; 111 111 const char *name; 112 + int ret; 112 113 113 114 if (!led_cdev->trigger && !trig) 114 - return; 115 + return 0; 115 116 116 117 name = trig ? trig->name : "none"; 117 118 event = kasprintf(GFP_KERNEL, "TRIGGER=%s", name); ··· 135 134 list_add_tail(&led_cdev->trig_list, &trig->led_cdevs); 136 135 write_unlock_irqrestore(&trig->leddev_list_lock, flags); 137 136 led_cdev->trigger = trig; 137 + 138 138 if (trig->activate) 139 - trig->activate(led_cdev); 139 + ret = trig->activate(led_cdev); 140 + else 141 + ret = 0; 142 + 143 + if (ret) 144 + goto err_activate; 140 145 } 141 146 142 147 if (event) { ··· 153 146 "%s: Error sending uevent\n", __func__); 154 147 kfree(event); 155 148 } 149 + 150 + return 0; 151 + 152 + err_activate: 153 + led_cdev->trigger = NULL; 154 + write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags); 155 + list_del(&led_cdev->trig_list); 156 + write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, flags); 157 + led_set_brightness(led_cdev, LED_OFF); 158 + 159 + return ret; 156 160 } 157 161 EXPORT_SYMBOL_GPL(led_trigger_set); 158 162
+5 -3
drivers/leds/trigger/ledtrig-activity.c
··· 178 178 179 179 static DEVICE_ATTR(invert, 0644, led_invert_show, led_invert_store); 180 180 181 - static void activity_activate(struct led_classdev *led_cdev) 181 + static int activity_activate(struct led_classdev *led_cdev) 182 182 { 183 183 struct activity_data *activity_data; 184 184 int rc; 185 185 186 186 activity_data = kzalloc(sizeof(*activity_data), GFP_KERNEL); 187 187 if (!activity_data) 188 - return; 188 + return 0; 189 189 190 190 led_cdev->trigger_data = activity_data; 191 191 rc = device_create_file(led_cdev->dev, &dev_attr_invert); 192 192 if (rc) { 193 193 kfree(led_cdev->trigger_data); 194 - return; 194 + return 0; 195 195 } 196 196 197 197 activity_data->led_cdev = led_cdev; ··· 201 201 led_activity_function(&activity_data->timer); 202 202 set_bit(LED_BLINK_SW, &led_cdev->work_flags); 203 203 led_cdev->activated = true; 204 + 205 + return 0; 204 206 } 205 207 206 208 static void activity_deactivate(struct led_classdev *led_cdev)
+5 -3
drivers/leds/trigger/ledtrig-backlight.c
··· 97 97 } 98 98 static DEVICE_ATTR(inverted, 0644, bl_trig_invert_show, bl_trig_invert_store); 99 99 100 - static void bl_trig_activate(struct led_classdev *led) 100 + static int bl_trig_activate(struct led_classdev *led) 101 101 { 102 102 int ret; 103 103 ··· 107 107 led->trigger_data = n; 108 108 if (!n) { 109 109 dev_err(led->dev, "unable to allocate backlight trigger\n"); 110 - return; 110 + return 0; 111 111 } 112 112 113 113 ret = device_create_file(led->dev, &dev_attr_inverted); ··· 124 124 dev_err(led->dev, "unable to register backlight trigger\n"); 125 125 led->activated = true; 126 126 127 - return; 127 + return 0; 128 128 129 129 err_invert: 130 130 led->trigger_data = NULL; 131 131 kfree(n); 132 + 133 + return 0; 132 134 } 133 135 134 136 static void bl_trig_deactivate(struct led_classdev *led)
+2 -1
drivers/leds/trigger/ledtrig-default-on.c
··· 16 16 #include <linux/leds.h> 17 17 #include "../leds.h" 18 18 19 - static void defon_trig_activate(struct led_classdev *led_cdev) 19 + static int defon_trig_activate(struct led_classdev *led_cdev) 20 20 { 21 21 led_set_brightness_nosleep(led_cdev, led_cdev->max_brightness); 22 + return 0; 22 23 } 23 24 24 25 static struct led_trigger defon_led_trigger = {
+5 -3
drivers/leds/trigger/ledtrig-gpio.c
··· 162 162 } 163 163 static DEVICE_ATTR(gpio, 0644, gpio_trig_gpio_show, gpio_trig_gpio_store); 164 164 165 - static void gpio_trig_activate(struct led_classdev *led) 165 + static int gpio_trig_activate(struct led_classdev *led) 166 166 { 167 167 struct gpio_trig_data *gpio_data; 168 168 int ret; 169 169 170 170 gpio_data = kzalloc(sizeof(*gpio_data), GFP_KERNEL); 171 171 if (!gpio_data) 172 - return; 172 + return 0; 173 173 174 174 ret = device_create_file(led->dev, &dev_attr_gpio); 175 175 if (ret) ··· 187 187 led->trigger_data = gpio_data; 188 188 led->activated = true; 189 189 190 - return; 190 + return 0; 191 191 192 192 err_brightness: 193 193 device_remove_file(led->dev, &dev_attr_inverted); ··· 197 197 198 198 err_gpio: 199 199 kfree(gpio_data); 200 + 201 + return 0; 200 202 } 201 203 202 204 static void gpio_trig_deactivate(struct led_classdev *led)
+5 -3
drivers/leds/trigger/ledtrig-heartbeat.c
··· 121 121 122 122 static DEVICE_ATTR(invert, 0644, led_invert_show, led_invert_store); 123 123 124 - static void heartbeat_trig_activate(struct led_classdev *led_cdev) 124 + static int heartbeat_trig_activate(struct led_classdev *led_cdev) 125 125 { 126 126 struct heartbeat_trig_data *heartbeat_data; 127 127 int rc; 128 128 129 129 heartbeat_data = kzalloc(sizeof(*heartbeat_data), GFP_KERNEL); 130 130 if (!heartbeat_data) 131 - return; 131 + return 0; 132 132 133 133 led_cdev->trigger_data = heartbeat_data; 134 134 heartbeat_data->led_cdev = led_cdev; 135 135 rc = device_create_file(led_cdev->dev, &dev_attr_invert); 136 136 if (rc) { 137 137 kfree(led_cdev->trigger_data); 138 - return; 138 + return 0; 139 139 } 140 140 141 141 timer_setup(&heartbeat_data->timer, led_heartbeat_function, 0); ··· 145 145 led_heartbeat_function(&heartbeat_data->timer); 146 146 set_bit(LED_BLINK_SW, &led_cdev->work_flags); 147 147 led_cdev->activated = true; 148 + 149 + return 0; 148 150 } 149 151 150 152 static void heartbeat_trig_deactivate(struct led_classdev *led_cdev)
+5 -3
drivers/leds/trigger/ledtrig-netdev.c
··· 388 388 (atomic_read(&trigger_data->interval)*2)); 389 389 } 390 390 391 - static void netdev_trig_activate(struct led_classdev *led_cdev) 391 + static int netdev_trig_activate(struct led_classdev *led_cdev) 392 392 { 393 393 struct led_netdev_data *trigger_data; 394 394 int rc; 395 395 396 396 trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL); 397 397 if (!trigger_data) 398 - return; 398 + return 0; 399 399 400 400 spin_lock_init(&trigger_data->lock); 401 401 ··· 432 432 rc = register_netdevice_notifier(&trigger_data->notifier); 433 433 if (rc) 434 434 goto err_out_interval; 435 - return; 435 + return 0; 436 436 437 437 err_out_interval: 438 438 device_remove_file(led_cdev->dev, &dev_attr_interval); ··· 447 447 err_out: 448 448 led_cdev->trigger_data = NULL; 449 449 kfree(trigger_data); 450 + 451 + return 0; 450 452 } 451 453 452 454 static void netdev_trig_deactivate(struct led_classdev *led_cdev)
+5 -3
drivers/leds/trigger/ledtrig-oneshot.c
··· 122 122 static DEVICE_ATTR(invert, 0644, led_invert_show, led_invert_store); 123 123 static DEVICE_ATTR(shot, 0200, NULL, led_shot); 124 124 125 - static void oneshot_trig_activate(struct led_classdev *led_cdev) 125 + static int oneshot_trig_activate(struct led_classdev *led_cdev) 126 126 { 127 127 struct oneshot_trig_data *oneshot_data; 128 128 int rc; 129 129 130 130 oneshot_data = kzalloc(sizeof(*oneshot_data), GFP_KERNEL); 131 131 if (!oneshot_data) 132 - return; 132 + return 0; 133 133 134 134 led_cdev->trigger_data = oneshot_data; 135 135 ··· 151 151 152 152 led_cdev->activated = true; 153 153 154 - return; 154 + return 0; 155 155 156 156 err_out_invert: 157 157 device_remove_file(led_cdev->dev, &dev_attr_invert); ··· 161 161 device_remove_file(led_cdev->dev, &dev_attr_delay_on); 162 162 err_out_trig_data: 163 163 kfree(led_cdev->trigger_data); 164 + 165 + return 0; 164 166 } 165 167 166 168 static void oneshot_trig_deactivate(struct led_classdev *led_cdev)
+5 -3
drivers/leds/trigger/ledtrig-timer.c
··· 70 70 static DEVICE_ATTR(delay_on, 0644, led_delay_on_show, led_delay_on_store); 71 71 static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store); 72 72 73 - static void timer_trig_activate(struct led_classdev *led_cdev) 73 + static int timer_trig_activate(struct led_classdev *led_cdev) 74 74 { 75 75 int rc; 76 76 ··· 78 78 79 79 rc = device_create_file(led_cdev->dev, &dev_attr_delay_on); 80 80 if (rc) 81 - return; 81 + return 0; 82 82 rc = device_create_file(led_cdev->dev, &dev_attr_delay_off); 83 83 if (rc) 84 84 goto err_out_delayon; ··· 87 87 &led_cdev->blink_delay_off); 88 88 led_cdev->activated = true; 89 89 90 - return; 90 + return 0; 91 91 92 92 err_out_delayon: 93 93 device_remove_file(led_cdev->dev, &dev_attr_delay_on); 94 + 95 + return 0; 94 96 } 95 97 96 98 static void timer_trig_deactivate(struct led_classdev *led_cdev)
+5 -3
drivers/leds/trigger/ledtrig-transient.c
··· 152 152 transient_duration_store); 153 153 static DEVICE_ATTR(state, 0644, transient_state_show, transient_state_store); 154 154 155 - static void transient_trig_activate(struct led_classdev *led_cdev) 155 + static int transient_trig_activate(struct led_classdev *led_cdev) 156 156 { 157 157 int rc; 158 158 struct transient_trig_data *tdata; ··· 161 161 if (!tdata) { 162 162 dev_err(led_cdev->dev, 163 163 "unable to allocate transient trigger\n"); 164 - return; 164 + return 0; 165 165 } 166 166 led_cdev->trigger_data = tdata; 167 167 tdata->led_cdev = led_cdev; ··· 181 181 timer_setup(&tdata->timer, transient_timer_function, 0); 182 182 led_cdev->activated = true; 183 183 184 - return; 184 + return 0; 185 185 186 186 err_out_state: 187 187 device_remove_file(led_cdev->dev, &dev_attr_duration); ··· 191 191 dev_err(led_cdev->dev, "unable to register transient trigger\n"); 192 192 led_cdev->trigger_data = NULL; 193 193 kfree(tdata); 194 + 195 + return 0; 194 196 } 195 197 196 198 static void transient_trig_deactivate(struct led_classdev *led_cdev)
+3 -1
drivers/tty/vt/keyboard.c
··· 959 959 unsigned int mask; 960 960 }; 961 961 962 - static void kbd_led_trigger_activate(struct led_classdev *cdev) 962 + static int kbd_led_trigger_activate(struct led_classdev *cdev) 963 963 { 964 964 struct kbd_led_trigger *trigger = 965 965 container_of(cdev->trigger, struct kbd_led_trigger, trigger); ··· 970 970 ledstate & trigger->mask ? 971 971 LED_FULL : LED_OFF); 972 972 tasklet_enable(&keyboard_tasklet); 973 + 974 + return 0; 973 975 } 974 976 975 977 #define KBD_LED_TRIGGER(_led_bit, _name) { \
+4 -3
drivers/usb/core/ledtrig-usbport.c
··· 298 298 return NOTIFY_DONE; 299 299 } 300 300 301 - static void usbport_trig_activate(struct led_classdev *led_cdev) 301 + static int usbport_trig_activate(struct led_classdev *led_cdev) 302 302 { 303 303 struct usbport_trig_data *usbport_data; 304 304 int err; 305 305 306 306 usbport_data = kzalloc(sizeof(*usbport_data), GFP_KERNEL); 307 307 if (!usbport_data) 308 - return; 308 + return 0; 309 309 usbport_data->led_cdev = led_cdev; 310 310 311 311 /* List of ports */ ··· 322 322 usb_register_notify(&usbport_data->nb); 323 323 324 324 led_cdev->activated = true; 325 - return; 325 + return 0; 326 326 327 327 err_free: 328 328 kfree(usbport_data); 329 + return 0; 329 330 } 330 331 331 332 static void usbport_trig_deactivate(struct led_classdev *led_cdev)
+9 -5
include/linux/leds.h
··· 253 253 struct led_trigger { 254 254 /* Trigger Properties */ 255 255 const char *name; 256 - void (*activate)(struct led_classdev *led_cdev); 256 + int (*activate)(struct led_classdev *led_cdev); 257 257 void (*deactivate)(struct led_classdev *led_cdev); 258 258 259 259 /* LEDs under control by this trigger (for simple triggers) */ ··· 288 288 unsigned long *delay_off, 289 289 int invert); 290 290 extern void led_trigger_set_default(struct led_classdev *led_cdev); 291 - extern void led_trigger_set(struct led_classdev *led_cdev, 292 - struct led_trigger *trigger); 291 + extern int led_trigger_set(struct led_classdev *led_cdev, 292 + struct led_trigger *trigger); 293 293 extern void led_trigger_remove(struct led_classdev *led_cdev); 294 294 295 295 static inline void *led_get_trigger_data(struct led_classdev *led_cdev) ··· 334 334 unsigned long *delay_off, 335 335 int invert) {} 336 336 static inline void led_trigger_set_default(struct led_classdev *led_cdev) {} 337 - static inline void led_trigger_set(struct led_classdev *led_cdev, 338 - struct led_trigger *trigger) {} 337 + static inline int led_trigger_set(struct led_classdev *led_cdev, 338 + struct led_trigger *trigger) 339 + { 340 + return 0; 341 + } 342 + 339 343 static inline void led_trigger_remove(struct led_classdev *led_cdev) {} 340 344 static inline void *led_get_trigger_data(struct led_classdev *led_cdev) 341 345 {
+4 -2
net/bluetooth/leds.c
··· 43 43 led_trigger_event(bt_power_led_trigger, enabled ? LED_FULL : LED_OFF); 44 44 } 45 45 46 - static void power_activate(struct led_classdev *led_cdev) 46 + static int power_activate(struct led_classdev *led_cdev) 47 47 { 48 48 struct hci_basic_led_trigger *htrig; 49 49 bool powered; ··· 52 52 powered = test_bit(HCI_UP, &htrig->hdev->flags); 53 53 54 54 led_trigger_event(led_cdev->trigger, powered ? LED_FULL : LED_OFF); 55 + 56 + return 0; 55 57 } 56 58 57 59 static struct led_trigger *led_allocate_basic(struct hci_dev *hdev, 58 - void (*activate)(struct led_classdev *led_cdev), 60 + int (*activate)(struct led_classdev *led_cdev), 59 61 const char *name) 60 62 { 61 63 struct hci_basic_led_trigger *htrig;
+15 -5
net/mac80211/led.c
··· 52 52 kfree(local->radio_led.name); 53 53 } 54 54 55 - static void ieee80211_tx_led_activate(struct led_classdev *led_cdev) 55 + static int ieee80211_tx_led_activate(struct led_classdev *led_cdev) 56 56 { 57 57 struct ieee80211_local *local = container_of(led_cdev->trigger, 58 58 struct ieee80211_local, 59 59 tx_led); 60 60 61 61 atomic_inc(&local->tx_led_active); 62 + 63 + return 0; 62 64 } 63 65 64 66 static void ieee80211_tx_led_deactivate(struct led_classdev *led_cdev) ··· 72 70 atomic_dec(&local->tx_led_active); 73 71 } 74 72 75 - static void ieee80211_rx_led_activate(struct led_classdev *led_cdev) 73 + static int ieee80211_rx_led_activate(struct led_classdev *led_cdev) 76 74 { 77 75 struct ieee80211_local *local = container_of(led_cdev->trigger, 78 76 struct ieee80211_local, 79 77 rx_led); 80 78 81 79 atomic_inc(&local->rx_led_active); 80 + 81 + return 0; 82 82 } 83 83 84 84 static void ieee80211_rx_led_deactivate(struct led_classdev *led_cdev) ··· 92 88 atomic_dec(&local->rx_led_active); 93 89 } 94 90 95 - static void ieee80211_assoc_led_activate(struct led_classdev *led_cdev) 91 + static int ieee80211_assoc_led_activate(struct led_classdev *led_cdev) 96 92 { 97 93 struct ieee80211_local *local = container_of(led_cdev->trigger, 98 94 struct ieee80211_local, 99 95 assoc_led); 100 96 101 97 atomic_inc(&local->assoc_led_active); 98 + 99 + return 0; 102 100 } 103 101 104 102 static void ieee80211_assoc_led_deactivate(struct led_classdev *led_cdev) ··· 112 106 atomic_dec(&local->assoc_led_active); 113 107 } 114 108 115 - static void ieee80211_radio_led_activate(struct led_classdev *led_cdev) 109 + static int ieee80211_radio_led_activate(struct led_classdev *led_cdev) 116 110 { 117 111 struct ieee80211_local *local = container_of(led_cdev->trigger, 118 112 struct ieee80211_local, 119 113 radio_led); 120 114 121 115 atomic_inc(&local->radio_led_active); 116 + 117 + return 0; 122 118 } 123 119 124 120 static void ieee80211_radio_led_deactivate(struct led_classdev *led_cdev) ··· 132 124 atomic_dec(&local->radio_led_active); 133 125 } 134 126 135 - static void ieee80211_tpt_led_activate(struct led_classdev *led_cdev) 127 + static int ieee80211_tpt_led_activate(struct led_classdev *led_cdev) 136 128 { 137 129 struct ieee80211_local *local = container_of(led_cdev->trigger, 138 130 struct ieee80211_local, 139 131 tpt_led); 140 132 141 133 atomic_inc(&local->tpt_led_active); 134 + 135 + return 0; 142 136 } 143 137 144 138 static void ieee80211_tpt_led_deactivate(struct led_classdev *led_cdev)
+3 -1
net/rfkill/core.c
··· 141 141 led_trigger_event(trigger, LED_FULL); 142 142 } 143 143 144 - static void rfkill_led_trigger_activate(struct led_classdev *led) 144 + static int rfkill_led_trigger_activate(struct led_classdev *led) 145 145 { 146 146 struct rfkill *rfkill; 147 147 148 148 rfkill = container_of(led->trigger, struct rfkill, led_trigger); 149 149 150 150 rfkill_led_trigger_event(rfkill); 151 + 152 + return 0; 151 153 } 152 154 153 155 const char *rfkill_get_led_trigger_name(struct rfkill *rfkill)