On Thu, Aug 20, 2015 at 04:43:32PM +0200, Jacek Anaszewski wrote: > led_set_brightness_sync function was visible only internally to the > LED subsystem. It is now being made publicly available since it has > become apparent that this is a caller who should decide whether > brightness is to be set in a synchronous or an asynchronous way. > > The function is modified to use brightness_set_blocking or > brightness_set op, depending on which of them is implemented, in case > brightness_set_sync op wasn't been provided. > > Signed-off-by: Jacek Anaszewski <j.anaszewski@xxxxxxxxxxx> > Cc: Andrew Lunn <andrew@xxxxxxx> > Cc: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx> > Cc: Pavel Machek <pavel@xxxxxx> > Cc: Stas Sergeev <stsp@xxxxxxxxxxxxxxxxxxxxx> > --- > drivers/leds/led-core.c | 25 +++++++++++++++++++++++++ > drivers/leds/leds.h | 13 ------------- > include/linux/leds.h | 15 +++++++++++++++ > 3 files changed, 40 insertions(+), 13 deletions(-) > > diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c > index 549de7e..3f3b71d 100644 > --- a/drivers/leds/led-core.c > +++ b/drivers/leds/led-core.c > @@ -141,6 +141,31 @@ void led_set_brightness(struct led_classdev *led_cdev, > } > EXPORT_SYMBOL(led_set_brightness); > > +int led_set_brightness_sync(struct led_classdev *led_cdev, > + enum led_brightness value) > +{ > + int ret = 0; > + > + led_cdev->brightness = min(value, led_cdev->max_brightness); > + > + if (led_cdev->flags & LED_SUSPENDED) > + return 0; > + > + if (led_cdev->brightness_set_sync) > + ret = led_cdev->brightness_set_sync(led_cdev, > + led_cdev->brightness); > + else if (led_cdev->brightness_set_blocking) > + led_cdev->brightness_set_blocking(led_cdev, > + led_cdev->brightness); > + else if (led_cdev->brightness_set) > + led_cdev->brightness_set(led_cdev, led_cdev->brightness); I don't see how this can be correct, when you say: > +/** > + * led_set_brightness_sync - set LED brightness synchronously > + * @led_cdev: the LED to set > + * @brightness: the brightness to set it to > + * > + * Set an LED's brightness immediately. This function will block > + * the caller for the time required for accessing device register, > + * and it can sleep. led_cdev->brightness_set_sync() is fine, it is defined to the synchronous. led_cdev->brightness_set_blocking() is O.K. But led_cdev->brightness_set() only guarantees: /* Set LED brightness level */ /* Must not sleep, use a workqueue if needed */ void (*brightness_set)(struct led_classdev *led_cdev, enum led_brightness brightness); and it seems like 50% of the current drivers use work queues. It has never been defined to by synchronous. If brightness_set() is your only choice, you should return -ENOSUP. With time, you could review all the drivers and move those that are synchronous to brightness_set_sync(). Andrew -- To unsubscribe from this list: send the line "unsubscribe linux-leds" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html