--- zzzz-none-000/linux-3.10.107/drivers/leds/led-triggers.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/leds/led-triggers.c 2021-02-04 17:41:59.000000000 +0000 @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -38,6 +37,14 @@ char trigger_name[TRIG_NAME_MAX]; struct led_trigger *trig; size_t len; + int ret = count; + + mutex_lock(&led_cdev->led_access); + + if (led_sysfs_is_disabled(led_cdev)) { + ret = -EBUSY; + goto unlock; + } trigger_name[sizeof(trigger_name) - 1] = '\0'; strncpy(trigger_name, buf, sizeof(trigger_name) - 1); @@ -48,7 +55,7 @@ if (!strcmp(trigger_name, "none")) { led_trigger_remove(led_cdev); - return count; + goto unlock; } down_read(&triggers_list_lock); @@ -59,12 +66,14 @@ up_write(&led_cdev->trigger_lock); up_read(&triggers_list_lock); - return count; + goto unlock; } } up_read(&triggers_list_lock); - return -EINVAL; +unlock: + mutex_unlock(&led_cdev->led_access); + return ret; } EXPORT_SYMBOL_GPL(led_trigger_store); @@ -220,9 +229,12 @@ { struct led_classdev *led_cdev; + if (list_empty_careful(&trig->next_trig)) + return; + /* Remove from the list of led triggers */ down_write(&triggers_list_lock); - list_del(&trig->next_trig); + list_del_init(&trig->next_trig); up_write(&triggers_list_lock); /* Remove anyone actively using this trigger */ @@ -242,18 +254,14 @@ void led_trigger_event(struct led_trigger *trig, enum led_brightness brightness) { - struct list_head *entry; + struct led_classdev *led_cdev; if (!trig) return; read_lock(&trig->leddev_list_lock); - list_for_each(entry, &trig->led_cdevs) { - struct led_classdev *led_cdev; - - led_cdev = list_entry(entry, struct led_classdev, trig_list); + list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list) led_set_brightness(led_cdev, brightness); - } read_unlock(&trig->leddev_list_lock); } EXPORT_SYMBOL_GPL(led_trigger_event); @@ -264,16 +272,13 @@ int oneshot, int invert) { - struct list_head *entry; + struct led_classdev *led_cdev; if (!trig) return; read_lock(&trig->leddev_list_lock); - list_for_each(entry, &trig->led_cdevs) { - struct led_classdev *led_cdev; - - led_cdev = list_entry(entry, struct led_classdev, trig_list); + list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list) { if (oneshot) led_blink_set_oneshot(led_cdev, delay_on, delay_off, invert);