From patchwork Thu Jun 16 10:27:36 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 9180429 X-Patchwork-Delegate: horms@verge.net.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BBCA36088F for ; Thu, 16 Jun 2016 10:27:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AC12D27BFF for ; Thu, 16 Jun 2016 10:27:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A0FF0282EE; Thu, 16 Jun 2016 10:27:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5911E27DF9 for ; Thu, 16 Jun 2016 10:27:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753779AbcFPK1x (ORCPT ); Thu, 16 Jun 2016 06:27:53 -0400 Received: from baptiste.telenet-ops.be ([195.130.132.51]:34147 "EHLO baptiste.telenet-ops.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752568AbcFPK1t (ORCPT ); Thu, 16 Jun 2016 06:27:49 -0400 Received: from ayla.of.borg ([84.195.107.21]) by baptiste.telenet-ops.be with bizsmtp id 7NTm1t0050TjorY01NTmzd; Thu, 16 Jun 2016 12:27:48 +0200 Received: from ramsan.of.borg ([192.168.97.29] helo=ramsan) by ayla.of.borg with esmtp (Exim 4.82) (envelope-from ) id 1bDUWY-0003b9-68; Thu, 16 Jun 2016 12:27:46 +0200 Received: from geert by ramsan with local (Exim 4.82) (envelope-from ) id 1bDUWY-0007JQ-Dm; Thu, 16 Jun 2016 12:27:46 +0200 From: Geert Uytterhoeven To: Simon Horman , Magnus Damm Cc: Mark Rutland , Lorenzo Pieralisi , Keita Kobayashi , Laurent Pinchart , Sergei Shtylyov , linux-renesas-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Magnus Damm , Geert Uytterhoeven Subject: [PATCH v4 07/13] ARM: shmobile: apmu: Add APMU DT support via Enable method Date: Thu, 16 Jun 2016 12:27:36 +0200 Message-Id: <1466072862-28030-8-git-send-email-geert+renesas@glider.be> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1466072862-28030-1-git-send-email-geert+renesas@glider.be> References: <1466072862-28030-1-git-send-email-geert+renesas@glider.be> Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Magnus Damm Allow DT configuration of the APMU hardware in the case when the APMU is pointed out in the DTB via the enable-method. The ability to configure the APMU via C code is still kept intact to prevent DTB breakage for older SoCs that do not rely on the enable-method for SMP support. Signed-off-by: Magnus Damm [geert: Fix CONFIG_SMP=n build] Signed-off-by: Geert Uytterhoeven --- v4: - Remove bogus of_node_put(), - Fix CONFIG_SMP=n build, - Correct whitespace, v3: - Move is_allowed declaration, break when allowed, v2: - Adjust to use .cpu_can_disable instead of .cpu_disable. --- arch/arm/mach-shmobile/platsmp-apmu.c | 92 +++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c index c1558ef0c590dd3e..0c6bb458b7a45128 100644 --- a/arch/arm/mach-shmobile/platsmp-apmu.c +++ b/arch/arm/mach-shmobile/platsmp-apmu.c @@ -24,6 +24,7 @@ #include #include "common.h" #include "platsmp-apmu.h" +#include "rcar-gen2.h" static struct { void __iomem *iomem; @@ -118,14 +119,66 @@ static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit), } } -void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus, - struct rcar_apmu_config *apmu_config, - int num) +static const struct of_device_id apmu_ids[] = { + { .compatible = "renesas,apmu" }, + { /*sentinel*/ } +}; + +static void apmu_parse_dt(void (*fn)(struct resource *res, int cpu, int bit)) +{ + struct device_node *np_apmu, *np_cpu; + struct resource res; + int bit, index; + u32 id; + + for_each_matching_node(np_apmu, apmu_ids) { + /* only enable the cluster that includes the boot CPU */ + bool is_allowed = false; + + for (bit = 0; bit < CONFIG_NR_CPUS; bit++) { + np_cpu = of_parse_phandle(np_apmu, "cpus", bit); + if (np_cpu) { + if (!of_property_read_u32(np_cpu, "reg", &id)) { + if (id == cpu_logical_map(0)) { + is_allowed = true; + of_node_put(np_cpu); + break; + } + + } + of_node_put(np_cpu); + } + } + if (!is_allowed) + continue; + + for (bit = 0; bit < CONFIG_NR_CPUS; bit++) { + np_cpu = of_parse_phandle(np_apmu, "cpus", bit); + if (np_cpu) { + if (!of_property_read_u32(np_cpu, "reg", &id)) { + index = get_logical_index(id); + if ((index >= 0) && + !of_address_to_resource(np_apmu, + 0, &res)) + fn(&res, index, bit); + } + of_node_put(np_cpu); + } + } + } +} + +static void __init shmobile_smp_apmu_setup_boot(void) { /* install boot code shared by all CPUs */ shmobile_boot_fn = virt_to_phys(shmobile_smp_boot); +} - /* perform per-cpu setup */ +void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus, + struct rcar_apmu_config *apmu_config, + int num) +{ + shmobile_smp_apmu_setup_boot(); apmu_parse_cfg(apmu_init_cpu, apmu_config, num); } @@ -136,7 +189,38 @@ int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle) return apmu_wrap(cpu, apmu_power_on); } + +static void __init shmobile_smp_apmu_prepare_cpus_dt(unsigned int max_cpus) +{ + shmobile_smp_apmu_setup_boot(); + apmu_parse_dt(apmu_init_cpu); + rcar_gen2_pm_init(); +} + +static int shmobile_smp_apmu_boot_secondary_md21(unsigned int cpu, + struct task_struct *idle) +{ + /* Error out when hardware debug mode is enabled */ + if (rcar_gen2_read_mode_pins() & BIT(21)) { + pr_warn("Unable to boot CPU%u when MD21 is set\n", cpu); + return -ENOTSUPP; + } + + return shmobile_smp_apmu_boot_secondary(cpu, idle); +} + +static struct smp_operations apmu_smp_ops __initdata = { + .smp_prepare_cpus = shmobile_smp_apmu_prepare_cpus_dt, + .smp_boot_secondary = shmobile_smp_apmu_boot_secondary_md21, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_can_disable = shmobile_smp_cpu_can_disable, + .cpu_die = shmobile_smp_apmu_cpu_die, + .cpu_kill = shmobile_smp_apmu_cpu_kill, #endif +}; + +CPU_METHOD_OF_DECLARE(shmobile_smp_apmu, "renesas,apmu", &apmu_smp_ops); +#endif /* CONFIG_SMP */ #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_SUSPEND) /* nicked from arch/arm/mach-exynos/hotplug.c */