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