linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] amba: move to pm ops
@ 2011-02-17  7:49 Rabin Vincent
  2011-02-17 17:44 ` Takashi Iwai
  2011-02-21  7:02 ` [PATCHv2] amba: support " Rabin Vincent
  0 siblings, 2 replies; 11+ messages in thread
From: Rabin Vincent @ 2011-02-17  7:49 UTC (permalink / raw)
  To: linux-arm-kernel

Support pm_ops in the AMBA bus instead of the legacy ops.   pm_ops is needed
for runtime pm, and there is also a general move to convert drivers to
dev_pm_ops rather than bus specific PM ops in order to facilitate core
development.

Since there are only 6 AMBA drivers using suspend/resume, convert them all in
one go and directly use the GENERIC_SUBSYS_PM_OPS in the bus.

Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Chris Ball <cjb@laptop.org>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Takashi Iwai <tiwai@suse.de>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
---
 drivers/amba/bus.c              |   25 ++-----------------------
 drivers/input/serio/ambakmi.c   |   13 ++++++++++---
 drivers/mmc/host/mmci.c         |   17 ++++++++++-------
 drivers/spi/amba-pl022.c        |   15 +++++++++------
 drivers/tty/serial/amba-pl010.c |   20 ++++++++++++++------
 drivers/tty/serial/amba-pl011.c |   22 +++++++++++++---------
 include/linux/amba/bus.h        |    4 ++--
 sound/arm/aaci.c                |   18 ++++++++++--------
 8 files changed, 70 insertions(+), 64 deletions(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index ca96b0a..402b07e 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -13,12 +13,12 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/io.h>
+#include <linux/pm.h>
 #include <linux/amba/bus.h>
 
 #include <asm/irq.h>
 #include <asm/sizes.h>
 
-#define to_amba_device(d)	container_of(d, struct amba_device, dev)
 #define to_amba_driver(d)	container_of(d, struct amba_driver, drv)
 
 static struct amba_id *
@@ -57,26 +57,6 @@ static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
 #define amba_uevent NULL
 #endif
 
-static int amba_suspend(struct device *dev, pm_message_t state)
-{
-	struct amba_driver *drv = to_amba_driver(dev->driver);
-	int ret = 0;
-
-	if (dev->driver && drv->suspend)
-		ret = drv->suspend(to_amba_device(dev), state);
-	return ret;
-}
-
-static int amba_resume(struct device *dev)
-{
-	struct amba_driver *drv = to_amba_driver(dev->driver);
-	int ret = 0;
-
-	if (dev->driver && drv->resume)
-		ret = drv->resume(to_amba_device(dev));
-	return ret;
-}
-
 #define amba_attr_func(name,fmt,arg...)					\
 static ssize_t name##_show(struct device *_dev,				\
 			   struct device_attribute *attr, char *buf)	\
@@ -111,8 +91,7 @@ struct bus_type amba_bustype = {
 	.dev_attrs	= amba_dev_attrs,
 	.match		= amba_match,
 	.uevent		= amba_uevent,
-	.suspend	= amba_suspend,
-	.resume		= amba_resume,
+	.pm		= GENERIC_SUBSYS_PM_OPS,
 };
 
 static int __init amba_init(void)
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
index 92563a6..c710437 100644
--- a/drivers/input/serio/ambakmi.c
+++ b/drivers/input/serio/ambakmi.c
@@ -176,15 +176,22 @@ static int __devexit amba_kmi_remove(struct amba_device *dev)
 	return 0;
 }
 
-static int amba_kmi_resume(struct amba_device *dev)
+#ifdef CONFIG_PM_SLEEP
+static int amba_kmi_resume(struct device *dev)
 {
-	struct amba_kmi_port *kmi = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct amba_kmi_port *kmi = amba_get_drvdata(adev);
 
 	/* kick the serio layer to rescan this port */
 	serio_reconnect(kmi->io);
 
 	return 0;
 }
