LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v7 2/5] powerpc/85xx: add HOTPLUG_CPU support
From: Kumar Gala @ 2012-07-13 12:15 UTC (permalink / raw)
  To: Zhao Chenhui; +Cc: scottwood, linuxppc-dev, linux-kernel
In-Reply-To: <1341310879-5468-2-git-send-email-chenhui.zhao@freescale.com>


On Jul 3, 2012, at 5:21 AM, Zhao Chenhui wrote:

> From: Li Yang <leoli@freescale.com>
>=20
> Add support to disable and re-enable individual cores at runtime
> on MPC85xx/QorIQ SMP machines. Currently support e500v1/e500v2 core.
>=20
> MPC85xx machines use ePAPR spin-table in boot page for CPU kick-off.
> This patch uses the boot page from bootloader to boot core at runtime.
> It supports 32-bit and 36-bit physical address.
>=20
> Add generic_set_cpu_up() to set cpu_state as CPU_UP_PREPARE in =
kick_cpu().

Shouldn't the generic_setup_cpu_up() be a separate patch, and refactor =
smp_generic_kick_cpu() to use it.

Also, we should pull the conversion of the spintable from #defines to =
struct into a separate patch before this one.

>=20
> Signed-off-by: Li Yang <leoli@freescale.com>
> Signed-off-by: Jin Qing <b24347@freescale.com>
> Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com>
> ---
> v7:
> * removed CONFIG_85xx_TB_SYNC
> no change to the rest of the patch set
>=20
> arch/powerpc/Kconfig                  |    6 +-
> arch/powerpc/include/asm/cacheflush.h |    2 +
> arch/powerpc/include/asm/smp.h        |    2 +
> arch/powerpc/kernel/head_fsl_booke.S  |   28 +++++++
> arch/powerpc/kernel/smp.c             |   10 +++
> arch/powerpc/platforms/85xx/smp.c     |  137 =
++++++++++++++++++++++++---------
> 6 files changed, 146 insertions(+), 39 deletions(-)
>=20
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 38786c8..d6bacbe 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -220,7 +220,8 @@ config ARCH_HIBERNATION_POSSIBLE
> config ARCH_SUSPEND_POSSIBLE
> 	def_bool y
> 	depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \
> -		   (PPC_85xx && !SMP) || PPC_86xx || PPC_PSERIES || 44x =
|| 40x
> +		   (PPC_85xx && !PPC_E500MC) || PPC_86xx || PPC_PSERIES =
\
> +		   || 44x || 40x
>=20
> config PPC_DCR_NATIVE
> 	bool
> @@ -331,7 +332,8 @@ config SWIOTLB
>=20
> config HOTPLUG_CPU
> 	bool "Support for enabling/disabling CPUs"
> -	depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || =
PPC_PMAC || PPC_POWERNV)
> +	depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || \
> +	PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC))
> 	---help---
> 	  Say Y here to be able to disable and re-enable individual
> 	  CPUs at runtime on SMP machines.
> diff --git a/arch/powerpc/include/asm/cacheflush.h =
b/arch/powerpc/include/asm/cacheflush.h
> index ab9e402..b843e35 100644
> --- a/arch/powerpc/include/asm/cacheflush.h
> +++ b/arch/powerpc/include/asm/cacheflush.h
> @@ -30,6 +30,8 @@ extern void flush_dcache_page(struct page *page);
> #define flush_dcache_mmap_lock(mapping)		do { } while (0)
> #define flush_dcache_mmap_unlock(mapping)	do { } while (0)
>=20
> +extern void __flush_disable_L1(void);
> +
> extern void __flush_icache_range(unsigned long, unsigned long);
> static inline void flush_icache_range(unsigned long start, unsigned =
long stop)
> {
> diff --git a/arch/powerpc/include/asm/smp.h =
b/arch/powerpc/include/asm/smp.h
> index ebc24dc..e807e9d 100644
> --- a/arch/powerpc/include/asm/smp.h
> +++ b/arch/powerpc/include/asm/smp.h
> @@ -65,6 +65,7 @@ int generic_cpu_disable(void);
> void generic_cpu_die(unsigned int cpu);
> void generic_mach_cpu_die(void);
> void generic_set_cpu_dead(unsigned int cpu);
> +void generic_set_cpu_up(unsigned int cpu);
> int generic_check_cpu_restart(unsigned int cpu);
> #endif
>=20
> @@ -190,6 +191,7 @@ extern unsigned long __secondary_hold_spinloop;
> extern unsigned long __secondary_hold_acknowledge;
> extern char __secondary_hold;
>=20
> +extern void __early_start(void);
> #endif /* __ASSEMBLY__ */
>=20
> #endif /* __KERNEL__ */
> diff --git a/arch/powerpc/kernel/head_fsl_booke.S =
b/arch/powerpc/kernel/head_fsl_booke.S
> index de80e0f..be0261b 100644
> --- a/arch/powerpc/kernel/head_fsl_booke.S
> +++ b/arch/powerpc/kernel/head_fsl_booke.S
> @@ -996,6 +996,34 @@ _GLOBAL(flush_dcache_L1)
>=20
> 	blr
>=20
> +/* Flush L1 d-cache, invalidate and disable d-cache and i-cache */
> +_GLOBAL(__flush_disable_L1)
> +	mflr	r10
> +	bl	flush_dcache_L1	/* Flush L1 d-cache */
> +	mtlr	r10
> +
> +	mfspr	r4, SPRN_L1CSR0	/* Invalidate and disable d-cache */
> +	li	r5, 2
> +	rlwimi	r4, r5, 0, 3
> +
> +	msync
> +	isync
> +	mtspr	SPRN_L1CSR0, r4
> +	isync
> +
> +1:	mfspr	r4, SPRN_L1CSR0	/* Wait for the invalidate to finish */
> +	andi.	r4, r4, 2
> +	bne	1b
> +
> +	mfspr	r4, SPRN_L1CSR1	/* Invalidate and disable i-cache */
> +	li	r5, 2
> +	rlwimi	r4, r5, 0, 3
> +
> +	mtspr	SPRN_L1CSR1, r4
> +	isync
> +
> +	blr
> +
> #ifdef CONFIG_SMP
> /* When we get here, r24 needs to hold the CPU # */
> 	.globl __secondary_start
> diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
> index d9f9441..e0ffe03 100644
> --- a/arch/powerpc/kernel/smp.c
> +++ b/arch/powerpc/kernel/smp.c
> @@ -423,6 +423,16 @@ void generic_set_cpu_dead(unsigned int cpu)
> 	per_cpu(cpu_state, cpu) =3D CPU_DEAD;
> }
>=20
> +/*
> + * The cpu_state should be set to CPU_UP_PREPARE in kick_cpu(), =
otherwise
> + * the cpu_state is always CPU_DEAD after calling =
generic_set_cpu_dead(),
> + * which makes the delay in generic_cpu_die() not happen.
> + */
> +void generic_set_cpu_up(unsigned int cpu)
> +{
> +	per_cpu(cpu_state, cpu) =3D CPU_UP_PREPARE;
> +}
> +
> int generic_check_cpu_restart(unsigned int cpu)
> {
> 	return per_cpu(cpu_state, cpu) =3D=3D CPU_UP_PREPARE;
> diff --git a/arch/powerpc/platforms/85xx/smp.c =
b/arch/powerpc/platforms/85xx/smp.c
> index 2e65fe8..925e678 100644
> --- a/arch/powerpc/platforms/85xx/smp.c
> +++ b/arch/powerpc/platforms/85xx/smp.c
> @@ -2,7 +2,7 @@
>  * Author: Andy Fleming <afleming@freescale.com>
>  * 	   Kumar Gala <galak@kernel.crashing.org>
>  *
> - * Copyright 2006-2008, 2011 Freescale Semiconductor Inc.
> + * Copyright 2006-2008, 2011-2012 Freescale Semiconductor Inc.
>  *
>  * This program is free software; you can redistribute  it and/or =
modify it
>  * under  the terms of  the GNU General  Public License as published =
by the
> @@ -17,6 +17,7 @@
> #include <linux/of.h>
> #include <linux/kexec.h>
> #include <linux/highmem.h>
> +#include <linux/cpu.h>
>=20
> #include <asm/machdep.h>
> #include <asm/pgtable.h>
> @@ -30,18 +31,14 @@
> #include <sysdev/mpic.h>
> #include "smp.h"
>=20
> -extern void __early_start(void);
> -
> -#define BOOT_ENTRY_ADDR_UPPER	0
> -#define BOOT_ENTRY_ADDR_LOWER	1
> -#define BOOT_ENTRY_R3_UPPER	2
> -#define BOOT_ENTRY_R3_LOWER	3
> -#define BOOT_ENTRY_RESV		4
> -#define BOOT_ENTRY_PIR		5
> -#define BOOT_ENTRY_R6_UPPER	6
> -#define BOOT_ENTRY_R6_LOWER	7
> -#define NUM_BOOT_ENTRY		8
> -#define SIZE_BOOT_ENTRY		(NUM_BOOT_ENTRY * sizeof(u32))
> +struct epapr_spin_table {
> +	u32	addr_h;
> +	u32	addr_l;
> +	u32	r3_h;
> +	u32	r3_l;
> +	u32	reserved;
> +	u32	pir;
> +};
>=20
> static struct ccsr_guts __iomem *guts;
> static u64 timebase;
> @@ -101,15 +98,45 @@ static void mpc85xx_take_timebase(void)
> 	local_irq_restore(flags);
> }
>=20
> -static int __init
> -smp_85xx_kick_cpu(int nr)
> +#ifdef CONFIG_HOTPLUG_CPU
> +static void __cpuinit smp_85xx_mach_cpu_die(void)
> +{
> +	unsigned int cpu =3D smp_processor_id();
> +	u32 tmp;
> +
> +	local_irq_disable();
> +	idle_task_exit();
> +	generic_set_cpu_dead(cpu);
> +	mb();
> +
> +	mtspr(SPRN_TCR, 0);
> +
> +	__flush_disable_L1();
> +	tmp =3D (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP;
> +	mtspr(SPRN_HID0, tmp);
> +	isync();
> +
> +	/* Enter NAP mode. */
> +	tmp =3D mfmsr();
> +	tmp |=3D MSR_WE;
> +	mb();
> +	mtmsr(tmp);
> +	isync();
> +
> +	while (1)
> +		;
> +}
> +#endif
> +
> +static int __cpuinit smp_85xx_kick_cpu(int nr)
> {
> 	unsigned long flags;
> 	const u64 *cpu_rel_addr;
> -	__iomem u32 *bptr_vaddr;
> +	__iomem struct epapr_spin_table *spin_table;
> 	struct device_node *np;
> -	int n =3D 0, hw_cpu =3D get_hard_smp_processor_id(nr);
> +	int hw_cpu =3D get_hard_smp_processor_id(nr);
> 	int ioremappable;
> +	int ret =3D 0;
>=20
> 	WARN_ON(nr < 0 || nr >=3D NR_CPUS);
> 	WARN_ON(hw_cpu < 0 || hw_cpu >=3D NR_CPUS);
> @@ -134,46 +161,80 @@ smp_85xx_kick_cpu(int nr)
>=20
> 	/* Map the spin table */
> 	if (ioremappable)
> -		bptr_vaddr =3D ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY);
> +		spin_table =3D ioremap(*cpu_rel_addr,
> +				sizeof(struct epapr_spin_table));
> 	else
> -		bptr_vaddr =3D phys_to_virt(*cpu_rel_addr);
> +		spin_table =3D phys_to_virt(*cpu_rel_addr);
>=20
> 	local_irq_save(flags);
> -
> -	out_be32(bptr_vaddr + BOOT_ENTRY_PIR, hw_cpu);
> #ifdef CONFIG_PPC32
> -	out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, =
__pa(__early_start));
> +#ifdef CONFIG_HOTPLUG_CPU
> +	/* Corresponding to generic_set_cpu_dead() */
> +	generic_set_cpu_up(nr);
> +
> +	if (system_state =3D=3D SYSTEM_RUNNING) {
> +		out_be32(&spin_table->addr_l, 0);
> +
> +		/*
> +		 * We don't set the BPTR register here since it already =
points
> +		 * to the boot page properly.
> +		 */
> +		mpic_reset_core(hw_cpu);
> +
> +		/* wait until core is ready... */
> +		if (!spin_event_timeout(in_be32(&spin_table->addr_l) =3D=3D=
 1,
> +						10000, 100)) {
> +			pr_err("%s: timeout waiting for core %d to =
reset\n",
> +							__func__, =
hw_cpu);
> +			ret =3D -ENOENT;
> +			goto out;
> +		}
> +
> +		/*  clear the acknowledge status */
> +		__secondary_hold_acknowledge =3D -1;
> +	}
> +#endif
> +	out_be32(&spin_table->pir, hw_cpu);
> +	out_be32(&spin_table->addr_l, __pa(__early_start));
>=20
> 	if (!ioremappable)
> -		flush_dcache_range((ulong)bptr_vaddr,
> -				(ulong)(bptr_vaddr + SIZE_BOOT_ENTRY));
> +		flush_dcache_range((ulong)spin_table,
> +			(ulong)spin_table + sizeof(struct =
epapr_spin_table));
>=20
> 	/* Wait a bit for the CPU to ack. */
> -	while ((__secondary_hold_acknowledge !=3D hw_cpu) && (++n < =
1000))
> -		mdelay(1);
> +	if (!spin_event_timeout(__secondary_hold_acknowledge =3D=3D =
hw_cpu,
> +					10000, 100)) {
> +		pr_err("%s: timeout waiting for core %d to ack\n",
> +						__func__, hw_cpu);
> +		ret =3D -ENOENT;
> +		goto out;
> +	}
> +out:
> #else
> 	smp_generic_kick_cpu(nr);
>=20
> -	out_be64((u64 *)(bptr_vaddr + BOOT_ENTRY_ADDR_UPPER),
> -		__pa((u64)*((unsigned long long *) =
generic_secondary_smp_init)));
> +	out_be32(&spin_table->pir, hw_cpu);
> +	out_be64((u64 *)(&spin_table->addr_h),
> +	  __pa((u64)*((unsigned long long =
*)generic_secondary_smp_init)));
>=20
> 	if (!ioremappable)
> -		flush_dcache_range((ulong)bptr_vaddr,
> -				(ulong)(bptr_vaddr + SIZE_BOOT_ENTRY));
> +		flush_dcache_range((ulong)spin_table,
> +			(ulong)spin_table + sizeof(struct =
epapr_spin_table));
> #endif
> -
> 	local_irq_restore(flags);
>=20
> 	if (ioremappable)
> -		iounmap(bptr_vaddr);
> +		iounmap(spin_table);
>=20
> -	pr_debug("waited %d msecs for CPU #%d.\n", n, nr);
> -
> -	return 0;
> +	return ret;
> }
>=20
> struct smp_ops_t smp_85xx_ops =3D {
> 	.kick_cpu =3D smp_85xx_kick_cpu,
> +#ifdef CONFIG_HOTPLUG_CPU
> +	.cpu_disable	=3D generic_cpu_disable,
> +	.cpu_die	=3D generic_cpu_die,
> +#endif
> #ifdef CONFIG_KEXEC
> 	.give_timebase	=3D smp_generic_give_timebase,
> 	.take_timebase	=3D smp_generic_take_timebase,
> @@ -277,8 +338,7 @@ static void mpc85xx_smp_machine_kexec(struct =
kimage *image)
> }
> #endif /* CONFIG_KEXEC */
>=20
> -static void __init
> -smp_85xx_setup_cpu(int cpu_nr)
> +static void __cpuinit smp_85xx_setup_cpu(int cpu_nr)
> {
> 	if (smp_85xx_ops.probe =3D=3D smp_mpic_probe)
> 		mpic_setup_this_cpu();
> @@ -329,6 +389,9 @@ void __init mpc85xx_smp_init(void)
> 		}
> 		smp_85xx_ops.give_timebase =3D mpc85xx_give_timebase;
> 		smp_85xx_ops.take_timebase =3D mpc85xx_take_timebase;
> +#ifdef CONFIG_HOTPLUG_CPU
> +		ppc_md.cpu_die =3D smp_85xx_mach_cpu_die;
> +#endif
> 	}
>=20
> 	smp_ops =3D &smp_85xx_ops;
> --=20
> 1.6.4.1
>=20

^ permalink raw reply

* Re: [PATCH] ppc44x/watchdog: Select WATCHDOG_NOWAYOUT option
From: Josh Boyer @ 2012-07-13 12:25 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, Jiang Lu
In-Reply-To: <D5792F52-7BE6-4B86-A3FD-B756DE3A165D@kernel.crashing.org>

On Fri, Jul 13, 2012 at 7:50 AM, Kumar Gala <galak@kernel.crashing.org> wrote:
>
> On Jul 12, 2012, at 9:44 PM, Jiang Lu wrote:
>
>> On PPC44x core, the WRC(Watchdog-timer Reset Control) field of TCR
>> of timer can not reset by software after set to a non-zero value.
>> Which means software can not reset the timeout behaviour of watchdog timer.
>>
>> This patch selects WATCHDOG_NOWAYOUT option for 44x platforms to
>> indicate the watchdog timer can not be disabled once fired.
>>
>> Signed-off-by: Jiang Lu <lu.jiang@windriver.com>
>> ---
>> drivers/watchdog/Kconfig |    1 +
>> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> I believe this is not 44x specific, but how Book-E watchdog is architected.

That is my understanding as well.

>> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
>> index 3709624..41f3dff 100644
>> --- a/drivers/watchdog/Kconfig
>> +++ b/drivers/watchdog/Kconfig
>> @@ -1084,6 +1084,7 @@ config PIKA_WDT
>> config BOOKE_WDT
>>       tristate "PowerPC Book-E Watchdog Timer"
>>       depends on BOOKE || 4xx
>> +     select WATCHDOG_NOWAYOUT if 44x
>
> This should probably be 'select WATCHDOG_NOWAYOUT if BOOKE'

I kind of disagree with this change.  It's a user selectable option for
a reason.

Right now, if the option is not set we call booke_wdt_disable which
indeed does not actually _disable_ the WDT, but it does set the timer
period to the maxium value.  We could go one step further and implement
a simple timer that pops and calls booke_wdt_ping if WATCHDOG_NOWAYOUT
is not set, then rearms itself.  That would leave the user with the
ability to perform recovery of the userspace process that exited or
died and was responsible for pinging the watchdog.

josh

^ permalink raw reply

* Re: [PATCH v6 3/5] powerpc/85xx: add sleep and deep sleep support
From: Kumar Gala @ 2012-07-13 12:27 UTC (permalink / raw)
  To: Zhao Chenhui; +Cc: scottwood, linuxppc-dev, linux-kernel
