diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2011-10-13 13:16:24 +0200 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2011-10-14 13:32:53 -0400 |
commit | 81452182be1a95567da3718773dfcb45b42a579c (patch) | |
tree | 4a993f9919b559f6a68ef578024459c34396a688 /drivers/ata | |
parent | adacaf1449ebb69f68075ba197495e3a61946fc2 (diff) | |
download | lwn-81452182be1a95567da3718773dfcb45b42a579c.tar.gz lwn-81452182be1a95567da3718773dfcb45b42a579c.zip |
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/ata')
-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 @@ /* * pata_sl82c105.c - SL82C105 PATA for new ATA layer * (C) 2005 Red Hat Inc + * (C) 2011 Bartlomiej Zolnierkiewicz * * Based in part on linux/drivers/ide/pci/sl82c105.c * SL82C105/Winbond 553 IDE driver @@ -289,6 +290,14 @@ static int sl82c105_bridge_revision(struct pci_dev *pdev) return bridge->revision; } +static void sl82c105_fixup(struct pci_dev *pdev) +{ + u32 val; + + pci_read_config_dword(pdev, 0x40, &val); + val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; + pci_write_config_dword(pdev, 0x40, val); +} static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id) { @@ -306,7 +315,6 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id /* for now use only the first port */ const struct ata_port_info *ppi[] = { &info_early, NULL }; - u32 val; int rev; int rc; @@ -325,13 +333,28 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id else ppi[0] = &info_dma; - pci_read_config_dword(dev, 0x40, &val); - val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; - pci_write_config_dword(dev, 0x40, val); + sl82c105_fixup(dev); return ata_pci_bmdma_init_one(dev, ppi, &sl82c105_sht, NULL, 0); } +#ifdef CONFIG_PM +static int sl82c105_reinit_one(struct pci_dev *pdev) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + int rc; + + rc = ata_pci_device_do_resume(pdev); + if (rc) + return rc; + + sl82c105_fixup(pdev); + + ata_host_resume(host); + return 0; +} +#endif + static const struct pci_device_id sl82c105[] = { { PCI_VDEVICE(WINBOND, PCI_DEVICE_ID_WINBOND_82C105), }, @@ -342,7 +365,11 @@ static struct pci_driver sl82c105_pci_driver = { .name = DRV_NAME, .id_table = sl82c105, .probe = sl82c105_init_one, - .remove = ata_pci_remove_one + .remove = ata_pci_remove_one, +#ifdef CONFIG_PM + .suspend = ata_pci_device_suspend, + .resume = sl82c105_reinit_one, +#endif }; static int __init sl82c105_init(void) |