All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tony Lindgren <tony@atomide.com>
To: Paul Walmsley <paul@pwsan.com>
Cc: linux-omap@vger.kernel.org, dirk.behme@googlemail.com
Subject: Re: [PATCH] mach-omap2/powerdomain.c: convert rwsem to rwlock
Date: Wed, 14 May 2008 15:25:36 -0700	[thread overview]
Message-ID: <20080514222536.GB8928@atomide.com> (raw)
In-Reply-To: <alpine.DEB.1.00.0805141215270.31270@utopia.booyaka.com>

* Paul Walmsley <paul@pwsan.com> [080514 14:58]:
> 
> The generic rwsem implementation of down_read() and down_write() does not
> save and restore interrupt state.  This causes powerdomain code to
> inadvertently enable interrupts early in the boot process, causing
> init/main.c to complain.   This patch converts powerdomain locking to
> r-w spinlocks instead.
> 
> I'm also curious to know if this fixes the BeagleBoard boot problem.

Pushing today.

Tony


> Signed-off-by: Paul Walmsley <paul@pwsan.com>
> ---
> 
>  arch/arm/mach-omap2/powerdomain.c |   46 ++++++++++++++++++++++---------------
>  1 files changed, 27 insertions(+), 19 deletions(-)
> 
> 
> diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
> index 939efe4..0a6caaf 100644
> --- a/arch/arm/mach-omap2/powerdomain.c
> +++ b/arch/arm/mach-omap2/powerdomain.c
> @@ -18,7 +18,7 @@
>  #include <linux/module.h>
>  #include <linux/types.h>
>  #include <linux/delay.h>
> -#include <linux/rwsem.h>
> +#include <linux/spinlock.h>
>  #include <linux/list.h>
>  #include <linux/errno.h>
>  #include <linux/err.h>
> @@ -38,10 +38,10 @@
>  static LIST_HEAD(pwrdm_list);
>  
>  /*
> - * pwrdm_rwsem protects pwrdm_list add and del ops - also reused to
> + * pwrdm_rwlock protects pwrdm_list add and del ops - also reused to
>   * protect pwrdm_clkdms[] during clkdm add/del ops
>   */
> -static DECLARE_RWSEM(pwrdm_rwsem);
> +static DEFINE_RWLOCK(pwrdm_rwlock);
>  
>  
>  /* Private functions */
> @@ -131,6 +131,7 @@ void pwrdm_init(struct powerdomain **pwrdm_list)
>   */
>  int pwrdm_register(struct powerdomain *pwrdm)
>  {
> +	unsigned long flags;
>  	int ret = -EINVAL;
>  
>  	if (!pwrdm)
> @@ -139,7 +140,7 @@ int pwrdm_register(struct powerdomain *pwrdm)
>  	if (!omap_chip_is(pwrdm->omap_chip))
>  		return -EINVAL;
>  
> -	down_write(&pwrdm_rwsem);
> +	write_lock_irqsave(&pwrdm_rwlock, flags);
>  	if (_pwrdm_lookup(pwrdm->name)) {
>  		ret = -EEXIST;
>  		goto pr_unlock;
> @@ -151,7 +152,7 @@ int pwrdm_register(struct powerdomain *pwrdm)
>  	ret = 0;
>  
>  pr_unlock:
> -	up_write(&pwrdm_rwsem);
> +	write_unlock_irqrestore(&pwrdm_rwlock, flags);
>  
>  	return ret;
>  }
> @@ -165,12 +166,14 @@ pr_unlock:
>   */
>  int pwrdm_unregister(struct powerdomain *pwrdm)
>  {
> +	unsigned long flags;
> +
>  	if (!pwrdm)
>  		return -EINVAL;
>  
> -	down_write(&pwrdm_rwsem);
> +	write_lock_irqsave(&pwrdm_rwlock, flags);
>  	list_del(&pwrdm->node);
> -	up_write(&pwrdm_rwsem);
> +	write_unlock_irqrestore(&pwrdm_rwlock, flags);
>  
>  	pr_debug("powerdomain: unregistered %s\n", pwrdm->name);
>  
> @@ -187,13 +190,14 @@ int pwrdm_unregister(struct powerdomain *pwrdm)
>  struct powerdomain *pwrdm_lookup(const char *name)
>  {
>  	struct powerdomain *pwrdm;
> +	unsigned long flags;
>  
>  	if (!name)
>  		return NULL;
>  
> -	down_read(&pwrdm_rwsem);
> +	read_lock_irqsave(&pwrdm_rwlock, flags);
>  	pwrdm = _pwrdm_lookup(name);
> -	up_read(&pwrdm_rwsem);
> +	read_unlock_irqrestore(&pwrdm_rwlock, flags);
>  
>  	return pwrdm;
>  }
> @@ -204,7 +208,7 @@ struct powerdomain *pwrdm_lookup(const char *name)
>   *
>   * Call the supplied function for each registered powerdomain.  The
>   * callback function can return anything but 0 to bail out early from
> - * the iterator.  The callback function is called with the pwrdm_rwsem
> + * the iterator.  The callback function is called with the pwrdm_rwlock
>   * held for reading, so no powerdomain structure manipulation
>   * functions should be called from the callback, although hardware
>   * powerdomain control functions are fine.  Returns the last return
> @@ -215,18 +219,19 @@ struct powerdomain *pwrdm_lookup(const char *name)
>  int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm))
>  {
>  	struct powerdomain *temp_pwrdm;
> +	unsigned long flags;
>  	int ret = 0;
>  
>  	if (!fn)
>  		return -EINVAL;
>  
> -	down_read(&pwrdm_rwsem);
> +	read_lock_irqsave(&pwrdm_rwlock, flags);
>  	list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
>  		ret = (*fn)(temp_pwrdm);
>  		if (ret)
>  			break;
>  	}
> -	up_read(&pwrdm_rwsem);
> +	read_unlock_irqrestore(&pwrdm_rwlock, flags);
>  
>  	return ret;
>  }
> @@ -243,6 +248,7 @@ int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm))
>   */
>  int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
>  {
> +	unsigned long flags;
>  	int i;
>  	int ret = -EINVAL;
>  
> @@ -252,7 +258,7 @@ int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
>  	pr_debug("powerdomain: associating clockdomain %s with powerdomain "
>  		 "%s\n", clkdm->name, pwrdm->name);
>  
> -	down_write(&pwrdm_rwsem);
> +	write_lock_irqsave(&pwrdm_rwlock, flags);
>  
>  	for (i = 0; i < PWRDM_MAX_CLKDMS; i++) {
>  		if (!pwrdm->pwrdm_clkdms[i])
> @@ -278,7 +284,7 @@ int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
>  	ret = 0;
>  
>  pac_exit:
> -	up_write(&pwrdm_rwsem);
> +	write_unlock_irqrestore(&pwrdm_rwlock, flags);
>  
>  	return ret;
>  }
> @@ -295,6 +301,7 @@ pac_exit:
>   */
>  int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
>  {
> +	unsigned long flags;
>  	int ret = -EINVAL;
>  	int i;
>  
> @@ -304,7 +311,7 @@ int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
>  	pr_debug("powerdomain: dissociating clockdomain %s from powerdomain "
>  		 "%s\n", clkdm->name, pwrdm->name);
>  
> -	down_write(&pwrdm_rwsem);
> +	write_lock_irqsave(&pwrdm_rwlock, flags);
>  
>  	for (i = 0; i < PWRDM_MAX_CLKDMS; i++)
>  		if (pwrdm->pwrdm_clkdms[i] == clkdm)
> @@ -322,7 +329,7 @@ int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
>  	ret = 0;
>  
>  pdc_exit:
> -	up_write(&pwrdm_rwsem);
> +	write_unlock_irqrestore(&pwrdm_rwlock, flags);
>  
>  	return ret;
>  }
> @@ -335,7 +342,7 @@ pdc_exit:
>   * Call the supplied function for each clockdomain in the powerdomain
>   * 'pwrdm'.  The callback function can return anything but 0 to bail
>   * out early from the iterator.  The callback function is called with
> - * the pwrdm_rwsem held for reading, so no powerdomain structure
> + * the pwrdm_rwlock held for reading, so no powerdomain structure
>   * manipulation functions should be called from the callback, although
>   * hardware powerdomain control functions are fine.  Returns -EINVAL
>   * if presented with invalid pointers; or passes along the last return
> @@ -346,18 +353,19 @@ int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
>  			 int (*fn)(struct powerdomain *pwrdm,
>  				   struct clockdomain *clkdm))
>  {
> +	unsigned long flags;
>  	int ret = 0;
>  	int i;
>  
>  	if (!fn)
>  		return -EINVAL;
>  
> -	down_read(&pwrdm_rwsem);
> +	read_lock_irqsave(&pwrdm_rwlock, flags);
>  
>  	for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
>  		ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
>  
> -	up_read(&pwrdm_rwsem);
> +	read_unlock_irqrestore(&pwrdm_rwlock, flags);
>  
>  	return ret;
>  }
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

  parent reply	other threads:[~2008-05-14 22:25 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-05-14 18:16 [PATCH] mach-omap2/powerdomain.c: convert rwsem to rwlock Paul Walmsley
2008-05-14 20:38 ` Koen Kooi
2008-05-14 22:25 ` Tony Lindgren [this message]
2008-05-15 16:45 ` Dirk Behme

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=20080514222536.GB8928@atomide.com \
    --to=tony@atomide.com \
    --cc=dirk.behme@googlemail.com \
    --cc=linux-omap@vger.kernel.org \
    --cc=paul@pwsan.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.