In-Reply-To: <1340706359-9455-3-git-send-email-chenhui.zhao@freescale.com>


On Jun 26, 2012, at 5:25 AM, Zhao Chenhui wrote:

> From: Li Yang <leoli@freescale.com>
>=20
> In sleep PM mode, the clocks of e500 core and unused IP blocks is
> turned off. IP blocks which are allowed to wake up the processor
> are still running.
>=20
> Some Freescale chips like MPC8536 and P1022 has deep sleep PM mode
> in addtion to the sleep PM mode.
>=20
> While in deep sleep PM mode, additionally, the power supply is
> removed from e500 core and most IP blocks. Only the blocks needed
> to wake up the chip out of deep sleep are ON.
>=20
> This patch supports 32-bit and 36-bit address space.
>=20
> The sleep mode is equal to the Standby state in Linux. The deep sleep
> mode is equal to the Suspend-to-RAM state of Linux Power Management.
>=20
> Command to enter sleep mode.
>  echo standby > /sys/power/state
> Command to enter deep sleep mode.
>  echo mem > /sys/power/state
>=20
> Signed-off-by: Dave Liu <daveliu@freescale.com>
> Signed-off-by: Li Yang <leoli@freescale.com>
> Signed-off-by: Jin Qing <b24347@freescale.com>
> Signed-off-by: Jerry Huang <Chang-Ming.Huang@freescale.com>
> Cc: Scott Wood <scottwood@freescale.com>
> Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com>
> ---
> Changes for v6:
> * changed the declaration of flush_dcache_L1()
> * some minor changes
>=20
> arch/powerpc/Kconfig                  |    2 +-
> arch/powerpc/include/asm/cacheflush.h |    2 +
> arch/powerpc/kernel/Makefile          |    3 +
> arch/powerpc/kernel/l2cache_85xx.S    |   53 +++
> arch/powerpc/platforms/85xx/Makefile  |    2 +-
> arch/powerpc/platforms/85xx/sleep.S   |  609 =
+++++++++++++++++++++++++++++++++
> arch/powerpc/sysdev/fsl_pmc.c         |   98 +++++-
> arch/powerpc/sysdev/fsl_soc.h         |    5 +
> 8 files changed, 754 insertions(+), 20 deletions(-)
> create mode 100644 arch/powerpc/kernel/l2cache_85xx.S
> create mode 100644 arch/powerpc/platforms/85xx/sleep.S
>=20


> diff --git a/arch/powerpc/kernel/l2cache_85xx.S =
b/arch/powerpc/kernel/l2cache_85xx.S
> new file mode 100644
> index 0000000..b0b7d1c
> --- /dev/null
> +++ b/arch/powerpc/kernel/l2cache_85xx.S
> @@ -0,0 +1,53 @@
> +/*
> + * Copyright (C) 2009-2012 Freescale Semiconductor, Inc. All rights =
reserved.
> + *	Scott Wood <scottwood@freescale.com>
> + *	Dave Liu <daveliu@freescale.com>
> + * implement the L2 cache operations of e500 based L2 controller
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include <asm/reg.h>
> +#include <asm/cputable.h>
> +#include <asm/ppc_asm.h>
> +#include <asm/asm-offsets.h>
> +
> +	.section .text
> +
> +	/* r3 =3D virtual address of L2 controller, WIMG =3D 01xx */
> +_GLOBAL(flush_disable_L2)
> +	/* It's a write-through cache, so only invalidation is needed. =
*/
> +	mbar
> +	isync
> +	lwz	r4, 0(r3)
> +	li	r5, 1
> +	rlwimi	r4, r5, 30, 0xc0000000

Can 0xc0000000 be a #define for what I'm guessing is L2E and L2I?

> +	stw	r4, 0(r3)
> +
> +	/* Wait for the invalidate to finish */
> +1:	lwz	r4, 0(r3)
> +	andis.	r4, r4, 0x4000

#define for 0x4000 -> L2I@h

> +	bne	1b
> +	mbar
> +
> +	blr
> +
> +	/* r3 =3D virtual address of L2 controller, WIMG =3D 01xx */
> +_GLOBAL(invalidate_enable_L2)
> +	mbar
> +	isync
> +	lwz	r4, 0(r3)
> +	li	r5, 3
> +	rlwimi	r4, r5, 30, 0xc0000000
> +	stw	r4, 0(r3)
> +
> +	/* Wait for the invalidate to finish */
> +1:	lwz	r4, 0(r3)
> +	andis.	r4, r4, 0x4000

same comments as above about #defines.

> +	bne	1b
> +	mbar
> +
> +	blr
> diff --git a/arch/powerpc/platforms/85xx/Makefile =
b/arch/powerpc/platforms/85xx/Makefile
> index 2125d4c..d154e39 100644
> --- a/arch/powerpc/platforms/85xx/Makefile
> +++ b/arch/powerpc/platforms/85xx/Makefile
> @@ -3,7 +3,7 @@
> #
> obj-$(CONFIG_SMP) +=3D smp.o
>=20
> -obj-y +=3D common.o
> +obj-y +=3D common.o sleep.o
>=20
> obj-$(CONFIG_MPC8540_ADS) +=3D mpc85xx_ads.o
> obj-$(CONFIG_MPC8560_ADS) +=3D mpc85xx_ads.o
> diff --git a/arch/powerpc/platforms/85xx/sleep.S =
b/arch/powerpc/platforms/85xx/sleep.S
> new file mode 100644
> index 0000000..b272f0c
> --- /dev/null
> +++ b/arch/powerpc/platforms/85xx/sleep.S
> @@ -0,0 +1,609 @@
> +/*
> + * Enter and leave deep sleep/sleep state on MPC85xx
> + *
> + * Author: Scott Wood <scottwood@freescale.com>
> + *
> + * Copyright (C) 2006-2012 Freescale Semiconductor, Inc. All rights =
reserved.
> + *
> + * This program is free software; you can redistribute it and/or =
modify it
> + * under the terms of the GNU General Public License version 2 as =
published
> + * by the Free Software Foundation.
> + */
> +
> +#include <asm/page.h>
> +#include <asm/ppc_asm.h>
> +#include <asm/reg.h>
> +#include <asm/asm-offsets.h>
> +
> +#define SS_TB		0x00
> +#define SS_HID		0x08 /* 2 HIDs */
> +#define SS_IAC		0x10 /* 2 IACs */
> +#define SS_DAC		0x18 /* 2 DACs */
> +#define SS_DBCR		0x20 /* 3 DBCRs */
> +#define SS_PID		0x2c /* 3 PIDs */
> +#define SS_SPRG		0x38 /* 8 SPRGs */
> +#define SS_IVOR		0x58 /* 20 interrupt vectors */
> +#define SS_TCR		0xa8
> +#define SS_BUCSR	0xac
> +#define SS_L1CSR	0xb0 /* 2 L1CSRs */
> +#define SS_MSR		0xb8
> +#define SS_USPRG	0xbc
> +#define SS_GPREG	0xc0 /* r12-r31 */
> +#define SS_LR		0x110
> +#define SS_CR		0x114
> +#define SS_SP		0x118
> +#define SS_CURRENT	0x11c
> +#define SS_IVPR		0x120
> +#define SS_BPTR		0x124
> +
> +
> +#define STATE_SAVE_SIZE 0x128
> +
> +	.section .data
> +	.align	5
> +mpc85xx_sleep_save_area:
> +	.space	STATE_SAVE_SIZE
> +ccsrbase_low:
> +	.long	0
> +ccsrbase_high:
> +	.long	0
> +powmgtreq:
> +	.long	0
> +
> +	.section .text
> +	.align	12
> +
> +	/*
> +	 * r3 =3D high word of physical address of CCSR
> +	 * r4 =3D low word of physical address of CCSR
> +	 * r5 =3D JOG or deep sleep request
> +	 *      JOG-0x00200000, deep sleep-0x00100000
> +	 */
> +_GLOBAL(mpc85xx_enter_deep_sleep)
> +	lis	r6, ccsrbase_low@ha
> +	stw	r4, ccsrbase_low@l(r6)
> +	lis	r6, ccsrbase_high@ha
> +	stw	r3, ccsrbase_high@l(r6)
> +
> +	lis	r6, powmgtreq@ha
> +	stw	r5, powmgtreq@l(r6)
> +
> +	lis	r10, mpc85xx_sleep_save_area@h
> +	ori	r10, r10, mpc85xx_sleep_save_area@l
> +
> +	mfspr	r5, SPRN_HID0
> +	mfspr	r6, SPRN_HID1
> +
> +	stw	r5, SS_HID+0(r10)
> +	stw	r6, SS_HID+4(r10)
> +
> +	mfspr	r4, SPRN_IAC1
> +	mfspr	r5, SPRN_IAC2
> +	mfspr	r6, SPRN_DAC1
> +	mfspr	r7, SPRN_DAC2
> +
> +	stw	r4, SS_IAC+0(r10)
> +	stw	r5, SS_IAC+4(r10)
> +	stw	r6, SS_DAC+0(r10)
> +	stw	r7, SS_DAC+4(r10)
> +
> +	mfspr	r4, SPRN_DBCR0
> +	mfspr	r5, SPRN_DBCR1
> +	mfspr	r6, SPRN_DBCR2
> +
> +	stw	r4, SS_DBCR+0(r10)
> +	stw	r5, SS_DBCR+4(r10)
> +	stw	r6, SS_DBCR+8(r10)
> +
> +	mfspr	r4, SPRN_PID0
> +	mfspr	r5, SPRN_PID1
> +	mfspr	r6, SPRN_PID2
> +
> +	stw	r4, SS_PID+0(r10)
> +	stw	r5, SS_PID+4(r10)
> +	stw	r6, SS_PID+8(r10)
> +
> +	mfspr	r4, SPRN_SPRG0
> +	mfspr	r5, SPRN_SPRG1
> +	mfspr	r6, SPRN_SPRG2
> +	mfspr	r7, SPRN_SPRG3
> +
> +	stw	r4, SS_SPRG+0x00(r10)
> +	stw	r5, SS_SPRG+0x04(r10)
> +	stw	r6, SS_SPRG+0x08(r10)
> +	stw	r7, SS_SPRG+0x0c(r10)
> +
> +	mfspr	r4, SPRN_SPRG4
> +	mfspr	r5, SPRN_SPRG5
> +	mfspr	r6, SPRN_SPRG6
> +	mfspr	r7, SPRN_SPRG7
> +
> +	stw	r4, SS_SPRG+0x10(r10)
> +	stw	r5, SS_SPRG+0x14(r10)
> +	stw	r6, SS_SPRG+0x18(r10)
> +	stw	r7, SS_SPRG+0x1c(r10)
> +
> +	mfspr	r4, SPRN_IVPR
> +	stw	r4, SS_IVPR(r10)
> +
> +	mfspr	r4, SPRN_IVOR0
> +	mfspr	r5, SPRN_IVOR1
> +	mfspr	r6, SPRN_IVOR2
> +	mfspr	r7, SPRN_IVOR3
> +
> +	stw	r4, SS_IVOR+0x00(r10)
> +	stw	r5, SS_IVOR+0x04(r10)
> +	stw	r6, SS_IVOR+0x08(r10)
> +	stw	r7, SS_IVOR+0x0c(r10)
> +
> +	mfspr	r4, SPRN_IVOR4
> +	mfspr	r5, SPRN_IVOR5
> +	mfspr	r6, SPRN_IVOR6
> +	mfspr	r7, SPRN_IVOR7
> +
> +	stw	r4, SS_IVOR+0x10(r10)
> +	stw	r5, SS_IVOR+0x14(r10)
> +	stw	r6, SS_IVOR+0x18(r10)
> +	stw	r7, SS_IVOR+0x1c(r10)
> +
> +	mfspr	r4, SPRN_IVOR8
> +	mfspr	r5, SPRN_IVOR9
> +	mfspr	r6, SPRN_IVOR10
> +	mfspr	r7, SPRN_IVOR11
> +
> +	stw	r4, SS_IVOR+0x20(r10)
> +	stw	r5, SS_IVOR+0x24(r10)
> +	stw	r6, SS_IVOR+0x28(r10)
> +	stw	r7, SS_IVOR+0x2c(r10)
> +
> +	mfspr	r4, SPRN_IVOR12
> +	mfspr	r5, SPRN_IVOR13
> +	mfspr	r6, SPRN_IVOR14
> +	mfspr	r7, SPRN_IVOR15
> +
> +	stw	r4, SS_IVOR+0x30(r10)
> +	stw	r5, SS_IVOR+0x34(r10)
> +	stw	r6, SS_IVOR+0x38(r10)
> +	stw	r7, SS_IVOR+0x3c(r10)
> +
> +	mfspr	r4, SPRN_IVOR32
> +	mfspr	r5, SPRN_IVOR33
> +	mfspr	r6, SPRN_IVOR34
> +	mfspr	r7, SPRN_IVOR35
> +
> +	stw	r4, SS_IVOR+0x40(r10)
> +	stw	r5, SS_IVOR+0x44(r10)
> +	stw	r6, SS_IVOR+0x48(r10)
> +	stw	r7, SS_IVOR+0x4c(r10)
> +
> +	mfspr	r4, SPRN_TCR
> +	mfspr	r5, SPRN_BUCSR
> +	mfspr	r6, SPRN_L1CSR0
> +	mfspr	r7, SPRN_L1CSR1
> +	mfspr	r8, SPRN_USPRG0
> +
> +	stw	r4, SS_TCR(r10)
> +	stw	r5, SS_BUCSR(r10)
> +	stw	r6, SS_L1CSR+0(r10)
> +	stw	r7, SS_L1CSR+4(r10)
> +	stw	r8, SS_USPRG+0(r10)
> +
> +	stmw	r12, SS_GPREG(r10)
> +
> +	mfmsr	r4
> +	mflr	r5
> +	mfcr	r6
> +
> +	stw	r4, SS_MSR(r10)
> +	stw	r5, SS_LR(r10)
> +	stw	r6, SS_CR(r10)
> +	stw	r1, SS_SP(r10)
> +	stw	r2, SS_CURRENT(r10)
> +
> +1:	mftbu	r4
> +	mftb	r5
> +	mftbu	r6
> +	cmpw	r4, r6
> +	bne	1b
> +
> +	stw	r4, SS_TB+0(r10)
> +	stw	r5, SS_TB+4(r10)
> +
> +	lis	r5, ccsrbase_low@ha
> +	lwz	r4, ccsrbase_low@l(r5)
> +	lis	r5, ccsrbase_high@ha
> +	lwz	r3, ccsrbase_high@l(r5)
> +
> +	/* Disable machine checks and critical exceptions */
> +	mfmsr	r5
> +	rlwinm	r5, r5, 0, ~MSR_CE
> +	rlwinm	r5, r5, 0, ~MSR_ME
> +	mtmsr	r5
> +	isync
> +
> +	/* Use TLB1[15] to map the CCSR at 0xf0000000 */
> +	lis	r5, 0x100f
> +	mtspr	SPRN_MAS0, r5
> +	lis	r5, 0xc000
> +	ori	r5, r5, 0x0500
> +	mtspr	SPRN_MAS1, r5
> +	lis	r5, 0xf000
> +	ori	r5, r5, 0x000a
> +	mtspr	SPRN_MAS2, r5
> +	rlwinm	r5, r4, 0, 0xfffff000
> +	ori	r5, r5, 0x0005

We have #defines that should be used instead of magic numbers for MAS =
defines/fields.

> +	mtspr	SPRN_MAS3, r5
> +	mtspr	SPRN_MAS7, r3
> +	isync
> +	tlbwe
> +	isync
> +
> +	lis	r3, 0xf000
> +	lwz	r4, 0x20(r3)
> +	stw	r4, SS_BPTR(r10)
> +
> +	lis	r3, 0xf002	/* L2 cache controller at CCSR+0x20000 =
*/
> +	bl	flush_disable_L2
> +	bl	__flush_disable_L1
> +
> +	/* Enable I-cache, so as not to upset the bus
> +	 * with our loop.
> +	 */
> +
> +	mfspr	r4, SPRN_L1CSR1
> +	ori	r4, r4, 1
> +	mtspr	SPRN_L1CSR1, r4
> +	isync
> +
> +	/* Set boot page translation */
> +	lis	r3, 0xf000
> +	lis	r4, (mpc85xx_deep_resume - PAGE_OFFSET)@h
> +	ori	r4, r4, (mpc85xx_deep_resume - PAGE_OFFSET)@l
> +	rlwinm	r4, r4, 20, 0x000fffff
> +	oris	r4, r4, 0x8000
> +	stw	r4, 0x20(r3)
> +	lwz	r4, 0x20(r3)		/* read-back to flush write */
> +	twi	0, r4, 0
> +	isync
> +
> +	/* Disable the decrementer */
> +	mfspr	r4, SPRN_TCR
> +	rlwinm	r4, r4, 0, ~TCR_DIE
> +	mtspr	SPRN_TCR, r4
> +
> +	mfspr	r4, SPRN_TSR
> +	oris	r4, r4, TSR_DIS@h
> +	mtspr	SPRN_TSR, r4
> +
> +	/* set PMRCCR[VRCNT] to wait power stable for 40ms */
> +	lis	r3, 0xf00e
> +	lwz	r4, 0x84(r3)
> +	clrlwi	r4, r4, 16
> +	oris	r4, r4, 0x12a3
> +	stw	r4, 0x84(r3)
> +	lwz	r4, 0x84(r3)

#defines here for magic numbers?
> +
> +	/* set deep sleep bit in POWMGTSCR */
> +	lis	r3, powmgtreq@ha
> +	lwz	r8, powmgtreq@l(r3)
> +
> +	lis	r3, 0xf00e
> +	lwz	r4, 0x80(r3)
> +	or	r4, r4, r8
> +	stw	r4, 0x80(r3)
> +	lwz	r4, 0x80(r3)		/* read-back to flush write */
> +	twi	0, r4, 0
> +	isync

#defines here for magic numbers?

> +
> +	mftb	r5
> +1:	/* spin until either we enter deep sleep, or the sleep process =
is
> +	 * aborted due to a pending wakeup event.  Wait some time =
between
> +	 * accesses, so we don't flood the bus and prevent the pmc from
> +	 * detecting an idle system.
> +	 */
> +
> +	mftb	r4
> +	subf	r7, r5, r4
> +	cmpwi	r7, 1000
> +	blt	1b
> +	mr	r5, r4
> +
> +	lwz	r6, 0x80(r3)
> +	andis.	r6, r6, 0x0010
> +	bne	1b
> +	b	2f

