linux-omap.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: Alan Stern <stern@rowland.harvard.edu>
Cc: Linux-pm mailing list <linux-pm@lists.linux-foundation.org>,
	Kevin Hilman <khilman@deeprootsystems.com>,
	Partha Basak <p-basak2@ti.com>,
	linux-omap@vger.kernel.org
Subject: Re: [PATCH] PM: add synchronous runtime interface for interrupt handlers
Date: Thu, 30 Sep 2010 22:15:59 +0200	[thread overview]
Message-ID: <201009302215.59937.rjw@sisk.pl> (raw)
In-Reply-To: <Pine.LNX.4.44L0.1009301420520.1314-100000@iolanthe.rowland.org>

Hi,

On Thursday, September 30, 2010, Alan Stern wrote:
> This patch (as1431) adds a synchronous runtime-PM interface suitable
> for use in interrupt handlers.  Four new helper functions are defined:
> 
> 	pm_runtime_suspend_irq(), pm_runtime_resume_irq(),
> 	pm_runtime_get_sync_irq(), pm_runtime_put_sync_irq(),
> 
> together with pm_runtime_callbacks_in_irq(), which subsystems use to
> tell the PM core that the runtime callbacks should be invoked with
> interrupts disabled.
> 
> Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
> 
> ---
> 
> In the end it turned out that a new RPM_IRQ call flag was needed along
> with the callbacks_in_irq flag in dev_pm_info.  The latter is required
> for the reasons I explained before, and RPM_IRQ tells the core whether
> or not it must leave interrupts disabled while waiting for a concurrent
> state change.
> 
> Kevin, this should be good enough to satisfy all your needs.  How does 
> it look?
> 
> Alan Stern
> 
> 
> Index: usb-2.6/include/linux/pm.h
> ===================================================================
> --- usb-2.6.orig/include/linux/pm.h
> +++ usb-2.6/include/linux/pm.h
> @@ -485,6 +485,7 @@ struct dev_pm_info {
>  	unsigned int		run_wake:1;
>  	unsigned int		runtime_auto:1;
>  	unsigned int		no_callbacks:1;
> +	unsigned int		callbacks_in_irq:1;

I kind of don't like this name.  What about irq_safe ?

>  	unsigned int		use_autosuspend:1;
>  	unsigned int		timer_autosuspends:1;
>  	enum rpm_request	request;
> Index: usb-2.6/include/linux/pm_runtime.h
> ===================================================================
> --- usb-2.6.orig/include/linux/pm_runtime.h
> +++ usb-2.6/include/linux/pm_runtime.h
> @@ -21,6 +21,7 @@
>  #define RPM_GET_PUT		0x04	/* Increment/decrement the
>  					    usage_count */
>  #define RPM_AUTO		0x08	/* Use autosuspend_delay */
> +#define RPM_IRQ			0x10	/* Don't enable interrupts */
>  
>  #ifdef CONFIG_PM_RUNTIME
>  
> @@ -40,6 +41,7 @@ extern int pm_generic_runtime_idle(struc
>  extern int pm_generic_runtime_suspend(struct device *dev);
>  extern int pm_generic_runtime_resume(struct device *dev);
>  extern void pm_runtime_no_callbacks(struct device *dev);
> +extern void pm_runtime_callbacks_in_irq(struct device *dev);

Perhaps this one can be called pm_runtime_irq_safe() in analogy to the struct
member?

>  extern void __pm_runtime_use_autosuspend(struct device *dev, bool use);
>  extern void pm_runtime_set_autosuspend_delay(struct device *dev, int delay);
>  extern unsigned long pm_runtime_autosuspend_expiration(struct device *dev);
> @@ -123,6 +125,7 @@ static inline int pm_generic_runtime_idl
>  static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; }
>  static inline int pm_generic_runtime_resume(struct device *dev) { return 0; }
>  static inline void pm_runtime_no_callbacks(struct device *dev) {}
> +static inline void pm_runtime_callbacks_in_irq(struct device *dev) {}
>  
>  static inline void pm_runtime_mark_last_busy(struct device *dev) {}
>  static inline void __pm_runtime_use_autosuspend(struct device *dev,
> @@ -144,6 +147,11 @@ static inline int pm_runtime_suspend(str
>  	return __pm_runtime_suspend(dev, 0);
>  }
>  
> +static inline int pm_runtime_suspend_irq(struct device *dev)
> +{
> +	return __pm_runtime_suspend(dev, RPM_IRQ);
> +}
> +
>  static inline int pm_runtime_autosuspend(struct device *dev)
>  {
>  	return __pm_runtime_suspend(dev, RPM_AUTO);
> @@ -154,6 +162,11 @@ static inline int pm_runtime_resume(stru
>  	return __pm_runtime_resume(dev, 0);
>  }
>  
> +static inline int pm_runtime_resume_irq(struct device *dev)
> +{
> +	return __pm_runtime_resume(dev, RPM_IRQ);
> +}
> +
>  static inline int pm_request_idle(struct device *dev)
>  {
>  	return __pm_runtime_idle(dev, RPM_ASYNC);
> @@ -179,6 +192,11 @@ static inline int pm_runtime_get_sync(st
>  	return __pm_runtime_resume(dev, RPM_GET_PUT);
>  }
>  
> +static inline int pm_runtime_get_sync_irq(struct device *dev)
> +{
> +	return __pm_runtime_resume(dev, RPM_GET_PUT | RPM_IRQ);
> +}
> +
>  static inline int pm_runtime_put(struct device *dev)
>  {
>  	return __pm_runtime_idle(dev, RPM_GET_PUT | RPM_ASYNC);
> @@ -195,6 +213,11 @@ static inline int pm_runtime_put_sync(st
>  	return __pm_runtime_idle(dev, RPM_GET_PUT);
>  }
>  
> +static inline int pm_runtime_put_sync_irq(struct device *dev)
> +{
> +	return __pm_runtime_idle(dev, RPM_GET_PUT | RPM_IRQ);
> +}
> +
>  static inline int pm_runtime_put_sync_autosuspend(struct device *dev)
>  {
>  	return __pm_runtime_suspend(dev, RPM_GET_PUT | RPM_AUTO);
> Index: usb-2.6/drivers/base/power/runtime.c
> ===================================================================
> --- usb-2.6.orig/drivers/base/power/runtime.c
> +++ usb-2.6/drivers/base/power/runtime.c
> @@ -170,10 +170,13 @@ static int rpm_idle(struct device *dev, 
>  	__releases(&dev->power.lock) __acquires(&dev->power.lock)
>  {
>  	int retval;
> +	int (*func)(struct device *dev);
>  
>  	retval = rpm_check_suspend_allowed(dev);
>  	if (retval < 0)
>  		;	/* Conditions are wrong. */
> +	else if ((rpmflags & RPM_IRQ) && !dev->power.callbacks_in_irq)
> +		retval = -EWOULDBLOCK;
>  
>  	/* Idle notifications are allowed only in the RPM_ACTIVE state. */
>  	else if (dev->power.runtime_status != RPM_ACTIVE)
> @@ -214,25 +217,27 @@ static int rpm_idle(struct device *dev, 
>  
>  	dev->power.idle_notification = true;
>  
> -	if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_idle) {
> -		spin_unlock_irq(&dev->power.lock);
> -
> -		dev->bus->pm->runtime_idle(dev);
> -
> -		spin_lock_irq(&dev->power.lock);
> -	} else if (dev->type && dev->type->pm && dev->type->pm->runtime_idle) {
> -		spin_unlock_irq(&dev->power.lock);
> +	func = NULL;
> +	if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_idle)
> +		func = dev->bus->pm->runtime_idle;
> +	else if (dev->type && dev->type->pm && dev->type->pm->runtime_idle)
> +		func = dev->type->pm->runtime_idle;
> +	else if (dev->class && dev->class->pm && dev->class->pm->runtime_idle)
> +		func = dev->class->pm->runtime_idle;
> +	if (func) {
> +		if (dev->power.callbacks_in_irq) {
> +			spin_unlock(&dev->power.lock);

Hmm.  This looks rather complicated.  I don't really feel good about this
change.  It seems to me that it might be better to actually implement
the _irq() helpers from scratch.  I think I'll try to do that.

Overall, it looks like there's some overlap between RPM_IRQ and
power.callbacks_in_irq, where the latter may influence the behavior of the
helpers even if RPM_IRQ is unset.

I think we should return error code if RPM_IRQ is used, but 
power.callbacks_in_irq is not set.  If RPM_IRQ is not set, but
power.callbacks_in_irq is set, we should fall back to the normal behavior
(ie. do not avoid sleeping).

That's why I think it's better to change the name of power.callbacks_in_irq
to power.irq_safe.

Also I think we should refuse to set power.callbacks_in_irq for a device
whose partent (1) doesn't have power.callbacks_in_irq and (2) doesn't
have power.ignore_children set , and (3) doesn't have power.disable_depth > 0.
Then, once we've set power.callbacks_in_irq for a device, we should take
this into consideration when trying to change the parent's settings.

There probably is more subtelties like this, but I can't see them at the moment.

Thanks,
Rafael

  reply	other threads:[~2010-09-30 20:17 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-24  0:05 runtime_pm_get_sync() from ISR with IRQs disabled? Kevin Hilman
2010-09-24 15:13 ` [linux-pm] " Alan Stern
2010-09-24 18:54   ` Kevin Hilman
2010-09-24 20:04     ` Rafael J. Wysocki
2010-09-27 13:57       ` Alan Stern
2010-09-27 20:00         ` Rafael J. Wysocki
2010-09-27 20:39           ` Alan Stern
2010-09-27 21:09             ` Rafael J. Wysocki
2010-09-28 14:55               ` Alan Stern
2010-09-28 18:19                 ` Rafael J. Wysocki
2010-09-30 18:25                   ` [PATCH] PM: add synchronous runtime interface for interrupt handlers Alan Stern
2010-09-30 20:15                     ` Rafael J. Wysocki [this message]
2010-09-30 21:42                       ` Alan Stern
2010-09-30 22:41                         ` Rafael J. Wysocki
2010-10-01 14:28                           ` Alan Stern
2010-10-01 21:23                             ` Rafael J. Wysocki
2010-10-02 14:12                               ` Alan Stern
2010-10-02 22:06                                 ` Rafael J. Wysocki
2010-10-03 15:52                                   ` Alan Stern
2010-10-03 20:33                                     ` Rafael J. Wysocki
2010-10-05 21:44                                 ` Kevin Hilman
2010-10-06 15:58                                   ` Alan Stern
2010-10-06 19:33                                     ` Rafael J. Wysocki
2010-10-06 19:35                                     ` Kevin Hilman
2010-10-06 20:28                                       ` Alan Stern
2010-10-06 21:47                                         ` Rafael J. Wysocki
2010-10-07 15:26                                           ` Alan Stern
2010-10-07 16:52                                             ` Kevin Hilman
2010-10-07 17:35                                               ` Alan Stern
2010-10-07 21:11                                                 ` Rafael J. Wysocki
2010-10-07 23:15                                                   ` Kevin Hilman
2010-10-07 23:37                                                     ` Rafael J. Wysocki
2010-10-07 23:55                                                       ` Kevin Hilman
2010-10-08 16:22                                                         ` Alan Stern
2010-10-08 21:04                                                           ` Kevin Hilman
2010-10-08 19:57                                                         ` Rafael J. Wysocki
2010-10-08 16:18                                                   ` Alan Stern
2010-10-08 19:53                                                     ` Rafael J. Wysocki
2010-10-09 11:09                                                       ` [linux-pm] " Rafael J. Wysocki
2010-10-11 17:00                                                         ` Alan Stern
2010-10-11 22:30                                                           ` Rafael J. Wysocki
2010-11-19 15:45                                           ` [PATCH ver. 2] " Alan Stern
2010-11-20 12:56                                             ` Rafael J. Wysocki
2010-11-20 16:59                                               ` Alan Stern
2010-11-20 19:41                                                 ` [linux-pm] " Alan Stern
2010-11-21 23:45                                                   ` Rafael J. Wysocki
2010-11-21 23:41                                                 ` Rafael J. Wysocki
2010-11-22 15:38                                                   ` Alan Stern
2010-11-22 23:01                                                     ` Rafael J. Wysocki
2010-11-23  3:19                                                       ` Alan Stern
2010-11-23 22:51                                                         ` Rafael J. Wysocki
2010-11-24  0:11                                                           ` Kevin Hilman
2010-11-24 16:43                                                             ` Alan Stern
2010-11-24 18:03                                                               ` Kevin Hilman
2010-11-24 14:56                                                           ` Alan Stern
2010-11-24 20:33                                                             ` Rafael J. Wysocki
2010-11-25 15:52                                                               ` [PATCH ver. 3] " Alan Stern
2010-11-25 18:58                                                                 ` [linux-pm] " Oliver Neukum
2010-11-25 20:03                                                                   ` Rafael J. Wysocki
2010-11-26 22:23                                                                 ` Rafael J. Wysocki
2010-10-06 23:51                                         ` [PATCH] " Kevin Hilman
2010-09-30 22:02                     ` Rafael J. Wysocki
2010-10-01 14:12                       ` Alan Stern
2010-10-01 21:14                         ` Rafael J. Wysocki
2010-09-27 21:11             ` [linux-pm] runtime_pm_get_sync() from ISR with IRQs disabled? Kevin Hilman
2010-09-24 20:27     ` Alan Stern
2010-09-24 21:52       ` Kevin Hilman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201009302215.59937.rjw@sisk.pl \
    --to=rjw@sisk.pl \
    --cc=khilman@deeprootsystems.com \
    --cc=linux-omap@vger.kernel.org \
    --cc=linux-pm@lists.linux-foundation.org \
    --cc=p-basak2@ti.com \
    --cc=stern@rowland.harvard.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).