|
38 | 38 | * tx - LED blinks on transmitted data
|
39 | 39 | * rx - LED blinks on receive data
|
40 | 40 | *
|
| 41 | + * Note: If the user selects a mode that is not supported by hw, default |
| 42 | + * behavior is to fall back to software control of the LED. However not every |
| 43 | + * hw supports software control. LED callbacks brightness_set() and |
| 44 | + * brightness_set_blocking() are NULL in this case. hw_control_is_supported() |
| 45 | + * should use available means supported by hw to inform the user that selected |
| 46 | + * mode isn't supported by hw. This could be switching off the LED or any |
| 47 | + * hw blink mode. If software control fallback isn't possible, we return |
| 48 | + * -EOPNOTSUPP to the user, but still store the selected mode. This is needed |
| 49 | + * in case an intermediate unsupported mode is necessary to switch from one |
| 50 | + * supported mode to another. |
41 | 51 | */
|
42 | 52 |
|
43 | 53 | struct led_netdev_data {
|
@@ -318,6 +328,7 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
|
318 | 328 | size_t size, enum led_trigger_netdev_modes attr)
|
319 | 329 | {
|
320 | 330 | struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
|
| 331 | + struct led_classdev *led_cdev = trigger_data->led_cdev; |
321 | 332 | unsigned long state, mode = trigger_data->mode;
|
322 | 333 | int ret;
|
323 | 334 | int bit;
|
@@ -363,6 +374,10 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
|
363 | 374 | trigger_data->mode = mode;
|
364 | 375 | trigger_data->hw_control = can_hw_control(trigger_data);
|
365 | 376 |
|
| 377 | + if (!led_cdev->brightness_set && !led_cdev->brightness_set_blocking && |
| 378 | + !trigger_data->hw_control) |
| 379 | + return -EOPNOTSUPP; |
| 380 | + |
366 | 381 | set_baseline_state(trigger_data);
|
367 | 382 |
|
368 | 383 | return size;
|
|
0 commit comments