linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ARM: S3C64XX: Add basic cpuidle driver
@ 2011-12-05 20:32 Mark Brown
  2011-12-06 11:31 ` Heiko Stübner
  2011-12-21  7:29 ` Kukjin Kim
  0 siblings, 2 replies; 6+ messages in thread
From: Mark Brown @ 2011-12-05 20:32 UTC (permalink / raw)
  To: linux-arm-kernel

Add a very basic cpuidle driver for S3C64xx which merely drives the CPU
into IDLE mode. We could do this with pm_idle but the more modern idiom
is to use cpuidle and the intention is to go further and support STOP
and DEEP-STOP states in conjunction with the pm_domain framework.

The actual state entry code was lifted from Tomasz Figa's work on spica.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 arch/arm/mach-s3c64xx/Makefile  |    1 +
 arch/arm/mach-s3c64xx/cpuidle.c |   91 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 92 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-s3c64xx/cpuidle.c

diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile
index e32093c..8f5574b 100644
--- a/arch/arm/mach-s3c64xx/Makefile
+++ b/arch/arm/mach-s3c64xx/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
 obj-$(CONFIG_PM)		+= pm.o
 obj-$(CONFIG_PM)		+= sleep.o
 obj-$(CONFIG_PM)		+= irq-pm.o
+obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 
 # Machine support
 
