From patchwork Thu Jan 24 06:27:55 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Pitre X-Patchwork-Id: 2029341 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id CE0EE3FD56 for ; Thu, 24 Jan 2013 06:35:52 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TyGN3-0007HN-Ae; Thu, 24 Jan 2013 06:33:09 +0000 Received: from relais.videotron.ca ([24.201.245.36]) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TyGIa-0003pw-Sh for linux-arm-kernel@lists.infradead.org; Thu, 24 Jan 2013 06:28:34 +0000 Received: from yoda.home ([24.202.213.203]) by VL-VM-MR002.ip.videotron.ca (Oracle Communications Messaging Exchange Server 7u4-22.01 64bit (built Apr 21 2011)) with ESMTP id <0MH400JZX9YSTA80@VL-VM-MR002.ip.videotron.ca> for linux-arm-kernel@lists.infradead.org; Thu, 24 Jan 2013 01:28:05 -0500 (EST) Received: from xanadu.home (xanadu.home [192.168.2.2]) by yoda.home (Postfix) with ESMTP id E09412DA0217 for ; Thu, 24 Jan 2013 01:28:04 -0500 (EST) From: Nicolas Pitre To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v2 12/16] ARM: vexpress/dcscb: do not hardcode number of CPUs per cluster Date: Thu, 24 Jan 2013 01:27:55 -0500 Message-id: <1359008879-9015-13-git-send-email-nicolas.pitre@linaro.org> X-Mailer: git-send-email 1.8.0 In-reply-to: <1359008879-9015-1-git-send-email-nicolas.pitre@linaro.org> References: <1359008879-9015-1-git-send-email-nicolas.pitre@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130124_012833_044876_19DB03FF X-CRM114-Status: GOOD ( 12.72 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [24.201.245.36 listed in list.dnswl.org] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org If 4 CPUs are assumed, the A15x1-A7x1 model configuration would never shut down the initial cluster as the 0xf reset bit mask will never be observed. Let's construct this mask based on the provided information in the DCSCB config register for the number of CPUs per cluster. Signed-off-by: Nicolas Pitre --- arch/arm/mach-vexpress/dcscb.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-vexpress/dcscb.c b/arch/arm/mach-vexpress/dcscb.c index cde9d3a8d2..e61ccce3c5 100644 --- a/arch/arm/mach-vexpress/dcscb.c +++ b/arch/arm/mach-vexpress/dcscb.c @@ -46,10 +46,12 @@ static arch_spinlock_t dcscb_lock = __ARCH_SPIN_LOCK_UNLOCKED; static void __iomem *dcscb_base; static int dcscb_use_count[4][2]; +static int dcscb_cluster_cpu_mask[2]; static int dcscb_power_up(unsigned int cpu, unsigned int cluster) { unsigned int rst_hold, cpumask = (1 << cpu); + unsigned int cluster_mask = dcscb_cluster_cpu_mask[cluster]; pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster); if (cpu >= 4 || cluster >= 2) @@ -68,7 +70,7 @@ static int dcscb_power_up(unsigned int cpu, unsigned int cluster) if (rst_hold & (1 << 8)) { /* remove cluster reset and add individual CPU's reset */ rst_hold &= ~(1 << 8); - rst_hold |= 0xf; + rst_hold |= cluster_mask; } rst_hold &= ~(cpumask | (cpumask << 4)); writel(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4); @@ -92,13 +94,14 @@ static int dcscb_power_up(unsigned int cpu, unsigned int cluster) static void dcscb_power_down(void) { - unsigned int mpidr, cpu, cluster, rst_hold, cpumask; + unsigned int mpidr, cpu, cluster, rst_hold, cpumask, cluster_mask; bool last_man = false, skip_wfi = false; mpidr = read_cpuid_mpidr(); cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); cpumask = (1 << cpu); + cluster_mask = dcscb_cluster_cpu_mask[cluster]; pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster); BUG_ON(cpu >= 4 || cluster >= 2); @@ -108,7 +111,7 @@ static void dcscb_power_down(void) if (dcscb_use_count[cpu][cluster] == 0) { rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4); rst_hold |= cpumask; - if (((rst_hold | (rst_hold >> 4)) & 0xf) == 0xf) { + if (((rst_hold | (rst_hold >> 4)) & cluster_mask) == cluster_mask) { rst_hold |= (1 << 8); last_man = true; } @@ -178,12 +181,15 @@ static void __init dcscb_usage_count_init(void) static int __init dcscb_init(void) { + unsigned int cfg; int ret; dcscb_base = ioremap(DCSCB_PHYS_BASE, 0x1000); if (!dcscb_base) return -ENOMEM; - + cfg = readl_relaxed(dcscb_base + DCS_CFG_R); + dcscb_cluster_cpu_mask[0] = (1 << (((cfg >> 16) >> (0 << 2)) & 0xf)) - 1; + dcscb_cluster_cpu_mask[1] = (1 << (((cfg >> 16) >> (1 << 2)) & 0xf)) - 1; dcscb_usage_count_init(); ret = bL_platform_power_register(&dcscb_power_ops);