From patchwork Sat Sep 29 23:44:35 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: York Sun X-Patchwork-Id: 188133 X-Patchwork-Delegate: galak@kernel.crashing.org Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from ozlabs.org (localhost [IPv6:::1]) by ozlabs.org (Postfix) with ESMTP id C87692C00FC for ; Sun, 30 Sep 2012 09:45:16 +1000 (EST) Received: from co1outboundpool.messaging.microsoft.com (co1ehsobe004.messaging.microsoft.com [216.32.180.187]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (Client CN "mail.global.frontbridge.com", Issuer "Microsoft Secure Server Authority" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 161472C00B0 for ; Sun, 30 Sep 2012 09:44:45 +1000 (EST) Received: from mail198-co1-R.bigfish.com (10.243.78.250) by CO1EHSOBE004.bigfish.com (10.243.66.67) with Microsoft SMTP Server id 14.1.225.23; Sat, 29 Sep 2012 23:44:39 +0000 Received: from mail198-co1 (localhost [127.0.0.1]) by mail198-co1-R.bigfish.com (Postfix) with ESMTP id 5B52CD00074 for ; Sat, 29 Sep 2012 23:44:39 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 1 X-BigFish: VS1(zzd6f1izz1202h1d1ah1d2ahzz8275bh8275dhz2dh2a8h668h839hd24he5bhf0ah107ah1288h12a5h12a9h12bdh12e5h137ah139eh13b6h1155h) Received: from mail198-co1 (localhost.localdomain [127.0.0.1]) by mail198-co1 (MessageSwitch) id 1348962278206165_9166; Sat, 29 Sep 2012 23:44:38 +0000 (UTC) Received: from CO1EHSMHS018.bigfish.com (unknown [10.243.78.254]) by mail198-co1.bigfish.com (Postfix) with ESMTP id 2EF261C005D for ; Sat, 29 Sep 2012 23:44:38 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by CO1EHSMHS018.bigfish.com (10.243.66.28) with Microsoft SMTP Server (TLS) id 14.1.225.23; Sat, 29 Sep 2012 23:44:38 +0000 Received: from tx30smr01.am.freescale.net (10.81.153.31) by 039-SN1MMR1-001.039d.mgd.msft.net (10.84.1.13) with Microsoft SMTP Server (TLS) id 14.2.309.3; Sat, 29 Sep 2012 18:44:36 -0500 Received: from oslab-l1.am.freescale.net ([10.214.85.229]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id q8TNiZfa028425; Sat, 29 Sep 2012 16:44:36 -0700 From: York Sun To: Subject: [PATCH] powerpc/mpc85xx: Change spin table to cached memory Date: Sat, 29 Sep 2012 16:44:35 -0700 Message-ID: <1348962275-24052-1-git-send-email-yorksun@freescale.com> X-Mailer: git-send-email 1.7.9.5 MIME-Version: 1.0 X-OriginatorOrg: freescale.com Cc: scottwood@freescale.com, kumar.gala@freescale.com, timur@freescale.com X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" ePAPR v1.1 requires the spin table to be in cached memory. So we need to change the call argument of ioremap to enable cache and coherence. We also flush the cache after writing to spin table to keep it compatible with previous cache-inhibit spin table. Flushing before and after accessing spin table is recommended by ePAPR. Signed-off-by: York Sun Acked-by: Timur Tabi --- This patch applies to git://git.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git next branch. arch/powerpc/platforms/85xx/smp.c | 49 +++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 6fcfa12..148c2f2 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -128,6 +128,19 @@ static void __cpuinit smp_85xx_mach_cpu_die(void) } #endif +static inline void flush_spin_table(void *spin_table) +{ + flush_dcache_range((ulong)spin_table, + (ulong)spin_table + sizeof(struct epapr_spin_table)); +} + +static inline u32 read_spin_table_addr_l(void *spin_table) +{ + flush_dcache_range((ulong)spin_table, + (ulong)spin_table + sizeof(struct epapr_spin_table)); + return in_be32(&((struct epapr_spin_table *)spin_table)->addr_l); +} + static int __cpuinit smp_85xx_kick_cpu(int nr) { unsigned long flags; @@ -161,8 +174,8 @@ static int __cpuinit smp_85xx_kick_cpu(int nr) /* Map the spin table */ if (ioremappable) - spin_table = ioremap(*cpu_rel_addr, - sizeof(struct epapr_spin_table)); + spin_table = ioremap_prot(*cpu_rel_addr, + sizeof(struct epapr_spin_table), _PAGE_COHERENT); else spin_table = phys_to_virt(*cpu_rel_addr); @@ -173,7 +186,16 @@ static int __cpuinit smp_85xx_kick_cpu(int nr) generic_set_cpu_up(nr); if (system_state == SYSTEM_RUNNING) { + /* + * To keep it compatible with old boot program which uses + * cache-inhibit spin table, we need to flush the cache + * before accessing spin table to invalidate any staled data. + * We also need to flush the cache after writing to spin + * table to push data out. + */ + flush_spin_table(spin_table); out_be32(&spin_table->addr_l, 0); + flush_spin_table(spin_table); /* * We don't set the BPTR register here since it already points @@ -181,9 +203,14 @@ static int __cpuinit smp_85xx_kick_cpu(int nr) */ mpic_reset_core(hw_cpu); - /* wait until core is ready... */ - if (!spin_event_timeout(in_be32(&spin_table->addr_l) == 1, - 10000, 100)) { + /* + * wait until core is ready... + * We need to invalidate the stale data, in case the boot + * loader uses a cache-inhibited spin table. + */ + if (!spin_event_timeout( + read_spin_table_addr_l(spin_table) == 1, + 10000, 100)) { pr_err("%s: timeout waiting for core %d to reset\n", __func__, hw_cpu); ret = -ENOENT; @@ -194,12 +221,10 @@ static int __cpuinit smp_85xx_kick_cpu(int nr) __secondary_hold_acknowledge = -1; } #endif + flush_spin_table(spin_table); out_be32(&spin_table->pir, hw_cpu); out_be32(&spin_table->addr_l, __pa(__early_start)); - - if (!ioremappable) - flush_dcache_range((ulong)spin_table, - (ulong)spin_table + sizeof(struct epapr_spin_table)); + flush_spin_table(spin_table); /* Wait a bit for the CPU to ack. */ if (!spin_event_timeout(__secondary_hold_acknowledge == hw_cpu, @@ -213,13 +238,11 @@ out: #else smp_generic_kick_cpu(nr); + flush_spin_table(spin_table); out_be32(&spin_table->pir, hw_cpu); out_be64((u64 *)(&spin_table->addr_h), __pa((u64)*((unsigned long long *)generic_secondary_smp_init))); - - if (!ioremappable) - flush_dcache_range((ulong)spin_table, - (ulong)spin_table + sizeof(struct epapr_spin_table)); + flush_spin_table(spin_table); #endif local_irq_restore(flags);