kernel: 4.19: fix usbport led trigger regression

|In the patch "usb: simplify usbport trigger" together with
|"leds: triggers: add device attribute support" caused an
|regression for the usbport trigger. it will no longer
|enumerate any "ports" (i.e the sysfs directory stays empty)
|if the usb host drivers are fully initialized before the
|usbport trigger was loaded.

<https://marc.info/?l=linux-usb&m=154577101631079>

Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
This commit is contained in:
Christian Lamparter 2018-12-25 21:54:42 +01:00
parent ef5ff08662
commit 96d55f9fd9

View File

@ -0,0 +1,84 @@
From 38a3549ffc0033761063cc5c7b994ab075694db8 Mon Sep 17 00:00:00 2001
From: Christian Lamparter <chunkeey@gmail.com>
Date: Tue, 25 Dec 2018 21:11:08 +0100
Subject: [RFC PATCH] leds: fix regression in usbport led trigger
In the patch "usb: simplify usbport trigger" together with
"leds: triggers: add device attribute support" caused an
regression for the usbport trigger. it will no longer
enumerate any "ports" (i.e the sysfs directory stays empty)
if the usb host drivers are fully initialized before the
usbport trigger was loaded.
The reason is that the usbport driver registers the sysfs
entries in the ports subdirectory during the activate()
callback. Whereas the patch
"leds: triggers: add device attribute support" made it so
that the sysfs "ports" group was only being added after
the activate() callback succeeded.
This patch moves the device_add_groups() in front of the
call to the trigger's activate() function in order to
solve the problem.
Fixes: 6f7b0bad8839 ("usb: simplify usbport trigger")
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
---
drivers/leds/led-triggers.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 17d73db1456e..08e7c724a9dc 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -134,6 +134,12 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
led_set_brightness(led_cdev, LED_OFF);
}
if (trig) {
+ ret = device_add_groups(led_cdev->dev, trig->groups);
+ if (ret) {
+ dev_err(led_cdev->dev, "Failed to add trigger attributes\n");
+ goto err_add_groups;
+ }
+
write_lock_irqsave(&trig->leddev_list_lock, flags);
list_add_tail(&led_cdev->trig_list, &trig->led_cdevs);
write_unlock_irqrestore(&trig->leddev_list_lock, flags);
@@ -146,12 +152,6 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
if (ret)
goto err_activate;
-
- ret = device_add_groups(led_cdev->dev, trig->groups);
- if (ret) {
- dev_err(led_cdev->dev, "Failed to add trigger attributes\n");
- goto err_add_groups;
- }
}
if (event) {
@@ -165,17 +165,18 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
return 0;
-err_add_groups:
-
+err_activate:
+ device_remove_groups(led_cdev->dev, trig->groups);
if (trig->deactivate)
trig->deactivate(led_cdev);
-err_activate:
led_cdev->trigger = NULL;
led_cdev->trigger_data = NULL;
write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags);
list_del(&led_cdev->trig_list);
write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, flags);
+
+err_add_groups:
led_set_brightness(led_cdev, LED_OFF);
return ret;
--
2.20.1