diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ide/pci/sc1200.c | 108 |
1 files changed, 38 insertions, 70 deletions
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c index 707d5ff66b03..f0029b364c57 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/pci/sc1200.c | |||
@@ -260,66 +260,39 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
260 | } | 260 | } |
261 | 261 | ||
262 | #ifdef CONFIG_PM | 262 | #ifdef CONFIG_PM |
263 | static ide_hwif_t *lookup_pci_dev (ide_hwif_t *prev, struct pci_dev *dev) | 263 | struct sc1200_saved_state { |
264 | { | 264 | u32 regs[8]; |
265 | int h; | 265 | }; |
266 | |||
267 | for (h = 0; h < MAX_HWIFS; h++) { | ||
268 | ide_hwif_t *hwif = &ide_hwifs[h]; | ||
269 | if (prev) { | ||
270 | if (hwif == prev) | ||
271 | prev = NULL; // found previous, now look for next match | ||
272 | } else { | ||
273 | if (hwif && hwif->pci_dev == dev) | ||
274 | return hwif; // found next match | ||
275 | } | ||
276 | } | ||
277 | return NULL; // not found | ||
278 | } | ||
279 | |||
280 | typedef struct sc1200_saved_state_s { | ||
281 | __u32 regs[4]; | ||
282 | } sc1200_saved_state_t; | ||
283 | |||
284 | 266 | ||
285 | static int sc1200_suspend (struct pci_dev *dev, pm_message_t state) | 267 | static int sc1200_suspend (struct pci_dev *dev, pm_message_t state) |
286 | { | 268 | { |
287 | ide_hwif_t *hwif = NULL; | ||
288 | |||
289 | printk("SC1200: suspend(%u)\n", state.event); | 269 | printk("SC1200: suspend(%u)\n", state.event); |
290 | 270 | ||
271 | /* | ||
272 | * we only save state when going from full power to less | ||
273 | */ | ||
291 | if (state.event == PM_EVENT_ON) { | 274 | if (state.event == PM_EVENT_ON) { |
292 | // we only save state when going from full power to less | 275 | struct sc1200_saved_state *ss; |
293 | 276 | unsigned int r; | |
294 | // | 277 | |
295 | // Loop over all interfaces that are part of this PCI device: | 278 | /* |
296 | // | 279 | * allocate a permanent save area, if not already allocated |
297 | while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) { | 280 | */ |
298 | sc1200_saved_state_t *ss; | 281 | ss = (struct sc1200_saved_state *)pci_get_drvdata(dev); |
299 | unsigned int basereg, r; | 282 | if (ss == NULL) { |
300 | // | 283 | ss = kmalloc(sizeof(*ss), GFP_KERNEL); |
301 | // allocate a permanent save area, if not already allocated | 284 | if (ss == NULL) |
302 | // | 285 | return -ENOMEM; |
303 | ss = (sc1200_saved_state_t *)hwif->config_data; | 286 | pci_set_drvdata(dev, ss); |
304 | if (ss == NULL) { | ||
305 | ss = kmalloc(sizeof(sc1200_saved_state_t), GFP_KERNEL); | ||
306 | if (ss == NULL) | ||
307 | return -ENOMEM; | ||
308 | hwif->config_data = (unsigned long)ss; | ||
309 | } | ||
310 | ss = (sc1200_saved_state_t *)hwif->config_data; | ||
311 | // | ||
312 | // Save timing registers: this may be unnecessary if | ||
313 | // BIOS also does it | ||
314 | // | ||
315 | basereg = hwif->channel ? 0x50 : 0x40; | ||
316 | for (r = 0; r < 4; ++r) { | ||
317 | pci_read_config_dword (hwif->pci_dev, basereg + (r<<2), &ss->regs[r]); | ||
318 | } | ||
319 | } | 287 | } |
320 | } | ||
321 | 288 | ||
322 | /* You don't need to iterate over disks -- sysfs should have done that for you already */ | 289 | /* |
290 | * save timing registers | ||
291 | * (this may be unnecessary if BIOS also does it) | ||
292 | */ | ||
293 | for (r = 0; r < 8; r++) | ||
294 | pci_read_config_dword(dev, 0x40 + r * 4, &ss->regs[r]); | ||
295 | } | ||
323 | 296 | ||
324 | pci_disable_device(dev); | 297 | pci_disable_device(dev); |
325 | pci_set_power_state(dev, pci_choose_state(dev, state)); | 298 | pci_set_power_state(dev, pci_choose_state(dev, state)); |
@@ -328,30 +301,25 @@ static int sc1200_suspend (struct pci_dev *dev, pm_message_t state) | |||
328 | 301 | ||
329 | static int sc1200_resume (struct pci_dev *dev) | 302 | static int sc1200_resume (struct pci_dev *dev) |
330 | { | 303 | { |
331 | ide_hwif_t *hwif = NULL; | 304 | struct sc1200_saved_state *ss; |
332 | int i; | 305 | unsigned int r; |
306 | int i; | ||
333 | 307 | ||
334 | i = pci_enable_device(dev); | 308 | i = pci_enable_device(dev); |
335 | if (i) | 309 | if (i) |
336 | return i; | 310 | return i; |
337 | 311 | ||
338 | // | 312 | ss = (struct sc1200_saved_state *)pci_get_drvdata(dev); |
339 | // loop over all interfaces that are part of this pci device: | 313 | |
340 | // | 314 | /* |
341 | while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) { | 315 | * restore timing registers |
342 | unsigned int basereg, r; | 316 | * (this may be unnecessary if BIOS also does it) |
343 | sc1200_saved_state_t *ss = (sc1200_saved_state_t *)hwif->config_data; | 317 | */ |
344 | 318 | if (ss) { | |
345 | // | 319 | for (r = 0; r < 8; r++) |
346 | // Restore timing registers: this may be unnecessary if BIOS also does it | 320 | pci_write_config_dword(dev, 0x40 + r * 4, ss->regs[r]); |
347 | // | ||
348 | basereg = hwif->channel ? 0x50 : 0x40; | ||
349 | if (ss != NULL) { | ||
350 | for (r = 0; r < 4; ++r) { | ||
351 | pci_write_config_dword(hwif->pci_dev, basereg + (r<<2), ss->regs[r]); | ||
352 | } | ||
353 | } | ||
354 | } | 321 | } |
322 | |||
355 | return 0; | 323 | return 0; |
356 | } | 324 | } |
357 | #endif | 325 | #endif |