123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- 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,
|