diff --git a/arch/arm/mach-s3c64xx/cpuidle.c b/arch/arm/mach-s3c64xx/cpuidle.c
new file mode 100644
index 0000000..625d2c7
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/cpuidle.c
@@ -0,0 +1,91 @@
+/* linux/arch/arm/mach-s3c64xx/cpuidle.c
+ *
+ * Copyright (c) 2011 Wolfson Microelectronics, plc
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/cpuidle.h>
+#include <linux/io.h>
+#include <linux/export.h>
+#include <linux/time.h>
+
+#include <asm/proc-fns.h>
+
+#include <mach/map.h>
+
+#include <mach/regs-sys.h>
+#include <mach/regs-syscon-power.h>
+
+static int s3c64xx_enter_idle(struct cpuidle_device *dev,
+			      struct cpuidle_driver *drv,
+			      int index)
+{
+	struct timeval before, after;
+	unsigned long tmp;
+	int idle_time;
+
+	local_irq_disable();
+	do_gettimeofday(&before);
+
+	/* Setup PWRCFG to enter idle mode */
+	tmp = __raw_readl(S3C64XX_PWR_CFG);
+	tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
+	tmp |= S3C64XX_PWRCFG_CFG_WFI_IDLE;
+	__raw_writel(tmp, S3C64XX_PWR_CFG);
+
+	cpu_do_idle();
+
+	do_gettimeofday(&after);
+	local_irq_enable();
+	idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+		    (after.tv_usec - before.tv_usec);
+
+	dev->last_residency = idle_time;
+	return index;
+}
+
+static struct cpuidle_state s3c64xx_cpuidle_set[] = {
+	[0] = {
+		.enter			= s3c64xx_enter_idle,
+		.exit_latency		= 1,
+		.target_residency	= 100000,
+		.flags			= CPUIDLE_FLAG_TIME_VALID,
+		.name			= "IDLE",
+		.desc			= "System active, ARM gated",
+	},
+};
+
+static struct cpuidle_driver s3c64xx_cpuidle_driver = {
+	.name		= "s3c64xx_cpuidle",
+	.owner		= THIS_MODULE,
+	.state_count	= ARRAY_SIZE(s3c64xx_cpuidle_set),
+};
+
+static struct cpuidle_device s3c64xx_cpuidle_device = {
+	.state_count	= ARRAY_SIZE(s3c64xx_cpuidle_set),
+};
+
+static int __init s3c64xx_init_cpuidle(void)
+{
+	int ret;
+
+	memcpy(s3c64xx_cpuidle_driver.states, s3c64xx_cpuidle_set,
+	       sizeof(s3c64xx_cpuidle_set));
+	cpuidle_register_driver(&s3c64xx_cpuidle_driver);
+
+	ret = cpuidle_register_device(&s3c64xx_cpuidle_device);
+	if (ret) {
+		pr_err("Failed to register cpuidle device: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+device_initcall(s3c64xx_init_cpuidle);
-- 
1.7.7.3

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

* [PATCH] ARM: S3C64XX: Add basic cpuidle driver
  2011-12-05 20:32 [PATCH] ARM: S3C64XX: Add basic cpuidle driver Mark Brown
@ 2011-12-06 11:31 ` Heiko Stübner
  2011-12-22 18:13   ` Mark Brown
  2011-12-21  7:29 ` Kukjin Kim
  1 sibling, 1 reply; 6+ messages in thread
From: Heiko Stübner @ 2011-12-06 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

Am Montag, 5. Dezember 2011, 21:32:49 schrieb Mark Brown:
> Add a very basic cpuidle driver for S3C64xx which merely drives the CPU
> into IDLE mode. We could do this with pm_idle but the more modern idiom
> is to use cpuidle and the intention is to go further and support STOP
> and DEEP-STOP states in conjunction with the pm_domain framework.
cool :-)

My S3C2416 playground is quite similar in its low power modes and their wakeup 
sources and I've got a idle driver for it in a similar state sitting here.

So I'm really looking forward to seeing a possible example on how to support 
the STOP and DEEP-STOP modes best.


> The actual state entry code was lifted from Tomasz Figa's work on spica.
>
> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Heiko Stuebner <heiko@sntech.de>


> ---
>  arch/arm/mach-s3c64xx/Makefile  |    1 +
>  arch/arm/mach-s3c64xx/cpuidle.c |   91
> +++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+),
> 0 deletions(-)
>  create mode 100644 arch/arm/mach-s3c64xx/cpuidle.c
> 
> diff --git a/arch/arm/mach-s3c64xx/Makefile
> b/arch/arm/mach-s3c64xx/Makefile index e32093c..8f5574b 100644
> --- a/arch/arm/mach-s3c64xx/Makefile
> +++ b/arch/arm/mach-s3c64xx/Makefile
> @@ -40,6 +40,7 @@ obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) +=
> setup-sdhci-gpio.o obj-$(CONFIG_PM)		+= pm.o
>  obj-$(CONFIG_PM)		+= sleep.o
>  obj-$(CONFIG_PM)		+= irq-pm.o
> +obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
> 
>  # Machine support
> 
> diff --git a/arch/arm/mach-s3c64xx/cpuidle.c
> b/arch/arm/mach-s3c64xx/cpuidle.c new file mode 100644
> index 0000000..625d2c7
> --- /dev/null
> +++ b/arch/arm/mach-s3c64xx/cpuidle.c
> @@ -0,0 +1,91 @@
> +/* linux/arch/arm/mach-s3c64xx/cpuidle.c
> + *
> + * Copyright (c) 2011 Wolfson Microelectronics, plc
> + * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> + *		http://www.samsung.com
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> +*/
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/cpuidle.h>
> +#include <linux/io.h>
> +#include <linux/export.h>
> +#include <linux/time.h>
> +
> +#include <asm/proc-fns.h>
> +
> +#include <mach/map.h>
> +
> +#include <mach/regs-sys.h>
> +#include <mach/regs-syscon-power.h>
> +
> +static int s3c64xx_enter_idle(struct cpuidle_device *dev,
> +			      struct cpuidle_driver *drv,
> +			      int index)
> +{
> +	struct timeval before, after;
> +	unsigned long tmp;
> +	int idle_time;
> +
> +	local_irq_disable();
> +	do_gettimeofday(&before);
> +
> +	/* Setup PWRCFG to enter idle mode */
> +	tmp = __raw_readl(S3C64XX_PWR_CFG);
> +	tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
> +	tmp |= S3C64XX_PWRCFG_CFG_WFI_IDLE;
> +	__raw_writel(tmp, S3C64XX_PWR_CFG);
> +
> +	cpu_do_idle();
> +
> +	do_gettimeofday(&after);
> +	local_irq_enable();
> +	idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
> +		    (after.tv_usec - before.tv_usec);
> +
> +	dev->last_residency = idle_time;
> +	return index;
> +}
> +
> +static struct cpuidle_state s3c64xx_cpuidle_set[] = {
> +	[0] = {
> +		.enter			= s3c64xx_enter_idle,
> +		.exit_latency		= 1,
> +		.target_residency	= 100000,
> +		.flags			= CPUIDLE_FLAG_TIME_VALID,
> +		.name			= "IDLE",
> +		.desc			= "System active, ARM gated",
> +	},
> +};
> +
> +static struct cpuidle_driver s3c64xx_cpuidle_driver = {
> +	.name		= "s3c64xx_cpuidle",
> +	.owner		= THIS_MODULE,
> +	.state_count	= ARRAY_SIZE(s3c64xx_cpuidle_set),
> +};
> +
> +static struct cpuidle_device s3c64xx_cpuidle_device = {
> +	.state_count	= ARRAY_SIZE(s3c64xx_cpuidle_set),
> +};
> +
> +static int __init s3c64xx_init_cpuidle(void)
> +{
> +	int ret;
> +
> +	memcpy(s3c64xx_cpuidle_driver.states, s3c64xx_cpuidle_set,
> +	       sizeof(s3c64xx_cpuidle_set));
> +	cpuidle_register_driver(&s3c64xx_cpuidle_driver);
> +
> +	ret = cpuidle_register_device(&s3c64xx_cpuidle_device);
> +	if (ret) {
> +		pr_err("Failed to register cpuidle device: %d\n", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +device_initcall(s3c64xx_init_cpuidle);

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

* [PATCH] ARM: S3C64XX: Add basic cpuidle driver
  2011-12-05 20:32 [PATCH] ARM: S3C64XX: Add basic cpuidle driver Mark Brown
  2011-12-06 11:31 ` Heiko Stübner
@ 2011-12-21  7:29 ` Kukjin Kim
  1 sibling, 0 replies; 6+ messages in thread
From: Kukjin Kim @ 2011-12-21  7:29 UTC (permalink / raw)
  To: linux-arm-kernel

Mark Brown wrote:
> 
> Add a very basic cpuidle driver for S3C64xx which merely drives the CPU
> into IDLE mode. We could do this with pm_idle but the more modern idiom
> is to use cpuidle and the intention is to go further and support STOP
> and DEEP-STOP states in conjunction with the pm_domain framework.
> 
> The actual state entry code was lifted from Tomasz Figa's work on spica.
> 
> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
> ---
>  arch/arm/mach-s3c64xx/Makefile  |    1 +
>  arch/arm/mach-s3c64xx/cpuidle.c |   91
> +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 92 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-s3c64xx/cpuidle.c
> 
> diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-
> s3c64xx/Makefile
> index e32093c..8f5574b 100644
> --- a/arch/arm/mach-s3c64xx/Makefile
> +++ b/arch/arm/mach-s3c64xx/Makefile
> @@ -40,6 +40,7 @@ obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-
> gpio.o
>  obj-$(CONFIG_PM)		+= pm.o
>  obj-$(CONFIG_PM)		+= sleep.o
>  obj-$(CONFIG_PM)		+= irq-pm.o
> +obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
> 
>  # Machine support
> 
> diff --git a/arch/arm/mach-s3c64xx/cpuidle.c b/arch/arm/mach-
> s3c64xx/cpuidle.c
> new file mode 100644
> index 0000000..625d2c7
> --- /dev/null
> +++ b/arch/arm/mach-s3c64xx/cpuidle.c
> @@ -0,0 +1,91 @@
> +/* linux/arch/arm/mach-s3c64xx/cpuidle.c
> + *
> + * Copyright (c) 2011 Wolfson Microelectronics, plc
> + * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> + *		http://www.samsung.com
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> +*/
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/cpuidle.h>
> +#include <linux/io.h>
> +#include <linux/export.h>
> +#include <linux/time.h>
> +
> +#include <asm/proc-fns.h>
> +
> +#include <mach/map.h>
> +
> +#include <mach/regs-sys.h>
> +#include <mach/regs-syscon-power.h>
> +
> +static int s3c64xx_enter_idle(struct cpuidle_device *dev,
> +			      struct cpuidle_driver *drv,
> +			      int index)
> +{
> +	struct timeval before, after;
> +	unsigned long tmp;
> +	int idle_time;
> +
> +	local_irq_disable();
> +	do_gettimeofday(&before);
> +
> +	/* Setup PWRCFG to enter idle mode */
> +	tmp = __raw_readl(S3C64XX_PWR_CFG);
> +	tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
> +	tmp |= S3C64XX_PWRCFG_CFG_WFI_IDLE;
> +	__raw_writel(tmp, S3C64XX_PWR_CFG);
> +
> +	cpu_do_idle();
> +
> +	do_gettimeofday(&after);
> +	local_irq_enable();
> +	idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
> +		    (after.tv_usec - before.tv_usec);
> +
> +	dev->last_residency = idle_time;
> +	return index;
> +}
> +
> +static struct cpuidle_state s3c64xx_cpuidle_set[] = {
> +	[0] = {
> +		.enter			= s3c64xx_enter_idle,
> +		.exit_latency		= 1,
> +		.target_residency	= 100000,
> +		.flags			= CPUIDLE_FLAG_TIME_VALID,
> +		.name			= "IDLE",
> +		.desc			= "System active, ARM gated",
> +	},
> +};
> +
> +static struct cpuidle_driver s3c64xx_cpuidle_driver = {
> +	.name		= "s3c64xx_cpuidle",
> +	.owner		= THIS_MODULE,
> +	.state_count	= ARRAY_SIZE(s3c64xx_cpuidle_set),
> +};
> +
> +static struct cpuidle_device s3c64xx_cpuidle_device = {
> +	.state_count	= ARRAY_SIZE(s3c64xx_cpuidle_set),
> +};
> +
> +static int __init s3c64xx_init_cpuidle(void)
> +{
> +	int ret;
> +
> +	memcpy(s3c64xx_cpuidle_driver.states, s3c64xx_cpuidle_set,
> +	       sizeof(s3c64xx_cpuidle_set));
> +	cpuidle_register_driver(&s3c64xx_cpuidle_driver);
> +
> +	ret = cpuidle_register_device(&s3c64xx_cpuidle_device);
> +	if (ret) {
> +		pr_err("Failed to register cpuidle device: %d\n", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +device_initcall(s3c64xx_init_cpuidle);
> --
> 1.7.7.3

Hi Mark,

Looks ok to me, will apply.
Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

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

* [PATCH] ARM: S3C64XX: Add basic cpuidle driver
  2011-12-06 11:31 ` Heiko Stübner
@ 2011-12-22 18:13   ` Mark Brown
  2012-03-30  8:32     ` Heiko Stübner
  0 siblings, 1 reply; 6+ messages in thread
From: Mark Brown @ 2011-12-22 18:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Dec 06, 2011 at 12:31:21PM +0100, Heiko St?bner wrote:

> My S3C2416 playground is quite similar in its low power modes and their wakeup 
> sources and I've got a idle driver for it in a similar state sitting here.

Yeah, there's a lot of ARM systems look like this.

> So I'm really looking forward to seeing a possible example on how to support 
> the STOP and DEEP-STOP modes best.

My plan there for the s3c64xx was to use pm_domain to figure out if the
system is idle enough to drop down, I've been adding some pm_runtime
support to provide the information to the core to let it figure this out.

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

* [PATCH] ARM: S3C64XX: Add basic cpuidle driver
  2011-12-22 18:13   ` Mark Brown
@ 2012-03-30  8:32     ` Heiko Stübner
  2012-03-30  9:35       ` Mark Brown
  0 siblings, 1 reply; 6+ messages in thread
From: Heiko Stübner @ 2012-03-30  8:32 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mark,

Am Donnerstag, 22. Dezember 2011, 19:13:59 schrieb Mark Brown:
> On Tue, Dec 06, 2011 at 12:31:21PM +0100, Heiko St?bner wrote:
> > So I'm really looking forward to seeing a possible example on how to
> > support the STOP and DEEP-STOP modes best.
> 
> My plan there for the s3c64xx was to use pm_domain to figure out if the
> system is idle enough to drop down, I've been adding some pm_runtime
> support to provide the information to the core to let it figure this out.

sorry for digging this up again, but do you happen to have some preliminary 
code laying around for this, that I could "borrow"?


Thanks
Heiko

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

* [PATCH] ARM: S3C64XX: Add basic cpuidle driver
  2012-03-30  8:32     ` Heiko Stübner
@ 2012-03-30  9:35       ` Mark Brown
  0 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2012-03-30  9:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 30, 2012 at 10:32:54AM +0200, Heiko St?bner wrote:
> Am Donnerstag, 22. Dezember 2011, 19:13:59 schrieb Mark Brown:

> > My plan there for the s3c64xx was to use pm_domain to figure out if the
> > system is idle enough to drop down, I've been adding some pm_runtime
> > support to provide the information to the core to let it figure this out.

> sorry for digging this up again, but do you happen to have some preliminary 
> code laying around for this, that I could "borrow"?

No, sorry.  The big problem is putting all the devices in power domains
since the Samsung port always has every single machine driver directly
register devices.  Until that problem is solved it's not possible to
figure out if we're idle.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120330/75918690/attachment-0001.sig>

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

end of thread, other threads:[~2012-03-30  9:35 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-05 20:32 [PATCH] ARM: S3C64XX: Add basic cpuidle driver Mark Brown
2011-12-06 11:31 ` Heiko Stübner
2011-12-22 18:13   ` Mark Brown
2012-03-30  8:32     ` Heiko Stübner
2012-03-30  9:35       ` Mark Brown
2011-12-21  7:29 ` Kukjin Kim

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