* [PATCH v2] PM / Runtime: let rpm_resume() succeed if RPM_ACTIVE, even when disabled
@ 2012-09-21 22:47 Kevin Hilman
2012-09-22 11:25 ` Rafael J. Wysocki
0 siblings, 1 reply; 4+ messages in thread
From: Kevin Hilman @ 2012-09-21 22:47 UTC (permalink / raw)
To: linux-arm-kernel
From: Kevin Hilman <khilman@ti.com>
There are several drivers where the return value of
pm_runtime_get_sync() is used to decide whether or not it is safe to
access hardware and that don't provide .suspend() callbacks for system
suspend (but may use late/noirq callbacks.) If such a driver happens
to call pm_runtime_get_sync() during system suspend, after the core
has disabled runtime PM, it will get the error code and will decide
that the hardware should not be accessed, although this may be a wrong
conclusion, depending on the state of the device when runtime PM was
disabled.
Drivers might work around this problem by using a test like:
ret = pm_runtime_get_sync(dev);
if (!ret || (ret == -EACCES && driver_private_data(dev)->suspended)) {
/* access hardware */
}
where driver_private_data(dev)->suspended is a flag set by the
driver's .suspend() method (that would have to be added for this
purpose). However, that potentially would need to be done by multiple
drivers which means quite a lot of duplicated code and bloat.
To avoid that we can use the observation that the core sets
dev->power.is_suspended before disabling runtime PM and use that
instead of the driver's private flag. Still, potentially many drivers
would need to repeat that same check in quite a few places, so it's
better to let the core do it.
Then we can be a bit smarter and check whether or not runtime PM was
disabled by the core only (disable_depth == 1) or by someone else in
addition to the core (disable_depth > 1). In the former case
rpm_resume() can return 1 if the runtime PM status is RPM_ACTIVE,
because it means the device was active when the core disabled runtime
PM. In the latter case it should still return -EACCES, because it
isn't clear why runtime PM has been disabled.
Tested on AM3730/Beagle-xM where a wakeup IRQ firing during the late
suspend phase triggers runtime PM activity in the I2C driver since the
wakeup IRQ is on an I2C-connected PMIC.
Cc: Rafael J. Wysocki <rjw@sisk.pl>
Cc: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Kevin Hilman <khilman@ti.com>
---
v2:
- major changelog rewrite, based largely on input from Rafael
- add check for disable_depth == 1 and move to separate if statement,
both suggested by Alan Stern
drivers/base/power/runtime.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 7d9c1cb..d43856b 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -509,6 +509,9 @@ static int rpm_resume(struct device *dev, int rpmflags)
repeat:
if (dev->power.runtime_error)
retval = -EINVAL;
+ else if (dev->power.disable_depth == 1 && dev->power.is_suspended
+ && dev->power.runtime_status == RPM_ACTIVE)
+ retval = 1;
else if (dev->power.disable_depth > 0)
retval = -EACCES;
if (retval)
--
1.7.9.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v2] PM / Runtime: let rpm_resume() succeed if RPM_ACTIVE, even when disabled
2012-09-21 22:47 [PATCH v2] PM / Runtime: let rpm_resume() succeed if RPM_ACTIVE, even when disabled Kevin Hilman
@ 2012-09-22 11:25 ` Rafael J. Wysocki
2012-09-22 15:33 ` Alan Stern
0 siblings, 1 reply; 4+ messages in thread
From: Rafael J. Wysocki @ 2012-09-22 11:25 UTC (permalink / raw)
To: linux-arm-kernel
On Saturday, September 22, 2012, Kevin Hilman wrote:
> From: Kevin Hilman <khilman@ti.com>
>
> There are several drivers where the return value of
> pm_runtime_get_sync() is used to decide whether or not it is safe to
> access hardware and that don't provide .suspend() callbacks for system
> suspend (but may use late/noirq callbacks.) If such a driver happens
> to call pm_runtime_get_sync() during system suspend, after the core
> has disabled runtime PM, it will get the error code and will decide
> that the hardware should not be accessed, although this may be a wrong
> conclusion, depending on the state of the device when runtime PM was
> disabled.
>
> Drivers might work around this problem by using a test like:
>
> ret = pm_runtime_get_sync(dev);
> if (!ret || (ret == -EACCES && driver_private_data(dev)->suspended)) {
> /* access hardware */
> }
>
> where driver_private_data(dev)->suspended is a flag set by the
> driver's .suspend() method (that would have to be added for this
> purpose). However, that potentially would need to be done by multiple
> drivers which means quite a lot of duplicated code and bloat.
>
> To avoid that we can use the observation that the core sets
> dev->power.is_suspended before disabling runtime PM and use that
> instead of the driver's private flag. Still, potentially many drivers
> would need to repeat that same check in quite a few places, so it's
> better to let the core do it.
>
> Then we can be a bit smarter and check whether or not runtime PM was
> disabled by the core only (disable_depth == 1) or by someone else in
> addition to the core (disable_depth > 1). In the former case
> rpm_resume() can return 1 if the runtime PM status is RPM_ACTIVE,
> because it means the device was active when the core disabled runtime
> PM. In the latter case it should still return -EACCES, because it
> isn't clear why runtime PM has been disabled.
>
> Tested on AM3730/Beagle-xM where a wakeup IRQ firing during the late
> suspend phase triggers runtime PM activity in the I2C driver since the
> wakeup IRQ is on an I2C-connected PMIC.
>
> Cc: Rafael J. Wysocki <rjw@sisk.pl>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Signed-off-by: Kevin Hilman <khilman@ti.com>
> ---
> v2:
> - major changelog rewrite, based largely on input from Rafael
> - add check for disable_depth == 1 and move to separate if statement,
> both suggested by Alan Stern
OK, this looks good to me, thanks!
Alan, what do you think?
Rafael
> drivers/base/power/runtime.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
> index 7d9c1cb..d43856b 100644
> --- a/drivers/base/power/runtime.c
> +++ b/drivers/base/power/runtime.c
> @@ -509,6 +509,9 @@ static int rpm_resume(struct device *dev, int rpmflags)
> repeat:
> if (dev->power.runtime_error)
> retval = -EINVAL;
> + else if (dev->power.disable_depth == 1 && dev->power.is_suspended
> + && dev->power.runtime_status == RPM_ACTIVE)
> + retval = 1;
> else if (dev->power.disable_depth > 0)
> retval = -EACCES;
> if (retval)
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2] PM / Runtime: let rpm_resume() succeed if RPM_ACTIVE, even when disabled
2012-09-22 11:25 ` Rafael J. Wysocki
@ 2012-09-22 15:33 ` Alan Stern
2012-09-22 19:42 ` Rafael J. Wysocki
0 siblings, 1 reply; 4+ messages in thread
From: Alan Stern @ 2012-09-22 15:33 UTC (permalink / raw)
To: linux-arm-kernel
On Sat, 22 Sep 2012, Rafael J. Wysocki wrote:
> On Saturday, September 22, 2012, Kevin Hilman wrote:
> OK, this looks good to me, thanks!
>
> Alan, what do you think?
>
> Rafael
> > --- a/drivers/base/power/runtime.c
> > +++ b/drivers/base/power/runtime.c
> > @@ -509,6 +509,9 @@ static int rpm_resume(struct device *dev, int rpmflags)
> > repeat:
> > if (dev->power.runtime_error)
> > retval = -EINVAL;
> > + else if (dev->power.disable_depth == 1 && dev->power.is_suspended
> > + && dev->power.runtime_status == RPM_ACTIVE)
> > + retval = 1;
> > else if (dev->power.disable_depth > 0)
> > retval = -EACCES;
> > if (retval)
Well, I'd prefer the indentation on the continuation line to be
different from the indentation of the following line, and I'd prefer
to have a comment explaining the reason for the exception.
But these are only matters of taste; the implementation itself looks
good.
Alan Stern
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2] PM / Runtime: let rpm_resume() succeed if RPM_ACTIVE, even when disabled
2012-09-22 15:33 ` Alan Stern
@ 2012-09-22 19:42 ` Rafael J. Wysocki
0 siblings, 0 replies; 4+ messages in thread
From: Rafael J. Wysocki @ 2012-09-22 19:42 UTC (permalink / raw)
To: linux-arm-kernel
On Saturday, September 22, 2012, Alan Stern wrote:
> On Sat, 22 Sep 2012, Rafael J. Wysocki wrote:
>
> > On Saturday, September 22, 2012, Kevin Hilman wrote:
>
> > OK, this looks good to me, thanks!
> >
> > Alan, what do you think?
> >
> > Rafael
>
> > > --- a/drivers/base/power/runtime.c
> > > +++ b/drivers/base/power/runtime.c
> > > @@ -509,6 +509,9 @@ static int rpm_resume(struct device *dev, int rpmflags)
> > > repeat:
> > > if (dev->power.runtime_error)
> > > retval = -EINVAL;
> > > + else if (dev->power.disable_depth == 1 && dev->power.is_suspended
> > > + && dev->power.runtime_status == RPM_ACTIVE)
> > > + retval = 1;
> > > else if (dev->power.disable_depth > 0)
> > > retval = -EACCES;
> > > if (retval)
>
> Well, I'd prefer the indentation on the continuation line to be
> different from the indentation of the following line, and I'd prefer
> to have a comment explaining the reason for the exception.
>
> But these are only matters of taste; the implementation itself looks
> good.
Thanks!
I've applied the patch as v3.7 material (and fixed up the white space).
Rafael
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2012-09-22 19:42 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-21 22:47 [PATCH v2] PM / Runtime: let rpm_resume() succeed if RPM_ACTIVE, even when disabled Kevin Hilman
2012-09-22 11:25 ` Rafael J. Wysocki
2012-09-22 15:33 ` Alan Stern
2012-09-22 19:42 ` Rafael J. Wysocki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).