diff options
author | Hannes Reinecke <hare@suse.de> | 2007-10-19 04:32:21 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.localdomain> | 2007-10-21 12:10:50 -0400 |
commit | b5720729f58a4a05b0e2c8c61ac3ed3a3e9f94e5 (patch) | |
tree | 7f1271417db63a27474d50d3e43e399a5cef4d93 /drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | |
parent | eb7a1698d24783dd215cb86a12cadebe9b4e7046 (diff) |
[SCSI] aic7xxx: Add suspend/resume support
The aic7xxx driver already contains fragments for suspend/resume
support. So we only need to update them to the current interface
and have full PCI suspend/resume.
Signed-off-by: Hannes Reinecke <hare@suse.de>
Tested-by: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/aic7xxx/aic7xxx_osm_pci.c')
-rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c index ea5687df732d..4488946cff2e 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | |||
@@ -49,6 +49,8 @@ static int ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, | |||
49 | static int ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc, | 49 | static int ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc, |
50 | u_long *bus_addr, | 50 | u_long *bus_addr, |
51 | uint8_t __iomem **maddr); | 51 | uint8_t __iomem **maddr); |
52 | static int ahc_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg); | ||
53 | static int ahc_linux_pci_dev_resume(struct pci_dev *pdev); | ||
52 | static void ahc_linux_pci_dev_remove(struct pci_dev *pdev); | 54 | static void ahc_linux_pci_dev_remove(struct pci_dev *pdev); |
53 | 55 | ||
54 | /* Define the macro locally since it's different for different class of chips. | 56 | /* Define the macro locally since it's different for different class of chips. |
@@ -133,10 +135,54 @@ MODULE_DEVICE_TABLE(pci, ahc_linux_pci_id_table); | |||
133 | static struct pci_driver aic7xxx_pci_driver = { | 135 | static struct pci_driver aic7xxx_pci_driver = { |
134 | .name = "aic7xxx", | 136 | .name = "aic7xxx", |
135 | .probe = ahc_linux_pci_dev_probe, | 137 | .probe = ahc_linux_pci_dev_probe, |
138 | #ifdef CONFIG_PM | ||
139 | .suspend = ahc_linux_pci_dev_suspend, | ||
140 | .resume = ahc_linux_pci_dev_resume, | ||
141 | #endif | ||
136 | .remove = ahc_linux_pci_dev_remove, | 142 | .remove = ahc_linux_pci_dev_remove, |
137 | .id_table = ahc_linux_pci_id_table | 143 | .id_table = ahc_linux_pci_id_table |
138 | }; | 144 | }; |
139 | 145 | ||
146 | static int | ||
147 | ahc_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg) | ||
148 | { | ||
149 | struct ahc_softc *ahc = pci_get_drvdata(pdev); | ||
150 | int rc; | ||
151 | |||
152 | if ((rc = ahc_suspend(ahc))) | ||
153 | return rc; | ||
154 | |||
155 | pci_save_state(pdev); | ||
156 | pci_disable_device(pdev); | ||
157 | |||
158 | if (mesg.event == PM_EVENT_SUSPEND) | ||
159 | pci_set_power_state(pdev, PCI_D3hot); | ||
160 | |||
161 | return rc; | ||
162 | } | ||
163 | |||
164 | static int | ||
165 | ahc_linux_pci_dev_resume(struct pci_dev *pdev) | ||
166 | { | ||
167 | struct ahc_softc *ahc = pci_get_drvdata(pdev); | ||
168 | int rc; | ||
169 | |||
170 | pci_set_power_state(pdev, PCI_D0); | ||
171 | pci_restore_state(pdev); | ||
172 | |||
173 | if ((rc = pci_enable_device(pdev))) { | ||
174 | dev_printk(KERN_ERR, &pdev->dev, | ||
175 | "failed to enable device after resume (%d)\n", rc); | ||
176 | return rc; | ||
177 | } | ||
178 | |||
179 | pci_set_master(pdev); | ||
180 | |||
181 | ahc_pci_resume(ahc); | ||
182 | |||
183 | return (ahc_resume(ahc)); | ||
184 | } | ||
185 | |||
140 | static void | 186 | static void |
141 | ahc_linux_pci_dev_remove(struct pci_dev *pdev) | 187 | ahc_linux_pci_dev_remove(struct pci_dev *pdev) |
142 | { | 188 | { |