#defines here for magic numbers?

> +
> +2:	mfspr	r4, SPRN_PIR
> +	andi.	r4, r4, 1
> +99:	bne	99b
> +
> +	/* Establish a temporary 64MB 0->0 mapping in TLB1[1]. */
> +	lis	r4, 0x1001
> +	mtspr	SPRN_MAS0, r4
> +	lis	r4, 0xc000
> +	ori	r4, r4, 0x0800
> +	mtspr	SPRN_MAS1, r4
> +	li	r4, 0
> +	mtspr	SPRN_MAS2, r4
> +	li	r4, 0x0015
> +	mtspr	SPRN_MAS3, r4
> +	li	r4, 0
> +	mtspr	SPRN_MAS7, r4

Same comment as above about #defines for MAS regs

> +	isync
> +	tlbwe
> +	isync
> +
> +	lis	r3, (3f - PAGE_OFFSET)@h
> +	ori	r3, r3, (3f - PAGE_OFFSET)@l
> +	mtctr	r3
> +	bctr
> +
> +	/* Locate the resume vector in the last word of the current =
page. */
> +	. =3D mpc85xx_enter_deep_sleep + 0xffc
> +mpc85xx_deep_resume:
> +	b	2b
> +
> +3:
> +	/* Restore the contents of TLB1[0].  It is assumed that it =
covers
> +	 * the currently executing code and the sleep save area, and =
that
> +	 * it does not alias our temporary mapping (which is at virtual =
zero).
> +	 */
> +	lis	r3, (TLBCAM - PAGE_OFFSET)@h
> +	ori	r3, r3, (TLBCAM - PAGE_OFFSET)@l
> +
> +	lwz	r4, 0(r3)
> +	lwz	r5, 4(r3)
> +	lwz	r6, 8(r3)
> +	lwz	r7, 12(r3)
> +	lwz	r8, 16(r3)
> +
> +	mtspr	SPRN_MAS0, r4
> +	mtspr	SPRN_MAS1, r5
> +	mtspr	SPRN_MAS2, r6
> +	mtspr	SPRN_MAS3, r7
> +	mtspr	SPRN_MAS7, r8
> +
> +	isync
> +	tlbwe
> +	isync
> +
> +	/* Access the ccsrbase address with TLB1[0] */
> +	lis	r5, ccsrbase_low@ha
> +	lwz	r4, ccsrbase_low@l(r5)
> +	lis	r5, ccsrbase_high@ha
> +	lwz	r3, ccsrbase_high@l(r5)
> +
> +	/* Use TLB1[15] to map the CCSR at 0xf0000000 */
> +	lis	r5, 0x100f
> +	mtspr	SPRN_MAS0, r5
> +	lis	r5, 0xc000
> +	ori	r5, r5, 0x0500
> +	mtspr	SPRN_MAS1, r5
> +	lis	r5, 0xf000
> +	ori	r5, r5, 0x000a
> +	mtspr	SPRN_MAS2, r5
> +	rlwinm	r5, r4, 0, 0xfffff000
> +	ori	r5, r5, 0x0005
> +	mtspr	SPRN_MAS3, r5
> +	mtspr	SPRN_MAS7, r3

Same comment as above about #defines for MAS regs

> +	isync
> +	tlbwe
> +	isync
> +
> +	lis	r3, 0xf002	/* L2 cache controller at CCSR+0x20000 =
*/
> +	bl	invalidate_enable_L2
> +
> +	/* Access the MEM(r10) with TLB1[0] */
> +	lis	r10, mpc85xx_sleep_save_area@h
> +	ori	r10, r10, mpc85xx_sleep_save_area@l
> +
> +	lis	r3, 0xf000
> +	lwz	r4, SS_BPTR(r10)
> +	stw	r4, 0x20(r3)		/* restore BPTR */
> +
> +	/* Program shift running space to PAGE_OFFSET */
> +	mfmsr	r3
> +	lis	r4, 1f@h
> +	ori	r4, r4, 1f@l
> +
> +	mtsrr1	r3
> +	mtsrr0	r4
> +	rfi
> +
> +1:	/* Restore the rest of TLB1, in ascending order so that
> +	 * the TLB1[1] gets invalidated first.
> +	 *
> +	 * XXX: It's better to invalidate the temporary mapping
> +	 * TLB1[15] for CCSR before restore any TLB1 entry include 0.
> +	 */
> +	lis	r4, 0x100f
> +	mtspr	SPRN_MAS0, r4
> +	lis	r4, 0
> +	mtspr	SPRN_MAS1, r4
> +	isync
> +	tlbwe
> +	isync
> +
> +	lis	r3, (TLBCAM + 5*4 - 4)@h
> +	ori	r3, r3, (TLBCAM + 5*4 - 4)@l
> +	li	r4, 15
> +	mtctr	r4
> +
> +2:
> +	lwz	r5, 4(r3)
> +	lwz	r6, 8(r3)
> +	lwz	r7, 12(r3)
> +	lwz	r8, 16(r3)
> +	lwzu	r9, 20(r3)
> +
> +	mtspr	SPRN_MAS0, r5
> +	mtspr	SPRN_MAS1, r6
> +	mtspr	SPRN_MAS2, r7
> +	mtspr	SPRN_MAS3, r8
> +	mtspr	SPRN_MAS7, r9
> +
> +	isync
> +	tlbwe
> +	isync
> +	bdnz	2b
> +
> +	lis	r10, mpc85xx_sleep_save_area@h
> +	ori	r10, r10, mpc85xx_sleep_save_area@l
> +
> +	lwz	r5, SS_HID+0(r10)
> +	lwz	r6, SS_HID+4(r10)
> +
> +	isync
> +	mtspr	SPRN_HID0, r5
> +	isync
> +
> +	msync
> +	mtspr	SPRN_HID1, r6
> +	isync
> +
> +	lwz	r4, SS_IAC+0(r10)
> +	lwz	r5, SS_IAC+4(r10)
> +	lwz	r6, SS_DAC+0(r10)
> +	lwz	r7, SS_DAC+4(r10)
> +
> +	mtspr	SPRN_IAC1, r4
> +	mtspr	SPRN_IAC2, r5
> +	mtspr	SPRN_DAC1, r6
> +	mtspr	SPRN_DAC2, r7
> +
> +	lwz	r4, SS_DBCR+0(r10)
> +	lwz	r5, SS_DBCR+4(r10)
> +	lwz	r6, SS_DBCR+8(r10)
> +
> +	mtspr	SPRN_DBCR0, r4
> +	mtspr	SPRN_DBCR1, r5
> +	mtspr	SPRN_DBCR2, r6
> +
> +	lwz	r4, SS_PID+0(r10)
> +	lwz	r5, SS_PID+4(r10)
> +	lwz	r6, SS_PID+8(r10)
> +
> +	mtspr	SPRN_PID0, r4
> +	mtspr	SPRN_PID1, r5
> +	mtspr	SPRN_PID2, r6
> +
> +	lwz	r4, SS_SPRG+0x00(r10)
> +	lwz	r5, SS_SPRG+0x04(r10)
> +	lwz	r6, SS_SPRG+0x08(r10)
> +	lwz	r7, SS_SPRG+0x0c(r10)
> +
> +	mtspr	SPRN_SPRG0, r4
> +	mtspr	SPRN_SPRG1, r5
> +	mtspr	SPRN_SPRG2, r6
> +	mtspr	SPRN_SPRG3, r7
> +
> +	lwz	r4, SS_SPRG+0x10(r10)
> +	lwz	r5, SS_SPRG+0x14(r10)
> +	lwz	r6, SS_SPRG+0x18(r10)
> +	lwz	r7, SS_SPRG+0x1c(r10)
> +
> +	mtspr	SPRN_SPRG4, r4
> +	mtspr	SPRN_SPRG5, r5
> +	mtspr	SPRN_SPRG6, r6
> +	mtspr	SPRN_SPRG7, r7
> +
> +	lwz	r4, SS_IVPR(r10)
> +	mtspr	SPRN_IVPR, r4
> +
> +	lwz	r4, SS_IVOR+0x00(r10)
> +	lwz	r5, SS_IVOR+0x04(r10)
> +	lwz	r6, SS_IVOR+0x08(r10)
> +	lwz	r7, SS_IVOR+0x0c(r10)
> +
> +	mtspr	SPRN_IVOR0, r4
> +	mtspr	SPRN_IVOR1, r5
> +	mtspr	SPRN_IVOR2, r6
> +	mtspr	SPRN_IVOR3, r7
> +
> +	lwz	r4, SS_IVOR+0x10(r10)
> +	lwz	r5, SS_IVOR+0x14(r10)
> +	lwz	r6, SS_IVOR+0x18(r10)
> +	lwz	r7, SS_IVOR+0x1c(r10)
> +
> +	mtspr	SPRN_IVOR4, r4
> +	mtspr	SPRN_IVOR5, r5
> +	mtspr	SPRN_IVOR6, r6
> +	mtspr	SPRN_IVOR7, r7
> +
> +	lwz	r4, SS_IVOR+0x20(r10)
> +	lwz	r5, SS_IVOR+0x24(r10)
> +	lwz	r6, SS_IVOR+0x28(r10)
> +	lwz	r7, SS_IVOR+0x2c(r10)
> +
> +	mtspr	SPRN_IVOR8, r4
> +	mtspr	SPRN_IVOR9, r5
> +	mtspr	SPRN_IVOR10, r6
> +	mtspr	SPRN_IVOR11, r7
> +
> +	lwz	r4, SS_IVOR+0x30(r10)
> +	lwz	r5, SS_IVOR+0x34(r10)
> +	lwz	r6, SS_IVOR+0x38(r10)
> +	lwz	r7, SS_IVOR+0x3c(r10)
> +
> +	mtspr	SPRN_IVOR12, r4
> +	mtspr	SPRN_IVOR13, r5
> +	mtspr	SPRN_IVOR14, r6
> +	mtspr	SPRN_IVOR15, r7
> +
> +	lwz	r4, SS_IVOR+0x40(r10)
> +	lwz	r5, SS_IVOR+0x44(r10)
> +	lwz	r6, SS_IVOR+0x48(r10)
> +	lwz	r7, SS_IVOR+0x4c(r10)
> +
> +	mtspr	SPRN_IVOR32, r4
> +	mtspr	SPRN_IVOR33, r5
> +	mtspr	SPRN_IVOR34, r6
> +	mtspr	SPRN_IVOR35, r7
> +
> +	lwz	r4, SS_TCR(r10)
> +	lwz	r5, SS_BUCSR(r10)
> +	lwz	r6, SS_L1CSR+0(r10)
> +	lwz	r7, SS_L1CSR+4(r10)
> +	lwz	r8, SS_USPRG+0(r10)
> +
> +	mtspr	SPRN_TCR, r4
> +	mtspr	SPRN_BUCSR, r5
> +
> +	msync
> +	isync
> +	mtspr	SPRN_L1CSR0, r6
> +	isync
> +
> +	mtspr	SPRN_L1CSR1, r7
> +	isync
> +
> +	mtspr	SPRN_USPRG0, r8
> +
> +	lmw	r12, SS_GPREG(r10)
> +
> +	lwz	r1, SS_SP(r10)
> +	lwz	r2, SS_CURRENT(r10)
> +	lwz	r4, SS_MSR(r10)
> +	lwz	r5, SS_LR(r10)
> +	lwz	r6, SS_CR(r10)
> +
> +	msync
> +	mtmsr	r4
> +	isync
> +
> +	mtlr	r5
> +	mtcr	r6
> +
> +	li	r4, 0
> +	mtspr	SPRN_TBWL, r4
> +
> +	lwz	r4, SS_TB+0(r10)
> +	lwz	r5, SS_TB+4(r10)
> +
> +	mtspr	SPRN_TBWU, r4
> +	mtspr	SPRN_TBWL, r5
> +
> +	lis	r3, 1
> +	mtdec	r3
> +
> +	blr

^ permalink raw reply

* Re: [PATCH] ppc44x/watchdog: Select WATCHDOG_NOWAYOUT option
From: Kumar Gala @ 2012-07-13 12:52 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev, Jiang Lu
In-Reply-To: <CA+5PVA6RG1m8c2OUL2g0gBK7dRCrmeu47rZfoqAjxODm1zcNRg@mail.gmail.com>


On Jul 13, 2012, at 7:25 AM, Josh Boyer wrote:

> On Fri, Jul 13, 2012 at 7:50 AM, Kumar Gala =
<galak@kernel.crashing.org> wrote:
>>=20
>> On Jul 12, 2012, at 9:44 PM, Jiang Lu wrote:
>>=20
>>> On PPC44x core, the WRC(Watchdog-timer Reset Control) field of TCR
>>> of timer can not reset by software after set to a non-zero value.
>>> Which means software can not reset the timeout behaviour of watchdog =
timer.
>>>=20
>>> This patch selects WATCHDOG_NOWAYOUT option for 44x platforms to
>>> indicate the watchdog timer can not be disabled once fired.
>>>=20
>>> Signed-off-by: Jiang Lu <lu.jiang@windriver.com>
>>> ---
>>> drivers/watchdog/Kconfig |    1 +
>>> 1 files changed, 1 insertions(+), 0 deletions(-)
>>=20
>> I believe this is not 44x specific, but how Book-E watchdog is =
architected.
>=20
> That is my understanding as well.
>=20
>>> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
>>> index 3709624..41f3dff 100644
>>> --- a/drivers/watchdog/Kconfig
>>> +++ b/drivers/watchdog/Kconfig
>>> @@ -1084,6 +1084,7 @@ config PIKA_WDT
>>> config BOOKE_WDT
>>>      tristate "PowerPC Book-E Watchdog Timer"
>>>      depends on BOOKE || 4xx
>>> +     select WATCHDOG_NOWAYOUT if 44x
>>=20
>> This should probably be 'select WATCHDOG_NOWAYOUT if BOOKE'
>=20
> I kind of disagree with this change.  It's a user selectable option =
for
> a reason.
>=20
> Right now, if the option is not set we call booke_wdt_disable which
> indeed does not actually _disable_ the WDT, but it does set the timer
> period to the maxium value.  We could go one step further and =
implement
> a simple timer that pops and calls booke_wdt_ping if WATCHDOG_NOWAYOUT
> is not set, then rearms itself.  That would leave the user with the
> ability to perform recovery of the userspace process that exited or
> died and was responsible for pinging the watchdog.
>=20
> josh

My only care was about it being Book-E and not 44x.  Otherwise I'm happy =
to defer to your take on this.

- k

^ permalink raw reply

* RE: Standalone SRIO Driver for Linux
From: Bounine, Alexandre @ 2012-07-13 12:48 UTC (permalink / raw)
  To: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <CAEqOc-QpXcwbLuJXLbGv3VgccKnkMrdGV+ZdwFaFZCzjG3K7Mw@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1451 bytes --]

This should work. We use similar approach to test our mport HW drivers.

Alex.

From: Linuxppc-dev [mailto:linuxppc-dev-bounces+alexandre.bounine=idt.com@lists.ozlabs.org] On Behalf Of Saravanan S
Sent: Friday, July 13, 2012 2:16 AM
To: linuxppc-dev@lists.ozlabs.org
Subject: Standalone SRIO Driver for Linux

Hi ,
      Iam currently working on the GE make DSP230 board consisting of Quad PowerPC8640 nodes   interconnected by SRIO with Linux 2.6.34 . However the only way to access the SRIO is through rionet facility . Our requirement is to use the SRIO interconnect without the Ethernet overheads. This would definitely enable higher speeds (though I cant find any throughput figures for SRIO in Linux on the net ??? ).  My query is that whether any attempt has been made  to develop a  standalone driver and API to access the messaging  and doorbell services of SRIO . If no then request you to please provide inputs on the same. From my study I have the following thoughts for the driver :

a) Have a character device interface for user .
b) Basically use the rio support functions provided in rio.c like  rio_add_inb_buffer ,  rio_add_outb_message to transfer and receive messages and add buffers .
c) Maintain a dedicated ring of buffers in the driver and transfer  data to and from the buffer to user space .


Is this the right direction . Would really appreciate any inputs . thanks in advance.

Regards,

S.Saravanan

