diff options
author | Andiry Xu <andiry.xu@amd.com> | 2010-10-14 18:22:57 +0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-10-22 21:22:12 +0400 |
commit | be88fe4f4dda93e3264a887745123b1e6c4a6845 (patch) | |
tree | e0a014c2eb0672da74dc458270fbc6e0a5af48b2 /drivers/usb/host/xhci.h | |
parent | 85f0ff46960c2853fd1436a56798260eae91db86 (diff) | |
download | linux-be88fe4f4dda93e3264a887745123b1e6c4a6845.tar.xz |
USB: xHCI: port power management implementation
Add software trigger USB device suspend resume function hook.
Do port suspend & resume in terms of xHCI spec.
Port Suspend:
Stop all endpoints via Stop Endpoint Command with Suspend (SP) flag set.
Place individual ports into suspend mode by writing '3' for Port Link State
(PLS) field into PORTSC register. This can only be done when the port is in
Enabled state. When writing, the Port Link State Write Strobe (LWS) bit shall
be set to '1'.
Allocate an xhci_command and stash it in xhci_virt_device to wait completion for
the last Stop Endpoint Command. Use the Suspend bit in TRB to indicate the Stop
Endpoint Command is for port suspend. Based on Sarah's suggestion.
Port Resume:
Write '0' in PLS field, device will transition to running state.
Ring an endpoints' doorbell to restart it.
Ref: USB device remote wake need another patch to implement. For details of
how USB subsystem do power management, please see:
Documentation/usb/power-management.txt
Signed-off-by: Crane Cai <crane.cai@amd.com>
Signed-off-by: Libin Yang <libin.yang@amd.com>
Signed-off-by: Andiry Xu <andiry.xu@amd.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/xhci.h')
-rw-r--r-- | drivers/usb/host/xhci.h | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index a7181b491e67..73e5db3e89c9 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -269,6 +269,10 @@ struct xhci_op_regs { * A read gives the current link PM state of the port, * a write with Link State Write Strobe set sets the link state. */ +#define PORT_PLS_MASK (0xf << 5) +#define XDEV_U0 (0x0 << 5) +#define XDEV_U3 (0x3 << 5) +#define XDEV_RESUME (0xf << 5) /* true: port has power (see HCC_PPC) */ #define PORT_POWER (1 << 9) /* bits 10:13 indicate device speed: @@ -510,6 +514,7 @@ struct xhci_slot_ctx { #define MAX_EXIT (0xffff) /* Root hub port number that is needed to access the USB device */ #define ROOT_HUB_PORT(p) (((p) & 0xff) << 16) +#define DEVINFO_TO_ROOT_HUB_PORT(p) (((p) >> 16) & 0xff) /* Maximum number of ports under a hub device */ #define XHCI_MAX_PORTS(p) (((p) & 0xff) << 24) @@ -754,6 +759,7 @@ struct xhci_virt_device { /* Status of the last command issued for this device */ u32 cmd_status; struct list_head cmd_list; + u8 port; }; @@ -884,6 +890,10 @@ struct xhci_event_cmd { #define TRB_TO_EP_INDEX(p) ((((p) & (0x1f << 16)) >> 16) - 1) #define EP_ID_FOR_TRB(p) ((((p) + 1) & 0x1f) << 16) +#define SUSPEND_PORT_FOR_TRB(p) (((p) & 1) << 23) +#define TRB_TO_SUSPEND_PORT(p) (((p) & (1 << 23)) >> 23) +#define LAST_EP_INDEX 30 + /* Set TR Dequeue Pointer command TRB fields */ #define TRB_TO_STREAM_ID(p) ((((p) & (0xffff << 16)) >> 16)) #define STREAM_ID_FOR_TRB(p) ((((p)) & 0xffff) << 16) @@ -1202,6 +1212,9 @@ struct xhci_hcd { #define XHCI_LINK_TRB_QUIRK (1 << 0) #define XHCI_RESET_EP_QUIRK (1 << 1) #define XHCI_NEC_HOST (1 << 2) + u32 port_c_suspend[8]; /* port suspend change*/ + u32 suspended_ports[8]; /* which ports are + suspended */ }; /* For testing purposes */ @@ -1409,7 +1422,7 @@ int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, int xhci_queue_vendor_command(struct xhci_hcd *xhci, u32 field1, u32 field2, u32 field3, u32 field4); int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, - unsigned int ep_index); + unsigned int ep_index, int suspend); int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, int slot_id, unsigned int ep_index); int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, @@ -1439,6 +1452,8 @@ void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, struct xhci_dequeue_state *deq_state); void xhci_stop_endpoint_command_watchdog(unsigned long arg); +void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, + unsigned int ep_index, unsigned int stream_id); /* xHCI roothub code */ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, |