Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1839963/?format=api
{ "id": 1839963, "url": "http://patchwork.ozlabs.org/api/patches/1839963/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/patch/20230926-gpio-led-trigger-dt-v2-3-e06e458b788e@linaro.org/", "project": { "id": 42, "url": "http://patchwork.ozlabs.org/api/projects/42/?format=api", "name": "Linux GPIO development", "link_name": "linux-gpio", "list_id": "linux-gpio.vger.kernel.org", "list_email": "linux-gpio@vger.kernel.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20230926-gpio-led-trigger-dt-v2-3-e06e458b788e@linaro.org>", "list_archive_url": null, "date": "2023-09-26T21:48:13", "name": "[v2,3/3] leds: triggers: gpio: Rewrite to use trigger-sources", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "574c21b2770465be3ae399881e48dd41c4690900", "submitter": { "id": 7055, "url": "http://patchwork.ozlabs.org/api/people/7055/?format=api", "name": "Linus Walleij", "email": "linus.walleij@linaro.org" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-gpio/patch/20230926-gpio-led-trigger-dt-v2-3-e06e458b788e@linaro.org/mbox/", "series": [ { "id": 375009, "url": "http://patchwork.ozlabs.org/api/series/375009/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/list/?series=375009", "date": "2023-09-26T21:48:11", "name": "Rewrite GPIO LED trigger to use trigger-sources", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/375009/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1839963/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1839963/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<linux-gpio-owner@vger.kernel.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256\n header.s=google header.b=EwC4MXuF;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2620:137:e000::1:20; helo=out1.vger.email;\n envelope-from=linux-gpio-owner@vger.kernel.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20])\n\tby legolas.ozlabs.org (Postfix) with ESMTP id 4RwFFy1KqZz1ypJ\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 27 Sep 2023 08:45:58 +1000 (AEST)", "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n id S230197AbjIZWpz (ORCPT <rfc822;incoming@patchwork.ozlabs.org>);\n Tue, 26 Sep 2023 18:45:55 -0400", "from lindbergh.monkeyblade.net ([23.128.96.19]:40992 \"EHLO\n lindbergh.monkeyblade.net\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n with ESMTP id S230525AbjIZWny (ORCPT\n <rfc822;linux-gpio@vger.kernel.org>); Tue, 26 Sep 2023 18:43:54 -0400", "from mail-lj1-x22d.google.com (mail-lj1-x22d.google.com\n [IPv6:2a00:1450:4864:20::22d])\n by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8180218E83\n for <linux-gpio@vger.kernel.org>;\n Tue, 26 Sep 2023 14:48:19 -0700 (PDT)", "by mail-lj1-x22d.google.com with SMTP id\n 38308e7fff4ca-2c12ae20a5cso159623261fa.2\n for <linux-gpio@vger.kernel.org>;\n Tue, 26 Sep 2023 14:48:19 -0700 (PDT)", "from [127.0.1.1] ([85.235.12.238])\n by smtp.gmail.com with ESMTPSA id\n f10-20020a19ae0a000000b0050334e5f5a8sm2299982lfc.271.2023.09.26.14.48.16\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 26 Sep 2023 14:48:17 -0700 (PDT)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=linaro.org; s=google; t=1695764897; x=1696369697;\n darn=vger.kernel.org;\n h=cc:to:in-reply-to:references:message-id:content-transfer-encoding\n :mime-version:subject:date:from:from:to:cc:subject:date:message-id\n :reply-to;\n bh=xCuTZhEJPz8ZqCyb/xY7ocE2o3PkqDSRE/J2TdY26/o=;\n b=EwC4MXuFj2KrB2CN2IakXRhv5gAh+jzTrViJkl4faVqa7/m+CPj2MsgMeoYlfFg3Qi\n Z/2oI2zSMem1yHL/Jl9EyPTjQ7Od0aGyjNcFNIP85BuO9CqUDh54hBLaJKg6H5cp9nY/\n PUdSuVqYxewnn9KlRtU/M1niG5mLWe+CI2hVdqK5NtEu1znrl12OMzk7FZTo0L1esxRq\n JRVCnXFkJTBprlSdbbOypOSCmPkMlEuqrhGwnqr3XhOrIuYSb0A1Vx7hE+DSYhLYBBjV\n wwN4ucX+T8qngUMQt87HlTOwkp4BVoPJ9pCHCg4O/k2KZGrShpjOHaXzlh9XQugO59Rq\n G8Mg==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1695764897; x=1696369697;\n h=cc:to:in-reply-to:references:message-id:content-transfer-encoding\n :mime-version:subject:date:from:x-gm-message-state:from:to:cc\n :subject:date:message-id:reply-to;\n bh=xCuTZhEJPz8ZqCyb/xY7ocE2o3PkqDSRE/J2TdY26/o=;\n b=TkUV2lcM7c528Sr8hJBUFegu1CX738pZW48nkEWNOUci3ocNwOklCAr2s/lpGUAlcu\n 7HT8Jt+PxXPFO5uH83TAo9a7HpopbNES195LcPIZrA1l3Bjis/K8MbYQFSjGGM21JB8w\n qXS3didgPHxBDBjo//3xW9IV2Ea8MHOMdcNb7ILGS0MNRNkJoNJ2Aiv/ceU3m9PatIpp\n dkGzV2B/QmNcgp9e7PMzG8gY79knIfbF8o1768xrmzcwnWyjaCFQPI3g0egI6GwzDJMX\n WhJPc3XMv3LwszXuvApTQxcR0NGm99znHk0uTpnOHG4bs3KFcaLMF6xlmEiOzqneQvF7\n htHw==", "X-Gm-Message-State": "AOJu0YyYK4UeoDYMRjeYKZNJxgbdzj64/4aPRLxvyg7WaG/Ceb2uKo+a\n tZXpDXqcYpJhECxt0kgh2AfGMg==", "X-Google-Smtp-Source": "\n AGHT+IGBrC0bECecJjFp+EqYLonAlaFQLJT/bnX6STpQt3TRBoCa+su9DN31qD3xXpVwLjbs+7PzsA==", "X-Received": "by 2002:ac2:58ef:0:b0:503:9c2:e44e with SMTP id\n v15-20020ac258ef000000b0050309c2e44emr16458lfo.55.1695764897557;\n Tue, 26 Sep 2023 14:48:17 -0700 (PDT)", "From": "Linus Walleij <linus.walleij@linaro.org>", "Date": "Tue, 26 Sep 2023 23:48:13 +0200", "Subject": "[PATCH v2 3/3] leds: triggers: gpio: Rewrite to use\n trigger-sources", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "7bit", "Message-Id": "<20230926-gpio-led-trigger-dt-v2-3-e06e458b788e@linaro.org>", "References": "<20230926-gpio-led-trigger-dt-v2-0-e06e458b788e@linaro.org>", "In-Reply-To": "<20230926-gpio-led-trigger-dt-v2-0-e06e458b788e@linaro.org>", "To": "=?utf-8?q?Jan_Kundr=C3=A1t?= <jan.kundrat@cesnet.cz>,\n Pavel Machek <pavel@ucw.cz>, Lee Jones <lee@kernel.org>,\n Rob Herring <robh+dt@kernel.org>,\n Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,\n Conor Dooley <conor+dt@kernel.org>,\n Jacek Anaszewski <jacek.anaszewski@gmail.com>", "Cc": "linux-leds@vger.kernel.org, linux-gpio@vger.kernel.org,\n devicetree@vger.kernel.org,\n Linus Walleij <linus.walleij@linaro.org>", "X-Mailer": "b4 0.12.3", "X-Spam-Status": "No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,\n DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE,\n SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no\n version=3.4.6", "X-Spam-Checker-Version": "SpamAssassin 3.4.6 (2021-04-09) on\n lindbergh.monkeyblade.net", "Precedence": "bulk", "List-ID": "<linux-gpio.vger.kernel.org>", "X-Mailing-List": "linux-gpio@vger.kernel.org" }, "content": "By providing a GPIO line as \"trigger-sources\" in the FWNODE\n(such as from the device tree) and combining with the\nGPIO trigger, we can support a GPIO LED trigger in a natural\nway from the hardware description instead of using the\ncustom sysfs and deprecated global GPIO numberspace.\n\nExample:\n\ngpio: gpio@0 {\n compatible \"my-gpio\";\n gpio-controller;\n #gpio-cells = <2>;\n interrupt-controller;\n #interrupt-cells = <2>;\n #trigger-source-cells = <2>;\n};\n\nleds {\n compatible = \"gpio-leds\";\n led-my-gpio {\n label = \"device:blue:myled\";\n gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;\n default-state = \"off\";\n linux,default-trigger = \"gpio\";\n trigger-sources = <&gpio 1 GPIO_ACTIVE_HIGH>;\n };\n};\n\nMake this the norm, unmark the driver as broken.\n\nDelete the sysfs handling of GPIOs.\n\nSince GPIO descriptors inherently can describe inversion,\nthe inversion handling can just be deleted.\n\nSigned-off-by: Linus Walleij <linus.walleij@linaro.org>\n---\nChangeLog v1->v2:\n- Fix a use-after-free bug found by Dan Carpenter\n---\n drivers/leds/trigger/Kconfig | 5 +-\n drivers/leds/trigger/ledtrig-gpio.c | 137 +++++++++++-------------------------\n 2 files changed, 41 insertions(+), 101 deletions(-)", "diff": "diff --git a/drivers/leds/trigger/Kconfig b/drivers/leds/trigger/Kconfig\nindex 2a57328eca20..d11d80176fc0 100644\n--- a/drivers/leds/trigger/Kconfig\n+++ b/drivers/leds/trigger/Kconfig\n@@ -83,13 +83,10 @@ config LEDS_TRIGGER_ACTIVITY\n config LEDS_TRIGGER_GPIO\n \ttristate \"LED GPIO Trigger\"\n \tdepends on GPIOLIB || COMPILE_TEST\n-\tdepends on BROKEN\n \thelp\n \t This allows LEDs to be controlled by gpio events. It's good\n \t when using gpios as switches and triggering the needed LEDs\n-\t from there. One use case is n810's keypad LEDs that could\n-\t be triggered by this trigger when user slides up to show\n-\t keypad.\n+\t from there. Triggers are defined as device properties.\n \n \t If unsure, say N.\n \ndiff --git a/drivers/leds/trigger/ledtrig-gpio.c b/drivers/leds/trigger/ledtrig-gpio.c\nindex 0120faa3dafa..9b7fe5dd5208 100644\n--- a/drivers/leds/trigger/ledtrig-gpio.c\n+++ b/drivers/leds/trigger/ledtrig-gpio.c\n@@ -3,12 +3,13 @@\n * ledtrig-gio.c - LED Trigger Based on GPIO events\n *\n * Copyright 2009 Felipe Balbi <me@felipebalbi.com>\n+ * Copyright 2023 Linus Walleij <linus.walleij@linaro.org>\n */\n \n #include <linux/module.h>\n #include <linux/kernel.h>\n #include <linux/init.h>\n-#include <linux/gpio.h>\n+#include <linux/gpio/consumer.h>\n #include <linux/interrupt.h>\n #include <linux/leds.h>\n #include <linux/slab.h>\n@@ -16,10 +17,8 @@\n \n struct gpio_trig_data {\n \tstruct led_classdev *led;\n-\n \tunsigned desired_brightness;\t/* desired brightness when led is on */\n-\tunsigned inverted;\t\t/* true when gpio is inverted */\n-\tunsigned gpio;\t\t\t/* gpio that triggers the leds */\n+\tstruct gpio_desc *gpiod;\t/* gpio that triggers the led */\n };\n \n static irqreturn_t gpio_trig_irq(int irq, void *_led)\n@@ -28,10 +27,7 @@ static irqreturn_t gpio_trig_irq(int irq, void *_led)\n \tstruct gpio_trig_data *gpio_data = led_get_trigger_data(led);\n \tint tmp;\n \n-\ttmp = gpio_get_value_cansleep(gpio_data->gpio);\n-\tif (gpio_data->inverted)\n-\t\ttmp = !tmp;\n-\n+\ttmp = gpiod_get_value_cansleep(gpio_data->gpiod);\n \tif (tmp) {\n \t\tif (gpio_data->desired_brightness)\n \t\t\tled_set_brightness_nosleep(gpio_data->led,\n@@ -73,93 +69,8 @@ static ssize_t gpio_trig_brightness_store(struct device *dev,\n static DEVICE_ATTR(desired_brightness, 0644, gpio_trig_brightness_show,\n \t\tgpio_trig_brightness_store);\n \n-static ssize_t gpio_trig_inverted_show(struct device *dev,\n-\t\tstruct device_attribute *attr, char *buf)\n-{\n-\tstruct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev);\n-\n-\treturn sprintf(buf, \"%u\\n\", gpio_data->inverted);\n-}\n-\n-static ssize_t gpio_trig_inverted_store(struct device *dev,\n-\t\tstruct device_attribute *attr, const char *buf, size_t n)\n-{\n-\tstruct led_classdev *led = led_trigger_get_led(dev);\n-\tstruct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev);\n-\tunsigned long inverted;\n-\tint ret;\n-\n-\tret = kstrtoul(buf, 10, &inverted);\n-\tif (ret < 0)\n-\t\treturn ret;\n-\n-\tif (inverted > 1)\n-\t\treturn -EINVAL;\n-\n-\tgpio_data->inverted = inverted;\n-\n-\t/* After inverting, we need to update the LED. */\n-\tif (gpio_is_valid(gpio_data->gpio))\n-\t\tgpio_trig_irq(0, led);\n-\n-\treturn n;\n-}\n-static DEVICE_ATTR(inverted, 0644, gpio_trig_inverted_show,\n-\t\tgpio_trig_inverted_store);\n-\n-static ssize_t gpio_trig_gpio_show(struct device *dev,\n-\t\tstruct device_attribute *attr, char *buf)\n-{\n-\tstruct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev);\n-\n-\treturn sprintf(buf, \"%u\\n\", gpio_data->gpio);\n-}\n-\n-static ssize_t gpio_trig_gpio_store(struct device *dev,\n-\t\tstruct device_attribute *attr, const char *buf, size_t n)\n-{\n-\tstruct led_classdev *led = led_trigger_get_led(dev);\n-\tstruct gpio_trig_data *gpio_data = led_trigger_get_drvdata(dev);\n-\tunsigned gpio;\n-\tint ret;\n-\n-\tret = sscanf(buf, \"%u\", &gpio);\n-\tif (ret < 1) {\n-\t\tdev_err(dev, \"couldn't read gpio number\\n\");\n-\t\treturn -EINVAL;\n-\t}\n-\n-\tif (gpio_data->gpio == gpio)\n-\t\treturn n;\n-\n-\tif (!gpio_is_valid(gpio)) {\n-\t\tif (gpio_is_valid(gpio_data->gpio))\n-\t\t\tfree_irq(gpio_to_irq(gpio_data->gpio), led);\n-\t\tgpio_data->gpio = gpio;\n-\t\treturn n;\n-\t}\n-\n-\tret = request_threaded_irq(gpio_to_irq(gpio), NULL, gpio_trig_irq,\n-\t\t\tIRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_RISING\n-\t\t\t| IRQF_TRIGGER_FALLING, \"ledtrig-gpio\", led);\n-\tif (ret) {\n-\t\tdev_err(dev, \"request_irq failed with error %d\\n\", ret);\n-\t} else {\n-\t\tif (gpio_is_valid(gpio_data->gpio))\n-\t\t\tfree_irq(gpio_to_irq(gpio_data->gpio), led);\n-\t\tgpio_data->gpio = gpio;\n-\t\t/* After changing the GPIO, we need to update the LED. */\n-\t\tgpio_trig_irq(0, led);\n-\t}\n-\n-\treturn ret ? ret : n;\n-}\n-static DEVICE_ATTR(gpio, 0644, gpio_trig_gpio_show, gpio_trig_gpio_store);\n-\n static struct attribute *gpio_trig_attrs[] = {\n \t&dev_attr_desired_brightness.attr,\n-\t&dev_attr_inverted.attr,\n-\t&dev_attr_gpio.attr,\n \tNULL\n };\n ATTRIBUTE_GROUPS(gpio_trig);\n@@ -167,16 +78,48 @@ ATTRIBUTE_GROUPS(gpio_trig);\n static int gpio_trig_activate(struct led_classdev *led)\n {\n \tstruct gpio_trig_data *gpio_data;\n+\tstruct device *dev = led->dev;\n+\tint ret;\n \n \tgpio_data = kzalloc(sizeof(*gpio_data), GFP_KERNEL);\n \tif (!gpio_data)\n \t\treturn -ENOMEM;\n \n-\tgpio_data->led = led;\n-\tgpio_data->gpio = -ENOENT;\n+\t/*\n+\t * The generic property \"trigger-sources\" is followed,\n+\t * and we hope that this is a GPIO.\n+\t */\n+\tgpio_data->gpiod = fwnode_gpiod_get_index(dev->fwnode,\n+\t\t\t\t\t\t \"trigger-sources\",\n+\t\t\t\t\t\t 0, GPIOD_IN,\n+\t\t\t\t\t\t \"led-trigger\");\n+\tif (IS_ERR(gpio_data->gpiod)) {\n+\t\tret = PTR_ERR(gpio_data->gpiod);\n+\t\tkfree(gpio_data);\n+\t\treturn ret;\n+\t}\n+\tif (!gpio_data->gpiod) {\n+\t\tdev_err(dev, \"no valid GPIO for the trigger\\n\");\n+\t\tkfree(gpio_data);\n+\t\treturn -EINVAL;\n+\t}\n \n+\tgpio_data->led = led;\n \tled_set_trigger_data(led, gpio_data);\n \n+\tret = request_threaded_irq(gpiod_to_irq(gpio_data->gpiod), NULL, gpio_trig_irq,\n+\t\t\tIRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_RISING\n+\t\t\t| IRQF_TRIGGER_FALLING, \"ledtrig-gpio\", led);\n+\tif (ret) {\n+\t\tdev_err(dev, \"request_irq failed with error %d\\n\", ret);\n+\t\tgpiod_put(gpio_data->gpiod);\n+\t\tkfree(gpio_data);\n+\t\treturn ret;\n+\t}\n+\n+\t/* Finally update the LED to initial status */\n+\tgpio_trig_irq(0, led);\n+\n \treturn 0;\n }\n \n@@ -184,8 +127,8 @@ static void gpio_trig_deactivate(struct led_classdev *led)\n {\n \tstruct gpio_trig_data *gpio_data = led_get_trigger_data(led);\n \n-\tif (gpio_is_valid(gpio_data->gpio))\n-\t\tfree_irq(gpio_to_irq(gpio_data->gpio), led);\n+\tfree_irq(gpiod_to_irq(gpio_data->gpiod), led);\n+\tgpiod_put(gpio_data->gpiod);\n \tkfree(gpio_data);\n }\n \n", "prefixes": [ "v2", "3/3" ] }