From patchwork Tue Feb 28 21:51:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= X-Patchwork-Id: 733898 Return-Path: X-Original-To: incoming-dt@patchwork.ozlabs.org Delivered-To: patchwork-incoming-dt@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3vXsts4dDMz9sNF for ; Wed, 1 Mar 2017 08:59:49 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="OeV8rnuY"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751668AbdB1V7s (ORCPT ); Tue, 28 Feb 2017 16:59:48 -0500 Received: from mail-lf0-f67.google.com ([209.85.215.67]:33774 "EHLO mail-lf0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751534AbdB1V7r (ORCPT ); Tue, 28 Feb 2017 16:59:47 -0500 Received: by mail-lf0-f67.google.com with SMTP id r36so1965011lfi.0 for ; Tue, 28 Feb 2017 13:59:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-transfer-encoding; bh=NkX/RQ7vv7kvA0qkC/dO8rXYZKrodv2g8W1OeixsgUI=; b=OeV8rnuYMgc4n9wyvOgmUpODsMgTHFOUEXdV3FhMqQU2M6xX05sOWjnxgD0R4zzwqB 1mwqnnjhWeLWtIXECthxzZzS2mht8x02BEmtW1I7NjGksNSNGwj2nE6xE/HiUT2cqiZq XFwZ4EgLDEMs2HqkVBJlTaQhJImkXMfGRm1SayN7l1bfX8wGqiLlNRmRb2X05jvoOpps OJTE8g14WpL+fARwr9KRpwNArA+XoLNvgpmz82QYFQ93OfOxG3YHINmE8Ib8aTt0izg3 YKeWbvwe+2NseIXDPbfDjT8XjY8YCgH2i58eNyEgaSsc4hGVYFW/yrlR2jE9wIdWenQk 9wmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding; bh=NkX/RQ7vv7kvA0qkC/dO8rXYZKrodv2g8W1OeixsgUI=; b=X1XDUbto44zB31qRkHzoQlxWMIJetqa5HZhNQYZOtUzW5ycHYONhIiU0E36N7OcJ0t OHfnvNMEEsEK22SPjswhCqnCbAiCVn0t/6O2okwuUiwNwKNrXcODxnlX5eotPMjfbXWt BBhq12p2lXlcXpnHXMrUPw3Puc6htUwRt+Pzj8pPECAXnxR115UPB7tpgUv+VYO/fNVz 7Rr7HsdWxRRGV2A8zKDH3UdUpOaJy/rCT8Hddgj0z7qTH4wGqBciX5qcZ37S+WpCtvFP v/veWcnfhD9sMX/WXy7MBoOudb8unDvcmIya1E8rqKtvm8yHVu9CRFnZNwHxeTl7GfV8 U7Sw== X-Gm-Message-State: AMke39lnabKn9rkO3GYMPoB1r6wWiQ2zhuZFxpTYKYs3T247DuHTy79HVeyJIP+RBbH8Gg== X-Received: by 10.25.204.9 with SMTP id c9mr1440009lfg.107.1488318720091; Tue, 28 Feb 2017 13:52:00 -0800 (PST) Received: from linux-samsung.lan (ip-194-187-74-233.konfederacka.maverick.com.pl. [194.187.74.233]) by smtp.googlemail.com with ESMTPSA id j78sm618789lfg.60.2017.02.28.13.51.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Feb 2017 13:51:59 -0800 (PST) Subject: Re: [PATCH 1/4] dt-bindings: leds: document property for LED triggers To: Jacek Anaszewski , Richard Purdie , linux-leds@vger.kernel.org References: <20170228120452.10043-1-zajec5@gmail.com> Cc: Rob Herring , Mark Rutland , devicetree@vger.kernel.org, =?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?= From: =?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?= Message-ID: <290ed068-2518-50ef-4d02-394bef8b7ee9@gmail.com> Date: Tue, 28 Feb 2017 22:51:58 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.6.0 MIME-Version: 1.0 In-Reply-To: Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org On 02/28/2017 10:38 PM, Jacek Anaszewski wrote: > I think that it would be simpler if we could initially see > a complete sample dts implementation containing all required DT > nodes. The example could contain timer trigger as well as usb-port > trigger specific bindings. Please take a look at attached patch. I used it on Tenda AC9 with: usb_trigger: usb-trigger { trigger-type = "usbport"; ports = <&ohci_port1>, <&ehci_port1>; }; usb { label = "bcm53xx:blue:usb"; gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>; triggers = <&usb_trigger>; }; > I suppose that we should see DT nodes containing #list-cells > properties that define the quantity of phandle arguments. > > It seems that this approach allows for defining a list of elements > with variable number of arguments, i.e. what you were initially > asking for. Are you sure we need #list-cells? Can't we simply use of_count_phandle_with_args(np, "triggers", NULL); ? From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 3 Oct 2016 16:49:05 +0200 Subject: [PATCH] usb: core: read USB ports from DT in the usbport LED trigger driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki --- .../devicetree/bindings/leds/triggers-usbport.txt | 19 ++++++++ drivers/leds/led-triggers.c | 3 +- drivers/usb/core/ledtrig-usbport.c | 56 ++++++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/leds/triggers-usbport.txt diff --git a/Documentation/devicetree/bindings/leds/triggers-usbport.txt b/Documentation/devicetree/bindings/leds/triggers-usbport.txt new file mode 100644 index 000000000000..10e55122cded --- /dev/null +++ b/Documentation/devicetree/bindings/leds/triggers-usbport.txt @@ -0,0 +1,19 @@ +USB port LED trigger properties. + +USB port trigger can be used for signalling to the user a presence of USB +device(s) in given ports. It's possible to specify USB ports in DT by providing +their references. + +Properties: +- trigger-type : Must be "usbport". +- ports : List of USB ports related to this LED. Some devices may have one USB + LED for all ports, other may have few of them (e.g. USB version + specific). It's used by usbport trigger for reading a list of ports + that should cause LED to turn on whenver device get connected. + +Examples: + +usbport-trigger { + trigger-type = "usbport"; + ports = <&ohci_port1>, <&ehci_port1>; +}; diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index c53c20d676cd..1d8bda9755ca 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -181,7 +181,8 @@ static void led_trigger_of_read_trigger(struct led_classdev *led_cdev) } /* Check if trigger specified in DT is supported */ - if (strcmp(trigger_type, "timer")) + if (strcmp(trigger_type, "timer") && + strcmp(trigger_type, "usbport")) goto err_node_put; led_cdev->default_trigger = trigger_type; diff --git a/drivers/usb/core/ledtrig-usbport.c b/drivers/usb/core/ledtrig-usbport.c index 1713248ab15a..599f7e6b0ba8 100644 --- a/drivers/usb/core/ledtrig-usbport.c +++ b/drivers/usb/core/ledtrig-usbport.c @@ -11,8 +11,10 @@ #include #include #include +#include #include #include +#include struct usbport_trig_data { struct led_classdev *led_cdev; @@ -123,6 +125,58 @@ static const struct attribute_group ports_group = { * Adding & removing ports ***************************************/ +/** + * usbport_trig_port_observed - Check if port should be observed + * + * Each LED may have list of related USB ports specified in a DT. This function + * reads them using ports property and sets a proper state. + */ +static bool usbport_trig_port_observed(struct usbport_trig_data *usbport_data, + struct usb_device *usb_dev, int port1) +{ + struct device_node *led_np = usbport_data->led_cdev->trigger_node; + struct device *dev = usbport_data->led_cdev->dev; + struct of_phandle_args args; + struct device_node *port_np; + int count, i; + + if (!led_np) + return false; + + /* Get node of port being added */ + port_np = usb_of_get_child_node(usb_dev->dev.of_node, port1); + if (!port_np) + return false; + + /* Amount of ports this LED references */ + count = of_count_phandle_with_args(led_np, "ports", NULL); + if (count < 0) { + dev_warn(dev, "Failed to get USB ports for %s\n", + led_np->full_name); + return false; + } + + /* Check if port is on this LED's list */ + for (i = 0; i < count; i++) { + int err; + + err = of_parse_phandle_with_args(led_np, "ports", NULL, i, + &args); + if (err) { + dev_err(dev, "Failed to get USB port phandle at index %d: %d\n", + i, err); + continue; + } + + of_node_put(args.np); + + if (args.np == port_np) + return true; + } + + return false; +} + static int usbport_trig_add_port(struct usbport_trig_data *usbport_data, struct usb_device *usb_dev, const char *hub_name, int portnum) @@ -141,6 +195,7 @@ static int usbport_trig_add_port(struct usbport_trig_data *usbport_data, port->data = usbport_data; port->hub = usb_dev; port->portnum = portnum; + port->observed = usbport_trig_port_observed(usbport_data, usb_dev, portnum); len = strlen(hub_name) + 8; port->port_name = kzalloc(len, GFP_KERNEL); @@ -255,6 +310,7 @@ static void usbport_trig_activate(struct led_classdev *led_cdev) if (err) goto err_free; usb_for_each_dev(usbport_data, usbport_trig_add_usb_dev_ports); + usbport_trig_update_count(usbport_data); /* Notifications */ usbport_data->nb.notifier_call = usbport_trig_notify,