Skip to content

Commit c8d1bc1

Browse files
committed
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 <[email protected]>
2 parents b7a4abb + bbc78c0 commit c8d1bc1

File tree

16 files changed

+59
-28
lines changed

16 files changed

+59
-28
lines changed

drivers/usb/core/hub.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3406,10 +3406,10 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
34063406
if (status) {
34073407
dev_dbg(&port_dev->dev, "can't resume, status %d\n", status);
34083408
} else {
3409-
/* drive resume for at least 20 msec */
3409+
/* drive resume for USB_RESUME_TIMEOUT msec */
34103410
dev_dbg(&udev->dev, "usb %sresume\n",
34113411
(PMSG_IS_AUTO(msg) ? "auto-" : ""));
3412-
msleep(25);
3412+
msleep(USB_RESUME_TIMEOUT);
34133413

34143414
/* Virtual root hubs can trigger on GET_PORT_STATUS to
34153415
* stop resume signaling. Then finish the resume

drivers/usb/dwc2/hcd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1529,7 +1529,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
15291529
dev_dbg(hsotg->dev,
15301530
"ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
15311531
writel(0, hsotg->regs + PCGCTL);
1532-
usleep_range(20000, 40000);
1532+
msleep(USB_RESUME_TIMEOUT);
15331533

15341534
hprt0 = dwc2_read_hprt0(hsotg);
15351535
hprt0 |= HPRT0_RES;

drivers/usb/host/ehci-hcd.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -792,12 +792,12 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
792792
ehci->reset_done[i] == 0))
793793
continue;
794794

795-
/* start 20 msec resume signaling from this port,
796-
* and make hub_wq collect PORT_STAT_C_SUSPEND to
797-
* stop that signaling. Use 5 ms extra for safety,
798-
* like usb_port_resume() does.
795+
/* start USB_RESUME_TIMEOUT msec resume signaling from
796+
* this port, and make hub_wq collect
797+
* PORT_STAT_C_SUSPEND to stop that signaling.
799798
*/
800-
ehci->reset_done[i] = jiffies + msecs_to_jiffies(25);
799+
ehci->reset_done[i] = jiffies +
800+
msecs_to_jiffies(USB_RESUME_TIMEOUT);
801801
set_bit(i, &ehci->resuming_ports);
802802
ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
803803
usb_hcd_start_port_resume(&hcd->self, i);

drivers/usb/host/ehci-hub.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -471,10 +471,13 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
471471
ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
472472
}
473473

