@@ -1770,7 +1770,8 @@ static int i2c_imx_probe(struct platform_device *pdev)
goto rpm_disable;
/* Request IRQ */
- ret = request_irq(irq, i2c_imx_isr, IRQF_SHARED, pdev->name, i2c_imx);
+ ret = request_irq(irq, i2c_imx_isr, IRQF_SHARED | IRQF_NO_SUSPEND,
+ pdev->name, i2c_imx);
if (ret) {
dev_err(&pdev->dev, "can't claim irq %d\n", irq);
goto rpm_disable;
@@ -1894,7 +1895,36 @@ static int i2c_imx_runtime_resume(struct device *dev)
return ret;
}
+static int i2c_imx_suspend(struct device *dev)
+{
+ /*
+ * Some I2C devices may need I2C controller up during resume_noirq()
+ * or suspend_noirq(), if the controller is autosuspended, there is
+ * no way to wakeup it once runtime pm is disabled (in suspend_late()).
+ * When system resume, I2C controller will be available until runtime pm
+ * is enabled(in_resume_early()). But it is too late for some devices.
+ * Wakeup the controller in suspend() callback while runtime pm is enabled,
+ * I2C controller will be available until suspend_noirq() callback
+ * (pm_runtime_force_suspend()) is called. During the resume, I2C controller
+ * can be restored by resume_noirq() callback (pm_runtime_force_resume()).
+ * Then resume() callback enables autosuspend. It will make I2C controller
+ * available until system suspend_noirq() and from resume_noirq().
+ */
+ return pm_runtime_resume_and_get(dev);
+}
+
+static int i2c_imx_resume(struct device *dev)
+{
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
+
+ return 0;
+}
+
static const struct dev_pm_ops i2c_imx_pm_ops = {
+ NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+ SYSTEM_SLEEP_PM_OPS(i2c_imx_suspend, i2c_imx_resume)
RUNTIME_PM_OPS(i2c_imx_runtime_suspend, i2c_imx_runtime_resume, NULL)
};