Skip to content

Commit 534696e

Browse files
andy-shevAndi Shyti
authored andcommitted
i2c: designware: Consolidate PM ops
We have the same (*) PM ops in the PCI and platform drivers. Instead, consolidate that PM ops under exported variable and deduplicate them. *) With the subtle ACPI and P-Unit behaviour differences in PCI case. But this is not a problem as for ACPI we need to take care of the P-Unit semaphore anyway and calling PM ops for PCI makes sense as it might provide specific operation regions in ACPI (however there are no known devices on market that are using it with PCI enabled I2C). Note, the clocks are not in use in the PCI case. Reviewed-by: Andi Shyti <[email protected]> Signed-off-by: Andy Shevchenko <[email protected]> Tested-by: Sanket Goswami <[email protected]> Acked-by: Jarkko Nikula <[email protected]> Signed-off-by: Andi Shyti <[email protected]>
1 parent 01e00b5 commit 534696e

File tree

4 files changed

+68
-105
lines changed

4 files changed

+68
-105
lines changed

drivers/i2c/busses/i2c-designware-common.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/kernel.h>
2222
#include <linux/module.h>
2323
#include <linux/of.h>
24+
#include <linux/pm.h>
2425
#include <linux/pm_runtime.h>
2526
#include <linux/property.h>
2627
#include <linux/regmap.h>
@@ -736,5 +737,66 @@ void i2c_dw_disable(struct dw_i2c_dev *dev)
736737
}
737738
EXPORT_SYMBOL_GPL(i2c_dw_disable);
738739

740+
static int i2c_dw_prepare(struct device *device)
741+
{
742+
/*
743+
* If the ACPI companion device object is present for this device,
744+
* it may be accessed during suspend and resume of other devices via
745+
* I2C operation regions, so tell the PM core and middle layers to
746+
* avoid skipping system suspend/resume callbacks for it in that case.
747+
*/
748+
return !has_acpi_companion(device);
749+
}
750+
751+
static int i2c_dw_runtime_suspend(struct device *device)
752+
{
753+
struct dw_i2c_dev *dev = dev_get_drvdata(device);
754+
755+
if (dev->shared_with_punit)
756+
return 0;
757+
758+
i2c_dw_disable(dev);
759+
i2c_dw_prepare_clk(dev, false);
760+
761+
return 0;
762+
}
763+
764+
static int i2c_dw_suspend(struct device *device)
765+
{
766+
struct dw_i2c_dev *dev = dev_get_drvdata(device);
767+
768+
i2c_mark_adapter_suspended(&dev->adapter);
769+
770+
return i2c_dw_runtime_suspend(device);
771+
}
772+
773+
static int i2c_dw_runtime_resume(struct device *device)
774+
{
775+
struct dw_i2c_dev *dev = dev_get_drvdata(device);
776+
777+
if (!dev->shared_with_punit)
778+
i2c_dw_prepare_clk(dev, true);
779+
780+
dev->init(dev);
781+
782+
return 0;
783+
}
784+
785+
static int i2c_dw_resume(struct device *device)
786+
{
787+
struct dw_i2c_dev *dev = dev_get_drvdata(device);
788+
789+
i2c_dw_runtime_resume(device);
790+
i2c_mark_adapter_resumed(&dev->adapter);
791+
792+
return 0;
793+
}
794+
795+
EXPORT_GPL_DEV_PM_OPS(i2c_dw_dev_pm_ops) = {
796+
.prepare = pm_sleep_ptr(i2c_dw_prepare),
797+
LATE_SYSTEM_SLEEP_PM_OPS(i2c_dw_suspend, i2c_dw_resume)
798+
RUNTIME_PM_OPS(i2c_dw_runtime_suspend, i2c_dw_runtime_resume, NULL)
799+
};
800+
739801
MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter core");
740802
MODULE_LICENSE("GPL");

drivers/i2c/busses/i2c-designware-core.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/dev_printk.h>
1616
#include <linux/errno.h>
1717
#include <linux/i2c.h>
18+
#include <linux/pm.h>
1819
#include <linux/regmap.h>
1920
#include <linux/types.h>
2021

@@ -341,6 +342,8 @@ int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev);
341342
int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev);
342343
u32 i2c_dw_func(struct i2c_adapter *adap);
343344

345+
extern const struct dev_pm_ops i2c_dw_dev_pm_ops;
346+
344347
static inline void __i2c_dw_enable(struct dw_i2c_dev *dev)
345348
{
346349
dev->status |= STATUS_ACTIVE;

drivers/i2c/busses/i2c-designware-pcidrv.c

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/kernel.h>
2020
#include <linux/module.h>
2121
#include <linux/pci.h>
22+
#include <linux/pm.h>
2223
#include <linux/pm_runtime.h>
2324
#include <linux/power_supply.h>
2425
#include <linux/sched.h>
@@ -194,47 +195,6 @@ static struct dw_pci_controller dw_pci_controllers[] = {
194195
},
195196
};
196197