474-
/* msleep for 20ms only if code is trying to resume port */
474+
/*
475+
* msleep for USB_RESUME_TIMEOUT ms only if code is trying to resume
476+
* port
477+
*/
475478
if (resume_needed) {
476479
spin_unlock_irq(&ehci->lock);
477-
msleep(20);
480+
msleep(USB_RESUME_TIMEOUT);
478481
spin_lock_irq(&ehci->lock);
479482
if (ehci->shutdown)
480483
goto shutdown;
@@ -942,7 +945,7 @@ int ehci_hub_control(
942945
temp &= ~PORT_WAKE_BITS;
943946
ehci_writel(ehci, temp | PORT_RESUME, status_reg);
944947
ehci->reset_done[wIndex] = jiffies
945-
+ msecs_to_jiffies(20);
948+
+ msecs_to_jiffies(USB_RESUME_TIMEOUT);
946949
set_bit(wIndex, &ehci->resuming_ports);
947950
usb_hcd_start_port_resume(&hcd->self, wIndex);
948951
break;

drivers/usb/host/fotg210-hcd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1595,7 +1595,7 @@ static int fotg210_hub_control(
15951595
/* resume signaling for 20 msec */
15961596
fotg210_writel(fotg210, temp | PORT_RESUME, status_reg);
15971597
fotg210->reset_done[wIndex] = jiffies
1598-
+ msecs_to_jiffies(20);
1598+
+ msecs_to_jiffies(USB_RESUME_TIMEOUT);
15991599
break;
16001600
case USB_PORT_FEAT_C_SUSPEND:
16011601
clear_bit(wIndex, &fotg210->port_c_suspend);

drivers/usb/host/fusbh200-hcd.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,10 +1550,9 @@ static int fusbh200_hub_control (
15501550
if ((temp & PORT_PE) == 0)
15511551
goto error;
15521552

1553-
/* resume signaling for 20 msec */
15541553
fusbh200_writel(fusbh200, temp | PORT_RESUME, status_reg);
15551554
fusbh200->reset_done[wIndex] = jiffies
1556-
+ msecs_to_jiffies(20);
1555+
+ msecs_to_jiffies(USB_RESUME_TIMEOUT);
15571556
break;
15581557
case USB_PORT_FEAT_C_SUSPEND:
15591558
clear_bit(wIndex, &fusbh200->port_c_suspend);

drivers/usb/host/isp116x-hcd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1490,7 +1490,7 @@ static int isp116x_bus_resume(struct usb_hcd *hcd)
14901490
spin_unlock_irq(&isp116x->lock);
14911491

14921492
hcd->state = HC_STATE_RESUMING;
1493-
msleep(20);
1493+
msleep(USB_RESUME_TIMEOUT);
14941494

14951495
/* Go operational */
14961496
spin_lock_irq(&isp116x->lock);

drivers/usb/host/oxu210hp-hcd.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2500,11 +2500,12 @@ static irqreturn_t oxu210_hcd_irq(struct usb_hcd *hcd)
25002500
|| oxu->reset_done[i] != 0)
25012501
continue;
25022502

2503-
/* start 20 msec resume signaling from this port,
2504-
* and make hub_wq collect PORT_STAT_C_SUSPEND to
2503+
/* start USB_RESUME_TIMEOUT resume signaling from this
2504+
* port, and make hub_wq collect PORT_STAT_C_SUSPEND to
25052505
* stop that signaling.
25062506
*/
2507-
oxu->reset_done[i] = jiffies + msecs_to_jiffies(20);
2507+
oxu->reset_done[i] = jiffies +
2508+
msecs_to_jiffies(USB_RESUME_TIMEOUT);
25082509
oxu_dbg(oxu, "port %d remote wakeup\n", i + 1);
25092510
mod_timer(&hcd->rh_timer, oxu->reset_done[i]);
25102511
}

drivers/usb/host/r8a66597-hcd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2301,7 +2301,7 @@ static int r8a66597_bus_resume(struct usb_hcd *hcd)
23012301
rh->port &= ~USB_PORT_STAT_SUSPEND;
23022302
rh->port |= USB_PORT_STAT_C_SUSPEND << 16;
23032303
r8a66597_mdfy(r8a66597, RESUME, RESUME | UACT, dvstctr_reg);
2304-
msleep(50);
2304+
msleep(USB_RESUME_TIMEOUT);
23052305
r8a66597_mdfy(r8a66597, UACT, RESUME | UACT, dvstctr_reg);
23062306
}
23072307

drivers/usb/host/sl811-hcd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1259,7 +1259,7 @@ sl811h_hub_control(
12591259
sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1);
12601260

12611261
mod_timer(&sl811->timer, jiffies
1262-
+ msecs_to_jiffies(20));
1262+
+ msecs_to_jiffies(USB_RESUME_TIMEOUT));
12631263
break;
12641264
case USB_PORT_FEAT_POWER:
12651265
port_power(sl811, 0);

drivers/usb/host/uhci-hub.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ static void uhci_check_ports(struct uhci_hcd *uhci)
166166
/* Port received a wakeup request */
167167
set_bit(port, &uhci->resuming_ports);
168168
uhci->ports_timeout = jiffies +
169-
msecs_to_jiffies(25);
169+
msecs_to_jiffies(USB_RESUME_TIMEOUT);
170170
usb_hcd_start_port_resume(
171171
&uhci_to_hcd(uhci)->self, port);
172172

@@ -338,7 +338,8 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
338338
uhci_finish_suspend(uhci, port, port_addr);
339339

340340
/* USB v2.0 7.1.7.5 */
341-
uhci->ports_timeout = jiffies + msecs_to_jiffies(50);
341+
uhci->ports_timeout = jiffies +
342+
msecs_to_jiffies(USB_RESUME_TIMEOUT);
342343
break;
343344
case USB_PORT_FEAT_POWER:
344345
/* UHCI has no power switching */

