diff options
Diffstat (limited to 'drivers/leds/led-core.c')
| -rw-r--r-- | drivers/leds/led-core.c | 66 | 
1 files changed, 47 insertions, 19 deletions
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index d65353d8d3f..2ab05af3de3 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -24,14 +24,6 @@ EXPORT_SYMBOL_GPL(leds_list_lock);  LIST_HEAD(leds_list);  EXPORT_SYMBOL_GPL(leds_list); -static void led_stop_software_blink(struct led_classdev *led_cdev) -{ -	/* deactivate previous settings */ -	del_timer_sync(&led_cdev->blink_timer); -	led_cdev->blink_delay_on = 0; -	led_cdev->blink_delay_off = 0; -} -  static void led_set_software_blink(struct led_classdev *led_cdev,  				   unsigned long delay_on,  				   unsigned long delay_off) @@ -53,7 +45,7 @@ static void led_set_software_blink(struct led_classdev *led_cdev,  	/* never off - just set to brightness */  	if (!delay_off) { -		led_set_brightness(led_cdev, led_cdev->blink_brightness); +		__led_set_brightness(led_cdev, led_cdev->blink_brightness);  		return;  	} @@ -61,13 +53,12 @@ static void led_set_software_blink(struct led_classdev *led_cdev,  } -void led_blink_set(struct led_classdev *led_cdev, -		   unsigned long *delay_on, -		   unsigned long *delay_off) +static void led_blink_setup(struct led_classdev *led_cdev, +		     unsigned long *delay_on, +		     unsigned long *delay_off)  { -	del_timer_sync(&led_cdev->blink_timer); - -	if (led_cdev->blink_set && +	if (!(led_cdev->flags & LED_BLINK_ONESHOT) && +	    led_cdev->blink_set &&  	    !led_cdev->blink_set(led_cdev, delay_on, delay_off))  		return; @@ -77,12 +68,49 @@ void led_blink_set(struct led_classdev *led_cdev,  	led_set_software_blink(led_cdev, *delay_on, *delay_off);  } + +void led_blink_set(struct led_classdev *led_cdev, +		   unsigned long *delay_on, +		   unsigned long *delay_off) +{ +	del_timer_sync(&led_cdev->blink_timer); + +	led_cdev->flags &= ~LED_BLINK_ONESHOT; +	led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP; + +	led_blink_setup(led_cdev, delay_on, delay_off); +}  EXPORT_SYMBOL(led_blink_set); -void led_brightness_set(struct led_classdev *led_cdev, +void led_blink_set_oneshot(struct led_classdev *led_cdev, +			   unsigned long *delay_on, +			   unsigned long *delay_off, +			   int invert) +{ +	if ((led_cdev->flags & LED_BLINK_ONESHOT) && +	     timer_pending(&led_cdev->blink_timer)) +		return; + +	led_cdev->flags |= LED_BLINK_ONESHOT; +	led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP; + +	if (invert) +		led_cdev->flags |= LED_BLINK_INVERT; +	else +		led_cdev->flags &= ~LED_BLINK_INVERT; + +	led_blink_setup(led_cdev, delay_on, delay_off); +} +EXPORT_SYMBOL(led_blink_set_oneshot); + +void led_set_brightness(struct led_classdev *led_cdev,  			enum led_brightness brightness)  { -	led_stop_software_blink(led_cdev); -	led_cdev->brightness_set(led_cdev, brightness); +	/* stop and clear soft-blink timer */ +	del_timer_sync(&led_cdev->blink_timer); +	led_cdev->blink_delay_on = 0; +	led_cdev->blink_delay_off = 0; + +	__led_set_brightness(led_cdev, brightness);  } -EXPORT_SYMBOL(led_brightness_set); +EXPORT_SYMBOL(led_set_brightness);  |