Diff markup
1 /* 1 /*
2 * (C) Copyright David Brownell 2000-2002 2 * (C) Copyright David Brownell 2000-2002
3 * 3 *
4 * This program is free software; you can redi 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public L 5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. 7 * option) any later version.
8 * 8 *
9 * This program is distributed in the hope tha 9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the impl 10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See t 11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details. 12 * for more details.
13 * 13 *
14 * You should have received a copy of the GNU 14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to t 15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 675 Mass Ave, Cambridge, MA 02139, US 16 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */ 17 */
18 18
19 #include <linux/kernel.h> 19 #include <linux/kernel.h>
20 #include <linux/module.h> 20 #include <linux/module.h>
21 #include <linux/pci.h> 21 #include <linux/pci.h>
22 #include <linux/usb.h> 22 #include <linux/usb.h>
23 23
24 #include <asm/io.h> 24 #include <asm/io.h>
25 #include <asm/irq.h> 25 #include <asm/irq.h>
26 26
27 #ifdef CONFIG_PPC_PMAC 27 #ifdef CONFIG_PPC_PMAC
28 #include <asm/machdep.h> 28 #include <asm/machdep.h>
29 #include <asm/pmac_feature.h> 29 #include <asm/pmac_feature.h>
30 #include <asm/pci-bridge.h> 30 #include <asm/pci-bridge.h>
31 #include <asm/prom.h> 31 #include <asm/prom.h>
32 #endif 32 #endif
33 33
34 #include "usb.h" 34 #include "usb.h"
35 #include "hcd.h" 35 #include "hcd.h"
36 36
37 37
38 /* PCI-based HCs are common, but plenty of non 38 /* PCI-based HCs are common, but plenty of non-PCI HCs are used too */
39 39
40 40
41 /*-------------------------------------------- 41 /*-------------------------------------------------------------------------*/
42 42
43 /* configure so an HC device and id are always 43 /* configure so an HC device and id are always provided */
44 /* always called with process context; sleepin 44 /* always called with process context; sleeping is OK */
45 45
46 /** 46 /**
47 * usb_hcd_pci_probe - initialize PCI-based HC 47 * usb_hcd_pci_probe - initialize PCI-based HCDs
48 * @dev: USB Host Controller being probed 48 * @dev: USB Host Controller being probed
49 * @id: pci hotplug id connecting controller t 49 * @id: pci hotplug id connecting controller to HCD framework
50 * Context: !in_interrupt() 50 * Context: !in_interrupt()
51 * 51 *
52 * Allocates basic PCI resources for this USB 52 * Allocates basic PCI resources for this USB host controller, and
53 * then invokes the start() method for the HCD 53 * then invokes the start() method for the HCD associated with it
54 * through the hotplug entry's driver_data. 54 * through the hotplug entry's driver_data.
55 * 55 *
56 * Store this function in the HCD's struct pci 56 * Store this function in the HCD's struct pci_driver as probe().
57 */ 57 */
58 int usb_hcd_pci_probe(struct pci_dev *dev, con 58 int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
59 { 59 {
60 struct hc_driver *driver; 60 struct hc_driver *driver;
61 struct usb_hcd *hcd; 61 struct usb_hcd *hcd;
62 int retval; 62 int retval;
63 63
64 if (usb_disabled()) 64 if (usb_disabled())
65 return -ENODEV; 65 return -ENODEV;
66 66
67 if (!id) 67 if (!id)
68 return -EINVAL; 68 return -EINVAL;
69 driver = (struct hc_driver *)id->drive 69 driver = (struct hc_driver *)id->driver_data;
70 if (!driver) 70 if (!driver)
71 return -EINVAL; 71 return -EINVAL;
72 72
73 if (pci_enable_device(dev) < 0) 73 if (pci_enable_device(dev) < 0)
74 return -ENODEV; 74 return -ENODEV;
75 dev->current_state = PCI_D0; 75 dev->current_state = PCI_D0;
76 dev->dev.power.power_state = PMSG_ON; <<
77 76
78 if (!dev->irq) { 77 if (!dev->irq) {
79 dev_err(&dev->dev, 78 dev_err(&dev->dev,
80 "Found HC with no IRQ. 79 "Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
81 pci_name(dev)); 80 pci_name(dev));
82 retval = -ENODEV; 81 retval = -ENODEV;
83 goto err1; 82 goto err1;
84 } 83 }
85 84
86 hcd = usb_create_hcd(driver, &dev->dev 85 hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev));
87 if (!hcd) { 86 if (!hcd) {
88 retval = -ENOMEM; 87 retval = -ENOMEM;
89 goto err1; 88 goto err1;
90 } 89 }
91 90
92 if (driver->flags & HCD_MEMORY) { 91 if (driver->flags & HCD_MEMORY) {
93 /* EHCI, OHCI */ 92 /* EHCI, OHCI */
94 hcd->rsrc_start = pci_resource 93 hcd->rsrc_start = pci_resource_start(dev, 0);
95 hcd->rsrc_len = pci_resource_l 94 hcd->rsrc_len = pci_resource_len(dev, 0);
96 if (!request_mem_region(hcd->r 95 if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
97 driver->descri 96 driver->description)) {
98 dev_dbg(&dev->dev, "co 97 dev_dbg(&dev->dev, "controller already in use\n");
99 retval = -EBUSY; 98 retval = -EBUSY;
100 goto err2; 99 goto err2;
101 } 100 }
102 hcd->regs = ioremap_nocache(hc 101 hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
103 if (hcd->regs == NULL) { 102 if (hcd->regs == NULL) {
104 dev_dbg(&dev->dev, "er 103 dev_dbg(&dev->dev, "error mapping memory\n");
105 retval = -EFAULT; 104 retval = -EFAULT;
106 goto err3; 105 goto err3;
107 } 106 }
108 107
109 } else { 108 } else {
110 /* UHCI */ 109 /* UHCI */
111 int region; 110 int region;
112 111
113 for (region = 0; region < PCI_ 112 for (region = 0; region < PCI_ROM_RESOURCE; region++) {
114 if (!(pci_resource_fla 113 if (!(pci_resource_flags(dev, region) &
115 IORESO 114 IORESOURCE_IO))
116 continue; 115 continue;
117 116
118 hcd->rsrc_start = pci_ 117 hcd->rsrc_start = pci_resource_start(dev, region);
119 hcd->rsrc_len = pci_re 118 hcd->rsrc_len = pci_resource_len(dev, region);
120 if (request_region(hcd 119 if (request_region(hcd->rsrc_start, hcd->rsrc_len,
121 driver 120 driver->description))
122 break; 121 break;
123 } 122 }
124 if (region == PCI_ROM_RESOURCE 123 if (region == PCI_ROM_RESOURCE) {
125 dev_dbg(&dev->dev, "no 124 dev_dbg(&dev->dev, "no i/o regions available\n");
126 retval = -EBUSY; 125 retval = -EBUSY;
127 goto err1; 126 goto err1;
128 } 127 }
129 } 128 }
130 129
131 pci_set_master(dev); 130 pci_set_master(dev);
132 131
133 retval = usb_add_hcd(hcd, dev->irq, IR 132 retval = usb_add_hcd(hcd, dev->irq, IRQF_DISABLED | IRQF_SHARED);
134 if (retval != 0) 133 if (retval != 0)
135 goto err4; 134 goto err4;
136 return retval; 135 return retval;
137 136
138 err4: 137 err4:
139 if (driver->flags & HCD_MEMORY) { 138 if (driver->flags & HCD_MEMORY) {
140 iounmap(hcd->regs); 139 iounmap(hcd->regs);
141 err3: 140 err3:
142 release_mem_region(hcd->rsrc_s 141 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
143 } else 142 } else
144 release_region(hcd->rsrc_start 143 release_region(hcd->rsrc_start, hcd->rsrc_len);
145 err2: 144 err2:
146 usb_put_hcd(hcd); 145 usb_put_hcd(hcd);
147 err1: 146 err1:
148 pci_disable_device(dev); 147 pci_disable_device(dev);
149 dev_err(&dev->dev, "init %s fail, %d\n 148 dev_err(&dev->dev, "init %s fail, %d\n", pci_name(dev), retval);
150 return retval; 149 return retval;
151 } 150 }
152 EXPORT_SYMBOL_GPL(usb_hcd_pci_probe); 151 EXPORT_SYMBOL_GPL(usb_hcd_pci_probe);
153 152
154 153
155 /* may be called without controller electrical 154 /* may be called without controller electrically present */
156 /* may be called with controller, bus, and dev 155 /* may be called with controller, bus, and devices active */
157 156
158 /** 157 /**
159 * usb_hcd_pci_remove - shutdown processing fo 158 * usb_hcd_pci_remove - shutdown processing for PCI-based HCDs
160 * @dev: USB Host Controller being removed 159 * @dev: USB Host Controller being removed
161 * Context: !in_interrupt() 160 * Context: !in_interrupt()
162 * 161 *
163 * Reverses the effect of usb_hcd_pci_probe(), 162 * Reverses the effect of usb_hcd_pci_probe(), first invoking
164 * the HCD's stop() method. It is always call 163 * the HCD's stop() method. It is always called from a thread
165 * context, normally "rmmod", "apmd", or somet 164 * context, normally "rmmod", "apmd", or something similar.
166 * 165 *
167 * Store this function in the HCD's struct pci 166 * Store this function in the HCD's struct pci_driver as remove().
168 */ 167 */
169 void usb_hcd_pci_remove(struct pci_dev *dev) 168 void usb_hcd_pci_remove(struct pci_dev *dev)
170 { 169 {
171 struct usb_hcd *hcd; 170 struct usb_hcd *hcd;
172 171
173 hcd = pci_get_drvdata(dev); 172 hcd = pci_get_drvdata(dev);
174 if (!hcd) 173 if (!hcd)
175 return; 174 return;
176 175
177 usb_remove_hcd(hcd); 176 usb_remove_hcd(hcd);
178 if (hcd->driver->flags & HCD_MEMORY) { 177 if (hcd->driver->flags & HCD_MEMORY) {
179 iounmap(hcd->regs); 178 iounmap(hcd->regs);
180 release_mem_region(hcd->rsrc_s 179 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
181 } else { 180 } else {
182 release_region(hcd->rsrc_start 181 release_region(hcd->rsrc_start, hcd->rsrc_len);
183 } 182 }
184 usb_put_hcd(hcd); 183 usb_put_hcd(hcd);
185 pci_disable_device(dev); 184 pci_disable_device(dev);
186 } 185 }
187 EXPORT_SYMBOL_GPL(usb_hcd_pci_remove); 186 EXPORT_SYMBOL_GPL(usb_hcd_pci_remove);
188 187
189 <<
190 #ifdef CONFIG_PM <<
191 <<
192 /** 188 /**
193 * usb_hcd_pci_suspend - power management susp !! 189 * usb_hcd_pci_shutdown - shutdown host controller
194 * @dev: USB Host Controller being suspended !! 190 * @dev: USB Host Controller being shutdown
195 * @message: semantics in flux <<
196 * <<
197 * Store this function in the HCD's struct pci <<
198 */ 191 */
199 int usb_hcd_pci_suspend(struct pci_dev *dev, p !! 192 void usb_hcd_pci_shutdown(struct pci_dev *dev)
200 { 193 {
201 struct usb_hcd *hcd; 194 struct usb_hcd *hcd;
202 int retval = 0; <<
203 int has_pci_pm; <<
204 195
205 hcd = pci_get_drvdata(dev); 196 hcd = pci_get_drvdata(dev);
>> 197 if (!hcd)
>> 198 return;
>> 199
>> 200 if (hcd->driver->shutdown)
>> 201 hcd->driver->shutdown(hcd);
>> 202 }
>> 203 EXPORT_SYMBOL_GPL(usb_hcd_pci_shutdown);
>> 204
>> 205 #ifdef CONFIG_PM_SLEEP
>> 206
>> 207 static int check_root_hub_suspended(struct device *dev)
>> 208 {
>> 209 struct pci_dev *pci_dev = to_pci_dev(dev);
>> 210 struct usb_hcd *hcd = pci_get_drvdata(pci_dev);
>> 211
>> 212 if (!(hcd->state == HC_STATE_SUSPENDED ||
>> 213 hcd->state == HC_STATE_HALT)) {
>> 214 dev_warn(dev, "Root hub is not suspended\n");
>> 215 return -EBUSY;
>> 216 }
>> 217 return 0;
>> 218 }
>> 219
>> 220 static int hcd_pci_suspend(struct device *dev)
>> 221 {
>> 222 struct pci_dev *pci_dev = to_pci_dev(dev);
>> 223 struct usb_hcd *hcd = pci_get_drvdata(pci_dev);
>> 224 int retval;
206 225
207 /* Root hub suspend should have stoppe 226 /* Root hub suspend should have stopped all downstream traffic,
208 * and all bus master traffic. And do 227 * and all bus master traffic. And done so for both the interface
209 * and the stub usb_device (which we c 228 * and the stub usb_device (which we check here). But maybe it
210 * didn't; writing sysfs power/state f 229 * didn't; writing sysfs power/state files ignores such rules...
211 * <<
212 * We must ignore the FREEZE vs SUSPEN <<
213 * otherwise the swsusp will save (and <<
214 */ 230 */
215 if (!(hcd->state == HC_STATE_SUSPENDED !! 231 retval = check_root_hub_suspended(dev);
216 hcd->state == HC_STATE !! 232 if (retval)
217 return -EBUSY; !! 233 return retval;
218 234
219 if (hcd->driver->suspend) { !! 235 /* We might already be suspended (runtime PM -- not yet written) */
220 retval = hcd->driver->suspend( !! 236 if (pci_dev->current_state != PCI_D0)
221 suspend_report_result(hcd->dri !! 237 return retval;
>> 238
>> 239 if (hcd->driver->pci_suspend) {
>> 240 retval = hcd->driver->pci_suspend(hcd);
>> 241 suspend_report_result(hcd->driver->pci_suspend, retval);
222 if (retval) 242 if (retval)
223 goto done; !! 243 return retval;
224 } 244 }
225 synchronize_irq(dev->irq); <<
226 <<
227 /* FIXME until the generic PM interfac <<
228 * can't use PCI D1 and D2 states. Fo <<
229 * between messages and states will ne <<
230 * will need to provide a target syste <<
231 * <<
232 * It'll be important to learn charact <<
233 * especially on embedded hardware whe <<
234 * charge of an external VBUS power su <<
235 * Some target system states will leav <<
236 * (With PCI, that's often handled by <<
237 */ <<
238 245
239 /* even when the PCI layer rejects som !! 246 synchronize_irq(pci_dev->irq);
240 * below, HCs can try global suspend a <<
241 * PM-sensitive HCDs may already have <<
242 */ <<
243 has_pci_pm = pci_find_capability(dev, <<
244 247
245 /* Downstream ports from this root hub 248 /* Downstream ports from this root hub should already be quiesced, so
246 * there will be no DMA activity. Now 249 * there will be no DMA activity. Now we can shut down the upstream
247 * link (except maybe for PME# resume !! 250 * link (except maybe for PME# resume signaling). We'll enter a
248 * low power state, if the hardware al !! 251 * low power state during suspend_noirq, if the hardware allows.
249 */ 252 */
250 if (hcd->state == HC_STATE_SUSPENDED) !! 253 pci_disable_device(pci_dev);
>> 254 return retval;
>> 255 }
251 256
252 /* no DMA or IRQs except when !! 257 static int hcd_pci_suspend_noirq(struct device *dev)
253 if (dev->current_state == PCI_ !! 258 {
254 pci_save_state(dev); !! 259 struct pci_dev *pci_dev = to_pci_dev(dev);
255 pci_disable_device(dev !! 260 struct usb_hcd *hcd = pci_get_drvdata(pci_dev);
256 } !! 261 int retval;
257 262
258 if (message.event == PM_EVENT_ !! 263 retval = check_root_hub_suspended(dev);
259 message.event !! 264 if (retval)
260 dev_dbg(hcd->self.cont !! 265 return retval;
261 goto done; <<
262 } <<
263 266
264 if (!has_pci_pm) { !! 267 pci_save_state(pci_dev);
265 dev_dbg(hcd->self.cont <<
266 goto done; <<
267 } <<
268 268
269 /* NOTE: dev->current_state b !! 269 /* If the root hub is HALTed rather than SUSPENDed,
270 * only for devices that suppo !! 270 * disallow remote wakeup.
271 * PCI_D3 (but not PCI_D1 or P !! 271 */
272 * some device state (e.g. as !! 272 if (hcd->state == HC_STATE_HALT)
273 */ !! 273 device_set_wakeup_enable(dev, 0);
274 retval = pci_set_power_state(d !! 274 dev_dbg(dev, "wakeup: %d\n", device_may_wakeup(dev));
275 suspend_report_result(pci_set_ <<
276 if (retval == 0) { <<
277 int wake = device_can_ <<
278 <<
279 wake = wake && device_ <<
280 <<
281 dev_dbg(hcd->self.cont <<
282 wake ? <<
283 <<
284 /* Ignore these return <<
285 * reject requests the <<
286 * than coding the sam <<
287 */ <<
288 (void) pci_enable_wake <<
289 (void) pci_enable_wake <<
290 } else { <<
291 dev_dbg(&dev->dev, "PC <<
292 retval <<
293 (void) usb_hcd_pci_res <<
294 } <<
295 275
296 } else if (hcd->state != HC_STATE_HALT !! 276 /* Possibly enable remote wakeup,
297 dev_dbg(hcd->self.controller, !! 277 * choose the appropriate low-power state, and go to that state.
298 hcd->state); !! 278 */
299 WARN_ON(1); !! 279 retval = pci_prepare_to_sleep(pci_dev);
300 retval = -EINVAL; !! 280 if (retval == -EIO) { /* Low-power not supported */
>> 281 dev_dbg(dev, "--> PCI D0 legacy\n");
>> 282 retval = 0;
>> 283 } else if (retval == 0) {
>> 284 dev_dbg(dev, "--> PCI %s\n",
>> 285 pci_power_name(pci_dev->current_state));
>> 286 } else {
>> 287 suspend_report_result(pci_prepare_to_sleep, retval);
>> 288 return retval;
301 } 289 }
302 290
303 done: <<
304 if (retval == 0) { <<
305 dev->dev.power.power_state = P <<
306 <<
307 #ifdef CONFIG_PPC_PMAC 291 #ifdef CONFIG_PPC_PMAC
308 /* Disable ASIC clocks for USB !! 292 /* Disable ASIC clocks for USB */
309 if (machine_is(powermac)) { !! 293 if (machine_is(powermac)) {
310 struct device_node !! 294 struct device_node *of_node;
311 <<
312 of_node = pci_device_t <<
313 if (of_node) <<
314 pmac_call_feat <<
315 <<
316 } <<
317 #endif <<
318 } <<
319 295
>> 296 of_node = pci_device_to_OF_node(pci_dev);
>> 297 if (of_node)
>> 298 pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
>> 299 }
>> 300 #endif
320 return retval; 301 return retval;
321 } 302 }
322 EXPORT_SYMBOL_GPL(usb_hcd_pci_suspend); <<
323 303
324 /** !! 304 static int hcd_pci_resume_noirq(struct device *dev)
325 * usb_hcd_pci_resume - power management resum <<
326 * @dev: USB Host Controller being resumed <<
327 * <<
328 * Store this function in the HCD's struct pci <<
329 */ <<
330 int usb_hcd_pci_resume(struct pci_dev *dev) <<
331 { 305 {
332 struct usb_hcd *hcd; !! 306 struct pci_dev *pci_dev = to_pci_dev(dev);
333 int retval; <<
334 <<
335 hcd = pci_get_drvdata(dev); <<
336 if (hcd->state != HC_STATE_SUSPENDED) <<
337 dev_dbg(hcd->self.controller, <<
338 "can't resume, <<
339 return 0; <<
340 } <<
341 307
342 #ifdef CONFIG_PPC_PMAC 308 #ifdef CONFIG_PPC_PMAC
343 /* Reenable ASIC clocks for USB */ 309 /* Reenable ASIC clocks for USB */
344 if (machine_is(powermac)) { 310 if (machine_is(powermac)) {
345 struct device_node *of_node; 311 struct device_node *of_node;
346 312
347 of_node = pci_device_to_OF_nod !! 313 of_node = pci_device_to_OF_node(pci_dev);
348 if (of_node) 314 if (of_node)
349 pmac_call_feature(PMAC 315 pmac_call_feature(PMAC_FTR_USB_ENABLE,
350 316 of_node, 0, 1);
351 } 317 }
352 #endif 318 #endif
353 319
354 /* NOTE: chip docs cover clean "real !! 320 /* Go back to D0 and disable remote wakeup */
355 * calls "standby", "suspend to RAM", !! 321 pci_back_from_sleep(pci_dev);
356 * dirty cases when swsusp fakes a sus !! 322 return 0;
357 */ !! 323 }
358 if (dev->current_state != PCI_D0) { !! 324
359 #ifdef DEBUG !! 325 static int resume_common(struct device *dev, bool hibernated)
360 int pci_pm; !! 326 {
361 u16 pmcr; !! 327 struct pci_dev *pci_dev = to_pci_dev(dev);
362 !! 328 struct usb_hcd *hcd = pci_get_drvdata(pci_dev);
363 pci_pm = pci_find_capability(d !! 329 int retval;
364 pci_read_config_word(dev, pci_ !! 330
365 pmcr &= PCI_PM_CTRL_STATE_MASK !! 331 if (hcd->state != HC_STATE_SUSPENDED) {
366 if (pmcr) { !! 332 dev_dbg(dev, "can't resume, not suspended!\n");
367 /* Clean case: power !! 333 return 0;
368 * maintained; remote <<
369 */ <<
370 dev_dbg(hcd->self.cont <<
371 pmcr); <<
372 } else { <<
373 /* Clean: HC lost Vcc <<
374 * + Vaux may have p <<
375 * state ... for r <<
376 * + or not; HCD mus <<
377 * <<
378 * Dirty: D0 semi-init <<
379 * + after BIOS init <<
380 * + after Linux ini <<
381 */ <<
382 dev_dbg(hcd->self.cont <<
383 "PCI D0, from <<
384 dev->current_s <<
385 } <<
386 #endif <<
387 /* yes, ignore these results t <<
388 (void) pci_enable_wake(dev, de <<
389 (void) pci_enable_wake(dev, PC <<
390 } else { <<
391 /* Same basic cases: clean (po <<
392 dev_dbg(hcd->self.controller, <<
393 } 334 }
394 335
395 /* NOTE: the PCI API itself is asymme !! 336 retval = pci_enable_device(pci_dev);
396 * pci_set_power_state(PCI_D0) since t <<
397 * but that won't re-enable bus master <<
398 * explicitly disables bus mastering.. <<
399 */ <<
400 retval = pci_enable_device(dev); <<
401 if (retval < 0) { 337 if (retval < 0) {
402 dev_err(hcd->self.controller, !! 338 dev_err(dev, "can't re-enable after resume, %d!\n", retval);
403 "can't re-enable after <<
404 return retval; 339 return retval;
405 } 340 }
406 pci_set_master(dev); <<
407 pci_restore_state(dev); <<
408 341
409 dev->dev.power.power_state = PMSG_ON; !! 342 pci_set_master(pci_dev);
410 343
411 clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flag 344 clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
412 345
413 if (hcd->driver->resume) { !! 346 if (hcd->driver->pci_resume) {
414 retval = hcd->driver->resume(h !! 347 retval = hcd->driver->pci_resume(hcd, hibernated);
415 if (retval) { 348 if (retval) {
416 dev_err(hcd->self.cont !! 349 dev_err(dev, "PCI post-resume error %d!\n", retval);
417 "PCI post-resu <<
418 usb_hc_died(hcd); 350 usb_hc_died(hcd);
419 } 351 }
420 } 352 }
421 <<
422 return retval; 353 return retval;
423 } 354 }
424 EXPORT_SYMBOL_GPL(usb_hcd_pci_resume); <<
425 355
426 #endif /* CONFIG_PM */ !! 356 static int hcd_pci_resume(struct device *dev)
427 <<
428 /** <<
429 * usb_hcd_pci_shutdown - shutdown host contro <<
430 * @dev: USB Host Controller being shutdown <<
431 */ <<
432 void usb_hcd_pci_shutdown(struct pci_dev *dev) <<
433 { 357 {
434 struct usb_hcd *hcd; !! 358 return resume_common(dev, false);
435 !! 359 }
436 hcd = pci_get_drvdata(dev); <<
437 if (!hcd) <<
438 return; <<
439 360
440 if (hcd->driver->shutdown) !! 361 static int hcd_pci_restore(struct device *dev)
441 hcd->driver->shutdown(hcd); !! 362 {
>> 363 return resume_common(dev, true);
442 } 364 }
443 EXPORT_SYMBOL_GPL(usb_hcd_pci_shutdown); <<
444 365
>> 366 struct dev_pm_ops usb_hcd_pci_pm_ops = {
>> 367 .suspend = hcd_pci_suspend,
>> 368 .suspend_noirq = hcd_pci_suspend_noirq,
>> 369 .resume_noirq = hcd_pci_resume_noirq,
>> 370 .resume = hcd_pci_resume,
>> 371 .freeze = check_root_hub_suspended,
>> 372 .freeze_noirq = check_root_hub_suspended,
>> 373 .thaw_noirq = NULL,
>> 374 .thaw = NULL,
>> 375 .poweroff = hcd_pci_suspend,
>> 376 .poweroff_noirq = hcd_pci_suspend_noirq,
>> 377 .restore_noirq = hcd_pci_resume_noirq,
>> 378 .restore = hcd_pci_restore,
>> 379 };
>> 380 EXPORT_SYMBOL_GPL(usb_hcd_pci_pm_ops);
>> 381
>> 382 #endif /* CONFIG_PM_SLEEP */
445 383
|
This page was automatically generated by the
LXR engine.
|