[-- Attachment #2: Type: text/html, Size: 4340 bytes --]

^ permalink raw reply

* P1022DS board support upstream?
From: Kumar Gala @ 2012-07-13 13:01 UTC (permalink / raw)
  To: linuxppc-dev@lists.ozlabs.org list; +Cc: Timur Tabi

Is the functionality of all of these SDK patches upstream now?

[ ignore commit id's ]

b257909 powerpc/85xx: p1022ds: disable the NAND flash node if video is =
enabled
ee260f4 powerpc/mpc85xx: p1022ds support the MTD for NOR and NAND flash
4be8bb6 powerpc/mpc85xx: 32bit address support for p1022ds
25f9408 powerpc/85xx: fix PCI and localbus properties in p1022ds.dts
1bcb442 powerpc/p1022ds/DTS: Add RTC support
05e5bc8 powerpc/85xx: create 32-bit DTS for the P1022DS
79111f3 powerpc/85xx: p1022ds: disable the NOR flash node if video is =
enabled

- k=

^ permalink raw reply

* Re: P1022DS board support upstream?
From: Kumar Gala @ 2012-07-13 13:36 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev@lists.ozlabs.org list, Timur Tabi
In-Reply-To: <1F81EF77-1E39-4D16-BB8B-24D5CA53F929@freescale.com>


On Jul 13, 2012, at 8:01 AM, Kumar Gala wrote:

> Is the functionality of all of these SDK patches upstream now?
>=20
> [ ignore commit id's ]
>=20
> b257909 powerpc/85xx: p1022ds: disable the NAND flash node if video is =
enabled
> ee260f4 powerpc/mpc85xx: p1022ds support the MTD for NOR and NAND =
flash
> 4be8bb6 powerpc/mpc85xx: 32bit address support for p1022ds
> 25f9408 powerpc/85xx: fix PCI and localbus properties in p1022ds.dts
> 1bcb442 powerpc/p1022ds/DTS: Add RTC support
> 05e5bc8 powerpc/85xx: create 32-bit DTS for the P1022DS
> 79111f3 powerpc/85xx: p1022ds: disable the NOR flash node if video is =
enabled
>=20
> - k

Please ignore, this was meant for out internal list.

Sorry for the noise.

- k

^ permalink raw reply

* Re: [PATCH] powerpc/85xx: L2sram: Add compatible string to the device id list
From: Kumar Gala @ 2012-07-13 13:54 UTC (permalink / raw)
  To: <b29983@freescale.com>; +Cc: Tang Yuantian, linuxppc-dev
In-Reply-To: <1342146455-27729-1-git-send-email-b29983@freescale.com>


On Jul 12, 2012, at 9:27 PM, <b29983@freescale.com> =
<b29983@freescale.com> wrote:

> From: Tang Yuantian <Yuantian.Tang@freescale.com>
>=20
> The following platforms are supported:
> mpc8544, mpc8572, mpc8536, p1021, p1025, p1024, p1010.
>=20
> Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
> ---
> arch/powerpc/sysdev/fsl_85xx_l2ctlr.c |   10 ++++++++++
> 1 files changed, 10 insertions(+), 0 deletions(-)

applied to next

- k=

^ permalink raw reply

* Re: [PATCH] powerpc/85xx: Fix pci base address error for p2020rdb-pc in dts
From: Kumar Gala @ 2012-07-13 13:55 UTC (permalink / raw)
  To: <b29983@freescale.com>; +Cc: Tang Yuantian, linuxppc-dev
In-Reply-To: <1342146455-27729-2-git-send-email-b29983@freescale.com>


On Jul 12, 2012, at 9:27 PM, <b29983@freescale.com> =
<b29983@freescale.com> wrote:

> From: Tang Yuantian <Yuantian.Tang@freescale.com>
>=20
> Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
> ---
> arch/powerpc/boot/dts/p2020rdb-pc_32b.dts |    4 ++--
> arch/powerpc/boot/dts/p2020rdb-pc_36b.dts |    4 ++--
> 2 files changed, 4 insertions(+), 4 deletions(-)

applied to next

- k=

^ permalink raw reply

* [PATCH] powerpc/85xx: p1022ds: disable the NAND flash node if video is enabled
From: Timur Tabi @ 2012-07-13 19:28 UTC (permalink / raw)
  To: Kumar Gala, linuxppc-dev

The Freescale P1022 has a unique pin muxing "feature" where the DIU video
controller's video signals are muxed with 24 of the local bus address signals.
When the DIU is enabled, the bulk of the local bus is disabled, preventing
access to memory-mapped devices like NAND flash and the pixis FPGA.

Therefore, if the DIU is going to be enabled, then memory-mapped devices on
the localbus, like NAND flash, need to be disabled.

This patch is similar to "powerpc/85xx: p1022ds: disable the NOR flash node
if video is enabled", except that it disables the NAND flash node instead.
This PIXIS node needs to remain enabled because it is used by platform code
to switch into indirect mode.

Signed-off-by: Timur Tabi <timur@freescale.com>
---
 arch/powerpc/platforms/85xx/p1022_ds.c |   58 +++++++++++++++++++++-----------
 1 files changed, 38 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index 89ee02c..5ca2823a 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -419,18 +419,6 @@ void __init p1022_ds_pic_init(void)
 
 #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
 
-/*
- * Disables a node in the device tree.
- *
- * This function is called before kmalloc() is available, so the 'new' object
- * should be allocated in the global area.  The easiest way is to do that is
- * to allocate one static local variable for each call to this function.
- */
-static void __init disable_one_node(struct device_node *np, struct property *new)
-{
-	prom_update_property(np, new);
-}
-
 /* TRUE if there is a "video=fslfb" command-line parameter. */
 static bool fslfb;
 
@@ -493,28 +481,58 @@ static void __init p1022_ds_setup_arch(void)
 	diu_ops.valid_monitor_port	= p1022ds_valid_monitor_port;
 
 	/*
-	 * Disable the NOR flash node if there is video=fslfb... command-line
-	 * parameter.  When the DIU is active, NOR flash is unavailable, so we
-	 * have to disable the node before the MTD driver loads.
+	 * Disable the NOR and NAND flash nodes if there is video=fslfb...
+	 * command-line parameter.  When the DIU is active, the localbus is
+	 * unavailable, so we have to disable these nodes before the MTD
+	 * driver loads.
 	 */
 	if (fslfb) {
 		struct device_node *np =
 			of_find_compatible_node(NULL, NULL, "fsl,p1022-elbc");
 
 		if (np) {
-			np = of_find_compatible_node(np, NULL, "cfi-flash");
-			if (np) {
+			struct device_node *np2;
+
+			of_node_get(np);
+			np2 = of_find_compatible_node(np, NULL, "cfi-flash");
+			if (np2) {
 				static struct property nor_status = {
 					.name = "status",
 					.value = "disabled",
 					.length = sizeof("disabled"),
 				};
 
+				/*
+				 * prom_update_property() is called before
+				 * kmalloc() is available, so the 'new' object
+				 * should be allocated in the global area.
+				 * The easiest way is to do that is to
+				 * allocate one static local variable for each
+				 * call to this function.
+				 */
+				pr_info("p1022ds: disabling %s node",
+					np2->full_name);
+				prom_update_property(np2, &nor_status);
+				of_node_put(np2);
+			}
+
+			of_node_get(np);
+			np2 = of_find_compatible_node(np, NULL,
+						      "fsl,elbc-fcm-nand");
+			if (np2) {
+				static struct property nand_status = {
+					.name = "status",
+					.value = "disabled",
+					.length = sizeof("disabled"),
+				};
+
 				pr_info("p1022ds: disabling %s node",
-					np->full_name);
-				disable_one_node(np, &nor_status);
-				of_node_put(np);
+					np2->full_name);
+				prom_update_property(np2, &nand_status);
+				of_node_put(np2);
 			}
+
+			of_node_put(np);
 		}
 
 	}
-- 
1.7.3.4

^ permalink raw reply related

* Re: [PATCH 5/7] pci: minimal alignment for bars of P2P bridges
From: Bjorn Helgaas @ 2012-07-13 20:12 UTC (permalink / raw)
  To: Gavin Shan; +Cc: linux-pci, yinghai, linuxram, linuxppc-dev
In-Reply-To: <878dcc914319fd110ceda936c2ce5b6bb7a449ab.1340949637.git.shangw@linux.vnet.ibm.com>

On Fri, Jun 29, 2012 at 02:47:48PM +0800, Gavin Shan wrote:
> On some powerpc platforms, device BARs need to be assigned to separate
> "segments" of the address space in order for the error isolation and HW
> virtualization mechanisms (EEH) to work properly. Those "segments" have
> a minimum size that can be fairly large (16M). In order to be able to
> use the generic resource assignment code rather than re-inventing our
> own, we chose to group devices by bus. That way, a simple change of the
> minimum alignment requirements of resources assigned to PCI to PCI (P2P)
> bridges is enough to ensure that all BARs for devices below those bridges
> will fit into contiguous sets of segments and there will be no overlap.

If I understand correctly, you might have something like this:

  PCI host bridge to bus 0000:00
  pci_bus 0000:00: root bus resource [mem 0xc0000000-0xcfffffff]
  0000:00:01.0: PCI bridge to [bus 10-1f]
  0000:00:01.0:   bridge window [mem 0xc1000000-0xc1ffffff]
  0000:00:02.0: PCI bridge to [bus 20-2f]
  0000:00:02.0:   bridge window [mem 0xc2000000-0xc2ffffff]

where everything under bridge 00:01.0 is in one EEH segment, and
everything under 00:02.0 is in another.  In this case, each EEH
segment is 16MB.

I think your proposal is basically that when we add up resources required
below the P2P bridges, we round up to the default 1MB (the minimum P2P
bridge memory aperture size per spec) *or* to a larger value, e.g., 16MB,
if the architecture requires it.

That makes sense to me, but I have some implementation questions.

Your patches make the required alignment a property of the host bridge.
But don't you want to do this rounding up only at certain levels of the
hierarchy?  For example, what if you had another P2P bridge:

  0000:10:01.0: PCI bridge to [bus 18-1f]

I assume the devices on bus 0000:18 would still be in the first EEH
segment, and you wouldn't necessarily want to round up the 10:01.0
apertures to 16MB.

Maybe there should be an interface like this:

  resource_size_t __weak pcibios_window_alignment(struct pci_bus *bus,
						  unsigned long type)
  {
    if (type & IORESOURCE_MEM)
      return 1024*1024;		/* mem windows must be 1MB aligned */
    if (bus->self->io_window_1k)
      return 1024;
    return 4*1024;		/* I/O windows default to 4K alignment */
  }

that the arch could override?  Then you could return the 16MB alignment
for the top-level P2P bridge leading to an EEH segment, and use the
default alignment for P2P bridges *inside* the segment.

> This patch provides a way for the host bridge to override the default
> alignment values used by the resource allocation code for that purpose.
> 
> Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
> Reviewed-by: Ram Pai <linuxram@us.ibm.com>
> Reviewed-by: Richard Yang <weiyang@linux.vnet.ibm.com>
> ---
>  drivers/pci/probe.c |    5 +++++
>  include/linux/pci.h |    8 ++++++++
>  2 files changed, 13 insertions(+)
> 
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 658ac97..a196529 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -431,6 +431,11 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
>  	if (bridge) {
>  		INIT_LIST_HEAD(&bridge->windows);
>  		bridge->bus = b;
> +
> +		/* Set minimal alignment shift of P2P bridges */
> +		bridge->io_align_shift = PCI_DEFAULT_IO_ALIGN_SHIFT;
> +		bridge->mem_align_shift = PCI_DEFAULT_MEM_ALIGN_SHIFT;
> +		bridge->pmem_align_shift = PCI_DEFAULT_PMEM_ALIGN_SHIFT;
>  	}
>  
>  	return bridge;
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index e66f4b2..2b2b38d 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -376,9 +376,17 @@ struct pci_host_bridge_window {
>  	resource_size_t offset;		/* bus address + offset = CPU address */
>  };
>  
> +/* Default shits for P2P I/O and MMIO bar minimal alignment shifts */
> +#define PCI_DEFAULT_IO_ALIGN_SHIFT	12	/* 4KB  */
> +#define PCI_DEFAULT_MEM_ALIGN_SHIFT	20	/* 1MB  */
> +#define PCI_DEFAULT_PMEM_ALIGN_SHIFT	20	/* 1MB */
> +
>  struct pci_host_bridge {
>  	struct device dev;
>  	struct pci_bus *bus;		/* root bus */
> +	int io_align_shift;		/* P2P I/O bar minimal alignment shift  */
> +	int mem_align_shift;		/* P2P MMIO bar minimal alignment shift */
> +	int pmem_align_shift;		/* P2P prefetchable MMIO bar minimal alignment shift */
>  	struct list_head windows;	/* pci_host_bridge_windows */
>  	void (*release_fn)(struct pci_host_bridge *);
>  	void *release_data;
> -- 
> 1.7.9.5
> 

^ permalink raw reply

* [PATCH] powerpc/85xx: remove P1020RDB and P2020RDB CAMP device trees
From: Timur Tabi @ 2012-07-13 22:40 UTC (permalink / raw)
  To: Kumar Gala, linuxppc-dev

We only need two examples of CAMP device trees in the upstream kernel.

Co-operative Asymmetric Multi-Processing (CAMP) is a technique where two
or more operating systems (typically multiple copies of the same Linux kernel)
are loaded into memory, and each kernel is given a subset of the available
cores to execute on.  For example, on a four-core system, one kernel runs on
cores 0 and 1, and the other runs on cores 2 and 3.

The devices are also partitioned among the operating systems, and this is
done with customized device trees.  Each kernel gets its own device tree
that has only the devices that it should know about.

Unfortunately, this approach is very hackish.  The kernels are trusted to
only access devices in their respective device trees, and the partitioning
only works for devices that can be handled.  Crafting the device trees is a
tricky process, and getting U-Boot to load and start all kernels is cumbersome.

But most importantly, each CAMP setup is very application-specific, since
the actual partitioning of resources is done in the DTS by the system
designer.  Therefore, it doesn't make a lot of sense to have a lot of CAMP
device trees, since we only expect them to be used as examples.

Signed-off-by: Timur Tabi <timur@freescale.com>
---
 arch/powerpc/boot/dts/p1020rdb_camp_core0.dts |   63 -----------
 arch/powerpc/boot/dts/p1020rdb_camp_core1.dts |  141 -------------------------
 arch/powerpc/boot/dts/p2020rdb_camp_core0.dts |   67 ------------
 arch/powerpc/boot/dts/p2020rdb_camp_core1.dts |  125 ----------------------
 4 files changed, 0 insertions(+), 396 deletions(-)
 delete mode 100644 arch/powerpc/boot/dts/p1020rdb_camp_core0.dts
 delete mode 100644 arch/powerpc/boot/dts/p1020rdb_camp_core1.dts
 delete mode 100644 arch/powerpc/boot/dts/p2020rdb_camp_core0.dts
 delete mode 100644 arch/powerpc/boot/dts/p2020rdb_camp_core1.dts

diff --git a/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts b/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts
deleted file mode 100644
index 41b4585..0000000
--- a/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * P1020 RDB  Core0 Device Tree Source in CAMP mode.
- *
- * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
- * can be shared, all the other devices must be assigned to one core only.
- * This dts file allows core0 to have memory, l2, i2c, spi, gpio, tdm, dma, usb,
- * eth1, eth2, sdhc, crypto, global-util, message, pci0, pci1, msi.
- *
- * Please note to add "-b 0" for core0's dts compiling.
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-/include/ "p1020rdb.dts"
-
-/ {
-	model = "fsl,P1020RDB";
-	compatible = "fsl,P1020RDB", "fsl,MPC85XXRDB-CAMP";
-
-	aliases {
-		ethernet1 = &enet1;
-		ethernet2 = &enet2;
-		serial0 = &serial0;
-		pci0 = &pci0;
-		pci1 = &pci1;
-	};
-
-	cpus {
-		PowerPC,P1020@1 {
-			status = "disabled";
-		};
-	};
-
-	memory {
-		device_type = "memory";
-	};
-
-	localbus@ffe05000 {
-		status = "disabled";
-	};
-
-	soc@ffe00000 {
-		serial1: serial@4600 {
-			status = "disabled";
-		};
-
-		enet0: ethernet@b0000 {
-			status = "disabled";
-		};
-
-		mpic: pic@40000 {
-			protected-sources = <
-			42 29 30 34	/* serial1, enet0-queue-group0 */
-			17 18 24 45	/* enet0-queue-group1, crypto */
-			>;
-		};
-	};
-};
diff --git a/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts b/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts
deleted file mode 100644
index 5174538..0000000
--- a/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * P1020 RDB Core1 Device Tree Source in CAMP mode.
- *
- * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
- * can be shared, all the other devices must be assigned to one core only.
- * This dts allows core1 to have l2, eth0, crypto.
- *
- * Please note to add "-b 1" for core1's dts compiling.
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-/include/ "p1020rdb.dts"
-
-/ {
-	model = "fsl,P1020RDB";
-	compatible = "fsl,P1020RDB", "fsl,MPC85XXRDB-CAMP";
-
-	aliases {
-		ethernet0 = &enet0;
-		serial0 = &serial1;
-		};
-
-	cpus {
-		PowerPC,P1020@0 {
-			status = "disabled";
-		};
-	};
-
-	memory {
-		device_type = "memory";
-	};
-
-	localbus@ffe05000 {
-		status = "disabled";
-	};
-
-	soc@ffe00000 {
-		ecm-law@0 {
-			status = "disabled";
-		};
-
-		ecm@1000 {
-			status = "disabled";
-		};
-
-		memory-controller@2000 {
-			status = "disabled";
-		};
-
-		i2c@3000 {
-			status = "disabled";
-		};
-
-		i2c@3100 {
-			status = "disabled";
-		};
-
-		serial0: serial@4500 {
-			status = "disabled";
-		};
-
-		spi@7000 {
-			status = "disabled";
-		};
-
-		gpio: gpio-controller@f000 {
-			status = "disabled";
-		};
-
-		dma@21300 {
-			status = "disabled";
-		};
-
-		mdio@24000 {
-			status = "disabled";
-		};
-
-		mdio@25000 {
-			status = "disabled";
-		};
-
-		enet1: ethernet@b1000 {
-			status = "disabled";
-		};
-
-		enet2: ethernet@b2000 {
-			status = "disabled";
-		};
-
-		usb@22000 {
-			status = "disabled";
-		};
-
-		sdhci@2e000 {
-			status = "disabled";
-		};
-
-		mpic: pic@40000 {
-			protected-sources = <
-			16 		/* ecm, mem, L2, pci0, pci1 */
-			43 42 59	/* i2c, serial0, spi */
-			47 63 62 	/* gpio, tdm */
-			20 21 22 23	/* dma */
-			03 02 		/* mdio */
-			35 36 40	/* enet1-queue-group0 */
-			51 52 67	/* enet1-queue-group1 */
-			31 32 33	/* enet2-queue-group0 */
-			25 26 27	/* enet2-queue-group1 */
-			28 72 58 	/* usb, sdhci, crypto */
-			0xb0 0xb1 0xb2	/* message */
-			0xb3 0xb4 0xb5
-			0xb6 0xb7
-			0xe0 0xe1 0xe2	/* msi */
-			0xe3 0xe4 0xe5
-			0xe6 0xe7		/* sdhci, crypto , pci */
-			>;
-		};
-
-		msi@41600 {
-			status = "disabled";
-		};
-
-		global-utilities@e0000 {	//global utilities block
-			status = "disabled";
-		};
-	};
-
-	pci0: pcie@ffe09000 {
-		status = "disabled";
-	};
-
-	pci1: pcie@ffe0a000 {
-		status = "disabled";
-	};
-};
diff --git a/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts b/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts
deleted file mode 100644
index 66aac86..0000000
--- a/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * P2020 RDB  Core0 Device Tree Source in CAMP mode.
- *
- * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
- * can be shared, all the other devices must be assigned to one core only.
- * This dts file allows core0 to have memory, l2, i2c, spi, gpio, dma1, usb,
- * eth1, eth2, sdhc, crypto, global-util, pci0.
- *
- * Copyright 2009-2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-/include/ "p2020rdb.dts"
-
-/ {
-	model = "fsl,P2020RDB";
-	compatible = "fsl,P2020RDB", "fsl,MPC85XXRDB-CAMP";
-
-	cpus {
-		PowerPC,P2020@1 {
-			status = "disabled";
-		};
-	};
-
-	localbus@ffe05000 {
-		status = "disabled";
-	};
-
-	soc@ffe00000 {
-		serial1: serial@4600 {
-			status = "disabled";
-		};
-
-		dma@c300 {
-			status = "disabled";
-		};
-
-		enet0: ethernet@24000 {
-			status = "disabled";
-		};
-
-		mpic: pic@40000 {
-			protected-sources = <
-			42 76 77 78 79 /* serial1 , dma2 */
-			29 30 34 26 /* enet0, pci1 */
-			0xe0 0xe1 0xe2 0xe3 /* msi */
-			0xe4 0xe5 0xe6 0xe7
-			>;
-		};
-
-		msi@41600 {
-			status = "disabled";
-		};
-	};
-
-	pci0: pcie@ffe08000 {
-		status = "disabled";
-	};
-
-	pci2: pcie@ffe0a000 {
-		status = "disabled";
-	};
-};
diff --git a/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts b/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts
deleted file mode 100644
index 9bd8ef4..0000000
--- a/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * P2020 RDB Core1 Device Tree Source in CAMP mode.
- *
- * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
- * can be shared, all the other devices must be assigned to one core only.
- * This dts allows core1 to have l2, dma2, eth0, pci1, msi.
- *
- * Please note to add "-b 1" for core1's dts compiling.
- *
- * Copyright 2009-2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-/include/ "p2020rdb.dts"
-
-/ {
-	model = "fsl,P2020RDB";
-	compatible = "fsl,P2020RDB", "fsl,MPC85XXRDB-CAMP";
-
-	cpus {
-		PowerPC,P2020@0 {
-			status = "disabled";
-		};
-	};
-
-	localbus@ffe05000 {
-		status = "disabled";
-	};
-
-	soc@ffe00000 {
-		ecm-law@0 {
-			status = "disabled";
-		};
-
-		ecm@1000 {
-			status = "disabled";
-		};
-
-		memory-controller@2000 {
-			status = "disabled";
-		};
-
-		i2c@3000 {
-			status = "disabled";
-		};
-
-		i2c@3100 {
-			status = "disabled";
-		};
-
-		serial0: serial@4500 {
-			status = "disabled";
-		};
-
-		spi@7000 {
-			status = "disabled";
-		};
-
-		gpio: gpio-controller@f000 {
-			status = "disabled";
-		};
-
-		dma@21300 {
-			status = "disabled";
-		};
-
-		usb@22000 {
-			status = "disabled";
-		};
-
-		mdio@24520 {
-			status = "disabled";
-		};
-
-		mdio@25520 {
-			status = "disabled";
-		};
-
-		mdio@26520 {
-			status = "disabled";
-		};
-
-		enet1: ethernet@25000 {
-			status = "disabled";
-		};
-
-		enet2: ethernet@26000 {
-			status = "disabled";
-		};
-
-		sdhci@2e000 {
-			status = "disabled";
-		};
-
-		crypto@30000 {
-			status = "disabled";
-		};
-
-		mpic: pic@40000 {
-			protected-sources = <
-			17 18 43 42 59 47 /*ecm, mem, i2c, serial0, spi,gpio */
-			16 20 21 22 23 28 	/* L2, dma1, USB */
-			03 35 36 40 31 32 33 	/* mdio, enet1, enet2 */
-			72 45 58 25 		/* sdhci, crypto , pci */
-			>;
-		};
-
-		global-utilities@e0000 {	//global utilities block
-			status = "disabled";
-		};
-
-	};
-
-	pci0: pcie@ffe08000 {
-		status = "disabled";
-	};
-
-	pci1: pcie@ffe09000 {
-		status = "disabled";
-	};
-};
-- 
1.7.3.4

^ permalink raw reply related

* Re: Standalone SRIO Driver for Linux
From: Saravanan S @ 2012-07-14  6:24 UTC (permalink / raw)
  To: Bounine, Alexandre; +Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <8D983423E7EDF846BB3056827B8CC5D10285E9@corpmail1.na.ads.idt.com>

[-- Attachment #1: Type: text/plain, Size: 1939 bytes --]

Hi ,
     Thanks for the reply . i will try to share some of my code later .
Looking forward to ur ideas.

Regards,

S.Saravanan

On Fri, Jul 13, 2012 at 6:18 PM, Bounine, Alexandre <
Alexandre.Bounine@idt.com> wrote:

>  This should work. We use similar approach to test our mport HW drivers.**
> **
>
> ** **
>
> Alex.****
>
> ** **
>
> *From:* Linuxppc-dev [mailto:linuxppc-dev-bounces+alexandre.bounine=
> idt.com@lists.ozlabs.org] *On Behalf Of *Saravanan S
> *Sent:* Friday, July 13, 2012 2:16 AM
> *To:* linuxppc-dev@lists.ozlabs.org
> *Subject:* Standalone SRIO Driver for Linux****
>
> ** **
>
> Hi ,
>
>       Iam currently working on the GE make DSP230 board consisting of Quad
> PowerPC8640 nodes   interconnected by SRIO with Linux 2.6.34 . However the
> only way to access the SRIO is through rionet facility . Our requirement is
> to use the SRIO interconnect without the Ethernet overheads. This would
> definitely enable higher speeds (though I cant find any throughput figures
> for SRIO in Linux on the net ??? ).  My query is that whether any attempt
> has been made  to develop a  standalone driver and API to access the
> messaging  and doorbell services of SRIO . If no then request you to please
> provide inputs on the same. From my study I have the following thoughts for
> the driver :
>
> a) Have a character device interface for user .
> b) Basically use the rio support functions provided in rio.c like
> rio_add_inb_buffer ,  rio_add_outb_message to transfer and receive messages
> and add buffers .
> c) Maintain a dedicated ring of buffers in the driver and transfer  data
> to and from the buffer to user space .
>
>
> Is this the right direction . Would really appreciate any inputs . thanks
> in advance.
>
> Regards,
>
> S.Saravanan****
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>

[-- Attachment #2: Type: text/html, Size: 3843 bytes --]

^ permalink raw reply

* [PATCH] powerpc: SMT priority (PPR) save and restore
From: Haren Myneni @ 2012-07-14  9:43 UTC (permalink / raw)
  To: benh, paulus, anton; +Cc: linuxppc-dev

powerpc: SMT priority (PPR) save and restore
    
On P7 systems, users can define SMT priority levels 2,3 and 4 for
processes so that some can run higher priority than the other ones.
In the current kernel, the default priority is set to 4 which prohibits
processes to use higher priority. Also the kernel boosts the priority to
4 during exception without saving the user defined priority values when
the task enters the kernel. So we will be loosing the process PPR value
and can not be restored it back when the task exits the kernel.
    
This patch sets the default priority to 3 when tasks are created such
that users can use 4 for higher priority tasks. It also provides to save
and restore the user defined priorities for all tasks.
    
When the task enters in to kernel space, the user defined priority (PPR)
will be saved in to PACA at the beginning of first level exception
vector and then copy from PACA to thread_info in second level vector.
PPR will be restored from thread_info before exits the kernel space.
    
P7 temporarily raises the thread priority to higher level during
exception until the program executes HMT_* calls. But it will not modify
PPR register. So we saves PPR value whenever some register is available
to use and then calls HMT_MEDIUM to increase the priority. This feature
supports on P7 or later processors.
    
Signed-off-by: Haren Myneni <hbabu@us.ibm.com>

diff --git a/arch/powerpc/include/asm/cputable.h
b/arch/powerpc/include/asm/cputable.h
index 50d82c8..e7b80d6 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -203,6 +203,7 @@ extern const char *powerpc_base_platform;
 #define CPU_FTR_POPCNTD			LONG_ASM_CONST(0x0800000000000000)
 #define CPU_FTR_ICSWX			LONG_ASM_CONST(0x1000000000000000)
 #define CPU_FTR_VMX_COPY		LONG_ASM_CONST(0x2000000000000000)
+#define CPU_FTR_HAS_PPR			LONG_ASM_CONST(0x4000000000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -432,7 +433,8 @@ extern const char *powerpc_base_platform;
 	    CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
 	    CPU_FTR_DSCR | CPU_FTR_SAO  | CPU_FTR_ASYM_SMT | \
 	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD |
\
-	    CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY)
+	    CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY |
\
+	    CPU_FTR_HAS_PPR)
 #define CPU_FTRS_CELL	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
 	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
diff --git a/arch/powerpc/include/asm/exception-64s.h
b/arch/powerpc/include/asm/exception-64s.h
index d58fc4e..1fae8aa 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -47,6 +47,7 @@
 #define EX_R3		64
 #define EX_LR		72
 #define EX_CFAR		80
+#define EX_PPR		88	/* SMT thread status register (priority) */
 
 /*
  * We're short on space and time in the exception prolog, so we can't
@@ -61,10 +62,46 @@
 #define EXC_HV	H
 #define EXC_STD
 
+/* 
+ * PPR save/restore macros - Used only on P7 or later processors
+ */
+#define SAVE_PPR(area, ra, rb)
\
+BEGIN_FTR_SECTION_NESTED(940)
\
+       ld      ra,area+EX_PPR(r13);    /* Read PPR from paca */
\
+       clrrdi  rb,r1,THREAD_SHIFT;     /* thread_info struct */
\
+       std     ra,TI_PPR(rb);          /* Save PPR in thread_info */
\
+END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,940)
+
+#define RESTORE_PPR(ra,rb)
\
+BEGIN_FTR_SECTION_NESTED(941)
\
+       clrrdi  ra,r1,THREAD_SHIFT;
\
+       ld      rb,TI_PPR(ra);          /* Read PPR from thread_info */
\
+       mtspr   SPRN_PPR,rb;            /* Restore PPR */
\
+END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,941)
+
+#define RESTORE_PPR_PACA(area,ra)
\
+BEGIN_FTR_SECTION_NESTED(942)
\
+       ld      ra,area+EX_PPR(r13);
\
+       mtspr   SPRN_PPR,ra;
\
+END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,942)
+
+#define HMT_FTR_NO_PPR
\
+BEGIN_FTR_SECTION_NESTED(944)					       \
+       HMT_MEDIUM;
\
+END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,0,944) 	/*non P7*/
+
+#define HMT_FTR_HAS_PPR(area, ra)
\
+BEGIN_FTR_SECTION_NESTED(943)
\
+       mfspr   ra,SPRN_PPR;            /* Read PPR */
\
+       std     ra,area+EX_PPR(r13);    /* Save PPR in paca */
\
+       HMT_MEDIUM;
\
+END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,943) /* P7 */
+
 #define __EXCEPTION_PROLOG_1(area, extra, vec)				\
 	GET_PACA(r13);							\
