Skip to content

Commit 1cbd53c

Browse files
g0hl1ngregkh
authored andcommitted
usb: core: introduce per-port over-current counters
For some userspace applications information on the number of over-current conditions at specific USB hub ports is relevant. In our case we have a series of USB hardware (using the cp210x driver) which communicates using a proprietary protocol. These devices sometimes trigger an over-current situation on some hubs. In case of such an over-current situation the USB devices offer an interface for reducing the max used power. As these conditions are quite rare and imply performance reductions of the device we don't want to reduce the max power always. Therefore give user-space applications the possibility to react adequately by introducing an over_current_counter in the usb port struct which is exported via sysfs. Signed-off-by: Richard Leitner <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent e3cb7bd commit 1cbd53c

File tree

4 files changed

+24
-1
lines changed

4 files changed

+24
-1
lines changed

Documentation/ABI/testing/sysfs-bus-usb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,16 @@ Description:
189189
The file will read "hotplug", "wired" and "not used" if the
190190
information is available, and "unknown" otherwise.
191191

192+
What: /sys/bus/usb/devices/.../(hub interface)/portX/over_current_count
193+
Date: February 2018
194+
Contact: Richard Leitner <[email protected]>
195+
Description:
196+
Most hubs are able to detect over-current situations on their
197+
ports and report them to the kernel. This attribute is to expose
198+
the number of over-current situation occurred on a specific port
199+
to user space. This file will contain an unsigned 32 bit value
200+
which wraps to 0 after its maximum is reached.
201+
192202
What: /sys/bus/usb/devices/.../(hub interface)/portX/usb3_lpm_permit
193203
Date: November 2015
194204
Contact: Lu Baolu <[email protected]>

drivers/usb/core/hub.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5104,8 +5104,10 @@ static void port_event(struct usb_hub *hub, int port1)
51045104

51055105
if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
51065106
u16 status = 0, unused;
5107+
port_dev->over_current_count++;
51075108

5108-
dev_dbg(&port_dev->dev, "over-current change\n");
5109+
dev_dbg(&port_dev->dev, "over-current change #%u\n",
5110+
port_dev->over_current_count);
51095111
usb_clear_port_feature(hdev, port1,
51105112
USB_PORT_FEAT_C_OVER_CURRENT);
51115113
msleep(100); /* Cool down */

drivers/usb/core/hub.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ struct usb_port {
9696
enum usb_port_connect_type connect_type;
9797
usb_port_location_t location;
9898
struct mutex status_lock;
99+
u32 over_current_count;
99100
u8 portnum;
100101
unsigned int is_superspeed:1;
101102
unsigned int usb3_lpm_u1_permit:1;

drivers/usb/core/port.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ static ssize_t connect_type_show(struct device *dev,
4141
}
4242
static DEVICE_ATTR_RO(connect_type);
4343

44+
static ssize_t over_current_count_show(struct device *dev,
45+
struct device_attribute *attr, char *buf)
46+
{
47+
struct usb_port *port_dev = to_usb_port(dev);
48+
49+
return sprintf(buf, "%u\n", port_dev->over_current_count);
50+
}
51+
static DEVICE_ATTR_RO(over_current_count);
52+
4453
static ssize_t usb3_lpm_permit_show(struct device *dev,
4554
struct device_attribute *attr, char *buf)
4655
{
@@ -109,6 +118,7 @@ static DEVICE_ATTR_RW(usb3_lpm_permit);
109118

110119
static struct attribute *port_dev_attrs[] = {
111120
&dev_attr_connect_type.attr,
121+
&dev_attr_over_current_count.attr,
112122
NULL,
113123
};
114124

0 commit comments

Comments
 (0)