diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2011-10-13 07:16:24 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2011-10-14 13:32:53 -0400 |
commit | 81452182be1a95567da3718773dfcb45b42a579c (patch) | |
tree | 4a993f9919b559f6a68ef578024459c34396a688 /drivers | |
parent | adacaf1449ebb69f68075ba197495e3a61946fc2 (diff) |
pata_sl82c105: add Power Management support
Fixes IDE -> libata regression.
There shouldn't be any problems with it as corresponding IDE's host
driver (sl82c105) has been supporting PCI Power Management since
Oct 10 2008 (commit feb22b7f "ide: add proper PCI PM support (v2)")
and IDE PM since Jun 14 2003 (patch v2.5.73 "ide: Power Management").
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/pata_sl82c105.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c index c06ce8ced566..24cf200dd1c9 100644 --- a/drivers/ata/pata_sl82c105.c +++ b/drivers/ata/pata_sl82c105.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * pata_sl82c105.c - SL82C105 PATA for new ATA layer | 2 | * pata_sl82c105.c - SL82C105 PATA for new ATA layer |
3 | * (C) 2005 Red Hat Inc | 3 | * (C) 2005 Red Hat Inc |
4 | * (C) 2011 Bartlomiej Zolnierkiewicz | ||
4 | * | 5 | * |
5 | * Based in part on linux/drivers/ide/pci/sl82c105.c | 6 | * Based in part on linux/drivers/ide/pci/sl82c105.c |
6 | * SL82C105/Winbond 553 IDE driver | 7 | * SL82C105/Winbond 553 IDE driver |
@@ -289,6 +290,14 @@ static int sl82c105_bridge_revision(struct pci_dev *pdev) | |||
289 | return bridge->revision; | 290 | return bridge->revision; |
290 | } | 291 | } |
291 | 292 | ||
293 | static void sl82c105_fixup(struct pci_dev *pdev) | ||
294 | { | ||
295 | u32 val; | ||
296 | |||
297 | pci_read_config_dword(pdev, 0x40, &val); | ||
298 | val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; | ||
299 | pci_write_config_dword(pdev, 0x40, val); | ||
300 | } | ||
292 | 301 | ||
293 | static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id) | 302 | static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id) |
294 | { | 303 | { |
@@ -306,7 +315,6 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id | |||
306 | /* for now use only the first port */ | 315 | /* for now use only the first port */ |
307 | const struct ata_port_info *ppi[] = { &info_early, | 316 | const struct ata_port_info *ppi[] = { &info_early, |
308 | NULL }; | 317 | NULL }; |
309 | u32 val; | ||
310 | int rev; | 318 | int rev; |
311 | int rc; | 319 | int rc; |
312 | 320 | ||
@@ -325,13 +333,28 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id | |||
325 | else | 333 | else |
326 | ppi[0] = &info_dma; | 334 | ppi[0] = &info_dma; |
327 | 335 | ||
328 | pci_read_config_dword(dev, 0x40, &val); | 336 | sl82c105_fixup(dev); |
329 | val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; | ||
330 | pci_write_config_dword(dev, 0x40, val); | ||
331 | 337 | ||
332 | return ata_pci_bmdma_init_one(dev, ppi, &sl82c105_sht, NULL, 0); | 338 | return ata_pci_bmdma_init_one(dev, ppi, &sl82c105_sht, NULL, 0); |
333 | } | 339 | } |
334 | 340 | ||
341 | #ifdef CONFIG_PM | ||
342 | static int sl82c105_reinit_one(struct pci_dev *pdev) | ||
343 | { | ||
344 | struct ata_host *host = dev_get_drvdata(&pdev->dev); | ||
345 | int rc; | ||
346 | |||
347 | rc = ata_pci_device_do_resume(pdev); | ||
348 | if (rc) | ||
349 | return rc; | ||
350 | |||
351 | sl82c105_fixup(pdev); | ||
352 | |||
353 | ata_host_resume(host); | ||
354 | return 0; | ||
355 | } | ||
356 | #endif | ||
357 | |||
335 | static const struct pci_device_id sl82c105[] = { | 358 | static const struct pci_device_id sl82c105[] = { |
336 | { PCI_VDEVICE(WINBOND, PCI_DEVICE_ID_WINBOND_82C105), }, | 359 | { PCI_VDEVICE(WINBOND, PCI_DEVICE_ID_WINBOND_82C105), }, |
337 | 360 | ||
@@ -342,7 +365,11 @@ static struct pci_driver sl82c105_pci_driver = { | |||
342 | .name = DRV_NAME, | 365 | .name = DRV_NAME, |
343 | .id_table = sl82c105, | 366 | .id_table = sl82c105, |
344 | .probe = sl82c105_init_one, | 367 | .probe = sl82c105_init_one, |
345 | .remove = ata_pci_remove_one | 368 | .remove = ata_pci_remove_one, |
369 | #ifdef CONFIG_PM | ||
370 | .suspend = ata_pci_device_suspend, | ||
371 | .resume = sl82c105_reinit_one, | ||
372 | #endif | ||
346 | }; | 373 | }; |
347 | 374 | ||
348 | static int __init sl82c105_init(void) | 375 | static int __init sl82c105_init(void) |