-	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
-	std	r10,area+EX_R10(r13);					\
+	std	r9,area+EX_R9(r13);	/* save r9 */			\
+	HMT_FTR_HAS_PPR(area,r9); 					\
+	std	r10,area+EX_R10(r13);	/* save r10 - r12 */		\
 	BEGIN_FTR_SECTION_NESTED(66);					\
 	mfspr	r10,SPRN_CFAR;						\
 	std	r10,area+EX_CFAR(r13);					\
@@ -176,8 +213,10 @@ do_kvm_##n:								\
 	std	r10,0(r1);		/* make stack chain pointer	*/ \
 	std	r0,GPR0(r1);		/* save r0 in stackframe	*/ \
 	std	r10,GPR1(r1);		/* save r1 in stackframe	*/ \
+	beq	4f;							   \
 	ACCOUNT_CPU_USER_ENTRY(r9, r10);				   \
-	std	r2,GPR2(r1);		/* save r2 in stackframe	*/ \
+	SAVE_PPR(area, r9, r10);					   \
+4:	std	r2,GPR2(r1);		/* save r2 in stackframe	*/ \
 	SAVE_4GPRS(3, r1);		/* save r3 - r6 in stackframe	*/ \
 	SAVE_2GPRS(7, r1);		/* save r7, r8 in stackframe	*/ \
 	ld	r9,area+EX_R9(r13);	/* move r9, r10 to stackframe	*/ \
@@ -218,7 +257,7 @@ do_kvm_##n:								\
 	. = loc;					\
 	.globl label##_pSeries;				\
 label##_pSeries:					\
-	HMT_MEDIUM;					\
+	HMT_FTR_NO_PPR; 				\
 	SET_SCRATCH0(r13);		/* save r13 */		\
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common,	\
 				 EXC_STD, KVMTEST_PR, vec)
@@ -227,7 +266,7 @@ label##_pSeries:					\
 	. = loc;					\
 	.globl label##_hv;				\
 label##_hv:						\
-	HMT_MEDIUM;					\
+	HMT_FTR_NO_PPR; 				\
 	SET_SCRATCH0(r13);	/* save r13 */			\
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common,	\
 				 EXC_HV, KVMTEST, vec)
@@ -258,7 +297,7 @@ label##_hv:						\
 	_SOFTEN_TEST(EXC_STD, vec)
 
 #define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra)		\
-	HMT_MEDIUM;							\
+	HMT_FTR_NO_PPR;  						\
 	SET_SCRATCH0(r13);    /* save r13 */				\
 	__EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec);		\
 	EXCEPTION_PROLOG_PSERIES_1(label##_common, h);
diff --git a/arch/powerpc/include/asm/paca.h
b/arch/powerpc/include/asm/paca.h
index daf813f..d32b1e5 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -93,9 +93,9 @@ struct paca_struct {
 	 * Now, starting in cacheline 2, the exception save areas
 	 */
 	/* used for most interrupts/exceptions */
-	u64 exgen[11] __attribute__((aligned(0x80)));
-	u64 exmc[11];		/* used for machine checks */
-	u64 exslb[11];		/* used for SLB/segment table misses
+	u64 exgen[12] __attribute__((aligned(0x80)));
+	u64 exmc[12];		/* used for machine checks */
+	u64 exslb[12];		/* used for SLB/segment table misses
  				 * on the linear mapping */
 	/* SLB related definitions */
 	u16 vmalloc_sllp;
diff --git a/arch/powerpc/include/asm/ppc_asm.h
b/arch/powerpc/include/asm/ppc_asm.h
index 1544420..b5437a2 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -30,7 +30,6 @@
 #define ACCOUNT_STOLEN_TIME
 #else
 #define ACCOUNT_CPU_USER_ENTRY(ra, rb)					\
-	beq	2f;			/* if from kernel mode */	\
 	MFTB(ra);			/* get timebase */		\
 	ld	rb,PACA_STARTTIME_USER(r13);				\
 	std	ra,PACA_STARTTIME(r13);					\
@@ -38,7 +37,6 @@
 	ld	ra,PACA_USER_TIME(r13);					\
 	add	ra,ra,rb;		/* add on to user time */	\
 	std	ra,PACA_USER_TIME(r13);					\
-2:
 
 #define ACCOUNT_CPU_USER_EXIT(ra, rb)					\
 	MFTB(ra);			/* get timebase */		\
diff --git a/arch/powerpc/include/asm/reg.h
b/arch/powerpc/include/asm/reg.h
index f0cb7f4..1e61116 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -284,6 +284,7 @@
 #define SPRN_DBAT6U	0x23C	/* Data BAT 6 Upper Register */
 #define SPRN_DBAT7L	0x23F	/* Data BAT 7 Lower Register */
 #define SPRN_DBAT7U	0x23E	/* Data BAT 7 Upper Register */
+#define SPRN_PPR	0x380	/* Local SMT Thread status resgiter */
 
 #define SPRN_DEC	0x016		/* Decrement Register */
 #define SPRN_DER	0x095		/* Debug Enable Regsiter */
diff --git a/arch/powerpc/include/asm/thread_info.h
b/arch/powerpc/include/asm/thread_info.h
index 68831e9..618e35c 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -40,10 +40,22 @@ struct thread_info {
 	struct restart_block restart_block;
 	unsigned long	local_flags;		/* private flags for thread */
 
+#ifdef CONFIG_PPC64
+	unsigned long	ppr;			/* SMT Thread status register */
+#endif
 	/* low level flags - has atomic operations done on it */
 	unsigned long	flags ____cacheline_aligned_in_smp;
 };
 
+#ifdef CONFIG_PPC64
+/* Default SMT priority to (11- 13bits). */
+/* .ppr is Used to save/restore only on P7 or later */
+#define INIT_PPR \
+	.ppr =  (3ull << 50),
+#else
+#define INIT_PPR 
+#endif
+
 /*
  * macros/functions for gaining access to the thread information
structure
  */
@@ -56,6 +68,7 @@ struct thread_info {
 	.restart_block = {			\
 		.fn = do_no_restart_syscall,	\
 	},					\
+	INIT_PPR				\
 	.flags =	0,			\
 }
 
diff --git a/arch/powerpc/kernel/asm-offsets.c
b/arch/powerpc/kernel/asm-offsets.c
index 52c7ad7..0b3a5fe 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -127,6 +127,7 @@ int main(void)
 	DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
 
 #ifdef CONFIG_PPC64
+	DEFINE(TI_PPR,  offsetof(struct thread_info, ppr));
 	DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
 	DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches,
log_dline_size));
 	DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct ppc64_caches,
dlines_per_page));
diff --git a/arch/powerpc/kernel/entry_64.S
b/arch/powerpc/kernel/entry_64.S
index 5971c85..671a3db 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -33,6 +33,7 @@
 #include <asm/irqflags.h>
 #include <asm/ftrace.h>
 #include <asm/hw_irq.h>
+#include <asm/exception-64s.h> /* SAVE_PPR and RESTORE_PPR */
 
 /*
  * System calls.
@@ -62,8 +63,10 @@ system_call_common:
 	std	r12,_MSR(r1)
 	std	r0,GPR0(r1)
 	std	r10,GPR1(r1)
+	beq	2f
 	ACCOUNT_CPU_USER_ENTRY(r10, r11)
-	std	r2,GPR2(r1)
+	SAVE_PPR(PACA_EXGEN, r10, r11)  
+2:	std	r2,GPR2(r1)
 	std	r3,GPR3(r1)
 	mfcr	r2
 	std	r4,GPR4(r1)
@@ -228,6 +231,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
 
 	beq-	1f
 	ACCOUNT_CPU_USER_EXIT(r11, r12)
+	RESTORE_PPR(r11, r12)		
 	ld	r13,GPR13(r1)	/* only restore r13 if returning to usermode */
 1:	ld	r2,GPR2(r1)
 	ld	r1,GPR1(r1)
@@ -698,6 +702,7 @@ fast_exception_return:
 	andi.	r0,r3,MSR_PR
 	beq	1f
 	ACCOUNT_CPU_USER_EXIT(r2, r4)
+	RESTORE_PPR(r2, r4)		
 	REST_GPR(13, r1)
 1:
 	mtspr	SPRN_SRR1,r3
diff --git a/arch/powerpc/kernel/exceptions-64s.S
b/arch/powerpc/kernel/exceptions-64s.S
index 1c06d29..c3bddf8 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -40,7 +40,7 @@ __start_interrupts:
 
 	.globl system_reset_pSeries;
 system_reset_pSeries:
