Skip to content

Commit 4289e43

Browse files
hkallweitlag-linaro
authored andcommitted
leds: trigger: netdev: Add core support for hw not supporting fallback to LED sw control
If hw doesn't support sw control of the LED and we switch to a mode not supported by hw, currently we get lots of errors because neither brigthness_set() nor brithness_set_blocking() is set. Deal with this by not falling back to sw control, and return -EOPNOTSUPP to the user. Note that we still store the new mode. This is needed in case an intermediate unsupported mode is necessary to switch from one supported mode to another. Add a comment explaining how a driver for such hw is supposed to behave. Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Link: https://lore.kernel.org/r/3fd5184c-3641-4b0b-b59a-f489ec69a6cd@gmail.com Signed-off-by: Lee Jones <lee@kernel.org>
1 parent afacb21 commit 4289e43

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

drivers/leds/trigger/ledtrig-netdev.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@
3838
* tx - LED blinks on transmitted data
3939
* rx - LED blinks on receive data
4040
*
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.
4151
*/
4252

4353
struct led_netdev_data {
@@ -318,6 +328,7 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
318328
size_t size, enum led_trigger_netdev_modes attr)
319329
{
320330
struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
331+
struct led_classdev *led_cdev = trigger_data->led_cdev;
321332
unsigned long state, mode = trigger_data->mode;
322333
int ret;
323334
int bit;
@@ -363,6 +374,10 @@ static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
363374
trigger_data->mode = mode;
364375
trigger_data->hw_control = can_hw_control(trigger_data);
365376

377+
if (!led_cdev->brightness_set && !led_cdev->brightness_set_blocking &&
378+
!trigger_data->hw_control)
379+
return -EOPNOTSUPP;
380+
366381
set_baseline_state(trigger_data);
367382

368383
return size;

0 commit comments

Comments
 (0)