1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * of.c The helpers for hcd device tree support 4 * 5 * Copyright (C) 2016 Freescale Semiconductor, Inc. 6 * Author: Peter Chen <peter.chen@freescale.com> 7 * Copyright (C) 2017 Johan Hovold <johan@kernel.org> 8 */ 9 10 #include <linux/of.h> 11 #include <linux/usb/of.h> 12 13 /** 14 * usb_of_get_device_node() - get a USB device node 15 * @hub: hub to which device is connected 16 * @port1: one-based index of port 17 * 18 * Look up the node of a USB device given its parent hub device and one-based 19 * port number. 20 * 21 * Return: A pointer to the node with incremented refcount if found, or 22 * %NULL otherwise. 23 */ 24 struct device_node *usb_of_get_device_node(struct usb_device *hub, int port1) 25 { 26 struct device_node *node; 27 u32 reg; 28 29 for_each_child_of_node(hub->dev.of_node, node) { 30 if (of_property_read_u32(node, "reg", ®)) 31 continue; 32 33 if (reg == port1) 34 return node; 35 } 36 37 return NULL; 38 } 39 EXPORT_SYMBOL_GPL(usb_of_get_device_node); 40 41 /** 42 * usb_of_has_combined_node() - determine whether a device has a combined node 43 * @udev: USB device 44 * 45 * Determine whether a USB device has a so called combined node which is 46 * shared with its sole interface. This is the case if and only if the device 47 * has a node and its descriptors report the following: 48 * 49 * 1) bDeviceClass is 0 or 9, and 50 * 2) bNumConfigurations is 1, and 51 * 3) bNumInterfaces is 1. 52 * 53 * Return: True iff the device has a device node and its descriptors match the 54 * criteria for a combined node. 55 */ 56 bool usb_of_has_combined_node(struct usb_device *udev) 57 { 58 struct usb_device_descriptor *ddesc = &udev->descriptor; 59 struct usb_config_descriptor *cdesc; 60 61 if (!udev->dev.of_node) 62 return false; 63 64 switch (ddesc->bDeviceClass) { 65 case USB_CLASS_PER_INTERFACE: 66 case USB_CLASS_HUB: 67 if (ddesc->bNumConfigurations == 1) { 68 cdesc = &udev->config->desc; 69 if (cdesc->bNumInterfaces == 1) 70 return true; 71 } 72 } 73 74 return false; 75 } 76 EXPORT_SYMBOL_GPL(usb_of_has_combined_node); 77 78 /** 79 * usb_of_get_interface_node() - get a USB interface node 80 * @udev: USB device of interface 81 * @config: configuration value 82 * @ifnum: interface number 83 * 84 * Look up the node of a USB interface given its USB device, configuration 85 * value and interface number. 86 * 87 * Return: A pointer to the node with incremented refcount if found, or 88 * %NULL otherwise. 89 */ 90 struct device_node * 91 usb_of_get_interface_node(struct usb_device *udev, u8 config, u8 ifnum) 92 { 93 struct device_node *node; 94 u32 reg[2]; 95 96 for_each_child_of_node(udev->dev.of_node, node) { 97 if (of_property_read_u32_array(node, "reg", reg, 2)) 98 continue; 99 100 if (reg[0] == ifnum && reg[1] == config) 101 return node; 102 } 103 104 return NULL; 105 } 106 EXPORT_SYMBOL_GPL(usb_of_get_interface_node); 107