197-
static int __maybe_unused i2c_dw_pci_runtime_suspend(struct device *dev)
198-
{
199-
struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
200-
201-
i2c_dw_disable(i_dev);
202-
return 0;
203-
}
204-
205-
static int __maybe_unused i2c_dw_pci_suspend(struct device *dev)
206-
{
207-
struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
208-
209-
i2c_mark_adapter_suspended(&i_dev->adapter);
210-
211-
return i2c_dw_pci_runtime_suspend(dev);
212-
}
213-
214-
static int __maybe_unused i2c_dw_pci_runtime_resume(struct device *dev)
215-
{
216-
struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
217-
218-
return i_dev->init(i_dev);
219-
}
220-
221-
static int __maybe_unused i2c_dw_pci_resume(struct device *dev)
222-
{
223-
struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
224-
int ret;
225-
226-
ret = i2c_dw_pci_runtime_resume(dev);
227-
228-
i2c_mark_adapter_resumed(&i_dev->adapter);
229-
230-
return ret;
231-
}
232-
233-
static const struct dev_pm_ops i2c_dw_pm_ops = {
234-
SET_SYSTEM_SLEEP_PM_OPS(i2c_dw_pci_suspend, i2c_dw_pci_resume)
235-
SET_RUNTIME_PM_OPS(i2c_dw_pci_runtime_suspend, i2c_dw_pci_runtime_resume, NULL)
236-
};
237-
238198
static const struct property_entry dgpu_properties[] = {
239199
/* USB-C doesn't power the system */
240200
PROPERTY_ENTRY_U8("scope", POWER_SUPPLY_SCOPE_DEVICE),
@@ -402,7 +362,7 @@ static struct pci_driver dw_i2c_driver = {
402362
.probe = i2c_dw_pci_probe,
403363
.remove = i2c_dw_pci_remove,
404364
.driver = {
405-
.pm = &i2c_dw_pm_ops,
365+
.pm = pm_ptr(&i2c_dw_dev_pm_ops),
406366
},
407367
.id_table = i2c_designware_pci_ids,
408368
};

drivers/i2c/busses/i2c-designware-platdrv.c

Lines changed: 1 addition & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
#include <linux/reset.h>
3030
#include <linux/sched.h>
3131
#include <linux/slab.h>
32-
#include <linux/suspend.h>
3332
#include <linux/units.h>
3433

3534
#include "i2c-designware-core.h"
@@ -339,67 +338,6 @@ static void dw_i2c_plat_remove(struct platform_device *pdev)
339338
reset_control_assert(dev->rst);
340339
}
341340

342-
static int dw_i2c_plat_prepare(struct device *dev)
343-
{
344-
/*
345-
* If the ACPI companion device object is present for this device, it
346-
* may be accessed during suspend and resume of other devices via I2C
347-
* operation regions, so tell the PM core and middle layers to avoid
348-
* skipping system suspend/resume callbacks for it in that case.
349-
*/
350-
return !has_acpi_companion(dev);
351-
}
352-
353-
static int dw_i2c_plat_runtime_suspend(struct device *dev)
354-
{
355-
struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
356-
357-
if (i_dev->shared_with_punit)
358-
return 0;
359-
360-
i2c_dw_disable(i_dev);
361-
i2c_dw_prepare_clk(i_dev, false);
362-
363-
return 0;
364-
}
365-
366-
static int dw_i2c_plat_suspend(struct device *dev)
367-
{
368-
struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
369-
370-
i2c_mark_adapter_suspended(&i_dev->adapter);
371-
372-
return dw_i2c_plat_runtime_suspend(dev);
373-
}
374-
375-
static int dw_i2c_plat_runtime_resume(struct device *dev)
376-
{
377-
struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
378-
379-
if (!i_dev->shared_with_punit)
380-
i2c_dw_prepare_clk(i_dev, true);
381-
382-
i_dev->init(i_dev);
383-
384-
return 0;
385-
}
386-
387-
static int dw_i2c_plat_resume(struct device *dev)
388-
{
389-
struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
390-
391-
dw_i2c_plat_runtime_resume(dev);
392-
i2c_mark_adapter_resumed(&i_dev->adapter);
393-
394-
return 0;
395-
}
396-
397-
static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
398-
.prepare = pm_sleep_ptr(dw_i2c_plat_prepare),
399-
LATE_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
400-
RUNTIME_PM_OPS(dw_i2c_plat_runtime_suspend, dw_i2c_plat_runtime_resume, NULL)
401-
};
402-
403341
static const struct of_device_id dw_i2c_of_match[] = {
404342
{ .compatible = "snps,designware-i2c", },
405343
{ .compatible = "mscc,ocelot-i2c", .data = (void *)MODEL_MSCC_OCELOT },
@@ -442,7 +380,7 @@ static struct platform_driver dw_i2c_driver = {
442380
.name = "i2c_designware",
443381
.of_match_table = dw_i2c_of_match,
444382
.acpi_match_table = dw_i2c_acpi_match,
445-
.pm = pm_ptr(&dw_i2c_dev_pm_ops),
383+
.pm = pm_ptr(&i2c_dw_dev_pm_ops),
446384
},
447385
.id_table = dw_i2c_platform_ids,
448386
};

0 commit comments

Comments
 (0)