mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-09 22:50:41 +00:00
usb: generic resume timeout for v4.1
This part 2 pull request contains only the patches which make sure everybody on linux uses the same resume timeout value. Signed-off-by: Felipe Balbi <balbi@ti.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJVJEivAAoJEIaOsuA1yqREV6QP/1oJVdBxzOeQVXyGZsZT4k0E T8SKmTIJmaCdSjgazSXAhqF7IR992sTM7urHZ2hww3tftODNVHvfFkgDlSguHwkr GV95YpNv99ash7spjod3xVOt8lDvrt6FHs7Foj4b0yQZ1yXUZsOH4j8G4gMYOgTd bq1mO2/NaaM7xiddzPMCGpSkL6NcsWrurJ8JiOlBXaUIkSR+Cwe9+8vzEDrxfSM+ 6yBTLQCdvR0ammqV0YMNsF9dGLO8yiDotC6b104i3yCqpAZnyj0RJQ3riH7ESxsG eSKkCXXGY0OWDGDcnWTskYEHJ7iDfg5MrlzBJyneMjauGKNeIoJRRYWP/f6NSV9m GHxRV1ITKC61Dtt3w+Oy2a16UpAbq7/w1q/SkQl4YtJ8l0P1PUb+TfOZpTOsCLLF cLXUKJufGWhuGbo+e2m6GizNCsDi5LlfdZcjIjVKRXpyiZI0peqyGj16mTm70UUY /A9nsLtE7c6bqHMTcFQFRx4d2iHmkilyzQqOvx4ulo1rovNMafgmZJF7Kq0LY7ZO Uj4s2rEAjqbELbOiEIf8HzGP+J/QuECG4SHyPEQsiG0drYyoCOqGR1S3kV7aJgFz krl4zTvXR8EOk2IpPa8PDzmMr7YCYzlXOxzmSoJiZhqqpLH7cHYkDiRTmyxn+eB3 lEjEzBA8J9CG4iRIFjk3 =RqsO -----END PGP SIGNATURE----- Merge tag 'usb-for-v4.1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-testing Felipe writes: usb: generic resume timeout for v4.1 This part 2 pull request contains only the patches which make sure everybody on linux uses the same resume timeout value. Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
commit
c8d1bc12c7
@ -3406,10 +3406,10 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
|
||||
if (status) {
|
||||
dev_dbg(&port_dev->dev, "can't resume, status %d\n", status);
|
||||
} else {
|
||||
/* drive resume for at least 20 msec */
|
||||
/* drive resume for USB_RESUME_TIMEOUT msec */
|
||||
dev_dbg(&udev->dev, "usb %sresume\n",
|
||||
(PMSG_IS_AUTO(msg) ? "auto-" : ""));
|
||||
msleep(25);
|
||||
msleep(USB_RESUME_TIMEOUT);
|
||||
|
||||
/* Virtual root hubs can trigger on GET_PORT_STATUS to
|
||||
* stop resume signaling. Then finish the resume
|
||||
|
@ -1529,7 +1529,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
|
||||
dev_dbg(hsotg->dev,
|
||||
"ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
|
||||
writel(0, hsotg->regs + PCGCTL);
|
||||
usleep_range(20000, 40000);
|
||||
msleep(USB_RESUME_TIMEOUT);
|
||||
|
||||
hprt0 = dwc2_read_hprt0(hsotg);
|
||||
hprt0 |= HPRT0_RES;
|
||||
|
@ -792,12 +792,12 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
|
||||
ehci->reset_done[i] == 0))
|
||||
continue;
|
||||
|
||||
/* start 20 msec resume signaling from this port,
|
||||
* and make hub_wq collect PORT_STAT_C_SUSPEND to
|
||||
* stop that signaling. Use 5 ms extra for safety,
|
||||
* like usb_port_resume() does.
|
||||
/* start USB_RESUME_TIMEOUT msec resume signaling from
|
||||
* this port, and make hub_wq collect
|
||||
* PORT_STAT_C_SUSPEND to stop that signaling.
|
||||
*/
|
||||
ehci->reset_done[i] = jiffies + msecs_to_jiffies(25);
|
||||
ehci->reset_done[i] = jiffies +
|
||||
msecs_to_jiffies(USB_RESUME_TIMEOUT);
|
||||
set_bit(i, &ehci->resuming_ports);
|
||||
ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
|
||||
usb_hcd_start_port_resume(&hcd->self, i);
|
||||
|
@ -471,10 +471,13 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
|
||||
ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
|
||||
}
|
||||
|
||||
/* msleep for 20ms only if code is trying to resume port */
|
||||
/*
|
||||
* msleep for USB_RESUME_TIMEOUT ms only if code is trying to resume
|
||||
* port
|
||||
*/
|
||||
if (resume_needed) {
|
||||
spin_unlock_irq(&ehci->lock);
|
||||
msleep(20);
|
||||
msleep(USB_RESUME_TIMEOUT);
|
||||
spin_lock_irq(&ehci->lock);
|
||||
if (ehci->shutdown)
|
||||
goto shutdown;
|
||||
@ -942,7 +945,7 @@ int ehci_hub_control(
|
||||
temp &= ~PORT_WAKE_BITS;
|
||||
ehci_writel(ehci, temp | PORT_RESUME, status_reg);
|
||||
ehci->reset_done[wIndex] = jiffies
|
||||
+ msecs_to_jiffies(20);
|
||||
+ msecs_to_jiffies(USB_RESUME_TIMEOUT);
|
||||
set_bit(wIndex, &ehci->resuming_ports);
|
||||
usb_hcd_start_port_resume(&hcd->self, wIndex);
|
||||
break;
|
||||
|
@ -1595,7 +1595,7 @@ static int fotg210_hub_control(
|
||||
/* resume signaling for 20 msec */
|
||||
fotg210_writel(fotg210, temp | PORT_RESUME, status_reg);
|
||||
fotg210->reset_done[wIndex] = jiffies
|
||||
+ msecs_to_jiffies(20);
|
||||
+ msecs_to_jiffies(USB_RESUME_TIMEOUT);
|
||||
break;
|
||||
case USB_PORT_FEAT_C_SUSPEND:
|
||||
clear_bit(wIndex, &fotg210->port_c_suspend);
|
||||
|
@ -1550,10 +1550,9 @@ static int fusbh200_hub_control (
|
||||
if ((temp & PORT_PE) == 0)
|
||||
goto error;
|
||||
|
||||
/* resume signaling for 20 msec */
|
||||
fusbh200_writel(fusbh200, temp | PORT_RESUME, status_reg);
|
||||
fusbh200->reset_done[wIndex] = jiffies
|
||||
+ msecs_to_jiffies(20);
|
||||
+ msecs_to_jiffies(USB_RESUME_TIMEOUT);
|
||||
break;
|
||||
case USB_PORT_FEAT_C_SUSPEND:
|
||||
clear_bit(wIndex, &fusbh200->port_c_suspend);
|
||||
|
@ -1490,7 +1490,7 @@ static int isp116x_bus_resume(struct usb_hcd *hcd)
|
||||
spin_unlock_irq(&isp116x->lock);
|
||||
|
||||
hcd->state = HC_STATE_RESUMING;
|
||||
msleep(20);
|
||||
msleep(USB_RESUME_TIMEOUT);
|
||||
|
||||
/* Go operational */
|
||||
spin_lock_irq(&isp116x->lock);
|
||||
|
@ -2500,11 +2500,12 @@ static irqreturn_t oxu210_hcd_irq(struct usb_hcd *hcd)
|
||||
|| oxu->reset_done[i] != 0)
|
||||
continue;
|
||||
|
||||
/* start 20 msec resume signaling from this port,
|
||||
* and make hub_wq collect PORT_STAT_C_SUSPEND to
|
||||
/* start USB_RESUME_TIMEOUT resume signaling from this
|
||||
* port, and make hub_wq collect PORT_STAT_C_SUSPEND to
|
||||
* stop that signaling.
|
||||
*/
|
||||
oxu->reset_done[i] = jiffies + msecs_to_jiffies(20);
|
||||
oxu->reset_done[i] = jiffies +
|
||||
msecs_to_jiffies(USB_RESUME_TIMEOUT);
|
||||
oxu_dbg(oxu, "port %d remote wakeup\n", i + 1);
|
||||
mod_timer(&hcd->rh_timer, oxu->reset_done[i]);
|
||||
}
|
||||
|
@ -2301,7 +2301,7 @@ static int r8a66597_bus_resume(struct usb_hcd *hcd)
|
||||
rh->port &= ~USB_PORT_STAT_SUSPEND;
|
||||
rh->port |= USB_PORT_STAT_C_SUSPEND << 16;
|
||||
r8a66597_mdfy(r8a66597, RESUME, RESUME | UACT, dvstctr_reg);
|
||||
msleep(50);
|
||||
msleep(USB_RESUME_TIMEOUT);
|
||||
r8a66597_mdfy(r8a66597, UACT, RESUME | UACT, dvstctr_reg);
|
||||
}
|
||||
|
||||
|
@ -1259,7 +1259,7 @@ sl811h_hub_control(
|
||||
sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1);
|
||||
|
||||
mod_timer(&sl811->timer, jiffies
|
||||
+ msecs_to_jiffies(20));
|
||||
+ msecs_to_jiffies(USB_RESUME_TIMEOUT));
|
||||
break;
|
||||
case USB_PORT_FEAT_POWER:
|
||||
port_power(sl811, 0);
|
||||
|
@ -166,7 +166,7 @@ static void uhci_check_ports(struct uhci_hcd *uhci)
|
||||
/* Port received a wakeup request */
|
||||
set_bit(port, &uhci->resuming_ports);
|
||||
uhci->ports_timeout = jiffies +
|
||||
msecs_to_jiffies(25);
|
||||
msecs_to_jiffies(USB_RESUME_TIMEOUT);
|
||||
usb_hcd_start_port_resume(
|
||||
&uhci_to_hcd(uhci)->self, port);
|
||||
|
||||
@ -338,7 +338,8 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
||||
uhci_finish_suspend(uhci, port, port_addr);
|
||||
|
||||
/* USB v2.0 7.1.7.5 */
|
||||
uhci->ports_timeout = jiffies + msecs_to_jiffies(50);
|
||||
uhci->ports_timeout = jiffies +
|
||||
msecs_to_jiffies(USB_RESUME_TIMEOUT);
|
||||
break;
|
||||
case USB_PORT_FEAT_POWER:
|
||||
/* UHCI has no power switching */
|
||||
|
@ -1574,7 +1574,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
|
||||
} else {
|
||||
xhci_dbg(xhci, "resume HS port %d\n", port_id);
|
||||
bus_state->resume_done[faked_port_index] = jiffies +
|
||||
msecs_to_jiffies(20);
|
||||
msecs_to_jiffies(USB_RESUME_TIMEOUT);
|
||||
set_bit(faked_port_index, &bus_state->resuming_ports);
|
||||
mod_timer(&hcd->rh_timer,
|
||||
bus_state->resume_done[faked_port_index]);
|
||||
|
@ -1869,7 +1869,7 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
|
||||
reg_write32(hcd->regs, HC_PORTSC1,
|
||||
temp | PORT_RESUME);
|
||||
priv->reset_done = jiffies +
|
||||
msecs_to_jiffies(20);
|
||||
msecs_to_jiffies(USB_RESUME_TIMEOUT);
|
||||
}
|
||||
break;
|
||||
case USB_PORT_FEAT_C_SUSPEND:
|
||||
|
@ -99,6 +99,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/usb.h>
|
||||
|
||||
#include "musb_core.h"
|
||||
|
||||
@ -549,7 +550,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
|
||||
(USB_PORT_STAT_C_SUSPEND << 16)
|
||||
| MUSB_PORT_STAT_RESUME;
|
||||
musb->rh_timer = jiffies
|
||||
+ msecs_to_jiffies(20);
|
||||
+ msecs_to_jiffies(USB_RESUME_TIMEOUT);
|
||||
musb->need_finish_resume = 1;
|
||||
|
||||
musb->xceiv->otg->state = OTG_STATE_A_HOST;
|
||||
@ -2463,7 +2464,7 @@ static int musb_resume(struct device *dev)
|
||||
if (musb->need_finish_resume) {
|
||||
musb->need_finish_resume = 0;
|
||||
schedule_delayed_work(&musb->finish_resume_work,
|
||||
msecs_to_jiffies(20));
|
||||
msecs_to_jiffies(USB_RESUME_TIMEOUT));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2506,7 +2507,7 @@ static int musb_runtime_resume(struct device *dev)
|
||||
if (musb->need_finish_resume) {
|
||||
musb->need_finish_resume = 0;
|
||||
schedule_delayed_work(&musb->finish_resume_work,
|
||||
msecs_to_jiffies(20));
|
||||
msecs_to_jiffies(USB_RESUME_TIMEOUT));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -136,7 +136,7 @@ void musb_port_suspend(struct musb *musb, bool do_suspend)
|
||||
/* later, GetPortStatus will stop RESUME signaling */
|
||||
musb->port1_status |= MUSB_PORT_STAT_RESUME;
|
||||
schedule_delayed_work(&musb->finish_resume_work,
|
||||
msecs_to_jiffies(20));
|
||||
msecs_to_jiffies(USB_RESUME_TIMEOUT));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,6 +205,32 @@ void usb_put_intf(struct usb_interface *intf);
|
||||
#define USB_MAXINTERFACES 32
|
||||
#define USB_MAXIADS (USB_MAXINTERFACES/2)
|
||||
|
||||
/*
|
||||
* USB Resume Timer: Every Host controller driver should drive the resume
|
||||
* signalling on the bus for the amount of time defined by this macro.
|
||||
*
|
||||
* That way we will have a 'stable' behavior among all HCDs supported by Linux.
|
||||
*
|
||||
* Note that the USB Specification states we should drive resume for *at least*
|
||||
* 20 ms, but it doesn't give an upper bound. This creates two possible
|
||||
* situations which we want to avoid:
|
||||
*
|
||||
* (a) sometimes an msleep(20) might expire slightly before 20 ms, which causes
|
||||
* us to fail USB Electrical Tests, thus failing Certification
|
||||
*
|
||||
* (b) Some (many) devices actually need more than 20 ms of resume signalling,
|
||||
* and while we can argue that's against the USB Specification, we don't have
|
||||
* control over which devices a certification laboratory will be using for
|
||||
* certification. If CertLab uses a device which was tested against Windows and
|
||||
* that happens to have relaxed resume signalling rules, we might fall into
|
||||
* situations where we fail interoperability and electrical tests.
|
||||
*
|
||||
* In order to avoid both conditions, we're using a 40 ms resume timeout, which
|
||||
* should cope with both LPJ calibration errors and devices not following every
|
||||
* detail of the USB Specification.
|
||||
*/
|
||||
#define USB_RESUME_TIMEOUT 40 /* ms */
|
||||
|
||||
/**
|
||||
* struct usb_interface_cache - long-term representation of a device interface
|
||||
* @num_altsetting: number of altsettings defined.
|
||||
|
Loading…
x
Reference in New Issue
Block a user