diff options
Diffstat (limited to 'drivers/usb/host/ehci-spear.c')
-rw-r--r-- | drivers/usb/host/ehci-spear.c | 71 |
1 files changed, 4 insertions, 67 deletions
diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c index 37ba8c8d2fd0..c718a065e154 100644 --- a/drivers/usb/host/ehci-spear.c +++ b/drivers/usb/host/ehci-spear.c | |||
@@ -41,19 +41,11 @@ static int ehci_spear_setup(struct usb_hcd *hcd) | |||
41 | 41 | ||
42 | /* registers start at offset 0x0 */ | 42 | /* registers start at offset 0x0 */ |
43 | ehci->caps = hcd->regs; | 43 | ehci->caps = hcd->regs; |
44 | ehci->regs = hcd->regs + HC_LENGTH(ehci, ehci_readl(ehci, | ||
45 | &ehci->caps->hc_capbase)); | ||
46 | /* cache this readonly data; minimize chip reads */ | ||
47 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
48 | retval = ehci_halt(ehci); | ||
49 | if (retval) | ||
50 | return retval; | ||
51 | 44 | ||
52 | retval = ehci_init(hcd); | 45 | retval = ehci_setup(hcd); |
53 | if (retval) | 46 | if (retval) |
54 | return retval; | 47 | return retval; |
55 | 48 | ||
56 | ehci_reset(ehci); | ||
57 | ehci_port_power(ehci, 0); | 49 | ehci_port_power(ehci, 0); |
58 | 50 | ||
59 | return retval; | 51 | return retval; |
@@ -97,71 +89,16 @@ static const struct hc_driver ehci_spear_hc_driver = { | |||
97 | static int ehci_spear_drv_suspend(struct device *dev) | 89 | static int ehci_spear_drv_suspend(struct device *dev) |
98 | { | 90 | { |
99 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 91 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
100 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 92 | bool do_wakeup = device_may_wakeup(dev); |
101 | unsigned long flags; | ||
102 | int rc = 0; | ||
103 | 93 | ||
104 | if (time_before(jiffies, ehci->next_statechange)) | 94 | return ehci_suspend(hcd, do_wakeup); |
105 | msleep(10); | ||
106 | |||
107 | /* | ||
108 | * Root hub was already suspended. Disable irq emission and mark HW | ||
109 | * unaccessible. The PM and USB cores make sure that the root hub is | ||
110 | * either suspended or stopped. | ||
111 | */ | ||
112 | spin_lock_irqsave(&ehci->lock, flags); | ||
113 | ehci_prepare_ports_for_controller_suspend(ehci, device_may_wakeup(dev)); | ||
114 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); | ||
115 | ehci_readl(ehci, &ehci->regs->intr_enable); | ||
116 | spin_unlock_irqrestore(&ehci->lock, flags); | ||
117 | |||
118 | return rc; | ||
119 | } | 95 | } |
120 | 96 | ||
121 | static int ehci_spear_drv_resume(struct device *dev) | 97 | static int ehci_spear_drv_resume(struct device *dev) |
122 | { | 98 | { |
123 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 99 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
124 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
125 | |||
126 | if (time_before(jiffies, ehci->next_statechange)) | ||
127 | msleep(100); | ||
128 | |||
129 | if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { | ||
130 | int mask = INTR_MASK; | ||
131 | |||
132 | ehci_prepare_ports_for_controller_resume(ehci); | ||
133 | |||
134 | if (!hcd->self.root_hub->do_remote_wakeup) | ||
135 | mask &= ~STS_PCD; | ||
136 | |||
137 | ehci_writel(ehci, mask, &ehci->regs->intr_enable); | ||
138 | ehci_readl(ehci, &ehci->regs->intr_enable); | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | usb_root_hub_lost_power(hcd->self.root_hub); | ||
143 | |||
144 | /* | ||
145 | * Else reset, to cope with power loss or flush-to-storage style | ||
146 | * "resume" having let BIOS kick in during reboot. | ||
147 | */ | ||
148 | ehci_halt(ehci); | ||
149 | ehci_reset(ehci); | ||
150 | |||
151 | /* emptying the schedule aborts any urbs */ | ||
152 | spin_lock_irq(&ehci->lock); | ||
153 | if (ehci->reclaim) | ||
154 | end_unlink_async(ehci); | ||
155 | |||
156 | ehci_work(ehci); | ||
157 | spin_unlock_irq(&ehci->lock); | ||
158 | |||
159 | ehci_writel(ehci, ehci->command, &ehci->regs->command); | ||
160 | ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); | ||
161 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ | ||
162 | 100 | ||
163 | /* here we "know" root ports should always stay powered */ | 101 | ehci_resume(hcd, false); |
164 | ehci_port_power(ehci, 1); | ||
165 | return 0; | 102 | return 0; |
166 | } | 103 | } |
167 | #endif /* CONFIG_PM */ | 104 | #endif /* CONFIG_PM */ |