aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2014-02-04 07:37:07 -0500
committerWolfram Sang <wsa@the-dreams.de>2014-03-09 04:29:21 -0400
commitbe58eda775c8753a3e92ec398124279abc59aa0d (patch)
tree06b4d716912e9dd21e80c58c57f612125bd91355 /drivers/i2c
parent6468276b22069d4442aafcd8c59e5d8ccae23f5f (diff)
i2c: designware-pci: Cleanup driver power management
The PCI part of the DesignWare I2C driver does a lot of things that are not required anymore. For example drivers aren't supposed to handle PCI state transitions themselves. This is all provided by the PCI bus core already. In addition to that there is no point scheduling RPM suspend on driver's idle hook but instead we can use RPM autosuspend for this (which is enabled in the driver already). As a bonus, this patch also fixes following compile warning which is emitted when the driver was compiled without CONFIG_PM_RUNTIME set: drivers/i2c/busses/i2c-designware-pcidrv.c:245:12: warning: ‘i2c_dw_pci_runtime_idle’ defined but not used [-Wunused-function] Reported-by: xinhui.pan <xinhuix.pan@intel.com> Reported-by: Jingoo Han <jg1.han@samsung.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-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;