aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/i2c/busses/i2c-designware-pcidrv.c57
1 files changed, 7 insertions, 50 deletions
diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c
index f6ed06c966ee..c0a87a5eb63e 100644
--- a/drivers/i2c/busses/i2c-designware-pcidrv.c
+++ b/drivers/i2c/busses/i2c-designware-pcidrv.c
@@ -138,69 +138,25 @@ static struct i2c_algorithm i2c_dw_algo = {
138 .functionality = i2c_dw_func, 138 .functionality = i2c_dw_func,
139}; 139};
140 140
141#ifdef CONFIG_PM
141static int i2c_dw_pci_suspend(struct device *dev) 142static int i2c_dw_pci_suspend(struct device *dev)
142{ 143{
143 struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); 144 struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
144 struct dw_i2c_dev *i2c = pci_get_drvdata(pdev);
145 int err;
146
147
148 i2c_dw_disable(i2c);
149
150 err = pci_save_state(pdev);
151 if (err) {
152 dev_err(&pdev->dev, "pci_save_state failed\n");
153 return err;
154 }
155
156 err = pci_set_power_state(pdev, PCI_D3hot);
157 if (err) {
158 dev_err(&pdev->dev, "pci_set_power_state failed\n");
159 return err;
160 }
161 145
146 i2c_dw_disable(pci_get_drvdata(pdev));
162 return 0; 147 return 0;
163} 148}
164 149
165static int i2c_dw_pci_resume(struct device *dev) 150static int i2c_dw_pci_resume(struct device *dev)
166{ 151{
167 struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); 152 struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
168 struct dw_i2c_dev *i2c = pci_get_drvdata(pdev);
169 int err;
170 u32 enabled;
171
172 enabled = i2c_dw_is_enabled(i2c);
173 if (enabled)
174 return 0;
175
176 err = pci_set_power_state(pdev, PCI_D0);
177 if (err) {
178 dev_err(&pdev->dev, "pci_set_power_state() failed\n");
179 return err;
180 }
181 153
182 pci_restore_state(pdev); 154 return i2c_dw_init(pci_get_drvdata(pdev));
183
184 i2c_dw_init(i2c);
185 return 0;
186} 155}
156#endif
187 157
188static int i2c_dw_pci_runtime_idle(struct device *dev) 158static UNIVERSAL_DEV_PM_OPS(i2c_dw_pm_ops, i2c_dw_pci_suspend,
189{ 159 i2c_dw_pci_resume, NULL);
190 int err = pm_schedule_suspend(dev, 500);
191 dev_dbg(dev, "runtime_idle called\n");
192
193 if (err != 0)
194 return 0;
195 return -EBUSY;
196}
197
198static const struct dev_pm_ops i2c_dw_pm_ops = {
199 .resume = i2c_dw_pci_resume,
200 .suspend = i2c_dw_pci_suspend,
201 SET_RUNTIME_PM_OPS(i2c_dw_pci_suspend, i2c_dw_pci_resume,
202 i2c_dw_pci_runtime_idle)
203};
204 160
205static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev) 161static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
206{ 162{
@@ -290,6 +246,7 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
290 246
291 pm_runtime_set_autosuspend_delay(&pdev->dev, 1000); 247 pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
292 pm_runtime_use_autosuspend(&pdev->dev); 248 pm_runtime_use_autosuspend(&pdev->dev);
249 pm_runtime_put_autosuspend(&pdev->dev);
293 pm_runtime_allow(&pdev->dev); 250 pm_runtime_allow(&pdev->dev);
294 251
295 return 0; 252 return 0;