From: Charlie Paul <cpaul.windri...@gmail.com> There exists a race condition when an over-current fault is cleared, between the event processing in the hub_event function and the setting of the event bits in the hub_irq function. When the over-current is cleared the hub_event call tries to read the event bits, which havent been set by the hub_irq. In this patch when the over-current is cleared the hub_event will check the event bits and if they are not set it will pause and check again. It will sync the event bits.
Signed-off-by: Charlie Paul <cpaul.windri...@gmail.com> --- drivers/usb/core/hub.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 35fb2bef..07da7ea 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -5019,8 +5019,8 @@ static void port_event(struct usb_hub *hub, int port1) dev_dbg(&port_dev->dev, "over-current change\n"); usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_OVER_CURRENT); - msleep(100); /* Cool down */ hub_power_on(hub, true); + msleep(100); /* Cool down */ hub_port_status(hub, port1, &status, &unused); if (status & USB_PORT_STAT_OVERCURRENT) dev_err(&port_dev->dev, "over-current condition\n"); @@ -5137,6 +5137,7 @@ static void hub_event(struct work_struct *work) hub->error = 0; } + /* deal with port status changes */ for (i = 1; i <= hdev->maxchild; i++) { struct usb_port *port_dev = hub->ports[i - 1]; @@ -5159,7 +5160,9 @@ static void hub_event(struct work_struct *work) port_event(hub, i); usb_unlock_port(port_dev); pm_runtime_put_sync(&port_dev->dev); - } + } else + /* Wait for the hub_irq to finish then update the port status */ + msleep(100); } /* deal with hub status changes */ -- 2.7.4 -- _______________________________________________ linux-yocto mailing list linux-yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/linux-yocto