At the moment the port over-current message is displayed only if the over-current condition is permanent. But in case of permanent short-circuit or over-current, some USB power-distribution switches (such as the TPS20xx, etc.), after the over-current detection and the consequent shutdown, return in the normal state. So, in these cases, the over-current error message never appears. To overcome this problem, the "over-current condition" message is displayed even after a series of some over-current events. Signed-off-by: Flavio Suligoi <f.suligoi@xxxxxxx> --- drivers/usb/core/hub.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 86658a81d284..24ef09ad208b 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -50,6 +50,9 @@ #define USB_TP_TRANSMISSION_DELAY_MAX 65535 /* ns */ #define USB_PING_RESPONSE_TIME 400 /* ns */ +#define USB_OC_COOL_DOWN_TIME 100 /* ms */ +#define USB_OC_REPEATED_MSG_DELAY 2000 /* ms */ + /* Protect struct usb_device->state and ->children members * Note: Both are also protected by ->dev.sem, except that ->state can * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */ @@ -5565,6 +5568,11 @@ static void port_event(struct usb_hub *hub, int port1) } } + /* + * The over-current events can be continuous or intermittent (sometimes + * the event disappears after the cooling-down time); in both cases + * display an error message. + */ if (portchange & USB_PORT_STAT_C_OVERCURRENT) { u16 status = 0, unused; port_dev->over_current_count++; @@ -5574,10 +5582,12 @@ static void port_event(struct usb_hub *hub, int port1) port_dev->over_current_count); usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_OVER_CURRENT); - msleep(100); /* Cool down */ + msleep(USB_OC_COOL_DOWN_TIME); /* Cool down */ hub_power_on(hub, true); hub_port_status(hub, port1, &status, &unused); - if (status & USB_PORT_STAT_OVERCURRENT) + if ((status & USB_PORT_STAT_OVERCURRENT) || + !(port_dev->over_current_count % + (USB_OC_REPEATED_MSG_DELAY / USB_OC_COOL_DOWN_TIME))) dev_err(&port_dev->dev, "over-current condition\n"); } -- 2.25.1