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/aic79xx_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/aic79xx_osm_pci.c')
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_osm_pci.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c index c62ce41f2793..66f0259edb69 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c | |||
@@ -50,6 +50,8 @@ static int ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, | |||
50 | static int ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, | 50 | static int ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, |
51 | u_long *bus_addr, | 51 | u_long *bus_addr, |
52 | uint8_t __iomem **maddr); | 52 | uint8_t __iomem **maddr); |
53 | static int ahd_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg); | ||
54 | static int ahd_linux_pci_dev_resume(struct pci_dev *pdev); | ||
53 | static void ahd_linux_pci_dev_remove(struct pci_dev *pdev); | 55 | static void ahd_linux_pci_dev_remove(struct pci_dev *pdev); |
54 | 56 | ||
55 | /* Define the macro locally since it's different for different class of chips. | 57 | /* Define the macro locally since it's different for different class of chips. |
@@ -86,10 +88,58 @@ MODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table); | |||
86 | static struct pci_driver aic79xx_pci_driver = { | 88 | static struct pci_driver aic79xx_pci_driver = { |
87 | .name = "aic79xx", | 89 | .name = "aic79xx", |
88 | .probe = ahd_linux_pci_dev_probe, | 90 | .probe = ahd_linux_pci_dev_probe, |
91 | #ifdef CONFIG_PM | ||
92 | .suspend = ahd_linux_pci_dev_suspend, | ||
93 | .resume = ahd_linux_pci_dev_resume, | ||
94 | #endif | ||
89 | .remove = ahd_linux_pci_dev_remove, | 95 | .remove = ahd_linux_pci_dev_remove, |
90 | .id_table = ahd_linux_pci_id_table | 96 | .id_table = ahd_linux_pci_id_table |
91 | }; | 97 | }; |
92 | 98 | ||
99 | static int | ||
100 | ahd_linux_pci_dev_suspend(struct pci_dev *pdev, pm_message_t mesg) | ||
101 | { | ||
102 | struct ahd_softc *ahd = pci_get_drvdata(pdev); | ||
103 | int rc; | ||
104 | |||
105 | if ((rc = ahd_suspend(ahd))) | ||
106 | return rc; | ||
107 | |||
108 | ahd_pci_suspend(ahd); | ||
109 | |||
110 | pci_save_state(pdev); | ||
111 | pci_disable_device(pdev); | ||
112 | |||
113 | if (mesg.event == PM_EVENT_SUSPEND) | ||
114 | pci_set_power_state(pdev, PCI_D3hot); | ||
115 | |||
116 | return rc; | ||
117 | } | ||
118 | |||
119 | static int | ||
120 | ahd_linux_pci_dev_resume(struct pci_dev *pdev) | ||
121 | { | ||
122 | struct ahd_softc *ahd = pci_get_drvdata(pdev); | ||
123 | int rc; | ||
124 | |||
125 | pci_set_power_state(pdev, PCI_D0); | ||
126 | pci_restore_state(pdev); | ||
127 | |||
128 | if ((rc = pci_enable_device(pdev))) { | ||
129 | dev_printk(KERN_ERR, &pdev->dev, | ||
130 | "failed to enable device after resume (%d)\n", rc); | ||
131 | return rc; | ||
132 | } | ||
133 | |||
134 | pci_set_master(pdev); | ||
135 | |||
136 | ahd_pci_resume(ahd); | ||
137 | |||
138 | ahd_resume(ahd); | ||
139 | |||
140 | return rc; | ||
141 | } | ||
142 | |||
93 | static void | 143 | static void |
94 | ahd_linux_pci_dev_remove(struct pci_dev *pdev) | 144 | ahd_linux_pci_dev_remove(struct pci_dev *pdev) |
95 | { | 145 | { |