[PATCH v2] usb: core: hub: improve port over-current alert msg

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux