Thread (34 messages) 34 messages, 4 authors, 2018-12-07

[PATCH 0/4] Update am437x and am335x dts to probe with ti-sysc

From: tony@atomide.com (Tony Lindgren)
Date: 2018-09-26 16:23:03
Also in: linux-devicetree, linux-omap
Subsystem: i2c subsystem, i2c subsystem host drivers, omap i2c driver, omap1 support, omap2+ support, the rest · Maintainers: Wolfram Sang, Andi Shyti, Vignesh R, Aaro Koskinen, Janusz Krzysztofik, Andreas Kemnade, Kevin Hilman, Roger Quadros, Tony Lindgren, Linus Torvalds

* Tony Lindgren [off-list ref] [180926 16:04]:
* Keerthy [off-list ref] [180926 04:12]:
quoted
So the below patch is solving the problem only for the first iteration
but i see the problem recurring from second iteration of suspend.

I tried the above cycle multiple times on am437x-gp-evm. I believe
we are one step closer still not completely fixed.
OK thanks, that's interesting, I'll take a look. Good to hear
that is the reason for pixcir issues though :)
Heh ooops the previous i2c-omap patch I posted does unpaired
runtime_pm calls.. The put must be left out omap_i2c_resume().

Below is a better patch, seems to work for me multiple times
now.

Regards,

Tony

8< ---------------------------
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -208,6 +208,8 @@ struct omap_i2c_dev {
 						 * if set, should be trsh+1
 						 */
 	u32			rev;
+	unsigned int		is_suspended:1;
+	unsigned int		needs_resume:1;
 	unsigned		b_hw:1;		/* bad h/w fixes */
 	unsigned		bb_valid:1;	/* true when BB-bit reflects
 						 * the I2C bus state
@@ -1498,8 +1500,7 @@ static int omap_i2c_remove(struct platform_device *pdev)
 	return 0;
 }
 
-#ifdef CONFIG_PM
-static int omap_i2c_runtime_suspend(struct device *dev)
+static int __maybe_unused omap_i2c_runtime_suspend(struct device *dev)
 {
 	struct omap_i2c_dev *omap = dev_get_drvdata(dev);
 
@@ -1521,11 +1522,12 @@ static int omap_i2c_runtime_suspend(struct device *dev)
 	}
 
 	pinctrl_pm_select_sleep_state(dev);
+	omap->is_suspended = true;
 
 	return 0;
 }
 
-static int omap_i2c_runtime_resume(struct device *dev)
+static int __maybe_unused omap_i2c_runtime_resume(struct device *dev)
 {
 	struct omap_i2c_dev *omap = dev_get_drvdata(dev);
 
@@ -1535,6 +1537,51 @@ static int omap_i2c_runtime_resume(struct device *dev)
 		return 0;
 
 	__omap_i2c_init(omap);
+	omap->is_suspended = false;
+
+	return 0;
+}
+
+static int __maybe_unused omap_i2c_suspend(struct device *dev)
+{
+	struct omap_i2c_dev *ddata = dev_get_drvdata(dev);
+	int error;
+
+	/* Is device still enabled because of autosuspend? */
+	if (ddata->is_suspended)
+		return 0;
+
+	/* Paired with call in omap_i2c_resume() */
+	error = pm_runtime_put_sync_suspend(dev);
+	if (error < 0) {
+		dev_err(dev, "%s failed: %i\n", __func__, error);
+
+		return error;
+	}
+
+	ddata->needs_resume = true;
+
+	return 0;
+}
+
+static int __maybe_unused omap_i2c_resume(struct device *dev)
+{
+	struct omap_i2c_dev *ddata = dev_get_drvdata(dev);
+	int error;
+
+	if (!ddata->needs_resume)
+		return 0;
+
+	/* Paired with call in omap_i2c_suspend() */
+	error = pm_runtime_get_sync(dev);
+	if (error < 0) {
+		dev_err(dev, "%s failed: %i\n", __func__, error);
+		pm_runtime_put_noidle(dev);
+
+		return error;
+	}
+
+	ddata->needs_resume = false;
 
 	return 0;
 }
@@ -1542,18 +1589,15 @@ static int omap_i2c_runtime_resume(struct device *dev)
 static const struct dev_pm_ops omap_i2c_pm_ops = {
 	SET_RUNTIME_PM_OPS(omap_i2c_runtime_suspend,
 			   omap_i2c_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(omap_i2c_suspend, omap_i2c_resume)
 };
-#define OMAP_I2C_PM_OPS (&omap_i2c_pm_ops)
-#else
-#define OMAP_I2C_PM_OPS NULL
-#endif /* CONFIG_PM */
 
 static struct platform_driver omap_i2c_driver = {
 	.probe		= omap_i2c_probe,
 	.remove		= omap_i2c_remove,
 	.driver		= {
 		.name	= "omap_i2c",
-		.pm	= OMAP_I2C_PM_OPS,
+		.pm	= &omap_i2c_pm_ops,
 		.of_match_table = of_match_ptr(omap_i2c_of_match),
 	},
 };
-- 
2.19.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help