|
|
@@ -0,0 +1,179 @@
|
|
|
+From 69bec725985324e79b1c47ea287815ac4ddb0521 Mon Sep 17 00:00:00 2001
|
|
|
+From: Peter Chen <[email protected]>
|
|
|
+Date: Fri, 19 Feb 2016 17:26:15 +0800
|
|
|
+Subject: [PATCH] USB: core: let USB device know device node
|
|
|
+
|
|
|
+Although most of USB devices are hot-plug's, there are still some devices
|
|
|
+are hard wired on the board, eg, for HSIC and SSIC interface USB devices.
|
|
|
+If these kinds of USB devices are multiple functions, and they can supply
|
|
|
+other interfaces like i2c, gpios for other devices, we may need to
|
|
|
+describe these at device tree.
|
|
|
+
|
|
|
+In this commit, it uses "reg" in dts as physical port number to match
|
|
|
+the phyiscal port number decided by USB core, if they are the same,
|
|
|
+then the device node is for the device we are creating for USB core.
|
|
|
+
|
|
|
+Signed-off-by: Peter Chen <[email protected]>
|
|
|
+Acked-by: Philipp Zabel <[email protected]>
|
|
|
+Acked-by: Alan Stern <[email protected]>
|
|
|
+Acked-by: Rob Herring <[email protected]>
|
|
|
+Acked-by: Arnd Bergmann <[email protected]>
|
|
|
+Signed-off-by: Greg Kroah-Hartman <[email protected]>
|
|
|
+---
|
|
|
+ .../devicetree/bindings/usb/usb-device.txt | 28 +++++++++++++
|
|
|
+ drivers/usb/core/Makefile | 2 +-
|
|
|
+ drivers/usb/core/of.c | 47 ++++++++++++++++++++++
|
|
|
+ drivers/usb/core/usb.c | 10 +++++
|
|
|
+ include/linux/usb/of.h | 7 ++++
|
|
|
+ 5 files changed, 93 insertions(+), 1 deletion(-)
|
|
|
+ create mode 100644 Documentation/devicetree/bindings/usb/usb-device.txt
|
|
|
+ create mode 100644 drivers/usb/core/of.c
|
|
|
+
|
|
|
+--- /dev/null
|
|
|
++++ b/Documentation/devicetree/bindings/usb/usb-device.txt
|
|
|
+@@ -0,0 +1,28 @@
|
|
|
++Generic USB Device Properties
|
|
|
++
|
|
|
++Usually, we only use device tree for hard wired USB device.
|
|
|
++The reference binding doc is from:
|
|
|
++http://www.firmware.org/1275/bindings/usb/usb-1_0.ps
|
|
|
++
|
|
|
++Required properties:
|
|
|
++- compatible: usbVID,PID. The textual representation of VID, PID shall
|
|
|
++ be in lower case hexadecimal with leading zeroes suppressed. The
|
|
|
++ other compatible strings from the above standard binding could also
|
|
|
++ be used, but a device adhering to this binding may leave out all except
|
|
|
++ for usbVID,PID.
|
|
|
++- reg: the port number which this device is connecting to, the range
|
|
|
++ is 1-31.
|
|
|
++
|
|
|
++Example:
|
|
|
++
|
|
|
++&usb1 {
|
|
|
++ status = "okay";
|
|
|
++
|
|
|
++ #address-cells = <1>;
|
|
|
++ #size-cells = <0>;
|
|
|
++
|
|
|
++ hub: genesys@1 {
|
|
|
++ compatible = "usb5e3,608";
|
|
|
++ reg = <1>;
|
|
|
++ };
|
|
|
++}
|
|
|
+--- a/drivers/usb/core/Makefile
|
|
|
++++ b/drivers/usb/core/Makefile
|
|
|
+@@ -5,7 +5,7 @@
|
|
|
+ usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o
|
|
|
+ usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o
|
|
|
+ usbcore-y += devio.o notify.o generic.o quirks.o devices.o
|
|
|
+-usbcore-y += port.o
|
|
|
++usbcore-y += port.o of.o
|
|
|
+
|
|
|
+ usbcore-$(CONFIG_PCI) += hcd-pci.o
|
|
|
+ usbcore-$(CONFIG_ACPI) += usb-acpi.o
|
|
|
+--- /dev/null
|
|
|
++++ b/drivers/usb/core/of.c
|
|
|
+@@ -0,0 +1,47 @@
|
|
|
++/*
|
|
|
++ * of.c The helpers for hcd device tree support
|
|
|
++ *
|
|
|
++ * Copyright (C) 2016 Freescale Semiconductor, Inc.
|
|
|
++ * Author: Peter Chen <[email protected]>
|
|
|
++ *
|
|
|
++ * This program is free software: you can redistribute it and/or modify
|
|
|
++ * it under the terms of the GNU General Public License version 2 of
|
|
|
++ * the License as published by the Free Software Foundation.
|
|
|
++ *
|
|
|
++ * This program is distributed in the hope that it will be useful,
|
|
|
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
++ * GNU General Public License for more details.
|
|
|
++ *
|
|
|
++ * You should have received a copy of the GNU General Public License
|
|
|
++ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
++ */
|
|
|
++
|
|
|
++#include <linux/of.h>
|
|
|
++
|
|
|
++/**
|
|
|
++ * usb_of_get_child_node - Find the device node match port number
|
|
|
++ * @parent: the parent device node
|
|
|
++ * @portnum: the port number which device is connecting
|
|
|
++ *
|
|
|
++ * Find the node from device tree according to its port number.
|
|
|
++ *
|
|
|
++ * Return: On success, a pointer to the device node, %NULL on failure.
|
|
|
++ */
|
|
|
++struct device_node *usb_of_get_child_node(struct device_node *parent,
|
|
|
++ int portnum)
|
|
|
++{
|
|
|
++ struct device_node *node;
|
|
|
++ u32 port;
|
|
|
++
|
|
|
++ for_each_child_of_node(parent, node) {
|
|
|
++ if (!of_property_read_u32(node, "reg", &port)) {
|
|
|
++ if (port == portnum)
|
|
|
++ return node;
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
++ return NULL;
|
|
|
++}
|
|
|
++EXPORT_SYMBOL_GPL(usb_of_get_child_node);
|
|
|
++
|
|
|
+--- a/drivers/usb/core/usb.c
|
|
|
++++ b/drivers/usb/core/usb.c
|
|
|
+@@ -36,6 +36,7 @@
|
|
|
+ #include <linux/mutex.h>
|
|
|
+ #include <linux/workqueue.h>
|
|
|
+ #include <linux/debugfs.h>
|
|
|
++#include <linux/usb/of.h>
|
|
|
+
|
|
|
+ #include <asm/io.h>
|
|
|
+ #include <linux/scatterlist.h>
|
|
|
+@@ -469,6 +470,7 @@ struct usb_device *usb_alloc_dev(struct
|
|
|
+ dev->route = 0;
|
|
|
+
|
|
|
+ dev->dev.parent = bus->controller;
|
|
|
++ dev->dev.of_node = bus->controller->of_node;
|
|
|
+ dev_set_name(&dev->dev, "usb%d", bus->busnum);
|
|
|
+ root_hub = 1;
|
|
|
+ } else {
|
|
|
+@@ -493,6 +495,14 @@ struct usb_device *usb_alloc_dev(struct
|
|
|
+ dev->dev.parent = &parent->dev;
|
|
|
+ dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath);
|
|
|
+
|
|
|
++ if (!parent->parent) {
|
|
|
++ /* device under root hub's port */
|
|
|
++ port1 = usb_hcd_find_raw_port_number(usb_hcd,
|
|
|
++ port1);
|
|
|
++ }
|
|
|
++ dev->dev.of_node = usb_of_get_child_node(parent->dev.of_node,
|
|
|
++ port1);
|
|
|
++
|
|
|
+ /* hub driver sets up TT records */
|
|
|
+ }
|
|
|
+
|
|
|
+--- a/include/linux/usb/of.h
|
|
|
++++ b/include/linux/usb/of.h
|
|
|
+@@ -15,6 +15,8 @@
|
|
|
+ bool of_usb_host_tpl_support(struct device_node *np);
|
|
|
+ int of_usb_update_otg_caps(struct device_node *np,
|
|
|
+ struct usb_otg_caps *otg_caps);
|
|
|
++struct device_node *usb_of_get_child_node(struct device_node *parent,
|
|
|
++ int portnum);
|
|
|
+ #else
|
|
|
+ static inline bool of_usb_host_tpl_support(struct device_node *np)
|
|
|
+ {
|
|
|
+@@ -25,6 +27,11 @@ static inline int of_usb_update_otg_caps
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
++static inline struct device_node *usb_of_get_child_node
|
|
|
++ (struct device_node *parent, int portnum)
|
|
|
++{
|
|
|
++ return NULL;
|
|
|
++}
|
|
|
+ #endif
|
|
|
+
|
|
|
+ #if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_USB_SUPPORT)
|