From patchwork Thu Aug 15 17:09:39 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep KarkadaNagesha X-Patchwork-Id: 2845234 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 139C69F239 for ; Thu, 15 Aug 2013 17:11:12 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C97B32035C for ; Thu, 15 Aug 2013 17:11:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6B99520377 for ; Thu, 15 Aug 2013 17:11:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759453Ab3HORKI (ORCPT ); Thu, 15 Aug 2013 13:10:08 -0400 Received: from service87.mimecast.com ([91.220.42.44]:47501 "EHLO service87.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759251Ab3HORKE (ORCPT ); Thu, 15 Aug 2013 13:10:04 -0400 Received: from cam-owa2.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Thu, 15 Aug 2013 18:10:02 +0100 Received: from e103737-lin.cambridge.arm.com ([10.1.255.212]) by cam-owa2.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Thu, 15 Aug 2013 18:10:01 +0100 From: Sudeep KarkadaNagesha To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, microblaze-uclinux@itee.uq.edu.au, linux@lists.openrisc.net, linuxppc-dev@lists.ozlabs.org Cc: Sudeep.KarkadaNagesha@arm.com, Benjamin Herrenschmidt , Jonas Bonn , Michal Simek , "Rafael J. Wysocki" , Grant Likely , Rob Herring , Sudeep KarkadaNagesha Subject: [RFC PATCH 3/4] powerpc: refactor of_get_cpu_node to support other architectures Date: Thu, 15 Aug 2013 18:09:39 +0100 Message-Id: <1376586580-5409-4-git-send-email-Sudeep.KarkadaNagesha@arm.com> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: <1376586580-5409-1-git-send-email-Sudeep.KarkadaNagesha@arm.com> References: <1374492747-13879-1-git-send-email-Sudeep.KarkadaNagesha@arm.com> <1376586580-5409-1-git-send-email-Sudeep.KarkadaNagesha@arm.com> X-OriginalArrivalTime: 15 Aug 2013 17:10:01.0267 (UTC) FILETIME=[46F47830:01CE99DA] X-MC-Unique: 113081518100200501 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Spam-Status: No, score=-9.7 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Sudeep KarkadaNagesha Currently different drivers requiring to access cpu device node are parsing the device tree themselves. Since the ordering in the DT need not match the logical cpu ordering, the parsing logic needs to consider that. However, this has resulted in lots of code duplication and in some cases even incorrect logic. It's better to consolidate them by adding support for getting cpu device node for a given logical cpu index in DT core library. However logical to physical index mapping can be architecture specific. PowerPC has it's own implementation to get the cpu node for a given logical index. This patch refactors the current implementation of of_get_cpu_node. This in preparation to move the implementation to DT core library. It separates out the logical to physical mapping so that a default matching of the physical id to the logical cpu index can be added when moved to common code. Architecture specific code can override it. Cc: Rob Herring Cc: Grant Likely Cc: Benjamin Herrenschmidt Signed-off-by: Sudeep KarkadaNagesha --- arch/powerpc/kernel/prom.c | 70 ++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index eb23ac9..594c9f9 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -865,45 +865,61 @@ static int __init prom_reconfig_setup(void) __initcall(prom_reconfig_setup); #endif +bool arch_match_cpu_phys_id(int cpu, u64 phys_id) +{ + return (int)phys_id == get_hard_smp_processor_id(cpu); +} + +static bool __of_find_n_match_cpu_property(struct device_node *cpun, + const char *prop_name, int cpu, unsigned int *thread) +{ + const __be32 *cell; + int ac, prop_len, tid; + u64 hwid; + + ac = of_n_addr_cells(cpun); + cell = of_get_property(cpun, prop_name, &prop_len); + if (!cell) + return false; + prop_len /= sizeof(*cell); + for (tid = 0; tid < prop_len; tid++) { + hwid = of_read_number(cell, ac); + if (arch_match_cpu_phys_id(cpu, hwid)) { + if (thread) + *thread = tid; + return true; + } + } + return false; +} + /* Find the device node for a given logical cpu number, also returns the cpu * local thread number (index in ibm,interrupt-server#s) if relevant and * asked for (non NULL) */ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) { - int hardid; - struct device_node *np; + struct device_node *cpun, *cpus; - hardid = get_hard_smp_processor_id(cpu); + cpus = of_find_node_by_path("/cpus"); + if (!cpus) { + pr_warn("Missing cpus node, bailing out\n"); + return NULL; + } - for_each_node_by_type(np, "cpu") { - const u32 *intserv; - unsigned int plen, t; + for_each_child_of_node(cpus, cpun) { + if (of_node_cmp(cpun->type, "cpu")) + continue; /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist * fallback to "reg" property and assume no threads */ - intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", - &plen); - if (intserv == NULL) { - const u32 *reg = of_get_property(np, "reg", NULL); - if (reg == NULL) - continue; - if (*reg == hardid) { - if (thread) - *thread = 0; - return np; - } - } else { - plen /= sizeof(u32); - for (t = 0; t < plen; t++) { - if (hardid == intserv[t]) { - if (thread) - *thread = t; - return np; - } - } - } + if (__of_find_n_match_cpu_property(cpun, + "ibm,ppc-interrupt-server#s", cpu, thread)) + return cpun; + + if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread)) + return cpun; } return NULL; }