From patchwork Mon Nov 6 12:34:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Eckert X-Patchwork-Id: 743223 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A1C71C4332F for ; Mon, 6 Nov 2023 12:34:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231709AbjKFMep (ORCPT ); Mon, 6 Nov 2023 07:34:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35946 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231641AbjKFMel (ORCPT ); Mon, 6 Nov 2023 07:34:41 -0500 Received: from mxout70.expurgate.net (mxout70.expurgate.net [194.37.255.70]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0057A97; Mon, 6 Nov 2023 04:34:38 -0800 (PST) Received: from [127.0.0.1] (helo=localhost) by relay.expurgate.net with smtp (Exim 4.92) (envelope-from ) id 1qzyoG-00HTx5-N0; Mon, 06 Nov 2023 13:34:28 +0100 Received: from [195.243.126.94] (helo=securemail.tdt.de) by relay.expurgate.net with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qzyoF-00DGWP-TQ; Mon, 06 Nov 2023 13:34:27 +0100 Received: from securemail.tdt.de (localhost [127.0.0.1]) by securemail.tdt.de (Postfix) with ESMTP id 77A08240049; Mon, 6 Nov 2023 13:34:27 +0100 (CET) Received: from mail.dev.tdt.de (unknown [10.2.4.42]) by securemail.tdt.de (Postfix) with ESMTP id C8B0824004B; Mon, 6 Nov 2023 13:34:26 +0100 (CET) Received: from localhost.localdomain (unknown [10.2.3.40]) by mail.dev.tdt.de (Postfix) with ESMTPSA id 754A1227EE; Mon, 6 Nov 2023 13:34:26 +0100 (CET) From: Florian Eckert To: Eckert.Florian@googlemail.com, gregkh@linuxfoundation.org, jirislaby@kernel.org, pavel@ucw.cz, lee@kernel.org, kabel@kernel.org, u.kleine-koenig@pengutronix.de, m.brock@vanmierlo.com Cc: linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, linux-leds@vger.kernel.org Subject: [Patch v7 1/6] tty: add new helper function tty_get_tiocm Date: Mon, 6 Nov 2023 13:34:10 +0100 Message-ID: <20231106123415.3365732-2-fe@dev.tdt.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20231106123415.3365732-1-fe@dev.tdt.de> References: <20231106123415.3365732-1-fe@dev.tdt.de> MIME-Version: 1.0 X-purgate-ID: 151534::1699274068-86F347EA-449FC374/0/0 X-purgate-type: clean X-purgate: clean Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org There is no in-kernel function to get the status register of a tty device like the TIOCMGET ioctl returns to userspace. Create a new function, tty_get_tiocm(), to obtain the status register that other portions of the kernel can call if they need this information, and move the existing internal tty_tiocmget() function to use this interface. Acked-by: Greg Kroah-Hartman Signed-off-by: Florian Eckert --- drivers/tty/tty_io.c | 28 ++++++++++++++++++++++------ include/linux/tty.h | 1 + 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 06414e43e0b5..e2e93404133e 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2498,6 +2498,24 @@ static int send_break(struct tty_struct *tty, unsigned int duration) return retval; } +/** + * tty_get_tiocm - get tiocm status register + * @tty: tty device + * + * Obtain the modem status bits from the tty driver if the feature + * is supported. + */ +int tty_get_tiocm(struct tty_struct *tty) +{ + int retval = -ENOTTY; + + if (tty->ops->tiocmget) + retval = tty->ops->tiocmget(tty); + + return retval; +} +EXPORT_SYMBOL_GPL(tty_get_tiocm); + /** * tty_tiocmget - get modem status * @tty: tty device @@ -2510,14 +2528,12 @@ static int send_break(struct tty_struct *tty, unsigned int duration) */ static int tty_tiocmget(struct tty_struct *tty, int __user *p) { - int retval = -ENOTTY; + int retval; - if (tty->ops->tiocmget) { - retval = tty->ops->tiocmget(tty); + retval = tty_get_tiocm(tty); + if (retval >= 0) + retval = put_user(retval, p); - if (retval >= 0) - retval = put_user(retval, p); - } return retval; } diff --git a/include/linux/tty.h b/include/linux/tty.h index 4b6340ac2af2..d219a11e3fe0 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -419,6 +419,7 @@ bool tty_unthrottle_safe(struct tty_struct *tty); int tty_do_resize(struct tty_struct *tty, struct winsize *ws); int tty_get_icount(struct tty_struct *tty, struct serial_icounter_struct *icount); +int tty_get_tiocm(struct tty_struct *tty); int is_current_pgrp_orphaned(void); void tty_hangup(struct tty_struct *tty); void tty_vhangup(struct tty_struct *tty); From patchwork Mon Nov 6 12:34:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Eckert X-Patchwork-Id: 741643 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 40055C4167B for ; Mon, 6 Nov 2023 12:34:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231719AbjKFMeq (ORCPT ); Mon, 6 Nov 2023 07:34:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35956 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231648AbjKFMem (ORCPT ); Mon, 6 Nov 2023 07:34:42 -0500 Received: from mxout70.expurgate.net (mxout70.expurgate.net [194.37.255.70]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 77D8BB7; Mon, 6 Nov 2023 04:34:39 -0800 (PST) Received: from [127.0.0.1] (helo=localhost) by relay.expurgate.net with smtp (Exim 4.92) (envelope-from ) id 1qzyoG-00GOPh-VV; Mon, 06 Nov 2023 13:34:29 +0100 Received: from [195.243.126.94] (helo=securemail.tdt.de) by relay.expurgate.net with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qzyoG-00HTwR-2T; Mon, 06 Nov 2023 13:34:28 +0100 Received: from securemail.tdt.de (localhost [127.0.0.1]) by securemail.tdt.de (Postfix) with ESMTP id ABAAF24004B; Mon, 6 Nov 2023 13:34:27 +0100 (CET) Received: from mail.dev.tdt.de (unknown [10.2.4.42]) by securemail.tdt.de (Postfix) with ESMTP id 0589224004D; Mon, 6 Nov 2023 13:34:27 +0100 (CET) Received: from localhost.localdomain (unknown [10.2.3.40]) by mail.dev.tdt.de (Postfix) with ESMTPSA id C858B2225B; Mon, 6 Nov 2023 13:34:26 +0100 (CET) From: Florian Eckert To: Eckert.Florian@googlemail.com, gregkh@linuxfoundation.org, jirislaby@kernel.org, pavel@ucw.cz, lee@kernel.org, kabel@kernel.org, u.kleine-koenig@pengutronix.de, m.brock@vanmierlo.com Cc: linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, linux-leds@vger.kernel.org Subject: [Patch v7 2/6] leds: ledtrig-tty: free allocated ttyname buffer on deactivate Date: Mon, 6 Nov 2023 13:34:11 +0100 Message-ID: <20231106123415.3365732-3-fe@dev.tdt.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20231106123415.3365732-1-fe@dev.tdt.de> References: <20231106123415.3365732-1-fe@dev.tdt.de> MIME-Version: 1.0 X-purgate-type: clean X-purgate: clean X-purgate-ID: 151534::1699274068-066056AA-98EB4578/0/0 Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org The ttyname buffer for the ledtrig_tty_data struct is allocated in the sysfs ttyname_store() function. This buffer must be released on trigger deactivation. This was missing and is thus a memory leak. While we are at it, the tty handler in the ledtrig_tty_data struct should also be returned in case of the trigger deactivation call. Fixes: fd4a641ac88f ("leds: trigger: implement a tty trigger") Signed-off-by: Florian Eckert --- drivers/leds/trigger/ledtrig-tty.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/leds/trigger/ledtrig-tty.c b/drivers/leds/trigger/ledtrig-tty.c index 8ae0d2d284af..3e69a7bde928 100644 --- a/drivers/leds/trigger/ledtrig-tty.c +++ b/drivers/leds/trigger/ledtrig-tty.c @@ -168,6 +168,10 @@ static void ledtrig_tty_deactivate(struct led_classdev *led_cdev) cancel_delayed_work_sync(&trigger_data->dwork); + kfree(trigger_data->ttyname); + tty_kref_put(trigger_data->tty); + trigger_data->tty = NULL; + kfree(trigger_data); } From patchwork Mon Nov 6 12:34:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Eckert X-Patchwork-Id: 741645 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EF876C4167D for ; Mon, 6 Nov 2023 12:34:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231566AbjKFMek (ORCPT ); Mon, 6 Nov 2023 07:34:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59636 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231558AbjKFMeh (ORCPT ); Mon, 6 Nov 2023 07:34:37 -0500 Received: from mxout70.expurgate.net (mxout70.expurgate.net [91.198.224.70]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CCC9EB6; Mon, 6 Nov 2023 04:34:34 -0800 (PST) Received: from [127.0.0.1] (helo=localhost) by relay.expurgate.net with smtp (Exim 4.92) (envelope-from ) id 1qzyoH-00BFYS-3c; Mon, 06 Nov 2023 13:34:29 +0100 Received: from [195.243.126.94] (helo=securemail.tdt.de) by relay.expurgate.net with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qzyoG-00Ddr6-7d; Mon, 06 Nov 2023 13:34:28 +0100 Received: from securemail.tdt.de (localhost [127.0.0.1]) by securemail.tdt.de (Postfix) with ESMTP id DCE61240050; Mon, 6 Nov 2023 13:34:27 +0100 (CET) Received: from mail.dev.tdt.de (unknown [10.2.4.42]) by securemail.tdt.de (Postfix) with ESMTP id 3BB64240052; Mon, 6 Nov 2023 13:34:27 +0100 (CET) Received: from localhost.localdomain (unknown [10.2.3.40]) by mail.dev.tdt.de (Postfix) with ESMTPSA id 05AE1227EE; Mon, 6 Nov 2023 13:34:27 +0100 (CET) From: Florian Eckert To: Eckert.Florian@googlemail.com, gregkh@linuxfoundation.org, jirislaby@kernel.org, pavel@ucw.cz, lee@kernel.org, kabel@kernel.org, u.kleine-koenig@pengutronix.de, m.brock@vanmierlo.com Cc: linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, linux-leds@vger.kernel.org Subject: [Patch v7 3/6] leds: ledtrig-tty: change logging if get icount failed Date: Mon, 6 Nov 2023 13:34:12 +0100 Message-ID: <20231106123415.3365732-4-fe@dev.tdt.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20231106123415.3365732-1-fe@dev.tdt.de> References: <20231106123415.3365732-1-fe@dev.tdt.de> MIME-Version: 1.0 X-purgate: clean X-purgate-ID: 151534::1699274068-65079C7C-E3564830/0/0 X-purgate-type: clean Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Change the log level from info to warn, because there is something wrong. That is more a warn message than an info message. While we are at it, the device prefix is also changed, as this is the led device and not the tty device that generates this message. Signed-off-by: Florian Eckert --- drivers/leds/trigger/ledtrig-tty.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/leds/trigger/ledtrig-tty.c b/drivers/leds/trigger/ledtrig-tty.c index 3e69a7bde928..86595add72cd 100644 --- a/drivers/leds/trigger/ledtrig-tty.c +++ b/drivers/leds/trigger/ledtrig-tty.c @@ -83,6 +83,7 @@ static void ledtrig_tty_work(struct work_struct *work) struct ledtrig_tty_data *trigger_data = container_of(work, struct ledtrig_tty_data, dwork.work); struct serial_icounter_struct icount; + struct led_classdev *led_cdev = trigger_data->led_cdev; int ret; mutex_lock(&trigger_data->mutex); @@ -117,7 +118,7 @@ static void ledtrig_tty_work(struct work_struct *work) ret = tty_get_icount(trigger_data->tty, &icount); if (ret) { - dev_info(trigger_data->tty->dev, "Failed to get icount, stopped polling\n"); + dev_warn(led_cdev->dev, "Failed to get icount, stop polling\n"); mutex_unlock(&trigger_data->mutex); return; } @@ -126,8 +127,7 @@ static void ledtrig_tty_work(struct work_struct *work) icount.tx != trigger_data->tx) { unsigned long interval = LEDTRIG_TTY_INTERVAL; - led_blink_set_oneshot(trigger_data->led_cdev, &interval, - &interval, 0); + led_blink_set_oneshot(led_cdev, &interval, &interval, 0); trigger_data->rx = icount.rx; trigger_data->tx = icount.tx; From patchwork Mon Nov 6 12:34:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Eckert X-Patchwork-Id: 741644 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 81FACC4708E for ; Mon, 6 Nov 2023 12:34:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229583AbjKFMel (ORCPT ); Mon, 6 Nov 2023 07:34:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59586 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231604AbjKFMej (ORCPT ); Mon, 6 Nov 2023 07:34:39 -0500 Received: from mxout70.expurgate.net (mxout70.expurgate.net [91.198.224.70]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1E0F5B8; Mon, 6 Nov 2023 04:34:36 -0800 (PST) Received: from [127.0.0.1] (helo=localhost) by relay.expurgate.net with smtp (Exim 4.92) (envelope-from ) id 1qzyoH-001isW-Dj; Mon, 06 Nov 2023 13:34:29 +0100 Received: from [195.243.126.94] (helo=securemail.tdt.de) by relay.expurgate.net with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qzyoG-001iry-Kp; Mon, 06 Nov 2023 13:34:28 +0100 Received: from securemail.tdt.de (localhost [127.0.0.1]) by securemail.tdt.de (Postfix) with ESMTP id 3FC4224004B; Mon, 6 Nov 2023 13:34:28 +0100 (CET) Received: from mail.dev.tdt.de (unknown [10.2.4.42]) by securemail.tdt.de (Postfix) with ESMTP id 8FE8D240040; Mon, 6 Nov 2023 13:34:27 +0100 (CET) Received: from localhost.localdomain (unknown [10.2.3.40]) by mail.dev.tdt.de (Postfix) with ESMTPSA id 3BB2E2225B; Mon, 6 Nov 2023 13:34:27 +0100 (CET) From: Florian Eckert To: Eckert.Florian@googlemail.com, gregkh@linuxfoundation.org, jirislaby@kernel.org, pavel@ucw.cz, lee@kernel.org, kabel@kernel.org, u.kleine-koenig@pengutronix.de, m.brock@vanmierlo.com Cc: linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, linux-leds@vger.kernel.org Subject: [Patch v7 4/6] leds: ledtrig-tty: replace mutex with completion Date: Mon, 6 Nov 2023 13:34:13 +0100 Message-ID: <20231106123415.3365732-5-fe@dev.tdt.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20231106123415.3365732-1-fe@dev.tdt.de> References: <20231106123415.3365732-1-fe@dev.tdt.de> MIME-Version: 1.0 X-purgate-ID: 151534::1699274069-DEFDB1F7-FD5AF955/0/0 X-purgate-type: clean X-purgate: clean Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org With this commit, the mutex handling is replaced by the completion handling. When handling mutex, it must always be ensured that the held mutex is also released again. This is more error-prone should the number of code paths increase. This is a preparatory commit to make the trigger more configurable via additional sysfs parameters. With this change, the worker always runs and is no longer stopped if no ttyname is set. Signed-off-by: Florian Eckert --- drivers/leds/trigger/ledtrig-tty.c | 60 +++++++++++++++--------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/drivers/leds/trigger/ledtrig-tty.c b/drivers/leds/trigger/ledtrig-tty.c index 86595add72cd..3badf74fa420 100644 --- a/drivers/leds/trigger/ledtrig-tty.c +++ b/drivers/leds/trigger/ledtrig-tty.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include #include #include @@ -12,15 +13,24 @@ struct ledtrig_tty_data { struct led_classdev *led_cdev; struct delayed_work dwork; - struct mutex mutex; + struct completion sysfs; const char *ttyname; struct tty_struct *tty; int rx, tx; }; -static void ledtrig_tty_restart(struct ledtrig_tty_data *trigger_data) +static int ledtrig_tty_waitforcompletion(struct device *dev) { - schedule_delayed_work(&trigger_data->dwork, 0); + struct ledtrig_tty_data *trigger_data = led_trigger_get_drvdata(dev); + int ret; + + ret = wait_for_completion_timeout(&trigger_data->sysfs, + msecs_to_jiffies(LEDTRIG_TTY_INTERVAL * 20)); + + if (ret == 0) + return -ETIMEDOUT; + + return ret; } static ssize_t ttyname_show(struct device *dev, @@ -28,14 +38,16 @@ static ssize_t ttyname_show(struct device *dev, { struct ledtrig_tty_data *trigger_data = led_trigger_get_drvdata(dev); ssize_t len = 0; + int completion; - mutex_lock(&trigger_data->mutex); + reinit_completion(&trigger_data->sysfs); + completion = ledtrig_tty_waitforcompletion(dev); + if (completion < 0) + return completion; if (trigger_data->ttyname) len = sprintf(buf, "%s\n", trigger_data->ttyname); - mutex_unlock(&trigger_data->mutex); - return len; } @@ -46,7 +58,7 @@ static ssize_t ttyname_store(struct device *dev, struct ledtrig_tty_data *trigger_data = led_trigger_get_drvdata(dev); char *ttyname; ssize_t ret = size; - bool running; + int completion; if (size > 0 && buf[size - 1] == '\n') size -= 1; @@ -59,9 +71,10 @@ static ssize_t ttyname_store(struct device *dev, ttyname = NULL; } - mutex_lock(&trigger_data->mutex); - - running = trigger_data->ttyname != NULL; + reinit_completion(&trigger_data->sysfs); + completion = ledtrig_tty_waitforcompletion(dev); + if (completion < 0) + return completion; kfree(trigger_data->ttyname); tty_kref_put(trigger_data->tty); @@ -69,11 +82,6 @@ static ssize_t ttyname_store(struct device *dev, trigger_data->ttyname = ttyname; - mutex_unlock(&trigger_data->mutex); - - if (ttyname && !running) - ledtrig_tty_restart(trigger_data); - return ret; } static DEVICE_ATTR_RW(ttyname); @@ -86,13 +94,8 @@ static void ledtrig_tty_work(struct work_struct *work) struct led_classdev *led_cdev = trigger_data->led_cdev; int ret; - mutex_lock(&trigger_data->mutex); - - if (!trigger_data->ttyname) { - /* exit without rescheduling */ - mutex_unlock(&trigger_data->mutex); - return; - } + if (!trigger_data->ttyname) + goto out; /* try to get the tty corresponding to $ttyname */ if (!trigger_data->tty) { @@ -117,11 +120,8 @@ static void ledtrig_tty_work(struct work_struct *work) } ret = tty_get_icount(trigger_data->tty, &icount); - if (ret) { - dev_warn(led_cdev->dev, "Failed to get icount, stop polling\n"); - mutex_unlock(&trigger_data->mutex); - return; - } + if (ret) + goto out; if (icount.rx != trigger_data->rx || icount.tx != trigger_data->tx) { @@ -134,7 +134,7 @@ static void ledtrig_tty_work(struct work_struct *work) } out: - mutex_unlock(&trigger_data->mutex); + complete_all(&trigger_data->sysfs); schedule_delayed_work(&trigger_data->dwork, msecs_to_jiffies(LEDTRIG_TTY_INTERVAL * 2)); } @@ -157,7 +157,9 @@ static int ledtrig_tty_activate(struct led_classdev *led_cdev) INIT_DELAYED_WORK(&trigger_data->dwork, ledtrig_tty_work); trigger_data->led_cdev = led_cdev; - mutex_init(&trigger_data->mutex); + init_completion(&trigger_data->sysfs); + + schedule_delayed_work(&trigger_data->dwork, 0); return 0; } From patchwork Mon Nov 6 12:34:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Eckert X-Patchwork-Id: 743224 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 11644C0018A for ; Mon, 6 Nov 2023 12:34:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231630AbjKFMek (ORCPT ); Mon, 6 Nov 2023 07:34:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35932 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231590AbjKFMej (ORCPT ); Mon, 6 Nov 2023 07:34:39 -0500 Received: from mxout70.expurgate.net (mxout70.expurgate.net [91.198.224.70]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0A094B7; Mon, 6 Nov 2023 04:34:35 -0800 (PST) Received: from [127.0.0.1] (helo=localhost) by relay.expurgate.net with smtp (Exim 4.92) (envelope-from ) id 1qzyoH-00CA0X-SH; Mon, 06 Nov 2023 13:34:29 +0100 Received: from [195.243.126.94] (helo=securemail.tdt.de) by relay.expurgate.net with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qzyoH-00DGWh-1Q; Mon, 06 Nov 2023 13:34:29 +0100 Received: from securemail.tdt.de (localhost [127.0.0.1]) by securemail.tdt.de (Postfix) with ESMTP id 9F46124004D; Mon, 6 Nov 2023 13:34:28 +0100 (CET) Received: from mail.dev.tdt.de (unknown [10.2.4.42]) by securemail.tdt.de (Postfix) with ESMTP id F33C6240049; Mon, 6 Nov 2023 13:34:27 +0100 (CET) Received: from localhost.localdomain (unknown [10.2.3.40]) by mail.dev.tdt.de (Postfix) with ESMTPSA id 8FF67227EE; Mon, 6 Nov 2023 13:34:27 +0100 (CET) From: Florian Eckert To: Eckert.Florian@googlemail.com, gregkh@linuxfoundation.org, jirislaby@kernel.org, pavel@ucw.cz, lee@kernel.org, kabel@kernel.org, u.kleine-koenig@pengutronix.de, m.brock@vanmierlo.com Cc: linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, linux-leds@vger.kernel.org Subject: [Patch v7 5/6] leds: ledtrig-tty: make rx tx activitate configurable Date: Mon, 6 Nov 2023 13:34:14 +0100 Message-ID: <20231106123415.3365732-6-fe@dev.tdt.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20231106123415.3365732-1-fe@dev.tdt.de> References: <20231106123415.3365732-1-fe@dev.tdt.de> MIME-Version: 1.0 X-purgate-ID: 151534::1699274069-CF6F53D8-D2756587/0/0 X-purgate: clean X-purgate-type: clean Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org Until now, the LED blinks when data is sent via the tty (rx/tx). This is not configurable. This change adds the possibility to make the indication for the direction of the transmitted data independently controllable via the new rx and tx sysfs entries. - rx: Signal reception (rx) of data on the named tty device. If set to 0, the LED will not blink on reception. If set to 1 (default), the LED will blink on reception. - tx: Signal transmission (tx) of data on the named tty device. If set to 0, the LED will not blink on transmission. If set to 1 (default), the LED will blink on transmission. This new sysfs entry are on by default. Thus the trigger behaves as before this change. Signed-off-by: Florian Eckert --- .../ABI/testing/sysfs-class-led-trigger-tty | 16 +++ drivers/leds/trigger/ledtrig-tty.c | 124 ++++++++++++++++-- 2 files changed, 130 insertions(+), 10 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-led-trigger-tty b/Documentation/ABI/testing/sysfs-class-led-trigger-tty index 2bf6b24e781b..504dece151b8 100644 --- a/Documentation/ABI/testing/sysfs-class-led-trigger-tty +++ b/Documentation/ABI/testing/sysfs-class-led-trigger-tty @@ -4,3 +4,19 @@ KernelVersion: 5.10 Contact: linux-leds@vger.kernel.org Description: Specifies the tty device name of the triggering tty + +What: /sys/class/leds//rx +Date: February 2024 +KernelVersion: 6.8 +Description: + Signal reception (rx) of data on the named tty device. + If set to 0, the LED will not blink on reception. + If set to 1 (default), the LED will blink on reception. + +What: /sys/class/leds//tx +Date: February 2024 +KernelVersion: 6.8 +Description: + Signal transmission (tx) of data on the named tty device. + If set to 0, the LED will not blink on transmission. + If set to 1 (default), the LED will blink on transmission. diff --git a/drivers/leds/trigger/ledtrig-tty.c b/drivers/leds/trigger/ledtrig-tty.c index 3badf74fa420..1a40a78bf1ee 100644 --- a/drivers/leds/trigger/ledtrig-tty.c +++ b/drivers/leds/trigger/ledtrig-tty.c @@ -17,6 +17,19 @@ struct ledtrig_tty_data { const char *ttyname; struct tty_struct *tty; int rx, tx; + bool mode_rx; + bool mode_tx; +}; + +/* Indicates which state the LED should now display */ +enum led_trigger_tty_state { + TTY_LED_BLINK, + TTY_LED_DISABLE, +}; + +enum led_trigger_tty_modes { + TRIGGER_TTY_RX = 0, + TRIGGER_TTY_TX, }; static int ledtrig_tty_waitforcompletion(struct device *dev) @@ -86,12 +99,82 @@ static ssize_t ttyname_store(struct device *dev, } static DEVICE_ATTR_RW(ttyname); +static ssize_t ledtrig_tty_attr_show(struct device *dev, char *buf, + enum led_trigger_tty_modes attr) +{ + struct ledtrig_tty_data *trigger_data = led_trigger_get_drvdata(dev); + int completion; + bool state; + + reinit_completion(&trigger_data->sysfs); + completion = ledtrig_tty_waitforcompletion(dev); + if (completion < 0) + return completion; + + switch (attr) { + case TRIGGER_TTY_RX: + state = trigger_data->mode_rx; + break; + case TRIGGER_TTY_TX: + state = trigger_data->mode_tx; + break; + } + + return sysfs_emit(buf, "%u\n", state); +} + +static ssize_t ledtrig_tty_attr_store(struct device *dev, const char *buf, + size_t size, enum led_trigger_tty_modes attr) +{ + struct ledtrig_tty_data *trigger_data = led_trigger_get_drvdata(dev); + int completion; + bool state; + int ret; + + ret = kstrtobool(buf, &state); + if (ret) + return ret; + + reinit_completion(&trigger_data->sysfs); + completion = ledtrig_tty_waitforcompletion(dev); + if (completion < 0) + return completion; + + switch (attr) { + case TRIGGER_TTY_RX: + trigger_data->mode_rx = state; + break; + case TRIGGER_TTY_TX: + trigger_data->mode_tx = state; + break; + } + + return size; +} + +#define DEFINE_TTY_TRIGGER(trigger_name, trigger) \ + static ssize_t trigger_name##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ + { \ + return ledtrig_tty_attr_show(dev, buf, trigger); \ + } \ + static ssize_t trigger_name##_store(struct device *dev, \ + struct device_attribute *attr, const char *buf, size_t size) \ + { \ + return ledtrig_tty_attr_store(dev, buf, size, trigger); \ + } \ + static DEVICE_ATTR_RW(trigger_name) + +DEFINE_TTY_TRIGGER(rx, TRIGGER_TTY_RX); +DEFINE_TTY_TRIGGER(tx, TRIGGER_TTY_TX); + static void ledtrig_tty_work(struct work_struct *work) { struct ledtrig_tty_data *trigger_data = container_of(work, struct ledtrig_tty_data, dwork.work); - struct serial_icounter_struct icount; struct led_classdev *led_cdev = trigger_data->led_cdev; + enum led_trigger_tty_state state = TTY_LED_DISABLE; + unsigned long interval = LEDTRIG_TTY_INTERVAL; int ret; if (!trigger_data->ttyname) @@ -119,21 +202,36 @@ static void ledtrig_tty_work(struct work_struct *work) trigger_data->tty = tty; } - ret = tty_get_icount(trigger_data->tty, &icount); - if (ret) - goto out; + if (trigger_data->mode_rx || trigger_data->mode_tx) { + struct serial_icounter_struct icount; - if (icount.rx != trigger_data->rx || - icount.tx != trigger_data->tx) { - unsigned long interval = LEDTRIG_TTY_INTERVAL; + ret = tty_get_icount(trigger_data->tty, &icount); + if (ret) + goto out; - led_blink_set_oneshot(led_cdev, &interval, &interval, 0); + if (trigger_data->mode_tx && (icount.tx != trigger_data->tx)) { + trigger_data->tx = icount.tx; + state = TTY_LED_BLINK; + } - trigger_data->rx = icount.rx; - trigger_data->tx = icount.tx; + if (trigger_data->mode_rx && (icount.rx != trigger_data->rx)) { + trigger_data->rx = icount.rx; + state = TTY_LED_BLINK; + } } out: + switch (state) { + case TTY_LED_BLINK: + led_blink_set_oneshot(led_cdev, &interval, &interval, 0); + break; + case TTY_LED_DISABLE: + fallthrough; + default: + led_set_brightness(led_cdev, LED_OFF); + break; + } + complete_all(&trigger_data->sysfs); schedule_delayed_work(&trigger_data->dwork, msecs_to_jiffies(LEDTRIG_TTY_INTERVAL * 2)); @@ -141,6 +239,8 @@ static void ledtrig_tty_work(struct work_struct *work) static struct attribute *ledtrig_tty_attrs[] = { &dev_attr_ttyname.attr, + &dev_attr_rx.attr, + &dev_attr_tx.attr, NULL }; ATTRIBUTE_GROUPS(ledtrig_tty); @@ -153,6 +253,10 @@ static int ledtrig_tty_activate(struct led_classdev *led_cdev) if (!trigger_data) return -ENOMEM; + /* Enable default rx/tx mode */ + trigger_data->mode_rx = true; + trigger_data->mode_tx = true; + led_set_trigger_data(led_cdev, trigger_data); INIT_DELAYED_WORK(&trigger_data->dwork, ledtrig_tty_work); From patchwork Mon Nov 6 12:34:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Eckert X-Patchwork-Id: 741642 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 77B67C4332F for ; Mon, 6 Nov 2023 12:34:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231743AbjKFMet (ORCPT ); Mon, 6 Nov 2023 07:34:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35992 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231671AbjKFMen (ORCPT ); Mon, 6 Nov 2023 07:34:43 -0500 Received: from mxout70.expurgate.net (mxout70.expurgate.net [194.37.255.70]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 68FBCB8; Mon, 6 Nov 2023 04:34:40 -0800 (PST) Received: from [127.0.0.1] (helo=localhost) by relay.expurgate.net with smtp (Exim 4.92) (envelope-from ) id 1qzyoI-00GOQ2-BU; Mon, 06 Nov 2023 13:34:30 +0100 Received: from [195.243.126.94] (helo=securemail.tdt.de) by relay.expurgate.net with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qzyoH-00HTxV-HT; Mon, 06 Nov 2023 13:34:29 +0100 Received: from securemail.tdt.de (localhost [127.0.0.1]) by securemail.tdt.de (Postfix) with ESMTP id 23098240049; Mon, 6 Nov 2023 13:34:29 +0100 (CET) Received: from mail.dev.tdt.de (unknown [10.2.4.42]) by securemail.tdt.de (Postfix) with ESMTP id 773AC240040; Mon, 6 Nov 2023 13:34:28 +0100 (CET) Received: from localhost.localdomain (unknown [10.2.3.40]) by mail.dev.tdt.de (Postfix) with ESMTPSA id F3E8D2225B; Mon, 6 Nov 2023 13:34:27 +0100 (CET) From: Florian Eckert To: Eckert.Florian@googlemail.com, gregkh@linuxfoundation.org, jirislaby@kernel.org, pavel@ucw.cz, lee@kernel.org, kabel@kernel.org, u.kleine-koenig@pengutronix.de, m.brock@vanmierlo.com Cc: linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, linux-leds@vger.kernel.org Subject: [Patch v7 6/6] leds: ledtrig-tty: add additional line state evaluation Date: Mon, 6 Nov 2023 13:34:15 +0100 Message-ID: <20231106123415.3365732-7-fe@dev.tdt.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20231106123415.3365732-1-fe@dev.tdt.de> References: <20231106123415.3365732-1-fe@dev.tdt.de> MIME-Version: 1.0 X-purgate-ID: 151534::1699274070-07E026AA-7D4B33CC/0/0 X-purgate: clean X-purgate-type: clean Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org The serial tty interface also supports additional input signals,that can also be evaluated within this trigger. This change is adding the following additional input sources, which could be controlled via the '/sys/class//' sysfs interface. Explanation: DCE = Data Communication Equipment (Modem) DTE = Data Terminal Equipment (Computer) - cts: DCE is ready to accept data from the DTE (CTS = Clear To Send). If the line state is detected, the LED is switched on. If set to 0 (default), the LED will not evaluate CTS. If set to 1, the LED will evaluate CTS. - dsr: DCE is ready to receive and send data (DSR = Data Set Ready). If the line state is detected, the LED is switched on. If set to 0 (default), the LED will not evaluate DSR. If set to 1, the LED will evaluate DSR. - dcd: DTE is receiving a carrier from the DCE (DCD = Data Carrier Detect). If the line state is detected, the LED is switched on. If set to 0 (default), the LED will not evaluate DCD. If set to 1, the LED will evaluate DCD. - rng: DCE has detected an incoming ring signal on the telephone line (RNG = Ring Indicator). If the line state is detected, the LED is switched on. If set to 0 (default), the LED will not evaluate RNG. If set to 1, the LED will evaluate RNG. Add an invert flag on LED blink, so that the LED blinks in the correct order. * LED was 'on' in the previous round, then it should first go 'off' and then 'on' again when it should blink (data has been transferred). * LED was 'off' in the previous round, then it should first go 'on' and then 'off' again when it should blink (data has been transferred). In order to also evaluate the LED 'state' form the previous round, so we could blink in the correct order, the 'state' must be saved in the trigger data struct. Signed-off-by: Florian Eckert --- .../ABI/testing/sysfs-class-led-trigger-tty | 40 ++++++++ drivers/leds/trigger/ledtrig-tty.c | 91 ++++++++++++++++++- 2 files changed, 126 insertions(+), 5 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-led-trigger-tty b/Documentation/ABI/testing/sysfs-class-led-trigger-tty index 504dece151b8..30cef9ac0f49 100644 --- a/Documentation/ABI/testing/sysfs-class-led-trigger-tty +++ b/Documentation/ABI/testing/sysfs-class-led-trigger-tty @@ -20,3 +20,43 @@ Description: Signal transmission (tx) of data on the named tty device. If set to 0, the LED will not blink on transmission. If set to 1 (default), the LED will blink on transmission. + +What: /sys/class/leds//cts +Date: February 2024 +KernelVersion: 6.8 +Description: + CTS = Clear To Send + DCE is ready to accept data from the DTE. + If the line state is detected, the LED is switched on. + If set to 0 (default), the LED will not evaluate CTS. + If set to 1, the LED will evaluate CTS. + +What: /sys/class/leds//dsr +Date: February 2024 +KernelVersion: 6.8 +Description: + DSR = Data Set Ready + DCE is ready to receive and send data. + If the line state is detected, the LED is switched on. + If set to 0 (default), the LED will not evaluate DSR. + If set to 1, the LED will evaluate DSR. + +What: /sys/class/leds//dcd +Date: February 2024 +KernelVersion: 6.8 +Description: + DCD = Data Carrier Detect + DTE is receiving a carrier from the DCE. + If the line state is detected, the LED is switched on. + If set to 0 (default), the LED will not evaluate CAR (DCD). + If set to 1, the LED will evaluate CAR (DCD). + +What: /sys/class/leds//rng +Date: February 2024 +KernelVersion: 6.8 +Description: + RNG = Ring Indicator + DCE has detected an incoming ring signal on the telephone + line. If the line state is detected, the LED is switched on. + If set to 0 (default), the LED will not evaluate RNG. + If set to 1, the LED will evaluate RNG. diff --git a/drivers/leds/trigger/ledtrig-tty.c b/drivers/leds/trigger/ledtrig-tty.c index 1a40a78bf1ee..107fbbca96de 100644 --- a/drivers/leds/trigger/ledtrig-tty.c +++ b/drivers/leds/trigger/ledtrig-tty.c @@ -17,19 +17,29 @@ struct ledtrig_tty_data { const char *ttyname; struct tty_struct *tty; int rx, tx; + int state; bool mode_rx; bool mode_tx; + bool mode_cts; + bool mode_dsr; + bool mode_dcd; + bool mode_rng; }; /* Indicates which state the LED should now display */ enum led_trigger_tty_state { TTY_LED_BLINK, + TTY_LED_ENABLE, TTY_LED_DISABLE, }; enum led_trigger_tty_modes { TRIGGER_TTY_RX = 0, TRIGGER_TTY_TX, + TRIGGER_TTY_CTS, + TRIGGER_TTY_DSR, + TRIGGER_TTY_DCD, + TRIGGER_TTY_RNG, }; static int ledtrig_tty_waitforcompletion(struct device *dev) @@ -118,6 +128,18 @@ static ssize_t ledtrig_tty_attr_show(struct device *dev, char *buf, case TRIGGER_TTY_TX: state = trigger_data->mode_tx; break; + case TRIGGER_TTY_CTS: + state = trigger_data->mode_cts; + break; + case TRIGGER_TTY_DSR: + state = trigger_data->mode_dsr; + break; + case TRIGGER_TTY_DCD: + state = trigger_data->mode_dcd; + break; + case TRIGGER_TTY_RNG: + state = trigger_data->mode_rng; + break; } return sysfs_emit(buf, "%u\n", state); @@ -147,6 +169,18 @@ static ssize_t ledtrig_tty_attr_store(struct device *dev, const char *buf, case TRIGGER_TTY_TX: trigger_data->mode_tx = state; break; + case TRIGGER_TTY_CTS: + trigger_data->mode_cts = state; + break; + case TRIGGER_TTY_DSR: + trigger_data->mode_dsr = state; + break; + case TRIGGER_TTY_DCD: + trigger_data->mode_dcd = state; + break; + case TRIGGER_TTY_RNG: + trigger_data->mode_rng = state; + break; } return size; @@ -167,16 +201,27 @@ static ssize_t ledtrig_tty_attr_store(struct device *dev, const char *buf, DEFINE_TTY_TRIGGER(rx, TRIGGER_TTY_RX); DEFINE_TTY_TRIGGER(tx, TRIGGER_TTY_TX); +DEFINE_TTY_TRIGGER(cts, TRIGGER_TTY_CTS); +DEFINE_TTY_TRIGGER(dsr, TRIGGER_TTY_DSR); +DEFINE_TTY_TRIGGER(dcd, TRIGGER_TTY_DCD); +DEFINE_TTY_TRIGGER(rng, TRIGGER_TTY_RNG); static void ledtrig_tty_work(struct work_struct *work) { struct ledtrig_tty_data *trigger_data = container_of(work, struct ledtrig_tty_data, dwork.work); struct led_classdev *led_cdev = trigger_data->led_cdev; - enum led_trigger_tty_state state = TTY_LED_DISABLE; unsigned long interval = LEDTRIG_TTY_INTERVAL; + int invert = 0; + int status; int ret; + if (trigger_data->state == TTY_LED_ENABLE) + invert = 1; + + /* Always disable the LED if no evaluation could be done */ + trigger_data->state = TTY_LED_DISABLE; + if (!trigger_data->ttyname) goto out; @@ -202,6 +247,33 @@ static void ledtrig_tty_work(struct work_struct *work) trigger_data->tty = tty; } + status = tty_get_tiocm(trigger_data->tty); + if (status > 0) { + if (trigger_data->mode_cts) { + if (status & TIOCM_CTS) + trigger_data->state = TTY_LED_ENABLE; + } + + if (trigger_data->mode_dsr) { + if (status & TIOCM_DSR) + trigger_data->state = TTY_LED_ENABLE; + } + + if (trigger_data->mode_dcd) { + if (status & TIOCM_CAR) + trigger_data->state = TTY_LED_ENABLE; + } + + if (trigger_data->mode_rng) { + if (status & TIOCM_RNG) + trigger_data->state = TTY_LED_ENABLE; + } + } + + /* + * The evaluation of rx/tx must be done after the evaluation + * of TIOCM_*, because rx/tx has priority. + */ if (trigger_data->mode_rx || trigger_data->mode_tx) { struct serial_icounter_struct icount; @@ -211,19 +283,22 @@ static void ledtrig_tty_work(struct work_struct *work) if (trigger_data->mode_tx && (icount.tx != trigger_data->tx)) { trigger_data->tx = icount.tx; - state = TTY_LED_BLINK; + trigger_data->state = TTY_LED_BLINK; } if (trigger_data->mode_rx && (icount.rx != trigger_data->rx)) { trigger_data->rx = icount.rx; - state = TTY_LED_BLINK; + trigger_data->state = TTY_LED_BLINK; } } out: - switch (state) { + switch (trigger_data->state) { case TTY_LED_BLINK: - led_blink_set_oneshot(led_cdev, &interval, &interval, 0); + led_blink_set_oneshot(led_cdev, &interval, &interval, invert); + break; + case TTY_LED_ENABLE: + led_set_brightness(led_cdev, led_cdev->blink_brightness); break; case TTY_LED_DISABLE: fallthrough; @@ -241,6 +316,10 @@ static struct attribute *ledtrig_tty_attrs[] = { &dev_attr_ttyname.attr, &dev_attr_rx.attr, &dev_attr_tx.attr, + &dev_attr_cts.attr, + &dev_attr_dsr.attr, + &dev_attr_dcd.attr, + &dev_attr_rng.attr, NULL }; ATTRIBUTE_GROUPS(ledtrig_tty); @@ -257,6 +336,8 @@ static int ledtrig_tty_activate(struct led_classdev *led_cdev) trigger_data->mode_rx = true; trigger_data->mode_tx = true; + trigger_data->state = TTY_LED_DISABLE; + led_set_trigger_data(led_cdev, trigger_data); INIT_DELAYED_WORK(&trigger_data->dwork, ledtrig_tty_work);