Message ID | 1327594923-21822-4-git-send-email-pdeschrijver@nvidia.com |
---|---|
State | Accepted, archived |
Headers | show |
On Thu, Jan 26, 2012 at 06:22:03PM +0200, Peter De Schrijver wrote:
> CPUidle driver for tegra. In this version only LP3 (clockgating) is supported.
Are you aware of the work Rob Lee is doing on providing a common library
for the ARM generic bits of cpuidle? I really must convert the s3c64xx
work I did on that over some time...
--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Jan 26, 2012 at 21:52:03, Peter De Schrijver wrote: [...] > +static int tegra_idle_enter_lp3(struct cpuidle_device *dev, > + struct cpuidle_driver *drv, int index) > +{ > + ktime_t enter, exit; > + s64 us; > + > + local_irq_disable(); > + local_fiq_disable(); > + > + enter = ktime_get(); > + > + tegra_cpu_wfi(); > + > + exit = ktime_sub(ktime_get(), enter); > + us = ktime_to_us(exit); > + > + local_fiq_enable(); > + local_irq_enable(); > + > + dev->last_residency = us; > + > + return index; > +} You can probably drop local_irq_disable() and local_irq_enable(). -- To unsubscribe from this list: send the line "unsubscribe linux-tegra" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Jan 26, 2012 at 10:59 PM, Bedia, Vaibhav <vaibhav.bedia@ti.com> wrote: > On Thu, Jan 26, 2012 at 21:52:03, Peter De Schrijver wrote: > [...] >> +static int tegra_idle_enter_lp3(struct cpuidle_device *dev, >> + struct cpuidle_driver *drv, int index) >> +{ >> + ktime_t enter, exit; >> + s64 us; >> + >> + local_irq_disable(); >> + local_fiq_disable(); >> + >> + enter = ktime_get(); >> + >> + tegra_cpu_wfi(); >> + >> + exit = ktime_sub(ktime_get(), enter); >> + us = ktime_to_us(exit); >> + >> + local_fiq_enable(); >> + local_irq_enable(); >> + >> + dev->last_residency = us; >> + >> + return index; >> +} > > You can probably drop local_irq_disable() and local_irq_enable(). local_irq_enable() is required by the cpuidle call semantics. See arch/arm/process.c, it has a WARN_ON(irqs_disabled()) after the idle function call. The local_irq_disable() can and probably should be dropped, although a comment that the function is called with interrupts off and is expected to return with interrupts on would be helpful. -- To unsubscribe from this list: send the line "unsubscribe linux-tegra" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Fri, Jan 27, 2012 at 12:40:58, Colin Cross wrote: > local_irq_enable() is required by the cpuidle call semantics. See > arch/arm/process.c, it has a WARN_ON(irqs_disabled()) after the > idle function call. The local_irq_disable() can and probably should > be dropped, although a comment that the function is called with > interrupts off and is expected to return with interrupts on would be > helpful. > Ah... I was too fixated on local_irq_disable() and local_irq_enable() in cpu_idle(). Thanks for clarifying. -- To unsubscribe from this list: send the line "unsubscribe linux-tegra" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Fri, Jan 27, 2012 at 00:41:34, Mark Brown wrote: > On Thu, Jan 26, 2012 at 06:22:03PM +0200, Peter De Schrijver wrote: > > CPUidle driver for tegra. In this version only LP3 (clockgating) is supported. > > Are you aware of the work Rob Lee is doing on providing a common library > for the ARM generic bits of cpuidle? I really must convert the s3c64xx > work I did on that over some time... Slightly off-topic.. This is probably a bit early to ask but when it that likely to get merged? I am working on cpuidle for AM33xx and if Rob's cpuidle consolidation is getting merged soon I will try to use them in my baseline. -- To unsubscribe from this list: send the line "unsubscribe linux-tegra" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Jan 26, 2012 at 06:22:03PM +0200, Peter De Schrijver wrote: > CPUidle driver for tegra. In this version only LP3 (clockgating) is supported. > > Based on work by: > > Colin Cross <ccross@android.com> > Gary King <gking@nvidia.com> > > Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com> > --- > arch/arm/mach-tegra/Makefile | 2 + > arch/arm/mach-tegra/cpuidle.c | 107 +++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 109 insertions(+), 0 deletions(-) > create mode 100644 arch/arm/mach-tegra/cpuidle.c > > diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile > index b78bda8..c06c280 100644 > --- a/arch/arm/mach-tegra/Makefile > +++ b/arch/arm/mach-tegra/Makefile > @@ -6,6 +6,8 @@ obj-y += irq.o > obj-y += clock.o > obj-y += timer.o > obj-y += fuse.o > +obj-y += cpuidle.o > +obj-y += sleep.o Nit: Not much use in building this if CONFIG_CPU_IDLE is off. Feel free to fix that up in a new patch. -Olof -- To unsubscribe from this list: send the line "unsubscribe linux-tegra" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index b78bda8..c06c280 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -6,6 +6,8 @@ obj-y += irq.o obj-y += clock.o obj-y += timer.o obj-y += fuse.o +obj-y += cpuidle.o +obj-y += sleep.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += powergate.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c new file mode 100644 index 0000000..d83a8c0 --- /dev/null +++ b/arch/arm/mach-tegra/cpuidle.c @@ -0,0 +1,107 @@ +/* + * arch/arm/mach-tegra/cpuidle.c + * + * CPU idle driver for Tegra CPUs + * + * Copyright (c) 2010-2012, NVIDIA Corporation. + * Copyright (c) 2011 Google, Inc. + * Author: Colin Cross <ccross@android.com> + * Gary King <gking@nvidia.com> + * + * Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/cpu.h> +#include <linux/cpuidle.h> +#include <linux/hrtimer.h> + +#include <mach/iomap.h> + +extern void tegra_cpu_wfi(void); + +static int tegra_idle_enter_lp3(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index); + +struct cpuidle_driver tegra_idle_driver = { + .name = "tegra_idle", + .owner = THIS_MODULE, + .state_count = 1, + .states = { + [0] = { + .enter = tegra_idle_enter_lp3, + .exit_latency = 10, + .target_residency = 10, + .power_usage = 600, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "LP3", + .desc = "CPU flow-controlled", + }, + }, +}; + +static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device); + +static int tegra_idle_enter_lp3(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + ktime_t enter, exit; + s64 us; + + local_irq_disable(); + local_fiq_disable(); + + enter = ktime_get(); + + tegra_cpu_wfi(); + + exit = ktime_sub(ktime_get(), enter); + us = ktime_to_us(exit); + + local_fiq_enable(); + local_irq_enable(); + + dev->last_residency = us; + + return index; +} + +static int __init tegra_cpuidle_init(void) +{ + int ret; + unsigned int cpu; + struct cpuidle_device *dev; + struct cpuidle_driver *drv = &tegra_idle_driver; + + ret = cpuidle_register_driver(&tegra_idle_driver); + if (ret) { + pr_err("CPUidle driver registration failed\n"); + return ret; + } + + for_each_possible_cpu(cpu) { + dev = &per_cpu(tegra_idle_device, cpu); + dev->cpu = cpu; + + dev->state_count = drv->state_count; + ret = cpuidle_register_device(dev); + if (ret) { + pr_err("CPU%u: CPUidle device registration failed\n", + cpu); + return ret; + } + } + return 0; +} +device_initcall(tegra_cpuidle_init);
CPUidle driver for tegra. In this version only LP3 (clockgating) is supported. Based on work by: Colin Cross <ccross@android.com> Gary King <gking@nvidia.com> Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com> --- arch/arm/mach-tegra/Makefile | 2 + arch/arm/mach-tegra/cpuidle.c | 107 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-tegra/cpuidle.c