Skip to content

Commit 75507a3

Browse files
rfvirgilwsakernel
authored andcommitted
i2c: designware: Fix unbalanced suspended flag
Ensure that i2c_mark_adapter_suspended() is always balanced by a call to i2c_mark_adapter_resumed(). dw_i2c_plat_resume() must always be called, so that i2c_mark_adapter_resumed() is called. This is not compatible with DPM_FLAG_MAY_SKIP_RESUME, so remove the flag. Since the controller is always resumed on system resume the dw_i2c_plat_complete() callback is redundant and has been removed. The unbalanced suspended flag was introduced by commit c57813b ("i2c: designware: Lock the adapter while setting the suspended flag") Before that commit, the system and runtime PM used the same functions. The DPM_FLAG_MAY_SKIP_RESUME was used to skip the system resume if the driver had been in runtime-suspend. If system resume was skipped, the suspended flag would be cleared by the next runtime resume. The check of the suspended flag was _after_ the call to pm_runtime_get_sync() in i2c_dw_xfer(). So either a system resume or a runtime resume would clear the flag before it was checked. Having introduced the unbalanced suspended flag with that commit, a further commit 80704a8 ("i2c: designware: Use the i2c_mark_adapter_suspended/resumed() helpers") changed from using a local suspended flag to using the i2c_mark_adapter_suspended/resumed() functions. These use a flag that is checked by I2C core code before issuing the transfer to the bus driver, so there was no opportunity for the bus driver to runtime resume itself before the flag check. Signed-off-by: Richard Fitzgerald <[email protected]> Fixes: c57813b ("i2c: designware: Lock the adapter while setting the suspended flag") Reviewed-by: Hans de Goede <[email protected]> Acked-by: Jarkko Nikula <[email protected]> Signed-off-by: Wolfram Sang <[email protected]>
1 parent c8c37bc commit 75507a3

File tree

1 file changed

+2
-18
lines changed

1 file changed

+2
-18
lines changed

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

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -351,13 +351,11 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
351351

352352
if (dev->flags & ACCESS_NO_IRQ_SUSPEND) {
353353
dev_pm_set_driver_flags(&pdev->dev,
354-
DPM_FLAG_SMART_PREPARE |
355-
DPM_FLAG_MAY_SKIP_RESUME);
354+
DPM_FLAG_SMART_PREPARE);
356355
} else {
357356
dev_pm_set_driver_flags(&pdev->dev,
358357
DPM_FLAG_SMART_PREPARE |
359-
DPM_FLAG_SMART_SUSPEND |
360-
DPM_FLAG_MAY_SKIP_RESUME);
358+
DPM_FLAG_SMART_SUSPEND);
361359
}
362360

363361
device_enable_async_suspend(&pdev->dev);
@@ -419,21 +417,8 @@ static int dw_i2c_plat_prepare(struct device *dev)
419417
*/
420418
return !has_acpi_companion(dev);
421419
}
422-
423-
static void dw_i2c_plat_complete(struct device *dev)
424-
{
425-
/*
426-
* The device can only be in runtime suspend at this point if it has not
427-
* been resumed throughout the ending system suspend/resume cycle, so if
428-
* the platform firmware might mess up with it, request the runtime PM
429-
* framework to resume it.
430-
*/
431-
if (pm_runtime_suspended(dev) && pm_resume_via_firmware())
432-
pm_request_resume(dev);
433-
}
434420
#else
435421
#define dw_i2c_plat_prepare NULL
436-
#define dw_i2c_plat_complete NULL
437422
#endif
438423

439424
#ifdef CONFIG_PM
@@ -483,7 +468,6 @@ static int __maybe_unused dw_i2c_plat_resume(struct device *dev)
483468

484469
static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
485470
.prepare = dw_i2c_plat_prepare,
486-
.complete = dw_i2c_plat_complete,
487471
SET_LATE_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
488472
SET_RUNTIME_PM_OPS(dw_i2c_plat_runtime_suspend, dw_i2c_plat_runtime_resume, NULL)
489473
};

0 commit comments

Comments
 (0)