| From 162cdee2033c61c65064d72592d471b96611f212 Mon Sep 17 00:00:00 2001 |
| From: Michal Simek <michal.simek@xilinx.com> |
| Date: Tue, 4 Jun 2013 07:17:39 +0000 |
| Subject: ARM: zynq: Add cpuidle support |
| |
| Add cpuidle support for Xilinx Zynq. |
| |
| Signed-off-by: Michal Simek <michal.simek@xilinx.com> |
| Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org> |
| Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| (cherry picked from commit bd2a337a25dd22bcd6b3fb1f99461f6991773e68) |
| Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp> |
| Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp> |
| --- |
| MAINTAINERS | 1 |
| drivers/cpuidle/Kconfig | 6 ++ |
| drivers/cpuidle/Makefile | 1 |
| drivers/cpuidle/cpuidle-zynq.c | 83 +++++++++++++++++++++++++++++++++++++++++ |
| 4 files changed, 91 insertions(+) |
| create mode 100644 drivers/cpuidle/cpuidle-zynq.c |
| |
| --- a/MAINTAINERS |
| +++ b/MAINTAINERS |
| @@ -1310,6 +1310,7 @@ W: http://wiki.xilinx.com |
| T: git git://git.xilinx.com/linux-xlnx.git |
| S: Supported |
| F: arch/arm/mach-zynq/ |
| +F: drivers/cpuidle/cpuidle-zynq.c |
| |
| ARM64 PORT (AARCH64 ARCHITECTURE) |
| M: Catalin Marinas <catalin.marinas@arm.com> |
| --- a/drivers/cpuidle/Kconfig |
| +++ b/drivers/cpuidle/Kconfig |
| @@ -39,4 +39,10 @@ config CPU_IDLE_CALXEDA |
| help |
| Select this to enable cpuidle on Calxeda processors. |
| |
| +config CPU_IDLE_ZYNQ |
| + bool "CPU Idle Driver for Xilinx Zynq processors" |
| + depends on ARCH_ZYNQ |
| + help |
| + Select this to enable cpuidle on Xilinx Zynq processors. |
| + |
| endif |
| --- a/drivers/cpuidle/Makefile |
| +++ b/drivers/cpuidle/Makefile |
| @@ -7,3 +7,4 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED |
| |
| obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o |
| obj-$(CONFIG_ARCH_KIRKWOOD) += cpuidle-kirkwood.o |
| +obj-$(CONFIG_CPU_IDLE_ZYNQ) += cpuidle-zynq.o |
| --- /dev/null |
| +++ b/drivers/cpuidle/cpuidle-zynq.c |
| @@ -0,0 +1,83 @@ |
| +/* |
| + * Copyright (C) 2012-2013 Xilinx |
| + * |
| + * CPU idle support for Xilinx Zynq |
| + * |
| + * based on arch/arm/mach-at91/cpuidle.c |
| + * |
| + * This program is free software; you can redistribute it and/or modify it |
| + * under the terms and conditions of the GNU General Public License, |
| + * version 2, as published by the Free Software Foundation. |
| + * |
| + * This program is distributed in the hope 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. |
| + * |
| + * You should have received a copy of the GNU General Public License along with |
| + * this program. If not, see <http://www.gnu.org/licenses/>. |
| + * |
| + * The cpu idle uses wait-for-interrupt and RAM self refresh in order |
| + * to implement two idle states - |
| + * #1 wait-for-interrupt |
| + * #2 wait-for-interrupt and RAM self refresh |
| + * |
| + * Maintainer: Michal Simek <michal.simek@xilinx.com> |
| + */ |
| + |
| +#include <linux/init.h> |
| +#include <linux/cpu_pm.h> |
| +#include <linux/cpuidle.h> |
| +#include <linux/of.h> |
| +#include <asm/proc-fns.h> |
| +#include <asm/cpuidle.h> |
| + |
| +#define ZYNQ_MAX_STATES 2 |
| + |
| +/* Actual code that puts the SoC in different idle states */ |
| +static int zynq_enter_idle(struct cpuidle_device *dev, |
| + struct cpuidle_driver *drv, int index) |
| +{ |
| + /* Devices must be stopped here */ |
| + cpu_pm_enter(); |
| + |
| + /* Add code for DDR self refresh start */ |
| + cpu_do_idle(); |
| + |
| + /* Add code for DDR self refresh stop */ |
| + cpu_pm_exit(); |
| + |
| + return index; |
| +} |
| + |
| +static struct cpuidle_driver zynq_idle_driver = { |
| + .name = "zynq_idle", |
| + .owner = THIS_MODULE, |
| + .states = { |
| + ARM_CPUIDLE_WFI_STATE, |
| + { |
| + .enter = zynq_enter_idle, |
| + .exit_latency = 10, |
| + .target_residency = 10000, |
| + .flags = CPUIDLE_FLAG_TIME_VALID | |
| + CPUIDLE_FLAG_TIMER_STOP, |
| + .name = "RAM_SR", |
| + .desc = "WFI and RAM Self Refresh", |
| + }, |
| + }, |
| + .safe_state_index = 0, |
| + .state_count = ZYNQ_MAX_STATES, |
| +}; |
| + |
| +/* Initialize CPU idle by registering the idle states */ |
| +static int __init zynq_cpuidle_init(void) |
| +{ |
| + if (!of_machine_is_compatible("xlnx,zynq-7000")) |
| + return -ENODEV; |
| + |
| + pr_info("Xilinx Zynq CpuIdle Driver started\n"); |
| + |
| + return cpuidle_register(&zynq_idle_driver, NULL); |
| +} |
| + |
| +device_initcall(zynq_cpuidle_init); |