-	HMT_MEDIUM;
+	HMT_FTR_NO_PPR  
 	SET_SCRATCH0(r13)
 #ifdef CONFIG_PPC_P7_NAP
 BEGIN_FTR_SECTION
@@ -94,7 +94,7 @@ machine_check_pSeries_1:
 	. = 0x300
 	.globl data_access_pSeries
 data_access_pSeries:
-	HMT_MEDIUM
+	HMT_FTR_NO_PPR
 	SET_SCRATCH0(r13)
 BEGIN_FTR_SECTION
 	b	data_access_check_stab
@@ -106,7 +106,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB)
 	. = 0x380
 	.globl data_access_slb_pSeries
 data_access_slb_pSeries:
-	HMT_MEDIUM
+	HMT_FTR_NO_PPR  
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST, 0x380)
 	std	r3,PACA_EXSLB+EX_R3(r13)
@@ -137,7 +137,7 @@ data_access_slb_pSeries:
 	. = 0x480
 	.globl instruction_access_slb_pSeries
 instruction_access_slb_pSeries:
-	HMT_MEDIUM
+	HMT_FTR_NO_PPR  
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x480)
 	std	r3,PACA_EXSLB+EX_R3(r13)
@@ -197,7 +197,7 @@ hardware_interrupt_hv:
 	. = 0xc00
 	.globl	system_call_pSeries
 system_call_pSeries:
-	HMT_MEDIUM
+	HMT_FTR_NO_PPR  
 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
 	SET_SCRATCH0(r13)
 	GET_PACA(r13)
@@ -213,6 +213,7 @@ BEGIN_FTR_SECTION
 END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
 	mr	r9,r13
 	GET_PACA(r13)
+	HMT_FTR_HAS_PPR(PACA_EXGEN,r10)
 	mfspr	r11,SPRN_SRR0
 	mfspr	r12,SPRN_SRR1
 	ld	r10,PACAKBASE(r13)
@@ -295,7 +296,7 @@ vsx_unavailable_pSeries_1:
 machine_check_pSeries:
 	.globl machine_check_fwnmi
 machine_check_fwnmi:
-	HMT_MEDIUM
+	HMT_FTR_NO_PPR  
 	SET_SCRATCH0(r13)		/* save r13 */
 	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common,
 				 EXC_STD, KVMTEST, 0x200)
@@ -417,7 +418,7 @@ _GLOBAL(__replay_interrupt)
 	.globl system_reset_fwnmi
       .align 7
 system_reset_fwnmi:
-	HMT_MEDIUM
+	HMT_FTR_NO_PPR  
 	SET_SCRATCH0(r13)		/* save r13 */
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD,
 				 NOTEST, 0x100)
@@ -717,7 +718,8 @@ _GLOBAL(slb_miss_realmode)
 	mtcrf	0x80,r9
 	mtcrf	0x01,r9		/* slb_allocate uses cr0 and cr7 */
 .machine	pop
-
+	
+	RESTORE_PPR_PACA(PACA_EXSLB,r9)		
 	ld	r9,PACA_EXSLB+EX_R9(r13)
 	ld	r10,PACA_EXSLB+EX_R10(r13)
 	ld	r11,PACA_EXSLB+EX_R11(r13)
@@ -1048,7 +1050,7 @@ initial_stab:
 
 #ifdef CONFIG_PPC_POWERNV
 _GLOBAL(opal_mc_secondary_handler)
-	HMT_MEDIUM
+	HMT_FTR_NO_PPR  
 	SET_SCRATCH0(r13)
 	GET_PACA(r13)
 	clrldi	r3,r3,2

^ permalink raw reply related

* Re: [PATCH 6/6] hrtimer: Update hrtimer base offsets each hrtimer_interrupt
From: Andreas Schwab @ 2012-07-15 15:22 UTC (permalink / raw)
  To: John Stultz
  Cc: Prarit Bhargava, Peter Zijlstra, Linux Kernel, stable,
	Thomas Gleixner, linuxppc-dev, Ingo Molnar
In-Reply-To: <1341960205-56738-8-git-send-email-johnstul@us.ibm.com>

This breaks resume on the iBook G4 (PowerBook6,7).  Apparently during or
before noirq resume the system is hanging by the same amount of time as
the system was sleeping.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply

* Re: [PATCH 6/6] hrtimer: Update hrtimer base offsets each hrtimer_interrupt
From: Andreas Schwab @ 2012-07-15 16:02 UTC (permalink / raw)
  To: John Stultz
  Cc: Prarit Bhargava, Peter Zijlstra, Linux Kernel, stable,
	Thomas Gleixner, linuxppc-dev, Ingo Molnar
In-Reply-To: <m2y5mlnj5z.fsf__49536.0585897744$1342365803$gmane$org@igel.home>

Andreas Schwab <schwab@linux-m68k.org> writes:

> This breaks resume on the iBook G4 (PowerBook6,7).  Apparently during or
> before noirq resume the system is hanging by the same amount of time as
> the system was sleeping.

The point where the time is wasted actually appears to be _after_ resume
(the elapsed time for the resume itself isn't affected).

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply

* Re: [PATCH 6/6] hrtimer: Update hrtimer base offsets each hrtimer_interrupt
From: Rafael J. Wysocki @ 2012-07-15 20:28 UTC (permalink / raw)
  To: Andreas Schwab, John Stultz
  Cc: Prarit Bhargava, Peter Zijlstra, Linux PM list, Linux Kernel,
	stable, Thomas Gleixner, linuxppc-dev, Ingo Molnar
In-Reply-To: <m2y5mlnj5z.fsf@igel.home>

On Sunday, July 15, 2012, Andreas Schwab wrote:
> This breaks resume on the iBook G4 (PowerBook6,7).  Apparently during or
> before noirq resume the system is hanging by the same amount of time as
> the system was sleeping.

I'm able to reproduce this problem on Toshiba Portege R500 with similar
symptoms, although that box sometimes hangs hard during resume from system
suspend with the "caps lock" LED blinking.

Reverting the patch fixes the problem 100% of the time.

Thanks,
Rafael

^ permalink raw reply

* Re: [PATCH] ppc44x/watchdog: Select WATCHDOG_NOWAYOUT option
From: Lu.Jiang @ 2012-07-16  2:07 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <D5792F52-7BE6-4B86-A3FD-B756DE3A165D@kernel.crashing.org>

于 2012年07月13日 19:50, Kumar Gala 写道:
> On Jul 12, 2012, at 9:44 PM, Jiang Lu wrote:
>
>> On PPC44x core, the WRC(Watchdog-timer Reset Control) field of TCR
>> of timer can not reset by software after set to a non-zero value.
>> Which means software can not reset the timeout behaviour of watchdog timer.
>>
>> This patch selects WATCHDOG_NOWAYOUT option for 44x platforms to
>> indicate the watchdog timer can not be disabled once fired.
>>
>> Signed-off-by: Jiang Lu <lu.jiang@windriver.com>
>> ---
>> drivers/watchdog/Kconfig |    1 +
>> 1 files changed, 1 insertions(+), 0 deletions(-)
> I believe this is not 44x specific, but how Book-E watchdog is architected.
>
>> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
>> index 3709624..41f3dff 100644
>> --- a/drivers/watchdog/Kconfig
>> +++ b/drivers/watchdog/Kconfig
>> @@ -1084,6 +1084,7 @@ config PIKA_WDT
>> config BOOKE_WDT
>> 	tristate "PowerPC Book-E Watchdog Timer"
>> 	depends on BOOKE || 4xx
>> +	select WATCHDOG_NOWAYOUT if 44x
> This should probably be 'select WATCHDOG_NOWAYOUT if BOOKE'

On ppc44x's processor, if we disabled 'WATCHDOG_NOWAYOUT ' option. The 
driver's release routine will try to disable the watchdog , by clearing 
the WIE & WTDP field in TCR.
Since the ppc44x's watch dog can not reset by software, such operation 
only set the timeout value(WDTP) to minimum, and cause the system reboot 
immediately.

I checked ppc 476, 405 & 450's manual, these document said the 
WRC(Watchdog-timer Reset Control) field of TCR of timer
can not reset by software after set to a non-zero value. I think all 
ppc44x core should got same limitation.

While on FSL's platform, we did not met such issue. So I think we should 
select 'WATCHDOG_NOWAYOUT' option for 44x platform.

Regards,
Jiang Lu

>
>> 	---help---
>> 	  Watchdog driver for PowerPC Book-E chips, such as the Freescale
>> 	  MPC85xx SOCs and the IBM PowerPC 440.
>> -- 
>> 1.7.7
>>
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>

^ permalink raw reply

* Re: [RFC PATCH v3 4/13] memory-hotplug : remove /sys/firmware/memmap/X sysfs
From: Wen Congyang @ 2012-07-16  2:32 UTC (permalink / raw)
  To: Yasuaki Ishimatsu
  Cc: len.brown, linux-acpi, linux-kernel, linux-mm, paulus,
	minchan.kim, kosaki.motohiro, rientjes, cl, linuxppc-dev, akpm,
	liuj97
In-Reply-To: <4FFAB1BA.9040801@jp.fujitsu.com>

At 07/09/2012 06:26 PM, Yasuaki Ishimatsu Wrote:
> When (hot)adding memory into system, /sys/firmware/memmap/X/{end, start, type}
> sysfs files are created. But there is no code to remove these files. The patch
> implements the function to remove them.
> 
> Note : The code does not free firmware_map_entry since there is no way to free
>        memory which is allocated by bootmem.
> 
> CC: David Rientjes <rientjes@google.com>
> CC: Jiang Liu <liuj97@gmail.com>
> CC: Len Brown <len.brown@intel.com>
> CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> CC: Paul Mackerras <paulus@samba.org>
> CC: Christoph Lameter <cl@linux.com>
> Cc: Minchan Kim <minchan.kim@gmail.com>
> CC: Andrew Morton <akpm@linux-foundation.org>
> CC: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
> CC: Wen Congyang <wency@cn.fujitsu.com>
> Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
> 
> ---
>  drivers/firmware/memmap.c    |   78 ++++++++++++++++++++++++++++++++++++++++++-
>  include/linux/firmware-map.h |    6 +++
>  mm/memory_hotplug.c          |    6 ++-
>  3 files changed, 88 insertions(+), 2 deletions(-)
> 
> Index: linux-3.5-rc6/mm/memory_hotplug.c
> ===================================================================
> --- linux-3.5-rc6.orig/mm/memory_hotplug.c	2012-07-09 18:23:13.323844923 +0900
> +++ linux-3.5-rc6/mm/memory_hotplug.c	2012-07-09 18:23:19.522767424 +0900
> @@ -661,7 +661,11 @@ EXPORT_SYMBOL_GPL(add_memory);
> 
>  int remove_memory(int nid, u64 start, u64 size)
>  {
> -	return -EBUSY;
> +	lock_memory_hotplug();
> +	/* remove memmap entry */
> +	firmware_map_remove(start, start + size - 1, "System RAM");
> +	unlock_memory_hotplug();
> +	return 0;
> 
>  }
>  EXPORT_SYMBOL_GPL(remove_memory);
> Index: linux-3.5-rc6/include/linux/firmware-map.h
> ===================================================================
> --- linux-3.5-rc6.orig/include/linux/firmware-map.h	2012-07-09 18:23:09.532892314 +0900
> +++ linux-3.5-rc6/include/linux/firmware-map.h	2012-07-09 18:23:19.523767412 +0900
> @@ -25,6 +25,7 @@
> 
>  int firmware_map_add_early(u64 start, u64 end, const char *type);
>  int firmware_map_add_hotplug(u64 start, u64 end, const char *type);
> +int firmware_map_remove(u64 start, u64 end, const char *type);
> 
>  #else /* CONFIG_FIRMWARE_MEMMAP */
> 
> @@ -38,6 +39,11 @@ static inline int firmware_map_add_hotpl
>  	return 0;
>  }
> 
> +static inline int firmware_map_remove(u64 start, u64 end, const char *type)
> +{
> +	return 0;
> +}
> +
>  #endif /* CONFIG_FIRMWARE_MEMMAP */
> 
>  #endif /* _LINUX_FIRMWARE_MAP_H */
> Index: linux-3.5-rc6/drivers/firmware/memmap.c
> ===================================================================
> --- linux-3.5-rc6.orig/drivers/firmware/memmap.c	2012-07-09 18:23:09.532892314 +0900
> +++ linux-3.5-rc6/drivers/firmware/memmap.c	2012-07-09 18:25:46.371931554 +0900
> @@ -21,6 +21,7 @@
>  #include <linux/types.h>
>  #include <linux/bootmem.h>
>  #include <linux/slab.h>
> +#include <linux/mm.h>
> 
>  /*
>   * Data types ------------------------------------------------------------------
> @@ -79,7 +80,22 @@ static const struct sysfs_ops memmap_att
>  	.show = memmap_attr_show,
>  };
> 
> +#define to_memmap_entry(obj) container_of(obj, struct firmware_map_entry, kobj)
> +
> +static void release_firmware_map_entry(struct kobject *kobj)
> +{
> +	struct firmware_map_entry *entry = to_memmap_entry(kobj);
> +	struct page *head_page;
> +
> +	head_page = virt_to_head_page(entry);
> +	if (PageSlab(head_page))
> +		kfree(entry);
> +
> +	/* There is no way to free memory allocated from bootmem*/
> +}
> +
>  static struct kobj_type memmap_ktype = {
> +	.release	= release_firmware_map_entry,
>  	.sysfs_ops	= &memmap_attr_ops,
>  	.default_attrs	= def_attrs,
>  };
> @@ -123,6 +139,16 @@ static int firmware_map_add_entry(u64 st
>  	return 0;
>  }
> 
> +/**
> + * firmware_map_remove_entry() - Does the real work to remove a firmware
> + * memmap entry.
> + * @entry: removed entry.
> + **/
> +static inline void firmware_map_remove_entry(struct firmware_map_entry *entry)
> +{
> +	list_del(&entry->list);
> +}
> +
>  /*
>   * Add memmap entry on sysfs
>   */
> @@ -144,6 +170,31 @@ static int add_sysfs_fw_map_entry(struct
>  	return 0;
>  }
> 
> +/*
> + * Remove memmap entry on sysfs
> + */
> +static inline void remove_sysfs_fw_map_entry(struct firmware_map_entry *entry)
> +{
> +	kobject_put(&entry->kobj);
> +}
> +
> +/*
> + * Search memmap entry
> + */
> +
> +struct firmware_map_entry * __meminit
> +find_firmware_map_entry(u64 start, u64 end, const char *type)
> +{
> +	struct firmware_map_entry *entry;
> +
> +	list_for_each_entry(entry, &map_entries, list)
> +		if ((entry->start == start) && (entry->end == end) &&
> +		    (!strcmp(entry->type, type)))
> +			return entry;
> +
> +	return NULL;
> +}
> +
>  /**
>   * firmware_map_add_hotplug() - Adds a firmware mapping entry when we do
>   * memory hotplug.
> @@ -196,6 +247,32 @@ int __init firmware_map_add_early(u64 st
>  	return firmware_map_add_entry(start, end, type, entry);
>  }
> 
> +/**
> + * firmware_map_remove() - remove a firmware mapping entry
> + * @start: Start of the memory range.
> + * @end:   End of the memory range (inclusive).
> + * @type:  Type of the memory range.
> + *
> + * removes a firmware mapping entry.
> + *
> + * Returns 0 on success, or -EINVAL if no entry.
> + **/
> +int __meminit firmware_map_remove(u64 start, u64 end, const char *type)
> +{
> +	struct firmware_map_entry *entry;
> +
> +	entry = find_firmware_map_entry(start, end, type);
> +	if (!entry)
> +		return -EINVAL;
> +
> +	/* remove the memmap entry */
> +	remove_sysfs_fw_map_entry(entry);
> +
> +	firmware_map_remove_entry(entry);

You should call firmware_map_remove_entry() before remove_sysfs_fw_map_entry(),
otherwise it will cause kernel panicked(entry may be freed in remove_sysfs_fw_map_entry()).

Thanks
Wen Congyang

> +
> +	return 0;
> +}
> +
>  /*
>   * Sysfs functions -------------------------------------------------------------
>   */
> @@ -218,7 +295,6 @@ static ssize_t type_show(struct firmware
>  }
> 
>  #define to_memmap_attr(_attr) container_of(_attr, struct memmap_attribute, attr)
> -#define to_memmap_entry(obj) container_of(obj, struct firmware_map_entry, kobj)
> 
>  static ssize_t memmap_attr_show(struct kobject *kobj,
>  				struct attribute *attr, char *buf)
> 
> 

^ permalink raw reply

* [PATCH V3] powerpc/85xx: Add machine check handler to fix PCIe erratum on mpc85xx
From: Jia Hongtao @ 2012-07-16  2:45 UTC (permalink / raw)
  To: linuxppc-dev, galak; +Cc: b38951

A PCIe erratum of mpc85xx may causes a core hang when a link of PCIe
goes down. when the link goes down, Non-posted transactions issued
via the ATMU requiring completion result in an instruction stall.
At the same time a machine-check exception is generated to the core
to allow further processing by the handler. We implements the handler
which skips the instruction caused the stall.

Signed-off-by: Zhao Chenhui <b35336@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
Signed-off-by: Liu Shuo <soniccat.liu@gmail.com>
Signed-off-by: Jia Hongtao <B38951@freescale.com>
---
V3 changed: Just rebase the patch.

 arch/powerpc/kernel/cpu_setup_fsl_booke.S |    2 +-
 arch/powerpc/kernel/traps.c               |    3 ++
 arch/powerpc/sysdev/fsl_pci.c             |   39 +++++++++++++++++++++++++++++
 arch/powerpc/sysdev/fsl_pci.h             |    6 ++++
 4 files changed, 49 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
index 69fdd23..9c4b768 100644
--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -64,7 +64,7 @@ _GLOBAL(__setup_cpu_e500v2)
 	bl	__e500_icache_setup
 	bl	__e500_dcache_setup
 	bl	__setup_e500_ivors
-#ifdef CONFIG_FSL_RIO
+#if defined(CONFIG_FSL_RIO) || defined(CONFIG_FSL_PCI)
 	/* Ensure that RFXE is set */
 	mfspr	r3,SPRN_HID1
 	oris	r3,r3,HID1_RFXE@h
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 1589723..096a1a1 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -59,6 +59,7 @@
 #include <asm/fadump.h>
 #include <asm/switch_to.h>
 #include <asm/debug.h>
+#include <sysdev/fsl_pci.h>
 
 #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
 int (*__debugger)(struct pt_regs *regs) __read_mostly;