drivers/usb/host/xhci-ring.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1574,7 +1574,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
15741574
} else {
15751575
xhci_dbg(xhci, "resume HS port %d\n", port_id);
15761576
bus_state->resume_done[faked_port_index] = jiffies +
1577-
msecs_to_jiffies(20);
1577+
msecs_to_jiffies(USB_RESUME_TIMEOUT);
15781578
set_bit(faked_port_index, &bus_state->resuming_ports);
15791579
mod_timer(&hcd->rh_timer,
15801580
bus_state->resume_done[faked_port_index]);

drivers/usb/isp1760/isp1760-hcd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1869,7 +1869,7 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
18691869
reg_write32(hcd->regs, HC_PORTSC1,
18701870
temp | PORT_RESUME);
18711871
priv->reset_done = jiffies +
1872-
msecs_to_jiffies(20);
1872+
msecs_to_jiffies(USB_RESUME_TIMEOUT);
18731873
}
18741874
break;
18751875
case USB_PORT_FEAT_C_SUSPEND:

drivers/usb/musb/musb_core.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
#include <linux/platform_device.h>
100100
#include <linux/io.h>
101101
#include <linux/dma-mapping.h>
102+
#include <linux/usb.h>
102103

103104
#include "musb_core.h"
104105

@@ -549,7 +550,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
549550
(USB_PORT_STAT_C_SUSPEND << 16)
550551
| MUSB_PORT_STAT_RESUME;
551552
musb->rh_timer = jiffies
552-
+ msecs_to_jiffies(20);
553+
+ msecs_to_jiffies(USB_RESUME_TIMEOUT);
553554
musb->need_finish_resume = 1;
554555

555556
musb->xceiv->otg->state = OTG_STATE_A_HOST;
@@ -2463,7 +2464,7 @@ static int musb_resume(struct device *dev)
24632464
if (musb->need_finish_resume) {
24642465
musb->need_finish_resume = 0;
24652466
schedule_delayed_work(&musb->finish_resume_work,
2466-
msecs_to_jiffies(20));
2467+
msecs_to_jiffies(USB_RESUME_TIMEOUT));
24672468
}
24682469

24692470
/*
@@ -2506,7 +2507,7 @@ static int musb_runtime_resume(struct device *dev)
25062507
if (musb->need_finish_resume) {
25072508
musb->need_finish_resume = 0;
25082509
schedule_delayed_work(&musb->finish_resume_work,
2509-
msecs_to_jiffies(20));
2510+
msecs_to_jiffies(USB_RESUME_TIMEOUT));
25102511
}
25112512

25122513
return 0;

drivers/usb/musb/musb_virthub.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ void musb_port_suspend(struct musb *musb, bool do_suspend)
136136
/* later, GetPortStatus will stop RESUME signaling */
137137
musb->port1_status |= MUSB_PORT_STAT_RESUME;
138138
schedule_delayed_work(&musb->finish_resume_work,
139-
msecs_to_jiffies(20));
139+
msecs_to_jiffies(USB_RESUME_TIMEOUT));
140140
}
141141
}
142142

include/linux/usb.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,32 @@ void usb_put_intf(struct usb_interface *intf);
205205
#define USB_MAXINTERFACES 32
206206
#define USB_MAXIADS (USB_MAXINTERFACES/2)
207207

208+
/*
209+
* USB Resume Timer: Every Host controller driver should drive the resume
210+
* signalling on the bus for the amount of time defined by this macro.
211+
*
212+
* That way we will have a 'stable' behavior among all HCDs supported by Linux.
213+
*
214+
* Note that the USB Specification states we should drive resume for *at least*
215+
* 20 ms, but it doesn't give an upper bound. This creates two possible
216+
* situations which we want to avoid:
217+
*
218+
* (a) sometimes an msleep(20) might expire slightly before 20 ms, which causes
219+
* us to fail USB Electrical Tests, thus failing Certification
220+
*
221+
* (b) Some (many) devices actually need more than 20 ms of resume signalling,
222+
* and while we can argue that's against the USB Specification, we don't have
223+
* control over which devices a certification laboratory will be using for
224+
* certification. If CertLab uses a device which was tested against Windows and
225+
* that happens to have relaxed resume signalling rules, we might fall into
226+
* situations where we fail interoperability and electrical tests.
227+
*
228+
* In order to avoid both conditions, we're using a 40 ms resume timeout, which
229+
* should cope with both LPJ calibration errors and devices not following every
230+
* detail of the USB Specification.
231+
*/
232+
#define USB_RESUME_TIMEOUT 40 /* ms */
233+
208234
/**
209235
* struct usb_interface_cache - long-term representation of a device interface
210236
* @num_altsetting: number of altsettings defined.

0 commit comments

Comments
 (0)