From patchwork Wed Apr 10 14:22:09 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 2421801 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) by patchwork1.kernel.org (Postfix) with ESMTP id 4504B3FD8C for ; Wed, 10 Apr 2013 14:25:35 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UPvwe-0000MO-GN; Wed, 10 Apr 2013 14:24:18 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UPvw3-0006XH-20; Wed, 10 Apr 2013 14:23:39 +0000 Received: from mail-we0-x22e.google.com ([2a00:1450:400c:c03::22e]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UPvv9-0006Kr-5e for linux-arm-kernel@lists.infradead.org; Wed, 10 Apr 2013 14:22:46 +0000 Received: by mail-we0-f174.google.com with SMTP id u12so411231wey.5 for ; Wed, 10 Apr 2013 07:22:40 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:x-gm-message-state; bh=HQfKJ6tNVo50GnmvgYI77weeW7Uyrhb/xY9ux+3NcLA=; b=AFei/G89J7wfyXB7gCHtd8nqoa10oKTdiyXUmMP28Btyo3n1rljQzn2CxujmY7tOtW iQ+aLurI6g26DsiaPtGWxm1nlkU7ogJ3JSWXzsHARrOz/zvM1DYYQIMyhbFn6Ha0YNR8 w3aNuNInqwfJl4jf739DO4GmhpHnb81HgVErE1CVhq4tUi6ZTNRsUU+fSKigeUQ2vNCo GcdMix8Mb5C32nVPqiXknAR++LD9W5t/U46ZwTmGOXADuF/wLB1Byo0kyD0OfePK/ieX 6C3sn8D97yyWGxer3FUHFmopgPnUQwDAgGBxJs/M2gWKP6qTFrffqdwY31Ondd4ROxDU ju4A== X-Received: by 10.180.77.10 with SMTP id o10mr27279613wiw.10.1365603760853; Wed, 10 Apr 2013 07:22:40 -0700 (PDT) Received: from mai.home (AToulouse-654-1-413-119.w82-125.abo.wanadoo.fr. [82.125.160.119]) by mx.google.com with ESMTPS id dp5sm32126938wib.1.2013.04.10.07.22.37 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 10 Apr 2013 07:22:39 -0700 (PDT) From: Daniel Lezcano To: rjw@sisk.pl Subject: [PATCH 04/18] ARM: imx: cpuidle: create separate drivers for imx5/imx6 Date: Wed, 10 Apr 2013 16:22:09 +0200 Message-Id: <1365603743-5618-5-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1365603743-5618-1-git-send-email-daniel.lezcano@linaro.org> References: <1365603743-5618-1-git-send-email-daniel.lezcano@linaro.org> X-Gm-Message-State: ALoCoQmkToo+SYOwv+mtWjOifbsHybaJGmq6ozEhTOZzAlZ5KUidsykewT4CtXoxYE0QGsVWvqGz X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130410_102243_506874_1D88D0A2 X-CRM114-Status: GOOD ( 26.92 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- 1.7 KHOP_BIG_TO_CC Sent to 10+ recipients instaed of Bcc or a list -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: andrew@lunn.ch, khilman@deeprootsystems.com, linus.walleij@linaro.org, nsekhar@ti.com, josephl@nvidia.com, kgene.kim@samsung.com, patches@linaro.org, magnus.damm@gmail.com, tony@atomide.com, plagnioj@jcrosoft.com, linaro-kernel@lists.linaro.org, jason@lakedaemon.net, swarren@wwwdotorg.org, nicolas.ferre@atmel.com, rob.herring@calxeda.com, horms@verge.net.au, linux@maxim.org.za, linux-arm-kernel@lists.infradead.org, deepthi@linux.vnet.ibm.com, jkosina@suse.cz, linux-pm@vger.kernel.org, lethal@linux-sh.org, santosh.shilimkar@ti.com, kernel@pengutronix.de X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The code intializes the cpuidle driver at different places. The cpuidle driver for : * imx5 : is in the pm-imx5.c, the init function is in cpuidle.c * imx6 : is in cpuidle-imx6q.c, the init function is in cpuidle.c and cpuidle-imx6q.c Instead of having the cpuidle code spread across different files, let's write a driver for each SoC and make the code similar. That implies some code duplication but that will be fixed with the next patches which consolidate the initialization for all the drivers. Signed-off-by: Daniel Lezcano --- arch/arm/mach-imx/Makefile | 1 + arch/arm/mach-imx/cpuidle-imx5.c | 74 ++++++++++++++++++++++++++++++++++ arch/arm/mach-imx/cpuidle-imx6q.c | 36 ++++++++++++++++- arch/arm/mach-imx/cpuidle.c | 80 ------------------------------------- arch/arm/mach-imx/cpuidle.h | 10 ++--- arch/arm/mach-imx/pm-imx5.c | 29 +------------- 6 files changed, 115 insertions(+), 115 deletions(-) create mode 100644 arch/arm/mach-imx/cpuidle-imx5.c delete mode 100644 arch/arm/mach-imx/cpuidle.c diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index c4ce090..bfd5f5b 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o ifeq ($(CONFIG_CPU_IDLE),y) obj-y += cpuidle.o +obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o endif diff --git a/arch/arm/mach-imx/cpuidle-imx5.c b/arch/arm/mach-imx/cpuidle-imx5.c new file mode 100644 index 0000000..3d9f0c9 --- /dev/null +++ b/arch/arm/mach-imx/cpuidle-imx5.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2012 Freescale Semiconductor, Inc. + * + * 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 +#include +#include +#include + +#include "hardware.h" + +static DEFINE_PER_CPU(struct cpuidle_device, devices); + +static int imx5_cpuidle_enter(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + arm_pm_idle(); + return index; +} + +static struct cpuidle_driver imx5_cpuidle_driver = { + .name = "imx5_cpuidle", + .owner = THIS_MODULE, + .states[0] = { + .enter = imx5_cpuidle_enter, + .exit_latency = 2, + .target_residency = 1, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "IMX5 SRPG", + .desc = "CPU state retained,powered off", + }, + .state_count = 1, +}; + +int __init imx5_cpuidle_init(void) +{ + struct cpuidle_device *dev; + int cpu, ret; + + ret = cpuidle_register_driver(&imx5_cpuidle_driver); + if (ret) { + pr_err("%s: Failed to register cpuidle driver with error: %d\n", + __func__, ret); + return ret; + } + + /* initialize state data for each cpuidle_device */ + for_each_possible_cpu(cpu) { + dev = &per_cpu(devices, cpu); + dev->cpu = cpu; + + ret = cpuidle_register_device(dev); + if (ret) { + pr_err("%s: Failed to register cpu %u, error: %d\n", + __func__, cpu, ret); + goto out_unregister; + } + } + + return 0; + +out_unregister: + for_each_possible_cpu(cpu) { + dev = &per_cpu(devices, cpu); + cpuidle_unregister_device(dev); + } + + cpuidle_unregister_driver(&imx5_cpuidle_driver); + return ret; +} diff --git a/arch/arm/mach-imx/cpuidle-imx6q.c b/arch/arm/mach-imx/cpuidle-imx6q.c index e2739ad..c066b74faa 100644 --- a/arch/arm/mach-imx/cpuidle-imx6q.c +++ b/arch/arm/mach-imx/cpuidle-imx6q.c @@ -14,6 +14,8 @@ #include "common.h" #include "cpuidle.h" +static DEFINE_PER_CPU(struct cpuidle_device, devices); + static atomic_t master = ATOMIC_INIT(0); static DEFINE_SPINLOCK(master_lock); @@ -65,11 +67,43 @@ static struct cpuidle_driver imx6q_cpuidle_driver = { int __init imx6q_cpuidle_init(void) { + struct cpuidle_device *dev; + int cpu, ret; + /* Need to enable SCU standby for entering WAIT modes */ imx_scu_standby_enable(); /* Set chicken bit to get a reliable WAIT mode support */ imx6q_set_chicken_bit(); - return imx_cpuidle_init(&imx6q_cpuidle_driver); + ret = cpuidle_register_driver(&imx6q_cpuidle_driver); + if (ret) { + pr_err("%s: Failed to register cpuidle driver with error: %d\n", + __func__, ret); + return ret; + } + + /* initialize state data for each cpuidle_device */ + for_each_possible_cpu(cpu) { + dev = &per_cpu(devices, cpu); + dev->cpu = cpu; + + ret = cpuidle_register_device(dev); + if (ret) { + pr_err("%s: Failed to register cpu %u, error: %d\n", + __func__, cpu, ret); + goto out_unregister; + } + } + + return 0; + +out_unregister: + for_each_possible_cpu(cpu) { + dev = &per_cpu(devices, cpu); + cpuidle_unregister_device(dev); + } + + cpuidle_unregister_driver(&imx6q_cpuidle_driver); + return ret; } diff --git a/arch/arm/mach-imx/cpuidle.c b/arch/arm/mach-imx/cpuidle.c deleted file mode 100644 index d4cb511..0000000 --- a/arch/arm/mach-imx/cpuidle.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2012 Freescale Semiconductor, Inc. - * Copyright 2012 Linaro Ltd. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include -#include -#include -#include -#include -#include - -static struct cpuidle_device __percpu * imx_cpuidle_devices; - -static void __init imx_cpuidle_devices_uninit(void) -{ - int cpu_id; - struct cpuidle_device *dev; - - for_each_possible_cpu(cpu_id) { - dev = per_cpu_ptr(imx_cpuidle_devices, cpu_id); - cpuidle_unregister_device(dev); - } - - free_percpu(imx_cpuidle_devices); -} - -int __init imx_cpuidle_init(struct cpuidle_driver *drv) -{ - struct cpuidle_device *dev; - int cpu_id, ret; - - if (drv->state_count > CPUIDLE_STATE_MAX) { - pr_err("%s: state_count exceeds maximum\n", __func__); - return -EINVAL; - } - - ret = cpuidle_register_driver(drv); - if (ret) { - pr_err("%s: Failed to register cpuidle driver with error: %d\n", - __func__, ret); - return ret; - } - - imx_cpuidle_devices = alloc_percpu(struct cpuidle_device); - if (imx_cpuidle_devices == NULL) { - ret = -ENOMEM; - goto unregister_drv; - } - - /* initialize state data for each cpuidle_device */ - for_each_possible_cpu(cpu_id) { - dev = per_cpu_ptr(imx_cpuidle_devices, cpu_id); - dev->cpu = cpu_id; - dev->state_count = drv->state_count; - - ret = cpuidle_register_device(dev); - if (ret) { - pr_err("%s: Failed to register cpu %u, error: %d\n", - __func__, cpu_id, ret); - goto uninit; - } - } - - return 0; - -uninit: - imx_cpuidle_devices_uninit(); - -unregister_drv: - cpuidle_unregister_driver(drv); - return ret; -} diff --git a/arch/arm/mach-imx/cpuidle.h b/arch/arm/mach-imx/cpuidle.h index e092d13..786f98e 100644 --- a/arch/arm/mach-imx/cpuidle.h +++ b/arch/arm/mach-imx/cpuidle.h @@ -10,18 +10,16 @@ * http://www.gnu.org/copyleft/gpl.html */ -#include - #ifdef CONFIG_CPU_IDLE -extern int imx_cpuidle_init(struct cpuidle_driver *drv); +extern int imx5_cpuidle_init(void); extern int imx6q_cpuidle_init(void); #else -static inline int imx_cpuidle_init(struct cpuidle_driver *drv) +static inline int imx5_cpuidle_init(void) { - return -ENODEV; + return 0; } static inline int imx6q_cpuidle_init(void) { - return -ENODEV; + return 0; } #endif diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c index 4b52b3e..82e79c6 100644 --- a/arch/arm/mach-imx/pm-imx5.c +++ b/arch/arm/mach-imx/pm-imx5.c @@ -149,32 +149,6 @@ static void imx5_pm_idle(void) imx5_cpu_do_idle(); } -static int imx5_cpuidle_enter(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int idx) -{ - int ret; - - ret = imx5_cpu_do_idle(); - if (ret < 0) - return ret; - - return idx; -} - -static struct cpuidle_driver imx5_cpuidle_driver = { - .name = "imx5_cpuidle", - .owner = THIS_MODULE, - .states[0] = { - .enter = imx5_cpuidle_enter, - .exit_latency = 2, - .target_residency = 1, - .flags = CPUIDLE_FLAG_TIME_VALID, - .name = "IMX5 SRPG", - .desc = "CPU state retained,powered off", - }, - .state_count = 1, -}; - static int __init imx5_pm_common_init(void) { int ret; @@ -192,8 +166,7 @@ static int __init imx5_pm_common_init(void) /* Set the registers to the default cpu idle state. */ mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE); - imx_cpuidle_init(&imx5_cpuidle_driver); - return 0; + return imx5_cpuidle_init(); } void __init imx51_pm_init(void)