Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 289438
b: refs/heads/master
c: 623bef9
h: refs/heads/master
v: v3
  • Loading branch information
Sarah Sharp committed Feb 14, 2012
1 parent 86b1955 commit 206046a
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d93814cfadb131fb219359d4b7008c728421c552
refs/heads/master: 623bef9e03a60adc623b09673297ca7a1cdfb367
25 changes: 20 additions & 5 deletions trunk/drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -2421,11 +2421,26 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
* we don't explicitly enable it here.
*/
if (udev->do_remote_wakeup) {
status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
USB_REQ_SET_FEATURE, USB_RECIP_DEVICE,
USB_DEVICE_REMOTE_WAKEUP, 0,
NULL, 0,
USB_CTRL_SET_TIMEOUT);
if (!hub_is_superspeed(hub->hdev)) {
status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
USB_REQ_SET_FEATURE, USB_RECIP_DEVICE,
USB_DEVICE_REMOTE_WAKEUP, 0,
NULL, 0,
USB_CTRL_SET_TIMEOUT);
} else {
/* Assume there's only one function on the USB 3.0
* device and enable remote wake for the first
* interface. FIXME if the interface association
* descriptor shows there's more than one function.
*/
status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
USB_REQ_SET_FEATURE,
USB_RECIP_INTERFACE,
USB_INTRF_FUNC_SUSPEND,
USB_INTRF_FUNC_SUSPEND_RW,
NULL, 0,
USB_CTRL_SET_TIMEOUT);
}
if (status) {
dev_dbg(&udev->dev, "won't remote wakeup, status %d\n",
status);
Expand Down
11 changes: 10 additions & 1 deletion trunk/drivers/usb/host/xhci-mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -2141,7 +2141,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
unsigned int val, val2;
u64 val_64;
struct xhci_segment *seg;
u32 page_size;
u32 page_size, temp;
int i;

page_size = xhci_readl(xhci, &xhci->op_regs->page_size);
Expand Down Expand Up @@ -2324,6 +2324,15 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)

INIT_LIST_HEAD(&xhci->lpm_failed_devs);

/* Enable USB 3.0 device notifications for function remote wake, which
* is necessary for allowing USB 3.0 devices to do remote wakeup from
* U3 (device suspend).
*/
temp = xhci_readl(xhci, &xhci->op_regs->dev_notification);
temp &= ~DEV_NOTE_MASK;
temp |= DEV_NOTE_FWAKE;
xhci_writel(xhci, temp, &xhci->op_regs->dev_notification);

return 0;

fail:
Expand Down
21 changes: 21 additions & 0 deletions trunk/drivers/usb/host/xhci-ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,24 @@ static unsigned int find_faked_portnum_from_hw_portnum(struct usb_hcd *hcd,
return num_similar_speed_ports;
}

static void handle_device_notification(struct xhci_hcd *xhci,
union xhci_trb *event)
{
u32 slot_id;

slot_id = TRB_TO_SLOT_ID(event->generic.field[3]);
if (!xhci->devs[slot_id])
xhci_warn(xhci, "Device Notification event for "
"unused slot %u\n", slot_id);
else
xhci_dbg(xhci, "Device Notification event for slot ID %u\n",
slot_id);
/* XXX should we kick khubd for the parent hub? It should have send an
* interrupt transfer when the port started signaling resume, so there's
* probably no need to do so.
*/
}

static void handle_port_status(struct xhci_hcd *xhci,
union xhci_trb *event)
{
Expand Down Expand Up @@ -2282,6 +2300,9 @@ static int xhci_handle_event(struct xhci_hcd *xhci)
else
update_ptrs = 0;
break;
case TRB_TYPE(TRB_DEV_NOTE):
handle_device_notification(xhci, event);
break;
default:
if ((le32_to_cpu(event->event_cmd.flags) & TRB_TYPE_BITMASK) >=
TRB_TYPE(48))
Expand Down

0 comments on commit 206046a

Please sign in to comment.