From patchwork Mon Apr 1 23:07:10 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Herring X-Patchwork-Id: 2373321 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 75DC43FD40 for ; Mon, 1 Apr 2013 23:10:54 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UMnp0-0004BD-CW; Mon, 01 Apr 2013 23:07:26 +0000 Received: from mail-qa0-f50.google.com ([209.85.216.50]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UMnow-0004Au-MA for linux-arm-kernel@lists.infradead.org; Mon, 01 Apr 2013 23:07:24 +0000 Received: by mail-qa0-f50.google.com with SMTP id bv4so1150243qab.16 for ; Mon, 01 Apr 2013 16:07:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer; bh=cyMCeQkpwzGK71fQigxXJmu9vAR4pFfW+iE9pIqJKHU=; b=bMCr3q5VQOsSRkZnYCzIE33ozYZZ+NEM+HhoO5p9GJB9TEdtBhOHC0+D6e64WyhYyL FfIUpiQIASjpo4/XniZfLl5/xUpL4Q+U1BNFxVO5ymVGrmgUwKDKXEoUi0Y3U3/V0SfD eSiqUYEeGZjQV7dE+4c699IOhKuG8MKPfmaZEr9RiT7YwfBvUPDWPGw444vW+D4ZjL4S o/+gzKF3cxcYT3cLAa48mlW/FZ1f7sLxdmdKHOX0qkvdO6JCyN2JhI5NYQh+npikXvvv rRhiBfHZ4sCy5WuVf2Qjz4XxkTReGyJ1xGXzeaKRWHqlgevRUm7/1QjiR28e6lZp/43T ndNA== X-Received: by 10.49.14.102 with SMTP id o6mr12191127qec.5.1364857641567; Mon, 01 Apr 2013 16:07:21 -0700 (PDT) Received: from rob-laptop.calxeda.com ([173.226.190.126]) by mx.google.com with ESMTPS id 10sm24658478qax.13.2013.04.01.16.07.19 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 01 Apr 2013 16:07:20 -0700 (PDT) From: Rob Herring To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v2] ARM: highbank: adapt to use ARM PSCI calls Date: Mon, 1 Apr 2013 18:07:10 -0500 Message-Id: <1364857630-8099-1-git-send-email-robherring2@gmail.com> X-Mailer: git-send-email 1.7.10.4 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130401_190722_821646_14544CF0 X-CRM114-Status: GOOD ( 24.45 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.216.50 listed in list.dnswl.org] 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (robherring2[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record 0.2 FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends in digit (robherring2[at]gmail.com) -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature Cc: arm@kernel.org, Will Deacon , Rob Herring , Stefano Stabellini 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 From: Rob Herring This adapts highbank to use the psci_smp_ops. Additionally, suspend/resume, reset and poweroff are all converted to use PSCI calls. Doing this removes direct access to the SCU and factors out the A9 vs. A15 differences. Signed-off-by: Rob Herring --- v2: Rebase to use Stefano's psci_smp_ops patch: http://lists.infradead.org/pipermail/linux-arm-kernel/2013-March/159187.html arch/arm/mach-highbank/Kconfig | 2 +- arch/arm/mach-highbank/Makefile | 4 +- arch/arm/mach-highbank/core.h | 7 ---- arch/arm/mach-highbank/highbank.c | 50 ++++--------------------- arch/arm/mach-highbank/hotplug.c | 40 -------------------- arch/arm/mach-highbank/platsmp.c | 75 ------------------------------------- arch/arm/mach-highbank/pm.c | 25 +++++-------- arch/arm/mach-highbank/sysregs.h | 67 ++++++--------------------------- arch/arm/mach-highbank/system.c | 32 ---------------- 9 files changed, 30 insertions(+), 272 deletions(-) delete mode 100644 arch/arm/mach-highbank/hotplug.c delete mode 100644 arch/arm/mach-highbank/platsmp.c delete mode 100644 arch/arm/mach-highbank/system.c diff --git a/arch/arm/mach-highbank/Kconfig b/arch/arm/mach-highbank/Kconfig index 44b12f9..9dc0c9e 100644 --- a/arch/arm/mach-highbank/Kconfig +++ b/arch/arm/mach-highbank/Kconfig @@ -5,13 +5,13 @@ config ARCH_HIGHBANK select ARCH_WANT_OPTIONAL_GPIOLIB select ARM_AMBA select ARM_GIC + select ARM_PSCI select ARM_TIMER_SP804 select CACHE_L2X0 select CLKDEV_LOOKUP select COMMON_CLK select CPU_V7 select GENERIC_CLOCKEVENTS - select HAVE_ARM_SCU select HAVE_SMP select MAILBOX select PL320_MBOX diff --git a/arch/arm/mach-highbank/Makefile b/arch/arm/mach-highbank/Makefile index 8a1ef57..aeabc32 100644 --- a/arch/arm/mach-highbank/Makefile +++ b/arch/arm/mach-highbank/Makefile @@ -1,8 +1,6 @@ -obj-y := highbank.o system.o smc.o +obj-y := highbank.o smc.o plus_sec := $(call as-instr,.arch_extension sec,+sec) AFLAGS_smc.o :=-Wa,-march=armv7-a$(plus_sec) -obj-$(CONFIG_SMP) += platsmp.o -obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o obj-$(CONFIG_PM_SLEEP) += pm.o diff --git a/arch/arm/mach-highbank/core.h b/arch/arm/mach-highbank/core.h index 3f65206..52b713a 100644 --- a/arch/arm/mach-highbank/core.h +++ b/arch/arm/mach-highbank/core.h @@ -1,10 +1,6 @@ #ifndef __HIGHBANK_CORE_H #define __HIGHBANK_CORE_H -extern void highbank_set_cpu_jump(int cpu, void *jump_addr); -extern void highbank_restart(char, const char *); -extern void __iomem *scu_base_addr; - #ifdef CONFIG_PM_SLEEP extern void highbank_pm_init(void); #else @@ -12,8 +8,5 @@ static inline void highbank_pm_init(void) {} #endif extern void highbank_smc1(int fn, int arg); -extern void highbank_cpu_die(unsigned int cpu); - -extern struct smp_operations highbank_smp_ops; #endif diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c index 3a5e62c..87efec6 100644 --- a/arch/arm/mach-highbank/highbank.c +++ b/arch/arm/mach-highbank/highbank.c @@ -26,9 +26,6 @@ #include #include -#include -#include -#include #include #include #include @@ -40,50 +37,15 @@ #include "sysregs.h" void __iomem *sregs_base; -void __iomem *scu_base_addr; - -static void __init highbank_scu_map_io(void) -{ - unsigned long base; - - /* Get SCU base */ - asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base)); - - scu_base_addr = ioremap(base, SZ_4K); -} - -#define HB_JUMP_TABLE_PHYS(cpu) (0x40 + (0x10 * (cpu))) -#define HB_JUMP_TABLE_VIRT(cpu) phys_to_virt(HB_JUMP_TABLE_PHYS(cpu)) - -void highbank_set_cpu_jump(int cpu, void *jump_addr) -{ - cpu = MPIDR_AFFINITY_LEVEL(cpu_logical_map(cpu), 0); - writel(virt_to_phys(jump_addr), HB_JUMP_TABLE_VIRT(cpu)); - __cpuc_flush_dcache_area(HB_JUMP_TABLE_VIRT(cpu), 16); - outer_clean_range(HB_JUMP_TABLE_PHYS(cpu), - HB_JUMP_TABLE_PHYS(cpu) + 15); -} - -#ifdef CONFIG_CACHE_L2X0 -static void highbank_l2x0_disable(void) -{ - /* Disable PL310 L2 Cache controller */ - highbank_smc1(0x102, 0x0); -} -#endif static void __init highbank_init_irq(void) { irqchip_init(); - if (of_find_compatible_node(NULL, NULL, "arm,cortex-a9")) - highbank_scu_map_io(); - #ifdef CONFIG_CACHE_L2X0 /* Enable PL310 L2 Cache controller */ highbank_smc1(0x102, 0x1); l2x0_of_init(0, ~0UL); - outer_cache.disable = highbank_l2x0_disable; #endif } @@ -123,10 +85,15 @@ static void __init highbank_timer_init(void) static void highbank_power_off(void) { - highbank_set_pwr_shutdown(); + highbank_cpu_off(HB_PWR_SHUTDOWN, 1); +} - while (1) - cpu_do_idle(); +static void highbank_restart(char mode, const char *cmd) +{ + if (mode == 'h') + highbank_cpu_off(HB_PWR_HARD_RESET, 1); + else + highbank_cpu_off(HB_PWR_SOFT_RESET, 1); } static int highbank_platform_notifier(struct notifier_block *nb, @@ -194,7 +161,6 @@ static const char *highbank_match[] __initconst = { }; DT_MACHINE_START(HIGHBANK, "Highbank") - .smp = smp_ops(highbank_smp_ops), .map_io = debug_ll_io_init, .init_irq = highbank_init_irq, .init_time = highbank_timer_init, diff --git a/arch/arm/mach-highbank/hotplug.c b/arch/arm/mach-highbank/hotplug.c deleted file mode 100644 index f30c528..0000000 --- a/arch/arm/mach-highbank/hotplug.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2011 Calxeda, Inc. - * - * 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 . - */ -#include - -#include - -#include "core.h" -#include "sysregs.h" - -extern void secondary_startup(void); - -/* - * platform-specific code to shutdown a CPU - * - */ -void __ref highbank_cpu_die(unsigned int cpu) -{ - flush_cache_all(); - - highbank_set_cpu_jump(cpu, phys_to_virt(0)); - highbank_set_core_pwr(); - - cpu_do_idle(); - - /* We should never return from idle */ - panic("highbank: cpu %d unexpectedly exit from shutdown\n", cpu); -} diff --git a/arch/arm/mach-highbank/platsmp.c b/arch/arm/mach-highbank/platsmp.c deleted file mode 100644 index 8797a70..0000000 --- a/arch/arm/mach-highbank/platsmp.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2010-2011 Calxeda, Inc. - * Based on platsmp.c, Copyright (C) 2002 ARM Ltd. - * - * 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 . - */ -#include -#include -#include -#include - -#include - -#include "core.h" - -extern void secondary_startup(void); - -static void __cpuinit highbank_secondary_init(unsigned int cpu) -{ - gic_secondary_init(0); -} - -static int __cpuinit highbank_boot_secondary(unsigned int cpu, struct task_struct *idle) -{ - highbank_set_cpu_jump(cpu, secondary_startup); - arch_send_wakeup_ipi_mask(cpumask_of(cpu)); - return 0; -} - -/* - * Initialise the CPU possible map early - this describes the CPUs - * which may be present or become present in the system. - */ -static void __init highbank_smp_init_cpus(void) -{ - unsigned int i, ncores = 4; - - /* sanity check */ - if (ncores > NR_CPUS) { - printk(KERN_WARNING - "highbank: no. of cores (%d) greater than configured " - "maximum of %d - clipping\n", - ncores, NR_CPUS); - ncores = NR_CPUS; - } - - for (i = 0; i < ncores; i++) - set_cpu_possible(i, true); -} - -static void __init highbank_smp_prepare_cpus(unsigned int max_cpus) -{ - if (scu_base_addr) - scu_enable(scu_base_addr); -} - -struct smp_operations highbank_smp_ops __initdata = { - .smp_init_cpus = highbank_smp_init_cpus, - .smp_prepare_cpus = highbank_smp_prepare_cpus, - .smp_secondary_init = highbank_secondary_init, - .smp_boot_secondary = highbank_boot_secondary, -#ifdef CONFIG_HOTPLUG_CPU - .cpu_die = highbank_cpu_die, -#endif -}; diff --git a/arch/arm/mach-highbank/pm.c b/arch/arm/mach-highbank/pm.c index 04eddb4..d1f511b 100644 --- a/arch/arm/mach-highbank/pm.c +++ b/arch/arm/mach-highbank/pm.c @@ -16,27 +16,21 @@ #include #include -#include #include -#include -#include #include -#include "core.h" #include "sysregs.h" static int highbank_suspend_finish(unsigned long val) { - outer_flush_all(); - outer_disable(); + const struct psci_power_state ps = { + .id = HB_PWR_SUSPEND, + .type = PSCI_POWER_STATE_TYPE_POWER_DOWN, + .affinity_level = 1, + }; - highbank_set_pwr_suspend(); - - cpu_do_idle(); - - highbank_clear_pwr_request(); - return 0; + return psci_ops.cpu_suspend(ps, __pa(cpu_resume)); } static int highbank_pm_enter(suspend_state_t state) @@ -44,15 +38,11 @@ static int highbank_pm_enter(suspend_state_t state) cpu_pm_enter(); cpu_cluster_pm_enter(); - highbank_set_cpu_jump(0, cpu_resume); cpu_suspend(0, highbank_suspend_finish); cpu_cluster_pm_exit(); cpu_pm_exit(); - highbank_smc1(0x102, 0x1); - if (scu_base_addr) - scu_enable(scu_base_addr); return 0; } @@ -63,5 +53,8 @@ static const struct platform_suspend_ops highbank_pm_ops = { void __init highbank_pm_init(void) { + if (!psci_ops.cpu_suspend) + return; + suspend_set_ops(&highbank_pm_ops); } diff --git a/arch/arm/mach-highbank/sysregs.h b/arch/arm/mach-highbank/sysregs.h index 5995df7..38818f3 100644 --- a/arch/arm/mach-highbank/sysregs.h +++ b/arch/arm/mach-highbank/sysregs.h @@ -16,71 +16,26 @@ #ifndef _MACH_HIGHBANK__SYSREGS_H_ #define _MACH_HIGHBANK__SYSREGS_H_ -#include -#include -#include -#include -#include "core.h" - -extern void __iomem *sregs_base; - -#define HB_SREG_A9_PWR_REQ 0xf00 -#define HB_SREG_A9_BOOT_STAT 0xf04 -#define HB_SREG_A9_BOOT_DATA 0xf08 +#include +#include #define HB_PWR_SUSPEND 0 #define HB_PWR_SOFT_RESET 1 #define HB_PWR_HARD_RESET 2 #define HB_PWR_SHUTDOWN 3 -#define SREG_CPU_PWR_CTRL(c) (0x200 + ((c) * 4)) - -static inline void highbank_set_core_pwr(void) -{ - int cpu = MPIDR_AFFINITY_LEVEL(cpu_logical_map(smp_processor_id()), 0); - if (scu_base_addr) - scu_power_mode(scu_base_addr, SCU_PM_POWEROFF); - else - writel_relaxed(1, sregs_base + SREG_CPU_PWR_CTRL(cpu)); -} - -static inline void highbank_clear_core_pwr(void) +static inline int highbank_cpu_off(int id, int affinity_level) { - int cpu = MPIDR_AFFINITY_LEVEL(cpu_logical_map(smp_processor_id()), 0); - if (scu_base_addr) - scu_power_mode(scu_base_addr, SCU_PM_NORMAL); - else - writel_relaxed(0, sregs_base + SREG_CPU_PWR_CTRL(cpu)); -} + struct psci_power_state ps = { + .id = id, + .type = PSCI_POWER_STATE_TYPE_POWER_DOWN, + .affinity_level = affinity_level, + }; -static inline void highbank_set_pwr_suspend(void) -{ - writel(HB_PWR_SUSPEND, sregs_base + HB_SREG_A9_PWR_REQ); - highbank_set_core_pwr(); -} + if (psci_ops.cpu_off) + return psci_ops.cpu_off(ps); -static inline void highbank_set_pwr_shutdown(void) -{ - writel(HB_PWR_SHUTDOWN, sregs_base + HB_SREG_A9_PWR_REQ); - highbank_set_core_pwr(); -} - -static inline void highbank_set_pwr_soft_reset(void) -{ - writel(HB_PWR_SOFT_RESET, sregs_base + HB_SREG_A9_PWR_REQ); - highbank_set_core_pwr(); -} - -static inline void highbank_set_pwr_hard_reset(void) -{ - writel(HB_PWR_HARD_RESET, sregs_base + HB_SREG_A9_PWR_REQ); - highbank_set_core_pwr(); -} - -static inline void highbank_clear_pwr_request(void) -{ - writel(~0UL, sregs_base + HB_SREG_A9_PWR_REQ); - highbank_clear_core_pwr(); + return -ENODEV; } #endif diff --git a/arch/arm/mach-highbank/system.c b/arch/arm/mach-highbank/system.c deleted file mode 100644 index 37d8384..0000000 --- a/arch/arm/mach-highbank/system.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2011 Calxeda, Inc. - * - * 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 . - */ -#include -#include - -#include "core.h" -#include "sysregs.h" - -void highbank_restart(char mode, const char *cmd) -{ - if (mode == 'h') - highbank_set_pwr_hard_reset(); - else - highbank_set_pwr_soft_reset(); - - while (1) - cpu_do_idle(); -} -