aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2016-02-19 04:26:15 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-03-05 15:05:01 -0500
commit69bec725985324e79b1c47ea287815ac4ddb0521 (patch)
treef6fbc0e6440facdafada6f45af9ec5754190d730
parentd883f52e1f6d2eca8378e3795f333c1396943873 (diff)
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 <peter.chen@freescale.com> Acked-by: Philipp Zabel <p.zabel@pengutronix.de> Acked-by: Alan Stern <stern@rowland.harvard.edu> Acked-by: Rob Herring <robh@kernel.org> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--Documentation/devicetree/bindings/usb/usb-device.txt28
-rw-r--r--drivers/usb/core/Makefile2
-rw-r--r--drivers/usb/core/of.c47
-rw-r--r--drivers/usb/core/usb.c10
-rw-r--r--include/linux/usb/of.h7
5 files changed, 93 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/usb/usb-device.txt b/Documentation/devicetree/bindings/usb/usb-device.txt
new file mode 100644
index 000000000000..1c35e7b665e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/usb-device.txt
@@ -0,0 +1,28 @@
1Generic USB Device Properties
2
3Usually, we only use device tree for hard wired USB device.
4The reference binding doc is from:
5http://www.firmware.org/1275/bindings/usb/usb-1_0.ps
6
7Required properties:
8- compatible: usbVID,PID. The textual representation of VID, PID shall
9 be in lower case hexadecimal with leading zeroes suppressed. The
10 other compatible strings from the above standard binding could also
11 be used, but a device adhering to this binding may leave out all except
12 for usbVID,PID.
13- reg: the port number which this device is connecting to, the range
14 is 1-31.
15
16Example:
17
18&usb1 {
19 status = "okay";
20
21 #address-cells = <1>;
22 #size-cells = <0>;
23
24 hub: genesys@1 {
25 compatible = "usb5e3,608";
26 reg = <1>;
27 };
28}
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index 2f6f93220046..9780877010b4 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -5,7 +5,7 @@
5usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o 5usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o
6usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o 6usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o
7usbcore-y += devio.o notify.o generic.o quirks.o devices.o 7usbcore-y += devio.o notify.o generic.o quirks.o devices.o
8usbcore-y += port.o 8usbcore-y += port.o of.o
9 9
10usbcore-$(CONFIG_PCI) += hcd-pci.o 10usbcore-$(CONFIG_PCI) += hcd-pci.o
11usbcore-$(CONFIG_ACPI) += usb-acpi.o 11usbcore-$(CONFIG_ACPI) += usb-acpi.o
diff --git a/drivers/usb/core/of.c b/drivers/usb/core/of.c
new file mode 100644
index 000000000000..2289700c31d6
--- /dev/null
+++ b/drivers/usb/core/of.c
@@ -0,0 +1,47 @@
1/*
2 * of.c The helpers for hcd device tree support
3 *
4 * Copyright (C) 2016 Freescale Semiconductor, Inc.
5 * Author: Peter Chen <peter.chen@freescale.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 of
9 * the License as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/of.h>
21
22/**
23 * usb_of_get_child_node - Find the device node match port number
24 * @parent: the parent device node
25 * @portnum: the port number which device is connecting
26 *
27 * Find the node from device tree according to its port number.
28 *
29 * Return: On success, a pointer to the device node, %NULL on failure.
30 */
31struct device_node *usb_of_get_child_node(struct device_node *parent,
32 int portnum)
33{
34 struct device_node *node;
35 u32 port;
36
37 for_each_child_of_node(parent, node) {
38 if (!of_property_read_u32(node, "reg", &port)) {
39 if (port == portnum)
40 return node;
41 }
42 }
43
44 return NULL;
45}
46EXPORT_SYMBOL_GPL(usb_of_get_child_node);
47
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 524c9822d2bb..ffa5cf13ffe1 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -36,6 +36,7 @@
36#include <linux/mutex.h> 36#include <linux/mutex.h>
37#include <linux/workqueue.h> 37#include <linux/workqueue.h>
38#include <linux/debugfs.h> 38#include <linux/debugfs.h>
39#include <linux/usb/of.h>
39 40
40#include <asm/io.h> 41#include <asm/io.h>
41#include <linux/scatterlist.h> 42#include <linux/scatterlist.h>
@@ -470,6 +471,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
470 dev->route = 0; 471 dev->route = 0;
471 472
472 dev->dev.parent = bus->controller; 473 dev->dev.parent = bus->controller;
474 dev->dev.of_node = bus->controller->of_node;
473 dev_set_name(&dev->dev, "usb%d", bus->busnum); 475 dev_set_name(&dev->dev, "usb%d", bus->busnum);
474 root_hub = 1; 476 root_hub = 1;
475 } else { 477 } else {
@@ -494,6 +496,14 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
494 dev->dev.parent = &parent->dev; 496 dev->dev.parent = &parent->dev;
495 dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath); 497 dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath);
496 498
499 if (!parent->parent) {
500 /* device under root hub's port */
501 port1 = usb_hcd_find_raw_port_number(usb_hcd,
502 port1);
503 }
504 dev->dev.of_node = usb_of_get_child_node(parent->dev.of_node,
505 port1);
506
497 /* hub driver sets up TT records */ 507 /* hub driver sets up TT records */
498 } 508 }
499 509
diff --git a/include/linux/usb/of.h b/include/linux/usb/of.h
index 974bce93aa28..de3237fce6b2 100644
--- a/include/linux/usb/of.h
+++ b/include/linux/usb/of.h
@@ -16,6 +16,8 @@ enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np);
16bool of_usb_host_tpl_support(struct device_node *np); 16bool of_usb_host_tpl_support(struct device_node *np);
17int of_usb_update_otg_caps(struct device_node *np, 17int of_usb_update_otg_caps(struct device_node *np,
18 struct usb_otg_caps *otg_caps); 18 struct usb_otg_caps *otg_caps);
19struct device_node *usb_of_get_child_node(struct device_node *parent,
20 int portnum);
19#else 21#else
20static inline enum usb_dr_mode 22static inline enum usb_dr_mode
21of_usb_get_dr_mode_by_phy(struct device_node *phy_np) 23of_usb_get_dr_mode_by_phy(struct device_node *phy_np)
@@ -31,6 +33,11 @@ static inline int of_usb_update_otg_caps(struct device_node *np,
31{ 33{
32 return 0; 34 return 0;
33} 35}
36static inline struct device_node *usb_of_get_child_node
37 (struct device_node *parent, int portnum)
38{
39 return NULL;
40}
34#endif 41#endif
35 42
36#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_USB_SUPPORT) 43#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_USB_SUPPORT)