Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp4181354rwb; Mon, 21 Nov 2022 04:52:45 -0800 (PST) X-Google-Smtp-Source: AA0mqf4MeBOWLYRgrELpaCf59NEnSGt3yxWq0ZaSf1DWwCnbqt4yvUGr9bjH+P9IwCw77KL9t3ea X-Received: by 2002:a17:906:e87:b0:78d:b88f:1548 with SMTP id p7-20020a1709060e8700b0078db88f1548mr15769271ejf.221.1669035165094; Mon, 21 Nov 2022 04:52:45 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669035165; cv=none; d=google.com; s=arc-20160816; b=Vsz9lJ4i+iELlbJEg5xb2pCoYqW7lSFzmVL8TY+S/WVL8vKjQbvuANcK/HRL5q87cU LvB8+Qj269PqewvAfBqqA0zrLKV69dw1uNLmvlaPvBjTTp8126yQWSG1tSMzf8J4JiTO vzd7BBTeu/1nyS0keI66uzLwELEvNqICczianFe8L/udifDlgJf5exBVnk5BTES6AZNR yhVIrNjdMRv2yC3YCajS7HhSpTxJQikr5RxGxPRKKgzAixgkJpDJHk/mqcBeCQLk7IJw GANH8kM91ERN2k09sx7L7ttBXuOa3KdweTBhXM2dZxMEVzl4xkQZEc9y7Be2dX/QOkAS 2F9w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=DUvu+YKp1hu6pdL6wHkphNXlL3BTh1Kqk0H1tPtLv58=; b=igKzKQ2s4i8FezmSbn6gpMH2zS8xkEiUIyuvaRSXNEjwXi+zyt7AN7Q73fmwqlZZp4 5zM+9rRy4VV/H/MkTTWQGzXwFkBLRULh5oVhAecR5nlyIZQYB8F/A94VutDCsPENkMSF ogFgJDJIrt7U/QQ1ooZBgjC+KNUrRFmNSU2FAp8FQR2ht9IMaYV13IyQV5pCE3xQJyLY pWcsEmjaMInWtYdvAb64OJU+Pks7WYYfc4rtFmDk3GJ9HqR8iKeqiqKzvItPXpEhgGwL yEClmKLpDKKGaf2EMjGMZhxQk3r5PfQnPwdOK/Rbm2iRQW1hiq0/B//W8pQK3TYixPS/ r2OA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sberdevices.ru header.s=mail header.b=nq2oAr7X; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=sberdevices.ru Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id l4-20020aa7d944000000b00467e2dc8d13si3280376eds.94.2022.11.21.04.52.17; Mon, 21 Nov 2022 04:52:45 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@sberdevices.ru header.s=mail header.b=nq2oAr7X; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=sberdevices.ru Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230342AbiKUMj6 (ORCPT + 92 others); Mon, 21 Nov 2022 07:39:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59454 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231576AbiKUMjl (ORCPT ); Mon, 21 Nov 2022 07:39:41 -0500 Received: from mx.sberdevices.ru (mx.sberdevices.ru [45.89.227.171]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 267FC1C412; Mon, 21 Nov 2022 04:39:33 -0800 (PST) Received: from s-lin-edge02.sberdevices.ru (localhost [127.0.0.1]) by mx.sberdevices.ru (Postfix) with ESMTP id 721865FD0B; Mon, 21 Nov 2022 15:39:31 +0300 (MSK) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sberdevices.ru; s=mail; t=1669034371; bh=DUvu+YKp1hu6pdL6wHkphNXlL3BTh1Kqk0H1tPtLv58=; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type; b=nq2oAr7XLtOOyJIHjGIg273R7HJyGriAS+nJKSg87sTFIFt10dptkhBo7lA4w7QB7 M8kL5F+VUAWVsk0IsKS50G53c+6wjjRPZtuvwmlfKEOxqjFnMrk+2i9jOJaHlM1MXE s0iQdr8yt+B9UZ2X1AoymTGVkpg1mKE6SKqJAiwNzupijmBJ0Wj9vzBh30OrVa2ZCN skT39m4hziy1wg8dsZF+A3wKnXNBCJMy6xBHH+TEnvg37TCvL/h027cmxy7V2n19d7 yDKRz3eV6yS7GPgJ9n+xVp2shgcKbs8QQRrCROmNFwNEX7PnUae1GoY8cbOpYU+qMt pRE7PC4d5PIWg== Received: from S-MS-EXCH01.sberdevices.ru (S-MS-EXCH01.sberdevices.ru [172.16.1.4]) by mx.sberdevices.ru (Postfix) with ESMTP; Mon, 21 Nov 2022 15:39:31 +0300 (MSK) From: Martin Kurbanov To: Pavel Machek , Raphael Teysseyre , Andy Shevchenko CC: , , , Martin Kurbanov Subject: [PATCH v2 2/2] leds: trigger: pattern: notify usespace if pattern finished Date: Mon, 21 Nov 2022 15:38:33 +0300 Message-ID: <20221121123833.164614-3-mmkurbanov@sberdevices.ru> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221121123833.164614-1-mmkurbanov@sberdevices.ru> References: <20221121123833.164614-1-mmkurbanov@sberdevices.ru> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [172.16.1.6] X-ClientProxiedBy: S-MS-EXCH02.sberdevices.ru (172.16.1.5) To S-MS-EXCH01.sberdevices.ru (172.16.1.4) X-KSMG-Rule-ID: 4 X-KSMG-Message-Action: clean X-KSMG-AntiSpam-Status: not scanned, disabled by settings X-KSMG-AntiSpam-Interceptor-Info: not scanned X-KSMG-AntiPhishing: not scanned, disabled by settings X-KSMG-AntiVirus: Kaspersky Secure Mail Gateway, version 1.1.2.30, bases: 2022/11/21 03:43:00 #20593185 X-KSMG-AntiVirus-Status: Clean, skipped X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In the current moment, userspace caller can schedule LED pattern with appropriate parameters, but it doesn't have ability to listen to any events indicated pattern finished. This patch implements such an event using sysfs node and sysfs_notify_dirent() call. Signed-off-by: Martin Kurbanov --- .../testing/sysfs-class-led-trigger-pattern | 11 ++++ drivers/leds/trigger/ledtrig-pattern.c | 63 ++++++++++++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-class-led-trigger-pattern b/Documentation/ABI/testing/sysfs-class-led-trigger-pattern index 8c57d2780554..b2564123b54b 100644 --- a/Documentation/ABI/testing/sysfs-class-led-trigger-pattern +++ b/Documentation/ABI/testing/sysfs-class-led-trigger-pattern @@ -38,3 +38,14 @@ Description: It should be noticed that some leds, like EL15203000 may only support indefinitely patterns, so they always store -1. + +What: /sys/class/leds//is_running +Date: October 2022 +KernelVersion: 6.1 +Description: + Indicates running of a software pattern for the LED. + + This file is read only and supports poll() to detect when the + software pattern ended. + + 1 means pattern is running and number 0 are finish or not run. diff --git a/drivers/leds/trigger/ledtrig-pattern.c b/drivers/leds/trigger/ledtrig-pattern.c index 354304b404aa..19a6b5dcd7af 100644 --- a/drivers/leds/trigger/ledtrig-pattern.c +++ b/drivers/leds/trigger/ledtrig-pattern.c @@ -33,7 +33,9 @@ struct pattern_trig_data { int delta_t; bool is_indefinite; bool is_hw_pattern; + bool is_running; struct timer_list timer; + struct kernfs_node *is_running_kn; }; static void pattern_trig_update_patterns(struct pattern_trig_data *data) @@ -76,8 +78,14 @@ static void pattern_trig_timer_function(struct timer_list *t) struct pattern_trig_data *data = from_timer(data, t, timer); for (;;) { - if (!data->is_indefinite && !data->repeat) + if (!data->is_indefinite && !data->repeat) { + data->is_running = false; + + if (data->is_running_kn) + sysfs_notify_dirent(data->is_running_kn); + break; + } if (data->curr->brightness == data->next->brightness) { /* Step change of brightness */ @@ -137,6 +145,7 @@ static int pattern_trig_start_pattern(struct led_classdev *led_cdev) data->curr = data->patterns; data->next = data->patterns + 1; data->timer.expires = jiffies; + data->is_running = true; add_timer(&data->timer); return 0; @@ -176,6 +185,7 @@ static ssize_t repeat_store(struct device *dev, struct device_attribute *attr, mutex_lock(&data->lock); del_timer_sync(&data->timer); + data->is_running = false; if (data->is_hw_pattern) led_cdev->pattern_clear(led_cdev); @@ -267,6 +277,7 @@ static ssize_t pattern_trig_store_patterns(struct led_classdev *led_cdev, mutex_lock(&data->lock); del_timer_sync(&data->timer); + data->is_running = false; if (data->is_hw_pattern) led_cdev->pattern_clear(led_cdev); @@ -327,6 +338,16 @@ static ssize_t hw_pattern_store(struct device *dev, } static DEVICE_ATTR_RW(hw_pattern); +static ssize_t is_running_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct pattern_trig_data *data = led_get_trigger_data(led_cdev); + + return sysfs_emit(buf, "%d\n", data->is_running); +} +static DEVICE_ATTR_RO(is_running); + static umode_t pattern_trig_attrs_mode(struct kobject *kobj, struct attribute *attr, int index) { @@ -382,9 +403,41 @@ static void pattern_init(struct led_classdev *led_cdev) kfree(pattern); } +static int pattern_trig_add_is_running(struct led_classdev *led_cdev) +{ + struct pattern_trig_data *data = led_get_trigger_data(led_cdev); + struct device *dev = led_cdev->dev; + int ret; + + ret = device_create_file(dev, &dev_attr_is_running); + if (ret) { + dev_err(dev, + "Error creating is_running (%pe)\n", ERR_PTR(ret)); + return ret; + } + + data->is_running_kn = sysfs_get_dirent(dev->kobj.sd, "is_running"); + if (!data->is_running_kn) { + dev_err(dev, "Error getting is_running kernelfs\n"); + device_remove_file(dev, &dev_attr_is_running); + return -ENXIO; + } + + return 0; +} + +static void pattern_trig_remove_is_running(struct led_classdev *led_cdev) +{ + struct pattern_trig_data *data = led_get_trigger_data(led_cdev); + + sysfs_put(data->is_running_kn); + device_remove_file(led_cdev->dev, &dev_attr_is_running); +} + static int pattern_trig_activate(struct led_classdev *led_cdev) { struct pattern_trig_data *data; + int err; data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) @@ -403,6 +456,13 @@ static int pattern_trig_activate(struct led_classdev *led_cdev) data->led_cdev = led_cdev; led_set_trigger_data(led_cdev, data); timer_setup(&data->timer, pattern_trig_timer_function, 0); + + err = pattern_trig_add_is_running(led_cdev); + if (err) + dev_warn(led_cdev->dev, + "pattern ended notifications disabled (%pe)\n", + ERR_PTR(err)); + led_cdev->activated = true; if (led_cdev->flags & LED_INIT_DEFAULT_TRIGGER) { @@ -428,6 +488,7 @@ static void pattern_trig_deactivate(struct led_classdev *led_cdev) led_cdev->pattern_clear(led_cdev); del_timer_sync(&data->timer); + pattern_trig_remove_is_running(led_cdev); led_set_brightness(led_cdev, LED_OFF); kfree(data); -- 2.38.1