diff mbox

[v1,2/7] serdev: add dev_pm_domain_attach|detach()

Message ID f976766cd499c8d7053a1f442aba1494b4d3314f.1522736996.git.sean.wang@mediatek.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sean Wang April 3, 2018, 7:15 a.m. UTC
From: Sean Wang <sean.wang@mediatek.com>

In order to open up the required power gate before any operation can be
effectively performed over the serial bus between CPU and serdev, it's
clearly essential to add common attach functions for PM domains to serdev
at the probe phase.

Similarly, the relevant dettach function for the PM domains should be
properly and reversely added at the remove phase.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-serial@vger.kernel.org
---
 drivers/tty/serdev/core.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

Comments

Marcel Holtmann April 3, 2018, 10:29 a.m. UTC | #1
Hi Sean,

> In order to open up the required power gate before any operation can be
> effectively performed over the serial bus between CPU and serdev, it's
> clearly essential to add common attach functions for PM domains to serdev
> at the probe phase.
> 
> Similarly, the relevant dettach function for the PM domains should be
> properly and reversely added at the remove phase.
> 
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Ulf Hansson <ulf.hansson@linaro.org>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Jiri Slaby <jslaby@suse.com>
> Cc: linux-serial@vger.kernel.org
> ---
> drivers/tty/serdev/core.c | 14 +++++++++++++-
> 1 file changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
> index df93b72..c93d8ee 100644
> --- a/drivers/tty/serdev/core.c
> +++ b/drivers/tty/serdev/core.c
> @@ -13,6 +13,7 @@
> #include <linux/module.h>
> #include <linux/of.h>
> #include <linux/of_device.h>
> +#include <linux/pm_domain.h>
> #include <linux/serdev.h>
> #include <linux/slab.h>
> 
> @@ -330,8 +331,16 @@ EXPORT_SYMBOL_GPL(serdev_device_set_tiocm);
> static int serdev_drv_probe(struct device *dev)
> {
> 	const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
> +	int ret;
> +
> +	ret = dev_pm_domain_attach(dev, true);
> +	if (ret != -EPROBE_DEFER) {
> +		ret = sdrv->probe(to_serdev_device(dev));
> +		if (ret)
> +			dev_pm_domain_detach(dev, true);
> +	}

so if this is deferred, when does the serdev device gets probed?

> 
> -	return sdrv->probe(to_serdev_device(dev));
> +	return ret;
> }
> 
> static int serdev_drv_remove(struct device *dev)
> @@ -339,6 +348,9 @@ static int serdev_drv_remove(struct device *dev)
> 	const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
> 	if (sdrv->remove)
> 		sdrv->remove(to_serdev_device(dev));
> +
> +	dev_pm_domain_detach(dev, true);
> +
> 	return 0;
> }

Regards

Marcel
Sean Wang April 26, 2018, 5:29 a.m. UTC | #2
On Tue, 2018-04-03 at 12:29 +0200, Marcel Holtmann wrote:
> Hi Sean,
> 
> > In order to open up the required power gate before any operation can be
> > effectively performed over the serial bus between CPU and serdev, it's
> > clearly essential to add common attach functions for PM domains to serdev
> > at the probe phase.
> > 
> > Similarly, the relevant dettach function for the PM domains should be
> > properly and reversely added at the remove phase.
> > 
> > Signed-off-by: Sean Wang <sean.wang@mediatek.com>
> > Cc: Rob Herring <robh@kernel.org>
> > Cc: Ulf Hansson <ulf.hansson@linaro.org>
> > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > Cc: Jiri Slaby <jslaby@suse.com>
> > Cc: linux-serial@vger.kernel.org
> > ---
> > drivers/tty/serdev/core.c | 14 +++++++++++++-
> > 1 file changed, 13 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
> > index df93b72..c93d8ee 100644
> > --- a/drivers/tty/serdev/core.c
> > +++ b/drivers/tty/serdev/core.c
> > @@ -13,6 +13,7 @@
> > #include <linux/module.h>
> > #include <linux/of.h>
> > #include <linux/of_device.h>
> > +#include <linux/pm_domain.h>
> > #include <linux/serdev.h>
> > #include <linux/slab.h>
> > 
> > @@ -330,8 +331,16 @@ EXPORT_SYMBOL_GPL(serdev_device_set_tiocm);
> > static int serdev_drv_probe(struct device *dev)
> > {
> > 	const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
> > +	int ret;
> > +
> > +	ret = dev_pm_domain_attach(dev, true);
> > +	if (ret != -EPROBE_DEFER) {
> > +		ret = sdrv->probe(to_serdev_device(dev));
> > +		if (ret)
> > +			dev_pm_domain_detach(dev, true);
> > +	}
> 
> so if this is deferred, when does the serdev device gets probed?
> 

driver probe deferral mechanism is supported in driver core

deferred_probe_initcall makes sure that deferred probing is
delayed until late_initcall time.


Below is a few of word I got from drivers/base/core.c I thought it helps
to understand the mechanism in complete picture

* If a required resource is not available yet, a driver can
request probing to be deferred by returning -EPROBE_DEFER from
its probe hook.

* A driver returning -EPROBE_DEFER causes the device to be added to the
pending list.  A successful driver probe will trigger moving all devices
from the pending to the active list so that the workqueue will
eventually retry them.

> > 
> > -	return sdrv->probe(to_serdev_device(dev));
> > +	return ret;
> > }
> > 
> > static int serdev_drv_remove(struct device *dev)
> > @@ -339,6 +348,9 @@ static int serdev_drv_remove(struct device *dev)
> > 	const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
> > 	if (sdrv->remove)
> > 		sdrv->remove(to_serdev_device(dev));
> > +
> > +	dev_pm_domain_detach(dev, true);
> > +
> > 	return 0;
> > }
> 
> Regards
> 
> Marcel
>
diff mbox

Patch

diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index df93b72..c93d8ee 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -13,6 +13,7 @@ 
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/pm_domain.h>
 #include <linux/serdev.h>
 #include <linux/slab.h>
 
@@ -330,8 +331,16 @@  EXPORT_SYMBOL_GPL(serdev_device_set_tiocm);
 static int serdev_drv_probe(struct device *dev)
 {
 	const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
+	int ret;
+
+	ret = dev_pm_domain_attach(dev, true);
+	if (ret != -EPROBE_DEFER) {
+		ret = sdrv->probe(to_serdev_device(dev));
+		if (ret)
+			dev_pm_domain_detach(dev, true);
+	}
 
-	return sdrv->probe(to_serdev_device(dev));
+	return ret;
 }
 
 static int serdev_drv_remove(struct device *dev)
@@ -339,6 +348,9 @@  static int serdev_drv_remove(struct device *dev)
 	const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
 	if (sdrv->remove)
 		sdrv->remove(to_serdev_device(dev));
+
+	dev_pm_domain_detach(dev, true);
+
 	return 0;
 }