@@ -555,6 +556,8 @@ int machine_check_e500(struct pt_regs *regs)
 	if (reason & MCSR_BUS_RBERR) {
 		if (fsl_rio_mcheck_exception(regs))
 			return 1;
+		if (fsl_pci_mcheck_exception(regs))
+			return 1;
 	}
 
 	printk("Machine check in kernel mode.\n");
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index a7b2a60..52f3b5d 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -30,6 +30,7 @@
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
 #include <asm/machdep.h>
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
@@ -808,6 +809,44 @@ u64 fsl_pci_immrbar_base(struct pci_controller *hose)
 	return 0;
 }
 
+static int is_in_pci_mem_space(phys_addr_t addr)
+{
+	struct pci_controller *hose;
+	struct resource *res;
+	int i;
+
+	list_for_each_entry(hose, &hose_list, list_node) {
+		if (!early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP))
+			continue;
+
+		for (i = 0; i < 3; i++) {
+			res = &hose->mem_resources[i];
+			if ((res->flags & IORESOURCE_MEM) &&
+				addr >= res->start && addr <= res->end)
+				return 1;
+		}
+	}
+	return 0;
+}
+
+int fsl_pci_mcheck_exception(struct pt_regs *regs)
+{
+	phys_addr_t addr = 0;
+
+#ifdef CONFIG_PHYS_64BIT
+	addr = mfspr(SPRN_MCARU);
+	addr <<= 32;
+#endif
+	addr += mfspr(SPRN_MCAR);
+
+	if (is_in_pci_mem_space(addr)) {
+		regs->nip += 4;
+		return 1;
+	}
+
+	return 0;
+}
+
 #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
 static const struct of_device_id pci_ids[] = {
 	{ .compatible = "fsl,mpc8540-pci", },
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index baa0fd1..efd1907 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -101,5 +101,11 @@ void fsl_pci_init(void);
 static inline void fsl_pci_init(void) {}
 #endif
 
+#ifdef CONFIG_FSL_PCI
+extern int fsl_pci_mcheck_exception(struct pt_regs *);
+#else
+static inline int fsl_pci_mcheck_exception(struct pt_regs *regs) {return 0; }
+#endif
+
 #endif /* __POWERPC_FSL_PCI_H */
 #endif /* __KERNEL__ */
-- 
1.7.5.1

^ permalink raw reply related

* [PATCH V3] powerpc/85xx: Add machine check handler to fix PCIe erratum on mpc85xx
From: Jia Hongtao @ 2012-07-16  2:59 UTC (permalink / raw)
  To: linuxppc-dev, galak; +Cc: b38951

A PCIe erratum of mpc85xx may causes a core hang when a link of PCIe
goes down. when the link goes down, Non-posted transactions issued
via the ATMU requiring completion result in an instruction stall.
At the same time a machine-check exception is generated to the core
to allow further processing by the handler. We implements the handler
which skips the instruction caused the stall.

Signed-off-by: Zhao Chenhui <b35336@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
Signed-off-by: Liu Shuo <soniccat.liu@gmail.com>
Signed-off-by: Jia Hongtao <B38951@freescale.com>
---
V3 changed:
1. Rebased the patch.
2. Only build fsl_pci_mcheck_exception on e500

 arch/powerpc/kernel/cpu_setup_fsl_booke.S |    2 +-
 arch/powerpc/kernel/traps.c               |    3 ++
 arch/powerpc/sysdev/fsl_pci.c             |   41 +++++++++++++++++++++++++++++
 arch/powerpc/sysdev/fsl_pci.h             |    6 ++++
 4 files changed, 51 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
index 69fdd23..9c4b768 100644
--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -64,7 +64,7 @@ _GLOBAL(__setup_cpu_e500v2)
 	bl	__e500_icache_setup
 	bl	__e500_dcache_setup
 	bl	__setup_e500_ivors
-#ifdef CONFIG_FSL_RIO
+#if defined(CONFIG_FSL_RIO) || defined(CONFIG_FSL_PCI)
 	/* Ensure that RFXE is set */
 	mfspr	r3,SPRN_HID1
 	oris	r3,r3,HID1_RFXE@h
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 1589723..096a1a1 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -59,6 +59,7 @@
 #include <asm/fadump.h>
 #include <asm/switch_to.h>
 #include <asm/debug.h>
+#include <sysdev/fsl_pci.h>
 
 #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
 int (*__debugger)(struct pt_regs *regs) __read_mostly;
@@ -555,6 +556,8 @@ int machine_check_e500(struct pt_regs *regs)
 	if (reason & MCSR_BUS_RBERR) {
 		if (fsl_rio_mcheck_exception(regs))
 			return 1;
+		if (fsl_pci_mcheck_exception(regs))
+			return 1;
 	}
 
 	printk("Machine check in kernel mode.\n");
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index a7b2a60..3a3e9c8 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -30,6 +30,7 @@
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
 #include <asm/machdep.h>
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
@@ -808,6 +809,46 @@ u64 fsl_pci_immrbar_base(struct pci_controller *hose)
 	return 0;
 }
 
+#ifdef CONFIG_E500
+static int is_in_pci_mem_space(phys_addr_t addr)
+{
+	struct pci_controller *hose;
+	struct resource *res;
+	int i;
+
+	list_for_each_entry(hose, &hose_list, list_node) {
+		if (!early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP))
+			continue;
+
+		for (i = 0; i < 3; i++) {
+			res = &hose->mem_resources[i];
+			if ((res->flags & IORESOURCE_MEM) &&
+				addr >= res->start && addr <= res->end)
+				return 1;
+		}
+	}
+	return 0;
+}
+
+int fsl_pci_mcheck_exception(struct pt_regs *regs)
+{
+	phys_addr_t addr = 0;
+
+#ifdef CONFIG_PHYS_64BIT
+	addr = mfspr(SPRN_MCARU);
+	addr <<= 32;
+#endif
+	addr += mfspr(SPRN_MCAR);
+
+	if (is_in_pci_mem_space(addr)) {
+		regs->nip += 4;
+		return 1;
+	}
+
+	return 0;
+}
+#endif
+
 #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
 static const struct of_device_id pci_ids[] = {
 	{ .compatible = "fsl,mpc8540-pci", },
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index baa0fd1..efd1907 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -101,5 +101,11 @@ void fsl_pci_init(void);
 static inline void fsl_pci_init(void) {}
 #endif
 
+#ifdef CONFIG_FSL_PCI
+extern int fsl_pci_mcheck_exception(struct pt_regs *);
+#else
+static inline int fsl_pci_mcheck_exception(struct pt_regs *regs) {return 0; }
+#endif
+
 #endif /* __POWERPC_FSL_PCI_H */
 #endif /* __KERNEL__ */
-- 
1.7.5.1

^ permalink raw reply related

* Re: [PATCH] powerpc: SMT priority (PPR) save and restore
From: Michael Neuling @ 2012-07-16  3:41 UTC (permalink / raw)
  To: Haren Myneni; +Cc: linuxppc-dev, paulus, anton
In-Reply-To: <1342259024.11305.38.camel@hbabu-laptop>

Heaven Myneni <haren@linux.vnet.ibm.com> wrote:

> powerpc: SMT priority (PPR) save and restore
>     
> On P7 systems, users can define SMT priority levels 2,3 and 4 for
> processes so that some can run higher priority than the other ones.
> In the current kernel, the default priority is set to 4 which prohibits
> processes to use higher priority. Also the kernel boosts the priority to
> 4 during exception without saving the user defined priority values when
> the task enters the kernel. So we will be loosing the process PPR value
> and can not be restored it back when the task exits the kernel.
>     
> This patch sets the default priority to 3 when tasks are created such
> that users can use 4 for higher priority tasks. It also provides to save
> and restore the user defined priorities for all tasks.
>     
> When the task enters in to kernel space, the user defined priority (PPR)
> will be saved in to PACA at the beginning of first level exception
> vector and then copy from PACA to thread_info in second level vector.
> PPR will be restored from thread_info before exits the kernel space.
>     
> P7 temporarily raises the thread priority to higher level during
> exception until the program executes HMT_* calls. But it will not modify
> PPR register. So we saves PPR value whenever some register is available
> to use and then calls HMT_MEDIUM to increase the priority. This feature
> supports on P7 or later processors.
>     
> Signed-off-by: Haren Myneni <hbabu@us.ibm.com>

Can you break this patch into a few parts that are easier to review than
one giant patch.  Start by adding the PPR ftr bits, then the extra space
in the paca, then the new macros, then use the new infrastructure.  I'm
sure you can get 5 or so patches which will be much easier to review.

Also this has been white space munged.  See here:
  http://patchwork.ozlabs.org/patch/170993/
All the #defines are broken.

Also, do you know what the impacts of this are on null syscall/page
faults etc on machines which need the PPR switched?  If it's big, we
might want to have this as a CONFIG option for those who don't care and
want the speed bump.

More comments below.

> 
> diff --git a/arch/powerpc/include/asm/cputable.h
> b/arch/powerpc/include/asm/cputable.h
> index 50d82c8..e7b80d6 100644
> --- a/arch/powerpc/include/asm/cputable.h
> +++ b/arch/powerpc/include/asm/cputable.h
> @@ -203,6 +203,7 @@ extern const char *powerpc_base_platform;
>  #define CPU_FTR_POPCNTD			LONG_ASM_CONST(0x0800000000000000)
>  #define CPU_FTR_ICSWX			LONG_ASM_CONST(0x1000000000000000)
>  #define CPU_FTR_VMX_COPY		LONG_ASM_CONST(0x2000000000000000)
> +#define CPU_FTR_HAS_PPR			LONG_ASM_CONST(0x4000000000000000)
>  
>  #ifndef __ASSEMBLY__
>  
> @@ -432,7 +433,8 @@ extern const char *powerpc_base_platform;
>  	    CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
>  	    CPU_FTR_DSCR | CPU_FTR_SAO  | CPU_FTR_ASYM_SMT | \
>  	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD |
> \
> -	    CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY)
> +	    CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY |
> \
> +	    CPU_FTR_HAS_PPR)

Add CPU_FTR_HAS_PPR to CPU_FTRS_POSSIBLE as well.


>  #define CPU_FTRS_CELL	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
>  	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
>  	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
> diff --git a/arch/powerpc/include/asm/exception-64s.h
> b/arch/powerpc/include/asm/exception-64s.h
> index d58fc4e..1fae8aa 100644
> --- a/arch/powerpc/include/asm/exception-64s.h
> +++ b/arch/powerpc/include/asm/exception-64s.h
> @@ -47,6 +47,7 @@
>  #define EX_R3		64
>  #define EX_LR		72
>  #define EX_CFAR		80
> +#define EX_PPR		88	/* SMT thread status register (priority) */
>  
>  /*
>   * We're short on space and time in the exception prolog, so we can't
> @@ -61,10 +62,46 @@
>  #define EXC_HV	H
>  #define EXC_STD
>  
> +/* 
> + * PPR save/restore macros - Used only on P7 or later processors
> + */
> +#define SAVE_PPR(area, ra, rb)
> \
> +BEGIN_FTR_SECTION_NESTED(940)
> \
> +       ld      ra,area+EX_PPR(r13);    /* Read PPR from paca */
> \
> +       clrrdi  rb,r1,THREAD_SHIFT;     /* thread_info struct */
> \
> +       std     ra,TI_PPR(rb);          /* Save PPR in thread_info */
> \
> +END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,940)
> +
> +#define RESTORE_PPR(ra,rb)
> \
> +BEGIN_FTR_SECTION_NESTED(941)
> \
> +       clrrdi  ra,r1,THREAD_SHIFT;
> \
> +       ld      rb,TI_PPR(ra);          /* Read PPR from thread_info */
> \
> +       mtspr   SPRN_PPR,rb;            /* Restore PPR */
> \
> +END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,941)
> +
> +#define RESTORE_PPR_PACA(area,ra)
> \
> +BEGIN_FTR_SECTION_NESTED(942)
> \
> +       ld      ra,area+EX_PPR(r13);
> \
> +       mtspr   SPRN_PPR,ra;
> \
> +END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,942)
> +
> +#define HMT_FTR_NO_PPR
> \
> +BEGIN_FTR_SECTION_NESTED(944)					       \
> +       HMT_MEDIUM;
> \
> +END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,0,944) 	/*non P7*/
> +
> +#define HMT_FTR_HAS_PPR(area, ra)
> \
> +BEGIN_FTR_SECTION_NESTED(943)
> \
> +       mfspr   ra,SPRN_PPR;            /* Read PPR */
> \
> +       std     ra,area+EX_PPR(r13);    /* Save PPR in paca */
> \
> +       HMT_MEDIUM;
> \
> +END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,943) /* P7 */

all munged.



> +
>  #define __EXCEPTION_PROLOG_1(area, extra, vec)				\
>  	GET_PACA(r13);							\
> -	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
> -	std	r10,area+EX_R10(r13);					\
> +	std	r9,area+EX_R9(r13);	/* save r9 */			\
> +	HMT_FTR_HAS_PPR(area,r9); 					\
> +	std	r10,area+EX_R10(r13);	/* save r10 - r12 */		\
>  	BEGIN_FTR_SECTION_NESTED(66);					\
>  	mfspr	r10,SPRN_CFAR;						\
>  	std	r10,area+EX_CFAR(r13);					\
> @@ -176,8 +213,10 @@ do_kvm_##n:								\
>  	std	r10,0(r1);		/* make stack chain pointer	*/ \
>  	std	r0,GPR0(r1);		/* save r0 in stackframe	*/ \
>  	std	r10,GPR1(r1);		/* save r1 in stackframe	*/ \
> +	beq	4f;							   \
>  	ACCOUNT_CPU_USER_ENTRY(r9, r10);				   \
> -	std	r2,GPR2(r1);		/* save r2 in stackframe	*/ \
> +	SAVE_PPR(area, r9, r10);					   \
> +4:	std	r2,GPR2(r1);		/* save r2 in stackframe	*/ \

why are we no longer doing ACCOUNT_CPU_USER_ENTRY here?



>  	SAVE_4GPRS(3, r1);		/* save r3 - r6 in stackframe	*/ \
>  	SAVE_2GPRS(7, r1);		/* save r7, r8 in stackframe	*/ \
>  	ld	r9,area+EX_R9(r13);	/* move r9, r10 to stackframe	*/ \
> @@ -218,7 +257,7 @@ do_kvm_##n:								\
>  	. = loc;					\
>  	.globl label##_pSeries;				\
>  label##_pSeries:					\
> -	HMT_MEDIUM;					\
> +	HMT_FTR_NO_PPR; 				\
>  	SET_SCRATCH0(r13);		/* save r13 */		\
>  	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common,	\
>  				 EXC_STD, KVMTEST_PR, vec)
> @@ -227,7 +266,7 @@ label##_pSeries:					\
>  	. = loc;					\
>  	.globl label##_hv;				\
>  label##_hv:						\
> -	HMT_MEDIUM;					\
> +	HMT_FTR_NO_PPR; 				\
>  	SET_SCRATCH0(r13);	/* save r13 */			\
>  	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common,	\
>  				 EXC_HV, KVMTEST, vec)
> @@ -258,7 +297,7 @@ label##_hv:						\
>  	_SOFTEN_TEST(EXC_STD, vec)
>  
>  #define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra)		\
> -	HMT_MEDIUM;							\
> +	HMT_FTR_NO_PPR;  						\
>  	SET_SCRATCH0(r13);    /* save r13 */				\
>  	__EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec);		\
>  	EXCEPTION_PROLOG_PSERIES_1(label##_common, h);
> diff --git a/arch/powerpc/include/asm/paca.h
> b/arch/powerpc/include/asm/paca.h
> index daf813f..d32b1e5 100644
> --- a/arch/powerpc/include/asm/paca.h
> +++ b/arch/powerpc/include/asm/paca.h
> @@ -93,9 +93,9 @@ struct paca_struct {
>  	 * Now, starting in cacheline 2, the exception save areas
>  	 */
>  	/* used for most interrupts/exceptions */
> -	u64 exgen[11] __attribute__((aligned(0x80)));
> -	u64 exmc[11];		/* used for machine checks */
> -	u64 exslb[11];		/* used for SLB/segment table misses
> +	u64 exgen[12] __attribute__((aligned(0x80)));
> +	u64 exmc[12];		/* used for machine checks */
> +	u64 exslb[12];		/* used for SLB/segment table misses
>   				 * on the linear mapping */
>  	/* SLB related definitions */
>  	u16 vmalloc_sllp;
> diff --git a/arch/powerpc/include/asm/ppc_asm.h
> b/arch/powerpc/include/asm/ppc_asm.h
> index 1544420..b5437a2 100644
> --- a/arch/powerpc/include/asm/ppc_asm.h
> +++ b/arch/powerpc/include/asm/ppc_asm.h
> @@ -30,7 +30,6 @@
>  #define ACCOUNT_STOLEN_TIME
>  #else
>  #define ACCOUNT_CPU_USER_ENTRY(ra, rb)					\
> -	beq	2f;			/* if from kernel mode */	\
>  	MFTB(ra);			/* get timebase */		\
>  	ld	rb,PACA_STARTTIME_USER(r13);				\
>  	std	ra,PACA_STARTTIME(r13);					\
> @@ -38,7 +37,6 @@
>  	ld	ra,PACA_USER_TIME(r13);					\
>  	add	ra,ra,rb;		/* add on to user time */	\
>  	std	ra,PACA_USER_TIME(r13);					\
> -2:

Why are you doing this?

>  
>  #define ACCOUNT_CPU_USER_EXIT(ra, rb)					\
>  	MFTB(ra);			/* get timebase */		\
> diff --git a/arch/powerpc/include/asm/reg.h
> b/arch/powerpc/include/asm/reg.h
> index f0cb7f4..1e61116 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -284,6 +284,7 @@
>  #define SPRN_DBAT6U	0x23C	/* Data BAT 6 Upper Register */
>  #define SPRN_DBAT7L	0x23F	/* Data BAT 7 Lower Register */
>  #define SPRN_DBAT7U	0x23E	/* Data BAT 7 Upper Register */
> +#define SPRN_PPR	0x380	/* Local SMT Thread status resgiter */

spelling mistake here

>  
>  #define SPRN_DEC	0x016		/* Decrement Register */
>  #define SPRN_DER	0x095		/* Debug Enable Regsiter */
> diff --git a/arch/powerpc/include/asm/thread_info.h
> b/arch/powerpc/include/asm/thread_info.h
> index 68831e9..618e35c 100644
> --- a/arch/powerpc/include/asm/thread_info.h
> +++ b/arch/powerpc/include/asm/thread_info.h
> @@ -40,10 +40,22 @@ struct thread_info {
>  	struct restart_block restart_block;
>  	unsigned long	local_flags;		/* private flags for thread */
>  
> +#ifdef CONFIG_PPC64
> +	unsigned long	ppr;			/* SMT Thread status register */
> +#endif



>  	/* low level flags - has atomic operations done on it */
>  	unsigned long	flags ____cacheline_aligned_in_smp;
>  };
>  
> +#ifdef CONFIG_PPC64
> +/* Default SMT priority to (11- 13bits). */
> +/* .ppr is Used to save/restore only on P7 or later */
> +#define INIT_PPR \
> +	.ppr =  (3ull << 50),
> +#else
> +#define INIT_PPR 
> +#endif
> +




>  /*
>   * macros/functions for gaining access to the thread information
> structure
>   */
> @@ -56,6 +68,7 @@ struct thread_info {
>  	.restart_block = {			\
>  		.fn = do_no_restart_syscall,	\
>  	},					\
> +	INIT_PPR				\
>  	.flags =	0,			\
>  }
>  
> diff --git a/arch/powerpc/kernel/asm-offsets.c
> b/arch/powerpc/kernel/asm-offsets.c
> index 52c7ad7..0b3a5fe 100644
> --- a/arch/powerpc/kernel/asm-offsets.c
> +++ b/arch/powerpc/kernel/asm-offsets.c
> @@ -127,6 +127,7 @@ int main(void)
>  	DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
>  
>  #ifdef CONFIG_PPC64
> +	DEFINE(TI_PPR,  offsetof(struct thread_info, ppr));
>  	DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
>  	DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches,
> log_dline_size));
>  	DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct ppc64_caches,
> dlines_per_page));
> diff --git a/arch/powerpc/kernel/entry_64.S
> b/arch/powerpc/kernel/entry_64.S
> index 5971c85..671a3db 100644
> --- a/arch/powerpc/kernel/entry_64.S
> +++ b/arch/powerpc/kernel/entry_64.S
> @@ -33,6 +33,7 @@
>  #include <asm/irqflags.h>
>  #include <asm/ftrace.h>
>  #include <asm/hw_irq.h>
> +#include <asm/exception-64s.h> /* SAVE_PPR and RESTORE_PPR */

