ehci_hub_control does the following related to overcurrent handling
(simplified):

        temp = ehci_readl(ehci, status_reg);

        if (temp & PORT_OCC) {
                status |= USB_PORT_STAT_C_OVERCURRENT << 16;

                if (temp & PORT_OC) {
                        ehci_port_power(ehci, wIndex, false);
                        temp = ehci_readl(ehci, status_reg);
                }
        }

        if (temp & PORT_OC)
                status |= USB_PORT_STAT_OVERCURRENT;

At least on my i.MX25 based machine rereading the PORTSC register after
port power was removed doesn't yield PORT_OC any more. The result is
that repeatedly changes related to over-current
(status |= USB_PORT_STAT_C_OVERCURRENT << 16) are reported, but
USB_PORT_STAT_OVERCURRENT doesn't toggle as expected and is always
unset. As a side effect the message

        dev_err(&port_dev->dev, "over-current condition\n");

from drivers/usb/core/hub.c's port_event() never makes it to the user.

Rereading the value was introduced with the rationale:

        I also think that the fact that we've cut off the port power
        should be reflected in the result of GetPortStatus request
        immediately, hence I'm adding a PORTSCn register readback after
        write...

As there are no further expected changes, just mask the PORT_POWER bit
instead of rereading the register.

An alternative would be to check for PORT_OC before checking for
PORT_OCC.

Fixes: 81463c1d7071 ("EHCI: only power off port if over-current is active")
Signed-off-by: Uwe Kleine-König <u.kleine-koe...@pengutronix.de>
---
 drivers/usb/host/ehci-hub.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index df169c8e7225..08f59654654b 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -1031,7 +1031,7 @@ int ehci_hub_control(
                                spin_unlock_irqrestore(&ehci->lock, flags);
                                ehci_port_power(ehci, wIndex, false);
                                spin_lock_irqsave(&ehci->lock, flags);
-                               temp = ehci_readl(ehci, status_reg);
+                               temp |= ~PORT_POWER;
                        }
                }
 
-- 
2.14.2

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to