kernel: backport usbport LED trigger driver support for DT
authorRafał Miłecki <rafal@milecki.pl>
Wed, 28 Jun 2017 09:31:14 +0000 (11:31 +0200)
committerRafał Miłecki <rafal@milecki.pl>
Mon, 21 Aug 2017 14:46:18 +0000 (16:46 +0200)
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
target/linux/generic/patches-4.4/084-0003-usb-core-read-USB-ports-from-DT-in-the-usbport-LED-t.patch [new file with mode: 0644]

diff --git a/target/linux/generic/patches-4.4/084-0003-usb-core-read-USB-ports-from-DT-in-the-usbport-LED-t.patch b/target/linux/generic/patches-4.4/084-0003-usb-core-read-USB-ports-from-DT-in-the-usbport-LED-t.patch
new file mode 100644 (file)
index 0000000..65d17c8
--- /dev/null
@@ -0,0 +1,106 @@
+From 4f04c210d031667e503d6538a72345a36f3b5d71 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Thu, 8 Jun 2017 18:08:32 +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
+
+This uses DT info to read relation description of LEDs and USB ports. If
+DT has properly described LEDs, trigger will know when to turn them on.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/ledtrig-usbport.c | 56 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 56 insertions(+)
+
+--- a/drivers/usb/core/ledtrig-usbport.c
++++ b/drivers/usb/core/ledtrig-usbport.c
+@@ -11,8 +11,10 @@
+ #include <linux/device.h>
+ #include <linux/leds.h>
+ #include <linux/module.h>
++#include <linux/of.h>
+ #include <linux/slab.h>
+ #include <linux/usb.h>
++#include <linux/usb/of.h>
+ struct usbport_trig_data {
+       struct led_classdev *led_cdev;
+@@ -123,6 +125,57 @@ static const struct attribute_group port
+  * Adding & removing ports
+  ***************************************/
++/**
++ * usbport_trig_port_observed - Check if port should be observed
++ */
++static bool usbport_trig_port_observed(struct usbport_trig_data *usbport_data,
++                                     struct usb_device *usb_dev, int port1)
++{
++      struct device *dev = usbport_data->led_cdev->dev;
++      struct device_node *led_np = dev->of_node;
++      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 trigger sources for this LED */
++      count = of_count_phandle_with_args(led_np, "trigger-sources",
++                                         "#trigger-source-cells");
++      if (count < 0) {
++              dev_warn(dev, "Failed to get trigger sources for %s\n",
++                       led_np->full_name);
++              return false;
++      }
++
++      /* Check list of sources for this specific port */
++      for (i = 0; i < count; i++) {
++              int err;
++
++              err = of_parse_phandle_with_args(led_np, "trigger-sources",
++                                               "#trigger-source-cells", i,
++                                               &args);
++              if (err) {
++                      dev_err(dev, "Failed to get trigger source 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 +194,8 @@ static int usbport_trig_add_port(struct
+       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
+       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,