aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-pci.c
diff options
context:
space:
mode:
authorAndiry Xu <andiry.xu@amd.com>2010-10-14 10:23:06 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-10-22 13:22:13 -0400
commit5535b1d5f8885695c6ded783c692e3c0d0eda8ca (patch)
treef5454493a1c50e4a6254d904578dc3ecfd1d6e63 /drivers/usb/host/xhci-pci.c
parent9777e3ce907d4cb5a513902a87ecd03b52499569 (diff)
USB: xHCI: PCI power management implementation
This patch implements the PCI suspend/resume. Please refer to xHCI spec for doing the suspend/resume operation. For S3, CSS/SRS in USBCMD is used to save/restore the internal state. However, an error maybe occurs while restoring the internal state. In this case, it means that HC internal state is wrong and HC will be re-initialized. Signed-off-by: Libin Yang <libin.yang@amd.com> Signed-off-by: Dong Nguyen <dong.nguyen@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-pci.c')
-rw-r--r--drivers/usb/host/xhci-pci.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 3865f8c6f647..bb668a894ab9 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -116,6 +116,30 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
116 return xhci_pci_reinit(xhci, pdev); 116 return xhci_pci_reinit(xhci, pdev);
117} 117}
118 118
119#ifdef CONFIG_PM
120static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
121{
122 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
123 int retval = 0;
124
125 if (hcd->state != HC_STATE_SUSPENDED)
126 return -EINVAL;
127
128 retval = xhci_suspend(xhci);
129
130 return retval;
131}
132
133static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
134{
135 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
136 int retval = 0;
137
138 retval = xhci_resume(xhci, hibernated);
139 return retval;
140}
141#endif /* CONFIG_PM */
142
119static const struct hc_driver xhci_pci_hc_driver = { 143static const struct hc_driver xhci_pci_hc_driver = {
120 .description = hcd_name, 144 .description = hcd_name,
121 .product_desc = "xHCI Host Controller", 145 .product_desc = "xHCI Host Controller",
@@ -132,7 +156,10 @@ static const struct hc_driver xhci_pci_hc_driver = {
132 */ 156 */
133 .reset = xhci_pci_setup, 157 .reset = xhci_pci_setup,
134 .start = xhci_run, 158 .start = xhci_run,
135 /* suspend and resume implemented later */ 159#ifdef CONFIG_PM
160 .pci_suspend = xhci_pci_suspend,
161 .pci_resume = xhci_pci_resume,
162#endif
136 .stop = xhci_stop, 163 .stop = xhci_stop,
137 .shutdown = xhci_shutdown, 164 .shutdown = xhci_shutdown,
138 165
@@ -188,6 +215,11 @@ static struct pci_driver xhci_pci_driver = {
188 /* suspend and resume implemented later */ 215 /* suspend and resume implemented later */
189 216
190 .shutdown = usb_hcd_pci_shutdown, 217 .shutdown = usb_hcd_pci_shutdown,
218#ifdef CONFIG_PM_SLEEP
219 .driver = {
220 .pm = &usb_hcd_pci_pm_ops
221 },
222#endif
191}; 223};
192 224
193int xhci_register_pci(void) 225int xhci_register_pci(void)