From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753811AbbIPKsL (ORCPT ); Wed, 16 Sep 2015 06:48:11 -0400 Received: from mailout2.samsung.com ([203.254.224.25]:34759 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753612AbbIPKsG (ORCPT ); Wed, 16 Sep 2015 06:48:06 -0400 X-AuditID: cbfee61a-f79a06d000005c6f-12-55f948e44575 From: Jacek Anaszewski To: linux-leds@vger.kernel.org Cc: linux-kernel@vger.kernel.org, andrew@lunn.ch, sakari.ailus@linux.intel.com, stsp@users.sourceforge.net, pavel@ucw.cz, ospite@studenti.unina.it, davem@davemloft.net, linus.walleij@linaro.org, ricardo.ribalda@gmail.com, p.meerwald@bct-electronic.com, Jacek Anaszewski Subject: [PATCH 2/5] leds: core: Add LED_BLINK_CHANGE and LED_BLINK_DISABLE flags Date: Wed, 16 Sep 2015 12:47:41 +0200 Message-id: <1442400464-27367-3-git-send-email-j.anaszewski@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1442400464-27367-1-git-send-email-j.anaszewski@samsung.com> References: <1442400464-27367-1-git-send-email-j.anaszewski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrFLMWRmVeSWpSXmKPExsVy+t9jQd0nHj9DDS7d0bY4f/cQs8Wc8y0s Fr1XnzNaTPmznMni8q45bBZb36xjtPjdvZvFou+QpMXdU0fZLLq65zFZfNryjcmis28aiwOP x4p7d5k8tqy8yeSxc9Zddo871/awecw7Geixc8dnJo++LasYPQ5dWMfisWL1d3aPplPtrB6f N8kFcEdx2aSk5mSWpRbp2yVwZby7O4el4LtsxbWmh0wNjNskuhg5OSQETCReH77PAmGLSVy4 t56ti5GLQ0hgFqPEuqeNjBDOT0aJtduesYNUsQkYSvx88Zqpi5GDQ0RATmLnmUqQGmaBdUwS nQsPgk0SFgiWmHdyLVg9i4CqxNu5f9hA6nkFPCRO9DuCmBICChJzJtmAVHAKeErMf3eaEcQW AqpYdvMW4wRG3gWMDKsYJVILkguKk9JzDfNSy/WKE3OLS/PS9ZLzczcxgkP4mdQOxoO73A8x CnAwKvHwvnj2I1SINbGsuDL3EKMEB7OSCO8jq5+hQrwpiZVVqUX58UWlOanFhxilOViUxHll Vz4LFRJITyxJzU5NLUgtgskycXBKNTAu17K2zGArXeD0MjXXL2n7q2e/OGanXXx1u81g5y/p PR7nWpP5xOPvzP1kOdu/NN7bTkTaZ9ms1k2qRVxaucIGCWZfvjEY3/nTsYHt9Q/vHbwCwsFz ZQ9PVXSscpGpZvIRiQPGycLPUU96EhZ9u/m0TTXzUoGz2ZYDB6KWNlRnWgm6Pb73WYmlOCPR UIu5qDgRAF4oVfJdAgAA Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch adds LED_BLINK_CHANGE flag to indicate that blink brightness has changed, and LED_BLINK_DISABLE flag to indicate that blinking deactivation has been requested. In order to use the flags led_timer_function and set_brightness_delayed callbacks as well as led_set_brightness function are being modified. The main goal of these modifications is to prepare set_brightness_work for extension of the scope of its responsibilities. Signed-off-by: Jacek Anaszewski --- drivers/leds/led-core.c | 36 ++++++++++++++++++++++++++---------- include/linux/leds.h | 10 ++++++---- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index 2cb4e37..1968e24 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -44,18 +44,18 @@ static void led_timer_function(unsigned long data) brightness = led_get_brightness(led_cdev); if (!brightness) { /* Time to switch the LED on. */ - if (led_cdev->delayed_set_value) { - led_cdev->blink_brightness = - led_cdev->delayed_set_value; - led_cdev->delayed_set_value = 0; - } brightness = led_cdev->blink_brightness; delay = led_cdev->blink_delay_on; } else { /* Store the current brightness value to be able * to restore it when the delay_off period is over. + * Do it only if there is no pending blink brightness + * change, to avoid overwriting the new value. */ - led_cdev->blink_brightness = brightness; + if (!(led_cdev->flags & LED_BLINK_CHANGE)) + led_cdev->blink_brightness = brightness; + else + led_cdev->flags &= ~LED_BLINK_CHANGE; brightness = LED_OFF; delay = led_cdev->blink_delay_off; } @@ -84,7 +84,11 @@ static void set_brightness_delayed(struct work_struct *ws) struct led_classdev *led_cdev = container_of(ws, struct led_classdev, set_brightness_work); - led_stop_software_blink(led_cdev); + if (led_cdev->flags & LED_BLINK_DISABLE) { + led_cdev->delayed_set_value = LED_OFF; + led_stop_software_blink(led_cdev); + led_cdev->flags &= ~LED_BLINK_DISABLE; + } led_set_brightness_async(led_cdev, led_cdev->delayed_set_value); } @@ -192,11 +196,23 @@ void led_set_brightness(struct led_classdev *led_cdev, { int ret = 0; - /* delay brightness if soft-blink is active */ + /* + * In case blinking is on delay brightness setting + * until the next timer tick. + */ if (led_cdev->blink_delay_on || led_cdev->blink_delay_off) { - led_cdev->delayed_set_value = brightness; - if (brightness == LED_OFF) + /* + * If need to disable soft blinking delegate this to the + * work queue task to avoid problems in case we are + * called from hard irq context. + */ + if (brightness == LED_OFF) { + led_cdev->flags |= LED_BLINK_DISABLE; schedule_work(&led_cdev->set_brightness_work); + } else { + led_cdev->flags |= LED_BLINK_CHANGE; + led_cdev->blink_brightness = brightness; + } return; } diff --git a/include/linux/leds.h b/include/linux/leds.h index b122eea..188352c 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -44,10 +44,12 @@ struct led_classdev { #define LED_BLINK_ONESHOT (1 << 17) #define LED_BLINK_ONESHOT_STOP (1 << 18) #define LED_BLINK_INVERT (1 << 19) -#define LED_SYSFS_DISABLE (1 << 20) -#define SET_BRIGHTNESS_ASYNC (1 << 21) -#define SET_BRIGHTNESS_SYNC (1 << 22) -#define LED_DEV_CAP_FLASH (1 << 23) +#define LED_BLINK_CHANGE (1 << 20) +#define LED_BLINK_DISABLE (1 << 21) +#define LED_SYSFS_DISABLE (1 << 22) +#define SET_BRIGHTNESS_ASYNC (1 << 23) +#define SET_BRIGHTNESS_SYNC (1 << 24) +#define LED_DEV_CAP_FLASH (1 << 25) /* Set LED brightness level */ /* Must not sleep, use a workqueue if needed */ -- 1.7.9.5