+#else
+#define amba_kmi_resume	NULL
+#endif
+
+static SIMPLE_DEV_PM_OPS(amba_kmi_pm, NULL, amba_kmi_resume);
 
 static struct amba_id amba_kmi_idtable[] = {
 	{
@@ -198,11 +205,11 @@ static struct amba_driver ambakmi_driver = {
 	.drv		= {
 		.name	= "kmi-pl050",
 		.owner	= THIS_MODULE,
+		.pm	= &amba_kmi_pm,
 	},
 	.id_table	= amba_kmi_idtable,
 	.probe		= amba_kmi_probe,
 	.remove		= __devexit_p(amba_kmi_remove),
-	.resume		= amba_kmi_resume,
 };
 
 static int __init amba_kmi_init(void)
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 8a29c9f..18e142b 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -1236,10 +1236,11 @@ static int __devexit mmci_remove(struct amba_device *dev)
 	return 0;
 }
 
-#ifdef CONFIG_PM
-static int mmci_suspend(struct amba_device *dev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int mmci_suspend(struct device *dev)
 {
-	struct mmc_host *mmc = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct mmc_host *mmc = amba_get_drvdata(adev);
 	int ret = 0;
 
 	if (mmc) {
@@ -1253,9 +1254,10 @@ static int mmci_suspend(struct amba_device *dev, pm_message_t state)
 	return ret;
 }
 
-static int mmci_resume(struct amba_device *dev)
+static int mmci_resume(struct device *dev)
 {
-	struct mmc_host *mmc = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct mmc_host *mmc = amba_get_drvdata(adev);
 	int ret = 0;
 
 	if (mmc) {
@@ -1273,6 +1275,8 @@ static int mmci_resume(struct amba_device *dev)
 #define mmci_resume	NULL
 #endif
 
+static SIMPLE_DEV_PM_OPS(mmci_pm, mmci_suspend, mmci_resume);
+
 static struct amba_id mmci_ids[] = {
 	{
 		.id	= 0x00041180,
@@ -1306,11 +1310,10 @@ static struct amba_id mmci_ids[] = {
 static struct amba_driver mmci_driver = {
 	.drv		= {
 		.name	= DRIVER_NAME,
+		.pm	= &mmci_pm,
 	},
 	.probe		= mmci_probe,
 	.remove		= __devexit_p(mmci_remove),
-	.suspend	= mmci_suspend,
-	.resume		= mmci_resume,
 	.id_table	= mmci_ids,
 };
 
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c
index 71a1219..eb16ea5 100644
--- a/drivers/spi/amba-pl022.c
+++ b/drivers/spi/amba-pl022.c
@@ -2184,9 +2184,10 @@ pl022_remove(struct amba_device *adev)
 	return 0;
 }
 
-#ifdef CONFIG_PM
-static int pl022_suspend(struct amba_device *adev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int pl022_suspend(struct device *dev)
 {
+	struct amba_device *adev = to_amba_device(dev);
 	struct pl022 *pl022 = amba_get_drvdata(adev);
 	int status = 0;
 
@@ -2203,8 +2204,9 @@ static int pl022_suspend(struct amba_device *adev, pm_message_t state)
 	return 0;
 }
 
-static int pl022_resume(struct amba_device *adev)
+static int pl022_resume(struct device *dev)
 {
+	struct amba_device *adev = to_amba_device(dev);
 	struct pl022 *pl022 = amba_get_drvdata(adev);
 	int status = 0;
 
@@ -2220,7 +2222,9 @@ static int pl022_resume(struct amba_device *adev)
 #else
 #define pl022_suspend NULL
 #define pl022_resume NULL
-#endif	/* CONFIG_PM */
+#endif
+
+static SIMPLE_DEV_PM_OPS(pl022_pm, pl022_suspend, pl022_resume);
 
 static struct vendor_data vendor_arm = {
 	.fifodepth = 8,
@@ -2284,12 +2288,11 @@ static struct amba_id pl022_ids[] = {
 static struct amba_driver pl022_driver = {
 	.drv = {
 		.name	= "ssp-pl022",
+		.pm	= &pl022_pm,
 	},
 	.id_table	= pl022_ids,
 	.probe		= pl022_probe,
 	.remove		= __devexit_p(pl022_remove),
-	.suspend        = pl022_suspend,
-	.resume         = pl022_resume,
 };
 
 
diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c
index 2904aa0..5e0e62f 100644
--- a/drivers/tty/serial/amba-pl010.c
+++ b/drivers/tty/serial/amba-pl010.c
@@ -757,9 +757,11 @@ static int pl010_remove(struct amba_device *dev)
 	return 0;
 }
 
-static int pl010_suspend(struct amba_device *dev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int pl010_suspend(struct device *dev)
 {
-	struct uart_amba_port *uap = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct uart_amba_port *uap = amba_get_drvdata(adev);
 
 	if (uap)
 		uart_suspend_port(&amba_reg, &uap->port);
@@ -767,15 +769,22 @@ static int pl010_suspend(struct amba_device *dev, pm_message_t state)
 	return 0;
 }
 
-static int pl010_resume(struct amba_device *dev)
+static int pl010_resume(struct device *dev)
 {
-	struct uart_amba_port *uap = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct uart_amba_port *uap = amba_get_drvdata(adev);
 
 	if (uap)
 		uart_resume_port(&amba_reg, &uap->port);
 
 	return 0;
 }
+#else
+#define pl010_suspend	NULL
+#define pl010_resume	NULL
+#endif
+
+static SIMPLE_DEV_PM_OPS(pl010_pm, pl010_suspend, pl010_resume);
 
 static struct amba_id pl010_ids[] = {
 	{
@@ -788,12 +797,11 @@ static struct amba_id pl010_ids[] = {
 static struct amba_driver pl010_driver = {
 	.drv = {
 		.name	= "uart-pl010",
+		.pm	= &pl010_pm,
 	},
 	.id_table	= pl010_ids,
 	.probe		= pl010_probe,
 	.remove		= pl010_remove,
-	.suspend	= pl010_suspend,
-	.resume		= pl010_resume,
 };
 
 static int __init pl010_init(void)
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index e76d7d0..52a5e18 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -1438,10 +1438,11 @@ static int pl011_remove(struct amba_device *dev)
 	return 0;
 }
 
-#ifdef CONFIG_PM
-static int pl011_suspend(struct amba_device *dev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int pl011_suspend(struct device *dev)
 {
-	struct uart_amba_port *uap = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct uart_amba_port *uap = amba_get_drvdata(adev);
 
 	if (!uap)
 		return -EINVAL;
@@ -1449,17 +1450,23 @@ static int pl011_suspend(struct amba_device *dev, pm_message_t state)
 	return uart_suspend_port(&amba_reg, &uap->port);
 }
 
-static int pl011_resume(struct amba_device *dev)
+static int pl011_resume(struct device *dev)
 {
-	struct uart_amba_port *uap = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct uart_amba_port *uap = amba_get_drvdata(adev);
 
 	if (!uap)
 		return -EINVAL;
 
 	return uart_resume_port(&amba_reg, &uap->port);
 }
+#else
+#define pl011_suspend	NULL
+#define pl011_resume	NULL
 #endif
 
+static SIMPLE_DEV_PM_OPS(pl011_pm, pl011_suspend, pl011_resume);
+
 static struct amba_id pl011_ids[] = {
 	{
 		.id	= 0x00041011,
@@ -1477,14 +1484,11 @@ static struct amba_id pl011_ids[] = {
 static struct amba_driver pl011_driver = {
 	.drv = {
 		.name	= "uart-pl011",
+		.pm	= &pl011_pm,
 	},
 	.id_table	= pl011_ids,
 	.probe		= pl011_probe,
 	.remove		= pl011_remove,
-#ifdef CONFIG_PM
-	.suspend	= pl011_suspend,
-	.resume		= pl011_resume,
-#endif
 };
 
 static int __init pl011_init(void)
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index a0ccf28..2f48827 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -46,8 +46,6 @@ struct amba_driver {
 	int			(*probe)(struct amba_device *, struct amba_id *);
 	int			(*remove)(struct amba_device *);
 	void			(*shutdown)(struct amba_device *);
-	int			(*suspend)(struct amba_device *, pm_message_t);
-	int			(*resume)(struct amba_device *);
 	struct amba_id		*id_table;
 };
 
@@ -58,6 +56,8 @@ enum amba_vendor {
 
 extern struct bus_type amba_bustype;
 
+#define to_amba_device(d)	container_of(d, struct amba_device, dev)
+
 #define amba_get_drvdata(d)	dev_get_drvdata(&d->dev)
 #define amba_set_drvdata(d,p)	dev_set_drvdata(&d->dev, p)
 
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index af5a152..040c5f0 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -35,7 +35,7 @@
 /*
  * PM support is not complete.  Turn it off.
  */
-#undef CONFIG_PM
+#undef CONFIG_PM_SLEEP
 
 static void aaci_ac97_select_codec(struct aaci *aaci, struct snd_ac97 *ac97)
 {
@@ -752,7 +752,7 @@ static struct snd_pcm_ops aaci_capture_ops = {
 /*
  * Power Management.
  */
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int aaci_do_suspend(struct snd_card *card, unsigned int state)
 {
 	struct aaci *aaci = card->private_data;
@@ -767,15 +767,17 @@ static int aaci_do_resume(struct snd_card *card, unsigned int state)
 	return 0;
 }
 
-static int aaci_suspend(struct amba_device *dev, pm_message_t state)
+static int aaci_suspend(struct device *dev)
 {
-	struct snd_card *card = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct snd_card *card = amba_get_drvdata(adev);
 	return card ? aaci_do_suspend(card) : 0;
 }
 
-static int aaci_resume(struct amba_device *dev)
+static int aaci_resume(struct device *dev)
 {
-	struct snd_card *card = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct snd_card *card = amba_get_drvdata(adev);
 	return card ? aaci_do_resume(card) : 0;
 }
 #else
@@ -785,6 +787,7 @@ static int aaci_resume(struct amba_device *dev)
 #define aaci_resume		NULL
 #endif
 
+static SIMPLE_DEV_PM_OPS(aaci_pm, aaci_suspend, aaci_resume);
 
 static struct ac97_pcm ac97_defs[] __devinitdata = {
 	[0] = {	/* Front PCM */
@@ -1099,11 +1102,10 @@ static struct amba_id aaci_ids[] = {
 static struct amba_driver aaci_driver = {
 	.drv		= {
 		.name	= DRIVER_NAME,
+		.pm	= &aaci_pm,
 	},
 	.probe		= aaci_probe,
 	.remove		= __devexit_p(aaci_remove),
-	.suspend	= aaci_suspend,
-	.resume		= aaci_resume,
 	.id_table	= aaci_ids,
 };
 
-- 
1.7.2.dirty

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH] amba: move to pm ops
  2011-02-17  7:49 [PATCH] amba: move to pm ops Rabin Vincent
@ 2011-02-17 17:44 ` Takashi Iwai
  2011-02-21  7:36   ` [linux-pm] " Rabin Vincent
  2011-02-21  7:02 ` [PATCHv2] amba: support " Rabin Vincent
  1 sibling, 1 reply; 11+ messages in thread
From: Takashi Iwai @ 2011-02-17 17:44 UTC (permalink / raw)
  To: linux-arm-kernel

At Thu, 17 Feb 2011 13:19:46 +0530,
Rabin Vincent wrote:
> 
> Support pm_ops in the AMBA bus instead of the legacy ops.   pm_ops is needed
> for runtime pm, and there is also a general move to convert drivers to
> dev_pm_ops rather than bus specific PM ops in order to facilitate core
> development.
> 
> Since there are only 6 AMBA drivers using suspend/resume, convert them all in
> one go and directly use the GENERIC_SUBSYS_PM_OPS in the bus.
> 
> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> Cc: Chris Ball <cjb@laptop.org>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Takashi Iwai <tiwai@suse.de>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Cc: Greg Kroah-Hartman <gregkh@suse.de>
> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>

For sound/arm/aaci.c,

  Acked-by: Takashi Iwai <tiwai@suse.de>

Though, this would result in a zero-filled *_pm struct when
CONFIG_PM_* isn't set?  It's a few bytes wastes ;)


thanks,

Takashi

> ---
>  drivers/amba/bus.c              |   25 ++-----------------------
>  drivers/input/serio/ambakmi.c   |   13 ++++++++++---
>  drivers/mmc/host/mmci.c         |   17 ++++++++++-------
>  drivers/spi/amba-pl022.c        |   15 +++++++++------
>  drivers/tty/serial/amba-pl010.c |   20 ++++++++++++++------
>  drivers/tty/serial/amba-pl011.c |   22 +++++++++++++---------
>  include/linux/amba/bus.h        |    4 ++--
>  sound/arm/aaci.c                |   18 ++++++++++--------
>  8 files changed, 70 insertions(+), 64 deletions(-)
> 
> diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
> index ca96b0a..402b07e 100644
> --- a/drivers/amba/bus.c
> +++ b/drivers/amba/bus.c
> @@ -13,12 +13,12 @@
>  #include <linux/string.h>
>  #include <linux/slab.h>
>  #include <linux/io.h>
> +#include <linux/pm.h>
>  #include <linux/amba/bus.h>
>  
>  #include <asm/irq.h>
>  #include <asm/sizes.h>
>  
> -#define to_amba_device(d)	container_of(d, struct amba_device, dev)
>  #define to_amba_driver(d)	container_of(d, struct amba_driver, drv)
>  
>  static struct amba_id *
> @@ -57,26 +57,6 @@ static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
>  #define amba_uevent NULL
>  #endif
>  
> -static int amba_suspend(struct device *dev, pm_message_t state)
> -{
> -	struct amba_driver *drv = to_amba_driver(dev->driver);
> -	int ret = 0;
> -
> -	if (dev->driver && drv->suspend)
> -		ret = drv->suspend(to_amba_device(dev), state);
> -	return ret;
> -}
> -
> -static int amba_resume(struct device *dev)
> -{
> -	struct amba_driver *drv = to_amba_driver(dev->driver);
> -	int ret = 0;
> -
> -	if (dev->driver && drv->resume)
> -		ret = drv->resume(to_amba_device(dev));
> -	return ret;
> -}
> -
>  #define amba_attr_func(name,fmt,arg...)					\
>  static ssize_t name##_show(struct device *_dev,				\
>  			   struct device_attribute *attr, char *buf)	\
> @@ -111,8 +91,7 @@ struct bus_type amba_bustype = {
>  	.dev_attrs	= amba_dev_attrs,
>  	.match		= amba_match,
>  	.uevent		= amba_uevent,
> -	.suspend	= amba_suspend,
> -	.resume		= amba_resume,
> +	.pm		= GENERIC_SUBSYS_PM_OPS,
>  };
>  
>  static int __init amba_init(void)
> diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
> index 92563a6..c710437 100644
> --- a/drivers/input/serio/ambakmi.c
> +++ b/drivers/input/serio/ambakmi.c
> @@ -176,15 +176,22 @@ static int __devexit amba_kmi_remove(struct amba_device *dev)
>  	return 0;
>  }
>  
> -static int amba_kmi_resume(struct amba_device *dev)
> +#ifdef CONFIG_PM_SLEEP
> +static int amba_kmi_resume(struct device *dev)
>  {
> -	struct amba_kmi_port *kmi = amba_get_drvdata(dev);
> +	struct amba_device *adev = to_amba_device(dev);
> +	struct amba_kmi_port *kmi = amba_get_drvdata(adev);
>  
>  	/* kick the serio layer to rescan this port */
>  	serio_reconnect(kmi->io);
>  
>  	return 0;
>  }
> +#else
> +#define amba_kmi_resume	NULL
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(amba_kmi_pm, NULL, amba_kmi_resume);
>  
>  static struct amba_id amba_kmi_idtable[] = {
>  	{
> @@ -198,11 +205,11 @@ static struct amba_driver ambakmi_driver = {
>  	.drv		= {
>  		.name	= "kmi-pl050",
>  		.owner	= THIS_MODULE,
> +		.pm	= &amba_kmi_pm,
>  	},
>  	.id_table	= amba_kmi_idtable,
>  	.probe		= amba_kmi_probe,
>  	.remove		= __devexit_p(amba_kmi_remove),
> -	.resume		= amba_kmi_resume,
>  };
>  
>  static int __init amba_kmi_init(void)
> diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
> index 8a29c9f..18e142b 100644
> --- a/drivers/mmc/host/mmci.c
> +++ b/drivers/mmc/host/mmci.c
> @@ -1236,10 +1236,11 @@ static int __devexit mmci_remove(struct amba_device *dev)
>  	return 0;
>  }
>  
> -#ifdef CONFIG_PM
> -static int mmci_suspend(struct amba_device *dev, pm_message_t state)
> +#ifdef CONFIG_PM_SLEEP
> +static int mmci_suspend(struct device *dev)
>  {
> -	struct mmc_host *mmc = amba_get_drvdata(dev);
> +	struct amba_device *adev = to_amba_device(dev);
> +	struct mmc_host *mmc = amba_get_drvdata(adev);
>  	int ret = 0;
>  
>  	if (mmc) {
> @@ -1253,9 +1254,10 @@ static int mmci_suspend(struct amba_device *dev, pm_message_t state)
>  	return ret;
>  }
>  
> -static int mmci_resume(struct amba_device *dev)
> +static int mmci_resume(struct device *dev)
>  {
> -	struct mmc_host *mmc = amba_get_drvdata(dev);
> +	struct amba_device *adev = to_amba_device(dev);
> +	struct mmc_host *mmc = amba_get_drvdata(adev);
>  	int ret = 0;
>  
>  	if (mmc) {
> @@ -1273,6 +1275,8 @@ static int mmci_resume(struct amba_device *dev)
>  #define mmci_resume	NULL
>  #endif
>  
> +static SIMPLE_DEV_PM_OPS(mmci_pm, mmci_suspend, mmci_resume);
> +
>  static struct amba_id mmci_ids[] = {
>  	{
>  		.id	= 0x00041180,
> @@ -1306,11 +1310,10 @@ static struct amba_id mmci_ids[] = {
>  static struct amba_driver mmci_driver = {
>  	.drv		= {
>  		.name	= DRIVER_NAME,
> +		.pm	= &mmci_pm,
>  	},
>  	.probe		= mmci_probe,
>  	.remove		= __devexit_p(mmci_remove),
> -	.suspend	= mmci_suspend,
> -	.resume		= mmci_resume,
>  	.id_table	= mmci_ids,
>  };
>  
> diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c
> index 71a1219..eb16ea5 100644
> --- a/drivers/spi/amba-pl022.c
> +++ b/drivers/spi/amba-pl022.c
> @@ -2184,9 +2184,10 @@ pl022_remove(struct amba_device *adev)
>  	return 0;
>  }
>  
> -#ifdef CONFIG_PM
> -static int pl022_suspend(struct amba_device *adev, pm_message_t state)
> +#ifdef CONFIG_PM_SLEEP
> +static int pl022_suspend(struct device *dev)
>  {
> +	struct amba_device *adev = to_amba_device(dev);
>  	struct pl022 *pl022 = amba_get_drvdata(adev);
>  	int status = 0;
>  
> @@ -2203,8 +2204,9 @@ static int pl022_suspend(struct amba_device *adev, pm_message_t state)
>  	return 0;
>  }
>  
> -static int pl022_resume(struct amba_device *adev)
> +static int pl022_resume(struct device *dev)
>  {
> +	struct amba_device *adev = to_amba_device(dev);
>  	struct pl022 *pl022 = amba_get_drvdata(adev);
>  	int status = 0;
>  
> @@ -2220,7 +2222,9 @@ static int pl022_resume(struct amba_device *adev)
>  #else
>  #define pl022_suspend NULL
>  #define pl022_resume NULL
> -#endif	/* CONFIG_PM */
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(pl022_pm, pl022_suspend, pl022_resume);
>  
>  static struct vendor_data vendor_arm = {
>  	.fifodepth = 8,
> @@ -2284,12 +2288,11 @@ static struct amba_id pl022_ids[] = {
>  static struct amba_driver pl022_driver = {
>  	.drv = {
>  		.name	= "ssp-pl022",
> +		.pm	= &pl022_pm,
>  	},
>  	.id_table	= pl022_ids,
>  	.probe		= pl022_probe,
>  	.remove		= __devexit_p(pl022_remove),
> -	.suspend        = pl022_suspend,
> -	.resume         = pl022_resume,
>  };
>  
>  
> diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c
> index 2904aa0..5e0e62f 100644
> --- a/drivers/tty/serial/amba-pl010.c
> +++ b/drivers/tty/serial/amba-pl010.c
> @@ -757,9 +757,11 @@ static int pl010_remove(struct amba_device *dev)
>  	return 0;
>  }
>  
> -static int pl010_suspend(struct amba_device *dev, pm_message_t state)
> +#ifdef CONFIG_PM_SLEEP
> +static int pl010_suspend(struct device *dev)
>  {
> -	struct uart_amba_port *uap = amba_get_drvdata(dev);
> +	struct amba_device *adev = to_amba_device(dev);
> +	struct uart_amba_port *uap = amba_get_drvdata(adev);
>  
>  	if (uap)
>  		uart_suspend_port(&amba_reg, &uap->port);
> @@ -767,15 +769,22 @@ static int pl010_suspend(struct amba_device *dev, pm_message_t state)
>  	return 0;
>  }
>  
> -static int pl010_resume(struct amba_device *dev)
> +static int pl010_resume(struct device *dev)
>  {
> -	struct uart_amba_port *uap = amba_get_drvdata(dev);
> +	struct amba_device *adev = to_amba_device(dev);
> +	struct uart_amba_port *uap = amba_get_drvdata(adev);
>  
>  	if (uap)
>  		uart_resume_port(&amba_reg, &uap->port);
>  
>  	return 0;
>  }
> +#else
> +#define pl010_suspend	NULL
> +#define pl010_resume	NULL
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(pl010_pm, pl010_suspend, pl010_resume);
>  
>  static struct amba_id pl010_ids[] = {
>  	{
> @@ -788,12 +797,11 @@ static struct amba_id pl010_ids[] = {
>  static struct amba_driver pl010_driver = {
>  	.drv = {
>  		.name	= "uart-pl010",
> +		.pm	= &pl010_pm,
>  	},
>  	.id_table	= pl010_ids,
>  	.probe		= pl010_probe,
>  	.remove		= pl010_remove,
> -	.suspend	= pl010_suspend,
> -	.resume		= pl010_resume,
>  };
>  
>  static int __init pl010_init(void)
> diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
> index e76d7d0..52a5e18 100644
> --- a/drivers/tty/serial/amba-pl011.c
> +++ b/drivers/tty/serial/amba-pl011.c
> @@ -1438,10 +1438,11 @@ static int pl011_remove(struct amba_device *dev)
>  	return 0;
>  }
>  
> -#ifdef CONFIG_PM
> -static int pl011_suspend(struct amba_device *dev, pm_message_t state)
> +#ifdef CONFIG_PM_SLEEP
> +static int pl011_suspend(struct device *dev)
>  {
> -	struct uart_amba_port *uap = amba_get_drvdata(dev);
> +	struct amba_device *adev = to_amba_device(dev);
> +	struct uart_amba_port *uap = amba_get_drvdata(adev);
>  
>  	if (!uap)
>  		return -EINVAL;
> @@ -1449,17 +1450,23 @@ static int pl011_suspend(struct amba_device *dev, pm_message_t state)
>  	return uart_suspend_port(&amba_reg, &uap->port);
>  }
>  
> -static int pl011_resume(struct amba_device *dev)
> +static int pl011_resume(struct device *dev)
>  {
> -	struct uart_amba_port *uap = amba_get_drvdata(dev);
> +	struct amba_device *adev = to_amba_device(dev);
> +	struct uart_amba_port *uap = amba_get_drvdata(adev);
>  
>  	if (!uap)
>  		return -EINVAL;
>  
>  	return uart_resume_port(&amba_reg, &uap->port);
>  }
> +#else
> +#define pl011_suspend	NULL
> +#define pl011_resume	NULL
>  #endif
>  
> +static SIMPLE_DEV_PM_OPS(pl011_pm, pl011_suspend, pl011_resume);
> +
>  static struct amba_id pl011_ids[] = {
>  	{
>  		.id	= 0x00041011,
> @@ -1477,14 +1484,11 @@ static struct amba_id pl011_ids[] = {
>  static struct amba_driver pl011_driver = {
>  	.drv = {
>  		.name	= "uart-pl011",
> +		.pm	= &pl011_pm,
>  	},
>  	.id_table	= pl011_ids,
>  	.probe		= pl011_probe,
>  	.remove		= pl011_remove,
> -#ifdef CONFIG_PM
> -	.suspend	= pl011_suspend,
> -	.resume		= pl011_resume,
> -#endif
>  };
>  
>  static int __init pl011_init(void)
> diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
> index a0ccf28..2f48827 100644
> --- a/include/linux/amba/bus.h
> +++ b/include/linux/amba/bus.h
> @@ -46,8 +46,6 @@ struct amba_driver {
>  	int			(*probe)(struct amba_device *, struct amba_id *);
>  	int			(*remove)(struct amba_device *);
>  	void			(*shutdown)(struct amba_device *);
> -	int			(*suspend)(struct amba_device *, pm_message_t);
> -	int			(*resume)(struct amba_device *);
>  	struct amba_id		*id_table;
>  };
>  
> @@ -58,6 +56,8 @@ enum amba_vendor {
>  
>  extern struct bus_type amba_bustype;
>  
> +#define to_amba_device(d)	container_of(d, struct amba_device, dev)
> +
>  #define amba_get_drvdata(d)	dev_get_drvdata(&d->dev)
>  #define amba_set_drvdata(d,p)	dev_set_drvdata(&d->dev, p)
>  
> diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
> index af5a152..040c5f0 100644
> --- a/sound/arm/aaci.c
> +++ b/sound/arm/aaci.c
> @@ -35,7 +35,7 @@
>  /*
>   * PM support is not complete.  Turn it off.
>   */
> -#undef CONFIG_PM
> +#undef CONFIG_PM_SLEEP
>  
>  static void aaci_ac97_select_codec(struct aaci *aaci, struct snd_ac97 *ac97)
>  {
> @@ -752,7 +752,7 @@ static struct snd_pcm_ops aaci_capture_ops = {
>  /*
>   * Power Management.
>   */
> -#ifdef CONFIG_PM
> +#ifdef CONFIG_PM_SLEEP
>  static int aaci_do_suspend(struct snd_card *card, unsigned int state)
>  {
>  	struct aaci *aaci = card->private_data;
> @@ -767,15 +767,17 @@ static int aaci_do_resume(struct snd_card *card, unsigned int state)
>  	return 0;
>  }
>  
> -static int aaci_suspend(struct amba_device *dev, pm_message_t state)
> +static int aaci_suspend(struct device *dev)
>  {
> -	struct snd_card *card = amba_get_drvdata(dev);
> +	struct amba_device *adev = to_amba_device(dev);
> +	struct snd_card *card = amba_get_drvdata(adev);
>  	return card ? aaci_do_suspend(card) : 0;
>  }
>  
> -static int aaci_resume(struct amba_device *dev)
> +static int aaci_resume(struct device *dev)
>  {
> -	struct snd_card *card = amba_get_drvdata(dev);
> +	struct amba_device *adev = to_amba_device(dev);
> +	struct snd_card *card = amba_get_drvdata(adev);
>  	return card ? aaci_do_resume(card) : 0;
>  }
>  #else
> @@ -785,6 +787,7 @@ static int aaci_resume(struct amba_device *dev)
>  #define aaci_resume		NULL
>  #endif
>  
> +static SIMPLE_DEV_PM_OPS(aaci_pm, aaci_suspend, aaci_resume);
>  
>  static struct ac97_pcm ac97_defs[] __devinitdata = {
>  	[0] = {	/* Front PCM */
> @@ -1099,11 +1102,10 @@ static struct amba_id aaci_ids[] = {
>  static struct amba_driver aaci_driver = {
>  	.drv		= {
>  		.name	= DRIVER_NAME,
> +		.pm	= &aaci_pm,
>  	},
>  	.probe		= aaci_probe,
>  	.remove		= __devexit_p(aaci_remove),
> -	.suspend	= aaci_suspend,
> -	.resume		= aaci_resume,
>  	.id_table	= aaci_ids,
>  };
>  
> -- 
> 1.7.2.dirty
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCHv2] amba: support pm ops
  2011-02-17  7:49 [PATCH] amba: move to pm ops Rabin Vincent
  2011-02-17 17:44 ` Takashi Iwai
@ 2011-02-21  7:02 ` Rabin Vincent
  2011-02-21 20:26   ` [linux-pm] " Rafael J. Wysocki
  1 sibling, 1 reply; 11+ messages in thread
From: Rabin Vincent @ 2011-02-21  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

Support pm_ops in the AMBA bus, required to allow drivers to use runtime pm.
The implementation of AMBA bus pm ops is based on the platform bus
implementation.

Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
---
v2: Base the implementation on the platform bus instead of the generic ops,
    implementation all the functions platform does and with the same behaviour.
    Also continue to support the legacy operations so that this patch doesn't
    need to modify all the drivers and thus becomes easier to merge.

 drivers/amba/bus.c       |  329 ++++++++++++++++++++++++++++++++++++++++++----
 include/linux/amba/bus.h |    2 +
 2 files changed, 308 insertions(+), 23 deletions(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index ca96b0a..7bc7762 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -13,12 +13,12 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/io.h>
+#include <linux/pm.h>
 #include <linux/amba/bus.h>
 
 #include <asm/irq.h>
 #include <asm/sizes.h>
 
-#define to_amba_device(d)	container_of(d, struct amba_device, dev)
 #define to_amba_driver(d)	container_of(d, struct amba_driver, drv)
 
 static struct amba_id *
@@ -57,26 +57,6 @@ static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
 #define amba_uevent NULL
 #endif
 
-static int amba_suspend(struct device *dev, pm_message_t state)
-{
-	struct amba_driver *drv = to_amba_driver(dev->driver);
-	int ret = 0;
-
-	if (dev->driver && drv->suspend)
-		ret = drv->suspend(to_amba_device(dev), state);
-	return ret;
-}
-
-static int amba_resume(struct device *dev)
-{
-	struct amba_driver *drv = to_amba_driver(dev->driver);
-	int ret = 0;
-
-	if (dev->driver && drv->resume)
-		ret = drv->resume(to_amba_device(dev));
-	return ret;
-}
-
 #define amba_attr_func(name,fmt,arg...)					\
 static ssize_t name##_show(struct device *_dev,				\
 			   struct device_attribute *attr, char *buf)	\
@@ -102,6 +82,310 @@ static struct device_attribute amba_dev_attrs[] = {
 	__ATTR_NULL,
 };
 
+#ifdef CONFIG_PM_SLEEP
+
+static int amba_legacy_suspend(struct device *dev, pm_message_t mesg)
+{
+	struct amba_driver *adrv = to_amba_driver(dev->driver);
+	struct amba_device *adev = to_amba_device(dev);
+	int ret = 0;
+
+	if (dev->driver && adrv->suspend)
+		ret = adrv->suspend(adev, mesg);
+
+	return ret;
+}
+
+static int amba_legacy_resume(struct device *dev)
+{
+	struct amba_driver *adrv = to_amba_driver(dev->driver);
+	struct amba_device *adev = to_amba_device(dev);
+	int ret = 0;
+
+	if (dev->driver && adrv->resume)
+		ret = adrv->resume(adev);
+
+	return ret;
+}
+
+static int amba_pm_prepare(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (drv && drv->pm && drv->pm->prepare)
+		ret = drv->pm->prepare(dev);
+
+	return ret;
+}
+
+static void amba_pm_complete(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+
+	if (drv && drv->pm && drv->pm->complete)
+		drv->pm->complete(dev);
+}
+
+#else /* !CONFIG_PM_SLEEP */
+
+#define amba_pm_prepare		NULL
+#define amba_pm_complete		NULL
+
+#endif /* !CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_SUSPEND
+
+static int amba_pm_suspend(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->suspend)
+			ret = drv->pm->suspend(dev);
+	} else {
+		ret = amba_legacy_suspend(dev, PMSG_SUSPEND);
+	}
+
+	return ret;
+}
+
+static int amba_pm_suspend_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->suspend_noirq)
+			ret = drv->pm->suspend_noirq(dev);
+	}
+
+	return ret;
+}
+
+static int amba_pm_resume(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->resume)
+			ret = drv->pm->resume(dev);
+	} else {
+		ret = amba_legacy_resume(dev);
+	}
+
+	return ret;
+}
+
+static int amba_pm_resume_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->resume_noirq)
+			ret = drv->pm->resume_noirq(dev);
+	}
+
+	return ret;
+}
+
+#else /* !CONFIG_SUSPEND */
+
+#define amba_pm_suspend		NULL
+#define amba_pm_resume		NULL
+#define amba_pm_suspend_noirq	NULL
+#define amba_pm_resume_noirq	NULL
+
+#endif /* !CONFIG_SUSPEND */
+
+#ifdef CONFIG_HIBERNATION
+
+static int amba_pm_freeze(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->freeze)
+			ret = drv->pm->freeze(dev);
+	} else {
+		ret = amba_legacy_suspend(dev, PMSG_FREEZE);
+	}
+
+	return ret;
+}
+
+static int amba_pm_freeze_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->freeze_noirq)
+			ret = drv->pm->freeze_noirq(dev);
+	}
+
+	return ret;
+}
+
+static int amba_pm_thaw(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->thaw)
+			ret = drv->pm->thaw(dev);
+	} else {
+		ret = amba_legacy_resume(dev);
+	}
+
+	return ret;
+}
+
+static int amba_pm_thaw_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->thaw_noirq)
+			ret = drv->pm->thaw_noirq(dev);
+	}
+
+	return ret;
+}
+
+static int amba_pm_poweroff(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->poweroff)
+			ret = drv->pm->poweroff(dev);
+	} else {
+		ret = amba_legacy_suspend(dev, PMSG_HIBERNATE);
+	}
+
+	return ret;
+}
+
+static int amba_pm_poweroff_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->poweroff_noirq)
+			ret = drv->pm->poweroff_noirq(dev);
+	}
+
+	return ret;
+}
+
+static int amba_pm_restore(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->restore)
+			ret = drv->pm->restore(dev);
+	} else {
+		ret = amba_legacy_resume(dev);
+	}
+
+	return ret;
+}
+
+static int amba_pm_restore_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->restore_noirq)
+			ret = drv->pm->restore_noirq(dev);
+	}
+
+	return ret;
+}
+
+#else /* !CONFIG_HIBERNATION */
+
+#define amba_pm_freeze		NULL
+#define amba_pm_thaw		NULL
+#define amba_pm_poweroff		NULL
+#define amba_pm_restore		NULL
+#define amba_pm_freeze_noirq	NULL
+#define amba_pm_thaw_noirq		NULL
+#define amba_pm_poweroff_noirq	NULL
+#define amba_pm_restore_noirq	NULL
+
+#endif /* !CONFIG_HIBERNATION */
+
+static const struct dev_pm_ops amba_pm = {
+	.prepare	= amba_pm_prepare,
+	.complete	= amba_pm_complete,
+	.suspend	= amba_pm_suspend,
+	.resume		= amba_pm_resume,
+	.freeze		= amba_pm_freeze,
+	.thaw		= amba_pm_thaw,
+	.poweroff	= amba_pm_poweroff,
+	.restore	= amba_pm_restore,
+	.suspend_noirq	= amba_pm_suspend_noirq,
+	.resume_noirq	= amba_pm_resume_noirq,
+	.freeze_noirq	= amba_pm_freeze_noirq,
+	.thaw_noirq	= amba_pm_thaw_noirq,
+	.poweroff_noirq	= amba_pm_poweroff_noirq,
+	.restore_noirq	= amba_pm_restore_noirq,
+	SET_RUNTIME_PM_OPS(
+		pm_generic_runtime_suspend,
+		pm_generic_runtime_resume,
+		pm_generic_runtime_idle
+	)
+};
+
 /*
  * Primecells are part of the Advanced Microcontroller Bus Architecture,
  * so we call the bus "amba".
@@ -111,8 +395,7 @@ struct bus_type amba_bustype = {
 	.dev_attrs	= amba_dev_attrs,
 	.match		= amba_match,
 	.uevent		= amba_uevent,
-	.suspend	= amba_suspend,
-	.resume		= amba_resume,
+	.pm		= &amba_pm,
 };
 
 static int __init amba_init(void)
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index a0ccf28..1849975 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -58,6 +58,8 @@ enum amba_vendor {
 
 extern struct bus_type amba_bustype;
 
+#define to_amba_device(d)	container_of(d, struct amba_device, dev)
+
 #define amba_get_drvdata(d)	dev_get_drvdata(&d->dev)
 #define amba_set_drvdata(d,p)	dev_set_drvdata(&d->dev, p)
 
-- 
1.7.2.dirty

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [linux-pm] [PATCH] amba: move to pm ops
  2011-02-17 17:44 ` Takashi Iwai
@ 2011-02-21  7:36   ` Rabin Vincent
  0 siblings, 0 replies; 11+ messages in thread
From: Rabin Vincent @ 2011-02-21  7:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 17, 2011 at 23:14, Takashi Iwai <tiwai@suse.de> wrote:
> At Thu, 17 Feb 2011 13:19:46 +0530,
> Rabin Vincent wrote:
>>
>> Support pm_ops in the AMBA bus instead of the legacy ops. ? pm_ops is needed
>> for runtime pm, and there is also a general move to convert drivers to
>> dev_pm_ops rather than bus specific PM ops in order to facilitate core
>> development.
>>
>> Since there are only 6 AMBA drivers using suspend/resume, convert them all in
>> one go and directly use the GENERIC_SUBSYS_PM_OPS in the bus.
>>
>> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
>> Cc: Chris Ball <cjb@laptop.org>
>> Cc: Grant Likely <grant.likely@secretlab.ca>
>> Cc: Takashi Iwai <tiwai@suse.de>
>> Cc: Linus Walleij <linus.walleij@linaro.org>
>> Cc: Greg Kroah-Hartman <gregkh@suse.de>
>> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
>
> For sound/arm/aaci.c,
>
> ?Acked-by: Takashi Iwai <tiwai@suse.de>
>
> Though, this would result in a zero-filled *_pm struct when
> CONFIG_PM_* isn't set? ?It's a few bytes wastes ;)

Thank you for the ack.  However, in v2 of the patch I've done a
different implementation in the bus code that doesn't necessitate
the conversion of all the drivers together, so this part is
dropped.  I will take this comment into consideration if I do
end up converting all the drivers.  Thanks.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [linux-pm] [PATCHv2] amba: support pm ops
  2011-02-21  7:02 ` [PATCHv2] amba: support " Rabin Vincent
@ 2011-02-21 20:26   ` Rafael J. Wysocki
  2011-02-22  5:41     ` [PATCHv3] " Rabin Vincent
  2011-02-22  5:44     ` [linux-pm] [PATCHv2] " Rabin Vincent
  0 siblings, 2 replies; 11+ messages in thread
From: Rafael J. Wysocki @ 2011-02-21 20:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday, February 21, 2011, Rabin Vincent wrote:
> Support pm_ops in the AMBA bus, required to allow drivers to use runtime pm.
> The implementation of AMBA bus pm ops is based on the platform bus
> implementation.
> 
> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>

Acked-by: Rafael J. Wysocki <rjw@sisk.pl>

(although I'd probably avoid creating an empty struct dev_pm_ops object
if both CONFIG_HIBERNATION and CONFIG_SUSPEND are unset).

> ---
> v2: Base the implementation on the platform bus instead of the generic ops,
>     implementation all the functions platform does and with the same behaviour.
>     Also continue to support the legacy operations so that this patch doesn't
>     need to modify all the drivers and thus becomes easier to merge.
> 
>  drivers/amba/bus.c       |  329 ++++++++++++++++++++++++++++++++++++++++++----
>  include/linux/amba/bus.h |    2 +
>  2 files changed, 308 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
> index ca96b0a..7bc7762 100644
> --- a/drivers/amba/bus.c
> +++ b/drivers/amba/bus.c
> @@ -13,12 +13,12 @@
>  #include <linux/string.h>
>  #include <linux/slab.h>
>  #include <linux/io.h>
> +#include <linux/pm.h>
>  #include <linux/amba/bus.h>
>  
>  #include <asm/irq.h>
>  #include <asm/sizes.h>
>  
> -#define to_amba_device(d)	container_of(d, struct amba_device, dev)
>  #define to_amba_driver(d)	container_of(d, struct amba_driver, drv)
>  
>  static struct amba_id *
> @@ -57,26 +57,6 @@ static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
>  #define amba_uevent NULL
>  #endif
>  
> -static int amba_suspend(struct device *dev, pm_message_t state)
> -{
> -	struct amba_driver *drv = to_amba_driver(dev->driver);
> -	int ret = 0;
> -
> -	if (dev->driver && drv->suspend)
> -		ret = drv->suspend(to_amba_device(dev), state);
> -	return ret;
> -}
> -
> -static int amba_resume(struct device *dev)
> -{
> -	struct amba_driver *drv = to_amba_driver(dev->driver);
> -	int ret = 0;
> -
> -	if (dev->driver && drv->resume)
> -		ret = drv->resume(to_amba_device(dev));
> -	return ret;
> -}
> -
>  #define amba_attr_func(name,fmt,arg...)					\
>  static ssize_t name##_show(struct device *_dev,				\
>  			   struct device_attribute *attr, char *buf)	\
> @@ -102,6 +82,310 @@ static struct device_attribute amba_dev_attrs[] = {
>  	__ATTR_NULL,
>  };
>  
> +#ifdef CONFIG_PM_SLEEP
> +
> +static int amba_legacy_suspend(struct device *dev, pm_message_t mesg)
> +{
> +	struct amba_driver *adrv = to_amba_driver(dev->driver);
> +	struct amba_device *adev = to_amba_device(dev);
> +	int ret = 0;
> +
> +	if (dev->driver && adrv->suspend)
> +		ret = adrv->suspend(adev, mesg);
> +
> +	return ret;
> +}
> +
> +static int amba_legacy_resume(struct device *dev)
> +{
> +	struct amba_driver *adrv = to_amba_driver(dev->driver);
> +	struct amba_device *adev = to_amba_device(dev);
> +	int ret = 0;
> +
> +	if (dev->driver && adrv->resume)
> +		ret = adrv->resume(adev);
> +
> +	return ret;
> +}
> +
> +static int amba_pm_prepare(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (drv && drv->pm && drv->pm->prepare)
> +		ret = drv->pm->prepare(dev);
> +
> +	return ret;
> +}
> +
> +static void amba_pm_complete(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +
> +	if (drv && drv->pm && drv->pm->complete)
> +		drv->pm->complete(dev);
> +}
> +
> +#else /* !CONFIG_PM_SLEEP */
> +
> +#define amba_pm_prepare		NULL
> +#define amba_pm_complete		NULL
> +
> +#endif /* !CONFIG_PM_SLEEP */
> +
> +#ifdef CONFIG_SUSPEND
> +
> +static int amba_pm_suspend(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->suspend)
> +			ret = drv->pm->suspend(dev);
> +	} else {
> +		ret = amba_legacy_suspend(dev, PMSG_SUSPEND);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_suspend_noirq(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->suspend_noirq)
> +			ret = drv->pm->suspend_noirq(dev);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_resume(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->resume)
> +			ret = drv->pm->resume(dev);
> +	} else {
> +		ret = amba_legacy_resume(dev);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_resume_noirq(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->resume_noirq)
> +			ret = drv->pm->resume_noirq(dev);
> +	}
> +
> +	return ret;
> +}
> +
> +#else /* !CONFIG_SUSPEND */
> +
> +#define amba_pm_suspend		NULL
> +#define amba_pm_resume		NULL
> +#define amba_pm_suspend_noirq	NULL
> +#define amba_pm_resume_noirq	NULL
> +
> +#endif /* !CONFIG_SUSPEND */
> +
> +#ifdef CONFIG_HIBERNATION
> +
> +static int amba_pm_freeze(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->freeze)
> +			ret = drv->pm->freeze(dev);
> +	} else {
> +		ret = amba_legacy_suspend(dev, PMSG_FREEZE);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_freeze_noirq(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->freeze_noirq)
> +			ret = drv->pm->freeze_noirq(dev);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_thaw(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->thaw)
> +			ret = drv->pm->thaw(dev);
> +	} else {
> +		ret = amba_legacy_resume(dev);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_thaw_noirq(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->thaw_noirq)
> +			ret = drv->pm->thaw_noirq(dev);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_poweroff(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->poweroff)
> +			ret = drv->pm->poweroff(dev);
> +	} else {
> +		ret = amba_legacy_suspend(dev, PMSG_HIBERNATE);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_poweroff_noirq(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->poweroff_noirq)
> +			ret = drv->pm->poweroff_noirq(dev);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_restore(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->restore)
> +			ret = drv->pm->restore(dev);
> +	} else {
> +		ret = amba_legacy_resume(dev);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_restore_noirq(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->restore_noirq)
> +			ret = drv->pm->restore_noirq(dev);
> +	}
> +
> +	return ret;
> +}
> +
> +#else /* !CONFIG_HIBERNATION */
> +
> +#define amba_pm_freeze		NULL
> +#define amba_pm_thaw		NULL
> +#define amba_pm_poweroff		NULL
> +#define amba_pm_restore		NULL
> +#define amba_pm_freeze_noirq	NULL
> +#define amba_pm_thaw_noirq		NULL
> +#define amba_pm_poweroff_noirq	NULL
> +#define amba_pm_restore_noirq	NULL
> +
> +#endif /* !CONFIG_HIBERNATION */
> +
> +static const struct dev_pm_ops amba_pm = {
> +	.prepare	= amba_pm_prepare,
> +	.complete	= amba_pm_complete,
> +	.suspend	= amba_pm_suspend,
> +	.resume		= amba_pm_resume,
> +	.freeze		= amba_pm_freeze,
> +	.thaw		= amba_pm_thaw,
> +	.poweroff	= amba_pm_poweroff,
> +	.restore	= amba_pm_restore,
> +	.suspend_noirq	= amba_pm_suspend_noirq,
> +	.resume_noirq	= amba_pm_resume_noirq,
> +	.freeze_noirq	= amba_pm_freeze_noirq,
> +	.thaw_noirq	= amba_pm_thaw_noirq,
> +	.poweroff_noirq	= amba_pm_poweroff_noirq,
> +	.restore_noirq	= amba_pm_restore_noirq,
> +	SET_RUNTIME_PM_OPS(
> +		pm_generic_runtime_suspend,
> +		pm_generic_runtime_resume,
> +		pm_generic_runtime_idle
> +	)
> +};
> +
>  /*
>   * Primecells are part of the Advanced Microcontroller Bus Architecture,
>   * so we call the bus "amba".
> @@ -111,8 +395,7 @@ struct bus_type amba_bustype = {
>  	.dev_attrs	= amba_dev_attrs,
>  	.match		= amba_match,
>  	.uevent		= amba_uevent,
> -	.suspend	= amba_suspend,
> -	.resume		= amba_resume,
> +	.pm		= &amba_pm,
>  };
>  
>  static int __init amba_init(void)
> diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
> index a0ccf28..1849975 100644
> --- a/include/linux/amba/bus.h
> +++ b/include/linux/amba/bus.h
> @@ -58,6 +58,8 @@ enum amba_vendor {
>  
>  extern struct bus_type amba_bustype;
>  
> +#define to_amba_device(d)	container_of(d, struct amba_device, dev)
> +
>  #define amba_get_drvdata(d)	dev_get_drvdata(&d->dev)
>  #define amba_set_drvdata(d,p)	dev_set_drvdata(&d->dev, p)
>  
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCHv3] amba: support pm ops
  2011-02-21 20:26   ` [linux-pm] " Rafael J. Wysocki
@ 2011-02-22  5:41     ` Rabin Vincent
  2011-02-22 14:17       ` Linus Walleij
  2011-02-22 20:02       ` Rafael J. Wysocki
  2011-02-22  5:44     ` [linux-pm] [PATCHv2] " Rabin Vincent
  1 sibling, 2 replies; 11+ messages in thread
From: Rabin Vincent @ 2011-02-22  5:41 UTC (permalink / raw)
  To: linux-arm-kernel

Support pm_ops in the AMBA bus, required to allow drivers to use runtime pm.
The implementation of AMBA bus pm ops is based on the platform bus
implementation.

Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
---
v3: add a missing header. don't keep an empty dev_pm_ops struct when it's
    not used.

 drivers/amba/bus.c       |  340 ++++++++++++++++++++++++++++++++++++++++++---
 include/linux/amba/bus.h |    2 +
 2 files changed, 319 insertions(+), 23 deletions(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index ca96b0a..7d38981 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -13,12 +13,13 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/io.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
 #include <linux/amba/bus.h>
 
 #include <asm/irq.h>
 #include <asm/sizes.h>
 
-#define to_amba_device(d)	container_of(d, struct amba_device, dev)
 #define to_amba_driver(d)	container_of(d, struct amba_driver, drv)
 
 static struct amba_id *
@@ -57,26 +58,6 @@ static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
 #define amba_uevent NULL
 #endif
 
-static int amba_suspend(struct device *dev, pm_message_t state)
-{
-	struct amba_driver *drv = to_amba_driver(dev->driver);
-	int ret = 0;
-
-	if (dev->driver && drv->suspend)
-		ret = drv->suspend(to_amba_device(dev), state);
-	return ret;
-}
-
-static int amba_resume(struct device *dev)
-{
-	struct amba_driver *drv = to_amba_driver(dev->driver);
-	int ret = 0;
-
-	if (dev->driver && drv->resume)
-		ret = drv->resume(to_amba_device(dev));
-	return ret;
-}
-
 #define amba_attr_func(name,fmt,arg...)					\
 static ssize_t name##_show(struct device *_dev,				\
 			   struct device_attribute *attr, char *buf)	\
@@ -102,6 +83,320 @@ static struct device_attribute amba_dev_attrs[] = {
 	__ATTR_NULL,
 };
 
+#ifdef CONFIG_PM_SLEEP
+
+static int amba_legacy_suspend(struct device *dev, pm_message_t mesg)
+{
+	struct amba_driver *adrv = to_amba_driver(dev->driver);
+	struct amba_device *adev = to_amba_device(dev);
+	int ret = 0;
+
+	if (dev->driver && adrv->suspend)
+		ret = adrv->suspend(adev, mesg);
+
+	return ret;
+}
+
+static int amba_legacy_resume(struct device *dev)
+{
+	struct amba_driver *adrv = to_amba_driver(dev->driver);
+	struct amba_device *adev = to_amba_device(dev);
+	int ret = 0;
+
+	if (dev->driver && adrv->resume)
+		ret = adrv->resume(adev);
+
+	return ret;
+}
+
+static int amba_pm_prepare(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (drv && drv->pm && drv->pm->prepare)
+		ret = drv->pm->prepare(dev);
+
+	return ret;
+}
+
+static void amba_pm_complete(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+
+	if (drv && drv->pm && drv->pm->complete)
+		drv->pm->complete(dev);
+}
+
+#else /* !CONFIG_PM_SLEEP */
+
+#define amba_pm_prepare		NULL
+#define amba_pm_complete		NULL
+
+#endif /* !CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_SUSPEND
+
+static int amba_pm_suspend(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->suspend)
+			ret = drv->pm->suspend(dev);
+	} else {
+		ret = amba_legacy_suspend(dev, PMSG_SUSPEND);
+	}
+
+	return ret;
+}
+
+static int amba_pm_suspend_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->suspend_noirq)
+			ret = drv->pm->suspend_noirq(dev);
+	}
+
+	return ret;
+}
+
+static int amba_pm_resume(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->resume)
+			ret = drv->pm->resume(dev);
+	} else {
+		ret = amba_legacy_resume(dev);
+	}
+
+	return ret;
+}
+
+static int amba_pm_resume_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->resume_noirq)
+			ret = drv->pm->resume_noirq(dev);
+	}
+
+	return ret;
+}
+
+#else /* !CONFIG_SUSPEND */
+
+#define amba_pm_suspend		NULL
+#define amba_pm_resume		NULL
+#define amba_pm_suspend_noirq	NULL
+#define amba_pm_resume_noirq	NULL
+
+#endif /* !CONFIG_SUSPEND */
+
+#ifdef CONFIG_HIBERNATION
+
+static int amba_pm_freeze(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->freeze)
+			ret = drv->pm->freeze(dev);
+	} else {
+		ret = amba_legacy_suspend(dev, PMSG_FREEZE);
+	}
+
+	return ret;
+}
+
+static int amba_pm_freeze_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->freeze_noirq)
+			ret = drv->pm->freeze_noirq(dev);
+	}
+
+	return ret;
+}
+
+static int amba_pm_thaw(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->thaw)
+			ret = drv->pm->thaw(dev);
+	} else {
+		ret = amba_legacy_resume(dev);
+	}
+
+	return ret;
+}
+
+static int amba_pm_thaw_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->thaw_noirq)
+			ret = drv->pm->thaw_noirq(dev);
+	}
+
+	return ret;
+}
+
+static int amba_pm_poweroff(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->poweroff)
+			ret = drv->pm->poweroff(dev);
+	} else {
+		ret = amba_legacy_suspend(dev, PMSG_HIBERNATE);
+	}
+
+	return ret;
+}
+
+static int amba_pm_poweroff_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->poweroff_noirq)
+			ret = drv->pm->poweroff_noirq(dev);
+	}
+
+	return ret;
+}
+
+static int amba_pm_restore(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->restore)
+			ret = drv->pm->restore(dev);
+	} else {
+		ret = amba_legacy_resume(dev);
+	}
+
+	return ret;
+}
+
+static int amba_pm_restore_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->restore_noirq)
+			ret = drv->pm->restore_noirq(dev);
+	}
+
+	return ret;
+}
+
+#else /* !CONFIG_HIBERNATION */
+
+#define amba_pm_freeze		NULL
+#define amba_pm_thaw		NULL
+#define amba_pm_poweroff		NULL
+#define amba_pm_restore		NULL
+#define amba_pm_freeze_noirq	NULL
+#define amba_pm_thaw_noirq		NULL
+#define amba_pm_poweroff_noirq	NULL
+#define amba_pm_restore_noirq	NULL
+
+#endif /* !CONFIG_HIBERNATION */
+
+#ifdef CONFIG_PM
+
+static const struct dev_pm_ops amba_pm = {
+	.prepare	= amba_pm_prepare,
+	.complete	= amba_pm_complete,
+	.suspend	= amba_pm_suspend,
+	.resume		= amba_pm_resume,
+	.freeze		= amba_pm_freeze,
+	.thaw		= amba_pm_thaw,
+	.poweroff	= amba_pm_poweroff,
+	.restore	= amba_pm_restore,
+	.suspend_noirq	= amba_pm_suspend_noirq,
+	.resume_noirq	= amba_pm_resume_noirq,
+	.freeze_noirq	= amba_pm_freeze_noirq,
+	.thaw_noirq	= amba_pm_thaw_noirq,
+	.poweroff_noirq	= amba_pm_poweroff_noirq,
+	.restore_noirq	= amba_pm_restore_noirq,
+	SET_RUNTIME_PM_OPS(
+		pm_generic_runtime_suspend,
+		pm_generic_runtime_resume,
+		pm_generic_runtime_idle
+	)
+};
+
+#define AMBA_PM (&amba_pm)
+
+#else /* !CONFIG_PM */
+
+#define AMBA_PM	NULL
+
+#endif /* !CONFIG_PM */
+
 /*
  * Primecells are part of the Advanced Microcontroller Bus Architecture,
  * so we call the bus "amba".
@@ -111,8 +406,7 @@ struct bus_type amba_bustype = {
 	.dev_attrs	= amba_dev_attrs,
 	.match		= amba_match,
 	.uevent		= amba_uevent,
-	.suspend	= amba_suspend,
-	.resume		= amba_resume,
+	.pm		= AMBA_PM,
 };
 
 static int __init amba_init(void)
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index a0ccf28..1849975 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -58,6 +58,8 @@ enum amba_vendor {
 
 extern struct bus_type amba_bustype;
 
+#define to_amba_device(d)	container_of(d, struct amba_device, dev)
+
 #define amba_get_drvdata(d)	dev_get_drvdata(&d->dev)
 #define amba_set_drvdata(d,p)	dev_set_drvdata(&d->dev, p)
 
-- 
1.7.2.dirty

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [linux-pm] [PATCHv2] amba: support pm ops
  2011-02-21 20:26   ` [linux-pm] " Rafael J. Wysocki
  2011-02-22  5:41     ` [PATCHv3] " Rabin Vincent
@ 2011-02-22  5:44     ` Rabin Vincent
  1 sibling, 0 replies; 11+ messages in thread
From: Rabin Vincent @ 2011-02-22  5:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 22, 2011 at 01:56, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Monday, February 21, 2011, Rabin Vincent wrote:
>> Support pm_ops in the AMBA bus, required to allow drivers to use runtime pm.
>> The implementation of AMBA bus pm ops is based on the platform bus
>> implementation.
>>
>> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
>
> Acked-by: Rafael J. Wysocki <rjw@sisk.pl>

Thanks.

> (although I'd probably avoid creating an empty struct dev_pm_ops object
> if both CONFIG_HIBERNATION and CONFIG_SUSPEND are unset).

Done in v3.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCHv3] amba: support pm ops
  2011-02-22  5:41     ` [PATCHv3] " Rabin Vincent
@ 2011-02-22 14:17       ` Linus Walleij
  2011-02-22 20:02       ` Rafael J. Wysocki
  1 sibling, 0 replies; 11+ messages in thread
From: Linus Walleij @ 2011-02-22 14:17 UTC (permalink / raw)
  To: linux-arm-kernel

2011/2/22 Rabin Vincent <rabin.vincent@stericsson.com>:
> Support pm_ops in the AMBA bus, required to allow drivers to use runtime pm.
> The implementation of AMBA bus pm ops is based on the platform bus
> implementation.
>
> Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
> ---
> v3: add a missing header. don't keep an empty dev_pm_ops struct when it's
> ? ?not used.

FWIW:
Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCHv3] amba: support pm ops
  2011-02-22  5:41     ` [PATCHv3] " Rabin Vincent
  2011-02-22 14:17       ` Linus Walleij
@ 2011-02-22 20:02       ` Rafael J. Wysocki
  2011-02-22 20:15         ` Russell King - ARM Linux
  1 sibling, 1 reply; 11+ messages in thread
From: Rafael J. Wysocki @ 2011-02-22 20:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, February 22, 2011, Rabin Vincent wrote:
> Support pm_ops in the AMBA bus, required to allow drivers to use runtime pm.
> The implementation of AMBA bus pm ops is based on the platform bus
> implementation.
> 
> Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>

Looks good.

Who's supposed to take it?

Rafael


> ---
> v3: add a missing header. don't keep an empty dev_pm_ops struct when it's
>     not used.
> 
>  drivers/amba/bus.c       |  340 ++++++++++++++++++++++++++++++++++++++++++---
>  include/linux/amba/bus.h |    2 +
>  2 files changed, 319 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
> index ca96b0a..7d38981 100644
> --- a/drivers/amba/bus.c
> +++ b/drivers/amba/bus.c
> @@ -13,12 +13,13 @@
>  #include <linux/string.h>
>  #include <linux/slab.h>
>  #include <linux/io.h>
> +#include <linux/pm.h>
> +#include <linux/pm_runtime.h>
>  #include <linux/amba/bus.h>
>  
>  #include <asm/irq.h>
>  #include <asm/sizes.h>
>  
> -#define to_amba_device(d)	container_of(d, struct amba_device, dev)
>  #define to_amba_driver(d)	container_of(d, struct amba_driver, drv)
>  
>  static struct amba_id *
> @@ -57,26 +58,6 @@ static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
>  #define amba_uevent NULL
>  #endif
>  
> -static int amba_suspend(struct device *dev, pm_message_t state)
> -{
> -	struct amba_driver *drv = to_amba_driver(dev->driver);
> -	int ret = 0;
> -
> -	if (dev->driver && drv->suspend)
> -		ret = drv->suspend(to_amba_device(dev), state);
> -	return ret;
> -}
> -
> -static int amba_resume(struct device *dev)
> -{
> -	struct amba_driver *drv = to_amba_driver(dev->driver);
> -	int ret = 0;
> -
> -	if (dev->driver && drv->resume)
> -		ret = drv->resume(to_amba_device(dev));
> -	return ret;
> -}
> -
>  #define amba_attr_func(name,fmt,arg...)					\
>  static ssize_t name##_show(struct device *_dev,				\
>  			   struct device_attribute *attr, char *buf)	\
> @@ -102,6 +83,320 @@ static struct device_attribute amba_dev_attrs[] = {
>  	__ATTR_NULL,
>  };
>  
> +#ifdef CONFIG_PM_SLEEP
> +
> +static int amba_legacy_suspend(struct device *dev, pm_message_t mesg)
> +{
> +	struct amba_driver *adrv = to_amba_driver(dev->driver);
> +	struct amba_device *adev = to_amba_device(dev);
> +	int ret = 0;
> +
> +	if (dev->driver && adrv->suspend)
> +		ret = adrv->suspend(adev, mesg);
> +
> +	return ret;
> +}
> +
> +static int amba_legacy_resume(struct device *dev)
> +{
> +	struct amba_driver *adrv = to_amba_driver(dev->driver);
> +	struct amba_device *adev = to_amba_device(dev);
> +	int ret = 0;
> +
> +	if (dev->driver && adrv->resume)
> +		ret = adrv->resume(adev);
> +
> +	return ret;
> +}
> +
> +static int amba_pm_prepare(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (drv && drv->pm && drv->pm->prepare)
> +		ret = drv->pm->prepare(dev);
> +
> +	return ret;
> +}
> +
> +static void amba_pm_complete(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +
> +	if (drv && drv->pm && drv->pm->complete)
> +		drv->pm->complete(dev);
> +}
> +
> +#else /* !CONFIG_PM_SLEEP */
> +
> +#define amba_pm_prepare		NULL
> +#define amba_pm_complete		NULL
> +
> +#endif /* !CONFIG_PM_SLEEP */
> +
> +#ifdef CONFIG_SUSPEND
> +
> +static int amba_pm_suspend(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->suspend)
> +			ret = drv->pm->suspend(dev);
> +	} else {
> +		ret = amba_legacy_suspend(dev, PMSG_SUSPEND);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_suspend_noirq(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->suspend_noirq)
> +			ret = drv->pm->suspend_noirq(dev);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_resume(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->resume)
> +			ret = drv->pm->resume(dev);
> +	} else {
> +		ret = amba_legacy_resume(dev);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_resume_noirq(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->resume_noirq)
> +			ret = drv->pm->resume_noirq(dev);
> +	}
> +
> +	return ret;
> +}
> +
> +#else /* !CONFIG_SUSPEND */
> +
> +#define amba_pm_suspend		NULL
> +#define amba_pm_resume		NULL
> +#define amba_pm_suspend_noirq	NULL
> +#define amba_pm_resume_noirq	NULL
> +
> +#endif /* !CONFIG_SUSPEND */
> +
> +#ifdef CONFIG_HIBERNATION
> +
> +static int amba_pm_freeze(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->freeze)
> +			ret = drv->pm->freeze(dev);
> +	} else {
> +		ret = amba_legacy_suspend(dev, PMSG_FREEZE);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_freeze_noirq(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->freeze_noirq)
> +			ret = drv->pm->freeze_noirq(dev);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_thaw(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->thaw)
> +			ret = drv->pm->thaw(dev);
> +	} else {
> +		ret = amba_legacy_resume(dev);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_thaw_noirq(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->thaw_noirq)
> +			ret = drv->pm->thaw_noirq(dev);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_poweroff(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->poweroff)
> +			ret = drv->pm->poweroff(dev);
> +	} else {
> +		ret = amba_legacy_suspend(dev, PMSG_HIBERNATE);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_poweroff_noirq(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->poweroff_noirq)
> +			ret = drv->pm->poweroff_noirq(dev);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_restore(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->restore)
> +			ret = drv->pm->restore(dev);
> +	} else {
> +		ret = amba_legacy_resume(dev);
> +	}
> +
> +	return ret;
> +}
> +
> +static int amba_pm_restore_noirq(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->restore_noirq)
> +			ret = drv->pm->restore_noirq(dev);
> +	}
> +
> +	return ret;
> +}
> +
> +#else /* !CONFIG_HIBERNATION */
> +
> +#define amba_pm_freeze		NULL
> +#define amba_pm_thaw		NULL
> +#define amba_pm_poweroff		NULL
> +#define amba_pm_restore		NULL
> +#define amba_pm_freeze_noirq	NULL
> +#define amba_pm_thaw_noirq		NULL
> +#define amba_pm_poweroff_noirq	NULL
> +#define amba_pm_restore_noirq	NULL
> +
> +#endif /* !CONFIG_HIBERNATION */
> +
> +#ifdef CONFIG_PM
> +
> +static const struct dev_pm_ops amba_pm = {
> +	.prepare	= amba_pm_prepare,
> +	.complete	= amba_pm_complete,
> +	.suspend	= amba_pm_suspend,
> +	.resume		= amba_pm_resume,
> +	.freeze		= amba_pm_freeze,
> +	.thaw		= amba_pm_thaw,
> +	.poweroff	= amba_pm_poweroff,
> +	.restore	= amba_pm_restore,
> +	.suspend_noirq	= amba_pm_suspend_noirq,
> +	.resume_noirq	= amba_pm_resume_noirq,
> +	.freeze_noirq	= amba_pm_freeze_noirq,
> +	.thaw_noirq	= amba_pm_thaw_noirq,
> +	.poweroff_noirq	= amba_pm_poweroff_noirq,
> +	.restore_noirq	= amba_pm_restore_noirq,
> +	SET_RUNTIME_PM_OPS(
> +		pm_generic_runtime_suspend,
> +		pm_generic_runtime_resume,
> +		pm_generic_runtime_idle
> +	)
> +};
> +
> +#define AMBA_PM (&amba_pm)
> +
> +#else /* !CONFIG_PM */
> +
> +#define AMBA_PM	NULL
> +
> +#endif /* !CONFIG_PM */
> +
>  /*
>   * Primecells are part of the Advanced Microcontroller Bus Architecture,
>   * so we call the bus "amba".
> @@ -111,8 +406,7 @@ struct bus_type amba_bustype = {
>  	.dev_attrs	= amba_dev_attrs,
>  	.match		= amba_match,
>  	.uevent		= amba_uevent,
> -	.suspend	= amba_suspend,
> -	.resume		= amba_resume,
> +	.pm		= AMBA_PM,
>  };
>  
>  static int __init amba_init(void)
> diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
> index a0ccf28..1849975 100644
> --- a/include/linux/amba/bus.h
> +++ b/include/linux/amba/bus.h
> @@ -58,6 +58,8 @@ enum amba_vendor {
>  
>  extern struct bus_type amba_bustype;
>  
> +#define to_amba_device(d)	container_of(d, struct amba_device, dev)
> +
>  #define amba_get_drvdata(d)	dev_get_drvdata(&d->dev)
>  #define amba_set_drvdata(d,p)	dev_set_drvdata(&d->dev, p)
>  
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCHv3] amba: support pm ops
  2011-02-22 20:02       ` Rafael J. Wysocki
@ 2011-02-22 20:15         ` Russell King - ARM Linux
  2011-02-22 20:28           ` Rafael J. Wysocki
  0 siblings, 1 reply; 11+ messages in thread
From: Russell King - ARM Linux @ 2011-02-22 20:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 22, 2011 at 09:02:14PM +0100, Rafael J. Wysocki wrote:
> On Tuesday, February 22, 2011, Rabin Vincent wrote:
> > Support pm_ops in the AMBA bus, required to allow drivers to use runtime pm.
> > The implementation of AMBA bus pm ops is based on the platform bus
> > implementation.
> > 
> > Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
> > Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
> 
> Looks good.
> 
> Who's supposed to take it?

Does this help?

ARM PRIMECELL BUS SUPPORT
M:      Russell King <linux@arm.linux.org.uk>
S:      Maintained
F:      drivers/amba/
F:      include/linux/amba/bus.h

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCHv3] amba: support pm ops
  2011-02-22 20:15         ` Russell King - ARM Linux
@ 2011-02-22 20:28           ` Rafael J. Wysocki
  0 siblings, 0 replies; 11+ messages in thread
From: Rafael J. Wysocki @ 2011-02-22 20:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, February 22, 2011, Russell King - ARM Linux wrote:
> On Tue, Feb 22, 2011 at 09:02:14PM +0100, Rafael J. Wysocki wrote:
> > On Tuesday, February 22, 2011, Rabin Vincent wrote:
> > > Support pm_ops in the AMBA bus, required to allow drivers to use runtime pm.
> > > The implementation of AMBA bus pm ops is based on the platform bus
> > > implementation.
> > > 
> > > Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
> > > Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
> > 
> > Looks good.
> > 
> > Who's supposed to take it?
> 
> Does this help?
> 
> ARM PRIMECELL BUS SUPPORT
> M:      Russell King <linux@arm.linux.org.uk>
> S:      Maintained
> F:      drivers/amba/
> F:      include/linux/amba/bus.h

Still, it's power management, right?

Anyway, I guess that means you're going to take care of it. :-)

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2011-02-22 20:28 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-17  7:49 [PATCH] amba: move to pm ops Rabin Vincent
2011-02-17 17:44 ` Takashi Iwai
2011-02-21  7:36   ` [linux-pm] " Rabin Vincent
2011-02-21  7:02 ` [PATCHv2] amba: support " Rabin Vincent
2011-02-21 20:26   ` [linux-pm] " Rafael J. Wysocki
2011-02-22  5:41     ` [PATCHv3] " Rabin Vincent
2011-02-22 14:17       ` Linus Walleij
2011-02-22 20:02       ` Rafael J. Wysocki
2011-02-22 20:15         ` Russell King - ARM Linux
2011-02-22 20:28           ` Rafael J. Wysocki
2011-02-22  5:44     ` [linux-pm] [PATCHv2] " Rabin Vincent

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).