pata_sl82c105: add Power Management support
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Thu, 13 Oct 2011 11:16:24 +0000 (13:16 +0200)
committerJeff Garzik <jgarzik@redhat.com>
Fri, 14 Oct 2011 17:32:53 +0000 (13:32 -0400)
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>
drivers/ata/pata_sl82c105.c

index c06ce8c..24cf200 100644 (file)
@@ -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)