aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/message.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/message.c')
-rw-r--r--drivers/usb/core/message.c50
1 files changed, 41 insertions, 9 deletions
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 77001bcfc504..c64cf6c4a83d 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -18,6 +18,7 @@
#include <linux/usb/cdc.h>
#include <linux/usb/quirks.h>
#include <linux/usb/hcd.h> /* for usbcore internals */
+#include <linux/usb/of.h>
#include <asm/byteorder.h>
#include "usb.h"
@@ -776,7 +777,7 @@ static int usb_get_langid(struct usb_device *dev, unsigned char *tbuf)
* deal with strings at all. Set string_langid to -1 in order to
* prevent any string to be retrieved from the device */
if (err < 0) {
- dev_err(&dev->dev, "string descriptor 0 read error: %d\n",
+ dev_info(&dev->dev, "string descriptor 0 read error: %d\n",
err);
dev->string_langid = -1;
return -EPIPE;
@@ -915,6 +916,30 @@ int usb_get_device_descriptor(struct usb_device *dev, unsigned int size)
return ret;
}
+/*
+ * usb_set_isoch_delay - informs the device of the packet transmit delay
+ * @dev: the device whose delay is to be informed
+ * Context: !in_interrupt()
+ *
+ * Since this is an optional request, we don't bother if it fails.
+ */
+int usb_set_isoch_delay(struct usb_device *dev)
+{
+ /* skip hub devices */
+ if (dev->descriptor.bDeviceClass == USB_CLASS_HUB)
+ return 0;
+
+ /* skip non-SS/non-SSP devices */
+ if (dev->speed < USB_SPEED_SUPER)
+ return 0;
+
+ return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ USB_REQ_SET_ISOCH_DELAY,
+ USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
+ cpu_to_le16(dev->hub_delay), 0, NULL, 0,
+ USB_CTRL_SET_TIMEOUT);
+}
+
/**
* usb_get_status - issues a GET_STATUS call
* @dev: the device whose status is being checked
@@ -1355,7 +1380,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
* so that the xHCI driver can recalculate the U1/U2 timeouts.
*/
if (usb_disable_lpm(dev)) {
- dev_err(&iface->dev, "%s Failed to disable LPM\n.", __func__);
+ dev_err(&iface->dev, "%s Failed to disable LPM\n", __func__);
mutex_unlock(hcd->bandwidth_mutex);
return -ENOMEM;
}
@@ -1499,7 +1524,7 @@ int usb_reset_configuration(struct usb_device *dev)
* that the xHCI driver can recalculate the U1/U2 timeouts.
*/
if (usb_disable_lpm(dev)) {
- dev_err(&dev->dev, "%s Failed to disable LPM\n.", __func__);
+ dev_err(&dev->dev, "%s Failed to disable LPM\n", __func__);
mutex_unlock(hcd->bandwidth_mutex);
return -ENOMEM;
}
@@ -1583,6 +1608,7 @@ static void usb_release_interface(struct device *dev)
kref_put(&intfc->ref, usb_release_interface_cache);
usb_put_dev(interface_to_usbdev(intf));
+ of_node_put(dev->of_node);
kfree(intf);
}
@@ -1846,7 +1872,7 @@ free_interfaces:
* timeouts.
*/
if (dev->actconfig && usb_disable_lpm(dev)) {
- dev_err(&dev->dev, "%s Failed to disable LPM\n.", __func__);
+ dev_err(&dev->dev, "%s Failed to disable LPM\n", __func__);
mutex_unlock(hcd->bandwidth_mutex);
ret = -ENOMEM;
goto free_interfaces;
@@ -1868,6 +1894,7 @@ free_interfaces:
struct usb_interface_cache *intfc;
struct usb_interface *intf;
struct usb_host_interface *alt;
+ u8 ifnum;
cp->interface[i] = intf = new_interfaces[i];
intfc = cp->intf_cache[i];
@@ -1886,11 +1913,17 @@ free_interfaces:
if (!alt)
alt = &intf->altsetting[0];
- intf->intf_assoc =
- find_iad(dev, cp, alt->desc.bInterfaceNumber);
+ ifnum = alt->desc.bInterfaceNumber;
+ intf->intf_assoc = find_iad(dev, cp, ifnum);
intf->cur_altsetting = alt;
usb_enable_interface(dev, intf, true);
intf->dev.parent = &dev->dev;
+ if (usb_of_has_combined_node(dev)) {
+ device_set_of_node_from_dev(&intf->dev, &dev->dev);
+ } else {
+ intf->dev.of_node = usb_of_get_interface_node(dev,
+ configuration, ifnum);
+ }
intf->dev.driver = NULL;
intf->dev.bus = &usb_bus_type;
intf->dev.type = &usb_if_device_type;
@@ -1905,9 +1938,8 @@ free_interfaces:
intf->minor = -1;
device_initialize(&intf->dev);
pm_runtime_no_callbacks(&intf->dev);
- dev_set_name(&intf->dev, "%d-%s:%d.%d",
- dev->bus->busnum, dev->devpath,
- configuration, alt->desc.bInterfaceNumber);
+ dev_set_name(&intf->dev, "%d-%s:%d.%d", dev->bus->busnum,
+ dev->devpath, configuration, ifnum);
usb_get_dev(dev);
}
kfree(new_interfaces);