aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-23 11:20:44 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-23 11:21:03 -0500
commitc69263c66e5b2a5d0c7e5a41c189b1846ae1de92 (patch)
tree81c6cf0f5b3b05739e2e73b0118077d9dd245182 /drivers/usb/host
parent45196cee28a5bcfb6ddbe2bffa4270cbed66ae4b (diff)
parent5407a3c3d942e75d4d123d213fd692bce5acc961 (diff)
Merge branch 'usb-3.3-rc4' into usb-next
This is to pull in the xhci changes and the other fixes and device id updates that were done in Linus's tree. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/ehci-fsl.c14
-rw-r--r--drivers/usb/host/ehci-fsl.h2
-rw-r--r--drivers/usb/host/ehci-hcd.c5
-rw-r--r--drivers/usb/host/ehci-hub.c8
-rw-r--r--drivers/usb/host/ehci-ls1x.c159
-rw-r--r--drivers/usb/host/imx21-dbg.c2
-rw-r--r--drivers/usb/host/uhci-hcd.c3
-rw-r--r--drivers/usb/host/xhci-hub.c41
-rw-r--r--drivers/usb/host/xhci-mem.c11
-rw-r--r--drivers/usb/host/xhci-ring.c74
-rw-r--r--drivers/usb/host/xhci.h1
11 files changed, 303 insertions, 17 deletions
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index c26a82e83f6e..10e008a730a5 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -323,7 +323,9 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
323 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 323 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
324 int retval; 324 int retval;
325 struct fsl_usb2_platform_data *pdata; 325 struct fsl_usb2_platform_data *pdata;
326 struct device *dev;
326 327
328 dev = hcd->self.controller;
327 pdata = hcd->self.controller->platform_data; 329 pdata = hcd->self.controller->platform_data;
328 ehci->big_endian_desc = pdata->big_endian_desc; 330 ehci->big_endian_desc = pdata->big_endian_desc;
329 ehci->big_endian_mmio = pdata->big_endian_mmio; 331 ehci->big_endian_mmio = pdata->big_endian_mmio;
@@ -353,6 +355,16 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
353 355
354 ehci_reset(ehci); 356 ehci_reset(ehci);
355 357
358 if (of_device_is_compatible(dev->parent->of_node,
359 "fsl,mpc5121-usb2-dr")) {
360 /*
361 * set SBUSCFG:AHBBRST so that control msgs don't
362 * fail when doing heavy PATA writes.
363 */
364 ehci_writel(ehci, SBUSCFG_INCR8,
365 hcd->regs + FSL_SOC_USB_SBUSCFG);
366 }
367
356 retval = ehci_fsl_reinit(ehci); 368 retval = ehci_fsl_reinit(ehci);
357 return retval; 369 return retval;
358} 370}
@@ -476,6 +488,8 @@ static int ehci_fsl_mpc512x_drv_resume(struct device *dev)
476 ehci_writel(ehci, ISIPHYCTRL_PXE | ISIPHYCTRL_PHYE, 488 ehci_writel(ehci, ISIPHYCTRL_PXE | ISIPHYCTRL_PHYE,
477 hcd->regs + FSL_SOC_USB_ISIPHYCTRL); 489 hcd->regs + FSL_SOC_USB_ISIPHYCTRL);
478 490
491 ehci_writel(ehci, SBUSCFG_INCR8, hcd->regs + FSL_SOC_USB_SBUSCFG);
492
479 /* restore EHCI registers */ 493 /* restore EHCI registers */
480 ehci_writel(ehci, pdata->pm_command, &ehci->regs->command); 494 ehci_writel(ehci, pdata->pm_command, &ehci->regs->command);
481 ehci_writel(ehci, pdata->pm_intr_enable, &ehci->regs->intr_enable); 495 ehci_writel(ehci, pdata->pm_intr_enable, &ehci->regs->intr_enable);
diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h
index bdf43e2adc51..6d5a94e9bb3c 100644
--- a/drivers/usb/host/ehci-fsl.h
+++ b/drivers/usb/host/ehci-fsl.h
@@ -19,6 +19,8 @@
19#define _EHCI_FSL_H 19#define _EHCI_FSL_H
20 20
21/* offsets for the non-ehci registers in the FSL SOC USB controller */ 21/* offsets for the non-ehci registers in the FSL SOC USB controller */
22#define FSL_SOC_USB_SBUSCFG 0x90
23#define SBUSCFG_INCR8 0x02 /* INCR8, specified */
22#define FSL_SOC_USB_ULPIVP 0x170 24#define FSL_SOC_USB_ULPIVP 0x170
23#define FSL_SOC_USB_PORTSC1 0x184 25#define FSL_SOC_USB_PORTSC1 0x184
24#define PORT_PTS_MSK (3<<30) 26#define PORT_PTS_MSK (3<<30)
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index a007a9fe0f87..4918b0c59af9 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1376,6 +1376,11 @@ MODULE_LICENSE ("GPL");
1376#define PLATFORM_DRIVER ehci_mv_driver 1376#define PLATFORM_DRIVER ehci_mv_driver
1377#endif 1377#endif
1378 1378
1379#ifdef CONFIG_MACH_LOONGSON1
1380#include "ehci-ls1x.c"
1381#define PLATFORM_DRIVER ehci_ls1x_driver
1382#endif
1383
1379#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ 1384#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
1380 !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ 1385 !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
1381 !defined(XILINX_OF_PLATFORM_DRIVER) 1386 !defined(XILINX_OF_PLATFORM_DRIVER)
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 77bbb2357e47..01011dd0cb5d 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -107,7 +107,7 @@ static void ehci_handover_companion_ports(struct ehci_hcd *ehci)
107 ehci->owned_ports = 0; 107 ehci->owned_ports = 0;
108} 108}
109 109
110static int ehci_port_change(struct ehci_hcd *ehci) 110static int __maybe_unused ehci_port_change(struct ehci_hcd *ehci)
111{ 111{
112 int i = HCS_N_PORTS(ehci->hcs_params); 112 int i = HCS_N_PORTS(ehci->hcs_params);
113 113
@@ -1076,7 +1076,8 @@ error_exit:
1076 return retval; 1076 return retval;
1077} 1077}
1078 1078
1079static void ehci_relinquish_port(struct usb_hcd *hcd, int portnum) 1079static void __maybe_unused ehci_relinquish_port(struct usb_hcd *hcd,
1080 int portnum)
1080{ 1081{
1081 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 1082 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
1082 1083
@@ -1085,7 +1086,8 @@ static void ehci_relinquish_port(struct usb_hcd *hcd, int portnum)
1085 set_owner(ehci, --portnum, PORT_OWNER); 1086 set_owner(ehci, --portnum, PORT_OWNER);
1086} 1087}
1087 1088
1088static int ehci_port_handed_over(struct usb_hcd *hcd, int portnum) 1089static int __maybe_unused ehci_port_handed_over(struct usb_hcd *hcd,
1090 int portnum)
1089{ 1091{
1090 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 1092 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
1091 u32 __iomem *reg; 1093 u32 __iomem *reg;
diff --git a/drivers/usb/host/ehci-ls1x.c b/drivers/usb/host/ehci-ls1x.c
new file mode 100644
index 000000000000..a283e59709d6
--- /dev/null
+++ b/drivers/usb/host/ehci-ls1x.c
@@ -0,0 +1,159 @@
1/*
2 * Bus Glue for Loongson LS1X built-in EHCI controller.
3 *
4 * Copyright (c) 2012 Zhang, Keguang <keguang.zhang@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation.
9 */
10
11
12#include <linux/platform_device.h>
13
14static int ehci_ls1x_reset(struct usb_hcd *hcd)
15{
16 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
17 int ret;
18
19 ehci->caps = hcd->regs;
20
21 ret = ehci_setup(hcd);
22 if (ret)
23 return ret;
24
25 ehci_port_power(ehci, 0);
26
27 return 0;
28}
29
30static const struct hc_driver ehci_ls1x_hc_driver = {
31 .description = hcd_name,
32 .product_desc = "LOONGSON1 EHCI",
33 .hcd_priv_size = sizeof(struct ehci_hcd),
34
35 /*
36 * generic hardware linkage
37 */
38 .irq = ehci_irq,
39 .flags = HCD_MEMORY | HCD_USB2,
40
41 /*
42 * basic lifecycle operations
43 */
44 .reset = ehci_ls1x_reset,
45 .start = ehci_run,
46 .stop = ehci_stop,
47 .shutdown = ehci_shutdown,
48
49 /*
50 * managing i/o requests and associated device resources
51 */
52 .urb_enqueue = ehci_urb_enqueue,
53 .urb_dequeue = ehci_urb_dequeue,
54 .endpoint_disable = ehci_endpoint_disable,
55 .endpoint_reset = ehci_endpoint_reset,
56
57 /*
58 * scheduling support
59 */
60 .get_frame_number = ehci_get_frame,
61
62 /*
63 * root hub support
64 */
65 .hub_status_data = ehci_hub_status_data,
66 .hub_control = ehci_hub_control,
67 .relinquish_port = ehci_relinquish_port,
68 .port_handed_over = ehci_port_handed_over,
69
70 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
71};
72
73static int ehci_hcd_ls1x_probe(struct platform_device *pdev)
74{
75 struct usb_hcd *hcd;
76 struct resource *res;
77 int irq;
78 int ret;
79
80 pr_debug("initializing loongson1 ehci USB Controller\n");
81
82 if (usb_disabled())
83 return -ENODEV;
84
85 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
86 if (!res) {
87 dev_err(&pdev->dev,
88 "Found HC with no IRQ. Check %s setup!\n",
89 dev_name(&pdev->dev));
90 return -ENODEV;
91 }
92 irq = res->start;
93
94 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
95 if (!res) {
96 dev_err(&pdev->dev,
97 "Found HC with no register addr. Check %s setup!\n",
98 dev_name(&pdev->dev));
99 return -ENODEV;
100 }
101
102 hcd = usb_create_hcd(&ehci_ls1x_hc_driver, &pdev->dev,
103 dev_name(&pdev->dev));
104 if (!hcd)
105 return -ENOMEM;
106 hcd->rsrc_start = res->start;
107 hcd->rsrc_len = resource_size(res);
108
109 if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
110 dev_dbg(&pdev->dev, "controller already in use\n");
111 ret = -EBUSY;
112 goto err_put_hcd;
113 }
114
115 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
116 if (hcd->regs == NULL) {
117 dev_dbg(&pdev->dev, "error mapping memory\n");
118 ret = -EFAULT;
119 goto err_release_region;
120 }
121
122 ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
123 if (ret)
124 goto err_iounmap;
125
126 return ret;
127
128err_iounmap:
129 iounmap(hcd->regs);
130err_release_region:
131 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
132err_put_hcd:
133 usb_put_hcd(hcd);
134 return ret;
135}
136
137static int ehci_hcd_ls1x_remove(struct platform_device *pdev)
138{
139 struct usb_hcd *hcd = platform_get_drvdata(pdev);
140
141 usb_remove_hcd(hcd);
142 iounmap(hcd->regs);
143 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
144 usb_put_hcd(hcd);
145
146 return 0;
147}
148
149static struct platform_driver ehci_ls1x_driver = {
150 .probe = ehci_hcd_ls1x_probe,
151 .remove = ehci_hcd_ls1x_remove,
152 .shutdown = usb_hcd_platform_shutdown,
153 .driver = {
154 .name = "ls1x-ehci",
155 .owner = THIS_MODULE,
156 },
157};
158
159MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ls1x-ehci");
diff --git a/drivers/usb/host/imx21-dbg.c b/drivers/usb/host/imx21-dbg.c
index 6d7533427163..ec98ecee3517 100644
--- a/drivers/usb/host/imx21-dbg.c
+++ b/drivers/usb/host/imx21-dbg.c
@@ -239,7 +239,7 @@ static int debug_status_show(struct seq_file *s, void *v)
239 "ETDs allocated: %d/%d (max=%d)\n" 239 "ETDs allocated: %d/%d (max=%d)\n"
240 "ETDs in use sw: %d\n" 240 "ETDs in use sw: %d\n"
241 "ETDs in use hw: %d\n" 241 "ETDs in use hw: %d\n"
242 "DMEM alocated: %d/%d (max=%d)\n" 242 "DMEM allocated: %d/%d (max=%d)\n"
243 "DMEM blocks: %d\n" 243 "DMEM blocks: %d\n"
244 "Queued waiting for ETD: %d\n" 244 "Queued waiting for ETD: %d\n"
245 "Queued waiting for DMEM: %d\n", 245 "Queued waiting for DMEM: %d\n",
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 6b5eb1017e2c..e37dea87bb56 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -565,6 +565,9 @@ static int uhci_start(struct usb_hcd *hcd)
565 struct dentry __maybe_unused *dentry; 565 struct dentry __maybe_unused *dentry;
566 566
567 hcd->uses_new_polling = 1; 567 hcd->uses_new_polling = 1;
568 /* Accept arbitrarily long scatter-gather lists */
569 if (!(hcd->driver->flags & HCD_LOCAL_MEM))
570 hcd->self.sg_tablesize = ~0;
568 571
569 spin_lock_init(&uhci->lock); 572 spin_lock_init(&uhci->lock);
570 setup_timer(&uhci->fsbr_timer, uhci_fsbr_timeout, 573 setup_timer(&uhci->fsbr_timer, uhci_fsbr_timeout,
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 557b6f32db86..673ad120c43e 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -422,6 +422,32 @@ void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array,
422 xhci_writel(xhci, temp, port_array[port_id]); 422 xhci_writel(xhci, temp, port_array[port_id]);
423} 423}
424 424
425void xhci_set_remote_wake_mask(struct xhci_hcd *xhci,
426 __le32 __iomem **port_array, int port_id, u16 wake_mask)
427{
428 u32 temp;
429
430 temp = xhci_readl(xhci, port_array[port_id]);
431 temp = xhci_port_state_to_neutral(temp);
432
433 if (wake_mask & USB_PORT_FEAT_REMOTE_WAKE_CONNECT)
434 temp |= PORT_WKCONN_E;
435 else
436 temp &= ~PORT_WKCONN_E;
437
438 if (wake_mask & USB_PORT_FEAT_REMOTE_WAKE_DISCONNECT)
439 temp |= PORT_WKDISC_E;
440 else
441 temp &= ~PORT_WKDISC_E;
442
443 if (wake_mask & USB_PORT_FEAT_REMOTE_WAKE_OVER_CURRENT)
444 temp |= PORT_WKOC_E;
445 else
446 temp &= ~PORT_WKOC_E;
447
448 xhci_writel(xhci, temp, port_array[port_id]);
449}
450
425/* Test and clear port RWC bit */ 451/* Test and clear port RWC bit */
426void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem **port_array, 452void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem **port_array,
427 int port_id, u32 port_bit) 453 int port_id, u32 port_bit)
@@ -448,6 +474,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
448 int slot_id; 474 int slot_id;
449 struct xhci_bus_state *bus_state; 475 struct xhci_bus_state *bus_state;
450 u16 link_state = 0; 476 u16 link_state = 0;
477 u16 wake_mask = 0;
451 478
452 max_ports = xhci_get_ports(hcd, &port_array); 479 max_ports = xhci_get_ports(hcd, &port_array);
453 bus_state = &xhci->bus_state[hcd_index(hcd)]; 480 bus_state = &xhci->bus_state[hcd_index(hcd)];
@@ -593,6 +620,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
593 case SetPortFeature: 620 case SetPortFeature:
594 if (wValue == USB_PORT_FEAT_LINK_STATE) 621 if (wValue == USB_PORT_FEAT_LINK_STATE)
595 link_state = (wIndex & 0xff00) >> 3; 622 link_state = (wIndex & 0xff00) >> 3;
623 if (wValue == USB_PORT_FEAT_REMOTE_WAKE_MASK)
624 wake_mask = wIndex & 0xff00;
596 wIndex &= 0xff; 625 wIndex &= 0xff;
597 if (!wIndex || wIndex > max_ports) 626 if (!wIndex || wIndex > max_ports)
598 goto error; 627 goto error;
@@ -703,6 +732,14 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
703 temp = xhci_readl(xhci, port_array[wIndex]); 732 temp = xhci_readl(xhci, port_array[wIndex]);
704 xhci_dbg(xhci, "set port reset, actual port %d status = 0x%x\n", wIndex, temp); 733 xhci_dbg(xhci, "set port reset, actual port %d status = 0x%x\n", wIndex, temp);
705 break; 734 break;
735 case USB_PORT_FEAT_REMOTE_WAKE_MASK:
736 xhci_set_remote_wake_mask(xhci, port_array,
737 wIndex, wake_mask);
738 temp = xhci_readl(xhci, port_array[wIndex]);
739 xhci_dbg(xhci, "set port remote wake mask, "
740 "actual port %d status = 0x%x\n",
741 wIndex, temp);
742 break;
706 case USB_PORT_FEAT_BH_PORT_RESET: 743 case USB_PORT_FEAT_BH_PORT_RESET:
707 temp |= PORT_WR; 744 temp |= PORT_WR;
708 xhci_writel(xhci, temp, port_array[wIndex]); 745 xhci_writel(xhci, temp, port_array[wIndex]);
@@ -883,6 +920,10 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
883 t2 |= PORT_LINK_STROBE | XDEV_U3; 920 t2 |= PORT_LINK_STROBE | XDEV_U3;
884 set_bit(port_index, &bus_state->bus_suspended); 921 set_bit(port_index, &bus_state->bus_suspended);
885 } 922 }
923 /* USB core sets remote wake mask for USB 3.0 hubs,
924 * including the USB 3.0 roothub, but only if CONFIG_USB_SUSPEND
925 * is enabled, so also enable remote wake here.
926 */
886 if (hcd->self.root_hub->do_remote_wakeup) { 927 if (hcd->self.root_hub->do_remote_wakeup) {
887 if (t1 & PORT_CONNECT) { 928 if (t1 & PORT_CONNECT) {
888 t2 |= PORT_WKOC_E | PORT_WKDISC_E; 929 t2 |= PORT_WKOC_E | PORT_WKDISC_E;
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 383fc857491c..8339d826ce58 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -2157,7 +2157,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
2157 unsigned int val, val2; 2157 unsigned int val, val2;
2158 u64 val_64; 2158 u64 val_64;
2159 struct xhci_segment *seg; 2159 struct xhci_segment *seg;
2160 u32 page_size; 2160 u32 page_size, temp;
2161 int i; 2161 int i;
2162 2162
2163 page_size = xhci_readl(xhci, &xhci->op_regs->page_size); 2163 page_size = xhci_readl(xhci, &xhci->op_regs->page_size);
@@ -2340,6 +2340,15 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
2340 2340
2341 INIT_LIST_HEAD(&xhci->lpm_failed_devs); 2341 INIT_LIST_HEAD(&xhci->lpm_failed_devs);
2342 2342
2343 /* Enable USB 3.0 device notifications for function remote wake, which
2344 * is necessary for allowing USB 3.0 devices to do remote wakeup from
2345 * U3 (device suspend).
2346 */
2347 temp = xhci_readl(xhci, &xhci->op_regs->dev_notification);
2348 temp &= ~DEV_NOTE_MASK;
2349 temp |= DEV_NOTE_FWAKE;
2350 xhci_writel(xhci, temp, &xhci->op_regs->dev_notification);
2351
2343 return 0; 2352 return 0;
2344 2353
2345fail: 2354fail:
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index b62037bff688..3a033240ec64 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1237,6 +1237,26 @@ static unsigned int find_faked_portnum_from_hw_portnum(struct usb_hcd *hcd,
1237 return num_similar_speed_ports; 1237 return num_similar_speed_ports;
1238} 1238}
1239 1239
1240static void handle_device_notification(struct xhci_hcd *xhci,
1241 union xhci_trb *event)
1242{
1243 u32 slot_id;
1244 struct usb_device *udev;
1245
1246 slot_id = TRB_TO_SLOT_ID(event->generic.field[3]);
1247 if (!xhci->devs[slot_id]) {
1248 xhci_warn(xhci, "Device Notification event for "
1249 "unused slot %u\n", slot_id);
1250 return;
1251 }
1252
1253 xhci_dbg(xhci, "Device Wake Notification event for slot ID %u\n",
1254 slot_id);
1255 udev = xhci->devs[slot_id]->udev;
1256 if (udev && udev->parent)
1257 usb_wakeup_notification(udev->parent, udev->portnum);
1258}
1259
1240static void handle_port_status(struct xhci_hcd *xhci, 1260static void handle_port_status(struct xhci_hcd *xhci,
1241 union xhci_trb *event) 1261 union xhci_trb *event)
1242{ 1262{
@@ -1321,20 +1341,21 @@ static void handle_port_status(struct xhci_hcd *xhci,
1321 } 1341 }
1322 1342
1323 if (DEV_SUPERSPEED(temp)) { 1343 if (DEV_SUPERSPEED(temp)) {
1324 xhci_dbg(xhci, "resume SS port %d\n", port_id); 1344 xhci_dbg(xhci, "remote wake SS port %d\n", port_id);
1345 /* Set a flag to say the port signaled remote wakeup,
1346 * so we can tell the difference between the end of
1347 * device and host initiated resume.
1348 */
1349 bus_state->port_remote_wakeup |= 1 << faked_port_index;
1350 xhci_test_and_clear_bit(xhci, port_array,
1351 faked_port_index, PORT_PLC);
1325 xhci_set_link_state(xhci, port_array, faked_port_index, 1352 xhci_set_link_state(xhci, port_array, faked_port_index,
1326 XDEV_U0); 1353 XDEV_U0);
1327 slot_id = xhci_find_slot_id_by_port(hcd, xhci, 1354 /* Need to wait until the next link state change
1328 faked_port_index + 1); 1355 * indicates the device is actually in U0.
1329 if (!slot_id) { 1356 */
1330 xhci_dbg(xhci, "slot_id is zero\n"); 1357 bogus_port_status = true;
1331 goto cleanup; 1358 goto cleanup;
1332 }
1333 xhci_ring_device(xhci, slot_id);
1334 xhci_dbg(xhci, "resume SS port %d finished\n", port_id);
1335 /* Clear PORT_PLC */
1336 xhci_test_and_clear_bit(xhci, port_array,
1337 faked_port_index, PORT_PLC);
1338 } else { 1359 } else {
1339 xhci_dbg(xhci, "resume HS port %d\n", port_id); 1360 xhci_dbg(xhci, "resume HS port %d\n", port_id);
1340 bus_state->resume_done[faked_port_index] = jiffies + 1361 bus_state->resume_done[faked_port_index] = jiffies +
@@ -1345,6 +1366,32 @@ static void handle_port_status(struct xhci_hcd *xhci,
1345 } 1366 }
1346 } 1367 }
1347 1368
1369 if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_U0 &&
1370 DEV_SUPERSPEED(temp)) {
1371 xhci_dbg(xhci, "resume SS port %d finished\n", port_id);
1372 /* We've just brought the device into U0 through either the
1373 * Resume state after a device remote wakeup, or through the
1374 * U3Exit state after a host-initiated resume. If it's a device
1375 * initiated remote wake, don't pass up the link state change,
1376 * so the roothub behavior is consistent with external
1377 * USB 3.0 hub behavior.
1378 */
1379 slot_id = xhci_find_slot_id_by_port(hcd, xhci,
1380 faked_port_index + 1);
1381 if (slot_id && xhci->devs[slot_id])
1382 xhci_ring_device(xhci, slot_id);
1383 if (bus_state->port_remote_wakeup && (1 << faked_port_index)) {
1384 bus_state->port_remote_wakeup &=
1385 ~(1 << faked_port_index);
1386 xhci_test_and_clear_bit(xhci, port_array,
1387 faked_port_index, PORT_PLC);
1388 usb_wakeup_notification(hcd->self.root_hub,
1389 faked_port_index + 1);
1390 bogus_port_status = true;
1391 goto cleanup;
1392 }
1393 }
1394
1348 if (hcd->speed != HCD_USB3) 1395 if (hcd->speed != HCD_USB3)
1349 xhci_test_and_clear_bit(xhci, port_array, faked_port_index, 1396 xhci_test_and_clear_bit(xhci, port_array, faked_port_index,
1350 PORT_PLC); 1397 PORT_PLC);
@@ -2277,6 +2324,9 @@ static int xhci_handle_event(struct xhci_hcd *xhci)
2277 else 2324 else
2278 update_ptrs = 0; 2325 update_ptrs = 0;
2279 break; 2326 break;
2327 case TRB_TYPE(TRB_DEV_NOTE):
2328 handle_device_notification(xhci, event);
2329 break;
2280 default: 2330 default:
2281 if ((le32_to_cpu(event->event_cmd.flags) & TRB_TYPE_BITMASK) >= 2331 if ((le32_to_cpu(event->event_cmd.flags) & TRB_TYPE_BITMASK) >=
2282 TRB_TYPE(48)) 2332 TRB_TYPE(48))
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index fb99c8379142..0f4936956103 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1344,6 +1344,7 @@ struct xhci_bus_state {
1344 /* ports suspend status arrays - max 31 ports for USB2, 15 for USB3 */ 1344 /* ports suspend status arrays - max 31 ports for USB2, 15 for USB3 */
1345 u32 port_c_suspend; 1345 u32 port_c_suspend;
1346 u32 suspended_ports; 1346 u32 suspended_ports;
1347 u32 port_remote_wakeup;
1347 unsigned long resume_done[USB_MAXCHILDREN]; 1348 unsigned long resume_done[USB_MAXCHILDREN];
1348}; 1349};
1349 1350