No need for the comment here

>  
>  /*
>   * System calls.
> @@ -62,8 +63,10 @@ system_call_common:
>  	std	r12,_MSR(r1)
>  	std	r0,GPR0(r1)
>  	std	r10,GPR1(r1)
> +	beq	2f
>  	ACCOUNT_CPU_USER_ENTRY(r10, r11)
> -	std	r2,GPR2(r1)
> +	SAVE_PPR(PACA_EXGEN, r10, r11)  
> +2:	std	r2,GPR2(r1)

anyway, why are we skipping this code

>  	std	r3,GPR3(r1)
>  	mfcr	r2
>  	std	r4,GPR4(r1)
> @@ -228,6 +231,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
>  
>  	beq-	1f
>  	ACCOUNT_CPU_USER_EXIT(r11, r12)
> +	RESTORE_PPR(r11, r12)		
>  	ld	r13,GPR13(r1)	/* only restore r13 if returning to usermode */
>  1:	ld	r2,GPR2(r1)
>  	ld	r1,GPR1(r1)
> @@ -698,6 +702,7 @@ fast_exception_return:
>  	andi.	r0,r3,MSR_PR
>  	beq	1f
>  	ACCOUNT_CPU_USER_EXIT(r2, r4)
> +	RESTORE_PPR(r2, r4)		
>  	REST_GPR(13, r1)
>  1:
>  	mtspr	SPRN_SRR1,r3
> diff --git a/arch/powerpc/kernel/exceptions-64s.S
> b/arch/powerpc/kernel/exceptions-64s.S
> index 1c06d29..c3bddf8 100644
> --- a/arch/powerpc/kernel/exceptions-64s.S
> +++ b/arch/powerpc/kernel/exceptions-64s.S
> @@ -40,7 +40,7 @@ __start_interrupts:
>  
>  	.globl system_reset_pSeries;
>  system_reset_pSeries:
> -	HMT_MEDIUM;
> +	HMT_FTR_NO_PPR  

Can we call this something else like HMT_MEDIUM_NO_PPR?



>  	SET_SCRATCH0(r13)
>  #ifdef CONFIG_PPC_P7_NAP
>  BEGIN_FTR_SECTION
> @@ -94,7 +94,7 @@ machine_check_pSeries_1:
>  	. = 0x300
>  	.globl data_access_pSeries
>  data_access_pSeries:
> -	HMT_MEDIUM
> +	HMT_FTR_NO_PPR
>  	SET_SCRATCH0(r13)
>  BEGIN_FTR_SECTION
>  	b	data_access_check_stab
> @@ -106,7 +106,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB)
>  	. = 0x380
>  	.globl data_access_slb_pSeries
>  data_access_slb_pSeries:
> -	HMT_MEDIUM
> +	HMT_FTR_NO_PPR  
>  	SET_SCRATCH0(r13)
>  	EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST, 0x380)
>  	std	r3,PACA_EXSLB+EX_R3(r13)
> @@ -137,7 +137,7 @@ data_access_slb_pSeries:
>  	. = 0x480
>  	.globl instruction_access_slb_pSeries
>  instruction_access_slb_pSeries:
> -	HMT_MEDIUM
> +	HMT_FTR_NO_PPR  
>  	SET_SCRATCH0(r13)
>  	EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x480)
>  	std	r3,PACA_EXSLB+EX_R3(r13)
> @@ -197,7 +197,7 @@ hardware_interrupt_hv:
>  	. = 0xc00
>  	.globl	system_call_pSeries
>  system_call_pSeries:
> -	HMT_MEDIUM
> +	HMT_FTR_NO_PPR  
>  #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
>  	SET_SCRATCH0(r13)
>  	GET_PACA(r13)
> @@ -213,6 +213,7 @@ BEGIN_FTR_SECTION
>  END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
>  	mr	r9,r13
>  	GET_PACA(r13)
> +	HMT_FTR_HAS_PPR(PACA_EXGEN,r10)
>  	mfspr	r11,SPRN_SRR0
>  	mfspr	r12,SPRN_SRR1
>  	ld	r10,PACAKBASE(r13)
> @@ -295,7 +296,7 @@ vsx_unavailable_pSeries_1:
>  machine_check_pSeries:
>  	.globl machine_check_fwnmi
>  machine_check_fwnmi:
> -	HMT_MEDIUM
> +	HMT_FTR_NO_PPR  
>  	SET_SCRATCH0(r13)		/* save r13 */
>  	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common,
>  				 EXC_STD, KVMTEST, 0x200)
> @@ -417,7 +418,7 @@ _GLOBAL(__replay_interrupt)
>  	.globl system_reset_fwnmi
>        .align 7
>  system_reset_fwnmi:
> -	HMT_MEDIUM
> +	HMT_FTR_NO_PPR  
>  	SET_SCRATCH0(r13)		/* save r13 */
>  	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD,
>  				 NOTEST, 0x100)
> @@ -717,7 +718,8 @@ _GLOBAL(slb_miss_realmode)
>  	mtcrf	0x80,r9
>  	mtcrf	0x01,r9		/* slb_allocate uses cr0 and cr7 */
>  .machine	pop
> -
> +	

Random whitespace change.

> +	RESTORE_PPR_PACA(PACA_EXSLB,r9)		
>  	ld	r9,PACA_EXSLB+EX_R9(r13)
>  	ld	r10,PACA_EXSLB+EX_R10(r13)
>  	ld	r11,PACA_EXSLB+EX_R11(r13)
> @@ -1048,7 +1050,7 @@ initial_stab:
>  
>  #ifdef CONFIG_PPC_POWERNV
>  _GLOBAL(opal_mc_secondary_handler)
> -	HMT_MEDIUM
> +	HMT_FTR_NO_PPR  
>  	SET_SCRATCH0(r13)
>  	GET_PACA(r13)
>  	clrldi	r3,r3,2
> 
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
> 

^ permalink raw reply

* [PATCH 1/2 v2] PCI: Add PCI_DEV_FLAGS_USE_NON_MSI_INTX_IRQ to enable non MSI/INTx interrupt
From: Shengzhou Liu @ 2012-07-16  3:31 UTC (permalink / raw)
  To: bhelgaas, linux-pci; +Cc: linuxppc-dev, Shengzhou Liu

On some platforms, in RC mode, root port has neither MSI/MSI-X nor INTx
interrupt generated, which are available only in EP mode on those platform.
In this case, we try to use other interrupt for port service driver to have
AER, Hot-plug, etc, services to work.

Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com>
---
v2: separated platform-specific part to arch/powerpc/sysdev.

 drivers/pci/pcie/portdrv_core.c |   10 ++++++++--
 drivers/pci/quirks.c            |    9 +++++++++
 include/linux/pci.h             |    5 +++++
 3 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 75915b3..837ad15 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -212,8 +212,14 @@ static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask)
 	if (!pcie_port_enable_msix(dev, irqs, mask))
 		return 0;
 
-	/* We're not going to use MSI-X, so try MSI and fall back to INTx */
-	if (!pci_enable_msi(dev) || dev->pin)
+	/*
+	 * We're not going to use MSI-X, so try MSI and fall back to INTx.
+	 * Eventually, if neither MSI/MSI-X nor INTx available, try other
+	 * interrupt. (On some platforms, root port doesn't support generating
+	 * MSI/MSI-X/INTx in RC mode)
+	 */
+	if (!pci_enable_msi(dev) || dev->pin || ((dev->dev_flags &
+			PCI_DEV_FLAGS_USE_NON_MSI_INTX_IRQ) && dev->irq))
 		irq = dev->irq;
 
  no_msi:
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 2a75216..2922cb8 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2640,6 +2640,15 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1083,
 			quirk_msi_intx_disable_bug);
 #endif /* CONFIG_PCI_MSI */
 
+/*
+ * Under some circumstances, root port has neither MSI/MSI-X nor INTx generated,
+ * so try other interrupt if supported.
+ */
+void __devinit quirk_enable_non_msi_intx_interrupt(struct pci_dev *dev)
+{
+	dev->dev_flags |= PCI_DEV_FLAGS_USE_NON_MSI_INTX_IRQ;
+}
+
 /* Allow manual resource allocation for PCI hotplug bridges
  * via pci=hpmemsize=nnM and pci=hpiosize=nnM parameters. For
  * some PCI-PCI hotplug bridges, like PLX 6254 (former HINT HB6),
diff --git a/include/linux/pci.h b/include/linux/pci.h
index d8c379d..f051a66 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -176,6 +176,11 @@ enum pci_dev_flags {
 	PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) 2,
 	/* Provide indication device is assigned by a Virtual Machine Manager */
 	PCI_DEV_FLAGS_ASSIGNED = (__force pci_dev_flags_t) 4,
+	/*
+	 * Use other interrupt (i.e. system shared interrupt) when MSI/MSI-X
+	 * and INTx are not supported in RC mode on some platforms.
+	 */
+	PCI_DEV_FLAGS_USE_NON_MSI_INTX_IRQ = (__force pci_dev_flags_t) 8,
 };
 
 enum pci_irq_reroute_variant {
-- 
1.6.4

^ permalink raw reply related

* [PATCH 2/2 v2] powerpc/fsl: PCI: add quirk_enable_non_msi_intx_interrupt
From: Shengzhou Liu @ 2012-07-16  3:31 UTC (permalink / raw)
  To: bhelgaas, linux-pci; +Cc: linuxppc-dev, Shengzhou Liu
In-Reply-To: <1342409487-28256-1-git-send-email-Shengzhou.Liu@freescale.com>

On current fsl powerpc platforms, the PCIe root port doesn't support
generating MSI/MSI-X and INTx interrupt in RC mode (those interrupts
are supported only in EP mode). So we use the shared error interrupt
by flag PCI_DEV_FLAGS_USE_NON_MSI_INTX_IRQ for PCIe port driver to
support AER, Hot-plug etc, services.

Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com>
---
v2: separated platform-specific part to arch/powerpc/sysdev.

 arch/powerpc/sysdev/fsl_pci.c |    2 ++
 arch/powerpc/sysdev/fsl_pci.h |    1 +
 2 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 6073288..fb8862f 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -498,6 +498,8 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
 #endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID,
+			quirk_enable_non_msi_intx_interrupt);
 
 #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x)
 struct mpc83xx_pcie_priv {
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index a39ed5c..a98c6d8 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -91,6 +91,7 @@ struct ccsr_pci {
 extern int fsl_add_bridge(struct device_node *dev, int is_primary);
 extern void fsl_pcibios_fixup_bus(struct pci_bus *bus);
 extern int mpc83xx_add_bridge(struct device_node *dev);
+extern void __devinit quirk_enable_non_msi_intx_interrupt(struct pci_dev *dev);
 u64 fsl_pci_immrbar_base(struct pci_controller *hose);
 
 #endif /* __POWERPC_FSL_PCI_H */
-- 
1.6.4

^ permalink raw reply related

* [PATCH] powerpc/85xx: workaround for chips with MSI hareware errata to support MSI-X
From: Jia Hongtao @ 2012-07-16  3:35 UTC (permalink / raw)
  To: linuxppc-dev, galak; +Cc: soniccat.liu, b38951

From: Liu Shuo <soniccat.liu@gmail.com>

The MPIC chip with version 2.0 has a MSI errata (errata PIC1 of mpc8544),
It causes that neither MSI nor MSI-X can work fine. There is a workaround
to allow MSI-X to function properly.

Signed-off-by: Liu Shuo <soniccat.liu@gmail.com>
Signed-off-by: Li Yang <leoli@freescale.com>
---
 arch/powerpc/include/asm/mpic.h |    3 ++
 arch/powerpc/sysdev/fsl_msi.c   |   63 +++++++++++++++++++++++++++++++++++++-
 arch/powerpc/sysdev/fsl_msi.h   |    3 ++
 3 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index c9f698a..a9e4f937 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -110,6 +110,9 @@
 #define 	MPIC_VECPRI_SENSE_MASK			0x00400000
 #define MPIC_IRQ_DESTINATION		0x00010
 
+#define 	MPIC_FSL_BRR1				0x00000
+#define 	MPIC_FSL_BRR1_VER			0x0000ffff
+
 #define MPIC_MAX_IRQ_SOURCES	2048
 #define MPIC_MAX_CPUS		32
 #define MPIC_MAX_ISU		32
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 6e097de..f2d340a 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -98,8 +98,23 @@ static int fsl_msi_init_allocator(struct fsl_msi *msi_data)
 
 static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int type)
 {
+	struct fsl_msi *msi;
+
 	if (type == PCI_CAP_ID_MSIX)
 		pr_debug("fslmsi: MSI-X untested, trying anyway.\n");
+	else if (type == PCI_CAP_ID_MSI) {
+		/*
+		 * MPIC chip with 2.0 version has erratum PIC1. It
+		 * causes that neither MSI nor MSI-X can work fine.
+		 * There is a workaround to allow MSI-X to function
+		 * properly.
+		 */
+		list_for_each_entry(msi, &msi_head, list) {
+			if ((msi->feature & MSI_HW_ERRATA_MASK)
+						== MSI_HW_ERRATA_ENDIAN)
+				return -EINVAL;
+		}
+	}
 
 	return 0;
 }
@@ -142,7 +157,11 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
 	msg->address_lo = lower_32_bits(address);
 	msg->address_hi = upper_32_bits(address);
 
-	msg->data = hwirq;
+	/* See the comment in fsl_msi_check_device() */
+	if ((msi_data->feature & MSI_HW_ERRATA_MASK) == MSI_HW_ERRATA_ENDIAN)
+		msg->data = __swab32(hwirq);
+	else
+		msg->data = hwirq;
 
 	pr_debug("%s: allocated srs: %d, ibs: %d\n",
 		__func__, hwirq / IRQS_PER_MSI_REG, hwirq % IRQS_PER_MSI_REG);
@@ -359,13 +378,43 @@ static int __devinit fsl_msi_setup_hwirq(struct fsl_msi *msi,
 	return 0;
 }
 
+/* MPIC chip with 2.0 version has erratum PIC1 */
+static int mpic_has_errata(struct platform_device *dev)
+{
+	struct device_node *mpic_node;
+
+	mpic_node = of_irq_find_parent(dev->dev.of_node);
+	if (mpic_node) {
+		u32 *reg_base, brr1 = 0;
+		/* Get the PIC reg base */
+		reg_base = of_iomap(mpic_node, 0);
+		of_node_put(mpic_node);
+		if (!reg_base) {
+			dev_err(&dev->dev, "ioremap problem failed.\n");
+			return -EIO;
+		}
+
+		/* Get the mpic chip version from block revision register 1 */
+		brr1 = in_be32(reg_base + MPIC_FSL_BRR1);
+		iounmap(reg_base);
+		if ((brr1 & MPIC_FSL_BRR1_VER) == 0x0200)
+			return 1;
+	} else {
+		dev_err(&dev->dev, "MSI can't find his parent mpic node.\n");
+		of_node_put(mpic_node);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
 static const struct of_device_id fsl_of_msi_ids[];
 static int __devinit fsl_of_msi_probe(struct platform_device *dev)
 {
 	const struct of_device_id *match;
 	struct fsl_msi *msi;
 	struct resource res;
-	int err, i, j, irq_index, count;
+	int err, i, j, irq_index, count, errata;
 	int rc;
 	const u32 *p;
 	struct fsl_msi_feature *features;
@@ -421,6 +470,16 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
 
 	msi->feature = features->fsl_pic_ip;
 
+	if ((features->fsl_pic_ip & FSL_PIC_IP_MASK) == FSL_PIC_IP_MPIC) {
+		errata = mpic_has_errata(dev);
+		if (errata > 0) {
+			msi->feature |= MSI_HW_ERRATA_ENDIAN;
+		} else if (errata < 0) {
+			err = errata;
+			goto error_out;
+		}
+	}
+
 	/*
 	 * Remember the phandle, so that we can match with any PCI nodes
 	 * that have an "fsl,msi" property.
diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h
index 8225f86..354d546 100644
--- a/arch/powerpc/sysdev/fsl_msi.h
+++ b/arch/powerpc/sysdev/fsl_msi.h
@@ -25,6 +25,9 @@
 #define FSL_PIC_IP_IPIC   0x00000002
 #define FSL_PIC_IP_VMPIC  0x00000003
 
+#define MSI_HW_ERRATA_MASK   0x000000F0
+#define MSI_HW_ERRATA_ENDIAN 0x00000010
+
 struct fsl_msi {
 	struct irq_domain *irqhost;
 
-- 
1.7.5.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox